@pithy-sh/support 0.6.2 → 0.7.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.
Files changed (44) hide show
  1. package/README.md +2 -0
  2. package/dist/capability.d.ts +1 -1
  3. package/dist/capability.d.ts.map +1 -1
  4. package/dist/capability.js +5 -4
  5. package/dist/config/config.d.ts +7 -5
  6. package/dist/config/config.d.ts.map +1 -1
  7. package/dist/config/config.js +6 -5
  8. package/dist/http/handlers.d.ts.map +1 -1
  9. package/dist/http/handlers.js +2 -1
  10. package/dist/http/responses.d.ts +5 -0
  11. package/dist/http/responses.d.ts.map +1 -1
  12. package/dist/http/responses.js +3 -2
  13. package/dist/http/schemas.d.ts.map +1 -1
  14. package/dist/http/schemas.js +1 -1
  15. package/dist/provision/provisionSupport.d.ts +19 -20
  16. package/dist/provision/provisionSupport.d.ts.map +1 -1
  17. package/dist/provision/provisionSupport.js +14 -17
  18. package/dist/provision/sendingCheck.d.ts +7 -0
  19. package/dist/provision/sendingCheck.d.ts.map +1 -0
  20. package/dist/provision/sendingCheck.js +63 -0
  21. package/dist/reply/fromName.d.ts +20 -0
  22. package/dist/reply/fromName.d.ts.map +1 -0
  23. package/dist/reply/fromName.js +29 -0
  24. package/dist/reply/send.d.ts +10 -1
  25. package/dist/reply/send.d.ts.map +1 -1
  26. package/dist/reply/send.js +16 -2
  27. package/dist/reply/sender.d.ts +16 -0
  28. package/dist/reply/sender.d.ts.map +1 -0
  29. package/dist/reply/sender.js +27 -0
  30. package/dist/version.generated.d.ts +1 -1
  31. package/dist/version.generated.js +1 -1
  32. package/package.json +8 -8
  33. package/pithy.manifest.json +1 -1
  34. package/src/capability.ts +18 -15
  35. package/src/config/config.ts +13 -5
  36. package/src/http/handlers.ts +1 -0
  37. package/src/http/responses.ts +9 -1
  38. package/src/http/schemas.ts +4 -1
  39. package/src/provision/provisionSupport.ts +20 -21
  40. package/src/provision/sendingCheck.ts +69 -0
  41. package/src/reply/fromName.ts +37 -0
  42. package/src/reply/send.ts +31 -3
  43. package/src/reply/sender.ts +35 -0
  44. package/src/version.generated.ts +1 -1
package/README.md CHANGED
@@ -14,6 +14,8 @@ pithy add support
14
14
 
