@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,12 +1,14 @@
1
1
  "use client";
2
2
  import { _ as throwIfResultError, n as getFluidGridsClient, x as getFluidGridsConfig } from "./client-C9XSzSXr.js";
3
3
  import { i as getGlobalStoreClient } from "./node-registry-refresh-Dy0uRg9f.js";
4
- import { A as StoreNodeProductsByTypeDocument, C as GetMyNodeInstallationsDocument, D as InstallWorkflowNodeDocument, c as ensureInstalledNodeTypesLoaded, d as ensureRegistryNodeTypesLoaded, i as AVAILABLE_NODES, o as NODE_CONFIGS, t as FluidGridsContext, vn as useFluidGridsAnalytics, x as BrowseWorkflowTemplatesDocument } from "./FluidGridsProvider-B1hgCbxG.js";
4
+ import { A as StoreNodeProductsByTypeDocument, C as GetMyNodeInstallationsDocument, D as InstallWorkflowNodeDocument, c as ensureInstalledNodeTypesLoaded, d as ensureRegistryNodeTypesLoaded, i as AVAILABLE_NODES, o as NODE_CONFIGS, t as FluidGridsContext, vn as useFluidGridsAnalytics, x as BrowseWorkflowTemplatesDocument } from "./FluidGridsProvider-TQ-aDPtn.js";
5
5
  import { r as useTr } from "./TranslationBridge-Da-TPgQm.js";
6
+ import { h as usePhaseDFlags } from "./feature-flags-B_b8PJ6Z.js";
6
7
  import { c as isQuotaExhaustedFailure } from "./quota-Cdt8yz7N.js";
7
8
  import { a as emitTemplateUsed, s as emitWorkflowCreated, t as emitNodeInstalled } from "./fluidgridsEvents-Dm5CaHtr.js";
8
9
  import { t as cn } from "./cn-QqidFIgr.js";
9
10
  import { t as Button } from "./button-DG7y_FVJ.js";
11
+ import { b as utf8Length } from "./workflow-code-transfer-Cshsgf2H.js";
10
12
  import { i as SdkPermissionButton, t as FLUIDGRIDS_PERMISSIONS } from "./constants-dcxg6zG6.js";
11
13
  import React, { Suspense, forwardRef, lazy, useCallback, useContext, useMemo, useState } from "react";
12
14
  import { useQuery } from "@apollo/client/react";
@@ -17,6 +19,7 @@ import { toast } from "sonner";
17
19
  import { useEventBus } from "@burdenoff/fe-libs/shared/events";
18
20
  import { cva } from "class-variance-authority";
19
21
  import { Download, Eye, Sparkles, Star } from "lucide-react";
22
+ import JSZip from "jszip";
20
23
 
21
24
  // src/feature-flags/durable-nodes.ts
22
25
  /**
@@ -567,7 +570,7 @@ function replaceVariables(str, inputs) {
567
570
  }
568
571
 
569
572
  // src/utils/template-import-flow.ts
570
- function isRecord(value) {
573
+ function isRecord$1(value) {
571
574
  return typeof value === "object" && value !== null && !Array.isArray(value);
572
575
  }
573
576
  function graphOf(value) {
@@ -585,13 +588,13 @@ function graphOf(value) {
585
588
  * manifest holds neither.
586
589
  */
