@spacefast/common 0.2.1 → 0.4.1

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 (226) hide show
  1. package/dist/agents/marketplace-prompts.d.ts +1 -0
  2. package/dist/agents/marketplace-prompts.js +6 -0
  3. package/dist/agents/registry/core.d.ts +4 -12
  4. package/dist/agents/registry/core.js +7 -28
  5. package/dist/config/domains.d.ts +10 -8
  6. package/dist/config/domains.js +4 -7
  7. package/dist/contracts/access-core.d.ts +135 -0
  8. package/dist/contracts/access-core.js +242 -0
  9. package/dist/contracts/access-profiles.d.ts +8 -8
  10. package/dist/contracts/access-profiles.js +8 -8
  11. package/dist/contracts/access.d.ts +14 -103
  12. package/dist/contracts/access.js +10 -210
  13. package/dist/contracts/activity.d.ts +54 -55
  14. package/dist/contracts/activity.js +38 -9
  15. package/dist/contracts/api-keys.d.ts +69 -26
  16. package/dist/contracts/api-keys.js +29 -2
  17. package/dist/contracts/application-journal.d.ts +197 -4
  18. package/dist/contracts/application-journal.js +97 -16
  19. package/dist/contracts/auth.d.ts +20 -0
  20. package/dist/contracts/auth.js +18 -0
  21. package/dist/contracts/beta.d.ts +13 -0
  22. package/dist/contracts/beta.js +28 -0
  23. package/dist/contracts/billing.d.ts +2 -2
  24. package/dist/contracts/bootstrap.d.ts +23 -6
  25. package/dist/contracts/builds.d.ts +24 -4
  26. package/dist/contracts/builds.js +16 -4
  27. package/dist/contracts/channels.d.ts +43 -0
  28. package/dist/contracts/channels.js +22 -6
  29. package/dist/contracts/comments.d.ts +49 -0
  30. package/dist/contracts/comments.js +61 -2
  31. package/dist/contracts/commerce.d.ts +19 -13
  32. package/dist/contracts/connector-access.d.ts +28 -0
  33. package/dist/contracts/connector-access.js +31 -0
  34. package/dist/contracts/connectors.d.ts +2382 -0
  35. package/dist/contracts/connectors.js +941 -0
  36. package/dist/contracts/content-contract-verification.d.ts +112 -58
  37. package/dist/contracts/content-contract-verification.js +42 -54
  38. package/dist/contracts/content-model-emit.d.ts +97 -0
  39. package/dist/contracts/content-model-emit.js +306 -0
  40. package/dist/contracts/content-model-sdk.d.ts +101 -0
  41. package/dist/contracts/content-model-sdk.js +232 -0
  42. package/dist/contracts/{content-program.d.ts → content-model.d.ts} +338 -82
  43. package/dist/contracts/{content-program.js → content-model.js} +291 -63
  44. package/dist/contracts/content-platform-fixture.d.ts +380 -110
  45. package/dist/contracts/content-platform-fixture.js +8 -8
  46. package/dist/contracts/content-sync.d.ts +197 -74
  47. package/dist/contracts/content-sync.js +98 -37
  48. package/dist/contracts/content.d.ts +30 -422
  49. package/dist/contracts/content.js +34 -294
  50. package/dist/contracts/dashboard-prefs.d.ts +10 -3
  51. package/dist/contracts/dashboard-prefs.js +6 -3
  52. package/dist/contracts/data-location.d.ts +9 -0
  53. package/dist/contracts/data-location.js +7 -0
  54. package/dist/contracts/deployment-comparison.d.ts +67 -0
  55. package/dist/contracts/deployment-comparison.js +68 -0
  56. package/dist/contracts/device-auth.d.ts +55 -11
  57. package/dist/contracts/domains.d.ts +40 -16
  58. package/dist/contracts/domains.js +23 -0
  59. package/dist/contracts/enums.d.ts +1 -10
  60. package/dist/contracts/enums.js +0 -15
  61. package/dist/contracts/error-code-meta.d.ts +388 -20
  62. package/dist/contracts/error-code-meta.js +201 -5
  63. package/dist/contracts/error-codes.d.ts +17 -4
  64. package/dist/contracts/error-codes.js +109 -10
  65. package/dist/contracts/events.d.ts +5 -0
  66. package/dist/contracts/events.js +12 -3
  67. package/dist/contracts/execution.d.ts +5 -1
  68. package/dist/contracts/execution.js +4 -0
  69. package/dist/contracts/feature-lifecycle.d.ts +53 -20
  70. package/dist/contracts/feature-lifecycle.js +65 -23
  71. package/dist/contracts/features.d.ts +57 -31
  72. package/dist/contracts/features.js +0 -1
  73. package/dist/contracts/feedback.d.ts +124 -0
  74. package/dist/contracts/feedback.js +64 -0
  75. package/dist/contracts/fixtures/content-model-sdk-v1.generated.d.ts +129 -0
  76. package/dist/contracts/fixtures/content-model-sdk-v1.generated.js +48 -0
  77. package/dist/contracts/fixtures/content-platform-v1.json +101 -49
  78. package/dist/contracts/frame-session.d.ts +60 -10
  79. package/dist/contracts/frame-session.js +52 -12
  80. package/dist/contracts/functions.d.ts +28 -2
  81. package/dist/contracts/functions.js +25 -2
  82. package/dist/contracts/grant-copy.d.ts +2 -0
  83. package/dist/contracts/grant-copy.js +2 -0
  84. package/dist/contracts/grants-core.d.ts +95 -0
  85. package/dist/contracts/grants-core.js +435 -0
  86. package/dist/contracts/grants.d.ts +13 -84
  87. package/dist/contracts/grants.js +21 -369
  88. package/dist/contracts/ids-core.d.ts +11 -0
  89. package/dist/contracts/ids-core.js +14 -0
  90. package/dist/contracts/ids.d.ts +7 -4
  91. package/dist/contracts/ids.js +12 -4
  92. package/dist/contracts/internal.d.ts +18 -0
  93. package/dist/contracts/internal.js +19 -0
  94. package/dist/contracts/mcp.d.ts +8 -18
  95. package/dist/contracts/mcp.js +2 -23
  96. package/dist/contracts/notifications.d.ts +4 -1
  97. package/dist/contracts/notifications.js +1 -0
  98. package/dist/contracts/oauth-resources.d.ts +55 -9
  99. package/dist/contracts/oauth-resources.js +64 -1
  100. package/dist/contracts/oauth-scope-actions.d.ts +27 -3
  101. package/dist/contracts/oauth-scope-actions.js +18 -8
  102. package/dist/contracts/operations.d.ts +1 -1
  103. package/dist/contracts/partner-account.d.ts +629 -0
  104. package/dist/contracts/partner-account.js +18 -0
  105. package/dist/contracts/principal-assertion.d.ts +74 -1
  106. package/dist/contracts/principal-assertion.js +67 -3
  107. package/dist/contracts/publish-archive.d.ts +22 -1
  108. package/dist/contracts/push-new.d.ts +3 -3
  109. package/dist/contracts/push-new.js +1 -1
  110. package/dist/contracts/quotas.js +2 -1
  111. package/dist/contracts/repository-connections.d.ts +10 -6
  112. package/dist/contracts/repository-connections.js +15 -0
  113. package/dist/contracts/resources.d.ts +6 -5
  114. package/dist/contracts/resources.js +7 -0
  115. package/dist/contracts/route-inventory.d.ts +74 -19
  116. package/dist/contracts/route-inventory.js +20 -6
  117. package/dist/contracts/runtime-api.d.ts +415 -4
  118. package/dist/contracts/runtime-api.js +60 -15
  119. package/dist/contracts/runtime-app.d.ts +6 -1
  120. package/dist/contracts/runtime-components.d.ts +646 -18
  121. package/dist/contracts/runtime-components.js +304 -188
  122. package/dist/contracts/runtime-services.d.ts +15 -0
  123. package/dist/contracts/runtime-services.js +25 -0
  124. package/dist/contracts/runtime-storage.d.ts +32 -0
  125. package/dist/contracts/runtime-storage.js +37 -0
  126. package/dist/contracts/source-workspaces.d.ts +511 -0
  127. package/dist/contracts/source-workspaces.js +276 -0
  128. package/dist/contracts/space-config-spacefast.d.ts +394 -0
  129. package/dist/contracts/space-config-spacefast.js +70 -0
  130. package/dist/contracts/space-config.d.ts +177 -90
  131. package/dist/contracts/space-config.js +77 -92
  132. package/dist/contracts/spaces.d.ts +132 -24
  133. package/dist/contracts/spaces.js +77 -13
  134. package/dist/contracts/superadmin-connectors.d.ts +371 -0
  135. package/dist/contracts/superadmin-connectors.js +61 -0
  136. package/dist/contracts/superadmin-emails.d.ts +1 -1
  137. package/dist/contracts/superadmin-emails.js +1 -1
  138. package/dist/contracts/superadmin-entities.d.ts +105 -0
  139. package/dist/contracts/superadmin-entities.js +64 -0
  140. package/dist/contracts/superadmin-runtime.d.ts +35 -116
  141. package/dist/contracts/superadmin-runtime.js +13 -69
  142. package/dist/contracts/superadmin-search.d.ts +12 -14
  143. package/dist/contracts/superadmin-search.js +2 -2
  144. package/dist/contracts/superadmin-spaces.d.ts +15 -72
  145. package/dist/contracts/superadmin-spaces.js +2 -7
  146. package/dist/contracts/superadmin-teams.d.ts +12 -0
  147. package/dist/contracts/superadmin-teams.js +7 -1
  148. package/dist/contracts/superadmin-tenants.d.ts +44 -16
  149. package/dist/contracts/superadmin.d.ts +2 -2
  150. package/dist/contracts/tags.d.ts +12 -12
  151. package/dist/contracts/teams.d.ts +29 -1
  152. package/dist/contracts/teams.js +24 -2
  153. package/dist/contracts/tenants.d.ts +98 -0
  154. package/dist/contracts/tenants.js +20 -0
  155. package/dist/contracts/transfers.d.ts +92 -0
  156. package/dist/contracts/transfers.js +37 -0
  157. package/dist/contracts/usage.d.ts +9 -1
  158. package/dist/contracts/usage.js +2 -0
  159. package/dist/contracts/visual-review.d.ts +448 -0
  160. package/dist/contracts/visual-review.js +156 -0
  161. package/dist/contracts/wordpress-php-toolkit.json +9 -0
  162. package/dist/contracts/work-mode.d.ts +24 -0
  163. package/dist/contracts/work-mode.js +17 -0
  164. package/dist/contracts/wp-cli.d.ts +66 -0
  165. package/dist/contracts/wp-cli.js +68 -0
  166. package/dist/contracts/zero-catalog.d.ts +29 -0
  167. package/dist/contracts/zero-catalog.js +55 -0
  168. package/dist/contracts/zero-platform-abilities.generated.d.ts +31 -0
  169. package/dist/contracts/zero-platform-abilities.generated.js +373 -0
  170. package/dist/contracts/zero-spacefast.d.ts +444 -0
  171. package/dist/contracts/zero-spacefast.js +149 -0
  172. package/dist/contracts/zero-types.d.ts +47 -0
  173. package/dist/contracts/zero-types.js +263 -0
  174. package/dist/contracts/zero.d.ts +781 -14
  175. package/dist/contracts/zero.js +204 -10
  176. package/dist/dashboard-paths/index.d.ts +2 -2
  177. package/dist/dashboard-paths/route-reservations.generated.d.ts +2 -2
  178. package/dist/dashboard-paths/route-reservations.generated.js +5 -0
  179. package/dist/docs/agent-prose.d.ts +1 -1
  180. package/dist/docs/agent-prose.js +15 -18
  181. package/dist/docs/agent-setup.d.ts +1 -1
  182. package/dist/docs/agent-setup.js +5 -13
  183. package/dist/docs/catalog.d.ts +64 -28
  184. package/dist/docs/catalog.js +155 -28
  185. package/dist/docs/error-docs.d.ts +365 -17
  186. package/dist/docs/error-docs.js +369 -21
  187. package/dist/docs/reference-urls.js +1 -1
  188. package/dist/docs/skills.d.ts +84 -84
  189. package/dist/docs/skills.js +66 -47
  190. package/dist/docs/start-prompts.d.ts +14 -0
  191. package/dist/docs/start-prompts.js +20 -0
  192. package/dist/utils/account-labels.d.ts +7 -0
  193. package/dist/utils/account-labels.js +15 -0
  194. package/dist/utils/auth.d.ts +1 -0
  195. package/dist/utils/auth.js +1 -0
  196. package/dist/utils/credential-policy.d.ts +22 -1
  197. package/dist/utils/credential-policy.js +55 -6
  198. package/dist/utils/local-space-state.d.ts +7 -0
  199. package/dist/utils/local-space-state.js +7 -0
  200. package/dist/utils/logger.d.ts +34 -0
  201. package/dist/utils/logger.js +144 -0
  202. package/dist/utils/page-routes.d.ts +9 -0
  203. package/dist/utils/page-routes.js +82 -0
  204. package/dist/utils/pages.d.ts +2 -0
  205. package/dist/utils/pages.js +7 -0
  206. package/dist/utils/publish-form-data.d.ts +2 -0
  207. package/dist/utils/publish-form-data.js +2 -0
  208. package/dist/utils/publish-policy-spacefast.d.ts +13 -0
  209. package/dist/utils/publish-policy-spacefast.js +117 -0
  210. package/dist/utils/publish-policy.d.ts +22 -16
  211. package/dist/utils/publish-policy.fixtures.json +15 -0
  212. package/dist/utils/publish-policy.js +62 -139
  213. package/dist/utils/query-client.js +9 -1
  214. package/dist/utils/runtime-upload.d.ts +4 -0
  215. package/dist/utils/runtime-upload.js +5 -0
  216. package/dist/utils/space-config.d.ts +2 -3
  217. package/dist/utils/space-config.js +1 -1
  218. package/dist/utils/uploaded-source.d.ts +4 -0
  219. package/dist/utils/uploaded-source.js +12 -0
  220. package/dist/visual-review.d.ts +4 -0
  221. package/dist/visual-review.js +208 -0
  222. package/dist/vocabulary.d.ts +38 -0
  223. package/dist/vocabulary.js +55 -0
  224. package/package.json +7 -2
  225. package/dist/agents/registry/deeplink-probes.d.ts +0 -23
  226. package/dist/agents/registry/deeplink-probes.js +0 -18
