frontpage-host 0.2.4 → 0.2.5
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 +1 -1
- package/CUSTOMER-INBOX.md +25 -3
- package/dist/commands/customer-inbox.js +1 -1
- package/llms.txt +1 -1
- package/package.json +1 -1
package/AGENTS.md
CHANGED
|
@@ -260,7 +260,7 @@ Use `frontpage people overview`, `groups`, `stages`, `membership`, `rules`, `att
|
|
|
260
260
|
|
|
261
261
|
## Customer Inbox
|
|
262
262
|
|
|
263
|
-
|
|
263
|
+
Scale and internal sites, after owner activation. No pilot allowlist. Use `frontpage customer-inbox get|put|post RESOURCE`, stable write keys and current versions. Full guide: [CUSTOMER-INBOX.md](./CUSTOMER-INBOX.md). `export CONVERSATION_ID --out FILE` writes authorized paginated history and file metadata; `download FILE_ID --out FILE` downloads through a file grant. Outputs never overwrite existing files. `frontpage usage` reports shared site credits, mail and storage. The owner toolbar uses `manage_customer_inbox` for all site-wide Inbox settings, unlocked knowledge, files, customer conversations, private guidance, replies, takeover/return and recovery. The support agent has a separate server-bound customer scope and requires verification for People data. Both agents cannot edit or unlock locked knowledge; human UI/CLI can unlock it. Never lend a website agent a human CLI key.
|
|
264
264
|
|
|
265
265
|
|
|
266
266
|
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/CUSTOMER-INBOX.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Customer Inbox
|
|
2
2
|
|
|
3
|
-
Customer Inbox uses the site's existing AI credits and storage allowance. It is available on internal plans after
|
|
3
|
+
Customer Inbox uses the site's existing AI credits and storage allowance. It is available on Scale and internal plans after owner activation. Other public plans do not include Inbox. No pilot allowlist is required. The support agent uses fixed GPT-6 Luna and bills AI usage at 10× raw provider cost. During human handling, customer messages use ordinary routing. Each authenticated owner email uses a small metered Luna Decisions call to keep private guidance, ownership controls and customer-facing replies distinct; the full support agent stays paused. UI and CLI controls need no intent call.
|
|
4
4
|
|
|
5
5
|
Run `frontpage help customer-inbox`. Use the site's normal CLI key:
|
|
6
6
|
|
|
@@ -94,6 +94,26 @@ Set `enabled:false` in settings to use manual handling for new conversations. Th
|
|
|
94
94
|
|
|
95
95
|
Set `guidanceToMe:true` in a versioned settings update to bind the signed current owner's verified address. Arbitrary recipient addresses and user IDs remain forbidden. The service saves only the resolved owner identity, not this setup flag.
|
|
96
96
|
|
|
97
|
+
## Verify a direct email sender
|
|
98
|
+
|
|
99
|
+
Fresh mail to the business address receives one generic confirmation email before support inference or People access. With passing receiving-service DMARC checks, a normal reply to its secret Reply-To confirms that mailbox. The customer can use **Confirm email** instead. No special reply words or AI decision are needed. Confirmation itself uses no AI credits; the email send and saved files use existing site allowances.
|
|
100
|
+
|
|
101
|
+
DMARC alone proves a sending domain, not a particular mailbox. Inbox requires the delivered secret destination, matching sender and site, active route, and live proof. It ignores sender-written authentication headers. Missing or gray checks offer the button only. A hard failure is held without an automatic reply. Temporary checks retry through the existing transport outbox and fall back to link confirmation after the third attempt.
|
|
102
|
+
|
|
103
|
+
The challenge lasts one hour. A successful email-only proof lasts 30 days. Repeated replies do not extend it. A used challenge address continues while its route and proof remain valid. Unused expired challenges and expired/revoked proofs grant no access. Send a new message to the business or ask its owner for a fresh link. An expired-route reply remains held with its original captured email; it does not silently become verified input. Owners can inspect held receipts and request a fresh confirmation rather than weakening identity checks.
|
|
104
|
+
|
|
105
|
+
Email confirmation never signs an existing browser into a customer account. A visitor who typed the same email still needs their own browser/app proof before history, orders, People notes or customer updates are available. Existing chat confirmation and recovery keep their browser-specific behavior. Once proven, email support joins the customer's continuous site thread and resumes the original question plus any new reply. Empty human replies can prove ownership without adding a blank customer message. Private guidance, manual handling, site eligibility and knowledge locks keep their existing rules.
|
|
106
|
+
|
|
107
|
+
Read `conversations/<id>/routing` for `identity.verified` and the email-only `verification` status. Status is `unrequested`, `pending`, `verified`, `expired`, `revoked`, `held`, `retrying` or `failed`; reasons and timestamps help separate proof from delivery. CLI 0.2.5 or later supports the new resend resource. A current human admin or owner-toolbar manager can send a fresh generic link to the already bound customer address:
|
|
108
|
+
|
|
109
|
+
```sh
|
|
110
|
+
printf '{}\n' > confirmation.json
|
|
111
|
+
frontpage customer-inbox post conversations/CONVERSATION_UUID/verification \
|
|
112
|
+
--file confirmation.json --request-key confirm_customer_20261016 --site my-site --json
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
The JSON CLI result contains `{"ok":true,"command":"customer-inbox","data":{"verification":"pending"}}`. Reuse the same key after a lost response. Inbox keeps one live pending challenge and enforces a one-minute resend cooldown. A reminder of a still-valid challenge keeps its original link and deadline; it does not create another grant or extend expiry. A pacing response uses HTTP `429` with `verification_cooldown`; retry after one minute. The request accepts no recipient or identity fields. A resend never grants authority by itself. The workspace provides the same **Send fresh confirmation** action. Owner-toolbar operation: `conversation_verify_email` with `{"id":"CONVERSATION_UUID"}`.
|
|
116
|
+
|
|
97
117
|
## Security review and recovery
|
|
98
118
|
|
|
99
119
|
| Resource | Method | JSON body |
|
|
@@ -105,7 +125,7 @@ Set `guidanceToMe:true` in a versioned settings update to bind the signed curren
|
|
|
105
125
|
| `receipts` | GET | Held inbound mail; admin only |
|
|
106
126
|
| `receipts/<id>` | POST | `{}` queues a held capture retry; admin only |
|
|
107
127
|
|
|
108
|
-
Only a validated clear attack can create an automatic site-scoped block.
|
|
128
|
+
Only a validated clear attack can create an automatic site-scoped block. DMARC-passing customer mail provides a site-scoped sender identity for abuse blocking only; it does not grant customer-data access. Unauthenticated mail stays thread-scoped. Blocks never ban a People contact across sites or a shared IP. Unblock preserves evidence and does not replay the attack. Uncertain, malformed, refused or unavailable screening pauses the agent and leaves human handling available. Known blocks and rate/size checks stop work before another paid call.
|
|
109
129
|
|
|
110
130
|
The fixed policy requires allow probability at least 0.90 and confidence at least 0.80, with no attack category. Automatic blocking requires malicious probability and confidence at least 0.98 and an attack category. Other results pause for human review; a review does not label the customer malicious. These are platform controls, not customer settings. Review email notices deduplicate per conversation and reason group per hour. Saved receipt retries wait at least 30 seconds so one failed receipt cannot monopolize recovery.
|
|
111
131
|
|
|
@@ -121,7 +141,7 @@ The developer guide lives at `https://frontpage.host/developers/customer-inbox`.
|
|
|
121
141
|
|
|
122
142
|
## Owner workspace and widget
|
|
123
143
|
|
|
124
|
-
Open `/workspace/sites/<siteId>/customer-inbox` on
|
|
144
|
+
Open `/workspace/sites/<siteId>/customer-inbox` on a Scale or internal site. The workspace uses the same versioned service operations as the CLI. Conversation rows show the latest public message. Customer messages, agent replies, owner replies, private guidance, notes and handling changes have distinct labels. Private guidance stays in the thread and does not transfer ownership.
|
|
125
145
|
|
|
126
146
|
Use `frontpage customer-inbox get widget --site my-site` as a human admin to get the script URL, site ID and server-side app identity key. Install the returned script through the normal Frontpage CLI file workflow or your app's template:
|
|
127
147
|
|
|
@@ -184,6 +204,8 @@ const identity = encoded + "." + createHmac("sha256", process.env.INBOX_IDENTITY
|
|
|
184
204
|
|
|
185
205
|
The service verifies the signature, site, origin and expiry. Assertions can last at most five minutes. They grant customer identity only, never owner or manager authority. Every app-session request must include the current signed identity matching that session's subject and email. Put a server-rendered assertion in `data-identity`, or preferably provide `data-identity-url="/api/support-identity"`. That same-origin HTTPS endpoint authenticates the current app user and returns `{"identity":"<signed assertion>"}`. The widget refreshes it; after logout or account changes, old app sessions cannot be read without the matching identity. Anonymous widgets need no assertion. Each approved origin has its own visitor session; email continues the bound conversation.
|
|
186
206
|
|
|
207
|
+
A new direct email to the public agent address can receive general business answers, but it does not prove mailbox ownership. DMARC validates the sending domain, not authority to read a customer record. The agent requests confirmation before reading or updating People, customer notes, orders or previous customer history. Fresh alias mail stays provisional until proof. Replies to a valid recipient-bound route can continue without a fresh click while the customer proof remains valid.
|
|
208
|
+
|
|
187
209
|
Unverified visitors can ask general business questions in their provisional chat. They cannot read or update an existing People contact, notes, orders or customer history. The same gate protects automatic People capture and every customer-data tool. After proof, People receives the customer and subsequent factual updates; the existing customer notes receipt remains idempotent. Public support and identity-protected support are distinct permissions.
|
|
188
210
|
|
|
189
211
|
Browser access lasts 30 days from creation or successful email verification/recovery. Verification links last one hour and work once; confirming rotates the credential. The widget retains access in that browser's storage and keeps it through temporary network failures. Returning browsers with valid access reopen their history automatically. When access is missing, ordinary **Continue** and email confirmation select the verified customer's continuous public-support conversation for that site. Both empty and nonempty provisional chats join only after proof; approved public origins can share the customer history through their own verified sessions. Typed email never restores history. Revoked credentials remain revoked; fresh proof does not reactivate an old token. Signed app identities remain separate by site, origin and subject. The recovery endpoint remains available, but customers need no separate Recover workflow. An empty unverified saved session with an email requests confirmation automatically; a receipt prevents duplicate requests during the link's one-hour lifetime, then rotates so an expired link cannot block a fresh confirmation.
|
|
@@ -5,7 +5,7 @@ import { takeFlag, assertNoUnknownFlags } from "../argv.js";
|
|
|
5
5
|
import { getApiKey } from "../auth/keychain.js";
|
|
6
6
|
import { apiBase, v1Get, httpErrorFromV1, CliHttpError, EXIT_AUTH, EXIT_USAGE, EXIT_OK, exitCodeForError, } from "../http/client.js";
|
|
7
7
|
import { emitOk, emitErr, isJson } from "../runtime.js";
|
|
8
|
-
const RESOURCE = /^(?:status|activation|address|widget|settings|knowledge(?:\/[0-9a-f-]+(?:\/history)?)?|sources|blocks(?:\/[0-9a-f-]+\/unblock)?|jobs(?:\/[0-9a-f-]+(?:\/resume)?)?|files(?:\/[0-9a-f-]+)?|receipts(?:\/[0-9a-f-]+)?|conversations(?:\/[0-9a-f-]+(?:\/(?:messages|routing|guidance|reply|control|state|revoke-sessions))?)?)(?:\?[^#]*)?$/;
|
|
8
|
+
const RESOURCE = /^(?:status|activation|address|widget|settings|knowledge(?:\/[0-9a-f-]+(?:\/history)?)?|sources|blocks(?:\/[0-9a-f-]+\/unblock)?|jobs(?:\/[0-9a-f-]+(?:\/resume)?)?|files(?:\/[0-9a-f-]+)?|receipts(?:\/[0-9a-f-]+)?|conversations(?:\/[0-9a-f-]+(?:\/(?:messages|routing|guidance|reply|control|state|revoke-sessions|verification))?)?)(?:\?[^#]*)?$/;
|
|
9
9
|
export function inboxCommand(args) {
|
|
10
10
|
const work = [...args], verb = work.shift(), resource = work.shift(), file = takeFlag(work, "--file"), key = takeFlag(work, "--request-key"), out = takeFlag(work, "--out");
|
|
11
11
|
assertNoUnknownFlags(work, "customer-inbox");
|
package/llms.txt
CHANGED
|
@@ -36,7 +36,7 @@
|
|
|
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
38
|
|
|
39
|
-
Customer Inbox (internal sites): CUSTOMER-INBOX.md. Settings, widget, knowledge, human guidance/relay, lifecycle, export/download and recovery. The owner toolbar manages all site-wide Inbox operations through manage_customer_inbox, including conversations, files and recovery, but cannot edit/unlock locked knowledge. The support agent is restricted to its verified customer and cannot change shared knowledge from customer input. No borrowed human credentials.
|
|
39
|
+
Customer Inbox (Scale and internal sites): CUSTOMER-INBOX.md. Settings, widget, knowledge, human guidance/relay, lifecycle, export/download and recovery. The owner toolbar manages all site-wide Inbox operations through manage_customer_inbox, including conversations, files and recovery, but cannot edit/unlock locked knowledge. The support agent is restricted to its verified customer and cannot change shared knowledge from customer input. No borrowed human credentials.
|
|
40
40
|
|
|
41
41
|
|
|
42
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.
|