@dimina-kit/devtools 0.3.1-dev.20260517100756 → 0.3.1-dev.20260518114324

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 (83) hide show
  1. package/README.md +138 -7
  2. package/dist/main/app/app.js +8 -0
  3. package/dist/main/index.bundle.js +374 -58
  4. package/dist/main/ipc/projects.d.ts +3 -1
  5. package/dist/main/ipc/projects.js +88 -4
  6. package/dist/main/ipc/session.js +9 -1
  7. package/dist/main/ipc/settings.js +8 -6
  8. package/dist/main/menu/index.js +11 -0
  9. package/dist/main/services/projects/builtin-templates.d.ts +3 -0
  10. package/dist/main/services/projects/builtin-templates.js +24 -0
  11. package/dist/main/services/projects/create-project-service.d.ts +7 -0
  12. package/dist/main/services/projects/create-project-service.js +84 -0
  13. package/dist/main/services/projects/index.d.ts +7 -0
  14. package/dist/main/services/projects/index.js +9 -0
  15. package/dist/main/services/projects/local-provider.d.ts +3 -0
  16. package/dist/main/services/projects/local-provider.js +25 -0
  17. package/dist/main/services/projects/templates.d.ts +21 -0
  18. package/dist/main/services/projects/templates.js +39 -0
  19. package/dist/main/services/projects/thumbnail.d.ts +8 -0
  20. package/dist/main/services/projects/thumbnail.js +37 -0
  21. package/dist/main/services/projects/types.d.ts +118 -0
  22. package/dist/main/services/projects/types.js +19 -0
  23. package/dist/main/services/settings/index.d.ts +7 -0
  24. package/dist/main/services/settings/index.js +4 -0
  25. package/dist/main/services/workbench-context.d.ts +35 -0
  26. package/dist/main/services/workbench-context.js +9 -0
  27. package/dist/main/services/workspace/workspace-service.d.ts +9 -7
  28. package/dist/main/services/workspace/workspace-service.js +81 -9
  29. package/dist/main/utils/sender-policy.d.ts +7 -5
  30. package/dist/main/utils/sender-policy.js +8 -6
  31. package/dist/main/windows/main-window/create.js +1 -1
  32. package/dist/preload/runtime/custom-apis.js +32 -3
  33. package/dist/preload/windows/simulator.js +26 -5
  34. package/dist/renderer/assets/index-Czz_bp6b.js +46 -0
  35. package/dist/renderer/assets/{input-C5M5Wxn6.js → input-DqVQNCx_.js} +2 -2
  36. package/dist/renderer/assets/{ipc-transport-CUsl-fS2.js → ipc-transport-CCHrCtDr.js} +2 -2
  37. package/dist/renderer/assets/ipc-transport-DqbRdZNO.css +1 -0
  38. package/dist/renderer/assets/{popover-BSBPVO0o.js → popover-BRg4XI_w.js} +2 -2
  39. package/dist/renderer/assets/{select-B1tF3UAc.js → select-CvILHHZU.js} +2 -2
  40. package/dist/renderer/assets/{settings-7w54H6p-.js → settings-BFNfnYvU.js} +2 -2
  41. package/dist/renderer/assets/{settings-api-BjJalghB.js → settings-api-DOAgmBst.js} +2 -2
  42. package/dist/renderer/assets/{workbenchSettings-q2_-nc8t.js → workbenchSettings-DjVMgMMH.js} +2 -2
  43. package/dist/renderer/entries/main/index.html +5 -5
  44. package/dist/renderer/entries/popover/index.html +5 -5
  45. package/dist/renderer/entries/settings/index.html +5 -5
  46. package/dist/renderer/entries/workbench-settings/index.html +4 -4
  47. package/dist/shared/ipc-channels.d.ts +20 -1
  48. package/dist/shared/ipc-channels.js +27 -0
  49. package/dist/shared/ipc-schemas.d.ts +5 -0
  50. package/dist/shared/ipc-schemas.js +5 -0
  51. package/dist/shared/types.d.ts +80 -0
  52. package/package.json +9 -4
  53. package/templates/blank/app.js +6 -0
  54. package/templates/blank/app.json +11 -0
  55. package/templates/blank/app.wxss +5 -0
  56. package/templates/blank/pages/index/index.js +6 -0
  57. package/templates/blank/pages/index/index.json +3 -0
  58. package/templates/blank/pages/index/index.wxml +3 -0
  59. package/templates/blank/pages/index/index.wxss +11 -0
  60. package/templates/blank/project.config.json +13 -0
  61. package/templates/blank/sitemap.json +9 -0
  62. package/templates/taro-todo/app.js +1 -0
  63. package/templates/taro-todo/app.json +1 -0
  64. package/templates/taro-todo/app.wxss +1 -0
  65. package/templates/taro-todo/base.wxml +851 -0
  66. package/templates/taro-todo/common.js +1 -0
  67. package/templates/taro-todo/comp.js +1 -0
  68. package/templates/taro-todo/comp.json +1 -0
  69. package/templates/taro-todo/comp.wxml +2 -0
  70. package/templates/taro-todo/custom-wrapper.js +1 -0
  71. package/templates/taro-todo/custom-wrapper.json +1 -0
  72. package/templates/taro-todo/custom-wrapper.wxml +4 -0
  73. package/templates/taro-todo/pages/index/index.js +2 -0
  74. package/templates/taro-todo/pages/index/index.json +1 -0
  75. package/templates/taro-todo/pages/index/index.wxml +2 -0
  76. package/templates/taro-todo/pages/index/index.wxss +1 -0
  77. package/templates/taro-todo/project.config.json +44 -0
  78. package/templates/taro-todo/runtime.js +1 -0
  79. package/templates/taro-todo/taro.js +2 -0
  80. package/templates/taro-todo/utils.wxs +39 -0
  81. package/templates/taro-todo/vendors.js +2 -0
  82. package/dist/renderer/assets/index-DW_0thr-.js +0 -46
  83. package/dist/renderer/assets/ipc-transport-CltRuvhi.css +0 -1
