@kky42/pievo-server 1.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 (197) hide show
  1. package/.output/nitro.json +17 -0
  2. package/.output/public/assets/CodeField-dOzyFQNH.js +34 -0
  3. package/.output/public/assets/LoopView-B4H9QibC.js +55 -0
  4. package/.output/public/assets/Modal-D33gNSgx.js +1 -0
  5. package/.output/public/assets/SignIn-SHuRRyOv.js +1 -0
  6. package/.output/public/assets/actionUi-ChGGALzg.js +1 -0
  7. package/.output/public/assets/app-DElSo_jy.css +2 -0
  8. package/.output/public/assets/artifactView-DFuubXLJ.js +66 -0
  9. package/.output/public/assets/index-DfpTWRSz.js +12 -0
  10. package/.output/public/assets/invite._token-DJtd-XE2.js +1 -0
  11. package/.output/public/assets/invite._token-T8oo4Qtw.js +1 -0
  12. package/.output/public/assets/jsx-runtime-BseJUIpC.js +1 -0
  13. package/.output/public/assets/lifecycleUi-DKkChdnU.js +1 -0
  14. package/.output/public/assets/loopApi-BM2nj71x.js +3 -0
  15. package/.output/public/assets/loops._loopId-B19Jw7jC.js +5 -0
  16. package/.output/public/assets/loops._loopId_.runs._runId-_CflHV38.js +3 -0
  17. package/.output/public/assets/notifyFns-DCubjpRy.js +1 -0
  18. package/.output/public/assets/preload-helper-CKUiEq3b.js +3 -0
  19. package/.output/public/assets/routes-B9tgli5f.js +1 -0
  20. package/.output/public/assets/routes-CTtlM_qt.js +1 -0
  21. package/.output/public/assets/t._teamId-Bm21mngW.js +1 -0
  22. package/.output/public/assets/t._teamId-gR7BVKkR.js +1 -0
  23. package/.output/public/assets/ui-Dp88qUWh.js +1 -0
  24. package/.output/public/assets/useRouter-DsjH8G0p.js +1 -0
  25. package/.output/public/favicon.svg +12 -0
  26. package/.output/public/fonts/GeistPixel-Square.woff2 +0 -0
  27. package/.output/server/_chunks/ssr-renderer.mjs +26 -0
  28. package/.output/server/_libs/@aws-crypto/crc32+[...].mjs +419 -0
  29. package/.output/server/_libs/@aws-sdk/checksums+[...].mjs +10732 -0
  30. package/.output/server/_libs/@aws-sdk/client-s3+[...].mjs +9475 -0
  31. package/.output/server/_libs/@aws-sdk/credential-provider-http+[...].mjs +137 -0
  32. package/.output/server/_libs/@aws-sdk/credential-provider-ini+[...].mjs +440 -0
  33. package/.output/server/_libs/@aws-sdk/credential-provider-process+[...].mjs +62 -0
  34. package/.output/server/_libs/@aws-sdk/credential-provider-sso+[...].mjs +818 -0
  35. package/.output/server/_libs/@aws-sdk/credential-provider-web-identity+[...].mjs +59 -0
  36. package/.output/server/_libs/@base-ui/react+[...].mjs +11125 -0
  37. package/.output/server/_libs/@codemirror/autocomplete+[...].mjs +19713 -0
  38. package/.output/server/_libs/@codemirror/lang-css+[...].mjs +2636 -0
  39. package/.output/server/_libs/@codemirror/lang-html+[...].mjs +2247 -0
  40. package/.output/server/_libs/@codemirror/lang-json+[...].mjs +79 -0
  41. package/.output/server/_libs/@reduxjs/toolkit+[...].mjs +1736 -0
  42. package/.output/server/_libs/@smithy/credential-provider-imds+[...].mjs +342 -0
  43. package/.output/server/_libs/@tanstack/react-router+[...].mjs +14300 -0
  44. package/.output/server/_libs/@uiw/codemirror-extensions-basic-setup+[...].mjs +76 -0
  45. package/.output/server/_libs/atomic-sleep.mjs +27 -0
  46. package/.output/server/_libs/aws-crypto__crc32c.mjs +314 -0
  47. package/.output/server/_libs/aws-sdk__nested-clients.mjs +2671 -0
  48. package/.output/server/_libs/babel__runtime.mjs +30 -0
  49. package/.output/server/_libs/clsx.mjs +16 -0
  50. package/.output/server/_libs/codemirror__commands.mjs +1725 -0
  51. package/.output/server/_libs/codemirror__lint.mjs +565 -0
  52. package/.output/server/_libs/codemirror__search.mjs +1138 -0
  53. package/.output/server/_libs/codemirror__theme-one-dark.mjs +161 -0
  54. package/.output/server/_libs/colorette.mjs +129 -0
  55. package/.output/server/_libs/croner.mjs +735 -0
  56. package/.output/server/_libs/d3-array.mjs +231 -0
  57. package/.output/server/_libs/d3-color.mjs +330 -0
  58. package/.output/server/_libs/d3-format.mjs +252 -0
  59. package/.output/server/_libs/d3-interpolate.mjs +163 -0
  60. package/.output/server/_libs/d3-path.mjs +77 -0
  61. package/.output/server/_libs/d3-scale+[...].mjs +1907 -0
  62. package/.output/server/_libs/d3-shape.mjs +689 -0
  63. package/.output/server/_libs/dateformat.mjs +341 -0
  64. package/.output/server/_libs/decimal.js-light.mjs +884 -0
  65. package/.output/server/_libs/diff.mjs +732 -0
  66. package/.output/server/_libs/dom-serializer+[...].mjs +708 -0
  67. package/.output/server/_libs/domhandler.mjs +461 -0
  68. package/.output/server/_libs/dompurify.mjs +2111 -0
  69. package/.output/server/_libs/domutils.mjs +868 -0
  70. package/.output/server/_libs/drizzle-orm+postgres.mjs +7689 -0
  71. package/.output/server/_libs/electric-sql__pglite.mjs +14674 -0
  72. package/.output/server/_libs/end-of-stream+once+wrappy.mjs +145 -0
  73. package/.output/server/_libs/es-toolkit.mjs +1737 -0
  74. package/.output/server/_libs/eventemitter3.mjs +236 -0
  75. package/.output/server/_libs/fast-copy.mjs +285 -0
  76. package/.output/server/_libs/fast-safe-stringify.mjs +172 -0
  77. package/.output/server/_libs/h3+rou3+srvx.mjs +1201 -0
  78. package/.output/server/_libs/html-dom-parser+htmlparser2.mjs +1560 -0
  79. package/.output/server/_libs/html-react-parser+[...].mjs +1360 -0
  80. package/.output/server/_libs/initdb.wasm +0 -0
  81. package/.output/server/_libs/marked.mjs +1548 -0
  82. package/.output/server/_libs/on-exit-leak-free.mjs +80 -0
  83. package/.output/server/_libs/pglite.data +37667 -8
  84. package/.output/server/_libs/pglite.wasm +0 -0
  85. package/.output/server/_libs/pino+[...].mjs +3196 -0
  86. package/.output/server/_libs/pino-abstract-transport+split2.mjs +194 -0
  87. package/.output/server/_libs/pino-pretty+[...].mjs +1623 -0
  88. package/.output/server/_libs/pinojs__redact.mjs +280 -0
  89. package/.output/server/_libs/react-redux+[...].mjs +205 -0
  90. package/.output/server/_libs/recharts+victory-vendor.mjs +15875 -0
  91. package/.output/server/_libs/tanstack__history.mjs +342 -0
  92. package/.output/server/_libs/ufo.mjs +64 -0
  93. package/.output/server/_libs/uiw__codemirror-themes.mjs +32 -0
  94. package/.output/server/_libs/uiw__react-codemirror.mjs +354 -0
  95. package/.output/server/_runtime.mjs +37 -0
  96. package/.output/server/_ssr/CodeField-tm4rr6G3.mjs +143 -0
  97. package/.output/server/_ssr/DashboardView-CC7htv28.mjs +2795 -0
  98. package/.output/server/_ssr/LoopPlaybook-BXH8mhiX.mjs +2105 -0
  99. package/.output/server/_ssr/LoopView-DCugEbHx.mjs +1106 -0
  100. package/.output/server/_ssr/Modal-DpKZHLZK.mjs +49 -0
  101. package/.output/server/_ssr/SignIn-dTndU6Hw.mjs +67 -0
  102. package/.output/server/_ssr/actionUi-CZbEixbf.mjs +119 -0
  103. package/.output/server/_ssr/adapters-BS8XosjF.mjs +130 -0
  104. package/.output/server/_ssr/artifactFiles-Cagtj7J0.mjs +61 -0
  105. package/.output/server/_ssr/artifactKind-BW0isV8L.mjs +37 -0
  106. package/.output/server/_ssr/artifactView-DS4O22wl.mjs +304 -0
  107. package/.output/server/_ssr/artifacts-DngKyW2u.mjs +2 -0
  108. package/.output/server/_ssr/auth-DY1DuYZd.mjs +38429 -0
  109. package/.output/server/_ssr/boot-BbtG0ImW.mjs +9010 -0
  110. package/.output/server/_ssr/boot-CMHTxQpJ.mjs +2 -0
  111. package/.output/server/_ssr/bun-sqlite-dialect-BW9W1_Ps-CU1Spd6z.mjs +162 -0
  112. package/.output/server/_ssr/core-RrmWoKne.mjs +5 -0
  113. package/.output/server/_ssr/createServerRpc-BD8Xn_0_.mjs +12 -0
  114. package/.output/server/_ssr/d1-sqlite-dialect-BLC8LXE6-DfG7tB8s.mjs +112 -0
  115. package/.output/server/_ssr/db-DWAuZq1o.mjs +2 -0
  116. package/.output/server/_ssr/dist-BIxFFVZg.mjs +342 -0
  117. package/.output/server/_ssr/empty-plugin-adapters-DKUlnwwl.mjs +5 -0
  118. package/.output/server/_ssr/factory-Blq0DYfT.mjs +6903 -0
  119. package/.output/server/_ssr/invite._token-BRCo9LGB.mjs +36 -0
  120. package/.output/server/_ssr/invite._token-DJxGLILJ.mjs +28 -0
  121. package/.output/server/_ssr/invite._token-NewFt27g.mjs +92 -0
  122. package/.output/server/_ssr/kysely-adapter-D3XTe64J.mjs +2 -0
  123. package/.output/server/_ssr/kysely-migration-tables-JkVUjPF_-bPAX9LR_.mjs +19 -0
  124. package/.output/server/_ssr/lifecycleUi-C9lg1r3r.mjs +38 -0
  125. package/.output/server/_ssr/logger-Dw82jNjH.mjs +2 -0
  126. package/.output/server/_ssr/loopApi-BtfkZQYK.mjs +532 -0
  127. package/.output/server/_ssr/loopApi-Cxe8WyOB.mjs +105 -0
  128. package/.output/server/_ssr/loops._loopId-7NQJPB9W.mjs +30 -0
  129. package/.output/server/_ssr/loops._loopId-DhnArGdL.mjs +1635 -0
  130. package/.output/server/_ssr/loops._loopId_.runs._runId-Bvuo2nki.mjs +29 -0
  131. package/.output/server/_ssr/loops._loopId_.runs._runId-Dip5Xk-q.mjs +674 -0
  132. package/.output/server/_ssr/machineFns-Dvr5ICUy.mjs +266 -0
  133. package/.output/server/_ssr/node-sqlite-dialect-DhyOpJTX.mjs +162 -0
  134. package/.output/server/_ssr/notifyFns-BcMRY5kP.mjs +118 -0
  135. package/.output/server/_ssr/notifyFns-Q458pZmE.mjs +580 -0
  136. package/.output/server/_ssr/router-J8KZ30xw.mjs +678 -0
  137. package/.output/server/_ssr/routes-Bcs4T1ox.mjs +28 -0
  138. package/.output/server/_ssr/routes-BoGrcf-b.mjs +43 -0
  139. package/.output/server/_ssr/routes-D4am3Zff.mjs +28 -0
  140. package/.output/server/_ssr/runDiff-CpEFqo7G.mjs +113 -0
  141. package/.output/server/_ssr/ssr.mjs +5837 -0
  142. package/.output/server/_ssr/start-4ifArtKx.mjs +4 -0
  143. package/.output/server/_ssr/store-b3JcQ08F.mjs +2 -0
  144. package/.output/server/_ssr/t._teamId-CeUhzgzT.mjs +32 -0
  145. package/.output/server/_ssr/t._teamId-DR-hQK7o.mjs +47 -0
  146. package/.output/server/_ssr/t._teamId-Dy_McbRt.mjs +31 -0
  147. package/.output/server/_ssr/teamCookie-B7hLOIie.mjs +10 -0
  148. package/.output/server/_ssr/teamFns-BIDnsg2A.mjs +473 -0
  149. package/.output/server/_ssr/teamFns-DA4ovI5g.mjs +33 -0
  150. package/.output/server/_ssr/tokens-ytd60FUt.mjs +2 -0
  151. package/.output/server/_ssr/ui-Dej2qjuS.mjs +267 -0
  152. package/.output/server/_tanstack-start-manifest_v-CVS6c7re.mjs +95 -0
  153. package/.output/server/drizzle/0000_round_marauders.sql +193 -0
  154. package/.output/server/drizzle/0001_naive_silver_fox.sql +25 -0
  155. package/.output/server/drizzle/0002_funny_sage.sql +12 -0
  156. package/.output/server/drizzle/0003_optimal_slapstick.sql +102 -0
  157. package/.output/server/drizzle/0004_remove_grok_agent.sql +5 -0
  158. package/.output/server/drizzle/0005_heavy_gauntlet.sql +8 -0
  159. package/.output/server/drizzle/0006_tranquil_sharon_carter.sql +1 -0
  160. package/.output/server/drizzle/0007_faulty_starbolt.sql +30 -0
  161. package/.output/server/drizzle/0008_durable_lifecycle_evidence.sql +15 -0
  162. package/.output/server/drizzle/meta/0000_snapshot.json +1333 -0
  163. package/.output/server/drizzle/meta/0001_snapshot.json +1498 -0
  164. package/.output/server/drizzle/meta/0002_snapshot.json +1576 -0
  165. package/.output/server/drizzle/meta/0003_snapshot.json +1666 -0
  166. package/.output/server/drizzle/meta/0005_snapshot.json +1666 -0
  167. package/.output/server/drizzle/meta/0006_snapshot.json +1672 -0
  168. package/.output/server/drizzle/meta/0007_snapshot.json +1787 -0
  169. package/.output/server/drizzle/meta/_journal.json +69 -0
  170. package/.output/server/index.mjs +464 -0
  171. package/.output/server/node_modules/tslib/modules/index.js +70 -0
  172. package/.output/server/node_modules/tslib/modules/package.json +3 -0
  173. package/.output/server/node_modules/tslib/package.json +47 -0
  174. package/.output/server/node_modules/tslib/tslib.js +484 -0
  175. package/.output/server/package.json +9 -0
  176. package/LICENSE +21 -0
  177. package/drizzle/0000_round_marauders.sql +193 -0
  178. package/drizzle/0001_naive_silver_fox.sql +25 -0
  179. package/drizzle/0002_funny_sage.sql +12 -0
  180. package/drizzle/0003_optimal_slapstick.sql +102 -0
  181. package/drizzle/0004_remove_grok_agent.sql +5 -0
  182. package/drizzle/0005_heavy_gauntlet.sql +8 -0
  183. package/drizzle/0006_tranquil_sharon_carter.sql +1 -0
  184. package/drizzle/0007_faulty_starbolt.sql +30 -0
  185. package/drizzle/0008_durable_lifecycle_evidence.sql +15 -0
  186. package/drizzle/meta/0000_snapshot.json +1333 -0
  187. package/drizzle/meta/0001_snapshot.json +1498 -0
  188. package/drizzle/meta/0002_snapshot.json +1576 -0
  189. package/drizzle/meta/0003_snapshot.json +1666 -0
  190. package/drizzle/meta/0005_snapshot.json +1666 -0
  191. package/drizzle/meta/0006_snapshot.json +1672 -0
  192. package/drizzle/meta/0007_snapshot.json +1787 -0
  193. package/drizzle/meta/_journal.json +69 -0
  194. package/package.json +84 -0
  195. package/scripts/pievo-server.mjs +390 -0
  196. package/scripts/prestart.mjs +66 -0
  197. package/scripts/server-cli-lib.mjs +451 -0
