mulmoclaude 0.1.2 → 0.4.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 (251) hide show
  1. package/bin/mulmoclaude.js +7 -24
  2. package/client/assets/html2canvas-Cx501zZr-Cv5snK9D.js +5 -0
  3. package/client/assets/index-CubzmCVK.css +2 -0
  4. package/client/assets/{index-D8rhwXLq.js → index-DtcyExH9.js} +80 -61
  5. package/client/assets/{index.es-D4YyL_Dg-BfRHLTZV.js → index.es-D4YyL_Dg-DnizuhIY.js} +5 -5
  6. package/client/index.html +2 -4
  7. package/package.json +13 -13
  8. package/server/agent/attachmentConverter.ts +2 -2
  9. package/server/agent/config.ts +12 -12
  10. package/server/agent/index.ts +9 -3
  11. package/server/agent/mcp-server.ts +19 -19
  12. package/server/agent/mcp-tools/index.ts +6 -6
  13. package/server/agent/mcp-tools/x.ts +7 -6
  14. package/server/agent/prompt.ts +195 -29
  15. package/server/agent/resumeFailover.ts +5 -5
  16. package/server/agent/sandboxMounts.ts +10 -10
  17. package/server/agent/stream.ts +4 -4
  18. package/server/api/auth/bearerAuth.ts +3 -3
  19. package/server/api/auth/token.ts +2 -2
  20. package/server/api/routes/agent.ts +21 -3
  21. package/server/api/routes/config.ts +1 -1
  22. package/server/api/routes/files.ts +22 -21
  23. package/server/api/routes/html.ts +2 -2
  24. package/server/api/routes/image.ts +7 -7
  25. package/server/api/routes/mulmo-script.ts +33 -31
  26. package/server/api/routes/pdf.ts +2 -2
  27. package/server/api/routes/plugins.ts +16 -6
  28. package/server/api/routes/roles.ts +2 -2
  29. package/server/api/routes/scheduler.ts +14 -12
  30. package/server/api/routes/schedulerHandlers.ts +12 -12
  31. package/server/api/routes/schedulerTasks.ts +19 -17
  32. package/server/api/routes/sessions.ts +26 -26
  33. package/server/api/routes/sessionsCursor.ts +4 -4
  34. package/server/api/routes/skills.ts +5 -5
  35. package/server/api/routes/sources.ts +3 -3
  36. package/server/api/routes/todosColumnsHandlers.ts +30 -30
  37. package/server/api/routes/todosHandlers.ts +1 -1
  38. package/server/api/routes/todosItemsHandlers.ts +14 -14
  39. package/server/api/routes/wiki.ts +36 -22
  40. package/server/api/sandboxStatus.ts +1 -1
  41. package/server/events/notifications.ts +6 -6
  42. package/server/events/pub-sub/index.ts +3 -3
  43. package/server/events/relay-client.ts +17 -16
  44. package/server/events/scheduler-adapter.ts +20 -20
  45. package/server/events/session-store/index.ts +10 -10
  46. package/server/events/task-manager/index.ts +7 -7
  47. package/server/index.ts +59 -65
  48. package/server/system/config.ts +5 -5
  49. package/server/system/credentials.ts +7 -5
  50. package/server/system/env.ts +5 -5
  51. package/server/utils/date.ts +18 -18
  52. package/server/utils/files/atomic.ts +16 -16
  53. package/server/utils/files/html-io.ts +5 -5
  54. package/server/utils/files/image-store.ts +19 -8
  55. package/server/utils/files/journal-io.ts +4 -4
  56. package/server/utils/files/json.ts +5 -5
  57. package/server/utils/files/markdown-store.ts +4 -4
  58. package/server/utils/files/naming.ts +2 -2
  59. package/server/utils/files/reference-dirs-io.ts +3 -3
  60. package/server/utils/files/roles-io.ts +12 -12
  61. package/server/utils/files/safe.ts +14 -14
  62. package/server/utils/files/scheduler-io.ts +5 -5
  63. package/server/utils/files/scheduler-overrides-io.ts +2 -2
  64. package/server/utils/files/session-io.ts +35 -35
  65. package/server/utils/files/spreadsheet-store.ts +7 -7
  66. package/server/utils/files/todos-io.ts +9 -9
  67. package/server/utils/files/user-tasks-io.ts +5 -5
  68. package/server/utils/files/workspace-io.ts +12 -12
  69. package/server/utils/gemini.ts +2 -2
  70. package/server/utils/gitignore.ts +9 -9
  71. package/server/utils/json.ts +5 -5
  72. package/server/utils/logBackgroundError.ts +12 -3
  73. package/server/utils/markdown.ts +5 -5
  74. package/server/utils/port.d.mts +6 -0
  75. package/server/utils/port.mjs +48 -0
  76. package/server/utils/request.ts +12 -6
  77. package/server/utils/spawn.ts +1 -1
  78. package/server/utils/types.ts +2 -2
  79. package/server/workspace/chat-index/indexer.ts +15 -15
  80. package/server/workspace/chat-index/summarizer.ts +4 -4
  81. package/server/workspace/custom-dirs.ts +16 -16
  82. package/server/workspace/journal/archivist.ts +35 -35
  83. package/server/workspace/journal/dailyPass.ts +31 -28
  84. package/server/workspace/journal/diff.ts +2 -2
  85. package/server/workspace/journal/index.ts +4 -4
  86. package/server/workspace/journal/indexFile.ts +29 -25
  87. package/server/workspace/journal/optimizationPass.ts +2 -2
  88. package/server/workspace/journal/state.ts +6 -6
  89. package/server/workspace/paths.ts +3 -3
  90. package/server/workspace/reference-dirs.ts +20 -20
  91. package/server/workspace/roles.ts +6 -6
  92. package/server/workspace/skills/discovery.ts +4 -4
  93. package/server/workspace/skills/parser.ts +6 -6
  94. package/server/workspace/skills/scheduler.ts +3 -3
  95. package/server/workspace/skills/user-tasks.ts +34 -34
  96. package/server/workspace/skills/writer.ts +3 -3
  97. package/server/workspace/sources/arxivDiscovery.ts +10 -10
  98. package/server/workspace/sources/classifier.ts +7 -7
  99. package/server/workspace/sources/fetchers/arxiv.ts +7 -7
  100. package/server/workspace/sources/fetchers/githubIssues.ts +7 -7
  101. package/server/workspace/sources/fetchers/githubReleases.ts +7 -7
  102. package/server/workspace/sources/fetchers/rss.ts +5 -5
  103. package/server/workspace/sources/fetchers/rssParser.ts +4 -4
  104. package/server/workspace/sources/interests.ts +12 -12
  105. package/server/workspace/sources/paths.ts +6 -6
  106. package/server/workspace/sources/pipeline/fetch.ts +36 -13
  107. package/server/workspace/sources/pipeline/index.ts +8 -13
  108. package/server/workspace/sources/pipeline/notify.ts +3 -3
  109. package/server/workspace/sources/pipeline/plan.ts +15 -13
  110. package/server/workspace/sources/pipeline/write.ts +5 -5
  111. package/server/workspace/sources/rateLimiter.ts +1 -1
  112. package/server/workspace/sources/registry.ts +16 -16
  113. package/server/workspace/sources/robots.ts +14 -14
  114. package/server/workspace/sources/sourceState.ts +17 -10
  115. package/server/workspace/sources/types.ts +9 -0
  116. package/server/workspace/sources/urls.ts +1 -1
  117. package/server/workspace/tool-trace/classify.ts +4 -4
  118. package/server/workspace/tool-trace/index.ts +1 -1
  119. package/server/workspace/tool-trace/writeSearch.ts +26 -16
  120. package/server/workspace/wiki-backlinks/index.ts +8 -8
  121. package/server/workspace/wiki-backlinks/sessionBacklinks.ts +15 -15
  122. package/server/workspace/workspace.ts +7 -7
  123. package/src/App.vue +315 -141
  124. package/src/components/CanvasViewToggle.vue +10 -7
  125. package/src/components/ChatInput.vue +67 -33
  126. package/src/components/FileContentHeader.vue +7 -4
  127. package/src/components/FileContentRenderer.vue +20 -6
  128. package/src/components/FileTree.vue +6 -3
  129. package/src/components/FileTreePane.vue +11 -8
  130. package/src/components/FilesView.vue +5 -3
  131. package/src/components/LockStatusPopup.vue +17 -14
  132. package/src/components/NotificationBell.vue +14 -5
  133. package/src/components/NotificationToast.vue +6 -3
  134. package/src/components/PluginLauncher.vue +19 -56
  135. package/src/components/RightSidebar.vue +13 -10
  136. package/src/components/RoleSelector.vue +2 -2
  137. package/src/components/SessionHistoryPanel.vue +38 -34
  138. package/src/components/SessionTabBar.vue +8 -10
  139. package/src/components/SettingsMcpTab.vue +49 -36
  140. package/src/components/SettingsModal.vue +24 -22
  141. package/src/components/SettingsReferenceDirsTab.vue +39 -34
  142. package/src/components/SettingsWorkspaceDirsTab.vue +37 -27
  143. package/src/components/SidebarHeader.vue +25 -4
  144. package/src/components/StackView.vue +4 -1
  145. package/src/components/SuggestionsPanel.vue +7 -4
  146. package/src/components/TodoExplorer.vue +26 -15
  147. package/src/components/ToolResultsPanel.vue +27 -13
  148. package/src/components/todo/TodoAddDialog.vue +19 -14
  149. package/src/components/todo/TodoEditDialog.vue +7 -2
  150. package/src/components/todo/TodoEditPanel.vue +17 -12
  151. package/src/components/todo/TodoKanbanView.vue +10 -5
  152. package/src/components/todo/TodoListView.vue +10 -7
  153. package/src/components/todo/TodoTableView.vue +5 -2
  154. package/src/composables/useAppApi.ts +9 -0
  155. package/src/composables/useClickOutside.ts +2 -2
  156. package/src/composables/useDynamicFavicon.ts +172 -37
  157. package/src/composables/useEventListeners.ts +7 -8
  158. package/src/composables/useFaviconState.ts +13 -2
  159. package/src/composables/useFileSelection.ts +24 -6
  160. package/src/composables/useFreshPluginData.ts +3 -3
  161. package/src/composables/useKeyNavigation.ts +11 -11
  162. package/src/composables/useLayoutMode.ts +32 -0
  163. package/src/composables/useMcpTools.ts +2 -2
  164. package/src/composables/useNotifications.ts +3 -3
  165. package/src/composables/usePdfDownload.ts +4 -4
  166. package/src/composables/usePendingCalls.ts +1 -1
  167. package/src/composables/usePubSub.ts +10 -10
  168. package/src/composables/useRoles.ts +1 -1
  169. package/src/composables/useSandboxStatus.ts +1 -1
  170. package/src/composables/useSessionDerived.ts +3 -3
  171. package/src/composables/useSessionHistory.ts +7 -17
  172. package/src/composables/useSessionSync.ts +8 -8
  173. package/src/composables/useViewLayout.ts +20 -34
  174. package/src/config/roles.ts +2 -2
  175. package/src/lang/de.ts +536 -0
  176. package/src/lang/en.ts +558 -0
  177. package/src/lang/es.ts +543 -0
  178. package/src/lang/fr.ts +536 -0
  179. package/src/lang/ja.ts +536 -0
  180. package/src/lang/ko.ts +540 -0
  181. package/src/lang/pt-BR.ts +534 -0
  182. package/src/lang/zh.ts +537 -0
  183. package/src/lib/vue-i18n.ts +97 -0
  184. package/src/main.ts +2 -0
  185. package/src/plugins/canvas/View.vue +102 -186
  186. package/src/plugins/canvas/definition.ts +0 -8
  187. package/src/plugins/chart/Preview.vue +5 -5
  188. package/src/plugins/chart/View.vue +9 -4
  189. package/src/plugins/manageRoles/Preview.vue +4 -1
  190. package/src/plugins/manageRoles/View.vue +59 -43
  191. package/src/plugins/manageSkills/Preview.vue +8 -3
  192. package/src/plugins/manageSkills/View.vue +29 -25
  193. package/src/plugins/manageSource/Preview.vue +2 -2
  194. package/src/plugins/manageSource/View.vue +73 -52
  195. package/src/plugins/markdown/Preview.vue +1 -1
  196. package/src/plugins/markdown/View.vue +26 -36
  197. package/src/plugins/presentHtml/Preview.vue +1 -1
  198. package/src/plugins/presentHtml/View.vue +7 -4
  199. package/src/plugins/presentHtml/helpers.ts +8 -8
  200. package/src/plugins/presentMulmoScript/Preview.vue +1 -1
  201. package/src/plugins/presentMulmoScript/View.vue +40 -30
  202. package/src/plugins/presentMulmoScript/helpers.ts +1 -1
  203. package/src/plugins/scheduler/Preview.vue +13 -10
  204. package/src/plugins/scheduler/TasksTab.vue +57 -28
  205. package/src/plugins/scheduler/View.vue +28 -19
  206. package/src/plugins/scheduler/formatSchedule.ts +93 -0
  207. package/src/plugins/spreadsheet/Preview.vue +8 -3
  208. package/src/plugins/spreadsheet/View.vue +21 -12
  209. package/src/plugins/textResponse/Preview.vue +15 -58
  210. package/src/plugins/textResponse/View.vue +29 -9
  211. package/src/plugins/todo/Preview.vue +13 -8
  212. package/src/plugins/todo/View.vue +38 -24
  213. package/src/plugins/todo/composables/useTodos.ts +5 -5
  214. package/src/plugins/ui-image/ImagePreview.vue +6 -3
  215. package/src/plugins/ui-image/ImageView.vue +7 -4
  216. package/src/plugins/wiki/Preview.vue +10 -7
  217. package/src/plugins/wiki/View.vue +202 -81
  218. package/src/plugins/wiki/helpers.ts +4 -4
  219. package/src/plugins/wiki/route.ts +112 -0
  220. package/src/router/guards.ts +46 -28
  221. package/src/router/index.ts +41 -26
  222. package/src/types/session.ts +4 -3
  223. package/src/types/vue-i18n.d.ts +20 -0
  224. package/src/utils/agent/request.ts +22 -3
  225. package/src/utils/canvas/layoutMode.ts +26 -0
  226. package/src/utils/dom/scrollable.ts +2 -2
  227. package/src/utils/files/expandedDirs.ts +1 -1
  228. package/src/utils/files/sortChildren.ts +6 -6
  229. package/src/utils/format/frontmatter.ts +6 -6
  230. package/src/utils/image/cacheBust.ts +16 -0
  231. package/src/utils/image/resolve.ts +16 -0
  232. package/src/utils/image/rewriteMarkdownImageRefs.ts +5 -5
  233. package/src/utils/markdown/extractFirstH1.ts +2 -2
  234. package/src/utils/path/relativeLink.ts +15 -15
  235. package/src/utils/path/workspaceLinkRouter.ts +81 -0
  236. package/src/utils/role/icon.ts +2 -2
  237. package/src/utils/role/merge.ts +2 -2
  238. package/src/utils/role/plugins.ts +1 -1
  239. package/src/utils/session/sessionFactory.ts +2 -2
  240. package/src/utils/session/sessionHelpers.ts +2 -2
  241. package/src/utils/tools/dedup.ts +4 -4
  242. package/src/utils/tools/result.ts +3 -3
  243. package/src/utils/types.ts +2 -2
  244. package/src/vite-env.d.ts +9 -0
  245. package/client/assets/chunk-vKJrgz-R-C_I3GbVV.js +0 -1
  246. package/client/assets/html2canvas-Cx501zZr-BF5dYYkY.js +0 -5
  247. package/client/assets/index-KNLBjwuh.css +0 -1
  248. package/client/assets/typeof-DBp4T-Ny-BC0P-2DM.js +0 -1
  249. package/src/composables/useCanvasViewMode.ts +0 -121
  250. package/src/utils/canvas/viewMode.ts +0 -46
  251. /package/client/assets/{purify.es-Fx1Nqyry-PeS5RUhs.js → purify.es-Fx1Nqyry-BwJECkqS.js} +0 -0
