@agentcomms/resend 0.18.2 → 0.20.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -29,6 +29,14 @@ approves, whatever the policy. The approval id is the request's `Idempotency-Key
29
29
  send whose outcome is unknown (`SEND_OUTCOME_UNKNOWN`) is never repeated, only checked, and a scheduled one is
30
30
  "accepted", never "sent", until Resend's own last event for it says so.
31
31
 
32
+ **An agent's email says so in its From.** Prepare labels it `"Acme (agent)" <hello@acme.test>`: the name the From
33
+ gave, or, for a bare address, the label name the person set in the core (its CLI's `label name`, or `comms_label`), then their word —
34
+ `agent` unless they chose another ([design](../../docs/superpowers/specs/2026-10-15-agent-label-design.md), §6). With
35
+ neither name, or a label over Resend's 100 characters, prepare refuses. `--as me` (`as: "me"` on
36
+ `resend_send_prepare`) sends the From exactly as given, for when the person said so for that email; their label rules
37
+ decide otherwise, and with none an email is labelled. The preview's first line says which, and the approval binds the
38
+ whole From.
39
+
32
40
  **The key is typed by a person, at a terminal.** `agent-resend account add` reads it from a hidden prompt, or from
33
41
  `RESEND_API_KEY` in that terminal, and stores it in the system keychain. No MCP tool accepts a key: a key typed into
34
42
  a chat stays in the transcript.
package/dist/cli.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { A as removeAccountChange, At as updateGateAtTerminal, C as inspectKey, Ct as runUpdateCheckChild, D as policyChange, Dt as terminalUpdateHooks, E as policyApprovalRefusal, Ft as writeResult, G as SEND_LOOKUP, H as CommsError, Ht as VERSION, J as approvalsOf, K as UPDATE_CHECK_CHILD_COMMAND, Lt as RESEND_CALLER, M as showAccount, Nt as waitForApproval, O as policyReport, P as ResendContext, Pt as wholeNumber, R as checkNewName, S as addAccountChange, St as runCommand, T as modeOf, Tt as serverPruneChange, U as EXIT_CODES, V as CHANNEL_SERVERS, W as PATH_OPTIONS, X as approveRefusedHint, Y as approveChangeAtTerminal, Z as canPrompt, _ as showSentEmail, _t as refuseUnclaimedApproval, a as revokeSendApproval, at as exemptFromUpdateGate, bt as renderPrune, c as downloadReceived, ct as handoffSentence, d as listReceived, dt as kindOf, et as cliHandoffs, f as listScheduled, g as showReceived, gt as pathOverridesFromCliOptions, ht as paint, i as prepareSend, it as escapeForDisplay, j as sendPolicyOf, k as policyWanted, kt as truncateDisplay, l as getMetrics, lt as handoffSentenceToFill, m as listSuppressions, mt as openCore, n as executeSend, nt as commandPathOf, o as sendStatus, p as listSentEmails, q as agentMarker, r as finishSendApproval, rt as describeFenceReport, s as cancelScheduledChange, st as gatedChangeAtTerminal, t as beginSendApproval, tt as colorEnabled, u as listDomains, ut as installExitStatus, vt as renderApprovalWait, w as listAccounts, wt as serverInstallChange, x as runDoctor, xt as resolvePaths, yt as renderInstall } from "./send-7cKVm9mA.mjs";
2
+ import { $ as colorEnabled, A as removeAccountChange, Bt as VERSION, C as inspectKey, Ct as serverPruneChange, D as policyChange, Dt as truncateDisplay, E as policyApprovalRefusal, Ft as RESEND_CALLER, G as UPDATE_CHECK_CHILD_COMMAND, H as CommsError, J as approveRefusedHint, K as agentMarker, M as showAccount, Mt as wholeNumber, Nt as writeResult, O as policyReport, Ot as updateNoticeAtTerminal, P as ResendContext, Q as cliHandoffs, R as checkNewName, S as addAccountChange, St as serverInstallChange, T as modeOf, Tt as terminalUpdateHooks, U as EXIT_CODES, V as CHANNEL_SERVERS, W as PATH_OPTIONS, Y as canPrompt, _ as showSentEmail, _t as renderInstall, a as revokeSendApproval, at as gatedChangeAtTerminal, bt as runCommand, c as downloadReceived, ct as installExitStatus, d as listReceived, et as commandPathOf, f as listScheduled, ft as openCore, g as showReceived, gt as renderApprovalWait, ht as refuseUnclaimedApproval, i as prepareSend, j as sendPolicyOf, jt as waitForApproval, k as policyWanted, l as getMetrics, lt as kindOf, m as listSuppressions, mt as pathOverridesFromCliOptions, n as executeSend, nt as escapeForDisplay, o as sendStatus, ot as handoffSentence, p as listSentEmails, pt as paint, q as approveChangeAtTerminal, r as finishSendApproval, rt as exemptFromUpdateNotice, s as cancelScheduledChange, st as handoffSentenceToFill, t as beginSendApproval, tt as describeFenceReport, u as listDomains, vt as renderPrune, w as listAccounts, x as runDoctor, xt as runUpdateCheckChild, yt as resolvePaths } from "./send-CE6wM0-w.mjs";
3
3
  import path from "node:path";
