@burdenoff/fluidgrids-fe-sdk 2026.1105.2 → 2026.1105.4

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.
Files changed (69) hide show
  1. package/README.md +42 -3
  2. package/dist/ExecutionDetailPage-OOHJQR2L.js +30 -0
  3. package/dist/ExecutionsListPage-6HS5VQOV.js +24 -0
  4. package/dist/WorkflowBuilder-PICIS7FI.js +35 -0
  5. package/dist/WorkflowsList-SD5XQC4Q.js +23 -0
  6. package/dist/{agentTools-5N3ZEZDW.js → agentTools-UH4LU6LA.js} +9 -7
  7. package/dist/{chunk-6ZK4MRVA.js → chunk-43GSC5Y6.js} +1 -1
  8. package/dist/{chunk-CH3YUGWR.js → chunk-4XAXF5VP.js} +4 -4
  9. package/dist/{chunk-6IS7EXIY.js → chunk-5GG2FEKW.js} +2 -2
  10. package/dist/{chunk-64JN2TVX.js → chunk-5Z4F24QT.js} +10 -39
  11. package/dist/chunk-6VIG44VF.js +32 -0
  12. package/dist/{chunk-QFC6E3WD.js → chunk-ASYYYJG2.js} +4 -4
  13. package/dist/{chunk-OXXXUAWM.js → chunk-CTKWMPQQ.js} +1 -1
  14. package/dist/{chunk-QFGZXWTM.js → chunk-EIMTOK6E.js} +3 -3
  15. package/dist/{chunk-AMXJLVZN.js → chunk-EXJW7EKR.js} +2 -2
  16. package/dist/{chunk-O7CJJNW6.js → chunk-GBJWPSLJ.js} +70 -5
  17. package/dist/{chunk-X25NCWG2.js → chunk-GBQC5WDH.js} +16 -8
  18. package/dist/{chunk-3XUWPDKJ.js → chunk-GPABUQTD.js} +650 -636
  19. package/dist/{chunk-3QCRKKTI.js → chunk-HSTP2RX3.js} +267 -2149
  20. package/dist/{chunk-US5QSLPV.js → chunk-JKLZ6YZ3.js} +22 -11
  21. package/dist/{chunk-GKFMK7FF.js → chunk-JRLBPR5U.js} +3 -3
  22. package/dist/{chunk-IL343FKX.js → chunk-KHS2DZHH.js} +1 -1
  23. package/dist/{chunk-SALZ3LQB.js → chunk-KJT5TAOE.js} +3 -3
  24. package/dist/{chunk-AASHQI77.js → chunk-KZCNJAMK.js} +2 -1
  25. package/dist/{chunk-TNFBRXU7.js → chunk-LLCVVRCE.js} +9 -8
  26. package/dist/{chunk-5CFCFA6O.js → chunk-M72SMQOS.js} +8 -7
  27. package/dist/{chunk-TCIBTMJI.js → chunk-NZMUKAXG.js} +3 -69
  28. package/dist/{chunk-2KUZBEWW.js → chunk-OLRIWGYM.js} +8 -7
  29. package/dist/{chunk-62CCBMDC.js → chunk-OTOQFZFO.js} +40 -39
  30. package/dist/{chunk-EYQ7GJRW.js → chunk-PASKZCII.js} +3 -3
  31. package/dist/{chunk-3IXU7WUC.js → chunk-PDODDDHY.js} +1 -1
  32. package/dist/chunk-SDZEAIIE.js +9 -0
  33. package/dist/chunk-TGWDFLEX.js +1932 -0
  34. package/dist/{chunk-AU7LACOY.js → chunk-TYI2XOSI.js} +1 -1
  35. package/dist/{chunk-L2N6DDOI.js → chunk-U7UNWR3D.js} +2 -2
  36. package/dist/{chunk-HK76ZUAK.js → chunk-UIS7KGHW.js} +4 -4
  37. package/dist/{chunk-QPLFALVV.js → chunk-UWCD7JUU.js} +8 -7
  38. package/dist/{chunk-CNKTQ5MG.js → chunk-UYTPURFW.js} +16 -50
  39. package/dist/{chunk-AJVU5YW6.js → chunk-WBRW67HX.js} +4 -3
  40. package/dist/{chunk-J3YQCEP3.js → chunk-WC526MLS.js} +3 -3
  41. package/dist/{chunk-XFH6SLDK.js → chunk-XNARCHMT.js} +2 -2
  42. package/dist/{chunk-W5WML3OO.js → chunk-XWINH6CR.js} +1 -1
  43. package/dist/{chunk-Y6M7K4UG.js → chunk-Y4UCHFGK.js} +1 -1
  44. package/dist/{chunk-OCJTTHTS.js → chunk-Y7FKJJMF.js} +1 -9
  45. package/dist/{client-YVZMLEQX.js → client-62VHXHKN.js} +2 -2
  46. package/dist/code-editor-field-WWPDMF4O.js +3 -0
  47. package/dist/executions.js +17 -15
  48. package/dist/{global-client-N5EIFW6T.js → global-client-PJ5LANJA.js} +2 -2
  49. package/dist/history.js +11 -8
  50. package/dist/index.d.ts +10 -4
  51. package/dist/index.js +69 -52
  52. package/dist/{node-detail-view-WIWW5N6N.js → node-detail-view-P5NV5CMO.js} +14 -12
  53. package/dist/nodes.js +3 -3
  54. package/dist/observability.js +10 -8
  55. package/dist/{quick-config-panel-O64TXXK3.js → quick-config-panel-ZNSBVF4G.js} +11 -9
  56. package/dist/settings.js +11 -9
  57. package/dist/templates.js +17 -14
  58. package/dist/{workflow-builder-7vv9dCdp.d.ts → workflow-builder-C-ekFbwR.d.ts} +37 -4
  59. package/dist/workflow-builder.d.ts +1 -1
  60. package/dist/workflow-builder.js +19 -16
  61. package/dist/workflow-preview.d.ts +158 -0
  62. package/dist/workflow-preview.js +721 -0
  63. package/dist/workflows-list.js +12 -10
  64. package/package.json +5 -1
  65. package/dist/ExecutionDetailPage-HQB2SWBP.js +0 -28
  66. package/dist/ExecutionsListPage-RSLL634L.js +0 -22
  67. package/dist/WorkflowBuilder-E3PNZX74.js +0 -32
  68. package/dist/WorkflowsList-473FRRP2.js +0 -21
  69. package/dist/code-editor-field-XWUVOKTA.js +0 -2
