mulmoclaude 0.5.2 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Dockerfile.sandbox +100 -0
- package/README.md +17 -4
- package/bin/mulmoclaude.js +46 -15
- package/bin/prepare-dist.js +18 -2
- package/client/assets/chunk-CernVdwh.js +1 -0
- package/client/assets/chunk-D8eiyYIV-C1eAZMzz.js +1 -0
- package/client/assets/html2canvas-CDGcmOD3-BbPeutDg.js +5 -0
- package/client/assets/index-BbgSjFQ8.js +4968 -0
- package/client/assets/index-ECD0lgIv.css +2 -0
- package/client/assets/{index.es-D4YyL_Dg-BgT6a3Nd.js → index.es-DqtpmBm8-DJdTPdnc.js} +5 -5
- package/client/assets/material-symbols-outlined-BLDfUw-_.woff2 +0 -0
- package/client/assets/runtime-protocol-vue-6WYa8hAs.js +1 -0
- package/client/assets/runtime-vue-BVUzgYGA.js +1 -0
- package/client/assets/typeof-DBp4T-Ny-C2xoZtcz.js +1 -0
- package/client/assets/vue-1e_vz2LW.js +1 -0
- package/client/assets/vue.runtime.esm-bundler-DQ8Kjjui.js +4 -0
- package/client/index.html +33 -2
- package/package.json +20 -18
- package/sandbox-entrypoint.sh +106 -0
- package/server/accounting/accountNormalize.ts +32 -0
- package/server/accounting/defaultAccounts.ts +87 -0
- package/server/accounting/eventPublisher.ts +51 -0
- package/server/accounting/journal.ts +252 -0
- package/server/accounting/openingBalances.ts +114 -0
- package/server/accounting/report.ts +237 -0
- package/server/accounting/service.ts +718 -0
- package/server/accounting/snapshotCache.ts +333 -0
- package/server/accounting/timeSeries.ts +265 -0
- package/server/accounting/types.ts +148 -0
- package/server/agent/activeTools.ts +128 -0
- package/server/agent/attachmentConverter.ts +10 -5
- package/server/agent/backend/claude-code.ts +8 -2
- package/server/agent/backend/types.ts +1 -1
- package/server/agent/config.ts +101 -31
- package/server/agent/index.ts +45 -33
- package/server/agent/mcp-server.ts +146 -69
- package/server/agent/mcp-tools/index.ts +1 -5
- package/server/agent/mcp-tools/notify.ts +2 -22
- package/server/agent/mcp-tools/x.ts +0 -4
- package/server/agent/mcpHealth.ts +168 -0
- package/server/agent/plugin-names.ts +20 -77
- package/server/agent/prompt.ts +259 -51
- package/server/agent/resumeFailover.ts +1 -1
- package/server/agent/stream.ts +0 -1
- package/server/api/auth/bearerAuth.ts +5 -5
- package/server/api/csrfGuard.ts +1 -1
- package/server/api/routes/accounting.ts +366 -0
- package/server/api/routes/agent.ts +509 -46
- package/server/api/routes/attachment.ts +104 -0
- package/server/api/routes/chart.ts +2 -1
- package/server/api/routes/config.ts +12 -12
- package/server/api/routes/files.ts +105 -48
- package/server/api/routes/image.ts +70 -25
- package/server/api/routes/journal.ts +35 -0
- package/server/api/routes/mulmo-script.ts +358 -118
- package/server/api/routes/mulmoScriptValidate.ts +1 -1
- package/server/api/routes/news.ts +1 -1
- package/server/api/routes/notifications.ts +92 -22
- package/server/api/routes/notifier.ts +98 -0
- package/server/api/routes/pdf.ts +188 -48
- package/server/api/routes/plugins.ts +34 -14
- package/server/api/routes/presentHtml.ts +58 -3
- package/server/api/routes/roles.ts +1 -8
- package/server/api/routes/runtime-plugin.ts +224 -0
- package/server/api/routes/scheduler.ts +7 -5
- package/server/api/routes/schedulerHandlers.ts +1 -1
- package/server/api/routes/schedulerTasks.ts +8 -7
- package/server/api/routes/sessions.ts +234 -121
- package/server/api/routes/skills.ts +56 -51
- package/server/api/routes/sources.ts +52 -45
- package/server/api/routes/translation.ts +44 -0
- package/server/api/routes/wiki/frontmatter.ts +13 -65
- package/server/api/routes/wiki/history.ts +261 -0
- package/server/api/routes/wiki/pageIndex.ts +1 -1
- package/server/api/routes/wiki.ts +50 -26
- package/server/events/file-change.ts +83 -0
- package/server/events/notifications.ts +247 -91
- package/server/events/pub-sub/index.ts +1 -1
- package/server/events/relay-client.ts +5 -5
- package/server/events/scheduler-adapter.ts +2 -2
- package/server/events/session-store/index.ts +110 -22
- package/server/events/task-manager/index.ts +10 -9
- package/server/index.ts +509 -33
- package/server/notifier/engine.ts +419 -0
- package/server/notifier/legacy-adapters.ts +76 -0
- package/server/notifier/runtime-api.ts +74 -0
- package/server/notifier/store.ts +70 -0
- package/server/notifier/types.ts +121 -0
- package/server/plugins/dev-loader.ts +171 -0
- package/server/plugins/dev-watcher.ts +150 -0
- package/server/plugins/diagnostics.ts +188 -0
- package/server/plugins/preset-list.ts +52 -0
- package/server/plugins/preset-loader.ts +112 -0
- package/server/plugins/runtime-chat-api.ts +38 -0
- package/server/plugins/runtime-loader.ts +430 -0
- package/server/plugins/runtime-registry.ts +112 -0
- package/server/plugins/runtime-tasks-api.ts +50 -0
- package/server/plugins/runtime.ts +378 -0
- package/server/services/translation/cache.ts +72 -0
- package/server/services/translation/index.ts +106 -0
- package/server/services/translation/llm.ts +140 -0
- package/server/services/translation/types.ts +35 -0
- package/server/system/credentials.ts +13 -2
- package/server/system/env.ts +6 -1
- package/server/system/logger/formatters.ts +46 -4
- package/server/system/logger/index.ts +4 -4
- package/server/system/logger/sinks.ts +26 -5
- package/server/system/logger/types.ts +2 -2
- package/server/utils/dev-plugin-args.d.mts +11 -0
- package/server/utils/dev-plugin-args.mjs +43 -0
- package/server/utils/errors.ts +13 -4
- package/server/utils/files/accounting-io.ts +295 -0
- package/server/utils/files/atomic.ts +17 -49
- package/server/utils/files/attachment-store.ts +182 -0
- package/server/utils/files/html-io.ts +1 -7
- package/server/utils/files/html-store.ts +19 -0
- package/server/utils/files/image-store.ts +20 -22
- package/server/utils/files/index.ts +5 -15
- package/server/utils/files/journal-io.ts +7 -35
- package/server/utils/files/json.ts +2 -29
- package/server/utils/files/markdown-image-fill.ts +6 -37
- package/server/utils/files/markdown-store.ts +6 -21
- package/server/utils/files/naming.ts +3 -39
- package/server/utils/files/plugins-io.ts +100 -0
- package/server/utils/files/reference-dirs-io.ts +1 -9
- package/server/utils/files/roles-io.ts +2 -10
- package/server/utils/files/safe.ts +17 -19
- package/server/utils/files/scheduler-io.ts +1 -7
- package/server/utils/files/scheduler-overrides-io.ts +3 -12
- package/server/utils/files/session-io.ts +21 -30
- package/server/utils/files/spreadsheet-store.ts +9 -22
- package/server/utils/files/translation-io.ts +46 -0
- package/server/utils/files/user-tasks-io.ts +1 -7
- package/server/utils/files/workspace-io.ts +3 -79
- package/server/utils/gemini.ts +33 -11
- package/server/utils/html/htmlArtifactSplicer.ts +41 -0
- package/server/utils/markdown/frontmatter.ts +112 -0
- package/server/utils/regex.ts +56 -0
- package/server/utils/router.ts +41 -0
- package/server/utils/slug.ts +5 -3
- package/server/utils/time.ts +12 -0
- package/server/workspace/chat-index/indexer.ts +15 -2
- package/server/workspace/chat-index/summarizer.ts +1 -1
- package/server/workspace/custom-dirs.ts +1 -1
- package/server/workspace/helps/gemini.md +1 -1
- package/server/workspace/helps/guide.md +61 -0
- package/server/workspace/helps/index.md +4 -0
- package/server/workspace/helps/presenthtml.md +80 -0
- package/server/workspace/helps/sandbox.md +7 -0
- package/server/workspace/helps/storyteller.md +101 -0
- package/server/workspace/helps/telegram.md +1 -0
- package/server/workspace/helps/wiki.md +9 -7
- package/server/workspace/journal/archivist-cli.ts +7 -33
- package/server/workspace/journal/archivist-schemas.ts +5 -43
- package/server/workspace/journal/dailyPass.ts +34 -187
- package/server/workspace/journal/diff.ts +3 -28
- package/server/workspace/journal/index.ts +10 -81
- package/server/workspace/journal/indexFile.ts +3 -24
- package/server/workspace/journal/latestDaily.ts +51 -0
- package/server/workspace/journal/memoryExtractor.ts +4 -20
- package/server/workspace/journal/optimizationPass.ts +4 -21
- package/server/workspace/journal/paths.ts +4 -23
- package/server/workspace/journal/state.ts +6 -29
- package/server/workspace/memory/io.ts +213 -0
- package/server/workspace/memory/llm-classifier.ts +158 -0
- package/server/workspace/memory/migrate.ts +263 -0
- package/server/workspace/memory/run.ts +84 -0
- package/server/workspace/memory/topic-cluster.ts +218 -0
- package/server/workspace/memory/topic-detect.ts +67 -0
- package/server/workspace/memory/topic-index-hook.ts +128 -0
- package/server/workspace/memory/topic-io.ts +180 -0
- package/server/workspace/memory/topic-migrate.ts +248 -0
- package/server/workspace/memory/topic-run.ts +172 -0
- package/server/workspace/memory/topic-swap.ts +135 -0
- package/server/workspace/memory/topic-types.ts +142 -0
- package/server/workspace/memory/types.ts +83 -0
- package/server/workspace/news/reader.ts +4 -5
- package/server/workspace/paths.ts +124 -47
- package/server/workspace/roles.ts +2 -11
- package/server/workspace/skills/parser.ts +38 -55
- package/server/workspace/skills/user-tasks.ts +1 -2
- package/server/workspace/skills-preset/mc-library/SKILL.md +188 -0
- package/server/workspace/skills-preset.ts +196 -0
- package/server/workspace/sources/fetchers/githubIssues.ts +13 -11
- package/server/workspace/sources/fetchers/index.ts +1 -1
- package/server/workspace/sources/fetchers/rssParser.ts +1 -1
- package/server/workspace/sources/pipeline/index.ts +2 -2
- package/server/workspace/sources/pipeline/notify.ts +3 -3
- package/server/workspace/sources/pipeline/write.ts +2 -2
- package/server/workspace/sources/registry.ts +39 -61
- package/server/workspace/sources/robots.ts +1 -1
- package/server/workspace/tool-trace/classify.ts +2 -1
- package/server/workspace/tool-trace/index.ts +1 -1
- package/server/workspace/tool-trace/writeSearch.ts +6 -1
- package/server/workspace/wiki-backlinks/index.ts +19 -7
- package/server/workspace/wiki-backlinks/sessionBacklinks.ts +1 -0
- package/server/workspace/wiki-history/hook/snapshot.mjs +98 -0
- package/server/workspace/wiki-history/hook/snapshot.ts +135 -0
- package/server/workspace/wiki-history/provision.ts +181 -0
- package/server/workspace/wiki-pages/io.ts +217 -0
- package/server/workspace/wiki-pages/snapshot.ts +380 -0
- package/server/workspace/workspace.ts +75 -13
- package/src/App.vue +115 -40
- package/src/_runtime/protocol-vue.ts +21 -0
- package/src/_runtime/vue.ts +22 -0
- package/src/components/ChatInput.vue +14 -10
- package/src/components/CopyChatButton.vue +76 -0
- package/src/components/FileContentRenderer.vue +67 -14
- package/src/components/FileTree.vue +2 -2
- package/src/components/FilesView.vue +17 -1
- package/src/components/NewsView.vue +16 -2
- package/src/components/NotificationBell.vue +320 -93
- package/src/components/PageChatComposer.vue +5 -4
- package/src/components/PluginLauncher.vue +42 -6
- package/src/components/PluginScopedRoot.vue +87 -0
- package/src/components/RoleSelector.vue +12 -1
- package/src/components/RolesView.vue +562 -0
- package/src/components/SentAttachmentChip.vue +102 -0
- package/src/components/SessionHistoryPanel.vue +109 -20
- package/src/components/SessionRoleIcon.vue +7 -4
- package/src/components/SessionSidebar.vue +20 -7
- package/src/components/SessionTabBar.vue +1 -1
- package/src/components/SettingsMcpTab.vue +4 -4
- package/src/components/SettingsModal.vue +2 -0
- package/src/components/SidebarHeader.vue +16 -5
- package/src/components/SourcesManager.vue +23 -9
- package/src/components/SourcesView.vue +1 -1
- package/src/components/StackView.vue +102 -6
- package/src/components/SuggestionsPanel.vue +105 -16
- package/src/components/SystemFileBanner.vue +1 -1
- package/src/components/TodoExplorer.vue +4 -5
- package/src/components/todo/TodoAddDialog.vue +2 -3
- package/src/components/todo/TodoEditDialog.vue +1 -2
- package/src/components/todo/TodoEditPanel.vue +2 -3
- package/src/components/todo/TodoKanbanView.vue +8 -5
- package/src/components/todo/TodoListView.vue +3 -5
- package/src/components/todo/TodoTableView.vue +7 -5
- package/src/composables/useAccountingChannel.ts +58 -0
- package/src/composables/useActiveSession.ts +4 -25
- package/src/composables/useAppApi.ts +6 -44
- package/src/composables/useClipboardCopy.ts +3 -20
- package/src/composables/useContentDisplay.ts +33 -2
- package/src/composables/useDevPluginReload.ts +23 -0
- package/src/composables/useDynamicFavicon.ts +5 -31
- package/src/composables/useEventListeners.ts +0 -20
- package/src/composables/useExpandedDirs.ts +4 -15
- package/src/composables/useFaviconState.ts +12 -46
- package/src/composables/useFileChange.ts +53 -0
- package/src/composables/useFreshPluginData.ts +6 -43
- package/src/composables/useHealth.ts +14 -43
- package/src/composables/useImageErrorRepair.ts +104 -0
- package/src/composables/useLatestDaily.ts +40 -0
- package/src/composables/useMarkdownDoc.ts +39 -0
- package/src/composables/useMarkdownLinkHandler.ts +1 -1
- package/src/composables/useMcpTools.ts +3 -16
- package/src/composables/useNotifications.ts +138 -112
- package/src/composables/usePdfDownload.ts +17 -3
- package/src/composables/usePendingCalls.ts +8 -26
- package/src/composables/usePluginErrorBoundary.ts +68 -0
- package/src/composables/usePubSub.ts +9 -17
- package/src/composables/useRunElapsed.ts +5 -22
- package/src/composables/useSandboxStatus.ts +4 -20
- package/src/composables/useSessionDerived.ts +7 -15
- package/src/composables/useSessionHistory.ts +70 -29
- package/src/composables/useSessionSync.ts +25 -3
- package/src/composables/useSkillsList.ts +59 -0
- package/src/composables/useTranslatedQueries.ts +109 -0
- package/src/config/apiRoutes.ts +181 -80
- package/src/config/historyFilters.ts +5 -3
- package/src/config/hostEvents.ts +17 -0
- package/src/config/mcpCatalog.ts +277 -5
- package/src/config/pubsubChannels.ts +134 -12
- package/src/config/roles.ts +212 -147
- package/src/config/systemFileDescriptors.ts +5 -5
- package/src/config/toolNames.ts +52 -30
- package/src/config/workspacePaths.ts +26 -2
- package/src/lang/de.ts +483 -27
- package/src/lang/en.ts +448 -27
- package/src/lang/es.ts +474 -27
- package/src/lang/fr.ts +476 -27
- package/src/lang/ja.ts +465 -27
- package/src/lang/ko.ts +466 -27
- package/src/lang/pt-BR.ts +473 -27
- package/src/lang/zh.ts +463 -27
- package/src/lib/vue-i18n.ts +1 -1
- package/src/lib/wiki-page/slug.ts +66 -0
- package/src/main.ts +85 -0
- package/src/plugins/_extras.ts +58 -0
- package/src/plugins/_generated/metas.ts +42 -0
- package/src/plugins/_generated/registrations.ts +44 -0
- package/src/plugins/_generated/server-bindings.ts +47 -0
- package/src/plugins/accounting/Preview.vue +106 -0
- package/src/plugins/accounting/View.vue +632 -0
- package/src/plugins/accounting/actions.ts +34 -0
- package/src/plugins/accounting/api.ts +301 -0
- package/src/plugins/accounting/components/AccountEditor.vue +250 -0
- package/src/plugins/accounting/components/AccountRow.vue +50 -0
- package/src/plugins/accounting/components/AccountsList.vue +102 -0
- package/src/plugins/accounting/components/AccountsModal.vue +300 -0
- package/src/plugins/accounting/components/BalanceSheet.vue +186 -0
- package/src/plugins/accounting/components/BookSettings.vue +284 -0
- package/src/plugins/accounting/components/BookSwitcher.vue +78 -0
- package/src/plugins/accounting/components/DateRangePicker.vue +140 -0
- package/src/plugins/accounting/components/JournalEntryForm.vue +504 -0
- package/src/plugins/accounting/components/JournalList.vue +553 -0
- package/src/plugins/accounting/components/Ledger.vue +206 -0
- package/src/plugins/accounting/components/NewBookForm.vue +211 -0
- package/src/plugins/accounting/components/OpeningBalancesForm.vue +271 -0
- package/src/plugins/accounting/components/ProfitLoss.vue +160 -0
- package/src/plugins/accounting/components/accountDraft.ts +13 -0
- package/src/plugins/accounting/components/accountNumbering.ts +103 -0
- package/src/plugins/accounting/components/accountValidation.ts +75 -0
- package/src/plugins/accounting/components/useLatestRequest.ts +44 -0
- package/src/plugins/accounting/countries.ts +158 -0
- package/src/plugins/accounting/currencies.ts +64 -0
- package/src/plugins/accounting/dates.ts +51 -0
- package/src/plugins/accounting/definition.ts +199 -0
- package/src/plugins/accounting/fiscalYear.ts +136 -0
- package/src/plugins/accounting/index.ts +49 -0
- package/src/plugins/accounting/meta.ts +91 -0
- package/src/plugins/accounting/timeSeriesEnums.ts +16 -0
- package/src/plugins/api.ts +125 -0
- package/src/plugins/canvas/View.vue +38 -28
- package/src/plugins/canvas/definition.ts +10 -8
- package/src/plugins/canvas/index.ts +15 -8
- package/src/plugins/canvas/meta.ts +12 -0
- package/src/plugins/chart/Preview.vue +1 -1
- package/src/plugins/chart/View.vue +2 -2
- package/src/plugins/chart/definition.ts +12 -2
- package/src/plugins/chart/index.ts +15 -7
- package/src/plugins/chart/meta.ts +18 -0
- package/src/plugins/editImages/definition.ts +44 -0
- package/src/plugins/editImages/index.ts +43 -0
- package/src/plugins/editImages/meta.ts +5 -0
- package/src/plugins/generateImage/View.vue +3 -1
- package/src/plugins/generateImage/definition.ts +2 -0
- package/src/plugins/generateImage/index.ts +13 -5
- package/src/plugins/generateImage/meta.ts +5 -0
- package/src/plugins/index.ts +35 -0
- package/src/plugins/manageRoles/Preview.vue +7 -4
- package/src/plugins/manageRoles/View.vue +12 -8
- package/src/plugins/manageRoles/definition.ts +6 -0
- package/src/plugins/manageRoles/index.ts +7 -6
- package/src/plugins/manageSkills/View.vue +11 -7
- package/src/plugins/manageSkills/definition.ts +4 -1
- package/src/plugins/manageSkills/index.ts +14 -7
- package/src/plugins/manageSkills/meta.ts +21 -0
- package/src/plugins/manageSource/definition.ts +4 -1
- package/src/plugins/manageSource/index.ts +15 -7
- package/src/plugins/manageSource/meta.ts +21 -0
- package/src/plugins/markdown/Preview.vue +10 -8
- package/src/plugins/markdown/View.vue +84 -17
- package/src/plugins/markdown/definition.ts +7 -1
- package/src/plugins/markdown/index.ts +15 -8
- package/src/plugins/markdown/meta.ts +16 -0
- package/src/plugins/meta-types.ts +97 -0
- package/src/plugins/metas.ts +224 -0
- package/src/plugins/presentForm/Preview.vue +4 -15
- package/src/plugins/presentForm/View.vue +35 -78
- package/src/plugins/presentForm/definition.ts +7 -6
- package/src/plugins/presentForm/index.ts +12 -5
- package/src/plugins/presentForm/meta.ts +11 -0
- package/src/plugins/presentForm/plugin.ts +8 -9
- package/src/plugins/presentForm/types.ts +0 -24
- package/src/plugins/presentHtml/Preview.vue +1 -8
- package/src/plugins/presentHtml/View.vue +401 -30
- package/src/plugins/presentHtml/definition.ts +8 -5
- package/src/plugins/presentHtml/index.ts +15 -8
- package/src/plugins/presentHtml/meta.ts +14 -0
- package/src/plugins/presentMulmoScript/View.vue +327 -107
- package/src/plugins/presentMulmoScript/definition.ts +34 -7
- package/src/plugins/presentMulmoScript/helpers.ts +4 -5
- package/src/plugins/presentMulmoScript/index.ts +20 -7
- package/src/plugins/presentMulmoScript/meta.ts +52 -0
- package/src/plugins/scheduler/AutomationsPreview.vue +2 -8
- package/src/plugins/scheduler/Preview.vue +5 -2
- package/src/plugins/scheduler/TasksTab.vue +16 -36
- package/src/plugins/scheduler/View.vue +22 -54
- package/src/plugins/scheduler/automationsDefinition.ts +14 -9
- package/src/plugins/scheduler/automationsMeta.ts +5 -0
- package/src/plugins/scheduler/calendarDefinition.ts +4 -7
- package/src/plugins/scheduler/calendarMeta.ts +28 -0
- package/src/plugins/scheduler/formatSchedule.ts +6 -24
- package/src/plugins/scheduler/index.ts +26 -52
- package/src/plugins/scope.ts +57 -0
- package/src/plugins/server-bindings-types.ts +38 -0
- package/src/plugins/server.ts +32 -0
- package/src/plugins/skill/Preview.vue +25 -0
- package/src/plugins/skill/View.vue +125 -0
- package/src/plugins/skill/definition.ts +23 -0
- package/src/plugins/skill/index.ts +36 -0
- package/src/plugins/skill/plugin.ts +31 -0
- package/src/plugins/skill/types.ts +21 -0
- package/src/plugins/spreadsheet/Preview.vue +1 -3
- package/src/plugins/spreadsheet/View.vue +29 -49
- package/src/plugins/spreadsheet/cellHighlights.ts +2 -3
- package/src/plugins/spreadsheet/definition.ts +5 -2
- package/src/plugins/spreadsheet/index.ts +15 -8
- package/src/plugins/spreadsheet/keyboardNav.ts +38 -0
- package/src/plugins/spreadsheet/meta.ts +14 -0
- package/src/plugins/textResponse/Preview.vue +9 -1
- package/src/plugins/textResponse/View.vue +59 -8
- package/src/plugins/textResponse/index.ts +11 -3
- package/src/plugins/textResponse/plugin.ts +8 -10
- package/src/plugins/textResponse/types.ts +28 -0
- package/src/plugins/wiki/Preview.vue +6 -4
- package/src/plugins/wiki/View.vue +463 -254
- package/src/plugins/wiki/components/WikiPageBody.vue +159 -0
- package/src/plugins/wiki/helpers.ts +17 -0
- package/src/plugins/wiki/history/HistoryDetail.vue +325 -0
- package/src/plugins/wiki/history/HistoryTab.vue +167 -0
- package/src/plugins/wiki/history/RestoreConfirm.vue +63 -0
- package/src/plugins/wiki/history/api.ts +52 -0
- package/src/plugins/wiki/history/diff.ts +145 -0
- package/src/plugins/wiki/index.ts +42 -32
- package/src/plugins/wiki/meta.ts +10 -0
- package/src/plugins/wiki/pageEditLoader.ts +53 -0
- package/src/plugins/wiki/route.ts +8 -0
- package/src/router/guards.ts +2 -1
- package/src/router/index.ts +19 -0
- package/src/router/pageRoutes.ts +1 -0
- package/src/tools/index.ts +50 -51
- package/src/tools/runtimeLoader.ts +141 -0
- package/src/tools/types.ts +44 -1
- package/src/types/notification.ts +23 -0
- package/src/types/pastedFile.ts +10 -0
- package/src/types/session.ts +61 -3
- package/src/types/sse.ts +21 -6
- package/src/utils/agent/eventDispatch.ts +12 -9
- package/src/utils/agent/pastedAttachment.ts +35 -0
- package/src/utils/agent/request.ts +32 -3
- package/src/utils/agent/toolCalls.ts +7 -1
- package/src/utils/api.ts +1 -1
- package/src/utils/chat/exportMarkdown.ts +243 -0
- package/src/utils/errors.ts +10 -2
- package/src/utils/files/expandedDirs.ts +1 -1
- package/src/utils/filesPreview/todoPreview.ts +13 -2
- package/src/utils/format/date.ts +1 -3
- package/src/utils/format/jsonSyntax.ts +5 -0
- package/src/utils/html/iframeHeightReporterScript.ts +62 -0
- package/src/utils/html/previewCsp.ts +29 -2
- package/src/utils/image/htmlSrcAttrs.ts +122 -0
- package/src/utils/image/imageRepairInlineScript.ts +115 -0
- package/src/utils/image/resolve.ts +17 -3
- package/src/utils/image/rewriteMarkdownImageRefs.ts +62 -9
- package/src/utils/markdown/frontmatter.ts +125 -0
- package/src/utils/markdown/taskList.ts +7 -2
- package/src/utils/plugin/runtime.ts +132 -0
- package/src/utils/session/mergeSessions.ts +40 -37
- package/src/utils/session/sessionEntries.ts +74 -18
- package/src/utils/session/sessionHelpers.ts +54 -10
- package/src/utils/tools/result.ts +76 -14
- package/src/vite-env.d.ts +6 -0
- package/client/assets/html2canvas-Cx501zZr-Bug0qRNv.js +0 -5
- package/client/assets/index-CY-WpQUm.css +0 -2
- package/client/assets/index-DbTz2Mfs.js +0 -4911
- package/client/assets/material-symbols-outlined-NzYEeyps.woff2 +0 -0
- package/server/api/routes/html.ts +0 -114
- package/server/api/routes/todos.ts +0 -293
- package/server/api/routes/todosColumnsHandlers.ts +0 -333
- package/server/api/routes/todosHandlers.ts +0 -274
- package/server/api/routes/todosItemsHandlers.ts +0 -386
- package/server/utils/files/todos-io.ts +0 -29
- package/src/components/NotificationToast.vue +0 -75
- package/src/plugins/editImage/definition.ts +0 -27
- package/src/plugins/editImage/index.ts +0 -37
- package/src/plugins/presentHtml/helpers.ts +0 -72
- package/src/plugins/scheduler/LegacySchedulerView.vue +0 -32
- package/src/plugins/scheduler/legacyShape.ts +0 -34
- package/src/plugins/todo/Preview.vue +0 -68
- package/src/plugins/todo/View.vue +0 -378
- package/src/plugins/todo/composables/useTodos.ts +0 -179
- package/src/plugins/todo/definition.ts +0 -45
- package/src/plugins/todo/index.ts +0 -62
- package/src/plugins/todo/labels.ts +0 -163
- package/src/plugins/todo/priority.ts +0 -98
- package/src/plugins/todo/viewModes.ts +0 -19
- package/src/plugins/wiki/definition.ts +0 -25
- package/src/tools/legacyPluginNames.ts +0 -13
- package/src/utils/format/frontmatter.ts +0 -80
- package/src/utils/image/rewriteHtmlImageRefs.ts +0 -50
- package/src/utils/notification/dispatch.ts +0 -58
- /package/client/assets/{purify.es-Fx1Nqyry-BwJECkqS.js → purify.es-Fx1Nqyry-BSVNht6S.js} +0 -0
- /package/src/plugins/{editImage → editImages}/Preview.vue +0 -0
- /package/src/plugins/{editImage → editImages}/View.vue +0 -0
- /package/src/{config/schedulerActions.ts → plugins/scheduler/actions.ts} +0 -0
|
Binary file
|
|
@@ -1,114 +0,0 @@
|
|
|
1
|
-
import { Router, Request, Response } from "express";
|
|
2
|
-
import { readCurrentHtml, writeCurrentHtml } from "../../utils/files/html-io.js";
|
|
3
|
-
import { getGeminiClient, isGeminiAvailable } from "../../utils/gemini.js";
|
|
4
|
-
import { errorMessage } from "../../utils/errors.js";
|
|
5
|
-
import { API_ROUTES } from "../../../src/config/apiRoutes.js";
|
|
6
|
-
import { log } from "../../system/logger/index.js";
|
|
7
|
-
import { promptMeta } from "../../utils/promptMeta.js";
|
|
8
|
-
|
|
9
|
-
const router = Router();
|
|
10
|
-
|
|
11
|
-
async function callGemini(prompt: string): Promise<string> {
|
|
12
|
-
const client = getGeminiClient();
|
|
13
|
-
const response = await client.models.generateContent({
|
|
14
|
-
model: "gemini-2.0-flash",
|
|
15
|
-
contents: [{ text: prompt }],
|
|
16
|
-
});
|
|
17
|
-
const text = response.candidates?.[0]?.content?.parts?.[0]?.text ?? "";
|
|
18
|
-
// Strip markdown code fences if present
|
|
19
|
-
return text
|
|
20
|
-
.replace(/^```html\n?/, "")
|
|
21
|
-
.replace(/^```\n?/, "")
|
|
22
|
-
.replace(/\n?```$/, "")
|
|
23
|
-
.trim();
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
interface HtmlPromptBody {
|
|
27
|
-
prompt: string;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
interface HtmlSuccessResponse {
|
|
31
|
-
message: string;
|
|
32
|
-
instructions?: string;
|
|
33
|
-
title?: string;
|
|
34
|
-
data?: { html: string; type: string };
|
|
35
|
-
updating?: boolean;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
interface HtmlErrorResponse {
|
|
39
|
-
message: string;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
type HtmlResponse = HtmlSuccessResponse | HtmlErrorResponse;
|
|
43
|
-
|
|
44
|
-
router.post(API_ROUTES.html.generate, async (req: Request<object, unknown, HtmlPromptBody>, res: Response<HtmlResponse>) => {
|
|
45
|
-
const { prompt } = req.body;
|
|
46
|
-
log.info("html", "generate: start", { prompt: typeof prompt === "string" ? promptMeta(prompt) : undefined });
|
|
47
|
-
if (!prompt) {
|
|
48
|
-
log.warn("html", "generate: missing prompt");
|
|
49
|
-
res.status(400).json({ message: "prompt is required" });
|
|
50
|
-
return;
|
|
51
|
-
}
|
|
52
|
-
if (!isGeminiAvailable()) {
|
|
53
|
-
log.warn("html", "generate: GEMINI_API_KEY not set");
|
|
54
|
-
res.status(500).json({ message: "GEMINI_API_KEY is not set" });
|
|
55
|
-
return;
|
|
56
|
-
}
|
|
57
|
-
try {
|
|
58
|
-
const fullPrompt = `Generate a complete, standalone HTML page based on this description: ${prompt}\n\nRequirements:\n- Self-contained with all CSS and JS inline\n- Use Tailwind CSS via CDN if needed\n- Return only the HTML code, no explanation`;
|
|
59
|
-
const html = await callGemini(fullPrompt);
|
|
60
|
-
|
|
61
|
-
await writeCurrentHtml(html);
|
|
62
|
-
log.info("html", "generate: ok", { bytes: html.length });
|
|
63
|
-
res.json({
|
|
64
|
-
message: "HTML generation succeeded",
|
|
65
|
-
instructions: "Acknowledge that the HTML was generated and has been presented to the user.",
|
|
66
|
-
title: prompt.slice(0, 50),
|
|
67
|
-
data: { html, type: "tailwind" },
|
|
68
|
-
});
|
|
69
|
-
} catch (err) {
|
|
70
|
-
log.error("html", "generate: threw", { error: errorMessage(err), prompt: promptMeta(prompt) });
|
|
71
|
-
res.status(500).json({ message: errorMessage(err) });
|
|
72
|
-
}
|
|
73
|
-
});
|
|
74
|
-
|
|
75
|
-
router.post(API_ROUTES.html.edit, async (req: Request<object, unknown, HtmlPromptBody>, res: Response<HtmlResponse>) => {
|
|
76
|
-
const { prompt } = req.body;
|
|
77
|
-
log.info("html", "edit: start", { prompt: typeof prompt === "string" ? promptMeta(prompt) : undefined });
|
|
78
|
-
if (!prompt) {
|
|
79
|
-
log.warn("html", "edit: missing prompt");
|
|
80
|
-
res.status(400).json({ message: "prompt is required" });
|
|
81
|
-
return;
|
|
82
|
-
}
|
|
83
|
-
if (!isGeminiAvailable()) {
|
|
84
|
-
log.warn("html", "edit: GEMINI_API_KEY not set");
|
|
85
|
-
res.status(500).json({ message: "GEMINI_API_KEY is not set" });
|
|
86
|
-
return;
|
|
87
|
-
}
|
|
88
|
-
try {
|
|
89
|
-
const existingHtml = await readCurrentHtml();
|
|
90
|
-
if (!existingHtml?.trim()) {
|
|
91
|
-
log.warn("html", "edit: no existing HTML to modify");
|
|
92
|
-
res.status(400).json({
|
|
93
|
-
message: "No HTML page has been generated yet. Use generateHtml first.",
|
|
94
|
-
});
|
|
95
|
-
return;
|
|
96
|
-
}
|
|
97
|
-
const fullPrompt = `Modify the following HTML page based on this instruction: ${prompt}\n\nExisting HTML:\n${existingHtml}\n\nRequirements:\n- Return only the complete modified HTML, no explanation`;
|
|
98
|
-
const html = await callGemini(fullPrompt);
|
|
99
|
-
await writeCurrentHtml(html);
|
|
100
|
-
log.info("html", "edit: ok", { bytes: html.length });
|
|
101
|
-
res.json({
|
|
102
|
-
message: "HTML editing succeeded",
|
|
103
|
-
instructions: "Acknowledge that the HTML was modified and has been presented to the user.",
|
|
104
|
-
title: prompt.slice(0, 50),
|
|
105
|
-
data: { html, type: "tailwind" },
|
|
106
|
-
updating: true,
|
|
107
|
-
});
|
|
108
|
-
} catch (err) {
|
|
109
|
-
log.error("html", "edit: threw", { error: errorMessage(err), prompt: promptMeta(prompt) });
|
|
110
|
-
res.status(500).json({ message: errorMessage(err) });
|
|
111
|
-
}
|
|
112
|
-
});
|
|
113
|
-
|
|
114
|
-
export default router;
|
|
@@ -1,293 +0,0 @@
|
|
|
1
|
-
import { Router, Request, Response } from "express";
|
|
2
|
-
import {
|
|
3
|
-
loadTodos as loadTodosRaw,
|
|
4
|
-
saveTodos as saveTodosRaw,
|
|
5
|
-
loadColumns as loadColumnsRaw,
|
|
6
|
-
saveColumns as saveColumnsRaw,
|
|
7
|
-
} from "../../utils/files/todos-io.js";
|
|
8
|
-
import { dispatchTodos, type TodosActionInput } from "./todosHandlers.js";
|
|
9
|
-
import {
|
|
10
|
-
type StatusColumn,
|
|
11
|
-
DEFAULT_COLUMNS,
|
|
12
|
-
handleAddColumn,
|
|
13
|
-
handleDeleteColumn,
|
|
14
|
-
handlePatchColumn,
|
|
15
|
-
handleReorderColumns,
|
|
16
|
-
normalizeColumns,
|
|
17
|
-
} from "./todosColumnsHandlers.js";
|
|
18
|
-
import {
|
|
19
|
-
handleCreate,
|
|
20
|
-
handleDeleteItem,
|
|
21
|
-
handleMove,
|
|
22
|
-
handlePatch,
|
|
23
|
-
migrateItems,
|
|
24
|
-
type CreateInput,
|
|
25
|
-
type MoveInput,
|
|
26
|
-
type PatchInput,
|
|
27
|
-
} from "./todosItemsHandlers.js";
|
|
28
|
-
import { respondWithDispatchResult, type DispatchSuccessResponse, type DispatchErrorResponse } from "./dispatchResponse.js";
|
|
29
|
-
|
|
30
|
-
import { API_ROUTES } from "../../../src/config/apiRoutes.js";
|
|
31
|
-
import { log } from "../../system/logger/index.js";
|
|
32
|
-
import { previewSnippet } from "../../utils/logPreview.js";
|
|
33
|
-
|
|
34
|
-
const router = Router();
|
|
35
|
-
|
|
36
|
-
export type TodoPriority = "low" | "medium" | "high" | "urgent";
|
|
37
|
-
|
|
38
|
-
export interface TodoItem {
|
|
39
|
-
id: string;
|
|
40
|
-
text: string;
|
|
41
|
-
note?: string;
|
|
42
|
-
labels?: string[];
|
|
43
|
-
completed: boolean;
|
|
44
|
-
createdAt: number;
|
|
45
|
-
// ── Added for the file-explorer kanban view ──
|
|
46
|
-
// status: id of a column from columns.json. Optional on the wire so
|
|
47
|
-
// legacy items load cleanly; migrateTodos() backfills it on read.
|
|
48
|
-
status?: string;
|
|
49
|
-
priority?: TodoPriority;
|
|
50
|
-
dueDate?: string; // ISO YYYY-MM-DD
|
|
51
|
-
order?: number; // sort key within the same status column
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
function loadColumns(): StatusColumn[] {
|
|
55
|
-
return normalizeColumns(loadColumnsRaw<unknown>(DEFAULT_COLUMNS));
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
function saveColumns(columns: StatusColumn[]): void {
|
|
59
|
-
saveColumnsRaw(columns);
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
function loadTodos(): TodoItem[] {
|
|
63
|
-
const raw = loadTodosRaw<TodoItem[]>([]);
|
|
64
|
-
const columns = loadColumns();
|
|
65
|
-
return migrateItems(raw, columns);
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
function saveTodos(items: TodoItem[]): void {
|
|
69
|
-
saveTodosRaw(items);
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
// ── GET /api/todos ───────────────────────────────────────────────
|
|
73
|
-
//
|
|
74
|
-
// Returns the migrated items + the current status columns. The
|
|
75
|
-
// columns field is new; existing chat-side consumers only read
|
|
76
|
-
// `data.items` so adding a sibling key is non-breaking.
|
|
77
|
-
|
|
78
|
-
interface TodosListResponse {
|
|
79
|
-
data: { items: TodoItem[]; columns: StatusColumn[] };
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
router.get(API_ROUTES.todos.list, (_req: Request, res: Response<TodosListResponse>) => {
|
|
83
|
-
res.json({ data: { items: loadTodos(), columns: loadColumns() } });
|
|
84
|
-
});
|
|
85
|
-
|
|
86
|
-
// ── POST /api/todos (legacy MCP action route) ────────────────────
|
|
87
|
-
//
|
|
88
|
-
// Uses the shared dispatcher response plumbing introduced in #145.
|
|
89
|
-
// The legacy MCP `manageTodoList` tool is the only consumer of this
|
|
90
|
-
// route — the file-explorer TodoExplorer calls the new id-based REST
|
|
91
|
-
// routes below instead — so the response shape stays the simple
|
|
92
|
-
// `{ data: { items } }` form. Columns aren't included here on purpose:
|
|
93
|
-
// the chat-side View.vue only reads `data.items`, and the explorer
|
|
94
|
-
// loads columns via GET /api/todos.
|
|
95
|
-
|
|
96
|
-
interface TodoBody extends TodosActionInput {
|
|
97
|
-
action: string;
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
// Actions whose handlers may mutate state. "show" / "list_labels"
|
|
101
|
-
// are read-only views; persisting their result would be a no-op.
|
|
102
|
-
const READ_ONLY_ACTIONS = new Set(["show", "list_labels"]);
|
|
103
|
-
|
|
104
|
-
router.post(API_ROUTES.todos.dispatch, (req: Request<object, unknown, TodoBody>, res: Response<DispatchSuccessResponse<TodoItem> | DispatchErrorResponse>) => {
|
|
105
|
-
const { action, ...input } = req.body;
|
|
106
|
-
log.info("todos", "POST dispatch: start", { action: previewSnippet(action) });
|
|
107
|
-
const items = loadTodos();
|
|
108
|
-
const result = dispatchTodos(action, items, input);
|
|
109
|
-
if (result.kind === "error") {
|
|
110
|
-
log.warn("todos", "POST dispatch: error", { action: previewSnippet(action), error: result.error });
|
|
111
|
-
}
|
|
112
|
-
respondWithDispatchResult(res, result, {
|
|
113
|
-
shouldPersist: !READ_ONLY_ACTIONS.has(action),
|
|
114
|
-
instructions: "Display the updated todo list to the user.",
|
|
115
|
-
persist: saveTodos,
|
|
116
|
-
});
|
|
117
|
-
});
|
|
118
|
-
|
|
119
|
-
// ── New REST routes for the file-explorer todo view ──────────────
|
|
120
|
-
//
|
|
121
|
-
// These are id-based and used exclusively by the web UI. They live
|
|
122
|
-
// alongside the legacy MCP action route so the LLM-facing contract
|
|
123
|
-
// stays unchanged.
|
|
124
|
-
|
|
125
|
-
interface ItemResponse {
|
|
126
|
-
data: { items: TodoItem[]; columns: StatusColumn[] };
|
|
127
|
-
item?: TodoItem;
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
interface ItemIdParams {
|
|
131
|
-
id: string;
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
interface ColumnIdParams {
|
|
135
|
-
id: string;
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
// POST /api/todos/items — create a new todo
|
|
139
|
-
router.post(API_ROUTES.todos.items, (req: Request<object, unknown, CreateInput>, res: Response<ItemResponse | DispatchErrorResponse>) => {
|
|
140
|
-
log.info("todos", "POST item: start");
|
|
141
|
-
const items = loadTodos();
|
|
142
|
-
const columns = loadColumns();
|
|
143
|
-
const result = handleCreate(items, columns, req.body);
|
|
144
|
-
if (result.kind === "error") {
|
|
145
|
-
log.warn("todos", "POST item: error", { error: result.error });
|
|
146
|
-
res.status(result.status).json({ error: result.error });
|
|
147
|
-
return;
|
|
148
|
-
}
|
|
149
|
-
saveTodos(result.items);
|
|
150
|
-
log.info("todos", "POST item: ok", { itemId: result.item?.id, total: result.items.length });
|
|
151
|
-
res.json({
|
|
152
|
-
data: { items: result.items, columns },
|
|
153
|
-
...(result.item && { item: result.item }),
|
|
154
|
-
});
|
|
155
|
-
});
|
|
156
|
-
|
|
157
|
-
// PATCH /api/todos/items/:id — partial update
|
|
158
|
-
router.patch(API_ROUTES.todos.item, (req: Request<ItemIdParams, unknown, PatchInput>, res: Response<ItemResponse | DispatchErrorResponse>) => {
|
|
159
|
-
log.info("todos", "PATCH item: start", { itemId: req.params.id });
|
|
160
|
-
const items = loadTodos();
|
|
161
|
-
const columns = loadColumns();
|
|
162
|
-
const result = handlePatch(items, columns, req.params.id, req.body);
|
|
163
|
-
if (result.kind === "error") {
|
|
164
|
-
log.warn("todos", "PATCH item: error", { itemId: req.params.id, error: result.error });
|
|
165
|
-
res.status(result.status).json({ error: result.error });
|
|
166
|
-
return;
|
|
167
|
-
}
|
|
168
|
-
saveTodos(result.items);
|
|
169
|
-
log.info("todos", "PATCH item: ok", { itemId: req.params.id });
|
|
170
|
-
res.json({
|
|
171
|
-
data: { items: result.items, columns },
|
|
172
|
-
...(result.item && { item: result.item }),
|
|
173
|
-
});
|
|
174
|
-
});
|
|
175
|
-
|
|
176
|
-
// POST /api/todos/items/:id/move — drag & drop persistence
|
|
177
|
-
router.post(API_ROUTES.todos.itemMove, (req: Request<ItemIdParams, unknown, MoveInput>, res: Response<ItemResponse | DispatchErrorResponse>) => {
|
|
178
|
-
log.info("todos", "POST item-move: start", { itemId: req.params.id });
|
|
179
|
-
const items = loadTodos();
|
|
180
|
-
const columns = loadColumns();
|
|
181
|
-
const result = handleMove(items, columns, req.params.id, req.body);
|
|
182
|
-
if (result.kind === "error") {
|
|
183
|
-
log.warn("todos", "POST item-move: error", { itemId: req.params.id, error: result.error });
|
|
184
|
-
res.status(result.status).json({ error: result.error });
|
|
185
|
-
return;
|
|
186
|
-
}
|
|
187
|
-
saveTodos(result.items);
|
|
188
|
-
log.info("todos", "POST item-move: ok", { itemId: req.params.id });
|
|
189
|
-
res.json({
|
|
190
|
-
data: { items: result.items, columns },
|
|
191
|
-
...(result.item && { item: result.item }),
|
|
192
|
-
});
|
|
193
|
-
});
|
|
194
|
-
|
|
195
|
-
// DELETE /api/todos/items/:id
|
|
196
|
-
router.delete(API_ROUTES.todos.item, (req: Request<ItemIdParams>, res: Response<ItemResponse | DispatchErrorResponse>) => {
|
|
197
|
-
log.info("todos", "DELETE item: start", { itemId: req.params.id });
|
|
198
|
-
const items = loadTodos();
|
|
199
|
-
const columns = loadColumns();
|
|
200
|
-
const result = handleDeleteItem(items, req.params.id);
|
|
201
|
-
if (result.kind === "error") {
|
|
202
|
-
log.warn("todos", "DELETE item: error", { itemId: req.params.id, error: result.error });
|
|
203
|
-
res.status(result.status).json({ error: result.error });
|
|
204
|
-
return;
|
|
205
|
-
}
|
|
206
|
-
saveTodos(result.items);
|
|
207
|
-
log.info("todos", "DELETE item: ok", { itemId: req.params.id, remaining: result.items.length });
|
|
208
|
-
res.json({ data: { items: result.items, columns } });
|
|
209
|
-
});
|
|
210
|
-
|
|
211
|
-
// ── Columns ──────────────────────────────────────────────────────
|
|
212
|
-
|
|
213
|
-
interface ColumnsResponse {
|
|
214
|
-
data: { items: TodoItem[]; columns: StatusColumn[] };
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
interface AddColumnBody {
|
|
218
|
-
label?: string;
|
|
219
|
-
isDone?: boolean;
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
interface PatchColumnBody {
|
|
223
|
-
label?: string;
|
|
224
|
-
isDone?: boolean;
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
interface ReorderColumnsBody {
|
|
228
|
-
ids?: string[];
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
router.get(API_ROUTES.todos.columns, (_req: Request, res: Response<ColumnsResponse>) => {
|
|
232
|
-
res.json({ data: { items: loadTodos(), columns: loadColumns() } });
|
|
233
|
-
});
|
|
234
|
-
|
|
235
|
-
router.post(API_ROUTES.todos.columns, (req: Request<object, unknown, AddColumnBody>, res: Response<ColumnsResponse | DispatchErrorResponse>) => {
|
|
236
|
-
log.info("todos", "POST column: start");
|
|
237
|
-
const items = loadTodos();
|
|
238
|
-
const result = handleAddColumn(loadColumns(), items, req.body);
|
|
239
|
-
if (result.kind === "error") {
|
|
240
|
-
log.warn("todos", "POST column: error", { error: result.error });
|
|
241
|
-
res.status(result.status).json({ error: result.error });
|
|
242
|
-
return;
|
|
243
|
-
}
|
|
244
|
-
saveColumns(result.columns);
|
|
245
|
-
if (result.items) saveTodos(result.items);
|
|
246
|
-
log.info("todos", "POST column: ok", { columns: result.columns.length });
|
|
247
|
-
res.json({ data: { items: loadTodos(), columns: result.columns } });
|
|
248
|
-
});
|
|
249
|
-
|
|
250
|
-
router.patch(API_ROUTES.todos.column, (req: Request<ColumnIdParams, unknown, PatchColumnBody>, res: Response<ColumnsResponse | DispatchErrorResponse>) => {
|
|
251
|
-
log.info("todos", "PATCH column: start", { columnId: req.params.id });
|
|
252
|
-
const items = loadTodos();
|
|
253
|
-
const result = handlePatchColumn(loadColumns(), req.params.id, req.body, items);
|
|
254
|
-
if (result.kind === "error") {
|
|
255
|
-
log.warn("todos", "PATCH column: error", { columnId: req.params.id, error: result.error });
|
|
256
|
-
res.status(result.status).json({ error: result.error });
|
|
257
|
-
return;
|
|
258
|
-
}
|
|
259
|
-
saveColumns(result.columns);
|
|
260
|
-
if (result.items) saveTodos(result.items);
|
|
261
|
-
log.info("todos", "PATCH column: ok", { columnId: req.params.id });
|
|
262
|
-
res.json({ data: { items: loadTodos(), columns: result.columns } });
|
|
263
|
-
});
|
|
264
|
-
|
|
265
|
-
router.delete(API_ROUTES.todos.column, (req: Request<ColumnIdParams>, res: Response<ColumnsResponse | DispatchErrorResponse>) => {
|
|
266
|
-
log.info("todos", "DELETE column: start", { columnId: req.params.id });
|
|
267
|
-
const items = loadTodos();
|
|
268
|
-
const result = handleDeleteColumn(loadColumns(), req.params.id, items);
|
|
269
|
-
if (result.kind === "error") {
|
|
270
|
-
log.warn("todos", "DELETE column: error", { columnId: req.params.id, error: result.error });
|
|
271
|
-
res.status(result.status).json({ error: result.error });
|
|
272
|
-
return;
|
|
273
|
-
}
|
|
274
|
-
saveColumns(result.columns);
|
|
275
|
-
if (result.items) saveTodos(result.items);
|
|
276
|
-
log.info("todos", "DELETE column: ok", { columnId: req.params.id, remaining: result.columns.length });
|
|
277
|
-
res.json({ data: { items: loadTodos(), columns: result.columns } });
|
|
278
|
-
});
|
|
279
|
-
|
|
280
|
-
router.put(API_ROUTES.todos.columnsOrder, (req: Request<object, unknown, ReorderColumnsBody>, res: Response<ColumnsResponse | DispatchErrorResponse>) => {
|
|
281
|
-
log.info("todos", "PUT columns-order: start", { count: req.body.ids?.length ?? 0 });
|
|
282
|
-
const result = handleReorderColumns(loadColumns(), req.body.ids ?? []);
|
|
283
|
-
if (result.kind === "error") {
|
|
284
|
-
log.warn("todos", "PUT columns-order: error", { error: result.error });
|
|
285
|
-
res.status(result.status).json({ error: result.error });
|
|
286
|
-
return;
|
|
287
|
-
}
|
|
288
|
-
saveColumns(result.columns);
|
|
289
|
-
log.info("todos", "PUT columns-order: ok", { columns: result.columns.length });
|
|
290
|
-
res.json({ data: { items: loadTodos(), columns: result.columns } });
|
|
291
|
-
});
|
|
292
|
-
|
|
293
|
-
export default router;
|