@spacefast/common 0.0.24 → 0.2.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 (320) 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.d.ts +6 -146
  7. package/dist/agents/connect-targets.js +63 -295
  8. package/dist/agents/private-key-oauth.d.ts +31 -2
  9. package/dist/agents/private-key-oauth.js +166 -92
  10. package/dist/agents/registry/core.d.ts +292 -0
  11. package/dist/agents/registry/core.js +1388 -0
  12. package/dist/agents/registry/deeplink-probes.d.ts +23 -0
  13. package/dist/agents/registry/deeplink-probes.js +18 -0
  14. package/dist/agents/registry/node.d.ts +56 -0
  15. package/dist/agents/registry/node.js +339 -0
  16. package/dist/brand-assets-build.js +3 -6
  17. package/dist/brand-assets.d.ts +5 -15
  18. package/dist/brand-assets.js +12 -14
  19. package/dist/brand.d.ts +17 -0
  20. package/dist/brand.js +24 -4
  21. package/dist/config/domains.d.ts +79 -12
  22. package/dist/config/domains.js +128 -29
  23. package/dist/config/index.js +1 -2
  24. package/dist/contracts/abuse.js +9 -24
  25. package/dist/contracts/access-profiles.d.ts +86 -0
  26. package/dist/contracts/access-profiles.js +89 -0
  27. package/dist/contracts/access.d.ts +24 -30
  28. package/dist/contracts/access.js +33 -64
  29. package/dist/contracts/activity.d.ts +18 -1
  30. package/dist/contracts/activity.js +72 -26
  31. package/dist/contracts/analytics.js +8 -10
  32. package/dist/contracts/api-keys.d.ts +77 -52
  33. package/dist/contracts/api-keys.js +44 -24
  34. package/dist/contracts/application-journal.d.ts +216 -0
  35. package/dist/contracts/application-journal.js +167 -0
  36. package/dist/contracts/auth.d.ts +90 -17
  37. package/dist/contracts/auth.js +86 -17
  38. package/dist/contracts/beta.d.ts +9 -4
  39. package/dist/contracts/beta.js +20 -16
  40. package/dist/contracts/billing.d.ts +2 -1
  41. package/dist/contracts/billing.js +37 -11
  42. package/dist/contracts/bootstrap.d.ts +791 -0
  43. package/dist/contracts/bootstrap.js +51 -0
  44. package/dist/contracts/builds.d.ts +209 -18
  45. package/dist/contracts/builds.js +93 -27
  46. package/dist/contracts/channels.d.ts +43 -0
  47. package/dist/contracts/channels.js +25 -9
  48. package/dist/contracts/cli.d.ts +7 -0
  49. package/dist/contracts/cli.js +6 -0
  50. package/dist/contracts/collab-public.d.ts +1 -1
  51. package/dist/contracts/collab-public.js +5 -8
  52. package/dist/contracts/comments.d.ts +44 -34
  53. package/dist/contracts/comments.js +107 -77
  54. package/dist/contracts/commerce.d.ts +165 -0
  55. package/dist/contracts/commerce.js +146 -0
  56. package/dist/contracts/common.d.ts +3 -3
  57. package/dist/contracts/common.js +20 -31
  58. package/dist/contracts/content-contract-verification.d.ts +521 -0
  59. package/dist/contracts/content-contract-verification.js +320 -0
  60. package/dist/contracts/content-platform-fixture.d.ts +1278 -0
  61. package/dist/contracts/content-platform-fixture.js +44 -0
  62. package/dist/contracts/content-program.d.ts +994 -0
  63. package/dist/contracts/content-program.js +658 -0
  64. package/dist/contracts/content-sync.d.ts +290 -0
  65. package/dist/contracts/content-sync.js +167 -0
  66. package/dist/contracts/content.d.ts +432 -0
  67. package/dist/contracts/content.js +303 -0
  68. package/dist/contracts/continuation.d.ts +17 -1
  69. package/dist/contracts/continuation.js +23 -23
  70. package/dist/contracts/countries.js +3 -4
  71. package/dist/contracts/crons.d.ts +52 -0
  72. package/dist/contracts/crons.js +60 -0
  73. package/dist/contracts/dashboard-prefs.d.ts +56 -0
  74. package/dist/contracts/dashboard-prefs.js +51 -0
  75. package/dist/contracts/device-auth.d.ts +234 -37
  76. package/dist/contracts/device-auth.js +267 -53
  77. package/dist/contracts/docs.d.ts +1 -5
  78. package/dist/contracts/docs.js +7 -15
  79. package/dist/contracts/domains.d.ts +501 -93
  80. package/dist/contracts/domains.js +193 -55
  81. package/dist/contracts/email-preferences.d.ts +3 -3
  82. package/dist/contracts/email-preferences.js +6 -7
  83. package/dist/contracts/enums.d.ts +27 -26
  84. package/dist/contracts/enums.js +68 -61
  85. package/dist/contracts/error-code-meta.d.ts +283 -7
  86. package/dist/contracts/error-code-meta.js +97 -5
  87. package/dist/contracts/error-codes.d.ts +5 -5
  88. package/dist/contracts/error-codes.js +82 -17
  89. package/dist/contracts/events.d.ts +100 -20
  90. package/dist/contracts/events.js +107 -20
  91. package/dist/contracts/execution.d.ts +48 -64
  92. package/dist/contracts/execution.js +52 -62
  93. package/dist/contracts/feature-lifecycle.d.ts +73 -27
  94. package/dist/contracts/feature-lifecycle.js +86 -26
  95. package/dist/contracts/features.d.ts +68 -19
  96. package/dist/contracts/features.js +42 -41
  97. package/dist/contracts/fixtures/content-platform-v1.json +1108 -0
  98. package/dist/contracts/frame-session.d.ts +192 -0
  99. package/dist/contracts/frame-session.js +164 -0
  100. package/dist/contracts/functions.d.ts +338 -164
  101. package/dist/contracts/functions.js +367 -198
  102. package/dist/contracts/git.d.ts +27 -33
  103. package/dist/contracts/git.js +10 -11
  104. package/dist/contracts/grant-copy.d.ts +43 -0
  105. package/dist/contracts/grant-copy.js +44 -0
  106. package/dist/contracts/grants.d.ts +62 -54
  107. package/dist/contracts/grants.js +124 -23
  108. package/dist/contracts/ids.d.ts +4 -1
  109. package/dist/contracts/ids.js +6 -3
  110. package/dist/contracts/internal.d.ts +8 -18
  111. package/dist/contracts/internal.js +13 -14
  112. package/dist/contracts/mcp.d.ts +28 -0
  113. package/dist/contracts/mcp.js +28 -0
  114. package/dist/contracts/me.d.ts +6 -1
  115. package/dist/contracts/me.js +12 -6
  116. package/dist/contracts/notifications.d.ts +27 -29
  117. package/dist/contracts/notifications.js +9 -4
  118. package/dist/contracts/oauth-resources.d.ts +112 -10
  119. package/dist/contracts/oauth-resources.js +116 -11
  120. package/dist/contracts/oauth-scope-actions.d.ts +90 -0
  121. package/dist/contracts/oauth-scope-actions.js +126 -0
  122. package/dist/contracts/operations.d.ts +27 -4
  123. package/dist/contracts/operations.js +12 -6
  124. package/dist/contracts/pages.d.ts +31 -7
  125. package/dist/contracts/pages.js +22 -5
  126. package/dist/contracts/partner-notifications.d.ts +3 -0
  127. package/dist/contracts/partner-notifications.js +65 -0
  128. package/dist/contracts/{platform.d.ts → partner.d.ts} +29 -42
  129. package/dist/contracts/{platform.js → partner.js} +27 -40
  130. package/dist/contracts/plan-policy.js +1 -1
  131. package/dist/contracts/principal-assertion.d.ts +43 -0
  132. package/dist/contracts/principal-assertion.js +67 -0
  133. package/dist/contracts/principals.d.ts +73 -0
  134. package/dist/contracts/principals.js +59 -0
  135. package/dist/contracts/privacy.d.ts +11 -0
  136. package/dist/contracts/privacy.js +17 -0
  137. package/dist/contracts/problem-document.js +3 -4
  138. package/dist/contracts/publish-archive.d.ts +269 -161
  139. package/dist/contracts/publish-archive.js +11 -1
  140. package/dist/contracts/push-new.d.ts +8 -8
  141. package/dist/contracts/quotas.js +5 -5
  142. package/dist/contracts/realtime.d.ts +52 -0
  143. package/dist/contracts/realtime.js +54 -0
  144. package/dist/contracts/repository-connections.d.ts +44 -31
  145. package/dist/contracts/repository-connections.js +17 -5
  146. package/dist/contracts/resources.d.ts +105 -14
  147. package/dist/contracts/resources.js +150 -26
  148. package/dist/contracts/route-inventory.d.ts +358 -0
  149. package/dist/contracts/route-inventory.js +141 -0
  150. package/dist/contracts/runtime-api.d.ts +206 -82
  151. package/dist/contracts/runtime-api.js +131 -70
  152. package/dist/contracts/runtime-app.d.ts +13 -23
  153. package/dist/contracts/runtime-app.js +39 -24
  154. package/dist/contracts/runtime-components.d.ts +143 -0
  155. package/dist/contracts/runtime-components.js +199 -0
  156. package/dist/contracts/runtime-db.d.ts +49 -23
  157. package/dist/contracts/runtime-db.js +87 -22
  158. package/dist/contracts/runtime-purge.d.ts +8 -0
  159. package/dist/contracts/runtime-purge.js +5 -0
  160. package/dist/contracts/runtime-services.d.ts +43 -75
  161. package/dist/contracts/runtime-services.js +29 -49
  162. package/dist/contracts/runtime-storage.d.ts +15 -14
  163. package/dist/contracts/runtime-storage.js +30 -14
  164. package/dist/contracts/sf-config-v1.d.ts +48 -14
  165. package/dist/contracts/slugs.js +13 -4
  166. package/dist/contracts/space-config.d.ts +283 -19
  167. package/dist/contracts/space-config.js +430 -80
  168. package/dist/contracts/spaces.d.ts +376 -290
  169. package/dist/contracts/spaces.js +200 -135
  170. package/dist/contracts/superadmin-activity.d.ts +3 -43
  171. package/dist/contracts/superadmin-activity.js +6 -30
  172. package/dist/contracts/superadmin-emails.d.ts +1 -0
  173. package/dist/contracts/superadmin-emails.js +17 -1
  174. package/dist/contracts/superadmin-runtime.d.ts +199 -0
  175. package/dist/contracts/superadmin-runtime.js +141 -0
  176. package/dist/contracts/superadmin-search.d.ts +22 -2
  177. package/dist/contracts/superadmin-search.js +14 -6
  178. package/dist/contracts/superadmin-spaces.d.ts +438 -189
  179. package/dist/contracts/superadmin-spaces.js +131 -25
  180. package/dist/contracts/superadmin-teams.d.ts +5 -2
  181. package/dist/contracts/superadmin-teams.js +1 -2
  182. package/dist/contracts/superadmin-tenants.d.ts +627 -12
  183. package/dist/contracts/superadmin-tenants.js +32 -13
  184. package/dist/contracts/superadmin.d.ts +232 -37
  185. package/dist/contracts/superadmin.js +106 -22
  186. package/dist/contracts/tags.d.ts +85 -58
  187. package/dist/contracts/tags.js +47 -37
  188. package/dist/contracts/teams.d.ts +86 -26
  189. package/dist/contracts/teams.js +90 -31
  190. package/dist/contracts/tenants.d.ts +135 -0
  191. package/dist/contracts/tenants.js +120 -0
  192. package/dist/contracts/test-triggers.d.ts +70 -0
  193. package/dist/contracts/test-triggers.js +116 -0
  194. package/dist/contracts/theme-json.js +3 -8
  195. package/dist/contracts/transfers.d.ts +1 -0
  196. package/dist/contracts/transfers.js +3 -2
  197. package/dist/contracts/usage.d.ts +209 -0
  198. package/dist/contracts/usage.js +124 -12
  199. package/dist/contracts/variables.d.ts +2 -2
  200. package/dist/contracts/variables.js +9 -13
  201. package/dist/contracts/webhooks.d.ts +13 -5
  202. package/dist/contracts/webhooks.js +3 -1
  203. package/dist/contracts/zero.d.ts +72 -81
  204. package/dist/contracts/zero.js +80 -78
  205. package/dist/dashboard-paths/index.d.ts +24 -21
  206. package/dist/dashboard-paths/index.js +35 -47
  207. package/dist/dashboard-paths/route-reservations.generated.d.ts +2 -0
  208. package/dist/dashboard-paths/route-reservations.generated.js +36 -0
  209. package/dist/docs/agent-arrival.d.ts +92 -0
  210. package/dist/docs/agent-arrival.js +227 -0
  211. package/dist/docs/agent-output-policy.d.ts +6 -0
  212. package/dist/docs/agent-output-policy.js +22 -0
  213. package/dist/docs/agent-prose.d.ts +12 -18
  214. package/dist/docs/agent-prose.js +73 -51
  215. package/dist/docs/agent-setup.d.ts +72 -41
  216. package/dist/docs/agent-setup.js +339 -436
  217. package/dist/docs/catalog.d.ts +153 -95
  218. package/dist/docs/catalog.js +163 -48
  219. package/dist/docs/error-docs.d.ts +2098 -1
  220. package/dist/docs/error-docs.js +421 -144
  221. package/dist/docs/index-build.d.ts +0 -1
  222. package/dist/docs/index-build.js +2 -3
  223. package/dist/docs/page-context-prompt.d.ts +77 -0
  224. package/dist/docs/page-context-prompt.js +131 -0
  225. package/dist/docs/reference-urls.d.ts +46 -0
  226. package/dist/docs/reference-urls.js +79 -0
  227. package/dist/docs/search.d.ts +6 -8
  228. package/dist/docs/search.js +10 -13
  229. package/dist/docs/skill-distribution.d.ts +4 -1
  230. package/dist/docs/skill-distribution.js +10 -5
  231. package/dist/docs/skills.d.ts +120 -120
  232. package/dist/docs/skills.js +121 -73
  233. package/dist/docs/start-prompts.d.ts +45 -0
  234. package/dist/docs/start-prompts.js +62 -0
  235. package/dist/domain-exploration.js +9 -13
  236. package/dist/og-template.d.ts +56 -0
  237. package/dist/og-template.js +56 -0
  238. package/dist/slug-policy/index.js +5 -11
  239. package/dist/test-helpers/fetch-stub.js +1 -0
  240. package/dist/utils/browser-credential.d.ts +13 -6
  241. package/dist/utils/browser-credential.js +14 -7
  242. package/dist/utils/build-settings.d.ts +21 -1
  243. package/dist/utils/build-settings.js +133 -15
  244. package/dist/utils/canonical-json.d.ts +3 -5
  245. package/dist/utils/canonical-json.js +4 -5
  246. package/dist/utils/cast-transport.d.ts +5 -17
  247. package/dist/utils/cast-transport.js +6 -19
  248. package/dist/utils/claim-token.js +1 -2
  249. package/dist/utils/comment-avatars.js +4 -6
  250. package/dist/utils/concurrency.js +3 -3
  251. package/dist/utils/content-type.d.ts +7 -6
  252. package/dist/utils/content-type.js +73 -51
  253. package/dist/utils/credential-policy.d.ts +50 -6
  254. package/dist/utils/credential-policy.js +126 -59
  255. package/dist/utils/dns-instructions.js +9 -9
  256. package/dist/utils/egress-policy.fixtures.json +1 -1
  257. package/dist/utils/error-code.js +1 -0
  258. package/dist/utils/generate-space-name.d.ts +3 -8
  259. package/dist/utils/generate-space-name.js +3 -8
  260. package/dist/utils/grant-decision.fixtures.json +2 -2
  261. package/dist/utils/grants.d.ts +0 -1
  262. package/dist/utils/grants.js +7 -8
  263. package/dist/utils/gravatar.d.ts +2 -4
  264. package/dist/utils/gravatar.js +6 -12
  265. package/dist/utils/id-hints.js +14 -23
  266. package/dist/utils/idempotency.d.ts +3 -3
  267. package/dist/utils/idempotency.js +6 -7
  268. package/dist/utils/local-space-state.d.ts +23 -26
  269. package/dist/utils/local-space-state.js +46 -46
  270. package/dist/utils/oauth-signed-query.d.ts +3 -5
  271. package/dist/utils/oauth-signed-query.js +6 -9
  272. package/dist/utils/one-shot-replay.d.ts +7 -6
  273. package/dist/utils/one-shot-replay.js +3 -5
  274. package/dist/utils/page-colors.d.ts +15 -19
  275. package/dist/utils/page-colors.js +23 -45
  276. package/dist/utils/page-fonts.d.ts +1 -1
  277. package/dist/utils/page-fonts.js +8 -20
  278. package/dist/utils/page-preview.d.ts +0 -1
  279. package/dist/utils/page-preview.js +0 -1
  280. package/dist/utils/pages.d.ts +33 -3
  281. package/dist/utils/pages.js +83 -30
  282. package/dist/utils/privacy-regions.d.ts +19 -0
  283. package/dist/utils/privacy-regions.js +91 -0
  284. package/dist/utils/publish-form-data.d.ts +4 -5
  285. package/dist/utils/publish-form-data.js +2 -3
  286. package/dist/utils/publish-policy.d.ts +11 -17
  287. package/dist/utils/publish-policy.fixtures.json +11 -5
  288. package/dist/utils/publish-policy.js +65 -110
  289. package/dist/utils/query-client.d.ts +2 -0
  290. package/dist/utils/query-client.js +10 -1
  291. package/dist/utils/runtime-paths.d.ts +4 -4
  292. package/dist/utils/runtime-paths.js +6 -8
  293. package/dist/utils/runtime-upload.d.ts +9 -0
  294. package/dist/utils/runtime-upload.js +12 -0
  295. package/dist/utils/secure-local-file.d.ts +3 -3
  296. package/dist/utils/secure-local-file.js +23 -40
  297. package/dist/utils/space-config.d.ts +12 -15
  298. package/dist/utils/space-config.js +13 -16
  299. package/dist/utils/static-runtime-policy.d.ts +10 -7
  300. package/dist/utils/static-runtime-policy.fixtures.json +38 -41
  301. package/dist/utils/static-runtime-policy.generated.d.ts +16 -0
  302. package/dist/utils/static-runtime-policy.generated.js +70 -0
  303. package/dist/utils/static-runtime-policy.js +31 -132
  304. package/dist/utils/storage-policy.js +1 -2
  305. package/dist/utils/upload-session.d.ts +4 -1
  306. package/dist/utils/upload-session.js +41 -19
  307. package/dist/utils/version-path.js +11 -19
  308. package/dist/utils/wpcom-auth-redirects.d.ts +5 -14
  309. package/dist/utils/wpcom-auth-redirects.js +1 -4
  310. package/dist/vocabulary.d.ts +13 -13
  311. package/dist/vocabulary.js +52 -27
  312. package/package.json +15 -18
  313. package/dist/agents/client-registry.d.ts +0 -22
  314. package/dist/agents/client-registry.js +0 -41
  315. package/dist/docs/agent-handoff-document.d.ts +0 -15
  316. package/dist/docs/agent-handoff-document.js +0 -180
  317. package/dist/docs/agent-solutions.d.ts +0 -110
  318. package/dist/docs/agent-solutions.js +0 -183
  319. package/dist/utils/query-keys.d.ts +0 -84
  320. package/dist/utils/query-keys.js +0 -108