package/README.md CHANGED
@@ -284,6 +284,126 @@ src/
284
284
 
285
285
  ---
286
286
 
287
+ ## Embedding & Extending the Project Panel
288
+
289
+ 宿主(如 qdmp)通过 `createWorkbenchApp({...})` 嵌入 devtools 时,可对项目面板做三个正交扩展:
290
+
291
+ | 扩展点 | 用途 |
292
+ | --- | --- |
293
+ | `projectsProvider` | 接管项目列表存储 —— 替换默认 `<userData>/dimina-projects.json`,对接 qdmp 后台 / IDE workspace / 远端工程库 |
294
+ | `projectTemplates` + `builtinTemplates` | 注入/覆盖/裁剪"新建项目"模板列表(同 id 覆盖内置;`builtinTemplates` 控制内置策略) |
295
+ | `customCreateProjectDialog` | 用宿主自家页面替换内置"新建项目"对话框(main 进程 hook,可 `new BrowserWindow` 加载任意 URL,通过 IPC/postMessage 回传结果) |
296
+
297
+ ### 何时需要哪个扩展点
298
+
299
+ | 场景 | 需要的扩展点 |
300
+ | --- | --- |
301
+ | 项目列表来自 qdmp 后台 / 团队工程库 | `projectsProvider` |
302
+ | 仅替换可选模板(e.g. 只提供 taro / qdmp 自家脚手架) | `projectTemplates` + `builtinTemplates` |
303
+ | 创建项目流程要走宿主自己的 wizard / 登录态 | `customCreateProjectDialog` |
304
+
305
+ ### 最小示例
306
+
307
+ ```typescript
308
+ import { createWorkbenchApp } from '@dimina-kit/devtools/app'
309
+ import type { ProjectsProvider, ProjectTemplate } from '@dimina-kit/devtools/projects-provider'
310
+ import { BrowserWindow } from 'electron'
311
+
312
+ const provider: ProjectsProvider = {
313
+ async listProjects() {
314
+ return await qdmp.api.listProjects()
315
+ },
316
+ async validateProjectDir(dirPath) {
317
+ return (await qdmp.api.isMiniApp(dirPath)) ? null : '不是合法的小程序工程'
318
+ },
319
+ async addProject(dirPath) {
320
+ return await qdmp.api.addProject(dirPath)
321
+ },
322
+ async removeProject(dirPath) {
323
+ await qdmp.api.removeProject(dirPath)
324
+ },
325
+ async updateLastOpened(dirPath) {
326
+ await qdmp.api.touchLastOpened(dirPath)
327
+ },
328
+ async getCompileConfig(dirPath) {
329
+ return await qdmp.api.getCompileConfig(dirPath)
330
+ },
331
+ async saveCompileConfig(dirPath, cfg) {
332
+ await qdmp.api.saveCompileConfig(dirPath, cfg)
333
+ },
334
+ // 缩略图走云端存储——dataUrl 形如 'data:image/png;base64,...'
335
+ async saveThumbnail(dirPath, imageDataUrl) {
336
+ await qdmp.api.uploadThumbnail(dirPath, imageDataUrl)
337
+ },
338
+ async getThumbnail(dirPath) {
339
+ return await qdmp.api.fetchThumbnail(dirPath)
340
+ },
341
+ }
342
+
343
+ const qdmpBlank: ProjectTemplate = {
344
+ id: 'blank', // 同 id 覆盖内置 blank
345
+ name: 'qdmp 空白工程',
346
+ description: '由 qdmp 维护的官方空白模板',
347
+ source: { type: 'directory', path: '/abs/path/to/template' },
348
+ }
349
+
350
+ createWorkbenchApp({
351
+ projectsProvider: provider,
352
+ projectTemplates: [qdmpBlank],
353
+ builtinTemplates: ['taro-todo'], // 只保留 taro-todo,干掉默认 blank
354
+ customCreateProjectDialog: async ({ parentWindow }) => {
355
+ const win = new BrowserWindow({ parent: parentWindow, modal: true, width: 720, height: 520 })
356
+ await win.loadURL('https://qdmp.example.com/devtools/new-project')
357
+ return await new Promise((resolve) => {
358
+ win.webContents.ipc.once('qdmp:create-project:done', (_e, payload) => {
359
+ win.close()
360
+ // payload 三选一(CustomCreateProjectDialogResult):
361
+ // null → 用户取消
362
+ // CreateProjectInput → 让 devtools 在本地物化模板并注册到 provider
363
+ // { ready: Project } → 宿主后端已经创建好,devtools 直接刷新列表
364
+ resolve(payload ?? null)
365
+ })
366
+ win.on('closed', () => resolve(null))
367
+ })
368
+ },
369
+ }).start()
370
+ ```
371
+
372
+ ### `customCreateProjectDialog` 返回值
373
+
374
+ `hook` 返回 `CustomCreateProjectDialogResult`,三种情形分别对应不同后续动作:
375
+
376
+ | 返回 | 行为 |
377
+ | --- | --- |
378
+ | `null` | 用户取消,无副作用 |
379
+ | `CreateProjectInput`(`{ name, path, templateId?, extra? }`) | devtools 在本地拷贝/生成模板 → 改写 `project.config.json` → `provider.addProject(path)`;适合"只想换 UI 但物化由 devtools 兜底" |
380
+ | `{ ready: Project }` | devtools 跳过物化,只刷新列表并打开该项目;适合宿主后端已经远端创建好项目,本地完全无需落盘 |
381
+
382
+ 物化失败(路径已存在/模板缺失/`provider.addProject` reject)会经 native dialog 弹出错误,再 reject 给渲染层;宿主端无需自己 toast。
383
+
384
+ ### 内置模板
385
+
386
+ devtools 自带两个 `source`-style 模板,位于 `packages/devtools/templates/`:
387
+
388
+ - `blank` — 最小空白小程序骨架(pages/index + app.js/json/wxss + project.config.json,约 8 个文件)
389
+ - `taro-todo` — 复制自 `dimina/fe/example/taro-todo`,作为 Taro 编译产物的端到端演示工程
390
+
391
+ `builtinTemplates: 'none'` 排除全部内置;`builtinTemplates: ['taro-todo']` 仅保留指定 id;`projectTemplates` 同 id 注入会覆盖(例如上文 `qdmpBlank` 覆盖了内置 `blank`)。
392
+
393
+ ### Provider 部分实现 / fallback 行为
394
+
395
+ `ProjectsProvider` 的多数方法是可选的;当宿主只实现 `listProjects` / `addProject` / `removeProject` 时:
396
+
397
+ - `validateProjectDir` 缺省 → 返回 `null`(不校验)
398
+ - `updateLastOpened` 缺省 → 静默 no-op,"最近"排序退化为 `listProjects` 返回顺序
399
+ - `getCompileConfig` 缺省 → 返回 `DEFAULT_COMPILE_CONFIG`(`{ startPage: '', scene: 1001, queryParams: [] }`)
400
+ - `saveCompileConfig` 缺省 → 静默 no-op,编译配置面板的编辑不会持久化
401
+ - `saveThumbnail` / `getThumbnail` 缺省 → save 静默 no-op,get 返回 `null`;项目卡缩略图不显示。实现这两个方法可让远端项目用云端缩略图(详见示例)
402
+
403
+ > 完整契约、参数语义和默认值见 `src/main/services/projects/types.ts` 的 JSDoc,那是 source of truth。
404
+
405
+ ---
406
+
287
407
  ## CompilationAdapter
