@kky42/pievo-server 2.4.1 → 2.4.4

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 (82) hide show
  1. package/.output/nitro.json +1 -1
  2. package/.output/public/assets/MachinesModal-Ci18Bitd.js +1 -0
  3. package/.output/public/assets/{SignIn-BdkKWOSs.js → SignIn-Czy-XJou.js} +1 -1
  4. package/.output/public/assets/{actionUi-BYBeYy7U.js → actionUi-DGJmNwsD.js} +1 -1
  5. package/.output/public/assets/app-CuZ0I3Mb.css +2 -0
  6. package/.output/public/assets/index-gJavUZIA.js +10 -0
  7. package/.output/public/assets/{invite._token-ZnVQqqq4.js → invite._token-BQUbjPMM.js} +1 -1
  8. package/.output/public/assets/invite._token-BUYUsIBj.js +1 -0
  9. package/.output/public/assets/lifecycleUi-C0DaC6NM.js +1 -0
  10. package/.output/public/assets/loops._loopId-BkEPvT1q.js +67 -0
  11. package/.output/public/assets/{loops._loopId_.runs._runId-CA0-q1y5.js → loops._loopId_.runs._runId-SM4sD1xB.js} +2 -2
  12. package/.output/public/assets/{preload-helper-CUIO87nJ.js → preload-helper-D1jXs0sN.js} +3 -3
  13. package/.output/public/assets/routes-4mIvs8LG.js +1 -0
  14. package/.output/public/assets/routes-B0svLfFq.js +1 -0
  15. package/.output/public/assets/t._teamId-BLO_bz6b.js +1 -0
  16. package/.output/public/assets/t._teamId-D-wGh4mo.js +1 -0
  17. package/.output/public/assets/{ui-DGOT8AoZ.js → ui-DGHTxOhC.js} +1 -1
  18. package/.output/server/_ssr/{DashboardView-D_hKsCsv.mjs → DashboardView-DqZLADCp.mjs} +70 -333
  19. package/.output/server/_ssr/{MachinesModal-DZ_9ErAU.mjs → MachinesModal-BsCfGuwp.mjs} +142 -9
  20. package/.output/server/_ssr/{SignIn-DjSrg0nO.mjs → SignIn-ffgDY0yf.mjs} +3 -3
  21. package/.output/server/_ssr/{SocialLinks-BTjsnVOm.mjs → SocialLinks-Bt7huqfS.mjs} +7 -13
  22. package/.output/server/_ssr/{actionUi-D15R8L7R.mjs → actionUi-DD7Cd7Le.mjs} +2 -2
  23. package/.output/server/_ssr/{artifactFiles-CV3OXxRD.mjs → artifactFiles-DHBXTtZn.mjs} +3 -3
  24. package/.output/server/_ssr/{artifactKind-ByzVa7fg.mjs → artifactKind-CwQ_Ddj6.mjs} +3 -3
  25. package/.output/server/_ssr/artifacts-BR3jj0NC.mjs +2 -0
  26. package/.output/server/_ssr/{auth-CPCDf6Wr.mjs → auth-C0zoZCGe.mjs} +9 -9
  27. package/.output/server/_ssr/boot-CdOO4xOo.mjs +2 -0
  28. package/.output/server/_ssr/{boot-BbWxaF-z.mjs → boot-sNlIkoLe.mjs} +66 -129
  29. package/.output/server/_ssr/{bun-sqlite-dialect-BW9W1_Ps-8MIh9jN1.mjs → bun-sqlite-dialect-BW9W1_Ps-DmlZWqO7.mjs} +2 -2
  30. package/.output/server/_ssr/{d1-sqlite-dialect-BLC8LXE6-CcMQ01_d.mjs → d1-sqlite-dialect-BLC8LXE6-CCNzqZwZ.mjs} +2 -2
  31. package/.output/server/_ssr/db-CwLD-5w1.mjs +2 -0
  32. package/.output/server/_ssr/{dist-AxCsRawm.mjs → dist-B3SxDOpW.mjs} +2 -2
  33. package/.output/server/_ssr/{factory-S7MaMVC2.mjs → factory-Dv3Zopis.mjs} +2 -2
  34. package/.output/server/_ssr/{invite._token-B1UgMbNQ.mjs → invite._token-AvtAuDKv.mjs} +4 -12
  35. package/.output/server/_ssr/{invite._token-BliJIGk4.mjs → invite._token-CHR5K84a.mjs} +6 -14
  36. package/.output/server/_ssr/{invite._token-D296YVGd.mjs → invite._token-tw3mgvEo.mjs} +8 -16
  37. package/.output/server/_ssr/{kysely-adapter-DUdpqcCJ.mjs → kysely-adapter-nL7WKSgw.mjs} +1 -1
  38. package/.output/server/_ssr/lifecycleUi-DOr6Af13.mjs +51 -0
  39. package/.output/server/_ssr/logger-B8m8F1Qu.mjs +2 -0
  40. package/.output/server/_ssr/{loopApi-Dy8ztANM.mjs → loopApi-7YHXDl5g.mjs} +14 -61
  41. package/.output/server/_ssr/{loopProjection-BZ1_IYCr.mjs → loopProjection-eZvVobW7.mjs} +30 -5
  42. package/.output/server/_ssr/{loops._loopId-CKsAnxMl.mjs → loops._loopId-TEIcuqZU.mjs} +84 -112
  43. package/.output/server/_ssr/{loops._loopId_.runs._runId-a_SyY8rX.mjs → loops._loopId_.runs._runId-B4jXeonc.mjs} +3 -3
  44. package/.output/server/_ssr/{loops._loopId_.runs._runId-DG405pQs.mjs → loops._loopId_.runs._runId-BVQKe8xT.mjs} +6 -6
  45. package/.output/server/_ssr/{machineFns-BSaE7K88.mjs → machineFns-ByMsgG12.mjs} +3 -3
  46. package/.output/server/_ssr/{node-sqlite-dialect-rWwVyt2J.mjs → node-sqlite-dialect-CjNineno.mjs} +2 -2
  47. package/.output/server/_ssr/{router-lMkobh5r.mjs → router-DyhWcIzt.mjs} +65 -118
  48. package/.output/server/_ssr/{routes-DNCZrs8z.mjs → routes-BWLQNDn5.mjs} +2 -2
  49. package/.output/server/_ssr/{routes-ufPbrGHs.mjs → routes-Cz49hLy6.mjs} +5 -5
  50. package/.output/server/_ssr/{routes-CRHc9cLG.mjs → routes-DqIGr7p0.mjs} +5 -5
  51. package/.output/server/_ssr/runDiff-Ba8Lg1vg.mjs +2 -0
  52. package/.output/server/_ssr/ssr.mjs +39 -47
  53. package/.output/server/_ssr/store-Cujtg2QE.mjs +2 -0
  54. package/.output/server/_ssr/{t._teamId-BoBoYEHL.mjs → t._teamId-COoQSQtH.mjs} +5 -5
  55. package/.output/server/_ssr/{t._teamId-DcWOYjPf.mjs → t._teamId-Dms0PTMu.mjs} +2 -2
  56. package/.output/server/_ssr/{t._teamId-QD2nN0wn.mjs → t._teamId-xFPYdSPu.mjs} +5 -5
  57. package/.output/server/_ssr/{teamFns-BsmconJ1.mjs → teamFns-H438WnZC.mjs} +12 -30
  58. package/.output/server/_ssr/{teamFns-DcoVuWyH.mjs → teamFns-gilVwh7z.mjs} +2 -2
  59. package/.output/server/_ssr/tokens-DgG_Syq3.mjs +2 -0
  60. package/.output/server/_ssr/{ui-DmFKW2H_.mjs → ui-dMEI4sHj.mjs} +13 -9
  61. package/.output/server/_tanstack-start-manifest_v-UkU-Jq6w.mjs +86 -0
  62. package/.output/server/index.mjs +84 -84
  63. package/package.json +1 -2
  64. package/.output/public/assets/MachinesModal-CEddj7la.js +0 -1
  65. package/.output/public/assets/app-BAgHQVvr.css +0 -2
  66. package/.output/public/assets/index-BZLqD3JI.js +0 -12
  67. package/.output/public/assets/invite._token-BCLgmTO7.js +0 -1
  68. package/.output/public/assets/lifecycleUi-C7dwHtbw.js +0 -1
  69. package/.output/public/assets/loops._loopId-X8PSlgdB.js +0 -67
  70. package/.output/public/assets/routes-BjKcDy6D.js +0 -1
  71. package/.output/public/assets/routes-bfMcArTT.js +0 -1
  72. package/.output/public/assets/t._teamId-B75J8h0x.js +0 -1
  73. package/.output/public/assets/t._teamId-D7WVPMDr.js +0 -1
  74. package/.output/server/_ssr/artifacts-BhQvaGjF.mjs +0 -2
  75. package/.output/server/_ssr/boot-COHf8Gv3.mjs +0 -2
  76. package/.output/server/_ssr/db-dw61xIt1.mjs +0 -2
  77. package/.output/server/_ssr/lifecycleUi-Dad3hvhm.mjs +0 -37
  78. package/.output/server/_ssr/logger-DdUWuMdh.mjs +0 -2
  79. package/.output/server/_ssr/runDiff-CrZzjokj.mjs +0 -2
  80. package/.output/server/_ssr/store-CirPHuib.mjs +0 -2
  81. package/.output/server/_ssr/tokens-XngoyCU8.mjs +0 -2
  82. package/.output/server/_tanstack-start-manifest_v-Xd5bMpJe.mjs +0 -87
