frontpage-host 0.1.7 → 0.1.9
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/AGENTS.md +10 -6
- package/dist/commands/deploy.js +9 -27
- package/dist/commands/media.js +24 -14
- package/dist/commands/prompt-attach.d.ts +12 -10
- package/dist/commands/prompt-attach.js +55 -22
- package/dist/commands/prompt.js +3 -1
- package/dist/commands/push.js +55 -19
- package/dist/commands/runs.js +33 -19
- package/dist/commands/wait-agent-idle.d.ts +49 -0
- package/dist/commands/wait-agent-idle.js +181 -0
- package/dist/http/client.d.ts +13 -7
- package/dist/http/client.js +46 -51
- package/dist/media/limits.d.ts +18 -0
- package/dist/media/limits.js +101 -0
- package/dist/media/select-transport.d.ts +27 -0
- package/dist/media/select-transport.js +134 -0
- package/dist/media/upload.d.ts +16 -0
- package/dist/media/upload.js +140 -0
- package/dist/registry.js +41 -16
- package/dist/runtime.d.ts +10 -0
- package/dist/runtime.js +32 -12
- package/llms.txt +5 -3
- package/package.json +4 -1
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared local-file upload used by `frontpage media upload` and `prompt --attach`.
|
|
3
|
+
*/
|
|
4
|
+
import { randomUUID } from "node:crypto";
|
|
5
|
+
import { readFile } from "node:fs/promises";
|
|
6
|
+
import { basename } from "node:path";
|
|
7
|
+
import { put } from "@vercel/blob/client";
|
|
8
|
+
import { apiBase, CliHttpError, EXIT_AUTH, EXIT_UNEXPECTED, EXIT_USAGE, getBearerAuthHeader, httpErrorFromV1, v1PostMultipart, } from "../http/client.js";
|
|
9
|
+
import { contentTypeForExt, sitePathFromKey } from "./limits.js";
|
|
10
|
+
import { selectMediaTransport } from "./select-transport.js";
|
|
11
|
+
async function requestClientToken(args) {
|
|
12
|
+
const auth = await getBearerAuthHeader();
|
|
13
|
+
const url = `${apiBase()}/api/v1/sites/${encodeURIComponent(args.slug)}/media/client`;
|
|
14
|
+
let res;
|
|
15
|
+
try {
|
|
16
|
+
res = await fetch(url, {
|
|
17
|
+
method: "POST",
|
|
18
|
+
headers: {
|
|
19
|
+
...auth,
|
|
20
|
+
Accept: "application/json",
|
|
21
|
+
"Content-Type": "application/json",
|
|
22
|
+
},
|
|
23
|
+
body: JSON.stringify({
|
|
24
|
+
type: "blob.generate-client-token",
|
|
25
|
+
payload: {
|
|
26
|
+
pathname: args.pathname,
|
|
27
|
+
clientPayload: JSON.stringify({ declaredSize: args.declaredSize }),
|
|
28
|
+
multipart: args.multipart,
|
|
29
|
+
},
|
|
30
|
+
}),
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
catch (err) {
|
|
34
|
+
throw new CliHttpError(`Network error: ${err instanceof Error ? err.message : String(err)}`, EXIT_UNEXPECTED, 0);
|
|
35
|
+
}
|
|
36
|
+
const text = await res.text();
|
|
37
|
+
let parsed = {};
|
|
38
|
+
try {
|
|
39
|
+
parsed = text ? JSON.parse(text) : {};
|
|
40
|
+
}
|
|
41
|
+
catch {
|
|
42
|
+
parsed = {};
|
|
43
|
+
}
|
|
44
|
+
if (!res.ok) {
|
|
45
|
+
const msg = typeof parsed.error === "string"
|
|
46
|
+
? parsed.error
|
|
47
|
+
: typeof parsed.error === "object" && parsed.error?.message
|
|
48
|
+
? parsed.error.message
|
|
49
|
+
: `Upload authorization failed (${res.status})`;
|
|
50
|
+
// Auth / rate-limit use v1 envelopes; policy denials use { error: string }.
|
|
51
|
+
if (typeof parsed.error === "object" && parsed.error) {
|
|
52
|
+
throw httpErrorFromV1(res.status, parsed, msg);
|
|
53
|
+
}
|
|
54
|
+
if (res.status === 401 || res.status === 403) {
|
|
55
|
+
throw new CliHttpError(msg, EXIT_AUTH, res.status);
|
|
56
|
+
}
|
|
57
|
+
if (res.status === 402 || res.status === 413 || res.status === 429 || res.status === 400) {
|
|
58
|
+
throw new CliHttpError(msg, EXIT_USAGE, res.status);
|
|
59
|
+
}
|
|
60
|
+
throw new CliHttpError(msg, EXIT_UNEXPECTED, res.status);
|
|
61
|
+
}
|
|
62
|
+
if (typeof parsed.clientToken !== "string" || !parsed.clientToken) {
|
|
63
|
+
throw new CliHttpError("Upload authorization failed (no client token).", EXIT_UNEXPECTED, res.status);
|
|
64
|
+
}
|
|
65
|
+
return parsed.clientToken;
|
|
66
|
+
}
|
|
67
|
+
async function uploadViaClient(args) {
|
|
68
|
+
const pathname = `uploads/${args.slug}/${randomUUID()}.${args.ext}`;
|
|
69
|
+
const multipart = args.bytes.length > 8 * 1024 * 1024;
|
|
70
|
+
const clientToken = await requestClientToken({
|
|
71
|
+
slug: args.slug,
|
|
72
|
+
pathname,
|
|
73
|
+
declaredSize: args.bytes.length,
|
|
74
|
+
multipart,
|
|
75
|
+
});
|
|
76
|
+
try {
|
|
77
|
+
const blob = await put(pathname, args.bytes, {
|
|
78
|
+
access: "public",
|
|
79
|
+
token: clientToken,
|
|
80
|
+
contentType: args.contentType,
|
|
81
|
+
multipart,
|
|
82
|
+
});
|
|
83
|
+
const key = blob.pathname.replace(/^\//, "");
|
|
84
|
+
return {
|
|
85
|
+
kind: args.kind,
|
|
86
|
+
url: blob.url,
|
|
87
|
+
key,
|
|
88
|
+
sitePath: sitePathFromKey(key),
|
|
89
|
+
filename: args.filename,
|
|
90
|
+
sizeBytes: args.bytes.length,
|
|
91
|
+
contentType: args.contentType || contentTypeForExt(args.ext),
|
|
92
|
+
transport: "client",
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
catch (err) {
|
|
96
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
97
|
+
throw new CliHttpError(`Upload failed: ${msg}`, EXIT_UNEXPECTED, 500);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
async function uploadViaProxy(args) {
|
|
101
|
+
const form = new FormData();
|
|
102
|
+
form.append("file", new Blob([Uint8Array.from(args.bytes)]), args.filename);
|
|
103
|
+
const data = await v1PostMultipart(`/api/v1/sites/${encodeURIComponent(args.slug)}/media`, form);
|
|
104
|
+
const key = data.key?.replace(/^\//, "");
|
|
105
|
+
return {
|
|
106
|
+
kind: data.kind,
|
|
107
|
+
url: data.url,
|
|
108
|
+
key,
|
|
109
|
+
sitePath: data.sitePath ?? (key ? sitePathFromKey(key) : undefined),
|
|
110
|
+
filename: data.filename ?? args.filename,
|
|
111
|
+
sizeBytes: data.sizeBytes ?? args.bytes.length,
|
|
112
|
+
contentType: data.contentType,
|
|
113
|
+
content: data.content,
|
|
114
|
+
transport: "proxy",
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
/** Upload a local file using the Phase E transport matrix. */
|
|
118
|
+
export async function uploadLocalMedia(args) {
|
|
119
|
+
const bytes = await readFile(args.filePath);
|
|
120
|
+
const filename = basename(args.filePath);
|
|
121
|
+
const decision = selectMediaTransport({
|
|
122
|
+
filename,
|
|
123
|
+
sizeBytes: bytes.length,
|
|
124
|
+
headBytes: bytes.subarray(0, 4096),
|
|
125
|
+
});
|
|
126
|
+
if (decision.transport === "reject") {
|
|
127
|
+
throw new CliHttpError(decision.message, EXIT_USAGE, 400, "bad_request");
|
|
128
|
+
}
|
|
129
|
+
if (decision.transport === "client") {
|
|
130
|
+
return uploadViaClient({
|
|
131
|
+
slug: args.slug,
|
|
132
|
+
bytes,
|
|
133
|
+
filename,
|
|
134
|
+
ext: decision.ext,
|
|
135
|
+
contentType: decision.contentType,
|
|
136
|
+
kind: decision.kind,
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
return uploadViaProxy({ slug: args.slug, bytes, filename });
|
|
140
|
+
}
|
package/dist/registry.js
CHANGED
|
@@ -88,10 +88,17 @@ export const COMMANDS = [
|
|
|
88
88
|
{
|
|
89
89
|
name: "push",
|
|
90
90
|
summary: "Upload local allowlisted files (CAS + active-run guard)",
|
|
91
|
-
usage: "frontpage push [--site <slug>] [--message …] [--json]",
|
|
91
|
+
usage: "frontpage push [--site <slug>] [--message …] [--wait] [--json]",
|
|
92
92
|
topics: ["sync"],
|
|
93
|
-
examples: [
|
|
94
|
-
|
|
93
|
+
examples: [
|
|
94
|
+
'frontpage push --message "Update hero copy"',
|
|
95
|
+
'frontpage push --message "…" --wait',
|
|
96
|
+
],
|
|
97
|
+
flags: [
|
|
98
|
+
"--site <slug>",
|
|
99
|
+
"--message <text>",
|
|
100
|
+
"--wait: after push, wait until no agent run is queued/running/deploying (same as deploy wait; not a Vercel oracle)",
|
|
101
|
+
],
|
|
95
102
|
dangers: [
|
|
96
103
|
"Requires prior pull (baseCommitSha)",
|
|
97
104
|
"Refused while an agent run is active (exit 3)",
|
|
@@ -197,7 +204,7 @@ export const COMMANDS = [
|
|
|
197
204
|
"--path must start with /",
|
|
198
205
|
"--attach: local file (uploads via media), /__media/… site path, or https Blob URL; repeatable",
|
|
199
206
|
"--asset-url: https image URL (legacy); repeatable",
|
|
200
|
-
"Local attach uses
|
|
207
|
+
"Local attach uses frontpage media upload (images/PDF ≤25 MB, video ≤50 MB, SVG/text ≤4 MB proxy)",
|
|
201
208
|
"stdout is bare runId (or JSON with --json)",
|
|
202
209
|
],
|
|
203
210
|
seeAlso: ["runs", "deploy", "media"],
|
|
@@ -215,7 +222,10 @@ export const COMMANDS = [
|
|
|
215
222
|
"frontpage runs retry <runId>",
|
|
216
223
|
"frontpage runs get <runId>",
|
|
217
224
|
],
|
|
218
|
-
flags: [
|
|
225
|
+
flags: [
|
|
226
|
+
"There is no runs continue — mid-task continuation is automatic",
|
|
227
|
+
"runs wait: failed/canceled → exit 2; --json uses ok:false and includes run.error",
|
|
228
|
+
],
|
|
219
229
|
seeAlso: ["prompt", "deploy"],
|
|
220
230
|
},
|
|
221
231
|
{
|
|
@@ -248,6 +258,7 @@ export const COMMANDS = [
|
|
|
248
258
|
flags: [
|
|
249
259
|
"Optional build wait only — staging is https://<subdomain>.frontpage.host",
|
|
250
260
|
"Does NOT promote to production; use publish only when the user asks",
|
|
261
|
+
"Fail-closed: exit 2 when the waited run (or latest, if already idle) is failed/canceled",
|
|
251
262
|
],
|
|
252
263
|
},
|
|
253
264
|
{
|
|
@@ -305,9 +316,20 @@ export const COMMANDS = [
|
|
|
305
316
|
},
|
|
306
317
|
{
|
|
307
318
|
name: "media",
|
|
308
|
-
summary: "List or upload site media
|
|
309
|
-
usage: "frontpage media list|upload <file> [--site <slug>]",
|
|
319
|
+
summary: "List or upload site media (images/PDF ≤25 MB, video ≤50 MB)",
|
|
320
|
+
usage: "frontpage media list|upload <file> [--site <slug>] [--json]",
|
|
310
321
|
topics: ["content"],
|
|
322
|
+
examples: [
|
|
323
|
+
"frontpage media list",
|
|
324
|
+
"frontpage media upload ./hero.webp",
|
|
325
|
+
"frontpage media upload ./clip.mp4",
|
|
326
|
+
],
|
|
327
|
+
flags: [
|
|
328
|
+
"Auto-selects proxy (≤4 MB) vs direct-to-Blob for large rasters/PDFs and all video",
|
|
329
|
+
"Prints sitePath (/__media/uploads/<slug>/…) for markup — never raw blob hosts in pages",
|
|
330
|
+
"SVG stays on the sanitizing proxy path (≤4 MB)",
|
|
331
|
+
],
|
|
332
|
+
seeAlso: ["prompt", "help content", "help site-building"],
|
|
311
333
|
},
|
|
312
334
|
{
|
|
313
335
|
name: "inbox",
|
|
@@ -422,7 +444,7 @@ export const TOPICS = {
|
|
|
422
444
|
frontpage status # tipDrift when remote moved since last pull
|
|
423
445
|
frontpage pull # downloads src/, public/, content/ into cwd
|
|
424
446
|
frontpage diff # local vs remote via git blobSha (--json → dirty + tipDrift)
|
|
425
|
-
frontpage push [--message …] # uploads allowlisted files; CAS + active-run guard
|
|
447
|
+
frontpage push [--message …] [--wait] # uploads allowlisted files; CAS + active-run guard
|
|
426
448
|
frontpage ls [prefix]
|
|
427
449
|
frontpage cat <path>
|
|
428
450
|
frontpage search <pattern> [path] [--regex] [--case-sensitive] [--whole-word] [--files-only]
|
|
@@ -431,6 +453,7 @@ export const TOPICS = {
|
|
|
431
453
|
Local state: .frontpage/state.json { slug, baseCommitSha }
|
|
432
454
|
Pull BEFORE EDITING when tip may have moved (UI agent / another checkout) — check tipDrift.
|
|
433
455
|
Pull before push so CAS has baseCommitSha. Do not push while the editor agent is building.
|
|
456
|
+
--wait after push blocks until no agent run is queued/running/deploying (same as deploy wait).
|
|
434
457
|
The UI/canvas agent does not use this CLI; only CLI checkouts need pull.
|
|
435
458
|
Pushing module markup may auto-activate modules (same as the agent).
|
|
436
459
|
tokens.ts may be auto-repaired at commit if it would break the build.
|
|
@@ -473,7 +496,7 @@ export const TOPICS = {
|
|
|
473
496
|
Modules & articles (short):
|
|
474
497
|
- Forms: <form data-fp-form="slug"> with named inputs; no action/onsubmit/honeypot.
|
|
475
498
|
- Articles: frontpage articles …; migrate folders via frontpage prompt (don't invent mass delete+write).
|
|
476
|
-
- Media
|
|
499
|
+
- Media: frontpage media upload (images/PDF ≤25 MB, video ≤50 MB). Use sitePath /__media/uploads/<slug>/… in markup (not raw blob URLs). Optional ?w= on rasters only.
|
|
477
500
|
|
|
478
501
|
Full guide: https://frontpage.host/developers/site-building
|
|
479
502
|
See also: frontpage help sync | content | AGENTS.md`,
|
|
@@ -482,10 +505,10 @@ export const TOPICS = {
|
|
|
482
505
|
frontpage prompt "Use this logo" --attach ./logo.png
|
|
483
506
|
frontpage prompt "…" --attach /__media/uploads/<slug>/… --asset-url https://…
|
|
484
507
|
frontpage runs # latest + active
|
|
485
|
-
frontpage runs wait [runId]
|
|
508
|
+
frontpage runs wait [runId] # failed/canceled → exit 2; JSON ok:false + run.error
|
|
486
509
|
frontpage runs cancel <runId>
|
|
487
510
|
frontpage runs retry <runId>
|
|
488
|
-
frontpage deploy wait # optional
|
|
511
|
+
frontpage deploy wait # optional build wait; fail-closed on failed/canceled; NOT publish
|
|
489
512
|
frontpage publish # ONLY if the user asked — production promote
|
|
490
513
|
frontpage unpublish --yes # admin only; never unless asked; --yes when non-TTY
|
|
491
514
|
frontpage usage
|
|
@@ -496,12 +519,13 @@ export const TOPICS = {
|
|
|
496
519
|
frontpage modules request-setup <key> --reason "…"
|
|
497
520
|
frontpage extensions
|
|
498
521
|
|
|
499
|
-
--attach uploads
|
|
522
|
+
--attach uploads via media (images/PDF/video/text) or accepts /__media/… / https URLs.
|
|
523
|
+
API errors include requestId in --json error envelopes (and stderr when not --json).
|
|
500
524
|
Mid-task continuation is automatic — there is no runs continue.
|
|
501
|
-
Do not
|
|
525
|
+
Do not file-sync while an agent run is active (see help sync for push --wait).
|
|
502
526
|
Default after work: review https://<subdomain>.frontpage.host; do not publish.`,
|
|
503
527
|
content: `Content
|
|
504
|
-
frontpage media list|upload <file>
|
|
528
|
+
frontpage media list|upload <file> # images/PDF ≤25 MB, video ≤50 MB; sitePath for markup
|
|
505
529
|
frontpage inbox [leads|subscribers|orders|…] [--mark-read] [--csv]
|
|
506
530
|
frontpage seo get|set --path /
|
|
507
531
|
frontpage articles list|content|create-section|create-article|set-draft|…
|
|
@@ -547,8 +571,9 @@ export const TOPICS = {
|
|
|
547
571
|
|
|
548
572
|
Global --json envelope:
|
|
549
573
|
{ "ok": true, "command": "…", "data": {…} }
|
|
550
|
-
{ "ok": false, "command": "…", "error": { "message", "code?", "httpStatus?", "exitCode" } }
|
|
551
|
-
Failures with --json still use the process exit code; envelope is on stdout
|
|
574
|
+
{ "ok": false, "command": "…", "error": { "message", "code?", "httpStatus?", "exitCode", "requestId?" }, "data"? }
|
|
575
|
+
Failures with --json still use the process exit code; envelope is on stdout.
|
|
576
|
+
Prefer requestId from error envelopes when filing support issues.`,
|
|
552
577
|
};
|
|
553
578
|
export function findCommand(name) {
|
|
554
579
|
return COMMANDS.find((c) => c.name === name);
|
package/dist/runtime.d.ts
CHANGED
|
@@ -13,8 +13,18 @@ export type JsonErrorBody = {
|
|
|
13
13
|
code?: string;
|
|
14
14
|
httpStatus?: number;
|
|
15
15
|
exitCode: number;
|
|
16
|
+
requestId?: string;
|
|
16
17
|
};
|
|
17
18
|
export declare function emitOk(command: string, data: unknown): void;
|
|
19
|
+
/** Structured failure with optional data payload (e.g. failed run wait). */
|
|
20
|
+
export declare function emitFail(command: string, args: {
|
|
21
|
+
message: string;
|
|
22
|
+
exitCode: number;
|
|
23
|
+
code?: string;
|
|
24
|
+
requestId?: string;
|
|
25
|
+
httpStatus?: number;
|
|
26
|
+
data?: unknown;
|
|
27
|
+
}): number;
|
|
18
28
|
export declare function emitErr(command: string, err: unknown): number;
|
|
19
29
|
export declare function emitUsage(command: string, message: string, exitCode?: number): number;
|
|
20
30
|
/** Progress / spinner lines — suppressed when --quiet or --json. */
|
package/dist/runtime.js
CHANGED
|
@@ -31,23 +31,43 @@ export function requireYesOrTty(action) {
|
|
|
31
31
|
export function emitOk(command, data) {
|
|
32
32
|
console.log(JSON.stringify({ ok: true, command, data }));
|
|
33
33
|
}
|
|
34
|
+
/** Structured failure with optional data payload (e.g. failed run wait). */
|
|
35
|
+
export function emitFail(command, args) {
|
|
36
|
+
const body = {
|
|
37
|
+
message: args.message,
|
|
38
|
+
exitCode: args.exitCode,
|
|
39
|
+
};
|
|
40
|
+
if (args.code)
|
|
41
|
+
body.code = args.code;
|
|
42
|
+
if (args.httpStatus)
|
|
43
|
+
body.httpStatus = args.httpStatus;
|
|
44
|
+
if (args.requestId)
|
|
45
|
+
body.requestId = args.requestId;
|
|
46
|
+
if (jsonMode) {
|
|
47
|
+
const out = { ok: false, command, error: body };
|
|
48
|
+
if (args.data !== undefined)
|
|
49
|
+
out.data = args.data;
|
|
50
|
+
console.log(JSON.stringify(out));
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
const suffix = args.requestId ? ` (requestId: ${args.requestId})` : "";
|
|
54
|
+
console.error(`${args.message}${suffix}`);
|
|
55
|
+
}
|
|
56
|
+
return args.exitCode;
|
|
57
|
+
}
|
|
34
58
|
export function emitErr(command, err) {
|
|
35
59
|
const exitCode = exitCodeForError(err);
|
|
36
60
|
const message = err instanceof Error ? err.message : String(err);
|
|
37
|
-
const body = { message, exitCode };
|
|
38
61
|
if (err instanceof CliHttpError) {
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
62
|
+
return emitFail(command, {
|
|
63
|
+
message,
|
|
64
|
+
exitCode,
|
|
65
|
+
code: err.code,
|
|
66
|
+
httpStatus: err.status || undefined,
|
|
67
|
+
requestId: err.requestId,
|
|
68
|
+
});
|
|
43
69
|
}
|
|
44
|
-
|
|
45
|
-
console.log(JSON.stringify({ ok: false, command, error: body }));
|
|
46
|
-
}
|
|
47
|
-
else {
|
|
48
|
-
console.error(message);
|
|
49
|
-
}
|
|
50
|
-
return exitCode;
|
|
70
|
+
return emitFail(command, { message, exitCode });
|
|
51
71
|
}
|
|
52
72
|
export function emitUsage(command, message, exitCode = 2) {
|
|
53
73
|
if (jsonMode) {
|
package/llms.txt
CHANGED
|
@@ -10,12 +10,14 @@
|
|
|
10
10
|
- Search flags: --regex --case-sensitive --whole-word --files-only --context-lines --max-results
|
|
11
11
|
- Modules setup: frontpage modules request-setup <key> --reason "…" (owner status bar; CLI cannot show it)
|
|
12
12
|
- Analytics ops: frontpage analytics summary|query|funnel|timeseries|compare|sql (bare analytics = dashboard)
|
|
13
|
-
-
|
|
13
|
+
- Media: frontpage media upload <file> (images/PDF ≤25 MB, video ≤50 MB, SVG/text ≤4 MB); use sitePath /__media/uploads/<slug>/… in markup
|
|
14
|
+
- Prompt attachments: frontpage prompt "…" --attach <file|/__media/…|https://…> [--asset-url https://…] (same media caps as media upload)
|
|
15
|
+
- Errors: --json error envelopes include requestId; runs wait failed/canceled → ok:false + run.error (exit 2); deploy wait fail-closed; push --wait
|
|
14
16
|
- Auth: mint fp_live_ key in Frontpage UI (Developers); frontpage login KEY or FRONTPAGE_API_KEY
|
|
15
17
|
- Site id: subdomain only (frontpage use <subdomain>). Not custom domains.
|
|
16
18
|
- Staging: https://<subdomain>.frontpage.host — push/prompt/edit update staging; no separate staging deploy step for agents
|
|
17
19
|
- Production: custom domain after frontpage publish — NEVER publish/unpublish unless the user explicitly asks
|
|
18
|
-
- Sync: allowlist src/ public/ content/; platform overlay + secret-like paths rejected; pull before edit if tip may have moved (status/diff tipDrift); pull → edit → diff (blobSha) → push (CAS); no push during active agent run; UI agent does not use CLI pull; review on subdomain
|
|
20
|
+
- Sync: allowlist src/ public/ content/; platform overlay + secret-like paths rejected; pull before edit if tip may have moved (status/diff tipDrift); pull → edit → diff (blobSha) → push [--wait] (CAS); no push during active agent run; UI agent does not use CLI pull; review on subdomain
|
|
19
21
|
- Machine: global --json / --quiet; exit 0/2/3/4/5 (see help exit-codes)
|
|
20
|
-
- deploy wait = optional build wait only; it is NOT go-live / publish
|
|
22
|
+
- deploy wait = optional build wait only (fail-closed on failed/canceled); it is NOT go-live / publish
|
|
21
23
|
- No runs continue, domains, billing, members, MCP, or git remotes in v1
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "frontpage-host",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.9",
|
|
4
4
|
"description": "Frontpage CLI — manage your site from the terminal",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -34,6 +34,9 @@
|
|
|
34
34
|
"cli",
|
|
35
35
|
"landing-page"
|
|
36
36
|
],
|
|
37
|
+
"dependencies": {
|
|
38
|
+
"@vercel/blob": "^2.4.0"
|
|
39
|
+
},
|
|
37
40
|
"devDependencies": {
|
|
38
41
|
"@types/node": "^22.13.10",
|
|
39
42
|
"tsx": "^4.19.3",
|