@spacefast/common 0.0.5 → 0.0.7

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 (183) hide show
  1. package/brand-assets/spacefast-favicon.svg +16 -0
  2. package/brand-assets/spacefast-sf-full-bleed.svg +13 -0
  3. package/brand-assets/spacefast-wordmark.svg +5 -0
  4. package/dist/agents/connect-targets.d.ts +138 -0
  5. package/dist/agents/connect-targets.js +243 -0
  6. package/dist/brand-assets-build.d.ts +26 -0
  7. package/dist/brand-assets-build.js +81 -0
  8. package/dist/brand-assets.d.ts +42 -0
  9. package/dist/brand-assets.js +30 -0
  10. package/dist/brand.d.ts +1 -0
  11. package/dist/brand.js +5 -0
  12. package/dist/config/domains.d.ts +12 -6
  13. package/dist/config/domains.js +30 -38
  14. package/dist/contracts/access.d.ts +967 -124
  15. package/dist/contracts/access.js +804 -148
  16. package/dist/contracts/activity.d.ts +1 -1
  17. package/dist/contracts/activity.js +28 -2
  18. package/dist/contracts/annotations.d.ts +2 -4
  19. package/dist/contracts/api-keys.d.ts +126 -4
  20. package/dist/contracts/api-keys.js +74 -6
  21. package/dist/contracts/archives.d.ts +8 -2
  22. package/dist/contracts/archives.js +11 -4
  23. package/dist/contracts/billing.d.ts +0 -9
  24. package/dist/contracts/builds.d.ts +65 -21
  25. package/dist/contracts/builds.js +29 -0
  26. package/dist/contracts/common.d.ts +2 -0
  27. package/dist/contracts/common.js +4 -0
  28. package/dist/contracts/continuation.d.ts +0 -3
  29. package/dist/contracts/countries.d.ts +2 -0
  30. package/dist/contracts/countries.js +261 -0
  31. package/dist/contracts/deployments.d.ts +34 -34
  32. package/dist/contracts/device-auth.d.ts +4 -11
  33. package/dist/contracts/device-auth.js +4 -0
  34. package/dist/contracts/docs.d.ts +119 -0
  35. package/dist/contracts/docs.js +51 -0
  36. package/dist/contracts/domains.d.ts +96 -54
  37. package/dist/contracts/domains.js +26 -4
  38. package/dist/contracts/enums.d.ts +15 -16
  39. package/dist/contracts/enums.js +26 -14
  40. package/dist/contracts/error-code-meta.d.ts +184 -0
  41. package/dist/contracts/error-code-meta.js +124 -10
  42. package/dist/contracts/error-codes.d.ts +1 -1
  43. package/dist/contracts/error-codes.js +42 -0
  44. package/dist/contracts/events.d.ts +1 -1
  45. package/dist/contracts/feature-lifecycle-core.d.ts +36 -0
  46. package/dist/contracts/feature-lifecycle-core.js +220 -0
  47. package/dist/contracts/feature-lifecycle.d.ts +7 -0
  48. package/dist/contracts/feature-lifecycle.js +31 -0
  49. package/dist/contracts/features.d.ts +76 -6
  50. package/dist/contracts/features.js +178 -13
  51. package/dist/contracts/generated-feature-launch-entries.d.ts +2 -0
  52. package/dist/contracts/generated-feature-launch-entries.js +518 -0
  53. package/dist/contracts/git.d.ts +2 -8
  54. package/dist/contracts/ids.d.ts +9 -0
  55. package/dist/contracts/ids.js +13 -0
  56. package/dist/contracts/mcp.d.ts +8 -10
  57. package/dist/contracts/me.js +1 -1
  58. package/dist/contracts/oauth-resources.d.ts +19 -8
  59. package/dist/contracts/oauth-resources.js +44 -13
  60. package/dist/contracts/operations.d.ts +161 -1
  61. package/dist/contracts/operations.js +49 -1
  62. package/dist/contracts/platform.d.ts +6 -102
  63. package/dist/contracts/platform.js +6 -50
  64. package/dist/contracts/publishes.d.ts +130 -0
  65. package/dist/contracts/publishes.js +145 -0
  66. package/dist/contracts/push-new.d.ts +4 -4
  67. package/dist/contracts/quotas.d.ts +2 -0
  68. package/dist/contracts/quotas.js +8 -0
  69. package/dist/contracts/repository-connections.d.ts +9 -8
  70. package/dist/contracts/repository-connections.js +13 -0
  71. package/dist/contracts/resources.d.ts +99 -13
  72. package/dist/contracts/resources.js +36 -4
  73. package/dist/contracts/routes.d.ts +0 -2
  74. package/dist/contracts/runtime-api.d.ts +363 -39
  75. package/dist/contracts/runtime-api.js +276 -6
  76. package/dist/contracts/sf-config-v1.d.ts +75 -0
  77. package/dist/contracts/sf-config-v1.js +6 -0
  78. package/dist/contracts/sites.d.ts +19 -2
  79. package/dist/contracts/sites.js +21 -0
  80. package/dist/contracts/space-config.d.ts +201 -2
  81. package/dist/contracts/space-config.js +135 -5
  82. package/dist/contracts/spaces.d.ts +376 -196
  83. package/dist/contracts/spaces.js +62 -10
  84. package/dist/contracts/superadmin-emails.d.ts +4 -2
  85. package/dist/contracts/superadmin-emails.js +8 -0
  86. package/dist/contracts/superadmin-queues.d.ts +26 -26
  87. package/dist/contracts/superadmin-spaces.d.ts +172 -42
  88. package/dist/contracts/superadmin-tenants.d.ts +6 -6
  89. package/dist/contracts/superadmin-tenants.js +6 -11
  90. package/dist/contracts/superadmin.d.ts +6 -93
  91. package/dist/contracts/superadmin.js +6 -14
  92. package/dist/contracts/tags.d.ts +10 -9
  93. package/dist/contracts/tags.js +2 -1
  94. package/dist/contracts/teams.d.ts +26 -30
  95. package/dist/contracts/teams.js +11 -17
  96. package/dist/contracts/theme-json.d.ts +30 -0
  97. package/dist/contracts/theme-json.js +48 -0
  98. package/dist/contracts/variables.d.ts +0 -2
  99. package/dist/contracts/variables.js +0 -5
  100. package/dist/contracts/webhooks.d.ts +2 -0
  101. package/dist/contracts/webhooks.js +1 -1
  102. package/dist/contracts/zero.d.ts +5 -10
  103. package/dist/docs/agent-prose.d.ts +43 -3
  104. package/dist/docs/agent-prose.js +146 -7
  105. package/dist/docs/agent-setup.d.ts +51 -0
  106. package/dist/docs/agent-setup.js +211 -14
  107. package/dist/docs/agent-solutions.d.ts +5 -5
  108. package/dist/docs/agent-solutions.js +2 -2
  109. package/dist/docs/catalog.d.ts +650 -0
  110. package/dist/docs/catalog.js +758 -0
  111. package/dist/docs/error-docs.d.ts +0 -2
  112. package/dist/docs/error-docs.js +189 -35
  113. package/dist/docs/index-build.d.ts +17 -0
  114. package/dist/docs/index-build.js +24 -0
  115. package/dist/docs/search.d.ts +54 -0
  116. package/dist/docs/search.js +96 -0
  117. package/dist/docs/skill-distribution.d.ts +5 -3
  118. package/dist/docs/skill-distribution.js +8 -8
  119. package/dist/slug-policy/blocklist.d.ts +4 -0
  120. package/dist/slug-policy/blocklist.js +122 -0
  121. package/dist/slug-policy/index.d.ts +17 -0
  122. package/dist/slug-policy/index.js +86 -0
  123. package/dist/utils/access-match.d.ts +39 -0
  124. package/dist/utils/access-match.js +296 -0
  125. package/dist/utils/auth-redirect.d.ts +3 -1
  126. package/dist/utils/auth-redirect.js +21 -1
  127. package/dist/utils/build-settings.d.ts +6 -0
  128. package/dist/utils/build-settings.js +429 -46
  129. package/dist/utils/claim-token.d.ts +8 -0
  130. package/dist/utils/claim-token.js +23 -2
  131. package/dist/utils/concurrency.d.ts +1 -0
  132. package/dist/utils/concurrency.js +22 -0
  133. package/dist/utils/content-type.d.ts +1 -0
  134. package/dist/utils/content-type.js +1 -1
  135. package/dist/utils/credential-policy.d.ts +54 -0
  136. package/dist/utils/{access-policy.js → credential-policy.js} +28 -2
  137. package/dist/utils/email.d.ts +1 -0
  138. package/dist/utils/email.js +3 -0
  139. package/dist/utils/gate-theme.d.ts +61 -0
  140. package/dist/utils/gate-theme.js +217 -0
  141. package/dist/utils/git-repository.d.ts +0 -1
  142. package/dist/utils/git-repository.js +0 -3
  143. package/dist/utils/id-hints.d.ts +8 -0
  144. package/dist/utils/id-hints.js +61 -0
  145. package/dist/utils/local-space-state.d.ts +91 -0
  146. package/dist/utils/local-space-state.js +251 -0
  147. package/dist/utils/oauth-signed-query.d.ts +8 -0
  148. package/dist/utils/oauth-signed-query.js +26 -0
  149. package/dist/utils/publish-detection.d.ts +0 -8
  150. package/dist/utils/publish-detection.js +0 -93
  151. package/dist/utils/publish-policy.d.ts +6 -5
  152. package/dist/utils/publish-policy.js +71 -7
  153. package/dist/utils/query-keys.d.ts +16 -4
  154. package/dist/utils/query-keys.js +31 -4
  155. package/dist/utils/runtime-paths.d.ts +0 -1
  156. package/dist/utils/runtime-paths.js +0 -1
  157. package/dist/utils/runtime-upload-batch.d.ts +18 -0
  158. package/dist/utils/runtime-upload-batch.js +90 -0
  159. package/dist/utils/runtime-upload.d.ts +2 -0
  160. package/dist/utils/runtime-upload.js +5 -0
  161. package/dist/utils/sf-config-v1.d.ts +2 -0
  162. package/dist/utils/sf-config-v1.js +542 -0
  163. package/dist/utils/space-config.d.ts +4 -0
  164. package/dist/utils/space-config.js +10 -1
  165. package/dist/utils/space-theme.d.ts +2 -0
  166. package/dist/utils/space-theme.js +9 -0
  167. package/dist/utils/static-runtime-policy.d.ts +0 -21
  168. package/dist/utils/static-runtime-policy.js +19 -103
  169. package/dist/utils/upload-session.d.ts +1 -1
  170. package/dist/utils/wpcom-auth-redirects.d.ts +32 -2
  171. package/dist/utils/wpcom-auth-redirects.js +26 -10
  172. package/dist/vocabulary.d.ts +130 -30
  173. package/dist/vocabulary.js +77 -36
  174. package/package.json +35 -1
  175. package/dist/contracts/account.d.ts +0 -28
  176. package/dist/contracts/account.js +0 -54
  177. package/dist/contracts/intercom.d.ts +0 -6
  178. package/dist/contracts/intercom.js +0 -5
  179. package/dist/contracts/telemetry.d.ts +0 -2
  180. package/dist/contracts/telemetry.js +0 -1
  181. package/dist/utils/access-policy.d.ts +0 -39
  182. package/dist/utils/error-display.d.ts +0 -7
  183. package/dist/utils/error-display.js +0 -42
