@burdenoff/fluidgrids-fe-sdk 2026.1112.7 → 2026.1112.8

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 (75) hide show
  1. package/dist/{AiStudioPage-QGTFaVpx.js → AiStudioPage-CtgPSPyc.js} +5 -5
  2. package/dist/{DataSinkDashboardPage-kyzcjpzL.js → DataSinkDashboardPage-Dt3xTBb8.js} +1 -1
  3. package/dist/{DataTablesPage-0U89KNBt.js → DataTablesPage-2xTLe_jk.js} +3 -3
  4. package/dist/{EntityTagPicker-dxfzv8aO.js → EntityTagPicker-CuZAMby_.js} +1 -1
  5. package/dist/{ExecutionDetailPage-D4Mdbzb2.js → ExecutionDetailPage-CL-w9c3L.js} +12 -12
  6. package/dist/{ExecutionsListPage-g_SPxAGX.js → ExecutionsListPage-Bf6Cvsnz.js} +8 -8
  7. package/dist/{FailureTriagePanel-D4lJ4zqQ.js → FailureTriagePanel-BjatYyAa.js} +1 -1
  8. package/dist/{FluidGridsProvider-B1hgCbxG.js → FluidGridsProvider-TQ-aDPtn.js} +3 -3
  9. package/dist/{HistoryPage-C7NwkVNC.js → HistoryPage-s9pl5gyl.js} +2 -2
  10. package/dist/{InsightsPage-D9B_qW8e.js → InsightsPage-CtjJCky-.js} +4 -4
  11. package/dist/{MissingNodesInstallModal-BkkgeFeN.js → MissingNodesInstallModal-BCbhddk4.js} +1 -1
  12. package/dist/{NodesPage-BEeUbIts.js → NodesPage-BSNpOUMX.js} +2 -2
  13. package/dist/OpenTemplateAsCodeButton-BgvgDaVe.js +94 -0
  14. package/dist/{SettingsPage-k21044-Z.js → SettingsPage-ywyjIAL8.js} +6 -6
  15. package/dist/{TagFilterSelect-CqhxcDjh.js → TagFilterSelect-DcusTt1p.js} +1 -1
  16. package/dist/{TaskQueuesPage-B86p51gH.js → TaskQueuesPage-C2dkenVF.js} +2 -2
  17. package/dist/{TemplateCard-DanOe65C.js → TemplateCard-XBc0qEA4.js} +214 -13
  18. package/dist/{TemplateConfigurationModal-CeMpPEhT.js → TemplateConfigurationModal-Dl_7RaCt.js} +20 -11
  19. package/dist/{TemplateDetailPanel-DnoA6mC3.js → TemplateDetailPanel-0Cc6jguU.js} +1 -1
  20. package/dist/{TemplatePreview-DY4GxnfC.js → TemplatePreview-CRLUX5yI.js} +23 -14
  21. package/dist/{TemplatesPage-C7f2xq12.js → TemplatesPage-wClKZLO4.js} +4 -4
  22. package/dist/{VersionDiffDialog-pLpG_I1r.js → VersionDiffDialog-c27yet_-.js} +1 -1
  23. package/dist/{WorkflowBuilder-DY1_KJiV.js → WorkflowBuilder-CK6c0eRp.js} +8 -8
  24. package/dist/{WorkflowBuilder-Aslfa2vj.js → WorkflowBuilder-qRGFtXJG.js} +3 -3
  25. package/dist/{WorkflowProposalCard-BjYAZH3q.js → WorkflowProposalCard-BvmJ5ea8.js} +1 -1
  26. package/dist/{WorkflowSearchRedirect-iPQBL6WO.js → WorkflowSearchRedirect-BGKduhfZ.js} +1 -1
  27. package/dist/{WorkflowShareDialog-DB-qJLB2.js → WorkflowShareDialog-BRwTF9QB.js} +1 -1
  28. package/dist/{WorkflowsList-rOxlI49U.js → WorkflowsList-Bocag4TX.js} +9 -8
  29. package/dist/{agentTools-B8gnHFVM.js → agentTools-BkQsycAp.js} +3 -3
  30. package/dist/{api-JpNuowX4.js → api-Dw8nfVRD.js} +1 -1
  31. package/dist/{api-Dvitj1aT.js → api-m8hX_l2k.js} +1 -1
  32. package/dist/{canvasNoteTools-Cj7MvVDH.js → canvasNoteTools-U7j1z7GR.js} +2 -2
  33. package/dist/{code-editor-field-yJZEDJBi.js → code-editor-field-CWGZyNGM.js} +1 -1
  34. package/dist/executions.js +2 -2
  35. package/dist/{feature-flags-DM5myWaD.js → feature-flags-B_b8PJ6Z.js} +63 -3
  36. package/dist/flags.d.ts +1 -1
  37. package/dist/flags.js +1 -1
  38. package/dist/{flow-builder-dvqpKs8d.js → flow-builder-9jDNwkID.js} +509 -296
  39. package/dist/{graphql-operation-types-z2oXfQvM.js → graphql-operation-types-DZVhCBEi.js} +250 -1
  40. package/dist/history.js +1 -1
  41. package/dist/{index-BcdtKBM-.d.ts → index-B4g88tCa.d.ts} +15 -1
  42. package/dist/{index-DNo9aFUT.d.ts → index-rj-TznII.d.ts} +29 -1
  43. package/dist/index.d.ts +3 -3
  44. package/dist/index.js +33 -33
  45. package/dist/{node-detail-view-ZnJ3Hvvo.js → node-detail-view-C1yupyvL.js} +9 -9
  46. package/dist/{node-editor-tab-body-BuiIr7VD.js → node-editor-tab-body-BtxSQPtX.js} +3 -3
  47. package/dist/{node-endpoint-configs-typvqw2c.js → node-endpoint-configs-BI7zc8eM.js} +1 -1
  48. package/dist/nodes.js +1 -1
  49. package/dist/observability.d.ts +1 -1
  50. package/dist/observability.js +2 -2
  51. package/dist/{popover-mexhIFP3.js → popover-BaYffpTw.js} +2 -2
  52. package/dist/{quick-config-panel-EV66lJOM.js → quick-config-panel-BvlhLiQp.js} +3 -3
  53. package/dist/{schedule-panel-BeLfDNFh.js → schedule-panel-D5VdzW2c.js} +8 -8
  54. package/dist/settings.js +1 -1
  55. package/dist/{sidebar-node-editor-D85Moj5d.js → sidebar-node-editor-BU4rJwvm.js} +3 -3
  56. package/dist/templates.js +2 -2
  57. package/dist/{useAgentDefinitions-Uy6nhpKN.js → useAgentDefinitions-B4sw7bLw.js} +1 -1
  58. package/dist/{useDurableParity-04-5PTk2.js → useDurableParity-B3h8jqP0.js} +2 -2
  59. package/dist/{useEntityTags-D5C0tdLs.js → useEntityTags-BpDeLhzV.js} +1 -1
  60. package/dist/{useExecutions-DJXtbA15.js → useExecutions-BbkBSYpS.js} +2 -2
  61. package/dist/{useObservability-Dfgh4yjv.js → useObservability-BASo2sA3.js} +1 -1
  62. package/dist/{useRunHistory-BZQ3t68Q.js → useRunHistory-C3Pv_SJW.js} +2 -2
  63. package/dist/useWorkflowCodeExport-k5Emm4ZS.js +226 -0
  64. package/dist/{useWorkflows-CP-d3ygY.js → useWorkflows-CRUlQBd3.js} +2 -2
  65. package/dist/workflow-builder.js +4 -4
  66. package/dist/workflow-code-transfer-Cshsgf2H.js +375 -0
  67. package/dist/workflow-host.d.ts +1 -1
  68. package/dist/workflow-host.js +1 -1
  69. package/dist/workflow-pages.d.ts +1 -1
  70. package/dist/workflow-pages.js +16 -16
  71. package/dist/workflow-transfer-CQnQC-ke.js +104 -0
  72. package/dist/workflows-list.js +1 -1
  73. package/package.json +1 -1
  74. package/dist/QuotaExhaustedDialog-Bj7AG_0y.js +0 -55
  75. package/dist/useWorkflowCodeExport-D0zapXXm.js +0 -643
@@ -1,31 +1,33 @@
1
1
  "use client";
2
2
  import { B as NODE_TYPE_DRAG_DATA_FORMAT, G as isTriggerOperation, H as useFlowStore, M as isImageIcon, T as resolveInputHandles, U as useIsValidConnection, V as STICKY_NOTE_TYPE, j as NodeTypeIcon, r as CODE_WORKFLOW_NODE_TYPE, z as NODE_OPERATION_DRAG_DATA_FORMAT } from "./node-operation-selection-DAbS6jSY.js";
