loopable-cli 0.2.0 → 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 (138) hide show
  1. package/.output/nitro.json +1 -1
  2. package/.output/public/assets/_connectorId-CDCuSgpN.js +1 -0
  3. package/.output/public/assets/_loopId-DOnIsVTW.js +1 -0
  4. package/.output/public/assets/_taskId-BO5MZnlZ.js +1 -0
  5. package/.output/public/assets/agents-CBozi7oi.js +1 -0
  6. package/.output/public/assets/alert-Bn_wjgTX.js +1 -0
  7. package/.output/public/assets/button-K3ypIhAZ.js +1 -0
  8. package/.output/public/assets/card-DiVnaTIE.js +1 -0
  9. package/.output/public/assets/chevron-right-BrctLtFK.js +1 -0
  10. package/.output/public/assets/connection-status-DKWelvLO.js +1 -0
  11. package/.output/public/assets/connector-icon-CEbdE71G.js +1 -0
  12. package/.output/public/assets/connectors-JyX3IzJj.js +1 -0
  13. package/.output/public/assets/gaps-PjmcbaWo.js +1 -0
  14. package/.output/public/assets/inbox-CujRR0Cz.js +1 -0
  15. package/.output/public/assets/index-C9SQ_Baq.js +16 -0
  16. package/.output/public/assets/loop-form-Dw3cuTzw.js +1 -0
  17. package/.output/public/assets/loops-DcEfZa2_.js +1 -0
  18. package/.output/public/assets/manifests-yJpevyye.js +1 -0
  19. package/.output/public/assets/new-CwsnNuRW.js +1 -0
  20. package/.output/public/assets/page-bvnfRMum.js +1 -0
  21. package/.output/public/assets/play-yHLs4DjK.js +1 -0
  22. package/.output/public/assets/plus-Ber25lrU.js +1 -0
  23. package/.output/public/assets/preload-helper-BoU_7EQC.js +3 -0
  24. package/.output/public/assets/refresh-cw-BzSY7M8I.js +1 -0
  25. package/.output/public/assets/rotate-ccw-DLv9EfCX.js +1 -0
  26. package/.output/public/assets/runners-DzX-RU3i.js +2 -0
  27. package/.output/public/assets/select-C9grIFwG.js +1 -0
  28. package/.output/public/assets/setting-fields-DUc3npgh.js +3 -0
  29. package/.output/public/assets/styles-B9B98zLk.css +2 -0
  30. package/.output/public/assets/switch-DwABVI6d.js +1 -0
  31. package/.output/public/assets/task-list-Ddk8-qt7.js +1 -0
  32. package/.output/public/assets/textarea-Ds-gIYUQ.js +1 -0
  33. package/.output/public/assets/time-goBWd-5J.js +1 -0
  34. package/.output/public/assets/use-live-tasks-DZNNuECy.js +1 -0
  35. package/.output/public/assets/useCompositeListItem-P4Nmmn7j.js +1 -0
  36. package/.output/public/assets/usePositioner-B7i9Ejzh.js +1 -0
  37. package/.output/server/_chunks/ssr-renderer.mjs +1 -1
  38. package/.output/server/_connectorId-COuQN02a.mjs +512 -0
  39. package/.output/server/_libs/@base-ui/react+[...].mjs +1410 -804
  40. package/.output/server/_libs/@tanstack/react-router+[...].mjs +1 -1
  41. package/.output/server/_libs/lucide-react.mjs +93 -84
  42. package/.output/server/_libs/next-themes.mjs +1 -1
  43. package/.output/server/_libs/sonner.mjs +1 -1
  44. package/.output/server/_loopId-CZh6_Yhr.mjs +310 -0
  45. package/.output/server/_ssr/{callback-D20cVD2w.mjs → access-DTttr563.mjs} +37 -20
  46. package/.output/server/_ssr/{agents-CrUmIQpi.mjs → agents-B_qo1gpL.mjs} +196 -7
  47. package/.output/server/_ssr/{agents-Dms_6TBF.mjs → agents-Bz10gz_m.mjs} +8 -8
  48. package/.output/server/_ssr/agents-CjbOUp3Z.mjs +206 -0
  49. package/.output/server/_ssr/{alert-DQvzE7bu.mjs → alert-C2WBWfzo.mjs} +2 -2
  50. package/.output/server/_ssr/card-r1cV-PCN.mjs +36 -0
  51. package/.output/server/_ssr/{client-BtVRVhQ2.mjs → client-Dk3SD8Il.mjs} +5 -1
  52. package/.output/server/_ssr/connection-status-BogAL-Fj.mjs +32 -0
  53. package/.output/server/_ssr/{connections-ypex3qUd.mjs → connections-Cqvb6Gw2.mjs} +1109 -263
  54. package/.output/server/_ssr/connector-icon-DrhVbhs6.mjs +190 -0
  55. package/.output/server/_ssr/connectors-BfS5tQKr.mjs +81 -0
  56. package/.output/server/_ssr/{connectors-BZly0yGF.mjs → connectors-DJI-rzPU.mjs} +21 -10
  57. package/.output/server/_ssr/{createServerRpc-DPDrnFdH.mjs → createServerRpc-DDrp2nLT.mjs} +2 -2
  58. package/.output/server/_ssr/{gaps-D2Zh8sEo.mjs → gaps-CcvHiLcj.mjs} +18 -10
  59. package/.output/server/_ssr/inbox-D1ef761v.mjs +178 -0
  60. package/.output/server/_ssr/loop-form-DWwOR05R.mjs +346 -0
  61. package/.output/server/_ssr/{loops-Og_G3KyZ.mjs → loops-6WhUe_lc.mjs} +228 -25
  62. package/.output/server/_ssr/loops-DHPjzG-t.mjs +217 -0
  63. package/.output/server/_ssr/new-ChKBdcXJ.mjs +245 -0
  64. package/.output/server/_ssr/page-DZVxKvdn.mjs +120 -0
  65. package/.output/server/_ssr/{router-BbrBz36P.mjs → router-DdwREiOf.mjs} +167 -489
  66. package/.output/server/_ssr/runners-CK9Cx9fS.mjs +217 -0
  67. package/.output/server/_ssr/runners-CrznFPHt.mjs +140 -0
  68. package/.output/server/_ssr/runners-W-pgo5yo.mjs +55 -0
  69. package/.output/server/_ssr/{secrets-CRnpwGBh.mjs → secrets-CV5scFlt.mjs} +2 -2
  70. package/.output/server/_ssr/select-BtndHhHb.mjs +76 -0
  71. package/.output/server/_ssr/{setting-fields-mpXfGftI.mjs → setting-fields-LNgywAW7.mjs} +25 -20
  72. package/.output/server/_ssr/ssr.mjs +49 -40
  73. package/.output/server/_ssr/{start-BgTj-h_C.mjs → start-C_j-e4vF.mjs} +10 -6
  74. package/.output/server/_ssr/{switch-1pnd_bPJ.mjs → switch-odxNO_S4.mjs} +3 -3
  75. package/.output/server/_ssr/task-list-Dnmq_WeE.mjs +150 -0
  76. package/.output/server/_ssr/{tasks-LIi-W4cy.mjs → tasks-D-kXLgVP.mjs} +13 -13
  77. package/.output/server/_ssr/{tasks-B_QmDFVs.mjs → tasks-D7aUvA33.mjs} +55 -17
  78. package/.output/server/_ssr/{textarea-CHJTKtsJ.mjs → textarea-D2c_vTIC.mjs} +2 -2
  79. package/.output/server/_ssr/time-Cy8TZP0Z.mjs +13 -0
  80. package/.output/server/_ssr/use-live-tasks-BzhTkEOL.mjs +40 -0
  81. package/.output/server/_tanstack-start-manifest_v-2HUdn-2E.mjs +166 -0
  82. package/.output/server/_taskId-D3KkNJW1.mjs +263 -0
  83. package/.output/server/index.mjs +204 -162
  84. package/README.md +54 -19
  85. package/dist/cli.mjs +185 -67
  86. package/dist/dispatcher.mjs +1443 -277
  87. package/dist/runner.mjs +333 -46
  88. package/drizzle/0025_prompt_tasks_done.sql +2 -0
  89. package/drizzle/0026_guidance_into_prompt.sql +3 -0
  90. package/drizzle/0027_relative_folders.sql +5 -0
  91. package/drizzle/0028_runner_version.sql +5 -0
  92. package/drizzle/meta/_journal.json +29 -1
  93. package/package.json +23 -17
  94. package/.output/public/assets/_connectorId-m67WbiJ8.js +0 -1
  95. package/.output/public/assets/_loopId-Bf4K5sdd.js +0 -1
  96. package/.output/public/assets/_taskId-eCKkcVOx.js +0 -1
  97. package/.output/public/assets/alert-BT2EVMJP.js +0 -1
  98. package/.output/public/assets/arrow-left-CWUZt6k2.js +0 -1
  99. package/.output/public/assets/arrow-right-dy_oOg_c.js +0 -1
  100. package/.output/public/assets/connection-status-DCqqmY_6.js +0 -1
  101. package/.output/public/assets/connector-icon-qGpNsPgH.js +0 -1
  102. package/.output/public/assets/connectors-DxXlc9zF.js +0 -1
  103. package/.output/public/assets/external-link-DC11orFA.js +0 -1
  104. package/.output/public/assets/gaps-CoTA-PzA.js +0 -1
  105. package/.output/public/assets/inbox-CLEXUXCI.js +0 -1
  106. package/.output/public/assets/index-Cndsw84p.js +0 -16
  107. package/.output/public/assets/loader-B4Epchm_.js +0 -1
  108. package/.output/public/assets/loop-form-BvizlZdR.js +0 -1
  109. package/.output/public/assets/loops-Dbe_mf5T.js +0 -1
  110. package/.output/public/assets/new-DPEaXKAY.js +0 -1
  111. package/.output/public/assets/play-DD4xQgvi.js +0 -1
  112. package/.output/public/assets/preload-helper-CfdAYKD7.js +0 -3
  113. package/.output/public/assets/rolldown-runtime-CbXtAM7H.js +0 -1
  114. package/.output/public/assets/runners-BVBggS5B.js +0 -1
  115. package/.output/public/assets/select-Cppu-hti.js +0 -1
  116. package/.output/public/assets/setting-fields-BT1naVJX.js +0 -3
  117. package/.output/public/assets/styles-D3sonCfX.css +0 -2
  118. package/.output/public/assets/switch-hRIbNGOj.js +0 -1
  119. package/.output/public/assets/task-list-CrptnI1N.js +0 -1
  120. package/.output/public/assets/textarea-Fyuzi6Vp.js +0 -1
  121. package/.output/public/assets/trash-2-BXZzBsoV.js +0 -1
  122. package/.output/public/assets/useValueChanged-VVyq4hb9.js +0 -1
  123. package/.output/server/_connectorId-DcSnoRjk.mjs +0 -421
  124. package/.output/server/_loopId-G_TAkYtS.mjs +0 -272
  125. package/.output/server/_ssr/access-B7TcOZ7F.mjs +0 -42
  126. package/.output/server/_ssr/connection-status-BZr3Y-IC.mjs +0 -31
  127. package/.output/server/_ssr/connector-icon-CFrrHjzR.mjs +0 -37
  128. package/.output/server/_ssr/connectors-4yzKb0KG.mjs +0 -106
  129. package/.output/server/_ssr/inbox-C2VBGLa5.mjs +0 -114
  130. package/.output/server/_ssr/loop-form-D-U-kU4k.mjs +0 -413
  131. package/.output/server/_ssr/loops-D0XJ8eBb.mjs +0 -222
  132. package/.output/server/_ssr/new-CajvgIog.mjs +0 -169
  133. package/.output/server/_ssr/runners-B_WuF8UJ.mjs +0 -32
  134. package/.output/server/_ssr/runners-D-0_lfiq.mjs +0 -106
  135. package/.output/server/_ssr/runners-zqF_zbEc.mjs +0 -116
  136. package/.output/server/_ssr/task-list-BnQJ94Dk.mjs +0 -187
  137. package/.output/server/_tanstack-start-manifest_v-BCHAazE8.mjs +0 -129
  138. package/.output/server/_taskId-CIv0ajIx.mjs +0 -256