@@ -0,0 +1,674 @@
1
+ import { o as __toESM } from "../_runtime.mjs";
2
+ import { C as require_jsx_runtime, S as require_react } from "../_libs/@base-ui/react+[...].mjs";
3
+ import { O as runPulseStyle, _ as fmt, a as StatusPill, c as btnDanger, g as dur, k as sectionHeadCls, n as Loading, o as btn, r as Pill, v as fnum, y as humanBytes } from "./ui-Dej2qjuS.mjs";
4
+ import { u as Link } from "../_libs/@tanstack/react-router+[...].mjs";
5
+ import { T as stopRun, _ as loadOlderRuns, f as getJobDetail, p as getRunDiff } from "./loopApi-Cxe8WyOB.mjs";
6
+ import { r as LoadErrorCard } from "./actionUi-CZbEixbf.mjs";
7
+ import { s as useSession } from "./LoopPlaybook-BXH8mhiX.mjs";
8
+ import { t as SignIn } from "./SignIn-dTndU6Hw.mjs";
9
+ import { t as Route } from "./loops._loopId_.runs._runId-Bvuo2nki.mjs";
10
+ //#region node_modules/.nitro/vite/services/ssr/assets/loops._loopId_.runs._runId-Dip5Xk-q.js
11
+ var import_react = /* @__PURE__ */ __toESM(require_react());
12
+ var import_jsx_runtime = require_jsx_runtime();
13
+ /**
14
+ * Classify one physical diff line, given whether we are already inside a hunk.
15
+ * Classification is STATEFUL over hunk position: only the preamble (before the
16
+ * first `@@`) may hold `---`/`+++`/`diff `/`index `/`Index:`/`===` headers, so
17
+ * once inside a hunk a content line whose text merely begins with `--`/`++`
18
+ * (a markdown `---` HR/frontmatter, a `-- comment`, a `++x`) is read by its
19
+ * single leading marker char and keeps its del/add tint + stat.
20
+ */
21
+ function classify(line, inHunk) {
22
+ if (line.startsWith("@@")) return {
23
+ kind: "hunk",
24
+ text: line,
25
+ gutter: ""
26
+ };
27
+ if (!inHunk) {
28
+ if (line.startsWith("---") || line.startsWith("+++") || line.startsWith("diff ") || line.startsWith("index ") || line.startsWith("Index:") || line.startsWith("===")) return {
29
+ kind: "meta",
30
+ text: line,
31
+ gutter: ""
32
+ };
33
+ return {
34
+ kind: "context",
35
+ text: line,
36
+ gutter: ""
37
+ };
38
+ }
39
+ if (line.startsWith("+")) return {
40
+ kind: "add",
41
+ text: line.slice(1),
42
+ gutter: "+"
43
+ };
44
+ if (line.startsWith("-")) return {
45
+ kind: "del",
46
+ text: line.slice(1),
47
+ gutter: "-"
48
+ };
49
+ if (line.startsWith(" ")) return {
50
+ kind: "context",
51
+ text: line.slice(1),
52
+ gutter: ""
53
+ };
54
+ return {
55
+ kind: "context",
56
+ text: line,
57
+ gutter: ""
58
+ };
59
+ }
60
+ /**
61
+ * Split a unified-diff string into classified lines. A trailing newline does not
62
+ * emit a spurious empty final line (common in generated diffs).
63
+ */
64
+ function parseUnifiedDiff(diff) {
65
+ if (!diff) return [];
66
+ const body = diff.endsWith("\n") ? diff.slice(0, -1) : diff;
67
+ let inHunk = false;
68
+ return body.split("\n").map((line) => {
69
+ const classified = classify(line, inHunk);
70
+ if (classified.kind === "hunk") inHunk = true;
71
+ return classified;
72
+ });
73
+ }
74
+ /** Counts of added/removed content lines — for a compact per-file "+N −M" tally. */
75
+ function diffStat(lines) {
76
+ let added = 0;
77
+ let removed = 0;
78
+ for (const l of lines) if (l.kind === "add") added++;
79
+ else if (l.kind === "del") removed++;
80
+ return {
81
+ added,
82
+ removed
83
+ };
84
+ }
85
+ /** Per-file status word + its ink (reused from the old Changes list). */
86
+ var STATUS_LABEL = {
87
+ added: "Added",
88
+ modified: "Changed",
89
+ removed: "Removed"
90
+ };
91
+ var STATUS_CLS = {
92
+ added: "text-success",
93
+ modified: "text-secondary",
94
+ removed: "text-accent"
95
+ };
96
+ /** Signed byte delta — "+1.8 KB", "−240 B", "" when unknown/zero. */
97
+ function fmtDelta(n) {
98
+ if (n == null || n === 0) return "";
99
+ return `${n > 0 ? "+" : "−"}${humanBytes(n)}`;
100
+ }
101
+ /** A diff line's row classes — line-level tint + gutter ink per kind. */
102
+ var LINE_CLS = {
103
+ add: "bg-[color:var(--color-diff-add-bg)] text-primary",
104
+ del: "bg-[color:var(--color-diff-del-bg)] text-primary",
105
+ hunk: "bg-[color:var(--color-diff-hunk-bg)] text-disabled",
106
+ meta: "text-disabled",
107
+ context: "text-secondary"
108
+ };
109
+ var GUTTER_CLS = {
110
+ add: "text-success",
111
+ del: "text-accent",
112
+ hunk: "text-disabled",
113
+ meta: "text-disabled",
114
+ context: "text-disabled"
115
+ };
116
+ /**
117
+ * The colored diff body for one file. Each physical line becomes a row with a
118
+ * `+`/`-`/` ` gutter and a line-level background tint (add=green, del=red, hunk
119
+ * de-emphasized). Long lines DON'T wrap — the pane scrolls them horizontally
120
+ * (`overflow-x-auto min-w-0`) so a wide line never widens the page. Height is
121
+ * capped so a long diff scrolls inside its own box.
122
+ */
123
+ function DiffBody({ lines }) {
124
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
125
+ className: "min-w-0 max-h-[420px] overflow-auto border-t border-hairline bg-raised font-mono text-label leading-[1.55]",
126
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
127
+ className: "min-w-max",
128
+ children: lines.map((l, i) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
129
+ className: `flex ${LINE_CLS[l.kind]}`,
130
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
131
+ "aria-hidden": true,
132
+ className: `w-6 shrink-0 select-none pl-2.5 text-center ${GUTTER_CLS[l.kind]}`,
133
+ children: l.gutter
134
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
135
+ className: "whitespace-pre pr-4",
136
+ children: l.text || "\xA0"
137
+ })]
138
+ }, i))
139
+ })
140
+ });
141
+ }
142
+ /** One file row header — status word, path, size delta, and binary/too-large markers. */
143
+ function FileHead({ f, lines }) {
144
+ const delta = fmtDelta(f.sizeDelta);
145
+ const stat = lines ? diffStat(lines) : null;
146
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", {
147
+ className: "flex min-w-0 flex-wrap items-baseline gap-x-2.5 gap-y-1 text-meta",
148
+ children: [
149
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
150
+ className: `shrink-0 text-caption font-medium ${STATUS_CLS[f.status]}`,
151
+ children: STATUS_LABEL[f.status]
152
+ }),
153
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
154
+ className: "min-w-0 break-all font-mono text-primary",
155
+ children: f.path
156
+ }),
157
+ stat && (stat.added > 0 || stat.removed > 0) && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", {
158
+ className: "shrink-0 font-mono text-caption",
159
+ children: [
160
+ stat.added > 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", {
161
+ className: "text-success",
162
+ children: ["+", stat.added]
163
+ }),
164
+ stat.added > 0 && stat.removed > 0 && " ",
165
+ stat.removed > 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", {
166
+ className: "text-accent",
167
+ children: ["−", stat.removed]
168
+ })
169
+ ]
170
+ }),
171
+ delta && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
172
+ className: "shrink-0 font-mono text-caption text-disabled",
173
+ children: delta
174
+ }),
175
+ f.binary && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
176
+ className: "shrink-0 text-caption text-secondary",
177
+ children: "Binary"
178
+ }),
179
+ f.tooLarge && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
180
+ className: "shrink-0 text-caption text-secondary",
181
+ children: "Too large to diff"
182
+ })
183
+ ]
184
+ });
185
+ }
186
+ /** Small enough to auto-open; larger diffs start collapsed. */
187
+ var AUTO_OPEN_LINES = 40;
188
+ /**
189
+ * The Changes diff view — a list of changed files, each collapsible, its unified
190
+ * diff rendered as colored add/remove/context lines. Files with no inline diff
191
+ * (binary / oversize / too-large) render just the header row. Small diffs default
192
+ * open, large ones collapsed. Built entirely from theme tokens — no external diff
193
+ * library.
194
+ */
195
+ function DiffView({ files }) {
196
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
197
+ className: "space-y-1.5",
198
+ children: files.map((f) => {
199
+ if (!f.diff) return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
200
+ className: "rounded-control border border-hairline bg-surface px-3.5 py-2",
201
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(FileHead, {
202
+ f,
203
+ lines: null
204
+ })
205
+ }, f.path);
206
+ const lines = parseUnifiedDiff(f.diff);
207
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("details", {
208
+ open: lines.length <= AUTO_OPEN_LINES,
209
+ className: "group min-w-0 overflow-hidden rounded-control border border-hairline bg-surface",
210
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("summary", {
211
+ className: "flex cursor-pointer select-none items-center gap-2 px-3.5 py-2 marker:content-['']",
212
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
213
+ "aria-hidden": true,
214
+ className: "shrink-0 text-micro text-disabled transition-transform group-open:rotate-90",
215
+ children: "▸"
216
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(FileHead, {
217
+ f,
218
+ lines
219
+ })]
220
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(DiffBody, { lines })]
221
+ }, f.path);
222
+ })
223
+ });
224
+ }
225
+ /** A section card - mirrors the loop page's surface panels with a sentence-case
226
+ * section heading. `min-w-0` so wide inner content (a wide diff line)
227
+ * scrolls inside the card, never widens the page. */
228
+ function Card({ label, count, children }) {
229
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("section", {
230
+ className: "min-w-0 rounded-card border border-hairline bg-surface px-6 py-5 shadow-card",
231
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
232
+ className: `mb-3.5 border-b border-hairline pb-1.5 ${sectionHeadCls}`,
233
+ children: [label, count != null && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", {
234
+ className: "text-disabled",
235
+ children: [
236
+ " (",
237
+ count,
238
+ ")"
239
+ ]
240
+ })]
241
+ }), children]
242
+ });
243
+ }
244
+ /** A stacked key/value field for the metadata rail - a small label over its value. */
245
+ function Field({ k, children }) {
246
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
247
+ className: "min-w-0",
248
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
249
+ className: "mb-0.5 text-label font-medium text-secondary",
250
+ children: k
251
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
252
+ className: "min-w-0 text-body text-primary",
253
+ children
254
+ })]
255
+ });
256
+ }
257
+ /** Per-run artifact diff vs the previous run (Phase 3), rendered as a colored diff
258
+ * view. Lazy by runId; degrades to a calm fallback for runs with no snapshot. */
259
+ function Changes({ run }) {
260
+ const [data, setData] = (0, import_react.useState)(null);
261
+ (0, import_react.useEffect)(() => {
262
+ if (run.queued || run.running) return;
263
+ let alive = true;
264
+ getRunDiff({ data: { runId: run.id } }).then((d) => alive && setData(d)).catch(() => alive && setData({
265
+ hasSnapshot: false,
266
+ files: []
267
+ }));
268
+ return () => {
269
+ alive = false;
270
+ };
271
+ }, [
272
+ run.id,
273
+ run.queued,
274
+ run.running
275
+ ]);
276
+ if (run.queued || run.running) return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Card, {
277
+ label: "Changes",
278
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
279
+ className: "text-body text-disabled",
280
+ children: "File changes appear once the run finishes."
281
+ })
282
+ });
283
+ if (!data) return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Card, {
284
+ label: "Changes",
285
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Loading, {})
286
+ });
287
+ if (!data.hasSnapshot) return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Card, {
288
+ label: "Changes",
289
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
290
+ className: "text-body text-disabled",
291
+ children: "No file snapshot was recorded for this run."
292
+ })
293
+ });
294
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Card, {
295
+ label: "Changes",
296
+ count: data.files.length,
297
+ children: data.files.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
298
+ className: "text-body text-disabled",
299
+ children: "No files changed since the previous run."
300
+ }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(DiffView, { files: data.files })
301
+ });
302
+ }
303
+ function RunningState({ run }) {
304
+ const elapsed = dur(Math.max(0, Date.now() - Date.parse(run.ts)));
305
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Card, {
306
+ label: "Activity",
307
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
308
+ className: "flex items-center gap-2.5 text-body text-secondary",
309
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
310
+ "aria-hidden": true,
311
+ className: "size-2 shrink-0 rounded-full",
312
+ style: runPulseStyle
313
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { children: [
314
+ "Run in progress",
315
+ elapsed ? ` for ${elapsed}` : "",
316
+ "."
317
+ ] })]
318
+ })
319
+ });
320
+ }
321
+ function SessionId({ id }) {
322
+ const [copied, setCopied] = (0, import_react.useState)(false);
323
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("button", {
324
+ type: "button",
325
+ onClick: () => {
326
+ navigator.clipboard?.writeText(id);
327
+ setCopied(true);
328
+ setTimeout(() => setCopied(false), 1200);
329
+ },
330
+ title: "Copy session id",
331
+ className: "inline-flex max-w-full cursor-pointer items-center gap-1.5 border-none bg-transparent p-0 text-left font-mono text-label text-secondary transition-colors hover:text-display",
332
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
333
+ className: "truncate",
334
+ children: id
335
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
336
+ "aria-hidden": true,
337
+ className: "shrink-0 text-micro text-disabled",
338
+ children: copied ? "✓ copied" : "copy"
339
+ })]
340
+ });
341
+ }
342
+ /** How many older pages to walk back looking for a run not in the latest set
343
+ * (cursor paging via loadOlderRuns) before giving up — a safety bound so a bad
344
+ * runId can't page the whole history. 64 × 100/page covers very deep histories. */
345
+ var MAX_OLDER_PAGES = 64;
346
+ /**
347
+ * Run detail PAGE body — its own route (`/loops/$loopId/runs/$runId`). Resolves
348
+ * the run by id from the loop's detail payload (reusing getJobDetail, no new
349
+ * backend); a run older than that latest window is located by paging backward
350
+ * with the existing `loadOlderRuns` cursor fn. Self-polls while it's in flight.
351
+ *
352
+ * Layout mirrors the loop detail page: a header card (name / status pill / chips
353
+ * + action toolbar), then a two-column main — the meaty content (Changes diff +
354
+ * Execution trace + Report) in a wide `minmax(0,1fr)` column, the run metadata in
355
+ * a capped right rail. `min-w-0` everywhere + panes that scroll their own wide
356
+ * content keep the page free of horizontal scroll at any width.
357
+ */
358
+ function RunDetailView({ loopId, runId }) {
359
+ const [detail, setDetail] = (0, import_react.useState)(null);
360
+ const [olderRun, setOlderRun] = (0, import_react.useState)(null);
361
+ const [searchDone, setSearchDone] = (0, import_react.useState)(false);
362
+ const [err, setErr] = (0, import_react.useState)(null);
363
+ const load = (0, import_react.useCallback)(async () => {
364
+ try {
365
+ setDetail(await getJobDetail({ data: loopId }));
366
+ setErr(null);
367
+ } catch (e) {
368
+ setErr(String(e));
369
+ }
370
+ }, [loopId]);
371
+ const poll = (0, import_react.useCallback)(async () => {
372
+ try {
373
+ setDetail(await getJobDetail({ data: loopId }));
374
+ } catch {}
375
+ }, [loopId]);
376
+ (0, import_react.useEffect)(() => {
377
+ setDetail(null);
378
+ setOlderRun(null);
379
+ setSearchDone(false);
380
+ setErr(null);
381
+ load();
382
+ }, [
383
+ loopId,
384
+ runId,
385
+ load
386
+ ]);
387
+ const run = detail?.runs.find((r) => r.id === runId) ?? olderRun;
388
+ (0, import_react.useEffect)(() => {
389
+ if (!detail || run || searchDone) return;
390
+ let alive = true;
391
+ (async () => {
392
+ try {
393
+ let cursor = detail.runs.length ? detail.runs[detail.runs.length - 1].ts : (/* @__PURE__ */ new Date()).toISOString();
394
+ for (let i = 0; i < MAX_OLDER_PAGES && alive; i++) {
395
+ const page = await loadOlderRuns({ data: {
396
+ loopId,
397
+ beforeTs: cursor,
398
+ limit: 100
399
+ } });
400
+ if (!page.length) break;
401
+ const hit = page.find((r) => r.id === runId);
402
+ if (hit) {
403
+ if (alive) setOlderRun(hit);
404
+ return;
405
+ }
406
+ cursor = page[0].ts;
407
+ }
408
+ } finally {
409
+ if (alive) setSearchDone(true);
410
+ }
411
+ })();
412
+ return () => {
413
+ alive = false;
414
+ };
415
+ }, [
416
+ detail,
417
+ run,
418
+ searchDone,
419
+ loopId,
420
+ runId
421
+ ]);
422
+ const running = !!(run?.queued || run?.running);
423
+ (0, import_react.useEffect)(() => {
424
+ if (!running) return;
425
+ const t = setInterval(() => void poll(), 3e3);
426
+ return () => clearInterval(t);
427
+ }, [running, poll]);
428
+ async function onStop() {
429
+ if (!run) return;
430
+ if (!confirm("Stop this run? If it is running, Pievo will ask the daemon to terminate it.")) return;
431
+ const r = await stopRun({ data: run.id });
432
+ if (r?.error) {
433
+ alert(`Stop failed: ${r.error}`);
434
+ return;
435
+ }
436
+ await load();
437
+ }
438
+ if (err) return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(LoadErrorCard, {
439
+ title: "Couldn't load this run.",
440
+ detail: err,
441
+ onRetry: () => void load()
442
+ });
443
+ if (!detail || !run && !searchDone) return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Loading, {});
444
+ if (!run) return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
445
+ className: "rounded-card border border-hairline bg-surface px-6 py-10 text-center shadow-card",
446
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
447
+ className: "text-[14px] text-secondary",
448
+ children: "This run is no longer available."
449
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Link, {
450
+ to: "/loops/$loopId",
451
+ params: { loopId },
452
+ className: "mt-3 inline-block text-label font-medium text-interactive underline underline-offset-2 hover:text-display",
453
+ children: "← Back to the loop"
454
+ })]
455
+ });
456
+ const jobName = detail.summary.name;
457
+ const roleChip = run.role || null;
458
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("header", {
459
+ className: "rounded-card border border-hairline bg-surface px-6 pb-5 pt-[22px] shadow-card",
460
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
461
+ className: "flex flex-wrap items-start justify-between gap-x-6 gap-y-4",
462
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
463
+ className: "min-w-0",
464
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
465
+ className: "flex flex-wrap items-center gap-3",
466
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("h1", {
467
+ className: "text-[26px] font-medium leading-tight tracking-tight text-display",
468
+ children: ["Run · ", jobName]
469
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(StatusPill, {
470
+ run,
471
+ colorText: true
472
+ })]
473
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
474
+ className: "mt-2.5 flex flex-wrap items-center gap-x-2.5 gap-y-1.5 text-meta text-secondary",
475
+ children: [
476
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
477
+ className: "text-primary",
478
+ children: fmt(run.ts)
479
+ }),
480
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
481
+ className: "text-wire",
482
+ children: "·"
483
+ }),
484
+ roleChip && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Pill, { children: roleChip }),
485
+ run.durationMs != null && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Pill, {
486
+ tone: "ink",
487
+ children: dur(run.durationMs)
488
+ }),
489
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("code", {
490
+ className: "font-mono text-disabled",
491
+ children: run.id
492
+ })
493
+ ]
494
+ })]
495
+ })
496
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
497
+ className: "mt-5 flex flex-wrap gap-2.5 border-t border-hairline pt-4",
498
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Link, {
499
+ to: "/loops/$loopId",
500
+ params: { loopId },
501
+ className: btn,
502
+ children: "View the whole loop →"
503
+ }), (run.queued || run.running) && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", {
504
+ type: "button",
505
+ onClick: onStop,
506
+ className: btnDanger,
507
+ disabled: !!run.running && detail.machine.daemonProtocol !== 2,
508
+ title: run.running && detail.machine.daemonProtocol !== 2 ? "Daemon upgrade required to stop a running process. Run `npm install -g @kky42/pievo@latest`, then `pievo daemon restart`." : void 0,
509
+ children: "Stop run"
510
+ })]
511
+ })]
512
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
513
+ className: "mt-6 grid grid-cols-1 gap-6 lg:grid-cols-[minmax(0,1fr)_minmax(300px,360px)]",
514
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
515
+ className: "flex min-w-0 flex-col gap-6",
516
+ children: [
517
+ run.queued ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Card, {
518
+ label: "Activity",
519
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
520
+ className: "text-body text-secondary",
521
+ children: "Queued; it starts when this loop is free and the machine polls."
522
+ })
523
+ }) : run.running ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(RunningState, { run }) : null,
524
+ run.message && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Card, {
525
+ label: "Report",
526
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
527
+ className: "whitespace-pre-wrap break-words rounded-control border border-hairline bg-raised px-4 py-3.5 text-body leading-relaxed text-primary",
528
+ children: run.message
529
+ })
530
+ }),
531
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Changes, { run }),
532
+ run.control && run.control.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Card, {
533
+ label: "Control actions",
534
+ count: run.control.length,
535
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("ul", {
536
+ className: "space-y-1.5",
537
+ children: run.control.map((c, i) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("li", {
538
+ className: "flex flex-wrap items-baseline gap-x-2 gap-y-0.5 font-mono text-label",
539
+ children: [
540
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
541
+ className: "text-display",
542
+ children: c.command
543
+ }),
544
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
545
+ className: "min-w-0 break-all text-secondary",
546
+ children: JSON.stringify(c.args)
547
+ }),
548
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
549
+ "aria-hidden": true,
550
+ className: "text-wire",
551
+ children: "→"
552
+ }),
553
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
554
+ className: "text-primary",
555
+ children: c.result
556
+ }),
557
+ c.detail && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", {
558
+ className: "text-disabled",
559
+ children: [
560
+ "(",
561
+ c.detail,
562
+ ")"
563
+ ]
564
+ })
565
+ ]
566
+ }, i))
567
+ })
568
+ }),
569
+ run.finalText && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Card, {
570
+ label: "Final output",
571
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
572
+ className: "whitespace-pre-wrap break-words text-body text-primary",
573
+ children: run.finalText
574
+ })
575
+ })
576
+ ]
577
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
578
+ className: "flex min-w-0 flex-col gap-6",
579
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Card, {
580
+ label: "Details",
581
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
582
+ className: "space-y-3.5",
583
+ children: [
584
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Field, {
585
+ k: "State",
586
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(StatusPill, {
587
+ run,
588
+ colorText: true
589
+ })
590
+ }),
591
+ run.status && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Field, {
592
+ k: "Status",
593
+ children: run.status
594
+ }),
595
+ run.durationMs != null && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Field, {
596
+ k: "Duration",
597
+ children: dur(run.durationMs)
598
+ }),
599
+ run.exitCode != null && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Field, {
600
+ k: "Exit code",
601
+ children: run.exitCode
602
+ }),
603
+ run.usage && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Field, {
604
+ k: "Token usage",
605
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", {
606
+ className: "text-disabled",
607
+ children: [
608
+ fnum((run.usage.inputTokens ?? 0) + (run.usage.cacheReadTokens ?? 0) + (run.usage.cacheCreationTokens ?? 0)),
609
+ " in · ",
610
+ fnum(run.usage.outputTokens ?? 0),
611
+ " out"
612
+ ]
613
+ })
614
+ }),
615
+ run.state != null && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Field, {
616
+ k: "Run state",
617
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("code", {
618
+ className: "block break-all font-mono text-label text-secondary",
619
+ children: JSON.stringify(run.state)
620
+ })
621
+ }),
622
+ run.error && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Field, {
623
+ k: "Error",
624
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
625
+ className: "break-words",
626
+ style: { color: "var(--color-run-error)" },
627
+ children: run.error
628
+ })
629
+ }),
630
+ run.sessionId && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Field, {
631
+ k: "Session",
632
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SessionId, { id: run.sessionId })
633
+ })
634
+ ]
635
+ })
636
+ })
637
+ })]
638
+ })] });
639
+ }
640
+ /**
641
+ * Run detail PAGE — `/loops/$loopId/runs/$runId`. A standalone page (the trailing
642
+ * `_` on the `$loopId` segment opts it out of the loop page's component so the run
643
+ * gets its own full surface, deep-linkable + browser-back friendly) rather than a
644
+ * modal or an inline panel. It resolves the run from the loop's detail payload
645
+ * (reusing getJobDetail — no new backend) and reuses the Phase 3 artifact diff.
646
+ *
647
+ * Auth-gated like the dashboard (`/`) so a logged-out/expired DEEP LINK shows the
648
+ * sign-in CTA instead of a raw `loop not found` error from the blocked fetch.
649
+ */
650
+ function RunDetailPage() {
651
+ const { loopId, runId } = Route.useParams();
652
+ const { auth } = Route.useLoaderData() ?? { auth: { enabled: false } };
653
+ const { data: session, isPending } = useSession();
654
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("main", {
655
+ className: "mx-auto max-w-[1360px] px-8 pb-24 pt-10",
656
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
657
+ className: "mb-5",
658
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Link, {
659
+ to: "/loops/$loopId",
660
+ params: { loopId },
661
+ className: "inline-flex items-center gap-1.5 text-label font-medium text-secondary transition-colors hover:text-display",
662
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
663
+ "aria-hidden": true,
664
+ children: "←"
665
+ }), " Back to loop"]
666
+ })
667
+ }), auth?.enabled && !isPending && !session ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SignIn, { callbackURL: `/loops/${loopId}/runs/${runId}` }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(RunDetailView, {
668
+ loopId,
669
+ runId
670
+ })]
671
+ });
672
+ }
673
+ //#endregion
674
+ export { RunDetailPage as component };