3
- import { $t as AUTOSAVE_DEBOUNCE_MS, Bn as useMarkdownRenderer, Bt as leaseCallSequence, Cn as loadDefinitionJson, Ct as watchLeavingLosesChanges, D as InstallWorkflowNodeDocument, E as InstallPurchasedNodeDocument, Et as useSaveWorkflow, F as getNodeMetadata, Ft as useEditLeaseLocked, Gt as tickAction, H as MissingParametersDialog, Hn as useBuilderReadOnly, Ht as phaseAfterTakeOver, It as useEditLeaseStore, Jt as rememberSessionForReload, Kt as EDIT_SESSION_ID, Ln as getNodeDetail, Lt as bannerOf, M as UninstallOrganizationPrivateNodeDocument, Mt as saveIndicatorOf, N as UninstallWorkflowNodeDocument, Nt as useSaveStatusStore, Pt as workflowSaveQueue, Qt as revisionOf, Rn as buildStickyNode, Rt as isLocked, S as CreateStoreOrderDocument, St as touchesSavedFields, T as InstallOrganizationPrivateNodeDocument, Tt as useFlowValidator, U as useRunGuard, Ut as releasesOnClose, V as useInsertNode, Vn as BuilderReadOnlyProvider, Vt as phaseAfterAcquire, W as workflowParameterIssues, Wt as shouldReleaseForIdle, Xt as rememberOwnStatusChange, Yt as sessionBeforeReload, Zt as rememberRevision, _t as departingSave, a as NODES_METADATA, an as resettledBaseline, b as BrowseWorkflowNodesDocument, bn as useCanvasEdges, bt as leavingLosesChanges, cn as useNodeExecution, en as AUTOSAVE_RETRY_DELAYS_MS, f as isNodeConfigsInitialized, g as registerWorkflowNodeTypes, gt as autosaveAllowedFor, ht as useManualSave, i as AVAILABLE_NODES, in as inAppLeaveTarget, jt as refusalOfQuota, k as OrganizationPrivateNodesDocument, l as ensureNodeConfigsLoaded, m as refetchStoreNodes, mt as useGuardedNavigate, o as NODE_CONFIGS, on as saveFailureActionOf, p as onNodeTypesUpdate, qt as forgetSessionForReload, s as NODE_TYPES, sn as workflowFingerprint, t as FluidGridsContext, tn as canAutosave, v as scheduleNodePaletteLoad, vt as editStateFor, w as GetNodeInstallableVersionsDocument, wt as isFlowComplete, xn as useNodeRegistryRevision, xt as savedEverythingBeforeLeaving, yt as editingLeaseLocked, z as buildOperationSeed, zn as loadMarkdown, zt as leaseCallQueue } from "./FluidGridsProvider-B1hgCbxG.js";
3
+ import { $t as AUTOSAVE_DEBOUNCE_MS, Bn as useMarkdownRenderer, Bt as leaseCallSequence, Cn as loadDefinitionJson, Ct as watchLeavingLosesChanges, D as InstallWorkflowNodeDocument, E as InstallPurchasedNodeDocument, Et as useSaveWorkflow, F as getNodeMetadata, Ft as useEditLeaseLocked, Gt as tickAction, H as MissingParametersDialog, Hn as useBuilderReadOnly, Ht as phaseAfterTakeOver, It as useEditLeaseStore, Jt as rememberSessionForReload, Kt as EDIT_SESSION_ID, Ln as getNodeDetail, Lt as bannerOf, M as UninstallOrganizationPrivateNodeDocument, Mt as saveIndicatorOf, N as UninstallWorkflowNodeDocument, Nt as useSaveStatusStore, Pt as workflowSaveQueue, Qt as revisionOf, Rn as buildStickyNode, Rt as isLocked, S as CreateStoreOrderDocument, St as touchesSavedFields, T as InstallOrganizationPrivateNodeDocument, Tt as useFlowValidator, U as useRunGuard, Ut as releasesOnClose, V as useInsertNode, Vn as BuilderReadOnlyProvider, Vt as phaseAfterAcquire, W as workflowParameterIssues, Wt as shouldReleaseForIdle, Xt as rememberOwnStatusChange, Yt as sessionBeforeReload, Zt as rememberRevision, _t as departingSave, a as NODES_METADATA, an as resettledBaseline, b as BrowseWorkflowNodesDocument, bn as useCanvasEdges, bt as leavingLosesChanges, cn as useNodeExecution, en as AUTOSAVE_RETRY_DELAYS_MS, f as isNodeConfigsInitialized, g as registerWorkflowNodeTypes, gt as autosaveAllowedFor, ht as useManualSave, i as AVAILABLE_NODES, in as inAppLeaveTarget, jt as refusalOfQuota, k as OrganizationPrivateNodesDocument, l as ensureNodeConfigsLoaded, m as refetchStoreNodes, mt as useGuardedNavigate, o as NODE_CONFIGS, on as saveFailureActionOf, p as onNodeTypesUpdate, qt as forgetSessionForReload, s as NODE_TYPES, sn as workflowFingerprint, t as FluidGridsContext, tn as canAutosave, v as scheduleNodePaletteLoad, vt as editStateFor, w as GetNodeInstallableVersionsDocument, wt as isFlowComplete, xn as useNodeRegistryRevision, xt as savedEverythingBeforeLeaving, yt as editingLeaseLocked, z as buildOperationSeed, zn as loadMarkdown, zt as leaseCallQueue } from "./FluidGridsProvider-TQ-aDPtn.js";
4
4
  import { r as useTr } from "./TranslationBridge-Da-TPgQm.js";
5
5
  import { n as preloadableLazy } from "./preloadable-lazy-Pp47mqQ9.js";
6
6
  import { a as DialogFooter$1, d as Input$1, i as DialogDescription$1, l as DialogTitle$1, o as DialogHeader$1, r as DialogContent$1, t as Dialog$1 } from "./dialog-Cjb4lB4D.js";
7
- import { _ as storeNodeInstallVersion, a as useTemplateImportFlow, d as filterStoreNodesForPalette, f as getStoreNodeAvailability, g as storeNodeDisplayVersion, h as isStoreNodeUpdateAvailable, k as filterPaletteNodes, m as getStoreNodeType, p as getStoreNodeIcon, t as TemplateCard, u as useWorkflowTemplates, v as useInstalledNodes, y as useGlobalStoreClient } from "./TemplateCard-DanOe65C.js";
7
+ import { _ as isStoreNodeUpdateAvailable, a as useTemplateImportFlow, b as useInstalledNodes, f as useWorkflowTemplates, g as getStoreNodeType, h as getStoreNodeIcon, j as filterPaletteNodes, m as getStoreNodeAvailability, p as filterStoreNodesForPalette, t as TemplateCard, v as storeNodeDisplayVersion, x as useGlobalStoreClient, y as storeNodeInstallVersion } from "./TemplateCard-XBc0qEA4.js";
8
8
  import { _ as throwIfResultError, d as emitFluidGridsEvent, m as describeOperationError, n as getFluidGridsClient, s as waitForFluidGridsClient, x as getFluidGridsConfig } from "./client-C9XSzSXr.js";
9
- import { c as useDurableParityEnabled, d as usePaletteGates, l as useFluidGridsFlag, m as useWorkflowTestsEnabled, s as useDurableFunctionNodesEnabled, t as FLUIDGRIDS_FLAGS } from "./feature-flags-DM5myWaD.js";
9
+ import { _ as useWorkflowTestsEnabled, d as useFluidGridsFlag, h as usePhaseDFlags, l as useDurableFunctionNodesEnabled, p as usePaletteGates, t as FLUIDGRIDS_FLAGS, u as useDurableParityEnabled } from "./feature-flags-B_b8PJ6Z.js";
10
10
  import { t as Button$2 } from "./button-DG7y_FVJ.js";
11
11
  import { t as PublishCustomNodeAction } from "./PublishCustomNodeAction-5XXnSA3H.js";
12
12
  import { o as emitUpgradeClicked, t as emitNodeInstalled } from "./fluidgridsEvents-Dm5CaHtr.js";
13
- import { $t as RemoveNodeFromWorkflowsDocument, Br as WorkflowGitPushesDocument, Ci as WorkflowVersioningDocument, Ft as NodeUsageStatusDocument, Gr as WorkflowPromotionRequestsDocument, Hn as TakeOverWorkflowEditLeaseDocument, Lr as WorkflowGenerationTemplatesDocument, Mn as SetWorkflowRolloutDocument, Mr as WorkflowEditLeaseDocument, Nt as NodeSchemaIntrospectionDocument, Or as WorkflowDefinitionDocument, Pr as WorkflowEnvironmentsDocument, Q as DeployWorkflowVersionToDevDocument, Qt as ReleaseWorkflowEditLeaseDocument, Rr as WorkflowGitCommitsDocument, S as CancelWorkflowPromotionDocument, Si as WorkflowVersionDrainageDocument, Vr as WorkflowGitRepositoryDocument, Xt as RejectWorkflowPromotionDocument, Y as DeleteWorkflowRolloutDocument, Zn as UnlinkWorkflowGitRepositoryDocument, br as WorkflowAuthoringDocument, l as ApproveWorkflowPromotionDocument, lr as UpdateWorkflowEnvironmentPolicyDocument, qt as PushWorkflowToGitDocument, r as ActivateWorkflowVersionCheckedDocument, rn as RequestWorkflowPromotionDocument, sn as RestoreWorkflowFromGitDocument, t as AcquireWorkflowEditLeaseDocument, wt as LinkWorkflowGitRepositoryDocument, zr as WorkflowGitDiffDocument } from "./graphql-operation-types-z2oXfQvM.js";
13
+ import { $t as RemoveNodeFromWorkflowsDocument, Br as WorkflowGitPushesDocument, Ci as WorkflowVersionDrainageDocument, Ft as NodeUsageStatusDocument, Gr as WorkflowPromotionRequestsDocument, Hn as TakeOverWorkflowEditLeaseDocument, Kr as WorkflowProposalCodeDocument, Lr as WorkflowGenerationTemplatesDocument, Mn as SetWorkflowRolloutDocument, Mr as WorkflowEditLeaseDocument, Nt as NodeSchemaIntrospectionDocument, Or as WorkflowDefinitionDocument, Pr as WorkflowEnvironmentsDocument, Q as DeployWorkflowVersionToDevDocument, Qt as ReleaseWorkflowEditLeaseDocument, Rr as WorkflowGitCommitsDocument, S as CancelWorkflowPromotionDocument, Vr as WorkflowGitRepositoryDocument, Xt as RejectWorkflowPromotionDocument, Y as DeleteWorkflowRolloutDocument, Zn as UnlinkWorkflowGitRepositoryDocument, br as WorkflowAuthoringDocument, l as ApproveWorkflowPromotionDocument, lr as UpdateWorkflowEnvironmentPolicyDocument, qt as PushWorkflowToGitDocument, r as ActivateWorkflowVersionCheckedDocument, rn as RequestWorkflowPromotionDocument, sn as RestoreWorkflowFromGitDocument, t as AcquireWorkflowEditLeaseDocument, wi as WorkflowVersioningDocument, wt as LinkWorkflowGitRepositoryDocument, zr as WorkflowGitDiffDocument } from "./graphql-operation-types-DZVhCBEi.js";
14
14
  import { n as useAgentMarksStore } from "./marksStore-DGCXjTmZ.js";
