@burdenoff/fluidgrids-fe-sdk 2026.1111.14 → 2026.1111.15

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 (43) hide show
  1. package/README.md +41 -0
  2. package/dist/{ExecutionDetailPage-itor_whl.js → ExecutionDetailPage-DO38vZ_F.js} +4 -4
  3. package/dist/{FluidGridsProvider-B30VcLdX.js → FluidGridsProvider-B9RR_CI_.js} +2 -309
  4. package/dist/{HistoryPage-DueEld8g.js → HistoryPage-CA42pU85.js} +1 -1
  5. package/dist/{InsightsPage-DQ7KCR9h.js → InsightsPage-CBoN_Mj9.js} +2 -2
  6. package/dist/{ManagedAiPolicyAuthority-C0YPTJMS.js → ManagedAiPolicyAuthority-CKihmbJE.js} +2 -2
  7. package/dist/{MissingNodesInstallModal-Cj31oMDX.js → MissingNodesInstallModal-Dm0nMBXM.js} +1 -1
  8. package/dist/{TemplateConfigurationModal-BAPCG8y-.js → TemplateConfigurationModal-Bs_V-E4u.js} +1 -1
  9. package/dist/{TemplateDetailPanel-CZ1uxEQL.js → TemplateDetailPanel-MlT39VLG.js} +1 -1
  10. package/dist/{TemplatesPage-DWdgZnIH.js → TemplatesPage-CHVpWBuw.js} +5 -4
  11. package/dist/{WorkflowSearchRedirect-C8vhSZK9.js → WorkflowSearchRedirect-3gyHcYY2.js} +13 -9
  12. package/dist/{WorkflowShareDialog-DnBQA3V6.js → WorkflowShareDialog-0Ai1HED-.js} +2 -1
  13. package/dist/{WorkflowsList-74jjJFsJ.js → WorkflowsList-CJ3KmMHX.js} +5 -4
  14. package/dist/agent-tools.d.ts +3 -0
  15. package/dist/agent-tools.js +5 -0
  16. package/dist/{agentTools-D5AW7zHn.js → agentTools-B1IK1JEO.js} +2 -2
  17. package/dist/{canvasNoteTools-BqQTTCll.js → canvasNoteTools-eewVHVuy.js} +3 -2
  18. package/dist/executions.js +1 -1
  19. package/dist/{flow-builder-BR8p5tXG.js → flow-builder-C_3sY3pZ.js} +12 -157
  20. package/dist/fluidgridsEvents-CNdcrUNN.js +310 -0
  21. package/dist/history.js +1 -1
  22. package/dist/index-CHeY7_A1.d.ts +105 -0
  23. package/dist/{index-CLqh2u28.d.ts → index-DRf25-D3.d.ts} +7 -105
  24. package/dist/index.d.ts +3 -2
  25. package/dist/index.js +21 -946
  26. package/dist/marksStore-DGCXjTmZ.js +151 -0
  27. package/dist/{node-detail-view-Dnhqdn8C.js → node-detail-view-CAws5qjg.js} +3 -3
  28. package/dist/observability.d.ts +1 -1
  29. package/dist/observability.js +1 -1
  30. package/dist/{quick-config-panel-C4tSpCrt.js → quick-config-panel-DOzNkSVV.js} +2 -2
  31. package/dist/settings.js +1 -1
  32. package/dist/templates.js +1 -1
  33. package/dist/uiMarkTools-nlmzsHQM.js +937 -0
  34. package/dist/{useExecutions-CNEN1ENQ.js → useExecutions-DkS0FTfw.js} +2 -1
  35. package/dist/{useObservability-CmFFXmKb.js → useObservability-BkxhHZsX.js} +2 -1
  36. package/dist/{useRunHistory-DhU_mrzF.js → useRunHistory-DHehG09Z.js} +1 -1
  37. package/dist/{useWorkflows-D01LC39Y.js → useWorkflows-DyhtoVwp.js} +25 -5
  38. package/dist/workflow-builder.js +2 -2
  39. package/dist/workflow-route.d.ts +33 -0
  40. package/dist/workflow-route.js +4 -0
  41. package/dist/workflowRouteData-BkfVOc-O.js +169 -0
  42. package/dist/workflows-list.js +1 -1
  43. package/package.json +9 -1
package/README.md CHANGED
@@ -270,6 +270,47 @@ import {
270
270
  - Nodes cannot be dragged, connected, selected or deleted; pan and zoom work.
271
271
  - `prefers-reduced-motion: reduce` turns every animation off.
272
272
 
273
+ ## Starting the builder's data early (optional)
274
+
275
+ On a cold load of a builder address the builder's own code takes a while to
276
+ arrive. A host can start the builder's read as soon as it knows the route and the
277
+ person's workspace token, and the builder takes the answer when it opens instead
278
+ of asking again. `./workflow-route` imports nothing else from the SDK, so it can
279
+ sit on the host's entry.
280
+
281
+ ```ts
282
+ import {
283
+ matchWorkflowBuilderRoute,
284
+ prefetchWorkflowForBuilder,
285
+ } from "@burdenoff/fluidgrids-fe-sdk/workflow-route";
286
+
287
+ const route = matchWorkflowBuilderRoute(location.pathname, "/workflows");
288
+ if (route && workspaceId && workspaceToken) {
289
+ prefetchWorkflowForBuilder({
290
+ ...route,
291
+ workspaceId, // the builder takes the read only for the same workspace
292
+ // The host's own GraphQL fetch with the person's tokens. Send it on its own
293
+ // request: a batch window would give back what starting early gains.
294
+ request: ({ operationName, query, variables }) =>
295
+ hostGraphqlFetch({ operationName, query, variables, batch: false }),
296
+ });
297
+ }
298
+ ```
299
+
300
+ - A read is handed to the builder once, for the same workspace, workflow key and
301
+ version, and only within 15 seconds of its start (`PREFETCHED_WORKFLOW_TTL_MS`).
302
+ - A read that fails, answers with errors or answers for another workflow is not
303
+ used: the builder sends its own read and reports the problem as before.
304
+ - Without a started read the builder sends its read itself, on its own request
305
+ (`context: { sendUnbatched: true }`), so a batching host client does not hold it.
306
+
307
+ ## Agent tools (optional)
308
+
309
+ `./agent-tools` carries FluidGrids' AI agent tools (`createFluidGridsAgentTools`)
310
+ and the assistant's point-at tools and callouts (`createUiMarkTools`,
311
+ `AgentCalloutOverlay`) without the rest of the SDK, for a shell that mounts them on
312
+ every page. The main entry still exports them.
313
+
273
314
  ## Styling
274
315
 
275
316
  The SDK uses Tailwind CSS for styling. Make sure you have Tailwind configured in your project, or import the pre-built styles:
@@ -1,10 +1,10 @@
1
1
  "use client";
2
2
  import { $r as WorkflowRunMetadataDocument, A as CreateWorkerTokenDocument, An as SetWorkerTokenConnectionAllowlistDocument, Bi as describeOperationError, Gn as TaskQueuesDocument, Mn as SetWorkflowRunVersioningOverrideDocument, Oi as getFluidGridsClient, Sn as RunLogsDocument, Sr as WorkflowBatchOperationUpdatedDocument, U as DeleteTaskQueueDocument, Ui as throwIfResultError, W as DeleteWorkerTokenDocument, Wn as TaskQueueStatsDocument, Xr as WorkflowRunHierarchyDocument, aa as useExecutionsStore, bn as RunLogAppendedDocument, c as AgentTraceDocument, dn as RotateWorkerTokenDocument, dt as ExplainRunDocument, ei as WorkflowRunPendingDocument, fn as RunAiUsageDocument, hr as WorkerTokensDocument, ia as DEFAULT_EXECUTIONS_FILTER, k as CreateTaskQueueDocument, ki as getFluidGridsClientSafe, nt as DurableParityRunFieldsDocument, oa as __exportAll, or as UpdateTaskQueueDocument, qi as getFluidGridsConfig, ri as WorkflowRunsCountDocument, s as AgentStepUpdatedDocument, wi as WorkflowWorkersDocument } from "./node-endpoint-configs-DHFGA5MQ.js";
3
- import { In as canSignalRun, Rn as durableInterfaceOf, Vn as runSignalTargets, Xn as useDurableParityEnabled, Yn as useDurableFunctionNodesEnabled, an as runDurationMs, er as usePhaseCFlags, in as nodeStateDurationMs, nr as useWorkflowTestsEnabled, rn as formatElapsedMs } from "./FluidGridsProvider-B30VcLdX.js";
3
+ import { Ln as usePhaseCFlags, Mn as useDurableFunctionNodesEnabled, Nn as useDurableParityEnabled, an as runDurationMs, in as nodeStateDurationMs, rn as formatElapsedMs, wn as runSignalTargets, xn as durableInterfaceOf, yn as canSignalRun, zn as useWorkflowTestsEnabled } from "./FluidGridsProvider-B9RR_CI_.js";
4
4
  import { r as useTr } from "./TranslationBridge-Da-TPgQm.js";
