@burdenoff/microfe-admin 2026.624.1 → 2026.626.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.
Files changed (76) hide show
  1. package/dist/admin/components/AccessDenied.js +2 -2
  2. package/dist/admin/components/AccessDenied.js.map +1 -1
  3. package/dist/admin/components/ActivityFeed.js +4 -4
  4. package/dist/admin/components/ActivityFeed.js.map +1 -1
  5. package/dist/admin/components/Charts.js.map +1 -1
  6. package/dist/admin/components/ConfirmDialog.js +1 -1
  7. package/dist/admin/components/ConfirmDialog.js.map +1 -1
  8. package/dist/admin/components/DataTable.js +5 -5
  9. package/dist/admin/components/DataTable.js.map +1 -1
  10. package/dist/admin/components/FormSheet.js +1 -1
  11. package/dist/admin/components/FormSheet.js.map +1 -1
  12. package/dist/admin/components/MetricCard.js +40 -37
  13. package/dist/admin/components/MetricCard.js.map +1 -1
  14. package/dist/admin/components/PageLayout.js +28 -22
  15. package/dist/admin/components/PageLayout.js.map +1 -1
  16. package/dist/admin/components/TenantSsoPanel.js +1 -1
  17. package/dist/admin/components/TenantSsoPanel.js.map +1 -1
  18. package/dist/admin/components/Toast.js +11 -11
  19. package/dist/admin/components/Toast.js.map +1 -1
  20. package/dist/admin/components/forms/SubscriptionForm.js +2 -2
  21. package/dist/admin/components/forms/SubscriptionForm.js.map +1 -1
  22. package/dist/admin/components/forms/TenantForm.js +1 -1
  23. package/dist/admin/components/forms/UserForm.js +1 -1
  24. package/dist/admin/components/ui.js +48 -41
  25. package/dist/admin/components/ui.js.map +1 -1
  26. package/dist/admin/constants/index.js +33 -24
  27. package/dist/admin/constants/index.js.map +1 -1
  28. package/dist/admin/pages/AuditLogsPage.js +94 -77
  29. package/dist/admin/pages/AuditLogsPage.js.map +1 -1
  30. package/dist/admin/pages/BillingPage.js +70 -18
  31. package/dist/admin/pages/BillingPage.js.map +1 -1
  32. package/dist/admin/pages/CommunicationsPage.js +98 -90
  33. package/dist/admin/pages/CommunicationsPage.js.map +1 -1
  34. package/dist/admin/pages/ContentPagesPage.js +276 -259
  35. package/dist/admin/pages/ContentPagesPage.js.map +1 -1
  36. package/dist/admin/pages/DashboardPage.js +114 -82
  37. package/dist/admin/pages/DashboardPage.js.map +1 -1
  38. package/dist/admin/pages/FeatureFlagsPage.js +94 -74
  39. package/dist/admin/pages/FeatureFlagsPage.js.map +1 -1
  40. package/dist/admin/pages/OrganizationsListPage.js +106 -86
  41. package/dist/admin/pages/OrganizationsListPage.js.map +1 -1
  42. package/dist/admin/pages/ProductsPage.js +139 -128
  43. package/dist/admin/pages/ProductsPage.js.map +1 -1
  44. package/dist/admin/pages/ReferralsPage.js +74 -52
  45. package/dist/admin/pages/ReferralsPage.js.map +1 -1
  46. package/dist/admin/pages/RolesPermissionsPage.js +137 -116
  47. package/dist/admin/pages/RolesPermissionsPage.js.map +1 -1
  48. package/dist/admin/pages/SREPage.js +38 -32
  49. package/dist/admin/pages/SREPage.js.map +1 -1
  50. package/dist/admin/pages/SandboxSettingsPage.js +361 -322
  51. package/dist/admin/pages/SandboxSettingsPage.js.map +1 -1
  52. package/dist/admin/pages/SettingsPage.js +145 -130
  53. package/dist/admin/pages/SettingsPage.js.map +1 -1
  54. package/dist/admin/pages/SyncFailuresPage.js +123 -118
  55. package/dist/admin/pages/SyncFailuresPage.js.map +1 -1
  56. package/dist/admin/pages/TenantDetailPage.js +261 -218
  57. package/dist/admin/pages/TenantDetailPage.js.map +1 -1
  58. package/dist/admin/pages/TenantFormRoutePage.js +65 -61
  59. package/dist/admin/pages/TenantFormRoutePage.js.map +1 -1
  60. package/dist/admin/pages/TenantsListPage.js +88 -71
  61. package/dist/admin/pages/TenantsListPage.js.map +1 -1
  62. package/dist/admin/pages/UsersListPage.js +129 -112
  63. package/dist/admin/pages/UsersListPage.js.map +1 -1
  64. package/dist/admin/pages/WaitlistPage.js +80 -63
  65. package/dist/admin/pages/WaitlistPage.js.map +1 -1
  66. package/dist/admin/pages/WorkflowsPage.js +108 -100
  67. package/dist/admin/pages/WorkflowsPage.js.map +1 -1
  68. package/dist/admin/pages/WorkspacesListPage.js +62 -49
  69. package/dist/admin/pages/WorkspacesListPage.js.map +1 -1
  70. package/dist/node_modules/@hookform/resolvers/dist/resolvers.js +2 -2
  71. package/dist/node_modules/@hookform/resolvers/dist/resolvers.js.map +1 -1
  72. package/dist/node_modules/@hookform/resolvers/zod/dist/zod.js +35 -26
  73. package/dist/node_modules/@hookform/resolvers/zod/dist/zod.js.map +1 -1
  74. package/dist/node_modules/react-hook-form/dist/index.esm.js +609 -516
  75. package/dist/node_modules/react-hook-form/dist/index.esm.js.map +1 -1
  76. package/package.json +2 -2