package/README.md CHANGED
@@ -229,6 +229,36 @@ const register = (spec: FgPageControlsSpec) => registerWithMyAssistant(spec);
229
229
  / `TabsSpec` (fe-libs >= 2026.1004.6 `appControls`), so a host can pass them
230
230
  straight to `enumFilter` / `tabsOf`.
231
231
 
232
+ ## Read-only workflow preview (optional)
233
+
234
+ `WorkflowPreviewCanvas` draws a stored workflow definition with the builder's own
235
+ node cards, read-only, and animates it as a workflow is built live (the AI
236
+ assistant's live preview). It needs no `FluidGridsProvider`, config, Apollo client
237
+ or node registry, and makes no request of its own.
238
+
239
+ ```tsx
240
+ import { WorkflowPreviewCanvas, previewCanvasFromDefinition, previewRevealOrder } from "@burdenoff/fluidgrids-fe-sdk/workflow-preview";
241
+
242
+ <div style={{ height: 520 }}>
243
+ <WorkflowPreviewCanvas
244
+ definition={workflow.definitionJson} // object or JSON string
245
+ visibleNodeIds={shown} // omit to show every node
246
+ freshNodeIds={justAdded} // highlighted with a ring
247
+ running={assistantIsWriting} // flow along edges, newest node pulses
248
+ />
249
+ </div>
250
+ ```
251
+
252
+ - The host drives the reveal: `previewRevealOrder(previewCanvasFromDefinition(def).nodes)`
253
+ gives the along-the-flow order. A node that becomes visible pops in, an edge
254
+ draws in once both ends are visible, and the camera eases to keep every
255
+ visible node in view (max zoom 1.5).
256
+ - `resolveNodeMeta(nodeType)` (optional, keep it stable) supplies registry names
257
+ and icons; without it a card uses the node's saved manifest, then a name and
258
+ icon derived from its type.
259
+ - Nodes cannot be dragged, connected, selected or deleted; pan and zoom work.
260
+ - `prefers-reduced-motion: reduce` turns every animation off.
261
+
232
262
  ## Styling
233
263
 
234
264
  The SDK uses Tailwind CSS for styling. Make sure you have Tailwind configured in your project, or import the pre-built styles:
@@ -262,16 +292,25 @@ embedding props (also settable with `setFluidGridsConfig`):
262
292
  values are validated (`themeToCssVariables`) and applied document-wide as
263
293
  inline properties on `<html>`, restored on unmount (`applyFluidGridsTheme`,
264
294
  `useFluidGridsTheme`). The public embed viewer also reads `accent`, `radius`
265
- and `font` query parameters next to `theme`.
295
+ and `font` query parameters next to `theme`; its single `radius` sets
296
+ `radius.base`, `radius.card`, `radius.button` and `radius.input` (builder node
297
+ cards follow `--radius-card`).
266
298
  - **`auth.onTokenExpired`** — called once per expired-session failure (401,
267
299
  `UNAUTHENTICATED`, expired/revoked credential); concurrent failures share one
268
300
  call; the request is retried once with the new token; on rejection the SDK
269
- emits `auth:failed` and surfaces the original error. Host-injected Apollo
301
+ emits `auth:failed` and surfaces the original error. A failed refresh is
302
+ reported once: requests already in flight with the expired token fail with
303
+ their own error without a second call or event; a request sent after the
304
+ failure may refresh again. Host-injected Apollo
270
305
  clients add `createFluidGridsTokenRefreshLink()` before their auth link.
271
306
  - **`onEvent`** — typed `FluidGridsEventMap`: `workflow:saved`,
272
307
  `workflow:activated`, `run:started`, `run:completed`, `node:selected`,
273
308
  `error`, `auth:failed`. Contract version `FLUIDGRIDS_EVENTS_VERSION` (semver:
274
- additive = minor, payload break = major).
309
+ additive = minor, payload break = major). The standalone `WorkflowBuilder` /
310
+ `WorkflowBuilderCore` canvas saves and runs locally (`onSave` / `onExecute`),
311
+ so it emits only `node:selected`.
312
+ - `FluidGridsRoot`, `WorkflowBuilder` and `WorkflowBuilderCore` work without a
313
+ host `ThemeProvider`; they reuse the host's when there is one.
275
314
 
