@spacefast/common 0.0.23 → 0.0.26

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 (224) hide show
  1. package/brand-assets/LICENSE-Haskoy.txt +93 -0
  2. package/brand-assets/haskoy-latin-variable.woff2 +0 -0
  3. package/brand-assets/spacefast-favicon.svg +4 -4
  4. package/brand-assets/spacefast-sf-full-bleed.svg +3 -3
  5. package/brand-assets/spacefast-wordmark.svg +2 -4
  6. package/dist/agents/connect-targets.js +1 -1
  7. package/dist/agents/private-key-oauth.d.ts +0 -1
  8. package/dist/agents/private-key-oauth.js +46 -63
  9. package/dist/brand-assets-build.js +4 -6
  10. package/dist/brand-assets.d.ts +5 -15
  11. package/dist/brand-assets.js +15 -14
  12. package/dist/config/domains.d.ts +47 -7
  13. package/dist/config/domains.js +66 -10
  14. package/dist/config/index.d.ts +0 -1
  15. package/dist/config/index.js +0 -1
  16. package/dist/contracts/abuse.d.ts +2 -0
  17. package/dist/contracts/abuse.js +12 -0
  18. package/dist/contracts/access.d.ts +124 -12
  19. package/dist/contracts/access.js +73 -9
  20. package/dist/contracts/activity.d.ts +1 -1
  21. package/dist/contracts/activity.js +5 -12
  22. package/dist/contracts/api-keys.d.ts +21 -21
  23. package/dist/contracts/api-keys.js +2 -2
  24. package/dist/contracts/beta.js +1 -1
  25. package/dist/contracts/billing.d.ts +3 -35
  26. package/dist/contracts/billing.js +33 -52
  27. package/dist/contracts/builds.d.ts +30 -18
  28. package/dist/contracts/builds.js +28 -9
  29. package/dist/contracts/channels.js +1 -1
  30. package/dist/contracts/cli.d.ts +10 -0
  31. package/dist/contracts/cli.js +10 -0
  32. package/dist/contracts/collab-public.d.ts +63 -0
  33. package/dist/contracts/collab-public.js +46 -0
  34. package/dist/contracts/comments.d.ts +282 -53
  35. package/dist/contracts/comments.js +173 -52
  36. package/dist/contracts/common.d.ts +3 -3
  37. package/dist/contracts/common.js +5 -5
  38. package/dist/contracts/crons.d.ts +35 -0
  39. package/dist/contracts/crons.js +42 -0
  40. package/dist/contracts/device-auth.d.ts +6 -6
  41. package/dist/contracts/device-auth.js +2 -2
  42. package/dist/contracts/docs.js +2 -2
  43. package/dist/contracts/domains.d.ts +38 -27
  44. package/dist/contracts/domains.js +29 -2
  45. package/dist/contracts/enums.d.ts +34 -30
  46. package/dist/contracts/enums.js +62 -48
  47. package/dist/contracts/error-code-meta.d.ts +50 -125
  48. package/dist/contracts/error-code-meta.js +29 -41
  49. package/dist/contracts/error-codes.d.ts +1 -1
  50. package/dist/contracts/error-codes.js +14 -33
  51. package/dist/contracts/execution.d.ts +47 -66
  52. package/dist/contracts/execution.js +53 -49
  53. package/dist/contracts/feature-lifecycle-core.d.ts +0 -6
  54. package/dist/contracts/feature-lifecycle-core.js +2 -31
  55. package/dist/contracts/feature-lifecycle.d.ts +12 -52
  56. package/dist/contracts/feature-lifecycle.js +16 -59
  57. package/dist/contracts/features.d.ts +48 -60
  58. package/dist/contracts/features.js +59 -51
  59. package/dist/contracts/functions.d.ts +266 -72
  60. package/dist/contracts/functions.js +260 -37
  61. package/dist/contracts/git.d.ts +28 -34
  62. package/dist/contracts/git.js +10 -11
  63. package/dist/contracts/grants.d.ts +9 -5
  64. package/dist/contracts/grants.js +18 -9
  65. package/dist/contracts/ids.js +2 -2
  66. package/dist/contracts/internal.d.ts +8 -6
  67. package/dist/contracts/internal.js +12 -12
  68. package/dist/contracts/mcp.d.ts +11 -0
  69. package/dist/contracts/mcp.js +5 -0
  70. package/dist/contracts/me.js +1 -1
  71. package/dist/contracts/oauth-resources.d.ts +4 -3
  72. package/dist/contracts/oauth-resources.js +12 -3
  73. package/dist/contracts/operations.d.ts +90 -5
  74. package/dist/contracts/operations.js +77 -3
  75. package/dist/contracts/pages.d.ts +12 -7
  76. package/dist/contracts/pages.js +24 -1
  77. package/dist/contracts/plan-policy.d.ts +0 -2
  78. package/dist/contracts/plan-policy.js +2 -3
  79. package/dist/contracts/platform.d.ts +61 -148
  80. package/dist/contracts/platform.js +70 -126
  81. package/dist/contracts/publish-archive.d.ts +508 -0
  82. package/dist/contracts/publish-archive.js +32 -0
  83. package/dist/contracts/push-new.d.ts +4 -4
  84. package/dist/contracts/quotas.js +2 -2
  85. package/dist/contracts/repository-connections.d.ts +43 -30
  86. package/dist/contracts/repository-connections.js +11 -3
  87. package/dist/contracts/resources.d.ts +12 -24
  88. package/dist/contracts/resources.js +36 -16
  89. package/dist/contracts/runtime-api.d.ts +433 -192
  90. package/dist/contracts/runtime-api.js +421 -356
  91. package/dist/contracts/runtime-app.d.ts +127 -120
  92. package/dist/contracts/runtime-app.js +19 -10
  93. package/dist/contracts/runtime-db.d.ts +5 -5
  94. package/dist/contracts/runtime-db.js +2 -2
  95. package/dist/contracts/runtime-purge.d.ts +8 -0
  96. package/dist/contracts/runtime-purge.js +7 -0
  97. package/dist/contracts/runtime-services.d.ts +219 -0
  98. package/dist/contracts/runtime-services.js +437 -0
  99. package/dist/contracts/runtime-storage.d.ts +46 -32
  100. package/dist/contracts/runtime-storage.js +31 -8
  101. package/dist/contracts/sf-config-v1.d.ts +48 -10
  102. package/dist/contracts/space-config.d.ts +69 -18
  103. package/dist/contracts/space-config.js +226 -27
  104. package/dist/contracts/spaces.d.ts +236 -450
  105. package/dist/contracts/spaces.js +131 -151
  106. package/dist/contracts/superadmin-activity.d.ts +57 -4
  107. package/dist/contracts/superadmin-activity.js +48 -2
  108. package/dist/contracts/superadmin-search.d.ts +126 -0
  109. package/dist/contracts/superadmin-search.js +61 -0
  110. package/dist/contracts/superadmin-spaces.d.ts +361 -92
  111. package/dist/contracts/superadmin-spaces.js +97 -24
  112. package/dist/contracts/superadmin-teams.d.ts +28 -10
  113. package/dist/contracts/superadmin-teams.js +5 -8
  114. package/dist/contracts/superadmin-tenants.d.ts +0 -6
  115. package/dist/contracts/superadmin-tenants.js +1 -7
  116. package/dist/contracts/superadmin.d.ts +135 -54
  117. package/dist/contracts/superadmin.js +46 -23
  118. package/dist/contracts/tags.d.ts +12 -12
  119. package/dist/contracts/tags.js +3 -3
  120. package/dist/contracts/teams.d.ts +49 -14
  121. package/dist/contracts/teams.js +40 -22
  122. package/dist/contracts/transfers.d.ts +0 -49
  123. package/dist/contracts/transfers.js +4 -8
  124. package/dist/contracts/usage.d.ts +61 -0
  125. package/dist/contracts/usage.js +64 -0
  126. package/dist/contracts/variables.d.ts +2 -7
  127. package/dist/contracts/variables.js +9 -8
  128. package/dist/contracts/webhooks.d.ts +2 -2
  129. package/dist/contracts/zero.d.ts +102 -73
  130. package/dist/contracts/zero.js +94 -32
  131. package/dist/dashboard-paths/index.d.ts +1 -1
  132. package/dist/dashboard-paths/index.js +1 -0
  133. package/dist/docs/agent-prose.d.ts +2 -2
  134. package/dist/docs/agent-prose.js +63 -70
  135. package/dist/docs/agent-setup.js +45 -15
  136. package/dist/docs/catalog.d.ts +24 -24
  137. package/dist/docs/catalog.js +35 -24
  138. package/dist/docs/error-docs.js +194 -270
  139. package/dist/docs/skills.d.ts +12 -12
  140. package/dist/docs/skills.js +4 -4
  141. package/dist/test-helpers/fetch-stub.d.ts +16 -0
  142. package/dist/test-helpers/fetch-stub.js +25 -0
  143. package/dist/utils/build-settings.d.ts +5 -1
  144. package/dist/utils/build-settings.js +91 -13
  145. package/dist/utils/canonical-json.d.ts +10 -0
  146. package/dist/utils/canonical-json.js +22 -0
  147. package/dist/utils/cast-transport.d.ts +28 -0
  148. package/dist/utils/cast-transport.js +52 -0
  149. package/dist/utils/claim-token.d.ts +0 -8
  150. package/dist/utils/claim-token.js +3 -15
  151. package/dist/utils/concurrency.js +1 -0
  152. package/dist/utils/credential-policy.d.ts +1 -1
  153. package/dist/utils/credential-policy.js +4 -3
  154. package/dist/utils/dns-instructions.js +9 -9
  155. package/dist/utils/env-file.d.ts +17 -0
  156. package/dist/utils/env-file.js +96 -0
  157. package/dist/utils/error-code.d.ts +2 -0
  158. package/dist/utils/error-code.js +8 -0
  159. package/dist/utils/generate-space-name.d.ts +8 -10
  160. package/dist/utils/generate-space-name.js +206 -21
  161. package/dist/utils/grant-decision.fixtures.json +2938 -0
  162. package/dist/utils/grants.d.ts +2 -0
  163. package/dist/utils/grants.js +26 -1
  164. package/dist/utils/gravatar.d.ts +9 -0
  165. package/dist/utils/gravatar.js +31 -0
  166. package/dist/utils/idempotency.d.ts +6 -0
  167. package/dist/utils/idempotency.js +28 -0
  168. package/dist/utils/local-space-state.d.ts +9 -16
  169. package/dist/utils/local-space-state.js +20 -50
  170. package/dist/utils/one-shot-replay.d.ts +4 -1
  171. package/dist/utils/page-colors.d.ts +14 -12
  172. package/dist/utils/page-colors.js +15 -13
  173. package/dist/utils/page-fonts.d.ts +2 -2
  174. package/dist/utils/page-fonts.js +15 -4
  175. package/dist/utils/pages.d.ts +21 -3
  176. package/dist/utils/pages.js +42 -13
  177. package/dist/utils/publish-form-data.d.ts +12 -0
  178. package/dist/utils/publish-form-data.js +10 -0
  179. package/dist/utils/publish-policy.d.ts +27 -0
  180. package/dist/utils/publish-policy.fixtures.json +403 -0
  181. package/dist/utils/publish-policy.js +45 -20
  182. package/dist/utils/push-new.d.ts +7 -0
  183. package/dist/utils/push-new.js +7 -0
  184. package/dist/utils/query-keys.d.ts +4 -5
  185. package/dist/utils/query-keys.js +2 -3
  186. package/dist/utils/runtime-paths.d.ts +5 -0
  187. package/dist/utils/runtime-paths.js +5 -0
  188. package/dist/utils/runtime-upload-batch.d.ts +0 -5
  189. package/dist/utils/runtime-upload-batch.js +1 -27
  190. package/dist/utils/runtime-upload.d.ts +6 -11
  191. package/dist/utils/runtime-upload.js +10 -13
  192. package/dist/utils/secure-local-file.js +5 -16
  193. package/dist/utils/space-config.d.ts +1 -34
  194. package/dist/utils/space-config.js +8 -326
  195. package/dist/utils/static-runtime-policy.d.ts +9 -3
  196. package/dist/utils/static-runtime-policy.fixtures.json +38 -41
  197. package/dist/utils/static-runtime-policy.js +22 -56
  198. package/dist/utils/storage-policy.d.ts +1 -1
  199. package/dist/utils/storage-policy.js +3 -1
  200. package/dist/utils/structured-error.d.ts +14 -0
  201. package/dist/utils/structured-error.js +22 -0
  202. package/dist/utils/upload-session.d.ts +4 -1
  203. package/dist/utils/upload-session.js +33 -5
  204. package/dist/utils/version-path.js +13 -4
  205. package/dist/vocabulary.d.ts +13 -11
  206. package/dist/vocabulary.js +42 -28
  207. package/package.json +7 -17
  208. package/dist/config/postgres-budget.d.ts +0 -129
  209. package/dist/config/postgres-budget.js +0 -140
  210. package/dist/config/postgres-budget.json +0 -51
  211. package/dist/contracts/archives.d.ts +0 -331
  212. package/dist/contracts/archives.js +0 -120
  213. package/dist/contracts/deployments.d.ts +0 -574
  214. package/dist/contracts/deployments.js +0 -97
  215. package/dist/contracts/sites.d.ts +0 -416
  216. package/dist/contracts/sites.js +0 -168
  217. package/dist/contracts/superadmin-queues.d.ts +0 -414
  218. package/dist/contracts/superadmin-queues.js +0 -202
  219. package/dist/contracts/superadmin-runtime.d.ts +0 -27
  220. package/dist/contracts/superadmin-runtime.js +0 -38
  221. package/dist/index.d.ts +0 -1
  222. package/dist/index.js +0 -1
  223. package/dist/utils/api.d.ts +0 -4
  224. package/dist/utils/api.js +0 -13
