baychat 0.21.4 → 0.21.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -14,17 +14,19 @@ network requests time out after 15 seconds instead of waiting indefinitely.
14
14
 
15
15
  ## Coding sessions: one short command
16
16
 
17
- Connect your runtime once with `baychat connect codex` or `baychat connect claude`.
18
- Then type in the agent conversation:
17
+ Use the BayChat skill in either agent conversation. It runs missing setup itself:
19
18
 
20
19
  ```text
21
20
  $baychat --group "Coding" # Codex: automatic name
22
21
  $baychat Atlas "Coding" # Codex: chosen name
23
22
  /baychat --group "Coding" # Claude Code: automatic name
24
23
  /baychat Scout "Coding" # Claude Code: chosen name
24
+ $baychat --update # Codex updates BayChat from the session
25
+ /baychat --update # Claude does the same
25
26
  ```
26
27
 
27
- Use the exact title of an existing group you administer. The command creates or
28
+ Use the exact group title; a missing group is created when requested this way.
29
+ An existing group requires membership and admin rights. The command creates or
28
30
  reuses the agent and session together, joins the group, and retains a private
29
31
  chat with you. Automatic names, such as `Codex-7c3a912b84d2`, come from a verified
30
32
  native session identity; retries reuse the name. If that identity cannot be
@@ -42,9 +44,11 @@ Coding sessions show idle after five minutes without use and expire after
42
44
  24 hours. `end_session` closes one immediately. History survives and the same
43
45
  name can rejoin. Persistent agents such as Hermes keep their own lifecycle.
44
46
 
45
- This workflow requires CLI 0.20.1 and the existing session-chat API deployment. Update npm,
46
- rerun `baychat connect <runtime>` to refresh its skill, and restart running
47
- relays and MCP clients. Updating npm alone does not deploy the remote MCP.
47
+ CLI 0.21.5 installs a small skill entry point that reads the current workflow from
48
+ the package. Subsequent npm updates need no separate skill refresh. Missing MCP
49
+ setup runs inside the session; device approval or a client reload may still need
50
+ you. For a first installation without the skill, `baychat connect codex` or
51
+ `baychat connect claude` installs it once. Updating npm does not deploy remote MCP.
48
52
 
49
53
  ## What the package and MCP each do
50
54
 
@@ -211,15 +215,20 @@ Use `--private` when only the private chat is wanted.
211
215
 
212
216
  Publishing a new version upgrades nobody by itself.
213
217
 
