@spacefast/common 0.0.13 → 0.0.17

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 (154) hide show
  1. package/dist/agents/client-registry.d.ts +22 -0
  2. package/dist/agents/client-registry.js +41 -0
  3. package/dist/agents/connect-targets.d.ts +51 -6
  4. package/dist/agents/connect-targets.js +93 -28
  5. package/dist/brand.d.ts +0 -11
  6. package/dist/brand.js +0 -20
  7. package/dist/config/domains.d.ts +15 -6
  8. package/dist/config/domains.js +24 -10
  9. package/dist/config/postgres-budget.d.ts +3 -0
  10. package/dist/config/postgres-budget.js +6 -1
  11. package/dist/config/postgres-budget.json +2 -1
  12. package/dist/contracts/abuse.js +1 -1
  13. package/dist/contracts/access.d.ts +149 -44
  14. package/dist/contracts/access.js +94 -8
  15. package/dist/contracts/activity.js +5 -1
  16. package/dist/contracts/api-keys.js +9 -9
  17. package/dist/contracts/archives.js +11 -11
  18. package/dist/contracts/beta.js +1 -1
  19. package/dist/contracts/builds.js +14 -14
  20. package/dist/contracts/channels.js +2 -2
  21. package/dist/contracts/comments.d.ts +86 -15
  22. package/dist/contracts/comments.js +116 -20
  23. package/dist/contracts/common.d.ts +12 -12
  24. package/dist/contracts/common.js +33 -30
  25. package/dist/contracts/continuation.js +5 -5
  26. package/dist/contracts/data-source-routes.js +1 -1
  27. package/dist/contracts/device-auth.d.ts +6 -6
  28. package/dist/contracts/device-auth.js +12 -12
  29. package/dist/contracts/docs.d.ts +10 -10
  30. package/dist/contracts/domains.js +39 -33
  31. package/dist/contracts/enums.d.ts +2 -10
  32. package/dist/contracts/enums.js +0 -2
  33. package/dist/contracts/error-code-meta.d.ts +116 -47
  34. package/dist/contracts/error-code-meta.js +37 -16
  35. package/dist/contracts/error-codes.d.ts +7 -4
  36. package/dist/contracts/error-codes.js +46 -21
  37. package/dist/contracts/events.d.ts +10 -3
  38. package/dist/contracts/events.js +33 -5
  39. package/dist/contracts/execution.d.ts +26 -0
  40. package/dist/contracts/execution.js +21 -0
  41. package/dist/contracts/feature-lifecycle.d.ts +21 -24
  42. package/dist/contracts/feature-lifecycle.js +28 -26
  43. package/dist/contracts/features.js +4 -4
  44. package/dist/contracts/functions.d.ts +8 -140
  45. package/dist/contracts/functions.js +9 -19
  46. package/dist/contracts/git.d.ts +1 -1
  47. package/dist/contracts/grants.d.ts +96 -79
  48. package/dist/contracts/grants.js +130 -43
  49. package/dist/contracts/ids.d.ts +2 -2
  50. package/dist/contracts/ids.js +2 -4
  51. package/dist/contracts/internal.js +2 -2
  52. package/dist/contracts/mcp.d.ts +17 -556
  53. package/dist/contracts/mcp.js +9 -103
  54. package/dist/contracts/me.js +3 -4
  55. package/dist/contracts/notifications.d.ts +108 -0
  56. package/dist/contracts/notifications.js +54 -0
  57. package/dist/contracts/oauth-resources.d.ts +18 -1
  58. package/dist/contracts/oauth-resources.js +22 -2
  59. package/dist/contracts/operations.d.ts +2 -50
  60. package/dist/contracts/operations.js +0 -19
  61. package/dist/contracts/pages.d.ts +8 -4
  62. package/dist/contracts/pages.js +16 -3
  63. package/dist/contracts/platform.js +10 -8
  64. package/dist/contracts/problem-document.d.ts +14 -0
  65. package/dist/contracts/problem-document.js +35 -0
  66. package/dist/contracts/push-new.d.ts +21 -6
  67. package/dist/contracts/push-new.js +3 -7
  68. package/dist/contracts/resources.d.ts +8 -7
  69. package/dist/contracts/resources.js +9 -6
  70. package/dist/contracts/runtime-api.d.ts +162 -92
  71. package/dist/contracts/runtime-api.js +99 -27
  72. package/dist/contracts/runtime-app.d.ts +41 -11
  73. package/dist/contracts/runtime-app.js +22 -1
  74. package/dist/contracts/runtime-db.d.ts +424 -0
  75. package/dist/contracts/runtime-db.js +108 -0
  76. package/dist/contracts/runtime-storage.d.ts +120 -0
  77. package/dist/contracts/runtime-storage.js +40 -0
  78. package/dist/contracts/sf-config-v1.d.ts +49 -1
  79. package/dist/contracts/sf-config-v1.js +2 -2
  80. package/dist/contracts/sites.d.ts +1 -0
  81. package/dist/contracts/sites.js +20 -12
  82. package/dist/contracts/space-config.d.ts +62 -22
  83. package/dist/contracts/space-config.js +173 -47
  84. package/dist/contracts/spaces.d.ts +79 -45
  85. package/dist/contracts/spaces.js +66 -50
  86. package/dist/contracts/superadmin-spaces.d.ts +13 -2
  87. package/dist/contracts/superadmin-spaces.js +15 -0
  88. package/dist/contracts/superadmin-tenants.js +4 -4
  89. package/dist/contracts/superadmin.d.ts +4 -0
  90. package/dist/contracts/superadmin.js +14 -1
  91. package/dist/contracts/tags.d.ts +17 -17
  92. package/dist/contracts/tags.js +1 -1
  93. package/dist/contracts/teams.js +25 -16
  94. package/dist/contracts/theme-json.js +1 -1
  95. package/dist/contracts/transfers.js +4 -4
  96. package/dist/contracts/variables.js +3 -3
  97. package/dist/contracts/zero.d.ts +204 -338
  98. package/dist/contracts/zero.js +94 -98
  99. package/dist/dashboard-paths/index.d.ts +16 -1
  100. package/dist/dashboard-paths/index.js +18 -0
  101. package/dist/docs/agent-handoff-document.d.ts +2 -2
  102. package/dist/docs/agent-handoff-document.js +8 -7
  103. package/dist/docs/agent-prose.d.ts +22 -3
  104. package/dist/docs/agent-prose.js +221 -51
  105. package/dist/docs/agent-setup.d.ts +13 -10
  106. package/dist/docs/agent-setup.js +279 -53
  107. package/dist/docs/agent-solutions.d.ts +6 -6
  108. package/dist/docs/agent-solutions.js +23 -21
  109. package/dist/docs/catalog.d.ts +29 -74
  110. package/dist/docs/catalog.js +65 -92
  111. package/dist/docs/error-docs.js +293 -221
  112. package/dist/docs/skill-distribution.d.ts +2 -0
  113. package/dist/docs/skill-distribution.js +7 -4
  114. package/dist/docs/skills.d.ts +546 -0
  115. package/dist/docs/skills.js +340 -0
  116. package/dist/utils/browser-credential.d.ts +19 -0
  117. package/dist/utils/browser-credential.js +62 -0
  118. package/dist/utils/comment-avatars.d.ts +7 -0
  119. package/dist/utils/comment-avatars.js +42 -0
  120. package/dist/utils/content-type.d.ts +3 -3
  121. package/dist/utils/content-type.js +38 -61
  122. package/dist/utils/domain-diagnostics.d.ts +5 -5
  123. package/dist/utils/domain-diagnostics.js +21 -10
  124. package/dist/utils/local-space-state.d.ts +78 -4
  125. package/dist/utils/local-space-state.js +383 -82
  126. package/dist/utils/one-shot-replay.d.ts +14 -0
  127. package/dist/utils/one-shot-replay.js +21 -0
  128. package/dist/utils/page-preview.d.ts +7 -0
  129. package/dist/utils/page-preview.js +9 -0
  130. package/dist/utils/pages.d.ts +2 -11
  131. package/dist/utils/pages.js +58 -14
  132. package/dist/utils/publish-form-data.d.ts +22 -0
  133. package/dist/utils/publish-form-data.js +26 -0
  134. package/dist/utils/publish-policy.js +20 -4
  135. package/dist/utils/query-keys.d.ts +7 -4
  136. package/dist/utils/query-keys.js +13 -4
  137. package/dist/utils/runtime-paths.d.ts +3 -0
  138. package/dist/utils/runtime-paths.js +7 -0
  139. package/dist/utils/secure-local-file.d.ts +73 -0
  140. package/dist/utils/secure-local-file.js +1373 -0
  141. package/dist/utils/space-config.d.ts +13 -4
  142. package/dist/utils/space-config.js +123 -15
  143. package/dist/utils/storage-policy.d.ts +20 -0
  144. package/dist/utils/storage-policy.fixtures.json +174 -0
  145. package/dist/utils/storage-policy.js +193 -0
  146. package/dist/utils/upload-session.d.ts +12 -1
  147. package/dist/utils/upload-session.js +37 -2
  148. package/dist/utils/version-file-browser.d.ts +13 -0
  149. package/dist/utils/version-file-browser.js +59 -0
  150. package/package.json +19 -1
  151. package/dist/contracts/mounts.d.ts +0 -142
  152. package/dist/contracts/mounts.js +0 -56
  153. package/dist/utils/asset-fingerprint.d.ts +0 -64
  154. package/dist/utils/asset-fingerprint.js +0 -620
