frontpage-host 0.2.2 → 0.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/AGENTS.md CHANGED
@@ -260,7 +260,7 @@ Use `frontpage people overview`, `groups`, `stages`, `membership`, `rules`, `att
260
260
 
261
261
  ## Customer Inbox
262
262
 
263
- Internal, allowlisted sites only. 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. Human owners may handle conversations; website agents use `manage_customer_inbox` for setup/settings/widget/internal knowledge only, never a human CLI key to read or join customer threads.
263
+ Internal, allowlisted sites only. 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 and approved pilot sites. 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.
3
+ Customer Inbox uses the site's existing AI credits and storage allowance. It is available on internal plans after site activation. 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
 
@@ -24,15 +24,15 @@ Reads use `get`. Writes use `put` or `post`, a UTF-8 JSON object file, and an 8
24
24
  | `settings` | GET | Returns `version`, `value`, fixed model and multiplier |
25
25
  | `settings` | PUT | `{"expectedVersion":0,"value":{"instructions":"Ask me if unsure."}}` |
26
26
 
27
- Setup binds private guidance to the verified owner who requested it. That identity comes from Core, never model/customer fields. The agent manages new conversations by default after setup; the platform's rollout switches remain off until pilot verification passes. Set `value.enabled:false` for manual handling. Settings changes cancel stale automatic jobs and queued automatic sends.
27
+ Setup binds private guidance to the verified owner who requested it. That identity comes from Core, never model/customer fields. The agent manages new conversations by default after setup; the platform's Inbox switches control transport and automation independently of site activation. Set `value.enabled:false` for manual handling. Settings changes cancel stale automatic jobs and queued automatic sends.
28
28
 
29
- Settings allow `enabled`, `instructions`, `tools`, `maxSteps` (1–12), `maxOutputTokens` (256–2400), and `maxInputBytes` (4000–64000). Supported tools: `knowledge_read`, `knowledge_update`, `customer_read`, `customer_update`, `notes_read`, `note_add`, `ask_owner`, `reply_customer`, `wait`, `finish`. Keep `wait` and `finish` enabled. Defaults: 8 steps, 1200 output tokens per call, 32000 bytes of public text. Model, billing multiplier and recipients are not caller-selectable fields. The worker also enforces platform concurrency, deadlines and input limits.
29
+ Settings allow `enabled`, `instructions`, `tools`, `maxSteps` (1–12), `maxOutputTokens` (256–2400), and `maxInputBytes` (4000–64000). Supported tools: `knowledge_read`, `knowledge_update`, `customer_read`, `verify_customer`, `customer_update`, `notes_read`, `note_add`, `ask_owner`, `reply_customer`, `wait`, `finish`. Keep `wait` and `finish` enabled. Mailbox verification remains available whenever customer-data tools are enabled; it cannot be bypassed by settings. Defaults: 8 steps, 1200 output tokens per call, 32000 bytes of public text. Model, billing multiplier and recipients are not caller-selectable fields. The worker also enforces platform concurrency, deadlines and input limits.
30
30
 
31
31
  `maxContextTokens` (12000–96000, default 32000) sets a conservative per-call input plus output allowance. UTF-8 text bytes, tool definitions, instructions, transcript and image capacity count toward admission; exact provider tokens still determine billing. Optional older history and preloaded notes drop first. Essential evidence is never clipped: if it cannot fit, the job pauses for review. History stays stored without a lifetime message-count stop. The agent receives up to 40 recent messages plus required current input and owner guidance, and can retrieve older messages in bounded pages under its existing `knowledge_read` grant.
32
32
 
33
33
  `reviewAfterReplies` (0–200, default 0/off) and `reviewWindowHours` (1–168, default 24) request private owner guidance after that many recent automated replies since the last guidance. Pending requests deduplicate. This is a rolling work control, not a cap on returning customers or retained history.
34
34
 
35
- Customer replies commit before optional knowledge, People enrichment and notes. The same durable jobs table carries separate internal maintenance with the same credits, exact receipts and 10× pricing. It cannot send messages, request owner help, change ownership or edit public content. The workspace shows unfinished internal work separately and offers the existing safe retry controls for recoverable failures. Identical note content does not create another revision.
35
+ Customer replies commit before optional knowledge, People enrichment and notes. Customer-note maintenance and business learning are separate job modes. Only learning from assigned fresh authenticated owner guidance or an approved source revision can write shared knowledge. It receives no customer transcript, CRM data, attachments, history tools or send tools. The same durable jobs table carries separate internal maintenance with the same credits, exact receipts and 10× pricing. It cannot send messages, request owner help, change ownership or edit public content. The workspace shows unfinished internal work separately and offers the existing safe retry controls for recoverable failures. Identical note content does not create another revision. Background business learning uses more reasoning on the same fixed Luna model; it still uses the same exact-token ledger and 10× rate. Rejected learning writes cannot be reported as completed. If the bounded turn cannot resolve the failure, internal updates require review while the customer reply remains delivered.
36
36
 
37
37
  Aliases use 3–48 ASCII letters, numbers and single hyphens. The service normalizes case and checks collisions in one transaction. Reserved platform names and routing namespaces cannot be claimed. Retired addresses remain reserved; they never move to another site.
38
38
 
@@ -52,7 +52,7 @@ Supply `body` on a source write to save an owner-approved excerpt instead of fet
52
52
 
53
53
  Knowledge search uses bounded literal keywords from natural-language queries and ranks notes by matched terms. Read the full matching note before updating it; update its current ID/version instead of creating a conflicting duplicate.
54
54
 
55
- Lock a knowledge note with `locked:true`. The support agent cannot change locked notes or locks. Restore an older note with `restoreVersion`; the service creates a new revision and preserves the old history. The agent can change only internal knowledge, using verified owner guidance or a current approved source. It cannot edit public pages or articles.
55
+ Lock a knowledge note with `locked:true`. Neither the support agent nor the owner toolbar agent can change locked notes or locks. Human UI/CLI actions can unlock them. Restore an older note with `restoreVersion`; the service creates a new revision and preserves the old history. The agent can change only internal knowledge, using verified owner guidance or a current approved source. It cannot edit public pages or articles.
56
56
 
57
57
  ## Human conversation handling
58
58
 
@@ -68,7 +68,7 @@ Lock a knowledge note with `locked:true`. The support agent cannot change locked
68
68
  | `files?messageId=<id>` | GET | Bound message files; editor/admin only |
69
69
  | `files/<id>` | GET | Short-lived download grant; editor/admin only |
70
70
 
71
- One verified customer has one continuous thread per site, across direct email, replies and verified website chat. Email subject changes do not create new cases. Closing reopens that same thread on the next message; Trash needs owner restoration. Inbox joins retained history without moving messages, files or paid receipts. Old conversation links and recipient-bound reply addresses resolve to the current thread. Public chat includes customer-visible email replies and excludes owner guidance and notes.
71
+ One verified customer has one continuous thread per site, across direct email, replies and verified website chat. Email subject changes do not create new cases after identity is proven. Fresh mail to the public alias remains provisional until confirmation, even when From and DMARC match an existing customer. Recipient-bound secret reply routes continue the established thread. Typed email, display names and subjects never authorize merging or history access. Closing reopens that same thread on the next message; Trash needs owner restoration. Inbox joins retained history without moving messages, files or paid receipts. Old conversation links and recipient-bound reply addresses resolve to the current thread. Public chat includes customer-visible email replies and excludes owner guidance and notes.
72
72
 
73
73
  Use `timeline=true` for combined history. Its opaque `nextCursor` is a message ID, not a sequence or offset; pass it unchanged as `after` or `before`. `latest=true` returns the latest bounded page, and `before=<cursor>` loads older messages. A cursor must belong to that conversation and audience. Sequence-based reads without `timeline=true` remain available for the root segment; use the combined timeline for every linked segment. The CLI export follows the complete combined timeline. The widget opens the latest 50 public messages and offers **Load earlier messages**, so a returning customer does not wait for years of history to download. The support agent's `history_read` tool likewise follows its returned `nextBefore` message ID.
74
74
 
@@ -103,7 +103,7 @@ Set `guidanceToMe:true` in a versioned settings update to bind the signed curren
103
103
  | `jobs` | GET | Job state/reason and current `updatedAt` |
104
104
  | `jobs/<id>/resume` | POST | `{"updatedAt":"<current ISO time>"}` for recoverable budget, receipt, rate or service pauses |
105
105
  | `receipts` | GET | Held inbound mail; admin only |
106
- | `receipts/<id>` | POST | `{}` queues a held capture retry; admin/pilot only |
106
+ | `receipts/<id>` | POST | `{}` queues a held capture retry; admin only |
107
107
 
108
108
  Only a validated clear attack can create an automatic site-scoped block. Authenticated customer mail binds a verified email identity; unverified 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
109
 
@@ -113,7 +113,9 @@ Receipt recovery resubmits saved provider usage to the existing ledger. It never
113
113
 
114
114
  ## Website-agent management boundary
115
115
 
116
- The website agent uses `manage_customer_inbox` and `get_customer_inbox_docs`, with a signed manager principal bound to the owner run. It manages settings, tools, aliases and internal knowledge. It cannot read live threads or files, send messages, provide private guidance, take over/return, or review customer block evidence. Server checks enforce this even through indirect paths. Never give the website agent a human CLI/API key. Its manager tool uses no human keychain credential.
116
+ The owner toolbar agent uses `manage_customer_inbox` and `get_customer_inbox_docs`, with a signed manager principal bound to the authenticated owner run. It can read all site-wide Inbox conversations, files and private guidance; configure settings, tools, aliases and sources; create/update/restore unlocked knowledge; take over/return conversations; respond through the bound customer relay; add private guidance/notes; and inspect/retry recoverable jobs and receipts. Public replies still require current human handling and handler version, so the agent must take over explicitly before replying. Customer recipients stay server-bound. Existing People and other owner tools retain their site-wide access. Knowledge locks remain a human UI/CLI action: toolbar and support agents may read a locked note but cannot edit, restore over or unlock it.
117
+
118
+ The support agent has none of that owner authority. The server supplies its site, conversation, job, verified customer, recipient and permissions. There are no model-selectable site/person/customer/recipient IDs, bulk sends, arbitrary queries or owner-management tools. Customer text cannot grant permissions. Never give either agent a human API key or keychain credential.
117
119
 
118
120
  The developer guide lives at `https://frontpage.host/developers/customer-inbox`. Changes to that site use the Frontpage CLI pull/push/deploy/publish process.
