@spacefast/common 0.0.5 → 0.0.6

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 (150) hide show
  1. package/dist/agents/connect-targets.d.ts +133 -0
  2. package/dist/agents/connect-targets.js +224 -0
  3. package/dist/brand.d.ts +1 -0
  4. package/dist/brand.js +5 -0
  5. package/dist/config/domains.d.ts +12 -6
  6. package/dist/config/domains.js +30 -38
  7. package/dist/contracts/access.d.ts +825 -125
  8. package/dist/contracts/access.js +771 -148
  9. package/dist/contracts/activity.d.ts +1 -1
  10. package/dist/contracts/activity.js +28 -2
  11. package/dist/contracts/annotations.d.ts +2 -4
  12. package/dist/contracts/api-keys.d.ts +3 -4
  13. package/dist/contracts/api-keys.js +9 -6
  14. package/dist/contracts/archives.d.ts +8 -2
  15. package/dist/contracts/archives.js +11 -4
  16. package/dist/contracts/billing.d.ts +0 -9
  17. package/dist/contracts/builds.d.ts +25 -21
  18. package/dist/contracts/builds.js +12 -0
  19. package/dist/contracts/common.d.ts +2 -0
  20. package/dist/contracts/common.js +4 -0
  21. package/dist/contracts/continuation.d.ts +0 -3
  22. package/dist/contracts/countries.d.ts +2 -0
  23. package/dist/contracts/countries.js +261 -0
  24. package/dist/contracts/deployments.d.ts +34 -34
  25. package/dist/contracts/device-auth.d.ts +4 -11
  26. package/dist/contracts/device-auth.js +4 -0
  27. package/dist/contracts/docs.d.ts +119 -0
  28. package/dist/contracts/docs.js +51 -0
  29. package/dist/contracts/domains.d.ts +96 -54
  30. package/dist/contracts/domains.js +26 -4
  31. package/dist/contracts/enums.d.ts +15 -16
  32. package/dist/contracts/enums.js +25 -14
  33. package/dist/contracts/error-code-meta.d.ts +72 -0
  34. package/dist/contracts/error-code-meta.js +96 -10
  35. package/dist/contracts/error-codes.d.ts +1 -1
  36. package/dist/contracts/error-codes.js +14 -0
  37. package/dist/contracts/events.d.ts +1 -1
  38. package/dist/contracts/features.d.ts +76 -6
  39. package/dist/contracts/features.js +178 -13
  40. package/dist/contracts/git.d.ts +2 -8
  41. package/dist/contracts/ids.d.ts +5 -0
  42. package/dist/contracts/ids.js +5 -0
  43. package/dist/contracts/mcp.d.ts +8 -10
  44. package/dist/contracts/me.js +1 -1
  45. package/dist/contracts/oauth-resources.d.ts +19 -8
  46. package/dist/contracts/oauth-resources.js +44 -13
  47. package/dist/contracts/platform.d.ts +0 -102
  48. package/dist/contracts/platform.js +0 -50
  49. package/dist/contracts/push-new.d.ts +4 -4
  50. package/dist/contracts/quotas.d.ts +2 -0
  51. package/dist/contracts/quotas.js +8 -0
  52. package/dist/contracts/repository-connections.d.ts +6 -8
  53. package/dist/contracts/resources.d.ts +97 -13
  54. package/dist/contracts/resources.js +26 -2
  55. package/dist/contracts/routes.d.ts +0 -2
  56. package/dist/contracts/runtime-api.d.ts +361 -39
  57. package/dist/contracts/runtime-api.js +275 -6
  58. package/dist/contracts/sites.d.ts +19 -2
  59. package/dist/contracts/sites.js +21 -0
  60. package/dist/contracts/space-config.d.ts +201 -2
  61. package/dist/contracts/space-config.js +135 -5
  62. package/dist/contracts/spaces.d.ts +364 -193
  63. package/dist/contracts/spaces.js +40 -8
  64. package/dist/contracts/superadmin-emails.d.ts +4 -2
  65. package/dist/contracts/superadmin-emails.js +8 -0
  66. package/dist/contracts/superadmin-queues.d.ts +26 -26
  67. package/dist/contracts/superadmin-spaces.d.ts +170 -42
  68. package/dist/contracts/superadmin.d.ts +6 -93
  69. package/dist/contracts/superadmin.js +6 -14
  70. package/dist/contracts/tags.d.ts +10 -9
  71. package/dist/contracts/tags.js +2 -1
  72. package/dist/contracts/teams.d.ts +21 -22
  73. package/dist/contracts/teams.js +0 -1
  74. package/dist/contracts/theme-json.d.ts +30 -0
  75. package/dist/contracts/theme-json.js +48 -0
  76. package/dist/contracts/variables.d.ts +0 -2
  77. package/dist/contracts/variables.js +0 -5
  78. package/dist/contracts/webhooks.d.ts +2 -0
  79. package/dist/contracts/webhooks.js +1 -1
  80. package/dist/contracts/zero.d.ts +5 -10
  81. package/dist/docs/agent-prose.d.ts +43 -3
  82. package/dist/docs/agent-prose.js +146 -7
  83. package/dist/docs/agent-setup.js +45 -13
  84. package/dist/docs/agent-solutions.d.ts +5 -5
  85. package/dist/docs/agent-solutions.js +2 -2
  86. package/dist/docs/catalog.d.ts +650 -0
  87. package/dist/docs/catalog.js +758 -0
  88. package/dist/docs/error-docs.d.ts +0 -2
  89. package/dist/docs/error-docs.js +77 -35
  90. package/dist/docs/index-build.d.ts +17 -0
  91. package/dist/docs/index-build.js +24 -0
  92. package/dist/docs/search.d.ts +54 -0
  93. package/dist/docs/search.js +96 -0
  94. package/dist/docs/skill-distribution.d.ts +5 -3
  95. package/dist/docs/skill-distribution.js +8 -8
  96. package/dist/utils/access-match.d.ts +39 -0
  97. package/dist/utils/access-match.js +296 -0
  98. package/dist/utils/auth-redirect.d.ts +3 -1
  99. package/dist/utils/auth-redirect.js +21 -1
  100. package/dist/utils/build-settings.d.ts +6 -0
  101. package/dist/utils/build-settings.js +429 -46
  102. package/dist/utils/claim-token.d.ts +8 -0
  103. package/dist/utils/claim-token.js +23 -2
  104. package/dist/utils/content-type.d.ts +1 -0
  105. package/dist/utils/content-type.js +1 -1
  106. package/dist/utils/credential-policy.d.ts +54 -0
  107. package/dist/utils/{access-policy.js → credential-policy.js} +28 -2
  108. package/dist/utils/gate-theme.d.ts +61 -0
  109. package/dist/utils/gate-theme.js +217 -0
  110. package/dist/utils/git-repository.d.ts +0 -1
  111. package/dist/utils/git-repository.js +0 -3
  112. package/dist/utils/id-hints.d.ts +8 -0
  113. package/dist/utils/id-hints.js +61 -0
  114. package/dist/utils/local-space-state.d.ts +91 -0
  115. package/dist/utils/local-space-state.js +251 -0
  116. package/dist/utils/oauth-signed-query.d.ts +8 -0
  117. package/dist/utils/oauth-signed-query.js +26 -0
  118. package/dist/utils/publish-detection.d.ts +0 -8
  119. package/dist/utils/publish-detection.js +0 -93
  120. package/dist/utils/publish-policy.d.ts +6 -5
  121. package/dist/utils/publish-policy.js +71 -7
  122. package/dist/utils/query-keys.d.ts +15 -4
  123. package/dist/utils/query-keys.js +27 -4
  124. package/dist/utils/runtime-paths.d.ts +0 -1
  125. package/dist/utils/runtime-paths.js +0 -1
  126. package/dist/utils/runtime-upload-batch.d.ts +18 -0
  127. package/dist/utils/runtime-upload-batch.js +90 -0
  128. package/dist/utils/runtime-upload.d.ts +2 -0
  129. package/dist/utils/runtime-upload.js +5 -0
  130. package/dist/utils/space-config.d.ts +4 -0
  131. package/dist/utils/space-config.js +10 -1
  132. package/dist/utils/space-theme.d.ts +2 -0
  133. package/dist/utils/space-theme.js +9 -0
  134. package/dist/utils/static-runtime-policy.d.ts +0 -21
  135. package/dist/utils/static-runtime-policy.js +19 -103
  136. package/dist/utils/upload-session.d.ts +1 -1
  137. package/dist/utils/wpcom-auth-redirects.d.ts +32 -2
  138. package/dist/utils/wpcom-auth-redirects.js +26 -10
  139. package/dist/vocabulary.d.ts +130 -30
  140. package/dist/vocabulary.js +77 -36
  141. package/package.json +16 -1
  142. package/dist/contracts/account.d.ts +0 -28
  143. package/dist/contracts/account.js +0 -54
  144. package/dist/contracts/intercom.d.ts +0 -6
  145. package/dist/contracts/intercom.js +0 -5
  146. package/dist/contracts/telemetry.d.ts +0 -2
  147. package/dist/contracts/telemetry.js +0 -1
  148. package/dist/utils/access-policy.d.ts +0 -39
  149. package/dist/utils/error-display.d.ts +0 -7
  150. package/dist/utils/error-display.js +0 -42
