@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.
- package/dist/index.js +117 -3
- package/dist/index.js.map +1 -1
- package/dist/src/channel.js +50 -2
- package/dist/src/channel.js.map +1 -1
- package/dist/src/config-schema.js +4 -0
- package/dist/src/config-schema.js.map +1 -1
- package/dist/src/monitor/approval.js +194 -96
- package/dist/src/monitor/approval.js.map +1 -1
- package/dist/src/monitor/command-auth.js +62 -0
- package/dist/src/monitor/command-auth.js.map +1 -0
- package/dist/src/monitor/command-bridge.js +27 -0
- package/dist/src/monitor/command-bridge.js.map +1 -0
- package/dist/src/monitor/discovery.js +15 -7
- package/dist/src/monitor/discovery.js.map +1 -1
- package/dist/src/monitor/index.js +343 -128
- package/dist/src/monitor/index.js.map +1 -1
- package/dist/src/monitor/media.js +33 -27
- package/dist/src/monitor/media.js.map +1 -1
- package/dist/src/monitor/utils.js +21 -0
- package/dist/src/monitor/utils.js.map +1 -1
- package/dist/src/session-roles.js +39 -0
- package/dist/src/session-roles.js.map +1 -0
- package/dist/src/settings.js +5 -1
- package/dist/src/settings.js.map +1 -1
- package/dist/src/types.js +5 -0
- package/dist/src/types.js.map +1 -1
- package/dist/src/urbit/send.js +6 -2
- package/dist/src/urbit/send.js.map +1 -1
- package/dist/src/urbit/sse-client.js +13 -2
- package/dist/src/urbit/sse-client.js.map +1 -1
- package/dist/src/urbit/upload.js +25 -20
- package/dist/src/urbit/upload.js.map +1 -1
- package/dist/src/version.generated.js +3 -0
- package/dist/src/version.generated.js.map +1 -0
- package/package.json +11 -11
|
@@ -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
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
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
|
|
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
|
|
12
|
-
|
|
13
|
-
|
|
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
|
|
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
|
|
47
|
-
`
|
|
142
|
+
return [
|
|
143
|
+
`DM request from ${approval.requestingShip}`,
|
|
144
|
+
preview,
|
|
145
|
+
"",
|
|
146
|
+
actionHintsDm(approval.id),
|
|
147
|
+
].join("\n");
|
|
48
148
|
case "channel":
|
|
49
|
-
return
|
|
50
|
-
|
|
51
|
-
|
|
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
|
|
54
|
-
`
|
|
55
|
-
|
|
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
|
-
|
|
60
|
-
|
|
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
|
-
|
|
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
|
|
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 ${
|
|
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
|
|
227
|
+
return `Approved DM access for ${ship}. They can now message the bot.`;
|
|
130
228
|
}
|
|
131
|
-
return
|
|
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
|
|
233
|
+
return `Approved ${ship} for ${channel}. They can now interact in this channel.`;
|
|
135
234
|
}
|
|
136
|
-
return
|
|
137
|
-
|
|
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
|
|
240
|
+
return `Approved group invite from ${ship} to ${group}. Joining group...`;
|
|
140
241
|
}
|
|
141
|
-
return
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
191
|
-
|
|
192
|
-
.
|
|
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":"AAAA
|
|
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"
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
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":"AAEA,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAE/C,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,GAAiD,EACjD,OAAmB,EACnB,OAAO,GAAG,CAAC;IAEX,IAAI,CAAC;QACH,MAAM,UAAU,GAAG,iBAAiB,CAAC,OAAO,CAAC,CAAC;QAC9C,OAAO,CAAC,GAAG,EAAE,CAAC,uCAAuC,OAAO,cAAc,UAAU,MAAM,CAAC,CAAC;QAC5F,MAAM,OAAO,GAAG,MAAM,GAAG,CAAC,IAAI,CAAC,yBAAyB,UAAU,OAAO,CAAC,CAAC;QAC3E,IAAI,OAAO,EAAE,CAAC;YACZ,OAAO,CAAC,GAAG,EAAE,CAAC,0CAA0C,CAAC,CAAC;YAC1D,OAAO,OAAO,CAAC;QACjB,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,OAAO,KAAU,EAAE,CAAC;QACpB,OAAO,CAAC,GAAG,EAAE,CACX,+DAA+D,KAAK,EAAE,OAAO,IAAI,MAAM,CAAC,KAAK,CAAC,EAAE,CACjG,CAAC;QACF,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;
|
|
1
|
+
{"version":3,"file":"discovery.js","sourceRoot":"","sources":["../../../src/monitor/discovery.ts"],"names":[],"mappings":"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"}
|