@zhin.js/adapter-icqq 1.1.26 → 1.1.28

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 (57) hide show
  1. package/CHANGELOG.md +160 -0
  2. package/LICENSE +21 -0
  3. package/PERMITS.md +5 -1
  4. package/README.md +6 -2
  5. package/adapters/icqq/index.js +4 -0
  6. package/adapters/icqq/index.ts +4 -0
  7. package/agents/icqq/conversation.js +3 -2
  8. package/agents/icqq/conversation.ts +3 -2
  9. package/agents/icqq/skills/icqq-conversation/tools/conversation_info/index.js +2 -2
  10. package/agents/icqq/skills/icqq-conversation/tools/conversation_info/index.ts +2 -2
  11. package/agents/icqq/skills/icqq-directory/tools/friend_list/index.js +1 -1
  12. package/agents/icqq/skills/icqq-directory/tools/friend_list/index.ts +1 -1
  13. package/agents/icqq/skills/icqq-directory/tools/group_list/index.js +1 -1
  14. package/agents/icqq/skills/icqq-directory/tools/group_list/index.ts +1 -1
  15. package/agents/icqq/skills/icqq-group-admin/tools/announce/index.js +6 -5
  16. package/agents/icqq/skills/icqq-group-admin/tools/announce/index.ts +7 -6
  17. package/agents/icqq/skills/icqq-group-admin/tools/essence/index.js +7 -3
  18. package/agents/icqq/skills/icqq-group-admin/tools/essence/index.ts +7 -3
  19. package/agents/icqq/skills/icqq-group-admin/tools/group_invite/index.js +4 -3
  20. package/agents/icqq/skills/icqq-group-admin/tools/group_invite/index.ts +5 -4
  21. package/agents/icqq/skills/icqq-group-admin/tools/group_kick/index.js +6 -5
  22. package/agents/icqq/skills/icqq-group-admin/tools/group_kick/index.ts +7 -6
  23. package/agents/icqq/skills/icqq-group-admin/tools/group_leave/index.js +1 -1
  24. package/agents/icqq/skills/icqq-group-admin/tools/group_leave/index.ts +1 -1
  25. package/agents/icqq/skills/icqq-group-admin/tools/recall_member_message/index.js +1 -2
  26. package/agents/icqq/skills/icqq-group-admin/tools/recall_member_message/index.ts +1 -2
  27. package/agents/icqq/skills/icqq-group-admin/tools/set_anonymous/index.js +5 -4
  28. package/agents/icqq/skills/icqq-group-admin/tools/set_anonymous/index.ts +6 -5
  29. package/agents/icqq/skills/icqq-group-admin/tools/set_group_admin/index.js +6 -6
  30. package/agents/icqq/skills/icqq-group-admin/tools/set_group_admin/index.ts +7 -7
  31. package/agents/icqq/skills/icqq-group-admin/tools/set_mute/index.js +5 -3
  32. package/agents/icqq/skills/icqq-group-admin/tools/set_mute/index.ts +6 -4
  33. package/agents/icqq/skills/icqq-group-admin/tools/set_title/index.js +5 -3
  34. package/agents/icqq/skills/icqq-group-admin/tools/set_title/index.ts +6 -4
  35. package/agents/icqq/skills/icqq-group-directory/tools/group_member_info/index.js +5 -4
  36. package/agents/icqq/skills/icqq-group-directory/tools/group_member_info/index.ts +5 -5
  37. package/agents/icqq/skills/icqq-group-interaction/tools/group_sign/index.js +5 -5
  38. package/agents/icqq/skills/icqq-group-interaction/tools/group_sign/index.ts +6 -6
  39. package/agents/icqq/skills/icqq-group-interaction/tools/poke/index.js +4 -4
  40. package/agents/icqq/skills/icqq-group-interaction/tools/poke/index.ts +5 -5
  41. package/agents/icqq/skills/icqq-group-state/SKILL.md +1 -1
  42. package/agents/icqq/skills/icqq-group-state/tools/group_files/index.js +6 -7
  43. package/agents/icqq/skills/icqq-group-state/tools/group_files/index.ts +7 -8
  44. package/agents/icqq/skills/icqq-group-state/tools/list_muted/index.js +5 -6
  45. package/agents/icqq/skills/icqq-group-state/tools/list_muted/index.ts +6 -7
  46. package/commands/icqq/login/definition.js +19 -16
  47. package/commands/icqq/login/definition.ts +18 -18
  48. package/lib/endpoint.js +3 -2
  49. package/lib/group-scene.d.ts +3 -0
  50. package/lib/group-scene.js +11 -0
  51. package/lib/protocol.d.ts +3 -1
  52. package/package.json +29 -28
  53. package/plugin.js +0 -5
  54. package/schema.json +0 -55
  55. package/src/endpoint.ts +3 -2
  56. package/src/group-scene.ts +12 -0
  57. package/src/protocol.ts +3 -2