@@ -11,18 +11,31 @@ export const FEATURE_KEYS = [
11
11
  "domains.search",
12
12
  "domains.registration",
13
13
  "domains.dns_management",
14
+ "domains.wpcom_dns",
15
+ "domains.domain_connect",
14
16
  "domains.proxy_bindings",
15
17
  "annotations.preview_loader",
16
18
  "annotations.comments",
17
19
  "annotations.anonymous_reviewers",
18
20
  "annotations.cli",
19
21
  "annotations.notices",
20
- "annotations.spacefast_token",
21
22
  "annotations.published_comments",
22
23
  "sites.dedicated_runtime",
23
24
  "shelf",
24
25
  "tags",
25
26
  "zero",
27
+ // Access product phases (access-plan §7, X-42): every phase ships behind its
28
+ // own dot-namespaced key, born internal-only. The lifecycle registry
29
+ // (stage/docsSlug per internal-docs/feature-lifecycle-plan.html) is not
30
+ // implemented yet — these use the existing FeatureDefinition shape with
31
+ // internal-only defaults until it lands.
32
+ "access.share_links",
33
+ "access.invites",
34
+ "access.firewall_card",
35
+ "access.sso_connections",
36
+ "access.byo_issuers",
37
+ "access.views_panel",
38
+ "pages.white_label",
26
39
  ];