587
590
  function manifestTemplateGraph(manifest) {
588
- if (!isRecord(manifest)) return null;
591
+ if (!isRecord$1(manifest)) return null;
589
592
  const direct = graphOf(manifest);
590
593
  if (direct) return direct;
591
594
  if (typeof manifest.jsonContent !== "string") return null;
592
595
  try {
593
596
  const parsed = JSON.parse(manifest.jsonContent);
594
- return isRecord(parsed) ? graphOf(parsed) : null;
597
+ return isRecord$1(parsed) ? graphOf(parsed) : null;
595
598
  } catch {
596
599
  return null;
597
600
  }
@@ -630,9 +633,9 @@ async function resolveTemplateContent(product, requiredNodeTypesOf) {
630
633
  */
631
634
  function unwrapTemplateDefinition(definitionJson) {
632
635
  const data = definitionJson.data;
633
- if (!isRecord(data)) return definitionJson;
634
- const nested = isRecord(data.workflowDefinition) ? data.workflowDefinition.definitionJson : void 0;
635
- return isRecord(nested) ? nested : definitionJson;
636
+ if (!isRecord$1(data)) return definitionJson;
637
+ const nested = isRecord$1(data.workflowDefinition) ? data.workflowDefinition.definitionJson : void 0;
638
+ return isRecord$1(nested) ? nested : definitionJson;
636
639
  }
637
640
  /**
638
641
  * Whether "Use this template" must stop at the configuration dialog before
@@ -673,6 +676,201 @@ async function installNodesInOrder(nodes, install, onProgress, onFailure) {
673
676
  return installed;
674
677
  }
675
678
 
679
+ // src/utils/template-code.ts
680
+ /**
681
+ * Templates as code (BOFF-9907, PLAN-D D2 and C-TEMPLATE).
682
+ *
683
+ * A store WORKFLOW template may carry its project files in `content.sources`
684
+ * next to the `definitionJson` every client installs. These helpers:
685
+ *
686
+ * - read a template's code defensively (store content is free JSON);
687
+ * - package it as a project zip for *Open as code*;
688
+ * - shape it as the `source` of `importWorkflowTemplate` for a tier-2
689
+ * install;
690
+ * - check code before it is published, with the same rules global-store-svc
691
+ * applies on every write (DD3 size guard, path rules, DD7), so a refusal is
692
+ * explained before anything is sent.
693
+ *
694
+ * Nothing here lifts or lowers code: the service does that.
695
+ */
696
+ /** DD3: the largest `content.sources` the store accepts, as UTF-8 JSON. */
697
+ const TEMPLATE_SOURCES_MAX_BYTES = 1048576;
698
+ /** DD3: the most files `content.sources` may hold. */
699
+ const TEMPLATE_SOURCES_MAX_FILES = 64;
700
+ /** The only package a tier-2 template's sources may import (C-TEMPLATE). */
701
+ const TEMPLATE_RUNTIME_PACKAGE = "@fluidgrids/workflows";
702
+ var TemplateCodeError = class extends Error {
703
+ problem;
704
+ constructor(problem) {
705
+ super(`Template code refused: ${problem.code}`);
706
+ this.problem = problem;
707
+ this.name = "TemplateCodeError";
708
+ }
709
+ };
710
+ function isRecord(value) {
711
+ return typeof value === "object" && value !== null && !Array.isArray(value);
712
+ }
713
+ /**
714
+ * Whether a source path is a plain relative POSIX path, as global-store-svc
715
+ * requires: not empty, not absolute, no drive letter, no backslash, no `.`,
716
+ * `..` or empty segment, and no control character.
717
+ */
718
+ function isSafeTemplateSourcePath(path) {
719
+ if (!path || path.startsWith("/") || path.includes("\\")) return false;
720
+ if (/^[A-Za-z]:/.test(path)) return false;
721
+ for (const character of path) {
722
+ const code = character.charCodeAt(0);
723
+ if (code < 32 || code === 127) return false;
724
+ }
725
+ return path.split("/").every((segment) => segment !== "" && segment !== "." && segment !== "..");
726
+ }
727
+ /** Bytes the store counts for a sources list: its UTF-8 JSON. */
728
+ function templateSourcesBytes(sources) {
729
+ return utf8Length(JSON.stringify(sources));
730
+ }
731
+ /**
732
+ * Module specifiers a source imports: static and dynamic `import`, `export
733
+ * … from` and `require`. Comments are not stripped, so a commented-out import
734
+ * is counted too; that only makes the check stricter.
735
+ */
736
+ function importedSpecifiers(source) {
737
+ const found = [];
738
+ for (const pattern of [
739
+ /\b(?:import|export)\s[^'"`;]*?\bfrom\s*['"]([^'"]+)['"]/g,
740
+ /\bimport\s*['"]([^'"]+)['"]/g,
741
+ /\bimport\s*\(\s*['"]([^'"]+)['"]\s*\)/g,
742
+ /\brequire\s*\(\s*['"]([^'"]+)['"]\s*\)/g
743
+ ]) for (const match of source.matchAll(pattern)) if (match[1] !== void 0) found.push(match[1]);
744
+ return found;
745
+ }
746
+ /** A specifier a tier-2 source may use: a project file or the SDK itself. */
747
+ function isAllowedSpecifier(specifier) {
748
+ return specifier.startsWith("./") || specifier.startsWith("../") || specifier === "@fluidgrids/workflows";
749
+ }
750
+ /**
751
+ * Checks sources against the store's rules (and, for tier 2, the import
752
+ * rule). Throws {@link TemplateCodeError} with the first problem found.
753
+ */
754
+ function assertTemplateSources(sources, tier) {
755
+ if (sources.length === 0) throw new TemplateCodeError({ code: "no-files" });
756
+ if (sources.length > 64) throw new TemplateCodeError({
757
+ code: "too-many-files",
758
+ limit: 64
759
+ });
760
+ const seen = /* @__PURE__ */ new Set();
761
+ for (const file of sources) {
762
+ if (!isSafeTemplateSourcePath(file.path)) throw new TemplateCodeError({
763
+ code: "unsafe-path",
764
+ path: file.path
765
+ });
766
+ const folded = file.path.toLowerCase();
767
+ if (seen.has(folded)) throw new TemplateCodeError({
768
+ code: "duplicate-path",
769
+ path: file.path
770
+ });
771
+ seen.add(folded);
772
+ if (tier === "tier2" && /\.[cm]?[jt]s$/.test(file.path)) {
773
+ const foreign = importedSpecifiers(file.content).find((specifier) => !isAllowedSpecifier(specifier));
774
+ if (foreign !== void 0) throw new TemplateCodeError({
775
+ code: "foreign-import",
776
+ path: file.path,
777
+ specifier: foreign
778
+ });
779
+ }
780
+ }
781
+ if (templateSourcesBytes(sources) > 1048576) throw new TemplateCodeError({
782
+ code: "too-large",
783
+ limitBytes: TEMPLATE_SOURCES_MAX_BYTES
784
+ });
785
+ }
786
+ /**
787
+ * A template's code, or null when it has none or what it has is not usable
788
+ * (not a list of files, unsafe paths, an unknown format or tier). The store
789
+ * refuses such content on write; reading defensively keeps a template written
790
+ * before the guard, or by another client, from breaking the page.
791
+ */
792
+ function readTemplateCode(content) {
793
+ if (!content || !Array.isArray(content.sources)) return null;
794
+ const files = [];
795
+ for (const entry of content.sources) {
796
+ if (!isRecord(entry) || typeof entry.path !== "string" || typeof entry.content !== "string") return null;
797
+ files.push({
798
+ path: entry.path,
799
+ contentType: typeof entry.contentType === "string" ? entry.contentType : contentTypeOf(entry.path),
800
+ content: entry.content
801
+ });
802
+ }
803
+ const format = content.sourceFormat ?? "TYPESCRIPT";
804
+ if (format !== "TYPESCRIPT" && format !== "PYTHON") return null;
805
+ const tier = content.codeTier ?? "tier1";
806
+ if (tier !== "tier1" && tier !== "tier2") return null;
807
+ try {
808
+ assertTemplateSources(files, "tier1");
809
+ } catch {
810
+ return null;
811
+ }
812
+ return {
813
+ files,
814
+ format,
815
+ tier,
816
+ irHash: typeof content.sourceIrHash === "string" ? content.sourceIrHash : null
817
+ };
818
+ }
819
+ /** The content type a project file is stored with, by its extension. */
820
+ function contentTypeOf(path) {
821
+ if (/\.[cm]?ts$/.test(path)) return "text/typescript";
822
+ if (/\.[cm]?js$/.test(path)) return "text/javascript";
823
+ if (path.endsWith(".py")) return "text/x-python";
824
+ if (path.endsWith(".json")) return "application/json";
825
+ return "text/plain";
826
+ }
827
+ /** A file name segment that is safe on every OS. */
828
+ function safeSegment(value) {
829
+ return value.toLowerCase().replace(/[^a-z0-9._-]+/g, "-").replace(/^-+|-+$/g, "");
830
+ }
831
+ /** The zip *Open as code* downloads for a template. */
832
+ function templateArchiveName(templateName) {
833
+ return `${safeSegment(templateName) || "template"}.code.zip`;
834
+ }
835
+ /**
836
+ * *Open as code*: the template's project files as one zip that keeps their
837
+ * paths, so unpacking it gives a FluidGrids project (`fluidgrids push`
838
+ * reads it as it is).
839
+ */
840
+ async function buildTemplateCodeDownload(templateName, code) {
841
+ const zip = new JSZip();
842
+ for (const file of code.files) zip.file(file.path, file.content);
843
+ return {
844
+ filename: templateArchiveName(templateName),
845
+ blob: await zip.generateAsync({
846
+ type: "blob",
847
+ mimeType: "application/zip"
848
+ })
849
+ };
850
+ }
851
+ /** The `source` of an `importWorkflowTemplate` for a tier-2 install. */
852
+ function templateImportSource(code) {
853
+ return {
854
+ format: code.format,
855
+ files: code.files.map((file) => ({
856
+ path: file.path,
857
+ content: file.content
858
+ }))
859
+ };
860
+ }
861
+ /**
862
+ * What `importWorkflowTemplate` installs a template from (PLAN-D D2): its
863
+ * sources for a tier-2 TypeScript template while code-first, durable-functions and
864
+ * code-templates are on (`codeTemplatesDurable`), else null, and the caller
865
+ * sends `definitionJson` exactly as before (tier 1, Python, no code, or a
866
+ * gate off).
867
+ */
868
+ function templateInstallSource(content, codeTemplatesDurable) {
869
+ if (!codeTemplatesDurable) return null;
870
+ const code = readTemplateCode(content);
871
+ return code?.tier === "tier2" && code.format === "TYPESCRIPT" ? templateImportSource(code) : null;
872
+ }
873
+
676
874
  // src/hooks/store/useImportWorkflowTemplate.ts
677
875
  const IMPORT_WORKFLOW_TEMPLATE = gql`
678
876
  mutation ImportWorkflowTemplate($input: ImportWorkflowTemplateInput!) {
@@ -739,6 +937,7 @@ function useImportWorkflowTemplate() {
739
937
  const context = useContext(FluidGridsContext);
740
938
  const workspaceId = context?.workspaceId ?? getFluidGridsConfig().workspaceId;
741
939
  const bus = useEventBus();
940
+ const { codeTemplatesDurable } = usePhaseDFlags();
742
941
  const getTemplateDetail = useCallback(async (templateId) => {
743
942
  return fetchTemplateDetail(templateId);
744
943
  }, [fetchTemplateDetail]);
@@ -771,8 +970,9 @@ function useImportWorkflowTemplate() {
771
970
  try {
772
971
  const content = options?.content ?? parseTemplateContent(template);
773
972
  if (!content) throw new Error("Template does not contain valid workflow definition data");
973
+ const installSource = templateInstallSource(content, codeTemplatesDurable);
774
974
  let definitionJson = unwrapTemplateDefinition(deepClone(content.definitionJson));
775
- if (options?.templateInputs) definitionJson = applyTemplateInputs(definitionJson, options.templateInputs);
975
+ if (options?.templateInputs && !installSource) definitionJson = applyTemplateInputs(definitionJson, options.templateInputs);
776
976
  const config = getFluidGridsConfig();
777
977
  const importContext = {
778
978
  ...options?.context || {},
@@ -783,7 +983,7 @@ function useImportWorkflowTemplate() {
783
983
  const importResult = throwIfResultError(await client.mutate({
784
984
  mutation: IMPORT_WORKFLOW_TEMPLATE,
785
985
  variables: { input: {
786
- definitionJson,
986
+ ...installSource ? { source: installSource } : { definitionJson },
787
987
  name: options?.name || content.defaultWorkflowName || template.name,
788
988
  description: options?.description || template.description,
789
989
  sourceTemplateId: template.id,
@@ -830,7 +1030,7 @@ function useImportWorkflowTemplate() {
830
1030
  workspaceId,
831
1031
  workflowId: importResult.workflow.id,
832
1032
  source: "template",
833
- definition: definitionJson
1033
+ definition: installSource ? importResult.workflow.definitionJson : definitionJson
834
1034
  });
835
1035
  emitTemplateUsed(bus, {
836
1036
  workspaceId,
@@ -864,7 +1064,8 @@ function useImportWorkflowTemplate() {
864
1064
  globalClient,
865
1065
  workspaceId,
866
1066
  context?.tenantId,
867
- bus
1067
+ bus,
1068
+ codeTemplatesDurable
868
1069
  ]),
869
1070
  /** Whether we're fetching template detail */
870
1071
  fetchingDetail,
@@ -1080,7 +1281,7 @@ async function dismissToastWhenShown(id) {
1080
1281
  }
1081
1282
 
1082
1283
  // src/hooks/store/useTemplateImportFlow.tsx
1083
- const LazyTemplateConfigurationModal = lazy(() => import("./TemplateConfigurationModal-CeMpPEhT.js").then((m) => ({ default: m.TemplateConfigurationModal })));
1284
+ const LazyTemplateConfigurationModal = lazy(() => import("./TemplateConfigurationModal-Dl_7RaCt.js").then((m) => ({ default: m.TemplateConfigurationModal })));
1084
1285
  /**
1085
1286
  * "Use this template", the same everywhere it is offered: the builder's
1086
1287
  * template panel, the Templates page and the template preview page
@@ -1450,4 +1651,4 @@ function TemplateCard({ template, onClick, onUseTemplate }) {
1450
1651
  });
1451
1652
  }
1452
1653
 
1453
- export { isDurableFunctionNodeType as A, CardFooter as C, RUN_CONTROL_NODE_TYPES as D, DURABLE_FUNCTION_NODE_TYPES as E, isRunControlNodeType as M, WORKFLOW_TEST_NODE_TYPES as O, CardDescription as S, CardTitle as T, storeNodeInstallVersion as _, useTemplateImportFlow as a, Card as b, getWorkflowNodeTypes as c, filterStoreNodesForPalette as d, getStoreNodeAvailability as f, storeNodeDisplayVersion as g, isStoreNodeUpdateAvailable as h, badgeVariants as i, isNodeTypeHiddenFromPalette as j, filterPaletteNodes as k, useImportWorkflowTemplate as l, getStoreNodeType as m, templatePreview as n, buildNodeCheck as o, getStoreNodeIcon as p, Badge as r, buildRequiredNodeTypes as s, TemplateCard as t, useWorkflowTemplates as u, useInstalledNodes as v, CardHeader as w, CardContent as x, useGlobalStoreClient as y };
1654
+ export { WORKFLOW_TEST_NODE_TYPES as A, CardContent as C, CardTitle as D, CardHeader as E, isDurableFunctionNodeType as M, isNodeTypeHiddenFromPalette as N, DURABLE_FUNCTION_NODE_TYPES as O, isRunControlNodeType as P, Card as S, CardFooter as T, isStoreNodeUpdateAvailable as _, useTemplateImportFlow as a, useInstalledNodes as b, getWorkflowNodeTypes as c, readTemplateCode as d, useWorkflowTemplates as f, getStoreNodeType as g, getStoreNodeIcon as h, badgeVariants as i, filterPaletteNodes as j, RUN_CONTROL_NODE_TYPES as k, useImportWorkflowTemplate as l, getStoreNodeAvailability as m, templatePreview as n, buildNodeCheck as o, filterStoreNodesForPalette as p, Badge as r, buildRequiredNodeTypes as s, TemplateCard as t, buildTemplateCodeDownload as u, storeNodeDisplayVersion as v, CardDescription as w, useGlobalStoreClient as x, storeNodeInstallVersion as y };
@@ -1,9 +1,10 @@
1
1
  "use client";
2
2
  import { a as DialogFooter, d as Input, i as DialogDescription, l as DialogTitle, o as DialogHeader, r as DialogContent, t as Dialog } from "./dialog-Cjb4lB4D.js";
3
3
  import { t as Button } from "./button-DG7y_FVJ.js";
4
- import { r as Badge } from "./TemplateCard-DanOe65C.js";
4
+ import { r as Badge } from "./TemplateCard-XBc0qEA4.js";
5
5
  import { t as Label } from "./label-CDy86rIZ.js";
6
6
  import { r as useTr } from "./TranslationBridge-Da-TPgQm.js";
7
+ import { t as OpenTemplateAsCodeButton } from "./OpenTemplateAsCodeButton-BgvgDaVe.js";
7
8
  import { useEffect, useMemo, useState } from "react";
8
9
  import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
9
10
  import { AlertTriangle, CheckCircle2, Download, ExternalLink, KeyRound, Loader2, ShoppingCart, Sparkles } from "lucide-react";
@@ -246,16 +247,24 @@ function TemplateConfigurationModal({ open, onOpenChange, template, content, nod
246
247
  })]
247
248
  }), /* @__PURE__ */ jsxs("div", {
248
249
  className: "flex w-full justify-end gap-2",
249
- children: [/* @__PURE__ */ jsx(Button, {
250
- variant: "outline",
251
- onClick: () => onOpenChange(false),
252
- disabled: importing,
253
- children: tr("fluidgrids.builder.templateConfigModal.cancelButton", "Cancel")
254
- }), /* @__PURE__ */ jsx(Button, {
255
- onClick: handleConfirm,
256
- disabled: !isValid || importing || hasPaidBlockers,
257
- children: importing ? /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(Loader2, { className: "size-4 mr-2 animate-spin" }), buttonLabel] }) : /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(Sparkles, { className: "size-4 mr-2" }), buttonLabel] })
258
- })]
250
+ children: [
251
+ /* @__PURE__ */ jsx(OpenTemplateAsCodeButton, {
252
+ templateName: template.name,
253
+ content,
254
+ className: "mr-auto"
255
+ }),
256
+ /* @__PURE__ */ jsx(Button, {
257
+ variant: "outline",
258
+ onClick: () => onOpenChange(false),
259
+ disabled: importing,
260
+ children: tr("fluidgrids.builder.templateConfigModal.cancelButton", "Cancel")
261
+ }),
262
+ /* @__PURE__ */ jsx(Button, {
263
+ onClick: handleConfirm,
264
+ disabled: !isValid || importing || hasPaidBlockers,
265
+ children: importing ? /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(Loader2, { className: "size-4 mr-2 animate-spin" }), buttonLabel] }) : /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(Sparkles, { className: "size-4 mr-2" }), buttonLabel] })
266
+ })
267
+ ]
259
268
  })]
260
269
  })
261
270
  ]
@@ -1,6 +1,6 @@
1
1
  "use client";
2
2
  import { t as Button } from "./button-DG7y_FVJ.js";
3
- import { n as templatePreview, r as Badge } from "./TemplateCard-DanOe65C.js";
3
+ import { n as templatePreview, r as Badge } from "./TemplateCard-XBc0qEA4.js";
4
4
  import { r as useTr } from "./TranslationBridge-Da-TPgQm.js";
5
5
  import { i as SdkPermissionButton, t as FLUIDGRIDS_PERMISSIONS } from "./constants-dcxg6zG6.js";
6
6
  import { Icon } from "@iconify/react";
@@ -1,9 +1,10 @@
1
1
  "use client";
2
2
  import { t as __exportAll } from "./rolldown-runtime-hDbaFkMy.js";
3
3
  import { t as ThemeProvider } from "./theme-provider-B3mIuz2d.js";
4
- import { t as FlowBuilderPage } from "./flow-builder-dvqpKs8d.js";
5
- import { a as useTemplateImportFlow, l as useImportWorkflowTemplate } from "./TemplateCard-DanOe65C.js";
6
- import { t as QuotaExhaustedDialog } from "./QuotaExhaustedDialog-Bj7AG_0y.js";
4
+ import { t as FlowBuilderPage } from "./flow-builder-9jDNwkID.js";
5
+ import { a as useTemplateImportFlow, l as useImportWorkflowTemplate } from "./TemplateCard-XBc0qEA4.js";
6
+ import { S as QuotaExhaustedDialog } from "./workflow-code-transfer-Cshsgf2H.js";
7
+ import { n as WithOpenTemplateAsCode } from "./OpenTemplateAsCodeButton-BgvgDaVe.js";
7
8
  import { r as useTr } from "./TranslationBridge-Da-TPgQm.js";
8
9
  import { i as SdkPermissionButton, t as FLUIDGRIDS_PERMISSIONS } from "./constants-dcxg6zG6.js";
9
10
  import { t as BILLING_PLANS_PATH } from "./quota-Cdt8yz7N.js";
@@ -52,6 +53,7 @@ function TemplatePreview() {
52
53
  const { getTemplateDetail, parseTemplateContent } = useImportWorkflowTemplate();
53
54
  const [workflow, setWorkflow] = useState(null);
54
55
  const [template, setTemplate] = useState(null);
56
+ const [content, setContent] = useState(null);
55
57
  const [loading, setLoading] = useState(true);
56
58
  const [error, setError] = useState(null);
57
59
  const [showQuotaExhausted, setShowQuotaExhausted] = useState(false);
@@ -86,6 +88,7 @@ function TemplatePreview() {
86
88
  }
87
89
  if (mounted) {
88
90
  setTemplate(full);
91
+ setContent(content);
89
92
  setWorkflow({
90
93
  id: productId,
91
94
  workflowKey: productId,
@@ -158,17 +161,23 @@ function TemplatePreview() {
158
161
  children: template.description
159
162
  }) : null]
160
163
  })]
161
- }), /* @__PURE__ */ jsx(SdkPermissionButton, {
162
- permission: FLUIDGRIDS_PERMISSIONS.WORKFLOW_CREATE,
163
- deniedTooltip: tr("fluidgrids.templates.useDeniedTooltip", "You don't have permission to create workflows from templates"),
164
- children: /* @__PURE__ */ jsxs(Button, {
165
- onClick: handleUse,
166
- disabled: importing || !template,
167
- className: "shrink-0 gap-2",
168
- children: [/* @__PURE__ */ jsx(Icon, {
169
- icon: importing ? "svg-spinners:ring-resize" : "mdi:plus",
170
- className: "size-4"
171
- }), tr("fluidgrids.pages.templatePreview.useThisTemplate", "Use this template")]
164
+ }), /* @__PURE__ */ jsx(WithOpenTemplateAsCode, {
165
+ templateName: template ? template.name : null,
166
+ content,
167
+ className: "shrink-0",
168
+ wrapperClassName: "flex shrink-0 items-center gap-2",
169
+ children: /* @__PURE__ */ jsx(SdkPermissionButton, {
170
+ permission: FLUIDGRIDS_PERMISSIONS.WORKFLOW_CREATE,
171
+ deniedTooltip: tr("fluidgrids.templates.useDeniedTooltip", "You don't have permission to create workflows from templates"),
172
+ children: /* @__PURE__ */ jsxs(Button, {
173
+ onClick: handleUse,
174
+ disabled: importing || !template,
175
+ className: "shrink-0 gap-2",
176
+ children: [/* @__PURE__ */ jsx(Icon, {
177
+ icon: importing ? "svg-spinners:ring-resize" : "mdi:plus",
178
+ className: "size-4"
179
+ }), tr("fluidgrids.pages.templatePreview.useThisTemplate", "Use this template")]
180
+ })
172
181
  })
173
182
  })]
174
183
  }), /* @__PURE__ */ jsx("div", {
@@ -1,12 +1,12 @@
1
1
  "use client";
2
2
  import { t as __exportAll } from "./rolldown-runtime-hDbaFkMy.js";
3
- import { h as useWorkflowDefinitions, l as useLazyWorkflowDefinition, s as useDuplicateWorkflow } from "./useWorkflows-CP-d3ygY.js";
4
- import { a as useTemplateImportFlow, t as TemplateCard, u as useWorkflowTemplates, y as useGlobalStoreClient } from "./TemplateCard-DanOe65C.js";
3
+ import { h as useWorkflowDefinitions, l as useLazyWorkflowDefinition, s as useDuplicateWorkflow } from "./useWorkflows-CRUlQBd3.js";
4
+ import { a as useTemplateImportFlow, f as useWorkflowTemplates, t as TemplateCard, x as useGlobalStoreClient } from "./TemplateCard-XBc0qEA4.js";
5
5
  import { kI as WorkflowStatus } from "./graphql-types-v6CTGwA0.js";
6
6
  import { i as SdkPermissionButton, t as FLUIDGRIDS_PERMISSIONS } from "./constants-dcxg6zG6.js";
7
- import { t as QuotaExhaustedDialog } from "./QuotaExhaustedDialog-Bj7AG_0y.js";
7
+ import { S as QuotaExhaustedDialog } from "./workflow-code-transfer-Cshsgf2H.js";
8
8
  import { r as useTr } from "./TranslationBridge-Da-TPgQm.js";
9
- import { O as MyWorkflowTemplateSubmissionsDocument, P as WithdrawWorkflowTemplateSubmissionDocument, j as SubmitWorkflowTemplateDocument, vn as useFluidGridsAnalytics } from "./FluidGridsProvider-B1hgCbxG.js";
9
+ import { O as MyWorkflowTemplateSubmissionsDocument, P as WithdrawWorkflowTemplateSubmissionDocument, j as SubmitWorkflowTemplateDocument, vn as useFluidGridsAnalytics } from "./FluidGridsProvider-TQ-aDPtn.js";
10
10
  import { a as emitTemplateUsed } from "./fluidgridsEvents-Dm5CaHtr.js";
11
11
  import { n as useFluidGridsPageControls } from "./pageControlsBridge-0pX9s-3k.js";
12
12
  import { r as templatesControls } from "./pageControlSpecs-DZJ9K37m.js";
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
  import { r as useTr } from "./TranslationBridge-Da-TPgQm.js";
3
3
  import { _ as throwIfResultError, m as describeOperationError, n as getFluidGridsClient } from "./client-C9XSzSXr.js";
4
- import { Or as WorkflowDefinitionDocument, xi as WorkflowVersionDiffDocument } from "./graphql-operation-types-z2oXfQvM.js";
4
+ import { Or as WorkflowDefinitionDocument, Si as WorkflowVersionDiffDocument } from "./graphql-operation-types-DZVhCBEi.js";
5
5
  import { t as canvasFromDefinition } from "./definition-canvas-Bshn_dSP.js";
6
6
  import { memo, useCallback, useEffect, useMemo, useRef, useState } from "react";
7
7
  import { Background, Controls, Handle, MiniMap, Position, ReactFlow, ReactFlowProvider } from "@xyflow/react";
@@ -1,18 +1,18 @@
1
1
  "use client";
2
2
  import { t as __exportAll } from "./rolldown-runtime-hDbaFkMy.js";
3
- import { d as releaseLeaseKeptForReload, f as useWorkflowReloadStore, t as FlowBuilderPage } from "./flow-builder-dvqpKs8d.js";
3
+ import { d as releaseLeaseKeptForReload, f as useWorkflowReloadStore, t as FlowBuilderPage } from "./flow-builder-9jDNwkID.js";
4
4
  import { n as registerLiveCanvasHandler } from "./liveCanvas-D5ytXDp8.js";
5
5
  import { _ as throwIfResultError, n as getFluidGridsClient, x as getFluidGridsConfig } from "./client-C9XSzSXr.js";
6
- import { Or as WorkflowDefinitionDocument } from "./graphql-operation-types-z2oXfQvM.js";
6
+ import { Or as WorkflowDefinitionDocument } from "./graphql-operation-types-DZVhCBEi.js";
7
7
  import { r as useTr } from "./TranslationBridge-Da-TPgQm.js";
8
- import { B as createConfiguredNode, Dt as blankWorkflowCreateInput, Nt as useSaveStatusStore, Z as paramsFromOperation, Zt as rememberRevision, g as registerWorkflowNodeTypes, gn as resolveNodeOperation, h as registerNodeManifests, kt as classifyCreateRefusal, m as refetchStoreNodes, nn as codeBuildIdOf, o as NODE_CONFIGS, sn as workflowFingerprint, u as ensureNodeTypesLoaded } from "./FluidGridsProvider-B1hgCbxG.js";
8
+ import { B as createConfiguredNode, Dt as blankWorkflowCreateInput, Nt as useSaveStatusStore, Z as paramsFromOperation, Zt as rememberRevision, g as registerWorkflowNodeTypes, gn as resolveNodeOperation, h as registerNodeManifests, kt as classifyCreateRefusal, m as refetchStoreNodes, nn as codeBuildIdOf, o as NODE_CONFIGS, sn as workflowFingerprint, u as ensureNodeTypesLoaded } from "./FluidGridsProvider-TQ-aDPtn.js";
9
9
  import { F as mergeStickyNotes, H as useFlowStore } from "./node-operation-selection-DAbS6jSY.js";
10
10
  import { t as canvasFromDefinition } from "./definition-canvas-Bshn_dSP.js";
11
- import { l as useLazyWorkflowDefinition, n as useCreateWorkflow } from "./useWorkflows-CP-d3ygY.js";
12
- import { c as getWorkflowNodeTypes, o as buildNodeCheck, s as buildRequiredNodeTypes, v as useInstalledNodes } from "./TemplateCard-DanOe65C.js";
11
+ import { l as useLazyWorkflowDefinition, n as useCreateWorkflow } from "./useWorkflows-CRUlQBd3.js";
12
+ import { b as useInstalledNodes, c as getWorkflowNodeTypes, o as buildNodeCheck, s as buildRequiredNodeTypes } from "./TemplateCard-XBc0qEA4.js";
13
13
  import { c as withoutGuidedTourIntent, l as decideMissingWorkflow, o as isGuidedTourIntent, s as pickGuidedTour, u as isCreateIntent } from "./firstWorkflow-C_h0KMB2.js";
14
14
  import { t as BILLING_PLANS_PATH } from "./quota-Cdt8yz7N.js";
15
- import { A as CreateWorkflowRefusalDialog } from "./useWorkflowCodeExport-D0zapXXm.js";
15
+ import { c as CreateWorkflowRefusalDialog } from "./useWorkflowCodeExport-k5Emm4ZS.js";
16
16
  import { Suspense, lazy, useCallback, useEffect, useMemo, useRef, useState } from "react";
17
17
  import { useLocation, useNavigate, useParams } from "react-router";
18
18
  import { Icon } from "@iconify/react";
@@ -1088,7 +1088,7 @@ function GuidedTourStarter({ ready }) {
1088
1088
  }
1089
1089
 
1090
1090
  // src/builder/app/workflow/work/page.tsx
1091
- const LazyMissingNodesInstallModal = lazy(() => import("./MissingNodesInstallModal-BkkgeFeN.js").then((m) => ({ default: m.MissingNodesInstallModal })));
1091
+ const LazyMissingNodesInstallModal = lazy(() => import("./MissingNodesInstallModal-BCbhddk4.js").then((m) => ({ default: m.MissingNodesInstallModal })));
1092
1092
  function WorkflowItem({ readonly = false }) {
1093
1093
  if (readonly) {
1094
1094
  const queryParams = new URLSearchParams(window.location.search);
@@ -1160,7 +1160,7 @@ function WorkflowItem({ readonly = false }) {
1160
1160
  setInstallErrors([]);
1161
1161
  try {
1162
1162
  const { getGlobalStoreClient } = await import("./node-registry-refresh-Dy0uRg9f.js").then((n) => n.a);
1163
- const { InstallWorkflowNodeDocument } = await import("./FluidGridsProvider-B1hgCbxG.js").then((n) => n.y);
1163
+ const { InstallWorkflowNodeDocument } = await import("./FluidGridsProvider-TQ-aDPtn.js").then((n) => n.y);
1164
1164
  const { getFluidGridsConfig } = await import("./client-C9XSzSXr.js").then((n) => n.b);
1165
1165
  const storeClient = getGlobalStoreClient();
1166
1166
  const cfg = getFluidGridsConfig();
@@ -1,12 +1,12 @@
1
1
  "use client";
2
- import { bn as useCanvasEdges, n as FluidGridsProvider } from "./FluidGridsProvider-B1hgCbxG.js";
2
+ import { bn as useCanvasEdges, n as FluidGridsProvider } from "./FluidGridsProvider-TQ-aDPtn.js";
3
3
  import { H as useFlowStore } from "./node-operation-selection-DAbS6jSY.js";
4
4
  import { t as Button } from "./button-DG7y_FVJ.js";
5
5
  import { d as Input } from "./dialog-Cjb4lB4D.js";
6
- import { b as Card } from "./TemplateCard-DanOe65C.js";
6
+ import { S as Card } from "./TemplateCard-XBc0qEA4.js";
7
7
  import { t as cn } from "./cn-QqidFIgr.js";
8
8
  import { r as useTr } from "./TranslationBridge-Da-TPgQm.js";
9
- import { _ as useNodeSelectedEvent, v as FluidGridsMark } from "./flow-builder-dvqpKs8d.js";
9
+ import { _ as useNodeSelectedEvent, v as FluidGridsMark } from "./flow-builder-9jDNwkID.js";
10
10
  import { useCallback, useEffect, useRef, useState } from "react";
11
11
  import { Background, Controls, Handle, MarkerType, MiniMap, Position, ReactFlow, ReactFlowProvider, useReactFlow } from "@xyflow/react";
12
12
  import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
  import { _ as throwIfResultError, h as isForbiddenError, n as getFluidGridsClient } from "./client-C9XSzSXr.js";
3
3
  import { r as useTr } from "./TranslationBridge-Da-TPgQm.js";
4
- import { C as CancelWorkflowProposalDocument, Gt as ProposeRunFixDocument, Kr as WorkflowProposalDocument, Kt as ProposeWorkflowChangeDocument, L as CreateWorkflowTestCaseDocument, R as CreateWorkflowTestCaseFromRunDocument, Z as DeleteWorkflowTestCaseDocument, Zt as RejectWorkflowProposalDocument, _i as WorkflowTestRunDocument, c as ApplyWorkflowProposalDocument, fr as UpdateWorkflowTestCaseDocument, gi as WorkflowTestCasesDocument, wn as RunWorkflowTestsDocument, yi as WorkflowTestRunsDocument } from "./graphql-operation-types-z2oXfQvM.js";
4
+ import { C as CancelWorkflowProposalDocument, Gt as ProposeRunFixDocument, Kt as ProposeWorkflowChangeDocument, L as CreateWorkflowTestCaseDocument, R as CreateWorkflowTestCaseFromRunDocument, Z as DeleteWorkflowTestCaseDocument, Zt as RejectWorkflowProposalDocument, _i as WorkflowTestCasesDocument, bi as WorkflowTestRunsDocument, c as ApplyWorkflowProposalDocument, fr as UpdateWorkflowTestCaseDocument, qr as WorkflowProposalDocument, vi as WorkflowTestRunDocument, wn as RunWorkflowTestsDocument } from "./graphql-operation-types-DZVhCBEi.js";
5
5
  import { MI as WorkflowTestExpectedStatus, NI as WorkflowTestRunSource, PI as WorkflowTestRunStatus, jI as WorkflowTestAssertionOperator, jd as ErrorType } from "./graphql-types-v6CTGwA0.js";
6
6
  import { a as notifyFluidGridsAiCreditsUpdated } from "./aiCreditsBridge-BuE92tKo.js";
7
7
  import { useCallback, useEffect, useRef, useState } from "react";
@@ -1,6 +1,6 @@
1
1
  "use client";
2
2
  import { t as __exportAll } from "./rolldown-runtime-hDbaFkMy.js";
3
- import { m as useWorkflowDefinition } from "./useWorkflows-CP-d3ygY.js";
3
+ import { m as useWorkflowDefinition } from "./useWorkflows-CRUlQBd3.js";
4
4
  import { Navigate, useParams } from "react-router";
5
5
  import { Icon } from "@iconify/react";
6
6
  import { jsx, jsxs } from "react/jsx-runtime";
@@ -3,7 +3,7 @@ import { t as __exportAll } from "./rolldown-runtime-hDbaFkMy.js";
3
3
  import { n as getFluidGridsClient } from "./client-C9XSzSXr.js";
4
4
  import { r as useTr } from "./TranslationBridge-Da-TPgQm.js";
5
5
  import { DI as WorkflowSharePrincipalType, II as WorkflowVisibility, JF as WorkflowAccess, OI as WorkflowShareRole } from "./graphql-types-v6CTGwA0.js";
6
- import { Pn as ShareWorkflowDocument, di as WorkflowSharingDocument } from "./graphql-operation-types-z2oXfQvM.js";
6
+ import { Pn as ShareWorkflowDocument, fi as WorkflowSharingDocument } from "./graphql-operation-types-DZVhCBEi.js";
7
7
  import { useMemo } from "react";
8
8
  import { jsx } from "react/jsx-runtime";
9
9
  import { ResourceShareDialog, createSharePrincipalLister } from "@burdenoff/fe-libs/connections";
@@ -1,20 +1,21 @@
1
1
  "use client";
2
2
  import { t as __exportAll } from "./rolldown-runtime-hDbaFkMy.js";
3
- import { c as useImportWorkflow, h as useWorkflowDefinitions, l as useLazyWorkflowDefinition, n as useCreateWorkflow, o as useDeleteWorkflow, s as useDuplicateWorkflow, u as usePreviewN8nImport } from "./useWorkflows-CP-d3ygY.js";
4
- import { At as createThenOpen, t as FluidGridsContext } from "./FluidGridsProvider-B1hgCbxG.js";
5
- import { A as CreateWorkflowRefusalDialog, D as typeScriptImportSource, O as typeScriptModuleFile, T as readProjectArchive, a as parseWorkflowImport, c as saveWorkflowDescription, d as CODE_EXPORT_FORMATS, f as ImportSourceError, g as checkTypeScriptImport, h as assertImportByteSize, i as downloadWorkflowExport, k as workflowNameFromFile, l as visibleWorkflowDescription, m as MAX_IMPORT_SOURCE_BYTES, n as useExportWorkflowAs, o as commitWorkflowDescription, p as MAX_IMPORT_ARCHIVE_BYTES, u as workflowDescriptionCharactersLeft, v as importAcceptAttribute, w as primaryImportModule, y as importFileKind } from "./useWorkflowCodeExport-D0zapXXm.js";
3
+ import { c as useImportWorkflow, h as useWorkflowDefinitions, l as useLazyWorkflowDefinition, n as useCreateWorkflow, o as useDeleteWorkflow, s as useDuplicateWorkflow, u as usePreviewN8nImport } from "./useWorkflows-CRUlQBd3.js";
4
+ import { At as createThenOpen, t as FluidGridsContext } from "./FluidGridsProvider-TQ-aDPtn.js";
5
+ import { a as saveWorkflowDescription, c as CreateWorkflowRefusalDialog, o as visibleWorkflowDescription, r as commitWorkflowDescription, s as workflowDescriptionCharactersLeft, t as useExportWorkflowAs } from "./useWorkflowCodeExport-k5Emm4ZS.js";
6
6
  import { c as isQuotaExhaustedFailure, t as BILLING_PLANS_PATH } from "./quota-Cdt8yz7N.js";
7
7
  import { H as useFlowStore } from "./node-operation-selection-DAbS6jSY.js";
8
8
  import { a as SdkPermissionGate, i as SdkPermissionButton, s as useFluidGridsPermission, t as FLUIDGRIDS_PERMISSIONS } from "./constants-dcxg6zG6.js";
9
- import { t as QuotaExhaustedDialog } from "./QuotaExhaustedDialog-Bj7AG_0y.js";
9
+ import { S as QuotaExhaustedDialog, a as assertImportByteSize, g as readProjectArchive, h as primaryImportModule, i as MAX_IMPORT_SOURCE_BYTES, l as importAcceptAttribute, n as ImportSourceError, r as MAX_IMPORT_ARCHIVE_BYTES, s as checkTypeScriptImport, t as CODE_EXPORT_FORMATS, u as importFileKind, v as typeScriptImportSource, x as workflowNameFromFile, y as typeScriptModuleFile } from "./workflow-code-transfer-Cshsgf2H.js";
10
10
  import { r as useTr } from "./TranslationBridge-Da-TPgQm.js";
11
11
  import { YF as WorkflowAccessFilter, rI as WorkflowExportFormat } from "./graphql-types-v6CTGwA0.js";
12
- import { i as canShareWorkflow, r as canEditWorkflow, t as WorkflowShareDialog } from "./WorkflowShareDialog-DB-qJLB2.js";
12
+ import { i as canShareWorkflow, r as canEditWorkflow, t as WorkflowShareDialog } from "./WorkflowShareDialog-BRwTF9QB.js";
13
13
  import { i as useOpenRequest, n as ACTION_PARAM_VALUES, r as useActionParam } from "./useActionParam-B0ebTZmg.js";
14
- import { l as useFluidGridsFlag, t as FLUIDGRIDS_FLAGS } from "./feature-flags-DM5myWaD.js";
14
+ import { d as useFluidGridsFlag, t as FLUIDGRIDS_FLAGS } from "./feature-flags-B_b8PJ6Z.js";
15
+ import { n as downloadWorkflowExport, r as parseWorkflowImport } from "./workflow-transfer-CQnQC-ke.js";
15
16
  import { _ as throwIfResultError, m as describeOperationError, n as getFluidGridsClient } from "./client-C9XSzSXr.js";
16
- import { Dt as MoveWorkflowFolderDocument, Fr as WorkflowFoldersDocument, J as DeleteWorkflowProjectDocument, N as CreateWorkflowFolderDocument, P as CreateWorkflowProjectDocument, Wr as WorkflowProjectsDocument, _ as BulkDeleteWorkflowsDocument, en as RenameWorkflowFolderDocument, g as BulkAssignWorkflowsToProjectDocument, q as DeleteWorkflowFolderDocument, tn as RenameWorkflowProjectDocument, v as BulkMoveWorkflowsToFolderDocument } from "./graphql-operation-types-z2oXfQvM.js";
17
- import { a as useExecutions } from "./useExecutions-DJXtbA15.js";
17
+ import { Dt as MoveWorkflowFolderDocument, Fr as WorkflowFoldersDocument, J as DeleteWorkflowProjectDocument, N as CreateWorkflowFolderDocument, P as CreateWorkflowProjectDocument, Wr as WorkflowProjectsDocument, _ as BulkDeleteWorkflowsDocument, en as RenameWorkflowFolderDocument, g as BulkAssignWorkflowsToProjectDocument, q as DeleteWorkflowFolderDocument, tn as RenameWorkflowProjectDocument, v as BulkMoveWorkflowsToFolderDocument } from "./graphql-operation-types-DZVhCBEi.js";
18
+ import { a as useExecutions } from "./useExecutions-BbkBSYpS.js";
18
19
  import { a as firstWorkflowProgress, i as builderPathFor, r as GUIDED_TOUR_STATE } from "./firstWorkflow-C_h0KMB2.js";
19
20
  import { n as useFluidGridsPageControls } from "./pageControlsBridge-0pX9s-3k.js";
20
21
  import { i as workflowsListControls } from "./pageControlSpecs-DZJ9K37m.js";
@@ -1,8 +1,8 @@
1
1
  "use client";
2
- import { B as createConfiguredNode, Nt as useSaveStatusStore, Q as selectedOperationOf, R as SENSITIVE_PARAM, Y as nodeTitle, Z as paramsFromOperation, _ as registryNodeData, f as isNodeConfigsInitialized, gt as autosaveAllowedFor, o as NODE_CONFIGS, q as fixedParameterState, wt as isFlowComplete } from "./FluidGridsProvider-B1hgCbxG.js";
2
+ import { B as createConfiguredNode, Nt as useSaveStatusStore, Q as selectedOperationOf, R as SENSITIVE_PARAM, Y as nodeTitle, Z as paramsFromOperation, _ as registryNodeData, f as isNodeConfigsInitialized, gt as autosaveAllowedFor, o as NODE_CONFIGS, q as fixedParameterState, wt as isFlowComplete } from "./FluidGridsProvider-TQ-aDPtn.js";
3
3
  import { E as resolveOutputHandles, H as useFlowStore, T as resolveInputHandles } from "./node-operation-selection-DAbS6jSY.js";
4
- import { j as isNodeTypeHiddenFromPalette } from "./TemplateCard-DanOe65C.js";
5
- import { g as computeAttachPosition } from "./flow-builder-dvqpKs8d.js";
4
+ import { N as isNodeTypeHiddenFromPalette } from "./TemplateCard-XBc0qEA4.js";
5
+ import { g as computeAttachPosition } from "./flow-builder-9jDNwkID.js";
6
6
  import { AgentToolError, defineAgentTool } from "@burdenoff/fe-libs/shared/agent-tools";
7
7
  import { z } from "zod";
8
8
 
@@ -1,6 +1,6 @@
1
1
  "use client";
2
2
  import { d as readTyped, f as writeTyped } from "./shared-CMfn30xT.js";
3
- import { A as CreateTaskQueueDocument, G as DeleteWorkerTokenDocument, Gn as TaskQueueStatsDocument, Kn as TaskQueuesDocument, Ti as WorkflowWorkersDocument, W as DeleteTaskQueueDocument, fn as RotateWorkerTokenDocument, gr as WorkerTokensDocument, j as CreateWorkerTokenDocument, jn as SetWorkerTokenConnectionAllowlistDocument, sr as UpdateTaskQueueDocument } from "./graphql-operation-types-z2oXfQvM.js";
3
+ import { A as CreateTaskQueueDocument, Ei as WorkflowWorkersDocument, G as DeleteWorkerTokenDocument, Gn as TaskQueueStatsDocument, Kn as TaskQueuesDocument, W as DeleteTaskQueueDocument, fn as RotateWorkerTokenDocument, gr as WorkerTokensDocument, j as CreateWorkerTokenDocument, jn as SetWorkerTokenConnectionAllowlistDocument, sr as UpdateTaskQueueDocument } from "./graphql-operation-types-DZVhCBEi.js";
4
4
 
5
5
  // src/modules/task-queues/api.ts
6
6
  /**