@@ -9,14 +9,15 @@ import "../components/index.js";
9
9
  import { useCallback as h, useEffect as g, useState as _ } from "react";
10
10
  import { Box as v, CheckSquare as y, Cpu as b, MemoryStick as x, Save as S, Timer as C, Users as w } from "lucide-react";
11
11
  import { jsx as T, jsxs as E } from "react/jsx-runtime";
12
+ import { NextSteps as D, PagePurpose as O } from "@burdenoff/fe-libs/ui";
12
13
  //#region src/admin/pages/SandboxSettingsPage.tsx
13
- var D = [
14
+ var k = [
14
15
  "VIBECONTROLS",
15
16
  "AI_BUILDER",
16
17
  "WORKFLOW_MULTI_NODE",
17
18
  "MISC_SHELL",
18
19
  "CUSTOM"
19
- ], O = [
20
+ ], A = [
20
21
  {
21
22
  label: "30 minutes",
22
23
  value: 1800
@@ -41,17 +42,17 @@ var D = [
41
42
  label: "24 hours",
42
43
  value: 86400
43
44
  }
44
- ], k = {
45
+ ], j = {
45
46
  totalActive: 12,
46
47
  totalQueued: 3,
47
48
  totalCompleted: 847,
48
49
  totalFailed: 14
49
50
  };
50
- function A(e) {
51
+ function M(e) {
51
52
  return e ? e.includes("localhost:4000") ? e.replace("localhost:4000", "localhost:4003").replace("/global/", "/workspaces/") : e.includes("/global/") ? e.replace(/\/\/graphql\./, "//graphqlworkspaces.").replace(/\/\/alphagraphql\./, "//alphagraphqlworkspaces.").replace("/global/", "/workspaces/") : "http://localhost:4003/workspaces/graphql" : "http://localhost:4003/workspaces/graphql";
52
53
  }
53
- function j() {
54
- let { canManageSandbox: j, isLoading: P } = n(), F = e(), { apiGatewayUrl: I, authToken: L, tenantId: R } = t(), z = A(I), [B, V] = _({
54
+ function N() {
55
+ let { canManageSandbox: N, isLoading: I } = n(), L = e(), { apiGatewayUrl: R, authToken: z, tenantId: B } = t(), V = M(R), [H, U] = _({
55
56
  defaultTtl: 3600,
56
57
  maxTtl: 14400,
57
58
  allowedSandboxTypes: [
@@ -67,21 +68,21 @@ function j() {
67
68
  defaultCpuLimit: "2",
68
69
  defaultMemoryRequest: "512Mi",
69
70
  defaultMemoryLimit: "4Gi"
70
- }), [H, U] = _(!1), [W, G] = _(!1);
71
+ }), [W, G] = _(!1), [K, q] = _(!1);
71
72
  g(() => {
72
- if (!R || P || !j) return;
73
+ if (!B || I || !N) return;
73
74
  let e = { "Content-Type": "application/json" };
74
- L && (e.Authorization = `Bearer ${L}`), R && (e["X-Workspace-ID"] = R), G(!0), fetch(z, {
75
+ z && (e.Authorization = `Bearer ${z}`), B && (e["X-Workspace-ID"] = B), q(!0), fetch(V, {
75
76
  method: "POST",
76
77
  headers: e,
77
78
  body: JSON.stringify({
78
79
  query: "query GetSandboxConfig($context: ContextInput!) {\n getSandboxConfig(context: $context) {\n id\n defaultTtlSeconds\n maxTtlSeconds\n allowedTemplates\n maxConcurrentPerUser\n maxConcurrentPerWorkspace\n defaultCpuRequest\n defaultCpuLimit\n defaultMemoryRequest\n defaultMemoryLimit\n }\n }",
79
- variables: { context: { workspaceId: R } }
80
+ variables: { context: { workspaceId: B } }
80
81
  })
81
82
  }).then((e) => e.json()).then((e) => {
82
83
  if (e.data?.getSandboxConfig) {
83
84
  let t = e.data.getSandboxConfig;
84
- V({
85
+ U({
85
86
  defaultTtl: t.defaultTtlSeconds,
86
87
  maxTtl: t.maxTtlSeconds,
87
88
  allowedSandboxTypes: t.allowedTemplates,
@@ -94,386 +95,424 @@ function j() {
94
95
  });
95
96
  }
96
97
  }).catch((e) => {
97
- console.error("Failed to load sandbox config:", e), F.error("Load Failed", "Failed to load sandbox configuration.");
98
- }).finally(() => G(!1));
98
+ console.error("Failed to load sandbox config:", e), L.error("Load Failed", "Failed to load sandbox configuration.");
99
+ }).finally(() => q(!1));
99
100
  }, [
100
- R,
101
- L,
101
+ B,
102
102
  z,
103
- P,
104
- j
103
+ V,
104
+ I,
105
+ N
105
106
  ]);
106
- let K = h((e, t) => {
107
- V((n) => ({
107
+ let J = h((e, t) => {
108
+ U((n) => ({
108
109
  ...n,
109
110
  [e]: t
110
111
  }));
111
- }, []), q = h((e) => {
112
- V((t) => {
112
+ }, []), Y = h((e) => {
113
+ U((t) => {
113
114
  let n = t.allowedSandboxTypes.includes(e) ? t.allowedSandboxTypes.filter((t) => t !== e) : [...t.allowedSandboxTypes, e];
114
115
  return {
115
116
  ...t,
116
117
  allowedSandboxTypes: n
117
118
  };
118
119
  });
119
- }, []), J = h(async () => {
120
- if (B.maxTtl < B.defaultTtl) {
121
- F.error("Validation Error", "Max TTL must be greater than or equal to Default TTL.");
120
+ }, []), X = h(async () => {
121
+ if (H.maxTtl < H.defaultTtl) {
122
+ L.error("Validation Error", "Max TTL must be greater than or equal to Default TTL.");
122
123
  return;
123
124
  }
124
- if (B.allowedSandboxTypes.length === 0) {
125
- F.error("Validation Error", "At least one sandbox type must be allowed.");
125
+ if (H.allowedSandboxTypes.length === 0) {
126
+ L.error("Validation Error", "At least one sandbox type must be allowed.");
126
127
  return;
127
128
  }
128
- U(!0);
129
+ G(!0);
129
130
  try {
130
131
  let e = { "Content-Type": "application/json" };
131
- L && (e.Authorization = `Bearer ${L}`), R && (e["X-Workspace-ID"] = R);
132
- let t = await (await fetch(z, {
132
+ z && (e.Authorization = `Bearer ${z}`), B && (e["X-Workspace-ID"] = B);
133
+ let t = await (await fetch(V, {
133
134
  method: "POST",
134
135
  headers: e,
135
136
  body: JSON.stringify({
136
137
  query: "mutation UpdateSandboxConfig($input: UpdateSandboxConfigInput!) {\n updateSandboxConfig(input: $input) {\n id\n defaultTtlSeconds\n maxTtlSeconds\n allowedTemplates\n maxConcurrentPerUser\n maxConcurrentPerWorkspace\n defaultCpuRequest\n defaultCpuLimit\n defaultMemoryRequest\n defaultMemoryLimit\n }\n }",
137
138
  variables: { input: {
138
- defaultTtlSeconds: B.defaultTtl,
139
- maxTtlSeconds: B.maxTtl,
140
- allowedTemplates: B.allowedSandboxTypes,
141
- maxConcurrentPerUser: B.maxConcurrentPerUser,
142
- maxConcurrentPerWorkspace: B.maxConcurrentPerWorkspace,
143
- defaultCpuRequest: B.defaultCpuRequest,
144
- defaultCpuLimit: B.defaultCpuLimit,
145
- defaultMemoryRequest: B.defaultMemoryRequest,
146
- defaultMemoryLimit: B.defaultMemoryLimit,
147
- context: { workspaceId: R }
139
+ defaultTtlSeconds: H.defaultTtl,
140
+ maxTtlSeconds: H.maxTtl,
141
+ allowedTemplates: H.allowedSandboxTypes,
142
+ maxConcurrentPerUser: H.maxConcurrentPerUser,
143
+ maxConcurrentPerWorkspace: H.maxConcurrentPerWorkspace,
144
+ defaultCpuRequest: H.defaultCpuRequest,
145
+ defaultCpuLimit: H.defaultCpuLimit,
146
+ defaultMemoryRequest: H.defaultMemoryRequest,
147
+ defaultMemoryLimit: H.defaultMemoryLimit,
148
+ context: { workspaceId: B }
148
149
  } }
149
150
  })
150
151
  })).json();
151
152
  if (t.errors) throw Error(t.errors[0]?.message || "Failed to save sandbox configuration");
152
- F.success("Settings Saved", "Sandbox configuration has been updated successfully.");
153
+ L.success("Settings Saved", "Sandbox configuration has been updated successfully.");
153
154
  } catch (e) {
154
- F.error("Save Failed", e instanceof Error ? e.message : "Failed to update sandbox configuration. Please try again.");
155
+ L.error("Save Failed", e instanceof Error ? e.message : "Failed to update sandbox configuration. Please try again.");
155
156
  } finally {
156
- U(!1);
157
+ G(!1);
157
158
  }
158
159
  }, [
159
- B,
160
- F,
160
+ H,
161
161
  L,
162
- R,
163
- z
164
- ]), Y = "h-10 w-full rounded-md border border-border-default bg-bg-surface px-3 py-2 text-sm";
162
+ z,
163
+ B,
164
+ V
165
+ ]), Z = "h-10 w-full rounded-md border border-border-default bg-bg-surface px-3 py-2 text-sm";
165
166
  return /* @__PURE__ */ T(m, {
166
- allowed: j,
167
- isLoading: P,
167
+ allowed: N,
168
+ isLoading: I,
168
169
  pageTitle: "Sandbox Settings",
169
170
  denyMessage: "You don't have permission to manage sandbox settings.",
170
171
  children: /* @__PURE__ */ E(d, {
171
172
  title: "Sandbox Settings",
173
+ gradientWord: "Settings",
172
174
  description: "Configure platform-wide sandbox defaults and resource limits",
173
- children: [/* @__PURE__ */ E(i, {
174
- className: "mb-6",
175
- children: [/* @__PURE__ */ E(s, { children: [/* @__PURE__ */ E("div", {
176
- className: "flex items-center gap-2",
177
- children: [/* @__PURE__ */ T(v, { className: "h-5 w-5 text-text-secondary" }), /* @__PURE__ */ T(c, {
178
- className: "text-lg",
179
- children: "Sandbox Stats"
180
- })]
181
- }), /* @__PURE__ */ T(o, { children: "Current sandbox usage across the platform" })] }), /* @__PURE__ */ T(a, { children: /* @__PURE__ */ E(p, { children: [
182
- /* @__PURE__ */ T(f, {
183
- title: "Active Sandboxes",
184
- value: k.totalActive,
185
- trend: "up"
186
- }),
187
- /* @__PURE__ */ T(f, {
188
- title: "Queued",
189
- value: k.totalQueued
190
- }),
191
- /* @__PURE__ */ T(f, {
192
- title: "Completed (all time)",
193
- value: k.totalCompleted
194
- }),
195
- /* @__PURE__ */ T(f, {
196
- title: "Failed (all time)",
197
- value: k.totalFailed,
198
- trend: "down"
199
- })
200
- ] }) })]
201
- }), /* @__PURE__ */ E("div", {
202
- className: "grid gap-6 lg:grid-cols-3",
203
- children: [/* @__PURE__ */ E("div", {
204
- className: "space-y-6 lg:col-span-2",
205
- children: [
206
- /* @__PURE__ */ E(i, { children: [/* @__PURE__ */ E(s, { children: [/* @__PURE__ */ E("div", {
207
- className: "flex items-center gap-2",
208
- children: [/* @__PURE__ */ T(C, { className: "h-5 w-5 text-text-secondary" }), /* @__PURE__ */ T(c, {
209
- className: "text-lg",
210
- children: "Time-to-Live (TTL)"
211
- })]
212
- }), /* @__PURE__ */ T(o, { children: "Control how long sandboxes stay alive before automatic cleanup" })] }), /* @__PURE__ */ T(a, {
213
- className: "space-y-4",
214
- children: /* @__PURE__ */ E("div", {
215
- className: "grid gap-4 sm:grid-cols-2",
216
- children: [/* @__PURE__ */ E("div", {
217
- className: "space-y-2",
218
- children: [
219
- /* @__PURE__ */ T("label", {
220
- className: "text-sm font-medium",
221
- children: "Default TTL"
222
- }),
223
- /* @__PURE__ */ T("select", {
224
- className: Y,
225
- value: B.defaultTtl,
226
- onChange: (e) => K("defaultTtl", Number(e.target.value)),
227
- children: O.map((e) => /* @__PURE__ */ T("option", {
228
- value: e.value,
229
- children: e.label
230
- }, e.value))
231
- }),
232
- /* @__PURE__ */ T("p", {
233
- className: "text-xs text-text-secondary",
234
- children: "Default lifetime for new sandboxes"
235
- })
236
- ]
237
- }), /* @__PURE__ */ E("div", {
238
- className: "space-y-2",
175
+ children: [
176
+ /* @__PURE__ */ T(O, {
177
+ className: "mb-6",
178
+ children: "Sandboxes are the disposable, isolated environments users spin up to safely run or preview their code without touching anything real. This page sets the platform-wide defaults for them — how long a sandbox lives before it's cleaned up, how much CPU and memory it gets, and how many a user or tenant may run at once. Tune these to balance a smooth experience against runaway resource costs."
179
+ }),
180
+ /* @__PURE__ */ T(D, {
181
+ storageKey: "admin-sandbox",
182
+ steps: [
183
+ {
184
+ id: "set-ttl",
185
+ label: "Set the sandbox TTL",
186
+ description: "Decide how long idle sandboxes live before automatic cleanup.",
187
+ href: "#ttl"
188
+ },
189
+ {
190
+ id: "set-limits",
191
+ label: "Cap CPU & memory",
192
+ description: "Set the resource ceiling each sandbox is allowed.",
193
+ href: "#resources"
194
+ },
195
+ {
196
+ id: "save-config",
197
+ label: "Save your configuration",
198
+ description: "Apply these defaults across the whole platform.",
199
+ onClick: () => void X()
200
+ }
201
+ ]
202
+ }),
203
+ /* @__PURE__ */ E(i, {
204
+ className: "mb-6",
205
+ children: [/* @__PURE__ */ E(s, { children: [/* @__PURE__ */ E("div", {
206
+ className: "flex items-center gap-2",
207
+ children: [/* @__PURE__ */ T(v, { className: "h-5 w-5 text-text-secondary" }), /* @__PURE__ */ T(c, {
208
+ className: "text-lg",
209
+ children: "Sandbox Stats"
210
+ })]
211
+ }), /* @__PURE__ */ T(o, { children: "Current sandbox usage across the platform" })] }), /* @__PURE__ */ T(a, { children: /* @__PURE__ */ E(p, { children: [
212
+ /* @__PURE__ */ T(f, {
213
+ title: "Active Sandboxes",
214
+ hero: !0,
215
+ value: j.totalActive,
216
+ trend: "up"
217
+ }),
218
+ /* @__PURE__ */ T(f, {
219
+ title: "Queued",
220
+ value: j.totalQueued
221
+ }),
222
+ /* @__PURE__ */ T(f, {
223
+ title: "Completed (all time)",
224
+ value: j.totalCompleted
225
+ }),
226
+ /* @__PURE__ */ T(f, {
227
+ title: "Failed (all time)",
228
+ value: j.totalFailed,
229
+ trend: "down"
230
+ })
231
+ ] }) })]
232
+ }),
233
+ /* @__PURE__ */ E("div", {
234
+ className: "grid gap-6 lg:grid-cols-3",
235
+ children: [/* @__PURE__ */ E("div", {
236
+ className: "space-y-6 lg:col-span-2",
237
+ children: [
238
+ /* @__PURE__ */ E(i, {
239
+ id: "ttl",
240
+ children: [/* @__PURE__ */ E(s, { children: [/* @__PURE__ */ E("div", {
241
+ className: "flex items-center gap-2",
242
+ children: [/* @__PURE__ */ T(C, { className: "h-5 w-5 text-text-secondary" }), /* @__PURE__ */ T(c, {
243
+ className: "text-lg",
244
+ children: "Time-to-Live (TTL)"
245
+ })]
246
+ }), /* @__PURE__ */ T(o, { children: "Control how long sandboxes stay alive before automatic cleanup" })] }), /* @__PURE__ */ T(a, {
247
+ className: "space-y-4",
248
+ children: /* @__PURE__ */ E("div", {
249
+ className: "grid gap-4 sm:grid-cols-2",
250
+ children: [/* @__PURE__ */ E("div", {
251
+ className: "space-y-2",
252
+ children: [
253
+ /* @__PURE__ */ T("label", {
254
+ className: "text-sm font-medium",
255
+ children: "Default TTL"
256
+ }),
257
+ /* @__PURE__ */ T("select", {
258
+ className: Z,
259
+ value: H.defaultTtl,
260
+ onChange: (e) => J("defaultTtl", Number(e.target.value)),
261
+ children: A.map((e) => /* @__PURE__ */ T("option", {
262
+ value: e.value,
263
+ children: e.label
264
+ }, e.value))
265
+ }),
266
+ /* @__PURE__ */ T("p", {
267
+ className: "text-xs text-text-secondary",
268
+ children: "Default lifetime for new sandboxes"
269
+ })
270
+ ]
271
+ }), /* @__PURE__ */ E("div", {
272
+ className: "space-y-2",
273
+ children: [
274
+ /* @__PURE__ */ T("label", {
275
+ className: "text-sm font-medium",
276
+ children: "Max TTL"
277
+ }),
278
+ /* @__PURE__ */ T("select", {
279
+ className: Z,
280
+ value: H.maxTtl,
281
+ onChange: (e) => J("maxTtl", Number(e.target.value)),
282
+ children: A.map((e) => /* @__PURE__ */ T("option", {
283
+ value: e.value,
284
+ children: e.label
285
+ }, e.value))
286
+ }),
287
+ /* @__PURE__ */ T("p", {
288
+ className: "text-xs text-text-secondary",
289
+ children: "Maximum allowed TTL (must be >= default)"
290
+ })
291
+ ]
292
+ })]
293
+ })
294
+ })]
295
+ }),
296
+ /* @__PURE__ */ E(i, { children: [/* @__PURE__ */ E(s, { children: [/* @__PURE__ */ E("div", {
297
+ className: "flex items-center gap-2",
298
+ children: [/* @__PURE__ */ T(y, { className: "h-5 w-5 text-text-secondary" }), /* @__PURE__ */ T(c, {
299
+ className: "text-lg",
300
+ children: "Allowed Sandbox Types"
301
+ })]
302
+ }), /* @__PURE__ */ T(o, { children: "Select which sandbox types users are permitted to create" })] }), /* @__PURE__ */ T(a, { children: /* @__PURE__ */ T("div", {
303
+ className: "space-y-3",
304
+ children: k.map((e) => /* @__PURE__ */ E("label", {
305
+ className: "flex items-center gap-3 rounded-lg border border-border-subtle p-4 cursor-pointer hover:bg-bg-sunken/50 transition-colors",
306
+ children: [/* @__PURE__ */ T("input", {
307
+ type: "checkbox",
308
+ checked: H.allowedSandboxTypes.includes(e),
309
+ onChange: () => Y(e),
310
+ className: "h-4 w-4 rounded border-border-default text-primary focus:ring-primary"
311
+ }), /* @__PURE__ */ E("div", { children: [/* @__PURE__ */ T("div", {
312
+ className: "font-medium text-sm",
313
+ children: P(e)
314
+ }), /* @__PURE__ */ T("div", {
315
+ className: "text-xs text-text-secondary",
316
+ children: F(e)
317
+ })] })]
318
+ }, e))
319
+ }) })] }),
320
+ /* @__PURE__ */ E(i, {
321
+ id: "resources",
322
+ children: [/* @__PURE__ */ E(s, { children: [/* @__PURE__ */ E("div", {
323
+ className: "flex items-center gap-2",
324
+ children: [/* @__PURE__ */ T(b, { className: "h-5 w-5 text-text-secondary" }), /* @__PURE__ */ T(c, {
325
+ className: "text-lg",
326
+ children: "Default Resource Limits"
327
+ })]
328
+ }), /* @__PURE__ */ T(o, { children: "Kubernetes resource requests and limits applied to new sandboxes" })] }), /* @__PURE__ */ E(a, {
329
+ className: "space-y-4",
239
330
  children: [
240
- /* @__PURE__ */ T("label", {
241
- className: "text-sm font-medium",
242
- children: "Max TTL"
243
- }),
244
- /* @__PURE__ */ T("select", {
245
- className: Y,
246
- value: B.maxTtl,
247
- onChange: (e) => K("maxTtl", Number(e.target.value)),
248
- children: O.map((e) => /* @__PURE__ */ T("option", {
249
- value: e.value,
250
- children: e.label
251
- }, e.value))
331
+ /* @__PURE__ */ E("div", {
332
+ className: "grid gap-4 sm:grid-cols-2",
333
+ children: [/* @__PURE__ */ E("div", {
334
+ className: "space-y-2",
335
+ children: [
336
+ /* @__PURE__ */ T("label", {
337
+ className: "text-sm font-medium",
338
+ children: "CPU Request"
339
+ }),
340
+ /* @__PURE__ */ T(l, {
341
+ value: H.defaultCpuRequest,
342
+ onChange: (e) => J("defaultCpuRequest", e.target.value),
343
+ placeholder: "500m"
344
+ }),
345
+ /* @__PURE__ */ T("p", {
346
+ className: "text-xs text-text-secondary",
347
+ children: "Kubernetes CPU request (e.g. 500m, 1)"
348
+ })
349
+ ]
350
+ }), /* @__PURE__ */ E("div", {
351
+ className: "space-y-2",
352
+ children: [
353
+ /* @__PURE__ */ T("label", {
354
+ className: "text-sm font-medium",
355
+ children: "CPU Limit"
356
+ }),
357
+ /* @__PURE__ */ T(l, {
358
+ value: H.defaultCpuLimit,
359
+ onChange: (e) => J("defaultCpuLimit", e.target.value),
360
+ placeholder: "2"
361
+ }),
362
+ /* @__PURE__ */ T("p", {
363
+ className: "text-xs text-text-secondary",
364
+ children: "Kubernetes CPU limit (e.g. 1, 2, 4)"
365
+ })
366
+ ]
367
+ })]
252
368
  }),
253
- /* @__PURE__ */ T("p", {
254
- className: "text-xs text-text-secondary",
255
- children: "Maximum allowed TTL (must be >= default)"
369
+ /* @__PURE__ */ T(u, {}),
370
+ /* @__PURE__ */ E("div", {
371
+ className: "grid gap-4 sm:grid-cols-2",
372
+ children: [/* @__PURE__ */ E("div", {
373
+ className: "space-y-2",
374
+ children: [
375
+ /* @__PURE__ */ T("label", {
376
+ className: "text-sm font-medium",
377
+ children: "Memory Request"
378
+ }),
379
+ /* @__PURE__ */ T(l, {
380
+ value: H.defaultMemoryRequest,
381
+ onChange: (e) => J("defaultMemoryRequest", e.target.value),
382
+ placeholder: "512Mi"
383
+ }),
384
+ /* @__PURE__ */ T("p", {
385
+ className: "text-xs text-text-secondary",
386
+ children: "Kubernetes memory request (e.g. 512Mi, 1Gi)"
387
+ })
388
+ ]
389
+ }), /* @__PURE__ */ E("div", {
390
+ className: "space-y-2",
391
+ children: [
392
+ /* @__PURE__ */ T("label", {
393
+ className: "text-sm font-medium",
394
+ children: "Memory Limit"
395
+ }),
396
+ /* @__PURE__ */ T(l, {
397
+ value: H.defaultMemoryLimit,
398
+ onChange: (e) => J("defaultMemoryLimit", e.target.value),
399
+ placeholder: "4Gi"
400
+ }),
401
+ /* @__PURE__ */ T("p", {
402
+ className: "text-xs text-text-secondary",
403
+ children: "Kubernetes memory limit (e.g. 2Gi, 4Gi, 8Gi)"
404
+ })
405
+ ]
406
+ })]
256
407
  })
257
408
  ]
258
409
  })]
259
410
  })
260
- })] }),
261
- /* @__PURE__ */ E(i, { children: [/* @__PURE__ */ E(s, { children: [/* @__PURE__ */ E("div", {
262
- className: "flex items-center gap-2",
263
- children: [/* @__PURE__ */ T(y, { className: "h-5 w-5 text-text-secondary" }), /* @__PURE__ */ T(c, {
264
- className: "text-lg",
265
- children: "Allowed Sandbox Types"
266
- })]
267
- }), /* @__PURE__ */ T(o, { children: "Select which sandbox types users are permitted to create" })] }), /* @__PURE__ */ T(a, { children: /* @__PURE__ */ T("div", {
268
- className: "space-y-3",
269
- children: D.map((e) => /* @__PURE__ */ E("label", {
270
- className: "flex items-center gap-3 rounded-lg border border-border-subtle p-4 cursor-pointer hover:bg-bg-sunken/50 transition-colors",
271
- children: [/* @__PURE__ */ T("input", {
272
- type: "checkbox",
273
- checked: B.allowedSandboxTypes.includes(e),
274
- onChange: () => q(e),
275
- className: "h-4 w-4 rounded border-border-default text-primary focus:ring-primary"
276
- }), /* @__PURE__ */ E("div", { children: [/* @__PURE__ */ T("div", {
277
- className: "font-medium text-sm",
278
- children: M(e)
279
- }), /* @__PURE__ */ T("div", {
280
- className: "text-xs text-text-secondary",
281
- children: N(e)
282
- })] })]
283
- }, e))
284
- }) })] }),
285
- /* @__PURE__ */ E(i, { children: [/* @__PURE__ */ E(s, { children: [/* @__PURE__ */ E("div", {
286
- className: "flex items-center gap-2",
287
- children: [/* @__PURE__ */ T(b, { className: "h-5 w-5 text-text-secondary" }), /* @__PURE__ */ T(c, {
288
- className: "text-lg",
289
- children: "Default Resource Limits"
290
- })]
291
- }), /* @__PURE__ */ T(o, { children: "Kubernetes resource requests and limits applied to new sandboxes" })] }), /* @__PURE__ */ E(a, {
292
- className: "space-y-4",
293
- children: [
294
- /* @__PURE__ */ E("div", {
295
- className: "grid gap-4 sm:grid-cols-2",
296
- children: [/* @__PURE__ */ E("div", {
297
- className: "space-y-2",
298
- children: [
299
- /* @__PURE__ */ T("label", {
300
- className: "text-sm font-medium",
301
- children: "CPU Request"
302
- }),
303
- /* @__PURE__ */ T(l, {
304
- value: B.defaultCpuRequest,
305
- onChange: (e) => K("defaultCpuRequest", e.target.value),
306
- placeholder: "500m"
307
- }),
308
- /* @__PURE__ */ T("p", {
309
- className: "text-xs text-text-secondary",
310
- children: "Kubernetes CPU request (e.g. 500m, 1)"
311
- })
312
- ]
313
- }), /* @__PURE__ */ E("div", {
314
- className: "space-y-2",
315
- children: [
316
- /* @__PURE__ */ T("label", {
317
- className: "text-sm font-medium",
318
- children: "CPU Limit"
319
- }),
320
- /* @__PURE__ */ T(l, {
321
- value: B.defaultCpuLimit,
322
- onChange: (e) => K("defaultCpuLimit", e.target.value),
323
- placeholder: "2"
324
- }),
325
- /* @__PURE__ */ T("p", {
326
- className: "text-xs text-text-secondary",
327
- children: "Kubernetes CPU limit (e.g. 1, 2, 4)"
328
- })
329
- ]
330
- })]
331
- }),
332
- /* @__PURE__ */ T(u, {}),
333
- /* @__PURE__ */ E("div", {
334
- className: "grid gap-4 sm:grid-cols-2",
335
- children: [/* @__PURE__ */ E("div", {
411
+ ]
412
+ }), /* @__PURE__ */ E("div", {
413
+ className: "space-y-6",
414
+ children: [
415
+ /* @__PURE__ */ E(i, { children: [/* @__PURE__ */ T(s, { children: /* @__PURE__ */ E("div", {
416
+ className: "flex items-center gap-2",
417
+ children: [/* @__PURE__ */ T(w, { className: "h-5 w-5 text-text-secondary" }), /* @__PURE__ */ T(c, {
418
+ className: "text-lg",
419
+ children: "Concurrency"
420
+ })]
421
+ }) }), /* @__PURE__ */ E(a, {
422
+ className: "space-y-4",
423
+ children: [
424
+ /* @__PURE__ */ E("div", {
336
425
  className: "space-y-2",
337
426
  children: [
338
427
  /* @__PURE__ */ T("label", {
339
428
  className: "text-sm font-medium",
340
- children: "Memory Request"
429
+ children: "Max Per User"
341
430
  }),
342
431
  /* @__PURE__ */ T(l, {
343
- value: B.defaultMemoryRequest,
344
- onChange: (e) => K("defaultMemoryRequest", e.target.value),
345
- placeholder: "512Mi"
432
+ type: "number",
433
+ min: 1,
434
+ max: 50,
435
+ value: H.maxConcurrentPerUser,
436
+ onChange: (e) => J("maxConcurrentPerUser", Number(e.target.value))
346
437
  }),
347
438
  /* @__PURE__ */ T("p", {
348
439
  className: "text-xs text-text-secondary",
349
- children: "Kubernetes memory request (e.g. 512Mi, 1Gi)"
440
+ children: "Maximum concurrent sandboxes per user"
350
441
  })
351
442
  ]
352
- }), /* @__PURE__ */ E("div", {
443
+ }),
444
+ /* @__PURE__ */ T(u, {}),
445
+ /* @__PURE__ */ E("div", {
353
446
  className: "space-y-2",
354
447
  children: [
355
448
  /* @__PURE__ */ T("label", {
356
449
  className: "text-sm font-medium",
357
- children: "Memory Limit"
450
+ children: "Max Per Workspace"
358
451
  }),
359
452
  /* @__PURE__ */ T(l, {
360
- value: B.defaultMemoryLimit,
361
- onChange: (e) => K("defaultMemoryLimit", e.target.value),
362
- placeholder: "4Gi"
453
+ type: "number",
454
+ min: 1,
455
+ max: 200,
456
+ value: H.maxConcurrentPerWorkspace,
457
+ onChange: (e) => J("maxConcurrentPerWorkspace", Number(e.target.value))
363
458
  }),
364
459
  /* @__PURE__ */ T("p", {
365
460
  className: "text-xs text-text-secondary",
366
- children: "Kubernetes memory limit (e.g. 2Gi, 4Gi, 8Gi)"
461
+ children: "Maximum concurrent sandboxes per workspace"
367
462
  })
368
463
  ]
369
- })]
370
- })
371
- ]
372
- })] })
373
- ]
374
- }), /* @__PURE__ */ E("div", {
375
- className: "space-y-6",
376
- children: [
377
- /* @__PURE__ */ E(i, { children: [/* @__PURE__ */ T(s, { children: /* @__PURE__ */ E("div", {
378
- className: "flex items-center gap-2",
379
- children: [/* @__PURE__ */ T(w, { className: "h-5 w-5 text-text-secondary" }), /* @__PURE__ */ T(c, {
380
- className: "text-lg",
381
- children: "Concurrency"
382
- })]
383
- }) }), /* @__PURE__ */ E(a, {
384
- className: "space-y-4",
385
- children: [
386
- /* @__PURE__ */ E("div", {
387
- className: "space-y-2",
388
- children: [
389
- /* @__PURE__ */ T("label", {
390
- className: "text-sm font-medium",
391
- children: "Max Per User"
392
- }),
393
- /* @__PURE__ */ T(l, {
394
- type: "number",
395
- min: 1,
396
- max: 50,
397
- value: B.maxConcurrentPerUser,
398
- onChange: (e) => K("maxConcurrentPerUser", Number(e.target.value))
399
- }),
400
- /* @__PURE__ */ T("p", {
401
- className: "text-xs text-text-secondary",
402
- children: "Maximum concurrent sandboxes per user"
403
- })
404
- ]
405
- }),
406
- /* @__PURE__ */ T(u, {}),
407
- /* @__PURE__ */ E("div", {
408
- className: "space-y-2",
409
- children: [
410
- /* @__PURE__ */ T("label", {
411
- className: "text-sm font-medium",
412
- children: "Max Per Workspace"
413
- }),
414
- /* @__PURE__ */ T(l, {
415
- type: "number",
416
- min: 1,
417
- max: 200,
418
- value: B.maxConcurrentPerWorkspace,
419
- onChange: (e) => K("maxConcurrentPerWorkspace", Number(e.target.value))
420
- }),
421
- /* @__PURE__ */ T("p", {
422
- className: "text-xs text-text-secondary",
423
- children: "Maximum concurrent sandboxes per workspace"
424
- })
425
- ]
426
- })
427
- ]
428
- })] }),
429
- /* @__PURE__ */ E(i, { children: [/* @__PURE__ */ T(s, { children: /* @__PURE__ */ E("div", {
430
- className: "flex items-center gap-2",
431
- children: [/* @__PURE__ */ T(x, { className: "h-5 w-5 text-text-secondary" }), /* @__PURE__ */ T(c, {
432
- className: "text-lg",
433
- children: "Resource Info"
434
- })]
435
- }) }), /* @__PURE__ */ E(a, {
436
- className: "space-y-3",
437
- children: [
438
- /* @__PURE__ */ T("p", {
439
- className: "text-sm text-text-secondary",
440
- children: "Resource defaults are applied to all new sandboxes. Individual sandboxes can override these within the max limits defined by the sandbox type."
441
- }),
442
- /* @__PURE__ */ T(u, {}),
443
- /* @__PURE__ */ E("div", {
444
- className: "space-y-2 text-xs text-text-secondary",
445
- children: [/* @__PURE__ */ E("div", {
446
- className: "flex justify-between",
447
- children: [/* @__PURE__ */ T("span", { children: "CPU units" }), /* @__PURE__ */ T("span", {
448
- className: "font-mono",
449
- children: "millicores (m)"
450
- })]
451
- }), /* @__PURE__ */ E("div", {
452
- className: "flex justify-between",
453
- children: [/* @__PURE__ */ T("span", { children: "Memory units" }), /* @__PURE__ */ T("span", {
454
- className: "font-mono",
455
- children: "Mi / Gi"
464
+ })
465
+ ]
466
+ })] }),
467
+ /* @__PURE__ */ E(i, { children: [/* @__PURE__ */ T(s, { children: /* @__PURE__ */ E("div", {
468
+ className: "flex items-center gap-2",
469
+ children: [/* @__PURE__ */ T(x, { className: "h-5 w-5 text-text-secondary" }), /* @__PURE__ */ T(c, {
470
+ className: "text-lg",
471
+ children: "Resource Info"
472
+ })]
473
+ }) }), /* @__PURE__ */ E(a, {
474
+ className: "space-y-3",
475
+ children: [
476
+ /* @__PURE__ */ T("p", {
477
+ className: "text-sm text-text-secondary",
478
+ children: "Resource defaults are applied to all new sandboxes. Individual sandboxes can override these within the max limits defined by the sandbox type."
479
+ }),
480
+ /* @__PURE__ */ T(u, {}),
481
+ /* @__PURE__ */ E("div", {
482
+ className: "space-y-2 text-xs text-text-secondary",
483
+ children: [/* @__PURE__ */ E("div", {
484
+ className: "flex justify-between",
485
+ children: [/* @__PURE__ */ T("span", { children: "CPU units" }), /* @__PURE__ */ T("span", {
486
+ className: "font-mono",
487
+ children: "millicores (m)"
488
+ })]
489
+ }), /* @__PURE__ */ E("div", {
490
+ className: "flex justify-between",
491
+ children: [/* @__PURE__ */ T("span", { children: "Memory units" }), /* @__PURE__ */ T("span", {
492
+ className: "font-mono",
493
+ children: "Mi / Gi"
494
+ })]
456
495
  })]
457
- })]
496
+ })
497
+ ]
498
+ })] }),
499
+ /* @__PURE__ */ T(i, { children: /* @__PURE__ */ T(a, {
500
+ className: "p-6",
501
+ children: /* @__PURE__ */ E(r, {
502
+ className: "w-full",
503
+ onClick: X,
504
+ disabled: W || K,
505
+ children: [/* @__PURE__ */ T(S, { className: "mr-2 h-4 w-4" }), W ? "Saving..." : K ? "Loading..." : "Save Configuration"]
458
506
  })
459
- ]
460
- })] }),
461
- /* @__PURE__ */ T(i, { children: /* @__PURE__ */ T(a, {
462
- className: "p-6",
463
- children: /* @__PURE__ */ E(r, {
464
- className: "w-full",
465
- onClick: J,
466
- disabled: H || W,
467
- children: [/* @__PURE__ */ T(S, { className: "mr-2 h-4 w-4" }), H ? "Saving..." : W ? "Loading..." : "Save Configuration"]
468
- })
469
- }) })
470
- ]
471
- })]
472
- })]
507
+ }) })
508
+ ]
509
+ })]
510
+ })
511
+ ]
473
512
  })
474
513
  });
475
514
  }
476
- function M(e) {
515
+ function P(e) {
477
516
  return {
478
517
  VIBECONTROLS: "VibeControls",
479
518
  AI_BUILDER: "AI Builder",
@@ -482,7 +521,7 @@ function M(e) {
482
521
  CUSTOM: "Custom"
483
522
  }[e];
484
523
  }
485
- function N(e) {
524
+ function F(e) {
486
525
  return {
487
526
  VIBECONTROLS: "Full VibeControls development environment with pre-configured tooling",
488
527
  AI_BUILDER: "AI agent development sandbox with OpenCode SDK and model access",
@@ -492,6 +531,6 @@ function N(e) {
492
531
  }[e];
493
532
  }
494
533
  //#endregion
495
- export { j as SandboxSettingsPage };
534
+ export { N as SandboxSettingsPage };
496
535
 
497
536
  //# sourceMappingURL=SandboxSettingsPage.js.map