15
- import { A as CreateWorkflowRefusalDialog, C as orderedExportFiles, E as sortFidelityItems, S as lineOfNode, _ as fileBaseName, b as isLosslessReport, c as saveWorkflowDescription, l as visibleWorkflowDescription, o as commitWorkflowDescription, r as useWorkflowCodeExport, s as normalizeWorkflowDescription, t as downloadWorkflowCodeExport, u as workflowDescriptionCharactersLeft, x as isLossyFidelityItem } from "./useWorkflowCodeExport-D0zapXXm.js";
15
+ import { a as saveWorkflowDescription, c as CreateWorkflowRefusalDialog, i as normalizeWorkflowDescription, n as useWorkflowCodeExport, o as visibleWorkflowDescription, r as commitWorkflowDescription, s as workflowDescriptionCharactersLeft } from "./useWorkflowCodeExport-k5Emm4ZS.js";
16
16
  import { r as RUNS_QUOTA_NAME, t as BILLING_PLANS_PATH } from "./quota-Cdt8yz7N.js";
17
- import { t as EntityTagPicker } from "./EntityTagPicker-dxfzv8aO.js";
17
+ import { t as EntityTagPicker } from "./EntityTagPicker-CuZAMby_.js";
18
18
  import { t as FluidGridsDocsLink } from "./FluidGridsDocsLink-JxkBpOeb.js";
19
19
  import { n as runsQuotaLevel, t as readRunsQuota } from "./runsQuota-DvXR6mRN.js";
20
20
  import { a as SdkPermissionGate, i as SdkPermissionButton, s as useFluidGridsPermission, t as FLUIDGRIDS_PERMISSIONS } from "./constants-dcxg6zG6.js";
21
- import { a as useDeactivateWorkflow, d as useRestoreWorkflowVersion, o as useDeleteWorkflow, t as useActivateWorkflow, v as useWorkflowVersions } from "./useWorkflows-CP-d3ygY.js";
22
- import { n as VersionLifecycleBar, r as countLifecycle, t as VersionDiffDialog } from "./VersionDiffDialog-pLpG_I1r.js";
21
+ import { a as useDeactivateWorkflow, d as useRestoreWorkflowVersion, o as useDeleteWorkflow, t as useActivateWorkflow, v as useWorkflowVersions } from "./useWorkflows-CRUlQBd3.js";
22
+ import { n as VersionLifecycleBar, r as countLifecycle, t as VersionDiffDialog } from "./VersionDiffDialog-c27yet_-.js";
23
23
  import { $P as VersioningBehavior, Eu as DrainageStatus, MI as WorkflowTestExpectedStatus, jo as CodeReplaceStatus, nI as WorkflowEnvironment, rI as WorkflowExportFormat } from "./graphql-types-v6CTGwA0.js";
24
24
  import { n as useConnections } from "./useConnections-Cs7LCWEM.js";
25
25
  import { t as buildNodeDisplayMap } from "./run-display-BycKYSU0.js";
26
- import { a as TEST_STATUS_TONE_CLASS, c as draftToInput, d as isTestRunOpen, f as nextSortOrder, g as testStatusTone, h as testStatusLabel, i as useWorkflowTests, l as emptyTestCaseDraft, m as testRunSummaryText, n as useWorkflowProposal, p as pinnedOutputsFromCanvas, s as draftFromTestCase, t as WorkflowProposalCard, u as enabledCaseIds } from "./WorkflowProposalCard-BjYAZH3q.js";
26
+ import { a as TEST_STATUS_TONE_CLASS, c as draftToInput, d as isTestRunOpen, f as nextSortOrder, g as testStatusTone, h as testStatusLabel, i as useWorkflowTests, l as emptyTestCaseDraft, m as testRunSummaryText, n as useWorkflowProposal, p as pinnedOutputsFromCanvas, s as draftFromTestCase, t as WorkflowProposalCard, u as enabledCaseIds } from "./WorkflowProposalCard-BvmJ5ea8.js";
27
27
  import { n as useRequestedProposal } from "./useRequestedProposal-B7uPXfZB.js";
28
28
  import { t as AiCreditBalanceSlot } from "./aiCreditsBridge-BuE92tKo.js";
29
+ import { t as downloadBlob } from "./workflow-transfer-CQnQC-ke.js";
30
+ import { _ as sortFidelityItems, c as fileBaseName, d as isLosslessReport, f as isLossyFidelityItem, m as orderedExportFiles, o as buildExportDownload, p as lineOfNode } from "./workflow-code-transfer-Cshsgf2H.js";
29
31
  import * as React$1 from "react";
30
32
  import { Suspense, createContext, lazy, memo, useCallback, useContext, useDeferredValue, useEffect, useLayoutEffect, useMemo, useRef, useState, useSyncExternalStore } from "react";
31
33
  import { Link, useNavigate, useParams } from "react-router";
@@ -260,10 +262,10 @@ function IntroductionPropertyPanel() {
260
262
  * waiting for its chunk and React's Suspense throttle (about 0.5 s on first
261
263
  * open even with the chunk cached).
262
264
  */
263
- const NodeDetailViewOverlay = preloadableLazy(() => import("./node-detail-view-ZnJ3Hvvo.js").then((m) => m.NodeDetailView), "NodeDetailView");
264
- const QuickConfigPanelOverlay = preloadableLazy(() => import("./quick-config-panel-EV66lJOM.js").then((m) => m.QuickConfigPanel), "QuickConfigPanel");
265
- const SidebarNodeEditorOverlay = preloadableLazy(() => import("./sidebar-node-editor-D85Moj5d.js").then((m) => m.SidebarNodeEditor), "SidebarNodeEditor");
266
- const WorkflowShareDialogOverlay = preloadableLazy(() => import("./WorkflowShareDialog-DB-qJLB2.js").then((n) => n.n).then((m) => m.WorkflowShareDialog), "WorkflowShareDialog");
265
+ const NodeDetailViewOverlay = preloadableLazy(() => import("./node-detail-view-C1yupyvL.js").then((m) => m.NodeDetailView), "NodeDetailView");
266
+ const QuickConfigPanelOverlay = preloadableLazy(() => import("./quick-config-panel-BvlhLiQp.js").then((m) => m.QuickConfigPanel), "QuickConfigPanel");
267
+ const SidebarNodeEditorOverlay = preloadableLazy(() => import("./sidebar-node-editor-BU4rJwvm.js").then((m) => m.SidebarNodeEditor), "SidebarNodeEditor");
268
+ const WorkflowShareDialogOverlay = preloadableLazy(() => import("./WorkflowShareDialog-BRwTF9QB.js").then((n) => n.n).then((m) => m.WorkflowShareDialog), "WorkflowShareDialog");
267
269
  const ConnectionFormDialogOverlay = preloadableLazy(() => import("./ConnectionFormDialog-Bg9_OdHX.js").then((n) => n.n).then((m) => m.ConnectionFormDialog), "ConnectionFormDialog");