27
40
  export const featureKeySchema = z.enum(FEATURE_KEYS).describe("Feature flag key.");
28
41
  // Feature override states (env `SPACEFAST_FLAG_*` and the feature_overrides
@@ -66,6 +79,27 @@ export const planLimitsSchema = z
66
79
  // Queryable analytics history window. Storage retains rollups for everyone
67
80
  // (env-bounded); this only clamps how far back the analytics API serves.
68
81
  analyticsRetentionDays: planLimitValueSchema,
82
+ // Access-surface abuse ceilings (access-plan §5.1, X-40): generous by
83
+ // default, enterprise unlimited — never upsell levers. Per-plan tightening
84
+ // (if ever) happens here, never as constants in route code.
85
+ // Cloud-lane rules per space (incl. TTL'd blocks; managed blocks excluded
86
+ // from the count).
87
+ cloudRulesPerSpace: planLimitValueSchema,
88
+ // Active (non-revoked, non-expired) share links per space.
89
+ shareLinksPerSpace: planLimitValueSchema,
90
+ // Active invites per space (§5.3 — enforced when invites land).
91
+ invitesPerSpace: planLimitValueSchema,
92
+ // Invite emails per space / per account, daily (§5.3 abuse posture).
93
+ inviteEmailsPerSpaceDaily: planLimitValueSchema,
94
+ inviteEmailsPerAccountDaily: planLimitValueSchema,
95
+ // Pending access requests per space (§5.4).
96
+ pendingAccessRequestsPerSpace: planLimitValueSchema,
97
+ // Service tokens per team (§5.5).
98
+ serviceTokensPerTeam: planLimitValueSchema,
99
+ // OIDC + external issuer connections per team (§6).
100
+ connectionsPerTeam: planLimitValueSchema,
101
+ // Team-default rules (X-24).
102
+ teamDefaultRules: planLimitValueSchema,
69
103
  })
70
104
  .describe("Named plan limit table.");
71
105
  // Resolved team entitlements: plan limits after add-on grants plus the
@@ -79,6 +113,16 @@ export const teamEntitlementsSchema = z
79
113
  .boolean()
80
114
  .describe("Whether `_headers` Basic-Auth rules compile on this plan."),
81
115
  externalProxy: z.boolean().describe("Whether external proxy upstreams compile on this plan."),
116
+ dedicatedRuntime: z.boolean().describe("Whether the team can use dedicated runtime sites."),
117
+ pagesWhiteLabel: z
118
+ .boolean()
119
+ .describe("Whether the pages.white_label tier compiles (Spacefast branding removed from gate pages)."),
120
+ pagesCustomHtml: z
121
+ .boolean()
122
+ .describe("Whether custom gate-page HTML compiles (401.html/403.html slot overrides and .spacefast/templates/layout.html chrome, access-plan §8/§9 paid tier 1)."),
123
+ pagesAdvancedTheming: z
124
+ .boolean()
125
+ .describe("Whether the sf.theme.jsonc escape-hatch theme tier compiles (access-plan §8/§9 paid tier 1); theme.json and pages.theme basics stay free."),
82
126
  runtimePhpWorkers: z.number().int().describe("PHP workers per serving site."),
83
127
  analyticsHourlyGranularity: z
84
128
  .boolean()
@@ -120,6 +164,29 @@ const UNLIMITED_LIMITS = {
120
164
  buildAccessLogRetentionHours: "unlimited",
121
165
  buildsDeploysMonthly: "unlimited",
122
166
  analyticsRetentionDays: "unlimited",
167
+ cloudRulesPerSpace: "unlimited",
168
+ shareLinksPerSpace: "unlimited",
169
+ invitesPerSpace: "unlimited",
170
+ inviteEmailsPerSpaceDaily: "unlimited",
171
+ inviteEmailsPerAccountDaily: "unlimited",
172
+ pendingAccessRequestsPerSpace: "unlimited",
173
+ serviceTokensPerTeam: "unlimited",
174
+ connectionsPerTeam: "unlimited",
175
+ teamDefaultRules: "unlimited",
176
+ };
177
+ // The §5.1 access abuse-ceiling table (X-40): applied verbatim to every
178
+ // self-serve plan; enterprise/internal stay unlimited. These sit far above
179
+ // honest use — they are abuse ceilings, not upsell levers.
180
+ const ACCESS_QUOTA_DEFAULTS = {
181
+ cloudRulesPerSpace: 200,
182
+ shareLinksPerSpace: 100,
183
+ invitesPerSpace: 500,
184
+ inviteEmailsPerSpaceDaily: 200,
185
+ inviteEmailsPerAccountDaily: 500,
186
+ pendingAccessRequestsPerSpace: 100,
187
+ serviceTokensPerTeam: 50,
188
+ connectionsPerTeam: 10,
189
+ teamDefaultRules: 50,
123
190
  };
