@shadowob/openclaw-shadowob 1.1.6 → 1.1.7

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.
@@ -1201,22 +1201,89 @@ function resolveOwnerAllowFrom(policyConfig) {
1201
1201
  const ownerId = typeof policyConfig?.ownerId === "string" ? policyConfig.ownerId.trim() : "";
1202
1202
  return ownerId ? [ownerId] : void 0;
1203
1203
  }
1204
- async function buildMentionedServerAppSkillsContext(params) {
1204
+ var MAX_SERVER_APPS_IN_CONTEXT = 8;
1205
+ function serverAppCommandSummary(app) {
1206
+ return app.manifest.commands.slice(0, 6).map(
1207
+ (command) => `${command.name}(${command.action}, permission=${command.permission}, approval=${command.approvalMode ?? app.defaultApprovalMode})`
1208
+ ).join("; ");
1209
+ }
1210
+ function formatInstalledServerAppSummary(ref) {
1211
+ const app = ref.app;
1212
+ if (!app) {
1213
+ return `- ${ref.label}: appKey=${ref.appKey}, server=${ref.server}${ref.mentioned ? ", mentioned=true" : ""}`;
1214
+ }
1215
+ return [
1216
+ `- ${app.name}: appKey=${app.appKey}, server=${ref.server}, defaultPermissions=${app.defaultPermissions.join(",") || "none"}, defaultApproval=${app.defaultApprovalMode}`,
1217
+ app.description ? ` description=${app.description}` : "",
1218
+ ` commands=${serverAppCommandSummary(app)}`
1219
+ ].filter(Boolean).join("\n");
1220
+ }
1221
+ function serverAppContextFields(apps) {
1222
+ if (apps.length === 0) return {};
1223
+ return {
1224
+ ServerApps: apps.map((app) => ({
1225
+ id: app.id,
1226
+ serverId: app.serverId,
1227
+ appKey: app.appKey,
1228
+ name: app.name,
1229
+ description: app.description,
1230
+ defaultPermissions: app.defaultPermissions,
1231
+ defaultApprovalMode: app.defaultApprovalMode,
1232
+ commands: app.manifest.commands.map((command) => ({
1233
+ name: command.name,
1234
+ title: command.title,
1235
+ description: command.description,
1236
+ permission: command.permission,
1237
+ action: command.action,
1238
+ dataClass: command.dataClass,
1239
+ approvalMode: command.approvalMode ?? app.defaultApprovalMode
1240
+ }))
1241
+ })),
1242
+ ServerAppSummary: apps.map((app) => `${app.name} (${app.appKey})`).join(", ")
1243
+ };
1244
+ }
1245
+ async function buildServerAppSkillsContext(params) {
1205
1246
  const appRefs = /* @__PURE__ */ new Map();
1247
+ const installedApps = [];
1248
+ if (params.serverInfo) {
1249
+ const server = params.serverInfo.serverSlug || params.serverInfo.serverId;
1250
+ try {
1251
+ const apps = await params.client.listServerApps(params.serverInfo.serverId);
1252
+ for (const app of apps.filter((item) => item.status !== "disabled")) {
1253
+ installedApps.push(app);
1254
+ appRefs.set(`${params.serverInfo.serverId}:${app.appKey}`, {
1255
+ appKey: app.appKey,
1256
+ server,
1257
+ label: app.name,
1258
+ app,
1259
+ mentioned: false
1260
+ });
1261
+ }
1262
+ } catch (err) {
1263
+ params.runtime.error?.(
1264
+ `[server-app] Failed listing apps for ${params.serverInfo.serverId}: ${String(err)}`
1265
+ );
1266
+ }
1267
+ }
1206
1268
  for (const mention of params.mentions) {
1207
1269
  if (mention.kind !== "app") continue;
1208
1270
  const appKey = mention.appKey ?? mention.targetId;
1209
1271
  const server = mention.serverId ?? mention.serverSlug ?? params.serverInfo?.serverId;
1210
1272
  if (!appKey || !server) continue;
1211
- appRefs.set(`${server}:${appKey}`, {
1273
+ const key = `${server}:${appKey}`;
1274
+ const existing = appRefs.get(key);
1275
+ appRefs.set(key, {
1276
+ ...existing,
1212
1277
  appKey,
1213
1278
  server,
1214
- label: mention.label || mention.sourceToken || mention.token || appKey
1279
+ label: mention.label || mention.sourceToken || mention.token || appKey,
1280
+ mentioned: true
1215
1281
  });
1216
1282
  }
1217
- if (appRefs.size === 0) return "";
1283
+ if (appRefs.size === 0) return { prompt: "", fields: {} };
1284
+ const refs = Array.from(appRefs.values()).slice(0, MAX_SERVER_APPS_IN_CONTEXT);
1218
1285
  const documents = await Promise.all(
1219
- Array.from(appRefs.values()).map(async (ref) => {
1286
+ refs.map(async (ref) => {
1220
1287
  try {
1221
1288
  const skill = await params.client.getServerAppSkills(ref.server, ref.appKey);
1222
1289
  return [
@@ -1235,13 +1302,17 @@ async function buildMentionedServerAppSkillsContext(params) {
1235
1302
  })
1236
1303
  );
1237
1304
  const loaded = documents.filter(Boolean);
1238
- if (loaded.length === 0) return "";
1239
- return [
1240
- "Injected Shadow Server App Skills:",
1241
- "These instructions are authoritative for mentioned server apps in this message. Use the Shadow CLI path described below so Shadow can bind identity, app grants, and policy.",
1305
+ const prompt = [
1306
+ "Shadow Server Apps available in this server:",
1307
+ ...refs.map(formatInstalledServerAppSummary),
1242
1308
  "",
1309
+ "Use these apps when the user asks natural-language questions or tasks that match an installed app name, description, or command capability. Do not wait for the user to say a CLI command or explicitly mention the app.",
1310
+ 'Operate server apps through the mounted Shadow CLI only so Shadow can bind the Buddy identity, app grants, approval prompts, and policy: run `shadowob app discover --server "<current-server-id-or-slug>" --json` when needed, then `shadowob app call "<appKey>" <command> --server "<current-server-id-or-slug>" --channel-id "<current-channel-id>" --json-input \'<raw-command-input-json>\' --json`. Do not use curl, fetch, raw HTTP routes, or SDK calls for server-app commands.',
1311
+ "Shadow App command approvals are system permission prompts, not chat interactive dialogs. Never send a Shadow interactive form/buttons/approval message as a substitute for App command approval, and never call the App approval endpoint yourself as a Buddy. If the CLI returns SERVER_APP_COMMAND_APPROVAL_REQUIRED, tell the user that Shadow opened the approval popup, then stop until a person confirms and asks you to retry.",
1312
+ loaded.length > 0 ? "Injected Shadow Server App Skills:" : "",
1243
1313
  ...loaded
1244
- ].join("\n");
1314
+ ].filter(Boolean).join("\n");
1315
+ return { prompt, fields: serverAppContextFields(installedApps) };
1245
1316
  }
1246
1317
  async function processShadowMessage(params) {
1247
1318
  const {
@@ -1337,7 +1408,7 @@ async function processShadowMessage(params) {
1337
1408
  const conversationLabel = serverInfo ? `${serverInfo.serverName} ${channelLabel}` : peerId;
1338
1409
  const messageBodyForAgent = interactiveResponseContext.text || baseBodyForAgent;
1339
1410
  const client = new ShadowClient2(account.serverUrl, account.token);
1340
- const serverAppSkillsContext = await buildMentionedServerAppSkillsContext({
1411
+ const serverAppContext = await buildServerAppSkillsContext({
1341
1412
  mentions: structuredMentions,
1342
1413
  client,
1343
1414
  serverInfo,
@@ -1353,7 +1424,7 @@ async function processShadowMessage(params) {
1353
1424
  buildCommerceContextForAgent(account),
1354
1425
  viewerCommerceContext,
1355
1426
  mentionContext,
1356
- serverAppSkillsContext,
1427
+ serverAppContext.prompt,
1357
1428
  messageBodyForAgent
1358
1429
  ].filter(Boolean).join("\n\n");
1359
1430
  const body = core.channel.reply.formatAgentEnvelope({
@@ -1388,6 +1459,7 @@ async function processShadowMessage(params) {
1388
1459
  MessageSid: message.id,
1389
1460
  WasMentioned: wasMentioned,
1390
1461
  ...mentionContextFields(structuredMentions),
1462
+ ...serverAppContext.fields,
1391
1463
  OriginatingChannel: "shadowob",
1392
1464
  OriginatingTo: `shadowob:channel:${channelId}`,
1393
1465
  NativeChannelId: channelId,
package/dist/index.js CHANGED
@@ -15,7 +15,7 @@ import {
15
15
  resolveOutboundMentions,
16
16
  setShadowRuntime,
17
17
  tryGetShadowRuntime
18
- } from "./chunk-4G572ZLC.js";
18
+ } from "./chunk-XOO7S6K5.js";
19
19
 
20
20
  // index.ts
21
21
  import { defineChannelPluginEntry } from "openclaw/plugin-sdk/core";
@@ -960,7 +960,7 @@ shadowPlugin.gateway = {
960
960
  lastError: null
961
961
  });
962
962
  ctx.log?.info(`Starting Shadow connection for account ${accountId}`);
963
- const { monitorShadowProvider: monitorShadowProvider2 } = await import("./monitor-XDUBTELB.js");
963
+ const { monitorShadowProvider: monitorShadowProvider2 } = await import("./monitor-K7U33EFS.js");
964
964
  await monitorShadowProvider2({
965
965
  account,
966
966
  accountId,
@@ -5,7 +5,7 @@ import {
5
5
  normalizeShadowSlashCommands,
6
6
  resolveShadowAgentIdFromConfig,
7
7
  shouldCatchUpShadowMessage
8
- } from "./chunk-4G572ZLC.js";
8
+ } from "./chunk-XOO7S6K5.js";
9
9
  export {
10
10
  formatSlashCommandPrompt,
11
11
  matchShadowSlashCommand,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shadowob/openclaw-shadowob",
3
- "version": "1.1.6",
3
+ "version": "1.1.7",
4
4
  "description": "OpenClaw Shadow channel plugin — enables AI agents to interact in Shadow server channels",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -58,7 +58,7 @@
58
58
  "dependencies": {
59
59
  "zod": "^3.25.67",
60
60
  "openclaw": "^2026.5.7",
61
- "@shadowob/sdk": "1.1.6"
61
+ "@shadowob/sdk": "1.1.7"
62
62
  },
63
63
  "devDependencies": {
64
64
  "@types/node": "^22.15.21",
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: shadowob
3
- description: "Use when live Shadow context or actions are needed: channel/DM history, pins, members, server/channel/workspace/shop/app/agent data, or sending/managing Shadow content via the shadowob CLI."
3
+ description: "Use when live Shadow context or actions are needed: channel/DM history, pins, members, server/channel/workspace/shop/app/buddy data, or sending/managing Shadow content via the shadowob CLI."
4
4
  metadata:
5
5
  {
6
6
  "openclaw":
@@ -18,7 +18,7 @@ allowed-tools: ["exec"]
18
18
  Use `shadowob` CLI to interact with Shadow servers.
19
19
 
20
20
  Activate this skill when you need current Shadow context, such as recent channel or DM history,
21
- pinned messages, member/server/channel state, workspace/shop/app/agent data, or when you need to
21
+ pinned messages, member/server/channel state, workspace/shop/app/buddy data, or when you need to
22
22
  send or manage Shadow content. Prefer narrow `--json` reads before acting.
23
23
 
24
24
  ## Quickstart
@@ -78,13 +78,13 @@ shadowob servers discover --json
78
78
 
79
79
  ```bash
80
80
  # List channels
81
- shadowob channels list --server-id <server-id> --json
81
+ shadowob channels list --server <server> --json
82
82
 
83
83
  # Get channel
84
84
  shadowob channels get <channel-id> --json
85
85
 
86
86
  # Create/Delete
87
- shadowob channels create --server-id <id> --name <name> [--type text] --json
87
+ shadowob channels create --server <server> --name <name> [--type text] --json
88
88
  shadowob channels delete <channel-id>
89
89
 
90
90
  # Messages
@@ -141,29 +141,29 @@ shadowob dms send <dm-channel-id> --content "text" --json
141
141
  shadowob dms delete <dm-channel-id>
142
142
  ```
143
143
 
144
- ## Agents
144
+ ## Buddies
145
145
 
146
146
  ```bash
147
- # List agents
148
- shadowob agents list --json
147
+ # List buddies
148
+ shadowob buddies list --json
149
149
 
150
- # Get agent
151
- shadowob agents get <agent-id> --json
150
+ # Get buddy
151
+ shadowob buddies get <buddy-id> --json
152
152
 
153
153
  # Create/Update/Delete
154
- shadowob agents create --name <name> [--display-name <name>] [--avatar-url <url>] --json
155
- shadowob agents update <agent-id> [--name <name>] [--display-name <name>] --json
156
- shadowob agents delete <agent-id>
154
+ shadowob buddies create --name <name> --username <username> [--display-name <name>] [--avatar-url <url>] --json
155
+ shadowob buddies update <buddy-id> [--name <name>] [--display-name <name>] --json
156
+ shadowob buddies delete <buddy-id>
157
157
 
158
158
  # Control
159
- shadowob agents start <agent-id>
160
- shadowob agents stop <agent-id>
159
+ shadowob buddies start <buddy-id>
160
+ shadowob buddies stop <buddy-id>
161
161
 
162
162
  # Token
163
- shadowob agents token <agent-id> --json
163
+ shadowob buddies token <buddy-id> --json
164
164
 
165
165
  # Config
166
- shadowob agents config <agent-id> --json
166
+ shadowob buddies config <buddy-id> --json
167
167
  ```
168
168
 
169
169
  ## Workspace
@@ -211,7 +211,6 @@ shadowob shop me get --json
211
211
  shadowob shop products list <server-id> [--status active] [--keyword <text>] [--limit <n>] --json
212
212
  shadowob shop products list-by-shop <shop-id> [--status active] [--limit <n>] --json
213
213
  shadowob shop products get <server-id> <product-id> --json
214
- shadowob shop products context <product-id> --json
215
214
  shadowob shop products purchase <shop-id> <product-id> --idempotency-key <unique-operation-id> --json
216
215
 
217
216
  # Offers, deliverables, and shop assets
@@ -246,7 +245,7 @@ shadowob commerce cards list --channel-id <channel-id> [--keyword <text>] --json
246
245
  shadowob commerce cards purchase <message-id> <card-id> --idempotency-key <unique-operation-id> --json
247
246
 
248
247
  # Purchases, delivery, protected files, and community assets
249
- shadowob commerce entitlements list [--server-id <server-id>] --json
248
+ shadowob commerce entitlements list [--server <server>] --json
250
249
  shadowob commerce entitlements get <entitlement-id> --json
251
250
  shadowob commerce entitlements verify <entitlement-id> --json
252
251
  shadowob commerce paid-files open <file-id> --json
@@ -277,17 +276,22 @@ shadowob commerce gifts send --recipient-user-id <user-id> --assets '<json-array
277
276
  # Server App integrations
278
277
  shadowob app list --server <server-id-or-slug> --json
279
278
  shadowob app preview --server <server-id-or-slug> --manifest-url <manifest-url> --json
279
+ shadowob app install --server <server-id-or-slug> --manifest-url <manifest-url> --json
280
+ shadowob app uninstall <app-key> --server <server-id-or-slug>
280
281
  shadowob app discover --server <server-id-or-slug> --json
281
282
  shadowob app inspect <app-key> --server <server-id-or-slug> --json
282
283
  shadowob app skills <app-key> --server <server-id-or-slug>
283
- shadowob app call <app-key> <command> --server <server-id-or-slug> --json-input '<raw-command-input-json>' --json
284
+ shadowob app call <app-key> <command> --server <server-id-or-slug> --channel-id <channel-id> --json-input '<raw-command-input-json>' --json
284
285
  ```
285
286
 
286
287
  For server App commands, use the `shadowob app` CLI path only. Do not use curl, fetch, raw HTTP
287
288
  routes, or the JavaScript SDK to call server App commands. Pass the command input object directly
288
289
  to `--json-input`, for example `{"title":"Example","priority":"high"}`; the CLI wraps the HTTP
289
290
  request for you and binds Shadow OAuth identity, server membership, App grants, and command policy.
290
- When a channel message mentions a server App, use the mentioned app key/server id directly.
291
+ When a channel message mentions a server App, use the mentioned app key/server id directly and pass
292
+ the current channel id with `--channel-id` when available. If a server App command requires
293
+ approval, do not send a chat form or call the approval endpoint yourself as a Buddy. Wait for a
294
+ person to confirm the Shadow approval popup, then retry the original command.
291
295
 
292
296
  ```bash
293
297
  # Legacy workspace apps
@@ -404,7 +408,7 @@ shadowob marketplace contracts extend <contract-id> --hours <n> --json
404
408
 
405
409
  ```bash
406
410
  # Upload a file
407
- shadowob media upload --file <path> [--server-id <id>] [--channel-id <id>] --json
411
+ shadowob media upload --file <path> [--server <server>] [--channel-id <id>] --json
408
412
 
409
413
  # Download a file
410
414
  shadowob media download <file-url> [--output <path>]
@@ -414,7 +418,7 @@ shadowob media download <file-url> [--output <path>]
414
418
 
415
419
  ```bash
416
420
  # Search messages
417
- shadowob search messages --query <text> [--server-id <id>] [--channel-id <id>] [--author-id <id>] [--after <date>] [--before <date>] [--has-attachments] [--limit <n>] --json
421
+ shadowob search messages --query <text> [--server <server>] [--channel-id <id>] [--author-id <id>] [--after <date>] [--before <date>] [--has-attachments] [--limit <n>] --json
418
422
  ```
419
423
 
420
424
  ## Listen (Real-time Events)