@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,266 @@
1
+ import { $t as updateMachine, At as machineIdFromToken, D as createMachine$1, F as ensureServer, Kt as sha256, Mt as mintDeviceToken, N as deleteMachine$1, Rt as rememberConnectKey, Z as getMachine, bt as listMachines$1, kt as loopsForMachine, xt as listMachinesForTeam } from "./boot-BbtG0ImW.mjs";
2
+ import { n as createServerFn } from "./ssr.mjs";
3
+ import { requestScope } from "./auth-DY1DuYZd.mjs";
4
+ import { t as createServerRpc } from "./createServerRpc-BD8Xn_0_.mjs";
5
+ //#region node_modules/.nitro/vite/services/ssr/assets/machineScope-2h-fcKmG.js
6
+ /**
7
+ * Whether a machine is visible/actionable in the request scope. Mirrors
8
+ * listMachines: open mode sees everything; otherwise the requester must own the
9
+ * machine or share the active team with its owner. `teamMachineIds` is a THUNK
10
+ * (the team set needs a DB join) invoked only after the owner check misses — the
11
+ * hot path (machineStatus polls every ~2.5s while the connect dialog is open,
12
+ * usually by the owner) pays no query.
13
+ */
14
+ function machineInScope(m, scope, teamMachineIds) {
15
+ if (!scope.enforce) return true;
16
+ if (!scope.userId) return false;
17
+ if (m.userId === scope.userId) return true;
18
+ return teamMachineIds().has(m.id);
19
+ }
20
+ /**
21
+ * Whether the machine's PLAINTEXT device token may be serialized to this
22
+ * requester. Owner-only under the gate — the token fully impersonates the
23
+ * machine, so even a teammate/admin who may see (or delete) the row gets
24
+ * `token: null`. Open mode keeps the v1 behavior (token shown, e.g. for the
25
+ * reconnect command).
26
+ */
27
+ function tokenVisibleTo(m, scope) {
28
+ return !scope.enforce || m.userId === scope.userId;
29
+ }
30
+ //#endregion
31
+ //#region node_modules/.nitro/vite/services/ssr/assets/machineFns-Dvr5ICUy.js
32
+ /**
33
+ * Latest published @kky42/pievo version — a cached, fail-silent lookup of the
34
+ * npm dist-tag `latest`, so the web can tell a user their daemon is outdated and
35
+ * show the exact update command.
36
+ *
37
+ * Zero-exec invariant: this is a plain HTTP GET against the public npm registry —
38
+ * the server runs no LLM and executes no user code. It NEVER surfaces an error:
39
+ * if npm is unreachable/slow/garbage, the cache simply stays as-is (undefined at
40
+ * first) and the web shows no update hint. Bounded timeout + ~1h in-memory cache
41
+ * so the machine-list hot path never blocks on the network.
42
+ *
43
+ * The fetch is injectable (mirroring the gateway's injectable notifier/blobStore)
44
+ * so tests need no network: construct a `LatestDaemonVersion` with a fake fetch
45
+ * and `now`, or call the pure `fetchNpmLatest` directly.
46
+ */
47
+ var NPM_URL = "https://registry.npmjs.org/@kky42/pievo";
48
+ var DEFAULT_TTL_MS = 3600 * 1e3;
49
+ var FETCH_TIMEOUT_MS = 4e3;
50
+ /**
51
+ * One npm `latest` read — bounded + fail-silent. Returns the version string or
52
+ * null (unreachable/timeout/malformed). Pure w.r.t. the injected fetch, so it's
53
+ * directly unit-testable with no network.
54
+ */
55
+ async function fetchNpmLatest(fetchImpl, timeoutMs = FETCH_TIMEOUT_MS) {
56
+ const ctrl = new AbortController();
57
+ const timer = setTimeout(() => ctrl.abort(), timeoutMs);
58
+ try {
59
+ const res = await fetchImpl(NPM_URL, {
60
+ headers: { accept: "application/vnd.npm.install-v1+json" },
61
+ signal: ctrl.signal
62
+ });
63
+ if (!res.ok) return null;
64
+ const latest = (await res.json())?.["dist-tags"]?.latest;
65
+ return typeof latest === "string" && latest.trim() ? latest.trim() : null;
66
+ } catch {
67
+ return null;
68
+ } finally {
69
+ clearTimeout(timer);
70
+ }
71
+ }
72
+ /**
73
+ * In-memory cached accessor. `get()` returns the currently cached value (null
74
+ * until the first successful fetch) and, when the cache is stale, kicks off a
75
+ * background refresh — it never blocks the caller and never throws. A single
76
+ * refresh is in-flight at a time (concurrent `get()`s share it).
77
+ */
78
+ var LatestDaemonVersion = class {
79
+ fetchImpl;
80
+ ttlMs;
81
+ now;
82
+ cached = null;
83
+ fetchedAt = 0;
84
+ inflight = null;
85
+ constructor(fetchImpl = fetch, ttlMs = DEFAULT_TTL_MS, now = Date.now) {
86
+ this.fetchImpl = fetchImpl;
87
+ this.ttlMs = ttlMs;
88
+ this.now = now;
89
+ }
90
+ /** Cached latest version, refreshing in the background when stale. Non-blocking. */
91
+ get() {
92
+ if (this.now() - this.fetchedAt >= this.ttlMs) this.refresh();
93
+ return this.cached;
94
+ }
95
+ /** Force a refresh and resolve with the (possibly unchanged) cached value.
96
+ * Await-able for tests; production callers use `get()`. Never throws. */
97
+ async refresh() {
98
+ if (this.inflight) return this.inflight;
99
+ this.inflight = (async () => {
100
+ const v = await fetchNpmLatest(this.fetchImpl);
101
+ this.fetchedAt = this.now();
102
+ if (v) this.cached = v;
103
+ return this.cached;
104
+ })();
105
+ try {
106
+ return await this.inflight;
107
+ } finally {
108
+ this.inflight = null;
109
+ }
110
+ }
111
+ };
112
+ /** Process-wide singleton the machine server fns read (fail-silent, cached). */
113
+ var latestDaemonVersion = new LatestDaemonVersion();
114
+ /**
115
+ * Machine management server functions. Connect flow (two acts):
116
+ * 1. createMachine() → mint a token, create a PENDING (unnamed) row, return
117
+ * {id, token}. The UI shows the connect command + "waiting…".
118
+ * 2. the daemon connects → poll records online + hostname/platform/arch. The
119
+ * UI polls machineStatus(id); once connected it shows the name field
120
+ * (prefilled with the hostname). finalizeMachine({id,name}) names it →
121
+ * it appears in the list. cancelMachine(id) drops a pending row.
122
+ *
123
+ * Scoping: when the auth gate is on, every fn requires a signed-in user, and a
124
+ * machine is visible/actionable only when the requester owns it, its owner is a
125
+ * member of the active team, or the scope is the admin "All teams" view (the
126
+ * same rule listMachines filters by). The PLAINTEXT device token is serialized
127
+ * ONLY to the machine's owner — it fully impersonates the machine (poll /
128
+ * create-loop / log), so a teammate who can see the row must never exfiltrate
129
+ * it. Open mode (gate off) keeps the shared workspace: everyone sees/manages
130
+ * all machines, tokens included. No workdir jail (fully open) for now.
131
+ */
132
+ /** Ids of the machines membership-visible in the scope's active team (the same
133
+ * set listMachines serves). Empty when the scope needs no team check (open
134
+ * mode or signed-out — machineInScope settles those before ever invoking its
135
+ * team-set thunk). */
136
+ async function teamMachineIds(scope) {
137
+ if (!scope.enforce || !scope.userId) return /* @__PURE__ */ new Set();
138
+ return new Set((await listMachinesForTeam(scope.teamId)).map((m) => m.id));
139
+ }
140
+ /**
141
+ * Resolve a machine and authorize it against the request scope (the machine-fn
142
+ * twin of loopApi's `ownedLoop`). `machine` is undefined when it's missing OR
143
+ * out of scope — callers treat both as "not found" so existence never leaks.
144
+ * The scope rides along so callers don't re-run requestScope (a second session
145
+ * decrypt); the team-set thunk keeps the owner fast path query-free.
146
+ */
147
+ async function scopedMachine(id) {
148
+ const scope = await requestScope();
149
+ const m = await getMachine(id);
150
+ const teamIds = await teamMachineIds(scope);
151
+ return {
152
+ scope,
153
+ machine: m && machineInScope(m, scope, () => teamIds) ? m : void 0
154
+ };
155
+ }
156
+ async function toSummary(m, scope) {
157
+ return {
158
+ id: m.id,
159
+ name: m.name,
160
+ online: !!m.online,
161
+ lastSeen: m.lastSeen ?? null,
162
+ hostname: m.hostname ?? null,
163
+ platform: m.platform ?? null,
164
+ arch: m.arch ?? null,
165
+ daemonVersion: m.daemonVersion ?? null,
166
+ daemonProtocol: m.daemonProtocol ?? null,
167
+ latestDaemonVersion: latestDaemonVersion.get(),
168
+ token: tokenVisibleTo(m, scope) ? m.token ?? null : null,
169
+ loopCount: (await loopsForMachine(m.id)).length
170
+ };
171
+ }
172
+ /** Named machines only (pending/unnamed rows are mid-connect). Scoped to the
173
+ * given/active team when the gate is on; the full shared list in open mode. An
174
+ * explicit `teamId` (the `/t/<id>` route) scopes this request independent of the
175
+ * cookie, so a tab on /t/A and one on /t/B list different machines at once. */
176
+ var listMachines_createServerFn_handler = createServerRpc({
177
+ id: "aa46310016bb8a58b273a648ffd498c87f1f450d12827e30110a3b83ba6a27d9",
178
+ name: "listMachines",
179
+ filename: "src/server/machineFns.ts"
180
+ }, (opts) => listMachines.__executeServer(opts));
181
+ var listMachines = createServerFn({ method: "GET" }).validator((teamId) => teamId).handler(listMachines_createServerFn_handler, async ({ data: teamId }) => {
182
+ await ensureServer();
183
+ const scope = await requestScope(teamId);
184
+ const { enforce, userId, teamId: active } = scope;
185
+ if (enforce && !userId) return [];
186
+ const list = enforce ? await listMachinesForTeam(active) : await listMachines$1();
187
+ return Promise.all(list.filter((m) => m.name.trim()).map((m) => toSummary(m, scope)));
188
+ });
189
+ var createMachine_createServerFn_handler = createServerRpc({
190
+ id: "ed679b4e1e05e903a5d4ba4a70d9b9d883991ab22ed59b4d2d69078941818415",
191
+ name: "createMachine",
192
+ filename: "src/server/machineFns.ts"
193
+ }, (opts) => createMachine.__executeServer(opts));
194
+ var createMachine = createServerFn({ method: "POST" }).validator((teamId) => teamId).handler(createMachine_createServerFn_handler, async ({ data: teamId }) => {
195
+ await ensureServer();
196
+ const { enforce, userId, teamId: active } = await requestScope(teamId);
197
+ if (enforce && !userId) return { error: "not signed in" };
198
+ const token = mintDeviceToken();
199
+ const id = machineIdFromToken(token);
200
+ const owner = userId ?? "shared";
201
+ await rememberConnectKey(token, {
202
+ userId: owner,
203
+ teamId: active
204
+ });
205
+ await createMachine$1({
206
+ id,
207
+ userId: owner,
208
+ teamId: active,
209
+ name: "",
210
+ tokenHash: sha256(token),
211
+ token,
212
+ online: false
213
+ });
214
+ return {
215
+ id,
216
+ token
217
+ };
218
+ });
219
+ var machineStatus_createServerFn_handler = createServerRpc({
220
+ id: "169566e7637a22599b4eb32ee3775574e99677406922bbef7482a102036c33dd",
221
+ name: "machineStatus",
222
+ filename: "src/server/machineFns.ts"
223
+ }, (opts) => machineStatus.__executeServer(opts));
224
+ var machineStatus = createServerFn({ method: "GET" }).validator((id) => id).handler(machineStatus_createServerFn_handler, async ({ data: id }) => {
225
+ await ensureServer();
226
+ const { scope, machine } = await scopedMachine(id);
227
+ return machine ? toSummary(machine, scope) : null;
228
+ });
229
+ var finalizeMachine_createServerFn_handler = createServerRpc({
230
+ id: "27d7eba0b6a2257949392fdd56057275a5c5366484ae01faf3b5897a225ecd83",
231
+ name: "finalizeMachine",
232
+ filename: "src/server/machineFns.ts"
233
+ }, (opts) => finalizeMachine.__executeServer(opts));
234
+ var finalizeMachine = createServerFn({ method: "POST" }).validator((d) => d).handler(finalizeMachine_createServerFn_handler, async ({ data }) => {
235
+ await ensureServer();
236
+ const name = data.name?.trim();
237
+ if (!name) return { ok: false };
238
+ const { machine } = await scopedMachine(data.id);
239
+ if (!machine) return { ok: false };
240
+ return { ok: !!await updateMachine(data.id, { name }) };
241
+ });
242
+ var deleteMachine_createServerFn_handler = createServerRpc({
243
+ id: "a6384dc7154d9930422d29396f5de64b3ac69c62ad3824bc4a22d745fc07b293",
244
+ name: "deleteMachine",
245
+ filename: "src/server/machineFns.ts"
246
+ }, (opts) => deleteMachine.__executeServer(opts));
247
+ var deleteMachine = createServerFn({ method: "POST" }).validator((id) => id).handler(deleteMachine_createServerFn_handler, async ({ data: id }) => {
248
+ await ensureServer();
249
+ const { scope, machine } = await scopedMachine(id);
250
+ if (scope.enforce && !scope.userId) return {
251
+ ok: false,
252
+ error: "unauthorized"
253
+ };
254
+ if (!machine) return {
255
+ ok: false,
256
+ error: "machine not found"
257
+ };
258
+ const loops = await loopsForMachine(id);
259
+ if (loops.length > 0) return {
260
+ ok: false,
261
+ error: `This machine still has ${loops.length} loop${loops.length === 1 ? "" : "s"} — delete ${loops.length === 1 ? "it" : "them"} first.`
262
+ };
263
+ return { ok: await deleteMachine$1(id) };
264
+ });
265
+ //#endregion
266
+ export { createMachine_createServerFn_handler, deleteMachine_createServerFn_handler, finalizeMachine_createServerFn_handler, listMachines_createServerFn_handler, machineStatus_createServerFn_handler };
@@ -0,0 +1,162 @@
1
+ import { n as DefaultQueryCompiler, o as CompiledQuery, s as sql$1 } from "./auth-DY1DuYZd.mjs";
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-DhyOpJTX.js
4
+ var NodeSqliteAdapter = class {
5
+ get supportsCreateIfNotExists() {
6
+ return true;
7
+ }
8
+ get supportsTransactionalDdl() {
9
+ return false;
10
+ }
11
+ get supportsMultipleConnections() {
12
+ return false;
13
+ }
14
+ get supportsReturning() {
15
+ return true;
16
+ }
17
+ async acquireMigrationLock() {}
18
+ async releaseMigrationLock() {}
19
+ get supportsOutput() {
20
+ return true;
21
+ }
22
+ };
23
+ var NodeSqliteDriver = class {
24
+ #config;
25
+ #connectionMutex = new ConnectionMutex();
26
+ #db;
27
+ #connection;
28
+ constructor(config) {
29
+ this.#config = { ...config };
30
+ }
31
+ async init() {
32
+ this.#db = this.#config.database;
33
+ this.#connection = new NodeSqliteConnection(this.#db);
34
+ if (this.#config.onCreateConnection) await this.#config.onCreateConnection(this.#connection);
35
+ }
36
+ async acquireConnection() {
37
+ await this.#connectionMutex.lock();
38
+ return this.#connection;
39
+ }
40
+ async beginTransaction(connection) {
41
+ await connection.executeQuery(CompiledQuery.raw("begin"));
42
+ }
43
+ async commitTransaction(connection) {
44
+ await connection.executeQuery(CompiledQuery.raw("commit"));
45
+ }
46
+ async rollbackTransaction(connection) {
47
+ await connection.executeQuery(CompiledQuery.raw("rollback"));
48
+ }
49
+ async releaseConnection() {
50
+ this.#connectionMutex.unlock();
51
+ }
52
+ async destroy() {
53
+ this.#db?.close();
54
+ }
55
+ };
56
+ var NodeSqliteConnection = class {
57
+ #db;
58
+ constructor(db) {
59
+ this.#db = db;
60
+ }
61
+ executeQuery(compiledQuery) {
62
+ const { sql, parameters } = compiledQuery;
63
+ const stmt = this.#db.prepare(sql);
64
+ const params = parameters;
65
+ if (stmt.columns().length > 0) return Promise.resolve({ rows: stmt.all(...params) });
66
+ const { changes, lastInsertRowid } = stmt.run(...params);
67
+ return Promise.resolve({
68
+ rows: [],
69
+ numAffectedRows: BigInt(changes),
70
+ insertId: typeof lastInsertRowid === "bigint" ? lastInsertRowid : BigInt(lastInsertRowid)
71
+ });
72
+ }
73
+ async *streamQuery() {
74
+ throw new Error("Streaming query is not supported by SQLite driver.");
75
+ }
76
+ };
77
+ var ConnectionMutex = class {
78
+ #promise;
79
+ #resolve;
80
+ async lock() {
81
+ while (this.#promise !== void 0) await this.#promise;
82
+ this.#promise = new Promise((resolve) => {
83
+ this.#resolve = resolve;
84
+ });
85
+ }
86
+ unlock() {
87
+ const resolve = this.#resolve;
88
+ this.#promise = void 0;
89
+ this.#resolve = void 0;
90
+ resolve?.();
91
+ }
92
+ };
93
+ var NodeSqliteIntrospector = class {
94
+ #db;
95
+ constructor(db) {
96
+ this.#db = db;
97
+ }
98
+ async getSchemas() {
99
+ return [];
100
+ }
101
+ async getTables(options = { withInternalKyselyTables: false }) {
102
+ let query = this.#db.selectFrom("sqlite_schema").where("type", "=", "table").where("name", "not like", "sqlite_%").select("name").$castTo();
103
+ if (!options.withInternalKyselyTables) query = query.where("name", "!=", DEFAULT_MIGRATION_TABLE).where("name", "!=", DEFAULT_MIGRATION_LOCK_TABLE);
104
+ const tables = await query.execute();
105
+ return Promise.all(tables.map(({ name }) => this.#getTableMetadata(name)));
106
+ }
107
+ async #getTableMetadata(table) {
108
+ const db = this.#db;
109
+ const autoIncrementCol = (await db.selectFrom("sqlite_master").where("name", "=", table).select("sql").$castTo().execute())[0]?.sql?.split(/[\(\),]/)?.find((it) => it.toLowerCase().includes("autoincrement"))?.split(/\s+/)?.[0]?.replace(/["`]/g, "");
110
+ return {
111
+ name: table,
112
+ columns: (await db.selectFrom(sql$1`pragma_table_info(${table})`.as("table_info")).select([
113
+ "name",
114
+ "type",
115
+ "notnull",
116
+ "dflt_value"
117
+ ]).execute()).map((col) => ({
118
+ name: col.name,
119
+ dataType: col.type,
120
+ isNullable: !col.notnull,
121
+ isAutoIncrementing: col.name === autoIncrementCol,
122
+ hasDefaultValue: col.dflt_value != null
123
+ })),
124
+ isView: false,
125
+ isForeign: false
126
+ };
127
+ }
128
+ };
129
+ var NodeSqliteQueryCompiler = class extends DefaultQueryCompiler {
130
+ getCurrentParameterPlaceholder() {
131
+ return "?";
132
+ }
133
+ getLeftIdentifierWrapper() {
134
+ return "\"";
135
+ }
136
+ getRightIdentifierWrapper() {
137
+ return "\"";
138
+ }
139
+ getAutoIncrement() {
140
+ return "autoincrement";
141
+ }
142
+ };
143
+ var NodeSqliteDialect = class {
144
+ #config;
145
+ constructor(config) {
146
+ this.#config = { ...config };
147
+ }
148
+ createDriver() {
149
+ return new NodeSqliteDriver(this.#config);
150
+ }
151
+ createQueryCompiler() {
152
+ return new NodeSqliteQueryCompiler();
153
+ }
154
+ createAdapter() {
155
+ return new NodeSqliteAdapter();
156
+ }
157
+ createIntrospector(db) {
158
+ return new NodeSqliteIntrospector(db);
159
+ }
160
+ };
161
+ //#endregion
162
+ export { NodeSqliteDialect };
@@ -0,0 +1,118 @@
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-BbtG0ImW.mjs";
2
+ import { n as createServerFn } from "./ssr.mjs";
3
+ import { requestScope } from "./auth-DY1DuYZd.mjs";
4
+ import { t as createServerRpc } from "./createServerRpc-BD8Xn_0_.mjs";
5
+ //#region node_modules/.nitro/vite/services/ssr/assets/notifyFns-BcMRY5kP.js
6
+ /**
7
+ * Notification-channel server functions. Channels are per-team push targets a
8
+ * loop can route its run messages to. Secrets (bot token / chat id) live in the
9
+ * channel's `config` and are NEVER returned to the client — list/test surface
10
+ * only a redacted summary. Scoped to the request's team (see requestScope).
11
+ *
12
+ * Per-type behavior (validate / hint / send) lives in `CHANNELS` (gateway/notify);
13
+ * this module just wires it to auth + storage.
14
+ */
15
+ function toSummary(c) {
16
+ return {
17
+ id: c.id,
18
+ type: c.type,
19
+ name: c.name,
20
+ hint: CHANNELS[c.type]?.hint(c.config) ?? "—"
21
+ };
22
+ }
23
+ /** Resolve a channel and authorize it against the request's team — undefined when
24
+ * missing OR (gate on) owned by another team, so existence never leaks. Mirrors
25
+ * loopApi's ownedLoop for the channel routes. */
26
+ async function ownedChannel(id) {
27
+ const ch = await getChannel(id);
28
+ if (!ch) return void 0;
29
+ const { enforce, teamId } = await requestScope();
30
+ if (enforce && ch.teamId !== teamId) return void 0;
31
+ return ch;
32
+ }
33
+ /** GET — the team's channels (redacted summaries, newest first). */
34
+ var listChannels_createServerFn_handler = createServerRpc({
35
+ id: "ced5641f28e3e64d3b8773ea4c875b78ee305bd08caba90a2207e86ef1ab3327",
36
+ name: "listChannels",
37
+ filename: "src/server/notifyFns.ts"
38
+ }, (opts) => listChannels.__executeServer(opts));
39
+ var listChannels = createServerFn({ method: "GET" }).handler(listChannels_createServerFn_handler, async () => {
40
+ await ensureServer();
41
+ const { enforce, userId, teamId } = await requestScope();
42
+ if (enforce && !userId) return [];
43
+ return (await listChannels$1(teamId)).map(toSummary);
44
+ });
45
+ var createChannel_createServerFn_handler = createServerRpc({
46
+ id: "d6cb1ea6f7fdaf940fbbe91d6b0898a0d5ac2308f8bc572dc3b856824a1f4581",
47
+ name: "createChannel",
48
+ filename: "src/server/notifyFns.ts"
49
+ }, (opts) => createChannel.__executeServer(opts));
50
+ var createChannel = createServerFn({ method: "POST" }).validator((d) => d).handler(createChannel_createServerFn_handler, async ({ data }) => {
51
+ await ensureServer();
52
+ const { enforce, userId, teamId } = await requestScope();
53
+ if (enforce && !userId) return {
54
+ ok: false,
55
+ error: "not signed in"
56
+ };
57
+ const name = data.name?.trim();
58
+ if (!name) return {
59
+ ok: false,
60
+ error: "name required"
61
+ };
62
+ const kind = CHANNELS[data.type];
63
+ if (!kind) return {
64
+ ok: false,
65
+ error: "unknown channel type"
66
+ };
67
+ const cfg = data.config ?? {};
68
+ const missing = kind.required.filter((k) => !cfg[k]?.trim());
69
+ if (missing.length) return {
70
+ ok: false,
71
+ error: `${data.type} needs: ${missing.join(", ")}`
72
+ };
73
+ const keys = [...kind.required, ...kind.optional ?? []];
74
+ const config = Object.fromEntries(keys.filter((k) => cfg[k]?.trim()).map((k) => [k, cfg[k].trim()]));
75
+ const invalid = kind.validate?.(config);
76
+ if (invalid) return {
77
+ ok: false,
78
+ error: invalid
79
+ };
80
+ return {
81
+ ok: true,
82
+ id: (await createChannel$1({
83
+ teamId,
84
+ type: data.type,
85
+ name,
86
+ config
87
+ })).id
88
+ };
89
+ });
90
+ var deleteChannel_createServerFn_handler = createServerRpc({
91
+ id: "9defc1b5d0f4316d61621e2c4614a70dc052ad6b7a3aa2ead00836f7d5cb5b4c",
92
+ name: "deleteChannel",
93
+ filename: "src/server/notifyFns.ts"
94
+ }, (opts) => deleteChannel.__executeServer(opts));
95
+ var deleteChannel = createServerFn({ method: "POST" }).validator((id) => id).handler(deleteChannel_createServerFn_handler, async ({ data: id }) => {
96
+ await ensureServer();
97
+ if (!await ownedChannel(id)) return {
98
+ ok: false,
99
+ error: "channel not found"
100
+ };
101
+ return { ok: await deleteChannel$1(id) };
102
+ });
103
+ var testChannel_createServerFn_handler = createServerRpc({
104
+ id: "a4e3ae06af7087a3dc291236cf6d5ad272e2f754884c1f948e75a18a4ebada93",
105
+ name: "testChannel",
106
+ filename: "src/server/notifyFns.ts"
107
+ }, (opts) => testChannel.__executeServer(opts));
108
+ var testChannel = createServerFn({ method: "POST" }).validator((id) => id).handler(testChannel_createServerFn_handler, async ({ data: id }) => {
109
+ await ensureServer();
110
+ const ch = await ownedChannel(id);
111
+ if (!ch) return {
112
+ ok: false,
113
+ error: "channel not found"
114
+ };
115
+ return CHANNELS[ch.type].send(ch.config, ch.name, "Pievo test message — this channel is wired up. ✓");
116
+ });
117
+ //#endregion
118
+ export { createChannel_createServerFn_handler, deleteChannel_createServerFn_handler, listChannels_createServerFn_handler, testChannel_createServerFn_handler };