@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,16 +1,16 @@
1
1
  import { j as sql } from "../_libs/drizzle-orm+postgres.mjs";
2
- import { A as ensureServer, Dt as readJsonBody, Et as readByteBody, Yt as validOptionalPollString, l as MACHINE_BODY_CAP } from "./boot-BbWxaF-z.mjs";
2
+ import { Dt as readByteBody, Ot as readJsonBody, Qt as validPollWireId, Xt as validOptionalPollString, Zt as validPollCurrentRun, d as POLL_HTTP_BODY_FIELDS, j as ensureServer, l as MACHINE_BODY_CAP } from "./boot-sNlIkoLe.mjs";
3
3
  import { h as require_jsx_runtime } from "../_libs/@base-ui/react+[...].mjs";
4
4
  import { c as createFileRoute, i as HeadContent, l as createRootRoute, o as createRouter, r as Scripts } from "../_libs/@tanstack/react-router+[...].mjs";
5
- import { t as Route$14 } from "./invite._token-BliJIGk4.mjs";
6
- import { r as imageMime, t as Route$15 } from "./artifactKind-ByzVa7fg.mjs";
7
- import { t as Route$16 } from "./loops._loopId_.runs._runId-a_SyY8rX.mjs";
8
- import { t as Route$17 } from "./routes-CRHc9cLG.mjs";
9
- import { t as Route$18 } from "./t._teamId-QD2nN0wn.mjs";
10
- //#region node_modules/.nitro/vite/services/ssr/assets/router-lMkobh5r.js
5
+ import { t as Route$12 } from "./invite._token-CHR5K84a.mjs";
6
+ import { r as imageMime, t as Route$13 } from "./artifactKind-CwQ_Ddj6.mjs";
7
+ import { t as Route$14 } from "./loops._loopId_.runs._runId-B4jXeonc.mjs";
8
+ import { t as Route$15 } from "./routes-DqIGr7p0.mjs";
9
+ import { t as Route$16 } from "./t._teamId-xFPYdSPu.mjs";
10
+ //#region node_modules/.nitro/vite/services/ssr/assets/router-DyhWcIzt.js
11
11
  var import_jsx_runtime = require_jsx_runtime();