@@ -1,20 +1,16 @@
1
1
  import { o as __toESM } from "../_runtime.mjs";
2
2
  import { g as require_react, h as require_jsx_runtime, s as TooltipProvider } from "../_libs/@base-ui/react+[...].mjs";
3
- import { E as selectCls, S as rel, a as btn, b as labelCls, c as btnPrimaryPill, d as cronText, k as useHydrated, o as btnDanger, p as dotLabel, r as Pill, s as btnPrimary, t as ErrorBanner, u as btnSm, x as lastRunOf, y as inputCls } from "./ui-DmFKW2H_.mjs";
3
+ import { T as selectCls, _ as inputCls, a as btn, l as btnSm, o as btnDanger, r as Pill, s as btnPrimary, t as ErrorBanner, v as labelCls } from "./ui-dMEI4sHj.mjs";
4
4
  import { d as useNavigate } from "../_libs/@tanstack/react-router+[...].mjs";
5
- import { _ as listMyTeams, f as getConfig, g as listLoops, n as GitHubIcon, o as claimStatus, r as PievoLogo, t as GITHUB_URL, v as loadOlderRuns, y as mintClaim } from "./SocialLinks-BTjsnVOm.mjs";
5
+ import { _ as loadOlderRuns, d as getConfig, g as listMyTeams, h as listLoops, n as GitHubIcon, r as PievoLogo, t as GITHUB_URL, v as mintClaim } from "./SocialLinks-Bt7huqfS.mjs";
6
6
  import { t as setActiveTeamCookie } from "./teamCookie-B7hLOIie.mjs";
