@burdenoff/fluidgrids-fe-sdk 2026.1113.12 → 2026.1114.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.
@@ -3423,6 +3423,7 @@ function useWorkspaceSecurityReport() {
3423
3423
  const refresh = useCallback(() => {
3424
3424
  setState((current) => ({
3425
3425
  ...current,
3426
+ error: null,
3426
3427
  loading: true
3427
3428
  }));
3428
3429
  setGeneration((value) => value + 1);
@@ -3513,6 +3514,20 @@ function findingKey(finding) {
3513
3514
  finding.connectionId ?? ""
3514
3515
  ].join("|");
3515
3516
  }
3517
+ /**
3518
+ * One unique key per finding row. Two findings with the same check, workflow,
3519
+ * version, node and connection would collide on {@link findingKey}; later
3520
+ * repeats get a `#n` suffix so React keys stay unique.
3521
+ */
3522
+ function uniqueFindingKeys(findings) {
3523
+ const seen = /* @__PURE__ */ new Map();
3524
+ return findings.map((finding) => {
3525
+ const key = findingKey(finding);
3526
+ const count = seen.get(key) ?? 0;
3527
+ seen.set(key, count + 1);
3528
+ return count === 0 ? key : `${key}#${count}`;
3529
+ });
3530
+ }
3516
3531
 
3517
3532
  // src/modules/settings/utils/security-report-labels.ts
3518
3533
  const TONE_CLASSES$1 = {
@@ -3766,6 +3781,7 @@ function FindingsTable({ tr, findings, hasAnyFindings }) {
3766
3781
  children: !hasAnyFindings ? tr("fluidgrids.settings.securityReport.noFindings", "No risky workflows found.") : tr("fluidgrids.settings.securityReport.noMatches", "No findings match these filters.")
3767
3782
  })]
3768
3783
  });
3784
+ const rowKeys = uniqueFindingKeys(findings);
3769
3785
  return /* @__PURE__ */ jsx("div", {
3770
3786
  className: "overflow-x-auto rounded-lg border border-border-default bg-surface",
3771
3787
  children: /* @__PURE__ */ jsxs("table", {
@@ -3795,10 +3811,10 @@ function FindingsTable({ tr, findings, hasAnyFindings }) {
3795
3811
  children: tr("fluidgrids.settings.securityReport.detailsColumn", "What to do")
3796
3812
  })
3797
3813
  ] })
3798
- }), /* @__PURE__ */ jsx("tbody", { children: findings.map((finding) => /* @__PURE__ */ jsx(FindingRow, {
3814
+ }), /* @__PURE__ */ jsx("tbody", { children: findings.map((finding, index) => /* @__PURE__ */ jsx(FindingRow, {
3799
3815
  finding,
3800
3816
  tr
3801
- }, findingKey(finding))) })]
3817
+ }, rowKeys[index])) })]
3802
3818
  })
3803
3819
  });
3804
3820
  }
@@ -87,9 +87,18 @@ function formatAge(iso, now = Date.now()) {
87
87
  if (seconds < 86400) return `${Math.round(seconds / 3600)}h ago`;
88
88
  return new Date(iso).toLocaleDateString();
89
89
  }
90
+ /**
91
+ * The queue a worker token names for one queue row (spec 06 §6, G10): the
92
+ * plain name for an unscoped row (workers may serve every environment), and
93
+ * `name@<env>` for a row scoped to one environment, which binds the token so
94
+ * its workers only take that environment's tasks.
95
+ */
96
+ function workerQueueOf(queue) {
97
+ return queue.environment ? `${queue.name}@${queue.environment.toLowerCase()}` : queue.name;
98
+ }
90
99
  /** The one-line worker start command shown with a new token (no token in it). */
91
100
  function workerRunCommand(taskQueues, bridgeUrl) {
92
- return `FLUIDGRIDS_WORKER_TOKEN=<token> fluidgrids worker run --task-queue ${taskQueues[0] ?? "my-queue"}${bridgeUrl ? ` --bridge-url ${bridgeUrl}` : ""}`;
101
+ return `FLUIDGRIDS_WORKER_TOKEN=<token> fluidgrids worker run --queue ${taskQueues.length > 0 ? taskQueues.join(",") : "my-queue"}${bridgeUrl ? ` --bridge-url ${bridgeUrl}` : ""}`;
93
102
  }
