@spacefast/common 0.0.26 → 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 (302) hide show
  1. package/dist/agents/connect-targets.d.ts +6 -146
  2. package/dist/agents/connect-targets.js +63 -295
  3. package/dist/agents/private-key-oauth.d.ts +31 -1
  4. package/dist/agents/private-key-oauth.js +124 -33
  5. package/dist/agents/registry/core.d.ts +292 -0
  6. package/dist/agents/registry/core.js +1388 -0
  7. package/dist/agents/registry/deeplink-probes.d.ts +23 -0
  8. package/dist/agents/registry/deeplink-probes.js +18 -0
  9. package/dist/agents/registry/node.d.ts +56 -0
  10. package/dist/agents/registry/node.js +339 -0
  11. package/dist/brand-assets-build.js +1 -2
  12. package/dist/brand-assets.js +4 -7
  13. package/dist/brand.d.ts +17 -0
  14. package/dist/brand.js +24 -4
  15. package/dist/config/domains.d.ts +55 -28
  16. package/dist/config/domains.js +85 -41
  17. package/dist/config/index.js +1 -2
  18. package/dist/contracts/abuse.js +9 -24
  19. package/dist/contracts/access-profiles.d.ts +86 -0
  20. package/dist/contracts/access-profiles.js +89 -0
  21. package/dist/contracts/access.d.ts +21 -27
  22. package/dist/contracts/access.js +33 -64
  23. package/dist/contracts/activity.d.ts +18 -1
  24. package/dist/contracts/activity.js +70 -26
  25. package/dist/contracts/analytics.js +8 -10
  26. package/dist/contracts/api-keys.d.ts +77 -52
  27. package/dist/contracts/api-keys.js +44 -24
  28. package/dist/contracts/application-journal.d.ts +216 -0
  29. package/dist/contracts/application-journal.js +167 -0
  30. package/dist/contracts/auth.d.ts +90 -17
  31. package/dist/contracts/auth.js +86 -17
  32. package/dist/contracts/beta.d.ts +9 -4
  33. package/dist/contracts/beta.js +20 -16
  34. package/dist/contracts/billing.js +7 -11
  35. package/dist/contracts/bootstrap.d.ts +791 -0
  36. package/dist/contracts/bootstrap.js +51 -0
  37. package/dist/contracts/builds.d.ts +186 -7
  38. package/dist/contracts/builds.js +75 -21
  39. package/dist/contracts/channels.d.ts +43 -0
  40. package/dist/contracts/channels.js +25 -9
  41. package/dist/contracts/cli.d.ts +7 -0
  42. package/dist/contracts/cli.js +6 -0
  43. package/dist/contracts/collab-public.d.ts +1 -1
  44. package/dist/contracts/collab-public.js +5 -8
  45. package/dist/contracts/comments.d.ts +45 -35
  46. package/dist/contracts/comments.js +107 -77
  47. package/dist/contracts/commerce.d.ts +165 -0
  48. package/dist/contracts/commerce.js +146 -0
  49. package/dist/contracts/common.d.ts +3 -3
  50. package/dist/contracts/common.js +18 -29
  51. package/dist/contracts/content-contract-verification.d.ts +521 -0
  52. package/dist/contracts/content-contract-verification.js +320 -0
  53. package/dist/contracts/content-platform-fixture.d.ts +1278 -0
  54. package/dist/contracts/content-platform-fixture.js +44 -0
  55. package/dist/contracts/content-program.d.ts +994 -0
  56. package/dist/contracts/content-program.js +658 -0
  57. package/dist/contracts/content-sync.d.ts +290 -0
  58. package/dist/contracts/content-sync.js +167 -0
  59. package/dist/contracts/content.d.ts +432 -0
  60. package/dist/contracts/content.js +303 -0
  61. package/dist/contracts/continuation.d.ts +17 -1
  62. package/dist/contracts/continuation.js +23 -23
  63. package/dist/contracts/countries.js +3 -4
  64. package/dist/contracts/crons.d.ts +17 -0
  65. package/dist/contracts/crons.js +33 -15
  66. package/dist/contracts/dashboard-prefs.d.ts +56 -0
  67. package/dist/contracts/dashboard-prefs.js +51 -0
  68. package/dist/contracts/device-auth.d.ts +234 -37
  69. package/dist/contracts/device-auth.js +267 -53
  70. package/dist/contracts/docs.d.ts +6 -10
  71. package/dist/contracts/docs.js +5 -13
  72. package/dist/contracts/domains.d.ts +499 -102
  73. package/dist/contracts/domains.js +169 -58
  74. package/dist/contracts/email-preferences.d.ts +3 -3
  75. package/dist/contracts/email-preferences.js +6 -7
  76. package/dist/contracts/enums.d.ts +26 -26
  77. package/dist/contracts/enums.js +61 -54
  78. package/dist/contracts/error-code-meta.d.ts +269 -7
  79. package/dist/contracts/error-code-meta.js +80 -5
  80. package/dist/contracts/error-codes.d.ts +5 -5
  81. package/dist/contracts/error-codes.js +78 -16
  82. package/dist/contracts/events.d.ts +100 -20
  83. package/dist/contracts/events.js +107 -20
  84. package/dist/contracts/execution.d.ts +47 -66
  85. package/dist/contracts/execution.js +51 -64
  86. package/dist/contracts/feature-lifecycle.d.ts +70 -14
  87. package/dist/contracts/feature-lifecycle.js +86 -15
  88. package/dist/contracts/features.d.ts +100 -37
  89. package/dist/contracts/features.js +21 -27
  90. package/dist/contracts/fixtures/content-platform-v1.json +1108 -0
  91. package/dist/contracts/frame-session.d.ts +192 -0
  92. package/dist/contracts/frame-session.js +164 -0
  93. package/dist/contracts/functions.d.ts +218 -211
  94. package/dist/contracts/functions.js +273 -260
  95. package/dist/contracts/grant-copy.d.ts +43 -0
  96. package/dist/contracts/grant-copy.js +44 -0
  97. package/dist/contracts/grants.d.ts +64 -56
  98. package/dist/contracts/grants.js +124 -23
  99. package/dist/contracts/ids.d.ts +4 -1
  100. package/dist/contracts/ids.js +4 -1
  101. package/dist/contracts/internal.d.ts +5 -4
  102. package/dist/contracts/internal.js +12 -3
  103. package/dist/contracts/mcp.d.ts +17 -0
  104. package/dist/contracts/mcp.js +23 -0
  105. package/dist/contracts/me.d.ts +6 -1
  106. package/dist/contracts/me.js +12 -6
  107. package/dist/contracts/notifications.d.ts +27 -29
  108. package/dist/contracts/notifications.js +9 -4
  109. package/dist/contracts/oauth-resources.d.ts +112 -10
  110. package/dist/contracts/oauth-resources.js +116 -11
  111. package/dist/contracts/oauth-scope-actions.d.ts +90 -0
  112. package/dist/contracts/oauth-scope-actions.js +126 -0
  113. package/dist/contracts/operations.d.ts +27 -4
  114. package/dist/contracts/operations.js +11 -5
  115. package/dist/contracts/pages.d.ts +29 -5
  116. package/dist/contracts/pages.js +22 -5
  117. package/dist/contracts/partner-notifications.d.ts +3 -0
  118. package/dist/contracts/partner-notifications.js +65 -0
  119. package/dist/contracts/{platform.d.ts → partner.d.ts} +29 -42
  120. package/dist/contracts/{platform.js → partner.js} +27 -40
  121. package/dist/contracts/plan-policy.d.ts +1 -1
  122. package/dist/contracts/principal-assertion.d.ts +43 -0
  123. package/dist/contracts/principal-assertion.js +67 -0
  124. package/dist/contracts/principals.d.ts +73 -0
  125. package/dist/contracts/principals.js +59 -0
  126. package/dist/contracts/privacy.d.ts +11 -0
  127. package/dist/contracts/privacy.js +17 -0
  128. package/dist/contracts/problem-document.js +3 -4
  129. package/dist/contracts/publish-archive.d.ts +116 -18
  130. package/dist/contracts/publish-archive.js +6 -3
  131. package/dist/contracts/push-new.d.ts +4 -4
  132. package/dist/contracts/quotas.js +3 -3
  133. package/dist/contracts/realtime.d.ts +52 -0
  134. package/dist/contracts/realtime.js +54 -0
  135. package/dist/contracts/repository-connections.d.ts +1 -1
  136. package/dist/contracts/repository-connections.js +6 -2
  137. package/dist/contracts/resources.d.ts +105 -14
  138. package/dist/contracts/resources.js +145 -21
  139. package/dist/contracts/route-inventory.d.ts +358 -0
  140. package/dist/contracts/route-inventory.js +141 -0
  141. package/dist/contracts/runtime-api.d.ts +112 -35
  142. package/dist/contracts/runtime-api.js +86 -66
  143. package/dist/contracts/runtime-app.d.ts +11 -21
  144. package/dist/contracts/runtime-app.js +39 -24
  145. package/dist/contracts/runtime-components.d.ts +143 -0
  146. package/dist/contracts/runtime-components.js +199 -0
  147. package/dist/contracts/runtime-db.d.ts +45 -19
  148. package/dist/contracts/runtime-db.js +85 -20
  149. package/dist/contracts/runtime-purge.js +3 -5
  150. package/dist/contracts/runtime-services.d.ts +43 -75
  151. package/dist/contracts/runtime-services.js +29 -49
  152. package/dist/contracts/runtime-storage.d.ts +14 -14
  153. package/dist/contracts/runtime-storage.js +28 -13
  154. package/dist/contracts/sf-config-v1.d.ts +14 -18
  155. package/dist/contracts/slugs.js +13 -4
  156. package/dist/contracts/space-config.d.ts +235 -28
  157. package/dist/contracts/space-config.js +246 -91
  158. package/dist/contracts/spaces.d.ts +360 -255
  159. package/dist/contracts/spaces.js +190 -122
  160. package/dist/contracts/superadmin-activity.d.ts +3 -43
  161. package/dist/contracts/superadmin-activity.js +6 -30
  162. package/dist/contracts/superadmin-emails.d.ts +1 -0
  163. package/dist/contracts/superadmin-emails.js +17 -1
  164. package/dist/contracts/superadmin-runtime.d.ts +199 -0
  165. package/dist/contracts/superadmin-runtime.js +141 -0
  166. package/dist/contracts/superadmin-search.d.ts +22 -2
  167. package/dist/contracts/superadmin-search.js +14 -6
  168. package/dist/contracts/superadmin-spaces.d.ts +435 -186
  169. package/dist/contracts/superadmin-spaces.js +131 -25
  170. package/dist/contracts/superadmin-teams.d.ts +3 -0
  171. package/dist/contracts/superadmin-teams.js +1 -2
  172. package/dist/contracts/superadmin-tenants.d.ts +627 -6
  173. package/dist/contracts/superadmin-tenants.js +32 -7
  174. package/dist/contracts/superadmin.d.ts +98 -16
  175. package/dist/contracts/superadmin.js +63 -10
  176. package/dist/contracts/tags.d.ts +85 -58
  177. package/dist/contracts/tags.js +44 -34
  178. package/dist/contracts/teams.d.ts +72 -9
  179. package/dist/contracts/teams.js +84 -25
  180. package/dist/contracts/tenants.d.ts +135 -0
  181. package/dist/contracts/tenants.js +120 -0
  182. package/dist/contracts/test-triggers.d.ts +70 -0
  183. package/dist/contracts/test-triggers.js +116 -0
  184. package/dist/contracts/theme-json.js +3 -8
  185. package/dist/contracts/transfers.d.ts +1 -0
  186. package/dist/contracts/transfers.js +1 -0
  187. package/dist/contracts/usage.d.ts +209 -0
  188. package/dist/contracts/usage.js +124 -12
  189. package/dist/contracts/variables.d.ts +2 -2
  190. package/dist/contracts/variables.js +9 -13
  191. package/dist/contracts/webhooks.d.ts +13 -5
  192. package/dist/contracts/webhooks.js +3 -1
  193. package/dist/contracts/zero.d.ts +57 -64
  194. package/dist/contracts/zero.js +68 -66
  195. package/dist/dashboard-paths/index.d.ts +24 -21
  196. package/dist/dashboard-paths/index.js +35 -47
  197. package/dist/dashboard-paths/route-reservations.generated.d.ts +2 -0
  198. package/dist/dashboard-paths/route-reservations.generated.js +36 -0
  199. package/dist/docs/agent-arrival.d.ts +92 -0
  200. package/dist/docs/agent-arrival.js +227 -0
  201. package/dist/docs/agent-output-policy.d.ts +6 -0
  202. package/dist/docs/agent-output-policy.js +22 -0
  203. package/dist/docs/agent-prose.d.ts +11 -17
  204. package/dist/docs/agent-prose.js +62 -37
  205. package/dist/docs/agent-setup.d.ts +72 -41
  206. package/dist/docs/agent-setup.js +336 -436
  207. package/dist/docs/catalog.d.ts +147 -89
  208. package/dist/docs/catalog.js +157 -42
  209. package/dist/docs/error-docs.d.ts +2098 -1
  210. package/dist/docs/error-docs.js +281 -16
  211. package/dist/docs/index-build.d.ts +0 -1
  212. package/dist/docs/index-build.js +2 -3
  213. package/dist/docs/page-context-prompt.d.ts +77 -0
  214. package/dist/docs/page-context-prompt.js +131 -0
  215. package/dist/docs/reference-urls.d.ts +46 -0
  216. package/dist/docs/reference-urls.js +79 -0
  217. package/dist/docs/search.d.ts +6 -8
  218. package/dist/docs/search.js +10 -13
  219. package/dist/docs/skill-distribution.d.ts +4 -1
  220. package/dist/docs/skill-distribution.js +10 -5
  221. package/dist/docs/skills.d.ts +117 -117
  222. package/dist/docs/skills.js +120 -72
  223. package/dist/docs/start-prompts.d.ts +45 -0
  224. package/dist/docs/start-prompts.js +62 -0
  225. package/dist/domain-exploration.js +9 -13
  226. package/dist/og-template.d.ts +56 -0
  227. package/dist/og-template.js +56 -0
  228. package/dist/slug-policy/index.js +5 -11
  229. package/dist/utils/browser-credential.d.ts +13 -6
  230. package/dist/utils/browser-credential.js +14 -7
  231. package/dist/utils/build-settings.d.ts +16 -0
  232. package/dist/utils/build-settings.js +63 -17
  233. package/dist/utils/canonical-json.d.ts +3 -5
  234. package/dist/utils/canonical-json.js +3 -5
  235. package/dist/utils/cast-transport.d.ts +5 -17
  236. package/dist/utils/cast-transport.js +6 -19
  237. package/dist/utils/claim-token.js +1 -2
  238. package/dist/utils/comment-avatars.js +4 -6
  239. package/dist/utils/concurrency.js +2 -3
  240. package/dist/utils/content-type.d.ts +7 -6
  241. package/dist/utils/content-type.js +73 -51
  242. package/dist/utils/credential-policy.d.ts +50 -6
  243. package/dist/utils/credential-policy.js +123 -57
  244. package/dist/utils/egress-policy.fixtures.json +1 -1
  245. package/dist/utils/generate-space-name.d.ts +3 -8
  246. package/dist/utils/generate-space-name.js +3 -8
  247. package/dist/utils/grants.d.ts +0 -1
  248. package/dist/utils/grants.js +4 -7
  249. package/dist/utils/gravatar.d.ts +2 -4
  250. package/dist/utils/gravatar.js +6 -12
  251. package/dist/utils/id-hints.js +14 -23
  252. package/dist/utils/idempotency.d.ts +3 -3
  253. package/dist/utils/idempotency.js +6 -7
  254. package/dist/utils/local-space-state.d.ts +15 -15
  255. package/dist/utils/local-space-state.js +34 -23
  256. package/dist/utils/oauth-signed-query.d.ts +3 -5
  257. package/dist/utils/oauth-signed-query.js +6 -9
  258. package/dist/utils/one-shot-replay.d.ts +3 -5
  259. package/dist/utils/one-shot-replay.js +3 -5
  260. package/dist/utils/page-colors.d.ts +4 -10
  261. package/dist/utils/page-colors.js +11 -35
  262. package/dist/utils/page-fonts.js +6 -11
  263. package/dist/utils/page-preview.d.ts +0 -1
  264. package/dist/utils/page-preview.js +0 -1
  265. package/dist/utils/pages.d.ts +22 -11
  266. package/dist/utils/pages.js +70 -30
  267. package/dist/utils/privacy-regions.d.ts +19 -0
  268. package/dist/utils/privacy-regions.js +91 -0
  269. package/dist/utils/publish-form-data.d.ts +4 -5
  270. package/dist/utils/publish-form-data.js +2 -3
  271. package/dist/utils/publish-policy.d.ts +10 -23
  272. package/dist/utils/publish-policy.js +63 -116
  273. package/dist/utils/query-client.d.ts +2 -0
  274. package/dist/utils/query-client.js +10 -1
  275. package/dist/utils/runtime-paths.d.ts +4 -4
  276. package/dist/utils/runtime-paths.js +6 -8
  277. package/dist/utils/runtime-upload.d.ts +4 -0
  278. package/dist/utils/runtime-upload.js +5 -0
  279. package/dist/utils/secure-local-file.d.ts +3 -3
  280. package/dist/utils/secure-local-file.js +18 -24
  281. package/dist/utils/space-config.d.ts +11 -14
  282. package/dist/utils/space-config.js +10 -16
  283. package/dist/utils/static-runtime-policy.d.ts +5 -8
  284. package/dist/utils/static-runtime-policy.generated.d.ts +16 -0
  285. package/dist/utils/static-runtime-policy.generated.js +70 -0
  286. package/dist/utils/static-runtime-policy.js +17 -84
  287. package/dist/utils/storage-policy.js +1 -2
  288. package/dist/utils/upload-session.js +8 -14
  289. package/dist/utils/version-path.js +11 -19
  290. package/dist/utils/wpcom-auth-redirects.d.ts +5 -14
  291. package/dist/utils/wpcom-auth-redirects.js +1 -4
  292. package/dist/vocabulary.d.ts +7 -7
  293. package/dist/vocabulary.js +30 -16
  294. package/package.json +14 -2
  295. package/dist/agents/client-registry.d.ts +0 -22
  296. package/dist/agents/client-registry.js +0 -41
  297. package/dist/docs/agent-handoff-document.d.ts +0 -15
  298. package/dist/docs/agent-handoff-document.js +0 -180
  299. package/dist/docs/agent-solutions.d.ts +0 -110
  300. package/dist/docs/agent-solutions.js +0 -183
  301. package/dist/utils/query-keys.d.ts +0 -84
  302. package/dist/utils/query-keys.js +0 -108