7
- import { a as getTeamDetail, d as revokeTeamInvite, f as setTeamMemberRole, i as deleteTeam, l as removeTeamMember, n as createTeam, o as leaveTeam, r as createTeamInvite, s as listManagedTeams, t as addTeamMember, u as renameTeam } from "./teamFns-DcoVuWyH.mjs";
8
- import { r as deriveLoopLifecycle } from "./lifecycleUi-Dad3hvhm.mjs";
9
- import { a as Timeline, i as ModalSection, n as Modal, o as listMachines, r as ModalHead, s as mergeRuns, t as MachinesModal } from "./MachinesModal-DZ_9ErAU.mjs";
10
- //#region node_modules/.nitro/vite/services/ssr/assets/DashboardView-D_hKsCsv.js
7
+ import { a as getTeamDetail, d as revokeTeamInvite, f as setTeamMemberRole, i as deleteTeam, l as removeTeamMember, n as createTeam, o as leaveTeam, r as createTeamInvite, s as listManagedTeams, t as addTeamMember, u as renameTeam } from "./teamFns-gilVwh7z.mjs";
8
+ import { a as ModalSection, c as listMachines, i as ModalHead, l as mergeRuns, n as MachinesModal, r as Modal, s as daemonConnectCommand, t as LoopOverview } from "./MachinesModal-BsCfGuwp.mjs";
9
+ //#region node_modules/.nitro/vite/services/ssr/assets/DashboardView-DqZLADCp.js
11
10
  var import_react = /* @__PURE__ */ __toESM(require_react());
12
11
  var import_jsx_runtime = require_jsx_runtime();
