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
@@ -1,272 +0,0 @@
1
- import { i as __toESM } from "./_runtime.mjs";
2
- import { U as require_jsx_runtime, W as require_react, i as TabsRoot, n as TabsPanel, r as TabsTab, t as TabsList$1 } from "./_libs/@base-ui/react+[...].mjs";
3
- import { f as Link, m as useRouter } from "./_libs/@tanstack/react-router+[...].mjs";
4
- import { t as cva } from "./_libs/class-variance-authority+clsx.mjs";
5
- import { a as connectorManifest } from "./_ssr/connections-ypex3qUd.mjs";
6
- import { B as ArrowLeft, M as CircleAlert, S as Eye, f as Play } from "./_libs/lucide-react.mjs";
7
- import { n as toast } from "./_libs/sonner.mjs";
8
- import { H as cn, L as Button$1, O as runLoopNow, R as Card, S as Input$1, T as runLoopBacklog, b as Label, f as useLiveRefresh, o as Route$10, z as CardContent } from "./_ssr/router-BbrBz36P.mjs";
9
- import { t as Switch$1 } from "./_ssr/switch-1pnd_bPJ.mjs";
10
- import { n as AlertDescription, r as AlertTitle, t as Alert } from "./_ssr/alert-DQvzE7bu.mjs";
11
- import { n as TaskList } from "./_ssr/task-list-BnQJ94Dk.mjs";
12
- import { t as LoopForm } from "./_ssr/loop-form-D-U-kU4k.mjs";
13
- import { n as issuesFor } from "./_ssr/gaps-D2Zh8sEo.mjs";
14
- //#region node_modules/.nitro/vite/services/ssr/assets/_loopId-G_TAkYtS.js
15
- var import_react = /* @__PURE__ */ __toESM(require_react());
16
- var import_jsx_runtime = require_jsx_runtime();
17
- function Tabs$1({ className, orientation = "horizontal", ...props }) {
18
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TabsRoot, {
19
- "data-slot": "tabs",
20
- "data-orientation": orientation,
21
- className: cn("group/tabs flex gap-2 data-horizontal:flex-col", className),
22
- ...props
23
- });
24
- }
25
- var tabsListVariants = cva("group/tabs-list inline-flex w-fit items-center justify-center rounded-lg p-[3px] text-muted-foreground group-data-horizontal/tabs:h-8 group-data-vertical/tabs:h-fit group-data-vertical/tabs:flex-col data-[variant=line]:rounded-none", {
26
- variants: { variant: {
27
- default: "bg-muted",
28
- line: "gap-1 bg-transparent"
29
- } },
30
- defaultVariants: { variant: "default" }
31
- });
32
- function TabsList({ className, variant = "default", ...props }) {
33
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TabsList$1, {
34
- "data-slot": "tabs-list",
35
- "data-variant": variant,
36
- className: cn(tabsListVariants({ variant }), className),
37
- ...props
38
- });
39
- }
40
- function TabsTrigger({ className, ...props }) {
41
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TabsTab, {
42
- "data-slot": "tabs-trigger",
43
- className: cn("relative inline-flex h-[calc(100%-1px)] flex-1 items-center justify-center gap-1.5 rounded-md border border-transparent px-1.5 py-0.5 text-sm font-medium whitespace-nowrap text-foreground/60 transition-all group-data-vertical/tabs:w-full group-data-vertical/tabs:justify-start hover:text-foreground focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 focus-visible:outline-1 focus-visible:outline-ring disabled:pointer-events-none disabled:opacity-50 has-data-[icon=inline-end]:pr-1 has-data-[icon=inline-start]:pl-1 aria-disabled:pointer-events-none aria-disabled:opacity-50 dark:text-muted-foreground dark:hover:text-foreground group-data-[variant=default]/tabs-list:data-active:shadow-sm group-data-[variant=line]/tabs-list:data-active:shadow-none [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", "group-data-[variant=line]/tabs-list:bg-transparent group-data-[variant=line]/tabs-list:data-active:bg-transparent dark:group-data-[variant=line]/tabs-list:data-active:border-transparent dark:group-data-[variant=line]/tabs-list:data-active:bg-transparent", "data-active:bg-background data-active:text-foreground dark:data-active:border-input dark:data-active:bg-input/30 dark:data-active:text-foreground", "after:absolute after:bg-foreground after:opacity-0 after:transition-opacity group-data-horizontal/tabs:after:inset-x-0 group-data-horizontal/tabs:after:bottom-[-5px] group-data-horizontal/tabs:after:h-0.5 group-data-vertical/tabs:after:inset-y-0 group-data-vertical/tabs:after:-right-1 group-data-vertical/tabs:after:w-0.5 group-data-[variant=line]/tabs-list:data-active:after:opacity-100", className),
44
- ...props
45
- });
46
- }
47
- function TabsContent({ className, ...props }) {
48
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TabsPanel, {
49
- "data-slot": "tabs-content",
50
- className: cn("flex-1 text-sm outline-none", className),
51
- ...props
52
- });
53
- }
54
- function LoopPage() {
55
- const { loop, tasks, poll, readiness } = Route$10.useLoaderData();
56
- useLiveRefresh();
57
- const issues = issuesFor(readiness, loop);
58
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
59
- className: "flex flex-col gap-6",
60
- children: [
61
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Link, {
62
- to: "/loops",
63
- className: "flex items-center gap-1.5 text-sm text-muted-foreground hover:text-foreground",
64
- children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(ArrowLeft, { className: "size-4" }), "Loops"]
65
- }),
66
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("h1", {
67
- className: "text-2xl font-semibold tracking-tight",
68
- children: loop.name
69
- }),
70
- issues.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Alert, { children: [
71
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(CircleAlert, {}),
72
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(AlertTitle, { children: "This loop cannot run yet" }),
73
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(AlertDescription, {
74
- className: "flex flex-col gap-1",
75
- children: issues.map((line) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: line }, line))
76
- })
77
- ] }) : null,
78
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Watching, {
79
- loop,
80
- poll
81
- }),
82
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Tabs$1, {
83
- defaultValue: "settings",
84
- children: [
85
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(TabsList, { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(TabsTrigger, {
86
- value: "settings",
87
- children: "Settings"
88
- }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TabsTrigger, {
89
- value: "tasks",
90
- children: "Tasks"
91
- })] }),
92
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TabsContent, {
93
- value: "settings",
94
- className: "pt-2",
95
- children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(LoopForm, { loop })
96
- }),
97
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(TabsContent, {
98
- value: "tasks",
99
- className: "flex flex-col gap-4 pt-2",
100
- children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(RunBox, { loop }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TaskList, {
101
- tasks,
102
- showLoop: false,
103
- empty: "This loop has not run yet."
104
- })]
105
- })
106
- ]
107
- })
108
- ]
109
- });
110
- }
111
- function when(iso) {
112
- return new Date(iso).toLocaleString();
113
- }
114
- /**
115
- * Whether the loop is really watching is the one thing a page cannot work out
116
- * for itself, and the thing a person most wants to know after turning one on.
117
- */
118
- function Watching({ loop, poll }) {
119
- const router = useRouter();
120
- const [busy, setBusy] = (0, import_react.useState)(false);
121
- if (!loop.enabled) return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Alert, { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(AlertTitle, { children: "This loop is off" }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(AlertDescription, { children: "Nothing is being watched for until you turn it back on." })] });
122
- if (poll.pollError) return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Alert, {
123
- variant: "destructive",
124
- children: [
125
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(CircleAlert, {}),
126
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(AlertTitle, { children: "The last look did not work" }),
127
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(AlertDescription, { children: poll.pollError })
128
- ]
129
- });
130
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Card, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(CardContent, {
131
- className: "flex flex-col gap-4 pt-6",
132
- children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
133
- className: "flex items-start gap-3 text-sm",
134
- children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Eye, { className: "mt-0.5 size-4 shrink-0 text-muted-foreground" }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
135
- className: "text-muted-foreground",
136
- children: poll.polledAt ? `Watching. Last looked ${when(poll.polledAt)}.` : "Not looked yet. The dispatcher checks every couple of minutes; the first look records what is already waiting without running it."
137
- })]
138
- }), poll.backlog.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
139
- className: "flex flex-col gap-3 rounded-lg border p-4",
140
- children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
141
- className: "flex flex-wrap items-start justify-between gap-3",
142
- children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
143
- className: "text-sm font-medium",
144
- children: poll.backlog.length === 1 ? "One thing is waiting" : `${poll.backlog.length} things are waiting`
145
- }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
146
- className: "mt-1 text-xs text-muted-foreground",
147
- children: "Matched, but not run: either it was already there before the loop was made, or it was held back for the reason shown. Run them if you want them dealt with too."
148
- })] }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button$1, {
149
- variant: "outline",
150
- size: "sm",
151
- disabled: busy,
152
- onClick: async () => {
153
- setBusy(true);
154
- try {
155
- const { queued } = await runLoopBacklog({ data: { id: loop.id } });
156
- await router.invalidate();
157
- toast.success(queued === 1 ? "Queued 1 run" : `Queued ${queued} runs`);
158
- } catch (error) {
159
- toast.error(error instanceof Error ? error.message : String(error));
160
- } finally {
161
- setBusy(false);
162
- }
163
- },
164
- children: busy ? "Queueing..." : "Run these too"
165
- })]
166
- }), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("ul", {
167
- className: "flex flex-col gap-1 text-xs text-muted-foreground",
168
- children: [poll.backlog.slice(0, 8).map((item) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("li", {
169
- className: "truncate",
170
- children: [
171
- item.sourceRef,
172
- " · ",
173
- item.sourceTitle,
174
- item.hold ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", {
175
- className: "text-foreground",
176
- children: [" · ", item.hold]
177
- }) : null
178
- ]
179
- }, item.key)), poll.backlog.length > 8 ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("li", { children: [
180
- "and ",
181
- poll.backlog.length - 8,
182
- " more"
183
- ] }) : null]
184
- })]
185
- }) : null]
186
- }) });
187
- }
188
- /**
189
- * A loop that runs by itself still has to be shaped, and waiting for a real
190
- * signal to arrive is a slow way to do it. Dry run means that shaping leaves
191
- * no marks on a real repository.
192
- */
193
- function RunBox({ loop }) {
194
- const router = useRouter();
195
- const [url, setUrl] = (0, import_react.useState)("");
196
- const [dryRun, setDryRun] = (0, import_react.useState)(true);
197
- const [running, setRunning] = (0, import_react.useState)(false);
198
- const manifest = connectorManifest(loop.connectorId);
199
- const byHand = manifest?.byHand ?? { kind: "none" };
200
- const run = async () => {
201
- setRunning(true);
202
- try {
203
- await runLoopNow({ data: {
204
- loopId: loop.id,
205
- url: url.trim(),
206
- dryRun
207
- } });
208
- await router.invalidate();
209
- setUrl("");
210
- toast.success(dryRun ? "Queued as a dry run" : "Queued");
211
- } catch (error) {
212
- toast.error(error instanceof Error ? error.message : String(error));
213
- } finally {
214
- setRunning(false);
215
- }
216
- };
217
- if (byHand.kind === "none") return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Card, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(CardContent, {
218
- className: "pt-6 text-sm text-muted-foreground",
219
- children: "This loop can only run on something arriving, so there is nothing to start by hand. What it does with what arrives is worth trying on the first one, with dry run left on."
220
- }) });
221
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Card, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(CardContent, {
222
- className: "flex flex-col gap-4 pt-6",
223
- children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
224
- className: "flex flex-col gap-2",
225
- children: byHand.kind === "now" ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Label, { children: "Run it now, without waiting for the time" }), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
226
- className: "flex items-center justify-between gap-4",
227
- children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
228
- className: "text-xs text-muted-foreground",
229
- children: "Runs exactly as it would when the clock came round, and does not count as that run: the next scheduled one still happens."
230
- }), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Button$1, {
231
- onClick: run,
232
- disabled: running,
233
- children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Play, {}), "Run"]
234
- })]
235
- })] }) : /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Label, {
236
- htmlFor: "run-url",
237
- children: [
238
- "Try this loop on a ",
239
- manifest?.name ?? "",
240
- " link"
241
- ]
242
- }), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
243
- className: "flex gap-2",
244
- children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Input$1, {
245
- id: "run-url",
246
- value: url,
247
- placeholder: byHand.placeholder,
248
- onChange: (event) => setUrl(event.target.value)
249
- }), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Button$1, {
250
- onClick: run,
251
- disabled: running || url.trim() === "",
252
- children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Play, {}), "Run"]
253
- })]
254
- })] })
255
- }), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
256
- className: "flex items-center justify-between gap-4",
257
- children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Label, {
258
- htmlFor: "run-dry",
259
- children: "Dry run"
260
- }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
261
- className: "mt-1 text-xs text-muted-foreground",
262
- children: dryRun ? "Prepare the result and show it to you, without writing anything." : "Write the result back, exactly as the loop would on its own."
263
- })] }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Switch$1, {
264
- id: "run-dry",
265
- checked: dryRun,
266
- onCheckedChange: setDryRun
267
- })]
268
- })]
269
- }) });
270
- }
271
- //#endregion
272
- export { LoopPage as component };
@@ -1,42 +0,0 @@
1
- import { r as isLoopbackHost } from "./callback-D20cVD2w.mjs";
2
- //#region node_modules/.nitro/vite/services/ssr/assets/access-B7TcOZ7F.js
3
- var APP_ACCESS_COOKIE = "loopable_access";
4
- function bearer(request) {
5
- const header = request.headers.get("authorization") ?? "";
6
- return /^Bearer\s+(.+)$/i.exec(header)?.[1]?.trim() ?? "";
7
- }
8
- function cookieValue(header, name) {
9
- if (!header) return null;
10
- for (const part of header.split(";")) {
11
- const [rawName, ...rest] = part.trim().split("=");
12
- if (rawName === name) return decodeURIComponent(rest.join("="));
13
- }
14
- return null;
15
- }
16
- function readAppToken(request) {
17
- const fromBearer = bearer(request);
18
- if (fromBearer) return fromBearer;
19
- const fromQuery = new URL(request.url).searchParams.get("token")?.trim();
20
- if (fromQuery) return fromQuery;
21
- return cookieValue(request.headers.get("cookie"), APP_ACCESS_COOKIE);
22
- }
23
- function appAccessCookie(token) {
24
- const secure = process.env.LOOPABLE_BASE_URL?.startsWith("https:") ? "; Secure" : "";
25
- return `${APP_ACCESS_COOKIE}=${encodeURIComponent(token)}; Path=/; HttpOnly; SameSite=Lax${secure}`;
26
- }
27
- /**
28
- * Loopback stays open. Anything else needs LOOPABLE_APP_TOKEN, or the UI is
29
- * on the network with no door.
30
- */
31
- function assertAppAccess(request) {
32
- if (isLoopbackHost(new URL(request.url).hostname)) return;
33
- const expected = process.env.LOOPABLE_APP_TOKEN;
34
- if (!expected) throw new Error("Set LOOPABLE_APP_TOKEN before exposing Loopable off loopback.");
35
- if (readAppToken(request) !== expected) throw new Error("This Loopable is not open to you.");
36
- }
37
- /** Runner pull and OAuth callbacks have their own tokens. */
38
- function isPublicApiPath(pathname) {
39
- return pathname.startsWith("/api/runners/") || pathname.startsWith("/api/connectors/");
40
- }
41
- //#endregion
42
- export { readAppToken as a, isPublicApiPath as i, assertAppAccess as n, bearer as r, appAccessCookie as t };
@@ -1,31 +0,0 @@
1
- import { U as require_jsx_runtime } from "../_libs/@base-ui/react+[...].mjs";
2
- import { I as Badge } from "./router-BbrBz36P.mjs";
3
- //#region node_modules/.nitro/vite/services/ssr/assets/connection-status-BZr3Y-IC.js
4
- var import_jsx_runtime = require_jsx_runtime();
5
- var LABELS = {
6
- connected: {
7
- text: "Connected",
8
- variant: "default"
9
- },
10
- needs_reauth: {
11
- text: "Needs reconnecting",
12
- variant: "destructive"
13
- },
14
- error: {
15
- text: "Error",
16
- variant: "destructive"
17
- },
18
- paused: {
19
- text: "Paused",
20
- variant: "secondary"
21
- }
22
- };
23
- function ConnectionStatusBadge({ status }) {
24
- const label = LABELS[status] ?? LABELS.error;
25
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Badge, {
26
- variant: label.variant,
27
- children: label.text
28
- });
29
- }
30
- //#endregion
31
- export { ConnectionStatusBadge as t };
@@ -1,37 +0,0 @@
1
- import { U as require_jsx_runtime } from "../_libs/@base-ui/react+[...].mjs";
2
- import { d as Plug, w as Clock } from "../_libs/lucide-react.mjs";
3
- import { H as cn } from "./router-BbrBz36P.mjs";
4
- //#region node_modules/.nitro/vite/services/ssr/assets/connector-icon-CFrrHjzR.js
5
- var import_jsx_runtime = require_jsx_runtime();
6
- function mark(viewBox, d) {
7
- return function Mark({ className }) {
8
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("svg", {
9
- viewBox,
10
- fill: "currentColor",
11
- "aria-hidden": true,
12
- className,
13
- children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d })
14
- });
15
- };
16
- }
17
- /**
18
- * Manifests name their icon as a string so no connector ships a component into
19
- * the client bundle. Names resolve here, explicitly, to keep the bundle from
20
- * pulling in a whole icon set.
21
- */
22
- var ICONS = {
23
- Github: mark("0 0 16 16", "M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-2.65-.89-2.65-2.5 0-.77.27-1.4.72-1.9-.07-.18-.31-.9.07-1.87 0 0 .59-.19 1.93.72a6.5 6.5 0 0 1 1.76-.24c.6 0 1.2.08 1.76.24 1.34-.91 1.93-.72 1.93-.72.38.97.14 1.69.07 1.87.45.5.72 1.13.72 1.9 0 1.62-.88 2.3-2.66 2.5.28.24.52.71.52 1.44 0 1.03-.01 1.87-.01 2.13 0 .21.15.46.55.38A7.99 7.99 0 0 0 16 8c0-4.42-3.58-8-8-8Z"),
24
- Gmail: mark("0 0 24 24", "M24 5.457v13.909c0 .904-.732 1.636-1.636 1.636h-3.819V11.73L12 16.64l-6.545-4.91v9.273H1.636A1.636 1.636 0 0 1 0 19.366V5.457c0-.904.732-1.636 1.636-1.636h.749L12 10.907l9.615-7.086h.749c.904 0 1.636.732 1.636 1.636Z"),
25
- Wechat: mark("0 0 24 24", "M8.691 2.188C3.891 2.188 0 5.476 0 9.53c0 2.212 1.17 4.203 3.002 5.55a.59.59 0 0 1 .213.665l-.39 1.48c-.019.07-.048.141-.048.213 0 .163.13.295.29.295a.326.326 0 0 0 .167-.054l1.903-1.114a.864.864 0 0 1 .717-.098 10.16 10.16 0 0 0 2.837.403c.276 0 .543-.027.811-.05-.857-2.578.157-4.972 1.932-6.446 1.703-1.415 4.882-2.235 7.621-1.552-.983-3.29-4.269-5.653-8.163-5.653zm-2.877 3.63a1.09 1.09 0 0 1 1.089 1.089 1.09 1.09 0 0 1-1.089 1.09 1.09 1.09 0 0 1-1.089-1.09 1.09 1.09 0 0 1 1.09-1.089zm5.807 0a1.09 1.09 0 0 1 1.089 1.089 1.09 1.09 0 0 1-1.09 1.09 1.09 1.09 0 0 1-1.088-1.09 1.09 1.09 0 0 1 1.089-1.089zm5.463 3.573C13.008 9.39 9.9 12.06 9.9 15.354c0 1.874 1.017 3.582 2.67 4.834a.492.492 0 0 1 .177.554l-.324 1.235c-.016.058-.04.117-.04.177 0 .136.108.246.242.246a.271.271 0 0 0 .14-.045l1.586-.928a.72.72 0 0 1 .597-.082c.786.226 1.633.336 2.517.336 4 0 7.245-2.741 7.245-6.122 0-3.38-3.245-6.121-7.245-6.121zm-2.203 3.026a.908.908 0 0 1 .907.907.908.908 0 0 1-.907.908.908.908 0 0 1-.908-.908.908.908 0 0 1 .908-.907zm4.839 0a.908.908 0 0 1 .907.907.908.908 0 0 1-.907.908.908.908 0 0 1-.908-.908.908.908 0 0 1 .908-.907z"),
26
- Clock,
27
- Plug
28
- };
29
- function ConnectorIcon({ icon, accent, className }) {
30
- const Icon = ICONS[icon] ?? Plug;
31
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
32
- className: cn("flex size-9 shrink-0 items-center justify-center rounded-lg", accent, className),
33
- children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Icon, { className: "size-5" })
34
- });
35
- }
36
- //#endregion
37
- export { ConnectorIcon as t };
@@ -1,106 +0,0 @@
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 } from "../_libs/@tanstack/react-router+[...].mjs";
4
- import { t as CONNECTOR_MANIFESTS, u as needsAccount } from "./connections-ypex3qUd.mjs";
5
- import { M as CircleAlert, z as ArrowRight } from "../_libs/lucide-react.mjs";
6
- import { n as toast } from "../_libs/sonner.mjs";
7
- import { B as CardHeader, I as Badge, L as Button$1, R as Card, d as Route$15, z as CardContent } from "./router-BbrBz36P.mjs";
8
- import { t as ConnectionStatusBadge } from "./connection-status-BZr3Y-IC.mjs";
9
- import { t as ConnectorIcon } from "./connector-icon-CFrrHjzR.mjs";
10
- //#region node_modules/.nitro/vite/services/ssr/assets/connectors-4yzKb0KG.js
11
- var import_react = /* @__PURE__ */ __toESM(require_react());
12
- var import_jsx_runtime = require_jsx_runtime();
13
- function ConnectorsPage() {
14
- const overview = Route$15.useLoaderData();
15
- const { connected, error } = Route$15.useSearch();
16
- const navigate = Route$15.useNavigate();
17
- (0, import_react.useEffect)(() => {
18
- if (!connected && !error) return;
19
- if (connected) toast.success(`Connected as ${connected}`);
20
- if (error) toast.error(error);
21
- navigate({
22
- search: {},
23
- replace: true
24
- });
25
- }, [
26
- connected,
27
- error,
28
- navigate
29
- ]);
30
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
31
- className: "flex flex-col gap-6",
32
- children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("header", { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h1", {
33
- className: "text-2xl font-semibold tracking-tight",
34
- children: "Connectors"
35
- }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
36
- className: "mt-1 text-sm text-muted-foreground",
37
- children: "Connect the services a loop should watch. Credentials stay with Loopable."
38
- })] }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
39
- className: "flex flex-col gap-4",
40
- children: CONNECTOR_MANIFESTS.filter((manifest) => needsAccount(manifest.id)).map((manifest) => {
41
- const state = overview.find((entry) => entry.connectorId === manifest.id);
42
- const connections = state?.connections ?? [];
43
- const readiness = state?.readiness;
44
- const unavailable = readiness && !readiness.ready ? readiness : null;
45
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Card, { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(CardHeader, {
46
- className: "flex flex-row items-start gap-4",
47
- children: [
48
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ConnectorIcon, {
49
- icon: manifest.icon,
50
- accent: manifest.accent
51
- }),
52
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
53
- className: "flex-1",
54
- children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
55
- className: "flex items-center gap-2",
56
- children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h2", {
57
- className: "font-medium",
58
- children: manifest.name
59
- }), connections.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Badge, {
60
- variant: "secondary",
61
- children: [
62
- connections.length,
63
- " account",
64
- connections.length > 1 ? "s" : ""
65
- ]
66
- }) : null]
67
- }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
68
- className: "mt-1 text-sm text-muted-foreground",
69
- children: manifest.tagline
70
- })]
71
- }),
72
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Button$1, {
73
- variant: "outline",
74
- render: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Link, {
75
- to: "/connectors/$connectorId",
76
- params: { connectorId: manifest.id }
77
- }),
78
- children: [connections.length > 0 ? "Manage" : "Set up", /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ArrowRight, {})]
79
- })
80
- ]
81
- }), (connections.length > 0 || unavailable) && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(CardContent, {
82
- className: "flex flex-col gap-2 border-t pt-4",
83
- children: [unavailable ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", {
84
- className: "flex items-start gap-2 text-sm text-muted-foreground",
85
- children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(CircleAlert, { className: "mt-0.5 size-4 shrink-0" }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: unavailable.reason })]
86
- }) : null, connections.map((connection) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
87
- className: "flex items-center gap-3 text-sm",
88
- children: [
89
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
90
- className: "font-medium",
91
- children: connection.accountLabel
92
- }),
93
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ConnectionStatusBadge, { status: connection.status }),
94
- connection.lastError ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
95
- className: "truncate text-muted-foreground",
96
- children: connection.lastError
97
- }) : null
98
- ]
99
- }, connection.id))]
100
- })] }, manifest.id);
101
- })
102
- })]
103
- });
104
- }
105
- //#endregion
106
- export { ConnectorsPage as component };
@@ -1,114 +0,0 @@
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 { f as Play } from "../_libs/lucide-react.mjs";
5
- import { n as toast } from "../_libs/sonner.mjs";
6
- import { B as CardHeader, L as Button$1, R as Card, _ as SelectItem, b as Label, g as SelectContent, h as Select$1, k as runPrompt, l as Route$13, v as SelectTrigger, y as SelectValue, z as CardContent } from "./router-BbrBz36P.mjs";
7
- import { t as Textarea } from "./textarea-CHJTKtsJ.mjs";
8
- import { n as TaskList } from "./task-list-BnQJ94Dk.mjs";
9
- //#region node_modules/.nitro/vite/services/ssr/assets/inbox-C2VBGLa5.js
10
- var import_react = /* @__PURE__ */ __toESM(require_react());
11
- var import_jsx_runtime = require_jsx_runtime();
12
- function InboxPage() {
13
- const { tasks, agents } = Route$13.useLoaderData();
14
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
15
- className: "flex flex-col gap-6",
16
- children: [
17
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("header", { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h1", {
18
- className: "text-2xl font-semibold tracking-tight",
19
- children: "Inbox"
20
- }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
21
- className: "mt-1 text-sm text-muted-foreground",
22
- children: "Every run, in the order it happened, whether it wrote something or decided there was nothing to say."
23
- })] }),
24
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(PromptRunBox, { agents }),
25
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TaskList, {
26
- tasks,
27
- empty: "Nothing has run yet. Try a prompt above, or open a loop and try it against a pull request or issue link."
28
- }),
29
- tasks.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
30
- className: "text-center text-sm text-muted-foreground",
31
- children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Link, {
32
- to: "/loops",
33
- className: "underline",
34
- children: "Go to loops"
35
- })
36
- }) : null
37
- ]
38
- });
39
- }
40
- function PromptRunBox({ agents }) {
41
- const router = useRouter();
42
- const [prompt, setPrompt] = (0, import_react.useState)("");
43
- const [agentId, setAgentId] = (0, import_react.useState)(agents[0]?.agentId ?? "");
44
- const [running, setRunning] = (0, import_react.useState)(false);
45
- (0, import_react.useEffect)(() => {
46
- if (!agents.some((agent) => agent.agentId === agentId)) setAgentId(agents[0]?.agentId ?? "");
47
- }, [agents, agentId]);
48
- const canRun = Boolean(prompt.trim() && agentId && !running);
49
- const run = async () => {
50
- if (!canRun) return;
51
- setRunning(true);
52
- try {
53
- await runPrompt({ data: {
54
- prompt,
55
- agentId
56
- } });
57
- await router.invalidate();
58
- setPrompt("");
59
- toast.success("Queued");
60
- } catch (error) {
61
- toast.error(error instanceof Error ? error.message : String(error));
62
- } finally {
63
- setRunning(false);
64
- }
65
- };
66
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Card, { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(CardHeader, {
67
- className: "text-base font-medium",
68
- children: "Run a prompt"
69
- }), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(CardContent, {
70
- className: "flex flex-col gap-4",
71
- children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
72
- className: "flex flex-col gap-2",
73
- children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Label, {
74
- htmlFor: "inbox-prompt",
75
- children: "Prompt"
76
- }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Textarea, {
77
- id: "inbox-prompt",
78
- value: prompt,
79
- onChange: (event) => setPrompt(event.target.value),
80
- placeholder: "Ask the agent something. The reply stays in Inbox; nothing is written back.",
81
- rows: 4
82
- })]
83
- }), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
84
- className: "flex flex-col gap-3 sm:flex-row sm:items-end",
85
- children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
86
- className: "flex min-w-0 flex-1 flex-col gap-2",
87
- children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Label, {
88
- htmlFor: "inbox-agent",
89
- children: "Agent"
90
- }), agents.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
91
- className: "text-sm text-muted-foreground",
92
- children: "Start a runner with an agent signed in, then you can run a prompt."
93
- }) : /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Select$1, {
94
- value: agentId,
95
- onValueChange: (value) => value && setAgentId(value),
96
- children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(SelectTrigger, {
97
- id: "inbox-agent",
98
- className: "w-full sm:max-w-xs",
99
- children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SelectValue, { children: (value) => agents.find((agent) => agent.agentId === value)?.name ?? value })
100
- }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SelectContent, { children: agents.map((agent) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SelectItem, {
101
- value: agent.agentId,
102
- children: agent.name
103
- }, agent.agentId)) })]
104
- })]
105
- }), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Button$1, {
106
- onClick: run,
107
- disabled: !canRun || agents.length === 0,
108
- children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Play, {}), running ? "Queueing..." : "Run"]
109
- })]
110
- })]
111
- })] });
112
- }
113
- //#endregion
114
- export { InboxPage as component };