@@ -0,0 +1,22 @@
1
+ import { CLI_EXIT_CODES } from "../contracts/cli.js";
2
+ export class StructuredError extends Error {
3
+ code;
4
+ details;
5
+ exitCode;
6
+ type;
7
+ constructor(input) {
8
+ super(input.message);
9
+ this.name = "StructuredError";
10
+ this.code = input.code;
11
+ this.details = input.details;
12
+ this.exitCode = input.exitCode ?? CLI_EXIT_CODES.validation;
13
+ this.type = input.type;
14
+ }
15
+ }
16
+ export function structuredValidationError(message, details) {
17
+ return new StructuredError({
18
+ code: "validation_error",
19
+ message,
20
+ ...(details ? { details } : {}),
21
+ });
22
+ }
@@ -33,8 +33,10 @@ export declare class UploadTargetError extends Error {
33
33
  readonly target: UploadTarget;
34
34
  readonly status: number;
35
35
  readonly serverError?: UploadTargetServerError | undefined;
36
- constructor(target: UploadTarget, status: number, message: string, serverError?: UploadTargetServerError | undefined);
36
+ readonly retryAfterMs?: number | undefined;
37
+ constructor(target: UploadTarget, status: number, message: string, serverError?: UploadTargetServerError | undefined, retryAfterMs?: number | undefined);
37
38
  }