13
12
  function LoopCard({ loop, onOpen, onPickRun }) {
14
13
  const en = loop.enabled;
15
- const last = lastRunOf(loop);
16
- const lifecycle = deriveLoopLifecycle(loop);
17
- const hydrated = useHydrated();
18
14
  const [older, setOlder] = (0, import_react.useState)([]);
19
15
  const runs = (0, import_react.useMemo)(() => older.length ? mergeRuns(loop.runs ?? [], older) : loop.runs ?? [], [loop.runs, older]);
20
16
  const newestRun = runs.at(-1);
@@ -30,92 +26,17 @@ function LoopCard({ loop, onOpen, onPickRun }) {
30
26
  if (more.length) setOlder((prev) => mergeRuns(prev, more));
31
27
  return more.length;
32
28
  };
33
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
29
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
34
30
  onClick: () => onOpen(loop.id),
35
31
  className: `mb-[18px] cursor-pointer rounded-card border border-hairline bg-surface px-[26px] pb-5 pt-[22px] shadow-card transition-colors hover:border-wire ${en || latestIncidentRun?.reportIncident || loop.pauseCause?.kind === "failure-streak" || loop.pauseCause?.kind === "blocked" ? "" : "opacity-60"}`,
36
32
  style: { animation: "fadeIn .25s cubic-bezier(0.25,0.1,0.25,1) both" },
37
- children: [
38
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
39
- className: "mb-6 flex flex-wrap items-center gap-3",
40
- children: [
41
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", {
42
- type: "button",
43
- onClick: (e) => {
44
- e.stopPropagation();
45
- onOpen(loop.id);
46
- },
47
- className: "cursor-pointer rounded-sm text-left text-[17px] font-semibold tracking-[-0.01em] text-display outline-none focus-visible:ring-2 focus-visible:ring-interactive focus-visible:ring-offset-4 focus-visible:ring-offset-surface",
48
- children: loop.name
49
- }),
50
- lifecycle === "stopping" ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Pill, {
51
- tone: "running",
52
- dot: "pulse",
53
- children: "Stopping"
54
- }) : lifecycle === "paused-finishing" ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Pill, { children: loop.pauseCause?.kind === "blocked" ? "Paused — blocked · current run finishing" : loop.pauseCause?.kind === "owner" ? "Paused by owner · current run finishing" : "Paused · current run finishing" }) : lifecycle === "deleting" ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Pill, { children: "Deleting" }) : loop.running ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Pill, {
55
- tone: "running",
56
- dot: "pulse",
57
- children: "Running"
58
- }) : loop.queued && loop.reconciliationBlocking ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Pill, {
59
- tone: "outline",
60
- children: "Queued · waiting for machine recovery"
61
- }) : loop.queued ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Pill, {
62
- tone: "outline",
63
- children: "Queued"
64
- }) : null,
65
- lifecycle === "paused" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Pill, {
66
- tone: loop.pauseCause?.kind === "blocked" ? "accent" : void 0,
67
- children: loop.pauseCause?.kind === "blocked" ? "Paused — blocked" : loop.pauseCause?.kind === "failure-streak" ? "Paused automatically" : loop.pauseCause?.kind === "owner" ? "Paused by owner" : "Paused"
68
- }),
69
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
70
- className: "ml-auto min-w-0 text-right text-meta text-secondary",
71
- children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
72
- className: "whitespace-nowrap",
73
- children: [
74
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
75
- className: "text-primary",
76
- title: loop.schedule.mode === "cron" ? loop.schedule.cron : void 0,
77
- children: loop.schedule.mode === "continuous" ? `continuous · ${loop.schedule.delayMinutes}m` : `${cronText(loop.schedule.cron)} · ${loop.schedule.timezone} · ${loop.schedule.overlap}`
78
- }),
79
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
80
- className: "mx-2.5 text-wire",
81
- children: "·"
82
- }),
83
- loop.agent
84
- ]
85
- }), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
86
- className: "mt-1 truncate text-caption text-disabled",
87
- title: loop.workdir,
88
- children: [
89
- loop.workdir,
90
- " · Model: ",
91
- loop.model || "default",
92
- " · Reasoning: ",
93
- loop.reasoningEffort || "default"
94
- ]
95
- })]
96
- })
97
- ]
98
- }),
99
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Timeline, {
100
- loop,
101
- runs,
102
- total: loop.runCount,
103
- onLoadMore: loadMore,
104
- onPickRun: (run) => onPickRun(loop.id, run)
105
- }),
106
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
107
- className: "mt-[18px] flex items-center gap-2 text-label text-secondary",
108
- children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { children: [loop.runCount, " runs"] }), last && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { children: [
109
- "· last ",
110
- dotLabel(last),
111
- hydrated && ` · ${rel(last.ts)}`
112
- ] })]
113
- }),
114
- latestIncidentRun?.reportIncident && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
115
- className: "mt-1.5 text-label text-secondary",
116
- children: latestIncidentRun.phase === "error" ? "Last run failed · Terminal report rejected" : "Last run telemetry warning · Terminal report rejected"
117
- })
118
- ]
33
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(LoopOverview, {
34
+ loop,
35
+ runs,
36
+ onLoadMore: loadMore,
37
+ onPickRun: (run) => onPickRun(loop.id, run),
38
+ onOpen: () => onOpen(loop.id)
39
+ })
119
40
  });