124
191
  export const PLAN_DEFINITIONS = {
125
192
  free: {
@@ -130,7 +197,7 @@ export const PLAN_DEFINITIONS = {
130
197
  storageBytes: 5 * GB,
131
198
  teamMembers: 3,
132
199
  subTeams: 0,
133
- externalDomainGroups: 1,
200
+ externalDomainGroups: 3,
134
201
  publicImmutableVersionWindowDays: 7,
135
202
  versionRetentionDays: 30, // included full-retention window (charter A3)
136
203
  versionGatedKeepDays: 183, // kept gated ~6 months from readyAt, then deleted
@@ -142,9 +209,14 @@ export const PLAN_DEFINITIONS = {
142
209
  buildAccessLogRetentionHours: 48,
143
210
  buildsDeploysMonthly: 100,
144
211
  analyticsRetentionDays: 30,
212
+ ...ACCESS_QUOTA_DEFAULTS,
145
213
  },
146
214
  headersBasicAuth: false,
147
215
  externalProxy: false,
216
+ dedicatedRuntime: false,
217
+ pagesWhiteLabel: false,
218
+ pagesCustomHtml: false,
219
+ pagesAdvancedTheming: false,
148
220
  runtimePhpWorkers: 2,
149
221
  analyticsHourlyGranularity: false,
150
222
  },
@@ -164,9 +236,14 @@ export const PLAN_DEFINITIONS = {
164
236
  buildAccessLogRetentionHours: MONTH_HOURS,
165
237
  buildsDeploysMonthly: 1000,
166
238
  analyticsRetentionDays: 365,
239
+ ...ACCESS_QUOTA_DEFAULTS,
167
240
  },
168
241
  headersBasicAuth: true,
169
242
  externalProxy: true,
243
+ dedicatedRuntime: false,
244
+ pagesWhiteLabel: false,
245
+ pagesCustomHtml: true,
246
+ pagesAdvancedTheming: true,
170
247
  runtimePhpWorkers: 4,
171
248
  analyticsHourlyGranularity: true,
172
249
  },
@@ -182,9 +259,14 @@ export const PLAN_DEFINITIONS = {
182
259
  // "unlimited" limits, so this must stay numeric.
183
260
  teamMembers: 15,
184
261
  subTeams: 0,
262
+ ...ACCESS_QUOTA_DEFAULTS,
185
263
  },
186
264
  headersBasicAuth: true,
187
265
  externalProxy: true,
266
+ dedicatedRuntime: false,
267
+ pagesWhiteLabel: true,
268
+ pagesCustomHtml: true,
269
+ pagesAdvancedTheming: true,
188
270
  runtimePhpWorkers: 4,
189
271
  analyticsHourlyGranularity: true,
190
272
  },
@@ -196,6 +278,10 @@ export const PLAN_DEFINITIONS = {
196
278
  limits: { ...UNLIMITED_LIMITS },
197
279
  headersBasicAuth: true,
198
280
  externalProxy: true,
281
+ dedicatedRuntime: true,
282
+ pagesWhiteLabel: true,
283
+ pagesCustomHtml: true,
284
+ pagesAdvancedTheming: true,
199
285
  runtimePhpWorkers: 4,
200
286
  analyticsHourlyGranularity: true,
201
287
  },
@@ -206,6 +292,10 @@ export const PLAN_DEFINITIONS = {
206
292
  limits: { ...UNLIMITED_LIMITS },
207
293
  headersBasicAuth: true,
208
294
  externalProxy: true,
295
+ dedicatedRuntime: true,
296
+ pagesWhiteLabel: true,
297
+ pagesCustomHtml: true,
298
+ pagesAdvancedTheming: true,
209
299
  runtimePhpWorkers: 4,
210
300
  analyticsHourlyGranularity: true,
211
301
  },
@@ -264,6 +354,22 @@ export const FEATURE_DEFINITIONS = {
264
354
  enabledForA8c: true,
265
355
  planDefaults: {},
266
356
  },
