@kky42/pievo-server 1.0.0 → 2.0.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 +1 -1
- package/.output/public/assets/{LoopView-B4H9QibC.js → LoopView-d0XYkzpx.js} +3 -3
- package/.output/public/assets/Modal-D_od-AuP.js +1 -0
- package/.output/public/assets/{SignIn-SHuRRyOv.js → SignIn-CbMeIAJZ.js} +1 -1
- package/.output/public/assets/app-vKFxjMMk.css +2 -0
- package/.output/public/assets/{artifactView-DFuubXLJ.js → artifactView-DekEs5ME.js} +1 -1
- package/.output/public/assets/index-DSF-1ahT.js +12 -0
- package/.output/public/assets/{invite._token-T8oo4Qtw.js → invite._token-Cl9Oarnq.js} +1 -1
- package/.output/public/assets/{lifecycleUi-DKkChdnU.js → lifecycleUi-DGVOf5yS.js} +1 -1
- package/.output/public/assets/{loopApi-BM2nj71x.js → loopApi-5s2-kCnu.js} +1 -1
- package/.output/public/assets/loops._loopId-B-dYxc9i.js +4 -0
- package/.output/public/assets/{loops._loopId_.runs._runId-_CflHV38.js → loops._loopId_.runs._runId-DepMp3Me.js} +2 -2
- package/.output/public/assets/notifyFns-b_jCi5XK.js +1 -0
- package/.output/public/assets/{preload-helper-CKUiEq3b.js → preload-helper-ycaoAemE.js} +1 -1
- package/.output/public/assets/{routes-B9tgli5f.js → routes-BB4aDC1D.js} +1 -1
- package/.output/public/assets/{t._teamId-Bm21mngW.js → t._teamId-D552b9PT.js} +1 -1
- package/.output/server/_libs/@base-ui/react+[...].mjs +23 -2375
- package/.output/server/_libs/@tanstack/react-router+[...].mjs +1 -1
- package/.output/server/_libs/html-react-parser+[...].mjs +1 -1
- package/.output/server/_libs/react-redux+[...].mjs +1 -1
- package/.output/server/_libs/recharts+victory-vendor.mjs +1 -1
- package/.output/server/_libs/uiw__react-codemirror.mjs +1 -1
- package/.output/server/_ssr/{CodeField-tm4rr6G3.mjs → CodeField-B7oOmmwH.mjs} +4 -4
- package/.output/server/_ssr/{DashboardView-CC7htv28.mjs → DashboardView-D3E-zevQ.mjs} +45 -35
- package/.output/server/_ssr/{LoopPlaybook-BXH8mhiX.mjs → LoopPlaybook-DJlWGia5.mjs} +3 -3
- package/.output/server/_ssr/{LoopView-DCugEbHx.mjs → LoopView-BtMANpb_.mjs} +5 -5
- package/.output/server/_ssr/Modal-DpKZHLZK.mjs +1 -1
- package/.output/server/_ssr/{SignIn-dTndU6Hw.mjs → SignIn-CjFonm71.mjs} +3 -3
- package/.output/server/_ssr/actionUi-CZbEixbf.mjs +1 -1
- package/.output/server/_ssr/{adapters-BS8XosjF.mjs → adapters-vbuo_-wD.mjs} +10 -5
- package/.output/server/_ssr/{artifactFiles-Cagtj7J0.mjs → artifactFiles-BGod8IWQ.mjs} +3 -3
- package/.output/server/_ssr/{artifactView-DS4O22wl.mjs → artifactView-CYV1r48i.mjs} +3 -3
- package/.output/server/_ssr/artifacts-CduiDAM2.mjs +2 -0
- package/.output/server/_ssr/{auth-DY1DuYZd.mjs → auth-Ca-um-e8.mjs} +9 -9
- package/.output/server/_ssr/{boot-CMHTxQpJ.mjs → boot-C0f0HGCw.mjs} +1 -1
- package/.output/server/_ssr/{boot-BbtG0ImW.mjs → boot-CkFZynUz.mjs} +533 -294
- package/.output/server/_ssr/{bun-sqlite-dialect-BW9W1_Ps-CU1Spd6z.mjs → bun-sqlite-dialect-BW9W1_Ps-CG9VPNj0.mjs} +2 -2
- package/.output/server/_ssr/{d1-sqlite-dialect-BLC8LXE6-DfG7tB8s.mjs → d1-sqlite-dialect-BLC8LXE6-DBf7xVin.mjs} +2 -2
- package/.output/server/_ssr/db-Cs0gnPZZ.mjs +2 -0
- package/.output/server/_ssr/{dist-BIxFFVZg.mjs → dist-CwI9FwLx.mjs} +2 -2
- package/.output/server/_ssr/{factory-Blq0DYfT.mjs → factory-L3gsmDL7.mjs} +2 -2
- package/.output/server/_ssr/{invite._token-NewFt27g.mjs → invite._token-CN2p7Gt3.mjs} +6 -6
- package/.output/server/_ssr/invite._token-DJxGLILJ.mjs +1 -1
- package/.output/server/_ssr/{invite._token-BRCo9LGB.mjs → invite._token-KLCPnHk-.mjs} +4 -4
- package/.output/server/_ssr/{kysely-adapter-D3XTe64J.mjs → kysely-adapter-Czkfz-W-.mjs} +1 -1
- package/.output/server/_ssr/{lifecycleUi-C9lg1r3r.mjs → lifecycleUi-BhRsBvJ7.mjs} +4 -4
- package/.output/server/_ssr/logger-Cj1GFV_8.mjs +2 -0
- package/.output/server/_ssr/{loopApi-Cxe8WyOB.mjs → loopApi-BfMnXaKT.mjs} +7 -7
- package/.output/server/_ssr/{loopApi-BtfkZQYK.mjs → loopApi-CVf9RC6s.mjs} +32 -16
- package/.output/server/_ssr/{loops._loopId-DhnArGdL.mjs → loops._loopId-CbuhuTAp.mjs} +239 -397
- package/.output/server/_ssr/{loops._loopId-7NQJPB9W.mjs → loops._loopId-gNSxIQBe.mjs} +4 -4
- package/.output/server/_ssr/{loops._loopId_.runs._runId-Dip5Xk-q.mjs → loops._loopId_.runs._runId-0MahUyHy.mjs} +48 -6
- package/.output/server/_ssr/{loops._loopId_.runs._runId-Bvuo2nki.mjs → loops._loopId_.runs._runId-BptlCXat.mjs} +4 -4
- package/.output/server/_ssr/{machineFns-Dvr5ICUy.mjs → machineFns-D5rQWyLl.mjs} +3 -3
- package/.output/server/_ssr/{node-sqlite-dialect-DhyOpJTX.mjs → node-sqlite-dialect-Dr9_QokR.mjs} +2 -2
- package/.output/server/_ssr/{notifyFns-BcMRY5kP.mjs → notifyFns-BobPaLWi.mjs} +3 -3
- package/.output/server/_ssr/{notifyFns-Q458pZmE.mjs → notifyFns-c7ZY2TWF.mjs} +5 -5
- package/.output/server/_ssr/{router-J8KZ30xw.mjs → router-B8JTBtGd.mjs} +30 -30
- package/.output/server/_ssr/{routes-D4am3Zff.mjs → routes-B-MWifFy.mjs} +6 -6
- package/.output/server/_ssr/{routes-BoGrcf-b.mjs → routes-BJCWMIzb.mjs} +5 -5
- package/.output/server/_ssr/routes-Bcs4T1ox.mjs +1 -1
- package/.output/server/_ssr/{runDiff-CpEFqo7G.mjs → runDiff-C0w1D4a3.mjs} +2 -2
- package/.output/server/_ssr/ssr.mjs +49 -49
- package/.output/server/_ssr/store-LYphMSJ-.mjs +2 -0
- package/.output/server/_ssr/t._teamId-Dy_McbRt.mjs +1 -1
- package/.output/server/_ssr/{t._teamId-CeUhzgzT.mjs → t._teamId-FYVEIAGw.mjs} +6 -6
- package/.output/server/_ssr/{t._teamId-DR-hQK7o.mjs → t._teamId-fw8RfHyI.mjs} +5 -5
- package/.output/server/_ssr/{teamFns-DA4ovI5g.mjs → teamFns-D4I-0dEB.mjs} +2 -2
- package/.output/server/_ssr/{teamFns-BIDnsg2A.mjs → teamFns-Dz41U7gA.mjs} +3 -3
- package/.output/server/_ssr/tokens-3ZFpqsuf.mjs +2 -0
- package/.output/server/_ssr/ui-Dej2qjuS.mjs +1 -1
- package/.output/server/{_tanstack-start-manifest_v-CVS6c7re.mjs → _tanstack-start-manifest_v-C9p30TZH.mjs} +20 -20
- package/.output/server/drizzle/0009_ordinary_electro.sql +1 -0
- package/.output/server/drizzle/0010_workable_rage.sql +14 -0
- package/.output/server/drizzle/0011_steep_marvel_zombies.sql +3 -0
- package/.output/server/drizzle/meta/0009_snapshot.json +1793 -0
- package/.output/server/drizzle/meta/0010_snapshot.json +1891 -0
- package/.output/server/drizzle/meta/0011_snapshot.json +1872 -0
- package/.output/server/drizzle/meta/_journal.json +21 -0
- package/.output/server/index.mjs +101 -101
- package/drizzle/0009_ordinary_electro.sql +1 -0
- package/drizzle/0010_workable_rage.sql +14 -0
- package/drizzle/0011_steep_marvel_zombies.sql +3 -0
- package/drizzle/meta/0009_snapshot.json +1793 -0
- package/drizzle/meta/0010_snapshot.json +1891 -0
- package/drizzle/meta/0011_snapshot.json +1872 -0
- package/drizzle/meta/_journal.json +21 -0
- package/package.json +1 -1
- package/scripts/pievo-server.mjs +5 -0
- package/scripts/server-cli-lib.mjs +2 -0
- package/.output/public/assets/Modal-D33gNSgx.js +0 -1
- package/.output/public/assets/app-DElSo_jy.css +0 -2
- package/.output/public/assets/index-DfpTWRSz.js +0 -12
- package/.output/public/assets/loops._loopId-B19Jw7jC.js +0 -5
- package/.output/public/assets/notifyFns-DCubjpRy.js +0 -1
- package/.output/server/_ssr/artifacts-DngKyW2u.mjs +0 -2
- package/.output/server/_ssr/db-DWAuZq1o.mjs +0 -2
- package/.output/server/_ssr/logger-Dw82jNjH.mjs +0 -2
- package/.output/server/_ssr/store-b3JcQ08F.mjs +0 -2
- package/.output/server/_ssr/tokens-ytd60FUt.mjs +0 -2
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
import { o as __toESM } from "../_runtime.mjs";
|
|
2
|
-
import {
|
|
3
|
-
import { c as CODING_AGENTS, ft as isTaskEntry, h as buildFileEntries } from "./boot-
|
|
2
|
+
import { g as require_jsx_runtime, h as require_react } from "../_libs/@base-ui/react+[...].mjs";
|
|
3
|
+
import { c as CODING_AGENTS, ft as isTaskEntry, h as buildFileEntries } from "./boot-CkFZynUz.mjs";
|
|
4
4
|
import { A as selectCls, C as labelCls, E as rel, M as until, O as runPulseStyle, S as isCompleted, _ as fmt, b as inputCls, c as btnDanger, d as btnQuiet, g as dur, h as dotLabel, i as Pre, j as tsShort, k as sectionHeadCls, l as btnPrimary, m as dotColor, n as Loading, o as btn, p as cronText, r as Pill, s as btnCost, t as ErrorBanner, x as isClosed, y as humanBytes } from "./ui-Dej2qjuS.mjs";
|
|
5
5
|
import { d as useNavigate, u as Link } from "../_libs/@tanstack/react-router+[...].mjs";
|
|
6
|
-
import { C as
|
|
7
|
-
import { n as TaskFileView, r as ViewerHead, t as ArtifactBody } from "./artifactView-
|
|
8
|
-
import {
|
|
9
|
-
import { s as useSession } from "./LoopPlaybook-BXH8mhiX.mjs";
|
|
6
|
+
import { C as stopJob, S as startJob, a as evolveJob, b as requestEdit, d as getJobDetail, g as loadOlderRuns, i as deleteJob, s as getArtifacts, v as patchJob, x as runJob, y as pauseJob } from "./loopApi-BfMnXaKT.mjs";
|
|
7
|
+
import { n as TaskFileView, r as ViewerHead, t as ArtifactBody } from "./artifactView-CYV1r48i.mjs";
|
|
8
|
+
import { s as useSession } from "./LoopPlaybook-DJlWGia5.mjs";
|
|
10
9
|
import { t as setActiveTeamCookie } from "./teamCookie-B7hLOIie.mjs";
|
|
11
|
-
import { t as SignIn } from "./SignIn-
|
|
12
|
-
import { i as
|
|
13
|
-
import {
|
|
14
|
-
import { t as
|
|
15
|
-
|
|
10
|
+
import { t as SignIn } from "./SignIn-CjFonm71.mjs";
|
|
11
|
+
import { i as useFlash, n as FlashLine, r as LoadErrorCard, t as ConfirmBar } from "./actionUi-CZbEixbf.mjs";
|
|
12
|
+
import { i as lifecycleDisplay, n as daemonStopSupport, r as deriveLoopLifecycle, t as DAEMON_UPGRADE_REQUIRED } from "./lifecycleUi-BhRsBvJ7.mjs";
|
|
13
|
+
import { a as listChannels, n as Timeline, s as mergeRuns, t as MachinesModal } from "./notifyFns-c7ZY2TWF.mjs";
|
|
14
|
+
import { t as Route } from "./loops._loopId-gNSxIQBe.mjs";
|
|
15
|
+
//#region node_modules/.nitro/vite/services/ssr/assets/loops._loopId-CbuhuTAp.js
|
|
16
16
|
var import_react = /* @__PURE__ */ __toESM(require_react());
|
|
17
17
|
var import_jsx_runtime = require_jsx_runtime();
|
|
18
18
|
/**
|
|
@@ -187,20 +187,21 @@ function ArtifactEntryView({ loopId, file }) {
|
|
|
187
187
|
/**
|
|
188
188
|
* Build the exec slice of a manual form save.
|
|
189
189
|
*
|
|
190
|
-
* Always emits so model / allowControl ride with Save even
|
|
191
|
-
*
|
|
192
|
-
* so patchJob can clear stored
|
|
193
|
-
* coerce cleared fields to `undefined` or gate the whole object on workdir.
|
|
190
|
+
* Always emits so model / reasoningEffort / allowControl ride with Save even
|
|
191
|
+
* when workdir is empty. Empty strings
|
|
192
|
+
* stay defined so patchJob can clear stored execution settings via `trim() || null` -
|
|
193
|
+
* do not coerce cleared fields to `undefined` or gate the whole object on workdir.
|
|
194
194
|
*/
|
|
195
195
|
function buildFormExec(f) {
|
|
196
196
|
return {
|
|
197
197
|
executor: "claude",
|
|
198
198
|
workdir: f.workdir.trim(),
|
|
199
199
|
model: f.model.trim(),
|
|
200
|
+
reasoningEffort: f.reasoningEffort.trim(),
|
|
200
201
|
allowControl: f.allowControl
|
|
201
202
|
};
|
|
202
203
|
}
|
|
203
|
-
var CodeField = (0, import_react.lazy)(() => import("./CodeField-
|
|
204
|
+
var CodeField = (0, import_react.lazy)(() => import("./CodeField-B7oOmmwH.mjs"));
|
|
204
205
|
function initState(initial) {
|
|
205
206
|
const e = initial?.exec;
|
|
206
207
|
return {
|
|
@@ -211,12 +212,12 @@ function initState(initial) {
|
|
|
211
212
|
taskFile: initial?.taskFile ?? "",
|
|
212
213
|
notify: initial?.notify ?? "auto",
|
|
213
214
|
channelId: initial?.channelId ?? "",
|
|
214
|
-
workflow: initial?.workflow ?? "",
|
|
215
215
|
stateSchema: initial?.stateSchema ? JSON.stringify(initial.stateSchema) : "",
|
|
216
216
|
ui: initial?.ui ?? "",
|
|
217
217
|
agent: initial?.agent ?? "claude-code",
|
|
218
218
|
workdir: e?.workdir ?? "",
|
|
219
219
|
model: e?.model ?? "",
|
|
220
|
+
reasoningEffort: e?.reasoningEffort ?? "",
|
|
220
221
|
allowControl: !!e?.allowControl
|
|
221
222
|
};
|
|
222
223
|
}
|
|
@@ -229,14 +230,17 @@ var AGENT_LABEL$1 = {
|
|
|
229
230
|
codex: "Codex"
|
|
230
231
|
};
|
|
231
232
|
function TextField({ label, value, onChange, mono, ph, hint }) {
|
|
233
|
+
const id = (0, import_react.useId)();
|
|
232
234
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
233
235
|
className: "min-w-0",
|
|
234
236
|
children: [
|
|
235
237
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("label", {
|
|
238
|
+
htmlFor: id,
|
|
236
239
|
className: labelCls,
|
|
237
240
|
children: label
|
|
238
241
|
}),
|
|
239
242
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", {
|
|
243
|
+
id,
|
|
240
244
|
type: "text",
|
|
241
245
|
className: mono ? `${inputCls} font-mono` : inputCls,
|
|
242
246
|
value,
|
|
@@ -300,7 +304,6 @@ var LoopForm = (0, import_react.forwardRef)(function LoopForm({ initial, channel
|
|
|
300
304
|
taskFile: f.taskFile.trim(),
|
|
301
305
|
notify: f.notify,
|
|
302
306
|
channelId: f.channelId || null,
|
|
303
|
-
workflow: f.workflow.trim(),
|
|
304
307
|
ui: f.ui.trim() || void 0,
|
|
305
308
|
agent: f.agent,
|
|
306
309
|
exec: buildFormExec(f),
|
|
@@ -445,13 +448,21 @@ var LoopForm = (0, import_react.forwardRef)(function LoopForm({ initial, channel
|
|
|
445
448
|
onChange: (v) => set("workdir", v),
|
|
446
449
|
mono: true,
|
|
447
450
|
ph: "/Users/you/Workspace/project",
|
|
448
|
-
hint: "Project root on the machine
|
|
451
|
+
hint: "Project root on the machine. Empty lets the daemon use a scratch directory."
|
|
449
452
|
}),
|
|
450
453
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(TextField, {
|
|
451
454
|
label: "Model",
|
|
452
455
|
value: f.model,
|
|
453
456
|
onChange: (v) => set("model", v),
|
|
454
|
-
|
|
457
|
+
ph: "default",
|
|
458
|
+
hint: "Optional arbitrary model id. Empty uses the coding-agent CLI default."
|
|
459
|
+
}),
|
|
460
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(TextField, {
|
|
461
|
+
label: "Reasoning effort",
|
|
462
|
+
value: f.reasoningEffort,
|
|
463
|
+
onChange: (v) => set("reasoningEffort", v),
|
|
464
|
+
ph: "default",
|
|
465
|
+
hint: "Optional arbitrary effort value. Empty uses the coding-agent CLI default."
|
|
455
466
|
}),
|
|
456
467
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", {
|
|
457
468
|
className: "mt-4 flex cursor-pointer items-center gap-2 text-body text-primary",
|
|
@@ -468,29 +479,7 @@ var LoopForm = (0, import_react.forwardRef)(function LoopForm({ initial, channel
|
|
|
468
479
|
children: [
|
|
469
480
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Section, {
|
|
470
481
|
title: "Agent-authored content",
|
|
471
|
-
hint: "
|
|
472
|
-
}),
|
|
473
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("label", {
|
|
474
|
-
className: labelCls,
|
|
475
|
-
children: "Workflow · JavaScript function body"
|
|
476
|
-
}),
|
|
477
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react.Suspense, {
|
|
478
|
-
fallback: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(EditorFallback, { minHeight: "180px" }),
|
|
479
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(CodeField, {
|
|
480
|
-
lang: "js",
|
|
481
|
-
value: f.workflow,
|
|
482
|
-
onChange: (v) => set("workflow", v),
|
|
483
|
-
minHeight: "180px",
|
|
484
|
-
placeholder: "const res = await tools.call(\"server.tool\", { ... })\nreturn { message: \"...\", state: { ... } }"
|
|
485
|
-
})
|
|
486
|
-
}),
|
|
487
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
488
|
-
className: hintCls,
|
|
489
|
-
children: [
|
|
490
|
-
"Deterministic zero-LLM pre-stage; top-level await and return ",
|
|
491
|
-
"{message, state}",
|
|
492
|
-
" are allowed (optional)."
|
|
493
|
-
]
|
|
482
|
+
hint: "Metrics and dashboard - usually written by evolve passes; edit by hand here when you know exactly what you want."
|
|
494
483
|
}),
|
|
495
484
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("label", {
|
|
496
485
|
className: labelCls,
|
|
@@ -567,7 +556,7 @@ var EDIT_SEEDS = [
|
|
|
567
556
|
seed: "Give this loop a goal, and finish it once the goal is met: "
|
|
568
557
|
}
|
|
569
558
|
];
|
|
570
|
-
var LoopView = (0, import_react.lazy)(() => import("./LoopView-
|
|
559
|
+
var LoopView = (0, import_react.lazy)(() => import("./LoopView-BtMANpb_.mjs").then((m) => ({ default: m.LoopView })));
|
|
571
560
|
/**
|
|
572
561
|
* Loop detail PAGE body (`/loops/$loopId`) — the redesign of the former modal.
|
|
573
562
|
* One scrolling page: a loop header (name / status / schedule / agent / machine +
|
|
@@ -576,14 +565,13 @@ var LoopView = (0, import_react.lazy)(() => import("./LoopView-DCugEbHx.mjs").th
|
|
|
576
565
|
* the Runs timeline (a strip + a clickable list, each run linking to its own
|
|
577
566
|
* detail route). Self-polls while open (fast while a run is live).
|
|
578
567
|
*
|
|
579
|
-
* Editing (2026-07 redesign): the primary path is an INLINE composer
|
|
580
|
-
*
|
|
568
|
+
* Editing (2026-07 redesign): the primary path is an INLINE composer below the
|
|
569
|
+
* always-visible action toolbar - the page stays visible, so
|
|
581
570
|
* the owner describes the change while looking at the spec/dashboard it applies
|
|
582
571
|
* to. Dispatch swaps the composer for a live status card under the header
|
|
583
572
|
* (queued → applying → settled with report + files + a link to
|
|
584
573
|
* the edit run); the page keeps polling, so the applied change surfaces around
|
|
585
|
-
* the card.
|
|
586
|
-
* full-page takeover.
|
|
574
|
+
* the card. Settings remains a full-page field-form takeover.
|
|
587
575
|
*/
|
|
588
576
|
function LoopDetailView({ id }) {
|
|
589
577
|
const navigate = useNavigate();
|
|
@@ -598,11 +586,9 @@ function LoopDetailView({ id }) {
|
|
|
598
586
|
const [editDispatched, setEditDispatched] = (0, import_react.useState)(false);
|
|
599
587
|
const [editRunId, setEditRunId] = (0, import_react.useState)(null);
|
|
600
588
|
const editBoxRef = (0, import_react.useRef)(null);
|
|
601
|
-
const [pushOpen, setPushOpen] = (0, import_react.useState)(false);
|
|
602
|
-
const [pushSaved, setPushSaved] = (0, import_react.useState)(false);
|
|
603
589
|
const [machinesOpen, setMachinesOpen] = (0, import_react.useState)(false);
|
|
604
590
|
const [pending, setPending] = (0, import_react.useState)(null);
|
|
605
|
-
const [
|
|
591
|
+
const [confirmingDelete, setConfirmingDelete] = (0, import_react.useState)(false);
|
|
606
592
|
const [flash, setFlash] = useFlash();
|
|
607
593
|
const formRef = (0, import_react.useRef)(null);
|
|
608
594
|
const deletingRef = (0, import_react.useRef)(false);
|
|
@@ -626,7 +612,7 @@ function LoopDetailView({ id }) {
|
|
|
626
612
|
setPromptCopied(false);
|
|
627
613
|
setEditDispatched(false);
|
|
628
614
|
setEditRunId(null);
|
|
629
|
-
|
|
615
|
+
setConfirmingDelete(false);
|
|
630
616
|
setOlder([]);
|
|
631
617
|
load();
|
|
632
618
|
listChannels().then(setChannels).catch(() => {});
|
|
@@ -641,25 +627,15 @@ function LoopDetailView({ id }) {
|
|
|
641
627
|
running,
|
|
642
628
|
load
|
|
643
629
|
]);
|
|
644
|
-
(0, import_react.useEffect)(() => {
|
|
645
|
-
if (!pushSaved) return;
|
|
646
|
-
const t = setTimeout(() => setPushSaved(false), 1800);
|
|
647
|
-
return () => clearTimeout(t);
|
|
648
|
-
}, [pushSaved]);
|
|
649
630
|
async function refreshAll() {
|
|
650
631
|
await load();
|
|
651
632
|
}
|
|
652
|
-
function onRun() {
|
|
653
|
-
if (detail?.job.exec) setConfirming("run");
|
|
654
|
-
else doRun();
|
|
655
|
-
}
|
|
656
633
|
async function doRun() {
|
|
657
634
|
setActionErr(null);
|
|
658
635
|
setPending("run");
|
|
659
636
|
try {
|
|
660
637
|
const r = await runJob({ data: id });
|
|
661
638
|
if (r?.error) return setActionErr(`Run failed: ${r.error}`);
|
|
662
|
-
setConfirming(null);
|
|
663
639
|
setFlash({
|
|
664
640
|
label: r.coalesced ? "Already queued" : "Queued",
|
|
665
641
|
hold: 4e3
|
|
@@ -675,7 +651,6 @@ function LoopDetailView({ id }) {
|
|
|
675
651
|
try {
|
|
676
652
|
const r = await evolveJob({ data: id });
|
|
677
653
|
if (r?.error) return setActionErr(`Evolve failed: ${r.error}`);
|
|
678
|
-
setConfirming(null);
|
|
679
654
|
setFlash({
|
|
680
655
|
label: r.coalesced ? "Evolve already queued" : "Evolve queued",
|
|
681
656
|
hold: 4e3
|
|
@@ -689,12 +664,12 @@ function LoopDetailView({ id }) {
|
|
|
689
664
|
setActionErr(null);
|
|
690
665
|
setPending("lifecycle");
|
|
691
666
|
try {
|
|
692
|
-
const r = action === "pause" ? await pauseJob({ data: id }) : action === "start" ? await startJob({ data: id }) : action === "stop" ? await stopJob({ data: id }) : action === "
|
|
667
|
+
const r = action === "pause" ? await pauseJob({ data: id }) : action === "start" ? await startJob({ data: id }) : action === "stop" ? await stopJob({ data: id }) : action === "reopen" ? await patchJob({ data: {
|
|
693
668
|
id,
|
|
694
|
-
|
|
695
|
-
} });
|
|
696
|
-
if (r.error) return setActionErr(`${action
|
|
697
|
-
|
|
669
|
+
patch: { enabled: true }
|
|
670
|
+
} }) : await deleteJob({ data: id });
|
|
671
|
+
if (r.error) return setActionErr(`${action[0].toUpperCase() + action.slice(1)} failed: ${r.error}`);
|
|
672
|
+
setConfirmingDelete(false);
|
|
698
673
|
if (r.deleted) {
|
|
699
674
|
deletingRef.current = false;
|
|
700
675
|
navigate({ to: "/" });
|
|
@@ -702,21 +677,11 @@ function LoopDetailView({ id }) {
|
|
|
702
677
|
}
|
|
703
678
|
if (action === "delete") deletingRef.current = true;
|
|
704
679
|
await refreshAll();
|
|
705
|
-
setFlash({ label: action === "start" ? "Started" : action === "pause" ? "Paused" : action === "stop" ? "Stop requested" : "Deleting" });
|
|
680
|
+
setFlash({ label: action === "start" ? "Started" : action === "reopen" ? "Reopened" : action === "pause" ? "Paused" : action === "stop" ? "Stop requested" : "Deleting" });
|
|
706
681
|
} finally {
|
|
707
682
|
setPending(null);
|
|
708
683
|
}
|
|
709
684
|
}
|
|
710
|
-
async function setPush(patch) {
|
|
711
|
-
setActionErr(null);
|
|
712
|
-
const r = await patchJob({ data: {
|
|
713
|
-
id,
|
|
714
|
-
patch
|
|
715
|
-
} });
|
|
716
|
-
if (r.error) return setActionErr(`Save failed: ${r.error}`);
|
|
717
|
-
await refreshAll();
|
|
718
|
-
setPushSaved(true);
|
|
719
|
-
}
|
|
720
685
|
async function onSave() {
|
|
721
686
|
const payload = formRef.current?.read();
|
|
722
687
|
if (!payload) return;
|
|
@@ -755,14 +720,6 @@ function LoopDetailView({ id }) {
|
|
|
755
720
|
setPending(null);
|
|
756
721
|
}
|
|
757
722
|
}
|
|
758
|
-
function onConfirm() {
|
|
759
|
-
if (confirming === "run") doRun();
|
|
760
|
-
else if (confirming === "evolve") doEvolve();
|
|
761
|
-
else if (confirming === "pause") doLifecycle("pause");
|
|
762
|
-
else if (confirming === "stop") doLifecycle("stop");
|
|
763
|
-
else if (confirming === "delete") doLifecycle("delete");
|
|
764
|
-
else if (confirming === "force-delete") doLifecycle("force-delete");
|
|
765
|
-
}
|
|
766
723
|
const backLink = /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Link, {
|
|
767
724
|
to: "/",
|
|
768
725
|
className: "inline-flex items-center gap-1.5 text-meta font-medium text-secondary transition-colors hover:text-display",
|
|
@@ -815,41 +772,6 @@ function LoopDetailView({ id }) {
|
|
|
815
772
|
setActionErr("Could not copy the prompt - try again or copy it manually.");
|
|
816
773
|
}
|
|
817
774
|
};
|
|
818
|
-
const CONFIRM = {
|
|
819
|
-
run: {
|
|
820
|
-
q: "Run one real cycle now?",
|
|
821
|
-
note: `Spawns the coding agent (${AGENT_LABEL[job.agent ?? "claude-code"] ?? job.agent ?? "Claude Code"}).`,
|
|
822
|
-
cta: "Run once",
|
|
823
|
-
danger: false
|
|
824
|
-
},
|
|
825
|
-
evolve: {
|
|
826
|
-
q: "Trigger an evolution pass now?",
|
|
827
|
-
note: "Re-authors the dashboard / tightens the gate from real run data.",
|
|
828
|
-
cta: "Evolve",
|
|
829
|
-
danger: false
|
|
830
|
-
},
|
|
831
|
-
pause: {
|
|
832
|
-
q: "Pause future runs? The current run will continue.",
|
|
833
|
-
cta: "Pause",
|
|
834
|
-
danger: false
|
|
835
|
-
},
|
|
836
|
-
stop: {
|
|
837
|
-
q: "Pause this loop, cancel queued work, and stop the current run if it is still running?",
|
|
838
|
-
cta: "Stop",
|
|
839
|
-
danger: true
|
|
840
|
-
},
|
|
841
|
-
delete: {
|
|
842
|
-
q: "Stop this loop and delete its Pievo history and synced artifacts? Local project files are not deleted.",
|
|
843
|
-
cta: "Delete",
|
|
844
|
-
danger: true
|
|
845
|
-
},
|
|
846
|
-
"force-delete": {
|
|
847
|
-
q: "Delete server data anyway",
|
|
848
|
-
note: "The machine is unreachable. Its local process may still be running. This removes Pievo authority and server data only.",
|
|
849
|
-
cta: "Delete server data anyway",
|
|
850
|
-
danger: true
|
|
851
|
-
}
|
|
852
|
-
};
|
|
853
775
|
const flashLine = flash && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
854
776
|
className: "mb-2.5",
|
|
855
777
|
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(FlashLine, {
|
|
@@ -858,296 +780,192 @@ function LoopDetailView({ id }) {
|
|
|
858
780
|
onUndo: flash.undo
|
|
859
781
|
})
|
|
860
782
|
});
|
|
861
|
-
const
|
|
862
|
-
const
|
|
863
|
-
const
|
|
864
|
-
const
|
|
865
|
-
const
|
|
866
|
-
const
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
danger: c.danger,
|
|
871
|
-
busy: confirmLocked,
|
|
872
|
-
onConfirm,
|
|
873
|
-
onCancel: () => setConfirming(null)
|
|
874
|
-
}, confirming) : lifecycle === "deleting" ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
875
|
-
className: "flex flex-wrap items-center gap-3 rounded-md border border-wire bg-raised px-4 py-3",
|
|
876
|
-
children: [
|
|
877
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
878
|
-
className: "text-body font-medium text-display",
|
|
879
|
-
children: lifecycleText
|
|
880
|
-
}),
|
|
881
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
882
|
-
className: "text-meta text-secondary",
|
|
883
|
-
children: "Server deletion is waiting for execution authority to end."
|
|
884
|
-
}),
|
|
885
|
-
!online && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", {
|
|
886
|
-
type: "button",
|
|
887
|
-
className: btnDanger,
|
|
888
|
-
onClick: () => setConfirming("force-delete"),
|
|
889
|
-
disabled: busy,
|
|
890
|
-
children: "Delete server data anyway"
|
|
891
|
-
})
|
|
892
|
-
]
|
|
893
|
-
}) : editVia ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
894
|
-
onKeyDown: (e) => {
|
|
895
|
-
if (e.key === "Escape" && pending !== "edit") {
|
|
896
|
-
e.stopPropagation();
|
|
897
|
-
setEditVia(false);
|
|
898
|
-
}
|
|
899
|
-
},
|
|
783
|
+
const deleting = lifecycle === "deleting";
|
|
784
|
+
const paused = !s.enabled && !completed && !deleting;
|
|
785
|
+
const active = s.enabled && !completed && !deleting;
|
|
786
|
+
const actionDisabled = busy || deleting;
|
|
787
|
+
const canRunWork = active || paused;
|
|
788
|
+
const canStop = canRunWork && !!s.running && protocolSupport.supported;
|
|
789
|
+
const stopTitle = s.running && !protocolSupport.supported ? DAEMON_UPGRADE_REQUIRED : !s.running ? "No run is currently running" : void 0;
|
|
790
|
+
const actionBar = /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
791
|
+
className: "min-w-0",
|
|
900
792
|
children: [
|
|
901
793
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
902
|
-
className: "flex flex-wrap items-
|
|
903
|
-
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
904
|
-
className: "text-body font-medium text-display",
|
|
905
|
-
children: "Edit with your coding agent"
|
|
906
|
-
}), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", {
|
|
907
|
-
className: "text-meta text-secondary",
|
|
908
|
-
children: [
|
|
909
|
-
"One agent pass on ",
|
|
910
|
-
onMachine,
|
|
911
|
-
" · spends credits"
|
|
912
|
-
]
|
|
913
|
-
})]
|
|
914
|
-
}),
|
|
915
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("textarea", {
|
|
916
|
-
ref: editBoxRef,
|
|
917
|
-
autoFocus: true,
|
|
918
|
-
value: editInstruction,
|
|
919
|
-
onChange: (e) => setEditInstruction(e.target.value),
|
|
920
|
-
onKeyDown: (e) => {
|
|
921
|
-
if ((e.metaKey || e.ctrlKey) && e.key === "Enter" && editInstruction.trim() && pending !== "edit") onRequestEdit();
|
|
922
|
-
},
|
|
923
|
-
rows: 3,
|
|
924
|
-
placeholder: "e.g. run at 9am on weekdays instead, and also check coffee stock",
|
|
925
|
-
className: "mt-3 w-full resize-y rounded-control border border-wire bg-raised p-3 font-mono text-label leading-relaxed text-primary outline-none transition-shadow placeholder:text-disabled focus:border-transparent focus:shadow-focus"
|
|
926
|
-
}),
|
|
927
|
-
!editInstruction.trim() && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
928
|
-
className: "mt-2 flex flex-wrap gap-1.5",
|
|
929
|
-
children: EDIT_SEEDS.map((sd) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", {
|
|
930
|
-
type: "button",
|
|
931
|
-
onClick: () => {
|
|
932
|
-
setEditInstruction(sd.seed);
|
|
933
|
-
editBoxRef.current?.focus();
|
|
934
|
-
},
|
|
935
|
-
className: "cursor-pointer rounded-full border border-wire bg-surface px-3 py-1 text-label font-medium text-secondary transition-colors hover:bg-raised hover:text-display",
|
|
936
|
-
children: sd.label
|
|
937
|
-
}, sd.label))
|
|
938
|
-
}),
|
|
939
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
940
|
-
className: "mt-3.5 flex flex-wrap items-center gap-x-2.5 gap-y-2",
|
|
794
|
+
className: "flex min-w-0 flex-wrap items-center gap-2",
|
|
941
795
|
children: [
|
|
942
796
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", {
|
|
943
|
-
className:
|
|
944
|
-
disabled:
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
797
|
+
className: btnPrimary,
|
|
798
|
+
disabled: actionDisabled || !canRunWork,
|
|
799
|
+
onClick: () => void doRun(),
|
|
800
|
+
title: !canRunWork ? "Unavailable for a completed or deleting loop" : offlineHint ?? (job.exec ? "Spends credits" : void 0),
|
|
801
|
+
"aria-label": job.exec ? "Run once - spends credits" : "Run once",
|
|
802
|
+
children: pending === "run" ? "Queuing…" : "Run once"
|
|
948
803
|
}),
|
|
949
804
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", {
|
|
950
|
-
type: "button",
|
|
951
805
|
className: btn,
|
|
952
|
-
disabled:
|
|
953
|
-
|
|
954
|
-
|
|
806
|
+
disabled: actionDisabled || !(canRunWork || completed),
|
|
807
|
+
title: "Dispatch or copy a prompt for an owner-requested edit",
|
|
808
|
+
onClick: () => setEditVia(true),
|
|
809
|
+
children: "Agent edit"
|
|
955
810
|
}),
|
|
956
811
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", {
|
|
957
812
|
className: btn,
|
|
958
|
-
disabled:
|
|
959
|
-
|
|
960
|
-
|
|
813
|
+
disabled: actionDisabled || !canRunWork,
|
|
814
|
+
title: !canRunWork ? "Unavailable for a completed or deleting loop" : offlineHint ?? "Spends credits",
|
|
815
|
+
onClick: () => void doEvolve(),
|
|
816
|
+
children: pending === "evolve" ? "Evolving…" : "Evolve once"
|
|
961
817
|
}),
|
|
962
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("
|
|
963
|
-
className:
|
|
964
|
-
|
|
818
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", {
|
|
819
|
+
className: btn,
|
|
820
|
+
disabled: actionDisabled,
|
|
821
|
+
onClick: () => setEditing(true),
|
|
822
|
+
children: "Settings"
|
|
965
823
|
}),
|
|
966
824
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", {
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
825
|
+
className: btn,
|
|
826
|
+
disabled: actionDisabled || !paused,
|
|
827
|
+
onClick: () => void doLifecycle("start"),
|
|
828
|
+
children: "Start"
|
|
829
|
+
}),
|
|
830
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", {
|
|
831
|
+
className: btn,
|
|
832
|
+
disabled: actionDisabled || !active,
|
|
833
|
+
onClick: () => void doLifecycle("pause"),
|
|
834
|
+
children: "Pause"
|
|
835
|
+
}),
|
|
836
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", {
|
|
837
|
+
className: btnDanger,
|
|
838
|
+
disabled: actionDisabled || !canStop,
|
|
839
|
+
title: stopTitle,
|
|
840
|
+
onClick: () => void doLifecycle("stop"),
|
|
841
|
+
children: "Stop"
|
|
842
|
+
}),
|
|
843
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", {
|
|
844
|
+
className: btn,
|
|
845
|
+
disabled: actionDisabled || !completed,
|
|
846
|
+
onClick: () => void doLifecycle("reopen"),
|
|
847
|
+
children: "Reopen"
|
|
848
|
+
}),
|
|
849
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", {
|
|
850
|
+
className: btnDanger,
|
|
851
|
+
disabled: actionDisabled,
|
|
852
|
+
onClick: () => setConfirmingDelete(true),
|
|
853
|
+
children: deleting ? "Deleting…" : "Delete"
|
|
974
854
|
})
|
|
975
855
|
]
|
|
976
856
|
}),
|
|
977
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
978
|
-
className: "mt-
|
|
979
|
-
children:
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
" ",
|
|
989
|
-
"and paste the prompt to adjust the loop yourself."
|
|
990
|
-
]
|
|
991
|
-
}) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_jsx_runtime.Fragment, { children: "Prefer to adjust it yourself? Copy prompt drops a ready-to-paste prompt for your own coding agent - no dispatch, no credits." })
|
|
992
|
-
})
|
|
993
|
-
]
|
|
994
|
-
}) : pushOpen ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
995
|
-
className: "flex flex-wrap items-center gap-2.5",
|
|
996
|
-
children: [
|
|
997
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
998
|
-
className: "text-label font-medium text-secondary",
|
|
999
|
-
children: "Push"
|
|
1000
|
-
}),
|
|
1001
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("select", {
|
|
1002
|
-
"aria-label": "Notify",
|
|
1003
|
-
className: pushSelectCls,
|
|
1004
|
-
value: job.notify,
|
|
1005
|
-
disabled: busy,
|
|
1006
|
-
onChange: (e) => void setPush({ notify: e.target.value }),
|
|
1007
|
-
children: [
|
|
1008
|
-
"auto",
|
|
1009
|
-
"always",
|
|
1010
|
-
"never"
|
|
1011
|
-
].map((n) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", {
|
|
1012
|
-
value: n,
|
|
1013
|
-
children: n
|
|
1014
|
-
}, n))
|
|
1015
|
-
}),
|
|
1016
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
1017
|
-
"aria-hidden": true,
|
|
1018
|
-
className: "text-secondary",
|
|
1019
|
-
children: "→"
|
|
857
|
+
confirmingDelete && !deleting && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
858
|
+
className: "mt-3",
|
|
859
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ConfirmBar, {
|
|
860
|
+
prompt: "Stop this loop and delete its server data?",
|
|
861
|
+
note: "This stops the loop and deletes server history and synced artifacts. Local files are not deleted. If the machine is unreachable, server data is still deleted and its local process may continue running.",
|
|
862
|
+
cta: "Delete",
|
|
863
|
+
danger: true,
|
|
864
|
+
busy,
|
|
865
|
+
onConfirm: () => void doLifecycle("delete"),
|
|
866
|
+
onCancel: () => setConfirmingDelete(false)
|
|
867
|
+
})
|
|
1020
868
|
}),
|
|
1021
|
-
/* @__PURE__ */ (0, import_jsx_runtime.
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
value: job.channelId ?? "",
|
|
1025
|
-
disabled: busy,
|
|
1026
|
-
onChange: (e) => void setPush({ channelId: e.target.value }),
|
|
1027
|
-
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", {
|
|
1028
|
-
value: "",
|
|
1029
|
-
children: "none (dashboard only)"
|
|
1030
|
-
}), channels.map((ch) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", {
|
|
1031
|
-
value: ch.id,
|
|
1032
|
-
children: ch.name
|
|
1033
|
-
}, ch.id))]
|
|
869
|
+
deleting && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
870
|
+
className: "mt-3 rounded-md border border-wire bg-raised px-4 py-3 text-meta text-secondary",
|
|
871
|
+
children: "Deleting… graceful stop is waiting for execution authority to end."
|
|
1034
872
|
}),
|
|
1035
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
1036
|
-
className: "
|
|
1037
|
-
|
|
1038
|
-
"
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
873
|
+
editVia && !deleting && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
874
|
+
className: "mt-4 border-t border-hairline pt-4",
|
|
875
|
+
onKeyDown: (e) => {
|
|
876
|
+
if (e.key === "Escape" && pending !== "edit") {
|
|
877
|
+
e.stopPropagation();
|
|
878
|
+
setEditVia(false);
|
|
879
|
+
}
|
|
880
|
+
},
|
|
881
|
+
children: [
|
|
882
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
883
|
+
className: "flex flex-wrap items-baseline justify-between gap-x-4 gap-y-1",
|
|
884
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
885
|
+
className: "text-body font-medium text-display",
|
|
886
|
+
children: "Edit with your coding agent"
|
|
887
|
+
}), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", {
|
|
888
|
+
className: "text-meta text-secondary",
|
|
889
|
+
children: [
|
|
890
|
+
"One agent pass on ",
|
|
891
|
+
onMachine,
|
|
892
|
+
" · spends credits"
|
|
893
|
+
]
|
|
894
|
+
})]
|
|
895
|
+
}),
|
|
896
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("textarea", {
|
|
897
|
+
ref: editBoxRef,
|
|
898
|
+
autoFocus: true,
|
|
899
|
+
value: editInstruction,
|
|
900
|
+
onChange: (e) => setEditInstruction(e.target.value),
|
|
901
|
+
onKeyDown: (e) => {
|
|
902
|
+
if ((e.metaKey || e.ctrlKey) && e.key === "Enter" && editInstruction.trim() && pending !== "edit") onRequestEdit();
|
|
903
|
+
},
|
|
904
|
+
rows: 3,
|
|
905
|
+
placeholder: "e.g. run at 9am on weekdays instead, and also check coffee stock",
|
|
906
|
+
className: "mt-3 w-full resize-y rounded-control border border-wire bg-raised p-3 font-mono text-label leading-relaxed text-primary outline-none transition-shadow placeholder:text-disabled focus:border-transparent focus:shadow-focus"
|
|
907
|
+
}),
|
|
908
|
+
!editInstruction.trim() && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
909
|
+
className: "mt-2 flex flex-wrap gap-1.5",
|
|
910
|
+
children: EDIT_SEEDS.map((sd) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", {
|
|
911
|
+
type: "button",
|
|
912
|
+
onClick: () => {
|
|
913
|
+
setEditInstruction(sd.seed);
|
|
914
|
+
editBoxRef.current?.focus();
|
|
915
|
+
},
|
|
916
|
+
className: "cursor-pointer rounded-full border border-wire bg-surface px-3 py-1 text-label font-medium text-secondary transition-colors hover:bg-raised hover:text-display",
|
|
917
|
+
children: sd.label
|
|
918
|
+
}, sd.label))
|
|
919
|
+
}),
|
|
920
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
921
|
+
className: "mt-3.5 flex flex-wrap items-center gap-x-2.5 gap-y-2",
|
|
922
|
+
children: [
|
|
923
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", {
|
|
924
|
+
className: btnCost,
|
|
925
|
+
disabled: pending === "edit" || !editInstruction.trim(),
|
|
926
|
+
title: offlineHint,
|
|
927
|
+
onClick: () => void onRequestEdit(),
|
|
928
|
+
children: pending === "edit" ? "Dispatching…" : "Dispatch to your coding agent"
|
|
929
|
+
}),
|
|
930
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", {
|
|
931
|
+
type: "button",
|
|
932
|
+
className: btn,
|
|
933
|
+
disabled: pending === "edit",
|
|
934
|
+
onClick: () => void copyEditPrompt(),
|
|
935
|
+
children: promptCopied ? "✓ Prompt copied" : "Copy prompt"
|
|
936
|
+
}),
|
|
937
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", {
|
|
938
|
+
className: btn,
|
|
939
|
+
disabled: pending === "edit",
|
|
940
|
+
onClick: () => setEditVia(false),
|
|
941
|
+
children: "Cancel"
|
|
942
|
+
}),
|
|
943
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
944
|
+
className: "hidden text-caption text-disabled sm:inline",
|
|
945
|
+
children: "⌘↩ dispatch · esc cancel"
|
|
946
|
+
})
|
|
947
|
+
]
|
|
948
|
+
}),
|
|
949
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
950
|
+
className: "mt-2 text-caption leading-snug text-disabled",
|
|
951
|
+
children: promptCopied ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", {
|
|
952
|
+
className: "text-secondary",
|
|
953
|
+
children: [
|
|
954
|
+
"✓ Copied · run your coding agent",
|
|
955
|
+
" ",
|
|
956
|
+
editDir ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: ["in ", /* @__PURE__ */ (0, import_jsx_runtime.jsx)("code", {
|
|
957
|
+
className: "break-all font-mono text-primary",
|
|
958
|
+
children: editDir
|
|
959
|
+
})] }) : "in the loop’s local directory on this machine",
|
|
960
|
+
" ",
|
|
961
|
+
"and paste the prompt to adjust the loop yourself."
|
|
962
|
+
]
|
|
963
|
+
}) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_jsx_runtime.Fragment, { children: "Prefer to adjust it yourself? Copy prompt drops a ready-to-paste prompt for your own coding agent - no dispatch, no credits." })
|
|
964
|
+
})
|
|
965
|
+
]
|
|
1047
966
|
})
|
|
1048
967
|
]
|
|
1049
|
-
})
|
|
1050
|
-
className: "flex flex-wrap items-center gap-2",
|
|
1051
|
-
children: [
|
|
1052
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", {
|
|
1053
|
-
className: btnPrimary,
|
|
1054
|
-
disabled: busy || completed,
|
|
1055
|
-
onClick: onRun,
|
|
1056
|
-
title: completed ? "Loop completed - only Edit is available until it is reopened" : s.running || s.queued ? "Queues or coalesces one exec follow-up" : offlineHint ?? (job.exec ? "Spends credits" : void 0),
|
|
1057
|
-
"aria-label": job.exec ? "Run once - spends credits" : "Run once",
|
|
1058
|
-
children: pending === "run" ? "Queuing…" : s.running || s.queued ? "Queue run" : "Run once"
|
|
1059
|
-
}),
|
|
1060
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", {
|
|
1061
|
-
className: btn,
|
|
1062
|
-
disabled: busy,
|
|
1063
|
-
title: "Queues an edit; a queued edit is updated with the latest instruction",
|
|
1064
|
-
onClick: () => setEditVia(true),
|
|
1065
|
-
children: "Edit"
|
|
1066
|
-
}),
|
|
1067
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(MenuRoot, { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(MenuTrigger, {
|
|
1068
|
-
className: `${btn} px-2.5`,
|
|
1069
|
-
disabled: busy,
|
|
1070
|
-
"aria-label": "More actions",
|
|
1071
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("svg", {
|
|
1072
|
-
"aria-hidden": true,
|
|
1073
|
-
width: "16",
|
|
1074
|
-
height: "16",
|
|
1075
|
-
viewBox: "0 0 16 16",
|
|
1076
|
-
fill: "currentColor",
|
|
1077
|
-
children: [
|
|
1078
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("circle", {
|
|
1079
|
-
cx: "3",
|
|
1080
|
-
cy: "8",
|
|
1081
|
-
r: "1.4"
|
|
1082
|
-
}),
|
|
1083
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("circle", {
|
|
1084
|
-
cx: "8",
|
|
1085
|
-
cy: "8",
|
|
1086
|
-
r: "1.4"
|
|
1087
|
-
}),
|
|
1088
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("circle", {
|
|
1089
|
-
cx: "13",
|
|
1090
|
-
cy: "8",
|
|
1091
|
-
r: "1.4"
|
|
1092
|
-
})
|
|
1093
|
-
]
|
|
1094
|
-
})
|
|
1095
|
-
}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(MenuPortal, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(MenuPositioner, {
|
|
1096
|
-
side: "bottom",
|
|
1097
|
-
align: "end",
|
|
1098
|
-
sideOffset: 6,
|
|
1099
|
-
className: "z-[950]",
|
|
1100
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(MenuPopup, {
|
|
1101
|
-
className: "glass-strong min-w-[176px] origin-[var(--transform-origin)] rounded-control py-1.5 outline-none transition-[opacity,transform] duration-150 data-[ending-style]:scale-95 data-[ending-style]:opacity-0 data-[starting-style]:scale-95 data-[starting-style]:opacity-0",
|
|
1102
|
-
children: [
|
|
1103
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(MenuItem, {
|
|
1104
|
-
className: menuItem,
|
|
1105
|
-
disabled: busy || completed,
|
|
1106
|
-
onClick: () => setConfirming("evolve"),
|
|
1107
|
-
title: completed ? "Completed loops only accept manual edits" : offlineHint ?? "Spends credits",
|
|
1108
|
-
children: pending === "evolve" ? "Evolving…" : "Evolve now"
|
|
1109
|
-
}),
|
|
1110
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(MenuItem, {
|
|
1111
|
-
className: menuItem,
|
|
1112
|
-
onClick: () => setPushOpen(true),
|
|
1113
|
-
children: "Push…"
|
|
1114
|
-
}),
|
|
1115
|
-
completed ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(MenuItem, {
|
|
1116
|
-
className: menuItem,
|
|
1117
|
-
onClick: () => void patchJob({ data: {
|
|
1118
|
-
id,
|
|
1119
|
-
patch: { enabled: true }
|
|
1120
|
-
} }).then(refreshAll),
|
|
1121
|
-
children: "Reopen"
|
|
1122
|
-
}) : lifecycle === "paused" ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(MenuItem, {
|
|
1123
|
-
className: menuItem,
|
|
1124
|
-
onClick: () => void doLifecycle("start"),
|
|
1125
|
-
children: "Start"
|
|
1126
|
-
}) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(MenuItem, {
|
|
1127
|
-
className: menuItem,
|
|
1128
|
-
onClick: () => setConfirming("pause"),
|
|
1129
|
-
children: "Pause"
|
|
1130
|
-
}),
|
|
1131
|
-
!completed && lifecycle !== "stopping" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(MenuItem, {
|
|
1132
|
-
className: menuItemDanger,
|
|
1133
|
-
disabled: !!s.running && !protocolSupport.supported,
|
|
1134
|
-
title: s.running && !protocolSupport.supported ? "Daemon upgrade required to stop a running process. Run `npm install -g @kky42/pievo@latest`, then `pievo daemon restart`." : void 0,
|
|
1135
|
-
onClick: () => setConfirming("stop"),
|
|
1136
|
-
children: "Stop"
|
|
1137
|
-
}),
|
|
1138
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Separator, { className: "my-1.5 h-px bg-hairline" }),
|
|
1139
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(MenuItem, {
|
|
1140
|
-
className: menuItemDanger,
|
|
1141
|
-
disabled: !!s.running && !protocolSupport.supported,
|
|
1142
|
-
title: s.running && !protocolSupport.supported ? DAEMON_UPGRADE_REQUIRED : void 0,
|
|
1143
|
-
onClick: () => setConfirming("delete"),
|
|
1144
|
-
children: "Delete"
|
|
1145
|
-
})
|
|
1146
|
-
]
|
|
1147
|
-
})
|
|
1148
|
-
}) })] })
|
|
1149
|
-
]
|
|
1150
|
-
}) });
|
|
968
|
+
});
|
|
1151
969
|
const actionErrEl = actionErr && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ErrorBanner, {
|
|
1152
970
|
message: actionErr,
|
|
1153
971
|
onDismiss: () => setActionErr(null),
|
|
@@ -1245,6 +1063,10 @@ function LoopDetailView({ id }) {
|
|
|
1245
1063
|
})]
|
|
1246
1064
|
});
|
|
1247
1065
|
const agentLabel = AGENT_LABEL[job.agent ?? "claude-code"] ?? job.agent ?? "Claude Code";
|
|
1066
|
+
const modelLabel = job.exec?.model?.trim() || "default";
|
|
1067
|
+
const reasoningEffortLabel = job.exec?.reasoningEffort?.trim() || "default";
|
|
1068
|
+
const newestRun = runs[0];
|
|
1069
|
+
const latestIncidentRun = newestRun?.reportIncident ? newestRun : void 0;
|
|
1248
1070
|
const metaDot = /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
1249
1071
|
className: "text-wire",
|
|
1250
1072
|
children: "·"
|
|
@@ -1266,7 +1088,7 @@ function LoopDetailView({ id }) {
|
|
|
1266
1088
|
className: "text-[28px] font-semibold leading-tight tracking-[-0.015em] text-display",
|
|
1267
1089
|
children: s.name
|
|
1268
1090
|
}),
|
|
1269
|
-
completed ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Pill, {
|
|
1091
|
+
lifecycle === "completed" ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Pill, {
|
|
1270
1092
|
tone: "success",
|
|
1271
1093
|
dot: "green",
|
|
1272
1094
|
children: "Completed"
|
|
@@ -1289,6 +1111,22 @@ function LoopDetailView({ id }) {
|
|
|
1289
1111
|
title: "Recorded coding agent",
|
|
1290
1112
|
children: agentLabel
|
|
1291
1113
|
}),
|
|
1114
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Pill, {
|
|
1115
|
+
tone: "outline",
|
|
1116
|
+
title: `Model: ${modelLabel}`,
|
|
1117
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", {
|
|
1118
|
+
className: "max-w-72 truncate",
|
|
1119
|
+
children: ["Model: ", modelLabel]
|
|
1120
|
+
})
|
|
1121
|
+
}),
|
|
1122
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Pill, {
|
|
1123
|
+
tone: "outline",
|
|
1124
|
+
title: `Reasoning: ${reasoningEffortLabel}`,
|
|
1125
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", {
|
|
1126
|
+
className: "max-w-72 truncate",
|
|
1127
|
+
children: ["Reasoning: ", reasoningEffortLabel]
|
|
1128
|
+
})
|
|
1129
|
+
}),
|
|
1292
1130
|
crossTeam && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Pill, {
|
|
1293
1131
|
tone: "outline",
|
|
1294
1132
|
title: "This loop belongs to another of your teams",
|
|
@@ -1339,7 +1177,7 @@ function LoopDetailView({ id }) {
|
|
|
1339
1177
|
children: s.goal
|
|
1340
1178
|
})]
|
|
1341
1179
|
}),
|
|
1342
|
-
completed && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
1180
|
+
lifecycle === "completed" && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
1343
1181
|
className: "mt-2 text-body leading-snug text-success",
|
|
1344
1182
|
children: [
|
|
1345
1183
|
"Completed",
|
|
@@ -1349,6 +1187,10 @@ function LoopDetailView({ id }) {
|
|
|
1349
1187
|
children: [" - ", s.completionReason]
|
|
1350
1188
|
})
|
|
1351
1189
|
]
|
|
1190
|
+
}),
|
|
1191
|
+
latestIncidentRun?.reportIncident && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
1192
|
+
className: "mt-2 text-body leading-snug text-secondary",
|
|
1193
|
+
children: latestIncidentRun.outcome === "error" ? "Last run failed · Terminal report rejected" : "Last run telemetry warning · Terminal report rejected"
|
|
1352
1194
|
})
|
|
1353
1195
|
]
|
|
1354
1196
|
})
|
|
@@ -1495,7 +1337,7 @@ function LoopDetailView({ id }) {
|
|
|
1495
1337
|
});
|
|
1496
1338
|
}
|
|
1497
1339
|
/**
|
|
1498
|
-
*
|
|
1340
|
+
* Settings page heading. The field form is an in-page mode takeover (NOT
|
|
1499
1341
|
* a modal), so this is a plain heading - NOT `ModalHead`, whose Base UI
|
|
1500
1342
|
* `Dialog.Title`/`Dialog.Close` require a `Dialog.Root` ancestor and throw
|
|
1501
1343
|
* ("Cannot destructure property 'store' of 'useDialogRootContext(...)'") when
|
|
@@ -1514,11 +1356,11 @@ function EditHead({ name, onBack }) {
|
|
|
1514
1356
|
}),
|
|
1515
1357
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("h1", {
|
|
1516
1358
|
className: "mt-2.5 text-[24px] font-semibold leading-tight tracking-[-0.015em] text-display",
|
|
1517
|
-
children: ["
|
|
1359
|
+
children: ["Settings · ", name]
|
|
1518
1360
|
}),
|
|
1519
1361
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
|
|
1520
1362
|
className: "mt-1.5 max-w-[640px] text-meta leading-snug text-secondary",
|
|
1521
|
-
children: "
|
|
1363
|
+
children: "Loop configuration, notifications, and push channel, saved directly - no agent pass or credits. For changes in plain words, use Agent edit instead."
|
|
1522
1364
|
})
|
|
1523
1365
|
] });
|
|
1524
1366
|
}
|