hermium 0.1.2 → 0.1.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 (150) hide show
  1. package/bin/hermium.mjs +184 -145
  2. package/dist/server/index.mjs +65 -65
  3. package/dist/web-server/__23tanstack-start-plugin-adapters-Cwee5PKy.mjs +6 -0
  4. package/dist/web-server/_chunks/ssr-renderer.mjs +22 -0
  5. package/dist/web-server/_libs/babel__runtime.mjs +237 -0
  6. package/dist/web-server/_libs/bail.mjs +8 -0
  7. package/dist/web-server/_libs/base-ui__react.mjs +9554 -0
  8. package/dist/web-server/_libs/base-ui__utils.mjs +1101 -0
  9. package/dist/web-server/_libs/ccount.mjs +16 -0
  10. package/dist/web-server/_libs/character-entities-legacy.mjs +111 -0
  11. package/dist/web-server/_libs/character-entities.mjs +2130 -0
  12. package/dist/web-server/_libs/character-reference-invalid.mjs +33 -0
  13. package/dist/web-server/_libs/class-variance-authority.mjs +44 -0
  14. package/dist/web-server/_libs/clsx.mjs +16 -0
  15. package/dist/web-server/_libs/comma-separated-tokens.mjs +31 -0
  16. package/dist/web-server/_libs/cookie-es.mjs +44 -0
  17. package/dist/web-server/_libs/croner.mjs +1 -0
  18. package/dist/web-server/_libs/crossws.mjs +1 -0
  19. package/dist/web-server/_libs/decode-named-character-reference+[...].mjs +8 -0
  20. package/dist/web-server/_libs/devlop.mjs +8 -0
  21. package/dist/web-server/_libs/escape-string-regexp.mjs +9 -0
  22. package/dist/web-server/_libs/estree-util-is-identifier-name.mjs +11 -0
  23. package/dist/web-server/_libs/extend.mjs +97 -0
  24. package/dist/web-server/_libs/fault.mjs +1 -0
  25. package/dist/web-server/_libs/floating-ui__core.mjs +663 -0
  26. package/dist/web-server/_libs/floating-ui__dom.mjs +624 -0
  27. package/dist/web-server/_libs/floating-ui__react-dom.mjs +279 -0
  28. package/dist/web-server/_libs/floating-ui__utils.mjs +322 -0
  29. package/dist/web-server/_libs/format.mjs +1 -0
  30. package/dist/web-server/_libs/h3.mjs +408 -0
  31. package/dist/web-server/_libs/hast-util-parse-selector.mjs +39 -0
  32. package/dist/web-server/_libs/hast-util-to-jsx-runtime.mjs +388 -0
  33. package/dist/web-server/_libs/hast-util-whitespace.mjs +10 -0
  34. package/dist/web-server/_libs/hastscript.mjs +200 -0
  35. package/dist/web-server/_libs/highlight.js.mjs +1 -0
  36. package/dist/web-server/_libs/hookable.mjs +1 -0
  37. package/dist/web-server/_libs/html-url-attributes.mjs +26 -0
  38. package/dist/web-server/_libs/inline-style-parser.mjs +142 -0
  39. package/dist/web-server/_libs/is-alphabetical.mjs +7 -0
  40. package/dist/web-server/_libs/is-alphanumerical.mjs +8 -0
  41. package/dist/web-server/_libs/is-decimal.mjs +7 -0
  42. package/dist/web-server/_libs/is-hexadecimal.mjs +7 -0
  43. package/dist/web-server/_libs/is-plain-obj.mjs +10 -0
  44. package/dist/web-server/_libs/isbot.mjs +21 -0
  45. package/dist/web-server/_libs/longest-streak.mjs +25 -0
  46. package/dist/web-server/_libs/lowlight.mjs +1 -0
  47. package/dist/web-server/_libs/markdown-table.mjs +142 -0
  48. package/dist/web-server/_libs/mdast-util-find-and-replace.mjs +109 -0
  49. package/dist/web-server/_libs/mdast-util-from-markdown.mjs +717 -0
  50. package/dist/web-server/_libs/mdast-util-gfm-autolink-literal+[...].mjs +156 -0
  51. package/dist/web-server/_libs/mdast-util-gfm-footnote.mjs +117 -0
  52. package/dist/web-server/_libs/mdast-util-gfm-strikethrough.mjs +54 -0
  53. package/dist/web-server/_libs/mdast-util-gfm-table.mjs +157 -0
  54. package/dist/web-server/_libs/mdast-util-gfm-task-list-item.mjs +77 -0
  55. package/dist/web-server/_libs/mdast-util-gfm.mjs +29 -0
  56. package/dist/web-server/_libs/mdast-util-phrasing.mjs +30 -0
  57. package/dist/web-server/_libs/mdast-util-to-hast.mjs +710 -0
  58. package/dist/web-server/_libs/mdast-util-to-markdown.mjs +798 -0
  59. package/dist/web-server/_libs/mdast-util-to-string.mjs +38 -0
  60. package/dist/web-server/_libs/micromark-core-commonmark.mjs +2259 -0
  61. package/dist/web-server/_libs/micromark-extension-gfm-autolink-literal+[...].mjs +344 -0
  62. package/dist/web-server/_libs/micromark-extension-gfm-footnote+[...].mjs +279 -0
  63. package/dist/web-server/_libs/micromark-extension-gfm-strikethrough+[...].mjs +98 -0
  64. package/dist/web-server/_libs/micromark-extension-gfm-table.mjs +491 -0
  65. package/dist/web-server/_libs/micromark-extension-gfm-tagfilter+[...].mjs +1 -0
  66. package/dist/web-server/_libs/micromark-extension-gfm-task-list-item+[...].mjs +77 -0
  67. package/dist/web-server/_libs/micromark-extension-gfm.mjs +18 -0
  68. package/dist/web-server/_libs/micromark-factory-destination.mjs +94 -0
  69. package/dist/web-server/_libs/micromark-factory-label.mjs +63 -0
  70. package/dist/web-server/_libs/micromark-factory-space.mjs +24 -0
  71. package/dist/web-server/_libs/micromark-factory-title.mjs +65 -0
  72. package/dist/web-server/_libs/micromark-factory-whitespace.mjs +22 -0
  73. package/dist/web-server/_libs/micromark-util-character.mjs +44 -0
  74. package/dist/web-server/_libs/micromark-util-chunked.mjs +36 -0
  75. package/dist/web-server/_libs/micromark-util-classify-character+[...].mjs +12 -0
  76. package/dist/web-server/_libs/micromark-util-combine-extensions+[...].mjs +41 -0
  77. package/dist/web-server/_libs/micromark-util-decode-numeric-character-reference+[...].mjs +19 -0
  78. package/dist/web-server/_libs/micromark-util-decode-string.mjs +21 -0
  79. package/dist/web-server/_libs/micromark-util-encode.mjs +1 -0
  80. package/dist/web-server/_libs/micromark-util-html-tag-name.mjs +69 -0
  81. package/dist/web-server/_libs/micromark-util-normalize-identifier+[...].mjs +6 -0
  82. package/dist/web-server/_libs/micromark-util-resolve-all.mjs +15 -0
  83. package/dist/web-server/_libs/micromark-util-sanitize-uri.mjs +41 -0
  84. package/dist/web-server/_libs/micromark-util-subtokenize.mjs +346 -0
  85. package/dist/web-server/_libs/micromark.mjs +906 -0
  86. package/dist/web-server/_libs/ocache.mjs +1 -0
  87. package/dist/web-server/_libs/ohash.mjs +1 -0
  88. package/dist/web-server/_libs/parse-entities.mjs +245 -0
  89. package/dist/web-server/_libs/property-information.mjs +1210 -0
  90. package/dist/web-server/_libs/react-dom.mjs +10779 -0
  91. package/dist/web-server/_libs/react-markdown.mjs +147 -0
  92. package/dist/web-server/_libs/react-syntax-highlighter.mjs +941 -0
  93. package/dist/web-server/_libs/react.mjs +513 -0
  94. package/dist/web-server/_libs/refractor.mjs +2425 -0
  95. package/dist/web-server/_libs/remark-gfm.mjs +20 -0
  96. package/dist/web-server/_libs/remark-parse.mjs +19 -0
  97. package/dist/web-server/_libs/remark-rehype.mjs +21 -0
  98. package/dist/web-server/_libs/reselect.mjs +1 -0
  99. package/dist/web-server/_libs/rou3.mjs +8 -0
  100. package/dist/web-server/_libs/seroval-plugins.mjs +58 -0
  101. package/dist/web-server/_libs/seroval.mjs +1775 -0
  102. package/dist/web-server/_libs/space-separated-tokens.mjs +11 -0
  103. package/dist/web-server/_libs/srvx.mjs +781 -0
  104. package/dist/web-server/_libs/style-to-js.mjs +72 -0
  105. package/dist/web-server/_libs/style-to-object.mjs +38 -0
  106. package/dist/web-server/_libs/tabler__icons-react.mjs +224 -0
  107. package/dist/web-server/_libs/tanstack__history.mjs +204 -0
  108. package/dist/web-server/_libs/tanstack__query-core.mjs +2552 -0
  109. package/dist/web-server/_libs/tanstack__react-query.mjs +190 -0
  110. package/dist/web-server/_libs/tanstack__react-router.mjs +1120 -0
  111. package/dist/web-server/_libs/tanstack__react-store.mjs +2 -0
  112. package/dist/web-server/_libs/tanstack__router-core.mjs +4288 -0
  113. package/dist/web-server/_libs/tanstack__store.mjs +1 -0
  114. package/dist/web-server/_libs/trim-lines.mjs +41 -0
  115. package/dist/web-server/_libs/trough.mjs +85 -0
  116. package/dist/web-server/_libs/ufo.mjs +54 -0
  117. package/dist/web-server/_libs/unctx.mjs +1 -0
  118. package/dist/web-server/_libs/ungap__structured-clone.mjs +224 -0
  119. package/dist/web-server/_libs/unified.mjs +661 -0
  120. package/dist/web-server/_libs/unist-util-is.mjs +100 -0
  121. package/dist/web-server/_libs/unist-util-position.mjs +27 -0
  122. package/dist/web-server/_libs/unist-util-stringify-position.mjs +27 -0
  123. package/dist/web-server/_libs/unist-util-visit-parents.mjs +83 -0
  124. package/dist/web-server/_libs/unist-util-visit.mjs +24 -0
  125. package/dist/web-server/_libs/unstorage.mjs +1 -0
  126. package/dist/web-server/_libs/use-sync-external-store.mjs +139 -0
  127. package/dist/web-server/_libs/vfile-message.mjs +138 -0
  128. package/dist/web-server/_libs/vfile.mjs +467 -0
  129. package/dist/web-server/_libs/zod.mjs +3915 -0
  130. package/dist/web-server/_libs/zustand.mjs +343 -0
  131. package/dist/web-server/_libs/zwitch.mjs +1 -0
  132. package/dist/web-server/_ssr/index-BLK6uN4p.mjs +612 -0
  133. package/dist/web-server/_ssr/index-BkkxTg0a.mjs +1855 -0
  134. package/dist/web-server/_ssr/index-Bp9a_nTf.mjs +66 -0
  135. package/dist/web-server/_ssr/index-C8t8AZQG.mjs +513 -0
  136. package/dist/web-server/_ssr/index-DSIu0x-q.mjs +449 -0
  137. package/dist/web-server/_ssr/index-DqFrn6kj.mjs +278 -0
  138. package/dist/web-server/_ssr/index-EKE8NFy_.mjs +189 -0
  139. package/dist/web-server/_ssr/index-JzLhPyir.mjs +213 -0
  140. package/dist/web-server/_ssr/index-wTy_4MhH.mjs +369 -0
  141. package/dist/web-server/_ssr/index.mjs +1558 -0
  142. package/dist/web-server/_ssr/input-BQFduUUo.mjs +20 -0
  143. package/dist/web-server/_ssr/router-59cN5lqo.mjs +1998 -0
  144. package/dist/web-server/_ssr/start-HYkvq4Ni.mjs +4 -0
  145. package/dist/web-server/_ssr/switch-Bim4kX8N.mjs +33 -0
  146. package/dist/web-server/_ssr/syntax-highlighter-5vezNTce.mjs +62 -0
  147. package/dist/web-server/_ssr/textarea-CK0ROhfF.mjs +18 -0
  148. package/dist/web-server/_tanstack-start-manifest_v-DLw6M7p4.mjs +4 -0
  149. package/dist/web-server/index.mjs +611 -0
  150. package/package.json +1 -1
