@stigmer/react 3.5.2 → 3.6.0

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 (193) hide show
  1. package/agent/AgentPicker.d.ts +10 -1
  2. package/agent/AgentPicker.d.ts.map +1 -1
  3. package/agent/AgentPicker.js +2 -2
  4. package/agent/AgentPicker.js.map +1 -1
  5. package/channel/AgentChannelsPanel.d.ts.map +1 -1
  6. package/channel/AgentChannelsPanel.js +22 -5
  7. package/channel/AgentChannelsPanel.js.map +1 -1
  8. package/channel/ChannelTemplatesDialog.d.ts +53 -0
  9. package/channel/ChannelTemplatesDialog.d.ts.map +1 -0
  10. package/channel/ChannelTemplatesDialog.js +150 -0
  11. package/channel/ChannelTemplatesDialog.js.map +1 -0
  12. package/channel/index.d.ts +8 -0
  13. package/channel/index.d.ts.map +1 -1
  14. package/channel/index.js +4 -0
  15. package/channel/index.js.map +1 -1
  16. package/channel/providers.d.ts +12 -0
  17. package/channel/providers.d.ts.map +1 -1
  18. package/channel/providers.js +14 -2
  19. package/channel/providers.js.map +1 -1
  20. package/channel/templatePresentation.d.ts +37 -0
  21. package/channel/templatePresentation.d.ts.map +1 -0
  22. package/channel/templatePresentation.js +69 -0
  23. package/channel/templatePresentation.js.map +1 -0
  24. package/channel/useChannelTemplateList.d.ts +64 -0
  25. package/channel/useChannelTemplateList.d.ts.map +1 -0
  26. package/channel/useChannelTemplateList.js +69 -0
  27. package/channel/useChannelTemplateList.js.map +1 -0
  28. package/channel/useChannelTemplateReadiness.d.ts +53 -0
  29. package/channel/useChannelTemplateReadiness.d.ts.map +1 -0
  30. package/channel/useChannelTemplateReadiness.js +42 -0
  31. package/channel/useChannelTemplateReadiness.js.map +1 -0
  32. package/dashboard/useDashboardFailedRuns.d.ts.map +1 -1
  33. package/dashboard/useDashboardFailedRuns.js +2 -0
  34. package/dashboard/useDashboardFailedRuns.js.map +1 -1
  35. package/index.d.ts +4 -2
  36. package/index.d.ts.map +1 -1
  37. package/index.js +9 -1
  38. package/index.js.map +1 -1
  39. package/library/useExportResource.d.ts +4 -3
  40. package/library/useExportResource.d.ts.map +1 -1
  41. package/library/useExportResource.js +1 -1
  42. package/library/useExportResource.js.map +1 -1
  43. package/organization/OrgProvider.d.ts +11 -4
  44. package/organization/OrgProvider.d.ts.map +1 -1
  45. package/organization/OrgProvider.js +28 -4
  46. package/organization/OrgProvider.js.map +1 -1
  47. package/package.json +4 -4
  48. package/resource-detail/useDeleteResource.d.ts +1 -1
  49. package/resource-detail/useDeleteResource.d.ts.map +1 -1
  50. package/resource-detail/useDeleteResource.js +5 -0
  51. package/resource-detail/useDeleteResource.js.map +1 -1
  52. package/resource-workbench/components/ResourceWorkbench.d.ts +10 -1
  53. package/resource-workbench/components/ResourceWorkbench.d.ts.map +1 -1
  54. package/resource-workbench/components/ResourceWorkbench.js +6 -2
  55. package/resource-workbench/components/ResourceWorkbench.js.map +1 -1
  56. package/resource-workbench/hooks/useResourceCollection.d.ts +8 -0
  57. package/resource-workbench/hooks/useResourceCollection.d.ts.map +1 -1
  58. package/resource-workbench/hooks/useResourceCollection.js +2 -2
  59. package/resource-workbench/hooks/useResourceCollection.js.map +1 -1
  60. package/schedule/CadenceField.d.ts +31 -0
  61. package/schedule/CadenceField.d.ts.map +1 -0
  62. package/schedule/CadenceField.js +116 -0
  63. package/schedule/CadenceField.js.map +1 -0
  64. package/schedule/ScheduleDetailView.d.ts +58 -0
  65. package/schedule/ScheduleDetailView.d.ts.map +1 -0
  66. package/schedule/ScheduleDetailView.js +236 -0
  67. package/schedule/ScheduleDetailView.js.map +1 -0
  68. package/schedule/ScheduleForm.d.ts +43 -0
  69. package/schedule/ScheduleForm.d.ts.map +1 -0
  70. package/schedule/ScheduleForm.js +129 -0
  71. package/schedule/ScheduleForm.js.map +1 -0
  72. package/schedule/ScheduleRowActions.d.ts +20 -0
  73. package/schedule/ScheduleRowActions.d.ts.map +1 -0
  74. package/schedule/ScheduleRowActions.js +54 -0
  75. package/schedule/ScheduleRowActions.js.map +1 -0
  76. package/schedule/TimeZoneField.d.ts +32 -0
  77. package/schedule/TimeZoneField.d.ts.map +1 -0
  78. package/schedule/TimeZoneField.js +104 -0
  79. package/schedule/TimeZoneField.js.map +1 -0
  80. package/schedule/cadence.d.ts +95 -0
  81. package/schedule/cadence.d.ts.map +1 -0
  82. package/schedule/cadence.js +242 -0
  83. package/schedule/cadence.js.map +1 -0
  84. package/schedule/index.d.ts +31 -0
  85. package/schedule/index.d.ts.map +1 -0
  86. package/schedule/index.js +16 -0
  87. package/schedule/index.js.map +1 -0
  88. package/schedule/scheduleColumns.d.ts +26 -0
  89. package/schedule/scheduleColumns.d.ts.map +1 -0
  90. package/schedule/scheduleColumns.js +77 -0
  91. package/schedule/scheduleColumns.js.map +1 -0
  92. package/schedule/scheduleListFn.d.ts +50 -0
  93. package/schedule/scheduleListFn.d.ts.map +1 -0
  94. package/schedule/scheduleListFn.js +65 -0
  95. package/schedule/scheduleListFn.js.map +1 -0
  96. package/schedule/scheduleState.d.ts +43 -0
  97. package/schedule/scheduleState.d.ts.map +1 -0
  98. package/schedule/scheduleState.js +67 -0
  99. package/schedule/scheduleState.js.map +1 -0
  100. package/schedule/useCreateSchedule.d.ts +57 -0
  101. package/schedule/useCreateSchedule.d.ts.map +1 -0
  102. package/schedule/useCreateSchedule.js +61 -0
  103. package/schedule/useCreateSchedule.js.map +1 -0
  104. package/schedule/useResumeSchedule.d.ts +30 -0
  105. package/schedule/useResumeSchedule.d.ts.map +1 -0
  106. package/schedule/useResumeSchedule.js +45 -0
  107. package/schedule/useResumeSchedule.js.map +1 -0
  108. package/schedule/useSchedule.d.ts +39 -0
  109. package/schedule/useSchedule.d.ts.map +1 -0
  110. package/schedule/useSchedule.js +44 -0
  111. package/schedule/useSchedule.js.map +1 -0
  112. package/schedule/useScheduleCount.d.ts +38 -0
  113. package/schedule/useScheduleCount.d.ts.map +1 -0
  114. package/schedule/useScheduleCount.js +30 -0
  115. package/schedule/useScheduleCount.js.map +1 -0
  116. package/schedule/useScheduleList.d.ts +48 -0
  117. package/schedule/useScheduleList.d.ts.map +1 -0
  118. package/schedule/useScheduleList.js +43 -0
  119. package/schedule/useScheduleList.js.map +1 -0
  120. package/schedule/useSetScheduleEnabled.d.ts +31 -0
  121. package/schedule/useSetScheduleEnabled.d.ts.map +1 -0
  122. package/schedule/useSetScheduleEnabled.js +53 -0
  123. package/schedule/useSetScheduleEnabled.js.map +1 -0
  124. package/schedule/useTriggerSchedule.d.ts +28 -0
  125. package/schedule/useTriggerSchedule.d.ts.map +1 -0
  126. package/schedule/useTriggerSchedule.js +43 -0
  127. package/schedule/useTriggerSchedule.js.map +1 -0
  128. package/search/useResourceCount.d.ts +2 -1
  129. package/search/useResourceCount.d.ts.map +1 -1
  130. package/search/useResourceCount.js +6 -1
  131. package/search/useResourceCount.js.map +1 -1
  132. package/src/agent/AgentPicker.tsx +13 -1
  133. package/src/channel/AgentChannelsPanel.tsx +43 -1
  134. package/src/channel/ChannelTemplatesDialog.tsx +433 -0
  135. package/src/channel/__tests__/AgentChannelsPanel.test.tsx +73 -0
  136. package/src/channel/__tests__/ChannelTemplatesDialog.test.tsx +292 -0
  137. package/src/channel/__tests__/providers.test.ts +9 -0
  138. package/src/channel/__tests__/templatePresentation.test.ts +96 -0
  139. package/src/channel/__tests__/useChannelTemplateList.test.tsx +216 -0
  140. package/src/channel/__tests__/useChannelTemplateReadiness.test.tsx +124 -0
  141. package/src/channel/index.ts +15 -0
  142. package/src/channel/providers.ts +26 -2
  143. package/src/channel/templatePresentation.ts +82 -0
  144. package/src/channel/useChannelTemplateList.ts +123 -0
  145. package/src/channel/useChannelTemplateReadiness.ts +69 -0
  146. package/src/dashboard/__tests__/useDashboardFailedRuns.test.tsx +106 -0
  147. package/src/dashboard/useDashboardFailedRuns.ts +2 -0
  148. package/src/execution/__tests__/PlanArtifactCard.test.tsx +23 -2
  149. package/src/index.ts +65 -0
  150. package/src/library/useExportResource.ts +4 -3
  151. package/src/organization/OrgProvider.tsx +29 -4
  152. package/src/organization/__tests__/OrgProvider.orgSwitch.test.tsx +89 -0
  153. package/src/resource-detail/useDeleteResource.ts +11 -1
  154. package/src/resource-workbench/__tests__/ResourceWorkbench.test.tsx +112 -0
  155. package/src/resource-workbench/components/ResourceWorkbench.tsx +32 -15
  156. package/src/resource-workbench/hooks/useResourceCollection.ts +11 -1
  157. package/src/schedule/CadenceField.tsx +365 -0
  158. package/src/schedule/ScheduleDetailView.tsx +583 -0
  159. package/src/schedule/ScheduleForm.tsx +405 -0
  160. package/src/schedule/ScheduleRowActions.tsx +124 -0
  161. package/src/schedule/TimeZoneField.tsx +199 -0
  162. package/src/schedule/__tests__/ScheduleDetailView.test.tsx +260 -0
  163. package/src/schedule/__tests__/cadence.test.ts +278 -0
  164. package/src/schedule/__tests__/scheduleColumnsRowActions.test.tsx +176 -0
  165. package/src/schedule/__tests__/scheduleCreation.test.tsx +340 -0
  166. package/src/schedule/__tests__/scheduleHooks.test.tsx +312 -0
  167. package/src/schedule/__tests__/scheduleListFn.test.ts +128 -0
  168. package/src/schedule/__tests__/scheduleState.test.ts +133 -0
  169. package/src/schedule/cadence.ts +298 -0
  170. package/src/schedule/index.ts +57 -0
  171. package/src/schedule/scheduleColumns.tsx +118 -0
  172. package/src/schedule/scheduleListFn.ts +108 -0
  173. package/src/schedule/scheduleState.ts +96 -0
  174. package/src/schedule/useCreateSchedule.ts +88 -0
  175. package/src/schedule/useResumeSchedule.ts +67 -0
  176. package/src/schedule/useSchedule.ts +67 -0
  177. package/src/schedule/useScheduleCount.ts +57 -0
  178. package/src/schedule/useScheduleList.ts +83 -0
  179. package/src/schedule/useSetScheduleEnabled.ts +84 -0
  180. package/src/schedule/useTriggerSchedule.ts +65 -0
  181. package/src/search/__tests__/useResourceCount.test.tsx +89 -0
  182. package/src/search/useResourceCount.ts +8 -2
  183. package/src/workflow/WorkflowDashboard.tsx +1 -0
  184. package/src/workflow/useWorkflowExecutionList.ts +13 -2
  185. package/styles.css +1 -1
  186. package/workflow/CanvasTransitionEdge.d.ts +1 -1
  187. package/workflow/WorkflowDashboard.d.ts.map +1 -1
  188. package/workflow/WorkflowDashboard.js +1 -0
  189. package/workflow/WorkflowDashboard.js.map +1 -1
  190. package/workflow/useWorkflowExecutionList.d.ts +10 -0
  191. package/workflow/useWorkflowExecutionList.d.ts.map +1 -1
  192. package/workflow/useWorkflowExecutionList.js +3 -2
  193. package/workflow/useWorkflowExecutionList.js.map +1 -1
