mulmoclaude 0.3.0 → 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 (185) 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-eHWB79u5.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/index.ts +9 -3
  10. package/server/agent/mcp-tools/index.ts +6 -6
  11. package/server/agent/mcp-tools/x.ts +2 -1
  12. package/server/agent/prompt.ts +187 -26
  13. package/server/agent/resumeFailover.ts +5 -5
  14. package/server/agent/sandboxMounts.ts +3 -3
  15. package/server/api/auth/bearerAuth.ts +3 -3
  16. package/server/api/auth/token.ts +2 -2
  17. package/server/api/routes/agent.ts +21 -3
  18. package/server/api/routes/config.ts +1 -1
  19. package/server/api/routes/files.ts +13 -12
  20. package/server/api/routes/html.ts +2 -2
  21. package/server/api/routes/image.ts +7 -7
  22. package/server/api/routes/mulmo-script.ts +33 -31
  23. package/server/api/routes/pdf.ts +2 -2
  24. package/server/api/routes/plugins.ts +16 -6
  25. package/server/api/routes/roles.ts +2 -2
  26. package/server/api/routes/scheduler.ts +8 -6
  27. package/server/api/routes/schedulerTasks.ts +5 -3
  28. package/server/api/routes/sessions.ts +2 -2
  29. package/server/api/routes/sessionsCursor.ts +4 -4
  30. package/server/api/routes/skills.ts +5 -5
  31. package/server/api/routes/sources.ts +3 -3
  32. package/server/api/routes/todosHandlers.ts +1 -1
  33. package/server/api/routes/todosItemsHandlers.ts +14 -14
  34. package/server/api/routes/wiki.ts +22 -8
  35. package/server/api/sandboxStatus.ts +1 -1
  36. package/server/events/notifications.ts +6 -6
  37. package/server/events/pub-sub/index.ts +3 -3
  38. package/server/events/relay-client.ts +17 -16
  39. package/server/index.ts +40 -46
  40. package/server/system/config.ts +5 -5
  41. package/server/system/credentials.ts +7 -5
  42. package/server/system/env.ts +5 -5
  43. package/server/utils/files/atomic.ts +11 -11
  44. package/server/utils/files/image-store.ts +17 -6
  45. package/server/utils/files/journal-io.ts +2 -2
  46. package/server/utils/files/json.ts +5 -5
  47. package/server/utils/files/markdown-store.ts +4 -4
  48. package/server/utils/files/reference-dirs-io.ts +3 -3
  49. package/server/utils/files/roles-io.ts +4 -4
  50. package/server/utils/files/safe.ts +14 -14
  51. package/server/utils/files/scheduler-overrides-io.ts +2 -2
  52. package/server/utils/files/spreadsheet-store.ts +5 -5
  53. package/server/utils/files/workspace-io.ts +12 -12
  54. package/server/utils/gemini.ts +2 -2
  55. package/server/utils/gitignore.ts +9 -9
  56. package/server/utils/json.ts +5 -5
  57. package/server/utils/logBackgroundError.ts +12 -3
  58. package/server/utils/markdown.ts +5 -5
  59. package/server/utils/port.d.mts +6 -0
  60. package/server/utils/port.mjs +48 -0
  61. package/server/utils/request.ts +12 -6
  62. package/server/utils/spawn.ts +1 -1
  63. package/server/utils/types.ts +2 -2
  64. package/server/workspace/chat-index/summarizer.ts +4 -4
  65. package/server/workspace/custom-dirs.ts +5 -5
  66. package/server/workspace/journal/diff.ts +2 -2
  67. package/server/workspace/journal/index.ts +4 -4
  68. package/server/workspace/journal/optimizationPass.ts +2 -2
  69. package/server/workspace/journal/state.ts +6 -6
  70. package/server/workspace/paths.ts +3 -3
  71. package/server/workspace/reference-dirs.ts +3 -3
  72. package/server/workspace/skills/parser.ts +6 -6
  73. package/server/workspace/skills/scheduler.ts +3 -3
  74. package/server/workspace/skills/writer.ts +3 -3
  75. package/server/workspace/sources/arxivDiscovery.ts +2 -2
  76. package/server/workspace/sources/fetchers/rss.ts +5 -5
  77. package/server/workspace/sources/fetchers/rssParser.ts +4 -4
  78. package/server/workspace/sources/interests.ts +3 -3
  79. package/server/workspace/sources/paths.ts +6 -6
  80. package/server/workspace/sources/pipeline/fetch.ts +36 -13
  81. package/server/workspace/sources/pipeline/index.ts +2 -7
  82. package/server/workspace/sources/pipeline/notify.ts +3 -3
  83. package/server/workspace/sources/pipeline/plan.ts +11 -9
  84. package/server/workspace/sources/pipeline/write.ts +5 -5
  85. package/server/workspace/sources/rateLimiter.ts +1 -1
  86. package/server/workspace/sources/sourceState.ts +9 -4
  87. package/server/workspace/sources/types.ts +9 -0
  88. package/server/workspace/sources/urls.ts +1 -1
  89. package/server/workspace/tool-trace/classify.ts +4 -4
  90. package/server/workspace/workspace.ts +7 -7
  91. package/src/App.vue +286 -112
  92. package/src/components/CanvasViewToggle.vue +10 -7
  93. package/src/components/ChatInput.vue +60 -26
  94. package/src/components/FileContentHeader.vue +7 -4
  95. package/src/components/FileContentRenderer.vue +20 -6
  96. package/src/components/FileTree.vue +6 -3
  97. package/src/components/FileTreePane.vue +11 -8
  98. package/src/components/FilesView.vue +5 -3
  99. package/src/components/LockStatusPopup.vue +15 -12
  100. package/src/components/NotificationBell.vue +14 -5
  101. package/src/components/NotificationToast.vue +4 -1
  102. package/src/components/PluginLauncher.vue +19 -56
  103. package/src/components/RightSidebar.vue +13 -10
  104. package/src/components/SessionHistoryPanel.vue +33 -29
  105. package/src/components/SessionTabBar.vue +8 -10
  106. package/src/components/SettingsMcpTab.vue +43 -30
  107. package/src/components/SettingsModal.vue +21 -19
  108. package/src/components/SettingsReferenceDirsTab.vue +29 -24
  109. package/src/components/SettingsWorkspaceDirsTab.vue +32 -22
  110. package/src/components/SidebarHeader.vue +25 -4
  111. package/src/components/StackView.vue +4 -1
  112. package/src/components/SuggestionsPanel.vue +5 -2
  113. package/src/components/TodoExplorer.vue +26 -15
  114. package/src/components/ToolResultsPanel.vue +27 -13
  115. package/src/components/todo/TodoAddDialog.vue +17 -12
  116. package/src/components/todo/TodoEditDialog.vue +7 -2
  117. package/src/components/todo/TodoEditPanel.vue +15 -10
  118. package/src/components/todo/TodoKanbanView.vue +10 -5
  119. package/src/components/todo/TodoListView.vue +5 -2
  120. package/src/components/todo/TodoTableView.vue +5 -2
  121. package/src/composables/useAppApi.ts +9 -0
  122. package/src/composables/useDynamicFavicon.ts +172 -37
  123. package/src/composables/useEventListeners.ts +7 -8
  124. package/src/composables/useFaviconState.ts +13 -2
  125. package/src/composables/useFileSelection.ts +24 -6
  126. package/src/composables/useLayoutMode.ts +32 -0
  127. package/src/composables/useSessionHistory.ts +7 -17
  128. package/src/composables/useViewLayout.ts +20 -34
  129. package/src/lang/de.ts +536 -0
  130. package/src/lang/en.ts +558 -0
  131. package/src/lang/es.ts +543 -0
  132. package/src/lang/fr.ts +536 -0
  133. package/src/lang/ja.ts +536 -0
  134. package/src/lang/ko.ts +540 -0
  135. package/src/lang/pt-BR.ts +534 -0
  136. package/src/lang/zh.ts +537 -0
  137. package/src/lib/vue-i18n.ts +97 -0
  138. package/src/main.ts +2 -0
  139. package/src/plugins/canvas/View.vue +102 -186
  140. package/src/plugins/canvas/definition.ts +0 -8
  141. package/src/plugins/chart/Preview.vue +1 -1
  142. package/src/plugins/chart/View.vue +9 -4
  143. package/src/plugins/manageRoles/Preview.vue +4 -1
  144. package/src/plugins/manageRoles/View.vue +59 -43
  145. package/src/plugins/manageSkills/Preview.vue +8 -3
  146. package/src/plugins/manageSkills/View.vue +26 -22
  147. package/src/plugins/manageSource/Preview.vue +1 -1
  148. package/src/plugins/manageSource/View.vue +73 -52
  149. package/src/plugins/markdown/Preview.vue +1 -1
  150. package/src/plugins/markdown/View.vue +24 -34
  151. package/src/plugins/presentHtml/Preview.vue +1 -1
  152. package/src/plugins/presentHtml/View.vue +7 -4
  153. package/src/plugins/presentMulmoScript/Preview.vue +1 -1
  154. package/src/plugins/presentMulmoScript/View.vue +36 -26
  155. package/src/plugins/scheduler/Preview.vue +7 -4
  156. package/src/plugins/scheduler/TasksTab.vue +53 -24
  157. package/src/plugins/scheduler/View.vue +28 -19
  158. package/src/plugins/scheduler/formatSchedule.ts +93 -0
  159. package/src/plugins/spreadsheet/Preview.vue +8 -3
  160. package/src/plugins/spreadsheet/View.vue +21 -12
  161. package/src/plugins/textResponse/Preview.vue +15 -58
  162. package/src/plugins/textResponse/View.vue +27 -7
  163. package/src/plugins/todo/Preview.vue +11 -6
  164. package/src/plugins/todo/View.vue +27 -13
  165. package/src/plugins/ui-image/ImagePreview.vue +6 -3
  166. package/src/plugins/ui-image/ImageView.vue +7 -4
  167. package/src/plugins/wiki/Preview.vue +5 -2
  168. package/src/plugins/wiki/View.vue +202 -81
  169. package/src/plugins/wiki/route.ts +112 -0
  170. package/src/router/guards.ts +42 -24
  171. package/src/router/index.ts +41 -26
  172. package/src/types/vue-i18n.d.ts +20 -0
  173. package/src/utils/agent/request.ts +19 -0
  174. package/src/utils/canvas/layoutMode.ts +26 -0
  175. package/src/utils/image/cacheBust.ts +16 -0
  176. package/src/utils/image/resolve.ts +16 -0
  177. package/src/utils/path/workspaceLinkRouter.ts +81 -0
  178. package/src/vite-env.d.ts +9 -0
  179. package/client/assets/chunk-vKJrgz-R-C_I3GbVV.js +0 -1
  180. package/client/assets/html2canvas-Cx501zZr-BF5dYYkY.js +0 -5
  181. package/client/assets/index-Bm70FDU2.css +0 -1
  182. package/client/assets/typeof-DBp4T-Ny-BC0P-2DM.js +0 -1
  183. package/src/composables/useCanvasViewMode.ts +0 -121
  184. package/src/utils/canvas/viewMode.ts +0 -46
  185. /package/client/assets/{purify.es-Fx1Nqyry-PeS5RUhs.js → purify.es-Fx1Nqyry-BwJECkqS.js} +0 -0
