@truefoundry/trueforge-ui 0.3.0-rc.2 → 0.3.0-rc.4

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 (107) hide show
  1. package/CHANGELOG.md +63 -0
  2. package/README.md +18 -10
  3. package/dist/{AgentCodeSnippets-637HQUXD.js → AgentCodeSnippets-U6KQWVBJ.js} +38 -23
  4. package/dist/AgentCodeSnippets-U6KQWVBJ.js.map +1 -0
  5. package/dist/AgentMetricChart-3D6FUFO6.js +15 -0
  6. package/dist/{AgentOverview-3FJ5EE6N.js → AgentOverview-RLJ6HZCN.js} +7 -7
  7. package/dist/{AgentSessionEventTimeline-VELWUYPR.js → AgentSessionEventTimeline-CDXRRUZQ.js} +8 -8
  8. package/dist/{AgentSessionEventTimeline-VELWUYPR.js.map → AgentSessionEventTimeline-CDXRRUZQ.js.map} +1 -1
  9. package/dist/{AgentSessionEventTimelineChart-CUKETHWM.js → AgentSessionEventTimelineChart-S2WX6ZEA.js} +12 -12
  10. package/dist/AgentSessionEventTimelineChart-S2WX6ZEA.js.map +1 -0
  11. package/dist/{AgentSessions-T7MOGOTZ.js → AgentSessions-UI3L7XY2.js} +72 -24
  12. package/dist/AgentSessions-UI3L7XY2.js.map +1 -0
  13. package/dist/{ConnectorSettings-ESZ2RSRG.js → ConnectorSettings-OIGAC2HU.js} +156 -116
  14. package/dist/ConnectorSettings-OIGAC2HU.js.map +1 -0
  15. package/dist/{DockLayout-NLFNU6F2.js → DockLayout-J5BRKMJZ.js} +10 -10
  16. package/dist/{DrawerLayout-PR3SMKA6.js → DrawerLayout-65YHGHIF.js} +13 -11
  17. package/dist/DrawerLayout-65YHGHIF.js.map +1 -0
  18. package/dist/{ModelSettings-LYW64IRR.js → ModelSettings-VP6WCMGT.js} +10 -10
  19. package/dist/{ModelSettings-LYW64IRR.js.map → ModelSettings-VP6WCMGT.js.map} +1 -1
  20. package/dist/OpenUiFenceBlock-UTDCTNTM.js +9 -0
  21. package/dist/{SandboxSettings-DF64LHYI.js → SandboxSettings-GTZT7LD6.js} +9 -9
  22. package/dist/SchedulesPage-ARWU7BZF.js +15 -0
  23. package/dist/{SettingsBuilder-LSXK2VN4.js → SettingsBuilder-A4BPYIFZ.js} +8 -8
  24. package/dist/{ShellRouteSync-B22IAV2W.js → ShellRouteSync-SSLGM35F.js} +157 -22
  25. package/dist/ShellRouteSync-SSLGM35F.js.map +1 -0
  26. package/dist/{SidebarLayout-XW6LXB7R.js → SidebarLayout-MFDOGAVJ.js} +74 -53
  27. package/dist/SidebarLayout-MFDOGAVJ.js.map +1 -0
  28. package/dist/{SkillSettings-64VXUO6J.js → SkillSettings-WQPUQ5TE.js} +18 -13
  29. package/dist/SkillSettings-WQPUQ5TE.js.map +1 -0
  30. package/dist/{TrueForgeUIWithRouter-3TSLV22Q.js → TrueForgeUIWithRouter-5CDICMCE.js} +9 -9
  31. package/dist/{WidgetLayout-Q5P7PYSJ.js → WidgetLayout-HE7E4UL5.js} +10 -10
  32. package/dist/{chunk-SQGT43Z3.js → chunk-2BDTG544.js} +21 -4
  33. package/dist/chunk-2BDTG544.js.map +1 -0
  34. package/dist/{chunk-YQO2NMJ3.js → chunk-2OKGEU6X.js} +4425 -2982
  35. package/dist/chunk-2OKGEU6X.js.map +1 -0
  36. package/dist/{chunk-FQK2XVVE.js → chunk-6CFZHEYH.js} +225 -72
  37. package/dist/chunk-6CFZHEYH.js.map +1 -0
  38. package/dist/{chunk-QC42MLAK.js → chunk-7AAO4UDQ.js} +4 -3
  39. package/dist/chunk-7AAO4UDQ.js.map +1 -0
  40. package/dist/chunk-E4GVP6PM.js +195 -0
  41. package/dist/chunk-E4GVP6PM.js.map +1 -0
  42. package/dist/{chunk-LGRHHFHN.js → chunk-F7ZAQIRE.js} +166 -45
  43. package/dist/chunk-F7ZAQIRE.js.map +1 -0
  44. package/dist/{chunk-VJ7BZGAF.js → chunk-GTTMLDCI.js} +2 -2
  45. package/dist/{chunk-5I2COQNL.js → chunk-IOPHQEUY.js} +13 -11
  46. package/dist/chunk-IOPHQEUY.js.map +1 -0
  47. package/dist/{chunk-G2TUAD65.js → chunk-KCYBMKQL.js} +235 -108
  48. package/dist/chunk-KCYBMKQL.js.map +1 -0
  49. package/dist/{chunk-H6WTY5PM.js → chunk-MAA7U4RF.js} +17 -227
  50. package/dist/chunk-MAA7U4RF.js.map +1 -0
  51. package/dist/{chunk-GXYAOAK5.js → chunk-MJULWIPI.js} +224 -162
  52. package/dist/chunk-MJULWIPI.js.map +1 -0
  53. package/dist/chunk-P7J2ABEP.js +587 -0
  54. package/dist/chunk-P7J2ABEP.js.map +1 -0
  55. package/dist/{chunk-VUMGMGKZ.js → chunk-TGKQRK3S.js} +52 -8
  56. package/dist/chunk-TGKQRK3S.js.map +1 -0
  57. package/dist/{chunk-I3AL54MA.js → chunk-VXKNS7FH.js} +28 -24
  58. package/dist/chunk-VXKNS7FH.js.map +1 -0
  59. package/dist/chunk-XO3FYN2W.js +517 -0
  60. package/dist/chunk-XO3FYN2W.js.map +1 -0
  61. package/dist/{createTrueFoundryServer-CmZnBh_l.d.ts → createTrueFoundryServer-B_FYhSdn.d.ts} +8 -5
  62. package/dist/index.d.ts +300 -89
  63. package/dist/index.js +65 -488
  64. package/dist/index.js.map +1 -1
  65. package/dist/plugins/trueforge-agent-server-adapter/index.d.ts +44 -13
  66. package/dist/plugins/trueforge-agent-server-adapter/index.js +73 -37
  67. package/dist/plugins/trueforge-agent-server-adapter/index.js.map +1 -1
  68. package/dist/styles.css +1 -1
  69. package/package.json +3 -3
  70. package/dist/AgentCodeSnippets-637HQUXD.js.map +0 -1
  71. package/dist/AgentMetricChart-4FYECRIN.js +0 -15
  72. package/dist/AgentSessionEventTimelineChart-CUKETHWM.js.map +0 -1
  73. package/dist/AgentSessions-T7MOGOTZ.js.map +0 -1
  74. package/dist/ConnectorSettings-ESZ2RSRG.js.map +0 -1
  75. package/dist/DrawerLayout-PR3SMKA6.js.map +0 -1
  76. package/dist/OpenUiFenceBlock-JEPNPJ7U.js +0 -9
  77. package/dist/SchedulesPage-WQU4H25F.js +0 -15
  78. package/dist/ShellRouteSync-B22IAV2W.js.map +0 -1
  79. package/dist/SidebarLayout-XW6LXB7R.js.map +0 -1
  80. package/dist/SkillSettings-64VXUO6J.js.map +0 -1
  81. package/dist/chunk-5I2COQNL.js.map +0 -1
  82. package/dist/chunk-BWHOZFIV.js +0 -587
  83. package/dist/chunk-BWHOZFIV.js.map +0 -1
  84. package/dist/chunk-FQK2XVVE.js.map +0 -1
  85. package/dist/chunk-G2TUAD65.js.map +0 -1
  86. package/dist/chunk-GXYAOAK5.js.map +0 -1
  87. package/dist/chunk-H6WTY5PM.js.map +0 -1
  88. package/dist/chunk-I3AL54MA.js.map +0 -1
  89. package/dist/chunk-LGRHHFHN.js.map +0 -1
  90. package/dist/chunk-NHHSZB5N.js +0 -74
  91. package/dist/chunk-NHHSZB5N.js.map +0 -1
  92. package/dist/chunk-QC42MLAK.js.map +0 -1
  93. package/dist/chunk-SFZNIO6U.js +0 -18
  94. package/dist/chunk-SFZNIO6U.js.map +0 -1
  95. package/dist/chunk-SQGT43Z3.js.map +0 -1
  96. package/dist/chunk-VUMGMGKZ.js.map +0 -1
  97. package/dist/chunk-YQO2NMJ3.js.map +0 -1
  98. /package/dist/{AgentMetricChart-4FYECRIN.js.map → AgentMetricChart-3D6FUFO6.js.map} +0 -0
  99. /package/dist/{AgentOverview-3FJ5EE6N.js.map → AgentOverview-RLJ6HZCN.js.map} +0 -0
  100. /package/dist/{DockLayout-NLFNU6F2.js.map → DockLayout-J5BRKMJZ.js.map} +0 -0
  101. /package/dist/{OpenUiFenceBlock-JEPNPJ7U.js.map → OpenUiFenceBlock-UTDCTNTM.js.map} +0 -0
  102. /package/dist/{SandboxSettings-DF64LHYI.js.map → SandboxSettings-GTZT7LD6.js.map} +0 -0
  103. /package/dist/{SchedulesPage-WQU4H25F.js.map → SchedulesPage-ARWU7BZF.js.map} +0 -0
  104. /package/dist/{SettingsBuilder-LSXK2VN4.js.map → SettingsBuilder-A4BPYIFZ.js.map} +0 -0
  105. /package/dist/{TrueForgeUIWithRouter-3TSLV22Q.js.map → TrueForgeUIWithRouter-5CDICMCE.js.map} +0 -0
  106. /package/dist/{WidgetLayout-Q5P7PYSJ.js.map → WidgetLayout-HE7E4UL5.js.map} +0 -0
  107. /package/dist/{chunk-VJ7BZGAF.js.map → chunk-GTTMLDCI.js.map} +0 -0