@@ -0,0 +1,22 @@
1
+ export declare const MACHINE_AGENT_CLIENT_IDS: readonly ["universal", "claude-code", "codex", "opencode", "github-copilot", "factory-droid", "cursor", "vscode", "gemini-cli", "windsurf", "cline", "continue"];
2
+ export declare const CONNECT_TARGET_IDS: readonly ["claude-code", "cursor", "vscode", "codex", "claude", "chatgpt"];
3
+ export type MachineAgentClientId = (typeof MACHINE_AGENT_CLIENT_IDS)[number];
4
+ export type ConnectTargetId = (typeof CONNECT_TARGET_IDS)[number];
5
+ export type AgentProductId = MachineAgentClientId | ConnectTargetId;
6
+ export declare const AGENT_PRODUCT_NAMES: {
7
+ readonly universal: "Universal (.agents)";
8
+ readonly "claude-code": "Claude Code";
9
+ readonly codex: "Codex";
10
+ readonly cursor: "Cursor";
11
+ readonly vscode: "VS Code";
12
+ readonly "github-copilot": "GitHub Copilot";
13
+ readonly "factory-droid": "Factory Droid";
14
+ readonly opencode: "OpenCode";
15
+ readonly "gemini-cli": "Gemini CLI";
16
+ readonly windsurf: "Windsurf";
17
+ readonly cline: "Cline";
18
+ readonly continue: "Continue";
19
+ readonly claude: "Claude";
20
+ readonly chatgpt: "ChatGPT";
21
+ };
22
+ export declare function agentProductName(id: AgentProductId): string;
@@ -0,0 +1,41 @@
1
+ export const MACHINE_AGENT_CLIENT_IDS = [
2
+ "universal",
3
+ "claude-code",
4
+ "codex",
5
+ "opencode",
6
+ "github-copilot",
7
+ "factory-droid",
8
+ "cursor",
9
+ "vscode",
10
+ "gemini-cli",
11
+ "windsurf",
12
+ "cline",
13
+ "continue",
14
+ ];
15
+ export const CONNECT_TARGET_IDS = [
16
+ "claude-code",
17
+ "cursor",
18
+ "vscode",
19
+ "codex",
20
+ "claude",
21
+ "chatgpt",
22
+ ];
23
+ export const AGENT_PRODUCT_NAMES = {
24
+ universal: "Universal (.agents)",
25
+ "claude-code": "Claude Code",
26
+ codex: "Codex",
27
+ cursor: "Cursor",
28
+ vscode: "VS Code",
29
+ "github-copilot": "GitHub Copilot",
30
+ "factory-droid": "Factory Droid",
31
+ opencode: "OpenCode",
32
+ "gemini-cli": "Gemini CLI",
33
+ windsurf: "Windsurf",
34
+ cline: "Cline",
35
+ continue: "Continue",
36
+ claude: "Claude",
37
+ chatgpt: "ChatGPT",
38
+ };
39
+ export function agentProductName(id) {
40
+ return AGENT_PRODUCT_NAMES[id];
41
+ }
@@ -1,7 +1,10 @@
1
+ import { type ConnectTargetId } from "./client-registry.js";
2
+ export { CONNECT_TARGET_IDS } from "./client-registry.js";
3
+ export type { ConnectTargetId } from "./client-registry.js";
1
4
  export declare const LOCAL_MCP_PACKAGE = "spacefast";
