@agentcomms/resend 0.23.0 → 0.25.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/dist/cli.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
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-Dnq7bTQn.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-1murS6En.mjs";
3
3
  import path from "node:path";
4
4
  import { createInterface } from "node:readline/promises";
5
5
  import { stripVTControlCharacters } from "node:util";
@@ -3488,7 +3488,7 @@ Exit codes: 0 ok · 1 unexpected · 10 a send or a change was refused or needs a
3488
3488
  }));
3489
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) => {
3490
3490
  ran = true;
3491
- const startResendStdioServer = deps.startMcp ?? (await import("./stdio-entry-BWw-XnwO.mjs")).startResendStdioServer;
3491
+ const startResendStdioServer = deps.startMcp ?? (await import("./stdio-entry-EutVt-Bl.mjs")).startResendStdioServer;
3492
3492
  const core = coreForInvocation();
3493
3493
  await startResendStdioServer({
3494
3494
  ...deps,
package/dist/index.d.mts CHANGED
@@ -4322,7 +4322,7 @@ 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/launcher-CD40rL4F.d.mts
4325
+ //#region ../core/dist/launcher-B8pYW7eG.d.mts
4326
4326
  interface RegisteredServer {
4327
4327
  client: string;
4328
4328
  path: string;
package/dist/index.mjs CHANGED
@@ -1,5 +1,5 @@
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-Dnq7bTQn.mjs";
2
- import { t as createResendMcpServer } from "./server-CCzhekl9.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-1murS6En.mjs";
2
+ import { t as createResendMcpServer } from "./server-COls8j1E.mjs";
3
3
  //#region src/operations/events.ts
4
4
  const BODY_LIMIT = 2e4;
5
5
  const STATUS = /* @__PURE__ */ new Set([
@@ -12,7 +12,7 @@ import { execFile, spawn } from "node:child_process";
12
12
  //#endregion
13
13
  //#region src/version.ts
14
14
  /** The package version, read from package.json at build time. */
15
- const VERSION$2 = "0.23.0";
15
+ const VERSION$2 = "0.25.0";
16
16
  //#endregion
17
17
  //#region src/api/routes.ts
18
18
  /**
@@ -201,7 +201,7 @@ const RESEND_CALLER = Object.freeze({
201
201
  packageName: PACKAGE_NAME
202
202
  });
203
203
  //#endregion
204
- //#region ../core/dist/update-check-BrR1qAfk.mjs
204
+ //#region ../core/dist/update-check-CMD_Te5S.mjs
205
205
  /**
206
206
  * Every failure a user or an agent can act on carries a specific, stable code from this registry, a message, an
207
207
  * optional one-line hint and structured `details`. The code decides the process exit status; agents and skills branch
@@ -1997,8 +1997,12 @@ function programNeedsQuotes(command) {
1997
1997
  const [program] = command.words;
1998
1998
  return command.platform === "win32" && program !== void 0 && windowsShellWord(program) !== program;
1999
1999
  }
2000
+ /**
2001
+ * One word for a POSIX shell: as it is when nothing in it is special, otherwise in single quotes. A word that starts
2002
+ * with `=` or `~` is quoted too: zsh reads `=ls` as the path of `ls`, and `~` as a home.
2003
+ */
2000
2004
  function posixShellWord(word) {
2001
- return /^[\w@%+=:,./-]+$/.test(word) ? word : `'${word.replace(/'/g, `'\\''`)}'`;
2005
+ return /^(?![=~])[\w@%+=:,./-]+$/.test(word) ? word : `'${word.replace(/'/g, `'\\''`)}'`;
2002
2006
  }
2003
2007
  /**
2004
2008
  * The word as cmd.exe, Windows PowerShell and PowerShell 7 all hand it to a program, or null when no printing of it
@@ -7811,6 +7815,24 @@ function parseConfig(text, source = "config.json") {
7811
7815
  if (!parsed.success) throw new CommsError("CONFIG", `${source} is invalid: ${describeIssues(parsed.error, naming === 1 ? 1 : 2)}`);
7812
7816
  return parsed.data;
7813
7817
  }
7818
+ /**
7819
+ * How a config write waits for the config lock: five seconds for each holder, thirty seconds in all.
7820
+ *
7821
+ * The lock is a queue. Every send prepare, claim and approval on every channel runs `ensureSendEpochConfig` first, and
7822
+ * while a legacy drain is open that is a config write or two per call, so an agent's parallel calls across several MCP
7823
+ * servers arrive at this lock together, each holding it for one read, check and fsynced rename (and the drain's, for a
7824
+ * list of the approvals too). Counted from when each waiter began, the lock's five seconds were a budget for the whole
7825
+ * line ahead: on the Windows runner a line of twelve writes gave up at the ninth, "another agent-communications process
7826
+ * is holding", while the lock was being handed on exactly as it should be. A holder there took about half a second, and
7827
+ * on Windows a rename alone may retry for one. Counted per holder, as Resend's throttle and Gmail's history caches count
7828
+ * theirs, a write gives up only on a holder that keeps the lock for the whole five seconds: the stuck lock the timeout is
7829
+ * for. The lock is polled rather than queued, so thirty seconds in all bounds the rest, and leaves room inside the minute
7830
+ * an MCP client waits for a tool call.
7831
+ */
7832
+ const CONFIG_WRITE_LOCK = {
7833
+ timeoutPerHolder: true,
7834
+ maxWaitMs: 3e4
7835
+ };
7814
7836
  var ConfigStore = class {
7815
7837
  path;
7816
7838
  #lockPath;
@@ -7831,6 +7853,10 @@ var ConfigStore = class {
7831
7853
  #namesMigrateAgain(why) {
7832
7854
  return handoffSentence(requiredHandoffs(this.#handoffs).core(["names", "migrate"]), (command) => `Run ${command} again ${why}.`, { instead: `Call comms_names_migrate again ${why}.` });
7833
7855
  }
7856
+ /** Runs `fn` holding the config lock, waited for as a write waits for it (`CONFIG_WRITE_LOCK`). */
7857
+ #withWriteLock(fn) {
7858
+ return withFileLock(this.#lockPath, fn, CONFIG_WRITE_LOCK);
7859
+ }
7834
7860
  /** The current config; an empty one when the file does not exist yet. */
7835
7861
  async load() {
7836
7862
  let key;
@@ -7857,7 +7883,7 @@ var ConfigStore = class {
7857
7883
  let committed;
7858
7884
  let result;
7859
7885
  try {
7860
- result = await withFileLock(this.#lockPath, async () => {
7886
+ result = await this.#withWriteLock(async () => {
7861
7887
  options.signal?.throwIfAborted();
7862
7888
  this.#cache = null;
7863
7889
  const current = structuredClone(await this.load());
@@ -12972,7 +12998,7 @@ function folding(platform) {
12972
12998
  return platform === "win32" ? (text) => text.toLowerCase() : (text) => text;
12973
12999
  }
12974
13000
  /** The package version, read from package.json at build time. */
12975
- const VERSION = "0.23.0";
13001
+ const VERSION = "0.25.0";
12976
13002
  /**
12977
13003
  * The command a person is told to run for one of this suite's own CLIs (design 2026-10-04, D1 and D5; CUE-403).
12978
13004
  *
@@ -17159,7 +17185,7 @@ function serverPruneChange(core, env, request, own) {
17159
17185
  };
17160
17186
  const { packageName, version } = ownProduct(request.channel, own) ?? {
17161
17187
  packageName: serverFacts(request.channel).packageName,
17162
- version: "0.23.0"
17188
+ version: "0.25.0"
17163
17189
  };
17164
17190
  const product = {
17165
17191
  packageName,
@@ -17830,8 +17856,9 @@ function updateToolNotice(options) {
17830
17856
  let running = null;
17831
17857
  let given = false;
17832
17858
  let turn = Promise.resolve();
17833
- return (tool) => {
17859
+ return (tool, args) => {
17834
17860
  if (updateCheckSwitchedOff(options.env) !== null) return Promise.resolve(null);
17861
+ if (options.quiet?.(tool, args)) return Promise.resolve(null);
17835
17862
  if (options.refresh && running === null) running = options.refresh().catch(() => void 0).finally(() => {
17836
17863
  running = null;
17837
17864
  });
@@ -18586,7 +18613,7 @@ function terminalUpdateHooks(core, env, options = {}) {
18586
18613
  } };
18587
18614
  }
18588
18615
  //#endregion
18589
- //#region ../core/dist/tool-arguments-C2vEASTA.mjs
18616
+ //#region ../core/dist/tool-arguments-BW3WUyxT.mjs
18590
18617
  const APPLIED = Symbol.for("agentcomms.strictToolArguments");
18591
18618
  const TARGET = "draft-2020-12";
18592
18619
  /**
@@ -18629,7 +18656,7 @@ function strictToolArguments(server, refuse, notice, retired = {}) {
18629
18656
  const parsed = await schema.safeParseAsync(input ?? {});
18630
18657
  if (!parsed.success) return refuse(refusal(name, published, input, parsed.error.issues, retired[name] ?? {}));
18631
18658
  const result = await (declared ? handler(parsed.data, context) : handler(context));
18632
- const line = notice ? await notice(name).catch(() => null) : null;
18659
+ const line = notice ? await notice(name, parsed.data).catch(() => null) : null;
18633
18660
  return line === null ? result : withUpdateNotice(result, line, room);
18634
18661
  });
18635
18662
  };
@@ -1,4 +1,4 @@
1
- import { A as removeAccountChange, At as waitCallOptions, B as strictToolArguments, Bt as VERSION, D as policyChange, E as policyApprovalRefusal, Et as toCommsError, F as CHANGE_POLICIES, H as CommsError, I as MODES, L as SEND_POLICIES, M as showAccount, O as policyReport, P as ResendContext, X as changeToolResult, Z as checkForUpdates, _ as showSentEmail, c as downloadReceived, d as listReceived, f as listScheduled, g as showReceived, ht as refuseUnclaimedApproval, i as prepareSend, it as gatedChange, jt as waitForApproval, k as policyWanted, kt as updateToolNotice, l as getMetrics, m as listSuppressions, n as executeSend, o as sendStatus, p as listSentEmails, s as cancelScheduledChange, u as listDomains, w as listAccounts, x as runDoctor } from "./send-Dnq7bTQn.mjs";
1
+ import { A as removeAccountChange, At as waitCallOptions, B as strictToolArguments, Bt as VERSION, D as policyChange, E as policyApprovalRefusal, Et as toCommsError, F as CHANGE_POLICIES, H as CommsError, I as MODES, L as SEND_POLICIES, M as showAccount, O as policyReport, P as ResendContext, X as changeToolResult, Z as checkForUpdates, _ as showSentEmail, c as downloadReceived, d as listReceived, f as listScheduled, g as showReceived, ht as refuseUnclaimedApproval, i as prepareSend, it as gatedChange, jt as waitForApproval, k as policyWanted, kt as updateToolNotice, l as getMetrics, m as listSuppressions, n as executeSend, o as sendStatus, p as listSentEmails, s as cancelScheduledChange, u as listDomains, w as listAccounts, x as runDoctor } from "./send-1murS6En.mjs";
2
2
  import { S as union, c as boolean, g as object, h as number, s as array, x as string } from "./iso-USuVU_sk.mjs";
3
3
  import { t as McpServer } from "./mcp-DIH4cS6P-CIWWZQbz.mjs";
4
4
  //#region src/mcp/server.ts
@@ -1,4 +1,4 @@
1
- import { t as createResendMcpServer } from "./server-CCzhekl9.mjs";
1
+ import { t as createResendMcpServer } from "./server-COls8j1E.mjs";
2
2
  //#region src/mcp/stdio-entry.ts
3
3
  /**
4
4
  * Starting the stdio server. On stdio, **stdout is the protocol**: one stray `console.log` corrupts the stream, so
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agentcomms/resend",
3
- "version": "0.23.0",
3
+ "version": "0.25.0",
4
4
  "description": "Resend for coding agents: read domains, sent and received mail, metrics and suppressions, and send mail that nothing sends without a person's approval of exactly what goes out.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -31,7 +31,7 @@
31
31
  "THIRD_PARTY_LICENSES"
32
32
  ],
33
33
  "dependencies": {
34
- "@agentcomms/core": "0.23.0"
34
+ "@agentcomms/core": "0.25.0"
35
35
  },
36
36
  "optionalDependencies": {
37
37
  "@napi-rs/keyring": "2.1.0"
@@ -107,5 +107,5 @@
107
107
  "typecheck": "tsc -p tsconfig.json",
108
108
  "test": "node --experimental-strip-types --test --test-timeout=600000 \"test/**/*.test.ts\""
109
109
  },
110
- "gitHead": "2431f1f1ffe5dd6dc02a1285a09fe3704b0caeb2"
110
+ "gitHead": "1aca79f8c2674add5086fe4f05a52c8fb2719657"
111
111
  }