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
@@ -5,22 +5,72 @@
5
5
  //
6
6
  // Tracks #175.
7
7
 
8
- import { makeTextResult } from "../tools/result";
9
- import { isTextEntry, isToolResultEntry, type ActiveSession, type SessionEntry, type SessionSummary } from "../../types/session";
8
+ import { makeSkillResult, makeTextResult, TEXT_LIKE_RESULT_TOOL_NAMES } from "../tools/result";
9
+ import {
10
+ isSessionOrigin,
11
+ isSkillEntry,
12
+ isTextEntry,
13
+ isToolResultEntry,
14
+ pluginPkgFromOrigin,
15
+ type ActiveSession,
16
+ type SessionEntry,
17
+ type SessionOrigin,
18
+ type SessionSummary,
19
+ } from "../../types/session";
10
20
  import { EVENT_TYPES } from "../../types/events";
11
21
  import type { ToolResultComplete } from "gui-chat-protocol/vue";
12
22
 
23
+ // Pull origin off the `session_meta` row in the entries payload, if
24
+ // present. The on-disk meta is the source of truth; the server fills
25
+ // `SessionSummary.origin` from it but the summary fetch (`/api/sessions`)
26
+ // races with the per-session detail fetch (`/api/sessions/:id`) on
27
+ // first mount of `/chat/<id>`. Codex review on PR #1237 caught this:
28
+ // without an entries-side fallback, plugin-seeded chats opened
29
+ // directly via URL miss the chip until the user navigates away and
30
+ // back. Returns undefined when no meta row exists or its origin is
31
+ // missing / malformed.
32
+ function extractMetaOrigin(entries: readonly SessionEntry[]): SessionOrigin | undefined {
33
+ for (const entry of entries) {
34
+ if (entry.type === EVENT_TYPES.sessionMeta) {
35
+ const candidate = (entry as { origin?: unknown }).origin;
36
+ return isSessionOrigin(candidate) ? candidate : undefined;
37
+ }
38
+ }
39
+ return undefined;
40
+ }
41
+
13
42
  // Walk the server's session entries and produce the flat
14
43
  // `toolResults` array the client keeps in `ActiveSession`. Drops
15
44
  // `session_meta` rows (they're metadata, not a result), converts
16
45
  // text entries into tool-result-shaped envelopes via
17
46
  // `makeTextResult`, and passes tool_result entries through verbatim.
