@burdenoff/microfe-botmanor 2026.1027.2 → 2026.1027.3

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 (80) hide show
  1. package/dist/botlit/BotlitRoutes.js +142 -132
  2. package/dist/botlit/BotlitRoutes.js.map +1 -1
  3. package/dist/botlit/components/AgentApprovalPanel.js +144 -126
  4. package/dist/botlit/components/AgentApprovalPanel.js.map +1 -1
  5. package/dist/botlit/components/ModelRegistrationPanel.js +4 -4
  6. package/dist/botlit/components/VersionHistoryPanel.js +92 -83
  7. package/dist/botlit/components/VersionHistoryPanel.js.map +1 -1
  8. package/dist/botlit/pages/A2AAgentDetailPage.js +212 -203
  9. package/dist/botlit/pages/A2AAgentDetailPage.js.map +1 -1
  10. package/dist/botlit/pages/A2ARegistryPage.js +129 -117
  11. package/dist/botlit/pages/A2ARegistryPage.js.map +1 -1
  12. package/dist/botlit/pages/AgentApprovalsPage.js +122 -110
  13. package/dist/botlit/pages/AgentApprovalsPage.js.map +1 -1
  14. package/dist/botlit/pages/AgentBuilderPage.js +18 -18
  15. package/dist/botlit/pages/AgentDetailPage.js +298 -273
  16. package/dist/botlit/pages/AgentDetailPage.js.map +1 -1
  17. package/dist/botlit/pages/AgentsListPage.js +145 -121
  18. package/dist/botlit/pages/AgentsListPage.js.map +1 -1
  19. package/dist/botlit/pages/BotChannelsTab.js +238 -226
  20. package/dist/botlit/pages/BotChannelsTab.js.map +1 -1
  21. package/dist/botlit/pages/BotDetailPage.js +307 -288
  22. package/dist/botlit/pages/BotDetailPage.js.map +1 -1
  23. package/dist/botlit/pages/BotWorkflowTab.js +125 -116
  24. package/dist/botlit/pages/BotWorkflowTab.js.map +1 -1
  25. package/dist/botlit/pages/BotsListPage.js +159 -144
  26. package/dist/botlit/pages/BotsListPage.js.map +1 -1
  27. package/dist/botlit/pages/BucketsPage.js +279 -258
  28. package/dist/botlit/pages/BucketsPage.js.map +1 -1
  29. package/dist/botlit/pages/ChannelDetailPage.js +346 -328
  30. package/dist/botlit/pages/ChannelDetailPage.js.map +1 -1
  31. package/dist/botlit/pages/ChannelRoutesPage.js +10 -10
  32. package/dist/botlit/pages/ChannelsPage.js +163 -148
  33. package/dist/botlit/pages/ChannelsPage.js.map +1 -1
  34. package/dist/botlit/pages/DashboardPage.js +129 -114
  35. package/dist/botlit/pages/DashboardPage.js.map +1 -1
  36. package/dist/botlit/pages/ExecutionDetailPage.js +145 -139
  37. package/dist/botlit/pages/ExecutionDetailPage.js.map +1 -1
  38. package/dist/botlit/pages/ExecutionsPage.js +14 -14
  39. package/dist/botlit/pages/InstalledPackagesPage.js +245 -227
  40. package/dist/botlit/pages/InstalledPackagesPage.js.map +1 -1
  41. package/dist/botlit/pages/KnowledgeBaseDetailPage.js +168 -156
  42. package/dist/botlit/pages/KnowledgeBaseDetailPage.js.map +1 -1
  43. package/dist/botlit/pages/KnowledgeBasesPage.js +91 -79
  44. package/dist/botlit/pages/KnowledgeBasesPage.js.map +1 -1
  45. package/dist/botlit/pages/MCPServerDetailPage.js +200 -188
  46. package/dist/botlit/pages/MCPServerDetailPage.js.map +1 -1
  47. package/dist/botlit/pages/MCPServersPage.js +170 -155
  48. package/dist/botlit/pages/MCPServersPage.js.map +1 -1
  49. package/dist/botlit/pages/PoliciesPage.js +113 -104
  50. package/dist/botlit/pages/PoliciesPage.js.map +1 -1
  51. package/dist/botlit/pages/PolicyDetailPage.js +145 -133
  52. package/dist/botlit/pages/PolicyDetailPage.js.map +1 -1
  53. package/dist/botlit/pages/PromptStudioPage.js +106 -97
  54. package/dist/botlit/pages/PromptStudioPage.js.map +1 -1
  55. package/dist/botlit/pages/PromptTemplateDetailPage.js +359 -347
  56. package/dist/botlit/pages/PromptTemplateDetailPage.js.map +1 -1
  57. package/dist/botlit/pages/PromptTemplatesPage.js +127 -112
  58. package/dist/botlit/pages/PromptTemplatesPage.js.map +1 -1
  59. package/dist/botlit/pages/RetrievalProfileDetailPage.js +219 -210
  60. package/dist/botlit/pages/RetrievalProfileDetailPage.js.map +1 -1
  61. package/dist/botlit/pages/RetrievalProfilesPage.js +112 -103
  62. package/dist/botlit/pages/RetrievalProfilesPage.js.map +1 -1
  63. package/dist/botlit/pages/SettingsPage.js +264 -252
  64. package/dist/botlit/pages/SettingsPage.js.map +1 -1
  65. package/dist/botlit/pages/SkillDetailPage.js +235 -226
  66. package/dist/botlit/pages/SkillDetailPage.js.map +1 -1
  67. package/dist/botlit/pages/SkillsPage.js +115 -106
  68. package/dist/botlit/pages/SkillsPage.js.map +1 -1
  69. package/dist/botlit/pages/StorePackageDetailPage.js +194 -188
  70. package/dist/botlit/pages/StorePackageDetailPage.js.map +1 -1
  71. package/dist/botlit/pages/StorePage.js +161 -155
  72. package/dist/botlit/pages/StorePage.js.map +1 -1
  73. package/dist/botlit/permissions/PermissionRequired.js +45 -0
  74. package/dist/botlit/permissions/PermissionRequired.js.map +1 -0
  75. package/dist/botlit/permissions/botmanorPermissions.js +72 -0
  76. package/dist/botlit/permissions/botmanorPermissions.js.map +1 -0
  77. package/dist/botlit/permissions/index.js +3 -0
  78. package/dist/botlit/permissions/useBotmanorPermissions.js +19 -0
  79. package/dist/botlit/permissions/useBotmanorPermissions.js.map +1 -0
  80. package/package.json +1 -1
@@ -1,233 +1,251 @@
1
1
  import { useTr as e } from "../../shared/hooks/useTr.js";
2
2
  import { useBotlit as t } from "../providers/BotlitProvider.js";
3
3
  import { formatRelativeTime as n } from "../utils/formatters.js";
4
- import { Card as r, CardContent as i, CardDescription as a, CardHeader as o, CardTitle as s } from "./Card.js";
5
- import { Button as c } from "./Button.js";
6
- import { Badge as l } from "./Badge.js";
7
- import { useAgentApprovalActions as u, useAgentApprovalRequests as d, useAgentApprovalSettings as f } from "../hooks/useAgentApprovals.js";
8
- import { useState as p } from "react";
9
- import { Dialog as m, DialogContent as h, DialogDescription as g, DialogFooter as _, DialogHeader as v, DialogTitle as y, Textarea as b } from "@burdenoff/fe-libs/ui";
10
- import { Fragment as x, jsx as S, jsxs as C } from "react/jsx-runtime";
11
- import { AlertTriangle as w, CheckCircle2 as T, Send as E, ShieldCheck as D, XCircle as O } from "lucide-react";
12
- import { toast as k } from "sonner";
4
+ import { BOTMANOR_PERMISSIONS as r } from "../permissions/botmanorPermissions.js";
5
+ import { BotmanorPermissionGate as i } from "../permissions/useBotmanorPermissions.js";
6
+ import { Button as a } from "./Button.js";
7
+ import "../permissions/index.js";
8
+ import { Card as o, CardContent as s, CardDescription as c, CardHeader as l, CardTitle as u } from "./Card.js";
9
+ import { Badge as d } from "./Badge.js";
10
+ import { useAgentApprovalActions as f, useAgentApprovalRequests as p, useAgentApprovalSettings as m } from "../hooks/useAgentApprovals.js";
11
+ import { useState as h } from "react";
12
+ import { Dialog as g, DialogContent as _, DialogDescription as v, DialogFooter as y, DialogHeader as b, DialogTitle as x, Textarea as S } from "@burdenoff/fe-libs/ui";
13
+ import { Fragment as C, jsx as w, jsxs as T } from "react/jsx-runtime";
14
+ import { AlertTriangle as E, CheckCircle2 as D, Send as O, ShieldCheck as k, XCircle as A } from "lucide-react";
15
+ import { toast as j } from "sonner";
13
16
  //#region src/botlit/components/AgentApprovalPanel.tsx
