mulmoclaude 0.1.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.
- package/README.md +44 -0
- package/bin/mulmoclaude.js +202 -0
- package/bin/prepare-dist.js +93 -0
- package/client/assets/chunk-vKJrgz-R-C_I3GbVV.js +1 -0
- package/client/assets/html2canvas-Cx501zZr-BF5dYYkY.js +5 -0
- package/client/assets/index-D8rhwXLq.js +4906 -0
- package/client/assets/index-KNLBjwuh.css +1 -0
- package/client/assets/index.es-D4YyL_Dg-BfRHLTZV.js +5 -0
- package/client/assets/material-icons-Dr0goTwe.woff +0 -0
- package/client/assets/material-icons-kAwBdRge.woff2 +0 -0
- package/client/assets/material-icons-outlined-BpWbwl2n.woff +0 -0
- package/client/assets/material-icons-outlined-DZhiGvEA.woff2 +0 -0
- package/client/assets/material-icons-round-BDlwx-sv.woff +0 -0
- package/client/assets/material-icons-round-DrirKXBx.woff2 +0 -0
- package/client/assets/material-icons-sharp-CH1KkVu7.woff +0 -0
- package/client/assets/material-icons-sharp-gidztirS.woff2 +0 -0
- package/client/assets/material-icons-two-tone-B7wz7mED.woff +0 -0
- package/client/assets/material-icons-two-tone-DuNIpaEj.woff2 +0 -0
- package/client/assets/mulmo_bw-ERmkSv0a.png +0 -0
- package/client/assets/purify.es-Fx1Nqyry-PeS5RUhs.js +2 -0
- package/client/assets/typeof-DBp4T-Ny-BC0P-2DM.js +1 -0
- package/client/index.html +28 -0
- package/package.json +66 -0
- package/server/agent/attachmentConverter.ts +270 -0
- package/server/agent/config.ts +414 -0
- package/server/agent/index.ts +260 -0
- package/server/agent/mcp-server.ts +412 -0
- package/server/agent/mcp-tools/index.ts +63 -0
- package/server/agent/mcp-tools/x.ts +188 -0
- package/server/agent/plugin-names.ts +75 -0
- package/server/agent/prompt.ts +349 -0
- package/server/agent/resumeFailover.ts +129 -0
- package/server/agent/sandboxMounts.ts +329 -0
- package/server/agent/stream.ts +194 -0
- package/server/api/auth/bearerAuth.ts +61 -0
- package/server/api/auth/token.ts +98 -0
- package/server/api/csrfGuard.ts +85 -0
- package/server/api/routes/agent.ts +478 -0
- package/server/api/routes/chart.ts +98 -0
- package/server/api/routes/chat-index.ts +46 -0
- package/server/api/routes/config.ts +258 -0
- package/server/api/routes/dispatchResponse.ts +79 -0
- package/server/api/routes/files.ts +812 -0
- package/server/api/routes/html.ts +101 -0
- package/server/api/routes/image.ts +169 -0
- package/server/api/routes/mulmo-script.ts +712 -0
- package/server/api/routes/mulmoScriptValidate.ts +101 -0
- package/server/api/routes/notifications.ts +69 -0
- package/server/api/routes/pdf.ts +163 -0
- package/server/api/routes/plugins.ts +276 -0
- package/server/api/routes/presentHtml.ts +48 -0
- package/server/api/routes/roles.ts +125 -0
- package/server/api/routes/scheduler.ts +153 -0
- package/server/api/routes/schedulerHandlers.ts +151 -0
- package/server/api/routes/schedulerTasks.ts +163 -0
- package/server/api/routes/sessions.ts +294 -0
- package/server/api/routes/sessionsCursor.ts +59 -0
- package/server/api/routes/skills.ts +195 -0
- package/server/api/routes/sources.ts +540 -0
- package/server/api/routes/todos.ts +263 -0
- package/server/api/routes/todosColumnsHandlers.ts +347 -0
- package/server/api/routes/todosHandlers.ts +274 -0
- package/server/api/routes/todosItemsHandlers.ts +386 -0
- package/server/api/routes/wiki/pageIndex.ts +53 -0
- package/server/api/routes/wiki.ts +363 -0
- package/server/api/sandboxStatus.ts +64 -0
- package/server/events/notifications.ts +160 -0
- package/server/events/pub-sub/index.ts +45 -0
- package/server/events/relay-client.ts +288 -0
- package/server/events/scheduler-adapter.ts +302 -0
- package/server/events/session-store/index.ts +492 -0
- package/server/events/task-manager/index.ts +181 -0
- package/server/index.ts +572 -0
- package/server/system/config.ts +243 -0
- package/server/system/credentials.ts +220 -0
- package/server/system/docker.ts +97 -0
- package/server/system/env.ts +109 -0
- package/server/system/logger/config.ts +112 -0
- package/server/system/logger/formatters.ts +40 -0
- package/server/system/logger/index.ts +53 -0
- package/server/system/logger/rotation.ts +37 -0
- package/server/system/logger/sinks.ts +101 -0
- package/server/system/logger/types.ts +29 -0
- package/server/utils/date.ts +57 -0
- package/server/utils/errors.ts +7 -0
- package/server/utils/fetch.ts +27 -0
- package/server/utils/files/atomic.ts +125 -0
- package/server/utils/files/html-io.ts +20 -0
- package/server/utils/files/image-store.ts +66 -0
- package/server/utils/files/index.ts +45 -0
- package/server/utils/files/journal-io.ts +213 -0
- package/server/utils/files/json.ts +69 -0
- package/server/utils/files/markdown-store.ts +33 -0
- package/server/utils/files/naming.ts +50 -0
- package/server/utils/files/reference-dirs-io.ts +45 -0
- package/server/utils/files/roles-io.ts +45 -0
- package/server/utils/files/safe.ts +106 -0
- package/server/utils/files/scheduler-io.ts +20 -0
- package/server/utils/files/scheduler-overrides-io.ts +64 -0
- package/server/utils/files/session-io.ts +136 -0
- package/server/utils/files/spreadsheet-store.ts +63 -0
- package/server/utils/files/todos-io.ts +29 -0
- package/server/utils/files/user-tasks-io.ts +25 -0
- package/server/utils/files/workspace-io.ts +221 -0
- package/server/utils/gemini.ts +59 -0
- package/server/utils/gitignore.ts +69 -0
- package/server/utils/http.ts +15 -0
- package/server/utils/httpError.ts +61 -0
- package/server/utils/id.ts +16 -0
- package/server/utils/json.ts +83 -0
- package/server/utils/logBackgroundError.ts +22 -0
- package/server/utils/markdown.ts +82 -0
- package/server/utils/request.ts +29 -0
- package/server/utils/slug.ts +50 -0
- package/server/utils/spawn.ts +62 -0
- package/server/utils/time.ts +34 -0
- package/server/utils/types.ts +47 -0
- package/server/workspace/chat-index/index.ts +153 -0
- package/server/workspace/chat-index/indexer.ts +209 -0
- package/server/workspace/chat-index/paths.ts +34 -0
- package/server/workspace/chat-index/summarizer.ts +247 -0
- package/server/workspace/chat-index/types.ts +38 -0
- package/server/workspace/custom-dirs.ts +220 -0
- package/server/workspace/helps/business.md +104 -0
- package/server/workspace/helps/github.md +23 -0
- package/server/workspace/helps/index.md +60 -0
- package/server/workspace/helps/mulmoscript.md +249 -0
- package/server/workspace/helps/sandbox.md +90 -0
- package/server/workspace/helps/spreadsheet.md +43 -0
- package/server/workspace/helps/telegram.md +135 -0
- package/server/workspace/helps/wiki.md +131 -0
- package/server/workspace/journal/archivist.ts +386 -0
- package/server/workspace/journal/dailyPass.ts +743 -0
- package/server/workspace/journal/diff.ts +71 -0
- package/server/workspace/journal/index.ts +185 -0
- package/server/workspace/journal/indexFile.ts +136 -0
- package/server/workspace/journal/linkRewrite.ts +4 -0
- package/server/workspace/journal/memoryExtractor.ts +130 -0
- package/server/workspace/journal/optimizationPass.ts +160 -0
- package/server/workspace/journal/paths.ts +76 -0
- package/server/workspace/journal/state.ts +125 -0
- package/server/workspace/paths.ts +158 -0
- package/server/workspace/reference-dirs.ts +252 -0
- package/server/workspace/roles.ts +37 -0
- package/server/workspace/skills/discovery.ts +125 -0
- package/server/workspace/skills/index.ts +10 -0
- package/server/workspace/skills/parser.ts +144 -0
- package/server/workspace/skills/paths.ts +41 -0
- package/server/workspace/skills/scheduler.ts +149 -0
- package/server/workspace/skills/types.ts +30 -0
- package/server/workspace/skills/user-tasks.ts +257 -0
- package/server/workspace/skills/writer.ts +189 -0
- package/server/workspace/sources/arxivDiscovery.ts +182 -0
- package/server/workspace/sources/classifier.ts +268 -0
- package/server/workspace/sources/fetchers/arxiv.ts +170 -0
- package/server/workspace/sources/fetchers/github.ts +106 -0
- package/server/workspace/sources/fetchers/githubIssues.ts +208 -0
- package/server/workspace/sources/fetchers/githubReleases.ts +186 -0
- package/server/workspace/sources/fetchers/index.ts +71 -0
- package/server/workspace/sources/fetchers/registerAll.ts +15 -0
- package/server/workspace/sources/fetchers/rss.ts +141 -0
- package/server/workspace/sources/fetchers/rssParser.ts +295 -0
- package/server/workspace/sources/httpFetcher.ts +230 -0
- package/server/workspace/sources/interests.ts +120 -0
- package/server/workspace/sources/paths.ts +110 -0
- package/server/workspace/sources/pipeline/dedup.ts +60 -0
- package/server/workspace/sources/pipeline/fetch.ts +136 -0
- package/server/workspace/sources/pipeline/index.ts +249 -0
- package/server/workspace/sources/pipeline/notify.ts +72 -0
- package/server/workspace/sources/pipeline/plan.ts +66 -0
- package/server/workspace/sources/pipeline/summarize.ts +189 -0
- package/server/workspace/sources/pipeline/write.ts +185 -0
- package/server/workspace/sources/rateLimiter.ts +148 -0
- package/server/workspace/sources/registry.ts +326 -0
- package/server/workspace/sources/robots.ts +271 -0
- package/server/workspace/sources/sourceState.ts +135 -0
- package/server/workspace/sources/taxonomy.ts +74 -0
- package/server/workspace/sources/types.ts +144 -0
- package/server/workspace/sources/urls.ts +112 -0
- package/server/workspace/tool-trace/classify.ts +114 -0
- package/server/workspace/tool-trace/index.ts +250 -0
- package/server/workspace/tool-trace/writeSearch.ts +98 -0
- package/server/workspace/wiki-backlinks/index.ts +107 -0
- package/server/workspace/wiki-backlinks/sessionBacklinks.ts +144 -0
- package/server/workspace/workspace.ts +66 -0
- package/src/App.vue +720 -0
- package/src/assets/mulmo_bw.png +0 -0
- package/src/components/CanvasViewToggle.vue +27 -0
- package/src/components/ChatAttachmentPreview.vue +45 -0
- package/src/components/ChatImagePreview.vue +17 -0
- package/src/components/ChatInput.vue +208 -0
- package/src/components/FileContentHeader.vue +49 -0
- package/src/components/FileContentRenderer.vue +162 -0
- package/src/components/FileTree.vue +115 -0
- package/src/components/FileTreePane.vue +85 -0
- package/src/components/FilesView.vue +206 -0
- package/src/components/LockStatusPopup.vue +111 -0
- package/src/components/NotificationBell.vue +131 -0
- package/src/components/NotificationToast.vue +72 -0
- package/src/components/PluginLauncher.vue +138 -0
- package/src/components/RightSidebar.vue +113 -0
- package/src/components/RoleSelector.vue +64 -0
- package/src/components/SessionHistoryPanel.vue +176 -0
- package/src/components/SessionTabBar.vue +81 -0
- package/src/components/SettingsMcpTab.vue +350 -0
- package/src/components/SettingsModal.vue +275 -0
- package/src/components/SettingsReferenceDirsTab.vue +173 -0
- package/src/components/SettingsWorkspaceDirsTab.vue +174 -0
- package/src/components/SidebarHeader.vue +69 -0
- package/src/components/StackView.vue +360 -0
- package/src/components/SuggestionsPanel.vue +65 -0
- package/src/components/TodoExplorer.vue +358 -0
- package/src/components/ToolResultsPanel.vue +77 -0
- package/src/components/todo/TodoAddDialog.vue +131 -0
- package/src/components/todo/TodoEditDialog.vue +47 -0
- package/src/components/todo/TodoEditPanel.vue +113 -0
- package/src/components/todo/TodoKanbanView.vue +249 -0
- package/src/components/todo/TodoListView.vue +79 -0
- package/src/components/todo/TodoTableView.vue +177 -0
- package/src/composables/useActiveSession.ts +40 -0
- package/src/composables/useAppApi.ts +45 -0
- package/src/composables/useCanvasViewMode.ts +121 -0
- package/src/composables/useChatScroll.ts +47 -0
- package/src/composables/useClickOutside.ts +26 -0
- package/src/composables/useClipboardCopy.ts +44 -0
- package/src/composables/useContentDisplay.ts +52 -0
- package/src/composables/useDebugBeat.ts +23 -0
- package/src/composables/useDynamicFavicon.ts +115 -0
- package/src/composables/useEventListeners.ts +42 -0
- package/src/composables/useExpandedDirs.ts +64 -0
- package/src/composables/useFaviconState.ts +30 -0
- package/src/composables/useFileSelection.ts +115 -0
- package/src/composables/useFileSortMode.ts +24 -0
- package/src/composables/useFileTree.ts +85 -0
- package/src/composables/useFreshPluginData.ts +89 -0
- package/src/composables/useHealth.ts +38 -0
- package/src/composables/useImeAwareEnter.ts +57 -0
- package/src/composables/useKeyNavigation.ts +60 -0
- package/src/composables/useMarkdownLinkHandler.ts +46 -0
- package/src/composables/useMarkdownMode.ts +17 -0
- package/src/composables/useMcpTools.ts +71 -0
- package/src/composables/useMergedSessions.ts +27 -0
- package/src/composables/useNotifications.ts +90 -0
- package/src/composables/usePdfDownload.ts +60 -0
- package/src/composables/usePendingCalls.ts +77 -0
- package/src/composables/usePubSub.ts +85 -0
- package/src/composables/useRightSidebar.ts +23 -0
- package/src/composables/useRoles.ts +34 -0
- package/src/composables/useSandboxStatus.ts +67 -0
- package/src/composables/useSelectedResult.ts +49 -0
- package/src/composables/useSessionDerived.ts +51 -0
- package/src/composables/useSessionHistory.ts +81 -0
- package/src/composables/useSessionSync.ts +57 -0
- package/src/composables/useViewLayout.ts +55 -0
- package/src/config/apiRoutes.ts +173 -0
- package/src/config/pubsubChannels.ts +45 -0
- package/src/config/roles.ts +335 -0
- package/src/config/schedulerActions.ts +25 -0
- package/src/config/toolNames.ts +71 -0
- package/src/config/workspacePaths.ts +24 -0
- package/src/index.css +107 -0
- package/src/main.ts +25 -0
- package/src/plugins/canvas/Preview.vue +13 -0
- package/src/plugins/canvas/View.vue +333 -0
- package/src/plugins/canvas/definition.ts +38 -0
- package/src/plugins/canvas/index.ts +36 -0
- package/src/plugins/chart/Preview.vue +49 -0
- package/src/plugins/chart/View.vue +143 -0
- package/src/plugins/chart/definition.ts +58 -0
- package/src/plugins/chart/index.ts +52 -0
- package/src/plugins/editImage/Preview.vue +13 -0
- package/src/plugins/editImage/View.vue +13 -0
- package/src/plugins/editImage/definition.ts +27 -0
- package/src/plugins/editImage/index.ts +36 -0
- package/src/plugins/generateImage/Preview.vue +13 -0
- package/src/plugins/generateImage/View.vue +33 -0
- package/src/plugins/generateImage/definition.ts +32 -0
- package/src/plugins/generateImage/index.ts +56 -0
- package/src/plugins/manageRoles/Preview.vue +49 -0
- package/src/plugins/manageRoles/View.vue +525 -0
- package/src/plugins/manageRoles/definition.ts +43 -0
- package/src/plugins/manageRoles/index.ts +47 -0
- package/src/plugins/manageSkills/Preview.vue +21 -0
- package/src/plugins/manageSkills/View.vue +321 -0
- package/src/plugins/manageSkills/definition.ts +49 -0
- package/src/plugins/manageSkills/index.ts +49 -0
- package/src/plugins/manageSource/Preview.vue +33 -0
- package/src/plugins/manageSource/View.vue +697 -0
- package/src/plugins/manageSource/definition.ts +63 -0
- package/src/plugins/manageSource/index.ts +66 -0
- package/src/plugins/markdown/Preview.vue +77 -0
- package/src/plugins/markdown/View.vue +476 -0
- package/src/plugins/markdown/definition.ts +50 -0
- package/src/plugins/markdown/index.ts +36 -0
- package/src/plugins/presentHtml/Preview.vue +25 -0
- package/src/plugins/presentHtml/View.vue +52 -0
- package/src/plugins/presentHtml/definition.ts +27 -0
- package/src/plugins/presentHtml/helpers.ts +72 -0
- package/src/plugins/presentHtml/index.ts +41 -0
- package/src/plugins/presentMulmoScript/Preview.vue +23 -0
- package/src/plugins/presentMulmoScript/View.vue +1166 -0
- package/src/plugins/presentMulmoScript/definition.ts +95 -0
- package/src/plugins/presentMulmoScript/helpers.ts +162 -0
- package/src/plugins/presentMulmoScript/index.ts +40 -0
- package/src/plugins/scheduler/Preview.vue +67 -0
- package/src/plugins/scheduler/TasksTab.vue +205 -0
- package/src/plugins/scheduler/View.vue +565 -0
- package/src/plugins/scheduler/definition.ts +57 -0
- package/src/plugins/scheduler/index.ts +45 -0
- package/src/plugins/scheduler/viewModes.ts +26 -0
- package/src/plugins/spreadsheet/Preview.vue +29 -0
- package/src/plugins/spreadsheet/View.vue +997 -0
- package/src/plugins/spreadsheet/cellHighlights.ts +79 -0
- package/src/plugins/spreadsheet/definition.ts +121 -0
- package/src/plugins/spreadsheet/engine/calculator.ts +459 -0
- package/src/plugins/spreadsheet/engine/cellBuilder.ts +81 -0
- package/src/plugins/spreadsheet/engine/date-parser.ts +220 -0
- package/src/plugins/spreadsheet/engine/date-utils.ts +56 -0
- package/src/plugins/spreadsheet/engine/engine.ts +176 -0
- package/src/plugins/spreadsheet/engine/evaluator.ts +390 -0
- package/src/plugins/spreadsheet/engine/formatter.ts +172 -0
- package/src/plugins/spreadsheet/engine/formulaRefs.ts +101 -0
- package/src/plugins/spreadsheet/engine/functions/date.ts +299 -0
- package/src/plugins/spreadsheet/engine/functions/financial.ts +387 -0
- package/src/plugins/spreadsheet/engine/functions/index.ts +16 -0
- package/src/plugins/spreadsheet/engine/functions/logical.ts +262 -0
- package/src/plugins/spreadsheet/engine/functions/lookup.ts +400 -0
- package/src/plugins/spreadsheet/engine/functions/mathematical.ts +297 -0
- package/src/plugins/spreadsheet/engine/functions/statistical.ts +338 -0
- package/src/plugins/spreadsheet/engine/functions/text.ts +389 -0
- package/src/plugins/spreadsheet/engine/index.ts +27 -0
- package/src/plugins/spreadsheet/engine/jsonCellLocator.ts +111 -0
- package/src/plugins/spreadsheet/engine/parser.ts +143 -0
- package/src/plugins/spreadsheet/engine/registry.ts +150 -0
- package/src/plugins/spreadsheet/engine/responseDecoder.ts +67 -0
- package/src/plugins/spreadsheet/engine/types.ts +64 -0
- package/src/plugins/spreadsheet/index.ts +36 -0
- package/src/plugins/textResponse/Preview.vue +94 -0
- package/src/plugins/textResponse/View.vue +503 -0
- package/src/plugins/textResponse/definition.ts +34 -0
- package/src/plugins/textResponse/index.ts +27 -0
- package/src/plugins/textResponse/plugin.ts +29 -0
- package/src/plugins/textResponse/samples.ts +97 -0
- package/src/plugins/textResponse/types.ts +11 -0
- package/src/plugins/todo/Preview.vue +63 -0
- package/src/plugins/todo/View.vue +364 -0
- package/src/plugins/todo/composables/useTodos.ts +177 -0
- package/src/plugins/todo/definition.ts +45 -0
- package/src/plugins/todo/index.ts +61 -0
- package/src/plugins/todo/labels.ts +163 -0
- package/src/plugins/todo/priority.ts +98 -0
- package/src/plugins/todo/viewModes.ts +19 -0
- package/src/plugins/ui-image/ImagePreview.vue +23 -0
- package/src/plugins/ui-image/ImageView.vue +34 -0
- package/src/plugins/ui-image/index.ts +3 -0
- package/src/plugins/ui-image/types.ts +4 -0
- package/src/plugins/wiki/Preview.vue +65 -0
- package/src/plugins/wiki/View.vue +342 -0
- package/src/plugins/wiki/definition.ts +25 -0
- package/src/plugins/wiki/helpers.ts +59 -0
- package/src/plugins/wiki/index.ts +52 -0
- package/src/router/guards.ts +61 -0
- package/src/router/index.ts +50 -0
- package/src/tools/index.ts +52 -0
- package/src/tools/types.ts +27 -0
- package/src/types/events.ts +16 -0
- package/src/types/fileTree.ts +13 -0
- package/src/types/notification.ts +67 -0
- package/src/types/session.ts +116 -0
- package/src/types/sse.ts +90 -0
- package/src/types/toolCallHistory.ts +13 -0
- package/src/utils/agent/eventDispatch.ts +74 -0
- package/src/utils/agent/request.ts +55 -0
- package/src/utils/agent/toolCalls.ts +62 -0
- package/src/utils/api.ts +218 -0
- package/src/utils/canvas/viewMode.ts +46 -0
- package/src/utils/dom/authTokenMeta.ts +20 -0
- package/src/utils/dom/clickOutside.ts +11 -0
- package/src/utils/dom/externalLink.ts +57 -0
- package/src/utils/dom/scrollable.ts +24 -0
- package/src/utils/errors.ts +11 -0
- package/src/utils/files/expandedDirs.ts +25 -0
- package/src/utils/files/filename.ts +12 -0
- package/src/utils/files/sortChildren.ts +20 -0
- package/src/utils/filesPreview/schedulerPreview.ts +38 -0
- package/src/utils/filesPreview/todoPreview.ts +40 -0
- package/src/utils/format/date.ts +85 -0
- package/src/utils/format/frontmatter.ts +80 -0
- package/src/utils/format/jsonSyntax.ts +109 -0
- package/src/utils/html/previewCsp.ts +65 -0
- package/src/utils/image/resolve.ts +8 -0
- package/src/utils/image/rewriteMarkdownImageRefs.ts +182 -0
- package/src/utils/markdown/extractFirstH1.ts +39 -0
- package/src/utils/notification/dispatch.ts +22 -0
- package/src/utils/path/relativeLink.ts +130 -0
- package/src/utils/role/icon.ts +20 -0
- package/src/utils/role/merge.ts +10 -0
- package/src/utils/role/plugins.ts +12 -0
- package/src/utils/session/mergeSessions.ts +103 -0
- package/src/utils/session/seedRoleDefault.ts +35 -0
- package/src/utils/session/sessionEntries.ts +121 -0
- package/src/utils/session/sessionFactory.ts +22 -0
- package/src/utils/session/sessionHelpers.ts +99 -0
- package/src/utils/tools/dedup.ts +17 -0
- package/src/utils/tools/mcp.ts +33 -0
- package/src/utils/tools/pendingCalls.ts +16 -0
- package/src/utils/tools/result.ts +40 -0
- package/src/utils/types.ts +44 -0
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Spreadsheet Function Registry
|
|
3
|
+
*
|
|
4
|
+
* This module provides a registry system for spreadsheet functions,
|
|
5
|
+
* allowing modular organization and easy extension of formula capabilities.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import type { CellValue } from "./types";
|
|
9
|
+
export type { CellValue };
|
|
10
|
+
export type CellGetter = (ref: string) => CellValue;
|
|
11
|
+
export type RangeGetter = (range: string) => CellValue[];
|
|
12
|
+
export type RawRangeGetter = (range: string) => CellValue[];
|
|
13
|
+
|
|
14
|
+
export interface FunctionContext {
|
|
15
|
+
getCellValue: CellGetter;
|
|
16
|
+
getRangeValues: RangeGetter;
|
|
17
|
+
getRangeValuesRaw?: RawRangeGetter;
|
|
18
|
+
evaluateFormula: (formula: string) => CellValue;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export type FunctionHandler = (args: string[], context: FunctionContext) => CellValue;
|
|
22
|
+
|
|
23
|
+
export interface FunctionDefinition {
|
|
24
|
+
name: string;
|
|
25
|
+
handler: FunctionHandler;
|
|
26
|
+
minArgs?: number;
|
|
27
|
+
maxArgs?: number;
|
|
28
|
+
description?: string;
|
|
29
|
+
examples?: string[];
|
|
30
|
+
category?: string;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
class FunctionRegistry {
|
|
34
|
+
private functions = new Map<string, FunctionDefinition>();
|
|
35
|
+
|
|
36
|
+
register(def: FunctionDefinition): void {
|
|
37
|
+
this.functions.set(def.name.toUpperCase(), def);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
get(name: string): FunctionDefinition | undefined {
|
|
41
|
+
return this.functions.get(name.toUpperCase());
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
hasFunction(name: string): boolean {
|
|
45
|
+
return this.functions.has(name.toUpperCase());
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
getAllFunctions(): FunctionDefinition[] {
|
|
49
|
+
return Array.from(this.functions.values());
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
getFunctionsByCategory(): Map<string, FunctionDefinition[]> {
|
|
53
|
+
const categories = new Map<string, FunctionDefinition[]>();
|
|
54
|
+
|
|
55
|
+
for (const func of Array.from(this.functions.values())) {
|
|
56
|
+
const category = func.category || "Other";
|
|
57
|
+
if (!categories.has(category)) {
|
|
58
|
+
categories.set(category, []);
|
|
59
|
+
}
|
|
60
|
+
categories.get(category)!.push(func);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
return categories;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export const functionRegistry = new FunctionRegistry();
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Helper function to convert a value to a number
|
|
71
|
+
*/
|
|
72
|
+
export function toNumber(value: CellValue): number {
|
|
73
|
+
if (typeof value === "number") return value;
|
|
74
|
+
|
|
75
|
+
// Handle percentage strings like "5%" or "0.4167%"
|
|
76
|
+
if (typeof value === "string" && value.includes("%")) {
|
|
77
|
+
const numericPart = value.replace("%", "").trim();
|
|
78
|
+
const num = parseFloat(numericPart);
|
|
79
|
+
return isNaN(num) ? 0 : num / 100;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// Handle currency strings like "$1,000" or "$1,000.00"
|
|
83
|
+
if (typeof value === "string" && value.includes("$")) {
|
|
84
|
+
const numericPart = value.replace(/[$,]/g, "").trim();
|
|
85
|
+
const num = parseFloat(numericPart);
|
|
86
|
+
return isNaN(num) ? 0 : num;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// Handle comma-separated numbers like "1,000"
|
|
90
|
+
if (typeof value === "string" && value.includes(",")) {
|
|
91
|
+
const numericPart = value.replace(/,/g, "").trim();
|
|
92
|
+
const num = parseFloat(numericPart);
|
|
93
|
+
return isNaN(num) ? 0 : num;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// Handle regular numeric strings
|
|
97
|
+
const num = parseFloat(String(value));
|
|
98
|
+
return isNaN(num) ? 0 : num;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Helper function to convert a value to a string
|
|
103
|
+
*/
|
|
104
|
+
export function toString(value: CellValue): string {
|
|
105
|
+
return String(value);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Helper to parse criteria for conditional functions like COUNTIF, SUMIF
|
|
110
|
+
* Returns a comparison function that tests if a value matches the criteria
|
|
111
|
+
*/
|
|
112
|
+
export function parseCriteria(criteria: string): (value: CellValue) => boolean {
|
|
113
|
+
// eslint-disable -- sonarjs/anchor-precedence
|
|
114
|
+
const trimmedCriteria = criteria.trim().replace(/^["']|["']$/g, "");
|
|
115
|
+
|
|
116
|
+
// Check for comparison operators
|
|
117
|
+
// eslint-disable -- sonarjs/slow-regex
|
|
118
|
+
const opMatch = trimmedCriteria.match(/^([><=!]+)(.+)$/);
|
|
119
|
+
if (opMatch) {
|
|
120
|
+
const [, op, value] = opMatch;
|
|
121
|
+
const numValue = parseFloat(value);
|
|
122
|
+
|
|
123
|
+
switch (op) {
|
|
124
|
+
case ">":
|
|
125
|
+
return (v) => toNumber(v) > numValue;
|
|
126
|
+
case ">=":
|
|
127
|
+
return (v) => toNumber(v) >= numValue;
|
|
128
|
+
case "<":
|
|
129
|
+
return (v) => toNumber(v) < numValue;
|
|
130
|
+
case "<=":
|
|
131
|
+
return (v) => toNumber(v) <= numValue;
|
|
132
|
+
case "=":
|
|
133
|
+
case "==":
|
|
134
|
+
return (v) => String(v) === value || toNumber(v) === numValue;
|
|
135
|
+
case "!=":
|
|
136
|
+
case "<>":
|
|
137
|
+
return (v) => String(v) !== value && toNumber(v) !== numValue;
|
|
138
|
+
default:
|
|
139
|
+
return () => false;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
// Exact match (string or number)
|
|
144
|
+
return (v) => {
|
|
145
|
+
const strMatch = String(v) === trimmedCriteria;
|
|
146
|
+
const numCriteria = parseFloat(trimmedCriteria);
|
|
147
|
+
const numMatch = !isNaN(numCriteria) && toNumber(v) === numCriteria;
|
|
148
|
+
return strMatch || numMatch;
|
|
149
|
+
};
|
|
150
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Decode the `/api/files/content` response for a spreadsheet file
|
|
3
|
+
* into an "ok with sheets" / "error with message" discriminated
|
|
4
|
+
* union. Extracted from `fetchSheets` in
|
|
5
|
+
* `src/plugins/spreadsheet/View.vue` where the decision tree was
|
|
6
|
+
* inlined as several nested try/catch + if branches.
|
|
7
|
+
*
|
|
8
|
+
* Pure — no fetch, no refs. Takes the parsed JSON body and returns
|
|
9
|
+
* a result the caller can pattern-match on. Tested in
|
|
10
|
+
* `test/plugins/spreadsheet/engine/test_responseDecoder.ts`.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import type { SheetData } from "./types.js";
|
|
14
|
+
|
|
15
|
+
/** Shape of the `/api/files/content` response we care about. The
|
|
16
|
+
* server returns more fields (kind, size, modifiedMs, …) but this
|
|
17
|
+
* decoder only depends on the three that drive branching. */
|
|
18
|
+
export interface FilesContentResponseLike {
|
|
19
|
+
kind?: string;
|
|
20
|
+
content?: string;
|
|
21
|
+
message?: string;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export type DecodeResult = { kind: "ok"; sheets: SheetData[] } | { kind: "error"; message: string };
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Turn a parsed `/files/content` body into an OK/error decision:
|
|
28
|
+
*
|
|
29
|
+
* - `kind` present and not "text" → error with the server's message
|
|
30
|
+
* (e.g. "too-large", "binary"). Spreadsheets only live in text
|
|
31
|
+
* JSON files.
|
|
32
|
+
* - Missing or non-string `content` → error.
|
|
33
|
+
* - `content` is not valid JSON → error.
|
|
34
|
+
* - Parsed `content` is not an array → error (server should never
|
|
35
|
+
* return a non-array but the guard protects downstream render).
|
|
36
|
+
* - Otherwise → ok with the sheets array.
|
|
37
|
+
*/
|
|
38
|
+
export function decodeSpreadsheetResponse(body: FilesContentResponseLike): DecodeResult {
|
|
39
|
+
if (body.kind && body.kind !== "text") {
|
|
40
|
+
return {
|
|
41
|
+
kind: "error",
|
|
42
|
+
message: body.message ?? `Cannot load spreadsheet: ${body.kind}`,
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
if (typeof body.content !== "string") {
|
|
46
|
+
return { kind: "error", message: "Spreadsheet file has no content" };
|
|
47
|
+
}
|
|
48
|
+
let parsed: unknown;
|
|
49
|
+
try {
|
|
50
|
+
parsed = JSON.parse(body.content);
|
|
51
|
+
} catch (err) {
|
|
52
|
+
return {
|
|
53
|
+
kind: "error",
|
|
54
|
+
message: `Spreadsheet JSON is malformed: ${err instanceof Error ? err.message : "parse error"}`,
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
if (!Array.isArray(parsed)) {
|
|
58
|
+
return {
|
|
59
|
+
kind: "error",
|
|
60
|
+
message: "Spreadsheet content is not an array of sheets",
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
// Array.isArray narrows to unknown[]; we trust the server contract
|
|
64
|
+
// and type the local explicitly rather than using an inline `as`.
|
|
65
|
+
const sheets: SheetData[] = parsed;
|
|
66
|
+
return { kind: "ok", sheets };
|
|
67
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Spreadsheet Engine Type Definitions
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
export type CellValue = number | string | boolean;
|
|
6
|
+
|
|
7
|
+
export interface SpreadsheetCell {
|
|
8
|
+
v: CellValue; // Value or formula (formulas start with "=")
|
|
9
|
+
f?: string; // Format code (e.g., "$#,##0.00")
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export interface SheetData {
|
|
13
|
+
name: string;
|
|
14
|
+
data: SpreadsheetCell[][];
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export interface CalculatedSheet {
|
|
18
|
+
name: string;
|
|
19
|
+
data: CellValue[][]; // Calculated values
|
|
20
|
+
formulas: FormulaInfo[]; // Formula metadata
|
|
21
|
+
errors: CalculationError[]; // Any errors encountered
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export interface CellRef {
|
|
25
|
+
row: number;
|
|
26
|
+
col: number;
|
|
27
|
+
sheet?: string; // For cross-sheet refs
|
|
28
|
+
absolute?: {
|
|
29
|
+
// For $A$1 style
|
|
30
|
+
row: boolean;
|
|
31
|
+
col: boolean;
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export interface RangeRef {
|
|
36
|
+
start: CellRef;
|
|
37
|
+
end: CellRef;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export interface EvaluationContext {
|
|
41
|
+
currentSheet: string;
|
|
42
|
+
sheets: Map<string, SpreadsheetCell[][]>;
|
|
43
|
+
calculatedValues?: Map<string, CellValue>; // Cache
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export interface FormulaInfo {
|
|
47
|
+
cell: CellRef;
|
|
48
|
+
formula: string;
|
|
49
|
+
dependencies: CellRef[];
|
|
50
|
+
result: CellValue;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export interface CalculationError {
|
|
54
|
+
cell: CellRef;
|
|
55
|
+
formula: string;
|
|
56
|
+
error: string;
|
|
57
|
+
type: "circular" | "invalid_ref" | "div_zero" | "syntax" | "unknown";
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export interface EngineOptions {
|
|
61
|
+
maxIterations?: number; // For circular reference detection
|
|
62
|
+
enableCrossSheetRefs?: boolean; // Default: true
|
|
63
|
+
strictMode?: boolean; // Throw on errors vs. return 0
|
|
64
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { ToolPlugin } from "../../tools/types";
|
|
2
|
+
import type { ToolResult } from "gui-chat-protocol";
|
|
3
|
+
import toolDefinition, { TOOL_NAME } from "./definition";
|
|
4
|
+
import type { SpreadsheetToolData } from "./definition";
|
|
5
|
+
import View from "./View.vue";
|
|
6
|
+
import Preview from "./Preview.vue";
|
|
7
|
+
import { apiPost } from "../../utils/api";
|
|
8
|
+
import { API_ROUTES } from "../../config/apiRoutes";
|
|
9
|
+
|
|
10
|
+
const spreadsheetPlugin: ToolPlugin<SpreadsheetToolData> = {
|
|
11
|
+
toolDefinition,
|
|
12
|
+
|
|
13
|
+
async execute(_context, args) {
|
|
14
|
+
const result = await apiPost<ToolResult<SpreadsheetToolData>>(API_ROUTES.plugins.presentSpreadsheet, args);
|
|
15
|
+
if (!result.ok) {
|
|
16
|
+
return {
|
|
17
|
+
toolName: TOOL_NAME,
|
|
18
|
+
uuid: crypto.randomUUID(),
|
|
19
|
+
message: result.error,
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
return {
|
|
23
|
+
...result.data,
|
|
24
|
+
toolName: TOOL_NAME,
|
|
25
|
+
uuid: crypto.randomUUID(),
|
|
26
|
+
};
|
|
27
|
+
},
|
|
28
|
+
|
|
29
|
+
isEnabled: () => true,
|
|
30
|
+
generatingMessage: "Creating spreadsheet...",
|
|
31
|
+
viewComponent: View,
|
|
32
|
+
previewComponent: Preview,
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
export default spreadsheetPlugin;
|
|
36
|
+
export { TOOL_NAME };
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="text-sm leading-snug" :class="textColorClass">
|
|
3
|
+
<div class="preview-markdown" v-html="renderedMarkdown" />
|
|
4
|
+
</div>
|
|
5
|
+
</template>
|
|
6
|
+
|
|
7
|
+
<script setup lang="ts">
|
|
8
|
+
import { computed } from "vue";
|
|
9
|
+
import { marked } from "marked";
|
|
10
|
+
import type { ToolResultComplete } from "gui-chat-protocol/vue";
|
|
11
|
+
import type { TextResponseData } from "./types";
|
|
12
|
+
|
|
13
|
+
const props = defineProps<{
|
|
14
|
+
result: ToolResultComplete<TextResponseData>;
|
|
15
|
+
}>();
|
|
16
|
+
|
|
17
|
+
const previewText = computed(() => props.result.data?.text ?? "");
|
|
18
|
+
const messageRole = computed(() => props.result.data?.role ?? "assistant");
|
|
19
|
+
|
|
20
|
+
const textColorClass = computed(() => {
|
|
21
|
+
switch (messageRole.value) {
|
|
22
|
+
case "system":
|
|
23
|
+
return "text-blue-700";
|
|
24
|
+
case "user":
|
|
25
|
+
return "text-green-700 font-medium";
|
|
26
|
+
default:
|
|
27
|
+
return "text-gray-700";
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
const renderedMarkdown = computed(() => marked(previewText.value, { breaks: true, gfm: true }));
|
|
32
|
+
</script>
|
|
33
|
+
|
|
34
|
+
<style scoped>
|
|
35
|
+
.preview-markdown {
|
|
36
|
+
overflow: hidden;
|
|
37
|
+
display: -webkit-box;
|
|
38
|
+
-webkit-line-clamp: 5;
|
|
39
|
+
-webkit-box-orient: vertical;
|
|
40
|
+
/* Links inside v-html would otherwise hijack the row-level
|
|
41
|
+
select click and navigate to the article URL. */
|
|
42
|
+
pointer-events: none;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
.preview-markdown :deep(p) {
|
|
46
|
+
margin: 0;
|
|
47
|
+
display: inline;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
.preview-markdown :deep(h1),
|
|
51
|
+
.preview-markdown :deep(h2),
|
|
52
|
+
.preview-markdown :deep(h3),
|
|
53
|
+
.preview-markdown :deep(h4),
|
|
54
|
+
.preview-markdown :deep(h5),
|
|
55
|
+
.preview-markdown :deep(h6) {
|
|
56
|
+
font-size: inherit;
|
|
57
|
+
font-weight: bold;
|
|
58
|
+
display: inline;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
.preview-markdown :deep(ul),
|
|
62
|
+
.preview-markdown :deep(ol) {
|
|
63
|
+
display: inline;
|
|
64
|
+
margin: 0;
|
|
65
|
+
padding: 0;
|
|
66
|
+
list-style: none;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
.preview-markdown :deep(li) {
|
|
70
|
+
display: inline;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
.preview-markdown :deep(li)::before {
|
|
74
|
+
content: "• ";
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
.preview-markdown :deep(strong) {
|
|
78
|
+
font-weight: bold;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
.preview-markdown :deep(em) {
|
|
82
|
+
font-style: italic;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
.preview-markdown :deep(code) {
|
|
86
|
+
font-family: monospace;
|
|
87
|
+
font-size: 0.9em;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
.preview-markdown :deep(pre) {
|
|
91
|
+
display: inline;
|
|
92
|
+
white-space: pre-wrap;
|
|
93
|
+
}
|
|
94
|
+
</style>
|