@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,10 +1,5 @@
1
1
  import { z } from "zod";
2
2
  import { baseDiagnosticSchema } from "./common.js";
3
- export const conventionFilesSchema = z.object({
4
- redirects: z.string().optional(),
5
- headers: z.string().optional(),
6
- routes: z.string().optional(),
7
- });
8
3
  const manifestSha256Schema = z
9
4
  .string()
10
5
  .regex(/^[0-9a-f]{64}$/, "sha256 must be 64 lowercase hex characters without a prefix.")
@@ -20,18 +15,13 @@ export const manifestFileSchema = z.object({
20
15
  size: z.number().int().nonnegative().describe("File size in bytes."),
21
16
  sha256: manifestSha256Schema
22
17
  .optional()
23
- .describe("SHA-256 content digest: exactly 64 lowercase hex characters, no `sha256:` prefix (Version.manifestHash is the only prefixed form). Required when the caller uploads local bytes; may be absent on historical records and sourceUrl entries."),
18
+ .describe("Optional SHA-256 content digest, 64 lowercase hex characters without the `sha256:` prefix. Omit it to let the runtime hash uploaded bytes; include it to upload by content address, with the digest verified as the bytes land."),
24
19
  contentType: z.string().optional().describe("Optional content type for serving metadata."),
25
20
  sourceUrl: manifestSourceUrlSchema
26
21
  .optional()
27
22
  .describe("Optional HTTPS URL the runtime can fetch directly for this file instead of receiving bytes from the client."),
28
23
  });
