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
@@ -17,12 +17,22 @@
17
17
  through CalendarView (force-tab="calendar") to keep the
18
18
  dual-tab bar from showing an empty Tasks panel (#828
19
19
  follow-up). -->
20
+ <!-- Plugin-owned views require a `<PluginScopedRoot>` ancestor
21
+ so descendants' `useRuntime()` calls resolve. The plugin
22
+ registry's `wrapWithScope` covers the chat-mounted variants;
23
+ this renderer is a separate mount path (file preview), so
24
+ the wrappers go here. PluginScopedRoot renders a fragment
25
+ via <slot/>, so the styling div must be inside. -->
20
26
  <div v-if="schedulerResult" class="h-full">
21
- <CalendarView :selected-result="schedulerResult" />
27
+ <PluginScopedRoot pkg-name="scheduler" :endpoints="API_ROUTES.scheduler">
28
+ <CalendarView :selected-result="schedulerResult" />
29
+ </PluginScopedRoot>
22
30
  </div>
23
31
  <!-- Todos todos.json: full kanban / table / list explorer. -->
24
32
  <div v-else-if="todoExplorerResult" class="h-full">
25
- <TodoExplorer :selected-result="todoExplorerResult" />
33
+ <PluginScopedRoot pkg-name="@mulmoclaude/todo-plugin">
34
+ <TodoExplorer :selected-result="todoExplorerResult" />
35
+ </PluginScopedRoot>
26
36
  </div>
27
37
  <!-- Markdown rendered: frontmatter panel + body -->
28
38
  <div v-else-if="isMarkdown && !mdRawMode" class="h-full flex flex-col overflow-auto">
@@ -31,12 +41,16 @@
31
41
  <span class="font-semibold text-gray-600 shrink-0">{{ field.key }}:</span>
32
42
  <template v-if="Array.isArray(field.value)">
33
43
  <span class="flex flex-wrap gap-1">
34
- <span v-for="item in field.value" :key="item" class="rounded-full bg-white border border-gray-300 px-2 py-0.5 text-gray-700">
35
- {{ item }}
44
+ <span
45
+ v-for="(item, idx) in field.value"
46
+ :key="String(idx) + ':' + formatScalarField(item)"
47
+ class="rounded-full bg-white border border-gray-300 px-2 py-0.5 text-gray-700"
48
+ >
49
+ {{ formatScalarField(item) }}
36
50
  </span>
37
51
  </span>
38
52
  </template>
39
- <span v-else class="text-gray-800 break-words">{{ field.value }}</span>
53
+ <span v-else class="text-gray-800 break-words">{{ formatScalarField(field.value) }}</span>
40
54
  </div>
41
55
  </div>
42
56
  <div class="flex-1 min-h-0" @click.capture="(e: MouseEvent) => emit('markdownLinkClick', e)">
@@ -59,10 +73,25 @@
59
73
  `allow-same-origin`, so the iframe keeps a null
60
74
  origin — it can't read MulmoClaude's cookies,
61
75
  localStorage, or the parent window's DOM.
62
- A CSP meta tag is injected via wrapHtmlWithPreviewCsp
63
- to restrict script loads to a vetted CDN whitelist +
64
- inline; connect-src is `'none'` so the page can't
65
- phone home. See src/utils/html/previewCsp.ts. -->
76
+
77
+ Two branches:
78
+ - Files under `artifacts/html/` load via iframe `src=`
79
+ pointing at the `/artifacts/html` static mount, so the
80
+ browser resolves relative `<img src="../images/...">`
81
+ against the file's real URL. CSP arrives as an HTTP
82
+ header on the response.
83
+ - Anything else falls back to `srcdoc` with a CSP meta
84
+ tag injected by `wrapHtmlWithPreviewCsp`. Relative
85
+ paths don't resolve under `srcdoc` (base URL is
86
+ `about:srcdoc`), but that's the historical behavior
87
+ for non-`artifacts/html/` HTML. -->
88
+ <iframe
89
+ v-else-if="isHtml && htmlPreviewUrl"
90
+ :src="htmlPreviewUrl"
91
+ class="w-full h-full border-0"
92
+ sandbox="allow-scripts"
93
+ :title="t('fileContentRenderer.htmlPreview')"
94
+ />
66
95
  <iframe
