frontpage-host 0.1.14 → 0.1.16

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 CHANGED
@@ -109,7 +109,7 @@ Sites are Astro 6 + Tailwind v4. More detail: `frontpage help site-building` or
109
109
  ## Modules & articles
110
110
 
111
111
  - Forms: `data-fp-form` markup in pages + `frontpage modules` for enable/config. No submit JS / honeypot / `action`.
112
- - Wizard / connect-once modules (payments/shop/ordering/google_reviews): after building gated markup, `frontpage modules request-setup <key> --reason "…"` once — owner finishes in the **editor status bar** (CLI cannot show it). Auto-active modules (forms/callbar/…) need markup, not request-setup. Typed settings: `frontpage modules callbar|forms|booking|signups get|set` (forms set needs `--instance`; do not target `default`). `frontpage modules <key>` prints that key's CLI usage (exit 2). Index: https://frontpage.host/developers/modules
112
+ - Wizard / connect-once modules (payments/shop/ordering): `frontpage modules <key> connect` opens Frontpage (you must be logged in there), then Stripe or Square. Already-connected sites stay live — do not retry connect. payments/shop connect needs an **admin** key; ordering connect needs **editor**. `--no-open` for CI. `request-setup` remains valid when you want the **editor amber bar** instead. payments and shop share one Stripe account — payments disconnect fails if the store still uses it. Auto-active modules (forms/callbar/…) need markup, not request-setup. Typed settings: `frontpage modules callbar|forms|booking|signups get|set` (forms set needs `--instance`; do not target `default`). `frontpage modules <key>` prints that key's CLI usage (exit 2). Index: https://frontpage.host/developers/modules · payments/shop/ordering pages under /developers/modules/<key>
113
113
  - Google reviews: platform nodes only (`data-fp-google-reviews` / `data-fp-google-ask` + required `data-fp-requires="google_reviews"`). `data-layout` is `feed` (default), `badge`, or `link`. Never invent stars, quotes, a 1–10, or a Maps URL. Do not pick a Place ID via Autocomplete and do not write `placeId` through `modules config`. Owner-supplied Place ID / Maps URL: `frontpage modules google_reviews connect --place-id …` or `--maps-url …` (server resolves + seeds). Curation: `list-reviews`, `hide --id`, `show --id`, `set-stars`, `set-sort`, `set-weight`, `reset-weights`, `refresh`, `disconnect`. Usage: `frontpage modules google_reviews`. Docs: https://frontpage.host/developers/modules/google-reviews. Ask-widget scores: `frontpage inbox google_reviews`.
114
114
  - Articles: `frontpage articles …` for lifecycle; bodies via sync under `content/` or `articles content get|set`. Section landing is an owned `src/pages/<section>/index.astro`.
115
115
  - Migrate a folder into Articles: prefer `frontpage prompt "migrate … into articles"` — do not invent a mass delete+write migration.
@@ -5,6 +5,7 @@ import { emitUsage } from "../runtime.js";
5
5
  import { formatModuleUsage, formatModulesIndex, isCliModuleAction, isDocumentedModuleKey, isGenericModuleVerb, } from "../modules/commands.js";
6
6
  import { runGoogleReviews } from "../modules/google_reviews.js";
7
7
  import { isTypedConfigCliKey, runTypedConfig } from "../modules/typed_config.js";
8
+ import { isOauthCliKey, runOauthHandoff } from "../modules/oauth.js";
8
9
  /** Drop --site so we can print local usage without resolving a checkout. */