@@ -1,5 +1,8 @@
1
1
  import { z } from "zod";
2
+ import { connectorRoleSchema } from "./connectors.js";
3
+ import { contentStableIdSchema } from "./content-model.js";
2
4
  import { appRoutePathSchema, EXECUTION_ENV_MAX_KEYS, executionBundleSchema, executionCapabilitiesSchema, executionEnvNameSchema, executionIdentifierSchema, executionInspectPolicySchema, executionSha256Schema, executionStaticFileSchema, httpMethodSchema, LAKEBED_SERVER_ENV_FILE, PLATFORM_ROUTE_PREFIX, runtimeRealtimeModeSchema, SERVER_ENV_FILE, } from "./execution.js";
5
+ import { compiledContentModelArtifactsV1Schema, runtimeCapabilityIdSchema, } from "./runtime-components.js";
3
6
  /**
4
7
  * Spacefast Zero: capsules of schema, queries, mutations and endpoints that run
5
8
  * together inside one parent-owned transaction, executed by the native runner
@@ -18,7 +21,19 @@ export const ZERO_SOURCE_METADATA_KEY = "statticZero";
18
21
  * worker.
19
22
  */
20
23
  export const ZERO_RUNTIME_KIND = "zero";
21
- export const ZERO_PLATFORM_ROUTE_PREFIX = `${PLATFORM_ROUTE_PREFIX}/zero`;
24
+ /**
25
+ * The canonical Zero control namespace. Every Zero HTTP control route lives
26
+ * under this prefix; new clients, the dev server, the runtime engine and the
27
+ * finalizer all emit it.
28
+ */
29
+ export const ZERO_PLATFORM_ROUTE_PREFIX = "/__zero";
30
+ /**
31
+ * The pre-cutover namespace, served forever as an alias of the canonical one.
32
+ * Frozen capsules baked clients that fetch these paths at build time and a
33
+ * republish cannot be assumed, so the runtime answers both prefixes with the
34
+ * same handlers and never redirects between them.
35
+ */
36
+ export const ZERO_LEGACY_ROUTE_PREFIX = `${PLATFORM_ROUTE_PREFIX}/zero`;
22
37
  /**
23
38
  * Entry paths the Zero scaffold writes into `sf.jsonc#runtime`. Starting points
24
39
  * only: a capsule's entries are whatever its `runtime.server`/`runtime.client`
@@ -33,9 +48,27 @@ export const ZERO_RUNTIME_ROUTE_PATHS = {
33
48
  db: `${ZERO_PLATFORM_ROUTE_PREFIX}/db`,
34
49
  logs: `${ZERO_PLATFORM_ROUTE_PREFIX}/logs`,
35
50
  run: `${ZERO_PLATFORM_ROUTE_PREFIX}/run`,
36
- authStart: `${ZERO_PLATFORM_ROUTE_PREFIX}/auth/gravatar/start`,
51
+ // Provider-agnostic on purpose: which identity providers answer it (Gravatar
52
+ // today, WordPress.com as the option lands) is the auth flow's business, not
53
+ // the URL's.
54
+ authStart: `${ZERO_PLATFORM_ROUTE_PREFIX}/auth/start`,
37
55
  authSignOut: `${ZERO_PLATFORM_ROUTE_PREFIX}/auth/sign-out`,
38
56
  };
57
+ /**
58
+ * The same operations under {@link ZERO_LEGACY_ROUTE_PREFIX}, spelled exactly
59
+ * as frozen clients baked them (note `auth/gravatar/start`). Registration-side
60
+ * only: handlers register both, emission always uses the canonical paths.
61
+ */
62
+ export const ZERO_LEGACY_ROUTE_PATHS = {
63
+ config: `${ZERO_LEGACY_ROUTE_PREFIX}/config`,
64
+ realtime: `${ZERO_LEGACY_ROUTE_PREFIX}/realtime`,
65
+ inspect: `${ZERO_LEGACY_ROUTE_PREFIX}/inspect`,
66
+ db: `${ZERO_LEGACY_ROUTE_PREFIX}/db`,
67
+ logs: `${ZERO_LEGACY_ROUTE_PREFIX}/logs`,
68
+ run: `${ZERO_LEGACY_ROUTE_PREFIX}/run`,
69
+ authStart: `${ZERO_LEGACY_ROUTE_PREFIX}/auth/gravatar/start`,
70
+ authSignOut: `${ZERO_LEGACY_ROUTE_PREFIX}/auth/sign-out`,
71
+ };
39
72
  export const ZERO_RUNTIME_STORAGE_ROOT = "__spacefast/zero";
