@burdenoff/fluidgrids-fe-sdk 2026.1014.13 → 2026.1016.1

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.
@@ -1,7 +1,7 @@
1
- export { ExecutionDetailPage } from './chunk-IPNGNROQ.js';
1
+ export { ExecutionDetailPage } from './chunk-PF6MKIOS.js';
2
2
  import './chunk-NM5TH27W.js';
3
3
  import './chunk-QBFAJNUC.js';
4
- import './chunk-SYU74PMY.js';
4
+ import './chunk-ONVGFVNH.js';
5
5
  import './chunk-JL7CASN5.js';
6
6
  import './chunk-D3UWK7GY.js';
7
7
  import './chunk-UZG3ZIQM.js';
@@ -1,6 +1,6 @@
1
- export { WorkflowBuilder } from './chunk-CHVYBESW.js';
1
+ export { WorkflowBuilder } from './chunk-3UAUUUUL.js';
2
2
  import './chunk-6N27YGMB.js';
3
- import './chunk-ZJ6HKHFX.js';
3
+ import './chunk-5O4QSCWG.js';
4
4
  import './chunk-GEMNVFPK.js';
5
5
  import './chunk-IEVSFCFS.js';
6
6
  import './chunk-7LSGGJ7D.js';
@@ -8,7 +8,7 @@ import './chunk-GDAFKRQO.js';
8
8
  import './chunk-SQFFJUAT.js';
9
9
  import './chunk-PXIFUMLA.js';
10
10
  import './chunk-FZBGMZRM.js';
11
- import './chunk-SYU74PMY.js';
11
+ import './chunk-ONVGFVNH.js';
12
12
  import './chunk-JL7CASN5.js';
13
13
  import './chunk-IYTHK7B5.js';
14
14
  import './chunk-UZG3ZIQM.js';
@@ -1,7 +1,7 @@
1
- export { WorkflowsList } from './chunk-JNARGGYF.js';
1
+ export { WorkflowsList } from './chunk-TILF7THS.js';
2
2
  import './chunk-6N27YGMB.js';
3
3
  import './chunk-SQFFJUAT.js';
4
- import './chunk-SYU74PMY.js';
4
+ import './chunk-ONVGFVNH.js';
5
5
  import './chunk-JL7CASN5.js';
6
6
  import './chunk-IYTHK7B5.js';
7
7
  import './chunk-D3UWK7GY.js';
@@ -1,5 +1,5 @@
1
1
  import { isCreateIntent, decideMissingWorkflow } from './chunk-6N27YGMB.js';
2
- import { useInstalledNodes, buildNodeCheck, refetchStoreNodes, FlowBuilderPage, buildRequiredNodeTypes, mergeStickyNotes } from './chunk-ZJ6HKHFX.js';
2
+ import { useInstalledNodes, buildNodeCheck, refetchStoreNodes, FlowBuilderPage, buildRequiredNodeTypes, mergeStickyNotes } from './chunk-5O4QSCWG.js';
3
3
  import { useLazyWorkflowDefinition, useCreateWorkflow } from './chunk-IYTHK7B5.js';
4
4
  import { useFlowStore } from './chunk-PYQHV2NT.js';
5
5
  import { useTr } from './chunk-UULVIT25.js';
@@ -5,7 +5,7 @@ import { Badge as Badge$1, Button as Button$1 } from './chunk-GDAFKRQO.js';
5
5
  import { QuotaExhaustedDialog } from './chunk-SQFFJUAT.js';
6
6
  import { getGlobalStoreClient, createGlobalStoreClient, setGlobalStoreClient, resetGlobalStoreClient } from './chunk-PXIFUMLA.js';
7
7
  import { GetMyNodeInstallationsDocument, BrowseWorkflowTemplatesDocument, InstallWorkflowNodeDocument, InstallPurchasedNodeDocument, BrowseWorkflowNodesDocument, UninstallWorkflowNodeDocument, CreateStoreOrderDocument, GetNodeInstallableVersionsDocument } from './chunk-FZBGMZRM.js';
