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
@@ -0,0 +1,383 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.buildBasicManifest = buildBasicManifest;
4
+ exports.buildBasicPackageJson = buildBasicPackageJson;
5
+ exports.buildBasicMain = buildBasicMain;
6
+ exports.buildGitignore = buildGitignore;
7
+ exports.buildBasicReadme = buildBasicReadme;
8
+ function buildBasicManifest(name) {
9
+ return {
10
+ id: name,
11
+ name,
12
+ version: '1.0.0',
13
+ displayName: name,
14
+ author: 'mulby',
15
+ description: '插件描述',
16
+ main: 'dist/main.js',
17
+ icon: 'icon.png',
18
+ features: [
19
+ {
20
+ code: 'main',
21
+ explain: '主功能',
22
+ cmds: [{ type: 'keyword', value: name }]
23
+ }
24
+ ]
25
+ };
26
+ }
27
+ function buildBasicPackageJson(name) {
28
+ return {
29
+ name,
30
+ version: '1.0.0',
31
+ scripts: {
32
+ build: 'esbuild src/main.ts --bundle --platform=node --outfile=dist/main.js',
33
+ dev: 'mulby dev',
34
+ pack: 'mulby pack'
35
+ },
36
+ devDependencies: {
37
+ esbuild: '^0.20.0',
38
+ typescript: '^5.0.0'
39
+ }
40
+ };
41
+ }
42
+ function buildBasicMain(name) {
43
+ return `interface PluginContext {
44
+ api: {
45
+ clipboard: {
46
+ readText: () => string
47
+ writeText: (text: string) => Promise<void>
48
+ readImage: () => Uint8Array | null
49
+ writeImage: (buffer: Uint8Array) => void
50
+ readFiles: () => Array<{ path: string; name: string; size: number; isDirectory: boolean }>
51
+ getFormat: () => 'text' | 'image' | 'files' | 'empty'
52
+ }
53
+ clipboardHistory: {
54
+ query: (options?: {
55
+ type?: 'text' | 'image' | 'files'
56
+ search?: string
57
+ favorite?: boolean
58
+ limit?: number
59
+ offset?: number
60
+ }) => Promise<any[]>
61
+ get: (id: string) => Promise<any>
62
+ copy: (id: string) => Promise<{ success: boolean; error?: string }>
63
+ toggleFavorite: (id: string) => Promise<{ success: boolean }>
64
+ delete: (id: string) => Promise<{ success: boolean }>
65
+ clear: () => Promise<{ success: boolean }>
66
+ stats: () => Promise<{ total: number; text: number; image: number; files: number; favorite: number }>
67
+ }
68
+ notification: {
69
+ show: (message: string, type?: string) => void
70
+ }
71
+ storage: {
72
+ get: (key: string) => unknown
73
+ set: (key: string, value: unknown) => unknown
74
+ remove: (key: string) => unknown
75
+ clear: () => unknown
76
+ keys: () => string[]
77
+ }
78
+ filesystem: {
79
+ readFile: (path: string, encoding?: 'utf-8' | 'base64') => Promise<string | Uint8Array>
80
+ writeFile: (path: string, data: string | Uint8Array, encoding?: 'utf-8' | 'base64') => Promise<void>
81
+ exists: (path: string) => Promise<boolean>
82
+ unlink: (path: string) => Promise<void>
83
+ readdir: (path: string) => Promise<string[]>
84
+ mkdir: (path: string) => Promise<void>
85
+ stat: (path: string) => Promise<any>
86
+ copy: (src: string, dest: string) => Promise<void>
87
+ move: (src: string, dest: string) => Promise<void>
88
+ extname: (path: string) => string
89
+ join: (...paths: string[]) => string
90
+ dirname: (path: string) => string
91
+ basename: (path: string, ext?: string) => string
92
+ }
93
+ http: {
94
+ request: (options: { url: string; method?: string; headers?: Record<string, string>; body?: string | object; timeout?: number }) => Promise<any>
95
+ get: (url: string, headers?: Record<string, string>) => Promise<any>
96
+ post: (url: string, body?: string | object, headers?: Record<string, string>) => Promise<any>
97
+ put: (url: string, body?: string | object, headers?: Record<string, string>) => Promise<any>
98
+ delete: (url: string, headers?: Record<string, string>) => Promise<any>
99
+ }
100
+ screen: {
101
+ getAllDisplays: () => Promise<any[]>
102
+ getPrimaryDisplay: () => Promise<any>
103
+ getDisplayNearestPoint: (point: { x: number; y: number }) => Promise<any>
104
+ getCursorScreenPoint: () => Promise<{ x: number; y: number }>
105
+ getSources: (options?: any) => Promise<any[]>
106
+ capture: (options?: any) => Promise<Uint8Array>
107
+ captureRegion: (region: { x: number; y: number; width: number; height: number }, options?: any) => Promise<Uint8Array>
108
+ getMediaStreamConstraints: (options: any) => Promise<any>
109
+ }
110
+ shell: {
111
+ openPath: (path: string) => Promise<string>
112
+ openExternal: (url: string) => Promise<void>
113
+ showItemInFolder: (path: string) => void
114
+ openFolder: (path: string) => Promise<string>
115
+ trashItem: (path: string) => Promise<void>
116
+ beep: () => void
117
+ runCommand: (input: {
118
+ command: string
119
+ args?: string[]
120
+ cwd?: string
121
+ env?: Record<string, string>
122
+ timeoutMs?: number
123
+ shell?: boolean
124
+ }) => Promise<any>
125
+ getRunCommandPolicy: () => Promise<{
126
+ enabled: boolean
127
+ requireConsent: boolean
128
+ allowShell: boolean
129
+ allowList?: string[]
130
+ denyList?: string[]
131
+ }>
132
+ listRunCommandAudit: (limit?: number) => Promise<any[]>
133
+ }
134
+ dialog: {
135
+ showOpenDialog: (options?: any) => Promise<string[]>
136
+ showSaveDialog: (options?: any) => Promise<string | null>
137
+ showMessageBox: (options: any) => Promise<{ response: number }>
138
+ showErrorBox: (title: string, content: string) => void
139
+ }
140
+ system: {
141
+ getSystemInfo: () => Promise<any>
142
+ getAppInfo: () => Promise<any>
143
+ getPath: (name: 'home' | 'appData' | 'userData' | 'temp' | 'desktop' | 'documents' | 'downloads' | 'music' | 'pictures' | 'videos') => Promise<string>
144
+ getEnv: (name: string) => Promise<string>
145
+ getIdleTime: () => Promise<number>
146
+ }
147
+ shortcut: Record<string, (...args: any[]) => any>
148
+ security: Record<string, (...args: any[]) => any>
149
+ media: {
150
+ getAccessStatus: (mediaType: 'microphone' | 'camera') => 'granted' | 'denied' | 'not-determined' | 'restricted' | 'unknown'
151
+ askForAccess: (mediaType: 'microphone' | 'camera') => Promise<boolean>
152
+ hasCameraAccess: () => Promise<boolean>
153
+ hasMicrophoneAccess: () => Promise<boolean>
154
+ }
155
+ power: {
156
+ getSystemIdleTime: () => number
157
+ getSystemIdleState: (idleThreshold: number) => 'active' | 'idle' | 'locked' | 'unknown'
158
+ isOnBatteryPower: () => boolean
159
+ getCurrentThermalState: () => 'unknown' | 'nominal' | 'fair' | 'serious' | 'critical'
160
+ }
161
+ tray: Record<string, (...args: any[]) => any>
162
+ network: {
163
+ isOnline: () => boolean
164
+ }
165
+ input: Record<string, (...args: any[]) => any>
166
+ permission: {
167
+ getStatus: (type: 'geolocation' | 'camera' | 'microphone' | 'notifications' | 'screen' | 'accessibility' | 'contacts' | 'calendar') => any
168
+ request: (type: 'geolocation' | 'camera' | 'microphone' | 'notifications' | 'screen' | 'accessibility' | 'contacts' | 'calendar') => Promise<any>
169
+ canRequest: (type: 'geolocation' | 'camera' | 'microphone' | 'notifications' | 'screen' | 'accessibility' | 'contacts' | 'calendar') => any
170
+ openSystemSettings: (type: 'geolocation' | 'camera' | 'microphone' | 'notifications' | 'screen' | 'accessibility' | 'contacts' | 'calendar') => Promise<any>
171
+ isAccessibilityTrusted: () => boolean
172
+ }
173
+ features: {
174
+ getFeatures: (codes?: string[]) => Array<{ code: string }>
175
+ setFeature: (feature: {
176
+ code: string
177
+ explain?: string
178
+ icon?: string
179
+ platform?: string | string[]
180
+ mode?: 'ui' | 'silent' | 'detached'
181
+ route?: string
182
+ mainHide?: boolean
183
+ mainPush?: boolean
184
+ cmds: Array<
185
+ | string
186
+ | { type: 'keyword'; value: string; explain?: string }
187
+ | { type: 'regex'; match: string; explain?: string; label?: string; minLength?: number; maxLength?: number }
188
+ | { type: 'files'; exts?: string[]; fileType?: 'file' | 'directory' | 'any'; match?: string; minLength?: number; maxLength?: number }
189
+ | { type: 'img'; exts?: string[] }
190
+ | { type: 'over'; label?: string; exclude?: string; minLength?: number; maxLength?: number }
191
+ >
192
+ }) => void
193
+ removeFeature: (code: string) => boolean
194
+ redirectHotKeySetting: (cmdLabel: string, autocopy?: boolean) => void
195
+ redirectAiModelsSetting: () => void
196
+ }
197
+ messaging: {
198
+ send: (targetPluginId: string, type: string, payload: unknown) => Promise<void>
199
+ broadcast: (type: string, payload: unknown) => Promise<void>
200
+ on: (handler: (message: { id: string; from: string; to?: string; type: string; payload: unknown; timestamp: number }) => void | Promise<void>) => void
201
+ off: (handler?: (message: any) => void) => void
202
+ }
203
+ scheduler: {
204
+ schedule: (task: {
205
+ name: string
206
+ type: 'once' | 'repeat' | 'delay'
207
+ callback: string
208
+ time?: number
209
+ cron?: string
210
+ delay?: number
211
+ payload?: any
212
+ maxRetries?: number
213
+ retryDelay?: number
214
+ timeout?: number
215
+ }) => Promise<any>
216
+ cancel: (taskId: string) => Promise<void>
217
+ pause: (taskId: string) => Promise<void>
218
+ resume: (taskId: string) => Promise<void>
219
+ get: (taskId: string) => Promise<any>
220
+ list: (filter?: { status?: string; type?: string; limit?: number }) => Promise<any[]>
221
+ getExecutions: (taskId: string, limit?: number) => Promise<any[]>
222
+ validateCron: (expression: string) => boolean
223
+ getNextCronTime: (expression: string, after?: Date) => Date
224
+ describeCron: (expression: string) => string
225
+ }
226
+ ai: {
227
+ call: (option: {
228
+ model?: string
229
+ messages: Array<{ role: 'system' | 'user' | 'assistant'; content?: string | Array<any> }>
230
+ tools?: Array<{ type: 'function'; function: { name: string; description?: string; parameters?: object } }>
231
+ capabilities?: string[]
232
+ internalTools?: string[]
233
+ toolingPolicy?: {
234
+ enableInternalTools?: boolean
235
+ capabilityAllowList?: string[]
236
+ capabilityDenyList?: string[]
237
+ }
238
+ mcp?: { mode?: 'off' | 'manual' | 'auto'; serverIds?: string[]; allowedToolIds?: string[] }
239
+ skills?: { mode?: 'off' | 'manual' | 'auto'; skillIds?: string[]; variables?: Record<string, string> }
240
+ params?: any
241
+ toolContext?: {
242
+ pluginName?: string
243
+ internalTag?: string
244
+ mcpScope?: { allowedServerIds?: string[]; allowedToolIds?: string[] }
245
+ }
246
+ maxToolSteps?: number
247
+ }, onChunk?: (chunk: any) => void) => Promise<{ role: 'assistant'; content?: string }>
248
+ allModels: () => Promise<any[]>
249
+ abort: (requestId: string) => void
250
+ skills: {
251
+ listEnabled: () => Promise<any[]>
252
+ previewForCall: (input: { option?: Record<string, any>; skillIds?: string[]; prompt?: string }) => Promise<any>
253
+ }
254
+ tokens: {
255
+ estimate: (input: { model?: string; messages: Array<any>; outputText?: string }) => Promise<{ inputTokens: number; outputTokens: number }>
256
+ }
257
+ attachments: {
258
+ upload: (input: { filePath?: string; buffer?: ArrayBuffer; mimeType: string; purpose?: string }) => Promise<any>
259
+ get: (attachmentId: string) => Promise<any>
260
+ delete: (attachmentId: string) => Promise<void>
261
+ uploadToProvider: (input: { attachmentId: string; model?: string; providerId?: string; purpose?: string }) => Promise<{
262
+ providerId: string
263
+ fileId: string
264
+ uri?: string
265
+ }>
266
+ }
267
+ images: {
268
+ generate: (input: { model: string; prompt: string; size?: string; count?: number }) => Promise<{
269
+ images: string[]
270
+ tokens: { inputTokens: number; outputTokens: number }
271
+ }>
272
+ generateStream: (
273
+ input: { model: string; prompt: string; size?: string; count?: number },
274
+ onChunk: (chunk: any) => void
275
+ ) => Promise<{ images: string[]; tokens: { inputTokens: number; outputTokens: number } }>
276
+ edit: (input: { model: string; imageAttachmentId: string; prompt: string }) => Promise<{
277
+ images: string[]
278
+ tokens: { inputTokens: number; outputTokens: number }
279
+ }>
280
+ }
281
+ }
282
+ }
283
+ input?: string
284
+ featureCode?: string
285
+ attachments?: Array<any>
286
+ }
287
+
288
+ export function onLoad() {
289
+ console.log('[${name}] 插件已加载')
290
+ }
291
+
292
+ export function onUnload() {
293
+ console.log('[${name}] 插件已卸载')
294
+ }
295
+
296
+ export function onEnable() {
297
+ console.log('[${name}] 插件已启用')
298
+ }
299
+
300
+ export function onDisable() {
301
+ console.log('[${name}] 插件已禁用')
302
+ }
303
+
304
+ export async function run(context: PluginContext) {
305
+ const { clipboard, notification } = context.api
306
+ const text = context.input || clipboard.readText()
307
+
308
+ // 在这里实现你的逻辑
309
+ const result = text.toUpperCase()
310
+
311
+ await clipboard.writeText(result)
312
+ notification.show('处理完成')
313
+ }
314
+
315
+ const plugin = { onLoad, onUnload, onEnable, onDisable, run }
316
+ export default plugin
317
+ `;
318
+ }
319
+ function buildGitignore() {
320
+ return `node_modules
321
+ dist
322
+ .DS_Store
323
+ *.log
324
+ `;
325
+ }
326
+ function buildBasicReadme(name) {
327
+ return `# ${name}
328
+
329
+ 插件描述
330
+
331
+ ## 功能特性
332
+
333
+ - 功能 1
334
+ - 功能 2
335
+ - 功能 3
336
+
337
+ ## 触发方式
338
+
339
+ - \`${name}\` - 主功能
340
+
341
+ ## 开发
342
+
343
+ ### 安装依赖
344
+
345
+ \`\`\`bash
346
+ npm install
347
+ \`\`\`
348
+
349
+ ### 开发模式
350
+
351
+ \`\`\`bash
352
+ npm run dev
353
+ \`\`\`
354
+
355
+ ### 构建
356
+
357
+ \`\`\`bash
358
+ npm run build
359
+ \`\`\`
360
+
361
+ ### 打包
362
+
363
+ \`\`\`bash
364
+ npm run pack
365
+ \`\`\`
366
+
367
+ ## 项目结构
368
+
369
+ \`\`\`
370
+ ${name}/
371
+ ├── manifest.json # 插件配置
372
+ ├── package.json
373
+ ├── src/
374
+ │ └── main.ts # 后端入口
375
+ ├── dist/ # 构建输出
376
+ └── icon.png # 插件图标
377
+ \`\`\`
378
+
379
+ ## 许可证
380
+
381
+ MIT License
382
+ `;
383
+ }
@@ -0,0 +1,72 @@
1
+ "use strict";
2
+ /**
3
+ * React 插件模板 - 后端代码生成器
4
+ * 包含:src/main.ts
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.buildBackendMain = buildBackendMain;
8
+ /**
9
+ * 生成后端 main.ts 内容
10
+ */
11
+ function buildBackendMain(name) {
12
+ return `/// <reference path="./types/mulby.d.ts" />
13
+ // PluginContext 类型由 src/types/mulby.d.ts 提供
14
+ type PluginContext = BackendPluginContext
15
+
16
+ export function onLoad() {
17
+ console.log('[${name}] 插件已加载')
18
+ }
19
+
20
+ export function onUnload() {
21
+ console.log('[${name}] 插件已卸载')
22
+ }
23
+
24
+ export function onEnable() {
25
+ console.log('[${name}] 插件已启用')
26
+ }
27
+
28
+ export function onDisable() {
29
+ console.log('[${name}] 插件已禁用')
30
+ }
31
+
32
+ export async function run(context: PluginContext) {
33
+ const { notification } = context.api
34
+ notification.show('插件已启动')
35
+ }
36
+
37
+ // 导出 host 方法供 UI 调用
38
+ // 支持三种导出方式(按优先级):
39
+ // 1. 直接导出函数: export async function myMethod(context, ...args) {}
40
+ // 2. host 对象(推荐): export const host = { myMethod(context, ...args) {} }
41
+ // 3. 其他对象: export const api = { myMethod(context, ...args) {} }
42
+
43
+ export const host = {
44
+ // 示例方法:处理数据
45
+ async processData(context: PluginContext, data: any) {
46
+ const { notification } = context.api
47
+ notification.show('处理数据中...')
48
+
49
+ // 处理逻辑
50
+ const result = {
51
+ ...data,
52
+ processed: true,
53
+ timestamp: Date.now()
54
+ }
55
+
56
+ return result
57
+ },
58
+
59
+ // 示例方法:获取配置
60
+ async getConfig(context: PluginContext) {
61
+ // 可以使用 context.api 中的所有 API
62
+ return {
63
+ version: '1.0.0',
64
+ settings: {}
65
+ }
66
+ }
67
+ }
68
+
69
+ const plugin = { onLoad, onUnload, onEnable, onDisable, run, host }
70
+ export default plugin
71
+ `;
72
+ }
@@ -0,0 +1,166 @@
1
+ "use strict";
2
+ /**
3
+ * React 插件模板 - 配置文件生成器
4
+ * 包含:manifest.json, package.json, tsconfig.json, vite.config.ts,
5
+ * postcss.config.mjs, tailwind.config.js, .gitignore
6
+ */
7
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ exports.buildReactManifest = buildReactManifest;
9
+ exports.buildReactPackageJson = buildReactPackageJson;
10
+ exports.buildTsConfig = buildTsConfig;
11
+ exports.buildViteConfig = buildViteConfig;
12
+ exports.buildPostcssConfig = buildPostcssConfig;
13
+ exports.buildTailwindConfig = buildTailwindConfig;
14
+ exports.buildGitignore = buildGitignore;
15
+ /**
16
+ * 生成 manifest.json 内容
17
+ */
18
+ function buildReactManifest(name) {
19
+ return {
20
+ id: name,
21
+ name,
22
+ version: '1.0.0',
23
+ author: 'mulby',
24
+ displayName: name,
25
+ description: '插件描述',
26
+ main: 'dist/main.js',
27
+ ui: 'ui/index.html',
28
+ icon: 'icon.png',
29
+ window: {
30
+ width: 800, // 默认宽度
31
+ height: 600, // 默认高度
32
+ minWidth: 400, // 最小宽度
33
+ minHeight: 300, // 最小高度
34
+ maxWidth: 1200, // 最大宽度
35
+ maxHeight: 900 // 最大高度
36
+ },
37
+ features: [
38
+ {
39
+ code: 'main',
40
+ explain: '主功能',
41
+ cmds: [{ type: 'keyword', value: name }]
42
+ }
43
+ ]
44
+ };
45
+ }
46
+ /**
47
+ * 生成 package.json 内容
48
+ */
49
+ function buildReactPackageJson(name) {
50
+ return {
51
+ name,
52
+ version: '1.0.0',
53
+ type: 'module',
54
+ scripts: {
55
+ dev: 'mulby dev',
56
+ build: 'npm run build:backend && npm run build:ui',
57
+ 'build:backend': 'esbuild src/main.ts --bundle --platform=node --outfile=dist/main.js',
58
+ 'build:ui': 'vite build',
59
+ pack: 'mulby pack'
60
+ },
61
+ dependencies: {
62
+ react: '^18.3.1',
63
+ 'react-dom': '^18.3.1',
64
+ 'lucide-react': '^0.562.0'
65
+ },
66
+ devDependencies: {
67
+ '@types/react': '^18.3.3',
68
+ '@types/react-dom': '^18.3.0',
69
+ '@vitejs/plugin-react': '^4.3.1',
70
+ autoprefixer: '^10.4.19',
71
+ postcss: '^8.4.38',
72
+ tailwindcss: '^3.4.4',
73
+ typescript: '^5.2.2',
74
+ vite: '^5.3.1'
75
+ }
76
+ };
77
+ }
78
+ /**
79
+ * 生成 tsconfig.json 内容
80
+ */
81
+ function buildTsConfig() {
82
+ return {
83
+ compilerOptions: {
84
+ target: 'ES2020',
85
+ useDefineForClassFields: true,
86
+ lib: ['ES2020', 'DOM', 'DOM.Iterable'],
87
+ module: 'ESNext',
88
+ skipLibCheck: true,
89
+ moduleResolution: 'bundler',
90
+ allowImportingTsExtensions: true,
91
+ resolveJsonModule: true,
92
+ isolatedModules: true,
93
+ noEmit: true,
94
+ jsx: 'react-jsx',
95
+ strict: true,
96
+ noUnusedLocals: true,
97
+ noUnusedParameters: true,
98
+ noFallthroughCasesInSwitch: true
99
+ },
100
+ include: ['src']
101
+ };
102
+ }
103
+ /**
104
+ * 生成 vite.config.ts 内容
105
+ */
106
+ function buildViteConfig() {
107
+ return `import { defineConfig } from 'vite'
108
+ import react from '@vitejs/plugin-react'
109
+ import path from 'path'
110
+
111
+ export default defineConfig({
112
+ plugins: [react()],
113
+ root: 'src/ui',
114
+ base: './',
115
+ build: {
116
+ outDir: '../../ui',
117
+ emptyOutDir: true
118
+ },
119
+ resolve: {
120
+ alias: {
121
+ '@': path.resolve(__dirname, 'src')
122
+ }
123
+ }
124
+ })
125
+ `;
126
+ }
127
+ /**
128
+ * 生成 postcss.config.mjs 内容
129
+ */
130
+ function buildPostcssConfig() {
131
+ return `export default {
132
+ plugins: {
133
+ tailwindcss: {},
134
+ autoprefixer: {},
135
+ },
136
+ }
137
+ `;
138
+ }
139
+ /**
140
+ * 生成 tailwind.config.js 内容
141
+ */
142
+ function buildTailwindConfig() {
143
+ return `/** @type {import('tailwindcss').Config} */
144
+ export default {
145
+ content: [
146
+ "./src/ui/index.html",
147
+ "./src/ui/**/*.{js,ts,jsx,tsx}",
148
+ ],
149
+ theme: {
150
+ extend: {},
151
+ },
152
+ plugins: [],
153
+ }
154
+ `;
155
+ }
156
+ /**
157
+ * 生成 .gitignore 内容
158
+ */
159
+ function buildGitignore() {
160
+ return `node_modules
161
+ dist
162
+ /ui/
163
+ .DS_Store
164
+ *.log
165
+ `;
166
+ }
@@ -0,0 +1,78 @@
1
+ "use strict";
2
+ /**
3
+ * React 插件模板 - 文档生成器
4
+ * 包含:README.md
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.buildReactReadme = buildReactReadme;
8
+ /**
9
+ * 生成 README.md 内容
10
+ */
11
+ function buildReactReadme(name) {
12
+ return `# ${name}
13
+
14
+ 插件描述
15
+
16
+ ## 功能特性
17
+
18
+ - 功能 1
19
+ - 功能 2
20
+ - 功能 3
21
+
22
+ ## 触发方式
23
+
24
+ - \`${name}\` - 主功能
25
+
26
+ ## 开发
27
+
28
+ ### 安装依赖
29
+
30
+ \`\`\`bash
31
+ npm install
32
+ \`\`\`
33
+
34
+ ### 开发模式
35
+
36
+ \`\`\`bash
37
+ npm run dev
38
+ \`\`\`
39
+
40
+ ### 构建
41
+
42
+ \`\`\`bash
43
+ npm run build
44
+ \`\`\`
45
+
46
+ ### 打包
47
+
48
+ \`\`\`bash
49
+ npm run pack
50
+ \`\`\`
51
+
52
+ ## 项目结构
53
+
54
+ \`\`\`
55
+ ${name}/
56
+ ├── manifest.json # 插件配置
57
+ ├── package.json
58
+ ├── src/
59
+ │ ├── main.ts # 后端入口
60
+ │ ├── ui/
61
+ │ │ ├── App.tsx # 主应用
62
+ │ │ ├── main.tsx # UI 入口
63
+ │ │ ├── index.html # HTML 模板
64
+ │ │ ├── styles.css # 全局样式
65
+ │ │ ├── hooks/
66
+ │ │ │ └── useMulby.ts # Mulby API Hook
67
+ │ └── types/
68
+ │ └── mulby.d.ts # 类型定义(含 BackendPluginContext)
69
+ ├── dist/ # 后端构建输出
70
+ ├── ui/ # UI 构建输出
71
+ └── icon.png # 插件图标
72
+ \`\`\`
73
+
74
+ ## 许可证
75
+
76
+ MIT License
77
+ `;
78
+ }