@kky42/pievo-server 2.4.11 → 2.4.13

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 (86) hide show
  1. package/.output/nitro.json +1 -1
  2. package/.output/public/assets/SignIn-CDCdDD1a.js +1 -0
  3. package/.output/public/assets/{ui-s5IMg6RF.js → actionUi-D8m1FDHO.js} +1 -1
  4. package/.output/public/assets/app-PPhgN9iN.css +2 -0
  5. package/.output/public/assets/index-c0XPWXuz.js +10 -0
  6. package/.output/public/assets/loops._loopId-D7i_BGiE.js +67 -0
  7. package/.output/public/assets/loops._loopId_.runs._runId-CksSrEY7.js +3 -0
  8. package/.output/public/assets/{preload-helper-Bs7oCAsw.js → preload-helper-Zcmr31XG.js} +3 -3
  9. package/.output/public/assets/routes-79D939J4.js +1 -0
  10. package/.output/public/assets/routes-BYgl3Tmv.js +1 -0
  11. package/.output/server/_libs/@tanstack/react-router+[...].mjs +1 -1
  12. package/.output/server/_ssr/{MachinesModal-BhRw7oOx.mjs → MachinesModal-DBIP648Z.mjs} +18 -57
  13. package/.output/server/_ssr/{SignIn-BhoZIOUp.mjs → SignIn-Bp3uWaCQ.mjs} +3 -3
  14. package/.output/server/_ssr/{ui-DGz-q9MT.mjs → actionUi-C_WswNb1.mjs} +113 -2
  15. package/.output/server/_ssr/{artifactFiles-ChuJ4PzC.mjs → artifactFiles-BvVmixrs.mjs} +3 -3
  16. package/.output/server/_ssr/{artifactKind-DXumOv7c.mjs → artifactKind-DRCbYHZU.mjs} +6 -14
  17. package/.output/server/_ssr/artifacts-CzDJLaa6.mjs +2 -0
  18. package/.output/server/_ssr/{auth-LwPp_iim.mjs → auth-BV0MxVdo.mjs} +44 -124
  19. package/.output/server/_ssr/{SocialLinks-DVCLmql0.mjs → auth-client-RTpMpT4L.mjs} +143 -109
  20. package/.output/server/_ssr/boot-CsLXrLEa.mjs +2 -0
  21. package/.output/server/_ssr/{boot-BIxtZHU-.mjs → boot-U-CFI65B.mjs} +58 -331
  22. package/.output/server/_ssr/{bun-sqlite-dialect-BW9W1_Ps-CHMDkKqA.mjs → bun-sqlite-dialect-BW9W1_Ps-D9KUBJ-L.mjs} +2 -2
  23. package/.output/server/_ssr/{d1-sqlite-dialect-BLC8LXE6-DYum6qky.mjs → d1-sqlite-dialect-BLC8LXE6-CVHRzH1n.mjs} +2 -2
  24. package/.output/server/_ssr/db-BTX-xORB.mjs +2 -0
  25. package/.output/server/_ssr/{dist-bWqs5sTy.mjs → dist-D7UDVZ5G.mjs} +2 -2
  26. package/.output/server/_ssr/{factory-pBwrjVTI.mjs → factory-DYFx1fg-.mjs} +2 -2
  27. package/.output/server/_ssr/{kysely-adapter-DMf5pFTf.mjs → kysely-adapter-CwdB7yBh.mjs} +1 -1
  28. package/.output/server/_ssr/logger-CwiKSMp6.mjs +2 -0
  29. package/.output/server/_ssr/{loopApi-Im6JSK0p.mjs → loopApi-C4nN0msL.mjs} +29 -90
  30. package/.output/server/_ssr/{loopProjection-DIpGR6rp.mjs → loopProjection-DMSNHux6.mjs} +2 -2
  31. package/.output/server/_ssr/{loops._loopId-B5iPseDG.mjs → loops._loopId-Q4pRYPip.mjs} +19 -45
  32. package/.output/server/_ssr/{loops._loopId_.runs._runId-DVtG0xYb.mjs → loops._loopId_.runs._runId-DNXVmCt5.mjs} +6 -13
  33. package/.output/server/_ssr/{loops._loopId_.runs._runId-BA-P6sGA.mjs → loops._loopId_.runs._runId-ty3AhkOi.mjs} +31 -23
  34. package/.output/server/_ssr/{machineFns-Bb9KNXun.mjs → machineFns-CkNms3zA.mjs} +41 -108
  35. package/.output/server/_ssr/{node-sqlite-dialect-Dho9YjXb.mjs → node-sqlite-dialect-B_g92oFK.mjs} +2 -2
  36. package/.output/server/_ssr/{router-DPz3uoUr.mjs → router-DCNZ2xLm.mjs} +26 -40
  37. package/.output/server/_ssr/routes-8JSF7bX_.mjs +27 -0
  38. package/.output/server/_ssr/{routes-FO0MFfYK.mjs → routes-B3fulW5I.mjs} +4 -9
  39. package/.output/server/_ssr/routes-BaanDO41.mjs +367 -0
  40. package/.output/server/_ssr/runDiff-D7CxAgYL.mjs +2 -0
  41. package/.output/server/_ssr/ssr.mjs +28 -88
  42. package/.output/server/_ssr/store-DSNbXxqz.mjs +2 -0
  43. package/.output/server/_ssr/tokens-DzUv7CCp.mjs +2 -0
  44. package/.output/server/_tanstack-start-manifest_v-DkmxsHDK.mjs +52 -0
  45. package/.output/server/drizzle/0002_remove_teams.sql +15 -0
  46. package/.output/server/drizzle/meta/_journal.json +7 -0
  47. package/.output/server/index.mjs +49 -98
  48. package/drizzle/0002_remove_teams.sql +15 -0
  49. package/drizzle/meta/_journal.json +7 -0
  50. package/package.json +2 -2
  51. package/.output/public/assets/MachinesModal-ByHejech.js +0 -1
  52. package/.output/public/assets/SignIn-Cf4HOpdF.js +0 -1
  53. package/.output/public/assets/actionUi-yYVvoOTn.js +0 -1
  54. package/.output/public/assets/app-IrlFuBXa.css +0 -2
  55. package/.output/public/assets/index-ia26HsP1.js +0 -10
  56. package/.output/public/assets/invite._token-B0EKVyrU.js +0 -1
  57. package/.output/public/assets/invite._token-tDfe3p0Z.js +0 -1
  58. package/.output/public/assets/lifecycleUi-C0DaC6NM.js +0 -1
  59. package/.output/public/assets/loops._loopId-CuYq_XgT.js +0 -67
  60. package/.output/public/assets/loops._loopId_.runs._runId-mOaF51Qu.js +0 -3
  61. package/.output/public/assets/routes-4N6mrQK_.js +0 -1
  62. package/.output/public/assets/routes-Dbl_3lt_.js +0 -1
  63. package/.output/public/assets/t._teamId-BVsl0EGm.js +0 -1
  64. package/.output/public/assets/t._teamId-CAUjvMZ6.js +0 -1
  65. package/.output/server/_ssr/DashboardView-BMHMrOfC.mjs +0 -842
  66. package/.output/server/_ssr/actionUi-Cf6DuEC2.mjs +0 -119
  67. package/.output/server/_ssr/artifacts-DOLHJHcd.mjs +0 -2
  68. package/.output/server/_ssr/boot-D8cj4uZj.mjs +0 -2
  69. package/.output/server/_ssr/db-BphSJs66.mjs +0 -2
  70. package/.output/server/_ssr/invite._token-CPSvdDox.mjs +0 -27
  71. package/.output/server/_ssr/invite._token-CRBsTSTZ.mjs +0 -84
  72. package/.output/server/_ssr/invite._token-CaTLt92a.mjs +0 -20
  73. package/.output/server/_ssr/lifecycleUi-DauKavgx.mjs +0 -50
  74. package/.output/server/_ssr/logger-EinA2J6y.mjs +0 -2
  75. package/.output/server/_ssr/routes-B9zD2h4Y.mjs +0 -26
  76. package/.output/server/_ssr/routes-BuILEmHs.mjs +0 -39
  77. package/.output/server/_ssr/runDiff-BLdot9mi.mjs +0 -2
  78. package/.output/server/_ssr/store-CFCp_ggC.mjs +0 -2
  79. package/.output/server/_ssr/t._teamId-1t5wOXrV.mjs +0 -43
  80. package/.output/server/_ssr/t._teamId-A37pQ8Vp.mjs +0 -32
  81. package/.output/server/_ssr/t._teamId-D1BTwhWf.mjs +0 -31
  82. package/.output/server/_ssr/teamCookie-B7hLOIie.mjs +0 -10
  83. package/.output/server/_ssr/teamFns-DfqtuBW2.mjs +0 -451
  84. package/.output/server/_ssr/teamFns-cI_tsiCv.mjs +0 -32
  85. package/.output/server/_ssr/tokens-CUz4LDLm.mjs +0 -2
  86. package/.output/server/_tanstack-start-manifest_v-CojB4Veh.mjs +0 -86