67
96
  v-else-if="isHtml"
68
97
  :srcdoc="sandboxedHtml"
@@ -124,15 +153,16 @@ import { useI18n } from "vue-i18n";
124
153
  import TextResponseView from "../plugins/textResponse/View.vue";
125
154
  import CalendarView from "../plugins/scheduler/CalendarView.vue";
126
155
  import TodoExplorer from "./TodoExplorer.vue";
156
+ import PluginScopedRoot from "./PluginScopedRoot.vue";
127
157
  import SystemFileBanner from "./SystemFileBanner.vue";
128
158
  import type { FileContent } from "../composables/useFileSelection";
129
159
  import type { ToolResultComplete } from "gui-chat-protocol/vue";
130
160
  import type { TextResponseData } from "../plugins/textResponse/types";
131
161
  import type { SchedulerData } from "../plugins/scheduler/index";
132
- import type { TodoData } from "../plugins/todo/index";
162
+ import type { TodoData } from "@mulmoclaude/todo-plugin/shared";
133
163
  import { JSON_TOKEN_CLASS } from "../utils/format/jsonSyntax";
134
164
  import type { JsonToken, JsonlLine } from "../utils/format/jsonSyntax";
135
- import type { Frontmatter } from "../utils/format/frontmatter";
165
+ import { formatScalarField, type MarkdownDocView } from "../composables/useMarkdownDoc";
136
166
  import { rewriteMarkdownImageRefs } from "../utils/image/rewriteMarkdownImageRefs";
137
167
  import { API_ROUTES } from "../config/apiRoutes";
138
168
  import { descriptorForPath } from "../config/systemFileDescriptors";
@@ -152,9 +182,10 @@ const props = defineProps<{
152
182
  isJsonl: boolean;
153
183
  mdRawMode: boolean;
154
184
  sandboxedHtml: string;
185
+ htmlPreviewUrl: string | null;
155
186
  jsonTokens: JsonToken[];
156
187
  jsonlLines: JsonlLine[];
157
- mdFrontmatter: Frontmatter | null;
188
+ mdFrontmatter: MarkdownDocView | null;
158
189
  rawSaveError: string | null;
159
190
  }>();
160
191
 
@@ -177,13 +208,35 @@ function markdownResult(text: string): ToolResultComplete<TextResponseData> {
177
208
  const slash = current.lastIndexOf("/");
178
209
  const basePath = slash >= 0 ? current.slice(0, slash) : "";
179
210
  const rewritten = rewriteMarkdownImageRefs(text, basePath);
211
+ // The displayed text strips frontmatter (rendered separately as a
212
+ // metadata bar above) — but the PDF source must keep the original
213
+ // markdown so the server can decide what to keep / strip via the
214
+ // `pdfStripFrontmatter` flag. Otherwise non-wiki files with
215
+ // frontmatter would silently lose it from the PDF too.
216
+ const fullSource = props.content?.kind === "text" ? props.content.content : text;
217
+ // Strip frontmatter from the PDF whenever the UI shows it as a
218
+ // separate metadata panel — otherwise the YAML duplicates as plain
219
+ // text on page 1 of the PDF.
220
+ const hasFrontmatter = props.mdFrontmatter !== null;
180
221
  return {
181
222
  uuid: "files-preview",
182
223
  toolName: "text-response",
183
224
  message: rewritten,
184
225
  title: props.selectedPath ?? "",
185
- // role: "user" hides the PDF download button in TextResponseView
186
- data: { text: rewritten, role: "user", transportKind: "text-rest" },
226
+ data: {
227
+ text: rewritten,
228
+ role: "assistant",
229
+ transportKind: "text-rest",
230
+ // `pdfSourceText`: un-rewritten markdown so the server-side
231
+ // image inliner resolves against on-disk paths, not the
232
+ // `/api/files/raw?…` URLs the display layer produces.
233
+ pdfSourceText: fullSource,
234
+ // Pass basePath as-is (including empty string for top-level
235
+ // files like README.md). The server distinguishes empty
236
+ // (= workspace root) from undefined (= legacy default).
237
+ pdfBaseDir: basePath,
238
+ pdfStripFrontmatter: hasFrontmatter,
239
+ },
187
240
  };
188
241
  }
