@shenhh/popo 0.1.18 → 0.1.20

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": "@shenhh/popo",
3
- "version": "0.1.18",
3
+ "version": "0.1.20",
4
4
  "type": "module",
5
5
  "description": "OpenClaw POPO channel plugin",
6
6
  "license": "MIT",
@@ -237,16 +237,6 @@ Common errors:
237
237
 
238
238
  Recall (retract) a sent message within the allowed time window.
239
239
 
240
- ```json
241
- {
242
- "action": "recall",
243
- "msgId": "794076f2-68b1-4d0e-94eb-c15946580b56",
244
- "target": "user@corp.netease.com"
245
- }
246
- ```
247
-
248
- Or using POPO-specific parameters:
249
-
250
240
  ```json
251
241
  {
252
242
  "action": "recall",
@@ -258,11 +248,8 @@ Or using POPO-specific parameters:
258
248
 
259
249
  **Parameters:**
260
250
  - `msgId` (required): Message ID to recall
261
- - `target` (required*): Target user email or group ID (OpenClaw standard)
262
- - `sessionId` (required*): Session ID (user email for P2P, group ID for group) - alias for target
263
- - `sessionType` (optional): `1` for P2P, `3` for group (auto-detected from target if not provided)
264
-
265
- \* Either `target` or `sessionId` must be provided.
251
+ - `sessionId` (required): Session ID (user email for P2P, group ID for group)
252
+ - `sessionType` (required): `1` for P2P, `3` for group
266
253
 
267
254
  **Note:** Messages can only be recalled within a limited time (typically 2 minutes).
268
255
 
package/src/channel.ts CHANGED
@@ -60,6 +60,7 @@ export const popoPlugin: ChannelPlugin<ResolvedPopoAccount> = {
60
60
  agentPrompt: {
61
61
  messageToolHints: () => [
62
62
  "- POPO targeting: omit `target` to reply to the current conversation (auto-inferred). Explicit targets: `user:email@example.com` or `group:groupId`.",
63
+ "- POPO actions: send, card, unsend (target=to), addParticipant (target=tid), channel-info/channel-edit/channel-delete (channelId=tid), channel-create (no target), member-info (tid param). Custom actions without target: read-ack (msgId), download-file (fileId), update-team-mgmt, view-scope, modify-view-scope, publish-robot, update-instruction-options, configure-card-callback.",
63
64
  ],
64
65
  },
65
66
  groups: {
@@ -171,18 +172,22 @@ export const popoPlugin: ChannelPlugin<ResolvedPopoAccount> = {
171
172
  const enabled = cfg.channels?.popo?.enabled !== false;
172
173
  if (!enabled) return [];
173
174
  // Return all supported actions
175
+ // Use built-in action names to work with OpenClaw's target mode system:
176
+ // - unsend (recall), channel-create (create-team), addParticipant (invite-team)
177
+ // - channel-delete (drop-team), member-info (team-members), channel-info (team-info)
178
+ // - channel-edit (update-team-info)
174
179
  return [
175
180
  "send",
176
181
  "card",
177
- "recall",
182
+ "unsend",
183
+ "channel-create",
184
+ "addParticipant",
185
+ "channel-delete",
186
+ "member-info",
187
+ "channel-info",
188
+ "channel-edit",
178
189
  "read-ack",
179
190
  "download-file",
180
- "create-team",
181
- "invite-team",
182
- "drop-team",
183
- "team-members",
184
- "team-info",
185
- "update-team-info",
186
191
  "update-team-mgmt",
187
192
  "view-scope",
188
193
  "modify-view-scope",
@@ -310,17 +315,22 @@ export const popoPlugin: ChannelPlugin<ResolvedPopoAccount> = {
310
315
  };
311
316
  }
312
317
 
313
- // Handle recall action
314
- if (action === "recall") {
315
- const msgId = typeof params.msgId === "string" ? params.msgId : typeof params.messageId === "string" ? params.messageId : "";
316
- // Support both target (OpenClaw standard) and sessionId (POPO-specific)
317
- const target = typeof params.target === "string" ? params.target : "";
318
- const sessionId = typeof params.sessionId === "string" ? params.sessionId : target;
319
- const sessionType = typeof params.sessionType === "number" ? params.sessionType : (target.includes("@") ? 1 : 3);
318
+ // Handle unsend action (recall message) - uses built-in "unsend" which has proper target mode
319
+ // Accepts: target (to), messageId, sessionId, sessionType
320
+ if (action === "unsend") {
321
+ const msgId = typeof params.messageId === "string" ? params.messageId : typeof params.msgId === "string" ? params.msgId : "";
322
+ // For unsend, sessionId can come from "to" (target) or explicit sessionId
323
+ const sessionId =
324
+ typeof params.sessionId === "string"
325
+ ? params.sessionId
326
+ : typeof params.to === "string"
327
+ ? params.to.trim()
328
+ : "";
329
+ const sessionType = typeof params.sessionType === "number" ? params.sessionType : 1;
320
330
  if (!msgId || !sessionId) {
321
331
  return {
322
332
  isError: true,
323
- content: [{ type: "text", text: "Recall requires msgId and target (or sessionId)." }],
333
+ content: [{ type: "text", text: "Unsend requires messageId and target (or sessionId)." }],
324
334
  };
325
335
  }
326
336
  const result = await recallMessagePopo({ cfg, msgId, sessionId, sessionType: sessionType as 1 | 3 });
@@ -404,8 +414,9 @@ export const popoPlugin: ChannelPlugin<ResolvedPopoAccount> = {
404
414
 
405
415
  // ==================== Team Management Actions ====================
406
416
 
407
- // Handle create-team action
408
- if (action === "create-team") {
417
+ // Handle channel-create action (create team)
418
+ // Built-in action with targetMode: none
419
+ if (action === "channel-create") {
409
420
  const uid = typeof params.uid === "string" ? params.uid : "";
410
421
  const name = typeof params.name === "string" ? params.name : undefined;
411
422
  const uidList = Array.isArray(params.uidList) ? params.uidList : [];
@@ -413,7 +424,7 @@ export const popoPlugin: ChannelPlugin<ResolvedPopoAccount> = {
413
424
  if (!uid || uidList.length === 0) {
414
425
  return {
415
426
  isError: true,
416
- content: [{ type: "text", text: "Create-team requires uid (owner) and uidList (members)." }],
427
+ content: [{ type: "text", text: "channel-create requires uid (owner) and uidList (members)." }],
417
428
  };
418
429
  }
419
430
  const result = await createTeam({ cfg, uid, name, uidList, photoUrl });
@@ -434,16 +445,22 @@ export const popoPlugin: ChannelPlugin<ResolvedPopoAccount> = {
434
445
  };
435
446
  }
436
447
 
437
- // Handle invite-team action
438
- if (action === "invite-team") {
439
- const tid = typeof params.tid === "string" ? params.tid : "";
440
- const inviteList = Array.isArray(params.inviteList) ? params.inviteList : [];
448
+ // Handle addParticipant action (invite to team)
449
+ // Built-in action with targetMode: to (tid comes from target/to)
450
+ if (action === "addParticipant") {
451
+ const tid =
452
+ typeof params.tid === "string"
453
+ ? params.tid
454
+ : typeof params.to === "string"
455
+ ? params.to.trim()
456
+ : "";
457
+ const inviteList = Array.isArray(params.inviteList) ? params.inviteList : Array.isArray(params.participant) ? params.participant : [];
441
458
  const type = typeof params.type === "string" ? (params.type as "1" | "2") : "1";
442
459
  const text = typeof params.text === "string" ? params.text : undefined;
443
460
  if (!tid || inviteList.length === 0) {
444
461
  return {
445
462
  isError: true,
446
- content: [{ type: "text", text: "Invite-team requires tid and inviteList." }],
463
+ content: [{ type: "text", text: "addParticipant requires target (tid) and inviteList/participant." }],
447
464
  };
448
465
  }
449
466
  const result = await inviteToTeam({ cfg, tid, inviteList, type, text });
@@ -463,13 +480,19 @@ export const popoPlugin: ChannelPlugin<ResolvedPopoAccount> = {
463
480
  };
464
481
  }
465
482
 
466
- // Handle drop-team action
467
- if (action === "drop-team") {
468
- const tid = typeof params.tid === "string" ? params.tid : "";
483
+ // Handle channel-delete action (drop/disband team)
484
+ // Built-in action with targetMode: channelId
485
+ if (action === "channel-delete") {
486
+ const tid =
487
+ typeof params.tid === "string"
488
+ ? params.tid
489
+ : typeof params.channelId === "string"
490
+ ? params.channelId.trim()
491
+ : "";
469
492
  if (!tid) {
470
493
  return {
471
494
  isError: true,
472
- content: [{ type: "text", text: "Drop-team requires tid (team ID)." }],
495
+ content: [{ type: "text", text: "channel-delete requires channelId (team ID)." }],
473
496
  };
474
497
  }
475
498
  const result = await dropTeam({ cfg, tid });
@@ -487,15 +510,16 @@ export const popoPlugin: ChannelPlugin<ResolvedPopoAccount> = {
487
510
  };
488
511
  }
489
512
 
490
- // Handle team-members action
491
- if (action === "team-members") {
513
+ // Handle member-info action (get team members)
514
+ // Built-in action with targetMode: none
515
+ if (action === "member-info") {
492
516
  const tid = typeof params.tid === "string" ? params.tid : "";
493
517
  const page = typeof params.page === "number" ? params.page : 1;
494
518
  const limit = typeof params.limit === "number" ? params.limit : 20;
495
519
  if (!tid) {
496
520
  return {
497
521
  isError: true,
498
- content: [{ type: "text", text: "Team-members requires tid (team ID)." }],
522
+ content: [{ type: "text", text: "member-info requires tid (team ID)." }],
499
523
  };
500
524
  }
501
525
  const result = await getTeamMembers({ cfg, tid, page, limit });
@@ -517,14 +541,20 @@ export const popoPlugin: ChannelPlugin<ResolvedPopoAccount> = {
517
541
  };
518
542
  }
519
543
 
520
- // Handle team-info action
521
- if (action === "team-info") {
522
- const tid = typeof params.tid === "string" ? params.tid : "";
544
+ // Handle channel-info action (get team info)
545
+ // Built-in action with targetMode: channelId
546
+ if (action === "channel-info") {
547
+ const tid =
548
+ typeof params.tid === "string"
549
+ ? params.tid
550
+ : typeof params.channelId === "string"
551
+ ? params.channelId.trim()
552
+ : "";
523
553
  const scopes = Array.isArray(params.scopes) ? params.scopes : undefined;
524
554
  if (!tid) {
525
555
  return {
526
556
  isError: true,
527
- content: [{ type: "text", text: "Team-info requires tid (team ID)." }],
557
+ content: [{ type: "text", text: "channel-info requires channelId (team ID)." }],
528
558
  };
529
559
  }
530
560
  const result = await getTeamInfo({ cfg, tid, scopes });
@@ -543,16 +573,22 @@ export const popoPlugin: ChannelPlugin<ResolvedPopoAccount> = {
543
573
  };
544
574
  }
545
575
 
546
- // Handle update-team-info action
547
- if (action === "update-team-info") {
548
- const tid = typeof params.tid === "string" ? params.tid : "";
576
+ // Handle channel-edit action (update team info)
577
+ // Built-in action with targetMode: channelId
578
+ if (action === "channel-edit") {
579
+ const tid =
580
+ typeof params.tid === "string"
581
+ ? params.tid
582
+ : typeof params.channelId === "string"
583
+ ? params.channelId.trim()
584
+ : "";
549
585
  const name = typeof params.name === "string" ? params.name : "";
550
586
  const board = typeof params.board === "string" ? params.board : "";
551
587
  const type = typeof params.type === "number" ? params.type : undefined;
552
588
  if (!tid || !name || !board) {
553
589
  return {
554
590
  isError: true,
555
- content: [{ type: "text", text: "Update-team-info requires tid, name, and board." }],
591
+ content: [{ type: "text", text: "channel-edit requires channelId (tid), name, and board." }],
556
592
  };
557
593
  }
558
594
  const result = await updateTeamInfo({ cfg, tid, name, board, type });