94
103
 
95
104
  // src/modules/task-queues/components/TaskQueueDialogs.tsx
@@ -356,6 +365,11 @@ function WorkerTokenDialog({ queues, canSetAllowlist, onClose, onCreated }) {
356
365
  className: "text-sm text-text-secondary",
357
366
  children: tr("fluidgrids.taskQueues.noQueues", "Create a self-hosted queue first.")
358
367
  }),
368
+ queues.some((queue) => queue.includes("@")) && /* @__PURE__ */ jsx("p", {
369
+ className: "text-xs text-text-secondary",
370
+ "data-testid": "worker-token-environment-hint",
371
+ children: tr("fluidgrids.taskQueues.tokenEnvironmentHint", "A queue shown as name@environment binds the token: its workers only take tasks of runs in that environment. A plain name serves every environment.")
372
+ }),
359
373
  queues.map((queue) => /* @__PURE__ */ jsxs("label", {
360
374
  className: "flex items-center gap-2 text-sm text-text-primary",
361
375
  children: [/* @__PURE__ */ jsx("input", {
@@ -555,7 +569,7 @@ function TaskQueuesContent() {
555
569
  const [issuing, setIssuing] = useState(false);
556
570
  const [secret, setSecret] = useState(null);
557
571
  const [allowlist, setAllowlist] = useState(null);
558
- const selfHosted = (queues.data ?? []).filter((queue) => queue.kind === "SELF_HOSTED").map((queue) => queue.name);
572
+ const selfHosted = [...new Set((queues.data ?? []).filter((queue) => queue.kind === "SELF_HOSTED").map(workerQueueOf))];
559
573
  const removeQueue = async () => {
560
574
  if (!deleting?.id) return;
561
575
  try {
package/dist/index.js CHANGED
@@ -31,7 +31,7 @@ import { t as TemplatesPage } from "./TemplatesPage-DIVghCB6.js";
31
31
  import { a as WorkflowSharingDocument, o as ShareWorkflowDocument } from "./WorkflowShareDialog-D8psodlb.js";
32
32
  import { S as CreateTaskQueueDocument, _ as DeleteWorkerTokenDocument, b as DeleteTaskQueueDocument, f as WorkerTokensDocument, g as SetWorkerTokenConnectionAllowlistDocument, h as TaskQueuesDocument, m as TaskQueueStatsDocument, p as WorkflowWorkersDocument, v as RotateWorkerTokenDocument, x as UpdateTaskQueueDocument, y as CreateWorkerTokenDocument } from "./api-DKfMt0IX.js";
33
33
  import { t as NodesPage } from "./NodesPage-C3sh0aL9.js";
34
- import { a as ManagedAiWorkspacePolicyDocument, c as UpdateManagedAiWorkspacePolicyDocument, i as WorkflowNotificationSettingsDocument, l as UpdateDurableHistoryCapsDocument, o as DurableHistoryCapsDocument, r as WorkspaceSecurityReportDocument, s as UpdateWorkflowNotificationSettingsDocument, t as SettingsPage } from "./SettingsPage-CnGs6Ggy.js";
34
+ import { a as ManagedAiWorkspacePolicyDocument, c as UpdateManagedAiWorkspacePolicyDocument, i as WorkflowNotificationSettingsDocument, l as UpdateDurableHistoryCapsDocument, o as DurableHistoryCapsDocument, r as WorkspaceSecurityReportDocument, s as UpdateWorkflowNotificationSettingsDocument, t as SettingsPage } from "./SettingsPage-CmIa107C.js";
35
35
  import { _ as useWorkflowRuns, a as useDeactivateWorkflow, b as PreviewN8nImportDocument, c as useImportWorkflow, d as useRestoreWorkflowVersion, f as useTriggerWorkflow, g as useWorkflowRun, h as useWorkflowDefinitions, i as useDashboardSummary, l as useLazyWorkflowDefinition, m as useWorkflowDefinition, n as useCreateWorkflow, o as useDeleteWorkflow, p as useUpdateWorkflow, r as useCreateWorkflowVersion, s as useDuplicateWorkflow, t as useActivateWorkflow, u as usePreviewN8nImport, v as useWorkflowVersions, y as WorkflowDefinitionForBuilderDocument } from "./useWorkflows-B5kFIfrZ.js";
36
36
  import { t as WorkflowDefinitionDocument } from "./WorkflowDefinitionDocument-DZLbTPUZ.js";
37
37
  import { t as WorkflowProposalDocument } from "./WorkflowProposalDocument-BdUbsrd0.js";
@@ -47,7 +47,7 @@ import { t as RunnersPage } from "./RunnersPage-BXODCbq0.js";
47
47
  import { a as useRunners, i as useRunnerActions, n as RUNNER_INSTALL_SCRIPT_URL, r as runnerInstallCommand, t as RunnerStatusPill } from "./RunnerStatusPill-Bh7mEsPh.js";
48
48
  import { n as buttonVariants, t as Button } from "./button-DG7y_FVJ.js";
49
49
  import { t as Input } from "./input-ChT6Q-Pr.js";
50
- import { a as taskQueueNameProblem, i as taskQueueInputOf, n as TaskQueuesPage, t as TaskQueueStatsCard } from "./TaskQueuesPage-DLzuumGp.js";
50
+ import { a as taskQueueNameProblem, i as taskQueueInputOf, n as TaskQueuesPage, t as TaskQueueStatsCard } from "./TaskQueuesPage-BNoe05qF.js";
51
51
  import { i as decodePayloads, n as checkCodecServerUrl, o as isEncodedPayload } from "./codec-client-CAYl6j46.js";
52
52
  import { a as HumanRequestCard, i as usePendingToolApprovals, r as useDecideToolApproval, t as ApprovalInboxPage } from "./ApprovalInboxPage-DVoqdqwA.js";
53
53
  import { n as useRespondToHumanRequest, r as useRunHumanRequests, t as usePendingHumanRequests } from "./useHumanRequests-DwG2tQ3f.js";
package/dist/settings.js CHANGED
@@ -1,5 +1,5 @@
1
1
  "use client";
2
- import { t as SettingsPage } from "./SettingsPage-CnGs6Ggy.js";
2
+ import { t as SettingsPage } from "./SettingsPage-CmIa107C.js";
3
3
  import { t as ManagedAiPolicyAuthorityProvider } from "./ManagedAiPolicyAuthority-BxwJ3ptd.js";
4
4
 
5
5
  export { ManagedAiPolicyAuthorityProvider, SettingsPage };
@@ -64,13 +64,13 @@ const pages = createWorkflowPages({
64
64
  HistoryPage: () => import("./HistoryPage-CCZS-hPw.js").then((n) => n.n),
65
65
  TemplatesPage: () => import("./TemplatesPage-DIVghCB6.js").then((n) => n.n),
66
66
  NodesPage: () => import("./NodesPage-C3sh0aL9.js").then((n) => n.n),
67
- SettingsPage: () => import("./SettingsPage-CnGs6Ggy.js").then((n) => n.n),
67
+ SettingsPage: () => import("./SettingsPage-CmIa107C.js").then((n) => n.n),
68
68
  InsightsPage: () => import("./InsightsPage-C-Nm9YNI.js").then((n) => n.r),
69
69
  ErrorAnalyticsPage: () => import("./InsightsPage-C-Nm9YNI.js").then((n) => n.r),
70
70
  DataSinkDashboardPage: () => import("./DataSinkDashboardPage-BoyLrZnt.js").then((n) => n.n),
71
71
  VariablesPage: () => import("./VariablesPage-_RKdfiw5.js").then((n) => n.n),
72
72
  RunnersPage: () => import("./RunnersPage-BXODCbq0.js").then((n) => n.n),
73
- TaskQueuesPage: () => import("./TaskQueuesPage-DLzuumGp.js").then((n) => n.r),
73
+ TaskQueuesPage: () => import("./TaskQueuesPage-BNoe05qF.js").then((n) => n.r),
74
74
  ApprovalInboxPage: () => import("./ApprovalInboxPage-DVoqdqwA.js").then((n) => n.n),
75
75
  DataTablesPage: () => import("./DataTablesPage-DR6BesNp.js").then((n) => n.n)
76
76
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@burdenoff/fluidgrids-fe-sdk",
3
- "version": "2026.1113.12",
3
+ "version": "2026.1114.1",
4
4
  "description": "FluidGrids Workflow Builder SDK - Embeddable visual workflow automation",
5
5
  "type": "module",
6
6
  "imports": {