8
- import { SdkPermissionGate, FLUIDGRIDS_PERMISSIONS, SdkPermissionButton } from './chunk-SYU74PMY.js';
8
+ import { SdkPermissionGate, FLUIDGRIDS_PERMISSIONS, SdkPermissionButton } from './chunk-ONVGFVNH.js';
9
9
  import { cn as cn$1 } from './chunk-JL7CASN5.js';
10
10
  import { useWorkflowVersions, useRestoreWorkflowVersion, useActivateWorkflow, useDeleteWorkflow, useLazyWorkflowDefinition, useDeactivateWorkflow } from './chunk-IYTHK7B5.js';
11
11
  import { config, getFluidGridsConfig, validateTrustedOrigin, resetFluidGridsExecutionState, setFluidGridsConfig, resetFluidGridsConfig } from './chunk-UZG3ZIQM.js';
@@ -16,7 +16,7 @@ import { useTr, FluidGridsTranslationProvider, ENGLISH_FALLBACK_TRANSLATOR } fro
16
16
  import { waitForFluidGridsClient, getFluidGridsClient, getFluidGridsClientSafe, createFluidGridsClient, setFluidGridsClient, resetFluidGridsClient } from './chunk-NTWG3CJX.js';
17
17
  import * as React2 from 'react';
18
18
  import React2__default, { forwardRef, useState, useImperativeHandle, useRef, useEffect, useMemo, memo, createContext, lazy, useCallback, useSyncExternalStore, useContext, useLayoutEffect, Suspense, useDeferredValue, useId } from 'react';
19
- import { Textarea, Input, Button, Card, Badge, CardContent as CardContent$1, Dialog, DialogTrigger, DialogContent, DialogHeader, DialogTitle, DialogDescription, DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuLabel, DropdownMenuItem, DropdownMenuSeparator, Sheet, SheetTrigger, SheetContent, SheetHeader, SheetTitle, TooltipProvider, AlertDialog, AlertDialogContent, AlertDialogHeader, AlertDialogTitle, AlertDialogDescription, AlertDialogFooter, AlertDialogCancel, AlertDialogAction, Popover, PopoverTrigger, PopoverContent, Tooltip, TooltipTrigger, TooltipContent, Toaster, Tabs, TabsList, TabsTrigger, TabsContent, CardHeader as CardHeader$1, CardTitle as CardTitle$1, CardDescription as CardDescription$1, ScrollArea, Label, Select, SelectTrigger, SelectValue, SelectContent, SelectItem } from '@burdenoff/fe-libs/ui';
19
+ import { Textarea, Input, Button, Card, Badge, CardContent as CardContent$1, Dialog, DialogTrigger, DialogContent, DialogHeader, DialogTitle, DialogDescription, DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuLabel, DropdownMenuItem, DropdownMenuSeparator, Select, SelectTrigger, SelectValue, SelectContent, SelectItem, Sheet, SheetTrigger, SheetContent, SheetHeader, SheetTitle, TooltipProvider, AlertDialog, AlertDialogContent, AlertDialogHeader, AlertDialogTitle, AlertDialogDescription, AlertDialogFooter, AlertDialogCancel, AlertDialogAction, Popover, PopoverTrigger, PopoverContent, Tooltip, TooltipTrigger, TooltipContent, Toaster, Tabs, TabsList, TabsTrigger, TabsContent, CardHeader as CardHeader$1, CardTitle as CardTitle$1, CardDescription as CardDescription$1, ScrollArea, Label } from '@burdenoff/fe-libs/ui';
20
20
  import { cn } from '@burdenoff/fe-libs/utils';
21
21
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
22
22
  import { Icon } from '@iconify/react';
@@ -6638,6 +6638,233 @@ var CardFooter = forwardRef(
6638
6638
  )
6639
6639
  );
6640
6640
  CardFooter.displayName = "CardFooter";