39
+ export declare function uploadRetryAfterMs(value: string | null, now?: number): number | undefined;
38
40
  export declare function uploadPageHasRemainder(page: UploadSession): boolean;
39
41
  export declare const UPLOAD_STALLED_RESUME_MAX_ATTEMPTS = 3;
40
42
  export declare function uploadQueueAdvanced(before: UploadSession, after: UploadSession | null): boolean;
@@ -42,6 +44,7 @@ export declare function executeUploadSession(input: {
42
44
  session: UploadSession;
43
45
  targets?: readonly UploadTarget[] | undefined;
44
46
  concurrency?: number | undefined;
47
+ settleOnFailure?: boolean | undefined;
45
48
  fetch?: ((...args: Parameters<typeof fetch>) => ReturnType<typeof fetch>) | undefined;
46
49
  prepareTarget?: ((target: UploadTarget) => Promise<UploadTargetBody> | UploadTargetBody) | undefined;
47
50
  onEvent?: ((event: UploadSessionEvent) => void) | undefined;
@@ -2,14 +2,30 @@ export class UploadTargetError extends Error {
2
2
  target;
3
3
  status;
4
4
  serverError;
5
- constructor(target, status, message, serverError) {
5
+ retryAfterMs;
6
+ constructor(target, status, message, serverError, retryAfterMs) {
6
7
  super(message);
7
8
  this.target = target;
8
9
  this.status = status;
9
10
  this.serverError = serverError;
11
+ this.retryAfterMs = retryAfterMs;
10
12
  this.name = "UploadTargetError";
11
13
  }
12
14
  }
15
+ export function uploadRetryAfterMs(value, now = Date.now()) {
16
+ if (!value) {
17
+ return undefined;
18
+ }
19
+ const seconds = Number(value);
20
+ if (Number.isFinite(seconds) && seconds >= 0) {
21
+ return Math.ceil(seconds * 1000);
22
+ }
23
+ const date = Date.parse(value);
24
+ if (!Number.isFinite(date)) {
25
+ return undefined;
26
+ }
27
+ return Math.max(0, date - now);
28
+ }
13
29
  function parseUploadTargetServerError(raw) {
14
30
  let parsed;
15
31
  try {
@@ -73,7 +89,7 @@ export function uploadQueueAdvanced(before, after) {
73
89
  }
74
90
  return after.targets.some((target, index) => target.path !== before.targets[index]?.path);
75
91
  }
76
- async function runConcurrent(items, concurrency, fn) {
92
+ async function runConcurrent(items, concurrency, settleOnFailure, fn) {
77
93
  let nextIndex = 0;
78
94
  const runWorker = async () => {
79
95
  const item = items[nextIndex++];
@@ -83,7 +99,18 @@ async function runConcurrent(items, concurrency, fn) {
83
99
  await fn(item);
84
100
  return runWorker();
85
101
  };
86
- await Promise.all(Array.from({ length: Math.min(Math.max(concurrency, 1), items.length || 1) }).map(() => runWorker()));
102
+ const workers = Array.from({
103
+ length: Math.min(Math.max(concurrency, 1), items.length || 1),
104
+ }).map(() => runWorker());
105
+ if (!settleOnFailure) {
106
+ await Promise.all(workers);
107
+ return;
108
+ }
109
+ const outcomes = await Promise.allSettled(workers);
110
+ const failed = outcomes.find((outcome) => outcome.status === "rejected");
111
+ if (failed) {
112
+ throw failed.reason;
113
+ }
87
114
  }
88
115
  export async function executeUploadSession(input) {
89
116
  const targets = input.targets ?? input.session.targets;
@@ -91,7 +118,8 @@ export async function executeUploadSession(input) {
91
118
  return;
92
119
  }
93
120
  const fetchImpl = input.fetch ?? fetch;
94
- await runConcurrent(targets, input.concurrency ?? 4, async (target) => {
121
+ const settleOnFailure = input.settleOnFailure ?? false;
122
+ await runConcurrent(targets, input.concurrency ?? 4, settleOnFailure, async (target) => {
95
123
  input.onEvent?.({ type: "target-start", target });
96
124
  try {
97
125
  const prepared = input.prepareTarget
@@ -114,7 +142,7 @@ export async function executeUploadSession(input) {
114
142
  const details = await response.text().catch(() => "");
115
143
  const serverError = parseUploadTargetServerError(details);
116
144
  const suffix = details.trim() ? `: ${details.trim().slice(0, 1_000)}` : "";
117
- throw new UploadTargetError(target, response.status, `Upload failed for ${target.path} with ${response.status} ${response.statusText}${suffix}.`, serverError);
145
+ throw new UploadTargetError(target, response.status, `Upload failed for ${target.path} with ${response.status} ${response.statusText}${suffix}.`, serverError, uploadRetryAfterMs(response.headers.get("retry-after")));
118
146
  }
119
147
  input.onEvent?.({ type: "target-done", target });
120
148
  }
@@ -1,14 +1,22 @@
1
- // Canonical object-path form (internal-docs/platform.md "Upload Contract"):
1
+ // Canonical object-path form (the platform spec "Upload Contract"):
2
2
  // UTF-8, Unicode NFC, percent-decoded exactly once. This canonical form is
3
3
  // what manifest paths, finalize's normalized paths, route-map keys, and dedup
4
4
  // keys all mean. The PHP runtime applies the same transform (rawurldecode once
5
5
  // + Normalizer::normalize) at upload and serve time.
6
+ // oxlint-disable-next-line no-control-regex -- matching control characters is the point: they are never part of a servable path.
6
7
  const CONTROL_CHARS_PATTERN = /[\u0000-\u001f\u007f]/;
7
8
  // Structural normalization shared by lookups and intake: forward slashes,
8
- // no leading slashes, no empty/"."/".." segments. Idempotent; safe to apply
9
- // to already-canonical stored paths (NFC is idempotent, no percent-decoding).
9
+ // no leading slashes, no control characters, no empty/"."/".." segments.
10
+ // Idempotent; safe to apply to already-canonical stored paths (NFC is
11
+ // idempotent, no percent-decoding).
10
12
  export function normalizeVersionPath(input) {
11
13
  const normalized = input.replace(/\\/g, "/").replace(/^\/+/, "").normalize("NFC");
14
+ // Here rather than only in canonicalizeVersionPath: publish-policy's
15
+ // staticUploadPathViolation validates with this function, so a control
16
+ // character in an uploaded path used to pass the policy unclassified.
17
+ if (CONTROL_CHARS_PATTERN.test(normalized)) {
18
+ throw new Error(`invalid_version_path:${input}`);
19
+ }
12
20
  const segments = [];
13
21
  for (const segment of normalized.split("/")) {
14
22
  if (!segment || segment === ".") {
@@ -41,7 +49,8 @@ export function canonicalizeVersionPath(input) {
41
49
  const canonical = decoded.normalize("NFC");
42
50
  // Backslashes as separators are denied at intake (spec "Static path
43
51
  // policy"); only client-side helpers translate Windows separators.
44
- if (CONTROL_CHARS_PATTERN.test(canonical) || canonical.includes("\\")) {
52
+ // Control characters are rejected by normalizeVersionPath below.
53
+ if (canonical.includes("\\")) {
45
54
  throw new Error(`invalid_version_path:${input}`);
46
55
  }
47
56
  return normalizeVersionPath(canonical);
@@ -7,6 +7,8 @@ export type TermContext =
7
7
  "platform-api"
8
8
  /** The GitHub integration vocabulary (push deploys, deployment status). */
9
9
  | "github-integration"
10
+ /** Internal operator surfaces (superadmin, ops scripts, fleet inventory). */
11
+ | "operator"
10
12
  /** A fixed marketing phrase, spelled out verbatim in `allowedPhrases`. */
11
13
  | "fixed-phrase";
12
14
  /** A single canonical product concept and the words allowed to express it. */
@@ -38,8 +40,8 @@ export declare const CONCEPTS: {
38
40
  readonly id: "space";
39
41
  readonly canonicalNoun: "space";
40
42
  readonly aliases: readonly [];
41
- readonly externalTerms: readonly ["site"];
42
- readonly deprecated: readonly ["project"];
43
+ readonly externalTerms: readonly [];
44
+ readonly deprecated: readonly ["project", "site"];
43
45
  readonly description: string;
44
46
  };
45
47
  readonly publish: {
@@ -102,8 +104,8 @@ export declare const CONCEPTS: {
102
104
  readonly id: "infra";
103
105
  readonly canonicalNoun: "infra";
104
106
  readonly aliases: readonly ["infrastructure"];
105
- readonly externalTerms: readonly ["WP.Cloud"];
106
- readonly deprecated: readonly ["code.storage", "Pierre"];
107
+ readonly externalTerms: readonly ["WP Cloud"];
108
+ readonly deprecated: readonly ["code.storage", "Pierre", "the hosting provider"];
107
109
  readonly description: string;
108
110
  };
109
111
  };
@@ -137,14 +139,14 @@ export declare const EXTERNAL_TERM_ALLOWLIST: readonly [{
137
139
  }, {
138
140
  readonly term: "site";
139
141
  readonly concept: "space";
140
- readonly allowedContexts: readonly ["platform-api"];
142
+ readonly allowedContexts: readonly ["operator"];
141
143
  readonly replacement: "space";
142
144
  readonly reason: string;
143
145
  }, {
144
- readonly term: "WP.Cloud";
146
+ readonly term: "WP Cloud";
145
147
  readonly concept: "infra";
146
- readonly allowedContexts: readonly ["platform-api", "fixed-phrase"];
147
- readonly allowedPhrases: readonly ["built on WP.Cloud"];
148
+ readonly allowedContexts: readonly ["fixed-phrase"];
149
+ readonly allowedPhrases: readonly ["the same infra as Automattic, WP Cloud, Pressable, and WordPress.com"];
148
150
  readonly replacement: "infra";
149
151
  readonly reason: string;
150
152
  }];
@@ -206,10 +208,10 @@ export declare const PROVIDER_HYGIENE: {
206
208
  readonly reason: "The build sandbox vendor is never named; it is 'Spacefast Builds'.";
207
209
  };
208
210
  readonly wpcloud: {
209
- readonly internalName: "WP.Cloud";
211
+ readonly internalName: "WP Cloud";
210
212
  readonly replacement: "infra";
211
- readonly allowedContexts: readonly ["platform-api", "fixed-phrase"];
212
- readonly allowedPhrases: readonly ["built on WP.Cloud"];
213
+ readonly allowedContexts: readonly ["fixed-phrase"];
214
+ readonly allowedPhrases: readonly ["the same infra as Automattic, WP Cloud, Pressable, and WordPress.com"];
213
215
  readonly reason: string;
214
216
  };
215
217
  readonly codeStorage: {
@@ -8,9 +8,10 @@
8
8
  // It is additive — wiring consumers (CLI, MCP, dashboard, docs generators) onto
9
9
  // it happens in later chunks. The decisions encoded here are LOCKED:
10
10
  //
11
- // - `space` is the primitive noun on every user surface. `site` survives only
12
- // as the platform-API term for the shared-pool host a space is placed on
13
- // (see contracts/sites.ts, internal-docs/platform.md "Site").
11
+ // - `space` is the primitive noun everywhere, user surfaces and platform API
12
+ // alike. A space IS a site: there is no second host entity to name. `site`
13
+ // survives only as WP Cloud's own word for the box, in operator surfaces
14
+ // and the warm-pool inventory.
14
15
  // - `publish` is the verb. AMENDED 2026-07-02: `deploy` / `deployments` are
15
16
  // first-class ALIASES of `publish` / `versions` (see DEPLOY_ALIASES) — they
16
17
  // stay listed and documented, always with the sanctioned disambiguation
@@ -21,19 +22,24 @@
21
22
  // - `API key` — never "access token".
22
23
  // - `Collab` is the feature; `comment` is the unit.
23
24
  // - `Superpowers` is the page-enhancement feature.
24
- // - Provider names never leak externally: never "E2B" (say "Spacefast
25
- // Builds" / "Spacefast CI"), never "WP.Cloud" (say "infra", except the
26
- // platform API or the fixed phrase "built on WP.Cloud"), never
27
- // "code.storage" / "Pierre" (see PROVIDER_HYGIENE).
25
+ // - Provider names stay off public surfaces by default: never "E2B" (say
26
+ // "Spacefast Builds" / "Spacefast CI"), never "code.storage" / "Pierre".
27
+ // The infra brand is "WP Cloud" never "WP.Cloud"/"wp-cloud" (AMENDED
28
+ // 2026-08-13). Prefer "infra"; when an external reference is genuinely
29
+ // necessary (provider identity fields, domain conflicts), name WP Cloud
30
+ // outright — NEVER the euphemism "the hosting provider". Marketing may use
31
+ // the family line "the same infra as Automattic, WP Cloud, Pressable, and
32
+ // WordPress.com" (see PROVIDER_HYGIENE).
28
33
  export const CONCEPTS = {
29
34
  space: {
30
35
  id: "space",
31
36
  canonicalNoun: "space",
32
37
  aliases: [],
33
- externalTerms: ["site"],
34
- deprecated: ["project"],
35
- description: "The primitive noun everywhere a user works. 'Site' is the platform-API " +
36
- "term for the shared host a space lands on; 'project' is never the primitive.",
38
+ externalTerms: [],
39
+ deprecated: ["project", "site"],
40
+ description: "The primitive noun everywhere, user surfaces and platform API alike. A " +
41
+ "space IS a site, so 'site' names nothing of ours; 'project' is never " +
42
+ "the primitive.",
37
43
  },
38
44
  publish: {
39
45
  id: "publish",
@@ -100,10 +106,11 @@ export const CONCEPTS = {
100
106
  id: "infra",
101
107
  canonicalNoun: "infra",
102
108
  aliases: ["infrastructure"],
103
- externalTerms: ["WP.Cloud"],
104
- deprecated: ["code.storage", "Pierre"],
105
- description: "The hosting substrate. Say 'infra' externally; 'WP.Cloud' only in the " +
106
- "platform API or the phrase 'built on WP.Cloud'. Never 'code.storage'/'Pierre'.",
109
+ externalTerms: ["WP Cloud"],
110
+ deprecated: ["code.storage", "Pierre", "the hosting provider"],
111
+ description: "The hosting substrate. Prefer 'infra'; when an external reference is " +
112
+ "necessary, name 'WP Cloud' (its real spelling) never the euphemism " +
113
+ "'the hosting provider'. Never 'code.storage'/'Pierre'.",
107
114
  },
108
115
  };
109
116
  export const EXTERNAL_TERM_ALLOWLIST = [
@@ -129,19 +136,24 @@ export const EXTERNAL_TERM_ALLOWLIST = [
129
136
  {
130
137
  term: "site",
131
138
  concept: "space",
132
- allowedContexts: ["platform-api"],
139
+ allowedContexts: ["operator"],
133
140
  replacement: "space",
134
- reason: "'Site' is the platform-API host primitive (shared pool capacity); user " +
135
- "surfaces always say 'space'.",
141
+ reason: "A space IS a site, so 'site' is no longer a Spacefast noun it is only " +
142
+ "WP Cloud's word for the box, which operator surfaces and warm-pool " +
143
+ "inventory may use. Every customer-facing surface says 'space'.",
136
144
  },
137
145
  {
138
- term: "WP.Cloud",
146
+ term: "WP Cloud",
139
147
  concept: "infra",
140
- allowedContexts: ["platform-api", "fixed-phrase"],
141
- allowedPhrases: ["built on WP.Cloud"],
148
+ allowedContexts: ["fixed-phrase"],
149
+ allowedPhrases: ["the same infra as Automattic, WP Cloud, Pressable, and WordPress.com"],
142
150
  replacement: "infra",
143
- reason: "Only the platform API or the exact phrase 'built on WP.Cloud' may name " +
144
- "the provider; general copy says 'infra'.",
151
+ reason: "AMENDED 2026-08-13: prefer 'infra'. Same day: the platform-api " +
152
+ "carve-out is revoked API values say mysql/phpmyadmin/infra, never " +
153
+ "wpcloud. Name WP Cloud (its real spelling — never 'WP.Cloud') only " +
154
+ "where the external reference is necessary: domain-conflict copy and " +
155
+ "the marketing family line in allowedPhrases. Never the euphemism " +
156
+ "'the hosting provider'.",
145
157
  },
146
158
  ];
147
159
  export const DEPLOY_ALIASES = [
@@ -164,12 +176,14 @@ export const PROVIDER_HYGIENE = {
164
176
  reason: "The build sandbox vendor is never named; it is 'Spacefast Builds'.",
165
177
  },
166
178
  wpcloud: {
167
- internalName: "WP.Cloud",
179
+ internalName: "WP Cloud",
168
180
  replacement: "infra",
169
- allowedContexts: ["platform-api", "fixed-phrase"],
170
- allowedPhrases: ["built on WP.Cloud"],
171
- reason: "Hosting substrate; externally 'infra' except the platform API or the " +
172
- "phrase 'built on WP.Cloud'.",
181
+ allowedContexts: ["fixed-phrase"],
182
+ allowedPhrases: ["the same infra as Automattic, WP Cloud, Pressable, and WordPress.com"],
183
+ reason: "Hosting substrate; prefer 'infra' (AMENDED 2026-08-13, same day: the " +
184
+ "platform-api carve-out is revoked — API values say mysql/phpmyadmin/" +
185
+ "infra, never wpcloud). Necessary external references name WP Cloud " +
186
+ "outright — never 'the hosting provider'.",
173
187
  },
174
188
  codeStorage: {
175
189
  internalName: "code.storage",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@spacefast/common",
3
- "version": "0.0.23",
3
+ "version": "0.0.26",
4
4
  "license": "MIT",
5
5
  "description": "Shared TypeScript contracts and utilities for Spacefast packages.",
6
6
  "repository": {
@@ -20,22 +20,6 @@
20
20
  "brand-assets",
21
21
  "dist"
22
22
  ],
23
- "spacefastTestCache": {
24
- "mode": "hermetic",
25
- "inputs": [
26
- "../../apps/www/dist/.well-known/agent-card.json",
27
- "../../apps/www/dist/ai.txt",
28
- "../../apps/www/dist/llms-full.txt",
29
- "../../apps/www/dist/llms.txt",
30
- "../../apps/www/public/skill-references.md",
31
- "../../apps/www/public/skill.md",
32
- "../../e2e-tests/fixtures/zero-all-features/api-finalize-request.json",
33
- "../../e2e-tests/fixtures/zero-all-features/runtime-compiler-finalize-input.json",
34
- "../../runtime/engine/shared/fonts",
35
- "../cli/SKILL.md",
36
- "../cli/references.md"
37
- ]
38
- },
39
23
  "exports": {
40
24
  "./brand": {
41
25
  "types": "./dist/brand.d.ts",
@@ -75,6 +59,11 @@
75
59
  "import": "./dist/utils/*.js",
76
60
  "default": "./dist/utils/*.js"
77
61
  },
62
+ "./test-helpers/*": {
63
+ "types": "./dist/test-helpers/*.d.ts",
64
+ "import": "./dist/test-helpers/*.js",
65
+ "default": "./dist/test-helpers/*.js"
66
+ },
78
67
  "./slug-policy": {
79
68
  "types": "./dist/slug-policy/index.d.ts",
80
69
  "import": "./dist/slug-policy/index.js",
@@ -111,6 +100,7 @@
111
100
  "culori": "^4.0.2",
112
101
  "js-yaml": "^4.1.1",
113
102
  "mime": "^4.1.0",
103
+ "oauth4webapi": "3.8.7",
114
104
  "parse5": "^7.3.0",
115
105
  "smol-toml": "^1.7.0",
116
106
  "zod": "^4.4.3"
@@ -1,129 +0,0 @@
1
- import { z } from "zod";
2
- declare const postgresConnectionBudgetSchema: z.ZodObject<{
3
- server: z.ZodObject<{
4
- maxConnections: z.ZodNumber;
5
- superuserReservedConnections: z.ZodNumber;
6
- }, z.core.$strip>;
7
- migrationConnections: z.ZodNumber;
8
- operationalReserveConnections: z.ZodNumber;
9
- transactionPools: z.ZodRecord<z.ZodString, z.ZodObject<{
10
- serverConnections: z.ZodNumber;
11
- }, z.core.$strip>>;
12
- services: z.ZodObject<{
13
- api: z.ZodObject<{
14
- enabledInProduction: z.ZodBoolean;
15
- replicas: z.ZodNumber;
16
- poolConnectionsPerReplica: z.ZodNumber;
17
- fixedConnectionsPerReplica: z.ZodNumber;
18
- maxPinnedTransactionsPerReplica: z.ZodNumber;
19
- rolloutOverlapReplicas: z.ZodNumber;
20
- connectionBudget: z.ZodString;
21
- }, z.core.$strip>;
22
- worker: z.ZodObject<{
23
- enabledInProduction: z.ZodBoolean;
24
- replicas: z.ZodNumber;
25
- poolConnectionsPerReplica: z.ZodNumber;
26
- fixedConnectionsPerReplica: z.ZodNumber;
27
- maxPinnedTransactionsPerReplica: z.ZodNumber;
28
- rolloutOverlapReplicas: z.ZodNumber;
29
- connectionBudget: z.ZodString;
30
- }, z.core.$strip>;
31
- cast: z.ZodObject<{
32
- enabledInProduction: z.ZodBoolean;
33
- replicas: z.ZodNumber;
34
- poolConnectionsPerReplica: z.ZodNumber;
35
- fixedConnectionsPerReplica: z.ZodNumber;
36
- maxPinnedTransactionsPerReplica: z.ZodNumber;
37
- rolloutOverlapReplicas: z.ZodNumber;
38
- connectionBudget: z.ZodString;
39
- }, z.core.$strip>;
40
- scanWorker: z.ZodObject<{
41
- enabledInProduction: z.ZodBoolean;
42
- replicas: z.ZodNumber;
43
- poolConnectionsPerReplica: z.ZodNumber;
44
- fixedConnectionsPerReplica: z.ZodNumber;
45
- maxPinnedTransactionsPerReplica: z.ZodNumber;
46
- rolloutOverlapReplicas: z.ZodNumber;
47
- connectionBudget: z.ZodString;
48
- }, z.core.$strip>;
49
- }, z.core.$strip>;
50
- }, z.core.$strip>;
51
- export type PostgresConnectionBudget = z.infer<typeof postgresConnectionBudgetSchema>;
52
- export type PostgresBudgetService = keyof PostgresConnectionBudget["services"];
53
- export type PostgresConnectionBudgetSummary = {
54
- usableServerConnections: number;
55
- directSteadyConnections: number;
56
- transactionPoolConnections: number;
57
- transactionPoolPinnedConnections: number;
58
- transactionPoolQueryHeadroom: number;
59
- steadyConnections: number;
60
- rollingDeploySurgeConnections: number;
61
- migrationConnections: number;
62
- operationalReserveConnections: number;
63
- plannedConnections: number;
64
- unallocatedConnections: number;
65
- };
66
- export declare const POSTGRES_CONNECTION_BUDGET: {
67
- server: {
68
- maxConnections: number;
69
- superuserReservedConnections: number;
70
- };
71
- migrationConnections: number;
72
- operationalReserveConnections: number;
73
- transactionPools: Record<string, {
74
- serverConnections: number;
75
- }>;
76
- services: {
77
- api: {
78
- enabledInProduction: boolean;
79
- replicas: number;
80
- poolConnectionsPerReplica: number;
81
- fixedConnectionsPerReplica: number;
82
- maxPinnedTransactionsPerReplica: number;
83
- rolloutOverlapReplicas: number;
84
- connectionBudget: string;
85
- };
86
- worker: {
87
- enabledInProduction: boolean;
88
- replicas: number;
89
- poolConnectionsPerReplica: number;
90
- fixedConnectionsPerReplica: number;
91
- maxPinnedTransactionsPerReplica: number;
92
- rolloutOverlapReplicas: number;
93
- connectionBudget: string;
94
- };
95
- cast: {
96
- enabledInProduction: boolean;
97
- replicas: number;
98
- poolConnectionsPerReplica: number;
99
- fixedConnectionsPerReplica: number;
100
- maxPinnedTransactionsPerReplica: number;
101
- rolloutOverlapReplicas: number;
102
- connectionBudget: string;
103
- };
104
- scanWorker: {
105
- enabledInProduction: boolean;
106
- replicas: number;
107
- poolConnectionsPerReplica: number;
108
- fixedConnectionsPerReplica: number;
109
- maxPinnedTransactionsPerReplica: number;
110
- rolloutOverlapReplicas: number;
111
- connectionBudget: string;
112
- };
113
- };
114
- };
115
- export declare function calculatePostgresConnectionBudget(plan: PostgresConnectionBudget, server?: {
116
- maxConnections: number;
117
- superuserReservedConnections: number;
118
- }): PostgresConnectionBudgetSummary;
119
- export declare function assertPostgresServiceConnectionUrl(service: PostgresBudgetService, rawUrl: string, options?: {
120
- allowDirectDevelopmentConnection?: boolean;
121
- }): void;
122
- export declare function assertPostgresServicePoolBudget(service: PostgresBudgetService, configuredPoolConnections: number): void;
123
- export declare function assertPostgresServiceNamedLockBudget(service: PostgresBudgetService, configuredNamedLockTransactions: number): void;
124
- export declare function assertPostgresServerBudget(server: {
125
- maxConnections: number;
126
- superuserReservedConnections: number;
127
- }): PostgresConnectionBudgetSummary;
128
- export declare const POSTGRES_CONNECTION_BUDGET_SUMMARY: PostgresConnectionBudgetSummary;
129
- export {};