@zaofan/dsh-qqbot 1.0.1 → 1.1.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 (105) hide show
  1. package/README.md +6 -0
  2. package/client/qqbot-settings.js +667 -54
  3. package/dist/api/group-admin.d.ts +37 -0
  4. package/dist/api/group-admin.d.ts.map +1 -1
  5. package/dist/api/group-admin.js +57 -0
  6. package/dist/api/group-admin.js.map +1 -1
  7. package/dist/channel-tools.d.ts.map +1 -1
  8. package/dist/channel-tools.js +373 -25
  9. package/dist/channel-tools.js.map +1 -1
  10. package/dist/commands/botplay.d.ts.map +1 -1
  11. package/dist/commands/botplay.js +6 -2
  12. package/dist/commands/botplay.js.map +1 -1
  13. package/dist/commands/index.d.ts.map +1 -1
  14. package/dist/commands/index.js +6 -2
  15. package/dist/commands/index.js.map +1 -1
  16. package/dist/commands/inject.d.ts +17 -0
  17. package/dist/commands/inject.d.ts.map +1 -0
  18. package/dist/commands/inject.js +70 -0
  19. package/dist/commands/inject.js.map +1 -0
  20. package/dist/commands/misc.d.ts +1 -1
  21. package/dist/commands/misc.d.ts.map +1 -1
  22. package/dist/commands/misc.js +25 -3
  23. package/dist/commands/misc.js.map +1 -1
  24. package/dist/commands/session.d.ts +2 -0
  25. package/dist/commands/session.d.ts.map +1 -1
  26. package/dist/commands/session.js +41 -3
  27. package/dist/commands/session.js.map +1 -1
  28. package/dist/config.d.ts +25 -0
  29. package/dist/config.d.ts.map +1 -1
  30. package/dist/config.js +18 -1
  31. package/dist/config.js.map +1 -1
  32. package/dist/features/botplay-store.d.ts +13 -0
  33. package/dist/features/botplay-store.d.ts.map +1 -0
  34. package/dist/features/botplay-store.js +99 -0
  35. package/dist/features/botplay-store.js.map +1 -0
  36. package/dist/features/botplay.d.ts +8 -0
  37. package/dist/features/botplay.d.ts.map +1 -1
  38. package/dist/features/botplay.js +22 -7
  39. package/dist/features/botplay.js.map +1 -1
  40. package/dist/features/broadcast.d.ts +63 -0
  41. package/dist/features/broadcast.d.ts.map +1 -0
  42. package/dist/features/broadcast.js +225 -0
  43. package/dist/features/broadcast.js.map +1 -0
  44. package/dist/features/card-callback.d.ts +52 -0
  45. package/dist/features/card-callback.d.ts.map +1 -0
  46. package/dist/features/card-callback.js +133 -0
  47. package/dist/features/card-callback.js.map +1 -0
  48. package/dist/features/group-hub.d.ts +14 -0
  49. package/dist/features/group-hub.d.ts.map +1 -1
  50. package/dist/features/group-hub.js +87 -4
  51. package/dist/features/group-hub.js.map +1 -1
  52. package/dist/features/group-join-request.d.ts.map +1 -1
  53. package/dist/features/group-join-request.js +9 -2
  54. package/dist/features/group-join-request.js.map +1 -1
  55. package/dist/features/poll-join-requests.d.ts +9 -0
  56. package/dist/features/poll-join-requests.d.ts.map +1 -0
  57. package/dist/features/poll-join-requests.js +249 -0
  58. package/dist/features/poll-join-requests.js.map +1 -0
  59. package/dist/features/preset-switcher.d.ts +39 -0
  60. package/dist/features/preset-switcher.d.ts.map +1 -0
  61. package/dist/features/preset-switcher.js +172 -0
  62. package/dist/features/preset-switcher.js.map +1 -0
  63. package/dist/features/session-registry.d.ts +6 -0
  64. package/dist/features/session-registry.d.ts.map +1 -1
  65. package/dist/features/session-registry.js +80 -0
  66. package/dist/features/session-registry.js.map +1 -1
  67. package/dist/gateway/bootstrap.d.ts.map +1 -1
  68. package/dist/gateway/bootstrap.js +74 -4
  69. package/dist/gateway/bootstrap.js.map +1 -1
  70. package/dist/gateway/debounce.d.ts.map +1 -1
  71. package/dist/gateway/debounce.js +7 -0
  72. package/dist/gateway/debounce.js.map +1 -1
  73. package/dist/index.d.ts.map +1 -1
  74. package/dist/index.js +24 -5
  75. package/dist/index.js.map +1 -1
  76. package/dist/middleware/media-history.d.ts.map +1 -1
  77. package/dist/middleware/media-history.js +23 -6
  78. package/dist/middleware/media-history.js.map +1 -1
  79. package/dist/model/settings-reader.d.ts +7 -0
  80. package/dist/model/settings-reader.d.ts.map +1 -1
  81. package/dist/model/settings-reader.js +14 -0
  82. package/dist/model/settings-reader.js.map +1 -1
  83. package/dist/session/session-manager.d.ts +26 -0
  84. package/dist/session/session-manager.d.ts.map +1 -1
  85. package/dist/session/session-manager.js +101 -0
  86. package/dist/session/session-manager.js.map +1 -1
  87. package/dist/transport/inbound.d.ts.map +1 -1
  88. package/dist/transport/inbound.js +46 -50
  89. package/dist/transport/inbound.js.map +1 -1
  90. package/dist/transport/inject-rules.d.ts.map +1 -1
  91. package/dist/transport/inject-rules.js +8 -2
  92. package/dist/transport/inject-rules.js.map +1 -1
  93. package/dist/transport/media-kind.d.ts +37 -0
  94. package/dist/transport/media-kind.d.ts.map +1 -0
  95. package/dist/transport/media-kind.js +60 -0
  96. package/dist/transport/media-kind.js.map +1 -0
  97. package/dist/transport/outbound-buffer.d.ts +20 -2
  98. package/dist/transport/outbound-buffer.d.ts.map +1 -1
  99. package/dist/transport/outbound-buffer.js +25 -5
  100. package/dist/transport/outbound-buffer.js.map +1 -1
  101. package/dist/transport/outbound.d.ts.map +1 -1
  102. package/dist/transport/outbound.js +68 -4
  103. package/dist/transport/outbound.js.map +1 -1
  104. package/package.json +1 -1
  105. package/settings-host.js +406 -21