@@ -5,16 +5,13 @@ export declare const LOCAL_SPACE_STATE_FILE_NAME = "state.json";
5
5
  /**
6
6
  * Local Spacefast checkout contract.
7
7
  *
8
- * `.spacefast/space.json` is the committable selection axis: it names which
9
- * space a checkout targets (`space`) and may carry non-secret provider/team
10
- * coordinates (`team`, `apiBaseUrl`). It must not carry credentials.
8
+ * `.spacefast/space.json` is the committable selection axis: which space a
9
+ * checkout targets, plus non-secret provider/team coordinates. Never credentials.
11
10
  *
12
- * `.spacefast/state.json` is the local credential/cache axis: it records the
13
- * resolved `spaceId`, provider `apiUrl`, anonymous `claimToken` before claim,
14
- * durable `accessToken` after continuation, and small publish caches such as
15
- * `lastVersionId`. It is secret, machine-written, gitignored, and merge-written.
16
- * The strict versioned schema fails closed instead of letting an older tool
17
- * reinterpret fields written under a contract it does not understand.
11
+ * `.spacefast/state.json` is the secret axis: credentials and small publish
12
+ * caches, machine-written, gitignored, merge-written. Its strict versioned
13
+ * schema fails closed rather than let an older tool reinterpret fields written
14
+ * under a contract it does not understand.
18
15
  */
