frontpage-host 0.1.21 → 0.1.22
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 +3 -2
- package/dist/bin.js +4 -1
- package/dist/commands/modules.js +13 -1
- package/dist/commands/people.js +29 -1
- package/dist/commands/routines.d.ts +1 -0
- package/dist/commands/routines.js +156 -0
- package/dist/commands/shop.js +95 -49
- package/dist/completions/generate.js +12 -11
- package/dist/http/client.js +1 -1
- package/dist/modules/commands.d.ts +3 -2
- package/dist/modules/commands.js +21 -89
- package/dist/modules/oauth.d.ts +2 -2
- package/dist/modules/oauth.js +7 -101
- package/dist/registry.d.ts +2 -0
- package/dist/registry.js +62 -29
- package/dist/routines-parse.d.ts +7 -0
- package/dist/routines-parse.js +78 -0
- package/llms.txt +3 -2
- package/package.json +1 -1
package/dist/modules/commands.js
CHANGED
|
@@ -7,9 +7,6 @@ export const DOCUMENTED_MODULE_KEYS = [
|
|
|
7
7
|
"forms",
|
|
8
8
|
"booking",
|
|
9
9
|
"signups",
|
|
10
|
-
"payments",
|
|
11
|
-
"shop",
|
|
12
|
-
"ordering",
|
|
13
10
|
"articles",
|
|
14
11
|
"google_reviews",
|
|
15
12
|
];
|
|
@@ -130,85 +127,6 @@ export const MODULE_COMMANDS = [
|
|
|
130
127
|
"Typed flags write the same whitelist as `modules config`. Generic JSON config still works.",
|
|
131
128
|
],
|
|
132
129
|
},
|
|
133
|
-
{
|
|
134
|
-
key: "payments",
|
|
135
|
-
name: "Pay buttons",
|
|
136
|
-
summary: "One-click Stripe pay buttons. No cart. Connect finishes in the browser, not the terminal.",
|
|
137
|
-
genericActions: GENERIC_ACTIONS,
|
|
138
|
-
extraActions: [
|
|
139
|
-
"status",
|
|
140
|
-
"connect [--no-open]",
|
|
141
|
-
"disconnect [--yes]",
|
|
142
|
-
],
|
|
143
|
-
notYet: [],
|
|
144
|
-
examples: [
|
|
145
|
-
"frontpage modules payments",
|
|
146
|
-
"frontpage modules payments status",
|
|
147
|
-
"frontpage modules payments connect --no-open",
|
|
148
|
-
"frontpage modules payments disconnect --yes",
|
|
149
|
-
"frontpage modules payments docs",
|
|
150
|
-
'frontpage modules payments request-setup --reason "Deposit button needs Stripe"',
|
|
151
|
-
],
|
|
152
|
-
notes: [
|
|
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
|
-
"Pay buttons and the Online store share one Stripe account. Disconnecting Pay buttons fails if the store still uses that account.",
|
|
155
|
-
"request-setup still lights the editor amber bar when you want the owner to finish there.",
|
|
156
|
-
],
|
|
157
|
-
},
|
|
158
|
-
{
|
|
159
|
-
key: "shop",
|
|
160
|
-
name: "Online store",
|
|
161
|
-
summary: "Catalog, cart, and Stripe checkout. Shares the Pay buttons Stripe account.",
|
|
162
|
-
genericActions: GENERIC_ACTIONS,
|
|
163
|
-
extraActions: [
|
|
164
|
-
"status",
|
|
165
|
-
"connect [--no-open]",
|
|
166
|
-
"disconnect [--yes]",
|
|
167
|
-
],
|
|
168
|
-
notYet: [],
|
|
169
|
-
examples: [
|
|
170
|
-
"frontpage modules shop",
|
|
171
|
-
"frontpage modules shop status",
|
|
172
|
-
"frontpage modules shop connect --no-open",
|
|
173
|
-
"frontpage modules shop disconnect --yes",
|
|
174
|
-
"frontpage modules shop docs",
|
|
175
|
-
'frontpage modules shop request-setup --reason "You asked for a store — Stripe setup makes checkout live"',
|
|
176
|
-
],
|
|
177
|
-
notes: [
|
|
178
|
-
"Connect needs an admin API key. It opens Frontpage (you must be logged in there), then Stripe. Already-connected sites stay live.",
|
|
179
|
-
"payments and shop share one Stripe account. Shop disconnect keeps the account on payments.",
|
|
180
|
-
"Shop still needs the shipping step in Modules if you have not set it.",
|
|
181
|
-
"request-setup still lights the editor amber bar when you want the owner to finish there.",
|
|
182
|
-
],
|
|
183
|
-
},
|
|
184
|
-
{
|
|
185
|
-
key: "ordering",
|
|
186
|
-
name: "Online ordering",
|
|
187
|
-
summary: "Square ordering. Connect finishes in the browser, not the terminal.",
|
|
188
|
-
genericActions: GENERIC_ACTIONS,
|
|
189
|
-
extraActions: [
|
|
190
|
-
"status",
|
|
191
|
-
"connect [--no-open]",
|
|
192
|
-
"disconnect [--yes]",
|
|
193
|
-
"sync",
|
|
194
|
-
],
|
|
195
|
-
notYet: ["fulfillment get|set"],
|
|
196
|
-
examples: [
|
|
197
|
-
"frontpage modules ordering",
|
|
198
|
-
"frontpage modules ordering status",
|
|
199
|
-
"frontpage modules ordering connect --no-open",
|
|
200
|
-
"frontpage modules ordering sync",
|
|
201
|
-
"frontpage modules ordering disconnect --yes",
|
|
202
|
-
"frontpage modules ordering docs",
|
|
203
|
-
'frontpage modules ordering request-setup --reason "You asked for online ordering — Square setup makes it live"',
|
|
204
|
-
],
|
|
205
|
-
notes: [
|
|
206
|
-
"Connect needs an editor API key. It opens Frontpage (you must be logged in there), then Square. Already-connected sites stay live.",
|
|
207
|
-
"sync refreshes the Square catalog (same as the hub Sync button).",
|
|
208
|
-
"request-setup still lights the editor amber bar when you want the owner to finish there.",
|
|
209
|
-
"Fulfillment (pickup/delivery) is not in this CLI yet — use Modules or the editor.",
|
|
210
|
-
],
|
|
211
|
-
},
|
|
212
130
|
{
|
|
213
131
|
key: "articles",
|
|
214
132
|
name: "Articles",
|
|
@@ -281,7 +199,6 @@ export const GOOGLE_REVIEWS_CLI_ACTIONS = [
|
|
|
281
199
|
];
|
|
282
200
|
export const TYPED_CONFIG_CLI_ACTIONS = ["get", "set"];
|
|
283
201
|
export const STRIPE_OAUTH_CLI_ACTIONS = ["status", "connect", "disconnect"];
|
|
284
|
-
export const ORDERING_OAUTH_CLI_ACTIONS = ["status", "connect", "disconnect", "sync"];
|
|
285
202
|
export function isCliModuleAction(key, action) {
|
|
286
203
|
if (key === "google_reviews") {
|
|
287
204
|
return GOOGLE_REVIEWS_CLI_ACTIONS.includes(action);
|
|
@@ -301,12 +218,6 @@ export function isCliModuleAction(key, action) {
|
|
|
301
218
|
if (key === "callbar" || key === "booking" || key === "signups") {
|
|
302
219
|
return TYPED_CONFIG_CLI_ACTIONS.includes(action);
|
|
303
220
|
}
|
|
304
|
-
if (key === "payments" || key === "shop") {
|
|
305
|
-
return STRIPE_OAUTH_CLI_ACTIONS.includes(action);
|
|
306
|
-
}
|
|
307
|
-
if (key === "ordering") {
|
|
308
|
-
return ORDERING_OAUTH_CLI_ACTIONS.includes(action);
|
|
309
|
-
}
|
|
310
221
|
return false;
|
|
311
222
|
}
|
|
312
223
|
export function isDocumentedModuleKey(raw) {
|
|
@@ -318,6 +229,26 @@ export function isGenericModuleVerb(raw) {
|
|
|
318
229
|
export function moduleCommand(key) {
|
|
319
230
|
return MODULE_COMMANDS.find((c) => c.key === key);
|
|
320
231
|
}
|
|
232
|
+
export function formatShopIsNotAModule() {
|
|
233
|
+
return [
|
|
234
|
+
"shop is not a module. Use frontpage store.",
|
|
235
|
+
"",
|
|
236
|
+
"Catalog, fulfillment, pay buttons, and Stripe connect:",
|
|
237
|
+
" frontpage store items|variants|categories|settings|orders|payments|connect|status|disconnect",
|
|
238
|
+
"",
|
|
239
|
+
"See also: https://frontpage.host/developers/store",
|
|
240
|
+
].join("\n");
|
|
241
|
+
}
|
|
242
|
+
export function formatPaymentsIsNotAModule() {
|
|
243
|
+
return [
|
|
244
|
+
"payments is not a module. Use frontpage store.",
|
|
245
|
+
"",
|
|
246
|
+
"Stripe connect lives on Store:",
|
|
247
|
+
" frontpage store connect|status|disconnect|payments",
|
|
248
|
+
"",
|
|
249
|
+
"See also: https://frontpage.host/developers/store",
|
|
250
|
+
].join("\n");
|
|
251
|
+
}
|
|
321
252
|
export function formatModuleUsage(key) {
|
|
322
253
|
const def = moduleCommand(key);
|
|
323
254
|
const lines = [
|
|
@@ -353,6 +284,7 @@ export function formatModulesIndex() {
|
|
|
353
284
|
...rows,
|
|
354
285
|
"",
|
|
355
286
|
"Generic: frontpage modules list|docs|request-setup|enable|disable|archive|config …",
|
|
287
|
+
"Store: frontpage store …",
|
|
356
288
|
"Articles content: frontpage articles …",
|
|
357
289
|
"Index: https://frontpage.host/developers/modules",
|
|
358
290
|
].join("\n");
|
package/dist/modules/oauth.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export declare const OAUTH_CLI_KEYS: readonly [
|
|
1
|
+
export declare const OAUTH_CLI_KEYS: readonly [];
|
|
2
2
|
export type OauthCliKey = (typeof OAUTH_CLI_KEYS)[number];
|
|
3
3
|
export declare function isOauthCliKey(key: string): key is OauthCliKey;
|
|
4
4
|
export declare function resolveOpenUrl(raw: unknown): string | null;
|
|
@@ -9,4 +9,4 @@ export declare function browserOpenCommand(url: string, platform?: NodeJS.Platfo
|
|
|
9
9
|
windowsVerbatimArguments?: boolean;
|
|
10
10
|
};
|
|
11
11
|
export declare function openBrowser(url: string): void;
|
|
12
|
-
export declare function runOauthHandoff(
|
|
12
|
+
export declare function runOauthHandoff(_key: OauthCliKey, _slug: string, _action: string, _flags: string[]): Promise<number>;
|
package/dist/modules/oauth.js
CHANGED
|
@@ -1,19 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Browser helpers for Store Stripe connect (`frontpage store connect`).
|
|
3
|
+
* Leftover-order module OAuth is gone.
|
|
3
4
|
*/
|
|
4
5
|
import { spawn } from "node:child_process";
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
|
|
8
|
-
import { formatModuleUsage } from "./commands.js";
|
|
9
|
-
export const OAUTH_CLI_KEYS = ["payments", "shop", "ordering"];
|
|
6
|
+
import { apiBase } from "../http/client.js";
|
|
7
|
+
import { emitUsage } from "../runtime.js";
|
|
8
|
+
export const OAUTH_CLI_KEYS = [];
|
|
10
9
|
export function isOauthCliKey(key) {
|
|
11
10
|
return OAUTH_CLI_KEYS.includes(key);
|
|
12
11
|
}
|
|
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
12
|
export function resolveOpenUrl(raw) {
|
|
18
13
|
if (typeof raw !== "string" || !raw.trim())
|
|
19
14
|
return null;
|
|
@@ -44,95 +39,6 @@ export function openBrowser(url) {
|
|
|
44
39
|
...(spec.windowsVerbatimArguments ? { windowsVerbatimArguments: true } : {}),
|
|
45
40
|
}).unref();
|
|
46
41
|
}
|
|
47
|
-
function
|
|
48
|
-
|
|
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}".`);
|
|
42
|
+
export async function runOauthHandoff(_key, _slug, _action, _flags) {
|
|
43
|
+
return emitUsage("modules", "Unknown module.");
|
|
138
44
|
}
|
package/dist/registry.d.ts
CHANGED
|
@@ -6,6 +6,8 @@ export type CommandDef = {
|
|
|
6
6
|
name: string;
|
|
7
7
|
summary: string;
|
|
8
8
|
usage?: string;
|
|
9
|
+
/** Unpublished leftover names that still dispatch. Help does not list these. */
|
|
10
|
+
aliases?: readonly string[];
|
|
9
11
|
/** Topic tags for `help <topic>`. */
|
|
10
12
|
topics?: string[];
|
|
11
13
|
examples?: string[];
|
package/dist/registry.js
CHANGED
|
@@ -335,13 +335,12 @@ export const COMMANDS = [
|
|
|
335
335
|
"frontpage modules callbar set --phone +14085551234 --sms no",
|
|
336
336
|
"frontpage modules forms get",
|
|
337
337
|
"frontpage modules forms set --instance lead-gen --notify-email hi@example.com",
|
|
338
|
-
"frontpage
|
|
339
|
-
"frontpage modules payments status",
|
|
338
|
+
"frontpage store connect --no-open",
|
|
340
339
|
"frontpage modules docs forms",
|
|
341
340
|
"frontpage modules docs google_reviews",
|
|
342
341
|
"frontpage modules docs signups",
|
|
343
342
|
"frontpage modules list",
|
|
344
|
-
'frontpage
|
|
343
|
+
'frontpage store connect --no-open',
|
|
345
344
|
'frontpage modules request-setup google_reviews --reason "You asked for Google reviews — pick your listing so we show the right ones"',
|
|
346
345
|
],
|
|
347
346
|
flags: [
|
|
@@ -349,13 +348,13 @@ export const COMMANDS = [
|
|
|
349
348
|
"Key-first and verb-first both work: `modules google_reviews enable` = `modules enable google_reviews`",
|
|
350
349
|
"google_reviews extras: connect / resolve / status / list-reviews / hide / show / set-stars / set-sort / set-weight / reset-weights / refresh / disconnect / write-review-url",
|
|
351
350
|
"callbar/forms/booking/signups: typed get / set (same whitelist as `modules config`)",
|
|
352
|
-
"
|
|
351
|
+
"Store Stripe connect is frontpage store connect. request-setup still lights the editor amber bar.",
|
|
353
352
|
"See https://frontpage.host/developers/modules and /developers/modules/google-reviews",
|
|
354
353
|
],
|
|
355
354
|
dangers: [
|
|
356
355
|
"Secret values are never returned — masks only",
|
|
357
356
|
"request-setup surfaces an owner prompt in the editor status bar (CLI cannot show it)",
|
|
358
|
-
"payments and
|
|
357
|
+
"payments and the store share one Stripe account — payments disconnect 409s if the store still uses it",
|
|
359
358
|
"OAuth cannot finish in the terminal; connect only opens the vendor URL",
|
|
360
359
|
"Do not write placeId through generic config — that skips listing resolve + seed",
|
|
361
360
|
],
|
|
@@ -413,6 +412,29 @@ export const COMMANDS = [
|
|
|
413
412
|
topics: ["content"],
|
|
414
413
|
dangers: ["--mark-read is side-effecting with no confirm"],
|
|
415
414
|
},
|
|
415
|
+
{
|
|
416
|
+
name: "routines",
|
|
417
|
+
summary: "Schedule a prompt for the site agent (not a module)",
|
|
418
|
+
usage: "frontpage routines list|get|add|set|pause|resume|rm|run|runs [--site <slug>] [--json]",
|
|
419
|
+
topics: ["content"],
|
|
420
|
+
examples: [
|
|
421
|
+
"frontpage routines list",
|
|
422
|
+
"frontpage routines add --cadence weekly --weekdays tue,thu,fri --hours 8am,12pm,4pm --timezone America/Chicago --name \"Weekday check\" --prompt \"Review new form submissions and reply to each customer.\"",
|
|
423
|
+
"frontpage routines pause <id>",
|
|
424
|
+
"frontpage routines resume <id>",
|
|
425
|
+
"frontpage routines run <id>",
|
|
426
|
+
],
|
|
427
|
+
flags: [
|
|
428
|
+
"add requires --name, --prompt, --cadence hourly|daily|weekly|monthly, and --timezone (IANA, such as America/Chicago)",
|
|
429
|
+
"--hours accepts 8, 8am, 12pm, 4pm. Several hours: 8am,12pm,4pm stores [8, 12, 16]",
|
|
430
|
+
"--weekdays accepts tue,thu,fri or 2,4,5. Sunday is 0. Weekly only",
|
|
431
|
+
"--month-days accepts 1,15. Days are 1 through 28. Monthly only",
|
|
432
|
+
"add starts the clock. pause stops it. run fires once and does not move the next time",
|
|
433
|
+
"That Tuesday example stores hours [8, 12, 16] and weekdays [2, 4, 5] on one routine",
|
|
434
|
+
"Unknown leftover flags fail closed (exit 2)",
|
|
435
|
+
],
|
|
436
|
+
seeAlso: ["people", "https://frontpage.host/developers/routines"],
|
|
437
|
+
},
|
|
416
438
|
{
|
|
417
439
|
name: "people",
|
|
418
440
|
summary: "List and manage site People (not inbox, not a module)",
|
|
@@ -422,6 +444,7 @@ export const COMMANDS = [
|
|
|
422
444
|
"frontpage people list",
|
|
423
445
|
"frontpage people add --email alex@example.com --name Alex",
|
|
424
446
|
"frontpage people set <id> --status working",
|
|
447
|
+
"frontpage people set <id> --line1 \"12 Main\" --city Austin --region TX --postal 78701 --country US",
|
|
425
448
|
"frontpage people note <id> --body \"Called them\"",
|
|
426
449
|
"frontpage people follow-up <id> --at 2026-09-12T00:00:00Z",
|
|
427
450
|
"frontpage people hide <id>",
|
|
@@ -440,36 +463,42 @@ export const COMMANDS = [
|
|
|
440
463
|
seeAlso: ["inbox", "https://frontpage.host/developers/people"],
|
|
441
464
|
},
|
|
442
465
|
{
|
|
443
|
-
name: "
|
|
444
|
-
summary: "Store catalog: items, variants, stock, and store settings (not
|
|
445
|
-
usage: "frontpage
|
|
466
|
+
name: "store",
|
|
467
|
+
summary: "Store catalog: items, variants, stock, and store settings (not inbox)",
|
|
468
|
+
usage: "frontpage store items|variants|categories|settings|orders|payments|connect|status|disconnect|import … [--site <slug>] [--json]",
|
|
446
469
|
topics: ["content"],
|
|
447
470
|
examples: [
|
|
448
|
-
"frontpage
|
|
449
|
-
"frontpage
|
|
450
|
-
"frontpage
|
|
451
|
-
"frontpage
|
|
452
|
-
"frontpage
|
|
453
|
-
"frontpage
|
|
454
|
-
"frontpage
|
|
455
|
-
"frontpage
|
|
456
|
-
"frontpage
|
|
457
|
-
"frontpage
|
|
458
|
-
"frontpage
|
|
459
|
-
"frontpage
|
|
471
|
+
"frontpage store items list",
|
|
472
|
+
"frontpage store categories create hats --label Hats",
|
|
473
|
+
"frontpage store items create camp-hat --title \"Camp hat\" --price-cents 4999 --categories hats --stock 20",
|
|
474
|
+
"frontpage store settings set-checkout --mode cart",
|
|
475
|
+
"frontpage store items list --category hats",
|
|
476
|
+
"frontpage store variants add camp-hat --id m --option Size=M --price-cents 4999 --stock 8",
|
|
477
|
+
"frontpage store items stock camp-hat --variant m --add 5",
|
|
478
|
+
"frontpage store items stock camp-hat --variant m --remove 5",
|
|
479
|
+
"frontpage store items stock camp-hat --variant m --set 20",
|
|
480
|
+
"frontpage store settings set-fulfillment --mode pickup",
|
|
481
|
+
"frontpage store settings set-fulfillment --pickup --delivery --mode flat-rate --flat-cents 500 --pickup-location \"The shop\"",
|
|
482
|
+
"frontpage store settings set-currency --currency usd",
|
|
483
|
+
"frontpage store settings set-currency --currency jpy",
|
|
484
|
+
"frontpage store connect --no-open",
|
|
485
|
+
"frontpage store status",
|
|
486
|
+
"frontpage store import",
|
|
460
487
|
],
|
|
461
488
|
flags: [
|
|
462
|
-
"Integer cents only. $49.99 is 4999. Do not send 49.99 or a dollar string.",
|
|
489
|
+
"Integer cents only. $49.99 is 4999. Do not send 49.99 or a dollar string. --price-cents is the usual cost. Optional --discount-cents is the sale the buyer pays (strictly less than price). Omit --discount-cents when there is no sale. Checkout charges the sale; the site strikes through the usual price.",
|
|
463
490
|
"--add / --remove become signed delta. 5 adds 5. --remove 5 removes 5. Result copy is added 5 / removed 5 / set to 20 / stockNow.",
|
|
464
491
|
"Pass either --add, --remove, or --set. Never two together. --set unlimited returns counted stock to unlimited.",
|
|
465
492
|
"items: list|get|create|update|archive|activate [--off] | images --urls … | stock [--variant m] --add|--remove|--set. list --category hats. create/update --categories hats,summer",
|
|
466
493
|
"categories: list|create|rename|archive. Create the category first. Assigning an unknown slug fails.",
|
|
467
494
|
"variants: add|update|archive <itemId> --id m --price-cents … [--option Size=M] [--stock]",
|
|
468
|
-
"settings: get|set-fulfillment|set-currency|set-checkout-fee. Connect: frontpage
|
|
495
|
+
"settings: get|set-fulfillment|set-currency|set-checkout|set-checkout-fee. Currency is any Stripe presentment code such as usd or jpy. Checkout is store-wide (cart or instant). Do not use leftover items --checkout to pick cart vs Pay now. Gift cards still use --amount open --min-cents. Service fee applies to Add to cart and Pay now. Connect: frontpage store connect|status|disconnect. connect opens Frontpage then Stripe; --no-open for CI. disconnect keeps the shared Stripe account on payments.",
|
|
496
|
+
"Page markup is yours: data-fp-store-grid + data-fp-cart (cart starts hidden), every store control data-fp-requires=store. Product pages are the default: unless they said they do not want product pages, write one src/pages/products/item.astro (or shop) with data-fp-store-product. If they said no, skip that file and do not bind href or url. Description is a small markdown subset. PDP bind is <div data-fp-store-bind=description>. Do not bake titles or prices. Guide: https://frontpage.host/developers/store",
|
|
497
|
+
"import reads src/content/products/*.json from the site store into Store. One default variant each. Skip if that itemId already exists. Does not invent categories or change fulfillment.",
|
|
469
498
|
"orders / payments list|get read the same ledgers as frontpage inbox orders|payments",
|
|
470
499
|
"Unknown leftover flags fail closed (exit 2)",
|
|
471
500
|
],
|
|
472
|
-
seeAlso: ["inbox", "https://frontpage.host/developers/
|
|
501
|
+
seeAlso: ["inbox", "https://frontpage.host/developers/store"],
|
|
473
502
|
},
|
|
474
503
|
{
|
|
475
504
|
name: "mail",
|
|
@@ -691,6 +720,7 @@ export const TOPICS = {
|
|
|
691
720
|
- Forms: <form data-fp-form="slug"> with named inputs; no action/onsubmit/honeypot.
|
|
692
721
|
- Articles: frontpage articles …; migrate folders via frontpage prompt (don't invent mass delete+write).
|
|
693
722
|
- Media: frontpage media upload (images/PDF ≤25 MB, video ≤50 MB). frontpage images generate --prompt "…" [--count N] for 1–4 AI variations of one invented picture (AI $ + storage). Use sitePath /__media/uploads/<slug>/… in markup (not raw blob URLs). Optional ?w= on rasters only.
|
|
723
|
+
- Store: frontpage store for catalog, settings set-checkout / set-fulfillment / set-checkout-fee, and connect. Write data-fp-store-grid + data-fp-cart (data-fp-requires=store; cart starts hidden). Unless they said they do not want product pages, write one src/pages/products/item.astro with data-fp-store-product. If they said no, skip that file and do not bind href or url. Guide: https://frontpage.host/developers/store
|
|
694
724
|
|
|
695
725
|
Full guide: https://frontpage.host/developers/site-building
|
|
696
726
|
See also: frontpage help sync | content | AGENTS.md`,
|
|
@@ -727,9 +757,13 @@ export const TOPICS = {
|
|
|
727
757
|
frontpage inbox [leads|subscribers|orders|google_reviews|…] [--mark-read] [--csv]
|
|
728
758
|
frontpage people list|get|add|set|note|rm-note|follow-up|hide|unhide|tag|export
|
|
729
759
|
# People CRM guide: https://frontpage.host/developers/people
|
|
730
|
-
frontpage
|
|
731
|
-
#
|
|
760
|
+
frontpage routines list|get|add|set|pause|resume|rm|run|runs
|
|
761
|
+
# Routines guide: https://frontpage.host/developers/routines
|
|
762
|
+
# 8am,12pm,4pm and tue,thu,fri store hours [8, 12, 16] and weekdays [2, 4, 5] on one routine. Timezone is IANA.
|
|
763
|
+
frontpage store items|variants|categories|settings|orders|payments|connect|status|disconnect
|
|
764
|
+
# Store catalog + live storefront: https://frontpage.host/developers/store
|
|
732
765
|
# Integer cents only. $49.99 is 4999. stock --add/--remove are signed delta.
|
|
766
|
+
# Markup: data-fp-store-grid / data-fp-store-product / data-fp-cart. One item.astro, not one file per product.
|
|
733
767
|
frontpage mail settings|email|template|series|send|sends|enrolments|suppress
|
|
734
768
|
frontpage seo get [/path|--path /path] | seo set --path /
|
|
735
769
|
frontpage redirects list|set|rm --from /old --to /new
|
|
@@ -738,8 +772,7 @@ export const TOPICS = {
|
|
|
738
772
|
frontpage tokens set --group … --key … --value …
|
|
739
773
|
frontpage modules list|docs|request-setup|enable|disable|archive|config <key>
|
|
740
774
|
frontpage modules <key> # that key's CLI usage
|
|
741
|
-
frontpage
|
|
742
|
-
frontpage modules ordering sync
|
|
775
|
+
frontpage store connect [--no-open] # Store Stripe connect
|
|
743
776
|
# mailing list key: signups. Index: https://frontpage.host/developers/modules
|
|
744
777
|
frontpage extensions list|docs|enable|disable|config <key>
|
|
745
778
|
frontpage settings get|set
|
|
@@ -749,7 +782,7 @@ export const TOPICS = {
|
|
|
749
782
|
Do not fake payments/checkout. LOCKED extensions → do not fake; say plan required.
|
|
750
783
|
Migrate pages → articles: prefer frontpage prompt "migrate …" over mass delete+write.
|
|
751
784
|
edit uses click-edit (exact single occurrence), not push / gated-write.
|
|
752
|
-
Connect opens Frontpage (logged-in), then Stripe
|
|
785
|
+
Connect opens Frontpage (logged-in), then Stripe; never accepts or returns OAuth secrets. Store connect is frontpage store connect.
|
|
753
786
|
Site contract: frontpage help site-building · https://frontpage.host/developers/site-building
|
|
754
787
|
Domains, billing, members, and site delete are out of v1.`,
|
|
755
788
|
history: `History
|
|
@@ -787,5 +820,5 @@ export const TOPICS = {
|
|
|
787
820
|
Prefer requestId from API error envelopes when filing support issues.`,
|
|
788
821
|
};
|
|
789
822
|
export function findCommand(name) {
|
|
790
|
-
return COMMANDS.find((c) => c.name === name);
|
|
823
|
+
return COMMANDS.find((c) => c.name === name || c.aliases?.includes(name));
|
|
791
824
|
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLI schedule words → the numbers the API stores.
|
|
3
|
+
* tue,thu,fri and 8am,12pm,4pm become weekdays [2, 4, 5] and hours [8, 12, 16].
|
|
4
|
+
*/
|
|
5
|
+
export declare function parseHourList(raw: string | undefined): number[];
|
|
6
|
+
export declare function parseWeekdayList(raw: string | undefined): number[];
|
|
7
|
+
export declare function parseMonthDayList(raw: string | undefined): number[];
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLI schedule words → the numbers the API stores.
|
|
3
|
+
* tue,thu,fri and 8am,12pm,4pm become weekdays [2, 4, 5] and hours [8, 12, 16].
|
|
4
|
+
*/
|
|
5
|
+
const WEEKDAYS = {
|
|
6
|
+
sun: 0,
|
|
7
|
+
sunday: 0,
|
|
8
|
+
mon: 1,
|
|
9
|
+
monday: 1,
|
|
10
|
+
tue: 2,
|
|
11
|
+
tues: 2,
|
|
12
|
+
tuesday: 2,
|
|
13
|
+
wed: 3,
|
|
14
|
+
wednesday: 3,
|
|
15
|
+
thu: 4,
|
|
16
|
+
thur: 4,
|
|
17
|
+
thurs: 4,
|
|
18
|
+
thursday: 4,
|
|
19
|
+
fri: 5,
|
|
20
|
+
friday: 5,
|
|
21
|
+
sat: 6,
|
|
22
|
+
saturday: 6,
|
|
23
|
+
};
|
|
24
|
+
export function parseHourList(raw) {
|
|
25
|
+
if (!raw || !raw.trim())
|
|
26
|
+
return [];
|
|
27
|
+
return unique(raw.split(",").map((part) => parseHour(part.trim())));
|
|
28
|
+
}
|
|
29
|
+
export function parseWeekdayList(raw) {
|
|
30
|
+
if (!raw || !raw.trim())
|
|
31
|
+
return [];
|
|
32
|
+
return unique(raw.split(",").map((part) => parseWeekday(part.trim())));
|
|
33
|
+
}
|
|
34
|
+
export function parseMonthDayList(raw) {
|
|
35
|
+
if (!raw || !raw.trim())
|
|
36
|
+
return [];
|
|
37
|
+
return unique(raw.split(",").map((part) => {
|
|
38
|
+
const n = Number(part.trim());
|
|
39
|
+
if (!Number.isInteger(n) || n < 1 || n > 28) {
|
|
40
|
+
throw new Error(`Month day must be 1 through 28. Got "${part.trim()}".`);
|
|
41
|
+
}
|
|
42
|
+
return n;
|
|
43
|
+
}));
|
|
44
|
+
}
|
|
45
|
+
function unique(values) {
|
|
46
|
+
return [...new Set(values)].sort((a, b) => a - b);
|
|
47
|
+
}
|
|
48
|
+
function parseHour(raw) {
|
|
49
|
+
const ampm = raw.toLowerCase().match(/^(\d{1,2})(?::(\d{2}))?\s*(am|pm)$/);
|
|
50
|
+
if (ampm) {
|
|
51
|
+
if (ampm[2] && ampm[2] !== "00") {
|
|
52
|
+
throw new Error(`Routines fire at minute 0. Got "${raw}".`);
|
|
53
|
+
}
|
|
54
|
+
let hour = Number(ampm[1]);
|
|
55
|
+
if (hour < 1 || hour > 12)
|
|
56
|
+
throw new Error(`Hour "${raw}" is not valid.`);
|
|
57
|
+
if (ampm[3] === "am")
|
|
58
|
+
hour = hour === 12 ? 0 : hour;
|
|
59
|
+
else
|
|
60
|
+
hour = hour === 12 ? 12 : hour + 12;
|
|
61
|
+
return hour;
|
|
62
|
+
}
|
|
63
|
+
if (/^\d{1,2}$/.test(raw)) {
|
|
64
|
+
const hour = Number(raw);
|
|
65
|
+
if (hour < 0 || hour > 23)
|
|
66
|
+
throw new Error(`Hour must be 0 through 23. Got "${raw}".`);
|
|
67
|
+
return hour;
|
|
68
|
+
}
|
|
69
|
+
throw new Error(`Hour "${raw}" is not valid. Use 8, 8am, or 4pm.`);
|
|
70
|
+
}
|
|
71
|
+
function parseWeekday(raw) {
|
|
72
|
+
const named = WEEKDAYS[raw.toLowerCase()];
|
|
73
|
+
if (named !== undefined)
|
|
74
|
+
return named;
|
|
75
|
+
if (/^[0-6]$/.test(raw))
|
|
76
|
+
return Number(raw);
|
|
77
|
+
throw new Error(`Weekday "${raw}" is not valid. Use tue or 2. Sunday is 0.`);
|
|
78
|
+
}
|
package/llms.txt
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
- 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.
|
|
10
10
|
- Module/extension docs: frontpage modules docs <key> | frontpage extensions docs <key>
|
|
11
11
|
- Search flags: --regex --case-sensitive --whole-word --files-only --context-lines --max-results
|
|
12
|
-
- Modules setup:
|
|
12
|
+
- Modules setup: Store Stripe connect is frontpage store connect. payments disconnect 409s if the store 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). Form destinations: frontpage modules forms destinations|connect-destination|attach-destination|detach-destination|remove-destination --yes|request-destination-setup (token = admin; request-destination-setup lights the editor bar; request-setup forms is a no-op; connect does not attach every form). Privyr: paste Incoming Webhook URL (https://www.privyr.com/api/v1/incoming-leads/…), not a token. HubSpot: Development → Keys → Service keys or Legacy apps → Auth → Show token. Pipedrive: profile → Company settings → Personal preferences → API. Docs: https://frontpage.host/developers/modules#forms-destinations. 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.
|
|
13
13
|
- Analytics ops: frontpage analytics summary|query|funnel|timeseries|compare|sql (bare analytics = dashboard)
|
|
14
14
|
- 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).
|
|
15
15
|
- Prompt attachments: frontpage prompt "…" --attach <file|/__media/…|https://…> [--asset-url https://…] (same media caps as media upload)
|
|
@@ -17,7 +17,8 @@
|
|
|
17
17
|
- SEO get: frontpage seo get [/path|--path /path]; search path filter: [path|--path <path>]; open [/path|--path /path]
|
|
18
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
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
|
-
-
|
|
20
|
+
- Routines: frontpage routines list|get|add|set|pause|resume|rm|run|runs. Several hours and several days are one routine. 8am,12pm,4pm and tue,thu,fri store hours [8, 12, 16] and weekdays [2, 4, 5]. Timezone is IANA. Do not guess UTC. Guide: https://frontpage.host/developers/routines
|
|
21
|
+
- Store catalog: frontpage store items|variants|categories|settings|orders|payments|connect|status|disconnect. Integer cents only ($49.99 is 4999). --price-cents is the usual cost. Optional --discount-cents is the sale the buyer pays (must be lower). Create a category before assigning it. Photos are /__media/uploads/<this-slug>/… or an HTTPS URL already saved on this site. frontpage store connect [--no-open] opens Frontpage then Stripe. Checkout is store-wide (settings set-checkout); do not use leftover items --checkout to pick cart vs Pay now. Service fee is settings set-checkout-fee. The cart starts hidden. Product pages are the default: unless they said they do not want product pages, write one src/pages/products/item.astro (or shop) with data-fp-store-product. If they said no, skip that file and do not bind href or url. Description is a small markdown subset; product-page bind is <div data-fp-store-bind="description">. Every store control carries data-fp-requires="store". Leave data-fp-store-variants empty. Do not bake titles or prices. Guide: https://frontpage.host/developers/store
|
|
21
22
|
- Analytics funnel: --steps JSON array or comma paths (/, /pricing); bad JSON → Invalid JSON for --steps
|
|
22
23
|
- Modules: unknown key errors list Known: …; mailing list module key is signups (not subscribe)
|
|
23
24
|
- 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
|