@@ -8,7 +8,7 @@ export default defineAgentTool({
8
8
  adapter: 'icqq',
9
9
  scopes: ['group'],
10
10
  currentConversationBotRoles: ['admin', 'member'],
11
- permissions: ['role(master)'],
11
+ permissions: ['owner'],
12
12
  requiresApproval: 'human',
13
13
  risk: 'dangerous',
14
14
  riskCategory: 'member',
@@ -9,8 +9,7 @@ export default defineAgentTool({
9
9
  // ADR 0044: offered only while the Bot can actually do this here (e.g. it is a group admin).
10
10
  requiresCapabilities: ['actions.recall.others'],
11
11
  scopes: ['group'],
12
- currentConversationBotRoles: ['owner', 'admin'],
13
- permissions: ['role(master,admin,trusted,owner)'],
12
+ permissions: ['platform:admin', 'bot:admin'],
14
13
  requiresApproval: 'never',
15
14
  inputSchema: z.object({
16
15
  message_id: z.string().min(1).describe('当前群中要撤回的真实消息 ID,或消息头里的 m<n> 别名'),
@@ -9,8 +9,7 @@ export default defineAgentTool({
9
9
  // ADR 0044: offered only while the Bot can actually do this here (e.g. it is a group admin).
10
10
  requiresCapabilities: ['actions.recall.others'],
11
11
  scopes: ['group'],
12
- currentConversationBotRoles: ['owner', 'admin'],
13
- permissions: ['role(master,admin,trusted,owner)'],
12
+ permissions: ['platform:admin', 'bot:admin'],
14
13
  requiresApproval: 'never',
15
14
  inputSchema: z.object({
16
15
  message_id: z.string().min(1).describe('当前群中要撤回的真实消息 ID,或消息头里的 m<n> 别名'),
@@ -1,19 +1,20 @@
1
1
  // Generated by build-plugin-runtime-entries.mjs. Do not edit.
2
2
  import { messages as t } from "../../../../messages.js";
3
+ import { currentGroup } from "../../../../conversation.js";
3
4
  import { freshMember, isGroupManager } from "../../../../members.js";
4
5
  import { defineAgentTool } from '@zhin.js/tool';
5
6
  import { z } from 'zod';
6
7
  export default defineAgentTool({
7
- description: '开启或关闭 QQ 群的匿名聊天功能',
8
+ description: '开启或关闭当前 QQ 群的匿名聊天功能',
8
9
  inputSchema: z.object({
9
- group_id: z.number().describe('目标群号'),
10
10
  enable: z.boolean().optional().describe('true=开启,false=关闭,默认 true'),
11
11
  }),
12
12
  adapter: 'icqq',
13
13
  requiresApproval: 'once',
14
14
  scopes: ['group'],
15
- permissions: ['role(master,trusted,owner,admin)'],
16
- async execute({ group_id, enable }, context) {
15
+ permissions: ['platform:admin', 'bot:admin'],
16
+ async execute({ enable }, context) {
17
+ const group_id = currentGroup(context);
17
18
  const client = context.$client;
18
19
  const on = enable ?? true;
19
20
  if (!isGroupManager(await freshMember(client, group_id, client.uin)))
@@ -1,18 +1,19 @@
1
1
  import { messages as t } from "../../../../messages.js";
2
+ import { currentGroup } from "../../../../conversation.js";
2
3
  import { freshMember, isGroupManager } from "../../../../members.js";
3
4
  import { defineAgentTool } from '@zhin.js/tool';
4
5
  import { z } from 'zod';
5
- export default defineAgentTool<{ group_id: number; enable?: boolean }>({
6
- description: '开启或关闭 QQ 群的匿名聊天功能',
6
+ export default defineAgentTool<{ enable?: boolean }>({
7
+ description: '开启或关闭当前 QQ 群的匿名聊天功能',
7
8
  inputSchema: z.object({
8
- group_id: z.number().describe('目标群号'),
9
9
  enable: z.boolean().optional().describe('true=开启,false=关闭,默认 true'),
10
10
  }),
11
11
  adapter: 'icqq',
12
12
  requiresApproval: 'once',
13
13
  scopes:['group'],
14
- permissions: ['role(master,trusted,owner,admin)'],
15
- async execute({ group_id, enable }, context) {
14
+ permissions: ['platform:admin', 'bot:admin'],
15
+ async execute({ enable }, context) {
16
+ const group_id = currentGroup(context);
16
17
  const client = context.$client;
17
18
  const on = enable ?? true;
18
19
  if (!isGroupManager(await freshMember(client, group_id, client.uin))) return { success: false, message: t(context.locale, 'anonymousForbidden') };
@@ -1,23 +1,23 @@
1
1
  // Generated by build-plugin-runtime-entries.mjs. Do not edit.
2
2
  import { messages as t } from "../../../../messages.js";
3
+ import { currentGroup } from "../../../../conversation.js";
3
4
  import { freshMember } from "../../../../members.js";
4
5
  import { defineAgentTool } from '@zhin.js/tool';
5
6
  import { z } from 'zod';
6
7
  export default defineAgentTool({
7
- description: '设置或取消 QQ 群管理员(enabled=true 设为管理员,false 取消管理员);仅你是该群群主时可用,每次人工审批',
8
+ description: '设置或取消当前 QQ 群管理员(enabled=true 设为管理员,false 取消管理员);仅你是本群群主时可用,每次人工审批',
8
9
  inputSchema: z.object({
9
- group_id: z.number().describe('目标群号'),
10
10
  user_id: z.number().describe('目标成员 QQ号'),
11
11
  enabled: z.boolean().describe('true 设为管理员(目标须为普通成员);false 取消管理员(目标须为现任管理员)'),
12
- reason: z.string().min(1).describe('本次设置或取消管理员的具体原因,随目标群和成员一起供人工确认'),
12
+ reason: z.string().min(1).describe('本次设置或取消管理员的具体原因,随目标成员一起供人工确认'),
13
13
  }),
14
14
  adapter: 'icqq',
15
15
  scopes: ['group'],
16
16
  requiresCapabilities: ['actions.setAdmin'],
17
- currentConversationBotRoles: ['owner'],
18
- permissions: ['role(master,admin,trusted,owner)'],
17
+ permissions: ['platform:owner', 'bot:owner'],
19
18
  requiresApproval: 'human',
20
- async execute({ group_id, user_id, enabled }, context) {
19
+ async execute({ user_id, enabled }, context) {
20
+ const group_id = currentGroup(context);
21
21
  const client = context.$client;
22
22
  if (user_id === client.uin)
23
23
  return { success: false, message: t(context.locale, 'adminForbidden') };
@@ -1,22 +1,22 @@
1
1
  import { messages as t } from "../../../../messages.js";
2
+ import { currentGroup } from "../../../../conversation.js";
2
3
  import { freshMember } from "../../../../members.js";
3
4
  import { defineAgentTool } from '@zhin.js/tool';
4
5
  import { z } from 'zod';
5
- export default defineAgentTool<{ group_id: number; user_id: number; enabled: boolean; reason: string }>({
6
- description: '设置或取消 QQ 群管理员(enabled=true 设为管理员,false 取消管理员);仅你是该群群主时可用,每次人工审批',
6
+ export default defineAgentTool<{ user_id: number; enabled: boolean; reason: string }>({
7
+ description: '设置或取消当前 QQ 群管理员(enabled=true 设为管理员,false 取消管理员);仅你是本群群主时可用,每次人工审批',
7
8
  inputSchema: z.object({
8
- group_id: z.number().describe('目标群号'),
9
9
  user_id: z.number().describe('目标成员 QQ号'),
10
10
  enabled: z.boolean().describe('true 设为管理员(目标须为普通成员);false 取消管理员(目标须为现任管理员)'),
11
- reason: z.string().min(1).describe('本次设置或取消管理员的具体原因,随目标群和成员一起供人工确认'),
11
+ reason: z.string().min(1).describe('本次设置或取消管理员的具体原因,随目标成员一起供人工确认'),
12
12
  }),
13
13
  adapter: 'icqq',
14
14
  scopes: ['group'],
15
15
  requiresCapabilities: ['actions.setAdmin'],
16
- currentConversationBotRoles: ['owner'],
17
- permissions: ['role(master,admin,trusted,owner)'],
16
+ permissions: ['platform:owner', 'bot:owner'],
18
17
  requiresApproval: 'human',
19
- async execute({ group_id, user_id, enabled }, context) {
18
+ async execute({ user_id, enabled }, context) {
19
+ const group_id = currentGroup(context);
20
20
  const client = context.$client;
21
21
  if (user_id === client.uin) return { success: false, message: t(context.locale, 'adminForbidden') };
22
22
  const [self, member] = await Promise.all([freshMember(client, group_id, client.uin), freshMember(client, group_id, user_id)]);
@@ -1,12 +1,12 @@
1
1
  // Generated by build-plugin-runtime-entries.mjs. Do not edit.
2
2
  import { messages as t } from "../../../../messages.js";
3
+ import { currentGroup } from "../../../../conversation.js";
3
4
  import { freshMember, isGroupManager } from "../../../../members.js";
4
5
  import { defineAgentTool } from '@zhin.js/tool';
5
6
  import { z } from 'zod';
6
7
  export default defineAgentTool({
7
- description: '禁言/解除禁言指定成员',
8
+ description: '禁言/解除禁言当前 QQ 群的指定成员',
8
9
  inputSchema: z.object({
9
- group_id: z.number().describe('目标群号'),
10
10
  user_id: z.number().describe('目标成员 QQ号'),
11
11
  duration: z.number().describe('禁言时间(秒),0=解除禁言').default(0),
12
12
  }),
@@ -14,8 +14,10 @@ export default defineAgentTool({
14
14
  // ADR 0044: offered only while the Bot can actually do this here (e.g. it is a group admin).
15
15
  requiresCapabilities: ['actions.mute'],
16
16
  scopes: ['group'],
17
+ permissions: ['platform:admin', 'bot:admin'],
17
18
  requiresApproval: 'always',
18
- async execute({ group_id, user_id, duration }, context) {
19
+ async execute({ user_id, duration }, context) {
20
+ const group_id = currentGroup(context);
19
21
  const client = context.$client;
20
22
  const [self, member] = await Promise.all([freshMember(client, group_id, client.uin), freshMember(client, group_id, user_id)]);
21
23
  if (!isGroupManager(self))
@@ -1,11 +1,11 @@
1
1
  import { messages as t } from "../../../../messages.js";
2
+ import { currentGroup } from "../../../../conversation.js";
2
3
  import { freshMember, isGroupManager } from "../../../../members.js";
3
4
  import { defineAgentTool } from '@zhin.js/tool';
4
5
  import { z } from 'zod';
5
- export default defineAgentTool<{ group_id: number; user_id: number; duration?: number }>({
6
- description: '禁言/解除禁言指定成员',
6
+ export default defineAgentTool<{ user_id: number; duration?: number }>({
7
+ description: '禁言/解除禁言当前 QQ 群的指定成员',
7
8
  inputSchema: z.object({
8
- group_id: z.number().describe('目标群号'),
9
9
  user_id: z.number().describe('目标成员 QQ号'),
10
10
  duration: z.number().describe('禁言时间(秒),0=解除禁言').default(0),
11
11
  }),
@@ -13,8 +13,10 @@ export default defineAgentTool<{ group_id: number; user_id: number; duration?: n
13
13
  // ADR 0044: offered only while the Bot can actually do this here (e.g. it is a group admin).
14
14
  requiresCapabilities: ['actions.mute'],
15
15
  scopes:['group'],
16
+ permissions: ['platform:admin', 'bot:admin'],
16
17
  requiresApproval: 'always',
17
- async execute({ group_id, user_id, duration }, context) {
18
+ async execute({ user_id, duration }, context) {
19
+ const group_id = currentGroup(context);
18
20
  const client = context.$client;
19
21
  const [self, member] = await Promise.all([freshMember(client, group_id, client.uin), freshMember(client, group_id, user_id)]);
20
22
  if (!isGroupManager(self)) return { success: false, message: t(context.locale, 'muteForbidden') };
@@ -1,12 +1,12 @@
1
1
  // Generated by build-plugin-runtime-entries.mjs. Do not edit.
2
2
  import { messages as t } from "../../../../messages.js";
3
+ import { currentGroup } from "../../../../conversation.js";
3
4
  import { freshMember, isGroupManager } from "../../../../members.js";
4
5
  import { defineAgentTool } from '@zhin.js/tool';
5
6
  import { z } from 'zod';
6
7
  export default defineAgentTool({
7
- description: '设置 QQ 群成员的专属头衔',
8
+ description: '设置当前 QQ 群成员的专属头衔',
8
9
  inputSchema: z.object({
9
- group_id: z.number().describe('目标群号'),
10
10
  user_id: z.number().describe('目标成员 QQ号'),
11
11
  title: z.string().describe('头衔文字'),
12
12
  duration: z.number().optional().describe('持续时间(秒),-1永久').default(-1),
@@ -15,8 +15,10 @@ export default defineAgentTool({
15
15
  // ADR 0044: offered only while the Bot can actually do this here (e.g. it is a group admin).
16
16
  requiresCapabilities: ['actions.setTitle'],
17
17
  scopes: ['group'],
18
+ permissions: ['platform:admin', 'bot:owner'],
18
19
  requiresApproval: 'always',
19
- async execute({ group_id, user_id, title, duration }, context) {
20
+ async execute({ user_id, title, duration }, context) {
21
+ const group_id = currentGroup(context);
20
22
  const client = context.$client;
21
23
  const [self, member] = await Promise.all([freshMember(client, group_id, client.uin), freshMember(client, group_id, user_id)]);
22
24
  if (!isGroupManager(self))
@@ -1,11 +1,11 @@
1
1
  import { messages as t } from "../../../../messages.js";
2
+ import { currentGroup } from "../../../../conversation.js";
2
3
  import { freshMember, isGroupManager } from "../../../../members.js";
3
4
  import { defineAgentTool } from '@zhin.js/tool';
4
5
  import { z } from 'zod';
5
- export default defineAgentTool<{ group_id: number; user_id: number; title: string; duration?: number }>({
6
- description: '设置 QQ 群成员的专属头衔',
6
+ export default defineAgentTool<{ user_id: number; title: string; duration?: number }>({
7
+ description: '设置当前 QQ 群成员的专属头衔',
7
8
  inputSchema: z.object({
8
- group_id: z.number().describe('目标群号'),
9
9
  user_id: z.number().describe('目标成员 QQ号'),
10
10
  title: z.string().describe('头衔文字'),
11
11
  duration: z.number().optional().describe('持续时间(秒),-1永久').default(-1),
@@ -14,8 +14,10 @@ export default defineAgentTool<{ group_id: number; user_id: number; title: strin
14
14
  // ADR 0044: offered only while the Bot can actually do this here (e.g. it is a group admin).
15
15
  requiresCapabilities: ['actions.setTitle'],
16
16
  scopes:['group'],
17
+ permissions: ['platform:admin', 'bot:owner'],
17
18
  requiresApproval: 'always',
18
- async execute({ group_id, user_id, title, duration }, context) {
19
+ async execute({ user_id, title, duration }, context) {
20
+ const group_id = currentGroup(context);
19
21
  const client = context.$client;
20
22
  const [self, member] = await Promise.all([freshMember(client, group_id, client.uin), freshMember(client, group_id, user_id)]);
21
23
  if (!isGroupManager(self)) return { success: false, message: t(context.locale, 'titleForbidden') };
@@ -1,19 +1,20 @@
1
1
  // Generated by build-plugin-runtime-entries.mjs. Do not edit.
2
2
  import { messages as t } from "../../../../messages.js";
3
3
  import { freshMember } from "../../../../members.js";
4
+ import { currentGroup } from "../../../../conversation.js";
4
5
  import { defineAgentTool } from '@zhin.js/tool';
5
6
  import { z } from 'zod';
6
7
  export default defineAgentTool({
7
- description: '获取 QQ 群成员信息',
8
+ description: '获取当前 QQ 群的成员信息',
8
9
  inputSchema: z.object({
9
- group_id: z.number().describe('目标群号'),
10
10
  user_id: z.number().describe('目标成员 QQ号'),
11
11
  }),
12
12
  adapter: 'icqq',
13
13
  scopes: ['group'],
14
- permissions: ['role(master,admin,trusted,owner)'],
14
+ permissions: ['trusted'],
15
15
  requiresApproval: 'never',
16
- async execute({ group_id, user_id }, context) {
16
+ async execute({ user_id }, context) {
17
+ const group_id = currentGroup(context);
17
18
  // pickMember 返回的是实体对象,序列化后只剩 `{}`:模型会据此以为成员不在群里。按 group_kick 的口径实时查询。
18
19
  const info = await freshMember(context.$client, group_id, user_id);
19
20
  if (!info)
@@ -1,23 +1,23 @@
1
1
  import { messages as t } from "../../../../messages.js";
2
2
  import { freshMember } from "../../../../members.js";
3
+ import { currentGroup } from "../../../../conversation.js";
3
4
  import { defineAgentTool } from '@zhin.js/tool';
4
5
  import { z } from 'zod';
5
6
  interface GroupMemberInfoInput {
6
- group_id: number;
7
7
  user_id: number;
8
8
  }
9
9
 
10
10
  export default defineAgentTool<GroupMemberInfoInput>({
11
- description: '获取 QQ 群成员信息',
11
+ description: '获取当前 QQ 群的成员信息',
12
12
  inputSchema: z.object({
13
- group_id: z.number().describe('目标群号'),
14
13
  user_id: z.number().describe('目标成员 QQ号'),
15
14
  }),
16
15
  adapter: 'icqq',
17
16
  scopes:['group'],
18
- permissions: ['role(master,admin,trusted,owner)'],
17
+ permissions: ['trusted'],
19
18
  requiresApproval: 'never',
20
- async execute({ group_id, user_id }, context) {
19
+ async execute({ user_id }, context) {
20
+ const group_id = currentGroup(context);
21
21
  // pickMember 返回的是实体对象,序列化后只剩 `{}`:模型会据此以为成员不在群里。按 group_kick 的口径实时查询。
22
22
  const info = await freshMember(context.$client, group_id, user_id);
23
23
  if (!info) return { success: false, message: t(context.locale, 'memberMissing') };
@@ -1,16 +1,16 @@
1
1
  // Generated by build-plugin-runtime-entries.mjs. Do not edit.
2
2
  import { messages as t } from "../../../../messages.js";
3
+ import { currentGroup } from "../../../../conversation.js";
3
4
  import { defineAgentTool } from '@zhin.js/tool';
4
5
  import { z } from 'zod';
5
6
  export default defineAgentTool({
6
- description: 'QQ 群签到/打卡',
7
- inputSchema: z.object({
8
- group_id: z.number().describe('目标群号'),
9
- }),
7
+ description: '在当前 QQ 群签到/打卡',
8
+ inputSchema: z.object({}),
10
9
  adapter: 'icqq',
11
10
  scopes: ['group'],
12
11
  requiresApproval: 'never',
13
- async execute({ group_id }, context) {
12
+ async execute(_input, context) {
13
+ const group_id = currentGroup(context);
14
14
  const client = context.$client;
15
15
  const groupInfo = client.pickGroup(group_id);
16
16
  if (!groupInfo)
@@ -1,15 +1,15 @@
1
1
  import { messages as t } from "../../../../messages.js";
2
+ import { currentGroup } from "../../../../conversation.js";
2
3
  import { defineAgentTool } from '@zhin.js/tool';
3
4
  import { z } from 'zod';
4
- export default defineAgentTool<{ group_id: number }>({
5
- description: 'QQ 群签到/打卡',
6
- inputSchema: z.object({
7
- group_id: z.number().describe('目标群号'),
8
- }),
5
+ export default defineAgentTool<Record<string, never>>({
6
+ description: '在当前 QQ 群签到/打卡',
7
+ inputSchema: z.object({}),
9
8
  adapter: 'icqq',
10
9
  scopes:['group'],
11
10
  requiresApproval: 'never',
12
- async execute({ group_id }, context) {
11
+ async execute(_input, context) {
12
+ const group_id = currentGroup(context);
13
13
  const client = context.$client;
14
14
  const groupInfo= client.pickGroup(group_id);
15
15
  if(!groupInfo) return { success: false, message: t(context.locale, 'groupMissing') };
@@ -1,18 +1,18 @@
1
1
  // Generated by build-plugin-runtime-entries.mjs. Do not edit.
2
2
  import { messages as t } from "../../../../messages.js";
3
+ import { currentGroup } from "../../../../conversation.js";
3
4
  import { defineAgentTool } from '@zhin.js/tool';
4
5
  import { z } from 'zod';
5
6
  export default defineAgentTool({
6
- description: '在 QQ 群中对某个成员执行戳一戳互动操作',
7
+ description: '在当前 QQ 群中对某个成员执行戳一戳互动操作',
7
8
  inputSchema: z.object({
8
- group_id: z.number().describe('目标群号'),
9
9
  user_id: z.number().describe('要戳的目标成员 QQ号'),
10
10
  }),
11
11
  adapter: 'icqq',
12
12
  scopes: ['group'],
13
13
  requiresApproval: 'never',
14
- async execute({ group_id, user_id }, context) {
15
- await context.$client.sendGroupPoke(group_id, user_id);
14
+ async execute({ user_id }, context) {
15
+ await context.$client.sendGroupPoke(currentGroup(context), user_id);
16
16
  return { success: true, message: t(context.locale, 'poked', { p0: user_id }) };
17
17
  },
18
18
  });
@@ -1,17 +1,17 @@
1
1
  import { messages as t } from "../../../../messages.js";
2
+ import { currentGroup } from "../../../../conversation.js";
2
3
  import { defineAgentTool } from '@zhin.js/tool';
3
4
  import { z } from 'zod';
4
- export default defineAgentTool<{ group_id: number; user_id: number }>({
5
- description: '在 QQ 群中对某个成员执行戳一戳互动操作',
5
+ export default defineAgentTool<{ user_id: number }>({
6
+ description: '在当前 QQ 群中对某个成员执行戳一戳互动操作',
6
7
  inputSchema: z.object({
7
- group_id: z.number().describe('目标群号'),
8
8
  user_id: z.number().describe('要戳的目标成员 QQ号'),
9
9
  }),
10
10
  adapter: 'icqq',
11
11
  scopes:['group'],
12
12
  requiresApproval: 'never',
13
- async execute({ group_id, user_id }, context) {
14
- await context.$client.sendGroupPoke(group_id, user_id);
13
+ async execute({ user_id }, context) {
14
+ await context.$client.sendGroupPoke(currentGroup(context), user_id);
15
15
  return { success: true, message: t(context.locale, 'poked', { p0: user_id }) };
16
16
  },
17
17
  });
@@ -15,4 +15,4 @@ scopes:
15
15
  ---
16
16
  # icqq-group-state
17
17
 
18
- 用于读取群文件和禁言状态。确认群号后调用,不把列表之外的信息当作已验证事实。
18
+ 用于读取当前群的群文件和禁言状态(只作用于当前群,不接受群号)。不把列表之外的信息当作已验证事实。
@@ -1,18 +1,17 @@
1
1
  // Generated by build-plugin-runtime-entries.mjs. Do not edit.
2
2
  import { messages as t } from "../../../../messages.js";
3
+ import { currentGroup } from "../../../../conversation.js";
3
4
  import { defineAgentTool } from '@zhin.js/tool';
4
5
  import { z } from 'zod';
5
6
  export default defineAgentTool({
6
- description: '获取 QQ 群的群文件列表',
7
- inputSchema: z.object({
8
- group_id: z.number().describe('群号'),
9
- }),
7
+ description: '获取当前 QQ 群的群文件列表',
8
+ inputSchema: z.object({}),
10
9
  adapter: 'icqq',
11
10
  requiresApproval: 'once',
12
11
  scopes: ['group'],
13
- permissions: ['role(master,admin,trusted,owner)'],
14
- async execute({ group_id }, context) {
15
- const files = await context.$client.acquireGfs(group_id).ls('/');
12
+ permissions: ['trusted'],
13
+ async execute(_input, context) {
14
+ const files = await context.$client.acquireGfs(currentGroup(context)).ls('/');
16
15
  if (!files.length)
17
16
  return { files: [], message: t(context.locale, 'filesEmpty') };
18
17
  return {
@@ -1,17 +1,16 @@
1
1
  import { messages as t } from "../../../../messages.js";
2
+ import { currentGroup } from "../../../../conversation.js";
2
3
  import { defineAgentTool } from '@zhin.js/tool';
3
4
  import { z } from 'zod';
4
- export default defineAgentTool<{ group_id: number }>({
5
- description: '获取 QQ 群的群文件列表',
6
- inputSchema: z.object({
7
- group_id: z.number().describe('群号'),
8
- }),
5
+ export default defineAgentTool<Record<string, never>>({
6
+ description: '获取当前 QQ 群的群文件列表',
7
+ inputSchema: z.object({}),
9
8
  adapter: 'icqq',
10
9
  requiresApproval: 'once',
11
10
  scopes:['group'],
12
- permissions: ['role(master,admin,trusted,owner)'],
13
- async execute({ group_id }, context) {
14
- const files = await context.$client.acquireGfs(group_id).ls('/');
11
+ permissions: ['trusted'],
12
+ async execute(_input, context) {
13
+ const files = await context.$client.acquireGfs(currentGroup(context)).ls('/');
15
14
  if (!files.length) return { files: [], message: t(context.locale, 'filesEmpty') };
16
15
  return {
17
16
  files: files.slice(0, 30).map((f) => 'size' in f
@@ -1,16 +1,15 @@
1
1
  // Generated by build-plugin-runtime-entries.mjs. Do not edit.
2
+ import { currentGroup } from "../../../../conversation.js";
2
3
  import { defineAgentTool } from '@zhin.js/tool';
3
4
  import { z } from 'zod';
4
5
  export default defineAgentTool({
5
- description: '查询 QQ 群中当前被禁言的成员列表',
6
- inputSchema: z.object({
7
- group_id: z.number().describe('目标群号'),
8
- }),
6
+ description: '查询当前 QQ 群中当前被禁言的成员列表',
7
+ inputSchema: z.object({}),
9
8
  adapter: 'icqq',
10
9
  scopes: ['group'],
11
10
  requiresApproval: 'never',
12
- async execute({ group_id }, context) {
13
- const members = await context.$client.getGroupMemberList(group_id);
11
+ async execute(_input, context) {
12
+ const members = await context.$client.getGroupMemberList(currentGroup(context));
14
13
  const now = Math.floor(Date.now() / 1000);
15
14
  const muted = Array.from(members.values()).filter((m) => m.shutup_time > now);
16
15
  return { muted_members: muted, count: muted.length };
@@ -1,15 +1,14 @@
1
+ import { currentGroup } from "../../../../conversation.js";
1
2
  import { defineAgentTool } from '@zhin.js/tool';
2
3
  import { z } from 'zod';
3
- export default defineAgentTool<{ group_id: number }>({
4
- description: '查询 QQ 群中当前被禁言的成员列表',
5
- inputSchema: z.object({
6
- group_id: z.number().describe('目标群号'),
7
- }),
4
+ export default defineAgentTool<Record<string, never>>({
5
+ description: '查询当前 QQ 群中当前被禁言的成员列表',
6
+ inputSchema: z.object({}),
8
7
  adapter: 'icqq',
9
8
  scopes:['group'],
10
9
  requiresApproval: 'never',
11
- async execute({ group_id }, context) {
12
- const members = await context.$client.getGroupMemberList(group_id);
10
+ async execute(_input, context) {
11
+ const members = await context.$client.getGroupMemberList(currentGroup(context));
13
12
  const now = Math.floor(Date.now() / 1000);
14
13
  const muted = Array.from(members.values()).filter((m) => m.shutup_time > now);
15
14
  return { muted_members: muted, count: muted.length };
@@ -4,37 +4,40 @@
4
4
  *
5
5
  * They are registered by the ICQQ plugin but can be invoked from any connected
6
6
  * adapter (typically the QQ instance that delivered the outage notice), so the
7
- * master can fetch the QR image and confirm/send verification codes without the
7
+ * owner can fetch the QR image and confirm/send verification codes without the
8
8
  * Console or terminal.
9
9
  */
10
10
  import { icqqLoginControls } from "../../../lib/icqq-login-control.js";
11
11
  export { icqqLoginControls };
12
- /** Master = framework master(s), or the configured outage-notify conversation id(s). */
12
+ /**
13
+ * Operator = a **global** chat-role `owner` (ADR 0056 §2: the command reaches an ICQQ account from
14
+ * any adapter, so a conversation / account owner elsewhere does not qualify), or the configured
15
+ * outage-notify conversation id(s).
16
+ */
13
17
  export function isIcqqLoginOperator(config, input) {
14
18
  const cfg = (config ?? {});
15
- const masters = new Set();
19
+ const sender = input?.sender;
20
+ const senderId = (typeof sender === 'object' && sender?.id) ? String(sender.id).trim() : '';
21
+ if (!senderId)
22
+ return false;
23
+ if (sender?.chatRole === 'owner' && sender.chatRoleLevels?.owner === 'global')
24
+ return true;
25
+ const targets = new Set();
16
26
  const collect = (value) => {
17
27
  if (value === undefined || value === null)
18
28
  return;
19
29
  const text = String(value).trim();
20
30
  if (text)
21
- masters.add(text);
31
+ targets.add(text);
22
32
  };
23
- collect(cfg.master);
24
33
  collect(cfg.notify?.id);
25
34
  if (Array.isArray(cfg.endpoints)) {
26
- for (const endpoint of cfg.endpoints) {
27
- collect(endpoint.master);
35
+ for (const endpoint of cfg.endpoints)
28
36
  collect(endpoint.notify?.id);
29
- }
30
37
  }
31
- // Login control is account-sensitive: without an explicit master/notify target,
32
- // refuse chat recovery and leave it to the authenticated Console page.
33
- if (masters.size === 0)
34
- return false;
35
- const senderRaw = input?.sender;
36
- const senderId = (typeof senderRaw === 'object' && senderRaw?.id) ? String(senderRaw.id).trim() : '';
37
- return senderId !== '' && masters.has(senderId);
38
+ // Login control is account-sensitive: without an owner or a notify target, chat recovery is
39
+ // refused and left to the authenticated Console page.
40
+ return targets.has(senderId);
38
41
  }
39
42
  export function pickIcqqLoginControl(controls, requested) {
40
43
  const wanted = requested?.trim();
@@ -51,7 +54,7 @@ export function pickIcqqLoginControl(controls, requested) {
51
54
  return { text: `有多个 ICQQ endpoint,请指定 QQ 号:${[...controls.keys()].join('、')}` };
52
55
  }
53
56
  export function icqqLoginForbidden() {
54
- return '仅 master 或 notify 目标账号可以操作 ICQQ 登录';
57
+ return '仅 owner(聊天角色)或 notify 目标账号可以操作 ICQQ 登录';
55
58
  }
56
59
  export function pendingTaskLabel(type) {
57
60
  switch (type) {