@spacefast/common 0.0.23 → 0.0.24

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 (176) hide show
  1. package/dist/config/domains.d.ts +1 -1
  2. package/dist/config/domains.js +1 -0
  3. package/dist/config/index.d.ts +0 -1
  4. package/dist/config/index.js +0 -1
  5. package/dist/contracts/abuse.d.ts +2 -0
  6. package/dist/contracts/abuse.js +12 -0
  7. package/dist/contracts/access.d.ts +121 -9
  8. package/dist/contracts/access.js +73 -9
  9. package/dist/contracts/activity.d.ts +1 -1
  10. package/dist/contracts/activity.js +0 -9
  11. package/dist/contracts/api-keys.d.ts +21 -21
  12. package/dist/contracts/beta.js +1 -1
  13. package/dist/contracts/billing.d.ts +1 -34
  14. package/dist/contracts/billing.js +4 -53
  15. package/dist/contracts/builds.d.ts +8 -8
  16. package/dist/contracts/builds.js +10 -3
  17. package/dist/contracts/cli.d.ts +10 -0
  18. package/dist/contracts/cli.js +10 -0
  19. package/dist/contracts/collab-public.d.ts +63 -0
  20. package/dist/contracts/collab-public.js +46 -0
  21. package/dist/contracts/comments.d.ts +283 -54
  22. package/dist/contracts/comments.js +173 -52
  23. package/dist/contracts/common.d.ts +3 -3
  24. package/dist/contracts/device-auth.d.ts +6 -6
  25. package/dist/contracts/device-auth.js +1 -1
  26. package/dist/contracts/docs.d.ts +5 -5
  27. package/dist/contracts/domains.d.ts +36 -36
  28. package/dist/contracts/enums.d.ts +33 -30
  29. package/dist/contracts/enums.js +52 -38
  30. package/dist/contracts/error-code-meta.d.ts +37 -126
  31. package/dist/contracts/error-code-meta.js +12 -41
  32. package/dist/contracts/error-codes.d.ts +1 -1
  33. package/dist/contracts/error-codes.js +10 -32
  34. package/dist/contracts/execution.d.ts +35 -57
  35. package/dist/contracts/execution.js +41 -40
  36. package/dist/contracts/feature-lifecycle-core.d.ts +0 -6
  37. package/dist/contracts/feature-lifecycle-core.js +2 -31
  38. package/dist/contracts/feature-lifecycle.d.ts +8 -38
  39. package/dist/contracts/feature-lifecycle.js +16 -48
  40. package/dist/contracts/features.d.ts +15 -13
  41. package/dist/contracts/features.js +39 -38
  42. package/dist/contracts/functions.d.ts +97 -70
  43. package/dist/contracts/functions.js +101 -34
  44. package/dist/contracts/git.d.ts +1 -1
  45. package/dist/contracts/grants.d.ts +7 -3
  46. package/dist/contracts/grants.js +18 -9
  47. package/dist/contracts/internal.d.ts +14 -1
  48. package/dist/contracts/internal.js +17 -7
  49. package/dist/contracts/oauth-resources.d.ts +4 -3
  50. package/dist/contracts/oauth-resources.js +12 -3
  51. package/dist/contracts/operations.d.ts +90 -5
  52. package/dist/contracts/operations.js +75 -1
  53. package/dist/contracts/pages.d.ts +6 -1
  54. package/dist/contracts/pages.js +24 -1
  55. package/dist/contracts/plan-policy.d.ts +1 -3
  56. package/dist/contracts/plan-policy.js +1 -2
  57. package/dist/contracts/platform.d.ts +61 -148
  58. package/dist/contracts/platform.js +70 -126
  59. package/dist/contracts/publish-archive.d.ts +498 -0
  60. package/dist/contracts/publish-archive.js +25 -0
  61. package/dist/contracts/resources.d.ts +12 -24
  62. package/dist/contracts/resources.js +32 -12
  63. package/dist/contracts/runtime-api.d.ts +369 -175
  64. package/dist/contracts/runtime-api.js +372 -348
  65. package/dist/contracts/runtime-app.d.ts +127 -120
  66. package/dist/contracts/runtime-app.js +19 -10
  67. package/dist/contracts/runtime-db.d.ts +1 -1
  68. package/dist/contracts/runtime-services.d.ts +219 -0
  69. package/dist/contracts/runtime-services.js +437 -0
  70. package/dist/contracts/runtime-storage.d.ts +45 -32
  71. package/dist/contracts/runtime-storage.js +30 -8
  72. package/dist/contracts/space-config.d.ts +10 -16
  73. package/dist/contracts/space-config.js +14 -10
  74. package/dist/contracts/spaces.d.ts +241 -436
  75. package/dist/contracts/spaces.js +128 -145
  76. package/dist/contracts/superadmin-activity.d.ts +57 -4
  77. package/dist/contracts/superadmin-activity.js +48 -2
  78. package/dist/contracts/superadmin-search.d.ts +126 -0
  79. package/dist/contracts/superadmin-search.js +61 -0
  80. package/dist/contracts/superadmin-spaces.d.ts +358 -89
  81. package/dist/contracts/superadmin-spaces.js +97 -24
  82. package/dist/contracts/superadmin-teams.d.ts +28 -10
  83. package/dist/contracts/superadmin-teams.js +5 -8
  84. package/dist/contracts/superadmin.d.ts +0 -32
  85. package/dist/contracts/superadmin.js +3 -11
  86. package/dist/contracts/tags.d.ts +9 -9
  87. package/dist/contracts/teams.d.ts +38 -0
  88. package/dist/contracts/teams.js +34 -16
  89. package/dist/contracts/transfers.d.ts +0 -49
  90. package/dist/contracts/transfers.js +2 -6
  91. package/dist/contracts/usage.d.ts +61 -0
  92. package/dist/contracts/usage.js +64 -0
  93. package/dist/contracts/variables.d.ts +2 -7
  94. package/dist/contracts/variables.js +6 -5
  95. package/dist/contracts/webhooks.d.ts +2 -2
  96. package/dist/contracts/zero.d.ts +87 -56
  97. package/dist/contracts/zero.js +82 -20
  98. package/dist/dashboard-paths/index.d.ts +1 -1
  99. package/dist/dashboard-paths/index.js +1 -0
  100. package/dist/docs/agent-prose.d.ts +1 -1
  101. package/dist/docs/agent-prose.js +57 -61
  102. package/dist/docs/agent-setup.js +40 -13
  103. package/dist/docs/catalog.d.ts +19 -19
  104. package/dist/docs/catalog.js +30 -19
  105. package/dist/docs/error-docs.js +63 -151
  106. package/dist/test-helpers/fetch-stub.d.ts +16 -0
  107. package/dist/test-helpers/fetch-stub.js +24 -0
  108. package/dist/utils/build-settings.js +9 -3
  109. package/dist/utils/canonical-json.d.ts +10 -0
  110. package/dist/utils/canonical-json.js +21 -0
  111. package/dist/utils/cast-transport.d.ts +28 -0
  112. package/dist/utils/cast-transport.js +52 -0
  113. package/dist/utils/claim-token.d.ts +0 -8
  114. package/dist/utils/claim-token.js +3 -15
  115. package/dist/utils/credential-policy.d.ts +1 -1
  116. package/dist/utils/env-file.d.ts +17 -0
  117. package/dist/utils/env-file.js +96 -0
  118. package/dist/utils/error-code.d.ts +2 -0
  119. package/dist/utils/error-code.js +7 -0
  120. package/dist/utils/generate-space-name.d.ts +8 -10
  121. package/dist/utils/generate-space-name.js +206 -21
  122. package/dist/utils/grant-decision.fixtures.json +2938 -0
  123. package/dist/utils/grants.d.ts +2 -0
  124. package/dist/utils/grants.js +25 -2
  125. package/dist/utils/gravatar.d.ts +9 -0
  126. package/dist/utils/gravatar.js +31 -0
  127. package/dist/utils/idempotency.d.ts +6 -0
  128. package/dist/utils/idempotency.js +28 -0
  129. package/dist/utils/local-space-state.d.ts +1 -5
  130. package/dist/utils/local-space-state.js +7 -26
  131. package/dist/utils/page-fonts.d.ts +2 -2
  132. package/dist/utils/page-fonts.js +22 -4
  133. package/dist/utils/pages.d.ts +1 -2
  134. package/dist/utils/pages.js +21 -5
  135. package/dist/utils/publish-form-data.d.ts +12 -0
  136. package/dist/utils/publish-form-data.js +10 -0
  137. package/dist/utils/publish-policy.d.ts +20 -0
  138. package/dist/utils/publish-policy.fixtures.json +397 -0
  139. package/dist/utils/publish-policy.js +36 -19
  140. package/dist/utils/push-new.d.ts +7 -0
  141. package/dist/utils/push-new.js +7 -0
  142. package/dist/utils/query-keys.d.ts +0 -1
  143. package/dist/utils/query-keys.js +0 -1
  144. package/dist/utils/runtime-paths.d.ts +5 -0
  145. package/dist/utils/runtime-paths.js +5 -0
  146. package/dist/utils/runtime-upload-batch.d.ts +0 -5
  147. package/dist/utils/runtime-upload-batch.js +1 -27
  148. package/dist/utils/runtime-upload.d.ts +3 -13
  149. package/dist/utils/runtime-upload.js +4 -14
  150. package/dist/utils/space-config.d.ts +0 -33
  151. package/dist/utils/space-config.js +5 -326
  152. package/dist/utils/storage-policy.d.ts +1 -1
  153. package/dist/utils/storage-policy.js +3 -1
  154. package/dist/utils/structured-error.d.ts +14 -0
  155. package/dist/utils/structured-error.js +22 -0
  156. package/dist/utils/version-path.js +12 -3
  157. package/dist/vocabulary.d.ts +5 -3
  158. package/dist/vocabulary.js +13 -10
  159. package/package.json +10 -5
  160. package/dist/config/postgres-budget.d.ts +0 -129
  161. package/dist/config/postgres-budget.js +0 -140
  162. package/dist/config/postgres-budget.json +0 -51
  163. package/dist/contracts/archives.d.ts +0 -331
  164. package/dist/contracts/archives.js +0 -120
  165. package/dist/contracts/deployments.d.ts +0 -574
  166. package/dist/contracts/deployments.js +0 -97
  167. package/dist/contracts/sites.d.ts +0 -416
  168. package/dist/contracts/sites.js +0 -168
  169. package/dist/contracts/superadmin-queues.d.ts +0 -414
  170. package/dist/contracts/superadmin-queues.js +0 -202
  171. package/dist/contracts/superadmin-runtime.d.ts +0 -27
  172. package/dist/contracts/superadmin-runtime.js +0 -38
  173. package/dist/index.d.ts +0 -1
  174. package/dist/index.js +0 -1
  175. package/dist/utils/api.d.ts +0 -4
  176. package/dist/utils/api.js +0 -13