268
270
  /**
269
271
  * Loads every overlay's code (and the markdown renderer the sticky notes and
@@ -2742,7 +2744,7 @@ function TemplatesGrid({ templates, loading, hasMore, onLoadMore, onTemplateClic
2742
2744
  }
2743
2745
 
2744
2746
  // src/builder/components/flow-builder/components/templates/TemplatesModal.tsx
2745
- const LazyTemplateDetailPanel = lazy(() => import("./TemplateDetailPanel-DnoA6mC3.js").then((m) => ({ default: m.TemplateDetailPanel })));
2747
+ const LazyTemplateDetailPanel = lazy(() => import("./TemplateDetailPanel-0Cc6jguU.js").then((m) => ({ default: m.TemplateDetailPanel })));
2746
2748
  /**
2747
2749
  * Modal for browsing and selecting workflow templates
2748
2750
  * Features:
@@ -16234,6 +16236,435 @@ function canvasHasWork(nodes) {
16234
16236
  return nodes.length > 1;
16235
16237
  }
16236
16238
 
16239
+ // src/hooks/useWorkflowProposalCode.ts
16240
+ /**
16241
+ * Generate with AI emits code (BOFF-9907, PLAN-D D1): an AI proposal's
16242
+ * definition lifted to TypeScript or Python.
16243
+ *
16244
+ * The model never writes code (DD5): the service lifts the validated
16245
+ * definition through C-LIFT on each read (`WorkflowProposal.code(format)`),
16246
+ * so the files always lower back to the proposal and the fidelity report
16247
+ * proves it. The AI panel reads it only while a code tab is open, with
16248
+ * `fluidgrids.code-first` and `fluidgrids.ai-code` on; the service re-checks
16249
+ * both flags on every read.
16250
+ */
16251
+ /**
16252
+ * One network round trip; never served from the Apollo cache, because the
16253
+ * lift follows the proposal's current definition. Null while the proposal has
16254
+ * no definition (still processing, or failed).
16255
+ */
16256
+ async function fetchWorkflowProposalCode(id, format) {
16257
+ const result = await getFluidGridsClient().query({
16258
+ query: WorkflowProposalCodeDocument,
16259
+ variables: {
16260
+ id,
16261
+ format
16262
+ },
16263
+ fetchPolicy: "network-only"
16264
+ });
16265
+ throwIfResultError(result);
16266
+ return result.data?.workflowProposal?.code ?? null;
16267
+ }
16268
+ /**
16269
+ * The lifted code of one proposal in one format, fetched while `enabled` (a
16270
+ * code tab is open). A response for an older request (the format or the
16271
+ * proposal changed meanwhile) is dropped, so the Python tab never shows
16272
+ * TypeScript. `revision` refetches when it changes, for example when the
16273
+ * proposal's status or definition moved on.
16274
+ */
16275
+ function useWorkflowProposalCode(id, format, enabled, revision, errorFallback) {
16276
+ const key = `${id ?? ""}\u0000${format}\u0000${revision}`;
16277
+ const [answer, setAnswer] = useState(null);
16278
+ const [pendingKey, setPendingKey] = useState(null);
16279
+ const request = useRef(0);
16280
+ const refetch = useCallback(async () => {
16281
+ if (!id) return;
16282
+ const current = ++request.current;
16283
+ setPendingKey(key);
16284
+ try {
16285
+ const code = await fetchWorkflowProposalCode(id, format);
16286
+ if (current !== request.current) return;
16287
+ setAnswer({
16288
+ key,
16289
+ data: code,
16290
+ error: null
16291
+ });
16292
+ } catch (err) {
16293
+ if (current !== request.current) return;
16294
+ setAnswer({
16295
+ key,
16296
+ data: null,
16297
+ error: describeOperationError(err, errorFallback)
16298
+ });
16299
+ } finally {
16300
+ if (current === request.current) setPendingKey(null);
16301
+ }
16302
+ }, [
16303
+ id,
16304
+ format,
16305
+ key,
16306
+ errorFallback
16307
+ ]);
16308
+ useEffect(() => {
16309
+ if (!enabled || !id) {
16310
+ request.current++;
16311
+ return;
16312
+ }
16313
+ refetch();
16314
+ }, [
16315
+ enabled,
16316
+ id,
16317
+ refetch
16318
+ ]);
16319
+ const current = answer?.key === key ? answer : null;
16320
+ return {
16321
+ data: current?.data ?? null,
16322
+ loading: enabled && id !== null && pendingKey === key,
16323
+ error: current?.error ?? null,
16324
+ refetch
16325
+ };
16326
+ }
16327
+
16328
+ // src/builder/components/flow-builder/components/ui/code-view-fidelity.tsx
16329
+ /**
16330
+ * The fidelity report of a code export (BOFF-9904, spec 07 §2), as the
16331
+ * builder's Code view shows it: whether lowering the exported code gives the
16332
+ * same workflow back, and every item the service reported, each linked to its
16333
+ * node on the canvas.
16334
+ */
16335
+ function FidelityLevelBadge({ fidelity }) {
16336
+ const tr = useTr();
16337
+ const lossless = isLosslessReport(fidelity);
16338
+ return /* @__PURE__ */ jsxs(Badge, {
16339
+ variant: lossless ? "secondary" : "destructive",
16340
+ "data-testid": "fluidgrids-code-fidelity-level",
16341
+ "data-level": lossless ? "lossless" : "lossy",
16342
+ className: "gap-1",
16343
+ children: [/* @__PURE__ */ jsx(Icon, {
16344
+ icon: lossless ? "mynaui:check-circle" : "mynaui:danger-triangle",
16345
+ className: "size-3.5"
16346
+ }), lossless ? tr("fluidgrids.builder.codeView.lossless", "Lossless") : tr("fluidgrids.builder.codeView.lossy", "Lossy")]
16347
+ });
16348
+ }
16349
+ function FidelityReportList({ fidelity, source, hasNode, onShowNode, hints }) {
16350
+ const tr = useTr();
16351
+ const items = sortFidelityItems(fidelity.items);
16352
+ return /* @__PURE__ */ jsxs("section", {
16353
+ "aria-labelledby": "fg-code-fidelity",
16354
+ "data-testid": "fluidgrids-code-fidelity",
16355
+ className: "space-y-2",
16356
+ children: [
16357
+ /* @__PURE__ */ jsxs("div", {
16358
+ className: "flex items-center justify-between gap-2",
16359
+ children: [/* @__PURE__ */ jsx("h3", {
16360
+ id: "fg-code-fidelity",
16361
+ className: "text-xs font-semibold uppercase tracking-wide text-muted-foreground",
16362
+ children: tr("fluidgrids.builder.codeView.fidelityTitle", "Fidelity")
16363
+ }), /* @__PURE__ */ jsx(FidelityLevelBadge, { fidelity })]
16364
+ }),
16365
+ /* @__PURE__ */ jsx("p", {
16366
+ className: "text-xs text-muted-foreground",
16367
+ children: hints ? isLosslessReport(fidelity) ? hints.lossless : hints.lossy : isLosslessReport(fidelity) ? tr("fluidgrids.builder.codeView.losslessHint", "Lowering this code gives back exactly this workflow.") : tr("fluidgrids.builder.codeView.lossyHint", "Lowering this code does not give back exactly this workflow. The items marked lossy say what differs.")
16368
+ }),
16369
+ items.length === 0 ? /* @__PURE__ */ jsx("p", {
16370
+ className: "text-xs text-muted-foreground",
16371
+ children: tr("fluidgrids.builder.codeView.noFidelityItems", "Nothing to report.")
16372
+ }) : /* @__PURE__ */ jsx("ul", {
16373
+ className: "space-y-1.5",
16374
+ children: items.map((item, index) => {
16375
+ const lossy = isLossyFidelityItem(item);
16376
+ const nodeId = item.nodeId ?? null;
16377
+ const line = nodeId && source !== void 0 ? lineOfNode(source, nodeId) : null;
16378
+ return /* @__PURE__ */ jsxs("li", {
16379
+ "data-testid": "fluidgrids-code-fidelity-item",
16380
+ "data-kind": item.kind,
16381
+ "data-lossy": lossy ? "true" : "false",
16382
+ className: cn("rounded-md border p-2 text-xs", lossy ? "border-[var(--color-status-error-border)] bg-[var(--color-status-error-bg)]" : "border-border bg-muted/30"),
16383
+ children: [
16384
+ /* @__PURE__ */ jsxs("div", {
16385
+ className: "flex flex-wrap items-center gap-1.5",
16386
+ children: [
16387
+ /* @__PURE__ */ jsx(Badge, {
16388
+ variant: lossy ? "destructive" : "outline",
16389
+ className: "text-[10px]",
16390
+ children: lossy ? tr("fluidgrids.builder.codeView.itemLossy", "Lossy") : tr("fluidgrids.builder.codeView.itemLossless", "Kept")
16391
+ }),
16392
+ /* @__PURE__ */ jsx("code", {
16393
+ className: "font-mono text-[11px] text-card-foreground",
16394
+ children: item.kind
16395
+ }),
16396
+ line !== null && /* @__PURE__ */ jsx("span", {
16397
+ className: "text-muted-foreground",
16398
+ children: tr("fluidgrids.builder.codeView.itemLine", "line {{line}}", { line: String(line) })
16399
+ })
16400
+ ]
16401
+ }),
16402
+ /* @__PURE__ */ jsx("p", {
16403
+ className: "mt-1 break-words text-card-foreground",
16404
+ children: item.detail
16405
+ }),
16406
+ item.path && /* @__PURE__ */ jsx("p", {
16407
+ className: "mt-0.5 break-all font-mono text-[11px] text-muted-foreground",
16408
+ children: item.path
16409
+ }),
16410
+ nodeId && onShowNode && /* @__PURE__ */ jsxs(Button, {
16411
+ variant: "link",
16412
+ size: "sm",
16413
+ className: "mt-1 h-auto gap-1 p-0 text-xs",
16414
+ disabled: !hasNode?.(nodeId),
16415
+ onClick: () => onShowNode(nodeId),
16416
+ "data-testid": "fluidgrids-code-fidelity-node",
16417
+ children: [/* @__PURE__ */ jsx(Icon, {
16418
+ icon: "mynaui:location",
16419
+ className: "size-3.5"
16420
+ }), tr("fluidgrids.builder.codeView.showNode", "Show node {{nodeId}}", { nodeId })]
16421
+ })
16422
+ ]
16423
+ }, `${item.kind}-${nodeId ?? ""}-${item.path ?? ""}-${index}`);
16424
+ })
16425
+ })
16426
+ ]
16427
+ });
16428
+ }
16429
+
16430
+ // src/builder/components/flow-builder/components/ui/code-files-view.tsx
16431
+ /**
16432
+ * CodeFilesView — the presentational part of a read-only code view
16433
+ * (BOFF-9904, split out for BOFF-9907 PLAN-D D1).
16434
+ *
16435
+ * Shows a set of lifted files (the workflow module first, then its sidecars
16436
+ * and generated node clients) syntax-highlighted and read-only, the irHash,
16437
+ * the fidelity report, and *Copy* and *Download*. It fetches nothing: the
16438
+ * builder's Code view passes an `exportWorkflow` result, and the AI panel's
16439
+ * code tabs pass `WorkflowProposal.code`. Both download exactly what the
16440
+ * service lifted, through `buildExportDownload`.
16441
+ */
16442
+ const LazyCodeEditorField = lazy(() => import("./code-editor-field-CWGZyNGM.js").then((n) => n.n).then((m) => ({ default: m.CodeEditorField })));
16443
+ function editorLanguageOf(path) {
16444
+ if (path.endsWith(".py")) return "python";
16445
+ if (path.endsWith(".ts")) return "typescript";
16446
+ return "javascript";
16447
+ }
16448
+ function CodeFilesView({ format, result, loading, error, onRetry, download, toolbarStart, notice, hasNode, onShowNode, editorLabel, loadingText, emptyText, save = downloadBlob }) {
16449
+ const tr = useTr();
16450
+ const [picked, setPicked] = useState(null);
16451
+ const selectedPath = picked?.format === format ? picked.path : null;
16452
+ const [downloading, setDownloading] = useState(false);
16453
+ const files = useMemo(() => result ? orderedExportFiles(result.files, format) : [], [result, format]);
16454
+ const shown = files.find((file) => file.path === selectedPath) ?? files[0] ?? null;
16455
+ const shownContent = shown?.content ?? "";
16456
+ const copy = async () => {
16457
+ if (!shown) return;
16458
+ try {
16459
+ await navigator.clipboard.writeText(shownContent);
16460
+ toast.success(tr("fluidgrids.builder.codeView.copied", "Code copied"));
16461
+ } catch (err) {
16462
+ toast.error(tr("fluidgrids.builder.codeView.copyError", "Copy failed"), { description: describeOperationError(err) });
16463
+ }
16464
+ };
16465
+ const startDownload = async () => {
16466
+ if (!result) return;
16467
+ setDownloading(true);
16468
+ try {
16469
+ const { filename, blob } = await buildExportDownload({
16470
+ ...download,
16471
+ files: [...result.files]
16472
+ }, format);
16473
+ save(filename, blob);
16474
+ } catch (err) {
16475
+ toast.error(tr("fluidgrids.builder.codeView.downloadError", "Download failed"), { description: describeOperationError(err) });
16476
+ } finally {
16477
+ setDownloading(false);
16478
+ }
16479
+ };
16480
+ return /* @__PURE__ */ jsxs("div", {
16481
+ className: "flex flex-1 flex-col gap-4",
16482
+ children: [
16483
+ /* @__PURE__ */ jsxs("div", {
16484
+ className: "flex flex-wrap items-center justify-between gap-2",
16485
+ children: [toolbarStart ?? /* @__PURE__ */ jsx("span", {}), /* @__PURE__ */ jsxs("div", {
16486
+ className: "flex items-center gap-2",
16487
+ children: [/* @__PURE__ */ jsxs(Button, {
16488
+ variant: "outline",
16489
+ size: "sm",
16490
+ className: "h-8 gap-1 text-xs",
16491
+ onClick: () => void copy(),
16492
+ disabled: !shown || loading,
16493
+ children: [/* @__PURE__ */ jsx(Icon, {
16494
+ icon: "mynaui:copy",
16495
+ className: "size-3.5"
16496
+ }), tr("fluidgrids.builder.codeView.copy", "Copy")]
16497
+ }), /* @__PURE__ */ jsxs(Button, {
16498
+ variant: "outline",
16499
+ size: "sm",
16500
+ className: "h-8 gap-1 text-xs",
16501
+ onClick: () => void startDownload(),
16502
+ disabled: !result || loading || downloading,
16503
+ "data-testid": "fluidgrids-code-download",
16504
+ children: [/* @__PURE__ */ jsx(Icon, {
16505
+ icon: "mynaui:download",
16506
+ className: "size-3.5"
16507
+ }), tr("fluidgrids.builder.codeView.download", "Download")]
16508
+ })]
16509
+ })]
16510
+ }),
16511
+ notice,
16512
+ loading && !result ? /* @__PURE__ */ jsxs("div", {
16513
+ className: "flex items-center justify-center py-8 text-sm text-muted-foreground",
16514
+ children: [/* @__PURE__ */ jsx(Icon, {
16515
+ icon: "mynaui:spinner",
16516
+ className: "mr-2 size-4 animate-spin"
16517
+ }), loadingText]
16518
+ }) : error ? /* @__PURE__ */ jsxs("div", {
16519
+ className: "py-6 text-sm",
16520
+ role: "alert",
16521
+ children: [/* @__PURE__ */ jsx("p", {
16522
+ className: "text-[var(--color-status-error-text)]",
16523
+ children: error
16524
+ }), /* @__PURE__ */ jsx(Button, {
16525
+ variant: "outline",
16526
+ size: "sm",
16527
+ className: "mt-3",
16528
+ onClick: onRetry,
16529
+ children: tr("fluidgrids.builder.codeView.retry", "Retry")
16530
+ })]
16531
+ }) : result && shown ? /* @__PURE__ */ jsxs(Fragment$1, { children: [
16532
+ files.length > 1 && /* @__PURE__ */ jsx("div", {
16533
+ className: "flex flex-wrap gap-1",
16534
+ role: "group",
16535
+ "aria-label": tr("fluidgrids.builder.codeView.files", "Files"),
16536
+ children: files.map((file) => /* @__PURE__ */ jsx(Button, {
16537
+ variant: file === shown ? "secondary" : "ghost",
16538
+ size: "sm",
16539
+ className: "h-7 font-mono text-[11px]",
16540
+ title: file.path,
16541
+ "aria-pressed": file === shown,
16542
+ onClick: () => setPicked({
16543
+ format,
16544
+ path: file.path
16545
+ }),
16546
+ children: fileBaseName(file.path)
16547
+ }, file.path))
16548
+ }),
16549
+ /* @__PURE__ */ jsxs("div", {
16550
+ className: "flex items-center justify-between gap-2 text-[11px] text-muted-foreground",
16551
+ children: [/* @__PURE__ */ jsx("span", {
16552
+ className: "truncate font-mono",
16553
+ title: shown.path,
16554
+ children: shown.path
16555
+ }), /* @__PURE__ */ jsxs("span", {
16556
+ className: "flex shrink-0 items-center gap-2",
16557
+ children: [/* @__PURE__ */ jsx("span", {
16558
+ className: "font-mono",
16559
+ title: result.irHash,
16560
+ children: result.irHash.slice(0, 19)
16561
+ }), /* @__PURE__ */ jsx(FidelityLevelBadge, { fidelity: result.fidelity })]
16562
+ })]
16563
+ }),
16564
+ /* @__PURE__ */ jsx(Suspense, {
16565
+ fallback: /* @__PURE__ */ jsx("div", {
16566
+ className: "min-h-[260px] rounded-md border border-border bg-muted/30",
16567
+ role: "status",
16568
+ "aria-label": editorLabel
16569
+ }),
16570
+ children: /* @__PURE__ */ jsx(LazyCodeEditorField, {
16571
+ value: shownContent,
16572
+ language: editorLanguageOf(shown.path),
16573
+ label: editorLabel,
16574
+ readOnly: true,
16575
+ minHeight: "260px",
16576
+ maxHeight: "55vh",
16577
+ "data-testid": "fluidgrids-code-editor"
16578
+ })
16579
+ }),
16580
+ /* @__PURE__ */ jsx(FidelityReportList, {
16581
+ fidelity: result.fidelity,
16582
+ source: shownContent,
16583
+ hasNode,
16584
+ onShowNode
16585
+ })
16586
+ ] }) : /* @__PURE__ */ jsx("p", {
16587
+ className: "py-6 text-sm text-muted-foreground",
16588
+ children: emptyText
16589
+ })
16590
+ ]
16591
+ });
16592
+ }
16593
+
16594
+ // src/builder/components/flow-builder/components/ui/ai-draft-code-tabs.tsx
16595
+ /**
16596
+ * The AI panel's *Canvas | TypeScript | Python* tabs (BOFF-9907, PLAN-D D1).
16597
+ *
16598
+ * *Canvas* is the proposal card exactly as before. The code tabs show the
16599
+ * proposed definition lifted by the service (`WorkflowProposal.code`), read
16600
+ * when the tab opens and never from the cache, with its fidelity report and
16601
+ * *Download*. The model never writes the code (DD5): what the tab shows is the
16602
+ * validated proposal, so importing the files gives back the same workflow.
16603
+ *
16604
+ * Rendered only while `fluidgrids.code-first` and `fluidgrids.ai-code` are on
16605
+ * (the panel checks `usePhaseDFlags().aiCode`) and the proposal has a
16606
+ * definition; otherwise the panel renders the card alone, as it always did.
16607
+ */
16608
+ function isDraftTab(value) {
16609
+ return value === "canvas" || value === "TYPESCRIPT" || value === "PYTHON";
16610
+ }
16611
+ /** The version label a lifted proposal carries: it is not a stored version. */
16612
+ const DRAFT_CODE_VERSION = "draft";
16613
+ function AiDraftCodeTabs({ proposal, canvas, save }) {
16614
+ const tr = useTr();
16615
+ const [tab, setTab] = useState("canvas");
16616
+ const format = tab === "canvas" ? "TYPESCRIPT" : tab;
16617
+ const revision = `${proposal.status}:${proposal.updatedAt ?? ""}`;
16618
+ const code = useWorkflowProposalCode(proposal.id, format, tab !== "canvas", revision, tr("fluidgrids.builder.aiDraft.codeLoadFailed", "The code could not be loaded"));
16619
+ return /* @__PURE__ */ jsxs("div", {
16620
+ className: "flex flex-col gap-3",
16621
+ "data-testid": "ai-draft-tabs",
16622
+ children: [/* @__PURE__ */ jsx(Tabs, {
16623
+ value: tab,
16624
+ onValueChange: (value) => {
16625
+ if (isDraftTab(value)) setTab(value);
16626
+ },
16627
+ children: /* @__PURE__ */ jsxs(TabsList, { children: [
16628
+ /* @__PURE__ */ jsx(TabsTrigger, {
16629
+ value: "canvas",
16630
+ "data-testid": "ai-draft-tab-canvas",
16631
+ children: tr("fluidgrids.builder.aiDraft.tabCanvas", "Canvas")
16632
+ }),
16633
+ /* @__PURE__ */ jsx(TabsTrigger, {
16634
+ value: "TYPESCRIPT",
16635
+ "data-testid": "ai-draft-tab-typescript",
16636
+ children: tr("fluidgrids.builder.aiDraft.tabTypescript", "TypeScript")
16637
+ }),
16638
+ /* @__PURE__ */ jsx(TabsTrigger, {
16639
+ value: "PYTHON",
16640
+ "data-testid": "ai-draft-tab-python",
16641
+ children: tr("fluidgrids.builder.aiDraft.tabPython", "Python")
16642
+ })
16643
+ ] })
16644
+ }), tab === "canvas" ? canvas : /* @__PURE__ */ jsxs("div", {
16645
+ "data-testid": "ai-draft-code",
16646
+ children: [/* @__PURE__ */ jsx("p", {
16647
+ className: "mb-3 text-xs text-muted-foreground",
16648
+ children: tr("fluidgrids.builder.aiDraft.codeDescription", "The proposal as code, lifted by FluidGrids from the validated draft. Importing these files gives back the same workflow.")
16649
+ }), /* @__PURE__ */ jsx(CodeFilesView, {
16650
+ format,
16651
+ result: code.data,
16652
+ loading: code.loading,
16653
+ error: code.error,
16654
+ onRetry: () => void code.refetch(),
16655
+ download: {
16656
+ workflowKey: proposal.workflowKey || proposal.name || "workflow",
16657
+ version: DRAFT_CODE_VERSION
16658
+ },
16659
+ editorLabel: tr("fluidgrids.builder.aiDraft.codeEditorLabel", "Proposed workflow code (read-only)"),
16660
+ loadingText: tr("fluidgrids.builder.aiDraft.codeLoading", "Lifting the proposal…"),
16661
+ emptyText: tr("fluidgrids.builder.aiDraft.codeEmpty", "The proposal has no definition to show as code yet."),
16662
+ save
16663
+ })]
16664
+ })]
16665
+ });
16666
+ }
16667
+
16237
16668
  // src/builder/components/flow-builder/components/ui/ai-draft-panel.tsx
