hermium 0.1.10 → 0.3.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 (216) hide show
  1. package/README.md +56 -0
  2. package/bin/hermium.mjs +201 -136
  3. package/dist/api.mjs +3513 -0
  4. package/dist/{web-server → server}/_chunks/ssr-renderer.mjs +1 -1
  5. package/dist/{web-server → server}/_libs/base-ui__react.mjs +338 -34
  6. package/dist/{web-server → server}/_libs/base-ui__utils.mjs +38 -33
  7. package/dist/server/_libs/comma-separated-tokens.mjs +10 -0
  8. package/dist/{web-server → server}/_libs/floating-ui__core.mjs +3 -3
  9. package/dist/{web-server → server}/_libs/floating-ui__dom.mjs +4 -4
  10. package/dist/{web-server → server}/_libs/floating-ui__react-dom.mjs +3 -3
  11. package/dist/{web-server → server}/_libs/floating-ui__utils.mjs +38 -38
  12. package/dist/{web-server → server}/_libs/h3.mjs +3 -3
  13. package/dist/server/_libs/hast-util-is-element.mjs +75 -0
  14. package/dist/{web-server → server}/_libs/hast-util-to-jsx-runtime.mjs +2 -2
  15. package/dist/server/_libs/hast-util-to-text.mjs +305 -0
  16. package/dist/server/_libs/highlight.js.mjs +14756 -0
  17. package/dist/server/_libs/lowlight.mjs +262 -0
  18. package/dist/{web-server → server}/_libs/mdast-util-from-markdown.mjs +1 -1
  19. package/dist/{web-server → server}/_libs/mdast-util-gfm-autolink-literal+[...].mjs +2 -2
  20. package/dist/{web-server → server}/_libs/mdast-util-to-hast.mjs +1 -1
  21. package/dist/{web-server → server}/_libs/micromark-core-commonmark.mjs +24 -24
  22. package/dist/{web-server → server}/_libs/micromark-extension-gfm-autolink-literal+[...].mjs +1 -1
  23. package/dist/{web-server → server}/_libs/micromark-extension-gfm-footnote+[...].mjs +2 -2
  24. package/dist/{web-server → server}/_libs/micromark-extension-gfm-table.mjs +1 -1
  25. package/dist/{web-server → server}/_libs/micromark-extension-gfm-task-list-item+[...].mjs +1 -1
  26. package/dist/{web-server → server}/_libs/micromark-factory-destination.mjs +1 -1
  27. package/dist/{web-server → server}/_libs/micromark-factory-label.mjs +1 -1
  28. package/dist/{web-server → server}/_libs/micromark-factory-space.mjs +1 -1
  29. package/dist/{web-server → server}/_libs/micromark-factory-whitespace.mjs +1 -1
  30. package/dist/{web-server → server}/_libs/micromark-util-character.mjs +12 -12
  31. package/dist/{web-server → server}/_libs/micromark-util-classify-character+[...].mjs +1 -1
  32. package/dist/{web-server → server}/_libs/micromark-util-html-tag-name.mjs +2 -2
  33. package/dist/{web-server → server}/_libs/micromark-util-sanitize-uri.mjs +1 -1
  34. package/dist/{web-server → server}/_libs/micromark.mjs +3 -3
  35. package/dist/{web-server → server}/_libs/property-information.mjs +2 -3
  36. package/dist/{web-server → server}/_libs/react-dom.mjs +1 -1
  37. package/dist/{web-server → server}/_libs/react.mjs +42 -42
  38. package/dist/server/_libs/rehype-highlight.mjs +94 -0
  39. package/dist/server/_libs/space-separated-tokens.mjs +6 -0
  40. package/dist/server/_libs/tabler__icons-react.mjs +140 -0
  41. package/dist/server/_libs/tailwind-merge.mjs +3255 -0
  42. package/dist/server/_libs/tanstack__history.mjs +29 -0
  43. package/dist/{web-server → server}/_libs/tanstack__react-router.mjs +3 -3
  44. package/dist/{web-server → server}/_libs/tanstack__router-core.mjs +47 -741
  45. package/dist/server/_libs/unist-util-find-after.mjs +41 -0
  46. package/dist/{web-server → server}/_libs/unist-util-position.mjs +2 -2
  47. package/dist/{web-server → server}/_libs/use-sync-external-store.mjs +1 -1
  48. package/dist/server/_libs/zustand.mjs +43 -0
  49. package/dist/server/_ssr/ChatInputBlock-Bu2-iop_.mjs +220 -0
  50. package/dist/server/_ssr/MarkdownMessage-CNS7OSKN.mjs +68 -0
  51. package/dist/server/_ssr/chat._sessionId-P02iSfut.mjs +477 -0
  52. package/dist/{web-server/_ssr/index-CoDfv1vI.mjs → server/_ssr/chat.index-BYB_48NC.mjs} +6 -8
  53. package/dist/server/_ssr/index-C1mT_2d8.mjs +4890 -0
  54. package/dist/server/_ssr/index-DFV9_oCk.mjs +43 -0
  55. package/dist/server/_ssr/memory-CW_fSOG9.mjs +257 -0
  56. package/dist/{web-server/_ssr/router-CS6Zq3md.mjs → server/_ssr/router-CUAfx91O.mjs} +1009 -1108
  57. package/dist/server/_ssr/settings-DoXurzvn.mjs +10 -0
  58. package/dist/server/_ssr/skills-Cs7A5ZwO.mjs +422 -0
  59. package/dist/server/_ssr/theme-BK4-7E2h.mjs +42 -0
  60. package/dist/server/_ssr/usage-Bs2-LXGz.mjs +298 -0
  61. package/dist/server/_tanstack-start-manifest_v-C7Upe2TI.mjs +4 -0
  62. package/dist/server/index.mjs +502 -240
  63. package/package.json +4 -3
  64. package/dist/public/assets/IconAlertCircle-BW147gsG.js +0 -1
  65. package/dist/public/assets/IconAlertTriangle-DCoTLVSd.js +0 -1
  66. package/dist/public/assets/IconCheck-DAO7Fpl9.js +0 -1
  67. package/dist/public/assets/IconCode-BqfTl5wU.js +0 -1
  68. package/dist/public/assets/IconLoader2-B_pehSXN.js +0 -1
  69. package/dist/public/assets/IconRefresh-BbMGoMV8.js +0 -1
  70. package/dist/public/assets/geist-cyrillic-wght-normal-CHSlOQsW.woff2 +0 -0
  71. package/dist/public/assets/geist-latin-ext-wght-normal-DMtmJ5ZE.woff2 +0 -0
  72. package/dist/public/assets/geist-latin-wght-normal-Dm3htQBi.woff2 +0 -0
  73. package/dist/public/assets/index-BL9a2Xg9.js +0 -1
  74. package/dist/public/assets/index-BSwXjgjr.js +0 -1
  75. package/dist/public/assets/index-BWl8tn18.js +0 -1
  76. package/dist/public/assets/index-CQh8SXb2.js +0 -94
  77. package/dist/public/assets/index-Cxd-kSUY.js +0 -1
  78. package/dist/public/assets/index-DA5SH--7.js +0 -2
  79. package/dist/public/assets/index-DCHbvtBS.js +0 -1
  80. package/dist/public/assets/index-DCYXJZEe.js +0 -1
  81. package/dist/public/assets/index-DFDfp0ca.js +0 -1
  82. package/dist/public/assets/index-GuAAqSCJ.js +0 -14
  83. package/dist/public/assets/index-WIDirTHx.js +0 -29
  84. package/dist/public/assets/index-X3XZcAzy.js +0 -1
  85. package/dist/public/assets/input-7TQEEJq6.js +0 -1
  86. package/dist/public/assets/inter-cyrillic-ext-wght-normal-BOeWTOD4.woff2 +0 -0
  87. package/dist/public/assets/inter-cyrillic-wght-normal-DqGufNeO.woff2 +0 -0
  88. package/dist/public/assets/inter-greek-ext-wght-normal-DlzME5K_.woff2 +0 -0
  89. package/dist/public/assets/inter-greek-wght-normal-CkhJZR-_.woff2 +0 -0
  90. package/dist/public/assets/inter-latin-ext-wght-normal-DO1Apj_S.woff2 +0 -0
  91. package/dist/public/assets/inter-latin-wght-normal-Dx4kXJAl.woff2 +0 -0
  92. package/dist/public/assets/inter-vietnamese-wght-normal-CBcvBZtf.woff2 +0 -0
  93. package/dist/public/assets/models-BlUb1eaf.js +0 -1
  94. package/dist/public/assets/styles-PHtUFHUr.css +0 -1
  95. package/dist/public/assets/switch-B_iYUUM3.js +0 -1
  96. package/dist/public/assets/syntax-highlighter-DcBYfnEK.js +0 -6
  97. package/dist/public/assets/textarea-Dm4aaRqS.js +0 -1
  98. package/dist/public/favicon.ico +0 -0
  99. package/dist/public/favicon.png +0 -0
  100. package/dist/public/manifest.json +0 -25
  101. package/dist/public/nous-logo.png +0 -0
  102. package/dist/public/robots.txt +0 -3
  103. package/dist/web-server/_libs/babel__runtime.mjs +0 -237
  104. package/dist/web-server/_libs/character-entities-legacy.mjs +0 -111
  105. package/dist/web-server/_libs/character-reference-invalid.mjs +0 -33
  106. package/dist/web-server/_libs/comma-separated-tokens.mjs +0 -31
  107. package/dist/web-server/_libs/cookie-es.mjs +0 -44
  108. package/dist/web-server/_libs/hast-util-parse-selector.mjs +0 -39
  109. package/dist/web-server/_libs/hastscript.mjs +0 -200
  110. package/dist/web-server/_libs/is-alphabetical.mjs +0 -7
  111. package/dist/web-server/_libs/is-alphanumerical.mjs +0 -8
  112. package/dist/web-server/_libs/is-decimal.mjs +0 -7
  113. package/dist/web-server/_libs/is-hexadecimal.mjs +0 -7
  114. package/dist/web-server/_libs/lowlight.mjs +0 -1
  115. package/dist/web-server/_libs/parse-entities.mjs +0 -245
  116. package/dist/web-server/_libs/react-syntax-highlighter.mjs +0 -941
  117. package/dist/web-server/_libs/refractor.mjs +0 -2425
  118. package/dist/web-server/_libs/seroval-plugins.mjs +0 -58
  119. package/dist/web-server/_libs/seroval.mjs +0 -1775
  120. package/dist/web-server/_libs/space-separated-tokens.mjs +0 -11
  121. package/dist/web-server/_libs/tabler__icons-react.mjs +0 -233
  122. package/dist/web-server/_libs/tanstack__history.mjs +0 -204
  123. package/dist/web-server/_libs/tanstack__query-core.mjs +0 -2552
  124. package/dist/web-server/_libs/tanstack__react-query.mjs +0 -190
  125. package/dist/web-server/_libs/zod.mjs +0 -3915
  126. package/dist/web-server/_libs/zustand.mjs +0 -343
  127. package/dist/web-server/_ssr/index--Bo2_ipW.mjs +0 -277
  128. package/dist/web-server/_ssr/index-BEvygh5x.mjs +0 -612
  129. package/dist/web-server/_ssr/index-BFaKxYfN.mjs +0 -40
  130. package/dist/web-server/_ssr/index-BdrMzRTd.mjs +0 -513
  131. package/dist/web-server/_ssr/index-Cwp8Gyl1.mjs +0 -1812
  132. package/dist/web-server/_ssr/index-DQsfKYjV.mjs +0 -449
  133. package/dist/web-server/_ssr/index-Dbs9k8Ea.mjs +0 -251
  134. package/dist/web-server/_ssr/index-Dk93oyZD.mjs +0 -213
  135. package/dist/web-server/_ssr/index-KNJ7huw_.mjs +0 -369
  136. package/dist/web-server/_ssr/index.mjs +0 -1558
  137. package/dist/web-server/_ssr/input-BV1DMASc.mjs +0 -20
  138. package/dist/web-server/_ssr/models-MzrvbL2i.mjs +0 -43
  139. package/dist/web-server/_ssr/start-HYkvq4Ni.mjs +0 -4
  140. package/dist/web-server/_ssr/switch-Bd-Sg0HG.mjs +0 -33
  141. package/dist/web-server/_ssr/syntax-highlighter-5vezNTce.mjs +0 -62
  142. package/dist/web-server/_ssr/textarea-CB4kQp9w.mjs +0 -18
  143. package/dist/web-server/_tanstack-start-manifest_v-m5lY48LR.mjs +0 -4
  144. package/dist/web-server/index.mjs +0 -611
  145. /package/dist/{web-server → server}/__23tanstack-start-plugin-adapters-Cwee5PKy.mjs +0 -0
  146. /package/dist/{web-server → server}/_libs/bail.mjs +0 -0
  147. /package/dist/{web-server → server}/_libs/ccount.mjs +0 -0
  148. /package/dist/{web-server → server}/_libs/character-entities.mjs +0 -0
  149. /package/dist/{web-server → server}/_libs/class-variance-authority.mjs +0 -0
  150. /package/dist/{web-server → server}/_libs/clsx.mjs +0 -0
  151. /package/dist/{web-server/_libs/croner.mjs → server/_libs/cookie-es.mjs} +0 -0
  152. /package/dist/{web-server/_libs/crossws.mjs → server/_libs/croner.mjs} +0 -0
  153. /package/dist/{web-server/_libs/fault.mjs → server/_libs/crossws.mjs} +0 -0
  154. /package/dist/{web-server → server}/_libs/decode-named-character-reference+[...].mjs +0 -0
  155. /package/dist/{web-server → server}/_libs/devlop.mjs +0 -0
  156. /package/dist/{web-server → server}/_libs/escape-string-regexp.mjs +0 -0
  157. /package/dist/{web-server → server}/_libs/estree-util-is-identifier-name.mjs +0 -0
  158. /package/dist/{web-server → server}/_libs/extend.mjs +0 -0
  159. /package/dist/{web-server → server}/_libs/hast-util-whitespace.mjs +0 -0
  160. /package/dist/{web-server → server}/_libs/hookable.mjs +0 -0
  161. /package/dist/{web-server → server}/_libs/html-url-attributes.mjs +0 -0
  162. /package/dist/{web-server → server}/_libs/inline-style-parser.mjs +0 -0
  163. /package/dist/{web-server → server}/_libs/is-plain-obj.mjs +0 -0
  164. /package/dist/{web-server → server}/_libs/isbot.mjs +0 -0
  165. /package/dist/{web-server → server}/_libs/longest-streak.mjs +0 -0
  166. /package/dist/{web-server → server}/_libs/markdown-table.mjs +0 -0
  167. /package/dist/{web-server → server}/_libs/mdast-util-find-and-replace.mjs +0 -0
  168. /package/dist/{web-server → server}/_libs/mdast-util-gfm-footnote.mjs +0 -0
  169. /package/dist/{web-server → server}/_libs/mdast-util-gfm-strikethrough.mjs +0 -0
  170. /package/dist/{web-server → server}/_libs/mdast-util-gfm-table.mjs +0 -0
  171. /package/dist/{web-server → server}/_libs/mdast-util-gfm-task-list-item.mjs +0 -0
  172. /package/dist/{web-server → server}/_libs/mdast-util-gfm.mjs +0 -0
  173. /package/dist/{web-server → server}/_libs/mdast-util-phrasing.mjs +0 -0
  174. /package/dist/{web-server → server}/_libs/mdast-util-to-markdown.mjs +0 -0
  175. /package/dist/{web-server → server}/_libs/mdast-util-to-string.mjs +0 -0
  176. /package/dist/{web-server → server}/_libs/micromark-extension-gfm-strikethrough+[...].mjs +0 -0
  177. /package/dist/{web-server → server}/_libs/micromark-extension-gfm-tagfilter+[...].mjs +0 -0
  178. /package/dist/{web-server → server}/_libs/micromark-extension-gfm.mjs +0 -0
  179. /package/dist/{web-server → server}/_libs/micromark-factory-title.mjs +0 -0
  180. /package/dist/{web-server → server}/_libs/micromark-util-chunked.mjs +0 -0
  181. /package/dist/{web-server → server}/_libs/micromark-util-combine-extensions+[...].mjs +0 -0
  182. /package/dist/{web-server → server}/_libs/micromark-util-decode-numeric-character-reference+[...].mjs +0 -0
  183. /package/dist/{web-server → server}/_libs/micromark-util-decode-string.mjs +0 -0
  184. /package/dist/{web-server → server}/_libs/micromark-util-encode.mjs +0 -0
  185. /package/dist/{web-server → server}/_libs/micromark-util-normalize-identifier+[...].mjs +0 -0
  186. /package/dist/{web-server → server}/_libs/micromark-util-resolve-all.mjs +0 -0
  187. /package/dist/{web-server → server}/_libs/micromark-util-subtokenize.mjs +0 -0
  188. /package/dist/{web-server → server}/_libs/ocache.mjs +0 -0
  189. /package/dist/{web-server → server}/_libs/ohash.mjs +0 -0
  190. /package/dist/{web-server → server}/_libs/react-markdown.mjs +0 -0
  191. /package/dist/{web-server → server}/_libs/remark-gfm.mjs +0 -0
  192. /package/dist/{web-server → server}/_libs/remark-parse.mjs +0 -0
  193. /package/dist/{web-server → server}/_libs/remark-rehype.mjs +0 -0
  194. /package/dist/{web-server → server}/_libs/reselect.mjs +0 -0
  195. /package/dist/{web-server → server}/_libs/rou3.mjs +0 -0
  196. /package/dist/{web-server/_libs/format.mjs → server/_libs/seroval-plugins.mjs} +0 -0
  197. /package/dist/{web-server/_libs/highlight.js.mjs → server/_libs/seroval.mjs} +0 -0
  198. /package/dist/{web-server → server}/_libs/srvx.mjs +0 -0
  199. /package/dist/{web-server → server}/_libs/style-to-js.mjs +0 -0
  200. /package/dist/{web-server → server}/_libs/style-to-object.mjs +0 -0
  201. /package/dist/{web-server → server}/_libs/tanstack__react-store.mjs +0 -0
  202. /package/dist/{web-server → server}/_libs/tanstack__store.mjs +0 -0
  203. /package/dist/{web-server → server}/_libs/trim-lines.mjs +0 -0
  204. /package/dist/{web-server → server}/_libs/trough.mjs +0 -0
  205. /package/dist/{web-server → server}/_libs/ufo.mjs +0 -0
  206. /package/dist/{web-server → server}/_libs/unctx.mjs +0 -0
  207. /package/dist/{web-server → server}/_libs/ungap__structured-clone.mjs +0 -0
  208. /package/dist/{web-server → server}/_libs/unified.mjs +0 -0
  209. /package/dist/{web-server → server}/_libs/unist-util-is.mjs +0 -0
  210. /package/dist/{web-server → server}/_libs/unist-util-stringify-position.mjs +0 -0
  211. /package/dist/{web-server → server}/_libs/unist-util-visit-parents.mjs +0 -0
  212. /package/dist/{web-server → server}/_libs/unist-util-visit.mjs +0 -0
  213. /package/dist/{web-server → server}/_libs/unstorage.mjs +0 -0
  214. /package/dist/{web-server → server}/_libs/vfile-message.mjs +0 -0
  215. /package/dist/{web-server → server}/_libs/vfile.mjs +0 -0
  216. /package/dist/{web-server → server}/_libs/zwitch.mjs +0 -0
