@tloncorp/openclaw 0.1.0 → 0.2.0

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.
@@ -1,27 +1,87 @@
1
+ import { randomUUID } from "node:crypto";
2
+ function displayChannel(nest, ctx) {
3
+ const name = ctx?.channelNames?.get(nest);
4
+ return name ? `${name} (${nest})` : nest;
5
+ }
6
+ function displayGroup(flag, ctx, titleOverride) {
7
+ const name = titleOverride || ctx?.groupNames?.get(flag);
8
+ return name ? `${name} (${flag})` : flag;
9
+ }
10
+ // ============================================================================
11
+ // Emoji Reaction Mapping
12
+ // ============================================================================
13
+ /** Map a reaction emoji to an approval action. Returns undefined for unrecognized emoji. */
14
+ export function emojiToApprovalAction(emoji) {
15
+ switch (emoji) {
16
+ case "👍":
17
+ return "approve";
18
+ case "👎":
19
+ return "deny";
20
+ case "🛑":
21
+ return "block";
22
+ default:
23
+ return undefined;
24
+ }
25
+ }
26
+ // ============================================================================
27
+ // Notification Message ID Normalization
28
+ // ============================================================================
1
29
  /**
2
- * Approval system for managing DM, channel mention, and group invite approvals.
3
- *
4
- * When an unknown ship tries to interact with the bot, the owner receives
5
- * a notification and can approve or deny the request.
30
+ * Normalize a message ID for comparison between sendDm return values and SSE event IDs.
31
+ * sendDm returns "~ship/170.141.184.XXX", SSE events use "170.141.184.XXX" (bare timestamp).
32
+ * This strips the ship prefix and dots so both forms compare equal.
6
33
  */
34
+ export function normalizeNotificationId(id) {
35
+ // Strip ship prefix: "~zod/170.141..." → "170.141..."
36
+ if (id.includes("/") && id.startsWith("~")) {
37
+ id = id.slice(id.indexOf("/") + 1);
38
+ }
39
+ // Strip dots: "170.141.184..." → "170141184..."
40
+ return id.replace(/\./g, "");
41
+ }
42
+ // ============================================================================
43
+ // Approval Expiration
44
+ // ============================================================================
45
+ /** Pending approvals expire after 48 hours. */
46
+ export const APPROVAL_TTL_MS = 48 * 60 * 60 * 1000;
47
+ /** Check if a pending approval has expired. */
48
+ export function isExpired(approval) {
49
+ return Date.now() - approval.timestamp > APPROVAL_TTL_MS;
50
+ }
51
+ /** Filter out expired approvals from a list. */
52
+ export function pruneExpired(approvals) {
53
+ return approvals.filter((a) => !isExpired(a));
54
+ }
55
+ // ============================================================================
56
+ // Approval ID Generation
57
+ // ============================================================================
7
58
  /**
8
- * Generate a unique approval ID in the format: {type}-{timestamp}-{shortHash}
59
+ * Generate a short approval ID: type-prefix char + 4 hex chars.
60
+ * e.g. "da1b2" for dm, "cc3d4" for channel, "g5f6e" for group.
9
61
  */
