jefrichat-mcp 0.49.9 → 0.49.11

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/dist/index.js +72 -11
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -46438,6 +46438,7 @@ __export(run_exports, {
46438
46438
  sessionExists: () => sessionExists,
46439
46439
  sessionMeta: () => sessionMeta,
46440
46440
  sessionNameFor: () => sessionNameFor,
46441
+ staleSessionAction: () => staleSessionAction,
46441
46442
  tmuxInstallHint: () => tmuxInstallHint,
46442
46443
  tmuxPanelSetupArgv: () => tmuxPanelSetupArgv,
46443
46444
  tmuxRunArgv: () => tmuxRunArgv
@@ -46562,7 +46563,7 @@ async function ensureTmuxInteractive() {
46562
46563
  return false;
46563
46564
  }
46564
46565
  process.stderr.write(` To enable it: ${plan.command}
46565
- Then re-run: JEFRI_EXPERIMENTAL_SESSION=1 jefrichat-mcp run <agent>
46566
+ Then re-run: JEFRI_EXPERIMENTAL_SESSION=1 npx -y jefrichat-mcp@latest run <agent>
46566
46567
  `);
46567
46568
  return false;
46568
46569
  }
@@ -46605,7 +46606,7 @@ async function runWrapped(argv) {
46605
46606
  Autonomous HEADLESS (default) and INTERVAL modes work right away \u2014 nothing to install.
46606
46607
  The experimental "session" mode (watch messages typed into THIS window live) needs
46607
46608
  tmux + an opt-in. To try it later:
46608
- JEFRI_EXPERIMENTAL_SESSION=1 jefrichat-mcp run ${cmdStr}
46609
+ JEFRI_EXPERIMENTAL_SESSION=1 npx -y jefrichat-mcp@latest run ${cmdStr}
46609
46610
 
46610
46611
  `
46611
46612
  );
@@ -46621,14 +46622,14 @@ async function runWrapped(argv) {
46621
46622
  2. Ask your agent to turn autonomy on: jefri_autonomous({ enabled: true })
46622
46623
  (it will present the run modes and ask which you want \u2014 choose "session" for the live mode this window is armed for)
46623
46624
  3. Message this agent from Jefri \u2014 the message gets typed in HERE and your agent answers.
46624
- (leave it running in the background: Ctrl-b then d \xB7 come back: jefrichat-mcp run ${cmdStr})
46625
+ (leave it running in the background: Ctrl-b then d \xB7 come back: npx -y jefrichat-mcp@latest run ${cmdStr})
46625
46626
 
46626
46627
  ` : `
46627
46628
  \u{1F427} Launching "${cmdStr}" in a Jefri-managed tmux session.
46628
46629
  Autonomous HEADLESS and INTERVAL modes work as usual (no extra steps).
46629
46630
  The experimental "session" mode (watch it type into THIS window) is OFF \u2014 to try it,
46630
- relaunch with: JEFRI_EXPERIMENTAL_SESSION=1 jefrichat-mcp run ${cmdStr}
46631
- (leave running: Ctrl-b then d \xB7 reattach: jefrichat-mcp run ${cmdStr})
46631
+ relaunch with: JEFRI_EXPERIMENTAL_SESSION=1 npx -y jefrichat-mcp@latest run ${cmdStr}
46632
+ (leave running: Ctrl-b then d \xB7 reattach: npx -y jefrichat-mcp@latest run ${cmdStr})
46632
46633
 
46633
46634
  `
46634
46635
  );
@@ -46645,15 +46646,70 @@ async function runWrapped(argv) {
46645
46646
  cp6.spawnSync("tmux", ["set-option", "-t", name, "@jefri_agent", verdict.identity], { stdio: "ignore" });
46646
46647
  mustCreate = false;
46647
46648
  } else if (!forceReplace) {
46648
- process.stderr.write(
46649
- `
46650
- \u2717 existing session "${name}" looks ${verdict.reason} \u2014 NOT attaching, and NOT touching it.
46649
+ process.stderr.write(` \u23F3 session "${name}" isn't answering \u2014 re-checking in 3s (a hub deploy looks like this)\u2026
46650
+ `);
46651
+ await new Promise((r) => setTimeout(r, 3e3));
46652
+ const probe2 = await probeSessionConnector(name);
46653
+ const verdict2 = assessSession({ probe: probe2, currentVersion: connectorVersion(), expectedIdentity: meta.agent });
46654
+ const attachedOut = cp6.spawnSync("tmux", ["display-message", "-p", "-t", name, "#{session_attached}"], { encoding: "utf8" });
46655
+ const attached = (attachedOut.stdout ?? "").trim() !== "0" && attachedOut.status === 0;
46656
+ const action = staleSessionAction({
46657
+ recovered: verdict2.reuse,
46658
+ attached,
46659
+ everAnswered: probe !== null || probe2 !== null,
46660
+ isTTY: !!process.stdin.isTTY
46661
+ });
46662
+ if (action === "reuse") {
46663
+ process.stderr.write(` \u267B\uFE0F it recovered \u2014 reusing healthy session "${name}" (it was riding an outage)
46664
+ `);
46665
+ cp6.spawnSync("tmux", ["set-option", "-t", name, "@jefri_agent", verdict2.identity], { stdio: "ignore" });
46666
+ mustCreate = false;
46667
+ } else if (action === "auto") {
46668
+ process.stderr.write(` \u{1F9DF} session "${name}" is ${verdict2.reason}, detached, and never answered \u2014 replacing it automatically
46669
+ `);
46670
+ const killed = cp6.spawnSync("tmux", ["kill-session", "-t", name], { stdio: "ignore" });
46671
+ if (killed.status !== 0 || sessionExists(name)) {
46672
+ process.stderr.write(`
46673
+ \u2717 could not remove the stale session "${name}" \u2014 remove it yourself (tmux kill-session -t ${JSON.stringify(name)}) and re-run.
46674
+ `);
46675
+ return 1;
46676
+ }
46677
+ } else if (action === "ask") {
46678
+ process.stderr.write(`
46679
+ \u26A0\uFE0F session "${name}" looks ${verdict2.reason}${attached ? " and a terminal is ATTACHED to it (it may hold live work)" : ""}.
46680
+ `);
46681
+ process.stderr.write(` Replace it? Destroys whatever is in that window. [y/N] `);
46682
+ const ans = await new Promise((resolve) => {
46683
+ const t = setTimeout(() => resolve("n"), 3e4);
46684
+ process.stdin.once("data", (d) => {
46685
+ clearTimeout(t);
46686
+ resolve(String(d).trim().toLowerCase());
46687
+ });
46688
+ });
46689
+ if (ans === "y" || ans === "yes") {
46690
+ const killed = cp6.spawnSync("tmux", ["kill-session", "-t", name], { stdio: "ignore" });
46691
+ if (killed.status !== 0 || sessionExists(name)) {
46692
+ process.stderr.write(`
46693
+ \u2717 could not remove the stale session "${name}" \u2014 remove it yourself (tmux kill-session -t ${JSON.stringify(name)}) and re-run.
46694
+ `);
46695
+ return 1;
46696
+ }
46697
+ } else {
46698
+ process.stderr.write(` Left untouched. Inspect it: tmux attach -t ${JSON.stringify(name)}
46699
+ `);
46700
+ return 1;
46701
+ }
46702
+ } else {
46703
+ process.stderr.write(
46704
+ `
46705
+ \u2717 existing session "${name}" looks ${verdict2.reason} \u2014 NOT attaching, and NOT touching it.
46651
46706
  If it's mid-outage (hub deploy?), just re-run in a moment.
46652
- To REPLACE it (destroys whatever is in that window): jefrichat-mcp run --restart ${agentCmd.join(" ")}
46707
+ To REPLACE it (destroys whatever is in that window): npx -y jefrichat-mcp@latest run --restart ${agentCmd.join(" ")}
46653
46708
  To inspect it first: tmux attach -t ${JSON.stringify(name)}
46654
46709
  `
46655
- );
46656
- return 1;
46710
+ );
46711
+ return 1;
46712
+ }
46657
46713
  } else {
46658
46714
  const why = verdict.reuse ? ticketPresent ? "being TAKEN OVER (ticket present \u2014 a healthy look is the doomed pane's last 10 seconds)" : "healthy, but --restart asked for a fresh one" : verdict.reason;
46659
46715
  process.stderr.write(` \u{1F9DF} session "${name}" is ${why} \u2014 replacing it (${ticketPresent ? "takeover ticket" : "--restart"} given)
@@ -46800,6 +46856,11 @@ async function probeSessionConnector(name) {
46800
46856
  }
46801
46857
  return null;
46802
46858
  }
46859
+ function staleSessionAction(d) {
46860
+ if (d.recovered) return "reuse";
46861
+ if (!d.attached && !d.everAnswered) return "auto";
46862
+ return d.isTTY ? "ask" : "refuse";
46863
+ }
46803
46864
  function assessSession(s) {
46804
46865
  if (!s.probe) return { reuse: false, reason: "a zombie (no answering connector in its panes)" };
46805
46866
  if (!s.probe.online) return { reuse: false, reason: `deaf (connector for @${safeHandle(s.probe.identity)} is not connected to the hub)` };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jefrichat-mcp",
3
- "version": "0.49.9",
3
+ "version": "0.49.11",
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": {