5
- import { h as useWorkflowDefinitions, v as useWorkflowVersions } from "./useWorkflows-D01LC39Y.js";
5
+ import { h as useWorkflowDefinitions, v as useWorkflowVersions } from "./useWorkflows-DyhtoVwp.js";
6
6
  import { $u as ErrorType, L as AgentStepKind, LF as WorkflowQueryRejectCondition, RF as WorkflowResetType, bF as WorkflowBatchOperationType, hI as FLUIDGRIDS_PERMISSIONS, tI as WorkflowUpdateWaitFor, vI as SdkPermissionButton, xI as useFluidGridsPermission, yP as VersioningBehavior } from "./graphql-types-XcDLtFwU.js";
7
- import { _ as statusCountFilter, c as OPERATORS_BY_TYPE, d as STATUS_COUNT_GROUP_BY, f as callbackTone, g as shortRunId, h as runChainLinks, i as useExecutionStats, l as buildSearchAttributeFilter, m as parseMetadataDefinition, n as useExecution, o as useExecutionsWithStore, p as overrideRequestOf, r as useExecutionActions, s as EMPTY_SEARCH_FILTER, t as useAutoRefresh, u as searchFilterConflicts, v as statusCountsOf, y as validateDateRange } from "./useExecutions-CNEN1ENQ.js";
7
+ import { _ as statusCountFilter, c as OPERATORS_BY_TYPE, d as STATUS_COUNT_GROUP_BY, f as callbackTone, g as shortRunId, h as runChainLinks, i as useExecutionStats, l as buildSearchAttributeFilter, m as parseMetadataDefinition, n as useExecution, o as useExecutionsWithStore, p as overrideRequestOf, r as useExecutionActions, s as EMPTY_SEARCH_FILTER, t as useAutoRefresh, u as searchFilterConflicts, v as statusCountsOf, y as validateDateRange } from "./useExecutions-DkS0FTfw.js";
8
8
  import { n as useFluidGridsPageControls } from "./pageControlsBridge-0pX9s-3k.js";
9
9
  import { t as executionsControls } from "./pageControlSpecs-DZJ9K37m.js";
10
10
  import { t as FluidGridsDocsLink } from "./FluidGridsDocsLink-JxkBpOeb.js";
@@ -13,7 +13,7 @@ import { C as useAvailableTags, _ as buildNodeDisplayMap, b as EntityTagPicker,
13
13
  import { t as AiCreditBalanceSlot } from "./aiCreditsBridge-BuE92tKo.js";
14
14
  import { a as fetchRunFailureClusters, i as dismissRunFailureCluster, o as runListFilterFromSearch, r as OPEN_STATUSES, s as runListLinkKey, t as BUCKET_LABELS } from "./FailureTriagePanel-BHiduL7A.js";
15
15
  import { a as encodedPayloadBytes, f as EffectBadge, h as useRunPolicyDecisions, i as decodePayloads, l as formatBudgetUsd, n as checkCodecServerUrl, o as isEncodedPayload, r as containsEncodedPayload, t as CodecServerError } from "./codec-client-DstqyzTN.js";
16
- import { a as useDurableRunFields, i as useDeterminismStatus, n as SignalRunDialog, o as useRunStackTrace, r as terminateDurableRun, s as RunHistoryView, t as useRunHistory } from "./useRunHistory-DhU_mrzF.js";
16
+ import { a as useDurableRunFields, i as useDeterminismStatus, n as SignalRunDialog, o as useRunStackTrace, r as terminateDurableRun, s as RunHistoryView, t as useRunHistory } from "./useRunHistory-DHehG09Z.js";
17
17
  import { a as formatTokens, d as formatMicroUsd, o as modelLabel, r as aiCost } from "./ai-usage-D5p7ZeRR.js";
18
18
  import { useCallback, useEffect, useMemo, useRef, useState } from "react";
19
19
  import { Link, useNavigate, useParams, useSearchParams } from "react-router";
@@ -2,6 +2,7 @@
2
2
  import { At as NodeManifestsDocument, Bi as describeOperationError, Di as createFluidGridsClient, Dr as WorkflowDefinitionDocument, En as SaveWorkflowDraftDocument, Jn as TriggerWorkflowDocument, Jr as WorkflowRunDocument, Li as emitFluidGridsEvent, Mi as setFluidGridsClient, Ni as waitForFluidGridsClient, Oi as getFluidGridsClient, Pi as createFluidGridsTokenRefreshLink, Qi as validateTrustedOrigin, R as CreateWorkflowVersionDocument, Ri as emitOperationErrorEvent, Ui as throwIfResultError, Wi as createLiveTokenReader, Xi as resetFluidGridsExecutionState, Yi as resetFluidGridsConfig, Zi as setFluidGridsConfig, at as EventRegistrationsDocument, j as CreateWorkflowDefinitionDocument, ji as resetFluidGridsClient, jt as NodePaletteEntriesDocument, ki as getFluidGridsClientSafe, oa as __exportAll, ot as ExecuteStepDocument, qi as getFluidGridsConfig, st as ExecutionDetailDocument, t as fetchAllNodeEndpointConfigs, vn as RunFromNodeDocument, zi as emitRunCompletedOnce } from "./node-endpoint-configs-DHFGA5MQ.js";
3
3
  import { A as nodeAccent, C as nodeAdaptersOf, D as NodeCard, E as resolveOutputHandles, H as useFlowStore, I as partitionStickyNotes, L as resolveStickyColor, N as DEFAULT_STICKY_COLOR, O as NodeCardBody, P as STICKY_COLORS, R as stickySurfaceStyle, T as resolveInputHandles, V as STICKY_NOTE_TYPE, W as isNodeTrigger, _ as LogicNodeCard, b as alignPlainOutputEdges, i as WAIT_FOR_SIGNAL_NODE_TYPE, j as NodeTypeIcon, k as NodeCardHeader, l as interfaceFields, m as readSignalName, n as synchronizeOperationUpdate, p as readCodeWorkflowState, r as CODE_WORKFLOW_NODE_TYPE, t as resolveOperationName, u as interfaceHandlers, v as InputHandles, w as outputHandlesSpacerHeight, x as hasNodeManifest, y as OutputHandles } from "./node-operation-selection--oy-yEq_.js";
4
4
  import { n as FluidGridsTranslationProvider, r as useTr, t as ENGLISH_FALLBACK_TRANSLATOR } from "./TranslationBridge-Da-TPgQm.js";
5
+ import { _ as errorCodesOf, g as collectExtensions, i as emitRunStarted, m as RUNS_QUOTA_NAME, n as emitRunFailed, p as QUOTA_EXHAUSTED_CODE, r as emitRunLimitHit, s as emitWorkflowCreated, v as findQuotaRefusal } from "./fluidgridsEvents-CNdcrUNN.js";
5
6
  import { createContext, memo, useCallback, useContext, useEffect, useMemo, useRef, useState, useSyncExternalStore } from "react";
6
7
  import { useNavigate, useParams } from "react-router";
7
8
  import { ApolloProvider } from "@apollo/client/react";
@@ -1379,314 +1380,6 @@ function NodeInfoButtonWithModal({ metadata }) {
1379
1380
  })] });
1380
1381
  }
1381
1382
 