@@ -1,6 +1,7 @@
1
1
  import {
2
2
  Button,
3
3
  ConnectorConnectButton,
4
+ CreatedByCell,
4
5
  DEFAULT_TABLE_PAGE_SIZE,
5
6
  Dialog,
6
7
  DialogContent,
@@ -23,30 +24,34 @@ import {
23
24
  TableTokenPagination,
24
25
  Tooltip,
25
26
  auiInputClass,
27
+ hasCreatedBySubject,
26
28
  mountName,
27
- searchAllAgents,
29
+ useResourcePermissions,
30
+ useSlot,
28
31
  useToasterOptional
29
- } from "./chunk-YQO2NMJ3.js";
32
+ } from "./chunk-2OKGEU6X.js";
30
33
  import {
31
34
  readScheduleShareSearch,
32
- replaceScheduleShareSearch
33
- } from "./chunk-NHHSZB5N.js";
35
+ replaceScheduleShareSearch,
36
+ searchAllAgents
37
+ } from "./chunk-E4GVP6PM.js";
34
38
  import {
35
39
  DraftCatalogProvider,
36
40
  Icon,
37
41
  PageHeader,
38
42
  auiButtonClass,
39
43
  useDraftCatalog
40
- } from "./chunk-H6WTY5PM.js";
44
+ } from "./chunk-MAA7U4RF.js";
41
45
  import {
42
46
  libraryAgentId,
43
47
  useOptionalCatalogServer,
48
+ useOptionalShellMode,
44
49
  useScheduleServer,
45
50
  useServer
46
- } from "./chunk-FQK2XVVE.js";
51
+ } from "./chunk-6CFZHEYH.js";
47
52
  import {
48
53
  cn
49
- } from "./chunk-BWHOZFIV.js";
54
+ } from "./chunk-P7J2ABEP.js";
50
55
 
51
56
  // src/atoms/schedules/SchedulesPage.tsx
52
57
  import { useCallback, useEffect as useEffect3, useMemo as useMemo2, useRef, useState as useState3 } from "react";
@@ -278,7 +283,9 @@ function ScheduleFormFields({
278
283
  agentId,
279
284
  onAgentIdChange,
280
285
  agentOptions,
281
- agentPickerDisabled = false
286
+ agentOptionsLoaded = true,
287
+ agentPickerDisabled = false,
288
+ onBuildAgent
282
289
  }) {
283
290
  const cron = valuesToCron(values);
284
291
  const cadence = formatCadenceSummary({ cron, timezone: values.timezone });
@@ -302,7 +309,12 @@ function ScheduleFormFields({
302
309
  value: agentId,
303
310
  options: agentOptions.map((agent) => ({ value: agent.agentId, label: agent.name })),
304
311
  onValueChange: (value) => onAgentIdChange?.(value),
305
- disabled: agentPickerDisabled || onAgentIdChange == null
312
+ disabled: agentPickerDisabled || onAgentIdChange == null,
313
+ emptyContent: agentOptionsLoaded ? /* @__PURE__ */ jsx("p", { className: "text-text-secondary px-3 py-5 text-center text-sm", children: "No Agents created yet" }) : null,
314
+ footer: agentOptionsLoaded && agentOptions.length === 0 && onBuildAgent != null ? /* @__PURE__ */ jsx("div", { className: "flex justify-end border-t border-border px-2 pt-2", children: /* @__PURE__ */ jsxs(Button.Ghost, { type: "button", onClick: onBuildAgent, children: [
315
+ /* @__PURE__ */ jsx(Icon, { name: "plus", className: "size-3.5" }),
316
+ "Build Agent"
317
+ ] }) }) : null
306
318
  }
307
319
  )
308
320
  ] }),