@@ -1,23 +1,65 @@
1
1
  import { z } from "zod";
2
2
  import { SPACE_SLUG_MAX_LENGTH } from "../slug-policy/index.js";
3
+ import { normalizeVersionPath } from "../utils/version-path.js";
3
4
  import { publishedAccessSchema } from "./access.js";
4
5
  import { AsyncOperationSchema, baseDiagnosticSchema, CursorPaginationSchema, cursorListQuerySchema, } from "./common.js";
5
6
  import { versionStatus, spaceStatus } from "./enums.js";
6
- import { runtimeKindSchema } from "./execution.js";
7
- import { conventionFilesSchema, uploadInstructionsSchema, manifestFileSchema } from "./internal.js";
7
+ import { conventionFilesSchema, uploadInstructionsSchema, manifestFileSchema, uploadManifestFileSchema, } from "./internal.js";
8
8
  import { VersionSchema, PublishSourceSchema, SpaceSchema, spaceSettingsDigestSchema, } from "./resources.js";
9
9
  import { runtimeAppSchema } from "./runtime-app.js";
10
10
  import { SPACE_CONFIG_ACCEPTED_FILES, spaceConfigSchema, spacePlacementConfigSchema, } from "./space-config.js";
11
11
  import { principalIdSchema } from "./transfers.js";
