frontpage-host 0.1.28 → 0.2.0
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 -2
- package/CUSTOMER-INBOX.md +237 -0
- package/PAYMENTS.md +334 -0
- package/PEOPLE.md +34 -14
- package/README.md +3 -0
- package/dist/argv.d.ts +2 -0
- package/dist/argv.js +8 -0
- package/dist/bin.js +6 -0
- package/dist/commands/customer-inbox.d.ts +14 -0
- package/dist/commands/customer-inbox.js +157 -0
- package/dist/commands/payments.d.ts +1 -0
- package/dist/commands/payments.js +303 -0
- package/dist/commands/people-workspace.js +1 -2
- package/dist/commands/people.js +5 -1
- package/dist/commands/shop.js +42 -87
- package/dist/completions/generate.js +9 -6
- package/dist/registry.js +100 -42
- package/llms.txt +7 -2
- package/package.json +5 -3
package/dist/commands/shop.js
CHANGED
|
@@ -3,10 +3,8 @@ import { resolveSlug } from "../site.js";
|
|
|
3
3
|
import { CliHttpError, EXIT_OK, EXIT_USAGE, v1Get, v1Patch, v1Post, v1Put, } from "../http/client.js";
|
|
4
4
|
import { assertNoUnknownFlags, hasFlag, takeFlag } from "../argv.js";
|
|
5
5
|
import { emitErr, emitOk, emitUsage, isJson, requireYesOrTty } from "../runtime.js";
|
|
6
|
-
import { openBrowser, resolveOpenUrl } from "../modules/oauth.js";
|
|
7
6
|
import { SHOP_ID_RE, VARIANT_ID_RE } from "./shop-ids.js";
|
|
8
|
-
const USAGE = "Usage: frontpage store items|variants|categories|settings|orders|
|
|
9
|
-
const CONNECT_FINISH = "Open the Frontpage URL while logged in, finish Stripe in the browser, then re-run status. This CLI cannot complete OAuth.";
|
|
7
|
+
const USAGE = "Usage: frontpage store items|variants|categories|settings|orders|import … [--site <slug>] [--json]";
|
|
10
8
|
const CENTS_HINT = "$49.99 is 4999";
|
|
11
9
|
function takeAll(work, name) {
|
|
12
10
|
const out = [];
|
|
@@ -142,7 +140,7 @@ async function readJsonFile(path) {
|
|
|
142
140
|
function printItem(row) {
|
|
143
141
|
const live = (row.variants ?? []).filter((v) => !v.archivedAt);
|
|
144
142
|
const prices = live.map((v) => v.discountPriceCents != null ? `${v.discountPriceCents}/${v.priceCents}` : String(v.priceCents));
|
|
145
|
-
const stocks = live.map((v) =>
|
|
143
|
+
const stocks = live.map((v) => v.stock == null ? "unlimited" : String(v.stock));
|
|
146
144
|
const bits = [
|
|
147
145
|
row.checkout ?? "",
|
|
148
146
|
row.amount ?? "",
|
|
@@ -218,7 +216,6 @@ export async function runShop(args) {
|
|
|
218
216
|
work.splice(work.indexOf(itemId), 1);
|
|
219
217
|
const title = takeFlag(work, "--title");
|
|
220
218
|
const description = takeFlag(work, "--description");
|
|
221
|
-
const checkout = takeFlag(work, "--checkout");
|
|
222
219
|
const amount = takeFlag(work, "--amount");
|
|
223
220
|
const minCents = parseCentsFlag(takeFlag(work, "--min-cents"), "minCents");
|
|
224
221
|
const requiresShipping = parseBoolFlag(takeFlag(work, "--requires-shipping"), "requiresShipping");
|
|
@@ -238,8 +235,6 @@ export async function runShop(args) {
|
|
|
238
235
|
body.title = title;
|
|
239
236
|
if (description !== undefined)
|
|
240
237
|
body.description = description;
|
|
241
|
-
if (checkout)
|
|
242
|
-
body.checkout = checkout;
|
|
243
238
|
if (amount)
|
|
244
239
|
body.amount = amount;
|
|
245
240
|
if (minCents !== undefined)
|
|
@@ -254,13 +249,14 @@ export async function runShop(args) {
|
|
|
254
249
|
body.images = images;
|
|
255
250
|
if (body.amount == null)
|
|
256
251
|
body.amount = "fixed";
|
|
257
|
-
|
|
252
|
+
const initialPrice = priceCents ?? (body.amount === "open" && typeof body.minCents === "number" ? body.minCents : undefined);
|
|
253
|
+
if (!Array.isArray(body.variants) && initialPrice !== undefined) {
|
|
258
254
|
const stock = stockRaw === undefined ? undefined : stockRaw === "unlimited" ? null : parseCountFlag(stockRaw, "stock");
|
|
259
255
|
body.variants = [
|
|
260
256
|
{
|
|
261
257
|
variantId: variantId ?? "default",
|
|
262
258
|
...(options ? { options } : {}),
|
|
263
|
-
priceCents,
|
|
259
|
+
priceCents: initialPrice,
|
|
264
260
|
...(discountCents !== undefined ? { discountPriceCents: discountCents } : {}),
|
|
265
261
|
...(stock !== undefined ? { stock } : {}),
|
|
266
262
|
},
|
|
@@ -281,7 +277,6 @@ export async function runShop(args) {
|
|
|
281
277
|
const itemId = requireShopId(work);
|
|
282
278
|
const title = takeFlag(work, "--title");
|
|
283
279
|
const description = takeFlag(work, "--description");
|
|
284
|
-
const checkout = takeFlag(work, "--checkout");
|
|
285
280
|
const amount = takeFlag(work, "--amount");
|
|
286
281
|
const minCents = parseCentsFlag(takeFlag(work, "--min-cents"), "minCents");
|
|
287
282
|
const requiresShipping = parseBoolFlag(takeFlag(work, "--requires-shipping"), "requiresShipping");
|
|
@@ -294,8 +289,6 @@ export async function runShop(args) {
|
|
|
294
289
|
body.title = title;
|
|
295
290
|
if (description !== undefined)
|
|
296
291
|
body.description = description;
|
|
297
|
-
if (checkout !== undefined)
|
|
298
|
-
body.checkout = checkout;
|
|
299
292
|
if (amount !== undefined)
|
|
300
293
|
body.amount = amount;
|
|
301
294
|
if (minCents !== undefined)
|
|
@@ -319,10 +312,10 @@ export async function runShop(args) {
|
|
|
319
312
|
printItem(data.item);
|
|
320
313
|
return EXIT_OK;
|
|
321
314
|
}
|
|
322
|
-
if (sub === "archive") {
|
|
315
|
+
if (sub === "archive" || sub === "restore") {
|
|
323
316
|
const itemId = requireShopId(work);
|
|
324
317
|
assertNoUnknownFlags(work, "store");
|
|
325
|
-
const data = await v1Post(`${base}/items/${encodeURIComponent(itemId)}
|
|
318
|
+
const data = await v1Post(`${base}/items/${encodeURIComponent(itemId)}/${sub}`, {});
|
|
326
319
|
if (isJson()) {
|
|
327
320
|
emitOk("store", data);
|
|
328
321
|
return EXIT_OK;
|
|
@@ -466,11 +459,11 @@ export async function runShop(args) {
|
|
|
466
459
|
printItem(data.item);
|
|
467
460
|
return EXIT_OK;
|
|
468
461
|
}
|
|
469
|
-
if (sub === "archive") {
|
|
462
|
+
if (sub === "archive" || sub === "restore") {
|
|
470
463
|
const itemId = requireShopId(work, "Item id", { allowIdFlag: false });
|
|
471
464
|
const variantId = requireVariantId(takeFlag(work, "--id") ?? takeFlag(work, "--variant"));
|
|
472
465
|
assertNoUnknownFlags(work, "store");
|
|
473
|
-
const data = await v1Post(`${base}/items/${encodeURIComponent(itemId)}/variants/${encodeURIComponent(variantId)}
|
|
466
|
+
const data = await v1Post(`${base}/items/${encodeURIComponent(itemId)}/variants/${encodeURIComponent(variantId)}/${sub}`, {});
|
|
474
467
|
if (isJson()) {
|
|
475
468
|
emitOk("store", data);
|
|
476
469
|
return EXIT_OK;
|
|
@@ -568,7 +561,9 @@ export async function runShop(args) {
|
|
|
568
561
|
fulfill.pickupEnabled ? "pickup" : null,
|
|
569
562
|
fulfill.shippingEnabled ? "delivery" : null,
|
|
570
563
|
].filter(Boolean);
|
|
571
|
-
const fulfillText = methods.length > 0
|
|
564
|
+
const fulfillText = methods.length > 0
|
|
565
|
+
? methods.join("+")
|
|
566
|
+
: (fulfill.shipping ?? "(no fulfillment)");
|
|
572
567
|
const checkoutText = s.storeCheckout === "instant" ? "pay-now" : "cart";
|
|
573
568
|
const feeText = fee.enabled ? `service-fee ${fee.cents ?? 0}` : "service-fee off";
|
|
574
569
|
console.log(`${s.currency ?? "(no currency)"} ${fulfillText} ${checkoutText} ${feeText}`);
|
|
@@ -619,39 +614,54 @@ export async function runShop(args) {
|
|
|
619
614
|
console.log("Fulfillment saved.");
|
|
620
615
|
return EXIT_OK;
|
|
621
616
|
}
|
|
622
|
-
if (sub === "set-
|
|
623
|
-
const
|
|
617
|
+
if (sub === "set-receipt") {
|
|
618
|
+
const templateId = takeFlag(work, "--template");
|
|
619
|
+
const stock = hasFlag(work, "--stock");
|
|
624
620
|
assertNoUnknownFlags(work, "store");
|
|
625
|
-
if (!
|
|
626
|
-
throw new CliHttpError("
|
|
627
|
-
}
|
|
628
|
-
|
|
621
|
+
if ((templateId === undefined) === !stock)
|
|
622
|
+
throw new CliHttpError("Use --template <id> or --stock, never both.", EXIT_USAGE, 0, "bad_request");
|
|
623
|
+
const data = await v1Post(`${base}/settings/receipt`, {
|
|
624
|
+
templateId: stock ? "" : templateId,
|
|
625
|
+
});
|
|
629
626
|
if (isJson())
|
|
630
627
|
emitOk("store", data);
|
|
631
628
|
else
|
|
632
|
-
console.log("
|
|
629
|
+
console.log("Order receipt saved. No email was sent.");
|
|
633
630
|
return EXIT_OK;
|
|
634
631
|
}
|
|
635
|
-
if (sub === "
|
|
636
|
-
const
|
|
632
|
+
if (sub === "availability") {
|
|
633
|
+
const mode = work.shift() ?? "get";
|
|
634
|
+
if (!["get", "on", "off"].includes(mode))
|
|
635
|
+
throw new CliHttpError("Use store settings availability get|on|off.", EXIT_USAGE, 0, "bad_request");
|
|
637
636
|
assertNoUnknownFlags(work, "store");
|
|
638
|
-
if (
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
637
|
+
if (mode !== "get") {
|
|
638
|
+
const problem = requireYesOrTty("Change Store availability");
|
|
639
|
+
if (problem)
|
|
640
|
+
throw new CliHttpError(problem, EXIT_USAGE, 0, "bad_request");
|
|
641
|
+
}
|
|
642
|
+
const data = mode === "get"
|
|
643
|
+
? await v1Get(`${base}/settings/availability`)
|
|
644
|
+
: await v1Post(`${base}/settings/availability`, {
|
|
645
|
+
enabled: mode === "on",
|
|
646
|
+
confirm: true,
|
|
647
|
+
});
|
|
642
648
|
if (isJson())
|
|
643
649
|
emitOk("store", data);
|
|
644
650
|
else
|
|
645
|
-
console.log(
|
|
651
|
+
console.log(JSON.stringify(data, null, 2));
|
|
646
652
|
return EXIT_OK;
|
|
647
653
|
}
|
|
648
654
|
if (sub === "set-checkout-fee") {
|
|
649
655
|
const off = hasFlag(work, "--off");
|
|
650
656
|
const cents = parseCentsFlag(takeFlag(work, "--cents"), "checkoutFeeCents");
|
|
657
|
+
const mode = takeFlag(work, "--mode");
|
|
658
|
+
const bps = parseCountFlag(takeFlag(work, "--bps"), "checkoutFeeBps");
|
|
651
659
|
assertNoUnknownFlags(work, "store");
|
|
652
660
|
const data = await v1Post(`${base}/settings/checkout-fee`, {
|
|
653
661
|
enabled: off ? false : true,
|
|
654
662
|
cents,
|
|
663
|
+
mode,
|
|
664
|
+
bps,
|
|
655
665
|
});
|
|
656
666
|
if (isJson())
|
|
657
667
|
emitOk("store", data);
|
|
@@ -661,61 +671,6 @@ export async function runShop(args) {
|
|
|
661
671
|
}
|
|
662
672
|
return emitUsage("store", USAGE);
|
|
663
673
|
}
|
|
664
|
-
if (group === "connect") {
|
|
665
|
-
const work = rest.slice(1);
|
|
666
|
-
const noOpen = hasFlag(work, "--no-open");
|
|
667
|
-
assertNoUnknownFlags(work, "store");
|
|
668
|
-
const data = await v1Post(`${base}/connect`, { action: "connect" });
|
|
669
|
-
const already = data.alreadyConnected === true;
|
|
670
|
-
if (isJson()) {
|
|
671
|
-
emitOk("store", data);
|
|
672
|
-
}
|
|
673
|
-
else {
|
|
674
|
-
const url = resolveOpenUrl(data.connectUrl);
|
|
675
|
-
if (url)
|
|
676
|
-
console.log(url);
|
|
677
|
-
console.log(typeof data.message === "string" ? data.message : already ? "Already connected." : CONNECT_FINISH);
|
|
678
|
-
if (typeof data.warning === "string")
|
|
679
|
-
console.log(data.warning);
|
|
680
|
-
}
|
|
681
|
-
const url = resolveOpenUrl(data.connectUrl);
|
|
682
|
-
if (url && !noOpen && !already)
|
|
683
|
-
openBrowser(url);
|
|
684
|
-
return EXIT_OK;
|
|
685
|
-
}
|
|
686
|
-
if (group === "status") {
|
|
687
|
-
const work = rest.slice(1);
|
|
688
|
-
assertNoUnknownFlags(work, "store");
|
|
689
|
-
const data = await v1Get(`${base}/connect`);
|
|
690
|
-
if (isJson()) {
|
|
691
|
-
emitOk("store", data);
|
|
692
|
-
return EXIT_OK;
|
|
693
|
-
}
|
|
694
|
-
const connection = (data.connection ?? {});
|
|
695
|
-
const display = connection.display ?? {};
|
|
696
|
-
console.log(`connected ${connection.ready ? "yes" : "no"}`);
|
|
697
|
-
console.log(`charges ${display.chargesEnabled == null ? "—" : display.chargesEnabled ? "yes" : "no"}`);
|
|
698
|
-
console.log(`account ${display.accountPresent ? "present" : "none"}`);
|
|
699
|
-
if (typeof data.sharedStripe === "string")
|
|
700
|
-
console.log(`note ${data.sharedStripe}`);
|
|
701
|
-
if (typeof data.connectUrl === "string")
|
|
702
|
-
console.log(`connect ${data.connectUrl}`);
|
|
703
|
-
return EXIT_OK;
|
|
704
|
-
}
|
|
705
|
-
if (group === "disconnect") {
|
|
706
|
-
const work = rest.slice(1);
|
|
707
|
-
assertNoUnknownFlags(work, "store");
|
|
708
|
-
const refuse = requireYesOrTty("disconnect the store (shared Stripe account with payments)");
|
|
709
|
-
if (refuse)
|
|
710
|
-
return emitUsage("store", refuse);
|
|
711
|
-
const data = await v1Post(`${base}/connect`, { action: "disconnect" });
|
|
712
|
-
if (isJson()) {
|
|
713
|
-
emitOk("store", data);
|
|
714
|
-
return EXIT_OK;
|
|
715
|
-
}
|
|
716
|
-
console.log(typeof data.message === "string" ? data.message : "Disconnected.");
|
|
717
|
-
return EXIT_OK;
|
|
718
|
-
}
|
|
719
674
|
if (group === "import") {
|
|
720
675
|
const work = rest.slice(1);
|
|
721
676
|
assertNoUnknownFlags(work, "store");
|
|
@@ -740,7 +695,7 @@ export async function runShop(args) {
|
|
|
740
695
|
console.log(`${imported.length} imported ${skipped.length} skipped ${failed.length} failed`);
|
|
741
696
|
return EXIT_OK;
|
|
742
697
|
}
|
|
743
|
-
if (group === "orders"
|
|
698
|
+
if (group === "orders") {
|
|
744
699
|
const noun = group;
|
|
745
700
|
const sub = rest[1] ?? "list";
|
|
746
701
|
const work = rest.slice(2);
|
|
@@ -27,7 +27,8 @@ _frontpage_completions() {
|
|
|
27
27
|
analytics) COMPREPLY=( $(compgen -W "dashboard summary query funnel timeseries compare sql" -- "\${cur}") ) ;;
|
|
28
28
|
people) COMPREPLY=( $(compgen -W "list get add set note rm-note follow-up hide unhide" -- "\${cur}") ) ;;
|
|
29
29
|
routines) COMPREPLY=( $(compgen -W "list get add set pause resume rm run runs" -- "\${cur}") ) ;;
|
|
30
|
-
|
|
30
|
+
payments) COMPREPLY=( $(compgen -W "status settings connect availability activity buttons tax invoices recurring customers --file --operation-key --preview-hash --person --email --description --amount-cents --cadence --first-date --time-zone --due-days --no-open --site --json --yes" -- "\${cur}") ) ;;
|
|
31
|
+
store) COMPREPLY=( $(compgen -W "items variants categories settings orders import" -- "\${cur}") ) ;;
|
|
31
32
|
modules)
|
|
32
33
|
if [[ \${COMP_CWORD} -ge 3 && \${COMP_WORDS[2]} == google_reviews ]]; then
|
|
33
34
|
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}") )
|
|
@@ -36,7 +37,7 @@ _frontpage_completions() {
|
|
|
36
37
|
elif [[ \${COMP_CWORD} -ge 3 && (\${COMP_WORDS[2]} == callbar || \${COMP_WORDS[2]} == booking || \${COMP_WORDS[2]} == signups) ]]; then
|
|
37
38
|
COMPREPLY=( $(compgen -W "docs request-setup enable disable archive config get set" -- "\${cur}") )
|
|
38
39
|
elif [[ \${COMP_CWORD} -ge 3 && \${COMP_WORDS[2]} == payments ]]; then
|
|
39
|
-
COMPREPLY=( $(compgen -W "docs
|
|
40
|
+
COMPREPLY=( $(compgen -W "docs" -- "\${cur}") )
|
|
40
41
|
else
|
|
41
42
|
COMPREPLY=( $(compgen -W "list docs request-setup enable disable archive config callbar forms booking signups payments articles google_reviews" -- "\${cur}") )
|
|
42
43
|
fi
|
|
@@ -72,7 +73,8 @@ _frontpage() {
|
|
|
72
73
|
analytics) _values 'subcommand' dashboard summary query funnel timeseries compare sql ;;
|
|
73
74
|
people) _values 'subcommand' list get add set note rm-note follow-up hide unhide ;;
|
|
74
75
|
routines) _values 'subcommand' list get add set pause resume rm run runs ;;
|
|
75
|
-
|
|
76
|
+
payments) _values 'subcommand' status settings connect availability activity buttons tax invoices recurring customers ;;
|
|
77
|
+
store) _values 'subcommand' items variants categories settings orders import ;;
|
|
76
78
|
modules)
|
|
77
79
|
if [[ $words[2] == google_reviews ]]; then
|
|
78
80
|
_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
|
|
@@ -81,7 +83,7 @@ _frontpage() {
|
|
|
81
83
|
elif [[ $words[2] == callbar || $words[2] == booking || $words[2] == signups ]]; then
|
|
82
84
|
_values 'subcommand' docs request-setup enable disable archive config get set
|
|
83
85
|
elif [[ $words[2] == payments ]]; then
|
|
84
|
-
_values 'subcommand' docs
|
|
86
|
+
_values 'subcommand' docs
|
|
85
87
|
else
|
|
86
88
|
_values 'subcommand' list docs request-setup enable disable archive config callbar forms booking signups payments articles google_reviews
|
|
87
89
|
fi
|
|
@@ -110,12 +112,13 @@ export function generateFishCompletion() {
|
|
|
110
112
|
`complete -c frontpage -n "__fish_seen_subcommand_from analytics" -a "dashboard summary query funnel timeseries compare sql"`,
|
|
111
113
|
`complete -c frontpage -n "__fish_seen_subcommand_from people" -a "list get add set note rm-note follow-up hide unhide"`,
|
|
112
114
|
`complete -c frontpage -n "__fish_seen_subcommand_from routines" -a "list get add set pause resume rm run runs"`,
|
|
113
|
-
`complete -c frontpage -n "__fish_seen_subcommand_from
|
|
115
|
+
`complete -c frontpage -n "__fish_seen_subcommand_from payments" -a "status settings connect availability activity buttons tax invoices recurring customers"
|
|
116
|
+
complete -c frontpage -n "__fish_seen_subcommand_from store" -a "items variants categories settings orders import"`,
|
|
114
117
|
`complete -c frontpage -n "__fish_seen_subcommand_from modules" -a "list docs request-setup enable disable archive config callbar forms booking signups payments articles google_reviews"`,
|
|
115
118
|
`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"`,
|
|
116
119
|
`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"`,
|
|
117
120
|
`complete -c frontpage -n "__fish_seen_subcommand_from modules; and __fish_seen_subcommand_from callbar booking signups" -a "get set"`,
|
|
118
|
-
`complete -c frontpage -n "__fish_seen_subcommand_from modules; and __fish_seen_subcommand_from payments" -a "
|
|
121
|
+
`complete -c frontpage -n "__fish_seen_subcommand_from modules; and __fish_seen_subcommand_from payments" -a "docs"`,
|
|
119
122
|
`complete -c frontpage -n "__fish_seen_subcommand_from extensions" -a "list docs enable disable config"`,
|
|
120
123
|
`complete -c frontpage -l site -d "Site subdomain slug"`,
|
|
121
124
|
];
|
package/dist/registry.js
CHANGED
|
@@ -39,7 +39,9 @@ export const COMMANDS = [
|
|
|
39
39
|
usage: "frontpage login [api-key]",
|
|
40
40
|
topics: ["auth"],
|
|
41
41
|
examples: ['frontpage login', 'frontpage login "$FRONTPAGE_API_KEY"'],
|
|
42
|
-
flags: [
|
|
42
|
+
flags: [
|
|
43
|
+
"FRONTPAGE_API_KEY env overrides keychain after login for that process"
|
|
44
|
+
],
|
|
43
45
|
seeAlso: ["whoami", "doctor", "logout"],
|
|
44
46
|
},
|
|
45
47
|
{
|
|
@@ -68,7 +70,9 @@ export const COMMANDS = [
|
|
|
68
70
|
usage: "frontpage use <subdomain>",
|
|
69
71
|
topics: ["auth", "sync"],
|
|
70
72
|
examples: ["frontpage use arbiter"],
|
|
71
|
-
dangers: [
|
|
73
|
+
dangers: [
|
|
74
|
+
"Clears baseCommitSha when switching sites — run pull again before push"
|
|
75
|
+
],
|
|
72
76
|
seeAlso: ["link", "pull", "status"],
|
|
73
77
|
},
|
|
74
78
|
{
|
|
@@ -200,7 +204,11 @@ export const COMMANDS = [
|
|
|
200
204
|
summary: "Open the site subdomain in a browser",
|
|
201
205
|
usage: "frontpage open [/path|--path /path] [--site <slug>] [--prod]",
|
|
202
206
|
topics: ["sync"],
|
|
203
|
-
examples: [
|
|
207
|
+
examples: [
|
|
208
|
+
"frontpage open",
|
|
209
|
+
"frontpage open /updates",
|
|
210
|
+
"frontpage open --path /pricing"
|
|
211
|
+
],
|
|
204
212
|
flags: [
|
|
205
213
|
"Optional site-relative path appended to https://<slug>.frontpage.host",
|
|
206
214
|
"--prod is a no-op stub today — still opens the *.frontpage.host subdomain",
|
|
@@ -337,12 +345,12 @@ export const COMMANDS = [
|
|
|
337
345
|
"frontpage modules forms get",
|
|
338
346
|
"frontpage modules forms set --instance lead-gen --notify-email hi@example.com",
|
|
339
347
|
"frontpage modules forms set --instance lead-gen --confirm-template <template-id>",
|
|
340
|
-
"frontpage
|
|
348
|
+
"frontpage payments connect --no-open",
|
|
341
349
|
"frontpage modules docs forms",
|
|
342
350
|
"frontpage modules docs google_reviews",
|
|
343
351
|
"frontpage modules docs signups",
|
|
344
352
|
"frontpage modules list",
|
|
345
|
-
|
|
353
|
+
"frontpage payments connect --no-open",
|
|
346
354
|
'frontpage modules request-setup google_reviews --reason "You asked for Google reviews — pick your listing so we show the right ones"',
|
|
347
355
|
],
|
|
348
356
|
flags: [
|
|
@@ -350,7 +358,7 @@ export const COMMANDS = [
|
|
|
350
358
|
"Key-first and verb-first both work: `modules google_reviews enable` = `modules enable google_reviews`",
|
|
351
359
|
"google_reviews extras: connect / resolve / status / list-reviews / hide / show / set-stars / set-sort / set-weight / reset-weights / refresh / disconnect / write-review-url",
|
|
352
360
|
"callbar/forms/booking/signups: typed get / set (same whitelist as `modules config`)",
|
|
353
|
-
"
|
|
361
|
+
"Stripe setup is frontpage payments connect. request-setup still lights the editor amber bar.",
|
|
354
362
|
"See https://frontpage.host/developers/modules and /developers/modules/google-reviews",
|
|
355
363
|
],
|
|
356
364
|
dangers: [
|
|
@@ -407,6 +415,26 @@ export const COMMANDS = [
|
|
|
407
415
|
],
|
|
408
416
|
seeAlso: ["prompt", "help content", "help site-building"],
|
|
409
417
|
},
|
|
418
|
+
{
|
|
419
|
+
name: "customer-inbox",
|
|
420
|
+
summary: "Manage internal Customer Inbox settings, knowledge and human conversation handling",
|
|
421
|
+
usage: "frontpage customer-inbox get|put|post <resource> [--file <json>] [--request-key <key>] [--site <slug>] [--json]; export|download <id> --out <new-file>",
|
|
422
|
+
topics: ["content"],
|
|
423
|
+
examples: [
|
|
424
|
+
"frontpage customer-inbox get settings",
|
|
425
|
+
"frontpage customer-inbox put settings --file ./inbox-settings.json --request-key settings_revision_1",
|
|
426
|
+
"frontpage customer-inbox get conversations",
|
|
427
|
+
"frontpage customer-inbox get knowledge"
|
|
428
|
+
],
|
|
429
|
+
flags: [
|
|
430
|
+
"Internal plans and the site pilot apply",
|
|
431
|
+
"Writes require a stable --request-key and a JSON file; reuse both on retries",
|
|
432
|
+
"Human CLI access can guide, take over and reply; website-agent tools have management scope only",
|
|
433
|
+
"Luna and 10× AI billing are fixed",
|
|
434
|
+
"Full request examples: CUSTOMER-INBOX.md"
|
|
435
|
+
],
|
|
436
|
+
seeAlso: ["people", "usage"],
|
|
437
|
+
},
|
|
410
438
|
{
|
|
411
439
|
name: "inbox",
|
|
412
440
|
summary: "List leads / subscribers / orders",
|
|
@@ -461,7 +489,7 @@ export const COMMANDS = [
|
|
|
461
489
|
"frontpage people export",
|
|
462
490
|
],
|
|
463
491
|
flags: [
|
|
464
|
-
"Workspace: groups list|get|create|update|archive|restore|preview; stages create|update|reorder|archive|restore; membership get|add|remove|move|stage|advance|override|hold; rules list|get|create|update|enable|pause|archive|validate|preview|runs|retry; attachments create; import preview|start|get|retry; person permission;
|
|
492
|
+
"Workspace: groups list|get|create|update|archive|restore|preview; stages create|update|reorder|archive|restore; membership get|add|remove|move|stage|advance|override|hold; rules list|get|create|update|enable|pause|archive|validate|preview|runs|retry; attachments create; import preview|start|get|retry; person permission; audience preview; overview; sources",
|
|
465
493
|
"All workspace operations accept --file JSON or --data JSON. Named flags: --id --label --name --group --stage --person --from-group --mode --color --position --terminal --enabled --hold --allowed --archived --reset --override include|exclude|auto --email-kind template|series --email-id --rule --run --cursor --limit --request-key. Boolean flags take true|false. Complex conditions/actions/mappings use JSON.",
|
|
466
494
|
"CSV: --csv PATH plus --file mapping.json. import start requires a stable --request-key. Retry the same import with the same key and contents.",
|
|
467
495
|
"list/export: --group GROUP_ID --stage STAGE_ID. See package PEOPLE.md for full examples and every JSON shape.",
|
|
@@ -476,41 +504,68 @@ export const COMMANDS = [
|
|
|
476
504
|
},
|
|
477
505
|
{
|
|
478
506
|
name: "store",
|
|
479
|
-
summary: "Store
|
|
480
|
-
usage: "frontpage store items|variants|categories|settings|orders|
|
|
507
|
+
summary: "Cart-only Store: products, variants, stock, categories, fulfillment, fees, receipts and orders",
|
|
508
|
+
usage: "frontpage store items|variants|categories|settings|orders|import … [--site <slug>] [--json]",
|
|
481
509
|
topics: ["content"],
|
|
482
510
|
examples: [
|
|
483
|
-
|
|
484
|
-
"frontpage store
|
|
485
|
-
"frontpage store
|
|
486
|
-
"frontpage store settings set-checkout --mode
|
|
487
|
-
"frontpage store
|
|
488
|
-
"frontpage store
|
|
489
|
-
"frontpage store items stock camp-hat --variant m --add 5",
|
|
490
|
-
"frontpage store items stock camp-hat --variant m --remove 5",
|
|
491
|
-
"frontpage store items stock camp-hat --variant m --set 20",
|
|
492
|
-
"frontpage store settings set-fulfillment --mode pickup",
|
|
493
|
-
"frontpage store settings set-fulfillment --pickup --delivery --mode flat-rate --flat-cents 500 --pickup-location \"The shop\"",
|
|
494
|
-
"frontpage store settings set-currency --currency usd",
|
|
495
|
-
"frontpage store settings set-currency --currency jpy",
|
|
496
|
-
"frontpage store connect --no-open",
|
|
497
|
-
"frontpage store status",
|
|
498
|
-
"frontpage store import",
|
|
511
|
+
'frontpage store items create camp-hat --title "Camp hat" --price-cents 4999 --stock 20',
|
|
512
|
+
"frontpage store items restore camp-hat",
|
|
513
|
+
"frontpage store settings set-fulfillment --pickup --delivery --mode flat-rate --flat-cents 500",
|
|
514
|
+
"frontpage store settings set-checkout-fee --mode percent --bps 250",
|
|
515
|
+
"frontpage store settings set-receipt --stock",
|
|
516
|
+
"frontpage store settings availability off --yes",
|
|
499
517
|
],
|
|
500
518
|
flags: [
|
|
501
|
-
"
|
|
502
|
-
"
|
|
503
|
-
"
|
|
504
|
-
"
|
|
505
|
-
"
|
|
506
|
-
"
|
|
507
|
-
"
|
|
508
|
-
"
|
|
509
|
-
"
|
|
510
|
-
|
|
511
|
-
|
|
519
|
+
"items list|get|create|update|archive|restore|activate|images|stock; use --file for nested variants, options, customizations and images. Existing fixed/open pricing is retained. Store always uses Add to cart.",
|
|
520
|
+
"Descriptions use a small markdown subset. Bind data-fp-store-bind=description for the full product story; do not bake titles, prices or images into the page. Store is cart-only; use Payments for explicit Pay now.",
|
|
521
|
+
"items stock uses --add/--remove as a signed delta, or --set/--unlimited. Never combine these verbs. Product pages use data-fp-store-product and the platform cart templates. Store prices use the account currency.",
|
|
522
|
+
"variants add|update|archive|restore; categories list|create|rename|archive. Create categories before assigning their slugs.",
|
|
523
|
+
"settings get|set-fulfillment|set-checkout-fee|set-receipt|availability get|on|off. Fee mode flat uses --cents; percent uses --bps (250 is 2.5%). Receipt takes --template <id> or --stock. Availability requires admin and --yes in scripts.",
|
|
524
|
+
"orders list|get; import explicitly reads the existing site product files. No fleet import or data conversion occurs.",
|
|
525
|
+
"Money fields use integer minor units: $49.99 is 4999 minor units in USD; JPY 4999 is ¥4999. Currency is read-only from Stripe. No --checkout, set-checkout or set-currency command.",
|
|
526
|
+
"Store off preserves catalog/orders and leaves Pay now/invoices/recurring billing running. Payments, Stripe setup, tax, activity and Pay now management use frontpage payments.",
|
|
527
|
+
"Full Store reference: packaged README.md and https://frontpage.host/developers/store. List bounds are source-specific; manage_store list_items is at most 25 compact rows.",
|
|
528
|
+
],
|
|
529
|
+
seeAlso: ["payments", "people", "https://frontpage.host/developers/store"],
|
|
530
|
+
},
|
|
531
|
+
{
|
|
532
|
+
name: "payments",
|
|
533
|
+
summary: "Stripe, tax, payment activity, Pay now buttons, invoices and native recurring billing",
|
|
534
|
+
usage: "frontpage payments status|settings|connect|availability|activity|tax|buttons|invoices|recurring|customers … [--site <slug>] [--json]",
|
|
535
|
+
topics: ["content"],
|
|
536
|
+
examples: [
|
|
537
|
+
"frontpage payments status",
|
|
538
|
+
"frontpage payments connect --no-open",
|
|
539
|
+
"frontpage payments invoices preview --file invoice.json --json",
|
|
540
|
+
"frontpage payments invoices send --file invoice.json --preview-hash <hash> --operation-key <stable-uuid> --yes --json",
|
|
541
|
+
"frontpage payments recurring preview --file recurring.json --json",
|
|
542
|
+
"frontpage payments recurring create --file recurring.json --preview-hash <hash> --operation-key <stable-uuid> --yes",
|
|
543
|
+
"frontpage payments customers send-billing-link <customerMapId> --operation-key <stable-uuid> --yes",
|
|
544
|
+
"frontpage payments availability off --yes",
|
|
545
|
+
],
|
|
546
|
+
flags: [
|
|
547
|
+
"status; settings; connect [--no-open]. Connect returns an existing signed-in admin browser handoff; it never accepts Stripe terms or completes onboarding.",
|
|
548
|
+
"availability preview|on|off. off reads affected counts before confirmed pause/void; a partial response stays off and requires another off request. on never resumes stopped billing or restores void invoices.",
|
|
549
|
+
"activity list|get <id> --source order|payment. invoices and recurring have separate get commands. Source IDs never collide.",
|
|
550
|
+
"buttons list [--limit 1..100 --offset N --archived true]; get|create|update|archive. create uses --id, --title, --price-cents, optional --amount open --min-cents; update takes an id and --file. Change price separately from details. Archive requires --yes. Only explicit Pay now references/registrations qualify; an old instant Store setting does not.",
|
|
551
|
+
"tax get; tax settings --file <file> --yes; tax registrations list|add --country US --state CA --yes|end <id> --yes. Supply the business's actual tax registrations. No automatic tax advice or raw Account Session secrets.",
|
|
552
|
+
"invoices preview|send --file <file>; list [--limit 1..100 --offset N --arrangement <id>]; get|refresh|resend|void <id>. send/resend need --operation-key; send needs --preview-hash; financial writes require --yes in scripts.",
|
|
553
|
+
"recurring preview|create --file <file>; list|get|refresh|cancel|resume|resend-invitation. Supported cadence: weekly, fortnightly, monthly, quarterly, yearly; firstDate YYYY-MM-DD, explicit IANA timeZone, 09:00 start. create/resume/invitation need stable operation keys. Resume requires first-date, preview-hash and --yes; no missed-period backfill.",
|
|
554
|
+
"customers billing-link|send-billing-link <customerMapId> --operation-key <key>. Send requires --yes. A returned link is private and expires after 30 minutes; do not put it in logs.",
|
|
555
|
+
"Common invoice flags: --person <CRM-id> OR --email <email> [--name <name>], --description, --amount-cents, --kind once|recurring, --collection manual|autopay, --cadence, --first-date, --time-zone, --due-days 7|14|30, --preview-hash, --operation-key. Use --file for nested address (line1,line2,city,region,postal,country).",
|
|
556
|
+
"Full REST methods, JSON examples, permissions, retries and financial semantics are in packaged PAYMENTS.md. All normal global auth/site/JSON/quiet/error/exit rules still apply.",
|
|
557
|
+
],
|
|
558
|
+
dangers: [
|
|
559
|
+
"Reuse the same operation key and reviewed input after a timeout. Do not create a new key to force a send. Accepted email is not paid or proof of arrival; Stripe test mode may suppress invoice emails.",
|
|
560
|
+
"Autopay create sends an invitation. The customer must agree and finish Stripe setup. Saved cards, owner flags and browser returns are not consent or payment.",
|
|
561
|
+
"CLI requires Scale/Enterprise/Internal. New invoices require Growth+ separately. Financial writes require admin; existing tax writes and private reads permit editors; viewers receive no private ledger.",
|
|
562
|
+
],
|
|
563
|
+
seeAlso: [
|
|
564
|
+
"store",
|
|
565
|
+
"people",
|
|
566
|
+
"modules",
|
|
567
|
+
"https://frontpage.host/developers/payments",
|
|
512
568
|
],
|
|
513
|
-
seeAlso: ["inbox", "https://frontpage.host/developers/store"],
|
|
514
569
|
},
|
|
515
570
|
{
|
|
516
571
|
name: "mail",
|
|
@@ -561,7 +616,9 @@ export const COMMANDS = [
|
|
|
561
616
|
"frontpage seo get --path /updates",
|
|
562
617
|
"frontpage seo set --path / --title \"Home\"",
|
|
563
618
|
],
|
|
564
|
-
flags: [
|
|
619
|
+
flags: [
|
|
620
|
+
"get accepts positional path or --path (flag wins); unknown leftover flags fail closed"
|
|
621
|
+
],
|
|
565
622
|
},
|
|
566
623
|
{
|
|
567
624
|
name: "articles",
|
|
@@ -733,7 +790,7 @@ export const TOPICS = {
|
|
|
733
790
|
- Forms: <form data-fp-form="slug"> with named inputs; no action/onsubmit/honeypot.
|
|
734
791
|
- Articles: frontpage articles …; migrate folders via frontpage prompt (don't invent mass delete+write).
|
|
735
792
|
- 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.
|
|
736
|
-
- Store: frontpage store for catalog, settings set-
|
|
793
|
+
- Store: frontpage store for catalog, settings set-fulfillment / set-checkout-fee / set-receipt; frontpage payments owns Stripe and invoices. 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
|
|
737
794
|
|
|
738
795
|
Full guide: https://frontpage.host/developers/site-building
|
|
739
796
|
See also: frontpage help sync | content | AGENTS.md`,
|
|
@@ -773,7 +830,8 @@ export const TOPICS = {
|
|
|
773
830
|
frontpage routines list|get|add|set|pause|resume|rm|run|runs
|
|
774
831
|
# Routines guide: https://frontpage.host/developers/routines
|
|
775
832
|
# 8am,12pm,4pm and tue,thu,fri store hours [8, 12, 16] and weekdays [2, 4, 5] on one routine. Timezone is IANA.
|
|
776
|
-
frontpage store items|variants|categories|settings|orders|
|
|
833
|
+
frontpage store items|variants|categories|settings|orders|import
|
|
834
|
+
frontpage payments status|connect|availability|activity|buttons|tax|invoices|recurring|customers
|
|
777
835
|
# Store catalog + live storefront: https://frontpage.host/developers/store
|
|
778
836
|
# Integer cents only. $49.99 is 4999. stock --add/--remove are signed delta.
|
|
779
837
|
# Markup: data-fp-store-grid / data-fp-store-product / data-fp-cart. One item.astro, not one file per product.
|
|
@@ -785,7 +843,7 @@ export const TOPICS = {
|
|
|
785
843
|
frontpage tokens set --group … --key … --value …
|
|
786
844
|
frontpage modules list|docs|request-setup|enable|disable|archive|config <key>
|
|
787
845
|
frontpage modules <key> # that key's CLI usage
|
|
788
|
-
frontpage
|
|
846
|
+
frontpage payments connect [--no-open] # Payments Stripe connect
|
|
789
847
|
# mailing list key: signups. Index: https://frontpage.host/developers/modules
|
|
790
848
|
frontpage extensions list|docs|enable|disable|config <key>
|
|
791
849
|
frontpage settings get|set
|
|
@@ -795,7 +853,7 @@ export const TOPICS = {
|
|
|
795
853
|
Do not fake payments/checkout. LOCKED extensions → do not fake; say plan required.
|
|
796
854
|
Migrate pages → articles: prefer frontpage prompt "migrate …" over mass delete+write.
|
|
797
855
|
edit uses click-edit (exact single occurrence), not push / gated-write.
|
|
798
|
-
Connect opens Frontpage (logged-in), then Stripe; never accepts or returns OAuth secrets.
|
|
856
|
+
Connect opens Frontpage (logged-in), then Stripe; never accepts or returns OAuth secrets. Stripe setup is frontpage payments connect.
|
|
799
857
|
Site contract: frontpage help site-building · https://frontpage.host/developers/site-building
|
|
800
858
|
Domains, billing, members, and site delete are out of v1.`,
|
|
801
859
|
history: `History
|
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: Store Stripe connect is frontpage
|
|
12
|
+
- Modules setup: Store Stripe connect is frontpage payments connect. Payments availability owns pause/restore and retains 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)
|
|
@@ -18,7 +18,7 @@
|
|
|
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|
|
|
21
|
+
- Store catalog: frontpage store items|variants|categories|settings|orders|import. 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 payments connect [--no-open] opens Frontpage then Stripe. Store is cart-only; currency comes from Stripe and cannot be set. Use frontpage payments for standalone Pay now and invoices. 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
|
|
22
22
|
- Analytics funnel: --steps JSON array or comma paths (/, /pricing); bad JSON → Invalid JSON for --steps
|
|
23
23
|
- Modules: unknown key errors list Known: …; mailing list module key is signups (not subscribe)
|
|
24
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
|
|
@@ -35,3 +35,8 @@
|
|
|
35
35
|
## People groups, stages, rules, and imports
|
|
36
36
|
|
|
37
37
|
Use `frontpage people overview`, `groups`, `stages`, `membership`, `rules`, `attachments`, `import`, and `company`. Use `frontpage mail campaign` for one-off group/stage/list audiences in Emails. Every editor action is available through these commands or `frontpage people workspace OPERATION --file payload.json`. Full operations and examples: [PEOPLE.md](./PEOPLE.md); public guide: https://frontpage.host/developers/people. Automated emails select a saved template or series. Campaigns use their own drafts.
|
|
38
|
+
|
|
39
|
+
Customer Inbox (internal sites): CUSTOMER-INBOX.md. Settings, widget, knowledge, human guidance/relay, lifecycle, export/download and recovery. Website agents configure through manage_customer_inbox and must not use human credentials for conversations.
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
Payments, invoices and recurring billing: see packaged [PAYMENTS.md](./PAYMENTS.md), `frontpage help payments`, and https://frontpage.host/developers/payments. Version 0.2.0 removes writable currency, Store checkout mode and Store-owned money commands; Store stays cart-only. Preview/review before sends; keep stable operation keys on retries. Autopay requires the customer’s own verified authorization.
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "frontpage-host",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "Frontpage CLI
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "Frontpage CLI \u2014 manage your site from the terminal",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
7
7
|
"frontpage": "dist/bin.js"
|
|
@@ -11,7 +11,9 @@
|
|
|
11
11
|
"README.md",
|
|
12
12
|
"AGENTS.md",
|
|
13
13
|
"llms.txt",
|
|
14
|
-
"PEOPLE.md"
|
|
14
|
+
"PEOPLE.md",
|
|
15
|
+
"CUSTOMER-INBOX.md",
|
|
16
|
+
"PAYMENTS.md"
|
|
15
17
|
],
|
|
16
18
|
"scripts": {
|
|
17
19
|
"build": "tsc -p tsconfig.json",
|