mulby-cli 1.1.5

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 (59) hide show
  1. package/PLUGIN_DEVELOP_PROMPT.md +1164 -0
  2. package/README.md +852 -0
  3. package/assets/default-icon.png +0 -0
  4. package/dist/commands/ai-session.js +44 -0
  5. package/dist/commands/build.js +111 -0
  6. package/dist/commands/config-ai.js +291 -0
  7. package/dist/commands/config.js +53 -0
  8. package/dist/commands/create/ai-create.js +183 -0
  9. package/dist/commands/create/assets.js +53 -0
  10. package/dist/commands/create/basic.js +72 -0
  11. package/dist/commands/create/index.js +73 -0
  12. package/dist/commands/create/react.js +136 -0
  13. package/dist/commands/create/templates/basic.js +383 -0
  14. package/dist/commands/create/templates/react/backend.js +72 -0
  15. package/dist/commands/create/templates/react/config.js +166 -0
  16. package/dist/commands/create/templates/react/docs.js +78 -0
  17. package/dist/commands/create/templates/react/hooks.js +469 -0
  18. package/dist/commands/create/templates/react/index.js +41 -0
  19. package/dist/commands/create/templates/react/types.js +1228 -0
  20. package/dist/commands/create/templates/react/ui.js +528 -0
  21. package/dist/commands/create/templates/react.js +1888 -0
  22. package/dist/commands/dev.js +141 -0
  23. package/dist/commands/pack.js +160 -0
  24. package/dist/commands/resume.js +97 -0
  25. package/dist/commands/test-ui.js +50 -0
  26. package/dist/index.js +71 -0
  27. package/dist/services/ai/PLUGIN_API.md +1102 -0
  28. package/dist/services/ai/PLUGIN_DEVELOP_PROMPT.md +1164 -0
  29. package/dist/services/ai/context-manager.js +639 -0
  30. package/dist/services/ai/index.js +88 -0
  31. package/dist/services/ai/knowledge.js +52 -0
  32. package/dist/services/ai/prompts.js +114 -0
  33. package/dist/services/ai/providers/base.js +38 -0
  34. package/dist/services/ai/providers/claude.js +284 -0
  35. package/dist/services/ai/providers/deepseek.js +28 -0
  36. package/dist/services/ai/providers/gemini.js +191 -0
  37. package/dist/services/ai/providers/glm.js +31 -0
  38. package/dist/services/ai/providers/minimax.js +27 -0
  39. package/dist/services/ai/providers/openai.js +177 -0
  40. package/dist/services/ai/tools.js +204 -0
  41. package/dist/services/ai-generator.js +968 -0
  42. package/dist/services/config-manager.js +117 -0
  43. package/dist/services/dependency-manager.js +236 -0
  44. package/dist/services/file-writer.js +66 -0
  45. package/dist/services/plan-adapter.js +244 -0
  46. package/dist/services/plan-command-handler.js +172 -0
  47. package/dist/services/plan-manager.js +502 -0
  48. package/dist/services/session-manager.js +113 -0
  49. package/dist/services/task-analyzer.js +136 -0
  50. package/dist/services/tui/index.js +57 -0
  51. package/dist/services/tui/store.js +123 -0
  52. package/dist/types/ai.js +172 -0
  53. package/dist/types/plan.js +2 -0
  54. package/dist/ui/Terminal.js +56 -0
  55. package/dist/ui/components/InputArea.js +176 -0
  56. package/dist/ui/components/LogArea.js +19 -0
  57. package/dist/ui/components/PlanPanel.js +69 -0
  58. package/dist/ui/components/SelectArea.js +13 -0
  59. package/package.json +45 -0