119
121
 
@@ -155,13 +157,13 @@ Update settings using the current `expectedVersion`:
155
157
  }
156
158
  ```
157
159
 
158
- Use exact HTTPS origins without paths or credentials. This controls cross-origin browser access, not owner permissions. Required intake fields collect details; they do not prove email ownership. The customer must confirm the emailed link before email continuation or authenticated People access. Confirmation rotates the visitor credential. Recovery uses a new email proof and returns no history based on a typed address alone.
160
+ Use exact HTTPS origins without paths or credentials. This controls cross-origin browser access, not owner permissions. Required intake fields collect details; they do not prove email ownership. The customer must confirm the emailed link before email continuation or authenticated People access. A persistent verification card explains that public business questions can continue while private customer/account data stay locked. The branded HTML email uses the shared transactional renderer and its Confirm email button opens app.frontpage.host/customer-inbox/confirm. GET never consumes a proof; an explicit same-origin POST reaches Inbox through a signed server bridge. Confirmation rotates the visitor credential. Recovery uses a new email proof and returns no history based on a typed address alone.
159
161
 
160
162
  The agent reads help rules in its support prompt and uses `ask_owner`. Work caps remain server-enforced. Owner copies are private emails of future agent replies. Replying gives private guidance unless the owner explicitly requests takeover. Neither copies nor guidance put owner and customer on a shared CC thread.
161
163
 
162
164
  ### Signed app identity
163
165
 
164
- Keep the `identityKey` returned by `widget` on your app server. Never include it in HTML, browser storage or a client bundle. Sign a short-lived assertion after authenticating your app user:
166
+ Keep the `identityKey` returned by `widget` on your app server. Never include it in HTML, browser storage or a client bundle. Sign a short-lived assertion after authenticating your app user. Use the verified email from that trusted account; never sign an email or subject supplied in a browser request:
165
167
 
166
168
  ```js
