baychat 0.32.0 → 0.32.1

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.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "baychat",
3
- "version": "0.32.0",
3
+ "version": "0.32.1",
4
4
  "displayName": "BayChat",
5
5
  "description": "Wakes this Claude Code session the moment a BayChat message arrives: no Monitor, no 30-minute deadline. Uses the baychat CLI already on this computer (npm install -g baychat, then baychat login).",
6
6
  "author": {
package/dist/bays.js CHANGED
@@ -14,7 +14,8 @@
14
14
  //
15
15
  // This file is the PURE part — names, lookups, the default switch. No I/O.
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
- exports.DEFAULT_MCP_ENTRY = void 0;
17
+ exports.LAUNCH_MCP_ENTRY = exports.DEFAULT_MCP_ENTRY = void 0;
18
+ exports.channelBay = channelBay;
18
19
  exports.baySlug = baySlug;
19
20
  exports.bayEntryName = bayEntryName;
20
21
  exports.extraBayEntries = extraBayEntries;
@@ -24,6 +25,27 @@ exports.withDefaultBay = withDefaultBay;
24
25
  exports.renderBayList = renderBayList;
25
26
  /** The MCP server name every client has always had: the default Bay. */
26
27
  exports.DEFAULT_MCP_ENTRY = "baychat";
28
+ /**
29
+ * The MCP server name of a session launched by a relay on a setup of its own (another config
30
+ * folder or server: relay/launcher/relay-identity.ts). It is a CONNECTION name, never a Bay:
31
+ * that session has exactly one login, the relay's, so wherever it is passed as a Bay it means
32
+ * the default login (`channelBay`).
33
+ */
34
+ exports.LAUNCH_MCP_ENTRY = "baychat-relay";
35
+ /**
36
+ * The Bay a channel call names, as the login lookup should read it: undefined = the default
37
+ * login. A value that is the launch connection's name (`baychat-relay`), or any value on a
38
+ * computer with one login (no saved Bay set, or a set of one), is the default — there is no
39
+ * other Bay it could mean, and failing there left a launched session without its channel
40
+ * (Mac QA 2026-10-16: `listen {"bay":"baychat-relay"}` → failed). With several Bays an unknown
41
+ * name still fails in `findBayLogin`: the wrong Bay is the wrong room.
42
+ */
43
+ function channelBay(bay, bays) {
44
+ const q = bay?.trim();
45
+ if (!q || q === exports.LAUNCH_MCP_ENTRY || bays.length <= 1)
46
+ return undefined;
47
+ return q;
48
+ }
27
49
  /** How a Bay name becomes part of an MCP server name: `[a-z0-9-]`, no edge dashes, short. */
28
50
  function baySlug(name) {
29
51
  const slug = name
@@ -255,16 +255,22 @@ class ChannelFeed {
255
255
  // An answered decision is said as itself; anything that does not read as one stays an
256
256
  // ordinary wake, so a malformed entry can never make the session miss a message.
257
257
  const approvals = [];
258
+ const clears = [];
258
259
  const items = [];
259
260
  for (const entry of entries) {
260
261
  const approval = answeredApproval(entry);
262
+ const cleared = approval ? undefined : clearedChat(entry);
261
263
  if (approval)
262
264
  approvals.push(approval);
265
+ else if (cleared)
266
+ clears.push(cleared);
263
267
  else
264
268
  items.push(entry);
265
269
  }
266
270
  for (const approval of approvals)
267
271
  await this.pushApproval(approval);
272
+ for (const cleared of clears)
273
+ await this.pushCleared(cleared);
268
274
  if (!items.length)
269
275
  return;
270
276
  const conversations = [...new Set(items.map((m) => m.conversationId))];
@@ -287,6 +293,14 @@ class ChannelFeed {
287
293
  request_id: a.requestId,
288
294
  }));
289
295
  }