120
41
  }
121
42
  /**
@@ -629,113 +550,21 @@ function TeamsModal({ open, onClose, activeTeamId }) {
629
550
  ]
630
551
  });
631
552
  }
632
- var SLOW_WAIT_MS = 1e5;
633
- var AGENT_LABEL = {
634
- "claude-code": "Claude Code",
635
- codex: "Codex"
636
- };
637
- function ClaudeCodeMark({ size = 14 }) {
638
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("svg", {
639
- "aria-hidden": true,
640
- width: size,
641
- height: size,
642
- viewBox: "0 0 24 24",
643
- fill: "#D97757",
644
- fillRule: "evenodd",
645
- className: "shrink-0",
646
- xmlns: "http://www.w3.org/2000/svg",
647
- children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", {
648
- clipRule: "evenodd",
649
- d: "M20.998 10.949H24v3.102h-3v3.028h-1.487V20H18v-2.921h-1.487V20H15v-2.921H9V20H7.488v-2.921H6V20H4.487v-2.921H3V14.05H0V10.95h3V5h17.998v5.949zM6 10.949h1.488V8.102H6v2.847zm10.51 0H18V8.102h-1.49v2.847z"
650
- })
651
- });
652
- }
653
- /** Codex color mark (LobeHub icon set) — verbatim: white app tile + gradient glyph. */
654
- function CodexMark({ size = 14 }) {
655
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("svg", {
656
- "aria-hidden": true,
657
- width: size,
658
- height: size,
659
- viewBox: "0 0 24 24",
660
- className: "shrink-0",
661
- xmlns: "http://www.w3.org/2000/svg",
662
- children: [
663
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", {
664
- d: "M19.503 0H4.496A4.496 4.496 0 000 4.496v15.007A4.496 4.496 0 004.496 24h15.007A4.496 4.496 0 0024 19.503V4.496A4.496 4.496 0 0019.503 0z",
665
- fill: "#fff"
666
- }),
667
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", {
668
- d: "M9.064 3.344a4.578 4.578 0 012.285-.312c1 .115 1.891.54 2.673 1.275.01.01.024.017.037.021a.09.09 0 00.043 0 4.55 4.55 0 013.046.275l.047.022.116.057a4.581 4.581 0 012.188 2.399c.209.51.313 1.041.315 1.595a4.24 4.24 0 01-.134 1.223.123.123 0 00.03.115c.594.607.988 1.33 1.183 2.17.289 1.425-.007 2.71-.887 3.854l-.136.166a4.548 4.548 0 01-2.201 1.388.123.123 0 00-.081.076c-.191.551-.383 1.023-.74 1.494-.9 1.187-2.222 1.846-3.711 1.838-1.187-.006-2.239-.44-3.157-1.302a.107.107 0 00-.105-.024c-.388.125-.78.143-1.204.138a4.441 4.441 0 01-1.945-.466 4.544 4.544 0 01-1.61-1.335c-.152-.202-.303-.392-.414-.617a5.81 5.81 0 01-.37-.961 4.582 4.582 0 01-.014-2.298.124.124 0 00.006-.056.085.085 0 00-.027-.048 4.467 4.467 0 01-1.034-1.651 3.896 3.896 0 01-.251-1.192 5.189 5.189 0 01.141-1.6c.337-1.112.982-1.985 1.933-2.618.212-.141.413-.251.601-.33.215-.089.43-.164.646-.227a.098.098 0 00.065-.066 4.51 4.51 0 01.829-1.615 4.535 4.535 0 011.837-1.388zm3.482 10.565a.637.637 0 000 1.272h3.636a.637.637 0 100-1.272h-3.636zM8.462 9.23a.637.637 0 00-1.106.631l1.272 2.224-1.266 2.136a.636.636 0 101.095.649l1.454-2.455a.636.636 0 00.005-.64L8.462 9.23z",
669
- fill: "url(#lobe-icons-codex-grad)"
670
- }),
671
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("defs", { children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("linearGradient", {
672
- gradientUnits: "userSpaceOnUse",
673
- id: "lobe-icons-codex-grad",
674
- x1: "12",
675
- x2: "12",
676
- y1: "3",
677
- y2: "21",
678
- children: [
679
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("stop", { stopColor: "#B1A7FF" }),
680
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("stop", {
681
- offset: ".5",
682
- stopColor: "#7A9DFF"
683
- }),
684
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("stop", {
685
- offset: "1",
686
- stopColor: "#3941FF"
687
- })
688
- ]
689
- }) })
690
- ]
691
- });
692
- }
693
- var instructionFor = (origin) => `Fetch ${origin}/api/bootstrap and help me build a loop.`;
694
- /**
695
- * New loop = capture-from-Claude-Code (paste-forward, no machine picker). The web
696
- * mints a claim token, shows ONE instruction block, and waits. The user pastes it
697
- * into their own Claude Code session (where they just did the task); Claude
698
- * follows /api/bootstrap — ensures a daemon is running (the token authorizes a new
699
- * machine, or the machine's stored token reuses an existing one) and POSTs the
700
- * loop through /api/machine/cli with this token as `claim`. We poll until
701
- * the loop lands, then close. No machine selection: the binding is decided on the
702
- * machine, the claim just correlates the result back to this dialog.
703
- *
704
- * Pievo is BYOA-only: every loop runs on the connected machine; there is no
705
- * hosted-agent option.
706
- */
707
- function ComposeModal({ open, onClose, onCreated, teamId }) {
553
+ function ComposeModal({ open, onClose, teamId }) {
708
554
  const [token, setToken] = (0, import_react.useState)(null);
709
555
  const [config, setConfig] = (0, import_react.useState)(null);
710
- const [created, setCreated] = (0, import_react.useState)(null);
711
556
  const [copied, setCopied] = (0, import_react.useState)(false);
712
- const [slow, setSlow] = (0, import_react.useState)(false);
713
557
  const [error, setError] = (0, import_react.useState)(null);
714
558
  const [configError, setConfigError] = (0, import_react.useState)(false);
715
- const pollRef = (0, import_react.useRef)(null);
716
- const onCreatedRef = (0, import_react.useRef)(onCreated);
717
- onCreatedRef.current = onCreated;
718
559
  const origin = typeof window !== "undefined" ? window.location.origin : "";
719
- const instruction = instructionFor(origin);
720
- const configLines = token && config ? [
721
- `server-url: ${origin}`,
722
- `connect-key: ${token}`,
723
- ...config?.customCli ? [`pievo-cli: ${config.pievoCli}`] : []
724
- ].join("\n") : "";
725
- const snippet = token && config ? [
726
- instruction,
727
- "",
728
- configLines
729
- ].join("\n") : "";
560
+ const command = token && config ? daemonConnectCommand(origin, token, config.pievoCli, config.customCli) : "";
730
561
  (0, import_react.useEffect)(() => {
731
562
  if (!open) return;
732
563
  setToken(null);
733
564
  setConfig(null);
734
- setCreated(null);
565
+ setCopied(false);
735
566
  setError(null);
736
567
  setConfigError(false);
737
- setCopied(false);
738
- setSlow(false);
739
568
  }, [open]);
740
569
  (0, import_react.useEffect)(() => {
741
570
  if (!open) return;
@@ -745,8 +574,10 @@ function ComposeModal({ open, onClose, onCreated, teamId }) {
745
574
  }).catch(() => {
746
575
  if (active) setConfigError(true);
747
576
  });
748
- mintClaim({ data: teamId }).then((r) => {
749
- if (active) "token" in r ? setToken(r.token) : setError(r.error);
577
+ mintClaim({ data: teamId }).then((result) => {
578
+ if (!active) return;
579
+ if ("token" in result) setToken(result.token);
580
+ else setError(result.error);
750
581
  }).catch(() => {
751
582
  if (active) setError("could not mint a connect key");
752
583
  });
@@ -754,119 +585,15 @@ function ComposeModal({ open, onClose, onCreated, teamId }) {
754
585
  active = false;
755
586
  };
756
587
  }, [open, teamId]);
757
- (0, import_react.useEffect)(() => {
758
- if (!open || created || !token) return;
759
- if (pollRef.current) clearInterval(pollRef.current);
760
- pollRef.current = setInterval(() => {
761
- claimStatus({ data: token }).then((s) => {
762
- if (s.done) {
763
- if (!s.id || !s.name || !s.agent) throw new Error("invalid claim response");
764
- if (pollRef.current) clearInterval(pollRef.current);
765
- setCreated({
766
- id: s.id,
767
- name: s.name,
768
- agent: s.agent
769
- });
770
- onCreatedRef.current();
771
- }
772
- }).catch(() => {});
773
- }, 2500);
774
- const slowTimer = setTimeout(() => setSlow(true), SLOW_WAIT_MS);
775
- return () => {
776
- if (pollRef.current) clearInterval(pollRef.current);
777
- clearTimeout(slowTimer);
778
- };
779
- }, [
780
- open,
781
- created,
782
- token
783
- ]);
784
- async function copy() {
588
+ async function copyCommand() {
785
589
  try {
786
- await navigator.clipboard.writeText(snippet);
590
+ await navigator.clipboard.writeText(command);
787
591
  setCopied(true);
788
592
  setTimeout(() => setCopied(false), 1500);
789
593
  } catch {
790
- setError("could not copy - select the text and copy manually");
594
+ setError("could not copy - select the command and copy manually");
791
595
  }
792
596
  }
793
- const snippetBox = (showInlineCopy = true) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
794
- className: "min-w-0 flex-1",
795
- children: [
796
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
797
- className: "flex items-center justify-between gap-3",
798
- children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h3", {
799
- className: "text-label font-semibold text-display",
800
- children: "Paste to capture it"
801
- }), showInlineCopy && snippet && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", {
802
- className: btnSm,
803
- onClick: () => void copy(),
804
- children: copied ? "✓ Copied" : "Copy"
805
- })]
806
- }),
807
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
808
- className: "mt-2 overflow-hidden rounded-control border border-hairline bg-raised p-3 font-mono text-label text-primary",
809
- children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
810
- className: "leading-relaxed",
811
- children: instruction
812
- }), configLines ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("pre", {
813
- className: "mt-3 overflow-x-auto whitespace-pre-wrap border-t border-hairline pt-3 leading-relaxed text-secondary",
814
- children: configLines
815
- }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
816
- className: "mt-3 border-t border-hairline pt-3 leading-relaxed text-secondary",
817
- children: configError ? "Could not load the CLI configuration. Close and try again." : token ? "Loading CLI configuration…" : "Minting a connect key…"
818
- })]
819
- }),
820
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
821
- className: "mt-2 text-body leading-snug text-secondary",
822
- children: "Paste it in that same session - reuses this machine automatically. Your agent will ask what the loop should do."
823
- })
824
- ]
825
- });
826
- const wait = slow ? {
827
- dot: "bg-secondary",
828
- text: "Still waiting - check your coding agent is running in the right project, then paste again."
829
- } : {
830
- dot: "animate-pulse bg-rubik-orange",
831
- text: "Waiting for your coding agent…"
832
- };
833
- const copyPromptButton = /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("button", {
834
- className: `${btnPrimaryPill} ml-auto`,
835
- onClick: () => void copy(),
836
- disabled: !snippet,
837
- children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", {
838
- className: "inline-flex items-center gap-0.5",
839
- children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(ClaudeCodeMark, {}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(CodexMark, {})]
840
- }), copied ? "✓ Copied" : "Copy prompt"]
841
- });
842
- if (created) return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Modal, {
843
- open,
844
- onClose,
845
- children: [
846
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ModalHead, {
847
- title: "Loop created",
848
- sub: `Configured to run with ${AGENT_LABEL[created.agent]}.`
849
- }),
850
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
851
- className: "mt-5 rounded-card border border-hairline bg-surface p-5 shadow-card",
852
- children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
853
- className: "text-[17px] font-medium text-display",
854
- children: ["✓ ", created.name]
855
- }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
856
- className: "mt-1 text-body text-secondary",
857
- children: "It’s scheduled now and will run on the machine."
858
- })]
859
- }),
860
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
861
- className: "mt-4",
862
- children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", {
863
- className: btnPrimary,
864
- onClick: onClose,
865
- children: "Done"
866
- })
867
- })
868
- ]
869
- });
870
597
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Modal, {
871
598
  open,
872
599
  onClose,
@@ -874,50 +601,62 @@ function ComposeModal({ open, onClose, onCreated, teamId }) {
874
601
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ModalHead, { title: "New loop" }),
875
602
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
876
603
  className: "mt-6",
877
- children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
878
- className: "flex gap-3.5",
879
- children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
880
- className: "flex flex-col items-center",
881
- children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
882
- className: "flex size-5 shrink-0 items-center justify-center rounded-full border border-display text-micro font-medium leading-none text-display",
883
- children: "1"
884
- }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "mt-1 w-px flex-1 bg-hairline" })]
604
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Step, {
605
+ number: "1",
606
+ continued: true,
607
+ title: "Install and connect the daemon",
608
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
609
+ className: "mt-1.5 text-body leading-snug text-secondary",
610
+ children: "Paste this command into the foreground coding-agent session where the loop should run."
885
611
  }), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