40
73
  export const ZERO_RUNTIME_ARTIFACT_PATH = `${ZERO_RUNTIME_STORAGE_ROOT}/artifact.json`;
41
74
  export const ZERO_RUNTIME_CONFIG_PATH = `${ZERO_RUNTIME_STORAGE_ROOT}/config.json`;
@@ -64,6 +97,20 @@ export const ZERO_PLATFORM_ASSET_ROOT = `${ZERO_PLATFORM_ASSET_NAMESPACE}/platfo
64
97
  export function zeroPlatformAssetPath(digest, fileName) {
65
98
  return `${ZERO_PLATFORM_ASSET_ROOT}/${digest}/${fileName}`;
66
99
  }
100
+ /**
101
+ * Where a capsule's island bytes serve from: one content-addressed directory per
102
+ * build.
103
+ *
104
+ * Capsule code, unlike {@link ZERO_PLATFORM_ASSET_ROOT} — these are the author's
105
+ * own components, code-split. They share the namespace because they share its
106
+ * one property that matters: the URL names the bytes, so a browser holding the
107
+ * previous build's chunk never serves it for this one.
108
+ */
109
+ export const ZERO_ISLANDS_ASSET_ROOT = `${ZERO_PLATFORM_ASSET_NAMESPACE}/islands`;
110
+ /** The serving path of one file in the island bundle identified by `digest`. */
111
+ export function zeroIslandAssetPath(digest, fileName) {
112
+ return `${ZERO_ISLANDS_ASSET_ROOT}/${digest}/${fileName}`;
113
+ }
67
114
  /**
68
115
  * The compiled capsule server, which the QuickJS runner instantiates whole.
69
116
  *
@@ -120,8 +167,108 @@ const zeroRoutePathSchema = appRoutePathSchema({
120
167
  reservedPaths: ZERO_RESERVED_APP_ROUTE_PATHS,
121
168
  reservedPrefixes: ZERO_RESERVED_APP_ROUTE_PREFIXES,
122
169
  });
170
+ const zeroPageAppPathSchema = appRoutePathSchema({
171
+ subject: "Zero pages",
172
+ reservedPaths: [
173
+ ...ZERO_RESERVED_APP_ROUTE_PATHS.filter((path) => path !== "/"),
174
+ ZERO_PLATFORM_ROUTE_PREFIX,
175
+ "/zero",
176
+ ],
177
+ reservedPrefixes: [
178
+ ...ZERO_RESERVED_APP_ROUTE_PREFIXES,
179
+ `${ZERO_PLATFORM_ROUTE_PREFIX}/`,
180
+ "/zero/",
181
+ ],
182
+ });
183
+ export const zeroPagePathSchema = z.string().superRefine((path, ctx) => {
184
+ const segments = path.split("/");
185
+ if (segments.some((segment, index) => segment.startsWith(".") && !(index === 1 && segment.toLowerCase() === ".well-known")) ||
186
+ ["/.well-known/spacefast-runtime", "/.well-known/stattic-runtime"].includes(path.toLowerCase())) {
187
+ ctx.addIssue({ code: "custom", message: "Zero pages cannot use a runtime-private path." });
188
+ }
189
+ const params = new Set();
190
+ for (const [index, segment] of segments.entries()) {
191
+ if (!segment.startsWith(":") && !segment.startsWith("*"))
192
+ continue;
193
+ const name = segment.slice(1);
194
+ if (!/^[A-Za-z_$][A-Za-z0-9_$]*$/.test(name) ||
195
+ params.has(name) ||
196
+ (segment.startsWith("*") && index !== segments.length - 1)) {
197
+ ctx.addIssue({
198
+ code: "custom",
199
+ message: "Zero pages require unique named parameters and a terminal catch-all.",
200
+ });
201
+ }
202
+ params.add(name);
203
+ }
204
+ const parsed = zeroPageAppPathSchema.safeParse(segments
205
+ .map((segment) => segment.startsWith("*") ? ":splat" : segment.startsWith(":") ? ":param" : segment)
206
+ .join("/"));
207
+ if (!parsed.success) {
208
+ for (const issue of parsed.error.issues)
209
+ ctx.addIssue({ code: "custom", message: issue.message });
210
+ }
211
+ if (path === `/${ZERO_PLATFORM_ASSET_NAMESPACE}` || path === `/${ZERO_RUNTIME_STORAGE_ROOT}`) {
212
+ ctx.addIssue({
213
+ code: "custom",
214
+ message: "Zero pages cannot use a path the platform reserves.",
215
+ });
216
+ }
217
+ });
218
+ export const ZERO_PUBLIC_CLIENT_SHELL_PATH = "_spacefast/pages/client.html";
219
+ const zeroPageFields = {
220
+ id: contentStableIdSchema,
221
+ path: zeroPagePathSchema,
222
+ file: z.string().min(1),
223
+ params: z.array(z.string()),
224
+ };
225
+ export const zeroPageSchema = z
226
+ .discriminatedUnion("render", [
227
+ z
228
+ .object({
229
+ ...zeroPageFields,
230
+ render: z.literal("document"),
231
+ bindingId: contentStableIdSchema,
232
+ })
233
+ .strict(),
234
+ z
235
+ .object({
236
+ ...zeroPageFields,
237
+ render: z.literal("client"),
238
+ shell: z.literal(ZERO_PUBLIC_CLIENT_SHELL_PATH),
239
+ })
240
+ .strict(),
241
+ ])
242
+ .superRefine((page, ctx) => {
243
+ const params = page.path
244
+ .split("/")
245
+ .filter((segment) => /^[*:]/.test(segment))
246
+ .map((segment) => segment.slice(1));
247
+ if (params.length !== page.params.length ||
248
+ params.some((param, index) => param !== page.params[index])) {
249
+ ctx.addIssue({
250
+ code: "custom",
251
+ path: ["params"],
252
+ message: "Page parameters must match the route, in order.",
253
+ });
254
+ }
255
+ if (page.render === "document" && params.length > 0) {
256
+ ctx.addIssue({
257
+ code: "custom",
258
+ path: ["path"],
259
+ message: "Document pages require a literal route.",
260
+ });
261
+ }
262
+ });
263
+ /**
264
+ * What an invocation is allowed to do. Every Zero invocation declares it, and
265
+ * the runtime opens the matching transaction: a `read` runs on one read-only
266
+ * consistent snapshot, a `write` on the handler's own transaction.
267
+ */
268
+ export const zeroExecutionModeSchema = z.enum(["read", "write"]);
123
269
  export const zeroEndpointSchema = z
124
270
  .object({
271
+ mode: zeroExecutionModeSchema,
125
272
  method: httpMethodSchema,
126
273
  path: zeroRoutePathSchema,
127
274
  })
@@ -251,6 +398,12 @@ export const zeroTableSchema = z
251
398
  }
252
399
  });
253
400
  export const zeroDatabaseSchema = z.record(z.string(), zeroTableSchema);
401
+ export const ZERO_BUILD_CONTEXT_ENV = "SPACEFAST_ZERO_BUILD_CONTEXT";
402
+ export const zeroBuildContextSchema = z
403
+ .object({
404
+ previousSchema: zeroDatabaseSchema.nullable(),
405
+ })
406
+ .strict();
254
407
  const zeroSha256Schema = executionSha256Schema;
255
408
  /**
256
409
  * The compiled server travels inline in the finalize payload, which keeps the
@@ -267,10 +420,16 @@ export const zeroRuntimeBundleSchema = executionBundleSchema({
267
420
  export const zeroRuntimeStaticFileSchema = executionStaticFileSchema({
268
421
  storageRoot: ZERO_RUNTIME_STORAGE_ROOT,
269
422
  maxBytes: ZERO_CLIENT_BUNDLE_MAX_BYTES,
270
- platformAssetRoot: ZERO_PLATFORM_ASSET_ROOT,
423
+ // The whole namespace, not just `platform/`: it already holds two
424
+ // content-addressed directories — the platform build and a capsule's island
425
+ // bundle — and {@link ZERO_RESERVED_APP_ROUTE_PREFIXES} reserves all of it
426
+ // from capsule routes for exactly that reason. A third would be the compiler's
427
+ // too, and enumerating them here would only ever be a list to forget.
428
+ platformAssetRoot: ZERO_PLATFORM_ASSET_NAMESPACE,
271
429
  });
272
430
  export const zeroRuntimeRunSourceSchema = z
273
431
  .object({
432
+ executionMode: zeroExecutionModeSchema,
274
433
  runId: z.string().min(1).max(256),
275
434
  source: z
276
435
  .string()
@@ -283,6 +442,7 @@ export const zeroRuntimeRunSourceSchema = z
283
442
  .strict();
284
443
  export const zeroRuntimeEndpointSourceSchema = z
285
444
  .object({
445
+ executionMode: zeroExecutionModeSchema,
286
446
  method: httpMethodSchema,
287
447
  path: zeroRoutePathSchema,
288
448
  endpointId: z.string().min(1).max(256),
@@ -506,6 +666,9 @@ export const zeroCapsuleArtifactSchema = z
506
666
  format: z.literal("stattic.zero.capsule.v1"),
507
667
  appName: z.string().min(1).max(128),
508
668
  serverRuntime: z.literal("quickjs-rust"),
669
+ requiredRuntimeCapabilities: z.array(runtimeCapabilityIdSchema).max(100).optional(),
670
+ pages: z.array(zeroPageSchema).optional(),
671
+ connectors: z.array(connectorRoleSchema).default([]),
509
672
  client: z
510
673
  .object({
511
674
  bundlePath: z.string().min(1),
@@ -518,7 +681,6 @@ export const zeroCapsuleArtifactSchema = z
518
681
  schema: zeroDatabaseSchema.default({}),
519
682
  queries: z.array(zeroNameSchema).default([]),
520
683
  mutations: z.array(zeroNameSchema).default([]),
521
- actions: z.array(zeroNameSchema).default([]),
522
684
  endpoints: z.array(zeroEndpointSchema).default([]),
523
685
  sockets: z.array(zeroNameSchema).default([]),
524
686
  })
@@ -576,9 +738,23 @@ export const zeroRuntimeFinalizePayloadSchema = z
576
738
  auth: z
577
739
  .object({
578
740
  provider: z.literal("gravatar").default("gravatar"),
579
- signInPath: z.literal(ZERO_RUNTIME_ROUTE_PATHS.authStart).nullable().default(null),
741
+ // Canonical or legacy spelling: configs frozen before the /__zero
742
+ // cutover carry the legacy paths and must keep validating.
743
+ signInPath: z
744
+ .union([
745
+ z.literal(ZERO_RUNTIME_ROUTE_PATHS.authStart),
746
+ z.literal(ZERO_LEGACY_ROUTE_PATHS.authStart),
747
+ ])
748
+ .nullable()
749
+ .default(null),
580
750
  signInUrl: zeroHttpUrlSchema.nullable().default(null),
581
- signOutPath: z.literal(ZERO_RUNTIME_ROUTE_PATHS.authSignOut).nullable().default(null),
751
+ signOutPath: z
752
+ .union([
753
+ z.literal(ZERO_RUNTIME_ROUTE_PATHS.authSignOut),
754
+ z.literal(ZERO_LEGACY_ROUTE_PATHS.authSignOut),
755
+ ])
756
+ .nullable()
757
+ .default(null),
582
758
  signOutUrl: zeroHttpUrlSchema.nullable().default(null),
583
759
  returnToParam: z.string().min(1).max(64).default("returnTo"),
584
760
  })
@@ -611,14 +787,30 @@ export const zeroRuntimeConfigSchema = zeroRuntimeFinalizePayloadSchema
611
787
  inspect: true,
612
788
  })
613
789
  .extend({
790
+ connectors: z.object({ token: z.string().min(1) }).optional(),
614
791
  variableValues: z.record(z.string(), z.string()).default({}),
615
792
  databaseUrlSource: z.enum(["application", "provider"]).default("application"),
616
793
  })
617
794
  .strict();
795
+ /**
796
+ * The `statticZero` bag a published version carries in its source metadata.
797
+ *
798
+ * `contentModel` rides here beside `finalize` because both are compiled from
799
+ * the same capsule in the same publish, and both must roll back with the
800
+ * version that shipped them. The bag stays `.strict()`: this schema is parsed
801
+ * on the finalize path, so an unrecognized key is a compiler and a control
802
+ * plane that disagree about what a publish carries, and that is worth failing
803
+ * on rather than dropping silently.
804
+ */
618
805
  export const zeroDeployMetadataSchema = z
619
806
  .object({
807
+ connectorsTokenHash: z
808
+ .string()
809
+ .regex(/^[a-f0-9]{64}$/)
810
+ .optional(),
620
811
  artifactId: z.string().min(1).optional(),
621
812
  finalize: zeroRuntimeFinalizePayloadSchema,
813
+ contentModel: compiledContentModelArtifactsV1Schema.optional(),
622
814
  })
623
815
  .strict();
624
816
  /**
@@ -647,7 +839,6 @@ export const zeroAppSchema = z
647
839
  tables: z.array(z.string()).default([]),
648
840
  queries: z.array(z.string()).default([]),
649
841
  mutations: z.array(z.string()).default([]),
650
- actions: z.array(z.string()).default([]),
651
842
  endpoints: z.array(zeroEndpointSchema).default([]),
652
843
  sockets: z.array(z.string()).default([]),
653
844
  /**
@@ -710,9 +901,10 @@ export function isDestructiveZeroMigrationOperation(operation) {
710
901
  operation.op === "rename_column");
711
902
  }
712
903
  export function createZeroCapsuleArtifact(input) {
713
- return zeroCapsuleArtifactSchema.parse({
904
+ const artifact = {
714
905
  format: "stattic.zero.capsule.v1",
715
906
  appName: input.appName,
907
+ connectors: input.connectors ?? [],
716
908
  serverRuntime: "quickjs-rust",
717
909
  client: {
718
910
  bundlePath: input.clientBundlePath ?? ZERO_PUBLIC_CLIENT_BUNDLE_PATH,
@@ -723,7 +915,6 @@ export function createZeroCapsuleArtifact(input) {
723
915
  schema: input.schema ?? {},
724
916
  queries: input.queries ?? [],
725
917
  mutations: input.mutations ?? [],
726
- actions: input.actions ?? [],
727
918
  endpoints: input.endpoints ?? [],
728
919
  sockets: input.sockets ?? [],
729
920
  },
@@ -745,7 +936,10 @@ export function createZeroCapsuleArtifact(input) {
745
936
  sourceRoot: ".",
746
937
  files: [],
747
938
  },
748
- });
939
+ };
940
+ if (input.pages?.length)
941
+ artifact.pages = input.pages;
942
+ return zeroCapsuleArtifactSchema.parse(artifact);
749
943
  }
750
944
  export function createZeroRuntimeInstallProfile(input) {
751
945
  return zeroRuntimeInstallProfileSchema.parse({
@@ -4,9 +4,9 @@
4
4
  */
5
5
  export declare const UNBUILT_SPACE_SLUG_ROUTE_RESERVATIONS: readonly ["connect"];
6
6
  /** Dashboard route first-segments that cannot be used as team slugs. */
7
- export declare const TEAM_SLUG_ROUTE_RESERVATIONS: readonly ["accept-beta-invite", "accept-invitation", "access", "account", "approvals", "claim", "device", "drop", "new-team", "oauth", "push", "sign-in", "start", "terminal", "two-factor"];
7
+ export declare const TEAM_SLUG_ROUTE_RESERVATIONS: readonly ["accept-beta-invite", "accept-invitation", "access", "account", "approvals", "claim", "device", "domains", "drop", "new-team", "oauth", "partners", "push", "sign-in", "spaces", "start", "terminal", "two-factor"];
8
8
  /** Dashboard route first-segments that cannot be used as space slugs. */
9
- export declare const SPACE_SLUG_ROUTE_RESERVATIONS: readonly ["agents", "api-keys", "billing", "domains", "drop", "handoffs", "members", "new", "resume", "settings", "variables", "webhooks", "connect"];
9
+ export declare const SPACE_SLUG_ROUTE_RESERVATIONS: readonly ["agents", "api-keys", "billing", "connectors", "domains", "drop", "handoffs", "members", "new", "partners", "resume", "settings", "variables", "webhooks", "connect"];
10
10
  export type TeamSlugRouteReservation = (typeof TEAM_SLUG_ROUTE_RESERVATIONS)[number];
11
11
  export type SpaceSlugRouteReservation = (typeof SPACE_SLUG_ROUTE_RESERVATIONS)[number];
12
12
  export declare const TEAM_SLUG_ROUTE_RESERVATION_SET: ReadonlySet<string>;
@@ -1,2 +1,2 @@
1
- export declare const DERIVED_TEAM_SLUG_ROUTE_RESERVATIONS: readonly ["accept-beta-invite", "accept-invitation", "access", "account", "approvals", "claim", "device", "drop", "new-team", "oauth", "push", "sign-in", "start", "terminal", "two-factor"];
2
- export declare const DERIVED_SPACE_SLUG_ROUTE_RESERVATIONS: readonly ["agents", "api-keys", "billing", "domains", "drop", "handoffs", "members", "new", "resume", "settings", "variables", "webhooks"];
1
+ export declare const DERIVED_TEAM_SLUG_ROUTE_RESERVATIONS: readonly ["accept-beta-invite", "accept-invitation", "access", "account", "approvals", "claim", "device", "domains", "drop", "new-team", "oauth", "partners", "push", "sign-in", "spaces", "start", "terminal", "two-factor"];
2
+ export declare const DERIVED_SPACE_SLUG_ROUTE_RESERVATIONS: readonly ["agents", "api-keys", "billing", "connectors", "domains", "drop", "handoffs", "members", "new", "partners", "resume", "settings", "variables", "webhooks"];
@@ -11,11 +11,14 @@ export const DERIVED_TEAM_SLUG_ROUTE_RESERVATIONS = [
11
11
  "approvals",
12
12
  "claim",
13
13
  "device",
14
+ "domains",
14
15
  "drop",
15
16
  "new-team",
16
17
  "oauth",
18
+ "partners",
17
19
  "push",
18
20
  "sign-in",
21
+ "spaces",
19
22
  "start",
20
23
  "terminal",
21
24
  "two-factor",
@@ -24,11 +27,13 @@ export const DERIVED_SPACE_SLUG_ROUTE_RESERVATIONS = [
24
27
  "agents",
25
28
  "api-keys",
26
29
  "billing",
30
+ "connectors",
27
31
  "domains",
28
32
  "drop",
29
33
  "handoffs",
30
34
  "members",
31
35
  "new",
36
+ "partners",
32
37
  "resume",
33
38
  "settings",
34
39
  "variables",
@@ -9,7 +9,7 @@ export declare const LANE_PICKER_PROSE: string;
9
9
  export declare const HOW_TO_RESEARCH_PROSE: string;
10
10
  /** Curl/API skill lane: docs URLs only, no MCP or CLI tools required. */
11
11
  export declare const HOW_TO_RESEARCH_API_PROSE: string;
12
- /** MCP plugin skill lane: prefer skills for workflows and execute for the OpenAPI catalog. */
12
+ /** MCP plugin skill lane: use execute for documentation and the OpenAPI catalog. */
13
13
  export declare const HOW_TO_RESEARCH_MCP_PROSE: string;
14
14
  export declare const ENV_NOTES_PROSE: string;
15
15
  export declare const ENV_NOTES_API_PROSE: string;
@@ -86,13 +86,15 @@ export const EXPLAIN_TO_USER_PROSE = [
86
86
  ].join("\n");
87
87
  export const FEEDBACK_PROSE = "With user approval, send feedback with `sf feedback`, MCP `execute` (search `send feedback`), or `POST /v1/feedback`. Never include credentials or private links.";
88
88
  export const FAILURE_CONDUCT_PROSE = [
89
- "On failure, surface the problem document's `code`, `type`, and `requestId`, then stop.",
90
- "Do not invent undocumented endpoints. Do not read credentials out of auth files. Retrying a",
91
- "failed publish with the same files is safe: it returns the Space the first attempt created.",
89
+ "On failure, report the problem document's `code`, `type`, and `requestId`. Follow its documented recovery.",
90
+ "Do not invent endpoints or read credentials out of auth files. After an uncertain write,",
91
+ "reuse its retry ID and exact input. Identical files alone do not make a new request safe to retry.",
92
+ "For authenticated MCP publish, set `requestId` before the first call. For HTTP writes, follow",
93
+ "the endpoint's idempotency contract. When a receipt provides a status operation, read it before another write.",
92
94
  FEEDBACK_PROSE,
93
95
  ].join("\n");
94
96
  export const LANE_PICKER_PROSE = [
95
- "Pick the lane by environment: a one-off publish means curl; a git checkout means the push.new",
97
+ "Pick the lane by environment: a one-off publish means curl; a git checkout means the git.spacefast.com",
96
98
  "remote; repeat work with a filesystem means the CLI — the best setup, `npx -y spacefast` runs it",
97
99
  "with no install, and `sf plugins` installs your client's plugin; no filesystem means hosted MCP;",
98
100
  "CI means a machine OAuth client. After success, recommend the best next-time setup for the",
@@ -110,11 +112,11 @@ export const HOW_TO_RESEARCH_API_PROSE = [
110
112
  "`https://spacefast.com/llms.txt`. For contracts, read `https://spacefast.com/publish-spec.json`",