4
4
  import { createInterface } from "node:readline/promises";
5
5
  import { stripVTControlCharacters } from "node:util";
@@ -3182,8 +3182,7 @@ Getting started — run these with this CLI:
3182
3182
  received list --account acme/resend
3183
3183
  mcp install --client claude-code register the server with an agent, once a person approves it
3184
3184
 
3185
- Exit codes: 0 ok · 1 unexpected · 10 a send or a change was refused or needs approval · 11 an update
3186
- is out: update first, or put it off (the stop names both commands) · 64 usage ·
3185
+ Exit codes: 0 ok · 1 unexpected · 10 a send or a change was refused or needs approval · 64 usage ·
3187
3186
  65 bad data · 66 not found · 69 provider or secret store unavailable · 75 temporary (retry later) ·
3188
3187
  77 key or permission needed · 78 configuration problem.`).exitOverride();
3189
3188
  for (const { flag } of PATH_OPTIONS) program.addOption(new Option(`${flag} <dir>`, "pin this suite directory for this run").argParser((value) => {
@@ -3225,40 +3224,23 @@ is out: update first, or put it off (the stop names both commands) · 64 usage
3225
3224
  color: globals().color,
3226
3225
  platform
3227
3226
  });
3228
- let gated = null;
3229
3227
  program.hook("preAction", async (_program, command) => {
3230
3228
  const path = commandPathOf(command);
3231
- if (exemptFromUpdateGate(path, ["update-check-child"])) return;
3229
+ if (exemptFromUpdateNotice(path, ["update-check-child"])) return;
3232
3230
  const core = coreForInvocation();
3233
- let ended = null;
3234
- const code = await runCommand(output(), async () => {
3235
- ended = await updateGateAtTerminal({
3236
- core,
3237
- env,
3238
- binary: "agent-resend",
3239
- channel: "resend",
3240
- running: VERSION,
3241
- output: output(),
3242
- noInput: false,
3243
- streams,
3244
- approvals: approvalsOf(command),
3245
- approvalClaim: path.join(" ") === "send status" ? SEND_LOOKUP : path.join(" ") === "send wait" ? { lookup: true } : void 0,
3246
- ...terminalUpdateHooks(core, env, {
3247
- channel: "resend",
3248
- output: output(),
3249
- streams
3250
- })
3251
- });
3252
- }, streams);
3253
- gated = code !== 0 ? code : ended;
3231
+ await updateNoticeAtTerminal({
3232
+ core,
3233
+ env,
3234
+ channel: "resend",
3235
+ running: VERSION,
3236
+ output: output(),
3237
+ streams,
3238
+ ...terminalUpdateHooks(core, env)
3239
+ });
3254
3240
  });
3255
3241
  const act = (body) => async (...args) => {
3256
3242
  ran = true;
3257
3243
  softExit = null;
3258
- if (gated !== null) {
3259
- exitCode = gated;
3260
- return;
3261
- }
3262
3244
  const core = coreForInvocation();
3263
3245
  const context = new ResendContext({
3264
3246
  ...deps,
@@ -3407,7 +3389,7 @@ is out: update first, or put it off (the stop names both commands) · 64 usage
3407
3389
  writeResult(result, output(), (data) => renderRead(data, options.color), streams);
3408
3390
  }));
3409
3391
  const send = program.command("send").description("prepare an email, and send it once a person has approved it");
3410
- accountOption(send.command("prepare")).description("build an email and show exactly what would go, to whom. Sends nothing").requiredOption("--from <address>", "the sender, at a verified domain: `Name <you@example.com>` or a bare address").requiredOption("--to <address>", "a recipient; repeat for more", collect, []).option("--cc <address>", "a copy recipient; repeat for more", collect, []).option("--bcc <address>", "a blind recipient; repeat for more — the preview lists every one", collect, []).requiredOption("--subject <subject>", "the subject").option("--text <text>", "the plain-text body").option("--html <html>", "an HTML body whose visible text is the text body; no images, forms or hidden parts").option("--attach <path>", "a file to attach, from an allowed folder; repeat for more", collect, []).option("--reply-to <address>", "where replies go; repeat for more", collect, []).option("--in-reply-to <messageId>", "the Message-ID this replies to, to keep the thread").option("--references <messageId>", "an earlier Message-ID in the thread; repeat for more", collect, []).option("--scheduled-at <time>", "send later: an ISO 8601 time with a zone, at most 30 days ahead").action(act(async (context, _options, flags) => {
3392
+ accountOption(send.command("prepare")).description("build an email and show exactly what would go, to whom. Sends nothing").requiredOption("--from <address>", "the sender, at a verified domain: `Name <you@example.com>` or a bare address").requiredOption("--to <address>", "a recipient; repeat for more", collect, []).option("--cc <address>", "a copy recipient; repeat for more", collect, []).option("--bcc <address>", "a blind recipient; repeat for more — the preview lists every one", collect, []).requiredOption("--subject <subject>", "the subject").option("--text <text>", "the plain-text body").option("--html <html>", "an HTML body whose visible text is the text body; no images, forms or hidden parts").option("--attach <path>", "a file to attach, from an allowed folder; repeat for more", collect, []).option("--reply-to <address>", "where replies go; repeat for more", collect, []).option("--in-reply-to <messageId>", "the Message-ID this replies to, to keep the thread").option("--references <messageId>", "an earlier Message-ID in the thread; repeat for more", collect, []).option("--scheduled-at <time>", "send later: an ISO 8601 time with a zone, at most 30 days ahead").option("--as <who>", "who it appears to come from: agent (From labelled) or me (From as given, only when the person said so)").action(act(async (context, _options, flags) => {
3411
3393
  const prepared = await prepareSend(context, String(flags.account), {
3412
3394
  from: String(flags.from),
3413
3395
  to: flags.to,
@@ -3420,7 +3402,8 @@ is out: update first, or put it off (the stop names both commands) · 64 usage
3420
3402
  replyTo: flags.replyTo,
3421
3403
  inReplyTo: flags.inReplyTo === void 0 ? void 0 : String(flags.inReplyTo),
3422
3404
  references: flags.references,
3423
- scheduledAt: flags.scheduledAt === void 0 ? void 0 : String(flags.scheduledAt)
3405
+ scheduledAt: flags.scheduledAt === void 0 ? void 0 : String(flags.scheduledAt),
3406
+ as: flags.as === void 0 ? void 0 : String(flags.as)
3424
3407
  });
3425
3408
  writeResult(prepared, output(), renderPrepared, streams);
3426
3409
  }));
@@ -3505,7 +3488,7 @@ is out: update first, or put it off (the stop names both commands) · 64 usage
3505
3488
  }));
3506
3489
  const mcp = program.command("mcp").description("run the MCP server on stdio, for a coding agent to connect to").option("--account <name>", "pin the server to one account; every tool then acts on it and no other").action(async (flags) => {
3507
3490
  ran = true;
3508
- const startResendStdioServer = deps.startMcp ?? (await import("./stdio-entry-CskP8Urx.mjs")).startResendStdioServer;
3491
+ const startResendStdioServer = deps.startMcp ?? (await import("./stdio-entry-BlerMgOC.mjs")).startResendStdioServer;
3509
3492
  const core = coreForInvocation();
3510
3493
  await startResendStdioServer({
3511
3494
  ...deps,
package/dist/index.d.mts CHANGED
@@ -4322,7 +4322,8 @@ declare namespace external_d_exports {
4322
4322
  export { $brand, $input, $output, BRAND, CompileOptions, GlobalMeta, INVALID, Infer$1 as Infer, IssueData, JSONType, NEVER, $RefinementCtx as RefinementCtx, SafeExtendShape, Schema, TimePrecision, TypeOf, ZodAny, ZodArray, ZodBase64, ZodBase64URL, ZodBigInt, ZodBigIntFormat, ZodBoolean, ZodCIDRv4, ZodCIDRv6, ZodCUID, ZodCUID2, ZodCatch, ZodCodec, ZodCoercedBigInt, ZodCoercedBoolean, ZodCoercedDate, ZodCoercedNumber, ZodCoercedString, ZodCompileAsyncError, ZodCompileUnsupportedError, ZodCreditCard, ZodCustom, ZodCustomStringFormat, ZodDate, ZodDefault, ZodDiscriminatedUnion, ZodE164, ZodEmail, ZodEmoji, ZodEnum, ZodError, ZodErrorMap, ZodExactOptional, ZodFile, ZodFirstPartySchemaTypes, ZodFirstPartyTypeKind, ZodFlattenedError, ZodFloat32, ZodFloat64, ZodFormattedError, ZodFunction, ZodGUID, ZodIBAN, ZodIPv4, ZodIPv6, ZodISODate, ZodISODateTime, ZodISODuration, ZodISOTime, ZodInstanceOf, ZodInt, ZodInt32, ZodInt64, ZodIntersection, ZodIssue, ZodIssueCode, ZodJSONSchema, ZodJSONSchemaInternals, ZodJWT, ZodKSUID, ZodLazy, ZodLiteral, ZodMAC, ZodMap, ZodNaN, ZodNanoID, ZodNever, ZodNonOptional, ZodNull, ZodNullable, ZodNumber, ZodNumberFormat, ZodObject, ZodOptional, ZodPipe, ZodPrefault, ZodPreprocess, ZodPromise, ZodRawShape$1 as ZodRawShape, ZodReadonly, ZodRealError, ZodRecord, ZodSafeParseError, ZodSafeParseResult, ZodSafeParseSuccess, ZodSchema, ZodSet, ZodStandardSchemaWithJSON, ZodString, ZodStringFormat, ZodSuccess, ZodSymbol, ZodTemplateLiteral, ZodTransform, ZodTuple, ZodType, ZodTypeAny, ZodUInt32, ZodUInt64, ZodULID, ZodURL, ZodUUID, ZodUndefined, ZodUnion, ZodUnknown, ZodVoid, ZodXID, ZodXor, _ZodBigInt, _ZodBoolean, _ZodDate, _ZodNumber, _ZodString, _ZodType, _default, _function, any, array, base64, base64url, bigint$1 as bigint, boolean$1 as boolean, _catch as catch, check, cidrv4, cidrv6, clone, codec, coerce_d_exports as coerce, compile, config, index_d_exports$1 as core, creditCard, cuid, cuid2, currencyCode, custom, date$2 as date, decode, decodeAsync, deepPartial, describe, discriminatedUnion, e164, email, emoji, encode, encodeAsync, _endsWith as endsWith, _enum as enum, exactOptional, file, flattenError, float32, float64, formatError, fromJSONSchema, _function as function, getDiscriminatedOption, getErrorMap, globalRegistry, _gt as gt, _gte as gte, guid, hash, hex, hostname, httpUrl, iban, _includes as includes, output$1 as infer, inferFlattenedErrors, inferFormattedError, input, _instanceof as instanceof, int, int32, int64, intersection, invertCodec, ipv4, ipv6, iso_d_exports as iso, json, jwt, keyof, ksuid, lazy, _length as length, literal, index_d_exports$2 as locales, looseObject, looseRecord, _lowercase as lowercase, _lt as lt, _lte as lte, mac, map, _maxLength as maxLength, _maxSize as maxSize, memoizer, meta, _mime as mime, _minLength as minLength, _minSize as minSize, _multipleOf as multipleOf, nan, nanoid, nativeEnum, _negative as negative, never, _nonnegative as nonnegative, nonoptional, _nonpositive as nonpositive, _normalize as normalize, _null as null, nullable, nullish, number$1 as number, object, optional, output, _overwrite as overwrite, parse, parseAsync, partialRecord, pipe, _positive as positive, prefault, preprocess, prettifyError, promise, _properties as properties, _property as property, readonly, record, refine, _regex as regex, regexes_d_exports as regexes, registry, safeDecode, safeDecodeAsync, safeEncode, safeEncodeAsync, safeParse, safeParseAsync, set, setErrorMap, _size as size, _slugify as slugify, _startsWith as startsWith, strictObject, string$1 as string, stringFormat, stringbool, success, superRefine, symbol, templateLiteral, toJSONSchema, _toLowerCase as toLowerCase, _toUpperCase as toUpperCase, toZod, transform, treeifyError, _trim as trim, tuple, uint32, uint64, ulid, _undefined as undefined, union, unknown, _uppercase as uppercase, url, util_d_exports as util, uuid, uuidv4, uuidv6, uuidv7, validate, validateAsync, _void as void, withParser, xid, xor };
4323
4323
  }
4324
4324
  //#endregion
4325
- //#region ../core/dist/change-flow-j65bYTxL.d.mts
4325
+ //#region ../core/dist/launcher-VgihcM7Q.d.mts
4326
+ //#endregion
4326
4327
  //#region src/config-hooks.d.ts
4327
4328
  /**
4328
4329
  * Test-only pauses inside `ConfigStore.convertToVersion3`, for the tests that prove a write racing the conversion is
@@ -4414,7 +4415,7 @@ interface ResolvedPaths {
4414
4415
  */
4415
4416
  downloadsDir: string;
4416
4417
  }
4417
- type ErrorCode = "UNEXPECTED" | "APPROVAL_REQUIRED" | "APPROVAL_PENDING" | "APPROVAL_EXPIRED" | "APPROVAL_VOID" | "SEND_OUTCOME_UNKNOWN" | "SEND_REFUSED" | "POLICY_NEVER" | "RATE_CAPPED" | "UNSENDABLE_HTML" | "LOOSENING_REFUSED" | "UPDATE_REQUIRED" | "USAGE" | "CURSOR_MISMATCH" | "BAD_DATA" | "REPLY_INVALID" | "NOT_FOUND" | "PROVIDER_UNAVAILABLE" | "SOURCE_UNAVAILABLE" | "SECRET_STORE_UNAVAILABLE" | "TRANSIENT" | "KEYCHAIN_APPROVAL_PENDING" | "LOCK_TIMEOUT" | "AUTH_REQUIRED" | "SCOPE_MISSING" | "WHATSAPP_VISIBILITY_SEAM_REQUIRED" | "CONFIG";
4418
+ type ErrorCode = "UNEXPECTED" | "APPROVAL_REQUIRED" | "APPROVAL_PENDING" | "APPROVAL_EXPIRED" | "APPROVAL_VOID" | "SEND_OUTCOME_UNKNOWN" | "SEND_REFUSED" | "POLICY_NEVER" | "RATE_CAPPED" | "UNSENDABLE_HTML" | "LOOSENING_REFUSED" | "USAGE" | "CURSOR_MISMATCH" | "BAD_DATA" | "REPLY_INVALID" | "NOT_FOUND" | "PROVIDER_UNAVAILABLE" | "SOURCE_UNAVAILABLE" | "SECRET_STORE_UNAVAILABLE" | "TRANSIENT" | "KEYCHAIN_APPROVAL_PENDING" | "LOCK_TIMEOUT" | "AUTH_REQUIRED" | "SCOPE_MISSING" | "WHATSAPP_VISIBILITY_SEAM_REQUIRED" | "CONFIG";
4418
4419
  interface CommsErrorOptions {
4419
4420
  hint?: string;
4420
4421
  details?: Record<string, unknown>;
@@ -4594,7 +4595,7 @@ type SendPolicy = "chat" | "confirm" | "never";
4594
4595
  * way to change it, and that passes no gate at all.
4595
4596
  */
4596
4597
  type ChangePolicy = "chat" | "confirm";
4597
- /** Whether this machine checks for a newer release once a day, and stops until it is updated or put off. */
4598
+ /** 0.18's switch for the daily update check: what `defaults.updates` reads from until a level is set. */
4598
4599
  type UpdateCheckSetting = "on" | "off";
4599
4600
  type StoreKind = "keychain" | "file";
4600
4601
  interface ClientConfig {
@@ -4667,6 +4668,16 @@ interface Defaults {
4667
4668
  * it is what keeps a machine from quietly falling behind a release — so it is approved like one; on applies at once.
4668
4669
  */
4669
4670
  updateCheck?: UpdateCheckSetting | undefined;
4671
+ /**
4672
+ * How this machine updates (design 2026-10-16, U2): `auto`, `every-14-days` or `never`. Absent reads from
4673
+ * `updateCheck` — `on` as `auto`, `off` as `never` — and both absent as `auto`. A word this release does not know
4674
+ * reads as `auto`, and the file stays readable: a later release may add a level.
4675
+ *
4676
+ * Moving to a level that updates less is a loosening, approved like one; moving back applies at once. Every write of
4677
+ * a level writes `updateCheck` beside it, `off` for `never` and `on` otherwise, so a release before 0.20 sharing the
4678
+ * file checks, or does not, as the person chose.
4679
+ */
4680
+ updates?: string | undefined;
4670
4681
  }
4671
4682
  /**
4672
4683
  * A connected account on a platform that is not mail: a Slack workspace, and every channel after it (design
@@ -4780,6 +4791,16 @@ interface ConfigBody {
4780
4791
  /** Superseded rotating credentials which still need conclusive per-token cleanup. */
4781
4792
  pendingRevocations?: PendingRevocation[] | undefined;
4782
4793
  defaults: Defaults;
4794
+ /**
4795
+ * How what an agent sends is labelled (design 2026-10-15-agent-label, L5): the word, the name, the rules that say
4796
+ * who a message appears to come from, and each Slack account's agent emoji.
4797
+ *
4798
+ * `unknown` here, on purpose: it is read only through `agentLabelOf`, which reads a value it does not understand
4799
+ * as the stricter one — an unknown word as `agent`, a rule list it cannot read as no rules — so a hand edit or a
4800
+ * later release's key can only tighten. Kept through every write as the schemas keep every key they do not name, and
4801
+ * judged by `classifyChange`.
4802
+ */
4803
+ agentLabel?: unknown;
4783
4804
  }
4784
4805
  interface ConfigV1 extends ConfigBody {
4785
4806
  version: 1;
@@ -4824,6 +4845,25 @@ interface OrganisationSlackApp {
4824
4845
  clientId: string;
4825
4846
  appId?: string | undefined;
4826
4847
  }
4848
+ /**
4849
+ * An organisation's update caps, as the file beside its profile names them (design 2026-10-16, U8), and the SHA-256 of
4850
+ * that file, so `org update` can tell the organisation changing them from the record drifting. A `max` word this release
4851
+ * does not know reads as `never`, the strictest it could mean: caps only ever tighten.
4852
+ */
4853
+ interface OrganisationUpdates {
4854
+ max?: string | undefined;
4855
+ background?: boolean | undefined;
4856
+ sha256: string;
4857
+ }
4858
+ /**
4859
+ * The organisation's bot-only agent app, as its profile's agent-app file names it (CUE-493): the app's id, and the
4860
+ * SHA-256 of that file, so `org update` can tell the organisation changing it from the record drifting. No client id:
4861
+ * nobody signs in through it — its administrator installs it once and its members paste its bot token.
4862
+ */
4863
+ interface OrganisationAgentApp {
4864
+ appId: string;
4865
+ sha256: string;
4866
+ }
4827
4867
  /**
4828
4868
  * What this machine records of one organisation profile: never its bytes and never its secret — where it was read
4829
4869
  * from, the SHA-256 of what was read and when, the generations of its Google client, and its Slack apps.
@@ -4852,8 +4892,11 @@ interface OrganisationRecord {
4852
4892
  apps: {
4853
4893
  read?: OrganisationSlackApp | undefined;
4854
4894
  send?: OrganisationSlackApp | undefined;
4895
+ agent?: OrganisationAgentApp | undefined;
4855
4896
  };
4856
4897
  } | undefined;
4898
+ /** The organisation's update caps, from the file beside its profile; absent when it names none. */
4899
+ updates?: OrganisationUpdates | undefined;
4857
4900
  }
4858
4901
  interface ConfigV2 extends ConfigBody {
4859
4902
  version: 2;
@@ -5780,10 +5823,19 @@ interface ApprovalStoreOptions {
5780
5823
  * count and interrupt every step. Every other read and write of the store is unaffected.
5781
5824
  */
5782
5825
  io?: ApprovalIo | undefined;
5826
+ /**
5827
+ * Told when a person has answered a send or post: approved at a terminal, or claimed to be sent — the person's yes
5828
+ * under the chat policy (design 2026-10-16, U7: the security line a preview carried counts as asked once its approval
5829
+ * is answered). Never when it is only prepared, refused or revoked. Awaited, and whatever it throws is ignored:
5830
+ * nothing it does may stop a send. `openCore` passes `securityAnswered`.
5831
+ */
5832
+ answered?: ((approvalId: string) => Promise<void>) | undefined;
5783
5833
  }
5784
5834
  declare class ApprovalStore {
5785
5835
  #private;
5786
5836
  readonly directory: string;
5837
+ /** `ApprovalStoreOptions.answered`, never throwing. */
5838
+ readonly answered: ((approvalId: string) => Promise<void>) | undefined;
5787
5839
  constructor(stateDir: string, options?: ApprovalStoreOptions);
5788
5840
  /**
5789
5841
  * Daily retention (design 2026-10-05 §D9): once a day per state directory, a bounded batch deletes valid finished
package/dist/index.mjs CHANGED
@@ -1,5 +1,5 @@
1
- import { Bt as RESEND_DOWNLOAD_ORIGIN, Et as stripInvisible, H as CommsError, Ht as VERSION, It as PACKAGE_NAME, Lt as RESEND_CALLER, N as resendRequest, P as ResendContext, Rt as REFUSED, Vt as ROUTES, b as readBody, ft as neutralise, h as resendId, pt as newBoundary, v as addressesOf, y as attachmentRisks, z as keyPermissionOf, zt as RESEND_API_ORIGIN } from "./send-7cKVm9mA.mjs";
2
- import { t as createResendMcpServer } from "./server-CSe84nMI.mjs";
1
+ import { Bt as VERSION, Ft as RESEND_CALLER, H as CommsError, It as REFUSED, Lt as RESEND_API_ORIGIN, N as resendRequest, P as ResendContext, Pt as PACKAGE_NAME, Rt as RESEND_DOWNLOAD_ORIGIN, b as readBody, dt as newBoundary, h as resendId, ut as neutralise, v as addressesOf, wt as stripInvisible, y as attachmentRisks, z as keyPermissionOf, zt as ROUTES } from "./send-CE6wM0-w.mjs";
2
+ import { t as createResendMcpServer } from "./server-C1sSuZ8K.mjs";
3
3
  //#region src/operations/events.ts
4
4
  const BODY_LIMIT = 2e4;
5
5
  const STATUS = /* @__PURE__ */ new Set([