@openclaw/qqbot 2026.7.1-beta.6 → 2026.7.2-beta.1
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/dist/api.js +8 -7
- package/dist/{channel-D1UztsnG.js → channel-BbwpkiY3.js} +99 -54
- package/dist/{channel-entry-C5YdhX3Y.js → channel-entry-Cj1lWXpt.js} +4 -4
- package/dist/channel-entry-api.js +1 -1
- package/dist/channel-plugin-api.js +1 -1
- package/dist/{channel.setup-2ItDYKhz.js → channel.setup-DfhritPL.js} +1 -1
- package/dist/{config-C1qZbh0K.js → config-CpOXnoEc.js} +2 -2
- package/dist/{config-schema-JZEf1dvB.js → config-schema-B5Mle_87.js} +38 -47
- package/dist/doctor-contract-api.js +1 -1
- package/dist/{gateway-pJQppxe4.js → gateway-be5-Ckdc.js} +284 -174
- package/dist/{group-o0GmovSf.js → group-Dbpnjalm.js} +19 -17
- package/dist/{handler-runtime-zQvT6SrI.js → handler-runtime-BvR-ayNW.js} +8 -12
- package/dist/{log-DEtcoDWe.js → log-Da4jz75I.js} +4 -8
- package/dist/{outbound-BIrfvvFJ.js → outbound-BLl8Tsu7.js} +8 -142
- package/dist/{runtime-DodcT_fQ.js → runtime-Du28LbOJ.js} +2 -2
- package/dist/runtime-api.js +1 -1
- package/dist/secret-contract-api.js +6 -22
- package/dist/{sender-CjDuU-uz.js → sender-0vqsivoI.js} +220 -66
- package/dist/setup-plugin-api.js +1 -1
- package/dist/state-keys-jLJ2SmJA.js +225 -0
- package/dist/{tools-UJJ-tLHP.js → tools-DYb23LBU.js} +48 -6
- package/dist/tools-api.js +1 -1
- package/node_modules/p-map/index.d.ts +155 -0
- package/node_modules/p-map/index.js +284 -0
- package/node_modules/p-map/license +9 -0
- package/node_modules/p-map/package.json +57 -0
- package/node_modules/p-map/readme.md +190 -0
- package/node_modules/parse-ms/index.d.ts +30 -0
- package/node_modules/parse-ms/index.js +45 -0
- package/node_modules/parse-ms/license +9 -0
- package/node_modules/parse-ms/package.json +47 -0
- package/node_modules/parse-ms/readme.md +46 -0
- package/node_modules/pretty-ms/index.d.ts +157 -0
- package/node_modules/pretty-ms/index.js +149 -0
- package/node_modules/pretty-ms/license +9 -0
- package/node_modules/pretty-ms/package.json +55 -0
- package/node_modules/pretty-ms/readme.md +179 -0
- package/npm-shrinkwrap.json +44 -3
- package/openclaw.plugin.json +61 -89
- package/package.json +8 -4
- package/dist/state-keys-CQKlAFyo.js +0 -141
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "pretty-ms",
|
|
3
|
+
"version": "9.3.0",
|
|
4
|
+
"description": "Convert milliseconds to a human readable string: `1337000000` → `15d 11h 23m 20s`",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"repository": "sindresorhus/pretty-ms",
|
|
7
|
+
"funding": "https://github.com/sponsors/sindresorhus",
|
|
8
|
+
"author": {
|
|
9
|
+
"name": "Sindre Sorhus",
|
|
10
|
+
"email": "sindresorhus@gmail.com",
|
|
11
|
+
"url": "https://sindresorhus.com"
|
|
12
|
+
},
|
|
13
|
+
"type": "module",
|
|
14
|
+
"exports": {
|
|
15
|
+
"types": "./index.d.ts",
|
|
16
|
+
"default": "./index.js"
|
|
17
|
+
},
|
|
18
|
+
"sideEffects": false,
|
|
19
|
+
"engines": {
|
|
20
|
+
"node": ">=18"
|
|
21
|
+
},
|
|
22
|
+
"scripts": {
|
|
23
|
+
"test": "xo && ava && tsd"
|
|
24
|
+
},
|
|
25
|
+
"files": [
|
|
26
|
+
"index.js",
|
|
27
|
+
"index.d.ts"
|
|
28
|
+
],
|
|
29
|
+
"keywords": [
|
|
30
|
+
"pretty",
|
|
31
|
+
"prettify",
|
|
32
|
+
"human",
|
|
33
|
+
"humanize",
|
|
34
|
+
"humanized",
|
|
35
|
+
"readable",
|
|
36
|
+
"time",
|
|
37
|
+
"ms",
|
|
38
|
+
"milliseconds",
|
|
39
|
+
"duration",
|
|
40
|
+
"period",
|
|
41
|
+
"range",
|
|
42
|
+
"text",
|
|
43
|
+
"string",
|
|
44
|
+
"number",
|
|
45
|
+
"hrtime"
|
|
46
|
+
],
|
|
47
|
+
"dependencies": {
|
|
48
|
+
"parse-ms": "^4.0.0"
|
|
49
|
+
},
|
|
50
|
+
"devDependencies": {
|
|
51
|
+
"ava": "^6.2.0",
|
|
52
|
+
"tsd": "^0.31.2",
|
|
53
|
+
"xo": "^0.59.3"
|
|
54
|
+
}
|
|
55
|
+
}
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
# pretty-ms
|
|
2
|
+
|
|
3
|
+
> Convert milliseconds to a human readable string: `1337000000` → `15d 11h 23m 20s`
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```sh
|
|
8
|
+
npm install pretty-ms
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
```js
|
|
14
|
+
import prettyMilliseconds from 'pretty-ms';
|
|
15
|
+
|
|
16
|
+
prettyMilliseconds(1337000000);
|
|
17
|
+
//=> '15d 11h 23m 20s'
|
|
18
|
+
|
|
19
|
+
prettyMilliseconds(1337000000n);
|
|
20
|
+
//=> '15d 11h 23m 20s'
|
|
21
|
+
|
|
22
|
+
prettyMilliseconds(1337);
|
|
23
|
+
//=> '1.3s'
|
|
24
|
+
|
|
25
|
+
prettyMilliseconds(133);
|
|
26
|
+
//=> '133ms'
|
|
27
|
+
|
|
28
|
+
// `compact` option
|
|
29
|
+
prettyMilliseconds(1337, {compact: true});
|
|
30
|
+
//=> '1s'
|
|
31
|
+
|
|
32
|
+
// `verbose` option
|
|
33
|
+
prettyMilliseconds(1335669000, {verbose: true});
|
|
34
|
+
//=> '15 days 11 hours 1 minute 9 seconds'
|
|
35
|
+
|
|
36
|
+
// `colonNotation` option
|
|
37
|
+
prettyMilliseconds(95500, {colonNotation: true});
|
|
38
|
+
//=> '1:35.5'
|
|
39
|
+
|
|
40
|
+
// `formatSubMilliseconds` option
|
|
41
|
+
prettyMilliseconds(100.400080, {formatSubMilliseconds: true})
|
|
42
|
+
//=> '100ms 400µs 80ns'
|
|
43
|
+
|
|
44
|
+
// `subSecondsAsDecimals` option
|
|
45
|
+
prettyMilliseconds(900, {subSecondsAsDecimals: true});
|
|
46
|
+
//=> '0.9s'
|
|
47
|
+
|
|
48
|
+
// Can be useful for time durations
|
|
49
|
+
prettyMilliseconds(new Date(2014, 0, 1, 10, 40) - new Date(2014, 0, 1, 10, 5))
|
|
50
|
+
//=> '35m'
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## API
|
|
54
|
+
|
|
55
|
+
### prettyMilliseconds(milliseconds, options?)
|
|
56
|
+
|
|
57
|
+
#### milliseconds
|
|
58
|
+
|
|
59
|
+
Type: `number | bigint`
|
|
60
|
+
|
|
61
|
+
Milliseconds to humanize.
|
|
62
|
+
|
|
63
|
+
#### options
|
|
64
|
+
|
|
65
|
+
Type: `object`
|
|
66
|
+
|
|
67
|
+
##### secondsDecimalDigits
|
|
68
|
+
|
|
69
|
+
Type: `number`\
|
|
70
|
+
Default: `1`
|
|
71
|
+
|
|
72
|
+
Number of digits to appear after the seconds decimal point.
|
|
73
|
+
|
|
74
|
+
##### millisecondsDecimalDigits
|
|
75
|
+
|
|
76
|
+
Type: `number`\
|
|
77
|
+
Default: `0`
|
|
78
|
+
|
|
79
|
+
Number of digits to appear after the milliseconds decimal point.
|
|
80
|
+
|
|
81
|
+
Useful in combination with [`process.hrtime()`](https://nodejs.org/api/process.html#process_process_hrtime_time).
|
|
82
|
+
|
|
83
|
+
##### keepDecimalsOnWholeSeconds
|
|
84
|
+
|
|
85
|
+
Type: `boolean`\
|
|
86
|
+
Default: `false`
|
|
87
|
+
|
|
88
|
+
Keep milliseconds on whole seconds: `13s` → `13.0s`.
|
|
89
|
+
|
|
90
|
+
Useful when you are showing a number of seconds spent on an operation and don't want the width of the output to change when hitting a whole number.
|
|
91
|
+
|
|
92
|
+
##### compact
|
|
93
|
+
|
|
94
|
+
Type: `boolean`\
|
|
95
|
+
Default: `false`
|
|
96
|
+
|
|
97
|
+
Only show the first unit: `1h 10m` → `1h`.
|
|
98
|
+
|
|
99
|
+
Also ensures that `millisecondsDecimalDigits` and `secondsDecimalDigits` are both set to `0`.
|
|
100
|
+
|
|
101
|
+
##### unitCount
|
|
102
|
+
|
|
103
|
+
Type: `number`\
|
|
104
|
+
Default: `Infinity`
|
|
105
|
+
|
|
106
|
+
Number of units to show. Setting `compact` to `true` overrides this option.
|
|
107
|
+
|
|
108
|
+
##### verbose
|
|
109
|
+
|
|
110
|
+
Type: `boolean`\
|
|
111
|
+
Default: `false`
|
|
112
|
+
|
|
113
|
+
Use full-length units: `5h 1m 45s` → `5 hours 1 minute 45 seconds`
|
|
114
|
+
|
|
115
|
+
##### separateMilliseconds
|
|
116
|
+
|
|
117
|
+
Type: `boolean`\
|
|
118
|
+
Default: `false`
|
|
119
|
+
|
|
120
|
+
Show milliseconds separately. This means they won't be included in the decimal part of the seconds.
|
|
121
|
+
|
|
122
|
+
##### formatSubMilliseconds
|
|
123
|
+
|
|
124
|
+
Type: `boolean`\
|
|
125
|
+
Default: `false`
|
|
126
|
+
|
|
127
|
+
Show microseconds and nanoseconds.
|
|
128
|
+
|
|
129
|
+
##### colonNotation
|
|
130
|
+
|
|
131
|
+
Type: `boolean`\
|
|
132
|
+
Default: `false`
|
|
133
|
+
|
|
134
|
+
Display time using colon notation: `5h 1m 45s` → `5:01:45`. Always shows time in at least minutes: `1s` → `0:01`
|
|
135
|
+
|
|
136
|
+
Useful when you want to display time without the time units, similar to a digital watch.
|
|
137
|
+
|
|
138
|
+
Setting `colonNotation` to `true` overrides the following options to `false`:
|
|
139
|
+
- `compact`
|
|
140
|
+
- `formatSubMilliseconds`
|
|
141
|
+
- `separateMilliseconds`
|
|
142
|
+
- `verbose`
|
|
143
|
+
|
|
144
|
+
##### hideYear
|
|
145
|
+
|
|
146
|
+
Type: `boolean`\
|
|
147
|
+
Default: `false`
|
|
148
|
+
|
|
149
|
+
Hides the year and shows the hidden year additionally as days (365 per year): `1y 3d 5h 1m 45s` → `368d 5h 1m 45s`.
|
|
150
|
+
|
|
151
|
+
##### hideYearAndDays
|
|
152
|
+
|
|
153
|
+
Type: `boolean`\
|
|
154
|
+
Default: `false`
|
|
155
|
+
|
|
156
|
+
Hides the year and days and shows the hidden values additionally as hours: `1y 3d 5h 1m 45s` → `8837h 1m 45s`.
|
|
157
|
+
|
|
158
|
+
##### hideSeconds
|
|
159
|
+
|
|
160
|
+
Type: `boolean`\
|
|
161
|
+
Default: `false`
|
|
162
|
+
|
|
163
|
+
Hides the seconds: `1y 3d 5h 1m 45s` → `1y 3d 5h 1m`.
|
|
164
|
+
|
|
165
|
+
##### subSecondsAsDecimals
|
|
166
|
+
|
|
167
|
+
Type: `boolean`\
|
|
168
|
+
Default: `false`
|
|
169
|
+
|
|
170
|
+
Show sub-second values as decimal seconds: `900ms` → `0.9s`.
|
|
171
|
+
|
|
172
|
+
Useful for progress indicators where you want consistent unit format to prevent flickering.
|
|
173
|
+
|
|
174
|
+
## Related
|
|
175
|
+
|
|
176
|
+
- [pretty-ms-cli](https://github.com/sindresorhus/pretty-ms-cli) - CLI for this module
|
|
177
|
+
- [parse-ms](https://github.com/sindresorhus/parse-ms) - Parse milliseconds into an object
|
|
178
|
+
- [to-milliseconds](https://github.com/sindresorhus/to-milliseconds) - Convert an object of time properties to milliseconds
|
|
179
|
+
- [pretty-bytes](https://github.com/sindresorhus/pretty-bytes) - Convert bytes to a human readable string
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,21 +1,23 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openclaw/qqbot",
|
|
3
|
-
"version": "2026.7.
|
|
3
|
+
"version": "2026.7.2-beta.1",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "@openclaw/qqbot",
|
|
9
|
-
"version": "2026.7.
|
|
9
|
+
"version": "2026.7.2-beta.1",
|
|
10
10
|
"dependencies": {
|
|
11
11
|
"@tencent-connect/qqbot-connector": "1.1.0",
|
|
12
12
|
"mpg123-decoder": "1.0.3",
|
|
13
|
+
"p-map": "7.0.5",
|
|
14
|
+
"pretty-ms": "9.3.0",
|
|
13
15
|
"silk-wasm": "3.7.1",
|
|
14
16
|
"ws": "8.21.0",
|
|
15
17
|
"zod": "4.4.3"
|
|
16
18
|
},
|
|
17
19
|
"peerDependencies": {
|
|
18
|
-
"openclaw": ">=2026.7.
|
|
20
|
+
"openclaw": ">=2026.7.2-beta.1"
|
|
19
21
|
},
|
|
20
22
|
"peerDependenciesMeta": {
|
|
21
23
|
"openclaw": {
|
|
@@ -64,6 +66,45 @@
|
|
|
64
66
|
"url": "https://github.com/sponsors/eshaz"
|
|
65
67
|
}
|
|
66
68
|
},
|
|
69
|
+
"node_modules/p-map": {
|
|
70
|
+
"version": "7.0.5",
|
|
71
|
+
"resolved": "https://registry.npmjs.org/p-map/-/p-map-7.0.5.tgz",
|
|
72
|
+
"integrity": "sha512-e8vJF4XdVkzqqSHguEMz41mQO1wKwxKm5ENrUJQUu9kLDCtn83cxbyHZcszr4QC5zEA7WffRRC4gsTecC7J9oA==",
|
|
73
|
+
"license": "MIT",
|
|
74
|
+
"engines": {
|
|
75
|
+
"node": ">=18"
|
|
76
|
+
},
|
|
77
|
+
"funding": {
|
|
78
|
+
"url": "https://github.com/sponsors/sindresorhus"
|
|
79
|
+
}
|
|
80
|
+
},
|
|
81
|
+
"node_modules/parse-ms": {
|
|
82
|
+
"version": "4.0.0",
|
|
83
|
+
"resolved": "https://registry.npmjs.org/parse-ms/-/parse-ms-4.0.0.tgz",
|
|
84
|
+
"integrity": "sha512-TXfryirbmq34y8QBwgqCVLi+8oA3oWx2eAnSn62ITyEhEYaWRlVZ2DvMM9eZbMs/RfxPu/PK/aBLyGj4IrqMHw==",
|
|
85
|
+
"license": "MIT",
|
|
86
|
+
"engines": {
|
|
87
|
+
"node": ">=18"
|
|
88
|
+
},
|
|
89
|
+
"funding": {
|
|
90
|
+
"url": "https://github.com/sponsors/sindresorhus"
|
|
91
|
+
}
|
|
92
|
+
},
|
|
93
|
+
"node_modules/pretty-ms": {
|
|
94
|
+
"version": "9.3.0",
|
|
95
|
+
"resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-9.3.0.tgz",
|
|
96
|
+
"integrity": "sha512-gjVS5hOP+M3wMm5nmNOucbIrqudzs9v/57bWRHQWLYklXqoXKrVfYW2W9+glfGsqtPgpiz5WwyEEB+ksXIx3gQ==",
|
|
97
|
+
"license": "MIT",
|
|
98
|
+
"dependencies": {
|
|
99
|
+
"parse-ms": "^4.0.0"
|
|
100
|
+
},
|
|
101
|
+
"engines": {
|
|
102
|
+
"node": ">=18"
|
|
103
|
+
},
|
|
104
|
+
"funding": {
|
|
105
|
+
"url": "https://github.com/sponsors/sindresorhus"
|
|
106
|
+
}
|
|
107
|
+
},
|
|
67
108
|
"node_modules/qrcode-terminal": {
|
|
68
109
|
"version": "0.12.0",
|
|
69
110
|
"resolved": "https://registry.npmjs.org/qrcode-terminal/-/qrcode-terminal-0.12.0.tgz",
|
package/openclaw.plugin.json
CHANGED
|
@@ -196,29 +196,22 @@
|
|
|
196
196
|
]
|
|
197
197
|
},
|
|
198
198
|
"streaming": {
|
|
199
|
-
"
|
|
200
|
-
|
|
201
|
-
|
|
199
|
+
"type": "object",
|
|
200
|
+
"additionalProperties": false,
|
|
201
|
+
"properties": {
|
|
202
|
+
"mode": {
|
|
203
|
+
"type": "string",
|
|
204
|
+
"enum": [
|
|
205
|
+
"off",
|
|
206
|
+
"partial"
|
|
207
|
+
],
|
|
208
|
+
"default": "partial"
|
|
202
209
|
},
|
|
203
|
-
{
|
|
204
|
-
"type": "
|
|
205
|
-
"
|
|
206
|
-
"properties": {
|
|
207
|
-
"mode": {
|
|
208
|
-
"type": "string",
|
|
209
|
-
"enum": [
|
|
210
|
-
"off",
|
|
211
|
-
"partial"
|
|
212
|
-
],
|
|
213
|
-
"default": "partial"
|
|
214
|
-
},
|
|
215
|
-
"c2cStreamApi": {
|
|
216
|
-
"type": "boolean",
|
|
217
|
-
"description": "Use QQ C2C official stream_messages API (single-message typing-style updates)."
|
|
218
|
-
}
|
|
219
|
-
}
|
|
210
|
+
"nativeTransport": {
|
|
211
|
+
"type": "boolean",
|
|
212
|
+
"description": "Use QQ's official C2C stream_messages API for DM replies (single-message typing-style updates)."
|
|
220
213
|
}
|
|
221
|
-
|
|
214
|
+
}
|
|
222
215
|
},
|
|
223
216
|
"groups": {
|
|
224
217
|
"$ref": "#/$defs/groups"
|
|
@@ -280,29 +273,22 @@
|
|
|
280
273
|
]
|
|
281
274
|
},
|
|
282
275
|
"streaming": {
|
|
283
|
-
"
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
"
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
"default": "partial"
|
|
298
|
-
},
|
|
299
|
-
"c2cStreamApi": {
|
|
300
|
-
"type": "boolean",
|
|
301
|
-
"description": "Use QQ C2C official stream_messages API (single-message typing-style updates)."
|
|
302
|
-
}
|
|
303
|
-
}
|
|
276
|
+
"type": "object",
|
|
277
|
+
"additionalProperties": false,
|
|
278
|
+
"properties": {
|
|
279
|
+
"mode": {
|
|
280
|
+
"type": "string",
|
|
281
|
+
"enum": [
|
|
282
|
+
"off",
|
|
283
|
+
"partial"
|
|
284
|
+
],
|
|
285
|
+
"default": "partial"
|
|
286
|
+
},
|
|
287
|
+
"nativeTransport": {
|
|
288
|
+
"type": "boolean",
|
|
289
|
+
"description": "Use QQ's official C2C stream_messages API for DM replies (single-message typing-style updates)."
|
|
304
290
|
}
|
|
305
|
-
|
|
291
|
+
}
|
|
306
292
|
},
|
|
307
293
|
"accounts": {
|
|
308
294
|
"type": "object",
|
|
@@ -503,31 +489,24 @@
|
|
|
503
489
|
]
|
|
504
490
|
},
|
|
505
491
|
"streaming": {
|
|
506
|
-
"
|
|
507
|
-
|
|
508
|
-
|
|
492
|
+
"type": "object",
|
|
493
|
+
"properties": {
|
|
494
|
+
"mode": {
|
|
495
|
+
"default": "partial",
|
|
496
|
+
"type": "string",
|
|
497
|
+
"enum": [
|
|
498
|
+
"off",
|
|
499
|
+
"partial"
|
|
500
|
+
]
|
|
509
501
|
},
|
|
510
|
-
{
|
|
511
|
-
"type": "
|
|
512
|
-
"properties": {
|
|
513
|
-
"mode": {
|
|
514
|
-
"default": "partial",
|
|
515
|
-
"type": "string",
|
|
516
|
-
"enum": [
|
|
517
|
-
"off",
|
|
518
|
-
"partial"
|
|
519
|
-
]
|
|
520
|
-
},
|
|
521
|
-
"c2cStreamApi": {
|
|
522
|
-
"type": "boolean"
|
|
523
|
-
}
|
|
524
|
-
},
|
|
525
|
-
"required": [
|
|
526
|
-
"mode"
|
|
527
|
-
],
|
|
528
|
-
"additionalProperties": {}
|
|
502
|
+
"nativeTransport": {
|
|
503
|
+
"type": "boolean"
|
|
529
504
|
}
|
|
530
|
-
|
|
505
|
+
},
|
|
506
|
+
"required": [
|
|
507
|
+
"mode"
|
|
508
|
+
],
|
|
509
|
+
"additionalProperties": false
|
|
531
510
|
},
|
|
532
511
|
"execApprovals": {
|
|
533
512
|
"type": "object",
|
|
@@ -867,31 +846,24 @@
|
|
|
867
846
|
]
|
|
868
847
|
},
|
|
869
848
|
"streaming": {
|
|
870
|
-
"
|
|
871
|
-
|
|
872
|
-
|
|
849
|
+
"type": "object",
|
|
850
|
+
"properties": {
|
|
851
|
+
"mode": {
|
|
852
|
+
"default": "partial",
|
|
853
|
+
"type": "string",
|
|
854
|
+
"enum": [
|
|
855
|
+
"off",
|
|
856
|
+
"partial"
|
|
857
|
+
]
|
|
873
858
|
},
|
|
874
|
-
{
|
|
875
|
-
"type": "
|
|
876
|
-
"properties": {
|
|
877
|
-
"mode": {
|
|
878
|
-
"default": "partial",
|
|
879
|
-
"type": "string",
|
|
880
|
-
"enum": [
|
|
881
|
-
"off",
|
|
882
|
-
"partial"
|
|
883
|
-
]
|
|
884
|
-
},
|
|
885
|
-
"c2cStreamApi": {
|
|
886
|
-
"type": "boolean"
|
|
887
|
-
}
|
|
888
|
-
},
|
|
889
|
-
"required": [
|
|
890
|
-
"mode"
|
|
891
|
-
],
|
|
892
|
-
"additionalProperties": {}
|
|
859
|
+
"nativeTransport": {
|
|
860
|
+
"type": "boolean"
|
|
893
861
|
}
|
|
894
|
-
|
|
862
|
+
},
|
|
863
|
+
"required": [
|
|
864
|
+
"mode"
|
|
865
|
+
],
|
|
866
|
+
"additionalProperties": false
|
|
895
867
|
},
|
|
896
868
|
"execApprovals": {
|
|
897
869
|
"type": "object",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openclaw/qqbot",
|
|
3
|
-
"version": "2026.7.
|
|
3
|
+
"version": "2026.7.2-beta.1",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "OpenClaw QQ Bot channel plugin for group and direct-message workflows.",
|
|
6
6
|
"repository": {
|
|
@@ -11,12 +11,14 @@
|
|
|
11
11
|
"dependencies": {
|
|
12
12
|
"@tencent-connect/qqbot-connector": "1.1.0",
|
|
13
13
|
"mpg123-decoder": "1.0.3",
|
|
14
|
+
"p-map": "7.0.5",
|
|
15
|
+
"pretty-ms": "9.3.0",
|
|
14
16
|
"silk-wasm": "3.7.1",
|
|
15
17
|
"ws": "8.21.0",
|
|
16
18
|
"zod": "4.4.3"
|
|
17
19
|
},
|
|
18
20
|
"peerDependencies": {
|
|
19
|
-
"openclaw": ">=2026.7.
|
|
21
|
+
"openclaw": ">=2026.7.2-beta.1"
|
|
20
22
|
},
|
|
21
23
|
"peerDependenciesMeta": {
|
|
22
24
|
"openclaw": {
|
|
@@ -45,10 +47,10 @@
|
|
|
45
47
|
"minHostVersion": ">=2026.4.10"
|
|
46
48
|
},
|
|
47
49
|
"compat": {
|
|
48
|
-
"pluginApi": ">=2026.7.
|
|
50
|
+
"pluginApi": ">=2026.7.2-beta.1"
|
|
49
51
|
},
|
|
50
52
|
"build": {
|
|
51
|
-
"openclawVersion": "2026.7.
|
|
53
|
+
"openclawVersion": "2026.7.2-beta.1"
|
|
52
54
|
},
|
|
53
55
|
"release": {
|
|
54
56
|
"publishToClawHub": true,
|
|
@@ -69,6 +71,8 @@
|
|
|
69
71
|
"bundledDependencies": [
|
|
70
72
|
"@tencent-connect/qqbot-connector",
|
|
71
73
|
"mpg123-decoder",
|
|
74
|
+
"p-map",
|
|
75
|
+
"pretty-ms",
|
|
72
76
|
"silk-wasm",
|
|
73
77
|
"ws",
|
|
74
78
|
"zod"
|
|
@@ -1,141 +0,0 @@
|
|
|
1
|
-
import crypto from "node:crypto";
|
|
2
|
-
import { asObjectRecord } from "openclaw/plugin-sdk/runtime-doctor";
|
|
3
|
-
//#region extensions/qqbot/src/doctor-contract.ts
|
|
4
|
-
const RESTRICTED_GROUP_TOOLS = { deny: [
|
|
5
|
-
"exec",
|
|
6
|
-
"read",
|
|
7
|
-
"write"
|
|
8
|
-
] };
|
|
9
|
-
function hasLegacyGroupToolPolicy(value) {
|
|
10
|
-
const groups = asObjectRecord(value);
|
|
11
|
-
if (!groups) return false;
|
|
12
|
-
return Object.values(groups).some((group) => asObjectRecord(group)?.toolPolicy !== void 0);
|
|
13
|
-
}
|
|
14
|
-
function hasLegacyAccountGroupToolPolicy(value) {
|
|
15
|
-
const accounts = asObjectRecord(value);
|
|
16
|
-
if (!accounts) return false;
|
|
17
|
-
return Object.values(accounts).some((account) => hasLegacyGroupToolPolicy(asObjectRecord(account)?.groups));
|
|
18
|
-
}
|
|
19
|
-
function migrateToolPolicy(value) {
|
|
20
|
-
if (value === "none") return { deny: ["*"] };
|
|
21
|
-
if (value === "full") return { allow: [] };
|
|
22
|
-
if (value === "restricted") return { ...RESTRICTED_GROUP_TOOLS };
|
|
23
|
-
}
|
|
24
|
-
function describeToolPolicy(value) {
|
|
25
|
-
return typeof value === "string" ? value : String(value);
|
|
26
|
-
}
|
|
27
|
-
function migrateGroups(params) {
|
|
28
|
-
let changed = false;
|
|
29
|
-
const nextGroups = { ...params.groups };
|
|
30
|
-
for (const [groupId, rawGroup] of Object.entries(params.groups)) {
|
|
31
|
-
const group = asObjectRecord(rawGroup);
|
|
32
|
-
if (!group || group.toolPolicy === void 0) continue;
|
|
33
|
-
const { toolPolicy, ...rest } = group;
|
|
34
|
-
const nextGroup = { ...rest };
|
|
35
|
-
const policy = migrateToolPolicy(toolPolicy);
|
|
36
|
-
const path = `${params.pathPrefix}.${groupId}`;
|
|
37
|
-
if (nextGroup.tools !== void 0) params.changes.push(`Removed ${path}.toolPolicy (${path}.tools already exists).`);
|
|
38
|
-
else if (policy) {
|
|
39
|
-
nextGroup.tools = policy;
|
|
40
|
-
params.changes.push(`Moved ${path}.toolPolicy=${describeToolPolicy(toolPolicy)} to ${path}.tools.`);
|
|
41
|
-
} else params.changes.push(`Removed unsupported ${path}.toolPolicy=${describeToolPolicy(toolPolicy)}.`);
|
|
42
|
-
nextGroups[groupId] = nextGroup;
|
|
43
|
-
changed = true;
|
|
44
|
-
}
|
|
45
|
-
return {
|
|
46
|
-
groups: nextGroups,
|
|
47
|
-
changed
|
|
48
|
-
};
|
|
49
|
-
}
|
|
50
|
-
const legacyConfigRules = [{
|
|
51
|
-
path: [
|
|
52
|
-
"channels",
|
|
53
|
-
"qqbot",
|
|
54
|
-
"groups"
|
|
55
|
-
],
|
|
56
|
-
message: "channels.qqbot.groups.<id>.toolPolicy is legacy and was ignored by QQBot group tool enforcement; use channels.qqbot.groups.<id>.tools instead. Run \"openclaw doctor --fix\".",
|
|
57
|
-
match: hasLegacyGroupToolPolicy
|
|
58
|
-
}, {
|
|
59
|
-
path: [
|
|
60
|
-
"channels",
|
|
61
|
-
"qqbot",
|
|
62
|
-
"accounts"
|
|
63
|
-
],
|
|
64
|
-
message: "channels.qqbot.accounts.<id>.groups.<groupId>.toolPolicy is legacy and was ignored by QQBot group tool enforcement; use channels.qqbot.accounts.<id>.groups.<groupId>.tools instead. Run \"openclaw doctor --fix\".",
|
|
65
|
-
match: hasLegacyAccountGroupToolPolicy
|
|
66
|
-
}];
|
|
67
|
-
function normalizeCompatibilityConfig({ cfg }) {
|
|
68
|
-
const rawEntry = asObjectRecord(cfg.channels?.qqbot);
|
|
69
|
-
if (!rawEntry) return {
|
|
70
|
-
config: cfg,
|
|
71
|
-
changes: []
|
|
72
|
-
};
|
|
73
|
-
const changes = [];
|
|
74
|
-
let updated = rawEntry;
|
|
75
|
-
let changed = false;
|
|
76
|
-
const groups = asObjectRecord(updated.groups);
|
|
77
|
-
if (groups) {
|
|
78
|
-
const migrated = migrateGroups({
|
|
79
|
-
groups,
|
|
80
|
-
pathPrefix: "channels.qqbot.groups",
|
|
81
|
-
changes
|
|
82
|
-
});
|
|
83
|
-
if (migrated.changed) {
|
|
84
|
-
updated = {
|
|
85
|
-
...updated,
|
|
86
|
-
groups: migrated.groups
|
|
87
|
-
};
|
|
88
|
-
changed = true;
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
const accounts = asObjectRecord(updated.accounts);
|
|
92
|
-
if (accounts) {
|
|
93
|
-
let accountsChanged = false;
|
|
94
|
-
const nextAccounts = { ...accounts };
|
|
95
|
-
for (const [accountId, rawAccount] of Object.entries(accounts)) {
|
|
96
|
-
const account = asObjectRecord(rawAccount);
|
|
97
|
-
const accountGroups = asObjectRecord(account?.groups);
|
|
98
|
-
if (!account || !accountGroups) continue;
|
|
99
|
-
const migrated = migrateGroups({
|
|
100
|
-
groups: accountGroups,
|
|
101
|
-
pathPrefix: `channels.qqbot.accounts.${accountId}.groups`,
|
|
102
|
-
changes
|
|
103
|
-
});
|
|
104
|
-
if (migrated.changed) {
|
|
105
|
-
nextAccounts[accountId] = {
|
|
106
|
-
...account,
|
|
107
|
-
groups: migrated.groups
|
|
108
|
-
};
|
|
109
|
-
accountsChanged = true;
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
if (accountsChanged) {
|
|
113
|
-
updated = {
|
|
114
|
-
...updated,
|
|
115
|
-
accounts: nextAccounts
|
|
116
|
-
};
|
|
117
|
-
changed = true;
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
if (!changed) return {
|
|
121
|
-
config: cfg,
|
|
122
|
-
changes: []
|
|
123
|
-
};
|
|
124
|
-
return {
|
|
125
|
-
config: {
|
|
126
|
-
...cfg,
|
|
127
|
-
channels: {
|
|
128
|
-
...cfg.channels,
|
|
129
|
-
qqbot: updated
|
|
130
|
-
}
|
|
131
|
-
},
|
|
132
|
-
changes
|
|
133
|
-
};
|
|
134
|
-
}
|
|
135
|
-
//#endregion
|
|
136
|
-
//#region extensions/qqbot/src/engine/utils/state-keys.ts
|
|
137
|
-
function buildQQBotStateKey(...parts) {
|
|
138
|
-
return crypto.createHash("sha256").update(JSON.stringify(parts)).digest("hex");
|
|
139
|
-
}
|
|
140
|
-
//#endregion
|
|
141
|
-
export { legacyConfigRules as n, normalizeCompatibilityConfig as r, buildQQBotStateKey as t };
|