18
- export function parseSessionEntries(entries: readonly SessionEntry[]): ToolResultComplete[] {
47
+ //
48
+ // When the effective origin is a `plugin:<pkg>` tag (Phase 1 of the
49
+ // Encore plan), the FIRST user text entry is marked with
50
+ // `seededByPlugin` so the textResponse view renders a "from <pkg>"
51
+ // chip + muted background, indicating the seed message came from a
52
+ // plugin's `runtime.chat.start()` call rather than the user
53
+ // themselves. The effective origin prefers the explicit
54
+ // `sessionOrigin` argument (from the summary) and falls back to the
55
+ // `session_meta` row in `entries` so URL-loaded chats render the
56
+ // chip even before the summary fetch resolves.
57
+ export function parseSessionEntries(entries: readonly SessionEntry[], sessionOrigin?: SessionOrigin): ToolResultComplete[] {
58
+ const effectiveOrigin = sessionOrigin ?? extractMetaOrigin(entries);
59
+ const seedingPkg = pluginPkgFromOrigin(effectiveOrigin);
60
+ let firstUserSeen = false;
19
61
  const out: ToolResultComplete[] = [];
20
62
  for (const entry of entries) {
21
63
  if (entry.type === EVENT_TYPES.sessionMeta) continue;
22
- if (isTextEntry(entry)) {
23
- out.push(makeTextResult(entry.message, entry.source));
64
+ if (isSkillEntry(entry)) {
65
+ // Skill bodies are routed through the dedicated skill plugin
66
+ // View (collapsed by default) so they don't dump a wall of
67
+ // markdown into the canvas. #1218.
68
+ out.push(makeSkillResult(entry));
69
+ } else if (isTextEntry(entry)) {
70
+ const tagThis = !firstUserSeen && entry.source === "user" && seedingPkg !== null;
71
+ const seededBy = tagThis ? seedingPkg : undefined;
72
+ if (entry.source === "user") firstUserSeen = true;
73
+ out.push(makeTextResult(entry.message, entry.source, entry.attachments, seededBy ?? undefined));
24
74
  } else if (isToolResultEntry(entry)) {
25
75
  out.push(entry.result);
26
76
  }
@@ -31,27 +81,33 @@ export function parseSessionEntries(entries: readonly SessionEntry[]): ToolResul
31
81
  // Pick the `selectedResultUuid` the session should restore to.
32
82
  // Rules:
33
83
  // 1. If the URL carries `?result=<uuid>` AND that uuid actually
34
- // exists in the loaded list, honour it verbatim. This lets
35
- // bookmarks restore the exact result the user was viewing.
36
- // 2. Otherwise fall back to the heuristic: the most recent
37
- // non-text tool result (images, wiki pages, etc. carry more
38
- // visual information than bare text).
39
- // 3. If there are no non-text results, use the last result of
40
- // any kind.
84
+ // exists in the loaded list, honour it verbatim bookmarks
85
+ // restore the exact result the user was viewing.
86
+ // 2. Otherwise pick the most recent non-text-like tool result
87
+ // images, wiki pages, etc. carry more visual information
88
+ // than a bare text response or a collapsed skill card.
89
+ // 3. If every result is text-like (`text-response` or `skill`,
90
+ // see `TEXT_LIKE_RESULT_TOOL_NAMES`), fall back to the last
91
+ // one — typically the most recent assistant reply, NOT the
92
+ // skill card that preceded it. Codex iter-4 review on PR
93
+ // #1220 surfaced the inconsistency between this reload-time
94
+ // selector and the live-run `shouldSelectAssistantText`
95
+ // before they were unified on the same allowlist.
41
96
  // 4. If the list is empty, return null.
97
+ //
42
98
  export function resolveSelectedUuid(toolResults: readonly ToolResultComplete[], urlResult: string | null): string | null {
43
99
  if (urlResult && toolResults.some((result) => result.uuid === urlResult)) {
44
100
  return urlResult;
45
101
  }
46
- // Iterate backwards for the "last non-text" lookup so callers
47
- // don't pay for an intermediate reverse copy.
102
+ if (toolResults.length === 0) return null;
103
+ // Iterate backwards for the "last non-text-like" lookup so
104
+ // callers don't pay for an intermediate reverse copy.
48
105
  for (let i = toolResults.length - 1; i >= 0; i--) {
49
- if (toolResults[i].toolName !== "text-response") {
106
+ if (!TEXT_LIKE_RESULT_TOOL_NAMES.has(toolResults[i].toolName)) {
50
107
  return toolResults[i].uuid;
51
108
  }
52
109
  }
53
- const last = toolResults[toolResults.length - 1];
54
- return last?.uuid ?? null;
110
+ return toolResults[toolResults.length - 1].uuid;
55
111
  }
56
112
 
57
113
  // Decide the `startedAt` / `updatedAt` to seed the in-memory
@@ -98,7 +154,7 @@ export function buildLoadedSession(opts: {
98
154
  const { id, entries, defaultRoleId, urlResult, serverSummary, nowIso } = opts;
99
155
  const meta = entries.find((entry) => entry.type === EVENT_TYPES.sessionMeta);
100
156
  const roleId = meta?.roleId ?? defaultRoleId;
101
- const toolResults = parseSessionEntries(entries);
157
+ const toolResults = parseSessionEntries(entries, serverSummary?.origin);
102
158
  const selectedResultUuid = resolveSelectedUuid(toolResults, urlResult);
103
159
  const { startedAt, updatedAt } = resolveSessionTimestamps(serverSummary, nowIso);
104
160
  const resultTimestamps = interpolateTimestamps(toolResults, startedAt, updatedAt);
@@ -4,8 +4,8 @@
4
4
 
5
5
  import { v4 as uuidv4 } from "uuid";
6
6
  import type { ToolResultComplete } from "gui-chat-protocol/vue";
7
- import type { ActiveSession } from "../../types/session";
8
- import { makeTextResult } from "../tools/result";
7
+ import type { ActiveSession, SkillScope } from "../../types/session";
8
+ import { makeSkillResult, makeTextResult, SKILL_TOOL_NAME } from "../tools/result";
9
9
  import { shouldSelectAssistantText } from "../agent/toolCalls";
10
10
 
11
11
  /** Push a result and record its timestamp in one place. */
@@ -28,10 +28,13 @@ export function pushErrorMessage(session: ActiveSession, message: string): void
28
28
  session.selectedResultUuid = errorResult.uuid;
29
29
  }
30
30
 
31
- /** Append the user's message so it renders immediately. */
32
- export function beginUserTurn(session: ActiveSession, message: string): void {
31
+ /** Append the user's message so it renders immediately. `attachments`
32
+ * carries the workspace-relative paths the user attached for this
33
+ * turn (paste/drop/file-picker) so the chat bubble can render an
34
+ * icon / thumbnail chip alongside the text. */
35
+ export function beginUserTurn(session: ActiveSession, message: string, attachments?: readonly string[]): void {
33
36
  session.updatedAt = new Date().toISOString();
34
- pushResult(session, makeTextResult(message, "user"));
37
+ pushResult(session, makeTextResult(message, "user", attachments));
35
38
  session.runStartIndex = session.toolResults.length;
36
39
  }
37
40
 
@@ -59,11 +62,13 @@ function isDuplicateUserText(session: ActiveSession, message: string): boolean {
59
62
  /** Handle an incoming text event (user or assistant) from the
60
63
  * agent's SSE/pubsub stream. Deduplicates user messages,
61
64
  * streams assistant text into the last card, and selects the
62
- * result when appropriate. */
63
- export function applyTextEvent(session: ActiveSession, message: string, source: "user" | "assistant"): void {
65
+ * result when appropriate. `attachments` is forwarded for cross-tab
66
+ * user-text broadcasts so observing tabs render chips identically
67
+ * to the originating tab. */
68
+ export function applyTextEvent(session: ActiveSession, message: string, source: "user" | "assistant", attachments?: readonly string[]): void {
64
69
  if (source === "user") {
65
70
  if (!isDuplicateUserText(session, message)) {
66
- pushResult(session, makeTextResult(message, "user"));
71
+ pushResult(session, makeTextResult(message, "user", attachments));
67
72
  session.runStartIndex = session.toolResults.length;
68
73
  }
69
74
  return;
@@ -76,6 +81,42 @@ export function applyTextEvent(session: ActiveSession, message: string, source:
76
81
  }
77
82
  }
78
83
 
84
+ /** Replace the trailing assistant text-response (the streamed skill
85
+ * body from Claude CLI) with a collapsed skill card, preserving the
86
+ * uuid so any view bound to that uuid (selection, scroll anchors)
87
+ * doesn't lose its handle. Falls back to pushing a fresh skill
88
+ * card if no assistant text-response is at the tail (e.g. flush
89
+ * fired with no streamed deltas, or another result snuck in
90
+ * between). #1218 */
91
+ export function applySkillEvent(
92
+ session: ActiveSession,
93
+ payload: {
94
+ skillName: string;
95
+ skillScope: SkillScope;
96
+ skillPath: string | null;
97
+ skillDescription: string | null;
98
+ message: string;
99
+ },
100
+ ): void {
101
+ const last = session.toolResults[session.toolResults.length - 1];
102
+ const lastData = last?.data as { role?: string } | undefined;
103
+ if (last?.toolName === "text-response" && lastData?.role === "assistant") {
104
+ const replacement = makeSkillResult(payload);
105
+ // Preserve uuid so selection / scroll anchors don't blink off.
106
+ Object.assign(last, { ...replacement, uuid: last.uuid });
107
+ return;
108
+ }
109
+ const skillResult = makeSkillResult(payload);
110
+ pushResult(session, skillResult);
111
+ if (shouldSelectAssistantText(session.toolResults, session.runStartIndex)) {
112
+ session.selectedResultUuid = skillResult.uuid;
113
+ }
114
+ }
115
+
116
+ // Re-export so callers don't need to import from `tools/result` for
117
+ // the tool-name comparison constant.
118
+ export { SKILL_TOOL_NAME };
119
+
79
120
  /** In-place update a result that was re-emitted by a plugin view
80
121
  * (e.g. after the user edits a chart config). */
81
122
  export function updateResult(session: ActiveSession, updatedResult: ToolResultComplete): void {
@@ -86,8 +127,11 @@ export function updateResult(session: ActiveSession, updatedResult: ToolResultCo
86
127
  }
87
128
 
88
129
  /** Handle an incoming tool_result event: upsert into the session's
89
- * result list. Selects the result only on insert; in-place updates
90
- * preserve the user's current selection. */
130
+ * result list. Selects the result on insert; in-place updates
131
+ * preserve the user's current selection. The MCP bridge skips the
132
+ * toolResult POST for narrate-only actions (handlers that omit
133
+ * `data`), so every result that reaches this function is intended
134
+ * to surface a card. */
91
135
  export function applyToolResultToSession(session: ActiveSession, result: ToolResultComplete): void {
92
136
  const idx = session.toolResults.findIndex((existing) => existing.uuid === result.uuid);
93
137
  if (idx >= 0) {
@@ -5,36 +5,98 @@
5
5
  import type { ToolResultComplete } from "gui-chat-protocol/vue";
6
6
  import { v4 as uuidv4 } from "uuid";
7
7
  import { isRecord } from "../types";
8
+ import type { SkillScope } from "../../types/session";
9
+
10
+ /** Tool name used by the synthetic envelope `makeSkillResult`
11
+ * produces for `type: "skill"` jsonl entries. The skill plugin's
12
+ * registration matches on this in `getPlugin()` so the canvas
13
+ * routes skill bodies through `src/plugins/skill/View.vue` instead
14
+ * of the default `text-response` view (#1218). */
15
+ export const SKILL_TOOL_NAME = "skill";
16
+
17
+ /** Result tool-names that count as "assistant text" for selection
18
+ * purposes. `text-response` is the original case; `skill` was
19
+ * added in #1218 because the skill envelope is a collapsed card
20
+ * in the same conversational lane as plain assistant prose, not a
21
+ * richer plugin output (image / wiki / chart) that should hold
22
+ * its own selection.
23
+ *
24
+ * Single source of truth for the live-run selector
25
+ * (`shouldSelectAssistantText`) and the reload-time selector
26
+ * (`resolveSelectedUuid`) — Codex iter-3 / iter-4 review on PR
27
+ * #1220 surfaced the inconsistency between the two before this
28
+ * was unified. */
29
+ export const TEXT_LIKE_RESULT_TOOL_NAMES: ReadonlySet<string> = new Set(["text-response", SKILL_TOOL_NAME]);
8
30
 
9
31
  // Type guard: a text-response entry whose `data.role` is `"user"`.
10
32
  // Used by App.vue to find the first user message in a live session
11
33
  // when building the merged history list.
12
34
  export function isUserTextResponse(res: ToolResultComplete): boolean {
13
35
  if (res.toolName !== "text-response") return false;
14
- const data = res.data;
36
+ const { data } = res;
15
37
  if (!isRecord(data)) return false;
16
38
  return data.role === "user";
17
39
  }
18
40
 
19
- // Pull out the optional base64 image attached to a tool result, if
20
- // any. Returns `undefined` for results that have no `data.imageData`
21
- // or where it isn't a string.
22
- export function extractImageData(result: ToolResultComplete | undefined): string | undefined {
23
- const data = result?.data;
24
- if (isRecord(data) && typeof data.imageData === "string") {
25
- return data.imageData;
26
- }
27
- return undefined;
28
- }
29
-
30
41
  // Build a synthetic text-response result for either a user or
31
42
  // assistant turn. Used by sendMessage and the chat history UI.
32
- export function makeTextResult(text: string, role: "user" | "assistant"): ToolResultComplete {
43
+ // `attachments` is optional and only meaningful on user turns —
44
+ // they're the workspace paths the user attached for this message
45
+ // and surface as chips next to the bubble. `seededByPlugin` is
46
+ // optional and set by `parseSessionEntries` on the first user turn
47
+ // of a plugin-origin session (Phase 1 of the Encore plan); the
48
+ // textResponse view renders a "from <pkg>" chip when present.
49
+ export function makeTextResult(text: string, role: "user" | "assistant", attachments?: readonly string[], seededByPlugin?: string): ToolResultComplete {
50
+ const data: Record<string, unknown> = { text, role, transportKind: "text-rest" };
51
+ if (attachments && attachments.length > 0) {
52
+ data.attachments = [...attachments];
53
+ }
54
+ if (seededByPlugin) {
55
+ data.seededByPlugin = seededByPlugin;
56
+ }
33
57
  return {
34
58
  uuid: uuidv4(),
35
59
  toolName: "text-response",
36
60
  message: text,
37
61
  title: role === "user" ? "You" : "Assistant",
38
- data: { text, role, transportKind: "text-rest" },
62
+ data,
63
+ };
64
+ }
65
+
66
+ export interface SkillResultData {
67
+ skillName: string;
68
+ skillScope: SkillScope;
69
+ skillPath: string | null;
70
+ skillDescription: string | null;
71
+ /** Full SKILL.md body as Claude CLI synthesised it. Available in
72
+ * the data field for the View's expand toggle. */
73
+ body: string;
74
+ }
75
+
76
+ /** Build a synthetic skill-result envelope from a parsed jsonl
77
+ * `SkillEntry`. The skill plugin's View collapses by default to
78
+ * `<skillName> · <skillDescription>` and reveals `body` on toggle.
79
+ * Distinct from `makeTextResult` so the canvas can render it
80
+ * without the wall-of-text default applied to assistant prose. */
81
+ export function makeSkillResult(entry: {
82
+ skillName: string;
83
+ skillScope: SkillScope;
84
+ skillPath: string | null;
85
+ skillDescription: string | null;
86
+ message: string;
87
+ }): ToolResultComplete {
88
+ const data: SkillResultData = {
89
+ skillName: entry.skillName,
90
+ skillScope: entry.skillScope,
91
+ skillPath: entry.skillPath,
92
+ skillDescription: entry.skillDescription,
93
+ body: entry.message,
94
+ };
95
+ return {
96
+ uuid: uuidv4(),
97
+ toolName: SKILL_TOOL_NAME,
98
+ message: entry.skillDescription ?? entry.skillName,
99
+ title: `Skill: ${entry.skillName}`,
100
+ data: data as unknown as Record<string, unknown>,
39
101
  };
40
102
  }
package/src/vite-env.d.ts CHANGED
@@ -2,6 +2,12 @@
2
2
 
3
3
  interface ImportMetaEnv {
4
4
  readonly VITE_LOCALE?: "en" | "ja";
5
+ // Set `VITE_DEV_MODE=1` in `.env` to surface `isDebugRole` roles
6
+ // in the dropdown. Anything else (including unset, "0", "true",
7
+ // "yes") hides them — the consumer side does an exact `=== "1"`
8
+ // check so the type stays open to whatever string Vite hands
9
+ // through, instead of pretending only `"1" | "0"` are reachable.
10
+ readonly VITE_DEV_MODE?: string;
5
11
  }
6
12
 
7
13
  interface ImportMeta {