1382
- // src/billing/quota.ts
1383
- /**
1384
- * Plan-quota refusals for the FluidGrids SDK.
1385
- *
1386
- * wspace-workflow-svc meters two quotas with `@usage`, and the gateway refuses
1387
- * a call past either one with `429 QUOTA_EXHAUSTED`:
1388
- *
1389
- * - `fluidgrids.runs.monthly` — every mutation that starts a run:
1390
- * `triggerWorkflow`, `runFromNode`, `replayWorkflowRun`, `retryWorkflowRuns`
1391
- * and `listenForWebhookTestEvent`.
1392
- * - `fluidgrids.workflows.count` — the mutations that create a workflow
1393
- * (save, duplicate, template import). Those keep their local
1394
- * `QuotaExhaustedDialog`.
1395
- * - `fluidgrids.nodes.count` — node additions are counted by workflow save;
1396
- * the same save dialog handles its refusal.
1397
- *
1398
- * A run refusal opens the shell's shared upgrade prompt — see
1399
- * `openRunQuotaUpgradePrompt` in `./upgradePrompt`. This module is the pure
1400
- * detection half, so it imports nothing from `@burdenoff/fe-libs`.
1401
- *
1402
- * ★★ Why this does not just call fe-libs `isQuotaExhaustedError`. That helper
1403
- * reads the Apollo 3 shapes (`graphQLErrors`, `networkError.result.errors`, a
1404
- * code in the message). Under Apollo 4 — what every host runs — the refusal
1405
- * never takes those shapes:
1406
- *
1407
- * - the gateway answers `429`, and Apollo 4's HTTP link turns any non-2xx
1408
- * `application/json` response into a `ServerError` whose GraphQL body is
1409
- * only in `bodyText` (message: "Response not successful: Received status
1410
- * code 429");
1411
- * - a 2xx GraphQL error arrives as `CombinedGraphQLErrors`, whose list is
1412
- * `.errors`, not `.graphQLErrors`;
1413
- * - `throwIfResultError` wraps either one in a plain `Error`, keeping the
1414
- * original as `cause`.
1415
- *
1416
- * None of those match, so the refusal read as an ordinary failure. This walker
1417
- * reads all of them, and the Apollo 3 shapes too.
1418
- */
1419
- /** The monthly run allowance every run-starting mutation is metered against. */
1420
- const RUNS_QUOTA_NAME = "fluidgrids.runs.monthly";
1421
- /** The workflow-count allowance save / duplicate / template import consume. */
1422
- const WORKFLOWS_QUOTA_NAME = "fluidgrids.workflows.count";
1423
- /**
1424
- * Where an upgrade CTA sends the user: the plan picker, not the billing
1425
- * overview. Matches the shared `UpgradePromptModal` default and the shell nav.
1426
- */
1427
- const BILLING_PLANS_PATH = "/billing/plans";
1428
- const QUOTA_EXHAUSTED_CODE = "QUOTA_EXHAUSTED";
1429
- const QUOTA_NOT_PROVISIONED_CODE = "QUOTA_NOT_PROVISIONED";
1430
- function asRecord$3(value) {
1431
- return typeof value === "object" && value !== null ? value : null;
1432
- }
1433
- /** The `extensions` of each entry of an `errors`-like list. */
1434
- function extensionsOfList(list) {
1435
- if (!Array.isArray(list)) return [];
1436
- const found = [];
1437
- for (const entry of list) {
1438
- const extensions = asRecord$3(asRecord$3(entry)?.extensions);
1439
- if (extensions) found.push(extensions);
1440
- }
1441
- return found;
1442
- }
1443
- /** The GraphQL `errors[].extensions` inside a raw response body, if it is JSON. */
1444
- function extensionsOfBody(bodyText) {
1445
- if (typeof bodyText !== "string" || !bodyText.includes("errors")) return [];
1446
- try {
1447
- return extensionsOfList(asRecord$3(JSON.parse(bodyText))?.errors);
1448
- } catch {
1449
- return [];
1450
- }
1451
- }
1452
- /** Bounds the `cause` walk; real chains are one or two links long. */
1453
- const MAX_CAUSE_DEPTH = 5;
1454
- /**
1455
- * Every `extensions` object reachable on a thrown value, across the Apollo 3
1456
- * and Apollo 4 shapes and the `cause` chain `throwIfResultError` adds.
1457
- */
1458
- function collectExtensions(error) {
1459
- const found = [];
1460
- const seen = /* @__PURE__ */ new Set();
1461
- let current = error;
1462
- for (let depth = 0; depth < MAX_CAUSE_DEPTH; depth += 1) {
1463
- const host = asRecord$3(current);
1464
- if (!host || seen.has(host)) break;
1465
- seen.add(host);
1466
- const direct = asRecord$3(host.extensions);
1467
- if (direct) found.push(direct);
1468
- found.push(...extensionsOfList(host.errors));
1469
- found.push(...extensionsOfList(host.graphQLErrors));
1470
- const networkError = asRecord$3(host.networkError);
1471
- found.push(...extensionsOfList(asRecord$3(networkError?.result)?.errors));
1472
- found.push(...extensionsOfBody(networkError?.bodyText));
1473
- found.push(...extensionsOfList(asRecord$3(host.result)?.errors));
1474
- found.push(...extensionsOfBody(host.bodyText));
1475
- current = host.cause;
1476
- }
1477
- return found;
1478
- }
1479
- /** Every GraphQL `extensions.code` carried by `error` or its causes. */
1480
- function errorCodesOf(error) {
1481
- return collectExtensions(error).map((ext) => ext.code).filter((code) => typeof code === "string");
1482
- }
1483
- function stringField(extensions, key) {
1484
- const value = extensions[key];
1485
- return typeof value === "string" && value.length > 0 ? value : null;
1486
- }
1487
- /**
1488
- * The refusal kind one GraphQL `extensions` object reports, or null.
1489
- *
1490
- * The gateway sets both `code` and `quotaBlock` on a quota refusal
1491
- * (`sendQuotaExhausted` in wspace-public-gateway); either is enough here, so
1492
- * a refusal relayed with only one of them (a proxy, an older gateway build)
1493
- * still reads as one.
1494
- */
1495
- function refusalKindOf(extensions) {
1496
- if (extensions.code === "QUOTA_NOT_PROVISIONED" || extensions.quotaBlock === "not-provisioned") return "not-provisioned";
1497
- if (extensions.code === "QUOTA_EXHAUSTED" || extensions.quotaBlock === "exhausted") return "exhausted";
1498
- return null;
1499
- }
1500
- /**
1501
- * The quota refusal carried by `error`, or null when it is not one.
1502
- *
1503
- * Keyed on `extensions.code` (or the gateway's `extensions.quotaBlock`), never
1504
- * on the HTTP status or the message: both refusals are 429s, and only those
1505
- * fields tell "used up" from "never granted". `not-provisioned` wins when both
1506
- * appear.
1507
- */
1508
- function findQuotaRefusal(error) {
1509
- const all = collectExtensions(error);
1510
- const notProvisioned = all.find((ext) => refusalKindOf(ext) === "not-provisioned");
1511
- if (notProvisioned) return {
1512
- kind: "not-provisioned",
1513
- quotaName: stringField(notProvisioned, "quotaName"),
1514
- limitLeft: null
1515
- };
1516
- const exhausted = all.find((ext) => refusalKindOf(ext) === "exhausted");
1517
- if (exhausted) {
1518
- const limitLeft = exhausted.limitLeft;
1519
- return {
1520
- kind: "exhausted",
1521
- quotaName: stringField(exhausted, "quotaName"),
1522
- limitLeft: typeof limitLeft === "number" ? limitLeft : null
1523
- };
1524
- }
1525
- return null;
1526
- }
1527
- /** True when `error` is an exhausted (not merely unprovisioned) plan quota. */
1528
- function isQuotaExhaustedFailure(error) {
1529
- return findQuotaRefusal(error)?.kind === "exhausted";
1530
- }
1531
-
1532
- // src/analytics/fluidgridsEvents.ts
1533
- /** `component` stamped on every event so devtools/OTel can tell the emitter. */
1534
- const FLUIDGRIDS_ANALYTICS_COMPONENT = "fluidgrids-fe-sdk";
1535
- /** Upper bound for a slug-like dimension; anything longer is not a slug. */
1536
- const MAX_DIMENSION_LENGTH = 64;
1537
- const SLUG_PATTERN = /^[A-Za-z0-9][A-Za-z0-9_./:-]*$/;
1538
- /**
1539
- * Keep a dimension only when it is a short slug (`integration/slack`,
1540
- * `trigger_webhook`, `marketing`). Anything else — spaces, free text, a very
1541
- * long value — is dropped rather than risk sending user data.
1542
- */
1543
- function toDimension(value) {
1544
- if (typeof value !== "string") return void 0;
1545
- const trimmed = value.trim();
1546
- if (!trimmed || trimmed.length > MAX_DIMENSION_LENGTH) return void 0;
1547
- return SLUG_PATTERN.test(trimmed) ? trimmed : void 0;
1548
- }
1549
- /** Non-empty string id, or undefined. */
1550
- function idOrUndefined(value) {
1551
- return typeof value === "string" && value.length > 0 ? value : void 0;
1552
- }
1553
- /** A finite, non-negative integer count, or undefined. */
1554
- function countOrUndefined(value) {
1555
- return typeof value === "number" && Number.isFinite(value) && value >= 0 ? Math.round(value) : void 0;
1556
- }
1557
- function emit(bus, name, payload) {
1558
- if (!bus) return;
1559
- const clean = Object.fromEntries(Object.entries(payload).filter(([, value]) => value !== void 0));
1560
- try {
1561
- bus.emit(name, clean, { component: FLUIDGRIDS_ANALYTICS_COMPONENT });
1562
- } catch (error) {
1563
- console.warn(`[fluidgrids analytics] failed to emit ${name}`, error);
1564
- }
1565
- }
1566
- function asRecord$2(value) {
1567
- return typeof value === "object" && value !== null && !Array.isArray(value) ? value : null;
1568
- }
1569
- /**
1570
- * The executable node list of a workflow definition, wherever it sits: the
1571
- * flow store's `{ nodes }`, a saved `definitionJson` (`{ data: { nodes } }`) or
1572
- * a raw list.
1573
- */
1574
- function nodesOf(definition) {
1575
- if (Array.isArray(definition)) return definition;
1576
- const record = asRecord$2(definition);
1577
- if (!record) return [];
1578
- if (Array.isArray(record.nodes)) return record.nodes;
1579
- const data = asRecord$2(record.data);
1580
- if (data && Array.isArray(data.nodes)) return data.nodes;
1581
- return [];
1582
- }
1583
- function isTriggerNode(node) {
1584
- if ((typeof node.type === "string" ? node.type.toLowerCase() : "").includes("trigger")) return true;
1585
- const data = asRecord$2(node.data);
1586
- return data?.isTrigger === true || data?.category === "trigger";
1587
- }
1588
- /** Node-type slug of the workflow's trigger node, when it has one. */
1589
- function triggerTypeOf(definition) {
1590
- const trigger = nodesOf(definition).find(isTriggerNode);
1591
- return trigger ? toDimension(trigger.type) : void 0;
1592
- }
1593
- /** Number of executable nodes on the canvas. */
1594
- function nodeCountOf(definition) {
1595
- const nodes = nodesOf(definition);
1596
- return nodes.length > 0 ? nodes.length : void 0;
1597
- }
1598
- /** `fluidgrids.workflow.created` — a new workflow exists in the workspace. */
1599
- function emitWorkflowCreated(bus, fact) {
1600
- emit(bus, "fluidgrids.workflow.created", {
1601
- workspaceId: idOrUndefined(fact.workspaceId),
1602
- workflowId: idOrUndefined(fact.workflowId),
1603
- source: fact.source,
1604
- triggerType: triggerTypeOf(fact.definition),
1605
- nodeCount: nodeCountOf(fact.definition)
1606
- });
1607
- }
1608
- /** `fluidgrids.workflow.published` — a version was activated. */
1609
- function emitWorkflowPublished(bus, fact) {
1610
- emit(bus, "fluidgrids.workflow.published", {
1611
- workspaceId: idOrUndefined(fact.workspaceId),
1612
- workflowId: idOrUndefined(fact.workflowId),
1613
- triggerType: triggerTypeOf(fact.definition),
1614
- nodeCount: nodeCountOf(fact.definition)
1615
- });
1616
- }
1617
- /** `fluidgrids.workflow.run_started` — the backend accepted a run. */
1618
- function emitRunStarted(bus, fact) {
1619
- emit(bus, "fluidgrids.workflow.run_started", {
1620
- workspaceId: idOrUndefined(fact.workspaceId),
1621
- workflowId: idOrUndefined(fact.workflowId),
1622
- executionId: idOrUndefined(fact.executionId),
1623
- trigger: fact.trigger
1624
- });
1625
- }
1626
- /**
1627
- * `fluidgrids.workflow.run_failed` — a run this user started ended FAILED.
1628
- * `errorCode` is the run's machine error classification (`TIMEOUT`,
1629
- * `VALIDATION`, …), never its message.
1630
- */
1631
- function emitRunFailed(bus, fact) {
1632
- emit(bus, "fluidgrids.workflow.run_failed", {
1633
- workspaceId: idOrUndefined(fact.workspaceId),
1634
- workflowId: idOrUndefined(fact.workflowId),
1635
- executionId: idOrUndefined(fact.executionId),
1636
- trigger: fact.trigger,
1637
- errorCode: toDimension(fact.errorCode),
1638
- durationMs: countOrUndefined(fact.durationMs)
1639
- });
1640
- }
1641
- /** `fluidgrids.template.used` — a store template became a workflow. */
1642
- function emitTemplateUsed(bus, fact) {
1643
- emit(bus, "fluidgrids.template.used", {
1644
- workspaceId: idOrUndefined(fact.workspaceId),
1645
- templateId: idOrUndefined(fact.templateId),
1646
- category: toDimension(fact.category)
1647
- });
1648
- }
1649
- /** `fluidgrids.node.installed` — a store node was installed. */
1650
- function emitNodeInstalled(bus, fact) {
1651
- emit(bus, "fluidgrids.node.installed", {
1652
- workspaceId: idOrUndefined(fact.workspaceId),
1653
- nodeType: toDimension(fact.nodeType),
1654
- source: fact.source
1655
- });
1656
- }
1657
- /** `fluidgrids.quota.workflow_limit_hit` — a create was refused at the limit. */
1658
- function emitWorkflowLimitHit(bus, fact) {
1659
- emit(bus, "fluidgrids.quota.workflow_limit_hit", {
1660
- workspaceId: idOrUndefined(fact.workspaceId),
1661
- quotaKey: WORKFLOWS_QUOTA_NAME,
1662
- surface: fact.surface
1663
- });
1664
- }
1665
- /** `fluidgrids.quota.run_limit_hit` — a run was refused at the monthly limit. */
1666
- function emitRunLimitHit(bus, fact) {
1667
- emit(bus, "fluidgrids.quota.run_limit_hit", {
1668
- workspaceId: idOrUndefined(fact.workspaceId),
1669
- quotaKey: toDimension(fact.quotaKey) ?? "fluidgrids.runs.monthly",
1670
- surface: fact.surface
1671
- });
1672
- }
1673
- /** `fluidgrids.billing.upgrade_clicked` — a FluidGrids upgrade CTA was clicked. */
1674
- function emitUpgradeClicked(bus, fact) {
1675
- emit(bus, "fluidgrids.billing.upgrade_clicked", {
1676
- workspaceId: idOrUndefined(fact.workspaceId),
1677
- surface: fact.surface,
1678
- quotaKey: toDimension(fact.quotaKey)
1679
- });
1680
- }
1681
- /**
1682
- * Map a run's backend mode/trigger to the analytics trigger dimension. The
1683
- * builder's debug paths are always `TEST`; anything else a person started by
1684
- * hand is `manual`.
1685
- */
1686
- function runTriggerFromMode(mode) {
1687
- return typeof mode === "string" && mode.toUpperCase() === "TEST" ? "test" : "manual";
1688
- }
1689
-
1690
1383
  // src/billing/upgradePrompt.ts
