@tritard/waterbrother 0.16.105 → 0.16.107

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.105",
3
+ "version": "0.16.107",
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
@@ -3190,6 +3190,16 @@ function formatTelegramRemoteActor(request = {}) {
3190
3190
  return username || userId || "telegram";
3191
3191
  }
3192
3192
 
3193
+ function parseTerminalLabelIntent(text = "") {
3194
+ const value = String(text || "").trim();
3195
+ if (!value) return null;
3196
+ const match = value.match(/^(?:name|label|rename|call)\s+(?:this\s+|my\s+)?(?:terminal|tui|session)(?:\s+(?:to|as))?\s+(.+?)\s*$/i);
3197
+ if (!match?.[1]) return null;
3198
+ const label = String(match[1] || "").trim().replace(/^["'`]+|["'`]+$/g, "").trim();
3199
+ if (!label) return null;
3200
+ return { action: "label-terminal", label };
3201
+ }
3202
+
3193
3203
  async function planTelegramVerificationCommands(cwd) {
3194
3204
  const packageJsonPath = path.join(cwd, "package.json");
3195
3205
  let scripts = {};
@@ -7637,7 +7647,7 @@ Be concrete about surfaces — name actual pages/flows. Choose the best stack fo
7637
7647
  autonomy: agent.getAutonomyMode(),
7638
7648
  profile: agent.getProfile()
7639
7649
  });
7640
- const telegramBridgeLabel = `${telegramBridgeOperator.name} terminal ${String(currentSession.id || "").trim().slice(-6)}`.trim();
7650
+ let telegramBridgeLabel = `${telegramBridgeOperator.name} terminal ${String(currentSession.id || "").trim().slice(-6)}`.trim();
7641
7651
  await registerTelegramBridgeHost({
7642
7652
  sessionId: currentSession.id,
7643
7653
  cwd: context.cwd,
@@ -7779,7 +7789,7 @@ Be concrete about surfaces — name actual pages/flows. Choose the best stack fo
7779
7789
  await touchTelegramBridgeHost({
7780
7790
  sessionId: currentSession.id,
7781
7791
  cwd: context.cwd,
7782
- label: `${telegramBridgeOperator.name} terminal`,
7792
+ label: telegramBridgeLabel,
7783
7793
  surface: "live-tui",
7784
7794
  ownerId: telegramBridgeOperator.id,
7785
7795
  ownerName: telegramBridgeOperator.name,
@@ -7901,6 +7911,25 @@ Be concrete about surfaces — name actual pages/flows. Choose the best stack fo
7901
7911
  continue;
7902
7912
  }
7903
7913
 
7914
+ const terminalLabelIntent = parseTerminalLabelIntent(line);
7915
+ if (terminalLabelIntent) {
7916
+ telegramBridgeLabel = terminalLabelIntent.label;
7917
+ await touchTelegramBridgeHost({
7918
+ sessionId: currentSession.id,
7919
+ cwd: context.cwd,
7920
+ label: telegramBridgeLabel,
7921
+ surface: "live-tui",
7922
+ ownerId: telegramBridgeOperator.id,
7923
+ ownerName: telegramBridgeOperator.name,
7924
+ provider: context.runtime.provider,
7925
+ model: context.runtime.model,
7926
+ runtimeProfile: currentSession.runtimeProfile || "",
7927
+ actor: { id: telegramBridgeOperator.id, name: telegramBridgeOperator.name }
7928
+ });
7929
+ console.log(`terminal label -> ${telegramBridgeLabel}`);
7930
+ continue;
7931
+ }
7932
+
7904
7933
  const lowerLine = line.toLowerCase();
7905
7934
  if (/^gateway\b/.test(lowerLine)) {
7906
7935
  console.log("That looks like a shell subcommand. Run it in your terminal, not at the you> prompt.");
package/src/gateway.js CHANGED
@@ -815,6 +815,13 @@ function parseTelegramAgentIntent(text = "") {
815
815
  const lowered = value.toLowerCase();
816
816
  if (!value) return null;
817
817
  if (/^(how|what|why|when|where|who)\b/.test(lowered)) return null;
818
+ const labelMatch = value.match(/^(?:name|label|rename|call)\s+(?:this\s+|my\s+)?(?:bot|terminal|tui|session)(?:\s+(?:to|as))?\s+(.+?)\s*$/i);
819
+ if (labelMatch?.[1]) {
820
+ const label = String(labelMatch[1] || "").trim().replace(/^["'`]+|["'`]+$/g, "").trim();
821
+ if (label) {
822
+ return { action: "agent-label", target: "this terminal", label };
823
+ }
824
+ }
818
825
  const reviewPatterns = [
819
826
  /^(?:have|ask|use)\s+(.+?)['’]s\s+(?:bot|terminal)\s+(?:to\s+)?review(?:\s+this)?\s*$/i,
820
827
  /^(?:have|ask|use)\s+(.+?)\s+(?:bot|terminal)\s+(?:to\s+)?review(?:\s+this)?\s*$/i,
@@ -2092,6 +2099,58 @@ class TelegramGateway {
2092
2099
  if (!targetAgent) {
2093
2100
  throw new Error(`No terminal found for ${intent.target}. Ask them to connect their Waterbrother bot/terminal first.`);
2094
2101
  }
2102
+ if (intent.action === "agent-label") {
2103
+ const nextLabel = String(intent.label || "").trim();
2104
+ if (!nextLabel) {
2105
+ throw new Error("Terminal label cannot be empty.");
2106
+ }
2107
+ const bridge = await loadGatewayBridge("telegram");
2108
+ const updateHost = (host = {}) => ({
2109
+ ...host,
2110
+ label: nextLabel,
2111
+ updatedAt: new Date().toISOString()
2112
+ });
2113
+ let changed = false;
2114
+ if (String(targetAgent.sessionId || "").trim()) {
2115
+ if (String(bridge.activeHost?.sessionId || "").trim() === String(targetAgent.sessionId || "").trim()) {
2116
+ bridge.activeHost = updateHost(bridge.activeHost || {});
2117
+ changed = true;
2118
+ }
2119
+ if (Array.isArray(bridge.hosts)) {
2120
+ bridge.hosts = bridge.hosts.map((host) => {
2121
+ if (String(host?.sessionId || "").trim() === String(targetAgent.sessionId || "").trim()) {
2122
+ changed = true;
2123
+ return updateHost(host);
2124
+ }
2125
+ return host;
2126
+ });
2127
+ }
2128
+ }
2129
+ if (changed) {
2130
+ await saveGatewayBridge("telegram", bridge);
2131
+ }
2132
+ const labeledAgent = {
2133
+ ...targetAgent,
2134
+ label: nextLabel
2135
+ };
2136
+ const nextProject = await upsertSharedAgent(session.cwd || this.cwd, labeledAgent, {
2137
+ actorId,
2138
+ actorName: actor.displayName || actorId
2139
+ });
2140
+ return {
2141
+ kind: "agent",
2142
+ project: nextProject,
2143
+ markup: [
2144
+ "<b>Roundtable terminal labeled</b>",
2145
+ `owner: <code>${escapeTelegramHtml(getAgentOwnerDisplay(labeledAgent, actor.displayName || actor.userId || "current operator"))}</code>`,
2146
+ `terminal: <code>${escapeTelegramHtml(nextLabel)}</code>`,
2147
+ `role: <code>${escapeTelegramHtml(labeledAgent.role || "standby")}</code>`,
2148
+ labeledAgent.provider && labeledAgent.model ? `runtime: <code>${escapeTelegramHtml(`${labeledAgent.provider}/${labeledAgent.model}`)}</code>` : "",
2149
+ `project: <code>${escapeTelegramHtml(project.projectName || path.basename(session.cwd || this.cwd))}</code>`,
2150
+ "You can now refer to this terminal by that label in the room."
2151
+ ].filter(Boolean).join("\n")
2152
+ };
2153
+ }
2095
2154
  const nextProject = await upsertSharedAgent(session.cwd || this.cwd, {
2096
2155
  ...targetAgent,
2097
2156
  role: intent.role