288
408
 
289
409
  实现此接口接入自定义构建流程:
@@ -379,26 +499,37 @@ launch({ preloadPath: '/absolute/path/to/my-preload.js' })
379
499
 
380
500
  > ⚠️ 使用本功能要求模拟器 preload 调用 `installCustomApisBridge()`(详见上方 "Preload Instrumentation")。内置 preload 已包含此调用;若你用了自定义 preload 又忘记调用,注册的 API 在小程序运行时**没有任何反应**,且不会报错。
381
501
 
502
+ ### 命名约定
503
+
504
+ `name` 是 dimina service 层 `invokeAPI(name, opts)` 用的**裸名**,不带 `wx.` 前缀。注册之后小程序里通过 `wx.<name>(...)`(以及你在 `apiNamespaces` 配的其它命名空间)调用都会命中:
505
+
506
+ | 小程序里写 | `registerSimulatorApi` 的 name |
507
+ | --- | --- |
508
+ | `wx.login(...)` | `'login'` |
509
+ | `wx.request(...)` | `'request'` |
510
+ | `wx.getStorage(...)` 覆盖内置 | `'getStorage'`(小心:这会**屏蔽** dimina 容器的实现) |
511
+
382
512
  ```typescript
383
513
  import { registerSimulatorApi } from '@dimina-kit/devtools/simulator-apis'
384
514
 
385
- const dispose = registerSimulatorApi('myCompany.login', async ({ username }) => {
515
+ // 提供 wx.login 的实现(dimina 容器默认未实现,注册后才能用)
516
+ const dispose = registerSimulatorApi('login', async ({ success }) => {
386
517
  // 主进程上下文:可调用内部 HTTP、读取凭证文件、访问原生模块
387
- return await callInternalAuth(username)
518
+ const code = await callInternalAuth()
519
+ return { code }
388
520
  })
389
521
 
390
522
  // 不再需要时取消注册(不传也行,进程退出会一起清理)
391
523
  dispose()
392
524
  ```