1691
1384
  /**
1692
1385
  * The shared upgrade prompt for the monthly run allowance.
@@ -11046,4 +10739,4 @@ function useFluidGridsContext() {
11046
10739
  return context;
11047
10740
  }
11048
10741
 
11049
- export { isStringOptionList as $, usePaletteGates as $n, inAppLeaveTarget as $t, StoreNodeProductsByTypeDocument as A, isQuotaExhaustedFailure as An, useSaveStatusStore as At, useRunGuard as B, payloadFromCardValues as Bn, shouldReleaseForIdle as Bt, GetMyNodeInstallationsDocument as C, nodesOf as Cn, useSaveWorkflow as Ct, InstallWorkflowNodeDocument as D, WORKFLOWS_QUOTA_NAME as Dn, createThenOpen as Dt, InstallPurchasedNodeDocument as E, RUNS_QUOTA_NAME as En, classifyCreateRefusal as Et, getNodeMetadata as F, useCodeWorkflowInterface as Fn, leaseCallQueue as Ft, nodeSubtitle as G, PHASE_C_FLAGS_OFF as Gn, sessionBeforeReload as Gt, asRecord as H, signalPayloadCard as Hn, EDIT_SESSION_ID as Ht, buildOperationSeed as I, canSignalRun as In, leaseCallSequence as It, paramsFromOperation as J, useContinuousOptimisationEnabled as Jn, AUTOSAVE_DEBOUNCE_MS as Jt, nodeTitle as K, resolveFluidGridsFlagsSettled as Kn, rememberOwnStatusChange as Kt, createConfiguredNode as L, declaredSignals as Ln, phaseAfterAcquire as Lt, UninstallOrganizationPrivateNodeDocument as M, useNodeRegistryRevision as Mn, useEditLeaseStore as Mt, UninstallWorkflowNodeDocument as N, clearCodeWorkflowDefinitionCache as Nn, bannerOf as Nt, MyWorkflowTemplateSubmissionsDocument as O, collectExtensions as On, refusalOfQuota as Ot, WithdrawWorkflowTemplateSubmissionDocument as P, loadDefinitionJson as Pn, isLocked as Pt, stripSubmitActions as Q, useFluidGridsFlagsSettled as Qn, findSaveConflict as Qt, useInsertNode as R, durableInterfaceOf as Rn, phaseAfterTakeOver as Rt, CreateStoreOrderDocument as S, emitWorkflowPublished as Sn, useFlowValidator as St, InstallOrganizationPrivateNodeDocument as T, BILLING_PLANS_PATH as Tn, builderPathOf as Tt, coerceNumber as U, FLUIDGRIDS_FLAGS as Un, forgetSessionForReload as Ut, workflowParameterIssues as V, runSignalTargets as Vn, tickAction as Vt, fixedParameterState as W, FLUIDGRIDS_FLAG_DEFAULTS as Wn, rememberSessionForReload as Wt, useNodeConfig as X, useDurableParityEnabled as Xn, canAutosave as Xt, selectedOperationOf as Y, useDurableFunctionNodesEnabled as Yn, AUTOSAVE_RETRY_DELAYS_MS as Yt, resolveUiSpec as Z, useFluidGridsFlag as Zn, codeBuildIdOf as Zt, registryNodeData as _, emitRunStarted as _n, leavingLosesChanges as _t, NODES_METADATA as a, runDurationMs as an, matchesAdapterProvider as ar, casesFromRules as at, BrowseWorkflowNodesDocument as b, emitWorkflowCreated as bn, watchLeavingLosesChanges as bt, ensureInstalledNodeTypesLoaded as c, structuredParameterType as cn, getNodeDetail as cr, latestNodeLog as ct, ensureRegistryNodeTypesLoaded as d, isParamVisible as dn, useBuilderReadOnly as dr, useGuardedNavigate as dt, saveFailureActionOf as en, usePhaseCFlags as er, optionListText as et, isNodeConfigsInitialized as f, useFluidGridsAnalytics as fn, createGlobalStoreClient as fr, useManualSave as ft, registerWorkflowNodeTypes as g, emitRunLimitHit as gn, setGlobalStoreClient as gr, editingLeaseLocked as gt, registerNodeManifests as h, emitRunFailed as hn, resetGlobalStoreClient as hr, editStateFor as ht, AVAILABLE_NODES as i, nodeStateDurationMs as in, isOptionalAdapter as ir, SwitchRulesEditor as it, SubmitWorkflowTemplateDocument as j, useCanvasEdges as jn, useEditLeaseLocked as jt, OrganizationPrivateNodesDocument as k, findQuotaRefusal as kn, saveIndicatorOf as kt, ensureNodeConfigsLoaded as l, fieldsFromValue as ln, buildStickyNode as lr, boundFieldsOf as lt, refetchStoreNodes as m, emitNodeInstalled as mn, global_client_exports as mr, departingSave as mt, FluidGridsProvider as n, useNodeExecution as nn, useWorkflowTestsEnabled as nr, resolveLoadOptionsSpec as nt, NODE_CONFIGS as o, formatParameterValue as on, newConnectionProviderKey as or, FieldTree as ot, onNodeTypesUpdate as p, openRunQuotaUpgradePrompt as pn, getGlobalStoreClient as pr, autosaveAllowedFor as pt, optionText as q, resolvePhaseCFlags as qn, rememberRevision as qt, useFluidGridsContext as r, formatElapsedMs as rn, connectionsForAdapter as rr, ConditionTreeBuilder as rt, NODE_TYPES as s, parseParameterValue as sn, replaceAdapterConnections as sr, parseMappingValue as st, FluidGridsContext as t, workflowFingerprint as tn, useSelfHostedWorkersEnabled as tr, optionListValues as tt, ensureNodeTypesLoaded as u, resolveNodeOperation as un, BuilderReadOnlyProvider as ur, missingRequiredParameters as ut, scheduleNodePaletteLoad as v, emitTemplateUsed as vn, savedEverythingBeforeLeaving as vt, GetNodeInstallableVersionsDocument as w, runTriggerFromMode as wn, blankWorkflowCreateInput as wt, BrowseWorkflowTemplatesDocument as x, emitWorkflowLimitHit as xn, isFlowComplete as xt, global_operations_exports as y, emitUpgradeClicked as yn, touchesSavedFields as yt, MissingParametersDialog as z, parseRawSignalPayload as zn, releasesOnClose as zt };
10742
+ export { isStringOptionList as $, setGlobalStoreClient as $n, inAppLeaveTarget as $t, StoreNodeProductsByTypeDocument as A, resolvePhaseCFlags as An, useSaveStatusStore as At, useRunGuard as B, connectionsForAdapter as Bn, shouldReleaseForIdle as Bt, GetMyNodeInstallationsDocument as C, payloadFromCardValues as Cn, useSaveWorkflow as Ct, InstallWorkflowNodeDocument as D, FLUIDGRIDS_FLAG_DEFAULTS as Dn, createThenOpen as Dt, InstallPurchasedNodeDocument as E, FLUIDGRIDS_FLAGS as En, classifyCreateRefusal as Et, getNodeMetadata as F, useFluidGridsFlagsSettled as Fn, leaseCallQueue as Ft, nodeSubtitle as G, getNodeDetail as Gn, sessionBeforeReload as Gt, asRecord as H, matchesAdapterProvider as Hn, EDIT_SESSION_ID as Ht, buildOperationSeed as I, usePaletteGates as In, leaseCallSequence as It, paramsFromOperation as J, useBuilderReadOnly as Jn, AUTOSAVE_DEBOUNCE_MS as Jt, nodeTitle as K, buildStickyNode as Kn, rememberOwnStatusChange as Kt, createConfiguredNode as L, usePhaseCFlags as Ln, phaseAfterAcquire as Lt, UninstallOrganizationPrivateNodeDocument as M, useDurableFunctionNodesEnabled as Mn, useEditLeaseStore as Mt, UninstallWorkflowNodeDocument as N, useDurableParityEnabled as Nn, bannerOf as Nt, MyWorkflowTemplateSubmissionsDocument as O, PHASE_C_FLAGS_OFF as On, refusalOfQuota as Ot, WithdrawWorkflowTemplateSubmissionDocument as P, useFluidGridsFlag as Pn, isLocked as Pt, stripSubmitActions as Q, resetGlobalStoreClient as Qn, findSaveConflict as Qt, useInsertNode as R, useSelfHostedWorkersEnabled as Rn, phaseAfterTakeOver as Rt, CreateStoreOrderDocument as S, parseRawSignalPayload as Sn, useFlowValidator as St, InstallOrganizationPrivateNodeDocument as T, signalPayloadCard as Tn, builderPathOf as Tt, coerceNumber as U, newConnectionProviderKey as Un, forgetSessionForReload as Ut, workflowParameterIssues as V, isOptionalAdapter as Vn, tickAction as Vt, fixedParameterState as W, replaceAdapterConnections as Wn, rememberSessionForReload as Wt, useNodeConfig as X, getGlobalStoreClient as Xn, canAutosave as Xt, selectedOperationOf as Y, createGlobalStoreClient as Yn, AUTOSAVE_RETRY_DELAYS_MS as Yt, resolveUiSpec as Z, global_client_exports as Zn, codeBuildIdOf as Zt, registryNodeData as _, loadDefinitionJson as _n, leavingLosesChanges as _t, NODES_METADATA as a, runDurationMs as an, casesFromRules as at, BrowseWorkflowNodesDocument as b, declaredSignals as bn, watchLeavingLosesChanges as bt, ensureInstalledNodeTypesLoaded as c, structuredParameterType as cn, latestNodeLog as ct, ensureRegistryNodeTypesLoaded as d, isParamVisible as dn, useGuardedNavigate as dt, saveFailureActionOf as en, optionListText as et, isNodeConfigsInitialized as f, useFluidGridsAnalytics as fn, useManualSave as ft, registerWorkflowNodeTypes as g, clearCodeWorkflowDefinitionCache as gn, editingLeaseLocked as gt, registerNodeManifests as h, useNodeRegistryRevision as hn, editStateFor as ht, AVAILABLE_NODES as i, nodeStateDurationMs as in, SwitchRulesEditor as it, SubmitWorkflowTemplateDocument as j, useContinuousOptimisationEnabled as jn, useEditLeaseLocked as jt, OrganizationPrivateNodesDocument as k, resolveFluidGridsFlagsSettled as kn, saveIndicatorOf as kt, ensureNodeConfigsLoaded as l, fieldsFromValue as ln, boundFieldsOf as lt, refetchStoreNodes as m, useCanvasEdges as mn, departingSave as mt, FluidGridsProvider as n, useNodeExecution as nn, resolveLoadOptionsSpec as nt, NODE_CONFIGS as o, formatParameterValue as on, FieldTree as ot, onNodeTypesUpdate as p, openRunQuotaUpgradePrompt as pn, autosaveAllowedFor as pt, optionText as q, BuilderReadOnlyProvider as qn, rememberRevision as qt, useFluidGridsContext as r, formatElapsedMs as rn, ConditionTreeBuilder as rt, NODE_TYPES as s, parseParameterValue as sn, parseMappingValue as st, FluidGridsContext as t, workflowFingerprint as tn, optionListValues as tt, ensureNodeTypesLoaded as u, resolveNodeOperation as un, missingRequiredParameters as ut, scheduleNodePaletteLoad as v, useCodeWorkflowInterface as vn, savedEverythingBeforeLeaving as vt, GetNodeInstallableVersionsDocument as w, runSignalTargets as wn, blankWorkflowCreateInput as wt, BrowseWorkflowTemplatesDocument as x, durableInterfaceOf as xn, isFlowComplete as xt, global_operations_exports as y, canSignalRun as yn, touchesSavedFields as yt, MissingParametersDialog as z, useWorkflowTestsEnabled as zn, releasesOnClose as zt };
@@ -1,5 +1,5 @@
1
1
  "use client";
2
- import { d as useRestoreWorkflowVersion, h as useWorkflowDefinitions } from "./useWorkflows-D01LC39Y.js";
2
+ import { d as useRestoreWorkflowVersion, h as useWorkflowDefinitions } from "./useWorkflows-DyhtoVwp.js";
3
3
  import { i as versionsOfWorkflow, t as VersionDiffDialog } from "./VersionDiffDialog-Dq2xlPFI.js";
4
4
  import { r as useTr } from "./TranslationBridge-Da-TPgQm.js";
5
5
  import { qi as getFluidGridsConfig } from "./node-endpoint-configs-DHFGA5MQ.js";
@@ -1,12 +1,12 @@
1
1
  "use client";
2
2
  import { Fn as SnoozeOptimisationSuggestionDocument, Gr as WorkflowProposalDocument, It as OptimisationSuggestionsDocument, Oi as getFluidGridsClient, On as SetContinuousOptimisationEnabledDocument, Q as DismissOptimisationSuggestionDocument, T as ContinuousOptimisationSettingsDocument, Ti as WorkspaceAiUsageDocument, Ui as throwIfResultError, Ut as ProposeOptimisationDocument, it as ErrorAnalyticsDocument, mt as FgRunOptimisationScanDocument } from "./node-endpoint-configs-DHFGA5MQ.js";
3
- import { Jn as useContinuousOptimisationEnabled } from "./FluidGridsProvider-B30VcLdX.js";
3
+ import { jn as useContinuousOptimisationEnabled } from "./FluidGridsProvider-B9RR_CI_.js";
4
4
  import { r as useTr } from "./TranslationBridge-Da-TPgQm.js";
5
5
  import { HC as OptimisationDismissReason, UC as OptimisationKind, WC as OptimisationSuggestionStatus, hI as FLUIDGRIDS_PERMISSIONS, vI as SdkPermissionButton, xI as useFluidGridsPermission } from "./graphql-types-XcDLtFwU.js";
6
6
  import { t as proposalCanvasPath } from "./useRequestedProposal-B7uPXfZB.js";
7
7
  import { c as runListPath, l as utcDay, n as FailureTriagePanel } from "./FailureTriagePanel-BHiduL7A.js";
8
8
  import { a as formatTokens, c as DISMISS_REASONS, f as monthlySavingLabel, i as aiSpendPeriod, l as evidenceFacts, p as shortRunId, r as aiCost, s as runsOfWorkflowPath, t as AI_SPEND_RANGE_DAYS, u as evidenceWindowDays } from "./ai-usage-D5p7ZeRR.js";
9
- import { n as useDataSinks, o as useRunReplayActions, r as useInsightsData, t as useDataSinkData } from "./useObservability-CmFFXmKb.js";
9
+ import { n as useDataSinks, o as useRunReplayActions, r as useInsightsData, t as useDataSinkData } from "./useObservability-BkxhHZsX.js";
10
10
  import { useCallback, useEffect, useMemo, useRef, useState } from "react";
11
11
  import { Link, useNavigate } from "react-router";
12
12
  import { Icon } from "@iconify/react";
@@ -1,6 +1,6 @@
1
1
  "use client";
2
2
  import { Bi as describeOperationError, Oi as getFluidGridsClient, Tt as ManagedAiWorkspacePolicyDocument, Ui as throwIfResultError, Vr as WorkflowNotificationSettingsDocument, ar as UpdateManagedAiWorkspacePolicyDocument, ir as UpdateDurableHistoryCapsDocument, lr as UpdateWorkflowNotificationSettingsDocument, qi as getFluidGridsConfig, tt as DurableHistoryCapsDocument } from "./node-endpoint-configs-DHFGA5MQ.js";
3
- import { At as useSaveStatusStore, Qt as findSaveConflict, Un as FLUIDGRIDS_FLAGS, Xn as useDurableParityEnabled, Zn as useFluidGridsFlag, er as usePhaseCFlags, pr as getGlobalStoreClient } from "./FluidGridsProvider-B30VcLdX.js";
3
+ import { At as useSaveStatusStore, En as FLUIDGRIDS_FLAGS, Ln as usePhaseCFlags, Nn as useDurableParityEnabled, Pn as useFluidGridsFlag, Qt as findSaveConflict, Xn as getGlobalStoreClient } from "./FluidGridsProvider-B9RR_CI_.js";
4
4
  import { H as useFlowStore } from "./node-operation-selection--oy-yEq_.js";
5
5
  import { r as useTr } from "./TranslationBridge-Da-TPgQm.js";
6
6
  import { Wt as useWorkflowDefinitionQuery, a as useConnections, n as useAgentDefinitions, qt as useWorkflowDefinitionsQuery, zt as useUpdateWorkflowDefinitionMutation } from "./useAgentDefinitions-NFtLytDR.js";
@@ -8,7 +8,7 @@ import { KF as WorkflowSearchAttributeType, hI as FLUIDGRIDS_PERMISSIONS, xI as
8
8
  import { t as FluidGridsDocsLink } from "./FluidGridsDocsLink-JxkBpOeb.js";
9
9
  import { C as createSearchAttribute, E as deleteSearchAttribute, J as saveArchiveSettings, N as fetchCodecServerSettings, P as fetchPauseRules, R as fetchSearchAttributes, S as createPauseRule, T as deletePauseRule, Y as saveCodecServerSettings, _ as useResource, a as formToInput$2, b as clearArchiveSettings, c as FieldError, d as NativeSelect, i as emptyAgentForm, k as fetchArchiveSettings, n as agentToForm, o as grantDays, p as StatusPill, r as describeRule, t as AgentFormError } from "./agent-form-BvMWhQ42.js";
10
10
  import { c as budgetInputValue, d as withBudgetMode, f as EffectBadge, m as useActionPolicies, n as checkCodecServerUrl, p as effectLabel, s as BUDGET_DIMENSIONS, u as withBudgetLimit } from "./codec-client-DstqyzTN.js";
11
- import { a as useLogStreamDestinations, i as useLogStreamDestinationActions } from "./useObservability-CmFFXmKb.js";
11
+ import { a as useLogStreamDestinations, i as useLogStreamDestinationActions } from "./useObservability-BkxhHZsX.js";
12
12
  import { createContext, useCallback, useContext, useEffect, useLayoutEffect, useMemo, useRef, useState } from "react";
13
13
  import { useNavigate, useParams } from "react-router";
14
14
  import { Icon } from "@iconify/react";
@@ -1,5 +1,5 @@
1
1
  "use client";
2
- import { A as DialogFooter, E as Dialog, O as DialogContent, P as DialogTitle, j as DialogHeader, k as DialogDescription, w as Badge } from "./flow-builder-BR8p5tXG.js";
2
+ import { C as Dialog, D as DialogFooter, E as DialogDescription, O as DialogHeader, T as DialogContent, j as DialogTitle, x as Badge } from "./flow-builder-C_3sY3pZ.js";
3
3
  import { i as Button } from "./PublishCustomNodeAction-D2F7oN0S.js";
4
4
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
5
5
  import { AlertTriangle, CheckCircle2, Download, ExternalLink, Loader2, Puzzle, ShoppingCart } from "lucide-react";
@@ -1,5 +1,5 @@
1
1
  "use client";
2
- import { A as DialogFooter, Ct as Input, E as Dialog, O as DialogContent, P as DialogTitle, j as DialogHeader, k as DialogDescription, w as Badge } from "./flow-builder-BR8p5tXG.js";
2
+ import { C as Dialog, D as DialogFooter, E as DialogDescription, O as DialogHeader, T as DialogContent, bt as Input, j as DialogTitle, x as Badge } from "./flow-builder-C_3sY3pZ.js";
3
3
  import { i as Button } from "./PublishCustomNodeAction-D2F7oN0S.js";
4
4
  import { t as Label } from "./label-CDy86rIZ.js";
5
5
  import { r as useTr } from "./TranslationBridge-Da-TPgQm.js";
@@ -1,6 +1,6 @@
1
1
  "use client";
2
2
  import { i as Button } from "./PublishCustomNodeAction-D2F7oN0S.js";
3
- import { C as templatePreview, w as Badge } from "./flow-builder-BR8p5tXG.js";
3
+ import { b as templatePreview, x as Badge } from "./flow-builder-C_3sY3pZ.js";
4
4
  import { r as useTr } from "./TranslationBridge-Da-TPgQm.js";
5
5
  import { hI as FLUIDGRIDS_PERMISSIONS, vI as SdkPermissionButton } from "./graphql-types-XcDLtFwU.js";
6
6
  import { Icon } from "@iconify/react";
@@ -1,10 +1,11 @@
1
1
  "use client";
2
2
  import { Bi as describeOperationError, Ui as throwIfResultError } from "./node-endpoint-configs-DHFGA5MQ.js";
3
- import { An as isQuotaExhaustedFailure, O as MyWorkflowTemplateSubmissionsDocument, P as WithdrawWorkflowTemplateSubmissionDocument, Tn as BILLING_PLANS_PATH, fn as useFluidGridsAnalytics, j as SubmitWorkflowTemplateDocument, vn as emitTemplateUsed } from "./FluidGridsProvider-B30VcLdX.js";
3
+ import { O as MyWorkflowTemplateSubmissionsDocument, P as WithdrawWorkflowTemplateSubmissionDocument, fn as useFluidGridsAnalytics, j as SubmitWorkflowTemplateDocument } from "./FluidGridsProvider-B9RR_CI_.js";
4
4
  import { r as useTr } from "./TranslationBridge-Da-TPgQm.js";
5
- import { H as useWorkflowTemplates, L as useTemplateImportFlow, S as TemplateCard, V as useImportWorkflowTemplate, et as useGlobalStoreClient, t as FlowBuilderPage } from "./flow-builder-BR8p5tXG.js";
6
- import { h as useWorkflowDefinitions, l as useLazyWorkflowDefinition, s as useDuplicateWorkflow } from "./useWorkflows-D01LC39Y.js";
7
- import { k as QuotaExhaustedDialog } from "./WorkflowShareDialog-DnBQA3V6.js";
5
+ import { P as useTemplateImportFlow, R as useImportWorkflowTemplate, Z as useGlobalStoreClient, t as FlowBuilderPage, y as TemplateCard, z as useWorkflowTemplates } from "./flow-builder-C_3sY3pZ.js";
6
+ import { a as emitTemplateUsed, f as BILLING_PLANS_PATH, y as isQuotaExhaustedFailure } from "./fluidgridsEvents-CNdcrUNN.js";
7
+ import { h as useWorkflowDefinitions, l as useLazyWorkflowDefinition, s as useDuplicateWorkflow } from "./useWorkflows-DyhtoVwp.js";
8
+ import { k as QuotaExhaustedDialog } from "./WorkflowShareDialog-0Ai1HED-.js";
8
9
  import { YF as WorkflowStatus, hI as FLUIDGRIDS_PERMISSIONS, vI as SdkPermissionButton } from "./graphql-types-XcDLtFwU.js";
9
10
  import { n as useFluidGridsPageControls } from "./pageControlsBridge-0pX9s-3k.js";
10
11
  import { r as templatesControls } from "./pageControlSpecs-DZJ9K37m.js";
@@ -1,13 +1,14 @@
1
1
  "use client";
2
2
  import { Dr as WorkflowDefinitionDocument, Oi as getFluidGridsClient, Ui as throwIfResultError, oa as __exportAll, qi as getFluidGridsConfig } from "./node-endpoint-configs-DHFGA5MQ.js";
3
- import { At as useSaveStatusStore, Et as classifyCreateRefusal, J as paramsFromOperation, L as createConfiguredNode, Tn as BILLING_PLANS_PATH, Zt as codeBuildIdOf, g as registerWorkflowNodeTypes, h as registerNodeManifests, jn as useCanvasEdges, m as refetchStoreNodes, n as FluidGridsProvider, o as NODE_CONFIGS, qt as rememberRevision, tn as workflowFingerprint, u as ensureNodeTypesLoaded, un as resolveNodeOperation, wt as blankWorkflowCreateInput } from "./FluidGridsProvider-B30VcLdX.js";
3
+ import { At as useSaveStatusStore, Et as classifyCreateRefusal, J as paramsFromOperation, L as createConfiguredNode, Zt as codeBuildIdOf, g as registerWorkflowNodeTypes, h as registerNodeManifests, m as refetchStoreNodes, mn as useCanvasEdges, n as FluidGridsProvider, o as NODE_CONFIGS, qt as rememberRevision, tn as workflowFingerprint, u as ensureNodeTypesLoaded, un as resolveNodeOperation, wt as blankWorkflowCreateInput } from "./FluidGridsProvider-B9RR_CI_.js";
4
4
  import { F as mergeStickyNotes, H as useFlowStore } from "./node-operation-selection--oy-yEq_.js";
5
5
  import { r as useTr } from "./TranslationBridge-Da-TPgQm.js";
6
- import { B as getWorkflowNodeTypes, Ct as Input, R as buildNodeCheck, U as useInstalledNodes, _t as Card, gt as FluidGridsMark, h as useWorkflowReloadStore, ht as useNodeSelectedEvent, m as releaseLeaseKeptForReload, t as FlowBuilderPage, z as buildRequiredNodeTypes } from "./flow-builder-BR8p5tXG.js";
6
+ import { B as useInstalledNodes, F as buildNodeCheck, I as buildRequiredNodeTypes, L as getWorkflowNodeTypes, bt as Input, ft as useNodeSelectedEvent, h as useWorkflowReloadStore, m as releaseLeaseKeptForReload, mt as Card, pt as FluidGridsMark, t as FlowBuilderPage } from "./flow-builder-C_3sY3pZ.js";
7
+ import { f as BILLING_PLANS_PATH } from "./fluidgridsEvents-CNdcrUNN.js";
7
8
  import { t as cn } from "./cn-QqidFIgr.js";
8
9
  import { i as Button } from "./PublishCustomNodeAction-D2F7oN0S.js";
9
- import { l as useLazyWorkflowDefinition, m as useWorkflowDefinition, n as useCreateWorkflow } from "./useWorkflows-D01LC39Y.js";
10
- import { O as CreateWorkflowRefusalDialog } from "./WorkflowShareDialog-DnBQA3V6.js";
10
+ import { l as useLazyWorkflowDefinition, m as useWorkflowDefinition, n as useCreateWorkflow } from "./useWorkflows-DyhtoVwp.js";
11
+ import { O as CreateWorkflowRefusalDialog } from "./WorkflowShareDialog-0Ai1HED-.js";
11
12
  import { c as withoutGuidedTourIntent, l as decideMissingWorkflow, o as isGuidedTourIntent, s as pickGuidedTour, u as isCreateIntent } from "./firstWorkflow-C_h0KMB2.js";
12
13
  import { t as canvasFromDefinition } from "./definition-canvas--3MPHoP-.js";
13
14
  import { n as registerLiveCanvasHandler } from "./liveCanvas-D5ytXDp8.js";
@@ -1626,7 +1627,7 @@ function GuidedTourStarter({ ready }) {
1626
1627
  }
1627
1628
 
1628
1629
  // src/builder/app/workflow/work/page.tsx
1629
- const LazyMissingNodesInstallModal = lazy(() => import("./MissingNodesInstallModal-Cj31oMDX.js").then((m) => ({ default: m.MissingNodesInstallModal })));
1630
+ const LazyMissingNodesInstallModal = lazy(() => import("./MissingNodesInstallModal-Dm0nMBXM.js").then((m) => ({ default: m.MissingNodesInstallModal })));
1630
1631
  function WorkflowItem({ readonly = false }) {
1631
1632
  if (readonly) {
1632
1633
  const queryParams = new URLSearchParams(window.location.search);
@@ -1666,7 +1667,10 @@ function WorkflowItem({ readonly = false }) {
1666
1667
  const seenReloadNonceRef = useRef(reloadNonce);
1667
1668
  const pendingReloadRef = useRef(null);
1668
1669
  const [reloadFailed, setReloadFailed] = useState(false);
1669
- const { getWorkflow } = useLazyWorkflowDefinition({ withNodeManifests: true });
1670
+ const { getWorkflow } = useLazyWorkflowDefinition({
1671
+ withNodeManifests: true,
1672
+ routeCritical: true
1673
+ });
1670
1674
  const { createWorkflow } = useCreateWorkflow();
1671
1675
  const creatingRef = useRef(false);
1672
1676
  const fromSharedLoadedRef = useRef(false);
@@ -1694,8 +1698,8 @@ function WorkflowItem({ readonly = false }) {
1694
1698
  setInstalling(true);
1695
1699
  setInstallErrors([]);
1696
1700
  try {
1697
- const { getGlobalStoreClient } = await import("./FluidGridsProvider-B30VcLdX.js").then((n) => n.mr);
1698
- const { InstallWorkflowNodeDocument } = await import("./FluidGridsProvider-B30VcLdX.js").then((n) => n.y);
1701
+ const { getGlobalStoreClient } = await import("./FluidGridsProvider-B9RR_CI_.js").then((n) => n.Zn);
1702
+ const { InstallWorkflowNodeDocument } = await import("./FluidGridsProvider-B9RR_CI_.js").then((n) => n.y);
1699
1703
  const { getFluidGridsConfig } = await import("./node-endpoint-configs-DHFGA5MQ.js").then((n) => n.Ki);
1700
1704
  const storeClient = getGlobalStoreClient();
1701
1705
  const cfg = getFluidGridsConfig();
@@ -1850,7 +1854,7 @@ function WorkflowItem({ readonly = false }) {
1850
1854
  return;
1851
1855
  }
1852
1856
  const freshCreate = createIntentRef.current && !creatingRef.current && !fetchedCopy() && !loadRunId;
1853
- const result = freshCreate ? null : await getWorkflow(id, void 0, version);
1857
+ const result = freshCreate ? null : await getWorkflow(id, void 0, version, { reusePrefetched: !reloadPending() });
1854
1858
  const definitionJson = result?.definitionJson;
1855
1859
  const defData = definitionJson?.data ?? (definitionJson?.nodes ? definitionJson : void 0);
1856
1860
  if (defData) {
@@ -1,7 +1,8 @@
1
1
  "use client";
2
2
  import { Bi as describeOperationError, Nn as ShareWorkflowDocument, Oi as getFluidGridsClient, Ui as throwIfResultError, ft as ExportWorkflowCodeDocument, ui as WorkflowSharingDocument } from "./node-endpoint-configs-DHFGA5MQ.js";
3
- import { Dn as WORKFLOWS_QUOTA_NAME, fn as useFluidGridsAnalytics, xn as emitWorkflowLimitHit, yn as emitUpgradeClicked } from "./FluidGridsProvider-B30VcLdX.js";
3
+ import { fn as useFluidGridsAnalytics } from "./FluidGridsProvider-B9RR_CI_.js";
4
4
  import { r as useTr } from "./TranslationBridge-Da-TPgQm.js";
5
+ import { c as emitWorkflowLimitHit, h as WORKFLOWS_QUOTA_NAME, o as emitUpgradeClicked } from "./fluidgridsEvents-CNdcrUNN.js";
5
6
  import { CF as WorkflowExportFormat, Fd as FidelityLevel, JF as WorkflowShareRole, hF as WorkflowAccess, nI as WorkflowVisibility, qF as WorkflowSharePrincipalType } from "./graphql-types-XcDLtFwU.js";
6
7
  import { useCallback, useEffect, useMemo, useRef, useState } from "react";
7
8
  import { jsx, jsxs } from "react/jsx-runtime";
@@ -1,12 +1,13 @@
1
1
  "use client";
2
- import { c as useImportWorkflow, h as useWorkflowDefinitions, l as useLazyWorkflowDefinition, n as useCreateWorkflow, o as useDeleteWorkflow, s as useDuplicateWorkflow, u as usePreviewN8nImport } from "./useWorkflows-D01LC39Y.js";
3
- import { An as isQuotaExhaustedFailure, Dt as createThenOpen, Tn as BILLING_PLANS_PATH, Un as FLUIDGRIDS_FLAGS, Zn as useFluidGridsFlag, t as FluidGridsContext } from "./FluidGridsProvider-B30VcLdX.js";
4
- import { C as readProjectArchive, D as workflowNameFromFile, E as typeScriptModuleFile, O as CreateWorkflowRefusalDialog, S as primaryImportModule, T as typeScriptImportSource, _ as importFileKind, a as downloadWorkflowExport, c as canShareWorkflow, d as MAX_IMPORT_ARCHIVE_BYTES, f as MAX_IMPORT_SOURCE_BYTES, g as importAcceptAttribute, k as QuotaExhaustedDialog, l as CODE_EXPORT_FORMATS, m as checkTypeScriptImport, o as parseWorkflowImport, p as assertImportByteSize, r as useExportWorkflowAs, s as canEditWorkflow, t as WorkflowShareDialog, u as ImportSourceError } from "./WorkflowShareDialog-DnBQA3V6.js";
2
+ import { c as useImportWorkflow, h as useWorkflowDefinitions, l as useLazyWorkflowDefinition, n as useCreateWorkflow, o as useDeleteWorkflow, s as useDuplicateWorkflow, u as usePreviewN8nImport } from "./useWorkflows-DyhtoVwp.js";
3
+ import { Dt as createThenOpen, En as FLUIDGRIDS_FLAGS, Pn as useFluidGridsFlag, t as FluidGridsContext } from "./FluidGridsProvider-B9RR_CI_.js";
4
+ import { C as readProjectArchive, D as workflowNameFromFile, E as typeScriptModuleFile, O as CreateWorkflowRefusalDialog, S as primaryImportModule, T as typeScriptImportSource, _ as importFileKind, a as downloadWorkflowExport, c as canShareWorkflow, d as MAX_IMPORT_ARCHIVE_BYTES, f as MAX_IMPORT_SOURCE_BYTES, g as importAcceptAttribute, k as QuotaExhaustedDialog, l as CODE_EXPORT_FORMATS, m as checkTypeScriptImport, o as parseWorkflowImport, p as assertImportByteSize, r as useExportWorkflowAs, s as canEditWorkflow, t as WorkflowShareDialog, u as ImportSourceError } from "./WorkflowShareDialog-0Ai1HED-.js";
5
+ import { f as BILLING_PLANS_PATH, y as isQuotaExhaustedFailure } from "./fluidgridsEvents-CNdcrUNN.js";
5
6
  import { H as useFlowStore } from "./node-operation-selection--oy-yEq_.js";
6
7
  import { CF as WorkflowExportFormat, gF as WorkflowAccessFilter, hI as FLUIDGRIDS_PERMISSIONS, vI as SdkPermissionButton, xI as useFluidGridsPermission, yI as SdkPermissionGate } from "./graphql-types-XcDLtFwU.js";
7
8
  import { r as useTr } from "./TranslationBridge-Da-TPgQm.js";
8
9
  import { $t as RenameWorkflowFolderDocument, Bi as describeOperationError, Et as MoveWorkflowFolderDocument, K as DeleteWorkflowFolderDocument, M as CreateWorkflowFolderDocument, N as CreateWorkflowProjectDocument, Oi as getFluidGridsClient, Pr as WorkflowFoldersDocument, Ui as throwIfResultError, Ur as WorkflowProjectsDocument, _ as BulkMoveWorkflowsToFolderDocument, en as RenameWorkflowProjectDocument, g as BulkDeleteWorkflowsDocument, h as BulkAssignWorkflowsToProjectDocument, oa as __exportAll, q as DeleteWorkflowProjectDocument } from "./node-endpoint-configs-DHFGA5MQ.js";
9
- import { a as useExecutions } from "./useExecutions-CNEN1ENQ.js";
10
+ import { a as useExecutions } from "./useExecutions-DkS0FTfw.js";
10
11
  import { a as firstWorkflowProgress, i as builderPathFor, r as GUIDED_TOUR_STATE } from "./firstWorkflow-C_h0KMB2.js";
11
12
  import { n as useFluidGridsPageControls } from "./pageControlsBridge-0pX9s-3k.js";
12
13
  import { i as workflowsListControls } from "./pageControlSpecs-DZJ9K37m.js";
@@ -0,0 +1,3 @@
1
+
2
+ import { a as createUiMarkTools, c as FluidGridsAgentToolDeps, d as triggerNodesOf, i as UiMarkToolOptions, l as createFluidGridsAgentTools, n as resetAgentMarks, o as AgentCalloutOverlay, r as useAgentMarksStore, s as AgentCalloutOverlayProps, t as CanvasNote, u as pickTriggerNode } from "./index-CHeY7_A1.js";
3
+ export { AgentCalloutOverlay, type AgentCalloutOverlayProps, type CanvasNote, type FluidGridsAgentToolDeps, type UiMarkToolOptions, createFluidGridsAgentTools, createUiMarkTools, pickTriggerNode, resetAgentMarks, triggerNodesOf, useAgentMarksStore };
@@ -0,0 +1,5 @@
1
+ "use client";
2
+ import { a as triggerNodesOf, i as pickTriggerNode, n as AgentCalloutOverlay, r as createFluidGridsAgentTools, t as createUiMarkTools } from "./uiMarkTools-nlmzsHQM.js";
3
+ import { n as useAgentMarksStore, t as resetAgentMarks } from "./marksStore-DGCXjTmZ.js";
4
+
5
+ export { AgentCalloutOverlay, createFluidGridsAgentTools, createUiMarkTools, pickTriggerNode, resetAgentMarks, triggerNodesOf, useAgentMarksStore };