@@ -1,31 +1,15 @@
1
- import { A as ensureServer, Bt as sha256, C as createMachine$1, G as getMachine, Jt as updateMachine, P as forceDeleteMachine, St as mintDeviceToken, T as daemonNeedsUpdate, X as getTeamMember, bt as machineIdFromToken, dt as listMachines$1, ft as listMachinesForTeam, jt as rememberConnectKey, u as MIN_DAEMON_VERSION, yt as loopsForMachine } from "./boot-BIxtZHU-.mjs";
2
- import { requestScope } from "./auth-LwPp_iim.mjs";
1
+ import { At as updateMachine, Ct as sha256, D as forceDeleteMachine, L as getMachine, b as createMachine$1, et as listMachines$1, lt as mintDeviceToken, ot as loopsForMachine, st as machineIdFromToken, tt as listMachinesForUser, u as MIN_DAEMON_VERSION, w as ensureServer, x as daemonNeedsUpdate } from "./boot-U-CFI65B.mjs";
2
+ import { requestScope } from "./auth-BV0MxVdo.mjs";
3
3
  import { n as createServerFn } from "./ssr.mjs";
4
4
  import { t as createServerRpc } from "./createServerRpc-BD8Xn_0_.mjs";
5
- //#region node_modules/.nitro/vite/services/ssr/assets/machineFns-Bb9KNXun.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);
5
+ //#region node_modules/.nitro/vite/services/ssr/assets/machineFns-CkNms3zA.js
6
+ /** Open mode sees every machine; auth mode sees only the signed-in owner's rows. */
7
+ function machineInScope(machine, scope) {
8
+ return !scope.enforce || !!scope.userId && machine.userId === scope.userId;
19
9
  }
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;
10
+ /** A device token fully impersonates its machine, so auth mode keeps it owner-only. */
11
+ function tokenVisibleTo(machine, scope) {
12
+ return machineInScope(machine, scope);
29
13
  }