886
- className: "pb-6",
887
- children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h3", {
888
- className: "text-label font-semibold text-display",
889
- children: "Do it once in your coding agent"
890
- }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
891
- className: "mt-1.5 text-body leading-snug text-secondary",
892
- children: "Run the task yourself first, to a real result you’re happy with."
612
+ className: "mt-3 flex min-w-0 items-start gap-2",
613
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("pre", {
614
+ className: "min-w-0 flex-1 overflow-x-auto whitespace-pre-wrap break-all rounded-control bg-display p-4 font-mono text-label leading-relaxed text-paper",
615
+ children: command || (configError ? "Could not load the connection command. Close and try again." : token ? "Loading CLI configuration…" : "Minting a connect key…")
616
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", {
617
+ className: btnSm,
618
+ onClick: () => void copyCommand(),
619
+ disabled: !command,
620
+ children: copied ? "Copied ✓" : "Copy"
893
621
  })]
894
622
  })]
895
- }), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
896
- className: "flex gap-3.5",
897
- children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
898
- className: "flex size-5 shrink-0 items-center justify-center rounded-full border border-display text-micro font-medium leading-none text-display",
899
- children: "2"
900
- }), snippetBox(false)]
623
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Step, {
624
+ number: "2",
625
+ title: "Create the loop",
626
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
627
+ className: "mt-1.5 text-body leading-snug text-secondary",
628
+ children: "Then, in the same session, say:"
629
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
630
+ className: "mt-3 rounded-control border border-hairline bg-raised p-4 text-body font-medium text-display",
631
+ children: "Create a Pievo loop."
632
+ })]
901
633
  })]
