mulmoclaude 0.5.2 → 0.6.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.
Files changed (486) hide show
  1. package/Dockerfile.sandbox +100 -0
  2. package/README.md +17 -4
  3. package/bin/mulmoclaude.js +46 -15
  4. package/bin/prepare-dist.js +18 -2
  5. package/client/assets/chunk-CernVdwh.js +1 -0
  6. package/client/assets/chunk-D8eiyYIV-C1eAZMzz.js +1 -0
  7. package/client/assets/html2canvas-CDGcmOD3-BbPeutDg.js +5 -0
  8. package/client/assets/index-BbgSjFQ8.js +4968 -0
  9. package/client/assets/index-ECD0lgIv.css +2 -0
  10. package/client/assets/{index.es-D4YyL_Dg-BgT6a3Nd.js → index.es-DqtpmBm8-DJdTPdnc.js} +5 -5
  11. package/client/assets/material-symbols-outlined-BLDfUw-_.woff2 +0 -0
  12. package/client/assets/runtime-protocol-vue-6WYa8hAs.js +1 -0
  13. package/client/assets/runtime-vue-BVUzgYGA.js +1 -0
  14. package/client/assets/typeof-DBp4T-Ny-C2xoZtcz.js +1 -0
  15. package/client/assets/vue-1e_vz2LW.js +1 -0
  16. package/client/assets/vue.runtime.esm-bundler-DQ8Kjjui.js +4 -0
  17. package/client/index.html +33 -2
  18. package/package.json +20 -18
  19. package/sandbox-entrypoint.sh +106 -0
  20. package/server/accounting/accountNormalize.ts +32 -0
  21. package/server/accounting/defaultAccounts.ts +87 -0
  22. package/server/accounting/eventPublisher.ts +51 -0
  23. package/server/accounting/journal.ts +252 -0
  24. package/server/accounting/openingBalances.ts +114 -0
  25. package/server/accounting/report.ts +237 -0
  26. package/server/accounting/service.ts +718 -0
  27. package/server/accounting/snapshotCache.ts +333 -0
  28. package/server/accounting/timeSeries.ts +265 -0
  29. package/server/accounting/types.ts +148 -0
  30. package/server/agent/activeTools.ts +128 -0
  31. package/server/agent/attachmentConverter.ts +10 -5
  32. package/server/agent/backend/claude-code.ts +8 -2
  33. package/server/agent/backend/types.ts +1 -1
  34. package/server/agent/config.ts +101 -31
  35. package/server/agent/index.ts +45 -33
  36. package/server/agent/mcp-server.ts +146 -69
  37. package/server/agent/mcp-tools/index.ts +1 -5
  38. package/server/agent/mcp-tools/notify.ts +2 -22
  39. package/server/agent/mcp-tools/x.ts +0 -4
  40. package/server/agent/mcpHealth.ts +168 -0
  41. package/server/agent/plugin-names.ts +20 -77
  42. package/server/agent/prompt.ts +259 -51
  43. package/server/agent/resumeFailover.ts +1 -1
  44. package/server/agent/stream.ts +0 -1
  45. package/server/api/auth/bearerAuth.ts +5 -5
  46. package/server/api/csrfGuard.ts +1 -1
  47. package/server/api/routes/accounting.ts +366 -0
  48. package/server/api/routes/agent.ts +509 -46
  49. package/server/api/routes/attachment.ts +104 -0
  50. package/server/api/routes/chart.ts +2 -1
  51. package/server/api/routes/config.ts +12 -12
  52. package/server/api/routes/files.ts +105 -48
  53. package/server/api/routes/image.ts +70 -25
  54. package/server/api/routes/journal.ts +35 -0
  55. package/server/api/routes/mulmo-script.ts +358 -118
  56. package/server/api/routes/mulmoScriptValidate.ts +1 -1
  57. package/server/api/routes/news.ts +1 -1
  58. package/server/api/routes/notifications.ts +92 -22
  59. package/server/api/routes/notifier.ts +98 -0
  60. package/server/api/routes/pdf.ts +188 -48
  61. package/server/api/routes/plugins.ts +34 -14
  62. package/server/api/routes/presentHtml.ts +58 -3
  63. package/server/api/routes/roles.ts +1 -8
  64. package/server/api/routes/runtime-plugin.ts +224 -0
  65. package/server/api/routes/scheduler.ts +7 -5
  66. package/server/api/routes/schedulerHandlers.ts +1 -1
  67. package/server/api/routes/schedulerTasks.ts +8 -7
  68. package/server/api/routes/sessions.ts +234 -121
  69. package/server/api/routes/skills.ts +56 -51
  70. package/server/api/routes/sources.ts +52 -45
  71. package/server/api/routes/translation.ts +44 -0
  72. package/server/api/routes/wiki/frontmatter.ts +13 -65
  73. package/server/api/routes/wiki/history.ts +261 -0
  74. package/server/api/routes/wiki/pageIndex.ts +1 -1
  75. package/server/api/routes/wiki.ts +50 -26
  76. package/server/events/file-change.ts +83 -0
  77. package/server/events/notifications.ts +247 -91
  78. package/server/events/pub-sub/index.ts +1 -1
  79. package/server/events/relay-client.ts +5 -5
  80. package/server/events/scheduler-adapter.ts +2 -2
  81. package/server/events/session-store/index.ts +110 -22
  82. package/server/events/task-manager/index.ts +10 -9
  83. package/server/index.ts +509 -33
  84. package/server/notifier/engine.ts +419 -0
  85. package/server/notifier/legacy-adapters.ts +76 -0
  86. package/server/notifier/runtime-api.ts +74 -0
  87. package/server/notifier/store.ts +70 -0
  88. package/server/notifier/types.ts +121 -0
  89. package/server/plugins/dev-loader.ts +171 -0
  90. package/server/plugins/dev-watcher.ts +150 -0
  91. package/server/plugins/diagnostics.ts +188 -0
  92. package/server/plugins/preset-list.ts +52 -0
  93. package/server/plugins/preset-loader.ts +112 -0
  94. package/server/plugins/runtime-chat-api.ts +38 -0
  95. package/server/plugins/runtime-loader.ts +430 -0
  96. package/server/plugins/runtime-registry.ts +112 -0
  97. package/server/plugins/runtime-tasks-api.ts +50 -0
  98. package/server/plugins/runtime.ts +378 -0
  99. package/server/services/translation/cache.ts +72 -0
  100. package/server/services/translation/index.ts +106 -0
  101. package/server/services/translation/llm.ts +140 -0
  102. package/server/services/translation/types.ts +35 -0
  103. package/server/system/credentials.ts +13 -2
  104. package/server/system/env.ts +6 -1
  105. package/server/system/logger/formatters.ts +46 -4
  106. package/server/system/logger/index.ts +4 -4
  107. package/server/system/logger/sinks.ts +26 -5
  108. package/server/system/logger/types.ts +2 -2
  109. package/server/utils/dev-plugin-args.d.mts +11 -0
  110. package/server/utils/dev-plugin-args.mjs +43 -0
  111. package/server/utils/errors.ts +13 -4
  112. package/server/utils/files/accounting-io.ts +295 -0
  113. package/server/utils/files/atomic.ts +17 -49
  114. package/server/utils/files/attachment-store.ts +182 -0
  115. package/server/utils/files/html-io.ts +1 -7
  116. package/server/utils/files/html-store.ts +19 -0
  117. package/server/utils/files/image-store.ts +20 -22
  118. package/server/utils/files/index.ts +5 -15
  119. package/server/utils/files/journal-io.ts +7 -35
  120. package/server/utils/files/json.ts +2 -29
  121. package/server/utils/files/markdown-image-fill.ts +6 -37
  122. package/server/utils/files/markdown-store.ts +6 -21
  123. package/server/utils/files/naming.ts +3 -39
  124. package/server/utils/files/plugins-io.ts +100 -0
  125. package/server/utils/files/reference-dirs-io.ts +1 -9
  126. package/server/utils/files/roles-io.ts +2 -10
  127. package/server/utils/files/safe.ts +17 -19
  128. package/server/utils/files/scheduler-io.ts +1 -7
  129. package/server/utils/files/scheduler-overrides-io.ts +3 -12
  130. package/server/utils/files/session-io.ts +21 -30
  131. package/server/utils/files/spreadsheet-store.ts +9 -22
  132. package/server/utils/files/translation-io.ts +46 -0
  133. package/server/utils/files/user-tasks-io.ts +1 -7
  134. package/server/utils/files/workspace-io.ts +3 -79
  135. package/server/utils/gemini.ts +33 -11
  136. package/server/utils/html/htmlArtifactSplicer.ts +41 -0
  137. package/server/utils/markdown/frontmatter.ts +112 -0
  138. package/server/utils/regex.ts +56 -0
  139. package/server/utils/router.ts +41 -0
  140. package/server/utils/slug.ts +5 -3
  141. package/server/utils/time.ts +12 -0
  142. package/server/workspace/chat-index/indexer.ts +15 -2
  143. package/server/workspace/chat-index/summarizer.ts +1 -1
  144. package/server/workspace/custom-dirs.ts +1 -1
  145. package/server/workspace/helps/gemini.md +1 -1
  146. package/server/workspace/helps/guide.md +61 -0
  147. package/server/workspace/helps/index.md +4 -0
  148. package/server/workspace/helps/presenthtml.md +80 -0
  149. package/server/workspace/helps/sandbox.md +7 -0
  150. package/server/workspace/helps/storyteller.md +101 -0
  151. package/server/workspace/helps/telegram.md +1 -0
  152. package/server/workspace/helps/wiki.md +9 -7
  153. package/server/workspace/journal/archivist-cli.ts +7 -33
  154. package/server/workspace/journal/archivist-schemas.ts +5 -43
  155. package/server/workspace/journal/dailyPass.ts +34 -187
  156. package/server/workspace/journal/diff.ts +3 -28
  157. package/server/workspace/journal/index.ts +10 -81
  158. package/server/workspace/journal/indexFile.ts +3 -24
  159. package/server/workspace/journal/latestDaily.ts +51 -0
  160. package/server/workspace/journal/memoryExtractor.ts +4 -20
  161. package/server/workspace/journal/optimizationPass.ts +4 -21
  162. package/server/workspace/journal/paths.ts +4 -23
  163. package/server/workspace/journal/state.ts +6 -29
  164. package/server/workspace/memory/io.ts +213 -0
  165. package/server/workspace/memory/llm-classifier.ts +158 -0
  166. package/server/workspace/memory/migrate.ts +263 -0
  167. package/server/workspace/memory/run.ts +84 -0
  168. package/server/workspace/memory/topic-cluster.ts +218 -0
  169. package/server/workspace/memory/topic-detect.ts +67 -0
  170. package/server/workspace/memory/topic-index-hook.ts +128 -0
  171. package/server/workspace/memory/topic-io.ts +180 -0
  172. package/server/workspace/memory/topic-migrate.ts +248 -0
  173. package/server/workspace/memory/topic-run.ts +172 -0
  174. package/server/workspace/memory/topic-swap.ts +135 -0
  175. package/server/workspace/memory/topic-types.ts +142 -0
  176. package/server/workspace/memory/types.ts +83 -0
  177. package/server/workspace/news/reader.ts +4 -5
  178. package/server/workspace/paths.ts +124 -47
  179. package/server/workspace/roles.ts +2 -11
  180. package/server/workspace/skills/parser.ts +38 -55
  181. package/server/workspace/skills/user-tasks.ts +1 -2
  182. package/server/workspace/skills-preset/mc-library/SKILL.md +188 -0
  183. package/server/workspace/skills-preset.ts +196 -0
  184. package/server/workspace/sources/fetchers/githubIssues.ts +13 -11
  185. package/server/workspace/sources/fetchers/index.ts +1 -1
  186. package/server/workspace/sources/fetchers/rssParser.ts +1 -1
  187. package/server/workspace/sources/pipeline/index.ts +2 -2
  188. package/server/workspace/sources/pipeline/notify.ts +3 -3
  189. package/server/workspace/sources/pipeline/write.ts +2 -2
  190. package/server/workspace/sources/registry.ts +39 -61
  191. package/server/workspace/sources/robots.ts +1 -1
  192. package/server/workspace/tool-trace/classify.ts +2 -1
  193. package/server/workspace/tool-trace/index.ts +1 -1
  194. package/server/workspace/tool-trace/writeSearch.ts +6 -1
  195. package/server/workspace/wiki-backlinks/index.ts +19 -7
  196. package/server/workspace/wiki-backlinks/sessionBacklinks.ts +1 -0
  197. package/server/workspace/wiki-history/hook/snapshot.mjs +98 -0
  198. package/server/workspace/wiki-history/hook/snapshot.ts +135 -0
  199. package/server/workspace/wiki-history/provision.ts +181 -0
  200. package/server/workspace/wiki-pages/io.ts +217 -0
  201. package/server/workspace/wiki-pages/snapshot.ts +380 -0
  202. package/server/workspace/workspace.ts +75 -13
  203. package/src/App.vue +115 -40
  204. package/src/_runtime/protocol-vue.ts +21 -0
  205. package/src/_runtime/vue.ts +22 -0
  206. package/src/components/ChatInput.vue +14 -10
  207. package/src/components/CopyChatButton.vue +76 -0
  208. package/src/components/FileContentRenderer.vue +67 -14
  209. package/src/components/FileTree.vue +2 -2
  210. package/src/components/FilesView.vue +17 -1
  211. package/src/components/NewsView.vue +16 -2
  212. package/src/components/NotificationBell.vue +320 -93
  213. package/src/components/PageChatComposer.vue +5 -4
  214. package/src/components/PluginLauncher.vue +42 -6
  215. package/src/components/PluginScopedRoot.vue +87 -0
  216. package/src/components/RoleSelector.vue +12 -1
  217. package/src/components/RolesView.vue +562 -0
  218. package/src/components/SentAttachmentChip.vue +102 -0
  219. package/src/components/SessionHistoryPanel.vue +109 -20
  220. package/src/components/SessionRoleIcon.vue +7 -4
  221. package/src/components/SessionSidebar.vue +20 -7
  222. package/src/components/SessionTabBar.vue +1 -1
  223. package/src/components/SettingsMcpTab.vue +4 -4
  224. package/src/components/SettingsModal.vue +2 -0
  225. package/src/components/SidebarHeader.vue +16 -5
  226. package/src/components/SourcesManager.vue +23 -9
  227. package/src/components/SourcesView.vue +1 -1
  228. package/src/components/StackView.vue +102 -6
  229. package/src/components/SuggestionsPanel.vue +105 -16
  230. package/src/components/SystemFileBanner.vue +1 -1
  231. package/src/components/TodoExplorer.vue +4 -5
  232. package/src/components/todo/TodoAddDialog.vue +2 -3
  233. package/src/components/todo/TodoEditDialog.vue +1 -2
  234. package/src/components/todo/TodoEditPanel.vue +2 -3
  235. package/src/components/todo/TodoKanbanView.vue +8 -5
  236. package/src/components/todo/TodoListView.vue +3 -5
  237. package/src/components/todo/TodoTableView.vue +7 -5
  238. package/src/composables/useAccountingChannel.ts +58 -0
  239. package/src/composables/useActiveSession.ts +4 -25
  240. package/src/composables/useAppApi.ts +6 -44
  241. package/src/composables/useClipboardCopy.ts +3 -20
  242. package/src/composables/useContentDisplay.ts +33 -2
  243. package/src/composables/useDevPluginReload.ts +23 -0
  244. package/src/composables/useDynamicFavicon.ts +5 -31
  245. package/src/composables/useEventListeners.ts +0 -20
  246. package/src/composables/useExpandedDirs.ts +4 -15
  247. package/src/composables/useFaviconState.ts +12 -46
  248. package/src/composables/useFileChange.ts +53 -0
  249. package/src/composables/useFreshPluginData.ts +6 -43
  250. package/src/composables/useHealth.ts +14 -43
  251. package/src/composables/useImageErrorRepair.ts +104 -0
  252. package/src/composables/useLatestDaily.ts +40 -0
  253. package/src/composables/useMarkdownDoc.ts +39 -0
  254. package/src/composables/useMarkdownLinkHandler.ts +1 -1
  255. package/src/composables/useMcpTools.ts +3 -16
  256. package/src/composables/useNotifications.ts +138 -112
  257. package/src/composables/usePdfDownload.ts +17 -3
  258. package/src/composables/usePendingCalls.ts +8 -26
  259. package/src/composables/usePluginErrorBoundary.ts +68 -0
  260. package/src/composables/usePubSub.ts +9 -17
  261. package/src/composables/useRunElapsed.ts +5 -22
  262. package/src/composables/useSandboxStatus.ts +4 -20
  263. package/src/composables/useSessionDerived.ts +7 -15
  264. package/src/composables/useSessionHistory.ts +70 -29
  265. package/src/composables/useSessionSync.ts +25 -3
  266. package/src/composables/useSkillsList.ts +59 -0
  267. package/src/composables/useTranslatedQueries.ts +109 -0
  268. package/src/config/apiRoutes.ts +181 -80
  269. package/src/config/historyFilters.ts +5 -3
  270. package/src/config/hostEvents.ts +17 -0
  271. package/src/config/mcpCatalog.ts +277 -5
  272. package/src/config/pubsubChannels.ts +134 -12
  273. package/src/config/roles.ts +212 -147
  274. package/src/config/systemFileDescriptors.ts +5 -5
  275. package/src/config/toolNames.ts +52 -30
  276. package/src/config/workspacePaths.ts +26 -2
  277. package/src/lang/de.ts +483 -27
  278. package/src/lang/en.ts +448 -27
  279. package/src/lang/es.ts +474 -27
  280. package/src/lang/fr.ts +476 -27
  281. package/src/lang/ja.ts +465 -27
  282. package/src/lang/ko.ts +466 -27
  283. package/src/lang/pt-BR.ts +473 -27
  284. package/src/lang/zh.ts +463 -27
  285. package/src/lib/vue-i18n.ts +1 -1
  286. package/src/lib/wiki-page/slug.ts +66 -0
  287. package/src/main.ts +85 -0
  288. package/src/plugins/_extras.ts +58 -0
  289. package/src/plugins/_generated/metas.ts +42 -0
  290. package/src/plugins/_generated/registrations.ts +44 -0
  291. package/src/plugins/_generated/server-bindings.ts +47 -0
  292. package/src/plugins/accounting/Preview.vue +106 -0
  293. package/src/plugins/accounting/View.vue +632 -0
  294. package/src/plugins/accounting/actions.ts +34 -0
  295. package/src/plugins/accounting/api.ts +301 -0
  296. package/src/plugins/accounting/components/AccountEditor.vue +250 -0
  297. package/src/plugins/accounting/components/AccountRow.vue +50 -0
  298. package/src/plugins/accounting/components/AccountsList.vue +102 -0
  299. package/src/plugins/accounting/components/AccountsModal.vue +300 -0
  300. package/src/plugins/accounting/components/BalanceSheet.vue +186 -0
  301. package/src/plugins/accounting/components/BookSettings.vue +284 -0
  302. package/src/plugins/accounting/components/BookSwitcher.vue +78 -0
  303. package/src/plugins/accounting/components/DateRangePicker.vue +140 -0
  304. package/src/plugins/accounting/components/JournalEntryForm.vue +504 -0
  305. package/src/plugins/accounting/components/JournalList.vue +553 -0
  306. package/src/plugins/accounting/components/Ledger.vue +206 -0
  307. package/src/plugins/accounting/components/NewBookForm.vue +211 -0
  308. package/src/plugins/accounting/components/OpeningBalancesForm.vue +271 -0
  309. package/src/plugins/accounting/components/ProfitLoss.vue +160 -0
  310. package/src/plugins/accounting/components/accountDraft.ts +13 -0
  311. package/src/plugins/accounting/components/accountNumbering.ts +103 -0
  312. package/src/plugins/accounting/components/accountValidation.ts +75 -0
  313. package/src/plugins/accounting/components/useLatestRequest.ts +44 -0
  314. package/src/plugins/accounting/countries.ts +158 -0
  315. package/src/plugins/accounting/currencies.ts +64 -0
  316. package/src/plugins/accounting/dates.ts +51 -0
  317. package/src/plugins/accounting/definition.ts +199 -0
  318. package/src/plugins/accounting/fiscalYear.ts +136 -0
  319. package/src/plugins/accounting/index.ts +49 -0
  320. package/src/plugins/accounting/meta.ts +91 -0
  321. package/src/plugins/accounting/timeSeriesEnums.ts +16 -0
  322. package/src/plugins/api.ts +125 -0
  323. package/src/plugins/canvas/View.vue +38 -28
  324. package/src/plugins/canvas/definition.ts +10 -8
  325. package/src/plugins/canvas/index.ts +15 -8
  326. package/src/plugins/canvas/meta.ts +12 -0
  327. package/src/plugins/chart/Preview.vue +1 -1
  328. package/src/plugins/chart/View.vue +2 -2
  329. package/src/plugins/chart/definition.ts +12 -2
  330. package/src/plugins/chart/index.ts +15 -7
  331. package/src/plugins/chart/meta.ts +18 -0
  332. package/src/plugins/editImages/definition.ts +44 -0
  333. package/src/plugins/editImages/index.ts +43 -0
  334. package/src/plugins/editImages/meta.ts +5 -0
  335. package/src/plugins/generateImage/View.vue +3 -1
  336. package/src/plugins/generateImage/definition.ts +2 -0
  337. package/src/plugins/generateImage/index.ts +13 -5
  338. package/src/plugins/generateImage/meta.ts +5 -0
  339. package/src/plugins/index.ts +35 -0
  340. package/src/plugins/manageRoles/Preview.vue +7 -4
  341. package/src/plugins/manageRoles/View.vue +12 -8
  342. package/src/plugins/manageRoles/definition.ts +6 -0
  343. package/src/plugins/manageRoles/index.ts +7 -6
  344. package/src/plugins/manageSkills/View.vue +11 -7
  345. package/src/plugins/manageSkills/definition.ts +4 -1
  346. package/src/plugins/manageSkills/index.ts +14 -7
  347. package/src/plugins/manageSkills/meta.ts +21 -0
  348. package/src/plugins/manageSource/definition.ts +4 -1
  349. package/src/plugins/manageSource/index.ts +15 -7
  350. package/src/plugins/manageSource/meta.ts +21 -0
  351. package/src/plugins/markdown/Preview.vue +10 -8
  352. package/src/plugins/markdown/View.vue +84 -17
  353. package/src/plugins/markdown/definition.ts +7 -1
  354. package/src/plugins/markdown/index.ts +15 -8
  355. package/src/plugins/markdown/meta.ts +16 -0
  356. package/src/plugins/meta-types.ts +97 -0
  357. package/src/plugins/metas.ts +224 -0
  358. package/src/plugins/presentForm/Preview.vue +4 -15
  359. package/src/plugins/presentForm/View.vue +35 -78
  360. package/src/plugins/presentForm/definition.ts +7 -6
  361. package/src/plugins/presentForm/index.ts +12 -5
  362. package/src/plugins/presentForm/meta.ts +11 -0
  363. package/src/plugins/presentForm/plugin.ts +8 -9
  364. package/src/plugins/presentForm/types.ts +0 -24
  365. package/src/plugins/presentHtml/Preview.vue +1 -8
  366. package/src/plugins/presentHtml/View.vue +401 -30
  367. package/src/plugins/presentHtml/definition.ts +8 -5
  368. package/src/plugins/presentHtml/index.ts +15 -8
  369. package/src/plugins/presentHtml/meta.ts +14 -0
  370. package/src/plugins/presentMulmoScript/View.vue +327 -107
  371. package/src/plugins/presentMulmoScript/definition.ts +34 -7
  372. package/src/plugins/presentMulmoScript/helpers.ts +4 -5
  373. package/src/plugins/presentMulmoScript/index.ts +20 -7
  374. package/src/plugins/presentMulmoScript/meta.ts +52 -0
  375. package/src/plugins/scheduler/AutomationsPreview.vue +2 -8
  376. package/src/plugins/scheduler/Preview.vue +5 -2
  377. package/src/plugins/scheduler/TasksTab.vue +16 -36
  378. package/src/plugins/scheduler/View.vue +22 -54
  379. package/src/plugins/scheduler/automationsDefinition.ts +14 -9
  380. package/src/plugins/scheduler/automationsMeta.ts +5 -0
  381. package/src/plugins/scheduler/calendarDefinition.ts +4 -7
  382. package/src/plugins/scheduler/calendarMeta.ts +28 -0
  383. package/src/plugins/scheduler/formatSchedule.ts +6 -24
  384. package/src/plugins/scheduler/index.ts +26 -52
  385. package/src/plugins/scope.ts +57 -0
  386. package/src/plugins/server-bindings-types.ts +38 -0
  387. package/src/plugins/server.ts +32 -0
  388. package/src/plugins/skill/Preview.vue +25 -0
  389. package/src/plugins/skill/View.vue +125 -0
  390. package/src/plugins/skill/definition.ts +23 -0
  391. package/src/plugins/skill/index.ts +36 -0
  392. package/src/plugins/skill/plugin.ts +31 -0
  393. package/src/plugins/skill/types.ts +21 -0
  394. package/src/plugins/spreadsheet/Preview.vue +1 -3
  395. package/src/plugins/spreadsheet/View.vue +29 -49
  396. package/src/plugins/spreadsheet/cellHighlights.ts +2 -3
  397. package/src/plugins/spreadsheet/definition.ts +5 -2
  398. package/src/plugins/spreadsheet/index.ts +15 -8
  399. package/src/plugins/spreadsheet/keyboardNav.ts +38 -0
  400. package/src/plugins/spreadsheet/meta.ts +14 -0
  401. package/src/plugins/textResponse/Preview.vue +9 -1
  402. package/src/plugins/textResponse/View.vue +59 -8
  403. package/src/plugins/textResponse/index.ts +11 -3
  404. package/src/plugins/textResponse/plugin.ts +8 -10
  405. package/src/plugins/textResponse/types.ts +28 -0
  406. package/src/plugins/wiki/Preview.vue +6 -4
  407. package/src/plugins/wiki/View.vue +463 -254
  408. package/src/plugins/wiki/components/WikiPageBody.vue +159 -0
  409. package/src/plugins/wiki/helpers.ts +17 -0
  410. package/src/plugins/wiki/history/HistoryDetail.vue +325 -0
  411. package/src/plugins/wiki/history/HistoryTab.vue +167 -0
  412. package/src/plugins/wiki/history/RestoreConfirm.vue +63 -0
  413. package/src/plugins/wiki/history/api.ts +52 -0
  414. package/src/plugins/wiki/history/diff.ts +145 -0
  415. package/src/plugins/wiki/index.ts +42 -32
  416. package/src/plugins/wiki/meta.ts +10 -0
  417. package/src/plugins/wiki/pageEditLoader.ts +53 -0
  418. package/src/plugins/wiki/route.ts +8 -0
  419. package/src/router/guards.ts +2 -1
  420. package/src/router/index.ts +19 -0
  421. package/src/router/pageRoutes.ts +1 -0
  422. package/src/tools/index.ts +50 -51
  423. package/src/tools/runtimeLoader.ts +141 -0
  424. package/src/tools/types.ts +44 -1
  425. package/src/types/notification.ts +23 -0
  426. package/src/types/pastedFile.ts +10 -0
  427. package/src/types/session.ts +61 -3
  428. package/src/types/sse.ts +21 -6
  429. package/src/utils/agent/eventDispatch.ts +12 -9
  430. package/src/utils/agent/pastedAttachment.ts +35 -0
  431. package/src/utils/agent/request.ts +32 -3
  432. package/src/utils/agent/toolCalls.ts +7 -1
  433. package/src/utils/api.ts +1 -1
  434. package/src/utils/chat/exportMarkdown.ts +243 -0
  435. package/src/utils/errors.ts +10 -2
  436. package/src/utils/files/expandedDirs.ts +1 -1
  437. package/src/utils/filesPreview/todoPreview.ts +13 -2
  438. package/src/utils/format/date.ts +1 -3
  439. package/src/utils/format/jsonSyntax.ts +5 -0
  440. package/src/utils/html/iframeHeightReporterScript.ts +62 -0
  441. package/src/utils/html/previewCsp.ts +29 -2
  442. package/src/utils/image/htmlSrcAttrs.ts +122 -0
  443. package/src/utils/image/imageRepairInlineScript.ts +115 -0
  444. package/src/utils/image/resolve.ts +17 -3
  445. package/src/utils/image/rewriteMarkdownImageRefs.ts +62 -9
  446. package/src/utils/markdown/frontmatter.ts +125 -0
  447. package/src/utils/markdown/taskList.ts +7 -2
  448. package/src/utils/plugin/runtime.ts +132 -0
  449. package/src/utils/session/mergeSessions.ts +40 -37
  450. package/src/utils/session/sessionEntries.ts +74 -18
  451. package/src/utils/session/sessionHelpers.ts +54 -10
  452. package/src/utils/tools/result.ts +76 -14
  453. package/src/vite-env.d.ts +6 -0
  454. package/client/assets/html2canvas-Cx501zZr-Bug0qRNv.js +0 -5
  455. package/client/assets/index-CY-WpQUm.css +0 -2
  456. package/client/assets/index-DbTz2Mfs.js +0 -4911
  457. package/client/assets/material-symbols-outlined-NzYEeyps.woff2 +0 -0
  458. package/server/api/routes/html.ts +0 -114
  459. package/server/api/routes/todos.ts +0 -293
  460. package/server/api/routes/todosColumnsHandlers.ts +0 -333
  461. package/server/api/routes/todosHandlers.ts +0 -274
  462. package/server/api/routes/todosItemsHandlers.ts +0 -386
  463. package/server/utils/files/todos-io.ts +0 -29
  464. package/src/components/NotificationToast.vue +0 -75
  465. package/src/plugins/editImage/definition.ts +0 -27
  466. package/src/plugins/editImage/index.ts +0 -37
  467. package/src/plugins/presentHtml/helpers.ts +0 -72
  468. package/src/plugins/scheduler/LegacySchedulerView.vue +0 -32
  469. package/src/plugins/scheduler/legacyShape.ts +0 -34
  470. package/src/plugins/todo/Preview.vue +0 -68
  471. package/src/plugins/todo/View.vue +0 -378
  472. package/src/plugins/todo/composables/useTodos.ts +0 -179
  473. package/src/plugins/todo/definition.ts +0 -45
  474. package/src/plugins/todo/index.ts +0 -62
  475. package/src/plugins/todo/labels.ts +0 -163
  476. package/src/plugins/todo/priority.ts +0 -98
  477. package/src/plugins/todo/viewModes.ts +0 -19
  478. package/src/plugins/wiki/definition.ts +0 -25
  479. package/src/tools/legacyPluginNames.ts +0 -13
  480. package/src/utils/format/frontmatter.ts +0 -80
  481. package/src/utils/image/rewriteHtmlImageRefs.ts +0 -50
  482. package/src/utils/notification/dispatch.ts +0 -58
  483. /package/client/assets/{purify.es-Fx1Nqyry-BwJECkqS.js → purify.es-Fx1Nqyry-BSVNht6S.js} +0 -0
  484. /package/src/plugins/{editImage → editImages}/Preview.vue +0 -0
  485. /package/src/plugins/{editImage → editImages}/View.vue +0 -0
  486. /package/src/{config/schedulerActions.ts → plugins/scheduler/actions.ts} +0 -0