@@ -1,11 +1,12 @@
1
1
  /**
2
- * Map a file extension to a Content-Type header value. Returns
3
- * `application/octet-stream` when the extension is not recognized.
4
- *
5
- * MIME extension coverage comes from the maintained `mime` database. The
6
- * small overrides above preserve intentional existing policy; this module
7
- * does not carry a second partial extension registry.
2
+ * Content-Type for a file extension, `application/octet-stream` when unknown.
3
+ * Coverage comes from the `mime` database; the overrides above are the only
4
+ * exceptions, and this module never grows a second extension registry.
8
5
  */
9
6
  export declare function contentTypeForPath(filePath: string): string;
10
7
  export declare function textTypeForPath(filePath: string): string | null;
8
+ export declare const CONTENT_SNIFF_KINDS: readonly ["png", "jpeg", "gif", "webp", "avif", "ico", "pdf", "gzip", "woff", "woff2", "ttf", "otf", "text", "binary"];
9
+ export type ContentSniffKind = (typeof CONTENT_SNIFF_KINDS)[number];
10
+ export declare function contentSniffKind(bytes: Uint8Array): ContentSniffKind;
11
+ export declare function contentTypeForSniff(filePath: string, sniff: ContentSniffKind): string;
11
12
  export declare function contentTypeForBytes(filePath: string, bytes: Uint8Array): string;