12
- var app_default = "/assets/app-BAgHQVvr.css";
13
- var Route$13 = createRootRoute({
12
+ var app_default = "/assets/app-CuZ0I3Mb.css";
13
+ var Route$11 = createRootRoute({
14
14
  head: () => ({
15
15
  meta: [
16
16
  { charSet: "utf-8" },
@@ -164,7 +164,7 @@ function machineRouteLimit(request, token, opts = {}) {
164
164
  return null;
165
165
  }
166
166
  /** POST /machine/report — finalize a run (Bearer run token). */
167
- var Route$12 = createFileRoute("/machine/report")({ server: { handlers: { POST: async ({ request }) => {
167
+ var Route$10 = createFileRoute("/machine/report")({ server: { handlers: { POST: async ({ request }) => {
168
168
  const auth = request.headers.get("authorization") ?? "";
169
169
  const token = auth.startsWith("Bearer ") ? auth.slice(7) : "";
170
170
  const limited = machineRouteLimit(request, token || void 0);
@@ -173,7 +173,7 @@ var Route$12 = createFileRoute("/machine/report")({ server: { handlers: { POST:
173
173
  const parsed = await readJsonBody(request, MACHINE_BODY_CAP);
174
174
  if (parsed.kind === "too-large") return Response.json({ error: "body too large" }, { status: 413 });
175
175
  const body = parsed.kind === "ok" && parsed.body && typeof parsed.body === "object" ? parsed.body : {};
176
- const { getGateway } = await import("./boot-COHf8Gv3.mjs");
176
+ const { getGateway } = await import("./boot-CdOO4xOo.mjs");
177
177
  const r = await (await getGateway()).report(token, body);
178
178
  return Response.json(r.body, { status: r.status });
179
179
  } } } });
@@ -190,20 +190,14 @@ async function readyResponse(ensure = ensureServer, env = process.env) {
190
190
  nonce: env.PIEVO_SERVER_LAUNCH_NONCE ?? null
191
191
  });
192
192
  }
193
- var Route$11 = createFileRoute("/api/ready")({ server: { handlers: { GET: () => readyResponse() } } });
193
+ var Route$9 = createFileRoute("/api/ready")({ server: { handlers: { GET: () => readyResponse() } } });
194
194
  var buildSha = () => process.env.GIT_SHA || "unknown";
195
195
  var buildAt = () => process.env.BUILT_AT || "unknown";
196
- var Route$10 = createFileRoute("/api/health")({ server: { handlers: { GET: async () => Response.json({
196
+ var Route$8 = createFileRoute("/api/health")({ server: { handlers: { GET: async () => Response.json({
197
197
  ok: true,
198
198
  sha: buildSha(),
199
199
  builtAt: buildAt()
200
200
  }) } } });
201
- var bootstrap_default = "# Pievo — connect this machine and create a scheduled prompt\n\nYou're reading this because the user pasted a Pievo capture snippet (`Fetch\n<server-url>/api/bootstrap and help me build a loop.`). Their Pievo web tab is waiting\nfor the machine and new loop. Work end to end, with short confirmations rather than a\nlong interview.\n\n## Pasted values\n\nUse these values exactly as supplied:\n\n- **server-url** — the Pievo server base URL.\n- **connect-key** — the one-time machine connection and web-dialog claim.\n- **pievo-cli** *(optional)* — the command prefix for every Pievo invocation. If it is\n absent, use `pievo` after installing the current package.\n- An optional task description below the values — the requested scheduled prompt.\n\n## 1 · Connect\n\nFetch and follow the connection reference:\n\n```text\n<server-url>/api/skill/references/connect.md\n```\n\nPass the pasted `server-url` and `connect-key` to its daemon start command. Do not\nreplace a supplied custom `pievo-cli` prefix.\n\n## 2 · Create\n\nAfter the daemon reports the machine online, fetch and follow:\n\n```text\n<server-url>/api/skill/references/create.md\n```\n\nThe create reference owns the remaining flow: identify the concrete prompt, confirm\nits exclusive cron or continuous schedule and three status definitions, choose the\nworking directory and coding agent, optionally select exact artifact files, preview the\ncanonical JSON, and run `pievo new`. On this first-capture path, pass the same\n`connect-key` to `pievo new` so the created loop appears in the waiting web dialog.\n\nPievo is a scheduled prompt runner. Configure only the fields listed in the create\nreference. The stored user prompt is delivered unchanged, followed only by Pievo's\ncomplete status/report contract.\n";
202
- /** GET /api/bootstrap — the first-capture bootstrap doc Claude Code follows (see ComposeModal). */
203
- var Route$9 = createFileRoute("/api/bootstrap")({ server: { handlers: { GET: () => new Response(bootstrap_default, { headers: {
204
- "content-type": "text/markdown; charset=utf-8",
205
- "cache-control": "no-cache"
206
- } }) } } });
207
201
  /**
208
202
  * POST /api/machine/sync — exact artifact sync (Bearer DEVICE token). The daemon
209
203
  * posts the complete configured-path manifest after a run; the server reconciles
@@ -215,53 +209,41 @@ var Route$9 = createFileRoute("/api/bootstrap")({ server: { handlers: { GET: ()
215
209
  * already bounded by the exact-path/hash handshake and 32MB sync-body cap, so a
216
210
  * limiter would only throttle a legitimate large sync.
217
211
  */
218
- var Route$8 = createFileRoute("/api/machine/sync")({ server: { handlers: { POST: async ({ request }) => {
212
+ var Route$7 = createFileRoute("/api/machine/sync")({ server: { handlers: { POST: async ({ request }) => {
219
213
  const auth = request.headers.get("authorization") ?? "";
220
214
  const token = auth.startsWith("Bearer ") ? auth.slice(7) : "";
221
215
  if (!token) return Response.json({ error: "missing device token" }, { status: 401 });
222
- const { SYNC_BODY_CAP, parseArtifactSyncBody } = await import("./artifacts-BhQvaGjF.mjs");
216
+ const { SYNC_BODY_CAP, parseArtifactSyncBody } = await import("./artifacts-BR3jj0NC.mjs");
223
217
  const parsed = await readJsonBody(request, SYNC_BODY_CAP);
224
218
  if (parsed.kind === "too-large") return Response.json({ error: "sync body too large" }, { status: 413 });
225
219
  if (parsed.kind === "invalid") return Response.json({ error: "invalid JSON" }, { status: 400 });
226
220
  const body = parseArtifactSyncBody(parsed.body);
227
221
  if (!body) return Response.json({ error: "invalid sync body" }, { status: 400 });
228
- const { getArtifactSync } = await import("./boot-COHf8Gv3.mjs");
222
+ const { getArtifactSync } = await import("./boot-CdOO4xOo.mjs");
229
223
  const r = await (await getArtifactSync()).sync(token, body);
230
224
  return Response.json(r.body, { status: r.status });
231
225
  } } } });
232
226
  /** GET /api/machine/status — is this machine's daemon live? (Bearer device token) */
233
- var Route$7 = createFileRoute("/api/machine/status")({ server: { handlers: { GET: async ({ request }) => {
227
+ var Route$6 = createFileRoute("/api/machine/status")({ server: { handlers: { GET: async ({ request }) => {
234
228
  const auth = request.headers.get("authorization") ?? "";
235
229
  const token = auth.startsWith("Bearer ") ? auth.slice(7) : "";
236
230
  const limited = machineRouteLimit(request, token || void 0);
237
231
  if (limited) return limited;
238
232
  if (!token) return Response.json({ error: "missing device token" }, { status: 401 });
239
- const { getGateway } = await import("./boot-COHf8Gv3.mjs");
233
+ const { getGateway } = await import("./boot-CdOO4xOo.mjs");
240
234
  const r = await (await getGateway()).status(token);
241
235
  return Response.json(r.body, { status: r.status });
242
236
  } } } });
243
- var POLL_BODY_FIELDS = new Set([
244
- "host",
245
- "platform",
246
- "arch",
247
- "version",
248
- "protocolVersion",
249
- "currentRuns",
250
- "daemonInstanceId",
251
- "recoveryComplete"
252
- ]);
253
- var validWireId = (value) => typeof value === "string" && value.length <= 200 && value.trim().length > 0 && !value.includes("\0");
254
- var validCurrentRun = (value) => value !== null && typeof value === "object" && !Array.isArray(value) && Object.keys(value).length === 2 && Object.prototype.hasOwnProperty.call(value, "runId") && Object.prototype.hasOwnProperty.call(value, "stage") && validWireId(value.runId) && (value.stage === "executing" || value.stage === "reporting");
255
237
  /** Reject non-object bodies, additions, coercible types, over-cap strings, and
256
238
  * NUL-bearing text before the gateway is loaded or any state can mutate. */
257
239
  function parsePollBody(value) {
258
240
  if (value === null || typeof value !== "object" || Array.isArray(value)) return null;
259
- if (Object.keys(value).some((key) => !POLL_BODY_FIELDS.has(key))) return null;
241
+ if (Object.keys(value).some((key) => !POLL_HTTP_BODY_FIELDS.has(key))) return null;
260
242
  const body = value;
261
243
  if (!validOptionalPollString(body.host, 524288) || !validOptionalPollString(body.platform, 524288) || !validOptionalPollString(body.arch, 524288) || !validOptionalPollString(body.version, 64)) return null;
262
244
  if (body.protocolVersion !== void 0 && (typeof body.protocolVersion !== "number" || !Number.isInteger(body.protocolVersion))) return null;
263
- if (body.currentRuns !== void 0 && (!Array.isArray(body.currentRuns) || body.currentRuns.some((run) => !validCurrentRun(run)))) return null;
264
- if (body.daemonInstanceId !== void 0 && !validWireId(body.daemonInstanceId)) return null;
245
+ if (body.currentRuns !== void 0 && (!Array.isArray(body.currentRuns) || body.currentRuns.some((run) => !validPollCurrentRun(run)))) return null;
246
+ if (body.daemonInstanceId !== void 0 && !validPollWireId(body.daemonInstanceId)) return null;
265
247
  if (body.recoveryComplete !== void 0 && typeof body.recoveryComplete !== "boolean") return null;
266
248
  return body;
267
249
  }
@@ -281,7 +263,7 @@ function gatewayPollRequest(body) {
281
263
  };
282
264
  }
283
265
  /** POST /api/machine/poll — daemon claims this machine's pending runs (Bearer device token). */
284
- var Route$6 = createFileRoute("/api/machine/poll")({ server: { handlers: { POST: async ({ request }) => {
266
+ var Route$5 = createFileRoute("/api/machine/poll")({ server: { handlers: { POST: async ({ request }) => {
285
267
  const auth = request.headers.get("authorization") ?? "";
286
268
  const token = auth.startsWith("Bearer ") ? auth.slice(7) : "";
287
269
  const limited = machineRouteLimit(request, token || void 0);
@@ -292,7 +274,7 @@ var Route$6 = createFileRoute("/api/machine/poll")({ server: { handlers: { POST:
292
274
  if (parsed.kind !== "ok") return Response.json({ error: "invalid JSON body" }, { status: 400 });
293
275
  const body = parsePollBody(parsed.body);
294
276
  if (!body) return Response.json({ error: "unknown or invalid poll body fields" }, { status: 400 });
295
- const { getGateway } = await import("./boot-COHf8Gv3.mjs");
277
+ const { getGateway } = await import("./boot-CdOO4xOo.mjs");
296
278
  const r = await (await getGateway()).pollV4Wait(token, gatewayPollRequest(body));
297
279
  return Response.json(r.body, { status: r.status });
298
280
  } } } });
@@ -309,7 +291,7 @@ function parseCliBody(value) {
309
291
  * commands, while an `rk_` run credential can only report its run. Uses the standard
310
292
  * 2MB machine JSON body cap.
311
293
  */
312
- var Route$5 = createFileRoute("/api/machine/cli")({ server: { handlers: { POST: async ({ request }) => {
294
+ var Route$4 = createFileRoute("/api/machine/cli")({ server: { handlers: { POST: async ({ request }) => {
313
295
  const auth = request.headers.get("authorization") ?? "";
314
296
  const token = auth.startsWith("Bearer ") ? auth.slice(7) : "";
315
297
  const limited = machineRouteLimit(request, token || void 0);
@@ -319,7 +301,7 @@ var Route$5 = createFileRoute("/api/machine/cli")({ server: { handlers: { POST:
319
301
  if (parsed.kind === "too-large") return Response.json({ error: "body too large" }, { status: 413 });
320
302
  const body = parsed.kind === "ok" ? parseCliBody(parsed.body) : null;
321
303
  if (!body) return Response.json({ error: "body must be exactly {argv:string[]}" }, { status: 400 });
322
- const { getCliGateway } = await import("./boot-COHf8Gv3.mjs");
304
+ const { getCliGateway } = await import("./boot-CdOO4xOo.mjs");
323
305
  const r = await (await getCliGateway()).cli(token, body.argv);
324
306
  return Response.json(r.body, { status: r.status });
325
307
  } } } });
@@ -346,9 +328,9 @@ var Route$5 = createFileRoute("/api/machine/cli")({ server: { handlers: { POST:
346
328
  * Drizzle imported inside the handler so it stays out of the client bundle.
347
329
  */
348
330
  var PROBE_TIMEOUT_MS = 5e3;
349
- var Route$4 = createFileRoute("/api/health/db")({ server: { handlers: { GET: async () => {
331
+ var Route$3 = createFileRoute("/api/health/db")({ server: { handlers: { GET: async () => {
350
332
  try {
351
- const { db } = await import("./db-dw61xIt1.mjs");
333
+ const { db } = await import("./db-CwLD-5w1.mjs");
352
334
  const ping = db.execute(sql`select 1`);
353
335
  const timeout = new Promise((_, reject) => {
354
336
  setTimeout(() => reject(/* @__PURE__ */ new Error(`db ping timed out after ${PROBE_TIMEOUT_MS}ms`)), PROBE_TIMEOUT_MS).unref?.();
@@ -367,33 +349,10 @@ var Route$4 = createFileRoute("/api/health/db")({ server: { handlers: { GET: asy
367
349
  }
368
350
  } } } });
369
351
  /** Better Auth handler — GET/POST /api/auth/* (OAuth callbacks, session, sign-out). */
370
- var Route$3 = createFileRoute("/api/auth/$")({ server: { handlers: {
371
- GET: async ({ request }) => (await import("./auth-CPCDf6Wr.mjs")).auth.handler(request),
372
- POST: async ({ request }) => (await import("./auth-CPCDf6Wr.mjs")).auth.handler(request)
352
+ var Route$2 = createFileRoute("/api/auth/$")({ server: { handlers: {
353
+ GET: async ({ request }) => (await import("./auth-C0zoZCGe.mjs")).auth.handler(request),
354
+ POST: async ({ request }) => (await import("./auth-C0zoZCGe.mjs")).auth.handler(request)
373
355
  } } });
374
- var REFERENCES = {
375
- "connect.md": "# Connect a machine\n\nUse the **pievo-cli** command prefix supplied by the user; otherwise use `pievo`.\nA first-capture snippet supplies a **server-url** and one-time **connect-key**. Use\nboth verbatim.\n\nIf no custom command prefix was supplied, install the current CLI:\n\n```bash\nnpm install -g @kky42/pievo@latest\n```\n\nStart the daemon:\n\n```bash\n<pievo-cli> daemon start --server-url <server-url> --connect-key <connect-key>\n```\n\nThe command is idempotent: it reuses this machine's identity, starts one detached\ndaemon if needed, and waits for the server to see it online. It exits successfully\nwith `daemon online …` or `daemon already running …`. If it cannot connect, follow\nthe printed log path rather than guessing credentials or server settings.\n\nOnce connected, continue with `create.md` when the user wants a new loop. Existing\nconnections normally need no server URL or key on later `pievo` commands.\n",
376
- "create.md": "# Create a loop\n\nA Pievo loop runs one server-stored prompt with one selected coding agent in a fixed\nworking directory. Use the **pievo-cli** prefix supplied by the user (default `pievo`).\nIf this machine is not connected, follow `connect.md` first.\n\n## 1 · Identify the prompt\n\nStart from concrete evidence in the current session:\n\n- If the user just completed or described a recurring task, turn that task into a\n standalone prompt grounded in its real paths, commands, URLs, constraints, and\n expected result.\n- If there is no task yet, inspect the project, propose a few useful scheduled prompts,\n and let the user choose. Do not invent and create one silently.\n\nThe stored `prompt` is sent unchanged. Make it self-contained for a fresh coding-agent\nprocess, but do not add Pievo runtime instructions: the server appends the complete\nstatus definitions and required `pievo report` command.\n\n## 2 · Confirm schedule and outcomes\n\nBefore creating, propose any missing choices in one short message and get confirmation:\n\n- **Schedule:** use cron for wall-clock work or continuous for a fixed delay after the\n prior run finishes. For cron, confirm the timezone and whether an occurrence while a\n run is still open should `skip` or `queue-one` coalesced follow-up. Continuous never\n overlaps.\n- **Statuses:** define what `keep`, `no-change`, and `block` mean for this task. All\n three definitions are required and must be non-empty. `block` means owner attention\n is required and pauses the loop.\n- **Artifacts:** if the user wants files visible in Pievo, list exact paths relative to\n `workdir`. Use stable filenames. Globs, absolute paths, traversal, and directories\n are not supported. Missing or unreadable files do not fail a run.\n\n## 3 · Author the canonical config\n\nCron example:\n\n```json\n{\n \"name\": \"Daily dependency check\",\n \"schedule\": {\n \"mode\": \"cron\",\n \"cron\": \"0 9 * * *\",\n \"timezone\": \"America/Los_Angeles\",\n \"overlap\": \"skip\"\n },\n \"workdir\": \"/absolute/path/to/project\",\n \"agent\": \"claude-code\",\n \"model\": null,\n \"reasoningEffort\": null,\n \"prompt\": \"Inspect the repository's open dependency updates. Verify each update against its exact diff and current checks, then write any safe action or reason to defer it to dependency-check.md.\",\n \"statusDefinitions\": {\n \"keep\": \"A verified action or useful finding was produced.\",\n \"noChange\": \"The check completed and found no actionable change.\",\n \"block\": \"Owner input or unavailable access prevents a safe decision.\"\n },\n \"artifacts\": [\"dependency-check.md\"],\n \"enabled\": true\n}\n```\n\nContinuous schedule shape:\n\n```json\n{\n \"mode\": \"continuous\",\n \"delayMinutes\": 30\n}\n```\n\nRules:\n\n- Required: `name`, `schedule`, absolute `workdir`, `agent`, non-empty `prompt`, and\n all three `statusDefinitions`.\n- `agent` is `claude-code` or `codex`.\n- `model` and `reasoningEffort` are optional strings. Omit them or use `null` to let\n the selected coding-agent CLI use its default.\n- `artifacts` is optional and contains only exact workdir-relative file paths.\n- `enabled` is optional and defaults to `true`.\n- Cron and continuous are exclusive shapes. Do not mix their fields.\n\n## 4 · Validate, then create\n\nPreview the exact config first:\n\n```bash\n<pievo-cli> new --json '<config>' --dry-run\n```\n\nFix every rejection. Then create it:\n\n```bash\n<pievo-cli> new --json '<config>'\n```\n\nOn a first-capture flow, include the pasted claim so the web dialog resolves:\n\n```bash\n<pievo-cli> new --json '<config>' --connect-key <connect-key>\n```\n\nOn success, tell the user the loop name, schedule, working directory, selected agent,\nand whether any artifact files were configured.\n",
377
- "update.md": "# Edit an existing loop\n\nUse the same **pievo-cli** prefix used to connect the machine (default `pievo`). The\nmachine's persisted device credential authorizes edits to loops bound to it.\n\nFind the loop and inspect its current editable envelope:\n\n```bash\n<pievo-cli> loops\n<pievo-cli> show <loop-id> --json\n```\n\nPatch only the requested fields with one JSON object. Preview before applying:\n\n```bash\n<pievo-cli> edit <loop-id> --json '<patch>' --dry-run\n<pievo-cli> edit <loop-id> --json '<patch>'\n```\n\nAccepted fields are:\n\n| field | value |\n|---|---|\n| `name` | non-empty string |\n| `schedule` | complete cron or continuous schedule object |\n| `workdir` | absolute working-directory path |\n| `agent` | `claude-code` or `codex` |\n| `model` | string or `null` for provider default |\n| `reasoningEffort` | string or `null` for provider default |\n| `prompt` | non-empty string, preserved as written |\n| `statusDefinitions` | complete `{keep,noChange,block}` object with non-empty strings |\n| `artifacts` | array of exact paths relative to `workdir` |\n| `enabled` | boolean |\n\nSchedule examples:\n\n```bash\n<pievo-cli> edit <loop-id> --json '{\"schedule\":{\"mode\":\"cron\",\"cron\":\"0 9 * * 1-5\",\"timezone\":\"Europe/London\",\"overlap\":\"queue-one\"}}'\n<pievo-cli> edit <loop-id> --json '{\"schedule\":{\"mode\":\"continuous\",\"delayMinutes\":15}}'\n```\n\nOther examples:\n\n```bash\n<pievo-cli> edit <loop-id> --json '{\"prompt\":\"Run the verified release check and summarize only actionable findings.\"}'\n<pievo-cli> edit <loop-id> --json '{\"statusDefinitions\":{\"keep\":\"A verified action was completed.\",\"noChange\":\"The check completed with nothing actionable.\",\"block\":\"Owner input is required.\"}}'\n<pievo-cli> edit <loop-id> --json '{\"artifacts\":[\"release-check.md\"]}'\n<pievo-cli> edit <loop-id> --json '{\"model\":null,\"reasoningEffort\":null}'\n```\n\nImportant constraints:\n\n- Replacing `schedule` requires one complete exclusive shape. Cron requires `cron`,\n `timezone`, and `overlap`; continuous requires only `delayMinutes`.\n- Replacing `statusDefinitions` requires all three definitions.\n- Artifact entries are exact stable file paths, not globs. They must be relative to\n `workdir` and cannot traverse outside it.\n- The server validates every field and rejects unknown keys without mutating the loop.\n- Pievo appends the runtime report contract to `prompt`; do not duplicate it in the\n stored prompt.\n\nRun once is intentionally a Web action: use **Run once** on the loop detail page.\nFor Pause, Start, Stop, Delete, and history, use `<pievo-cli> --help` and the\nrelevant command's `--help` instead of treating lifecycle operations as\nprompt-authoring fields.\n"
378
- };
379
- var PREFIX$1 = "/api/skill/references/";
380
- /**
381
- * GET /api/skill/references/:file — serve one pievo skill reference file. Path-safe:
382
- * only an exact, single-segment name from the static REFERENCES map resolves; anything
383
- * else (nested paths, traversal, unknown names) is 404. The server only reads bytes it
384
- * shipped — no filesystem access, no user input reaches disk (zero-exec invariant holds).
385
- */
386
- var Route$2 = createFileRoute("/api/skill/references/$")({ server: { handlers: { GET: ({ request }) => {
387
- const pathname = new URL(request.url).pathname;
388
- if (!pathname.startsWith(PREFIX$1)) return Response.json({ error: "not found" }, { status: 404 });
389
- const name = pathname.slice(22);
390
- const body = Object.prototype.hasOwnProperty.call(REFERENCES, name) ? REFERENCES[name] : void 0;
391
- if (body === void 0) return Response.json({ error: "not found" }, { status: 404 });
392
- return new Response(body, { headers: {
393
- "content-type": "text/markdown; charset=utf-8",
394
- "cache-control": "no-cache"
395
- } });
396
- } } } });
397
356
  /**
398
357
  * `decodeURIComponent` that returns null on malformed percent-encoding instead
399
358
  * of throwing a URIError (which would escape a route handler as a 500). Shared
@@ -426,12 +385,12 @@ var Route$1 = createFileRoute("/api/machine/blob/$hash")({ server: { handlers: {
426
385
  if (!token) return Response.json({ error: "missing device token" }, { status: 401 });
427
386
  const hash = safeDecode(new URL(request.url).pathname.split("/").pop() ?? "");
428
387
  if (hash === null) return Response.json({ error: "bad hash" }, { status: 400 });
429
- const { BLOB_CAP } = await import("./artifacts-BhQvaGjF.mjs");
388
+ const { BLOB_CAP } = await import("./artifacts-BR3jj0NC.mjs");
430
389
  const body = await readByteBody(request, BLOB_CAP);
431
390
  if (body.kind === "too-large") return Response.json({ error: "blob exceeds size cap" }, { status: 413 });
432
391
  if (body.kind === "invalid") return Response.json({ error: "could not read blob body" }, { status: 400 });
433
392
  const buf = Buffer.from(body.bytes.buffer, body.bytes.byteOffset, body.bytes.byteLength);
434
- const { getArtifactSync } = await import("./boot-COHf8Gv3.mjs");
393
+ const { getArtifactSync } = await import("./boot-CdOO4xOo.mjs");
435
394
  const r = await (await getArtifactSync()).putBlob(token, hash, buf);
436
395
  return Response.json(r.body, { status: r.status });
437
396
  } } } });
@@ -466,11 +425,11 @@ var Route = createFileRoute("/api/artifact/$loopId/$")({ server: { handlers: { G
466
425
  const segments = after.slice(slash + 1).split("/").map((s) => safeDecode(s));
467
426
  if (segments.some((s) => s === null)) return Response.json({ error: "bad path" }, { status: 400 });
468
427
  const relPath = segments.join("/");
469
- const loop = await (await import("./store-CirPHuib.mjs")).getLoop(loopId);
428
+ const loop = await (await import("./store-Cujtg2QE.mjs")).getLoop(loopId);
470
429
  if (!loop) return Response.json({ error: "not found" }, { status: 404 });
471
- const { requestScope, canAccessLoop } = await import("./auth-CPCDf6Wr.mjs");
430
+ const { requestScope, canAccessLoop } = await import("./auth-C0zoZCGe.mjs");
472
431
  if (!await canAccessLoop(loop.teamId, await requestScope())) return Response.json({ error: "not found" }, { status: 404 });
473
- const { readLoopArtifactBytes } = await import("./artifactFiles-CV3OXxRD.mjs");
432
+ const { readLoopArtifactBytes } = await import("./artifactFiles-DHBXTtZn.mjs");
474
433
  const r = await readLoopArtifactBytes(loopId, relPath);
475
434
  if (r.status !== 200 || !r.bytes) return Response.json({ error: "not found" }, { status: r.status });
476
435
  const filename = (r.filename || "file").replace(/["\\\r\n]/g, "_");
@@ -496,100 +455,89 @@ var Route = createFileRoute("/api/artifact/$loopId/$")({ server: { handlers: { G
496
455
  }
497
456
  });
498
457
  } } } });
499
- var IndexRoute = Route$17.update({
458
+ var IndexRoute = Route$15.update({
500
459
  id: "/",
501
460
  path: "/",
502
- getParentRoute: () => Route$13
461
+ getParentRoute: () => Route$11
503
462
  });
504
- var TTeamIdRoute = Route$18.update({
463
+ var TTeamIdRoute = Route$16.update({
505
464
  id: "/t/$teamId",
506
465
  path: "/t/$teamId",
507
- getParentRoute: () => Route$13
466
+ getParentRoute: () => Route$11
508
467
  });
509
- var MachineReportRoute = Route$12.update({
468
+ var MachineReportRoute = Route$10.update({
510
469
  id: "/machine/report",
511
470
  path: "/machine/report",
512
- getParentRoute: () => Route$13
471
+ getParentRoute: () => Route$11
513
472
  });
514
- var LoopsLoopIdRoute = Route$15.update({
473
+ var LoopsLoopIdRoute = Route$13.update({
515
474
  id: "/loops/$loopId",
516
475
  path: "/loops/$loopId",
517
- getParentRoute: () => Route$13
476
+ getParentRoute: () => Route$11
518
477
  });
519
- var InviteTokenRoute = Route$14.update({
478
+ var InviteTokenRoute = Route$12.update({
520
479
  id: "/invite/$token",
521
480
  path: "/invite/$token",
522
- getParentRoute: () => Route$13
481
+ getParentRoute: () => Route$11
523
482
  });
524
- var ApiReadyRoute = Route$11.update({
483
+ var ApiReadyRoute = Route$9.update({
525
484
  id: "/api/ready",
526
485
  path: "/api/ready",
527
- getParentRoute: () => Route$13
486
+ getParentRoute: () => Route$11
528
487
  });
529
- var ApiHealthRoute = Route$10.update({
488
+ var ApiHealthRoute = Route$8.update({
530
489
  id: "/api/health",
531
490
  path: "/api/health",
532
- getParentRoute: () => Route$13
533
- });
534
- var ApiBootstrapRoute = Route$9.update({
535
- id: "/api/bootstrap",
536
- path: "/api/bootstrap",
537
- getParentRoute: () => Route$13
491
+ getParentRoute: () => Route$11
538
492
  });
539
- var ApiMachineSyncRoute = Route$8.update({
493
+ var ApiMachineSyncRoute = Route$7.update({
540
494
  id: "/api/machine/sync",
541
495
  path: "/api/machine/sync",
542
- getParentRoute: () => Route$13
496
+ getParentRoute: () => Route$11
543
497
  });
544
- var ApiMachineStatusRoute = Route$7.update({
498
+ var ApiMachineStatusRoute = Route$6.update({
545
499
  id: "/api/machine/status",
546
500
  path: "/api/machine/status",
547
- getParentRoute: () => Route$13
501
+ getParentRoute: () => Route$11
548
502
  });
549
- var ApiMachinePollRoute = Route$6.update({
503
+ var ApiMachinePollRoute = Route$5.update({
550
504
  id: "/api/machine/poll",
551
505
  path: "/api/machine/poll",
552
- getParentRoute: () => Route$13
506
+ getParentRoute: () => Route$11
553
507
  });
554
- var ApiMachineCliRoute = Route$5.update({
508
+ var ApiMachineCliRoute = Route$4.update({
555
509
  id: "/api/machine/cli",
556
510
  path: "/api/machine/cli",
557
- getParentRoute: () => Route$13
511
+ getParentRoute: () => Route$11
558
512
  });
559
- var ApiHealthDbRoute = Route$4.update({
513
+ var ApiHealthDbRoute = Route$3.update({
560
514
  id: "/db",
561
515
  path: "/db",
562
516
  getParentRoute: () => ApiHealthRoute
563
517
  });
564
- var ApiAuthSplatRoute = Route$3.update({
518
+ var ApiAuthSplatRoute = Route$2.update({
565
519
  id: "/api/auth/$",
566
520
  path: "/api/auth/$",
567
- getParentRoute: () => Route$13
521
+ getParentRoute: () => Route$11
568
522
  });
569
- var LoopsLoopIdRunsRunIdRoute = Route$16.update({
523
+ var LoopsLoopIdRunsRunIdRoute = Route$14.update({
570
524
  id: "/loops/$loopId_/runs/$runId",
571
525
  path: "/loops/$loopId/runs/$runId",
572
- getParentRoute: () => Route$13
573
- });
574
- var ApiSkillReferencesSplatRoute = Route$2.update({
575
- id: "/api/skill/references/$",
576
- path: "/api/skill/references/$",
577
- getParentRoute: () => Route$13
526
+ getParentRoute: () => Route$11
578
527
  });
579
528
  var ApiMachineBlobHashRoute = Route$1.update({
580
529
  id: "/api/machine/blob/$hash",
581
530
  path: "/api/machine/blob/$hash",
582
- getParentRoute: () => Route$13
531
+ getParentRoute: () => Route$11
583
532
  });
584
533
  var ApiArtifactLoopIdSplatRoute = Route.update({
585
534
  id: "/api/artifact/$loopId/$",
586
535
  path: "/api/artifact/$loopId/$",
587
- getParentRoute: () => Route$13
536
+ getParentRoute: () => Route$11
588
537
  });
589
538
  var ApiHealthRouteChildren = { ApiHealthDbRoute };
590
539
  var rootRouteChildren = {
591
540
  IndexRoute,
592
- ApiBootstrapRoute,
593
541
  ApiHealthRoute: ApiHealthRoute._addFileChildren(ApiHealthRouteChildren),
594
542
  ApiReadyRoute,
595
543
  InviteTokenRoute,
@@ -603,10 +551,9 @@ var rootRouteChildren = {
603
551
  ApiMachineSyncRoute,
604
552
  ApiArtifactLoopIdSplatRoute,
605
553
  ApiMachineBlobHashRoute,
606
- ApiSkillReferencesSplatRoute,
607
554
  LoopsLoopIdRunsRunIdRoute
608
555
  };
609
- var routeTree = Route$13._addFileChildren(rootRouteChildren)._addFileTypes();
556
+ var routeTree = Route$11._addFileChildren(rootRouteChildren)._addFileTypes();
610
557
  function getRouter() {
611
558
  return createRouter({
612
559
  routeTree,
@@ -1,7 +1,7 @@
1
1
  import { h as require_jsx_runtime } from "../_libs/@base-ui/react+[...].mjs";
2
- import { r as LoadErrorCard } from "./actionUi-D15R8L7R.mjs";
2
+ import { r as LoadErrorCard } from "./actionUi-DD7Cd7Le.mjs";
3
3
  import { f as useRouter } from "../_libs/@tanstack/react-router+[...].mjs";
4
- //#region node_modules/.nitro/vite/services/ssr/assets/routes-DNCZrs8z.js
4
+ //#region node_modules/.nitro/vite/services/ssr/assets/routes-BWLQNDn5.js
5
5
  var import_jsx_runtime = require_jsx_runtime();
6
6
  /**
7
7
  * The home route. Under the auth gate it is now a THIN redirect to the explicit
@@ -1,9 +1,9 @@
1
1
  import { h as require_jsx_runtime } from "../_libs/@base-ui/react+[...].mjs";
2
- import { D as useSession } from "./SocialLinks-BTjsnVOm.mjs";
3
- import { t as SignIn } from "./SignIn-DjSrg0nO.mjs";
4
- import { t as DashboardView } from "./DashboardView-D_hKsCsv.mjs";
5
- import { t as Route } from "./routes-CRHc9cLG.mjs";
6
- //#region node_modules/.nitro/vite/services/ssr/assets/routes-ufPbrGHs.js
2
+ import { E as useSession } from "./SocialLinks-Bt7huqfS.mjs";
3
+ import { t as SignIn } from "./SignIn-ffgDY0yf.mjs";
4
+ import { t as DashboardView } from "./DashboardView-DqZLADCp.mjs";
5
+ import { t as Route } from "./routes-DqIGr7p0.mjs";
6
+ //#region node_modules/.nitro/vite/services/ssr/assets/routes-Cz49hLy6.js
7
7
  var import_jsx_runtime = require_jsx_runtime();
8
8
  /**
9
9
  * The home route. Under the auth gate it is now a THIN redirect to the explicit
@@ -1,9 +1,9 @@
1
1
  import { c as createFileRoute, p as redirect, s as lazyRouteComponent } from "../_libs/@tanstack/react-router+[...].mjs";
2
- import { d as getAuthState, i as authClient, p as getDefaultTeam } from "./SocialLinks-BTjsnVOm.mjs";
3
- import { n as fetchLiveData } from "./DashboardView-D_hKsCsv.mjs";
4
- //#region node_modules/.nitro/vite/services/ssr/assets/routes-CRHc9cLG.js
5
- var $$splitErrorComponentImporter = () => import("./routes-DNCZrs8z.mjs");
6
- var $$splitComponentImporter = () => import("./routes-ufPbrGHs.mjs");
2
+ import { f as getDefaultTeam, i as authClient, u as getAuthState } from "./SocialLinks-Bt7huqfS.mjs";
3
+ import { n as fetchLiveData } from "./DashboardView-DqZLADCp.mjs";
4
+ //#region node_modules/.nitro/vite/services/ssr/assets/routes-DqIGr7p0.js
5
+ var $$splitErrorComponentImporter = () => import("./routes-BWLQNDn5.mjs");
6
+ var $$splitComponentImporter = () => import("./routes-Cz49hLy6.mjs");
7
7
  /**
8
8
  * The home route. Under the auth gate it is now a THIN redirect to the explicit
9
9
  * team URL (`/t/<lastUsed|personal>`) so the dashboard's team lives in the path
@@ -0,0 +1,2 @@
1
+ import { _ as computeRunDiff } from "./boot-sNlIkoLe.mjs";
2
+ export { computeRunDiff };