6641
+ var RUNNER_FIELDS = gql`
6642
+ fragment SandboxRunnerFields on SandboxRunner {
6643
+ id
6644
+ name
6645
+ status
6646
+ hostname
6647
+ os
6648
+ arch
6649
+ driver
6650
+ version
6651
+ capacity
6652
+ tokenPrefix
6653
+ lastSeenAt
6654
+ connectedAt
6655
+ createdBy
6656
+ createdAt
6657
+ }
6658
+ `;
6659
+ var LIST_RUNNERS = gql`
6660
+ ${RUNNER_FIELDS}
6661
+ query SandboxRunners {
6662
+ sandboxRunners(context: {}) {
6663
+ ...SandboxRunnerFields
6664
+ }
6665
+ }
6666
+ `;
6667
+ var CREATE_RUNNER = gql`
6668
+ ${RUNNER_FIELDS}
6669
+ mutation CreateSandboxRunner($name: String!) {
6670
+ createSandboxRunner(input: { name: $name, context: {} }) {
6671
+ token
6672
+ bridgeUrl
6673
+ runner {
6674
+ ...SandboxRunnerFields
6675
+ }
6676
+ }
6677
+ }
6678
+ `;
6679
+ var ROTATE_RUNNER_TOKEN = gql`
6680
+ ${RUNNER_FIELDS}
6681
+ mutation RotateSandboxRunnerToken($id: ID!) {
6682
+ rotateSandboxRunnerToken(id: $id, context: {}) {
6683
+ token
6684
+ bridgeUrl
6685
+ runner {
6686
+ ...SandboxRunnerFields
6687
+ }
6688
+ }
6689
+ }
6690
+ `;
6691
+ var DELETE_RUNNER = gql`
6692
+ mutation DeleteSandboxRunner($id: ID!) {
6693
+ deleteSandboxRunner(id: $id, context: {})
6694
+ }
6695
+ `;
6696
+ var RUNNER_INSTALL_SCRIPT_URL = "https://www.fluidgrids.ai/downloads/runner/install.sh";
6697
+ function runnerInstallCommand(token, bridgeUrl) {
6698
+ const urlFlag = bridgeUrl && bridgeUrl !== DEFAULT_BRIDGE_URL ? ` --url ${bridgeUrl}` : "";
6699
+ return `curl -fsSL ${RUNNER_INSTALL_SCRIPT_URL} | sh -s -- --token ${token}${urlFlag}`;
6700
+ }
6701
+ var DEFAULT_BRIDGE_URL = "wss://graphqlworkspaces.burdenoff.com/runner-bridge";
6702
+ function useRunners(options) {
6703
+ const [runners, setRunners] = useState([]);
6704
+ const [loading, setLoading] = useState(!options?.skip);
6705
+ const [error, setError] = useState(null);
6706
+ const mounted = useRef(true);
6707
+ const fetchRunners = useCallback(async () => {
6708
+ if (options?.skip) return;
6709
+ try {
6710
+ const result = await getFluidGridsClient().query({ query: LIST_RUNNERS, fetchPolicy: "network-only" });
6711
+ if (!mounted.current) return;
6712
+ setRunners(result.data?.sandboxRunners ?? []);
6713
+ setError(null);
6714
+ } catch (err) {
6715
+ if (mounted.current) setError(err);
6716
+ } finally {
6717
+ if (mounted.current) setLoading(false);
6718
+ }
6719
+ }, [options?.skip]);
6720
+ useEffect(() => {
6721
+ mounted.current = true;
6722
+ void fetchRunners();
6723
+ const pollMs = options?.pollMs ?? 1e4;
6724
+ const timer = pollMs > 0 ? setInterval(fetchRunners, pollMs) : null;
6725
+ return () => {
6726
+ mounted.current = false;
6727
+ if (timer) clearInterval(timer);
6728
+ };
6729
+ }, [fetchRunners, options?.pollMs]);
6730
+ return { runners, loading, error, refetch: fetchRunners };
6731
+ }
6732
+ function useRunnerActions() {
6733
+ const [busy, setBusy] = useState(false);
6734
+ const run = useCallback(async (fn) => {
6735
+ setBusy(true);
6736
+ try {
6737
+ return await fn();
6738
+ } finally {
6739
+ setBusy(false);
6740
+ }
6741
+ }, []);
6742
+ const createRunner = useCallback(
6743
+ (name) => run(async () => {
6744
+ const result = throwIfResultError(
6745
+ await getFluidGridsClient().mutate({ mutation: CREATE_RUNNER, variables: { name } })
6746
+ );
6747
+ if (!result.data?.createSandboxRunner)
6748
+ throw new Error("No runner returned");
6749
+ return result.data.createSandboxRunner;
6750
+ }),
6751
+ [run]
6752
+ );
6753
+ const rotateToken = useCallback(
6754
+ (id) => run(async () => {
6755
+ const result = throwIfResultError(
6756
+ await getFluidGridsClient().mutate({ mutation: ROTATE_RUNNER_TOKEN, variables: { id } })
6757
+ );
6758
+ if (!result.data?.rotateSandboxRunnerToken)
6759
+ throw new Error("No runner returned");
6760
+ return result.data.rotateSandboxRunnerToken;
6761
+ }),
6762
+ [run]
6763
+ );
6764
+ const deleteRunner = useCallback(
6765
+ (id) => run(async () => {
6766
+ const result = throwIfResultError(
6767
+ await getFluidGridsClient().mutate({
6768
+ mutation: DELETE_RUNNER,
6769
+ variables: { id }
6770
+ })
6771
+ );
6772
+ return result.data?.deleteSandboxRunner === true;
6773
+ }),
6774
+ [run]
6775
+ );
6776
+ return { createRunner, rotateToken, deleteRunner, busy };
6777
+ }
6778
+ var STYLES = {
6779
+ ONLINE: "border-status-success-border bg-status-success-bg-subtle text-status-success-text",
6780
+ OFFLINE: "border-status-neutral-border bg-status-neutral-bg-subtle text-status-neutral-text",
6781
+ NEVER_CONNECTED: "border-status-warning-border bg-status-warning-bg-subtle text-status-warning-text"
6782
+ };
6783
+ function RunnerStatusPill({
6784
+ status,
6785
+ className
6786
+ }) {
6787
+ const tr = useTr();
6788
+ const label = status === "ONLINE" ? tr("fluidgrids.runners.online", "Online") : status === "OFFLINE" ? tr("fluidgrids.runners.offline", "Offline") : tr("fluidgrids.runners.neverConnected", "Not connected yet");
6789
+ return /* @__PURE__ */ jsx(
6790
+ "span",
6791
+ {
6792
+ className: cn(
6793
+ "inline-flex items-center rounded-full border px-2 py-0.5 text-xs font-medium",
6794
+ STYLES[status],
6795
+ className
6796
+ ),
6797
+ "data-testid": "runner-status",
6798
+ "data-status": status,
6799
+ children: label
6800
+ }
6801
+ );
6802
+ }
6803
+ var CLOUD = "__fluidgrids_cloud__";
6804
+ function RunOnSection({
6805
+ value,
6806
+ onChange,
6807
+ sectionLabelClassName
6808
+ }) {
6809
+ const tr = useTr();
6810
+ const { runners, loading } = useRunners({ pollMs: 15e3 });
6811
+ const selected = value ? runners.find((r) => r.id === value.runnerId) : void 0;
6812
+ return /* @__PURE__ */ jsxs("section", { className: "space-y-2", "data-testid": "ndv-settings-run-on", children: [
6813
+ /* @__PURE__ */ jsx("div", { className: sectionLabelClassName, children: tr("fluidgrids.builder.nodeSettings.runOn", "Run on") }),
6814
+ /* @__PURE__ */ jsxs(
6815
+ Select,
6816
+ {
6817
+ value: value?.runnerId ?? CLOUD,
6818
+ onValueChange: (v) => onChange(v === CLOUD ? null : { kind: "runner", runnerId: v }),
6819
+ children: [
6820
+ /* @__PURE__ */ jsx(
6821
+ SelectTrigger,
6822
+ {
6823
+ className: "w-full",
6824
+ "data-testid": "ndv-settings-run-on-select",
6825
+ children: /* @__PURE__ */ jsx(SelectValue, {})
6826
+ }
6827
+ ),
6828
+ /* @__PURE__ */ jsxs(SelectContent, { children: [
6829
+ /* @__PURE__ */ jsx(SelectItem, { value: CLOUD, "data-testid": "run-on-cloud", children: tr(
6830
+ "fluidgrids.builder.nodeSettings.runOnCloud",
6831
+ "FluidGrids Cloud (default)"
6832
+ ) }),
6833
+ runners.map((runner) => /* @__PURE__ */ jsxs(
6834
+ SelectItem,
6835
+ {
6836
+ value: runner.id,
6837
+ "data-testid": "run-on-runner-option",
6838
+ children: [
6839
+ runner.name,
6840
+ runner.status !== "ONLINE" ? ` (${runner.status === "OFFLINE" ? tr("fluidgrids.runners.offline", "Offline") : tr("fluidgrids.runners.neverConnected", "Not connected yet")})` : ""
6841
+ ]
6842
+ },
6843
+ runner.id
6844
+ )),
6845
+ value && !loading && !selected && /* @__PURE__ */ jsx(SelectItem, { value: value.runnerId, disabled: true, children: tr(
6846
+ "fluidgrids.builder.nodeSettings.runOnMissing",
6847
+ "Removed runner"
6848
+ ) })
6849
+ ] })
6850
+ ]
6851
+ }
6852
+ ),
6853
+ value ? /* @__PURE__ */ jsxs("div", { className: "flex items-start gap-2 text-xs text-text-secondary", children: [
6854
+ selected && /* @__PURE__ */ jsx(RunnerStatusPill, { status: selected.status }),
6855
+ /* @__PURE__ */ jsx("span", { children: tr(
6856
+ "fluidgrids.builder.nodeSettings.runOnRunnerHint",
6857
+ "This node runs on your runner, in a local sandbox. If the runner is offline the node fails \u2014 it never falls back to FluidGrids Cloud. The node's input and the credentials it uses are sent to that machine."
6858
+ ) })
6859
+ ] }) : /* @__PURE__ */ jsx("p", { className: "text-xs text-text-secondary", children: runners.length === 0 && !loading ? tr(
6860
+ "fluidgrids.builder.nodeSettings.runOnNoRunners",
6861
+ "Runs in FluidGrids Cloud. Add a runner under Workflows \u2192 Runners to run nodes on your own machine."
6862
+ ) : tr(
6863
+ "fluidgrids.builder.nodeSettings.runOnCloudHint",
6864
+ "Runs in FluidGrids Cloud."
6865
+ ) })
6866
+ ] });
6867
+ }
6641
6868
  var FLUIDGRIDS_ENTITY_TYPES = ["FLUIDGRIDS_WORKFLOW"];