296
+ async pushCleared(c) {
297
+ await this.deps.push(`${c.by} cleared BayChat conversation ${c.conversationId} for everyone: every earlier message and file in it was deleted. ` +
298
+ `Treat that chat as a fresh start — do not refer to or rely on anything said there before. No reply is needed.`, this.meta({
299
+ event: "cleared",
300
+ conversation_ids: c.conversationId,
301
+ message_ids: c.messageId,
302
+ }));
303
+ }
290
304
  async pushReset() {
291
305
  await this.deps.push(`BayChat reset the feed for session "${this.deps.session}". Catch up on your joined conversations with get_messages; ` +
292
306
  `a reset never means there were no messages. The channel stays open.`, this.meta({ event: "reset" }));
@@ -322,6 +336,14 @@ function answeredApproval(entry) {
322
336
  return undefined;
323
337
  return { conversationId: entry.conversationId, messageId: entry.messageId, requestId: a.requestId, question, answer };
324
338
  }
339
+ /** An entry's `cleared`, when it is a well-formed "cleared for everyone" notice; else undefined. */
340
+ function clearedChat(entry) {
341
+ const c = entry.cleared;
342
+ if (!c || typeof c !== "object" || c.status !== "cleared")
343
+ return undefined;
344
+ const by = typeof c.by === "string" ? oneLine(c.by) : "";
345
+ return { conversationId: entry.conversationId, messageId: entry.messageId, by: by || "Someone" };
346
+ }
325
347
  /** One line of plain text, no control characters or quotes that would blur where it ends. */
326
348
  function oneLine(text) {
327
349
  const line = text
@@ -115,22 +115,27 @@ function realCommandLink(log) {
115
115
  }
116
116
  /** The relay that serves a Bay's sessions: the default relay, or that Bay's own (relay/bay-relays.ts). */
117
117
  function relaySocketFor(bay) {
118
- if (bay === undefined || !bay.trim())
118
+ const bays = (0, config_1.loadBayLogins)();
119
+ const named = (0, bays_1.channelBay)(bay, bays);
120
+ if (named === undefined)
119
121
  return (0, socket_1.socketPath)();
120
- const login = (0, bays_1.findBayLogin)((0, config_1.loadBayLogins)(), bay);
122
+ const login = (0, bays_1.findBayLogin)(bays, named);
121
123
  return login.isDefault ? (0, socket_1.socketPath)() : (0, bay_relays_1.bayRelayScope)(login.bayId, (0, config_1.configDir)(), (0, socket_1.socketPath)()).socket;
122
124
  }
123
- /** The real login lookup: the default Bay, or a named one from `credentials.json`. */
125
+ /** The real login lookup: the default Bay, or a named one from `credentials.json` (`channelBay`). */
124
126
  function realLogin(bay) {
125
127
  const device = (0, config_1.loadDeviceCredentials)();
126
128
  if (!device)
127
129
  throw new Error("This computer is not signed in to BayChat. Run `baychat login`.");
128
130
  const bays = (0, config_1.loadBayLogins)();
129
- if (bay === undefined || !bay.trim()) {
131
+ // `baychat-relay` (a launched session's connection), or any name on a one-login computer, is
132
+ // the default login (bays.ts `channelBay`).
133
+ const named = (0, bays_1.channelBay)(bay, bays);
134
+ if (named === undefined) {
130
135
  const def = bays.find((b) => b.isDefault);
131
136
  return { baseUrl: device.baseUrl, token: device.token, expiresAt: device.expiresAt, ...(def ? { bayName: def.bayName } : {}) };
132
137
  }
133
- const found = (0, bays_1.findBayLogin)(bays, bay);
138
+ const found = (0, bays_1.findBayLogin)(bays, named);
134
139
  return { baseUrl: device.baseUrl, token: found.token, expiresAt: found.expiresAt, bayName: found.bayName };
135
140
  }
136
141
  /** One remote tool call over the BayChat HTTP MCP endpoint, then disconnect. */