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,346 @@
1
+ import { i as __toESM } from "../_runtime.mjs";
2
+ import { K as require_jsx_runtime, q as require_react } from "../_libs/@base-ui/react+[...].mjs";
3
+ import { p as useNavigate } from "../_libs/@tanstack/react-router+[...].mjs";
4
+ import { b as writerName, f as isInboxOnly, l as connectorWorkflow, o as connectorAction, s as connectorManifest, x as writers } from "./connections-Cqvb6Gw2.mjs";
5
+ import { t as AGENT_MANIFESTS } from "./agents-B_qo1gpL.mjs";
6
+ import { F as ChevronRight } from "../_libs/lucide-react.mjs";
7
+ import { n as toast } from "../_libs/sonner.mjs";
8
+ import { C as saveLoop, g as Input$1, v as Button$1 } from "./router-DdwREiOf.mjs";
9
+ import { n as Field, s as Section } from "./page-DZVxKvdn.mjs";
10
+ import { a as SelectValue, i as SelectTrigger, n as SelectContent, r as SelectItem, t as Select$1 } from "./select-BtndHhHb.mjs";
11
+ import { t as Textarea } from "./textarea-D2c_vTIC.mjs";
12
+ import { n as initialFieldValues, t as SettingFieldInputs } from "./setting-fields-LNgywAW7.mjs";
13
+ import { n as AlertDescription, r as AlertTitle, t as Alert } from "./alert-C2WBWfzo.mjs";
14
+ //#region node_modules/.nitro/vite/services/ssr/assets/loop-form-DWwOR05R.js
15
+ var import_react = /* @__PURE__ */ __toESM(require_react());
16
+ var import_jsx_runtime = require_jsx_runtime();
17
+ var DEFAULT_AGENT = "__default";
18
+ /** Zero is stored as null: "as often as the dispatcher does" is not a duration. */
19
+ var POLL_CHOICES = [
20
+ {
21
+ value: "0",
22
+ label: "Every couple of minutes"
23
+ },
24
+ {
25
+ value: String(6e4),
26
+ label: "Every minute"
27
+ },
28
+ {
29
+ value: String(6e5),
30
+ label: "Every 10 minutes"
31
+ },
32
+ {
33
+ value: String(18e5),
34
+ label: "Every 30 minutes"
35
+ },
36
+ {
37
+ value: String(36e5),
38
+ label: "Every hour"
39
+ },
40
+ {
41
+ value: String(144e5),
42
+ label: "Every 4 hours"
43
+ }
44
+ ];
45
+ var RUNS_IN = {
46
+ checkout: "A fresh clone of the repository",
47
+ folder: "The folder this loop names",
48
+ temp: "A scratch folder with only what it was given"
49
+ };
50
+ var ANSWER = {
51
+ review: "A summary, plus comments on lines",
52
+ code: "A change to the code",
53
+ text: "One block of text"
54
+ };
55
+ /**
56
+ * The parts of a workflow a loop cannot change: what it asks the service,
57
+ * where the agent runs, and how the answer is read. Folded away, since they
58
+ * are worth checking once and never editing.
59
+ */
60
+ function WorkflowDetails({ workflow }) {
61
+ const rows = [];
62
+ if (workflow.watches) rows.push(["Looks for", /* @__PURE__ */ (0, import_jsx_runtime.jsx)("code", {
63
+ className: "font-mono text-xs",
64
+ children: workflow.watches
65
+ })]);
66
+ rows.push(["Runs in", RUNS_IN[workflow.runsIn ?? "temp"]]);
67
+ rows.push(["Answer", ANSWER[workflow.answer]]);
68
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("details", {
69
+ suppressHydrationWarning: true,
70
+ className: "group text-sm",
71
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("summary", {
72
+ className: "flex w-fit cursor-pointer list-none items-center gap-1 text-xs text-muted-foreground hover:text-foreground",
73
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(ChevronRight, { className: "size-3.5 transition-transform group-open:rotate-90" }), "Fixed by the trigger"]
74
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("dl", {
75
+ className: "mt-2 grid grid-cols-[6rem_1fr] gap-x-3 gap-y-1.5 rounded-lg bg-muted/50 p-3 text-xs",
76
+ children: rows.map(([label, value]) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
77
+ className: "contents",
78
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("dt", {
79
+ className: "text-muted-foreground",
80
+ children: label
81
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("dd", { children: value })]
82
+ }, label))
83
+ })]
84
+ });
85
+ }
86
+ /**
87
+ * A loop is one of a connector's workflows with its own answers to the
88
+ * questions it asks: what narrows it, which agent runs it and with what
89
+ * words, and where the answer goes.
90
+ *
91
+ * Serves a loop that exists and one that does not. A loop with no id has been
92
+ * chosen and not saved, so leaving this page is the end of it.
93
+ */
94
+ function LoopForm({ loop, trigger }) {
95
+ const navigate = useNavigate();
96
+ const fresh = loop.id === null;
97
+ const connector = connectorManifest(loop.connectorId);
98
+ const workflow = connectorWorkflow(loop.connectorId, loop.workflowId);
99
+ const [name, setName] = (0, import_react.useState)(loop.name);
100
+ const [prompt, setPrompt] = (0, import_react.useState)(loop.prompt);
101
+ const [folder, setFolder] = (0, import_react.useState)(() => {
102
+ const saved = typeof loop.settings.folder === "string" ? loop.settings.folder : "";
103
+ return saved.startsWith("~/") ? saved.slice(2) : saved;
104
+ });
105
+ const [agentId, setAgentId] = (0, import_react.useState)(loop.agentId ?? DEFAULT_AGENT);
106
+ const [settings, setSettings] = (0, import_react.useState)(() => initialFieldValues(workflow?.settings ?? [], loop.settings));
107
+ const [pollEveryMs, setPollEveryMs] = (0, import_react.useState)(String(loop.pollEveryMs ?? 0));
108
+ const [actionConnectorId, setActionConnectorId] = (0, import_react.useState)(loop.actionConnectorId);
109
+ const [actionId, setActionId] = (0, import_react.useState)(loop.actionId);
110
+ const [actionTarget, setActionTarget] = (0, import_react.useState)(() => initialFieldValues(connectorAction(loop.actionConnectorId, loop.actionId)?.target ?? [], loop.actionTarget));
111
+ const [saving, setSaving] = (0, import_react.useState)(false);
112
+ const [written] = (0, import_react.useState)(loop.prompt.trim() !== "");
113
+ const action = connectorAction(actionConnectorId, actionId);
114
+ const sourceName = connector?.name ?? loop.connectorId;
115
+ const chooseDestination = (connectorId, id) => {
116
+ setActionConnectorId(connectorId);
117
+ setActionId(id);
118
+ setActionTarget(initialFieldValues(connectorAction(connectorId, id)?.target ?? [], {}));
119
+ };
120
+ if (!workflow) return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Alert, {
121
+ variant: "destructive",
122
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(AlertTitle, { children: "This workflow is no longer offered" }), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(AlertDescription, { children: [
123
+ sourceName,
124
+ " no longer has ",
125
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("code", { children: loop.workflowId }),
126
+ ", so this loop cannot run or be edited. You can still delete it."
127
+ ] })]
128
+ });
129
+ const save = async () => {
130
+ setSaving(true);
131
+ try {
132
+ const saved = await saveLoop({ data: {
133
+ id: loop.id,
134
+ name,
135
+ connectorId: loop.connectorId,
136
+ workflowId: loop.workflowId,
137
+ prompt,
138
+ guidance: null,
139
+ agentId: agentId === DEFAULT_AGENT ? null : agentId,
140
+ settings: workflow.runsIn === "folder" ? {
141
+ ...settings,
142
+ folder
143
+ } : settings,
144
+ actionConnectorId,
145
+ actionId,
146
+ actionTarget,
147
+ pollEveryMs: Number(pollEveryMs) || null,
148
+ enabled: loop.enabled
149
+ } });
150
+ toast.success(fresh ? `Added ${saved.name}` : `Saved ${saved.name}`);
151
+ await navigate({
152
+ to: "/loops/$loopId",
153
+ params: { loopId: saved.id }
154
+ });
155
+ } catch (error) {
156
+ toast.error(error instanceof Error ? error.message : String(error));
157
+ } finally {
158
+ setSaving(false);
159
+ }
160
+ };
161
+ const crosses = action && actionConnectorId !== loop.connectorId;
162
+ const flattens = action && workflow.answer === "review" && !action.accepts.includes("review");
163
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
164
+ className: "flex flex-col",
165
+ children: [
166
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Section, {
167
+ title: "When",
168
+ description: `When ${workflow.trigger}.`,
169
+ children: [
170
+ trigger,
171
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Field, {
172
+ label: "Name",
173
+ htmlFor: "loop-name",
174
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Input$1, {
175
+ id: "loop-name",
176
+ value: name,
177
+ onChange: (event) => setName(event.target.value)
178
+ })
179
+ }),
180
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SettingFieldInputs, {
181
+ fields: workflow.settings,
182
+ values: settings,
183
+ idPrefix: "setting-",
184
+ onChange: (key, value) => setSettings((prev) => ({
185
+ ...prev,
186
+ [key]: value
187
+ }))
188
+ }),
189
+ loop.connectorId === "schedule" ? null : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Field, {
190
+ label: "Check",
191
+ htmlFor: "loop-every",
192
+ className: "sm:max-w-xs",
193
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Select$1, {
194
+ value: pollEveryMs,
195
+ onValueChange: (value) => value && setPollEveryMs(value),
196
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(SelectTrigger, {
197
+ id: "loop-every",
198
+ className: "w-full",
199
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SelectValue, { children: (value) => POLL_CHOICES.find((choice) => choice.value === value)?.label ?? `Every ${Math.round(Number(value) / 6e4)} minutes` })
200
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SelectContent, { children: POLL_CHOICES.map((choice) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SelectItem, {
201
+ value: choice.value,
202
+ children: choice.label
203
+ }, choice.value)) })]
204
+ })
205
+ }),
206
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(WorkflowDetails, { workflow })
207
+ ]
208
+ }),
209
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Section, {
210
+ title: "Agent",
211
+ children: [
212
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Field, {
213
+ label: "Run with",
214
+ htmlFor: "loop-agent",
215
+ className: "sm:max-w-xs",
216
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Select$1, {
217
+ value: agentId,
218
+ onValueChange: (value) => value && setAgentId(value),
219
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(SelectTrigger, {
220
+ id: "loop-agent",
221
+ className: "w-full",
222
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SelectValue, { children: (value) => value === DEFAULT_AGENT ? "Default agent" : AGENT_MANIFESTS.find((entry) => entry.id === value)?.name ?? value })
223
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(SelectContent, { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(SelectItem, {
224
+ value: DEFAULT_AGENT,
225
+ children: "Default agent"
226
+ }), AGENT_MANIFESTS.map((entry) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SelectItem, {
227
+ value: entry.id,
228
+ children: entry.name
229
+ }, entry.id))] })]
230
+ })
231
+ }),
232
+ workflow.runsIn === "folder" ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Field, {
233
+ label: "Folder",
234
+ htmlFor: "loop-folder",
235
+ hint: "Inside the runner's home folder. The agent works here.",
236
+ className: "sm:max-w-sm",
237
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
238
+ className: "flex items-center rounded-lg border border-input focus-within:border-ring focus-within:ring-3 focus-within:ring-ring/50",
239
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
240
+ className: "pl-2.5 font-mono text-sm text-muted-foreground",
241
+ children: "~/"
242
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Input$1, {
243
+ id: "loop-folder",
244
+ value: folder,
245
+ placeholder: "code/web",
246
+ onChange: (event) => setFolder(event.target.value),
247
+ className: "border-0 pl-1 font-mono shadow-none focus-visible:ring-0"
248
+ })]
249
+ })
250
+ }) : null,
251
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Field, {
252
+ label: "Prompt",
253
+ htmlFor: "loop-prompt",
254
+ hint: written ? `Starts as “${workflow.name}”. Changes stay on this loop.` : void 0,
255
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Textarea, {
256
+ id: "loop-prompt",
257
+ rows: 10,
258
+ className: "font-mono text-xs",
259
+ placeholder: "What should the agent do?",
260
+ value: prompt,
261
+ onChange: (event) => setPrompt(event.target.value)
262
+ })
263
+ })
264
+ ]
265
+ }),
266
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Section, {
267
+ title: "Answer",
268
+ children: [
269
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
270
+ className: "grid gap-4 sm:grid-cols-2",
271
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Field, {
272
+ label: "Send to",
273
+ htmlFor: "loop-writer",
274
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Select$1, {
275
+ value: actionConnectorId,
276
+ onValueChange: (value) => value && chooseDestination(value, connectorManifest(value).actions[0].id),
277
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(SelectTrigger, {
278
+ id: "loop-writer",
279
+ className: "w-full",
280
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SelectValue, { children: (value) => writerName(value) })
281
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SelectContent, { children: writers().map((writer) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SelectItem, {
282
+ value: writer.id,
283
+ children: writerName(writer.id)
284
+ }, writer.id)) })]
285
+ })
286
+ }), isInboxOnly(actionConnectorId, actionId) ? null : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Field, {
287
+ label: "As",
288
+ htmlFor: "loop-action",
289
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Select$1, {
290
+ value: actionId,
291
+ onValueChange: (value) => value && chooseDestination(actionConnectorId, value),
292
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(SelectTrigger, {
293
+ id: "loop-action",
294
+ className: "w-full",
295
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SelectValue, { children: (value) => connectorAction(actionConnectorId, value)?.name ?? value })
296
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SelectContent, { children: (connectorManifest(actionConnectorId)?.actions ?? []).map((entry) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SelectItem, {
297
+ value: entry.id,
298
+ children: entry.name
299
+ }, entry.id)) })]
300
+ })
301
+ })]
302
+ }),
303
+ crosses && !isInboxOnly(actionConnectorId, actionId) ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", {
304
+ className: "-mt-2 text-xs text-muted-foreground",
305
+ children: [
306
+ sourceName,
307
+ " and ",
308
+ writerName(actionConnectorId),
309
+ " both need a connection."
310
+ ]
311
+ }) : flattens ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
312
+ className: "-mt-2 text-xs text-muted-foreground",
313
+ children: "Line comments arrive as text, with file and line written in."
314
+ }) : null,
315
+ action && action.target.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SettingFieldInputs, {
316
+ fields: action.target,
317
+ values: actionTarget,
318
+ idPrefix: "target-",
319
+ onChange: (key, value) => setActionTarget((prev) => ({
320
+ ...prev,
321
+ [key]: value
322
+ }))
323
+ }) : null
324
+ ]
325
+ }),
326
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
327
+ className: "flex items-center gap-2 border-t pt-6 md:pl-52",
328
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button$1, {
329
+ onClick: save,
330
+ disabled: saving,
331
+ children: saving ? "Saving..." : fresh ? "Add loop" : "Save changes"
332
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button$1, {
333
+ variant: "ghost",
334
+ onClick: () => navigate(fresh ? { to: "/loops/new" } : {
335
+ to: "/loops/$loopId",
336
+ params: { loopId: loop.id }
337
+ }),
338
+ disabled: saving,
339
+ children: "Cancel"
340
+ })]
341
+ })
342
+ ]
343
+ });
344
+ }
345
+ //#endregion
346
+ export { LoopForm as t };