@spacefast/common 0.2.2 → 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 +18 -4
  26. package/dist/contracts/builds.js +7 -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 +384 -20
  62. package/dist/contracts/error-code-meta.js +200 -5
  63. package/dist/contracts/error-codes.d.ts +17 -4
  64. package/dist/contracts/error-codes.js +108 -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 +46 -9
  99. package/dist/contracts/oauth-resources.js +50 -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 +361 -17
  186. package/dist/docs/error-docs.js +365 -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,8 +1,6 @@
1
1
  import { z } from "zod";
2
- import { serviceOrigin } from "../config/domains.js";
3
2
  import { normalizeSlug } from "../utils/slug.js";
4
- import { defaultPlanNameSchema, planCatalogSchema } from "./commerce.js";
5
- import { GRANT_RESOURCE_PATTERN_LIMIT, identityConnectionPublicKeySchema, normalizeGrantResourcePattern, } from "./grants.js";
3
+ import { GRANT_RESOURCE_PATTERN_LIMIT, identityConnectionPublicKeySchema, normalizeGrantResourcePattern, } from "./grants-core.js";
6
4
  export const SPACE_CONFIG_CANONICAL_FILE = "sf.jsonc";
7
5
  export const SPACE_CONFIG_ALIAS_FILES = [
8
6
  "spacefast.jsonc",
@@ -74,16 +72,16 @@ export const SPACE_CONFIG_CAPS = {
74
72
  /** Max `system.api.allowedOrigins` entries. */
75
73
  systemApiAllowedOrigins: 32,
76
74
  /** Max `system.tokenIssuers` entries. */
77
- systemTokenIssuers: 16,
75
+ systemTokenIssuers: 1,
78
76
  /** Max `system.tokenIssuers[].issuer` length. */
79
77
  systemIssuerChars: 512,
80
78
  /** Max `system.tokenIssuers[].keys` entries. */
81
- systemIssuerKeys: 16,
79
+ systemIssuerKeys: 5,
82
80
  /** Max `system.tokenIssuers[].keys[].kid` length. */
83
81
  systemKeyIdChars: 64,
84
82
  /** Exact raw Ed25519 public-key length after base64url encoding. */
85
83
  systemPublicKeyChars: 43,
86
- /** Max `system.tokenIssuers[].proof` length. */
84
+ /** Max `system.tokenIssuers[].proofs[]` length. */
87
85
  systemProofChars: 4096,
88
86
  /** Max `system.subscriptions` entries. */
89
87
  systemSubscriptions: 32,
@@ -92,8 +90,15 @@ export const SPACE_CONFIG_CAPS = {
92
90
  /** Max length of a `system.subscriptions[].events` name. */
93
91
  systemEventChars: 128,
94
92
  };
95
- /** Published JSON Schema URL for `sf.jsonc` ($schema autocomplete). */
96
- export const SPACE_CONFIG_SCHEMA_URL = `${serviceOrigin("www", "prod")}/schemas/sf.json`;
93
+ /**
94
+ * Published JSON Schema URL for `sf.jsonc` ($schema autocomplete).
95
+ *
96
+ * A format identifier, not a brand string: the `$schema` an editor resolves is
97
+ * one document at one URL for every space, so it is compiled in rather than
98
+ * resolved through the hostname registry. The literal is checked against that
99
+ * registry in `config/domains.test.ts`.
100
+ */
101
+ export const SPACE_CONFIG_SCHEMA_URL = "https://spacefast.com/schemas/sf.json";
97
102
  // Pages theme tokens: presentation only, never layout, behavior, or protocol.
98
103
  // The color grammar accepts hex, rgb(a), hsl(a), and named CSS colors, and
99
104
  // rejects anything that could escape a style context.
@@ -168,9 +173,8 @@ export const spaceBuildSettingsSchema = z
168
173
  })
169
174
  .strict()
170
175
  .describe("Remote build settings used by repository builds.");
171
- // Every space gets its own site, so there is nothing to place between: no mode,
172
- // no region knob. `burstable` says whether the space's site may burst provider
173
- // PHP workers. Data location is chosen once, at creation, and never changes.
176
+ // Placement controls whether the Space's site may burst provider PHP workers.
177
+ // Data location is chosen once, at creation, and never changes.
174
178
  export const spacePlacementConfigSchema = z