276
315
  Full guide: [docs.fluidgrids.ai/developers/embedding](https://docs.fluidgrids.ai/developers/embedding).
277
316
 
@@ -0,0 +1,30 @@
1
+ export { ExecutionDetailPage } from './chunk-GPABUQTD.js';
2
+ import './chunk-ASYYYJG2.js';
3
+ import './chunk-UYTPURFW.js';
4
+ import './chunk-WC526MLS.js';
5
+ import './chunk-NZMUKAXG.js';
6
+ import './chunk-NZAYYUQ4.js';
7
+ import './chunk-EXJW7EKR.js';
8
+ import './chunk-WZ3EJVS6.js';
9
+ import './chunk-5ERAJC2I.js';
10
+ import './chunk-PASKZCII.js';
11
+ import './chunk-JDLQ6QIB.js';
12
+ import './chunk-KHS2DZHH.js';
13
+ import './chunk-Y53CVZVV.js';
14
+ import './chunk-FNZZ5JJL.js';
15
+ import './chunk-EIMTOK6E.js';
16
+ import './chunk-PJAWNFJV.js';
17
+ import './chunk-H4ERTSMX.js';
18
+ import './chunk-HSTP2RX3.js';
19
+ import './chunk-5375NUIO.js';
20
+ import './chunk-JL7CASN5.js';
21
+ import './chunk-SDZEAIIE.js';
22
+ import './chunk-TGWDFLEX.js';
23
+ import './chunk-Y7FKJJMF.js';
24
+ import './chunk-TYI2XOSI.js';
25
+ import './chunk-G77IGC3Y.js';
26
+ import './chunk-Z3ABLERJ.js';
27
+ import './chunk-UULVIT25.js';
28
+ import './chunk-PDODDDHY.js';
29
+ import './chunk-JKLZ6YZ3.js';
30
+ import './chunk-UEG2WC3G.js';
@@ -0,0 +1,24 @@
1
+ export { ExecutionsListPage } from './chunk-UIS7KGHW.js';
2
+ import './chunk-UYTPURFW.js';
3
+ import './chunk-WC526MLS.js';
4
+ import './chunk-WZ3EJVS6.js';
5
+ import './chunk-5ERAJC2I.js';
6
+ import './chunk-KHS2DZHH.js';
7
+ import './chunk-FNZZ5JJL.js';
8
+ import './chunk-EIMTOK6E.js';
9
+ import './chunk-PJAWNFJV.js';
10
+ import './chunk-H4ERTSMX.js';
11
+ import './chunk-4VJ3MDOV.js';
12
+ import './chunk-HSTP2RX3.js';
13
+ import './chunk-5375NUIO.js';
14
+ import './chunk-JL7CASN5.js';
15
+ import './chunk-SDZEAIIE.js';
16
+ import './chunk-TGWDFLEX.js';
17
+ import './chunk-Y7FKJJMF.js';
18
+ import './chunk-TYI2XOSI.js';
19
+ import './chunk-G77IGC3Y.js';
20
+ import './chunk-Z3ABLERJ.js';
21
+ import './chunk-UULVIT25.js';
22
+ import './chunk-PDODDDHY.js';
23
+ import './chunk-JKLZ6YZ3.js';
24
+ import './chunk-UEG2WC3G.js';
@@ -0,0 +1,35 @@
1
+ export { WorkflowBuilder } from './chunk-LLCVVRCE.js';
2
+ import './chunk-Y4UCHFGK.js';
3
+ import './chunk-PIKYQE7P.js';
4
+ import './chunk-OTOQFZFO.js';
5
+ import './chunk-XWINH6CR.js';
6
+ import './chunk-GEMNVFPK.js';
7
+ import './chunk-B6CCE2RW.js';
8
+ import './chunk-IEVSFCFS.js';
9
+ import './chunk-YXMFRQYV.js';
10
+ import './chunk-BQXVT32O.js';
11
+ import './chunk-43GSC5Y6.js';
12
+ import './chunk-JRLBPR5U.js';
13
+ import './chunk-PASKZCII.js';
14
+ import './chunk-JDLQ6QIB.js';
15
+ import './chunk-KHS2DZHH.js';
16
+ import './chunk-Y53CVZVV.js';
17
+ import './chunk-5Z4F24QT.js';
18
+ import './chunk-6VIG44VF.js';
19
+ import './chunk-EIMTOK6E.js';
20
+ import './chunk-GLYINMOR.js';
21
+ import './chunk-H4ERTSMX.js';
22
+ import './chunk-4VJ3MDOV.js';
23
+ import './chunk-HSTP2RX3.js';
24
+ import './chunk-5375NUIO.js';
25
+ import './chunk-JL7CASN5.js';
26
+ import './chunk-SDZEAIIE.js';
27
+ import './chunk-TGWDFLEX.js';
28
+ import './chunk-Y7FKJJMF.js';
29
+ import './chunk-TYI2XOSI.js';
30
+ import './chunk-G77IGC3Y.js';
31
+ import './chunk-Z3ABLERJ.js';
32
+ import './chunk-UULVIT25.js';
33
+ import './chunk-PDODDDHY.js';
34
+ import './chunk-JKLZ6YZ3.js';
35
+ import './chunk-UEG2WC3G.js';
@@ -0,0 +1,23 @@
1
+ export { WorkflowsList } from './chunk-M72SMQOS.js';
2
+ import './chunk-Y4UCHFGK.js';
3
+ import './chunk-WC526MLS.js';
4
+ import './chunk-5ERAJC2I.js';
5
+ import './chunk-JRLBPR5U.js';
6
+ import './chunk-FNZZ5JJL.js';
7
+ import './chunk-EIMTOK6E.js';
8
+ import './chunk-PJAWNFJV.js';
9
+ import './chunk-H4ERTSMX.js';
10
+ import './chunk-4VJ3MDOV.js';
11
+ import './chunk-HSTP2RX3.js';
12
+ import './chunk-5375NUIO.js';
13
+ import './chunk-JL7CASN5.js';
14
+ import './chunk-SDZEAIIE.js';
15
+ import './chunk-TGWDFLEX.js';
16
+ import './chunk-Y7FKJJMF.js';
17
+ import './chunk-TYI2XOSI.js';
18
+ import './chunk-G77IGC3Y.js';
19
+ import './chunk-Z3ABLERJ.js';
20
+ import './chunk-UULVIT25.js';
21
+ import './chunk-PDODDDHY.js';
22
+ import './chunk-JKLZ6YZ3.js';
23
+ import './chunk-UEG2WC3G.js';
@@ -1,15 +1,17 @@
1
- import { nodeTitle, selectedOperationOf, paramsFromOperation, fixedParameterState } from './chunk-AJVU5YW6.js';
2
- import { computeAttachPosition } from './chunk-W5WML3OO.js';
3
- import { NODE_CONFIGS, createConfiguredNode, resolveOutputHandles, resolveInputHandles, isNodeConfigsInitialized, useFlowStore, useSaveStatusStore, autosaveAllowedFor, isFlowComplete, isNodeTypeHiddenFromPalette } from './chunk-3QCRKKTI.js';
1
+ import { nodeTitle, selectedOperationOf, paramsFromOperation, fixedParameterState } from './chunk-WBRW67HX.js';
2
+ import { computeAttachPosition } from './chunk-XWINH6CR.js';
3
+ import { NODE_CONFIGS, createConfiguredNode, isNodeConfigsInitialized, useSaveStatusStore, autosaveAllowedFor, isFlowComplete, isNodeTypeHiddenFromPalette } from './chunk-HSTP2RX3.js';
4
4
  import './chunk-5375NUIO.js';
5
5
  import './chunk-JL7CASN5.js';
6
- import './chunk-OCJTTHTS.js';
7
- import './chunk-AU7LACOY.js';
6
+ import './chunk-SDZEAIIE.js';
7
+ import { resolveOutputHandles, resolveInputHandles, useFlowStore } from './chunk-TGWDFLEX.js';
8
+ import './chunk-Y7FKJJMF.js';
9
+ import './chunk-TYI2XOSI.js';
8
10
  import './chunk-G77IGC3Y.js';
9
11
  import './chunk-Z3ABLERJ.js';
10
12
  import './chunk-UULVIT25.js';
11
- import './chunk-3IXU7WUC.js';
12
- import './chunk-US5QSLPV.js';
13
+ import './chunk-PDODDDHY.js';
14
+ import './chunk-JKLZ6YZ3.js';
13
15
  import './chunk-UEG2WC3G.js';
14
16
  import { defineAgentTool, AgentToolError } from '@burdenoff/fe-libs/shared/agent-tools';
15
17
  import { z } from 'zod';
@@ -1,4 +1,4 @@
1
- import { useFlowStore } from './chunk-3QCRKKTI.js';
1
+ import { useFlowStore } from './chunk-TGWDFLEX.js';
2
2
  import { useTr } from './chunk-UULVIT25.js';
3
3
  import { useState, useRef, useCallback, useEffect } from 'react';
4
4
  import { cn } from '@burdenoff/fe-libs/utils';
@@ -1,10 +1,10 @@
1
- import { useImportWorkflowTemplate, FlowBuilderPage, useWorkflowTemplates, TEMPLATE_STORE_CATEGORIES, TemplateCard, useTemplateSubmissions, usePublishToStore } from './chunk-62CCBMDC.js';
2
- import { QuotaExhaustedDialog } from './chunk-GKFMK7FF.js';
1
+ import { useImportWorkflowTemplate, FlowBuilderPage, useWorkflowTemplates, TEMPLATE_STORE_CATEGORIES, TemplateCard, useTemplateSubmissions, usePublishToStore } from './chunk-OTOQFZFO.js';
2
+ import { QuotaExhaustedDialog } from './chunk-JRLBPR5U.js';
3
3
  import { templatesControls } from './chunk-FNZZ5JJL.js';
4
- import { useWorkflowDefinitions, useDuplicateWorkflow, useLazyWorkflowDefinition } from './chunk-QFGZXWTM.js';
4
+ import { useWorkflowDefinitions, useDuplicateWorkflow, useLazyWorkflowDefinition } from './chunk-EIMTOK6E.js';
5
5
  import { useFluidGridsPageControls } from './chunk-PJAWNFJV.js';
6
6
  import { FluidGridsDocsLink } from './chunk-4VJ3MDOV.js';
7
- import { BILLING_PLANS_PATH, useFluidGridsAnalytics, emitTemplateUsed, isQuotaExhaustedFailure } from './chunk-3QCRKKTI.js';
7
+ import { BILLING_PLANS_PATH, useFluidGridsAnalytics, emitTemplateUsed, isQuotaExhaustedFailure } from './chunk-HSTP2RX3.js';
8
8
  import { SdkPermissionButton, FLUIDGRIDS_PERMISSIONS } from './chunk-5375NUIO.js';
9
9
  import { useTr } from './chunk-UULVIT25.js';
10
10
  import { useState, useEffect, useCallback, useMemo } from 'react';
@@ -1,6 +1,6 @@
1
- import { versionsOfWorkflow, VersionDiffDialog } from './chunk-64JN2TVX.js';
1
+ import { versionsOfWorkflow, VersionDiffDialog } from './chunk-5Z4F24QT.js';
2
2
  import { historyControls } from './chunk-FNZZ5JJL.js';
3
- import { useWorkflowDefinitions, useRestoreWorkflowVersion } from './chunk-QFGZXWTM.js';
3
+ import { useWorkflowDefinitions, useRestoreWorkflowVersion } from './chunk-EIMTOK6E.js';
4
4
  import { useFluidGridsPageControls } from './chunk-PJAWNFJV.js';
5
5
  import { FluidGridsDocsLink } from './chunk-4VJ3MDOV.js';
6
6
  import { useTr } from './chunk-UULVIT25.js';
@@ -1,8 +1,8 @@
1
- import { mergeStickyNotes } from './chunk-3QCRKKTI.js';
1
+ import { canvasFromDefinition } from './chunk-6VIG44VF.js';
2
2
  import { WorkflowDefinitionDocument, WorkflowVersionDiffDocument } from './chunk-Z3ABLERJ.js';
3
3
  import { useTr } from './chunk-UULVIT25.js';
4
- import { getFluidGridsClient } from './chunk-3IXU7WUC.js';
5
- import { describeOperationError, throwIfResultError } from './chunk-US5QSLPV.js';
4
+ import { getFluidGridsClient } from './chunk-PDODDDHY.js';
5
+ import { describeOperationError, throwIfResultError } from './chunk-JKLZ6YZ3.js';
6
6
  import { memo, useState, useEffect, useMemo, useRef, useCallback } from 'react';
7
7
  import { ArrowLeftRight, Eye, RotateCcw, Loader2 } from 'lucide-react';
8
8
  import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription, Button, Badge, AlertDialog, AlertDialogContent, AlertDialogHeader, AlertDialogTitle, AlertDialogDescription, AlertDialogFooter, AlertDialogCancel, AlertDialogAction, Tabs, TabsList, TabsTrigger, TabsContent } from '@burdenoff/fe-libs/ui';
