loopable-cli 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.output/nitro.json +17 -0
- package/.output/public/apple-touch-icon.png +0 -0
- package/.output/public/assets/_connectorId-BWjYn5tm.js +1 -0
- package/.output/public/assets/_loopId-Ds4RkyEc.js +1 -0
- package/.output/public/assets/_taskId-BOzICXDf.js +1 -0
- package/.output/public/assets/alert-Bn9-Zm0l.js +1 -0
- package/.output/public/assets/arrow-left-BF9juV9T.js +1 -0
- package/.output/public/assets/arrow-right-CzqvnOY1.js +1 -0
- package/.output/public/assets/button-HCY6DCY-.js +1 -0
- package/.output/public/assets/connection-status-CYZB8kLy.js +1 -0
- package/.output/public/assets/connector-icon-BZ_MUJV_.js +1 -0
- package/.output/public/assets/connectors-BvzttfSu.js +1 -0
- package/.output/public/assets/connectors-DdJNwRN_.js +1 -0
- package/.output/public/assets/external-link-D46X-bXa.js +1 -0
- package/.output/public/assets/gaps-D-I6xiDc.js +1 -0
- package/.output/public/assets/geist-cyrillic-ext-wght-normal-DjL33-gN.woff2 +0 -0
- package/.output/public/assets/geist-cyrillic-wght-normal-BEAKL7Jp.woff2 +0 -0
- package/.output/public/assets/geist-latin-ext-wght-normal-DC-KSUi6.woff2 +0 -0
- package/.output/public/assets/geist-latin-wght-normal-BgDaEnEv.woff2 +0 -0
- package/.output/public/assets/geist-vietnamese-wght-normal-6IgcOCM7.woff2 +0 -0
- package/.output/public/assets/inbox-BUUu9xxE.js +1 -0
- package/.output/public/assets/index-ztzex0FN.js +10 -0
- package/.output/public/assets/loader-CcBl2u8m.js +1 -0
- package/.output/public/assets/loop-form-dB3CLcZb.js +1 -0
- package/.output/public/assets/loops-DRunQrxL.js +1 -0
- package/.output/public/assets/loops-oSdqMd29.js +1 -0
- package/.output/public/assets/manifests-DNMqf7Vi.js +7 -0
- package/.output/public/assets/new-uyFxVjuB.js +1 -0
- package/.output/public/assets/preload-helper-ORbuV86A.js +3 -0
- package/.output/public/assets/runners-DSU3r5Ww.js +1 -0
- package/.output/public/assets/setting-fields-ixkpdBb-.js +3 -0
- package/.output/public/assets/styles-DZL5V1o7.css +2 -0
- package/.output/public/assets/switch-d5ummmHY.js +1 -0
- package/.output/public/assets/task-list-BpOStt9v.js +1 -0
- package/.output/public/assets/tasks-B8MsKgic.js +1 -0
- package/.output/public/assets/trash-2-D6u6NpzO.js +1 -0
- package/.output/public/favicon.svg +9 -0
- package/.output/server/_chunks/ssr-renderer.mjs +26 -0
- package/.output/server/_connectorId-8nb5yOzG.mjs +421 -0
- package/.output/server/_libs/@base-ui/react+[...].mjs +12841 -0
- package/.output/server/_libs/@tanstack/react-router+[...].mjs +14349 -0
- package/.output/server/_libs/class-variance-authority+clsx.mjs +69 -0
- package/.output/server/_libs/dijkstrajs.mjs +118 -0
- package/.output/server/_libs/drizzle-orm.mjs +4349 -0
- package/.output/server/_libs/h3+rou3+srvx.mjs +1361 -0
- package/.output/server/_libs/lucide-react.mjs +911 -0
- package/.output/server/_libs/next-themes.mjs +53 -0
- package/.output/server/_libs/pngjs.mjs +1680 -0
- package/.output/server/_libs/qrcode.mjs +2583 -0
- package/.output/server/_libs/sonner.mjs +955 -0
- package/.output/server/_libs/tailwind-merge.mjs +3380 -0
- package/.output/server/_libs/tanstack__history.mjs +341 -0
- package/.output/server/_libs/ufo.mjs +64 -0
- package/.output/server/_loopId-BsUL1SeL.mjs +272 -0
- package/.output/server/_runtime.mjs +35 -0
- package/.output/server/_ssr/access-zIl15o8y.mjs +42 -0
- package/.output/server/_ssr/agents-Btql102J.mjs +657 -0
- package/.output/server/_ssr/agents-DAOZPgO2.mjs +76 -0
- package/.output/server/_ssr/alert-NEiOCTOl.mjs +37 -0
- package/.output/server/_ssr/callback-CUINvl7M.mjs +62 -0
- package/.output/server/_ssr/client-CKkOfh-s.mjs +335 -0
- package/.output/server/_ssr/connection-status-Bi5peUAk.mjs +31 -0
- package/.output/server/_ssr/connections-qnw2GVlP.mjs +2542 -0
- package/.output/server/_ssr/connector-icon-DZXQLLFo.mjs +37 -0
- package/.output/server/_ssr/connectors-BHNwuIMj.mjs +106 -0
- package/.output/server/_ssr/connectors-C28g0i4c.mjs +83 -0
- package/.output/server/_ssr/createServerRpc-DPDrnFdH.mjs +12 -0
- package/.output/server/_ssr/empty-plugin-adapters-BJ4m9L8g.mjs +5 -0
- package/.output/server/_ssr/gaps-RAFSXLZf.mjs +53 -0
- package/.output/server/_ssr/inbox-k5zHergU.mjs +35 -0
- package/.output/server/_ssr/loop-form-DlObSewZ.mjs +412 -0
- package/.output/server/_ssr/loops-APFcP0y6.mjs +311 -0
- package/.output/server/_ssr/loops-xt2Bn7_q.mjs +222 -0
- package/.output/server/_ssr/new-DfKyd2Wa.mjs +169 -0
- package/.output/server/_ssr/router-3WmpE5b_.mjs +1553 -0
- package/.output/server/_ssr/runners-By-mwc3F.mjs +32 -0
- package/.output/server/_ssr/runners-DI_NxpHC.mjs +116 -0
- package/.output/server/_ssr/runners-DtXs4Q8a.mjs +106 -0
- package/.output/server/_ssr/secrets-Hqti-niS.mjs +199 -0
- package/.output/server/_ssr/setting-fields-8vKFj4df.mjs +92 -0
- package/.output/server/_ssr/ssr.mjs +6605 -0
- package/.output/server/_ssr/start-Bdc2GJUI.mjs +51 -0
- package/.output/server/_ssr/switch-ReNglgH6.mjs +18 -0
- package/.output/server/_ssr/task-list-CUITIqkb.mjs +186 -0
- package/.output/server/_ssr/tasks-SAjNovX6.mjs +110 -0
- package/.output/server/_ssr/tasks-vcoodp_D.mjs +533 -0
- package/.output/server/_tanstack-start-manifest_v-C0cP5F0M.mjs +125 -0
- package/.output/server/_taskId-CXS3lod0.mjs +249 -0
- package/.output/server/index.mjs +541 -0
- package/README.md +81 -0
- package/dist/cli.mjs +165 -0
- package/dist/dispatcher.mjs +9871 -0
- package/dist/runner.mjs +657 -0
- package/drizzle/0000_cold_demogoblin.sql +29 -0
- package/drizzle/0001_fancy_blonde_phantom.sql +13 -0
- package/drizzle/0002_spooky_smiling_tiger.sql +16 -0
- package/drizzle/0003_small_golden_guardian.sql +25 -0
- package/drizzle/0004_wonderful_thunderbolts.sql +39 -0
- package/drizzle/0005_named_workflows.sql +7 -0
- package/drizzle/0006_signals.sql +18 -0
- package/drizzle/0007_review_comments.sql +1 -0
- package/drizzle/0008_held_signals.sql +1 -0
- package/drizzle/0009_work_item_ref.sql +58 -0
- package/drizzle/0010_signal_payload.sql +2 -0
- package/drizzle/0011_rule_poll_cursor.sql +1 -0
- package/drizzle/0012_loops.sql +63 -0
- package/drizzle/0013_loop_owns_action_and_prompt.sql +154 -0
- package/drizzle/0014_loop_poll_every.sql +4 -0
- package/drizzle/0015_machines.sql +10 -0
- package/drizzle/0016_task_machine.sql +1 -0
- package/drizzle/0017_loop_machine.sql +1 -0
- package/drizzle/0018_runners.sql +1 -0
- package/drizzle/0019_task_runner.sql +1 -0
- package/drizzle/0020_loop_runner.sql +1 -0
- package/drizzle/0021_drop_runner_kind.sql +1 -0
- package/drizzle/0022_drop_loop_runner.sql +1 -0
- package/drizzle/0023_shared_host.sql +6 -0
- package/drizzle/meta/0000_snapshot.json +206 -0
- package/drizzle/meta/0001_snapshot.json +284 -0
- package/drizzle/meta/0002_snapshot.json +390 -0
- package/drizzle/meta/0003_snapshot.json +566 -0
- package/drizzle/meta/0004_snapshot.json +633 -0
- package/drizzle/meta/0005_snapshot.json +626 -0
- package/drizzle/meta/0006_snapshot.json +752 -0
- package/drizzle/meta/0007_snapshot.json +759 -0
- package/drizzle/meta/0008_snapshot.json +766 -0
- package/drizzle/meta/0009_snapshot.json +752 -0
- package/drizzle/meta/0010_snapshot.json +766 -0
- package/drizzle/meta/0011_snapshot.json +773 -0
- package/drizzle/meta/0012_snapshot.json +773 -0
- package/drizzle/meta/0013_snapshot.json +817 -0
- package/drizzle/meta/_journal.json +174 -0
- package/package.json +88 -0
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { t as createMiddleware } from "./ssr.mjs";
|
|
2
|
+
import { l as migrateIfNeeded } from "./client-CKkOfh-s.mjs";
|
|
3
|
+
import { r as isLoopbackHost } from "./callback-CUINvl7M.mjs";
|
|
4
|
+
import { a as readAppToken, i as isPublicApiPath, n as assertAppAccess, t as appAccessCookie } from "./access-zIl15o8y.mjs";
|
|
5
|
+
//#region node_modules/.nitro/vite/services/ssr/assets/start-Bdc2GJUI.js
|
|
6
|
+
function dedupeSerializationAdapters(deduped, serializationAdapters) {
|
|
7
|
+
for (let i = 0, len = serializationAdapters.length; i < len; i++) {
|
|
8
|
+
const current = serializationAdapters[i];
|
|
9
|
+
if (!deduped.has(current)) {
|
|
10
|
+
deduped.add(current);
|
|
11
|
+
if (current.extends) dedupeSerializationAdapters(deduped, current.extends);
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
var createStart = (getOptions) => {
|
|
16
|
+
return {
|
|
17
|
+
getOptions: async () => {
|
|
18
|
+
const options = await getOptions();
|
|
19
|
+
if (options.serializationAdapters) {
|
|
20
|
+
const deduped = /* @__PURE__ */ new Set();
|
|
21
|
+
dedupeSerializationAdapters(deduped, options.serializationAdapters);
|
|
22
|
+
options.serializationAdapters = Array.from(deduped);
|
|
23
|
+
}
|
|
24
|
+
return options;
|
|
25
|
+
},
|
|
26
|
+
createMiddleware
|
|
27
|
+
};
|
|
28
|
+
};
|
|
29
|
+
var migrated = null;
|
|
30
|
+
function ensureMigrated() {
|
|
31
|
+
migrated ??= migrateIfNeeded();
|
|
32
|
+
return migrated;
|
|
33
|
+
}
|
|
34
|
+
var appAccess = createMiddleware({ type: "request" }).server(async ({ next, request, pathname }) => {
|
|
35
|
+
await ensureMigrated();
|
|
36
|
+
if (isPublicApiPath(pathname)) return next();
|
|
37
|
+
try {
|
|
38
|
+
assertAppAccess(request);
|
|
39
|
+
} catch (error) {
|
|
40
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
41
|
+
return new Response(message, { status: 401 });
|
|
42
|
+
}
|
|
43
|
+
const result = await next();
|
|
44
|
+
const token = readAppToken(request);
|
|
45
|
+
const expected = process.env.LOOPABLE_APP_TOKEN;
|
|
46
|
+
if (token && expected && token === expected && !isLoopbackHost(new URL(request.url).hostname)) result.response.headers.append("Set-Cookie", appAccessCookie(token));
|
|
47
|
+
return result;
|
|
48
|
+
});
|
|
49
|
+
var startInstance = createStart(() => ({ requestMiddleware: [appAccess] }));
|
|
50
|
+
//#endregion
|
|
51
|
+
export { startInstance };
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { U as require_jsx_runtime, c as SwitchThumb, l as SwitchRoot } from "../_libs/@base-ui/react+[...].mjs";
|
|
2
|
+
import { V as cn } from "./router-3WmpE5b_.mjs";
|
|
3
|
+
//#region node_modules/.nitro/vite/services/ssr/assets/switch-ReNglgH6.js
|
|
4
|
+
var import_jsx_runtime = require_jsx_runtime();
|
|
5
|
+
function Switch$1({ className, size = "default", ...props }) {
|
|
6
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SwitchRoot, {
|
|
7
|
+
"data-slot": "switch",
|
|
8
|
+
"data-size": size,
|
|
9
|
+
className: cn("peer group/switch relative inline-flex shrink-0 items-center rounded-full border border-transparent transition-all outline-none group-has-[:focus-visible]/field-label:border-transparent group-has-[:focus-visible]/field-label:ring-0 after:absolute after:-inset-x-3 after:-inset-y-2 focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 data-[size=default]:h-[18.4px] data-[size=default]:w-[32px] data-[size=sm]:h-[14px] data-[size=sm]:w-[24px] dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 data-checked:bg-primary data-unchecked:bg-input dark:data-unchecked:bg-input/80 data-disabled:cursor-not-allowed data-disabled:opacity-50", className),
|
|
10
|
+
...props,
|
|
11
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SwitchThumb, {
|
|
12
|
+
"data-slot": "switch-thumb",
|
|
13
|
+
className: "pointer-events-none block rounded-full bg-background ring-0 transition-transform group-data-[size=default]/switch:size-4 group-data-[size=sm]/switch:size-3 group-data-[size=default]/switch:data-checked:translate-x-[calc(100%-2px)] group-data-[size=sm]/switch:data-checked:translate-x-[calc(100%-2px)] dark:data-checked:bg-primary-foreground group-data-[size=default]/switch:data-unchecked:translate-x-0 group-data-[size=sm]/switch:data-unchecked:translate-x-0 dark:data-unchecked:bg-foreground"
|
|
14
|
+
})
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
//#endregion
|
|
18
|
+
export { Switch$1 as t };
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
import { U as require_jsx_runtime } from "../_libs/@base-ui/react+[...].mjs";
|
|
2
|
+
import { f as Link } from "../_libs/@tanstack/react-router+[...].mjs";
|
|
3
|
+
import { a as connectorManifest } from "./connections-qnw2GVlP.mjs";
|
|
4
|
+
import { n as agentManifest } from "./agents-Btql102J.mjs";
|
|
5
|
+
import { A as CircleMinus, D as CircleSlash, I as Bot, T as CircleX, b as FileText, d as Plug, g as Loader, j as CircleCheck, n as Workflow, w as Clock } from "../_libs/lucide-react.mjs";
|
|
6
|
+
import { I as Badge, L as Card, R as CardContent, V as cn, p as useLiveTasks } from "./router-3WmpE5b_.mjs";
|
|
7
|
+
import { t as ConnectorIcon } from "./connector-icon-DZXQLLFo.mjs";
|
|
8
|
+
//#region node_modules/.nitro/vite/services/ssr/assets/task-list-CUITIqkb.js
|
|
9
|
+
var import_jsx_runtime = require_jsx_runtime();
|
|
10
|
+
var STATES = {
|
|
11
|
+
queued: {
|
|
12
|
+
label: "Queued",
|
|
13
|
+
icon: Clock,
|
|
14
|
+
tone: "text-muted-foreground"
|
|
15
|
+
},
|
|
16
|
+
preparing: {
|
|
17
|
+
label: "Working",
|
|
18
|
+
icon: Loader,
|
|
19
|
+
tone: "text-muted-foreground"
|
|
20
|
+
},
|
|
21
|
+
awaiting_agent: {
|
|
22
|
+
label: "On a runner",
|
|
23
|
+
icon: Bot,
|
|
24
|
+
tone: "text-muted-foreground"
|
|
25
|
+
},
|
|
26
|
+
applying: {
|
|
27
|
+
label: "Writing",
|
|
28
|
+
icon: Loader,
|
|
29
|
+
tone: "text-muted-foreground"
|
|
30
|
+
},
|
|
31
|
+
prepared: {
|
|
32
|
+
label: "Prepared",
|
|
33
|
+
icon: FileText,
|
|
34
|
+
tone: "text-muted-foreground"
|
|
35
|
+
},
|
|
36
|
+
done: {
|
|
37
|
+
label: "Written",
|
|
38
|
+
icon: CircleCheck,
|
|
39
|
+
tone: "text-emerald-600"
|
|
40
|
+
},
|
|
41
|
+
skipped: {
|
|
42
|
+
label: "Nothing to say",
|
|
43
|
+
icon: CircleMinus,
|
|
44
|
+
tone: "text-muted-foreground"
|
|
45
|
+
},
|
|
46
|
+
failed: {
|
|
47
|
+
label: "Failed",
|
|
48
|
+
icon: CircleX,
|
|
49
|
+
tone: "text-destructive"
|
|
50
|
+
},
|
|
51
|
+
cancelled: {
|
|
52
|
+
label: "Stopped",
|
|
53
|
+
icon: CircleSlash,
|
|
54
|
+
tone: "text-muted-foreground"
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
function TaskStateLabel({ state }) {
|
|
58
|
+
const meta = STATES[state];
|
|
59
|
+
const Icon = meta.icon;
|
|
60
|
+
const spinning = state === "preparing" || state === "awaiting_agent" || state === "applying";
|
|
61
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", {
|
|
62
|
+
className: cn("flex items-center gap-1.5 text-xs", meta.tone),
|
|
63
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Icon, { className: cn("size-3.5", spinning && "animate-spin") }), meta.label]
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
/** A queued task has no title yet: the connector has not fetched it. */
|
|
67
|
+
function taskTitle(task) {
|
|
68
|
+
return task.sourceTitle ?? task.sourceRef;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Kinds whose reference a person can read. A repository and a number say
|
|
72
|
+
* where the work is; a mail or a message id is a handle for fetching it
|
|
73
|
+
* again and means nothing on a page.
|
|
74
|
+
*/
|
|
75
|
+
var NAMED_REF = /* @__PURE__ */ new Set(["pull_request", "issue"]);
|
|
76
|
+
/** What to call the thing a task is about, where a sentence needs a noun. */
|
|
77
|
+
var KIND_LABEL = {
|
|
78
|
+
pull_request: "Pull request",
|
|
79
|
+
issue: "Issue",
|
|
80
|
+
message: "Message",
|
|
81
|
+
email: "Email",
|
|
82
|
+
occurrence: "Scheduled run"
|
|
83
|
+
};
|
|
84
|
+
function when(iso) {
|
|
85
|
+
const seconds = Math.round((Date.now() - new Date(iso).getTime()) / 1e3);
|
|
86
|
+
if (seconds < 60) return "just now";
|
|
87
|
+
const minutes = Math.round(seconds / 60);
|
|
88
|
+
if (minutes < 60) return `${minutes}m ago`;
|
|
89
|
+
const hours = Math.round(minutes / 60);
|
|
90
|
+
if (hours < 24) return `${hours}h ago`;
|
|
91
|
+
return new Date(iso).toLocaleDateString();
|
|
92
|
+
}
|
|
93
|
+
function TaskList({ tasks, showLoop = true, empty }) {
|
|
94
|
+
useLiveTasks(tasks);
|
|
95
|
+
if (tasks.length === 0) return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Card, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(CardContent, {
|
|
96
|
+
className: "py-8 text-center text-sm text-muted-foreground",
|
|
97
|
+
children: empty
|
|
98
|
+
}) });
|
|
99
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
100
|
+
className: "flex flex-col gap-2",
|
|
101
|
+
children: tasks.map((task) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Link, {
|
|
102
|
+
to: "/inbox/$taskId",
|
|
103
|
+
params: { taskId: task.id },
|
|
104
|
+
className: "rounded-lg border bg-card p-4 transition-colors hover:bg-accent/40",
|
|
105
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
106
|
+
className: "flex items-start gap-3",
|
|
107
|
+
children: [
|
|
108
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(ConnectorIcon, {
|
|
109
|
+
icon: connectorManifest(task.connectorId)?.icon ?? "Plug",
|
|
110
|
+
accent: connectorManifest(task.connectorId)?.accent ?? "bg-muted",
|
|
111
|
+
className: "mt-0.5 size-7 shrink-0"
|
|
112
|
+
}),
|
|
113
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
114
|
+
className: "min-w-0 flex-1",
|
|
115
|
+
children: [
|
|
116
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
|
|
117
|
+
className: "truncate text-sm font-medium",
|
|
118
|
+
children: taskTitle(task)
|
|
119
|
+
}),
|
|
120
|
+
NAMED_REF.has(task.sourceKind) && task.sourceTitle ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
|
|
121
|
+
className: "mt-0.5 truncate text-xs text-muted-foreground",
|
|
122
|
+
children: task.sourceRef
|
|
123
|
+
}) : null,
|
|
124
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(TaskMeta, {
|
|
125
|
+
task,
|
|
126
|
+
showLoop
|
|
127
|
+
}),
|
|
128
|
+
task.output ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
|
|
129
|
+
className: "mt-2 line-clamp-2 text-xs text-muted-foreground",
|
|
130
|
+
children: task.output
|
|
131
|
+
}) : task.error ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
|
|
132
|
+
className: "mt-2 line-clamp-2 text-xs text-destructive",
|
|
133
|
+
children: task.error
|
|
134
|
+
}) : null
|
|
135
|
+
]
|
|
136
|
+
}),
|
|
137
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
138
|
+
className: "flex shrink-0 items-center gap-2",
|
|
139
|
+
children: [task.dryRun ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Badge, {
|
|
140
|
+
variant: "outline",
|
|
141
|
+
children: "Dry run"
|
|
142
|
+
}) : null, /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TaskStateLabel, { state: task.state })]
|
|
143
|
+
})
|
|
144
|
+
]
|
|
145
|
+
})
|
|
146
|
+
}, task.id))
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* What ran, and what it ran through. Which agent wrote the words matters when
|
|
151
|
+
* two loops disagree, and it is only known once the dispatcher has picked the task
|
|
152
|
+
* up, so it is absent rather than wrong while a task is queued.
|
|
153
|
+
*/
|
|
154
|
+
function TaskMeta({ task, showLoop }) {
|
|
155
|
+
const connector = connectorManifest(task.connectorId);
|
|
156
|
+
const agent = task.agentId ? agentManifest(task.agentId) : void 0;
|
|
157
|
+
const parts = [];
|
|
158
|
+
if (showLoop) parts.push({
|
|
159
|
+
icon: Workflow,
|
|
160
|
+
label: task.loopName
|
|
161
|
+
});
|
|
162
|
+
if (connector) parts.push({
|
|
163
|
+
icon: Plug,
|
|
164
|
+
label: connector.name
|
|
165
|
+
});
|
|
166
|
+
if (agent) parts.push({
|
|
167
|
+
icon: Bot,
|
|
168
|
+
label: agent.name
|
|
169
|
+
});
|
|
170
|
+
parts.push({
|
|
171
|
+
icon: Clock,
|
|
172
|
+
label: when(task.createdAt)
|
|
173
|
+
});
|
|
174
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
175
|
+
className: "mt-1.5 flex flex-wrap items-center gap-x-3 gap-y-1 text-xs text-muted-foreground",
|
|
176
|
+
children: parts.map((part) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", {
|
|
177
|
+
className: "flex min-w-0 items-center gap-1",
|
|
178
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(part.icon, { className: "size-3 shrink-0" }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
179
|
+
className: "truncate",
|
|
180
|
+
children: part.label
|
|
181
|
+
})]
|
|
182
|
+
}, part.label))
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
//#endregion
|
|
186
|
+
export { taskTitle as i, TaskList as n, TaskStateLabel as r, KIND_LABEL as t };
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { n as createServerFn } from "./ssr.mjs";
|
|
2
|
+
import { f as eq } from "../_libs/drizzle-orm.mjs";
|
|
3
|
+
import { r as appSettings, s as db } from "./client-CKkOfh-s.mjs";
|
|
4
|
+
import { l as onlineRunnerCount } from "./runners-DtXs4Q8a.mjs";
|
|
5
|
+
import { c as readTaskLog, i as getTask, l as requestCancel, r as enqueueTask, s as listTasks } from "./tasks-vcoodp_D.mjs";
|
|
6
|
+
import { t as createServerRpc } from "./createServerRpc-DPDrnFdH.mjs";
|
|
7
|
+
import { randomUUID } from "node:crypto";
|
|
8
|
+
//#region node_modules/.nitro/vite/services/ssr/assets/tasks-SAjNovX6.js
|
|
9
|
+
async function readSetting(key, fallback) {
|
|
10
|
+
const row = await db().select().from(appSettings).where(eq(appSettings.key, key)).get();
|
|
11
|
+
return row === void 0 ? fallback : row.value;
|
|
12
|
+
}
|
|
13
|
+
/** New key first, then the old engine.* name so a laptop install keeps its pause. */
|
|
14
|
+
async function readSettingRenamed(key, previous, fallback) {
|
|
15
|
+
const row = await db().select().from(appSettings).where(eq(appSettings.key, key)).get();
|
|
16
|
+
if (row !== void 0) return row.value;
|
|
17
|
+
return readSetting(previous, fallback);
|
|
18
|
+
}
|
|
19
|
+
async function writeSetting(key, value) {
|
|
20
|
+
await db().insert(appSettings).values({
|
|
21
|
+
key,
|
|
22
|
+
value
|
|
23
|
+
}).onConflictDoUpdate({
|
|
24
|
+
target: appSettings.key,
|
|
25
|
+
set: {
|
|
26
|
+
value,
|
|
27
|
+
updatedAt: /* @__PURE__ */ new Date()
|
|
28
|
+
}
|
|
29
|
+
}).run();
|
|
30
|
+
}
|
|
31
|
+
var DISPATCHER_DEFAULTS = {
|
|
32
|
+
paused: false,
|
|
33
|
+
maxConcurrentRuns: 1
|
|
34
|
+
};
|
|
35
|
+
var PAUSED_KEY = "dispatcher.paused";
|
|
36
|
+
var CONCURRENCY_KEY = "dispatcher.maxConcurrentRuns";
|
|
37
|
+
async function dispatcherSettings() {
|
|
38
|
+
const concurrency = await readSettingRenamed(CONCURRENCY_KEY, "engine.maxConcurrentRuns", DISPATCHER_DEFAULTS.maxConcurrentRuns);
|
|
39
|
+
return {
|
|
40
|
+
paused: await readSettingRenamed(PAUSED_KEY, "engine.paused", DISPATCHER_DEFAULTS.paused) === true,
|
|
41
|
+
maxConcurrentRuns: Number.isFinite(concurrency) && concurrency > 0 ? Math.floor(concurrency) : 1
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
async function setDispatcherPaused(paused) {
|
|
45
|
+
await writeSetting(PAUSED_KEY, paused);
|
|
46
|
+
return dispatcherSettings();
|
|
47
|
+
}
|
|
48
|
+
var UNTIL_KEY = "dispatcher.leaseUntil";
|
|
49
|
+
function ownerId() {
|
|
50
|
+
return process.env.LOOPABLE_DISPATCHER_ID ?? process.env.LOOPABLE_ENGINE_ID ?? randomUUID();
|
|
51
|
+
}
|
|
52
|
+
ownerId();
|
|
53
|
+
/** True when a dispatcher has renewed its lease recently. */
|
|
54
|
+
async function dispatcherIsAlive() {
|
|
55
|
+
return Number(await readSettingRenamed(UNTIL_KEY, "engine.leaseUntil", 0)) > Date.now();
|
|
56
|
+
}
|
|
57
|
+
var getInbox_createServerFn_handler = createServerRpc({
|
|
58
|
+
id: "48bc32df9d6f69f45df8dfbc6e798e1f99152dbd4b4ed65b149fa2612c65e687",
|
|
59
|
+
name: "getInbox",
|
|
60
|
+
filename: "src/server/functions/tasks.ts"
|
|
61
|
+
}, (opts) => getInbox.__executeServer(opts));
|
|
62
|
+
var getInbox = createServerFn({ method: "GET" }).handler(getInbox_createServerFn_handler, async () => await listTasks());
|
|
63
|
+
var getLoopTasks_createServerFn_handler = createServerRpc({
|
|
64
|
+
id: "3f938fac3e5ec1631e700a2fdd4790e78abbefeb732ecfbbe6864cc19f0d5aac",
|
|
65
|
+
name: "getLoopTasks",
|
|
66
|
+
filename: "src/server/functions/tasks.ts"
|
|
67
|
+
}, (opts) => getLoopTasks.__executeServer(opts));
|
|
68
|
+
var getLoopTasks = createServerFn({ method: "GET" }).inputValidator((data) => data).handler(getLoopTasks_createServerFn_handler, async ({ data }) => await listTasks({ loopId: data.loopId }));
|
|
69
|
+
var getTaskById_createServerFn_handler = createServerRpc({
|
|
70
|
+
id: "0033ef7c619c027b1428a722dff188d315ed335645afcb1033528630b7c95e88",
|
|
71
|
+
name: "getTaskById",
|
|
72
|
+
filename: "src/server/functions/tasks.ts"
|
|
73
|
+
}, (opts) => getTaskById.__executeServer(opts));
|
|
74
|
+
var getTaskById = createServerFn({ method: "GET" }).inputValidator((data) => data).handler(getTaskById_createServerFn_handler, async ({ data }) => await getTask(data.id));
|
|
75
|
+
var getTaskLog_createServerFn_handler = createServerRpc({
|
|
76
|
+
id: "81f567724371f0d6f24e636906e2e9ea5b7384422ac583c86a1050fb838664ce",
|
|
77
|
+
name: "getTaskLog",
|
|
78
|
+
filename: "src/server/functions/tasks.ts"
|
|
79
|
+
}, (opts) => getTaskLog.__executeServer(opts));
|
|
80
|
+
var getTaskLog = createServerFn({ method: "GET" }).inputValidator((data) => data).handler(getTaskLog_createServerFn_handler, async ({ data }) => await readTaskLog(data.id));
|
|
81
|
+
var runLoopNow_createServerFn_handler = createServerRpc({
|
|
82
|
+
id: "7258ce5fc6f23acf3aab039ecd4acdb006d42b2ddbf3ab8629b4000e101b51dc",
|
|
83
|
+
name: "runLoopNow",
|
|
84
|
+
filename: "src/server/functions/tasks.ts"
|
|
85
|
+
}, (opts) => runLoopNow.__executeServer(opts));
|
|
86
|
+
var runLoopNow = createServerFn({ method: "POST" }).inputValidator((data) => data).handler(runLoopNow_createServerFn_handler, async ({ data }) => await enqueueTask(data));
|
|
87
|
+
var stopTask_createServerFn_handler = createServerRpc({
|
|
88
|
+
id: "a57f49c322cc5afa2996e4a5777fa533fd963755d614d4a14eb32e51fb198d9d",
|
|
89
|
+
name: "stopTask",
|
|
90
|
+
filename: "src/server/functions/tasks.ts"
|
|
91
|
+
}, (opts) => stopTask.__executeServer(opts));
|
|
92
|
+
var stopTask = createServerFn({ method: "POST" }).inputValidator((data) => data).handler(stopTask_createServerFn_handler, async ({ data }) => await requestCancel(data.id));
|
|
93
|
+
var getDispatcherState_createServerFn_handler = createServerRpc({
|
|
94
|
+
id: "921b049ebafe3c6fb5206fbe3e2100608d3333b944e18385e57da62a28233bc6",
|
|
95
|
+
name: "getDispatcherState",
|
|
96
|
+
filename: "src/server/functions/tasks.ts"
|
|
97
|
+
}, (opts) => getDispatcherState.__executeServer(opts));
|
|
98
|
+
var getDispatcherState = createServerFn({ method: "GET" }).handler(getDispatcherState_createServerFn_handler, async () => ({
|
|
99
|
+
alive: await dispatcherIsAlive(),
|
|
100
|
+
onlineRunners: await onlineRunnerCount(),
|
|
101
|
+
...await dispatcherSettings()
|
|
102
|
+
}));
|
|
103
|
+
var pauseDispatcher_createServerFn_handler = createServerRpc({
|
|
104
|
+
id: "0fa144f67263a4a51c51e8baf134a15b89c0afdf9b92b64660520a5bce247eec",
|
|
105
|
+
name: "pauseDispatcher",
|
|
106
|
+
filename: "src/server/functions/tasks.ts"
|
|
107
|
+
}, (opts) => pauseDispatcher.__executeServer(opts));
|
|
108
|
+
var pauseDispatcher = createServerFn({ method: "POST" }).inputValidator((data) => data).handler(pauseDispatcher_createServerFn_handler, async ({ data }) => await setDispatcherPaused(data.paused));
|
|
109
|
+
//#endregion
|
|
110
|
+
export { getDispatcherState_createServerFn_handler, getInbox_createServerFn_handler, getLoopTasks_createServerFn_handler, getTaskById_createServerFn_handler, getTaskLog_createServerFn_handler, pauseDispatcher_createServerFn_handler, runLoopNow_createServerFn_handler, stopTask_createServerFn_handler };
|