@zhin.js/adapter-kook 5.0.0 → 5.0.2

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.
Files changed (97) hide show
  1. package/CHANGELOG.md +34 -0
  2. package/README.md +1 -0
  3. package/{skills/kook → agent}/PERMITS.md +1 -1
  4. package/agent/tools/blacklist.ts +33 -0
  5. package/agent/tools/create_role.ts +25 -0
  6. package/agent/tools/delete_role.ts +21 -0
  7. package/agent/tools/grant_role.ts +22 -0
  8. package/agent/tools/list_roles.ts +27 -0
  9. package/agent/tools/revoke_role.ts +22 -0
  10. package/dist/index.js +2 -2
  11. package/lib/agent/tools/blacklist.js +33 -0
  12. package/lib/agent/tools/blacklist.js.map +1 -0
  13. package/lib/agent/tools/create_role.js +25 -0
  14. package/lib/agent/tools/create_role.js.map +1 -0
  15. package/lib/agent/tools/delete_role.js +21 -0
  16. package/lib/agent/tools/delete_role.js.map +1 -0
  17. package/lib/agent/tools/grant_role.js +22 -0
  18. package/lib/agent/tools/grant_role.js.map +1 -0
  19. package/lib/agent/tools/list_roles.js +27 -0
  20. package/lib/agent/tools/list_roles.js.map +1 -0
  21. package/lib/agent/tools/revoke_role.js +22 -0
  22. package/lib/agent/tools/revoke_role.js.map +1 -0
  23. package/lib/{adapter.js → src/adapter.js} +4 -3
  24. package/lib/src/adapter.js.map +1 -0
  25. package/lib/{endpoint.js → src/endpoint.js} +93 -59
  26. package/lib/src/endpoint.js.map +1 -0
  27. package/lib/src/index.js +197 -0
  28. package/lib/src/index.js.map +1 -0
  29. package/lib/src/kook-agent-deps.js +10 -0
  30. package/lib/src/kook-agent-deps.js.map +1 -0
  31. package/lib/src/kook-asset-upload.js.map +1 -0
  32. package/lib/src/kook-inbound.js.map +1 -0
  33. package/lib/src/kook-msg-route.js.map +1 -0
  34. package/lib/{kook-side-events.js → src/kook-side-events.js} +52 -33
  35. package/lib/src/kook-side-events.js.map +1 -0
  36. package/lib/src/outbound-keyboard.js +66 -0
  37. package/lib/src/outbound-keyboard.js.map +1 -0
  38. package/lib/{outbound-media.js → src/outbound-media.js} +4 -1
  39. package/lib/src/outbound-media.js.map +1 -0
  40. package/lib/{outbound-sendable.js → src/outbound-sendable.js} +9 -0
  41. package/lib/src/outbound-sendable.js.map +1 -0
  42. package/lib/{platform-permit.js → src/platform-permit.js} +5 -2
  43. package/lib/src/platform-permit.js.map +1 -0
  44. package/lib/src/segment-mapper.js +2 -0
  45. package/lib/src/segment-mapper.js.map +1 -0
  46. package/lib/src/types.js.map +1 -0
  47. package/package.json +26 -16
  48. package/src/adapter.ts +5 -5
  49. package/src/endpoint.ts +97 -66
  50. package/src/index.ts +14 -168
  51. package/src/kook-agent-deps.ts +22 -0
  52. package/src/kook-side-events.ts +66 -38
  53. package/src/outbound-keyboard.ts +77 -0
  54. package/src/outbound-media.ts +1 -8
  55. package/src/outbound-sendable.ts +13 -1
  56. package/src/platform-permit.ts +5 -6
  57. package/src/segment-mapper.ts +1 -0
  58. package/src/types.ts +1 -2
  59. package/lib/adapter.d.ts +0 -29
  60. package/lib/adapter.d.ts.map +0 -1
  61. package/lib/adapter.js.map +0 -1
  62. package/lib/endpoint.d.ts +0 -155
  63. package/lib/endpoint.d.ts.map +0 -1
  64. package/lib/endpoint.js.map +0 -1
  65. package/lib/index.d.ts +0 -18
  66. package/lib/index.d.ts.map +0 -1
  67. package/lib/index.js +0 -350
  68. package/lib/index.js.map +0 -1
  69. package/lib/kook-asset-upload.d.ts +0 -12
  70. package/lib/kook-asset-upload.d.ts.map +0 -1
  71. package/lib/kook-asset-upload.js.map +0 -1
  72. package/lib/kook-inbound.d.ts +0 -6
  73. package/lib/kook-inbound.d.ts.map +0 -1
  74. package/lib/kook-inbound.js.map +0 -1
  75. package/lib/kook-msg-route.d.ts +0 -34
  76. package/lib/kook-msg-route.d.ts.map +0 -1
  77. package/lib/kook-msg-route.js.map +0 -1
  78. package/lib/kook-side-events.d.ts +0 -43
  79. package/lib/kook-side-events.d.ts.map +0 -1
  80. package/lib/kook-side-events.js.map +0 -1
  81. package/lib/outbound-media.d.ts +0 -10
  82. package/lib/outbound-media.d.ts.map +0 -1
  83. package/lib/outbound-media.js.map +0 -1
  84. package/lib/outbound-sendable.d.ts +0 -11
  85. package/lib/outbound-sendable.d.ts.map +0 -1
  86. package/lib/outbound-sendable.js.map +0 -1
  87. package/lib/platform-permit.d.ts +0 -14
  88. package/lib/platform-permit.d.ts.map +0 -1
  89. package/lib/platform-permit.js.map +0 -1
  90. package/lib/types.d.ts +0 -54
  91. package/lib/types.d.ts.map +0 -1
  92. package/lib/types.js.map +0 -1
  93. /package/{skills/kook/SKILL.md → agent/skills/kook.md} +0 -0
  94. /package/lib/{kook-asset-upload.js → src/kook-asset-upload.js} +0 -0
  95. /package/lib/{kook-inbound.js → src/kook-inbound.js} +0 -0
  96. /package/lib/{kook-msg-route.js → src/kook-msg-route.js} +0 -0
  97. /package/lib/{types.js → src/types.js} +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kook-side-events.js","sourceRoot":"","sources":["../../src/kook-side-events.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAEL,OAAO,EACP,cAAc,EACd,YAAY,EACZ,WAAW,EACX,aAAa,GACd,MAAM,SAAS,CAAC;AAyBjB,MAAM,mBAAmB,GAAG,GAAG,CAAC;AAEhC,MAAM,UAAU,wBAAwB,CAAC,IAAa;IACpD,IAAI,CAAC,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC;IACpD,MAAM,EAAE,GAAG,IAAwB,CAAC;IACpC,IAAI,EAAE,CAAC,IAAI,KAAK,mBAAmB;QAAE,OAAO,IAAI,CAAC;IACjD,OAAO,EAAE,CAAC,YAAY,KAAK,WAAW,CAAC;AACzC,CAAC;AAED,MAAM,UAAU,6BAA6B,CAC3C,KAAuB,EACvB,IAA0B;IAE1B,IAAI,KAAK,CAAC,MAAM;QAAE,OAAO,GAAG,IAAI,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC;IACnD,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,IAAI,EAAE,CAAC;IAChC,MAAM,UAAU,GAAG,KAAK,CAAC,IAAI,IAAI,MAAM,CAAC,KAAK,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC;IAC1D,MAAM,KAAK,GAAG,KAAK,CAAC,SAAS,IAAI,EAAE,CAAC;IACpC,MAAM,EAAE,GAAG,KAAK,CAAC,aAAa,IAAI,CAAC,CAAC;IACpC,OAAO,GAAG,IAAI,IAAI,EAAE,IAAI,UAAU,IAAI,KAAK,EAAE,CAAC;AAChD,CAAC;AAED,SAAS,UAAU,CAAC,GAAwC,EAAE,GAAW;IACvE,MAAM,CAAC,GAAG,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC;IACrB,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,KAAK,EAAE;QAAE,OAAO,SAAS,CAAC;IAC5C,OAAO,MAAM,CAAC,CAAC,CAAC,CAAC;AACnB,CAAC;AAED,MAAM,UAAU,wBAAwB,CACtC,KAAuB;IAEvB,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,IAAI,EAAE,CAAC;IAChC,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,IAAI,EAAE,CAAC;IAC9B,MAAM,OAAO,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC;IAEzC,IAAI,KAAK,CAAC,YAAY,KAAK,WAAW,EAAE,CAAC;QACvC,MAAM,OAAO,GACX,UAAU,CAAC,IAAI,EAAE,UAAU,CAAC;eACzB,KAAK,CAAC,QAAQ;eACd,KAAK,CAAC,SAAS;eACf,EAAE,CAAC;QACR,OAAO,EAAE,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;IACxC,CAAC;IAED,IAAI,KAAK,CAAC,IAAI,KAAK,mBAAmB,IAAI,KAAK,CAAC,YAAY,KAAK,OAAO,EAAE,CAAC;QACzE,MAAM,OAAO,GACX,UAAU,CAAC,IAAI,EAAE,UAAU,CAAC;eACzB,KAAK,CAAC,QAAQ;eACd,KAAK,CAAC,SAAS;eACf,EAAE,CAAC;QACR,IACE,OAAO,KAAK,cAAc;eACvB,OAAO,KAAK,cAAc;eAC1B,OAAO,KAAK,eAAe;eAC3B,OAAO,KAAK,eAAe;eAC3B,OAAO,CAAC,UAAU,CAAC,YAAY,CAAC;eAChC,OAAO,CAAC,UAAU,CAAC,cAAc,CAAC;eAClC,OAAO,CAAC,UAAU,CAAC,cAAc,CAAC;eAClC,OAAO,CAAC,UAAU,CAAC,aAAa,CAAC;eACjC,OAAO,CAAC,UAAU,CAAC,eAAe,CAAC;eACnC,OAAO,KAAK,mBAAmB;eAC/B,OAAO,KAAK,mBAAmB,EAClC,CAAC;YACD,OAAO,EAAE,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;QACxC,CAAC;QACD,MAAM,SAAS,GACb,UAAU,CAAC,IAAI,EAAE,YAAY,CAAC;eAC3B,KAAK,CAAC,UAAU;eAChB,KAAK,CAAC,SAAS;eACf,EAAE,CAAC;QACR,OAAO,EAAE,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;IAC5C,CAAC;IAED,IACE,OAAO,CAAC,UAAU,CAAC,UAAU,CAAC;WAC3B,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAC;WACnC,KAAK,CAAC,YAAY,KAAK,QAAQ,EAClC,CAAC;QACD,MAAM,MAAM,GACV,UAAU,CAAC,IAAI,EAAE,SAAS,CAAC;eACxB,UAAU,CAAC,IAAI,EAAE,WAAW,CAAC;eAC7B,KAAK,CAAC,SAAS;eACf,KAAK,CAAC,SAAS;eACf,EAAE,CAAC;QACR,OAAO,EAAE,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;IACzC,CAAC;IAED,MAAM,SAAS,GACb,UAAU,CAAC,IAAI,EAAE,YAAY,CAAC;WAC3B,KAAK,CAAC,UAAU;WAChB,KAAK,CAAC,SAAS;WACf,EAAE,CAAC;IACR,OAAO,EAAE,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;AAC5C,CAAC;AAED,MAAM,UAAU,2BAA2B,CAAC,KAAuB;IACjE,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,IAAI,EAAE,CAAC;IAChC,MAAM,UAAU,GAAG,KAAK,CAAC,IAAI,CAAC;IAC9B,IAAI,CAAC,wBAAwB,CAAC,KAAK,CAAC,EAAE,CAAC;QACrC,OAAO,EAAE,GAAI,KAAgB,EAAE,SAAS,EAAE,SAAS,EAAsB,CAAC;IAC5E,CAAC;IACD,OAAO;QACL,GAAI,KAAgB;QACpB,SAAS,EAAE,QAAQ;QACnB,WAAW,EAAE,UAAU,IAAI,QAAQ;KAChB,CAAC;AACxB,CAAC;AAED,MAAM,UAAU,gBAAgB,CAC9B,KAAuB,EACvB,YAAoB;IAEpB,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,IAAI,EAAE,CAAC;IAChC,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,IAAI,EAAE,CAAC;IAC9B,MAAM,OAAO,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,IAAI,SAAS,CAAC,CAAC;IAChD,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,GAAG,cAAc,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjE,MAAM,OAAO,GAAG,wBAAwB,CAAC,KAAK,CAAC,CAAC;IAChD,MAAM,EAAE,GAAG,KAAK,CAAC,aAAa,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC;IAE7C,MAAM,QAAQ,GACZ,UAAU,CAAC,IAAI,EAAE,SAAS,CAAC;WACxB,UAAU,CAAC,IAAI,EAAE,QAAQ,CAAC;WAC1B,UAAU,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;IACnC,MAAM,UAAU,GACd,UAAU,CAAC,IAAI,EAAE,aAAa,CAAC;WAC5B,CAAC,KAAK,CAAC,SAAS,KAAK,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;IAE7D,OAAO,WAAW,CAAC,KAAK,EAAE;QACxB,GAAG,EAAE,6BAA6B,CAAC,KAAK,EAAE,QAAQ,CAAC;QACnD,QAAQ,EAAE,MAAM;QAChB,SAAS,EAAE,YAAY;QACvB,KAAK,EAAE,QAAQ;QACf,SAAS,EAAE,OAAO,CAAC,EAAE;QACrB,WAAW,EAAE,UAAU;QACvB,SAAS,EAAE,QAAQ;QACnB,MAAM,EAAE,YAAY,CAAC,UAAU,CAAC;QAChC,OAAO,EAAE,YAAY,CAAC,QAAQ,CAAC;QAC/B,UAAU,EAAE,EAAE;KACf,CAAC,CAAC;AACL,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,MAA2C;IAC7E,OAAO,aAAa,CAAC;QACnB,MAAM,EAAE,GAAG,MAAM,CAAC,KAAK,IAAI,MAAM,CAAC,WAAW,IAAI,MAAM,CAAC,SAAS,EAAE;QACnE,SAAS,EAAE,MAAM,CAAC,SAAS;QAC3B,KAAK,EAAE,GAAG,MAAM,CAAC,WAAW,IAAI,MAAM,CAAC,SAAS,GAAG;QACnD,QAAQ,EAAE,MAAM,CAAC,SAAS;KAC3B,CAAC,CAAC;AACL,CAAC;AAED,MAAM,UAAU,sBAAsB,CAAC,KAAuB;IAC5D,OAAO,KAAK,CAAC,IAAI,KAAK,mBAAmB,IAAI,KAAK,CAAC,KAAK,EAAE,IAAI,KAAK,mBAAmB,CAAC;AACzF,CAAC;AAED,MAAM,UAAU,4BAA4B,CAC1C,KAAuB,EACvB,YAAoB;IAEpB,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,IAAI,EAAE,CAAC;IAChC,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,IAAI,EAAE,CAAC;IAC9B,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC;IACzC,MAAM,QAAQ,GAAG,IAAI,CAAC,SAA8E,CAAC;IACrG,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,IAAI,QAAQ,EAAE,EAAE,IAAI,KAAK,CAAC,SAAS,IAAI,EAAE,CAAC,CAAC;IAC7E,MAAM,QAAQ,GAAG,QAAQ,EAAE,QAAQ,IAAI,QAAQ,EAAE,QAAQ,IAAI,MAAM,CAAC;IACpE,MAAM,eAAe,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC;IAElD,IAAI,WAAW,GAA0B,SAAS,CAAC;IACnD,IAAI,SAAS,GAAG,MAAM,CAAC,IAAI,CAAC,SAAS,IAAI,KAAK,CAAC,SAAS,IAAI,MAAM,CAAC,CAAC;IACpE,IAAI,IAAI,CAAC,YAAY,KAAK,OAAO,IAAI,KAAK,CAAC,YAAY,KAAK,OAAO,EAAE,CAAC;QACpE,WAAW,GAAG,SAAS,CAAC;QACxB,SAAS,GAAG,MAAM,CAAC,IAAI,CAAC,SAAS,IAAI,KAAK,CAAC,SAAS,IAAI,SAAS,CAAC,CAAC;IACrE,CAAC;SAAM,IAAI,IAAI,CAAC,YAAY,KAAK,QAAQ,IAAI,KAAK,CAAC,YAAY,KAAK,QAAQ,EAAE,CAAC;QAC7E,WAAW,GAAG,SAAS,CAAC;QACxB,SAAS,GAAG,MAAM,CAAC,IAAI,CAAC,SAAS,IAAI,KAAK,CAAC,SAAS,IAAI,MAAM,CAAC,CAAC;IAClE,CAAC;IAED,OAAO,OAAO,CAAC,IAAI,CAAC,KAAK,EAAE;QACzB,GAAG,EAAE,KAAK,CAAC,MAAM,IAAI,OAAO,IAAI,CAAC,GAAG,EAAE,EAAE;QACxC,QAAQ,EAAE,MAAM;QAChB,SAAS,EAAE,YAAY;QACvB,OAAO,EAAE,EAAE,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE;QACvC,QAAQ,EAAE,EAAE,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,WAAW,EAAE;QAC9C,QAAQ,EAAE,CAAC;gBACT,IAAI,EAAE,QAAQ;gBACd,IAAI,EAAE;oBACJ,EAAE,EAAE,OAAO;oBACX,OAAO;oBACP,eAAe;iBAChB;aACF,CAAC;QACF,IAAI,EAAE,OAAO;QACb,UAAU,EAAE,KAAK,CAAC,aAAa,IAAI,IAAI,CAAC,GAAG,EAAE;QAC7C,OAAO,EAAE,KAAK,IAAI,EAAE,GAAE,CAAC;QACvB,MAAM,EAAE,KAAK,IAAI,EAAE,CAAC,EAAE;KACvB,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,66 @@