@@ -1,7 +1,7 @@
1
1
  import mime from "mime";
2
2
  const CONTENT_TYPE_OVERRIDES = {
3
- // Preserve the public uploader/runtime policy where the database's preferred
4
- // server-oriented type differs from the established browser-facing type.
3
+ // Where the mime database's server-oriented type differs from the
4
+ // browser-facing type we already serve.
5
5
  ".cjs": "text/javascript",
6
6
  ".cts": "text/plain",
7
7
  ".d.ts": "text/plain",
@@ -18,12 +18,9 @@ const UTF8_APPLICATION_TYPES = new Set([
18
18
  "application/xml",
19
19
  ]);
20
20
  /**
21
- * Map a file extension to a Content-Type header value. Returns
22
- * `application/octet-stream` when the extension is not recognized.
23
- *
24
- * MIME extension coverage comes from the maintained `mime` database. The
25
- * small overrides above preserve intentional existing policy; this module
26
- * does not carry a second partial extension registry.
21
+ * Content-Type for a file extension, `application/octet-stream` when unknown.
22
+ * Coverage comes from the `mime` database; the overrides above are the only
23
+ * exceptions, and this module never grows a second extension registry.
27
24
  */
28
25
  export function contentTypeForPath(filePath) {
29
26
  const normalizedPath = filePath.toLowerCase();
@@ -70,53 +67,78 @@ function bytesLookTextual(bytes) {
70
67
  }
71
68
  return true;
72
69
  }
73
- export function contentTypeForBytes(filePath, bytes) {
74
- if (hasPrefix(bytes, [0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a])) {
75
- return "image/png";
76
- }
77
- if (hasPrefix(bytes, [0xff, 0xd8, 0xff])) {
78
- return "image/jpeg";
79
- }
80
- if (hasAsciiPrefix(bytes, "GIF87a") || hasAsciiPrefix(bytes, "GIF89a")) {
81
- return "image/gif";
82
- }
83
- if (hasAsciiPrefix(bytes, "RIFF") && hasAsciiPrefix(bytes.slice(8), "WEBP")) {
84
- return "image/webp";
85
- }
70
+ export const CONTENT_SNIFF_KINDS = [
71
+ "png",
72
+ "jpeg",
73
+ "gif",
74
+ "webp",
75
+ "avif",
76
+ "ico",
77
+ "pdf",
78
+ "gzip",
79
+ "woff",
80
+ "woff2",
81
+ "ttf",
82
+ "otf",
83
+ "text",
84
+ "binary",
85
+ ];
86
+ export function contentSniffKind(bytes) {
87
+ if (hasPrefix(bytes, [0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a]))
88
+ return "png";
89
+ if (hasPrefix(bytes, [0xff, 0xd8, 0xff]))
90
+ return "jpeg";
91
+ if (hasAsciiPrefix(bytes, "GIF87a") || hasAsciiPrefix(bytes, "GIF89a"))
92
+ return "gif";
93
+ if (hasAsciiPrefix(bytes, "RIFF") && hasAsciiPrefix(bytes.slice(8), "WEBP"))
94
+ return "webp";
86
95
  if (hasAsciiPrefix(bytes.slice(4), "ftypavif") || hasAsciiPrefix(bytes.slice(4), "ftypavis")) {
87
- return "image/avif";
88
- }
89
- if (hasPrefix(bytes, [0x00, 0x00, 0x01, 0x00])) {
90
- return "image/x-icon";
91
- }
92
- if (hasAsciiPrefix(bytes, "%PDF-")) {
93
- return "application/pdf";
94
- }
95
- if (hasPrefix(bytes, [0x1f, 0x8b, 0x08])) {
96
- return "application/gzip";
97
- }
98
- if (hasAsciiPrefix(bytes, "wOFF")) {
99
- return "font/woff";
100
- }
101
- if (hasAsciiPrefix(bytes, "wOF2")) {
102
- return "font/woff2";
103
- }
104
- if (hasPrefix(bytes, [0x00, 0x01, 0x00, 0x00]) || hasAsciiPrefix(bytes, "true")) {
105
- return "font/ttf";
106
- }
107
- if (hasAsciiPrefix(bytes, "OTTO")) {
108
- return "font/otf";
109
- }
96
+ return "avif";
97
+ }
98
+ if (hasPrefix(bytes, [0x00, 0x00, 0x01, 0x00]))
99
+ return "ico";
100
+ if (hasAsciiPrefix(bytes, "%PDF-"))
101
+ return "pdf";
102
+ if (hasPrefix(bytes, [0x1f, 0x8b, 0x08]))
103
+ return "gzip";
104
+ if (hasAsciiPrefix(bytes, "wOFF"))
105
+ return "woff";
106
+ if (hasAsciiPrefix(bytes, "wOF2"))
107
+ return "woff2";
108
+ if (hasPrefix(bytes, [0x00, 0x01, 0x00, 0x00]) || hasAsciiPrefix(bytes, "true"))
109
+ return "ttf";
110
+ if (hasAsciiPrefix(bytes, "OTTO"))
111
+ return "otf";
112
+ return bytesLookTextual(bytes) ? "text" : "binary";
113
+ }
114
+ const CONTENT_TYPES_BY_SNIFF = {
115
+ png: "image/png",
116
+ jpeg: "image/jpeg",
117
+ gif: "image/gif",
118
+ webp: "image/webp",
119
+ avif: "image/avif",
120
+ ico: "image/x-icon",
121
+ pdf: "application/pdf",
122
+ gzip: "application/gzip",
123
+ woff: "font/woff",
124
+ woff2: "font/woff2",
125
+ ttf: "font/ttf",
126
+ otf: "font/otf",
127
+ text: null,
128
+ binary: null,
129
+ };
130
+ export function contentTypeForSniff(filePath, sniff) {
131
+ const detected = CONTENT_TYPES_BY_SNIFF[sniff];
132
+ if (detected)
133
+ return detected;
110
134
  const textType = textTypeForPath(filePath);
111
- if (textType && bytesLookTextual(bytes)) {
135
+ if (sniff === "text" && textType)
112
136
  return textType;
113
- }
114
- // Container signatures such as ISO-BMFF, WebM, and Ogg are shared by audio
115
- // and video variants. The extension is the reliable discriminator for the
116
- // manifest declaration, while unknown binary extensions remain generic.
117
137
  const pathType = contentTypeForPath(filePath);
118
- if (pathType.startsWith("audio/") || pathType.startsWith("video/")) {
138
+ if (pathType.startsWith("audio/") || pathType.startsWith("video/"))
119
139
  return pathType;
120
- }
121
140
  return "application/octet-stream";
122
141
  }
142
+ export function contentTypeForBytes(filePath, bytes) {
143
+ return contentTypeForSniff(filePath, contentSniffKind(bytes));
144
+ }
@@ -1,3 +1,4 @@
1
+ import { type ApprovableScope } from "../contracts/access-profiles.js";
1
2
  import { type ApiKeyPreset, type ApiCredentialPolicy, type StatticAction } from "../contracts/api-keys.js";
2
3
  type RequestCondition = NonNullable<ApiCredentialPolicy["statements"][number]["conditions"]>;
3
4
  export type PolicyCompileInput = {
@@ -8,21 +9,64 @@ export type PolicyAuthorizeInput = {
8
9
  policy: ApiCredentialPolicy;
9
10
  action: StatticAction;
10
11
  /**
11
- * Candidate resource URIs for one request target, evaluated together: spaces
12
- * are addressed by their canonical site-rooted URI AND a principal-scoped
13
- * candidate so principal wildcards cover them. A deny matching ANY candidate
14
- * wins; otherwise an allow matching any candidate permits.
12
+ * Candidate URIs for one request target: a space is addressed both by its
13
+ * site-rooted URI and by a principal-scoped one. A deny on any candidate
14
+ * wins; an allow on any candidate permits.
15
15
  */
16
16
  resource: string | readonly string[];
17
17
  conditions?: RequestCondition;
18
18
  };
19
- export declare const publishActions: ("spaces:read" | "spaces:write" | "spaces:publish" | "builds:trigger" | "spaces:create" | "versions:read" | "versions:promote" | "versions:download" | "builds:read" | "builds:create")[];
19
+ /**
20
+ * What a publishing credential may do — the same set the `publish:write` OAuth
21
+ * scope grants, derived from the one scope⇄action table so an API-key preset
22
+ * and an OAuth client of the same tier can never drift apart.
23
+ */
24
+ export declare const publishActions: ("teams:read" | "teams:create" | "spaces:read" | "spaces:write" | "spaces:rename" | "domains:read" | "spaces:publish" | "builds:trigger" | "*" | "spaces:create" | "spaces:delete" | "spaces:transfer" | "spaces:export" | "spaces:import" | "spaces:policy.write" | "versions:read" | "versions:promote" | "versions:delete" | "versions:download" | "domains:create" | "domains:verify" | "domains:assign" | "domains:bind" | "domains:delete" | "domains:dns.write" | "domains:dns.credentials.write" | "domains:purchase" | "webhooks:read" | "webhooks:write" | "builds:read" | "builds:create" | "variables:read" | "variables:write" | "tenants:read" | "tenants:write" | "principals:read" | "principals:write" | "infrastructure:read" | "teams:write" | "teams:members.write" | "billing:read" | "billing:write" | "tokens:read" | "tokens:create" | "tokens:revoke" | "runtime:manage")[];
25
+ /** The canonical policy resource for a team principal's subtree. */
26
+ export declare function teamResource(input: PolicyCompileInput): string;
20
27
  export declare function compileApiKeyPreset(preset: ApiKeyPreset, input: PolicyCompileInput): ApiCredentialPolicy;
21
- /** Expand a named API-key preset into the finite permissions sent on the public wire contract. */
28
+ /**
29
+ * Expand a named API-key preset into the finite permissions sent on the public
30
+ * wire contract. Deduplicated, because presets compose overlapping action
31
+ * groups and `allowPolicy` dedupes what it compiles — the wire list and the
32
+ * compiled statement must name the same actions.
33
+ */
22
34
  export declare function apiKeyPresetPermissions(preset: ApiKeyPreset): StatticAction[];
35
+ export declare function compileTenantRootedPolicy(input: {
36
+ tenantId: string;
37
+ preset: ApiKeyPreset;
38
+ }): ApiCredentialPolicy;
39
+ export declare function compilePartnerPrincipalPolicy(input: {
40
+ tenantId: string;
41
+ normalizedPrincipalId: string;
42
+ }): ApiCredentialPolicy;
23
43
  export declare function compileTeamRolePolicy(input: PolicyCompileInput & {
24
44
  role: string;
25
45
  }): ApiCredentialPolicy;
46
+ /**
47
+ * The authority a membership-following key resolves to for one team: an action
48
+ * set bounded by the member's live role.
49
+ *
50
+ * Takes the action set rather than a preset name because a key's authority is
51
+ * not always its preset's CURRENT meaning. A key whose stored preset was
52
+ * redefined under it carries an explicit pin of the actions it was granted
53
+ * (`preset_actions_pin`), and that pin is what it keeps authorizing by.
54
+ */
55
+ export declare function compileBoundedActionsPolicy(actions: readonly StatticAction[], input: PolicyCompileInput & {
56
+ role: string;
57
+ }): ApiCredentialPolicy;
58
+ /**
59
+ * Whether a person holding `role` in a team can currently exercise `scope`
60
+ * there. Account-plane scopes are admission the person always holds for
61
+ * themselves — no team role could bound them. Team-plane scopes need every
62
+ * action they grant inside the role's compiled policy.
63
+ *
64
+ * Informational, not a gate: approval no longer fails on role (authority is
65
+ * bounded live, per request, by `compileBoundedActionsPolicy`); the approval
66
+ * page uses this to tell the approver what a grant will actually do under
67
+ * their current role.
68
+ */
69
+ export declare function scopeGrantableByRole(scope: ApprovableScope, role: string): boolean;
26
70
  export declare function compileBoundedPresetPolicy(preset: ApiKeyPreset, input: PolicyCompileInput & {
27
71
  role: string;
28
72
  }): ApiCredentialPolicy;
@@ -1,16 +1,12 @@
1
+ import { SCOPE_PLANES } from "../contracts/access-profiles.js";
1
2
  import { SPACEFAST_ACCESS_POLICY_VERSION, parseStatticResource, } from "../contracts/api-keys.js";
2
- export const publishActions = [
3
- "spaces:read",
4
- "spaces:create",
5
- "spaces:write",
6
- "spaces:publish",
7
- "versions:read",
8
- "versions:promote",
9
- "versions:download",
10
- "builds:read",
11
- "builds:trigger",
12
- "builds:create",
13
- ];
3
+ import { oauthScopeActions, oauthScopeActionsFor } from "../contracts/oauth-scope-actions.js";
4
+ /**
5
+ * What a publishing credential may do — the same set the `publish:write` OAuth
6
+ * scope grants, derived from the one scope⇄action table so an API-key preset
7
+ * and an OAuth client of the same tier can never drift apart.
8
+ */
9
+ export const publishActions = oauthScopeActionsFor("publish:write");
14
10
  const spaceAdminActions = [
15
11
  ...publishActions,
16
12
  "spaces:rename",
@@ -19,22 +15,13 @@ const spaceAdminActions = [
19
15
  "spaces:export",
20
16
  "spaces:import",
21
17
  "versions:delete",
22
- // Resolving the owning team (name/slug) is part of administering its spaces:
23
- // the CLI resolves teams before every publish, so admin-tier presets carry
24
- // read access to the team resource itself.
18
+ // The CLI resolves the owning team before every publish, so admin-tier
19
+ // presets need read access to the team resource itself.
25
20
  "teams:read",
26
21
  ];
27
- const domainActions = [
28
- "domains:read",
29
- "domains:create",
30
- "domains:verify",
31
- "domains:assign",
32
- "domains:bind",
33
- "domains:delete",
34
- "domains:dns.write",
35
- "domains:purchase",
36
- ];
37
- function teamResource(input) {
22
+ const domainActions = oauthScopeActionsFor("domains:write");
23
+ /** The canonical policy resource for a team principal's subtree. */
24
+ export function teamResource(input) {
38
25
  return `stt://tenant/${input.tenantId}/principal/team/${input.teamId}/*`;
39
26
  }
40
27
  function spaceResource(input) {
@@ -43,21 +30,29 @@ function spaceResource(input) {
43
30
  export function compileApiKeyPreset(preset, input) {
44
31
  return allowPolicy(apiKeyPresetPermissions(preset), [teamResource(input)]);
45
32
  }
46
- /** Expand a named API-key preset into the finite permissions sent on the public wire contract. */
33
+ /**
34
+ * Expand a named API-key preset into the finite permissions sent on the public
35
+ * wire contract. Deduplicated, because presets compose overlapping action
36
+ * groups and `allowPolicy` dedupes what it compiles — the wire list and the
37
+ * compiled statement must name the same actions.
38
+ */
47
39
  export function apiKeyPresetPermissions(preset) {
40
+ return [...new Set(presetActions(preset))];
41
+ }
42
+ function presetActions(preset) {
48
43
  switch (preset) {
49
44
  case "ci_deploy":
50
45
  case "space_publisher":
51
- return [...publishActions];
46
+ // `sf publish` resolves the owning team before it creates a Space, so a
47
+ // publishing key that cannot read its own team cannot publish a new one
48
+ // at all - the CLI's team pre-flight sees an empty list and stops before
49
+ // the API, which would have resolved the team from the key itself.
50
+ // `publishActions` stays the pure set of publish actions: claim
51
+ // continuation checks a team role against it.
52
+ return [...publishActions, "teams:read"];
52
53
  case "space_admin":
53
- return [...spaceAdminActions];
54
- case "site_admin":
55
54
  return [
56
- "sites:read",
57
- "sites:create",
58
- "sites:write",
59
- "sites:delete",
60
- "sites:policy.write",
55
+ "spaces:policy.write",
61
56
  ...spaceAdminActions,
62
57
  ...domainActions,
63
58
  "webhooks:read",
@@ -69,9 +64,54 @@ export function apiKeyPresetPermissions(preset) {
69
64
  return ["teams:read", "billing:read"];
70
65
  case "team_admin":
71
66
  return ["*"];
67
+ // The partner tier: everything a partner needs to run its own customers'
68
+ // spaces on our infrastructure, and nothing that mints credentials, edits
69
+ // team membership, or moves money.
70
+ case "partner_admin":
71
+ return [
72
+ "tenants:read",
73
+ "tenants:write",
74
+ "principals:read",
75
+ "principals:write",
76
+ "infrastructure:read",
77
+ "spaces:policy.write",
78
+ ...spaceAdminActions,
79
+ ...domainActions,
80
+ "webhooks:read",
81
+ "webhooks:write",
82
+ "teams:read",
83
+ "billing:read",
84
+ ];
72
85
  }
73
86
  throw new Error("Unsupported API key preset.");
74
87
  }
88
+ // A partner credential is rooted at the tenant, not at a team principal: it
89
+ // reaches every principal the tenant owns — teams and external customers alike —
90
+ // and stops at the tenant boundary. `compileApiKeyPreset` stays the team-rooted
91
+ // compiler; it needs a teamId this shape has no meaning for.
92
+ export function compileTenantRootedPolicy(input) {
93
+ return allowPolicy(apiKeyPresetPermissions(input.preset), [`stt://tenant/${input.tenantId}`]);
94
+ }
95
+ export function compilePartnerPrincipalPolicy(input) {
96
+ if (input.normalizedPrincipalId.includes("*") || input.normalizedPrincipalId.includes("/")) {
97
+ throw new Error("Partner principal id contains a reserved policy character.");
98
+ }
99
+ return allowPolicy([
100
+ "spaces:read",
101
+ "spaces:create",
102
+ "spaces:write",
103
+ "spaces:rename",
104
+ "spaces:publish",
105
+ "versions:read",
106
+ "versions:promote",
107
+ "versions:download",
108
+ "builds:read",
109
+ "builds:trigger",
110
+ "builds:create",
111
+ "variables:read",
112
+ "variables:write",
113
+ ], [`stt://tenant/${input.tenantId}/principal/external/${input.normalizedPrincipalId}/*`]);
114
+ }
75
115
  export function compileTeamRolePolicy(input) {
76
116
  switch (input.role) {
77
117
  case "owner":
@@ -79,7 +119,6 @@ export function compileTeamRolePolicy(input) {
79
119
  return compileApiKeyPreset("team_admin", input);
80
120
  case "member":
81
121
  return allowPolicy([
82
- "sites:read",
83
122
  "spaces:read",
84
123
  "spaces:create",
85
124
  "spaces:write",
@@ -99,24 +138,56 @@ export function compileTeamRolePolicy(input) {
99
138
  return denyAllPolicy();
100
139
  }
101
140
  }
102
- export function compileBoundedPresetPolicy(preset, input) {
103
- const presetPolicy = compileApiKeyPreset(preset, input);
141
+ /**
142
+ * The authority a membership-following key resolves to for one team: an action
143
+ * set bounded by the member's live role.
144
+ *
145
+ * Takes the action set rather than a preset name because a key's authority is
146
+ * not always its preset's CURRENT meaning. A key whose stored preset was
147
+ * redefined under it carries an explicit pin of the actions it was granted
148
+ * (`preset_actions_pin`), and that pin is what it keeps authorizing by.
149
+ */
150
+ export function compileBoundedActionsPolicy(actions, input) {
104
151
  const rolePolicy = compileTeamRolePolicy(input);
105
- const presetActions = new Set(presetPolicy.statements
106
- .filter((statement) => statement.effect === "allow")
107
- .flatMap((statement) => statement.actions));
152
+ const presetActions = new Set(actions);
108
153
  const roleActions = new Set(rolePolicy.statements
109
154
  .filter((statement) => statement.effect === "allow")
110
155
  .flatMap((statement) => statement.actions));
111
- const actions = presetActions.has("*")
156
+ const bounded = presetActions.has("*")
112
157
  ? [...roleActions]
113
158
  : roleActions.has("*")
114
159
  ? [...presetActions]
115
160
  : [...presetActions].filter((action) => roleActions.has(action));
116
- if (actions.length === 0) {
161
+ if (bounded.length === 0) {
117
162
  return { version: SPACEFAST_ACCESS_POLICY_VERSION, statements: [] };
118
163
  }
119
- return allowPolicy(actions, [teamResource(input)]);
164
+ return allowPolicy(bounded, [teamResource(input)]);
165
+ }
166
+ /**
167
+ * Whether a person holding `role` in a team can currently exercise `scope`
168
+ * there. Account-plane scopes are admission the person always holds for
169
+ * themselves — no team role could bound them. Team-plane scopes need every
170
+ * action they grant inside the role's compiled policy.
171
+ *
172
+ * Informational, not a gate: approval no longer fails on role (authority is
173
+ * bounded live, per request, by `compileBoundedActionsPolicy`); the approval
174
+ * page uses this to tell the approver what a grant will actually do under
175
+ * their current role.
176
+ */
177
+ export function scopeGrantableByRole(scope, role) {
178
+ if (SCOPE_PLANES[scope] === "account") {
179
+ return true;
180
+ }
181
+ const roleActions = new Set(compileTeamRolePolicy({ tenantId: "-", teamId: "-", role })
182
+ .statements.filter((statement) => statement.effect === "allow")
183
+ .flatMap((statement) => statement.actions));
184
+ if (roleActions.has("*")) {
185
+ return true;
186
+ }
187
+ return oauthScopeActions([scope]).every((action) => roleActions.has(action));
188
+ }
189
+ export function compileBoundedPresetPolicy(preset, input) {
190
+ return compileBoundedActionsPolicy(apiKeyPresetPermissions(preset), input);
120
191
  }
121
192
  export function compileSpaceContinuationPolicy(input) {
122
193
  return allowPolicy(publishActions.filter((action) => action !== "spaces:create"), [spaceResource(input)]);
@@ -141,7 +212,7 @@ export function policyIsSubsetOfGrantor(requested, grantor) {
141
212
  return statement.actions.every((action) => statement.resources.every((resource) => grantorAllows(grantor, action, resource, statement.conditions)));
142
213
  }) && grantorDeniesArePreserved(requested, grantor));
143
214
  }
144
- // Request-time evaluation (internal-docs/platform.md IAM-lite): explicit deny wins,
215
+ // Request-time evaluation (the platform spec IAM-lite): explicit deny wins,
145
216
  // explicit allow permits, otherwise implicit deny. Condition keys are ANDed and an
146
217
  // unresolvable condition attribute fails closed (see `conditionsMatch`).
147
218
  export function policyAllows(input) {
@@ -152,7 +223,7 @@ export function policyAllows(input) {
152
223
  return resources.some((resource) => matchesEffect(input.policy, "allow", input.action, resource, input.conditions, "request"));
153
224
  }
154
225
  // The tenants a credential's policy grants any access to. Drives tenant
155
- // selection (internal-docs/platform.md Tenant): `X-Spacefast-Tenant-Id` may pick
226
+ // selection (the platform spec Tenant): `X-Spacefast-Tenant-Id` may pick
156
227
  // one granted tenant but is never an authority by itself, and a token spanning
157
228
  // multiple tenants must fail ambiguous requests with `tenant_selection_required`.
158
229
  export function grantedTenantsFromPolicy(policy) {
@@ -189,9 +260,8 @@ export function grantedPrincipalsFromPolicy(policy, input) {
189
260
  if (!parsed || (parsed.tenantId !== input.tenantId && parsed.tenantId !== "*")) {
190
261
  continue;
191
262
  }
192
- // Tenant-rooted grants (both `stt://tenant/*` and a concrete
193
- // `stt://tenant/{t}` already filtered to this tenant) are scope-wide:
194
- // they reach every principal in the tenant.
263
+ // A tenant-rooted grant is scope-wide: `stt://tenant/*` and a concrete
264
+ // `stt://tenant/{t}` both reach every principal in the tenant.
195
265
  if (parsed.kind === "tenant") {
196
266
  all = true;
197
267
  }
@@ -226,9 +296,8 @@ export function grantedPrincipalsFromPolicy(policy, input) {
226
296
  ],
227
297
  };
228
298
  }
229
- // Whether the policy's allow statements reach a resource subtree at all
230
- // either a statement resource covers the base, or it lives inside the base.
231
- // This is a visibility/scoping check (404 vs 403), never an action grant.
299
+ // Whether the policy's allow statements reach a resource subtree at all. This
300
+ // is a visibility/scoping check (404 vs 403), never an action grant.
232
301
  export function policyReaches(policy, resourceBase) {
233
302
  return policy.statements.some((statement) => statement.effect === "allow" &&
234
303
  statement.resources.some((resource) => resourceMatches(resource, resourceBase) ||
@@ -259,10 +328,8 @@ function resourceMatches(pattern, resource) {
259
328
  if (pattern.endsWith("/*")) {
260
329
  return resource === pattern.slice(0, -2) || resource.startsWith(pattern.slice(0, -1));
261
330
  }
262
- // A tenant-rooted resource is scope-wide (internal-docs/platform.md L617/L879:
263
- // `stt://tenant/{t}` is a grantable StatticResource and resource grants cover
264
- // their subtree): it covers every resource inside that tenant. This is the
265
- // tenant-scoped (partner/agency) credential shape.
331
+ // A tenant-rooted resource covers every resource inside that tenant. This is
332
+ // the tenant-scoped (partner/agency) credential shape.
266
333
  if (parseStatticResource(pattern)?.kind === "tenant") {
267
334
  return resource.startsWith(`${pattern}/`);
268
335
  }
@@ -273,11 +340,11 @@ function conditionsMatch(statementConditions, contextConditions, effect, mode) {
273
340
  return true;
274
341
  }
275
342
  return Object.entries(statementConditions).every(([key, value]) => {
343
+ // SAFETY: Object.entries obtains key from the named RequestCondition object immediately above.
276
344
  const resolved = contextConditions?.[key];
277
345
  if (resolved === undefined && mode === "request") {
278
- // Fail closed on unresolvable condition attributes: the condition never
279
- // matches for allow statements and always matches for deny statements, so
280
- // callers cannot dodge a deny by stripping request context.
346
+ // Fail closed: a caller cannot dodge a deny by stripping the request
347
+ // context its condition reads.
281
348
  return effect === "deny";
282
349
  }
283
350
  return resolved === value;
@@ -15,15 +15,15 @@ export function addressDnsInstructionsForHostname(input) {
15
15
  normalizeDnsName(instruction.name) !== hostname) {
16
16
  return [];
17
17
  }
18
- return [
19
- {
20
- type: instruction.type,
21
- name: instruction.name,
22
- value: instruction.value,
23
- purpose: instruction.purpose,
24
- ...(instruction.ttl === undefined ? {} : { ttl: instruction.ttl }),
25
- },
26
- ];
18
+ const result = {
19
+ type: instruction.type,
20
+ name: instruction.name,
21
+ value: instruction.value,
22
+ purpose: instruction.purpose,
23
+ };
24
+ if (instruction.ttl !== undefined)
25
+ result.ttl = instruction.ttl;
26
+ return [result];
27
27
  });
28
28
  }
29
29
  function normalizeAddress(value) {
@@ -45,7 +45,7 @@
45
45
  { "host": "sub.localhost", "allowed": false },
46
46
  { "host": "169.254.169.254", "allowed": false },
47
47
  { "host": "view.fast", "allowed": false },
48
- { "host": "wpc-manage-site-123.view.fast", "allowed": false },
48
+ { "host": "site-123.view.fast", "allowed": false },
49
49
  { "host": "example.com", "allowed": true }
50
50
  ]
51
51
  }
@@ -3,5 +3,6 @@ export function hasErrorCode(error, code) {
3
3
  return (error !== null &&
4
4
  typeof error === "object" &&
5
5
  "code" in error &&
6
+ // SAFETY: The preceding checks prove error is a non-null object with a code property.
6
7
  error.code === code);
7
8
  }
@@ -1,12 +1,7 @@
1
1
  /**
2
- * Generates a short, readable space title.
3
- *
4
- * The pool mixes a little WordPress and web flavor with broad nature, color,
5
- * motion, and craft vocabulary. The result should suit any site instead of
6
- * reading like a CMS inside joke, while staying compact enough for a hostname.
7
- *
8
- * The generator is intentionally dependency-free so it can be shared by the
9
- * control-plane, dashboard, CLI, and future publishing surfaces.
2
+ * Short, readable space titles. Keep the pools site-neutral and short enough
3
+ * for a hostname. Dependency-free so the control plane, dashboard and CLI can
4
+ * all share it.
10
5
  */
11
6
  export declare const SPACE_TITLE_COMBINATION_COUNT: number;
12
7
  export declare function generateSpaceTitle(random?: () => number): string;
@@ -1,12 +1,7 @@
1
1
  /**
2
- * Generates a short, readable space title.
3
- *
4
- * The pool mixes a little WordPress and web flavor with broad nature, color,
5
- * motion, and craft vocabulary. The result should suit any site instead of
6
- * reading like a CMS inside joke, while staying compact enough for a hostname.
7
- *
8
- * The generator is intentionally dependency-free so it can be shared by the
9
- * control-plane, dashboard, CLI, and future publishing surfaces.
2
+ * Short, readable space titles. Keep the pools site-neutral and short enough
3
+ * for a hostname. Dependency-free so the control plane, dashboard and CLI can
4
+ * all share it.
10
5
  */
11
6
  const ADJECTIVES = [
12
7
  "Atomic",
@@ -1438,8 +1438,8 @@
1438
1438
  "principal": {}
1439
1439
  },
1440
1440
  "expected": {
1441
- "capabilities": ["page.view"],
1442
- "matchedGrantIds": ["grt_all_versions"]
1441
+ "capabilities": [],
1442
+ "matchedGrantIds": []
1443
1443
  },
1444
1444
  "phpProjectionCompiles": true
1445
1445
  },
@@ -44,7 +44,6 @@ export type GrantEvaluation = {
44
44
  matches: GrantMatch[];
45
45
  };
46
46
  export declare function grantResourcePatternMatches(pattern: string, resource: string, resourceKind?: "route" | "artifact"): boolean;
47
- /** Does a Grant's resource set reach this path? Include, minus exclude. */
48
47
  export declare function grantResourceSetMatches(resources: Grant["resources"], resource: string, resourceKind?: "route" | "artifact"): boolean;
49
48
  export type GrantEvaluationExplanation = {
50
49
  grantId: string;