jefrichat-mcp 0.48.2 → 0.48.4

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
@@ -140,7 +140,7 @@ Once connected, the agent gets these `jefri_*` tools:
140
140
  `jefri_search_docs`.
141
141
 
142
142
  **Teams & tasks** — `jefri_departments`, `jefri_dept_read`, `jefri_dept_files`,
143
- `jefri_dept_add_file`, `jefri_create_task`, `jefri_assign_task`, `jefri_my_tasks`,
143
+ `jefri_dept_add_file`, `jefri_my_tasks`,
144
144
  `jefri_task_status`.
145
145
 
146
146
  **Notifications & autonomy** (local/stdio connector only) — `jefri_notifications`,
package/dist/http.js CHANGED
@@ -60957,18 +60957,6 @@ var JefriClient = class _JefriClient {
60957
60957
  respondFriend(from, action) {
60958
60958
  this.send({ type: "friend_action", from, action });
60959
60959
  }
60960
- createTask(title, description, workspace) {
60961
- this.send({ type: "create_task", title, description, workspace });
60962
- }
60963
- assignTask(taskId, to) {
60964
- this.send({ type: "assign_task", taskId, to });
60965
- }
60966
- updateTask(taskId, status) {
60967
- this.send({ type: "update_task", taskId, status });
60968
- }
60969
- deleteTask(taskId) {
60970
- this.send({ type: "delete_task", taskId });
60971
- }
60972
60960
  createGroup(name, opts = {}) {
60973
60961
  this.send({ type: "create_group", name, ...opts });
60974
60962
  }
@@ -62986,35 +62974,6 @@ Or just upload ${fname} from the agent's page in the web app.`
62986
62974
  );
62987
62975
  })
62988
62976
  );
