@codeforbreakfast/commy-mcp 0.16.0 → 0.17.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/server.js +134 -47
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@codeforbreakfast/commy-mcp",
3
- "version": "0.16.0",
3
+ "version": "0.17.0",
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
@@ -6657,7 +6657,7 @@ var require_dist = __commonJS((exports, module) => {
6657
6657
  });
6658
6658
 
6659
6659
  // packages/mcp/server.ts
6660
- import { basename as basename2, join as join9 } from "node:path";
6660
+ import { basename as basename2, join as join10 } from "node:path";
6661
6661
  // node_modules/.bun/effect@3.21.4/node_modules/effect/dist/esm/Array.js
6662
6662
  var exports_Array = {};
6663
6663
  __export(exports_Array, {
@@ -56816,6 +56816,7 @@ var envConfigError = (issues) => new EnvConfigError({
56816
56816
  });
56817
56817
  var SessionIdSchema = exports_Schema.UUID.pipe(exports_Schema.brand("SessionId"));
56818
56818
  var parseSessionId = exports_Schema.decodeUnknownOption(SessionIdSchema);
56819
+ var readBootSessionId = exports_Effect.orElseSucceed(exports_Effect.map(exports_Config.option(exports_Config.string("CLAUDE_CODE_SESSION_ID")), exports_Option.flatMap(parseSessionId)), () => exports_Option.none());
56819
56820
  var BOT_NAME_RE = /^[a-z][a-z0-9_-]*$/;
56820
56821
  var parseBotName = (raw3) => {
56821
56822
  if (raw3.length === 0 || raw3.length > 40)
@@ -57163,6 +57164,35 @@ var createEnsureBound = (deps) => exports_Effect.map(exports_Ref.make({ kind: "i
57163
57164
  return ensureBound;
57164
57165
  });
57165
57166
 
57167
+ // packages/mcp/target-cursor.ts
57168
+ import { homedir as homedir2 } from "node:os";
57169
+ import { join as join8 } from "node:path";
57170
+ var deliveryTargetOf = (message) => exports_Data.struct({
57171
+ channel: message.ref.channel.name,
57172
+ thread: exports_Option.map(message.ref.thread, (observed) => observed.name)
57173
+ });
57174
+ var DeliveryTargetSchema = exports_Schema.Data(exports_Schema.Struct({
57175
+ channel: ChannelNameSchema,
57176
+ thread: exports_Schema.OptionFromNullOr(ThreadNameSchema)
57177
+ }));
57178
+ var TargetCursorsFileSchema = exports_Schema.parseJson(exports_Schema.HashMap({ key: DeliveryTargetSchema, value: TimestampSchema }));
57179
+ var decodeTargetCursorsFile = exports_Schema.decodeUnknown(TargetCursorsFileSchema);
57180
+ var encodeTargetCursorsFile = exports_Schema.encode(TargetCursorsFileSchema);
57181
+ var FILENAME_SAFE2 = /[^a-zA-Z0-9._-]/g;
57182
+ var cursorsFilename = (id3) => `${id3.replace(FILENAME_SAFE2, "_")}.json`;
57183
+ var isNotFound2 = (error2) => error2._tag === "SystemError" && error2.reason === "NotFound";
57184
+ var readCursors = (fs, path) => fs.readFileString(path).pipe(exports_Effect.flatMap(decodeTargetCursorsFile), exports_Effect.map(exports_Option.some), exports_Effect.catchIf(isNotFound2, () => exports_Effect.succeed(exports_Option.none())));
57185
+ var advanceTargetCursor = (fs, dir, id3, target, ts) => {
57186
+ const path = join8(dir, cursorsFilename(id3));
57187
+ return readCursors(fs, path).pipe(exports_Effect.catchTag("ParseError", () => exports_Effect.succeed(exports_Option.none())), exports_Effect.map(exports_Option.getOrElse(() => exports_HashMap.empty())), exports_Effect.flatMap((cursors) => {
57188
+ const prior = exports_HashMap.get(cursors, target);
57189
+ return exports_Option.isSome(prior) && prior.value >= ts ? exports_Effect.void : encodeTargetCursorsFile(exports_HashMap.set(cursors, target, ts)).pipe(exports_Effect.orDie, exports_Effect.flatMap((json4) => fs.makeDirectory(dir, { recursive: true }).pipe(exports_Effect.zipRight(fs.writeFileString(path, json4)))));
57190
+ }));
57191
+ };
57192
+ var STATE_SEGMENT2 = "commy";
57193
+ var stateBaseConfig2 = exports_Config.nonEmptyString("XDG_STATE_HOME").pipe(exports_Config.withDefault(join8(homedir2(), ".local", "state")));
57194
+ var targetCursorDirConfig = stateBaseConfig2.pipe(exports_Config.map((base) => join8(base, STATE_SEGMENT2, "target-cursors")));
57195
+
57166
57196
  // packages/mcp/event-pump.ts
57167
57197
  var originatorId = (event) => exports_Match.value(event).pipe(exports_Match.discriminatorsExhaustive("kind")({
57168
57198
  "message-posted": (message) => message.message.sender.id,
@@ -57218,9 +57248,11 @@ var startEventPump = (deps) => exports_Effect.gen(function* () {
57218
57248
  deps.rememberIdentity(identity6);
57219
57249
  }
57220
57250
  const mentionAdvance = deps.onMention !== undefined && event.kind === "mention-received" ? deps.onMention(event.message.ts) : exports_Effect.void;
57251
+ const deliveryAdvance = deps.onDelivery !== undefined && (event.kind === "message-posted" || event.kind === "mention-received") ? deps.onDelivery(deliveryTargetOf(event.message), event.message.ts) : exports_Effect.void;
57252
+ const advance = exports_Effect.zipRight(mentionAdvance, deliveryAdvance);
57221
57253
  if (recordMessageDelivery(event, seenDelivered) === "duplicate")
57222
- return mentionAdvance;
57223
- return mentionAdvance.pipe(exports_Effect.zipRight(renderEvent(event, botIdentityId)), exports_Effect.flatMap((payload) => exports_Effect.tryPromise({
57254
+ return advance;
57255
+ return advance.pipe(exports_Effect.zipRight(renderEvent(event, botIdentityId)), exports_Effect.flatMap((payload) => exports_Effect.tryPromise({
57224
57256
  try: () => deps.notifier(payload),
57225
57257
  catch: (cause3) => new DispatchFailure({ cause: cause3 })
57226
57258
  })));
@@ -58730,7 +58762,7 @@ class Server extends Protocol {
58730
58762
  }
58731
58763
 
58732
58764
  // packages/mcp/mcp-server.ts
58733
- var PLUGIN_VERSION = "0.16.0";
58765
+ var PLUGIN_VERSION = "0.17.0";
58734
58766
  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.
58735
58767
 
58736
58768
  **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.
@@ -58793,6 +58825,8 @@ var mentionsMatches = (intents, mentions, botIdentityId) => {
58793
58825
  var createNarrowSet = () => {
58794
58826
  let intents = exports_HashSet.empty();
58795
58827
  let seenTopics = exports_HashSet.empty();
58828
+ const pending3 = [];
58829
+ let recording = false;
58796
58830
  const newTopicsMatches = (ref) => exports_Option.match(threadKey(ref), {
58797
58831
  onNone: () => false,
58798
58832
  onSome: (tk) => {
@@ -58807,15 +58841,30 @@ var createNarrowSet = () => {
58807
58841
  const messagePostedMatches = (ref) => refMatches(ref, intents) || newTopicsMatches(ref);
58808
58842
  return {
58809
58843
  add: (intent) => {
58810
- intents = exports_HashSet.add(intents, intentKey(intent));
58844
+ const key = intentKey(intent);
58845
+ intents = exports_HashSet.add(intents, key);
58846
+ if (recording)
58847
+ pending3.push({ op: "add", key });
58811
58848
  },
58812
58849
  remove: (intent) => {
58813
- intents = exports_HashSet.remove(intents, intentKey(intent));
58850
+ const key = intentKey(intent);
58851
+ intents = exports_HashSet.remove(intents, key);
58852
+ if (recording)
58853
+ pending3.push({ op: "remove", key });
58814
58854
  },
58815
58855
  size: () => exports_HashSet.size(intents),
58816
58856
  intents: () => exports_Array.fromIterable(intents).map(keyToIntent),
58817
- replace: (next4) => {
58818
- intents = exports_HashSet.fromIterable(next4.map(intentKey));
58857
+ beginBuffering: () => {
58858
+ recording = true;
58859
+ },
58860
+ load: (base) => {
58861
+ const seeded = exports_Option.match(base, {
58862
+ onNone: () => intents,
58863
+ onSome: (next4) => exports_HashSet.fromIterable(next4.map(intentKey))
58864
+ });
58865
+ intents = pending3.reduce((acc, delta) => delta.op === "add" ? exports_HashSet.add(acc, delta.key) : exports_HashSet.remove(acc, delta.key), seeded);
58866
+ pending3.length = 0;
58867
+ recording = false;
58819
58868
  },
58820
58869
  matches: (event, botIdentityId) => exports_Match.value(event).pipe(exports_Match.discriminatorsExhaustive("kind")({
58821
58870
  "message-posted": (e) => messagePostedMatches(e.message.ref) || mentionsMatches(intents, e.message.mentions, botIdentityId),
@@ -58830,24 +58879,28 @@ var createNarrowSet = () => {
58830
58879
  var DEFAULT_TIMEOUT_MS = 5000;
58831
58880
  var raceReleaseAgainstTimeout = (release, timeoutMs = DEFAULT_TIMEOUT_MS) => release.pipe(exports_Effect.tapDefect((cause3) => exports_Effect.logError(`release failed: ${exports_Cause.pretty(cause3)}`)), exports_Effect.catchAllDefect(() => exports_Effect.void), exports_Effect.timeoutOption(exports_Duration.millis(timeoutMs)), exports_Effect.flatMap((result) => exports_Option.isNone(result) ? exports_Effect.logError(`release timed out after ${timeoutMs}ms`) : exports_Effect.void));
58832
58881
 
58882
+ // packages/mcp/session-id.ts
58883
+ class SessionId extends exports_Context.Tag("commy/mcp/SessionId")() {
58884
+ }
58885
+ var SessionIdLive = exports_Layer.effect(SessionId, exports_Deferred.make());
58886
+
58833
58887
  // packages/mcp/subscription-restore.ts
58834
- var applyRestored = (deps, intents) => exports_Effect.sync(() => deps.narrowSet.replace(intents)).pipe(exports_Effect.zipRight(exports_Effect.forEach(intents, (intent) => deps.inbox.subscribe(intentToTarget(intent)), {
58888
+ var applyRestored = (deps, intents) => exports_Effect.sync(() => deps.narrowSet.load(exports_Option.some(intents))).pipe(exports_Effect.zipRight(exports_Effect.forEach(intents, (intent) => deps.inbox.subscribe(intentToTarget(intent)), {
58835
58889
  discard: true
58836
58890
  })));
58837
- var seedDefaultsIfFresh = (deps, sessionId, project3) => deps.subscriptionStore.read(sessionId).pipe(exports_Effect.flatMap(exports_Option.match({
58891
+ var seedDefaultsIfFresh = (deps, project3) => deps.subscriptionStore.read().pipe(exports_Effect.flatMap(exports_Option.match({
58838
58892
  onNone: () => deps.registerDefaults(project3),
58839
58893
  onSome: () => exports_Effect.void
58840
58894
  })));
58841
- var restoreSubscriptions = (deps, sessionId) => deps.subscriptionStore.read(sessionId).pipe(exports_Effect.flatMap(exports_Option.match({
58842
- onNone: () => exports_Effect.void,
58895
+ var restoreSubscriptions = (deps) => deps.subscriptionStore.read().pipe(exports_Effect.flatMap(exports_Option.match({
58896
+ onNone: () => exports_Effect.sync(() => deps.narrowSet.load(exports_Option.none())),
58843
58897
  onSome: (intents) => applyRestored(deps, intents)
58844
58898
  })));
58845
- var makeSessionRestore = (deps) => exports_Effect.map(exports_Deferred.make(), (known) => (sessionId) => exports_Deferred.succeed(known, sessionId).pipe(exports_Effect.flatMap((won) => won ? restoreSubscriptions(deps, sessionId) : exports_Effect.void)));
58846
- var persistSubscriptions = (store, narrowSet, sessionId) => store.write(sessionId, narrowSet.intents());
58899
+ var persistSubscriptions = (store, narrowSet) => store.write(narrowSet.intents());
58847
58900
 
58848
58901
  // packages/mcp/subscription-store.ts
58849
- import { homedir as homedir2 } from "node:os";
58850
- import { join as join8 } from "node:path";
58902
+ import { homedir as homedir3 } from "node:os";
58903
+ import { join as join9 } from "node:path";
58851
58904
  class SubscriptionStoreTag extends exports_Context.Tag("SubscriptionStore")() {
58852
58905
  }
58853
58906
  var SubscribeIntentSchema = exports_Schema.Union(exports_Schema.Struct({ kind: exports_Schema.Literal("mentions") }), exports_Schema.Struct({ kind: exports_Schema.Literal("channel"), channelName: ChannelNameSchema }), exports_Schema.Struct({
@@ -58857,24 +58910,33 @@ var SubscribeIntentSchema = exports_Schema.Union(exports_Schema.Struct({ kind: e
58857
58910
  }), exports_Schema.Struct({ kind: exports_Schema.Literal("new-topics-in-channel"), channelName: ChannelNameSchema }));
58858
58911
  var SubscriptionsFileSchema = exports_Schema.parseJson(exports_Schema.Array(SubscribeIntentSchema));
58859
58912
  var decodeSubscriptionsFile = exports_Schema.decodeUnknown(SubscriptionsFileSchema);
58860
- var FILENAME_SAFE2 = /[^a-zA-Z0-9._-]/g;
58913
+ var FILENAME_SAFE3 = /[^a-zA-Z0-9._-]/g;
58861
58914
  var subscriptionFilename = (id3) => {
58862
- const safe = id3.replace(FILENAME_SAFE2, "_");
58915
+ const safe = id3.replace(FILENAME_SAFE3, "_");
58863
58916
  return `${safe}.json`;
58864
58917
  };
58865
- var isNotFound2 = (error2) => error2._tag === "SystemError" && error2.reason === "NotFound";
58866
- var readSubscriptions = (fs, path) => fs.readFileString(path).pipe(exports_Effect.flatMap(decodeSubscriptionsFile), exports_Effect.map((intents) => exports_Option.some(intents)), exports_Effect.catchIf(isNotFound2, () => exports_Effect.succeed(exports_Option.none())));
58918
+ var isNotFound3 = (error2) => error2._tag === "SystemError" && error2.reason === "NotFound";
58919
+ var readSubscriptions = (fs, path) => fs.readFileString(path).pipe(exports_Effect.flatMap(decodeSubscriptionsFile), exports_Effect.map((intents) => exports_Option.some(intents)), exports_Effect.catchIf(isNotFound3, () => exports_Effect.succeed(exports_Option.none())));
58867
58920
  var createFileSubscriptionStore = (deps) => {
58868
- const { dir, fs } = deps;
58869
- const pathFor = (id3) => join8(dir, subscriptionFilename(id3));
58870
- const read3 = (id3) => readSubscriptions(fs, pathFor(id3));
58871
- const write4 = (id3, intents) => fs.makeDirectory(dir, { recursive: true }).pipe(exports_Effect.zipRight(fs.writeFileString(pathFor(id3), JSON.stringify(intents))));
58872
- return { read: read3, write: write4 };
58873
- };
58874
- var STATE_SEGMENT2 = "commy";
58875
- var stateBaseConfig2 = exports_Config.nonEmptyString("XDG_STATE_HOME").pipe(exports_Config.withDefault(join8(homedir2(), ".local", "state")));
58876
- var subscriptionDirConfig = stateBaseConfig2.pipe(exports_Config.map((base) => join8(base, STATE_SEGMENT2, "subscriptions")));
58877
- var FileSubscriptionStoreLive = exports_Layer.effect(SubscriptionStoreTag, exports_Effect.all([exports_FileSystem.FileSystem, exports_Effect.orDie(subscriptionDirConfig)]).pipe(exports_Effect.map(([fs, dir]) => createFileSubscriptionStore({ dir, fs }))));
58921
+ const { dir, fs, cursorDir, session } = deps;
58922
+ const pathFor = (id3) => join9(dir, subscriptionFilename(id3));
58923
+ const read3 = () => exports_Effect.flatMap(exports_Deferred.await(session), (id3) => readSubscriptions(fs, pathFor(id3)));
58924
+ const write4 = (intents) => exports_Effect.flatMap(exports_Deferred.await(session), (id3) => fs.makeDirectory(dir, { recursive: true }).pipe(exports_Effect.zipRight(fs.writeFileString(pathFor(id3), JSON.stringify(intents)))));
58925
+ const advanceCursor = (target, ts) => exports_Effect.flatMap(exports_Deferred.poll(session), exports_Option.match({
58926
+ onNone: () => exports_Effect.void,
58927
+ onSome: (awaitId) => exports_Effect.flatMap(awaitId, (id3) => advanceTargetCursor(fs, cursorDir, id3, target, ts))
58928
+ }));
58929
+ return { read: read3, write: write4, advanceCursor };
58930
+ };
58931
+ var STATE_SEGMENT3 = "commy";
58932
+ var stateBaseConfig3 = exports_Config.nonEmptyString("XDG_STATE_HOME").pipe(exports_Config.withDefault(join9(homedir3(), ".local", "state")));
58933
+ var subscriptionDirConfig = stateBaseConfig3.pipe(exports_Config.map((base) => join9(base, STATE_SEGMENT3, "subscriptions")));
58934
+ var FileSubscriptionStoreLive = exports_Layer.effect(SubscriptionStoreTag, exports_Effect.all([
58935
+ exports_FileSystem.FileSystem,
58936
+ exports_Effect.orDie(subscriptionDirConfig),
58937
+ exports_Effect.orDie(targetCursorDirConfig),
58938
+ SessionId
58939
+ ]).pipe(exports_Effect.map(([fs, dir, cursorDir, session]) => createFileSubscriptionStore({ dir, fs, cursorDir, session }))));
58878
58940
 
58879
58941
  // packages/mcp/tools.ts
58880
58942
  var emptyObjectSchema = {
@@ -59048,11 +59110,17 @@ var buildToolDefs = (deps, cache) => {
59048
59110
  description: "Calling session's working directory. In Claude Code, the PreToolUse hook injects this from the harness cwd; non-CC MCP clients may supply their own. Drives the project component of ephemeral cc-<project>-<8> names — without this the minted name falls back to bare cc-<8> (or the operator-forced COMMY_PROJECT slug)."
59049
59111
  };
59050
59112
  const readSessionId = (args2) => exports_Option.getOrUndefined(parseSessionId(args2["session_id"]));
59113
+ const feedSession = (sessionId) => sessionId === undefined || deps.feedSessionId === undefined ? exports_Effect.void : deps.feedSessionId(sessionId);
59051
59114
  const readCwd = (args2) => {
59052
59115
  const raw3 = args2["cwd"];
59053
59116
  return exports_Predicate.isString(raw3) ? raw3 : undefined;
59054
59117
  };
59055
59118
  const projectForArgs = (args2) => projectForCwd(readCwd(args2));
59119
+ const ensureBoundForArgs = (args2) => exports_Effect.gen(function* () {
59120
+ const sessionId = readSessionId(args2);
59121
+ yield* feedSession(sessionId);
59122
+ return yield* identityCache.ensureBoundFor(sessionId, yield* projectForArgs(args2));
59123
+ });
59056
59124
  const stickyThreadEngagement = async (channel, threadName3) => {
59057
59125
  if (exports_Option.isNone(threadName3))
59058
59126
  return;
@@ -59074,8 +59142,7 @@ var buildToolDefs = (deps, cache) => {
59074
59142
  additionalProperties: false
59075
59143
  },
59076
59144
  handler: async (args2) => {
59077
- const sessionId = readSessionId(args2);
59078
- const ensureBound = await runEdge(exports_Effect.flatMap(projectForArgs(args2), (project3) => identityCache.ensureBoundFor(sessionId, project3)));
59145
+ const ensureBound = await runEdge(ensureBoundForArgs(args2));
59079
59146
  const current2 = ensureBound.current();
59080
59147
  if (current2 === undefined) {
59081
59148
  return { state: "unbound", identity: null };
@@ -59181,7 +59248,7 @@ var buildToolDefs = (deps, cache) => {
59181
59248
  additionalProperties: false
59182
59249
  },
59183
59250
  handler: async (args2) => {
59184
- await runEdge(exports_Effect.flatMap(projectForArgs(args2), (project3) => identityCache.ensureBoundFor(readSessionId(args2), project3)).pipe(exports_Effect.flatMap((ensureBound) => ensureBound())));
59251
+ await runEdge(ensureBoundForArgs(args2).pipe(exports_Effect.flatMap((ensureBound) => ensureBound())));
59185
59252
  const ref = await runEdge(exports_Effect.gen(function* () {
59186
59253
  const { channel_name, body, thread, mentions, reply_to } = yield* exports_Schema.decodeUnknown(PostArgs)(args2);
59187
59254
  const channel = yield* decodeChannelName(channel_name);
@@ -59235,7 +59302,7 @@ var buildToolDefs = (deps, cache) => {
59235
59302
  additionalProperties: false
59236
59303
  },
59237
59304
  handler: async (args2) => {
59238
- await runEdge(exports_Effect.flatMap(projectForArgs(args2), (project3) => identityCache.ensureBoundFor(readSessionId(args2), project3)).pipe(exports_Effect.flatMap((ensureBound) => ensureBound())));
59305
+ await runEdge(ensureBoundForArgs(args2).pipe(exports_Effect.flatMap((ensureBound) => ensureBound())));
59239
59306
  const ref = await runEdge(exports_Effect.gen(function* () {
59240
59307
  const { message_id, body, channel_name } = yield* exports_Schema.decodeUnknown(EditMessageArgs)(args2);
59241
59308
  const target = yield* reconstructMessageRef(cache, message_id, channel_name);
@@ -59269,7 +59336,7 @@ var buildToolDefs = (deps, cache) => {
59269
59336
  additionalProperties: false
59270
59337
  },
59271
59338
  handler: async (args2) => {
59272
- await runEdge(exports_Effect.flatMap(projectForArgs(args2), (project3) => identityCache.ensureBoundFor(readSessionId(args2), project3)).pipe(exports_Effect.flatMap((ensureBound) => ensureBound())));
59339
+ await runEdge(ensureBoundForArgs(args2).pipe(exports_Effect.flatMap((ensureBound) => ensureBound())));
59273
59340
  const { ref, threadName: threadName3 } = await runEdge(exports_Effect.gen(function* () {
59274
59341
  const { message_id, emoji: emoji2, channel_name, thread } = yield* exports_Schema.decodeUnknown(ReactArgs)(args2);
59275
59342
  const target = yield* reconstructMessageRef(cache, message_id, channel_name);
@@ -59300,7 +59367,7 @@ var buildToolDefs = (deps, cache) => {
59300
59367
  additionalProperties: false
59301
59368
  },
59302
59369
  handler: async (args2) => {
59303
- await runEdge(exports_Effect.flatMap(projectForArgs(args2), (project3) => identityCache.ensureBoundFor(readSessionId(args2), project3)).pipe(exports_Effect.flatMap((ensureBound) => ensureBound())));
59370
+ await runEdge(ensureBoundForArgs(args2).pipe(exports_Effect.flatMap((ensureBound) => ensureBound())));
59304
59371
  await runEdge(exports_Effect.gen(function* () {
59305
59372
  const { message_id, emoji: emoji2, channel_name } = yield* exports_Schema.decodeUnknown(ReactArgs)(args2);
59306
59373
  const ref = yield* reconstructMessageRef(cache, message_id, channel_name);
@@ -59330,13 +59397,14 @@ var buildToolDefs = (deps, cache) => {
59330
59397
  const { target: raw3 } = yield* exports_Schema.decodeUnknown(SubscribeArgs)(args2);
59331
59398
  const intent = yield* parseSubscribeTarget(raw3);
59332
59399
  const sessionId = readSessionId(args2);
59400
+ yield* feedSession(sessionId);
59333
59401
  if (sessionId !== undefined && deps.ensureSessionSubscriptions !== undefined) {
59334
59402
  yield* deps.ensureSessionSubscriptions(sessionId, yield* projectForArgs(args2));
59335
59403
  }
59336
59404
  narrowSet.add(intent);
59337
59405
  yield* adapter4.inbox.subscribe(intentToTarget(intent));
59338
- if (sessionId !== undefined && deps.persistSessionSubscriptions !== undefined) {
59339
- yield* deps.persistSessionSubscriptions(sessionId);
59406
+ if (deps.persistSessionSubscriptions !== undefined) {
59407
+ yield* deps.persistSessionSubscriptions;
59340
59408
  }
59341
59409
  }));
59342
59410
  return {};
@@ -59363,13 +59431,14 @@ var buildToolDefs = (deps, cache) => {
59363
59431
  const { target: raw3 } = yield* exports_Schema.decodeUnknown(SubscribeArgs)(args2);
59364
59432
  const intent = yield* parseSubscribeTarget(raw3);
59365
59433
  const sessionId = readSessionId(args2);
59434
+ yield* feedSession(sessionId);
59366
59435
  if (sessionId !== undefined && deps.ensureSessionSubscriptions !== undefined) {
59367
59436
  yield* deps.ensureSessionSubscriptions(sessionId, yield* projectForArgs(args2));
59368
59437
  }
59369
59438
  narrowSet.remove(intent);
59370
59439
  yield* adapter4.inbox.unsubscribe(intentToTarget(intent));
59371
- if (sessionId !== undefined && deps.persistSessionSubscriptions !== undefined) {
59372
- yield* deps.persistSessionSubscriptions(sessionId);
59440
+ if (deps.persistSessionSubscriptions !== undefined) {
59441
+ yield* deps.persistSessionSubscriptions;
59373
59442
  }
59374
59443
  }));
59375
59444
  return {};
@@ -59669,6 +59738,12 @@ var makeProgram = (params = {}) => exports_Effect.scoped(exports_Effect.gen(func
59669
59738
  const adapter4 = yield* SubstrateAdapter;
59670
59739
  const cursorStore = yield* CursorStoreTag;
59671
59740
  const subscriptionStore = yield* SubscriptionStoreTag;
59741
+ const sessionIdDeferred = yield* SessionId;
59742
+ yield* exports_Effect.flatMap(readBootSessionId, exports_Option.match({
59743
+ onNone: () => exports_Effect.void,
59744
+ onSome: (sessionId) => exports_Deferred.succeed(sessionIdDeferred, sessionId).pipe(exports_Effect.asVoid)
59745
+ }));
59746
+ const feedSessionId = (sessionId) => exports_Deferred.succeed(sessionIdDeferred, sessionId).pipe(exports_Effect.asVoid);
59672
59747
  const fs = yield* exports_FileSystem.FileSystem;
59673
59748
  const loggerLayer = params.loggerLayer ?? stderrLoggerLayer;
59674
59749
  const commandExecutor = yield* exports_CommandExecutor.CommandExecutor;
@@ -59694,12 +59769,14 @@ var makeProgram = (params = {}) => exports_Effect.scoped(exports_Effect.gen(func
59694
59769
  const mcp = buildMcpServer();
59695
59770
  const notifier = params.notifier ?? channelNotifier(mcp);
59696
59771
  const registerType2Defaults = parsed.botName === undefined ? createType2DefaultsOnAcquire(narrowSet, adapter4.inbox) : undefined;
59697
- const sessionRestoreFeed = parsed.botName === undefined ? yield* makeSessionRestore({ subscriptionStore, narrowSet, inbox: adapter4.inbox }) : undefined;
59772
+ const restoreOnResume = parsed.botName !== undefined ? exports_Effect.void : restoreSubscriptions({ subscriptionStore, narrowSet, inbox: adapter4.inbox }).pipe(exports_Effect.catchAll((err) => exports_Effect.logError(`commy plugin: subscription restore failed: ${exports_Predicate.isError(err) ? err.message : String(err)}`)), exports_Effect.provide(loggerLayer));
59698
59773
  const seedDefaults = (project3) => registerType2Defaults !== undefined ? registerType2Defaults(project3) : exports_Effect.void;
59699
- const feedSession = (sessionId) => sessionRestoreFeed === undefined ? exports_Effect.void : sessionRestoreFeed(sessionId).pipe(exports_Effect.catchAll((err) => exports_Effect.logError(`commy plugin: subscription restore failed for ${sessionId}: ${exports_Predicate.isError(err) ? err.message : String(err)}`)), exports_Effect.provide(loggerLayer));
59700
- const seedIfFresh = (sessionId, project3) => parsed.botName !== undefined ? exports_Effect.void : seedDefaultsIfFresh({ subscriptionStore, registerDefaults: seedDefaults }, sessionId, 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));
59701
- const ensureSessionSubscriptions = (sessionId, project3) => feedSession(sessionId).pipe(exports_Effect.zipRight(seedIfFresh(sessionId, project3)));
59702
- const persistSessionSubscriptions = (sessionId) => parsed.botName !== undefined ? exports_Effect.void : persistSubscriptions(subscriptionStore, narrowSet, sessionId).pipe(exports_Effect.catchAll((err) => exports_Effect.logError(`commy plugin: subscription persist failed for ${sessionId}: ${exports_Predicate.isError(err) ? err.message : String(err)}`)), exports_Effect.provide(loggerLayer));
59774
+ 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));
59775
+ const ensureSessionSubscriptions = (sessionId, project3) => seedIfFresh(sessionId, project3);
59776
+ const persistSessionSubscriptions = parsed.botName !== undefined ? exports_Effect.void : exports_Deferred.poll(sessionIdDeferred).pipe(exports_Effect.flatMap(exports_Option.match({
59777
+ onNone: () => exports_Effect.void,
59778
+ onSome: () => persistSubscriptions(subscriptionStore, narrowSet).pipe(exports_Effect.catchAll((err) => exports_Effect.logError(`commy plugin: subscription persist failed: ${exports_Predicate.isError(err) ? err.message : String(err)}`)), exports_Effect.provide(loggerLayer))
59779
+ })));
59703
59780
  const ephemeralOnAcquire = parsed.botName === undefined ? (acquired, project3, sessionId) => ensureSessionSubscriptions(sessionId, project3).pipe(exports_Effect.zipRight(catchUpMentions({
59704
59781
  cursorStore,
59705
59782
  inbox: adapter4.inbox,
@@ -59723,6 +59800,9 @@ var makeProgram = (params = {}) => exports_Effect.scoped(exports_Effect.gen(func
59723
59800
  yield* exports_Effect.addFinalizer(() => identityCache.boundIdentityIds().size > 0 ? raceReleaseAgainstTimeout(adapter4.identity.release({ persistent: releasePersistent }), RELEASE_TIMEOUT_MS) : exports_Effect.void);
59724
59801
  const runsIdleSweep = parsed.botName === undefined;
59725
59802
  const subscribedIntents = yield* subscribeFromEnv(adapter4.inbox, narrowSet, parsed);
59803
+ if (parsed.botName === undefined) {
59804
+ narrowSet.beginBuffering();
59805
+ }
59726
59806
  const toolsCache = registerTools(mcp, {
59727
59807
  adapter: adapter4,
59728
59808
  identityCache,
@@ -59730,10 +59810,11 @@ var makeProgram = (params = {}) => exports_Effect.scoped(exports_Effect.gen(func
59730
59810
  projectForCwd,
59731
59811
  ensureSessionSubscriptions,
59732
59812
  persistSessionSubscriptions,
59813
+ feedSessionId,
59733
59814
  downloadFile: (urlPath) => exports_Effect.gen(function* () {
59734
59815
  const result = yield* adapter4.downloadFile(urlPath);
59735
59816
  const dir = yield* fs.makeTempDirectory({ prefix: "commy-dl-" });
59736
- const filePath = join9(dir, basename2(urlPath));
59817
+ const filePath = join10(dir, basename2(urlPath));
59737
59818
  yield* fs.writeFile(filePath, result.data);
59738
59819
  return { filePath, contentType: result.contentType, size: result.data.byteLength };
59739
59820
  }),
@@ -59786,15 +59867,21 @@ var makeProgram = (params = {}) => exports_Effect.scoped(exports_Effect.gen(func
59786
59867
  if (id3 === undefined)
59787
59868
  return exports_Effect.void;
59788
59869
  return cursorStore.write(id3, ts).pipe(exports_Effect.catchAllCause(() => exports_Effect.void));
59870
+ },
59871
+ onDelivery: (target, ts) => {
59872
+ if (parsed.botName !== undefined)
59873
+ return exports_Effect.void;
59874
+ return subscriptionStore.advanceCursor(target, ts).pipe(exports_Effect.catchAllCause(() => exports_Effect.void));
59789
59875
  }
59790
59876
  });
59791
59877
  yield* exports_Effect.addFinalizer(() => pump.cancel);
59792
59878
  if (runsIdleSweep) {
59793
59879
  yield* forkIdleSweep(identityCache, EPHEMERAL_IDLE_SWEEP_INTERVAL_MS);
59794
59880
  }
59881
+ yield* exports_Effect.forkScoped(restoreOnResume);
59795
59882
  yield* exports_Effect.raceFirst(pump.done, params.shutdownSignal ?? exports_Effect.never);
59796
59883
  }));
59797
- var AppLayer = exports_Layer.mergeAll(ZulipAdapterLive, FileCursorStoreLive, FileSubscriptionStoreLive, stderrLoggerLayer);
59884
+ var AppLayer = exports_Layer.mergeAll(ZulipAdapterLive, FileCursorStoreLive, exports_Layer.provideMerge(FileSubscriptionStoreLive, SessionIdLive), stderrLoggerLayer);
59798
59885
  var PlatformLive = exports_Layer.mergeAll(exports_Layer.setConfigProvider(exports_ConfigProvider.fromEnv()), exports_FetchHttpClient.layer, exports_NodeContext.layer);
59799
59886
  var MainLive = exports_Layer.provideMerge(AppLayer, PlatformLive);
59800
59887
  var clientDisconnect = (stdin3) => exports_Effect.async((resume2) => {