@kky42/pievo-server 4.1.0 → 5.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.
Files changed (43) hide show
  1. package/.output/nitro.json +1 -1
  2. package/.output/public/assets/{MarkdownView-BuFKr9Jg.js → MarkdownView-T28pBEgh.js} +1 -1
  3. package/.output/public/assets/{actionUi-BZrLpgHT.js → actionUi-CY207nNM.js} +1 -1
  4. package/.output/public/assets/app-Cye1TgwS.css +2 -0
  5. package/.output/public/assets/{index-D0FIKiiW.js → index-BxXrF3gW.js} +3 -3
  6. package/.output/public/assets/loops._loopId-DuSEcu38.js +2 -0
  7. package/.output/public/assets/loops._loopId_.runs._runId-vjQaPXEe.js +3 -0
  8. package/.output/public/assets/{preload-helper-BSxGu4d0.js → preload-helper-B7p1iHUP.js} +2 -2
  9. package/.output/public/assets/routes-BUMEAWuS.js +1 -0
  10. package/.output/public/assets/{routes-BIOJZsig.js → routes-BrqOpUEi.js} +1 -1
  11. package/.output/server/_ssr/{MachinesModal-CLBZxZkq.mjs → MachinesModal-CB8rpDG2.mjs} +60 -29
  12. package/.output/server/_ssr/{MarkdownView-D1J7ImYF.mjs → MarkdownView-BOe75tli.mjs} +3 -6
  13. package/.output/server/_ssr/{actionUi-DE-Pb2tv.mjs → actionUi-CPYgZIr7.mjs} +57 -61
  14. package/.output/server/_ssr/artifactFiles-DLfSRhrV.mjs +67 -0
  15. package/.output/server/_ssr/{artifactKind-a2oxT2wQ.mjs → artifactKind-C0oXLA23.mjs} +2 -7
  16. package/.output/server/_ssr/{boot-DmpKtb0A.mjs → boot-jtVCf_pN.mjs} +239 -289
  17. package/.output/server/_ssr/{lifecycleUi-DEjM8Etm.mjs → lifecycleUi-Bd7_sthp.mjs} +8 -15
  18. package/.output/server/_ssr/{loopApi-DK1lQPrx.mjs → loopApi-0nR35Kh2.mjs} +12 -18
  19. package/.output/server/_ssr/{loopProjection-DdFivf7-.mjs → loopProjection-ZNfSmA5e.mjs} +3 -2
  20. package/.output/server/_ssr/{loops._loopId-DVCvGSEc.mjs → loops._loopId-CcJ3rxCU.mjs} +18 -89
  21. package/.output/server/_ssr/loops._loopId_.runs._runId-DFlrV3dJ.mjs +11 -0
  22. package/.output/server/_ssr/{loops._loopId_.runs._runId-BXbTfLlC.mjs → loops._loopId_.runs._runId-XkGF7HKo.mjs} +28 -19
  23. package/.output/server/_ssr/{machineFns-DLRHgDdS.mjs → machineFns-D-97a_hz.mjs} +6 -20
  24. package/.output/server/_ssr/{router-BhHsTGqu.mjs → router-CZ9CFWS2.mjs} +22 -31
  25. package/.output/server/_ssr/{routes-CCallyCT.mjs → routes-BBmuVs6n.mjs} +2 -2
  26. package/.output/server/_ssr/{routes-ngpX7h8D.mjs → routes-JxTh5mbj.mjs} +2 -2
  27. package/.output/server/_ssr/{routes-CL2Kef-Q.mjs → routes-fHRtSpkH.mjs} +6 -6
  28. package/.output/server/_ssr/ssr.mjs +22 -22
  29. package/.output/server/{_tanstack-start-manifest_v-BPiJ4yWT.mjs → _tanstack-start-manifest_v-C9JsxlwC.mjs} +8 -8
  30. package/.output/server/drizzle/0002_run_attention.sql +1 -0
  31. package/.output/server/drizzle/0003_run_status_ok.sql +13 -0
  32. package/.output/server/drizzle/meta/_journal.json +14 -0
  33. package/.output/server/index.mjs +49 -49
  34. package/drizzle/0002_run_attention.sql +1 -0
  35. package/drizzle/0003_run_status_ok.sql +13 -0
  36. package/drizzle/meta/_journal.json +14 -0
  37. package/package.json +1 -1
  38. package/.output/public/assets/app-x1CeeY7N.css +0 -2
  39. package/.output/public/assets/loops._loopId-DTkIz4C0.js +0 -2
  40. package/.output/public/assets/loops._loopId_.runs._runId-CsV2Ih4Z.js +0 -3
  41. package/.output/public/assets/routes-m4Z90DTR.js +0 -1
  42. package/.output/server/_ssr/artifactFiles-B0NPRDOR.mjs +0 -52
  43. package/.output/server/_ssr/loops._loopId_.runs._runId-Dr6E-FA5.mjs +0 -16
