loopable-cli 0.1.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 (133) hide show
  1. package/.output/nitro.json +17 -0
  2. package/.output/public/apple-touch-icon.png +0 -0
  3. package/.output/public/assets/_connectorId-BWjYn5tm.js +1 -0
  4. package/.output/public/assets/_loopId-Ds4RkyEc.js +1 -0
  5. package/.output/public/assets/_taskId-BOzICXDf.js +1 -0
  6. package/.output/public/assets/alert-Bn9-Zm0l.js +1 -0
  7. package/.output/public/assets/arrow-left-BF9juV9T.js +1 -0
  8. package/.output/public/assets/arrow-right-CzqvnOY1.js +1 -0
  9. package/.output/public/assets/button-HCY6DCY-.js +1 -0
  10. package/.output/public/assets/connection-status-CYZB8kLy.js +1 -0
  11. package/.output/public/assets/connector-icon-BZ_MUJV_.js +1 -0
  12. package/.output/public/assets/connectors-BvzttfSu.js +1 -0
  13. package/.output/public/assets/connectors-DdJNwRN_.js +1 -0
  14. package/.output/public/assets/external-link-D46X-bXa.js +1 -0
  15. package/.output/public/assets/gaps-D-I6xiDc.js +1 -0
  16. package/.output/public/assets/geist-cyrillic-ext-wght-normal-DjL33-gN.woff2 +0 -0
  17. package/.output/public/assets/geist-cyrillic-wght-normal-BEAKL7Jp.woff2 +0 -0
  18. package/.output/public/assets/geist-latin-ext-wght-normal-DC-KSUi6.woff2 +0 -0
  19. package/.output/public/assets/geist-latin-wght-normal-BgDaEnEv.woff2 +0 -0
  20. package/.output/public/assets/geist-vietnamese-wght-normal-6IgcOCM7.woff2 +0 -0
  21. package/.output/public/assets/inbox-BUUu9xxE.js +1 -0
  22. package/.output/public/assets/index-ztzex0FN.js +10 -0
  23. package/.output/public/assets/loader-CcBl2u8m.js +1 -0
  24. package/.output/public/assets/loop-form-dB3CLcZb.js +1 -0
  25. package/.output/public/assets/loops-DRunQrxL.js +1 -0
  26. package/.output/public/assets/loops-oSdqMd29.js +1 -0
  27. package/.output/public/assets/manifests-DNMqf7Vi.js +7 -0
  28. package/.output/public/assets/new-uyFxVjuB.js +1 -0
  29. package/.output/public/assets/preload-helper-ORbuV86A.js +3 -0
  30. package/.output/public/assets/runners-DSU3r5Ww.js +1 -0
  31. package/.output/public/assets/setting-fields-ixkpdBb-.js +3 -0
  32. package/.output/public/assets/styles-DZL5V1o7.css +2 -0
  33. package/.output/public/assets/switch-d5ummmHY.js +1 -0
  34. package/.output/public/assets/task-list-BpOStt9v.js +1 -0
  35. package/.output/public/assets/tasks-B8MsKgic.js +1 -0
  36. package/.output/public/assets/trash-2-D6u6NpzO.js +1 -0
  37. package/.output/public/favicon.svg +9 -0
  38. package/.output/server/_chunks/ssr-renderer.mjs +26 -0
  39. package/.output/server/_connectorId-8nb5yOzG.mjs +421 -0
  40. package/.output/server/_libs/@base-ui/react+[...].mjs +12841 -0
  41. package/.output/server/_libs/@tanstack/react-router+[...].mjs +14349 -0
  42. package/.output/server/_libs/class-variance-authority+clsx.mjs +69 -0
  43. package/.output/server/_libs/dijkstrajs.mjs +118 -0
  44. package/.output/server/_libs/drizzle-orm.mjs +4349 -0
  45. package/.output/server/_libs/h3+rou3+srvx.mjs +1361 -0
  46. package/.output/server/_libs/lucide-react.mjs +911 -0
  47. package/.output/server/_libs/next-themes.mjs +53 -0
  48. package/.output/server/_libs/pngjs.mjs +1680 -0
  49. package/.output/server/_libs/qrcode.mjs +2583 -0
  50. package/.output/server/_libs/sonner.mjs +955 -0
  51. package/.output/server/_libs/tailwind-merge.mjs +3380 -0
  52. package/.output/server/_libs/tanstack__history.mjs +341 -0
  53. package/.output/server/_libs/ufo.mjs +64 -0
  54. package/.output/server/_loopId-BsUL1SeL.mjs +272 -0
  55. package/.output/server/_runtime.mjs +35 -0
  56. package/.output/server/_ssr/access-zIl15o8y.mjs +42 -0
  57. package/.output/server/_ssr/agents-Btql102J.mjs +657 -0
  58. package/.output/server/_ssr/agents-DAOZPgO2.mjs +76 -0
  59. package/.output/server/_ssr/alert-NEiOCTOl.mjs +37 -0
  60. package/.output/server/_ssr/callback-CUINvl7M.mjs +62 -0
  61. package/.output/server/_ssr/client-CKkOfh-s.mjs +335 -0
  62. package/.output/server/_ssr/connection-status-Bi5peUAk.mjs +31 -0
  63. package/.output/server/_ssr/connections-qnw2GVlP.mjs +2542 -0
  64. package/.output/server/_ssr/connector-icon-DZXQLLFo.mjs +37 -0
  65. package/.output/server/_ssr/connectors-BHNwuIMj.mjs +106 -0
  66. package/.output/server/_ssr/connectors-C28g0i4c.mjs +83 -0
  67. package/.output/server/_ssr/createServerRpc-DPDrnFdH.mjs +12 -0
  68. package/.output/server/_ssr/empty-plugin-adapters-BJ4m9L8g.mjs +5 -0
  69. package/.output/server/_ssr/gaps-RAFSXLZf.mjs +53 -0
  70. package/.output/server/_ssr/inbox-k5zHergU.mjs +35 -0
  71. package/.output/server/_ssr/loop-form-DlObSewZ.mjs +412 -0
  72. package/.output/server/_ssr/loops-APFcP0y6.mjs +311 -0
  73. package/.output/server/_ssr/loops-xt2Bn7_q.mjs +222 -0
  74. package/.output/server/_ssr/new-DfKyd2Wa.mjs +169 -0
  75. package/.output/server/_ssr/router-3WmpE5b_.mjs +1553 -0
  76. package/.output/server/_ssr/runners-By-mwc3F.mjs +32 -0
  77. package/.output/server/_ssr/runners-DI_NxpHC.mjs +116 -0
  78. package/.output/server/_ssr/runners-DtXs4Q8a.mjs +106 -0
  79. package/.output/server/_ssr/secrets-Hqti-niS.mjs +199 -0
  80. package/.output/server/_ssr/setting-fields-8vKFj4df.mjs +92 -0
  81. package/.output/server/_ssr/ssr.mjs +6605 -0
  82. package/.output/server/_ssr/start-Bdc2GJUI.mjs +51 -0
  83. package/.output/server/_ssr/switch-ReNglgH6.mjs +18 -0
  84. package/.output/server/_ssr/task-list-CUITIqkb.mjs +186 -0
  85. package/.output/server/_ssr/tasks-SAjNovX6.mjs +110 -0
  86. package/.output/server/_ssr/tasks-vcoodp_D.mjs +533 -0
  87. package/.output/server/_tanstack-start-manifest_v-C0cP5F0M.mjs +125 -0
  88. package/.output/server/_taskId-CXS3lod0.mjs +249 -0
  89. package/.output/server/index.mjs +541 -0
  90. package/README.md +81 -0
  91. package/dist/cli.mjs +165 -0
  92. package/dist/dispatcher.mjs +9871 -0
  93. package/dist/runner.mjs +657 -0
  94. package/drizzle/0000_cold_demogoblin.sql +29 -0
  95. package/drizzle/0001_fancy_blonde_phantom.sql +13 -0
  96. package/drizzle/0002_spooky_smiling_tiger.sql +16 -0
  97. package/drizzle/0003_small_golden_guardian.sql +25 -0
  98. package/drizzle/0004_wonderful_thunderbolts.sql +39 -0
  99. package/drizzle/0005_named_workflows.sql +7 -0
  100. package/drizzle/0006_signals.sql +18 -0
  101. package/drizzle/0007_review_comments.sql +1 -0
  102. package/drizzle/0008_held_signals.sql +1 -0
  103. package/drizzle/0009_work_item_ref.sql +58 -0
  104. package/drizzle/0010_signal_payload.sql +2 -0
  105. package/drizzle/0011_rule_poll_cursor.sql +1 -0
  106. package/drizzle/0012_loops.sql +63 -0
  107. package/drizzle/0013_loop_owns_action_and_prompt.sql +154 -0
  108. package/drizzle/0014_loop_poll_every.sql +4 -0
  109. package/drizzle/0015_machines.sql +10 -0
  110. package/drizzle/0016_task_machine.sql +1 -0
  111. package/drizzle/0017_loop_machine.sql +1 -0
  112. package/drizzle/0018_runners.sql +1 -0
  113. package/drizzle/0019_task_runner.sql +1 -0
  114. package/drizzle/0020_loop_runner.sql +1 -0
  115. package/drizzle/0021_drop_runner_kind.sql +1 -0
  116. package/drizzle/0022_drop_loop_runner.sql +1 -0
  117. package/drizzle/0023_shared_host.sql +6 -0
  118. package/drizzle/meta/0000_snapshot.json +206 -0
  119. package/drizzle/meta/0001_snapshot.json +284 -0
  120. package/drizzle/meta/0002_snapshot.json +390 -0
  121. package/drizzle/meta/0003_snapshot.json +566 -0
  122. package/drizzle/meta/0004_snapshot.json +633 -0
  123. package/drizzle/meta/0005_snapshot.json +626 -0
  124. package/drizzle/meta/0006_snapshot.json +752 -0
  125. package/drizzle/meta/0007_snapshot.json +759 -0
  126. package/drizzle/meta/0008_snapshot.json +766 -0
  127. package/drizzle/meta/0009_snapshot.json +752 -0
  128. package/drizzle/meta/0010_snapshot.json +766 -0
  129. package/drizzle/meta/0011_snapshot.json +773 -0
  130. package/drizzle/meta/0012_snapshot.json +773 -0
  131. package/drizzle/meta/0013_snapshot.json +817 -0
  132. package/drizzle/meta/_journal.json +174 -0
  133. package/package.json +88 -0
