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
@@ -1,5 +1,7 @@
1
1
  <template>
2
- <ImageView v-if="imageResult" :selected-result="imageResult" />
2
+ <div data-testid="generate-image-view" class="w-full h-full">
3
+ <ImageView v-if="imageResult" :selected-result="imageResult" />
4
+ </div>
3
5
  </template>
4
6
 
5
7
  <script setup lang="ts">
@@ -1,6 +1,8 @@
1
1
  import type { ToolDefinition } from "gui-chat-protocol";
2
2
 
3
3
  export const TOOL_NAME = "generateImage";
4
+ // Endpoint contract is shared with editImages (see
5
+ // `editImages/definition.ts#ImageEndpoints`).
4
6
 
5
7
  export interface ImageToolData {
6
8
  imageData: string;
@@ -1,11 +1,13 @@
1
1
  import type { ToolResult } from "gui-chat-protocol";
2
- import type { ToolPlugin } from "../../tools/types";
2
+ import type { PluginRegistration, ToolPlugin } from "../../tools/types";
3
3
  import toolDefinition, { TOOL_NAME } from "./definition";
4
4
  import type { ImageToolData } from "./definition";
5
+ import { pluginEndpoints } from "../api";
6
+ import { wrapWithScope } from "../scope";
7
+ import type { ImageEndpoints } from "../editImages/definition";
5
8
  import View from "./View.vue";
6
9
  import Preview from "./Preview.vue";
7
10
  import { apiPost } from "../../utils/api";
8
- import { API_ROUTES } from "../../config/apiRoutes";
9
11
  import { makeUuid } from "../../utils/id";
10
12
 
11
13
  function createUploadedImageResult(imageData: string, fileName: string, prompt: string): ToolResult<ImageToolData, never> {
@@ -21,7 +23,8 @@ const generateImagePlugin: ToolPlugin<ImageToolData> = {
21
23
  toolDefinition,
22
24
 
23
25
  async execute(_context, args) {
24
- const result = await apiPost<ToolResult<ImageToolData>>(API_ROUTES.image.generate, args);
26
+ const endpoints = pluginEndpoints<ImageEndpoints>("image");
27
+ const result = await apiPost<ToolResult<ImageToolData>>(endpoints.generate, args);
25
28
  if (!result.ok) {
26
29
  return {
27
30
  toolName: TOOL_NAME,
@@ -49,9 +52,14 @@ const generateImagePlugin: ToolPlugin<ImageToolData> = {
49
52
  handleInput: (imageData: string) => createUploadedImageResult(imageData, "clipboard-image.png", ""),
50
53
  },
51
54
  ],
52
- viewComponent: View,
53
- previewComponent: Preview,
55
+ viewComponent: wrapWithScope("image", View),
56
+ previewComponent: wrapWithScope("image", Preview),
54
57
  };
55
58
 
56
59
  export default generateImagePlugin;
57
60
  export { TOOL_NAME };
61
+
62
+ export const REGISTRATION: PluginRegistration = {
63
+ toolName: TOOL_NAME,
64
+ entry: generateImagePlugin,
65
+ };
@@ -0,0 +1,5 @@
1
+ import { definePluginMeta } from "../meta-types";
2
+
3
+ export const META = definePluginMeta({
4
+ toolName: "generateImage",
5
+ });
@@ -0,0 +1,35 @@
1
+ // Built-in plugin registry — single source of truth for "which
2
+ // in-tree plugins ship in the bundle".
3
+ //
4
+ // Each plugin co-locates its TOOL_NAMES key with its Vue entry by
5
+ // exporting a `REGISTRATION` (singular) or `REGISTRATIONS` (array,
6
+ // for multi-entry plugins like scheduler). The codegen barrel below
7
+ // (`_generated/registrations.ts`) discovers them by scanning
8
+ // `src/plugins/<name>/index.ts`. External-package plugins (mindmap /
9
+ // quiz / present3d) live in `_extras.ts` because they aren't
10
+ // co-located in this source tree.
11
+ //
12
+ // **Auto-generated**. To add a built-in plugin: drop a new
13
+ // `src/plugins/<name>/` directory with an `index.ts` exporting
14
+ // `REGISTRATION` (or `REGISTRATIONS`); `yarn plugins:codegen` (run
15
+ // automatically via `predev` / `prebuild`) picks it up. This file
16
+ // stays unchanged.
17
+ //
18
+ // Runtime-installed plugins (#1043 C-2) live in a separate registry
19
+ // and are merged at lookup time in `src/tools/index.ts:getPlugin`;
20
+ // the array below is build-time-bundled only.
21
+
22
+ import type { PluginRegistration } from "../tools/types";
23
+ import { GENERATED_PLUGIN_REGISTRATIONS } from "./_generated/registrations";
24
+ import { EXTERNAL_PLUGIN_REGISTRATIONS } from "./_extras";
25
+
26
+ // `@gui-chat-plugin/weather` is now installed via the user's
27
+ // workspace ledger (`~/mulmoclaude/plugins/plugins.json`) rather
28
+ // than as a build-time bundle. The View loads via the runtime-plugin
29
+ // dynamic-import path; no static import here. (Briefly registered as
30
+ // a preset in `server/plugins/preset-list.ts` — that wedged because
31
+ // users who'd already installed it via the ledger then saw a
32
+ // "name collides" warning on every boot. Until that double-source
33
+ // case is handled cleanly, no presets ship by default.)
34
+
35
+ export const BUILT_IN_PLUGINS: readonly PluginRegistration[] = [...GENERATED_PLUGIN_REGISTRATIONS, ...EXTERNAL_PLUGIN_REGISTRATIONS];
@@ -15,17 +15,20 @@
15
15
  import { ref, watch } from "vue";
16
16
  import { useI18n } from "vue-i18n";
17
17
  import type { ToolResultComplete } from "gui-chat-protocol/vue";
18
-
19
- const { t } = useI18n();
20
18
  import type { ManageRolesData, CustomRole } from "./index";
21
19
  import { useFreshPluginData } from "../../composables/useFreshPluginData";
22
- import { API_ROUTES } from "../../config/apiRoutes";
20
+ import { pluginEndpoints } from "../api";
21
+ import type { RolesEndpoints } from "./definition";
22
+
23
+ const { t } = useI18n();
23
24
 
24
25
  const props = defineProps<{ result: ToolResultComplete<ManageRolesData> }>();
25
26
  const customRoles = ref<CustomRole[]>(props.result.data?.customRoles ?? []);
26
27
 
28
+ const endpoints = pluginEndpoints<RolesEndpoints>("roles");
29
+
27
30
  const { refresh } = useFreshPluginData<CustomRole[]>({
28
- endpoint: () => API_ROUTES.roles.list,
31
+ endpoint: () => endpoints.list,
29
32
  extract: (json) => (Array.isArray(json) ? (json as CustomRole[]) : null),
30
33
  apply: (data) => {
31
34
  customRoles.value = data;
@@ -283,9 +283,9 @@ import { useFreshPluginData } from "../../composables/useFreshPluginData";
283
283
  import { useAppApi } from "../../composables/useAppApi";
284
284
  import type { ToolResultComplete } from "gui-chat-protocol/vue";
285
285
  import type { CustomRole, ManageRolesData } from "./index";
286
- import { getAllPluginNames } from "../../tools/index";
287
286
  import { apiGet, apiPost } from "../../utils/api";
288
- import { API_ROUTES } from "../../config/apiRoutes";
287
+ import { pluginEndpoints, pluginAllPluginNames } from "../api";
288
+ import type { RolesEndpoints } from "./definition";
289
289
 
290
290
  const { t } = useI18n();
291
291
 
@@ -296,15 +296,17 @@ interface PluginEntry {
296
296
  }
297
297
 
298
298
  // Plugins the user can assign — exclude internal/auto-managed ones
299
- const EXCLUDED = new Set(["text-response", "switchRole"]);
300
- const guiPlugins: PluginEntry[] = getAllPluginNames()
299
+ const EXCLUDED = new Set(["text-response"]);
300
+ const guiPlugins: PluginEntry[] = pluginAllPluginNames()
301
301
  .filter((name) => !EXCLUDED.has(name))
302
302
  .map((name) => ({ name, enabled: true, requiredEnv: [] }));
303
303
 
304
304
  const availablePlugins = ref<PluginEntry[]>(guiPlugins);
305
305
 
306
+ const mcpEndpoints = pluginEndpoints<{ list: string }>("mcpTools");
307
+
306
308
  onMounted(async () => {
307
- const result = await apiGet<PluginEntry[]>(API_ROUTES.mcpTools.list);
309
+ const result = await apiGet<PluginEntry[]>(mcpEndpoints.list);
308
310
  if (result.ok) {
309
311
  availablePlugins.value = [...guiPlugins, ...result.data];
310
312
  }
@@ -321,8 +323,10 @@ const appApi = useAppApi();
321
323
 
322
324
  const customRoles = ref<CustomRole[]>(props.selectedResult?.data?.customRoles ?? []);
323
325
 
326
+ const rolesEndpoints = pluginEndpoints<RolesEndpoints>("roles");
327
+
324
328
  const { refresh: refreshCustomRoles } = useFreshPluginData<CustomRole[]>({
325
- endpoint: () => API_ROUTES.roles.list,
329
+ endpoint: () => rolesEndpoints.list,
326
330
  extract: (json) => (Array.isArray(json) ? (json as CustomRole[]) : null),
327
331
  apply: (data) => {
328
332
  customRoles.value = data;
@@ -403,7 +407,7 @@ function selectRole(role: CustomRole) {
403
407
  name: role.name,
404
408
  icon: role.icon,
405
409
  prompt: role.prompt,
406
- selectedPlugins: role.availablePlugins.filter((plugin) => plugin !== "switchRole"),
410
+ selectedPlugins: [...role.availablePlugins],
407
411
  queriesText: (role.queries ?? []).join("\n"),
408
412
  };
409
413
  }
@@ -417,7 +421,7 @@ interface ManageResult {
417
421
  }
418
422
 
419
423
  async function callManage(body: Record<string, unknown>): Promise<ManageResult> {
420
- const result = await apiPost<ManageResult>(API_ROUTES.roles.manage, body);
424
+ const result = await apiPost<ManageResult>(rolesEndpoints.manage, body);
421
425
  if (!result.ok) {
422
426
  // Prefer the backend's error message (e.g. validation failure
423
427
  // details). Fall back to a status code only when the server didn't
@@ -2,6 +2,12 @@ import type { ToolDefinition } from "gui-chat-protocol";
2
2
 
3
3
  export const TOOL_NAME = "manageRoles";
4
4
 
5
+ export interface RolesEndpoints {
6
+ [key: string]: string;
7
+ list: string;
8
+ manage: string;
9
+ }
10
+
5
11
  const toolDefinition: ToolDefinition = {
6
12
  type: "function",
7
13
  name: TOOL_NAME,
@@ -1,11 +1,11 @@
1
1
  import type { ToolPlugin } from "../../tools/types";
2
2
  import type { ToolResult } from "gui-chat-protocol";
3
- import toolDefinition from "./definition";
4
- import { TOOL_NAME } from "./definition";
3
+ import toolDefinition, { TOOL_NAME, type RolesEndpoints } from "./definition";
4
+ import { pluginEndpoints } from "../api";
5
+ import { wrapWithScope } from "../scope";
5
6
  import View from "./View.vue";
6
7
  import Preview from "./Preview.vue";
7
8
  import { apiPost } from "../../utils/api";
8
- import { API_ROUTES } from "../../config/apiRoutes";
9
9
  import { makeUuid } from "../../utils/id";
10
10
 
11
11
  export interface CustomRole {
@@ -24,7 +24,8 @@ export interface ManageRolesData {
24
24
  const manageRolesPlugin: ToolPlugin = {
25
25
  toolDefinition,
26
26
  async execute(_context, args) {
27
- const result = await apiPost<ToolResult<ManageRolesData>>(API_ROUTES.roles.manage, args);
27
+ const endpoints = pluginEndpoints<RolesEndpoints>("roles");
28
+ const result = await apiPost<ToolResult<ManageRolesData>>(endpoints.manage, args);
28
29
  if (!result.ok) {
29
30
  return {
30
31
  toolName: TOOL_NAME,
@@ -40,8 +41,8 @@ const manageRolesPlugin: ToolPlugin = {
40
41
  },
41
42
  isEnabled: () => true,
42
43
  generatingMessage: "Managing roles…",
43
- viewComponent: View,
44
- previewComponent: Preview,
44
+ viewComponent: wrapWithScope("roles", View),
45
+ previewComponent: wrapWithScope("roles", Preview),
45
46
  };
46
47
 
47
48
  export default manageRolesPlugin;
@@ -147,7 +147,9 @@ import type { ToolResultComplete } from "gui-chat-protocol/vue";
147
147
  import type { ManageSkillsData, SkillSummary } from "./index";
148
148
  import { useAppApi } from "../../composables/useAppApi";
149
149
  import { apiGet, apiPut, apiDelete } from "../../utils/api";
150
- import { API_ROUTES } from "../../config/apiRoutes";
150
+ import { pluginEndpoints } from "../api";
151
+ import { buildRouteUrl } from "../meta-types";
152
+ import type { SkillsEndpoints } from "./definition";
151
153
 
152
154
  const { t } = useI18n();
153
155
 
@@ -197,11 +199,13 @@ watch(
197
199
 
198
200
  const listError = ref<string | null>(null);
199
201
 
202
+ const endpoints = pluginEndpoints<SkillsEndpoints>("skills");
203
+
200
204
  // Standalone mode: if no selectedResult was passed, fetch the skill
201
205
  // list from the API on mount so the view is populated.
202
206
  onMounted(async () => {
203
207
  if (props.selectedResult || skills.value.length > 0) return;
204
- const response = await apiGet<{ skills: SkillSummary[] }>(API_ROUTES.skills.list);
208
+ const response = await apiGet<{ skills: SkillSummary[] }>(endpoints.list.url);
205
209
  if (!response.ok) {
206
210
  listError.value = t("pluginManageSkills.errListFailed", { error: response.error });
207
211
  return;
@@ -229,7 +233,7 @@ watch(
229
233
  editing.value = false;
230
234
  detailLoading.value = true;
231
235
  detailError.value = null;
232
- const response = await apiGet<{ skill: SkillDetail }>(API_ROUTES.skills.detail.replace(":name", encodeURIComponent(name)));
236
+ const response = await apiGet<{ skill: SkillDetail }>(buildRouteUrl(endpoints.detail, { name }));
233
237
  if (selectedName.value !== name) {
234
238
  // Selection changed while this request was in flight — drop it.
235
239
  return;
@@ -258,10 +262,10 @@ function cancelEdit(): void {
258
262
 
259
263
  async function saveEdit(): Promise<void> {
260
264
  if (!detail.value) return;
261
- const name = detail.value.name;
265
+ const { name } = detail.value;
262
266
  saving.value = true;
263
267
  detailError.value = null;
264
- const result = await apiPut<{ updated: boolean; path: string }>(API_ROUTES.skills.update.replace(":name", encodeURIComponent(name)), {
268
+ const result = await apiPut<{ updated: boolean; path: string }>(buildRouteUrl(endpoints.update, { name }), {
265
269
  description: editDescription.value,
266
270
  body: editBody.value,
267
271
  });
@@ -304,12 +308,12 @@ function runSkill(): void {
304
308
  // since the action is reversible by re-saving via the conversation.
305
309
  async function deleteSkill(): Promise<void> {
306
310
  if (!detail.value || detail.value.source !== "project") return;
307
- const name = detail.value.name;
311
+ const { name } = detail.value;
308
312
  if (!window.confirm(t("pluginManageSkills.confirmDelete", { name }))) {
309
313
  return;
310
314
  }
311
315
  deleting.value = true;
312
- const result = await apiDelete<unknown>(API_ROUTES.skills.remove.replace(":name", encodeURIComponent(name)));
316
+ const result = await apiDelete<unknown>(buildRouteUrl(endpoints.remove, { name }));
313
317
  deleting.value = false;
314
318
  if (!result.ok) {
315
319
  detailError.value = result.error || t("pluginManageSkills.errDeleteFailed");
@@ -1,6 +1,9 @@
1
1
  import type { ToolDefinition } from "gui-chat-protocol";
2
+ import { META } from "./meta";
3
+ import type { ResolvedRoute } from "../meta-types";
2
4
 
3
- export const TOOL_NAME = "manageSkills";
5
+ export const TOOL_NAME = META.toolName;
6
+ export type SkillsEndpoints = { readonly [K in keyof typeof META.apiRoutes]: ResolvedRoute };
4
7
 
5
8
  const toolDefinition: ToolDefinition = {
6
9
  type: "function",
@@ -1,9 +1,10 @@
1
- import type { ToolPlugin } from "../../tools/types";
2
- import toolDefinition, { TOOL_NAME } from "./definition";
1
+ import type { PluginRegistration, ToolPlugin } from "../../tools/types";
2
+ import toolDefinition, { TOOL_NAME, type SkillsEndpoints } from "./definition";
3
+ import { pluginEndpoints } from "../api";
4
+ import { wrapWithScope } from "../scope";
3
5
  import View from "./View.vue";
4
6
  import Preview from "./Preview.vue";
5
7
  import { apiGet } from "../../utils/api";
6
- import { API_ROUTES } from "../../config/apiRoutes";
7
8
  import { makeUuid } from "../../utils/id";
8
9
 
9
10
  export interface SkillSummary {
@@ -22,7 +23,8 @@ const manageSkillsPlugin: ToolPlugin<ManageSkillsData> = {
22
23
  // Claude invokes this tool to show the user their skills list.
23
24
  // The server exposes GET /api/skills (discovery + merge); we just
24
25
  // shape it for the View component.
25
- const result = await apiGet<{ skills: SkillSummary[] }>(API_ROUTES.skills.list);
26
+ const endpoints = pluginEndpoints<SkillsEndpoints>("skills");
27
+ const result = await apiGet<{ skills: SkillSummary[] }>(endpoints.list.url);
26
28
  if (!result.ok) {
27
29
  return {
28
30
  toolName: TOOL_NAME,
@@ -31,7 +33,7 @@ const manageSkillsPlugin: ToolPlugin<ManageSkillsData> = {
31
33
  error: `Failed to load skills: ${result.error}`,
32
34
  };
33
35
  }
34
- const skills = result.data.skills;
36
+ const { skills } = result.data;
35
37
  return {
36
38
  toolName: TOOL_NAME,
37
39
  uuid: makeUuid(),
@@ -42,9 +44,14 @@ const manageSkillsPlugin: ToolPlugin<ManageSkillsData> = {
42
44
  },
43
45
  isEnabled: () => true,
44
46
  generatingMessage: "Loading skills…",
45
- viewComponent: View,
46
- previewComponent: Preview,
47
+ viewComponent: wrapWithScope("skills", View),
48
+ previewComponent: wrapWithScope("skills", Preview),
47
49
  };
48
50
 
49
51
  export default manageSkillsPlugin;
50
52
  export { TOOL_NAME };
53
+
54
+ export const REGISTRATION: PluginRegistration = {
55
+ toolName: TOOL_NAME,
56
+ entry: manageSkillsPlugin,
57
+ };
@@ -0,0 +1,21 @@
1
+ import { definePluginMeta } from "../meta-types";
2
+
3
+ export const META = definePluginMeta({
4
+ toolName: "manageSkills",
5
+ apiNamespace: "skills",
6
+ apiRoutes: {
7
+ /** GET /api/skills — list every available skill (user + project). */
8
+ list: { method: "GET", path: "" },
9
+ /** GET /api/skills/:name — read one skill's body + frontmatter. */
10
+ detail: { method: "GET", path: "/:name" },
11
+ /** POST /api/skills — create a new project-scope skill. The MCP
12
+ * bridge posts here. */
13
+ create: { method: "POST", path: "" },
14
+ /** PUT /api/skills/:name — overwrite an existing project-scope
15
+ * skill. */
16
+ update: { method: "PUT", path: "/:name" },
17
+ /** DELETE /api/skills/:name — delete a project-scope skill. */
18
+ remove: { method: "DELETE", path: "/:name" },
19
+ },
20
+ mcpDispatch: "create",
21
+ });
@@ -1,6 +1,9 @@
1
1
  import type { ToolDefinition } from "gui-chat-protocol";
2
+ import { META } from "./meta";
3
+ import type { ResolvedRoute } from "../meta-types";
2
4
 
3
- export const TOOL_NAME = "manageSource";
5
+ export const TOOL_NAME = META.toolName;
6
+ export type SourcesEndpoints = { readonly [K in keyof typeof META.apiRoutes]: ResolvedRoute };
4
7
 
5
8
  const toolDefinition: ToolDefinition = {
6
9
  type: "function",
@@ -1,10 +1,11 @@
1
- import type { ToolPlugin } from "../../tools/types";
1
+ import type { PluginRegistration, ToolPlugin } from "../../tools/types";
2
2
  import type { ToolResult } from "gui-chat-protocol";
3
- import toolDefinition, { TOOL_NAME } from "./definition";
3
+ import toolDefinition, { TOOL_NAME, type SourcesEndpoints } from "./definition";
4
+ import { pluginEndpoints } from "../api";
5
+ import { wrapWithScope } from "../scope";
4
6
  import View from "./View.vue";
5
7
  import Preview from "./Preview.vue";
6
- import { apiPost } from "../../utils/api";
7
- import { API_ROUTES } from "../../config/apiRoutes";
8
+ import { apiCall } from "../../utils/api";
8
9
  import { makeUuid } from "../../utils/id";
9
10
 
10
11
  // Mirrors server/sources/types.ts#Source. Re-declared here so the
@@ -43,7 +44,9 @@ export interface ManageSourceData {
43
44
  const manageSourcePlugin: ToolPlugin<ManageSourceData> = {
44
45
  toolDefinition,
45
46
  async execute(_context, args) {
46
- const result = await apiPost<ToolResult<ManageSourceData>>(API_ROUTES.sources.manage, args);
47
+ const endpoints = pluginEndpoints<SourcesEndpoints>("sources");
48
+ const { method, url } = endpoints.manage;
49
+ const result = await apiCall<ToolResult<ManageSourceData>>(url, { method, body: args });
47
50
  if (!result.ok) {
48
51
  return {
49
52
  toolName: TOOL_NAME,
@@ -59,9 +62,14 @@ const manageSourcePlugin: ToolPlugin<ManageSourceData> = {
59
62
  },
60
63
  isEnabled: () => true,
61
64
  generatingMessage: "Managing sources…",
62
- viewComponent: View,
63
- previewComponent: Preview,
65
+ viewComponent: wrapWithScope("sources", View),
66
+ previewComponent: wrapWithScope("sources", Preview),
64
67
  };
65
68
 
66
69
  export default manageSourcePlugin;
67
70
  export { TOOL_NAME };
71
+
72
+ export const REGISTRATION: PluginRegistration = {
73
+ toolName: TOOL_NAME,
74
+ entry: manageSourcePlugin,
75
+ };
@@ -0,0 +1,21 @@
1
+ import { definePluginMeta } from "../meta-types";
2
+
3
+ export const META = definePluginMeta({
4
+ toolName: "manageSource",
5
+ apiNamespace: "sources",
6
+ apiRoutes: {
7
+ /** GET /api/sources — list every registered source. */
8
+ list: { method: "GET", path: "" },
9
+ /** POST /api/sources — register a new source. */
10
+ create: { method: "POST", path: "" },
11
+ /** DELETE /api/sources/:slug — remove a registered source. */
12
+ remove: { method: "DELETE", path: "/:slug" },
13
+ /** POST /api/sources/rebuild — re-run every fetcher, refresh
14
+ * archives. */
15
+ rebuild: { method: "POST", path: "/rebuild" },
16
+ /** POST /api/sources/manage — single-action dispatch route used
17
+ * by the MCP bridge. */
18
+ manage: { method: "POST", path: "/manage" },
19
+ },
20
+ mcpDispatch: "manage",
21
+ });
@@ -15,7 +15,9 @@ import type { ToolResult } from "gui-chat-protocol";
15
15
  import { isFilePath, type MarkdownToolData } from "./definition";
16
16
  import { extractFirstH1 } from "../../utils/markdown/extractFirstH1";
17
17
  import { apiGet } from "../../utils/api";
18
- import { API_ROUTES } from "../../config/apiRoutes";
18
+ import { pluginEndpoints } from "../api";
19
+
20
+ const filesEndpoints = pluginEndpoints<{ content: string }>("files");
19
21
 
20
22
  const props = defineProps<{
21
23
  result: ToolResult<MarkdownToolData>;
@@ -29,7 +31,7 @@ async function fetchContent(): Promise<void> {
29
31
  fetchedContent.value = "";
30
32
  return;
31
33
  }
32
- const result = await apiGet<{ content?: string }>(API_ROUTES.files.content, {
34
+ const result = await apiGet<{ content?: string }>(filesEndpoints.content, {
33
35
  path: raw,
34
36
  });
35
37
  if (!result.ok) {
@@ -42,6 +44,12 @@ async function fetchContent(): Promise<void> {
42
44
  fetchContent();
43
45
  watch(() => props.result.data?.markdown, fetchContent);
44
46
 
47
+ const resolvedMarkdown = computed(() => {
48
+ const raw = props.result.data?.markdown;
49
+ if (!raw) return "";
50
+ return isFilePath(raw) ? fetchedContent.value : raw;
51
+ });
52
+
45
53
  const displayTitle = computed(() => {
46
54
  if (props.result.title) {
47
55
  return props.result.title;
@@ -54,12 +62,6 @@ const displayTitle = computed(() => {
54
62
  return "Markdown Document";
55
63
  });
56
64
 
57
- const resolvedMarkdown = computed(() => {
58
- const raw = props.result.data?.markdown;
59
- if (!raw) return "";
60
- return isFilePath(raw) ? fetchedContent.value : raw;
61
- });
62
-
63
65
  function extractPreview(markdown: string): string {
64
66
  const lines = markdown
65
67
  .split("\n")