111
113
  "or the OpenAPI linked from the API docs. Never guess limits: publish, then read diagnostics.",
112
114
  ].join("\n");
113
- /** MCP plugin skill lane: prefer skills for workflows and execute for the OpenAPI catalog. */
115
+ /** MCP plugin skill lane: use execute for documentation and the OpenAPI catalog. */
114
116
  export const HOW_TO_RESEARCH_MCP_PROSE = [
115
- "For an error, fetch the problem document's `type` URL when present. For workflows and how-to",
116
- "recipes, call `search_docs`; the `skills` tool serves the `execute` guide, not workflow recipes.",
117
- "For capability questions, use `execute` with `tools.search`.",
117
+ "For an error, fetch the problem document's `type` URL when present. For workflows, how-to",
118
+ "recipes, and capability questions, use one `execute` program with `tools.search`.",
119
+ "Search for and describe the generated documentation operation before you call it.",
118
120
  "For contracts, read `publish-spec.json` or OpenAPI via docs. Never guess limits: publish,",
119
121
  "then inspect status or diagnostics through `execute`.",
120
122
  ].join("\n");
@@ -161,15 +163,10 @@ export const CHECK_BEFORE_PUBLISH_API_PROSE = [
161
163
  "and the user wants a new one.",
162
164
  ].join("\n");