14
- function A(e) {
17
+ function M(e) {
15
18
  return e === "PENDING" ? "warning" : e === "APPROVED" ? "success" : e === "REJECTED" ? "destructive" : "outline";
16
19
  }
17
- var j = ({ kind: t, loading: n, onClose: r, onConfirm: i }) => {
18
- let a = e(), [o, s] = p(""), l = t === "reject", u = {
20
+ var N = ({ kind: t, loading: n, onClose: r, onConfirm: i }) => {
21
+ let o = e(), [s, c] = h(""), l = t === "reject", u = {
19
22
  request: {
20
- title: a("botlit.agentApproval.dialog.request.title", "Request activation"),
21
- description: a("botlit.agentApproval.dialog.request.description", "A reviewer will check the agent's current prompt, model, tools and limits before it goes live. Changing the agent afterwards makes this request stale."),
22
- confirm: a("botlit.agentApproval.dialog.request.confirm", "Submit for review")
23
+ title: o("botlit.agentApproval.dialog.request.title", "Request activation"),
24
+ description: o("botlit.agentApproval.dialog.request.description", "A reviewer will check the agent's current prompt, model, tools and limits before it goes live. Changing the agent afterwards makes this request stale."),
25
+ confirm: o("botlit.agentApproval.dialog.request.confirm", "Submit for review")
23
26
  },
24
27
  approve: {
25
- title: a("botlit.agentApproval.dialog.approve.title", "Approve and go live"),
26
- description: a("botlit.agentApproval.dialog.approve.description", "Approving publishes the agent's draft and makes it ACTIVE immediately."),
27
- confirm: a("botlit.agentApproval.dialog.approve.confirm", "Approve")
28
+ title: o("botlit.agentApproval.dialog.approve.title", "Approve and go live"),
29
+ description: o("botlit.agentApproval.dialog.approve.description", "Approving publishes the agent's draft and makes it ACTIVE immediately."),
30
+ confirm: o("botlit.agentApproval.dialog.approve.confirm", "Approve")
28
31
  },
29
32
  reject: {
30
- title: a("botlit.agentApproval.dialog.reject.title", "Reject activation"),
31
- description: a("botlit.agentApproval.dialog.reject.description", "Tell the requester what needs to change. The agent stays as it is."),
32
- confirm: a("botlit.agentApproval.dialog.reject.confirm", "Reject")
33
+ title: o("botlit.agentApproval.dialog.reject.title", "Reject activation"),
34
+ description: o("botlit.agentApproval.dialog.reject.description", "Tell the requester what needs to change. The agent stays as it is."),
35
+ confirm: o("botlit.agentApproval.dialog.reject.confirm", "Reject")
33
36
  }
34
37
  }, d = t ? u[t] : null;
35
- return /* @__PURE__ */ S(m, {
38
+ return /* @__PURE__ */ w(g, {
36
39
  open: t !== null,
37
40
  onOpenChange: (e) => {
38
- e || (s(""), r());
41
+ e || (c(""), r());
39
42
  },
40
- children: /* @__PURE__ */ C(h, { children: [
41
- /* @__PURE__ */ C(v, { children: [/* @__PURE__ */ S(y, { children: d?.title }), /* @__PURE__ */ S(g, { children: d?.description })] }),
42
- /* @__PURE__ */ S(b, {
43
- "aria-label": t === "request" ? a("botlit.agentApproval.dialog.noteLabel", "Note for the reviewer") : a("botlit.agentApproval.dialog.reasonLabel", "Reason"),
44
- value: o,
43
+ children: /* @__PURE__ */ T(_, { children: [
44
+ /* @__PURE__ */ T(b, { children: [/* @__PURE__ */ w(x, { children: d?.title }), /* @__PURE__ */ w(v, { children: d?.description })] }),
45
+ /* @__PURE__ */ w(S, {
46
+ "aria-label": t === "request" ? o("botlit.agentApproval.dialog.noteLabel", "Note for the reviewer") : o("botlit.agentApproval.dialog.reasonLabel", "Reason"),
47
+ value: s,
45
48
  maxLength: 2e3,
46
- onChange: (e) => s(e.target.value),
47
- placeholder: t === "request" ? a("botlit.agentApproval.dialog.notePlaceholder", "What changed and why (optional)") : l ? a("botlit.agentApproval.dialog.reasonRequiredPlaceholder", "Reason (required)") : a("botlit.agentApproval.dialog.reasonPlaceholder", "Reason (optional)"),
49
+ onChange: (e) => c(e.target.value),
50
+ placeholder: t === "request" ? o("botlit.agentApproval.dialog.notePlaceholder", "What changed and why (optional)") : l ? o("botlit.agentApproval.dialog.reasonRequiredPlaceholder", "Reason (required)") : o("botlit.agentApproval.dialog.reasonPlaceholder", "Reason (optional)"),
48
51
  rows: 4
49
52
  }),
50
- /* @__PURE__ */ C(_, { children: [/* @__PURE__ */ S(c, {
53
+ /* @__PURE__ */ T(y, { children: [/* @__PURE__ */ w(a, {
51
54
  variant: "outline",
52
55
  onClick: () => {
53
- s(""), r();
56
+ c(""), r();
54
57
  },
55
- children: a("botlit.common.cancel", "Cancel")
56
- }), /* @__PURE__ */ S(c, {
58
+ children: o("botlit.common.cancel", "Cancel")
59
+ }), /* @__PURE__ */ w(a, {
57
60
  variant: t === "reject" ? "destructive" : "default",
58
61
  isLoading: n,
59
- disabled: l && o.trim().length === 0,
62
+ disabled: l && s.trim().length === 0,
60
63
  onClick: async () => {
61
- await i(o), s("");
64
+ await i(s), c("");
62
65
  },
63
66
  children: d?.confirm
64
67
  })] })
65
68
  ] })
66
69
  });
67
- }, M = ({ agentId: m, agentStatus: h, onChanged: g }) => {
68
- let _ = e(), { currentUser: v } = t(), y = f(), b = d({ agentId: m }), { run: M, pending: N } = u(), [P, F] = p(null), I = y.data?.requireActivationApproval === !0, L = b.data.find((e) => e.status === "PENDING") ?? null, R = b.data.filter((e) => e.status !== "PENDING").slice(0, 10), z = L !== null && L.requestedById === v?.id, B = (e) => e && e === v?.id ? _("botlit.agentApproval.you", "you") : e ?? "—", V = async (e) => {
69
- if (P) try {
70
- P.kind === "request" ? (await M({
70
+ }, P = ({ agentId: g, agentStatus: _, onChanged: v }) => {
71
+ let y = e(), { currentUser: b } = t(), x = m(), S = p({ agentId: g }), { run: P, pending: F } = f(), [I, L] = h(null), R = x.data?.requireActivationApproval === !0, z = S.data.find((e) => e.status === "PENDING") ?? null, B = S.data.filter((e) => e.status !== "PENDING").slice(0, 10), V = z !== null && z.requestedById === b?.id, H = (e) => e && e === b?.id ? y("botlit.agentApproval.you", "you") : e ?? "—", U = async (e) => {
72
+ if (I) try {
73
+ I.kind === "request" ? (await P({
71
74
  kind: "request",
72
- agentId: m,
75
+ agentId: g,
73
76
  note: e
74
- }), k.success(_("botlit.agentApproval.toast.requested", "Activation requested"))) : P.kind === "approve" && P.request ? (await M({
77
+ }), j.success(y("botlit.agentApproval.toast.requested", "Activation requested"))) : I.kind === "approve" && I.request ? (await P({
75
78
  kind: "approve",
76
- id: P.request.id,
79
+ id: I.request.id,
77
80
  reason: e
78
- }), k.success(_("botlit.agentApproval.toast.approved", "Approved — the agent is live")), g?.()) : P.kind === "reject" && P.request && (await M({
81
+ }), j.success(y("botlit.agentApproval.toast.approved", "Approved — the agent is live")), v?.()) : I.kind === "reject" && I.request && (await P({
79
82
  kind: "reject",
80
- id: P.request.id,
83
+ id: I.request.id,
81
84
  reason: e
82
- }), k.success(_("botlit.agentApproval.toast.rejected", "Activation rejected"))), F(null), await b.refetch();
85
+ }), j.success(y("botlit.agentApproval.toast.rejected", "Activation rejected"))), L(null), await S.refetch();
83
86
  } catch (e) {
84
- k.error(e instanceof Error ? e.message : _("botlit.agentApproval.toast.error", "Approval action failed"));
87
+ j.error(e instanceof Error ? e.message : y("botlit.agentApproval.toast.error", "Approval action failed"));
85
88
  }
86
- }, H = async (e) => {
89
+ }, W = async (e) => {
87
90
  try {
88
- await M({
91
+ await P({
89
92
  kind: "cancel",
90
93
  id: e.id
91
- }), k.success(_("botlit.agentApproval.toast.cancelled", "Request cancelled")), await b.refetch();
94
+ }), j.success(y("botlit.agentApproval.toast.cancelled", "Request cancelled")), await S.refetch();
92
95
  } catch (e) {
93
- k.error(e instanceof Error ? e.message : _("botlit.agentApproval.toast.error", "Approval action failed"));
96
+ j.error(e instanceof Error ? e.message : y("botlit.agentApproval.toast.error", "Approval action failed"));
94
97
  }
95
98
  };
96
- return /* @__PURE__ */ C(r, {
99
+ return /* @__PURE__ */ T(o, {
97
100
  "data-testid": "agent-approval-panel",
98
101
  children: [
99
- /* @__PURE__ */ C(o, {
102
+ /* @__PURE__ */ T(l, {
100
103
  className: "flex flex-row items-start justify-between gap-4",
101
- children: [/* @__PURE__ */ C("div", { children: [/* @__PURE__ */ C(s, {
104
+ children: [/* @__PURE__ */ T("div", { children: [/* @__PURE__ */ T(u, {
102
105
  className: "flex items-center gap-2",
103
106
  children: [
104
- /* @__PURE__ */ S(D, { size: 18 }),
105
- _("botlit.agentApproval.title", "Activation approval"),
106
- /* @__PURE__ */ S(l, {
107
- variant: I ? "warning" : "outline",
108
- children: I ? _("botlit.agentApproval.required", "Required in this workspace") : _("botlit.agentApproval.optional", "Optional")
107
+ /* @__PURE__ */ w(k, { size: 18 }),
108
+ y("botlit.agentApproval.title", "Activation approval"),
109
+ /* @__PURE__ */ w(d, {
110
+ variant: R ? "warning" : "outline",
111
+ children: R ? y("botlit.agentApproval.required", "Required in this workspace") : y("botlit.agentApproval.optional", "Optional")
109
112
  })
110
113
  ]
111
- }), /* @__PURE__ */ S(a, { children: I ? _("botlit.agentApproval.descriptionRequired", "This workspace requires a reviewer to approve an agent before it goes live or before a new version is published.") : _("botlit.agentApproval.descriptionOptional", "You can ask a reviewer to check this agent before it goes live. A workspace admin can make review mandatory on the Approvals page.") })] }), !L && h !== "ARCHIVED" && /* @__PURE__ */ S(c, {
112
- leftIcon: /* @__PURE__ */ S(E, { size: 16 }),
113
- onClick: () => F({ kind: "request" }),
114
- children: _("botlit.agentApproval.requestAction", "Request activation")
114
+ }), /* @__PURE__ */ w(c, { children: R ? y("botlit.agentApproval.descriptionRequired", "This workspace requires a reviewer to approve an agent before it goes live or before a new version is published.") : y("botlit.agentApproval.descriptionOptional", "You can ask a reviewer to check this agent before it goes live. A workspace admin can make review mandatory on the Approvals page.") })] }), !z && _ !== "ARCHIVED" && /* @__PURE__ */ w(i, {
115
+ permission: r.AGENT_UPDATE,
116
+ children: /* @__PURE__ */ w(a, {
117
+ leftIcon: /* @__PURE__ */ w(O, { size: 16 }),
118
+ onClick: () => L({ kind: "request" }),
119
+ children: y("botlit.agentApproval.requestAction", "Request activation")
120
+ })
115
121
  })]
116
122
  }),
117
- /* @__PURE__ */ C(i, {
123
+ /* @__PURE__ */ T(s, {
118
124
  className: "space-y-4",
119
125
  children: [
120
- b.loading && b.data.length === 0 ? /* @__PURE__ */ S("div", { className: "h-20 bg-bg-sunken motion-safe:animate-vc-shimmer rounded-lg" }) : null,
121
- L && /* @__PURE__ */ C("div", {
126
+ S.loading && S.data.length === 0 ? /* @__PURE__ */ w("div", { className: "h-20 bg-bg-sunken motion-safe:animate-vc-shimmer rounded-lg" }) : null,
127
+ z && /* @__PURE__ */ T("div", {
122
128
  className: "p-4 border border-status-warning-border bg-bg-sunken rounded-lg space-y-2",
123
129
  "data-testid": "agent-approval-pending",
124
130
  children: [
125
- /* @__PURE__ */ C("div", {
131
+ /* @__PURE__ */ T("div", {
126
132
  className: "flex items-center gap-2 flex-wrap",
127
- children: [/* @__PURE__ */ S(l, {
133
+ children: [/* @__PURE__ */ w(d, {
128
134
  variant: "warning",
129
- children: L.status
130
- }), /* @__PURE__ */ C("span", {
135
+ children: z.status
136
+ }), /* @__PURE__ */ T("span", {
131
137
  className: "text-sm text-text-secondary",
132
138
  children: [
133
- _("botlit.agentApproval.requestedBy", "Requested by"),
139
+ y("botlit.agentApproval.requestedBy", "Requested by"),
134
140
  " ",
135
- B(L.requestedById),
141
+ H(z.requestedById),
136
142
  " ",
137
- n(L.createdAt)
143
+ n(z.createdAt)
138
144
  ]
139
145
  })]
140
146
  }),
141
- L.requestNote && /* @__PURE__ */ S("p", {
147
+ z.requestNote && /* @__PURE__ */ w("p", {
142
148
  className: "text-sm break-words",
143
- children: L.requestNote
149
+ children: z.requestNote
144
150
  }),
145
- L.isStale && /* @__PURE__ */ C("p", {
151
+ z.isStale && /* @__PURE__ */ T("p", {
146
152
  className: "flex items-center gap-2 text-sm text-status-warning-text",
147
- children: [/* @__PURE__ */ S(w, { size: 14 }), _("botlit.agentApproval.stale", "The agent changed after this request. Submit a new request so the reviewer sees the current configuration.")]
153
+ children: [/* @__PURE__ */ w(E, { size: 14 }), y("botlit.agentApproval.stale", "The agent changed after this request. Submit a new request so the reviewer sees the current configuration.")]
148
154
  }),
149
- /* @__PURE__ */ S("div", {
155
+ /* @__PURE__ */ w("div", {
150
156
  className: "flex gap-2 flex-wrap",
151
- children: z ? /* @__PURE__ */ C(x, { children: [/* @__PURE__ */ S(c, {
152
- variant: "outline",
153
- size: "sm",
154
- isLoading: N === "cancel",
155
- onClick: () => void H(L),
156
- children: _("botlit.agentApproval.cancelAction", "Cancel request")
157
- }), L.isStale && /* @__PURE__ */ S(c, {
158
- size: "sm",
159
- onClick: () => F({ kind: "request" }),
160
- children: _("botlit.agentApproval.resubmitAction", "Submit new request")
161
- })] }) : /* @__PURE__ */ C(x, { children: [/* @__PURE__ */ S(c, {
162
- size: "sm",
163
- leftIcon: /* @__PURE__ */ S(T, { size: 14 }),
164
- disabled: L.isStale,
165
- onClick: () => F({
166
- kind: "approve",
167
- request: L
168
- }),
169
- children: _("botlit.agentApproval.approveAction", "Approve")
170
- }), /* @__PURE__ */ S(c, {
171
- size: "sm",
172
- variant: "destructive",
173
- leftIcon: /* @__PURE__ */ S(O, { size: 14 }),
174
- onClick: () => F({
175
- kind: "reject",
176
- request: L
177
- }),
178
- children: _("botlit.agentApproval.rejectAction", "Reject")
157
+ children: V ? /* @__PURE__ */ T(C, { children: [/* @__PURE__ */ w(i, {
158
+ permission: r.AGENT_UPDATE,
159
+ children: /* @__PURE__ */ w(a, {
160
+ variant: "outline",
161
+ size: "sm",
162
+ isLoading: F === "cancel",
163
+ onClick: () => void W(z),
164
+ children: y("botlit.agentApproval.cancelAction", "Cancel request")
165
+ })
166
+ }), z.isStale && /* @__PURE__ */ w(i, {
167
+ permission: r.AGENT_UPDATE,
168
+ children: /* @__PURE__ */ w(a, {
169
+ size: "sm",
170
+ onClick: () => L({ kind: "request" }),
171
+ children: y("botlit.agentApproval.resubmitAction", "Submit new request")
172
+ })
173
+ })] }) : /* @__PURE__ */ T(C, { children: [/* @__PURE__ */ w(i, {
174
+ permission: r.AGENT_APPROVE,
175
+ children: /* @__PURE__ */ w(a, {
176
+ size: "sm",
177
+ leftIcon: /* @__PURE__ */ w(D, { size: 14 }),
178
+ disabled: z.isStale,
179
+ onClick: () => L({
180
+ kind: "approve",
181
+ request: z
182
+ }),
183
+ children: y("botlit.agentApproval.approveAction", "Approve")
184
+ })
185
+ }), /* @__PURE__ */ w(i, {
186
+ permission: r.AGENT_APPROVE,
187
+ children: /* @__PURE__ */ w(a, {
188
+ size: "sm",
189
+ variant: "destructive",
190
+ leftIcon: /* @__PURE__ */ w(A, { size: 14 }),
191
+ onClick: () => L({
192
+ kind: "reject",
193
+ request: z
194
+ }),
195
+ children: y("botlit.agentApproval.rejectAction", "Reject")
196
+ })
179
197
  })] })
180
198
  })
181
199
  ]
182
200
  }),
183
- R.length > 0 && /* @__PURE__ */ C("div", {
201
+ B.length > 0 && /* @__PURE__ */ T("div", {
184
202
  className: "space-y-2",
185
- children: [/* @__PURE__ */ S("p", {
203
+ children: [/* @__PURE__ */ w("p", {
186
204
  className: "text-sm font-medium",
187
- children: _("botlit.agentApproval.history", "Decision history")
188
- }), /* @__PURE__ */ S("ul", {
205
+ children: y("botlit.agentApproval.history", "Decision history")
206
+ }), /* @__PURE__ */ w("ul", {
189
207
  className: "space-y-2",
190
208
  "data-testid": "agent-approval-history",
191
- children: R.map((e) => /* @__PURE__ */ C("li", {
209
+ children: B.map((e) => /* @__PURE__ */ T("li", {
192
210
  className: "p-3 border border-border-subtle rounded-lg text-sm space-y-1",
193
- children: [/* @__PURE__ */ C("div", {
211
+ children: [/* @__PURE__ */ T("div", {
194
212
  className: "flex items-center gap-2 flex-wrap",
195
- children: [/* @__PURE__ */ S(l, {
196
- variant: A(e.status),
213
+ children: [/* @__PURE__ */ w(d, {
214
+ variant: M(e.status),
197
215
  children: e.status
198
- }), /* @__PURE__ */ C("span", {
216
+ }), /* @__PURE__ */ T("span", {
199
217
  className: "text-text-secondary",
200
218
  children: [
201
- _("botlit.agentApproval.decidedBy", "by"),
219
+ y("botlit.agentApproval.decidedBy", "by"),
202
220
  " ",
203
- B(e.reviewerId),
221
+ H(e.reviewerId),
204
222
  " ",
205
223
  e.decidedAt ? n(e.decidedAt) : ""
206
224
  ]
207
225
  })]
208
- }), e.decisionReason && /* @__PURE__ */ S("p", {
226
+ }), e.decisionReason && /* @__PURE__ */ w("p", {
209
227
  className: "break-words",
210
228
  children: e.decisionReason
211
229
  })]
212
230
  }, e.id))
213
231
  })]
214
232
  }),
215
- !L && R.length === 0 && !b.loading && /* @__PURE__ */ S("p", {
233
+ !z && B.length === 0 && !S.loading && /* @__PURE__ */ w("p", {
216
234
  className: "text-sm text-text-secondary",
217
- children: _("botlit.agentApproval.empty", "No activation requests for this agent yet.")
235
+ children: y("botlit.agentApproval.empty", "No activation requests for this agent yet.")
218
236
  })
219
237
  ]
220
238
  }),
221
- /* @__PURE__ */ S(j, {
222
- kind: P?.kind ?? null,
223
- loading: N !== null,
224
- onClose: () => F(null),
225
- onConfirm: V
239
+ /* @__PURE__ */ w(N, {
240
+ kind: I?.kind ?? null,
241
+ loading: F !== null,
242
+ onClose: () => L(null),
243
+ onConfirm: U
226
244
  })
227
245
  ]
228
246
  });
229
247
  };
230
248
  //#endregion
231
- export { M as AgentApprovalPanel, j as ApprovalDecisionDialog, A as approvalStatusVariant };
249
+ export { P as AgentApprovalPanel, N as ApprovalDecisionDialog, M as approvalStatusVariant };
232
250
 
233
251
  //# sourceMappingURL=AgentApprovalPanel.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"AgentApprovalPanel.js","names":[],"sources":["../../../src/botlit/components/AgentApprovalPanel.tsx"],"sourcesContent":["/**\n * Agent Activation Approval Panel (BOFF-9682)\n * @module botlit/components\n *\n * Reviewer gate on the agent detail page. Builders request activation (the\n * request pins the agent's current config); reviewers with\n * `botmanor-agent:approve` approve it, which publishes the draft and takes the\n * agent live, or reject it with a reason. The requester cannot decide their\n * own request, and a request whose agent changed afterwards is flagged stale\n * and cannot be approved.\n */\n\nimport { useState, type FC } from 'react';\nimport { AlertTriangle, CheckCircle2, ShieldCheck, Send, XCircle } from 'lucide-react';\nimport { toast } from 'sonner';\nimport {\n Dialog,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n Textarea,\n} from '@burdenoff/fe-libs/ui';\nimport { useTr } from '../../shared/hooks/useTr';\nimport { Card, CardContent, CardDescription, CardHeader, CardTitle } from './Card';\nimport { Button } from './Button';\nimport { Badge } from './Badge';\nimport {\n useAgentApprovalActions,\n useAgentApprovalRequests,\n useAgentApprovalSettings,\n type AgentApprovalRequestRecord,\n type AgentApprovalStatus,\n} from '../hooks/useAgentApprovals';\nimport { useBotlit } from '../providers/BotlitProvider';\nimport { formatRelativeTime } from '../utils/formatters';\n\nexport function approvalStatusVariant(\n status: AgentApprovalStatus\n): 'warning' | 'success' | 'destructive' | 'outline' {\n if (status === 'PENDING') return 'warning';\n if (status === 'APPROVED') return 'success';\n if (status === 'REJECTED') return 'destructive';\n return 'outline';\n}\n\ntype DecisionKind = 'request' | 'approve' | 'reject';\n\ninterface DecisionDialogProps {\n kind: DecisionKind | null;\n loading: boolean;\n onClose: () => void;\n onConfirm: (text: string) => Promise<void>;\n}\n\n/** Note / reason dialog shared by the detail panel and the approvals page. */\nexport const ApprovalDecisionDialog: FC<DecisionDialogProps> = ({\n kind,\n loading,\n onClose,\n onConfirm,\n}) => {\n const t = useTr();\n const [text, setText] = useState('');\n const reasonRequired = kind === 'reject';\n\n const copy: Record<DecisionKind, { title: string; description: string; confirm: string }> = {\n request: {\n title: t('botlit.agentApproval.dialog.request.title', 'Request activation'),\n description: t(\n 'botlit.agentApproval.dialog.request.description',\n \"A reviewer will check the agent's current prompt, model, tools and limits before it goes live. Changing the agent afterwards makes this request stale.\"\n ),\n confirm: t('botlit.agentApproval.dialog.request.confirm', 'Submit for review'),\n },\n approve: {\n title: t('botlit.agentApproval.dialog.approve.title', 'Approve and go live'),\n description: t(\n 'botlit.agentApproval.dialog.approve.description',\n \"Approving publishes the agent's draft and makes it ACTIVE immediately.\"\n ),\n confirm: t('botlit.agentApproval.dialog.approve.confirm', 'Approve'),\n },\n reject: {\n title: t('botlit.agentApproval.dialog.reject.title', 'Reject activation'),\n description: t(\n 'botlit.agentApproval.dialog.reject.description',\n 'Tell the requester what needs to change. The agent stays as it is.'\n ),\n confirm: t('botlit.agentApproval.dialog.reject.confirm', 'Reject'),\n },\n };\n const current = kind ? copy[kind] : null;\n\n return (\n <Dialog\n open={kind !== null}\n onOpenChange={(open) => {\n if (!open) {\n setText('');\n onClose();\n }\n }}\n >\n <DialogContent>\n <DialogHeader>\n <DialogTitle>{current?.title}</DialogTitle>\n <DialogDescription>{current?.description}</DialogDescription>\n </DialogHeader>\n <Textarea\n aria-label={\n kind === 'request'\n ? t('botlit.agentApproval.dialog.noteLabel', 'Note for the reviewer')\n : t('botlit.agentApproval.dialog.reasonLabel', 'Reason')\n }\n value={text}\n maxLength={2000}\n onChange={(event) => setText(event.target.value)}\n placeholder={\n kind === 'request'\n ? t('botlit.agentApproval.dialog.notePlaceholder', 'What changed and why (optional)')\n : reasonRequired\n ? t('botlit.agentApproval.dialog.reasonRequiredPlaceholder', 'Reason (required)')\n : t('botlit.agentApproval.dialog.reasonPlaceholder', 'Reason (optional)')\n }\n rows={4}\n />\n <DialogFooter>\n <Button\n variant=\"outline\"\n onClick={() => {\n setText('');\n onClose();\n }}\n >\n {t('botlit.common.cancel', 'Cancel')}\n </Button>\n <Button\n variant={kind === 'reject' ? 'destructive' : 'default'}\n isLoading={loading}\n disabled={reasonRequired && text.trim().length === 0}\n onClick={async () => {\n await onConfirm(text);\n setText('');\n }}\n >\n {current?.confirm}\n </Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n );\n};\n\ninterface AgentApprovalPanelProps {\n agentId: string;\n agentStatus: string;\n /** Called after a decision that changes the agent so the page can refetch it. */\n onChanged?: () => void;\n}\n\nexport const AgentApprovalPanel: FC<AgentApprovalPanelProps> = ({\n agentId,\n agentStatus,\n onChanged,\n}) => {\n const t = useTr();\n const { currentUser } = useBotlit();\n const settings = useAgentApprovalSettings();\n const requests = useAgentApprovalRequests({ agentId });\n const { run, pending } = useAgentApprovalActions();\n const [dialog, setDialog] = useState<{\n kind: DecisionKind;\n request?: AgentApprovalRequestRecord;\n } | null>(null);\n\n const required = settings.data?.requireActivationApproval === true;\n const open = requests.data.find((request) => request.status === 'PENDING') ?? null;\n const history = requests.data.filter((request) => request.status !== 'PENDING').slice(0, 10);\n const isRequester = open !== null && open.requestedById === currentUser?.id;\n\n const who = (id?: string | null): string =>\n id && id === currentUser?.id ? t('botlit.agentApproval.you', 'you') : (id ?? '—');\n\n const confirm = async (text: string): Promise<void> => {\n if (!dialog) return;\n try {\n if (dialog.kind === 'request') {\n await run({ kind: 'request', agentId, note: text });\n toast.success(t('botlit.agentApproval.toast.requested', 'Activation requested'));\n } else if (dialog.kind === 'approve' && dialog.request) {\n await run({ kind: 'approve', id: dialog.request.id, reason: text });\n toast.success(t('botlit.agentApproval.toast.approved', 'Approved — the agent is live'));\n onChanged?.();\n } else if (dialog.kind === 'reject' && dialog.request) {\n await run({ kind: 'reject', id: dialog.request.id, reason: text });\n toast.success(t('botlit.agentApproval.toast.rejected', 'Activation rejected'));\n }\n setDialog(null);\n await requests.refetch();\n } catch (err: unknown) {\n toast.error(\n err instanceof Error\n ? err.message\n : t('botlit.agentApproval.toast.error', 'Approval action failed')\n );\n }\n };\n\n const cancel = async (request: AgentApprovalRequestRecord): Promise<void> => {\n try {\n await run({ kind: 'cancel', id: request.id });\n toast.success(t('botlit.agentApproval.toast.cancelled', 'Request cancelled'));\n await requests.refetch();\n } catch (err: unknown) {\n toast.error(\n err instanceof Error\n ? err.message\n : t('botlit.agentApproval.toast.error', 'Approval action failed')\n );\n }\n };\n\n return (\n <Card data-testid=\"agent-approval-panel\">\n <CardHeader className=\"flex flex-row items-start justify-between gap-4\">\n <div>\n <CardTitle className=\"flex items-center gap-2\">\n <ShieldCheck size={18} />\n {t('botlit.agentApproval.title', 'Activation approval')}\n <Badge variant={required ? 'warning' : 'outline'}>\n {required\n ? t('botlit.agentApproval.required', 'Required in this workspace')\n : t('botlit.agentApproval.optional', 'Optional')}\n </Badge>\n </CardTitle>\n <CardDescription>\n {required\n ? t(\n 'botlit.agentApproval.descriptionRequired',\n 'This workspace requires a reviewer to approve an agent before it goes live or before a new version is published.'\n )\n : t(\n 'botlit.agentApproval.descriptionOptional',\n 'You can ask a reviewer to check this agent before it goes live. A workspace admin can make review mandatory on the Approvals page.'\n )}\n </CardDescription>\n </div>\n {!open && agentStatus !== 'ARCHIVED' && (\n <Button leftIcon={<Send size={16} />} onClick={() => setDialog({ kind: 'request' })}>\n {t('botlit.agentApproval.requestAction', 'Request activation')}\n </Button>\n )}\n </CardHeader>\n <CardContent className=\"space-y-4\">\n {requests.loading && requests.data.length === 0 ? (\n <div className=\"h-20 bg-bg-sunken motion-safe:animate-vc-shimmer rounded-lg\" />\n ) : null}\n\n {open && (\n <div\n className=\"p-4 border border-status-warning-border bg-bg-sunken rounded-lg space-y-2\"\n data-testid=\"agent-approval-pending\"\n >\n <div className=\"flex items-center gap-2 flex-wrap\">\n <Badge variant=\"warning\">{open.status}</Badge>\n <span className=\"text-sm text-text-secondary\">\n {t('botlit.agentApproval.requestedBy', 'Requested by')} {who(open.requestedById)}{' '}\n {formatRelativeTime(open.createdAt)}\n </span>\n </div>\n {open.requestNote && <p className=\"text-sm break-words\">{open.requestNote}</p>}\n {open.isStale && (\n <p className=\"flex items-center gap-2 text-sm text-status-warning-text\">\n <AlertTriangle size={14} />\n {t(\n 'botlit.agentApproval.stale',\n 'The agent changed after this request. Submit a new request so the reviewer sees the current configuration.'\n )}\n </p>\n )}\n <div className=\"flex gap-2 flex-wrap\">\n {isRequester ? (\n <>\n <Button\n variant=\"outline\"\n size=\"sm\"\n isLoading={pending === 'cancel'}\n onClick={() => void cancel(open)}\n >\n {t('botlit.agentApproval.cancelAction', 'Cancel request')}\n </Button>\n {open.isStale && (\n <Button size=\"sm\" onClick={() => setDialog({ kind: 'request' })}>\n {t('botlit.agentApproval.resubmitAction', 'Submit new request')}\n </Button>\n )}\n </>\n ) : (\n <>\n <Button\n size=\"sm\"\n leftIcon={<CheckCircle2 size={14} />}\n disabled={open.isStale}\n onClick={() => setDialog({ kind: 'approve', request: open })}\n >\n {t('botlit.agentApproval.approveAction', 'Approve')}\n </Button>\n <Button\n size=\"sm\"\n variant=\"destructive\"\n leftIcon={<XCircle size={14} />}\n onClick={() => setDialog({ kind: 'reject', request: open })}\n >\n {t('botlit.agentApproval.rejectAction', 'Reject')}\n </Button>\n </>\n )}\n </div>\n </div>\n )}\n\n {history.length > 0 && (\n <div className=\"space-y-2\">\n <p className=\"text-sm font-medium\">\n {t('botlit.agentApproval.history', 'Decision history')}\n </p>\n <ul className=\"space-y-2\" data-testid=\"agent-approval-history\">\n {history.map((request) => (\n <li\n key={request.id}\n className=\"p-3 border border-border-subtle rounded-lg text-sm space-y-1\"\n >\n <div className=\"flex items-center gap-2 flex-wrap\">\n <Badge variant={approvalStatusVariant(request.status)}>{request.status}</Badge>\n <span className=\"text-text-secondary\">\n {t('botlit.agentApproval.decidedBy', 'by')} {who(request.reviewerId)}{' '}\n {request.decidedAt ? formatRelativeTime(request.decidedAt) : ''}\n </span>\n </div>\n {request.decisionReason && (\n <p className=\"break-words\">{request.decisionReason}</p>\n )}\n </li>\n ))}\n </ul>\n </div>\n )}\n\n {!open && history.length === 0 && !requests.loading && (\n <p className=\"text-sm text-text-secondary\">\n {t('botlit.agentApproval.empty', 'No activation requests for this agent yet.')}\n </p>\n )}\n </CardContent>\n\n <ApprovalDecisionDialog\n kind={dialog?.kind ?? null}\n loading={pending !== null}\n onClose={() => setDialog(null)}\n onConfirm={confirm}\n />\n </Card>\n );\n};\n"],"mappings":";;;;;;;;;;;;;AAsCA,SAAgB,EACd,GACmD;AAInD,QAHI,MAAW,YAAkB,YAC7B,MAAW,aAAmB,YAC9B,MAAW,aAAmB,gBAC3B;;AAaT,IAAa,KAAmD,EAC9D,SACA,YACA,YACA,mBACI;CACJ,IAAM,IAAI,GAAO,EACX,CAAC,GAAM,KAAW,EAAS,GAAG,EAC9B,IAAiB,MAAS,UAE1B,IAAsF;EAC1F,SAAS;GACP,OAAO,EAAE,6CAA6C,qBAAqB;GAC3E,aAAa,EACX,mDACA,yJACD;GACD,SAAS,EAAE,+CAA+C,oBAAoB;GAC/E;EACD,SAAS;GACP,OAAO,EAAE,6CAA6C,sBAAsB;GAC5E,aAAa,EACX,mDACA,yEACD;GACD,SAAS,EAAE,+CAA+C,UAAU;GACrE;EACD,QAAQ;GACN,OAAO,EAAE,4CAA4C,oBAAoB;GACzE,aAAa,EACX,kDACA,qEACD;GACD,SAAS,EAAE,8CAA8C,SAAS;GACnE;EACF,EACK,IAAU,IAAO,EAAK,KAAQ;AAEpC,QACE,kBAAC,GAAD;EACE,MAAM,MAAS;EACf,eAAe,MAAS;AACtB,GAAK,MACH,EAAQ,GAAG,EACX,GAAS;;YAIb,kBAAC,GAAD,EAAA,UAAA;GACE,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,GAAD,EAAA,UAAc,GAAS,OAAoB,CAAA,EAC3C,kBAAC,GAAD,EAAA,UAAoB,GAAS,aAAgC,CAAA,CAChD,EAAA,CAAA;GACf,kBAAC,GAAD;IACE,cACE,MAAS,YACL,EAAE,yCAAyC,wBAAwB,GACnE,EAAE,2CAA2C,SAAS;IAE5D,OAAO;IACP,WAAW;IACX,WAAW,MAAU,EAAQ,EAAM,OAAO,MAAM;IAChD,aACE,MAAS,YACL,EAAE,+CAA+C,kCAAkC,GACnF,IACE,EAAE,yDAAyD,oBAAoB,GAC/E,EAAE,iDAAiD,oBAAoB;IAE/E,MAAM;IACN,CAAA;GACF,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,GAAD;IACE,SAAQ;IACR,eAAe;AAEb,KADA,EAAQ,GAAG,EACX,GAAS;;cAGV,EAAE,wBAAwB,SAAS;IAC7B,CAAA,EACT,kBAAC,GAAD;IACE,SAAS,MAAS,WAAW,gBAAgB;IAC7C,WAAW;IACX,UAAU,KAAkB,EAAK,MAAM,CAAC,WAAW;IACnD,SAAS,YAAY;AAEnB,KADA,MAAM,EAAU,EAAK,EACrB,EAAQ,GAAG;;cAGZ,GAAS;IACH,CAAA,CACI,EAAA,CAAA;GACD,EAAA,CAAA;EACT,CAAA;GAWA,KAAmD,EAC9D,YACA,gBACA,mBACI;CACJ,IAAM,IAAI,GAAO,EACX,EAAE,mBAAgB,GAAW,EAC7B,IAAW,GAA0B,EACrC,IAAW,EAAyB,EAAE,YAAS,CAAC,EAChD,EAAE,QAAK,eAAY,GAAyB,EAC5C,CAAC,GAAQ,KAAa,EAGlB,KAAK,EAET,IAAW,EAAS,MAAM,8BAA8B,IACxD,IAAO,EAAS,KAAK,MAAM,MAAY,EAAQ,WAAW,UAAU,IAAI,MACxE,IAAU,EAAS,KAAK,QAAQ,MAAY,EAAQ,WAAW,UAAU,CAAC,MAAM,GAAG,GAAG,EACtF,IAAc,MAAS,QAAQ,EAAK,kBAAkB,GAAa,IAEnE,KAAO,MACX,KAAM,MAAO,GAAa,KAAK,EAAE,4BAA4B,MAAM,GAAI,KAAM,KAEzE,IAAU,OAAO,MAAgC;AAChD,QACL,KAAI;AAaF,GAZI,EAAO,SAAS,aAClB,MAAM,EAAI;IAAE,MAAM;IAAW;IAAS,MAAM;IAAM,CAAC,EACnD,EAAM,QAAQ,EAAE,wCAAwC,uBAAuB,CAAC,IACvE,EAAO,SAAS,aAAa,EAAO,WAC7C,MAAM,EAAI;IAAE,MAAM;IAAW,IAAI,EAAO,QAAQ;IAAI,QAAQ;IAAM,CAAC,EACnE,EAAM,QAAQ,EAAE,uCAAuC,+BAA+B,CAAC,EACvF,KAAa,IACJ,EAAO,SAAS,YAAY,EAAO,YAC5C,MAAM,EAAI;IAAE,MAAM;IAAU,IAAI,EAAO,QAAQ;IAAI,QAAQ;IAAM,CAAC,EAClE,EAAM,QAAQ,EAAE,uCAAuC,sBAAsB,CAAC,GAEhF,EAAU,KAAK,EACf,MAAM,EAAS,SAAS;WACjB,GAAc;AACrB,KAAM,MACJ,aAAe,QACX,EAAI,UACJ,EAAE,oCAAoC,yBAAyB,CACpE;;IAIC,IAAS,OAAO,MAAuD;AAC3E,MAAI;AAGF,GAFA,MAAM,EAAI;IAAE,MAAM;IAAU,IAAI,EAAQ;IAAI,CAAC,EAC7C,EAAM,QAAQ,EAAE,wCAAwC,oBAAoB,CAAC,EAC7E,MAAM,EAAS,SAAS;WACjB,GAAc;AACrB,KAAM,MACJ,aAAe,QACX,EAAI,UACJ,EAAE,oCAAoC,yBAAyB,CACpE;;;AAIL,QACE,kBAAC,GAAD;EAAM,eAAY;YAAlB;GACE,kBAAC,GAAD;IAAY,WAAU;cAAtB,CACE,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,GAAD;KAAW,WAAU;eAArB;MACE,kBAAC,GAAD,EAAa,MAAM,IAAM,CAAA;MACxB,EAAE,8BAA8B,sBAAsB;MACvD,kBAAC,GAAD;OAAO,SAAS,IAAW,YAAY;iBACpC,IACG,EAAE,iCAAiC,6BAA6B,GAChE,EAAE,iCAAiC,WAAW;OAC5C,CAAA;MACE;QACZ,kBAAC,GAAD,EAAA,UACG,IACG,EACE,4CACA,mHACD,GACD,EACE,4CACA,qIACD,EACW,CAAA,CACd,EAAA,CAAA,EACL,CAAC,KAAQ,MAAgB,cACxB,kBAAC,GAAD;KAAQ,UAAU,kBAAC,GAAD,EAAM,MAAM,IAAM,CAAA;KAAE,eAAe,EAAU,EAAE,MAAM,WAAW,CAAC;eAChF,EAAE,sCAAsC,qBAAqB;KACvD,CAAA,CAEA;;GACb,kBAAC,GAAD;IAAa,WAAU;cAAvB;KACG,EAAS,WAAW,EAAS,KAAK,WAAW,IAC5C,kBAAC,OAAD,EAAK,WAAU,+DAAgE,CAAA,GAC7E;KAEH,KACC,kBAAC,OAAD;MACE,WAAU;MACV,eAAY;gBAFd;OAIE,kBAAC,OAAD;QAAK,WAAU;kBAAf,CACE,kBAAC,GAAD;SAAO,SAAQ;mBAAW,EAAK;SAAe,CAAA,EAC9C,kBAAC,QAAD;SAAM,WAAU;mBAAhB;UACG,EAAE,oCAAoC,eAAe;UAAC;UAAE,EAAI,EAAK,cAAc;UAAE;UACjF,EAAmB,EAAK,UAAU;UAC9B;WACH;;OACL,EAAK,eAAe,kBAAC,KAAD;QAAG,WAAU;kBAAuB,EAAK;QAAgB,CAAA;OAC7E,EAAK,WACJ,kBAAC,KAAD;QAAG,WAAU;kBAAb,CACE,kBAAC,GAAD,EAAe,MAAM,IAAM,CAAA,EAC1B,EACC,8BACA,6GACD,CACC;;OAEN,kBAAC,OAAD;QAAK,WAAU;kBACZ,IACC,kBAAA,GAAA,EAAA,UAAA,CACE,kBAAC,GAAD;SACE,SAAQ;SACR,MAAK;SACL,WAAW,MAAY;SACvB,eAAe,KAAK,EAAO,EAAK;mBAE/B,EAAE,qCAAqC,iBAAiB;SAClD,CAAA,EACR,EAAK,WACJ,kBAAC,GAAD;SAAQ,MAAK;SAAK,eAAe,EAAU,EAAE,MAAM,WAAW,CAAC;mBAC5D,EAAE,uCAAuC,qBAAqB;SACxD,CAAA,CAEV,EAAA,CAAA,GAEH,kBAAA,GAAA,EAAA,UAAA,CACE,kBAAC,GAAD;SACE,MAAK;SACL,UAAU,kBAAC,GAAD,EAAc,MAAM,IAAM,CAAA;SACpC,UAAU,EAAK;SACf,eAAe,EAAU;UAAE,MAAM;UAAW,SAAS;UAAM,CAAC;mBAE3D,EAAE,sCAAsC,UAAU;SAC5C,CAAA,EACT,kBAAC,GAAD;SACE,MAAK;SACL,SAAQ;SACR,UAAU,kBAAC,GAAD,EAAS,MAAM,IAAM,CAAA;SAC/B,eAAe,EAAU;UAAE,MAAM;UAAU,SAAS;UAAM,CAAC;mBAE1D,EAAE,qCAAqC,SAAS;SAC1C,CAAA,CACR,EAAA,CAAA;QAED,CAAA;OACF;;KAGP,EAAQ,SAAS,KAChB,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,KAAD;OAAG,WAAU;iBACV,EAAE,gCAAgC,mBAAmB;OACpD,CAAA,EACJ,kBAAC,MAAD;OAAI,WAAU;OAAY,eAAY;iBACnC,EAAQ,KAAK,MACZ,kBAAC,MAAD;QAEE,WAAU;kBAFZ,CAIE,kBAAC,OAAD;SAAK,WAAU;mBAAf,CACE,kBAAC,GAAD;UAAO,SAAS,EAAsB,EAAQ,OAAO;oBAAG,EAAQ;UAAe,CAAA,EAC/E,kBAAC,QAAD;UAAM,WAAU;oBAAhB;WACG,EAAE,kCAAkC,KAAK;WAAC;WAAE,EAAI,EAAQ,WAAW;WAAE;WACrE,EAAQ,YAAY,EAAmB,EAAQ,UAAU,GAAG;WACxD;YACH;YACL,EAAQ,kBACP,kBAAC,KAAD;SAAG,WAAU;mBAAe,EAAQ;SAAmB,CAAA,CAEtD;UAbE,EAAQ,GAaV,CACL;OACC,CAAA,CACD;;KAGP,CAAC,KAAQ,EAAQ,WAAW,KAAK,CAAC,EAAS,WAC1C,kBAAC,KAAD;MAAG,WAAU;gBACV,EAAE,8BAA8B,6CAA6C;MAC5E,CAAA;KAEM;;GAEd,kBAAC,GAAD;IACE,MAAM,GAAQ,QAAQ;IACtB,SAAS,MAAY;IACrB,eAAe,EAAU,KAAK;IAC9B,WAAW;IACX,CAAA;GACG"}
1
+ {"version":3,"file":"AgentApprovalPanel.js","names":[],"sources":["../../../src/botlit/components/AgentApprovalPanel.tsx"],"sourcesContent":["/**\n * Agent Activation Approval Panel (BOFF-9682)\n * @module botlit/components\n *\n * Reviewer gate on the agent detail page. Builders request activation (the\n * request pins the agent's current config); reviewers with\n * `botmanor-agent:approve` approve it, which publishes the draft and takes the\n * agent live, or reject it with a reason. The requester cannot decide their\n * own request, and a request whose agent changed afterwards is flagged stale\n * and cannot be approved.\n */\n\nimport { useState, type FC } from 'react';\nimport { AlertTriangle, CheckCircle2, ShieldCheck, Send, XCircle } from 'lucide-react';\nimport { toast } from 'sonner';\nimport {\n Dialog,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n Textarea,\n} from '@burdenoff/fe-libs/ui';\nimport { useTr } from '../../shared/hooks/useTr';\nimport { Card, CardContent, CardDescription, CardHeader, CardTitle } from './Card';\nimport { Button } from './Button';\nimport { Badge } from './Badge';\nimport {\n useAgentApprovalActions,\n useAgentApprovalRequests,\n useAgentApprovalSettings,\n type AgentApprovalRequestRecord,\n type AgentApprovalStatus,\n} from '../hooks/useAgentApprovals';\nimport { useBotlit } from '../providers/BotlitProvider';\nimport { formatRelativeTime } from '../utils/formatters';\nimport { BOTMANOR_PERMISSIONS, BotmanorPermissionGate } from '../permissions';\n\nexport function approvalStatusVariant(\n status: AgentApprovalStatus\n): 'warning' | 'success' | 'destructive' | 'outline' {\n if (status === 'PENDING') return 'warning';\n if (status === 'APPROVED') return 'success';\n if (status === 'REJECTED') return 'destructive';\n return 'outline';\n}\n\ntype DecisionKind = 'request' | 'approve' | 'reject';\n\ninterface DecisionDialogProps {\n kind: DecisionKind | null;\n loading: boolean;\n onClose: () => void;\n onConfirm: (text: string) => Promise<void>;\n}\n\n/** Note / reason dialog shared by the detail panel and the approvals page. */\nexport const ApprovalDecisionDialog: FC<DecisionDialogProps> = ({\n kind,\n loading,\n onClose,\n onConfirm,\n}) => {\n const t = useTr();\n const [text, setText] = useState('');\n const reasonRequired = kind === 'reject';\n\n const copy: Record<DecisionKind, { title: string; description: string; confirm: string }> = {\n request: {\n title: t('botlit.agentApproval.dialog.request.title', 'Request activation'),\n description: t(\n 'botlit.agentApproval.dialog.request.description',\n \"A reviewer will check the agent's current prompt, model, tools and limits before it goes live. Changing the agent afterwards makes this request stale.\"\n ),\n confirm: t('botlit.agentApproval.dialog.request.confirm', 'Submit for review'),\n },\n approve: {\n title: t('botlit.agentApproval.dialog.approve.title', 'Approve and go live'),\n description: t(\n 'botlit.agentApproval.dialog.approve.description',\n \"Approving publishes the agent's draft and makes it ACTIVE immediately.\"\n ),\n confirm: t('botlit.agentApproval.dialog.approve.confirm', 'Approve'),\n },\n reject: {\n title: t('botlit.agentApproval.dialog.reject.title', 'Reject activation'),\n description: t(\n 'botlit.agentApproval.dialog.reject.description',\n 'Tell the requester what needs to change. The agent stays as it is.'\n ),\n confirm: t('botlit.agentApproval.dialog.reject.confirm', 'Reject'),\n },\n };\n const current = kind ? copy[kind] : null;\n\n return (\n <Dialog\n open={kind !== null}\n onOpenChange={(open) => {\n if (!open) {\n setText('');\n onClose();\n }\n }}\n >\n <DialogContent>\n <DialogHeader>\n <DialogTitle>{current?.title}</DialogTitle>\n <DialogDescription>{current?.description}</DialogDescription>\n </DialogHeader>\n <Textarea\n aria-label={\n kind === 'request'\n ? t('botlit.agentApproval.dialog.noteLabel', 'Note for the reviewer')\n : t('botlit.agentApproval.dialog.reasonLabel', 'Reason')\n }\n value={text}\n maxLength={2000}\n onChange={(event) => setText(event.target.value)}\n placeholder={\n kind === 'request'\n ? t('botlit.agentApproval.dialog.notePlaceholder', 'What changed and why (optional)')\n : reasonRequired\n ? t('botlit.agentApproval.dialog.reasonRequiredPlaceholder', 'Reason (required)')\n : t('botlit.agentApproval.dialog.reasonPlaceholder', 'Reason (optional)')\n }\n rows={4}\n />\n <DialogFooter>\n <Button\n variant=\"outline\"\n onClick={() => {\n setText('');\n onClose();\n }}\n >\n {t('botlit.common.cancel', 'Cancel')}\n </Button>\n <Button\n variant={kind === 'reject' ? 'destructive' : 'default'}\n isLoading={loading}\n disabled={reasonRequired && text.trim().length === 0}\n onClick={async () => {\n await onConfirm(text);\n setText('');\n }}\n >\n {current?.confirm}\n </Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n );\n};\n\ninterface AgentApprovalPanelProps {\n agentId: string;\n agentStatus: string;\n /** Called after a decision that changes the agent so the page can refetch it. */\n onChanged?: () => void;\n}\n\nexport const AgentApprovalPanel: FC<AgentApprovalPanelProps> = ({\n agentId,\n agentStatus,\n onChanged,\n}) => {\n const t = useTr();\n const { currentUser } = useBotlit();\n const settings = useAgentApprovalSettings();\n const requests = useAgentApprovalRequests({ agentId });\n const { run, pending } = useAgentApprovalActions();\n const [dialog, setDialog] = useState<{\n kind: DecisionKind;\n request?: AgentApprovalRequestRecord;\n } | null>(null);\n\n const required = settings.data?.requireActivationApproval === true;\n const open = requests.data.find((request) => request.status === 'PENDING') ?? null;\n const history = requests.data.filter((request) => request.status !== 'PENDING').slice(0, 10);\n const isRequester = open !== null && open.requestedById === currentUser?.id;\n\n const who = (id?: string | null): string =>\n id && id === currentUser?.id ? t('botlit.agentApproval.you', 'you') : (id ?? '—');\n\n const confirm = async (text: string): Promise<void> => {\n if (!dialog) return;\n try {\n if (dialog.kind === 'request') {\n await run({ kind: 'request', agentId, note: text });\n toast.success(t('botlit.agentApproval.toast.requested', 'Activation requested'));\n } else if (dialog.kind === 'approve' && dialog.request) {\n await run({ kind: 'approve', id: dialog.request.id, reason: text });\n toast.success(t('botlit.agentApproval.toast.approved', 'Approved — the agent is live'));\n onChanged?.();\n } else if (dialog.kind === 'reject' && dialog.request) {\n await run({ kind: 'reject', id: dialog.request.id, reason: text });\n toast.success(t('botlit.agentApproval.toast.rejected', 'Activation rejected'));\n }\n setDialog(null);\n await requests.refetch();\n } catch (err: unknown) {\n toast.error(\n err instanceof Error\n ? err.message\n : t('botlit.agentApproval.toast.error', 'Approval action failed')\n );\n }\n };\n\n const cancel = async (request: AgentApprovalRequestRecord): Promise<void> => {\n try {\n await run({ kind: 'cancel', id: request.id });\n toast.success(t('botlit.agentApproval.toast.cancelled', 'Request cancelled'));\n await requests.refetch();\n } catch (err: unknown) {\n toast.error(\n err instanceof Error\n ? err.message\n : t('botlit.agentApproval.toast.error', 'Approval action failed')\n );\n }\n };\n\n return (\n <Card data-testid=\"agent-approval-panel\">\n <CardHeader className=\"flex flex-row items-start justify-between gap-4\">\n <div>\n <CardTitle className=\"flex items-center gap-2\">\n <ShieldCheck size={18} />\n {t('botlit.agentApproval.title', 'Activation approval')}\n <Badge variant={required ? 'warning' : 'outline'}>\n {required\n ? t('botlit.agentApproval.required', 'Required in this workspace')\n : t('botlit.agentApproval.optional', 'Optional')}\n </Badge>\n </CardTitle>\n <CardDescription>\n {required\n ? t(\n 'botlit.agentApproval.descriptionRequired',\n 'This workspace requires a reviewer to approve an agent before it goes live or before a new version is published.'\n )\n : t(\n 'botlit.agentApproval.descriptionOptional',\n 'You can ask a reviewer to check this agent before it goes live. A workspace admin can make review mandatory on the Approvals page.'\n )}\n </CardDescription>\n </div>\n {!open && agentStatus !== 'ARCHIVED' && (\n <BotmanorPermissionGate permission={BOTMANOR_PERMISSIONS.AGENT_UPDATE}>\n <Button leftIcon={<Send size={16} />} onClick={() => setDialog({ kind: 'request' })}>\n {t('botlit.agentApproval.requestAction', 'Request activation')}\n </Button>\n </BotmanorPermissionGate>\n )}\n </CardHeader>\n <CardContent className=\"space-y-4\">\n {requests.loading && requests.data.length === 0 ? (\n <div className=\"h-20 bg-bg-sunken motion-safe:animate-vc-shimmer rounded-lg\" />\n ) : null}\n\n {open && (\n <div\n className=\"p-4 border border-status-warning-border bg-bg-sunken rounded-lg space-y-2\"\n data-testid=\"agent-approval-pending\"\n >\n <div className=\"flex items-center gap-2 flex-wrap\">\n <Badge variant=\"warning\">{open.status}</Badge>\n <span className=\"text-sm text-text-secondary\">\n {t('botlit.agentApproval.requestedBy', 'Requested by')} {who(open.requestedById)}{' '}\n {formatRelativeTime(open.createdAt)}\n </span>\n </div>\n {open.requestNote && <p className=\"text-sm break-words\">{open.requestNote}</p>}\n {open.isStale && (\n <p className=\"flex items-center gap-2 text-sm text-status-warning-text\">\n <AlertTriangle size={14} />\n {t(\n 'botlit.agentApproval.stale',\n 'The agent changed after this request. Submit a new request so the reviewer sees the current configuration.'\n )}\n </p>\n )}\n <div className=\"flex gap-2 flex-wrap\">\n {isRequester ? (\n <>\n <BotmanorPermissionGate permission={BOTMANOR_PERMISSIONS.AGENT_UPDATE}>\n <Button\n variant=\"outline\"\n size=\"sm\"\n isLoading={pending === 'cancel'}\n onClick={() => void cancel(open)}\n >\n {t('botlit.agentApproval.cancelAction', 'Cancel request')}\n </Button>\n </BotmanorPermissionGate>\n {open.isStale && (\n <BotmanorPermissionGate permission={BOTMANOR_PERMISSIONS.AGENT_UPDATE}>\n <Button size=\"sm\" onClick={() => setDialog({ kind: 'request' })}>\n {t('botlit.agentApproval.resubmitAction', 'Submit new request')}\n </Button>\n </BotmanorPermissionGate>\n )}\n </>\n ) : (\n <>\n <BotmanorPermissionGate permission={BOTMANOR_PERMISSIONS.AGENT_APPROVE}>\n <Button\n size=\"sm\"\n leftIcon={<CheckCircle2 size={14} />}\n disabled={open.isStale}\n onClick={() => setDialog({ kind: 'approve', request: open })}\n >\n {t('botlit.agentApproval.approveAction', 'Approve')}\n </Button>\n </BotmanorPermissionGate>\n <BotmanorPermissionGate permission={BOTMANOR_PERMISSIONS.AGENT_APPROVE}>\n <Button\n size=\"sm\"\n variant=\"destructive\"\n leftIcon={<XCircle size={14} />}\n onClick={() => setDialog({ kind: 'reject', request: open })}\n >\n {t('botlit.agentApproval.rejectAction', 'Reject')}\n </Button>\n </BotmanorPermissionGate>\n </>\n )}\n </div>\n </div>\n )}\n\n {history.length > 0 && (\n <div className=\"space-y-2\">\n <p className=\"text-sm font-medium\">\n {t('botlit.agentApproval.history', 'Decision history')}\n </p>\n <ul className=\"space-y-2\" data-testid=\"agent-approval-history\">\n {history.map((request) => (\n <li\n key={request.id}\n className=\"p-3 border border-border-subtle rounded-lg text-sm space-y-1\"\n >\n <div className=\"flex items-center gap-2 flex-wrap\">\n <Badge variant={approvalStatusVariant(request.status)}>{request.status}</Badge>\n <span className=\"text-text-secondary\">\n {t('botlit.agentApproval.decidedBy', 'by')} {who(request.reviewerId)}{' '}\n {request.decidedAt ? formatRelativeTime(request.decidedAt) : ''}\n </span>\n </div>\n {request.decisionReason && (\n <p className=\"break-words\">{request.decisionReason}</p>\n )}\n </li>\n ))}\n </ul>\n </div>\n )}\n\n {!open && history.length === 0 && !requests.loading && (\n <p className=\"text-sm text-text-secondary\">\n {t('botlit.agentApproval.empty', 'No activation requests for this agent yet.')}\n </p>\n )}\n </CardContent>\n\n <ApprovalDecisionDialog\n kind={dialog?.kind ?? null}\n loading={pending !== null}\n onClose={() => setDialog(null)}\n onConfirm={confirm}\n />\n </Card>\n );\n};\n"],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  import { useCreateLLMModel as e } from "../hooks/useLLMProviders.js";
2
- import { Card as t, CardContent as n, CardHeader as r, CardTitle as i } from "./Card.js";
3
- import { Button as a } from "./Button.js";
2
+ import { Button as t } from "./Button.js";
3
+ import { Card as n, CardContent as r, CardHeader as i, CardTitle as a } from "./Card.js";
4
4
  import { FormField as o, Input as s } from "./Input.js";
5
5
  import { useState as c } from "react";
6
6
  import { jsx as l, jsxs as u } from "react/jsx-runtime";
@@ -12,7 +12,7 @@ function f({ providers: f, onCreated: p }) {
12
12
  "AZURE_OPENAI",
13
13
  "CUSTOM"
14
14
  ].includes(F?.type ?? ""), L = P.some((e) => e.id === g) && !!(v.trim() && b.trim()) && Number.isSafeInteger(Number(E)) && Number(E) > 0 && (S !== "embedding" || I && Number.isInteger(Number(w)) && Number(w) > 0 && Number(w) <= 16e3) && (S === "embedding" || Number.isSafeInteger(Number(O)) && Number(O) > 0) && (S === "embedding" ? [A] : [A, M]).every((e) => e.trim() !== "" && Number.isFinite(Number(e)) && Number(e) >= 0);
15
- return /* @__PURE__ */ u(t, { children: [/* @__PURE__ */ l(r, { children: /* @__PURE__ */ l(i, { children: "Register model" }) }), /* @__PURE__ */ u(n, {
15
+ return /* @__PURE__ */ u(n, { children: [/* @__PURE__ */ l(i, { children: /* @__PURE__ */ l(a, { children: "Register model" }) }), /* @__PURE__ */ u(r, {
16
16
  className: "space-y-4",
17
17
  children: [
18
18
  /* @__PURE__ */ l("p", {
@@ -138,7 +138,7 @@ function f({ providers: f, onCreated: p }) {
138
138
  onChange: (e) => N(e.target.value)
139
139
  })
140
140
  }),
141
- /* @__PURE__ */ l(a, {
141
+ /* @__PURE__ */ l(t, {
142
142
  disabled: !L,
143
143
  isLoading: h,
144
144
  onClick: async () => {