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
@@ -41,7 +41,7 @@ export interface RateLimiterDeps {
41
41
  export function defaultRateLimiterDeps(): RateLimiterDeps {
42
42
  return {
43
43
  now: () => Date.now(),
44
- sleep: (ms: number) => new Promise<void>((resolve) => setTimeout(resolve, ms)),
44
+ sleep: (millis: number) => new Promise<void>((resolve) => setTimeout(resolve, millis)),
45
45
  };
46
46
  }
47
47
 
@@ -50,10 +50,9 @@ export function validateSourceState(raw: unknown, slug: string): SourceState {
50
50
  const record = raw as Record<string, unknown>;
51
51
  const lastFetchedAt = typeof record.lastFetchedAt === "string" ? record.lastFetchedAt : null;
52
52
  const nextAttemptAt = typeof record.nextAttemptAt === "string" ? record.nextAttemptAt : null;
53
- const consecutiveFailures =
54
- typeof record.consecutiveFailures === "number" && Number.isFinite(record.consecutiveFailures) && record.consecutiveFailures >= 0
55
- ? Math.floor(record.consecutiveFailures)
56
- : 0;
53
+ const emptyBackoffUntil = typeof record.emptyBackoffUntil === "string" ? record.emptyBackoffUntil : null;
54
+ const consecutiveFailures = toNonNegativeInt(record.consecutiveFailures);
55
+ const consecutiveEmptyFetches = toNonNegativeInt(record.consecutiveEmptyFetches);
57
56
  const cursor = validateCursor(record.cursor);
58
57
  return {
59
58
  slug,
@@ -61,9 +60,15 @@ export function validateSourceState(raw: unknown, slug: string): SourceState {
61
60
  cursor,
62
61
  consecutiveFailures,
63
62
  nextAttemptAt,
63
+ consecutiveEmptyFetches,
64
+ emptyBackoffUntil,
64
65
  };
65
66
  }
66
67
 
68
+ function toNonNegativeInt(value: unknown): number {
69
+ return typeof value === "number" && Number.isFinite(value) && value >= 0 ? Math.floor(value) : 0;
70
+ }
71
+
67
72
  function validateCursor(raw: unknown): Record<string, string> {
68
73
  if (!isRecord(raw)) {
69
74
  return {};
@@ -131,6 +131,13 @@ export interface SourceState {
131
131
  // Timestamp after which the next attempt is allowed, so backoff
132
132
  // survives server restarts.
133
133
  nextAttemptAt: string | null;
134
+ // Consecutive empty-success count (fetcher returned 0 items).
135
+ // Reset to 0 when items are found. Drives adaptive empty backoff.
136
+ consecutiveEmptyFetches: number;
137
+ // Timestamp after which the next attempt is allowed following
138
+ // repeated empty fetches. Separate from nextAttemptAt (error
139
+ // backoff) so the two policies don't interfere.
140
+ emptyBackoffUntil: string | null;
134
141
  }
135
142
 
136
143
  export function defaultSourceState(slug: string): SourceState {
@@ -140,5 +147,7 @@ export function defaultSourceState(slug: string): SourceState {
140
147
  cursor: {},
141
148
  consecutiveFailures: 0,
142
149
  nextAttemptAt: null,
150
+ consecutiveEmptyFetches: 0,
151
+ emptyBackoffUntil: null,
143
152
  };
144
153
  }
@@ -80,7 +80,7 @@ export function normalizeUrl(raw: string): string | null {
80
80
  // Sort remaining params for deterministic ordering. Preserve
81
81
  // multi-value params by iterating all entries.
82
82
  const entries = Array.from(url.searchParams.entries());
83
- entries.sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0));
83
+ entries.sort(([leftKey], [rightKey]) => (leftKey < rightKey ? -1 : leftKey > rightKey ? 1 : 0));
84
84
  // Clear and reinsert.
85
85
  for (const name of Array.from(url.searchParams.keys())) {
86
86
  url.searchParams.delete(name);
@@ -96,10 +96,10 @@ function imagePointerFromContent(content: string): string | null {
96
96
  // regardless of how the tool happened to quote it. Leave "../"
97
97
  // prefixes alone — a relative escape is a bug and we want it visible
98
98
  // rather than silently fixed up.
99
- function normalizeWorkspacePath(p: string): string {
100
- if (p.startsWith("./")) return p.slice(2);
101
- if (p.startsWith("/")) return p.slice(1);
102
- return p;
99
+ function normalizeWorkspacePath(candidatePath: string): string {
100
+ if (candidatePath.startsWith("./")) return candidatePath.slice(2);
101
+ if (candidatePath.startsWith("/")) return candidatePath.slice(1);
102
+ return candidatePath;
103
103
  }
104
104
 
105
105
  function inlineWithTruncation(content: string): Classification {
@@ -1,5 +1,5 @@
1
1
  import { execSync } from "child_process";
2
- import fs from "fs";
2
+ import { copyFileSync, existsSync, mkdirSync, readdirSync } from "fs";
3
3
  import path from "path";
4
4
  import { fileURLToPath } from "url";
5
5
  import { log } from "../system/logger/index.js";
@@ -16,12 +16,12 @@ const TEMPLATES_DIR = path.join(__dirname, "helps");
16
16
  export { workspacePath };
17
17
 
18
18
  // Must exist before downstream modules call realpathSync(workspacePath) at their own module-load time.
19
- fs.mkdirSync(workspacePath, { recursive: true });
19
+ mkdirSync(workspacePath, { recursive: true });
20
20
 
21
21
  export function initWorkspace(): string {
22
22
  // Create directory structure if needed
23
23
  for (const key of EAGER_WORKSPACE_DIRS) {
24
- fs.mkdirSync(WORKSPACE_PATHS[key], { recursive: true });
24
+ mkdirSync(WORKSPACE_PATHS[key], { recursive: true });
25
25
  }
26
26
 
27
27
  // Create memory.md if it doesn't exist
@@ -30,9 +30,9 @@ export function initWorkspace(): string {
30
30
  }
31
31
 
32
32
  // Always sync all files from server/helps/ into workspace/helps/
33
- fs.mkdirSync(WORKSPACE_PATHS.helps, { recursive: true });
34
- for (const file of fs.readdirSync(TEMPLATES_DIR)) {
35
- fs.copyFileSync(path.join(TEMPLATES_DIR, file), path.join(WORKSPACE_PATHS.helps, file));
33
+ mkdirSync(WORKSPACE_PATHS.helps, { recursive: true });
34
+ for (const file of readdirSync(TEMPLATES_DIR)) {
35
+ copyFileSync(path.join(TEMPLATES_DIR, file), path.join(WORKSPACE_PATHS.helps, file));
36
36
  }
37
37
 
38
38
  // Create .gitignore if missing. The workspace is a git repo for
@@ -56,7 +56,7 @@ export function initWorkspace(): string {
56
56
 
57
57
  // Git init if not already a repo
58
58
  const gitDir = path.join(workspacePath, ".git");
59
- if (!fs.existsSync(gitDir)) {
59
+ if (!existsSync(gitDir)) {
60
60
  execSync("git init", { cwd: workspacePath });
61
61
  log.info("workspace", "initialized git repository", { workspacePath });
62
62
  }