@spacefast/common 0.0.13 → 0.0.18
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.
- package/dist/agents/client-registry.d.ts +22 -0
- package/dist/agents/client-registry.js +41 -0
- package/dist/agents/connect-targets.d.ts +51 -6
- package/dist/agents/connect-targets.js +93 -28
- package/dist/brand.d.ts +0 -11
- package/dist/brand.js +0 -20
- package/dist/config/domains.d.ts +15 -6
- package/dist/config/domains.js +24 -10
- package/dist/config/postgres-budget.d.ts +3 -0
- package/dist/config/postgres-budget.js +6 -1
- package/dist/config/postgres-budget.json +2 -1
- package/dist/contracts/abuse.js +1 -1
- package/dist/contracts/access.d.ts +149 -44
- package/dist/contracts/access.js +94 -8
- package/dist/contracts/activity.js +5 -1
- package/dist/contracts/api-keys.js +9 -9
- package/dist/contracts/archives.js +11 -11
- package/dist/contracts/beta.js +1 -1
- package/dist/contracts/builds.js +14 -14
- package/dist/contracts/channels.js +2 -2
- package/dist/contracts/comments.d.ts +86 -15
- package/dist/contracts/comments.js +116 -20
- package/dist/contracts/common.d.ts +12 -12
- package/dist/contracts/common.js +33 -30
- package/dist/contracts/continuation.js +5 -5
- package/dist/contracts/data-source-routes.js +1 -1
- package/dist/contracts/device-auth.d.ts +6 -6
- package/dist/contracts/device-auth.js +12 -12
- package/dist/contracts/docs.d.ts +10 -10
- package/dist/contracts/domains.js +39 -33
- package/dist/contracts/enums.d.ts +2 -10
- package/dist/contracts/enums.js +0 -2
- package/dist/contracts/error-code-meta.d.ts +116 -47
- package/dist/contracts/error-code-meta.js +37 -16
- package/dist/contracts/error-codes.d.ts +7 -4
- package/dist/contracts/error-codes.js +46 -21
- package/dist/contracts/events.d.ts +10 -3
- package/dist/contracts/events.js +33 -5
- package/dist/contracts/execution.d.ts +26 -0
- package/dist/contracts/execution.js +21 -0
- package/dist/contracts/feature-lifecycle.d.ts +21 -24
- package/dist/contracts/feature-lifecycle.js +28 -26
- package/dist/contracts/features.js +4 -4
- package/dist/contracts/functions.d.ts +8 -140
- package/dist/contracts/functions.js +9 -19
- package/dist/contracts/git.d.ts +1 -1
- package/dist/contracts/grants.d.ts +96 -79
- package/dist/contracts/grants.js +130 -43
- package/dist/contracts/ids.d.ts +2 -2
- package/dist/contracts/ids.js +2 -4
- package/dist/contracts/internal.js +2 -2
- package/dist/contracts/mcp.d.ts +17 -556
- package/dist/contracts/mcp.js +9 -103
- package/dist/contracts/me.js +3 -4
- package/dist/contracts/notifications.d.ts +108 -0
- package/dist/contracts/notifications.js +54 -0
- package/dist/contracts/oauth-resources.d.ts +18 -1
- package/dist/contracts/oauth-resources.js +22 -2
- package/dist/contracts/operations.d.ts +2 -50
- package/dist/contracts/operations.js +0 -19
- package/dist/contracts/pages.d.ts +8 -4
- package/dist/contracts/pages.js +16 -3
- package/dist/contracts/platform.js +10 -8
- package/dist/contracts/problem-document.d.ts +14 -0
- package/dist/contracts/problem-document.js +35 -0
- package/dist/contracts/push-new.d.ts +21 -6
- package/dist/contracts/push-new.js +3 -7
- package/dist/contracts/resources.d.ts +8 -7
- package/dist/contracts/resources.js +9 -6
- package/dist/contracts/runtime-api.d.ts +162 -92
- package/dist/contracts/runtime-api.js +99 -27
- package/dist/contracts/runtime-app.d.ts +41 -11
- package/dist/contracts/runtime-app.js +22 -1
- package/dist/contracts/runtime-db.d.ts +424 -0
- package/dist/contracts/runtime-db.js +108 -0
- package/dist/contracts/runtime-storage.d.ts +120 -0
- package/dist/contracts/runtime-storage.js +40 -0
- package/dist/contracts/sf-config-v1.d.ts +49 -1
- package/dist/contracts/sf-config-v1.js +2 -2
- package/dist/contracts/sites.d.ts +1 -0
- package/dist/contracts/sites.js +20 -12
- package/dist/contracts/space-config.d.ts +62 -22
- package/dist/contracts/space-config.js +173 -47
- package/dist/contracts/spaces.d.ts +79 -45
- package/dist/contracts/spaces.js +66 -50
- package/dist/contracts/superadmin-spaces.d.ts +13 -2
- package/dist/contracts/superadmin-spaces.js +15 -0
- package/dist/contracts/superadmin-tenants.js +4 -4
- package/dist/contracts/superadmin.d.ts +4 -0
- package/dist/contracts/superadmin.js +14 -1
- package/dist/contracts/tags.d.ts +17 -17
- package/dist/contracts/tags.js +1 -1
- package/dist/contracts/teams.js +25 -16
- package/dist/contracts/theme-json.js +1 -1
- package/dist/contracts/transfers.js +4 -4
- package/dist/contracts/variables.js +3 -3
- package/dist/contracts/zero.d.ts +204 -338
- package/dist/contracts/zero.js +94 -98
- package/dist/dashboard-paths/index.d.ts +16 -1
- package/dist/dashboard-paths/index.js +18 -0
- package/dist/docs/agent-handoff-document.d.ts +2 -2
- package/dist/docs/agent-handoff-document.js +8 -7
- package/dist/docs/agent-prose.d.ts +22 -3
- package/dist/docs/agent-prose.js +221 -51
- package/dist/docs/agent-setup.d.ts +13 -10
- package/dist/docs/agent-setup.js +279 -53
- package/dist/docs/agent-solutions.d.ts +6 -6
- package/dist/docs/agent-solutions.js +23 -21
- package/dist/docs/catalog.d.ts +29 -74
- package/dist/docs/catalog.js +65 -92
- package/dist/docs/error-docs.js +293 -221
- package/dist/docs/skill-distribution.d.ts +2 -0
- package/dist/docs/skill-distribution.js +7 -4
- package/dist/docs/skills.d.ts +546 -0
- package/dist/docs/skills.js +340 -0
- package/dist/utils/browser-credential.d.ts +19 -0
- package/dist/utils/browser-credential.js +62 -0
- package/dist/utils/comment-avatars.d.ts +7 -0
- package/dist/utils/comment-avatars.js +42 -0
- package/dist/utils/content-type.d.ts +3 -3
- package/dist/utils/content-type.js +38 -61
- package/dist/utils/domain-diagnostics.d.ts +5 -5
- package/dist/utils/domain-diagnostics.js +21 -10
- package/dist/utils/local-space-state.d.ts +78 -4
- package/dist/utils/local-space-state.js +383 -82
- package/dist/utils/one-shot-replay.d.ts +14 -0
- package/dist/utils/one-shot-replay.js +21 -0
- package/dist/utils/page-preview.d.ts +7 -0
- package/dist/utils/page-preview.js +9 -0
- package/dist/utils/pages.d.ts +2 -11
- package/dist/utils/pages.js +58 -14
- package/dist/utils/publish-form-data.d.ts +22 -0
- package/dist/utils/publish-form-data.js +26 -0
- package/dist/utils/publish-policy.js +20 -4
- package/dist/utils/query-keys.d.ts +7 -4
- package/dist/utils/query-keys.js +13 -4
- package/dist/utils/runtime-paths.d.ts +3 -0
- package/dist/utils/runtime-paths.js +7 -0
- package/dist/utils/secure-local-file.d.ts +73 -0
- package/dist/utils/secure-local-file.js +1373 -0
- package/dist/utils/space-config.d.ts +13 -4
- package/dist/utils/space-config.js +123 -15
- package/dist/utils/storage-policy.d.ts +20 -0
- package/dist/utils/storage-policy.fixtures.json +174 -0
- package/dist/utils/storage-policy.js +193 -0
- package/dist/utils/upload-session.d.ts +12 -1
- package/dist/utils/upload-session.js +37 -2
- package/dist/utils/version-file-browser.d.ts +13 -0
- package/dist/utils/version-file-browser.js +59 -0
- package/package.json +19 -1
- package/dist/contracts/mounts.d.ts +0 -142
- package/dist/contracts/mounts.js +0 -56
- package/dist/utils/asset-fingerprint.d.ts +0 -64
- package/dist/utils/asset-fingerprint.js +0 -620
package/dist/docs/agent-setup.js
CHANGED
|
@@ -1,16 +1,29 @@
|
|
|
1
|
-
import { getConnectTarget, } from "../agents/connect-targets.js";
|
|
1
|
+
import { buildClaudeMcpAddCommand, buildHermesMcpAddCommand, cursorHostedMcpDeeplink, cursorHostedMcpServersJson, getConnectTarget, opencodeHostedMcpConfig, vscodeHostedMcpDeeplink, vscodeHostedMcpServersJson, } from "../agents/connect-targets.js";
|
|
2
2
|
import { BRAND } from "../brand.js";
|
|
3
|
+
import { serviceOrigin } from "../config/domains.js";
|
|
4
|
+
import { createBrowserCredentialUrl, parseBrowserCredentialUrl, } from "../utils/browser-credential.js";
|
|
3
5
|
import { CHECK_BEFORE_PUBLISH_PROSE, CONTINUE_AFTER_CLAIM_PROSE, ENV_NOTES_PROSE, FAILURE_CONDUCT_PROSE, HOW_TO_RESEARCH_PROSE, LANE_PICKER_PROSE, POSITIONING_PROSE, PUBLISH_SEQUENCE_PROSE, RECEIPT_SHAPE_PROSE, SAVE_STATE_PROSE, SECRET_RULES_PROSE, SIGNED_UPLOAD_PROSE, UPDATE_SPACE_PROSE, } from "./agent-prose.js";
|
|
4
|
-
import { spacefastInstallCurlCommand, spacefastInstallPowerShellCommand, spacefastSkillFetchCommand, spacefastSkillInstallCommand, spacefastSkillUrl, } from "./skill-distribution.js";
|
|
5
|
-
|
|
6
|
-
|
|
6
|
+
import { spacefastClaudePluginAddCommand, spacefastClaudeDesktopExtensionUrl, spacefastClaudePluginInstallCommand, spacefastCodexPluginAddCommand, spacefastCodexPluginInstallCommand, spacefastInstallCurlCommand, spacefastInstallPowerShellCommand, spacefastSkillFetchCommand, spacefastSkillInstallCommand, spacefastSkillUrl, } from "./skill-distribution.js";
|
|
7
|
+
// The one URL every agent prompt points at. /setup.md is the actionable front
|
|
8
|
+
// door (publish now, then set up your client); /ai.txt stays the deep
|
|
9
|
+
// reference contract it links out to.
|
|
10
|
+
export const agentSetupUrl = `${serviceOrigin("www", "prod")}/setup.md`;
|
|
11
|
+
export const agentSetupTextUrl = `${serviceOrigin("www", "prod")}/ai.txt`;
|
|
7
12
|
const agentSetupParsedUrl = new URL(agentSetupUrl);
|
|
8
13
|
export const agentSetupHostLabel = agentSetupParsedUrl.host + agentSetupParsedUrl.pathname;
|
|
9
|
-
|
|
14
|
+
// Deliberately bare: the document itself tells the agent to ask what to
|
|
15
|
+
// publish when it isn't obvious and to update an existing space, so the prompt
|
|
16
|
+
// stays a single gesture that works in any client.
|
|
17
|
+
export const agentSetupPrompt = `Fetch ${agentSetupUrl}`;
|
|
18
|
+
// The no-install publish: one POST, no account. Single-sourced so the
|
|
19
|
+
// marketing pages and the setup doc can never show different commands.
|
|
20
|
+
export const anonymousPublishCurlCommand = `curl -F "files=@index.html" ${serviceOrigin("api", "prod")}/v1/publish`;
|
|
10
21
|
/*
|
|
11
|
-
* Agent handoff contract: links
|
|
12
|
-
*
|
|
13
|
-
*
|
|
22
|
+
* Agent handoff contract: private links carry a one-use path token on
|
|
23
|
+
* https://<access-origin>/agent/<documentId>/<token>; durable agent credentials stay encrypted at
|
|
24
|
+
* the broker. Agents fetch the reconstructed clean dashboard document URL, never the private
|
|
25
|
+
* handoff URL. Fetching never consumes a
|
|
26
|
+
* handoff; exactly one successful redemption
|
|
14
27
|
* does. Redemption is app-private, reuses the existing device/OAuth approval service, and returns
|
|
15
28
|
* the already-approved finite Space-scoped credential: there is no public AgentGrant resource,
|
|
16
29
|
* durable key table, or team-wide publisher key. The CLI accepts links only through stdin or a
|
|
@@ -47,19 +60,18 @@ function isSafeHttpUrl(url) {
|
|
|
47
60
|
}
|
|
48
61
|
/**
|
|
49
62
|
* The single shared grammar for handoff links:
|
|
50
|
-
* `<
|
|
51
|
-
* `[A-Za-z0-9_-]{1,512}` and the
|
|
52
|
-
*
|
|
53
|
-
*
|
|
54
|
-
*
|
|
55
|
-
* second host allowlist that would reject legitimate dev or container origins.
|
|
63
|
+
* `<access-origin>/agent/<documentId>/<oneUseToken>`. The document ID must match
|
|
64
|
+
* `[A-Za-z0-9_-]{1,512}` and the token `[A-Za-z0-9_-]{16,512}`; the two must differ;
|
|
65
|
+
* queries, fragments, and URL userinfo are forbidden. The URL must sit exactly on the caller's
|
|
66
|
+
* configured HTTP(S) access origin; the clean static document may live on a separate explicitly
|
|
67
|
+
* supplied dashboard origin.
|
|
56
68
|
* Normalization is part of the contract: the input is WHATWG-URL-normalized first (backslashes,
|
|
57
69
|
* dot segments, stray tab/CR/LF, empty userinfo, case, default ports), the grammar is enforced on
|
|
58
70
|
* the normalized URL, and only the reconstructed canonical URL ever leaves this function.
|
|
59
71
|
* Dashboard minting, CLI ingestion, and control-plane validation must all use this parser so the
|
|
60
72
|
* grammar can never fork.
|
|
61
73
|
*/
|
|
62
|
-
export function parseAgentHandoffUrl(value, expectedOrigin) {
|
|
74
|
+
export function parseAgentHandoffUrl(value, expectedOrigin, documentOrigin = expectedOrigin) {
|
|
63
75
|
let expectedUrl;
|
|
64
76
|
try {
|
|
65
77
|
expectedUrl = new URL(expectedOrigin);
|
|
@@ -71,26 +83,54 @@ export function parseAgentHandoffUrl(value, expectedOrigin) {
|
|
|
71
83
|
throw new TypeError("Agent handoff expectedOrigin must be an HTTP(S) origin.");
|
|
72
84
|
}
|
|
73
85
|
const canonicalExpectedOrigin = expectedUrl.origin;
|
|
86
|
+
let canonicalDocumentOrigin;
|
|
87
|
+
try {
|
|
88
|
+
const documentUrl = new URL(documentOrigin);
|
|
89
|
+
if (!isSafeHttpUrl(documentUrl) ||
|
|
90
|
+
documentUrl.username ||
|
|
91
|
+
documentUrl.password ||
|
|
92
|
+
documentUrl.pathname !== "/" ||
|
|
93
|
+
documentUrl.search ||
|
|
94
|
+
documentUrl.hash) {
|
|
95
|
+
throw new TypeError("invalid_document_origin");
|
|
96
|
+
}
|
|
97
|
+
canonicalDocumentOrigin = documentUrl.origin;
|
|
98
|
+
}
|
|
99
|
+
catch {
|
|
100
|
+
throw new TypeError("Agent handoff documentOrigin must be a clean HTTP(S) origin.");
|
|
101
|
+
}
|
|
74
102
|
let url;
|
|
103
|
+
let parsedCredential;
|
|
75
104
|
try {
|
|
76
105
|
url = new URL(value);
|
|
106
|
+
parsedCredential = parseBrowserCredentialUrl(value);
|
|
77
107
|
}
|
|
78
108
|
catch {
|
|
79
|
-
throw new TypeError("Agent handoff URL must be a valid HTTP(S) URL.");
|
|
109
|
+
throw new TypeError("Agent handoff URL must be a valid private HTTP(S) URL.");
|
|
80
110
|
}
|
|
81
|
-
const documentId = /^\/agent\/([^/]+)
|
|
82
|
-
const secret =
|
|
111
|
+
const documentId = /^\/agent\/([^/]+)\/[^/]+$/.exec(url.pathname)?.[1];
|
|
112
|
+
const secret = parsedCredential.credential;
|
|
83
113
|
if (url.origin !== canonicalExpectedOrigin ||
|
|
84
|
-
url.username !== "" ||
|
|
85
|
-
url.password !== "" ||
|
|
86
114
|
value.includes("?") ||
|
|
115
|
+
url.hash !== "" ||
|
|
87
116
|
!documentId ||
|
|
88
117
|
!opaqueHandoffDocumentId.test(documentId) ||
|
|
89
118
|
!opaqueHandoffSecret.test(secret) ||
|
|
90
119
|
documentId === secret) {
|
|
91
|
-
throw new TypeError("Agent handoff URL must be
|
|
120
|
+
throw new TypeError("Agent handoff URL must be a private /agent/<id>/<token> URL on the access origin with one opaque token (16-512 chars, distinct from the id) and no userinfo, query, or fragment.");
|
|
92
121
|
}
|
|
93
|
-
|
|
122
|
+
const handoffUrl = createBrowserCredentialUrl({
|
|
123
|
+
origin: canonicalExpectedOrigin,
|
|
124
|
+
path: "/agent",
|
|
125
|
+
publicId: documentId,
|
|
126
|
+
credential: secret,
|
|
127
|
+
});
|
|
128
|
+
return {
|
|
129
|
+
documentId,
|
|
130
|
+
documentUrl: new URL(`/agent/${encodeURIComponent(documentId)}`, canonicalDocumentOrigin).toString(),
|
|
131
|
+
handoffUrl,
|
|
132
|
+
secret,
|
|
133
|
+
};
|
|
94
134
|
}
|
|
95
135
|
function validateMcpEndpoint(value) {
|
|
96
136
|
let url;
|
|
@@ -114,11 +154,11 @@ function validateMcpEndpoint(value) {
|
|
|
114
154
|
export const AGENT_HANDOFF_CLI_TARGET_IDS = ["claude-code", "codex"];
|
|
115
155
|
export const AGENT_HANDOFF_PREAMBLE = "Talk to the user before installing tools or publishing. Confirm the file or folder they want to publish.";
|
|
116
156
|
/** The fetch-safety contract: reading the document never consumes or leaks a handoff. */
|
|
117
|
-
export const AGENT_HANDOFF_FETCH_SAFETY = "Keep the original handoff link private. Fetching this document did not use
|
|
118
|
-
export const
|
|
157
|
+
export const AGENT_HANDOFF_FETCH_SAFETY = "Keep the original handoff link private. Fetching this clean document URL did not use or send its credential; the credential is spent only by one successful exchange. An expired, used, or revoked link fails safely, so ask the user for a fresh one from the dashboard.";
|
|
158
|
+
export const AGENT_HANDOFF_CREDENTIAL_HYGIENE = "Keep the private handoff URL out of commands, request URLs, logs, and replies.";
|
|
119
159
|
export const AGENT_HANDOFF_CLI_APPROVAL_GUIDANCE = `Run \`sf setup agent\` to initiate the handoff exchange; if \`sf\` is missing, install it first (macOS/Linux: \`${spacefastInstallCurlCommand}\`; Windows PowerShell: \`${spacefastInstallPowerShellCommand}\`). When it asks for the handoff link on stdin, paste the original link into that prompt; never pass the link as an argv value. Ask the user to approve in the browser, then wait for the CLI's approval result before publishing.`;
|
|
120
160
|
export const AGENT_HANDOFF_BROWSER_APPROVAL_GUIDANCE = "When the client opens browser approval, ask the user to approve there before publishing.";
|
|
121
|
-
export const AGENT_HANDOFF_PUBLISH_PROSE = "After approval, confirm the selected Space and permissions, then publish only the files the user approved. Report the bare Live and immutable Version addresses separately from the private
|
|
161
|
+
export const AGENT_HANDOFF_PUBLISH_PROSE = "After approval, confirm the selected Space and permissions, then publish only the files the user approved. Report the bare Live and immutable Version addresses separately from the private Access URL; create a scoped Link when a recipient needs access.";
|
|
122
162
|
/** One target's Connect prose: blurb, copyable setup blocks, deeplink/download lines. */
|
|
123
163
|
export function agentHandoffConnectSections(target) {
|
|
124
164
|
const setupSections = [target.primary, target.config].flatMap((setup) => setup ? [[setup.label, `\`\`\`${setup.language}`, setup.value, "```"].join("\n")] : []);
|
|
@@ -142,7 +182,7 @@ function renderAgentHandoffInstructions(documentUrl, target) {
|
|
|
142
182
|
"## Continue the approved handoff",
|
|
143
183
|
AGENT_HANDOFF_FETCH_SAFETY,
|
|
144
184
|
approvalGuidance,
|
|
145
|
-
|
|
185
|
+
AGENT_HANDOFF_CREDENTIAL_HYGIENE,
|
|
146
186
|
].join("\n\n"),
|
|
147
187
|
["## Publish", AGENT_HANDOFF_PUBLISH_PROSE].join("\n\n"),
|
|
148
188
|
`General agent instructions: ${agentSetupTextUrl}`,
|
|
@@ -151,12 +191,12 @@ function renderAgentHandoffInstructions(documentUrl, target) {
|
|
|
151
191
|
}
|
|
152
192
|
/** Builds every copy-ready handoff artifact from one validated URL and target catalog row. */
|
|
153
193
|
export function buildAgentHandoff(input) {
|
|
154
|
-
const { documentUrl, secret } = parseAgentHandoffUrl(input.url, input.expectedOrigin);
|
|
194
|
+
const { documentUrl, handoffUrl, secret } = parseAgentHandoffUrl(input.url, input.expectedOrigin, input.documentOrigin);
|
|
155
195
|
const mcpEndpoint = validateMcpEndpoint(input.mcpEndpoint);
|
|
156
196
|
const target = getConnectTarget(input.targetId, {
|
|
157
197
|
mcpEndpoint,
|
|
158
198
|
});
|
|
159
|
-
const prompt = `Fetch ${documentUrl}
|
|
199
|
+
const prompt = `Fetch ${documentUrl} and follow the ${target.name} setup instructions to publish with ${BRAND.productName}. Use this private one-use handoff only for the exchange step: ${handoffUrl}. Do not fetch the private handoff URL. Ask me what I want to publish if it isn't obvious.`;
|
|
160
200
|
const instructions = renderAgentHandoffInstructions(documentUrl, target);
|
|
161
201
|
const actions = [
|
|
162
202
|
{ kind: "copy", label: "Copy for my agent", sensitive: true, value: prompt },
|
|
@@ -188,7 +228,7 @@ export function buildAgentHandoff(input) {
|
|
|
188
228
|
}),
|
|
189
229
|
];
|
|
190
230
|
if (publicProjections.some((projection) => projection.includes(secret))) {
|
|
191
|
-
throw new TypeError("Agent handoff inputs would leak the
|
|
231
|
+
throw new TypeError("Agent handoff inputs would leak the private credential into a public projection.");
|
|
192
232
|
}
|
|
193
233
|
return { actions, documentUrl, instructions, prompt };
|
|
194
234
|
}
|
|
@@ -244,8 +284,8 @@ export function aiInstructionsText() {
|
|
|
244
284
|
HOW_TO_RESEARCH_PROSE,
|
|
245
285
|
"",
|
|
246
286
|
'Add a bearer access token with `-H "Authorization: Bearer ..."` to publish into the user\'s',
|
|
247
|
-
"team instead of anonymously. Agent clients should prefer OAuth client credentials. Errors come back as
|
|
248
|
-
"`
|
|
287
|
+
"team instead of anonymously. Agent clients should prefer OAuth client credentials. Errors come back as RFC 9457 problem documents with stable `code` values and a",
|
|
288
|
+
"`type` URL; fetch the `type` URL when you need recovery steps.",
|
|
249
289
|
"",
|
|
250
290
|
"## Install the CLI (On-Device files, updates, versions, rollback, and the rest)",
|
|
251
291
|
"",
|
|
@@ -282,7 +322,7 @@ export function aiInstructionsText() {
|
|
|
282
322
|
LANE_PICKER_PROSE,
|
|
283
323
|
"",
|
|
284
324
|
"Hosted MCP is the no-download cloud lane for ChatGPT, Codex, Claude, Cursor, and browser",
|
|
285
|
-
"clients that can authenticate with OAuth
|
|
325
|
+
"clients that can authenticate with OAuth:",
|
|
286
326
|
"",
|
|
287
327
|
"```text",
|
|
288
328
|
"https://mcp.spacefast.com",
|
|
@@ -293,25 +333,17 @@ export function aiInstructionsText() {
|
|
|
293
333
|
"`spaces:read` for status, versions, diffs, and logs, `spaces:write` for claim/create/update,",
|
|
294
334
|
"`spaces:rename` for slug and managed-address renames, `publish:write` for publish and rollback,",
|
|
295
335
|
"and `domains:read`/`domains:write` for domain",
|
|
296
|
-
"inventory, DNS diagnostics, assignment, verification, and mutation. Hosted MCP
|
|
297
|
-
"
|
|
298
|
-
"session.",
|
|
336
|
+
"inventory, DNS diagnostics, assignment, verification, and mutation. Hosted MCP has no",
|
|
337
|
+
"filesystem access.",
|
|
299
338
|
"",
|
|
300
|
-
"For hosted MCP,
|
|
301
|
-
"
|
|
302
|
-
"`import_from_url` when the archive already has an HTTPS URL. Hosted MCP is the right path for",
|
|
339
|
+
"For hosted MCP, call `publish` with inline files. For larger artifacts, use `execute` to",
|
|
340
|
+
"discover and invoke the catalog publish operations. Hosted MCP is the right path for",
|
|
303
341
|
"ChatGPT/browser agents because it requires no download and never claims local filesystem access.",
|
|
304
|
-
"
|
|
305
|
-
"
|
|
306
|
-
|
|
307
|
-
"
|
|
308
|
-
"
|
|
309
|
-
"`spacefast://spaces/{spaceId}`, and `spacefast://policy/current` for bounded read-only",
|
|
310
|
-
"context.",
|
|
311
|
-
"`execute` is dry-run-first; mutating multi-step workflows can return",
|
|
312
|
-
"`approval_required` and continue through `resume` after the user approves.",
|
|
313
|
-
"",
|
|
314
|
-
"Use On-Device MCP when the agent needs the user's checkout, path-based publish, or file edits:",
|
|
342
|
+
"`execute` runs code in Spacefast's secure QuickJS sandbox. Mutating OpenAPI calls pause before HTTP",
|
|
343
|
+
"and return an execution ID; continue the same live execution with `resume` and an",
|
|
344
|
+
"`accept`, `decline`, or `cancel` action.",
|
|
345
|
+
"",
|
|
346
|
+
"Use On-Device MCP when the agent needs path-based publish from the user's checkout:",
|
|
315
347
|
"",
|
|
316
348
|
"```bash",
|
|
317
349
|
"sf setup agent --agent auto --connect",
|
|
@@ -330,7 +362,7 @@ export function aiInstructionsText() {
|
|
|
330
362
|
"",
|
|
331
363
|
"## After publishing",
|
|
332
364
|
"",
|
|
333
|
-
"- Report the bare Live URL, the immutable Version URL when ready, the private
|
|
365
|
+
"- Report the bare Live URL, the immutable Version URL when ready, the private Access URL, and",
|
|
334
366
|
" — for anonymous spaces — the claim link with its expiry. Bare Live and Version URLs carry",
|
|
335
367
|
" no authority for a private Space; create a scoped Link when a recipient needs access.",
|
|
336
368
|
" If the receipt's immutable URL is null, poll the",
|
|
@@ -347,8 +379,9 @@ export function aiInstructionsText() {
|
|
|
347
379
|
" `200` proxy rules.",
|
|
348
380
|
"- `_headers` — supported response headers.",
|
|
349
381
|
"- `404.html` — custom not-found page.",
|
|
350
|
-
"- `sf.jsonc` — serving config (index, fallback, listing, meta)
|
|
351
|
-
" `
|
|
382
|
+
"- `sf.jsonc` — serving config (index, fallback, listing, meta), the optional `space`",
|
|
383
|
+
" link, and `redirects` / `rewrites` / `headers` arrays in the same matcher grammar",
|
|
384
|
+
" the files use. JSON Schema: https://spacefast.com/schemas/sf.json",
|
|
352
385
|
"- `/llms.txt` and `/ai.txt` — publish these in the user's site when it should be",
|
|
353
386
|
" agent-readable too.",
|
|
354
387
|
"- Plan limits surface as diagnostics, not failures you should guess at: publish the",
|
|
@@ -368,7 +401,7 @@ export function aiInstructionsText() {
|
|
|
368
401
|
"",
|
|
369
402
|
"- Docs index for agents: https://spacefast.com/llms.txt",
|
|
370
403
|
"- One-click connect (Claude Code, Claude, Codex, Cursor, VS Code): https://spacefast.com/agents",
|
|
371
|
-
"- Agent guide: https://spacefast.com/docs/agents",
|
|
404
|
+
"- Agent guide: https://spacefast.com/docs/getting-started/agents",
|
|
372
405
|
"- CLI reference: https://spacefast.com/docs/cli",
|
|
373
406
|
"- REST API + OpenAPI: https://spacefast.com/docs/api",
|
|
374
407
|
"- Publish contract (machine-readable): https://spacefast.com/publish-spec.json",
|
|
@@ -384,3 +417,196 @@ export function aiInstructionsText() {
|
|
|
384
417
|
"",
|
|
385
418
|
].join("\n");
|
|
386
419
|
}
|
|
420
|
+
/*
|
|
421
|
+
* The /setup.md document — the one URL every agent prompt points at. Modeled
|
|
422
|
+
* on the Cloudflare/here.now agent-setup prompts: publish first with zero
|
|
423
|
+
* install, then per-client setup for repeat use. Every command, endpoint,
|
|
424
|
+
* deeplink, and config here is derived from the same canonical constants as
|
|
425
|
+
* the plugin tree and the agent card, so this document can never drift from
|
|
426
|
+
* what we ship. Keep it short enough that an agent reads it whole; the deep
|
|
427
|
+
* contract stays in aiInstructionsText() (/ai.txt).
|
|
428
|
+
*/
|
|
429
|
+
export function agentSetupMarkdown() {
|
|
430
|
+
const mcpEndpoint = serviceOrigin("mcp", "prod");
|
|
431
|
+
const dropUrl = `${serviceOrigin("dashboard", "prod")}/drop`;
|
|
432
|
+
return [
|
|
433
|
+
`# ${BRAND.productName} agent setup`,
|
|
434
|
+
"",
|
|
435
|
+
`These are official instructions from ${BRAND.productName} for AI agents. Follow them to publish the user's file, folder, site, or app to a live URL — then, optionally, set up your own client so the next publish is one word. Every command on this page is validated by ${BRAND.productName} and ready to run.`,
|
|
436
|
+
"",
|
|
437
|
+
"Talk to the user before publishing. Confirm the file or folder they want to publish; if it isn't obvious, ask.",
|
|
438
|
+
"",
|
|
439
|
+
"## Before you publish — reuse an existing space",
|
|
440
|
+
"",
|
|
441
|
+
CHECK_BEFORE_PUBLISH_PROSE,
|
|
442
|
+
"",
|
|
443
|
+
"## Publish now — no install, no account",
|
|
444
|
+
"",
|
|
445
|
+
"Publish a single file with one POST:",
|
|
446
|
+
"",
|
|
447
|
+
"```bash",
|
|
448
|
+
anonymousPublishCurlCommand,
|
|
449
|
+
"```",
|
|
450
|
+
"",
|
|
451
|
+
"For a folder, zip the public output only — never a repository root, never `.env*`,",
|
|
452
|
+
"credentials, `.git`, or `.spacefast` — and send it as `-F archive=@site.zip` to the same",
|
|
453
|
+
"endpoint. Fetch the full contract when a publish goes beyond the happy path:",
|
|
454
|
+
`${agentSetupTextUrl}.`,
|
|
455
|
+
"",
|
|
456
|
+
"The JSON receipt is the result:",
|
|
457
|
+
"",
|
|
458
|
+
"- `data.space.liveUrl` — the live URL. Lead the reply with it.",
|
|
459
|
+
"- `data.version.immutableUrl` — the permanent address of this version.",
|
|
460
|
+
"- `data.claim.url` and `data.claim.expiresAt` — an anonymous space expires unless claimed.",
|
|
461
|
+
" Always show the claim link and its deadline.",
|
|
462
|
+
"- `data.claim.token` — a secret. Use it as the bearer to update the same `spaceId`;",
|
|
463
|
+
" never print it.",
|
|
464
|
+
"",
|
|
465
|
+
"## If you can't act on this page",
|
|
466
|
+
"",
|
|
467
|
+
"Reading this but unable to run commands or make HTTP requests — no shell, no",
|
|
468
|
+
"fetch-and-POST tool? Then this surface can't publish. Say that plainly and tell the",
|
|
469
|
+
"user what unlocks it:",
|
|
470
|
+
"",
|
|
471
|
+
"- In ChatGPT: switch to Work mode or the desktop app (paid plans). The Free plan",
|
|
472
|
+
" can't publish.",
|
|
473
|
+
"- In any other client: enable its tool/agent mode, or pick a client from",
|
|
474
|
+
` ${serviceOrigin("www", "prod")}/setup.`,
|
|
475
|
+
"",
|
|
476
|
+
"Don't fall back to generating files for the user to download and re-upload by hand",
|
|
477
|
+
"unless they ask for exactly that.",
|
|
478
|
+
"",
|
|
479
|
+
"## Set up your agent (optional, for repeat use)",
|
|
480
|
+
"",
|
|
481
|
+
'Use the section for your client. If yours isn\'t listed, use "Every other agent".',
|
|
482
|
+
"",
|
|
483
|
+
"### Claude Code",
|
|
484
|
+
"",
|
|
485
|
+
"The plugin ships the publish skill plus MCP in one install:",
|
|
486
|
+
"",
|
|
487
|
+
"```bash",
|
|
488
|
+
spacefastClaudePluginAddCommand,
|
|
489
|
+
spacefastClaudePluginInstallCommand,
|
|
490
|
+
"```",
|
|
491
|
+
"",
|
|
492
|
+
"Restart Claude Code (or run `/reload-plugins`) to activate it. MCP-only alternative:",
|
|
493
|
+
"",
|
|
494
|
+
"```bash",
|
|
495
|
+
buildClaudeMcpAddCommand(mcpEndpoint),
|
|
496
|
+
"```",
|
|
497
|
+
"",
|
|
498
|
+
"### Codex",
|
|
499
|
+
"",
|
|
500
|
+
"```bash",
|
|
501
|
+
spacefastCodexPluginAddCommand,
|
|
502
|
+
spacefastCodexPluginInstallCommand,
|
|
503
|
+
"```",
|
|
504
|
+
"",
|
|
505
|
+
"Or teach every task in a repository with one AGENTS.md line:",
|
|
506
|
+
"",
|
|
507
|
+
"```text",
|
|
508
|
+
`To publish, fetch ${agentSetupUrl} and follow the instructions.`,
|
|
509
|
+
"```",
|
|
510
|
+
"",
|
|
511
|
+
"### Cursor",
|
|
512
|
+
"",
|
|
513
|
+
`One click: ${cursorHostedMcpDeeplink(mcpEndpoint)}`,
|
|
514
|
+
"",
|
|
515
|
+
"Or add to `~/.cursor/mcp.json`:",
|
|
516
|
+
"",
|
|
517
|
+
"```json",
|
|
518
|
+
JSON.stringify(cursorHostedMcpServersJson(mcpEndpoint), null, 2),
|
|
519
|
+
"```",
|
|
520
|
+
"",
|
|
521
|
+
"### VS Code",
|
|
522
|
+
"",
|
|
523
|
+
`One click: ${vscodeHostedMcpDeeplink(mcpEndpoint)}`,
|
|
524
|
+
"",
|
|
525
|
+
"Or add to `.vscode/mcp.json`:",
|
|
526
|
+
"",
|
|
527
|
+
"```json",
|
|
528
|
+
JSON.stringify(vscodeHostedMcpServersJson(mcpEndpoint), null, 2),
|
|
529
|
+
"```",
|
|
530
|
+
"",
|
|
531
|
+
"### Claude (web, desktop, and Cowork)",
|
|
532
|
+
"",
|
|
533
|
+
"Settings → Connectors → Add custom connector, paste the endpoint. Approve once in the",
|
|
534
|
+
"browser, nothing to install:",
|
|
535
|
+
"",
|
|
536
|
+
"```text",
|
|
537
|
+
mcpEndpoint,
|
|
538
|
+
"```",
|
|
539
|
+
"",
|
|
540
|
+
"On desktop, the extension is a double-click install:",
|
|
541
|
+
spacefastClaudeDesktopExtensionUrl,
|
|
542
|
+
"",
|
|
543
|
+
"### ChatGPT and ChatGPT Work",
|
|
544
|
+
"",
|
|
545
|
+
// TODO(plugin-directory): once the Spacefast listing is live, lead this
|
|
546
|
+
// section with the one-click Plugin Directory install instead.
|
|
547
|
+
"Publishing works from Work mode or the desktop app (paid plans) — follow the",
|
|
548
|
+
"publish-now section above; nothing to install. On ChatGPT Work, an admin can add",
|
|
549
|
+
"Spacefast once as a workspace app (Workspace settings → Apps) with the endpoint",
|
|
550
|
+
"below and deploy it to the whole team:",
|
|
551
|
+
"",
|
|
552
|
+
"```text",
|
|
553
|
+
mcpEndpoint,
|
|
554
|
+
"```",
|
|
555
|
+
"",
|
|
556
|
+
"If this ChatGPT can't run tools (Free plan, plain Chat), say so and point the user",
|
|
557
|
+
"at Work mode or the desktop app — see “If you can't act on this page”.",
|
|
558
|
+
"",
|
|
559
|
+
"### Every other agent (OpenClaw, Hermes, Raycast, Pi, OpenCode, Devin, Poke, Indent, …)",
|
|
560
|
+
"",
|
|
561
|
+
"Install the publish skill:",
|
|
562
|
+
"",
|
|
563
|
+
"```bash",
|
|
564
|
+
spacefastSkillInstallCommand,
|
|
565
|
+
"```",
|
|
566
|
+
"",
|
|
567
|
+
"Clients that speak MCP add the hosted server; sign-in happens once on first tool use.",
|
|
568
|
+
"Hermes — one command:",
|
|
569
|
+
"",
|
|
570
|
+
"```bash",
|
|
571
|
+
buildHermesMcpAddCommand(mcpEndpoint),
|
|
572
|
+
"```",
|
|
573
|
+
"",
|
|
574
|
+
"OpenCode V2 — merge this schema-pinned config into `~/.config/opencode/opencode.jsonc`:",
|
|
575
|
+
"",
|
|
576
|
+
"```json",
|
|
577
|
+
JSON.stringify(opencodeHostedMcpConfig(mcpEndpoint), null, 2),
|
|
578
|
+
"```",
|
|
579
|
+
"",
|
|
580
|
+
'Any other MCP client, under `"mcpServers"`:',
|
|
581
|
+
"",
|
|
582
|
+
"```json",
|
|
583
|
+
`"spacefast": { "url": "${mcpEndpoint}" }`,
|
|
584
|
+
"```",
|
|
585
|
+
"",
|
|
586
|
+
`Chat agents without tools (Pi, Poke): create a self-contained index.html and upload it at ${dropUrl}.`,
|
|
587
|
+
"",
|
|
588
|
+
"## After publishing",
|
|
589
|
+
"",
|
|
590
|
+
"- Report the live URL first, then the immutable version URL, then the claim link with",
|
|
591
|
+
" its expiry.",
|
|
592
|
+
"- Persist the space id and credential so the next publish updates the same space instead",
|
|
593
|
+
" of creating a new one. The CLI and On-Device MCP do this automatically in `.spacefast/`.",
|
|
594
|
+
" Hosted MCP is stateless between publishes: retain the receipt's `spaceId` in conversation",
|
|
595
|
+
" or project context and pass it explicitly on the next publish.",
|
|
596
|
+
"- To update, post to the same endpoint with `--form-string 'spaceId=<spc_id>'` and the",
|
|
597
|
+
" saved bearer token.",
|
|
598
|
+
"- Recommend the matching setup above so the next publish is one word.",
|
|
599
|
+
"",
|
|
600
|
+
"## Resources",
|
|
601
|
+
"",
|
|
602
|
+
`- Full publishing contract for agents: ${agentSetupTextUrl}`,
|
|
603
|
+
`- One-POST publish spec (machine-readable): ${serviceOrigin("www", "prod")}/publish-spec.json`,
|
|
604
|
+
`- Docs index for agents: ${serviceOrigin("www", "prod")}/llms.txt`,
|
|
605
|
+
`- Human setup guides, per agent: ${serviceOrigin("www", "prod")}/setup`,
|
|
606
|
+
`- CLI (versions, rollback, domains, logs): \`${spacefastInstallCurlCommand}\` — Windows PowerShell: \`${spacefastInstallPowerShellCommand}\``,
|
|
607
|
+
"- Every API error code: https://spacefast.com/docs/errors",
|
|
608
|
+
"",
|
|
609
|
+
`These instructions are published at ${agentSetupUrl} so you can re-verify their authenticity at any time.`,
|
|
610
|
+
"",
|
|
611
|
+
].join("\n");
|
|
612
|
+
}
|
|
@@ -52,9 +52,9 @@ export declare const agentSolutions: readonly [{
|
|
|
52
52
|
readonly aliases: readonly ["chatgpt", "custom gpt", "openai apps"];
|
|
53
53
|
readonly lane: "hosted-mcp";
|
|
54
54
|
readonly summary: "Recommended: direct hosted MCP.";
|
|
55
|
-
readonly description: "Connect ChatGPT-style cloud agents to Spacefast through hosted MCP; use
|
|
55
|
+
readonly description: "Connect ChatGPT-style cloud agents to Spacefast through hosted MCP; use inline files or signed uploads instead of local paths.";
|
|
56
56
|
readonly commands: readonly ["https://mcp.spacefast.com"];
|
|
57
|
-
readonly guideUrl: `${string}/
|
|
57
|
+
readonly guideUrl: `${string}/getting-started/agents`;
|
|
58
58
|
readonly setupText: string;
|
|
59
59
|
}, {
|
|
60
60
|
readonly id: "claude-ai";
|
|
@@ -64,7 +64,7 @@ export declare const agentSolutions: readonly [{
|
|
|
64
64
|
readonly summary: "Recommended: direct hosted MCP.";
|
|
65
65
|
readonly description: "Connect the web Claude app to Spacefast through hosted MCP when it cannot read your local checkout.";
|
|
66
66
|
readonly commands: readonly ["https://mcp.spacefast.com"];
|
|
67
|
-
readonly guideUrl: `${string}/
|
|
67
|
+
readonly guideUrl: `${string}/getting-started/agents`;
|
|
68
68
|
readonly setupText: string;
|
|
69
69
|
}, {
|
|
70
70
|
readonly id: "raycast";
|
|
@@ -74,7 +74,7 @@ export declare const agentSolutions: readonly [{
|
|
|
74
74
|
readonly summary: "Recommended: direct hosted MCP.";
|
|
75
75
|
readonly description: "Use hosted MCP for Raycast and similar clients that can connect to a remote MCP server but should not need a local Spacefast install.";
|
|
76
76
|
readonly commands: readonly ["https://mcp.spacefast.com"];
|
|
77
|
-
readonly guideUrl: `${string}/
|
|
77
|
+
readonly guideUrl: `${string}/getting-started/agents`;
|
|
78
78
|
readonly setupText: string;
|
|
79
79
|
}, {
|
|
80
80
|
readonly id: "cursor";
|
|
@@ -84,7 +84,7 @@ export declare const agentSolutions: readonly [{
|
|
|
84
84
|
readonly summary: "Recommended: local MCP when it needs the checkout.";
|
|
85
85
|
readonly description: "Use On-Device MCP for editor agents that need local files; use hosted MCP instead when they only need cloud-safe tools.";
|
|
86
86
|
readonly commands: readonly ["sf setup agent --agent auto --connect", "sf mcp install --agent auto --mode local --transport stdio --connect"];
|
|
87
|
-
readonly guideUrl: `${string}/
|
|
87
|
+
readonly guideUrl: `${string}/getting-started/agents`;
|
|
88
88
|
readonly setupText: string;
|
|
89
89
|
}, {
|
|
90
90
|
readonly id: "terminal";
|
|
@@ -94,7 +94,7 @@ export declare const agentSolutions: readonly [{
|
|
|
94
94
|
readonly summary: "Recommended: Spacefast CLI.";
|
|
95
95
|
readonly description: "Use the CLI for repeat publishes, CI jobs, JSON output, rollback, logs, and domains.";
|
|
96
96
|
readonly commands: readonly [string, "sf login", "sf publish {file-or-dir} --json"];
|
|
97
|
-
readonly guideUrl: `${string}/
|
|
97
|
+
readonly guideUrl: `${string}/cli`;
|
|
98
98
|
readonly setupText: string;
|
|
99
99
|
}, {
|
|
100
100
|
readonly id: "generic";
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { BRAND } from "../brand.js";
|
|
2
|
+
import { DOCS_BASE_URL, serviceOrigin } from "../config/domains.js";
|
|
2
3
|
import { agentSetupPrompt, agentSetupTextUrl, agentSetupUrl } from "./agent-setup.js";
|
|
3
4
|
import { spacefastClaudePluginAddCommand, spacefastClaudePluginInstallCommand, spacefastCodexSkillInstallCommand, spacefastInstallCurlCommand, } from "./skill-distribution.js";
|
|
4
5
|
export const hostedMcpEndpointUrl = "https://mcp.spacefast.com";
|
|
6
|
+
const WEBSITE_ORIGIN = serviceOrigin("www", "prod");
|
|
5
7
|
function pluginText(label, commands, guideUrl) {
|
|
6
8
|
return [
|
|
7
9
|
`Set up ${BRAND.productName} for ${label}.`,
|
|
@@ -24,7 +26,7 @@ function hostedMcpText(label, guideUrl) {
|
|
|
24
26
|
"Minimum scope: mcp:tools",
|
|
25
27
|
"Common scopes: teams:read teams:create spaces:read spaces:write spaces:rename publish:write domains:read domains:write",
|
|
26
28
|
"",
|
|
27
|
-
"Hosted MCP is for cloud/browser agents.
|
|
29
|
+
"Hosted MCP is for cloud/browser agents. Publish small generated files inline or use signed uploads for larger artifacts; it has no filesystem.",
|
|
28
30
|
`Guide: ${guideUrl}`,
|
|
29
31
|
`Plain-text setup contract: ${agentSetupTextUrl}`,
|
|
30
32
|
].join("\n");
|
|
@@ -51,9 +53,9 @@ export const agentSolutions = [
|
|
|
51
53
|
summary: "Recommended: Codex plugin.",
|
|
52
54
|
description: `Install the ${BRAND.productName} skill/plugin so Codex can publish, update, and inspect spaces from the same setup path.`,
|
|
53
55
|
commands: [spacefastCodexSkillInstallCommand],
|
|
54
|
-
guideUrl: `${
|
|
55
|
-
detailGuideUrl: `${
|
|
56
|
-
setupText: pluginText("Codex", [spacefastCodexSkillInstallCommand], `${
|
|
56
|
+
guideUrl: `${WEBSITE_ORIGIN}/for-codex`,
|
|
57
|
+
detailGuideUrl: `${WEBSITE_ORIGIN}/guides/how-to-use-with-codex`,
|
|
58
|
+
setupText: pluginText("Codex", [spacefastCodexSkillInstallCommand], `${WEBSITE_ORIGIN}/for-codex`),
|
|
57
59
|
},
|
|
58
60
|
{
|
|
59
61
|
id: "claude-code",
|
|
@@ -63,9 +65,9 @@ export const agentSolutions = [
|
|
|
63
65
|
summary: "Recommended: Claude plugin.",
|
|
64
66
|
description: `Install the ${BRAND.productName} Claude plugin once, then Claude Code can publish and operate spaces from the terminal.`,
|
|
65
67
|
commands: [spacefastClaudePluginAddCommand, spacefastClaudePluginInstallCommand],
|
|
66
|
-
guideUrl: `${
|
|
67
|
-
detailGuideUrl: `${
|
|
68
|
-
setupText: pluginText("Claude Code", [spacefastClaudePluginAddCommand, spacefastClaudePluginInstallCommand], `${
|
|
68
|
+
guideUrl: `${WEBSITE_ORIGIN}/for-claude`,
|
|
69
|
+
detailGuideUrl: `${WEBSITE_ORIGIN}/guides/how-to-use-with-claude-code`,
|
|
70
|
+
setupText: pluginText("Claude Code", [spacefastClaudePluginAddCommand, spacefastClaudePluginInstallCommand], `${WEBSITE_ORIGIN}/guides/how-to-use-with-claude-code`),
|
|
69
71
|
},
|
|
70
72
|
{
|
|
71
73
|
id: "claude-cowork",
|
|
@@ -75,9 +77,9 @@ export const agentSolutions = [
|
|
|
75
77
|
summary: "Recommended: Claude plugin.",
|
|
76
78
|
description: `Use the ${BRAND.productName} Claude plugin path so Cowork gets the same publish instructions and MCP-aware setup as Claude Code.`,
|
|
77
79
|
commands: [spacefastClaudePluginAddCommand, spacefastClaudePluginInstallCommand],
|
|
78
|
-
guideUrl: `${
|
|
79
|
-
detailGuideUrl: `${
|
|
80
|
-
setupText: pluginText("Claude Cowork", [spacefastClaudePluginAddCommand, spacefastClaudePluginInstallCommand, agentSetupPrompt], `${
|
|
80
|
+
guideUrl: `${WEBSITE_ORIGIN}/for-claude`,
|
|
81
|
+
detailGuideUrl: `${WEBSITE_ORIGIN}/guides/how-to-use-with-claude-cowork`,
|
|
82
|
+
setupText: pluginText("Claude Cowork", [spacefastClaudePluginAddCommand, spacefastClaudePluginInstallCommand, agentSetupPrompt], `${WEBSITE_ORIGIN}/guides/how-to-use-with-claude-cowork`),
|
|
81
83
|
},
|
|
82
84
|
{
|
|
83
85
|
id: "chatgpt",
|
|
@@ -85,10 +87,10 @@ export const agentSolutions = [
|
|
|
85
87
|
aliases: ["chatgpt", "custom gpt", "openai apps"],
|
|
86
88
|
lane: "hosted-mcp",
|
|
87
89
|
summary: "Recommended: direct hosted MCP.",
|
|
88
|
-
description: `Connect ChatGPT-style cloud agents to ${BRAND.productName} through hosted MCP; use
|
|
90
|
+
description: `Connect ChatGPT-style cloud agents to ${BRAND.productName} through hosted MCP; use inline files or signed uploads instead of local paths.`,
|
|
89
91
|
commands: [hostedMcpEndpointUrl],
|
|
90
|
-
guideUrl: `${
|
|
91
|
-
setupText: hostedMcpText("ChatGPT", `${
|
|
92
|
+
guideUrl: `${DOCS_BASE_URL}/getting-started/agents`,
|
|
93
|
+
setupText: hostedMcpText("ChatGPT", `${DOCS_BASE_URL}/getting-started/agents`),
|
|
92
94
|
},
|
|
93
95
|
{
|
|
94
96
|
id: "claude-ai",
|
|
@@ -98,8 +100,8 @@ export const agentSolutions = [
|
|
|
98
100
|
summary: "Recommended: direct hosted MCP.",
|
|
99
101
|
description: `Connect the web Claude app to ${BRAND.productName} through hosted MCP when it cannot read your local checkout.`,
|
|
100
102
|
commands: [hostedMcpEndpointUrl],
|
|
101
|
-
guideUrl: `${
|
|
102
|
-
setupText: hostedMcpText("Claude.ai", `${
|
|
103
|
+
guideUrl: `${DOCS_BASE_URL}/getting-started/agents`,
|
|
104
|
+
setupText: hostedMcpText("Claude.ai", `${DOCS_BASE_URL}/getting-started/agents`),
|
|
103
105
|
},
|
|
104
106
|
{
|
|
105
107
|
id: "raycast",
|
|
@@ -109,8 +111,8 @@ export const agentSolutions = [
|
|
|
109
111
|
summary: "Recommended: direct hosted MCP.",
|
|
110
112
|
description: `Use hosted MCP for Raycast and similar clients that can connect to a remote MCP server but should not need a local ${BRAND.productName} install.`,
|
|
111
113
|
commands: [hostedMcpEndpointUrl],
|
|
112
|
-
guideUrl: `${
|
|
113
|
-
setupText: hostedMcpText("Raycast", `${
|
|
114
|
+
guideUrl: `${DOCS_BASE_URL}/getting-started/agents`,
|
|
115
|
+
setupText: hostedMcpText("Raycast", `${DOCS_BASE_URL}/getting-started/agents`),
|
|
114
116
|
},
|
|
115
117
|
{
|
|
116
118
|
id: "cursor",
|
|
@@ -123,8 +125,8 @@ export const agentSolutions = [
|
|
|
123
125
|
"sf setup agent --agent auto --connect",
|
|
124
126
|
"sf mcp install --agent auto --mode local --transport stdio --connect",
|
|
125
127
|
],
|
|
126
|
-
guideUrl: `${
|
|
127
|
-
setupText: localMcpText("Cursor or another MCP client", `${
|
|
128
|
+
guideUrl: `${DOCS_BASE_URL}/getting-started/agents`,
|
|
129
|
+
setupText: localMcpText("Cursor or another MCP client", `${DOCS_BASE_URL}/getting-started/agents`),
|
|
128
130
|
},
|
|
129
131
|
{
|
|
130
132
|
id: "terminal",
|
|
@@ -134,12 +136,12 @@ export const agentSolutions = [
|
|
|
134
136
|
summary: `Recommended: ${BRAND.productName} CLI.`,
|
|
135
137
|
description: "Use the CLI for repeat publishes, CI jobs, JSON output, rollback, logs, and domains.",
|
|
136
138
|
commands: [spacefastInstallCurlCommand, "sf login", "sf publish {file-or-dir} --json"],
|
|
137
|
-
guideUrl: `${
|
|
139
|
+
guideUrl: `${DOCS_BASE_URL}/cli`,
|
|
138
140
|
setupText: [
|
|
139
141
|
`Install CLI: ${spacefastInstallCurlCommand}`,
|
|
140
142
|
"Login: sf login",
|
|
141
143
|
"Publish: sf publish {file-or-dir} --json",
|
|
142
|
-
`Guide: ${
|
|
144
|
+
`Guide: ${DOCS_BASE_URL}/cli`,
|
|
143
145
|
].join("\n"),
|
|
144
146
|
},
|
|
145
147
|
{
|