mioku-plugin-help 2.0.0

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/config.md ADDED
@@ -0,0 +1,195 @@
1
+ ---
2
+ title: WebUI插件配置API展示
3
+ description: 教你如何编写插件的help.md文件
4
+ fields:
5
+ - key: demo.textValue
6
+ label: text 单行文本
7
+ type: text
8
+ description: 最基础的单行文本输入。
9
+ placeholder: 输入任意文本
10
+
11
+ - key: demo.secretValue
12
+ label: secret 密文输入
13
+ type: secret
14
+ description: 适合 token、密码、密钥这类敏感字段。
15
+ placeholder: 输入密文内容
16
+
17
+ - key: demo.textareaValue
18
+ label: textarea 大文本
19
+ type: textarea
20
+ description: 适合提示词、描述、人设、长文本模板。
21
+ placeholder: 输入多行文本
22
+
23
+ - key: demo.numberValue
24
+ label: number 数字输入
25
+ type: number
26
+ description: 用于整数、小数或数量限制。
27
+ placeholder: 请输入数字
28
+
29
+ - key: demo.switchValue
30
+ label: switch 布尔开关
31
+ type: switch
32
+ description: 按钮交互
33
+
34
+ - key: demo.selectStaticValue
35
+ label: select 静态单选
36
+ type: select
37
+ description: 适合枚举值、模式切换、等级选择。
38
+ options:
39
+ - value: low
40
+ label: 低
41
+ - value: medium
42
+ label: 中
43
+ - value: high
44
+ label: 高
45
+
46
+ - key: demo.selectFriendValue
47
+ label: select 好友单选
48
+ type: select
49
+ source: qq_friends
50
+ description: 点击输入框弹窗,从当前好友列表中选择一个好友。
51
+ placeholder: 点击选择好友
52
+
53
+ - key: demo.selectGroupValue
54
+ label: select 群聊单选
55
+ type: select
56
+ source: qq_groups
57
+ description: 点击输入框弹窗,从当前已加入群聊中选择一个群。
58
+ placeholder: 点击选择群聊
59
+
60
+ - key: demo.multiSelectStaticValue
61
+ label: multi-select 静态多选
62
+ type: multi-select
63
+ description: 适合静态标签、开关集合、白名单集合。
64
+ options:
65
+ - value: alpha
66
+ label: alpha
67
+ - value: beta
68
+ label: beta
69
+ - value: gamma
70
+ label: gamma
71
+
72
+ - key: demo.multiSelectFriendsValue
73
+ label: multi-select 好友多选
74
+ type: multi-select
75
+ source: qq_friends
76
+ description: 点击输入框弹窗,可按昵称、备注或 QQ 号模糊搜索并多选好友。
77
+ placeholder: 点击选择多个好友
78
+
79
+ - key: demo.multiSelectGroupsValue
80
+ label: multi-select 群聊多选
81
+ type: multi-select
82
+ source: qq_groups
83
+ description: 点击输入框弹窗,可按群名称或群号模糊搜索并多选群聊。
84
+ placeholder: 点击选择多个群聊
85
+
86
+ - key: demo.jsonValue
87
+ label: json 原始对象
88
+ type: json
89
+ description: 用于复杂对象、复杂数组或暂时不想拆字段的高级配置。
90
+ ---
91
+
92
+ # Help 插件配置 API 演示
93
+
94
+ 这个页面只用于演示当前 `config.md` 的能力,不会影响 help 插件的实际功能。
95
+
96
+ ## 1. `mioku-field` 单字段渲染
97
+
98
+ ```mioku-field
99
+ key: demo.textValue
100
+ ```
101
+
102
+ 用法:当你只想在某个位置插入一个配置项时,使用 `mioku-field`,并通过 `key` 指向 frontmatter 里定义好的字段。
103
+
104
+ ```mioku-field
105
+ key: demo.secretValue
106
+ ```
107
+
108
+ 用法:`secret` 类型会使用密文输入框,适合 API Key、密码、令牌等敏感内容。
109
+
110
+ ```mioku-field
111
+ key: demo.textareaValue
112
+ ```
113
+
114
+ 用法:`textarea` 适合长文本。显示时会自动把配置里的字面量 `\n` 转成真实换行。
115
+
116
+ ```mioku-field
117
+ key: demo.numberValue
118
+ ```
119
+
120
+ 用法:`number` 用于限制值、数量、权重、超时等数值字段。
121
+
122
+ ```mioku-field
123
+ key: demo.switchValue
124
+ ```
125
+
126
+ 用法:`switch` 用于布尔开关,当前 UI 会用勾选卡片模式展示。
127
+
128
+ ## 2. 静态单选与动态单选
129
+
130
+ ```mioku-field
131
+ key: demo.selectStaticValue
132
+ ```
133
+
134
+ 用法:静态 `select` 通过 `options` 直接定义所有候选值。
135
+
136
+ ```mioku-field
137
+ key: demo.selectFriendValue
138
+ ```
139
+
140
+ 用法:动态 `select` 通过 `source: qq_friends` 读取当前好友列表,点击输入框后弹窗选择。
141
+
142
+ ```mioku-field
143
+ key: demo.selectGroupValue
144
+ ```
145
+
146
+ 用法:动态 `select` 通过 `source: qq_groups` 读取当前群聊列表,支持按群名称或群号模糊搜索。
147
+
148
+ ## 3. 静态多选与动态多选
149
+
150
+ ```mioku-field
151
+ key: demo.multiSelectStaticValue
152
+ ```
153
+
154
+ 用法:静态 `multi-select` 适合少量固定标签集合。
155
+
156
+ ```mioku-field
157
+ key: demo.multiSelectFriendsValue
158
+ ```
159
+
160
+ 用法:动态好友多选会打开弹窗,支持按昵称、备注或 QQ 号搜索,并批量确认。
161
+
162
+ ```mioku-field
163
+ key: demo.multiSelectGroupsValue
164
+ ```
165
+
166
+ 用法:动态群聊多选会打开弹窗,支持按群名或群号搜索,并展示群头像、群号和人数。
167
+
168
+ ## 4. `json` 高级配置
169
+
170
+ ```mioku-field
171
+ key: demo.jsonValue
172
+ ```
173
+
174
+ 用法:当配置结构复杂,不适合拆成很多基础字段时,可以直接暴露一个 `json` 编辑器。
175
+
176
+ ## 5. `mioku-fields` 多字段渲染
177
+
178
+ ```mioku-fields
179
+ keys:
180
+ - demo.textValue
181
+ - demo.numberValue
182
+ - demo.switchValue
183
+ ```
184
+
185
+ 用法:当你希望按顺序连续渲染多个字段时,可以使用 `mioku-fields`。
186
+
187
+ ## 6. `mioku-file` 原始文件渲染
188
+
189
+ ```mioku-file
190
+ config: demo
191
+ ```
192
+
193
+ 用法:`mioku-file` 会直接把某个配置文件完整显示为 JSON 编辑器,适合调试或保底兜底。
194
+
195
+ ---
package/demo-config.ts ADDED
@@ -0,0 +1,21 @@
1
+ export const HELP_DEMO_CONFIG = {
2
+ demo: {
3
+ textValue: "示例文本",
4
+ secretValue: "",
5
+ textareaValue:
6
+ "这是一个多行文本输入示例。\\n你可以在这里写较长的说明、提示词或模板内容。",
7
+ numberValue: 42,
8
+ switchValue: true,
9
+ selectStaticValue: "medium",
10
+ selectFriendValue: "",
11
+ selectGroupValue: "",
12
+ multiSelectStaticValue: ["alpha", "gamma"],
13
+ multiSelectFriendsValue: [],
14
+ multiSelectGroupsValue: [],
15
+ jsonValue: {
16
+ enabled: true,
17
+ tags: ["demo", "help"],
18
+ note: "用于演示 json 类型配置项",
19
+ },
20
+ },
21
+ };
package/index.ts ADDED
@@ -0,0 +1,107 @@
1
+ import type { ConfigService } from "mioku";
2
+ import type { HelpService } from "mioku";
3
+ import type { ScreenshotService } from "mioku";
4
+ import { definePlugin, type MiokiContext } from "mioki";
5
+ import * as path from "path";
6
+ import { HELP_DEMO_CONFIG } from "./demo-config";
7
+ import {
8
+ generateHelpImage,
9
+ getPackageVersion,
10
+ replyWithImage,
11
+ resolveHelpBotProfile,
12
+ resolveHelpImageIntent,
13
+ } from "./shared";
14
+ import { resetHelpRuntimeState, setHelpRuntimeState } from "./runtime";
15
+
16
+ const helpPlugin = definePlugin({
17
+ name: "help",
18
+ version: "1.0.0",
19
+ description: "帮助插件,生成帮助图片",
20
+
21
+ async setup(ctx: MiokiContext) {
22
+ const configService = ctx.services?.config as ConfigService | undefined;
23
+ const helpService = ctx.services?.help as HelpService | undefined;
24
+ const screenshotService = ctx.services?.screenshot as
25
+ | ScreenshotService
26
+ | undefined;
27
+
28
+ if (!helpService) {
29
+ ctx.logger.warn("help-service 未加载,帮助插件无法运行");
30
+ return;
31
+ }
32
+
33
+ if (!screenshotService) {
34
+ ctx.logger.warn("screenshot 服务未加载,帮助插件功能受限");
35
+ }
36
+
37
+ if (configService) {
38
+ await configService.registerConfig("help", "demo", HELP_DEMO_CONFIG.demo);
39
+ }
40
+
41
+ const miokiVersion = await getPackageVersion(
42
+ path.join(process.cwd(), "node_modules/mioku/node_modules/mioki/package.json"),
43
+ );
44
+ const miokuVersion = await getPackageVersion(
45
+ path.join(process.cwd(), "node_modules/mioku/package.json"),
46
+ );
47
+
48
+ setHelpRuntimeState({
49
+ miokiVersion,
50
+ miokuVersion,
51
+ });
52
+
53
+ ctx.handle("message", async (event: any) => {
54
+ const text = ctx.text(event);
55
+ if (!text) {
56
+ return;
57
+ }
58
+
59
+ const allHelp = helpService.getAllHelp();
60
+ const intent = resolveHelpImageIntent(text, allHelp);
61
+ if (intent.type === "none") {
62
+ return;
63
+ }
64
+
65
+ if (!screenshotService) {
66
+ await event.reply("screenshot 服务未加载,无法生成帮助图片");
67
+ return;
68
+ }
69
+
70
+ if (intent.type === "unknown") {
71
+ await event.reply(`没有找到插件 ${intent.keyword} 的帮助`);
72
+ return;
73
+ }
74
+
75
+ try {
76
+ const { botNickname, botAvatarUrl } = resolveHelpBotProfile(ctx, event);
77
+ const imagePath = await generateHelpImage({
78
+ helpService,
79
+ screenshotService,
80
+ miokiVersion,
81
+ miokuVersion,
82
+ botNickname,
83
+ botAvatarUrl,
84
+ targetPluginName:
85
+ intent.type === "detail" ? intent.pluginName : undefined,
86
+ });
87
+
88
+ if (!imagePath) {
89
+ await event.reply("生成帮助图片失败");
90
+ return;
91
+ }
92
+
93
+ await replyWithImage(event, ctx.segment, imagePath);
94
+ } catch (error) {
95
+ ctx.logger.error(`生成帮助图片失败: ${error}`);
96
+ await event.reply(`生成帮助图片失败: ${error}`);
97
+ }
98
+ });
99
+
100
+ return () => {
101
+ resetHelpRuntimeState();
102
+ ctx.logger.info("帮助插件已卸载");
103
+ };
104
+ },
105
+ });
106
+
107
+ export default helpPlugin;
package/package.json ADDED
@@ -0,0 +1,29 @@
1
+ {
2
+ "name": "mioku-plugin-help",
3
+ "version": "2.0.0",
4
+ "description": "帮助插件,使用截图服务生成美观的帮助图片",
5
+ "main": "index.ts",
6
+ "type": "module",
7
+ "keywords": [
8
+ "mioku"
9
+ ],
10
+ "repository": {
11
+ "type": "git",
12
+ "url": "https://github.com/mioku-lab/mioku.git"
13
+ },
14
+ "mioku": {
15
+ "services": [
16
+ "help",
17
+ "screenshot",
18
+ "config"
19
+ ]
20
+ },
21
+ "peerDependencies": {
22
+ "mioku": "^0.8.0",
23
+ "mioki": "^0.16.0"
24
+ },
25
+ "devDependencies": {
26
+ "mioku": "workspace:*",
27
+ "mioki": "^0.16.0"
28
+ }
29
+ }
package/runtime.ts ADDED
@@ -0,0 +1,25 @@
1
+ export interface HelpPluginRuntimeState {
2
+ miokiVersion?: string;
3
+ miokuVersion?: string;
4
+ }
5
+
6
+ const runtimeState: HelpPluginRuntimeState = {};
7
+
8
+ export function setHelpRuntimeState(
9
+ nextState: HelpPluginRuntimeState,
10
+ ): HelpPluginRuntimeState {
11
+ Object.assign(runtimeState, nextState);
12
+ return runtimeState;
13
+ }
14
+
15
+ export function getHelpRuntimeState(): HelpPluginRuntimeState {
16
+ return runtimeState;
17
+ }
18
+
19
+ export function resetHelpRuntimeState(): void {
20
+ for (const key of Object.keys(runtimeState) as Array<
21
+ keyof HelpPluginRuntimeState
22
+ >) {
23
+ delete runtimeState[key];
24
+ }
25
+ }