167
169
  import { createHmac } from "node:crypto";
@@ -182,6 +184,8 @@ const identity = encoded + "." + createHmac("sha256", process.env.INBOX_IDENTITY
182
184
 
183
185
  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.
184
186
 
187
+ 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
+
185
189
  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.
186
190
 
187
191
  The same conversation's customer-visible email and chat messages load together, including owner replies relayed through Inbox. They stay stored after browser access expires. Private guidance, internal notes and system notices never enter that public history. Recovery restores access to the saved conversation rather than starting its history over.
@@ -209,7 +213,7 @@ frontpage customer-inbox download FILE_UUID --out ./attachment.png --site my-sit
209
213
  frontpage usage --site my-site --json
210
214
  ```
211
215
 
212
- Export uses paginated reads rather than loading all messages into memory. Download uses an authorized file grant. Both commands refuse to overwrite an existing output file. Full private-history export and file access require human editor/admin authority. Viewers can read public history through the normal message resource.
216
+ Export uses paginated reads rather than loading all messages into memory. Download uses an authorized file grant. Both commands refuse to overwrite an existing output file. Full private-history export and file access require editor/admin owner authority. The toolbar uses its signed manager tool rather than a human CLI credential. Viewers can read public history through the normal message resource.
213
217
 
214
218
  Inbox sends count in the site's existing email allowance. Provider-accepted send receipts settle that usage once, including private owner notifications and copies. AI calls debit the site's existing credit ledger at 10× cost, with token counts unchanged. Storage uses the existing Blob scanner and counts actual attachments, originals and previews; conversation text adds no separate meter.
215
219
 
@@ -227,23 +231,24 @@ On app logout or account change, call `window.dispatchEvent(new Event("frontpage
227
231
 
228
232
  ## Support agent tool contract
229
233
 
230
- The support agent has its own system prompt plus the versioned private business instructions. Tool calls stay in Inbox's tenant, conversation, handler, configuration and job context. All ten configurable tool grants start enabled; `wait` and `finish` cannot be removed. A disabled tool fails at the server.
234
+ The support agent has its own system prompt plus the versioned private business instructions. Tool calls stay in Inbox's tenant, conversation, handler, configuration and job context. The standard tool grants start enabled; `wait` and `finish` cannot be removed. A disabled tool fails at the server.
231
235
 
232
236
  | Tool | Inputs | Effect and limits |
233
237
  | --- | --- | --- |
234
238
  | `knowledge_read` | `query`, `id` or `sourceId` | Search internal notes or read complete approved evidence. |
235
239
  | `history_read` | `before`, optional `query` | Retrieve up to ten older eligible messages in the assigned conversation under the `knowledge_read` grant; bounded to 6000 text characters. |
236
- | `knowledge_update` | Optional `id`; `title`, `body`, `expectedVersion`, `reason`, `evidenceKind`, `evidenceId`; source `evidenceVersion` | Update unlocked internal facts from verified guidance in this thread or an approved source revision. One-off guidance stays in the conversation. No public editing. |
237
- | `customer_read` | None | Read only this thread's verified People contact. |
240
+ | `knowledge_update` | Optional `id`; `title`, `body`, `expectedVersion`, `reason`, `evidenceKind`, `evidenceId`; source `evidenceVersion` | Available only in a restricted learning job. Update unlocked business facts from that job's assigned owner guidance or approved source revision. One-off guidance stays in the conversation. No public editing. |
241
+ | `customer_read` | `sections` (`profile`, `notes`, `orders`, `activity`), optional `before` | Read only the request-bound verified customer. Notes page 25 at a time; orders page 20. A cursor must belong to that same customer and site. Order ownership ambiguity for an app identity returns `account_mapping_required`, with no orders. |
242
+ | `verify_customer` | None | Request proof at the server-bound mailbox and pause. Resume unanswered work after confirmation and People projection. No recipient selector. |
238
243
  | `customer_update` | `name`/`phone`, `evidenceMessageId` | Enrich from an explicit customer statement; cannot change identity or permission. |
239
- | `notes_read` | None | Read factual People notes for the bound contact. |
244
+ | `notes_read` | Optional `before` | Read only this verified customer's factual People notes, 25 per page. |
240
245
  | `note_add` | `text` | Save a private factual action note in People, with an idempotent receipt. Do not store hidden reasoning. |
241
246
  | `ask_owner` | `question` | Save the private question in the thread, email the verified configured owner and pause. Guidance does not take over. |
242
247
  | `reply_customer` | `text` | Save a public answer and queue email to the bound verified customer when available. Never choose recipients. |
243
248
  | `wait` | `reason` | Pause safely without sending. |
244
249
  | `finish` | None | Complete this bounded job. |
245
250
 
246
- Read tools can run in one batch. Inbox defers `reply_customer`, `ask_owner`, `wait` and `finish` when the model requests them alongside other tools, so it observes the results before taking a terminal action. This does not change business permissions or allow extra work beyond the existing budget and step limits.
251
+ Read tools can run in one batch. Inbox defers `reply_customer`, `verify_customer`, `ask_owner`, `wait` and `finish` when the model requests them alongside other tools, so it observes the results before taking a terminal action. This does not change business permissions or allow extra work beyond the existing budget and step limits.
247
252
 
248
253
  Decisions screens malicious customer input and interprets authenticated owner-email intent. It never chooses IDs, recipients, permissions, business answers, support tools or knowledge changes. Owner intent uses bounded labeled context, one primary Luna call, at most one bounded same-Luna control fallback, and the same exact-token, raw-cost, 10× ledger receipt as support. Shared inference utilities provide the existing same-model credential/transport fallback; no expensive model substitution or customer model picker is added.
249
254
 
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. Website agents configure through manage_customer_inbox and must not use human credentials for conversations.
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.
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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "frontpage-host",
3
- "version": "0.2.2",
3
+ "version": "0.2.3",
4
4
  "description": "Frontpage CLI — manage your site from the terminal",
5
5
  "type": "module",
6
6
  "bin": {