16238
16669
  /**
16239
16670
  * AiDraftPanel — "Generate with AI" in the builder (BOFF-4304, BOFF-3662).
@@ -16275,6 +16706,7 @@ function AiDraftPanel({ className, compact = false }) {
16275
16706
  setOpen(true);
16276
16707
  openProposal(proposalId);
16277
16708
  }, [openProposal]), Boolean(workflowKey));
16709
+ const { aiCode } = usePhaseDFlags();
16278
16710
  const [nodes, setNodes, setEdges] = useFlowStore(useShallow((s) => [
16279
16711
  s.workflow.nodes,
16280
16712
  s.actions.nodes.setNodes,
@@ -16367,6 +16799,22 @@ function AiDraftPanel({ className, compact = false }) {
16367
16799
  proposal.reset();
16368
16800
  }, [proposal]);
16369
16801
  const finished = status !== void 0 && status !== "PROCESSING" && status !== "PROPOSED";
16802
+ const proposalCanvas = current ? /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(WorkflowProposalCard, {
16803
+ proposal: current,
16804
+ isDeciding: proposal.isDeciding || reverting,
16805
+ onApply: () => void handleApply(),
16806
+ onReject: () => void handleReject(),
16807
+ onCancel: () => void proposal.cancel(),
16808
+ onOpenWorkflow: openWorkflow,
16809
+ onRevert: (key, version) => void handleRevert(key, version)
16810
+ }), status === "PROPOSED" && !workflowKey && /* @__PURE__ */ jsx(Button, {
16811
+ variant: "ghost",
16812
+ size: "sm",
16813
+ className: "mt-2",
16814
+ "data-testid": "ai-draft-accept",
16815
+ onClick: handlePutOnCanvas,
16816
+ children: tr("fluidgrids.builder.aiDraft.putOnCanvas", "Add to canvas without saving")
16817
+ })] }) : null;
16370
16818
  return /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsxs(Sheet, {
16371
16819
  open,
16372
16820
  onOpenChange: setOpen,
@@ -16465,24 +16913,18 @@ function AiDraftPanel({ className, compact = false }) {
16465
16913
  className: "rounded-md border border-[var(--color-status-error-border)] bg-[var(--color-status-error-bg-subtle)] p-3 text-sm text-[var(--color-status-error-text)]",
16466
16914
  children: proposal.timedOut ? tr("fluidgrids.builder.aiDraft.timedOut", "The draft is taking longer than expected. Try again in a moment.") : proposal.error
16467
16915
  }),
16468
- current && /* @__PURE__ */ jsxs("div", {
16916
+ current && /* @__PURE__ */ jsx("div", {
16469
16917
  "data-testid": "ai-draft-result",
16470
- children: [/* @__PURE__ */ jsx(WorkflowProposalCard, {
16471
- proposal: current,
16472
- isDeciding: proposal.isDeciding || reverting,
16473
- onApply: () => void handleApply(),
16474
- onReject: () => void handleReject(),
16475
- onCancel: () => void proposal.cancel(),
16476
- onOpenWorkflow: openWorkflow,
16477
- onRevert: (key, version) => void handleRevert(key, version)
16478
- }), status === "PROPOSED" && !workflowKey && /* @__PURE__ */ jsx(Button, {
16479
- variant: "ghost",
16480
- size: "sm",
16481
- className: "mt-2",
16482
- "data-testid": "ai-draft-accept",
16483
- onClick: handlePutOnCanvas,
16484
- children: tr("fluidgrids.builder.aiDraft.putOnCanvas", "Add to canvas without saving")
16485
- })]
16918
+ children: aiCode && current.definitionJson ? /* @__PURE__ */ jsx(AiDraftCodeTabs, {
16919
+ proposal: {
16920
+ id: current.id,
16921
+ status: String(current.status),
16922
+ workflowKey: current.workflowKey,
16923
+ name: current.name,
16924
+ updatedAt: current.updatedAt
16925
+ },
16926
+ canvas: proposalCanvas
16927
+ }, current.id) : proposalCanvas
16486
16928
  })
16487
16929
  ]
16488
16930
  })]