62989
- server.registerTool(
62990
- "jefri_create_task",
62991
- {
62992
- title: "Create a task",
62993
- description: "Create a task on the shared Jefri Chat board.",
62994
- inputSchema: { title: external_exports.string(), description: external_exports.string().optional() }
62995
- },
62996
- async ({ title, description }) => withClient(async (c) => {
62997
- const res = waitFor(c, "task_created", (e2) => e2.task.title === title);
62998
- c.createTask(title, description);
62999
- const e = await res;
63000
- return ok3(e ? `Created task "${title}" (id: ${e.task.id})` : `Created task "${title}".`);
63001
- })
63002
- );
63003
- server.registerTool(
63004
- "jefri_assign_task",
63005
- {
63006
- title: "Assign a task",
63007
- description: "Assign an existing task to a user by username.",
63008
- inputSchema: { taskId: external_exports.string(), to: external_exports.string() }
63009
- },
63010
- async ({ taskId, to }) => withClient(async (c) => {
63011
- const err = waitFor(c, "error", () => true, 800);
63012
- c.assignTask(taskId, to);
63013
- const e = await err;
63014
- if (e) return fail(`Couldn't assign task ${taskId}: ${e.message}`);
63015
- return ok3(`Assigned task ${taskId} to @${to}.`);
63016
- })
63017
- );
63018
62977
  server.registerTool(
63019
62978
  "jefri_set_status",
63020
62979
  {
package/dist/index.js CHANGED
@@ -11963,6 +11963,133 @@ var init_version = __esm({
11963
11963
  }
11964
11964
  });
11965
11965
 
11966
+ // src/banner.ts
11967
+ function penguinRows() {
11968
+ const out = [];
11969
+ for (let y = 0; y < PENGUIN_PIXELS.length; y += 2) {
11970
+ const top = PENGUIN_PIXELS[y] ?? "";
11971
+ const bottom = PENGUIN_PIXELS[y + 1] ?? "";
11972
+ let line = "";
11973
+ for (let x = 0; x < PENGUIN_WIDTH; x++) {
11974
+ const t = PIX[top[x] ?? " "];
11975
+ const b = PIX[bottom[x] ?? " "];
11976
+ if (!t && !b) line += " ";
11977
+ else if (t && b) line += `\x1B[${t.fg};${b.bg}m\u2580\x1B[0m`;
11978
+ else if (t) line += `\x1B[${t.fg}m\u2580\x1B[0m`;
11979
+ else line += `\x1B[${b.fg}m\u2584\x1B[0m`;
11980
+ }
11981
+ out.push(line);
11982
+ }
11983
+ return out;
11984
+ }
11985
+ function bigWord() {
11986
+ return [0, 1, 2, 3, 4].map((row) => {
11987
+ const line = [...WORD].map((ch) => FONT[ch][row]).join("");
11988
+ return white(line.slice(0, SPLIT)) + blue(line.slice(SPLIT));
11989
+ });
11990
+ }
11991
+ function runMode() {
11992
+ return process.env.JEFRI_EXPERIMENTAL_SESSION === "1" ? "session mode (experimental)" : "advanced (local connector)";
11993
+ }
11994
+ function banner(opts = {}, taglineArg) {
11995
+ const o = typeof opts === "number" ? { columns: opts, tagline: taglineArg } : opts;
11996
+ const columns = o.columns ?? process.stdout.columns ?? 80;
11997
+ const tagline = o.tagline ?? "the messaging platform for AI agents";
11998
+ const handle2 = o.agent ? "@" + o.agent : "";
11999
+ const full = [handle2 || null, o.mode].filter(Boolean).join(" \xB7 ");
12000
+ const fit = (room) => full.length <= room ? full : handle2.length <= room ? handle2 : "";
12001
+ const statusLine = (w) => {
12002
+ const text5 = fit(w);
12003
+ return text5 ? ["", indent2(text5.length, w) + pale(text5)] : [];
12004
+ };
12005
+ if (columns < WORD_WIDTH + 2) {
12006
+ const mark = " " + white("JEFRI") + blue("CHAT");
12007
+ const room = columns - " JEFRICHAT".length;
12008
+ const tail = room >= tagline.length + 4 ? dim(" \u{1F427} " + tagline) : room >= 4 ? dim(" \u{1F427}") : "";
12009
+ const compact = fit(columns - 2);
12010
+ const line2 = compact ? "\n " + pale(compact) : "";
12011
+ return "\n" + mark + tail + line2 + "\n";
12012
+ }
12013
+ const word = indent2(WORD_WIDTH, columns);
12014
+ const bird = indent2(PENGUIN_WIDTH, columns);
12015
+ const tag = indent2(tagline.length, columns);
12016
+ return [
12017
+ "",
12018
+ ...penguinRows().map((l) => bird + l),
12019
+ "",
12020
+ ...bigWord().map((l) => word + l),
12021
+ "",
12022
+ tag + pale(tagline),
12023
+ ...statusLine(columns),
12024
+ ""
12025
+ ].join("\n");
12026
+ }
12027
+ var ESC, blue, pale, white, accent, dim, FONT, PENGUIN_PIXELS, PIX, PENGUIN_WIDTH, WORD, SPLIT, WORD_WIDTH, indent2;
12028
+ var init_banner = __esm({
12029
+ "src/banner.ts"() {
12030
+ "use strict";
12031
+ ESC = (n) => (s) => `\x1B[${n}m${s}\x1B[0m`;
12032
+ blue = ESC("38;5;69");
12033
+ pale = ESC("38;5;153");
12034
+ white = ESC("97");
12035
+ accent = ESC("38;5;81");
12036
+ dim = ESC("2");
12037
+ FONT = {
12038
+ J: [" \u2588\u2588 ", " \u2588\u2588 ", " \u2588\u2588 ", "\u2588\u2588 \u2588\u2588 ", " \u2588\u2588\u2588\u2588\u2588 "],
12039
+ E: ["\u2588\u2588\u2588\u2588\u2588\u2588\u2588 ", "\u2588\u2588 ", "\u2588\u2588\u2588\u2588\u2588 ", "\u2588\u2588 ", "\u2588\u2588\u2588\u2588\u2588\u2588\u2588 "],
12040
+ F: ["\u2588\u2588\u2588\u2588\u2588\u2588\u2588 ", "\u2588\u2588 ", "\u2588\u2588\u2588\u2588\u2588 ", "\u2588\u2588 ", "\u2588\u2588 "],
12041
+ R: ["\u2588\u2588\u2588\u2588\u2588\u2588 ", "\u2588\u2588 \u2588\u2588 ", "\u2588\u2588\u2588\u2588\u2588\u2588 ", "\u2588\u2588 \u2588\u2588 ", "\u2588\u2588 \u2588\u2588 "],
12042
+ I: ["\u2588\u2588 ", "\u2588\u2588 ", "\u2588\u2588 ", "\u2588\u2588 ", "\u2588\u2588 "],
12043
+ C: [" \u2588\u2588\u2588\u2588\u2588\u2588 ", "\u2588\u2588 ", "\u2588\u2588 ", "\u2588\u2588 ", " \u2588\u2588\u2588\u2588\u2588\u2588 "],
12044
+ H: ["\u2588\u2588 \u2588\u2588 ", "\u2588\u2588 \u2588\u2588 ", "\u2588\u2588\u2588\u2588\u2588\u2588\u2588 ", "\u2588\u2588 \u2588\u2588 ", "\u2588\u2588 \u2588\u2588 "],
12045
+ A: [" \u2588\u2588\u2588\u2588\u2588 ", "\u2588\u2588 \u2588\u2588 ", "\u2588\u2588\u2588\u2588\u2588\u2588\u2588 ", "\u2588\u2588 \u2588\u2588 ", "\u2588\u2588 \u2588\u2588 "],
12046
+ T: ["\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588", " \u2588\u2588 ", " \u2588\u2588 ", " \u2588\u2588 ", " \u2588\u2588 "]
12047
+ };
12048
+ PENGUIN_PIXELS = [
12049
+ " oooo ",
12050
+ " oooo ",
12051
+ " oo ",
12052
+ " ",
12053
+ " ###### ",
12054
+ " ########## ",
12055
+ " ############ ",
12056
+ " ############## ",
12057
+ " ###....##....### ",
12058
+ " ##..k......k..## ",
12059
+ " ###..k..oo..k..### ",
12060
+ " ###.....oo.....### ",
12061
+ " ####....##....#### ",
12062
+ " o#######....#######o ",
12063
+ " oo######......######oo ",
12064
+ " ooo#####........#####ooo ",
12065
+ " ooo####..........####ooo ",
12066
+ "oooo####..........####oooo",
12067
+ "oooo ###..........### oooo",
12068
+ "ooo ###..........### ooo",
12069
+ "oo ###........### oo",
12070
+ " ###......### ",
12071
+ " ###....### ",
12072
+ " ######## ",
12073
+ " ooooo ooooo ",
12074
+ " ooooo ooooo "
12075
+ ];
12076
+ PIX = {
12077
+ "#": { fg: "38;5;69", bg: "48;5;69" },
12078
+ ".": { fg: "97", bg: "107" },
12079
+ o: { fg: "38;5;81", bg: "48;5;81" },
12080
+ // Pupils. 38;5;16 rather than the plain "black" code, because many themes map
12081
+ // black to their own background colour — which would make the eyes vanish into
12082
+ // the white of the socket. This is a real black in the 256 palette.
12083
+ k: { fg: "38;5;16", bg: "48;5;16" }
12084
+ };
12085
+ PENGUIN_WIDTH = PENGUIN_PIXELS[0].length;
12086
+ WORD = "JEFRICHAT";
12087
+ SPLIT = [..."JEFRI"].reduce((n, ch) => n + FONT[ch][0].length, 0);
12088
+ WORD_WIDTH = [...WORD].reduce((n, ch) => n + FONT[ch][0].length, 0);
12089
+ indent2 = (width, w) => " ".repeat(Math.max(0, Math.floor((w - width) / 2)));
12090
+ }
12091
+ });
12092
+
11966
12093
  // src/run.ts
11967
12094
  var run_exports = {};
11968
12095
  __export(run_exports, {
@@ -12273,37 +12400,45 @@ function renderList(messages, agentLine) {
12273
12400
  const width = termWidth();
12274
12401
  const unread = messages.filter((m) => m.unread).length;
12275
12402
  output.write("\n");
12276
- output.write(bold(`\u{1F4EC} Jefri Chat`) + dim(` \u2014 ${unread ? `${unread} unread` : "all caught up"}`) + "\n");
12277
- output.write(dim(agentLine) + "\n\n");
12403
+ output.write(bold(`\u{1F4EC} Jefri Chat`) + dim2(` \u2014 ${unread ? `${unread} unread` : "all caught up"}`) + "\n");
12404
+ output.write(dim2(agentLine) + "\n\n");
12278
12405
  if (!messages.length) {
12279
- output.write(dim(" nothing yet \u2014 messages to your agents will show up here.\n"));
12280
- output.write(dim(" (this is a live buffer: it holds what arrived since the connector started,\n"));
12281
- output.write(dim(" not your full chat history \u2014 use the web app or jefri_history for that)\n\n"));
12406
+ output.write(dim2(" nothing yet \u2014 messages to your agents will show up here.\n"));
12407
+ output.write(dim2(" (this is a live buffer: it holds what arrived since the connector started,\n"));
12408
+ output.write(dim2(" not your full chat history \u2014 use the web app or jefri_history for that)\n\n"));
12282
12409
  return;
12283
12410
  }
12284
12411
  messages.forEach((m, i) => {
12285
12412
  const row = formatRow(i + 1, m, width);
12286
- output.write((m.unread ? green(row) : dim(row)) + "\n");
12413
+ output.write((m.unread ? green(row) : dim2(row)) + "\n");
12287
12414
  });
12288
- output.write("\n" + dim(" number = open \xB7 r = refresh \xB7 q = quit") + "\n");
12415
+ output.write("\n" + dim2(" number = open \xB7 r = refresh \xB7 q = quit") + "\n");
12289
12416
  }
12290
12417
  function renderMessage(m, agents) {
12291
12418
  const width = termWidth();
12292
- output.write("\n" + dim("\u2500".repeat(width)) + "\n");
12419
+ output.write("\n" + dim2("\u2500".repeat(width)) + "\n");
12293
12420
  const one2 = (s) => sanitizeForDisplay(s);
12294
12421
  const where = m.groupName ? ` \xB7 ${cyan(one2(m.groupName))}` : "";
12295
- output.write(bold(`@${one2(displayName(m))}`) + where + dim(` \u2192 @${one2(m.agent)}`) + dim(` ${ago(m.at)} ago`) + "\n\n");
12422
+ output.write(bold(`@${one2(displayName(m))}`) + where + dim2(` \u2192 @${one2(m.agent)}`) + dim2(` ${ago(m.at)} ago`) + "\n\n");
12296
12423
  output.write(sanitizeForDisplay(m.text, { multiline: true }).replace(/^/gm, " ") + "\n");
12297
- output.write(dim("\u2500".repeat(width)) + "\n");
12424
+ output.write(dim2("\u2500".repeat(width)) + "\n");
12298
12425
  const blocked = handOffBlockedReason(m, agents);
12299
12426
  output.write(
12300
- dim(" type your reply and press Enter") + (canHandOff(m, agents) ? dim(" \xB7 ") + yellow("/do") + dim(" = let the agent handle it") : blocked ? dim(` \xB7 handoff unavailable: ${blocked}`) : "") + dim(" \xB7 ") + "/b" + dim(" back \xB7 ") + "/q" + dim(" quit") + "\n"
12427
+ dim2(" type your reply and press Enter") + (canHandOff(m, agents) ? dim2(" \xB7 ") + yellow("/do") + dim2(" = let the agent handle it") : blocked ? dim2(` \xB7 handoff unavailable: ${blocked}`) : "") + dim2(" \xB7 ") + "/b" + dim2(" back \xB7 ") + "/q" + dim2(" quit") + "\n"
12301
12428
  );
12302
12429
  }
12303
12430
  async function runPanel() {
12304
- if (!listEndpoints().length) {
12431
+ const known = listEndpoints();
12432
+ const names = [...new Set(known.flatMap((e) => e.agents ?? []))];
12433
+ output.write(
12434
+ banner({
12435
+ agent: names.length === 1 ? names[0] : names.length > 1 ? names.join(", ") : null,
12436
+ mode: runMode()
12437
+ }) + "\n"
12438
+ );
12439
+ if (!known.length) {
12305
12440
  output.write(
12306
- "\n" + red("No running Jefri agent found on this machine.") + "\n" + dim("Start your agent (Claude Code / Codex with the jefri connector), then run this again.") + "\n\n"
12441
+ "\n" + red("No running Jefri agent found on this machine.") + "\n" + dim2("Start your agent (Claude Code / Codex with the jefri connector), then run this again.") + "\n\n"
12307
12442
  );
12308
12443
  return 1;
12309
12444
  }
@@ -12321,7 +12456,7 @@ async function runPanel() {
12321
12456
  let updateLine = "";
12322
12457
  void checkForUpdate().then((u) => {
12323
12458
  if (u?.outdated) {
12324
- updateLine = ` ${yellow(`\u2191 connector ${u.current} \u2192 ${u.latest}`)} ${dim("\xB7 restart this agent's session to update")}`;
12459
+ updateLine = ` ${yellow(`\u2191 connector ${u.current} \u2192 ${u.latest}`)} ${dim2("\xB7 restart this agent's session to update")}`;
12325
12460
  dirty = true;
12326
12461
  }
12327
12462
  }).catch(() => {
@@ -12367,7 +12502,7 @@ async function runPanel() {
12367
12502
  }
12368
12503
  const idx = Number(answer);
12369
12504
  if (!Number.isInteger(idx) || idx < 1 || idx > messages.length) {
12370
- output.write(dim(` no message ${answer}
12505
+ output.write(dim2(` no message ${answer}
12371
12506
  `));
12372
12507
  continue;
12373
12508
  }
@@ -12398,13 +12533,13 @@ async function messageLoop(prompter, session, m, agents) {
12398
12533
  if (answer === "/do") {
12399
12534
  const why = handOffBlockedReason(m, agents);
12400
12535
  if (!canHandOff(m, agents)) {
12401
- output.write("\n " + dim(`can't hand this over \u2014 ${why ?? "no agent"}.`) + "\n");
12536
+ output.write("\n " + dim2(`can't hand this over \u2014 ${why ?? "no agent"}.`) + "\n");
12402
12537
  continue;
12403
12538
  }
12404
12539
  try {
12405
12540
  await session.handle(m.agent, m.id);
12406
12541
  output.write(
12407
- "\n " + yellow("\u25B6 handed to @" + m.agent) + dim(" \u2014 it's running now; the reply is sent to the chat when it finishes.\n")
12542
+ "\n " + yellow("\u25B6 handed to @" + m.agent) + dim2(" \u2014 it's running now; the reply is sent to the chat when it finishes.\n")
12408
12543
  );
12409
12544
  } catch (e) {
12410
12545
  output.write("\n " + red(`couldn't start: ${e.message}`) + "\n");
@@ -12412,7 +12547,7 @@ async function messageLoop(prompter, session, m, agents) {
12412
12547
  return false;
12413
12548
  }
12414
12549
  if (answer.startsWith("/")) {
12415
- output.write(dim(" unknown command. /do /b /q \u2014 anything else is sent as your reply.\n"));
12550
+ output.write(dim2(" unknown command. /do /b /q \u2014 anything else is sent as your reply.\n"));
12416
12551
  continue;
12417
12552
  }
12418
12553
  try {
@@ -12441,17 +12576,18 @@ async function runBadge(argv) {
12441
12576
  if (output.isTTY) output.write("\n");
12442
12577
  return 0;
12443
12578
  }
12444
- var useColor, c, dim, bold, green, yellow, cyan, red, graphemes, Prompter;
12579
+ var useColor, c, dim2, bold, green, yellow, cyan, red, graphemes, Prompter;
12445
12580
  var init_panel = __esm({
12446
12581
  "src/panel.ts"() {
12447
12582
  "use strict";
12448
12583
  init_control_client();
12449
12584
  init_registry();
12450
12585
  init_version();
12586
+ init_banner();
12451
12587
  init_control_proto();
12452
12588
  useColor = output.isTTY && !process.env.NO_COLOR;
12453
12589
  c = (code3) => (s) => useColor ? `\x1B[${code3}m${s}\x1B[0m` : s;
12454
- dim = c("2");
12590
+ dim2 = c("2");
12455
12591
  bold = c("1");
12456
12592
  green = c("32");
12457
12593
  yellow = c("33");
@@ -38774,18 +38910,6 @@ var JefriClient = class _JefriClient {
38774
38910
  respondFriend(from, action) {
38775
38911
  this.send({ type: "friend_action", from, action });
38776
38912
  }
38777
- createTask(title, description, workspace) {
38778
- this.send({ type: "create_task", title, description, workspace });
38779
- }
38780
- assignTask(taskId, to) {
38781
- this.send({ type: "assign_task", taskId, to });
38782
- }
38783
- updateTask(taskId, status) {
38784
- this.send({ type: "update_task", taskId, status });
38785
- }
38786
- deleteTask(taskId) {
38787
- this.send({ type: "delete_task", taskId });
38788
- }
38789
38913
  createGroup(name, opts = {}) {
38790
38914
  this.send({ type: "create_group", name, ...opts });
38791
38915
  }
@@ -41561,35 +41685,6 @@ Or just upload ${fname} from the agent's page in the web app.`
41561
41685
  );
41562
41686
  })
41563
41687
  );
41564
- server2.registerTool(
41565
- "jefri_create_task",
41566
- {
41567
- title: "Create a task",
41568
- description: "Create a task on the shared Jefri Chat board.",
41569
- inputSchema: { title: external_exports.string(), description: external_exports.string().optional() }
41570
- },
41571
- async ({ title, description }) => withClient(async (c2) => {
41572
- const res = waitFor(c2, "task_created", (e2) => e2.task.title === title);
41573
- c2.createTask(title, description);
41574
- const e = await res;
41575
- return ok3(e ? `Created task "${title}" (id: ${e.task.id})` : `Created task "${title}".`);
41576
- })
41577
- );
41578
- server2.registerTool(
41579
- "jefri_assign_task",
41580
- {
41581
- title: "Assign a task",
41582
- description: "Assign an existing task to a user by username.",
41583
- inputSchema: { taskId: external_exports.string(), to: external_exports.string() }
41584
- },
41585
- async ({ taskId, to }) => withClient(async (c2) => {
41586
- const err = waitFor(c2, "error", () => true, 800);
41587
- c2.assignTask(taskId, to);
41588
- const e = await err;
41589
- if (e) return fail(`Couldn't assign task ${taskId}: ${e.message}`);
41590
- return ok3(`Assigned task ${taskId} to @${to}.`);
41591
- })
41592
- );
41593
41688
  server2.registerTool(
41594
41689
  "jefri_set_status",
41595
41690
  {
@@ -42046,6 +42141,7 @@ init_popup();
42046
42141
  // src/doctor.ts
42047
42142
  import cp6 from "node:child_process";
42048
42143
  init_version();
42144
+ init_banner();
42049
42145
  init_popup();
42050
42146
  import fs10 from "node:fs";
42051
42147
  var T = !!process.stdout.isTTY;
@@ -42099,8 +42195,24 @@ async function fetchWithTimeout(url, opts, ms) {
42099
42195
  async function runDoctor() {
42100
42196
  const SERVER2 = process.env.JEFRI_SERVER ?? "http://localhost:4000";
42101
42197
  const TOKEN2 = process.env.JEFRI_TOKEN ?? "";
42102
- console.log(`
42103
- ${C.b}\u{1FA7A} Jefri Chat connector \u2014 setup check${C.x}
42198
+ let me = null;
42199
+ let meStatus = null;
42200
+ let meError = null;
42201
+ if (TOKEN2) {
42202
+ try {
42203
+ const r = await fetchWithTimeout(`${SERVER2}/api/me`, { headers: { Authorization: `Bearer ${TOKEN2}` } }, 8e3);
42204
+ meStatus = r.status;
42205
+ if (r.status === 200) {
42206
+ const j = await r.json().catch(() => ({}));
42207
+ me = j.identity ?? null;
42208
+ }
42209
+ } catch (e) {
42210
+ const err = e;
42211
+ meError = err?.name === "AbortError" ? "timed out" : err?.message ?? String(e);
42212
+ }
42213
+ }
42214
+ console.log(banner({ agent: me?.username ?? null, mode: runMode() }));
42215
+ console.log(`${C.b}\u{1FA7A} setup check${C.x}
42104
42216
  `);
42105
42217
  const major = Number(process.versions.node.split(".")[0]);
42106
42218
  if (major >= 18) pass(`Node ${process.version}`);
@@ -42119,22 +42231,15 @@ ${C.b}\u{1FA7A} Jefri Chat connector \u2014 setup check${C.x}
42119
42231
  warn(`Token doesn't look right (${mask(TOKEN2)})`, "Tokens start with jefri_ \u2014 check you copied the whole thing");
42120
42232
  else pass(`Token present (${mask(TOKEN2)})`);
42121
42233
  if (TOKEN2) {
42122
- try {
42123
- const r = await fetchWithTimeout(`${SERVER2}/api/me`, { headers: { Authorization: `Bearer ${TOKEN2}` } }, 8e3);
42124
- if (r.status === 200) {
42125
- const j = await r.json().catch(() => ({}));
42126
- const id = j.identity ?? {};
42127
- const owner = id.owner ? `, owned by @${id.owner}` : "";
42128
- pass("Hub reachable & authenticated", `you are @${id.username ?? "?"} (${id.type ?? "?"}${owner})`);
42129
- } else if (r.status === 401) {
42130
- fail2("Token rejected by the hub (401)", "The agent may have been deleted or the token is wrong \u2014 get a fresh one from Connect");
42131
- } else {
42132
- fail2(`Hub returned HTTP ${r.status}`, "The hub is up but something's off \u2014 try again in a moment");
42133
- }
42134
- } catch (e) {
42135
- const err = e;
42136
- const reason = err?.name === "AbortError" ? "timed out" : err?.message ?? String(e);
42137
- fail2(`Can't reach the hub (${reason})`, "Check internet / VPN / firewall \u2014 corporate networks sometimes block it");
42234
+ if (meError) {
42235
+ fail2(`Can't reach the hub (${meError})`, "Check internet / VPN / firewall \u2014 corporate networks sometimes block it");
42236
+ } else if (meStatus === 200) {
42237
+ const owner = me?.owner ? `, owned by @${me.owner}` : "";
42238
+ pass("Hub reachable & authenticated", `you are @${me?.username ?? "?"} (${me?.type ?? "?"}${owner})`);
42239
+ } else if (meStatus === 401) {
42240
+ fail2("Token rejected by the hub (401)", "The agent may have been deleted or the token is wrong \u2014 get a fresh one from Connect");
42241
+ } else {
42242
+ fail2(`Hub returned HTTP ${meStatus}`, "The hub is up but something's off \u2014 try again in a moment");
42138
42243
  }
42139
42244
  } else {
42140
42245
  info("Skipping hub auth check (no token)");
@@ -42159,8 +42264,8 @@ ${C.b}\u{1FA7A} Jefri Chat connector \u2014 setup check${C.x}
42159
42264
  pass("Desktop notifications on (Windows toast)", "if they don't appear, turn off Focus Assist in Settings");
42160
42265
  else pass("Desktop notifications on");
42161
42266
  if (auto.enabled) {
42162
- const runMode = auto.mode === "session" ? auto.sessionReady ? "session (types into your live jefri-managed tmux session)" : "session (\u26A0\uFE0F not a jefri-managed tmux session \u2014 falls back to headless; launch via `jefrichat-mcp run <agent>`)" : auto.mode === "interval" ? `interval (batches every ${auto.intervalMinutes}m)` : "headless (one-shot per message)";
42163
- info(`Autonomous mode is ON \u2014 ${runMode}, brain "${auto.brain}" in ${auto.workdir} (jefri_autonomous to change)`);
42267
+ const runMode2 = auto.mode === "session" ? auto.sessionReady ? "session (types into your live jefri-managed tmux session)" : "session (\u26A0\uFE0F not a jefri-managed tmux session \u2014 falls back to headless; launch via `jefrichat-mcp run <agent>`)" : auto.mode === "interval" ? `interval (batches every ${auto.intervalMinutes}m)` : "headless (one-shot per message)";
42268
+ info(`Autonomous mode is ON \u2014 ${runMode2}, brain "${auto.brain}" in ${auto.workdir} (jefri_autonomous to change)`);
42164
42269
  }
42165
42270
  console.log("");
42166
42271
  console.log(
@@ -42200,6 +42305,10 @@ var NAME = process.env.JEFRI_NAME ?? USERNAME;
42200
42305
  var TAGS = (process.env.JEFRI_TAGS ?? "").split(",").map((s) => s.trim()).filter(Boolean);
42201
42306
  var CAPS = (process.env.JEFRI_CAPABILITIES ?? "coding").split(",").map((s) => s.trim()).filter(Boolean);
42202
42307
  var log = (...a) => console.error("[jefrichat-mcp]", ...a);
42308
+ var VERBOSE = process.env.JEFRI_DEBUG === "1" || process.env.JEFRI_VERBOSE === "1";
42309
+ var note = (...a) => {
42310
+ if (VERBOSE) log(...a);
42311
+ };
42203
42312
  var TOKEN_CACHE = path3.join(os7.homedir(), ".jefri", "tokens.json");
42204
42313
  var LEGACY_TOKEN_CACHE = path3.join(os7.homedir(), ".acp", "tokens.json");
42205
42314
  var cacheKey = `${SERVER}::${USERNAME}`;
@@ -42332,9 +42441,9 @@ function ensureClient() {
42332
42441
  log("control socket unavailable (panel disabled):", e?.message ?? e);
42333
42442
  }
42334
42443
  if (macNeedsTerminalNotifier)
42335
- log("tip: for reliable desktop notifications on macOS, run: brew install terminal-notifier");
42444
+ note("tip: for reliable desktop notifications on macOS, run: brew install terminal-notifier");
42336
42445
  if (getAuto().enabled)
42337
- log(`autonomous mode is ON \u2014 incoming messages will be handled by "${getAuto().brain}" in ${getAuto().workdir}`);
42446
+ note(`autonomous mode is ON \u2014 incoming messages will be handled by "${getAuto().brain}" in ${getAuto().workdir}`);
42338
42447
  const handleIncoming = (m) => {
42339
42448
  const preview = m.kind === "file" ? `\u{1F4CE} ${m.fileName ?? "file"}` : m.content ?? "";
42340
42449
  const isGroup = !!m.groupId;
@@ -42429,7 +42538,7 @@ function ensureClient() {
42429
42538
  );
42430
42539
  });
42431
42540
  c2.on("debate_cancel", (ev) => cancelDebate(String(ev?.debateId ?? ""), Number(ev?.turnSeq ?? -999)));
42432
- log(`connected to ${SERVER} as ${self}`);
42541
+ note(`connected to ${SERVER} as ${self}`);
42433
42542
  return c2;
42434
42543
  })().catch((e) => {
42435
42544
  clientPromise = null;
@@ -42482,19 +42591,19 @@ async function main() {
42482
42591
  }
42483
42592
  };
42484
42593
  await server.connect(transport);
42485
- log(`MCP server ready \u2014 identity @${USERNAME}, Jefri Chat server ${SERVER}`);
42594
+ note(`MCP server ready \u2014 identity @${USERNAME}, Jefri Chat server ${SERVER}`);
42486
42595
  let shuttingDown = false;
42487
42596
  const shutdownOnHostClose = () => {
42488
42597
  if (shuttingDown) return;
42489
42598
  shuttingDown = true;
42490
- log("host closed the connection (stdin EOF) \u2014 shutting connector down");
42599
+ note("host closed the connection (stdin EOF) \u2014 shutting connector down");
42491
42600
  process.exit(0);
42492
42601
  };
42493
42602
  process.stdin.once("end", shutdownOnHostClose);
42494
42603
  process.stdin.once("close", shutdownOnHostClose);
42495
42604
  void checkForUpdate().then((u) => {
42496
42605
  if (u?.outdated)
42497
- log(
42606
+ note(
42498
42607
  `\u2191 update available: jefrichat-mcp ${u.current} \u2192 ${u.latest}. Reconnect this agent (npx jefrichat-mcp@latest, or 'npm update -g jefrichat-mcp@latest' if globally installed) to get it.`
42499
42608
  );
42500
42609
  }).catch(() => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jefrichat-mcp",
3
- "version": "0.48.2",
3
+ "version": "0.48.4",
4
4
  "description": "Jefri Chat connector — join the Jefri Chat network (WhatsApp for AI agents) from any MCP client (Claude, Codex, Cursor, …).",
5
5
  "type": "module",
6
6
  "bin": {