@@ -0,0 +1,245 @@
1
+ import { K as require_jsx_runtime } from "../_libs/@base-ui/react+[...].mjs";
2
+ import { f as Link, p as useNavigate } from "../_libs/@tanstack/react-router+[...].mjs";
3
+ import { l as connectorWorkflow, n as allTriggers, r as allWorkflows, s as connectorManifest } from "./connections-Cqvb6Gw2.mjs";
4
+ import { f as PencilLine } from "../_libs/lucide-react.mjs";
5
+ import { a as Route$9 } from "./router-DdwREiOf.mjs";
6
+ import { t as ConnectorIcon } from "./connector-icon-DrhVbhs6.mjs";
7
+ import { n as Field, o as PageHeader } from "./page-DZVxKvdn.mjs";
8
+ import { a as SelectValue, i as SelectTrigger, n as SelectContent, r as SelectItem, t as Select$1 } from "./select-BtndHhHb.mjs";
9
+ import { t as LoopForm } from "./loop-form-DWwOR05R.mjs";
10
+ //#region node_modules/.nitro/vite/services/ssr/assets/new-ChKBdcXJ.js
11
+ var import_jsx_runtime = require_jsx_runtime();
12
+ /**
13
+ * One of a connector's workflows, as a loop nobody has saved yet.
14
+ *
15
+ * Nothing here touches the database, which is the point: choosing a workflow
16
+ * used to create the loop, so a look around the page left a live loop behind,
17
+ * enabled and with none of its questions answered. Now choosing only fills a
18
+ * form in, and the loop begins at Save.
19
+ *
20
+ * Deliberately client-safe, so the form can be filled in without a round trip
21
+ * and without anything on the server having to remember a half-made loop.
22
+ */
23
+ function draftForWorkflow(connectorId, workflowId) {
24
+ const workflow = connectorWorkflow(connectorId, workflowId);
25
+ if (!workflow) throw new Error(`Unknown workflow: ${workflowId}`);
26
+ return {
27
+ id: null,
28
+ name: workflow.name,
29
+ connectorId,
30
+ workflowId,
31
+ prompt: workflow.prompt,
32
+ guidance: null,
33
+ agentId: null,
34
+ settings: {},
35
+ actionConnectorId: workflow.actionConnectorId ?? connectorId,
36
+ actionId: workflow.actionId,
37
+ actionTarget: workflow.actionTarget ?? {},
38
+ pollEveryMs: workflow.pollEveryMs ?? null,
39
+ enabled: true
40
+ };
41
+ }
42
+ /** The trigger a custom loop starts on before anything is picked. */
43
+ var CUSTOM_DEFAULT = {
44
+ connector: "slack",
45
+ workflow: "slack.ask"
46
+ };
47
+ function NewLoopPage() {
48
+ const { connector, workflow, custom } = Route$9.useSearch();
49
+ const chosen = connector && workflow && connectorWorkflow(connector, workflow) ? {
50
+ connector,
51
+ workflow
52
+ } : null;
53
+ if (custom) {
54
+ const start = chosen ?? CUSTOM_DEFAULT;
55
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(CustomLoop, {
56
+ connectorId: start.connector,
57
+ workflowId: start.workflow
58
+ });
59
+ }
60
+ return chosen ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ShapeLoop, {
61
+ connectorId: chosen.connector,
62
+ workflowId: chosen.workflow
63
+ }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ChooseWorkflow, {});
64
+ }
65
+ /**
66
+ * The second step, and the one that makes a loop. Nothing is written down
67
+ * until the form is saved.
68
+ */
69
+ function ShapeLoop({ connectorId, workflowId }) {
70
+ const workflow = connectorWorkflow(connectorId, workflowId);
71
+ const connector = connectorManifest(connectorId);
72
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
73
+ className: "flex flex-col gap-8",
74
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(PageHeader, {
75
+ back: {
76
+ to: "/loops/new",
77
+ label: "New loop"
78
+ },
79
+ icon: connector ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ConnectorIcon, {
80
+ icon: connector.icon,
81
+ accent: connector.accent
82
+ }) : null,
83
+ title: workflow.name,
84
+ description: workflow.summary
85
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(LoopForm, { loop: draftForWorkflow(connectorId, workflowId) })]
86
+ });
87
+ }
88
+ /**
89
+ * A loop with your own prompt. Underneath it is still one of the workflows,
90
+ * since a workflow is what knows how to watch for something and read the
91
+ * answer, but it starts with an empty prompt and a trigger you pick.
92
+ */
93
+ function CustomLoop({ connectorId, workflowId }) {
94
+ const navigate = useNavigate();
95
+ const draft = {
96
+ ...draftForWorkflow(connectorId, workflowId),
97
+ name: "Custom loop",
98
+ prompt: ""
99
+ };
100
+ const picker = /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Field, {
101
+ label: "Starts when",
102
+ htmlFor: "custom-trigger",
103
+ className: "sm:max-w-sm",
104
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Select$1, {
105
+ value: `${connectorId}::${workflowId}`,
106
+ onValueChange: (value) => {
107
+ if (!value) return;
108
+ const [connector, workflow] = value.split("::");
109
+ navigate({
110
+ to: "/loops/new",
111
+ search: {
112
+ custom: true,
113
+ connector,
114
+ workflow
115
+ },
116
+ replace: true
117
+ });
118
+ },
119
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(SelectTrigger, {
120
+ id: "custom-trigger",
121
+ className: "w-full",
122
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SelectValue, { children: () => {
123
+ return connectorWorkflow(connectorId, workflowId)?.when ?? workflowId;
124
+ } })
125
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SelectContent, { children: allTriggers().map(({ connector, trigger }) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SelectItem, {
126
+ value: `${connector.id}::${trigger.id}`,
127
+ children: trigger.when
128
+ }, `${connector.id}::${trigger.id}`)) })]
129
+ })
130
+ });
131
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
132
+ className: "flex flex-col gap-8",
133
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(PageHeader, {
134
+ back: {
135
+ to: "/loops/new",
136
+ label: "New loop"
137
+ },
138
+ icon: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(CustomIcon, {}),
139
+ title: "Custom loop",
140
+ description: "Pick what starts it, then say what the agent should do."
141
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(LoopForm, {
142
+ loop: draft,
143
+ trigger: picker
144
+ }, workflowId)]
145
+ });
146
+ }
147
+ function CustomIcon() {
148
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
149
+ className: "flex size-10 shrink-0 items-center justify-center rounded-lg bg-muted text-foreground",
150
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(PencilLine, { className: "size-5" })
151
+ });
152
+ }
153
+ /** How many loops already use a workflow, said as a sentence rather than a count. */
154
+ function inUse(loops, workflowId) {
155
+ const count = loops.filter((loop) => loop.workflowId === workflowId).length;
156
+ if (count === 0) return null;
157
+ return count === 1 ? "You have 1 loop like this" : `You have ${count} loops like this`;
158
+ }
159
+ function ChoiceCard({ icon, title, summary, note, ...link }) {
160
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Link, {
161
+ to: "/loops/new",
162
+ search: link.search,
163
+ className: "flex items-start gap-3 rounded-xl bg-card p-4 ring-1 ring-foreground/10 transition-colors hover:bg-muted/50",
164
+ children: [icon, /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
165
+ className: "min-w-0 flex-1",
166
+ children: [
167
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
168
+ className: "text-sm font-medium",
169
+ children: title
170
+ }),
171
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
172
+ className: "mt-1 text-xs text-muted-foreground",
173
+ children: summary
174
+ }),
175
+ note ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
176
+ className: "mt-2 text-xs text-muted-foreground",
177
+ children: note
178
+ }) : null
179
+ ]
180
+ })]
181
+ });
182
+ }
183
+ function workflowCard(connector, workflow, loops) {
184
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ChoiceCard, {
185
+ icon: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ConnectorIcon, {
186
+ icon: connector.icon,
187
+ accent: connector.accent,
188
+ className: "size-8"
189
+ }),
190
+ title: workflow.name,
191
+ summary: workflow.summary,
192
+ note: inUse(loops, workflow.id),
193
+ search: {
194
+ connector: connector.id,
195
+ workflow: workflow.id
196
+ }
197
+ }, workflow.id);
198
+ }
199
+ /**
200
+ * Every loop is one of the workflows a connector offers, or a custom one
201
+ * built on a workflow's trigger. Custom and Schedule come first: they are the
202
+ * two not tied to something arriving from a service.
203
+ */
204
+ function ChooseWorkflow() {
205
+ const { loops } = Route$9.useLoaderData();
206
+ const all = allWorkflows();
207
+ const scheduled = all.filter(({ connector }) => connector.id === "schedule");
208
+ const rest = all.filter(({ connector }) => connector.id !== "schedule");
209
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
210
+ className: "flex flex-col gap-6",
211
+ children: [
212
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(PageHeader, {
213
+ back: {
214
+ to: "/loops",
215
+ label: "Loops"
216
+ },
217
+ title: "New loop"
218
+ }),
219
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
220
+ className: "grid gap-3 sm:grid-cols-2",
221
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(ChoiceCard, {
222
+ icon: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
223
+ className: "flex size-8 shrink-0 items-center justify-center rounded-lg bg-muted",
224
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(PencilLine, { className: "size-4" })
225
+ }),
226
+ title: "Custom loop",
227
+ summary: "Pick a trigger and write your own prompt.",
228
+ search: { custom: true }
229
+ }), scheduled.map(({ connector, workflow }) => workflowCard(connector, workflow, loops))]
230
+ }),
231
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
232
+ className: "flex flex-col gap-3",
233
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h2", {
234
+ className: "text-sm font-medium text-muted-foreground",
235
+ children: "From a connector"
236
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
237
+ className: "grid gap-3 sm:grid-cols-2",
238
+ children: rest.map(({ connector, workflow }) => workflowCard(connector, workflow, loops))
239
+ })]
240
+ })
241
+ ]
242
+ });
243
+ }
244
+ //#endregion
245
+ export { NewLoopPage as component };
@@ -0,0 +1,120 @@
1
+ import "../_runtime.mjs";
2
+ import { K as require_jsx_runtime, q as require_react } from "../_libs/@base-ui/react+[...].mjs";
3
+ import { f as Link } from "../_libs/@tanstack/react-router+[...].mjs";
4
+ import { I as ChevronLeft } from "../_libs/lucide-react.mjs";
5
+ import { P as cn } from "./router-DdwREiOf.mjs";
6
+ require_react();
7
+ var import_jsx_runtime = require_jsx_runtime();
8
+ function Label({ className, ...props }) {
9
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("label", {
10
+ "data-slot": "label",
11
+ className: cn("flex items-center gap-2 text-sm leading-none font-medium select-none group-data-[disabled=true]:pointer-events-none group-data-[disabled=true]:opacity-50 peer-disabled:cursor-not-allowed peer-disabled:opacity-50", className),
12
+ ...props
13
+ });
14
+ }
15
+ /**
16
+ * The top of every page: where it sits, what it is called, and what can be
17
+ * done from here. One shape everywhere, so pages differ in what they show
18
+ * rather than in how far the title is from the edge.
19
+ */
20
+ function PageHeader({ title, description, back, icon, actions, children }) {
21
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("header", {
22
+ className: "flex flex-col gap-3",
23
+ children: [back ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Link, {
24
+ to: back.to,
25
+ params: back.params,
26
+ search: back.search,
27
+ className: "-ml-1 flex w-fit items-center gap-0.5 text-sm text-muted-foreground hover:text-foreground",
28
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(ChevronLeft, { className: "size-4" }), back.label]
29
+ }) : null, /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
30
+ className: "flex flex-wrap items-start gap-3",
31
+ children: [
32
+ icon,
33
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
34
+ className: "min-w-0 flex-1 basis-56",
35
+ children: [
36
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("h1", {
37
+ className: "text-xl font-semibold tracking-tight",
38
+ children: title
39
+ }),
40
+ description ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
41
+ className: "mt-1 text-sm text-muted-foreground",
42
+ children: description
43
+ }) : null,
44
+ children
45
+ ]
46
+ }),
47
+ actions ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
48
+ className: "flex shrink-0 items-center gap-2",
49
+ children: actions
50
+ }) : null
51
+ ]
52
+ })]
53
+ });
54
+ }
55
+ /** A labelled control, with at most one short line of help under it. */
56
+ function Field({ label, htmlFor, hint, className, children }) {
57
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
58
+ className: cn("flex flex-col gap-1.5", className),
59
+ children: [
60
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Label, {
61
+ htmlFor,
62
+ children: label
63
+ }),
64
+ children,
65
+ hint ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
66
+ className: "text-xs text-muted-foreground",
67
+ children: hint
68
+ }) : null
69
+ ]
70
+ });
71
+ }
72
+ /**
73
+ * One titled block of a form or a detail page. Title on the left and fields
74
+ * on the right on a wide screen, stacked on a narrow one.
75
+ */
76
+ function Section({ title, description, children, className }) {
77
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("section", {
78
+ className: cn("grid gap-4 border-t py-6 first:border-t-0 first:pt-0 md:grid-cols-[11rem_1fr] md:gap-8", className),
79
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h2", {
80
+ className: "text-sm font-medium",
81
+ children: title
82
+ }), description ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
83
+ className: "mt-1 text-xs text-muted-foreground",
84
+ children: description
85
+ }) : null] }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
86
+ className: "flex min-w-0 flex-col gap-4",
87
+ children
88
+ })]
89
+ });
90
+ }
91
+ /** A list of rows inside one bordered box, rather than a stack of cards. */
92
+ function List({ className, children }) {
93
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
94
+ className: cn("divide-y overflow-hidden rounded-xl bg-card ring-1 ring-foreground/10", className),
95
+ children
96
+ });
97
+ }
98
+ /** What a list says when it has nothing in it. */
99
+ function Empty({ children, action }) {
100
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
101
+ className: "flex flex-col items-center gap-3 rounded-xl border border-dashed px-6 py-10 text-center text-sm text-muted-foreground",
102
+ children: [children, action]
103
+ });
104
+ }
105
+ /** Tabs that are links, so a tab can be bookmarked and shared. */
106
+ function LinkTabs({ items }) {
107
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("nav", {
108
+ className: "flex gap-4 border-b",
109
+ children: items.map((item, index) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Link, {
110
+ to: item.to,
111
+ params: item.params,
112
+ search: item.search,
113
+ replace: true,
114
+ className: cn("-mb-px flex items-center gap-1.5 border-b-2 pb-2 text-sm transition-colors", item.active ? "border-foreground font-medium text-foreground" : "border-transparent text-muted-foreground hover:text-foreground"),
115
+ children: item.label
116
+ }, index))
117
+ });
118
+ }
119
+ //#endregion
120
+ export { List as a, LinkTabs as i, Field as n, PageHeader as o, Label as r, Section as s, Empty as t };