@@ -245,8 +245,8 @@ export declare const zeroRuntimePublicRealtimeModeSchema: z.ZodEnum<{
245
245
  "local-websocket": "local-websocket";
246
246
  }>;
247
247
  export declare const zeroInspectPolicySchema: z.ZodEnum<{
248
- private: "private";
249
248
  public: "public";
249
+ private: "private";
250
250
  }>;
251
251
  export declare const zeroRuntimePublicAuthConfigSchema: z.ZodObject<{
252
252
  provider: z.ZodDefault<z.ZodLiteral<"wpcom">>;
@@ -256,7 +256,6 @@ export declare const zeroRuntimePublicAuthConfigSchema: z.ZodObject<{
256
256
  signOutUrl: z.ZodDefault<z.ZodNullable<z.ZodString>>;
257
257
  returnToParam: z.ZodDefault<z.ZodString>;
258
258
  }, z.core.$strict>;
259
- export type ZeroRuntimePublicAuthConfig = z.infer<typeof zeroRuntimePublicAuthConfigSchema>;
260
259
  export declare const zeroRuntimePublicRealtimeConfigSchema: z.ZodObject<{
261
260
  mode: z.ZodEnum<{
262
261
  "stattic-central": "stattic-central";
@@ -275,7 +274,6 @@ export declare const zeroRuntimePublicRealtimeConfigSchema: z.ZodObject<{
275
274
  spaceId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
276
275
  versionId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
277
276
  }, z.core.$strict>;
278
- export type ZeroRuntimePublicRealtimeConfig = z.infer<typeof zeroRuntimePublicRealtimeConfigSchema>;
279
277
  export declare const zeroRuntimeClientConfigSchema: z.ZodObject<{
280
278
  runtimeKind: z.ZodLiteral<"zero">;
281
279
  basePath: z.ZodOptional<z.ZodString>;
@@ -782,8 +780,8 @@ export declare const zeroRuntimeFinalizePayloadSchema: z.ZodObject<{
782
780
  }, z.core.$strict>>;
783
781
  inspect: z.ZodDefault<z.ZodObject<{
784
782
  policy: z.ZodDefault<z.ZodEnum<{
785
- private: "private";
786
783
  public: "public";
784
+ private: "private";
787
785
  }>>;
788
786
  }, z.core.$strict>>;
789
787
  }, z.core.$strict>;
@@ -1057,8 +1055,8 @@ export declare const zeroDeployMetadataSchema: z.ZodObject<{
1057
1055
  }, z.core.$strict>>;
1058
1056
  inspect: z.ZodDefault<z.ZodObject<{
1059
1057
  policy: z.ZodDefault<z.ZodEnum<{
1060
- private: "private";
1061
1058
  public: "public";
1059
+ private: "private";
1062
1060
  }>>;
1063
1061
  }, z.core.$strict>>;
1064
1062
  }, z.core.$strict>;
@@ -1073,8 +1071,8 @@ export declare const zeroInspectResponseSchema: z.ZodObject<{
1073
1071
  serverRuntime: z.ZodLiteral<"quickjs-rust">;
1074
1072
  inspect: z.ZodObject<{
1075
1073
  policy: z.ZodEnum<{
1076
- private: "private";
1077
1074
  public: "public";
1075
+ private: "private";
1078
1076
  }>;
1079
1077
  }, z.core.$strict>;
1080
1078
  install: z.ZodObject<{
@@ -1156,8 +1154,8 @@ export declare const zeroInspectPublicResponseSchema: z.ZodObject<{
1156
1154
  serverRuntime: z.ZodLiteral<"quickjs-rust">;
1157
1155
  inspect: z.ZodObject<{
1158
1156
  policy: z.ZodEnum<{
1159
- private: "private";
1160
1157
  public: "public";
1158
+ private: "private";
1161
1159
  }>;
1162
1160
  }, z.core.$strict>;
1163
1161
  install: z.ZodObject<{
@@ -1372,7 +1370,6 @@ export declare const zeroDbDumpQuerySchema: z.ZodObject<{
1372
1370
  table: z.ZodOptional<z.ZodString>;
1373
1371
  limit: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
1374
1372
  }, z.core.$strict>;
1375
- export type ZeroDbDumpQuery = z.infer<typeof zeroDbDumpQuerySchema>;
1376
1373
  export declare const zeroDbDumpTableSchema: z.ZodObject<{
1377
1374
  name: z.ZodString;
1378
1375
  rows: z.ZodDefault<z.ZodArray<z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
@@ -1447,12 +1444,10 @@ export declare const zeroRealtimeEventIntakeResponseSchema: z.ZodObject<{
1447
1444
  delivered: z.ZodDefault<z.ZodNumber>;
1448
1445
  duplicate: z.ZodDefault<z.ZodBoolean>;
1449
1446
  }, z.core.$strict>;
1450
- export type ZeroRealtimeEventIntakeResponse = z.infer<typeof zeroRealtimeEventIntakeResponseSchema>;
1451
1447
  export declare const zeroRealtimeEventListQuerySchema: z.ZodObject<{
1452
1448
  afterEventId: z.ZodOptional<z.ZodString>;
1453
1449
  limit: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
1454
1450
  }, z.core.$strict>;
1455
- export type ZeroRealtimeEventListQuery = z.infer<typeof zeroRealtimeEventListQuerySchema>;
1456
1451
  export declare const zeroRealtimeEventListResponseSchema: z.ZodObject<{
1457
1452
  data: z.ZodArray<z.ZodObject<{
1458
1453
  eventId: z.ZodString;
@@ -1,9 +1,37 @@
1
- export declare const ARCHIVE_SECRET_GLOBS: readonly [".env*", ".npmrc", ".netrc", "*/.git/*", "*/.stattic/*", "*/.ssh/*", "*/.aws/*", "*/.kube/*", "*/.docker/*", "credentials.json", "*.pem", "*.key", "*.p12", "*.pfx", "*.crt", "*id_rsa*"];
1
+ export declare const ARCHIVE_SECRET_GLOBS: readonly [".env*", ".npmrc", ".netrc", "*/.git/*", "*/.spacefast/*", "*/.ssh/*", "*/.aws/*", "*/.kube/*", "*/.docker/*", "credentials.json", "*.pem", "*.key", "*.p12", "*.pfx", "*.crt", "*id_rsa*"];
2
2
  /**
3
3
  * The credential rules every surface must repeat. Treat tokens as secrets, keep
4
4
  * them out of logs and transcripts, and never echo them back.
5
5
  */
6
6
  export declare const SECRET_RULES_PROSE: string;
7
+ export declare const POSITIONING_PROSE: string;
8
+ export declare const EXPLAIN_TO_USER_PROSE: string;
9
+ export declare const FAILURE_CONDUCT_PROSE: string;
10
+ export declare const LANE_PICKER_PROSE: string;
11
+ export declare const HOW_TO_RESEARCH_PROSE: string;
12
+ export declare const ENV_NOTES_PROSE: string;
13
+ /**
14
+ * The CHECK verb: before ever creating a space, look for the one the project
15
+ * already has. This is what keeps a returning agent from pushing a duplicate
16
+ * anonymous space instead of a new version.
17
+ */
18
+ export declare const CHECK_BEFORE_PUBLISH_PROSE: string;
19
+ /**
20
+ * The SAVE verb: persist the space id and credential after a first publish so
21
+ * every later publish targets the same space. The CLI and On-Device MCP write
22
+ * this state automatically; curl-only agents write the same files themselves.
23
+ */
24
+ export declare const SAVE_STATE_PROSE: string;
25
+ /**
26
+ * The UPDATE verb: a new version to the SAME space. Never re-run the
27
+ * first-publish recipe when saved state exists.
28
+ */
29
+ export declare const UPDATE_SPACE_PROSE: string;
30
+ /**
31
+ * The CLAIM / CONTINUE verb: show the claim link, and after the user claims,
32
+ * self-correct by exchanging the claim token once for a durable credential.
33
+ */
34
+ export declare const CONTINUE_AFTER_CLAIM_PROSE: string;
7
35
  /**
8
36
  * The zero-install publish sequence: one curl for a file, a secret-preflighted
9
37
  * zip for a folder. This is the load-bearing rung 0 — an agent that stops here
@@ -21,15 +49,27 @@ export declare const RECEIPT_SHAPE_PROSE: string;
21
49
  */
22
50
  export declare const SIGNED_UPLOAD_PROSE: string;
23
51
  /**
24
- * Named fragments for the skill-template generator. The template carries
52
+ * Named fragments for the skill-template generator. The templates carry
25
53
  * `{{prose.secretRules}}`, `{{prose.publishSequence}}`,
26
- * `{{prose.receiptShape}}`, and `{{prose.signedUpload}}` placeholders;
54
+ * `{{prose.receiptShape}}`, `{{prose.signedUpload}}`,
55
+ * `{{prose.checkBeforePublish}}`, `{{prose.saveState}}`,
56
+ * `{{prose.updateSpace}}`, and `{{prose.continueAfterClaim}}` placeholders;
27
57
  * generate-skill.mjs substitutes these.
28
58
  */
29
59
  export declare const AGENT_PROSE: {
60
+ readonly positioning: string;
30
61
  readonly secretRules: string;
62
+ readonly explainToUser: string;
63
+ readonly failureConduct: string;
31
64
  readonly publishSequence: string;
32
65
  readonly receiptShape: string;
33
66
  readonly signedUpload: string;
67
+ readonly checkBeforePublish: string;
68
+ readonly saveState: string;
69
+ readonly updateSpace: string;
70
+ readonly continueAfterClaim: string;
71
+ readonly lanePicker: string;
72
+ readonly howToResearch: string;
73
+ readonly envNotes: string;
34
74
  };
35
75
  export type AgentProseKey = keyof typeof AGENT_PROSE;
@@ -16,6 +16,7 @@ import { BRAND } from "../brand.js";
16
16
  // the receipt shape or secret handling changes, change it here once.
17
17
  const API_ORIGIN = BRAND.apiOrigin;
18
18
  const PUBLISH_ENDPOINT = `${API_ORIGIN}/v1/publish`;
19
+ const EXCHANGE_ENDPOINT = `${API_ORIGIN}/v1/anonymous-claim/exchange`;
19
20
  // Centralized secret/credential patterns excluded from a publish archive. The
20
21
  // `find` preflight and the `zip -x` exclusions are derived from the same list so
21
22
  // they can never disagree, and the no-install / skill copies stay identical.
@@ -24,7 +25,7 @@ export const ARCHIVE_SECRET_GLOBS = [
24
25
  ".npmrc",
25
26
  ".netrc",
26
27
  "*/.git/*",
27
- "*/.stattic/*",
28
+ "*/.spacefast/*",
28
29
  "*/.ssh/*",
29
30
  "*/.aws/*",
30
31
  "*/.kube/*",
@@ -43,9 +44,18 @@ function findExpr(globs) {
43
44
  .join(" -o ");
44
45
  }
45
46
  function zipExcludeExpr(globs) {
46
- // zip uses relative patterns: a leading "*/" is just a directory match, so
47
- // collapse it to the directory glob the archive root sees.
48
- return globs.map((glob) => `"${glob.replace(/^\*\//, "")}"`).join(" ");
47
+ // zip -x patterns need both the archive-root form and an any-depth form:
48
+ // ".spacefast/*" excludes only at the root, while "*/.spacefast/*" catches
49
+ // nested copies.
50
+ return globs
51
+ .flatMap((glob) => {
52
+ if (glob.startsWith("*/")) {
53
+ return [glob.slice(2), glob];
54
+ }
55
+ return [glob, `*/${glob}`];
56
+ })
57
+ .map((glob) => `"${glob}"`)
58
+ .join(" ");
49
59
  }
50
60
  /**
51
61
  * The credential rules every surface must repeat. Treat tokens as secrets, keep
@@ -58,6 +68,121 @@ export const SECRET_RULES_PROSE = [
58
68
  "present. On shared hosts, prefer one-off environment variables or restrictive temporary files,",
59
69
  "clear them after use, and avoid durable auth unless the user explicitly asks.",
60
70
  ].join("\n");
71
+ export const POSITIONING_PROSE = [
72
+ "Spacefast is a static host for AI-made web artifacts: permanent live URLs, immutable version",
73
+ "URLs, anonymous publish with a claim link, and agent continuation after claim. It serves",
74
+ "static files. It does not execute server code, run databases, or build-on-push on the",
75
+ "anonymous lane.",
76
+ "",
77
+ "Honest comparisons an agent can relay: Vercel and Netlify are broader app platforms;",
78
+ "Cloudflare Pages is edge-first static hosting; GitHub Pages is repository-native. Spacefast",
79
+ "optimizes for agent-safe one-shot publish, claim, versioning, rollback, and continuation.",
80
+ ].join("\n");
81
+ export const EXPLAIN_TO_USER_PROSE = [
82
+ "Relay `data.shareBlurb` verbatim when present. State anonymous expiry in user terms:",
83
+ "the space expires unless claimed by `data.claim.expiresAt`. After claim, the agent key is",
84
+ "named and revocable in the dashboard.",
85
+ ].join("\n");
86
+ export const FAILURE_CONDUCT_PROSE = [
87
+ "On failure, surface `error.code`, `error.docsUrl`, and `error.requestId`, then stop.",
88
+ "Do not invent undocumented endpoints. Do not read credentials out of auth files. Do not",
89
+ "retry a one-shot operation without reusing its `Idempotency-Key`.",
90
+ ].join("\n");
91
+ export const LANE_PICKER_PROSE = [
92
+ "Pick the lane by environment: filesystem plus repeat work means CLI or On-Device MCP; no",
93
+ "filesystem means hosted MCP; one-off publish means curl; CI means an agent account. After",
94
+ "success, recommend the best next-time setup for the user's client.",
95
+ ].join("\n");
96
+ export const HOW_TO_RESEARCH_PROSE = [
97
+ "For an error, fetch `error.docsUrl`. For capability questions, use `search_docs` or append",
98
+ "`.md` to website docs URLs. For contracts, read `publish-spec.json` or OpenAPI. Never guess",
99
+ "limits: publish, then read diagnostics.",
100
+ ].join("\n");
101
+ export const ENV_NOTES_PROSE = [
102
+ "claude.ai: allow `api.spacefast.com` in egress settings. Codex sandbox: escalate only the",
103
+ "network call. Terminal agents: use the CLI when filesystem access matters.",
104
+ ].join("\n");
105
+ /**
106
+ * The CHECK verb: before ever creating a space, look for the one the project
107
+ * already has. This is what keeps a returning agent from pushing a duplicate
108
+ * anonymous space instead of a new version.
109
+ */
110
+ export const CHECK_BEFORE_PUBLISH_PROSE = [
111
+ "Before creating a space, check whether this project already has one:",
112
+ "",
113
+ "- Look for `.spacefast/space.json` or `.spacefast/state.json`, walking up from the working",
114
+ " directory toward the filesystem root.",
115
+ "- Look for a publish receipt earlier in this conversation.",
116
+ "- When authenticated, list existing spaces (`sf spaces list`, or the `spaces_list` MCP tool).",
117
+ "",
118
+ "If any of these finds a space, publish a new version to that `spaceId` (see the update",
119
+ "instructions) instead of creating another space. Only create a new space when none exists",
120
+ "and the user wants a new site.",
121
+ ].join("\n");
122
+ /**
123
+ * The SAVE verb: persist the space id and credential after a first publish so
124
+ * every later publish targets the same space. The CLI and On-Device MCP write
125
+ * this state automatically; curl-only agents write the same files themselves.
126
+ */
127
+ export const SAVE_STATE_PROSE = [
128
+ "After the first publish, persist the space id and credential so every later publish updates",
129
+ "the same space instead of creating a new one. The CLI and On-Device MCP do this automatically",
130
+ "in `.spacefast/`; when publishing with curl, write the files yourself from the receipt:",
131
+ "",
132
+ "```bash",
133
+ "mkdir -p .spacefast",
134
+ "# non-secret, committable:",
135
+ `printf '{"space":"<spc_id>"}' > .spacefast/space.json`,
136
+ "# secret — never publish, never print:",
137
+ `printf '{"spaceId":"<spc_id>","claimToken":"<token>","apiUrl":"${API_ORIGIN}"}' > .spacefast/state.json`,
138
+ "grep -qx '.spacefast/state.json' .gitignore 2>/dev/null || echo '.spacefast/state.json' >> .gitignore",
139
+ "```",
140
+ "",
141
+ "`<spc_id>` is `data.space.id` and `<token>` is `data.claim.token` from the receipt. Keep",
142
+ "`.spacefast/state.json` out of publish archives, commits, logs, and chat.",
143
+ ].join("\n");
144
+ /**
145
+ * The UPDATE verb: a new version to the SAME space. Never re-run the
146
+ * first-publish recipe when saved state exists.
147
+ */
148
+ export const UPDATE_SPACE_PROSE = [
149
+ "To publish a new version of an existing space, send the same `spaceId` with bearer auth —",
150
+ "never re-run the first-publish recipe when saved state exists:",
151
+ "",
152
+ "```bash",
153
+ 'curl -sS -H "Authorization: Bearer <claim-token-or-access-token>" \\',
154
+ " -F 'spaceId=<spc_id>' \\",
155
+ ' -F "files=@index.html" \\',
156
+ ` ${PUBLISH_ENDPOINT}`,
157
+ "```",
158
+ "",
159
+ "Use the saved claim token for an unclaimed anonymous space, or an access token for owned",
160
+ "spaces. Send a folder as `-F archive=@site.zip` exactly like a first publish; the receipt",
161
+ "shape is identical.",
162
+ ].join("\n");
163
+ /**
164
+ * The CLAIM / CONTINUE verb: show the claim link, and after the user claims,
165
+ * self-correct by exchanging the claim token once for a durable credential.
166
+ */
167
+ export const CONTINUE_AFTER_CLAIM_PROSE = [
168
+ "Always show the user the claim link (`data.claim.url`) and its expiry (`data.claim.expiresAt`).",
169
+ 'If the user says "claimed", check claim status and exchange the saved claim token; do not wait',
170
+ "for a publish failure before continuing.",
171
+ "After the user claims the space in the browser, the saved claim token stops authorizing",
172
+ "publishes: the next publish fails with error code `space_claimed_credential_available`. That",
173
+ "failure is the signal to upgrade your credential — call the exchange endpoint exactly once:",
174
+ "",
175
+ "```bash",
176
+ 'curl -sS -X POST -H "Authorization: Bearer <claim-token>" \\',
177
+ ` ${EXCHANGE_ENDPOINT}`,
178
+ "```",
179
+ "",
180
+ 'It returns `{ "data": { "space": {...}, "credential": { "accessToken": "...", "label": "..." } } }`.',
181
+ "Save `data.credential.accessToken` into `.spacefast/state.json` (replace the `claimToken`",
182
+ 'field with `"accessToken"`), then retry the publish with the new bearer. The exchange works',
183
+ "exactly once; if it returns `continuation_used` or `continuation_unavailable`, ask the user",
184
+ "to mint an access token in the dashboard (Account → Access tokens).",
185
+ ].join("\n");
61
186
  /**
62
187
  * The zero-install publish sequence: one curl for a file, a secret-preflighted
63
188
  * zip for a folder. This is the load-bearing rung 0 — an agent that stops here
@@ -102,7 +227,9 @@ export const RECEIPT_SHAPE_PROSE = [
102
227
  " always show the user the claim link and the deadline so the space becomes theirs.",
103
228
  "- `data.claim.token` — a secret capability. For anonymous spaces, use it as",
104
229
  " `Authorization: Bearer <claim-token>` when polling `data.links.status`, finalizing uploads,",
105
- " or updating the same `spaceId`.",
230
+ " or updating the same `spaceId`. Save it to `.spacefast/state.json` so the next publish",
231
+ " updates this space. After the user claims the space, exchange it once at",
232
+ ` \`POST ${EXCHANGE_ENDPOINT}\` for a durable credential.`,
106
233
  " Never print it back to the user.",
107
234
  "- `data.links.status`, `resume`, `finalize`, and `promote` — follow-up API paths.",
108
235
  "- `error.code`, `error.docsUrl`, and `error.hint` — stable error code plus exact recovery docs and a next step.",
@@ -144,14 +271,26 @@ export const SIGNED_UPLOAD_PROSE = [
144
271
  "Do not base64 large archives into chat or MCP tool arguments.",
145
272
  ].join("\n");
146
273
  /**
147
- * Named fragments for the skill-template generator. The template carries
274
+ * Named fragments for the skill-template generator. The templates carry
148
275
  * `{{prose.secretRules}}`, `{{prose.publishSequence}}`,
149
- * `{{prose.receiptShape}}`, and `{{prose.signedUpload}}` placeholders;
276
+ * `{{prose.receiptShape}}`, `{{prose.signedUpload}}`,
277
+ * `{{prose.checkBeforePublish}}`, `{{prose.saveState}}`,
278
+ * `{{prose.updateSpace}}`, and `{{prose.continueAfterClaim}}` placeholders;
150
279
  * generate-skill.mjs substitutes these.
151
280
  */
152
281
  export const AGENT_PROSE = {
282
+ positioning: POSITIONING_PROSE,
153
283
  secretRules: SECRET_RULES_PROSE,
284
+ explainToUser: EXPLAIN_TO_USER_PROSE,
285
+ failureConduct: FAILURE_CONDUCT_PROSE,
154
286
  publishSequence: PUBLISH_SEQUENCE_PROSE,
155
287
  receiptShape: RECEIPT_SHAPE_PROSE,
156
288
  signedUpload: SIGNED_UPLOAD_PROSE,
289
+ checkBeforePublish: CHECK_BEFORE_PUBLISH_PROSE,
290
+ saveState: SAVE_STATE_PROSE,
291
+ updateSpace: UPDATE_SPACE_PROSE,
292
+ continueAfterClaim: CONTINUE_AFTER_CLAIM_PROSE,
293
+ lanePicker: LANE_PICKER_PROSE,
294
+ howToResearch: HOW_TO_RESEARCH_PROSE,
295
+ envNotes: ENV_NOTES_PROSE,
157
296
  };
@@ -1,6 +1,57 @@
1
+ import { type ConnectTargetId } from "../agents/connect-targets.js";
1
2
  export declare const agentSetupUrl: string;
2
3
  export declare const agentSetupTextUrl: string;
3
4
  export declare const agentSetupHostLabel: string;
4
5
  export declare const agentSetupPrompt: string;
6
+ /**
7
+ * Typed, safe decline states for the app-private redemption exchange.
8
+ * `invalid_handoff` is the single answer for both an unknown document ID and a wrong secret, so a
9
+ * decline never becomes an existence oracle; state-specific reasons are returned only after the
10
+ * supplied secret authenticates the handoff. `already_redeemed` makes one-use explicit: after the
11
+ * first exchange succeeds, the second fails with this reason. Declines are terminal and never
12
+ * reveal whether a secret was close to correct.
13
+ */
14
+ export declare const AGENT_HANDOFF_DECLINE_REASONS: readonly ["invalid_handoff", "expired", "already_redeemed", "revoked", "client_mismatch", "origin_mismatch"];
15
+ export type AgentHandoffDeclineReason = (typeof AGENT_HANDOFF_DECLINE_REASONS)[number];
16
+ export type AgentHandoffAction = Readonly<{
17
+ kind: "copy";
18
+ label: string;
19
+ sensitive: boolean;
20
+ value: string;
21
+ }> | Readonly<{
22
+ kind: "open";
23
+ label: string;
24
+ href: string;
25
+ }>;
26
+ export type AgentHandoff = Readonly<{
27
+ actions: readonly AgentHandoffAction[];
28
+ documentUrl: string;
29
+ instructions: string;
30
+ prompt: string;
31
+ }>;
32
+ /**
33
+ * The single shared grammar for handoff links:
34
+ * `https://<app-origin>/agent/<documentId>#<secret>`. The document ID must match
35
+ * `[A-Za-z0-9_-]{1,512}` and the secret `[A-Za-z0-9_-]{16,512}` (the minimum keeps secrets
36
+ * high-entropy and makes the public-projection leak check meaningful); the two must differ;
37
+ * queries and embedded credentials are forbidden; HTTPS is required except on loopback hosts.
38
+ * Normalization is part of the contract: the input is WHATWG-URL-normalized first (backslashes,
39
+ * dot segments, stray tab/CR/LF, empty userinfo, case, default ports), the grammar is enforced on
40
+ * the normalized URL, and only the reconstructed canonical URL ever leaves this function.
41
+ * Dashboard minting, CLI ingestion, and control-plane validation must all use this parser so the
42
+ * grammar can never fork.
43
+ */
44
+ export declare function parseAgentHandoffUrl(value: string, expectedOrigin: string): Readonly<{
45
+ documentId: string;
46
+ documentUrl: string;
47
+ secret: string;
48
+ }>;
49
+ /** Builds every copy-ready handoff artifact from one validated URL and target catalog row. */
50
+ export declare function buildAgentHandoff(input: {
51
+ expectedOrigin: string;
52
+ mcpEndpoint: string;
53
+ targetId: ConnectTargetId;
54
+ url: string;
55
+ }): AgentHandoff;
5
56
  export declare function renderAgentSetupTemplate(value: string): string;
6
57
  export declare function aiInstructionsText(): string;