10
- export function generateApprovalId(type) {
11
- const timestamp = Date.now();
12
- const randomPart = Math.random().toString(36).substring(2, 6);
13
- return `${type}-${timestamp}-${randomPart}`;
62
+ export function generateApprovalId(type, existingIds = []) {
63
+ const prefix = type[0]; // 'd', 'c', or 'g'
64
+ for (let attempt = 0; attempt < 10; attempt++) {
65
+ const shortId = randomUUID().slice(0, 4);
66
+ const id = `${prefix}${shortId}`;
67
+ if (!existingIds.includes(id)) {
68
+ return id;
69
+ }
70
+ }
71
+ // Fallback: use 8 chars to avoid collision
72
+ return `${prefix}${randomUUID().slice(0, 8)}`;
14
73
  }
15
74
  /**
16
75
  * Create a pending approval object.
17
76
  */
18
- export function createPendingApproval(params) {
77
+ export function createPendingApproval(params, existingIds = []) {
19
78
  return {
20
- id: generateApprovalId(params.type),
79
+ id: generateApprovalId(params.type, existingIds),
21
80
  type: params.type,
22
81
  requestingShip: params.requestingShip,
23
82
  channelNest: params.channelNest,
24
83
  groupFlag: params.groupFlag,
84
+ groupTitle: params.groupTitle,
25
85
  messagePreview: params.messagePreview,
26
86
  originalMessage: params.originalMessage,
27
87
  timestamp: Date.now(),
@@ -36,60 +96,95 @@ function truncate(text, maxLength) {
36
96
  }
37
97
  return text.substring(0, maxLength - 3) + "...";
38
98
  }
99
+ // ============================================================================
100
+ // Approval Request Formatting
101
+ // ============================================================================
102
+ const REACTION_HINT = "React to this message: 👍 approve · 👎 deny · 🛑 block";
103
+ function actionHintsDm(id) {
104
+ return [
105
+ REACTION_HINT,
106
+ "",
107
+ "Or use a slash command:",
108
+ ` /allow ${id} — allow this ship to DM`,
109
+ ` /reject ${id} — decline (they can try again)`,
110
+ ` /ban ${id} — block this ship`,
111
+ ].join("\n");
112
+ }
113
+ function actionHintsChannel(id) {
114
+ return [
115
+ REACTION_HINT,
116
+ "",
117
+ "Or use a slash command:",
118
+ ` /allow ${id} — allow this ship in this channel`,
119
+ ` /reject ${id} — decline (they can try again)`,
120
+ ` /ban ${id} — block this ship`,
121
+ ].join("\n");
122
+ }
123
+ function actionHintsGroup(id) {
124
+ return [
125
+ REACTION_HINT,
126
+ "",
127
+ "Or use a slash command:",
128
+ ` /allow ${id} — join this group`,
129
+ ` /reject ${id} — decline the invite`,
130
+ ` /ban ${id} — block this ship`,
131
+ ].join("\n");
132
+ }
39
133
  /**
40
134
  * Format a notification message for the owner about a pending approval.
41
135
  */
42
- export function formatApprovalRequest(approval) {
43
- const preview = approval.messagePreview ? `\n"${truncate(approval.messagePreview, 100)}"` : "";
136
+ export function formatApprovalRequest(approval, ctx) {
137
+ const preview = approval.messagePreview
138
+ ? `\n"${truncate(approval.messagePreview, 100)}"`
139
+ : "";
44
140
  switch (approval.type) {
45
141
  case "dm":
46
- return (`New DM request from ${approval.requestingShip}:${preview}\n\n` +
47
- `Reply "approve", "deny", or "block" (ID: ${approval.id})`);
142
+ return [
143
+ `DM request from ${approval.requestingShip}`,
144
+ preview,
145
+ "",
146
+ actionHintsDm(approval.id),
147
+ ].join("\n");
48
148
  case "channel":
49
- return (`${approval.requestingShip} mentioned you in ${approval.channelNest}:${preview}\n\n` +
50
- `Reply "approve", "deny", or "block"\n` +
51
- `(ID: ${approval.id})`);
149
+ return [
150
+ `${approval.requestingShip} mentioned the bot in ${displayChannel(approval.channelNest ?? "", ctx)}`,
151
+ preview,
152
+ "",
153
+ actionHintsChannel(approval.id),
154
+ ].join("\n");
52
155
  case "group":
53
- return (`Group invite from ${approval.requestingShip} to join ${approval.groupFlag}\n\n` +
54
- `Reply "approve", "deny", or "block"\n` +
55
- `(ID: ${approval.id})`);
156
+ return [
157
+ `Group invite from ${approval.requestingShip} to join ${displayGroup(approval.groupFlag ?? "", ctx, approval.groupTitle)}`,
158
+ "",
159
+ actionHintsGroup(approval.id),
160
+ ].join("\n");
56
161
  }
57
162
  }
58
- /**
59
- * Parse an owner's response to an approval request.
60
- * Supports formats:
61
- * - "approve" / "deny" / "block" (applies to most recent pending)
62
- * - "approve dm-1234567890-abc" / "deny dm-1234567890-abc" (specific ID)
63
- * - "block" permanently blocks the ship via Tlon's native blocking
64
- */
65
- export function parseApprovalResponse(text) {
66
- const trimmed = text.trim().toLowerCase();
67
- // Match "approve", "deny", or "block" optionally followed by an ID
68
- const match = trimmed.match(/^(approve|deny|block)(?:\s+(.+))?$/);
69
- if (!match) {
70
- return null;
71
- }
72
- const action = match[1];
73
- const id = match[2]?.trim();
74
- return { action, id };
75
- }
76
- /**
77
- * Check if a message text looks like an approval response.
78
- * Used to determine if we should intercept the message before normal processing.
79
- */
80
- export function isApprovalResponse(text) {
81
- const trimmed = text.trim().toLowerCase();
82
- return trimmed.startsWith("approve") || trimmed.startsWith("deny") || trimmed.startsWith("block");
83
- }
163
+ // ============================================================================
164
+ // Approval Lookup & Removal
165
+ // ============================================================================
84
166
  /**
85
167
  * Find a pending approval by ID, or return the most recent if no ID specified.
168
+ * Supports prefix matching for shortened IDs.
169
+ * Skips expired approvals.
86
170
  */
87
171
  export function findPendingApproval(pendingApprovals, id) {
172
+ const active = pruneExpired(pendingApprovals);
88
173
  if (id) {
89
- return pendingApprovals.find((a) => a.id === id);
174
+ // Exact match first
175
+ const exact = active.find((a) => a.id === id);
176
+ if (exact) {
177
+ return exact;
178
+ }
179
+ // Prefix match (for partial input or old-format IDs)
180
+ const prefixMatches = active.filter((a) => a.id.startsWith(id));
181
+ if (prefixMatches.length === 1) {
182
+ return prefixMatches[0];
183
+ }
184
+ return undefined;
90
185
  }
91
186
  // Return most recent
92
- return pendingApprovals[pendingApprovals.length - 1];
187
+ return active[active.length - 1];
93
188
  }
94
189
  /**
95
190
  * Check if there's already a pending approval for the same ship/channel/group combo.
@@ -115,62 +210,42 @@ export function hasDuplicatePending(pendingApprovals, type, requestingShip, chan
115
210
  export function removePendingApproval(pendingApprovals, id) {
116
211
  return pendingApprovals.filter((a) => a.id !== id);
117
212
  }
213
+ // ============================================================================
214
+ // Approval Confirmation Formatting
215
+ // ============================================================================
118
216
  /**
119
217
  * Format a confirmation message after an approval action.
120
218
  */
121
- export function formatApprovalConfirmation(approval, action) {
219
+ export function formatApprovalConfirmation(approval, action, ctx) {
220
+ const ship = approval.requestingShip;
122
221
  if (action === "block") {
123
- return `Blocked ${approval.requestingShip}. They will no longer be able to contact the bot.`;
222
+ return `Blocked ${ship}. They will no longer be able to contact the bot.`;
124
223
  }
125
- const actionText = action === "approve" ? "Approved" : "Denied";
126
224
  switch (approval.type) {
127
225
  case "dm":
128
226
  if (action === "approve") {
129
- return `${actionText} DM access for ${approval.requestingShip}. They can now message the bot.`;
227
+ return `Approved DM access for ${ship}. They can now message the bot.`;
130
228
  }
131
- return `${actionText} DM request from ${approval.requestingShip}.`;
132
- case "channel":
229
+ return `Denied DM request from ${ship}.`;
230
+ case "channel": {
231
+ const channel = displayChannel(approval.channelNest ?? "", ctx);
133
232
  if (action === "approve") {
134
- return `${actionText} ${approval.requestingShip} for ${approval.channelNest}. They can now interact in this channel.`;
233
+ return `Approved ${ship} for ${channel}. They can now interact in this channel.`;
135
234
  }
136
- return `${actionText} ${approval.requestingShip} for ${approval.channelNest}.`;
137
- case "group":
235
+ return `Denied ${ship} for ${channel}.`;
236
+ }
237
+ case "group": {
238
+ const group = displayGroup(approval.groupFlag ?? "", ctx, approval.groupTitle);
138
239
  if (action === "approve") {
139
- return `${actionText} group invite from ${approval.requestingShip} to ${approval.groupFlag}. Joining group...`;
240
+ return `Approved group invite from ${ship} to ${group}. Joining group...`;
140
241
  }
141
- return `${actionText} group invite from ${approval.requestingShip} to ${approval.groupFlag}.`;
142
- }
143
- }
144
- /**
145
- * Parse an admin command from owner message.
146
- * Supports:
147
- * - "unblock ~ship" - unblock a specific ship
148
- * - "blocked" - list all blocked ships
149
- * - "pending" - list all pending approvals
150
- */
151
- export function parseAdminCommand(text) {
152
- const trimmed = text.trim().toLowerCase();
153
- // "blocked" - list blocked ships
154
- if (trimmed === "blocked") {
155
- return { type: "blocked" };
156
- }
157
- // "pending" - list pending approvals
158
- if (trimmed === "pending") {
159
- return { type: "pending" };
160
- }
161
- // "unblock ~ship" - unblock a specific ship
162
- const unblockMatch = trimmed.match(/^unblock\s+(~[\w-]+)$/);
163
- if (unblockMatch) {
164
- return { type: "unblock", ship: unblockMatch[1] };
242
+ return `Denied group invite from ${ship} to ${group}.`;
243
+ }
165
244
  }
166
- return null;
167
- }
168
- /**
169
- * Check if a message text looks like an admin command.
170
- */
171
- export function isAdminCommand(text) {
172
- return parseAdminCommand(text) !== null;
173
245
  }
246
+ // ============================================================================
247
+ // List Formatting
248
+ // ============================================================================
174
249
  /**
175
250
  * Format the list of blocked ships for display to owner.
176
251
  */
@@ -178,17 +253,40 @@ export function formatBlockedList(ships) {
178
253
  if (ships.length === 0) {
179
254
  return "No ships are currently blocked.";
180
255
  }
181
- return `Blocked ships (${ships.length}):\n${ships.map((s) => `• ${s}`).join("\n")}`;
256
+ const lines = ships.map((s) => ` ${s}`);
257
+ return [
258
+ `Blocked ships (${ships.length}):`,
259
+ ...lines,
260
+ "",
261
+ "To unban: `/unban ~ship-name`",
262
+ ].join("\n");
182
263
  }
183
264
  /**
184
265
  * Format the list of pending approvals for display to owner.
185
266
  */
186
- export function formatPendingList(approvals) {
187
- if (approvals.length === 0) {
267
+ export function formatPendingList(approvals, ctx) {
268
+ const active = pruneExpired(approvals);
269
+ if (active.length === 0) {
188
270
  return "No pending approval requests.";
189
271
  }
190
- return `Pending approvals (${approvals.length}):\n${approvals
191
- .map((a) => `• ${a.id}: ${a.type} from ${a.requestingShip}`)
192
- .join("\n")}`;
272
+ const entries = active.map((a) => {
273
+ const ship = a.requestingShip;
274
+ const preview = a.messagePreview ? `\n "${truncate(a.messagePreview, 80)}"` : "";
275
+ switch (a.type) {
276
+ case "dm":
277
+ return ` #${a.id} - DM from ${ship}${preview}`;
278
+ case "channel":
279
+ return ` #${a.id} - Mention in ${displayChannel(a.channelNest ?? "", ctx)} by ${ship}${preview}`;
280
+ case "group":
281
+ return ` #${a.id} - Group invite from ${ship} to ${displayGroup(a.groupFlag ?? "", ctx, a.groupTitle)}`;
282
+ }
283
+ });
284
+ return [
285
+ `Pending requests (${active.length}):`,
286
+ "",
287
+ ...entries,
288
+ "",
289
+ "Use /allow, /reject, or /ban with the ID.",
290
+ ].join("\n");
193
291
  }
194
292
  //# sourceMappingURL=approval.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"approval.js","sourceRoot":"","sources":["../../../src/monitor/approval.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"approval.js","sourceRoot":"","sources":["../../../src/monitor/approval.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,62 @@
1
+ /**
2
+ * Command Auth — bridge resolution + owner guard for slash commands.
3
+ *
4
+ * Pure module with no OpenClaw SDK dependency. Accepts a minimal
5
+ * CommandContextLike instead of the full PluginCommandContext.
6
+ */
7
+ import { getBridge, getAllBridges } from "./command-bridge.js";
8
+ import { normalizeShip } from "../targets.js";
9
+ /**
10
+ * Resolve the correct bridge for a command invocation and verify ownership.
11
+ *
12
+ * Selection strategy (does not assume accountId exists):
13
+ * 1. If accountId is set and matches a bridge → use it
14
+ * 2. Else if exactly one bridge exists → use it
15
+ * 3. Else if senderId matches exactly one bridge's ownerShip → use it
16
+ * 4. Else → error
17
+ */
18
+ export function resolveBridgeForCommand(ctx) {
19
+ // 1. Try accountId if available
20
+ if (ctx.accountId) {
21
+ const bridge = getBridge(ctx.accountId);
22
+ if (bridge)
23
+ return checkOwner(ctx, bridge);
24
+ }
25
+ // 2. Fallback: enumerate all bridges
26
+ const all = getAllBridges();
27
+ if (all.size === 0)
28
+ return { error: "Bot is not connected yet." };
29
+ if (all.size === 1) {
30
+ const [, only] = [...all.entries()][0];
31
+ return checkOwner(ctx, only);
32
+ }
33
+ // 3. Multiple bridges — try to match by senderId
34
+ // Note: if two accounts share the same ownerShip, matches.length > 1
35
+ // and we correctly fall through to the ambiguity error.
36
+ if (ctx.senderId) {
37
+ const normalized = normalizeShip(ctx.senderId);
38
+ const matches = [...all.values()].filter((b) => b.ownerShip === normalized);
39
+ if (matches.length === 1)
40
+ return checkOwner(ctx, matches[0]);
41
+ }
42
+ return {
43
+ error: "Multiple accounts connected. Run this command from the owner DM for the target account.",
44
+ };
45
+ }
46
+ /**
47
+ * Default-deny owner check. Both ownerShip and senderId must be known
48
+ * and must match; otherwise the command is refused.
49
+ */
50
+ export function checkOwner(ctx, bridge) {
51
+ if (!bridge.ownerShip) {
52
+ return { error: "Owner ship not configured." };
53
+ }
54
+ if (!ctx.senderId) {
55
+ return { error: "Cannot identify sender." };
56
+ }
57
+ if (normalizeShip(ctx.senderId) !== bridge.ownerShip) {
58
+ return { error: "Only the bot owner can use this command." };
59
+ }
60
+ return { bridge };
61
+ }
62
+ //# sourceMappingURL=command-auth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"command-auth.js","sourceRoot":"","sources":["../../../src/monitor/command-auth.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,SAAS,EAAE,aAAa,EAA8B,MAAM,qBAAqB,CAAC;AAC3F,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAQ9C;;;;;;;;GAQG;AACH,MAAM,UAAU,uBAAuB,CACrC,GAAuB;IAEvB,gCAAgC;IAChC,IAAI,GAAG,CAAC,SAAS,EAAE,CAAC;QAClB,MAAM,MAAM,GAAG,SAAS,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QACxC,IAAI,MAAM;YAAE,OAAO,UAAU,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;IAC7C,CAAC;IAED,qCAAqC;IACrC,MAAM,GAAG,GAAG,aAAa,EAAE,CAAC;IAC5B,IAAI,GAAG,CAAC,IAAI,KAAK,CAAC;QAAE,OAAO,EAAE,KAAK,EAAE,2BAA2B,EAAE,CAAC;IAClE,IAAI,GAAG,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;QACnB,MAAM,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QACvC,OAAO,UAAU,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;IAC/B,CAAC;IAED,iDAAiD;IACjD,qEAAqE;IACrE,wDAAwD;IACxD,IAAI,GAAG,CAAC,QAAQ,EAAE,CAAC;QACjB,MAAM,UAAU,GAAG,aAAa,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAC/C,MAAM,OAAO,GAAG,CAAC,GAAG,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,KAAK,UAAU,CAAC,CAAC;QAC5E,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,UAAU,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;IAC/D,CAAC;IAED,OAAO;QACL,KAAK,EAAE,yFAAyF;KACjG,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,UAAU,CACxB,GAAuB,EACvB,MAA6B;IAE7B,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC;QACtB,OAAO,EAAE,KAAK,EAAE,4BAA4B,EAAE,CAAC;IACjD,CAAC;IACD,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC;QAClB,OAAO,EAAE,KAAK,EAAE,yBAAyB,EAAE,CAAC;IAC9C,CAAC;IACD,IAAI,aAAa,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,MAAM,CAAC,SAAS,EAAE,CAAC;QACrD,OAAO,EAAE,KAAK,EAAE,0CAA0C,EAAE,CAAC;IAC/D,CAAC;IACD,OAAO,EAAE,MAAM,EAAE,CAAC;AACpB,CAAC"}
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Command Bridge Registry
3
+ *
4
+ * Bridges OpenClaw slash commands (registered at plugin init) with monitor
5
+ * approval state (available after SSE starts). Each monitor registers a bridge
6
+ * keyed by accountId; command handlers resolve the correct bridge at runtime.
7
+ */
8
+ const bridges = new Map();
9
+ const DEFAULT_KEY = "default";
10
+ export function setBridge(accountId, b) {
11
+ bridges.set(accountId ?? DEFAULT_KEY, b);
12
+ }
13
+ /** Only removes if the current entry is the same object (safe across monitor restarts). */
14
+ export function removeBridge(accountId, b) {
15
+ const key = accountId ?? DEFAULT_KEY;
16
+ if (bridges.get(key) === b) {
17
+ bridges.delete(key);
18
+ }
19
+ }
20
+ export function getBridge(accountId) {
21
+ return bridges.get(accountId ?? DEFAULT_KEY) ?? null;
22
+ }
23
+ /** Get all registered bridges (for fallback resolution when accountId is unavailable). */
24
+ export function getAllBridges() {
25
+ return bridges;
26
+ }
27
+ //# sourceMappingURL=command-bridge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"command-bridge.js","sourceRoot":"","sources":["../../../src/monitor/command-bridge.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAeH,MAAM,OAAO,GAAG,IAAI,GAAG,EAAiC,CAAC;AAEzD,MAAM,WAAW,GAAG,SAAS,CAAC;AAE9B,MAAM,UAAU,SAAS,CAAC,SAA6B,EAAE,CAAwB;IAC/E,OAAO,CAAC,GAAG,CAAC,SAAS,IAAI,WAAW,EAAE,CAAC,CAAC,CAAC;AAC3C,CAAC;AAED,2FAA2F;AAC3F,MAAM,UAAU,YAAY,CAAC,SAA6B,EAAE,CAAwB;IAClF,MAAM,GAAG,GAAG,SAAS,IAAI,WAAW,CAAC;IACrC,IAAI,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;QAC3B,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IACtB,CAAC;AACH,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,SAA6B;IACrD,OAAO,OAAO,CAAC,GAAG,CAAC,SAAS,IAAI,WAAW,CAAC,IAAI,IAAI,CAAC;AACvD,CAAC;AAED,0FAA0F;AAC1F,MAAM,UAAU,aAAa;IAC3B,OAAO,OAAO,CAAC;AACjB,CAAC"}
@@ -25,13 +25,21 @@ export async function fetchInitData(api, runtime) {
25
25
  const initData = (await api.scry("/groups-ui/v6/init.json"));
26
26
  const channels = [];
27
27
  const channelToGroup = new Map();
28
+ const groupNames = new Map();
28
29
  if (initData?.groups) {
29
30
  for (const [groupFlag, groupData] of Object.entries(initData.groups)) {
30
- if (groupData && typeof groupData === "object" && groupData.channels) {
31
- for (const channelNest of Object.keys(groupData.channels)) {
32
- if (channelNest.startsWith("chat/") || channelNest.startsWith("heap/") || channelNest.startsWith("diary/")) {
33
- channels.push(channelNest);
34
- channelToGroup.set(channelNest, groupFlag);
31
+ if (groupData && typeof groupData === "object") {
32
+ // Extract group title from metadata
33
+ const title = groupData.meta?.title;
34
+ if (title && typeof title === "string") {
35
+ groupNames.set(groupFlag, title);
36
+ }
37
+ if (groupData.channels) {
38
+ for (const channelNest of Object.keys(groupData.channels)) {
39
+ if (channelNest.startsWith("chat/") || channelNest.startsWith("heap/") || channelNest.startsWith("diary/")) {
40
+ channels.push(channelNest);
41
+ channelToGroup.set(channelNest, groupFlag);
42
+ }
35
43
  }
36
44
  }
37
45
  }
@@ -50,11 +58,11 @@ export async function fetchInitData(api, runtime) {
50
58
  runtime.log?.(`[tlon] Found ${pendingCount} pending group invite(s)`);
51
59
  }
52
60
  }
53
- return { channels, channelToGroup, foreigns };
61
+ return { channels, channelToGroup, groupNames, foreigns };
54
62
  }
55
63
  catch (error) {
56
64
  runtime.log?.(`[tlon] Init data fetch failed: ${error?.message ?? String(error)}`);
57
- return { channels: [], channelToGroup: new Map(), foreigns: null };
65
+ return { channels: [], channelToGroup: new Map(), groupNames: new Map(), foreigns: null };
58
66
  }
59
67
  }
60
68
  export async function fetchAllChannels(api, runtime) {
@@ -1 +1 @@
1
- {"version":3,"file":"discovery.js","sourceRoot":"","sources":["../../../src/monitor/discovery.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"discovery.js","sourceRoot":"","sources":["../../../src/monitor/discovery.ts"],"names":[],"mappings":"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"}