dsh-qq-tools 0.9.0 → 0.9.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.
package/README.md
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
| 列出 QQ 群 | `qq_list_groups` | 群号、群名、人数 |
|
|
10
10
|
| 看群聊天记录 | `qq_get_group_history` | 最近消息 + 图片,只读;消息带 `#message_id` |
|
|
11
11
|
| 看群成员 | `qq_get_group_members` | 昵称、群名片、QQ 号、身份 |
|
|
12
|
-
| 发群消息 | `qq_send_group_message` |
|
|
12
|
+
| 发群消息 | `qq_send_group_message` | 发群消息,可引用消息、@人、@全体;同时负责 @ 提醒和群后续轮询 |
|
|
13
13
|
| 发表情 | `qq_send_face` | 在群里或私聊里发系统表情或 QQ 收藏夹里的自定义表情,可带一句话 |
|
|
14
14
|
| 收藏表情 | `qq_list_faces` / `qq_favorite_face` | 看/管理 QQ 账号收藏夹(SnowLuma):收藏图片、取消收藏、改备注、移到最前 |
|
|
15
15
|
| 私聊 | `qq_list_friends` / `qq_get_private_history` / `qq_send_private_message` | 好友列表、私聊记录、发私聊消息;同时负责私聊消息唤醒 |
|
|
@@ -102,12 +102,22 @@ test/smoke.mjs 离线冒烟测试:假 OneBot HTTP 服务 +
|
|
|
102
102
|
|
|
103
103
|
这些自定义表情接口是 SnowLuma 扩展,NapCat 没有。用 NapCat 时系统表情照常能发,收藏表情工具会提示接口不可用。
|
|
104
104
|
|
|
105
|
+
## 群消息:引用和 @
|
|
106
|
+
|
|
107
|
+
`qq_send_group_message` 除了 `group_id` 和 `message`,还支持:
|
|
108
|
+
|
|
109
|
+
- `reply_to`:消息前面的 `#编号`,引用那条消息;
|
|
110
|
+
- `at_user_ids`:QQ 号数组,@ 这些人;
|
|
111
|
+
- `at_all`:`true` 表示 @全体成员(这时 `at_user_ids` 会被忽略)。
|
|
112
|
+
|
|
113
|
+
`message` 可以只写文字,也可以留空只发 @;引用和 @ 可以同时用。群 @ 提醒和群后续里的每条消息是 `昵称(QQ号):内容(消息 #编号)`,可以直接把 `#编号` 传给 `reply_to`,把里面括号中的 QQ 号传给 `at_user_ids`。戳一戳和私聊唤醒也是 `昵称(QQ号)` 的形式。
|
|
114
|
+
|
|
105
115
|
## 私聊
|
|
106
116
|
|
|
107
117
|
私聊和群聊在程序里是分开的两条路径:群聊靠轮询 @,私聊靠 WebSocket 的 `message_type=private` 事件。私聊没有观察窗,每收到一条私聊消息都会直接唤醒目标会话。
|
|
108
118
|
|
|
109
|
-
-
|
|
110
|
-
- 模型用 `qq_get_private_history` 看和对方的最近记录,用 `qq_send_private_message`
|
|
119
|
+
- 唤醒提示里的消息行是 `昵称(QQ号):内容(消息 #编号)`;如果消息里有图片,也会把图片一起给模型看(有 sharp 时 GIF 会拆成首/中/尾最多 3 帧;没有 sharp 时交给 DSH 显示首帧,和群聊记录的处理一致)。
|
|
120
|
+
- 模型用 `qq_get_private_history` 看和对方的最近记录,用 `qq_send_private_message` 回文字(传 `reply_to=#编号` 可以引用),用 `qq_send_face` 回表情。
|
|
111
121
|
- `qq_list_friends` 列好友,可以按昵称、备注或 QQ 号搜;`privateUsers` 非空时只列白名单里的好友。
|
|
112
122
|
- `qq_get_private_history` 的消息带 `#message_id`,可以传给 `qq_send_private_message` / `qq_send_face` 的 `reply_to` 做引用回复。
|
|
113
123
|
- 私聊唤醒的 `source.kind` 是 `qq-private`,和群聊的 `qq-mention` / `qq-followup` / `qq-poke` 区分开。
|
|
@@ -179,7 +189,7 @@ dsh plugin --profile <profile> add dsh-qq-tools
|
|
|
179
189
|
需要固定版本时:
|
|
180
190
|
|
|
181
191
|
```sh
|
|
182
|
-
dsh plugin --profile <profile> add dsh-qq-tools@0.9.
|
|
192
|
+
dsh plugin --profile <profile> add dsh-qq-tools@0.9.2
|
|
183
193
|
```
|
|
184
194
|
|
|
185
195
|
### 本地开发 / 自己改代码
|
|
@@ -192,7 +202,7 @@ dsh plugin --profile <profile> add link:/path/to/dsh-qq-tools
|
|
|
192
202
|
|
|
193
203
|
```sh
|
|
194
204
|
pnpm pack
|
|
195
|
-
dsh plugin --profile <profile> add ./dsh-qq-tools-0.9.
|
|
205
|
+
dsh plugin --profile <profile> add ./dsh-qq-tools-0.9.2.tgz
|
|
196
206
|
```
|
|
197
207
|
|
|
198
208
|
`dsh plugin` 会在安装后自动把这个包追加进 profile 的 `dsh.profile.bundles`,不用手改 `package.json`。卸载用:
|
|
@@ -201,6 +211,14 @@ dsh plugin --profile <profile> add ./dsh-qq-tools-0.9.0.tgz
|
|
|
201
211
|
dsh plugin --profile <profile> remove dsh-qq-tools
|
|
202
212
|
```
|
|
203
213
|
|
|
214
|
+
## 兼容性、权限与商城状态
|
|
215
|
+
|
|
216
|
+
Node.js 要求为 `>=22`,DSH 支持范围为 `0.2.x`,与原有依赖说明一致。机器可读版本范围声明位于 `package.json` 的 `dsh.compatibility`。
|
|
217
|
+
|
|
218
|
+
本次声明依据、已获得的安装证据及未验证项见 [整改记录](docs/verification/README.md)。用户已自行测试现有功能;本次不重复功能测试,也不将手工使用情况冒充完整的商城生命周期验收。
|
|
219
|
+
|
|
220
|
+
本插件需要文件、网络和 OneBot token 权限。配置/诊断日志、本地图片读取、外部服务、账号写操作及失败边界详见 [SECURITY.md](SECURITY.md)。这些能力是 QQ 桥接的实际需要;补齐声明和验收证据不保证 DSH STORE 自动批准,商城可能仍要求 `user-reviewed` 专项审阅或保持 `blocked`。本仓库的验收记录不构成独立安全审计。
|
|
221
|
+
|
|
204
222
|
## 依赖
|
|
205
223
|
|
|
206
224
|
- DSH 0.2.x(cordis 插件体系)
|
|
@@ -212,4 +230,4 @@ dsh plugin --profile <profile> remove dsh-qq-tools
|
|
|
212
230
|
|
|
213
231
|
---
|
|
214
232
|
|
|
215
|
-
版本:0.9.
|
|
233
|
+
版本:0.9.2
|
package/lib/shared.js
CHANGED
|
@@ -442,6 +442,14 @@ function senderId(m) {
|
|
|
442
442
|
return clean(s.user_id || (m && m.user_id) || '')
|
|
443
443
|
}
|
|
444
444
|
|
|
445
|
+
// 唤醒提示里的消息行:和戳一戳一致,固定带上昵称和 QQ 号。
|
|
446
|
+
// 有 message_id 时附在末尾,模型可以把它传给 reply_to 做引用。
|
|
447
|
+
export function formatIncomingLine(name, userId, text, messageId) {
|
|
448
|
+
const who = clean(name) || 'QQ'
|
|
449
|
+
const qq = String(userId || '?')
|
|
450
|
+
return `${who}(${qq}):${text || '(空)'}` + (messageId != null ? `(消息 #${messageId})` : '')
|
|
451
|
+
}
|
|
452
|
+
|
|
445
453
|
|
|
446
454
|
function renderTool(_args, v) {
|
|
447
455
|
if (!v || !v.ok) return [{ type: 'text', text: 'QQ 工具失败:' + String((v && v.error) || '未知错误') }]
|
|
@@ -917,15 +925,19 @@ export function makeSendTool(onSent) {
|
|
|
917
925
|
name: 'qq_send_group_message',
|
|
918
926
|
description:
|
|
919
927
|
'在指定群里发一条消息。发之前先确认群号;只发到允许的群。' +
|
|
928
|
+
'reply_to 传消息前面的 #编号 可以引用那条消息;at_user_ids 传 QQ 号可以 @ 人,at_all=true 是 @全体成员。' +
|
|
920
929
|
'普通闲聊不要用 Markdown;一句话短一点,像群友随手打的。' +
|
|
921
930
|
'不想说话就不要调用这个工具;调用后不要再重复说自己发了什么。',
|
|
922
931
|
parameters: {
|
|
923
932
|
type: 'object',
|
|
924
933
|
properties: {
|
|
925
934
|
group_id: { type: 'number', description: '群号' },
|
|
926
|
-
message: { type: 'string', description: '
|
|
935
|
+
message: { type: 'string', description: '要发到群里的文字;只 @ 不说话时可以留空' },
|
|
936
|
+
reply_to: { type: 'string', description: '要引用的消息 ID(消息前面的 #编号),可选' },
|
|
937
|
+
at_user_ids: { type: 'array', items: { type: 'number' }, description: '要 @ 的 QQ 号列表,可选' },
|
|
938
|
+
at_all: { type: 'boolean', description: 'true = @全体成员,可选' },
|
|
927
939
|
},
|
|
928
|
-
required: ['group_id'
|
|
940
|
+
required: ['group_id'],
|
|
929
941
|
additionalProperties: false,
|
|
930
942
|
},
|
|
931
943
|
output: { schema: { type: 'object', additionalProperties: true }, render: renderTool },
|
|
@@ -933,24 +945,42 @@ export function makeSendTool(onSent) {
|
|
|
933
945
|
const cfg = loadCfg()
|
|
934
946
|
const groupId = Number(args && args.group_id)
|
|
935
947
|
const text = String((args && args.message) || '').trim()
|
|
948
|
+
const atIds = [...new Set(
|
|
949
|
+
(Array.isArray(args && args.at_user_ids) ? args.at_user_ids : [])
|
|
950
|
+
.map((x) => Number(x)).filter((x) => Number.isInteger(x) && x > 0),
|
|
951
|
+
)].slice(0, 20)
|
|
952
|
+
const atAll = args && args.at_all === true
|
|
936
953
|
if (!Number.isFinite(groupId)) return { ok: false, error: 'group_id 不是有效群号' }
|
|
937
|
-
if (!text) return { ok: false, error: '消息是空的' }
|
|
954
|
+
if (!text && !atIds.length && !atAll) return { ok: false, error: '消息是空的' }
|
|
938
955
|
if (!allowedGroup(groupId, cfg)) return { ok: false, error: '这个群不在允许列表里' }
|
|
939
956
|
try {
|
|
940
|
-
const
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
)
|
|
957
|
+
const message = []
|
|
958
|
+
const replyTo = args && args.reply_to
|
|
959
|
+
if (replyTo != null && replyTo !== '') message.push({ type: 'reply', data: { id: String(replyTo) } })
|
|
960
|
+
if (atAll) message.push({ type: 'at', data: { qq: 'all' } })
|
|
961
|
+
else for (const qq of atIds) message.push({ type: 'at', data: { qq: String(qq) } })
|
|
962
|
+
if (text) message.push({ type: 'text', data: { text: text.slice(0, 1000) } })
|
|
963
|
+
const data = await onebot('send_group_msg', { group_id: groupId, message }, cfg)
|
|
945
964
|
try { if (typeof onSent === 'function') onSent(groupId, '发群消息') } catch (error) {}
|
|
946
|
-
return {
|
|
965
|
+
return {
|
|
966
|
+
ok: true,
|
|
967
|
+
group_id: groupId,
|
|
968
|
+
message_id: data && data.message_id,
|
|
969
|
+
reply_to: replyTo != null && replyTo !== '' ? String(replyTo) : '',
|
|
970
|
+
at_user_ids: atAll ? [] : atIds,
|
|
971
|
+
at_all: atAll,
|
|
972
|
+
}
|
|
947
973
|
} catch (error) {
|
|
948
974
|
return { ok: false, error: String((error && error.message) || error) }
|
|
949
975
|
}
|
|
950
976
|
},
|
|
951
977
|
render(_args, v) {
|
|
952
978
|
if (!v || !v.ok) return [{ type: 'text', text: '发群消息失败:' + String((v && v.error) || '未知错误') }]
|
|
953
|
-
|
|
979
|
+
const extra = []
|
|
980
|
+
if (v.reply_to) extra.push('引用了 #' + v.reply_to)
|
|
981
|
+
if (v.at_all) extra.push('@全体成员')
|
|
982
|
+
else if (Array.isArray(v.at_user_ids) && v.at_user_ids.length) extra.push('@了 ' + v.at_user_ids.join('、'))
|
|
983
|
+
return [{ type: 'text', text: `已发到群 ${v.group_id}(消息 ${v.message_id || '?'}${extra.length ? ',' + extra.join(',') : ''})。` }]
|
|
954
984
|
},
|
|
955
985
|
}
|
|
956
986
|
}
|
|
@@ -1096,6 +1126,7 @@ export function makeSendPrivateTool() {
|
|
|
1096
1126
|
name: 'qq_send_private_message',
|
|
1097
1127
|
description:
|
|
1098
1128
|
'给某个 QQ 好友发一条私聊消息。user_id 从 qq_list_friends 或私聊唤醒提示里拿。' +
|
|
1129
|
+
'reply_to 传消息前面的 #编号 可以引用那条消息。' +
|
|
1099
1130
|
'普通闲聊不要用 Markdown;一句话短一点,像聊天一样。' +
|
|
1100
1131
|
'不想说话就不要调用;调用后不要再重复说自己发了什么。',
|
|
1101
1132
|
parameters: {
|
|
@@ -1103,7 +1134,7 @@ export function makeSendPrivateTool() {
|
|
|
1103
1134
|
properties: {
|
|
1104
1135
|
user_id: { type: 'number', description: '对方的 QQ 号' },
|
|
1105
1136
|
message: { type: 'string', description: '要发的文字,不要 Markdown' },
|
|
1106
|
-
reply_to: { type: 'string', description: '
|
|
1137
|
+
reply_to: { type: 'string', description: '要引用的消息 ID(消息前面的 #编号),可选' },
|
|
1107
1138
|
group_id: { type: 'number', description: '临时会话的来源群号,可选;普通好友私聊不用传' },
|
|
1108
1139
|
},
|
|
1109
1140
|
required: ['user_id', 'message'],
|
|
@@ -1126,14 +1157,20 @@ export function makeSendPrivateTool() {
|
|
|
1126
1157
|
const body = { user_id: userId, message }
|
|
1127
1158
|
if (groupId) body.group_id = groupId
|
|
1128
1159
|
const data = await onebot('send_private_msg', body, cfg)
|
|
1129
|
-
return {
|
|
1160
|
+
return {
|
|
1161
|
+
ok: true,
|
|
1162
|
+
user_id: userId,
|
|
1163
|
+
message_id: data && data.message_id,
|
|
1164
|
+
reply_to: replyTo != null && replyTo !== '' ? String(replyTo) : '',
|
|
1165
|
+
}
|
|
1130
1166
|
} catch (error) {
|
|
1131
1167
|
return { ok: false, error: String((error && error.message) || error) }
|
|
1132
1168
|
}
|
|
1133
1169
|
},
|
|
1134
1170
|
render(_args, v) {
|
|
1135
1171
|
if (!v || !v.ok) return [{ type: 'text', text: '发私聊消息失败:' + String((v && v.error) || '未知错误') }]
|
|
1136
|
-
|
|
1172
|
+
const quote = v.reply_to ? ',引用了 #' + v.reply_to : ''
|
|
1173
|
+
return [{ type: 'text', text: `已发给 QQ ${v.user_id}(消息 ${v.message_id || '?'}${quote})。` }]
|
|
1137
1174
|
},
|
|
1138
1175
|
}
|
|
1139
1176
|
}
|
|
@@ -2959,13 +2996,30 @@ async function pollMentions(ctx) {
|
|
|
2959
2996
|
)
|
|
2960
2997
|
const text = segText(segs) || '(没有文字)'
|
|
2961
2998
|
const name = clean((m.sender && (m.sender.card || m.sender.nickname)) || String(uid))
|
|
2999
|
+
const senderQQ = String(uid || (m.sender && m.sender.user_id) || '?')
|
|
2962
3000
|
const winUntil = windows.get(String(gid)) || 0
|
|
2963
3001
|
if (Date.now() < winUntil) {
|
|
2964
3002
|
const arr = followups.get(String(gid)) || []
|
|
2965
|
-
arr.push({
|
|
3003
|
+
arr.push({
|
|
3004
|
+
gid: String(gid),
|
|
3005
|
+
group: names.get(String(gid)) || String(gid),
|
|
3006
|
+
sender: name,
|
|
3007
|
+
user_id: senderQQ,
|
|
3008
|
+
message_id: mid,
|
|
3009
|
+
text,
|
|
3010
|
+
time: t,
|
|
3011
|
+
})
|
|
2966
3012
|
followups.set(String(gid), arr)
|
|
2967
3013
|
} else if (atMe) {
|
|
2968
|
-
mentions.push({
|
|
3014
|
+
mentions.push({
|
|
3015
|
+
gid: String(gid),
|
|
3016
|
+
group: names.get(String(gid)) || String(gid),
|
|
3017
|
+
sender: name,
|
|
3018
|
+
user_id: senderQQ,
|
|
3019
|
+
message_id: mid,
|
|
3020
|
+
text,
|
|
3021
|
+
time: t,
|
|
3022
|
+
})
|
|
2969
3023
|
}
|
|
2970
3024
|
}
|
|
2971
3025
|
lastSeen.set(String(gid), maxTime)
|
|
@@ -2973,15 +3027,19 @@ async function pollMentions(ctx) {
|
|
|
2973
3027
|
if (seen.size > 500) seen.clear()
|
|
2974
3028
|
for (const [gid, until] of windows) if (Date.now() >= until) windows.delete(gid)
|
|
2975
3029
|
if (!mentions.length && followups.size === 0) return
|
|
2976
|
-
const
|
|
3030
|
+
const fmtLine = (x) => formatIncomingLine(x.sender, x.user_id, x.text, x.message_id)
|
|
3031
|
+
const lines = mentions.slice(-5).map((x) => `群「${x.group}」${fmtLine(x)}`)
|
|
2977
3032
|
const sendTools = []
|
|
2978
3033
|
if (hasActiveTool('qq_send_group_message')) sendTools.push('qq_send_group_message')
|
|
2979
3034
|
if (hasActiveTool('qq_send_face')) sendTools.push('qq_send_face')
|
|
2980
3035
|
const sendHint = sendTools.length ? '想说话可以用 ' + sendTools.join(' / ') + ' 回复;' : ''
|
|
3036
|
+
const quoteHint = hasActiveTool('qq_send_group_message')
|
|
3037
|
+
? '想引用某条消息就传 reply_to=消息编号;想 @ 人就传 at_user_ids=[QQ号],@全体传 at_all=true;'
|
|
3038
|
+
: ''
|
|
2981
3039
|
const prompt =
|
|
2982
3040
|
'【群聊 @ 提醒】有人 @ 了你:\n' +
|
|
2983
3041
|
lines.join('\n') +
|
|
2984
|
-
'\n' + lookHint() + '再决定要不要回复、回哪个群。' + sendHint + '不想说话就安静待着;' +
|
|
3042
|
+
'\n' + lookHint() + '再决定要不要回复、回哪个群。' + sendHint + quoteHint + '不想说话就安静待着;' +
|
|
2985
3043
|
'不要用 Markdown,不要提工具和私聊内容,短一点。'
|
|
2986
3044
|
const message = {
|
|
2987
3045
|
id: randomUUID(),
|
|
@@ -2995,12 +3053,12 @@ async function pollMentions(ctx) {
|
|
|
2995
3053
|
}
|
|
2996
3054
|
for (const [gid, list] of followups) {
|
|
2997
3055
|
const group = list[0] && list[0].group ? list[0].group : gid
|
|
2998
|
-
const lines2 = list.slice(-10).map(
|
|
3056
|
+
const lines2 = list.slice(-10).map(fmtLine)
|
|
2999
3057
|
const prompt2 =
|
|
3000
3058
|
'【群聊后续】你刚才在群「' + group + '」里说过话,现在又有人说话:\n' +
|
|
3001
3059
|
lines2.join('\n') +
|
|
3002
3060
|
'\n想接就接;' +
|
|
3003
|
-
(hasActiveTool('qq_send_group_message') ? '想说话用 qq_send_group_message
|
|
3061
|
+
(hasActiveTool('qq_send_group_message') ? '想说话用 qq_send_group_message 发到这个群,引用某条传 reply_to=消息编号,@人传 at_user_ids=[QQ号],@全体传 at_all=true;' : '') +
|
|
3004
3062
|
(hasActiveTool('qq_send_face') ? '想回表情用 qq_send_face;' : '') +
|
|
3005
3063
|
'不想接就安静待着。不要用 Markdown,短一点。'
|
|
3006
3064
|
await agent.followup({
|
|
@@ -3127,20 +3185,20 @@ async function handlePrivateMessage(ctx, ev, admitImages) {
|
|
|
3127
3185
|
const segs = Array.isArray(ev.message) ? ev.message : []
|
|
3128
3186
|
const text = segText(segs) || clean(ev.raw_message) || '(没有文字)'
|
|
3129
3187
|
const groupId = ev.group_id ? String(ev.group_id) : ''
|
|
3188
|
+
const midHint = ev.message_id != null ? ',引用传 reply_to=' + ev.message_id : ''
|
|
3130
3189
|
const actions = []
|
|
3131
3190
|
if (hasActiveTool('qq_get_private_history')) {
|
|
3132
3191
|
actions.push('想看上下文用 qq_get_private_history(user_id=' + userId + ')')
|
|
3133
3192
|
}
|
|
3134
3193
|
if (hasActiveTool('qq_send_private_message')) {
|
|
3135
|
-
actions.push('想回就用 qq_send_private_message(user_id=' + userId + (groupId ? ', group_id=' + groupId : '') + ')')
|
|
3194
|
+
actions.push('想回就用 qq_send_private_message(user_id=' + userId + (groupId ? ', group_id=' + groupId : '') + midHint + ')')
|
|
3136
3195
|
}
|
|
3137
3196
|
if (hasActiveTool('qq_send_face')) {
|
|
3138
|
-
actions.push('想回表情用 qq_send_face(user_id=' + userId + (groupId ? ', group_id=' + groupId : '') + ')')
|
|
3197
|
+
actions.push('想回表情用 qq_send_face(user_id=' + userId + (groupId ? ', group_id=' + groupId : '') + midHint + ')')
|
|
3139
3198
|
}
|
|
3140
3199
|
const where = groupId ? '群 ' + groupId + ' 的临时会话' : '私聊'
|
|
3141
3200
|
const prompt =
|
|
3142
|
-
'【QQ ' + where + '】' + name
|
|
3143
|
-
(ev.message_id != null ? '\n(消息 #' + ev.message_id + ')' : '') +
|
|
3201
|
+
'【QQ ' + where + '】' + formatIncomingLine(name, userId, text, ev.message_id) +
|
|
3144
3202
|
'\n' + (actions.length ? actions.join(';') + '。' : '') +
|
|
3145
3203
|
'不想回就安静待着;不要用 Markdown,不要提工具,短一点。'
|
|
3146
3204
|
const content = [{ type: 'text', text: prompt }]
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-qq-tools",
|
|
3
|
-
"version": "0.9.
|
|
4
|
-
"description": "给大肥鱼会话用的 QQ
|
|
3
|
+
"version": "0.9.2",
|
|
4
|
+
"description": "给大肥鱼会话用的 QQ 群/私聊工具:列群、看群记录、发群消息(可引用/@)、发表情、收藏表情(SnowLuma 收藏夹)、好友/私聊记录、发私聊消息、私聊唤醒、群成员、戳一戳感知/戳回去、更改头像、好友管理(资料/备注/分组/删好友/名片赞/好友申请)、QQ 空间说说(列表/详情/发表/评论/点赞/权限)、挂载会话选择。11 个工具组加 1 个设置组件,可在插件页逐个开关。",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "lib/index.js",
|
|
7
7
|
"license": "MIT",
|
|
@@ -29,6 +29,8 @@
|
|
|
29
29
|
"locale",
|
|
30
30
|
"cordis.patch.yml",
|
|
31
31
|
"README.md",
|
|
32
|
+
"SECURITY.md",
|
|
33
|
+
"docs/verification",
|
|
32
34
|
"LICENSE"
|
|
33
35
|
],
|
|
34
36
|
"engines": {
|
|
@@ -78,6 +80,10 @@
|
|
|
78
80
|
"./package.json": "./package.json"
|
|
79
81
|
},
|
|
80
82
|
"dsh": {
|
|
83
|
+
"compatibility": {
|
|
84
|
+
"dsh": "0.2.x",
|
|
85
|
+
"node": ">=22"
|
|
86
|
+
},
|
|
81
87
|
"bundle": {
|
|
82
88
|
"patch": "./cordis.patch.yml"
|
|
83
89
|
},
|