12
+ // Capacity accounting for the provider site a space runs on. A space IS a
13
+ // site, so occupancy is not a question — storage is. Warm-pool inventory rows
14
+ // carry the same shape before a space adopts them.
15
+ export const SpaceCapacitySchema = z
16
+ .object({
17
+ storageBytes: z
18
+ .number()
19
+ .int()
20
+ .nonnegative()
21
+ .optional()
22
+ .describe("Storage budget for the space in bytes."),
23
+ })
24
+ .describe("Capacity accounting for a space's provider site.");
25
+ export const SpacePressureSchema = z
26
+ .object({
27
+ ewmaLimitedPct: z.number().nonnegative().optional(),
28
+ ewma429: z.number().nonnegative().optional(),
29
+ ewma429PerMin: z.number().nonnegative().optional(),
30
+ ewmaWorkersMax: z.number().nonnegative().optional(),
31
+ ewmaCpuPct: z.number().nonnegative().optional(),
32
+ lastSampleAt: z.string().datetime().optional(),
33
+ consecutivePressured: z.number().int().nonnegative().optional(),
34
+ consecutiveClean: z.number().int().nonnegative().optional(),
35
+ // Monotonic CAS token shared by explicit operator hold actions and the
36
+ // pressure sampler. Every durable hold transition advances it, including
37
+ // transitions that restore a prior timestamp.
38
+ placementHoldRevision: z.number().int().nonnegative().optional(),
39
+ // Provenance stamp for the sampler's automatic hold: set on trip to the
40
+ // exact hold instant it wrote, so release only clears holds the pressure
41
+ // pipeline itself set — never an operator-set placement hold.
42
+ pressureHoldUntil: z.string().datetime().optional(),
43
+ // Last time a bulk-lane engine job on this space reported activity via the
44
+ // job callbacks (runtime/callback-events.ts); the sampler discounts the
45
+ // CPU signal while this is within the sampling window.
46
+ lastBulkLaneActivityAt: z.string().datetime().optional(),
47
+ })
48
+ .passthrough()
49
+ .describe("Placement pressure signals computed outside the request path.");
12
50
  export const spaceClaimReceiptSchema = z.object({
13
- token: z
51
+ key: z
14
52
  .string()
15
53
  .min(1)
16
- .describe("One-time, space-scoped credential returned only at anonymous space creation. Save it immediately. The server never shows it again. You need it to publish and manage the space until the space is claimed."),
54
+ .describe("The space key (sfc_…): the one credential for this unclaimed space. Bearer auth for publish, update, status, sharing, rotation, and the one-time continuation exchange. Returned only at creation and rotation; save it immediately."),
17
55
  url: z
18
56
  .string()
19
57
  .url()
20
- .describe("Browser-only claim link with a short-lived, one-use path token. The access origin consumes it into an HttpOnly handoff, then redirects to a clean claim page. API clients use the separate claim token as bearer auth for publish, update, status, and exchange."),
58
+ .describe("The site door: the live URL with the space key in /__/<key> form. Opening it exchanges the key for a private view session and lands on the site. Same key, URL form share it as carefully as the key."),
59
+ claimUrl: z
60
+ .string()
61
+ .url()
62
+ .describe("Claim page link in /claim#<key> form. The fragment is the key; browsers never send it to a server and the claim page strips it before analytics. Works until expiresAt and can be opened more than once."),
21
63
  expiresAt: z.string().datetime(),
22
64
  });
23
65
  export const SpaceCreateResponseSchema = z.object({
@@ -42,10 +84,6 @@ export const principalRefInputSchema = z.object({
42
84
  });
43
85
  export const spaceCreateSchema = z
44
86
  .object({
45
- // `siteId` selects the static site the space lives under. Optional today:
46
- // when omitted the tenant's default static site is resolved (internal-docs/platform.md "Site
47
- // Context Resolution"). Spaces are valid only under static sites.
48
- siteId: z.string().min(1).optional(),
49
87
  teamId: z.string().nullable().optional(),
50
88
  principal: principalRefInputSchema.optional(),
51
89
  slug: z.string().min(2).max(55).optional(),
@@ -108,50 +146,25 @@ export const spacePatchSchema = z
108
146
  });
109
147
  }
110
148
  });