@@ -2,15 +2,12 @@ import { o as __toESM } from "../_runtime.mjs";
2
2
  import { g as require_react, h as require_jsx_runtime } from "../_libs/@base-ui/react+[...].mjs";
3
3
  import { t as purify } from "../_libs/dompurify.mjs";
4
4
  import { t as g } from "../_libs/marked.mjs";
5
- //#region node_modules/.nitro/vite/services/ssr/assets/MarkdownView-D1J7ImYF.js
5
+ //#region node_modules/.nitro/vite/services/ssr/assets/MarkdownView-BOe75tli.js
6
6
  var import_react = /* @__PURE__ */ __toESM(require_react());
7
7
  var import_jsx_runtime = require_jsx_runtime();
8
8
  /**
9
- * Shared markdown → sanitized HTML pipeline: marked (GFM) → DOMPurify (an
10
- * allowlisted prose subset, NO script/handlers). ONE sanitizer config for every
11
- * loop-file markdown surface so the allowlist cannot drift between viewers.
12
- * Render the output under
13
- * the `.artifact-markdown` styles.
9
+ * marked (GFM) → DOMPurify with one allowlisted prose subset (no scripts or
10
+ * handlers) for every loop-file markdown surface, so viewers cannot drift.
14
11
  */
15
12
  var MD_SANITIZE = {
16
13
  ALLOWED_TAGS: [
@@ -1,6 +1,6 @@
1
1
  import { o as __toESM } from "../_runtime.mjs";
2
2
  import { g as require_react, h as require_jsx_runtime } from "../_libs/@base-ui/react+[...].mjs";
3
- //#region node_modules/.nitro/vite/services/ssr/assets/actionUi-DE-Pb2tv.js
3
+ //#region node_modules/.nitro/vite/services/ssr/assets/actionUi-CPYgZIr7.js
4
4
  var import_react = /* @__PURE__ */ __toESM(require_react());
5
5
  var import_jsx_runtime = require_jsx_runtime();
6
6
  var fmt = (t) => t ? new Date(t).toLocaleString() : "—";
@@ -78,13 +78,9 @@ function humanBytes(n) {
78
78
  return `${(abs / (1024 * 1024)).toFixed(1)} MB`;
79
79
  }
80
80
  var ST = {
81
- keep: {
82
- c: "var(--color-run-keep)",
83
- label: "Keep"
84
- },
85
- "no-change": {
86
- c: "var(--color-run-no-change)",
87
- label: "No change"
81
+ ok: {
82
+ c: "var(--color-run-ok)",
83
+ label: "OK"
88
84
  },
89
85
  block: {
90
86
  c: "var(--color-run-block)",
@@ -94,10 +90,6 @@ var ST = {
94
90
  c: "var(--color-run-error)",
95
91
  label: "Error"
96
92
  },
97
- warning: {
98
- c: "var(--color-run-warning)",
99
- label: "Missing status"
100
- },
101
93
  canceled: {
102
94
  c: "var(--color-run-canceled)",
103
95
  label: "Canceled"
@@ -107,7 +99,7 @@ var ST = {
107
99
  label: "Queued"
108
100
  },
109
101
  reconciling: {
110
- c: "var(--color-run-warning)",
102
+ c: "var(--color-run-reconciling)",
111
103
  label: "Reconciling…"
112
104
  },
113
105
  active: {
@@ -115,48 +107,49 @@ var ST = {
115
107
  label: "Running…"
116
108
  }
117
109
  };
118
- var statusMeta = (k) => k === "keep" || k === "no-change" || k === "block" ? ST[k] : void 0;
110
+ /** The run's ink, for text and borders. Fills use `runSwatch`. */
119
111
  function dotColor(r) {
120
112
  if (r.reconciliation) return ST.reconciling.c;
121
113
  if (r.phase === "running") return ST.active.c;
122
114
  if (r.phase === "error") return ST.error.c;
123
- if (r.status === "block") return ST.block.c;
124
115
  if (r.phase === "pending") return ST.queued.c;
125
116
  if (r.phase === "canceled") return ST.canceled.c;
126
- if (r.phase === "done" && !statusMeta(r.status)) return ST.warning.c;
127
- return (statusMeta(r.status) ?? ST["no-change"]).c;
117
+ return r.status === "block" ? ST.block.c : ST.ok.c;
128
118
  }
129
- function dotOpacity(r) {
130
- if (r.reconciliation || r.phase === "running" || r.status === "block" || r.phase === "error") return 1;
131
- if (r.phase === "pending") return .7;
132
- if (r.phase === "canceled") return .5;
133
- if (r.phase === "done" && !statusMeta(r.status)) return .9;
134
- if (r.status === "no-change") return .55;
135
- return 1;
119
+ var runPulseAnim = { animation: "runPulse 1.1s ease-in-out infinite" };
120
+ /** Fill, outline, and motion for a run block or dot. */
121
+ function runSwatch(r) {
122
+ const ink = dotColor(r);
123
+ if (r.reconciliation) return {
124
+ outline: `1.5px dashed ${ink}`,
125
+ outlineOffset: "-1.5px",
126
+ animation: "runWait 2.4s ease-in-out infinite"
127
+ };
128
+ if (r.phase === "running") return {
129
+ background: ink,
130
+ ...runPulseAnim
131
+ };
132
+ if (r.phase === "pending") return { boxShadow: `inset 0 0 0 1.5px ${ink}` };
133
+ if (r.phase === "canceled") return {
134
+ background: ink,
135
+ opacity: .5
136
+ };
137
+ if (r.phase === "error") return { background: `repeating-linear-gradient(135deg, ${ink} 0 3px, var(--color-run-error-stripe) 3px 6px)` };
138
+ return { background: ink };
136
139
  }
137
140
  function dotLabel(r) {
138
141
  if (r.reconciliation === "blocking") return "Waiting for machine recovery";
139
142
  if (r.reconciliation === "report-only") return "Awaiting late report";
140
143
  if (r.phase === "pending") return ST.queued.label;
141
- if (r.phase === "running") {
142
- if (r.cancelRequested) return "Stopping…";
143
- return ST.active.label;
144
- }
145
- if (r.phase === "error") {
146
- if (r.cancelRequested) return "Failed while stopping";
147
- return ST.error.label;
148
- }
144
+ if (r.phase === "running") return r.cancelRequested ? "Stopping…" : ST.active.label;
145
+ if (r.phase === "error") return r.cancelRequested ? "Failed while stopping" : ST.error.label;
146
+ if (r.phase === "canceled") return ST.canceled.label;
149
147
  if (r.status === "block") return ST.block.label;
150
- if (r.phase === "canceled") {
151
- if (r.error === "stopped by user") return "Canceled";
152
- return "Canceled";
153
- }
154
- if (r.cancelRequested && r.phase === "done") return "Succeeded while stopping";
155
- if (r.status === "keep") return ST.keep.label;
156
- if (r.status === "no-change") return ST["no-change"].label;
157
- if (r.phase === "done") return ST.warning.label;
158
- return ST["no-change"].label;
148
+ return r.cancelRequested ? "Succeeded while stopping" : ST.ok.label;
159
149
  }
150
+ /** The newest finished run, whose attention reason the loop card surfaces until a
151
+ * later run finishes without one. */
152
+ var lastFinishedRun = (runs) => runs.findLast((r) => r.phase === "done" || r.phase === "error");
160
153
  var lastRunOf = (j) => {
161
154
  const a = j.runs ?? [];
162
155
  return a.length ? a[a.length - 1] : null;
@@ -174,14 +167,10 @@ var sectionHeadCls = "text-label font-semibold text-secondary";
174
167
  var labelCls = "mb-1.5 mt-3 block text-label font-medium text-secondary";
175
168
  var inputCls = `w-full rounded-control border border-wire bg-surface px-3 py-2.5 text-sm text-primary outline-none transition-shadow focus:border-transparent focus:shadow-focus`;
176
169
  var selectCls = `${inputCls} lp-select cursor-pointer`;
177
- /**
178
- * The live "running" pulse — a display-ink fill breathing via the `runPulse`
179
- * keyframe (app.css). Shared so the in-flight timeline block and the Running
180
- * badge stay in lockstep. Spread into a `style` prop.
181
- */
182
- var runPulseAnim = { animation: "runPulse 1.1s ease-in-out infinite" };
170
+ /** The live "running" indicator outside the timeline: the same ink fill and
171
+ * `runPulse` breath as the in-flight run block. Spread into a `style` prop. */
183
172
  var runPulseStyle = {
184
- background: "var(--color-rubik-yellow)",
173
+ background: "var(--color-run-active)",
185
174
  ...runPulseAnim
186
175
  };
187
176
  function ErrorBanner({ message, onDismiss, className = "mb-2" }) {
@@ -206,20 +195,16 @@ var PILL_TONES = {
206
195
  neutral: "bg-raised text-secondary",
207
196
  ink: "bg-raised text-primary",
208
197
  outline: "border border-hairline text-secondary",
209
- running: "bg-running-soft text-running",
210
- attention: "bg-running-soft text-running",
198
+ attention: "bg-attention-soft text-attention",
211
199
  success: "bg-success-soft text-success",
212
200
  accent: "bg-accent-soft text-accent",
213
201
  warn: "bg-warn-soft text-warn"
214
202
  };
215
- function Pill({ tone = "neutral", dot, title, className = "", children }) {
216
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", {
203
+ function Pill({ tone = "neutral", title, className = "", children }) {
204
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
217
205
  title,
218
206
  className: `inline-flex h-[22px] items-center gap-1.5 rounded-full px-2.5 text-caption font-medium ${PILL_TONES[tone]} ${className}`,
219
- children: [dot && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
220
- className: "size-1.5 rounded-full",
221
- style: dot === "pulse" ? runPulseStyle : { background: "var(--color-rubik-green)" }
222
- }), children]
207
+ children
223
208
  });
224
209
  }
225
210
  function Loading({ className = "" }) {
@@ -228,16 +213,27 @@ function Loading({ className = "" }) {
228
213
  children: "Loading…"
229
214
  });
230
215
  }
216
+ /** Yellow "!" for a run that asked for owner attention. It overlays the status
217
+ * color instead of replacing it because attention is independent of status; the
218
+ * dark outline keeps yellow legible on green, red, and grey blocks. */
219
+ function AttentionMark() {
220
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
221
+ "aria-hidden": true,
222
+ className: "pointer-events-none select-none text-[14px] font-black leading-none text-run-attention",
223
+ style: {
224
+ WebkitTextStroke: "3px rgba(0,0,0,0.55)",
225
+ paintOrder: "stroke fill"
226
+ },
227
+ children: "!"
228
+ });
229
+ }
231
230
  function StatusPill({ run, colorText }) {
232
231
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", {
233
232
  className: "inline-flex items-center gap-1.5 font-medium",
234
233
  style: colorText ? { color: dotColor(run) } : void 0,
235
234
  children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
236
235
  className: "size-2 rounded-full",
237
- style: {
238
- background: dotColor(run),
239
- opacity: dotOpacity(run)
240
- }
236
+ style: runSwatch(run)
241
237
  }), dotLabel(run)]
242
238
  });
