@codeforbreakfast/commy-mcp 0.24.1 → 0.24.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/server.js +232 -113
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@codeforbreakfast/commy-mcp",
3
- "version": "0.24.1",
3
+ "version": "0.24.3",
4
4
  "description": "commy MCP server — the inter-agent communication substrate, runnable on node via npx.",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",
package/server.js CHANGED
@@ -3048,10 +3048,11 @@ var require_data = __commonJS((exports, module) => {
3048
3048
  };
3049
3049
  });
3050
3050
 
3051
- // node_modules/.bun/fast-uri@4.1.3/node_modules/fast-uri/lib/utils.js
3051
+ // node_modules/.bun/fast-uri@4.2.1/node_modules/fast-uri/lib/utils.js
3052
3052
  var require_utils = __commonJS((exports, module) => {
3053
3053
  var isUUID = RegExp.prototype.test.bind(/^[\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\da-f]{4}-[\da-f]{12}$/iu);
3054
3054
  var isIPv4 = RegExp.prototype.test.bind(/^(?:(?:25[0-5]|2[0-4]\d|1\d{2}|[1-9]\d|\d)\.){3}(?:25[0-5]|2[0-4]\d|1\d{2}|[1-9]\d|\d)$/u);
3055
+ var isPort = RegExp.prototype.test.bind(/^\d*$/u);
3055
3056
  var isHexPair = RegExp.prototype.test.bind(/^[\da-f]{2}$/iu);
3056
3057
  var isUnreserved = RegExp.prototype.test.bind(/^[\da-z\-._~]$/iu);
3057
3058
  var isPathCharacter = RegExp.prototype.test.bind(/^[A-Za-z0-9\-._~!$&'()*+,;=:@/]$/u);
@@ -3533,6 +3534,22 @@ var require_utils = __commonJS((exports, module) => {
3533
3534
  }
3534
3535
  return output;
3535
3536
  }
3537
+ function recomposeZonedIPv6Host(component) {
3538
+ const zone = component.ipv6Zone;
3539
+ if (zone === undefined)
3540
+ return;
3541
+ const host = component.host;
3542
+ const separator = host.indexOf("%");
3543
+ if (separator === -1)
3544
+ return;
3545
+ const address = host.slice(0, separator);
3546
+ const escaped = address + "%25" + zone;
3547
+ const derived = normalizeIPv6("[" + escaped + "]");
3548
+ if (derived.isIPV6 === true && derived.host === host) {
3549
+ return "[" + escaped + "]";
3550
+ }
3551
+ return;
3552
+ }
3536
3553
  function recomposeAuthority(component) {
3537
3554
  const uriTokens = [];
3538
3555
  if (component.userinfo !== undefined) {
@@ -3542,22 +3559,31 @@ var require_utils = __commonJS((exports, module) => {
3542
3559
  if (component.host !== undefined) {
3543
3560
  let host = component.host;
3544
3561
  if (!isIPv4(host)) {
3545
- let ipV6res = normalizeIPv6(host);
3546
- if (ipV6res.isIPV6 !== true && ipV6res.isIPVFuture !== true) {
3547
- host = normalizePercentEncoding(host, true);
3548
- ipV6res = normalizeIPv6(host);
3549
- }
3550
- if (ipV6res.isIPV6 === true || ipV6res.isIPVFuture === true) {
3551
- host = `[${ipV6res.escapedHost}]`;
3562
+ const zonedHost = recomposeZonedIPv6Host(component);
3563
+ if (zonedHost !== undefined) {
3564
+ host = zonedHost;
3552
3565
  } else {
3553
- host = reescapeHostDelimiters(host, false);
3566
+ let ipV6res = normalizeIPv6(host);
3567
+ if (ipV6res.isIPV6 !== true && ipV6res.isIPVFuture !== true) {
3568
+ host = normalizePercentEncoding(host, true);
3569
+ ipV6res = normalizeIPv6(host);
3570
+ }
3571
+ if (ipV6res.isIPV6 === true || ipV6res.isIPVFuture === true) {
3572
+ host = `[${ipV6res.escapedHost}]`;
3573
+ } else {
3574
+ host = reescapeHostDelimiters(host, false);
3575
+ }
3554
3576
  }
3555
3577
  }
3556
3578
  uriTokens.push(host);
3557
3579
  }
3558
3580
  if (typeof component.port === "number" || typeof component.port === "string") {
3581
+ const port3 = String(component.port);
3582
+ if (!isPort(port3)) {
3583
+ throw new TypeError("URI port is malformed.");
3584
+ }
3559
3585
  uriTokens.push(":");
3560
- uriTokens.push(String(component.port));
3586
+ uriTokens.push(port3);
3561
3587
  }
3562
3588
  return uriTokens.length ? uriTokens.join("") : undefined;
3563
3589
  }
@@ -3584,7 +3610,7 @@ var require_utils = __commonJS((exports, module) => {
3584
3610
  };
3585
3611
  });
3586
3612
 
3587
- // node_modules/.bun/fast-uri@4.1.3/node_modules/fast-uri/lib/schemes.js
3613
+ // node_modules/.bun/fast-uri@4.2.1/node_modules/fast-uri/lib/schemes.js
3588
3614
  var require_schemes = __commonJS((exports, module) => {
3589
3615
  var { isUUID, BYTE_HEX, percentEncodeNonAscii, nonSimpleMailtoDomain } = require_utils();
3590
3616
  var URN_REG = /^([\da-z][\d\-a-z]{0,31}):((?:[\w!$'()*+,\-./:;=@]|%[\da-f]{2})+)$/iu;
@@ -3759,6 +3785,7 @@ var require_schemes = __commonJS((exports, module) => {
3759
3785
  var HEX_PAIR = /^[\da-f]{2}$/iu;
3760
3786
  var MAILTO_DOMAIN_LITERAL = /^\[[\x21-\x5A\x5E-\x7E]*\]$/u;
3761
3787
  var MAILTO_DOMAIN_ERROR = "URI mailto has an invalid recipient domain.";
3788
+ var MAILTO_AUTHORITY_ERROR = "URI mailto must not have an authority component.";
3762
3789
  var HAS_SURROGATE = /[\uD800-\uDFFF]/u;
3763
3790
  function decodeHex2(str) {
3764
3791
  if (typeof str !== "string" || str.indexOf("%") === -1) {
@@ -3873,30 +3900,37 @@ var require_schemes = __commonJS((exports, module) => {
3873
3900
  mailtoComponent.error = mailtoComponent.error || "URI mailto has malformed header fields.";
3874
3901
  continue;
3875
3902
  }
3876
- const name = eqIdx === -1 ? token : token.slice(0, eqIdx);
3903
+ const name = decodeHex2(eqIdx === -1 ? token : token.slice(0, eqIdx));
3904
+ const normalizedName = name.toLowerCase();
3877
3905
  const value5 = eqIdx === -1 ? "" : token.slice(eqIdx + 1);
3878
- if (name === "to") {
3906
+ if (normalizedName === "to") {
3879
3907
  const addrs = value5.split(",");
3880
3908
  for (let j = 0;j < addrs.length; j++)
3881
3909
  to.push(addrs[j]);
3882
3910
  continue;
3883
3911
  }
3884
- if (name === "subject") {
3912
+ if (normalizedName === "subject") {
3885
3913
  mailtoComponent.subject = decodeHex2(value5);
3886
3914
  continue;
3887
3915
  }
3888
- if (name === "body") {
3916
+ if (normalizedName === "body") {
3889
3917
  mailtoComponent.body = decodeHex2(value5);
3890
3918
  continue;
3891
3919
  }
3892
3920
  if (headers === null)
3893
3921
  headers = Object.create(null);
3894
- headers[decodeHex2(name)] = decodeHex2(value5);
3922
+ headers[name] = decodeHex2(value5);
3895
3923
  }
3896
3924
  if (headers !== null)
3897
3925
  mailtoComponent.headers = headers;
3898
3926
  }
3899
3927
  mailtoComponent.query = undefined;
3928
+ if (to.length > 0 && (mailtoComponent.userinfo !== undefined || mailtoComponent.host !== undefined || mailtoComponent.port !== undefined)) {
3929
+ mailtoComponent.userinfo = undefined;
3930
+ mailtoComponent.host = undefined;
3931
+ mailtoComponent.port = undefined;
3932
+ mailtoComponent.error = mailtoComponent.error || MAILTO_AUTHORITY_ERROR;
3933
+ }
3900
3934
  for (let i = 0;i < to.length; i++) {
3901
3935
  const rawAddr = to[i];
3902
3936
  const atIdx = rawAddr.lastIndexOf("@");
@@ -3913,10 +3947,35 @@ var require_schemes = __commonJS((exports, module) => {
3913
3947
  mailtoComponent.to = to;
3914
3948
  return mailtoComponent;
3915
3949
  }
3950
+ function mailtoEncodeHeaderName(name) {
3951
+ return encodeWithAllow(name.replace(/%/gu, "%25"), HFNAME);
3952
+ }
3916
3953
  function mailtoSerialize(component, options5) {
3917
3954
  const mailtoComponent = component;
3918
3955
  const to = Array.isArray(mailtoComponent.to) ? mailtoComponent.to.slice() : [];
3956
+ const sourceHeaders = mailtoComponent.headers && typeof mailtoComponent.headers === "object" ? Object.assign(Object.create(null), mailtoComponent.headers) : Object.create(null);
3957
+ const headers = Object.create(null);
3958
+ for (const name in sourceHeaders) {
3959
+ const normalizedName = name.toLowerCase();
3960
+ if (normalizedName === "to") {
3961
+ const addrs = String(sourceHeaders[name]).split(",");
3962
+ for (let i = 0;i < addrs.length; i++)
3963
+ to.push(addrs[i]);
3964
+ } else if (normalizedName === "subject" || normalizedName === "body") {
3965
+ headers[normalizedName] = sourceHeaders[name];
3966
+ } else {
3967
+ headers[name] = sourceHeaders[name];
3968
+ }
3969
+ }
3970
+ if (mailtoComponent.subject !== undefined)
3971
+ headers.subject = mailtoComponent.subject;
3972
+ if (mailtoComponent.body !== undefined)
3973
+ headers.body = mailtoComponent.body;
3974
+ mailtoComponent.headers = headers;
3919
3975
  if (to.length) {
3976
+ mailtoComponent.userinfo = undefined;
3977
+ mailtoComponent.host = undefined;
3978
+ mailtoComponent.port = undefined;
3920
3979
  for (let i = 0;i < to.length; i++) {
3921
3980
  const addr = String(to[i]);
3922
3981
  const atIdx = addr.lastIndexOf("@");
@@ -3932,18 +3991,12 @@ var require_schemes = __commonJS((exports, module) => {
3932
3991
  } else {
3933
3992
  mailtoComponent.path = undefined;
3934
3993
  }
3935
- const headers = mailtoComponent.headers && typeof mailtoComponent.headers === "object" ? Object.assign(Object.create(null), mailtoComponent.headers) : Object.create(null);
3936
- if (mailtoComponent.subject)
3937
- headers.subject = mailtoComponent.subject;
3938
- if (mailtoComponent.body)
3939
- headers.body = mailtoComponent.body;
3940
- mailtoComponent.headers = headers;
3941
3994
  let query = "";
3942
3995
  let count4 = 0;
3943
3996
  for (const name in headers) {
3944
3997
  if (count4++ !== 0)
3945
3998
  query += "&";
3946
- query += encodeWithAllow(name, HFNAME) + "=" + encodeWithAllow(String(headers[name]), HFNAME);
3999
+ query += mailtoEncodeHeaderName(name) + "=" + encodeWithAllow(String(headers[name]), HFNAME);
3947
4000
  }
3948
4001
  if (count4 !== 0) {
3949
4002
  mailtoComponent.query = query;
@@ -3982,7 +4035,7 @@ var require_schemes = __commonJS((exports, module) => {
3982
4035
  };
3983
4036
  });
3984
4037
 
3985
- // node_modules/.bun/fast-uri@4.1.3/node_modules/fast-uri/index.js
4038
+ // node_modules/.bun/fast-uri@4.2.1/node_modules/fast-uri/index.js
3986
4039
  var require_fast_uri = __commonJS((exports, module) => {
3987
4040
  var { normalizeIPv6, removeDotSegments, recomposeAuthority, normalizePercentEncoding, normalizePathEncoding, serializePathEncoding, normalizeQueryFragmentEncoding, encodeQuery, encodeFragment, reescapeHostDelimiters, isIPv4, nonSimpleDomain } = require_utils();
3988
4041
  var { SCHEMES, getSchemeHandler } = require_schemes();
@@ -4036,6 +4089,12 @@ var require_fast_uri = __commonJS((exports, module) => {
4036
4089
  schemelessOptions.skipEscape = true;
4037
4090
  return serialize2(resolved, schemelessOptions);
4038
4091
  }
4092
+ function copyHost(target, source) {
4093
+ target.host = source.host;
4094
+ if (source.ipv6Zone !== undefined) {
4095
+ target.ipv6Zone = source.ipv6Zone;
4096
+ }
4097
+ }
4039
4098
  function resolveComponent(base, relative, options5, skipNormalization) {
4040
4099
  const target = {};
4041
4100
  if (!skipNormalization) {
@@ -4046,14 +4105,14 @@ var require_fast_uri = __commonJS((exports, module) => {
4046
4105
  if (!options5.tolerant && relative.scheme) {
4047
4106
  target.scheme = relative.scheme;
4048
4107
  target.userinfo = relative.userinfo;
4049
- target.host = relative.host;
4108
+ copyHost(target, relative);
4050
4109
  target.port = relative.port;
4051
4110
  target.path = removeDotSegments(relative.path || "");
4052
4111
  target.query = relative.query;
4053
4112
  } else {
4054
4113
  if (relative.userinfo !== undefined || relative.host !== undefined || relative.port !== undefined) {
4055
4114
  target.userinfo = relative.userinfo;
4056
- target.host = relative.host;
4115
+ copyHost(target, relative);
4057
4116
  target.port = relative.port;
4058
4117
  target.path = removeDotSegments(relative.path || "");
4059
4118
  target.query = relative.query;
@@ -4081,7 +4140,7 @@ var require_fast_uri = __commonJS((exports, module) => {
4081
4140
  target.query = relative.query;
4082
4141
  }
4083
4142
  target.userinfo = base.userinfo;
4084
- target.host = base.host;
4143
+ copyHost(target, base);
4085
4144
  target.port = base.port;
4086
4145
  }
4087
4146
  target.scheme = base.scheme;
@@ -4097,6 +4156,7 @@ var require_fast_uri = __commonJS((exports, module) => {
4097
4156
  function serialize2(cmpts, opts) {
4098
4157
  const component = {
4099
4158
  host: cmpts.host,
4159
+ ipv6Zone: cmpts.ipv6Zone,
4100
4160
  scheme: cmpts.scheme,
4101
4161
  userinfo: cmpts.userinfo,
4102
4162
  port: cmpts.port,
@@ -4191,12 +4251,16 @@ var require_fast_uri = __commonJS((exports, module) => {
4191
4251
  }
4192
4252
  return false;
4193
4253
  }
4254
+ function isIPLiteral(host) {
4255
+ return host[0] === "[" && host[host.length - 1] === "]";
4256
+ }
4194
4257
  function hasMalformedComponentPercentEncoding(matches) {
4195
4258
  const host = matches[4];
4196
- return hasMalformedPercentEncoding(matches[3]) || host !== undefined && !(host[0] === "[" && host[host.length - 1] === "]") && hasMalformedPercentEncoding(host) || hasMalformedPercentEncoding(matches[6]) || hasMalformedPercentEncoding(matches[7]) || hasMalformedPercentEncoding(matches[8]);
4259
+ return hasMalformedPercentEncoding(matches[3]) || host !== undefined && !isIPLiteral(host) && hasMalformedPercentEncoding(host) || hasMalformedPercentEncoding(matches[6]) || hasMalformedPercentEncoding(matches[7]) || hasMalformedPercentEncoding(matches[8]);
4197
4260
  }
4198
4261
  function canonicalizeHost(parsed, options5, schemeHandler, isIP) {
4199
- if (!options5.unicodeSupport && (!schemeHandler || !schemeHandler.unicodeSupport) && parsed.host && parsed.host[0] !== "[" && (options5.domainHost || schemeHandler && schemeHandler.domainHost) && isIP === false && nonSimpleDomain(parsed.host)) {
4262
+ const bracketedIPLiteral = parsed.host && parsed.host[0] === "[" && parsed.host[parsed.host.length - 1] === "]";
4263
+ if (!options5.unicodeSupport && (!schemeHandler || !schemeHandler.unicodeSupport) && parsed.host && !isIPLiteral(parsed.host) && (options5.domainHost || schemeHandler && schemeHandler.domainHost) && isIP === false && !bracketedIPLiteral && nonSimpleDomain(parsed.host)) {
4200
4264
  try {
4201
4265
  parsed.host = new URL("http://" + parsed.host).hostname;
4202
4266
  } catch (e) {
@@ -4283,11 +4347,15 @@ var require_fast_uri = __commonJS((exports, module) => {
4283
4347
  if (parsed.host) {
4284
4348
  const ipv4result = isIPv4(parsed.host);
4285
4349
  if (ipv4result === false) {
4286
- const bracketedIPLiteral = parsed.host[0] === "[" && parsed.host[parsed.host.length - 1] === "]";
4350
+ const bracketedIPLiteral = isIPLiteral(parsed.host);
4351
+ const hasIPLiteralBracket = parsed.host.indexOf("[") !== -1 || parsed.host.indexOf("]") !== -1;
4287
4352
  const ipv6result = normalizeIPv6(parsed.host);
4288
4353
  isIP = ipv6result.isIPV6 || ipv6result.isIPVFuture === true;
4289
- malformedIPLiteral = bracketedIPLiteral && ipv6result.error === true;
4354
+ malformedIPLiteral = hasIPLiteralBracket && (!bracketedIPLiteral || ipv6result.error === true);
4290
4355
  parsed.host = isIP ? ipv6result.host : ipv6result.host.toLowerCase();
4356
+ if (isIP && ipv6result.isIPV6 === true && parsed.host.indexOf("%") !== -1) {
4357
+ parsed.ipv6Zone = parsed.host.slice(parsed.host.indexOf("%") + 1);
4358
+ }
4291
4359
  if (malformedIPLiteral) {
4292
4360
  parsed.error = parsed.error || "URI host is malformed.";
4293
4361
  malformedAuthorityOrPort = true;
@@ -4309,14 +4377,17 @@ var require_fast_uri = __commonJS((exports, module) => {
4309
4377
  parsed.error = parsed.error || "URI is not a " + options5.reference + " reference.";
4310
4378
  }
4311
4379
  const schemeHandler = getSchemeHandler(options5.scheme || parsed.scheme);
4312
- malformedHost = canonicalizeHost(parsed, options5, schemeHandler, isIP);
4313
- if (!schemeHandler || schemeHandler && !schemeHandler.skipNormalize) {
4314
- if (uri.indexOf("%") !== -1) {
4315
- if (parsed.host !== undefined && !malformedIPLiteral) {
4316
- const host = isIP ? parsed.host : normalizePercentEncoding(parsed.host, true);
4317
- parsed.host = reescapeHostDelimiters(host, isIP);
4318
- }
4380
+ if (!malformedIPLiteral) {
4381
+ malformedHost = canonicalizeHost(parsed, options5, schemeHandler, isIP);
4382
+ }
4383
+ if (uri.indexOf("%") !== -1 && parsed.host !== undefined && !malformedIPLiteral) {
4384
+ let host = isIP ? parsed.host : normalizePercentEncoding(parsed.host, true);
4385
+ if (!isIP) {
4386
+ host = normalizePercentEncoding(host.toLowerCase());
4319
4387
  }
4388
+ parsed.host = reescapeHostDelimiters(host, isIP);
4389
+ }
4390
+ if (!schemeHandler || schemeHandler && !schemeHandler.skipNormalize) {
4320
4391
  if (parsed.path) {
4321
4392
  parsed.path = normalizePathEncoding(parsed.path);
4322
4393
  }
@@ -50358,7 +50429,7 @@ var runMain2 = runMain;
50358
50429
 
50359
50430
  // node_modules/.bun/@effect+platform-node@0.108.2+7b41a6254ced90d9/node_modules/@effect/platform-node/dist/esm/NodeRuntime.js
50360
50431
  var runMain3 = runMain2;
50361
- // node_modules/.bun/@modelcontextprotocol+sdk@1.29.0/node_modules/@modelcontextprotocol/sdk/dist/esm/server/stdio.js
50432
+ // node_modules/.bun/@modelcontextprotocol+sdk@1.30.1/node_modules/@modelcontextprotocol/sdk/dist/esm/server/stdio.js
50362
50433
  import process3 from "node:process";
50363
50434
 
50364
50435
  // node_modules/.bun/zod@4.4.3/node_modules/zod/v4/core/core.js
@@ -55477,7 +55548,7 @@ function preprocess(fn2, schema) {
55477
55548
  // node_modules/.bun/zod@4.4.3/node_modules/zod/v4/classic/external.js
55478
55549
  config2(en_default());
55479
55550
 
55480
- // node_modules/.bun/@modelcontextprotocol+sdk@1.29.0/node_modules/@modelcontextprotocol/sdk/dist/esm/types.js
55551
+ // node_modules/.bun/@modelcontextprotocol+sdk@1.30.1/node_modules/@modelcontextprotocol/sdk/dist/esm/types.js
55481
55552
  var LATEST_PROTOCOL_VERSION = "2025-11-25";
55482
55553
  var SUPPORTED_PROTOCOL_VERSIONS = [LATEST_PROTOCOL_VERSION, "2025-06-18", "2025-03-26", "2024-11-05", "2024-10-07"];
55483
55554
  var RELATED_TASK_META_KEY = "io.modelcontextprotocol/related-task";
@@ -56312,9 +56383,19 @@ class UrlElicitationRequiredError extends McpError {
56312
56383
  }
56313
56384
  }
56314
56385
 
56315
- // node_modules/.bun/@modelcontextprotocol+sdk@1.29.0/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/stdio.js
56386
+ // node_modules/.bun/@modelcontextprotocol+sdk@1.30.1/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/stdio.js
56387
+ var STDIO_DEFAULT_MAX_BUFFER_SIZE = 10 * 1024 * 1024;
56388
+
56316
56389
  class ReadBuffer {
56390
+ constructor(options5) {
56391
+ this._maxBufferSize = options5?.maxBufferSize ?? STDIO_DEFAULT_MAX_BUFFER_SIZE;
56392
+ }
56317
56393
  append(chunk5) {
56394
+ const newSize = (this._buffer?.length ?? 0) + chunk5.length;
56395
+ if (newSize > this._maxBufferSize) {
56396
+ this.clear();
56397
+ throw new Error(`ReadBuffer exceeded maximum size of ${this._maxBufferSize} bytes`);
56398
+ }
56318
56399
  this._buffer = this._buffer ? Buffer.concat([this._buffer, chunk5]) : chunk5;
56319
56400
  }
56320
56401
  readMessage() {
@@ -56342,20 +56423,25 @@ function serializeMessage(message) {
56342
56423
  `;
56343
56424
  }
56344
56425
 
56345
- // node_modules/.bun/@modelcontextprotocol+sdk@1.29.0/node_modules/@modelcontextprotocol/sdk/dist/esm/server/stdio.js
56426
+ // node_modules/.bun/@modelcontextprotocol+sdk@1.30.1/node_modules/@modelcontextprotocol/sdk/dist/esm/server/stdio.js
56346
56427
  class StdioServerTransport {
56347
- constructor(_stdin = process3.stdin, _stdout = process3.stdout) {
56428
+ constructor(_stdin = process3.stdin, _stdout = process3.stdout, options5) {
56348
56429
  this._stdin = _stdin;
56349
56430
  this._stdout = _stdout;
56350
- this._readBuffer = new ReadBuffer;
56351
56431
  this._started = false;
56352
56432
  this._ondata = (chunk5) => {
56353
- this._readBuffer.append(chunk5);
56354
- this.processReadBuffer();
56433
+ try {
56434
+ this._readBuffer.append(chunk5);
56435
+ this.processReadBuffer();
56436
+ } catch (error2) {
56437
+ this.onerror?.(error2);
56438
+ this.close().catch(() => {});
56439
+ }
56355
56440
  };
56356
56441
  this._onerror = (error2) => {
56357
56442
  this.onerror?.(error2);
56358
56443
  };
56444
+ this._readBuffer = new ReadBuffer({ maxBufferSize: options5?.maxBufferSize });
56359
56445
  }
56360
56446
  async start() {
56361
56447
  if (this._started) {
@@ -56599,9 +56685,15 @@ var toMention = (directory) => MentionSpan.$match({
56599
56685
  UserSpan: ({ userId }) => exports_Effect.succeed(exports_Option.map(exports_Option.fromNullable(directory.byUserId(userId)), (identity6) => Mention.UserMention({ identity: identity6 })))
56600
56686
  });
56601
56687
  var renderedMentions = (rendered, directory) => exports_Effect.forEach(mentionSpans(rendered), toMention(directory)).pipe(exports_Effect.map(exports_Array.getSomes), exports_Effect.map(exports_Array.dedupeWith((a, b) => exports_Equal.equals(identityOf(a), identityOf(b)))));
56602
- var mentionsOfMessage = (renderedFor, message, directory) => mayMention(message.content) ? renderedFor(message.id).pipe(exports_Effect.flatMap(exports_Option.match({
56688
+ var mentionedUserIds = (rendered) => exports_Array.filterMap(mentionSpans(rendered), MentionSpan.$match({
56689
+ UserSpan: ({ userId }) => exports_Option.some(userId),
56690
+ GroupSpan: () => exports_Option.none(),
56691
+ ChannelWildcardSpan: () => exports_Option.none(),
56692
+ TopicWildcardSpan: () => exports_Option.none()
56693
+ }));
56694
+ var mentionsOfMessage = (renderedFor, message, directoryFor) => mayMention(message.content) ? renderedFor(message.id).pipe(exports_Effect.flatMap(exports_Option.match({
56603
56695
  onNone: () => exports_Effect.succeed([]),
56604
- onSome: (rendered) => renderedMentions(rendered, directory)
56696
+ onSome: (rendered) => directoryFor(mentionedUserIds(rendered)).pipe(exports_Effect.flatMap((directory) => renderedMentions(rendered, directory)))
56605
56697
  }))) : exports_Effect.succeed([]);
56606
56698
 
56607
56699
  // packages/zulip/resolved-topic.ts
@@ -56615,6 +56707,10 @@ var splitTopic = (rawTopic) => {
56615
56707
  var applyResolvedPrefix = (name, resolved) => resolved ? isResolvedTopic(name) ? name : RESOLVED_TOPIC_PREFIX + name : stripResolvedPrefix(name);
56616
56708
 
56617
56709
  // packages/zulip/events.ts
56710
+ var mentionDirectoryOf = (directory) => ({
56711
+ byName: directory.byName,
56712
+ byUserId: (userId) => directory.byId.get(userId)
56713
+ });
56618
56714
  var createMessageRefCache = (maxSize = 1e4) => {
56619
56715
  const map32 = new Map;
56620
56716
  return {
@@ -56713,7 +56809,8 @@ var decodeSenderIdentity = (message, directory) => {
56713
56809
  });
56714
56810
  };
56715
56811
  var messageToInboundEvents = (message, directory, boundIdentity, base, renderedFor) => exports_Effect.gen(function* () {
56716
- const sender = yield* decodeSenderIdentity(message, directory);
56812
+ const covered = yield* directory.cover([message.sender_id]);
56813
+ const sender = yield* decodeSenderIdentity(message, covered);
56717
56814
  const ref = yield* decodeMessageRef(message, base);
56718
56815
  const body = yield* decodeMessageBody(message.content);
56719
56816
  const ts = yield* decodeTimestamp(message.timestamp);
@@ -56722,10 +56819,7 @@ var messageToInboundEvents = (message, directory, boundIdentity, base, renderedF
56722
56819
  sender,
56723
56820
  body,
56724
56821
  ts,
56725
- mentions: yield* mentionsOfMessage(renderedFor, message, {
56726
- byName: directory.byName,
56727
- byUserId: (userId) => directory.byId.get(userId)
56728
- }),
56822
+ mentions: yield* mentionsOfMessage(renderedFor, message, (userIds) => covered.cover(userIds).pipe(exports_Effect.map(mentionDirectoryOf))),
56729
56823
  reactions: []
56730
56824
  };
56731
56825
  const out = [{ kind: "message-posted", message: portMessage }];
@@ -56759,7 +56853,7 @@ var decodeReactionIdentity = (reaction, directory) => {
56759
56853
  });
56760
56854
  };
56761
56855
  var reactionToInboundEvent = (reaction, directory, target) => exports_Effect.gen(function* () {
56762
- const by = yield* decodeReactionIdentity(reaction, directory);
56856
+ const by = yield* decodeReactionIdentity(reaction, yield* directory.cover([reaction.user_id]));
56763
56857
  const emoji2 = yield* decodeEmoji(reaction.emoji_name);
56764
56858
  return {
56765
56859
  kind: reactionKind(reaction.op),
@@ -56794,8 +56888,8 @@ var fetchMessageRef = (http, messageId, base) => http.get("/messages", singleMes
56794
56888
  }).pipe(exports_Effect.flatMap((res) => {
56795
56889
  const message = res.messages[0];
56796
56890
  if (message === undefined || message.id !== messageId)
56797
- return exports_Effect.succeed(exports_Option.none());
56798
- return decodeMessageRef(message, base).pipe(exports_Effect.map(exports_Option.some));
56891
+ return exports_Effect.succeedNone;
56892
+ return decodeMessageRef(message, base).pipe(exports_Effect.asSome);
56799
56893
  }));
56800
56894
  var describeError = (err) => messageOf(err);
56801
56895
  var markReplayed = (events) => events.map((ev) => {
@@ -57111,7 +57205,10 @@ var makeZulipHttp = (config3) => exports_Effect.gen(function* () {
57111
57205
  ...hostHeader === undefined ? {} : { host: hostHeader }
57112
57206
  })));
57113
57207
  const resolvePath = (path) => path.startsWith("/") ? exports_Effect.succeed(base + path) : exports_Effect.die(new TypeError(`ZulipHttp path must start with '/' — received: ${JSON.stringify(path)}`));
57114
- const attempt = (url3, request2) => httpClient.execute(request2).pipe(exports_Effect.flatMap((response) => response.text.pipe(exports_Effect.mapError((cause3) => transportError(url3, cause3)), exports_Effect.flatMap((text3) => classifyEnvelope(text3, response.status, url3)))), exports_Effect.catchTag("RequestError", (cause3) => exports_Effect.fail(transportError(url3, cause3))), exports_Effect.catchTag("ResponseError", (cause3) => exports_Effect.fail(transportError(url3, cause3))));
57208
+ const attempt = (url3, request2) => httpClient.execute(request2).pipe(exports_Effect.flatMap((response) => response.text.pipe(exports_Effect.mapError((cause3) => transportError(url3, cause3)), exports_Effect.flatMap((text3) => classifyEnvelope(text3, response.status, url3)))), exports_Effect.catchTags({
57209
+ RequestError: (cause3) => exports_Effect.fail(transportError(url3, cause3)),
57210
+ ResponseError: (cause3) => exports_Effect.fail(transportError(url3, cause3))
57211
+ }));
57115
57212
  const sendWithRetry = (url3, request2) => attempt(url3, request2).pipe(exports_Effect.retry({ schedule: rateLimitSchedule() }));
57116
57213
  const sendJson = (url3, request2, schema) => {
57117
57214
  const decode8 = exports_Schema.decodeUnknown(exports_Schema.parseJson(schema));
@@ -57142,7 +57239,10 @@ var makeZulipHttp = (config3) => exports_Effect.gen(function* () {
57142
57239
  data: new Uint8Array(buf),
57143
57240
  contentType: response.headers["content-type"] ?? "application/octet-stream"
57144
57241
  })), exports_Effect.mapError((cause3) => transportError(url3, cause3)));
57145
- }), exports_Effect.catchTag("RequestError", (cause3) => exports_Effect.fail(transportError(url3, cause3))), exports_Effect.catchTag("ResponseError", (cause3) => exports_Effect.fail(transportError(url3, cause3))));
57242
+ }), exports_Effect.catchTags({
57243
+ RequestError: (cause3) => exports_Effect.fail(transportError(url3, cause3)),
57244
+ ResponseError: (cause3) => exports_Effect.fail(transportError(url3, cause3))
57245
+ }));
57146
57246
  })() : exports_Effect.die(new TypeError(`ZulipHttp realmPath must start with '/' — received: ${JSON.stringify(realmPath)}`)),
57147
57247
  uploadRaw: (filename, data) => resolvePath("/user_uploads").pipe(exports_Effect.flatMap((url3) => {
57148
57248
  const form = new FormData;
@@ -57205,6 +57305,10 @@ var sentMessageSchema = exports_Schema.Struct({
57205
57305
  id: exports_Schema.Int
57206
57306
  });
57207
57307
  var successSchema2 = exports_Schema.Struct({ result: exports_Schema.Literal("success") });
57308
+ var renderedSchema = exports_Schema.Struct({
57309
+ result: exports_Schema.Literal("success"),
57310
+ rendered: exports_Schema.String
57311
+ });
57208
57312
  var classifyEditFailure = (cause3) => {
57209
57313
  if (cause3 instanceof ZulipApiError) {
57210
57314
  const text3 = cause3.message.toLowerCase();
@@ -57302,7 +57406,9 @@ var toIdentity = (u) => exports_Effect.all({
57302
57406
  kind: u.is_bot ? "agent" : "human"
57303
57407
  })));
57304
57408
  var isActiveOfKind = (kind) => (u) => u.is_active && (kind === "agent" ? u.is_bot : !u.is_bot);
57305
- var streamIsListening = (state, channelName) => exports_HashSet.has(state.subscribedChannels, channelName) || exports_HashSet.has(state.newTopicsChannels, channelName);
57409
+ var heldNarrowOf = (target) => exports_Predicate.isString(target) ? exports_Data.struct({ channel: target, thread: exports_Option.none() }) : exports_Data.struct({ channel: target.channel, thread: exports_Option.some(target.thread) });
57410
+ var holdsChannel = (state, channelName) => exports_HashSet.some(state.heldNarrows, (narrow) => narrow.channel === channelName);
57411
+ var streamIsListening = (state, channelName) => holdsChannel(state, channelName) || exports_HashSet.has(state.newTopicsChannels, channelName);
57306
57412
  var observeNewTopic = (state, channelName, threadName3) => {
57307
57413
  const seen = exports_HashMap.get(state.seenTopicsByChannel, channelName).pipe(exports_Option.getOrElse(() => exports_HashSet.empty()));
57308
57414
  if (exports_HashSet.has(seen, threadName3))
@@ -57339,7 +57445,8 @@ var zulipAdapter = (config3) => exports_Effect.gen(function* () {
57339
57445
  })));
57340
57446
  const boundHttp = () => bindOnDemand.pipe(exports_Effect.zipRight(requireBound()), exports_Effect.map((b) => b.http));
57341
57447
  const fetchMembers = () => minterHttp.get("/users", usersSchema).pipe(exports_Effect.map((res) => res.members));
57342
- const buildDirectoryLookup = () => fetchMembers().pipe(exports_Effect.flatMap((members) => exports_Effect.gen(function* () {
57448
+ const fetchMembersById = (userIds) => minterHttp.get("/users", usersSchema, { user_ids: JSON.stringify(userIds) }).pipe(exports_Effect.map((res) => res.members));
57449
+ const directoryOf = (members) => exports_Effect.gen(function* () {
57343
57450
  const byId = new Map;
57344
57451
  const byName = new Map;
57345
57452
  const byIdentityId = new Map;
@@ -57352,11 +57459,23 @@ var zulipAdapter = (config3) => exports_Effect.gen(function* () {
57352
57459
  if (u.is_active)
57353
57460
  active2.add(ident.id);
57354
57461
  }
57355
- return { byId, byName, byIdentityId, active: active2 };
57356
- })));
57462
+ const lookup = {
57463
+ byId,
57464
+ byName,
57465
+ byIdentityId,
57466
+ active: active2,
57467
+ cover: (userIds) => {
57468
+ const missing = exports_Array.dedupe(userIds.filter((id3) => !byId.has(ZulipUserRef(id3))));
57469
+ return exports_Array.isEmptyReadonlyArray(missing) ? exports_Effect.succeed(lookup) : fetchMembersById(missing).pipe(exports_Effect.flatMap((found) => directoryOf([...members, ...found])));
57470
+ }
57471
+ };
57472
+ return lookup;
57473
+ });
57474
+ const buildDirectoryLookup = () => fetchMembers().pipe(exports_Effect.flatMap(directoryOf));
57357
57475
  const recipientDirectory = () => buildDirectoryLookup().pipe(exports_Effect.map((lookup) => ({
57358
57476
  byId: new Map([...lookup.byId.entries()].map(([id3, ident]) => [id3, { kind: ident.kind }]))
57359
57477
  })));
57478
+ const renderedMentionIds = (content) => minterHttp.post("/messages/render", renderedSchema, { content }).pipe(exports_Effect.map((res) => mentionedUserIds(res.rendered)));
57360
57479
  const mentionDirectory = (directory2) => ({
57361
57480
  byName: directory2.byName,
57362
57481
  byUserId: (userId) => directory2.byId.get(ZulipUserRef(userId))
@@ -57373,8 +57492,8 @@ var zulipAdapter = (config3) => exports_Effect.gen(function* () {
57373
57492
  };
57374
57493
  const validateOutboundMentions = (operation, body) => !mentionTokens(body).some(MentionToken.$is("UserToken")) ? exports_Effect.void : buildDirectoryLookup().pipe(exports_Effect.flatMap((directory2) => {
57375
57494
  const dead = unresolvedMentions(body, notifiableMentionDirectory(directory2));
57376
- return dead.length === 0 ? exports_Effect.void : exports_Effect.fail(new UnresolvedMention({ operation, tokens: dead, substrate: "zulip" }));
57377
- }));
57495
+ return exports_Array.isEmptyReadonlyArray(dead) ? exports_Effect.succeed(dead) : renderedMentionIds(body).pipe(exports_Effect.flatMap(directory2.cover), exports_Effect.map((covered) => unresolvedMentions(body, notifiableMentionDirectory(covered))));
57496
+ }), exports_Effect.flatMap((dead) => exports_Array.isEmptyReadonlyArray(dead) ? exports_Effect.void : exports_Effect.fail(new UnresolvedMention({ operation, tokens: dead, substrate: "zulip" }))));
57378
57497
  const mapHistoricalReactions = (raw3, directory2) => exports_Effect.gen(function* () {
57379
57498
  const byEmoji = new Map;
57380
57499
  for (const r of raw3) {
@@ -57408,7 +57527,7 @@ var zulipAdapter = (config3) => exports_Effect.gen(function* () {
57408
57527
  sender,
57409
57528
  body,
57410
57529
  ts: m.ts,
57411
- mentions: yield* mentionsOfMessage(renderedFor, { id: Number(m.id), content: m.content }, mentionDirectory(directory2)),
57530
+ mentions: yield* mentionsOfMessage(renderedFor, { id: Number(m.id), content: m.content }, (userIds) => directory2.cover(userIds).pipe(exports_Effect.map(mentionDirectory))),
57412
57531
  reactions
57413
57532
  };
57414
57533
  });
@@ -57426,7 +57545,7 @@ var zulipAdapter = (config3) => exports_Effect.gen(function* () {
57426
57545
  onPage: (query, rows) => exports_Effect.gen(function* () {
57427
57546
  const renderedFor = yield* renderedContentForBatch(minterHttp, query, rows);
57428
57547
  const historical = yield* exports_Effect.forEach(rows, toHistoricalMessage);
57429
- const directory2 = yield* exports_Fiber.join(directoryFiber);
57548
+ const directory2 = yield* exports_Fiber.join(directoryFiber).pipe(exports_Effect.flatMap((d) => d.cover(historical.flatMap((m) => [m.senderId, ...m.reactions.map((r) => r.userId)]))));
57430
57549
  return yield* exports_Effect.forEach(historical, (m) => mapHistoricalMessage(m, directory2, renderedFor));
57431
57550
  })
57432
57551
  });
@@ -57533,10 +57652,16 @@ var zulipAdapter = (config3) => exports_Effect.gen(function* () {
57533
57652
  onNone: () => exports_Effect.succeed([undefined, current2]),
57534
57653
  onSome: (existing) => (opts?.persistent === true ? exports_Effect.void : minterHttp.delete(`/bots/${existing.userId}`, successSchema2).pipe(exports_Effect.asVoid, exports_Effect.catchAll(() => exports_Effect.void))).pipe(exports_Effect.as([undefined, exports_Option.none()]))
57535
57654
  })).pipe(exports_Effect.asVoid),
57536
- resolve: (name) => minterHttp.get("/users", usersSchema).pipe(exports_Effect.flatMap((res) => exports_Array.findFirst(res.members, (u) => u.is_active && u.full_name === name).pipe(exports_Option.match({
57537
- onNone: () => exports_Effect.succeed(exports_Option.none()),
57538
- onSome: (match23) => toIdentity(match23).pipe(exports_Effect.map(exports_Option.some))
57539
- }))), exports_Effect.mapError((cause3) => new IdentityError({ operation: "resolve", cause: cause3 })))
57655
+ resolve: (name) => {
57656
+ const activeNamed = (members) => exports_Array.findFirst(members, (u) => u.is_active && u.full_name === name);
57657
+ return fetchMembers().pipe(exports_Effect.flatMap((members) => exports_Option.match(activeNamed(members), {
57658
+ onSome: (match23) => exports_Effect.succeedSome(match23),
57659
+ onNone: () => renderedMentionIds(`@**${name}**`).pipe(exports_Effect.flatMap((userIds) => exports_Array.isEmptyReadonlyArray(userIds) ? exports_Effect.succeed([]) : fetchMembersById(userIds)), exports_Effect.map(activeNamed))
57660
+ })), exports_Effect.flatMap(exports_Option.match({
57661
+ onNone: () => exports_Effect.succeed(exports_Option.none()),
57662
+ onSome: (match23) => toIdentity(match23).pipe(exports_Effect.asSome)
57663
+ })), exports_Effect.mapError((cause3) => new IdentityError({ operation: "resolve", cause: cause3 })));
57664
+ }
57540
57665
  };
57541
57666
  const directory = {
57542
57667
  listAgents: () => fetchMembers().pipe(exports_Effect.flatMap((members) => exports_Effect.forEach(members.filter(isActiveOfKind("agent")), toIdentity)), exports_Effect.mapError((cause3) => new DirectoryError({ operation: "listAgents", cause: cause3 }))),
@@ -57600,14 +57725,14 @@ var zulipAdapter = (config3) => exports_Effect.gen(function* () {
57600
57725
  const lookupChannel = (name) => exports_Ref.get(knownStreamsRef).pipe(exports_Effect.flatMap(exports_Option.match({
57601
57726
  onNone: () => refreshKnownStreams(),
57602
57727
  onSome: exports_Effect.succeed
57603
- })), exports_Effect.flatMap((map32) => map32.has(name) ? exports_Effect.succeed(map32) : refreshKnownStreams()), exports_Effect.map((map32) => exports_Option.fromNullable(map32.get(name))));
57728
+ })), exports_Effect.filterOrElse((map32) => map32.has(name), () => refreshKnownStreams()), exports_Effect.map((map32) => exports_Option.fromNullable(map32.get(name))));
57604
57729
  const resolvePublishChannel = (requested) => lookupChannel(requested).pipe(exports_Effect.flatMap(exports_Option.match({
57605
57730
  onNone: () => exports_Effect.fail(new UnknownChannel({ channel: requested, substrate: "zulip" })),
57606
57731
  onSome: exports_Effect.succeed
57607
57732
  })));
57608
57733
  const fetchChannelDescription = (channel) => minterHttp.get(`/streams/${encodeURIComponent(channel.id)}`, streamResponseSchema).pipe(exports_Effect.flatMap((res) => exports_Option.match(fromWireDescription(res.stream.description), {
57609
57734
  onNone: () => exports_Effect.succeed(exports_Option.none()),
57610
- onSome: (raw3) => decodeChannelDescription(raw3).pipe(exports_Effect.map(exports_Option.some))
57735
+ onSome: (raw3) => decodeChannelDescription(raw3).pipe(exports_Effect.asSome)
57611
57736
  })));
57612
57737
  const setChannelDescription = (channel, description) => resolvePublishChannel(channel).pipe(exports_Effect.flatMap((channelRef) => exports_Option.match(exports_Option.flatMap(description, (text3) => rejectionFor(channelRef.name, text3)), {
57613
57738
  onSome: (rejection) => exports_Effect.fail(rejection),
@@ -57625,7 +57750,7 @@ var zulipAdapter = (config3) => exports_Effect.gen(function* () {
57625
57750
  apply_markdown: false
57626
57751
  }).pipe(exports_Effect.flatMap((res) => exports_Array.last(res.messages).pipe(exports_Option.match({
57627
57752
  onNone: () => exports_Effect.succeed(exports_Option.none()),
57628
- onSome: (m) => decodeMessageId(String(m.id)).pipe(exports_Effect.map(exports_Option.some))
57753
+ onSome: (m) => decodeMessageId(String(m.id)).pipe(exports_Effect.asSome)
57629
57754
  }))));
57630
57755
  const setThreadResolved = (channel, thread, resolved) => {
57631
57756
  const operation = resolved ? "resolveThread" : "unresolveThread";
@@ -57683,7 +57808,7 @@ var zulipAdapter = (config3) => exports_Effect.gen(function* () {
57683
57808
  setChannelDescription
57684
57809
  };
57685
57810
  const inboxRef = yield* exports_SynchronizedRef.make({
57686
- subscribedChannels: exports_HashSet.empty(),
57811
+ heldNarrows: exports_HashSet.empty(),
57687
57812
  newTopicsChannels: exports_HashSet.empty(),
57688
57813
  seenTopicsByChannel: exports_HashMap.empty(),
57689
57814
  registration: exports_Option.none()
@@ -57706,7 +57831,7 @@ var zulipAdapter = (config3) => exports_Effect.gen(function* () {
57706
57831
  onNone: () => [false, state],
57707
57832
  onSome: (t) => observeNewTopic(state, cname, t.name)
57708
57833
  });
57709
- if (exports_HashSet.has(state.subscribedChannels, cname))
57834
+ if (holdsChannel(state, cname))
57710
57835
  return [true, ticked];
57711
57836
  if (me !== undefined && mentionsIdentity(message.mentions, me.id)) {
57712
57837
  return [true, ticked];
@@ -57731,7 +57856,7 @@ var zulipAdapter = (config3) => exports_Effect.gen(function* () {
57731
57856
  newTopicsChannels: exports_HashSet.add(state.newTopicsChannels, channel)
57732
57857
  } : {
57733
57858
  ...state,
57734
- subscribedChannels: exports_HashSet.add(state.subscribedChannels, channel)
57859
+ heldNarrows: exports_HashSet.add(state.heldNarrows, heldNarrowOf(target))
57735
57860
  };
57736
57861
  return [wasListening, next4];
57737
57862
  }).pipe(exports_Effect.flatMap((wasListening) => {
@@ -57751,7 +57876,7 @@ var zulipAdapter = (config3) => exports_Effect.gen(function* () {
57751
57876
  seenTopicsByChannel: exports_HashMap.remove(state.seenTopicsByChannel, channel)
57752
57877
  } : {
57753
57878
  ...state,
57754
- subscribedChannels: exports_HashSet.remove(state.subscribedChannels, channel)
57879
+ heldNarrows: exports_HashSet.remove(state.heldNarrows, heldNarrowOf(target))
57755
57880
  };
57756
57881
  return [streamIsListening(next4, channel), next4];
57757
57882
  }).pipe(exports_Effect.flatMap((stillListening) => stillListening ? exports_Effect.void : http.delete("/users/me/subscriptions", subscriptionsResponseSchema, {
@@ -57806,7 +57931,7 @@ var zulipAdapter = (config3) => exports_Effect.gen(function* () {
57806
57931
  fetchPage: (query) => minterHttp.get("/messages", replayResponseSchema, query).pipe(exports_Effect.map((res) => res.messages)),
57807
57932
  onPage: (query, rows) => exports_Effect.gen(function* () {
57808
57933
  const renderedFor = yield* renderedContentForBatch(minterHttp, query, rows);
57809
- const directory2 = yield* exports_Fiber.join(directoryFiber);
57934
+ const directory2 = yield* exports_Fiber.join(directoryFiber).pipe(exports_Effect.flatMap((d) => d.cover(rows.map((row) => row.sender_id))));
57810
57935
  return yield* exports_Effect.forEach(rows, (raw3) => {
57811
57936
  const { flags: _flags, ...message } = raw3;
57812
57937
  return messageToInboundEvents(message, directory2, exports_Option.getOrUndefined(current2)?.identity, base, renderedFor);
@@ -57834,7 +57959,7 @@ var zulipAdapter = (config3) => exports_Effect.gen(function* () {
57834
57959
  { operator: "channel", operand: channel },
57835
57960
  { operator: "topic", operand: topic }
57836
57961
  ]);
57837
- return readTopic(threadName3).pipe(exports_Effect.flatMap((messages) => messages.length > 0 ? exports_Effect.succeed(messages) : readTopic(applyResolvedPrefix(threadName3, true))), exports_Effect.mapError((cause3) => new HistoryError({ operation: "readThread", cause: cause3 })));
57962
+ return readTopic(threadName3).pipe(exports_Effect.filterOrElse((messages) => messages.length > 0, () => readTopic(applyResolvedPrefix(threadName3, true))), exports_Effect.mapError((cause3) => new HistoryError({ operation: "readThread", cause: cause3 })));
57838
57963
  },
57839
57964
  recentThreads: (sender, opts) => {
57840
57965
  const limit = opts?.limit ?? RECENT_THREADS_DEFAULT_LIMIT;
@@ -57903,7 +58028,7 @@ var buildQueueStateHooks = (deps) => {
57903
58028
  queueIdleTimeoutSecs: idleTimeoutSecs,
57904
58029
  onQueueRegister: (queue) => withSession((id3) => exports_Deferred.poll(resumeOutcome).pipe(exports_Effect.flatMap(exports_Option.match({
57905
58030
  onSome: () => store.write(id3, queue),
57906
- onNone: () => store.read(id3).pipe(exports_Effect.map(exports_Option.isNone), exports_Effect.catchAll(() => exports_Effect.succeed(true)), exports_Effect.flatMap((isFresh3) => isFresh3 ? store.write(id3, queue) : exports_Effect.void))
58031
+ onNone: () => store.read(id3).pipe(exports_Effect.map(exports_Option.isNone), exports_Effect.orElseSucceed(() => true), exports_Effect.flatMap((isFresh3) => isFresh3 ? store.write(id3, queue) : exports_Effect.void))
57907
58032
  })), exports_Effect.catchAllCause(() => exports_Effect.void))),
57908
58033
  onQueueAdvance: (lastEventId) => withSession((id3) => store.advance(id3, lastEventId).pipe(exports_Effect.catchAllCause(() => exports_Effect.void))),
57909
58034
  resumeQueue: () => exports_Deferred.poll(session).pipe(exports_Effect.flatMap(exports_Option.match({
@@ -57925,7 +58050,7 @@ var QueueStateFileSchema = exports_Schema.parseJson(exports_Schema.Struct({ queu
57925
58050
  var decodeQueueStateFile = exports_Schema.decodeUnknown(QueueStateFileSchema);
57926
58051
  var encodeQueueStateFile = exports_Schema.encode(QueueStateFileSchema);
57927
58052
  var isNotFound = (error2) => error2._tag === "SystemError" && error2.reason === "NotFound";
57928
- var readState = (fs, path) => fs.readFileString(path).pipe(exports_Effect.flatMap(decodeQueueStateFile), exports_Effect.map(exports_Option.some), exports_Effect.catchIf(isNotFound, () => exports_Effect.succeed(exports_Option.none())));
58053
+ var readState = (fs, path) => fs.readFileString(path).pipe(exports_Effect.flatMap(decodeQueueStateFile), exports_Effect.asSome, exports_Effect.catchIf(isNotFound, () => exports_Effect.succeed(exports_Option.none())));
57929
58054
  var createFileQueueStateStore = (deps) => {
57930
58055
  const { dir, fs } = deps;
57931
58056
  const pathFor = (id3) => join7(dir, stateFilename(id3));
@@ -58204,7 +58329,7 @@ var basename2 = (path) => {
58204
58329
  };
58205
58330
  var deriveProject = (deps) => {
58206
58331
  if (deps.project !== undefined) {
58207
- return exports_Effect.succeed(exports_Option.some(deps.project));
58332
+ return exports_Effect.succeedSome(deps.project);
58208
58333
  }
58209
58334
  return exports_Effect.map(deps.readGitContext(deps.cwd), (context9) => matchGitContext(context9, {
58210
58335
  NotInRepo: () => exports_Option.none(),
@@ -58214,7 +58339,7 @@ var deriveProject = (deps) => {
58214
58339
  })
58215
58340
  }));
58216
58341
  };
58217
- var gitStdout = (cwd, args2) => exports_Command.make("git", "-C", cwd, ...args2).pipe(exports_Command.stderr("pipe"), exports_Command.string, exports_Effect.map((out) => out.trim()), exports_Effect.catchAll(() => exports_Effect.succeed("")));
58342
+ var gitStdout = (cwd, args2) => exports_Command.make("git", "-C", cwd, ...args2).pipe(exports_Command.stderr("pipe"), exports_Command.string, exports_Effect.map((out) => out.trim()), exports_Effect.orElseSucceed(() => ""));
58218
58343
  var readGitContext = (cwd) => exports_Effect.gen(function* () {
58219
58344
  const gitRoot = yield* gitStdout(cwd, ["rev-parse", "--show-toplevel"]);
58220
58345
  if (gitRoot.length === 0)
@@ -58602,7 +58727,7 @@ var createEphemeralIdentityCache = (deps) => exports_Effect.map(exports_Synchron
58602
58727
  releaseAllBound: () => releaseBoundSlot
58603
58728
  };
58604
58729
  });
58605
- // node_modules/.bun/@modelcontextprotocol+sdk@1.29.0/node_modules/@modelcontextprotocol/sdk/dist/esm/server/zod-compat.js
58730
+ // node_modules/.bun/@modelcontextprotocol+sdk@1.30.1/node_modules/@modelcontextprotocol/sdk/dist/esm/server/zod-compat.js
58606
58731
  function isZ4Schema(s) {
58607
58732
  const schema = s;
58608
58733
  return !!schema._zod;
@@ -58665,7 +58790,7 @@ function getLiteralValue(schema) {
58665
58790
  return;
58666
58791
  }
58667
58792
 
58668
- // node_modules/.bun/@modelcontextprotocol+sdk@1.29.0/node_modules/@modelcontextprotocol/sdk/dist/esm/experimental/tasks/interfaces.js
58793
+ // node_modules/.bun/@modelcontextprotocol+sdk@1.30.1/node_modules/@modelcontextprotocol/sdk/dist/esm/experimental/tasks/interfaces.js
58669
58794
  function isTerminal(status3) {
58670
58795
  return status3 === "completed" || status3 === "failed" || status3 === "cancelled";
58671
58796
  }
@@ -58674,7 +58799,7 @@ function isTerminal(status3) {
58674
58799
  var ignoreOverride = Symbol("Let zodToJsonSchema decide on which parser to use");
58675
58800
  // node_modules/.bun/zod-to-json-schema@3.25.2+68a1e3a0c4588df3/node_modules/zod-to-json-schema/dist/esm/parsers/string.js
58676
58801
  var ALPHA_NUMERIC = new Set("ABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvxyz0123456789");
58677
- // node_modules/.bun/@modelcontextprotocol+sdk@1.29.0/node_modules/@modelcontextprotocol/sdk/dist/esm/server/zod-json-schema-compat.js
58802
+ // node_modules/.bun/@modelcontextprotocol+sdk@1.30.1/node_modules/@modelcontextprotocol/sdk/dist/esm/server/zod-json-schema-compat.js
58678
58803
  function getMethodLiteral(schema) {
58679
58804
  const shape = getObjectShape(schema);
58680
58805
  const methodSchema = shape?.method;
@@ -58695,7 +58820,7 @@ function parseWithCompat(schema, data) {
58695
58820
  return result.data;
58696
58821
  }
58697
58822
 
58698
- // node_modules/.bun/@modelcontextprotocol+sdk@1.29.0/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/protocol.js
58823
+ // node_modules/.bun/@modelcontextprotocol+sdk@1.30.1/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/protocol.js
58699
58824
  var DEFAULT_REQUEST_TIMEOUT_MSEC = 60000;
58700
58825
 
58701
58826
  class Protocol {
@@ -59536,7 +59661,7 @@ function mergeCapabilities(base, additional) {
59536
59661
  return result;
59537
59662
  }
59538
59663
 
59539
- // node_modules/.bun/@modelcontextprotocol+sdk@1.29.0/node_modules/@modelcontextprotocol/sdk/dist/esm/validation/ajv-provider.js
59664
+ // node_modules/.bun/@modelcontextprotocol+sdk@1.30.1/node_modules/@modelcontextprotocol/sdk/dist/esm/validation/ajv-provider.js
59540
59665
  var import_ajv = __toESM(require_ajv(), 1);
59541
59666
  var import_ajv_formats = __toESM(require_dist(), 1);
59542
59667
  function createDefaultAjvInstance() {
@@ -59576,7 +59701,7 @@ class AjvJsonSchemaValidator {
59576
59701
  }
59577
59702
  }
59578
59703
 
59579
- // node_modules/.bun/@modelcontextprotocol+sdk@1.29.0/node_modules/@modelcontextprotocol/sdk/dist/esm/experimental/tasks/server.js
59704
+ // node_modules/.bun/@modelcontextprotocol+sdk@1.30.1/node_modules/@modelcontextprotocol/sdk/dist/esm/experimental/tasks/server.js
59580
59705
  class ExperimentalServerTasks {
59581
59706
  constructor(_server) {
59582
59707
  this._server = _server;
@@ -59654,7 +59779,7 @@ class ExperimentalServerTasks {
59654
59779
  }
59655
59780
  }
59656
59781
 
59657
- // node_modules/.bun/@modelcontextprotocol+sdk@1.29.0/node_modules/@modelcontextprotocol/sdk/dist/esm/experimental/tasks/helpers.js
59782
+ // node_modules/.bun/@modelcontextprotocol+sdk@1.30.1/node_modules/@modelcontextprotocol/sdk/dist/esm/experimental/tasks/helpers.js
59658
59783
  function assertToolsCallTaskCapability(requests, method, entityName) {
59659
59784
  if (!requests) {
59660
59785
  throw new Error(`${entityName} does not support task creation (required for ${method})`);
@@ -59689,7 +59814,7 @@ function assertClientRequestTaskCapability(requests, method, entityName) {
59689
59814
  }
59690
59815
  }
59691
59816
 
59692
- // node_modules/.bun/@modelcontextprotocol+sdk@1.29.0/node_modules/@modelcontextprotocol/sdk/dist/esm/server/index.js
59817
+ // node_modules/.bun/@modelcontextprotocol+sdk@1.30.1/node_modules/@modelcontextprotocol/sdk/dist/esm/server/index.js
59693
59818
  class Server extends Protocol {
59694
59819
  constructor(_serverInfo, options5) {
59695
59820
  super(options5);
@@ -59737,16 +59862,7 @@ class Server extends Protocol {
59737
59862
  if (!methodSchema) {
59738
59863
  throw new Error("Schema is missing a method literal");
59739
59864
  }
59740
- let methodValue;
59741
- if (isZ4Schema(methodSchema)) {
59742
- const v4Schema = methodSchema;
59743
- const v4Def = v4Schema._zod?.def;
59744
- methodValue = v4Def?.value ?? v4Schema.value;
59745
- } else {
59746
- const v3Schema = methodSchema;
59747
- const legacyDef = v3Schema._def;
59748
- methodValue = legacyDef?.value ?? v3Schema.value;
59749
- }
59865
+ const methodValue = getLiteralValue(methodSchema);
59750
59866
  if (typeof methodValue !== "string") {
59751
59867
  throw new Error("Schema method literal must be a string");
59752
59868
  }
@@ -60023,7 +60139,7 @@ class Server extends Protocol {
60023
60139
  }
60024
60140
 
60025
60141
  // packages/mcp/mcp-server.ts
60026
- var PLUGIN_VERSION = "0.24.1";
60142
+ var PLUGIN_VERSION = "0.24.3";
60027
60143
  var COMMY_INSTRUCTIONS = `**Substrate.** commy is the inter-agent channel: agents and humans coordinate here. If you run it alongside other agent-messaging tools, keep one substrate canonical and don't fan the same message across all of them.
60028
60144
 
60029
60145
  **Channels.** Each project has one channel: \`#<project-slug>\` where the slug is resolved per session as \`COMMY_PROJECT\` env > git remote \`origin\` basename > git root basename. Sessions launched outside a git repo (e.g. \`/tmp\`, \`$HOME\`) have no project channel and should post to \`#general\` instead. Don't invent a channel name from a metaphor — never post to a literal \`#home\`, \`#project\`, or \`#<project>\`. Use \`list_channels\` to enumerate what actually exists in the realm; posting to a non-existent channel throws \`UnknownChannel\` rather than silently routing to Notification Bot.
@@ -60177,7 +60293,7 @@ var subscriptionFilename = (id3) => {
60177
60293
  return `${safe}.json`;
60178
60294
  };
60179
60295
  var isNotFound3 = (error2) => error2._tag === "SystemError" && error2.reason === "NotFound";
60180
- var readSubscriptions = (fs, id3, path) => fs.readFileString(path).pipe(exports_Effect.flatMap((raw3) => decodeSubscriptionsFile(id3, raw3)), exports_Effect.map((intents) => exports_Option.some(intents)), exports_Effect.catchIf(isNotFound3, () => exports_Effect.succeed(exports_Option.none())));
60296
+ var readSubscriptions = (fs, id3, path) => fs.readFileString(path).pipe(exports_Effect.flatMap((raw3) => decodeSubscriptionsFile(id3, raw3)), exports_Effect.asSome, exports_Effect.catchIf(isNotFound3, () => exports_Effect.succeed(exports_Option.none())));
60181
60297
  var createFileSubscriptionStore = (deps) => {
60182
60298
  const { dir, fs, session } = deps;
60183
60299
  const pathFor = (id3) => join9(dir, subscriptionFilename(id3));
@@ -60368,7 +60484,7 @@ var DownloadFileArgs = exports_Schema.Struct({ url_path: exports_Schema.String }
60368
60484
  var UploadFileArgs = exports_Schema.Struct({ path: exports_Schema.String });
60369
60485
  var buildToolDefs = (deps, cache) => {
60370
60486
  const { adapter: adapter4, identityCache, narrowSet } = deps;
60371
- const projectForCwd = deps.projectForCwd ?? (() => exports_Effect.succeed(undefined));
60487
+ const projectForCwd = deps.projectForCwd ?? (() => exports_Effect.succeedNone);
60372
60488
  const hostSuppliedSessionId = ["session_id"];
60373
60489
  const cwdField = {
60374
60490
  type: "string",
@@ -60383,7 +60499,10 @@ var buildToolDefs = (deps, cache) => {
60383
60499
  const projectForArgs = (args2) => projectForCwd(readCwd(args2));
60384
60500
  const runFor = (args2) => (effect4) => {
60385
60501
  const sessionId = readSessionId(args2);
60386
- return runEdge(projectForArgs(args2).pipe(exports_Effect.flatMap((project3) => feedSession(sessionId).pipe(exports_Effect.zipRight(withSessionContext(effect4, { sessionId, project: project3 }))))));
60502
+ return runEdge(projectForArgs(args2).pipe(exports_Effect.flatMap((project3) => feedSession(sessionId).pipe(exports_Effect.zipRight(withSessionContext(effect4, {
60503
+ sessionId,
60504
+ project: exports_Option.getOrUndefined(project3)
60505
+ }))))));
60387
60506
  };
60388
60507
  const stickyThreadEngagement = async (run6, channel, threadName3) => {
60389
60508
  if (exports_Option.isNone(threadName3))
@@ -60666,7 +60785,7 @@ var buildToolDefs = (deps, cache) => {
60666
60785
  const intent = yield* parseSubscribeTarget(raw3);
60667
60786
  const sessionId = readSessionId(args2);
60668
60787
  if (sessionId !== undefined && deps.ensureSessionSubscriptions !== undefined) {
60669
- yield* deps.ensureSessionSubscriptions(sessionId, yield* projectForArgs(args2));
60788
+ yield* deps.ensureSessionSubscriptions(sessionId, exports_Option.getOrUndefined(yield* projectForArgs(args2)));
60670
60789
  }
60671
60790
  yield* exports_Effect.sync(() => narrowSet.add(intent)).pipe(exports_Effect.andThen(adapter4.inbox.subscribe(intentToTarget(intent))));
60672
60791
  if (deps.persistSessionSubscriptions !== undefined) {
@@ -60699,7 +60818,7 @@ var buildToolDefs = (deps, cache) => {
60699
60818
  const intent = yield* parseSubscribeTarget(raw3);
60700
60819
  const sessionId = readSessionId(args2);
60701
60820
  if (sessionId !== undefined && deps.ensureSessionSubscriptions !== undefined) {
60702
- yield* deps.ensureSessionSubscriptions(sessionId, yield* projectForArgs(args2));
60821
+ yield* deps.ensureSessionSubscriptions(sessionId, exports_Option.getOrUndefined(yield* projectForArgs(args2)));
60703
60822
  }
60704
60823
  yield* exports_Effect.sync(() => narrowSet.remove(intent)).pipe(exports_Effect.andThen(adapter4.inbox.unsubscribe(intentToTarget(intent))));
60705
60824
  if (deps.persistSessionSubscriptions !== undefined) {
@@ -61068,7 +61187,7 @@ var makeProgram = (params = {}) => exports_Effect.scoped(exports_Effect.gen(func
61068
61187
  }));
61069
61188
  const reportNothingToResume = parsed.botName !== undefined ? exports_Effect.void : exports_Deferred.poll(sessionIdDeferred).pipe(exports_Effect.flatMap(exports_Option.match({
61070
61189
  onNone: () => exports_Effect.void,
61071
- onSome: (awaitId) => exports_Effect.flatMap(awaitId, (sessionId) => queueStateStore.read(sessionId).pipe(exports_Effect.map(exports_Option.isNone), exports_Effect.catchAll(() => exports_Effect.succeed(true)), exports_Effect.flatMap((nothingPersisted) => nothingPersisted ? exports_Deferred.succeed(resumeOutcome, false).pipe(exports_Effect.asVoid) : exports_Effect.void)))
61190
+ onSome: (awaitId) => exports_Effect.flatMap(awaitId, (sessionId) => queueStateStore.read(sessionId).pipe(exports_Effect.map(exports_Option.isNone), exports_Effect.orElseSucceed(() => true), exports_Effect.flatMap((nothingPersisted) => nothingPersisted ? exports_Deferred.succeed(resumeOutcome, false).pipe(exports_Effect.asVoid) : exports_Effect.void)))
61072
61191
  })));
61073
61192
  yield* reportNothingToResume;
61074
61193
  const feedSessionId = (sessionId) => exports_Deferred.succeed(sessionIdDeferred, sessionId).pipe(exports_Effect.asVoid);
@@ -61089,10 +61208,10 @@ var makeProgram = (params = {}) => exports_Effect.scoped(exports_Effect.gen(func
61089
61208
  const logSettingsFailure = (label) => (cause3) => exports_Effect.logWarning(`commy plugin: ${label} failed: ${exports_Cause.pretty(cause3)}`);
61090
61209
  const projectForCwd = (cwd) => {
61091
61210
  if (parsed.project !== undefined)
61092
- return exports_Effect.succeed(parsed.project);
61211
+ return exports_Effect.succeedSome(parsed.project);
61093
61212
  if (cwd === undefined)
61094
- return exports_Effect.succeed(undefined);
61095
- return exports_Effect.map(deriveProject({ cwd, readGitContext: readGitContext2 }), exports_Option.getOrUndefined);
61213
+ return exports_Effect.succeedNone;
61214
+ return deriveProject({ cwd, readGitContext: readGitContext2 });
61096
61215
  };
61097
61216
  const canEditMessages = yield* adapter4.publisher.editingAvailable().pipe(exports_Effect.catchAll((error2) => exports_Effect.logWarning(`commy plugin: could not read the realm's message-editing setting (${error2.message}); offering edit_message and letting the substrate refuse if it is off`).pipe(exports_Effect.as(true))));
61098
61217
  const narrowSet = createNarrowSet();
@@ -61100,12 +61219,12 @@ var makeProgram = (params = {}) => exports_Effect.scoped(exports_Effect.gen(func
61100
61219
  const notifier = params.notifier ?? channelNotifier(mcp);
61101
61220
  const registerType2Defaults = parsed.botName === undefined ? createType2DefaultsOnAcquire(narrowSet, adapter4.inbox) : undefined;
61102
61221
  const persistedTopicIntents = parsed.botName === undefined ? subscriptionStore.read() : exports_Effect.succeedNone;
61103
- const rebuildNarrowSet = (parsed.botName === undefined ? exports_Deferred.await(sessionIdDeferred).pipe(exports_Effect.map((sessionId) => sessionId)) : exports_Effect.succeed(undefined)).pipe(exports_Effect.flatMap((sessionId) => withSessionContext(restoreSubscriptions({
61222
+ const rebuildNarrowSet = (parsed.botName === undefined ? exports_Deferred.await(sessionIdDeferred).pipe(exports_Effect.asSome) : exports_Effect.succeedNone).pipe(exports_Effect.flatMap((sessionId) => withSessionContext(restoreSubscriptions({
61104
61223
  persisted: persistedTopicIntents,
61105
61224
  isBound: () => identityCache.boundIdentityIds().size > 0,
61106
61225
  narrowSet,
61107
61226
  inbox: adapter4.inbox
61108
- }), { sessionId, project: parsed.project })), exports_Effect.catchAll((err) => exports_Effect.logError(`commy plugin: could not rebuild the subscription set: ${exports_Predicate.isError(err) ? err.message : String(err)}`).pipe(exports_Effect.zipRight(exports_Effect.sync(() => narrowSet.load(exports_Option.none()))))), exports_Effect.provide(loggerLayer));
61227
+ }), { sessionId: exports_Option.getOrUndefined(sessionId), project: parsed.project })), exports_Effect.catchAll((err) => exports_Effect.logError(`commy plugin: could not rebuild the subscription set: ${exports_Predicate.isError(err) ? err.message : String(err)}`).pipe(exports_Effect.zipRight(exports_Effect.sync(() => narrowSet.load(exports_Option.none()))))), exports_Effect.provide(loggerLayer));
61109
61228
  const seedDefaults = (project3) => registerType2Defaults !== undefined ? registerType2Defaults(project3) : exports_Effect.void;
61110
61229
  const seedIfFresh = (sessionId, project3) => parsed.botName !== undefined ? exports_Effect.void : seedDefaultsIfFresh({ subscriptionStore, registerDefaults: seedDefaults }, project3).pipe(exports_Effect.catchAll((err) => exports_Effect.logError(`commy plugin: subscription seed check failed for ${sessionId}: ${exports_Predicate.isError(err) ? err.message : String(err)}`).pipe(exports_Effect.zipRight(seedDefaults(project3)))), exports_Effect.provide(loggerLayer));
61111
61230
  const ensureSessionSubscriptions = (sessionId, project3) => seedIfFresh(sessionId, project3);