frontpage-host 0.2.1 → 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 +1 -1
- package/CUSTOMER-INBOX.md +29 -16
- package/dist/commands/customer-inbox.js +9 -9
- 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
|
-
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.
|
|
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
|
|
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
|
|
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`.
|
|
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
|
|
|
@@ -60,7 +60,7 @@ Lock a knowledge note with `locked:true`. The support agent cannot change locked
|
|
|
60
60
|
| --- | --- | --- |
|
|
61
61
|
| `conversations` | GET | Paginated list; `?limit=50&after=<id>` |
|
|
62
62
|
| `conversations/<id>` | GET | Thread and latest public message |
|
|
63
|
-
| `conversations/<id>/messages` | GET | `?
|
|
63
|
+
| `conversations/<id>/messages` | GET | `?timeline=true&limit=50&audience=all`; follow the returned message-ID `nextCursor` with `after`; viewers get public history only |
|
|
64
64
|
| `conversations/<id>/routing` | GET | Current handler/version, People link and delivery states |
|
|
65
65
|
| `conversations/<id>/reply` | POST | `{"text":"Tuesday at 6:30 works. Keep staffing private.","handlerVersion":0,"privateGuidance":true}` |
|
|
66
66
|
| `conversations/<id>/control` | POST | `{"action":"takeover","handlerVersion":0}` or `{"action":"return","handlerVersion":1}` |
|
|
@@ -68,6 +68,10 @@ 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 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
|
+
|
|
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
|
+
|
|
71
75
|
Private guidance stays in the same internal thread. The agent asks by a private email and stores its question in the history. Replying by email or UI gives context and leaves the agent responsible for the customer. The agent uses that context to answer and can update unlocked internal knowledge.
|
|
72
76
|
|
|
73
77
|
General owner facts, such as support hours and standard policies, update related unlocked knowledge without an explicit save request. One-time customer exceptions and private staffing details stay in the conversation. The agent reads the full note and records verified evidence before changing it. Late private guidance can still update knowledge after the customer has an answer; that work cannot send a duplicate customer reply. Locks, manual handling, paused automation and work limits still apply.
|
|
@@ -99,7 +103,7 @@ Set `guidanceToMe:true` in a versioned settings update to bind the signed curren
|
|
|
99
103
|
| `jobs` | GET | Job state/reason and current `updatedAt` |
|
|
100
104
|
| `jobs/<id>/resume` | POST | `{"updatedAt":"<current ISO time>"}` for recoverable budget, receipt, rate or service pauses |
|
|
101
105
|
| `receipts` | GET | Held inbound mail; admin only |
|
|
102
|
-
| `receipts/<id>` | POST | `{}` queues a held capture retry; admin
|
|
106
|
+
| `receipts/<id>` | POST | `{}` queues a held capture retry; admin only |
|
|
103
107
|
|
|
104
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.
|
|
105
109
|
|
|
@@ -109,7 +113,9 @@ Receipt recovery resubmits saved provider usage to the existing ledger. It never
|
|
|
109
113
|
|
|
110
114
|
## Website-agent management boundary
|
|
111
115
|
|
|
112
|
-
The
|
|
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.
|
|
113
119
|
|
|
114
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.
|
|
115
121
|
|
|
@@ -151,13 +157,13 @@ Update settings using the current `expectedVersion`:
|
|
|
151
157
|
}
|
|
152
158
|
```
|
|
153
159
|
|
|
154
|
-
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.
|
|
155
161
|
|
|
156
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.
|
|
157
163
|
|
|
158
164
|
### Signed app identity
|
|
159
165
|
|
|
160
|
-
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:
|
|
161
167
|
|
|
162
168
|
```js
|
|
163
169
|
import { createHmac } from "node:crypto";
|
|
@@ -178,12 +184,16 @@ const identity = encoded + "." + createHmac("sha256", process.env.INBOX_IDENTITY
|
|
|
178
184
|
|
|
179
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.
|
|
180
186
|
|
|
181
|
-
|
|
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
|
+
|
|
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.
|
|
182
190
|
|
|
183
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.
|
|
184
192
|
|
|
185
193
|
## Conversation state, exports and shared usage
|
|
186
194
|
|
|
195
|
+
Use `frontpage-host` 0.2.2 or later to export every linked history segment through message-ID cursors. Update with `npm install -g frontpage-host@latest`.
|
|
196
|
+
|
|
187
197
|
| Resource | Method | Body or behavior |
|
|
188
198
|
| --- | --- | --- |
|
|
189
199
|
| `conversations?state=active` | GET | Open threads; also `closed`, `trash` or `all` |
|
|
@@ -203,7 +213,7 @@ frontpage customer-inbox download FILE_UUID --out ./attachment.png --site my-sit
|
|
|
203
213
|
frontpage usage --site my-site --json
|
|
204
214
|
```
|
|
205
215
|
|
|
206
|
-
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
|
|
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.
|
|
207
217
|
|
|
208
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.
|
|
209
219
|
|
|
@@ -221,22 +231,25 @@ On app logout or account change, call `window.dispatchEvent(new Event("frontpage
|
|
|
221
231
|
|
|
222
232
|
## Support agent tool contract
|
|
223
233
|
|
|
224
|
-
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.
|
|
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.
|
|
225
235
|
|
|
226
236
|
| Tool | Inputs | Effect and limits |
|
|
227
237
|
| --- | --- | --- |
|
|
228
238
|
| `knowledge_read` | `query`, `id` or `sourceId` | Search internal notes or read complete approved evidence. |
|
|
229
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. |
|
|
230
|
-
| `knowledge_update` | Optional `id`; `title`, `body`, `expectedVersion`, `reason`, `evidenceKind`, `evidenceId`; source `evidenceVersion` | Update unlocked
|
|
231
|
-
| `customer_read` |
|
|
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. |
|
|
232
243
|
| `customer_update` | `name`/`phone`, `evidenceMessageId` | Enrich from an explicit customer statement; cannot change identity or permission. |
|
|
233
|
-
| `notes_read` |
|
|
244
|
+
| `notes_read` | Optional `before` | Read only this verified customer's factual People notes, 25 per page. |
|
|
234
245
|
| `note_add` | `text` | Save a private factual action note in People, with an idempotent receipt. Do not store hidden reasoning. |
|
|
235
246
|
| `ask_owner` | `question` | Save the private question in the thread, email the verified configured owner and pause. Guidance does not take over. |
|
|
236
247
|
| `reply_customer` | `text` | Save a public answer and queue email to the bound verified customer when available. Never choose recipients. |
|
|
237
248
|
| `wait` | `reason` | Pause safely without sending. |
|
|
238
249
|
| `finish` | None | Complete this bounded job. |
|
|
239
250
|
|
|
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.
|
|
252
|
+
|
|
240
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.
|
|
241
254
|
|
|
242
255
|
The installed widget loads two public static scripts: `/customer-inbox/widget.js` and `/customer-inbox/view.js` on `https://app.frontpage.host`. The shared renderer contains no session, owner data or credentials. If your app sets a Content Security Policy, allow those script URLs and connections to `https://frontpage-inbox-api.fly.dev`; keep the existing widget origin and identity checks. Owner Inbox pages remain authenticated.
|
|
@@ -49,7 +49,7 @@ export async function runCustomerInbox(args) {
|
|
|
49
49
|
const prefix = `/api/v1/sites/${encodeURIComponent(slug)}/customer-inbox`;
|
|
50
50
|
if (operation.method === "DOWNLOAD") {
|
|
51
51
|
const record = await v1Get(`${prefix}/files/${operation.resource}`);
|
|
52
|
-
const response = await fetch(record.
|
|
52
|
+
const response = await fetch(record.downloadUrl, {
|
|
53
53
|
redirect: "error",
|
|
54
54
|
signal: AbortSignal.timeout(60000),
|
|
55
55
|
});
|
|
@@ -64,25 +64,25 @@ export async function runCustomerInbox(args) {
|
|
|
64
64
|
}
|
|
65
65
|
else {
|
|
66
66
|
const conversation = await v1Get(`${prefix}/conversations/${operation.resource}`);
|
|
67
|
-
await handle.writeFile(JSON.stringify({ type: "conversation", value: conversation
|
|
67
|
+
await handle.writeFile(JSON.stringify({ type: "conversation", value: conversation }) +
|
|
68
68
|
"\n");
|
|
69
|
-
let cursor =
|
|
69
|
+
let cursor = null;
|
|
70
70
|
for (;;) {
|
|
71
|
-
const page = await v1Get(`${prefix}/conversations/${operation.resource}/messages?
|
|
72
|
-
for (const message of page.
|
|
71
|
+
const page = await v1Get(`${prefix}/conversations/${operation.resource}/messages?timeline=true&limit=100&audience=all${cursor ? `&after=${cursor}` : ""}`);
|
|
72
|
+
for (const message of page.messages) {
|
|
73
73
|
const attachments = await v1Get(`${prefix}/files?messageId=${message.id}`);
|
|
74
74
|
await handle.writeFile(JSON.stringify({
|
|
75
75
|
type: "message",
|
|
76
76
|
value: message,
|
|
77
|
-
attachments
|
|
77
|
+
attachments,
|
|
78
78
|
}) + "\n");
|
|
79
79
|
count++;
|
|
80
80
|
}
|
|
81
|
-
if (page.
|
|
81
|
+
if (page.nextCursor === null)
|
|
82
82
|
break;
|
|
83
|
-
if (page.
|
|
83
|
+
if (page.nextCursor === cursor)
|
|
84
84
|
throw new Error("History cursor did not advance.");
|
|
85
|
-
cursor = page.
|
|
85
|
+
cursor = page.nextCursor;
|
|
86
86
|
}
|
|
87
87
|
}
|
|
88
88
|
await handle.sync();
|
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.
|
|
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.
|