@kky42/pievo-server 2.0.0 → 2.0.2

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 (83) hide show
  1. package/.output/nitro.json +1 -1
  2. package/.output/public/assets/{LoopView-d0XYkzpx.js → LoopView-XXW59HAV.js} +3 -3
  3. package/.output/public/assets/{Modal-D_od-AuP.js → Modal-BnCPgN_k.js} +1 -1
  4. package/.output/public/assets/{SignIn-CbMeIAJZ.js → SignIn-BAoOONQ9.js} +1 -1
  5. package/.output/public/assets/{actionUi-ChGGALzg.js → actionUi-Dxe9cHAc.js} +1 -1
  6. package/.output/public/assets/app-DzFILlbu.css +2 -0
  7. package/.output/public/assets/index-BtvLZjhl.js +12 -0
  8. package/.output/public/assets/{invite._token-DJtd-XE2.js → invite._token-BAqaXvte.js} +1 -1
  9. package/.output/public/assets/{invite._token-Cl9Oarnq.js → invite._token-q54LLZ6A.js} +1 -1
  10. package/.output/public/assets/{lifecycleUi-DGVOf5yS.js → lifecycleUi-B8Je9exd.js} +1 -1
  11. package/.output/public/assets/loops._loopId-BCK4oIRv.js +4 -0
  12. package/.output/public/assets/{loops._loopId_.runs._runId-DepMp3Me.js → loops._loopId_.runs._runId-lGYlHXTN.js} +2 -2
  13. package/.output/public/assets/notifyFns-BneSItOi.js +1 -0
  14. package/.output/public/assets/{routes-CTtlM_qt.js → routes-C7Pw5lGn.js} +1 -1
  15. package/.output/public/assets/{routes-BB4aDC1D.js → routes-D0zKR7gK.js} +1 -1
  16. package/.output/public/assets/{t._teamId-gR7BVKkR.js → t._teamId-CCgajlMS.js} +1 -1
  17. package/.output/public/assets/{t._teamId-D552b9PT.js → t._teamId-Cn7cRGAh.js} +1 -1
  18. package/.output/public/assets/ui-RFP3R3lU.js +1 -0
  19. package/.output/server/_ssr/{DashboardView-D3E-zevQ.mjs → DashboardView-BhJBW7IL.mjs} +13 -10
  20. package/.output/server/_ssr/{LoopPlaybook-DJlWGia5.mjs → LoopPlaybook-BC9Dvnw2.mjs} +2 -2
  21. package/.output/server/_ssr/{LoopView-BtMANpb_.mjs → LoopView-Dom6Ad5G.mjs} +4 -4
  22. package/.output/server/_ssr/{Modal-DpKZHLZK.mjs → Modal-CfWC9R49.mjs} +2 -2
  23. package/.output/server/_ssr/{SignIn-CjFonm71.mjs → SignIn-D70NUJsN.mjs} +3 -3
  24. package/.output/server/_ssr/{actionUi-CZbEixbf.mjs → actionUi-mDYOvJdB.mjs} +2 -2
  25. package/.output/server/_ssr/{adapters-vbuo_-wD.mjs → adapters-D0d1fBKK.mjs} +7 -4
  26. package/.output/server/_ssr/{artifactFiles-BGod8IWQ.mjs → artifactFiles-BfE1070_.mjs} +3 -3
  27. package/.output/server/_ssr/artifacts-CSGRJdSy.mjs +2 -0
  28. package/.output/server/_ssr/{auth-Ca-um-e8.mjs → auth-BP81awUE.mjs} +9 -9
  29. package/.output/server/_ssr/boot-pUGFIxSA.mjs +2 -0
  30. package/.output/server/_ssr/{boot-CkFZynUz.mjs → boot-sM4t8RJu.mjs} +148 -97
  31. package/.output/server/_ssr/{bun-sqlite-dialect-BW9W1_Ps-CG9VPNj0.mjs → bun-sqlite-dialect-BW9W1_Ps-CZJuWL5Z.mjs} +2 -2
  32. package/.output/server/_ssr/{d1-sqlite-dialect-BLC8LXE6-DBf7xVin.mjs → d1-sqlite-dialect-BLC8LXE6-C2PCtZfI.mjs} +2 -2
  33. package/.output/server/_ssr/db-Cc6I8bWL.mjs +2 -0
  34. package/.output/server/_ssr/{dist-CwI9FwLx.mjs → dist-Z7v6ihws.mjs} +2 -2
  35. package/.output/server/_ssr/{factory-L3gsmDL7.mjs → factory-BQ_XiP23.mjs} +2 -2
  36. package/.output/server/_ssr/{invite._token-DJxGLILJ.mjs → invite._token-23daBIfe.mjs} +2 -2
  37. package/.output/server/_ssr/{invite._token-CN2p7Gt3.mjs → invite._token-CRAl6-yK.mjs} +5 -5
  38. package/.output/server/_ssr/{invite._token-KLCPnHk-.mjs → invite._token-VKmyC9-R.mjs} +4 -4
  39. package/.output/server/_ssr/{kysely-adapter-Czkfz-W-.mjs → kysely-adapter-DjQPkqgJ.mjs} +1 -1
  40. package/.output/server/_ssr/{lifecycleUi-BhRsBvJ7.mjs → lifecycleUi-l3nx9i3T.mjs} +3 -3
  41. package/.output/server/_ssr/logger-CHoC5_kz.mjs +2 -0
  42. package/.output/server/_ssr/{loopApi-CVf9RC6s.mjs → loopApi-i7xdpokI.mjs} +11 -11
  43. package/.output/server/_ssr/{loops._loopId-CbuhuTAp.mjs → loops._loopId-DOPfN_Op.mjs} +43 -12
  44. package/.output/server/_ssr/{loops._loopId-gNSxIQBe.mjs → loops._loopId-jXSgPWG1.mjs} +3 -3
  45. package/.output/server/_ssr/{loops._loopId_.runs._runId-BptlCXat.mjs → loops._loopId_.runs._runId-BhoM6DWj.mjs} +3 -3
  46. package/.output/server/_ssr/{loops._loopId_.runs._runId-0MahUyHy.mjs → loops._loopId_.runs._runId-DiBP2rCe.mjs} +6 -6
  47. package/.output/server/_ssr/{machineFns-D5rQWyLl.mjs → machineFns-ChO1NM3C.mjs} +5 -3
  48. package/.output/server/_ssr/{node-sqlite-dialect-Dr9_QokR.mjs → node-sqlite-dialect-BGlhyZkk.mjs} +2 -2
  49. package/.output/server/_ssr/{notifyFns-BobPaLWi.mjs → notifyFns-B1MSIzrT.mjs} +3 -3
  50. package/.output/server/_ssr/{notifyFns-c7ZY2TWF.mjs → notifyFns-DWotltSJ.mjs} +35 -45
  51. package/.output/server/_ssr/{router-B8JTBtGd.mjs → router-BOHN4CWd.mjs} +29 -29
  52. package/.output/server/_ssr/{routes-B-MWifFy.mjs → routes-BQjhKV-m.mjs} +5 -5
  53. package/.output/server/_ssr/{routes-BJCWMIzb.mjs → routes-C2VJzARp.mjs} +5 -5
  54. package/.output/server/_ssr/{routes-Bcs4T1ox.mjs → routes-DjaTMZqZ.mjs} +2 -2
  55. package/.output/server/_ssr/{runDiff-C0w1D4a3.mjs → runDiff-SlGPjjNq.mjs} +2 -2
  56. package/.output/server/_ssr/ssr.mjs +48 -48
  57. package/.output/server/_ssr/store-BjXC623Z.mjs +2 -0
  58. package/.output/server/_ssr/{t._teamId-FYVEIAGw.mjs → t._teamId-CRgNlDGk.mjs} +5 -5
  59. package/.output/server/_ssr/{t._teamId-Dy_McbRt.mjs → t._teamId-D_vi_OuG.mjs} +2 -2
  60. package/.output/server/_ssr/{t._teamId-fw8RfHyI.mjs → t._teamId-o86wLJrg.mjs} +5 -5
  61. package/.output/server/_ssr/{teamFns-Dz41U7gA.mjs → teamFns-C3vnwAqv.mjs} +3 -3
  62. package/.output/server/_ssr/tokens-BCOvumer.mjs +2 -0
  63. package/.output/server/_ssr/{ui-Dej2qjuS.mjs → ui-WGITbP6Z.mjs} +72 -51
  64. package/.output/server/{_tanstack-start-manifest_v-C9p30TZH.mjs → _tanstack-start-manifest_v-DYC0z7st.mjs} +25 -25
  65. package/.output/server/drizzle/0012_blocked_run_status.sql +12 -0
  66. package/.output/server/drizzle/0013_drop_run_outcome.sql +2 -0
  67. package/.output/server/drizzle/meta/_journal.json +14 -0
  68. package/.output/server/index.mjs +105 -105
  69. package/drizzle/0012_blocked_run_status.sql +12 -0
  70. package/drizzle/0013_drop_run_outcome.sql +2 -0
  71. package/drizzle/meta/_journal.json +14 -0
  72. package/package.json +1 -1
  73. package/.output/public/assets/app-vKFxjMMk.css +0 -2
  74. package/.output/public/assets/index-DSF-1ahT.js +0 -12
  75. package/.output/public/assets/loops._loopId-B-dYxc9i.js +0 -4
  76. package/.output/public/assets/notifyFns-b_jCi5XK.js +0 -1
  77. package/.output/public/assets/ui-Dp88qUWh.js +0 -1
  78. package/.output/server/_ssr/artifacts-CduiDAM2.mjs +0 -2
  79. package/.output/server/_ssr/boot-C0f0HGCw.mjs +0 -2
  80. package/.output/server/_ssr/db-Cs0gnPZZ.mjs +0 -2
  81. package/.output/server/_ssr/logger-Cj1GFV_8.mjs +0 -2
  82. package/.output/server/_ssr/store-LYphMSJ-.mjs +0 -2
  83. package/.output/server/_ssr/tokens-3ZFpqsuf.mjs +0 -2
