@tritard/waterbrother 0.16.78 → 0.16.79

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tritard/waterbrother",
3
- "version": "0.16.78",
3
+ "version": "0.16.79",
4
4
  "description": "Waterbrother: bring-your-own-model coding CLI with local tools, sessions, operator modes, and approval controls",
5
5
  "type": "module",
6
6
  "bin": {
package/src/cli.js CHANGED
@@ -3107,23 +3107,49 @@ async function clearTelegramBridgeHost() {
3107
3107
  async function dequeueTelegramBridgeRequest({ cwd }) {
3108
3108
  const bridge = await loadGatewayBridge(TELEGRAM_BRIDGE_SERVICE);
3109
3109
  const activeHost = bridge.activeHost || {};
3110
- if (Number(activeHost.pid || 0) !== process.pid) {
3111
- return null;
3112
- }
3113
- if (activeHost.cwd && String(activeHost.cwd) !== String(cwd || "")) {
3114
- return null;
3115
- }
3110
+ const currentHost = Number(activeHost.pid || 0) === process.pid
3111
+ ? activeHost
3112
+ : (Array.isArray(bridge.hosts) ? bridge.hosts.find((host) => Number(host?.pid || 0) === process.pid) : null) || {};
3116
3113
  const pending = Array.isArray(bridge.pendingRequests) ? bridge.pendingRequests : [];
3117
3114
  if (!pending.length) {
3118
3115
  return null;
3119
3116
  }
3120
- const [next, ...rest] = pending;
3117
+ const nextIndex = pending.findIndex((request) => {
3118
+ const targetPid = Number(request?.targetPid || 0);
3119
+ const targetSessionId = String(request?.targetSessionId || "").trim();
3120
+ if (targetPid > 0 && targetPid !== process.pid) {
3121
+ return false;
3122
+ }
3123
+ if (targetSessionId && targetSessionId !== String(currentHost.sessionId || "").trim()) {
3124
+ return false;
3125
+ }
3126
+ if (currentHost.cwd && String(currentHost.cwd) !== String(cwd || "")) {
3127
+ return false;
3128
+ }
3129
+ return true;
3130
+ });
3131
+ if (nextIndex < 0) {
3132
+ return null;
3133
+ }
3134
+ const next = pending[nextIndex];
3135
+ const rest = pending.filter((_, index) => index !== nextIndex);
3121
3136
  bridge.pendingRequests = rest;
3122
- bridge.activeHost = {
3123
- ...activeHost,
3124
- updatedAt: new Date().toISOString()
3125
- };
3126
- bridge.hosts = upsertTelegramBridgeHostEntry(bridge.hosts, bridge.activeHost);
3137
+ if (Number(currentHost.pid || 0) === process.pid) {
3138
+ const updatedHost = {
3139
+ ...currentHost,
3140
+ updatedAt: new Date().toISOString()
3141
+ };
3142
+ if (Number(activeHost.pid || 0) === process.pid) {
3143
+ bridge.activeHost = updatedHost;
3144
+ }
3145
+ bridge.hosts = upsertTelegramBridgeHostEntry(bridge.hosts, updatedHost);
3146
+ } else if (Number(activeHost.pid || 0) === process.pid) {
3147
+ bridge.activeHost = {
3148
+ ...activeHost,
3149
+ updatedAt: new Date().toISOString()
3150
+ };
3151
+ bridge.hosts = upsertTelegramBridgeHostEntry(bridge.hosts, bridge.activeHost);
3152
+ }
3127
3153
  await saveGatewayBridge(TELEGRAM_BRIDGE_SERVICE, bridge);
3128
3154
  return next;
3129
3155
  }
@@ -54,6 +54,9 @@ function normalizeBridgeRequest(parsed = {}) {
54
54
  sessionId: String(parsed?.sessionId || "").trim(),
55
55
  text: String(parsed?.text || "").trim(),
56
56
  explicitExecution: parsed?.explicitExecution === true,
57
+ targetPid: Number.isFinite(Number(parsed?.targetPid)) ? Math.floor(Number(parsed.targetPid)) : 0,
58
+ targetSessionId: String(parsed?.targetSessionId || "").trim(),
59
+ targetOwnerId: String(parsed?.targetOwnerId || "").trim(),
57
60
  runtimeProfile: String(parsed?.runtimeProfile || "").trim(),
58
61
  replyToMessageId: Number.isFinite(Number(parsed?.replyToMessageId)) ? Math.floor(Number(parsed.replyToMessageId)) : 0,
59
62
  requestedAt: String(parsed?.requestedAt || "").trim(),
package/src/gateway.js CHANGED
@@ -473,6 +473,16 @@ function formatBridgeHostLabel(host = {}) {
473
473
  return [owner || label, label && label !== owner ? `(${label})` : "", runtime ? `[${runtime}]` : ""].filter(Boolean).join(" ").trim();
474
474
  }
475
475
 
476
+ function findLiveHostForAgent(hosts = [], agent = {}) {
477
+ const ownerId = String(agent?.ownerId || "").trim();
478
+ const sessionId = String(agent?.sessionId || "").trim();
479
+ return (Array.isArray(hosts) ? hosts : []).find((host) => {
480
+ const hostOwnerId = String(host?.ownerId || "").trim();
481
+ const hostSessionId = String(host?.sessionId || "").trim();
482
+ return (ownerId && hostOwnerId === ownerId) || (sessionId && hostSessionId === sessionId);
483
+ }) || null;
484
+ }
485
+
476
486
  function getLatestBlockingReviewPolicy(project) {
477
487
  const events = Array.isArray(project?.recentEvents) ? [...project.recentEvents] : [];
478
488
  const ordered = events
@@ -2631,7 +2641,7 @@ class TelegramGateway {
2631
2641
  }
2632
2642
 
2633
2643
  async runPromptViaBridge(message, sessionId, promptText, options = {}) {
2634
- const host = await this.getLiveBridgeHost();
2644
+ const host = options.targetHost || await this.getLiveBridgeHost();
2635
2645
  if (!host) {
2636
2646
  return null;
2637
2647
  }
@@ -2650,6 +2660,9 @@ class TelegramGateway {
2650
2660
  sessionId: String(sessionId || "").trim(),
2651
2661
  text: String(promptText || "").trim(),
2652
2662
  explicitExecution: options.explicitExecution === true,
2663
+ targetPid: Number(host?.pid || 0),
2664
+ targetSessionId: String(host?.sessionId || "").trim(),
2665
+ targetOwnerId: String(host?.ownerId || "").trim(),
2653
2666
  runtimeProfile: String(project?.runtimeProfile || "").trim(),
2654
2667
  replyToMessageId: message.message_id,
2655
2668
  requestedAt: new Date().toISOString(),
@@ -2678,7 +2691,11 @@ class TelegramGateway {
2678
2691
  }
2679
2692
 
2680
2693
  const activeHost = nextBridge.activeHost || {};
2681
- if (Number(activeHost.pid || 0) <= 0) {
2694
+ const knownHosts = Array.isArray(nextBridge.hosts) ? nextBridge.hosts : [];
2695
+ if (Number(host?.pid || 0) > 0 && !knownHosts.some((item) => Number(item?.pid || 0) === Number(host.pid || 0))) {
2696
+ break;
2697
+ }
2698
+ if (Number(activeHost.pid || 0) <= 0 && !(Number(host?.pid || 0) > 0)) {
2682
2699
  break;
2683
2700
  }
2684
2701
  }
@@ -3819,6 +3836,7 @@ Ask them to run <code>/whoami</code> and then <code>/accept-invite ${escapeTeleg
3819
3836
  });
3820
3837
  return;
3821
3838
  }
3839
+ const liveHosts = await this.getLiveBridgeHosts({ cwd: operatorGate.session?.cwd || this.cwd });
3822
3840
  const host = await this.getLiveBridgeHost();
3823
3841
  const activeExecutor = {
3824
3842
  surface: host?.surface || (host ? "live-tui" : "telegram-fallback"),
@@ -3831,10 +3849,12 @@ Ask them to run <code>/whoami</code> and then <code>/accept-invite ${escapeTeleg
3831
3849
  label: host?.label || ""
3832
3850
  };
3833
3851
  const selectedExecutor = chooseExecutorAgent(operatorGate.project, activeExecutor);
3852
+ const selectedLiveHost = selectedExecutor ? findLiveHostForAgent(liveHosts, selectedExecutor) : null;
3834
3853
  if (
3835
3854
  selectedExecutor?.ownerId
3836
3855
  && activeExecutor.ownerId
3837
3856
  && String(selectedExecutor.ownerId).trim() !== String(activeExecutor.ownerId).trim()
3857
+ && !selectedLiveHost
3838
3858
  ) {
3839
3859
  const selectedName = String(selectedExecutor.ownerName || selectedExecutor.label || selectedExecutor.ownerId || "selected executor").trim();
3840
3860
  const currentName = String(activeExecutor.ownerName || activeExecutor.label || activeExecutor.ownerId || "current terminal").trim();
@@ -3871,7 +3891,10 @@ Ask them to run <code>/whoami</code> and then <code>/accept-invite ${escapeTeleg
3871
3891
  return;
3872
3892
  }
3873
3893
  previewMessage = await this.sendProgressMessage(message.chat.id, message.message_id);
3874
- const content = (await this.runPromptViaBridge(message, sessionId, promptText, { explicitExecution: shouldExecutePrompt }))
3894
+ const content = (await this.runPromptViaBridge(message, sessionId, promptText, {
3895
+ explicitExecution: shouldExecutePrompt,
3896
+ targetHost: selectedLiveHost || host || null
3897
+ }))
3875
3898
  ?? (await this.runPromptFallback(sessionId, promptText));
3876
3899
  await this.deliverPromptResult(message.chat.id, message.message_id, previewMessage, content);
3877
3900
  await this.rememberContinuation(message, content);