2
5
  export declare const LOCAL_MCP_COMMAND = "npx";
3
- export declare const LOCAL_MCP_ARGS: readonly ["-y", "spacefast", "mcp", "--preset", "essential"];
4
- /** The copy-paste one-liner form with the lean default tool surface. */
6
+ export declare const LOCAL_MCP_ARGS: readonly ["-y", "spacefast", "mcp"];
7
+ /** The copy-paste one-liner for the fixed On-Device product surface. */
5
8
  export declare const LOCAL_MCP_COMMAND_LINE: string;
6
9
  /**
7
10
  * base64 of a UTF-8 string, without Buffer. Byte-identical to
@@ -14,7 +17,7 @@ export declare function localMcpServersJson(): {
14
17
  mcpServers: {
15
18
  spacefast: {
16
19
  command: string;
17
- args: ("mcp" | "essential" | "spacefast" | "-y" | "--preset")[];
20
+ args: ("mcp" | "spacefast" | "-y")[];
18
21
  env: {};
19
22
  };
20
23
  };
@@ -30,12 +33,30 @@ export declare function vscodeMcpServersJson(): {
30
33
  spacefast: {
31
34
  type: string;
32
35
  command: string;
33
- args: ("mcp" | "essential" | "spacefast" | "-y" | "--preset")[];
36
+ args: ("mcp" | "spacefast" | "-y")[];
34
37
  };
35
38
  };
36
39
  };
37
40
  export declare function cursorHostedMcpDeeplink(mcpEndpoint: string): string;
38
41
  export declare function vscodeHostedMcpDeeplink(mcpEndpoint: string): string;
42
+ export declare function pokeHostedMcpDeeplink(mcpEndpoint: string): string;
43
+ /**
44
+ * The hosted server entry for the Pi coding agent's `pi-mcp-extension`
45
+ * (`~/.pi/agent/mcp.json` or a project `.pi/mcp.json`). Pi has no built-in
46
+ * MCP; the extension (`pi install npm:pi-mcp-extension`) adds it with a
47
+ * `transport: "streamable-http"` entry — its own key names, not the
48
+ * `type: "http"` shape Claude Code and VS Code use.
49
+ */
50
+ export declare function piHostedMcpConfig(mcpEndpoint: string): {
51
+ mcpServers: {
52
+ spacefast: {
53
+ transport: string;
54
+ url: string;
55
+ };
56
+ };
57
+ };
58
+ export declare function claudeHostedConnectorInstallUrl(mcpEndpoint: string): string;
59
+ export declare function claudeOrgConnectorInstallUrl(mcpEndpoint: string): string;
39
60
  /**
40
61
  * The hosted server entry for Claude Code's `.mcp.json`. Claude Code rejects a
41
62
  * bare `{ url }` as invalid, so the entry carries `type: "http"` — byte-identical
@@ -72,6 +93,18 @@ export declare function vscodeHostedMcpServersJson(mcpEndpoint: string): {
72
93
  };
73
94
  };
74
95
  };
96
+ /** A complete, schema-pinned OpenCode V2 config for the hosted MCP server. */
97
+ export declare function opencodeHostedMcpConfig(mcpEndpoint: string): {
98
+ $schema: string;
99
+ mcp: {
100
+ servers: {
101
+ spacefast: {
102
+ type: string;
103
+ url: string;
104
+ };
105
+ };
106
+ };
107
+ };
75
108
  export declare function codexHostedMcpToml(mcpEndpoint: string): string;
76
109
  export declare const CODEX_MCP_TOML: string;
77
110
  /**
@@ -86,6 +119,20 @@ export declare function buildClaudeMcpAddCommand(mcpEndpoint: string): string;
86
119
  * connection unauthenticated and the tools 401.
87
120
  */