@@ -16498,108 +16940,6 @@ function AiDraftPanel({ className, compact = false }) {
16498
16940
  })] });
16499
16941
  }
16500
16942
 
16501
- // src/builder/components/flow-builder/components/ui/code-view-fidelity.tsx
16502
- /**
16503
- * The fidelity report of a code export (BOFF-9904, spec 07 §2), as the
16504
- * builder's Code view shows it: whether lowering the exported code gives the
16505
- * same workflow back, and every item the service reported, each linked to its
16506
- * node on the canvas.
16507
- */
16508
- function FidelityLevelBadge({ fidelity }) {
16509
- const tr = useTr();
16510
- const lossless = isLosslessReport(fidelity);
16511
- return /* @__PURE__ */ jsxs(Badge, {
16512
- variant: lossless ? "secondary" : "destructive",
16513
- "data-testid": "fluidgrids-code-fidelity-level",
16514
- "data-level": lossless ? "lossless" : "lossy",
16515
- className: "gap-1",
16516
- children: [/* @__PURE__ */ jsx(Icon, {
16517
- icon: lossless ? "mynaui:check-circle" : "mynaui:danger-triangle",
16518
- className: "size-3.5"
16519
- }), lossless ? tr("fluidgrids.builder.codeView.lossless", "Lossless") : tr("fluidgrids.builder.codeView.lossy", "Lossy")]
16520
- });
16521
- }
16522
- function FidelityReportList({ fidelity, source, hasNode, onShowNode }) {
16523
- const tr = useTr();
16524
- const items = sortFidelityItems(fidelity.items);
16525
- return /* @__PURE__ */ jsxs("section", {
16526
- "aria-labelledby": "fg-code-fidelity",
16527
- "data-testid": "fluidgrids-code-fidelity",
16528
- className: "space-y-2",
16529
- children: [
16530
- /* @__PURE__ */ jsxs("div", {
16531
- className: "flex items-center justify-between gap-2",
16532
- children: [/* @__PURE__ */ jsx("h3", {
16533
- id: "fg-code-fidelity",
16534
- className: "text-xs font-semibold uppercase tracking-wide text-muted-foreground",
16535
- children: tr("fluidgrids.builder.codeView.fidelityTitle", "Fidelity")
16536
- }), /* @__PURE__ */ jsx(FidelityLevelBadge, { fidelity })]
16537
- }),
16538
- /* @__PURE__ */ jsx("p", {
16539
- className: "text-xs text-muted-foreground",
16540
- children: isLosslessReport(fidelity) ? tr("fluidgrids.builder.codeView.losslessHint", "Lowering this code gives back exactly this workflow.") : tr("fluidgrids.builder.codeView.lossyHint", "Lowering this code does not give back exactly this workflow. The items marked lossy say what differs.")
16541
- }),
16542
- items.length === 0 ? /* @__PURE__ */ jsx("p", {
16543
- className: "text-xs text-muted-foreground",
16544
- children: tr("fluidgrids.builder.codeView.noFidelityItems", "Nothing to report.")
16545
- }) : /* @__PURE__ */ jsx("ul", {
16546
- className: "space-y-1.5",
16547
- children: items.map((item, index) => {
16548
- const lossy = isLossyFidelityItem(item);
16549
- const nodeId = item.nodeId ?? null;
16550
- const line = nodeId && source !== void 0 ? lineOfNode(source, nodeId) : null;
16551
- return /* @__PURE__ */ jsxs("li", {
16552
- "data-testid": "fluidgrids-code-fidelity-item",
16553
- "data-kind": item.kind,
16554
- "data-lossy": lossy ? "true" : "false",
16555
- className: cn("rounded-md border p-2 text-xs", lossy ? "border-[var(--color-status-error-border)] bg-[var(--color-status-error-bg)]" : "border-border bg-muted/30"),
16556
- children: [
16557
- /* @__PURE__ */ jsxs("div", {
16558
- className: "flex flex-wrap items-center gap-1.5",
16559
- children: [
16560
- /* @__PURE__ */ jsx(Badge, {
16561
- variant: lossy ? "destructive" : "outline",
16562
- className: "text-[10px]",
16563
- children: lossy ? tr("fluidgrids.builder.codeView.itemLossy", "Lossy") : tr("fluidgrids.builder.codeView.itemLossless", "Kept")
16564
- }),
16565
- /* @__PURE__ */ jsx("code", {
16566
- className: "font-mono text-[11px] text-card-foreground",
16567
- children: item.kind
16568
- }),
16569
- line !== null && /* @__PURE__ */ jsx("span", {
16570
- className: "text-muted-foreground",
16571
- children: tr("fluidgrids.builder.codeView.itemLine", "line {{line}}", { line: String(line) })
16572
- })
16573
- ]
16574
- }),
16575
- /* @__PURE__ */ jsx("p", {
16576
- className: "mt-1 break-words text-card-foreground",
16577
- children: item.detail
16578
- }),
16579
- item.path && /* @__PURE__ */ jsx("p", {
16580
- className: "mt-0.5 break-all font-mono text-[11px] text-muted-foreground",
16581
- children: item.path
16582
- }),
16583
- nodeId && /* @__PURE__ */ jsxs(Button, {
16584
- variant: "link",
16585
- size: "sm",
16586
- className: "mt-1 h-auto gap-1 p-0 text-xs",
16587
- disabled: !hasNode(nodeId),
16588
- onClick: () => onShowNode(nodeId),
16589
- "data-testid": "fluidgrids-code-fidelity-node",
16590
- children: [/* @__PURE__ */ jsx(Icon, {
16591
- icon: "mynaui:location",
16592
- className: "size-3.5"
16593
- }), tr("fluidgrids.builder.codeView.showNode", "Show node {{nodeId}}", { nodeId })]
16594
- })
16595
- ]
16596
- }, `${item.kind}-${nodeId ?? ""}-${item.path ?? ""}-${index}`);
16597
- })
16598
- })
16599
- ]
16600
- });
16601
- }
16602
-
16603
16943
  // src/builder/components/flow-builder/components/ui/code-view-panel.tsx
