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,40 @@
1
+ import { i as __toESM } from "../_runtime.mjs";
2
+ import { q as require_react } from "../_libs/@base-ui/react+[...].mjs";
3
+ import { m as useRouter } from "../_libs/@tanstack/react-router+[...].mjs";
4
+ //#region node_modules/.nitro/vite/services/ssr/assets/use-live-tasks-BzhTkEOL.js
5
+ var import_react = /* @__PURE__ */ __toESM(require_react());
6
+ /**
7
+ * States still in flight. Used by the pages to know when
8
+ * to keep looking, and by the reaper to find runs a dead process abandoned.
9
+ */
10
+ var TASK_ACTIVE_STATES = [
11
+ "queued",
12
+ "preparing",
13
+ "awaiting_agent",
14
+ "applying"
15
+ ];
16
+ function isTaskActive(state) {
17
+ return TASK_ACTIVE_STATES.includes(state);
18
+ }
19
+ /**
20
+ * The work happens in the dispatcher, so the page has to go and look. Polling only
21
+ * while something is actually running keeps an idle inbox quiet.
22
+ */
23
+ function useLiveTasks(states, everyMs = 2e3) {
24
+ useLiveRefresh(everyMs, states.some((task) => isTaskActive(task.state)));
25
+ }
26
+ /** Runner inventory changes without this page doing anything, so it looks again. */
27
+ function useLiveRefresh(everyMs = 1e4, enabled = true) {
28
+ const router = useRouter();
29
+ (0, import_react.useEffect)(() => {
30
+ if (!enabled) return;
31
+ const timer = setInterval(() => void router.invalidate(), everyMs);
32
+ return () => clearInterval(timer);
33
+ }, [
34
+ enabled,
35
+ everyMs,
36
+ router
37
+ ]);
38
+ }
39
+ //#endregion
40
+ export { useLiveRefresh as n, useLiveTasks as r, isTaskActive as t };
@@ -0,0 +1,166 @@
1
+ //#region node_modules/.nitro/vite/services/ssr/assets/_tanstack-start-manifest_v-2HUdn-2E.js
2
+ var tsrStartManifest = () => ({ routes: {
3
+ __root__: {
4
+ filePath: "/Users/bytedance/codex-projects/loopable/src/routes/__root.tsx",
5
+ children: [
6
+ "/",
7
+ "/connectors/$connectorId",
8
+ "/inbox/$taskId",
9
+ "/loops/$loopId",
10
+ "/loops/new",
11
+ "/agents/",
12
+ "/connectors/",
13
+ "/inbox/",
14
+ "/loops/",
15
+ "/machines/",
16
+ "/runners/",
17
+ "/api/runners/claim",
18
+ "/api/runners/heartbeat",
19
+ "/api/runners/hello",
20
+ "/api/connectors/$connectorId/authorize",
21
+ "/api/connectors/$connectorId/callback",
22
+ "/api/runners/jobs/$taskId/complete",
23
+ "/api/runners/jobs/$taskId/log"
24
+ ],
25
+ preloads: [
26
+ "/assets/index-C9SQ_Baq.js",
27
+ "/assets/preload-helper-BoU_7EQC.js",
28
+ "/assets/button-K3ypIhAZ.js",
29
+ "/assets/usePositioner-B7i9Ejzh.js"
30
+ ],
31
+ scripts: [{ attrs: {
32
+ type: "module",
33
+ async: !0,
34
+ src: "/assets/index-C9SQ_Baq.js"
35
+ } }]
36
+ },
37
+ "/connectors/$connectorId": {
38
+ filePath: "/Users/bytedance/codex-projects/loopable/src/routes/connectors/$connectorId.tsx",
39
+ children: void 0,
40
+ preloads: [
41
+ "/assets/_connectorId-CDCuSgpN.js",
42
+ "/assets/page-bvnfRMum.js",
43
+ "/assets/chevron-right-BrctLtFK.js",
44
+ "/assets/connector-icon-CEbdE71G.js",
45
+ "/assets/time-goBWd-5J.js",
46
+ "/assets/plus-Ber25lrU.js",
47
+ "/assets/refresh-cw-BzSY7M8I.js",
48
+ "/assets/rotate-ccw-DLv9EfCX.js",
49
+ "/assets/setting-fields-DUc3npgh.js",
50
+ "/assets/connection-status-DKWelvLO.js",
51
+ "/assets/alert-Bn_wjgTX.js",
52
+ "/assets/card-DiVnaTIE.js"
53
+ ]
54
+ },
55
+ "/inbox/$taskId": {
56
+ filePath: "/Users/bytedance/codex-projects/loopable/src/routes/inbox/$taskId.tsx",
57
+ children: void 0,
58
+ preloads: [
59
+ "/assets/_taskId-BO5MZnlZ.js",
60
+ "/assets/page-bvnfRMum.js",
61
+ "/assets/chevron-right-BrctLtFK.js",
62
+ "/assets/task-list-Ddk8-qt7.js",
63
+ "/assets/time-goBWd-5J.js",
64
+ "/assets/manifests-yJpevyye.js",
65
+ "/assets/use-live-tasks-DZNNuECy.js",
66
+ "/assets/alert-Bn_wjgTX.js",
67
+ "/assets/card-DiVnaTIE.js"
68
+ ]
69
+ },
70
+ "/loops/$loopId": {
71
+ filePath: "/Users/bytedance/codex-projects/loopable/src/routes/loops/$loopId.tsx",
72
+ children: void 0,
73
+ preloads: [
74
+ "/assets/_loopId-DOnIsVTW.js",
75
+ "/assets/page-bvnfRMum.js",
76
+ "/assets/chevron-right-BrctLtFK.js",
77
+ "/assets/task-list-Ddk8-qt7.js",
78
+ "/assets/connector-icon-CEbdE71G.js",
79
+ "/assets/time-goBWd-5J.js",
80
+ "/assets/play-yHLs4DjK.js",
81
+ "/assets/refresh-cw-BzSY7M8I.js",
82
+ "/assets/gaps-PjmcbaWo.js",
83
+ "/assets/switch-DwABVI6d.js",
84
+ "/assets/manifests-yJpevyye.js",
85
+ "/assets/use-live-tasks-DZNNuECy.js",
86
+ "/assets/alert-Bn_wjgTX.js",
87
+ "/assets/loop-form-Dw3cuTzw.js"
88
+ ]
89
+ },
90
+ "/loops/new": {
91
+ filePath: "/Users/bytedance/codex-projects/loopable/src/routes/loops/new.tsx",
92
+ children: void 0,
93
+ preloads: [
94
+ "/assets/new-CwsnNuRW.js",
95
+ "/assets/select-C9grIFwG.js",
96
+ "/assets/page-bvnfRMum.js",
97
+ "/assets/connector-icon-CEbdE71G.js",
98
+ "/assets/loop-form-Dw3cuTzw.js"
99
+ ]
100
+ },
101
+ "/agents/": {
102
+ filePath: "/Users/bytedance/codex-projects/loopable/src/routes/agents/index.tsx",
103
+ children: void 0,
104
+ preloads: [
105
+ "/assets/agents-CBozi7oi.js",
106
+ "/assets/select-C9grIFwG.js",
107
+ "/assets/page-bvnfRMum.js",
108
+ "/assets/connector-icon-CEbdE71G.js",
109
+ "/assets/manifests-yJpevyye.js",
110
+ "/assets/use-live-tasks-DZNNuECy.js"
111
+ ]
112
+ },
113
+ "/connectors/": {
114
+ filePath: "/Users/bytedance/codex-projects/loopable/src/routes/connectors/index.tsx",
115
+ children: void 0,
116
+ preloads: [
117
+ "/assets/connectors-JyX3IzJj.js",
118
+ "/assets/page-bvnfRMum.js",
119
+ "/assets/chevron-right-BrctLtFK.js",
120
+ "/assets/connector-icon-CEbdE71G.js",
121
+ "/assets/connection-status-DKWelvLO.js"
122
+ ]
123
+ },
124
+ "/inbox/": {
125
+ filePath: "/Users/bytedance/codex-projects/loopable/src/routes/inbox/index.tsx",
126
+ children: void 0,
127
+ preloads: [
128
+ "/assets/inbox-CujRR0Cz.js",
129
+ "/assets/select-C9grIFwG.js",
130
+ "/assets/page-bvnfRMum.js",
131
+ "/assets/task-list-Ddk8-qt7.js",
132
+ "/assets/play-yHLs4DjK.js",
133
+ "/assets/useCompositeListItem-P4Nmmn7j.js",
134
+ "/assets/textarea-Ds-gIYUQ.js"
135
+ ]
136
+ },
137
+ "/loops/": {
138
+ filePath: "/Users/bytedance/codex-projects/loopable/src/routes/loops/index.tsx",
139
+ children: void 0,
140
+ preloads: [
141
+ "/assets/loops-DcEfZa2_.js",
142
+ "/assets/page-bvnfRMum.js",
143
+ "/assets/connector-icon-CEbdE71G.js",
144
+ "/assets/plus-Ber25lrU.js",
145
+ "/assets/gaps-PjmcbaWo.js",
146
+ "/assets/switch-DwABVI6d.js",
147
+ "/assets/useCompositeListItem-P4Nmmn7j.js",
148
+ "/assets/manifests-yJpevyye.js",
149
+ "/assets/use-live-tasks-DZNNuECy.js",
150
+ "/assets/alert-Bn_wjgTX.js"
151
+ ]
152
+ },
153
+ "/runners/": {
154
+ filePath: "/Users/bytedance/codex-projects/loopable/src/routes/runners/index.tsx",
155
+ children: void 0,
156
+ preloads: [
157
+ "/assets/runners-DzX-RU3i.js",
158
+ "/assets/page-bvnfRMum.js",
159
+ "/assets/rotate-ccw-DLv9EfCX.js",
160
+ "/assets/manifests-yJpevyye.js",
161
+ "/assets/use-live-tasks-DZNNuECy.js"
162
+ ]
163
+ }
164
+ } });
165
+ //#endregion
166
+ export { tsrStartManifest };
@@ -0,0 +1,263 @@
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 { f as Link, m as useRouter } from "./_libs/@tanstack/react-router+[...].mjs";
4
+ import { d as destinationLabel, s as connectorManifest } from "./_ssr/connections-Cqvb6Gw2.mjs";
5
+ import { n as agentManifest } from "./_ssr/agents-B_qo1gpL.mjs";
6
+ import { D as CircleStop, F as ChevronRight, S as ExternalLink, g as Loader, x as FileCode } from "./_libs/lucide-react.mjs";
7
+ import { n as toast } from "./_libs/sonner.mjs";
8
+ import { D as stopTask, _ as Badge, c as Route$12, v as Button$1 } from "./_ssr/router-DdwREiOf.mjs";
9
+ import { o as PageHeader } from "./_ssr/page-DZVxKvdn.mjs";
10
+ import { n as AlertDescription, r as AlertTitle, t as Alert } from "./_ssr/alert-C2WBWfzo.mjs";
11
+ import { i as CardTitle, n as CardContent, r as CardHeader, t as Card } from "./_ssr/card-r1cV-PCN.mjs";
12
+ import { t as ago } from "./_ssr/time-Cy8TZP0Z.mjs";
13
+ import { r as useLiveTasks, t as isTaskActive } from "./_ssr/use-live-tasks-BzhTkEOL.mjs";
14
+ import { i as taskTitle, r as TaskStateLabel, t as KIND_LABEL } from "./_ssr/task-list-Dnmq_WeE.mjs";
15
+ //#region node_modules/.nitro/vite/services/ssr/assets/_taskId-D3KkNJW1.js
16
+ var import_react = /* @__PURE__ */ __toESM(require_react());
17
+ var import_jsx_runtime = require_jsx_runtime();
18
+ function TaskPage() {
19
+ const { task, log } = Route$12.useLoaderData();
20
+ const writer = connectorManifest(task.actionConnectorId);
21
+ const agent = task.agentId ? agentManifest(task.agentId) : void 0;
22
+ const live = isTaskActive(task.state);
23
+ useLiveTasks([task]);
24
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
25
+ className: "flex flex-col gap-6",
26
+ children: [
27
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(PageHeader, {
28
+ back: {
29
+ to: "/inbox",
30
+ label: "Inbox"
31
+ },
32
+ title: taskTitle(task),
33
+ actions: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
34
+ task.dryRun ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Badge, {
35
+ variant: "outline",
36
+ children: "Dry run"
37
+ }) : null,
38
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TaskStateLabel, { state: task.state }),
39
+ live ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(StopButton, { task }) : null
40
+ ] }),
41
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", {
42
+ className: "mt-1 flex flex-wrap items-center gap-x-1.5 text-sm text-muted-foreground",
43
+ children: [
44
+ task.sourceKind === "prompt" ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: KIND_LABEL.prompt }) : task.sourceUrl ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("a", {
45
+ href: task.sourceUrl,
46
+ target: "_blank",
47
+ rel: "noreferrer",
48
+ className: "hover:text-foreground hover:underline",
49
+ children: task.sourceRef
50
+ }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: task.sourceRef }),
51
+ task.loopId ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: "·" }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Link, {
52
+ to: "/loops/$loopId",
53
+ params: { loopId: task.loopId },
54
+ className: "hover:text-foreground hover:underline",
55
+ children: task.loopName
56
+ })] }) : null,
57
+ agent ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { children: ["· ", agent.name] }) : null,
58
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", {
59
+ suppressHydrationWarning: true,
60
+ children: ["· ", ago(task.createdAt)]
61
+ })
62
+ ]
63
+ })
64
+ }),
65
+ task.error ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Alert, {
66
+ variant: task.state === "failed" ? "destructive" : void 0,
67
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(AlertTitle, { children: task.state === "failed" ? "Failed" : task.state === "cancelled" ? "Stopped" : "Will try again" }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(AlertDescription, {
68
+ className: "whitespace-pre-wrap",
69
+ children: task.error
70
+ })]
71
+ }) : null,
72
+ task.output ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Card, { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(CardHeader, {
73
+ className: "flex flex-row items-center gap-3",
74
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(CardTitle, {
75
+ className: "flex-1",
76
+ children: task.state === "done" ? "Written" : task.state === "skipped" ? "Nothing to write" : "Result"
77
+ }), task.resultUrl ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Button$1, {
78
+ variant: "outline",
79
+ size: "sm",
80
+ nativeButton: false,
81
+ render: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("a", {
82
+ href: task.resultUrl,
83
+ target: "_blank",
84
+ rel: "noreferrer"
85
+ }),
86
+ children: [
87
+ "Open in ",
88
+ writer?.name ?? task.actionConnectorId,
89
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ExternalLink, {})
90
+ ]
91
+ }) : null]
92
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(CardContent, {
93
+ className: "flex flex-col gap-4",
94
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("pre", {
95
+ className: "whitespace-pre-wrap break-words font-sans text-sm leading-relaxed",
96
+ children: task.output
97
+ }), task.comments.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Comments, { comments: task.comments }) : null]
98
+ })] }) : task.state === "skipped" ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
99
+ className: "text-sm text-muted-foreground",
100
+ children: "The agent had nothing to say, so nothing was written."
101
+ }) : null,
102
+ log ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(AgentLog, {
103
+ log,
104
+ live,
105
+ open: live || task.state === "failed"
106
+ }) : null,
107
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Fold, {
108
+ title: "Details",
109
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("dl", {
110
+ className: "grid grid-cols-[6rem_1fr] gap-x-4 gap-y-2 text-sm",
111
+ children: [
112
+ task.sourceKind === "prompt" ? null : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Row, {
113
+ label: "Writes",
114
+ children: destinationLabel(task.actionConnectorId, task.actionId)
115
+ }),
116
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Row, {
117
+ label: "Queued",
118
+ children: new Date(task.createdAt).toLocaleString()
119
+ }),
120
+ task.durationMs ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Row, {
121
+ label: "Took",
122
+ children: [(task.durationMs / 1e3).toFixed(1), "s"]
123
+ }) : null,
124
+ task.attempts > 1 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Row, {
125
+ label: "Attempts",
126
+ children: task.attempts
127
+ }) : null,
128
+ task.prompt ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Row, {
129
+ label: "Prompt",
130
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("pre", {
131
+ className: "max-h-64 overflow-auto rounded-md bg-muted p-2.5 text-xs whitespace-pre-wrap",
132
+ children: task.prompt
133
+ })
134
+ }) : null,
135
+ task.agentCommand ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Row, {
136
+ label: "Command",
137
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("pre", {
138
+ className: "overflow-x-auto rounded-md bg-muted p-2.5 text-xs",
139
+ children: task.agentCommand
140
+ })
141
+ }) : null
142
+ ]
143
+ })
144
+ })
145
+ ]
146
+ });
147
+ }
148
+ /** A titled block that opens and closes, for what is only sometimes worth reading. */
149
+ function Fold({ title, open, aside, children }) {
150
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("details", {
151
+ open,
152
+ suppressHydrationWarning: true,
153
+ className: "group rounded-xl bg-card ring-1 ring-foreground/10",
154
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("summary", {
155
+ className: "flex cursor-pointer list-none items-center gap-2 px-4 py-3 text-sm font-medium",
156
+ children: [
157
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ChevronRight, { className: "size-4 text-muted-foreground transition-transform group-open:rotate-90" }),
158
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
159
+ className: "flex-1",
160
+ children: title
161
+ }),
162
+ aside
163
+ ]
164
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
165
+ className: "px-4 pb-4",
166
+ children
167
+ })]
168
+ });
169
+ }
170
+ /**
171
+ * The findings that go on the lines rather than in the body. Shown separately
172
+ * because that is what they are: on GitHub they will be spread across the
173
+ * diff, and this is the only place they can be read as a list.
174
+ */
175
+ function Comments({ comments }) {
176
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
177
+ className: "flex flex-col gap-3 border-t pt-4",
178
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
179
+ className: "text-xs text-muted-foreground",
180
+ children: comments.length === 1 ? "1 line comment" : `${comments.length} line comments`
181
+ }), comments.map((comment, index) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
182
+ className: "flex flex-col gap-1",
183
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", {
184
+ className: "flex items-center gap-1.5 font-mono text-xs text-muted-foreground",
185
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(FileCode, { className: "size-3.5 shrink-0" }), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", {
186
+ className: "truncate",
187
+ children: [
188
+ comment.path,
189
+ ":",
190
+ comment.startLine ? `${comment.startLine}-${comment.line}` : comment.line
191
+ ]
192
+ })]
193
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("pre", {
194
+ className: "whitespace-pre-wrap break-words border-l-2 pl-3 font-sans text-sm leading-relaxed",
195
+ children: comment.body
196
+ })]
197
+ }, `${comment.path}:${comment.line}:${index}`))]
198
+ });
199
+ }
200
+ /**
201
+ * Everything the agent printed, as it prints it. Four minutes of a spinner
202
+ * tells you nothing; this is what tells you the run is alive, and afterwards
203
+ * it is the only place that explains a failure.
204
+ */
205
+ function AgentLog({ log, live, open }) {
206
+ const box = (0, import_react.useRef)(null);
207
+ (0, import_react.useEffect)(() => {
208
+ if (live && box.current) box.current.scrollTop = box.current.scrollHeight;
209
+ }, [live, log]);
210
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Fold, {
211
+ title: "Agent log",
212
+ open,
213
+ aside: live ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", {
214
+ className: "flex items-center gap-1.5 text-xs font-normal text-muted-foreground",
215
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Loader, { className: "size-3.5 animate-spin" }), "Running"]
216
+ }) : null,
217
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("pre", {
218
+ ref: box,
219
+ className: "max-h-96 overflow-auto rounded-md bg-muted p-2.5 text-xs leading-relaxed whitespace-pre-wrap break-words",
220
+ children: log
221
+ })
222
+ });
223
+ }
224
+ /**
225
+ * The run is in the other process, so this only leaves a note. The dispatcher
226
+ * sees it when it next renews its claim, which is why the button says it has
227
+ * been asked for rather than pretending it is already done.
228
+ */
229
+ function StopButton({ task }) {
230
+ const router = useRouter();
231
+ const [asked, setAsked] = (0, import_react.useState)(task.cancelRequested);
232
+ const stop = async () => {
233
+ setAsked(true);
234
+ try {
235
+ await stopTask({ data: { id: task.id } });
236
+ await router.invalidate();
237
+ } catch (error) {
238
+ setAsked(false);
239
+ toast.error(error instanceof Error ? error.message : String(error));
240
+ }
241
+ };
242
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Button$1, {
243
+ variant: "outline",
244
+ size: "sm",
245
+ onClick: stop,
246
+ disabled: asked,
247
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(CircleStop, {}), asked ? "Stopping" : "Stop"]
248
+ });
249
+ }
250
+ function Row({ label, children }) {
251
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
252
+ className: "contents",
253
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("dt", {
254
+ className: "text-xs leading-5 text-muted-foreground",
255
+ children: label
256
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("dd", {
257
+ className: "min-w-0",
258
+ children
259
+ })]
260
+ });
261
+ }
262
+ //#endregion
263
+ export { TaskPage as component };