902
634
  }),
903
635
  error && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
904
- className: "mt-3 text-body text-accent",
636
+ className: "mt-4 text-body text-accent",
905
637
  children: ["Error: ", error]
906
- }),
907
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
908
- className: "mt-6 flex items-start gap-3",
909
- children: [
910
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: `mt-1 inline-block h-2 w-2 shrink-0 rounded-full ${wait.dot}` }),
911
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
912
- className: "text-label leading-relaxed text-secondary",
913
- children: wait.text
914
- }),
915
- copyPromptButton
916
- ]
917
638
  })
918
639
  ]
919
640
  });
920
641
  }
642
+ function Step({ number, title, continued = false, children }) {
643
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
644
+ className: "flex gap-3.5",
645
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
646
+ className: "flex flex-col items-center",
647
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
648
+ className: "flex size-5 shrink-0 items-center justify-center rounded-full border border-display text-micro font-medium leading-none text-display",
649
+ children: number
650
+ }), continued && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "mt-1 w-px flex-1 bg-hairline" })]
651
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
652
+ className: continued ? "min-w-0 flex-1 pb-7" : "min-w-0 flex-1",
653
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h3", {
654
+ className: "text-label font-semibold text-display",
655
+ children: title
656
+ }), children]
657
+ })]
658
+ });
659
+ }
921
660
  /** Loops, machines, and teams change between polls.
922
661
  *
923
662
  * `teamId` (the `/t/<id>` route's team, in id form or undefined in open mode)
@@ -964,7 +703,6 @@ function DashboardView({ teamId, initial }) {
964
703
  }, anyRunning ? 3e3 : 1e4);
965
704
  return () => clearInterval(t);
966
705
  }, [refetch, anyRunning]);
967
- const refresh = () => void refetch();
968
706
  const activeOn = loops.filter((j) => j.enabled).length;
969
707
  const cardProps = () => ({
970
708
  onOpen: (id) => void navigate({
@@ -1051,7 +789,7 @@ function DashboardView({ teamId, initial }) {
1051
789
  className: "mb-5 mt-12 flex items-baseline gap-2.5",
1052
790
  children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h2", {
1053
791
  className: "text-body font-semibold text-display",
1054
- children: "Active loops"
792
+ children: "Loops"
1055
793
  }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
1056
794
  className: "text-label text-secondary",
1057
795
  children: loops.length ? `${activeOn} scheduled · ${loops.length} total` : ""
@@ -1076,8 +814,7 @@ function DashboardView({ teamId, initial }) {
1076
814
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ComposeModal, {
1077
815
  open: composeOpen,
1078
816
  teamId,
1079
- onClose: () => setComposeOpen(false),
1080
- onCreated: refresh
817
+ onClose: () => setComposeOpen(false)
1081
818
  }),
1082
819
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(MachinesModal, {
1083
820
  open: machinesOpen,