@@ -334,107 +346,96 @@ function ScheduleFormFields({
334
346
  )
335
347
  ] }),
336
348
  /* @__PURE__ */ jsxs("fieldset", { children: [
337
- /* @__PURE__ */ jsx("legend", { className: "mb-1.5 text-sm font-medium", children: "Recurrence" }),
338
- /* @__PURE__ */ jsx("div", { className: "grid grid-cols-3 gap-1 rounded-lg border border-border p-1", children: RECURRENCE_OPTIONS.map((opt) => {
339
- const selected = values.recurrence === opt.value;
340
- return /* @__PURE__ */ jsx(
341
- "button",
342
- {
343
- type: "button",
344
- className: cn(
345
- "rounded-md px-2 py-1.5 text-xs font-medium transition-colors",
346
- selected ? "border border-primary-button-bg/40 bg-primary-button-bg/10 text-primary-button-bg" : "text-text-secondary hover:bg-ghost-button-hover border border-transparent"
347
- ),
348
- "aria-pressed": selected,
349
- onClick: () => set("recurrence", opt.value),
350
- children: opt.label
351
- },
352
- opt.value
353
- );
354
- }) })
355
- ] }),
356
- values.recurrence === "hourly" ? /* @__PURE__ */ jsxs("div", { className: "block max-w-[8rem]", children: [
357
- /* @__PURE__ */ jsx("span", { className: "mb-1.5 block text-sm font-medium", children: "Minute" }),
358
- /* @__PURE__ */ jsx(
359
- PopoverSelect,
360
- {
361
- "aria-label": "Minute",
362
- value: String(values.minute),
363
- options: MINUTE_OPTIONS,
364
- onValueChange: (value) => set("minute", Number(value))
365
- }
366
- )
367
- ] }) : null,
368
- values.recurrence === "daily" || values.recurrence === "weekly" ? /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap gap-3", children: [
369
- /* @__PURE__ */ jsxs("div", { className: "block min-w-[7rem] flex-1", children: [
370
- /* @__PURE__ */ jsx("span", { className: "mb-1.5 block text-sm font-medium", children: "Hour" }),
371
- /* @__PURE__ */ jsx(
372
- PopoverSelect,
373
- {
374
- "aria-label": "Hour",
375
- value: String(values.hour),
376
- options: HOUR_OPTIONS,
377
- onValueChange: (value) => set("hour", Number(value))
378
- }
379
- )
380
- ] }),
381
- /* @__PURE__ */ jsxs("div", { className: "block min-w-[7rem] flex-1", children: [
382
- /* @__PURE__ */ jsx("span", { className: "mb-1.5 block text-sm font-medium", children: "Minute" }),
383
- /* @__PURE__ */ jsx(
384
- PopoverSelect,
385
- {
386
- "aria-label": "Minute",
387
- value: String(values.minute),
388
- options: MINUTE_OPTIONS,
389
- onValueChange: (value) => set("minute", Number(value))
390
- }
391
- )
392
- ] })
393
- ] }) : null,
394
- values.recurrence === "weekly" ? /* @__PURE__ */ jsxs("fieldset", { children: [
395
- /* @__PURE__ */ jsx("legend", { className: "mb-1.5 text-sm font-medium", children: "Days" }),
396
- /* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-1.5", children: WEEKDAY_OPTIONS.map((day) => {
397
- const selected = values.weekdays.includes(day.value);
398
- return /* @__PURE__ */ jsx(
399
- "button",
400
- {
401
- type: "button",
402
- className: cn(
403
- "rounded-md border px-2.5 py-1 text-xs font-medium",
404
- selected ? "border-primary-button-bg/40 bg-primary-button-bg/10 text-primary-button-bg" : "border-border text-text-secondary hover:bg-ghost-button-hover"
405
- ),
406
- "aria-pressed": selected,
407
- onClick: () => toggleWeekday(day.value),
408
- children: day.label
409
- },
410
- day.value
411
- );
412
- }) })
413
- ] }) : null,
414
- values.recurrence === "custom" ? /* @__PURE__ */ jsxs("div", { className: "rounded-md border border-border bg-secondary-bg/40 px-3 py-2", children: [
415
- /* @__PURE__ */ jsx("span", { className: "text-text-secondary block text-xs", children: "Existing custom schedule" }),
416
- /* @__PURE__ */ jsx("code", { className: "text-text-primary mt-1 block font-mono text-sm", children: values.customCron }),
417
- /* @__PURE__ */ jsx("span", { className: "text-text-secondary mt-1 block text-xs", children: "Select Hourly, Daily, or Weekly to replace this schedule." })
418
- ] }) : null,
419
- /* @__PURE__ */ jsxs("div", { className: "block", children: [
420
- /* @__PURE__ */ jsx("span", { className: "mb-1.5 block text-sm font-medium", children: "Timezone" }),
421
- /* @__PURE__ */ jsx(
422
- PopoverSelect,
423
- {
424
- "aria-label": "Timezone",
425
- value: values.timezone,
426
- options: timezoneOptions,
427
- onValueChange: (value) => set("timezone", value),
428
- menuPlacement: "top"
429
- }
430
- )
431
- ] }),
432
- /* @__PURE__ */ jsxs("div", { className: "rounded-lg border border-border bg-secondary-bg/40 px-3 py-3", children: [
433
- /* @__PURE__ */ jsxs("div", { className: "flex items-start justify-between gap-3", children: [
434
- /* @__PURE__ */ jsx("span", { className: "text-text-secondary text-[10px] font-semibold tracking-wide uppercase", children: "Frequency" }),
435
- /* @__PURE__ */ jsx("code", { className: "text-text-secondary font-mono text-xs", children: cron || "\u2014" })
436
- ] }),
437
- /* @__PURE__ */ jsx("p", { className: "text-text-primary mt-1 text-sm font-semibold", children: cadence || "\u2014" })
349
+ /* @__PURE__ */ jsx("legend", { className: "mb-1.5 text-sm font-medium", children: "Frequency" }),
350
+ /* @__PURE__ */ jsx("div", { className: "rounded-t-lg border border-border p-4", children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-4", children: [
351
+ /* @__PURE__ */ jsx("div", { className: "grid grid-cols-3 gap-1 rounded-lg border border-border bg-primary-bg p-1", children: RECURRENCE_OPTIONS.map((opt) => {
352
+ const selected = values.recurrence === opt.value;
353
+ return /* @__PURE__ */ jsx(
354
+ "button",
355
+ {
356
+ type: "button",
357
+ className: cn(
358
+ "rounded-md border px-2 py-2 text-sm font-medium transition-colors",
359
+ selected ? "border-primary-button-bg/40 bg-primary-button-bg/10 font-semibold text-primary-button-bg" : "border-transparent text-text-secondary hover:bg-ghost-button-hover"
360
+ ),
361
+ "aria-pressed": selected,
362
+ onClick: () => set("recurrence", opt.value),
363
+ children: opt.label
364
+ },
365
+ opt.value
366
+ );
367
+ }) }),
368
+ values.recurrence === "custom" ? /* @__PURE__ */ jsxs("div", { className: "rounded-md border border-border bg-secondary-bg/40 px-3 py-2", children: [
369
+ /* @__PURE__ */ jsx("span", { className: "block text-xs text-text-secondary", children: "Existing custom schedule" }),
370
+ /* @__PURE__ */ jsx("code", { className: "mt-1 block font-mono text-sm text-text-primary", children: values.customCron }),
371
+ /* @__PURE__ */ jsx("span", { className: "mt-1 block text-xs text-text-secondary", children: "Select Hourly, Daily, or Weekly to replace this schedule." })
372
+ ] }) : null,
373
+ values.recurrence === "weekly" ? /* @__PURE__ */ jsxs("fieldset", { children: [
374
+ /* @__PURE__ */ jsx("legend", { className: "mb-2 text-sm font-medium", children: "Days" }),
375
+ /* @__PURE__ */ jsx("div", { className: "flex gap-2", children: WEEKDAY_OPTIONS.map((day) => {
376
+ const selected = values.weekdays.includes(day.value);
377
+ return /* @__PURE__ */ jsx(
378
+ "button",
379
+ {
380
+ type: "button",
381
+ className: cn(
382
+ "min-w-0 flex-1 rounded-md border px-3 py-2 text-[0.8125rem] font-medium",
383
+ selected ? "border-primary-button-bg/40 bg-primary-button-bg/10 font-semibold text-primary-button-bg" : "border-border text-text-secondary hover:bg-ghost-button-hover"
384
+ ),
385
+ "aria-pressed": selected,
386
+ onClick: () => toggleWeekday(day.value),
387
+ children: day.label
388
+ },
389
+ day.value
390
+ );
391
+ }) })
392
+ ] }) : null,
393
+ /* @__PURE__ */ jsxs("div", { className: "flex gap-4", children: [
394
+ values.recurrence === "daily" || values.recurrence === "weekly" ? /* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1", children: [
395
+ /* @__PURE__ */ jsx("span", { className: "mb-1.5 block text-sm font-medium", children: "Hour" }),
396
+ /* @__PURE__ */ jsx(
397
+ PopoverSelect,
398
+ {
399
+ "aria-label": "Hour",
400
+ value: String(values.hour),
401
+ options: HOUR_OPTIONS,
402
+ onValueChange: (value) => set("hour", Number(value))
403
+ }
404
+ )
405
+ ] }) : null,
406
+ values.recurrence !== "custom" ? /* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1", children: [
407
+ /* @__PURE__ */ jsx("span", { className: "mb-1.5 block text-sm font-medium", children: "Minute" }),
408
+ /* @__PURE__ */ jsx(
409
+ PopoverSelect,
410
+ {
411
+ "aria-label": "Minute",
412
+ value: String(values.minute),
413
+ options: MINUTE_OPTIONS,
414
+ onValueChange: (value) => set("minute", Number(value))
415
+ }
416
+ )
417
+ ] }) : null,
418
+ /* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1", children: [
419
+ /* @__PURE__ */ jsx("span", { className: "mb-1.5 block text-sm font-medium", children: "Timezone" }),
420
+ /* @__PURE__ */ jsx(
421
+ PopoverSelect,
422
+ {
423
+ "aria-label": "Timezone",
424
+ value: values.timezone,
425
+ options: timezoneOptions,
426
+ onValueChange: (value) => set("timezone", value),
427
+ menuClassName: "w-full min-w-0"
428
+ }
429
+ )
430
+ ] })
431
+ ] })
432
+ ] }) }),
433
+ /* @__PURE__ */ jsx("div", { className: "rounded-b-lg border border-t-0 border-border bg-primary-button-bg/10 px-4 py-3", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
434
+ /* @__PURE__ */ jsx(Icon, { name: "clock", className: "size-4 shrink-0 text-primary-button-bg" }),
435
+ /* @__PURE__ */ jsx("span", { className: "shrink-0 text-xs font-medium text-text-secondary", children: "Schedule" }),
436
+ /* @__PURE__ */ jsx("p", { className: "min-w-0 flex-1 truncate text-sm text-text-primary", children: cadence || "\u2014" }),
437
+ /* @__PURE__ */ jsx("code", { className: "shrink-0 whitespace-nowrap font-mono text-[0.8125rem] font-bold text-text-secondary", children: cron || "\u2014" })
438
+ ] }) })
438
439
  ] })
