@inline-openclaw/inline 0.0.56 → 0.0.57
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/README.md +10 -11
- package/dist/approval-handler.runtime.js +43 -19
- package/dist/approval-handler.runtime.js.map +3 -3
- package/dist/channel-plugin-api.js +43 -19
- package/dist/channel-plugin-api.js.map +3 -3
- package/docs/create-inline-bot.md +64 -0
- package/docs/openclaw-setup.md +138 -0
- package/openclaw.plugin.json +71 -5
- package/package.json +4 -2
package/README.md
CHANGED
|
@@ -4,8 +4,8 @@ OpenClaw channel plugin for interacting with an OpenClaw agent via **Inline**.
|
|
|
4
4
|
|
|
5
5
|
Status: **beta** (solid foundation; expect iteration).
|
|
6
6
|
|
|
7
|
-
Quick setup guide:
|
|
8
|
-
Create bot/token guide:
|
|
7
|
+
Quick setup guide: [docs/openclaw-setup.md](docs/openclaw-setup.md).
|
|
8
|
+
Create bot/token guide: [docs/create-inline-bot.md](docs/create-inline-bot.md).
|
|
9
9
|
|
|
10
10
|
Supports:
|
|
11
11
|
|
|
@@ -40,13 +40,12 @@ Requires OpenClaw `2026.6.11` or newer.
|
|
|
40
40
|
|
|
41
41
|
| Plugin version | OpenClaw host | Inline realtime SDK | Status | Notes |
|
|
42
42
|
| --- | --- | --- | --- | --- |
|
|
43
|
-
| `0.0.
|
|
44
|
-
| `0.0.
|
|
43
|
+
| `0.0.57` | `>=2026.6.11 || >=2026.7.1-0` | `0.0.14` | Current | Hardens exact CLI-managed upgrades, deterministic channel listing, default/help consistency, and packed-artifact validation. |
|
|
44
|
+
| `0.0.56` | `>=2026.6.11 || >=2026.7.1-0` | `0.0.14` | Previous | Finalizes unified Inline CLI setup compatibility while preserving the separately installed OpenClaw plugin boundary. |
|
|
45
|
+
| `0.0.55` | `>=2026.6.11 || >=2026.7.1-0` | `0.0.14` | Stable | Enforces empty-payload nudges, canonical visible-text sanitizing, hard access-before-mention policy, explicit auto-threading, and clearer formatting guidance; explicitly admits npm's `2026.7.1-2` stable host version. |
|
|
45
46
|
| `0.0.54` | `>=2026.6.11` | `0.0.13` | Stable | Keeps recovered WebSocket and best-effort cursor warnings out of healthy channel status; validated through OpenClaw `2026.7.1-2`. |
|
|
46
47
|
| `0.0.53` | `>=2026.6.11` | `0.0.13` | Stable | Clears recovered Inline WebSocket errors from channel status after reconnect. |
|
|
47
48
|
| `0.0.52` | `>=2026.6.11` | `0.0.13` | Stable | Patch release for the SDK protocol dependency. |
|
|
48
|
-
| `0.0.51` | `>=2026.6.11` | `0.0.12` | Stable | Added follow-mode mention gating for eligible reply/fresh Inline threads. |
|
|
49
|
-
| `0.0.50` | `>=2026.6.11` | `0.0.11` | Stable | Supported line for current stable OpenClaw. Uses focused plugin SDK entrypoints and canonical ClawHub install metadata. |
|
|
50
49
|
|
|
51
50
|
From npm:
|
|
52
51
|
|
|
@@ -110,7 +109,7 @@ You can also leave `token` unset and provide `INLINE_TOKEN` in the gateway envir
|
|
|
110
109
|
`baseUrl` defaults to `https://api.inline.chat`.
|
|
111
110
|
`dmPolicy` defaults to `pairing` (recommended starting point).
|
|
112
111
|
`defaultTo` is optional and gives outbound sends a fallback target when no explicit target is supplied.
|
|
113
|
-
`
|
|
112
|
+
`groupPolicy` defaults to `"open"`, and `requireMention` defaults to `true`, so group chats are broadly available but only explicit mentions wake the bot unless configured otherwise.
|
|
114
113
|
|
|
115
114
|
### Who can talk to the bot?
|
|
116
115
|
|
|
@@ -122,8 +121,8 @@ Use these settings together:
|
|
|
122
121
|
| DMs | `dmPolicy: "allowlist"` + `allowFrom` | Only listed Inline user ids can DM the bot. |
|
|
123
122
|
| DMs | `dmPolicy: "open"` + `allowFrom: ["*"]` | Any Inline user can DM the bot. Use only for public/demo bots. |
|
|
124
123
|
| DMs | `dmPolicy: "disabled"` | DM messages are ignored. |
|
|
125
|
-
| Groups | `groupPolicy: "
|
|
126
|
-
| Groups | `groupPolicy: "
|
|
124
|
+
| Groups | `groupPolicy: "open"` | Any group chat can reach the bot; this is the default. `requireMention` also defaults to `true`, so ambient messages do not wake it. |
|
|
125
|
+
| Groups | `groupPolicy: "allowlist"` + `groups` | Only listed group chat ids can reach the bot. Setup keeps `requireMention: true` unless explicitly overridden. |
|
|
127
126
|
| Groups | `groupPolicy: "disabled"` | Group messages are ignored. |
|
|
128
127
|
| Group senders | `groupAllowFrom` or `groups.<chat>.allowFrom` | Optional sender allowlist inside allowed groups. Per-group entries override the account-wide list for that group. Leave empty to allow any sender in an allowed group. |
|
|
129
128
|
|
|
@@ -153,10 +152,10 @@ channels:
|
|
|
153
152
|
target: "dm" # dm|channel|both
|
|
154
153
|
|
|
155
154
|
# Group threads/chats:
|
|
156
|
-
groupPolicy: "
|
|
155
|
+
groupPolicy: "open" # open|allowlist|disabled; default open
|
|
157
156
|
groupAllowFrom:
|
|
158
157
|
- "inline:123" # or "user:123" or just "123"
|
|
159
|
-
requireMention: true # optional: default is
|
|
158
|
+
requireMention: true # optional: default is true
|
|
160
159
|
replyToBotWithoutMention: true # if true, replies to bot messages can bypass mention requirement
|
|
161
160
|
replyThreadMode: "auto" # auto|thread|main; auto threads only explicit requests, thread always routes top-level turns
|
|
162
161
|
replyThreadRequireExplicitMention: false # optional, default false; bot-participated reply threads continue without @mention
|
|
@@ -48274,6 +48274,7 @@ function mapTranslation(translation) {
|
|
|
48274
48274
|
}
|
|
48275
48275
|
function mapChatEntry(params) {
|
|
48276
48276
|
const dialog = params.dialogByChatId.get(String(params.chat.id));
|
|
48277
|
+
const lastMessage = params.chat.lastMsgId != null ? params.messagesById.get(String(params.chat.lastMsgId)) : undefined;
|
|
48277
48278
|
const peer = params.chat.peerId?.type;
|
|
48278
48279
|
let peerUser = null;
|
|
48279
48280
|
if (peer?.oneofKind === "user") {
|
|
@@ -48287,6 +48288,7 @@ function mapChatEntry(params) {
|
|
|
48287
48288
|
isPublic: params.chat.isPublic ?? false,
|
|
48288
48289
|
createdBy: params.chat.createdBy != null ? String(params.chat.createdBy) : null,
|
|
48289
48290
|
date: params.chat.date != null ? Number(params.chat.date) * 1000 : null,
|
|
48291
|
+
lastMessageDate: lastMessage?.date != null ? Number(lastMessage.date) * 1000 : null,
|
|
48290
48292
|
unreadCount: dialog?.unreadCount ?? 0,
|
|
48291
48293
|
archived: Boolean(dialog?.archived),
|
|
48292
48294
|
pinned: Boolean(dialog?.pinned),
|
|
@@ -48295,22 +48297,32 @@ function mapChatEntry(params) {
|
|
|
48295
48297
|
id: String(peer.user.userId),
|
|
48296
48298
|
target: `user:${String(peer.user.userId)}`,
|
|
48297
48299
|
username: peerUser?.username ?? null,
|
|
48298
|
-
name: peerUser ? buildInlineUserDisplayName(peerUser) : null
|
|
48300
|
+
name: peerUser ? buildInlineUserDisplayName(peerUser) : null,
|
|
48301
|
+
bot: peerUser?.bot ?? false
|
|
48299
48302
|
} : peer?.oneofKind === "chat" ? { kind: "chat", id: String(peer.chat.chatId), target: `chat:${String(peer.chat.chatId)}` } : null
|
|
48300
48303
|
};
|
|
48301
48304
|
}
|
|
48302
|
-
function
|
|
48303
|
-
|
|
48305
|
+
function compareInlineChatActivityDesc(left, right) {
|
|
48306
|
+
const activityOrder = (right.lastMessageDate ?? 0) - (left.lastMessageDate ?? 0);
|
|
48307
|
+
if (activityOrder !== 0)
|
|
48308
|
+
return activityOrder;
|
|
48309
|
+
const leftId = BigInt(left.id);
|
|
48310
|
+
const rightId = BigInt(right.id);
|
|
48311
|
+
return rightId > leftId ? 1 : rightId < leftId ? -1 : 0;
|
|
48304
48312
|
}
|
|
48305
|
-
function
|
|
48313
|
+
function projectInlinePeer(entry) {
|
|
48314
|
+
if (entry.peer?.kind !== "user")
|
|
48315
|
+
return null;
|
|
48306
48316
|
return {
|
|
48307
|
-
|
|
48308
|
-
|
|
48309
|
-
|
|
48310
|
-
|
|
48311
|
-
bot: user.bot ?? false
|
|
48317
|
+
...entry.peer,
|
|
48318
|
+
chatId: entry.id,
|
|
48319
|
+
chatTarget: entry.target,
|
|
48320
|
+
lastMessageDate: entry.lastMessageDate
|
|
48312
48321
|
};
|
|
48313
48322
|
}
|
|
48323
|
+
function normalizeInlineListQuery(query) {
|
|
48324
|
+
return query?.trim().toLowerCase() ?? "";
|
|
48325
|
+
}
|
|
48314
48326
|
function mapPeerBotCommandGroup(group) {
|
|
48315
48327
|
const bot = group.bot ?? null;
|
|
48316
48328
|
const commands = (group.commands ?? []).map((command) => ({
|
|
@@ -50167,26 +50179,38 @@ var inlineMessageActions = {
|
|
|
50167
50179
|
}
|
|
50168
50180
|
const dialogByChatId = buildDialogMap(result.getChats.dialogs ?? []);
|
|
50169
50181
|
const usersById = buildUserMap2(result.getChats.users ?? []);
|
|
50170
|
-
const
|
|
50171
|
-
const
|
|
50172
|
-
const peers = (result.getChats.users ?? []).map((user) => mapUserPeerEntry(user));
|
|
50182
|
+
const messagesById = new Map((result.getChats.messages ?? []).map((message) => [String(message.id), message]));
|
|
50183
|
+
const chats = (result.getChats.chats ?? []).map((chat) => mapChatEntry({ chat, dialogByChatId, usersById, messagesById }));
|
|
50173
50184
|
const normalizedQuery = normalizeInlineListQuery(query);
|
|
50174
50185
|
const filteredChats = chats.filter((entry) => matchesInlineListQuery([entry.id, entry.target, entry.title, entry.peer?.kind === "user" ? entry.peer.username ?? "" : "", entry.peer?.kind === "user" ? entry.peer.name ?? "" : ""].join(`
|
|
50175
50186
|
`), normalizedQuery));
|
|
50176
|
-
const filteredGroups =
|
|
50187
|
+
const filteredGroups = filteredChats.filter((entry) => entry.peer?.kind !== "user" && matchesInlineListQuery([entry.id, entry.target, entry.title].join(`
|
|
50177
50188
|
`), normalizedQuery));
|
|
50178
|
-
const
|
|
50189
|
+
const filteredPeerChats = filteredChats.filter((entry) => entry.peer?.kind === "user" && matchesInlineListQuery([
|
|
50190
|
+
entry.id,
|
|
50191
|
+
entry.target,
|
|
50192
|
+
entry.peer.id,
|
|
50193
|
+
entry.peer.target,
|
|
50194
|
+
entry.peer.username ?? "",
|
|
50195
|
+
entry.peer.name ?? ""
|
|
50196
|
+
].join(`
|
|
50179
50197
|
`), normalizedQuery));
|
|
50198
|
+
const groupScope = ["groups", "group", "channels", "channel"].includes(scope);
|
|
50199
|
+
const peerScope = ["peers", "peer", "members", "member", "users", "user"].includes(scope);
|
|
50200
|
+
const scopedChats = groupScope ? filteredGroups : peerScope ? filteredPeerChats : filteredChats;
|
|
50201
|
+
const selectedChats = [...scopedChats].sort(compareInlineChatActivityDesc).slice(0, limit);
|
|
50202
|
+
const selectedGroups = selectedChats.filter((entry) => entry.peer?.kind !== "user");
|
|
50203
|
+
const selectedPeers = selectedChats.map(projectInlinePeer).filter((entry) => entry != null);
|
|
50180
50204
|
return jsonResult(toJsonSafe({
|
|
50181
50205
|
ok: true,
|
|
50182
50206
|
scope,
|
|
50183
50207
|
query: query ?? null,
|
|
50184
50208
|
count: filteredChats.length,
|
|
50185
50209
|
groupsCount: filteredGroups.length,
|
|
50186
|
-
peersCount:
|
|
50187
|
-
chats:
|
|
50188
|
-
groups:
|
|
50189
|
-
peers:
|
|
50210
|
+
peersCount: filteredPeerChats.length,
|
|
50211
|
+
chats: groupScope || peerScope ? [] : selectedChats,
|
|
50212
|
+
groups: peerScope ? [] : selectedGroups,
|
|
50213
|
+
peers: groupScope ? [] : selectedPeers
|
|
50190
50214
|
}));
|
|
50191
50215
|
}
|
|
50192
50216
|
});
|
|
@@ -51220,5 +51244,5 @@ export {
|
|
|
51220
51244
|
inlineApprovalNativeRuntime
|
|
51221
51245
|
};
|
|
51222
51246
|
|
|
51223
|
-
//# debugId=
|
|
51247
|
+
//# debugId=A08D41E59E933D4864756E2164756E21
|
|
51224
51248
|
//# sourceMappingURL=approval-handler.runtime.js.map
|