163
165
  export const CHECK_BEFORE_PUBLISH_MCP_PROSE = [
164
- "Before creating a space, check whether this project already has one:",
165
- "",
166
- "- Look for `.spacefast/space.json` or `.spacefast/state.json`, walking up from the working",
167
- " directory toward the filesystem root (On-Device reuses this link automatically).",
168
- "- Look for a publish receipt earlier in this conversation.",
169
- "- When authenticated, use `execute` to call the generated list-spaces operation.",
170
- "",
171
- "If any of these finds a space, publish a new version to that space instead of creating",
172
- "another. Only create a new space when none exists and the user wants a new one.",
166
+ "Use the Space from the current conversation or checkout link for an ordinary publish.",
167
+ "On-Device reuses `.spacefast/` automatically. Do not read its credential file or list all",
168
+ "Spaces before publishing. Hosted callers must pass the known `spaceId` to update a Space.",
169
+ "Set `createNew` only when the user requests a separate Space. Do not also set `spaceId`.",
173
170
  ].join("\n");
174
171
  /**
175
172
  * The SAVE verb: persist the space id and credential after a first publish so
@@ -236,7 +233,7 @@ export const PUSH_TO_DEPLOY_PROSE = [
236
233
  "and pushing are one credential, not two.",
237
234
  "",
238
235
  "```bash",
239
- "git remote add spacefast https://t:<key>@push.new/<space-slug>.git",
236
+ "git remote add spacefast https://t:<key>@git.spacefast.com/<space-slug>.git",
240
237
  "git push spacefast main",
241
238
  "```",
242
239
  "",
@@ -37,7 +37,7 @@ export declare const AGENT_HANDOFF_CLI_TARGET_IDS: readonly ConnectTargetId[];
37
37
  export declare const AGENT_HANDOFF_PREAMBLE = "Talk to the user before you install tools or publish. Confirm the file or folder to publish.";
38
38
  export declare const AGENT_HANDOFF_CREDENTIAL_HYGIENE = "Keep the handoff URL out of command arguments, logs, and replies. It goes in exactly two places: the stdin prompt of `sf setup agent`, or the redeem request body.";
39
39
  export declare const AGENT_HANDOFF_CLI_APPROVAL_GUIDANCE: string;
40
- export declare const AGENT_HANDOFF_PUBLISH_PROSE = "After login, confirm the Space and the files with the user, then publish the simplest way that fits: a one-off through `sf publish` or the publish API; a git checkout by pushing to the Space's push.new remote (`git.remoteUrl`); for repeat work the CLI is best, and `sf plugins` installs your client's plugin. Report the Live URL and the immutable Version URL; keep the private Access URL out of shared replies. Create a scoped Link only when a recipient needs access.";
40
+ export declare const AGENT_HANDOFF_PUBLISH_PROSE = "After login, confirm the Space and the files with the user, then publish the simplest way that fits: a one-off through `sf publish` or the publish API; a git checkout by pushing to the Space's git.spacefast.com remote (`git.remoteUrl`); for repeat work the CLI is best, and `sf plugins` installs your client's plugin. Report the Live URL and the immutable Version URL; keep the private Access URL out of shared replies. Create a scoped Link only when a recipient needs access.";
41
41
  /** One target's Connect prose: blurb, copyable setup blocks, deeplink/download lines. */