@@ -50,35 +50,6 @@ function versionsOfWorkflow(rows, workflowKey) {
50
50
  return rows.filter((row) => row.workflowKey === workflowKey).sort((a, b) => time(b.createdAt) - time(a.createdAt));
51
51
  }
52
52
 
53
- // src/builder/live/definition-canvas.ts
54
- function isRecord(value) {
55
- return typeof value === "object" && value !== null && !Array.isArray(value);
56
- }
57
- function hasId(item) {
58
- return isRecord(item) && typeof item.id === "string" && item.id.length > 0;
59
- }
60
- function canvasFromDefinition(definitionJson) {
61
- let definition = definitionJson;
62
- if (typeof definition === "string") {
63
- try {
64
- definition = JSON.parse(definition);
65
- } catch {
66
- return null;
67
- }
68
- }
69
- if (!isRecord(definition)) return null;
70
- const data = isRecord(definition.data) ? definition.data : definition;
71
- if (!Array.isArray(data.nodes)) return null;
72
- const nodes = mergeStickyNotes({
73
- nodes: data.nodes,
74
- stickyNotes: Array.isArray(data.stickyNotes) ? data.stickyNotes : []
75
- }).filter(hasId);
76
- const edges = (Array.isArray(data.edges) ? data.edges : []).filter(
77
- hasId
78
- );
79
- return { nodes, edges };
80
- }
81
-
82
53
  // src/modules/history/utils/version-graph-diff.ts