package/src/lang/en.ts ADDED
@@ -0,0 +1,558 @@
1
+ // English dictionary for vue-i18n.
2
+ //
3
+ // Structure is grouped by feature area (common, chat, session, ...).
4
+ // Prefer nested objects over flat keys so related strings stay
5
+ // together and the namespace serves as self-documentation.
6
+
7
+ // No `as const` — the module augmentation in src/types/vue-i18n.d.ts
8
+ // reads `typeof en` to feed `DefineLocaleMessage`, and readonly literal
9
+ // types would conflict with vue-i18n's writable message interface.
10
+
11
+ // ⚠️ Angle-bracket text (e.g. `<name>`, `</tag>`) in a plain string
12
+ // message trips vue-i18n's XSS heuristic and logs
13
+ // `[intlify] Detected HTML in '…' message` on every mount. If the
14
+ // copy must contain `<...>`, use the **function form** so the
15
+ // message compiler is skipped entirely:
16
+ //
17
+ // subheading: ({ named }: { named: (key: string) => unknown }) =>
18
+ // `${named("count")} available · invokes as /<name>`,
19
+ //
20
+ // See `argsPlaceholder` and `pluginManageSkills.subheading` for
21
+ // worked examples. Mirror the same form in every other lang file
22
+ // when the English side uses a function.
23
+
24
+ const enMessages = {
25
+ common: {
26
+ save: "Save",
27
+ cancel: "Cancel",
28
+ loading: "Loading...",
29
+ close: "Close",
30
+ dismiss: "Dismiss",
31
+ add: "Add",
32
+ remove: "Remove",
33
+ saving: "Saving...",
34
+ saved: "Saved",
35
+ noResultsYet: "No results yet",
36
+ noImageYet: "No image yet",
37
+ },
38
+ sessionTabBar: {
39
+ newSession: "New session",
40
+ sessionHistory: "Session history",
41
+ // vue-i18n pluralization: `t(key, count)` picks singular / plural
42
+ // based on the number. `{count}` is interpolated.
43
+ activeSessions: "{count} active session (agent running) | {count} active sessions (agent running)",
44
+ unreadReplies: "{count} unread reply | {count} unread replies",
45
+ },
46
+ chatInput: {
47
+ placeholder: "Type a task, or drop / paste / attach a file…",
48
+ expandEditor: "Expand editor",
49
+ composeMessage: "Compose message",
50
+ sendHint: "Cmd+Enter to send",
51
+ send: "Send",
52
+ attachFile: "Attach file",
53
+ fileTooLarge: "File too large ({sizeMB} MB). Maximum is 30 MB.",
54
+ unsupportedFileType: "File type not supported. Accepted: images, PDF, DOCX, XLSX, PPTX, text files.",
55
+ },
56
+ sessionHistoryPanel: {
57
+ filters: {
58
+ all: "All",
59
+ unread: "Unread",
60
+ human: "Human",
61
+ scheduler: "Scheduler",
62
+ skill: "Skill",
63
+ bridge: "Bridge",
64
+ },
65
+ failedToRefresh: "⚠ Failed to refresh: {error}",
66
+ showingLastKnown: " — showing last known list.",
67
+ noSessions: "No sessions yet.",
68
+ noMatching: "No matching sessions.",
69
+ running: "Running",
70
+ unread: "Unread",
71
+ noMessages: "(no messages)",
72
+ },
73
+ notificationBell: {
74
+ notifications: "Notifications",
75
+ markAllRead: "Mark all read",
76
+ noNotifications: "No notifications",
77
+ dismiss: "Dismiss",
78
+ },
79
+ sidebarHeader: {
80
+ home: "Go to latest chat",
81
+ toolCallHistory: "Tool call history",
82
+ settings: "Settings",
83
+ },
84
+ rightSidebar: {
85
+ toggleSystemPrompt: "Toggle system prompt",
86
+ systemPrompt: "System Prompt",
87
+ availableTools: "Available Tools",
88
+ toggleToolDescription: "Toggle tool description",
89
+ toolCallHistory: "Tool Call History",
90
+ noToolCalls: "No tool calls yet",
91
+ arguments: "Arguments",
92
+ error: "Error",
93
+ result: "Result",
94
+ running: "Running...",
95
+ },
96
+ fileTreePane: {
97
+ sort: "Sort:",
98
+ sortByName: "Sort by name",
99
+ name: "Name",
100
+ sortByRecent: "Sort by modified date (newest first)",
101
+ recent: "Recent",
102
+ reference: "Reference",
103
+ // "RO" = Read-Only. Kept short on purpose — rendered as a compact
104
+ // badge next to the Reference label.
105
+ readOnlyBadge: "RO",
106
+ },
107
+ fileTree: {
108
+ workspace: "(workspace)",
109
+ recentlyChanged: "Recently changed",
110
+ },
111
+ lockStatusPopup: {
112
+ sandboxEnabledTooltip: "Sandbox enabled (Docker)",
113
+ noSandboxTooltip: "No sandbox (Docker not found)",
114
+ sandboxEnabledLabel: "Sandbox enabled:",
115
+ sandboxEnabledBody: "Docker is running. Filesystem access is isolated.",
116
+ noSandboxLabel: "No sandbox:",
117
+ noSandboxBodyPrefix: "Claude can access all files on your machine. Install",
118
+ noSandboxBodySuffix: "to enable filesystem isolation.",
119
+ dockerDesktop: "Docker Desktop",
120
+ hostCredentials: "Host credentials attached:",
121
+ credsLoading: "loading…",
122
+ sshAgent: "SSH agent:",
123
+ forwarded: "forwarded",
124
+ notForwarded: "not forwarded",
125
+ mountedConfigs: "Mounted configs:",
126
+ none: "none",
127
+ testIsolation: "Test sandbox isolation:",
128
+ },
129
+ settingsModal: {
130
+ title: "Settings",
131
+ tabs: {
132
+ tools: "Allowed Tools",
133
+ mcp: "MCP Servers",
134
+ dirs: "Directories",
135
+ refs: "Reference Dirs",
136
+ },
137
+ toolNamesLabel: "Tool names",
138
+ invalidToolNamesPrefix: "These look non-standard (expected prefix",
139
+ invalidToolNamesSuffix: "):",
140
+ mcpToolsError: "⚠ Could not fetch MCP tool status: {error}. Showing all tools regardless of enablement.",
141
+ changesHint: "Changes apply on the next message. No restart needed.",
142
+ cannotSaveTooltip: "Cannot save until settings load successfully",
143
+ saving: "Saving…",
144
+ loadingLabel: "Loading…",
145
+ },
146
+ canvasViewToggle: {
147
+ stackViewTooltip: "Stack view · click to switch to Single (⌘1)",
148
+ singleViewTooltip: "Single view · click to switch to Stack (⌘2)",
149
+ switchToSingle: "Switch to Single view",
150
+ switchToStack: "Switch to Stack view",
151
+ },
152
+ settingsWorkspaceDirs: {
153
+ explanation: "Custom directories for organizing files under {dataDir} and {artifactsDir}. Claude uses these to route file saves.",
154
+ noEntries: "No custom directories configured.",
155
+ addDirTitle: "Add directory",
156
+ pathPlaceholder: "data/clients or artifacts/reports",
157
+ descPlaceholder: "Description (what goes in this folder)",
158
+ errPathRequired: "Path required",
159
+ errMustStartWith: "Must start with data/ or artifacts/",
160
+ errAlreadyExists: "Already exists",
161
+ },
162
+ settingsReferenceDirs: {
163
+ explanation:
164
+ "External directories Claude can read but not modify. In Docker mode, these are mounted read-only. Useful for referencing Obsidian vaults, project code, or document folders.",
165
+ noEntries: "No reference directories configured.",
166
+ addDirTitle: "Add reference directory",
167
+ pathPlaceholder: "/Users/me/ObsidianVault or ~/Documents/notes",
168
+ labelPlaceholder: "Label (optional — defaults to folder name)",
169
+ readOnlyBadge: "read-only",
170
+ errPathRequired: "Path required",
171
+ errMustBeAbsolute: "Must be an absolute path or start with ~/",
172
+ errAlreadyExists: "Already exists",
173
+ errLabelConflict: 'Label "{label}" already exists',
174
+ },
175
+ pluginLauncher: {
176
+ todos: { label: "Todos", title: "Open todos (⌘4)" },
177
+ scheduler: { label: "Schedule", title: "Open schedule (⌘5)" },
178
+ wiki: { label: "Wiki", title: "Open wiki (⌘6)" },
179
+ skills: { label: "Skills", title: "Open skills (⌘7)" },
180
+ roles: { label: "Roles", title: "Open roles (⌘8)" },
181
+ files: { label: "Files", title: "Open workspace files (⌘3)" },
182
+ },
183
+ fileContentHeader: {
184
+ showRendered: "Show rendered Markdown",
185
+ showRaw: "Show raw source",
186
+ rendered: "Rendered",
187
+ raw: "Raw",
188
+ closeFile: "Close file",
189
+ },
190
+ fileContentRenderer: {
191
+ selectFile: "Select a file",
192
+ htmlPreview: "HTML preview",
193
+ pdfPreview: "PDF preview",
194
+ parseError: "parse error",
195
+ },
196
+ settingsMcpTab: {
197
+ explanation:
198
+ "Add external MCP servers. HTTP servers work in every mode. Stdio servers use the sandbox image's {npx} / {node} / {tsx}; paths must live under the workspace when Docker is enabled.",
199
+ localhostRewrite: "In Docker mode {localhost} is rewritten to {hostDockerInternal}.",
200
+ noServers: "No MCP servers configured yet.",
201
+ enabled: "enabled",
202
+ urlLabel: "URL:",
203
+ commandLabel: "Command:",
204
+ dockerNonWorkspaceWarning: "⚠ Contains paths outside the workspace — will not resolve inside Docker.",
205
+ addServerButton: "+ Add MCP Server",
206
+ nameLabel: "Name",
207
+ namePlaceholder: "my-server",
208
+ typeHttp: "HTTP",
209
+ typeStdio: "Stdio (command)",
210
+ urlFieldLabel: "URL",
211
+ urlPlaceholder: "https://example.com/mcp",
212
+ commandFieldLabel: "Command",
213
+ argsLabel: "Arguments (one per line)",
214
+ // Message function form — skips vue-i18n's message compiler so
215
+ // the literal `@` isn't parsed as a linked-message reference.
216
+ argsPlaceholder: () => "-y\n@modelcontextprotocol/server-filesystem\n/workspace/path",
217
+ errNoName: "Please provide a Name, or enter a URL / args we can derive one from.",
218
+ errBadName: "Name must start with a lowercase letter and contain only [a-z0-9_-].",
219
+ errIdExists: 'Server id "{id}" already exists.',
220
+ errBadHttpUrl: "HTTP URL must start with http:// or https://",
221
+ },
222
+ pluginScheduler: {
223
+ prev: "Previous",
224
+ today: "Today",
225
+ goToday: "Go to today",
226
+ next: "Next",
227
+ deleteItem: "Delete item",
228
+ closeEditor: "Close editor",
229
+ apiError: "⚠ Failed to update scheduler: {error}",
230
+ tabCalendar: "Calendar",
231
+ tabTasks: "Tasks",
232
+ heading: "Scheduler",
233
+ itemCount: "{count} item | {count} items",
234
+ noScheduled: "No scheduled items",
235
+ unscheduled: "Unscheduled",
236
+ editItem: "Edit item",
237
+ update: "Update",
238
+ editSource: "Edit Source",
239
+ applyChanges: "Apply Changes",
240
+ propLabel: "{key}:",
241
+ moreCount: "+{count} more",
242
+ previewIcon: "📅",
243
+ previewUpcoming: "{count} upcoming",
244
+ previewMore: "+ {count} more…",
245
+ },
246
+ pluginSchedulerTasks: {
247
+ recommendedFrequencies: "Recommended Frequencies",
248
+ tableTaskType: "Task type",
249
+ tableSuggestedSchedule: "Suggested schedule",
250
+ noTasks: "No scheduled tasks",
251
+ runNow: "Run now",
252
+ enable: "Enable",
253
+ disable: "Disable",
254
+ delete: "Delete",
255
+ nextRun: "Next: {time}",
256
+ originSystem: "System",
257
+ originUser: "User",
258
+ originSkill: "Skill",
259
+ runFailed: "Run failed: {error}",
260
+ toggleFailed: "Toggle failed: {error}",
261
+ deleteFailed: "Delete failed: {error}",
262
+ },
263
+ pluginCanvas: {
264
+ undo: "Undo",
265
+ redo: "Redo",
266
+ clear: "Clear",
267
+ styleLabel: "Style:",
268
+ },
269
+ pluginChart: {
270
+ untitled: "Chart",
271
+ chartCount: "{count} chart | {count} charts",
272
+ chartTitle: "Chart {num}",
273
+ png: "PNG",
274
+ },
275
+ pluginTodo: {
276
+ clearFilters: "Clear all filters",
277
+ deleteItem: "Delete item",
278
+ apiError: "⚠ Failed to update todos: {error}",
279
+ heading: "Todo List",
280
+ completedRatio: "{done}/{total} completed",
281
+ filter: "Filter:",
282
+ noItems: "No todo items yet",
283
+ noMatchingFilter: "No items match the active filter",
284
+ update: "Update",
285
+ clearCompleted: "Clear completed",
286
+ clearButton: "Clear ✕",
287
+ deleteSymbol: "✕",
288
+ },
289
+ todoExplorer: {
290
+ heading: "Todo",
291
+ doneRatio: "{done}/{total} done",
292
+ addButton: "+ Add",
293
+ addColumnButton: "+ Column",
294
+ labels: "Labels:",
295
+ searchPlaceholder: "Search...",
296
+ clearButton: "Clear ✕",
297
+ clearFiltersTitle: "Clear label filters",
298
+ emptyHint: 'No todo items yet. Click "+ Add" to create one.',
299
+ addColumn: "Add Column",
300
+ newColumnLabelField: "Label",
301
+ newColumnPlaceholder: "Review",
302
+ noMatchingFilter: "No items match the current filter",
303
+ },
304
+ todoPreview: {
305
+ completedRatio: "{done}/{total} completed",
306
+ moreItems: "+ {count} more…",
307
+ headerIcon: "☑",
308
+ doneIcon: "✓",
309
+ pendingIcon: "○",
310
+ moreLabels: "+{count}",
311
+ },
312
+ todoDialogs: {
313
+ addTitle: "Add Todo",
314
+ editTitle: "Edit Todo",
315
+ deleteButton: "Delete",
316
+ deleteTitle: "Delete this item",
317
+ noneOption: "— None —",
318
+ fieldText: "Text",
319
+ fieldNote: "Note",
320
+ fieldStatus: "Status",
321
+ fieldPriority: "Priority",
322
+ fieldDueDate: "Due date",
323
+ fieldLabels: "Labels",
324
+ fieldLabelsCommaSeparated: "Labels (comma-separated)",
325
+ textPlaceholder: "What needs doing?",
326
+ labelsPlaceholder: "work, urgent",
327
+ },
328
+ todoKanban: {
329
+ rename: "Rename",
330
+ alreadyDoneColumn: "Already done column",
331
+ markAsDoneColumn: "Mark as done column",
332
+ deleteColumn: "Delete column",
333
+ columnActions: "Column actions",
334
+ addCard: "+ Add card",
335
+ },
336
+ todoTableList: {
337
+ noMatchingFilter: "No items match the current filter",
338
+ },
339
+ pluginWiki: {
340
+ backToIndex: "Back to index",
341
+ pdf: "PDF",
342
+ pdfFailed: "⚠ PDF failed",
343
+ tabIndex: "Index",
344
+ tabLog: "Log",
345
+ tabLint: "Lint",
346
+ empty: "Wiki is empty. Ask the Wiki Manager to ingest a source.",
347
+ previewMore: "+ {count} more…",
348
+ chatPlaceholder: "Ask about this page…",
349
+ chatSend: "Start a new chat about this page",
350
+ },
351
+ pluginPresentHtml: {
352
+ saveAsPdf: "Save as PDF (opens print dialog)",
353
+ pdf: "PDF",
354
+ untitled: "HTML Page",
355
+ hideSource: "Hide Source <>",
356
+ showSource: "Show Source <>",
357
+ },
358
+ pluginManageSource: {
359
+ titlePlaceholder: "Title (optional)",
360
+ heading: "Information sources",
361
+ sourceCount: "{count} source | {count} sources",
362
+ addButton: "Add",
363
+ rebuildNow: "Rebuild now",
364
+ rebuilding: "Rebuilding…",
365
+ typeField: "Type",
366
+ addingLabel: "Adding…",
367
+ addAndRebuild: "Add + Rebuild",
368
+ emptyPickPack: "No sources registered yet. Pick a starter pack below, click {addBold} above, or ask Claude to register one.",
369
+ emptyAddStrong: "+ Add",
370
+ registering: "Registering + fetching…",
371
+ removeLabel: "Remove",
372
+ removingLabel: "Removing…",
373
+ todaysBrief: "Today's brief",
374
+ todaysBriefLoading: "Loading today's brief…",
375
+ briefNone: "No brief written for this date yet. Click Rebuild now.",
376
+ briefEmpty: "Today's brief is empty.",
377
+ briefLoadFailed: "Failed to load brief",
378
+ lastRebuildSummary: "Last rebuild ({date}): {itemCount} items from {planned} sources, {duplicates} duplicates dropped.",
379
+ archiveErrorsSuffix: "({count} archive errors)",
380
+ kindRss: "RSS",
381
+ kindGithubRel: "GitHub rel",
382
+ kindGithubIss: "GitHub iss",
383
+ kindArxiv: "arXiv",
384
+ kindGithubReleases: "GitHub releases",
385
+ kindGithubIssues: "GitHub issues",
386
+ briefDateLabel: "({date})",
387
+ primaryRssPlaceholder: "https://news.ycombinator.com/rss",
388
+ primaryGithubPlaceholder: "https://github.com/owner/repo (or owner/repo)",
389
+ primaryArxivPlaceholder: "cat:cs.CL",
390
+ primaryRssHint: "Feed URL (RSS 2.0 / Atom / RDF)",
391
+ primaryGithubRelHint: "GitHub repo URL or owner/repo — fetches releases",
392
+ primaryGithubIssHint: "GitHub repo URL or owner/repo — fetches issues",
393
+ primaryArxivHint: "arXiv search query (e.g. cat:cs.CL or au:hinton)",
394
+ confirmRemove: 'Remove source "{slug}"?',
395
+ flashRegistered: "Registered. Fetching new items…",
396
+ flashRebuildReady: "Ready: {itemCount} items from {planned} source.|Ready: {itemCount} items from {planned} sources.",
397
+ flashRebuildComplete: "Rebuild complete: {itemCount} items from {planned} sources.",
398
+ flashRebuildFailed: "Rebuild failed: {error}",
399
+ flashRegisterFailed: "Failed to register source",
400
+ flashRegisterSucceededRebuildFailed: "Register succeeded but rebuild failed: {error}",
401
+ flashRemoved: 'Removed "{slug}".',
402
+ flashRemoveFailed: "Remove failed: {error}",
403
+ flashRefreshListFailed: "Failed to refresh sources: {error}",
404
+ flashPresetAlreadyRegistered: 'All sources in "{label}" are already registered.',
405
+ flashPresetRegistered: 'Registered {count} source from "{label}". Fetching…|Registered {count} sources from "{label}". Fetching…',
406
+ flashPresetPartial: "Registered {ok}/{total}. Errors: {errors}",
407
+ },
408
+ pluginManageSkills: {
409
+ deleteProjectSkill: "Delete this project-scope skill",
410
+ heading: "Skills",
411
+ previewCount: "{count} skill | {count} skills",
412
+ previewMore: "+{count} more",
413
+ // Function form skips vue-i18n's message compiler, which
414
+ // otherwise flags the literal `<name>` as a suspected HTML
415
+ // fragment and warns about XSS on every mount.
416
+ subheading: ({ named }: { named: (key: string) => unknown }) => `${named("count")} available · click one to view · "Run" invokes it as /<name>`,
417
+ emptyWithPath: "No skills found. Add skill folders under {path}.",
418
+ emptySkillPath: "~/.claude/skills/",
419
+ selectHint: "Select a skill on the left to view its SKILL.md.",
420
+ loading: "Loading…",
421
+ fieldDescription: "Description",
422
+ fieldBody: "Body (Markdown)",
423
+ emptyBody: "(empty body)",
424
+ btnEdit: "Edit",
425
+ btnDelete: "Delete",
426
+ btnRun: "Run",
427
+ errListFailed: "Failed to load skills: {error}",
428
+ errDetailFailed: "Failed to load skill: {error}",
429
+ errSaveFailed: "Save failed: {error}",
430
+ errDeleteFailed: "Failed to delete",
431
+ confirmDelete: 'Delete skill "{name}"? This removes ~/mulmoclaude/.claude/skills/{name}/SKILL.md.',
432
+ },
433
+ pluginManageRoles: {
434
+ heading: "Custom Roles",
435
+ roleCount: "{count} role | {count} roles",
436
+ previewCount: "{count} custom role | {count} custom roles",
437
+ addButton: "+ Add",
438
+ createPanel: "Create new role",
439
+ fieldId: "ID",
440
+ fieldName: "Name",
441
+ fieldIcon: "Icon",
442
+ fieldPrompt: "Prompt",
443
+ fieldPlugins: "Plugins",
444
+ fieldStarterQueries: "Starter queries",
445
+ onePerLine: "(one per line)",
446
+ helpLink: "?",
447
+ idFormatted: "({id})",
448
+ missingEnv: "(missing {env})",
449
+ requiresEnv: "Requires {env} in .env",
450
+ collapse: "Collapse",
451
+ expand: "Expand",
452
+ idPlaceholder: "unique-id",
453
+ creating: "Creating…",
454
+ create: "Create",
455
+ updating: "Updating…",
456
+ update: "Update",
457
+ cancel: "Cancel",
458
+ delete: "Delete",
459
+ emptyHint: 'No custom roles yet. Click "+ Add" or ask Claude to create one.',
460
+ errIdRequired: "ID is required.",
461
+ errIdInvalid: "ID may only contain letters, numbers, '-' and '_'.",
462
+ errNameRequired: "Name is required.",
463
+ errIdDuplicate: "A role with ID '{id}' already exists.",
464
+ errCreateFailed: "Create failed",
465
+ errSaveFailed: "Save failed",
466
+ errDeleteFailed: "Delete failed",
467
+ errNetworkError: "Network error",
468
+ errServerError: "Server error: {status}",
469
+ },
470
+ pluginUiImage: {
471
+ promptLabel: "{label}:",
472
+ },
473
+ pluginMulmoScript: {
474
+ beatCount: "{count} beat | {count} beats",
475
+ movie: "Movie",
476
+ generating: "Generating…",
477
+ rendering: "Rendering…",
478
+ saving: "Saving…",
479
+ update: "Update",
480
+ characters: "Characters",
481
+ drop: "Drop",
482
+ gen: "Gen",
483
+ play: "▶ Play",
484
+ stop: "■ Stop",
485
+ errPrefix: "⚠ Error",
486
+ noBeats: "No beats found in script",
487
+ editSource: "Edit Script Source",
488
+ applyChanges: "Apply Changes",
489
+ generateAll: "Generate All",
490
+ orDropImage: "or drop image",
491
+ generate: "Generate",
492
+ generateAudio: "♪ Generate",
493
+ saveErrorInvalidJson: "⚠ Invalid JSON: {error}",
494
+ saveErrorSaveFailed: "⚠ Save failed: {error}",
495
+ },
496
+ pluginMarkdown: {
497
+ loading: "Loading document...",
498
+ loadFailed: "⚠ Failed to load document: {error}",
499
+ refreshFailed: "⚠ Failed to refresh document: {error} — showing last successfully loaded content.",
500
+ noContent: "No markdown content available",
501
+ pdf: "PDF",
502
+ pdfFailedShort: "⚠ PDF failed",
503
+ editSource: "Edit Markdown Source",
504
+ saving: "Saving...",
505
+ applyChanges: "Apply Changes",
506
+ cancel: "Cancel",
507
+ saveFailed: "Save failed: {error}",
508
+ saveError: "⚠ Save failed: {error}",
509
+ copyLabel: "Copy",
510
+ copiedLabel: "Copied!",
511
+ },
512
+ pluginTextResponse: {
513
+ pdf: "PDF",
514
+ pdfFailed: "⚠ PDF failed",
515
+ editContent: "Edit Text Content",
516
+ applyChanges: "Apply Changes",
517
+ copyLabel: "Copy",
518
+ copiedLabel: "Copied!",
519
+ cancel: "Cancel",
520
+ },
521
+ pluginSpreadsheet: {
522
+ previewLabel: "📊 Spreadsheet",
523
+ previewUntitled: "Spreadsheet",
524
+ previewSheets: "{count} sheet | {count} sheets",
525
+ untitled: "Spreadsheet",
526
+ excel: "Excel",
527
+ valuePlaceholder: "Value",
528
+ valueOrFormulaPlaceholder: "Value or Formula (e.g., 100 or SUM(B2:B11))",
529
+ formatPlaceholder: "Format (e.g., $#,##0.00)",
530
+ loading: "Loading spreadsheet...",
531
+ noData: "No spreadsheet data available",
532
+ editData: "Edit Spreadsheet Data",
533
+ applyChanges: "Apply Changes",
534
+ update: "Update",
535
+ stringType: "String",
536
+ formulaType: "Formula",
537
+ },
538
+ app: {
539
+ // `<i18n-t>` slots — named `envKey` / `envFile` render as inline
540
+ // `<code>` in App.vue, so the literal variable and file names
541
+ // stay untranslated while the surrounding copy is localised.
542
+ geminiRequired: "Image generation requires {envKey}. Add it to {envFile} and restart the app.",
543
+ startConversation: "Start a conversation",
544
+ },
545
+ suggestionsPanel: {
546
+ suggestions: "Suggestions",
547
+ sendEditHint: "click to send · shift+click to edit",
548
+ },
549
+ settingsToolsTab: {
550
+ // Rendered via <i18n-t> with named slots `allowedTools` and `claudeMcp`
551
+ // so the inline `<code>` tags keep their styling while the copy
552
+ // is translatable.
553
+ explanation:
554
+ "Extra tool names to pass to Claude via {allowedTools}. One per line. Useful for built-in Claude Code MCP servers like Gmail / Google Calendar after you have authenticated via {claudeMcp}.",
555
+ },
556
+ };
557
+
558
+ export default enMessages;