@@ -257,19 +257,291 @@ export const MCP_CATALOG: McpCatalogEntry[] = [
257
257
 
258
258
  // Weather forecast / current conditions via Open-Meteo. Open-Meteo
259
259
  // is keyless for non-commercial use, so this entry is config-free.
260
- // TODO(reviewer): pick the most-active community package — as of
261
- // 2026-04 candidates include `mcp-server-open-meteo` and
262
- // `@cloud-rocket/mcp-server-open-meteo`.
260
+ // Apple native apps (macOS only) bundles Reminders / Calendar /
261
+ // Notes / Mail / Maps / Messages via AppleScript bridges. No
262
+ // credentials needed since it talks to the local system apps; the
263
+ // package no-ops on Linux/Windows. Bundle entry keeps install simple;
264
+ // if per-app granularity is wanted later, split into separate ids.
265
+ //
266
+ // TODO(reviewer): pin the most-active bundle package — as of 2026-04
267
+ // candidates include `apple-mcp` (Dhravya) and per-app variants like
268
+ // `mcp-server-apple-reminders` / `apple-notes-mcp`.
269
+ {
270
+ id: "apple-native",
271
+ displayName: "settingsMcpTab.catalog.entry.appleNative.displayName",
272
+ description: "settingsMcpTab.catalog.entry.appleNative.description",
273
+ audience: "general",
274
+ upstreamUrl: "https://github.com/Dhravya/apple-mcp",
275
+ spec: {
276
+ type: "stdio",
277
+ command: "npx",
278
+ args: ["-y", "@dhravya/apple-mcp"],
279
+ },
280
+ configSchema: [],
281
+ // Reads + writes Reminders / Notes / Calendar etc. — flagged
282
+ // medium because the agent can modify the user's data, even
283
+ // though no auth secret leaves the box.
284
+ riskLevel: "medium",
285
+ },
286
+
287
+ // Gmail read / send / label via a community MCP server. BYO OAuth
288
+ // credentials: the user creates an OAuth client in their own Google
289
+ // Cloud project, downloads `credentials.json`, and points the entry
290
+ // at it. Avoids the verified-app / CASA-audit cost — see plan
291
+ // `plans/done/feat-mcp-catalog-community-expansion.md`.
292
+ //
293
+ // TODO(reviewer): pin the most-active Gmail MCP — as of 2026-04
294
+ // `@gongrzhe/server-gmail-autoauth-mcp` is widely used; alternatives
295
+ // include `mcp-gmail` and Smithery-hosted variants.
296
+ {
297
+ id: "gmail",
298
+ displayName: "settingsMcpTab.catalog.entry.gmail.displayName",
299
+ description: "settingsMcpTab.catalog.entry.gmail.description",
300
+ audience: "general",
301
+ upstreamUrl: "https://github.com/GongRzhe/Gmail-MCP-Server",
302
+ setupGuideUrl: "https://developers.google.com/workspace/guides/create-credentials#desktop-app",
303
+ spec: {
304
+ type: "stdio",
305
+ command: "npx",
306
+ args: ["-y", "@gongrzhe/server-gmail-autoauth-mcp"],
307
+ env: {
308
+ GMAIL_OAUTH_PATH: "${GMAIL_OAUTH_PATH}",
309
+ },
310
+ },
311
+ configSchema: [
312
+ {
313
+ key: "GMAIL_OAUTH_PATH",
314
+ label: "settingsMcpTab.catalog.entry.gmail.field.credentials.label",
315
+ kind: "path",
316
+ placeholder: "~/.gmail-mcp/credentials.json",
317
+ required: true,
318
+ helpUrl: "https://console.cloud.google.com/apis/credentials",
319
+ helpText: "settingsMcpTab.catalog.entry.gmail.field.credentials.help",
320
+ },
321
+ ],
322
+ // Full mailbox access if the OAuth scope is broad — high.
323
+ riskLevel: "high",
324
+ },
325
+
326
+ // Google Calendar via a community MCP server. Same BYO-credentials
327
+ // pattern as Gmail above.
328
+ //
329
+ // TODO(reviewer): pin the most-active GCal MCP — as of 2026-04
330
+ // `@cocal/google-calendar-mcp` is a candidate.
331
+ {
332
+ id: "google-calendar",
333
+ displayName: "settingsMcpTab.catalog.entry.googleCalendar.displayName",
334
+ description: "settingsMcpTab.catalog.entry.googleCalendar.description",
335
+ audience: "general",
336
+ upstreamUrl: "https://github.com/nspady/google-calendar-mcp",
337
+ setupGuideUrl: "https://developers.google.com/workspace/guides/create-credentials#desktop-app",
338
+ spec: {
339
+ type: "stdio",
340
+ command: "npx",
341
+ args: ["-y", "@cocal/google-calendar-mcp"],
342
+ env: {
343
+ GOOGLE_OAUTH_CREDENTIALS: "${GOOGLE_OAUTH_CREDENTIALS}",
344
+ },
345
+ },
346
+ configSchema: [
347
+ {
348
+ key: "GOOGLE_OAUTH_CREDENTIALS",
349
+ label: "settingsMcpTab.catalog.entry.googleCalendar.field.credentials.label",
350
+ kind: "path",
351
+ placeholder: "~/.gcal-mcp/credentials.json",
352
+ required: true,
353
+ helpUrl: "https://console.cloud.google.com/apis/credentials",
354
+ helpText: "settingsMcpTab.catalog.entry.googleCalendar.field.credentials.help",
355
+ },
356
+ ],
357
+ riskLevel: "medium",
358
+ },
359
+
360
+ // Google Drive via the official-style MCP server. Token-cached
361
+ // OAuth — the package writes a refresh token next to the
362
+ // credentials file on first auth.
363
+ //
364
+ // TODO(reviewer): the upstream `@modelcontextprotocol/server-gdrive`
365
+ // was archived; double-check whether to point at the maintained
366
+ // fork or another community package.
367
+ {
368
+ id: "google-drive",
369
+ displayName: "settingsMcpTab.catalog.entry.googleDrive.displayName",
370
+ description: "settingsMcpTab.catalog.entry.googleDrive.description",
371
+ audience: "general",
372
+ upstreamUrl: "https://github.com/modelcontextprotocol/servers-archived/tree/main/src/gdrive",
373
+ setupGuideUrl: "https://developers.google.com/workspace/guides/create-credentials#desktop-app",
374
+ spec: {
375
+ type: "stdio",
376
+ command: "npx",
377
+ args: ["-y", "@modelcontextprotocol/server-gdrive"],
378
+ env: {
379
+ GDRIVE_CREDENTIALS_PATH: "${GDRIVE_CREDENTIALS_PATH}",
380
+ },
381
+ },
382
+ configSchema: [
383
+ {
384
+ key: "GDRIVE_CREDENTIALS_PATH",
385
+ label: "settingsMcpTab.catalog.entry.googleDrive.field.credentials.label",
386
+ kind: "path",
387
+ placeholder: "~/.gdrive-mcp/credentials.json",
388
+ required: true,
389
+ helpUrl: "https://console.cloud.google.com/apis/credentials",
390
+ helpText: "settingsMcpTab.catalog.entry.googleDrive.field.credentials.help",
391
+ },
392
+ ],
393
+ riskLevel: "medium",
394
+ },
395
+
396
+ // GitHub repos / issues / PRs / search via the official MCP server.
397
+ // Auth is a single Personal Access Token (classic or fine-grained).
398
+ // Token scope dictates the risk: a `repo` scope can write to any
399
+ // repository the user has access to, so we flag this medium-to-high
400
+ // and tell users to scope down in the help text.
401
+ //
402
+ // TODO(reviewer): pin version. The package has been actively
403
+ // maintained as of 2026-04.
404
+ {
405
+ id: "github",
406
+ displayName: "settingsMcpTab.catalog.entry.github.displayName",
407
+ description: "settingsMcpTab.catalog.entry.github.description",
408
+ audience: "general",
409
+ upstreamUrl: "https://github.com/modelcontextprotocol/servers/tree/main/src/github",
410
+ setupGuideUrl: "https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens",
411
+ spec: {
412
+ type: "stdio",
413
+ command: "npx",
414
+ args: ["-y", "@modelcontextprotocol/server-github"],
415
+ env: {
416
+ GITHUB_PERSONAL_ACCESS_TOKEN: "${GITHUB_PERSONAL_ACCESS_TOKEN}",
417
+ },
418
+ },
419
+ configSchema: [
420
+ {
421
+ key: "GITHUB_PERSONAL_ACCESS_TOKEN",
422
+ label: "settingsMcpTab.catalog.entry.github.field.token.label",
423
+ kind: "secret",
424
+ placeholder: "ghp_…",
425
+ required: true,
426
+ helpUrl: "https://github.com/settings/tokens",
427
+ helpText: "settingsMcpTab.catalog.entry.github.field.token.help",
428
+ },
429
+ ],
430
+ // Token scope is on the user — high if `repo` is granted, low if
431
+ // it's read-only public. Default to medium.
432
+ riskLevel: "medium",
433
+ },
434
+
435
+ // Linear issues / projects / cycles via a community MCP server.
436
+ // Auth is a single Linear API key from the user's Linear settings.
437
+ //
438
+ // TODO(reviewer): pin the most-active Linear MCP — as of 2026-04
439
+ // candidates include `@tacticlaunch/mcp-linear` and various
440
+ // smithery-hosted variants.
441
+ {
442
+ id: "linear",
443
+ displayName: "settingsMcpTab.catalog.entry.linear.displayName",
444
+ description: "settingsMcpTab.catalog.entry.linear.description",
445
+ audience: "general",
446
+ upstreamUrl: "https://github.com/tacticlaunch/mcp-linear",
447
+ setupGuideUrl: "https://linear.app/docs/personal-api-keys",
448
+ spec: {
449
+ type: "stdio",
450
+ command: "npx",
451
+ args: ["-y", "@tacticlaunch/mcp-linear"],
452
+ env: {
453
+ LINEAR_API_KEY: "${LINEAR_API_KEY}",
454
+ },
455
+ },
456
+ configSchema: [
457
+ {
458
+ key: "LINEAR_API_KEY",
459
+ label: "settingsMcpTab.catalog.entry.linear.field.apiKey.label",
460
+ kind: "secret",
461
+ placeholder: "lin_api_…",
462
+ required: true,
463
+ helpUrl: "https://linear.app/settings/api",
464
+ helpText: "settingsMcpTab.catalog.entry.linear.field.apiKey.help",
465
+ },
466
+ ],
467
+ riskLevel: "medium",
468
+ },
469
+
470
+ // Open-Meteo weather forecasts. Package switched from the
471
+ // (non-existent on npm) `mcp-server-open-meteo` to `open-meteo-mcp`,
472
+ // verified via `npm view` 2026-04-27. No API key required —
473
+ // Open-Meteo is keyless for non-commercial use.
263
474
  {
264
475
  id: "weather-open-meteo",
265
476
  displayName: "settingsMcpTab.catalog.entry.weatherOpenMeteo.displayName",
266
477
  description: "settingsMcpTab.catalog.entry.weatherOpenMeteo.description",
267
478
  audience: "general",
268
- upstreamUrl: "https://open-meteo.com/",
479
+ upstreamUrl: "https://www.npmjs.com/package/open-meteo-mcp",
480
+ spec: {
481
+ type: "stdio",
482
+ command: "npx",
483
+ args: ["-y", "open-meteo-mcp"],
484
+ },
485
+ configSchema: [],
486
+ riskLevel: "low",
487
+ },
488
+
489
+ // Spotify Web API access — search tracks, manage playlists, control
490
+ // playback. Switched from the (non-existent on npm) package
491
+ // `@superseoworld/mcp-spotify` to `spotify-mcp` (calebWei/SpotifyMCP),
492
+ // verified via `npm view` 2026-04-27. Uses PKCE flow — no client
493
+ // secret needed; just a Client ID. Users must run a one-time
494
+ // `npx spotify-mcp@latest auth` to log in (browser window opens, the
495
+ // refresh token is cached at `~/.spotify-mcp/tokens.json`). The
496
+ // help text below points users at that step.
497
+ {
498
+ id: "spotify",
499
+ displayName: "settingsMcpTab.catalog.entry.spotify.displayName",
500
+ description: "settingsMcpTab.catalog.entry.spotify.description",
501
+ audience: "general",
502
+ upstreamUrl: "https://github.com/calebWei/SpotifyMCP",
503
+ setupGuideUrl: "https://developer.spotify.com/documentation/web-api/concepts/apps",
504
+ spec: {
505
+ type: "stdio",
506
+ command: "npx",
507
+ args: ["-y", "spotify-mcp@latest"],
508
+ env: {
509
+ SPOTIFY_CLIENT_ID: "${SPOTIFY_CLIENT_ID}",
510
+ },
511
+ },
512
+ configSchema: [
513
+ {
514
+ key: "SPOTIFY_CLIENT_ID",
515
+ label: "settingsMcpTab.catalog.entry.spotify.field.clientId.label",
516
+ kind: "secret",
517
+ placeholder: "spotify-client-id",
518
+ required: true,
519
+ helpUrl: "https://developer.spotify.com/dashboard",
520
+ helpText: "settingsMcpTab.catalog.entry.spotify.field.clientId.help",
521
+ },
522
+ ],
523
+ riskLevel: "medium",
524
+ },
525
+
526
+ // YouTube transcript fetcher — give it a video URL and it returns
527
+ // the captions. No auth needed; the package scrapes the public
528
+ // transcript endpoint. Useful for "summarise this YouTube video"
529
+ // workflows where Claude Code's built-in WebFetch can't reach the
530
+ // separate transcript subresource.
531
+ //
532
+ // TODO(reviewer): pin the most-active package — as of 2026-04
533
+ // candidates include `@kimtaeyoon83/mcp-server-youtube-transcript`
534
+ // and `mcp-youtube-transcript`.
535
+ {
536
+ id: "youtube-transcript",
537
+ displayName: "settingsMcpTab.catalog.entry.youtubeTranscript.displayName",
538
+ description: "settingsMcpTab.catalog.entry.youtubeTranscript.description",
539
+ audience: "general",
540
+ upstreamUrl: "https://github.com/kimtaeyoon83/mcp-server-youtube-transcript",
269
541
  spec: {
270
542
  type: "stdio",
271
543
  command: "npx",
272
- args: ["-y", "mcp-server-open-meteo"],
544
+ args: ["-y", "@kimtaeyoon83/mcp-server-youtube-transcript"],
273
545
  },
274
546
  configSchema: [],
275
547
  riskLevel: "low",
@@ -9,8 +9,23 @@
9
9
  // - a new channel gets declared here first, then wired — the
10
10
  // declaration serves as a lightweight registry / audit list
11
11
  //
12
+ // **Aggregator shape**: plugins that own static channels declare
13
+ // them in their `meta.ts` under `staticChannels` and the host
14
+ // auto-merges via `BUILT_IN_PLUGIN_METAS`. Channel factories
15
+ // (e.g. `bookChannel(bookId)`) stay as named exports in each
16
+ // plugin's meta.ts because their signatures are plugin-specific —
17
+ // re-exported below under the existing public names.
18
+ //
12
19
  // First slice of issue #289 (item 6: pub-sub channels).
13
20
 
21
+ import { BUILT_IN_PLUGIN_METAS, defineHostAggregate, type BuiltInPluginMetas, type HostPluginCollision, type IntraPluginCollision } from "../plugins/metas";
22
+ import {
23
+ bookChannel as accountingBookChannelFromMeta,
24
+ BOOK_EVENT_KINDS as ACCOUNTING_BOOK_EVENT_KINDS_FROM_META,
25
+ type BookEventKind as AccountingBookEventKindFromMeta,
26
+ type BookChannelPayload as AccountingBookChannelPayloadFromMeta,
27
+ } from "../plugins/accounting/meta";
28
+
14
29
  /**
15
30
  * Channel for the per-session event stream. One per chat session.
16
31
  * Publishers: `server/session-store/index.ts` (tool results, status,
@@ -22,24 +37,131 @@ export function sessionChannel(chatSessionId: string): string {
22
37
  return `session.${chatSessionId}`;
23
38
  }
24
39
 
25
- /** Static pub/sub channel names. Factories for parameterised channels
26
- * (e.g. `sessionChannel(id)`) live alongside as named helpers. */
27
- export const PUBSUB_CHANNELS = {
40
+ /**
41
+ * Channel for "this workspace file just changed". One per workspace-
42
+ * relative path. The path is normalised to POSIX separators so a
43
+ * Windows publisher and a Linux subscriber agree on the channel name
44
+ * (the workspace is per-machine, but tests, fixtures, and future
45
+ * remote editing all benefit from a portable contract).
46
+ *
47
+ * Publishers: any route that writes to disk and wants the UI to
48
+ * re-render — currently `presentHtml` (POST + PUT) and the markdown
49
+ * `updateMarkdown` route.
50
+ * Subscribers: `useFileChange(filePath)` — wired from
51
+ * `presentHtml/View.vue` and `markdown/View.vue`.
52
+ */
53
+ /** Normalise a workspace-relative path to the POSIX form used as both
54
+ * the `fileChannel` suffix and the `FileChannelPayload.path`. Exposed
55
+ * separately so publishers can share one normalised string between the
56
+ * channel name and the payload — keeping them in sync is the contract. */
57
+ export function toPosixWorkspacePath(workspaceRelativePath: string): string {
58
+ // Replace backslashes too — covers both Windows (`\`) and any
59
+ // pre-normalised mixed separators from upstream code.
60
+ return workspaceRelativePath.split(/[\\/]/g).filter(Boolean).join("/");
61
+ }
62
+
63
+ export function fileChannel(workspaceRelativePath: string): string {
64
+ return `file:${toPosixWorkspacePath(workspaceRelativePath)}`;
65
+ }
66
+
67
+ /** Payload published on `fileChannel(...)`. `mtimeMs` is the post-write
68
+ * `fs.stat().mtimeMs`; subscribers use it both as a cache-buster and
69
+ * as a monotonic clock to drop out-of-order events. */
70
+ export interface FileChannelPayload {
71
+ path: string; // workspace-relative POSIX, matches the channel suffix
72
+ mtimeMs: number;
73
+ }
74
+
75
+ /** Payload published on `PUBSUB_CHANNELS.sessions`.
76
+ * - Empty `{}` for ordinary "something changed, refetch" hints
77
+ * (run/finish, mark-read, bookmark toggle).
78
+ * - `{ deletedIds }` when sessions have been hard-deleted, so
79
+ * subscribers can drop them from their local caches without a
80
+ * full refetch (cursor diffs don't carry deletions). */
81
+ export interface SessionsChannelPayload {
82
+ deletedIds?: string[];
83
+ }
84
+
85
+ /**
86
+ * Per-book change channel — one channel per book id. Publishers
87
+ * fan out journal / opening / accounts / snapshot events scoped to
88
+ * a single bookId (see `AccountingBookChannelPayload`).
89
+ *
90
+ * Publisher: `server/accounting/eventPublisher.ts` (called from
91
+ * every mutating action in the service layer).
92
+ * Subscribers: View.vue + sub-components via
93
+ * `useAccountingChannel(bookId)`.
94
+ *
95
+ * Book-list-level events (a new book was created, an existing one
96
+ * was deleted) ride the static `PUBSUB_CHANNELS.accountingBooks`
97
+ * channel below — kept separate so a `JournalList.vue` viewing book
98
+ * A doesn't repaint when the user creates book B from another window.
99
+ */
100
+ // Plugin-owned: re-export accounting helpers from `meta.ts` under
101
+ // the existing public names so external consumers don't have to
102
+ // migrate their imports.
103
+ export const accountingBookChannel = accountingBookChannelFromMeta;
104
+ export const ACCOUNTING_BOOK_EVENT_KINDS = ACCOUNTING_BOOK_EVENT_KINDS_FROM_META;
105
+ export type AccountingBookEventKind = AccountingBookEventKindFromMeta;
106
+ export type AccountingBookChannelPayload = AccountingBookChannelPayloadFromMeta;
107
+
108
+ // Plugin-owned static channel names auto-merged from each plugin's
109
+ // META. Mapped type preserves the literal channel string (e.g.
110
+ // `"accounting:books"`) so consumers get string-literal types.
111
+ //
112
+ // Distributive conditional types collapse the union of per-plugin
113
+ // records into an INTERSECTION so consumers see the merged shape
114
+ // (`{ accountingBooks: "..." } & { ... }`) rather than the
115
+ // per-plugin union (which TS won't let you index into safely).
116
+ type UnionToIntersection<U> = (U extends unknown ? (k: U) => void : never) extends (k: infer I) => void ? I : never;
117
+
118
+ // `Record<never, never>` (no index signature), not
119
+ // `Record<string, never>` — the latter's index signature collapses
120
+ // `keyof` of the merged intersection back to `string`, breaking
121
+ // literal-key consumers. Same trap as `PluginWorkspaceDirsContribution`.
122
+ type PluginStaticChannelsContribution<M> = M extends { readonly staticChannels: infer C } ? { readonly [K in keyof C]: C[K] } : Record<never, never>;
123
+
124
+ type PluginStaticChannelsMap<T extends BuiltInPluginMetas> = UnionToIntersection<PluginStaticChannelsContribution<T[number]>>;
125
+
126
+ const HOST_STATIC_CHANNELS = {
28
127
  /** Sidebar "a session updated, please refetch" notification.
29
- * Publisher: `server/session-store/index.ts#notifySessionsChanged`.
30
- * Subscriber: `src/App.vue`. */
128
+ * Publisher: `server/session-store/index.ts#publishSessionsChanged`.
129
+ * Subscribers: `useSessionHistory` (purges deletedIds from the
130
+ * cached list), `useSessionSync` (purges deletedIds from
131
+ * sessionMap; refetches summaries for live state). */
31
132
  sessions: "sessions",
32
133
  /** Server-side debug heartbeat — wired through the task-manager
33
134
  * demo counter. Useful for sanity-checking that the WS pipe is
34
135
  * alive end-to-end. */
35
136
  debugBeat: "debug.beat",
36
- /** Broadcast push notifications to every open Web tab (scaffold for
37
- * the in-app notification center #144). The test endpoint
38
- * `POST /api/notifications/test` publishes here; the production
39
- * triggers (scheduler / todo reminders / journal) will follow
40
- * the same channel. Subscriber list starts empty the UI lands
41
- * in a separate PR. Payload: `{ message: string, firedAt: ISO8601 }`. */
42
- notifications: "notifications",
137
+ /** Dev plugin (`--dev-plugin <path>`) `dist/` changed debounced.
138
+ * Publisher: `server/plugins/dev-watcher.ts` after fs.watch fires.
139
+ * Subscriber: `src/composables/useDevPluginReload.ts` triggers
140
+ * `location.reload()` so the author sees their save without ⌘R.
141
+ * Payload: `{ name: string, changedFiles: string[], serverSideChange: boolean }`. */
142
+ devPluginChanged: "dev-plugin-changed",
143
+ /** Notifier state-change events (`published` / `cleared` /
144
+ * `cancelled`) as a discriminated union. Single global channel;
145
+ * subscribers filter by `pluginPkg` client-side. Publisher:
146
+ * `server/notifier/engine.ts` after persistence succeeds.
147
+ * Payload: `NotifierEvent`. */
148
+ notifier: "notifier",
43
149
  } as const;
44
150
 
151
+ // First-write-wins host+plugin aggregate (see `defineHostAggregate`):
152
+ // host keys win on collision, second-claiming plugin wins are
153
+ // dropped, both diagnostic lists are exposed for boot warnings.
154
+ const PUBSUB_CHANNELS_AGGREGATE = defineHostAggregate(BUILT_IN_PLUGIN_METAS, {
155
+ label: "PUBSUB_CHANNELS",
156
+ hostRecord: HOST_STATIC_CHANNELS,
157
+ extract: (meta) => meta.staticChannels,
158
+ dimension: "staticChannels",
159
+ });
160
+ export const PUBSUB_CHANNELS_HOST_COLLISIONS: readonly HostPluginCollision[] = PUBSUB_CHANNELS_AGGREGATE.hostCollisions;
161
+ export const PUBSUB_CHANNELS_INTRA_COLLISIONS: readonly IntraPluginCollision[] = PUBSUB_CHANNELS_AGGREGATE.intraCollisions;
162
+
163
+ /** Static pub/sub channel names. Factories for parameterised channels
164
+ * (e.g. `sessionChannel(id)`) live alongside as named helpers. */
165
+ export const PUBSUB_CHANNELS = PUBSUB_CHANNELS_AGGREGATE.merged as unknown as typeof HOST_STATIC_CHANNELS & PluginStaticChannelsMap<BuiltInPluginMetas>;
166
+
45
167
  export type StaticPubSubChannel = (typeof PUBSUB_CHANNELS)[keyof typeof PUBSUB_CHANNELS];