42
42
  export declare function agentHandoffConnectSections(target: ConnectTarget): string[];
43
43
  /**
@@ -17,15 +17,9 @@ export const agentSetupPrompt = `Fetch ${agentSetupUrl}`;
17
17
  // The no-install publish: one POST, no account. Single-sourced so the marketing
18
18
  // pages and the setup doc can never show different commands.
19
19
  //
20
- // `?wait=1` is load-bearing. Without it the 201 returns
21
- // `activation.outcome: "pending"` and a `next.action: "poll"` pointer at an
22
- // endpoint that needs the space key as bearer (measured in production: a receipt
23
- // at ~4.2s for a site that only settles ~37s later). With it the publish returns
24
- // `activated` / `done`, so the happy path is genuinely one command.
25
- //
26
- // The URL is quoted because `?` globs in zsh: unquoted, the command dies with
27
- // "no matches found" before curl ever runs.
28
- export const anonymousPublishCurlCommand = `curl -F "files=@index.html" "${serviceOrigin("api", "prod")}/v1/publish?wait=1"`;
20
+ // Omit `async` to wait for finalize. A publish that reaches the request ceiling
21
+ // still returns a polling receipt; agents must follow its `next` instruction.
22
+ export const anonymousPublishCurlCommand = `curl -F "files=@index.html" "${serviceOrigin("api", "prod")}/v1/publish"`;
29
23
  /*
30
24
  * Agent handoff contract: one opaque bearer lives at
31
25
  * https://<access-origin>/handoffs/<token>. Fetching that URL records a read and
@@ -140,7 +134,7 @@ function hostedHandoffTargetName(value) {
140
134
  return value;
141
135
  }
142
136
  }
143
- export const AGENT_HANDOFF_PUBLISH_PROSE = "After login, confirm the Space and the files with the user, then publish the simplest way that fits: a one-off through `sf publish` or the publish API; a git checkout by pushing to the Space's push.new remote (`git.remoteUrl`); for repeat work the CLI is best, and `sf plugins` installs your client's plugin. Report the Live URL and the immutable Version URL; keep the private Access URL out of shared replies. Create a scoped Link only when a recipient needs access.";
137
+ export const AGENT_HANDOFF_PUBLISH_PROSE = "After login, confirm the Space and the files with the user, then publish the simplest way that fits: a one-off through `sf publish` or the publish API; a git checkout by pushing to the Space's git.spacefast.com remote (`git.remoteUrl`); for repeat work the CLI is best, and `sf plugins` installs your client's plugin. Report the Live URL and the immutable Version URL; keep the private Access URL out of shared replies. Create a scoped Link only when a recipient needs access.";
144
138
  /** One target's Connect prose: blurb, copyable setup blocks, deeplink/download lines. */
145
139
  export function agentHandoffConnectSections(target) {
146
140
  // When the client's best lane IS its config file, `primary` and `config` are
@@ -381,9 +375,7 @@ function oauthClientNames() {
381
375
  }
382
376
  /** Clients that have a live one-click install today, named from the registry. */
383
377
  function deeplinkClientNames() {
384
- return AGENT_REGISTRY.filter((agent) => agent.methods.some((method) => method.kind === "deeplink" &&
385
- method.listing.status === "live" &&
386
- method.verification.status !== "failed"))
378
+ return AGENT_REGISTRY.filter((agent) => agent.methods.some((method) => method.kind === "deeplink" && method.listing.status === "live"))
387
379
  .map((agent) => agent.name)
388
380
  .join(", ");
389
381
  }