243
239
  }
@@ -353,4 +349,4 @@ function useFlash() {
353
349
  return [flash, setFlash];
354
350
  }
355
351
  //#endregion
356
- export { tsShort as A, lastRunOf as C, scheduleText as D, runPulseStyle as E, useFlash as M, useHydrated as N, sectionHeadCls as O, labelCls as S, runPulseAnim as T, fmt as _, Loading as a, humanBytes as b, btn as c, btnQuiet as d, btnSm as f, dur as g, dotOpacity as h, LoadErrorCard as i, until as j, selectCls as k, btnDanger as l, dotLabel as m, ErrorBanner as n, Pill as o, dotColor as p, FlashLine as r, StatusPill as s, ConfirmBar as t, btnPrimary as u, fnum as v, rel as w, inputCls as x, focusRing as y };
352
+ export { tsShort as A, lastRunOf as C, scheduleText as D, runSwatch as E, useFlash as M, useHydrated as N, sectionHeadCls as O, lastFinishedRun as S, runPulseStyle as T, fnum as _, LoadErrorCard as a, inputCls as b, StatusPill as c, btnPrimary as d, btnQuiet as f, fmt as g, dur as h, FlashLine as i, until as j, selectCls as k, btn as l, dotLabel as m, ConfirmBar as n, Loading as o, btnSm as p, ErrorBanner as r, Pill as s, AttentionMark as t, btnDanger as u, focusRing as v, rel as w, labelCls as x, humanBytes as y };
@@ -0,0 +1,67 @@
1
+ import { D as listArtifacts, M as loopFileNames, b as getArtifactFile, c as getLoopFiles, x as getLoop } from "./boot-jtVCf_pN.mjs";
2
+ import { n as toArtifactSummary } from "./loopProjection-ZNfSmA5e.mjs";
3
+ //#region node_modules/.nitro/vite/services/ssr/assets/artifactFiles-DLfSRhrV.js
4
+ /** Read-only access to a loop's current files, shared by the dashboard server
5
+ * functions and the download route. Bytes are decoded as text, never interpreted. */
6
+ async function listLoopArtifacts(loopId) {
7
+ const loop = await getLoop(loopId);
8
+ if (!loop) return [];
9
+ const rows = new Map((await listArtifacts(loopId)).map((row) => [row.path, row]));
10
+ return loopFileNames(loop).map((path) => {
11
+ const row = rows.get(path);
12
+ return row ? toArtifactSummary(row) : {
13
+ path,
14
+ size: 0,
15
+ updatedAt: loop.updatedAt,
16
+ binary: false,
17
+ oversize: false
18
+ };
19
+ }).sort((a, b) => a.path < b.path ? -1 : a.path > b.path ? 1 : 0);
20
+ }
21
+ /**
22
+ * One file's content for inline display: decoded text for a text file, or a
23
+ * binary/oversize marker (the UI then offers the download route). A configured
24
+ * file with no stored version reads as empty; an unknown name is an error —
25
+ * never throws.
26
+ */
27
+ async function readLoopArtifact(loopId, rawPath) {
28
+ const loop = await getLoop(loopId);
29
+ if (!loop) return { error: "file not found" };
30
+ const row = await getArtifactFile(loopId, rawPath);
31
+ if (!row || row.deleted) return loopFileNames(loop).includes(rawPath) ? { text: "" } : { error: "file not found" };
32
+ if (row.binary || row.oversize) return {
33
+ binary: true,
34
+ size: row.size ?? null,
35
+ oversize: row.oversize
36
+ };
37
+ if (!row.hash) return { error: "file has no stored version" };
38
+ const bytes = await (await getLoopFiles()).readBlob(row.hash);
39
+ if (!bytes) return { error: "file not found" };
40
+ return { text: bytes.toString("utf8") };
41
+ }
42
+ /**
43
+ * Resolve a loop file name to its stored bytes for the download route. A
44
+ * configured file with no stored version serves empty bytes; an unknown name is
45
+ * 404. The bytes stream straight from the BlobStore.
46
+ */
47
+ async function readLoopArtifactBytes(loopId, rawPath) {
48
+ const loop = await getLoop(loopId);
49
+ if (!loop) return { status: 404 };
50
+ const row = await getArtifactFile(loopId, rawPath);
51
+ if (!row || row.deleted || !row.hash) return loopFileNames(loop).includes(rawPath) ? {
52
+ status: 200,
53
+ bytes: Buffer.alloc(0),
54
+ binary: false,
55
+ filename: rawPath
56
+ } : { status: 404 };
57
+ const bytes = await (await getLoopFiles()).readBlob(row.hash);
58
+ if (!bytes) return { status: 404 };
59
+ return {
60
+ status: 200,
61
+ bytes,
62
+ binary: row.binary,
63
+ filename: rawPath
64
+ };
65
+ }
66
+ //#endregion
67
+ export { listLoopArtifacts, readLoopArtifact, readLoopArtifactBytes };
@@ -1,11 +1,6 @@
1
1
  import { c as createFileRoute, s as lazyRouteComponent } from "../_libs/@tanstack/react-router+[...].mjs";
2
- //#region node_modules/.nitro/vite/services/ssr/assets/artifactKind-a2oxT2wQ.js
3
- var $$splitComponentImporter = () => import("./loops._loopId-DVCvGSEc.mjs");
4
- /**
5
- * Loop detail page — `/loops/$loopId`: a loop header and action toolbar, the
6
- * loop Files panel, and the runs timeline. The view owns its own data + self-poll.
7
- * Run rows link on to `/loops/$loopId/runs/$runId`.
8
- */
2
+ //#region node_modules/.nitro/vite/services/ssr/assets/artifactKind-C0oXLA23.js
3
+ var $$splitComponentImporter = () => import("./loops._loopId-CcJ3rxCU.mjs");
9
4
  var Route = createFileRoute("/loops/$loopId")({
10
5
  ssr: false,
11
6
  component: lazyRouteComponent($$splitComponentImporter, "component")