6642
6869
  function tagLabel(assignment) {
6643
6870
  return assignment.tagInfo?.label ?? assignment.tagInfo?.key ?? assignment.tagId.slice(0, 8);
@@ -11296,8 +11523,8 @@ function DesktopSidebarFragment({
11296
11523
  }
11297
11524
  const { getFluidGridsClient: getFluidGridsClient2 } = await import('./client-EYQDMR4O.js');
11298
11525
  const { getFluidGridsConfig: getFluidGridsConfig2 } = await import('./config-AOSNG5I7.js');
11299
- const { gql: gql10 } = await import('@apollo/client/core');
11300
- const IMPORT_MUTATION = gql10`
11526
+ const { gql: gql11 } = await import('@apollo/client/core');
11527
+ const IMPORT_MUTATION = gql11`
11301
11528
  mutation ImportWorkflowTemplate(
11302
11529
  $input: ImportWorkflowTemplateInput!
11303
11530
  ) {
@@ -11443,8 +11670,8 @@ function DesktopSidebarFragment({
11443
11670
  { id: "template-load" }
11444
11671
  );
11445
11672
  const { getGlobalStoreClient: getGlobalStoreClient2 } = await import('./global-client-O2HCG5CJ.js');
11446
- const { gql: gql10 } = await import('@apollo/client/core');
11447
- const GET_TEMPLATE_DETAIL = gql10`
11673
+ const { gql: gql11 } = await import('@apollo/client/core');
11674
+ const GET_TEMPLATE_DETAIL = gql11`
11448
11675
  query GetWorkflowTemplateDetail($id: ID!) {
11449
11676
  product(id: $id) {
11450
11677
  id
@@ -19334,7 +19561,10 @@ function CanvasControls() {
19334
19561
  onPointerUp: handlePointerUp,
19335
19562
  onPointerCancel: handlePointerUp,
19336
19563
  className: [
19337
- "fixed bottom-3 z-50 flex items-center gap-1 rounded-xl border",
19564
+ // z-[15]: above the canvas, BELOW the sidebar panel (z-20). On a phone the
19565
+ // open panel floats over the canvas and this bar sat on top of its footer
19566
+ // action (Add / Install), making a node impossible to add.
19567
+ "fixed bottom-3 z-[15] flex items-center gap-1 rounded-xl border",
19338
19568
  "border-card-foreground/10 bg-card px-2 py-1.5 shadow-lg touch-none",
19339
19569
  isDragging ? "cursor-grabbing" : "cursor-grab"
19340
19570
  ].join(" "),
@@ -22322,6 +22552,10 @@ function nodeSubtitle(node) {
22322
22552
  const data = asRecord(node?.data);
22323
22553
  return typeof data?.operation_name === "string" ? data.operation_name : void 0;
22324
22554
  }
22555
+ function runOnOf(executionSettings) {
22556
+ const runOn = asRecord(executionSettings?.runOn);
22557
+ return runOn?.kind === "runner" && typeof runOn.runnerId === "string" ? { kind: "runner", runnerId: runOn.runnerId } : null;
22558
+ }
22325
22559
  function useNodeConfig(target, options) {
22326
22560
  const nodes = useFlowStore((s) => s.workflow.nodes);
22327
22561
  const edges = useFlowStore((s) => s.workflow.edges);
@@ -22537,9 +22771,12 @@ function useNodeConfig(target, options) {
22537
22771
  const next = store.workflow.nodes.map((n) => {
22538
22772
  if (n.id !== nodeId) return n;
22539
22773
  const data = { ...asRecord(n.data) ?? {} };
22540
- const prev = asRecord(data.executionSettings) ?? {};
22541
- const merged = { ...prev, ...patch };
22542
- if (!merged.alwaysOutputData && !merged.executeOnce) {
22774
+ const merged = {
22775
+ ...asRecord(data.executionSettings) ?? {},
22776
+ ...patch
22777
+ };
22778
+ if (merged.runOn === null) delete merged.runOn;
22779
+ if (!merged.alwaysOutputData && !merged.executeOnce && !merged.runOn) {
22543
22780
  delete data.executionSettings;
22544
22781
  } else {
22545
22782
  data.executionSettings = merged;
@@ -22568,6 +22805,7 @@ function useNodeConfig(target, options) {
22568
22805
  );
22569
22806
  const alwaysOutputData = executionSettings?.alwaysOutputData === true;
22570
22807
  const executeOnce = executionSettings?.executeOnce === true;
22808
+ const runOn = useMemo(() => runOnOf(executionSettings), [executionSettings]);
22571
22809
  const handleDropOnParam = (field) => (e) => {
22572
22810
  e.preventDefault();
22573
22811
  setDragField(null);
@@ -22613,6 +22851,7 @@ function useNodeConfig(target, options) {
22613
22851
  writeNotes,
22614
22852
  alwaysOutputData,
22615
22853
  executeOnce,
22854
+ runOn,
22616
22855
  writeExecutionSettings,
22617
22856
  writeNodeDataField
22618
22857
  };
@@ -23078,6 +23317,7 @@ function NodeSettingsPanel({
23078
23317
  writeNotes,
23079
23318
  alwaysOutputData,
23080
23319
  executeOnce,
23320
+ runOn,
23081
23321
  writeExecutionSettings
23082
23322
  } = config2;
23083
23323
  const onError = errorConfig?.onError ?? "stop";
@@ -23085,6 +23325,14 @@ function NodeSettingsPanel({
23085
23325
  const timeoutEnabled = !!errorConfig?.timeout?.duration;
23086
23326
  const branchTargets = nodes.filter((n) => n.id !== node?.id);
23087
23327
  return /* @__PURE__ */ jsxs("div", { className: "space-y-6", "data-testid": "ndv-settings-panel", children: [
23328
+ /* @__PURE__ */ jsx(
23329
+ RunOnSection,
23330
+ {
23331
+ value: runOn,
23332
+ onChange: (next) => writeExecutionSettings({ runOn: next }),
23333
+ sectionLabelClassName: SECTION_LABEL4
23334
+ }
23335
+ ),
23088
23336
  /* @__PURE__ */ jsxs("section", { className: "space-y-2", children: [
23089
23337
  /* @__PURE__ */ jsx("div", { className: SECTION_LABEL4, children: tr("fluidgrids.builder.nodeSettings.retrySection", "Retry on Fail") }),
23090
23338
  /* @__PURE__ */ jsxs("label", { className: "flex w-fit cursor-pointer items-center gap-2 text-sm", children: [
@@ -26251,4 +26499,4 @@ var FlowBuilderPage = ({
26251
26499
  ] });
26252
26500
  };
26253
26501
 
26254
- export { Card2 as Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, ConnectionFormDialog, ConnectionSelector, EntityTagPicker, FLUIDGRIDS_ENTITY_TYPES, FlowBuilderPage, FluidGridsMark, FluidGridsProvider, TemplateCard, buildNodeCheck, buildRequiredNodeTypes, listCustomBlocks, mergeStickyNotes, refetchStoreNodes, registerCustomBlock, resolveUiSpec, stripSubmitActions, tagLabel, useAvailableTags, useConnection, useConnections, useConnectionsByProvider, useCreateConnection, useCreateTag, useDraftEntityTags, useEntityTags, useFluidGridsContext, useImportWorkflowTemplate, useInitiateOAuth, useInstalledNodes, useNodeExecution, useProviders, useReplaceEntityTags, useSearchTags, useTagEntity, useUntagEntity, useWorkflowTemplates };
26502
+ export { Card2 as Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, ConnectionFormDialog, ConnectionSelector, EntityTagPicker, FLUIDGRIDS_ENTITY_TYPES, FlowBuilderPage, FluidGridsMark, FluidGridsProvider, RUNNER_INSTALL_SCRIPT_URL, RunOnSection, RunnerStatusPill, TemplateCard, buildNodeCheck, buildRequiredNodeTypes, listCustomBlocks, mergeStickyNotes, refetchStoreNodes, registerCustomBlock, resolveUiSpec, runnerInstallCommand, stripSubmitActions, tagLabel, useAvailableTags, useConnection, useConnections, useConnectionsByProvider, useCreateConnection, useCreateTag, useDraftEntityTags, useEntityTags, useFluidGridsContext, useImportWorkflowTemplate, useInitiateOAuth, useInstalledNodes, useNodeExecution, useProviders, useReplaceEntityTags, useRunnerActions, useRunners, useSearchTags, useTagEntity, useUntagEntity, useWorkflowTemplates };
@@ -158,7 +158,10 @@ var FLUIDGRIDS_PERMISSIONS = {
158
158
  SECRETS_PROVIDER_CONFIG_UPDATE: "secrets-provider-config:update",
159
159
  SECRETS_PROVIDER_CONFIG_TEST: "secrets-provider-config:test",
160
160
  // Integrations (wspace-integrations-svc)
161
- INTEGRATION_CONNECTION_CREATE: "integration-connection:create"
161
+ INTEGRATION_CONNECTION_CREATE: "integration-connection:create",
162
+ // Self-hosted runners (wspace-sandbox-svc; @rbac resource "sandbox")
163
+ SANDBOX_READ: "sandbox:read",
164
+ SANDBOX_CREATE: "sandbox:create"
162
165
  };
163
166
 
164
167
  export { ALLOW_ALL_PERMISSIONS, FLUIDGRIDS_PERMISSIONS, FluidGridsPermissionsProvider, SdkPermissionButton, SdkPermissionGate, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, evaluatePermissionCheck, useFluidGridsPermission };
@@ -1,5 +1,5 @@
1
1
  import { useExecution, buildNodeDisplayMap, useExecutionActions, useAutoRefresh, ExecutionStatusBadge, formatRunVersion, NodeTimeline, RunLogViewer } from './chunk-NM5TH27W.js';
2
- import { useFluidGridsPermission, FLUIDGRIDS_PERMISSIONS } from './chunk-SYU74PMY.js';
2
+ import { useFluidGridsPermission, FLUIDGRIDS_PERMISSIONS } from './chunk-ONVGFVNH.js';
3
3
  import { getFluidGridsConfig } from './chunk-UZG3ZIQM.js';
4
4
  import { RunLogsDocument, RunLogAppendedDocument } from './chunk-F2OUXT3V.js';
5
5
  import { throwIfResultError } from './chunk-CFCUM4CN.js';
@@ -1,4 +1,4 @@
1
- import { useImportWorkflowTemplate, FlowBuilderPage, useWorkflowTemplates, TemplateCard } from './chunk-ZJ6HKHFX.js';
1
+ import { useImportWorkflowTemplate, FlowBuilderPage, useWorkflowTemplates, TemplateCard } from './chunk-5O4QSCWG.js';
2
2
  import { QuotaExhaustedDialog } from './chunk-SQFFJUAT.js';
3
3
  import { useWorkflowDefinitions, useDuplicateWorkflow } from './chunk-IYTHK7B5.js';
4
4
  import { templatesControls } from './chunk-D3UWK7GY.js';
@@ -1,6 +1,6 @@
1
1
  import { NEW_WORKFLOW_NAV } from './chunk-6N27YGMB.js';
2
2
  import { QuotaExhaustedDialog } from './chunk-SQFFJUAT.js';
3
- import { SdkPermissionButton, FLUIDGRIDS_PERMISSIONS, SdkPermissionGate } from './chunk-SYU74PMY.js';
3
+ import { SdkPermissionButton, FLUIDGRIDS_PERMISSIONS, SdkPermissionGate } from './chunk-ONVGFVNH.js';
4
4
  import { useWorkflowDefinitions, useLazyWorkflowDefinition, useImportWorkflow, useDuplicateWorkflow, useDeleteWorkflow } from './chunk-IYTHK7B5.js';
5
5
  import { workflowsListControls } from './chunk-D3UWK7GY.js';
6
6
  import { useFluidGridsPageControls } from './chunk-PJAWNFJV.js';
@@ -1,4 +1,4 @@
1
- import { FluidGridsProvider, Card, FluidGridsMark } from './chunk-ZJ6HKHFX.js';
1
+ import { FluidGridsProvider, Card, FluidGridsMark } from './chunk-5O4QSCWG.js';
2
2
  import { Input } from './chunk-IEVSFCFS.js';
3
3
  import { Button } from './chunk-GDAFKRQO.js';
4
4
  import { cn } from './chunk-JL7CASN5.js';
@@ -1,9 +1,9 @@
1
1
  import './chunk-AD3BXTJS.js';
2
2
  export { ExecutionsListPage } from './chunk-ZB45VAXM.js';
3
- export { ExecutionDetailPage } from './chunk-IPNGNROQ.js';
3
+ export { ExecutionDetailPage } from './chunk-PF6MKIOS.js';
4
4
  import './chunk-NM5TH27W.js';
5
5
  import './chunk-QBFAJNUC.js';
6
- import './chunk-SYU74PMY.js';
6
+ import './chunk-ONVGFVNH.js';
7
7
  import './chunk-JL7CASN5.js';
8
8
  import './chunk-IYTHK7B5.js';
9
9
  import './chunk-D3UWK7GY.js';