@@ -0,0 +1,213 @@
1
+ import { r as reactExports, j as jsxRuntimeExports } from "../_libs/react.mjs";
2
+ import { a as cn, g as get } from "./router-59cN5lqo.mjs";
3
+ import { F as IconRefresh, s as IconChartBar } from "../_libs/tabler__icons-react.mjs";
4
+ import "../_libs/tanstack__react-router.mjs";
5
+ import "../_libs/tanstack__router-core.mjs";
6
+ import "../_libs/tanstack__history.mjs";
7
+ import "../_libs/cookie-es.mjs";
8
+ import "../_libs/seroval.mjs";
9
+ import "../_libs/seroval-plugins.mjs";
10
+ import "node:stream/web";
11
+ import "node:stream";
12
+ import "../_libs/react-dom.mjs";
13
+ import "util";
14
+ import "crypto";
15
+ import "async_hooks";
16
+ import "stream";
17
+ import "../_libs/isbot.mjs";
18
+ import "../_libs/tanstack__query-core.mjs";
19
+ import "../_libs/tanstack__react-query.mjs";
20
+ import "../_libs/clsx.mjs";
21
+ import "../_libs/class-variance-authority.mjs";
22
+ import "../_libs/zustand.mjs";
23
+ import "../_libs/base-ui__react.mjs";
24
+ import "../_libs/base-ui__utils.mjs";
25
+ import "../_libs/use-sync-external-store.mjs";
26
+ import "../_libs/floating-ui__utils.mjs";
27
+ import "../_libs/floating-ui__react-dom.mjs";
28
+ import "../_libs/floating-ui__dom.mjs";
29
+ import "../_libs/floating-ui__core.mjs";
30
+ import "../_libs/zod.mjs";
31
+ function fetchUsage(days = 30) {
32
+ return get(`/api/hermes/insights?days=${days}`);
33
+ }
34
+ const PERIODS = [
35
+ { label: "7d", days: 7 },
36
+ { label: "30d", days: 30 },
37
+ { label: "90d", days: 90 }
38
+ ];
39
+ function fmt(n) {
40
+ if (n >= 1e6) return `${(n / 1e6).toFixed(1)}M`;
41
+ if (n >= 1e3) return `${(n / 1e3).toFixed(1)}K`;
42
+ return String(n);
43
+ }
44
+ function fmtCost(n) {
45
+ if (n >= 1) return `$${n.toFixed(2)}`;
46
+ if (n >= 0.01) return `$${n.toFixed(4)}`;
47
+ return n > 0 ? `$${n.toFixed(6)}` : "$0.00";
48
+ }
49
+ function fmtPct(n) {
50
+ return `${(n * 100).toFixed(1)}%`;
51
+ }
52
+ function fmtDate(day) {
53
+ try {
54
+ const d = /* @__PURE__ */ new Date(day + "T00:00:00");
55
+ return d.toLocaleDateString(void 0, { month: "short", day: "numeric" });
56
+ } catch {
57
+ return day;
58
+ }
59
+ }
60
+ function StatCard({
61
+ label,
62
+ value,
63
+ sub
64
+ }) {
65
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "rounded-xl border border-border bg-card p-4 flex flex-col gap-1", children: [
66
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs text-muted-foreground/70", children: label }),
67
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xl font-semibold text-foreground tracking-tight", children: value }),
68
+ sub && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs text-muted-foreground/50", children: sub })
69
+ ] });
70
+ }
71
+ function ModelBreakdown({ models }) {
72
+ if (models.length === 0) return null;
73
+ const total = models.reduce((s, m) => s + m.sessions, 0);
74
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "rounded-xl border border-border bg-card p-4", children: [
75
+ /* @__PURE__ */ jsxRuntimeExports.jsx("h3", { className: "text-sm font-medium text-foreground mb-3", children: "Model Breakdown" }),
76
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "space-y-2.5", children: models.map((m) => /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex items-center gap-3", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1 min-w-0", children: [
77
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between mb-1", children: [
78
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-sm text-foreground truncate", children: m.model }),
79
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-sm text-muted-foreground tabular-nums ml-3", children: m.sessions })
80
+ ] }),
81
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-1.5 rounded-full bg-muted overflow-hidden", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
82
+ "div",
83
+ {
84
+ className: "h-full rounded-full bg-primary/50 transition-all",
85
+ style: { width: `${total > 0 ? m.sessions / total * 100 : 0}%` }
86
+ }
87
+ ) })
88
+ ] }) }, m.model)) })
89
+ ] });
90
+ }
91
+ function DailyTable({ daily }) {
92
+ if (daily.length === 0) return null;
93
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "rounded-xl border border-border bg-card", children: [
94
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 px-4 pt-4 pb-3", children: [
95
+ /* @__PURE__ */ jsxRuntimeExports.jsx(IconChartBar, { className: "size-4 text-muted-foreground" }),
96
+ /* @__PURE__ */ jsxRuntimeExports.jsx("h3", { className: "text-sm font-medium text-foreground", children: "Daily Usage (Last 30 Days)" })
97
+ ] }),
98
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "overflow-x-auto", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("table", { className: "w-full text-xs", children: [
99
+ /* @__PURE__ */ jsxRuntimeExports.jsx("thead", { children: /* @__PURE__ */ jsxRuntimeExports.jsxs("tr", { className: "border-t border-border text-muted-foreground/60", children: [
100
+ /* @__PURE__ */ jsxRuntimeExports.jsx("th", { className: "text-left px-4 py-2 font-medium", children: "Date" }),
101
+ /* @__PURE__ */ jsxRuntimeExports.jsx("th", { className: "text-right px-2 py-2 font-medium", children: "Input" }),
102
+ /* @__PURE__ */ jsxRuntimeExports.jsx("th", { className: "text-right px-2 py-2 font-medium", children: "Output" }),
103
+ /* @__PURE__ */ jsxRuntimeExports.jsx("th", { className: "text-right px-2 py-2 font-medium", children: "Cache Hit Rate" }),
104
+ /* @__PURE__ */ jsxRuntimeExports.jsx("th", { className: "text-right px-2 py-2 font-medium", children: "Sessions" })
105
+ ] }) }),
106
+ /* @__PURE__ */ jsxRuntimeExports.jsx("tbody", { children: daily.map((d) => /* @__PURE__ */ jsxRuntimeExports.jsxs("tr", { className: "border-t border-border/50 hover:bg-muted/30 transition-colors", children: [
107
+ /* @__PURE__ */ jsxRuntimeExports.jsx("td", { className: "px-4 py-2.5 text-foreground font-medium whitespace-nowrap", children: fmtDate(d.date) }),
108
+ /* @__PURE__ */ jsxRuntimeExports.jsx("td", { className: "px-2 py-2.5 text-right text-muted-foreground tabular-nums", children: d.input_tokens > 0 ? fmt(d.input_tokens) : "—" }),
109
+ /* @__PURE__ */ jsxRuntimeExports.jsx("td", { className: "px-2 py-2.5 text-right text-muted-foreground tabular-nums", children: d.output_tokens > 0 ? fmt(d.output_tokens) : "—" }),
110
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
111
+ "td",
112
+ {
113
+ className: "px-2 py-2.5 text-right tabular-nums",
114
+ style: { color: d.cache_hit_rate > 0.8 ? "#22c55e" : d.cache_hit_rate > 0.5 ? "#eab308" : "inherit" },
115
+ children: d.cache_hit_rate > 0 ? fmtPct(d.cache_hit_rate) : "—"
116
+ }
117
+ ),
118
+ /* @__PURE__ */ jsxRuntimeExports.jsx("td", { className: "px-2 py-2.5 text-right text-muted-foreground tabular-nums", children: d.sessions })
119
+ ] }, d.date)) })
120
+ ] }) })
121
+ ] });
122
+ }
123
+ function UsagePage() {
124
+ const [days, setDays] = reactExports.useState(30);
125
+ const [data, setData] = reactExports.useState(null);
126
+ const [loading, setLoading] = reactExports.useState(true);
127
+ const [error, setError] = reactExports.useState(null);
128
+ const load = reactExports.useCallback(() => {
129
+ setLoading(true);
130
+ setError(null);
131
+ fetchUsage(days).then(setData).catch((err) => setError(err instanceof Error ? err.message : "Failed to load")).finally(() => setLoading(false));
132
+ }, [days]);
133
+ reactExports.useEffect(() => {
134
+ load();
135
+ }, [load]);
136
+ return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex-1 min-w-0 overflow-y-auto", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mx-auto max-w-3xl px-6 py-6 flex flex-col gap-5", children: [
137
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between", children: [
138
+ /* @__PURE__ */ jsxRuntimeExports.jsx("h1", { className: "text-lg font-semibold text-foreground", children: "Usage" }),
139
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2", children: [
140
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex items-center gap-0.5 rounded-lg border border-border p-0.5", children: PERIODS.map((p) => /* @__PURE__ */ jsxRuntimeExports.jsx(
141
+ "button",
142
+ {
143
+ onClick: () => setDays(p.days),
144
+ className: cn(
145
+ "rounded-md px-2.5 py-1 text-xs font-medium transition-colors",
146
+ days === p.days ? "bg-muted text-foreground" : "text-muted-foreground hover:text-foreground"
147
+ ),
148
+ children: p.label
149
+ },
150
+ p.label
151
+ )) }),
152
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
153
+ "button",
154
+ {
155
+ onClick: load,
156
+ disabled: loading,
157
+ className: "flex items-center justify-center rounded-md size-7 text-muted-foreground hover:text-foreground hover:bg-muted transition-colors disabled:opacity-50",
158
+ "aria-label": "Refresh",
159
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(IconRefresh, { className: cn("size-3.5", loading && "animate-spin") })
160
+ }
161
+ )
162
+ ] })
163
+ ] }),
164
+ loading && !data && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex items-center justify-center py-20", children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "size-5 rounded-full border-2 border-muted-foreground/30 border-t-foreground animate-spin" }) }),
165
+ error && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "rounded-lg border border-destructive/30 bg-destructive/5 px-4 py-3", children: /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm text-destructive", children: error }) }),
166
+ data && /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
167
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid grid-cols-2 sm:grid-cols-4 gap-3", children: [
168
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
169
+ StatCard,
170
+ {
171
+ label: "Total Tokens",
172
+ value: data.total_tokens > 0 ? fmt(data.total_tokens) : "—",
173
+ sub: data.total_tokens > 0 ? `${fmt(data.total_input_tokens)} Input / ${fmt(data.total_output_tokens)} Output` : void 0
174
+ }
175
+ ),
176
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
177
+ StatCard,
178
+ {
179
+ label: "Total Sessions",
180
+ value: String(data.total_sessions),
181
+ sub: data.total_sessions > 0 ? `~${(data.total_sessions / days).toFixed(1)}/day avg` : void 0
182
+ }
183
+ ),
184
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
185
+ StatCard,
186
+ {
187
+ label: "Est. Cost",
188
+ value: fmtCost(data.total_cost)
189
+ }
190
+ ),
191
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
192
+ StatCard,
193
+ {
194
+ label: "Cache Hit Rate",
195
+ value: data.cache_hit_rate > 0 ? fmtPct(data.cache_hit_rate) : "—",
196
+ sub: data.total_cache_read > 0 ? `${fmt(data.total_cache_read)} Tokens` : void 0
197
+ }
198
+ )
199
+ ] }),
200
+ /* @__PURE__ */ jsxRuntimeExports.jsx(ModelBreakdown, { models: data.models }),
201
+ /* @__PURE__ */ jsxRuntimeExports.jsx(DailyTable, { daily: data.daily_tokens }),
202
+ data.daily_tokens.length === 0 && data.models.length === 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col items-center py-20 text-muted-foreground", children: [
203
+ /* @__PURE__ */ jsxRuntimeExports.jsx(IconChartBar, { className: "size-8 mb-3 opacity-40" }),
204
+ /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm font-medium", children: "No usage data available" }),
205
+ /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs mt-1 text-muted-foreground/60", children: "Start a conversation to see usage stats." })
206
+ ] })
207
+ ] })
208
+ ] }) });
209
+ }
210
+ const SplitComponent = UsagePage;
211
+ export {
212
+ SplitComponent as component
213
+ };
@@ -0,0 +1,369 @@
1
+ import { r as reactExports, j as jsxRuntimeExports } from "../_libs/react.mjs";
2
+ import { a as cn, g as get, p as post } from "./router-59cN5lqo.mjs";
3
+ import { o as IconBrain, e as IconUser, G as IconLoader2, H as IconAlertCircle, F as IconRefresh, a as IconX, N as IconCheck, v as IconPencil } from "../_libs/tabler__icons-react.mjs";
4
+ import { M as Markdown } from "../_libs/react-markdown.mjs";
5
+ import { r as remarkGfm } from "../_libs/remark-gfm.mjs";
6
+ import "../_libs/tanstack__react-router.mjs";
7
+ import "../_libs/tanstack__router-core.mjs";
8
+ import "../_libs/tanstack__history.mjs";
9
+ import "../_libs/cookie-es.mjs";
10
+ import "../_libs/seroval.mjs";
11
+ import "../_libs/seroval-plugins.mjs";
12
+ import "node:stream/web";
13
+ import "node:stream";
14
+ import "../_libs/react-dom.mjs";
15
+ import "util";
16
+ import "crypto";
17
+ import "async_hooks";
18
+ import "stream";
19
+ import "../_libs/isbot.mjs";
20
+ import "../_libs/tanstack__query-core.mjs";
21
+ import "../_libs/tanstack__react-query.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
+ import "../_libs/devlop.mjs";
34
+ import "../_libs/unified.mjs";
35
+ import "../_libs/bail.mjs";
36
+ import "../_libs/extend.mjs";
37
+ import "../_libs/is-plain-obj.mjs";
38
+ import "../_libs/trough.mjs";
39
+ import "../_libs/vfile.mjs";
40
+ import "../_libs/vfile-message.mjs";
41
+ import "../_libs/unist-util-stringify-position.mjs";
42
+ import "node:process";
43
+ import "node:path";
44
+ import "node:url";
45
+ import "../_libs/remark-parse.mjs";
46
+ import "../_libs/mdast-util-from-markdown.mjs";
47
+ import "../_libs/micromark-util-decode-numeric-character-reference+[...].mjs";
48
+ import "../_libs/micromark-util-decode-string.mjs";
49
+ import "../_libs/decode-named-character-reference+[...].mjs";
50
+ import "../_libs/character-entities.mjs";
51
+ import "../_libs/micromark-util-normalize-identifier+[...].mjs";
52
+ import "../_libs/micromark.mjs";
53
+ import "../_libs/micromark-util-combine-extensions+[...].mjs";
54
+ import "../_libs/micromark-util-chunked.mjs";
55
+ import "../_libs/micromark-factory-space.mjs";
56
+ import "../_libs/micromark-util-character.mjs";
57
+ import "../_libs/micromark-core-commonmark.mjs";
58
+ import "../_libs/micromark-util-classify-character+[...].mjs";
59
+ import "../_libs/micromark-util-resolve-all.mjs";
60
+ import "../_libs/micromark-util-subtokenize.mjs";
61
+ import "../_libs/micromark-factory-destination.mjs";
62
+ import "../_libs/micromark-factory-label.mjs";
63
+ import "../_libs/micromark-factory-title.mjs";
64
+ import "../_libs/micromark-factory-whitespace.mjs";
65
+ import "../_libs/micromark-util-html-tag-name.mjs";
66
+ import "../_libs/mdast-util-to-string.mjs";
67
+ import "../_libs/remark-rehype.mjs";
68
+ import "../_libs/mdast-util-to-hast.mjs";
69
+ import "../_libs/ungap__structured-clone.mjs";
70
+ import "../_libs/micromark-util-sanitize-uri.mjs";
71
+ import "../_libs/unist-util-position.mjs";
72
+ import "../_libs/trim-lines.mjs";
73
+ import "../_libs/unist-util-visit.mjs";
74
+ import "../_libs/unist-util-visit-parents.mjs";
75
+ import "../_libs/unist-util-is.mjs";
76
+ import "../_libs/hast-util-to-jsx-runtime.mjs";
77
+ import "../_libs/comma-separated-tokens.mjs";
78
+ import "../_libs/property-information.mjs";
79
+ import "../_libs/space-separated-tokens.mjs";
80
+ import "../_libs/style-to-js.mjs";
81
+ import "../_libs/style-to-object.mjs";
82
+ import "../_libs/inline-style-parser.mjs";
83
+ import "../_libs/hast-util-whitespace.mjs";
84
+ import "../_libs/estree-util-is-identifier-name.mjs";
85
+ import "../_libs/html-url-attributes.mjs";
86
+ import "../_libs/micromark-extension-gfm.mjs";
87
+ import "../_libs/micromark-extension-gfm-autolink-literal+[...].mjs";
88
+ import "../_libs/micromark-extension-gfm-footnote+[...].mjs";
89
+ import "../_libs/micromark-extension-gfm-strikethrough+[...].mjs";
90
+ import "../_libs/micromark-extension-gfm-table.mjs";
91
+ import "../_libs/micromark-extension-gfm-task-list-item+[...].mjs";
92
+ import "../_libs/mdast-util-gfm.mjs";
93
+ import "../_libs/mdast-util-gfm-autolink-literal+[...].mjs";
94
+ import "../_libs/ccount.mjs";
95
+ import "../_libs/mdast-util-find-and-replace.mjs";
96
+ import "../_libs/escape-string-regexp.mjs";
97
+ import "../_libs/mdast-util-gfm-footnote.mjs";
98
+ import "../_libs/mdast-util-gfm-strikethrough.mjs";
99
+ import "../_libs/mdast-util-gfm-table.mjs";
100
+ import "../_libs/markdown-table.mjs";
101
+ import "../_libs/mdast-util-to-markdown.mjs";
102
+ import "../_libs/longest-streak.mjs";
103
+ import "../_libs/mdast-util-phrasing.mjs";
104
+ import "../_libs/mdast-util-gfm-task-list-item.mjs";
105
+ async function fetchMemory() {
106
+ return get("/api/hermes/memory");
107
+ }
108
+ async function saveMemory(section, content) {
109
+ return post("/api/hermes/memory/write", { section, content });
110
+ }
111
+ const SECTIONS = [
112
+ { key: "memory", label: "My Notes", icon: IconBrain, desc: "Personal notes & knowledge", emptyLabel: "No notes yet — click Edit to start writing." },
113
+ { key: "user", label: "User Profile", icon: IconUser, desc: "About you & your context", emptyLabel: "No profile yet — click Edit to add details about yourself." }
114
+ ];
115
+ const markdownComponents = {
116
+ a({ href, children }) {
117
+ return /* @__PURE__ */ jsxRuntimeExports.jsx("a", { href, target: "_blank", rel: "noopener noreferrer", className: "text-blue-600 dark:text-blue-400 underline underline-offset-2 decoration-blue-400/30 hover:decoration-blue-600/60 transition-colors", children });
118
+ },
119
+ img({ src, alt }) {
120
+ return /* @__PURE__ */ jsxRuntimeExports.jsx("img", { src, alt, className: "rounded-xl max-w-full my-4", loading: "lazy" });
121
+ }
122
+ };
123
+ function MemoryPage() {
124
+ const [data, setData] = reactExports.useState(null);
125
+ const [loading, setLoading] = reactExports.useState(true);
126
+ const [error, setError] = reactExports.useState(null);
127
+ const [activeSection, setActiveSection] = reactExports.useState("memory");
128
+ const [editing, setEditing] = reactExports.useState(false);
129
+ const [editContent, setEditContent] = reactExports.useState("");
130
+ const [saving, setSaving] = reactExports.useState(false);
131
+ const [saveError, setSaveError] = reactExports.useState(null);
132
+ const load = reactExports.useCallback(async () => {
133
+ setLoading(true);
134
+ setError(null);
135
+ try {
136
+ const result = await fetchMemory();
137
+ setData(result);
138
+ } catch (e) {
139
+ setError(e instanceof Error ? e.message : "Failed to load memory");
140
+ } finally {
141
+ setLoading(false);
142
+ }
143
+ }, []);
144
+ reactExports.useEffect(() => {
145
+ load();
146
+ }, [load]);
147
+ const activeContent = data ? activeSection === "memory" ? data.memory : data.user : "";
148
+ const activeMtime = data ? activeSection === "memory" ? data.memory_mtime : data.user_mtime : null;
149
+ const activeMeta = SECTIONS.find((s) => s.key === activeSection);
150
+ const handleEdit = () => {
151
+ setEditContent(activeContent);
152
+ setSaveError(null);
153
+ setEditing(true);
154
+ };
155
+ const handleCancel = () => {
156
+ setEditing(false);
157
+ setSaveError(null);
158
+ };
159
+ const handleSave = async () => {
160
+ setSaving(true);
161
+ setSaveError(null);
162
+ try {
163
+ await saveMemory(activeSection, editContent);
164
+ const updated = await fetchMemory();
165
+ setData(updated);
166
+ setEditing(false);
167
+ } catch (e) {
168
+ setSaveError(e instanceof Error ? e.message : "Failed to save");
169
+ } finally {
170
+ setSaving(false);
171
+ }
172
+ };
173
+ const switchSection = (section) => {
174
+ if (editing) {
175
+ if (!confirm("You have unsaved changes. Discard them?")) return;
176
+ setEditing(false);
177
+ }
178
+ setActiveSection(section);
179
+ setSaveError(null);
180
+ };
181
+ if (loading) {
182
+ return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex flex-1 items-center justify-center", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col items-center gap-3 text-muted-foreground", children: [
183
+ /* @__PURE__ */ jsxRuntimeExports.jsx(IconLoader2, { className: "size-6 animate-spin" }),
184
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-sm", children: "Loading memory..." })
185
+ ] }) });
186
+ }
187
+ if (error) {
188
+ return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex flex-1 items-center justify-center", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col items-center gap-3 text-muted-foreground", children: [
189
+ /* @__PURE__ */ jsxRuntimeExports.jsx(IconAlertCircle, { className: "size-8 text-red-500" }),
190
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-sm", children: error }),
191
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(
192
+ "button",
193
+ {
194
+ onClick: load,
195
+ className: "inline-flex items-center gap-1.5 rounded-lg px-3 py-1.5 text-xs font-medium bg-muted hover:bg-muted/80 transition-colors",
196
+ children: [
197
+ /* @__PURE__ */ jsxRuntimeExports.jsx(IconRefresh, { className: "size-3.5" }),
198
+ "Retry"
199
+ ]
200
+ }
201
+ )
202
+ ] }) });
203
+ }
204
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-1 overflow-hidden", children: [
205
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("aside", { className: "flex w-56 shrink-0 flex-col border-r border-border", children: [
206
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2.5 px-3 py-3.5", children: [
207
+ /* @__PURE__ */ jsxRuntimeExports.jsx(IconBrain, { className: "size-5 text-muted-foreground" }),
208
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-sm font-semibold text-foreground", children: "Memory" })
209
+ ] }),
210
+ /* @__PURE__ */ jsxRuntimeExports.jsx("nav", { className: "flex-1 overflow-y-auto space-y-1 px-2 py-1", children: SECTIONS.map((s) => {
211
+ const Icon = s.icon;
212
+ const isActive = activeSection === s.key;
213
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs(
214
+ "button",
215
+ {
216
+ onClick: () => switchSection(s.key),
217
+ className: cn(
218
+ "flex w-full items-center gap-2.5 rounded-lg px-2.5 py-2.5 text-left transition-colors",
219
+ isActive ? "bg-muted text-foreground" : "text-muted-foreground hover:bg-muted hover:text-foreground"
220
+ ),
221
+ children: [
222
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Icon, { className: cn("size-4 shrink-0", isActive ? "text-foreground" : "text-muted-foreground/60") }),
223
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "min-w-0", children: [
224
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "truncate text-sm font-medium", children: s.label }),
225
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "truncate text-[10px] text-muted-foreground/70", children: s.desc })
226
+ ] })
227
+ ]
228
+ },
229
+ s.key
230
+ );
231
+ }) })
232
+ ] }),
233
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex flex-1 flex-col min-w-0 overflow-y-auto", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mx-auto w-full max-w-3xl px-8 py-8", children: [
234
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mb-6", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between gap-4", children: [
235
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
236
+ /* @__PURE__ */ jsxRuntimeExports.jsx("h2", { className: "text-lg font-semibold text-foreground", children: activeMeta.label }),
237
+ /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm text-muted-foreground mt-0.5", children: activeMeta.desc }),
238
+ activeMtime && !editing && /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "text-[11px] text-muted-foreground/60 mt-1", children: [
239
+ "Last modified ",
240
+ new Date(activeMtime * 1e3).toLocaleString()
241
+ ] })
242
+ ] }),
243
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex items-center gap-2 shrink-0", children: editing ? /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
244
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(
245
+ "button",
246
+ {
247
+ onClick: handleCancel,
248
+ disabled: saving,
249
+ className: "inline-flex items-center gap-1.5 rounded-lg px-3 py-1.5 text-sm font-medium text-muted-foreground hover:text-foreground hover:bg-muted transition-colors",
250
+ children: [
251
+ /* @__PURE__ */ jsxRuntimeExports.jsx(IconX, { className: "size-4" }),
252
+ "Cancel"
253
+ ]
254
+ }
255
+ ),
256
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(
257
+ "button",
258
+ {
259
+ onClick: handleSave,
260
+ disabled: saving,
261
+ className: cn(
262
+ "inline-flex items-center gap-1.5 rounded-lg px-4 py-1.5 text-sm font-medium transition-colors",
263
+ "bg-primary text-primary-foreground hover:bg-primary/90",
264
+ saving && "opacity-60 cursor-not-allowed"
265
+ ),
266
+ children: [
267
+ saving ? /* @__PURE__ */ jsxRuntimeExports.jsx(IconLoader2, { className: "size-4 animate-spin" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(IconCheck, { className: "size-4" }),
268
+ saving ? "Saving..." : "Save"
269
+ ]
270
+ }
271
+ )
272
+ ] }) : /* @__PURE__ */ jsxRuntimeExports.jsxs(
273
+ "button",
274
+ {
275
+ onClick: handleEdit,
276
+ className: "inline-flex items-center gap-1.5 rounded-lg px-4 py-1.5 text-sm font-medium bg-muted text-muted-foreground hover:text-foreground hover:bg-muted/80 transition-colors",
277
+ children: [
278
+ /* @__PURE__ */ jsxRuntimeExports.jsx(IconPencil, { className: "size-4" }),
279
+ "Edit"
280
+ ]
281
+ }
282
+ ) })
283
+ ] }) }),
284
+ saveError && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mb-6 rounded-lg border border-red-200 dark:border-red-800/40 bg-red-50 dark:bg-red-950/20 px-4 py-2.5", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "text-xs text-red-700 dark:text-red-300 flex items-center gap-1.5", children: [
285
+ /* @__PURE__ */ jsxRuntimeExports.jsx(IconAlertCircle, { className: "size-3.5 shrink-0" }),
286
+ saveError
287
+ ] }) }),
288
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "rounded-xl border border-border bg-card p-8", children: editing ? /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col gap-3", children: [
289
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
290
+ "textarea",
291
+ {
292
+ value: editContent,
293
+ onChange: (e) => setEditContent(e.target.value),
294
+ className: cn(
295
+ "w-full min-h-[420px] rounded-lg border border-border bg-background p-4 font-mono text-sm leading-relaxed",
296
+ "focus:outline-none focus:ring-2 focus:ring-primary/15 focus:border-primary/40",
297
+ "resize-y placeholder:text-muted-foreground/30"
298
+ ),
299
+ placeholder: `Write your ${activeMeta.label.toLowerCase()} using Markdown...`,
300
+ spellCheck: false,
301
+ autoFocus: true
302
+ }
303
+ ),
304
+ /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-[11px] text-muted-foreground/50", children: "Markdown formatting is supported — headers, lists, code blocks, links, and more." })
305
+ ] }) : activeContent ? /* @__PURE__ */ jsxRuntimeExports.jsx(
306
+ "div",
307
+ {
308
+ className: cn(
309
+ "max-w-none",
310
+ // Headings — generous spacing for readability
311
+ "[&_h1]:mt-8 [&_h1]:mb-4 [&_h1]:text-2xl [&_h1]:font-bold [&_h1]:tracking-tight [&_h1]:text-foreground",
312
+ "[&_h2]:mt-7 [&_h2]:mb-3 [&_h2]:text-xl [&_h2]:font-semibold [&_h2]:tracking-tight [&_h2]:text-foreground",
313
+ "[&_h3]:mt-6 [&_h3]:mb-2.5 [&_h3]:text-lg [&_h3]:font-semibold [&_h3]:text-foreground",
314
+ "[&_h4]:mt-5 [&_h4]:mb-2 [&_h4]:text-base [&_h4]:font-medium [&_h4]:text-foreground",
315
+ "[&_h5]:mt-4 [&_h5]:mb-1.5 [&_h5]:text-sm [&_h5]:font-medium [&_h5]:text-foreground/90",
316
+ "[&_h6]:mt-4 [&_h6]:mb-1.5 [&_h6]:text-sm [&_h6]:font-medium [&_h6]:text-muted-foreground",
317
+ // Paragraphs
318
+ "[&_p]:my-4 [&_p]:leading-[1.75] [&_p]:text-foreground/85",
319
+ // Lists — proper indentation and spacing
320
+ "[&_ul]:my-4 [&_ul]:pl-6 [&_ul]:list-disc [&_ul]:space-y-1.5 [&_ul]:marker:text-muted-foreground/40",
321
+ "[&_ol]:my-4 [&_ol]:pl-6 [&_ol]:list-decimal [&_ol]:space-y-1.5 [&_ol]:marker:text-muted-foreground/40",
322
+ "[&_li]:leading-relaxed [&_li]:text-foreground/85",
323
+ // Inline code
324
+ "[&_:not(pre)>code]:rounded-md [&_:not(pre)>code]:bg-muted/70 [&_:not(pre)>code]:px-1.5 [&_:not(pre)>code]:py-0.5 [&_:not(pre)>code]:text-[13px] [&_:not(pre)>code]:font-mono [&_:not(pre)>code]:text-foreground/90 [&_:not(pre)>code]:border [&_:not(pre)>code]:border-border/50",
325
+ // Code blocks
326
+ "[&_pre]:my-5 [&_pre]:rounded-xl [&_pre]:bg-muted/50 [&_pre]:border [&_pre]:border-border/60 [&_pre]:px-5 [&_pre]:py-4 [&_pre]:text-[13px] [&_pre]:leading-relaxed [&_pre]:overflow-x-auto [&_pre]:font-mono [&_pre]:whitespace-pre-wrap",
327
+ // Blockquotes
328
+ "[&_blockquote]:my-5 [&_blockquote]:border-l-[3px] [&_blockquote]:border-amber-400 dark:[&_blockquote]:border-amber-500 [&_blockquote]:pl-4 [&_blockquote]:text-muted-foreground [&_blockquote]:italic [&_blockquote]:leading-relaxed",
329
+ // Horizontal rules
330
+ "[&_hr]:my-8 [&_hr]:border-border/40",
331
+ // Tables
332
+ "[&_table]:w-full [&_table]:my-4 [&_table]:text-sm",
333
+ "[&_th]:border [&_th]:border-border [&_th]:bg-muted/60 [&_th]:px-4 [&_th]:py-2.5 [&_th]:text-left [&_th]:font-medium [&_th]:text-foreground/80 [&_th]:text-xs [&_th]:uppercase [&_th]:tracking-wider",
334
+ "[&_td]:border [&_td]:border-border [&_td]:px-4 [&_td]:py-2.5 [&_td]:text-foreground/80",
335
+ // Images
336
+ "[&_img]:rounded-xl [&_img]:my-5 [&_img]:max-w-full",
337
+ // First/last margin reset
338
+ "[&>*:first-child]:mt-0 [&>*:last-child]:mb-0"
339
+ ),
340
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(Markdown, { remarkPlugins: [remarkGfm], components: markdownComponents, children: activeContent })
341
+ }
342
+ ) : (
343
+ /* ── Empty state ── */
344
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col items-center justify-center py-16 gap-4", children: [
345
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex size-14 items-center justify-center rounded-2xl bg-muted/50 border border-border/50", children: /* @__PURE__ */ jsxRuntimeExports.jsx(activeMeta.icon, { className: "size-6 text-muted-foreground/30" }) }),
346
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "text-center max-w-xs", children: [
347
+ /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm font-medium text-foreground/70", children: activeMeta.emptyLabel }),
348
+ /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-muted-foreground/50 mt-1.5", children: "You can format your content with Markdown — headers, lists, code blocks, and more." })
349
+ ] }),
350
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(
351
+ "button",
352
+ {
353
+ onClick: handleEdit,
354
+ className: "inline-flex items-center gap-1.5 rounded-lg px-4 py-2 text-sm font-medium bg-muted hover:bg-muted/80 text-foreground/80 transition-colors",
355
+ children: [
356
+ /* @__PURE__ */ jsxRuntimeExports.jsx(IconPencil, { className: "size-3.5" }),
357
+ "Start Editing"
358
+ ]
359
+ }
360
+ )
361
+ ] })
362
+ ) })
363
+ ] }) })
364
+ ] });
365
+ }
366
+ const SplitComponent = MemoryPage;
367
+ export {
368
+ SplitComponent as component
369
+ };