30
14
  /**
31
15
  * Latest published @kky42/pievo version — a cached, fail-silent lookup of the
@@ -108,102 +92,64 @@ var LatestDaemonVersion = class {
108
92
  };
109
93
  var latestDaemonVersion = new LatestDaemonVersion();
110
94
  /**
111
- * Machine management server functions. Connect flow (two acts):
112
- * 1. createMachine() → mint a token, create a PENDING (unnamed) row, return
113
- * {id, token}. The UI shows the connect command + "waiting…".
114
- * 2. the daemon connects → poll records online + hostname/platform/arch. The
115
- * UI polls machineStatus(id); once connected it shows the name field
116
- * (prefilled with the hostname). finalizeMachine({id,name}) names it →
117
- * it appears in the list. cancelMachine(id) drops a pending row.
118
- *
119
- * Scoping: when the auth gate is on, every fn requires a signed-in user, and a
120
- * machine is visible/actionable only when the requester owns it, its owner is a
121
- * member of the active team, or the scope is the admin "All teams" view (the
122
- * same rule listMachines filters by). The PLAINTEXT device token is serialized
123
- * ONLY to the machine's owner — it fully impersonates the machine (poll /
124
- * create-loop / log), so a teammate who can see the row must never exfiltrate
125
- * it. Open mode (gate off) keeps the shared workspace: everyone sees/manages
126
- * all machines, tokens included. No workdir jail (fully open) for now.
127
- */
128
- /** Ids of the machines membership-visible in the scope's active team (the same
129
- * set listMachines serves). Empty when the scope needs no team check (open
130
- * mode or signed-out — machineInScope settles those before ever invoking its
131
- * team-set thunk). */
132
- async function teamMachineIds(scope) {
133
- if (!scope.enforce || !scope.userId) return /* @__PURE__ */ new Set();
134
- return new Set((await listMachinesForTeam(scope.teamId)).map((m) => m.id));
135
- }
136
- /**
137
- * Resolve a machine and authorize it against the request scope (the machine-fn
138
- * twin of loopApi's `ownedLoop`). `machine` is undefined when it's missing OR
139
- * out of scope — callers treat both as "not found" so existence never leaks.
140
- * The scope rides along so callers don't re-run requestScope (a second session
141
- * decrypt); the team-set thunk keeps the owner fast path query-free.
95
+ * Machine-management server functions. In auth mode, the signed-in user is the
96
+ * sole human authorization boundary. Open mode intentionally shares all machine
97
+ * administration, including reconnect tokens.
142
98
  */
99
+ /** Missing and out-of-scope machines both resolve to undefined. */
143
100
  async function scopedMachine(id) {
144
101
  const scope = await requestScope();
145
- const m = await getMachine(id);
146
- const teamIds = await teamMachineIds(scope);
102
+ if (scope.enforce && !scope.userId) return { scope };
103
+ const candidate = await getMachine(id);
147
104
  return {
148
105
  scope,
149
- machine: m && machineInScope(m, scope, () => teamIds) ? m : void 0
106
+ machine: candidate && machineInScope(candidate, scope) ? candidate : void 0
150
107
  };
151
108
  }