16604
16944
  /**
16605
16945
  * CodeViewPanel — the builder's read-only Code view (BOFF-9904, spec 07 §8).
@@ -16613,31 +16953,6 @@ function FidelityReportList({ fidelity, source, hasNode, onShowNode }) {
16613
16953
  * Behind the `fluidgrids.code-first` flag (default off); with the flag off
16614
16954
  * the panel renders nothing and the header is exactly as before.
16615
16955
  */
16616
- const LazyCodeEditorField = lazy(() => import("./code-editor-field-yJZEDJBi.js").then((n) => n.n).then((m) => ({ default: m.CodeEditorField })));
16617
- /** Read-only lifted-code editor with a sized placeholder while its chunk loads. */
16618
- function CodeViewEditor({ content, path, label }) {
16619
- return /* @__PURE__ */ jsx(Suspense, {
16620
- fallback: /* @__PURE__ */ jsx("div", {
16621
- className: "min-h-[260px] rounded-md border border-border bg-muted/30",
16622
- role: "status",
16623
- "aria-label": label
16624
- }),
16625
- children: /* @__PURE__ */ jsx(LazyCodeEditorField, {
16626
- value: content,
16627
- language: editorLanguageOf(path),
16628
- label,
16629
- readOnly: true,
16630
- minHeight: "260px",
16631
- maxHeight: "55vh",
16632
- "data-testid": "fluidgrids-code-editor"
16633
- })
16634
- });
16635
- }
16636
- function editorLanguageOf(path) {
16637
- if (path.endsWith(".py")) return "python";
16638
- if (path.endsWith(".ts")) return "typescript";
16639
- return "javascript";
16640
- }
16641
16956
  function isCodeViewFormat(value) {
16642
16957
  return value === "TYPESCRIPT" || value === "PYTHON";
16643
16958
  }