@@ -1,612 +0,0 @@
1
- import { r as reactExports, j as jsxRuntimeExports } from "../_libs/react.mjs";
2
- import { u as useQueryClient, b as useMutation, a as useQuery } from "../_libs/tanstack__react-query.mjs";
3
- import { B as Button, a as cn, d as patch, p as post, e as del, g as get } from "./router-CS6Zq3md.mjs";
4
- import { I as Input } from "./input-BV1DMASc.mjs";
5
- import { T as Textarea } from "./textarea-CB4kQp9w.mjs";
6
- import { Q as IconPlus, D as IconRefresh, R as IconClock, S as IconPower, s as IconPencil, v as IconTrash, T as IconPlayerPlay, U as IconCalendar, V as IconChevronRight, E as IconLoader2 } from "../_libs/tabler__icons-react.mjs";
7
- import "../_libs/tanstack__query-core.mjs";
8
- import "../_libs/tanstack__react-router.mjs";
9
- import "../_libs/tanstack__router-core.mjs";
10
- import "../_libs/tanstack__history.mjs";
11
- import "../_libs/cookie-es.mjs";
12
- import "../_libs/seroval.mjs";
13
- import "../_libs/seroval-plugins.mjs";
14
- import "node:stream/web";
15
- import "node:stream";
16
- import "../_libs/react-dom.mjs";
17
- import "util";
18
- import "crypto";
19
- import "async_hooks";
20
- import "stream";
21
- import "../_libs/isbot.mjs";
22
- import "../_libs/clsx.mjs";
23
- import "../_libs/class-variance-authority.mjs";
24
- import "../_libs/zustand.mjs";
25
- import "../_libs/base-ui__react.mjs";
26
- import "../_libs/base-ui__utils.mjs";
27
- import "../_libs/use-sync-external-store.mjs";
28
- import "../_libs/floating-ui__utils.mjs";
29
- import "../_libs/floating-ui__react-dom.mjs";
30
- import "../_libs/floating-ui__dom.mjs";
31
- import "../_libs/floating-ui__core.mjs";
32
- import "../_libs/zod.mjs";
33
- const DialogContext = reactExports.createContext(null);
34
- function useDialog() {
35
- const ctx = reactExports.useContext(DialogContext);
36
- if (!ctx) throw new Error("Dialog components must be used within <Dialog>");
37
- return ctx;
38
- }
39
- function Dialog({
40
- open,
41
- onOpenChange,
42
- children
43
- }) {
44
- const setOpen = reactExports.useCallback(
45
- (v) => onOpenChange(v),
46
- [onOpenChange]
47
- );
48
- reactExports.useEffect(() => {
49
- if (!open) return;
50
- const handleEsc = (e) => {
51
- if (e.key === "Escape") setOpen(false);
52
- };
53
- document.addEventListener("keydown", handleEsc);
54
- return () => document.removeEventListener("keydown", handleEsc);
55
- }, [open, setOpen]);
56
- if (!open) return null;
57
- return /* @__PURE__ */ jsxRuntimeExports.jsxs(DialogContext.Provider, { value: { open, setOpen }, children: [
58
- /* @__PURE__ */ jsxRuntimeExports.jsx(
59
- "div",
60
- {
61
- className: "fixed inset-0 z-50 bg-black/40 backdrop-blur-sm",
62
- onClick: () => setOpen(false)
63
- }
64
- ),
65
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "fixed inset-0 z-50 flex items-center justify-center p-4", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
66
- "div",
67
- {
68
- className: "relative w-full max-w-lg rounded-xl border border-border bg-card shadow-xl",
69
- onClick: (e) => e.stopPropagation(),
70
- children
71
- }
72
- ) })
73
- ] });
74
- }
75
- function DialogContent({ children, className }) {
76
- useDialog();
77
- return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: cn("p-5", className), children });
78
- }
79
- function DialogHeader({ children, className }) {
80
- return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: cn("mb-4", className), children });
81
- }
82
- function DialogTitle({ children, className }) {
83
- return /* @__PURE__ */ jsxRuntimeExports.jsx("h2", { className: cn("text-base font-semibold", className), children });
84
- }
85
- function DialogFooter({ children, className }) {
86
- return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: cn("flex items-center justify-end gap-2 mt-4", className), children });
87
- }
88
- function jobId(job) {
89
- return job.job_id || job.id || "";
90
- }
91
- function jobName(job) {
92
- return job.name || jobId(job) || "Untitled";
93
- }
94
- function describeCron(cron) {
95
- const parts = cron.trim().split(/\s+/);
96
- if (parts.length < 2) return cron;
97
- const minute = parseInt(parts[0], 10);
98
- const hour = parseInt(parts[1], 10);
99
- if (isNaN(minute) || isNaN(hour)) return cron;
100
- if (parts[1] === "*") {
101
- return `At minute ${minute} past every hour`;
102
- }
103
- const timeStr = new Date(0, 0, 0, hour, minute).toLocaleTimeString([], {
104
- hour: "numeric",
105
- minute: "2-digit",
106
- hour12: true
107
- });
108
- if (parts.length >= 5) {
109
- const dayField = parts.slice(2, 5).join(" ");
110
- if (dayField === "* * 1-5") return `${timeStr} weekdays`;
111
- if (dayField === "* * 0,6") return `${timeStr} weekends`;
112
- }
113
- return `${timeStr} daily`;
114
- }
115
- function scheduleText(schedule) {
116
- if (!schedule) return "—";
117
- if (typeof schedule === "string") return describeCron(schedule);
118
- const raw = schedule.display || schedule.expr || JSON.stringify(schedule);
119
- return describeCron(raw);
120
- }
121
- function formatSize(bytes) {
122
- if (bytes < 1024) return `${bytes}B`;
123
- if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)}KB`;
124
- return `${(bytes / 1024 / 1024).toFixed(1)}MB`;
125
- }
126
- function timeAgo(iso) {
127
- const d = new Date(iso);
128
- const diff = Date.now() - d.getTime();
129
- const mins = Math.floor(diff / 6e4);
130
- if (mins < 1) return "just now";
131
- if (mins < 60) return `${mins}m ago`;
132
- const hrs = Math.floor(mins / 60);
133
- if (hrs < 24) return `${hrs}h ago`;
134
- return `${Math.floor(hrs / 24)}d ago`;
135
- }
136
- function formatTime(iso) {
137
- return new Date(iso).toLocaleString(void 0, {
138
- month: "short",
139
- day: "numeric",
140
- hour: "2-digit",
141
- minute: "2-digit"
142
- });
143
- }
144
- function useJobs() {
145
- return useQuery({
146
- queryKey: ["cron", "jobs"],
147
- queryFn: () => get("/api/cron-history/jobs"),
148
- refetchInterval: 3e4
149
- });
150
- }
151
- function useCronRuns(jobId2) {
152
- return useQuery({
153
- queryKey: ["cron", "runs", jobId2],
154
- queryFn: () => get(
155
- `/api/cron-history${""}`
156
- ),
157
- refetchInterval: 15e3
158
- });
159
- }
160
- function toCron(hour, minute, dayMode) {
161
- if (dayMode === "hourly") return `${minute} * * * *`;
162
- const base = `${minute} ${hour}`;
163
- if (dayMode === "weekdays") return `${base} * * 1-5`;
164
- if (dayMode === "weekends") return `${base} * * 0,6`;
165
- return `${base} * * *`;
166
- }
167
- function describeSchedule(hour, minute, dayMode) {
168
- if (dayMode === "hourly") return `At minute ${minute} past every hour`;
169
- const timeStr = new Date(0, 0, 0, hour, minute).toLocaleTimeString([], {
170
- hour: "numeric",
171
- minute: "2-digit",
172
- hour12: true
173
- });
174
- const suffix = dayMode === "weekdays" ? "on weekdays" : dayMode === "weekends" ? "on weekends" : "daily";
175
- return `Runs ${timeStr} ${suffix}`;
176
- }
177
- const PRESETS = [
178
- { label: "Every hour", dayMode: "hourly", hour: 0, minute: 0 },
179
- { label: "Daily 9AM", dayMode: "daily", hour: 9, minute: 0 },
180
- { label: "Daily noon", dayMode: "daily", hour: 12, minute: 0 },
181
- { label: "Daily 6PM", dayMode: "daily", hour: 18, minute: 0 },
182
- { label: "Weekdays 9AM", dayMode: "weekdays", hour: 9, minute: 0 },
183
- { label: "Weekdays noon", dayMode: "weekdays", hour: 12, minute: 0 }
184
- ];
185
- function SchedulePicker({
186
- value,
187
- onChange
188
- }) {
189
- const [dayMode, setDayMode] = reactExports.useState("daily");
190
- const [hour, setHour] = reactExports.useState(9);
191
- const [minute, setMinute] = reactExports.useState(0);
192
- const [showRaw, setShowRaw] = reactExports.useState(false);
193
- const [rawCron, setRawCron] = reactExports.useState(value || "");
194
- const parsed = reactExports.useMemo(() => {
195
- if (!value) return null;
196
- const parts = value.trim().split(/\s+/);
197
- if (parts.length < 2) return null;
198
- const m = parseInt(parts[0], 10);
199
- const h = parseInt(parts[1], 10);
200
- if (isNaN(m) || isNaN(h)) return null;
201
- return { hour: h, minute: m };
202
- }, []);
203
- const initialized = reactExports.useRef(false);
204
- reactExports.useEffect(() => {
205
- if (initialized.current || !parsed) return;
206
- initialized.current = true;
207
- setHour(parsed.hour);
208
- setMinute(parsed.minute);
209
- const parts = value.trim().split(/\s+/);
210
- if (parts.length >= 5) {
211
- const dayField = parts.slice(2, 5).join(" ");
212
- if (dayField === "* * 1-5") setDayMode("weekdays");
213
- else if (dayField === "* * 0,6") setDayMode("weekends");
214
- else if (dayField === "* * *" || parts[2] === "*") setDayMode("daily");
215
- if (parts[1] === "*") setDayMode("hourly");
216
- }
217
- setRawCron(value);
218
- }, [parsed, value]);
219
- const cronExpr = reactExports.useMemo(() => toCron(hour, minute, dayMode), [hour, minute, dayMode]);
220
- const description = reactExports.useMemo(() => describeSchedule(hour, minute, dayMode), [hour, minute, dayMode]);
221
- const handleTimeChange = (e) => {
222
- const [h, m] = e.target.value.split(":").map(Number);
223
- if (!isNaN(h)) setHour(h);
224
- if (!isNaN(m)) setMinute(m);
225
- if (dayMode === "hourly") setDayMode("daily");
226
- };
227
- const handlePreset = (preset) => {
228
- setHour(preset.hour);
229
- setMinute(preset.minute);
230
- setDayMode(preset.dayMode);
231
- };
232
- const handleRawChange = (e) => {
233
- setRawCron(e.target.value);
234
- };
235
- const effectiveCron = showRaw ? rawCron : cronExpr;
236
- reactExports.useEffect(() => {
237
- onChange(effectiveCron);
238
- }, [effectiveCron]);
239
- return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-3", children: [
240
- /* @__PURE__ */ jsxRuntimeExports.jsx("label", { className: "text-xs font-medium text-muted-foreground mb-1 block", children: "Schedule" }),
241
- !showRaw ? /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
242
- /* @__PURE__ */ jsxRuntimeExports.jsx(
243
- "input",
244
- {
245
- type: "time",
246
- value: `${String(hour).padStart(2, "0")}:${String(minute).padStart(2, "0")}`,
247
- onChange: handleTimeChange,
248
- className: "flex h-10 w-full rounded-lg border border-input bg-background px-3 py-2 text-sm shadow-xs focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50"
249
- }
250
- ),
251
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex rounded-lg border border-border overflow-hidden text-xs font-medium", children: [
252
- { value: "daily", label: "Every day" },
253
- { value: "weekdays", label: "Weekdays" },
254
- { value: "weekends", label: "Weekends" }
255
- ].map((d, i) => /* @__PURE__ */ jsxRuntimeExports.jsx(
256
- "button",
257
- {
258
- type: "button",
259
- onClick: () => setDayMode(d.value),
260
- className: cn(
261
- "flex-1 px-3 py-1.5 transition-colors text-center",
262
- i > 0 && "border-l border-border",
263
- dayMode === d.value ? "bg-primary text-primary-foreground font-semibold" : "bg-background text-muted-foreground hover:bg-muted"
264
- ),
265
- children: d.label
266
- },
267
- d.value
268
- )) }),
269
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex flex-wrap gap-1.5", children: PRESETS.map((p) => /* @__PURE__ */ jsxRuntimeExports.jsx(
270
- "button",
271
- {
272
- type: "button",
273
- onClick: () => handlePreset(p),
274
- className: cn(
275
- "px-2.5 py-1 rounded-md text-[11px] font-medium transition-colors",
276
- hour === p.hour && minute === p.minute && dayMode === p.dayMode ? "bg-emerald-500/10 text-emerald-600 border border-emerald-500/20 shadow-xs" : "bg-muted/50 text-muted-foreground border border-border/50 hover:bg-muted hover:text-foreground"
277
- ),
278
- children: p.label
279
- },
280
- p.label
281
- )) }),
282
- /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "text-xs text-muted-foreground flex items-center gap-1.5", children: [
283
- /* @__PURE__ */ jsxRuntimeExports.jsx(IconClock, { className: "h-3.5 w-3.5" }),
284
- description
285
- ] }),
286
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between", children: [
287
- /* @__PURE__ */ jsxRuntimeExports.jsx("code", { className: "text-[11px] text-muted-foreground/60 font-mono", children: cronExpr }),
288
- /* @__PURE__ */ jsxRuntimeExports.jsx(
289
- "button",
290
- {
291
- type: "button",
292
- onClick: () => {
293
- setRawCron(cronExpr);
294
- setShowRaw(true);
295
- },
296
- className: "text-[10px] text-muted-foreground/40 hover:text-muted-foreground underline underline-offset-2 transition-colors",
297
- children: "Raw cron"
298
- }
299
- )
300
- ] })
301
- ] }) : /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-2", children: [
302
- /* @__PURE__ */ jsxRuntimeExports.jsx(
303
- Input,
304
- {
305
- value: rawCron,
306
- onChange: handleRawChange,
307
- placeholder: "0 9 * * *",
308
- className: "h-9 text-sm font-mono"
309
- }
310
- ),
311
- /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "text-[10px] text-muted-foreground flex items-center gap-1.5", children: [
312
- "minute hour day month weekday",
313
- /* @__PURE__ */ jsxRuntimeExports.jsx(
314
- "button",
315
- {
316
- type: "button",
317
- onClick: () => setShowRaw(false),
318
- className: "underline underline-offset-2 hover:text-foreground ml-auto transition-colors",
319
- children: "Use time picker"
320
- }
321
- )
322
- ] })
323
- ] })
324
- ] });
325
- }
326
- function StatusDot({ status }) {
327
- if (!status) return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-2 w-2 rounded-full bg-muted-foreground/30" });
328
- const ok = status === "ok" || status === "success" || status === "completed";
329
- return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: cn("h-2 w-2 rounded-full", ok ? "bg-emerald-500" : "bg-red-500") });
330
- }
331
- function JobCard({
332
- job,
333
- onEdit,
334
- onDelete,
335
- onToggle
336
- }) {
337
- return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: cn(
338
- "rounded-xl border bg-card p-5 transition-colors group relative",
339
- job.enabled !== false ? "border-border hover:border-emerald-500/30" : "border-border opacity-60"
340
- ), children: [
341
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "absolute top-3 right-3 flex items-center gap-0.5 opacity-0 group-hover:opacity-100 transition-opacity", children: [
342
- /* @__PURE__ */ jsxRuntimeExports.jsx(
343
- Button,
344
- {
345
- variant: "ghost",
346
- size: "icon-sm",
347
- className: "h-7 w-7",
348
- onClick: (e) => {
349
- e.stopPropagation();
350
- onToggle();
351
- },
352
- title: job.enabled !== false ? "Disable" : "Enable",
353
- children: /* @__PURE__ */ jsxRuntimeExports.jsx(IconPower, { className: cn("h-3.5 w-3.5", job.enabled !== false ? "text-emerald-500" : "text-muted-foreground") })
354
- }
355
- ),
356
- /* @__PURE__ */ jsxRuntimeExports.jsx(
357
- Button,
358
- {
359
- variant: "ghost",
360
- size: "icon-sm",
361
- className: "h-7 w-7",
362
- onClick: (e) => {
363
- e.stopPropagation();
364
- onEdit();
365
- },
366
- title: "Edit",
367
- children: /* @__PURE__ */ jsxRuntimeExports.jsx(IconPencil, { className: "h-3.5 w-3.5 text-muted-foreground" })
368
- }
369
- ),
370
- /* @__PURE__ */ jsxRuntimeExports.jsx(
371
- Button,
372
- {
373
- variant: "ghost",
374
- size: "icon-sm",
375
- className: "h-7 w-7 hover:text-red-500",
376
- onClick: (e) => {
377
- e.stopPropagation();
378
- onDelete();
379
- },
380
- title: "Delete",
381
- children: /* @__PURE__ */ jsxRuntimeExports.jsx(IconTrash, { className: "h-3.5 w-3.5 text-muted-foreground" })
382
- }
383
- )
384
- ] }),
385
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-start justify-between gap-3 mb-3", children: [
386
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2.5 min-w-0", children: [
387
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: cn(
388
- "h-8 w-8 rounded-lg flex items-center justify-center shrink-0",
389
- job.enabled !== false ? "bg-emerald-500/10 text-emerald-600" : "bg-muted text-muted-foreground"
390
- ), children: /* @__PURE__ */ jsxRuntimeExports.jsx(IconClock, { className: "h-4 w-4" }) }),
391
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "min-w-0", children: [
392
- /* @__PURE__ */ jsxRuntimeExports.jsx("h3", { className: "text-sm font-semibold truncate pr-20", children: jobName(job) }),
393
- /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-[11px] text-muted-foreground font-mono", children: scheduleText(job.schedule) })
394
- ] })
395
- ] }),
396
- /* @__PURE__ */ jsxRuntimeExports.jsx(StatusDot, { status: job.last_status })
397
- ] }),
398
- job.prompt && /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-muted-foreground leading-relaxed line-clamp-2 mb-3", children: job.prompt }),
399
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-4 text-[11px] text-muted-foreground", children: [
400
- job.run_count != null && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "flex items-center gap-1", children: [
401
- /* @__PURE__ */ jsxRuntimeExports.jsx(IconPlayerPlay, { className: "h-3 w-3" }),
402
- job.run_count,
403
- " runs"
404
- ] }),
405
- job.next_run_at && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "flex items-center gap-1", children: [
406
- /* @__PURE__ */ jsxRuntimeExports.jsx(IconCalendar, { className: "h-3 w-3" }),
407
- "Next: ",
408
- formatTime(job.next_run_at)
409
- ] }),
410
- job.last_run_at && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: timeAgo(job.last_run_at) })
411
- ] })
412
- ] });
413
- }
414
- function RunRow({ run }) {
415
- const [open, setOpen] = reactExports.useState(false);
416
- const detail = useQuery({
417
- queryKey: ["cron", "run", run.jobId, run.fileName],
418
- queryFn: () => get(
419
- `/api/cron-history/${encodeURIComponent(run.jobId)}/${encodeURIComponent(run.fileName)}`
420
- ),
421
- enabled: open
422
- });
423
- return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "border-b border-border/50 last:border-b-0", children: [
424
- /* @__PURE__ */ jsxRuntimeExports.jsxs(
425
- "button",
426
- {
427
- onClick: () => setOpen(!open),
428
- className: "flex w-full items-center gap-3 px-4 py-2.5 text-left hover:bg-muted/30 transition-colors group",
429
- children: [
430
- /* @__PURE__ */ jsxRuntimeExports.jsx(IconChevronRight, { className: cn("h-3.5 w-3.5 shrink-0 text-muted-foreground transition-transform", open && "rotate-90") }),
431
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs font-medium text-foreground/80 min-w-[80px]", children: run.jobId }),
432
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs text-muted-foreground flex-1", children: run.runTime }),
433
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-[10px] text-muted-foreground/60 font-mono shrink-0", children: formatSize(run.size) })
434
- ]
435
- }
436
- ),
437
- open && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "px-4 pb-4 pl-10", children: detail.isLoading ? /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 py-3 text-muted-foreground text-xs", children: [
438
- /* @__PURE__ */ jsxRuntimeExports.jsx(IconLoader2, { className: "h-3.5 w-3.5 animate-spin" }),
439
- "Loading..."
440
- ] }) : /* @__PURE__ */ jsxRuntimeExports.jsx("pre", { className: "text-[12px] font-mono leading-relaxed whitespace-pre-wrap text-foreground/80 bg-muted/30 rounded-lg p-3 border border-border/50 max-h-[400px] overflow-auto", children: detail.data?.content || "No output" }) })
441
- ] });
442
- }
443
- function AutomationsPage() {
444
- const queryClient = useQueryClient();
445
- const jobs = useJobs();
446
- const runs = useCronRuns(null);
447
- const [showForm, setShowForm] = reactExports.useState(false);
448
- const [editingJob, setEditingJob] = reactExports.useState(null);
449
- const [formName, setFormName] = reactExports.useState("");
450
- const [formSchedule, setFormSchedule] = reactExports.useState("");
451
- const [formPrompt, setFormPrompt] = reactExports.useState("");
452
- const refresh = reactExports.useCallback(() => {
453
- jobs.refetch();
454
- runs.refetch();
455
- }, [jobs, runs]);
456
- const createMut = useMutation({
457
- mutationFn: (data) => post("/api/cron-history/jobs", data),
458
- onSuccess: () => {
459
- queryClient.invalidateQueries({ queryKey: ["cron", "jobs"] });
460
- setShowForm(false);
461
- }
462
- });
463
- const updateMut = useMutation({
464
- mutationFn: ({ id, data }) => patch(`/api/cron-history/jobs/${id}`, data),
465
- onSuccess: () => {
466
- queryClient.invalidateQueries({ queryKey: ["cron", "jobs"] });
467
- setEditingJob(null);
468
- setShowForm(false);
469
- }
470
- });
471
- const deleteMut = useMutation({
472
- mutationFn: (id) => del(`/api/cron-history/jobs/${id}`),
473
- onSuccess: () => queryClient.invalidateQueries({ queryKey: ["cron", "jobs"] })
474
- });
475
- const toggleMut = useMutation({
476
- mutationFn: (id) => post(`/api/cron-history/jobs/${id}/toggle`, {}),
477
- onSuccess: () => queryClient.invalidateQueries({ queryKey: ["cron", "jobs"] })
478
- });
479
- return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-1 flex-col overflow-hidden", children: [
480
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "shrink-0 border-b px-6 py-4", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between", children: [
481
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
482
- /* @__PURE__ */ jsxRuntimeExports.jsx("h1", { className: "text-lg font-semibold", children: "Automations" }),
483
- /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm text-muted-foreground mt-1", children: "Scheduled cron jobs managed by the Hermes agent" })
484
- ] }),
485
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2", children: [
486
- /* @__PURE__ */ jsxRuntimeExports.jsxs(Button, { size: "sm", variant: "outline", className: "gap-1.5", onClick: () => {
487
- setEditingJob(null);
488
- setFormName("");
489
- setFormSchedule("");
490
- setFormPrompt("");
491
- setShowForm(true);
492
- }, children: [
493
- /* @__PURE__ */ jsxRuntimeExports.jsx(IconPlus, { className: "h-4 w-4" }),
494
- "New Job"
495
- ] }),
496
- /* @__PURE__ */ jsxRuntimeExports.jsx(
497
- "button",
498
- {
499
- onClick: refresh,
500
- className: "flex items-center gap-1.5 text-sm text-muted-foreground hover:text-foreground transition-colors",
501
- children: /* @__PURE__ */ jsxRuntimeExports.jsx(IconRefresh, { className: cn("h-4 w-4", (jobs.isFetching || runs.isFetching) && "animate-spin") })
502
- }
503
- )
504
- ] })
505
- ] }) }),
506
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1 overflow-y-auto", children: [
507
- /* @__PURE__ */ jsxRuntimeExports.jsx(Dialog, { open: showForm, onOpenChange: (v) => {
508
- if (!v) {
509
- setShowForm(false);
510
- setEditingJob(null);
511
- }
512
- }, children: /* @__PURE__ */ jsxRuntimeExports.jsxs(DialogContent, { children: [
513
- /* @__PURE__ */ jsxRuntimeExports.jsx(DialogHeader, { children: /* @__PURE__ */ jsxRuntimeExports.jsx(DialogTitle, { children: editingJob ? "Edit Cron Job" : "New Cron Job" }) }),
514
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-3", children: [
515
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
516
- /* @__PURE__ */ jsxRuntimeExports.jsx("label", { className: "text-xs font-medium text-muted-foreground mb-1 block", children: "Name" }),
517
- /* @__PURE__ */ jsxRuntimeExports.jsx(
518
- Input,
519
- {
520
- value: formName,
521
- onChange: (e) => setFormName(e.target.value),
522
- placeholder: "e.g. Daily weather report",
523
- className: "h-9 text-sm"
524
- }
525
- )
526
- ] }),
527
- /* @__PURE__ */ jsxRuntimeExports.jsx(
528
- SchedulePicker,
529
- {
530
- value: formSchedule,
531
- onChange: setFormSchedule
532
- }
533
- ),
534
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
535
- /* @__PURE__ */ jsxRuntimeExports.jsx("label", { className: "text-xs font-medium text-muted-foreground mb-1 block", children: "Prompt" }),
536
- /* @__PURE__ */ jsxRuntimeExports.jsx(
537
- Textarea,
538
- {
539
- value: formPrompt,
540
- onChange: (e) => setFormPrompt(e.target.value),
541
- placeholder: "What should the agent do when this job runs?",
542
- className: "min-h-[80px] text-sm",
543
- rows: 4
544
- }
545
- )
546
- ] })
547
- ] }),
548
- /* @__PURE__ */ jsxRuntimeExports.jsxs(DialogFooter, { children: [
549
- /* @__PURE__ */ jsxRuntimeExports.jsx(Button, { size: "sm", variant: "ghost", onClick: () => {
550
- setShowForm(false);
551
- setEditingJob(null);
552
- }, children: "Cancel" }),
553
- /* @__PURE__ */ jsxRuntimeExports.jsx(
554
- Button,
555
- {
556
- size: "sm",
557
- disabled: !formName.trim() || !formSchedule.trim(),
558
- onClick: () => {
559
- const data = { name: formName.trim(), schedule: formSchedule.trim(), prompt: formPrompt.trim() };
560
- if (editingJob) {
561
- updateMut.mutate({ id: jobId(editingJob), data });
562
- } else {
563
- createMut.mutate(data);
564
- }
565
- },
566
- children: editingJob ? "Save Changes" : "Create Job"
567
- }
568
- )
569
- ] })
570
- ] }) }),
571
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "px-6 pt-5 pb-2", children: [
572
- /* @__PURE__ */ jsxRuntimeExports.jsx("h2", { className: "text-xs font-semibold text-muted-foreground uppercase tracking-wider mb-3", children: "Jobs" }),
573
- jobs.isLoading ? /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4", children: [1, 2, 3].map((i) => /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "rounded-xl border border-border bg-card h-36 animate-pulse", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "p-5 space-y-3", children: [
574
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-4 bg-muted rounded w-1/2" }),
575
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-3 bg-muted rounded w-3/4" }),
576
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-3 bg-muted rounded w-full" })
577
- ] }) }, i)) }) : jobs.data?.jobs?.length ? /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4", children: jobs.data.jobs.map((job) => /* @__PURE__ */ jsxRuntimeExports.jsx(
578
- JobCard,
579
- {
580
- job,
581
- onEdit: () => {
582
- setEditingJob(job);
583
- setFormName(job.name || "");
584
- setFormSchedule(scheduleText(job.schedule));
585
- setFormPrompt(job.prompt || "");
586
- setShowForm(true);
587
- },
588
- onDelete: () => deleteMut.mutate(jobId(job)),
589
- onToggle: () => toggleMut.mutate(jobId(job))
590
- },
591
- jobId(job)
592
- )) }) : /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "rounded-xl border border-dashed border-border bg-muted/20 py-12 text-center", children: [
593
- /* @__PURE__ */ jsxRuntimeExports.jsx(IconClock, { className: "h-8 w-8 text-muted-foreground/40 mx-auto mb-3" }),
594
- /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm font-medium text-foreground", children: "No cron jobs yet" }),
595
- /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "text-xs text-muted-foreground mt-1", children: [
596
- "Click ",
597
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-medium", children: "New Job" }),
598
- " to create one"
599
- ] })
600
- ] })
601
- ] }),
602
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "px-6 pb-6", children: [
603
- /* @__PURE__ */ jsxRuntimeExports.jsx("h2", { className: "text-xs font-semibold text-muted-foreground uppercase tracking-wider mb-3 mt-6", children: "Run History" }),
604
- runs.isLoading ? /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "space-y-1", children: [1, 2, 3, 4, 5].map((i) => /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-10 bg-muted/30 rounded animate-pulse" }, i)) }) : runs.data?.runs?.length ? /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "rounded-xl border border-border bg-card overflow-hidden", children: runs.data.runs.slice(0, 50).map((run) => /* @__PURE__ */ jsxRuntimeExports.jsx(RunRow, { run }, `${run.jobId}/${run.fileName}`)) }) : /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "rounded-xl border border-dashed border-border bg-muted/20 py-10 text-center", children: /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm text-muted-foreground", children: "No runs yet" }) })
605
- ] })
606
- ] })
607
- ] });
608
- }
609
- const SplitComponent = AutomationsPage;
610
- export {
611
- SplitComponent as component
612
- };
@@ -1,40 +0,0 @@
1
- import { j as jsxRuntimeExports } from "../_libs/react.mjs";
2
- import { S as SettingsPage } from "./index-Dbs9k8Ea.mjs";
3
- import { R as Route$6 } from "./router-CS6Zq3md.mjs";
4
- import "../_libs/tanstack__react-query.mjs";
5
- import "../_libs/tanstack__query-core.mjs";
6
- import "../_libs/tabler__icons-react.mjs";
7
- import "../_libs/tanstack__react-router.mjs";
8
- import "../_libs/tanstack__router-core.mjs";
9
- import "../_libs/tanstack__history.mjs";
10
- import "../_libs/cookie-es.mjs";
11
- import "../_libs/seroval.mjs";
12
- import "../_libs/seroval-plugins.mjs";
13
- import "node:stream/web";
14
- import "node:stream";
15
- import "../_libs/react-dom.mjs";
16
- import "util";
17
- import "crypto";
18
- import "async_hooks";
19
- import "stream";
20
- import "../_libs/isbot.mjs";
21
- import "../_libs/clsx.mjs";
22
- import "../_libs/class-variance-authority.mjs";
23
- import "../_libs/zustand.mjs";
24
- import "../_libs/base-ui__react.mjs";
25
- import "../_libs/base-ui__utils.mjs";
26
- import "../_libs/use-sync-external-store.mjs";
27
- import "../_libs/floating-ui__utils.mjs";
28
- import "../_libs/floating-ui__react-dom.mjs";
29
- import "../_libs/floating-ui__dom.mjs";
30
- import "../_libs/floating-ui__core.mjs";
31
- import "../_libs/zod.mjs";
32
- function SettingsRoute() {
33
- const {
34
- section
35
- } = Route$6.useSearch();
36
- return /* @__PURE__ */ jsxRuntimeExports.jsx(SettingsPage, { section });
37
- }
38
- export {
39
- SettingsRoute as component
40
- };