@@ -0,0 +1,225 @@
1
+ /**
2
+ * broadcast.ts — 群发任务队列(M3, 2026-09-10 新增, 设计见 参考文档/群组管理_设计稿_20260909.md §3.3)
3
+ *
4
+ * 群发不是即时操作, 是持久化任务状态机:
5
+ * draft → queued → sending → partial_failed → done / cancelled
6
+ * - 逐目标推进(串行), 单个失败进重试桶(指数退避, 上限 3), 可中止;
7
+ * - 已发消息记录 message_id, 2 分钟内可撤回(官方撤回窗口);
8
+ * - 文件: {dataDir}/.qqbot/broadcast-tasks.json(与 join-pending 同目录)。
9
+ *
10
+ * ⚠️ 本地手改功能: 同步纪律同 group-admin(改完保持 src 与部署 dist 一致)。
11
+ */
12
+ import { readFileSync, writeFileSync, mkdirSync, existsSync, renameSync } from 'node:fs';
13
+ import { join } from 'node:path';
14
+ const TASK_TTL_MS = 7 * 24 * 3600 * 1000; // 任务记录保留 7 天(清理用)
15
+ const MAX_RETRIES = 3;
16
+ const RETRY_BASE_MS = 2_000; // 指数退避基数
17
+ function tasksPath(dataRoot) {
18
+ return join(dataRoot, '.qqbot', 'broadcast-tasks.json');
19
+ }
20
+ function emptyStore() {
21
+ return { tasks: [] };
22
+ }
23
+ function loadStore(dataRoot) {
24
+ try {
25
+ const raw = readFileSync(tasksPath(dataRoot), 'utf8');
26
+ const o = JSON.parse(raw);
27
+ if (o && Array.isArray(o.tasks))
28
+ return o;
29
+ return emptyStore();
30
+ }
31
+ catch {
32
+ return emptyStore();
33
+ }
34
+ }
35
+ function saveStore(dataRoot, store) {
36
+ try {
37
+ const dir = join(dataRoot, '.qqbot');
38
+ if (!existsSync(dir))
39
+ mkdirSync(dir, { recursive: true });
40
+ const file = tasksPath(dataRoot);
41
+ const tmp = file + '.tmp-' + Date.now();
42
+ writeFileSync(tmp, JSON.stringify(store, null, 2), 'utf8');
43
+ renameSync(tmp, file);
44
+ }
45
+ catch { /* 落盘失败不影响主链 */ }
46
+ }
47
+ /** 清理过期任务(保留 7 天; 每次 list 时顺手做) */
48
+ function prune(store, now = Date.now()) {
49
+ if (store.tasks.length <= 50)
50
+ return; // 任务少时无所谓
51
+ const before = store.tasks.length;
52
+ store.tasks = store.tasks.filter((t) => now - (t.done_at ?? t.created_at) < TASK_TTL_MS);
53
+ if (store.tasks.length !== before)
54
+ store.tasks.sort((a, b) => b.created_at - a.created_at);
55
+ }
56
+ export function createTask(dataRoot, input) {
57
+ const store = loadStore(dataRoot);
58
+ const task = {
59
+ task_id: 'bc-' + Date.now().toString(36) + '-' + Math.random().toString(36).slice(2, 8),
60
+ type: input.type,
61
+ payload: { content: input.content, ...(input.keyboard ? { keyboard: input.keyboard } : {}) },
62
+ targets: input.targets,
63
+ state: 'draft',
64
+ results: {},
65
+ retries: {},
66
+ created_at: Date.now(),
67
+ created_by: input.created_by,
68
+ };
69
+ store.tasks.unshift(task);
70
+ saveStore(dataRoot, store);
71
+ return task;
72
+ }
73
+ export function confirmTask(dataRoot, taskId) {
74
+ const store = loadStore(dataRoot);
75
+ const t = store.tasks.find((x) => x.task_id === taskId);
76
+ if (!t || t.state !== 'draft')
77
+ return t;
78
+ t.state = 'queued';
79
+ t.confirmed_at = Date.now();
80
+ saveStore(dataRoot, store);
81
+ return t;
82
+ }
83
+ export function cancelTask(dataRoot, taskId, by = 'dock') {
84
+ const store = loadStore(dataRoot);
85
+ const t = store.tasks.find((x) => x.task_id === taskId);
86
+ if (!t)
87
+ return t;
88
+ if (t.state === 'sending') {
89
+ // 发送中: 标记取消, 由推进循环在下一个目标前停下
90
+ t.state = 'cancelled';
91
+ t.cancelled_by = by;
92
+ t.done_at = Date.now();
93
+ }
94
+ else if (t.state === 'queued' || t.state === 'draft') {
95
+ t.state = 'cancelled';
96
+ t.cancelled_by = by;
97
+ t.done_at = Date.now();
98
+ }
99
+ saveStore(dataRoot, store);
100
+ return t;
101
+ }
102
+ export function listTasks(dataRoot) {
103
+ const store = loadStore(dataRoot);
104
+ prune(store);
105
+ saveStore(dataRoot, store);
106
+ return store.tasks;
107
+ }
108
+ export function getTask(dataRoot, taskId) {
109
+ return loadStore(dataRoot).tasks.find((x) => x.task_id === taskId);
110
+ }
111
+ /** 任务级推进锁(2026-09-10 修): host 后台定时器与 dock 的 list 请求可能同时推进同一任务,
112
+ * 两边都读到「results 里该目标为空」→ 同一个目标被发两次(主人实测"点一次发两条")。
113
+ * 用 Set 做进程内互斥: 同一任务同一时刻只允许一个推进在跑, 另一个直接返回当前快照。 */
114
+ const advancingTasks = new Set();
115
+ /**
116
+ * 推进一个 queued/sending 任务(串行逐目标 + 失败退避重试)—— 带并发保护的外层入口。
117
+ * 注意: 本函数是"单步推进"——由调用方(settings-host 定时器或每次请求)驱动,
118
+ * 每步处理 1 个未完成目标; 若同一任务多次调用会串行推进, 天然限频。
119
+ * 返回任务当前状态。
120
+ */
121
+ export async function advanceTask(dataRoot, taskId, client, opts) {
122
+ if (advancingTasks.has(taskId)) {
123
+ return loadStore(dataRoot).tasks.find((x) => x.task_id === taskId);
124
+ }
125
+ advancingTasks.add(taskId);
126
+ try {
127
+ return await advanceTaskInner(dataRoot, taskId, client, opts);
128
+ }
129
+ finally {
130
+ advancingTasks.delete(taskId);
131
+ }
132
+ }
133
+ /** 实际推进逻辑(仅由带锁的 advanceTask 调用) */
134
+ async function advanceTaskInner(dataRoot, taskId, client, opts) {
135
+ const store = loadStore(dataRoot);
136
+ const t = store.tasks.find((x) => x.task_id === taskId);
137
+ if (!t)
138
+ return t;
139
+ if (t.state === 'cancelled' || t.state === 'done')
140
+ return t;
141
+ if (t.state === 'draft')
142
+ return t; // 未确认不推进
143
+ // 找第一个未完成且未超重试的目标
144
+ let idx = -1;
145
+ for (let i = 0; i < t.targets.length; i++) {
146
+ const tg = t.targets[i];
147
+ const r = t.results[tg.peerId];
148
+ if (!r) {
149
+ idx = i;
150
+ break;
151
+ }
152
+ if (!r.ok && (t.retries[tg.peerId] || 0) < MAX_RETRIES) {
153
+ idx = i;
154
+ break;
155
+ }
156
+ }
157
+ if (idx === -1) {
158
+ // 全部目标处理完(或全部失败达上限) → 终态
159
+ const allOk = t.targets.every((tg2) => t.results[tg2.peerId]?.ok);
160
+ t.state = allOk ? 'done' : 'partial_failed';
161
+ t.done_at = Date.now();
162
+ saveStore(dataRoot, store);
163
+ return t;
164
+ }
165
+ if (t.state === 'queued')
166
+ t.state = 'sending';
167
+ const tg = t.targets[idx];
168
+ // 退避: 第 n 次重试前等 RETRY_BASE_MS * 2^(n-1)(首次失败的重试也适用)
169
+ const rn = t.retries[tg.peerId] || 0;
170
+ if (rn > 0) {
171
+ const wait = RETRY_BASE_MS * Math.pow(2, rn - 1);
172
+ await new Promise((resolve) => setTimeout(resolve, Math.min(wait, 30_000)));
173
+ }
174
+ if (opts?.isCancelled?.()) {
175
+ t.state = 'cancelled';
176
+ t.cancelled_by = 'operator';
177
+ t.done_at = Date.now();
178
+ saveStore(dataRoot, store);
179
+ return t;
180
+ }
181
+ try {
182
+ // card 类型(markdown+按钮)走卡片接口; 其余走文本接口(2026-09-10)
183
+ const sr = t.type === 'card'
184
+ ? (tg.scope === 'group'
185
+ ? await client.sendGroupCard(tg.peerId, t.payload.content, t.payload.keyboard)
186
+ : await client.sendC2cCard(tg.peerId, t.payload.content, t.payload.keyboard))
187
+ : (tg.scope === 'group'
188
+ ? await client.sendGroupText(tg.peerId, t.payload.content)
189
+ : await client.sendC2cText(tg.peerId, t.payload.content));
190
+ if (sr.ok) {
191
+ t.results[tg.peerId] = { ok: true, message_id: sr.data?.id };
192
+ }
193
+ else {
194
+ t.retries[tg.peerId] = (t.retries[tg.peerId] || 0) + 1;
195
+ t.results[tg.peerId] = { ok: false, err: sr.err.human };
196
+ }
197
+ }
198
+ catch (e) {
199
+ t.retries[tg.peerId] = (t.retries[tg.peerId] || 0) + 1;
200
+ t.results[tg.peerId] = { ok: false, err: String(e?.message ?? e) };
201
+ }
202
+ saveStore(dataRoot, store);
203
+ return t;
204
+ }
205
+ /** 撤回某任务发给指定目标的某条消息(2 分钟窗口, 由调用方做权限判断) */
206
+ export async function recallTaskMessage(dataRoot, taskId, peerId, client) {
207
+ const t = getTask(dataRoot, taskId);
208
+ if (!t)
209
+ return { ok: false, err: '任务不存在' };
210
+ const r = t.results[peerId];
211
+ if (!r?.ok || !r.message_id)
212
+ return { ok: false, err: '该目标没有可撤回的已发消息(未成功/无 message_id)' };
213
+ // 官方撤回窗口 2 分钟
214
+ const age = Date.now() - (t.done_at ?? Date.now());
215
+ if (age > 2 * 60 * 1000)
216
+ return { ok: false, err: '超过 2 分钟撤回窗口' };
217
+ try {
218
+ const sr = await client.recallMessage(r.message_id);
219
+ return sr.ok ? { ok: true, message_id: r.message_id } : { ok: false, err: sr.err.human, message_id: r.message_id };
220
+ }
221
+ catch (e) {
222
+ return { ok: false, err: String(e?.message ?? e), message_id: r.message_id };
223
+ }
224
+ }
225
+ //# sourceMappingURL=broadcast.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"broadcast.js","sourceRoot":"","sources":["../../src/features/broadcast.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,52 @@
1
+ /** 卡片按钮 data 前缀(区别于 botplay 的 `bp:` 与目录卡的 `bpc:`) */
2
+ export declare const CARD_BTN_PREFIX = "bpk:";
3
+ /** 按钮动作类型 */
4
+ export type CardButtonAction = 'text' | 'cmd' | 'url';
5
+ export interface CardCallbackButton {
6
+ /** 卡片内按钮短 id(b1/b2…),与 cardId 拼成 data */
7
+ id: string;
8
+ label: string;
9
+ action: CardButtonAction;
10
+ /** text=要回的文本;cmd=指令名(不带 /);url=跳转地址 */
11
+ payload: string;
12
+ }
13
+ export interface CardCallbackCard {
14
+ cardId: string;
15
+ buttons: CardCallbackButton[];
16
+ createdAt: number;
17
+ expireAt: number;
18
+ /** 发到哪(仅诊断用) */
19
+ scope?: 'group' | 'c2c';
20
+ targetId?: string;
21
+ }
22
+ export declare function cardCallbacksPath(dataRoot: string): string;
23
+ /** 追加一张卡片(顺带清理过期项、按上限截断);host 侧发卡时也会写同一文件 */
24
+ export declare function appendCardCallback(dataRoot: string, card: CardCallbackCard): void;
25
+ /** 按 cardId 查卡(过期返回 undefined) */
26
+ export declare function findCardCallback(dataRoot: string, cardId: string): CardCallbackCard | undefined;
27
+ /** 从 interaction 的 button_data 解析 cardId + buttonId;非本模块按钮返回 null */
28
+ export declare function parseCardButtonData(data: string | undefined): {
29
+ cardId: string;
30
+ buttonId: string;
31
+ } | null;
32
+ /** 命令执行器签名(与 botplay 指令型按钮一致:给命令名与回复目标,返回要发的文本) */
33
+ export type CardCommandExecutor = (cmdName: string, target: unknown) => Promise<string>;
34
+ export interface CardCallbackDeps {
35
+ dataRoot: string;
36
+ /** 发文本(群/私聊通用; 由 bootstrap 注入真实 sender) */
37
+ sendText: (target: unknown, text: string) => Promise<void>;
38
+ /** 执行斜杠命令(不带 /);未注入时指令按钮只提示不可用 */
39
+ commandExecutor?: CardCommandExecutor;
40
+ logger?: {
41
+ info?(m: string, ...a: unknown[]): void;
42
+ warn?(m: string, ...a: unknown[]): void;
43
+ };
44
+ }
45
+ /**
46
+ * 卡片按钮回调处理器:bootstrap 的 interaction 分发链**最后一环**。
47
+ * @returns true = 已消费(调用方无需其它处理)
48
+ */
49
+ export declare function createCardCallbackController(deps: CardCallbackDeps): {
50
+ handleInteraction(event: unknown, target: unknown): Promise<boolean>;
51
+ };
52
+ //# sourceMappingURL=card-callback.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"card-callback.d.ts","sourceRoot":"","sources":["../../src/features/card-callback.ts"],"names":[],"mappings":"AAqBA,qDAAqD;AACrD,eAAO,MAAM,eAAe,SAAS,CAAC;AAKtC,aAAa;AACb,MAAM,MAAM,gBAAgB,GAAG,MAAM,GAAG,KAAK,GAAG,KAAK,CAAC;AAEtD,MAAM,WAAW,kBAAkB;IACjC,yCAAyC;IACzC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,gBAAgB,CAAC;IACzB,wCAAwC;IACxC,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,kBAAkB,EAAE,CAAC;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,gBAAgB;IAChB,KAAK,CAAC,EAAE,OAAO,GAAG,KAAK,CAAC;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAOD,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAE1D;AAcD,6CAA6C;AAC7C,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,gBAAgB,GAAG,IAAI,CAcjF;AAED,kCAAkC;AAClC,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,gBAAgB,GAAG,SAAS,CAK/F;AAED,qEAAqE;AACrE,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAMzG;AAED,mDAAmD;AACnD,MAAM,MAAM,mBAAmB,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;AAExF,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,2CAA2C;IAC3C,QAAQ,EAAE,CAAC,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3D,kCAAkC;IAClC,eAAe,CAAC,EAAE,mBAAmB,CAAC;IACtC,MAAM,CAAC,EAAE;QAAE,IAAI,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;QAAC,IAAI,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,OAAO,EAAE,GAAG,IAAI,CAAA;KAAE,CAAC;CAC/F;AAED;;;GAGG;AACH,wBAAgB,4BAA4B,CAAC,IAAI,EAAE,gBAAgB,GAAG;IACpE,iBAAiB,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CACtE,CA6CA"}
@@ -0,0 +1,133 @@
1
+ /**
2
+ * card-callback.ts — 自定义卡片按钮回调(dock「📝 卡片」编辑器发出的卡)
3
+ *
4
+ * ⚠️ 2026-09-10 主人要求:卡片编辑器的按钮要能写「回文本 / 跳链接 / 执行命令」三种动作。
5
+ * 现状:编辑器发的卡是"裸"卡片,没有 botplay 事件挂靠 → 点击回调没人处理
6
+ * (botplay 的 handleInteraction 要求 findEvent 命中,否则直接回"事件已被删除")。
7
+ * 这里补一条**独立于 botplay 的兜底链路**:
8
+ * host(settings-host.js) 发卡时把按钮动作写入 `{dataRoot}/.qqbot/card-callbacks.json`,
9
+ * 按钮 data 编码为 `bpk:<cardId>:<buttonId>`(bp: 前缀归 botplay,bpk: 归本模块,互不干扰);
10
+ * 点击 → INTERACTION_CREATE(type=11) → bootstrap 分发兜底 → 查表执行:
11
+ * · action=text → 直接回该文本(sendMarkdown)
12
+ * · action=cmd → 走命令执行器(与 botplay 指令型按钮同一套 buildCommandList)
13
+ * · action=url → 官方 type=0 跳转按钮不会走到回调;真收到就提示手动打开
14
+ * 分工:presetSwitcher / approval / question / botplay 依次先处理,本模块只在**没人消费时**兜底。
15
+ *
16
+ * ⚠️ 文件格式是 host 与 dist 两侧的约定,改格式必须同步 settings-host.js 的
17
+ * `writeCardCallbacks` / `buildCardKeyboardFromPairs`。
18
+ */
19
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
20
+ import { dirname, join } from 'node:path';
21
+ /** 卡片按钮 data 前缀(区别于 botplay 的 `bp:` 与目录卡的 `bpc:`) */
22
+ export const CARD_BTN_PREFIX = 'bpk:';
23
+ /** 最多保留的卡片条数(超出丢最旧的;卡片本身有过期时间兜底) */
24
+ const MAX_CARDS = 200;
25
+ export function cardCallbacksPath(dataRoot) {
26
+ return join(dataRoot, '.qqbot', 'card-callbacks.json');
27
+ }
28
+ function readFile(dataRoot) {
29
+ const p = cardCallbacksPath(dataRoot);
30
+ try {
31
+ if (!existsSync(p))
32
+ return { version: 1, cards: [] };
33
+ const raw = JSON.parse(readFileSync(p, 'utf8'));
34
+ const cards = Array.isArray(raw?.cards) ? raw.cards : [];
35
+ return { version: 1, cards: cards.filter((c) => !!c && typeof c.cardId === 'string') };
36
+ }
37
+ catch {
38
+ return { version: 1, cards: [] };
39
+ }
40
+ }
41
+ /** 追加一张卡片(顺带清理过期项、按上限截断);host 侧发卡时也会写同一文件 */
42
+ export function appendCardCallback(dataRoot, card) {
43
+ const p = cardCallbacksPath(dataRoot);
44
+ try {
45
+ mkdirSync(dirname(p), { recursive: true });
46
+ const f = readFile(dataRoot);
47
+ const now = Date.now();
48
+ // 同 cardId 覆盖(重发同一张卡);过期项清掉
49
+ const kept = f.cards.filter((c) => c.cardId !== card.cardId && (c.expireAt || 0) > now);
50
+ kept.push(card);
51
+ const trimmed = kept.slice(-MAX_CARDS);
52
+ writeFileSync(p, JSON.stringify({ version: 1, cards: trimmed }, null, 1), 'utf8');
53
+ }
54
+ catch {
55
+ /* 写失败只影响按钮回调, 不阻断发卡 */
56
+ }
57
+ }
58
+ /** 按 cardId 查卡(过期返回 undefined) */
59
+ export function findCardCallback(dataRoot, cardId) {
60
+ const c = readFile(dataRoot).cards.find((x) => x.cardId === cardId);
61
+ if (!c)
62
+ return undefined;
63
+ if (c.expireAt && Date.now() > c.expireAt)
64
+ return undefined;
65
+ return c;
66
+ }
67
+ /** 从 interaction 的 button_data 解析 cardId + buttonId;非本模块按钮返回 null */
68
+ export function parseCardButtonData(data) {
69
+ if (!data || !data.startsWith(CARD_BTN_PREFIX))
70
+ return null;
71
+ const rest = data.slice(CARD_BTN_PREFIX.length);
72
+ const idx = rest.indexOf(':');
73
+ if (idx <= 0 || idx >= rest.length - 1)
74
+ return null;
75
+ return { cardId: rest.slice(0, idx), buttonId: rest.slice(idx + 1) };
76
+ }
77
+ /**
78
+ * 卡片按钮回调处理器:bootstrap 的 interaction 分发链**最后一环**。
79
+ * @returns true = 已消费(调用方无需其它处理)
80
+ */
81
+ export function createCardCallbackController(deps) {
82
+ const { dataRoot, sendText, commandExecutor, logger } = deps;
83
+ return {
84
+ async handleInteraction(event, target) {
85
+ const e = event;
86
+ if (e?.data?.type !== 11)
87
+ return false;
88
+ const parsed = parseCardButtonData(e.data.resolved?.button_data);
89
+ if (!parsed)
90
+ return false;
91
+ const card = findCardCallback(dataRoot, parsed.cardId);
92
+ if (!card) {
93
+ // 不是本模块发的卡 / 已过期 → 不消费, 让别的处理器或默认提示接手
94
+ return false;
95
+ }
96
+ const btn = card.buttons.find((b) => b.id === parsed.buttonId);
97
+ if (!btn)
98
+ return false;
99
+ try {
100
+ if (btn.action === 'text') {
101
+ const text = String(btn.payload ?? '').trim();
102
+ if (text)
103
+ await sendText(target, text);
104
+ return true;
105
+ }
106
+ if (btn.action === 'cmd') {
107
+ const cmdName = String(btn.payload ?? '').trim().replace(/^\//, '');
108
+ if (!cmdName)
109
+ return true;
110
+ if (!commandExecutor) {
111
+ await sendText(target, '指令执行器未就绪, 请稍后再试~');
112
+ return true;
113
+ }
114
+ const out = await commandExecutor(cmdName, target);
115
+ if (out && out.trim())
116
+ await sendText(target, out);
117
+ return true;
118
+ }
119
+ if (btn.action === 'url') {
120
+ // 官方 type=0 跳转按钮点击时客户端直接跳, 正常不会走到回调; 降级时给个提示
121
+ const url = String(btn.payload ?? '').trim();
122
+ await sendText(target, url ? `跳转按钮: ${url}(如未自动跳转请手动打开)` : '该按钮是跳转按钮, 请在支持跳转的客户端点击');
123
+ return true;
124
+ }
125
+ }
126
+ catch (err) {
127
+ logger?.warn?.(`[card-callback] 处理失败 card=${parsed.cardId} btn=${parsed.buttonId}: ${err instanceof Error ? err.message : String(err)}`);
128
+ }
129
+ return false;
130
+ },
131
+ };
132
+ }
133
+ //# sourceMappingURL=card-callback.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"card-callback.js","sourceRoot":"","sources":["../../src/features/card-callback.ts"],"names":[],"mappings":"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"}
@@ -25,6 +25,18 @@ export declare function safeAppendUserMessage(agent: unknown, text: string, logg
25
25
  * @returns 'ok' | 'no-hub' | 'no-session' | 其它见 safeAppendUserMessage
26
26
  */
27
27
  export declare function notifyGroupHub(manager: SessionManager, config: ImQQBotConfig, logger: Logger, ev: HubNotice): Promise<string>;
28
+ /**
29
+ * 唤醒指定会话的 LLM: 把 text 作为"用户消息" followup 给该会话的 agent,
30
+ * AI 开回合即可主动处理。可用于 hub 轮询唤醒, 也可跨会话发送+唤醒(工具用)。
31
+ * @returns 'ok' | 'no-session' | 'no-followup' | 'fail'
32
+ */
33
+ export declare function wakeSessionAgent(manager: SessionManager, sessionId: string, logger: Logger, text: string): Promise<string>;
34
+ /**
35
+ * 唤醒群组管理器会话的 LLM(轮询用): 把待审批摘要 followup 给 hub 会话的 agent,
36
+ * AI 开回合即可主动处理(查列表/按主人指令批拒)。不依赖普通群会话。
37
+ * @returns 'ok' | 'no-hub' | 'no-session' | 'no-followup'
38
+ */
39
+ export declare function wakeHubAgent(manager: SessionManager, config: ImQQBotConfig, logger: Logger, text: string): Promise<string>;
28
40
  /** GROUP_MEMBER_ADD: 新成员入群 → 记成员台账(事件无 username, 只落 openid)+ hub 通知 */
29
41
  export declare function handleGroupMemberAddEvent(data: unknown, opts: {
30
42
  config: ImQQBotConfig;
@@ -37,4 +49,6 @@ export declare function handleGroupAddRobotEvent(data: unknown, opts: {
37
49
  logger: Logger;
38
50
  manager: SessionManager;
39
51
  }): Promise<boolean>;
52
+ /** 与 chat-ledger 同 dataDir(表情包目录)的取法: config.dataRoot/cwd + 表情包 */
53
+ export declare function joinDataDir(config: ImQQBotConfig): string;
40
54
  //# sourceMappingURL=group-hub.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"group-hub.d.ts","sourceRoot":"","sources":["../../src/features/group-hub.ts"],"names":[],"mappings":"AAsBA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAClD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAM1D,MAAM,WAAW,SAAS;IACxB,qBAAqB;IACrB,IAAI,EAAE,cAAc,GAAG,YAAY,GAAG,WAAW,CAAC;IAClD,eAAe;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,2BAA2B;IAC3B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,mDAAmD;IACnD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,wBAAwB;IACxB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAMD;;;;GAIG;AACH,wBAAsB,qBAAqB,CACzC,KAAK,EAAE,OAAO,EACd,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,IAAI,GAAG,UAAU,GAAG,WAAW,GAAG,MAAM,GAAG,MAAM,CAAC,CA+C5D;AAED;;;;GAIG;AACH,wBAAsB,cAAc,CAClC,OAAO,EAAE,cAAc,EACvB,MAAM,EAAE,aAAa,EACrB,MAAM,EAAE,MAAM,EACd,EAAE,EAAE,SAAS,GACZ,OAAO,CAAC,MAAM,CAAC,CA4BjB;AAED,uEAAuE;AACvE,wBAAsB,yBAAyB,CAC7C,IAAI,EAAE,OAAO,EACb,IAAI,EAAE;IAAE,MAAM,EAAE,aAAa,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,cAAc,CAAA;CAAE,GACvE,OAAO,CAAC,OAAO,CAAC,CAqBlB;AAED,qEAAqE;AACrE,wBAAsB,wBAAwB,CAC5C,IAAI,EAAE,OAAO,EACb,IAAI,EAAE;IAAE,MAAM,EAAE,aAAa,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,cAAc,CAAA;CAAE,GACvE,OAAO,CAAC,OAAO,CAAC,CAkBlB"}
1
+ {"version":3,"file":"group-hub.d.ts","sourceRoot":"","sources":["../../src/features/group-hub.ts"],"names":[],"mappings":"AAsBA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAClD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAM1D,MAAM,WAAW,SAAS;IACxB,qBAAqB;IACrB,IAAI,EAAE,cAAc,GAAG,YAAY,GAAG,WAAW,CAAC;IAClD,eAAe;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,2BAA2B;IAC3B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,mDAAmD;IACnD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,wBAAwB;IACxB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAMD;;;;GAIG;AACH,wBAAsB,qBAAqB,CACzC,KAAK,EAAE,OAAO,EACd,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,IAAI,GAAG,UAAU,GAAG,WAAW,GAAG,MAAM,GAAG,MAAM,CAAC,CA0D5D;AAED;;;;GAIG;AACH,wBAAsB,cAAc,CAClC,OAAO,EAAE,cAAc,EACvB,MAAM,EAAE,aAAa,EACrB,MAAM,EAAE,MAAM,EACd,EAAE,EAAE,SAAS,GACZ,OAAO,CAAC,MAAM,CAAC,CA2BjB;AAED;;;;GAIG;AACH,wBAAsB,gBAAgB,CACpC,OAAO,EAAE,cAAc,EACvB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,MAAM,CAAC,CAiDjB;AAED;;;;GAIG;AACH,wBAAsB,YAAY,CAChC,OAAO,EAAE,cAAc,EACvB,MAAM,EAAE,aAAa,EACrB,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,MAAM,CAAC,CAIjB;AAED,uEAAuE;AACvE,wBAAsB,yBAAyB,CAC7C,IAAI,EAAE,OAAO,EACb,IAAI,EAAE;IAAE,MAAM,EAAE,aAAa,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,cAAc,CAAA;CAAE,GACvE,OAAO,CAAC,OAAO,CAAC,CAqBlB;AAED,qEAAqE;AACrE,wBAAsB,wBAAwB,CAC5C,IAAI,EAAE,OAAO,EACb,IAAI,EAAE;IAAE,MAAM,EAAE,aAAa,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,cAAc,CAAA;CAAE,GACvE,OAAO,CAAC,OAAO,CAAC,CAkBlB;AAED,mEAAmE;AACnE,wBAAgB,WAAW,CAAC,MAAM,EAAE,aAAa,GAAG,MAAM,CAGzD"}
@@ -57,7 +57,19 @@ export async function safeAppendUserMessage(agent, text, logger) {
57
57
  }
58
58
  catch { /* whenIdle 异常按未空闲处理 */ }
59
59
  if (!idle) {
60
- logger.warn?.('[group-hub] 回合未在等待窗口内空闲, 放弃 append(避免坏聊天记录)');
60
+ // 回合未在等待窗口内空闲: 降级宿主 inject 排队(回合安全, 不唤醒), 而不是放弃丢消息。
61
+ // inject = send(msg,'next-step',wakeup:false) → 排队到下一次 pre-step 组包, 不拆 tool_calls。
62
+ logger.warn?.('[group-hub] 回合未空闲, 降级 inject 排队(避免坏记录且不丢消息)');
63
+ if (typeof a.inject === 'function') {
64
+ try {
65
+ a.inject(msg);
66
+ return 'ok';
67
+ }
68
+ catch (err) {
69
+ logger.warn?.(`[group-hub] inject 兜底失败: ${err instanceof Error ? err.message : String(err)}`);
70
+ return 'fail';
71
+ }
72
+ }
61
73
  return 'busy';
62
74
  }
63
75
  }
@@ -97,8 +109,7 @@ export async function notifyGroupHub(manager, config, logger, ev) {
97
109
  logger.warn?.(`[group-hub] hub 会话未找到: ${ga.hubSessionId.slice(0, 8)}…(该会话可能已重建/换绑, 请在 dock 重新设置)`);
98
110
  return 'no-session';
99
111
  }
100
- const gidShort = tail(ev.gid, 8);
101
- const lines = [`【群管·${ev.kind === 'join_request' ? '入群申请' : ev.kind === 'member_add' ? '新成员入群' : '机器人被拉入群'}】群 ${gidShort}`];
112
+ const lines = [`【群管·${ev.kind === 'join_request' ? '入群申请' : ev.kind === 'member_add' ? '新成员入群' : '机器人被拉入群'}】群 ${ev.gid}`];
102
113
  if (ev.kind === 'join_request') {
103
114
  lines.push(`申请人: ${ev.name ?? '(未知昵称)'}(${tail(ev.memberOpenid)})`);
104
115
  if (ev.extra)
@@ -121,6 +132,78 @@ export async function notifyGroupHub(manager, config, logger, ev) {
121
132
  return 'fail';
122
133
  }
123
134
  }
135
+ /**
136
+ * 唤醒指定会话的 LLM: 把 text 作为"用户消息" followup 给该会话的 agent,
137
+ * AI 开回合即可主动处理。可用于 hub 轮询唤醒, 也可跨会话发送+唤醒(工具用)。
138
+ * @returns 'ok' | 'no-session' | 'no-followup' | 'fail'
139
+ */
140
+ export async function wakeSessionAgent(manager, sessionId, logger, text) {
141
+ if (!sessionId)
142
+ return 'no-session';
143
+ try {
144
+ let msg;
145
+ try {
146
+ msg = createUserMessage({
147
+ content: [{ type: 'text', text }],
148
+ source: { kind: 'user' },
149
+ });
150
+ }
151
+ catch {
152
+ return 'no-followup';
153
+ }
154
+ // ① 本插件会话表(QQ 会话): 走完整语义(lastInboundAt/turnActive + followup)
155
+ const rec = manager.findBySessionId(sessionId);
156
+ if (rec) {
157
+ const a = rec.agent;
158
+ if (typeof a.followup !== 'function')
159
+ return 'no-followup';
160
+ // 与 QQ 入站唤醒同语义(inbound.ts L203-206): 置回合活跃(消息聚合见忙攒消息) + followup 唤醒
161
+ rec.lastInboundAt = Date.now();
162
+ rec.turnActive = true;
163
+ a.followup(msg);
164
+ logger.info(`[group-hub] 唤醒 agent(${sessionId.slice(0, 8)}…) ok`);
165
+ return 'ok';
166
+ }
167
+ // ② 宿主全局 registry(web/hub 等非 QQ 会话): 进程内活 agent → 直接 followup
168
+ const host = manager.findHostAgent(sessionId);
169
+ if (host) {
170
+ const a = host.agent;
171
+ if (typeof a.followup !== 'function')
172
+ return 'no-followup';
173
+ a.followup(msg);
174
+ logger.info(`[group-hub] 唤醒宿主 agent(${sessionId.slice(0, 8)}…) ok`);
175
+ return 'ok';
176
+ }
177
+ // ③ 宿主持久化恢复(重启后唤起): 会话持久化在宿主, resume 拉回内存再 followup
178
+ // —— 与入站 getOrCreate 的 resume 路径同源: 重启后第一条消息就是这么唤起对话的
179
+ const resumed = await manager.resumeHostAgent(sessionId);
180
+ if (resumed) {
181
+ const a = resumed.agent;
182
+ if (typeof a.followup !== 'function')
183
+ return 'no-followup';
184
+ a.followup(msg);
185
+ logger.info(`[group-hub] resume+唤醒 agent(${sessionId.slice(0, 8)}…) ok`);
186
+ return 'ok';
187
+ }
188
+ logger.warn?.(`[group-hub] 会话未找到且无法恢复(唤醒): ${sessionId.slice(0, 8)}…`);
189
+ return 'no-session';
190
+ }
191
+ catch (err) {
192
+ logger.warn?.(`[group-hub] 唤醒异常: ${err instanceof Error ? err.message : String(err)}`);
193
+ return 'fail';
194
+ }
195
+ }
196
+ /**
197
+ * 唤醒群组管理器会话的 LLM(轮询用): 把待审批摘要 followup 给 hub 会话的 agent,
198
+ * AI 开回合即可主动处理(查列表/按主人指令批拒)。不依赖普通群会话。
199
+ * @returns 'ok' | 'no-hub' | 'no-session' | 'no-followup'
200
+ */
201
+ export async function wakeHubAgent(manager, config, logger, text) {
202
+ const ga = config.groupAdmin;
203
+ if (!ga?.hubSessionId)
204
+ return 'no-hub';
205
+ return wakeSessionAgent(manager, ga.hubSessionId, logger, text);
206
+ }
124
207
  /** GROUP_MEMBER_ADD: 新成员入群 → 记成员台账(事件无 username, 只落 openid)+ hub 通知 */
125
208
  export async function handleGroupMemberAddEvent(data, opts) {
126
209
  const { config, logger, manager } = opts;
@@ -167,7 +250,7 @@ export async function handleGroupAddRobotEvent(data, opts) {
167
250
  return true;
168
251
  }
169
252
  /** 与 chat-ledger 同 dataDir(表情包目录)的取法: config.dataRoot/cwd + 表情包 */
170
- function joinDataDir(config) {
253
+ export function joinDataDir(config) {
171
254
  const root = config.dataRoot || config.cwd || process.cwd();
172
255
  return join(root, '表情包');
173
256
  }
@@ -1 +1 @@
1
- {"version":3,"file":"group-hub.js","sourceRoot":"","sources":["../../src/features/group-hub.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"group-hub.js","sourceRoot":"","sources":["../../src/features/group-hub.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"group-join-request.d.ts","sourceRoot":"","sources":["../../src/features/group-join-request.ts"],"names":[],"mappings":"AAqBA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iCAAiC,CAAC;AACnE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAClD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAG1D,2CAA2C;AAC3C,MAAM,WAAW,qBAAqB;IACpC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,YAAY,GAAG,SAAS,CAAC;IACxC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,WAAW,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,cAAc,CAAC,EAAE,MAAM,CAAC;QAAC,cAAc,CAAC,EAAE,KAAK,CAAC;YAAE,QAAQ,EAAE,MAAM,CAAC;YAAC,MAAM,EAAE,MAAM,CAAA;SAAE,CAAC,CAAA;KAAE,CAAC;IACzH,aAAa,CAAC,EAAE;QAAE,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACzC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,gCAAgC;AAChC,MAAM,WAAW,kBAAkB;IACjC,YAAY,EAAE,MAAM,CAAC;IACrB,eAAe,EAAE,MAAM,CAAC;IACxB,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,qBAAqB;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,gBAAgB;IAChB,QAAQ,EAAE,OAAO,CAAC;CACnB;AAuCD,+CAA+C;AAC/C,wBAAgB,sBAAsB,CACpC,GAAG,EAAE,MAAM,GAAG,SAAS,EACvB,EAAE,EAAE,kBAAkB,GACrB,IAAI,CAUN;AAED,sCAAsC;AACtC,wBAAgB,uBAAuB,CACrC,GAAG,EAAE,MAAM,GAAG,SAAS,EACvB,GAAG,CAAC,EAAE,MAAM,GACX,kBAAkB,EAAE,CAItB;AAED;;;;;;;;GAQG;AACH,wBAAsB,2BAA2B,CAC/C,IAAI,EAAE,OAAO,EACb,IAAI,EAAE;IACJ,MAAM,EAAE,WAAW,CAAC;IACpB,MAAM,EAAE,aAAa,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,cAAc,CAAC;CACzB,GACA,OAAO,CAAC,OAAO,CAAC,CA+GlB"}
1
+ {"version":3,"file":"group-join-request.d.ts","sourceRoot":"","sources":["../../src/features/group-join-request.ts"],"names":[],"mappings":"AAqBA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iCAAiC,CAAC;AACnE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAClD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAK1D,2CAA2C;AAC3C,MAAM,WAAW,qBAAqB;IACpC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,YAAY,GAAG,SAAS,CAAC;IACxC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,WAAW,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,cAAc,CAAC,EAAE,MAAM,CAAC;QAAC,cAAc,CAAC,EAAE,KAAK,CAAC;YAAE,QAAQ,EAAE,MAAM,CAAC;YAAC,MAAM,EAAE,MAAM,CAAA;SAAE,CAAC,CAAA;KAAE,CAAC;IACzH,aAAa,CAAC,EAAE;QAAE,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACzC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,gCAAgC;AAChC,MAAM,WAAW,kBAAkB;IACjC,YAAY,EAAE,MAAM,CAAC;IACrB,eAAe,EAAE,MAAM,CAAC;IACxB,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,qBAAqB;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,gBAAgB;IAChB,QAAQ,EAAE,OAAO,CAAC;CACnB;AAuCD,+CAA+C;AAC/C,wBAAgB,sBAAsB,CACpC,GAAG,EAAE,MAAM,GAAG,SAAS,EACvB,EAAE,EAAE,kBAAkB,GACrB,IAAI,CAUN;AAED,sCAAsC;AACtC,wBAAgB,uBAAuB,CACrC,GAAG,EAAE,MAAM,GAAG,SAAS,EACvB,GAAG,CAAC,EAAE,MAAM,GACX,kBAAkB,EAAE,CAItB;AAED;;;;;;;;GAQG;AACH,wBAAsB,2BAA2B,CAC/C,IAAI,EAAE,OAAO,EACb,IAAI,EAAE;IACJ,MAAM,EAAE,WAAW,CAAC;IACpB,MAAM,EAAE,aAAa,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,cAAc,CAAC;CACzB,GACA,OAAO,CAAC,OAAO,CAAC,CAoHlB"}