1
+ /**
2
+ * core keyboard 段 → KOOK 卡片消息(action-group + button)
3
+ */
4
+ import { KeyboardSegment, isKeyboardSegment } from 'zhin.js';
5
+ function asKeyboardElement(el) {
6
+ if (el instanceof KeyboardSegment) {
7
+ return { type: "keyboard", data: el.data };
8
+ }
9
+ if (isKeyboardSegment(el))
10
+ return el;
11
+ return null;
12
+ }
13
+ function textFromElements(elements) {
14
+ return elements
15
+ .filter((el) => el.type === "text" && typeof el.data.text === "string")
16
+ .map((el) => el.data.text)
17
+ .join("\n")
18
+ .trim();
19
+ }
20
+ /** core keyboard 布局 → KOOK card[](可直接传给 sendChannelMsg / sendPrivateMsg) */
21
+ export function coreKeyboardToKookCard(data, prefixElements = []) {
22
+ const modules = [];
23
+ const prefixText = textFromElements(prefixElements);
24
+ if (prefixText) {
25
+ modules.push({
26
+ type: "section",
27
+ text: { type: "plain-text", content: prefixText },
28
+ });
29
+ }
30
+ for (const row of data.rows ?? []) {
31
+ modules.push({
32
+ type: "action-group",
33
+ elements: row.map((btn) => ({
34
+ type: "button",
35
+ theme: btn.disabled ? "secondary" : "primary",
36
+ value: btn.payload,
37
+ click: "return-val",
38
+ text: { type: "plain-text", content: btn.label },
39
+ })),
40
+ });
41
+ }
42
+ return [{
43
+ type: "card",
44
+ theme: "secondary",
45
+ size: "sm",
46
+ modules,
47
+ }];
48
+ }
49
+ export function findKeyboardSegment(elements) {
50
+ let keyboard;
51
+ const rest = [];
52
+ for (const el of elements) {
53
+ const kb = asKeyboardElement(el);
54
+ if (kb) {
55
+ if (keyboard)
56
+ return null;
57
+ keyboard = kb;
58
+ continue;
59
+ }
60
+ rest.push(el);
61
+ }
62
+ if (!keyboard)
63
+ return null;
64
+ return { keyboard, rest };
65
+ }
66
+ //# sourceMappingURL=outbound-keyboard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"outbound-keyboard.js","sourceRoot":"","sources":["../../src/outbound-keyboard.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAAE,eAAe,EAAE,iBAAiB,EAAiD,MAAM,SAAS,CAAC;AAE5G,SAAS,iBAAiB,CACxB,EAAkB;IAElB,IAAI,EAAE,YAAY,eAAe,EAAE,CAAC;QAClC,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,EAAE,CAAC,IAAI,EAAE,CAAC;IAC7C,CAAC;IACD,IAAI,iBAAiB,CAAC,EAAE,CAAC;QAAE,OAAO,EAAE,CAAC;IACrC,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,gBAAgB,CAAC,QAA0B;IAClD,OAAO,QAAQ;SACZ,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,IAAI,KAAK,MAAM,IAAI,OAAO,EAAE,CAAC,IAAI,CAAC,IAAI,KAAK,QAAQ,CAAC;SACtE,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,IAAc,CAAC;SACnC,IAAI,CAAC,IAAI,CAAC;SACV,IAAI,EAAE,CAAC;AACZ,CAAC;AAED,4EAA4E;AAC5E,MAAM,UAAU,sBAAsB,CACpC,IAAyB,EACzB,iBAAmC,EAAE;IAErC,MAAM,OAAO,GAAmC,EAAE,CAAC;IACnD,MAAM,UAAU,GAAG,gBAAgB,CAAC,cAAc,CAAC,CAAC;IACpD,IAAI,UAAU,EAAE,CAAC;QACf,OAAO,CAAC,IAAI,CAAC;YACX,IAAI,EAAE,SAAS;YACf,IAAI,EAAE,EAAE,IAAI,EAAE,YAAY,EAAE,OAAO,EAAE,UAAU,EAAE;SAClD,CAAC,CAAC;IACL,CAAC;IAED,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,IAAI,IAAI,EAAE,EAAE,CAAC;QAClC,OAAO,CAAC,IAAI,CAAC;YACX,IAAI,EAAE,cAAc;YACpB,QAAQ,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;gBAC1B,IAAI,EAAE,QAAQ;gBACd,KAAK,EAAE,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,SAAS;gBAC7C,KAAK,EAAE,GAAG,CAAC,OAAO;gBAClB,KAAK,EAAE,YAAY;gBACnB,IAAI,EAAE,EAAE,IAAI,EAAE,YAAY,EAAE,OAAO,EAAE,GAAG,CAAC,KAAK,EAAE;aACjD,CAAC,CAAC;SACJ,CAAC,CAAC;IACL,CAAC;IAED,OAAO,CAAC;YACN,IAAI,EAAE,MAAM;YACZ,KAAK,EAAE,WAAW;YAClB,IAAI,EAAE,IAAI;YACV,OAAO;SACR,CAAC,CAAC;AACL,CAAC;AAED,MAAM,UAAU,mBAAmB,CACjC,QAA0B;IAE1B,IAAI,QAAsE,CAAC;IAC3E,MAAM,IAAI,GAAqB,EAAE,CAAC;IAElC,KAAK,MAAM,EAAE,IAAI,QAAQ,EAAE,CAAC;QAC1B,MAAM,EAAE,GAAG,iBAAiB,CAAC,EAAE,CAAC,CAAC;QACjC,IAAI,EAAE,EAAE,CAAC;YACP,IAAI,QAAQ;gBAAE,OAAO,IAAI,CAAC;YAC1B,QAAQ,GAAG,EAAE,CAAC;YACd,SAAS;QACX,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAChB,CAAC;IAED,IAAI,CAAC,QAAQ;QAAE,OAAO,IAAI,CAAC;IAC3B,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;AAC5B,CAAC"}
@@ -1,4 +1,7 @@
1
- import { asMessageElements, extractBase64Buffer, isMediaSegmentType, isRemoteUrl, resolveLocalMediaPath, } from "zhin.js";
1
+ /**
2
+ * KOOK 出站 media:base64 / 本地文件须先走 /v3/asset/create 上传,再嵌入 KMarkdown。
3
+ */
4
+ import { asMessageElements, extractBase64Buffer, isMediaSegmentType, isRemoteUrl, resolveLocalMediaPath } from 'zhin.js';
2
5
  function isMessageSegment(seg) {
3
6
  return typeof seg.type === "string";
4
7
  }
