zyflow 0.6.4
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/.claude-flow/metrics/agent-metrics.json +1 -0
- package/.claude-flow/metrics/performance.json +87 -0
- package/.claude-flow/metrics/system-metrics.json +4370 -0
- package/.claude-flow/metrics/task-metrics.json +10 -0
- package/.claude-plugin/marketplace.json +18 -0
- package/.claude-plugin/plugin.json +17 -0
- package/.gitleaks.toml +69 -0
- package/.hive-mind/config/queens.json +59 -0
- package/.hive-mind/config/workers.json +72 -0
- package/.hive-mind/config.json +111 -0
- package/.hive-mind/hive.db +0 -0
- package/.hive-mind/hive.db-shm +0 -0
- package/.hive-mind/hive.db-wal +0 -0
- package/.leann/indexes/zyflow/documents.ids.txt +2078 -0
- package/.leann/indexes/zyflow/documents.index +0 -0
- package/.leann/indexes/zyflow/documents.leann.meta.json +25 -0
- package/.leann/indexes/zyflow/documents.leann.passages.idx +0 -0
- package/.leann/indexes/zyflow/documents.leann.passages.jsonl +2078 -0
- package/.mcp.json +41 -0
- package/.moai-backups/20260126_231508/.mcp.json +11 -0
- package/.moai-backups/20260126_231508/backup_metadata.json +34 -0
- package/.moai-backups/20260129_145438/.mcp.json +41 -0
- package/.moai-backups/20260129_145438/backup_metadata.json +53 -0
- package/.moai-backups/20260129_145504/.mcp.json +41 -0
- package/.moai-backups/20260129_145504/backup_metadata.json +20 -0
- package/.moai-backups/20260201_140004/.mcp.json +41 -0
- package/.moai-backups/20260201_140004/backup_metadata.json +51 -0
- package/.moai-backups/backup/.mcp.json +12 -0
- package/.moai-backups/settings-backup/settings.local.json +61 -0
- package/.pre-commit-config.yaml +74 -0
- package/.prettierignore +3 -0
- package/.prettierrc +7 -0
- package/.scannerwork/.sonar_lock +0 -0
- package/.scannerwork/report-task.txt +6 -0
- package/.serena/project.yml +105 -0
- package/.shadcn-admin-ref/.env.example +1 -0
- package/.shadcn-admin-ref/.prettierignore +18 -0
- package/.shadcn-admin-ref/.prettierrc +50 -0
- package/.shadcn-admin-ref/LICENSE +21 -0
- package/.shadcn-admin-ref/components.json +21 -0
- package/.shadcn-admin-ref/cz.yaml +7 -0
- package/.shadcn-admin-ref/eslint.config.js +59 -0
- package/.shadcn-admin-ref/index.html +80 -0
- package/.shadcn-admin-ref/knip.config.ts +8 -0
- package/.shadcn-admin-ref/netlify.toml +4 -0
- package/.shadcn-admin-ref/package.json +83 -0
- package/.shadcn-admin-ref/public/images/favicon.png +0 -0
- package/.shadcn-admin-ref/public/images/favicon.svg +4 -0
- package/.shadcn-admin-ref/public/images/favicon_light.png +0 -0
- package/.shadcn-admin-ref/public/images/favicon_light.svg +1 -0
- package/.shadcn-admin-ref/public/images/shadcn-admin.png +0 -0
- package/.shadcn-admin-ref/src/assets/brand-icons/icon-discord.tsx +28 -0
- package/.shadcn-admin-ref/src/assets/brand-icons/icon-docker.tsx +33 -0
- package/.shadcn-admin-ref/src/assets/brand-icons/icon-facebook.tsx +25 -0
- package/.shadcn-admin-ref/src/assets/brand-icons/icon-figma.tsx +27 -0
- package/.shadcn-admin-ref/src/assets/brand-icons/icon-github.tsx +25 -0
- package/.shadcn-admin-ref/src/assets/brand-icons/icon-gitlab.tsx +25 -0
- package/.shadcn-admin-ref/src/assets/brand-icons/icon-gmail.tsx +28 -0
- package/.shadcn-admin-ref/src/assets/brand-icons/icon-medium.tsx +30 -0
- package/.shadcn-admin-ref/src/assets/brand-icons/icon-notion.tsx +28 -0
- package/.shadcn-admin-ref/src/assets/brand-icons/icon-skype.tsx +26 -0
- package/.shadcn-admin-ref/src/assets/brand-icons/icon-slack.tsx +28 -0
- package/.shadcn-admin-ref/src/assets/brand-icons/icon-stripe.tsx +25 -0
- package/.shadcn-admin-ref/src/assets/brand-icons/icon-telegram.tsx +25 -0
- package/.shadcn-admin-ref/src/assets/brand-icons/icon-trello.tsx +27 -0
- package/.shadcn-admin-ref/src/assets/brand-icons/icon-whatsapp.tsx +26 -0
- package/.shadcn-admin-ref/src/assets/brand-icons/icon-zoom.tsx +26 -0
- package/.shadcn-admin-ref/src/assets/brand-icons/index.ts +16 -0
- package/.shadcn-admin-ref/src/assets/clerk-full-logo.tsx +41 -0
- package/.shadcn-admin-ref/src/assets/clerk-logo.tsx +23 -0
- package/.shadcn-admin-ref/src/assets/custom/icon-dir.tsx +110 -0
- package/.shadcn-admin-ref/src/assets/custom/icon-layout-compact.tsx +131 -0
- package/.shadcn-admin-ref/src/assets/custom/icon-layout-default.tsx +124 -0
- package/.shadcn-admin-ref/src/assets/custom/icon-layout-full.tsx +100 -0
- package/.shadcn-admin-ref/src/assets/custom/icon-sidebar-floating.tsx +82 -0
- package/.shadcn-admin-ref/src/assets/custom/icon-sidebar-inset.tsx +58 -0
- package/.shadcn-admin-ref/src/assets/custom/icon-sidebar-sidebar.tsx +53 -0
- package/.shadcn-admin-ref/src/assets/custom/icon-theme-dark.tsx +79 -0
- package/.shadcn-admin-ref/src/assets/custom/icon-theme-light.tsx +78 -0
- package/.shadcn-admin-ref/src/assets/custom/icon-theme-system.tsx +116 -0
- package/.shadcn-admin-ref/src/assets/logo.tsx +24 -0
- package/.shadcn-admin-ref/src/components/coming-soon.tsx +16 -0
- package/.shadcn-admin-ref/src/components/command-menu.tsx +91 -0
- package/.shadcn-admin-ref/src/components/config-drawer.tsx +354 -0
- package/.shadcn-admin-ref/src/components/confirm-dialog.tsx +67 -0
- package/.shadcn-admin-ref/src/components/data-table/bulk-actions.tsx +213 -0
- package/.shadcn-admin-ref/src/components/data-table/column-header.tsx +74 -0
- package/.shadcn-admin-ref/src/components/data-table/faceted-filter.tsx +146 -0
- package/.shadcn-admin-ref/src/components/data-table/index.ts +6 -0
- package/.shadcn-admin-ref/src/components/data-table/pagination.tsx +130 -0
- package/.shadcn-admin-ref/src/components/data-table/toolbar.tsx +85 -0
- package/.shadcn-admin-ref/src/components/data-table/view-options.tsx +56 -0
- package/.shadcn-admin-ref/src/components/date-picker.tsx +51 -0
- package/.shadcn-admin-ref/src/components/layout/app-sidebar.tsx +37 -0
- package/.shadcn-admin-ref/src/components/layout/app-title.tsx +64 -0
- package/.shadcn-admin-ref/src/components/layout/authenticated-layout.tsx +42 -0
- package/.shadcn-admin-ref/src/components/layout/data/sidebar-data.ts +205 -0
- package/.shadcn-admin-ref/src/components/layout/header.tsx +50 -0
- package/.shadcn-admin-ref/src/components/layout/main.tsx +27 -0
- package/.shadcn-admin-ref/src/components/layout/nav-group.tsx +185 -0
- package/.shadcn-admin-ref/src/components/layout/nav-user.tsx +124 -0
- package/.shadcn-admin-ref/src/components/layout/team-switcher.tsx +86 -0
- package/.shadcn-admin-ref/src/components/layout/top-nav.tsx +67 -0
- package/.shadcn-admin-ref/src/components/layout/types.ts +44 -0
- package/.shadcn-admin-ref/src/components/learn-more.tsx +44 -0
- package/.shadcn-admin-ref/src/components/long-text.tsx +84 -0
- package/.shadcn-admin-ref/src/components/navigation-progress.tsx +25 -0
- package/.shadcn-admin-ref/src/components/password-input.tsx +42 -0
- package/.shadcn-admin-ref/src/components/profile-dropdown.tsx +75 -0
- package/.shadcn-admin-ref/src/components/search.tsx +37 -0
- package/.shadcn-admin-ref/src/components/select-dropdown.tsx +62 -0
- package/.shadcn-admin-ref/src/components/sign-out-dialog.tsx +38 -0
- package/.shadcn-admin-ref/src/components/skip-to-main.tsx +10 -0
- package/.shadcn-admin-ref/src/components/theme-switch.tsx +58 -0
- package/.shadcn-admin-ref/src/components/ui/alert-dialog.tsx +154 -0
- package/.shadcn-admin-ref/src/components/ui/alert.tsx +65 -0
- package/.shadcn-admin-ref/src/components/ui/avatar.tsx +50 -0
- package/.shadcn-admin-ref/src/components/ui/badge.tsx +45 -0
- package/.shadcn-admin-ref/src/components/ui/button.tsx +58 -0
- package/.shadcn-admin-ref/src/components/ui/calendar.tsx +210 -0
- package/.shadcn-admin-ref/src/components/ui/card.tsx +91 -0
- package/.shadcn-admin-ref/src/components/ui/checkbox.tsx +29 -0
- package/.shadcn-admin-ref/src/components/ui/collapsible.tsx +31 -0
- package/.shadcn-admin-ref/src/components/ui/command.tsx +181 -0
- package/.shadcn-admin-ref/src/components/ui/dialog.tsx +142 -0
- package/.shadcn-admin-ref/src/components/ui/dropdown-menu.tsx +254 -0
- package/.shadcn-admin-ref/src/components/ui/form.tsx +164 -0
- package/.shadcn-admin-ref/src/components/ui/input-otp.tsx +74 -0
- package/.shadcn-admin-ref/src/components/ui/input.tsx +20 -0
- package/.shadcn-admin-ref/src/components/ui/label.tsx +23 -0
- package/.shadcn-admin-ref/src/components/ui/popover.tsx +45 -0
- package/.shadcn-admin-ref/src/components/ui/radio-group.tsx +42 -0
- package/.shadcn-admin-ref/src/components/ui/scroll-area.tsx +65 -0
- package/.shadcn-admin-ref/src/components/ui/select.tsx +182 -0
- package/.shadcn-admin-ref/src/components/ui/separator.tsx +25 -0
- package/.shadcn-admin-ref/src/components/ui/sheet.tsx +136 -0
- package/.shadcn-admin-ref/src/components/ui/sidebar.tsx +728 -0
- package/.shadcn-admin-ref/src/components/ui/skeleton.tsx +13 -0
- package/.shadcn-admin-ref/src/components/ui/sonner.tsx +21 -0
- package/.shadcn-admin-ref/src/components/ui/switch.tsx +28 -0
- package/.shadcn-admin-ref/src/components/ui/table.tsx +113 -0
- package/.shadcn-admin-ref/src/components/ui/tabs.tsx +63 -0
- package/.shadcn-admin-ref/src/components/ui/textarea.tsx +17 -0
- package/.shadcn-admin-ref/src/components/ui/tooltip.tsx +60 -0
- package/.shadcn-admin-ref/src/config/fonts.ts +19 -0
- package/.shadcn-admin-ref/src/context/direction-provider.tsx +61 -0
- package/.shadcn-admin-ref/src/context/font-provider.tsx +58 -0
- package/.shadcn-admin-ref/src/context/layout-provider.tsx +85 -0
- package/.shadcn-admin-ref/src/context/search-provider.tsx +46 -0
- package/.shadcn-admin-ref/src/context/theme-provider.tsx +110 -0
- package/.shadcn-admin-ref/src/features/apps/data/apps.tsx +110 -0
- package/.shadcn-admin-ref/src/features/apps/index.tsx +179 -0
- package/.shadcn-admin-ref/src/features/auth/auth-layout.tsx +19 -0
- package/.shadcn-admin-ref/src/features/auth/forgot-password/components/forgot-password-form.tsx +82 -0
- package/.shadcn-admin-ref/src/features/auth/forgot-password/index.tsx +44 -0
- package/.shadcn-admin-ref/src/features/auth/otp/components/otp-form.tsx +100 -0
- package/.shadcn-admin-ref/src/features/auth/otp/index.tsx +44 -0
- package/.shadcn-admin-ref/src/features/auth/sign-in/assets/dashboard-dark.png +0 -0
- package/.shadcn-admin-ref/src/features/auth/sign-in/assets/dashboard-light.png +0 -0
- package/.shadcn-admin-ref/src/features/auth/sign-in/components/user-auth-form.tsx +150 -0
- package/.shadcn-admin-ref/src/features/auth/sign-in/index.tsx +51 -0
- package/.shadcn-admin-ref/src/features/auth/sign-in/sign-in-2.tsx +69 -0
- package/.shadcn-admin-ref/src/features/auth/sign-up/components/sign-up-form.tsx +143 -0
- package/.shadcn-admin-ref/src/features/auth/sign-up/index.tsx +57 -0
- package/.shadcn-admin-ref/src/features/chats/components/new-chat.tsx +127 -0
- package/.shadcn-admin-ref/src/features/chats/data/chat-types.ts +4 -0
- package/.shadcn-admin-ref/src/features/chats/data/convo.json +309 -0
- package/.shadcn-admin-ref/src/features/chats/index.tsx +349 -0
- package/.shadcn-admin-ref/src/features/dashboard/components/analytics-chart.tsx +77 -0
- package/.shadcn-admin-ref/src/features/dashboard/components/analytics.tsx +189 -0
- package/.shadcn-admin-ref/src/features/dashboard/components/overview.tsx +82 -0
- package/.shadcn-admin-ref/src/features/dashboard/components/recent-sales.tsx +83 -0
- package/.shadcn-admin-ref/src/features/dashboard/index.tsx +220 -0
- package/.shadcn-admin-ref/src/features/errors/forbidden.tsx +25 -0
- package/.shadcn-admin-ref/src/features/errors/general-error.tsx +36 -0
- package/.shadcn-admin-ref/src/features/errors/maintenance-error.tsx +19 -0
- package/.shadcn-admin-ref/src/features/errors/not-found-error.tsx +25 -0
- package/.shadcn-admin-ref/src/features/errors/unauthorized-error.tsx +25 -0
- package/.shadcn-admin-ref/src/features/settings/account/account-form.tsx +173 -0
- package/.shadcn-admin-ref/src/features/settings/account/index.tsx +14 -0
- package/.shadcn-admin-ref/src/features/settings/appearance/appearance-form.tsx +162 -0
- package/.shadcn-admin-ref/src/features/settings/appearance/index.tsx +14 -0
- package/.shadcn-admin-ref/src/features/settings/components/content-section.tsx +22 -0
- package/.shadcn-admin-ref/src/features/settings/components/sidebar-nav.tsx +84 -0
- package/.shadcn-admin-ref/src/features/settings/display/display-form.tsx +121 -0
- package/.shadcn-admin-ref/src/features/settings/display/index.tsx +13 -0
- package/.shadcn-admin-ref/src/features/settings/index.tsx +74 -0
- package/.shadcn-admin-ref/src/features/settings/notifications/index.tsx +13 -0
- package/.shadcn-admin-ref/src/features/settings/notifications/notifications-form.tsx +220 -0
- package/.shadcn-admin-ref/src/features/settings/profile/index.tsx +13 -0
- package/.shadcn-admin-ref/src/features/settings/profile/profile-form.tsx +177 -0
- package/.shadcn-admin-ref/src/features/tasks/components/data-table-bulk-actions.tsx +193 -0
- package/.shadcn-admin-ref/src/features/tasks/components/data-table-row-actions.tsx +83 -0
- package/.shadcn-admin-ref/src/features/tasks/components/tasks-columns.tsx +123 -0
- package/.shadcn-admin-ref/src/features/tasks/components/tasks-dialogs.tsx +72 -0
- package/.shadcn-admin-ref/src/features/tasks/components/tasks-import-dialog.tsx +110 -0
- package/.shadcn-admin-ref/src/features/tasks/components/tasks-multi-delete-dialog.tsx +95 -0
- package/.shadcn-admin-ref/src/features/tasks/components/tasks-mutate-drawer.tsx +212 -0
- package/.shadcn-admin-ref/src/features/tasks/components/tasks-primary-buttons.tsx +21 -0
- package/.shadcn-admin-ref/src/features/tasks/components/tasks-provider.tsx +36 -0
- package/.shadcn-admin-ref/src/features/tasks/components/tasks-table.tsx +197 -0
- package/.shadcn-admin-ref/src/features/tasks/data/data.tsx +77 -0
- package/.shadcn-admin-ref/src/features/tasks/data/schema.ts +13 -0
- package/.shadcn-admin-ref/src/features/tasks/data/tasks.ts +29 -0
- package/.shadcn-admin-ref/src/features/tasks/index.tsx +41 -0
- package/.shadcn-admin-ref/src/features/users/components/data-table-bulk-actions.tsx +139 -0
- package/.shadcn-admin-ref/src/features/users/components/data-table-row-actions.tsx +63 -0
- package/.shadcn-admin-ref/src/features/users/components/users-action-dialog.tsx +326 -0
- package/.shadcn-admin-ref/src/features/users/components/users-columns.tsx +138 -0
- package/.shadcn-admin-ref/src/features/users/components/users-delete-dialog.tsx +81 -0
- package/.shadcn-admin-ref/src/features/users/components/users-dialogs.tsx +51 -0
- package/.shadcn-admin-ref/src/features/users/components/users-invite-dialog.tsx +150 -0
- package/.shadcn-admin-ref/src/features/users/components/users-multi-delete-dialog.tsx +95 -0
- package/.shadcn-admin-ref/src/features/users/components/users-primary-buttons.tsx +21 -0
- package/.shadcn-admin-ref/src/features/users/components/users-provider.tsx +36 -0
- package/.shadcn-admin-ref/src/features/users/components/users-table.tsx +194 -0
- package/.shadcn-admin-ref/src/features/users/data/data.ts +35 -0
- package/.shadcn-admin-ref/src/features/users/data/schema.ts +32 -0
- package/.shadcn-admin-ref/src/features/users/data/users.ts +33 -0
- package/.shadcn-admin-ref/src/features/users/index.tsx +47 -0
- package/.shadcn-admin-ref/src/hooks/use-dialog-state.tsx +18 -0
- package/.shadcn-admin-ref/src/hooks/use-mobile.tsx +19 -0
- package/.shadcn-admin-ref/src/hooks/use-table-url-state.ts +219 -0
- package/.shadcn-admin-ref/src/lib/cookies.ts +43 -0
- package/.shadcn-admin-ref/src/lib/handle-server-error.ts +24 -0
- package/.shadcn-admin-ref/src/lib/show-submitted-data.tsx +15 -0
- package/.shadcn-admin-ref/src/lib/utils.ts +60 -0
- package/.shadcn-admin-ref/src/main.tsx +107 -0
- package/.shadcn-admin-ref/src/routeTree.gen.ts +719 -0
- package/.shadcn-admin-ref/src/routes/(auth)/forgot-password.tsx +6 -0
- package/.shadcn-admin-ref/src/routes/(auth)/otp.tsx +6 -0
- package/.shadcn-admin-ref/src/routes/(auth)/sign-in-2.tsx +6 -0
- package/.shadcn-admin-ref/src/routes/(auth)/sign-in.tsx +12 -0
- package/.shadcn-admin-ref/src/routes/(auth)/sign-up.tsx +6 -0
- package/.shadcn-admin-ref/src/routes/(errors)/401.tsx +6 -0
- package/.shadcn-admin-ref/src/routes/(errors)/403.tsx +6 -0
- package/.shadcn-admin-ref/src/routes/(errors)/404.tsx +6 -0
- package/.shadcn-admin-ref/src/routes/(errors)/500.tsx +6 -0
- package/.shadcn-admin-ref/src/routes/(errors)/503.tsx +6 -0
- package/.shadcn-admin-ref/src/routes/__root.tsx +30 -0
- package/.shadcn-admin-ref/src/routes/_authenticated/apps/index.tsx +17 -0
- package/.shadcn-admin-ref/src/routes/_authenticated/chats/index.tsx +6 -0
- package/.shadcn-admin-ref/src/routes/_authenticated/errors/$error.tsx +45 -0
- package/.shadcn-admin-ref/src/routes/_authenticated/help-center/index.tsx +6 -0
- package/.shadcn-admin-ref/src/routes/_authenticated/index.tsx +6 -0
- package/.shadcn-admin-ref/src/routes/_authenticated/route.tsx +6 -0
- package/.shadcn-admin-ref/src/routes/_authenticated/settings/account.tsx +6 -0
- package/.shadcn-admin-ref/src/routes/_authenticated/settings/appearance.tsx +6 -0
- package/.shadcn-admin-ref/src/routes/_authenticated/settings/display.tsx +6 -0
- package/.shadcn-admin-ref/src/routes/_authenticated/settings/index.tsx +6 -0
- package/.shadcn-admin-ref/src/routes/_authenticated/settings/notifications.tsx +6 -0
- package/.shadcn-admin-ref/src/routes/_authenticated/settings/route.tsx +6 -0
- package/.shadcn-admin-ref/src/routes/_authenticated/tasks/index.tsx +23 -0
- package/.shadcn-admin-ref/src/routes/_authenticated/users/index.tsx +32 -0
- package/.shadcn-admin-ref/src/routes/clerk/(auth)/route.tsx +60 -0
- package/.shadcn-admin-ref/src/routes/clerk/(auth)/sign-in.tsx +14 -0
- package/.shadcn-admin-ref/src/routes/clerk/(auth)/sign-up.tsx +9 -0
- package/.shadcn-admin-ref/src/routes/clerk/_authenticated/route.tsx +6 -0
- package/.shadcn-admin-ref/src/routes/clerk/_authenticated/user-management.tsx +184 -0
- package/.shadcn-admin-ref/src/routes/clerk/route.tsx +135 -0
- package/.shadcn-admin-ref/src/stores/auth-store.ts +53 -0
- package/.shadcn-admin-ref/src/styles/index.css +87 -0
- package/.shadcn-admin-ref/src/styles/theme.css +102 -0
- package/.shadcn-admin-ref/src/tanstack-table.d.ts +10 -0
- package/.shadcn-admin-ref/src/vite-env.d.ts +1 -0
- package/.swarm/memory.db +0 -0
- package/.swarm/memory.db-shm +0 -0
- package/.swarm/memory.db-wal +0 -0
- package/.zyflow/cli-settings.json +30 -0
- package/.zyflow/db.sqlite +0 -0
- package/.zyflow/logs/add-gitdiagram-integration/1633-1765491505852.json +10 -0
- package/.zyflow/logs/add-gitdiagram-integration/1633-1765491622627.json +10 -0
- package/.zyflow/logs/add-gitdiagram-integration/1633-1765491794652.json +10 -0
- package/.zyflow/logs/add-gitdiagram-integration/1633-1765491890392.json +10 -0
- package/.zyflow/logs/add-gitdiagram-integration/1633-1765494002879.json +10 -0
- package/.zyflow/logs/add-gitdiagram-integration/1633-1765494183887.json +10 -0
- package/.zyflow/logs/add-gitdiagram-integration/1633-1765494342052.json +10 -0
- package/.zyflow/logs/add-gitdiagram-integration/1633-1765494387244.json +10 -0
- package/.zyflow/logs/add-gitdiagram-integration/1633-1765494387245.json +10 -0
- package/.zyflow/logs/add-gitdiagram-integration/1633-1765494606176.json +10 -0
- package/.zyflow/logs/add-gitdiagram-integration/1633-1765495967542.json +16 -0
- package/.zyflow/logs/add-gitdiagram-integration/1633-1765495967629.json +16 -0
- package/.zyflow/logs/add-gitdiagram-integration/1633-1765497861143.json +16 -0
- package/.zyflow/logs/add-gitdiagram-integration/1633-1765497861870.json +20 -0
- package/.zyflow/logs/add-gitdiagram-integration/1633-1765498021377.json +18 -0
- package/.zyflow/logs/add-gitdiagram-integration/1633-1765498021660.json +18 -0
- package/.zyflow/logs/add-gitdiagram-integration/1633-1765503255525.json +13 -0
- package/.zyflow/logs/add-gitdiagram-integration/1633-1765503256018.json +13 -0
- package/.zyflow/logs/add-gitdiagram-integration/1633-1765504009102.json +16 -0
- package/.zyflow/logs/add-gitdiagram-integration/1633-1765504492051.json +18 -0
- package/.zyflow/logs/add-gitdiagram-integration/1633-1765504946437.json +16 -0
- package/.zyflow/logs/add-gitdiagram-integration/1633-1765504946640.json +16 -0
- package/.zyflow/logs/add-gitdiagram-integration/1634-1765505950215.json +16 -0
- package/.zyflow/logs/add-gitdiagram-integration/1634-1765505950948.json +18 -0
- package/.zyflow/logs/add-gitdiagram-integration/1635-1765505971712.json +18 -0
- package/.zyflow/logs/add-gitdiagram-integration/1635-1765505971976.json +18 -0
- package/.zyflow/logs/add-gitdiagram-integration/1636-1765505986208.json +18 -0
- package/.zyflow/logs/add-gitdiagram-integration/1636-1765505986620.json +16 -0
- package/.zyflow/logs/integrate-claude-flow/3580-1765996816612.json +10 -0
- package/.zyflow/logs/integrate-claude-flow/3580-1766014825819.json +10 -0
- package/.zyflow/logs/integrate-claude-flow/3580-1766015183794.json +12 -0
- package/.zyflow/logs/integrate-claude-flow/3580-1766015474608.json +12 -0
- package/.zyflow/logs/integrate-claude-flow/3581-1766016502824.json +63 -0
- package/.zyflow/logs/integrate-claude-flow/3581-1766016576008.json +60 -0
- package/.zyflow/logs/integrate-claude-flow/3582-1766022737754.json +110 -0
- package/.zyflow/logs/integrate-claude-flow/3582-1766022809327.json +135 -0
- package/.zyflow/sessions.json +242 -0
- package/.zyflow/settings.json +6 -0
- package/.zyflow/tasks.db +0 -0
- package/.zyflow/tasks.db-shm +0 -0
- package/.zyflow/tasks.db-wal +0 -0
- package/.zyflow/zyflow.sqlite +0 -0
- package/Dockerfile +82 -0
- package/LICENSE +21 -0
- package/README.md +506 -0
- package/claude-flow +34 -0
- package/components.json +21 -0
- package/config/ports.ts +28 -0
- package/docker-compose.yml +52 -0
- package/eslint.config.js +34 -0
- package/index.html +19 -0
- package/logs/mcp-error.log +55 -0
- package/logs/mcp-out.log +0 -0
- package/logs/pm2-error.log +0 -0
- package/logs/pm2-out.log +265 -0
- package/logs/py-error.log +22 -0
- package/logs/py-out.log +0 -0
- package/logs/server-error.log +11000 -0
- package/logs/server-out.log +8117 -0
- package/logs/vite-error.log +404 -0
- package/logs/vite-out.log +311 -0
- package/mcp-server/agent-tools.ts +375 -0
- package/mcp-server/cli-models.ts +193 -0
- package/mcp-server/context.ts +110 -0
- package/mcp-server/diagram-tools.ts +341 -0
- package/mcp-server/index.ts +2014 -0
- package/mcp-server/integration-tools.ts +909 -0
- package/mcp-server/moai-spec-tools.ts +416 -0
- package/mcp-server/parser.ts +422 -0
- package/mcp-server/post-task-runner.ts +253 -0
- package/mcp-server/post-task-types.ts +426 -0
- package/mcp-server/quarantine-manager.ts +479 -0
- package/mcp-server/report-generator.ts +386 -0
- package/mcp-server/task-tools.ts +619 -0
- package/mcp-server/trigger-config.ts +288 -0
- package/mcp-server/trigger-router.ts +305 -0
- package/mcp-server/triggers/event-listener.ts +331 -0
- package/mcp-server/triggers/git-hooks.ts +283 -0
- package/mcp-server/triggers/scheduler.ts +289 -0
- package/mcp-server/types.ts +55 -0
- package/memory/claude-flow@alpha-data.json +5 -0
- package/nginx/zyflow.conf +144 -0
- package/openspec/config.yaml +78 -0
- package/openspec-backup.tar.gz +0 -0
- package/package.json +154 -0
- package/packages/gitdiagram-core/.claude-flow/metrics/agent-metrics.json +1 -0
- package/packages/gitdiagram-core/.claude-flow/metrics/performance.json +87 -0
- package/packages/gitdiagram-core/.claude-flow/metrics/task-metrics.json +10 -0
- package/packages/gitdiagram-core/package.json +41 -0
- package/packages/gitdiagram-core/src/file-tree.ts +272 -0
- package/packages/gitdiagram-core/src/generator.ts +283 -0
- package/packages/gitdiagram-core/src/index.ts +78 -0
- package/packages/gitdiagram-core/src/llm-adapter.ts +235 -0
- package/packages/gitdiagram-core/src/mermaid-utils.ts +304 -0
- package/packages/gitdiagram-core/src/prompts.ts +281 -0
- package/packages/zyflow-parser/package.json +34 -0
- package/packages/zyflow-parser/src/index.ts +26 -0
- package/packages/zyflow-parser/src/moai-parser.ts +603 -0
- package/packages/zyflow-parser/src/moai-types.ts +110 -0
- package/packages/zyflow-remote-plugin/.claude-flow/metrics/agent-metrics.json +1 -0
- package/packages/zyflow-remote-plugin/.claude-flow/metrics/performance.json +87 -0
- package/packages/zyflow-remote-plugin/.claude-flow/metrics/task-metrics.json +10 -0
- package/packages/zyflow-remote-plugin/package.json +31 -0
- package/packages/zyflow-remote-plugin/src/index.ts +71 -0
- package/packages/zyflow-remote-plugin/src/remote-config.ts +232 -0
- package/packages/zyflow-remote-plugin/src/router.ts +535 -0
- package/packages/zyflow-remote-plugin/src/ssh-config-parser.ts +123 -0
- package/packages/zyflow-remote-plugin/src/ssh-manager.ts +598 -0
- package/packages/zyflow-remote-plugin/src/types.ts +149 -0
- package/plugin/manifest.json +26 -0
- package/plugin/package.json +13 -0
- package/public/favicon.svg +4 -0
- package/server/adk/agents/error-analyzer.ts +223 -0
- package/server/adk/agents/fix-generator.ts +187 -0
- package/server/adk/agents/pr-agent.ts +264 -0
- package/server/adk/agents/validator.ts +187 -0
- package/server/adk/config.ts +43 -0
- package/server/adk/index.ts +69 -0
- package/server/adk/integration.ts +297 -0
- package/server/adk/orchestrator.ts +405 -0
- package/server/adk/tools/build-tools.ts +290 -0
- package/server/adk/tools/file-tools.ts +351 -0
- package/server/adk/tools/git-tools.ts +280 -0
- package/server/adk/tools/github-tools.ts +249 -0
- package/server/agents/agent-monitor.ts +416 -0
- package/server/agents/alert-integration.ts +312 -0
- package/server/agents/error-analyzer.ts +472 -0
- package/server/agents/error-detector.ts +442 -0
- package/server/agents/fix-generator.ts +421 -0
- package/server/agents/fix-validator.ts +428 -0
- package/server/agents/merge-policy.ts +362 -0
- package/server/agents/pr-workflow.ts +476 -0
- package/server/agents/prompts/error-analysis.ts +393 -0
- package/server/ai/gemini-client.ts +499 -0
- package/server/ai/index.ts +317 -0
- package/server/ai/types.ts +137 -0
- package/server/app.ts +3693 -0
- package/server/archive-manager.ts +604 -0
- package/server/backlog/index.ts +7 -0
- package/server/backlog/migration.ts +331 -0
- package/server/backlog/parser.ts +323 -0
- package/server/backlog/sync.ts +325 -0
- package/server/change-log.ts +868 -0
- package/server/claude-flow/index.ts +12 -0
- package/server/claude-flow/prompt-builder.ts +407 -0
- package/server/claude-flow/types.ts +33 -0
- package/server/cli-adapter/index.ts +11 -0
- package/server/cli-adapter/process-manager.ts +612 -0
- package/server/cli-adapter/profile-manager.ts +286 -0
- package/server/cli-adapter/routes.ts +561 -0
- package/server/cli-adapter/types.ts +226 -0
- package/server/config.d.ts +18 -0
- package/server/config.js +79 -0
- package/server/config.ts +262 -0
- package/server/flow-sync.ts +543 -0
- package/server/git/change-workflow.ts +446 -0
- package/server/git/commands.ts +370 -0
- package/server/git/github.ts +247 -0
- package/server/git/index.ts +1202 -0
- package/server/git/status.ts +322 -0
- package/server/index.ts +136 -0
- package/server/integrations/crypto.ts +142 -0
- package/server/integrations/db/client.ts +169 -0
- package/server/integrations/db/schema.ts +167 -0
- package/server/integrations/env-parser.ts +365 -0
- package/server/integrations/index.ts +101 -0
- package/server/integrations/keychain.ts +239 -0
- package/server/integrations/local/file-utils.ts +383 -0
- package/server/integrations/local/index.ts +64 -0
- package/server/integrations/local/resolver.ts +439 -0
- package/server/integrations/local/types.ts +122 -0
- package/server/integrations/routes.ts +1100 -0
- package/server/integrations/service-patterns.ts +771 -0
- package/server/integrations/services/accounts.ts +356 -0
- package/server/integrations/services/env-import.ts +279 -0
- package/server/integrations/services/projects.ts +552 -0
- package/server/integrations/services/system-import.ts +1110 -0
- package/server/migrations/ears-generator.ts +491 -0
- package/server/migrations/gherkin-generator.ts +605 -0
- package/server/migrations/index.ts +73 -0
- package/server/migrations/migrate-spec-format.ts +492 -0
- package/server/migrations/openspec-parser.ts +542 -0
- package/server/migrations/tag-generator.ts +474 -0
- package/server/moai-specs.ts +487 -0
- package/server/moai-watcher.ts +145 -0
- package/server/parser-debug.ts +37 -0
- package/server/parser-utils.ts +316 -0
- package/server/parser.d.ts +17 -0
- package/server/parser.js +221 -0
- package/server/parser.ts +342 -0
- package/server/remote-watcher.ts +367 -0
- package/server/replay-engine.ts +915 -0
- package/server/routes/alerts.ts +1028 -0
- package/server/routes/changes.ts +812 -0
- package/server/routes/docs.ts +898 -0
- package/server/routes/flow.ts +2814 -0
- package/server/routes/global-chat.ts +162 -0
- package/server/routes/leann.ts +327 -0
- package/server/routes/projects.ts +1282 -0
- package/server/routes/search.ts +266 -0
- package/server/routes/specs.ts +482 -0
- package/server/routes/webhooks.ts +579 -0
- package/server/server/parser.js +265 -0
- package/server/services/githubActionsPoller.ts +797 -0
- package/server/services/slackNotifier.ts +476 -0
- package/server/src/types/index.js +1 -0
- package/server/sync-tasks.ts +741 -0
- package/server/tasks/cli/commands.ts +269 -0
- package/server/tasks/cli/index.ts +152 -0
- package/server/tasks/core/search.ts +81 -0
- package/server/tasks/core/task.ts +307 -0
- package/server/tasks/db/client.ts +1008 -0
- package/server/tasks/db/schema.ts +572 -0
- package/server/tasks/index.ts +24 -0
- package/server/tasks.db +0 -0
- package/server/types/archive.ts +136 -0
- package/server/types/change-log.ts +643 -0
- package/server/types/spec.ts +188 -0
- package/server/unified-spec-scanner.ts +753 -0
- package/server/utils/crypto.ts +179 -0
- package/server/utils/webhook-verify.ts +216 -0
- package/server/watcher.ts +132 -0
- package/server/websocket.ts +99 -0
- package/server-output.log +6 -0
- package/sonar-project.properties +18 -0
- package/src/App.tsx +386 -0
- package/src/api/client.ts +346 -0
- package/src/api/error-interceptor.ts +366 -0
- package/src/api/errors.ts +123 -0
- package/src/api/flow.ts +233 -0
- package/src/api/offline-queue.ts +351 -0
- package/src/api/retry-logic.ts +233 -0
- package/src/components/OfflineModeBanner.tsx +159 -0
- package/src/components/SSEStatusIndicator.tsx +194 -0
- package/src/components/agent/AgentChat.tsx +243 -0
- package/src/components/agent/AgentPage.tsx +182 -0
- package/src/components/agent/AgentSidebar.tsx +231 -0
- package/src/components/agent/index.ts +7 -0
- package/src/components/alerts/AlertCenter.tsx +239 -0
- package/src/components/alerts/AlertDashboard.tsx +211 -0
- package/src/components/alerts/AlertDetail.tsx +474 -0
- package/src/components/alerts/AlertList.tsx +113 -0
- package/src/components/alerts/AlertSettings.tsx +336 -0
- package/src/components/alerts/index.ts +5 -0
- package/src/components/chat/ChatPanel.tsx +642 -0
- package/src/components/chat/index.ts +1 -0
- package/src/components/cli/AddCustomCLIDialog.tsx +210 -0
- package/src/components/cli/CLISelector.tsx +187 -0
- package/src/components/cli/index.ts +8 -0
- package/src/components/dashboard/ArchivedChangeList.tsx +102 -0
- package/src/components/dashboard/ArchivedChangeViewer.tsx +184 -0
- package/src/components/dashboard/ArchivedChangesPage.tsx +31 -0
- package/src/components/dashboard/ChangeList.tsx +86 -0
- package/src/components/dashboard/ThemeToggle.tsx +33 -0
- package/src/components/diagram/DiagramViewer.tsx +256 -0
- package/src/components/diagram/MermaidRenderer.tsx +163 -0
- package/src/components/diagram/ProjectDiagramTab.tsx +161 -0
- package/src/components/diagram/index.ts +13 -0
- package/src/components/errors/ErrorBoundary.tsx +276 -0
- package/src/components/errors/ErrorFallback.tsx +198 -0
- package/src/components/errors/ErrorToast.tsx +221 -0
- package/src/components/flow/BacklogView.tsx +1142 -0
- package/src/components/flow/ChangeDetail.tsx +475 -0
- package/src/components/flow/ChangeItem.tsx +230 -0
- package/src/components/flow/ChangeList.tsx +92 -0
- package/src/components/flow/ExecutionHistoryDialog.tsx +224 -0
- package/src/components/flow/FlowContent.tsx +212 -0
- package/src/components/flow/FlowPage.tsx +9 -0
- package/src/components/flow/PipelineBar.tsx +214 -0
- package/src/components/flow/ProjectDashboard.tsx +222 -0
- package/src/components/flow/SpecDetail.tsx +138 -0
- package/src/components/flow/SpecDetailTabs.tsx +176 -0
- package/src/components/flow/SpecItem.tsx +93 -0
- package/src/components/flow/SpecProgressBar.tsx +47 -0
- package/src/components/flow/StageContent.tsx +620 -0
- package/src/components/flow/StandaloneTasks.tsx +960 -0
- package/src/components/flow/TaskExecutionDialog.tsx +1204 -0
- package/src/components/flow/index.ts +9 -0
- package/src/components/flow/task-execution/AgentSlider.tsx +37 -0
- package/src/components/flow/task-execution/ConsensusSettings.tsx +129 -0
- package/src/components/flow/task-execution/ExecutionOutput.tsx +398 -0
- package/src/components/flow/task-execution/ModelSelector.tsx +134 -0
- package/src/components/flow/task-execution/ProviderSelector.tsx +137 -0
- package/src/components/flow/task-execution/RecommendationBanner.tsx +71 -0
- package/src/components/flow/task-execution/StatusBadge.tsx +43 -0
- package/src/components/flow/task-execution/StrategySelector.tsx +48 -0
- package/src/components/flow/task-execution/SwarmSummary.tsx +55 -0
- package/src/components/flow/task-execution/index.ts +14 -0
- package/src/components/flow/task-execution/types.ts +56 -0
- package/src/components/git/ChangeWorkflowDialog.tsx +582 -0
- package/src/components/git/ConflictResolutionDialog.tsx +398 -0
- package/src/components/git/GitBranchSelector.tsx +212 -0
- package/src/components/git/GitCommitDialog.tsx +254 -0
- package/src/components/git/GitStatusBadge.tsx +148 -0
- package/src/components/git/GitSyncButton.tsx +128 -0
- package/src/components/git/RemoteStatusBanner.tsx +143 -0
- package/src/components/git/index.ts +9 -0
- package/src/components/integrations/EnvImportDialog.tsx +524 -0
- package/src/components/integrations/EnvironmentDialog.tsx +227 -0
- package/src/components/integrations/IntegrationBadges.tsx +91 -0
- package/src/components/integrations/IntegrationsSettings.tsx +55 -0
- package/src/components/integrations/ProjectIntegrations.tsx +481 -0
- package/src/components/integrations/ServiceAccountDialog.tsx +422 -0
- package/src/components/integrations/ServiceAccountList.tsx +305 -0
- package/src/components/integrations/SystemImportDialog.tsx +436 -0
- package/src/components/integrations/TestAccountDialog.tsx +162 -0
- package/src/components/integrations/index.ts +6 -0
- package/src/components/layout/AppSidebar.tsx +284 -0
- package/src/components/layout/FlowSidebar.tsx +435 -0
- package/src/components/layout/GlobalCommandPalette.tsx +410 -0
- package/src/components/layout/MenuBar.tsx +227 -0
- package/src/components/layout/StatusBar.tsx +226 -0
- package/src/components/monitoring/ErrorDashboard.tsx +274 -0
- package/src/components/monitoring/ErrorDetailPanel.tsx +200 -0
- package/src/components/monitoring/ErrorFilters.tsx +219 -0
- package/src/components/monitoring/ErrorHistoryList.tsx +141 -0
- package/src/components/monitoring/ErrorStats.tsx +249 -0
- package/src/components/remote/RemoteFileBrowser.tsx +249 -0
- package/src/components/remote/RemoteServerDialog.tsx +234 -0
- package/src/components/remote/RemoteServerList.tsx +366 -0
- package/src/components/remote/index.ts +7 -0
- package/src/components/settings/CLISettings.tsx +522 -0
- package/src/components/settings/CustomCLIDialog.tsx +548 -0
- package/src/components/settings/IntegrationsSettings.tsx +51 -0
- package/src/components/settings/ProjectSettings.tsx +441 -0
- package/src/components/settings/ProjectsSettings.tsx +541 -0
- package/src/components/settings/SearchSettings.tsx +272 -0
- package/src/components/settings/SettingsPage.tsx +68 -0
- package/src/components/settings/index.ts +5 -0
- package/src/components/swarm/ExecutionPanel.tsx +284 -0
- package/src/components/swarm/LogViewer.tsx +196 -0
- package/src/components/swarm/ProgressIndicator.tsx +111 -0
- package/src/components/swarm/index.ts +3 -0
- package/src/components/tasks/ArchiveTable.tsx +203 -0
- package/src/components/tasks/KanbanBoard.tsx +264 -0
- package/src/components/tasks/TaskCard.tsx +138 -0
- package/src/components/tasks/TaskColumn.tsx +81 -0
- package/src/components/tasks/TaskDialog.tsx +274 -0
- package/src/components/tasks/index.ts +5 -0
- package/src/components/tasks/types.ts +43 -0
- package/src/components/ui/alert-dialog.tsx +154 -0
- package/src/components/ui/alert.tsx +65 -0
- package/src/components/ui/badge.tsx +45 -0
- package/src/components/ui/button.tsx +58 -0
- package/src/components/ui/card.tsx +91 -0
- package/src/components/ui/checkbox.tsx +29 -0
- package/src/components/ui/collapsible.tsx +31 -0
- package/src/components/ui/command.tsx +184 -0
- package/src/components/ui/confirm-dialog.tsx +55 -0
- package/src/components/ui/dialog.tsx +142 -0
- package/src/components/ui/dropdown-menu.tsx +254 -0
- package/src/components/ui/input.tsx +20 -0
- package/src/components/ui/label.tsx +22 -0
- package/src/components/ui/markdown.tsx +100 -0
- package/src/components/ui/progress.tsx +27 -0
- package/src/components/ui/resizable-sidebar.tsx +156 -0
- package/src/components/ui/resizable.tsx +54 -0
- package/src/components/ui/right-resizable-sidebar.tsx +158 -0
- package/src/components/ui/scroll-area.tsx +64 -0
- package/src/components/ui/select.tsx +185 -0
- package/src/components/ui/separator.tsx +25 -0
- package/src/components/ui/sheet.tsx +136 -0
- package/src/components/ui/sidebar.tsx +726 -0
- package/src/components/ui/skeleton.tsx +13 -0
- package/src/components/ui/slider.tsx +56 -0
- package/src/components/ui/switch.tsx +29 -0
- package/src/components/ui/table.tsx +113 -0
- package/src/components/ui/tabs.tsx +63 -0
- package/src/components/ui/textarea.tsx +17 -0
- package/src/components/ui/tooltip.tsx +60 -0
- package/src/config/api.ts +83 -0
- package/src/constants/error-codes.ts +255 -0
- package/src/constants/stages.ts +27 -0
- package/src/context/ErrorContext.tsx +185 -0
- package/src/context/theme-provider.tsx +63 -0
- package/src/hooks/use-mobile.tsx +19 -0
- package/src/hooks/useAI.ts +206 -0
- package/src/hooks/useAgentSession.ts +431 -0
- package/src/hooks/useAlerts.ts +935 -0
- package/src/hooks/useArchivedChanges.ts +39 -0
- package/src/hooks/useAsyncError.ts +45 -0
- package/src/hooks/useChangeGit.ts +727 -0
- package/src/hooks/useChanges.ts +20 -0
- package/src/hooks/useClaude.ts +130 -0
- package/src/hooks/useDocs.ts +182 -0
- package/src/hooks/useErrorDashboard.ts +243 -0
- package/src/hooks/useErrorHandler.ts +150 -0
- package/src/hooks/useExecutionHistory.ts +55 -0
- package/src/hooks/useFlowChanges.ts +850 -0
- package/src/hooks/useFlowItems.ts +205 -0
- package/src/hooks/useGit.ts +427 -0
- package/src/hooks/useHideCompletedSpecs.ts +15 -0
- package/src/hooks/useInstance.ts +40 -0
- package/src/hooks/useIntegrations.ts +737 -0
- package/src/hooks/useLeannStatus.ts +93 -0
- package/src/hooks/useNetworkStatus.ts +167 -0
- package/src/hooks/useProjects.ts +353 -0
- package/src/hooks/useRemoteServers.ts +383 -0
- package/src/hooks/useSSEConnection.ts +346 -0
- package/src/hooks/useSpecs.ts +39 -0
- package/src/hooks/useSwarm.ts +462 -0
- package/src/hooks/useTasks.ts +137 -0
- package/src/hooks/useURLSync.ts +122 -0
- package/src/hooks/useWebSocket.ts +262 -0
- package/src/lib/utils.ts +121 -0
- package/src/main.tsx +22 -0
- package/src/stores/errorStore.ts +301 -0
- package/src/stores/offlineStore.ts +266 -0
- package/src/stores/sseStore.ts +247 -0
- package/src/stores/useHideCompletedStore.ts +21 -0
- package/src/styles/index.css +87 -0
- package/src/styles/theme.css +102 -0
- package/src/types/ai.ts +191 -0
- package/src/types/errors.ts +253 -0
- package/src/types/flow.ts +382 -0
- package/src/types/index.ts +614 -0
- package/src/utils/error-logger.ts +399 -0
- package/src/utils/error-statistics.ts +305 -0
- package/src/utils/logger.ts +280 -0
- package/src/utils/task-routing.ts +795 -0
- package/src/vite-env.d.ts +1 -0
- package/test-results/.last-run.json +4 -0
- package/tmp/check-docker-final.ts +48 -0
- package/tmp/check-docker-tasks.ts +58 -0
- package/tmp/check-docker-tasks2.ts +48 -0
- package/tmp/check-docker-tasks3.ts +42 -0
- package/tmp/check-mobile-tasks.ts +57 -0
- package/tmp/check-zywiki-tasks.ts +49 -0
- package/tmp/sync-mobile.ts +11 -0
- package/tmp/sync-zywiki.ts +68 -0
- package/tmp/test-docker-parser.ts +15 -0
- package/tmp/test-mobile-parser.ts +28 -0
- package/tmp/test-parser.ts +27 -0
- package/tmp/test-unnumbered.ts +35 -0
- package/zyflow.db +0 -0
|
@@ -0,0 +1,1008 @@
|
|
|
1
|
+
import Database from 'better-sqlite3';
|
|
2
|
+
import { drizzle } from 'drizzle-orm/better-sqlite3';
|
|
3
|
+
import * as schema from './schema.js';
|
|
4
|
+
import { existsSync, mkdirSync } from 'fs';
|
|
5
|
+
import { dirname, join } from 'path';
|
|
6
|
+
import { homedir } from 'os';
|
|
7
|
+
|
|
8
|
+
let db: ReturnType<typeof drizzle<typeof schema>> | null = null;
|
|
9
|
+
let sqlite: Database.Database | null = null;
|
|
10
|
+
let currentDbPath: string | null = null;
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* 틸드(~)를 홈 디렉토리로 확장
|
|
14
|
+
* Node.js는 셸과 달리 ~를 자동으로 확장하지 않음
|
|
15
|
+
*/
|
|
16
|
+
function expandTilde(path: string): string {
|
|
17
|
+
if (path.startsWith('~')) {
|
|
18
|
+
return path.replace(/^~/, homedir())
|
|
19
|
+
}
|
|
20
|
+
return path
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* 중앙 DB 경로 반환
|
|
25
|
+
* - Docker: DATA_DIR 환경변수 사용 (예: /app/data)
|
|
26
|
+
* - Local: ~/.zyflow/tasks.db
|
|
27
|
+
* projectRoot 파라미터는 하위 호환성을 위해 유지하지만 무시됨
|
|
28
|
+
*/
|
|
29
|
+
export function getDbPath(_projectRoot?: string): string {
|
|
30
|
+
const dataDir = process.env.DATA_DIR
|
|
31
|
+
if (dataDir) {
|
|
32
|
+
return join(expandTilde(dataDir), 'tasks.db')
|
|
33
|
+
}
|
|
34
|
+
return join(homedir(), '.zyflow', 'tasks.db')
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export function initDb(_projectRoot?: string): ReturnType<typeof drizzle<typeof schema>> {
|
|
38
|
+
const dbPath = getDbPath();
|
|
39
|
+
|
|
40
|
+
if (db) return db;
|
|
41
|
+
|
|
42
|
+
const dbDir = dirname(dbPath);
|
|
43
|
+
|
|
44
|
+
// Ensure .zyflow directory exists
|
|
45
|
+
if (!existsSync(dbDir)) {
|
|
46
|
+
mkdirSync(dbDir, { recursive: true });
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
sqlite = new Database(dbPath);
|
|
50
|
+
|
|
51
|
+
// Enable WAL mode for better performance
|
|
52
|
+
sqlite.pragma('journal_mode = WAL');
|
|
53
|
+
|
|
54
|
+
// Create sequences table for auto-increment IDs
|
|
55
|
+
sqlite.exec(`
|
|
56
|
+
CREATE TABLE IF NOT EXISTS sequences (
|
|
57
|
+
name TEXT PRIMARY KEY,
|
|
58
|
+
value INTEGER NOT NULL DEFAULT 0
|
|
59
|
+
);
|
|
60
|
+
`);
|
|
61
|
+
|
|
62
|
+
// Initialize origin-based task sequences
|
|
63
|
+
// TAG-014: Removed 'task_openspec' sequence
|
|
64
|
+
sqlite.exec(`
|
|
65
|
+
INSERT OR IGNORE INTO sequences (name, value) VALUES ('task_inbox', 0);
|
|
66
|
+
INSERT OR IGNORE INTO sequences (name, value) VALUES ('task_moai', 0);
|
|
67
|
+
`);
|
|
68
|
+
|
|
69
|
+
// Create tasks table FIRST (before sequences sync that references it)
|
|
70
|
+
sqlite.exec(`
|
|
71
|
+
CREATE TABLE IF NOT EXISTS tasks (
|
|
72
|
+
id INTEGER PRIMARY KEY,
|
|
73
|
+
change_id TEXT,
|
|
74
|
+
stage TEXT NOT NULL DEFAULT 'task' CHECK(stage IN ('spec', 'task', 'code', 'test', 'commit', 'docs')),
|
|
75
|
+
title TEXT NOT NULL,
|
|
76
|
+
description TEXT,
|
|
77
|
+
status TEXT NOT NULL DEFAULT 'todo' CHECK(status IN ('todo', 'in-progress', 'review', 'done', 'archived')),
|
|
78
|
+
priority TEXT NOT NULL DEFAULT 'medium' CHECK(priority IN ('low', 'medium', 'high')),
|
|
79
|
+
tags TEXT,
|
|
80
|
+
assignee TEXT,
|
|
81
|
+
"order" INTEGER NOT NULL DEFAULT 0,
|
|
82
|
+
created_at INTEGER NOT NULL,
|
|
83
|
+
updated_at INTEGER NOT NULL,
|
|
84
|
+
archived_at INTEGER
|
|
85
|
+
);
|
|
86
|
+
`);
|
|
87
|
+
|
|
88
|
+
// NOTE: Sequence sync with origin column is moved after the origin column migration
|
|
89
|
+
// See the sync logic after "Migration: Add origin column" section below
|
|
90
|
+
|
|
91
|
+
// Create changes table (Flow의 최상위 단위)
|
|
92
|
+
// 복합 기본키: (id, project_id) - 같은 change id가 다른 프로젝트에서 사용 가능
|
|
93
|
+
sqlite.exec(`
|
|
94
|
+
CREATE TABLE IF NOT EXISTS changes (
|
|
95
|
+
id TEXT NOT NULL,
|
|
96
|
+
project_id TEXT NOT NULL,
|
|
97
|
+
title TEXT NOT NULL,
|
|
98
|
+
spec_path TEXT,
|
|
99
|
+
status TEXT NOT NULL DEFAULT 'active' CHECK(status IN ('active', 'completed', 'archived')),
|
|
100
|
+
current_stage TEXT NOT NULL DEFAULT 'spec' CHECK(current_stage IN ('spec', 'task', 'code', 'test', 'commit', 'docs')),
|
|
101
|
+
progress INTEGER NOT NULL DEFAULT 0,
|
|
102
|
+
created_at INTEGER NOT NULL,
|
|
103
|
+
updated_at INTEGER NOT NULL,
|
|
104
|
+
archived_at INTEGER,
|
|
105
|
+
PRIMARY KEY (id, project_id)
|
|
106
|
+
);
|
|
107
|
+
`);
|
|
108
|
+
|
|
109
|
+
// Migration: Add archived_at column to changes if it doesn't exist
|
|
110
|
+
try {
|
|
111
|
+
sqlite.exec(`ALTER TABLE changes ADD COLUMN archived_at INTEGER`);
|
|
112
|
+
} catch {
|
|
113
|
+
// Column already exists
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// Migration: Add artifact_status column for OpenSpec 1.0 artifact caching (JSON)
|
|
117
|
+
try {
|
|
118
|
+
sqlite.exec(`ALTER TABLE changes ADD COLUMN artifact_status TEXT`);
|
|
119
|
+
} catch {
|
|
120
|
+
// Column already exists
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// Migration: Add artifact_status_updated_at for cache invalidation
|
|
124
|
+
try {
|
|
125
|
+
sqlite.exec(`ALTER TABLE changes ADD COLUMN artifact_status_updated_at INTEGER`);
|
|
126
|
+
} catch {
|
|
127
|
+
// Column already exists
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// Migration: Convert changes table from single id PK to composite (id, project_id) PK
|
|
131
|
+
try {
|
|
132
|
+
// Check if current table has single id primary key
|
|
133
|
+
const tableInfo = sqlite.prepare("PRAGMA table_info(changes)").all() as Array<{ name: string; pk: number }>;
|
|
134
|
+
const pkColumns = tableInfo.filter(col => col.pk > 0);
|
|
135
|
+
|
|
136
|
+
if (pkColumns.length === 1 && pkColumns[0].name === 'id') {
|
|
137
|
+
console.log('[Migration] Converting changes table to composite primary key (id, project_id)...');
|
|
138
|
+
|
|
139
|
+
sqlite.exec(`
|
|
140
|
+
-- Create new table with composite primary key
|
|
141
|
+
CREATE TABLE changes_new (
|
|
142
|
+
id TEXT NOT NULL,
|
|
143
|
+
project_id TEXT NOT NULL,
|
|
144
|
+
title TEXT NOT NULL,
|
|
145
|
+
spec_path TEXT,
|
|
146
|
+
status TEXT NOT NULL DEFAULT 'active' CHECK(status IN ('active', 'completed', 'archived')),
|
|
147
|
+
current_stage TEXT NOT NULL DEFAULT 'spec' CHECK(current_stage IN ('spec', 'task', 'code', 'test', 'commit', 'docs')),
|
|
148
|
+
progress INTEGER NOT NULL DEFAULT 0,
|
|
149
|
+
created_at INTEGER NOT NULL,
|
|
150
|
+
updated_at INTEGER NOT NULL,
|
|
151
|
+
archived_at INTEGER,
|
|
152
|
+
PRIMARY KEY (id, project_id)
|
|
153
|
+
);
|
|
154
|
+
|
|
155
|
+
-- Copy data from old table
|
|
156
|
+
INSERT OR IGNORE INTO changes_new SELECT id, project_id, title, spec_path, status, current_stage, progress, created_at, updated_at, archived_at FROM changes;
|
|
157
|
+
|
|
158
|
+
-- Drop old table
|
|
159
|
+
DROP TABLE changes;
|
|
160
|
+
|
|
161
|
+
-- Rename new table
|
|
162
|
+
ALTER TABLE changes_new RENAME TO changes;
|
|
163
|
+
|
|
164
|
+
-- Recreate indexes
|
|
165
|
+
CREATE INDEX IF NOT EXISTS idx_changes_project_id ON changes(project_id);
|
|
166
|
+
CREATE INDEX IF NOT EXISTS idx_changes_status ON changes(status);
|
|
167
|
+
CREATE INDEX IF NOT EXISTS idx_changes_project_status ON changes(project_id, status);
|
|
168
|
+
CREATE INDEX IF NOT EXISTS idx_changes_updated_at ON changes(updated_at);
|
|
169
|
+
`);
|
|
170
|
+
|
|
171
|
+
console.log('[Migration] Changes table migration complete');
|
|
172
|
+
}
|
|
173
|
+
} catch (err) {
|
|
174
|
+
console.error('[Migration] Error migrating changes table:', err);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// Migration: Add archived_at column if it doesn't exist
|
|
178
|
+
try {
|
|
179
|
+
sqlite.exec(`ALTER TABLE tasks ADD COLUMN archived_at INTEGER`);
|
|
180
|
+
} catch {
|
|
181
|
+
// Column already exists, ignore
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
// Migration: Add change_id column for Flow integration
|
|
185
|
+
try {
|
|
186
|
+
sqlite.exec(`ALTER TABLE tasks ADD COLUMN change_id TEXT`);
|
|
187
|
+
} catch {
|
|
188
|
+
// Column already exists, ignore
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
// Migration: Add stage column for Flow pipeline
|
|
192
|
+
try {
|
|
193
|
+
sqlite.exec(`ALTER TABLE tasks ADD COLUMN stage TEXT NOT NULL DEFAULT 'task'`);
|
|
194
|
+
} catch {
|
|
195
|
+
// Column already exists, ignore
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
// Migration: Add group_title for tasks.md section grouping
|
|
199
|
+
try {
|
|
200
|
+
sqlite.exec(`ALTER TABLE tasks ADD COLUMN group_title TEXT`);
|
|
201
|
+
} catch {
|
|
202
|
+
// Column already exists, ignore
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
// Migration: Add group_order for section ordering (1, 2, 3...)
|
|
206
|
+
try {
|
|
207
|
+
sqlite.exec(`ALTER TABLE tasks ADD COLUMN group_order INTEGER NOT NULL DEFAULT 0`);
|
|
208
|
+
} catch {
|
|
209
|
+
// Column already exists, ignore
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
// Migration: Add task_order for task ordering within group (1, 2, 3...)
|
|
213
|
+
try {
|
|
214
|
+
sqlite.exec(`ALTER TABLE tasks ADD COLUMN task_order INTEGER NOT NULL DEFAULT 0`);
|
|
215
|
+
} catch {
|
|
216
|
+
// Column already exists, ignore
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
// Migration: Add major_title for 3-level hierarchy (## 1. Section -> major_title)
|
|
220
|
+
try {
|
|
221
|
+
sqlite.exec(`ALTER TABLE tasks ADD COLUMN major_title TEXT`);
|
|
222
|
+
} catch {
|
|
223
|
+
// Column already exists, ignore
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
// Migration: Add sub_order for 3-level hierarchy (### 1.1 -> sub_order = 1)
|
|
227
|
+
try {
|
|
228
|
+
sqlite.exec(`ALTER TABLE tasks ADD COLUMN sub_order INTEGER`);
|
|
229
|
+
} catch {
|
|
230
|
+
// Column already exists, ignore
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
// Migration: Add origin column for task source tracking (openspec/inbox/imported)
|
|
234
|
+
try {
|
|
235
|
+
sqlite.exec(`ALTER TABLE tasks ADD COLUMN origin TEXT NOT NULL DEFAULT 'inbox'`);
|
|
236
|
+
} catch {
|
|
237
|
+
// Column already exists, ignore
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
// Migration: Set origin based on existing data (change_id 유무로 판단)
|
|
241
|
+
// TAG-014: Changed from 'openspec' to 'moai' origin
|
|
242
|
+
try {
|
|
243
|
+
sqlite.exec(`
|
|
244
|
+
UPDATE tasks
|
|
245
|
+
SET origin = 'moai'
|
|
246
|
+
WHERE origin = 'inbox' AND change_id IS NOT NULL AND change_id != ''
|
|
247
|
+
`);
|
|
248
|
+
} catch (e) {
|
|
249
|
+
console.error('Migration warning (origin update):', e);
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
// Sync sequence values with actual max task IDs per origin
|
|
253
|
+
// This runs AFTER the origin column is added to avoid SQL errors
|
|
254
|
+
try {
|
|
255
|
+
sqlite.exec(`
|
|
256
|
+
UPDATE sequences
|
|
257
|
+
SET value = COALESCE((SELECT MAX(id) FROM tasks WHERE origin = 'inbox'), 0)
|
|
258
|
+
WHERE name = 'task_inbox' AND value < COALESCE((SELECT MAX(id) FROM tasks WHERE origin = 'inbox'), 0);
|
|
259
|
+
`);
|
|
260
|
+
sqlite.exec(`
|
|
261
|
+
UPDATE sequences
|
|
262
|
+
SET value = COALESCE((SELECT MAX(id) FROM tasks WHERE origin = 'moai'), 0)
|
|
263
|
+
WHERE name = 'task_moai' AND value < COALESCE((SELECT MAX(id) FROM tasks WHERE origin = 'moai'), 0);
|
|
264
|
+
`);
|
|
265
|
+
} catch (e) {
|
|
266
|
+
console.error('Migration warning (sequence sync):', e);
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
// Migration: Add project_id column for project-based task isolation
|
|
270
|
+
try {
|
|
271
|
+
sqlite.exec(`ALTER TABLE tasks ADD COLUMN project_id TEXT`);
|
|
272
|
+
} catch {
|
|
273
|
+
// Column already exists, ignore
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
// Migration: Add display_id column for task numbering (e.g., "1.1", "1.2.3")
|
|
277
|
+
try {
|
|
278
|
+
sqlite.exec(`ALTER TABLE tasks ADD COLUMN display_id TEXT`);
|
|
279
|
+
} catch {
|
|
280
|
+
// Column already exists, ignore
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
// =============================================
|
|
284
|
+
// Backlog.md 관련 컬럼 마이그레이션 (snake_case)
|
|
285
|
+
// =============================================
|
|
286
|
+
|
|
287
|
+
// Migration: Add backlog_file_id column (task-007 형식)
|
|
288
|
+
try {
|
|
289
|
+
sqlite.exec(`ALTER TABLE tasks ADD COLUMN backlog_file_id TEXT`);
|
|
290
|
+
} catch {
|
|
291
|
+
// Column already exists, ignore
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
// Migration: Add parent_task_id column for subtask relationship
|
|
295
|
+
try {
|
|
296
|
+
sqlite.exec(`ALTER TABLE tasks ADD COLUMN parent_task_id INTEGER`);
|
|
297
|
+
} catch {
|
|
298
|
+
// Column already exists, ignore
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
// Migration: Add blocked_by column for dependencies (JSON array)
|
|
302
|
+
try {
|
|
303
|
+
sqlite.exec(`ALTER TABLE tasks ADD COLUMN blocked_by TEXT`);
|
|
304
|
+
} catch {
|
|
305
|
+
// Column already exists, ignore
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
// Migration: Add plan column for plan section content
|
|
309
|
+
try {
|
|
310
|
+
sqlite.exec(`ALTER TABLE tasks ADD COLUMN plan TEXT`);
|
|
311
|
+
} catch {
|
|
312
|
+
// Column already exists, ignore
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
// Migration: Add acceptance_criteria column for AC section
|
|
316
|
+
try {
|
|
317
|
+
sqlite.exec(`ALTER TABLE tasks ADD COLUMN acceptance_criteria TEXT`);
|
|
318
|
+
} catch {
|
|
319
|
+
// Column already exists, ignore
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
// Migration: Add notes column for notes section
|
|
323
|
+
try {
|
|
324
|
+
sqlite.exec(`ALTER TABLE tasks ADD COLUMN notes TEXT`);
|
|
325
|
+
} catch {
|
|
326
|
+
// Column already exists, ignore
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
// Migration: Add due_date column for deadline
|
|
330
|
+
try {
|
|
331
|
+
sqlite.exec(`ALTER TABLE tasks ADD COLUMN due_date INTEGER`);
|
|
332
|
+
} catch {
|
|
333
|
+
// Column already exists, ignore
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
// Migration: Add milestone column for sprint/milestone grouping
|
|
337
|
+
try {
|
|
338
|
+
sqlite.exec(`ALTER TABLE tasks ADD COLUMN milestone TEXT`);
|
|
339
|
+
} catch {
|
|
340
|
+
// Column already exists, ignore
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
// =============================================
|
|
344
|
+
// MoAI SPEC TAG column migrations
|
|
345
|
+
// =============================================
|
|
346
|
+
|
|
347
|
+
// Migration: Add tag_id column for MoAI TAG identifier
|
|
348
|
+
try {
|
|
349
|
+
sqlite.exec(`ALTER TABLE tasks ADD COLUMN tag_id TEXT`);
|
|
350
|
+
} catch {
|
|
351
|
+
// Column already exists, ignore
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
// Migration: Add tag_scope column for TAG scope (file paths)
|
|
355
|
+
try {
|
|
356
|
+
sqlite.exec(`ALTER TABLE tasks ADD COLUMN tag_scope TEXT`);
|
|
357
|
+
} catch {
|
|
358
|
+
// Column already exists, ignore
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
// Migration: Add tag_dependencies column for TAG dependencies (JSON array)
|
|
362
|
+
try {
|
|
363
|
+
sqlite.exec(`ALTER TABLE tasks ADD COLUMN tag_dependencies TEXT`);
|
|
364
|
+
} catch {
|
|
365
|
+
// Column already exists, ignore
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
// Backlog indexes for performance
|
|
369
|
+
sqlite.exec(`CREATE INDEX IF NOT EXISTS idx_tasks_backlog_file_id ON tasks(backlog_file_id);`);
|
|
370
|
+
sqlite.exec(`CREATE INDEX IF NOT EXISTS idx_tasks_parent_task_id ON tasks(parent_task_id);`);
|
|
371
|
+
sqlite.exec(`CREATE INDEX IF NOT EXISTS idx_tasks_milestone ON tasks(milestone);`);
|
|
372
|
+
|
|
373
|
+
// MoAI TAG index
|
|
374
|
+
sqlite.exec(`CREATE INDEX IF NOT EXISTS idx_tasks_tag_id ON tasks(tag_id);`);
|
|
375
|
+
|
|
376
|
+
// Migration: Set default project_id for existing tasks
|
|
377
|
+
try {
|
|
378
|
+
sqlite.exec(`
|
|
379
|
+
UPDATE tasks
|
|
380
|
+
SET project_id = (SELECT project_id FROM changes WHERE changes.id = tasks.change_id)
|
|
381
|
+
WHERE project_id IS NULL AND change_id IS NOT NULL
|
|
382
|
+
`);
|
|
383
|
+
sqlite.exec(`UPDATE tasks SET project_id = 'default' WHERE project_id IS NULL`);
|
|
384
|
+
} catch (e) {
|
|
385
|
+
console.error('Migration warning (project_id update):', e);
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
// Migration: Convert to composite primary key (origin, id)
|
|
389
|
+
// TAG-014: Updated to handle 'moai' instead of 'openspec'
|
|
390
|
+
try {
|
|
391
|
+
const tableInfo = sqlite.prepare("SELECT sql FROM sqlite_master WHERE type='table' AND name='tasks'").get() as { sql: string } | undefined;
|
|
392
|
+
// Check if already migrated (has composite key)
|
|
393
|
+
if (tableInfo?.sql && !tableInfo.sql.includes('PRIMARY KEY (origin, id)')) {
|
|
394
|
+
console.log('Migrating tasks table to composite primary key (origin, id)...');
|
|
395
|
+
|
|
396
|
+
// Reassign inbox task IDs starting from 1
|
|
397
|
+
const inboxTasks = sqlite.prepare(`
|
|
398
|
+
SELECT id FROM tasks WHERE origin = 'inbox' ORDER BY created_at, id
|
|
399
|
+
`).all() as Array<{ id: number }>;
|
|
400
|
+
|
|
401
|
+
let newInboxId = 1;
|
|
402
|
+
for (const task of inboxTasks) {
|
|
403
|
+
sqlite.prepare(`UPDATE tasks SET id = ? WHERE id = ? AND origin = 'inbox'`).run(-task.id - 100000, task.id);
|
|
404
|
+
}
|
|
405
|
+
for (const task of inboxTasks) {
|
|
406
|
+
sqlite.prepare(`UPDATE tasks SET id = ? WHERE id = ? AND origin = 'inbox'`).run(newInboxId++, -task.id - 100000);
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
// Update inbox sequence
|
|
410
|
+
sqlite.prepare(`UPDATE sequences SET value = ? WHERE name = 'task_inbox'`).run(newInboxId - 1);
|
|
411
|
+
|
|
412
|
+
// TAG-014: Update moai sequence (previously openspec)
|
|
413
|
+
const maxMoaiId = sqlite.prepare(`SELECT MAX(id) as max FROM tasks WHERE origin = 'moai'`).get() as { max: number } | undefined;
|
|
414
|
+
sqlite.prepare(`UPDATE sequences SET value = ? WHERE name = 'task_moai'`).run(maxMoaiId?.max ?? 0);
|
|
415
|
+
|
|
416
|
+
console.log(`Migration completed: ${inboxTasks.length} inbox tasks renumbered (1-${newInboxId - 1})`);
|
|
417
|
+
}
|
|
418
|
+
} catch (e) {
|
|
419
|
+
console.error('Migration warning (composite key):', e);
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
// Migration: Convert TEXT id to INTEGER id
|
|
423
|
+
// This handles migration from TASK-1 format to pure numeric IDs
|
|
424
|
+
try {
|
|
425
|
+
const tableInfo = sqlite.prepare("SELECT sql FROM sqlite_master WHERE type='table' AND name='tasks'").get() as { sql: string } | undefined;
|
|
426
|
+
if (tableInfo?.sql && tableInfo.sql.includes('id TEXT PRIMARY KEY')) {
|
|
427
|
+
console.log('Migrating tasks table from TEXT id to INTEGER id...');
|
|
428
|
+
|
|
429
|
+
// Get current max sequence value
|
|
430
|
+
const seqResult = sqlite.prepare("SELECT value FROM sequences WHERE name = 'task'").get() as { value: number } | undefined;
|
|
431
|
+
const currentSeq = seqResult?.value ?? 0;
|
|
432
|
+
|
|
433
|
+
sqlite.exec(`
|
|
434
|
+
BEGIN TRANSACTION;
|
|
435
|
+
|
|
436
|
+
-- Create new table with INTEGER id
|
|
437
|
+
CREATE TABLE tasks_new (
|
|
438
|
+
id INTEGER PRIMARY KEY,
|
|
439
|
+
title TEXT NOT NULL,
|
|
440
|
+
description TEXT,
|
|
441
|
+
status TEXT NOT NULL DEFAULT 'todo' CHECK(status IN ('todo', 'in-progress', 'review', 'done', 'archived')),
|
|
442
|
+
priority TEXT NOT NULL DEFAULT 'medium' CHECK(priority IN ('low', 'medium', 'high')),
|
|
443
|
+
tags TEXT,
|
|
444
|
+
assignee TEXT,
|
|
445
|
+
"order" INTEGER NOT NULL DEFAULT 0,
|
|
446
|
+
created_at INTEGER NOT NULL,
|
|
447
|
+
updated_at INTEGER NOT NULL,
|
|
448
|
+
archived_at INTEGER
|
|
449
|
+
);
|
|
450
|
+
|
|
451
|
+
-- Copy data from old table, extracting numeric part from TASK-X format
|
|
452
|
+
INSERT INTO tasks_new (id, title, description, status, priority, tags, assignee, "order", created_at, updated_at, archived_at)
|
|
453
|
+
SELECT
|
|
454
|
+
CAST(REPLACE(id, 'TASK-', '') AS INTEGER) as id,
|
|
455
|
+
title, description, status, priority, tags, assignee, "order", created_at, updated_at, archived_at
|
|
456
|
+
FROM tasks;
|
|
457
|
+
|
|
458
|
+
-- Drop old table
|
|
459
|
+
DROP TABLE tasks;
|
|
460
|
+
|
|
461
|
+
-- Rename new table
|
|
462
|
+
ALTER TABLE tasks_new RENAME TO tasks;
|
|
463
|
+
|
|
464
|
+
-- Rebuild FTS table
|
|
465
|
+
DROP TABLE IF EXISTS tasks_fts;
|
|
466
|
+
|
|
467
|
+
COMMIT;
|
|
468
|
+
`);
|
|
469
|
+
|
|
470
|
+
// Recreate FTS triggers after table recreation
|
|
471
|
+
sqlite.exec(`DROP TRIGGER IF EXISTS tasks_ai`);
|
|
472
|
+
sqlite.exec(`DROP TRIGGER IF EXISTS tasks_ad`);
|
|
473
|
+
sqlite.exec(`DROP TRIGGER IF EXISTS tasks_au`);
|
|
474
|
+
|
|
475
|
+
console.log('Migration completed successfully.');
|
|
476
|
+
}
|
|
477
|
+
} catch (e) {
|
|
478
|
+
// Migration failed or not needed, continue
|
|
479
|
+
console.error('Migration warning:', e);
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
// Create FTS5 virtual table for full-text search
|
|
483
|
+
sqlite.exec(`
|
|
484
|
+
CREATE VIRTUAL TABLE IF NOT EXISTS tasks_fts USING fts5(
|
|
485
|
+
id,
|
|
486
|
+
title,
|
|
487
|
+
description,
|
|
488
|
+
group_title,
|
|
489
|
+
content='tasks',
|
|
490
|
+
content_rowid='rowid',
|
|
491
|
+
tokenize='unicode61'
|
|
492
|
+
);
|
|
493
|
+
`);
|
|
494
|
+
|
|
495
|
+
// Create triggers to keep FTS index in sync
|
|
496
|
+
sqlite.exec(`
|
|
497
|
+
CREATE TRIGGER IF NOT EXISTS tasks_ai AFTER INSERT ON tasks BEGIN
|
|
498
|
+
INSERT INTO tasks_fts(id, title, description, group_title) VALUES (new.id, new.title, new.description, new.group_title);
|
|
499
|
+
END;
|
|
500
|
+
`);
|
|
501
|
+
|
|
502
|
+
sqlite.exec(`
|
|
503
|
+
CREATE TRIGGER IF NOT EXISTS tasks_ad AFTER DELETE ON tasks BEGIN
|
|
504
|
+
INSERT INTO tasks_fts(tasks_fts, id, title, description, group_title) VALUES('delete', old.id, old.title, old.description, old.group_title);
|
|
505
|
+
END;
|
|
506
|
+
`);
|
|
507
|
+
|
|
508
|
+
sqlite.exec(`
|
|
509
|
+
CREATE TRIGGER IF NOT EXISTS tasks_au AFTER UPDATE ON tasks BEGIN
|
|
510
|
+
INSERT INTO tasks_fts(tasks_fts, id, title, description, group_title) VALUES('delete', old.id, old.title, old.description, old.group_title);
|
|
511
|
+
INSERT INTO tasks_fts(id, title, description, group_title) VALUES (new.id, new.title, new.description, new.group_title);
|
|
512
|
+
END;
|
|
513
|
+
`);
|
|
514
|
+
|
|
515
|
+
// Migration: Rebuild FTS table to include group_title
|
|
516
|
+
try {
|
|
517
|
+
// Check if group_title column exists in tasks_fts
|
|
518
|
+
const ftsInfo = sqlite.prepare("SELECT sql FROM sqlite_master WHERE type='table' AND name='tasks_fts'").get() as { sql: string } | undefined;
|
|
519
|
+
if (ftsInfo?.sql && !ftsInfo.sql.includes('group_title')) {
|
|
520
|
+
console.log('Rebuilding FTS table to include group_title...');
|
|
521
|
+
|
|
522
|
+
sqlite.exec(`
|
|
523
|
+
BEGIN TRANSACTION;
|
|
524
|
+
|
|
525
|
+
-- Drop existing FTS table
|
|
526
|
+
DROP TABLE IF EXISTS tasks_fts;
|
|
527
|
+
|
|
528
|
+
-- Drop existing triggers
|
|
529
|
+
DROP TRIGGER IF EXISTS tasks_ai;
|
|
530
|
+
DROP TRIGGER IF EXISTS tasks_ad;
|
|
531
|
+
DROP TRIGGER IF EXISTS tasks_au;
|
|
532
|
+
|
|
533
|
+
COMMIT;
|
|
534
|
+
`);
|
|
535
|
+
}
|
|
536
|
+
} catch (e) {
|
|
537
|
+
console.error('Migration warning (FTS rebuild):', e);
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
// Create indexes for better performance
|
|
541
|
+
sqlite.exec(`
|
|
542
|
+
CREATE INDEX IF NOT EXISTS idx_tasks_group_title ON tasks(group_title);
|
|
543
|
+
`);
|
|
544
|
+
|
|
545
|
+
sqlite.exec(`
|
|
546
|
+
CREATE INDEX IF NOT EXISTS idx_tasks_group_task_order ON tasks(group_order, task_order);
|
|
547
|
+
`);
|
|
548
|
+
|
|
549
|
+
// Additional indexes for performance optimization
|
|
550
|
+
sqlite.exec(`
|
|
551
|
+
CREATE INDEX IF NOT EXISTS idx_tasks_project_id ON tasks(project_id);
|
|
552
|
+
`);
|
|
553
|
+
|
|
554
|
+
sqlite.exec(`
|
|
555
|
+
CREATE INDEX IF NOT EXISTS idx_tasks_change_id ON tasks(change_id);
|
|
556
|
+
`);
|
|
557
|
+
|
|
558
|
+
sqlite.exec(`
|
|
559
|
+
CREATE INDEX IF NOT EXISTS idx_tasks_status ON tasks(status);
|
|
560
|
+
`);
|
|
561
|
+
|
|
562
|
+
sqlite.exec(`
|
|
563
|
+
CREATE INDEX IF NOT EXISTS idx_tasks_stage ON tasks(stage);
|
|
564
|
+
`);
|
|
565
|
+
|
|
566
|
+
sqlite.exec(`
|
|
567
|
+
CREATE INDEX IF NOT EXISTS idx_tasks_project_status ON tasks(project_id, status);
|
|
568
|
+
`);
|
|
569
|
+
|
|
570
|
+
sqlite.exec(`
|
|
571
|
+
CREATE INDEX IF NOT EXISTS idx_tasks_project_stage ON tasks(project_id, stage);
|
|
572
|
+
`);
|
|
573
|
+
|
|
574
|
+
// Changes table indexes
|
|
575
|
+
sqlite.exec(`
|
|
576
|
+
CREATE INDEX IF NOT EXISTS idx_changes_project_id ON changes(project_id);
|
|
577
|
+
`);
|
|
578
|
+
|
|
579
|
+
sqlite.exec(`
|
|
580
|
+
CREATE INDEX IF NOT EXISTS idx_changes_status ON changes(status);
|
|
581
|
+
`);
|
|
582
|
+
|
|
583
|
+
sqlite.exec(`
|
|
584
|
+
CREATE INDEX IF NOT EXISTS idx_changes_project_status ON changes(project_id, status);
|
|
585
|
+
`);
|
|
586
|
+
|
|
587
|
+
sqlite.exec(`
|
|
588
|
+
CREATE INDEX IF NOT EXISTS idx_changes_updated_at ON changes(updated_at);
|
|
589
|
+
`);
|
|
590
|
+
|
|
591
|
+
// =============================================
|
|
592
|
+
// Change Log & Replay 시스템 테이블
|
|
593
|
+
// =============================================
|
|
594
|
+
|
|
595
|
+
// Change Events 테이블 (이벤트 로그)
|
|
596
|
+
sqlite.exec(`
|
|
597
|
+
CREATE TABLE IF NOT EXISTS change_events (
|
|
598
|
+
id TEXT PRIMARY KEY,
|
|
599
|
+
type TEXT NOT NULL CHECK(type IN ('FILE_CHANGE', 'DB_CHANGE', 'SYNC_OPERATION', 'CONFLICT_DETECTED', 'CONFLICT_RESOLVED', 'RECOVERY_STARTED', 'RECOVERY_COMPLETED', 'BACKUP_CREATED', 'BACKUP_RESTORED', 'SYSTEM_EVENT')),
|
|
600
|
+
severity TEXT NOT NULL DEFAULT 'INFO' CHECK(severity IN ('DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL')),
|
|
601
|
+
source TEXT NOT NULL CHECK(source IN ('FILE_WATCHER', 'SYNC_MANAGER', 'RECOVERY_MANAGER', 'BACKUP_MANAGER', 'MCP_SERVER', 'USER_ACTION', 'SYSTEM')),
|
|
602
|
+
timestamp INTEGER NOT NULL,
|
|
603
|
+
project_id TEXT,
|
|
604
|
+
change_id TEXT,
|
|
605
|
+
correlation_id TEXT,
|
|
606
|
+
session_id TEXT,
|
|
607
|
+
user_id TEXT,
|
|
608
|
+
data_type TEXT NOT NULL,
|
|
609
|
+
data TEXT NOT NULL,
|
|
610
|
+
metadata TEXT NOT NULL,
|
|
611
|
+
processing_status TEXT NOT NULL DEFAULT 'PENDING' CHECK(processing_status IN ('PENDING', 'PROCESSING', 'COMPLETED', 'FAILED')),
|
|
612
|
+
processed_at INTEGER,
|
|
613
|
+
processing_error TEXT,
|
|
614
|
+
retry_count INTEGER NOT NULL DEFAULT 0,
|
|
615
|
+
max_retries INTEGER NOT NULL DEFAULT 3,
|
|
616
|
+
checksum TEXT,
|
|
617
|
+
size INTEGER NOT NULL,
|
|
618
|
+
created_at INTEGER NOT NULL,
|
|
619
|
+
updated_at INTEGER NOT NULL
|
|
620
|
+
);
|
|
621
|
+
`);
|
|
622
|
+
|
|
623
|
+
// Replay Sessions 테이블
|
|
624
|
+
sqlite.exec(`
|
|
625
|
+
CREATE TABLE IF NOT EXISTS replay_sessions (
|
|
626
|
+
id TEXT PRIMARY KEY,
|
|
627
|
+
name TEXT,
|
|
628
|
+
description TEXT,
|
|
629
|
+
filter TEXT NOT NULL,
|
|
630
|
+
options TEXT NOT NULL,
|
|
631
|
+
status TEXT NOT NULL DEFAULT 'PENDING' CHECK(status IN ('PENDING', 'RUNNING', 'COMPLETED', 'FAILED', 'CANCELLED')),
|
|
632
|
+
total_events INTEGER NOT NULL DEFAULT 0,
|
|
633
|
+
processed_events INTEGER NOT NULL DEFAULT 0,
|
|
634
|
+
succeeded_events INTEGER NOT NULL DEFAULT 0,
|
|
635
|
+
failed_events INTEGER NOT NULL DEFAULT 0,
|
|
636
|
+
skipped_events INTEGER NOT NULL DEFAULT 0,
|
|
637
|
+
created_at INTEGER NOT NULL,
|
|
638
|
+
started_at INTEGER,
|
|
639
|
+
completed_at INTEGER,
|
|
640
|
+
duration INTEGER,
|
|
641
|
+
result TEXT,
|
|
642
|
+
metadata TEXT
|
|
643
|
+
);
|
|
644
|
+
`);
|
|
645
|
+
|
|
646
|
+
// Replay Results 테이블
|
|
647
|
+
sqlite.exec(`
|
|
648
|
+
CREATE TABLE IF NOT EXISTS replay_results (
|
|
649
|
+
id INTEGER PRIMARY KEY,
|
|
650
|
+
session_id TEXT NOT NULL REFERENCES replay_sessions(id),
|
|
651
|
+
event_id TEXT NOT NULL,
|
|
652
|
+
status TEXT NOT NULL CHECK(status IN ('SUCCESS', 'FAILED', 'SKIPPED')),
|
|
653
|
+
duration INTEGER NOT NULL,
|
|
654
|
+
error TEXT,
|
|
655
|
+
warnings TEXT,
|
|
656
|
+
"order" INTEGER NOT NULL,
|
|
657
|
+
created_at INTEGER NOT NULL
|
|
658
|
+
);
|
|
659
|
+
`);
|
|
660
|
+
|
|
661
|
+
// Rollback Points 테이블
|
|
662
|
+
sqlite.exec(`
|
|
663
|
+
CREATE TABLE IF NOT EXISTS rollback_points (
|
|
664
|
+
id TEXT PRIMARY KEY,
|
|
665
|
+
session_id TEXT REFERENCES replay_sessions(id),
|
|
666
|
+
timestamp INTEGER NOT NULL,
|
|
667
|
+
description TEXT NOT NULL,
|
|
668
|
+
snapshot TEXT NOT NULL,
|
|
669
|
+
metadata TEXT,
|
|
670
|
+
is_active INTEGER NOT NULL DEFAULT 1,
|
|
671
|
+
is_expired INTEGER NOT NULL DEFAULT 0,
|
|
672
|
+
expires_at INTEGER,
|
|
673
|
+
created_at INTEGER NOT NULL,
|
|
674
|
+
updated_at INTEGER NOT NULL
|
|
675
|
+
);
|
|
676
|
+
`);
|
|
677
|
+
|
|
678
|
+
// Event Statistics 테이블 (성능 최적화용)
|
|
679
|
+
sqlite.exec(`
|
|
680
|
+
CREATE TABLE IF NOT EXISTS event_statistics (
|
|
681
|
+
id INTEGER PRIMARY KEY,
|
|
682
|
+
project_id TEXT,
|
|
683
|
+
event_type TEXT,
|
|
684
|
+
severity TEXT,
|
|
685
|
+
source TEXT,
|
|
686
|
+
date TEXT NOT NULL,
|
|
687
|
+
count INTEGER NOT NULL DEFAULT 0,
|
|
688
|
+
size INTEGER NOT NULL DEFAULT 0,
|
|
689
|
+
avg_duration REAL,
|
|
690
|
+
error_count INTEGER NOT NULL DEFAULT 0,
|
|
691
|
+
calculated_at INTEGER NOT NULL,
|
|
692
|
+
created_at INTEGER NOT NULL,
|
|
693
|
+
updated_at INTEGER NOT NULL
|
|
694
|
+
);
|
|
695
|
+
`);
|
|
696
|
+
|
|
697
|
+
// Event Indexes 테이블 (검색 성능 최적화용)
|
|
698
|
+
sqlite.exec(`
|
|
699
|
+
CREATE TABLE IF NOT EXISTS event_indexes (
|
|
700
|
+
id INTEGER PRIMARY KEY,
|
|
701
|
+
event_id TEXT NOT NULL REFERENCES change_events(id),
|
|
702
|
+
field_name TEXT NOT NULL,
|
|
703
|
+
field_value TEXT NOT NULL,
|
|
704
|
+
field_type TEXT NOT NULL,
|
|
705
|
+
weight REAL NOT NULL DEFAULT 1.0,
|
|
706
|
+
created_at INTEGER NOT NULL
|
|
707
|
+
);
|
|
708
|
+
`);
|
|
709
|
+
|
|
710
|
+
// Change Events 인덱스
|
|
711
|
+
sqlite.exec(`
|
|
712
|
+
CREATE INDEX IF NOT EXISTS idx_change_events_type ON change_events(type);
|
|
713
|
+
`);
|
|
714
|
+
|
|
715
|
+
sqlite.exec(`
|
|
716
|
+
CREATE INDEX IF NOT EXISTS idx_change_events_severity ON change_events(severity);
|
|
717
|
+
`);
|
|
718
|
+
|
|
719
|
+
sqlite.exec(`
|
|
720
|
+
CREATE INDEX IF NOT EXISTS idx_change_events_timestamp ON change_events(timestamp);
|
|
721
|
+
`);
|
|
722
|
+
|
|
723
|
+
sqlite.exec(`
|
|
724
|
+
CREATE INDEX IF NOT EXISTS idx_change_events_project_id ON change_events(project_id);
|
|
725
|
+
`);
|
|
726
|
+
|
|
727
|
+
// Replay Sessions 인덱스
|
|
728
|
+
sqlite.exec(`
|
|
729
|
+
CREATE INDEX IF NOT EXISTS idx_replay_sessions_status ON replay_sessions(status);
|
|
730
|
+
`);
|
|
731
|
+
|
|
732
|
+
// Replay Results 인덱스
|
|
733
|
+
sqlite.exec(`
|
|
734
|
+
CREATE INDEX IF NOT EXISTS idx_replay_results_session_id ON replay_results(session_id);
|
|
735
|
+
`);
|
|
736
|
+
|
|
737
|
+
// Rollback Points 인덱스
|
|
738
|
+
sqlite.exec(`
|
|
739
|
+
CREATE INDEX IF NOT EXISTS idx_rollback_points_session_id ON rollback_points(session_id);
|
|
740
|
+
`);
|
|
741
|
+
|
|
742
|
+
// =============================================
|
|
743
|
+
// Alert System 테이블
|
|
744
|
+
// =============================================
|
|
745
|
+
|
|
746
|
+
// Alerts 테이블
|
|
747
|
+
sqlite.exec(`
|
|
748
|
+
CREATE TABLE IF NOT EXISTS alerts (
|
|
749
|
+
id TEXT PRIMARY KEY,
|
|
750
|
+
source TEXT NOT NULL CHECK(source IN ('github', 'vercel', 'sentry', 'supabase', 'custom')),
|
|
751
|
+
type TEXT NOT NULL,
|
|
752
|
+
severity TEXT NOT NULL CHECK(severity IN ('critical', 'warning', 'info')),
|
|
753
|
+
status TEXT NOT NULL DEFAULT 'pending' CHECK(status IN ('pending', 'processing', 'resolved', 'ignored')),
|
|
754
|
+
title TEXT NOT NULL,
|
|
755
|
+
summary TEXT,
|
|
756
|
+
external_url TEXT,
|
|
757
|
+
payload TEXT NOT NULL,
|
|
758
|
+
metadata TEXT,
|
|
759
|
+
analysis TEXT,
|
|
760
|
+
resolution TEXT,
|
|
761
|
+
created_at INTEGER NOT NULL,
|
|
762
|
+
updated_at INTEGER NOT NULL,
|
|
763
|
+
resolved_at INTEGER,
|
|
764
|
+
expires_at INTEGER NOT NULL
|
|
765
|
+
);
|
|
766
|
+
`);
|
|
767
|
+
|
|
768
|
+
// Alerts 인덱스
|
|
769
|
+
sqlite.exec(`CREATE INDEX IF NOT EXISTS idx_alerts_status ON alerts(status);`);
|
|
770
|
+
sqlite.exec(`CREATE INDEX IF NOT EXISTS idx_alerts_source ON alerts(source);`);
|
|
771
|
+
sqlite.exec(`CREATE INDEX IF NOT EXISTS idx_alerts_severity ON alerts(severity);`);
|
|
772
|
+
sqlite.exec(`CREATE INDEX IF NOT EXISTS idx_alerts_created_at ON alerts(created_at);`);
|
|
773
|
+
sqlite.exec(`CREATE INDEX IF NOT EXISTS idx_alerts_expires_at ON alerts(expires_at);`);
|
|
774
|
+
|
|
775
|
+
// Activity Logs 테이블
|
|
776
|
+
sqlite.exec(`
|
|
777
|
+
CREATE TABLE IF NOT EXISTS activity_logs (
|
|
778
|
+
id TEXT PRIMARY KEY,
|
|
779
|
+
alert_id TEXT REFERENCES alerts(id) ON DELETE CASCADE,
|
|
780
|
+
actor TEXT NOT NULL CHECK(actor IN ('system', 'agent', 'user')),
|
|
781
|
+
action TEXT NOT NULL,
|
|
782
|
+
description TEXT NOT NULL,
|
|
783
|
+
metadata TEXT,
|
|
784
|
+
created_at INTEGER NOT NULL
|
|
785
|
+
);
|
|
786
|
+
`);
|
|
787
|
+
|
|
788
|
+
// Activity Logs 인덱스
|
|
789
|
+
sqlite.exec(`CREATE INDEX IF NOT EXISTS idx_activity_logs_alert_id ON activity_logs(alert_id);`);
|
|
790
|
+
sqlite.exec(`CREATE INDEX IF NOT EXISTS idx_activity_logs_created_at ON activity_logs(created_at);`);
|
|
791
|
+
|
|
792
|
+
// Webhook Configs 테이블
|
|
793
|
+
sqlite.exec(`
|
|
794
|
+
CREATE TABLE IF NOT EXISTS webhook_configs (
|
|
795
|
+
id TEXT PRIMARY KEY,
|
|
796
|
+
source TEXT NOT NULL CHECK(source IN ('github', 'vercel', 'sentry', 'supabase', 'custom')),
|
|
797
|
+
name TEXT NOT NULL,
|
|
798
|
+
endpoint_path TEXT NOT NULL,
|
|
799
|
+
secret TEXT,
|
|
800
|
+
enabled INTEGER NOT NULL DEFAULT 1,
|
|
801
|
+
project_filter TEXT,
|
|
802
|
+
created_at INTEGER NOT NULL,
|
|
803
|
+
updated_at INTEGER NOT NULL
|
|
804
|
+
);
|
|
805
|
+
`);
|
|
806
|
+
|
|
807
|
+
// Webhook Configs 인덱스
|
|
808
|
+
sqlite.exec(`CREATE INDEX IF NOT EXISTS idx_webhook_configs_source ON webhook_configs(source);`);
|
|
809
|
+
sqlite.exec(`CREATE INDEX IF NOT EXISTS idx_webhook_configs_enabled ON webhook_configs(enabled);`);
|
|
810
|
+
|
|
811
|
+
// Notification Config 테이블 (싱글톤)
|
|
812
|
+
sqlite.exec(`
|
|
813
|
+
CREATE TABLE IF NOT EXISTS notification_config (
|
|
814
|
+
id TEXT PRIMARY KEY DEFAULT 'default',
|
|
815
|
+
slack_webhook_url TEXT,
|
|
816
|
+
slack_channel TEXT,
|
|
817
|
+
slack_enabled INTEGER NOT NULL DEFAULT 0,
|
|
818
|
+
rule_on_critical INTEGER NOT NULL DEFAULT 1,
|
|
819
|
+
rule_on_autofix INTEGER NOT NULL DEFAULT 1,
|
|
820
|
+
rule_on_all INTEGER NOT NULL DEFAULT 0,
|
|
821
|
+
created_at INTEGER NOT NULL,
|
|
822
|
+
updated_at INTEGER NOT NULL
|
|
823
|
+
);
|
|
824
|
+
`);
|
|
825
|
+
|
|
826
|
+
// 기본 notification config 생성
|
|
827
|
+
sqlite.exec(`
|
|
828
|
+
INSERT OR IGNORE INTO notification_config (id, created_at, updated_at)
|
|
829
|
+
VALUES ('default', ${Date.now()}, ${Date.now()});
|
|
830
|
+
`);
|
|
831
|
+
|
|
832
|
+
// Migration: Add risk_assessment column to alerts
|
|
833
|
+
try {
|
|
834
|
+
sqlite.exec(`ALTER TABLE alerts ADD COLUMN risk_assessment TEXT`);
|
|
835
|
+
} catch {
|
|
836
|
+
// Column already exists, ignore
|
|
837
|
+
}
|
|
838
|
+
|
|
839
|
+
// Migration: Add GitHub Actions poller columns to notification_config
|
|
840
|
+
try {
|
|
841
|
+
sqlite.exec(`ALTER TABLE notification_config ADD COLUMN poller_enabled INTEGER NOT NULL DEFAULT 0`);
|
|
842
|
+
} catch {
|
|
843
|
+
// Column already exists, ignore
|
|
844
|
+
}
|
|
845
|
+
try {
|
|
846
|
+
sqlite.exec(`ALTER TABLE notification_config ADD COLUMN poller_interval_ms INTEGER NOT NULL DEFAULT 300000`);
|
|
847
|
+
} catch {
|
|
848
|
+
// Column already exists, ignore
|
|
849
|
+
}
|
|
850
|
+
try {
|
|
851
|
+
sqlite.exec(`ALTER TABLE notification_config ADD COLUMN poller_repos TEXT`);
|
|
852
|
+
} catch {
|
|
853
|
+
// Column already exists, ignore
|
|
854
|
+
}
|
|
855
|
+
try {
|
|
856
|
+
sqlite.exec(`ALTER TABLE notification_config ADD COLUMN poller_last_polled_at INTEGER`);
|
|
857
|
+
} catch {
|
|
858
|
+
// Column already exists, ignore
|
|
859
|
+
}
|
|
860
|
+
|
|
861
|
+
// Migration: Add project_id column to alerts table for project-based filtering
|
|
862
|
+
try {
|
|
863
|
+
sqlite.exec(`ALTER TABLE alerts ADD COLUMN project_id TEXT`);
|
|
864
|
+
} catch {
|
|
865
|
+
// Column already exists, ignore
|
|
866
|
+
}
|
|
867
|
+
|
|
868
|
+
// Create index for project_id on alerts
|
|
869
|
+
try {
|
|
870
|
+
sqlite.exec(`CREATE INDEX IF NOT EXISTS idx_alerts_project_id ON alerts(project_id);`);
|
|
871
|
+
} catch {
|
|
872
|
+
// Index already exists, ignore
|
|
873
|
+
}
|
|
874
|
+
|
|
875
|
+
// Migration: Recreate webhook_configs with correct schema (endpoint_path, project_filter)
|
|
876
|
+
try {
|
|
877
|
+
// Check if old schema exists by checking for 'endpoint' column
|
|
878
|
+
const tableInfo = sqlite.prepare(`PRAGMA table_info(webhook_configs)`).all() as Array<{ name: string }>
|
|
879
|
+
const hasOldSchema = tableInfo.some((col) => col.name === 'endpoint')
|
|
880
|
+
if (hasOldSchema) {
|
|
881
|
+
// Drop old table and let CREATE TABLE IF NOT EXISTS recreate it
|
|
882
|
+
sqlite.exec(`DROP TABLE IF EXISTS webhook_configs`)
|
|
883
|
+
sqlite.exec(`
|
|
884
|
+
CREATE TABLE webhook_configs (
|
|
885
|
+
id TEXT PRIMARY KEY,
|
|
886
|
+
source TEXT NOT NULL CHECK(source IN ('github', 'vercel', 'sentry', 'supabase', 'custom')),
|
|
887
|
+
name TEXT NOT NULL,
|
|
888
|
+
endpoint_path TEXT NOT NULL,
|
|
889
|
+
secret TEXT,
|
|
890
|
+
enabled INTEGER NOT NULL DEFAULT 1,
|
|
891
|
+
project_filter TEXT,
|
|
892
|
+
created_at INTEGER NOT NULL,
|
|
893
|
+
updated_at INTEGER NOT NULL
|
|
894
|
+
)
|
|
895
|
+
`)
|
|
896
|
+
sqlite.exec(`CREATE INDEX idx_webhook_configs_source ON webhook_configs(source);`)
|
|
897
|
+
sqlite.exec(`CREATE INDEX idx_webhook_configs_enabled ON webhook_configs(enabled);`)
|
|
898
|
+
}
|
|
899
|
+
} catch {
|
|
900
|
+
// Ignore migration errors
|
|
901
|
+
}
|
|
902
|
+
|
|
903
|
+
// =============================================
|
|
904
|
+
// Alert Patterns 테이블 (Phase 3: 유사 Alert 매칭)
|
|
905
|
+
// =============================================
|
|
906
|
+
sqlite.exec(`
|
|
907
|
+
CREATE TABLE IF NOT EXISTS alert_patterns (
|
|
908
|
+
id TEXT PRIMARY KEY,
|
|
909
|
+
source TEXT NOT NULL CHECK(source IN ('github', 'vercel', 'sentry', 'supabase', 'custom')),
|
|
910
|
+
type TEXT NOT NULL,
|
|
911
|
+
pattern_signature TEXT NOT NULL,
|
|
912
|
+
pattern_keywords TEXT,
|
|
913
|
+
resolution_count INTEGER NOT NULL DEFAULT 0,
|
|
914
|
+
auto_fix_count INTEGER NOT NULL DEFAULT 0,
|
|
915
|
+
manual_fix_count INTEGER NOT NULL DEFAULT 0,
|
|
916
|
+
avg_resolution_time INTEGER,
|
|
917
|
+
recommended_action TEXT,
|
|
918
|
+
recommended_fix TEXT,
|
|
919
|
+
success_rate REAL,
|
|
920
|
+
alert_ids TEXT,
|
|
921
|
+
created_at INTEGER NOT NULL,
|
|
922
|
+
updated_at INTEGER NOT NULL
|
|
923
|
+
);
|
|
924
|
+
`);
|
|
925
|
+
|
|
926
|
+
// Alert Patterns 인덱스
|
|
927
|
+
sqlite.exec(`CREATE INDEX IF NOT EXISTS idx_alert_patterns_source_type ON alert_patterns(source, type);`);
|
|
928
|
+
sqlite.exec(`CREATE INDEX IF NOT EXISTS idx_alert_patterns_signature ON alert_patterns(pattern_signature);`);
|
|
929
|
+
|
|
930
|
+
// =============================================
|
|
931
|
+
// Alert Trends 테이블 (Phase 3: 통계 대시보드)
|
|
932
|
+
// =============================================
|
|
933
|
+
sqlite.exec(`
|
|
934
|
+
CREATE TABLE IF NOT EXISTS alert_trends (
|
|
935
|
+
id INTEGER PRIMARY KEY,
|
|
936
|
+
date TEXT NOT NULL,
|
|
937
|
+
source TEXT NOT NULL CHECK(source IN ('github', 'vercel', 'sentry', 'supabase', 'custom', 'all')),
|
|
938
|
+
total_count INTEGER NOT NULL DEFAULT 0,
|
|
939
|
+
critical_count INTEGER NOT NULL DEFAULT 0,
|
|
940
|
+
warning_count INTEGER NOT NULL DEFAULT 0,
|
|
941
|
+
info_count INTEGER NOT NULL DEFAULT 0,
|
|
942
|
+
resolved_count INTEGER NOT NULL DEFAULT 0,
|
|
943
|
+
ignored_count INTEGER NOT NULL DEFAULT 0,
|
|
944
|
+
auto_fixed_count INTEGER NOT NULL DEFAULT 0,
|
|
945
|
+
avg_resolution_time INTEGER,
|
|
946
|
+
min_resolution_time INTEGER,
|
|
947
|
+
max_resolution_time INTEGER,
|
|
948
|
+
created_at INTEGER NOT NULL,
|
|
949
|
+
updated_at INTEGER NOT NULL
|
|
950
|
+
);
|
|
951
|
+
`);
|
|
952
|
+
|
|
953
|
+
// Alert Trends 인덱스
|
|
954
|
+
sqlite.exec(`CREATE INDEX IF NOT EXISTS idx_alert_trends_date_source ON alert_trends(date, source);`);
|
|
955
|
+
|
|
956
|
+
db = drizzle(sqlite, { schema });
|
|
957
|
+
currentDbPath = dbPath;
|
|
958
|
+
return db;
|
|
959
|
+
}
|
|
960
|
+
|
|
961
|
+
export function getDb(): ReturnType<typeof drizzle<typeof schema>> {
|
|
962
|
+
if (!db) {
|
|
963
|
+
return initDb();
|
|
964
|
+
}
|
|
965
|
+
return db;
|
|
966
|
+
}
|
|
967
|
+
|
|
968
|
+
export function getSqlite(): Database.Database {
|
|
969
|
+
if (!sqlite) {
|
|
970
|
+
initDb();
|
|
971
|
+
}
|
|
972
|
+
return sqlite!;
|
|
973
|
+
}
|
|
974
|
+
|
|
975
|
+
export function closeDb(): void {
|
|
976
|
+
if (sqlite) {
|
|
977
|
+
sqlite.close();
|
|
978
|
+
sqlite = null;
|
|
979
|
+
db = null;
|
|
980
|
+
currentDbPath = null;
|
|
981
|
+
}
|
|
982
|
+
}
|
|
983
|
+
|
|
984
|
+
/**
|
|
985
|
+
* Get next task ID for a specific origin type
|
|
986
|
+
* Uses sequences table to track and increment IDs
|
|
987
|
+
* TAG-014: Removed 'openspec' from origin options
|
|
988
|
+
*/
|
|
989
|
+
export function getNextTaskId(origin: 'inbox' | 'moai' | 'backlog' = 'backlog'): number {
|
|
990
|
+
const db = getSqlite();
|
|
991
|
+
const sequenceName = `task_${origin}`;
|
|
992
|
+
|
|
993
|
+
// Ensure sequence exists
|
|
994
|
+
db.prepare(`
|
|
995
|
+
INSERT OR IGNORE INTO sequences (name, value) VALUES (?, 0)
|
|
996
|
+
`).run(sequenceName);
|
|
997
|
+
|
|
998
|
+
// Increment and get next value
|
|
999
|
+
db.prepare(`
|
|
1000
|
+
UPDATE sequences SET value = value + 1 WHERE name = ?
|
|
1001
|
+
`).run(sequenceName);
|
|
1002
|
+
|
|
1003
|
+
const result = db.prepare(`
|
|
1004
|
+
SELECT value FROM sequences WHERE name = ?
|
|
1005
|
+
`).get(sequenceName) as { value: number };
|
|
1006
|
+
|
|
1007
|
+
return result.value;
|
|
1008
|
+
}
|