package/src/lang/zh.ts ADDED
@@ -0,0 +1,537 @@
1
+ // Simplified Chinese dictionary. Mirror the shape of src/lang/en.ts —
2
+ // missing keys fall back to English per createI18n's fallbackLocale.
3
+ //
4
+ // ⚠️ 包含 `<name>` 等尖括号的字符串会触发 vue-i18n 的 XSS
5
+ // 检测,输出 "Detected HTML in '…' message" 警告。此类文案必须
6
+ // 改用 **函数形式**。详见 en.ts 的头部注释。
7
+
8
+ const zhMessages = {
9
+ common: {
10
+ save: "保存",
11
+ cancel: "取消",
12
+ loading: "加载中...",
13
+ close: "关闭",
14
+ dismiss: "关闭",
15
+ add: "添加",
16
+ remove: "移除",
17
+ saving: "保存中...",
18
+ saved: "已保存",
19
+ noResultsYet: "暂无结果",
20
+ noImageYet: "暂无图片",
21
+ },
22
+ sessionTabBar: {
23
+ newSession: "新建会话",
24
+ sessionHistory: "会话历史",
25
+ // 中文无单复数之分,但仍保留 `|` 分隔符以对齐 vue-i18n 的 pluralization 约定。
26
+ activeSessions: "{count} 个活动会话(代理运行中)",
27
+ unreadReplies: "{count} 条未读回复",
28
+ },
29
+ chatInput: {
30
+ placeholder: "输入任务,或拖放 / 粘贴 / 附加文件…",
31
+ expandEditor: "展开编辑器",
32
+ composeMessage: "撰写消息",
33
+ sendHint: "Cmd+Enter 发送",
34
+ send: "发送",
35
+ attachFile: "附加文件",
36
+ fileTooLarge: "文件过大({sizeMB} MB)。上限为 30 MB。",
37
+ unsupportedFileType: "不支持的文件类型。支持:图像、PDF、DOCX、XLSX、PPTX、文本文件。",
38
+ },
39
+ sessionHistoryPanel: {
40
+ filters: {
41
+ all: "全部",
42
+ unread: "未读",
43
+ human: "人工",
44
+ scheduler: "调度器",
45
+ skill: "技能",
46
+ bridge: "桥接",
47
+ },
48
+ failedToRefresh: "⚠ 刷新失败: {error}",
49
+ showingLastKnown: " — 正在显示上一次成功加载的列表。",
50
+ noSessions: "暂无会话。",
51
+ noMatching: "没有匹配的会话。",
52
+ running: "运行中",
53
+ unread: "未读",
54
+ noMessages: "(无消息)",
55
+ },
56
+ notificationBell: {
57
+ notifications: "通知",
58
+ markAllRead: "全部标为已读",
59
+ noNotifications: "暂无通知",
60
+ dismiss: "关闭",
61
+ },
62
+ sidebarHeader: {
63
+ home: "前往最新对话",
64
+ toolCallHistory: "工具调用历史",
65
+ settings: "设置",
66
+ },
67
+ rightSidebar: {
68
+ toggleSystemPrompt: "切换系统提示词",
69
+ systemPrompt: "系统提示词",
70
+ availableTools: "可用工具",
71
+ toggleToolDescription: "切换工具说明",
72
+ toolCallHistory: "工具调用历史",
73
+ noToolCalls: "还没有工具调用",
74
+ arguments: "参数",
75
+ error: "错误",
76
+ result: "结果",
77
+ running: "运行中...",
78
+ },
79
+ fileTreePane: {
80
+ sort: "排序:",
81
+ sortByName: "按名称排序",
82
+ name: "名称",
83
+ sortByRecent: "按修改日期排序(最新在前)",
84
+ recent: "最近",
85
+ reference: "引用",
86
+ // "RO" = Read-Only. 保留英文缩写作为紧凑徽章。
87
+ readOnlyBadge: "RO",
88
+ },
89
+ fileTree: {
90
+ workspace: "(工作区)",
91
+ recentlyChanged: "最近修改",
92
+ },
93
+ lockStatusPopup: {
94
+ sandboxEnabledTooltip: "沙箱已启用 (Docker)",
95
+ noSandboxTooltip: "未启用沙箱 (未找到 Docker)",
96
+ sandboxEnabledLabel: "沙箱已启用:",
97
+ sandboxEnabledBody: "Docker 正在运行。文件系统访问已隔离。",
98
+ noSandboxLabel: "未启用沙箱:",
99
+ noSandboxBodyPrefix: "Claude 可以访问你计算机上的所有文件。请安装",
100
+ noSandboxBodySuffix: "以启用文件系统隔离。",
101
+ dockerDesktop: "Docker Desktop",
102
+ hostCredentials: "已附加的宿主凭据:",
103
+ credsLoading: "加载中…",
104
+ sshAgent: "SSH 代理:",
105
+ forwarded: "已转发",
106
+ notForwarded: "未转发",
107
+ mountedConfigs: "挂载的配置:",
108
+ none: "无",
109
+ testIsolation: "测试沙箱隔离:",
110
+ },
111
+ settingsModal: {
112
+ title: "设置",
113
+ tabs: {
114
+ tools: "允许的工具",
115
+ mcp: "MCP 服务器",
116
+ dirs: "目录",
117
+ refs: "引用目录",
118
+ },
119
+ toolNamesLabel: "工具名称",
120
+ invalidToolNamesPrefix: "以下工具名看起来不符合规范(预期前缀",
121
+ invalidToolNamesSuffix: "):",
122
+ mcpToolsError: "⚠ 无法获取 MCP 工具状态: {error}。无论是否启用,均显示所有工具。",
123
+ changesHint: "修改在下一次发送消息时生效,无需重启。",
124
+ cannotSaveTooltip: "设置加载失败前无法保存",
125
+ saving: "保存中…",
126
+ loadingLabel: "加载中…",
127
+ },
128
+ canvasViewToggle: {
129
+ stackViewTooltip: "堆叠视图 · 点击切换到单一视图 (⌘1)",
130
+ singleViewTooltip: "单一视图 · 点击切换到堆叠视图 (⌘2)",
131
+ switchToSingle: "切换到单一视图",
132
+ switchToStack: "切换到堆叠视图",
133
+ },
134
+ settingsWorkspaceDirs: {
135
+ explanation: "自定义用于在 {dataDir} 和 {artifactsDir} 下组织文件的目录。Claude 会参照这些来决定文件保存路径。",
136
+ noEntries: "未配置自定义目录。",
137
+ addDirTitle: "添加目录",
138
+ pathPlaceholder: "data/clients 或 artifacts/reports",
139
+ descPlaceholder: "说明(这个文件夹里放什么)",
140
+ errPathRequired: "路径不能为空",
141
+ errMustStartWith: "必须以 data/ 或 artifacts/ 开头",
142
+ errAlreadyExists: "已存在",
143
+ },
144
+ settingsReferenceDirs: {
145
+ explanation: "Claude 可读取但不能修改的外部目录。Docker 模式下以只读方式挂载。适合引用 Obsidian 仓库、项目代码或文档文件夹。",
146
+ noEntries: "未配置引用目录。",
147
+ addDirTitle: "添加引用目录",
148
+ pathPlaceholder: "/Users/me/ObsidianVault 或 ~/Documents/notes",
149
+ labelPlaceholder: "标签(可选 — 默认为文件夹名)",
150
+ readOnlyBadge: "只读",
151
+ errPathRequired: "路径不能为空",
152
+ errMustBeAbsolute: "必须为绝对路径或以 ~/ 开头",
153
+ errAlreadyExists: "已存在",
154
+ errLabelConflict: '标签 "{label}" 已存在',
155
+ },
156
+ pluginLauncher: {
157
+ todos: { label: "待办", title: "打开待办 (⌘4)" },
158
+ scheduler: { label: "日程", title: "打开日程 (⌘5)" },
159
+ wiki: { label: "百科", title: "打开 Wiki (⌘6)" },
160
+ skills: { label: "技能", title: "打开技能 (⌘7)" },
161
+ roles: { label: "角色", title: "打开角色 (⌘8)" },
162
+ files: { label: "文件", title: "打开工作区文件 (⌘3)" },
163
+ },
164
+ fileContentHeader: {
165
+ showRendered: "显示渲染后的 Markdown",
166
+ showRaw: "显示原始源代码",
167
+ rendered: "已渲染",
168
+ raw: "原始",
169
+ closeFile: "关闭文件",
170
+ },
171
+ fileContentRenderer: {
172
+ selectFile: "请选择一个文件",
173
+ htmlPreview: "HTML 预览",
174
+ pdfPreview: "PDF 预览",
175
+ parseError: "解析错误",
176
+ },
177
+ settingsMcpTab: {
178
+ explanation:
179
+ "添加外部 MCP 服务器。HTTP 服务器在所有模式下都可用。Stdio 服务器使用沙箱镜像中的 {npx} / {node} / {tsx};启用 Docker 时,路径必须位于工作区内。",
180
+ localhostRewrite: "Docker 模式下 {localhost} 会被改写为 {hostDockerInternal}。",
181
+ noServers: "尚未配置 MCP 服务器。",
182
+ enabled: "已启用",
183
+ urlLabel: "URL:",
184
+ commandLabel: "命令:",
185
+ dockerNonWorkspaceWarning: "⚠ 包含工作区外部的路径 — 在 Docker 内无法解析。",
186
+ addServerButton: "+ 添加 MCP 服务器",
187
+ nameLabel: "名称",
188
+ namePlaceholder: "my-server",
189
+ typeHttp: "HTTP",
190
+ typeStdio: "Stdio(命令)",
191
+ urlFieldLabel: "URL",
192
+ urlPlaceholder: "https://example.com/mcp",
193
+ commandFieldLabel: "命令",
194
+ argsLabel: "参数(每行一个)",
195
+ // Message function form — 跳过 vue-i18n 的消息编译器,
196
+ // 避免字面量 `@` 被解析为 linked message 引用。
197
+ argsPlaceholder: () => "-y\n@modelcontextprotocol/server-filesystem\n/workspace/path",
198
+ errNoName: "请填写名称,或输入可用于推断名称的 URL / 参数。",
199
+ errBadName: "名称必须以小写字母开头,且仅包含 [a-z0-9_-]。",
200
+ errIdExists: '服务器 id "{id}" 已存在。',
201
+ errBadHttpUrl: "HTTP URL 必须以 http:// 或 https:// 开头",
202
+ },
203
+ pluginScheduler: {
204
+ prev: "上一个",
205
+ today: "今天",
206
+ goToday: "跳到今天",
207
+ next: "下一个",
208
+ deleteItem: "删除项目",
209
+ closeEditor: "关闭编辑器",
210
+ apiError: "⚠ 更新调度器失败: {error}",
211
+ tabCalendar: "日历",
212
+ tabTasks: "任务",
213
+ heading: "调度器",
214
+ itemCount: "{count} 个项目",
215
+ noScheduled: "没有计划中的项目",
216
+ unscheduled: "未安排",
217
+ editItem: "编辑项目",
218
+ update: "更新",
219
+ editSource: "编辑源",
220
+ applyChanges: "应用更改",
221
+ propLabel: "{key}:",
222
+ moreCount: "+还有 {count} 个",
223
+ previewIcon: "📅",
224
+ previewUpcoming: "即将 {count} 个",
225
+ previewMore: "+ 还有 {count} 个…",
226
+ },
227
+ pluginSchedulerTasks: {
228
+ recommendedFrequencies: "推荐频率",
229
+ tableTaskType: "任务类型",
230
+ tableSuggestedSchedule: "建议的计划",
231
+ noTasks: "没有计划任务",
232
+ runNow: "立即运行",
233
+ enable: "启用",
234
+ disable: "停用",
235
+ delete: "删除",
236
+ nextRun: "下次: {time}",
237
+ originSystem: "系统",
238
+ originUser: "用户",
239
+ originSkill: "技能",
240
+ runFailed: "运行失败: {error}",
241
+ toggleFailed: "切换失败: {error}",
242
+ deleteFailed: "删除失败: {error}",
243
+ },
244
+ pluginCanvas: {
245
+ undo: "撤销",
246
+ redo: "重做",
247
+ clear: "清除",
248
+ styleLabel: "样式:",
249
+ },
250
+ pluginChart: {
251
+ untitled: "图表",
252
+ chartCount: "{count} 个图表",
253
+ chartTitle: "图表 {num}",
254
+ png: "PNG",
255
+ },
256
+ pluginTodo: {
257
+ clearFilters: "清除所有筛选",
258
+ deleteItem: "删除项目",
259
+ apiError: "⚠ 更新待办失败: {error}",
260
+ heading: "待办列表",
261
+ completedRatio: "{done}/{total} 已完成",
262
+ filter: "筛选:",
263
+ noItems: "还没有待办项",
264
+ noMatchingFilter: "没有项目匹配当前筛选",
265
+ update: "更新",
266
+ clearCompleted: "清除已完成",
267
+ clearButton: "清除 ✕",
268
+ deleteSymbol: "✕",
269
+ },
270
+ todoExplorer: {
271
+ heading: "待办",
272
+ doneRatio: "{done}/{total} 完成",
273
+ addButton: "+ 添加",
274
+ addColumnButton: "+ 列",
275
+ labels: "标签:",
276
+ searchPlaceholder: "搜索...",
277
+ clearButton: "清除 ✕",
278
+ clearFiltersTitle: "清除标签筛选",
279
+ emptyHint: '还没有待办项。点击 "+ 添加" 新建一个。',
280
+ addColumn: "添加列",
281
+ newColumnLabelField: "标签",
282
+ newColumnPlaceholder: "Review",
283
+ noMatchingFilter: "没有项目匹配当前筛选",
284
+ },
285
+ todoPreview: {
286
+ completedRatio: "{done}/{total} 已完成",
287
+ moreItems: "+ 还有 {count} 项…",
288
+ headerIcon: "☑",
289
+ doneIcon: "✓",
290
+ pendingIcon: "○",
291
+ moreLabels: "+{count}",
292
+ },
293
+ todoDialogs: {
294
+ addTitle: "添加待办",
295
+ editTitle: "编辑待办",
296
+ deleteButton: "删除",
297
+ deleteTitle: "删除此项",
298
+ noneOption: "— 无 —",
299
+ fieldText: "文本",
300
+ fieldNote: "备注",
301
+ fieldStatus: "状态",
302
+ fieldPriority: "优先级",
303
+ fieldDueDate: "截止日期",
304
+ fieldLabels: "标签",
305
+ fieldLabelsCommaSeparated: "标签(逗号分隔)",
306
+ textPlaceholder: "要做什么?",
307
+ labelsPlaceholder: "工作, 紧急",
308
+ },
309
+ todoKanban: {
310
+ rename: "重命名",
311
+ alreadyDoneColumn: "已经是完成列",
312
+ markAsDoneColumn: "设为完成列",
313
+ deleteColumn: "删除列",
314
+ columnActions: "列操作",
315
+ addCard: "+ 添加卡片",
316
+ },
317
+ todoTableList: {
318
+ noMatchingFilter: "没有项目匹配当前筛选",
319
+ },
320
+ pluginWiki: {
321
+ backToIndex: "返回目录",
322
+ pdf: "PDF",
323
+ pdfFailed: "⚠ PDF 失败",
324
+ tabIndex: "目录",
325
+ tabLog: "日志",
326
+ tabLint: "Lint",
327
+ empty: "Wiki 为空。请让 Wiki 管理器采集一个数据源。",
328
+ previewMore: "+ 还有 {count} 项…",
329
+ chatPlaceholder: "就本页提问…",
330
+ chatSend: "就本页开启新对话",
331
+ },
332
+ pluginPresentHtml: {
333
+ saveAsPdf: "另存为 PDF(打开打印对话框)",
334
+ pdf: "PDF",
335
+ untitled: "HTML 页面",
336
+ hideSource: "隐藏源代码 <>",
337
+ showSource: "显示源代码 <>",
338
+ },
339
+ pluginManageSource: {
340
+ titlePlaceholder: "标题(可选)",
341
+ heading: "信息源",
342
+ sourceCount: "{count} 个信息源",
343
+ addButton: "添加",
344
+ rebuildNow: "立即重建",
345
+ rebuilding: "重建中…",
346
+ typeField: "类型",
347
+ addingLabel: "添加中…",
348
+ addAndRebuild: "添加并重建",
349
+ emptyPickPack: "尚未注册任何信息源。可以从下方的初始包挑选、点击上方的 {addBold},或让 Claude 帮你注册。",
350
+ emptyAddStrong: "+ 添加",
351
+ registering: "注册并抓取中…",
352
+ removeLabel: "移除",
353
+ removingLabel: "移除中…",
354
+ todaysBrief: "今日简报",
355
+ todaysBriefLoading: "正在加载今日简报…",
356
+ briefNone: "还没有写入当天的简报。请点击 立即重建。",
357
+ briefEmpty: "今天的简报为空。",
358
+ briefLoadFailed: "简报加载失败",
359
+ lastRebuildSummary: "上次重建({date}): 从 {planned} 个信息源得到 {itemCount} 项,丢弃重复项 {duplicates} 个。",
360
+ archiveErrorsSuffix: "(归档错误 {count} 个)",
361
+ kindRss: "RSS",
362
+ kindGithubRel: "GitHub 发布",
363
+ kindGithubIss: "GitHub 议题",
364
+ kindArxiv: "arXiv",
365
+ kindGithubReleases: "GitHub 发布",
366
+ kindGithubIssues: "GitHub 议题",
367
+ briefDateLabel: "({date})",
368
+ primaryRssPlaceholder: "https://news.ycombinator.com/rss",
369
+ primaryGithubPlaceholder: "https://github.com/owner/repo (或 owner/repo)",
370
+ primaryArxivPlaceholder: "cat:cs.CL",
371
+ primaryRssHint: "Feed URL(RSS 2.0 / Atom / RDF)",
372
+ primaryGithubRelHint: "GitHub 仓库 URL 或 owner/repo — 抓取 releases",
373
+ primaryGithubIssHint: "GitHub 仓库 URL 或 owner/repo — 抓取 issues",
374
+ primaryArxivHint: "arXiv 搜索表达式(例如 cat:cs.CL 或 au:hinton)",
375
+ confirmRemove: '要移除信息源 "{slug}" 吗?',
376
+ flashRegistered: "已注册。正在抓取新项目…",
377
+ flashRebuildReady: "就绪: 从 {planned} 个信息源得到 {itemCount} 项。",
378
+ flashRebuildComplete: "重建完成: 从 {planned} 个信息源得到 {itemCount} 项。",
379
+ flashRebuildFailed: "重建失败: {error}",
380
+ flashRegisterFailed: "注册信息源失败",
381
+ flashRegisterSucceededRebuildFailed: "注册成功但重建失败: {error}",
382
+ flashRemoved: '已移除 "{slug}"。',
383
+ flashRemoveFailed: "移除失败: {error}",
384
+ flashRefreshListFailed: "刷新信息源列表失败: {error}",
385
+ flashPresetAlreadyRegistered: '"{label}" 中的所有信息源均已注册。',
386
+ flashPresetRegistered: '已从 "{label}" 注册 {count} 个信息源。正在抓取…',
387
+ flashPresetPartial: "已注册 {ok}/{total}。错误: {errors}",
388
+ },
389
+ pluginManageSkills: {
390
+ deleteProjectSkill: "删除此项目级技能",
391
+ heading: "技能",
392
+ previewCount: "{count} 个技能",
393
+ previewMore: "+还有 {count} 个",
394
+ // 使用函数形式绕过 vue-i18n 的消息编译器,否则 `<name>`
395
+ // 会被当作 HTML 片段,每次挂载都会触发
396
+ // "Detected HTML in '…' message" 警告。
397
+ subheading: ({ named }: { named: (key: string) => unknown }) => `${named("count")} 个可用 · 点击查看 · "Run" 会以 /<name> 的形式调用`,
398
+ emptyWithPath: "未找到技能。请在 {path} 下添加技能文件夹。",
399
+ emptySkillPath: "~/.claude/skills/",
400
+ selectHint: "在左侧选择一个技能以查看其 SKILL.md。",
401
+ loading: "加载中…",
402
+ fieldDescription: "说明",
403
+ fieldBody: "正文 (Markdown)",
404
+ emptyBody: "(正文为空)",
405
+ btnEdit: "编辑",
406
+ btnDelete: "删除",
407
+ btnRun: "运行",
408
+ errListFailed: "加载技能列表失败: {error}",
409
+ errDetailFailed: "加载技能详情失败: {error}",
410
+ errSaveFailed: "保存失败: {error}",
411
+ errDeleteFailed: "删除失败",
412
+ confirmDelete: '要删除技能 "{name}" 吗?将会移除 ~/mulmoclaude/.claude/skills/{name}/SKILL.md。',
413
+ },
414
+ pluginManageRoles: {
415
+ heading: "自定义角色",
416
+ roleCount: "{count} 个角色",
417
+ previewCount: "{count} 个自定义角色",
418
+ addButton: "+ 添加",
419
+ createPanel: "创建新角色",
420
+ fieldId: "ID",
421
+ fieldName: "名称",
422
+ fieldIcon: "图标",
423
+ fieldPrompt: "提示词",
424
+ fieldPlugins: "插件",
425
+ fieldStarterQueries: "启动提问",
426
+ onePerLine: "(每行一个)",
427
+ helpLink: "?",
428
+ idFormatted: "({id})",
429
+ missingEnv: "(缺少 {env})",
430
+ requiresEnv: "需要在 .env 中设置 {env}",
431
+ collapse: "折叠",
432
+ expand: "展开",
433
+ idPlaceholder: "unique-id",
434
+ creating: "创建中…",
435
+ create: "创建",
436
+ updating: "更新中…",
437
+ update: "更新",
438
+ cancel: "取消",
439
+ delete: "删除",
440
+ emptyHint: '还没有自定义角色。点击 "+ 添加" 或让 Claude 帮你创建一个。',
441
+ errIdRequired: "ID 不能为空。",
442
+ errIdInvalid: "ID 只能包含字母、数字、'-' 和 '_'。",
443
+ errNameRequired: "名称不能为空。",
444
+ errIdDuplicate: "已存在 ID 为 '{id}' 的角色。",
445
+ errCreateFailed: "创建失败",
446
+ errSaveFailed: "保存失败",
447
+ errDeleteFailed: "删除失败",
448
+ errNetworkError: "网络错误",
449
+ errServerError: "服务器错误: {status}",
450
+ },
451
+ pluginUiImage: {
452
+ promptLabel: "{label}:",
453
+ },
454
+ pluginMulmoScript: {
455
+ beatCount: "{count} 个 beat",
456
+ movie: "视频",
457
+ generating: "生成中…",
458
+ rendering: "渲染中…",
459
+ saving: "保存中…",
460
+ update: "更新",
461
+ characters: "角色",
462
+ drop: "拖放",
463
+ gen: "生成",
464
+ play: "▶ 播放",
465
+ stop: "■ 停止",
466
+ errPrefix: "⚠ 错误",
467
+ noBeats: "脚本中没有找到 beat",
468
+ editSource: "编辑脚本源",
469
+ applyChanges: "应用更改",
470
+ generateAll: "全部生成",
471
+ orDropImage: "或拖入图片",
472
+ generate: "生成",
473
+ generateAudio: "♪ 生成",
474
+ saveErrorInvalidJson: "⚠ JSON 无效: {error}",
475
+ saveErrorSaveFailed: "⚠ 保存失败: {error}",
476
+ },
477
+ pluginMarkdown: {
478
+ loading: "正在加载文档...",
479
+ loadFailed: "⚠ 加载文档失败: {error}",
480
+ refreshFailed: "⚠ 刷新文档失败: {error} — 正在显示上次成功加载的内容。",
481
+ noContent: "没有可用的 Markdown 内容",
482
+ pdf: "PDF",
483
+ pdfFailedShort: "⚠ PDF 失败",
484
+ editSource: "编辑 Markdown 源",
485
+ saving: "保存中...",
486
+ applyChanges: "应用更改",
487
+ cancel: "取消",
488
+ saveFailed: "保存失败: {error}",
489
+ saveError: "⚠ 保存失败: {error}",
490
+ copyLabel: "复制",
491
+ copiedLabel: "已复制!",
492
+ },
493
+ pluginTextResponse: {
494
+ pdf: "PDF",
495
+ pdfFailed: "⚠ PDF 失败",
496
+ editContent: "编辑文本内容",
497
+ applyChanges: "应用更改",
498
+ copyLabel: "复制",
499
+ copiedLabel: "已复制!",
500
+ cancel: "取消",
501
+ },
502
+ pluginSpreadsheet: {
503
+ previewLabel: "📊 电子表格",
504
+ previewUntitled: "电子表格",
505
+ previewSheets: "{count} 个工作表",
506
+ untitled: "电子表格",
507
+ excel: "Excel",
508
+ valuePlaceholder: "值",
509
+ valueOrFormulaPlaceholder: "值或公式(例如 100 或 SUM(B2:B11))",
510
+ formatPlaceholder: "格式(例如 $#,##0.00)",
511
+ loading: "正在加载电子表格...",
512
+ noData: "没有可用的电子表格数据",
513
+ editData: "编辑电子表格数据",
514
+ applyChanges: "应用更改",
515
+ update: "更新",
516
+ stringType: "字符串",
517
+ formulaType: "公式",
518
+ },
519
+ app: {
520
+ // `<i18n-t>` 插槽 — 命名为 `envKey` / `envFile`,在 App.vue 中作为
521
+ // 行内 `<code>` 渲染,因此字面的变量名和文件名保持不翻译。
522
+ geminiRequired: "图像生成需要 {envKey}。请将它加入 {envFile} 并重启应用。",
523
+ startConversation: "开始对话",
524
+ },
525
+ suggestionsPanel: {
526
+ suggestions: "建议",
527
+ sendEditHint: "点击发送 · shift+点击可编辑",
528
+ },
529
+ settingsToolsTab: {
530
+ // 通过 <i18n-t> 以命名插槽 `allowedTools` 和 `claudeMcp` 渲染,
531
+ // 以便保留 `<code>` 标签的样式,同时文本可本地化。
532
+ explanation:
533
+ "要通过 {allowedTools} 传递给 Claude 的额外工具名。每行一个。适用于在 {claudeMcp} 完成授权后,调用 Claude Code 内置的 MCP 服务器(如 Gmail / Google 日历)。",
534
+ },
535
+ };
536
+
537
+ export default zhMessages;
@@ -0,0 +1,97 @@
1
+ // vue-i18n setup.
2
+ //
3
+ // Locale resolution priority (highest → lowest):
4
+ // 1. `VITE_LOCALE` env var — explicit build-time / dev override
5
+ // (e.g. `VITE_LOCALE=ja yarn dev`)
6
+ // 2. Browser language list (`navigator.languages` falling back to
7
+ // `navigator.language`) — the browser inherits this from the OS,
8
+ // so Japanese-machine users get Japanese automatically without
9
+ // extra config. First entry that matches a supported locale wins.
10
+ // 3. Hard default `"en"`
11
+ //
12
+ // Language tags like `"ja-JP"` are matched by primary subtag, so
13
+ // `ja-JP`, `ja-Hira-JP`, etc. all collapse to `"ja"`. Unknown tags
14
+ // (`"fr-FR"`) skip to the next candidate.
15
+ //
16
+ // `legacy: false` switches vue-i18n to the Composition API mode, so
17
+ // components call `const { t } = useI18n()` instead of relying on
18
+ // the Options API `this.$t`. CLAUDE.md mandates Composition API.
19
+
20
+ import { createI18n } from "vue-i18n";
21
+ import enMessages from "../lang/en";
22
+ import jaMessages from "../lang/ja";
23
+ import zhMessages from "../lang/zh";
24
+ import koMessages from "../lang/ko";
25
+ import esMessages from "../lang/es";
26
+ import ptBRMessages from "../lang/pt-BR";
27
+ import frMessages from "../lang/fr";
28
+ import deMessages from "../lang/de";
29
+
30
+ // Schema generic on createI18n — this is what makes `t("common.save")`
31
+ // calls across the whole app compile-time checked (the module
32
+ // augmentation in src/types/vue-i18n.d.ts alone is not enough; vue-i18n
33
+ // v11's `t` overloads still fall back to `string` unless the schema is
34
+ // threaded through here).
35
+ type MessageSchema = typeof enMessages;
36
+ type Locale = "en" | "ja" | "zh" | "ko" | "es" | "pt-BR" | "fr" | "de";
37
+
38
+ const SUPPORTED_LOCALES: readonly Locale[] = ["en", "ja", "zh", "ko", "es", "pt-BR", "fr", "de"] as const;
39
+ const DEFAULT_LOCALE: Locale = "en";
40
+
41
+ function isSupported(tag: string): tag is Locale {
42
+ return (SUPPORTED_LOCALES as readonly string[]).includes(tag);
43
+ }
44
+
45
+ // Match the full tag first (so `pt-BR` resolves exactly), then collapse
46
+ // `ja-JP`, `ja-Hira-JP`, etc. to their primary subtag. Returns null when
47
+ // neither the full tag nor the primary subtag is supported.
48
+ function primarySubtagIfSupported(tag: string): Locale | null {
49
+ if (isSupported(tag)) return tag;
50
+ const lower = tag.toLowerCase();
51
+ for (const supported of SUPPORTED_LOCALES) {
52
+ if (supported.toLowerCase() === lower) return supported;
53
+ }
54
+ const primary = lower.split("-")[0];
55
+ return isSupported(primary) ? primary : null;
56
+ }
57
+
58
+ function detectLocale(): Locale {
59
+ // 1. explicit env override
60
+ const envLocale = import.meta.env.VITE_LOCALE;
61
+ if (typeof envLocale === "string" && isSupported(envLocale)) {
62
+ return envLocale;
63
+ }
64
+
65
+ // 2. browser / OS preference list
66
+ if (typeof navigator !== "undefined") {
67
+ const preferred = navigator.languages && navigator.languages.length > 0 ? navigator.languages : [navigator.language];
68
+ for (const tag of preferred) {
69
+ if (typeof tag !== "string") continue;
70
+ const match = primarySubtagIfSupported(tag);
71
+ if (match) return match;
72
+ }
73
+ }
74
+
75
+ // 3. hard default
76
+ return DEFAULT_LOCALE;
77
+ }
78
+
79
+ const locale = detectLocale();
80
+
81
+ const i18n = createI18n<[MessageSchema], Locale>({
82
+ legacy: false,
83
+ locale,
84
+ fallbackLocale: "en",
85
+ messages: {
86
+ en: enMessages,
87
+ ja: jaMessages,
88
+ zh: zhMessages,
89
+ ko: koMessages,
90
+ es: esMessages,
91
+ "pt-BR": ptBRMessages,
92
+ fr: frMessages,
93
+ de: deMessages,
94
+ },
95
+ });
96
+
97
+ export default i18n;
package/src/main.ts CHANGED
@@ -2,6 +2,7 @@ import { createApp } from "vue";
2
2
  import App from "./App.vue";
3
3
  import router from "./router/index";
4
4
  import { installGuards } from "./router/guards";
5
+ import i18n from "./lib/vue-i18n";
5
6
  import { setAuthToken } from "./utils/api";
6
7
  import { readAuthTokenFromMeta } from "./utils/dom/authTokenMeta";
7
8
  import "./index.css";
@@ -22,4 +23,5 @@ installGuards(router);
22
23
 
23
24
  const app = createApp(App);
24
25
  app.use(router);
26
+ app.use(i18n);
25
27
  app.mount("#app");