175
179
  .object({
176
180
  burstable: z.boolean().optional(),
@@ -484,11 +488,8 @@ const spaceConfigBaseSchema = z.object({
484
488
  .boolean()
485
489
  .optional()
486
490
  .describe("Accepted serving flag; runtime enforcement ships separately."),
487
- // Undescribed on purpose (hidden, experimental): enables the finalize-time
488
- // build pipeline. Accepted without diagnostics.
489
- experimental_gutenberg: z.boolean().optional(),
490
- // Hidden, experimental: static HTML snippets, honored only when
491
- // `experimental_gutenberg` is true. Byte caps are enforced by the shared
491
+ // Hidden, experimental: static HTML snippets injected into served pages,
492
+ // honored whenever they are present. Byte caps are enforced by the shared
492
493
  // validator (inject_snippet_too_large / inject_invalid).
493
494
  inject: z
494
495
  .object({
@@ -847,18 +848,49 @@ export const systemHostnamesSchema = z
847
848
  .describe("Apex hostname for the white-label surface."),
848
849
  })
849
850
  .strict();
851
+ const systemHttpsOriginSchema = systemHttpsUrlSchema
852
+ .refine((value) => {
853
+ try {
854
+ const url = new URL(value);
855
+ return (url.protocol === "https:" &&
856
+ !url.username &&
857
+ !url.password &&
858
+ !url.search &&
859
+ !url.hash &&
860
+ url.pathname === "/" &&
861
+ SYSTEM_HOSTNAME_PATTERN.test(url.hostname));
862
+ }
863
+ catch {
864
+ return false;
865
+ }
866
+ }, "must be an HTTPS origin without credentials, path, query, or fragment")
867
+ .transform((value) => new URL(value).origin);
850
868
  export const systemApiSchema = z
851
869
  .object({
852
- origin: systemHttpsUrlSchema
870
+ origin: systemHttpsOriginSchema
871
+ .refine((value) => new URL(value).port === "", "custom API origins use the default HTTPS port")
853
872
  .optional()
854
873
  .describe("https origin the partner API is served from."),
855
874
  allowedOrigins: z
856
- .array(systemHttpsUrlSchema)
875
+ .array(systemHttpsOriginSchema)
857
876
  .max(SPACE_CONFIG_CAPS.systemApiAllowedOrigins)
858
877
  .optional()
859
878
  .describe("https origins permitted to call the partner API (CORS)."),
860
879
  })
861
880
  .strict();
881
+ export const systemTokenIssuerKeysSchema = z
882
+ .array(identityConnectionPublicKeySchema)
883
+ .min(1)
884
+ .max(SPACE_CONFIG_CAPS.systemIssuerKeys)
885
+ .refine((keys) => new Set(keys.map((key) => key.kid)).size === keys.length, {
886
+ message: "Key IDs must be unique.",
887
+ })
888
+ .describe("Public verification keys, addressed by unique key ID.");
889
+ export const systemTokenIssuerProofsSchema = z
890
+ .array(z.string().trim().min(1).max(SPACE_CONFIG_CAPS.systemProofChars))
891
+ .min(1)
892
+ .max(SPACE_CONFIG_CAPS.systemIssuerKeys)
893
+ .describe("Signed challenge JWTs, one per new key, to activate the issuer or rotate keys. Read audience and challenge from manifestStatus.");
862
894
  export const systemTokenIssuerSchema = z
863
895
  .object({
864
896
  issuer: z
@@ -867,18 +899,8 @@ export const systemTokenIssuerSchema = z
867
899
  .min(1)
868
900
  .max(SPACE_CONFIG_CAPS.systemIssuerChars)
869
901
  .describe("Issuer identifier (the iss claim tokens must carry)."),
870
- keys: z
871
- .array(identityConnectionPublicKeySchema)
872
- .min(1)
873
- .max(SPACE_CONFIG_CAPS.systemIssuerKeys)
874
- .describe("Public verification keys, addressed by key id."),
875
- proof: z
876
- .string()
877
- .trim()
878
- .min(1)
879
- .max(SPACE_CONFIG_CAPS.systemProofChars)
880
- .optional()
881
- .describe("Ownership proof that completes the two-publish issuer activation."),
902
+ keys: systemTokenIssuerKeysSchema,
903
+ proofs: systemTokenIssuerProofsSchema.optional(),
882
904
  })
883
905
  .strict();
884
906
  export const systemSubscriptionSchema = z
@@ -891,6 +913,13 @@ export const systemSubscriptionSchema = z
891
913
  .describe("Event names delivered to this subscription."),
892
914
  })
893
915
  .strict();
916
+ /**
917
+ * Metering is the host's, not the format's: what a plan is, what it costs and
918
+ * which quotas it carries is Spacefast's commerce model. The manifest's plan
919
+ * catalog is therefore declared in `./space-config-spacefast.js`, which extends
920
+ * this object — parse an sf.jsonc that may declare plans through
921
+ * `spacefastSpaceConfigFileSchema` there, never through the schema below.
922
+ */
894
923
  export const spaceSystemManifestSchema = z
895
924
  .object({
896
925
  presentation: systemPresentationSchema.optional(),
@@ -900,35 +929,14 @@ export const spaceSystemManifestSchema = z
900
929
  .array(systemTokenIssuerSchema)
901
930
  .max(SPACE_CONFIG_CAPS.systemTokenIssuers)
902
931
  .optional()
903
- .describe("Trusted token issuers registered for the tenant."),
932
+ .describe("One trusted token issuer for the tenant. Omit this field or declare an empty array to revoke it."),
904
933
  subscriptions: z
905
934
  .array(systemSubscriptionSchema)
906
935
  .max(SPACE_CONFIG_CAPS.systemSubscriptions)
907
936
  .optional()
908
937
  .describe("Event subscriptions (webhooks) the tenant declares."),
909
- plans: planCatalogSchema
910
- .optional()
911
- .describe("Per-tenant plan catalog: plan name → { features, quotas.spaces, quotaPolicy }. Feature keys validated against the live vocabulary; plan names are arbitrary."),
912
- defaultPlan: defaultPlanNameSchema
913
- .optional()
914
- .describe("Plan unassigned principals fall back to. Must be a key in `plans`."),
915
938
  })
916
939
  .strict()
917
- .superRefine((manifest, ctx) => {
918
- if (manifest.defaultPlan === undefined) {
919
- return;
920
- }
921
- // A defaultPlan is only meaningful against a declared catalog: it must name a
922
- // plan the same manifest declares, or gate resolution would fall back to a
923
- // plan that does not exist.
924
- if (manifest.plans === undefined || !(manifest.defaultPlan in manifest.plans)) {
925
- ctx.addIssue({
926
- code: z.ZodIssueCode.custom,
927
- path: ["defaultPlan"],
928
- message: "defaultPlan must be one of the plan names declared in `plans`.",
929
- });
930
- }
931
- })
932
940
  .describe("Control-plane manifest for a tenant's designated system space. Parsed and reconciled by the control plane; ignored by other spaces.");
933
941
  export const spaceConfigFileSchema = spaceConfigBaseSchema.extend({
934
942
  $schema: z
@@ -956,29 +964,6 @@ export const spaceConfigFileSchema = spaceConfigBaseSchema.extend({
956
964
  .optional()
957
965
  .describe("Control-plane system-space manifest. Honored only for a tenant's designated system space; other spaces' declarations are ignored."),
958
966
  });
959
- /**
960
- * The published JSON Schema artifact for `sf.jsonc`, generated from the
961
- * zod file schema. Served at SPACE_CONFIG_SCHEMA_URL so editors and agents get
962
- * autocomplete and validation.
963
- */
964
- export function spaceConfigJsonSchema() {
965
- const schema = stripHiddenSpaceConfigKeys({
966
- ...z.toJSONSchema(spaceConfigFileSchema, { target: "draft-7", io: "input" }),
967
- $id: SPACE_CONFIG_SCHEMA_URL,
968
- title: "Spacefast space configuration (sf.jsonc)",
969
- });
970
- // `redirects`, `rewrites` and `headers` are real sf.jsonc keys owned by the
971
- // routing compiler, not by the serving shape above, so they are described
972
- // here. Without them an editor reads the documented routing examples as
973
- // unknown keys.
974
- return {
975
- ...schema,
976
- properties: {
977
- ...schema.properties,
978
- ...SPACE_CONFIG_ROUTING_SCHEMA_PROPERTIES,
979
- },
980
- };
981
- }
982
967
  // The `!` and `name=:capture` of a `_redirects` line, shared by both rule
983
968
  // sections and by `config::strict::public_json_schema`.
984
969
  const SPACE_CONFIG_ROUTING_FORCE_SCHEMA = {
@@ -989,10 +974,16 @@ const SPACE_CONFIG_ROUTING_FORCE_SCHEMA = {
989
974
  const SPACE_CONFIG_ROUTING_QUERY_SCHEMA = {
990
975
  type: "object",
991
976
  description: 'Query parameters the request must carry, as parameter name to capture name: { "id": "id" } is the name=:capture token id=:id.',
992
- propertyNames: { pattern: "^[A-Za-z][A-Za-z0-9_-]*$" },
977
+ propertyNames: { pattern: "^[A-Za-z_][A-Za-z0-9_-]*$" },
993
978
  additionalProperties: { type: "string", pattern: "^[A-Za-z][A-Za-z0-9_]*$" },
994
979
  };
995
- const SPACE_CONFIG_ROUTING_SCHEMA_PROPERTIES = {
980
+ /**
981
+ * Routing keys as JSON Schema. `redirects`, `rewrites` and `headers` are real
982
+ * sf.jsonc keys owned by the routing compiler rather than by the serving shape
983
+ * above, so a generated schema has to describe them separately or an editor
984
+ * reads the documented routing examples as unknown keys.
985
+ */
986
+ export const SPACE_CONFIG_ROUTING_SCHEMA_PROPERTIES = {
996
987
  redirects: {
997
988
  type: "array",
998
989
  description: "Browser redirect rules. Same matcher grammar as _redirects, and _redirects rules match first.",
@@ -1096,15 +1087,14 @@ const SPACE_CONFIG_ROUTING_SCHEMA_PROPERTIES = {
1096
1087
  },
1097
1088
  };
1098
1089
  /*
1099
- * `experimental_gutenberg` and its `inject` companion are ACCEPTED by the parser
1100
- * but never published: the bare key names alone would document the feature to
1101
- * every editor and agent reading a schema artifact. Every generator that derives
1102
- * a public artifact from the SpaceConfig zod shape (the sf.jsonc JSON Schema,
1103
- * the www publish-spec, the SDK OpenAPI documents) must run it through this
1104
- * stripper. The published schemas set no additionalProperties constraint, so
1105
- * configs using the hidden keys still validate. `inject` is removed only when it
1106
- * carries the SpaceConfig static-placement shape, so unrelated properties of the
1107
- * same name survive.
1090
+ * `inject` is ACCEPTED by the parser but never published: the bare key name
1091
+ * alone would document the feature to every editor and agent reading a schema
1092
+ * artifact. Every generator that derives a public artifact from the SpaceConfig
1093
+ * zod shape (the sf.jsonc JSON Schema, the www publish-spec, the SDK OpenAPI
1094
+ * documents) must run it through this stripper. The published schemas set no
1095
+ * additionalProperties constraint, so configs using the hidden key still
1096
+ * validate. `inject` is removed only when it carries the SpaceConfig
1097
+ * static-placement shape, so unrelated properties of the same name survive.
1108
1098
  */
1109
1099
  export function stripHiddenSpaceConfigKeys(schema) {
1110
1100
  if (Array.isArray(schema)) {
@@ -1115,12 +1105,7 @@ export function stripHiddenSpaceConfigKeys(schema) {
1115
1105
  }
1116
1106
  return Object.fromEntries(Object.entries(schema).map(([key, entry]) => {
1117
1107
  if (key === "properties" && entry && typeof entry === "object" && !Array.isArray(entry)) {
1118
- const kept = Object.fromEntries(Object.entries(entry).filter(([name, value]) => {
1119
- if (name === "experimental_gutenberg") {
1120
- return false;
1121
- }
1122
- return !(name === "inject" && isHiddenInjectSchema(value));
1123
- }));
1108
+ const kept = Object.fromEntries(Object.entries(entry).filter(([name, value]) => !(name === "inject" && isHiddenInjectSchema(value))));
1124
1109
  return [key, stripHiddenSpaceConfigKeys(kept)];
1125
1110
  }
1126
1111
  return [key, stripHiddenSpaceConfigKeys(entry)];