357
+ "domains.wpcom_dns": {
358
+ key: "domains.wpcom_dns",
359
+ name: "WordPress.com DNS automation",
360
+ description: "Manage a domain's DNS through the owner's WordPress.com account.",
361
+ defaultEnabled: false,
362
+ enabledForA8c: true,
363
+ planDefaults: {},
364
+ },
365
+ "domains.domain_connect": {
366
+ key: "domains.domain_connect",
367
+ name: "Domain Connect",
368
+ description: "One-click DNS setup at providers that implement Domain Connect.",
369
+ defaultEnabled: false,
370
+ enabledForA8c: true,
371
+ planDefaults: {},
372
+ },
267
373
  "domains.proxy_bindings": {
268
374
  key: "domains.proxy_bindings",
269
375
  name: "Domain proxy bindings",
@@ -317,23 +423,14 @@ export const FEATURE_DEFINITIONS = {
317
423
  enabledForA8c: true,
318
424
  planDefaults: {},
319
425
  },
320
- "annotations.spacefast_token": {
321
- key: "annotations.spacefast_token",
322
- name: "Spacefast-native annotation tokens",
323
- description: "Mints collaboration tokens as Spacefast EdDSA access tokens (dedicated Cast kid) instead of the legacy HS256 path; the Spacefast-native auth cutover.",
324
- defaultEnabled: false,
325
- enabledInDevelopment: true,
326
- enabledForA8c: true,
327
- planDefaults: {},
328
- },
329
426
  "annotations.published_comments": {
330
427
  key: "annotations.published_comments",
331
428
  name: "Published host annotation comments",
332
429
  description: "Allows the annotation overlay to mount comments on a space's live/published host, not just immutable preview URLs.",
333
430
  defaultEnabled: false,
334
431
  // ON in local dev so the Spacefast-native published path is exercised end-to-end
335
- // alongside annotations.comments + annotations.spacefast_token (which already
336
- // default on in dev). Production stays gated behind the per-space toggle.
432
+ // alongside annotations.comments (which already defaults on in dev).
433
+ // Production stays gated behind the per-space toggle.
337
434
  enabledInDevelopment: true,
338
435
  enabledForA8c: true,
339
436
  planDefaults: {},
@@ -373,6 +470,74 @@ export const FEATURE_DEFINITIONS = {
373
470
  enabledForA8c: true,
374
471
  planDefaults: {},
375
472
  },
473
+ // Access product phases (access-plan §7, X-42). Shipped surfaces default on;
474
+ // later-stage identity-provider pieces stay override-gated until they are
475
+ // ready for the main product path. When the lifecycle registry (stage +
476
+ // docsSlug, internal-docs/feature-lifecycle-plan.html) lands, these migrate
477
+ // onto it.
478
+ "access.share_links": {
479
+ key: "access.share_links",
480
+ name: "Share links",
481
+ description: "Enables the Share modal's sharing projection, the general-access selector, and share-link create/copy/revoke (access-plan §5.1/§5.2).",
482
+ defaultEnabled: true,
483
+ enabledInDevelopment: true,
484
+ enabledForA8c: true,
485
+ planDefaults: {},
486
+ },
487
+ "access.invites": {
488
+ key: "access.invites",
489
+ name: "Space invites",
490
+ description: "Enables account-less viewer invites with magic-link accept and the request-access loop (access-plan §5.3/§5.4).",
491
+ defaultEnabled: false,
492
+ enabledInDevelopment: true,
493
+ enabledForA8c: true,
494
+ planDefaults: {},
495
+ },
496
+ "access.firewall_card": {
497
+ key: "access.firewall_card",
498
+ name: "Firewall card",
499
+ description: "Enables the managed firewall block card (country/IP/bot rules) in space access settings (access-plan §5.6).",
500
+ defaultEnabled: true,
501
+ enabledInDevelopment: true,
502
+ enabledForA8c: true,
503
+ planDefaults: {},
504
+ },
505
+ "access.sso_connections": {
506
+ key: "access.sso_connections",
507
+ name: "Company SSO connections",
508
+ description: "Enables team-level OIDC connections minted at the authorize endpoint (access-plan §6.2, X-18).",
509
+ defaultEnabled: false,
510
+ enabledInDevelopment: true,
511
+ enabledForA8c: true,
512
+ planDefaults: {},
513
+ },
514
+ "access.byo_issuers": {
515
+ key: "access.byo_issuers",
516
+ name: "Bring-your-own issuers",
517
+ description: "Enables owner-held external token issuers with ext:-namespace binding (access-plan §6.3, X-19).",
518
+ defaultEnabled: false,
519
+ enabledInDevelopment: true,
520
+ enabledForA8c: true,
521
+ planDefaults: {},
522
+ },
523
+ "access.views_panel": {
524
+ key: "access.views_panel",
525
+ name: "Views panel",
526
+ description: "Enables the identified who-viewed-what panel riding the analytics tiers (access-plan §5.6b, X-28).",
527
+ defaultEnabled: true,
528
+ enabledInDevelopment: true,
529
+ enabledForA8c: true,
530
+ planDefaults: {},
531
+ },
532
+ "pages.white_label": {
533
+ key: "pages.white_label",
534
+ name: "White-label platform pages",
535
+ description: "Removes Spacefast branding from the challenge/deny page tier between theme tokens and full custom pages (access-plan §5.7, X-16).",
536
+ defaultEnabled: false,
537
+ enabledInDevelopment: true,
538
+ enabledForA8c: true,
539
+ planDefaults: {},
540
+ },
376
541
  };
377
542
  export const featureStateSourceSchema = z
378
543
  .enum(["kill_switch", "env", "override", "default"])
@@ -2,13 +2,13 @@ import { z } from "zod";
2
2
  export declare const buildTargetValues: readonly ["production", "preview"];
3
3
  export declare const buildTriggerValues: readonly ["manual", "push", "pull_request", "retry"];
4
4
  export declare const buildTarget: z.ZodEnum<{
5
- preview: "preview";
6
5
  production: "production";
6
+ preview: "preview";
7
7
  }>;
8
8
  export declare const buildTrigger: z.ZodEnum<{
9
9
  push: "push";
10
- pull_request: "pull_request";
11
10
  manual: "manual";
11
+ pull_request: "pull_request";
12
12
  retry: "retry";
13
13
  }>;
14
14
  export declare const buildEnvironmentScopeValues: readonly ["runtime", "build", "build:production", "build:preview"];
@@ -279,10 +279,4 @@ export declare const githubRepositorySchema: z.ZodObject<{
279
279
  private: z.ZodBoolean;
280
280
  }, z.core.$strip>;
281
281
  export type BuildTarget = z.infer<typeof buildTarget>;
282
- export type BuildTrigger = z.infer<typeof buildTrigger>;
283
- export type BuildEnvironmentScope = z.infer<typeof buildEnvironmentScope>;
284
282
  export type GitBuildSettings = z.infer<typeof gitBuildSettingsSchema>;
285
- export type GitConnection = z.infer<typeof gitConnectionSchema>;
286
- export type GitConnectionCreate = z.infer<typeof gitConnectionCreateSchema>;
287
- export type GitConnectionPatch = z.infer<typeof gitConnectionPatchSchema>;
288
- export type GitConnectionAnalyzeResponse = z.infer<typeof gitConnectionAnalyzeResponseSchema>;
@@ -26,6 +26,11 @@ export declare const ID_PREFIXES: {
26
26
  readonly tga: "TagRuntimeArtifact";
27
27
  readonly tgp: "TagPreviewSession";
28
28
  readonly bhk: "BuildHook";
29
+ readonly lnk: "ShareLink";
30
+ readonly sin: "SpaceInvite";
31
+ readonly arq: "AccessRequest";
32
+ readonly stk: "ServiceToken";
33
+ readonly acn: "AccessConnection";
29
34
  };
30
35
  export type IdPrefix = keyof typeof ID_PREFIXES;
31
36
  /** Any registered public resource id, e.g. `spc_…` or `ver_…`. */
@@ -34,6 +34,11 @@ export const ID_PREFIXES = {
34
34
  tgp: "TagPreviewSession",
35
35
  // Reserved for the deferred build-hook surface; never minted yet.
36
36
  bhk: "BuildHook",
37
+ lnk: "ShareLink",
38
+ sin: "SpaceInvite",
39
+ arq: "AccessRequest",
40
+ stk: "ServiceToken",
41
+ acn: "AccessConnection",
37
42
  };
38
43
  // The main Stattic tenant every self-serve team/user/resource lives under. A
39
44
  // well-known CONSTANT, never configuration: grammatically a normal tenant id with
@@ -51,8 +51,8 @@ export declare const hostedMcpApprovalSchema: z.ZodObject<{
51
51
  status: z.ZodEnum<{
52
52
  expired: "expired";
53
53
  pending: "pending";
54
- denied: "denied";
55
54
  approved: "approved";
55
+ denied: "denied";
56
56
  consumed: "consumed";
57
57
  }>;
58
58
  decision: z.ZodNullable<z.ZodEnum<{
@@ -167,8 +167,8 @@ export declare const hostedMcpExecutionRunSchema: z.ZodObject<{
167
167
  export declare const hostedMcpToolPolicySchema: z.ZodObject<{
168
168
  tool: z.ZodString;
169
169
  runtime: z.ZodEnum<{
170
- hosted: "hosted";
171
170
  "on-device": "on-device";
171
+ hosted: "hosted";
172
172
  both: "both";
173
173
  }>;
174
174
  category: z.ZodString;
@@ -191,8 +191,8 @@ export declare const hostedMcpPolicyDefaultsSchema: z.ZodObject<{
191
191
  toolPolicies: z.ZodArray<z.ZodObject<{
192
192
  tool: z.ZodString;
193
193
  runtime: z.ZodEnum<{
194
- hosted: "hosted";
195
194
  "on-device": "on-device";
195
+ hosted: "hosted";
196
196
  both: "both";
197
197
  }>;
198
198
  category: z.ZodString;
@@ -257,8 +257,8 @@ export declare const hostedMcpDashboardSchema: z.ZodObject<{
257
257
  toolPolicies: z.ZodArray<z.ZodObject<{
258
258
  tool: z.ZodString;
259
259
  runtime: z.ZodEnum<{
260
- hosted: "hosted";
261
260
  "on-device": "on-device";
261
+ hosted: "hosted";
262
262
  both: "both";
263
263
  }>;
264
264
  category: z.ZodString;
@@ -314,8 +314,8 @@ export declare const hostedMcpDashboardSchema: z.ZodObject<{
314
314
  status: z.ZodEnum<{
315
315
  expired: "expired";
316
316
  pending: "pending";
317
- denied: "denied";
318
317
  approved: "approved";
318
+ denied: "denied";
319
319
  consumed: "consumed";
320
320
  }>;
321
321
  decision: z.ZodNullable<z.ZodEnum<{
@@ -422,8 +422,8 @@ export declare const hostedMcpDashboardResponseSchema: z.ZodObject<{
422
422
  toolPolicies: z.ZodArray<z.ZodObject<{
423
423
  tool: z.ZodString;
424
424
  runtime: z.ZodEnum<{
425
- hosted: "hosted";
426
425
  "on-device": "on-device";
426
+ hosted: "hosted";
427
427
  both: "both";
428
428
  }>;
429
429
  category: z.ZodString;
@@ -479,8 +479,8 @@ export declare const hostedMcpDashboardResponseSchema: z.ZodObject<{
479
479
  status: z.ZodEnum<{
480
480
  expired: "expired";
481
481
  pending: "pending";
482
- denied: "denied";
483
482
  approved: "approved";
483
+ denied: "denied";
484
484
  consumed: "consumed";
485
485
  }>;
486
486
  decision: z.ZodNullable<z.ZodEnum<{
@@ -608,8 +608,8 @@ export declare const hostedMcpApprovalResponseSchema: z.ZodObject<{
608
608
  status: z.ZodEnum<{
609
609
  expired: "expired";
610
610
  pending: "pending";
611
- denied: "denied";
612
611
  approved: "approved";
612
+ denied: "denied";
613
613
  consumed: "consumed";
614
614
  }>;
615
615
  decision: z.ZodNullable<z.ZodEnum<{
@@ -776,9 +776,7 @@ export declare const hostedMcpExecutionRunResponseSchema: z.ZodObject<{
776
776
  }, z.core.$strip>;
777
777
  }, z.core.$strip>;
778
778
  export type HostedMcpSession = z.infer<typeof hostedMcpSessionSchema>;
779
- export type HostedMcpWorkspaceSummary = z.infer<typeof hostedMcpWorkspaceSummarySchema>;
780
779
  export type HostedMcpApproval = z.infer<typeof hostedMcpApprovalSchema>;
781
- export type HostedMcpApprovalDecisionRequest = z.infer<typeof hostedMcpApprovalDecisionRequestSchema>;
782
780
  export type HostedMcpSessionEvent = z.infer<typeof hostedMcpSessionEventSchema>;
783
781
  export type HostedMcpExecutionRun = z.infer<typeof hostedMcpExecutionRunSchema>;
784
782
  export type HostedMcpExecutionStep = z.infer<typeof hostedMcpExecutionStepSchema>;
@@ -97,7 +97,7 @@ export const meResponseSchema = z.object({
97
97
  slug: z.string().nullable().describe("Team slug."),
98
98
  source: betaEligibleTeamSourceSchema,
99
99
  }))
100
- .describe("Teams the user may join via the picker (pending invitation or auto-enroll match)."),
100
+ .describe("Teams the user may join via the picker (pending invitation, auto-enroll match, or Automattician access)."),
101
101
  })
102
102
  .describe("Private-beta state. Dashboards key the blocked screen on gateEnabled && !enrolled, " +
103
103
  "never on !enrolled alone — else launch-day flag-off would still block people."),
@@ -1,9 +1,8 @@
1
1
  export declare const OAUTH_AUTHORIZATION_SERVER_PATH: "/v1/auth";
2
- export declare const OAUTH_RESOURCE_PATHS: {
3
- readonly api: "/v1";
4
- readonly mcp: "/mcp";
5
- };
6
- export type OAuthResourceKey = keyof typeof OAUTH_RESOURCE_PATHS;
2
+ /** The API resource is a path on the api origin; the MCP resource is the whole
3
+ * mcp origin (`https://mcp.<domain>`), so it has no path entry here. */
4
+ export declare const OAUTH_API_RESOURCE_PATH: "/v1";
5
+ export type OAuthResourceKey = "api" | "mcp";
7
6
  export declare const OAUTH_API_RESOURCE_SCOPES: readonly ["teams:read", "spaces:read", "spaces:write", "publish:write", "domains:read", "domains:write"];
8
7
  export declare const OAUTH_MCP_TOOL_SCOPE: "mcp:tools";
9
8
  export declare const OAUTH_MCP_RESOURCE_SCOPES: readonly ["mcp:tools", "teams:read", "spaces:read", "spaces:write", "publish:write", "domains:read", "domains:write"];
@@ -11,20 +10,32 @@ export declare const OAUTH_PROVIDER_SCOPES: readonly ["openid", "profile", "emai
11
10
  export declare const OAUTH_RESOURCE_DEFINITIONS: {
12
11
  readonly api: {
13
12
  readonly key: "api";
14
- readonly path: "/v1";
15
13
  readonly name: "Spacefast API";
16
14
  readonly accessTokenTtlSeconds: number;
17
15
  readonly allowedScopes: readonly ["teams:read", "spaces:read", "spaces:write", "publish:write", "domains:read", "domains:write"];
18
16
  };
19
17
  readonly mcp: {
20
18
  readonly key: "mcp";
21
- readonly path: "/mcp";
22
19
  readonly name: "Spacefast MCP";
23
20
  readonly accessTokenTtlSeconds: number;
24
21
  readonly allowedScopes: readonly ["mcp:tools", "teams:read", "spaces:read", "spaces:write", "publish:write", "domains:read", "domains:write"];
25
22
  };
26
23
  };
27
- export declare function oauthResourceUrl(origin: string | URL, resource: OAuthResourceKey): string;
24
+ /** Resource identifier for the public API: `https://api.<domain>/v1`. */
25
+ export declare function oauthApiResourceUrl(apiOrigin: string | URL): string;
26
+ /**
27
+ * Resource identifier for hosted MCP: the mcp origin itself, in RFC 8707
28
+ * canonical form (lowercase scheme/host, no trailing slash) — this is the
29
+ * exact string MCP clients send as the `resource` parameter.
30
+ */
31
+ export declare function oauthMcpResourceUrl(mcpOrigin: string | URL): string;
32
+ export declare function normalizeOAuthResourceIdentifier(resource: string): string;
33
+ /**
34
+ * Derive the mcp origin from a configured api origin (`api.X` → `mcp.X`).
35
+ * Returns null when the api host doesn't follow the `api.` convention
36
+ * (loopback dev, docker test hosts) — callers fall back to the api origin.
37
+ */
38
+ export declare function oauthMcpOriginFromApiOrigin(apiOrigin: string | URL): string | null;
28
39
  export declare function oauthAuthorizationServerUrl(origin: string | URL): string;
29
40
  export declare function oauthTokenEndpointUrl(origin: string | URL): string;
30
41
  export declare function oauthResourceKeyForPathname(pathname: string): OAuthResourceKey | null;
@@ -1,8 +1,7 @@
1
1
  export const OAUTH_AUTHORIZATION_SERVER_PATH = "/v1/auth";
2
- export const OAUTH_RESOURCE_PATHS = {
3
- api: "/v1",
4
- mcp: "/mcp",
5
- };
2
+ /** The API resource is a path on the api origin; the MCP resource is the whole
3
+ * mcp origin (`https://mcp.<domain>`), so it has no path entry here. */
4
+ export const OAUTH_API_RESOURCE_PATH = "/v1";
6
5
  export const OAUTH_API_RESOURCE_SCOPES = [
7
6
  "teams:read",
8
7
  "spaces:read",
@@ -27,21 +26,56 @@ export const OAUTH_PROVIDER_SCOPES = [
27
26
  export const OAUTH_RESOURCE_DEFINITIONS = {
28
27
  api: {
29
28
  key: "api",
30
- path: OAUTH_RESOURCE_PATHS.api,
31
29
  name: "Spacefast API",
32
30
  accessTokenTtlSeconds: 15 * 60,
33
31
  allowedScopes: OAUTH_API_RESOURCE_SCOPES,
34
32
  },
35
33
  mcp: {
36
34
  key: "mcp",
37
- path: OAUTH_RESOURCE_PATHS.mcp,
38
35
  name: "Spacefast MCP",
39
36
  accessTokenTtlSeconds: 15 * 60,
40
37
  allowedScopes: OAUTH_MCP_RESOURCE_SCOPES,
41
38
  },
42
39
  };
43
- export function oauthResourceUrl(origin, resource) {
44
- return new URL(OAUTH_RESOURCE_PATHS[resource], origin).toString();
40
+ /** Resource identifier for the public API: `https://api.<domain>/v1`. */
41
+ export function oauthApiResourceUrl(apiOrigin) {
42
+ return new URL(OAUTH_API_RESOURCE_PATH, apiOrigin).toString();
43
+ }
44
+ /**
45
+ * Resource identifier for hosted MCP: the mcp origin itself, in RFC 8707
46
+ * canonical form (lowercase scheme/host, no trailing slash) — this is the
47
+ * exact string MCP clients send as the `resource` parameter.
48
+ */
49
+ export function oauthMcpResourceUrl(mcpOrigin) {
50
+ return new URL(mcpOrigin).origin;
51
+ }
52
+ export function normalizeOAuthResourceIdentifier(resource) {
53
+ const trimmed = resource.trim();
54
+ if (!trimmed) {
55
+ return trimmed;
56
+ }
57
+ const url = new URL(trimmed);
58
+ if (!url.search && !url.hash && url.pathname === "/") {
59
+ return url.origin;
60
+ }
61
+ if (!url.search && !url.hash && url.pathname === `${OAUTH_API_RESOURCE_PATH}/`) {
62
+ url.pathname = OAUTH_API_RESOURCE_PATH;
63
+ return url.toString();
64
+ }
65
+ return url.toString();
66
+ }
67
+ /**
68
+ * Derive the mcp origin from a configured api origin (`api.X` → `mcp.X`).
69
+ * Returns null when the api host doesn't follow the `api.` convention
70
+ * (loopback dev, docker test hosts) — callers fall back to the api origin.
71
+ */
72
+ export function oauthMcpOriginFromApiOrigin(apiOrigin) {
73
+ const url = new URL(apiOrigin);
74
+ if (!url.hostname.startsWith("api.")) {
75
+ return null;
76
+ }
77
+ url.hostname = `mcp.${url.hostname.slice("api.".length)}`;
78
+ return url.origin;
45
79
  }
46
80
  export function oauthAuthorizationServerUrl(origin) {
47
81
  return new URL(OAUTH_AUTHORIZATION_SERVER_PATH, origin).toString();
@@ -50,11 +84,8 @@ export function oauthTokenEndpointUrl(origin) {
50
84
  return new URL(`${OAUTH_AUTHORIZATION_SERVER_PATH}/oauth2/token`, origin).toString();
51
85
  }
52
86
  export function oauthResourceKeyForPathname(pathname) {
53
- if (pathname === OAUTH_RESOURCE_PATHS.mcp) {
54
- return "mcp";
55
- }
56
- if (pathname === OAUTH_RESOURCE_PATHS.api ||
57
- pathname.startsWith(`${OAUTH_RESOURCE_PATHS.api}/`)) {
87
+ if (pathname === OAUTH_API_RESOURCE_PATH ||
88
+ pathname.startsWith(`${OAUTH_API_RESOURCE_PATH}/`)) {
58
89
  return "api";
59
90
  }
60
91
  return null;