@@ -1,6 +1,6 @@
1
- import { n as DefaultQueryCompiler, o as CompiledQuery, s as sql$1 } from "./auth-Ca-um-e8.mjs";
1
+ import { n as DefaultQueryCompiler, o as CompiledQuery, s as sql$1 } from "./auth-BP81awUE.mjs";
2
2
  import { n as DEFAULT_MIGRATION_TABLE, t as DEFAULT_MIGRATION_LOCK_TABLE } from "./kysely-migration-tables-JkVUjPF_-bPAX9LR_.mjs";
3
- //#region node_modules/.nitro/vite/services/ssr/assets/bun-sqlite-dialect-BW9W1_Ps-CG9VPNj0.js
3
+ //#region node_modules/.nitro/vite/services/ssr/assets/bun-sqlite-dialect-BW9W1_Ps-CZJuWL5Z.js
4
4
  var BunSqliteAdapter = class {
5
5
  get supportsCreateIfNotExists() {
6
6
  return true;
@@ -1,6 +1,6 @@
1
- import { a as SqliteQueryCompiler, i as SqliteAdapter } from "./auth-Ca-um-e8.mjs";
1
+ import { a as SqliteQueryCompiler, i as SqliteAdapter } from "./auth-BP81awUE.mjs";
2
2
  import { n as DEFAULT_MIGRATION_TABLE, t as DEFAULT_MIGRATION_LOCK_TABLE } from "./kysely-migration-tables-JkVUjPF_-bPAX9LR_.mjs";
3
- //#region node_modules/.nitro/vite/services/ssr/assets/d1-sqlite-dialect-BLC8LXE6-DBf7xVin.js
3
+ //#region node_modules/.nitro/vite/services/ssr/assets/d1-sqlite-dialect-BLC8LXE6-C2PCtZfI.js
4
4
  var D1SqliteAdapter = class extends SqliteAdapter {};
5
5
  var D1SqliteDriver = class {
6
6
  #config;
@@ -0,0 +1,2 @@
1
+ import { j as db } from "./boot-sM4t8RJu.mjs";
2
+ export { db };
@@ -1,5 +1,5 @@
1
- import { _ as logger, o as createAdapterFactory } from "./factory-L3gsmDL7.mjs";
2
- //#region node_modules/.nitro/vite/services/ssr/assets/dist-CwI9FwLx.js
1
+ import { _ as logger, o as createAdapterFactory } from "./factory-BQ_XiP23.mjs";
2
+ //#region node_modules/.nitro/vite/services/ssr/assets/dist-Z7v6ihws.js
3
3
  /**
4
4
  * Case-insensitive in-memory comparison helpers.
5
5
  * Used when evaluating where clauses in the memory adapter.
@@ -1,5 +1,5 @@
1
- import { K as getEnvVar, L as env, a as BetterAuthError } from "./boot-CkFZynUz.mjs";
2
- //#region node_modules/.nitro/vite/services/ssr/assets/factory-L3gsmDL7.js
1
+ import { J as getEnvVar, a as BetterAuthError, z as env } from "./boot-sM4t8RJu.mjs";
2
+ //#region node_modules/.nitro/vite/services/ssr/assets/factory-BQ_XiP23.js
3
3
  var __defProp = Object.defineProperty;
4
4
  var __commonJSMin = (cb, mod) => () => (mod || (cb((mod = { exports: {} }).exports, mod), cb = null), mod.exports);
5
5
  var __exportAll = (all, no_symbols) => {
@@ -1,7 +1,7 @@
1
1
  import { g as require_jsx_runtime } from "../_libs/@base-ui/react+[...].mjs";
2
2
  import { f as useRouter } from "../_libs/@tanstack/react-router+[...].mjs";
3
- import { r as LoadErrorCard } from "./actionUi-CZbEixbf.mjs";
4
- //#region node_modules/.nitro/vite/services/ssr/assets/invite._token-DJxGLILJ.js
3
+ import { r as LoadErrorCard } from "./actionUi-mDYOvJdB.mjs";
4
+ //#region node_modules/.nitro/vite/services/ssr/assets/invite._token-23daBIfe.js
5
5
  var import_jsx_runtime = require_jsx_runtime();
6
6
  /**
7
7
  * Invite-link redeem (`/invite/<token>`, design §4 option B). The recipient opens
@@ -1,13 +1,13 @@
1
1
  import { o as __toESM } from "../_runtime.mjs";
2
2
  import { g as require_jsx_runtime, h as require_react } from "../_libs/@base-ui/react+[...].mjs";
3
- import { l as btnPrimary } from "./ui-Dej2qjuS.mjs";
3
+ import { l as btnPrimary } from "./ui-WGITbP6Z.mjs";
4
4
  import { d as useNavigate } from "../_libs/@tanstack/react-router+[...].mjs";
5
- import { i as PievoLogo, s as useSession } from "./LoopPlaybook-DJlWGia5.mjs";
5
+ import { i as PievoLogo, s as useSession } from "./LoopPlaybook-BC9Dvnw2.mjs";
6
6
  import { t as setActiveTeamCookie } from "./teamCookie-B7hLOIie.mjs";
7
7
  import { c as redeemTeamInvite } from "./teamFns-D4I-0dEB.mjs";
8
- import { t as Route } from "./invite._token-KLCPnHk-.mjs";
9
- import { t as SignIn } from "./SignIn-CjFonm71.mjs";
10
- //#region node_modules/.nitro/vite/services/ssr/assets/invite._token-CN2p7Gt3.js
8
+ import { t as Route } from "./invite._token-VKmyC9-R.mjs";
9
+ import { t as SignIn } from "./SignIn-D70NUJsN.mjs";
10
+ //#region node_modules/.nitro/vite/services/ssr/assets/invite._token-CRAl6-yK.js
11
11
  var import_react = /* @__PURE__ */ __toESM(require_react());
12
12
  var import_jsx_runtime = require_jsx_runtime();
13
13
  /**
@@ -1,9 +1,9 @@
1
1
  import { c as createFileRoute, s as lazyRouteComponent } from "../_libs/@tanstack/react-router+[...].mjs";
2
2
  import { c as getAuthState } from "./loopApi-BfMnXaKT.mjs";
3
- import { a as authClient } from "./LoopPlaybook-DJlWGia5.mjs";
4
- //#region node_modules/.nitro/vite/services/ssr/assets/invite._token-KLCPnHk-.js
5
- var $$splitErrorComponentImporter = () => import("./invite._token-DJxGLILJ.mjs");
6
- var $$splitComponentImporter = () => import("./invite._token-CN2p7Gt3.mjs");
3
+ import { a as authClient } from "./LoopPlaybook-BC9Dvnw2.mjs";
4
+ //#region node_modules/.nitro/vite/services/ssr/assets/invite._token-VKmyC9-R.js
5
+ var $$splitErrorComponentImporter = () => import("./invite._token-23daBIfe.mjs");
6
+ var $$splitComponentImporter = () => import("./invite._token-CRAl6-yK.mjs");
7
7
  /**
8
8
  * Invite-link redeem (`/invite/<token>`, design §4 option B). The recipient opens
9
9
  * the link the owner shared; if signed out (under the gate) they hit the normal
@@ -1,2 +1,2 @@
1
- import { r as kyselyAdapter, t as createKyselyAdapter } from "./auth-Ca-um-e8.mjs";
1
+ import { r as kyselyAdapter, t as createKyselyAdapter } from "./auth-BP81awUE.mjs";
2
2
  export { createKyselyAdapter, kyselyAdapter };
@@ -1,4 +1,4 @@
1
- //#region node_modules/.nitro/vite/services/ssr/assets/lifecycleUi-BhRsBvJ7.js
1
+ //#region node_modules/.nitro/vite/services/ssr/assets/lifecycleUi-l3nx9i3T.js
2
2
  var DAEMON_UPGRADE_REQUIRED = "Daemon upgrade required to stop a running process. Run `npm install -g @kky42/pievo@latest`, then `pievo daemon restart`.";
3
3
  /** Derive product lifecycle state only from durable server facts. */
4
4
  function deriveLoopLifecycle(job) {
@@ -29,8 +29,8 @@ function lifecycleDisplay(detail) {
29
29
  case "completed": return "Completed";
30
30
  case "deleting": return "Deleting";
31
31
  case "stopping": return "Stopping";
32
- case "paused-finishing": return detail.summary.pauseCause?.kind === "owner" ? "Paused by owner · current run finishing" : "Paused · current run finishing";
33
- case "paused": return detail.summary.pauseCause?.kind === "failure-streak" ? "Paused automatically" : detail.summary.pauseCause?.kind === "owner" ? "Paused by owner" : "Paused";
32
+ case "paused-finishing": return detail.summary.pauseCause?.kind === "blocked" ? "Paused — blocked · current run finishing" : detail.summary.pauseCause?.kind === "owner" ? "Paused by owner · current run finishing" : "Paused · current run finishing";
33
+ case "paused": return detail.summary.pauseCause?.kind === "blocked" ? "Paused — blocked" : detail.summary.pauseCause?.kind === "failure-streak" ? "Paused automatically" : detail.summary.pauseCause?.kind === "owner" ? "Paused by owner" : "Paused";
34
34
  case "active": return "Active";
35
35
  }
36
36
  }
@@ -0,0 +1,2 @@
1
+ import { At as logger } from "./boot-sM4t8RJu.mjs";
2
+ export { logger };
@@ -1,9 +1,9 @@
1
- import { $t as updateLoop, Et as listTeamsForUser, F as ensureServer, Ft as pauseLoop, Ht as requestDeleteLoop, Jt as startLoop, Pt as normalizeProviderSetting, Qt as tryDeleteLoop, Ut as requestRunCancel, W as getChannel, X as getLoop, Yt as stopLoop, Z as getMachine, at as hasRunningRun, b as coerceUi, et as getRun, g as canEvolve, jt as machinePresence, nt as getTeam, rt as getTeamMember, v as coerceCodingAgent, wt as listRunsBefore, y as coerceStateSchema, yt as listLoops, z as forceDeleteLoop } from "./boot-CkFZynUz.mjs";
1
+ import { $ as getMachine, Dt as listRunsBefore, Gt as requestDeleteLoop, K as getChannel, Kt as requestRunCancel, L as ensureServer, Lt as normalizeProviderSetting, Pt as machinePresence, Q as getLoop, Qt as stopLoop, Rt as pauseLoop, St as listLoops, V as forceDeleteLoop, Zt as startLoop, _ as canEvolve, at as getTeamMember, b as coerceStateSchema, it as getTeam, kt as listTeamsForUser, nn as updateLoop, nt as getRun, st as hasRunningRun, tn as tryDeleteLoop, x as coerceUi, y as coerceCodingAgent } from "./boot-sM4t8RJu.mjs";
2
2
  import { n as createServerFn } from "./ssr.mjs";
3
- import { i as toRunSummary, n as toJobDetail, r as toJobSummary } from "./adapters-vbuo_-wD.mjs";
4
- import { canAccessLoop, requestScope } from "./auth-Ca-um-e8.mjs";
3
+ import { i as toRunSummary, n as toJobDetail, r as toJobSummary } from "./adapters-D0d1fBKK.mjs";
4
+ import { canAccessLoop, requestScope } from "./auth-BP81awUE.mjs";
5
5
  import { t as createServerRpc } from "./createServerRpc-BD8Xn_0_.mjs";
6
- //#region node_modules/.nitro/vite/services/ssr/assets/loopApi-CVf9RC6s.js
6
+ //#region node_modules/.nitro/vite/services/ssr/assets/loopApi-i7xdpokI.js
7
7
  var meta_default$6 = {
8
8
  name: "dependency-triage",
9
9
  label: "Dependency Triage",
@@ -135,7 +135,7 @@ var getAuthState_createServerFn_handler = createServerRpc({
135
135
  filename: "src/server/loopApi.ts"
136
136
  }, (opts) => getAuthState.__executeServer(opts));
137
137
  var getAuthState = createServerFn({ method: "GET" }).handler(getAuthState_createServerFn_handler, async () => {
138
- const { authEnabled } = await import("./auth-Ca-um-e8.mjs");
138
+ const { authEnabled } = await import("./auth-BP81awUE.mjs");
139
139
  return { enabled: authEnabled };
140
140
  });
141
141
  var getConfig_createServerFn_handler = createServerRpc({
@@ -244,7 +244,7 @@ var getArtifacts_createServerFn_handler = createServerRpc({
244
244
  var getArtifacts = createServerFn({ method: "GET" }).validator((d) => d).handler(getArtifacts_createServerFn_handler, async ({ data }) => {
245
245
  await backend();
246
246
  if (!await ownedLoop(data.loopId)) return [];
247
- const { listLoopArtifacts } = await import("./artifactFiles-BGod8IWQ.mjs");
247
+ const { listLoopArtifacts } = await import("./artifactFiles-BfE1070_.mjs");
248
248
  return listLoopArtifacts(data.loopId);
249
249
  });
250
250
  var getArtifact_createServerFn_handler = createServerRpc({
@@ -255,7 +255,7 @@ var getArtifact_createServerFn_handler = createServerRpc({
255
255
  var getArtifact = createServerFn({ method: "GET" }).validator((d) => d).handler(getArtifact_createServerFn_handler, async ({ data }) => {
256
256
  await backend();
257
257
  if (!await ownedLoop(data.loopId)) return { error: "file not found" };
258
- const { readLoopArtifact } = await import("./artifactFiles-BGod8IWQ.mjs");
258
+ const { readLoopArtifact } = await import("./artifactFiles-BfE1070_.mjs");
259
259
  return readLoopArtifact(data.loopId, data.path);
260
260
  });
261
261
  var getRunDiff_createServerFn_handler = createServerRpc({
@@ -274,7 +274,7 @@ var getRunDiff = createServerFn({ method: "GET" }).validator((d) => d).handler(g
274
274
  hasSnapshot: false,
275
275
  files: []
276
276
  };
277
- const { computeRunDiff } = await import("./runDiff-C0w1D4a3.mjs");
277
+ const { computeRunDiff } = await import("./runDiff-SlGPjjNq.mjs");
278
278
  return computeRunDiff(data.runId);
279
279
  });
280
280
  var listTemplates_createServerFn_handler = createServerRpc({
@@ -389,7 +389,7 @@ var deleteJob = createServerFn({ method: "POST" }).validator((id) => id).handler
389
389
  if (!await requestDeleteLoop(id)) return { error: "not found" };
390
390
  if (unreachable && mayRetireAuthority) {
391
391
  if (!await forceDeleteLoop(id)) return { error: "delete failed; server data was not deleted" };
392
- const { logger } = await import("./logger-Cj1GFV_8.mjs");
392
+ const { logger } = await import("./logger-CHoC5_kz.mjs");
393
393
  logger.child({ mod: "loop-lifecycle" }).warn({
394
394
  action: "unreachable-delete",
395
395
  loopId: id,
@@ -429,7 +429,7 @@ var forceDeleteJob = createServerFn({ method: "POST" }).validator((d) => d).hand
429
429
  }
430
430
  scheduler.removeLoop(data.id);
431
431
  if (!await forceDeleteLoop(data.id)) return { error: "force delete failed; server data was not deleted" };
432
- const { logger } = await import("./logger-Cj1GFV_8.mjs");
432
+ const { logger } = await import("./logger-CHoC5_kz.mjs");
433
433
  logger.child({ mod: "loop-lifecycle" }).warn({
434
434
  action: "force-delete",
435
435
  loopId: data.id,
@@ -520,7 +520,7 @@ var mintClaim_createServerFn_handler = createServerRpc({
520
520
  }, (opts) => mintClaim.__executeServer(opts));
521
521
  var mintClaim = createServerFn({ method: "POST" }).validator((teamId) => teamId).handler(mintClaim_createServerFn_handler, async ({ data: teamId }) => {
522
522
  await backend();
523
- const { mintDeviceToken, rememberConnectKey } = await import("./tokens-3ZFpqsuf.mjs");
523
+ const { mintDeviceToken, rememberConnectKey } = await import("./tokens-BCOvumer.mjs");
524
524
  const { userId, teamId: active } = await requestScope(teamId);
525
525
  const owner = userId ?? "shared";
526
526
  const token = mintDeviceToken();
@@ -1,18 +1,18 @@
1
1
  import { o as __toESM } from "../_runtime.mjs";
2
2
  import { g as require_jsx_runtime, h as require_react } from "../_libs/@base-ui/react+[...].mjs";
3
- import { c as CODING_AGENTS, ft as isTaskEntry, h as buildFileEntries } from "./boot-CkFZynUz.mjs";
4
- import { A as selectCls, C as labelCls, E as rel, M as until, O as runPulseStyle, S as isCompleted, _ as fmt, b as inputCls, c as btnDanger, d as btnQuiet, g as dur, h as dotLabel, i as Pre, j as tsShort, k as sectionHeadCls, l as btnPrimary, m as dotColor, n as Loading, o as btn, p as cronText, r as Pill, s as btnCost, t as ErrorBanner, x as isClosed, y as humanBytes } from "./ui-Dej2qjuS.mjs";
3
+ import { c as CODING_AGENTS, g as buildFileEntries, ht as isTaskEntry } from "./boot-sM4t8RJu.mjs";
4
+ import { A as sectionHeadCls, C as isCompleted, D as rel, M as tsShort, N as until, S as isClosed, _ as dur, b as humanBytes, c as btnDanger, d as btnQuiet, h as dotLabel, i as Pre, j as selectCls, k as runPulseStyle, l as btnPrimary, m as dotColor, n as Loading, o as btn, p as cronText, r as Pill, s as btnCost, t as ErrorBanner, v as fmt, w as labelCls, x as inputCls } from "./ui-WGITbP6Z.mjs";
5
5
  import { d as useNavigate, u as Link } from "../_libs/@tanstack/react-router+[...].mjs";
6
6
  import { C as stopJob, S as startJob, a as evolveJob, b as requestEdit, d as getJobDetail, g as loadOlderRuns, i as deleteJob, s as getArtifacts, v as patchJob, x as runJob, y as pauseJob } from "./loopApi-BfMnXaKT.mjs";
7
7
  import { n as TaskFileView, r as ViewerHead, t as ArtifactBody } from "./artifactView-CYV1r48i.mjs";
8
- import { s as useSession } from "./LoopPlaybook-DJlWGia5.mjs";
8
+ import { i as useFlash, n as FlashLine, r as LoadErrorCard, t as ConfirmBar } from "./actionUi-mDYOvJdB.mjs";
9
+ import { s as useSession } from "./LoopPlaybook-BC9Dvnw2.mjs";
9
10
  import { t as setActiveTeamCookie } from "./teamCookie-B7hLOIie.mjs";
10
- import { t as SignIn } from "./SignIn-CjFonm71.mjs";
11
- import { i as useFlash, n as FlashLine, r as LoadErrorCard, t as ConfirmBar } from "./actionUi-CZbEixbf.mjs";
12
- import { i as lifecycleDisplay, n as daemonStopSupport, r as deriveLoopLifecycle, t as DAEMON_UPGRADE_REQUIRED } from "./lifecycleUi-BhRsBvJ7.mjs";
13
- import { a as listChannels, n as Timeline, s as mergeRuns, t as MachinesModal } from "./notifyFns-c7ZY2TWF.mjs";
14
- import { t as Route } from "./loops._loopId-gNSxIQBe.mjs";
15
- //#region node_modules/.nitro/vite/services/ssr/assets/loops._loopId-CbuhuTAp.js
11
+ import { t as SignIn } from "./SignIn-D70NUJsN.mjs";
12
+ import { i as lifecycleDisplay, n as daemonStopSupport, r as deriveLoopLifecycle, t as DAEMON_UPGRADE_REQUIRED } from "./lifecycleUi-l3nx9i3T.mjs";
13
+ import { a as listChannels, n as Timeline, s as mergeRuns, t as MachinesModal } from "./notifyFns-DWotltSJ.mjs";
14
+ import { t as Route } from "./loops._loopId-jXSgPWG1.mjs";
15
+ //#region node_modules/.nitro/vite/services/ssr/assets/loops._loopId-DOPfN_Op.js
16
16
  var import_react = /* @__PURE__ */ __toESM(require_react());
17
17
  var import_jsx_runtime = require_jsx_runtime();
18
18
  /**
@@ -556,7 +556,7 @@ var EDIT_SEEDS = [
556
556
  seed: "Give this loop a goal, and finish it once the goal is met: "
557
557
  }
558
558
  ];
559
- var LoopView = (0, import_react.lazy)(() => import("./LoopView-BtMANpb_.mjs").then((m) => ({ default: m.LoopView })));
559
+ var LoopView = (0, import_react.lazy)(() => import("./LoopView-Dom6Ad5G.mjs").then((m) => ({ default: m.LoopView })));
560
560
  /**
561
561
  * Loop detail PAGE body (`/loops/$loopId`) — the redesign of the former modal.
562
562
  * One scrolling page: a loop header (name / status / schedule / agent / machine +
@@ -1005,6 +1005,36 @@ function LoopDetailView({ id }) {
1005
1005
  })
1006
1006
  ]
1007
1007
  });
1008
+ const needsUpdateEl = detail.machine.needsUpdate && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
1009
+ className: "mb-2.5 flex flex-wrap items-center gap-x-3 gap-y-1.5 rounded-control border border-warn/40 bg-warn/10 px-4 py-2.5",
1010
+ children: [
1011
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", {
1012
+ className: "inline-flex items-center gap-2 text-meta font-medium text-primary",
1013
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
1014
+ "aria-hidden": true,
1015
+ className: "size-2 rounded-full bg-warn"
1016
+ }), "Daemon update required"]
1017
+ }),
1018
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", {
1019
+ className: "text-meta text-secondary",
1020
+ children: [
1021
+ "This server requires v",
1022
+ detail.machine.requiredDaemonVersion,
1023
+ "; ",
1024
+ detail.machine.name ? `“${detail.machine.name}”` : "the bound machine",
1025
+ " reports ",
1026
+ detail.machine.daemonVersion ? `v${detail.machine.daemonVersion}` : "an unknown version",
1027
+ ". Queued work will wait."
1028
+ ]
1029
+ }),
1030
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", {
1031
+ type: "button",
1032
+ onClick: () => setMachinesOpen(true),
1033
+ className: "ml-auto cursor-pointer text-meta font-medium text-interactive underline underline-offset-2 transition-colors hover:text-display",
1034
+ children: "Update daemon"
1035
+ })
1036
+ ]
1037
+ });
1008
1038
  const offlineEl = !online && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
1009
1039
  className: "mb-2.5 flex flex-wrap items-center gap-x-3 gap-y-1.5 rounded-control border border-hairline bg-raised px-4 py-2.5",
1010
1040
  children: [
@@ -1190,7 +1220,7 @@ function LoopDetailView({ id }) {
1190
1220
  }),
1191
1221
  latestIncidentRun?.reportIncident && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
1192
1222
  className: "mt-2 text-body leading-snug text-secondary",
1193
- children: latestIncidentRun.outcome === "error" ? "Last run failed · Terminal report rejected" : "Last run telemetry warning · Terminal report rejected"
1223
+ children: latestIncidentRun.phase === "error" ? "Last run failed · Terminal report rejected" : "Last run telemetry warning · Terminal report rejected"
1194
1224
  })
1195
1225
  ]
1196
1226
  })
@@ -1198,6 +1228,7 @@ function LoopDetailView({ id }) {
1198
1228
  className: "mt-5 border-t border-hairline pt-4",
1199
1229
  children: [
1200
1230
  crossTeamEl,
1231
+ needsUpdateEl,
1201
1232
  offlineEl,
1202
1233
  actionErrEl,
1203
1234
  flashLine,
@@ -1249,7 +1280,7 @@ function LoopDetailView({ id }) {
1249
1280
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
1250
1281
  className: "font-medium",
1251
1282
  style: { color: dotColor(editRun) },
1252
- children: editRun.canceled ? "Edit canceled" : editRun.outcome === "error" ? "Edit failed" : "Edit applied"
1283
+ children: editRun.canceled ? "Edit canceled" : editRun.phase === "error" ? "Edit failed" : "Edit applied"
1253
1284
  }),
1254
1285
  editRun.error && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", {
1255
1286
  className: "truncate text-secondary",
@@ -1,8 +1,8 @@
1
1
  import { c as createFileRoute, s as lazyRouteComponent } from "../_libs/@tanstack/react-router+[...].mjs";
2
2
  import { c as getAuthState } from "./loopApi-BfMnXaKT.mjs";
3
- import { a as authClient } from "./LoopPlaybook-DJlWGia5.mjs";
4
- //#region node_modules/.nitro/vite/services/ssr/assets/loops._loopId-gNSxIQBe.js
5
- var $$splitComponentImporter = () => import("./loops._loopId-CbuhuTAp.mjs");
3
+ import { a as authClient } from "./LoopPlaybook-BC9Dvnw2.mjs";
4
+ //#region node_modules/.nitro/vite/services/ssr/assets/loops._loopId-jXSgPWG1.js
5
+ var $$splitComponentImporter = () => import("./loops._loopId-DOPfN_Op.mjs");
6
6
  /**
7
7
  * Loop detail PAGE — `/loops/$loopId`. The dedicated page that replaced the old
8
8
  * dashboard modal: a loop header + action toolbar, the unified Files panel (task
@@ -1,8 +1,8 @@
1
1
  import { c as createFileRoute, s as lazyRouteComponent } from "../_libs/@tanstack/react-router+[...].mjs";
2
2
  import { c as getAuthState } from "./loopApi-BfMnXaKT.mjs";
3
- import { a as authClient } from "./LoopPlaybook-DJlWGia5.mjs";
4
- //#region node_modules/.nitro/vite/services/ssr/assets/loops._loopId_.runs._runId-BptlCXat.js
5
- var $$splitComponentImporter = () => import("./loops._loopId_.runs._runId-0MahUyHy.mjs");
3
+ import { a as authClient } from "./LoopPlaybook-BC9Dvnw2.mjs";
4
+ //#region node_modules/.nitro/vite/services/ssr/assets/loops._loopId_.runs._runId-BhoM6DWj.js
5
+ var $$splitComponentImporter = () => import("./loops._loopId_.runs._runId-DiBP2rCe.mjs");
6
6
  /**
7
7
  * Run detail PAGE — `/loops/$loopId/runs/$runId`. A standalone page (the trailing
8
8
  * `_` on the `$loopId` segment opts it out of the loop page's component so the run
@@ -1,13 +1,13 @@
1
1
  import { o as __toESM } from "../_runtime.mjs";
2
2
  import { g as require_jsx_runtime, h 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";
3
+ import { A as sectionHeadCls, _ as dur, a as StatusPill, b as humanBytes, c as btnDanger, k as runPulseStyle, n as Loading, o as btn, r as Pill, v as fmt, y as fnum } from "./ui-WGITbP6Z.mjs";
4
4
  import { u as Link } from "../_libs/@tanstack/react-router+[...].mjs";
5
5
  import { d as getJobDetail, f as getRunDiff, g as loadOlderRuns, w as stopRun } from "./loopApi-BfMnXaKT.mjs";
6
- import { s as useSession } from "./LoopPlaybook-DJlWGia5.mjs";
7
- import { t as SignIn } from "./SignIn-CjFonm71.mjs";
8
- import { r as LoadErrorCard } from "./actionUi-CZbEixbf.mjs";
9
- import { t as Route } from "./loops._loopId_.runs._runId-BptlCXat.mjs";
10
- //#region node_modules/.nitro/vite/services/ssr/assets/loops._loopId_.runs._runId-0MahUyHy.js
6
+ import { r as LoadErrorCard } from "./actionUi-mDYOvJdB.mjs";
7
+ import { s as useSession } from "./LoopPlaybook-BC9Dvnw2.mjs";
8
+ import { t as SignIn } from "./SignIn-D70NUJsN.mjs";
9
+ import { t as Route } from "./loops._loopId_.runs._runId-BhoM6DWj.mjs";
10
+ //#region node_modules/.nitro/vite/services/ssr/assets/loops._loopId_.runs._runId-DiBP2rCe.js
11
11
  var import_react = /* @__PURE__ */ __toESM(require_react());
12
12
  var import_jsx_runtime = require_jsx_runtime();
13
13
  /**
@@ -1,6 +1,6 @@
1
- import { At as machineIdFromToken, D as createMachine$1, F as ensureServer, Mt as mintDeviceToken, N as deleteMachine$1, Z as getMachine, bt as listMachines$1, en as updateMachine, kt as loopsForMachine, qt as sha256, xt as listMachinesForTeam, zt as rememberConnectKey } from "./boot-CkFZynUz.mjs";
1
+ import { $ as getMachine, A as daemonNeedsUpdate, Ct as listMachines$1, F as deleteMachine$1, Ft as mintDeviceToken, Ht as rememberConnectKey, L as ensureServer, Mt as loopsForMachine, Nt as machineIdFromToken, O as createMachine$1, Xt as sha256, d as MIN_DAEMON_VERSION, rn as updateMachine, wt as listMachinesForTeam } from "./boot-sM4t8RJu.mjs";
2
2
  import { n as createServerFn } from "./ssr.mjs";
3
- import { requestScope } from "./auth-Ca-um-e8.mjs";
3
+ import { requestScope } from "./auth-BP81awUE.mjs";
4
4
  import { t as createServerRpc } from "./createServerRpc-BD8Xn_0_.mjs";
5
5
  //#region node_modules/.nitro/vite/services/ssr/assets/machineScope-2h-fcKmG.js
6
6
  /**
@@ -28,7 +28,7 @@ function tokenVisibleTo(m, scope) {
28
28
  return !scope.enforce || m.userId === scope.userId;
29
29
  }
30
30
  //#endregion
31
- //#region node_modules/.nitro/vite/services/ssr/assets/machineFns-D5rQWyLl.js
31
+ //#region node_modules/.nitro/vite/services/ssr/assets/machineFns-ChO1NM3C.js
32
32
  /**
33
33
  * Latest published @kky42/pievo version — a cached, fail-silent lookup of the
34
34
  * npm dist-tag `latest`, so the web can tell a user their daemon is outdated and
@@ -165,6 +165,8 @@ async function toSummary(m, scope) {
165
165
  daemonVersion: m.daemonVersion ?? null,
166
166
  daemonProtocol: m.daemonProtocol ?? null,
167
167
  latestDaemonVersion: latestDaemonVersion.get(),
168
+ needsUpdate: daemonNeedsUpdate(m.daemonVersion),
169
+ requiredDaemonVersion: MIN_DAEMON_VERSION,
168
170
  token: tokenVisibleTo(m, scope) ? m.token ?? null : null,
169
171
  loopCount: (await loopsForMachine(m.id)).length
170
172
  };
@@ -1,6 +1,6 @@
1
- import { n as DefaultQueryCompiler, o as CompiledQuery, s as sql$1 } from "./auth-Ca-um-e8.mjs";
1
+ import { n as DefaultQueryCompiler, o as CompiledQuery, s as sql$1 } from "./auth-BP81awUE.mjs";
2
2
  import { n as DEFAULT_MIGRATION_TABLE, t as DEFAULT_MIGRATION_LOCK_TABLE } from "./kysely-migration-tables-JkVUjPF_-bPAX9LR_.mjs";
3
- //#region node_modules/.nitro/vite/services/ssr/assets/node-sqlite-dialect-Dr9_QokR.js
3
+ //#region node_modules/.nitro/vite/services/ssr/assets/node-sqlite-dialect-BGlhyZkk.js
4
4
  var NodeSqliteAdapter = class {
5
5
  get supportsCreateIfNotExists() {
6
6
  return true;
@@ -1,8 +1,8 @@
1
- import { C as createChannel$1, F as ensureServer, W as getChannel, j as deleteChannel$1, s as CHANNELS, vt as listChannels$1 } from "./boot-CkFZynUz.mjs";
1
+ import { K as getChannel, L as ensureServer, N as deleteChannel$1, s as CHANNELS, w as createChannel$1, xt as listChannels$1 } from "./boot-sM4t8RJu.mjs";
2
2
  import { n as createServerFn } from "./ssr.mjs";
3
- import { requestScope } from "./auth-Ca-um-e8.mjs";
3
+ import { requestScope } from "./auth-BP81awUE.mjs";
4
4
  import { t as createServerRpc } from "./createServerRpc-BD8Xn_0_.mjs";
5
- //#region node_modules/.nitro/vite/services/ssr/assets/notifyFns-BobPaLWi.js
5
+ //#region node_modules/.nitro/vite/services/ssr/assets/notifyFns-B1MSIzrT.js
6
6
  /**
7
7
  * Notification-channel server functions. Channels are per-team push targets a
8
8
  * loop can route its run messages to. Secrets (bot token / chat id) live in the
@@ -1,12 +1,12 @@
1
1
  import { o as __toESM } from "../_runtime.mjs";
2
2
  import { a as TooltipTrigger, g as require_jsx_runtime, h as require_react, i as TooltipPortal, n as TooltipPopup, o as TooltipRoot, r as TooltipPositioner } from "../_libs/@base-ui/react+[...].mjs";
3
- import { jt as machinePresence } from "./boot-CkFZynUz.mjs";
4
- import { C as labelCls, D as runPulseAnim, E as rel, M as until, N as useHydrated, S as isCompleted, _ as fmt, b as inputCls, c as btnDanger, g as dur, h as dotLabel, l as btnPrimary, m as dotColor, o as btn, t as ErrorBanner } from "./ui-Dej2qjuS.mjs";
3
+ import { Pt as machinePresence, ut as isOutdated } from "./boot-sM4t8RJu.mjs";
4
+ import { C as isCompleted, D as rel, N as until, O as runPulseAnim, P as useHydrated, _ as dur, c as btnDanger, g as dotOpacity, h as dotLabel, l as btnPrimary, m as dotColor, o as btn, t as ErrorBanner, v as fmt, w as labelCls, x as inputCls } from "./ui-WGITbP6Z.mjs";
5
5
  import { n as createServerFn } from "./ssr.mjs";
6
6
  import { l as getConfig, r as createSsrRpc } from "./loopApi-BfMnXaKT.mjs";
7
- import { n as ModalHead, r as ModalSection, t as Modal } from "./Modal-DpKZHLZK.mjs";
8
- import { n as daemonStopSupport } from "./lifecycleUi-BhRsBvJ7.mjs";
9
- //#region node_modules/.nitro/vite/services/ssr/assets/notifyFns-c7ZY2TWF.js
7
+ import { n as ModalHead, r as ModalSection, t as Modal } from "./Modal-CfWC9R49.mjs";
8
+ import { n as daemonStopSupport } from "./lifecycleUi-l3nx9i3T.mjs";
9
+ //#region node_modules/.nitro/vite/services/ssr/assets/notifyFns-DWotltSJ.js
10
10
  var import_react = /* @__PURE__ */ __toESM(require_react());
11
11
  var import_jsx_runtime = require_jsx_runtime();
12
12
  /**
@@ -90,6 +90,7 @@ function RunSeg({ run, onClick }) {
90
90
  className: `${SEG} cursor-pointer transition-opacity hover:opacity-70`,
91
91
  style: {
92
92
  background: dotColor(run),
93
+ opacity: dotOpacity(run),
93
94
  ...run.running ? runPulseAnim : {}
94
95
  }
95
96
  }) }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TooltipPortal, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TooltipPositioner, {
@@ -198,45 +199,6 @@ function Timeline({ job, runs, total, onLoadMore, onPickRun }) {
198
199
  ]
199
200
  });
200
201
  }
201
- /**
202
- * Tiny semver comparison — just enough to decide "is the daemon older than the
203
- * latest published version?" for the web's update hint. No dependency; we only
204
- * need numeric-core ordering (major.minor.patch), and a pre-release is treated
205
- * as older than its release (a "0.9.0-rc.1" daemon is still behind "0.9.0").
206
- */
207
- /** Parse the leading numeric core `x.y.z` of a version, ignoring any pre-release
208
- * / build suffix. Returns null when it isn't a recognizable version. */
209
- function core(v) {
210
- const m = /^\s*v?(\d+)\.(\d+)\.(\d+)/.exec(v);
211
- if (!m) return null;
212
- return [
213
- Number(m[1]),
214
- Number(m[2]),
215
- Number(m[3])
216
- ];
217
- }
218
- /** Does `v` carry a pre-release suffix (e.g. "1.2.3-rc.1")? */
219
- function isPre(v) {
220
- return /^\s*v?\d+\.\d+\.\d+-/.test(v);
221
- }
222
- /**
223
- * `true` when `current` is strictly older than `latest`. Returns `false` on any
224
- * unparseable/equal/newer input — the hint is opt-in, so we only ever show it
225
- * when we can be confident the daemon is genuinely behind.
226
- */
227
- function isOutdated(current, latest) {
228
- if (!current || !latest) return false;
229
- const a = core(current);
230
- const b = core(latest);
231
- if (!a || !b) return false;
232
- for (let i = 0; i < 3; i++) {
233
- const ai = a[i];
234
- const bi = b[i];
235
- if (ai < bi) return true;
236
- if (ai > bi) return false;
237
- }
238
- return isPre(current) && !isPre(latest);
239
- }
240
202
  /** User-facing daemon commands. Public UX installs globally; PIEVO_CLI dev
241
203
  * overrides are invoked verbatim and never trigger a global npm install. */
242
204
  function daemonConnectCommand(origin, token, cli, customCli) {
@@ -518,7 +480,35 @@ function MachinesModal({ open, onClose, teamId }) {
518
480
  children: connectCmd(m.token, cliConfig.pievoCli, cliConfig.customCli)
519
481
  }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(CopyButton, { text: connectCmd(m.token, cliConfig.pievoCli, cliConfig.customCli) })]
520
482
  })] }),
521
- isOutdated(m.daemonVersion, m.latestDaemonVersion) && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
483
+ m.needsUpdate && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
484
+ className: "flex flex-col gap-1.5 rounded-control border border-warn/40 bg-warn/10 p-3",
485
+ children: [
486
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
487
+ className: "text-label font-medium text-primary",
488
+ children: "Daemon needs update before this server will dispatch runs."
489
+ }),
490
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
491
+ className: "text-label text-secondary",
492
+ children: [
493
+ "running ",
494
+ m.daemonVersion ? `v${m.daemonVersion}` : "unknown version",
495
+ " · required v",
496
+ m.requiredDaemonVersion
497
+ ]
498
+ }),
499
+ cliConfig ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
500
+ className: "flex items-start gap-2",
501
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("pre", {
502
+ className: "flex-1 overflow-x-auto whitespace-pre-wrap break-all rounded-control bg-display p-3 font-mono text-caption leading-relaxed text-paper",
503
+ children: daemonUpgradeCommand(cliConfig.pievoCli, cliConfig.customCli)
504
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(CopyButton, { text: daemonUpgradeCommand(cliConfig.pievoCli, cliConfig.customCli) })]
505
+ }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
506
+ className: "text-label text-secondary",
507
+ children: configErr ? "Could not load the upgrade command. Close and try again." : "Loading upgrade command…"
508
+ })
509
+ ]
510
+ }),
511
+ !m.needsUpdate && isOutdated(m.daemonVersion, m.latestDaemonVersion) && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
522
512
  className: "flex flex-col gap-1.5",
523
513
  children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
524
514
  className: "text-label text-secondary",