83
54
  var LAYOUT_NODE_KEYS = /* @__PURE__ */ new Set([
84
55
  "position",
@@ -106,7 +77,7 @@ var LAYOUT_EDGE_KEYS = /* @__PURE__ */ new Set([
106
77
  ]);
107
78
  var DIFF_CARD_FOOTPRINT = { width: 220, height: 90 };
108
79
  var MAX_CHANGED_FIELDS = 20;
109
- function isRecord2(value) {
80
+ function isRecord(value) {
110
81
  return typeof value === "object" && value !== null && !Array.isArray(value);
111
82
  }
112
83
  function equalJson(left, right) {
@@ -114,7 +85,7 @@ function equalJson(left, right) {
114
85
  if (Array.isArray(left) && Array.isArray(right)) {
115
86
  return left.length === right.length && left.every((value, index) => equalJson(value, right[index]));
116
87
  }
117
- if (isRecord2(left) && isRecord2(right)) {
88
+ if (isRecord(left) && isRecord(right)) {
118
89
  const leftKeys = Object.keys(left).filter((k) => left[k] !== void 0);
119
90
  const rightKeys = Object.keys(right).filter((k) => right[k] !== void 0);
120
91
  if (leftKeys.length !== rightKeys.length) return false;
@@ -128,7 +99,7 @@ function changedPaths(before, after, prefix = "", limit = MAX_CHANGED_FIELDS) {
128
99
  const paths = [];
129
100
  const visit = (left, right, path) => {
130
101
  if (paths.length >= limit || equalJson(left, right)) return;
131
- if (isRecord2(left) && isRecord2(right)) {
102
+ if (isRecord(left) && isRecord(right)) {
132
103
  const keys = [
133
104
  .../* @__PURE__ */ new Set([...Object.keys(left), ...Object.keys(right)])
134
105
  ].sort((a, b) => a.localeCompare(b));
@@ -154,11 +125,11 @@ function text(value) {
154
125
  return typeof value === "string" && value.trim() ? value.trim() : null;
155
126
  }
156
127
  function nodeLabel(node) {
157
- const data = isRecord2(node.data) ? node.data : {};
128
+ const data = isRecord(node.data) ? node.data : {};
158
129
  return text(data.label) ?? text(data.name) ?? text(data.title) ?? String(node.id);
159
130
  }
160
131
  function nodeTypeOf(node) {
161
- const data = isRecord2(node.data) ? node.data : {};
132
+ const data = isRecord(node.data) ? node.data : {};
162
133
  return text(data.nodeType) ?? text(data.type) ?? text(node.type) ?? "node";
163
134
  }
164
135
  function positionOf(node) {
@@ -197,7 +168,7 @@ function edgeSignature(edge) {
197
168
  function edgeLabel(edge) {
198
169
  if (typeof edge.label === "string" && edge.label.trim())
199
170
  return edge.label.trim();
200
- const data = isRecord2(edge.data) ? edge.data : {};
171
+ const data = isRecord(edge.data) ? edge.data : {};
201
172
  return text(data.label);
202
173
  }
203
174
  function emptyCounts() {
@@ -1478,4 +1449,4 @@ function VersionDiffDialog({
1478
1449
  ] });
1479
1450
  }
1480
1451
 
1481
- export { VersionDiffDialog, VersionLifecycleBar, canvasFromDefinition, countLifecycle, versionsOfWorkflow };
1452
+ export { VersionDiffDialog, VersionLifecycleBar, countLifecycle, versionsOfWorkflow };
@@ -0,0 +1,32 @@
1
+ import { mergeStickyNotes } from './chunk-TGWDFLEX.js';
2
+
3
+ // src/builder/live/definition-canvas.ts
4
+ function isRecord(value) {
5
+ return typeof value === "object" && value !== null && !Array.isArray(value);
6
+ }
7
+ function hasId(item) {
8
+ return isRecord(item) && typeof item.id === "string" && item.id.length > 0;
9
+ }
10
+ function canvasFromDefinition(definitionJson) {
11
+ let definition = definitionJson;
12
+ if (typeof definition === "string") {
13
+ try {
14
+ definition = JSON.parse(definition);
15
+ } catch {
16
+ return null;
17
+ }
18
+ }
19
+ if (!isRecord(definition)) return null;
20
+ const data = isRecord(definition.data) ? definition.data : definition;
21
+ if (!Array.isArray(data.nodes)) return null;
22
+ const nodes = mergeStickyNotes({
23
+ nodes: data.nodes,
24
+ stickyNotes: Array.isArray(data.stickyNotes) ? data.stickyNotes : []
25
+ }).filter(hasId);
26
+ const edges = (Array.isArray(data.edges) ? data.edges : []).filter(
27
+ hasId
28
+ );
29
+ return { nodes, edges };
30
+ }
31
+
32
+ export { canvasFromDefinition };
@@ -1,8 +1,8 @@
1
- import { signalPayloadCard, components_default, payloadFromCardValues, parseRawSignalPayload } from './chunk-3QCRKKTI.js';
1
+ import { signalPayloadCard, components_default, payloadFromCardValues, parseRawSignalPayload } from './chunk-HSTP2RX3.js';
2
2
  import { TerminateWorkflowRunDocument, WorkflowRunHistoryDocument, RunEventAppendedDocument, DurableRunFieldsDocument, WorkflowRunDeterminismStatusDocument, WorkflowRunStackTraceDocument, SignalWorkflowRunDocument } from './chunk-Z3ABLERJ.js';
3
3
  import { useTr } from './chunk-UULVIT25.js';
4
- import { getFluidGridsClient, getFluidGridsClientSafe } from './chunk-3IXU7WUC.js';
5
- import { throwIfResultError, describeOperationError } from './chunk-US5QSLPV.js';
4
+ import { getFluidGridsClient, getFluidGridsClientSafe } from './chunk-PDODDDHY.js';
5
+ import { throwIfResultError, describeOperationError } from './chunk-JKLZ6YZ3.js';
6
6
  import { useState, useMemo, useRef, useCallback, useEffect } from 'react';
7
7
  import { Icon } from '@iconify/react';
8
8
  import { Button } from '@burdenoff/fe-libs/button';
@@ -579,7 +579,7 @@ function HistoryRow({
579
579
  href: event.payloadUrl ?? void 0,
580
580
  target: "_blank",
581
581
  rel: "noreferrer noopener",
582
- className: "text-action-primary-text hover:underline",
582
+ className: "text-text-link hover:text-text-linkHover hover:underline",
583
583
  children: tr(
584
584
  "fluidgrids.executions.history.offloadedPayload",
585
585
  "Download payload"
@@ -1,6 +1,6 @@
1
1
  import { NodeEndpointConfigsDocument, NodeEndpointConfigDocument, NodeManifestDocument, fetchAllNodeEndpointConfigs } from './chunk-Z3ABLERJ.js';
2
2
  import { useTr } from './chunk-UULVIT25.js';
3
- import { getFluidGridsClient } from './chunk-3IXU7WUC.js';
3
+ import { getFluidGridsClient } from './chunk-PDODDDHY.js';
4
4
  import { useMemo, useState, useCallback, useEffect } from 'react';
5
5
  import { useNavigate } from 'react-router';
6
6
  import { Icon } from '@iconify/react';
@@ -1,8 +1,8 @@
1
- import { useFluidGridsAnalytics, emitWorkflowCreated, emitRunStarted, runTriggerFromMode, openRunQuotaUpgradePrompt, emitWorkflowPublished } from './chunk-3QCRKKTI.js';
1
+ import { useFluidGridsAnalytics, emitWorkflowCreated, emitRunStarted, runTriggerFromMode, openRunQuotaUpgradePrompt, emitWorkflowPublished } from './chunk-HSTP2RX3.js';
2
2
  import { WorkflowDefinitionsDocument, WorkflowDefinitionDocument, WorkflowVersionsDocument, CreateWorkflowDefinitionDocument, ImportWorkflowDocument, PreviewN8nImportDocument, UpdateWorkflowDefinitionDocument, CreateWorkflowVersionDocument, DeleteWorkflowDefinitionDocument, DuplicateWorkflowDocument, RestoreWorkflowVersionDocument, TriggerWorkflowDocument, WorkflowRunsDocument, WorkflowRunDocument, DashboardSummaryDocument, ActivateWorkflowDefinitionDocument, DeactivateWorkflowDefinitionDocument } from './chunk-Z3ABLERJ.js';
3
3
  import { useTr } from './chunk-UULVIT25.js';
4
- import { getFluidGridsClient } from './chunk-3IXU7WUC.js';
5
- import { throwIfResultError, emitFluidGridsEvent, emitOperationErrorEvent } from './chunk-US5QSLPV.js';
4
+ import { getFluidGridsClient } from './chunk-PDODDDHY.js';
5
+ import { throwIfResultError, emitFluidGridsEvent, emitOperationErrorEvent } from './chunk-JKLZ6YZ3.js';
6
6
  import { getFluidGridsConfig } from './chunk-UEG2WC3G.js';
7
7
  import { useState, useCallback, useEffect, useMemo } from 'react';
8
8
 
@@ -1,6 +1,6 @@
1
1
  import { useTr } from './chunk-UULVIT25.js';
2
- import { getFluidGridsClient } from './chunk-3IXU7WUC.js';
3
- import { throwIfResultError, describeOperationError } from './chunk-US5QSLPV.js';
2
+ import { getFluidGridsClient } from './chunk-PDODDDHY.js';
3
+ import { throwIfResultError, describeOperationError } from './chunk-JKLZ6YZ3.js';
4
4
  import { useState, useCallback, useEffect, useMemo } from 'react';
5
5
  import { gql } from '@apollo/client';
6
6
  import { Button } from '@burdenoff/fe-libs/button';
@@ -1,13 +1,13 @@
1
- import { formatBytes, getFailureBreakdown, getTopFailingWorkflows, getTopFailingNodes, percentage, FailureTriagePanel, formatDuration, prettyJson } from './chunk-TCIBTMJI.js';
1
+ import { FailureTriagePanel } from './chunk-NZMUKAXG.js';
2
2
  import { aiSpendPeriod, AI_SPEND_RANGE_DAYS, evidenceFacts, monthlySavingLabel, evidenceWindowDays, shortRunId, DISMISS_REASONS, MAX_DISMISS_NOTE_LENGTH, aiCost, formatTokens, runsOfWorkflowPath } from './chunk-NZAYYUQ4.js';
3
- import { useDataSinks, useDataSinkData, useInsightsData, useRunReplayActions } from './chunk-SALZ3LQB.js';
3
+ import { useDataSinks, useDataSinkData, useInsightsData, useRunReplayActions } from './chunk-KJT5TAOE.js';
4
4
  import { proposalCanvasPath } from './chunk-GLYINMOR.js';
5
- import { useContinuousOptimisationEnabled } from './chunk-3QCRKKTI.js';
5
+ import { useContinuousOptimisationEnabled } from './chunk-HSTP2RX3.js';
6
6
  import { useFluidGridsPermission, FLUIDGRIDS_PERMISSIONS, SdkPermissionButton } from './chunk-5375NUIO.js';
7
7
  import { SetContinuousOptimisationEnabledDocument, FgRunOptimisationScanDocument, ProposeOptimisationDocument, WorkflowProposalDocument, DismissOptimisationSuggestionDocument, SnoozeOptimisationSuggestionDocument, WorkspaceAiUsageDocument, OptimisationSuggestionsDocument, ContinuousOptimisationSettingsDocument } from './chunk-Z3ABLERJ.js';
8
8
  import { useTr } from './chunk-UULVIT25.js';
9
- import { getFluidGridsClient } from './chunk-3IXU7WUC.js';
10
- import { throwIfResultError } from './chunk-US5QSLPV.js';
9
+ import { getFluidGridsClient } from './chunk-PDODDDHY.js';
10
+ import { throwIfResultError } from './chunk-JKLZ6YZ3.js';
11
11
  import { useState, useMemo, useEffect, useRef, useCallback } from 'react';
12
12
  import { Icon } from '@iconify/react';
13
13
  import { Button } from '@burdenoff/fe-libs/button';
@@ -17,6 +17,71 @@ import { useNavigate, Link } from 'react-router';
17
17
  import { toast } from 'sonner';
18
18
  import { Lightbulb, Scissors, Timer, ShieldCheck, DatabaseZap, BadgeDollarSign, RotateCcw } from 'lucide-react';
19
19
 
20
+ // src/modules/observability/utils.ts
21
+ function percentage(value, total) {
22
+ if (total <= 0) return 0;
23
+ return Math.round(value / total * 1e3) / 10;
24
+ }
25
+ function getFailureBreakdown(runs) {
26
+ const counts = /* @__PURE__ */ new Map();
27
+ for (const run of runs) {
28
+ const key = run.errorType || "UNKNOWN";
29
+ counts.set(key, (counts.get(key) ?? 0) + 1);
30
+ }
31
+ return [...counts.entries()].map(([key, count]) => ({ key, count })).sort((a, b) => b.count - a.count || a.key.localeCompare(b.key));
32
+ }
33
+ function getTopFailingWorkflows(runs) {
34
+ const counts = /* @__PURE__ */ new Map();
35
+ for (const run of runs) {
36
+ const current = counts.get(run.workflowKey);
37
+ if (current) {
38
+ current.count += 1;
39
+ } else {
40
+ counts.set(run.workflowKey, {
41
+ workflowKey: run.workflowKey,
42
+ label: run.workflow?.name || run.workflowKey,
43
+ count: 1
44
+ });
45
+ }
46
+ }
47
+ return [...counts.values()].sort(
48
+ (a, b) => b.count - a.count || a.label.localeCompare(b.label)
49
+ );
50
+ }
51
+ function getTopFailingNodes(nodeUsageStats) {
52
+ return [...nodeUsageStats].filter((stat) => stat.failureCount > 0).sort(
53
+ (a, b) => b.failureCount - a.failureCount || a.nodeType.localeCompare(b.nodeType)
54
+ );
55
+ }
56
+ function formatDuration(seconds) {
57
+ if (seconds === null || seconds === void 0 || !Number.isFinite(seconds)) {
58
+ return "\u2014";
59
+ }
60
+ if (seconds < 1) return `${Math.round(seconds * 1e3)}ms`;
61
+ if (seconds < 60) return `${seconds.toFixed(1)}s`;
62
+ const minutes = Math.floor(seconds / 60);
63
+ const remainingSeconds = Math.round(seconds % 60);
64
+ return `${minutes}m ${remainingSeconds}s`;
65
+ }
66
+ function formatBytes(bytes) {
67
+ if (!Number.isFinite(bytes) || bytes < 0) return "\u2014";
68
+ if (bytes < 1024) return `${bytes} B`;
69
+ const units = ["KB", "MB", "GB", "TB"];
70
+ let value = bytes / 1024;
71
+ let unit = units[0];
72
+ for (let i = 1; i < units.length && value >= 1024; i += 1) {
73
+ value /= 1024;
74
+ unit = units[i];
75
+ }
76
+ return `${value.toFixed(value >= 10 ? 0 : 1)} ${unit}`;
77
+ }
78
+ function prettyJson(value) {
79
+ try {
80
+ return JSON.stringify(value, null, 2) ?? "null";
81
+ } catch {
82
+ return String(value);
83
+ }
84
+ }
20
85
  function valueLabel(value) {
21
86
  if (value === null || value === void 0) return "\u2014";
22
87
  if (typeof value === "object") return JSON.stringify(value);
@@ -1,9 +1,10 @@
1
- import { Card, FluidGridsMark } from './chunk-62CCBMDC.js';
1
+ import { useNodeSelectedEvent, Card, FluidGridsMark } from './chunk-OTOQFZFO.js';
2
2
  import { Input } from './chunk-IEVSFCFS.js';
3
3
  import { Button } from './chunk-BQXVT32O.js';
4
- import { useWorkflowDefinition } from './chunk-QFGZXWTM.js';
5
- import { FluidGridsProvider, useFlowStore } from './chunk-3QCRKKTI.js';
4
+ import { useWorkflowDefinition } from './chunk-EIMTOK6E.js';
5
+ import { FluidGridsProvider } from './chunk-HSTP2RX3.js';
6
6
  import { cn } from './chunk-JL7CASN5.js';
7
+ import { useFlowStore } from './chunk-TGWDFLEX.js';
7
8
  import { useTr } from './chunk-UULVIT25.js';
8
9
  import { useState, useRef, useEffect, useCallback } from 'react';
9
10
  import { MarkerType, ReactFlowProvider, useReactFlow, ReactFlow, Background, Controls, MiniMap, Handle, Position } from '@xyflow/react';
@@ -11,9 +12,10 @@ import { useShallow } from 'zustand/shallow';
11
12
  import { edgeColor, nodeCategoryColor } from '@burdenoff/fe-libs/shared/utils';
12
13
  import '@xyflow/react/dist/style.css';
13
14
  import { ArrowLeft, Save, Play, Trash2 } from 'lucide-react';
14
- import { useTheme } from '@burdenoff/fe-libs/shared/hooks/shell';
15
+ import { useThemeOrNull, useTheme } from '@burdenoff/fe-libs/shared/hooks/shell';
15
16
  import { Toaster as Toaster$1 } from 'sonner';
16
- import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
17
+ import { jsx, Fragment, jsxs } from 'react/jsx-runtime';
18
+ import { ThemeProvider } from '@burdenoff/fe-libs/shared/providers/shell';
17
19
  import { useParams, Navigate } from 'react-router';
18
20
  import { Icon } from '@iconify/react';
19
21
 
@@ -36,6 +38,11 @@ var Toaster = ({ ...props }) => {
36
38
  }
37
39
  );
38
40
  };
41
+ function EnsureThemeProvider({ children }) {
42
+ const hostTheme = useThemeOrNull();
43
+ if (hostTheme) return /* @__PURE__ */ jsx(Fragment, { children });
44
+ return /* @__PURE__ */ jsx(ThemeProvider, { children });
45
+ }
39
46
  var defaultEdgeOptions = {
40
47
  type: "smoothstep",
41
48
  markerEnd: {
@@ -153,6 +160,7 @@ function FlowBuilderInner({
153
160
  }) {
154
161
  const reactFlowInstance = useReactFlow();
155
162
  const tr = useTr();
163
+ useNodeSelectedEvent();
156
164
  const setWorkflow = useFlowStore((s) => s.actions.setWorkflow);
157
165
  const resetWorkflow = useFlowStore((s) => s.actions.resetWorkflow);
158
166
  const deleteNode = useFlowStore((s) => s.actions.nodes.deleteNode);
@@ -474,10 +482,10 @@ function FlowBuilderInner({
474
482
  );
475
483
  }
476
484
  function WorkflowBuilderCore(props) {
477
- return /* @__PURE__ */ jsxs(ReactFlowProvider, { children: [
485
+ return /* @__PURE__ */ jsx(EnsureThemeProvider, { children: /* @__PURE__ */ jsxs(ReactFlowProvider, { children: [
478
486
  /* @__PURE__ */ jsx(FlowBuilderInner, { ...props }),
479
487
  /* @__PURE__ */ jsx(Toaster, { richColors: true, position: "bottom-center", duration: 2e3 })
480
- ] });
488
+ ] }) });
481
489
  }
482
490
  function WorkflowBuilder({
483
491
  workflowId,
@@ -560,4 +568,4 @@ function WorkflowSearchRedirect() {
560
568
  );
561
569
  }
562
570
 
563
- export { WorkflowBuilder, WorkflowBuilderCore, WorkflowSearchRedirect };
571
+ export { EnsureThemeProvider, WorkflowBuilder, WorkflowBuilderCore, WorkflowSearchRedirect };