package/README.md ADDED
@@ -0,0 +1,852 @@
1
+ # Mulby CLI
2
+
3
+ Mulby 插件开发的命令行工具,帮助你快速创建、调试、构建和打包插件。
4
+
5
+ ## 目录
6
+
7
+ - [安装](#安装)
8
+ - [快速开始](#快速开始)
9
+ - [命令参考](#命令参考)
10
+ - [插件开发指南](#插件开发指南)
11
+ - [项目结构](#项目结构)
12
+ - [manifest.json 配置](#manifestjson-配置)
13
+ - [动态功能入口](#动态功能入口)
14
+ - [开发模式](#开发模式)
15
+ - [使用第三方库](#使用第三方库)
16
+ - [插件 API](#插件-api)
17
+ - [构建与打包](#构建与打包)
18
+ - [完整示例](#完整示例)
19
+ - [AI 任务规划](#ai-任务规划)
20
+ - [常见问题](#常见问题)
21
+
22
+ ---
23
+
24
+ ## 安装
25
+
26
+ ```bash
27
+ # 全局安装
28
+ npm install -g mulby-cli
29
+
30
+ # 或在项目中作为开发依赖
31
+ npm install -D mulby-cli
32
+ ```
33
+
34
+ ---
35
+
36
+ ## 快速开始
37
+
38
+ ### 5 分钟创建你的第一个插件
39
+
40
+ ```bash
41
+ # 1. 创建插件项目
42
+ mulby create my-plugin
43
+
44
+ # 2. 进入项目目录
45
+ cd my-plugin
46
+
47
+ # 3. 安装依赖
48
+ npm install
49
+
50
+ # 4. 启动开发模式
51
+ npm run dev
52
+
53
+ # 5. 构建插件
54
+ npm run build
55
+
56
+ # 6. 打包发布
57
+ npm run pack
58
+ ```
59
+
60
+ 执行完成后,你将得到一个 `my-plugin-1.0.0.inplugin` 文件,可以直接安装到 Mulby 中。
61
+
62
+ ---
63
+
64
+ ## 命令参考
65
+
66
+ ### `mulby create <name>`
67
+
68
+ 创建新的插件项目。
69
+
70
+ ```bash
71
+ # 创建 React 插件(默认,带 UI)
72
+ mulby create my-plugin
73
+
74
+ # 创建基础插件(无 UI)
75
+ mulby create my-plugin --template basic
76
+ ```
77
+
78
+ **选项:**
79
+
80
+ | 选项 | 说明 | 默认值 |
81
+ |------|------|--------|
82
+ | `-t, --template <type>` | 模板类型:`react` 或 `basic` | `react` |
83
+
84
+ ### `mulby dev`
85
+
86
+ 启动开发模式,支持热重载。
87
+
88
+ ```bash
89
+ # 在插件目录中运行
90
+ mulby dev
91
+
92
+ # 或通过 npm
93
+ npm run dev
94
+ ```
95
+
96
+ **功能:**
97
+ - 后端代码变化时自动重新构建
98
+ - 有 UI 的插件会自动启动 Vite 开发服务器
99
+ - 支持 sourcemap 便于调试
100
+
101
+ ### `mulby build`
102
+
103
+ 构建插件,生成生产环境代码。
104
+
105
+ ```bash
106
+ mulby build
107
+
108
+ # 或通过 npm
109
+ npm run build
110
+ ```
111
+
112
+ **输出:**
113
+ - 后端代码:`dist/main.js`(压缩后)
114
+ - UI 代码:`ui/` 目录
115
+
116
+ ### `mulby pack`
117
+
118
+ 将插件打包成 `.inplugin` 文件,用于发布和安装。
119
+
120
+ ```bash
121
+ mulby pack
122
+
123
+ # 或通过 npm
124
+ npm run pack
125
+ ```
126
+
127
+ **输出:** `<插件名>-<版本号>.inplugin`
128
+
129
+ > ⚠️ **注意:** 打包前请先运行 `mulby build` 或 `npm run build`
130
+
131
+ ---
132
+
133
+ ## 插件开发指南
134
+
135
+ ### 项目结构
136
+
137
+ #### React 插件(默认模板)
138
+
139
+ ```
140
+ my-plugin/
141
+ ├── package.json # npm 配置
142
+ ├── manifest.json # 插件配置(核心文件)
143
+ ├── tsconfig.json # TypeScript 配置
144
+ ├── vite.config.ts # Vite 配置
145
+ ├── icon.png # 插件图标
146
+ ├── src/
147
+ │ ├── main.ts # 后端逻辑(沙箱运行)
148
+ │ ├── types/
149
+ │ │ └── mulby.d.ts # API 类型定义
150
+ │ └── ui/ # React UI 源码
151
+ │ ├── index.html
152
+ │ ├── main.tsx
153
+ │ ├── App.tsx
154
+ │ ├── hooks/
155
+ │ │ └── useMulby.ts
156
+ │ └── styles.css
157
+ ├── dist/ # 后端构建输出
158
+ │ └── main.js
159
+ └── ui/ # UI 构建输出
160
+ ├── index.html
161
+ └── assets/
162
+ ```
163
+
164
+ #### 基础插件(无 UI)
165
+
166
+ ```
167
+ my-plugin/
168
+ ├── package.json
169
+ ├── manifest.json
170
+ ├── icon.png
171
+ └── src/
172
+ └── main.ts
173
+ ```
174
+
175
+ ---
176
+
177
+ ### manifest.json 配置
178
+
179
+ `manifest.json` 是插件的核心配置文件,定义了插件的基本信息和触发条件。
180
+
181
+ ```json
182
+ {
183
+ "id": "my-plugin",
184
+ "name": "my-plugin",
185
+ "version": "1.0.0",
186
+ "type": "utility",
187
+ "displayName": "我的插件",
188
+ "description": "插件功能描述",
189
+ "main": "dist/main.js",
190
+ "ui": "ui/index.html",
191
+ "icon": "icon.png",
192
+ "pluginSetting": {
193
+ "single": true,
194
+ "height": 400
195
+ },
196
+ "window": {
197
+ "width": 800,
198
+ "height": 600
199
+ },
200
+ "features": [
201
+ {
202
+ "code": "main",
203
+ "explain": "主功能",
204
+ "cmds": [
205
+ { "type": "keyword", "value": "myplugin" }
206
+ ]
207
+ }
208
+ ]
209
+ }
210
+ ```
211
+
212
+ #### 顶层字段说明
213
+
214
+ | 字段 | 类型 | 必需 | 说明 |
215
+ |------|------|------|------|
216
+ | `name` | string | ✅ | 插件唯一标识(小写字母、数字、连字符) |
217
+ | `version` | string | ✅ | 语义化版本 (x.y.z) |
218
+ | `type` | string | ❌ | 插件类型 (utility/productivity/developer/system/media/network/ai/entertainment/other) |
219
+ | `displayName` | string | ✅ | 用户看到的名称 |
220
+ | `description` | string | ✅ | 功能描述 |
221
+ | `id` | string | ✅ | 插件唯一 ID(推荐,优先于 name) |
222
+ | `main` | string | ✅ | 后端入口文件路径 |
223
+ | `ui` | string | ❌ | UI 文件路径(有界面时必填) |
224
+ | `icon` | string/object | ❌ | 插件图标 |
225
+ | `features` | array | ✅ | 功能入口列表 |
226
+ | `pluginSetting` | object | ❌ | 插件行为设置 (`single`, `height`) |
227
+ | `window` | object | ❌ | 独立窗口配置 (`width`, `height`, `minWidth`, etc.) |
228
+ | `author` | string | ❌ | 作者名 |
229
+ | `homepage` | string | ❌ | 项目主页 |
230
+ | `minAppVersion` | string | ❌ | 最低 Mulby 版本要求 |
231
+
232
+ #### 功能入口 (features)
233
+
234
+ 一个插件可以有多个功能入口,每个入口可以有不同的触发方式:
235
+
236
+ ```json
237
+ {
238
+ "features": [
239
+ {
240
+ "code": "format",
241
+ "explain": "格式化 JSON",
242
+ "cmds": [
243
+ { "type": "keyword", "value": "json" },
244
+ { "type": "keyword", "value": "格式化" },
245
+ { "type": "regex", "match": "^\\s*[{\\[]", "explain": "检测到 JSON" }
246
+ ]
247
+ },
248
+ {
249
+ "code": "minify",
250
+ "explain": "压缩 JSON",
251
+ "cmds": [
252
+ { "type": "keyword", "value": "json压缩" }
253
+ ]
254
+ }
255
+ ]
256
+ }
257
+ ```
258
+
259
+ | 字段 | 类型 | 必需 | 说明 |
260
+ |------|------|------|------|
261
+ | `code` | string | ✅ | 功能代码,传递给插件 |
262
+ | `explain` | string | ✅ | 功能说明,显示给用户 |
263
+ | `cmds` | array | ✅ | 触发命令列表 |
264
+ | `mode` | string | ❌ | `ui` / `silent` / `detached` |
265
+ | `route` | string | ❌ | UI 路由(用于子窗口或页内路由) |
266
+ | `icon` | string/object | ❌ | 功能独立图标 |
267
+ | `mainHide` | boolean | ❌ | 触发时隐藏主窗口 |
268
+ | `mainPush` | boolean | ❌ | 向搜索框推送内容 |
269
+
270
+
271
+ #### 触发命令类型 (cmds)
272
+
273
+ | type | 说明 | 可用字段 |
274
+ |------|------|----------|
275
+ | `keyword` | 关键词触发 | `value`: 关键词 |
276
+ | `regex` | 正则匹配 | `match`: 正则表达式, `explain`: 说明, `label?`: 指令名称, `minLength?`, `maxLength?` |
277
+ | `files` | 文件拖入 | `exts?`, `fileType?` (file/directory/any), `match?` (文件名正则), `minLength?`, `maxLength?` |
278
+ | `img` | 图片拖入 | `exts?` |
279
+ | `over` | 选中文本 | `label?` (指令名称), `exclude?` (排除正则), `minLength?`, `maxLength?` |
280
+
281
+ #### 图标配置
282
+
283
+ 支持三种格式:
284
+
285
+ ```json
286
+ // 1. 本地文件(推荐)
287
+ "icon": "icon.png"
288
+
289
+ // 2. URL
290
+ "icon": "https://example.com/icon.png"
291
+
292
+ // 3. 内联 SVG
293
+ "icon": "<svg viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"...\"/></svg>"
294
+
295
+ // 4. 对象形式(支持更多类型)
296
+ "icon": { "type": "file", "value": "assets/logo.png" }
297
+ "icon": { "type": "url", "value": "https://example.com/icon.png" }
298
+ ```
299
+
300
+ > 💡 **提示:** 未设置 `icon` 时,会自动尝试加载插件目录下的 `icon.png`
301
+
302
+ ---
303
+
304
+ ### 动态功能入口
305
+
306
+ 后端可以通过 `context.api.features` 动态添加/移除功能入口:
307
+
308
+ ```ts
309
+ export function onLoad(context?: any) {
310
+ const features = context?.api?.features
311
+ if (!features) return
312
+
313
+ features.setFeature({
314
+ code: 'dynamic:hello',
315
+ explain: '动态指令:hello',
316
+ mode: 'silent',
317
+ cmds: ['hello', { type: 'keyword', value: 'hi' }]
318
+ })
319
+ }
320
+ ```
321
+
322
+ ---
323
+
324
+ ### 开发模式
325
+
326
+ #### 启动开发服务器
327
+
328
+ ```bash
329
+ npm run dev
330
+ ```
331
+
332
+ 开发模式会:
333
+ 1. **监听后端代码变化** - `src/main.ts` 及其依赖变化时自动重新构建
334
+ 2. **启动 Vite 开发服务器** - 有 UI 时自动启动,支持 HMR(热模块替换)
335
+
336
+ #### 在 Mulby 中预览
337
+
338
+ 1. 打开 Mulby 设置
339
+ 2. 添加开发目录(插件项目路径)
340
+ 3. 输入关键词触发插件
341
+
342
+ ---
343
+
344
+ ### 使用第三方库
345
+
346
+ Mulby CLI 使用 **esbuild** 打包,会将所有依赖内联到 `dist/main.js` 中,因此你可以自由使用任何 npm 包。
347
+
348
+ #### 示例:使用 dayjs 处理日期
349
+
350
+ **1. 安装依赖**
351
+
352
+ ```bash
353
+ npm install dayjs
354
+ ```
355
+
356
+ **2. 在代码中使用**
357
+
358
+ ```typescript
359
+ // src/main.ts
360
+ import dayjs from 'dayjs'
361
+
362
+ module.exports = {
363
+ async run(context: any) {
364
+ const { clipboard, notification } = context.api
365
+ const text = context.input || await clipboard.readText()
366
+
367
+ // 使用 dayjs 格式化日期
368
+ const result = dayjs(text).format('YYYY-MM-DD HH:mm:ss')
369
+
370
+ await clipboard.writeText(result)
371
+ notification.show('日期格式化完成')
372
+ }
373
+ }
374
+ ```
375
+
376
+ **3. 构建**
377
+
378
+ ```bash
379
+ npm run build
380
+ ```
381
+
382
+ 构建后,`dayjs` 的代码会被内联到 `dist/main.js` 中,无需用户单独安装。
383
+
384
+ ---
385
+
386
+ ### 插件 API
387
+
388
+ 插件在沙箱中运行,通过 `context.api` 访问各种 API。
389
+
390
+ > 📚 **完整 API 参考请查看 [`PLUGIN_DEVELOP_PROMPT.md`](./PLUGIN_DEVELOP_PROMPT.md)**
391
+ >
392
+ > 该文件会在创建插件时自动生成,包含全部 28 个 API 模块的详细说明。
393
+
394
+ #### 可用 API 模块
395
+
396
+ | 模块 | 说明 | 常用方法 |
397
+ |------|------|----------|
398
+ | `clipboard` | 剪贴板 | `readText`, `writeText`, `readImage` |
399
+ | `filesystem` | 文件系统 | `readFile`, `writeFile`, `readdir` |
400
+ | `storage` | 数据存储 | `get`, `set`, `remove` |
401
+ | `dialog` | 系统对话框 | `showOpenDialog`, `showMessageBox` |
402
+ | `notification` | 通知 | `show` |
403
+ | `shell` | 系统外壳 | `openExternal`, `showItemInFolder` |
404
+ | `http` | 网络请求 | `get`, `post`, `request` |
405
+ | `system` | 系统信息 | `getSystemInfo`, `getPath` |
406
+ | `screen` | 屏幕控制 | `capture`, `colorPick`, `getAllDisplays` |
407
+ | `input` | 模拟输入 | `simulateKeyboardTap`, `hideMainWindowPasteText` |
408
+ | `window` | 窗口控制 | `hide`, `setSize`, `create` |
409
+ | `theme` | 主题 | `get`, `set` |
410
+ | `plugin` | 插件管理 | `run`, `redirect`, `outPlugin` |
411
+ | `features` | 动态功能 | `setFeature`, `removeFeature` |
412
+ | `shortcut` | 全局快捷键 | `register`, `unregister` |
413
+ | `permission` | 权限管理 | `request`, `getStatus` |
414
+ | `security` | 安全 | `encryptString`, `decryptString` |
415
+ | `tray` | 系统托盘 | `create`, `setIcon` |
416
+ | `menu` | 上下文菜单 | `showContextMenu` |
417
+ | `network` | 网络状态 | `isOnline` |
418
+ | `power` | 电源监控 | `getSystemIdleTime`, `onAC` |
419
+ | `media` | 媒体权限 | `hasCameraAccess` |
420
+ | `geolocation` | 地理位置 | `getCurrentPosition` |
421
+ | `tts` | 语音合成 | `speak` |
422
+ | `host` | 主机控制 | `invoke` |
423
+ | `sharp` | 图像处理 | `resize`, `toBuffer` |
424
+ | `ffmpeg` | 音视频处理 | `run`, `download` |
425
+ | `inbrowser` | 浏览器自动化 | `goto`, `click`, `evaluate` |
426
+
427
+ #### 常用 API 快速示例
428
+
429
+ ```typescript
430
+ // 剪贴板
431
+ const text = clipboard.readText()
432
+ await clipboard.writeText('Hello')
433
+
434
+ // 通知
435
+ notification.show('操作成功')
436
+
437
+ // 存储
438
+ await storage.set('key', { data: 'value' })
439
+ const data = await storage.get('key')
440
+
441
+ // 文件系统
442
+ const content = filesystem.readFile('/path/file.txt', 'utf-8')
443
+
444
+ // HTTP 请求
445
+ const response = await http.post('https://api.example.com', { key: 'value' })
446
+
447
+ // 屏幕取色
448
+ const color = await screen.colorPick()
449
+
450
+ // 浏览器自动化
451
+ await inbrowser.goto('https://google.com')
452
+ await inbrowser.type('input[name="q"]', 'mulby')
453
+ await inbrowser.click('input[name="btnK"]')
454
+ ```
455
+
456
+ ---
457
+
458
+ ### 插件 UI
459
+
460
+ #### 在 UI 中访问 API
461
+
462
+ UI 通过 `window.mulby` 全局对象访问 API:
463
+
464
+ ```tsx
465
+ // src/ui/App.tsx
466
+ import { useEffect, useState } from 'react'
467
+
468
+ export default function App() {
469
+ const [input, setInput] = useState('')
470
+
471
+ // 接收插件初始化数据
472
+ useEffect(() => {
473
+ window.mulby?.onPluginInit?.((data) => {
474
+ if (data.input) setInput(data.input)
475
+ })
476
+ }, [])
477
+
478
+ const handleProcess = async () => {
479
+ const result = input.toUpperCase()
480
+ // 复制到剪贴板
481
+ await window.mulby?.clipboard?.writeText(result)
482
+ // 显示通知
483
+ window.mulby?.notification?.show('已复制到剪贴板')
484
+ }
485
+
486
+ return (
487
+ <div>
488
+ <textarea value={input} onChange={(e) => setInput(e.target.value)} />
489
+ <button onClick={handleProcess}>处理</button>
490
+ </div>
491
+ )
492
+ }
493
+ ```
494
+
495
+ #### 主题适配
496
+
497
+ 插件 UI 应跟随 Mulby 主题:
498
+
499
+ ```tsx
500
+ // 获取初始主题
501
+ function getInitialTheme(): 'light' | 'dark' {
502
+ const params = new URLSearchParams(window.location.search)
503
+ return (params.get('theme') as 'light' | 'dark') || 'light'
504
+ }
505
+
506
+ // 监听主题变化
507
+ useEffect(() => {
508
+ window.mulby?.onThemeChange?.((theme) => {
509
+ document.documentElement.classList.toggle('dark', theme === 'dark')
510
+ })
511
+ }, [])
512
+ ```
513
+
514
+ ---
515
+
516
+ ### 生命周期钩子
517
+
518
+ 插件支持生命周期钩子函数:
519
+
520
+ ```typescript
521
+ module.exports = {
522
+ // 插件加载时调用
523
+ onLoad() {
524
+ console.log('插件已加载')
525
+ },
526
+
527
+ // 插件卸载时调用
528
+ onUnload() {
529
+ console.log('插件即将卸载')
530
+ },
531
+
532
+ // 插件启用时调用
533
+ onEnable() {
534
+ console.log('插件已启用')
535
+ },
536
+
537
+ // 插件禁用时调用
538
+ onDisable() {
539
+ console.log('插件已禁用')
540
+ },
541
+
542
+ // 主执行函数
543
+ async run(context) {
544
+ // 插件主逻辑
545
+ }
546
+ }
547
+ ```
548
+
549
+ | 钩子 | 触发时机 | 用途 |
550
+ |------|----------|------|
551
+ | `onLoad` | 插件加载时 | 初始化资源、注册服务 |
552
+ | `onUnload` | 插件卸载时 | 清理资源、保存状态 |
553
+ | `onEnable` | 插件启用时 | 恢复服务、重新注册 |
554
+ | `onDisable` | 插件禁用时 | 暂停服务、释放资源 |
555
+
556
+ ---
557
+
558
+ ## 构建与打包
559
+
560
+ ### 构建流程
561
+
562
+ ```bash
563
+ # 构建生产版本
564
+ npm run build
565
+ ```
566
+
567
+ 构建命令会:
568
+ 1. 使用 esbuild 打包后端代码到 `dist/main.js`(压缩)
569
+ 2. 使用 Vite 构建 UI 到 `ui/` 目录(如果有 UI)
570
+
571
+ ### 打包发布
572
+
573
+ ```bash
574
+ # 打包成 .inplugin 文件
575
+ npm run pack
576
+ ```
577
+
578
+ 生成的 `.inplugin` 文件实际上是 ZIP 格式,包含:
579
+
580
+ ```
581
+ my-plugin-1.0.0.inplugin
582
+ ├── manifest.json # 插件配置
583
+ ├── main.js # 打包后的后端代码
584
+ ├── icon.png # 图标(可选)
585
+ └── ui/ # UI 资源(可选)
586
+ ├── index.html
587
+ └── assets/
588
+ ```
589
+
590
+ ### 安装插件
591
+
592
+ 用户可以通过以下方式安装 `.inplugin` 文件:
593
+
594
+ 1. **双击安装** - 直接双击 `.inplugin` 文件
595
+ 2. **拖拽安装** - 将文件拖入 Mulby 窗口
596
+ 3. **命令安装** - `mulby install ./my-plugin.inplugin`
597
+
598
+ ---
599
+
600
+ ## 完整示例
601
+
602
+ ### 示例 1:JSON 格式化插件(无 UI)
603
+
604
+ ```bash
605
+ mulby create json-formatter --template basic
606
+ cd json-formatter
607
+ ```
608
+
609
+ **manifest.json:**
610
+ ```json
611
+ {
612
+ "name": "json-formatter",
613
+ "version": "1.0.0",
614
+ "displayName": "JSON 格式化",
615
+ "description": "格式化或压缩 JSON 数据",
616
+ "main": "dist/main.js",
617
+ "icon": "<svg viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M5 3h2v2H5v5a2 2 0 01-2 2 2 2 0 012 2v5h2v2H5c-1.1 0-2-.9-2-2v-4a2 2 0 00-2-2H0v-2h1a2 2 0 002-2V5a2 2 0 012-2zm14 0a2 2 0 012 2v4a2 2 0 002 2h1v2h-1a2 2 0 00-2 2v4a2 2 0 01-2 2h-2v-2h2v-5a2 2 0 012-2 2 2 0 01-2-2V5h-2V3h2z\"/></svg>",
618
+ "features": [
619
+ {
620
+ "code": "format",
621
+ "explain": "格式化 JSON",
622
+ "cmds": [
623
+ { "type": "keyword", "value": "json" },
624
+ { "type": "regex", "match": "^\\s*[{\\[]", "explain": "检测到 JSON" }
625
+ ]
626
+ }
627
+ ]
628
+ }
629
+ ```
630
+
631
+ **src/main.ts:**
632
+ ```typescript
633
+ interface PluginContext {
634
+ api: {
635
+ clipboard: {
636
+ readText: () => string
637
+ writeText: (text: string) => Promise<void>
638
+ }
639
+ notification: {
640
+ show: (message: string, type?: string) => void
641
+ }
642
+ }
643
+ input?: string
644
+ }
645
+
646
+ export async function run(context: PluginContext) {
647
+ const { clipboard, notification } = context.api
648
+ const text = context.input || clipboard.readText()
649
+
650
+ try {
651
+ const obj = JSON.parse(text)
652
+ const formatted = JSON.stringify(obj, null, 2)
653
+ await clipboard.writeText(formatted)
654
+ notification.show('JSON 格式化成功')
655
+ } catch (e) {
656
+ notification.show('无效的 JSON', 'error')
657
+ }
658
+ }
659
+
660
+ export default { run }
661
+ ```
662
+
663
+ ### 示例 2:翻译插件(带 UI)
664
+
665
+ ```bash
666
+ mulby create translator
667
+ cd translator
668
+ npm install
669
+ ```
670
+
671
+ **manifest.json:**
672
+ ```json
673
+ {
674
+ "name": "translator",
675
+ "version": "1.0.0",
676
+ "displayName": "快速翻译",
677
+ "description": "中英文互译",
678
+ "main": "dist/main.js",
679
+ "ui": "ui/index.html",
680
+ "features": [
681
+ {
682
+ "code": "translate",
683
+ "explain": "翻译文本",
684
+ "cmds": [
685
+ { "type": "keyword", "value": "fy" },
686
+ { "type": "keyword", "value": "翻译" }
687
+ ]
688
+ }
689
+ ]
690
+ }
691
+ ```
692
+
693
+ **src/main.ts:**
694
+ ```typescript
695
+ export function onLoad() {
696
+ console.log('翻译插件已加载')
697
+ }
698
+
699
+ export async function run() {
700
+ // UI 插件通常不需要在 run 中做太多事
701
+ // 主要逻辑在 UI 中处理
702
+ }
703
+
704
+ export default { onLoad, run }
705
+ ```
706
+
707
+ **src/ui/App.tsx:**
708
+ ```tsx
709
+ import { useEffect, useState } from 'react'
710
+
711
+ export default function App() {
712
+ const [input, setInput] = useState('')
713
+ const [output, setOutput] = useState('')
714
+ const [loading, setLoading] = useState(false)
715
+
716
+ useEffect(() => {
717
+ window.mulby?.onPluginInit?.((data) => {
718
+ if (data.input) setInput(data.input)
719
+ })
720
+ }, [])
721
+
722
+ const handleTranslate = async () => {
723
+ if (!input.trim()) return
724
+
725
+ setLoading(true)
726
+ try {
727
+ // 调用翻译 API
728
+ const response = await fetch('https://api.translate.com/v1/translate', {
729
+ method: 'POST',
730
+ headers: { 'Content-Type': 'application/json' },
731
+ body: JSON.stringify({ text: input, from: 'auto', to: 'en' })
732
+ })
733
+ const data = await response.json()
734
+ setOutput(data.translation)
735
+ } catch (error) {
736
+ window.mulby?.notification?.show('翻译失败', 'error')
737
+ } finally {
738
+ setLoading(false)
739
+ }
740
+ }
741
+
742
+ const handleCopy = async () => {
743
+ await window.mulby?.clipboard?.writeText(output)
744
+ window.mulby?.notification?.show('已复制')
745
+ }
746
+
747
+ return (
748
+ <div className="app">
749
+ <div className="titlebar">快速翻译</div>
750
+ <div className="container">
751
+ <textarea
752
+ value={input}
753
+ onChange={(e) => setInput(e.target.value)}
754
+ placeholder="输入要翻译的文本..."
755
+ />
756
+ <button onClick={handleTranslate} disabled={loading}>
757
+ {loading ? '翻译中...' : '翻译'}
758
+ </button>
759
+ <textarea
760
+ value={output}
761
+ readOnly
762
+ placeholder="翻译结果..."
763
+ />
764
+ {output && <button onClick={handleCopy}>复制结果</button>}
765
+ </div>
766
+ </div>
767
+ )
768
+ }
769
+ ```
770
+
771
+ ---
772
+
773
+ ## AI 任务规划
774
+
775
+ Mulby CLI 内置了智能任务规划系统,自动识别复杂任务并帮助你分解执行。
776
+
777
+ ### 工作流程
778
+
779
+ 1. **自动识别** - AI 分析你的任务,判断是否需要规划
780
+ 2. **生成计划** - 如果是复杂任务,AI 自动生成 todo list
781
+ 3. **逐步执行** - 按照计划执行,完成一项勾选一项
782
+ 4. **进度保存** - 中途退出自动保存,下次可继续
783
+
784
+ ### 使用方式
785
+
786
+ **自动触发(推荐)**
787
+
788
+ 输入任务后,如果 AI 判断是复杂任务,会提示:
789
+
790
+ ```
791
+ 📊 复杂任务(预估 5 个步骤)
792
+ 原因:需要设计数据库、实现 API、编写前端页面
793
+
794
+ > 创建计划后执行 (推荐)
795
+ 直接执行
796
+ ```
797
+
798
+ 选择「创建计划后执行」,AI 会自动:
799
+ - 列出具体步骤
800
+ - 按顺序执行
801
+ - 完成后自动勾选
802
+
803
+ **手动触发**
804
+
805
+ ```bash
806
+ # 强制使用计划模式
807
+ /plan 实现用户登录功能
808
+
809
+ # 查看当前计划状态
810
+ /plan
811
+ ```
812
+
813
+ ### 示例
814
+
815
+ ```
816
+ 用户: /plan 实现一个 JSON 格式化插件
817
+
818
+ AI: 好的,让我为这个任务创建计划:
819
+
820
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
821
+ 📋 实现 JSON 格式化插件
822
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
823
+ ███████████░░░░░░░░░░░░░░░░░░░ 2/5 (40%)
824
+
825
+ ✅ 创建插件基础结构
826
+ ✅ 实现 JSON 解析和格式化
827
+ 🔄 添加错误处理
828
+ ⏸️ 编写 UI 界面
829
+ ⏸️ 测试和优化
830
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
831
+ ```
832
+
833
+ ---
834
+
835
+ ## 常见问题
836
+
837
+ ### Q: 如何调试插件?
838
+
839
+ A: 使用 `npm run dev` 启动开发模式,后端代码支持 sourcemap。可以在 Mulby 的开发者工具中查看日志和调试。
840
+
841
+ ### Q: 为什么我的第三方库不能用?
842
+
843
+ A: 确保依赖已安装(`npm install`)并且使用 `npm run build` 构建。CLI 会自动将依赖打包到 `dist/main.js` 中。
844
+
845
+ ### Q: 如何更新已安装的插件?
846
+
847
+ A: 修改 `manifest.json` 中的 `version` 字段,重新打包后安装即可。Mulby 会检测版本变化并更新。
848
+
849
+ ### Q: 插件可以访问系统命令吗?
850
+
851
+ A: 前端通过 `window.mulby.shell` 调用系统能力;后端运行在沙箱中,仅能使用 `context.api` 暴露的接口。具体能力以 `mulby.d.ts` 为准。
852
+