19
16
  export declare const localSpaceLinkSchema: z.ZodObject<{
20
17
  team: z.ZodOptional<z.ZodString>;
@@ -124,17 +121,15 @@ export declare function localSpaceStateDir(root: string): string;
124
121
  export declare function localSpaceStatePath(root: string): string;
125
122
  export declare function localSpaceLinkPath(root: string): string;
126
123
  export declare function readLocalSpaceLink(root: string): Promise<LocalSpaceLink | null>;
127
- /** Like readLocalSpaceLink, but reports the file path alongside the link. */
128
124
  export declare function readLocalSpaceLinkWithPath(root: string): Promise<{
129
125
  link: LocalSpaceLink;
130
126
  path: string;
131
127
  } | null>;
132
128
  export declare function readLocalSpaceStateAt(root: string): Promise<DiscoveredLocalSpaceState | null>;
133
129
  /**
134
- * Walk up from `startDir` to the filesystem root (or `boundary`, when given),
135
- * returning the first non-null result of `probe`. Shared by every "nearest
136
- * checkout marker" lookup (state+link discovery here, the CLI's link-only
137
- * discovery) so the traversal rules live in one place.
130
+ * Walk up from `startDir` to the filesystem root (or `boundary`), returning the
131
+ * first non-null `probe` result. Every "nearest checkout marker" lookup shares
132
+ * it so the traversal rules live in one place.
138
133
  */
139
134
  export declare function findUpward<T>(probe: (dir: string) => Promise<T | null>, startDir?: string, boundary?: string): Promise<T | null>;
140
135
  export declare function discoverLocalSpaceState(startDir?: string, boundary?: string): Promise<DiscoveredLocalSpaceState | null>;
@@ -144,8 +139,9 @@ export declare function mutateLocalSpaceState(root: string, mutate: (current: Lo
144
139
  afterBackup?: (() => void | Promise<void>) | undefined;
145
140
  /** Fault-injection observer used to synchronize concurrency tests. */
146
141
  onConflict?: (() => void | Promise<void>) | undefined;
142
+ /** Reports whether this mutation changed `.gitignore`. */
143
+ onGitignoreResult?: ((changed: boolean) => void) | undefined;
147
144
  }): Promise<LocalSpaceStateFile>;
148
- /** Reserve random replay custody before a claim token can be consumed. */
149
145
  export declare function reserveLocalCredentialReplay(root: string, input: {
150
146
  operation: LocalCredentialReplayOperation;
151
147
  claimToken: string;
@@ -155,4 +151,8 @@ export declare function saveLocalSpaceState(root: string, input: SaveLocalSpaceS
155
151
  statePath: string;
156
152
  linkPath: string;
157
153
  wroteLink: boolean;
154
+ gitignore: {
155
+ path: string;
156
+ changed: boolean;
157
+ };
158
158
  }>;
@@ -10,16 +10,13 @@ export const LOCAL_SPACE_STATE_FILE_NAME = "state.json";
10
10
  /**
11
11
  * Local Spacefast checkout contract.
12
12
  *
13
- * `.spacefast/space.json` is the committable selection axis: it names which
14
- * space a checkout targets (`space`) and may carry non-secret provider/team
15
- * coordinates (`team`, `apiBaseUrl`). It must not carry credentials.
13
+ * `.spacefast/space.json` is the committable selection axis: which space a
14
+ * checkout targets, plus non-secret provider/team coordinates. Never credentials.
16
15
  *
17
- * `.spacefast/state.json` is the local credential/cache axis: it records the
18
- * resolved `spaceId`, provider `apiUrl`, anonymous `claimToken` before claim,
19
- * durable `accessToken` after continuation, and small publish caches such as
20
- * `lastVersionId`. It is secret, machine-written, gitignored, and merge-written.
21
- * The strict versioned schema fails closed instead of letting an older tool
22
- * reinterpret fields written under a contract it does not understand.
16
+ * `.spacefast/state.json` is the secret axis: credentials and small publish
17
+ * caches, machine-written, gitignored, merge-written. Its strict versioned
18
+ * schema fails closed rather than let an older tool reinterpret fields written
19
+ * under a contract it does not understand.
23
20
  */
24
21
  export const localSpaceLinkSchema = z
25
22
  .object({
@@ -31,7 +28,7 @@ export const localSpaceLinkSchema = z
31
28
  export const LOCAL_SPACE_STATE_SCHEMA_VERSION = 1;
32
29
  // One reservation, two slots: it is written as `pendingPublish` and moved to
33
30
  // `creationReplay` once its receipt commits. Space creation is the only
34
- // mutation that reserves one — credential-free publishes are not idempotent.
31
+ // mutation that reserves one. Credential-free publishes are not idempotent.
35
32
  export const creationAttemptSchema = z
36
33
  .object({
37
34
  key: z.string().min(1),
@@ -145,7 +142,6 @@ function linkSpaceId(link) {
145
142
  export async function readLocalSpaceLink(root) {
146
143
  return (await readLocalSpaceLinkWithPath(root))?.link ?? null;
147
144
  }
148
- /** Like readLocalSpaceLink, but reports the file path alongside the link. */
149
145
  export async function readLocalSpaceLinkWithPath(root) {
150
146
  const primary = parseLink(await readJsonFile(root, path.join(LOCAL_SPACE_STATE_DIR_NAME, LOCAL_SPACE_LINK_FILE_NAME)));
151
147
  return primary ? { link: primary, path: localSpaceLinkPath(root) } : null;
@@ -183,10 +179,9 @@ function isWithinBoundary(current, boundary) {
183
179
  return relative === "" || (!relative.startsWith("..") && !path.isAbsolute(relative));
184
180
  }
185
181
  /**
186
- * Walk up from `startDir` to the filesystem root (or `boundary`, when given),
187
- * returning the first non-null result of `probe`. Shared by every "nearest
188
- * checkout marker" lookup (state+link discovery here, the CLI's link-only
189
- * discovery) so the traversal rules live in one place.
182
+ * Walk up from `startDir` to the filesystem root (or `boundary`), returning the
183
+ * first non-null `probe` result. Every "nearest checkout marker" lookup shares
184
+ * it so the traversal rules live in one place.
190
185
  */
191
186
  export async function findUpward(probe, startDir = process.cwd(), boundary) {
192
187
  let current = path.resolve(startDir);
@@ -251,7 +246,7 @@ async function ensureStateGitignored(root, onConflict) {
251
246
  const lines = raw.split(/\r?\n/);
252
247
  const missing = entries.filter((entry) => !lines.includes(entry));
253
248
  if (missing.length === 0)
254
- return;
249
+ return false;
255
250
  const prefix = raw.length > 0 && !raw.endsWith("\n") ? "\n" : "";
256
251
  await secureWriteFile({
257
252
  root,
@@ -261,7 +256,7 @@ async function ensureStateGitignored(root, onConflict) {
261
256
  mode: 0o644,
262
257
  expectedContent: existing,
263
258
  });
264
- return;
259
+ return true;
265
260
  }
266
261
  catch (error) {
267
262
  if (error instanceof SecureLocalFileConflictError)
@@ -274,6 +269,7 @@ async function ensureStateGitignored(root, onConflict) {
274
269
  }
275
270
  }
276
271
  /* eslint-enable no-await-in-loop */
272
+ throw new LocalSpaceStateConflictError("Local .gitignore stayed busy for too long.");
277
273
  }
278
274
  function assignDefined(target, input) {
279
275
  for (const [key, value] of Object.entries(input)) {
@@ -308,7 +304,8 @@ export async function writeLocalSpaceLink(root, link) {
308
304
  }
309
305
  export async function mutateLocalSpaceState(root, mutate, options = {}) {
310
306
  const stateRelativePath = path.join(LOCAL_SPACE_STATE_DIR_NAME, LOCAL_SPACE_STATE_FILE_NAME);
311
- await ensureStateGitignored(root, options.onConflict);
307
+ const gitignoreChanged = await ensureStateGitignored(root, options.onConflict);
308
+ options.onGitignoreResult?.(gitignoreChanged);
312
309
  /* eslint-disable no-await-in-loop -- compare-and-swap retries are intentionally serialized against the latest committed state. */
313
310
  for (let attempt = 1; attempt <= LOCAL_STATE_MUTATION_ATTEMPTS; attempt += 1) {
314
311
  try {
@@ -320,8 +317,8 @@ export async function mutateLocalSpaceState(root, mutate, options = {}) {
320
317
  const current = parsed?.success
321
318
  ? parsed.data
322
319
  : { schemaVersion: LOCAL_SPACE_STATE_SCHEMA_VERSION };
323
- // The callback may run again after a compare-and-swap collision. Keeping it
324
- // synchronous makes remote effects and other one-shot work impossible here.
320
+ // The callback may run again after a compare-and-swap collision; keeping
321
+ // it synchronous rules out one-shot work inside it.
325
322
  const payload = localSpaceStateSchema.parse({
326
323
  ...mutate(structuredClone(current)),
327
324
  schemaVersion: LOCAL_SPACE_STATE_SCHEMA_VERSION,
@@ -362,7 +359,6 @@ function sameCredentialReplay(left, right) {
362
359
  left.key === right.key &&
363
360
  left.principal === right.principal);
364
361
  }
365
- /** Reserve random replay custody before a claim token can be consumed. */
366
362
  export async function reserveLocalCredentialReplay(root, input) {
367
363
  const identity = createOneShotReplayIdentity(`sf-${input.operation}`);
368
364
  const candidate = {
@@ -396,6 +392,7 @@ function credentialMatches(state, expected) {
396
392
  return state.claimToken === expected.claimToken && state.accessToken === expected.accessToken;
397
393
  }
398
394
  export async function saveLocalSpaceState(root, input) {
395
+ let gitignoreChanged = false;
399
396
  await mutateLocalSpaceState(root, (existing) => {
400
397
  if (existing.spaceId && existing.spaceId !== input.spaceId && !input.replaceSpace) {
401
398
  throw new LocalSpaceStateConflictError(`Local Spacefast state changed from ${input.spaceId} to ${existing.spaceId}.`);
@@ -473,6 +470,10 @@ export async function saveLocalSpaceState(root, input) {
473
470
  delete next.pendingCredentialReplay;
474
471
  }
475
472
  return localSpaceStateSchema.parse(next);
473
+ }, {
474
+ onGitignoreResult: (changed) => {
475
+ gitignoreChanged = changed;
476
+ },
476
477
  });
477
478
  const statePath = localSpaceStatePath(root);
478
479
  const linkRelativePath = path.join(LOCAL_SPACE_STATE_DIR_NAME, LOCAL_SPACE_LINK_FILE_NAME);
@@ -495,7 +496,12 @@ export async function saveLocalSpaceState(root, input) {
495
496
  throw new LocalSpaceStateConflictError(`The committed checkout link selects ${inheritedLink.space}, not ${input.spaceId}.`);
496
497
  }
497
498
  if (inheritedLink) {
498
- return { statePath, linkPath: localSpaceLinkPath(root), wroteLink };
499
+ return {
500
+ statePath,
501
+ linkPath: localSpaceLinkPath(root),
502
+ wroteLink,
503
+ gitignore: { path: path.join(root, ".gitignore"), changed: gitignoreChanged },
504
+ };
499
505
  }
500
506
  }
501
507
  try {
@@ -519,5 +525,10 @@ export async function saveLocalSpaceState(root, input) {
519
525
  else if (primaryLink.space !== input.spaceId) {
520
526
  throw new LocalSpaceStateConflictError(`The committed checkout link selects ${primaryLink.space}, not ${input.spaceId}.`);
521
527
  }
522
- return { statePath, linkPath: localSpaceLinkPath(root), wroteLink };
528
+ return {
529
+ statePath,
530
+ linkPath: localSpaceLinkPath(root),
531
+ wroteLink,
532
+ gitignore: { path: path.join(root, ".gitignore"), changed: gitignoreChanged },
533
+ };
523
534
  }
@@ -1,8 +1,6 @@
1
1
  /**
2
- * The signed OAuth authorize continuation carried by a query string, or null
3
- * when there isn't one. Better Auth's signature covers every param it sent
4
- * (the set is self-declared in `ba_param`) anything extra that later joined
5
- * the URL (a returnTo, a tracking param) must be dropped before the query is
6
- * sent back, or verification fails.
2
+ * The signed authorize continuation in `query`, or null when there isn't one.
3
+ * The signature covers only the params `ba_param` names, so anything that
4
+ * joined the URL later must be dropped or verification fails.
7
5
  */
8
6
  export declare function signedOAuthQuerySubset(query: string): string | null;
@@ -1,13 +1,10 @@
1
- // Better Auth's OAuth authorize endpoint hands interaction prompts (login,
2
- // consent) to the dashboard by redirecting with the ENTIRE authorize query,
3
- // HMAC-signed by the auth server (`sig` + `exp` + `ba_*` bookkeeping params).
4
- // Verification hashes the query verbatim, so it must round-trip byte-exact.
1
+ // Better Auth redirects interaction prompts to the dashboard with the entire
2
+ // authorize query, HMAC-signed. Verification hashes it verbatim, so the query
3
+ // must round-trip byte-exact.
5
4
  /**
6
- * The signed OAuth authorize continuation carried by a query string, or null
7
- * when there isn't one. Better Auth's signature covers every param it sent
8
- * (the set is self-declared in `ba_param`) anything extra that later joined
9
- * the URL (a returnTo, a tracking param) must be dropped before the query is
10
- * sent back, or verification fails.
5
+ * The signed authorize continuation in `query`, or null when there isn't one.
6
+ * The signature covers only the params `ba_param` names, so anything that
7
+ * joined the URL later must be dropped or verification fails.
11
8
  */
12
9
  export function signedOAuthQuerySubset(query) {
13
10
  const params = new URLSearchParams(query);
@@ -3,11 +3,9 @@ export type OneShotReplayIdentity = {
3
3
  principal: string;
4
4
  };
5
5
  /**
6
- * Creates an unguessable capability for replaying one shown-once response.
7
- *
8
- * Neither value is derived from the credential consumed by the mutation. A
9
- * caller holding only that old credential therefore cannot locate the stored
10
- * response after the credential is revoked.
6
+ * An unguessable capability for replaying one shown-once response. Neither
7
+ * value derives from the credential the mutation consumes, so a caller holding
8
+ * only that revoked credential cannot locate the stored response.
11
9
  */
12
10
  export declare function createOneShotReplayIdentity(prefix: string): OneShotReplayIdentity;
13
11
  /** Production headers for one one-shot attempt (or one device-poll sequence). */
@@ -1,10 +1,8 @@
1
1
  import { randomBytes } from "node:crypto";
2
2
  /**
3
- * Creates an unguessable capability for replaying one shown-once response.
4
- *
5
- * Neither value is derived from the credential consumed by the mutation. A
6
- * caller holding only that old credential therefore cannot locate the stored
7
- * response after the credential is revoked.
3
+ * An unguessable capability for replaying one shown-once response. Neither
4
+ * value derives from the credential the mutation consumes, so a caller holding
5
+ * only that revoked credential cannot locate the stored response.
8
6
  */
9
7
  export function createOneShotReplayIdentity(prefix) {
10
8
  return {
@@ -1,7 +1,5 @@
1
1
  import type { SpacePageTheme } from "../contracts/space-config.js";
2
- /** Default page palette (mirrored into the shared template CSS) — the
3
- * printed-matter scheme: warm canvas, ink type, marker accent (always a
4
- * ground with ink on top; the link derivation handles its text-grade). */
2
+ /** Default page palette, mirrored into the shared template CSS. */
5
3
  export declare const PAGE_COLOR_DEFAULTS: {
6
4
  readonly accent: "#d8f24b";
7
5
  readonly bg: "#f7f5ef";
@@ -28,7 +26,6 @@ export type DerivedPageColors = {
28
26
  scheme: "adaptive" | "light" | "dark";
29
27
  /** The accent exactly as pushed (fills keep the brand color verbatim). */
30
28
  accent: string;
31
- /** Label color on accent fills. */
32
29
  onAccent: string;
33
30
  /** Accent-derived link color, readable on the light (or pinned) surface. */
34
31
  link: string;
@@ -38,15 +35,12 @@ export type DerivedPageColors = {
38
35
  pinned?: PageSchemeColors;
39
36
  };
40
37
  /**
41
- * Return `color` unchanged when it already meets `target` on `surface`;
42
- * otherwise move its OKLCH lightness (hue/chroma preserved) just far enough
43
- * to meet it. Falls back to plain black/white when even full lightness range
44
- * cannot reach the target (e.g. a mid-gray surface).
38
+ * Moves `color`'s OKLCH lightness (hue and chroma preserved) just far enough
39
+ * to meet `target` on `surface`. Falls back to black or white when the full
40
+ * lightness range cannot reach it, as on a mid-gray surface.
45
41
  */
46
42
  export declare function readableOn(color: string, surface: string, target: number): string;
47
- /** Button-label color for an accent fill: white when it can carry, else ink. */
48
43
  export declare function onAccentColor(accent: string): string;
49
- /** The one entry point: raw theme in, everything the templates paint with out. */
50
44
  export declare function derivePageColors(theme: Pick<SpacePageTheme, "accent" | "background">): DerivedPageColors;
51
45
  /** Hex form of any schema-accepted color, for color-picker inputs. */
52
46
  export declare function pageColorToHex(value: string): string | null;
@@ -1,26 +1,10 @@
1
- // Readability engine for Spacefast-authored pages.
2
- //
3
- // Theme colors are intent, not CSS: users and agents push any accent or
4
- // background (dashboard, spacefast.jsonc, API) and the platform guarantees
5
- // every rendered page stays readable. This module derives the full set of
6
- // colors the templates actually paint with:
7
- //
8
- // - `onAccent` — button-label color on accent fills (black or white).
9
- // - `link` — the accent, lightness-adjusted until it meets WCAG AA
10
- // against the surface it sits on. Hue and chroma survive,
11
- // so it still reads as the brand color.
12
- // - `pinned` — when a background is set, a complete coherent scheme
13
- // (fg/muted/surface/border) derived from it and pinned for
14
- // every visitor. A chosen background IS the page; the
15
- // visitor's OS dark-mode setting must not repaint half the
16
- // variables into an unreadable hybrid.
17
- //
18
- // Everything is pure and deterministic: publish finalize, dashboard previews,
19
- // and tests all call the same functions and get the same pixels.
1
+ // Readability engine for Spacefast-authored pages. Users and agents push any
2
+ // accent or background; this module derives the colors the templates paint
3
+ // with so every page meets WCAG AA. A pushed background pins a whole scheme,
4
+ // because the visitor's OS dark-mode setting must not repaint half the
5
+ // variables into an unreadable hybrid.
20
6
  import { formatHex, oklch, parse, wcagContrast } from "culori";
21
- /** Default page palette (mirrored into the shared template CSS) — the
22
- * printed-matter scheme: warm canvas, ink type, marker accent (always a
23
- * ground with ink on top; the link derivation handles its text-grade). */
7
+ /** Default page palette, mirrored into the shared template CSS. */
24
8
  export const PAGE_COLOR_DEFAULTS = {
25
9
  accent: "#d8f24b",
26
10
  bg: "#f7f5ef",
@@ -34,13 +18,10 @@ export const PAGE_COLOR_DEFAULTS = {
34
18
  darkCard: "#0c0c0c",
35
19
  darkBorder: "#2b2823",
36
20
  };
37
- /** WCAG AA for body-size text. */
21
+ // WCAG AA: 4.5 for text, 3 for non-text control boundaries.
38
22
  const TEXT_CONTRAST = 4.5;
39
- /** Body-size button labels on accent fills. */
40
23
  const UI_CONTRAST = 4.5;
41
- /** Essential control boundaries against their painted surface. */
42
24
  const CONTROL_CONTRAST = 3;
43
- /** Primary foreground meets AA even on mid-tone custom backgrounds. */
44
25
  const FG_CONTRAST = 4.5;
45
26
  function safeParse(value) {
46
27
  if (!value)
@@ -59,10 +40,9 @@ function isLightSurface(surface) {
59
40
  return contrast("#000000", surface) >= contrast("#ffffff", surface);
60
41
  }
61
42
  /**
62
- * Return `color` unchanged when it already meets `target` on `surface`;
63
- * otherwise move its OKLCH lightness (hue/chroma preserved) just far enough
64
- * to meet it. Falls back to plain black/white when even full lightness range
65
- * cannot reach the target (e.g. a mid-gray surface).
43
+ * Moves `color`'s OKLCH lightness (hue and chroma preserved) just far enough
44
+ * to meet `target` on `surface`. Falls back to black or white when the full
45
+ * lightness range cannot reach it, as on a mid-gray surface.
66
46
  */
67
47
  export function readableOn(color, surface, target) {
68
48
  if (contrast(color, surface) >= target)
@@ -78,8 +58,7 @@ export function readableOn(color, surface, target) {
78
58
  if (contrast(atLimit, surface) < target) {
79
59
  return isLightSurface(surface) ? "#000000" : "#ffffff";
80
60
  }
81
- // Binary search for the lightness closest to the original that still meets
82
- // the target; contrast is monotonic in lightness on a fixed surface side.
61
+ // Contrast is monotonic in lightness on a fixed surface side.
83
62
  let searchLimit = limit;
84
63
  let searchStart = base.l;
85
64
  for (let i = 0; i < 24; i += 1) {
@@ -93,14 +72,12 @@ export function readableOn(color, surface, target) {
93
72
  }
94
73
  return formatHex({ ...base, l: searchLimit });
95
74
  }
96
- /** Button-label color for an accent fill: white when it can carry, else ink. */
97
75
  export function onAccentColor(accent) {
98
76
  return contrast("#ffffff", accent) >= UI_CONTRAST ? "#ffffff" : "#000000";
99
77
  }
100
78
  function clamp(value, min, max) {
101
79
  return Math.min(max, Math.max(min, value));
102
80
  }
103
- /** Derive a complete coherent scheme from a pushed background color. */
104
81
  function schemeFromBackground(background) {
105
82
  const parsed = safeParse(background);
106
83
  const bg = parsed ? formatHex(parsed) : PAGE_COLOR_DEFAULTS.bg;
@@ -138,7 +115,6 @@ function schemeFromBackground(background) {
138
115
  },
139
116
  };
140
117
  }
141
- /** The one entry point: raw theme in, everything the templates paint with out. */
142
118
  export function derivePageColors(theme) {
143
119
  const accentInput = theme.accent?.trim();
144
120
  const accent = accentInput && safeParse(accentInput) ? accentInput : PAGE_COLOR_DEFAULTS.accent;
@@ -1,15 +1,10 @@
1
- // The platform page fonts. Recoleta is the only downloaded face (DESIGN.md
2
- // §4) body and mono are system stacks, so a published page pays for exactly
3
- // one typeface. It is commercial, never committed to this repo, and loads from
4
- // wordpress.com's font CDN so every space hostname reuses one warm
5
- // browser-cache entry instead of a cold per-space fetch.
6
- // `font-display:optional` renders the fallback and never swaps mid-view when a
7
- // font arrives late — cached loads (everything after the first) get the brand
8
- // font with no flicker either way.
1
+ // Recoleta is the only downloaded face (DESIGN.md §4); body and mono are system
2
+ // stacks. It is commercial, never committed to this repo, and loads from
3
+ // wordpress.com's font CDN so every space hostname shares one cache entry.
4
+ // `font-display:optional` never swaps mid-view when a font arrives late.
9
5
  const RECOLETA_BASE = "https://wordpress.com/i/fonts/recoleta/";
10
6
  const RECOLETA_WEIGHTS = [300, 400, 500, 600, 700];
11
7
  export const PAGE_FONT_FACES = RECOLETA_WEIGHTS.map((weight) => `@font-face{font-family:"Recoleta";src:url("${RECOLETA_BASE}${weight}.woff2") format("woff2");font-style:normal;font-weight:${weight};font-display:optional}`).join("");
12
- // Only the face the default pages actually download: Recoleta 400 for headings.
13
- // Fonts are a cross-origin fetch; `crossorigin` is required font requests are
14
- // CORS mode, and a mismatched preload is discarded.
8
+ // Only the weight the default pages render. `crossorigin` is required: font
9
+ // requests are CORS mode, and a mismatched preload is discarded.
15
10
  export const PAGE_FONT_PRELOAD_HTML = `<link rel="preload" href="${RECOLETA_BASE}400.woff2" as="font" type="font/woff2" crossorigin>`;
@@ -3,5 +3,4 @@
3
3
  * the preview page is reachable only under this query flag.
4
4
  */
5
5
  export declare const PAGE_PREVIEW_QUERY = "spacefast_view";
6
- /** The preview page for a file whose bytes live at `fileHref`. */
7
6
  export declare function previewPageHref(fileHref: string): string;
@@ -3,7 +3,6 @@
3
3
  * the preview page is reachable only under this query flag.
4
4
  */
5
5
  export const PAGE_PREVIEW_QUERY = "spacefast_view";
6
- /** The preview page for a file whose bytes live at `fileHref`. */
7
6
  export function previewPageHref(fileHref) {
8
7
  return `${fileHref}${fileHref.includes("?") ? "&" : "?"}${PAGE_PREVIEW_QUERY}=1`;
9
8
  }
@@ -1,4 +1,4 @@
1
- import { type CustomPageId, type SitePageId } from "../contracts/pages.js";
1
+ import { type CustomPageId, type PlatformPageId, type SitePageId } from "../contracts/pages.js";
2
2
  import { type DerivedPageColors } from "./page-colors.js";
3
3
  export { PAGE_PREVIEW_QUERY, previewPageHref } from "./page-preview.js";
4
4
  export type PageTheme = {
@@ -22,7 +22,7 @@ export type PagePreviewFile = {
22
22
  mime?: string;
23
23
  };
24
24
  export type PageExpansionContext = {
25
- page: CustomPageId | "layout";
25
+ page: CustomPageId | PlatformPageId | "layout";
26
26
  theme?: PageTheme;
27
27
  content?: string;
28
28
  displayPath?: string;
@@ -30,6 +30,9 @@ export type PageExpansionContext = {
30
30
  itemCount?: number;
31
31
  visibleItemCount?: number;
32
32
  hideSpacefastBranding?: boolean;
33
+ supportUrl?: string;
34
+ partnerBranding?: boolean;
35
+ useSystemDisplayFont?: boolean;
33
36
  files?: readonly PageFileEntry[];
34
37
  file?: PagePreviewFile;
35
38
  };
@@ -42,15 +45,10 @@ export type PageDiagnostic = {
42
45
  export declare function isPagePublicPath(path: string): boolean;
43
46
  export declare function escapePageHtml(value: string): string;
44
47
  /**
45
- * The custom properties a theme paints with. Pushed colors are intent; the
46
- * readability engine (page-colors.ts) derives what the templates actually use.
47
- * A custom background pins a complete scheme for both OS modes — emitting
48
- * `--sf-bg` alone used to leave dark-mode visitors with the dark foreground on
49
- * the user's light background.
50
- *
51
- * Exported because the dashboard's live preview paints the same tokens from an
52
- * unsaved draft: it passes the colors it has already derived, and gets exactly
53
- * what the published page would carry.
48
+ * The custom properties a theme paints with. A custom background pins a
49
+ * complete scheme for both OS modes; `--sf-bg` alone would leave dark-mode
50
+ * visitors with the dark foreground on a light background. Exported so the
51
+ * dashboard preview paints the same tokens from an unsaved draft.
54
52
  */
55
53
  export declare function pageThemeCss(theme: PageTheme, derived?: DerivedPageColors): string;
56
54
  export declare function expandPageHtml(source: string, context: PageExpansionContext): string;
@@ -69,6 +67,19 @@ export declare const DEFAULT_PAGE_TEMPLATES: {
69
67
  index: string;
70
68
  preview: string;
71
69
  };
70
+ export declare const DEFAULT_PLATFORM_PAGE_TEMPLATES: {
71
+ login: string;
72
+ undeployed: string;
73
+ suspended: string;
74
+ legal: string;
75
+ gone: string;
76
+ "runtime-error": string;
77
+ "rate-limited": string;
78
+ "tier-unavailable": string;
79
+ "proxy-error": string;
80
+ "method-not-allowed": string;
81
+ "content-too-large": string;
82
+ };
72
83
  export declare const DEFAULT_LAYOUT_TEMPLATE: string;
73
84
  export declare function defaultPageTemplate(id: SitePageId): string;
74
85
  export declare function pageIdFromFilename(filename: string): CustomPageId | null;