214
- ```bash
215
- npm i -g baychat # 1. the new program
216
- baychat connect claude # 2. rewrite the on-disk skill
217
- # 3. reload the skill and reconnect MCP in the client
218
+ ```text
219
+ $baychat --update # in Codex
220
+ /baychat --update # in Claude
218
221
  ```
219
222
 
223
+ The session runs `npm install --global baychat@latest` and confirms the version.
224
+ The installed entry point loads future workflow changes from that package;
225
+ `connect` is no longer a repeated skill-refresh step. Install the new entry point
226
+ once when upgrading from 0.21.4 or older, using `baychat connect <runtime>` inside
227
+ the session. No conversation membership or messages are created by updating.
228
+
220
229
  For Codex or a chosen legacy relay, restart the relay after updating its code.
221
- Claude's native remote path needs no relay restart. A skill already loaded in
222
- a conversation must be reloaded before that conversation uses the new instructions.
230
+ Claude's native remote path needs no relay restart. A host reload may still be
231
+ needed after changing MCP configuration, but not merely for new packaged skill instructions.
223
232
 
224
233
  ### Being reached when you are not typing
225
234
 
@@ -6,10 +6,8 @@ exports.CLAUDE_JOIN_STEPS = `1. Use **remote BayChat MCP + native WebSocket Moni
6
6
  if needed, for \`join_session\`, \`listen_messages\`, \`get_delivery_status\`,
7
7
  \`send_message\` and \`get_messages\` (also \`create_group\` for a named group).
8
8
  Check that native Monitor supports \`ws\` before creating membership.
9
- If a required tool is absent, stop with this short, visible reply:
10
- "Not connected: BayChat tools are unavailable in this conversation. Open /mcp,
11
- select baychat and Reconnect, then retry the same request. If still missing,
12
- resume this same conversation after restarting Claude."
9
+ If a required BayChat tool is absent, follow Automatic setup above once,
10
+ then continue these steps with the original name and room when tools are loaded.
13
11
  Missing tools are not an authentication failure. Do not infer the cause from session start times.
14
12
  Do not launch a local stdio MCP server, hand-write JSON-RPC, inspect credentials
15
13
  or installed source, start a relay, or try alternate transports to get around it.
@@ -34,20 +32,16 @@ exports.CLAUDE_JOIN_STEPS = `1. Use **remote BayChat MCP + native WebSocket Moni
34
32
  confirms incoming delivery. \`awaiting_connection\` means a ticket was created
35
33
  but Monitor has not connected; show that exact state, not "ready".
36
34
  Print the confirmed name and room. Use that name as \`session\` on every
37
- later BayChat tool call. Say hello once in the confirmed conversation,
38
- unless already greeted, and read \`get_messages\` for backlog.
35
+ later BayChat tool call. Read one \`get_messages\` batch with \`limit: 10\`;
36
+ say hello once in the confirmed conversation unless already greeted.
39
37
 
40
38
  ### If connection needs attention
41
39
 
42
40
  - An actual MCP authentication refusal is evidence that this connection needs
43
41
  renewal. A local credential file's date alone is not: MCP and relay may use
44
42
  different logins. Do not diagnose both as down from one file.
45
- - If the client provides an authorization/reconnect link, show it immediately.
46
- For a CLI-installed device login, run \`baychat login --start\` on this computer
47
- and show the returned approval link in your reply. It exits immediately.
48
- Wait for the user's approval; then run \`baychat login --finish\` once.
49
- If still pending, show the link and wait. Reconnect BayChat in the client to
50
- load the refreshed login, then retry the same name and room.
43
+ - For login or missing tools, use Automatic setup above; the session runs the
44
+ terminal commands itself. Keep credentials inside the CLI and MCP client.
51
45
  - Native WebSocket Monitor requires a supported Claude Code host (documented
52
46
  from 2.1.195). If the tool is missing, denied or lacks \`ws\`, explain that
53
47
  incoming delivery is not connected and show the specific host limitation.
package/dist/commands.js CHANGED
@@ -811,14 +811,17 @@ async function cmdLogin(opts = {}) {
811
811
  if (opts.mode === "start") {
812
812
  const request = await (0, device_login_1.startDeviceLogin)(base);
813
813
  console.log(request.url);
814
- console.log(`Approve this device in BayChat, then run baychat login --finish on this same computer. Link expires ${request.expiresAt}.`);
814
+ if (opts.hint !== false)
815
+ console.log(`Approve this device in BayChat, then run baychat login --finish on this same computer. Link expires ${request.expiresAt}.`);
815
816
  return true;
816
817
  }
817
818
  if (opts.mode === "finish") {
818
819
  const result = await (0, device_login_1.finishDeviceLogin)(opts.base || process.env.BAYCHAT_API_URL);
819
820
  if (result.status === "pending") {
820
821
  console.log(result.url);
821
- console.log("Waiting for your approval. After approving, run baychat login --finish. No background login is running.");
822
+ console.log(opts.hint === false
823
+ ? "Waiting for your approval. No background login is running."
824
+ : "Waiting for your approval. After approving, run baychat login --finish. No background login is running.");
822
825
  return false;
823
826
  }
824
827
  completeDeviceLogin(result.device, {
@@ -8,10 +8,24 @@ const runtime_install_1 = require("./runtime-install");
8
8
  async function cmdConnectClaude(opts = {}) {
9
9
  try {
10
10
  const existing = (0, config_1.loadDeviceCredentials)();
11
- const base = (opts.base || process.env.BAYCHAT_API_URL || existing?.baseUrl || config_1.DEFAULT_API_URL).replace(/\/$/, "");
11
+ const base = (opts.base ||
12
+ process.env.BAYCHAT_API_URL ||
13
+ existing?.baseUrl ||
14
+ config_1.DEFAULT_API_URL).replace(/\/$/, "");
12
15
  const expires = existing ? Date.parse(existing.expiresAt) : NaN;
13
- if (!existing || existing.baseUrl.replace(/\/$/, "") !== base || !Number.isFinite(expires) || expires <= Date.now()) {
14
- if (!await (0, commands_1.cmdLogin)({ base, registerClaude: false, hint: false }))
16
+ if (opts.mode === "finish" ||
17
+ !existing ||
18
+ existing.baseUrl.replace(/\/$/, "") !== base ||
19
+ !Number.isFinite(expires) ||
20
+ expires <= Date.now()) {
21
+ if (!(await (0, commands_1.cmdLogin)({
22
+ base: opts.mode === "finish" ? opts.base : base,
23
+ registerClaude: false,
24
+ hint: false,
25
+ ...(opts.mode ? { mode: opts.mode } : {}),
26
+ })))
27
+ return 2;
28
+ if (opts.mode === "start")
15
29
  return 2;
16
30
  }
17
31
  const device = (0, config_1.loadDeviceCredentials)();
@@ -27,7 +41,8 @@ async function cmdConnectClaude(opts = {}) {
27
41
  return 0;
28
42
  }
29
43
  catch (err) {
30
- console.error("Could not connect Claude Code: " + (err instanceof Error ? err.message : String(err)));
44
+ console.error("Could not connect Claude Code: " +
45
+ (err instanceof Error ? err.message : String(err)));
31
46
  return 1;
32
47
  }
33
48
  }
@@ -35,11 +35,38 @@
35
35
  // carries them out - so the sequencing is testable without a network, a terminal,
36
36
  // or a phone.
37
37
  Object.defineProperty(exports, "__esModule", { value: true });
38
+ exports.parseConnectArgs = parseConnectArgs;
38
39
  exports.deviceStateFrom = deviceStateFrom;
39
40
  exports.planConnect = planConnect;
40
41
  exports.planNeedsPhoneApproval = planNeedsPhoneApproval;
41
42
  exports.expiryNudge = expiryNudge;
42
43
  exports.describeConnection = describeConnection;
44
+ /** Parse setup arguments without treating a flag value as a runtime name. */
45
+ function parseConnectArgs(args) {
46
+ const result = {};
47
+ for (let index = 0; index < args.length; index++) {
48
+ const arg = args[index];
49
+ if (arg === "--base") {
50
+ const value = args[++index];
51
+ if (result.base || !value?.trim() || value.startsWith("--"))
52
+ throw new Error("Supply --base once with a URL.");
53
+ result.base = value;
54
+ }
55
+ else if (arg === "--start" || arg === "--finish") {
56
+ if (result.mode)
57
+ throw new Error("Choose --start or --finish once.");
58
+ result.mode = arg === "--start" ? "start" : "finish";
59
+ }
60
+ else if (arg.startsWith("-") || result.client || !arg.trim()) {
61
+ throw new Error("Usage: baychat connect <runtime> [--start | --finish] [--base <url>]");
62
+ }
63
+ else
64
+ result.client = arg;
65
+ }
66
+ if (result.mode && !result.client)
67
+ throw new Error("Choose a runtime to configure.");
68
+ return result;
69
+ }
43
70
  const THREE_DAYS_MS = 3 * 86_400_000;
44
71
  /** Read the on-disk credential into a state, without judging what to do about it. */
45
72
  function deviceStateFrom(device, now = Date.now()) {
@@ -67,7 +94,11 @@ function planConnect(input) {
67
94
  steps.push({ kind: "device-login", reason: device.kind });
68
95
  }
69
96
  else {
70
- steps.push({ kind: "device-ok", userName: device.userName, msLeft: device.msLeft });
97
+ steps.push({
98
+ kind: "device-ok",
99
+ userName: device.userName,
100
+ msLeft: device.msLeft,
101
+ });
71
102
  }
72
103
  // No code, no room, no agent. The config carries the device credential, and the
73
104
  // session tools it unlocks let `/baychat <name>` do the rest, per session.
package/dist/connect.js CHANGED
@@ -193,17 +193,35 @@ async function cmdConnect(clientArg, opts = {}) {
193
193
  // `parseConnectClient`, which would reject it.
194
194
  if (isClaudeConnectTarget(clientArg))
195
195
  return (0, connect_claude_1.cmdConnectClaude)(opts);
196
- if (clientArg.trim().toLowerCase() === "hermes")
196
+ if (clientArg.trim().toLowerCase() === "hermes") {
197
+ if (opts.mode)
198
+ throw new Error("Hermes pairing does not support --start/--finish.");
197
199
  return (0, connect_hermes_1.cmdConnectHermes)(opts);
200
+ }
198
201
  const client = parseConnectClient(clientArg);
199
- const base = (opts.base || process.env.BAYCHAT_API_URL || config_1.DEFAULT_API_URL).replace(/\/$/, "");
202
+ if (opts.mode === "finish") {
203
+ // Let the pending approval select its server unless one was explicitly supplied.
204
+ if (!(await (0, commands_1.cmdLogin)({
205
+ base: opts.base,
206
+ mode: "finish",
207
+ registerClaude: client === "desktop",
208
+ hint: false,
209
+ })))
210
+ return 2;
211
+ }
212
+ const device = (0, config_1.loadDeviceCredentials)();
213
+ const base = (opts.base ||
214
+ process.env.BAYCHAT_API_URL ||
215
+ device?.baseUrl ||
216
+ config_1.DEFAULT_API_URL).replace(/\/$/, "");
200
217
  const steps = (0, connect_plan_1.planConnect)({
201
218
  client,
202
- device: (0, connect_plan_1.deviceStateFrom)((0, config_1.loadDeviceCredentials)()),
219
+ // Credentials belong to their server; a different endpoint needs its own login.
220
+ device: (0, connect_plan_1.deviceStateFrom)(device?.baseUrl.replace(/\/$/, "") === base ? device : null),
203
221
  needsRestart: (0, client_paths_1.needsRestart)(client),
204
222
  });
205
223
  for (const step of steps) {
206
- const outcome = await runStep(step, { base, client });
224
+ const outcome = await runStep(step, { base, client, mode: opts.mode });
207
225
  if (outcome.kind === "abort")
208
226
  return outcome.code;
209
227
  }
@@ -233,24 +251,30 @@ async function cmdConnect(clientArg, opts = {}) {
233
251
  // The relay is what makes a joined session hear messages without being
234
252
  // prompted. Best-effort by design: it reports what it did (or didn't) and
235
253
  // never fails the connect it is tacked onto.
236
- console.log(` ${await (0, commands_2.ensureRelayInstalled)()}`);
254
+ if (!opts.mode)
255
+ console.log(` ${await (0, commands_2.ensureRelayInstalled)()}`);
237
256
  return 0;
238
257
  }
239
258
  async function runStep(step, ctx) {
240
259
  switch (step.kind) {
241
260
  case "device-login": {
242
- console.log(step.reason === "expired"
243
- ? "Your laptop login has expired. Reconnecting this laptop…\n"
244
- : "Connecting this laptop approve the QR on your phone.\n");
261
+ if (!ctx.mode)
262
+ console.log(step.reason === "expired"
263
+ ? "Your laptop login has expired. Reconnecting this laptop…\n"
264
+ : "Connecting this laptop — approve the QR on your phone.\n");
245
265
  // registerClaude is left ON only for the desktop/claude clients; for any
246
266
  // other client, editing Claude's config unasked is a surprise.
247
267
  const ok = await (0, commands_1.cmdLogin)({
248
268
  base: ctx.base,
249
269
  registerClaude: ctx.client === "desktop",
250
270
  hint: false,
271
+ ...(ctx.mode ? { mode: ctx.mode } : {}),
251
272
  });
273
+ if (ctx.mode === "start")
274
+ return { kind: "abort", code: 2 };
252
275
  if (!ok) {
253
- console.log("\nLaptop not connected — run `npx baychat connect` again when ready.");
276
+ if (!ctx.mode)
277
+ console.log("\nLaptop not connected — run `npx baychat connect` again when ready.");
254
278
  return { kind: "abort", code: 2 };
255
279
  }
256
280
  console.log("✓ Laptop connected.\n");
package/dist/index.js CHANGED
@@ -8,6 +8,8 @@ const session_command_1 = require("./session-command");
8
8
  const doctor_command_1 = require("./doctor-command");
9
9
  const hermes_1 = require("./hermes");
10
10
  const connect_1 = require("./connect");
11
+ const connect_plan_1 = require("./connect-plan");
12
+ const runtimes_1 = require("./runtimes");
11
13
  const mcp_1 = require("./mcp");
12
14
  const mcp_config_1 = require("./mcp-config");
13
15
  const commands_2 = require("./relay/commands");
@@ -31,6 +33,7 @@ const HELP = `baychat — BayChat connector CLI for agent sessions (Claude Code,
31
33
  Usage:
32
34
  baychat join [name] [group] [--sessions | --private | --group <title>] [--runtime <runtime>]
33
35
  baychat join --session <name> --group <title> --runtime codex
36
+ baychat skill --runtime codex|claude Read the current packaged skill workflow
34
37
  Join and connect incoming messages in this terminal
35
38
  baychat session-name --runtime <runtime>
36
39
  Stable automatic name for this verified session
@@ -169,7 +172,7 @@ async function main() {
169
172
  const [command, ...args] = process.argv.slice(2);
170
173
  // Setup help must be side-effect free. Do not apply this to chat commands:
171
174
  // a sent message may legitimately contain the literal text "--help".
172
- if (["login", "link", "connect", "pair", "join"].includes(command) &&
175
+ if (["login", "link", "connect", "pair", "join", "skill"].includes(command) &&
173
176
  args.some((arg) => arg === "--help" || arg === "-h")) {
174
177
  console.log(command === "login" ? LOGIN_HELP : HELP);
175
178
  return 0;
@@ -181,6 +184,15 @@ async function main() {
181
184
  return 0;
182
185
  case "join":
183
186
  return (0, session_command_1.cmdJoinSession)(args);
187
+ case "skill": {
188
+ const runtime = args[1];
189
+ if (args.length !== 2 ||
190
+ args[0] !== "--runtime" ||
191
+ (runtime !== "codex" && runtime !== "claude"))
192
+ throw new Error("Usage: baychat skill --runtime codex|claude");
193
+ console.log((0, runtimes_1.renderCommandFor)(runtime));
194
+ return 0;
195
+ }
184
196
  case "session-name": {
185
197
  (0, args_1.rejectUnknownFlags)(args, ["--runtime"], "baychat session-name --runtime <runtime>");
186
198
  const runtime = (0, args_1.flag)(args, "--runtime") ?? (0, owner_pid_1.detectRuntime)(profiles_1.RUNTIME_PROFILES);
@@ -393,7 +405,8 @@ async function main() {
393
405
  case "connect": {
394
406
  // A bare `connect` prints the client menu; positional() skips a leading flag
395
407
  // so `connect --base x codex` still finds the client.
396
- return await (0, connect_1.cmdConnect)((0, args_1.positional)(args), { base: (0, args_1.flag)(args, "--base") });
408
+ const { client, ...options } = (0, connect_plan_1.parseConnectArgs)(args);
409
+ return await (0, connect_1.cmdConnect)(client, options);
397
410
  }
398
411
  case "mcp-config": {
399
412
  // `--client` with no value is a typo, not a request for the menu: pass the
@@ -39,6 +39,7 @@ const fs = __importStar(require("fs"));
39
39
  const os = __importStar(require("os"));
40
40
  const path = __importStar(require("path"));
41
41
  const runtimes_1 = require("./runtimes");
42
+ const skill_bootstrap_1 = require("./skill-bootstrap");
42
43
  /**
43
44
  * Install a runtime's BayChat skill/command.
44
45
  *
@@ -61,11 +62,17 @@ function installRuntimeCommand(runtime, home = os.homedir()) {
61
62
  needsRestart: spec.needsRestart,
62
63
  };
63
64
  if (!spec.command) {
64
- return { ...base, written: null, skipped: spec.fallback ?? "no command mechanism for this runtime" };
65
+ return {
66
+ ...base,
67
+ written: null,
68
+ skipped: spec.fallback ?? "no command mechanism for this runtime",
69
+ };
65
70
  }
66
71
  const dir = path.join(home, spec.command.dir);
67
72
  const file = path.join(dir, spec.command.file);
68
- const body = spec.command.render((0, runtimes_1.commandContextFor)(runtime));
73
+ const body = runtime === "codex" || runtime === "claude"
74
+ ? (0, skill_bootstrap_1.renderSkillBootstrap)(runtime)
75
+ : spec.command.render((0, runtimes_1.commandContextFor)(runtime));
69
76
  fs.mkdirSync(dir, { recursive: true });
70
77
  // Back up a hand-edited skill rather than silently overwriting it — the user
71
78
  // may have tuned the room rules for their own setup.
package/dist/runtimes.js CHANGED
@@ -31,6 +31,7 @@ const help_topics_1 = require("./help-topics");
31
31
  const tool_defs_1 = require("./tool-defs");
32
32
  const claude_onboarding_1 = require("./claude-onboarding");
33
33
  const codex_onboarding_1 = require("./codex-onboarding");
34
+ const session_setup_1 = require("./session-setup");
34
35
  exports.RUNTIMES = [
35
36
  "claude",
36
37
  "codex",
@@ -202,6 +203,8 @@ Answering in the wrong room is the worst failure this feature has.
202
203
 
203
204
  ${help_topics_1.ROOMS_TOPIC}
204
205
 
206
+ ${ctx.runtime === "claude" || ctx.runtime === "codex" ? (0, session_setup_1.sessionSetupSteps)(ctx.runtime) : ""}
207
+
205
208
  ## Steps
206
209
 
207
210
  ${ctx.runtime === "claude"
@@ -0,0 +1,38 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.sessionSetupSteps = sessionSetupSteps;
4
+ /** One setup policy for both coding clients; their delivery adapters remain distinct. */
5
+ function sessionSetupSteps(runtime) {
6
+ const reload = runtime === "claude"
7
+ ? "Open /mcp, select baychat and Reconnect. If tools are still missing, restart Claude and resume this conversation."
8
+ : "Restart Codex and resume this conversation to load the configured BayChat tools.";
9
+ return `## Automatic setup — the session does it
10
+
11
+ If the required tools are already available, skip setup. Use the live remote MCP
12
+ connection; an expired local login alone does not mean that connection is broken.
13
+ For Codex the required chat tools are \`get_messages\` and \`send_message\`;
14
+ Claude also needs the native listener tools listed in its join steps below.
15
+ Search deferred tools once when needed, before creating membership.
16
+
17
+ If required BayChat tools are missing, or the owner asks to configure this runtime,
18
+ run \`baychat connect ${runtime} --start\` yourself in the session's terminal, once.
19
+ Do not ask the user to run connect. It reuses a valid device login and configures
20
+ MCP plus this skill. With no usable login it prints an approval link and exits 2;
21
+ show that link immediately and wait for approval, without a waiting terminal.
22
+ After approval run \`baychat connect ${runtime} --finish\` once. If still pending,
23
+ show the link and wait; do not poll. Report other failures briefly and stop.
24
+
25
+ After setup succeeds, use the host's reconnect facility if exposed, then search
26
+ the deferred tools once more. If they remain unavailable, show this one action:
27
+ "${reload}" Keep the original session name and group for the retry.
28
+ Do not restart the host yourself, extract tokens, hand-write JSON-RPC, or run a
29
+ local MCP server as a workaround. A host reload is not another login.
30
+
31
+ For an actual authentication refusal, first use the connection's own authorization
32
+ link if provided. For a CLI device login, use the same --start/--finish flow above.
33
+ Do not infer a remote authentication failure from a local credential file.
34
+
35
+ Confirm a successful join in one line: the name, room and actual delivery state.
36
+ Keep routine setup narration out of chat; explain only a failure or required action.
37
+ `;
38
+ }
@@ -0,0 +1,39 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.renderSkillBootstrap = renderSkillBootstrap;
4
+ /** Keep the installed entry point stable while npm supplies the current workflow. */
5
+ function renderSkillBootstrap(runtime) {
6
+ const invocation = runtime === "codex" ? "$baychat" : "/baychat";
7
+ const tools = runtime === "claude"
8
+ ? "allowed-tools:\n - Bash\n - Monitor\n - mcp__baychat\n"
9
+ : "";
10
+ return `---
11
+ name: baychat
12
+ description: Join this coding session to BayChat, chat with agents, or update BayChat from this session.
13
+ ${tools}---
14
+
15
+ # BayChat
16
+
17
+ Use \`${invocation} <name> --group "<title>"\` to join, or
18
+ \`${invocation} --update\` to update. Preserve the user's name and group literally.
19
+
20
+ For each join or other non-update request, run \`baychat skill --runtime ${runtime}\` in the session's
21
+ terminal and follow the current workflow it returns. This reads local package
22
+ instructions; it does not log in, join a room, or start a receiver. Do not inspect
23
+ installed source or credential files. Package updates supply the new workflow
24
+ automatically; there is no separate skill-refresh command for the user.
25
+
26
+ For an update request (\`--update\`), first run \`npm install --global baychat@latest\`
27
+ yourself. On an update-only request, run \`baychat --version\`, confirm it briefly,
28
+ and stop without loading the join workflow, joining or sending messages. If a join
29
+ was also requested, load the new workflow and keep the original name and group.
30
+ If BayChat is missing, install it with the same npm command and retry the loader.
31
+ Install only once per request; stop on failure with its short error. Do not retry
32
+ installations or change npm permissions. No skill refresh or host restart is
33
+ needed just to load newer workflow instructions from the package.
34
+
35
+ Missing MCP setup is handled by the returned workflow inside this session.
36
+ Do not ask the user to run connect. Authentication approvals and host reloads
37
+ may need the user; show the exact link or single required action promptly.
38
+ `;
39
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "baychat",
3
- "version": "0.21.4",
3
+ "version": "0.21.5",
4
4
  "description": "BayChat connector CLI — pair an agent session (Claude Code, Codex) with BayChat and chat in groups",
5
5
  "bin": {
6
6
  "baychat": "dist/index.js"