@spacefast/common 0.0.12 → 0.0.13
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/contracts/access.d.ts +386 -1201
- package/dist/contracts/access.js +240 -1057
- package/dist/contracts/activity.d.ts +1 -1
- package/dist/contracts/activity.js +6 -14
- package/dist/contracts/api-keys.d.ts +16 -0
- package/dist/contracts/api-keys.js +2 -0
- package/dist/contracts/archives.d.ts +1 -2
- package/dist/contracts/archives.js +4 -6
- package/dist/contracts/comments.d.ts +58 -85
- package/dist/contracts/comments.js +86 -67
- package/dist/contracts/countries.js +2 -7
- package/dist/contracts/data-source-routes.d.ts +20 -0
- package/dist/contracts/data-source-routes.js +15 -0
- package/dist/contracts/device-auth.d.ts +7 -3
- package/dist/contracts/enums.d.ts +2 -4
- package/dist/contracts/enums.js +3 -8
- package/dist/contracts/error-code-meta.d.ts +17 -20
- package/dist/contracts/error-code-meta.js +8 -5
- package/dist/contracts/error-codes.d.ts +1 -1
- package/dist/contracts/error-codes.js +4 -5
- package/dist/contracts/events.d.ts +13 -13
- package/dist/contracts/execution.d.ts +212 -0
- package/dist/contracts/execution.js +288 -0
- package/dist/contracts/feature-lifecycle.d.ts +21 -167
- package/dist/contracts/feature-lifecycle.js +27 -173
- package/dist/contracts/features.d.ts +13 -115
- package/dist/contracts/features.js +1 -31
- package/dist/contracts/functions.d.ts +729 -0
- package/dist/contracts/functions.js +485 -0
- package/dist/contracts/git.d.ts +1 -1
- package/dist/contracts/grants.d.ts +1158 -0
- package/dist/contracts/grants.js +696 -0
- package/dist/contracts/ids.d.ts +5 -3
- package/dist/contracts/ids.js +5 -3
- package/dist/contracts/mcp.d.ts +6 -6
- package/dist/contracts/oauth-resources.d.ts +5 -5
- package/dist/contracts/oauth-resources.js +1 -0
- package/dist/contracts/operations.d.ts +2 -2
- package/dist/contracts/pages.d.ts +6 -14
- package/dist/contracts/pages.js +6 -23
- package/dist/contracts/plan-policy.d.ts +1 -8
- package/dist/contracts/plan-policy.js +1 -4
- package/dist/contracts/platform.d.ts +78 -30
- package/dist/contracts/platform.js +59 -12
- package/dist/contracts/push-new.d.ts +26 -2
- package/dist/contracts/push-new.js +8 -0
- package/dist/contracts/quotas.d.ts +0 -1
- package/dist/contracts/quotas.js +0 -5
- package/dist/contracts/repository-connections.d.ts +1 -1
- package/dist/contracts/resources.d.ts +10 -66
- package/dist/contracts/resources.js +4 -10
- package/dist/contracts/runtime-api.d.ts +558 -265
- package/dist/contracts/runtime-api.js +178 -91
- package/dist/contracts/runtime-app.d.ts +138 -0
- package/dist/contracts/runtime-app.js +21 -0
- package/dist/contracts/sf-config-v1.d.ts +5 -0
- package/dist/contracts/sites.d.ts +5 -0
- package/dist/contracts/sites.js +12 -1
- package/dist/contracts/space-config.d.ts +46 -116
- package/dist/contracts/space-config.js +320 -24
- package/dist/contracts/spaces.d.ts +253 -158
- package/dist/contracts/spaces.js +68 -54
- package/dist/contracts/superadmin-emails.d.ts +2 -2
- package/dist/contracts/superadmin-spaces.d.ts +15 -130
- package/dist/contracts/superadmin-spaces.js +7 -0
- package/dist/contracts/tags.d.ts +23 -23
- package/dist/contracts/teams.d.ts +9 -9
- package/dist/contracts/transfers.d.ts +0 -1
- package/dist/contracts/zero.d.ts +195 -273
- package/dist/contracts/zero.js +78 -206
- package/dist/dashboard-paths/index.d.ts +2 -2
- package/dist/dashboard-paths/index.js +1 -0
- package/dist/docs/agent-prose.js +10 -8
- package/dist/docs/agent-setup.d.ts +2 -2
- package/dist/docs/agent-setup.js +11 -9
- package/dist/docs/agent-solutions.js +1 -1
- package/dist/docs/catalog.d.ts +28 -28
- package/dist/docs/catalog.js +29 -29
- package/dist/docs/error-docs.js +23 -27
- package/dist/utils/asset-fingerprint.d.ts +11 -0
- package/dist/utils/asset-fingerprint.js +46 -0
- package/dist/utils/auth-redirect.d.ts +1 -3
- package/dist/utils/auth-redirect.js +1 -21
- package/dist/utils/build-settings.d.ts +2 -0
- package/dist/utils/build-settings.js +61 -9
- package/dist/utils/credential-policy.d.ts +1 -1
- package/dist/utils/credential-policy.js +4 -0
- package/dist/utils/egress-policy.fixtures.json +1 -1
- package/dist/utils/grants.d.ts +53 -0
- package/dist/utils/grants.js +160 -0
- package/dist/utils/local-space-state.js +1 -0
- package/dist/utils/pages.d.ts +11 -5
- package/dist/utils/pages.js +19 -32
- package/dist/utils/publish-policy.d.ts +34 -4
- package/dist/utils/publish-policy.js +132 -61
- package/dist/utils/query-keys.d.ts +1 -6
- package/dist/utils/query-keys.js +1 -6
- package/dist/utils/space-config.d.ts +5 -1
- package/dist/utils/space-config.js +35 -0
- package/dist/utils/static-runtime-policy.d.ts +5 -0
- package/dist/utils/static-runtime-policy.js +54 -10
- package/dist/utils/upload-session.d.ts +3 -0
- package/dist/utils/upload-session.js +31 -0
- package/package.json +2 -1
- package/dist/utils/access-grant.d.ts +0 -14
- package/dist/utils/access-grant.js +0 -88
- package/dist/utils/access-match.d.ts +0 -46
- package/dist/utils/access-match.fixtures.json +0 -513
- package/dist/utils/access-match.js +0 -312
- package/dist/utils/access-verdict.fixtures.json +0 -421
- package/dist/utils/sf-config-v1.d.ts +0 -2
- package/dist/utils/sf-config-v1.fixtures.json +0 -9
- package/dist/utils/sf-config-v1.js +0 -551
package/dist/contracts/zero.js
CHANGED
|
@@ -1,8 +1,20 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import { dataEnvelope } from "./common.js";
|
|
3
|
+
import { appRoutePathSchema, EXECUTION_ENV_MAX_KEYS, executionBundleSchema, executionCapabilitiesSchema, executionEnvNameSchema, executionIdentifierSchema, executionInspectPolicySchema, executionLogEntrySchema, executionLogListQuerySchema, executionLogListResponseSchema, executionSha256Schema, executionStaticFileSchema, httpMethodSchema, PLATFORM_ROUTE_PREFIX, } from "./execution.js";
|
|
4
|
+
/**
|
|
5
|
+
* Spacefast Zero: capsules — schema, queries, mutations and endpoints that run
|
|
6
|
+
* together inside one parent-owned transaction — executed by the native runner
|
|
7
|
+
* on a dedicated wp.cloud site, against that site's own MySQL.
|
|
8
|
+
*
|
|
9
|
+
* The transaction is what makes this a separate product rather than a
|
|
10
|
+
* placement option for `./functions.js`. A capsule handler's semantics depend
|
|
11
|
+
* on the transaction wrapped around it, and an isolate reaching the database
|
|
12
|
+
* over a relay cannot offer one. See `endpointIsPortable` in `./execution.js`
|
|
13
|
+
* for the narrow surface both products can host.
|
|
14
|
+
*/
|
|
3
15
|
export const ZERO_SOURCE_METADATA_KEY = "statticZero";
|
|
4
16
|
export const ZERO_RUNTIME_KIND = "zero";
|
|
5
|
-
export const ZERO_PLATFORM_ROUTE_PREFIX =
|
|
17
|
+
export const ZERO_PLATFORM_ROUTE_PREFIX = `${PLATFORM_ROUTE_PREFIX}/zero`;
|
|
6
18
|
export const ZERO_CLIENT_ENTRY = "client/index.tsx";
|
|
7
19
|
export const ZERO_SERVER_ENTRY = "server/index.ts";
|
|
8
20
|
export const ZERO_RUNTIME_ROUTE_PATHS = {
|
|
@@ -18,7 +30,7 @@ export const ZERO_RUNTIME_ROUTE_PATHS = {
|
|
|
18
30
|
export const ZERO_RUNTIME_STORAGE_ROOT = "__spacefast/zero";
|
|
19
31
|
export const ZERO_RUNTIME_ARTIFACT_PATH = `${ZERO_RUNTIME_STORAGE_ROOT}/artifact.json`;
|
|
20
32
|
export const ZERO_RUNTIME_CONFIG_PATH = `${ZERO_RUNTIME_STORAGE_ROOT}/config.json`;
|
|
21
|
-
export const ZERO_RUNTIME_BINARY_PATH = `${ZERO_RUNTIME_STORAGE_ROOT}/bin/stattic-
|
|
33
|
+
export const ZERO_RUNTIME_BINARY_PATH = `${ZERO_RUNTIME_STORAGE_ROOT}/bin/stattic-runtime`;
|
|
22
34
|
export const ZERO_RUNTIME_BINARY_COMPATIBILITY_TARGET = "wpcloud-linux-x86_64-gnu-v1";
|
|
23
35
|
export const ZERO_RUNTIME_BUNDLE_ROOT = `${ZERO_RUNTIME_STORAGE_ROOT}/bundles`;
|
|
24
36
|
export const ZERO_RUNTIME_CLIENT_BUNDLE_PATH = `${ZERO_RUNTIME_BUNDLE_ROOT}/client.js`;
|
|
@@ -27,110 +39,28 @@ export const ZERO_SOURCE_ENV_FILE = ".env.zero.server";
|
|
|
27
39
|
export const ZERO_CONFIG_FILE = "zero.json";
|
|
28
40
|
export const ZERO_DEPLOY_FILE = ".zero/deploy.json";
|
|
29
41
|
export const ZERO_RUNTIME_BUNDLE_MAX_BYTES = 786_432;
|
|
30
|
-
export const ZERO_ENV_MAX_KEYS = 64;
|
|
31
|
-
export const ZERO_ENV_NAME_MAX_BYTES = 128;
|
|
32
|
-
export const ZERO_ENV_VALUE_MAX_BYTES = 16 * 1024;
|
|
33
|
-
export const ZERO_ENV_TOTAL_VALUE_MAX_BYTES = 64 * 1024;
|
|
34
|
-
export const ZERO_ENV_RESERVED_PREFIXES = ["SPACEFAST_", "ZERO_"];
|
|
35
42
|
export const ZERO_MANAGED_TABLE_COLUMNS = ["id", "createdAt", "updatedAt"];
|
|
43
|
+
/**
|
|
44
|
+
* Paths the Zero app shell itself answers, on top of the platform-reserved set
|
|
45
|
+
* in `./execution.js`. A capsule cannot claim these because its own client
|
|
46
|
+
* router and auth flow already do.
|
|
47
|
+
*/
|
|
36
48
|
export const ZERO_RESERVED_APP_ROUTE_PATHS = [
|
|
37
49
|
"/",
|
|
38
50
|
"/index.html",
|
|
39
51
|
"/client.js",
|
|
40
52
|
"/auth/callback",
|
|
41
|
-
"/__spacefast",
|
|
42
|
-
"/__span",
|
|
43
53
|
];
|
|
44
|
-
export const ZERO_RESERVED_APP_ROUTE_PREFIXES = ["/auth/"
|
|
45
|
-
|
|
46
|
-
const
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
.regex(/^[A-Za-z_][A-Za-z0-9_]*$/);
|
|
51
|
-
const zeroEnvNameSchema = z
|
|
52
|
-
.string()
|
|
53
|
-
.min(1)
|
|
54
|
-
.max(ZERO_ENV_NAME_MAX_BYTES)
|
|
55
|
-
.regex(/^[A-Za-z_][A-Za-z0-9_]*$/)
|
|
56
|
-
.refine((name) => !ZERO_ENV_RESERVED_PREFIXES.some((prefix) => name.toUpperCase().startsWith(prefix)), { message: "Zero env variable name uses a reserved prefix." });
|
|
57
|
-
function hasWellFormedUnicode(value) {
|
|
58
|
-
for (let index = 0; index < value.length; index++) {
|
|
59
|
-
const codeUnit = value.charCodeAt(index);
|
|
60
|
-
if (codeUnit >= 0xd800 && codeUnit <= 0xdbff) {
|
|
61
|
-
if (index + 1 >= value.length)
|
|
62
|
-
return false;
|
|
63
|
-
const next = value.charCodeAt(index + 1);
|
|
64
|
-
if (next < 0xdc00 || next > 0xdfff)
|
|
65
|
-
return false;
|
|
66
|
-
index++;
|
|
67
|
-
}
|
|
68
|
-
else if (codeUnit >= 0xdc00 && codeUnit <= 0xdfff) {
|
|
69
|
-
return false;
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
return true;
|
|
73
|
-
}
|
|
74
|
-
function hasNoAsciiControlCharacters(value) {
|
|
75
|
-
for (let index = 0; index < value.length; index++) {
|
|
76
|
-
const codeUnit = value.charCodeAt(index);
|
|
77
|
-
if (codeUnit <= 0x1f || codeUnit === 0x7f)
|
|
78
|
-
return false;
|
|
79
|
-
}
|
|
80
|
-
return true;
|
|
81
|
-
}
|
|
82
|
-
const zeroRoutePathSchema = z
|
|
83
|
-
.string()
|
|
84
|
-
.min(1)
|
|
85
|
-
.max(2048)
|
|
86
|
-
.startsWith("/")
|
|
87
|
-
.refine(hasWellFormedUnicode, {
|
|
88
|
-
message: "Zero capsule routes must contain well-formed Unicode.",
|
|
89
|
-
})
|
|
90
|
-
.refine((path) => path.normalize("NFC") === path, {
|
|
91
|
-
message: "Zero capsule routes must use NFC-normalized Unicode.",
|
|
92
|
-
})
|
|
93
|
-
.refine(hasNoAsciiControlCharacters, {
|
|
94
|
-
message: "Zero capsule routes must not contain ASCII control characters.",
|
|
95
|
-
})
|
|
96
|
-
.refine((path) => !path.includes("//") &&
|
|
97
|
-
!path.includes("\\") &&
|
|
98
|
-
!path.includes("*") &&
|
|
99
|
-
!path.includes("?") &&
|
|
100
|
-
!path.includes("#") &&
|
|
101
|
-
!path.endsWith("/") &&
|
|
102
|
-
path
|
|
103
|
-
.split("/")
|
|
104
|
-
.every((segment, index, segments) => segment !== "." &&
|
|
105
|
-
segment !== ".." &&
|
|
106
|
-
segment !== ":" &&
|
|
107
|
-
(segment !== ":splat" || index === segments.length - 1)), {
|
|
108
|
-
message: "Zero capsule routes must be absolute app paths without empty, traversal, unnamed parameter, * wildcard, non-terminal splat, \\, ?, or # segments.",
|
|
109
|
-
})
|
|
110
|
-
.refine((path) => !ZERO_RESERVED_APP_ROUTE_PATHS.some((reservedPath) => path === reservedPath), {
|
|
111
|
-
message: "Zero capsule route is reserved by the Zero app shell.",
|
|
112
|
-
})
|
|
113
|
-
.refine((path) => !ZERO_RESERVED_APP_ROUTE_PREFIXES.some((reservedPrefix) => path.startsWith(reservedPrefix)), {
|
|
114
|
-
message: "Zero capsule route prefix is reserved by the Zero app shell.",
|
|
115
|
-
})
|
|
116
|
-
.refine((path) => !path.startsWith(ZERO_PLATFORM_ROUTE_PREFIX), {
|
|
117
|
-
message: `Zero capsule routes cannot use ${ZERO_PLATFORM_ROUTE_PREFIX}.`,
|
|
118
|
-
})
|
|
119
|
-
.refine((path) => path !== "/__stattic" && !path.startsWith("/__stattic/"), {
|
|
120
|
-
message: "Zero capsule routes cannot use Spacefast private control paths.",
|
|
54
|
+
export const ZERO_RESERVED_APP_ROUTE_PREFIXES = ["/auth/"];
|
|
55
|
+
const zeroNameSchema = executionIdentifierSchema;
|
|
56
|
+
const zeroRoutePathSchema = appRoutePathSchema({
|
|
57
|
+
subject: "Zero capsule routes",
|
|
58
|
+
reservedPaths: ZERO_RESERVED_APP_ROUTE_PATHS,
|
|
59
|
+
reservedPrefixes: ZERO_RESERVED_APP_ROUTE_PREFIXES,
|
|
121
60
|
});
|
|
122
|
-
export const zeroHttpMethodSchema = z.enum([
|
|
123
|
-
"GET",
|
|
124
|
-
"HEAD",
|
|
125
|
-
"POST",
|
|
126
|
-
"PUT",
|
|
127
|
-
"PATCH",
|
|
128
|
-
"DELETE",
|
|
129
|
-
"OPTIONS",
|
|
130
|
-
]);
|
|
131
61
|
export const zeroEndpointSchema = z
|
|
132
62
|
.object({
|
|
133
|
-
method:
|
|
63
|
+
method: httpMethodSchema,
|
|
134
64
|
path: zeroRoutePathSchema,
|
|
135
65
|
})
|
|
136
66
|
.strict();
|
|
@@ -227,46 +157,21 @@ export const zeroTableSchema = z
|
|
|
227
157
|
})
|
|
228
158
|
.strict();
|
|
229
159
|
export const zeroDatabaseSchema = z.record(z.string(), zeroTableSchema);
|
|
230
|
-
const zeroSha256Schema =
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
size: z.number().int().nonnegative().max(ZERO_RUNTIME_BUNDLE_MAX_BYTES),
|
|
245
|
-
contentBase64: zeroBase64Schema,
|
|
246
|
-
})
|
|
247
|
-
.strict();
|
|
248
|
-
const zeroPublicStaticPathSchema = z
|
|
249
|
-
.string()
|
|
250
|
-
.min(1)
|
|
251
|
-
.max(2048)
|
|
252
|
-
.refine((path) => !path.startsWith("/") && !path.split("/").includes(".."), {
|
|
253
|
-
message: "Zero static file paths must be relative and cannot traverse.",
|
|
254
|
-
})
|
|
255
|
-
.refine((path) => !path.startsWith(ZERO_RUNTIME_STORAGE_ROOT + "/"), {
|
|
256
|
-
message: `Zero static files cannot use ${ZERO_RUNTIME_STORAGE_ROOT}.`,
|
|
257
|
-
})
|
|
258
|
-
.refine((path) => !path.startsWith("_") && !path.startsWith("."), {
|
|
259
|
-
message: "Zero static file paths cannot use private root prefixes.",
|
|
160
|
+
const zeroSha256Schema = executionSha256Schema;
|
|
161
|
+
/**
|
|
162
|
+
* Zero's bundles travel inline in the finalize payload — a capsule's compiled
|
|
163
|
+
* client and server fit comfortably under the ceiling, and inlining keeps the
|
|
164
|
+
* whole version one atomic write. Functions bundles do the opposite and land
|
|
165
|
+
* in the content store first; see `functionsBundleRefSchema`.
|
|
166
|
+
*/
|
|
167
|
+
export const zeroRuntimeBundleSchema = executionBundleSchema({
|
|
168
|
+
bundleRoot: ZERO_RUNTIME_BUNDLE_ROOT,
|
|
169
|
+
maxBytes: ZERO_RUNTIME_BUNDLE_MAX_BYTES,
|
|
170
|
+
});
|
|
171
|
+
export const zeroRuntimeStaticFileSchema = executionStaticFileSchema({
|
|
172
|
+
storageRoot: ZERO_RUNTIME_STORAGE_ROOT,
|
|
173
|
+
maxBytes: ZERO_RUNTIME_BUNDLE_MAX_BYTES,
|
|
260
174
|
});
|
|
261
|
-
export const zeroRuntimeStaticFileSchema = z
|
|
262
|
-
.object({
|
|
263
|
-
path: zeroPublicStaticPathSchema,
|
|
264
|
-
contentType: z.string().min(1).max(255),
|
|
265
|
-
sha256: zeroSha256Schema,
|
|
266
|
-
size: z.number().int().nonnegative().max(ZERO_RUNTIME_BUNDLE_MAX_BYTES),
|
|
267
|
-
contentBase64: zeroBase64Schema,
|
|
268
|
-
})
|
|
269
|
-
.strict();
|
|
270
175
|
export const zeroRuntimeRunSourceSchema = z
|
|
271
176
|
.object({
|
|
272
177
|
runId: z.string().min(1).max(256),
|
|
@@ -275,23 +180,13 @@ export const zeroRuntimeRunSourceSchema = z
|
|
|
275
180
|
.min(1)
|
|
276
181
|
.max(2 * 1024 * 1024),
|
|
277
182
|
schemaHash: z.string().min(1).max(256).optional(),
|
|
278
|
-
capabilities:
|
|
279
|
-
.object({
|
|
280
|
-
db: z.boolean().default(false),
|
|
281
|
-
fetch: z.boolean().default(false),
|
|
282
|
-
auth: z.boolean().default(false),
|
|
283
|
-
env: z.boolean().default(false),
|
|
284
|
-
realtime: z.boolean().default(false),
|
|
285
|
-
logging: z.boolean().default(false),
|
|
286
|
-
})
|
|
287
|
-
.partial()
|
|
288
|
-
.default({}),
|
|
183
|
+
capabilities: executionCapabilitiesSchema,
|
|
289
184
|
db: z.record(z.string(), z.unknown()).optional(),
|
|
290
185
|
})
|
|
291
186
|
.strict();
|
|
292
187
|
export const zeroRuntimeEndpointSourceSchema = z
|
|
293
188
|
.object({
|
|
294
|
-
method:
|
|
189
|
+
method: httpMethodSchema,
|
|
295
190
|
path: zeroRoutePathSchema,
|
|
296
191
|
endpointId: z.string().min(1).max(256),
|
|
297
192
|
source: z
|
|
@@ -375,7 +270,7 @@ const zeroRuntimePublicRealtimeCanonicalModeSchema = z.enum([
|
|
|
375
270
|
]);
|
|
376
271
|
export const zeroRealtimeModeSchema = zeroRealtimeCanonicalModeSchema;
|
|
377
272
|
export const zeroRuntimePublicRealtimeModeSchema = zeroRuntimePublicRealtimeCanonicalModeSchema;
|
|
378
|
-
export const zeroInspectPolicySchema =
|
|
273
|
+
export const zeroInspectPolicySchema = executionInspectPolicySchema;
|
|
379
274
|
const zeroRuntimePublicPathSchema = z.string().min(1).startsWith("/");
|
|
380
275
|
const zeroHttpUrlSchema = z
|
|
381
276
|
.string()
|
|
@@ -500,7 +395,7 @@ export const zeroSourceManifestSchema = z
|
|
|
500
395
|
env: z
|
|
501
396
|
.object({
|
|
502
397
|
file: z.literal(ZERO_SOURCE_ENV_FILE),
|
|
503
|
-
names: z.array(
|
|
398
|
+
names: z.array(executionEnvNameSchema).max(EXECUTION_ENV_MAX_KEYS).default([]),
|
|
504
399
|
})
|
|
505
400
|
.nullable()
|
|
506
401
|
.default(null),
|
|
@@ -643,38 +538,40 @@ export const zeroDeployMetadataSchema = z
|
|
|
643
538
|
finalize: zeroRuntimeFinalizePayloadSchema,
|
|
644
539
|
})
|
|
645
540
|
.strict();
|
|
646
|
-
|
|
541
|
+
/**
|
|
542
|
+
* What a live Zero capsule is, as the `app` member of a space's runtime status.
|
|
543
|
+
*
|
|
544
|
+
* There is no `versionId` here: this only ever describes the version the status
|
|
545
|
+
* response already names as live, and repeating it would invite the two to
|
|
546
|
+
* disagree. `artifactId` stays because it identifies the built capsule rather
|
|
547
|
+
* than the publish that carries it.
|
|
548
|
+
*/
|
|
549
|
+
export const zeroAppSchema = z
|
|
647
550
|
.object({
|
|
648
|
-
|
|
649
|
-
artifactId: z.string().min(1)
|
|
650
|
-
|
|
551
|
+
runtimeKind: z.literal(ZERO_RUNTIME_KIND),
|
|
552
|
+
artifactId: z.string().min(1),
|
|
553
|
+
appName: z.string().min(1),
|
|
554
|
+
serverRuntime: z.literal("quickjs-rust"),
|
|
555
|
+
inspect: z
|
|
651
556
|
.object({
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
sockets: z.array(z.string()).default([]),
|
|
666
|
-
variables: z
|
|
667
|
-
.object({
|
|
668
|
-
source: z.literal("stattic-variables"),
|
|
669
|
-
names: z.array(z.string()).default([]),
|
|
670
|
-
})
|
|
671
|
-
.strict(),
|
|
672
|
-
realtime: zeroRuntimePublicRealtimeConfigSchema,
|
|
557
|
+
policy: zeroInspectPolicySchema,
|
|
558
|
+
})
|
|
559
|
+
.strict(),
|
|
560
|
+
install: zeroRuntimeInstallProfileSchema,
|
|
561
|
+
tables: z.array(z.string()).default([]),
|
|
562
|
+
queries: z.array(z.string()).default([]),
|
|
563
|
+
mutations: z.array(z.string()).default([]),
|
|
564
|
+
endpoints: z.array(zeroEndpointSchema).default([]),
|
|
565
|
+
sockets: z.array(z.string()).default([]),
|
|
566
|
+
variables: z
|
|
567
|
+
.object({
|
|
568
|
+
source: z.literal("stattic-variables"),
|
|
569
|
+
names: z.array(z.string()).default([]),
|
|
673
570
|
})
|
|
674
|
-
.
|
|
571
|
+
.strict(),
|
|
572
|
+
realtime: zeroRuntimePublicRealtimeConfigSchema,
|
|
675
573
|
})
|
|
676
574
|
.strict();
|
|
677
|
-
export const zeroInspectPublicResponseSchema = dataEnvelope(zeroInspectResponseSchema);
|
|
678
575
|
export const zeroDbInspectResponseSchema = z
|
|
679
576
|
.object({
|
|
680
577
|
versionId: z.string().min(1).nullable(),
|
|
@@ -708,36 +605,11 @@ export const zeroDbDumpResponseSchema = z
|
|
|
708
605
|
})
|
|
709
606
|
.strict();
|
|
710
607
|
export const zeroDbDumpPublicResponseSchema = dataEnvelope(zeroDbDumpResponseSchema);
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
mutationName: z.string().min(1).optional(),
|
|
717
|
-
})
|
|
718
|
-
.strict();
|
|
719
|
-
export const zeroLogEntrySchema = z
|
|
720
|
-
.object({
|
|
721
|
-
id: z.string().min(1),
|
|
722
|
-
timestamp: z.string().datetime(),
|
|
723
|
-
level: z.enum(["debug", "info", "warn", "error"]),
|
|
724
|
-
requestId: z.string().min(1).nullable(),
|
|
725
|
-
versionId: z.string().min(1).nullable(),
|
|
726
|
-
mutationName: z.string().min(1).nullable(),
|
|
727
|
-
message: z.string(),
|
|
728
|
-
metadata: z.record(z.string(), z.unknown()).default({}),
|
|
729
|
-
})
|
|
730
|
-
.strict();
|
|
731
|
-
export const zeroLogListResponseSchema = z
|
|
732
|
-
.object({
|
|
733
|
-
data: z.array(zeroLogEntrySchema),
|
|
734
|
-
pagination: z
|
|
735
|
-
.object({
|
|
736
|
-
nextCursor: z.string().nullable(),
|
|
737
|
-
})
|
|
738
|
-
.strict(),
|
|
739
|
-
})
|
|
740
|
-
.strict();
|
|
608
|
+
// Both products emit the same log shape; `handlerName` carries the mutation
|
|
609
|
+
// name here and the worker handler name on Functions.
|
|
610
|
+
export const zeroLogListQuerySchema = executionLogListQuerySchema;
|
|
611
|
+
export const zeroLogEntrySchema = executionLogEntrySchema;
|
|
612
|
+
export const zeroLogListResponseSchema = executionLogListResponseSchema;
|
|
741
613
|
export const zeroRealtimeEventIntakeResponseSchema = z
|
|
742
614
|
.object({
|
|
743
615
|
accepted: z.literal(true),
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Append-only: add a new top-level static dashboard route's first segment here
|
|
5
5
|
* before its route module lands. A repository structural test enforces this.
|
|
6
6
|
*/
|
|
7
|
-
export declare const TEAM_SLUG_ROUTE_RESERVATIONS: readonly ["accept-beta-invite", "accept-invitation", "account", "agent", "claim", "device", "drop", "new-team", "oauth", "sign-in", "start", "terminal", "two-factor"];
|
|
7
|
+
export declare const TEAM_SLUG_ROUTE_RESERVATIONS: readonly ["accept-beta-invite", "accept-invitation", "account", "access", "agent", "claim", "device", "drop", "new-team", "oauth", "sign-in", "start", "terminal", "two-factor"];
|
|
8
8
|
/**
|
|
9
9
|
* Dashboard route first-segments that cannot be used as space slugs.
|
|
10
10
|
*
|
|
@@ -18,7 +18,7 @@ export type SpaceSlugRouteReservation = (typeof SPACE_SLUG_ROUTE_RESERVATIONS)[n
|
|
|
18
18
|
export declare const TEAM_SLUG_ROUTE_RESERVATION_SET: ReadonlySet<string>;
|
|
19
19
|
export declare const SPACE_SLUG_ROUTE_RESERVATION_SET: ReadonlySet<string>;
|
|
20
20
|
export type SpaceSettingsDestination = "access" | "advanced" | "builds" | "integrations" | "integrations/add" | "source-builds";
|
|
21
|
-
export type TeamSettingsDestination = "access" | "audit" | "developer" | "developer/agents" | "developer/environment-variables" | "developer/handoffs" | "developer/
|
|
21
|
+
export type TeamSettingsDestination = "access" | "audit" | "developer" | "developer/agents" | "developer/environment-variables" | "developer/handoffs" | "developer/webhooks" | "integrations";
|
|
22
22
|
export declare function teamPath(teamSlug: string): string;
|
|
23
23
|
export declare function spacePath(teamSlug: string, spaceSlug: string): string;
|
|
24
24
|
export declare function versionDetailPath(teamSlug: string, spaceSlug: string, versionRef: string): string;
|
|
@@ -8,6 +8,7 @@ export const TEAM_SLUG_ROUTE_RESERVATIONS = [
|
|
|
8
8
|
"accept-beta-invite",
|
|
9
9
|
"accept-invitation",
|
|
10
10
|
"account",
|
|
11
|
+
"access",
|
|
11
12
|
// Not a TanStack route module: /agent* is the edge-served handoff-document
|
|
12
13
|
// surface (apps/my/public/_redirects + vite middleware, #417). Those rewrite
|
|
13
14
|
// rules deliberately swallow every /agent-prefixed path, so a team named
|
package/dist/docs/agent-prose.js
CHANGED
|
@@ -79,9 +79,9 @@ export const POSITIONING_PROSE = [
|
|
|
79
79
|
"optimizes for agent-safe one-shot publish, claim, versioning, rollback, and continuation.",
|
|
80
80
|
].join("\n");
|
|
81
81
|
export const EXPLAIN_TO_USER_PROSE = [
|
|
82
|
-
"
|
|
83
|
-
"
|
|
84
|
-
"named and revocable in the dashboard.",
|
|
82
|
+
"Report the bare Live URL, repeatable expiring private Open URL, immutable Version URL, and Claim link",
|
|
83
|
+
"as separate actions. State anonymous expiry in user terms: the space expires unless claimed by",
|
|
84
|
+
"`data.claim.expiresAt`. After claim, the agent key is named and revocable in the dashboard.",
|
|
85
85
|
].join("\n");
|
|
86
86
|
export const FAILURE_CONDUCT_PROSE = [
|
|
87
87
|
"On failure, surface `error.code`, `error.docsUrl`, and `error.requestId`, then stop.",
|
|
@@ -181,7 +181,7 @@ export const CONTINUE_AFTER_CLAIM_PROSE = [
|
|
|
181
181
|
"Save `data.credential.accessToken` into `.spacefast/state.json` (replace the `claimToken`",
|
|
182
182
|
'field with `"accessToken"`), then retry the publish with the new bearer. The exchange works',
|
|
183
183
|
"exactly once; if it returns `continuation_used` or `continuation_unavailable`, ask the user",
|
|
184
|
-
"to
|
|
184
|
+
"to create an API key in the dashboard (Account → API keys).",
|
|
185
185
|
].join("\n");
|
|
186
186
|
/**
|
|
187
187
|
* The zero-install publish sequence: one curl for a file, a secret-preflighted
|
|
@@ -216,10 +216,12 @@ export const RECEIPT_SHAPE_PROSE = [
|
|
|
216
216
|
"The JSON receipt is the source of truth:",
|
|
217
217
|
"",
|
|
218
218
|
"- `data.space.liveUrl` — the live URL.",
|
|
219
|
-
"- `data.
|
|
220
|
-
" It is
|
|
221
|
-
"
|
|
222
|
-
"
|
|
219
|
+
"- `data.open.url` and `data.open.expiresAt` — a repeatable private author Link until expiry, claim, or revocation.",
|
|
220
|
+
" It is not a stable URL or recipient Link; clients must not persist it as Space state.",
|
|
221
|
+
"- `data.version.immutableUrl` — the permanent address of the frozen Version. The bare URL",
|
|
222
|
+
" carries no authority: use the receipt's Open URL for the author's browser or create a scoped",
|
|
223
|
+
" Link for a recipient. It is reserved in the initial receipt. If the publish is still",
|
|
224
|
+
" finalizing, poll `data.links.status` with the claim token until the status is `ready`.",
|
|
223
225
|
"- `data.upload` — signed upload instructions for manifest publishes when file bytes were not sent",
|
|
224
226
|
" with the request. Send each `data.upload.targets[]` instruction exactly as returned, treat",
|
|
225
227
|
" authorization headers and upload tokens as secrets, then finalize.",
|
|
@@ -50,13 +50,13 @@ export declare function parseAgentHandoffUrl(value: string, expectedOrigin: stri
|
|
|
50
50
|
}>;
|
|
51
51
|
/** Connect targets whose handoff continues through the CLI stdin exchange. */
|
|
52
52
|
export declare const AGENT_HANDOFF_CLI_TARGET_IDS: readonly ConnectTargetId[];
|
|
53
|
-
export declare const AGENT_HANDOFF_PREAMBLE = "Talk to the user before installing tools or publishing. Confirm the file or folder they want to
|
|
53
|
+
export declare const AGENT_HANDOFF_PREAMBLE = "Talk to the user before installing tools or publishing. Confirm the file or folder they want to publish.";
|
|
54
54
|
/** The fetch-safety contract: reading the document never consumes or leaks a handoff. */
|
|
55
55
|
export declare const AGENT_HANDOFF_FETCH_SAFETY = "Keep the original handoff link private. Fetching this document did not use the link or send its fragment secret; the secret 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.";
|
|
56
56
|
export declare const AGENT_HANDOFF_FRAGMENT_HYGIENE = "Keep its fragment out of commands, request URLs, logs, and replies.";
|
|
57
57
|
export declare const AGENT_HANDOFF_CLI_APPROVAL_GUIDANCE: string;
|
|
58
58
|
export declare const AGENT_HANDOFF_BROWSER_APPROVAL_GUIDANCE = "When the client opens browser approval, ask the user to approve there before publishing.";
|
|
59
|
-
export declare const AGENT_HANDOFF_PUBLISH_PROSE = "After approval, confirm the selected Space and permissions, then publish only the files the user approved.
|
|
59
|
+
export declare 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 Open URL; create a scoped Link when a recipient needs access.";
|
|
60
60
|
/** One target's Connect prose: blurb, copyable setup blocks, deeplink/download lines. */
|
|
61
61
|
export declare function agentHandoffConnectSections(target: ConnectTarget): string[];
|
|
62
62
|
/** Builds every copy-ready handoff artifact from one validated URL and target catalog row. */
|
package/dist/docs/agent-setup.js
CHANGED
|
@@ -112,13 +112,13 @@ function validateMcpEndpoint(value) {
|
|
|
112
112
|
*/
|
|
113
113
|
/** Connect targets whose handoff continues through the CLI stdin exchange. */
|
|
114
114
|
export const AGENT_HANDOFF_CLI_TARGET_IDS = ["claude-code", "codex"];
|
|
115
|
-
export const AGENT_HANDOFF_PREAMBLE = "Talk to the user before installing tools or publishing. Confirm the file or folder they want to
|
|
115
|
+
export const AGENT_HANDOFF_PREAMBLE = "Talk to the user before installing tools or publishing. Confirm the file or folder they want to publish.";
|
|
116
116
|
/** The fetch-safety contract: reading the document never consumes or leaks a handoff. */
|
|
117
117
|
export const AGENT_HANDOFF_FETCH_SAFETY = "Keep the original handoff link private. Fetching this document did not use the link or send its fragment secret; the secret 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.";
|
|
118
118
|
export const AGENT_HANDOFF_FRAGMENT_HYGIENE = "Keep its fragment out of commands, request URLs, logs, and replies.";
|
|
119
119
|
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
120
|
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.
|
|
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 Open URL; create a scoped Link when a recipient needs access.";
|
|
122
122
|
/** One target's Connect prose: blurb, copyable setup blocks, deeplink/download lines. */
|
|
123
123
|
export function agentHandoffConnectSections(target) {
|
|
124
124
|
const setupSections = [target.primary, target.config].flatMap((setup) => setup ? [[setup.label, `\`\`\`${setup.language}`, setup.value, "```"].join("\n")] : []);
|
|
@@ -250,7 +250,7 @@ export function aiInstructionsText() {
|
|
|
250
250
|
"## Install the CLI (On-Device files, updates, versions, rollback, and the rest)",
|
|
251
251
|
"",
|
|
252
252
|
"The CLI is the full surface: incremental publishes, version history, rollback,",
|
|
253
|
-
"
|
|
253
|
+
"sharing, domains, logs, and diagnostics. Install it when the user will keep",
|
|
254
254
|
"working on the space:",
|
|
255
255
|
"",
|
|
256
256
|
"```bash",
|
|
@@ -291,7 +291,8 @@ export function aiInstructionsText() {
|
|
|
291
291
|
"Request `mcp:tools` plus the API scopes the tools need: `teams:read` for team context,",
|
|
292
292
|
"`teams:create` for creating teams,",
|
|
293
293
|
"`spaces:read` for status, versions, diffs, and logs, `spaces:write` for claim/create/update,",
|
|
294
|
-
"`
|
|
294
|
+
"`spaces:rename` for slug and managed-address renames, `publish:write` for publish and rollback,",
|
|
295
|
+
"and `domains:read`/`domains:write` for domain",
|
|
295
296
|
"inventory, DNS diagnostics, assignment, verification, and mutation. Hosted MCP does not read",
|
|
296
297
|
"local paths; its workspace tools operate on a durable virtual workspace attached to the MCP",
|
|
297
298
|
"session.",
|
|
@@ -329,8 +330,10 @@ export function aiInstructionsText() {
|
|
|
329
330
|
"",
|
|
330
331
|
"## After publishing",
|
|
331
332
|
"",
|
|
332
|
-
"-
|
|
333
|
-
" the claim link with its expiry.
|
|
333
|
+
"- Report the bare Live URL, the immutable Version URL when ready, the private Open URL, and",
|
|
334
|
+
" — for anonymous spaces — the claim link with its expiry. Bare Live and Version URLs carry",
|
|
335
|
+
" no authority for a private Space; create a scoped Link when a recipient needs access.",
|
|
336
|
+
" If the receipt's immutable URL is null, poll the",
|
|
334
337
|
" operation and version links with the claim token as bearer auth until the version is ready.",
|
|
335
338
|
"- Never print access tokens, claim tokens, auth files, or `.spacefast/state.json`.",
|
|
336
339
|
"",
|
|
@@ -342,7 +345,7 @@ export function aiInstructionsText() {
|
|
|
342
345
|
"",
|
|
343
346
|
"- `_redirects` — redirects, rewrites, SPA fallbacks, custom 404 rules, and external",
|
|
344
347
|
" `200` proxy rules.",
|
|
345
|
-
"- `_headers` — response headers
|
|
348
|
+
"- `_headers` — supported response headers.",
|
|
346
349
|
"- `404.html` — custom not-found page.",
|
|
347
350
|
"- `sf.jsonc` — serving config (index, fallback, listing, meta) and the optional",
|
|
348
351
|
" `space` link. JSON Schema: https://spacefast.com/schemas/sf.json",
|
|
@@ -350,8 +353,7 @@ export function aiInstructionsText() {
|
|
|
350
353
|
" agent-readable too.",
|
|
351
354
|
"- Plan limits surface as diagnostics, not failures you should guess at: publish the",
|
|
352
355
|
" intended artifact, then read and report what the CLI or API says. When a feature",
|
|
353
|
-
' is plan-gated, say: "Not available on Free. Available on Personal and Work."
|
|
354
|
-
" simple gated access, `sf password set` needs no plan and no `_headers` rule.",
|
|
356
|
+
' is plan-gated, say: "Not available on Free. Available on Personal and Work."',
|
|
355
357
|
"",
|
|
356
358
|
"## Agent-aware routing",
|
|
357
359
|
"",
|
|
@@ -22,7 +22,7 @@ function hostedMcpText(label, guideUrl) {
|
|
|
22
22
|
"Transport: Streamable HTTP",
|
|
23
23
|
"Resource: https://mcp.spacefast.com",
|
|
24
24
|
"Minimum scope: mcp:tools",
|
|
25
|
-
"Common scopes: teams:read teams:create spaces:read spaces:write publish:write domains:read domains:write",
|
|
25
|
+
"Common scopes: teams:read teams:create spaces:read spaces:write spaces:rename publish:write domains:read domains:write",
|
|
26
26
|
"",
|
|
27
27
|
"Hosted MCP is for cloud/browser agents. It does not read local paths; use the hosted workspace tools or signed uploads for artifacts.",
|
|
28
28
|
`Guide: ${guideUrl}`,
|