@@ -0,0 +1,249 @@
1
+ import { i as __toESM } from "./_runtime.mjs";
2
+ import { U as require_jsx_runtime, W as require_react } from "./_libs/@base-ui/react+[...].mjs";
3
+ import { f as Link, m as useRouter } from "./_libs/@tanstack/react-router+[...].mjs";
4
+ import { a as connectorManifest, i as connectorAction } from "./_ssr/connections-qnw2GVlP.mjs";
5
+ import { B as ArrowLeft, C as ExternalLink, E as CircleStop, g as Loader, x as FileCode } from "./_libs/lucide-react.mjs";
6
+ import { n as toast } from "./_libs/sonner.mjs";
7
+ import { A as stopTask, B as CardTitle, C as Button$1, I as Badge, L as Card, R as CardContent, c as Route$12, m as isTaskActive, p as useLiveTasks, z as CardHeader } from "./_ssr/router-3WmpE5b_.mjs";
8
+ import { n as AlertDescription, r as AlertTitle, t as Alert } from "./_ssr/alert-NEiOCTOl.mjs";
9
+ import { i as taskTitle, r as TaskStateLabel, t as KIND_LABEL } from "./_ssr/task-list-CUITIqkb.mjs";
10
+ //#region node_modules/.nitro/vite/services/ssr/assets/_taskId-CXS3lod0.js
11
+ var import_react = /* @__PURE__ */ __toESM(require_react());
12
+ var import_jsx_runtime = require_jsx_runtime();
13
+ function TaskPage() {
14
+ const { task, log } = Route$12.useLoaderData();
15
+ const writer = connectorManifest(task.actionConnectorId);
16
+ const action = connectorAction(task.actionConnectorId, task.actionId);
17
+ useLiveTasks([task]);
18
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
19
+ className: "flex flex-col gap-6",
20
+ children: [
21
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Link, {
22
+ to: "/inbox",
23
+ className: "flex items-center gap-1.5 text-sm text-muted-foreground hover:text-foreground",
24
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(ArrowLeft, { className: "size-4" }), "Inbox"]
25
+ }),
26
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("header", {
27
+ className: "flex items-start gap-4",
28
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
29
+ className: "flex-1",
30
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h1", {
31
+ className: "text-xl font-semibold tracking-tight",
32
+ children: taskTitle(task)
33
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", {
34
+ className: "mt-1 text-sm text-muted-foreground",
35
+ children: [
36
+ task.sourceRef,
37
+ " ·",
38
+ " ",
39
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Link, {
40
+ to: "/loops/$loopId",
41
+ params: { loopId: task.loopId },
42
+ className: "underline",
43
+ children: task.loopName
44
+ })
45
+ ]
46
+ })]
47
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
48
+ className: "flex flex-col items-end gap-2",
49
+ children: [
50
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TaskStateLabel, { state: task.state }),
51
+ task.dryRun ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Badge, {
52
+ variant: "outline",
53
+ children: "Dry run"
54
+ }) : null,
55
+ isTaskActive(task.state) ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(StopButton, { task }) : null
56
+ ]
57
+ })]
58
+ }),
59
+ task.error ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Alert, {
60
+ variant: task.state === "failed" ? "destructive" : void 0,
61
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(AlertTitle, { children: task.state === "failed" ? "This run failed" : task.state === "cancelled" ? "Stopped before it finished" : "Waiting to try again" }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(AlertDescription, {
62
+ className: "whitespace-pre-wrap",
63
+ children: task.error
64
+ })]
65
+ }) : null,
66
+ task.state === "skipped" ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Alert, { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(AlertTitle, { children: "Nothing was written" }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(AlertDescription, { children: "The agent judged there was nothing worth posting, so Loopable stayed quiet." })] }) : null,
67
+ task.output ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Card, { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(CardHeader, {
68
+ className: "flex flex-row items-center gap-3",
69
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(CardTitle, {
70
+ className: "flex-1 text-base",
71
+ children: task.state === "done" ? "What was written" : "What the agent wrote"
72
+ }), task.resultUrl ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Button$1, {
73
+ variant: "outline",
74
+ size: "sm",
75
+ nativeButton: false,
76
+ render: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("a", {
77
+ href: task.resultUrl,
78
+ target: "_blank",
79
+ rel: "noreferrer"
80
+ }),
81
+ children: [
82
+ "See it on ",
83
+ writer?.name ?? task.actionConnectorId,
84
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ExternalLink, {})
85
+ ]
86
+ }) : null]
87
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(CardContent, {
88
+ className: "flex flex-col gap-4",
89
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("pre", {
90
+ className: "whitespace-pre-wrap break-words text-sm",
91
+ children: task.output
92
+ }), task.comments.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Comments, { comments: task.comments }) : null]
93
+ })] }) : null,
94
+ log ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(AgentLog, {
95
+ log,
96
+ live: isTaskActive(task.state)
97
+ }) : null,
98
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Card, { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(CardHeader, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(CardTitle, {
99
+ className: "text-base",
100
+ children: "How this ran"
101
+ }) }), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(CardContent, {
102
+ className: "flex flex-col gap-3 text-sm",
103
+ children: [
104
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Row, {
105
+ label: "Source",
106
+ children: task.sourceUrl ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("a", {
107
+ href: task.sourceUrl,
108
+ target: "_blank",
109
+ rel: "noreferrer",
110
+ className: "inline-flex items-center gap-1 underline",
111
+ children: [
112
+ KIND_LABEL[task.sourceKind],
113
+ " ",
114
+ task.sourceRef,
115
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ExternalLink, { className: "size-3" })
116
+ ]
117
+ }) : /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { children: [
118
+ KIND_LABEL[task.sourceKind],
119
+ " ",
120
+ task.sourceRef
121
+ ] })
122
+ }),
123
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Row, {
124
+ label: "Action",
125
+ children: [action?.name ?? task.actionId, task.actionConnectorId === task.connectorId ? null : ` on ${writer?.name ?? task.actionConnectorId}`]
126
+ }),
127
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Row, {
128
+ label: "Agent",
129
+ children: task.agentId ?? "unknown"
130
+ }),
131
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Row, {
132
+ label: "Queued",
133
+ children: new Date(task.createdAt).toLocaleString()
134
+ }),
135
+ task.attempts > 1 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Row, {
136
+ label: "Attempt",
137
+ children: task.attempts
138
+ }) : null,
139
+ task.durationMs ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Row, {
140
+ label: "Took",
141
+ children: [(task.durationMs / 1e3).toFixed(1), "s"]
142
+ }) : null,
143
+ task.agentCommand ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
144
+ className: "text-xs text-muted-foreground",
145
+ children: "Command"
146
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("pre", {
147
+ className: "mt-1 overflow-x-auto rounded-md bg-muted p-2.5 text-xs",
148
+ children: task.agentCommand
149
+ })] }) : null
150
+ ]
151
+ })] })
152
+ ]
153
+ });
154
+ }
155
+ /**
156
+ * The findings that go on the lines rather than in the body. Shown separately
157
+ * because that is what they are: on GitHub they will be spread across the
158
+ * diff, and this is the only place they can be read as a list.
159
+ */
160
+ function Comments({ comments }) {
161
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
162
+ className: "flex flex-col gap-3 border-t pt-4",
163
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
164
+ className: "text-xs text-muted-foreground",
165
+ children: comments.length === 1 ? "One comment, on the line it is about" : `${comments.length} comments, each on the line it is about`
166
+ }), comments.map((comment, index) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
167
+ className: "flex flex-col gap-1",
168
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", {
169
+ className: "flex items-center gap-1.5 font-mono text-xs text-muted-foreground",
170
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(FileCode, { className: "size-3.5 shrink-0" }), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", {
171
+ className: "truncate",
172
+ children: [
173
+ comment.path,
174
+ ":",
175
+ comment.startLine ? `${comment.startLine}-${comment.line}` : comment.line
176
+ ]
177
+ })]
178
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("pre", {
179
+ className: "whitespace-pre-wrap break-words border-l-2 pl-3 text-sm",
180
+ children: comment.body
181
+ })]
182
+ }, `${comment.path}:${comment.line}:${index}`))]
183
+ });
184
+ }
185
+ /**
186
+ * Everything the agent printed, as it prints it. Four minutes of a spinner
187
+ * tells you nothing; this is what tells you the run is alive, and afterwards
188
+ * it is the only place that explains a failure.
189
+ */
190
+ function AgentLog({ log, live }) {
191
+ const box = (0, import_react.useRef)(null);
192
+ (0, import_react.useEffect)(() => {
193
+ if (live && box.current) box.current.scrollTop = box.current.scrollHeight;
194
+ }, [live, log]);
195
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Card, { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(CardHeader, {
196
+ className: "flex flex-row items-center gap-3",
197
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(CardTitle, {
198
+ className: "flex-1 text-base",
199
+ children: "Agent log"
200
+ }), live ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", {
201
+ className: "flex items-center gap-1.5 text-xs text-muted-foreground",
202
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Loader, { className: "size-3.5 animate-spin" }), "still running"]
203
+ }) : null]
204
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(CardContent, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("pre", {
205
+ ref: box,
206
+ className: "max-h-80 overflow-auto rounded-md bg-muted p-2.5 text-xs leading-relaxed whitespace-pre-wrap break-words",
207
+ children: log
208
+ }) })] });
209
+ }
210
+ /**
211
+ * The run is in the other process, so this only leaves a note. The dispatcher
212
+ * sees it when it next renews its claim, which is why the button says it has
213
+ * been asked for rather than pretending it is already done.
214
+ */
215
+ function StopButton({ task }) {
216
+ const router = useRouter();
217
+ const [asked, setAsked] = (0, import_react.useState)(task.cancelRequested);
218
+ const stop = async () => {
219
+ setAsked(true);
220
+ try {
221
+ await stopTask({ data: { id: task.id } });
222
+ await router.invalidate();
223
+ } catch (error) {
224
+ setAsked(false);
225
+ toast.error(error instanceof Error ? error.message : String(error));
226
+ }
227
+ };
228
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Button$1, {
229
+ variant: "outline",
230
+ size: "sm",
231
+ onClick: stop,
232
+ disabled: asked,
233
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(CircleStop, {}), asked ? "Stopping" : "Stop"]
234
+ });
235
+ }
236
+ function Row({ label, children }) {
237
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
238
+ className: "flex gap-3",
239
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
240
+ className: "w-20 shrink-0 text-xs text-muted-foreground",
241
+ children: label
242
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
243
+ className: "text-sm",
244
+ children
245
+ })]
246
+ });
247
+ }
248
+ //#endregion
249
+ export { TaskPage as component };