@@ -16655,8 +16970,6 @@ function CodeViewSheet({ className, compact }) {
16655
16970
  const version = params?.version ?? null;
16656
16971
  const [open, setOpen] = useState(false);
16657
16972
  const [format, setFormat] = useState("TYPESCRIPT");
16658
- const [selectedPath, setSelectedPath] = useState(null);
16659
- const [downloading, setDownloading] = useState(false);
16660
16973
  const { data, loading, error, refetch } = useWorkflowCodeExport({
16661
16974
  workflowKey,
16662
16975
  version,
@@ -16674,10 +16987,6 @@ function CodeViewSheet({ className, compact }) {
16674
16987
  open,
16675
16988
  refetch
16676
16989
  ]);
16677
- const files = useMemo(() => data ? orderedExportFiles(data.files, format) : [], [data, format]);
16678
- const shown = files.find((file) => file.path === selectedPath) ?? files[0] ?? null;
16679
- const shownContent = shown?.content ?? "";
16680
- useEffect(() => setSelectedPath(null), [format]);
16681
16990
  const { fitView } = useReactFlow();
16682
16991
  const nodes = useFlowStore((s) => s.workflow.nodes);
16683
16992
  const onNodesChange = useFlowStore((s) => s.actions.nodes.onNodesChange);
@@ -16709,26 +17018,6 @@ function CodeViewSheet({ className, compact }) {
16709
17018
  showNodePropertiesOf,
16710
17019
  fitView
16711
17020
  ]);
16712
- const copy = async () => {
16713
- if (!shown) return;
16714
- try {
16715
- await navigator.clipboard.writeText(shownContent);
16716
- toast.success(tr("fluidgrids.builder.codeView.copied", "Code copied"));
16717
- } catch (err) {
16718
- toast.error(tr("fluidgrids.builder.codeView.copyError", "Copy failed"), { description: describeOperationError(err) });
16719
- }
16720
- };
16721
- const download = async () => {
16722
- if (!data) return;
16723
- setDownloading(true);
16724
- try {
16725
- await downloadWorkflowCodeExport(data, format);
16726
- } catch (err) {
16727
- toast.error(tr("fluidgrids.builder.codeView.downloadError", "Download failed"), { description: describeOperationError(err) });
16728
- } finally {
16729
- setDownloading(false);
16730
- }
16731
- };
16732
17021
  const label = tr("fluidgrids.builder.codeView.triggerButton", "Code");
16733
17022
  return /* @__PURE__ */ jsxs(Sheet, {
16734
17023
  open,
@@ -16758,120 +17047,44 @@ function CodeViewSheet({ className, compact }) {
16758
17047
  icon: "mynaui:code",
16759
17048
  className: "size-5"
16760
17049
  }), tr("fluidgrids.builder.codeView.title", "Code")]
16761
- }), /* @__PURE__ */ jsx(SheetDescription, { children: tr("fluidgrids.builder.codeView.description", "This version as code, read-only. It is what the FluidGrids CLI pulls; edit the canvas or push code with the CLI to change it.") })] }), /* @__PURE__ */ jsxs("div", {
16762
- className: "mt-4 flex flex-1 flex-col gap-4 pb-6",
16763
- children: [
16764
- /* @__PURE__ */ jsxs("div", {
16765
- className: "flex flex-wrap items-center justify-between gap-2",
16766
- children: [/* @__PURE__ */ jsx(Tabs, {
16767
- value: format,
16768
- onValueChange: (value) => {
16769
- if (isCodeViewFormat(value)) setFormat(value);
16770
- },
16771
- children: /* @__PURE__ */ jsxs(TabsList, { children: [/* @__PURE__ */ jsx(TabsTrigger, {
16772
- value: "TYPESCRIPT",
16773
- "data-testid": "fluidgrids-code-tab-typescript",
16774
- children: tr("fluidgrids.builder.codeView.typescript", "TypeScript")
16775
- }), /* @__PURE__ */ jsx(TabsTrigger, {
16776
- value: "PYTHON",
16777
- "data-testid": "fluidgrids-code-tab-python",
16778
- children: tr("fluidgrids.builder.codeView.python", "Python")
16779
- })] })
16780
- }), /* @__PURE__ */ jsxs("div", {
16781
- className: "flex items-center gap-2",
16782
- children: [/* @__PURE__ */ jsxs(Button, {
16783
- variant: "outline",
16784
- size: "sm",
16785
- className: "h-8 gap-1 text-xs",
16786
- onClick: () => void copy(),
16787
- disabled: !shown || loading,
16788
- children: [/* @__PURE__ */ jsx(Icon, {
16789
- icon: "mynaui:copy",
16790
- className: "size-3.5"
16791
- }), tr("fluidgrids.builder.codeView.copy", "Copy")]
16792
- }), /* @__PURE__ */ jsxs(Button, {
16793
- variant: "outline",
16794
- size: "sm",
16795
- className: "h-8 gap-1 text-xs",
16796
- onClick: () => void download(),
16797
- disabled: !data || loading || downloading,
16798
- children: [/* @__PURE__ */ jsx(Icon, {
16799
- icon: "mynaui:download",
16800
- className: "size-3.5"
16801
- }), tr("fluidgrids.builder.codeView.download", "Download")]
16802
- })]
16803
- })]
17050
+ }), /* @__PURE__ */ jsx(SheetDescription, { children: tr("fluidgrids.builder.codeView.description", "This version as code, read-only. It is what the FluidGrids CLI pulls; edit the canvas or push code with the CLI to change it.") })] }), /* @__PURE__ */ jsx("div", {
17051
+ className: "mt-4 flex flex-1 flex-col pb-6",
17052
+ children: /* @__PURE__ */ jsx(CodeFilesView, {
17053
+ format,
17054
+ result: data,
17055
+ loading,
17056
+ error,
17057
+ onRetry: () => void refetch(),
17058
+ download: {
17059
+ workflowKey: data?.workflowKey ?? workflowKey,
17060
+ version: data?.version ?? version ?? ""
17061
+ },
17062
+ hasNode,
17063
+ onShowNode: showNode,
17064
+ editorLabel: tr("fluidgrids.builder.codeView.editorLabel", "Workflow code (read-only)"),
17065
+ loadingText: tr("fluidgrids.builder.codeView.loading", "Lifting the workflow…"),
17066
+ emptyText: tr("fluidgrids.builder.codeView.empty", "The export returned no files."),
17067
+ toolbarStart: /* @__PURE__ */ jsx(Tabs, {
17068
+ value: format,
17069
+ onValueChange: (value) => {
17070
+ if (isCodeViewFormat(value)) setFormat(value);
17071
+ },
17072
+ children: /* @__PURE__ */ jsxs(TabsList, { children: [/* @__PURE__ */ jsx(TabsTrigger, {
17073
+ value: "TYPESCRIPT",
17074
+ "data-testid": "fluidgrids-code-tab-typescript",
17075
+ children: tr("fluidgrids.builder.codeView.typescript", "TypeScript")
17076
+ }), /* @__PURE__ */ jsx(TabsTrigger, {
17077
+ value: "PYTHON",
17078
+ "data-testid": "fluidgrids-code-tab-python",
17079
+ children: tr("fluidgrids.builder.codeView.python", "Python")
17080
+ })] })
16804
17081
  }),
16805
- dirty && /* @__PURE__ */ jsx("p", {
17082
+ notice: dirty ? /* @__PURE__ */ jsx("p", {
16806
17083
  role: "status",
16807
17084
  className: "rounded-md border border-[var(--color-status-warning-border)] bg-[var(--color-status-warning-bg)] px-3 py-2 text-xs text-[var(--color-status-warning-text)]",
16808
17085
  children: tr("fluidgrids.builder.codeView.unsavedNotice", "You have unsaved changes. The code shows the saved version and updates after the next save.")
16809
- }),
16810
- loading && !data ? /* @__PURE__ */ jsxs("div", {
16811
- className: "flex items-center justify-center py-8 text-sm text-muted-foreground",
16812
- children: [/* @__PURE__ */ jsx(Icon, {
16813
- icon: "mynaui:spinner",
16814
- className: "mr-2 size-4 animate-spin"
16815
- }), tr("fluidgrids.builder.codeView.loading", "Lifting the workflow…")]
16816
- }) : error ? /* @__PURE__ */ jsxs("div", {
16817
- className: "py-6 text-sm",
16818
- role: "alert",
16819
- children: [/* @__PURE__ */ jsx("p", {
16820
- className: "text-[var(--color-status-error-text)]",
16821
- children: error
16822
- }), /* @__PURE__ */ jsx(Button, {
16823
- variant: "outline",
16824
- size: "sm",
16825
- className: "mt-3",
16826
- onClick: () => void refetch(),
16827
- children: tr("fluidgrids.builder.codeView.retry", "Retry")
16828
- })]
16829
- }) : data && shown ? /* @__PURE__ */ jsxs(Fragment$1, { children: [
16830
- files.length > 1 && /* @__PURE__ */ jsx("div", {
16831
- className: "flex flex-wrap gap-1",
16832
- role: "group",
16833
- "aria-label": tr("fluidgrids.builder.codeView.files", "Files"),
16834
- children: files.map((file) => /* @__PURE__ */ jsx(Button, {
16835
- variant: file === shown ? "secondary" : "ghost",
16836
- size: "sm",
16837
- className: "h-7 font-mono text-[11px]",
16838
- title: file.path,
16839
- "aria-pressed": file === shown,
16840
- onClick: () => setSelectedPath(file.path),
16841
- children: fileBaseName(file.path)
16842
- }, file.path))
16843
- }),
16844
- /* @__PURE__ */ jsxs("div", {
16845
- className: "flex items-center justify-between gap-2 text-[11px] text-muted-foreground",
16846
- children: [/* @__PURE__ */ jsx("span", {
16847
- className: "truncate font-mono",
16848
- title: shown.path,
16849
- children: shown.path
16850
- }), /* @__PURE__ */ jsxs("span", {
16851
- className: "flex shrink-0 items-center gap-2",
16852
- children: [/* @__PURE__ */ jsx("span", {
16853
- className: "font-mono",
16854
- title: data.irHash,
16855
- children: data.irHash.slice(0, 19)
16856
- }), /* @__PURE__ */ jsx(FidelityLevelBadge, { fidelity: data.fidelity })]
16857
- })]
16858
- }),
16859
- /* @__PURE__ */ jsx(CodeViewEditor, {
16860
- content: shownContent,
16861
- path: shown.path,
16862
- label: tr("fluidgrids.builder.codeView.editorLabel", "Workflow code (read-only)")
16863
- }),
16864
- /* @__PURE__ */ jsx(FidelityReportList, {
16865
- fidelity: data.fidelity,
16866
- source: shownContent,
16867
- hasNode,
16868
- onShowNode: showNode
16869
- })
16870
- ] }) : /* @__PURE__ */ jsx("p", {
16871
- className: "py-6 text-sm text-muted-foreground",
16872
- children: tr("fluidgrids.builder.codeView.empty", "The export returned no files.")
16873
- })
16874
- ]
17086
+ }) : null
17087
+ })
16875
17088
  })]
16876
17089
  })]
16877
17090
  });
@@ -17736,7 +17949,7 @@ const FlowBuilder = ({ readOnly = false }) => {
17736
17949
  paletteGatesRef.current = paletteGates;
17737
17950
  }, [paletteGates]);
17738
17951
  useWarmBuilderOverlays();
17739
- useLazyAgentTools(() => import("./agentTools-B8gnHFVM.js").then(({ createBuilderAgentTools }) => createBuilderAgentTools({ durableFunctionsEnabled: () => paletteGatesRef.current })), !editingBlocked, "Agent tools");
17952
+ useLazyAgentTools(() => import("./agentTools-BkQsycAp.js").then(({ createBuilderAgentTools }) => createBuilderAgentTools({ durableFunctionsEnabled: () => paletteGatesRef.current })), !editingBlocked, "Agent tools");
17740
17953
  const [nodes, edges, onNodesChange, onEdgesChange, onConnect] = useFlowStore(useShallow((s) => {
17741
17954
  return [
17742
17955
  s.workflow.nodes,
@@ -17778,7 +17991,7 @@ const FlowBuilder = ({ readOnly = false }) => {
17778
17991
  useEffect(() => {
17779
17992
  fitViewRef.current = fitView;
17780
17993
  }, [fitView]);
17781
- useLazyAgentTools(() => import("./canvasNoteTools-Cj7MvVDH.js").then(({ createCanvasNoteTools }) => createCanvasNoteTools({ focusNode: (nodeId) => fitViewRef.current({
17994
+ useLazyAgentTools(() => import("./canvasNoteTools-U7j1z7GR.js").then(({ createCanvasNoteTools }) => createCanvasNoteTools({ focusNode: (nodeId) => fitViewRef.current({
17782
17995
  nodes: [{ id: nodeId }],
17783
17996
  duration: 400,
17784
17997
  padding: .6,