189
242
  </script>
@@ -48,6 +48,7 @@ import { useExpandedDirs } from "../composables/useExpandedDirs";
48
48
  import { sortChildren } from "../utils/files/sortChildren";
49
49
  import { descriptorForPath, EDIT_POLICY_ICON_COLOR } from "../config/systemFileDescriptors";
50
50
  import type { FileSortMode } from "../composables/useFileSortMode";
51
+ import type { TreeNode } from "../types/fileTree";
51
52
 
52
53
  const DEFAULT_FILE_ICON_COLOR = "text-gray-400";
53
54
 
@@ -57,7 +58,6 @@ const { t } = useI18n();
57
58
  // import it without depending on a .vue module. Re-export here so
58
59
  // existing `import { TreeNode } from "./FileTree.vue"` keeps working.
59
60
  export type { TreeNode } from "../types/fileTree";
60
- import type { TreeNode } from "../types/fileTree";
61
61
 
62
62
  const props = defineProps<{
63
63
  node: TreeNode;
@@ -124,7 +124,7 @@ const AUDIO_EXTENSIONS = new Set([".mp3", ".wav", ".m4a", ".ogg", ".oga", ".flac
124
124
 
125
125
  const fileIcon = computed(() => {
126
126
  if (props.node.type !== "file") return "description";
127
- const name = props.node.name;
127
+ const { name } = props.node;
128
128
  const dot = name.lastIndexOf(".");
129
129
  if (dot < 0) return "description";
130
130
  const ext = name.slice(dot).toLowerCase();
@@ -36,6 +36,7 @@
36
36
  :is-jsonl="isJsonl"
37
37
  :md-raw-mode="mdRawMode"
38
38
  :sandboxed-html="sandboxedHtml"
39
+ :html-preview-url="htmlPreviewUrl"
39
40
  :json-tokens="jsonTokens"
40
41
  :jsonl-lines="jsonlLines"
41
42
  :md-frontmatter="mdFrontmatter"
@@ -43,6 +44,18 @@
43
44
  @markdown-link-click="handleMarkdownLinkClick"
44
45
  @update-source="saveRawMarkdown"
45
46
  />
47
+ <!-- Per-file chat composer: spawns a fresh chat with a
48
+ "take a look at this file first" instruction prepended.
49
+ Mirrors the wiki per-page composer (see plugins/wiki/View.vue).
50
+ No roleId is passed, so the new chat inherits the user's
51
+ current role. -->
52
+ <PageChatComposer
53
+ v-if="selectedPath && !contentLoading && !contentError"
54
+ :key="selectedPath"
55
+ :placeholder="t('filesView.chatPlaceholder')"
56
+ :prepend-text="`Before answering, take a look at the file at ${selectedPath}.`"
57
+ test-id-prefix="files-page-chat"
58
+ />
46
59
  </div>
47
60
  </div>
48
61
  </template>
@@ -50,9 +63,11 @@
50
63
  <script setup lang="ts">
51
64
  import { ref, computed, watch, onMounted, onUnmounted } from "vue";
52
65
  import { useRoute } from "vue-router";
66
+ import { useI18n } from "vue-i18n";
53
67
  import FileTreePane from "./FileTreePane.vue";
54
68
  import FileContentHeader from "./FileContentHeader.vue";
55
69
  import FileContentRenderer from "./FileContentRenderer.vue";
70
+ import PageChatComposer from "./PageChatComposer.vue";
56
71
  import { useFileTree } from "../composables/useFileTree";
57
72
  import { useFileSelection, isValidFilePath, readPathMatch } from "../composables/useFileSelection";
58
73
  import { useMarkdownMode } from "../composables/useMarkdownMode";
@@ -67,6 +82,7 @@ import { toTodoExplorerResult } from "../utils/filesPreview/todoPreview";
67
82
  const RECENT_THRESHOLD_MS = 60 * 1000;
68
83
 
69
84
  const route = useRoute();
85
+ const { t } = useI18n();
70
86
 
71
87
  const props = defineProps<{
72
88
  refreshToken?: number;
@@ -87,7 +103,7 @@ const { mdRawMode, toggleMdRaw } = useMarkdownMode();
87
103
 
88
104
  const { sortMode, setSortMode } = useFileSortMode();
89
105
 
90
- const { isMarkdown, isHtml, isJson, isJsonl, sandboxedHtml, jsonTokens, jsonlLines, mdFrontmatter } = useContentDisplay(selectedPath, content);
106
+ const { isMarkdown, isHtml, isJson, isJsonl, sandboxedHtml, htmlPreviewUrl, jsonTokens, jsonlLines, mdFrontmatter } = useContentDisplay(selectedPath, content);
91
107
 
92
108
  // Save-error banner shown above the Rendered-mode markdown editor.
93
109
  // Cleared on every new file load and on the next successful save.
@@ -117,6 +117,7 @@
117
117
  <div v-if="bodyLoading" class="text-sm text-gray-400">{{ t("common.loading") }}</div>
118
118
  <div v-else-if="bodyError" class="text-sm text-red-600">{{ t("pluginNews.bodyError", { error: bodyError }) }}</div>
119
119
  <div v-else-if="!body" class="text-sm text-gray-400 italic">{{ t("pluginNews.noBody") }}</div>
120
+ <!-- eslint-disable-next-line vue/no-v-html -- marked.parse output of app-owned news body; trusted in-process render -->
120
121
  <div v-else class="markdown-content prose prose-slate max-w-none" v-html="renderedBody"></div>
121
122
  </div>
122
123
  </div>
@@ -125,7 +126,7 @@
125
126
  :key="selected.id"
126
127
  :placeholder="t('pluginNews.chatPlaceholder')"
127
128
  :prepend-text="`Read this article. ${selected.url}`"
128
- :allow-empty="true"
129
+ allow-empty
129
130
  test-id-prefix="news-page-chat"
130
131
  />
131
132
  </template>
@@ -144,6 +145,7 @@ import { apiGet } from "../utils/api";
144
145
  import { formatSmartTime } from "../utils/format/date";
145
146
  import { useNewsItems } from "../composables/useNewsItems";
146
147
  import { useNewsReadState } from "../composables/useNewsReadState";
148
+ import { parseFrontmatter } from "../utils/markdown/frontmatter";
147
149
  import FilterChip from "./FilterChip.vue";
148
150
  import PageChatComposer from "./PageChatComposer.vue";
149
151
 
@@ -191,7 +193,18 @@ const unreadCount = computed(() => items.value.filter((item) => !isRead(item.id)
191
193
 
192
194
  const selected = computed(() => items.value.find((item) => item.id === selectedId.value) ?? null);
193
195
 
194
- const renderedBody = computed(() => (body.value ? marked(body.value, { breaks: true, gfm: true }) : ""));
196
+ // Strip frontmatter before marked() renders the body. RSS-derived
197
+ // content typically has no `---\n...\n---` envelope, but a feed
198
+ // that mirrors a markdown blog could carry one — and we don't
199
+ // want it to surface as a stray `<hr>` plus key:value plain text.
200
+ // `parseFrontmatter` is a no-op for header-less inputs, so this
201
+ // is safe for the common case (#895 PR D — closes the issue's
202
+ // "Vue 側 ... news ... frontmatter が body に出ない" requirement).
203
+ const renderedBody = computed(() => {
204
+ if (!body.value) return "";
205
+ const { body: bodyOnly } = parseFrontmatter(body.value);
206
+ return marked(bodyOnly, { breaks: true, gfm: true });
207
+ });
195
208
 
196
209
  function selectItem(itemId: string): void {
197
210
  selectedId.value = itemId;
@@ -220,6 +233,7 @@ watch(
220
233
  const token = ++bodyToken;
221
234
  const url = API_ROUTES.news.itemBody.replace(":id", encodeURIComponent(itemId));
222
235
  const result = await apiGet<{ body: string | null }>(url);
236
+ // eslint-disable-next-line security/detect-possible-timing-attacks -- in-memory race-token guard, not an auth compare
223
237
  if (token !== bodyToken) return;
224
238
  bodyLoading.value = false;
225
239
  if (!result.ok) {