393
525
 
394
- 几点行为约定:
526
+ ### 行为约定
395
527
 
528
+ - **命中顺序**:小程序运行时按 `apiRegistry[name] → MiniApp 实例方法 → 扩展模块兜底` 查找,所以 `registerSimulatorApi` 注册的 name **优先于内置实现**——既能给"未实现"的 wx.* 补功能(如 `wx.login`),也能覆盖默认的 wx.* 行为(如 `wx.request`,dimina-kit 本身就在用这条路把 `request` 接到主进程 fetch)。
396
529
  - 同名重复注册:后注册的覆盖前者,静默替换。
397
530
  - `dispose()` 只会移除自己创建的那次注册——如果之后被别人覆盖了,旧的 disposer 是 no-op。
398
- - 调用未注册的 name:小程序侧拿到 reject,错误信息里带 name。
399
- - Handler 可同步或异步返回;返回值需可 JSON 序列化(IPC 限制)。
400
-
401
- 对小程序侧来说,这些 name 和内置 API(`wx.getStorage` 等)走同一个 `AppManager.apiRegistry`,没有区别。
531
+ - 调用未注册且容器内也没有的 name:小程序侧拿到 reject,错误信息里带 name。
532
+ - Handler 可同步或异步返回;**返回值需可 JSON 序列化**(IPC 限制)。函数、Symbol、Map/Set、循环引用都会丢失。
402
533
 
403
534
  ---
404
535
 
@@ -94,6 +94,14 @@ function createContext(config, mainWindow, rendererDir) {
94
94
  apiNamespaces: config.apiNamespaces,
95
95
  brandingProvider: config.brandingProvider,
96
96
  toolbarActions: config.toolbarActions,
97
+ // The host-supplied ProjectsProvider / template types in `shared/types`
98
+ // are structurally compatible with the main-process equivalents —
99
+ // these casts are safe; we re-narrow at the workspace-service /
100
+ // create-project-service boundary.
101
+ projectsProvider: config.projectsProvider,
102
+ projectTemplates: config.projectTemplates,
103
+ builtinTemplates: config.builtinTemplates,
104
+ customCreateProjectDialog: config.customCreateProjectDialog,
97
105
  });
98
106
  }
99
107
  function registerBuiltinModules(config, context) {