15
15
  **Search, by words and by meaning.** `GET /support/threads/search` takes `q`, a `mode` (`keyword`, `semantic` or `hybrid`), a `limit` (20, at most 50) and the inbox list's filters, and returns ranked threads, each named by its best-matching message with that message's raw `bm25` and similarity. Keyword is FTS5 with `search.fts` on and the `LIKE` scan otherwise; hybrid fuses it with semantic search by rank, so a paraphrase is found and an order number still comes first. The inbox list no longer takes `q`. **Semantic search costs a second inference per inbound message on your own Workers AI binding**, on top of classification — roughly double the per-message AI cost — so `search: { semantic: true }` is off until you turn it on. `pithy support provision` creates the Vectorize index and backfills it once, and `pithy vector reprocess --index support-messages` re-embeds after a model change, with no `vector()` composed. Vectors carry message ids only. See [`docs/commands/support.md`](../../docs/commands/support.md#search).
16
16
 
17
+ **Replies come from the inbox.** A mailed reply is sent from the address the customer wrote to, under the name of whoever answered: `"Jim Scott" <support@help.example.com>`, with that inbox as the `Reply-To`. `reply.fromName` is the display name, with `{agent}` replaced by the agent's name (default `{agent}`); with no agent name, the email capability's `fromName` is used. A fixed `reply.fromName` with no `{agent}` is used for every reply. Support declares the addresses it sends as, `inboundAddresses` and `reply.replyToAddress`, through `email().enqueueAs` (`@pithy-sh/email` ^0.9.0; an older one is refused at compose). A thread whose inbox is no longer claimed is answered from `reply.replyToAddress`, or refused when none is set. A domain Email Service cannot send from fails the job with the domain named, and nothing is sent from another address in its place. `pithy doctor` names each sending domain, inbound or reply-to, that cannot send.
18
+
17
19
  _Everything else is on the site. `pithy.sh/docs` is canonical — new prose goes there, not here._
18
20
 
19
21
  ## A person's data
@@ -46,7 +46,7 @@ export interface SupportWiring {
46
46
  enqueueEmail: EmailCapability["enqueue"] | undefined;
47
47
  /**
48
48
  * The optional peers the sender link reads through — `auth()`'s and `payments()`'s surfaces, set by
49
- * `compose` when each is composed. Found, never imported (#645): see `link/sender.ts`.
49
+ * `compose` when each is composed. Found, never imported: see `link/sender.ts`.
50
50
  */
51
51
  peers: SenderPeers;
52
52
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"capability.d.ts","sourceRoot":"","sources":["../src/capability.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,mCAAmC,CAAC;AAGnE,OAAO,EAAE,KAAK,UAAU,EAAoB,MAAM,0CAA0C,CAAC;AAC7F,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mCAAmC,CAAC;AACzE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,kCAAkC,CAAC;AAE3E,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AAItE,OAAO,EACL,KAAK,aAAa,EAClB,KAAK,kBAAkB,EAGxB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAqB,KAAK,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAO9E,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAIjD,OAAO,EAAkB,KAAK,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAW7E,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAErD;;;;;;;;GAQG;AACH,eAAO,MAAM,uBAAuB,OAAO,CAAC;AAE5C,+FAA+F;AAC/F,MAAM,MAAM,cAAc,GAAG,kBAAkB,GAAG;IAChD,6EAA6E;IAC7E,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF;;;;GAIG;AACH,MAAM,WAAW,aAAa;IAC5B,2BAA2B;IAC3B,MAAM,EAAE,aAAa,CAAC;IACtB,8BAA8B;IAC9B,UAAU,EAAE,iBAAiB,CAAC;IAC9B,0CAA0C;IAC1C,QAAQ,EAAE,oBAAoB,CAAC;IAC/B;;;;;OAKG;IACH,YAAY,EAAE,eAAe,CAAC,SAAS,CAAC,GAAG,SAAS,CAAC;IACrD;;;OAGG;IACH,KAAK,EAAE,WAAW,CAAC;IACnB;;;;;;;;OAQG;IACH,IAAI,EAAE,SAAS,CAAC;CACjB;AA4ED;;;;;GAKG;AACH,MAAM,WAAW,iBACf,SAAQ,UAAU,CAAC,eAAe,EAAE,kBAAkB,EAAE,SAAS,EAAE,OAAO,gBAAgB,CAAC;IAC3F,mCAAmC;IACnC,aAAa,EAAE,aAAa,CAAC;IAC7B,wGAAwG;IACxG,UAAU,EAAE,iBAAiB,CAAC;IAC9B,0CAA0C;IAC1C,QAAQ,EAAE,oBAAoB,CAAC;IAC/B,iFAAiF;IACjF,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,OAAO,CAAC,OAAO,GAAE,cAAmB,GAAG,iBAAiB,CAuIvE;AAED,2GAA2G;AAC3G,wBAAgB,mBAAmB,CAAC,UAAU,EAAE,UAAU,GAAG,UAAU,IAAI,iBAAiB,CAE3F"}
1
+ {"version":3,"file":"capability.d.ts","sourceRoot":"","sources":["../src/capability.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,mCAAmC,CAAC;AAGnE,OAAO,EAAE,KAAK,UAAU,EAAoB,MAAM,0CAA0C,CAAC;AAC7F,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mCAAmC,CAAC;AACzE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,kCAAkC,CAAC;AAE3E,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AAGtE,OAAO,EACL,KAAK,aAAa,EAClB,KAAK,kBAAkB,EAGxB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAqB,KAAK,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAO9E,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAMjD,OAAO,EAAkB,KAAK,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAW7E,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAErD;;;;;;;;GAQG;AACH,eAAO,MAAM,uBAAuB,OAAO,CAAC;AAE5C,+FAA+F;AAC/F,MAAM,MAAM,cAAc,GAAG,kBAAkB,GAAG;IAChD,6EAA6E;IAC7E,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF;;;;GAIG;AACH,MAAM,WAAW,aAAa;IAC5B,2BAA2B;IAC3B,MAAM,EAAE,aAAa,CAAC;IACtB,8BAA8B;IAC9B,UAAU,EAAE,iBAAiB,CAAC;IAC9B,0CAA0C;IAC1C,QAAQ,EAAE,oBAAoB,CAAC;IAC/B;;;;;OAKG;IACH,YAAY,EAAE,eAAe,CAAC,SAAS,CAAC,GAAG,SAAS,CAAC;IACrD;;;OAGG;IACH,KAAK,EAAE,WAAW,CAAC;IACnB;;;;;;;;OAQG;IACH,IAAI,EAAE,SAAS,CAAC;CACjB;AA4ED;;;;;GAKG;AACH,MAAM,WAAW,iBACf,SAAQ,UAAU,CAAC,eAAe,EAAE,kBAAkB,EAAE,SAAS,EAAE,OAAO,gBAAgB,CAAC;IAC3F,mCAAmC;IACnC,aAAa,EAAE,aAAa,CAAC;IAC7B,wGAAwG;IACxG,UAAU,EAAE,iBAAiB,CAAC;IAC9B,0CAA0C;IAC1C,QAAQ,EAAE,oBAAoB,CAAC;IAC/B,iFAAiF;IACjF,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,OAAO,CAAC,OAAO,GAAE,cAAmB,GAAG,iBAAiB,CAyIvE;AAED,2GAA2G;AAC3G,wBAAgB,mBAAmB,CAAC,UAAU,EAAE,UAAU,GAAG,UAAU,IAAI,iBAAiB,CAE3F"}
@@ -15,13 +15,14 @@ import { createSupportEmailHandler } from "./inbound/handler.js";
15
15
  import { senderPeers } from "./link/peers.js";
16
16
  import { SUPPORT_MIGRATIONS } from "./migrations/set.js";
17
17
  import { supportPresence } from "./presence/room.js";
18
+ import { supportSendingSettings } from "./provision/sendingCheck.js";
18
19
  import { supportUserPurge } from "./purge/contribution.js";
20
+ import { replySender } from "./reply/sender.js";
19
21
  import { supportExampleSeed } from "./seeds/example.js";
20
22
  import { PACKAGE_NAME, PACKAGE_VERSION } from "./version.generated.js";
21
23
  import { noopEmit } from "@pithy-sh/core/src/audit/recorder";
22
24
  import { defineCapability } from "@pithy-sh/core/src/capability/capability";
23
25
  import { workflowBindings } from "@pithy-sh/core/src/workflow/bindings";
24
- import { isEmailCapability } from "@pithy-sh/email/src/capability";
25
26
  //#region src/capability.ts
26
27
  /**
27
28
  * Sort order of the support migrations within the app database, relative to other capabilities.
@@ -164,7 +165,8 @@ function support(options = {}) {
164
165
  inapplicableSecrets: inapplicableAttachmentSecrets(resolved),
165
166
  workflows: supportWorkflows,
166
167
  requiredBindings,
167
- ciPermissions: ["email:routing"],
168
+ inboundRouting: { addresses: resolved.inboundAddresses },
169
+ settings: supportSendingSettings(resolved),
168
170
  databases: { app: {
169
171
  binding: "DB",
170
172
  tables: supportTables,
@@ -182,8 +184,7 @@ function support(options = {}) {
182
184
  ...resolved.staff ? { powers: [resolved.staff.readPower, resolved.staff.assignPower] } : {},
183
185
  compose: ({ capabilities }) => {
184
186
  assertStaffComposition(resolved.staff, capabilities);
185
- const email = capabilities.find(isEmailCapability);
186
- wiring.enqueueEmail = email?.enqueue;
187
+ wiring.enqueueEmail = replySender(capabilities, resolved);
187
188
  wiring.peers = senderPeers(capabilities, resolved);
188
189
  },
189
190
  client: () => clientProjection(resolved, mountPath),
@@ -128,6 +128,7 @@ export type SupportSubmissionConfig = z.output<typeof SupportSubmissionConfig>;
128
128
  export declare const SupportReplyConfig: z.ZodObject<{
129
129
  enabled: z.ZodDefault<z.ZodBoolean>;
130
130
  replyToAddress: z.ZodPipe<z.ZodOptional<z.ZodString>, z.ZodTransform<string | undefined, string | undefined>>;
131
+ fromName: z.ZodDefault<z.ZodString>;
131
132
  deliverInApp: z.ZodDefault<z.ZodBoolean>;
132
133
  snippets: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
133
134
  label: z.ZodString;
@@ -179,7 +180,7 @@ export type SupportSearchConfig = z.output<typeof SupportSearchConfig>;
179
180
  export declare function supportSemantic(search: SupportSearchConfig): SupportSemanticConfig | undefined;
180
181
  /** The full support configuration. */
181
182
  /**
182
- * **Who of the app's own signed-in users works the inbox (#816).** Off until named.
183
+ * **Who of the app's own signed-in users works the inbox.** Off until named.
183
184
  *
184
185
  * The inbox holds every customer's correspondence, so a signed-in user reaches it only through a power the
185
186
  * adopter names in their own role catalog, held in the organization the request acts for — the same seam
@@ -238,6 +239,7 @@ export declare const SupportConfig: z.ZodObject<{
238
239
  reply: z.ZodPrefault<z.ZodObject<{
239
240
  enabled: z.ZodDefault<z.ZodBoolean>;
240
241
  replyToAddress: z.ZodPipe<z.ZodOptional<z.ZodString>, z.ZodTransform<string | undefined, string | undefined>>;
242
+ fromName: z.ZodDefault<z.ZodString>;
241
243
  deliverInApp: z.ZodDefault<z.ZodBoolean>;
242
244
  snippets: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
243
245
  label: z.ZodString;
@@ -269,10 +271,10 @@ export type SupportConfigInput = z.input<typeof SupportConfig>;
269
271
  * All three default `true`, so the ordinary project is unaffected by this predicate existing.
270
272
  *
271
273
  * Two callers, and they must agree: `capability.ts` declares the binding only when this is true, and
272
- * `pithy support provision` creates the bucket only when this is true. They disagreed before #440 —
273
- * the provisioner asked about `enabled` and `retainRaw` and never about submissions, so a project that
274
- * wanted uploads but no mail attachments got a binding pointing at a bucket nothing had created, and
275
- * every submitted file was dropped with a warning. One predicate is what makes that unrepresentable.
274
+ * `pithy support provision` creates the bucket only when this is true. Were they to ask different
275
+ * questions, a project that wanted uploads but no mail attachments would get a binding pointing at a
276
+ * bucket nothing had created, and every submitted file would be dropped with a warning. One predicate is
277
+ * what makes that unrepresentable.
276
278
  */
277
279
  export declare function supportNeedsBucket(config: SupportConfig): boolean;
278
280
  //# sourceMappingURL=config.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/config/config.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB;;;;;;;;;;GAUG;AAEH;;;;;;;GAOG;AACH,eAAO,MAAM,sBAAsB,mCAAmC,CAAC;AAEvE,0DAA0D;AAC1D,eAAO,MAAM,eAAe;;;;;iBA+BkF,CAAC;AAC/G,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,eAAe,CAAC,CAAC;AAE/D,+DAA+D;AAC/D,eAAO,MAAM,wBAAwB;;;;;iBA6BkF,CAAC;AACxH,MAAM,MAAM,wBAAwB,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,wBAAwB,CAAC,CAAC;AAEjF;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB;;;;;;;iBA8C8D,CAAC;AAC9F,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAErE;;;;;;;;;;;;;;;GAeG;AACH;;;;;;;GAOG;AACH,eAAO,MAAM,0BAA0B,KAAK,CAAC;AAE7C,eAAO,MAAM,kCAAkC;;;;;iBAkC5C,CAAC;AACJ,MAAM,MAAM,kCAAkC,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,kCAAkC,CAAC,CAAC;AAErG;;;;;;;;;GASG;AACH,eAAO,MAAM,4BAA4B,MAAM,CAAC;AAChD,2FAA2F;AAC3F,eAAO,MAAM,yBAAyB,SAAU,CAAC;AAEjD;;;;;;;;;;;;;GAaG;AAEH,eAAO,MAAM,uBAAuB;;;;;;;;;;;iBAwCjC,CAAC;AACJ,MAAM,MAAM,uBAAuB,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,uBAAuB,CAAC,CAAC;AAE/E,uCAAuC;AACvC,eAAO,MAAM,kBAAkB;;;;;;;;;iBAmC5B,CAAC;AACJ,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAErE;;;;;;;GAOG;AACH,eAAO,MAAM,uBAAuB,oBAAoB,CAAC;AAEzD;;;GAGG;AACH,eAAO,MAAM,4BAA4B,OAAO,CAAC;AAEjD,oGAAoG;AACpG,eAAO,MAAM,qBAAqB;;;iBAmB2B,CAAC;AAC9D,MAAM,MAAM,qBAAqB,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAE3E;;;;;GAKG;AACH,eAAO,MAAM,mBAAmB;;;;;;iBAiB7B,CAAC;AACJ,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAEvE;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,mBAAmB,GAAG,qBAAqB,GAAG,SAAS,CAI9F;AAED,sCAAsC;AACtC;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,kBAAkB;;;iBAiB5B,CAAC;AACJ,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAErE,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAoCvB,CAAC;AACJ,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,aAAa,CAAC,CAAC;AAC3D,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,aAAa,CAAC,CAAC;AAE/D;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,aAAa,GAAG,OAAO,CAEjE"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/config/config.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB;;;;;;;;;;GAUG;AAEH;;;;;;;GAOG;AACH,eAAO,MAAM,sBAAsB,mCAAmC,CAAC;AAEvE,0DAA0D;AAC1D,eAAO,MAAM,eAAe;;;;;iBA+BkF,CAAC;AAC/G,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,eAAe,CAAC,CAAC;AAE/D,+DAA+D;AAC/D,eAAO,MAAM,wBAAwB;;;;;iBA6BkF,CAAC;AACxH,MAAM,MAAM,wBAAwB,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,wBAAwB,CAAC,CAAC;AAEjF;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB;;;;;;;iBA8C8D,CAAC;AAC9F,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAErE;;;;;;;;;;;;;;;GAeG;AACH;;;;;;;GAOG;AACH,eAAO,MAAM,0BAA0B,KAAK,CAAC;AAE7C,eAAO,MAAM,kCAAkC;;;;;iBAkC5C,CAAC;AACJ,MAAM,MAAM,kCAAkC,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,kCAAkC,CAAC,CAAC;AAErG;;;;;;;;;GASG;AACH,eAAO,MAAM,4BAA4B,MAAM,CAAC;AAChD,2FAA2F;AAC3F,eAAO,MAAM,yBAAyB,SAAU,CAAC;AAEjD;;;;;;;;;;;;;GAaG;AAEH,eAAO,MAAM,uBAAuB;;;;;;;;;;;iBAwCjC,CAAC;AACJ,MAAM,MAAM,uBAAuB,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,uBAAuB,CAAC,CAAC;AAE/E,uCAAuC;AACvC,eAAO,MAAM,kBAAkB;;;;;;;;;;iBA2C5B,CAAC;AACJ,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAErE;;;;;;;GAOG;AACH,eAAO,MAAM,uBAAuB,oBAAoB,CAAC;AAEzD;;;GAGG;AACH,eAAO,MAAM,4BAA4B,OAAO,CAAC;AAEjD,oGAAoG;AACpG,eAAO,MAAM,qBAAqB;;;iBAmB2B,CAAC;AAC9D,MAAM,MAAM,qBAAqB,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAE3E;;;;;GAKG;AACH,eAAO,MAAM,mBAAmB;;;;;;iBAiB7B,CAAC;AACJ,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAEvE;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,mBAAmB,GAAG,qBAAqB,GAAG,SAAS,CAI9F;AAED,sCAAsC;AACtC;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,kBAAkB;;;iBAiB5B,CAAC;AACJ,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAErE,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAoCvB,CAAC;AACJ,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,aAAa,CAAC,CAAC;AAC3D,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,aAAa,CAAC,CAAC;AAE/D;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,aAAa,GAAG,OAAO,CAEjE"}
@@ -128,6 +128,7 @@ const SupportSubmissionConfig = z.object({
128
128
  const SupportReplyConfig = z.object({
129
129
  enabled: z.boolean().default(true).describe("Allow replies from the control-plane route. Off makes the inbox read-only, which is a reasonable setting for a project that answers support from its own mail client."),
130
130
  replyToAddress: z.string().optional().transform((address) => address === void 0 ? void 0 : parseAddress(address) ?? normalizeAddress(address)).describe("The `Reply-To` a reply carries — the address the customer's answer comes back to, which must be one of `inboundAddresses` or the conversation ends there. Defaults to the inbox address the thread arrived on, which is almost always what you want."),
131
+ fromName: z.string().min(1).max(120).default("{agent}").describe("The display name a mailed reply is sent under, with `{agent}` replaced by the answering agent's name: `{agent} at Acme` sends `\"Jim Scott at Acme\" <support@help.example.com>`. The address is the inbox the thread arrived at, or `reply.replyToAddress` for a thread whose inbox is not in `inboundAddresses` or that arrived at none. With no agent name the email capability's `fromName` is used instead; a name with no `{agent}`, such as `Acme Support`, is used for every reply."),
131
132
  deliverInApp: z.boolean().default(false).describe("Answer an `app` thread by storing the reply for the submitter to read in the app, instead of mailing it. **A choice, not a fallback.** Turning on Email Routing takes over the zone's MX, so a project already running mail on that domain cannot receive support replies without consequences everywhere else on it — and for a submitter who is a signed-in user sitting on the screen they wrote from, the answer is better placed there anyway. In-app delivery also happens automatically when there is no address to reply from and no email capability to send with, whatever this says; the setting is what makes it reachable for a project whose mail works fine. It never applies to an `email` thread: a mail thread's sender has no read-back, so a stored answer there is one nobody would ever see."),
132
133
  snippets: z.record(z.string(), SupportReplySnippet).default({}).describe("Your own canned replies, merged over the ones Pithy ships and winning on a key collision. These are *starting points a human picks and edits* in the dashboard, not automatic replies — nothing here is ever sent without somebody pressing send. Author them with `defineSupportReplies` so a malformed one fails where it is written.")
133
134
  }).describe("Reply settings — whether replies are allowed, where the answer goes, and what to offer as a starting point.");
@@ -176,7 +177,7 @@ function supportSemantic(search) {
176
177
  }
177
178
  /** The full support configuration. */
178
179
  /**
179
- * **Who of the app's own signed-in users works the inbox (#816).** Off until named.
180
+ * **Who of the app's own signed-in users works the inbox.** Off until named.
180
181
  *
181
182
  * The inbox holds every customer's correspondence, so a signed-in user reaches it only through a power the
182
183
  * adopter names in their own role catalog, held in the organization the request acts for — the same seam
@@ -217,10 +218,10 @@ const SupportConfig = z.object({
217
218
  * All three default `true`, so the ordinary project is unaffected by this predicate existing.
218
219
  *
219
220
  * Two callers, and they must agree: `capability.ts` declares the binding only when this is true, and
220
- * `pithy support provision` creates the bucket only when this is true. They disagreed before #440 —
221
- * the provisioner asked about `enabled` and `retainRaw` and never about submissions, so a project that
222
- * wanted uploads but no mail attachments got a binding pointing at a bucket nothing had created, and
223
- * every submitted file was dropped with a warning. One predicate is what makes that unrepresentable.
221
+ * `pithy support provision` creates the bucket only when this is true. Were they to ask different
222
+ * questions, a project that wanted uploads but no mail attachments would get a binding pointing at a
223
+ * bucket nothing had created, and every submitted file would be dropped with a warning. One predicate is
224
+ * what makes that unrepresentable.
224
225
  */
225
226
  function supportNeedsBucket(config) {
226
227
  return config.attachments.enabled || config.attachments.retainRaw || config.submission.attachments.enabled;
@@ -1 +1 @@
1
- {"version":3,"file":"handlers.d.ts","sourceRoot":"","sources":["../../src/http/handlers.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"handlers.d.ts","sourceRoot":"","sources":["../../src/http/handlers.ts"],"names":[],"mappings":"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"}
@@ -91,7 +91,8 @@ async function presentAttachments(deps, attachments) {
91
91
  size: attachment.size,
92
92
  sha256: attachment.sha256,
93
93
  inline: attachment.inline,
94
- url
94
+ url,
95
+ messageId: attachment.messageId
95
96
  };
96
97
  }));
97
98
  }
@@ -138,6 +138,7 @@ export declare const SupportAttachmentView: z.ZodObject<{
138
138
  sha256: z.ZodString;
139
139
  inline: z.ZodBoolean;
140
140
  url: z.ZodNullable<z.ZodString>;
141
+ messageId: z.ZodOptional<z.ZodString>;
141
142
  }, z.core.$strip>;
142
143
  export type SupportAttachmentView = z.output<typeof SupportAttachmentView>;
143
144
  /** One of the sender's purchases, flattened to what a support console renders. */
@@ -503,6 +504,7 @@ export declare const SupportThreadResponse: z.ZodObject<{
503
504
  sha256: z.ZodString;
504
505
  inline: z.ZodBoolean;
505
506
  url: z.ZodNullable<z.ZodString>;
507
+ messageId: z.ZodOptional<z.ZodString>;
506
508
  }, z.core.$strip>>;
507
509
  sender: z.ZodObject<{
508
510
  authenticated: z.ZodBoolean;
@@ -953,6 +955,7 @@ export declare const SupportThreadResponseAsRead: z.ZodObject<{
953
955
  sha256: z.ZodString;
954
956
  inline: z.ZodBoolean;
955
957
  url: z.ZodNullable<z.ZodString>;
958
+ messageId: z.ZodOptional<z.ZodString>;
956
959
  }, z.core.$strip>>;
957
960
  sender: z.ZodObject<{
958
961
  authenticated: z.ZodBoolean;
@@ -1111,6 +1114,7 @@ export declare const SupportMyMessageView: z.ZodObject<{
1111
1114
  sha256: z.ZodString;
1112
1115
  inline: z.ZodBoolean;
1113
1116
  url: z.ZodNullable<z.ZodString>;
1117
+ messageId: z.ZodOptional<z.ZodString>;
1114
1118
  }, z.core.$strip>>;
1115
1119
  sentAt: z.ZodISODateTime;
1116
1120
  }, z.core.$strip>;
@@ -1168,6 +1172,7 @@ export declare const SupportMyThreadResponse: z.ZodObject<{
1168
1172
  sha256: z.ZodString;
1169
1173
  inline: z.ZodBoolean;
1170
1174
  url: z.ZodNullable<z.ZodString>;
1175
+ messageId: z.ZodOptional<z.ZodString>;
1171
1176
  }, z.core.$strip>>;
1172
1177
  sentAt: z.ZodISODateTime;
1173
1178
  }, z.core.$strip>>;
@@ -1 +1 @@
1
- {"version":3,"file":"responses.d.ts","sourceRoot":"","sources":["../../src/http/responses.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"responses.d.ts","sourceRoot":"","sources":["../../src/http/responses.ts"],"names":[],"mappings":"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"}
@@ -104,7 +104,8 @@ const SupportAttachmentView = z.object({
104
104
  size: z.number().int().describe("The size in bytes."),
105
105
  sha256: z.string().describe("The content digest, so a client can tell two identical attachments apart from one."),
106
106
  inline: z.boolean().describe("Whether it was referenced inline in the HTML body rather than attached."),
107
- url: z.string().nullable().describe("A signed URL valid for a few minutes, or null when no credentials were available to sign one. The `storageKey` is never here: it is server-derived precisely so a client cannot name an object or guess the one beside it.")
107
+ url: z.string().nullable().describe("A signed URL valid for a few minutes, or null when no credentials were available to sign one. The `storageKey` is never here: it is server-derived precisely so a client cannot name an object or guess the one beside it."),
108
+ messageId: z.string().optional().describe("The id of the message it arrived on, so a client can show each file under the message that carried it. Absent from a Worker that predates it.")
108
109
  }).describe("One attachment as a client receives it — metadata and a signed URL, never the storage key.");
109
110
  /** One of the sender's purchases, flattened to what a support console renders. */
110
111
  const SenderPurchaseView = z.object({
@@ -218,7 +219,7 @@ const SupportAssignmentView = z.object({
218
219
  const SupportThreadResponse = z.object({
219
220
  thread: SupportThreadView.describe("The conversation."),
220
221
  messages: z.array(SupportMessageView).describe("Its messages, oldest first — a conversation reads downward."),
221
- attachments: z.array(SupportAttachmentView).describe("Its attachments, across every message."),
222
+ attachments: z.array(SupportAttachmentView).describe("Its attachments, across every message, each naming the message it arrived on in `messageId`."),
222
223
  sender: SenderContextView.describe("What the app already knows about the sender."),
223
224
  replies: z.array(SupportReplyView).describe("The canned replies, ordered for this thread's category."),
224
225
  assignments: z.array(SupportAssignmentView).optional().describe("Every change of the assignee, oldest first. Empty when nobody was ever assigned; absent from a Worker that predates assignment.")
@@ -1 +1 @@
1
- {"version":3,"file":"schemas.d.ts","sourceRoot":"","sources":["../../src/http/schemas.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAcxB;;;;;;;;;;;GAWG;AAEH,+BAA+B;AAC/B,eAAO,MAAM,aAAa;;iBAOsC,CAAC;AACjE,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,aAAa,CAAC,CAAC;AAyC1D;;;;;;GAMG;AACH,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;kBAiBmE,CAAC;AACjG,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAEhE,yBAAyB;AACzB,eAAO,MAAM,iBAAiB;;;;EAI3B,CAAC;AACJ,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAElE,wBAAwB;AACxB,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAuBqF,CAAC;AACrH,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAEpE,kCAAkC;AAClC,eAAO,MAAM,kBAAkB;;iBAQuB,CAAC;AACvD,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAEpE,mCAAmC;AACnC,eAAO,MAAM,aAAa;;;iBAOoE,CAAC;AAC/F,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,aAAa,CAAC,CAAC;AAE1D,yDAAyD;AACzD,eAAO,MAAM,yBAAyB,MAAM,CAAC;AAE7C,iGAAiG;AACjG,eAAO,MAAM,iBAAiB;;;;;;iBAeiC,CAAC;AAChE,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAElE,sBAAsB;AACtB,eAAO,MAAM,UAAU;;;iBAgB0B,CAAC;AAClD,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,UAAU,CAAC,CAAC;AAEpD,iCAAiC;AACjC,eAAO,MAAM,UAAU;;;iBAWmC,CAAC;AAC3D,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,UAAU,CAAC,CAAC;AAEpD;;;;;;;;GAQG;AACH,eAAO,MAAM,wBAAwB;;;;iBA4B8D,CAAC;AACpG,MAAM,MAAM,wBAAwB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,wBAAwB,CAAC,CAAC;AAEhF;;;;;;;;;;GAUG;AACH,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;iBAiCqF,CAAC;AACtH,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAEtE,uCAAuC;AACvC,eAAO,MAAM,cAAc;;;iBAiBxB,CAAC;AACJ,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAC;AAE5D,sCAAsC;AACtC,eAAO,MAAM,YAAY;;iBAM4B,CAAC;AACtD,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,YAAY,CAAC,CAAC"}
1
+ {"version":3,"file":"schemas.d.ts","sourceRoot":"","sources":["../../src/http/schemas.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAcxB;;;;;;;;;;;GAWG;AAEH,+BAA+B;AAC/B,eAAO,MAAM,aAAa;;iBAOsC,CAAC;AACjE,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,aAAa,CAAC,CAAC;AAyC1D;;;;;;GAMG;AACH,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;kBAiBmE,CAAC;AACjG,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAEhE,yBAAyB;AACzB,eAAO,MAAM,iBAAiB;;;;EAI3B,CAAC;AACJ,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAElE,wBAAwB;AACxB,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAuBqF,CAAC;AACrH,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAEpE,kCAAkC;AAClC,eAAO,MAAM,kBAAkB;;iBAQuB,CAAC;AACvD,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAEpE,mCAAmC;AACnC,eAAO,MAAM,aAAa;;;iBAOoE,CAAC;AAC/F,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,aAAa,CAAC,CAAC;AAE1D,yDAAyD;AACzD,eAAO,MAAM,yBAAyB,MAAM,CAAC;AAE7C,iGAAiG;AACjG,eAAO,MAAM,iBAAiB;;;;;;iBAeiC,CAAC;AAChE,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAElE,sBAAsB;AACtB,eAAO,MAAM,UAAU;;;iBAmB0B,CAAC;AAClD,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,UAAU,CAAC,CAAC;AAEpD,iCAAiC;AACjC,eAAO,MAAM,UAAU;;;iBAWmC,CAAC;AAC3D,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,UAAU,CAAC,CAAC;AAEpD;;;;;;;;GAQG;AACH,eAAO,MAAM,wBAAwB;;;;iBA4B8D,CAAC;AACpG,MAAM,MAAM,wBAAwB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,wBAAwB,CAAC,CAAC;AAEhF;;;;;;;;;;GAUG;AACH,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;iBAiCqF,CAAC;AACtH,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAEtE,uCAAuC;AACvC,eAAO,MAAM,cAAc;;;iBAiBxB,CAAC;AACJ,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAC;AAE5D,sCAAsC;AACtC,eAAO,MAAM,YAAY;;iBAM4B,CAAC;AACtD,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,YAAY,CAAC,CAAC"}
@@ -79,7 +79,7 @@ const AssignThreadInput = z.object({
79
79
  /** The reply body. */
80
80
  const ReplyInput = z.object({
81
81
  body: z.string().min(1).max(5e4).describe("The reply text, as a human wrote and edited it. Rendered HTML-escaped into the adopter's email shell — it is prose, never markup."),
82
- agentName: z.string().min(1).max(80).optional().describe("Who is answering, signed at the bottom. Omitted rather than guessed.")
82
+ agentName: z.string().min(1).max(80).regex(/^[^@<>"]*$/, "A name may not contain @, <, > or a double quote.").optional().describe("Who is answering, signed at the bottom and written into the reply's From line. Omitted rather than guessed. May not contain `@`, `<`, `>` or `\"`, so the display name cannot pass for an address.")
83
83
  }).describe("An answer to send to the customer.");
84
84
  /** The per-viewer flags body. */
85
85
  const FlagsInput = z.object({
@@ -15,32 +15,29 @@ import { type DeprovisionTarget, type ManagedEnvironment } from "@pithy-sh/secre
15
15
  * orchestration (order, idempotency, per-env fan-out) is unit-tested without touching Cloudflare.
16
16
  * Every step is idempotent; re-running is a no-op.
17
17
  *
18
- * ## The routing rule is opt-in, and that is a safety decision
18
+ * ## The routing rule never enables Email Routing
19
19
  *
20
- * `ensureRoutingRule` returns `skipped: true` when no routing config is supplied, exactly as
21
- * `@pithy-sh/email`'s does — because **enabling Email Routing on a zone points its MX at Cloudflare.**
22
- * Creating a rule on the wrong zone would move an adopter's real inbound mail off their existing
23
- * provider, which is not a mistake a provisioning command gets to make on their behalf. So the zone,
24
- * the address, and the target worker are all explicit flags, and a project that has not decided yet
25
- * provisions everything else and adds the rule later.
20
+ * **Enabling Email Routing for a domain points its MX at Cloudflare**, so it stays the adopter's act. The CLI's
21
+ * routing step finds the zone that holds each environment's inbound address, refuses a domain Email Routing is
22
+ * not enabled for, and only then creates or updates the exact-address rule that sends it to that environment's
23
+ * app worker. It never enables routing and never touches DNS.
26
24
  *
27
- * The rule name is `<project>-global-support-inbound`, deliberately distinct from `@pithy-sh/email`'s
28
- * `<project>-global-email-bounce`. Idempotency in `ensureWorkerRoute` keys on the rule *name*, so
29
- * sharing one would make whichever capability provisioned second silently believe its rule already
30
- * existed — and the project segment is what stops two Pithy projects on one zone doing the same to
31
- * each other, with the loser's customer mail delivered to the winner's Worker.
25
+ * A rule is per environment, named `<project>-<env>-support-inbound`: each environment's address goes to its own
26
+ * app worker. The project-global `<project>-global-support-inbound` is what the explicit `--routing-zone`,
27
+ * `--inbound-address` and `--app-worker` override creates, distinct from `@pithy-sh/email`'s
28
+ * `<project>-global-email-bounce`, because that path keys idempotency on the rule's name.
32
29
  */
33
30
  /**
34
- * The name of the Email Routing rule this capability creates, for one project. Distinct from the
35
- * bounce handler's, and `global` in the environment slot because there is one rule per zone: the
36
- * environments are separated by which app Worker the rule is pointed at, not by the rule.
31
+ * The name of an Email Routing rule this capability creates, for one project: `<project>-<env>-support-inbound`
32
+ * for one environment's address, or `<project>-global-support-inbound` for the override that routes one address
33
+ * for the whole project. Distinct from the bounce handler's either way.
37
34
  *
38
35
  * **Still on the generic composer**, and deliberately: an Email Routing rule is not a namespace
39
36
  * `@pithy-sh/core/src/naming/limits` carries a verified Cloudflare cap for, and the facade exists so a
40
37
  * kind of thing brings its own number rather than borrowing one. It takes the conservative default
41
38
  * until that namespace lands — the same call `@pithy-sh/email`'s bounce rule makes.
42
39
  */
43
- export declare function supportRoutingRuleName(project: string): string;
40
+ export declare function supportRoutingRuleName(project: string, env?: ManagedEnvironment): string;
44
41
  /**
45
42
  * The deployed Worker name for a project's environment — also its resolved config basename. Composed
46
43
  * through core's naming facade under the **`worker`** namespace, so it is measured against a Worker
@@ -121,8 +118,9 @@ export interface SupportProvisioner {
121
118
  backfilled: boolean;
122
119
  }>;
123
120
  /**
124
- * Ensure the inbound Email Routing rule that delivers the support address to the app worker.
125
- * Idempotent, keyed on the rule name. Returns `skipped: true` when no routing config was supplied.
121
+ * Ensure the inbound Email Routing rules that deliver the support addresses to the app worker: each provisioned
122
+ * environment's own, or the one the override names. Idempotent. Returns `skipped: true` when there was nothing
123
+ * to route.
126
124
  */
127
125
  ensureRoutingRule(): Promise<{
128
126
  created: boolean;
@@ -192,8 +190,9 @@ export interface SupportDeprovisioner {
192
190
  /** Delete the env's classification worker. Idempotent. */
193
191
  deleteWorker(env: ManagedEnvironment): Promise<void>;
194
192
  /**
195
- * Remove the inbound routing rule, so mail stops being delivered here. Idempotent. Called only when the teardown
196
- * was asked to remove it (`removeRouting`).
193
+ * Remove the project-global inbound routing rule the override created, so mail stops being delivered here.
194
+ * Idempotent. Called only when the teardown was asked to remove it (`removeRouting`). An environment's own rule
195
+ * is the CLI's to remove, with that environment.
197
196
  */
198
197
  removeRoutingRule(): Promise<{
199
198
  removed: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"provisionSupport.d.ts","sourceRoot":"","sources":["../../src/provision/provisionSupport.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"provisionSupport.d.ts","sourceRoot":"","sources":["../../src/provision/provisionSupport.ts"],"names":[],"mappings":"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"}
@@ -20,35 +20,32 @@ import { assertSharedLeavesLast, deprovisionTarget, managedEnvironments } from "
20
20
  * orchestration (order, idempotency, per-env fan-out) is unit-tested without touching Cloudflare.
21
21
  * Every step is idempotent; re-running is a no-op.
22
22
  *
23
- * ## The routing rule is opt-in, and that is a safety decision
23
+ * ## The routing rule never enables Email Routing
24
24
  *
25
- * `ensureRoutingRule` returns `skipped: true` when no routing config is supplied, exactly as
26
- * `@pithy-sh/email`'s does — because **enabling Email Routing on a zone points its MX at Cloudflare.**
27
- * Creating a rule on the wrong zone would move an adopter's real inbound mail off their existing
28
- * provider, which is not a mistake a provisioning command gets to make on their behalf. So the zone,
29
- * the address, and the target worker are all explicit flags, and a project that has not decided yet
30
- * provisions everything else and adds the rule later.
25
+ * **Enabling Email Routing for a domain points its MX at Cloudflare**, so it stays the adopter's act. The CLI's
26
+ * routing step finds the zone that holds each environment's inbound address, refuses a domain Email Routing is
27
+ * not enabled for, and only then creates or updates the exact-address rule that sends it to that environment's
28
+ * app worker. It never enables routing and never touches DNS.
31
29
  *
32
- * The rule name is `<project>-global-support-inbound`, deliberately distinct from `@pithy-sh/email`'s
33
- * `<project>-global-email-bounce`. Idempotency in `ensureWorkerRoute` keys on the rule *name*, so
34
- * sharing one would make whichever capability provisioned second silently believe its rule already
35
- * existed — and the project segment is what stops two Pithy projects on one zone doing the same to
36
- * each other, with the loser's customer mail delivered to the winner's Worker.
30
+ * A rule is per environment, named `<project>-<env>-support-inbound`: each environment's address goes to its own
31
+ * app worker. The project-global `<project>-global-support-inbound` is what the explicit `--routing-zone`,
32
+ * `--inbound-address` and `--app-worker` override creates, distinct from `@pithy-sh/email`'s
33
+ * `<project>-global-email-bounce`, because that path keys idempotency on the rule's name.
37
34
  */
38
35
  /**
39
- * The name of the Email Routing rule this capability creates, for one project. Distinct from the
40
- * bounce handler's, and `global` in the environment slot because there is one rule per zone: the
41
- * environments are separated by which app Worker the rule is pointed at, not by the rule.
36
+ * The name of an Email Routing rule this capability creates, for one project: `<project>-<env>-support-inbound`
37
+ * for one environment's address, or `<project>-global-support-inbound` for the override that routes one address
38
+ * for the whole project. Distinct from the bounce handler's either way.
42
39
  *
43
40
  * **Still on the generic composer**, and deliberately: an Email Routing rule is not a namespace
44
41
  * `@pithy-sh/core/src/naming/limits` carries a verified Cloudflare cap for, and the facade exists so a
45
42
  * kind of thing brings its own number rather than borrowing one. It takes the conservative default
46
43
  * until that namespace lands — the same call `@pithy-sh/email`'s bounce rule makes.
47
44
  */
48
- function supportRoutingRuleName(project) {
45
+ function supportRoutingRuleName(project, env) {
49
46
  return resourceName({
50
47
  project,
51
- env: GLOBAL_SCOPE,
48
+ env: env ?? GLOBAL_SCOPE,
52
49
  thing: `${SUPPORT_CAPABILITY}-inbound`
53
50
  });
54
51
  }
@@ -0,0 +1,7 @@
1
+ // SPDX-FileCopyrightText: 2026 Pithy
2
+ // SPDX-License-Identifier: MIT
3
+ import type { CapabilitySettings } from "@pithy-sh/core/src/capability/settings";
4
+ import type { SupportConfig } from "../config/config";
5
+ /** Support's sending check, built from one composition's resolved config. */
6
+ export declare function supportSendingSettings(config: SupportConfig): CapabilitySettings;
7
+ //# sourceMappingURL=sendingCheck.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sendingCheck.d.ts","sourceRoot":"","sources":["../../src/provision/sendingCheck.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,kBAAkB,EAAmB,MAAM,wCAAwC,CAAC;AAElG,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAoBtD,6EAA6E;AAC7E,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,aAAa,GAAG,kBAAkB,CA0ChF"}
@@ -0,0 +1,63 @@
1
+ // SPDX-FileCopyrightText: 2026 Pithy
2
+ // SPDX-License-Identifier: MIT
3
+ import { InternalError } from "@pithy-sh/core/src/error/pithyError";
4
+ //#region src/provision/sendingCheck.ts
5
+ /**
6
+ * Whether each address a reply is sent from can send, as `pithy doctor` asks it.
7
+ *
8
+ * A mailed reply is sent from the inbox the thread arrived at, so an inbox on a domain Email Service cannot send
9
+ * from receives mail and cannot answer it: every reply fails at send with the domain named. Asked once per domain,
10
+ * only while replies are on. Nothing here writes.
11
+ */
12
+ /** The domain half of an address, lowercased, or `null` where it carries none. */
13
+ function domainOf(address) {
14
+ const at = address.lastIndexOf("@");
15
+ if (at < 0 || at === address.length - 1) return null;
16
+ return address.slice(at + 1).trim().toLowerCase();
17
+ }
18
+ /** Support's sending check, built from one composition's resolved config. */
19
+ function supportSendingSettings(config) {
20
+ return {
21
+ local: () => [],
22
+ account: async (context) => {
23
+ if (!config.reply.enabled) return [];
24
+ const senders = [...config.inboundAddresses.map((address) => ({
25
+ address,
26
+ setting: "inboundAddresses"
27
+ })), ...config.reply.replyToAddress ? [{
28
+ address: config.reply.replyToAddress,
29
+ setting: "reply.replyToAddress"
30
+ }] : []];
31
+ const byDomain = /* @__PURE__ */ new Map();
32
+ for (const { address, setting } of senders) {
33
+ const domain = domainOf(address);
34
+ if (domain === null) continue;
35
+ const entry = byDomain.get(domain) ?? {
36
+ setting,
37
+ addresses: []
38
+ };
39
+ if (!entry.addresses.includes(address)) entry.addresses.push(address);
40
+ byDomain.set(domain, entry);
41
+ }
42
+ if (byDomain.size === 0) return [];
43
+ const ask = context.account.sendingDomain;
44
+ if (!ask) throw new InternalError({
45
+ message: "This doctor cannot ask whether a domain can send.",
46
+ detail: "SettingsAccountReader.sendingDomain is absent."
47
+ });
48
+ const findings = [];
49
+ for (const [domain, { setting, addresses }] of byDomain) {
50
+ if (await ask.call(context.account, domain)) continue;
51
+ findings.push({
52
+ setting,
53
+ environment: null,
54
+ problem: `${domain} cannot send on Email Service, so a reply from ${addresses.join(", ")} fails.`,
55
+ action: `Onboard ${domain} for sending in the Cloudflare dashboard under Email Service, then rerun doctor.`
56
+ });
57
+ }
58
+ return findings;
59
+ }
60
+ };
61
+ }
62
+ //#endregion
63
+ export { supportSendingSettings };
@@ -0,0 +1,20 @@
1
+ // SPDX-FileCopyrightText: 2026 Pithy
2
+ // SPDX-License-Identifier: MIT
3
+ import type { SupportConfig } from "../config/config";
4
+ /** The placeholder `reply.fromName` writes the answering agent's name into. */
5
+ export declare const AGENT_PLACEHOLDER = "{agent}";
6
+ /**
7
+ * The display name a reply is sent under: `reply.fromName` with the agent's name written in.
8
+ *
9
+ * A pattern with no placeholder is a fixed name, used whoever answered. A pattern with one is undefined when no
10
+ * agent name is given, so the email capability's own `fromName` is used. Line breaks and control characters are
11
+ * folded to spaces, because the result is a header value.
12
+ */
13
+ export declare function replyFromName(pattern: string, agentName: string | undefined): string | undefined;
14
+ /**
15
+ * Every address support may send a reply as: its `inboundAddresses` and `reply.replyToAddress`, normalized and
16
+ * once each. `compose` binds the email capability's `enqueueAs` to exactly these, so a reply cannot be sent as
17
+ * an address this inbox does not claim.
18
+ */
19
+ export declare function claimedSenders(config: SupportConfig): string[];
20
+ //# sourceMappingURL=fromName.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fromName.d.ts","sourceRoot":"","sources":["../../src/reply/fromName.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAEtD,+EAA+E;AAC/E,eAAO,MAAM,iBAAiB,YAAY,CAAC;AAE3C;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAWhG;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,aAAa,GAAG,MAAM,EAAE,CAG9D"}
@@ -0,0 +1,29 @@
1
+ // SPDX-FileCopyrightText: 2026 Pithy
2
+ // SPDX-License-Identifier: MIT
3
+ //#region src/reply/fromName.ts
4
+ /** The placeholder `reply.fromName` writes the answering agent's name into. */
5
+ const AGENT_PLACEHOLDER = "{agent}";
6
+ /**
7
+ * The display name a reply is sent under: `reply.fromName` with the agent's name written in.
8
+ *
9
+ * A pattern with no placeholder is a fixed name, used whoever answered. A pattern with one is undefined when no
10
+ * agent name is given, so the email capability's own `fromName` is used. Line breaks and control characters are
11
+ * folded to spaces, because the result is a header value.
12
+ */
13
+ function replyFromName(pattern, agentName) {
14
+ const agent = agentName?.trim() ?? "";
15
+ if (pattern.includes("{agent}") && !agent) return void 0;
16
+ const name = pattern.split(AGENT_PLACEHOLDER).join(agent).replace(/[\u0000-\u001f\u007f]+/g, " ").replace(/ {2,}/g, " ").trim();
17
+ return name === "" ? void 0 : name;
18
+ }
19
+ /**
20
+ * Every address support may send a reply as: its `inboundAddresses` and `reply.replyToAddress`, normalized and
21
+ * once each. `compose` binds the email capability's `enqueueAs` to exactly these, so a reply cannot be sent as
22
+ * an address this inbox does not claim.
23
+ */
24
+ function claimedSenders(config) {
25
+ const addresses = [...config.inboundAddresses, ...config.reply.replyToAddress ? [config.reply.replyToAddress] : []];
26
+ return [...new Set(addresses)];
27
+ }
28
+ //#endregion
29
+ export { AGENT_PLACEHOLDER, claimedSenders, replyFromName };
@@ -71,6 +71,15 @@ export interface ReplyDeps {
71
71
  template: string;
72
72
  payload: unknown;
73
73
  replyTo?: string;
74
+ /**
75
+ * Who the reply is sent as: the thread's inbox, under `reply.fromName` with the agent's name written in.
76
+ * `name` is absent when no agent name was given, and the email capability's `fromName` is used. The seam
77
+ * `compose` binds refuses an address support does not claim.
78
+ */
79
+ from?: {
80
+ address: string;
81
+ name?: string;
82
+ };
74
83
  /** The language to write the shell in — the reporter's, taken off their submission context. */
75
84
  locale?: string;
76
85
  inReplyTo?: string;
@@ -93,7 +102,7 @@ export interface ReplyInput {
93
102
  threadId: string;
94
103
  /** The reply text, as a human wrote and edited it. */
95
104
  body: string;
96
- /** Who is answering, signed at the bottom. Optional. */
105
+ /** Who is answering: signed at the bottom, and written into the From line through `reply.fromName`. Optional. */
97
106
  agentName?: string;
98
107
  /** The verified control-plane subject sending it — the audit actor. */
99
108
  viewer: string;