152
- async function toSummary(m, scope) {
109
+ async function toSummary(machine, scope) {
153
110
  return {
154
- id: m.id,
155
- name: m.name,
156
- online: !!m.online,
157
- lastSeen: m.lastSeen ?? null,
158
- hostname: m.hostname ?? null,
159
- platform: m.platform ?? null,
160
- arch: m.arch ?? null,
161
- daemonVersion: m.daemonVersion ?? null,
162
- daemonProtocol: m.daemonProtocol ?? null,
111
+ id: machine.id,
112
+ name: machine.name,
113
+ online: !!machine.online,
114
+ lastSeen: machine.lastSeen ?? null,
115
+ hostname: machine.hostname ?? null,
116
+ platform: machine.platform ?? null,
117
+ arch: machine.arch ?? null,
118
+ daemonVersion: machine.daemonVersion ?? null,
119
+ daemonProtocol: machine.daemonProtocol ?? null,
163
120
  latestDaemonVersion: latestDaemonVersion.get(),
164
- needsUpdate: daemonNeedsUpdate(m.daemonVersion),
121
+ needsUpdate: daemonNeedsUpdate(machine.daemonVersion),
165
122
  requiredDaemonVersion: MIN_DAEMON_VERSION,
166
- token: tokenVisibleTo(m, scope) ? m.token ?? null : null,
167
- loopCount: (await loopsForMachine(m.id)).length
123
+ token: tokenVisibleTo(machine, scope) ? machine.token ?? null : null,
124
+ loopCount: (await loopsForMachine(machine.id)).length
168
125
  };
169
126
  }
170
- /** Named machines only (pending/unnamed rows are mid-connect). Scoped to the
171
- * given/active team when the gate is on; the full shared list in open mode. An
172
- * explicit `teamId` (the `/t/<id>` route) scopes this request independent of the
173
- * cookie, so a tab on /t/A and one on /t/B list different machines at once. */
174
127
  var listMachines_createServerFn_handler = createServerRpc({
175
128
  id: "aa46310016bb8a58b273a648ffd498c87f1f450d12827e30110a3b83ba6a27d9",
176
129
  name: "listMachines",
177
130
  filename: "src/server/machineFns.ts"
178
131
  }, (opts) => listMachines.__executeServer(opts));
179
- var listMachines = createServerFn({ method: "GET" }).validator((teamId) => teamId).handler(listMachines_createServerFn_handler, async ({ data: teamId }) => {
132
+ var listMachines = createServerFn({ method: "GET" }).handler(listMachines_createServerFn_handler, async () => {
180
133
  await ensureServer();
181
- const scope = await requestScope(teamId);
182
- const { enforce, userId, teamId: active } = scope;
183
- if (enforce && !userId) return [];
184
- const list = enforce ? await listMachinesForTeam(active) : await listMachines$1();
185
- return Promise.all(list.filter((m) => m.name.trim()).map((m) => toSummary(m, scope)));
134
+ const scope = await requestScope();
135
+ if (scope.enforce && !scope.userId) return [];
136
+ const machines = scope.enforce ? await listMachinesForUser(scope.userId) : await listMachines$1();
137
+ return Promise.all(machines.filter((machine) => machine.name.trim()).map((machine) => toSummary(machine, scope)));
186
138
  });
187
139
  var createMachine_createServerFn_handler = createServerRpc({
188
140
  id: "ed679b4e1e05e903a5d4ba4a70d9b9d883991ab22ed59b4d2d69078941818415",
189
141
  name: "createMachine",
190
142
  filename: "src/server/machineFns.ts"
191
143
  }, (opts) => createMachine.__executeServer(opts));
192
- var createMachine = createServerFn({ method: "POST" }).validator((teamId) => teamId).handler(createMachine_createServerFn_handler, async ({ data: teamId }) => {
144
+ var createMachine = createServerFn({ method: "POST" }).handler(createMachine_createServerFn_handler, async () => {
193
145
  await ensureServer();
194
- const { enforce, userId, teamId: active } = await requestScope(teamId);
195
- if (enforce && !userId) return { error: "not signed in" };
146
+ const scope = await requestScope();
147
+ if (scope.enforce && !scope.userId) return { error: "not signed in" };
196
148
  const token = mintDeviceToken();
197
149
  const id = machineIdFromToken(token);
198
- const owner = userId ?? "shared";
199
- await rememberConnectKey(token, {
200
- userId: owner,
201
- teamId: active
202
- });
203
150
  await createMachine$1({
204
151
  id,
205
- userId: owner,
206
- teamId: active,
152
+ userId: scope.userId ?? "shared",
207
153
  name: "",
208
154
  tokenHash: sha256(token),
209
155
  token,
@@ -229,7 +175,7 @@ var finalizeMachine_createServerFn_handler = createServerRpc({
229
175
  name: "finalizeMachine",
230
176
  filename: "src/server/machineFns.ts"
231
177
  }, (opts) => finalizeMachine.__executeServer(opts));
232
- var finalizeMachine = createServerFn({ method: "POST" }).validator((d) => d).handler(finalizeMachine_createServerFn_handler, async ({ data }) => {
178
+ var finalizeMachine = createServerFn({ method: "POST" }).validator((data) => data).handler(finalizeMachine_createServerFn_handler, async ({ data }) => {
233
179
  await ensureServer();
234
180
  const name = data.name?.trim();
235
181
  if (!name) return { ok: false };
@@ -253,21 +199,8 @@ var deleteMachine = createServerFn({ method: "POST" }).validator((id) => id).han
253
199
  ok: false,
254
200
  error: "machine not found"
255
201
  };
256
- const loops = await loopsForMachine(id);
257
- let allowedTeamIds = scope.enforce ? [] : void 0;
258
- if (scope.enforce && loops.length > 0) {
259
- allowedTeamIds = [...new Set(loops.map((loop) => loop.teamId))];
260
- if ((await Promise.all(allowedTeamIds.map((teamId) => getTeamMember(teamId, scope.userId)))).some((membership) => membership?.role !== "owner")) return {
261
- ok: false,
262
- error: "Only an owner of every affected team can delete this machine and its loops."
263
- };
264
- }
265
- const deleted = await forceDeleteMachine(id, allowedTeamIds);
266
- if (deleted.state === "forbidden") return {
267
- ok: false,
268
- error: "Machine loops changed while deleting; review them and try again."
269
- };
270
- if (deleted.state === "not-found") return {
202
+ const deleted = scope.enforce ? await forceDeleteMachine(id, scope.userId) : await forceDeleteMachine(id);
203
+ if (deleted.state === "forbidden" || deleted.state === "not-found") return {
271
204
  ok: false,
272
205
  error: "machine not found"
273
206
  };
@@ -1,6 +1,6 @@
1
- import { n as DefaultQueryCompiler, o as CompiledQuery, s as sql$1 } from "./auth-LwPp_iim.mjs";
1
+ import { n as DefaultQueryCompiler, o as CompiledQuery, s as sql$1 } from "./auth-BV0MxVdo.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-Dho9YjXb.js
3
+ //#region node_modules/.nitro/vite/services/ssr/assets/node-sqlite-dialect-B_g92oFK.js
4
4
  var NodeSqliteAdapter = class {
5
5
  get supportsCreateIfNotExists() {
6
6
  return true;
@@ -1,15 +1,13 @@
1
1
  import { j as sql } from "../_libs/drizzle-orm+postgres.mjs";
2
- import { A as ensureServer, Dt as readJsonBody, Et as readByteBody, Qt as validPollWireId, Xt as validOptionalPollString, Zt as validPollCurrentRun, d as POLL_HTTP_BODY_FIELDS, l as MACHINE_BODY_CAP } from "./boot-BIxtZHU-.mjs";
2
+ import { Mt as validPollCurrentRun, Nt as validPollWireId, d as POLL_HTTP_BODY_FIELDS, jt as validOptionalPollString, l as MACHINE_BODY_CAP, mt as readJsonBody, pt as readByteBody, w as ensureServer } from "./boot-U-CFI65B.mjs";
3
3
  import { h as require_jsx_runtime } from "../_libs/@base-ui/react+[...].mjs";
4
4
  import { c as createFileRoute, i as HeadContent, l as createRootRoute, o as createRouter, r as Scripts } from "../_libs/@tanstack/react-router+[...].mjs";
5
- import { t as Route$12 } from "./invite._token-CPSvdDox.mjs";
6
- import { r as imageMime, t as Route$13 } from "./artifactKind-DXumOv7c.mjs";
7
- import { t as Route$14 } from "./loops._loopId_.runs._runId-DVtG0xYb.mjs";
8
- import { t as Route$15 } from "./routes-BuILEmHs.mjs";
9
- import { t as Route$16 } from "./t._teamId-1t5wOXrV.mjs";
10
- //#region node_modules/.nitro/vite/services/ssr/assets/router-DPz3uoUr.js
5
+ import { r as imageMime, t as Route$12 } from "./artifactKind-DRCbYHZU.mjs";
6
+ import { t as Route$13 } from "./loops._loopId_.runs._runId-DNXVmCt5.mjs";
7
+ import { n as Route$14 } from "./routes-BaanDO41.mjs";
8
+ //#region node_modules/.nitro/vite/services/ssr/assets/router-DCNZ2xLm.js
11
9
  var import_jsx_runtime = require_jsx_runtime();
12
- var app_default = "/assets/app-IrlFuBXa.css";
10
+ var app_default = "/assets/app-PPhgN9iN.css";
13
11
  var Route$11 = createRootRoute({
14
12
  head: () => ({
15
13
  meta: [
@@ -169,7 +167,7 @@ var Route$10 = createFileRoute("/machine/report")({ server: { handlers: { POST:
169
167
  const parsed = await readJsonBody(request, MACHINE_BODY_CAP);
170
168
  if (parsed.kind === "too-large") return Response.json({ error: "body too large" }, { status: 413 });
171
169
  const body = parsed.kind === "ok" && parsed.body && typeof parsed.body === "object" ? parsed.body : {};
172
- const { getGateway } = await import("./boot-D8cj4uZj.mjs");
170
+ const { getGateway } = await import("./boot-CsLXrLEa.mjs");
173
171
  const r = await (await getGateway()).report(token, body);
174
172
  return Response.json(r.body, { status: r.status });
175
173
  } } } });
@@ -209,13 +207,13 @@ var Route$7 = createFileRoute("/api/machine/sync")({ server: { handlers: { POST:
209
207
  const auth = request.headers.get("authorization") ?? "";
210
208
  const token = auth.startsWith("Bearer ") ? auth.slice(7) : "";
211
209
  if (!token) return Response.json({ error: "missing device token" }, { status: 401 });
212
- const { SYNC_BODY_CAP, parseArtifactSyncBody } = await import("./artifacts-DOLHJHcd.mjs");
210
+ const { SYNC_BODY_CAP, parseArtifactSyncBody } = await import("./artifacts-CzDJLaa6.mjs");
213
211
  const parsed = await readJsonBody(request, SYNC_BODY_CAP);
214
212
  if (parsed.kind === "too-large") return Response.json({ error: "sync body too large" }, { status: 413 });
215
213
  if (parsed.kind === "invalid") return Response.json({ error: "invalid JSON" }, { status: 400 });
216
214
  const body = parseArtifactSyncBody(parsed.body);
217
215
  if (!body) return Response.json({ error: "invalid sync body" }, { status: 400 });
218
- const { getArtifactSync } = await import("./boot-D8cj4uZj.mjs");
216
+ const { getArtifactSync } = await import("./boot-CsLXrLEa.mjs");
219
217
  const r = await (await getArtifactSync()).sync(token, body);
220
218
  return Response.json(r.body, { status: r.status });
221
219
  } } } });
@@ -225,7 +223,7 @@ var Route$6 = createFileRoute("/api/machine/status")({ server: { handlers: { GET
225
223
  const limited = machineRouteLimit(request, token || void 0);
226
224
  if (limited) return limited;
227
225
  if (!token) return Response.json({ error: "missing device token" }, { status: 401 });
228
- const { getGateway } = await import("./boot-D8cj4uZj.mjs");
226
+ const { getGateway } = await import("./boot-CsLXrLEa.mjs");
229
227
  const r = await (await getGateway()).status(token);
230
228
  return Response.json(r.body, { status: r.status });
231
229
  } } } });
@@ -267,7 +265,7 @@ var Route$5 = createFileRoute("/api/machine/poll")({ server: { handlers: { POST:
267
265
  if (parsed.kind !== "ok") return Response.json({ error: "invalid JSON body" }, { status: 400 });
268
266
  const body = parsePollBody(parsed.body);
269
267
  if (!body) return Response.json({ error: "unknown or invalid poll body fields" }, { status: 400 });
270
- const { getGateway } = await import("./boot-D8cj4uZj.mjs");
268
+ const { getGateway } = await import("./boot-CsLXrLEa.mjs");
271
269
  const r = await (await getGateway()).pollV4Wait(token, gatewayPollRequest(body));
272
270
  return Response.json(r.body, { status: r.status });
273
271
  } } } });
@@ -294,7 +292,7 @@ var Route$4 = createFileRoute("/api/machine/cli")({ server: { handlers: { POST:
294
292
  if (parsed.kind === "too-large") return Response.json({ error: "body too large" }, { status: 413 });
295
293
  const body = parsed.kind === "ok" ? parseCliBody(parsed.body) : null;
296
294
  if (!body) return Response.json({ error: "body must be exactly {argv:string[]}" }, { status: 400 });
297
- const { getCliGateway } = await import("./boot-D8cj4uZj.mjs");
295
+ const { getCliGateway } = await import("./boot-CsLXrLEa.mjs");
298
296
  const r = await (await getCliGateway()).cli(token, body.argv);
299
297
  return Response.json(r.body, { status: r.status });
300
298
  } } } });
@@ -323,7 +321,7 @@ var Route$4 = createFileRoute("/api/machine/cli")({ server: { handlers: { POST:
323
321
  var PROBE_TIMEOUT_MS = 5e3;
324
322
  var Route$3 = createFileRoute("/api/health/db")({ server: { handlers: { GET: async () => {
325
323
  try {
326
- const { db } = await import("./db-BphSJs66.mjs");
324
+ const { db } = await import("./db-BTX-xORB.mjs");
327
325
  const ping = db.execute(sql`select 1`);
328
326
  const timeout = new Promise((_, reject) => {
329
327
  setTimeout(() => reject(/* @__PURE__ */ new Error(`db ping timed out after ${PROBE_TIMEOUT_MS}ms`)), PROBE_TIMEOUT_MS).unref?.();
@@ -342,8 +340,8 @@ var Route$3 = createFileRoute("/api/health/db")({ server: { handlers: { GET: asy
342
340
  }
343
341
  } } } });
344
342
  var Route$2 = createFileRoute("/api/auth/$")({ server: { handlers: {
345
- GET: async ({ request }) => (await import("./auth-LwPp_iim.mjs")).auth.handler(request),
346
- POST: async ({ request }) => (await import("./auth-LwPp_iim.mjs")).auth.handler(request)
343
+ GET: async ({ request }) => (await import("./auth-BV0MxVdo.mjs")).auth.handler(request),
344
+ POST: async ({ request }) => (await import("./auth-BV0MxVdo.mjs")).auth.handler(request)
347
345
  } } });
348
346
  /**
349
347
  * `decodeURIComponent` that returns null on malformed percent-encoding instead
@@ -377,12 +375,12 @@ var Route$1 = createFileRoute("/api/machine/blob/$hash")({ server: { handlers: {
377
375
  if (!token) return Response.json({ error: "missing device token" }, { status: 401 });
378
376
  const hash = safeDecode(new URL(request.url).pathname.split("/").pop() ?? "");
379
377
  if (hash === null) return Response.json({ error: "bad hash" }, { status: 400 });
380
- const { BLOB_CAP } = await import("./artifacts-DOLHJHcd.mjs");
378
+ const { BLOB_CAP } = await import("./artifacts-CzDJLaa6.mjs");
381
379
  const body = await readByteBody(request, BLOB_CAP);
382
380
  if (body.kind === "too-large") return Response.json({ error: "blob exceeds size cap" }, { status: 413 });
383
381
  if (body.kind === "invalid") return Response.json({ error: "could not read blob body" }, { status: 400 });
384
382
  const buf = Buffer.from(body.bytes.buffer, body.bytes.byteOffset, body.bytes.byteLength);
385
- const { getArtifactSync } = await import("./boot-D8cj4uZj.mjs");
383
+ const { getArtifactSync } = await import("./boot-CsLXrLEa.mjs");
386
384
  const r = await (await getArtifactSync()).putBlob(token, hash, buf);
387
385
  return Response.json(r.body, { status: r.status });
388
386
  } } } });
@@ -399,8 +397,8 @@ var Route$1 = createFileRoute("/api/machine/blob/$hash")({ server: { handlers: {
399
397
  * scripts - so an inline SVG can't run script against the session even if the
400
398
  * URL is opened directly. Non-image inline requests fall back to attachment.
401
399
  *
402
- * Authed via the WEB SESSION (not a machine token) and scoped to the loop's team,
403
- * mirroring the server fns' `ownedLoop` gate. Path-safe: the relative path is
400
+ * Authed via the web session (not a machine token) and scoped to the loop owner,
401
+ * mirroring the server functions' `ownedLoop` gate. Path-safe: the relative path is
404
402
  * normalized + traversal-rejected before it ever reaches a blob, and blob keys
405
403
  * are content hashes, never the user path. Reads stream from the BlobStore
406
404
  * (local by default, R2 when configured); the route never writes.
@@ -417,11 +415,11 @@ var Route = createFileRoute("/api/artifact/$loopId/$")({ server: { handlers: { G
417
415
  const segments = after.slice(slash + 1).split("/").map((s) => safeDecode(s));
418
416
  if (segments.some((s) => s === null)) return Response.json({ error: "bad path" }, { status: 400 });
419
417
  const relPath = segments.join("/");
420
- const loop = await (await import("./store-CFCp_ggC.mjs")).getLoop(loopId);
418
+ const loop = await (await import("./store-DSNbXxqz.mjs")).getLoop(loopId);
421
419
  if (!loop) return Response.json({ error: "not found" }, { status: 404 });
422
- const { requestScope, canAccessLoop } = await import("./auth-LwPp_iim.mjs");
423
- if (!await canAccessLoop(loop.teamId, await requestScope())) return Response.json({ error: "not found" }, { status: 404 });
424
- const { readLoopArtifactBytes } = await import("./artifactFiles-ChuJ4PzC.mjs");
420
+ const { requestScope, canAccessLoop } = await import("./auth-BV0MxVdo.mjs");
421
+ if (!canAccessLoop(loop.userId, await requestScope())) return Response.json({ error: "not found" }, { status: 404 });
422
+ const { readLoopArtifactBytes } = await import("./artifactFiles-BvVmixrs.mjs");
425
423
  const r = await readLoopArtifactBytes(loopId, relPath);
426
424
  if (r.status !== 200 || !r.bytes) return Response.json({ error: "not found" }, { status: r.status });
427
425
  const filename = (r.filename || "file").replace(/["\\\r\n]/g, "_");
@@ -447,31 +445,21 @@ var Route = createFileRoute("/api/artifact/$loopId/$")({ server: { handlers: { G
447
445
  }
448
446
  });
449
447
  } } } });
450
- var IndexRoute = Route$15.update({
448
+ var IndexRoute = Route$14.update({
451
449
  id: "/",
452
450
  path: "/",
453
451
  getParentRoute: () => Route$11
454
452
  });
455
- var TTeamIdRoute = Route$16.update({
456
- id: "/t/$teamId",
457
- path: "/t/$teamId",
458
- getParentRoute: () => Route$11
459
- });
460
453
  var MachineReportRoute = Route$10.update({
461
454
  id: "/machine/report",
462
455
  path: "/machine/report",
463
456
  getParentRoute: () => Route$11
464
457
  });
465
- var LoopsLoopIdRoute = Route$13.update({
458
+ var LoopsLoopIdRoute = Route$12.update({
466
459
  id: "/loops/$loopId",
467
460
  path: "/loops/$loopId",
468
461
  getParentRoute: () => Route$11
469
462
  });
470
- var InviteTokenRoute = Route$12.update({
471
- id: "/invite/$token",
472
- path: "/invite/$token",
473
- getParentRoute: () => Route$11
474
- });
475
463
  var ApiReadyRoute = Route$9.update({
476
464
  id: "/api/ready",
477
465
  path: "/api/ready",
@@ -512,7 +500,7 @@ var ApiAuthSplatRoute = Route$2.update({
512
500
  path: "/api/auth/$",
513
501
  getParentRoute: () => Route$11
514
502
  });
515
- var LoopsLoopIdRunsRunIdRoute = Route$14.update({
503
+ var LoopsLoopIdRunsRunIdRoute = Route$13.update({
516
504
  id: "/loops/$loopId_/runs/$runId",
517
505
  path: "/loops/$loopId/runs/$runId",
518
506
  getParentRoute: () => Route$11
@@ -532,10 +520,8 @@ var rootRouteChildren = {
532
520
  IndexRoute,
533
521
  ApiHealthRoute: ApiHealthRoute._addFileChildren(ApiHealthRouteChildren),
534
522
  ApiReadyRoute,
535
- InviteTokenRoute,
536
523
  LoopsLoopIdRoute,
537
524
  MachineReportRoute,
538
- TTeamIdRoute,
539
525
  ApiAuthSplatRoute,
540
526
  ApiMachineCliRoute,
541
527
  ApiMachinePollRoute,
@@ -0,0 +1,27 @@
1
+ import { h as require_jsx_runtime } from "../_libs/@base-ui/react+[...].mjs";
2
+ import { O as useSession } from "./auth-client-RTpMpT4L.mjs";
3
+ import { a as Loading } from "./actionUi-C_WswNb1.mjs";
4
+ import { t as SignIn } from "./SignIn-Bp3uWaCQ.mjs";
5
+ import { n as Route, t as DashboardView } from "./routes-BaanDO41.mjs";
6
+ //#region node_modules/.nitro/vite/services/ssr/assets/routes-8JSF7bX_.js
7
+ var import_jsx_runtime = require_jsx_runtime();
8
+ /** The dashboard route. Auth mode shows sign-in before loading owner-scoped data;
9
+ * open mode renders the server's shared administrative workspace. */
10
+ /** First-load failure screen — a calm retry instead of the router's default
11
+ * error dump. Only the initial loader can land here; the in-page poll is
12
+ * fetch-then-set and keeps stale data on a transient blip. */
13
+ function Home() {
14
+ const loaded = Route.useLoaderData();
15
+ const { data: session, isPending } = useSession();
16
+ if (loaded.auth.enabled && isPending) return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("main", {
17
+ className: "mx-auto max-w-[1180px] px-8 pt-12",
18
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Loading, {})
19
+ });
20
+ if (loaded.auth.enabled && !session) return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SignIn, {});
21
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(DashboardView, {
22
+ initial: loaded.initial,
23
+ mode: loaded.auth.enabled ? "auth" : "open"
24
+ });
25
+ }
26
+ //#endregion
27
+ export { Home as component };
@@ -1,15 +1,10 @@
1
1
  import { h 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-Cf6DuEC2.mjs";
4
- //#region node_modules/.nitro/vite/services/ssr/assets/routes-FO0MFfYK.js
3
+ import { i as LoadErrorCard } from "./actionUi-C_WswNb1.mjs";
4
+ //#region node_modules/.nitro/vite/services/ssr/assets/routes-B3fulW5I.js
5
5
  var import_jsx_runtime = require_jsx_runtime();
6
- /**
7
- * The home route. Under the auth gate it is now a THIN redirect to the explicit
8
- * team URL (`/t/<lastUsed|personal>`) so the dashboard's team lives in the path
9
- * (bookmarkable, multi-tab). `/` keeps working forever: a signed-out visitor gets
10
- * the sign-in CTA; open mode (no gate ⇒ a single shared workspace with no team to
11
- * expose in the URL) renders the dashboard right here, unchanged.
12
- */
6
+ /** The dashboard route. Auth mode shows sign-in before loading owner-scoped data;
7
+ * open mode renders the server's shared administrative workspace. */
13
8
  /** First-load failure screen — a calm retry instead of the router's default
14
9
  * error dump. Only the initial loader can land here; the in-page poll is
15
10
  * fetch-then-set and keeps stale data on a transient blip. */