@@ -0,0 +1,129 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { useCallback, useState } from "react";
4
+ import { cn } from "@stigmer/theme";
5
+ import { getUserMessage } from "@stigmer/sdk";
6
+ import { Popover } from "@base-ui/react/popover";
7
+ import { AgentPicker } from "../agent/AgentPicker.js";
8
+ import { Switch } from "../switch/Switch.js";
9
+ import { useStigmerPortalContainer } from "../portal-container.js";
10
+ import { CadenceField } from "./CadenceField.js";
11
+ import { TimeZoneField, browserTimeZone } from "./TimeZoneField.js";
12
+ import { useCreateSchedule } from "./useCreateSchedule.js";
13
+ import { cadenceToCron, validateCron } from "./cadence.js";
14
+ /** spec.proto pins AgentTarget.message to 8192 characters. */
15
+ const MESSAGE_MAX_LEN = 8192;
16
+ /** Show the remaining-characters counter once within this margin. */
17
+ const MESSAGE_COUNTER_THRESHOLD = 500;
18
+ /**
19
+ * Single-page form for creating a {@link Schedule}.
20
+ *
21
+ * Collects the four things a user decides about a schedule — which
22
+ * agent, what message, when ({@link CadenceField}, generating the cron
23
+ * expression from human-friendly presets), and whether it starts
24
+ * enabled — then creates it via {@link useCreateSchedule}.
25
+ *
26
+ * Enabled defaults to OFF, deliberately: it matches the proto/YAML
27
+ * default (an omitted `enabled` is false) and the platform's
28
+ * recommended workflow — create staged-disabled, validate with
29
+ * "Run now" on the detail page, then enable.
30
+ *
31
+ * Creation only. Editing an existing schedule must not flow through
32
+ * this form's curated input — see the note on {@link useCreateSchedule}.
33
+ *
34
+ * @example
35
+ * ```tsx
36
+ * <ScheduleForm
37
+ * org="acme"
38
+ * onComplete={(s) => navigate(`/library/schedules/${s.metadata?.org}/${s.metadata?.slug}`)}
39
+ * onCancel={() => navigate("/library/schedules")}
40
+ * />
41
+ * ```
42
+ */
43
+ export function ScheduleForm({ org, onComplete, onCancel, className, }) {
44
+ const { create, isCreating, error, clearError } = useCreateSchedule();
45
+ const [name, setName] = useState("");
46
+ const [agentRef, setAgentRef] = useState(null);
47
+ const [agentName, setAgentName] = useState(null);
48
+ const [message, setMessage] = useState("");
49
+ const [cadence, setCadence] = useState({
50
+ kind: "daily",
51
+ hour: 9,
52
+ minute: 0,
53
+ });
54
+ const [timeZone, setTimeZone] = useState(browserTimeZone);
55
+ const [enabled, setEnabled] = useState(false);
56
+ const [pickerOpen, setPickerOpen] = useState(false);
57
+ const trimmedName = name.trim();
58
+ const trimmedMessage = message.trim();
59
+ const cron = cadenceToCron(cadence).trim();
60
+ const cronValid = cron !== "" && validateCron(cron) === null;
61
+ const canSubmit = trimmedName !== "" &&
62
+ agentRef !== null &&
63
+ trimmedMessage !== "" &&
64
+ cronValid &&
65
+ !isCreating;
66
+ const handleAgentChange = useCallback((ref) => {
67
+ setAgentRef(ref);
68
+ if (ref === null)
69
+ setAgentName(null);
70
+ setPickerOpen(false);
71
+ }, []);
72
+ const handleSubmit = useCallback(async (e) => {
73
+ e.preventDefault();
74
+ if (!canSubmit || !agentRef)
75
+ return;
76
+ clearError();
77
+ try {
78
+ const schedule = await create({
79
+ name: trimmedName,
80
+ org,
81
+ cron,
82
+ timeZone,
83
+ enabled,
84
+ agent: { agentRef, message: trimmedMessage },
85
+ });
86
+ onComplete?.(schedule);
87
+ }
88
+ catch {
89
+ // error state is managed by useCreateSchedule
90
+ }
91
+ }, [
92
+ canSubmit,
93
+ agentRef,
94
+ clearError,
95
+ create,
96
+ trimmedName,
97
+ org,
98
+ cron,
99
+ timeZone,
100
+ enabled,
101
+ trimmedMessage,
102
+ onComplete,
103
+ ]);
104
+ const remaining = MESSAGE_MAX_LEN - message.length;
105
+ return (_jsxs("form", { onSubmit: handleSubmit, className: cn("max-w-2xl space-y-5", className), "aria-label": "New schedule", children: [_jsxs("div", { className: "space-y-1", children: [_jsx("label", { htmlFor: "stgm-new-schedule-name", className: labelClasses, children: "Name" }), _jsx("input", { id: "stgm-new-schedule-name", type: "text", value: name, onChange: (e) => setName(e.target.value), placeholder: "e.g. daily-fee-reminders", disabled: isCreating, autoFocus: true, required: true, className: inputClasses })] }), _jsxs("div", { className: "space-y-1", children: [_jsx("span", { id: "stgm-new-schedule-agent-label", className: labelClasses, children: "Agent to run" }), _jsxs(Popover.Root, { open: pickerOpen, onOpenChange: setPickerOpen, children: [_jsxs(Popover.Trigger, { disabled: isCreating, "aria-labelledby": "stgm-new-schedule-agent-label", className: cn("flex w-full items-center justify-between rounded-md border border-input bg-background px-2.5 py-1.5 text-left text-xs", "focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring", "disabled:pointer-events-none disabled:opacity-50", agentRef ? "text-foreground" : "text-muted-foreground"), children: [_jsx("span", { className: "truncate", children: agentRef
106
+ ? (agentName ?? `${agentRef.org}/${agentRef.slug}`)
107
+ : "Choose an agent…" }), _jsx(ChevronIcon, {})] }), _jsx(AgentPickerPopup, { org: org, value: agentRef, onChange: handleAgentChange, onDisplayNameResolved: (_key, resolvedName) => setAgentName(resolvedName), disabled: isCreating })] }), _jsxs("p", { className: hintClasses, children: ["Each fire runs this agent unattended in a fresh session. Only agents in ", _jsx("span", { className: "font-medium", children: org }), " can be scheduled."] })] }), _jsxs("div", { className: "space-y-1", children: [_jsx("label", { htmlFor: "stgm-new-schedule-message", className: labelClasses, children: "Message" }), _jsx("textarea", { id: "stgm-new-schedule-message", value: message, onChange: (e) => setMessage(e.target.value), placeholder: "The instruction the agent receives on every fire \u2014 write it for a run with no human present.", disabled: isCreating, required: true, rows: 5, maxLength: MESSAGE_MAX_LEN, className: cn(inputClasses, "resize-y") }), remaining <= MESSAGE_COUNTER_THRESHOLD && (_jsxs("p", { className: hintClasses, children: [remaining, " characters left"] }))] }), _jsxs("div", { className: "space-y-1", children: [_jsx("span", { className: labelClasses, children: "Runs" }), _jsx(CadenceField, { value: cadence, onChange: setCadence, timeZone: timeZone, disabled: isCreating })] }), _jsxs("div", { className: "space-y-1", children: [_jsx("label", { htmlFor: "stgm-new-schedule-tz", className: labelClasses, children: "Time zone" }), _jsx(TimeZoneField, { id: "stgm-new-schedule-tz", value: timeZone, onChange: setTimeZone, disabled: isCreating })] }), _jsxs("div", { className: "flex items-start gap-3", children: [_jsx(Switch, { id: "stgm-new-schedule-enabled", checked: enabled, onCheckedChange: setEnabled, disabled: isCreating, "aria-labelledby": "stgm-new-schedule-enabled-label" }), _jsxs("div", { className: "space-y-0.5", children: [_jsx("label", { id: "stgm-new-schedule-enabled-label", htmlFor: "stgm-new-schedule-enabled", className: labelClasses, children: "Enabled" }), _jsx("p", { className: hintClasses, children: "Leave off to create the schedule staged: validate it with \u201CRun now\u201D on the schedule page, then enable it there." })] })] }), error && (_jsx("p", { className: "text-xs text-destructive", role: "alert", children: getUserMessage(error) })), _jsxs("div", { className: "flex items-center gap-2", children: [_jsxs("button", { type: "submit", disabled: !canSubmit, className: cn("inline-flex items-center gap-1.5 rounded-md px-3 py-1.5 text-sm font-medium", "bg-primary text-primary-foreground hover:bg-primary-hover", "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring", "disabled:pointer-events-none disabled:opacity-40"), children: [isCreating && _jsx(SpinnerIcon, {}), "Create schedule"] }), onCancel && (_jsx("button", { type: "button", onClick: onCancel, disabled: isCreating, className: cn("rounded-md px-3 py-1.5 text-sm", "text-muted-foreground hover:bg-accent-hover hover:text-foreground", "disabled:pointer-events-none disabled:opacity-50"), children: "Cancel" }))] })] }));
108
+ }
109
+ // ---------------------------------------------------------------------------
110
+ // Private helpers
111
+ // ---------------------------------------------------------------------------
112
+ const labelClasses = "block text-xs font-medium text-foreground";
113
+ const hintClasses = "text-[0.65rem] text-muted-foreground";
114
+ const inputClasses = cn("w-full rounded-md border border-input bg-background px-2.5 py-1.5 text-xs text-foreground", "placeholder:text-muted-foreground", "focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring", "disabled:pointer-events-none disabled:opacity-50");
115
+ function AgentPickerPopup({ org, value, onChange, onDisplayNameResolved, disabled, }) {
116
+ const portalContainer = useStigmerPortalContainer();
117
+ return (_jsx(Popover.Portal, { container: portalContainer, children: _jsx(Popover.Positioner, { sideOffset: 4, align: "start", children: _jsx(Popover.Popup, { className: cn("z-popover overflow-x-hidden overflow-y-auto rounded-lg border border-border", "bg-popover p-3 text-popover-foreground shadow-md", "max-h-[60vh]"), children: _jsx(AgentPicker, { org: org, value: value, onChange: onChange, onDisplayNameResolved: onDisplayNameResolved,
118
+ // Schedules are org-local: the server rejects a target
119
+ // agent outside the schedule's org, so cross-org browsing
120
+ // could only offer choices that fail at submit.
121
+ scope: "org", showScopeToggle: false, disabled: disabled }) }) }) }));
122
+ }
123
+ function ChevronIcon() {
124
+ return (_jsx("svg", { width: "12", height: "12", viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round", className: "shrink-0 text-muted-foreground", "aria-hidden": "true", children: _jsx("path", { d: "M4 6l4 4 4-4" }) }));
125
+ }
126
+ function SpinnerIcon() {
127
+ return (_jsx("svg", { width: "14", height: "14", viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", className: "animate-spin", "aria-hidden": "true", children: _jsx("path", { d: "M8 2a6 6 0 1 0 6 6" }) }));
128
+ }
129
+ //# sourceMappingURL=ScheduleForm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ScheduleForm.js","sourceRoot":"","sources":["../../src/schedule/ScheduleForm.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ import type { Schedule } from "@stigmer/protos/ai/stigmer/agentic/schedule/v1/api_pb";
2
+ /** Props for {@link ScheduleRowActions}. */
3
+ export interface ScheduleRowActionsProps {
4
+ /** The schedule this row represents. */
5
+ readonly schedule: Schedule;
6
+ /** Called after a successful action so the list can refetch. */
7
+ readonly onChanged?: () => void;
8
+ }
9
+ /**
10
+ * Compact per-row actions for a schedule list: **Run now** on an active
11
+ * schedule (confirmation-gated — it starts a real, billable execution)
12
+ * and **Resume** on a platform-paused one. Exactly one action renders
13
+ * at a time — the one that is currently meaningful; an owner-disabled
14
+ * schedule renders neither (its remedy lives on the detail page).
15
+ *
16
+ * Shared by every console's schedule workbench via `renderItemAction`
17
+ * so row behavior never diverges between apps (DD-016).
18
+ */
19
+ export declare function ScheduleRowActions({ schedule, onChanged, }: ScheduleRowActionsProps): import("react/jsx-runtime").JSX.Element | null;
20
+ //# sourceMappingURL=ScheduleRowActions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ScheduleRowActions.d.ts","sourceRoot":"","sources":["../../src/schedule/ScheduleRowActions.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,uDAAuD,CAAC;AAOtF,4CAA4C;AAC5C,MAAM,WAAW,uBAAuB;IACtC,wCAAwC;IACxC,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAC5B,gEAAgE;IAChE,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;CACjC;AAED;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CAAC,EACjC,QAAQ,EACR,SAAS,GACV,EAAE,uBAAuB,kDA+DzB"}
@@ -0,0 +1,54 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { cn } from "@stigmer/theme";
4
+ import { ConfirmDialog } from "../resource-detail/ConfirmDialog.js";
5
+ import { useConfirmAction } from "../resource-detail/useConfirmAction.js";
6
+ import { deriveScheduleState } from "./scheduleState.js";
7
+ import { useResumeSchedule } from "./useResumeSchedule.js";
8
+ import { useTriggerSchedule } from "./useTriggerSchedule.js";
9
+ /**
10
+ * Compact per-row actions for a schedule list: **Run now** on an active
11
+ * schedule (confirmation-gated — it starts a real, billable execution)
12
+ * and **Resume** on a platform-paused one. Exactly one action renders
13
+ * at a time — the one that is currently meaningful; an owner-disabled
14
+ * schedule renders neither (its remedy lives on the detail page).
15
+ *
16
+ * Shared by every console's schedule workbench via `renderItemAction`
17
+ * so row behavior never diverges between apps (DD-016).
18
+ */
19
+ export function ScheduleRowActions({ schedule, onChanged, }) {
20
+ const { resumeSchedule, isResuming } = useResumeSchedule();
21
+ const { triggerSchedule, isTriggering } = useTriggerSchedule();
22
+ const { confirmState, confirm, handleConfirm, handleCancel } = useConfirmAction();
23
+ const info = deriveScheduleState(schedule.spec, schedule.status);
24
+ const scheduleId = schedule.metadata?.id ?? "";
25
+ const name = schedule.metadata?.name || schedule.metadata?.slug || "schedule";
26
+ const handleTrigger = async () => {
27
+ const confirmed = await confirm({
28
+ title: "Run this schedule now?",
29
+ description: `"${name}" starts a real agent execution immediately, outside ` +
30
+ "the cron cadence.",
31
+ confirmLabel: "Start run",
32
+ variant: "default",
33
+ });
34
+ if (!confirmed)
35
+ return;
36
+ await triggerSchedule(scheduleId);
37
+ onChanged?.();
38
+ };
39
+ const handleResume = async () => {
40
+ await resumeSchedule(scheduleId);
41
+ onChanged?.();
42
+ };
43
+ if (info.state === "disabled")
44
+ return null;
45
+ return (
46
+ // Row actions must never bubble into the row's navigate-to-detail
47
+ // click handler. The span is a non-interactive event fence — the
48
+ // real interactive element (with keyboard support) is the button.
49
+ _jsxs("span", { onClick: (e) => e.stopPropagation(), children: [info.state === "active" ? (_jsx(RowActionButton, { label: `Run ${name} now`, busy: isTriggering, onClick: () => void handleTrigger(), children: "Run now" })) : (_jsx(RowActionButton, { label: `Resume ${name}`, busy: isResuming, onClick: () => void handleResume(), children: "Resume" })), confirmState && (_jsx(ConfirmDialog, { state: confirmState, onConfirm: handleConfirm, onCancel: handleCancel }))] }));
50
+ }
51
+ function RowActionButton({ label, busy, onClick, children, }) {
52
+ return (_jsx("button", { type: "button", "aria-label": label, onClick: onClick, disabled: busy, className: cn("rounded-md border border-input bg-background px-2 py-1 text-xs font-medium text-foreground", "hover:bg-accent hover:text-accent-foreground", "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring", "disabled:pointer-events-none disabled:opacity-50"), children: children }));
53
+ }
54
+ //# sourceMappingURL=ScheduleRowActions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ScheduleRowActions.js","sourceRoot":"","sources":["../../src/schedule/ScheduleRowActions.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAEb,OAAO,EAAE,EAAE,EAAE,MAAM,gBAAgB,CAAC;AAEpC,OAAO,EAAE,aAAa,EAAE,MAAM,qCAAqC,CAAC;AACpE,OAAO,EAAE,gBAAgB,EAAE,MAAM,wCAAwC,CAAC;AAC1E,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAU7D;;;;;;;;;GASG;AACH,MAAM,UAAU,kBAAkB,CAAC,EACjC,QAAQ,EACR,SAAS,GACe;IACxB,MAAM,EAAE,cAAc,EAAE,UAAU,EAAE,GAAG,iBAAiB,EAAE,CAAC;IAC3D,MAAM,EAAE,eAAe,EAAE,YAAY,EAAE,GAAG,kBAAkB,EAAE,CAAC;IAC/D,MAAM,EAAE,YAAY,EAAE,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,GAC1D,gBAAgB,EAAE,CAAC;IAErB,MAAM,IAAI,GAAG,mBAAmB,CAAC,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;IACjE,MAAM,UAAU,GAAG,QAAQ,CAAC,QAAQ,EAAE,EAAE,IAAI,EAAE,CAAC;IAC/C,MAAM,IAAI,GAAG,QAAQ,CAAC,QAAQ,EAAE,IAAI,IAAI,QAAQ,CAAC,QAAQ,EAAE,IAAI,IAAI,UAAU,CAAC;IAE9E,MAAM,aAAa,GAAG,KAAK,IAAI,EAAE;QAC/B,MAAM,SAAS,GAAG,MAAM,OAAO,CAAC;YAC9B,KAAK,EAAE,wBAAwB;YAC/B,WAAW,EACT,IAAI,IAAI,uDAAuD;gBAC/D,mBAAmB;YACrB,YAAY,EAAE,WAAW;YACzB,OAAO,EAAE,SAAS;SACnB,CAAC,CAAC;QACH,IAAI,CAAC,SAAS;YAAE,OAAO;QACvB,MAAM,eAAe,CAAC,UAAU,CAAC,CAAC;QAClC,SAAS,EAAE,EAAE,CAAC;IAChB,CAAC,CAAC;IAEF,MAAM,YAAY,GAAG,KAAK,IAAI,EAAE;QAC9B,MAAM,cAAc,CAAC,UAAU,CAAC,CAAC;QACjC,SAAS,EAAE,EAAE,CAAC;IAChB,CAAC,CAAC;IAEF,IAAI,IAAI,CAAC,KAAK,KAAK,UAAU;QAAE,OAAO,IAAI,CAAC;IAE3C,OAAO;IACL,kEAAkE;IAClE,iEAAiE;IACjE,kEAAkE;IAClE,gBAAM,OAAO,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,eAAe,EAAE,aACtC,IAAI,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,CACzB,KAAC,eAAe,IACd,KAAK,EAAE,OAAO,IAAI,MAAM,EACxB,IAAI,EAAE,YAAY,EAClB,OAAO,EAAE,GAAG,EAAE,CAAC,KAAK,aAAa,EAAE,wBAGnB,CACnB,CAAC,CAAC,CAAC,CACF,KAAC,eAAe,IACd,KAAK,EAAE,UAAU,IAAI,EAAE,EACvB,IAAI,EAAE,UAAU,EAChB,OAAO,EAAE,GAAG,EAAE,CAAC,KAAK,YAAY,EAAE,uBAGlB,CACnB,EAEA,YAAY,IAAI,CACf,KAAC,aAAa,IACZ,KAAK,EAAE,YAAY,EACnB,SAAS,EAAE,aAAa,EACxB,QAAQ,EAAE,YAAY,GACtB,CACH,IACI,CACR,CAAC;AACJ,CAAC;AAED,SAAS,eAAe,CAAC,EACvB,KAAK,EACL,IAAI,EACJ,OAAO,EACP,QAAQ,GAMT;IACC,OAAO,CACL,iBACE,IAAI,EAAC,QAAQ,gBACD,KAAK,EACjB,OAAO,EAAE,OAAO,EAChB,QAAQ,EAAE,IAAI,EACd,SAAS,EAAE,EAAE,CACX,4FAA4F,EAC5F,8CAA8C,EAC9C,yEAAyE,EACzE,kDAAkD,CACnD,YAEA,QAAQ,GACF,CACV,CAAC;AACJ,CAAC"}
@@ -0,0 +1,32 @@
1
+ /** Props for {@link TimeZoneField}. */
2
+ export interface TimeZoneFieldProps {
3
+ /** Element ID, for association with an external `<label htmlFor>`. */
4
+ readonly id?: string;
5
+ /** The selected IANA time zone name. */
6
+ readonly value: string;
7
+ /** Called with the new zone when the user picks one. */
8
+ readonly onChange: (timeZone: string) => void;
9
+ /** Prevents interaction when `true`. */
10
+ readonly disabled?: boolean;
11
+ }
12
+ /**
13
+ * Searchable IANA time zone selector for the schedule form.
14
+ *
15
+ * The IANA database has ~400 zones — far too many for a plain
16
+ * `<select>` — so this follows the SDK's searchable-picker idiom
17
+ * (search input + listbox, as in `AgentPicker`): the input shows the
18
+ * selected zone; typing filters the list; Enter or click selects.
19
+ *
20
+ * The zone list comes from the runtime's own tz database
21
+ * (`Intl.supportedValuesOf`), which is also what {@link validateTimeZone}
22
+ * checks against — the offered choices and the accepted choices cannot
23
+ * drift.
24
+ *
25
+ * Internal to the schedule folder by design: public API surface is a
26
+ * contract, and this earns a barrel export only when a second consumer
27
+ * appears.
28
+ */
29
+ export declare function TimeZoneField({ id, value, onChange, disabled, }: TimeZoneFieldProps): import("react/jsx-runtime").JSX.Element;
30
+ /** The browser's own IANA time zone — the form's default. */
31
+ export declare function browserTimeZone(): string;
32
+ //# sourceMappingURL=TimeZoneField.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TimeZoneField.d.ts","sourceRoot":"","sources":["../../src/schedule/TimeZoneField.tsx"],"names":[],"mappings":"AAWA,uCAAuC;AACvC,MAAM,WAAW,kBAAkB;IACjC,sEAAsE;IACtE,QAAQ,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC;IACrB,wCAAwC;IACxC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,wDAAwD;IACxD,QAAQ,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IAC9C,wCAAwC;IACxC,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;CAC7B;AAKD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,aAAa,CAAC,EAC5B,EAAE,EACF,KAAK,EACL,QAAQ,EACR,QAAQ,GACT,EAAE,kBAAkB,2CAsIpB;AAaD,6DAA6D;AAC7D,wBAAgB,eAAe,IAAI,MAAM,CAExC"}
@@ -0,0 +1,104 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { useCallback, useMemo, useRef, useState, } from "react";
4
+ import { cn } from "@stigmer/theme";
5
+ const LIST_ID = "stgm-timezone-list";
6
+ const MAX_VISIBLE = 100;
7
+ /**
8
+ * Searchable IANA time zone selector for the schedule form.
9
+ *
10
+ * The IANA database has ~400 zones — far too many for a plain
11
+ * `<select>` — so this follows the SDK's searchable-picker idiom
12
+ * (search input + listbox, as in `AgentPicker`): the input shows the
13
+ * selected zone; typing filters the list; Enter or click selects.
14
+ *
15
+ * The zone list comes from the runtime's own tz database
16
+ * (`Intl.supportedValuesOf`), which is also what {@link validateTimeZone}
17
+ * checks against — the offered choices and the accepted choices cannot
18
+ * drift.
19
+ *
20
+ * Internal to the schedule folder by design: public API surface is a
21
+ * contract, and this earns a barrel export only when a second consumer
22
+ * appears.
23
+ */
24
+ export function TimeZoneField({ id, value, onChange, disabled, }) {
25
+ const zones = useMemo(() => allTimeZones(), []);
26
+ const [query, setQuery] = useState(null);
27
+ const [focusIndex, setFocusIndex] = useState(-1);
28
+ const listRef = useRef(null);
29
+ const isOpen = query !== null;
30
+ const filtered = useMemo(() => {
31
+ if (query === null)
32
+ return [];
33
+ const needle = query.trim().toLowerCase().replace(/\s+/g, "_");
34
+ const matches = needle
35
+ ? zones.filter((z) => z.toLowerCase().includes(needle))
36
+ : zones;
37
+ return matches.slice(0, MAX_VISIBLE);
38
+ }, [zones, query]);
39
+ const close = useCallback(() => {
40
+ setQuery(null);
41
+ setFocusIndex(-1);
42
+ }, []);
43
+ const select = useCallback((zone) => {
44
+ onChange(zone);
45
+ close();
46
+ }, [onChange, close]);
47
+ const handleKeyDown = useCallback((e) => {
48
+ if (e.key === "Escape") {
49
+ e.preventDefault();
50
+ close();
51
+ return;
52
+ }
53
+ if (!isOpen)
54
+ return;
55
+ if (e.key === "ArrowDown") {
56
+ e.preventDefault();
57
+ setFocusIndex((prev) => (prev < filtered.length - 1 ? prev + 1 : prev));
58
+ }
59
+ else if (e.key === "ArrowUp") {
60
+ e.preventDefault();
61
+ setFocusIndex((prev) => (prev > 0 ? prev - 1 : -1));
62
+ }
63
+ else if (e.key === "Enter") {
64
+ e.preventDefault();
65
+ if (focusIndex >= 0 && focusIndex < filtered.length) {
66
+ select(filtered[focusIndex]);
67
+ }
68
+ else if (filtered.length === 1) {
69
+ select(filtered[0]);
70
+ }
71
+ }
72
+ }, [isOpen, filtered, focusIndex, select, close]);
73
+ return (_jsxs("div", { className: "relative", children: [_jsx("input", { id: id, type: "text", role: "combobox", "aria-expanded": isOpen, "aria-controls": LIST_ID, "aria-activedescendant": focusIndex >= 0 ? `stgm-timezone-${focusIndex}` : undefined, "aria-label": "Time zone", placeholder: "Search time zones\u2026", value: query ?? value, onChange: (e) => {
74
+ setQuery(e.target.value);
75
+ setFocusIndex(-1);
76
+ }, onFocus: () => setQuery(""),
77
+ // Closing on blur reverts the input to the committed value —
78
+ // free-typed text is never submitted, only list selections.
79
+ onBlur: close, onKeyDown: handleKeyDown, disabled: disabled, className: cn("w-full rounded-md border border-input bg-background px-2.5 py-1.5 text-xs text-foreground", "placeholder:text-muted-foreground", "focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring", "disabled:pointer-events-none disabled:opacity-50") }), isOpen && (_jsx("div", { ref: listRef, id: LIST_ID, role: "listbox", "aria-label": "Time zones", className: cn("absolute z-popover mt-1 max-h-52 w-full overflow-y-auto rounded-md border border-border", "bg-popover p-1 text-popover-foreground shadow-md"), children: filtered.length === 0 ? (_jsx("div", { className: "py-3 text-center text-xs text-muted-foreground", children: "No time zones match" })) : (filtered.map((zone, idx) => (_jsx("button", { id: `stgm-timezone-${idx}`, type: "button", role: "option", "aria-selected": zone === value,
80
+ // Runs before the input's blur, so selection wins over
81
+ // the close-on-blur revert.
82
+ onMouseDown: (e) => {
83
+ e.preventDefault();
84
+ select(zone);
85
+ }, className: cn("flex w-full items-center rounded-sm px-2 py-1.5 text-left text-xs transition-colors", idx === focusIndex
86
+ ? "bg-accent text-foreground"
87
+ : "text-popover-foreground hover:bg-accent-hover", zone === value && "font-medium"), children: zone }, zone)))) }))] }));
88
+ }
89
+ function allTimeZones() {
90
+ try {
91
+ return Intl.supportedValuesOf("timeZone");
92
+ }
93
+ catch {
94
+ // Pre-2022 runtimes without supportedValuesOf: offer the browser's
95
+ // own zone plus UTC rather than an empty list.
96
+ const own = Intl.DateTimeFormat().resolvedOptions().timeZone;
97
+ return own && own !== "UTC" ? [own, "UTC"] : ["UTC"];
98
+ }
99
+ }
100
+ /** The browser's own IANA time zone — the form's default. */
101
+ export function browserTimeZone() {
102
+ return Intl.DateTimeFormat().resolvedOptions().timeZone || "UTC";
103
+ }
104
+ //# sourceMappingURL=TimeZoneField.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TimeZoneField.js","sourceRoot":"","sources":["../../src/schedule/TimeZoneField.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,95 @@
1
+ /**
2
+ * The cadence model behind {@link CadenceField} — a pure, dependency-free
3
+ * bridge between human-friendly schedule presets and the 5-field cron
4
+ * grammar the Schedule spec stores.
5
+ *
6
+ * Deliberately NOT a cron parser. The platform owns no cron parsing in
7
+ * either edition — calendar and DST semantics live in the Temporal server
8
+ * (see stigmer-server's schedule/controller/cron.go, DD-008 D2). This
9
+ * module only:
10
+ *
11
+ * 1. GENERATES cron strings from presets (`cadenceToCron`) — trivial
12
+ * string construction, always valid by construction.
13
+ * 2. RECOGNIZES the exact shapes the builder emits (`cronToCadence`)
14
+ * so a stored cron round-trips back into the preset UI; anything
15
+ * else falls back to the `custom` preset showing the raw string.
16
+ * 3. MIRRORS the server's purely lexical validation (`validateCron`,
17
+ * `validateTimeZone`) with the same user-facing wording, so the
18
+ * form can reject bad input instantly. The server remains the
19
+ * authority — its errors surface verbatim on submit.
20
+ */
21
+ /** A human-friendly cadence, convertible to/from a cron expression. */
22
+ export type CadencePreset = {
23
+ readonly kind: "hourly";
24
+ readonly minute: number;
25
+ } | {
26
+ readonly kind: "daily";
27
+ readonly hour: number;
28
+ readonly minute: number;
29
+ } | {
30
+ readonly kind: "weekly";
31
+ /** Days of week, cron numbering: 0 = Sunday … 6 = Saturday. */
32
+ readonly days: readonly number[];
33
+ readonly hour: number;
34
+ readonly minute: number;
35
+ } | {
36
+ readonly kind: "monthly";
37
+ /** Day of month, 1–31. Days 29–31 skip months without that day. */
38
+ readonly day: number;
39
+ readonly hour: number;
40
+ readonly minute: number;
41
+ } | {
42
+ readonly kind: "custom";
43
+ readonly cron: string;
44
+ };
45
+ /** Discriminant of {@link CadencePreset}. */
46
+ export type CadenceKind = CadencePreset["kind"];
47
+ /** Day-of-week labels indexed by cron numbering (0 = Sunday). */
48
+ export declare const WEEKDAY_LABELS: readonly ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"];
49
+ /**
50
+ * Build the 5-field cron expression for a preset.
51
+ *
52
+ * Output is always valid by construction: numeric fields only,
53
+ * day-of-week in cron numbering (0 = Sunday). For `custom`, the raw
54
+ * string is returned as-is — validate it with {@link validateCron}.
55
+ */
56
+ export declare function cadenceToCron(preset: CadencePreset): string;
57
+ /**
58
+ * Recognize a cron expression as one of the builder's presets.
59
+ *
60
+ * Only the exact shapes {@link cadenceToCron} emits (plus the
61
+ * calendar shorthands `@hourly`/`@daily`/`@weekly`/`@monthly`) map to a
62
+ * structured preset. Everything else — ranges, steps, names, `@yearly`
63
+ * — is a perfectly valid schedule that this UI simply cannot decompose,
64
+ * so it round-trips as `custom` with the raw string intact.
65
+ */
66
+ export declare function cronToCadence(cron: string): CadencePreset;
67
+ /**
68
+ * Human-readable summary of a cadence, e.g.
69
+ * `"Every day at 09:00 (Asia/Kolkata)"`.
70
+ *
71
+ * This is a description of the chosen preset, not a computed fire-time
72
+ * forecast — the platform's next fire time is published by the server
73
+ * as `status.next_fire_at` after apply.
74
+ */
75
+ export declare function describeCadence(preset: CadencePreset, timeZone?: string): string;
76
+ /** `9, 5` → `"09:05"` (24-hour clock, zero-padded). */
77
+ export declare function formatTime(hour: number, minute: number): string;
78
+ /**
79
+ * Validate a cron expression against the platform's lexical grammar.
80
+ *
81
+ * Returns the user-facing error message (identical wording to the
82
+ * server's) or `null` when the expression is acceptable. Purely
83
+ * lexical — it does not evaluate calendar semantics.
84
+ */
85
+ export declare function validateCron(cron: string): string | null;
86
+ /**
87
+ * Validate an IANA time zone name using the runtime's own tz database
88
+ * (`Intl`), mirroring the server's check against the platform tz
89
+ * database. Returns the user-facing error message or `null`.
90
+ *
91
+ * `"Local"` is rejected explicitly for the same reason the server
92
+ * rejects it: it is host-dependent, not a zone.
93
+ */
94
+ export declare function validateTimeZone(timeZone: string): string | null;
95
+ //# sourceMappingURL=cadence.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cadence.d.ts","sourceRoot":"","sources":["../../src/schedule/cadence.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAMH,uEAAuE;AACvE,MAAM,MAAM,aAAa,GACrB;IAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GACpD;IAAE,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAC1E;IACE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IACxB,+DAA+D;IAC/D,QAAQ,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;IACjC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB,GACD;IACE,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IACzB,mEAAmE;IACnE,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB,GACD;IAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAEvD,6CAA6C;AAC7C,MAAM,MAAM,WAAW,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC;AAEhD,iEAAiE;AACjE,eAAO,MAAM,cAAc,yFAQjB,CAAC;AAMX;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,aAAa,GAAG,MAAM,CAiB3D;AAWD;;;;;;;;GAQG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa,CAsDzD;AAcD;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAC7B,MAAM,EAAE,aAAa,EACrB,QAAQ,CAAC,EAAE,MAAM,GAChB,MAAM,CAoBR;AAED,uDAAuD;AACvD,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAE/D;AA2BD;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAiCxD;AAED;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAShE"}