@tritard/waterbrother 0.16.91 → 0.16.93

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/package.json +1 -1
  2. package/src/gateway.js +36 -12
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tritard/waterbrother",
3
- "version": "0.16.91",
3
+ "version": "0.16.93",
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/gateway.js CHANGED
@@ -786,6 +786,12 @@ function parseTelegramStateIntent(text = "") {
786
786
  const lower = value.toLowerCase();
787
787
  if (!value) return null;
788
788
 
789
+ if (/^(?:are you|you(?:'re| are)?|wb|waterbrother)\s+(?:online|running|alive|there)\??$/.test(lower)
790
+ || /^(?:you online|you running|you there)\??$/.test(lower)
791
+ || /^(?:are you online|are you running|are you there)\??$/.test(lower)) {
792
+ return { action: "bot-status" };
793
+ }
794
+
789
795
  if (/\bwhat project\b/.test(lower) || /\bwhich project\b/.test(lower) || /\bproject is this chat\b/.test(lower) || /\bchat bound to\b/.test(lower)) {
790
796
  return { action: "project-status" };
791
797
  }
@@ -2188,6 +2194,20 @@ class TelegramGateway {
2188
2194
  hostSessionId: host?.sessionId || ""
2189
2195
  };
2190
2196
 
2197
+ if (intent.action === "bot-status") {
2198
+ const lines = [
2199
+ "<b>Waterbrother status</b>",
2200
+ "status: <code>online</code>",
2201
+ `surface: <code>${escapeTelegramHtml(host ? "live-tui" : "telegram-fallback")}</code>`,
2202
+ `room mode: <code>${escapeTelegramHtml(project?.enabled ? (project.roomMode || "chat") : "off")}</code>`,
2203
+ project?.activeOperator?.id
2204
+ ? `active operator: <code>${escapeTelegramHtml(project.activeOperator.name || project.activeOperator.id)}</code>`
2205
+ : "active operator: <code>none</code>",
2206
+ `runtime: <code>${escapeTelegramHtml(`${executor.provider || "unknown"}/${executor.model || "unknown"}`)}</code>`
2207
+ ];
2208
+ return lines.join("\n");
2209
+ }
2210
+
2191
2211
  if (intent.action === "accept-reviewer-concerns") {
2192
2212
  if (!project?.enabled) {
2193
2213
  return "This project is not shared.";
@@ -3148,7 +3168,7 @@ class TelegramGateway {
3148
3168
  const userId = String(message.from.id);
3149
3169
 
3150
3170
  if (text === "/help") {
3151
- await this.sendMessage(message.chat.id, buildRemoteHelp(), message.message_id);
3171
+ await this.sendMarkup(message.chat.id, buildRemoteHelp(), message.message_id);
3152
3172
  return;
3153
3173
  }
3154
3174
 
@@ -3533,7 +3553,11 @@ class TelegramGateway {
3533
3553
  }
3534
3554
  try {
3535
3555
  const released = await releaseSharedOperator(session.cwd || this.cwd, userId, { actorId: userId });
3536
- await this.sendMessage(message.chat.id, released.activeOperator?.id ? await this.buildRoomMarkup(message, sessionId) : "Shared room released.", message.message_id);
3556
+ if (released.activeOperator?.id) {
3557
+ await this.sendMarkup(message.chat.id, await this.buildRoomMarkup(message, sessionId), message.message_id);
3558
+ } else {
3559
+ await this.sendMessage(message.chat.id, "Shared room released.", message.message_id);
3560
+ }
3537
3561
  } catch (error) {
3538
3562
  await this.sendMessage(message.chat.id, escapeTelegramHtml(error instanceof Error ? error.message : String(error)), message.message_id);
3539
3563
  }
@@ -3689,7 +3713,7 @@ Ask them to run <code>/whoami</code> and then <code>/accept-invite ${escapeTeleg
3689
3713
  const result = await moveSharedTask(session.cwd || this.cwd, taskId, state, { actorId: userId });
3690
3714
  await this.sendMarkup(message.chat.id, `Moved shared task <code>${escapeTelegramHtml(result.task.id)}</code> to <code>${escapeTelegramHtml(result.task.state)}</code>`, message.message_id);
3691
3715
  const notice = buildTaskOwnershipNotice(result.task, { action: "move", previousAssignee: before?.assignedTo || "", previousState: before?.state || "" });
3692
- if (notice) await this.sendMessage(message.chat.id, notice, null, { parseMode: "HTML" });
3716
+ if (notice) await this.sendMarkup(message.chat.id, notice);
3693
3717
  } catch (error) {
3694
3718
  await this.sendMessage(message.chat.id, escapeTelegramHtml(error instanceof Error ? error.message : String(error)), message.message_id);
3695
3719
  }
@@ -3712,7 +3736,7 @@ Ask them to run <code>/whoami</code> and then <code>/accept-invite ${escapeTeleg
3712
3736
  const result = await assignSharedTask(session.cwd || this.cwd, taskId, memberId, { actorId: userId });
3713
3737
  await this.sendMarkup(message.chat.id, `Assigned shared task <code>${escapeTelegramHtml(result.task.id)}</code> to <code>${escapeTelegramHtml(memberId)}</code>`, message.message_id);
3714
3738
  const notice = buildTaskOwnershipNotice(result.task, { action: "assign", previousAssignee: before?.assignedTo || "" });
3715
- if (notice) await this.sendMessage(message.chat.id, notice, null, { parseMode: "HTML" });
3739
+ if (notice) await this.sendMarkup(message.chat.id, notice);
3716
3740
  } catch (error) {
3717
3741
  await this.sendMessage(message.chat.id, escapeTelegramHtml(error instanceof Error ? error.message : String(error)), message.message_id);
3718
3742
  }
@@ -3757,7 +3781,7 @@ Ask them to run <code>/whoami</code> and then <code>/accept-invite ${escapeTeleg
3757
3781
  }
3758
3782
  try {
3759
3783
  const result = await getSharedTaskHistory(session.cwd || this.cwd, taskId, { actorId: userId });
3760
- await this.sendMessage(message.chat.id, formatTelegramTaskHistoryMarkup(result), message.message_id);
3784
+ await this.sendMarkup(message.chat.id, formatTelegramTaskHistoryMarkup(result), message.message_id);
3761
3785
  } catch (error) {
3762
3786
  await this.sendMessage(message.chat.id, escapeTelegramHtml(error instanceof Error ? error.message : String(error)), message.message_id);
3763
3787
  }
@@ -3779,7 +3803,7 @@ Ask them to run <code>/whoami</code> and then <code>/accept-invite ${escapeTeleg
3779
3803
  const result = await claimSharedTask(session.cwd || this.cwd, taskId, { actorId: userId });
3780
3804
  await this.sendMarkup(message.chat.id, `Claimed shared task <code>${escapeTelegramHtml(result.task.id)}</code>`, message.message_id);
3781
3805
  const notice = buildTaskOwnershipNotice(result.task, { action: "claim" });
3782
- if (notice) await this.sendMessage(message.chat.id, notice, null, { parseMode: "HTML" });
3806
+ if (notice) await this.sendMarkup(message.chat.id, notice);
3783
3807
  } catch (error) {
3784
3808
  await this.sendMessage(message.chat.id, escapeTelegramHtml(error instanceof Error ? error.message : String(error)), message.message_id);
3785
3809
  }
@@ -3788,7 +3812,7 @@ Ask them to run <code>/whoami</code> and then <code>/accept-invite ${escapeTeleg
3788
3812
 
3789
3813
  if (text === "/runtime") {
3790
3814
  const status = await this.runRuntimeStatus();
3791
- await this.sendMessage(message.chat.id, formatRuntimeStatus(status), message.message_id);
3815
+ await this.sendMarkup(message.chat.id, formatRuntimeStatus(status), message.message_id);
3792
3816
  return;
3793
3817
  }
3794
3818
 
@@ -3850,7 +3874,7 @@ Ask them to run <code>/whoami</code> and then <code>/accept-invite ${escapeTeleg
3850
3874
  const session = await loadSession(freshSessionId);
3851
3875
  session.cwd = target;
3852
3876
  await saveSession(session);
3853
- await this.sendMessage(
3877
+ await this.sendMarkup(
3854
3878
  message.chat.id,
3855
3879
  `Started new remote session <code>${escapeTelegramHtml(freshSessionId)}</code>\nCwd: <code>${escapeTelegramHtml(target)}</code>`,
3856
3880
  message.message_id
@@ -3860,14 +3884,14 @@ Ask them to run <code>/whoami</code> and then <code>/accept-invite ${escapeTeleg
3860
3884
 
3861
3885
  if (text === "/sessions") {
3862
3886
  const sessions = await this.listPeerSessions(userId);
3863
- await this.sendMessage(message.chat.id, formatSessionListMarkup(sessionId, sessions), message.message_id);
3887
+ await this.sendMarkup(message.chat.id, formatSessionListMarkup(sessionId, sessions), message.message_id);
3864
3888
  return;
3865
3889
  }
3866
3890
 
3867
3891
  if (text.startsWith("/resume")) {
3868
3892
  const nextSessionId = text.replace("/resume", "").trim();
3869
3893
  if (!nextSessionId) {
3870
- await this.sendMessage(
3894
+ await this.sendMarkup(
3871
3895
  message.chat.id,
3872
3896
  "Usage: <code>/resume &lt;session-id&gt;</code>\nUse <code>/sessions</code> to list recent remote session ids.",
3873
3897
  message.message_id
@@ -3875,7 +3899,7 @@ Ask them to run <code>/whoami</code> and then <code>/accept-invite ${escapeTeleg
3875
3899
  return;
3876
3900
  }
3877
3901
  const resumedId = await this.resumePeerSession(message, nextSessionId);
3878
- await this.sendMessage(
3902
+ await this.sendMarkup(
3879
3903
  message.chat.id,
3880
3904
  `Linked remote session: <code>${escapeTelegramHtml(resumedId)}</code>`,
3881
3905
  message.message_id
@@ -3885,7 +3909,7 @@ Ask them to run <code>/whoami</code> and then <code>/accept-invite ${escapeTeleg
3885
3909
 
3886
3910
  if (text === "/clear") {
3887
3911
  await this.clearRemoteConversation(sessionId);
3888
- await this.sendMessage(
3912
+ await this.sendMarkup(
3889
3913
  message.chat.id,
3890
3914
  `Cleared conversation history for <code>${escapeTelegramHtml(sessionId)}</code>.`,
3891
3915
  message.message_id