frontpage-host 0.1.17 → 0.1.19
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 +15 -8
- package/dist/bin-path.d.ts +21 -0
- package/dist/bin-path.js +65 -0
- package/dist/bin.js +12 -0
- package/dist/commands/mail.d.ts +1 -0
- package/dist/commands/mail.js +482 -0
- package/dist/commands/people.d.ts +1 -0
- package/dist/commands/people.js +341 -0
- package/dist/commands/publish.js +14 -10
- package/dist/commands/push.d.ts +5 -0
- package/dist/commands/push.js +13 -2
- package/dist/commands/redirects.d.ts +1 -0
- package/dist/commands/redirects.js +83 -0
- package/dist/commands/shop-ids.d.ts +3 -0
- package/dist/commands/shop-ids.js +3 -0
- package/dist/commands/shop.d.ts +1 -0
- package/dist/commands/shop.js +595 -0
- package/dist/commands/wait-site-compile.d.ts +1 -0
- package/dist/commands/wait-site-compile.js +14 -10
- package/dist/compile.d.ts +5 -0
- package/dist/compile.js +30 -2
- package/dist/completions/generate.js +3 -0
- package/dist/modules/commands.js +4 -4
- package/dist/registry.js +108 -3
- package/llms.txt +4 -0
- package/package.json +1 -1
package/dist/compile.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*
|
|
4
4
|
* GET /api/v1/sites/{slug}/deploy → ready when the live compile SHA equals the tip.
|
|
5
5
|
*/
|
|
6
|
-
import { EXIT_OK, EXIT_USAGE, v1Get } from "./http/client.js";
|
|
6
|
+
import { CliHttpError, EXIT_OK, EXIT_USAGE, v1Get } from "./http/client.js";
|
|
7
7
|
import { progress } from "./runtime.js";
|
|
8
8
|
const SHA_RE = /^[0-9a-f]{40}$/i;
|
|
9
9
|
export function normalizeSha(raw) {
|
|
@@ -32,6 +32,21 @@ export function compileIsReady(status, expectCommit) {
|
|
|
32
32
|
return true;
|
|
33
33
|
return live === expect;
|
|
34
34
|
}
|
|
35
|
+
/** Compile clock is gone (flag off / old API). A site-not-found 404 is not this. */
|
|
36
|
+
export function isMissingDeployApi(err) {
|
|
37
|
+
if (!(err instanceof CliHttpError))
|
|
38
|
+
return false;
|
|
39
|
+
const message = err.message.toLowerCase();
|
|
40
|
+
if (message.includes("api not available"))
|
|
41
|
+
return true;
|
|
42
|
+
if (err.status === 404 && (message === "not found." || message === "not found"))
|
|
43
|
+
return true;
|
|
44
|
+
return false;
|
|
45
|
+
}
|
|
46
|
+
/** A deploy payload we can poll. Missing `ready` means the compile clock is not there. */
|
|
47
|
+
export function deployStatusLooksComplete(status) {
|
|
48
|
+
return Boolean(status && typeof status.ready === "boolean");
|
|
49
|
+
}
|
|
35
50
|
export async function fetchDeployStatus(slug) {
|
|
36
51
|
return v1Get(`/api/v1/sites/${encodeURIComponent(slug)}/deploy`);
|
|
37
52
|
}
|
|
@@ -42,7 +57,20 @@ export async function waitForCompileReady(args) {
|
|
|
42
57
|
const started = Date.now();
|
|
43
58
|
let last = null;
|
|
44
59
|
while (Date.now() - started < maxMs) {
|
|
45
|
-
|
|
60
|
+
try {
|
|
61
|
+
last = await fetchStatus(args.slug);
|
|
62
|
+
}
|
|
63
|
+
catch (err) {
|
|
64
|
+
if (isMissingDeployApi(err)) {
|
|
65
|
+
progress("\n");
|
|
66
|
+
return { exitCode: EXIT_USAGE, timedOut: false, failed: true, apiMissing: true, status: null };
|
|
67
|
+
}
|
|
68
|
+
throw err;
|
|
69
|
+
}
|
|
70
|
+
if (!deployStatusLooksComplete(last)) {
|
|
71
|
+
progress("\n");
|
|
72
|
+
return { exitCode: EXIT_USAGE, timedOut: false, failed: true, apiMissing: true, status: last };
|
|
73
|
+
}
|
|
46
74
|
if (last.compileState === "failed" || last.compileState === "canceled") {
|
|
47
75
|
progress("\n");
|
|
48
76
|
return { exitCode: EXIT_USAGE, timedOut: false, failed: true, status: last };
|
|
@@ -25,6 +25,7 @@ _frontpage_completions() {
|
|
|
25
25
|
seo|settings) COMPREPLY=( $(compgen -W "get set" -- "\${cur}") ) ;;
|
|
26
26
|
articles) COMPREPLY=( $(compgen -W "list content create-section create-article set-draft" -- "\${cur}") ) ;;
|
|
27
27
|
analytics) COMPREPLY=( $(compgen -W "dashboard summary query funnel timeseries compare sql" -- "\${cur}") ) ;;
|
|
28
|
+
people) COMPREPLY=( $(compgen -W "list get add set note rm-note follow-up hide unhide" -- "\${cur}") ) ;;
|
|
28
29
|
modules)
|
|
29
30
|
if [[ \${COMP_CWORD} -ge 3 && \${COMP_WORDS[2]} == google_reviews ]]; then
|
|
30
31
|
COMPREPLY=( $(compgen -W "docs request-setup enable disable archive config connect resolve status list-reviews hide show set-stars set-sort set-weight reset-weights write-review-url refresh disconnect" -- "\${cur}") )
|
|
@@ -69,6 +70,7 @@ _frontpage() {
|
|
|
69
70
|
tokens) _values 'subcommand' set ;;
|
|
70
71
|
seo|settings) _values 'subcommand' get set ;;
|
|
71
72
|
analytics) _values 'subcommand' dashboard summary query funnel timeseries compare sql ;;
|
|
73
|
+
people) _values 'subcommand' list get add set note rm-note follow-up hide unhide ;;
|
|
72
74
|
modules)
|
|
73
75
|
if [[ $words[2] == google_reviews ]]; then
|
|
74
76
|
_values 'subcommand' docs request-setup enable disable archive config connect resolve status list-reviews hide show set-stars set-sort set-weight reset-weights write-review-url refresh disconnect
|
|
@@ -106,6 +108,7 @@ export function generateFishCompletion() {
|
|
|
106
108
|
`complete -c frontpage -n "__fish_seen_subcommand_from tokens" -a "set"`,
|
|
107
109
|
`complete -c frontpage -n "__fish_seen_subcommand_from seo settings" -a "get set"`,
|
|
108
110
|
`complete -c frontpage -n "__fish_seen_subcommand_from analytics" -a "dashboard summary query funnel timeseries compare sql"`,
|
|
111
|
+
`complete -c frontpage -n "__fish_seen_subcommand_from people" -a "list get add set note rm-note follow-up hide unhide"`,
|
|
109
112
|
`complete -c frontpage -n "__fish_seen_subcommand_from modules" -a "list docs request-setup enable disable archive config callbar forms booking signups payments shop ordering articles google_reviews"`,
|
|
110
113
|
`complete -c frontpage -n "__fish_seen_subcommand_from modules; and __fish_seen_subcommand_from google_reviews" -a "connect resolve status list-reviews hide show set-stars set-sort set-weight reset-weights write-review-url refresh disconnect"`,
|
|
111
114
|
`complete -c frontpage -n "__fish_seen_subcommand_from modules; and __fish_seen_subcommand_from forms" -a "get set destinations connect-destination remove-destination disconnect-destination attach-destination detach-destination request-destination-setup"`,
|
package/dist/modules/commands.js
CHANGED
|
@@ -132,8 +132,8 @@ export const MODULE_COMMANDS = [
|
|
|
132
132
|
},
|
|
133
133
|
{
|
|
134
134
|
key: "payments",
|
|
135
|
-
name: "
|
|
136
|
-
summary: "Stripe
|
|
135
|
+
name: "Pay buttons",
|
|
136
|
+
summary: "One-click Stripe pay buttons. No cart. Connect finishes in the browser, not the terminal.",
|
|
137
137
|
genericActions: GENERIC_ACTIONS,
|
|
138
138
|
extraActions: [
|
|
139
139
|
"status",
|
|
@@ -151,14 +151,14 @@ export const MODULE_COMMANDS = [
|
|
|
151
151
|
],
|
|
152
152
|
notes: [
|
|
153
153
|
"Connect needs an admin API key. It opens Frontpage (you must be logged in there), then Stripe. Already-connected sites stay live — disconnect first to switch accounts.",
|
|
154
|
-
"
|
|
154
|
+
"Pay buttons and the Online store share one Stripe account. Disconnecting Pay buttons fails if the store still uses that account.",
|
|
155
155
|
"request-setup still lights the editor amber bar when you want the owner to finish there.",
|
|
156
156
|
],
|
|
157
157
|
},
|
|
158
158
|
{
|
|
159
159
|
key: "shop",
|
|
160
160
|
name: "Online store",
|
|
161
|
-
summary: "Stripe
|
|
161
|
+
summary: "Catalog, cart, and Stripe checkout. Shares the Pay buttons Stripe account.",
|
|
162
162
|
genericActions: GENERIC_ACTIONS,
|
|
163
163
|
extraActions: [
|
|
164
164
|
"status",
|
package/dist/registry.js
CHANGED
|
@@ -413,6 +413,97 @@ export const COMMANDS = [
|
|
|
413
413
|
topics: ["content"],
|
|
414
414
|
dangers: ["--mark-read is side-effecting with no confirm"],
|
|
415
415
|
},
|
|
416
|
+
{
|
|
417
|
+
name: "people",
|
|
418
|
+
summary: "List and manage site People (not inbox, not a module)",
|
|
419
|
+
usage: "frontpage people list|get|add|set|note|rm-note|follow-up|hide|unhide|tag|export [--site <slug>] [--json]",
|
|
420
|
+
topics: ["content"],
|
|
421
|
+
examples: [
|
|
422
|
+
"frontpage people list",
|
|
423
|
+
"frontpage people add --email alex@example.com --name Alex",
|
|
424
|
+
"frontpage people set <id> --status working",
|
|
425
|
+
"frontpage people note <id> --body \"Called them\"",
|
|
426
|
+
"frontpage people follow-up <id> --at 2026-09-12T00:00:00Z",
|
|
427
|
+
"frontpage people hide <id>",
|
|
428
|
+
"frontpage people tag <id> --add vip",
|
|
429
|
+
"frontpage people list --tag vip",
|
|
430
|
+
"frontpage people export",
|
|
431
|
+
],
|
|
432
|
+
flags: [
|
|
433
|
+
"list: --q --status --source --form-slug --follow-up due|upcoming|none --hidden --sort --last-seen-days --tag --limit --cursor",
|
|
434
|
+
"add requires --email and/or --phone (never name alone)",
|
|
435
|
+
"tag: --add <label> | --remove <slug>",
|
|
436
|
+
"export writes UTF-8 CSV (same filters as list). Optional --out <file>",
|
|
437
|
+
"Hide is not forget. Unique email/phone stay; later ingest un-hides",
|
|
438
|
+
"Unknown leftover flags fail closed (exit 2)",
|
|
439
|
+
],
|
|
440
|
+
seeAlso: ["inbox", "https://frontpage.host/developers/people"],
|
|
441
|
+
},
|
|
442
|
+
{
|
|
443
|
+
name: "shop",
|
|
444
|
+
summary: "Store catalog: items, variants, stock, and store settings (not Square, not inbox)",
|
|
445
|
+
usage: "frontpage shop items|variants|settings|orders|payments … [--site <slug>] [--json]",
|
|
446
|
+
topics: ["content"],
|
|
447
|
+
examples: [
|
|
448
|
+
"frontpage shop items list",
|
|
449
|
+
"frontpage shop items create camp-hat --title \"Camp hat\" --price-cents 4999 --checkout cart --requires-shipping true --stock 20",
|
|
450
|
+
"frontpage shop variants add camp-hat --id m --option Size=M --price-cents 4999 --stock 8",
|
|
451
|
+
"frontpage shop items stock camp-hat --variant m --add 5",
|
|
452
|
+
"frontpage shop items stock camp-hat --variant m --remove 5",
|
|
453
|
+
"frontpage shop items stock camp-hat --variant m --set 20",
|
|
454
|
+
"frontpage shop settings set-fulfillment --mode pickup",
|
|
455
|
+
"frontpage shop settings set-currency --currency usd",
|
|
456
|
+
],
|
|
457
|
+
flags: [
|
|
458
|
+
"Integer cents only. $49.99 is 4999. Do not send 49.99 or a dollar string.",
|
|
459
|
+
"--add / --remove become signed delta. 5 adds 5. --remove 5 removes 5. Result copy is added 5 / removed 5 / set to 20 / stockNow.",
|
|
460
|
+
"Pass either --add, --remove, or --set. Never two together. --set unlimited returns counted stock to unlimited.",
|
|
461
|
+
"items: list|get|create|update|archive|activate [--off] | images --urls … | stock [--variant m] --add|--remove|--set",
|
|
462
|
+
"variants: add|update|archive <itemId> --id m --price-cents … [--option Size=M] [--stock]",
|
|
463
|
+
"settings: get|set-fulfillment|set-currency|set-checkout-fee. Connect stays frontpage modules shop|payments connect.",
|
|
464
|
+
"orders / payments list|get read the same ledgers as frontpage inbox orders|payments",
|
|
465
|
+
"Unknown leftover flags fail closed (exit 2)",
|
|
466
|
+
],
|
|
467
|
+
seeAlso: ["inbox", "https://frontpage.host/developers/shop"],
|
|
468
|
+
},
|
|
469
|
+
{
|
|
470
|
+
name: "mail",
|
|
471
|
+
summary: "Site mailings: drafts, templates, series, and sends (not People, not inbox)",
|
|
472
|
+
usage: "frontpage mail settings|email|template|series|send|sends|enrolments|suppress … [--site <slug>] [--json]",
|
|
473
|
+
topics: ["content"],
|
|
474
|
+
examples: [
|
|
475
|
+
"frontpage mail settings set --postal \"100 Main St\" --reply-to you@example.com",
|
|
476
|
+
"frontpage mail email create --file draft.json --name Hours",
|
|
477
|
+
"frontpage mail send --file email.json --to ada@example.com --wait",
|
|
478
|
+
"frontpage mail send template <id> --to ada@example.com --var first_name=Ada",
|
|
479
|
+
"frontpage mail series steps set <id> --file steps.json",
|
|
480
|
+
"frontpage mail suppress add --email bounce@example.com",
|
|
481
|
+
],
|
|
482
|
+
flags: [
|
|
483
|
+
"email list is unsent drafts only. Sent one-offs are mail sends list",
|
|
484
|
+
"send --file is an inline one-off (no saved document)",
|
|
485
|
+
"Blocks and series steps are JSON (--file). Unknown leftover flags fail closed (exit 2)",
|
|
486
|
+
],
|
|
487
|
+
seeAlso: ["people", "inbox"],
|
|
488
|
+
},
|
|
489
|
+
{
|
|
490
|
+
name: "redirects",
|
|
491
|
+
summary: "List, set, or remove HTTP 301/308 path redirects",
|
|
492
|
+
usage: "frontpage redirects list | set --from /old --to /new [--status 301|308] | rm --from /old [--site <slug>] [--json]",
|
|
493
|
+
topics: ["content", "site-building"],
|
|
494
|
+
examples: [
|
|
495
|
+
"frontpage redirects list",
|
|
496
|
+
"frontpage redirects set --from /agents --to /agent",
|
|
497
|
+
"frontpage redirects set --from /old --to /new --status 308",
|
|
498
|
+
"frontpage redirects rm --from /old",
|
|
499
|
+
],
|
|
500
|
+
flags: [
|
|
501
|
+
"Instant — no push or compile. Not a site file. frontpage revert does not undo a redirect.",
|
|
502
|
+
"Same-origin pathnames only. Status 301 (default) or 308. Cap 50 per site.",
|
|
503
|
+
"Unknown leftover flags fail closed (exit 2)",
|
|
504
|
+
],
|
|
505
|
+
seeAlso: ["seo", "help site-building"],
|
|
506
|
+
},
|
|
416
507
|
{
|
|
417
508
|
name: "seo",
|
|
418
509
|
summary: "Get or set page SEO",
|
|
@@ -502,7 +593,7 @@ export const TOPICS = {
|
|
|
502
593
|
4. mkdir work && cd work && frontpage use <subdomain>
|
|
503
594
|
5. frontpage pull
|
|
504
595
|
6. Edit files under src/, public/, or content/
|
|
505
|
-
7. frontpage push --message "…"
|
|
596
|
+
7. frontpage push --message "…" --wait
|
|
506
597
|
8. frontpage deploy wait # tip compile ready (optional; push --wait does this)
|
|
507
598
|
Review staging: https://<subdomain>.frontpage.host when that subdomain is publicly shareable.
|
|
508
599
|
With a custom domain connected, the subdomain is often owner-private (login wall ≠ failed push);
|
|
@@ -528,7 +619,7 @@ export const TOPICS = {
|
|
|
528
619
|
frontpage status # tipDrift when remote moved since last pull
|
|
529
620
|
frontpage pull # downloads src/, public/, content/ into cwd
|
|
530
621
|
frontpage diff # local vs remote via git blobSha (--json → dirty + tipDrift)
|
|
531
|
-
frontpage push [--message …] [--wait] # uploads allowlisted files; CAS + active-run guard
|
|
622
|
+
frontpage push [--message …] [--wait] # uploads allowlisted files; deletes remote-only allowlisted paths; CAS + active-run guard
|
|
532
623
|
frontpage ls [prefix]
|
|
533
624
|
frontpage cat <path>
|
|
534
625
|
frontpage search <pattern> [path|--path <path>] [--regex] [--case-sensitive] [--whole-word] [--files-only]
|
|
@@ -566,6 +657,10 @@ export const TOPICS = {
|
|
|
566
657
|
Hard fences:
|
|
567
658
|
- No API routes, serverless backends, or databases.
|
|
568
659
|
- No fake lead forms / checkout / card fields — use data-fp-* modules + frontpage modules, or refuse.
|
|
660
|
+
- Quoted attributes: in frontmatter JS, a backslash-quote is an escape. In an Astro attribute it is
|
|
661
|
+
not. The quote after href= closes the string and the next token fails the compile. Put HTML in a
|
|
662
|
+
frontmatter const and pass it as an expression (auditBody={auditBody}), or use an expression
|
|
663
|
+
attribute. Never put an HTML tag or a backslash-quote inside a quoted JSX attribute.
|
|
569
664
|
- Platform-owned paths are not syncable (BaseLayout overlay, module/extension shells, package.json…).
|
|
570
665
|
- Customer layouts (DocsLayout, GuideLayout, …) are fine when site-owned. A wrapper MUST render
|
|
571
666
|
<BaseLayout> and forward SEO: description={description}, ogImage={ogImage}, and
|
|
@@ -584,6 +679,8 @@ export const TOPICS = {
|
|
|
584
679
|
- Prefer src/components/Header.astro + Footer.astro (or chrome: { managed: true } in site.ts).
|
|
585
680
|
- seo block in site.ts + frontpage seo get|set; customize 404.astro but keep frontpage:404 meta;
|
|
586
681
|
never put /404 in nav or pages. robots/sitemap are platform-managed.
|
|
682
|
+
- Real HTTP 301/308s: frontpage redirects list|set|rm. Instant (no push). Do not ship Astro.redirect,
|
|
683
|
+
location.replace, or a meta refresh for a permanent move. frontpage revert does not undo redirects.
|
|
587
684
|
|
|
588
685
|
Modules & articles (short):
|
|
589
686
|
- Forms: <form data-fp-form="slug"> with named inputs; no action/onsubmit/honeypot.
|
|
@@ -623,7 +720,14 @@ export const TOPICS = {
|
|
|
623
720
|
frontpage media list|upload <file> # images/PDF/video; text/CSV = inline not library; sitePath first when stored
|
|
624
721
|
frontpage images generate --prompt "…" [--count N] # 1–4 AI variations of one prompt; sitePath first; AI $ + storage
|
|
625
722
|
frontpage inbox [leads|subscribers|orders|google_reviews|…] [--mark-read] [--csv]
|
|
723
|
+
frontpage people list|get|add|set|note|rm-note|follow-up|hide|unhide|tag|export
|
|
724
|
+
# People CRM guide: https://frontpage.host/developers/people
|
|
725
|
+
frontpage shop items|variants|settings|orders|payments
|
|
726
|
+
# Store catalog: https://frontpage.host/developers/shop
|
|
727
|
+
# Integer cents only. $49.99 is 4999. stock --add/--remove are signed delta.
|
|
728
|
+
frontpage mail settings|email|template|series|send|sends|enrolments|suppress
|
|
626
729
|
frontpage seo get [/path|--path /path] | seo set --path /
|
|
730
|
+
frontpage redirects list|set|rm --from /old --to /new
|
|
627
731
|
frontpage articles list|content|create-section|create-article|set-draft|…
|
|
628
732
|
frontpage fonts [list|search] [--slot …] [--query …]
|
|
629
733
|
frontpage tokens set --group … --key … --value …
|
|
@@ -652,7 +756,8 @@ export const TOPICS = {
|
|
|
652
756
|
revert creates a NEW commit whose tree matches the target (linear restore).
|
|
653
757
|
Target SHA must be on this site's history (not another site in the monorepo).
|
|
654
758
|
Refused while an agent run is active. Goes through commitSiteBranch (build gate).
|
|
655
|
-
--yes required when stdin is not a TTY
|
|
759
|
+
--yes required when stdin is not a TTY.
|
|
760
|
+
revert does not undo HTTP redirects — use frontpage redirects rm.`,
|
|
656
761
|
isolation: `Isolation
|
|
657
762
|
Every site-scoped call targets subdomain → branch site/<slug> only.
|
|
658
763
|
No client-supplied branch, ref, repo, or clone URL is accepted.
|
package/llms.txt
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
# Frontpage CLI (frontpage-host)
|
|
2
2
|
|
|
3
3
|
- Package: frontpage-host (npm). Binary: frontpage. Do NOT install npm package "frontpage".
|
|
4
|
+
- Astro quoted attributes: in frontmatter JS a backslash-quote is an escape; in an attribute it is not. Pass HTML as {auditBody}. Never HTML or a backslash-quote inside a quoted JSX attribute.
|
|
4
5
|
- Docs in this package: README.md, AGENTS.md (agent operating manual).
|
|
5
6
|
- Introspect: frontpage help | frontpage help --json | frontpage help <topic|command>
|
|
6
7
|
- Topics: quickstart, auth, sync, site-building, agent, content, history, isolation, exit-codes
|
|
@@ -14,6 +15,9 @@
|
|
|
14
15
|
- Prompt attachments: frontpage prompt "…" --attach <file|/__media/…|https://…> [--asset-url https://…] (same media caps as media upload)
|
|
15
16
|
- Version: frontpage --version | -V | version
|
|
16
17
|
- SEO get: frontpage seo get [/path|--path /path]; search path filter: [path|--path <path>]; open [/path|--path /path]
|
|
18
|
+
- Redirects: frontpage redirects list|set|rm — HTTP 301/308, instant, not a file; revert does not undo; do not fake with Astro.redirect / meta refresh
|
|
19
|
+
- People CRM: frontpage people list|get|add|set|note|rm-note|follow-up|hide|unhide|tag|export. Site-scoped person graph (email or phone). Inbox stays the raw ledger. Hide is not forget. List export is CSV. Unknown leftover flags fail closed. Guide: https://frontpage.host/developers/people
|
|
20
|
+
- Store catalog: frontpage shop items|variants|settings|orders|payments. Integer cents only ($49.99 is 4999). stock --add/--remove are signed delta (added 5 / removed 5 / set to 20 / stockNow). Connect stays frontpage modules shop|payments connect. Not Square ordering. Guide: https://frontpage.host/developers/shop
|
|
17
21
|
- Analytics funnel: --steps JSON array or comma paths (/, /pricing); bad JSON → Invalid JSON for --steps
|
|
18
22
|
- Modules: unknown key errors list Known: …; mailing list module key is signups (not subscribe)
|
|
19
23
|
- Errors: --json API envelopes include requestId when the server returned one; local validation omits requestId/httpStatus; runs wait failed/canceled → ok:false + run.error (exit 2); deploy wait = agent idle + tip compile ready (fail-closed / compile timeout → exit 2); push --wait and publish --wait wait for GET /deploy ready
|