29
- export const uploadManifestFileSchema = z
30
- .union([
31
- manifestFileSchema.extend({ sha256: manifestSha256Schema }),
32
- manifestFileSchema.extend({ sourceUrl: manifestSourceUrlSchema }),
33
- ])
34
- .describe("A declared upload file. Local bytes require sha256. A sourceUrl entry may omit sha256 because the runtime computes it while fetching.");
24
+ export const uploadManifestFileSchema = manifestFileSchema.describe("A declared upload file. sha256 is optional: omit it for runtime-hashed path uploads or sourceUrl fetches; include it for content-addressed uploads.");
35
25
  export const pendingUploadSchema = manifestFileSchema.pick({
36
26
  path: true,
37
27
  size: true,
@@ -87,9 +77,18 @@ export const uploadInstructionsSchema = z.object({
87
77
  targets: z
88
78
  .array(uploadTargetSchema)
89
79
  .default([])
90
- .describe("Opaque upload targets, bounded by the instruction payload budget. Upload these, then call `links.resume` for the remainder."),
80
+ .describe("Opaque upload targets, bounded by the instruction payload budget. Upload these, then call `links.refresh` for the remainder."),
91
81
  links: z.object({
92
- resume: z.string(),
82
+ // The key names the action — mint a fresh instruction page for whatever the
83
+ // session still needs — not the route that happens to serve it.
84
+ refresh: z.string(),
85
+ // Transition alias for clients baked before the rename (#2449). Deployed
86
+ // CLIs and dashboard bundles still *require* `links.resume`, so the server
87
+ // emits both keys with the same value and they keep parsing. Optional here
88
+ // so nothing new is forced to produce it. Remove — with the `/uploads/resume`
89
+ // route alias and the receipt's `links.resume` — once every baked client is
90
+ // rebuilt.
91
+ resume: z.string().optional(),
93
92
  finalize: z.string(),
94
93
  }),
95
94
  details: z
@@ -1,4 +1,21 @@
1
1
  import { z } from "zod";
2
+ export declare const HOSTED_MCP_SERVER_VERSION: "2026-08-22";
3
+ export declare const HOSTED_MCP_TOOL_CATALOG: readonly [{
4
+ readonly name: "execute";
5
+ readonly description: "Run JavaScript against the OpenAPI-generated Spacefast catalog in a secure sandbox.";
6
+ }, {
7
+ readonly name: "skills";
8
+ readonly description: "Fetch Spacefast how-to guidance for an MCP workflow.";
9
+ }, {
10
+ readonly name: "resume";
11
+ readonly description: "Resume an execution that paused for approval or input.";
12
+ }, {
13
+ readonly name: "publish";
14
+ readonly description: "Publish inline files as a new immutable Spacefast version.";
15
+ }, {
16
+ readonly name: "search_docs";
17
+ readonly description: "Search the published Spacefast documentation. An exact slug or path returns that page in full.";
18
+ }];
2
19
  export declare const hostedMcpSessionStatusSchema: z.ZodEnum<{
3
20
  active: "active";
4
21
  expired: "expired";
@@ -155,6 +172,16 @@ export declare const hostedMcpDashboardResponseSchema: z.ZodObject<{
155
172
  }, z.core.$strip>>;
156
173
  }, z.core.$strip>;
157
174
  }, z.core.$strip>;
175
+ export declare const hostedMcpProxyTokenSchema: z.ZodObject<{
176
+ accessToken: z.ZodString;
177
+ expiresAt: z.ZodString;
178
+ }, z.core.$strip>;
179
+ export declare const hostedMcpProxyTokenResponseSchema: z.ZodObject<{
180
+ data: z.ZodObject<{
181
+ accessToken: z.ZodString;
182
+ expiresAt: z.ZodString;
183
+ }, z.core.$strip>;
184
+ }, z.core.$strip>;
158
185
  export declare const hostedMcpCloseSessionResponseSchema: z.ZodObject<{
159
186
  data: z.ZodObject<{
160
187
  sessionId: z.ZodString;
@@ -243,5 +270,6 @@ export declare const hostedMcpApprovalResponseSchema: z.ZodObject<{
243
270
  export type HostedMcpSession = z.infer<typeof hostedMcpSessionSchema>;
244
271
  export type HostedMcpSessionEvent = z.infer<typeof hostedMcpSessionEventSchema>;
245
272
  export type HostedMcpDashboard = z.infer<typeof hostedMcpDashboardSchema>;
273
+ export type HostedMcpProxyToken = z.infer<typeof hostedMcpProxyTokenSchema>;
246
274
  export type HostedMcpPausedExecution = z.infer<typeof hostedMcpPausedExecutionSchema>;
247
275
  export type HostedMcpApprovalAction = z.infer<typeof hostedMcpApprovalActionSchema>;
@@ -1,5 +1,28 @@
1
1
  import { z } from "zod";
2
2
  import { AnyObjectSchema, dataEnvelope } from "./common.js";
3
+ export const HOSTED_MCP_SERVER_VERSION = "2026-08-22";
4
+ export const HOSTED_MCP_TOOL_CATALOG = [
5
+ {
6
+ name: "execute",
7
+ description: "Run JavaScript against the OpenAPI-generated Spacefast catalog in a secure sandbox.",
8
+ },
9
+ {
10
+ name: "skills",
11
+ description: "Fetch Spacefast how-to guidance for an MCP workflow.",
12
+ },
13
+ {
14
+ name: "resume",
15
+ description: "Resume an execution that paused for approval or input.",
16
+ },
17
+ {
18
+ name: "publish",
19
+ description: "Publish inline files as a new immutable Spacefast version.",
20
+ },
21
+ {
22
+ name: "search_docs",
23
+ description: "Search the published Spacefast documentation. An exact slug or path returns that page in full.",
24
+ },
25
+ ];
3
26
  export const hostedMcpSessionStatusSchema = z.enum(["active", "closed", "expired", "interrupted"]);
4
27
  export const hostedMcpSessionSchema = z.object({
5
28
  sessionId: z.string(),
@@ -50,6 +73,11 @@ export const hostedMcpDashboardSchema = z.object({
50
73
  events: z.array(hostedMcpSessionEventSchema),
51
74
  });
52
75
  export const hostedMcpDashboardResponseSchema = dataEnvelope(hostedMcpDashboardSchema);
76
+ export const hostedMcpProxyTokenSchema = z.object({
77
+ accessToken: z.string().min(1),
78
+ expiresAt: z.string().datetime(),
79
+ });
80
+ export const hostedMcpProxyTokenResponseSchema = dataEnvelope(hostedMcpProxyTokenSchema);
53
81
  export const hostedMcpCloseSessionResponseSchema = dataEnvelope(hostedMcpSessionSchema);
54
82
  export const hostedMcpSessionEventsResponseSchema = dataEnvelope(z.object({
55
83
  session: hostedMcpSessionSchema,
@@ -16,6 +16,12 @@ export declare const meResponseSchema: z.ZodObject<{
16
16
  isAutomattician: z.ZodBoolean;
17
17
  wpcom: z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
18
18
  isSuperadmin: z.ZodBoolean;
19
+ pendingDeletionAt: z.ZodNullable<z.ZodString>;
20
+ dashboardPrefs: z.ZodRecord<z.ZodString, z.ZodUnknown>;
21
+ privacy: z.ZodObject<{
22
+ analyticsOptOut: z.ZodBoolean;
23
+ advertisingOptOut: z.ZodBoolean;
24
+ }, z.core.$strip>;
19
25
  }, z.core.$strip>>;
20
26
  tenants: z.ZodArray<z.ZodObject<{
21
27
  id: z.ZodString;
@@ -65,7 +71,6 @@ export declare const meResponseSchema: z.ZodObject<{
65
71
  beta: z.ZodObject<{
66
72
  gateEnabled: z.ZodBoolean;
67
73
  enrolled: z.ZodBoolean;
68
- wpcom: z.ZodBoolean;
69
74
  eligibleTeams: z.ZodArray<z.ZodObject<{
70
75
  teamId: z.ZodString;
71
76
  name: z.ZodString;
@@ -1,11 +1,12 @@
1
1
  import { z } from "zod";
2
2
  import { betaEligibleTeamSourceSchema } from "./beta.js";
3
+ import { dashboardPrefsSchema } from "./dashboard-prefs.js";
3
4
  import { planCodeSchema } from "./features.js";
4
- // `GET /v1/me` (internal-docs/platform.md route catalog): the authenticated
5
- // subject, its tenant grants, principal/team memberships, and a plan summary.
6
- // Works for every credential kind sessions resolve their user and team
7
- // memberships; machine credentials resolve the teams and tenants their policy
8
- // grants.
5
+ import { privacySettingsSchema } from "./privacy.js";
6
+ // `GET /v1/me` (the platform spec route catalog): the authenticated subject, its
7
+ // tenant grants, principal/team memberships, and a plan summary. Sessions
8
+ // resolve their user and team memberships; machine credentials resolve the teams
9
+ // and tenants their policy grants.
9
10
  export const meResponseSchema = z.object({
10
11
  subject: z
11
12
  .object({
@@ -28,6 +29,12 @@ export const meResponseSchema = z.object({
28
29
  .nullable()
29
30
  .describe("Raw WordPress.com `/me` payload from the user's last WP.com login."),
30
31
  isSuperadmin: z.boolean().describe("Whether the user is a platform operator."),
32
+ pendingDeletionAt: z
33
+ .string()
34
+ .nullable()
35
+ .describe("When this account's deletion was requested, while the close is still running. Null for every account that is not being deleted."),
36
+ dashboardPrefs: dashboardPrefsSchema.describe("The user's dashboard preferences. Carried on the boot payload the dashboard already fetches, so applying a cross-device preference costs no extra request. Write with `PATCH /v1/me/dashboard-preferences`."),
37
+ privacy: privacySettingsSchema.describe("The user's account-level privacy choices. Write with `PATCH /v1/me/privacy`."),
31
38
  })
32
39
  .nullable()
33
40
  .describe("Authenticated user identity for user-subject credentials. Null for team-subject or service-subject machine credentials. Creator metadata is retained only for audit attribution, not request identity."),
@@ -89,7 +96,6 @@ export const meResponseSchema = z.object({
89
96
  enrolled: z
90
97
  .boolean()
91
98
  .describe("Whether the subject user is enrolled (beta_enrolled_at is set)."),
92
- wpcom: z.boolean().describe("Whether the user passed the Automattician check at enrollment."),
93
99
  eligibleTeams: z
94
100
  .array(z.object({
95
101
  teamId: z.string().describe("Team id."),
@@ -38,36 +38,34 @@ export declare const notificationListQuerySchema: z.ZodObject<{
38
38
  unread: z.ZodDefault<z.ZodOptional<z.ZodCodec<z.ZodString, z.ZodBoolean>>>;
39
39
  }, z.core.$strip>;
40
40
  export declare const notificationListResponseSchema: z.ZodObject<{
41
- data: z.ZodObject<{
42
- notifications: z.ZodArray<z.ZodObject<{
43
- id: z.ZodString;
44
- kind: z.ZodEnum<{
45
- "comment.created": "comment.created";
46
- "comment.replied": "comment.replied";
47
- "thread.archived": "thread.archived";
48
- "thread.unarchived": "thread.unarchived";
49
- mention: "mention";
50
- }>;
51
- teamId: z.ZodNullable<z.ZodString>;
52
- spaceId: z.ZodNullable<z.ZodString>;
53
- threadId: z.ZodNullable<z.ZodString>;
54
- title: z.ZodString;
55
- body: z.ZodNullable<z.ZodString>;
56
- actor: z.ZodObject<{
57
- name: z.ZodNullable<z.ZodString>;
58
- avatarUrl: z.ZodNullable<z.ZodString>;
59
- color: z.ZodNullable<z.ZodString>;
60
- }, z.core.$strip>;
61
- path: z.ZodNullable<z.ZodString>;
62
- versionId: z.ZodNullable<z.ZodString>;
63
- link: z.ZodNullable<z.ZodString>;
64
- readAt: z.ZodNullable<z.ZodString>;
65
- createdAt: z.ZodString;
66
- }, z.core.$strip>>;
67
- pagination: z.ZodObject<{
68
- nextCursor: z.ZodNullable<z.ZodString>;
69
- hasMore: z.ZodBoolean;
41
+ data: z.ZodArray<z.ZodObject<{
42
+ id: z.ZodString;
43
+ kind: z.ZodEnum<{
44
+ "comment.created": "comment.created";
45
+ "comment.replied": "comment.replied";
46
+ "thread.archived": "thread.archived";
47
+ "thread.unarchived": "thread.unarchived";
48
+ mention: "mention";
49
+ }>;
50
+ teamId: z.ZodNullable<z.ZodString>;
51
+ spaceId: z.ZodNullable<z.ZodString>;
52
+ threadId: z.ZodNullable<z.ZodString>;
53
+ title: z.ZodString;
54
+ body: z.ZodNullable<z.ZodString>;
55
+ actor: z.ZodObject<{
56
+ name: z.ZodNullable<z.ZodString>;
57
+ avatarUrl: z.ZodNullable<z.ZodString>;
58
+ color: z.ZodNullable<z.ZodString>;
70
59
  }, z.core.$strip>;
60
+ path: z.ZodNullable<z.ZodString>;
61
+ versionId: z.ZodNullable<z.ZodString>;
62
+ link: z.ZodNullable<z.ZodString>;
63
+ readAt: z.ZodNullable<z.ZodString>;
64
+ createdAt: z.ZodString;
65
+ }, z.core.$strip>>;
66
+ pagination: z.ZodObject<{
67
+ nextCursor: z.ZodNullable<z.ZodString>;
68
+ hasMore: z.ZodBoolean;
71
69
  }, z.core.$strip>;
72
70
  }, z.core.$strip>;
73
71
  export declare const notificationUnreadCountResponseSchema: z.ZodObject<{
@@ -28,12 +28,17 @@ export const notificationSchema = z.object({
28
28
  createdAt: z.string().datetime(),
29
29
  });
30
30
  export const notificationListQuerySchema = cursorListQuerySchema.extend({
31
- unread: z.stringbool().optional().default(false),
31
+ unread: z
32
+ .stringbool()
33
+ .optional()
34
+ .default(false)
35
+ .describe("Return only notifications that have not been read yet."),
32
36
  });
33
- export const notificationListResponseSchema = dataEnvelope(z.object({
34
- notifications: z.array(notificationSchema),
37
+ // The one platform list envelope: items in `data[]`, page state beside it.
38
+ export const notificationListResponseSchema = z.object({
39
+ data: z.array(notificationSchema),
35
40
  pagination: CursorPaginationSchema,
36
- }));
41
+ });
37
42
  export const notificationUnreadCountResponseSchema = dataEnvelope(z.object({ count: z.number().int().nonnegative() }));
38
43
  export const notificationReadRequestSchema = z.object({
39
44
  ids: z.array(z.string().min(1)).max(100).optional(),
@@ -3,19 +3,19 @@ export declare const OAUTH_AUTHORIZATION_SERVER_PATH: "/v1/auth";
3
3
  * mcp origin (`https://mcp.<domain>`), so it has no path entry here. */
4
4
  export declare const OAUTH_API_RESOURCE_PATH: "/v1";
5
5
  export type OAuthResourceKey = "api" | "mcp";
6
+ export declare const OAUTH_SHARED_API_RESOURCE_SCOPES: readonly ["teams:read", "teams:create", "spaces:read", "spaces:write", "spaces:rename", "publish:write", "domains:read", "domains:write"];
6
7
  export declare const OAUTH_API_RESOURCE_SCOPES: readonly ["teams:read", "teams:create", "spaces:read", "spaces:write", "spaces:rename", "publish:write", "domains:read", "domains:write", "spaces:publish", "builds:trigger"];
7
- export declare const OAUTH_MCP_TOOL_SCOPE: "mcp:tools";
8
8
  export declare const OAUTH_OFFLINE_ACCESS_SCOPE: "offline_access";
9
- export declare const OAUTH_MCP_RESOURCE_SCOPES: readonly ["mcp:tools", "teams:read", "teams:create", "spaces:read", "spaces:write", "spaces:rename", "publish:write", "domains:read", "domains:write"];
9
+ export declare const OAUTH_MCP_RESOURCE_SCOPES: readonly ["teams:read", "teams:create", "spaces:read", "spaces:write", "spaces:rename", "publish:write", "domains:read", "domains:write"];
10
10
  /**
11
11
  * A resource's `allowedScopes` is intersected with the requested scopes on every
12
- * token request, and the refresh token stores that intersection so a resource
12
+ * token request, and the refresh token stores that intersection, so a resource
13
13
  * that omits `offline_access` cannot mint a refresh token that survives
14
14
  * rotation, and its clients must re-consent in a browser every
15
15
  * `accessTokenTtlSeconds`. Kept separate from OAUTH_MCP_RESOURCE_SCOPES, which
16
- * is the list of capabilities the dashboard and CLI offer per agent account.
16
+ * is the list of capabilities the dashboard and CLI offer per machine OAuth client.
17
17
  */
18
- export declare const OAUTH_MCP_RESOURCE_ALLOWED_SCOPES: readonly ["mcp:tools", "teams:read", "teams:create", "spaces:read", "spaces:write", "spaces:rename", "publish:write", "domains:read", "domains:write", "offline_access"];
18
+ export declare const OAUTH_MCP_RESOURCE_ALLOWED_SCOPES: readonly ["teams:read", "teams:create", "spaces:read", "spaces:write", "spaces:rename", "publish:write", "domains:read", "domains:write", "offline_access"];
19
19
  export declare const OAUTH_API_RESOURCE_ALLOWED_SCOPES: readonly ["teams:read", "teams:create", "spaces:read", "spaces:write", "spaces:rename", "publish:write", "domains:read", "domains:write", "spaces:publish", "builds:trigger", "offline_access"];
20
20
  /**
21
21
  * Interactive MCP clients should be useful after one consent. Authorization is
@@ -23,8 +23,110 @@ export declare const OAUTH_API_RESOURCE_ALLOWED_SCOPES: readonly ["teams:read",
23
23
  * sensitive execution; these scopes only let the MCP resource represent those
24
24
  * capabilities. Machine clients may continue to request a narrower set.
25
25
  */
26
- export declare const OAUTH_MCP_DEFAULT_SCOPES: readonly ["mcp:tools", "teams:read", "teams:create", "spaces:read", "spaces:write", "spaces:rename", "publish:write", "domains:read", "domains:write", "offline_access"];
27
- export declare const OAUTH_PROVIDER_SCOPES: readonly ["openid", "profile", "email", "offline_access", "teams:read", "teams:create", "spaces:read", "spaces:write", "spaces:rename", "publish:write", "domains:read", "domains:write", "spaces:publish", "builds:trigger", "mcp:tools"];
26
+ export declare const OAUTH_MCP_DEFAULT_SCOPES: readonly ["teams:read", "teams:create", "spaces:read", "spaces:write", "spaces:rename", "publish:write", "domains:read", "domains:write", "offline_access"];
27
+ export declare const OAUTH_PROVIDER_SCOPES: readonly ["openid", "profile", "email", "offline_access", "teams:read", "teams:create", "spaces:read", "spaces:write", "spaces:rename", "publish:write", "domains:read", "domains:write", "spaces:publish", "builds:trigger"];
28
+ export declare const OAUTH_SCOPE_DESCRIPTIONS: {
29
+ readonly openid: "Identify the signed-in account.";
30
+ readonly profile: "Read the signed-in account's basic profile.";
31
+ readonly email: "Read the signed-in account's email address.";
32
+ readonly offline_access: "Refresh access without another interactive sign-in.";
33
+ readonly "teams:read": "Read the teams the account belongs to.";
34
+ readonly "teams:create": "Create teams.";
35
+ readonly "spaces:read": "Read spaces, versions, and build status.";
36
+ readonly "spaces:write": "Create and update spaces and their settings.";
37
+ readonly "spaces:rename": "Rename space slugs and managed addresses.";
38
+ readonly "publish:write": "Publish new immutable versions.";
39
+ readonly "spaces:publish": "Publish a version to an existing space.";
40
+ readonly "builds:trigger": "Start a build for an existing version.";
41
+ readonly "domains:read": "Read domain inventory and DNS diagnostics.";
42
+ readonly "domains:write": "Attach, verify, and mutate domains and DNS records.";
43
+ };
44
+ export declare const OAUTH_SCOPE_RISK_TINTS: readonly ["neutral", "warning", "critical"];
45
+ export type OAuthScopeRiskTint = (typeof OAUTH_SCOPE_RISK_TINTS)[number];
46
+ export type OAuthScopeId = keyof typeof OAUTH_SCOPE_DESCRIPTIONS;
47
+ export type OAuthScopeCopy = {
48
+ label: string;
49
+ description: string;
50
+ riskTint: OAuthScopeRiskTint;
51
+ };
52
+ /**
53
+ * Human-facing permission copy shared by every authorization surface. Keep raw
54
+ * OAuth scope ids in developer views only; consent, approvals, ledgers, CLI
55
+ * prompts, and email should all render this vocabulary.
56
+ */
57
+ export declare const OAUTH_SCOPE_COPY: {
58
+ readonly openid: {
59
+ readonly label: "Identify your account";
60
+ readonly description: "Identify the signed-in account.";
61
+ readonly riskTint: "neutral";
62
+ };
63
+ readonly profile: {
64
+ readonly label: "Read your profile";
65
+ readonly description: "Read the signed-in account's basic profile.";
66
+ readonly riskTint: "neutral";
67
+ };
68
+ readonly email: {
69
+ readonly label: "Read your email address";
70
+ readonly description: "Read the signed-in account's email address.";
71
+ readonly riskTint: "neutral";
72
+ };
73
+ readonly offline_access: {
74
+ readonly label: "Stay connected";
75
+ readonly description: "Refresh access without another interactive sign-in.";
76
+ readonly riskTint: "warning";
77
+ };
78
+ readonly "teams:read": {
79
+ readonly label: "Read your teams";
80
+ readonly description: "Read the teams the account belongs to.";
81
+ readonly riskTint: "neutral";
82
+ };
83
+ readonly "teams:create": {
84
+ readonly label: "Create teams";
85
+ readonly description: "Create teams.";
86
+ readonly riskTint: "warning";
87
+ };
88
+ readonly "spaces:read": {
89
+ readonly label: "Read your sites";
90
+ readonly description: "Read spaces, versions, and build status.";
91
+ readonly riskTint: "neutral";
92
+ };
93
+ readonly "spaces:write": {
94
+ readonly label: "Create and update your sites";
95
+ readonly description: "Create and update spaces and their settings.";
96
+ readonly riskTint: "warning";
97
+ };
98
+ readonly "spaces:rename": {
99
+ readonly label: "Rename your sites";
100
+ readonly description: "Rename space slugs and managed addresses.";
101
+ readonly riskTint: "warning";
102
+ };
103
+ readonly "publish:write": {
104
+ readonly label: "Publish and manage versions";
105
+ readonly description: "Publish new immutable versions.";
106
+ readonly riskTint: "warning";
107
+ };
108
+ readonly "spaces:publish": {
109
+ readonly label: "Publish new versions of your sites";
110
+ readonly description: "Publish a version to an existing space.";
111
+ readonly riskTint: "warning";
112
+ };
113
+ readonly "builds:trigger": {
114
+ readonly label: "Start builds";
115
+ readonly description: "Start a build for an existing version.";
116
+ readonly riskTint: "warning";
117
+ };
118
+ readonly "domains:read": {
119
+ readonly label: "Read your domains";
120
+ readonly description: "Read domain inventory and DNS diagnostics.";
121
+ readonly riskTint: "neutral";
122
+ };
123
+ readonly "domains:write": {
124
+ readonly label: "Manage domains and DNS";
125
+ readonly description: "Attach, verify, and mutate domains and DNS records.";
126
+ readonly riskTint: "critical";
127
+ };
128
+ };
129
+ export declare function oauthScopeCopy(scope: string): OAuthScopeCopy;
28
130
  export declare const OAUTH_RESOURCE_DEFINITIONS: {
29
131
  readonly api: {
30
132
  readonly key: "api";
@@ -36,14 +138,14 @@ export declare const OAUTH_RESOURCE_DEFINITIONS: {
36
138
  readonly key: "mcp";
37
139
  readonly name: "Spacefast MCP";
38
140
  readonly accessTokenTtlSeconds: number;
39
- readonly allowedScopes: readonly ["mcp:tools", "teams:read", "teams:create", "spaces:read", "spaces:write", "spaces:rename", "publish:write", "domains:read", "domains:write", "offline_access"];
141
+ readonly allowedScopes: readonly ["teams:read", "teams:create", "spaces:read", "spaces:write", "spaces:rename", "publish:write", "domains:read", "domains:write", "offline_access"];
40
142
  };
41
143
  };
42
144
  /** Resource identifier for the public API: `https://api.<domain>/v1`. */
43
145
  export declare function oauthApiResourceUrl(apiOrigin: string | URL): string;
44
146
  /**
45
147
  * Resource identifier for hosted MCP: the mcp origin itself, in RFC 8707
46
- * canonical form (lowercase scheme/host, no trailing slash) this is the
148
+ * canonical form (lowercase scheme/host, no trailing slash). This is the
47
149
  * exact string MCP clients send as the `resource` parameter.
48
150
  */
49
151
  export declare function oauthMcpResourceUrl(mcpOrigin: string | URL): string;
@@ -51,7 +153,7 @@ export declare function normalizeOAuthResourceIdentifier(resource: string): stri
51
153
  /**
52
154
  * Derive the mcp origin from a configured api origin (`api.X` → `mcp.X`).
53
155
  * Returns null when the api host doesn't follow the `api.` convention
54
- * (loopback dev, docker test hosts) callers fall back to the api origin.
156
+ * (loopback dev, docker test hosts). Callers fall back to the api origin.
55
157
  */
56
158
  export declare function oauthMcpOriginFromApiOrigin(apiOrigin: string | URL): string | null;
57
159
  /**
@@ -2,7 +2,12 @@ export const OAUTH_AUTHORIZATION_SERVER_PATH = "/v1/auth";
2
2
  /** The API resource is a path on the api origin; the MCP resource is the whole
3
3
  * mcp origin (`https://mcp.<domain>`), so it has no path entry here. */
4
4
  export const OAUTH_API_RESOURCE_PATH = "/v1";
5
- const OAUTH_SHARED_API_RESOURCE_SCOPES = [
5
+ // The scopes shared by the API resource, the MCP resource, and the interactive
6
+ // approval surface. `spaces:publish` and `builds:trigger` are deliberately NOT
7
+ // here: their actions are already covered by `publish:write`, so they exist
8
+ // only as granular API-resource scopes for clients (e.g. the WordPress plugin)
9
+ // that want to name them. Interactive approval and MCP speak this shared set.
10
+ export const OAUTH_SHARED_API_RESOURCE_SCOPES = [
6
11
  "teams:read",
7
12
  "teams:create",
8
13
  "spaces:read",
@@ -17,19 +22,18 @@ export const OAUTH_API_RESOURCE_SCOPES = [
17
22
  "spaces:publish",
18
23
  "builds:trigger",
19
24
  ];
20
- export const OAUTH_MCP_TOOL_SCOPE = "mcp:tools";
21
25
  export const OAUTH_OFFLINE_ACCESS_SCOPE = "offline_access";
22
- export const OAUTH_MCP_RESOURCE_SCOPES = [
23
- OAUTH_MCP_TOOL_SCOPE,
24
- ...OAUTH_SHARED_API_RESOURCE_SCOPES,
25
- ];
26
+ // Hosted MCP is pure transport over the API: a session represents exactly the
27
+ // shared API scopes, and each tool call is gated only by the underlying API
28
+ // scope it exercises. So the MCP resource's scopes are the shared API set.
29
+ export const OAUTH_MCP_RESOURCE_SCOPES = [...OAUTH_SHARED_API_RESOURCE_SCOPES];
26
30
  /**
27
31
  * A resource's `allowedScopes` is intersected with the requested scopes on every
28
- * token request, and the refresh token stores that intersection so a resource
32
+ * token request, and the refresh token stores that intersection, so a resource
29
33
  * that omits `offline_access` cannot mint a refresh token that survives
30
34
  * rotation, and its clients must re-consent in a browser every
31
35
  * `accessTokenTtlSeconds`. Kept separate from OAUTH_MCP_RESOURCE_SCOPES, which
32
- * is the list of capabilities the dashboard and CLI offer per agent account.
36
+ * is the list of capabilities the dashboard and CLI offer per machine OAuth client.
33
37
  */
34
38
  export const OAUTH_MCP_RESOURCE_ALLOWED_SCOPES = [
35
39
  ...OAUTH_MCP_RESOURCE_SCOPES,
@@ -52,8 +56,109 @@ export const OAUTH_PROVIDER_SCOPES = [
52
56
  "email",
53
57
  OAUTH_OFFLINE_ACCESS_SCOPE,
54
58
  ...OAUTH_API_RESOURCE_SCOPES,
55
- OAUTH_MCP_TOOL_SCOPE,
56
59
  ];
60
+ export const OAUTH_SCOPE_DESCRIPTIONS = {
61
+ openid: "Identify the signed-in account.",
62
+ profile: "Read the signed-in account's basic profile.",
63
+ email: "Read the signed-in account's email address.",
64
+ offline_access: "Refresh access without another interactive sign-in.",
65
+ "teams:read": "Read the teams the account belongs to.",
66
+ "teams:create": "Create teams.",
67
+ "spaces:read": "Read spaces, versions, and build status.",
68
+ "spaces:write": "Create and update spaces and their settings.",
69
+ "spaces:rename": "Rename space slugs and managed addresses.",
70
+ "publish:write": "Publish new immutable versions.",
71
+ "spaces:publish": "Publish a version to an existing space.",
72
+ "builds:trigger": "Start a build for an existing version.",
73
+ "domains:read": "Read domain inventory and DNS diagnostics.",
74
+ "domains:write": "Attach, verify, and mutate domains and DNS records.",
75
+ };
76
+ export const OAUTH_SCOPE_RISK_TINTS = ["neutral", "warning", "critical"];
77
+ /**
78
+ * Human-facing permission copy shared by every authorization surface. Keep raw
79
+ * OAuth scope ids in developer views only; consent, approvals, ledgers, CLI
80
+ * prompts, and email should all render this vocabulary.
81
+ */
82
+ export const OAUTH_SCOPE_COPY = {
83
+ openid: {
84
+ label: "Identify your account",
85
+ description: OAUTH_SCOPE_DESCRIPTIONS.openid,
86
+ riskTint: "neutral",
87
+ },
88
+ profile: {
89
+ label: "Read your profile",
90
+ description: OAUTH_SCOPE_DESCRIPTIONS.profile,
91
+ riskTint: "neutral",
92
+ },
93
+ email: {
94
+ label: "Read your email address",
95
+ description: OAUTH_SCOPE_DESCRIPTIONS.email,
96
+ riskTint: "neutral",
97
+ },
98
+ offline_access: {
99
+ label: "Stay connected",
100
+ description: OAUTH_SCOPE_DESCRIPTIONS.offline_access,
101
+ riskTint: "warning",
102
+ },
103
+ "teams:read": {
104
+ label: "Read your teams",
105
+ description: OAUTH_SCOPE_DESCRIPTIONS["teams:read"],
106
+ riskTint: "neutral",
107
+ },
108
+ "teams:create": {
109
+ label: "Create teams",
110
+ description: OAUTH_SCOPE_DESCRIPTIONS["teams:create"],
111
+ riskTint: "warning",
112
+ },
113
+ "spaces:read": {
114
+ label: "Read your sites",
115
+ description: OAUTH_SCOPE_DESCRIPTIONS["spaces:read"],
116
+ riskTint: "neutral",
117
+ },
118
+ "spaces:write": {
119
+ label: "Create and update your sites",
120
+ description: OAUTH_SCOPE_DESCRIPTIONS["spaces:write"],
121
+ riskTint: "warning",
122
+ },
123
+ "spaces:rename": {
124
+ label: "Rename your sites",
125
+ description: OAUTH_SCOPE_DESCRIPTIONS["spaces:rename"],
126
+ riskTint: "warning",
127
+ },
128
+ "publish:write": {
129
+ label: "Publish and manage versions",
130
+ description: OAUTH_SCOPE_DESCRIPTIONS["publish:write"],
131
+ riskTint: "warning",
132
+ },
133
+ "spaces:publish": {
134
+ label: "Publish new versions of your sites",
135
+ description: OAUTH_SCOPE_DESCRIPTIONS["spaces:publish"],
136
+ riskTint: "warning",
137
+ },
138
+ "builds:trigger": {
139
+ label: "Start builds",
140
+ description: OAUTH_SCOPE_DESCRIPTIONS["builds:trigger"],
141
+ riskTint: "warning",
142
+ },
143
+ "domains:read": {
144
+ label: "Read your domains",
145
+ description: OAUTH_SCOPE_DESCRIPTIONS["domains:read"],
146
+ riskTint: "neutral",
147
+ },
148
+ "domains:write": {
149
+ label: "Manage domains and DNS",
150
+ description: OAUTH_SCOPE_DESCRIPTIONS["domains:write"],
151
+ riskTint: "critical",
152
+ },
153
+ };
154
+ export function oauthScopeCopy(scope) {
155
+ const match = Object.entries(OAUTH_SCOPE_COPY).find(([knownScope]) => knownScope === scope);
156
+ return (match?.[1] ?? {
157
+ label: "Additional Spacefast access",
158
+ description: "Review this permission in Spacefast before you approve it.",
159
+ riskTint: "critical",
160
+ });
161
+ }
57
162
  export const OAUTH_RESOURCE_DEFINITIONS = {
58
163
  api: {
59
164
  key: "api",
@@ -74,7 +179,7 @@ export function oauthApiResourceUrl(apiOrigin) {
74
179
  }
75
180
  /**
76
181
  * Resource identifier for hosted MCP: the mcp origin itself, in RFC 8707
77
- * canonical form (lowercase scheme/host, no trailing slash) this is the
182
+ * canonical form (lowercase scheme/host, no trailing slash). This is the
78
183
  * exact string MCP clients send as the `resource` parameter.
79
184
  */
80
185
  export function oauthMcpResourceUrl(mcpOrigin) {
@@ -98,7 +203,7 @@ export function normalizeOAuthResourceIdentifier(resource) {
98
203
  /**
99
204
  * Derive the mcp origin from a configured api origin (`api.X` → `mcp.X`).
100
205
  * Returns null when the api host doesn't follow the `api.` convention
101
- * (loopback dev, docker test hosts) callers fall back to the api origin.
206
+ * (loopback dev, docker test hosts). Callers fall back to the api origin.
102
207
  */
103
208
  export function oauthMcpOriginFromApiOrigin(apiOrigin) {
104
209
  const url = new URL(apiOrigin);