@@ -0,0 +1 @@
1
+ {"version":3,"file":"outbound-media.js","sourceRoot":"","sources":["../../src/outbound-media.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,WAAW,EAAE,qBAAqB,EAA8D,MAAM,SAAS,CAAC;AAMrL,SAAS,gBAAgB,CAAC,GAAmB;IAC3C,OAAO,OAAO,GAAG,CAAC,IAAI,KAAK,QAAQ,CAAC;AACtC,CAAC;AAED,SAAS,eAAe,CAAC,GAAmB,EAAE,WAAmB;IAC/D,MAAM,IAAI,GAAG,EAAE,GAAG,GAAG,CAAC,IAAI,EAA6B,CAAC;IACxD,IAAI,CAAC,GAAG,GAAG,WAAW,CAAC;IACvB,IAAI,CAAC,IAAI,GAAG,WAAW,CAAC;IACxB,OAAO,IAAI,CAAC,MAAM,CAAC;IACnB,OAAO,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,IAAI,EAAoB,CAAC;AACpD,CAAC;AAED,KAAK,UAAU,mBAAmB,CAChC,QAA2B,EAC3B,GAAmB;IAEnB,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,IAAI,CAAC;QAAE,OAAO,GAAG,CAAC;IAE9C,MAAM,IAAI,GAAG,GAAG,CAAC,IAA+B,CAAC;IACjD,MAAM,GAAG,GAAG,OAAO,IAAI,CAAC,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC;IAChE,MAAM,IAAI,GAAG,OAAO,IAAI,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC;IACnE,IAAI,CAAC,GAAG,IAAI,WAAW,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,IAAI,WAAW,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC;QAC7D,OAAO,GAAG,CAAC;IACb,CAAC;IAED,MAAM,MAAM,GAAG,mBAAmB,CAAC,IAAI,CAAC,CAAC;IACzC,IAAI,MAAM,EAAE,CAAC;QACX,MAAM,QAAQ,GAAG,MAAM,QAAQ,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;QACpD,OAAO,eAAe,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;IACxC,CAAC;IAED,MAAM,KAAK,GAAG,qBAAqB,CAAC,IAAI,CAAC,CAAC;IAC1C,IAAI,KAAK,EAAE,CAAC;QACV,MAAM,QAAQ,GAAG,MAAM,QAAQ,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;QACnD,OAAO,eAAe,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;IACxC,CAAC;IAED,OAAO,GAAG,CAAC;AACb,CAAC;AAED,sCAAsC;AACtC,MAAM,CAAC,KAAK,UAAU,wBAAwB,CAC5C,QAA2B,EAC3B,OAAoB;IAEpB,MAAM,QAAQ,GAAG,iBAAiB,CAAC,OAAO,CAAC,CAAC;IAC5C,OAAO,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE;QAC7C,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC;YAAE,OAAO,IAAI,CAAC;QACzC,OAAO,mBAAmB,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;IAC7C,CAAC,CAAC,CAAC,CAAC;AACN,CAAC"}
@@ -3,6 +3,7 @@
3
3
  * 图片/音视频须用 segment 发送对应 msg_type,不能写成 Markdown ![alt](url)。
4
4
  */
5
5
  import { segment } from "kook-client";
6
+ import { coreKeyboardToKookCard, findKeyboardSegment } from "./outbound-keyboard.js";
6
7
  function mediaUrl(data) {
7
8
  return String(data.url ?? data.file ?? "");
8
9
  }
@@ -10,6 +11,14 @@ function mediaUrl(data) {
10
11
  * 单张图片(可带 reply)→ kook image 消息段(type=2)
11
12
  */
12
13
  export function convertToKookSendable(elements, formatText) {
14
+ const keyboardBundle = findKeyboardSegment(elements);
15
+ if (keyboardBundle) {
16
+ const { keyboard, rest } = keyboardBundle;
17
+ const nonReplyRest = rest.filter((el) => el.type !== "reply");
18
+ if (nonReplyRest.every((el) => el.type === "text" || el.type === "reply")) {
19
+ return coreKeyboardToKookCard(keyboard.data, nonReplyRest.filter((el) => el.type === "text"));
20
+ }
21
+ }
13
22
  const replies = [];
14
23
  const images = [];
15
24
  const videos = [];
@@ -0,0 +1 @@
1
+ {"version":3,"file":"outbound-sendable.js","sourceRoot":"","sources":["../../src/outbound-sendable.ts"],"names":[],"mappings":"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"}
@@ -1,3 +1,6 @@
1
+ /**
2
+ * KOOK platform permit — guild / channel 差异化门禁
3
+ */
1
4
  import { registerPlatformPermitChecker } from 'zhin.js';
2
5
  import { KookPermission } from './types.js';
3
6
  const ADAPTER = 'kook';
@@ -5,8 +8,8 @@ export function platformPermit(perm) {
5
8
  return `platform(${ADAPTER},${perm})`;
6
9
  }
7
10
  const FACTORY_PERM_MAP = {
8
- group_admin: 'guild_admin',
9
- group_owner: 'guild_owner',
11
+ scene_admin: 'guild_admin',
12
+ scene_owner: 'guild_owner',
10
13
  };
11
14
  export function kookGroupPermitResolver(logicalPerm) {
12
15
  return platformPermit(FACTORY_PERM_MAP[logicalPerm] ?? logicalPerm);
@@ -0,0 +1 @@
1
+ {"version":3,"file":"platform-permit.js","sourceRoot":"","sources":["../../src/platform-permit.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export { toCanonicalSegments, fromCanonicalSegments } from 'zhin.js';
2
+ //# sourceMappingURL=segment-mapper.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"segment-mapper.js","sourceRoot":"","sources":["../../src/segment-mapper.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,qBAAqB,EAAE,MAAM,SAAS,CAAC"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"AAOA,MAAM,CAAN,IAAY,cAKX;AALD,WAAY,cAAc;IACxB,uDAAU,CAAA;IACV,qDAAS,CAAA;IACT,qDAAS,CAAA;IACT,mEAAgB,CAAA;AAClB,CAAC,EALW,cAAc,KAAd,cAAc,QAKzB"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zhin.js/adapter-kook",
3
- "version": "5.0.0",
3
+ "version": "5.0.2",
4
4
  "description": "Zhin.js adapter for KOOK (开黑啦)",
5
5
  "type": "module",
6
6
  "main": "./lib/index.js",
@@ -38,25 +38,32 @@
38
38
  "devDependencies": {
39
39
  "@types/react": "^19.2.17",
40
40
  "@types/react-dom": "^19.2.3",
41
- "lucide-react": "^1.21.0",
41
+ "lucide-react": "^1.22.0",
42
42
  "typescript": "^6.0.3",
43
- "@zhin.js/cli": "1.0.91",
44
- "@zhin.js/client": "2.0.3",
45
- "@zhin.js/contract": "1.0.1",
46
- "@zhin.js/host-api": "2.0.3",
47
- "@zhin.js/host-router": "2.0.1",
48
- "@zhin.js/logger": "1.0.72",
49
- "zhin.js": "4.1.0"
43
+ "zod": "^4.4.3",
44
+ "@zhin.js/cli": "1.0.93",
45
+ "@zhin.js/client": "2.0.5",
46
+ "@zhin.js/contract": "1.0.3",
47
+ "@zhin.js/host-api": "2.0.5",
48
+ "@zhin.js/host-router": "2.0.3",
49
+ "@zhin.js/logger": "1.0.74",
50
+ "zhin.js": "4.1.2",
51
+ "@zhin.js/agent": "1.0.3"
50
52
  },
51
53
  "peerDependencies": {
52
- "@zhin.js/host-api": "2.0.3",
53
- "@zhin.js/contract": "1.0.1",
54
- "@zhin.js/client": "2.0.3",
55
- "@zhin.js/logger": "1.0.72",
56
- "@zhin.js/host-router": "2.0.1",
57
- "zhin.js": "4.1.0"
54
+ "zod": "^4.0.0",
55
+ "@zhin.js/client": "2.0.5",
56
+ "@zhin.js/host-api": "2.0.5",
57
+ "@zhin.js/contract": "1.0.3",
58
+ "@zhin.js/host-router": "2.0.3",
59
+ "@zhin.js/logger": "1.0.74",
60
+ "zhin.js": "4.1.2",
61
+ "@zhin.js/agent": "1.0.3"
58
62
  },
59
63
  "peerDependenciesMeta": {
64
+ "@zhin.js/agent": {
65
+ "optional": true
66
+ },
60
67
  "@zhin.js/client": {
61
68
  "optional": true
62
69
  },
@@ -65,6 +72,9 @@
65
72
  },
66
73
  "@zhin.js/host-api": {
67
74
  "optional": true
75
+ },
76
+ "zod": {
77
+ "optional": true
68
78
  }
69
79
  },
70
80
  "files": [
@@ -72,7 +82,7 @@
72
82
  "lib",
73
83
  "client",
74
84
  "dist",
75
- "skills",
85
+ "agent",
76
86
  "plugin.yml",
77
87
  "README.md",
78
88
  "node",
package/src/adapter.ts CHANGED
@@ -1,10 +1,9 @@
1
1
  /**
2
2
  * KOOK 适配器
3
3
  */
4
- import { formatCompact, Adapter, Plugin } from 'zhin.js';
4
+ import { formatCompact, Adapter, Plugin, type OutboundRichSegmentPolicy } from 'zhin.js';
5
5
  import { KookEndpoint } from "./endpoint.js";
6
6
  import type { KookEndpointConfig } from "./types.js";
7
- import type { OutboundRichSegmentPolicy } from "zhin.js";
8
7
 
9
8
  export class KookAdapter extends Adapter<KookEndpoint> {
10
9
  static override readonly capabilities = ['inbound', 'outbound'] as const;
@@ -13,6 +12,7 @@ export class KookAdapter extends Adapter<KookEndpoint> {
13
12
  html: 'image',
14
13
  markdown: 'origin',
15
14
  };
15
+ static override interactivePolicy = 'native' as const;
16
16
 
17
17
  constructor(plugin: Plugin) {
18
18
  super(plugin, "kook", []);
@@ -22,9 +22,9 @@ export class KookAdapter extends Adapter<KookEndpoint> {
22
22
  return new KookEndpoint(this, config);
23
23
  }
24
24
 
25
- // ── IGroupManagement 标准群管方法 ──────────────────────────────────
25
+ // ── ISceneManagement 标准群管方法 ──────────────────────────────────
26
26
 
27
- async kickMember(endpointId: string, sceneId: string, userId: string) {
27
+ async removeMember(endpointId: string, sceneId: string, userId: string) {
28
28
  const endpoint = this.endpoints.get(endpointId);
29
29
  if (!endpoint) throw new Error(`Endpoint ${endpointId} 不存在`);
30
30
  return endpoint.kickUser(sceneId, userId);
@@ -69,7 +69,7 @@ export class KookAdapter extends Adapter<KookEndpoint> {
69
69
 
70
70
  async stop(): Promise<void> {
71
71
  await super.stop();
72
- this.plugin.logger.info(formatCompact( { op: "stop" }));
72
+ this.plugin.logger.debug(formatCompact( { op: "stop" }));
73
73
  }
74
74
  }
75
75
 
package/src/endpoint.ts CHANGED
@@ -20,9 +20,10 @@ import {
20
20
  SendContent,
21
21
  MessageElement,
22
22
  segment,
23
+ expandInteractiveSegmentsInContent,
23
24
  MessageType,} from 'zhin.js';
24
- import type { KookEndpointConfig, KookSenderInfo, KookRawMessage } from "./types.js";
25
- import { KookPermission } from "./types.js";
25
+ import { KookPermission, type KookEndpointConfig, type KookSenderInfo, type KookRawMessage } from './types.js';
26
+
26
27
  import type { KookAdapter } from "./adapter.js";
27
28
  import { InboundMessageDeduper } from "./kook-inbound.js";
28
29
  import { normalizeKookSenderForPermit } from "./platform-permit.js";
@@ -30,6 +31,8 @@ import {
30
31
  enrichKookGatewayForPlugins,
31
32
  formatKookNotice,
32
33
  formatKookNoticeLog,
34
+ formatKookButtonClickMessage,
35
+ isKookButtonClickEvent,
33
36
  isKookNoticeGatewayEvent,
34
37
  resolveKookSideEventDedupeKey,
35
38
  type KookGatewayEvent,
@@ -54,6 +57,7 @@ import {
54
57
  import { materializeOutboundMedia } from "./outbound-media.js";
55
58
  import { uploadKookAsset } from "./kook-asset-upload.js";
56
59
  import { convertToKookSendable } from "./outbound-sendable.js";
60
+ import { fromCanonicalSegments, toCanonicalSegments } from './segment-mapper.js';
57
61
 
58
62
  export class KookEndpoint extends Client implements Endpoint<KookEndpointConfig, KookRawMessage> {
59
63
  $connected: boolean = false;
@@ -110,6 +114,17 @@ export class KookEndpoint extends Client implements Endpoint<KookEndpointConfig,
110
114
  const enriched = enrichKookGatewayForPlugins(raw);
111
115
  EventEmitter.prototype.emit.call(this.adapter, "kook.gateway", enriched);
112
116
 
117
+ if (isKookButtonClickEvent(raw)) {
118
+ const dedupeKey = resolveKookSideEventDedupeKey(raw, "gateway");
119
+ if (!this.inboundDeduper.shouldProcess(dedupeKey)) return;
120
+ const message = formatKookButtonClickMessage(raw, this.$id);
121
+ this.adapter.emit("message.receive", message);
122
+ this.pluginLogger.debug(
123
+ `KOOK 按钮点击 ${message.$channel.type}(${message.$channel.id}): ${message.$raw}`,
124
+ );
125
+ return;
126
+ }
127
+
113
128
  if (!isKookNoticeGatewayEvent(raw)) return;
114
129
 
115
130
  const dedupeKey = resolveKookSideEventDedupeKey(raw, "notice");
@@ -221,7 +236,7 @@ export class KookEndpoint extends Client implements Endpoint<KookEndpointConfig,
221
236
  ...(guildId ? { guild_id: guildId } : {}),
222
237
  },
223
238
 
224
- $content: this.parseMessageContent(msg.message),
239
+ $content: toCanonicalSegments(this.parseMessageContent(msg.message)),
225
240
  $raw: msg.raw_message,
226
241
  $timestamp: msg.timestamp,
227
242
 
@@ -493,73 +508,17 @@ export class KookEndpoint extends Client implements Endpoint<KookEndpointConfig,
493
508
 
494
509
  private parseMarkdown(content: string): MessageElement[] {
495
510
  const elements: MessageElement[] = [];
496
-
497
- // KMarkdown 图片格式: ![alt](url)
498
- const imageRegex = /!\[([^\]]*)\]\(([^)]+)\)/g;
499
- // KMarkdown @提及格式: (met)userId(met) 或 @用户名
500
- const mentionRegex = /\(met\)(\d+)\(met\)|@([^\s]+)/g;
501
- // KMarkdown 表情格式: (emj)表情名(emj)[表情ID]
502
- const emojiRegex = /\(emj\)([^(]+)\(emj\)\[([^\]]+)\]/g;
503
- // KMarkdown 频道格式: (chn)channelId(chn)
504
- const channelRegex = /\(chn\)(\d+)\(chn\)/g;
505
-
506
511
  let lastIndex = 0;
507
- const matches: Array<{ index: number; length: number; element: MessageElement }> = [];
508
-
509
- // 解析图片
510
- let match: RegExpExecArray | null;
511
- while ((match = imageRegex.exec(content)) !== null) {
512
- matches.push({
513
- index: match.index,
514
- length: match[0].length,
515
- element: { type: "image", data: { url: match[2], alt: match[1] } }
516
- });
517
- }
518
-
519
- // 解析 @提及
520
- while ((match = mentionRegex.exec(content)) !== null) {
521
- const userId = match[1] || match[2];
522
- matches.push({
523
- index: match.index,
524
- length: match[0].length,
525
- element: this.buildAtElement(userId),
526
- });
527
- }
528
-
529
- // 解析表情
530
- while ((match = emojiRegex.exec(content)) !== null) {
531
- matches.push({
532
- index: match.index,
533
- length: match[0].length,
534
- element: { type: "face", data: { id: match[2], name: match[1] } }
535
- });
536
- }
537
-
538
- // 解析频道引用
539
- while ((match = channelRegex.exec(content)) !== null) {
540
- matches.push({
541
- index: match.index,
542
- length: match[0].length,
543
- element: { type: "text", data: { text: `#频道:${match[1]}` } }
544
- });
545
- }
546
-
547
- // 按位置排序
548
- matches.sort((a, b) => a.index - b.index);
549
-
550
- // 组装消息段
551
- for (const match of matches) {
552
- // 添加之前的文本
553
- if (match.index > lastIndex) {
554
- const text = content.slice(lastIndex, match.index);
512
+ for (const token of this.scanKMarkdownTokens(content)) {
513
+ if (token.index > lastIndex) {
514
+ const text = content.slice(lastIndex, token.index);
555
515
  if (text) {
556
516
  elements.push({ type: "text", data: { text } });
557
517
  }
558
518
  }
559
519
 
560
- // 添加特殊元素
561
- elements.push(match.element);
562
- lastIndex = match.index + match.length;
520
+ elements.push(token.element);
521
+ lastIndex = token.index + token.length;
563
522
  }
564
523
 
565
524
  // 添加剩余文本
@@ -646,7 +605,76 @@ export class KookEndpoint extends Client implements Endpoint<KookEndpointConfig,
646
605
  * 检查文本是否包含 KMarkdown 特殊语法
647
606
  */
648
607
  private hasKMarkdownSyntax(text: string): boolean {
649
- return /!\[.*?\]\(.*?\)|\(met\)|\(emj\)|\(chn\)|@\S+/.test(text);
608
+ return text.includes('![')
609
+ || text.includes('(met)')
610
+ || text.includes('(emj)')
611
+ || text.includes('(chn)')
612
+ || text.includes('@');
613
+ }
614
+
615
+ private scanKMarkdownTokens(content: string): Array<{ index: number; length: number; element: MessageElement }> {
616
+ const tokens: Array<{ index: number; length: number; element: MessageElement }> = [];
617
+ let i = 0;
618
+ while (i < content.length) {
619
+ const token = this.readKMarkdownToken(content, i);
620
+ if (token) {
621
+ tokens.push(token);
622
+ i = token.index + token.length;
623
+ } else {
624
+ i++;
625
+ }
626
+ }
627
+ return tokens;
628
+ }
629
+
630
+ private readKMarkdownToken(content: string, index: number): { index: number; length: number; element: MessageElement } | null {
631
+ if (content.startsWith('![', index)) {
632
+ const labelEnd = content.indexOf(']', index + 2);
633
+ if (labelEnd >= 0 && content[labelEnd + 1] === '(') {
634
+ const urlEnd = content.indexOf(')', labelEnd + 2);
635
+ if (urlEnd >= 0) {
636
+ return {
637
+ index,
638
+ length: urlEnd + 1 - index,
639
+ element: { type: "image", data: { url: content.slice(labelEnd + 2, urlEnd), alt: content.slice(index + 2, labelEnd) } },
640
+ };
641
+ }
642
+ }
643
+ }
644
+ if (content.startsWith('(met)', index)) {
645
+ const idStart = index + '(met)'.length;
646
+ const idEnd = content.indexOf('(met)', idStart);
647
+ if (idEnd > idStart) {
648
+ return { index, length: idEnd + '(met)'.length - index, element: this.buildAtElement(content.slice(idStart, idEnd)) };
649
+ }
650
+ }
651
+ if (content[index] === '@') {
652
+ let end = index + 1;
653
+ while (end < content.length && !/\s/.test(content[end]!)) end++;
654
+ if (end > index + 1) {
655
+ return { index, length: end - index, element: this.buildAtElement(content.slice(index + 1, end)) };
656
+ }
657
+ }
658
+ if (content.startsWith('(emj)', index)) {
659
+ const nameStart = index + '(emj)'.length;
660
+ const nameEnd = content.indexOf('(emj)[', nameStart);
661
+ const idEnd = nameEnd >= 0 ? content.indexOf(']', nameEnd + 6) : -1;
662
+ if (nameEnd > nameStart && idEnd > nameEnd) {
663
+ return {
664
+ index,
665
+ length: idEnd + 1 - index,
666
+ element: { type: "face", data: { id: content.slice(nameEnd + 6, idEnd), name: content.slice(nameStart, nameEnd) } },
667
+ };
668
+ }
669
+ }
670
+ if (content.startsWith('(chn)', index)) {
671
+ const idStart = index + '(chn)'.length;
672
+ const idEnd = content.indexOf('(chn)', idStart);
673
+ if (idEnd > idStart) {
674
+ return { index, length: idEnd + '(chn)'.length - index, element: { type: "text", data: { text: `#频道:${content.slice(idStart, idEnd)}` } } };
675
+ }
676
+ }
677
+ return null;
650
678
  }
651
679
 
652
680
  /**
@@ -707,7 +735,10 @@ export class KookEndpoint extends Client implements Endpoint<KookEndpointConfig,
707
735
  try {
708
736
  const { id, type, content } = options;
709
737
 
710
- const elements = await materializeOutboundMedia(this, content);
738
+ const expanded = expandInteractiveSegmentsInContent(content);
739
+ const canonical = toCanonicalSegments(Array.isArray(expanded) ? expanded : [expanded]);
740
+ const wire = fromCanonicalSegments(canonical);
741
+ const elements = await materializeOutboundMedia(this, wire);
711
742
  const kookContent = convertToKookSendable(
712
743
  elements,
713
744
  (els) => this.convertToKookFormat(els),