111
- export const spaceClaimSchema = z
112
- .object({
113
- claimToken: z
114
- .string()
115
- .min(1)
116
- .describe("One-time claim token returned at anonymous creation. API clients send it as bearer auth; browser claim links carry a separate browser handoff credential."),
117
- teamId: z
149
+ // The one claim endpoint (POST /v1/claim). A converging loop: the caller sends
150
+ // what it has decided so far; the server either commits the claim or answers
151
+ // with the single decision still missing (`login_required`, `team_required`,
152
+ // `consent_required`).
153
+ export const anonymousClaimSchema = z.object({
154
+ key: z
118
155
  .string()
119
156
  .min(1)
120
157
  .optional()
121
- .describe("Team receiving the space. Inferred when you belong to exactly one team; otherwise required (`team_required`)."),
122
- targetTeamId: z
158
+ .describe("The space key, when not sent as bearer auth. Browser claim pages send it here after reading the /claim#<key> fragment."),
159
+ teamId: z
123
160
  .string()
124
161
  .min(1)
125
162
  .optional()
126
- .describe("Alias of teamId; must match when both are provided."),
127
- agentContinuation: z
128
- .boolean()
129
- .optional()
130
- .describe("User consent to keep the publishing agent authorized after the claim. The server independently proves continuation eligibility. Consent cannot grant continuation for an ineligible space."),
131
- })
132
- .superRefine((value, ctx) => {
133
- if (value.teamId && value.targetTeamId && value.teamId !== value.targetTeamId) {
134
- ctx.addIssue({
135
- code: z.ZodIssueCode.custom,
136
- path: ["teamId"],
137
- message: "teamId and targetTeamId must match when both are provided.",
138
- });
139
- }
140
- });
141
- export const anonymousClaimAssignSchema = z.object({
142
- teamId: z.string().min(1).optional(),
143
- nonce: z.string().min(1).optional().describe("Browser claim nonce from the claim handoff."),
144
- agentContinuation: z
145
- .boolean()
146
- .optional()
147
- .describe("User consent to keep the publishing agent authorized after the claim. The server independently proves continuation eligibility. Consent cannot grant continuation for an ineligible space."),
148
- });
149
- export const anonymousClaimResolveSchema = z.object({
150
- nonce: z.string().min(1).optional().describe("Browser claim nonce from the claim handoff."),
163
+ .describe("Team receiving the space. Inferred when the caller has exactly one writable team; otherwise the response answers `team_required` with the choices."),
151
164
  agentContinuation: z
152
165
  .boolean()
153
166
  .optional()
154
- .describe("User consent applied when resolve auto-claims. The server independently proves continuation eligibility. Consent cannot grant continuation for an ineligible space."),
167
+ .describe("User consent to keep the publishing agent authorized after the claim. Required (true or false) when the space is continuation-eligible; the server independently proves eligibility, so consent cannot grant continuation to an ineligible space."),
155
168
  });
156
169
  export const anonymousClaimTeamSchema = z.object({
157
170
  id: z.string(),
@@ -185,18 +198,20 @@ export const anonymousClaimSharingSummarySchema = z.object({
185
198
  });
186
199
  export const anonymousClaimResponseSchema = z.object({
187
200
  state: z.enum(["unclaimed", "claimed"]),
188
- action: z.enum(["claimed", "login_required", "team_required", "confirm_assign"]),
201
+ action: z.enum(["claimed", "login_required", "team_required", "consent_required"]),
189
202
  space: anonymousClaimSpacePreviewSchema,
190
203
  claim: z.object({
191
204
  expiresAt: z.string().datetime().nullable(),
192
205
  claimedAt: z.string().datetime().nullable(),
193
206
  }),
194
- access: publishedAccessSchema,
207
+ access: publishedAccessSchema
208
+ .optional()
209
+ .describe("The space's reusable Open link, returned once the claim commits so the page can open the (private-by-default) site. Pre-claim callers already hold the key and its door URL."),
195
210
  continuation: z
196
211
  .object({
197
212
  eligible: z
198
213
  .boolean()
199
- .describe("Server-proven continuation eligibility. Eligible means the publish intent records an originating agent that holds the claim token, the one-time exchange is unredeemed, and a safe secretless return exists. Only then can the UI offer continuation."),
214
+ .describe("Server-proven continuation eligibility. Eligible means the publish intent records an originating agent that holds the space key, the one-time exchange is unredeemed, and a safe secretless return exists. Only then can the UI offer continuation."),
200
215
  granted: z
201
216
  .boolean()
202
217
  .describe("Whether the claim left the one-time continuation exchange open for the originating agent."),
@@ -224,14 +239,16 @@ export const anonymousClaimStatusResponseSchema = z.object({
224
239
  }),
225
240
  claim: z.object({
226
241
  state: z.enum(["unclaimed", "claimed"]),
227
- url: z.string().nullable(),
242
+ url: z
243
+ .string()
244
+ .nullable()
245
+ .describe("Claim page link (/claim#<key>) while the space is unclaimed; null after."),
228
246
  expiresAt: z.string().datetime().nullable(),
229
247
  continuation: z
230
248
  .enum(["available", "used", "unavailable"])
231
249
  .optional()
232
- .describe("Present once the space is claimed. Whether this claim token can still be exchanged once for a durable API key (POST /v1/anonymous-claim/exchange)."),
250
+ .describe("Present once the space is claimed. Whether this key can still be exchanged once for a durable API key (POST /v1/claim/exchange)."),
233
251
  }),
234
- access: publishedAccessSchema,
235
252
  });
236
253
  export const anonymousClaimExchangeResponseSchema = z.object({
237
254
  space: z.object({
@@ -253,14 +270,7 @@ export const anonymousClaimRotateSchema = z.object({
253
270
  });
254
271
  export const anonymousClaimRotateResponseSchema = z.object({
255
272
  spaceId: z.string(),
256
- claimToken: z
257
- .string()
258
- .describe("Replacement claim token. Shown exactly once; store it before leaving this response."),
259
- claimNonce: z
260
- .string()
261
- .describe("Replacement browser claim nonce embedded in claimUrl. Shown exactly once."),
262
- claimUrl: z.string().url(),
263
- expiresAt: z.string().datetime(),
273
+ claim: spaceClaimReceiptSchema.describe("Replacement space key, door URL, and claim link. Shown exactly once; the previous key, its URLs, and its view sessions stop working."),
264
274
  });
265
275
  export const spaceClaimReminderSchema = z.object({
266
276
  email: z
@@ -320,8 +330,8 @@ export const spaceVersionCreateSchema = z
320
330
  .optional()
321
331
  .describe("Finalize intent for a declared upload. When every declared file lands, the version finalizes itself; the explicit finalize call remains available for recovery and replay."),
322
332
  files: z
323
- .array(manifestFileSchema)
324
- .describe("The complete desired file manifest. For first deploys, send `path`, `size`, and `contentType` without hashes so upload can begin immediately. For updates, include `sha256` so the server can skip unchanged files."),
333
+ .array(uploadManifestFileSchema)
334
+ .describe("The complete desired file manifest. Local-byte entries require `sha256` and are uploaded to a content-addressed target. A `sourceUrl` entry may omit `sha256` because the runtime computes it while fetching. Hashes also let updates skip unchanged files."),
325
335
  ...manifestMutationFieldsSchema,
326
336
  })
327
337
  .superRefine(refineManifestMutationRules);
@@ -408,36 +418,57 @@ export const spaceFilesResponseSchema = z.object({
408
418
  export const spaceVersionFilePathQuerySchema = z.object({
409
419
  path: z.string().min(1),
410
420
  });
411
- export const spaceVersionFileQuerySchema = spaceVersionFilePathQuerySchema.extend({
412
- download: z.string().optional(),
413
- });
414
- export const spaceVersionFileResponseSchema = z.object({
415
- versionId: z.string(),
416
- path: z.string(),
417
- size: z.number().int().nonnegative(),
418
- contentType: z.string().nullable(),
419
- sha256: z.string().nullable(),
420
- encoding: z.enum(["utf8", "base64"]),
421
- content: z.string(),
422
- truncated: z.boolean(),
423
- cached: z.boolean(),
421
+ /**
422
+ * Which representation of a path the runtime should hand back: `source` is the
423
+ * uploaded, pre-substitution object; `served` is the immutable byte the
424
+ * version actually serves. A private config input exists in `source` and is
425
+ * absent from `served`.
426
+ */
427
+ export const spaceVersionFileViewSchema = z.enum(["source", "served"]);
428
+ // Minting is a read, so it rides the URL — and a URL has a practical ceiling
429
+ // that a JSON body does not. Clients chunk; each chunk is one authorization.
430
+ export const VERSION_FILE_LINKS_MAX_PATHS = 200;
431
+ // Structural admission only. Whether the version HOLDS a path is the runtime's
432
+ // answer, given when the link is followed — the control plane keeps no catalog
433
+ // to check against and does not round-trip per path to fake one.
434
+ const spaceVersionFileLinkPathSchema = z
435
+ .string()
436
+ .min(1)
437
+ .refine((value) => {
438
+ try {
439
+ normalizeVersionPath(value);
440
+ return true;
441
+ }
442
+ catch {
443
+ return false;
444
+ }
445
+ }, { message: "Path must be version-relative, without traversal or control characters." });
446
+ /**
447
+ * Repeated `path` query parameters — `?path=index.html&path=about.html`. One
448
+ * path arrives as a bare string, so it is lifted into the batch shape before
449
+ * the per-path rules run.
450
+ */
451
+ export const spaceVersionFileLinksQuerySchema = z.object({
452
+ path: z
453
+ .preprocess((value) => (typeof value === "string" ? [value] : value), z.array(spaceVersionFileLinkPathSchema).min(1).max(VERSION_FILE_LINKS_MAX_PATHS))
454
+ .describe("Version-relative file paths to mint read links for; repeat the parameter per path."),
455
+ view: spaceVersionFileViewSchema
456
+ .default("source")
457
+ .describe("Which representation to read: the uploaded source or the served byte."),
458
+ });
459
+ export const spaceVersionFileLinkSchema = z.object({
460
+ url: z.string().url().describe("Short-lived signed URL that serves the file's bytes."),
461
+ expiresAt: z.string().describe("When the link stops working."),
424
462
  });
425
- export const spaceVersionFileUrlPreviewSchema = z.object({
463
+ /**
464
+ * Minting is blind to path validity — the control plane authorizes the version,
465
+ * not the path. A path that is not in the selected catalog view answers
466
+ * `version_file_not_found` when the link is followed.
467
+ */
468
+ export const spaceVersionFileLinksResponseSchema = z.object({
426
469
  versionId: z.string(),
427
- path: z.string(),
428
- sha256: z.string().nullable(),
429
- source: z.enum(["internet-shortcut", "webloc", "plain-url"]),
430
- url: z.string().url(),
431
- fetchedUrl: z.string().url().nullable(),
432
- title: z.string().nullable(),
433
- description: z.string().nullable(),
434
- siteName: z.string().nullable(),
435
- providerName: z.string().nullable(),
436
- authorName: z.string().nullable(),
437
- imageUrl: z.string().url().nullable(),
438
- oEmbedUrl: z.string().url().nullable(),
439
- status: z.enum(["ready", "unavailable"]),
440
- cached: z.boolean(),
470
+ view: spaceVersionFileViewSchema,
471
+ links: z.record(z.string(), spaceVersionFileLinkSchema),
441
472
  });
442
473
  export const spaceVersionConventionArtifactKindSchema = z.enum(["redirects", "headers"]);
443
474
  export const spaceVersionConventionArtifactPathSchema = z.enum(["_redirects", "_headers"]);
@@ -500,61 +531,15 @@ export const spaceVersionComputedRoutingSummarySchema = z.object({
500
531
  source: z.object({
501
532
  artifacts: z.array(spaceVersionConventionArtifactMetadataSchema),
502
533
  }),
534
+ // Finalize-written scalars, not a replay of a stored compiled-routing blob:
535
+ // the runtime owns the compile and reports these counts on its receipt.
503
536
  compiled: z.object({
504
537
  redirectRuleCount: z.number().int().nonnegative(),
505
538
  headerRuleCount: z.number().int().nonnegative(),
506
- staticRedirectCount: z.number().int().nonnegative(),
507
- dynamicRedirectCount: z.number().int().nonnegative(),
508
539
  proxyRuleCount: z.number().int().nonnegative(),
509
540
  }),
510
541
  diagnostics: z.array(spaceVersionRoutingDiagnosticSchema),
511
542
  });
512
- export const spaceVersionFileDiffStatusSchema = z.enum([
513
- "added",
514
- "modified",
515
- "deleted",
516
- "renamed",
517
- "unchanged",
518
- "binary",
519
- "too_large",
520
- ]);
521
- export const spaceVersionFileDiffEntrySchema = z.object({
522
- path: z.string(),
523
- oldPath: z.string().nullable(),
524
- status: spaceVersionFileDiffStatusSchema,
525
- before: spaceVersionFileSchema.nullable(),
526
- after: spaceVersionFileSchema.nullable(),
527
- patch: z
528
- .object({
529
- format: z.literal("unified"),
530
- content: z.string(),
531
- truncated: z.boolean(),
532
- truncationReason: z.literal("patch_byte_limit").nullable(),
533
- })
534
- .nullable(),
535
- patchOmission: z
536
- .enum(["input_too_large", "not_previewable", "content_unavailable", "patch_budget_exhausted"])
537
- .nullable(),
538
- });
539
- export const spaceVersionFileDiffQuerySchema = cursorListQuerySchema.extend({
540
- baseVersionId: z.string().optional(),
541
- });
542
- export const spaceVersionFileDiffResponseSchema = z.object({
543
- versionId: z.string(),
544
- baseVersionId: z.string().nullable(),
545
- files: z.array(spaceVersionFileDiffEntrySchema),
546
- pagination: CursorPaginationSchema,
547
- limits: z.object({
548
- maxFiles: z.number().int().positive(),
549
- maxInputBytes: z.number().int().positive(),
550
- maxPatchBytes: z.number().int().positive(),
551
- readConcurrency: z.number().int().positive(),
552
- }),
553
- usage: z.object({
554
- inputBytes: z.number().int().nonnegative(),
555
- patchBytes: z.number().int().nonnegative(),
556
- }),
557
- });
558
543
  // Upload state is inferable (internal-docs/platform.md L2216): `upload` present means bytes are
559
544
  // still needed (then finalize); `versionId` null means the manifest matched and nothing changed.
560
545
  // No redundant booleans ride along.
@@ -574,12 +559,11 @@ export const spaceVersionIntentResponseSchema = z.object({
574
559
  export const publishRequestSchema = z
575
560
  .object({
576
561
  spaceId: z.string().min(1).optional(),
577
- siteId: z.string().min(1).optional(),
578
562
  teamId: z.string().nullable().optional(),
579
563
  principal: principalRefInputSchema.optional(),
580
564
  files: z
581
- .array(manifestFileSchema)
582
- .describe("Desired file manifest for a declared publish session. Clients upload returned paths, then finalize."),
565
+ .array(uploadManifestFileSchema)
566
+ .describe("Desired file manifest for a declared publish session. Local-byte entries require `sha256`; sourceUrl entries may omit it. Clients upload returned targets, then finalize."),
583
567
  ...manifestMutationFieldsSchema,
584
568
  source: PublishSourceSchema.optional().describe('Publish provenance recorded on the version; defaults to {kind: "direct_upload"}.'),
585
569
  // Same fields, same bounds as spaceVersionCreateSchema: a publish that ran
@@ -680,7 +664,9 @@ export const publishNextSchema = z.object({
680
664
  });
681
665
  export const publishReceiptSchema = z.object({
682
666
  space: publishReceiptSpaceSchema,
683
- access: publishedAccessSchema.optional(),
667
+ access: publishedAccessSchema
668
+ .optional()
669
+ .describe("Reusable Open link for owned (team/external) publishes. Anonymous publishes get no separate access object: the space key in `claim` is the credential, and `claim.url` is the door."),
684
670
  version: publishReceiptVersionSchema,
685
671
  activation: publishActivationSchema,
686
672
  next: publishNextSchema,
@@ -711,7 +697,7 @@ export const publishReceiptSchema = z.object({
711
697
  status: z
712
698
  .string()
713
699
  .optional()
714
- .describe("Claim-token-authenticated anonymous publish status endpoint."),
700
+ .describe("Space-key-authenticated anonymous publish status endpoint."),
715
701
  })
716
702
  .optional()
717
703
  .describe("Follow-up links so agents can act on the receipt without knowing the full API."),
@@ -768,14 +754,11 @@ export const spaceRuntimeStatusSchema = z.object({
768
754
  .describe("Live space URL. It moves to the latest version after a successful publish to `live`."),
769
755
  runtimeState: spaceStatus.describe("Space operation-lifecycle status."),
770
756
  liveVersionStatus: versionStatus.nullable(),
771
- liveRuntimeKind: runtimeKindSchema
772
- .nullable()
773
- .describe("Runtime kind declared by the live version, if any."),
774
757
  pendingVersionStatus: versionStatus.nullable(),
775
758
  operation: AsyncOperationSchema.nullable(),
776
759
  app: runtimeAppSchema
777
760
  .nullable()
778
- .describe("What the live version runs: its Zero capsule or Functions worker, discriminated by `runtimeKind`. Null for a static space. Also null for callers whose credential does not carry `versions:read`, because app details read version contents, not serving state."),
761
+ .describe("What the live version runs: its Zero capsule and its Functions worker, each null when the published tree carries none of that product (both null for a static space). The whole object is null for callers whose credential does not carry `versions:read`, because app details read version contents, not serving state."),
779
762
  });
780
763
  export const spaceApplyChangeBaseSchema = z.object({
781
764
  kind: z.enum(["variable", "routing", "access", "settings"]),
@@ -2,6 +2,61 @@ import { z } from "zod";
2
2
  export declare const superadminActivityListQuerySchema: z.ZodObject<{
3
3
  limit: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
4
4
  }, z.core.$strip>;
5
+ export declare const superadminActivityEventQuerySchema: z.ZodObject<{
6
+ spaceId: z.ZodOptional<z.ZodString>;
7
+ tenantId: z.ZodOptional<z.ZodString>;
8
+ principalType: z.ZodOptional<z.ZodEnum<{
9
+ team: "team";
10
+ external: "external";
11
+ }>>;
12
+ principalId: z.ZodOptional<z.ZodString>;
13
+ actorType: z.ZodOptional<z.ZodEnum<{
14
+ system: "system";
15
+ user: "user";
16
+ api_key: "api_key";
17
+ oauth_client: "oauth_client";
18
+ anonymous_claim: "anonymous_claim";
19
+ }>>;
20
+ actorId: z.ZodOptional<z.ZodString>;
21
+ code: z.ZodOptional<z.ZodString>;
22
+ since: z.ZodOptional<z.ZodString>;
23
+ limit: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
24
+ cursor: z.ZodOptional<z.ZodString>;
25
+ }, z.core.$strip>;
26
+ export declare const SuperadminActivityEventSchema: z.ZodObject<{
27
+ id: z.ZodString;
28
+ sequence: z.ZodNumber;
29
+ tenantId: z.ZodString;
30
+ principalType: z.ZodNullable<z.ZodString>;
31
+ principalId: z.ZodNullable<z.ZodString>;
32
+ spaceId: z.ZodNullable<z.ZodString>;
33
+ actorType: z.ZodString;
34
+ actorId: z.ZodString;
35
+ code: z.ZodString;
36
+ message: z.ZodString;
37
+ details: z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
38
+ createdAt: z.ZodString;
39
+ }, z.core.$strip>;
40
+ export declare const SuperadminActivityEventListSchema: z.ZodObject<{
41
+ data: z.ZodArray<z.ZodObject<{
42
+ id: z.ZodString;
43
+ sequence: z.ZodNumber;
44
+ tenantId: z.ZodString;
45
+ principalType: z.ZodNullable<z.ZodString>;
46
+ principalId: z.ZodNullable<z.ZodString>;
47
+ spaceId: z.ZodNullable<z.ZodString>;
48
+ actorType: z.ZodString;
49
+ actorId: z.ZodString;
50
+ code: z.ZodString;
51
+ message: z.ZodString;
52
+ details: z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
53
+ createdAt: z.ZodString;
54
+ }, z.core.$strip>>;
55
+ pagination: z.ZodObject<{
56
+ nextCursor: z.ZodNullable<z.ZodString>;
57
+ hasMore: z.ZodBoolean;
58
+ }, z.core.$strip>;
59
+ }, z.core.$strip>;
5
60
  export declare const SuperadminLatestUserSchema: z.ZodObject<{
6
61
  id: z.ZodString;
7
62
  name: z.ZodString;
@@ -43,9 +98,7 @@ export declare const SuperadminLatestSpaceSchema: z.ZodObject<{
43
98
  teamSlug: z.ZodNullable<z.ZodString>;
44
99
  teamName: z.ZodNullable<z.ZodString>;
45
100
  externalCustomerId: z.ZodNullable<z.ZodString>;
46
- placementMode: z.ZodString;
47
101
  siteId: z.ZodNullable<z.ZodString>;
48
- siteClass: z.ZodNullable<z.ZodString>;
49
102
  siteStatus: z.ZodNullable<z.ZodString>;
50
103
  liveHostname: z.ZodNullable<z.ZodString>;
51
104
  disabledAt: z.ZodNullable<z.ZodString>;
@@ -65,9 +118,7 @@ export declare const SuperadminLatestSpaceListSchema: z.ZodObject<{
65
118
  teamSlug: z.ZodNullable<z.ZodString>;
66
119
  teamName: z.ZodNullable<z.ZodString>;
67
120
  externalCustomerId: z.ZodNullable<z.ZodString>;
68
- placementMode: z.ZodString;
69
121
  siteId: z.ZodNullable<z.ZodString>;
70
- siteClass: z.ZodNullable<z.ZodString>;
71
122
  siteStatus: z.ZodNullable<z.ZodString>;
72
123
  liveHostname: z.ZodNullable<z.ZodString>;
73
124
  disabledAt: z.ZodNullable<z.ZodString>;
@@ -198,6 +249,8 @@ export declare const SuperadminBadExperienceListSchema: z.ZodObject<{
198
249
  safetyReviews: z.ZodNumber;
199
250
  }, z.core.$strip>;
200
251
  }, z.core.$strip>;
252
+ export type SuperadminActivityEvent = z.infer<typeof SuperadminActivityEventSchema>;
253
+ export type SuperadminActivityEventQuery = z.infer<typeof superadminActivityEventQuerySchema>;
201
254
  export type SuperadminLatestUser = z.infer<typeof SuperadminLatestUserSchema>;
202
255
  export type SuperadminLatestSpace = z.infer<typeof SuperadminLatestSpaceSchema>;
203
256
  export type SuperadminLatestVersion = z.infer<typeof SuperadminLatestVersionSchema>;
@@ -1,7 +1,55 @@
1
1
  import { z } from "zod";
2
+ import { AnyObjectSchema, CursorPaginationSchema } from "./common.js";
2
3
  export const superadminActivityListQuerySchema = z.object({
3
4
  limit: z.coerce.number().int().min(1).max(100).default(50),
4
5
  });
6
+ // Cross-tenant reader over the `activity_events` audit log. Every superadmin
7
+ // mutation appends there, but only tenant-scoped /v1 readers existed; this is
8
+ // the operator's view of the same rows. At least one selective filter is
9
+ // required (see the route) so a query lands on one of the table's indexes
10
+ // instead of scanning the whole log.
11
+ export const superadminActivityEventQuerySchema = z.object({
12
+ spaceId: z.string().min(1).optional().describe("Filter to events for one Space, cross-tenant."),
13
+ tenantId: z.string().min(1).optional().describe("Filter to one tenant."),
14
+ principalType: z
15
+ .enum(["team", "external"])
16
+ .optional()
17
+ .describe("Owning principal kind; must be paired with principalId."),
18
+ principalId: z
19
+ .string()
20
+ .min(1)
21
+ .optional()
22
+ .describe("Owning principal id; must be paired with principalType."),
23
+ actorType: z
24
+ .enum(["user", "api_key", "oauth_client", "anonymous_claim", "system"])
25
+ .optional()
26
+ .describe("Actor kind; must be paired with actorId."),
27
+ actorId: z.string().min(1).optional().describe("Actor id; must be paired with actorType."),
28
+ code: z.string().min(1).optional().describe("Filter to one event code, e.g. `space.created`."),
29
+ since: z.string().datetime().optional().describe("Only events at or after this time."),
30
+ limit: z.coerce.number().int().min(1).max(200).default(50),
31
+ cursor: z.string().min(1).optional(),
32
+ });
33
+ // Operator surface: `message` and `details` are the raw audit payloads, not the
34
+ // tenant-facing projection. Nothing here widens any /v1 response.
35
+ export const SuperadminActivityEventSchema = z.object({
36
+ id: z.string(),
37
+ sequence: z.number().int().nonnegative(),
38
+ tenantId: z.string(),
39
+ principalType: z.string().nullable(),
40
+ principalId: z.string().nullable(),
41
+ spaceId: z.string().nullable(),
42
+ actorType: z.string(),
43
+ actorId: z.string(),
44
+ code: z.string(),
45
+ message: z.string(),
46
+ details: AnyObjectSchema.nullable(),
47
+ createdAt: z.string().datetime(),
48
+ });
49
+ export const SuperadminActivityEventListSchema = z.object({
50
+ data: z.array(SuperadminActivityEventSchema),
51
+ pagination: CursorPaginationSchema,
52
+ });
5
53
  export const SuperadminLatestUserSchema = z.object({
6
54
  id: z.string(),
7
55
  name: z.string(),
@@ -30,9 +78,7 @@ export const SuperadminLatestSpaceSchema = z.object({
30
78
  teamSlug: z.string().nullable(),
31
79
  teamName: z.string().nullable(),
32
80
  externalCustomerId: z.string().nullable(),
33
- placementMode: z.string(),
34
81
  siteId: z.string().nullable(),
35
- siteClass: z.string().nullable(),
36
82
  siteStatus: z.string().nullable(),
37
83
  liveHostname: z.string().nullable(),
38
84
  disabledAt: z.string().datetime().nullable(),