9
10
  function positionalArgs(args) {
10
11
  const rest = [];
@@ -46,6 +47,9 @@ export async function runModules(args) {
46
47
  if (isTypedConfigCliKey(peekedKey)) {
47
48
  return await runTypedConfig(peekedKey, slug, peekedAction, extraFlags);
48
49
  }
50
+ if (isOauthCliKey(peekedKey)) {
51
+ return await runOauthHandoff(peekedKey, slug, peekedAction, extraFlags);
52
+ }
49
53
  }
50
54
  if (!isGenericModuleVerb(peekedAction)) {
51
55
  return emitUsage("modules", `${formatModuleUsage(peekedKey)}\n\nUnknown action "${peekedAction}". Not in this CLI yet — use Modules or the editor.`);
@@ -29,6 +29,10 @@ _frontpage_completions() {
29
29
  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}") )
30
30
  elif [[ \${COMP_CWORD} -ge 3 && (\${COMP_WORDS[2]} == callbar || \${COMP_WORDS[2]} == forms || \${COMP_WORDS[2]} == booking || \${COMP_WORDS[2]} == signups) ]]; then
31
31
  COMPREPLY=( $(compgen -W "docs request-setup enable disable archive config get set" -- "\${cur}") )
32
+ elif [[ \${COMP_CWORD} -ge 3 && (\${COMP_WORDS[2]} == payments || \${COMP_WORDS[2]} == shop) ]]; then
33
+ COMPREPLY=( $(compgen -W "docs request-setup enable disable archive config status connect disconnect" -- "\${cur}") )
34
+ elif [[ \${COMP_CWORD} -ge 3 && \${COMP_WORDS[2]} == ordering ]]; then
35
+ COMPREPLY=( $(compgen -W "docs request-setup enable disable archive config status connect disconnect sync" -- "\${cur}") )
32
36
  else
33
37
  COMPREPLY=( $(compgen -W "list docs request-setup enable disable archive config callbar forms booking signups payments shop ordering articles google_reviews" -- "\${cur}") )
34
38
  fi
@@ -66,6 +70,10 @@ _frontpage() {
66
70
  _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
67
71
  elif [[ $words[2] == callbar || $words[2] == forms || $words[2] == booking || $words[2] == signups ]]; then
68
72
  _values 'subcommand' docs request-setup enable disable archive config get set
73
+ elif [[ $words[2] == payments || $words[2] == shop ]]; then
74
+ _values 'subcommand' docs request-setup enable disable archive config status connect disconnect
75
+ elif [[ $words[2] == ordering ]]; then
76
+ _values 'subcommand' docs request-setup enable disable archive config status connect disconnect sync
69
77
  else
70
78
  _values 'subcommand' list docs request-setup enable disable archive config callbar forms booking signups payments shop ordering articles google_reviews
71
79
  fi
@@ -94,6 +102,8 @@ export function generateFishCompletion() {
94
102
  `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"`,
95
103
  `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"`,
96
104
  `complete -c frontpage -n "__fish_seen_subcommand_from modules; and __fish_seen_subcommand_from callbar forms booking signups" -a "get set"`,
105
+ `complete -c frontpage -n "__fish_seen_subcommand_from modules; and __fish_seen_subcommand_from payments shop" -a "status connect disconnect"`,
106
+ `complete -c frontpage -n "__fish_seen_subcommand_from modules; and __fish_seen_subcommand_from ordering" -a "status connect disconnect sync"`,
97
107
  `complete -c frontpage -n "__fish_seen_subcommand_from extensions" -a "list docs enable disable config"`,
98
108
  `complete -c frontpage -l site -d "Site subdomain slug"`,
99
109
  ];
@@ -18,6 +18,8 @@ export type ModuleCommandDef = {
18
18
  export declare const MODULE_COMMANDS: readonly ModuleCommandDef[];
19
19
  export declare const GOOGLE_REVIEWS_CLI_ACTIONS: readonly ["connect", "resolve", "status", "list-reviews", "hide", "show", "set-stars", "set-sort", "set-weight", "reset-weights", "write-review-url", "refresh", "disconnect"];
20
20
  export declare const TYPED_CONFIG_CLI_ACTIONS: readonly ["get", "set"];
21
+ export declare const STRIPE_OAUTH_CLI_ACTIONS: readonly ["status", "connect", "disconnect"];
22
+ export declare const ORDERING_OAUTH_CLI_ACTIONS: readonly ["status", "connect", "disconnect", "sync"];
21
23
  export declare function isCliModuleAction(key: DocumentedModuleKey, action: string): boolean;
22
24
  export declare function isDocumentedModuleKey(raw: string): raw is DocumentedModuleKey;
23
25
  export declare function isGenericModuleVerb(raw: string): boolean;
@@ -124,16 +124,24 @@ export const MODULE_COMMANDS = [
124
124
  name: "Payments",
125
125
  summary: "Stripe payments. Connect finishes in the browser, not the terminal.",
126
126
  genericActions: GENERIC_ACTIONS,
127
- extraActions: [],
128
- notYet: ["connect", "disconnect", "status"],
127
+ extraActions: [
128
+ "status",
129
+ "connect [--no-open]",
130
+ "disconnect [--yes]",
131
+ ],
132
+ notYet: [],
129
133
  examples: [
130
134
  "frontpage modules payments",
135
+ "frontpage modules payments status",
136
+ "frontpage modules payments connect --no-open",
137
+ "frontpage modules payments disconnect --yes",
131
138
  "frontpage modules payments docs",
132
139
  'frontpage modules payments request-setup --reason "Deposit button needs Stripe"',
133
140
  ],
134
141
  notes: [
135
- "OAuth cannot finish in this CLI. Use request-setup (editor amber bar) or the Modules hub.",
136
- "payments and shop share one Stripe account.",
142
+ "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.",
143
+ "payments and shop share one Stripe account. Disconnecting payments fails if the store still uses that account.",
144
+ "request-setup still lights the editor amber bar when you want the owner to finish there.",
137
145
  ],
138
146
  },
139
147
  {
@@ -141,16 +149,25 @@ export const MODULE_COMMANDS = [
141
149
  name: "Online store",
142
150
  summary: "Stripe shop. Shares the payments Stripe account.",
143
151
  genericActions: GENERIC_ACTIONS,
144
- extraActions: [],
145
- notYet: ["connect", "disconnect", "status"],
152
+ extraActions: [
153
+ "status",
154
+ "connect [--no-open]",
155
+ "disconnect [--yes]",
156
+ ],
157
+ notYet: [],
146
158
  examples: [
147
159
  "frontpage modules shop",
160
+ "frontpage modules shop status",
161
+ "frontpage modules shop connect --no-open",
162
+ "frontpage modules shop disconnect --yes",
148
163
  "frontpage modules shop docs",
149
164
  'frontpage modules shop request-setup --reason "You asked for a store — Stripe setup makes checkout live"',
150
165
  ],
151
166
  notes: [
152
- "OAuth cannot finish in this CLI. Use request-setup (editor amber bar) or the Modules hub.",
153
- "payments and shop share one Stripe account.",
167
+ "Connect needs an admin API key. It opens Frontpage (you must be logged in there), then Stripe. Already-connected sites stay live.",
168
+ "payments and shop share one Stripe account. Shop disconnect keeps the account on payments.",
169
+ "Shop still needs the shipping step in Modules if you have not set it.",
170
+ "request-setup still lights the editor amber bar when you want the owner to finish there.",
154
171
  ],
155
172
  },
156
173
  {
@@ -158,15 +175,27 @@ export const MODULE_COMMANDS = [
158
175
  name: "Online ordering",
159
176
  summary: "Square ordering. Connect finishes in the browser, not the terminal.",
160
177
  genericActions: GENERIC_ACTIONS,
161
- extraActions: [],
162
- notYet: ["connect", "disconnect", "sync", "status"],
178
+ extraActions: [
179
+ "status",
180
+ "connect [--no-open]",
181
+ "disconnect [--yes]",
182
+ "sync",
183
+ ],
184
+ notYet: ["fulfillment get|set"],
163
185
  examples: [
164
186
  "frontpage modules ordering",
187
+ "frontpage modules ordering status",
188
+ "frontpage modules ordering connect --no-open",
189
+ "frontpage modules ordering sync",
190
+ "frontpage modules ordering disconnect --yes",
165
191
  "frontpage modules ordering docs",
166
192
  'frontpage modules ordering request-setup --reason "You asked for online ordering — Square setup makes it live"',
167
193
  ],
168
194
  notes: [
169
- "OAuth cannot finish in this CLI. Use request-setup (editor amber bar) or the Modules hub.",
195
+ "Connect needs an editor API key. It opens Frontpage (you must be logged in there), then Square. Already-connected sites stay live.",
196
+ "sync refreshes the Square catalog (same as the hub Sync button).",
197
+ "request-setup still lights the editor amber bar when you want the owner to finish there.",
198
+ "Fulfillment (pickup/delivery) is not in this CLI yet — use Modules or the editor.",
170
199
  ],
171
200
  },
172
201
  {
@@ -240,6 +269,8 @@ export const GOOGLE_REVIEWS_CLI_ACTIONS = [
240
269
  "disconnect",
241
270
  ];
242
271
  export const TYPED_CONFIG_CLI_ACTIONS = ["get", "set"];
272
+ export const STRIPE_OAUTH_CLI_ACTIONS = ["status", "connect", "disconnect"];
273
+ export const ORDERING_OAUTH_CLI_ACTIONS = ["status", "connect", "disconnect", "sync"];
243
274
  export function isCliModuleAction(key, action) {
244
275
  if (key === "google_reviews") {
245
276
  return GOOGLE_REVIEWS_CLI_ACTIONS.includes(action);
@@ -247,6 +278,12 @@ export function isCliModuleAction(key, action) {
247
278
  if (key === "callbar" || key === "forms" || key === "booking" || key === "signups") {
248
279
  return TYPED_CONFIG_CLI_ACTIONS.includes(action);
249
280
  }
281
+ if (key === "payments" || key === "shop") {
282
+ return STRIPE_OAUTH_CLI_ACTIONS.includes(action);
283
+ }
284
+ if (key === "ordering") {
285
+ return ORDERING_OAUTH_CLI_ACTIONS.includes(action);
286
+ }
250
287
  return false;
251
288
  }
252
289
  export function isDocumentedModuleKey(raw) {
@@ -0,0 +1,12 @@
1
+ export declare const OAUTH_CLI_KEYS: readonly ["payments", "shop", "ordering"];
2
+ export type OauthCliKey = (typeof OAUTH_CLI_KEYS)[number];
3
+ export declare function isOauthCliKey(key: string): key is OauthCliKey;
4
+ export declare function resolveOpenUrl(raw: unknown): string | null;
5
+ /** argv for the platform opener. Windows quotes the URL so `&` stays in the query. */
6
+ export declare function browserOpenCommand(url: string, platform?: NodeJS.Platform): {
7
+ command: string;
8
+ args: string[];
9
+ windowsVerbatimArguments?: boolean;
10
+ };
11
+ export declare function openBrowser(url: string): void;
12
+ export declare function runOauthHandoff(key: OauthCliKey, slug: string, action: string, flags: string[]): Promise<number>;
@@ -0,0 +1,138 @@
1
+ /**
2
+ * §CLI-MOD-OAUTH / §CLI-MOD-HARD — payments / shop / ordering connect, status, disconnect, sync.
3
+ */
4
+ import { spawn } from "node:child_process";
5
+ import { assertNoUnknownFlags, hasFlag } from "../argv.js";
6
+ import { apiBase, EXIT_OK, v1Get, v1Post } from "../http/client.js";
7
+ import { emitOk, emitUsage, isJson, requireYesOrTty } from "../runtime.js";
8
+ import { formatModuleUsage } from "./commands.js";
9
+ export const OAUTH_CLI_KEYS = ["payments", "shop", "ordering"];
10
+ export function isOauthCliKey(key) {
11
+ return OAUTH_CLI_KEYS.includes(key);
12
+ }
13
+ const FINISH = "Open the Frontpage URL while logged in, finish Stripe or Square in the browser, then re-run status. This CLI cannot complete OAuth.";
14
+ function pathFor(slug, key) {
15
+ return `/api/v1/sites/${encodeURIComponent(slug)}/modules/${encodeURIComponent(key)}`;
16
+ }
17
+ export function resolveOpenUrl(raw) {
18
+ if (typeof raw !== "string" || !raw.trim())
19
+ return null;
20
+ const trimmed = raw.trim();
21
+ if (/^https?:\/\//i.test(trimmed))
22
+ return trimmed;
23
+ if (trimmed.startsWith("/"))
24
+ return `${apiBase()}${trimmed}`;
25
+ return null;
26
+ }
27
+ /** argv for the platform opener. Windows quotes the URL so `&` stays in the query. */
28
+ export function browserOpenCommand(url, platform = process.platform) {
29
+ if (platform === "darwin")
30
+ return { command: "open", args: [url] };
31
+ if (platform !== "win32")
32
+ return { command: "xdg-open", args: [url] };
33
+ return {
34
+ command: "cmd",
35
+ args: ["/c", "start", '""', `"${url}"`],
36
+ windowsVerbatimArguments: true,
37
+ };
38
+ }
39
+ export function openBrowser(url) {
40
+ const spec = browserOpenCommand(url);
41
+ spawn(spec.command, spec.args, {
42
+ detached: true,
43
+ stdio: "ignore",
44
+ ...(spec.windowsVerbatimArguments ? { windowsVerbatimArguments: true } : {}),
45
+ }).unref();
46
+ }
47
+ function printStatus(key, data) {
48
+ const connection = (data.connection ?? {});
49
+ const display = connection.display ?? {};
50
+ console.log(`connected ${connection.ready ? "yes" : "no"}`);
51
+ if (key === "ordering") {
52
+ console.log(`merchant ${display.merchantName ?? "—"}`);
53
+ if (display.locationCount != null)
54
+ console.log(`locations ${display.locationCount}`);
55
+ if (display.cardProcessing != null)
56
+ console.log(`cards ${display.cardProcessing ? "yes" : "no"}`);
57
+ if (display.menuSyncedAt)
58
+ console.log(`menu sync ${display.menuSyncedAt}`);
59
+ }
60
+ else {
61
+ console.log(`charges ${display.chargesEnabled == null ? "—" : display.chargesEnabled ? "yes" : "no"}`);
62
+ console.log(`account ${display.accountPresent ? "present" : "none"}`);
63
+ if (typeof data.sharedStripe === "string")
64
+ console.log(`note ${data.sharedStripe}`);
65
+ }
66
+ if (typeof data.connectUrl === "string")
67
+ console.log(`connect ${data.connectUrl}`);
68
+ }
69
+ export async function runOauthHandoff(key, slug, action, flags) {
70
+ const work = [...flags];
71
+ const usage = formatModuleUsage(key);
72
+ if (action === "status") {
73
+ assertNoUnknownFlags(work, "modules");
74
+ const data = await v1Get(pathFor(slug, key));
75
+ if (isJson()) {
76
+ emitOk("modules", data);
77
+ return EXIT_OK;
78
+ }
79
+ printStatus(key, data);
80
+ return EXIT_OK;
81
+ }
82
+ if (action === "connect") {
83
+ const noOpen = hasFlag(work, "--no-open");
84
+ assertNoUnknownFlags(work, "modules");
85
+ const data = await v1Post(pathFor(slug, key), { action: "connect" });
86
+ const already = data.alreadyConnected === true;
87
+ if (isJson()) {
88
+ emitOk("modules", data);
89
+ }
90
+ else {
91
+ const url = resolveOpenUrl(data.connectUrl);
92
+ if (url)
93
+ console.log(url);
94
+ console.log(typeof data.message === "string" ? data.message : already ? "Already connected." : FINISH);
95
+ if (typeof data.warning === "string")
96
+ console.log(data.warning);
97
+ }
98
+ const url = resolveOpenUrl(data.connectUrl);
99
+ if (url && !noOpen && !already)
100
+ openBrowser(url);
101
+ return EXIT_OK;
102
+ }
103
+ if (action === "disconnect") {
104
+ assertNoUnknownFlags(work, "modules");
105
+ const label = key === "ordering"
106
+ ? "disconnect Square"
107
+ : key === "payments"
108
+ ? "disconnect payments (shared Stripe account with the store)"
109
+ : "disconnect the store (shared Stripe account with payments)";
110
+ const refuse = requireYesOrTty(label);
111
+ if (refuse)
112
+ return emitUsage("modules", refuse);
113
+ const data = await v1Post(pathFor(slug, key), { action: "disconnect" });
114
+ if (isJson()) {
115
+ emitOk("modules", data);
116
+ return EXIT_OK;
117
+ }
118
+ console.log(typeof data.message === "string" ? data.message : "Disconnected.");
119
+ if (typeof data.warning === "string" && data.warning !== data.message) {
120
+ console.log(data.warning);
121
+ }
122
+ return EXIT_OK;
123
+ }
124
+ if (action === "sync") {
125
+ if (key !== "ordering") {
126
+ return emitUsage("modules", `sync is only available for ordering.\n\n${usage}`);
127
+ }
128
+ assertNoUnknownFlags(work, "modules");
129
+ const data = await v1Post(pathFor(slug, key), { action: "sync" });
130
+ if (isJson()) {
131
+ emitOk("modules", data);
132
+ return EXIT_OK;
133
+ }
134
+ console.log(`Synced — ${data.itemCount ?? 0} items, ${data.locationCount ?? 0} locations.`);
135
+ return EXIT_OK;
136
+ }
137
+ return emitUsage("modules", `${usage}\n\nUnknown action "${action}".`);
138
+ }
package/dist/registry.js CHANGED
@@ -328,6 +328,8 @@ export const COMMANDS = [
328
328
  "frontpage modules callbar set --phone +14085551234 --sms no",
329
329
  "frontpage modules forms get",
330
330
  "frontpage modules forms set --instance lead-gen --notify-email hi@example.com",
331
+ "frontpage modules ordering connect --no-open",
332
+ "frontpage modules payments status",
331
333
  "frontpage modules docs forms",
332
334
  "frontpage modules docs google_reviews",
333
335
  "frontpage modules docs signups",
@@ -340,11 +342,14 @@ export const COMMANDS = [
340
342
  "Key-first and verb-first both work: `modules google_reviews enable` = `modules enable google_reviews`",
341
343
  "google_reviews extras: connect / resolve / status / list-reviews / hide / show / set-stars / set-sort / set-weight / reset-weights / refresh / disconnect / write-review-url",
342
344
  "callbar/forms/booking/signups: typed get / set (same whitelist as `modules config`)",
345
+ "payments/shop/ordering: connect opens the browser; finish there, then status. --no-open for CI. request-setup still lights the editor amber bar.",
343
346
  "See https://frontpage.host/developers/modules and /developers/modules/google-reviews",
344
347
  ],
345
348
  dangers: [
346
349
  "Secret values are never returned — masks only",
347
350
  "request-setup surfaces an owner prompt in the editor status bar (CLI cannot show it)",
351
+ "payments and shop share one Stripe account — payments disconnect 409s if the store still uses it",
352
+ "OAuth cannot finish in the terminal; connect only opens the vendor URL",
348
353
  "Do not write placeId through generic config — that skips listing resolve + seed",
349
354
  ],
350
355
  seeAlso: ["articles", "inbox"],
@@ -590,7 +595,9 @@ export const TOPICS = {
590
595
  frontpage fonts [list|search] [--slot …] [--query …]
591
596
  frontpage tokens set --group … --key … --value …
592
597
  frontpage modules list|docs|request-setup|enable|disable|archive|config <key>
593
- frontpage modules <key> # that key's CLI usage (generic only in this phase)
598
+ frontpage modules <key> # that key's CLI usage
599
+ frontpage modules payments|shop|ordering connect [--no-open] # opens Frontpage then Stripe/Square; then status
600
+ frontpage modules ordering sync
594
601
  # mailing list key: signups. Index: https://frontpage.host/developers/modules
595
602
  frontpage extensions list|docs|enable|disable|config <key>
596
603
  frontpage settings get|set
@@ -600,7 +607,7 @@ export const TOPICS = {
600
607
  Do not fake payments/checkout. LOCKED extensions → do not fake; say plan required.
601
608
  Migrate pages → articles: prefer frontpage prompt "migrate …" over mass delete+write.
602
609
  edit uses click-edit (exact single occurrence), not push / gated-write.
603
- Module OAuth and secret values are not exposed via the CLI.
610
+ Connect opens Frontpage (logged-in), then Stripe/Square; never accepts or returns OAuth secrets. payments/shop connect is admin.
604
611
  Site contract: frontpage help site-building · https://frontpage.host/developers/site-building
605
612
  Domains, billing, members, and site delete are out of v1.`,
606
613
  history: `History
package/llms.txt CHANGED
@@ -8,7 +8,7 @@
8
8
  - Fonts: frontpage fonts [--slot] [--query] → exact value → tokens set fonts.<role> → APPLY font-sans|serif|mono|display. Build bundles catalog faces from tokens.ts and/or CSS font-family contexts (not prose). Inline-only without tokens works for catalog faces after rebuild; prefer tokens+utilities for brand roles.
9
9
  - Module/extension docs: frontpage modules docs <key> | frontpage extensions docs <key>
10
10
  - Search flags: --regex --case-sensitive --whole-word --files-only --context-lines --max-results
11
- - Modules setup: frontpage modules request-setup <key> --reason "…" (owner status bar; CLI cannot show it). frontpage modules <key> prints that key's CLI usage. Index: https://frontpage.host/developers/modules. Typed config: frontpage modules callbar|forms|booking|signups get|set (forms set needs --instance; confirm emails paid-plan only). google_reviews: frontpage modules google_reviews connect --place-id | --maps-url (server resolve + seed; no Autocomplete; do not write placeId via config). Also status, list-reviews, hide/show, set-stars, set-sort, set-weight, reset-weights, refresh, disconnect. Docs: https://frontpage.host/developers/modules/google-reviews. Markup: data-fp-google-reviews / data-fp-google-ask + required data-fp-requires="google_reviews". Ask scores: frontpage inbox google_reviews.
11
+ - Modules setup: wizard modules (payments/shop/ordering): frontpage modules <key> connect [--no-open] opens Frontpage (logged-in browser) then Stripe/Square; already-connected stays live. payments/shop connect = admin key; ordering = editor. payments disconnect 409s if shop still uses the shared Stripe account. request-setup remains valid for the editor amber bar. frontpage modules <key> prints that key's CLI usage. Index: https://frontpage.host/developers/modules. Typed config: frontpage modules callbar|forms|booking|signups get|set (forms set needs --instance; confirm emails paid-plan only). google_reviews: frontpage modules google_reviews connect --place-id | --maps-url (server resolve + seed; no Autocomplete; do not write placeId via config). Also status, list-reviews, hide/show, set-stars, set-sort, set-weight, reset-weights, refresh, disconnect. Docs: https://frontpage.host/developers/modules/google-reviews. Markup: data-fp-google-reviews / data-fp-google-ask + required data-fp-requires="google_reviews". Ask scores: frontpage inbox google_reviews.
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); human prints sitePath first — use /__media/uploads/<slug>/… in markup. Text/CSV is inline only (not media library; --json omits full content).
14
14
  - Prompt attachments: frontpage prompt "…" --attach <file|/__media/…|https://…> [--asset-url https://…] (same media caps as media upload)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "frontpage-host",
3
- "version": "0.1.14",
3
+ "version": "0.1.16",
4
4
  "description": "Frontpage CLI — manage your site from the terminal",
5
5
  "type": "module",
6
6
  "bin": {