439
440
  ] });
440
441
  }
@@ -525,7 +526,7 @@ function ScheduleStatusBadge({ status }) {
525
526
  {
526
527
  className: cn(
527
528
  "inline-flex items-center gap-1.5 rounded-full border px-2.5 py-0.5 text-xs font-medium",
528
- active ? "border-emerald-600/30 bg-emerald-500/10 text-emerald-700 dark:border-emerald-400/35 dark:bg-emerald-500/15 dark:text-emerald-300" : "border-border bg-secondary-bg text-text-secondary"
529
+ active ? "border-emerald-600/30 bg-emerald-500/10 text-emerald-700 dark:border-emerald-400/35 dark:bg-emerald-500/15 dark:text-emerald-300" : "border-amber-600/30 bg-amber-500/10 text-amber-800 dark:border-amber-400/35 dark:bg-amber-500/15 dark:text-amber-300"
529
530
  ),
530
531
  children: [
531
532
  /* @__PURE__ */ jsx4(
@@ -533,7 +534,7 @@ function ScheduleStatusBadge({ status }) {
533
534
  {
534
535
  className: cn(
535
536
  "size-1.5 shrink-0 rounded-full",
536
- active ? "bg-emerald-600 dark:bg-emerald-400" : "bg-text-secondary"
537
+ active ? "bg-emerald-600 dark:bg-emerald-400" : "bg-amber-600 dark:bg-amber-400"
537
538
  ),
538
539
  "aria-hidden": true
539
540
  }
@@ -592,12 +593,12 @@ function TestScheduleScreen({ schedule, agentName, mcpMounts, onEditConfiguratio
592
593
  /* @__PURE__ */ jsxs4("section", { className: "overflow-hidden rounded-lg border border-border bg-card-bg", children: [
593
594
  /* @__PURE__ */ jsx5(DetailRow, { label: "Agent", children: agentName }),
594
595
  /* @__PURE__ */ jsx5(DetailRow, { label: "Name", children: schedule.name }),
596
+ /* @__PURE__ */ jsx5(DetailRow, { label: "Status", children: /* @__PURE__ */ jsx5(ScheduleStatusBadge, { status: schedule.status }) }),
595
597
  /* @__PURE__ */ jsx5(DetailRow, { label: "Task", children: /* @__PURE__ */ jsx5("span", { className: "whitespace-pre-wrap break-words", children: schedule.task }) }),
596
- /* @__PURE__ */ jsx5(DetailRow, { label: "Cadence", children: /* @__PURE__ */ jsxs4("div", { className: "flex flex-wrap items-center justify-end gap-1.5", children: [
598
+ /* @__PURE__ */ jsx5(DetailRow, { label: "Frequency", children: /* @__PURE__ */ jsxs4("div", { className: "flex flex-wrap items-center justify-end gap-1.5", children: [
597
599
  /* @__PURE__ */ jsx5("span", { children: cadence }),
598
600
  /* @__PURE__ */ jsx5("code", { className: "text-text-secondary font-mono text-xs", children: schedule.cron })
599
601
  ] }) }),
600
- /* @__PURE__ */ jsx5(DetailRow, { label: "Status", children: /* @__PURE__ */ jsx5(ScheduleStatusBadge, { status: schedule.status }) }),
601
602
  /* @__PURE__ */ jsx5("div", { className: "flex justify-end px-3 py-2.5", children: /* @__PURE__ */ jsxs4(Button.Secondary, { type: "button", size: "small", onClick: onEditConfiguration, children: [
602
603
  /* @__PURE__ */ jsx5(Icon, { name: "pencil", className: "size-3.5" }),
603
604
  "Edit Configuration"
@@ -657,10 +658,12 @@ function ScheduleFormDrawerBody({
657
658
  }) {
658
659
  const scheduleServer = useScheduleServer();
659
660
  const server = useServer();
661
+ const shell = useOptionalShellMode();
660
662
  const toaster = useToasterOptional();
661
663
  const [form, setForm] = useState2(defaultScheduleFormValues);
662
664
  const [agentId, setAgentId] = useState2(initialAgentId);
663
665
  const [agents, setAgents] = useState2([]);
666
+ const [agentsLoaded, setAgentsLoaded] = useState2(false);
664
667
  const [view, setView] = useState2({ kind: "form" });
665
668
  const [saving, setSaving] = useState2(false);
666
669
  const [activating, setActivating] = useState2(false);
@@ -668,12 +671,19 @@ function ScheduleFormDrawerBody({
668
671
  const savedFromCreate = view.kind === "form" ? view.saved : view.schedule;
669
672
  const isExternalEdit = mode === "edit" && view.kind === "form" && view.saved == null && schedule != null;
670
673
  const isCreatedEdit = view.kind === "form" && view.saved != null;
674
+ const isInitialCreate = mode === "create" && view.kind === "form" && view.saved == null;
675
+ const { allows: allowsAgent } = useResourcePermissions({
676
+ resourceType: "agent",
677
+ resourceIds: agentId.length === 0 ? [] : [agentId]
678
+ });
671
679
  useEffect2(() => {
672
680
  if (!open) return;
673
681
  let cancelled = false;
682
+ setAgentsLoaded(false);
674
683
  void searchAllAgents(server).then((rows) => {
675
684
  if (cancelled) return;
676
685
  setAgents(rows);
686
+ setAgentsLoaded(true);
677
687
  }).catch(() => void 0);
678
688
  return () => {
679
689
  cancelled = true;
@@ -720,8 +730,8 @@ function ScheduleFormDrawerBody({
720
730
  }, [selectedAgent]);
721
731
  const canSubmit = useMemo(() => {
722
732
  const cron = valuesToCron(form);
723
- return form.name.trim().length > 0 && form.task.trim().length > 0 && cron.length > 0 && agentId.length > 0;
724
- }, [form, agentId]);
733
+ return form.name.trim().length > 0 && form.task.trim().length > 0 && cron.length > 0 && agentId.length > 0 && (!isInitialCreate || allowsAgent(agentId, "USE"));
734
+ }, [agentId, allowsAgent, form, isInitialCreate]);
725
735
  const enterTestView = (saved) => {
726
736
  setView({ kind: "test", schedule: saved });
727
737
  setForm(
@@ -822,7 +832,7 @@ function ScheduleFormDrawerBody({
822
832
  if (view.kind === "test") {
823
833
  footer = /* @__PURE__ */ jsxs5("div", { className: "flex flex-col gap-2", children: [
824
834
  error != null ? /* @__PURE__ */ jsx6("p", { className: "text-failure-bg text-sm", children: error }) : null,
825
- /* @__PURE__ */ jsx6(Button.Secondary, { type: "button", className: "w-full", disabled: activating, onClick: () => void handleActivate(), children: "Activate Anyway" })
835
+ /* @__PURE__ */ jsx6(Button.Secondary, { type: "button", className: "w-full", disabled: activating, onClick: () => void handleActivate(), children: "Activate Schedule" })
826
836
  ] });
827
837
  } else {
828
838
  footer = /* @__PURE__ */ jsxs5("div", { className: "flex flex-col gap-2", children: [
@@ -841,7 +851,7 @@ function ScheduleFormDrawerBody({
841
851
  title,
842
852
  description,
843
853
  anchor: "right",
844
- size: "lg",
854
+ size: "xl",
845
855
  headerIcon: /* @__PURE__ */ jsx6("span", { className: "text-primary-button-bg inline-flex size-8 items-center justify-center", children: /* @__PURE__ */ jsx6(
846
856
  Icon,
847
857
  {
@@ -869,7 +879,12 @@ function ScheduleFormDrawerBody({
869
879
  agentId,
870
880
  onAgentIdChange: isExternalEdit || isCreatedEdit ? void 0 : setAgentId,
871
881
  agentOptions,
872
- agentPickerDisabled: isExternalEdit || isCreatedEdit
882
+ agentOptionsLoaded: agentsLoaded,
883
+ agentPickerDisabled: isExternalEdit || isCreatedEdit,
884
+ onBuildAgent: mode === "create" && shell?.isComposerEnabled === true ? () => {
885
+ onOpenChange(false);
886
+ shell.openAgentBuilder();
887
+ } : void 0
873
888
  }
874
889
  ) })
875
890
  }
@@ -908,16 +923,28 @@ function filtersFromSearch(search) {
908
923
  agentFilter: share.agent ?? "all"
909
924
  };
910
925
  }
926
+ function initialDrawerState(agentId) {
927
+ const share = readScheduleShareSearch(window.location.search);
928
+ if (!share.isNew) return { kind: "closed" };
929
+ const initialAgentId = agentId ?? share.agent;
930
+ return {
931
+ kind: "create",
932
+ ...initialAgentId == null ? {} : { agentId: initialAgentId }
933
+ };
934
+ }
911
935
  function ScheduleRowActions({
912
936
  schedule,
913
937
  running,
938
+ canManage,
939
+ canDelete,
914
940
  onRunNow,
915
941
  onEdit,
916
942
  onTogglePause,
917
943
  onDelete
918
944
  }) {
945
+ const PermissionGuard = useSlot("PermissionGuard");
919
946
  return /* @__PURE__ */ jsxs6("div", { className: "inline-flex items-center justify-end gap-1.5", children: [
920
- /* @__PURE__ */ jsxs6(
947
+ /* @__PURE__ */ jsx8(PermissionGuard, { allowed: canManage, children: /* @__PURE__ */ jsxs6(
921
948
  Button.Secondary,
922
949
  {
923
950
  type: "button",
@@ -930,7 +957,7 @@ function ScheduleRowActions({
930
957
  "Run now"
931
958
  ]
932
959
  }
933
- ),
960
+ ) }),
934
961
  /* @__PURE__ */ jsxs6(
935
962
  DropdownMenu,
936
963
  {
@@ -945,28 +972,32 @@ function ScheduleRowActions({
945
972
  }
946
973
  ),
947
974
  children: [
948
- /* @__PURE__ */ jsxs6(DropdownMenuItem, { onClick: onEdit, children: [
975
+ /* @__PURE__ */ jsx8(PermissionGuard, { allowed: canManage, children: /* @__PURE__ */ jsxs6(DropdownMenuItem, { onClick: onEdit, children: [
949
976
  /* @__PURE__ */ jsx8(Icon, { name: "pencil", className: "size-3.5" }),
950
977
  "Edit"
951
- ] }),
952
- /* @__PURE__ */ jsxs6(DropdownMenuItem, { onClick: onTogglePause, children: [
978
+ ] }) }),
979
+ /* @__PURE__ */ jsx8(PermissionGuard, { allowed: canManage, children: /* @__PURE__ */ jsxs6(DropdownMenuItem, { onClick: onTogglePause, children: [
953
980
  /* @__PURE__ */ jsx8(Icon, { name: schedule.status === "active" ? "pause" : "play", className: "size-3.5" }),
954
981
  schedule.status === "active" ? "Pause" : "Resume"
955
- ] }),
956
- /* @__PURE__ */ jsxs6(DropdownMenuItem, { className: "text-failure-bg focus:text-failure-bg", onClick: onDelete, children: [
982
+ ] }) }),
983
+ /* @__PURE__ */ jsx8(PermissionGuard, { allowed: canDelete, children: /* @__PURE__ */ jsxs6(DropdownMenuItem, { className: "text-failure-bg focus:text-failure-bg", onClick: onDelete, children: [
957
984
  /* @__PURE__ */ jsx8(Icon, { name: "trash", className: "size-3.5" }),
958
985
  "Delete"
959
- ] })
986
+ ] }) })
960
987
  ]
961
988
  }
962
989
  )
963
990
  ] });
964
991
  }
965
- function SchedulesPage() {
992
+ function SchedulesPage({ agentId }) {
966
993
  const scheduleServer = useScheduleServer();
967
994
  const server = useServer();
968
995
  const toaster = useToasterOptional();
969
996
  const [schedules, setSchedules] = useState3([]);
997
+ const { allows } = useResourcePermissions({
998
+ resourceType: "schedule",
999
+ resourceIds: schedules.map((schedule) => schedule.id)
1000
+ });
970
1001
  const [runsByScheduleId, setRunsByScheduleId] = useState3({});
971
1002
  const [runsLoading, setRunsLoading] = useState3(false);
972
1003
  const [runningScheduleIds, setRunningScheduleIds] = useState3(() => /* @__PURE__ */ new Set());
@@ -977,8 +1008,20 @@ function SchedulesPage() {
977
1008
  const [statusFilter, setStatusFilter] = useState3(
978
1009
  () => filtersFromSearch(window.location.search).statusFilter
979
1010
  );
980
- const [agentFilter, setAgentFilter] = useState3(() => filtersFromSearch(window.location.search).agentFilter);
981
- const [drawer, setDrawer] = useState3({ kind: "closed" });
1011
+ const [agentFilter, setAgentFilter] = useState3(
1012
+ () => agentId ?? filtersFromSearch(window.location.search).agentFilter
1013
+ );
1014
+ const permissionAgentId = agentId ?? (agentFilter === "all" ? null : agentFilter);
1015
+ const permissionAgentIds = useMemo2(
1016
+ () => permissionAgentId == null ? agentOptions.map((option) => option.agentId) : [permissionAgentId],
1017
+ [agentOptions, permissionAgentId]
1018
+ );
1019
+ const { allows: allowsAgent } = useResourcePermissions({
1020
+ resourceType: "agent",
1021
+ resourceIds: permissionAgentIds
1022
+ });
1023
+ const canCreateSchedule = server.permissions == null || (permissionAgentId == null ? agentOptions.some((option) => allowsAgent(option.agentId, "USE")) : allowsAgent(permissionAgentId, "USE"));
1024
+ const [drawer, setDrawer] = useState3(() => initialDrawerState(agentId));
982
1025
  const [pendingDelete, setPendingDelete] = useState3(null);
983
1026
  const [pageSize, setPageSize] = useState3(() => clampPageSize(DEFAULT_TABLE_PAGE_SIZE));
984
1027
  const [pageToken, setPageToken] = useState3(void 0);
@@ -1014,7 +1057,7 @@ function SchedulesPage() {
1014
1057
  [scheduleServer]
1015
1058
  );
1016
1059
  const loadSchedules = useCallback(
1017
- async ({ token, size, agentId }) => {
1060
+ async ({ token, size, agentId: agentId2 }) => {
1018
1061
  const gen = ++loadGenRef.current;
1019
1062
  setLoading(true);
1020
1063
  setError(null);
@@ -1022,7 +1065,7 @@ function SchedulesPage() {
1022
1065
  const page = await scheduleServer.listSchedules({
1023
1066
  limit: clampPageSize(size),
1024
1067
  ...token === void 0 || token === "" ? {} : { pageToken: token },
1025
- ...agentId === "all" ? {} : { agentIds: [agentId] }
1068
+ ...agentId2 === "all" ? {} : { agentIds: [agentId2] }
1026
1069
  });
1027
1070
  if (gen !== loadGenRef.current) return;
1028
1071
  setSchedules(page.data);
@@ -1044,29 +1087,34 @@ function SchedulesPage() {
1044
1087
  const resetToFirstPage = useCallback(
1045
1088
  (next) => {
1046
1089
  const size = next?.size ?? pageSize;
1047
- const agentId = next?.agentId ?? agentFilter;
1090
+ const agentId2 = next?.agentId ?? agentFilter;
1048
1091
  setPageToken(void 0);
1049
1092
  setPrevTokenStack([]);
1050
- void loadSchedules({ token: void 0, size, agentId });
1093
+ void loadSchedules({ token: void 0, size, agentId: agentId2 });
1051
1094
  },
1052
1095
  [agentFilter, loadSchedules, pageSize]
1053
1096
  );
1054
1097
  useEffect3(() => {
1055
1098
  replaceScheduleShareSearch({
1056
- agent: agentFilter === "all" ? null : agentFilter,
1099
+ agent: agentId === void 0 && agentFilter !== "all" ? agentFilter : null,
1057
1100
  status: statusFilter === "all" ? null : statusFilter,
1058
1101
  q: nameQuery.trim().length === 0 ? null : nameQuery
1059
1102
  });
1060
- }, [agentFilter, statusFilter, nameQuery]);
1103
+ }, [agentFilter, agentId, statusFilter, nameQuery]);
1104
+ useEffect3(() => {
1105
+ if (agentId === void 0) return;
1106
+ setAgentFilter((current) => {
1107
+ if (current === agentId) return current;
1108
+ setPageToken(void 0);
1109
+ setPrevTokenStack([]);
1110
+ return agentId;
1111
+ });
1112
+ }, [agentId]);
1061
1113
  useEffect3(() => {
1062
1114
  if (didConsumeIsNewRef.current) return;
1063
1115
  const share = readScheduleShareSearch(window.location.search);
1064
1116
  if (!share.isNew) return;
1065
1117
  didConsumeIsNewRef.current = true;
1066
- setDrawer({
1067
- kind: "create",
1068
- ...share.agent != null ? { agentId: share.agent } : {}
1069
- });
1070
1118
  replaceScheduleShareSearch({ isNew: null });
1071
1119
  }, []);
1072
1120
  useEffect3(() => {
@@ -1075,17 +1123,18 @@ function SchedulesPage() {
1075
1123
  setNameQuery(next.nameQuery);
1076
1124
  setStatusFilter(next.statusFilter);
1077
1125
  setAgentFilter((current) => {
1078
- if (current === next.agentFilter) return current;
1126
+ const nextAgentFilter = agentId ?? next.agentFilter;
1127
+ if (current === nextAgentFilter) return current;
1079
1128
  setPageToken(void 0);
1080
1129
  setPrevTokenStack([]);
1081
- return next.agentFilter;
1130
+ return nextAgentFilter;
1082
1131
  });
1083
1132
  };
1084
1133
  window.addEventListener("popstate", syncFromUrl);
1085
1134
  return () => {
1086
1135
  window.removeEventListener("popstate", syncFromUrl);
1087
1136
  };
1088
- }, []);
1137
+ }, [agentId]);
1089
1138
  useEffect3(() => {
1090
1139
  void loadSchedules({ token: pageToken, size: pageSize, agentId: agentFilter });
1091
1140
  }, [agentFilter, pageSize, pageToken, loadSchedules]);
@@ -1114,8 +1163,10 @@ function SchedulesPage() {
1114
1163
  return true;
1115
1164
  });
1116
1165
  }, [schedules, nameQuery, statusFilter]);
1166
+ const showCreatedByColumn = hasCreatedBySubject(schedules);
1117
1167
  const hasPageNav = prevTokenStack.length > 0 || nextPageToken != null;
1118
1168
  const handleTogglePause = async (schedule) => {
1169
+ if (!allows(schedule.id, "MANAGE")) return;
1119
1170
  const nextStatus = schedule.status === "active" ? "paused" : "active";
1120
1171
  try {
1121
1172
  await scheduleServer.updateSchedule({ ...schedule, status: nextStatus });
@@ -1125,6 +1176,7 @@ function SchedulesPage() {
1125
1176
  }
1126
1177
  };
1127
1178
  const handleRunNow = async (schedule) => {
1179
+ if (!allows(schedule.id, "MANAGE")) return;
1128
1180
  setRunningScheduleIds((prev) => new Set(prev).add(schedule.id));
1129
1181
  try {
1130
1182
  await scheduleServer.createScheduleRun({ scheduleId: schedule.id });
@@ -1142,6 +1194,7 @@ function SchedulesPage() {
1142
1194
  }
1143
1195
  };
1144
1196
  const handleDelete = async (schedule) => {
1197
+ if (!allows(schedule.id, "DELETE")) return;
1145
1198
  setPendingDelete(null);
1146
1199
  try {
1147
1200
  await scheduleServer.deleteSchedule({ id: schedule.id });
@@ -1166,7 +1219,7 @@ function SchedulesPage() {
1166
1219
  /* @__PURE__ */ jsx8(
1167
1220
  PageHeader,
1168
1221
  {
1169
- title: "Scheduled Agents",
1222
+ title: agentId === void 0 ? "Scheduled Agents" : void 0,
1170
1223
  end: /* @__PURE__ */ jsxs6(Fragment, { children: [
1171
1224
  /* @__PURE__ */ jsx8("div", { className: "w-full sm:w-56", children: /* @__PURE__ */ jsx8(SearchInput_default, { query: nameQuery, setQuery: setNameQuery, placeholder: "Search schedules by name" }) }),
1172
1225
  /* @__PURE__ */ jsx8(
@@ -1179,7 +1232,7 @@ function SchedulesPage() {
1179
1232
  "aria-label": "Filter by status"
1180
1233
  }
1181
1234
  ),
1182
- /* @__PURE__ */ jsx8(
1235
+ agentId === void 0 ? /* @__PURE__ */ jsx8(
1183
1236
  PopoverSelect,
1184
1237
  {
1185
1238
  value: agentFilter,
@@ -1195,12 +1248,13 @@ function SchedulesPage() {
1195
1248
  className: "sm:w-40",
1196
1249
  "aria-label": "Filter by agent"
1197
1250
  }
1198
- ),
1251
+ ) : null,
1199
1252
  /* @__PURE__ */ jsxs6(
1200
1253
  Button.Primary,
1201
1254
  {
1202
1255
  type: "button",
1203
- onClick: () => setDrawer({
1256
+ disabled: !canCreateSchedule,
1257
+ onClick: () => canCreateSchedule && setDrawer({
1204
1258
  kind: "create",
1205
1259
  agentId: agentFilter !== "all" ? agentFilter : void 0
1206
1260
  }),
@@ -1213,7 +1267,7 @@ function SchedulesPage() {
1213
1267
  ] })
1214
1268
  }
1215
1269
  ),
1216
- /* @__PURE__ */ jsx8("div", { className: "min-h-0 flex-1 overflow-auto px-4 py-4 md:px-6", children: loading ? /* @__PURE__ */ jsx8("div", { className: "flex flex-col gap-2", role: "status", "aria-label": "Loading schedules", children: Array.from({ length: 5 }, (_, i) => /* @__PURE__ */ jsx8(Skeleton, { className: "h-12 w-full rounded-md" }, i)) }) : error != null ? /* @__PURE__ */ jsx8("p", { className: "text-failure-bg px-3 py-8 text-center text-sm", children: error }) : schedules.length === 0 ? /* @__PURE__ */ jsx8(EmptyScreen, { title: "No Schedules Found", description: "Create one to get started.", className: "min-h-full" }) : filtered.length === 0 ? /* @__PURE__ */ jsxs6("div", { className: "flex min-h-full flex-col", children: [
1270
+ /* @__PURE__ */ jsx8("div", { className: "min-h-0 flex-1 overflow-auto px-4 py-4", children: loading ? /* @__PURE__ */ jsx8("div", { className: "flex flex-col gap-2", role: "status", "aria-label": "Loading schedules", children: Array.from({ length: 5 }, (_, i) => /* @__PURE__ */ jsx8(Skeleton, { className: "h-12 w-full rounded-md" }, i)) }) : error != null ? /* @__PURE__ */ jsx8("p", { className: "text-failure-bg px-3 py-8 text-center text-sm", children: error }) : schedules.length === 0 ? /* @__PURE__ */ jsx8(EmptyScreen, { title: "No Schedules Found", description: "Create one to get started.", className: "min-h-full" }) : filtered.length === 0 ? /* @__PURE__ */ jsxs6("div", { className: "flex min-h-full flex-col", children: [
1217
1271
  /* @__PURE__ */ jsx8(EmptyScreen, { title: "No Schedules Found", description: "No schedules match your filters.", className: "flex-1" }),
1218
1272
  hasPageNav ? /* @__PURE__ */ jsx8(
1219
1273
  TableTokenPagination,
@@ -1238,7 +1292,8 @@ function SchedulesPage() {
1238
1292
  /* @__PURE__ */ jsx8(TableHeader, { children: /* @__PURE__ */ jsxs6(TableRow, { className: "hover:bg-transparent", children: [
1239
1293
  /* @__PURE__ */ jsx8(TableHead, { children: "Name" }),
1240
1294
  /* @__PURE__ */ jsx8(TableHead, { children: "Agent" }),
1241
- /* @__PURE__ */ jsx8(TableHead, { children: "Cadence" }),
1295
+ showCreatedByColumn ? /* @__PURE__ */ jsx8(TableHead, { children: "Created by" }) : null,
1296
+ /* @__PURE__ */ jsx8(TableHead, { children: "Frequency" }),
1242
1297
  /* @__PURE__ */ jsx8(TableHead, { children: "Status" }),
1243
1298
  /* @__PURE__ */ jsx8(TableHead, { children: "Last 5 runs" }),
1244
1299
  /* @__PURE__ */ jsx8(TableHead, { children: /* @__PURE__ */ jsx8("span", { className: "sr-only", children: "Actions" }) })
@@ -1247,16 +1302,9 @@ function SchedulesPage() {
1247
1302
  const cadence = formatCadenceSummary({ cron: schedule.cron, timezone: schedule.timezone });
1248
1303
  const agentLabel = schedule.agentName ?? agentNameById.get(schedule.agentId) ?? schedule.agentId;
1249
1304
  return /* @__PURE__ */ jsxs6(TableRow, { children: [
1250
- /* @__PURE__ */ jsx8(TableCell, { className: "text-text-primary font-medium", children: /* @__PURE__ */ jsx8(
1251
- "button",
1252
- {
1253
- type: "button",
1254
- className: "cursor-pointer text-left",
1255
- onClick: () => setDrawer({ kind: "edit", schedule }),
1256
- children: schedule.name
1257
- }
1258
- ) }),
1305
+ /* @__PURE__ */ jsx8(TableCell, { className: "text-text-primary font-medium", children: /* @__PURE__ */ jsx8("span", { className: "text-left !no-underline", children: schedule.name }) }),
1259
1306
  /* @__PURE__ */ jsx8(TableCell, { children: agentLabel }),
1307
+ showCreatedByColumn ? /* @__PURE__ */ jsx8(TableCell, { children: /* @__PURE__ */ jsx8(CreatedByCell, { subject: schedule.createdBySubject }) }) : null,
1260
1308
  /* @__PURE__ */ jsx8(TableCell, { children: cadence }),
1261
1309
  /* @__PURE__ */ jsx8(TableCell, { children: /* @__PURE__ */ jsx8(ScheduleStatusBadge, { status: schedule.status }) }),
1262
1310
  /* @__PURE__ */ jsx8(TableCell, { children: runsLoading ? /* @__PURE__ */ jsx8("span", { className: "text-text-secondary text-sm", children: "\u2026" }) : /* @__PURE__ */ jsx8(ScheduleLastRunsCell, { runs: runsByScheduleId[schedule.id] ?? [] }) }),
@@ -1265,10 +1313,16 @@ function SchedulesPage() {
1265
1313
  {
1266
1314
  schedule,
1267
1315
  running: runningScheduleIds.has(schedule.id),
1316
+ canManage: allows(schedule.id, "MANAGE"),
1317
+ canDelete: allows(schedule.id, "DELETE"),
1268
1318
  onRunNow: () => void handleRunNow(schedule),
1269
- onEdit: () => setDrawer({ kind: "edit", schedule }),
1319
+ onEdit: () => {
1320
+ if (allows(schedule.id, "MANAGE")) setDrawer({ kind: "edit", schedule });
1321
+ },
1270
1322
  onTogglePause: () => void handleTogglePause(schedule),
1271
- onDelete: () => setPendingDelete(schedule)
1323
+ onDelete: () => {
1324
+ if (allows(schedule.id, "DELETE")) setPendingDelete(schedule);
1325
+ }
1272
1326
  }
1273
1327
  ) })
1274
1328
  ] }, schedule.id);
@@ -1337,7 +1391,15 @@ function SchedulesPage() {
1337
1391
  ] }) }),
1338
1392
  /* @__PURE__ */ jsxs6(DialogFooter, { children: [
1339
1393
  /* @__PURE__ */ jsx8(Button.Secondary, { type: "button", onClick: () => setPendingDelete(null), children: "Cancel" }),
1340
- /* @__PURE__ */ jsx8(Button.Destructive, { type: "button", onClick: () => void handleDelete(pendingDelete), children: "Delete" })
1394
+ /* @__PURE__ */ jsx8(
1395
+ Button.Destructive,
1396
+ {
1397
+ type: "button",
1398
+ disabled: !allows(pendingDelete.id, "DELETE"),
1399
+ onClick: () => void handleDelete(pendingDelete),
1400
+ children: "Delete"
1401
+ }
1402
+ )
1341
1403
  ] })
1342
1404
  ]
1343
1405
  }
@@ -1354,4 +1416,4 @@ export {
1354
1416
  ScheduleLastRunsCell,
1355
1417
  SchedulesPage
1356
1418
  };
1357
- //# sourceMappingURL=chunk-GXYAOAK5.js.map
1419
+ //# sourceMappingURL=chunk-MJULWIPI.js.map