88
121
  export declare function buildCodexMcpAddCommand(mcpEndpoint: string): string;
122
+ /**
123
+ * Hermes's hosted-MCP connect (`hermes mcp add --url`), the form NousResearch's
124
+ * hermes-agent MCP guide documents. `--auth oauth` opts the hosted server into
125
+ * the browser sign-in flow; unlike Codex there is no separate login command.
126
+ */
127
+ export declare function buildHermesMcpAddCommand(mcpEndpoint: string): string;
128
+ /**
129
+ * OpenClaw's hosted-MCP connect (`openclaw mcp add`), the form
130
+ * docs.openclaw.ai/cli/mcp documents: `--transport streamable-http` is required
131
+ * (no auto-detection), `--auth oauth` opts into OAuth. Sign-in is a separate
132
+ * two-step `openclaw mcp login <name>` (prints an auth URL, then `--code`), so
133
+ * setup copy must not promise a single-command flow.
134
+ */
135
+ export declare function buildOpenclawMcpAddCommand(mcpEndpoint: string): string;
89
136
  export type ConnectCopyLanguage = "bash" | "json" | "toml" | "text";
90
137
  export type ConnectCopy = Readonly<{
91
138
  /** Short label for the affordance and the copied-value toast. */
@@ -108,8 +155,6 @@ export type ConnectDownload = Readonly<{
108
155
  * a copy of the command/endpoint that wires it), plus an optional secondary
109
156
  * "copy the client config file" affordance.
110
157
  */
111
- export declare const CONNECT_TARGET_IDS: readonly ["claude-code", "cursor", "vscode", "codex", "claude", "chatgpt"];
112
- export type ConnectTargetId = (typeof CONNECT_TARGET_IDS)[number];
113
158
  export type ConnectTarget = Readonly<{
114
159
  id: ConnectTargetId;
115
160
  name: string;
@@ -4,7 +4,7 @@
4
4
  * One source of truth for "add Spacefast to your agent": the MCP launch config,
5
5
  * the one-click deeplinks, and the per-agent connect entries. Both the marketing
6
6
  * site (apps/www/src/lib/llmo.ts + agent-targets.ts, with the hardcoded prod
7
- * endpoint) and the dashboard (apps/my /account/agents, with the runtime-derived
7
+ * endpoint) and the Team Developer dashboard (with the runtime-derived
8
8
  * hosted endpoint) consume these, so every "connect an agent" surface advertises
9
9
  * the identical command, package, and config — they can never drift apart.
10
10
  *
@@ -13,10 +13,12 @@
13
13
  * standard in browsers, Node 16+, and Bun) rather than Buffer.
14
14
  */
15
15
  import { spacefastClaudePluginAddCommand, spacefastClaudePluginInstallCommand, spacefastCodexPluginAddCommand, spacefastCodexPluginInstallCommand, } from "../docs/skill-distribution.js";
16
+ import { agentProductName } from "./client-registry.js";
17
+ export { CONNECT_TARGET_IDS } from "./client-registry.js";
16
18
  export const LOCAL_MCP_PACKAGE = "spacefast";
17
19
  export const LOCAL_MCP_COMMAND = "npx";
18
- export const LOCAL_MCP_ARGS = ["-y", LOCAL_MCP_PACKAGE, "mcp", "--preset", "essential"];
19
- /** The copy-paste one-liner form with the lean default tool surface. */
20
+ export const LOCAL_MCP_ARGS = ["-y", LOCAL_MCP_PACKAGE, "mcp"];
21
+ /** The copy-paste one-liner for the fixed On-Device product surface. */
20
22
  export const LOCAL_MCP_COMMAND_LINE = `${LOCAL_MCP_COMMAND} ${LOCAL_MCP_ARGS.join(" ")}`;
21
23
  /**
22
24
  * base64 of a UTF-8 string, without Buffer. Byte-identical to
@@ -65,7 +67,7 @@ export function vscodeMcpServersJson() {
65
67
  * on-device for local ones — but a one-click install must never depend on the
66
68
  * user having npm/npx. The hosted URL server needs no runtime at all (the
67
69
  * client speaks HTTP + OAuth), so every deeplink and every primary action
68
- * carries the hosted endpoint. On-device stdio (`npx -y spacefast mcp --preset essential`) stays
70
+ * carries the hosted endpoint. On-device stdio (`npx -y spacefast mcp`) stays
69
71
  * available as the explicitly-labeled alternative for people who run the CLI —
70
72
  * their environment already provides npx.
71
73
  */
@@ -77,13 +79,57 @@ export function vscodeMcpServersJson() {
77
79
  export function cursorHostedMcpDeeplink(mcpEndpoint) {
78
80
  return `https://cursor.com/install-mcp?name=${LOCAL_MCP_PACKAGE}&config=${encodeURIComponent(base64Utf8(JSON.stringify({ url: mcpEndpoint })))}`;
79
81
  }
80
- // VS Code one-click MCP install link — the HTTPS redirect service GitHub's
81
- // install badges use, which works for stable VS Code (not just Insiders). The
82
- // config is the server object WITHOUT the name (name is the query param), and
83
- // `type: "http"` is mandatory — VS Code treats a bare `url` as a stdio command
84
- // and fails confusingly.
82
+ // VS Code one-click MCP install link — the HTTPS redirect service, which 302s
83
+ // into the documented `vscode:mcp/install?<uriencoded JSON>` URL handler. Host
84
+ // is `vscode.dev` (NOT the badge-era `insiders.vscode.dev`, which emits the
85
+ // same stable-VS-Code Location header today but reads as "insiders" to users
86
+ // and breaks if the redirect ever honors its host). The config is the server
87
+ // object WITHOUT the name (the service merges the `name` param into the JSON),
88
+ // plain URI-encoded — base64 is Cursor's rule, not VS Code's. `type: "http"`
89
+ // is mandatory: VS Code treats a bare `url` as a stdio command and fails
90
+ // confusingly.
85
91
  export function vscodeHostedMcpDeeplink(mcpEndpoint) {
86
- return `https://insiders.vscode.dev/redirect/mcp/install?name=${LOCAL_MCP_PACKAGE}&config=${encodeURIComponent(JSON.stringify({ type: "http", url: mcpEndpoint }))}`;
92
+ return `https://vscode.dev/redirect/mcp/install?name=${LOCAL_MCP_PACKAGE}&config=${encodeURIComponent(JSON.stringify({ type: "http", url: mcpEndpoint }))}`;
93
+ }
94
+ // Poke one-click MCP install link — a plain HTTPS page that prefills the
95
+ // new-integration form (https://poke.com/docs/mcp-servers): ordinary
96
+ // URI-encoded query params, no JSON blob, no base64. All params stay
97
+ // user-editable in the form; the user reviews and hits Create. `apiKey` is
98
+ // also accepted but must NEVER appear in a public link — our hosted server
99
+ // authenticates via OAuth.
100
+ export function pokeHostedMcpDeeplink(mcpEndpoint) {
101
+ return `https://poke.com/integrations/new?name=Spacefast&url=${encodeURIComponent(mcpEndpoint)}`;
102
+ }
103
+ /**
104
+ * The hosted server entry for the Pi coding agent's `pi-mcp-extension`
105
+ * (`~/.pi/agent/mcp.json` or a project `.pi/mcp.json`). Pi has no built-in
106
+ * MCP; the extension (`pi install npm:pi-mcp-extension`) adds it with a
107
+ * `transport: "streamable-http"` entry — its own key names, not the
108
+ * `type: "http"` shape Claude Code and VS Code use.
109
+ */
110
+ export function piHostedMcpConfig(mcpEndpoint) {
111
+ return {
112
+ mcpServers: {
113
+ [LOCAL_MCP_PACKAGE]: { transport: "streamable-http", url: mcpEndpoint },
114
+ },
115
+ };
116
+ }
117
+ // Claude custom-connector install link — opens claude.ai's "Add custom
118
+ // connector" dialog with name and URL prefilled (documented under "Share an
119
+ // install link", claude.com/docs/connectors/building/directory-vs-custom).
120
+ // Plain percent-encoded params, no JSON blob; the dialog shows the values came
121
+ // from an external link and the user confirms before anything is added. The
122
+ // connector then syncs to every Claude client (web, Desktop, mobile). Signed-out
123
+ // users get the sign-in first, then land on the prefilled dialog.
124
+ export function claudeHostedConnectorInstallUrl(mcpEndpoint) {
125
+ return `https://claude.ai/customize/connectors?modal=add-custom-connector&connectorName=Spacefast&connectorUrl=${encodeURIComponent(mcpEndpoint)}`;
126
+ }
127
+ // The same documented params on the admin path: prefills the ORG-WIDE custom
128
+ // connector dialog for Team/Enterprise Owners. Adding it org-wide connects
129
+ // nobody by itself — each member still clicks Connect on the rolled-out
130
+ // connector — so copy around this link must address the admin, not the member.
131
+ export function claudeOrgConnectorInstallUrl(mcpEndpoint) {
132
+ return `https://claude.ai/admin-settings/connectors?modal=add-custom-connector&connectorName=Spacefast&connectorUrl=${encodeURIComponent(mcpEndpoint)}`;
87
133
  }
88
134
  /**
89
135
  * The hosted server entry for Claude Code's `.mcp.json`. Claude Code rejects a
@@ -119,6 +165,20 @@ export function vscodeHostedMcpServersJson(mcpEndpoint) {
119
165
  },
120
166
  };
121
167
  }
168
+ /** A complete, schema-pinned OpenCode V2 config for the hosted MCP server. */
169
+ export function opencodeHostedMcpConfig(mcpEndpoint) {
170
+ return {
171
+ $schema: "https://opencode.ai/config.json",
172
+ mcp: {
173
+ servers: {
174
+ [LOCAL_MCP_PACKAGE]: {
175
+ type: "remote",
176
+ url: mcpEndpoint,
177
+ },
178
+ },
179
+ },
180
+ };
181
+ }
122
182
  // Codex reads MCP servers from `~/.codex/config.toml`; the hosted entry is a
123
183
  // bare streamable-HTTP url (same lane the committed codex plugin ships).
124
184
  export function codexHostedMcpToml(mcpEndpoint) {
@@ -147,18 +207,23 @@ export function buildCodexMcpAddCommand(mcpEndpoint) {
147
207
  return `codex mcp add ${LOCAL_MCP_PACKAGE} --url ${mcpEndpoint} && codex mcp login ${LOCAL_MCP_PACKAGE}`;
148
208
  }
149
209
  /**
150
- * A single connect card: one agent, one primary action (a one-click deeplink or
151
- * a copy of the command/endpoint that wires it), plus an optional secondary
152
- * "copy the client config file" affordance.
210
+ * Hermes's hosted-MCP connect (`hermes mcp add --url`), the form NousResearch's
211
+ * hermes-agent MCP guide documents. `--auth oauth` opts the hosted server into
212
+ * the browser sign-in flow; unlike Codex there is no separate login command.
153
213
  */
154
- export const CONNECT_TARGET_IDS = [
155
- "claude-code",
156
- "cursor",
157
- "vscode",
158
- "codex",
159
- "claude",
160
- "chatgpt",
161
- ];
214
+ export function buildHermesMcpAddCommand(mcpEndpoint) {
215
+ return `hermes mcp add ${LOCAL_MCP_PACKAGE} --url ${mcpEndpoint} --auth oauth`;
216
+ }
217
+ /**
218
+ * OpenClaw's hosted-MCP connect (`openclaw mcp add`), the form
219
+ * docs.openclaw.ai/cli/mcp documents: `--transport streamable-http` is required
220
+ * (no auto-detection), `--auth oauth` opts into OAuth. Sign-in is a separate
221
+ * two-step `openclaw mcp login <name>` (prints an auth URL, then `--code`), so
222
+ * setup copy must not promise a single-command flow.
223
+ */
224
+ export function buildOpenclawMcpAddCommand(mcpEndpoint) {
225
+ return `openclaw mcp add ${LOCAL_MCP_PACKAGE} --url ${mcpEndpoint} --transport streamable-http --auth oauth`;
226
+ }
162
227
  /**
163
228
  * The per-agent connect catalog, parameterized by the hosted MCP endpoint.
164
229
  * Every one-click and copy-config path carries the hosted endpoint (OAuth,
@@ -175,7 +240,7 @@ export function buildConnectTargets({ mcpEndpoint }) {
175
240
  // and stays updated through the marketplace. `claude mcp add` remains
176
241
  // the minimal MCP-only path in the config slot and on /agents.
177
242
  id: "claude-code",
178
- name: "Claude Code",
243
+ name: agentProductName("claude-code"),
179
244
  blurb: "One paste installs the plugin: publish skill plus MCP, updated from the marketplace.",
180
245
  primary: {
181
246
  label: "Install plugin",
@@ -190,21 +255,21 @@ export function buildConnectTargets({ mcpEndpoint }) {
190
255
  },
191
256
  {
192
257
  id: "cursor",
193
- name: "Cursor",
194
- blurb: "One click adds hosted MCP. OAuth sign-in, nothing to install.",
258
+ name: agentProductName("cursor"),
259
+ blurb: "One click adds hosted MCP. Approve once in the browser, nothing to install.",
195
260
  deeplink: { href: cursorHostedMcpDeeplink(mcpEndpoint), label: "Add to Cursor" },
196
261
  config: { label: "~/.cursor/mcp.json", value: cursorConfigJson, language: "json" },
197
262
  },
198
263
  {
199
264
  id: "vscode",
200
- name: "VS Code",
265
+ name: agentProductName("vscode"),
201
266
  blurb: "One click adds hosted MCP for Copilot agent mode.",
202
267
  deeplink: { href: vscodeHostedMcpDeeplink(mcpEndpoint), label: "Add to VS Code" },
203
268
  config: { label: ".vscode/mcp.json", value: vscodeHostedConfigJson, language: "json" },
204
269
  },
205
270
  {
206
271
  id: "codex",
207
- name: "Codex",
272
+ name: agentProductName("codex"),
208
273
  blurb: "One paste installs the plugin: publish skill plus MCP, updated from the marketplace.",
209
274
  primary: {
210
275
  label: "Install plugin",
@@ -219,7 +284,7 @@ export function buildConnectTargets({ mcpEndpoint }) {
219
284
  },
220
285
  {
221
286
  id: "claude",
222
- name: "Claude",
287
+ name: agentProductName("claude"),
223
288
  blurb: "Settings → Connectors → Add custom connector, paste this endpoint. Or grab the desktop extension.",
224
289
  primary: { label: "MCP endpoint", value: mcpEndpoint, language: "text" },
225
290
  download: {
@@ -229,7 +294,7 @@ export function buildConnectTargets({ mcpEndpoint }) {
229
294
  },
230
295
  {
231
296
  id: "chatgpt",
232
- name: "ChatGPT",
297
+ name: agentProductName("chatgpt"),
233
298
  blurb: "Turn on Developer mode (Settings → Apps & Connectors → Advanced), then Connectors → Create with this endpoint.",
234
299
  primary: { label: "MCP endpoint", value: mcpEndpoint, language: "text" },
235
300
  },
package/dist/brand.d.ts CHANGED
@@ -1,16 +1,5 @@
1
1
  export declare const BRAND: {
2
2
  /** Consumer product name shown on every user surface. */
3
3
  readonly productName: "Spacefast";
4
- /** Public website/docs origin (`/docs`, `/llms.txt`, install script). */
5
- readonly websiteOrigin: string;
6
- /** Origin agents should fetch for the canonical `/ai` setup instructions. */
7
- readonly agentSetupOrigin: string;
8
- /** Canonical public API origin (generated SDK/OpenAPI server, `/skill`). */
9
- readonly apiOrigin: string;
10
- /** Apex for default space hostnames: `{hostLabel}.<apex>` (OPEN apex decision). */
11
- readonly spaceHostnameApex: "view.fast";
12
- /** Apex for internal management hostnames: `{siteId}.<apex>` (OPEN apex decision). */
13
- readonly managementHostnameApex: "view.fast";
14
4
  };
15
- export declare const ERROR_DOCS_BASE_URL: `${string}/docs/errors`;
16
5
  export declare const GITHUB_CHECK_RUN_NAME: "Spacefast Builds";
package/dist/brand.js CHANGED
@@ -1,27 +1,7 @@
1
- // The single home for brand strings. Hostnames are NOT hardcoded here: they
2
- // derive from the canonical domain registry (`./config/domains`) so the whole
3
- // rename to spacefast.com is a one-file edit. Consumer surfaces never hardcode
4
- // these values; they import from here (and `domains` underneath).
5
- import { serviceOrigin } from "./config/domains.js";
6
- import { MANAGEMENT_HOSTNAME_APEX, SPACE_HOSTNAME_APEX } from "./config/domains.js";
7
1
  export const BRAND = {
8
2
  /** Consumer product name shown on every user surface. */
9
3
  productName: "Spacefast",
10
- /** Public website/docs origin (`/docs`, `/llms.txt`, install script). */
11
- websiteOrigin: serviceOrigin("www", "prod"),
12
- /** Origin agents should fetch for the canonical `/ai` setup instructions. */
13
- agentSetupOrigin: serviceOrigin("www", "prod"),
14
- /** Canonical public API origin (generated SDK/OpenAPI server, `/skill`). */
15
- apiOrigin: serviceOrigin("api", "prod"),
16
- /** Apex for default space hostnames: `{hostLabel}.<apex>` (OPEN apex decision). */
17
- spaceHostnameApex: SPACE_HOSTNAME_APEX,
18
- /** Apex for internal management hostnames: `{siteId}.<apex>` (OPEN apex decision). */
19
- managementHostnameApex: MANAGEMENT_HOSTNAME_APEX,
20
4
  };
21
- // Mechanical error-docs derivation base (contract decision locked by the build
22
- // plan: `${websiteOrigin}/docs/errors/{code}` forever). Lives next to the
23
- // brand origin it derives from; `error-codes.ts` consumes it.
24
- export const ERROR_DOCS_BASE_URL = `${BRAND.websiteOrigin}/docs/errors`;
25
5
  // The GitHub check-run name every build reports under. One constant because the
26
6
  // create and update paths live in different modules and drifted once
27
7
  // ("Stattic" vs "Spacefast") — GitHub keys check runs by name, so a mismatch
@@ -26,11 +26,20 @@ export declare const DEV_ENV_DOMAIN: "sf.localhost";
26
26
  export declare function envDomainsFor(domain: string): EnvDomains;
27
27
  /** Origin (scheme + host, no trailing slash) for a service in an environment. */
28
28
  export declare function serviceOrigin(service: Service, env: DeployEnv): string;
29
- /** Atomic infrastructure apex used for public managed/custom domains. */
30
- export declare const VIEW_FAST_APEX: "view.fast";
31
- /** Apex for default space hostnames: `{hostLabel}.view.fast`. */
32
- export declare const SPACE_HOSTNAME_APEX: "view.fast";
33
- /** Apex for internal management hostnames: `wpc-manage-{siteId}.view.fast`. */
34
- export declare const MANAGEMENT_HOSTNAME_APEX: "view.fast";
29
+ /** Base URL every documentation link catalog entries, skills, error pages — resolves against. */
30
+ export declare const DOCS_BASE_URL: string;
31
+ /**
32
+ * The production infrastructure apex. Committed artifacts and anything
33
+ * customer- or agent-facing (OpenAPI examples, docs, skills) must show this
34
+ * literal rather than the environment-resolved apex below: generating on a dev
35
+ * box would otherwise bake the dev apex into files everyone else reads.
36
+ */
37
+ export declare const PROD_VIEW_FAST_APEX: "view.fast";
38
+ /** The local-dev infrastructure apex. Never appears in committed artifacts. */
39
+ export declare const DEV_VIEW_FAST_APEX: "preview.space";
40
+ /** Resolve the infrastructure apex, allowing an explicit deployment override. */
41
+ export declare function resolveViewFastApex(environment: Readonly<Partial<Pick<NodeJS.ProcessEnv, "NODE_ENV" | "SPACEFAST_VIEW_FAST_APEX">>>): string;
42
+ /** Infrastructure apex used for public managed/custom domains. */
43
+ export declare const VIEW_FAST_APEX: string;
35
44
  /** Reserved first-label prefix for the management namespace; users may not register it. */
36
45
  export declare const MANAGEMENT_LABEL_PREFIX: "wpc-manage-";
@@ -52,16 +52,30 @@ export function serviceOrigin(service, env) {
52
52
  const d = BY_ENV[env];
53
53
  return `${d.protocol}://${d.hosts[service]}`;
54
54
  }
55
+ /** Base URL every documentation link — catalog entries, skills, error pages — resolves against. */
56
+ export const DOCS_BASE_URL = `${serviceOrigin("www", "prod")}/docs`;
55
57
  // --- Apexes that are NOT spacefast.com subdomains -------------------------------
56
- // These live outside the per-env map because they are stable infra identities.
57
- /** Atomic infrastructure apex used for public managed/custom domains. */
58
- export const VIEW_FAST_APEX = "view.fast";
59
- // D-4 resolved 2026-06-26: default space hostnames are
60
- // `{hostLabel}.view.fast`; internal management hostnames share the same apex
61
- // under the reserved `wpc-manage-` label prefix and are never public space URLs.
62
- /** Apex for default space hostnames: `{hostLabel}.view.fast`. */
63
- export const SPACE_HOSTNAME_APEX = VIEW_FAST_APEX;
64
- /** Apex for internal management hostnames: `wpc-manage-{siteId}.view.fast`. */
65
- export const MANAGEMENT_HOSTNAME_APEX = VIEW_FAST_APEX;
58
+ /**
59
+ * The production infrastructure apex. Committed artifacts and anything
60
+ * customer- or agent-facing (OpenAPI examples, docs, skills) must show this
61
+ * literal rather than the environment-resolved apex below: generating on a dev
62
+ * box would otherwise bake the dev apex into files everyone else reads.
63
+ */
64
+ export const PROD_VIEW_FAST_APEX = "view.fast";
65
+ /** The local-dev infrastructure apex. Never appears in committed artifacts. */
66
+ export const DEV_VIEW_FAST_APEX = "preview.space";
67
+ /** Resolve the infrastructure apex, allowing an explicit deployment override. */
68
+ export function resolveViewFastApex(environment) {
69
+ const nodeEnvironment = environment.NODE_ENV?.trim().toLowerCase();
70
+ return (environment.SPACEFAST_VIEW_FAST_APEX?.trim().toLowerCase() ||
71
+ (["prod", "production"].includes(nodeEnvironment ?? "")
72
+ ? PROD_VIEW_FAST_APEX
73
+ : DEV_VIEW_FAST_APEX));
74
+ }
75
+ /** Infrastructure apex used for public managed/custom domains. */
76
+ export const VIEW_FAST_APEX = resolveViewFastApex(typeof process === "undefined" ? {} : process.env);
77
+ // Default space hostnames are `{hostLabel}.{VIEW_FAST_APEX}`; internal
78
+ // management hostnames share the same apex under the reserved `wpc-manage-`
79
+ // label prefix and are never public space URLs.
66
80
  /** Reserved first-label prefix for the management namespace; users may not register it. */
67
81
  export const MANAGEMENT_LABEL_PREFIX = "wpc-manage-";
@@ -4,6 +4,7 @@ declare const postgresConnectionBudgetSchema: z.ZodObject<{
4
4
  maxConnections: z.ZodNumber;
5
5
  superuserReservedConnections: z.ZodNumber;
6
6
  }, z.core.$strip>;
7
+ migrationConnections: z.ZodNumber;
7
8
  operationalReserveConnections: z.ZodNumber;
8
9
  transactionPools: z.ZodRecord<z.ZodString, z.ZodObject<{
9
10
  serverConnections: z.ZodNumber;
@@ -57,6 +58,7 @@ export type PostgresConnectionBudgetSummary = {
57
58
  transactionPoolQueryHeadroom: number;
58
59
  steadyConnections: number;
59
60
  rollingDeploySurgeConnections: number;
61
+ migrationConnections: number;
60
62
  operationalReserveConnections: number;
61
63
  plannedConnections: number;
62
64
  unallocatedConnections: number;
@@ -66,6 +68,7 @@ export declare const POSTGRES_CONNECTION_BUDGET: {
66
68
  maxConnections: number;
67
69
  superuserReservedConnections: number;
68
70
  };
71
+ migrationConnections: number;
69
72
  operationalReserveConnections: number;
70
73
  transactionPools: Record<string, {
71
74
  serverConnections: number;
@@ -15,6 +15,7 @@ const postgresConnectionBudgetSchema = z
15
15
  maxConnections: z.number().int().positive(),
16
16
  superuserReservedConnections: z.number().int().nonnegative(),
17
17
  }),
18
+ migrationConnections: z.number().int().positive(),
18
19
  operationalReserveConnections: z.number().int().nonnegative(),
19
20
  transactionPools: z.record(z.string().min(1), z.object({
20
21
  serverConnections: z.number().int().positive(),
@@ -72,7 +73,10 @@ export function calculatePostgresConnectionBudget(plan, server = plan.server) {
72
73
  const transactionPoolQueryHeadroom = transactionPoolConnections - transactionPoolPinnedConnections;
73
74
  const steadyConnections = directSteadyConnections + transactionPoolConnections;
74
75
  const rollingDeploySurgeConnections = directServices.reduce((total, service) => total + service.rolloutOverlapReplicas * serviceFootprint(service), 0);
75
- const plannedConnections = steadyConnections + rollingDeploySurgeConnections + plan.operationalReserveConnections;
76
+ const plannedConnections = steadyConnections +
77
+ rollingDeploySurgeConnections +
78
+ plan.migrationConnections +
79
+ plan.operationalReserveConnections;
76
80
  return {
77
81
  usableServerConnections,
78
82
  directSteadyConnections,
@@ -81,6 +85,7 @@ export function calculatePostgresConnectionBudget(plan, server = plan.server) {
81
85
  transactionPoolQueryHeadroom,
82
86
  steadyConnections,
83
87
  rollingDeploySurgeConnections,
88
+ migrationConnections: plan.migrationConnections,
84
89
  operationalReserveConnections: plan.operationalReserveConnections,
85
90
  plannedConnections,
86
91
  unallocatedConnections: usableServerConnections - plannedConnections,
@@ -3,10 +3,11 @@
3
3
  "maxConnections": 25,
4
4
  "superuserReservedConnections": 3
5
5
  },
6
+ "migrationConnections": 1,
6
7
  "operationalReserveConnections": 4,
7
8
  "transactionPools": {
8
9
  "controlPlaneRuntime": {
9
- "serverConnections": 8
10
+ "serverConnections": 7
10
11
  }
11
12
  },
12
13
  "services": {
@@ -32,7 +32,7 @@ export const abuseReportSchema = z.object({
32
32
  spaceId: z
33
33
  .string()
34
34
  .nullable()
35
- .describe("Space the reported hostname resolved to, when it could be resolved."),
35
+ .describe("Space the reported hostname resolved to, when resolution succeeds."),
36
36
  createdAt: z.string().datetime().describe("When the report was filed."),
37
37
  });
38
38
  // Operator triage view: includes intake details the public receipt omits.