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.
Files changed (705) hide show
  1. package/.claude-flow/metrics/agent-metrics.json +1 -0
  2. package/.claude-flow/metrics/performance.json +87 -0
  3. package/.claude-flow/metrics/system-metrics.json +4370 -0
  4. package/.claude-flow/metrics/task-metrics.json +10 -0
  5. package/.claude-plugin/marketplace.json +18 -0
  6. package/.claude-plugin/plugin.json +17 -0
  7. package/.gitleaks.toml +69 -0
  8. package/.hive-mind/config/queens.json +59 -0
  9. package/.hive-mind/config/workers.json +72 -0
  10. package/.hive-mind/config.json +111 -0
  11. package/.hive-mind/hive.db +0 -0
  12. package/.hive-mind/hive.db-shm +0 -0
  13. package/.hive-mind/hive.db-wal +0 -0
  14. package/.leann/indexes/zyflow/documents.ids.txt +2078 -0
  15. package/.leann/indexes/zyflow/documents.index +0 -0
  16. package/.leann/indexes/zyflow/documents.leann.meta.json +25 -0
  17. package/.leann/indexes/zyflow/documents.leann.passages.idx +0 -0
  18. package/.leann/indexes/zyflow/documents.leann.passages.jsonl +2078 -0
  19. package/.mcp.json +41 -0
  20. package/.moai-backups/20260126_231508/.mcp.json +11 -0
  21. package/.moai-backups/20260126_231508/backup_metadata.json +34 -0
  22. package/.moai-backups/20260129_145438/.mcp.json +41 -0
  23. package/.moai-backups/20260129_145438/backup_metadata.json +53 -0
  24. package/.moai-backups/20260129_145504/.mcp.json +41 -0
  25. package/.moai-backups/20260129_145504/backup_metadata.json +20 -0
  26. package/.moai-backups/20260201_140004/.mcp.json +41 -0
  27. package/.moai-backups/20260201_140004/backup_metadata.json +51 -0
  28. package/.moai-backups/backup/.mcp.json +12 -0
  29. package/.moai-backups/settings-backup/settings.local.json +61 -0
  30. package/.pre-commit-config.yaml +74 -0
  31. package/.prettierignore +3 -0
  32. package/.prettierrc +7 -0
  33. package/.scannerwork/.sonar_lock +0 -0
  34. package/.scannerwork/report-task.txt +6 -0
  35. package/.serena/project.yml +105 -0
  36. package/.shadcn-admin-ref/.env.example +1 -0
  37. package/.shadcn-admin-ref/.prettierignore +18 -0
  38. package/.shadcn-admin-ref/.prettierrc +50 -0
  39. package/.shadcn-admin-ref/LICENSE +21 -0
  40. package/.shadcn-admin-ref/components.json +21 -0
  41. package/.shadcn-admin-ref/cz.yaml +7 -0
  42. package/.shadcn-admin-ref/eslint.config.js +59 -0
  43. package/.shadcn-admin-ref/index.html +80 -0
  44. package/.shadcn-admin-ref/knip.config.ts +8 -0
  45. package/.shadcn-admin-ref/netlify.toml +4 -0
  46. package/.shadcn-admin-ref/package.json +83 -0
  47. package/.shadcn-admin-ref/public/images/favicon.png +0 -0
  48. package/.shadcn-admin-ref/public/images/favicon.svg +4 -0
  49. package/.shadcn-admin-ref/public/images/favicon_light.png +0 -0
  50. package/.shadcn-admin-ref/public/images/favicon_light.svg +1 -0
  51. package/.shadcn-admin-ref/public/images/shadcn-admin.png +0 -0
  52. package/.shadcn-admin-ref/src/assets/brand-icons/icon-discord.tsx +28 -0
  53. package/.shadcn-admin-ref/src/assets/brand-icons/icon-docker.tsx +33 -0
  54. package/.shadcn-admin-ref/src/assets/brand-icons/icon-facebook.tsx +25 -0
  55. package/.shadcn-admin-ref/src/assets/brand-icons/icon-figma.tsx +27 -0
  56. package/.shadcn-admin-ref/src/assets/brand-icons/icon-github.tsx +25 -0
  57. package/.shadcn-admin-ref/src/assets/brand-icons/icon-gitlab.tsx +25 -0
  58. package/.shadcn-admin-ref/src/assets/brand-icons/icon-gmail.tsx +28 -0
  59. package/.shadcn-admin-ref/src/assets/brand-icons/icon-medium.tsx +30 -0
  60. package/.shadcn-admin-ref/src/assets/brand-icons/icon-notion.tsx +28 -0
  61. package/.shadcn-admin-ref/src/assets/brand-icons/icon-skype.tsx +26 -0
  62. package/.shadcn-admin-ref/src/assets/brand-icons/icon-slack.tsx +28 -0
  63. package/.shadcn-admin-ref/src/assets/brand-icons/icon-stripe.tsx +25 -0
  64. package/.shadcn-admin-ref/src/assets/brand-icons/icon-telegram.tsx +25 -0
  65. package/.shadcn-admin-ref/src/assets/brand-icons/icon-trello.tsx +27 -0
  66. package/.shadcn-admin-ref/src/assets/brand-icons/icon-whatsapp.tsx +26 -0
  67. package/.shadcn-admin-ref/src/assets/brand-icons/icon-zoom.tsx +26 -0
  68. package/.shadcn-admin-ref/src/assets/brand-icons/index.ts +16 -0
  69. package/.shadcn-admin-ref/src/assets/clerk-full-logo.tsx +41 -0
  70. package/.shadcn-admin-ref/src/assets/clerk-logo.tsx +23 -0
  71. package/.shadcn-admin-ref/src/assets/custom/icon-dir.tsx +110 -0
  72. package/.shadcn-admin-ref/src/assets/custom/icon-layout-compact.tsx +131 -0
  73. package/.shadcn-admin-ref/src/assets/custom/icon-layout-default.tsx +124 -0
  74. package/.shadcn-admin-ref/src/assets/custom/icon-layout-full.tsx +100 -0
  75. package/.shadcn-admin-ref/src/assets/custom/icon-sidebar-floating.tsx +82 -0
  76. package/.shadcn-admin-ref/src/assets/custom/icon-sidebar-inset.tsx +58 -0
  77. package/.shadcn-admin-ref/src/assets/custom/icon-sidebar-sidebar.tsx +53 -0
  78. package/.shadcn-admin-ref/src/assets/custom/icon-theme-dark.tsx +79 -0
  79. package/.shadcn-admin-ref/src/assets/custom/icon-theme-light.tsx +78 -0
  80. package/.shadcn-admin-ref/src/assets/custom/icon-theme-system.tsx +116 -0
  81. package/.shadcn-admin-ref/src/assets/logo.tsx +24 -0
  82. package/.shadcn-admin-ref/src/components/coming-soon.tsx +16 -0
  83. package/.shadcn-admin-ref/src/components/command-menu.tsx +91 -0
  84. package/.shadcn-admin-ref/src/components/config-drawer.tsx +354 -0
  85. package/.shadcn-admin-ref/src/components/confirm-dialog.tsx +67 -0
  86. package/.shadcn-admin-ref/src/components/data-table/bulk-actions.tsx +213 -0
  87. package/.shadcn-admin-ref/src/components/data-table/column-header.tsx +74 -0
  88. package/.shadcn-admin-ref/src/components/data-table/faceted-filter.tsx +146 -0
  89. package/.shadcn-admin-ref/src/components/data-table/index.ts +6 -0
  90. package/.shadcn-admin-ref/src/components/data-table/pagination.tsx +130 -0
  91. package/.shadcn-admin-ref/src/components/data-table/toolbar.tsx +85 -0
  92. package/.shadcn-admin-ref/src/components/data-table/view-options.tsx +56 -0
  93. package/.shadcn-admin-ref/src/components/date-picker.tsx +51 -0
  94. package/.shadcn-admin-ref/src/components/layout/app-sidebar.tsx +37 -0
  95. package/.shadcn-admin-ref/src/components/layout/app-title.tsx +64 -0
  96. package/.shadcn-admin-ref/src/components/layout/authenticated-layout.tsx +42 -0
  97. package/.shadcn-admin-ref/src/components/layout/data/sidebar-data.ts +205 -0
  98. package/.shadcn-admin-ref/src/components/layout/header.tsx +50 -0
  99. package/.shadcn-admin-ref/src/components/layout/main.tsx +27 -0
  100. package/.shadcn-admin-ref/src/components/layout/nav-group.tsx +185 -0
  101. package/.shadcn-admin-ref/src/components/layout/nav-user.tsx +124 -0
  102. package/.shadcn-admin-ref/src/components/layout/team-switcher.tsx +86 -0
  103. package/.shadcn-admin-ref/src/components/layout/top-nav.tsx +67 -0
  104. package/.shadcn-admin-ref/src/components/layout/types.ts +44 -0
  105. package/.shadcn-admin-ref/src/components/learn-more.tsx +44 -0
  106. package/.shadcn-admin-ref/src/components/long-text.tsx +84 -0
  107. package/.shadcn-admin-ref/src/components/navigation-progress.tsx +25 -0
  108. package/.shadcn-admin-ref/src/components/password-input.tsx +42 -0
  109. package/.shadcn-admin-ref/src/components/profile-dropdown.tsx +75 -0
  110. package/.shadcn-admin-ref/src/components/search.tsx +37 -0
  111. package/.shadcn-admin-ref/src/components/select-dropdown.tsx +62 -0
  112. package/.shadcn-admin-ref/src/components/sign-out-dialog.tsx +38 -0
  113. package/.shadcn-admin-ref/src/components/skip-to-main.tsx +10 -0
  114. package/.shadcn-admin-ref/src/components/theme-switch.tsx +58 -0
  115. package/.shadcn-admin-ref/src/components/ui/alert-dialog.tsx +154 -0
  116. package/.shadcn-admin-ref/src/components/ui/alert.tsx +65 -0
  117. package/.shadcn-admin-ref/src/components/ui/avatar.tsx +50 -0
  118. package/.shadcn-admin-ref/src/components/ui/badge.tsx +45 -0
  119. package/.shadcn-admin-ref/src/components/ui/button.tsx +58 -0
  120. package/.shadcn-admin-ref/src/components/ui/calendar.tsx +210 -0
  121. package/.shadcn-admin-ref/src/components/ui/card.tsx +91 -0
  122. package/.shadcn-admin-ref/src/components/ui/checkbox.tsx +29 -0
  123. package/.shadcn-admin-ref/src/components/ui/collapsible.tsx +31 -0
  124. package/.shadcn-admin-ref/src/components/ui/command.tsx +181 -0
  125. package/.shadcn-admin-ref/src/components/ui/dialog.tsx +142 -0
  126. package/.shadcn-admin-ref/src/components/ui/dropdown-menu.tsx +254 -0
  127. package/.shadcn-admin-ref/src/components/ui/form.tsx +164 -0
  128. package/.shadcn-admin-ref/src/components/ui/input-otp.tsx +74 -0
  129. package/.shadcn-admin-ref/src/components/ui/input.tsx +20 -0
  130. package/.shadcn-admin-ref/src/components/ui/label.tsx +23 -0
  131. package/.shadcn-admin-ref/src/components/ui/popover.tsx +45 -0
  132. package/.shadcn-admin-ref/src/components/ui/radio-group.tsx +42 -0
  133. package/.shadcn-admin-ref/src/components/ui/scroll-area.tsx +65 -0
  134. package/.shadcn-admin-ref/src/components/ui/select.tsx +182 -0
  135. package/.shadcn-admin-ref/src/components/ui/separator.tsx +25 -0
  136. package/.shadcn-admin-ref/src/components/ui/sheet.tsx +136 -0
  137. package/.shadcn-admin-ref/src/components/ui/sidebar.tsx +728 -0
  138. package/.shadcn-admin-ref/src/components/ui/skeleton.tsx +13 -0
  139. package/.shadcn-admin-ref/src/components/ui/sonner.tsx +21 -0
  140. package/.shadcn-admin-ref/src/components/ui/switch.tsx +28 -0
  141. package/.shadcn-admin-ref/src/components/ui/table.tsx +113 -0
  142. package/.shadcn-admin-ref/src/components/ui/tabs.tsx +63 -0
  143. package/.shadcn-admin-ref/src/components/ui/textarea.tsx +17 -0
  144. package/.shadcn-admin-ref/src/components/ui/tooltip.tsx +60 -0
  145. package/.shadcn-admin-ref/src/config/fonts.ts +19 -0
  146. package/.shadcn-admin-ref/src/context/direction-provider.tsx +61 -0
  147. package/.shadcn-admin-ref/src/context/font-provider.tsx +58 -0
  148. package/.shadcn-admin-ref/src/context/layout-provider.tsx +85 -0
  149. package/.shadcn-admin-ref/src/context/search-provider.tsx +46 -0
  150. package/.shadcn-admin-ref/src/context/theme-provider.tsx +110 -0
  151. package/.shadcn-admin-ref/src/features/apps/data/apps.tsx +110 -0
  152. package/.shadcn-admin-ref/src/features/apps/index.tsx +179 -0
  153. package/.shadcn-admin-ref/src/features/auth/auth-layout.tsx +19 -0
  154. package/.shadcn-admin-ref/src/features/auth/forgot-password/components/forgot-password-form.tsx +82 -0
  155. package/.shadcn-admin-ref/src/features/auth/forgot-password/index.tsx +44 -0
  156. package/.shadcn-admin-ref/src/features/auth/otp/components/otp-form.tsx +100 -0
  157. package/.shadcn-admin-ref/src/features/auth/otp/index.tsx +44 -0
  158. package/.shadcn-admin-ref/src/features/auth/sign-in/assets/dashboard-dark.png +0 -0
  159. package/.shadcn-admin-ref/src/features/auth/sign-in/assets/dashboard-light.png +0 -0
  160. package/.shadcn-admin-ref/src/features/auth/sign-in/components/user-auth-form.tsx +150 -0
  161. package/.shadcn-admin-ref/src/features/auth/sign-in/index.tsx +51 -0
  162. package/.shadcn-admin-ref/src/features/auth/sign-in/sign-in-2.tsx +69 -0
  163. package/.shadcn-admin-ref/src/features/auth/sign-up/components/sign-up-form.tsx +143 -0
  164. package/.shadcn-admin-ref/src/features/auth/sign-up/index.tsx +57 -0
  165. package/.shadcn-admin-ref/src/features/chats/components/new-chat.tsx +127 -0
  166. package/.shadcn-admin-ref/src/features/chats/data/chat-types.ts +4 -0
  167. package/.shadcn-admin-ref/src/features/chats/data/convo.json +309 -0
  168. package/.shadcn-admin-ref/src/features/chats/index.tsx +349 -0
  169. package/.shadcn-admin-ref/src/features/dashboard/components/analytics-chart.tsx +77 -0
  170. package/.shadcn-admin-ref/src/features/dashboard/components/analytics.tsx +189 -0
  171. package/.shadcn-admin-ref/src/features/dashboard/components/overview.tsx +82 -0
  172. package/.shadcn-admin-ref/src/features/dashboard/components/recent-sales.tsx +83 -0
  173. package/.shadcn-admin-ref/src/features/dashboard/index.tsx +220 -0
  174. package/.shadcn-admin-ref/src/features/errors/forbidden.tsx +25 -0
  175. package/.shadcn-admin-ref/src/features/errors/general-error.tsx +36 -0
  176. package/.shadcn-admin-ref/src/features/errors/maintenance-error.tsx +19 -0
  177. package/.shadcn-admin-ref/src/features/errors/not-found-error.tsx +25 -0
  178. package/.shadcn-admin-ref/src/features/errors/unauthorized-error.tsx +25 -0
  179. package/.shadcn-admin-ref/src/features/settings/account/account-form.tsx +173 -0
  180. package/.shadcn-admin-ref/src/features/settings/account/index.tsx +14 -0
  181. package/.shadcn-admin-ref/src/features/settings/appearance/appearance-form.tsx +162 -0
  182. package/.shadcn-admin-ref/src/features/settings/appearance/index.tsx +14 -0
  183. package/.shadcn-admin-ref/src/features/settings/components/content-section.tsx +22 -0
  184. package/.shadcn-admin-ref/src/features/settings/components/sidebar-nav.tsx +84 -0
  185. package/.shadcn-admin-ref/src/features/settings/display/display-form.tsx +121 -0
  186. package/.shadcn-admin-ref/src/features/settings/display/index.tsx +13 -0
  187. package/.shadcn-admin-ref/src/features/settings/index.tsx +74 -0
  188. package/.shadcn-admin-ref/src/features/settings/notifications/index.tsx +13 -0
  189. package/.shadcn-admin-ref/src/features/settings/notifications/notifications-form.tsx +220 -0
  190. package/.shadcn-admin-ref/src/features/settings/profile/index.tsx +13 -0
  191. package/.shadcn-admin-ref/src/features/settings/profile/profile-form.tsx +177 -0
  192. package/.shadcn-admin-ref/src/features/tasks/components/data-table-bulk-actions.tsx +193 -0
  193. package/.shadcn-admin-ref/src/features/tasks/components/data-table-row-actions.tsx +83 -0
  194. package/.shadcn-admin-ref/src/features/tasks/components/tasks-columns.tsx +123 -0
  195. package/.shadcn-admin-ref/src/features/tasks/components/tasks-dialogs.tsx +72 -0
  196. package/.shadcn-admin-ref/src/features/tasks/components/tasks-import-dialog.tsx +110 -0
  197. package/.shadcn-admin-ref/src/features/tasks/components/tasks-multi-delete-dialog.tsx +95 -0
  198. package/.shadcn-admin-ref/src/features/tasks/components/tasks-mutate-drawer.tsx +212 -0
  199. package/.shadcn-admin-ref/src/features/tasks/components/tasks-primary-buttons.tsx +21 -0
  200. package/.shadcn-admin-ref/src/features/tasks/components/tasks-provider.tsx +36 -0
  201. package/.shadcn-admin-ref/src/features/tasks/components/tasks-table.tsx +197 -0
  202. package/.shadcn-admin-ref/src/features/tasks/data/data.tsx +77 -0
  203. package/.shadcn-admin-ref/src/features/tasks/data/schema.ts +13 -0
  204. package/.shadcn-admin-ref/src/features/tasks/data/tasks.ts +29 -0
  205. package/.shadcn-admin-ref/src/features/tasks/index.tsx +41 -0
  206. package/.shadcn-admin-ref/src/features/users/components/data-table-bulk-actions.tsx +139 -0
  207. package/.shadcn-admin-ref/src/features/users/components/data-table-row-actions.tsx +63 -0
  208. package/.shadcn-admin-ref/src/features/users/components/users-action-dialog.tsx +326 -0
  209. package/.shadcn-admin-ref/src/features/users/components/users-columns.tsx +138 -0
  210. package/.shadcn-admin-ref/src/features/users/components/users-delete-dialog.tsx +81 -0
  211. package/.shadcn-admin-ref/src/features/users/components/users-dialogs.tsx +51 -0
  212. package/.shadcn-admin-ref/src/features/users/components/users-invite-dialog.tsx +150 -0
  213. package/.shadcn-admin-ref/src/features/users/components/users-multi-delete-dialog.tsx +95 -0
  214. package/.shadcn-admin-ref/src/features/users/components/users-primary-buttons.tsx +21 -0
  215. package/.shadcn-admin-ref/src/features/users/components/users-provider.tsx +36 -0
  216. package/.shadcn-admin-ref/src/features/users/components/users-table.tsx +194 -0
  217. package/.shadcn-admin-ref/src/features/users/data/data.ts +35 -0
  218. package/.shadcn-admin-ref/src/features/users/data/schema.ts +32 -0
  219. package/.shadcn-admin-ref/src/features/users/data/users.ts +33 -0
  220. package/.shadcn-admin-ref/src/features/users/index.tsx +47 -0
  221. package/.shadcn-admin-ref/src/hooks/use-dialog-state.tsx +18 -0
  222. package/.shadcn-admin-ref/src/hooks/use-mobile.tsx +19 -0
  223. package/.shadcn-admin-ref/src/hooks/use-table-url-state.ts +219 -0
  224. package/.shadcn-admin-ref/src/lib/cookies.ts +43 -0
  225. package/.shadcn-admin-ref/src/lib/handle-server-error.ts +24 -0
  226. package/.shadcn-admin-ref/src/lib/show-submitted-data.tsx +15 -0
  227. package/.shadcn-admin-ref/src/lib/utils.ts +60 -0
  228. package/.shadcn-admin-ref/src/main.tsx +107 -0
  229. package/.shadcn-admin-ref/src/routeTree.gen.ts +719 -0
  230. package/.shadcn-admin-ref/src/routes/(auth)/forgot-password.tsx +6 -0
  231. package/.shadcn-admin-ref/src/routes/(auth)/otp.tsx +6 -0
  232. package/.shadcn-admin-ref/src/routes/(auth)/sign-in-2.tsx +6 -0
  233. package/.shadcn-admin-ref/src/routes/(auth)/sign-in.tsx +12 -0
  234. package/.shadcn-admin-ref/src/routes/(auth)/sign-up.tsx +6 -0
  235. package/.shadcn-admin-ref/src/routes/(errors)/401.tsx +6 -0
  236. package/.shadcn-admin-ref/src/routes/(errors)/403.tsx +6 -0
  237. package/.shadcn-admin-ref/src/routes/(errors)/404.tsx +6 -0
  238. package/.shadcn-admin-ref/src/routes/(errors)/500.tsx +6 -0
  239. package/.shadcn-admin-ref/src/routes/(errors)/503.tsx +6 -0
  240. package/.shadcn-admin-ref/src/routes/__root.tsx +30 -0
  241. package/.shadcn-admin-ref/src/routes/_authenticated/apps/index.tsx +17 -0
  242. package/.shadcn-admin-ref/src/routes/_authenticated/chats/index.tsx +6 -0
  243. package/.shadcn-admin-ref/src/routes/_authenticated/errors/$error.tsx +45 -0
  244. package/.shadcn-admin-ref/src/routes/_authenticated/help-center/index.tsx +6 -0
  245. package/.shadcn-admin-ref/src/routes/_authenticated/index.tsx +6 -0
  246. package/.shadcn-admin-ref/src/routes/_authenticated/route.tsx +6 -0
  247. package/.shadcn-admin-ref/src/routes/_authenticated/settings/account.tsx +6 -0
  248. package/.shadcn-admin-ref/src/routes/_authenticated/settings/appearance.tsx +6 -0
  249. package/.shadcn-admin-ref/src/routes/_authenticated/settings/display.tsx +6 -0
  250. package/.shadcn-admin-ref/src/routes/_authenticated/settings/index.tsx +6 -0
  251. package/.shadcn-admin-ref/src/routes/_authenticated/settings/notifications.tsx +6 -0
  252. package/.shadcn-admin-ref/src/routes/_authenticated/settings/route.tsx +6 -0
  253. package/.shadcn-admin-ref/src/routes/_authenticated/tasks/index.tsx +23 -0
  254. package/.shadcn-admin-ref/src/routes/_authenticated/users/index.tsx +32 -0
  255. package/.shadcn-admin-ref/src/routes/clerk/(auth)/route.tsx +60 -0
  256. package/.shadcn-admin-ref/src/routes/clerk/(auth)/sign-in.tsx +14 -0
  257. package/.shadcn-admin-ref/src/routes/clerk/(auth)/sign-up.tsx +9 -0
  258. package/.shadcn-admin-ref/src/routes/clerk/_authenticated/route.tsx +6 -0
  259. package/.shadcn-admin-ref/src/routes/clerk/_authenticated/user-management.tsx +184 -0
  260. package/.shadcn-admin-ref/src/routes/clerk/route.tsx +135 -0
  261. package/.shadcn-admin-ref/src/stores/auth-store.ts +53 -0
  262. package/.shadcn-admin-ref/src/styles/index.css +87 -0
  263. package/.shadcn-admin-ref/src/styles/theme.css +102 -0
  264. package/.shadcn-admin-ref/src/tanstack-table.d.ts +10 -0
  265. package/.shadcn-admin-ref/src/vite-env.d.ts +1 -0
  266. package/.swarm/memory.db +0 -0
  267. package/.swarm/memory.db-shm +0 -0
  268. package/.swarm/memory.db-wal +0 -0
  269. package/.zyflow/cli-settings.json +30 -0
  270. package/.zyflow/db.sqlite +0 -0
  271. package/.zyflow/logs/add-gitdiagram-integration/1633-1765491505852.json +10 -0
  272. package/.zyflow/logs/add-gitdiagram-integration/1633-1765491622627.json +10 -0
  273. package/.zyflow/logs/add-gitdiagram-integration/1633-1765491794652.json +10 -0
  274. package/.zyflow/logs/add-gitdiagram-integration/1633-1765491890392.json +10 -0
  275. package/.zyflow/logs/add-gitdiagram-integration/1633-1765494002879.json +10 -0
  276. package/.zyflow/logs/add-gitdiagram-integration/1633-1765494183887.json +10 -0
  277. package/.zyflow/logs/add-gitdiagram-integration/1633-1765494342052.json +10 -0
  278. package/.zyflow/logs/add-gitdiagram-integration/1633-1765494387244.json +10 -0
  279. package/.zyflow/logs/add-gitdiagram-integration/1633-1765494387245.json +10 -0
  280. package/.zyflow/logs/add-gitdiagram-integration/1633-1765494606176.json +10 -0
  281. package/.zyflow/logs/add-gitdiagram-integration/1633-1765495967542.json +16 -0
  282. package/.zyflow/logs/add-gitdiagram-integration/1633-1765495967629.json +16 -0
  283. package/.zyflow/logs/add-gitdiagram-integration/1633-1765497861143.json +16 -0
  284. package/.zyflow/logs/add-gitdiagram-integration/1633-1765497861870.json +20 -0
  285. package/.zyflow/logs/add-gitdiagram-integration/1633-1765498021377.json +18 -0
  286. package/.zyflow/logs/add-gitdiagram-integration/1633-1765498021660.json +18 -0
  287. package/.zyflow/logs/add-gitdiagram-integration/1633-1765503255525.json +13 -0
  288. package/.zyflow/logs/add-gitdiagram-integration/1633-1765503256018.json +13 -0
  289. package/.zyflow/logs/add-gitdiagram-integration/1633-1765504009102.json +16 -0
  290. package/.zyflow/logs/add-gitdiagram-integration/1633-1765504492051.json +18 -0
  291. package/.zyflow/logs/add-gitdiagram-integration/1633-1765504946437.json +16 -0
  292. package/.zyflow/logs/add-gitdiagram-integration/1633-1765504946640.json +16 -0
  293. package/.zyflow/logs/add-gitdiagram-integration/1634-1765505950215.json +16 -0
  294. package/.zyflow/logs/add-gitdiagram-integration/1634-1765505950948.json +18 -0
  295. package/.zyflow/logs/add-gitdiagram-integration/1635-1765505971712.json +18 -0
  296. package/.zyflow/logs/add-gitdiagram-integration/1635-1765505971976.json +18 -0
  297. package/.zyflow/logs/add-gitdiagram-integration/1636-1765505986208.json +18 -0
  298. package/.zyflow/logs/add-gitdiagram-integration/1636-1765505986620.json +16 -0
  299. package/.zyflow/logs/integrate-claude-flow/3580-1765996816612.json +10 -0
  300. package/.zyflow/logs/integrate-claude-flow/3580-1766014825819.json +10 -0
  301. package/.zyflow/logs/integrate-claude-flow/3580-1766015183794.json +12 -0
  302. package/.zyflow/logs/integrate-claude-flow/3580-1766015474608.json +12 -0
  303. package/.zyflow/logs/integrate-claude-flow/3581-1766016502824.json +63 -0
  304. package/.zyflow/logs/integrate-claude-flow/3581-1766016576008.json +60 -0
  305. package/.zyflow/logs/integrate-claude-flow/3582-1766022737754.json +110 -0
  306. package/.zyflow/logs/integrate-claude-flow/3582-1766022809327.json +135 -0
  307. package/.zyflow/sessions.json +242 -0
  308. package/.zyflow/settings.json +6 -0
  309. package/.zyflow/tasks.db +0 -0
  310. package/.zyflow/tasks.db-shm +0 -0
  311. package/.zyflow/tasks.db-wal +0 -0
  312. package/.zyflow/zyflow.sqlite +0 -0
  313. package/Dockerfile +82 -0
  314. package/LICENSE +21 -0
  315. package/README.md +506 -0
  316. package/claude-flow +34 -0
  317. package/components.json +21 -0
  318. package/config/ports.ts +28 -0
  319. package/docker-compose.yml +52 -0
  320. package/eslint.config.js +34 -0
  321. package/index.html +19 -0
  322. package/logs/mcp-error.log +55 -0
  323. package/logs/mcp-out.log +0 -0
  324. package/logs/pm2-error.log +0 -0
  325. package/logs/pm2-out.log +265 -0
  326. package/logs/py-error.log +22 -0
  327. package/logs/py-out.log +0 -0
  328. package/logs/server-error.log +11000 -0
  329. package/logs/server-out.log +8117 -0
  330. package/logs/vite-error.log +404 -0
  331. package/logs/vite-out.log +311 -0
  332. package/mcp-server/agent-tools.ts +375 -0
  333. package/mcp-server/cli-models.ts +193 -0
  334. package/mcp-server/context.ts +110 -0
  335. package/mcp-server/diagram-tools.ts +341 -0
  336. package/mcp-server/index.ts +2014 -0
  337. package/mcp-server/integration-tools.ts +909 -0
  338. package/mcp-server/moai-spec-tools.ts +416 -0
  339. package/mcp-server/parser.ts +422 -0
  340. package/mcp-server/post-task-runner.ts +253 -0
  341. package/mcp-server/post-task-types.ts +426 -0
  342. package/mcp-server/quarantine-manager.ts +479 -0
  343. package/mcp-server/report-generator.ts +386 -0
  344. package/mcp-server/task-tools.ts +619 -0
  345. package/mcp-server/trigger-config.ts +288 -0
  346. package/mcp-server/trigger-router.ts +305 -0
  347. package/mcp-server/triggers/event-listener.ts +331 -0
  348. package/mcp-server/triggers/git-hooks.ts +283 -0
  349. package/mcp-server/triggers/scheduler.ts +289 -0
  350. package/mcp-server/types.ts +55 -0
  351. package/memory/claude-flow@alpha-data.json +5 -0
  352. package/nginx/zyflow.conf +144 -0
  353. package/openspec/config.yaml +78 -0
  354. package/openspec-backup.tar.gz +0 -0
  355. package/package.json +154 -0
  356. package/packages/gitdiagram-core/.claude-flow/metrics/agent-metrics.json +1 -0
  357. package/packages/gitdiagram-core/.claude-flow/metrics/performance.json +87 -0
  358. package/packages/gitdiagram-core/.claude-flow/metrics/task-metrics.json +10 -0
  359. package/packages/gitdiagram-core/package.json +41 -0
  360. package/packages/gitdiagram-core/src/file-tree.ts +272 -0
  361. package/packages/gitdiagram-core/src/generator.ts +283 -0
  362. package/packages/gitdiagram-core/src/index.ts +78 -0
  363. package/packages/gitdiagram-core/src/llm-adapter.ts +235 -0
  364. package/packages/gitdiagram-core/src/mermaid-utils.ts +304 -0
  365. package/packages/gitdiagram-core/src/prompts.ts +281 -0
  366. package/packages/zyflow-parser/package.json +34 -0
  367. package/packages/zyflow-parser/src/index.ts +26 -0
  368. package/packages/zyflow-parser/src/moai-parser.ts +603 -0
  369. package/packages/zyflow-parser/src/moai-types.ts +110 -0
  370. package/packages/zyflow-remote-plugin/.claude-flow/metrics/agent-metrics.json +1 -0
  371. package/packages/zyflow-remote-plugin/.claude-flow/metrics/performance.json +87 -0
  372. package/packages/zyflow-remote-plugin/.claude-flow/metrics/task-metrics.json +10 -0
  373. package/packages/zyflow-remote-plugin/package.json +31 -0
  374. package/packages/zyflow-remote-plugin/src/index.ts +71 -0
  375. package/packages/zyflow-remote-plugin/src/remote-config.ts +232 -0
  376. package/packages/zyflow-remote-plugin/src/router.ts +535 -0
  377. package/packages/zyflow-remote-plugin/src/ssh-config-parser.ts +123 -0
  378. package/packages/zyflow-remote-plugin/src/ssh-manager.ts +598 -0
  379. package/packages/zyflow-remote-plugin/src/types.ts +149 -0
  380. package/plugin/manifest.json +26 -0
  381. package/plugin/package.json +13 -0
  382. package/public/favicon.svg +4 -0
  383. package/server/adk/agents/error-analyzer.ts +223 -0
  384. package/server/adk/agents/fix-generator.ts +187 -0
  385. package/server/adk/agents/pr-agent.ts +264 -0
  386. package/server/adk/agents/validator.ts +187 -0
  387. package/server/adk/config.ts +43 -0
  388. package/server/adk/index.ts +69 -0
  389. package/server/adk/integration.ts +297 -0
  390. package/server/adk/orchestrator.ts +405 -0
  391. package/server/adk/tools/build-tools.ts +290 -0
  392. package/server/adk/tools/file-tools.ts +351 -0
  393. package/server/adk/tools/git-tools.ts +280 -0
  394. package/server/adk/tools/github-tools.ts +249 -0
  395. package/server/agents/agent-monitor.ts +416 -0
  396. package/server/agents/alert-integration.ts +312 -0
  397. package/server/agents/error-analyzer.ts +472 -0
  398. package/server/agents/error-detector.ts +442 -0
  399. package/server/agents/fix-generator.ts +421 -0
  400. package/server/agents/fix-validator.ts +428 -0
  401. package/server/agents/merge-policy.ts +362 -0
  402. package/server/agents/pr-workflow.ts +476 -0
  403. package/server/agents/prompts/error-analysis.ts +393 -0
  404. package/server/ai/gemini-client.ts +499 -0
  405. package/server/ai/index.ts +317 -0
  406. package/server/ai/types.ts +137 -0
  407. package/server/app.ts +3693 -0
  408. package/server/archive-manager.ts +604 -0
  409. package/server/backlog/index.ts +7 -0
  410. package/server/backlog/migration.ts +331 -0
  411. package/server/backlog/parser.ts +323 -0
  412. package/server/backlog/sync.ts +325 -0
  413. package/server/change-log.ts +868 -0
  414. package/server/claude-flow/index.ts +12 -0
  415. package/server/claude-flow/prompt-builder.ts +407 -0
  416. package/server/claude-flow/types.ts +33 -0
  417. package/server/cli-adapter/index.ts +11 -0
  418. package/server/cli-adapter/process-manager.ts +612 -0
  419. package/server/cli-adapter/profile-manager.ts +286 -0
  420. package/server/cli-adapter/routes.ts +561 -0
  421. package/server/cli-adapter/types.ts +226 -0
  422. package/server/config.d.ts +18 -0
  423. package/server/config.js +79 -0
  424. package/server/config.ts +262 -0
  425. package/server/flow-sync.ts +543 -0
  426. package/server/git/change-workflow.ts +446 -0
  427. package/server/git/commands.ts +370 -0
  428. package/server/git/github.ts +247 -0
  429. package/server/git/index.ts +1202 -0
  430. package/server/git/status.ts +322 -0
  431. package/server/index.ts +136 -0
  432. package/server/integrations/crypto.ts +142 -0
  433. package/server/integrations/db/client.ts +169 -0
  434. package/server/integrations/db/schema.ts +167 -0
  435. package/server/integrations/env-parser.ts +365 -0
  436. package/server/integrations/index.ts +101 -0
  437. package/server/integrations/keychain.ts +239 -0
  438. package/server/integrations/local/file-utils.ts +383 -0
  439. package/server/integrations/local/index.ts +64 -0
  440. package/server/integrations/local/resolver.ts +439 -0
  441. package/server/integrations/local/types.ts +122 -0
  442. package/server/integrations/routes.ts +1100 -0
  443. package/server/integrations/service-patterns.ts +771 -0
  444. package/server/integrations/services/accounts.ts +356 -0
  445. package/server/integrations/services/env-import.ts +279 -0
  446. package/server/integrations/services/projects.ts +552 -0
  447. package/server/integrations/services/system-import.ts +1110 -0
  448. package/server/migrations/ears-generator.ts +491 -0
  449. package/server/migrations/gherkin-generator.ts +605 -0
  450. package/server/migrations/index.ts +73 -0
  451. package/server/migrations/migrate-spec-format.ts +492 -0
  452. package/server/migrations/openspec-parser.ts +542 -0
  453. package/server/migrations/tag-generator.ts +474 -0
  454. package/server/moai-specs.ts +487 -0
  455. package/server/moai-watcher.ts +145 -0
  456. package/server/parser-debug.ts +37 -0
  457. package/server/parser-utils.ts +316 -0
  458. package/server/parser.d.ts +17 -0
  459. package/server/parser.js +221 -0
  460. package/server/parser.ts +342 -0
  461. package/server/remote-watcher.ts +367 -0
  462. package/server/replay-engine.ts +915 -0
  463. package/server/routes/alerts.ts +1028 -0
  464. package/server/routes/changes.ts +812 -0
  465. package/server/routes/docs.ts +898 -0
  466. package/server/routes/flow.ts +2814 -0
  467. package/server/routes/global-chat.ts +162 -0
  468. package/server/routes/leann.ts +327 -0
  469. package/server/routes/projects.ts +1282 -0
  470. package/server/routes/search.ts +266 -0
  471. package/server/routes/specs.ts +482 -0
  472. package/server/routes/webhooks.ts +579 -0
  473. package/server/server/parser.js +265 -0
  474. package/server/services/githubActionsPoller.ts +797 -0
  475. package/server/services/slackNotifier.ts +476 -0
  476. package/server/src/types/index.js +1 -0
  477. package/server/sync-tasks.ts +741 -0
  478. package/server/tasks/cli/commands.ts +269 -0
  479. package/server/tasks/cli/index.ts +152 -0
  480. package/server/tasks/core/search.ts +81 -0
  481. package/server/tasks/core/task.ts +307 -0
  482. package/server/tasks/db/client.ts +1008 -0
  483. package/server/tasks/db/schema.ts +572 -0
  484. package/server/tasks/index.ts +24 -0
  485. package/server/tasks.db +0 -0
  486. package/server/types/archive.ts +136 -0
  487. package/server/types/change-log.ts +643 -0
  488. package/server/types/spec.ts +188 -0
  489. package/server/unified-spec-scanner.ts +753 -0
  490. package/server/utils/crypto.ts +179 -0
  491. package/server/utils/webhook-verify.ts +216 -0
  492. package/server/watcher.ts +132 -0
  493. package/server/websocket.ts +99 -0
  494. package/server-output.log +6 -0
  495. package/sonar-project.properties +18 -0
  496. package/src/App.tsx +386 -0
  497. package/src/api/client.ts +346 -0
  498. package/src/api/error-interceptor.ts +366 -0
  499. package/src/api/errors.ts +123 -0
  500. package/src/api/flow.ts +233 -0
  501. package/src/api/offline-queue.ts +351 -0
  502. package/src/api/retry-logic.ts +233 -0
  503. package/src/components/OfflineModeBanner.tsx +159 -0
  504. package/src/components/SSEStatusIndicator.tsx +194 -0
  505. package/src/components/agent/AgentChat.tsx +243 -0
  506. package/src/components/agent/AgentPage.tsx +182 -0
  507. package/src/components/agent/AgentSidebar.tsx +231 -0
  508. package/src/components/agent/index.ts +7 -0
  509. package/src/components/alerts/AlertCenter.tsx +239 -0
  510. package/src/components/alerts/AlertDashboard.tsx +211 -0
  511. package/src/components/alerts/AlertDetail.tsx +474 -0
  512. package/src/components/alerts/AlertList.tsx +113 -0
  513. package/src/components/alerts/AlertSettings.tsx +336 -0
  514. package/src/components/alerts/index.ts +5 -0
  515. package/src/components/chat/ChatPanel.tsx +642 -0
  516. package/src/components/chat/index.ts +1 -0
  517. package/src/components/cli/AddCustomCLIDialog.tsx +210 -0
  518. package/src/components/cli/CLISelector.tsx +187 -0
  519. package/src/components/cli/index.ts +8 -0
  520. package/src/components/dashboard/ArchivedChangeList.tsx +102 -0
  521. package/src/components/dashboard/ArchivedChangeViewer.tsx +184 -0
  522. package/src/components/dashboard/ArchivedChangesPage.tsx +31 -0
  523. package/src/components/dashboard/ChangeList.tsx +86 -0
  524. package/src/components/dashboard/ThemeToggle.tsx +33 -0
  525. package/src/components/diagram/DiagramViewer.tsx +256 -0
  526. package/src/components/diagram/MermaidRenderer.tsx +163 -0
  527. package/src/components/diagram/ProjectDiagramTab.tsx +161 -0
  528. package/src/components/diagram/index.ts +13 -0
  529. package/src/components/errors/ErrorBoundary.tsx +276 -0
  530. package/src/components/errors/ErrorFallback.tsx +198 -0
  531. package/src/components/errors/ErrorToast.tsx +221 -0
  532. package/src/components/flow/BacklogView.tsx +1142 -0
  533. package/src/components/flow/ChangeDetail.tsx +475 -0
  534. package/src/components/flow/ChangeItem.tsx +230 -0
  535. package/src/components/flow/ChangeList.tsx +92 -0
  536. package/src/components/flow/ExecutionHistoryDialog.tsx +224 -0
  537. package/src/components/flow/FlowContent.tsx +212 -0
  538. package/src/components/flow/FlowPage.tsx +9 -0
  539. package/src/components/flow/PipelineBar.tsx +214 -0
  540. package/src/components/flow/ProjectDashboard.tsx +222 -0
  541. package/src/components/flow/SpecDetail.tsx +138 -0
  542. package/src/components/flow/SpecDetailTabs.tsx +176 -0
  543. package/src/components/flow/SpecItem.tsx +93 -0
  544. package/src/components/flow/SpecProgressBar.tsx +47 -0
  545. package/src/components/flow/StageContent.tsx +620 -0
  546. package/src/components/flow/StandaloneTasks.tsx +960 -0
  547. package/src/components/flow/TaskExecutionDialog.tsx +1204 -0
  548. package/src/components/flow/index.ts +9 -0
  549. package/src/components/flow/task-execution/AgentSlider.tsx +37 -0
  550. package/src/components/flow/task-execution/ConsensusSettings.tsx +129 -0
  551. package/src/components/flow/task-execution/ExecutionOutput.tsx +398 -0
  552. package/src/components/flow/task-execution/ModelSelector.tsx +134 -0
  553. package/src/components/flow/task-execution/ProviderSelector.tsx +137 -0
  554. package/src/components/flow/task-execution/RecommendationBanner.tsx +71 -0
  555. package/src/components/flow/task-execution/StatusBadge.tsx +43 -0
  556. package/src/components/flow/task-execution/StrategySelector.tsx +48 -0
  557. package/src/components/flow/task-execution/SwarmSummary.tsx +55 -0
  558. package/src/components/flow/task-execution/index.ts +14 -0
  559. package/src/components/flow/task-execution/types.ts +56 -0
  560. package/src/components/git/ChangeWorkflowDialog.tsx +582 -0
  561. package/src/components/git/ConflictResolutionDialog.tsx +398 -0
  562. package/src/components/git/GitBranchSelector.tsx +212 -0
  563. package/src/components/git/GitCommitDialog.tsx +254 -0
  564. package/src/components/git/GitStatusBadge.tsx +148 -0
  565. package/src/components/git/GitSyncButton.tsx +128 -0
  566. package/src/components/git/RemoteStatusBanner.tsx +143 -0
  567. package/src/components/git/index.ts +9 -0
  568. package/src/components/integrations/EnvImportDialog.tsx +524 -0
  569. package/src/components/integrations/EnvironmentDialog.tsx +227 -0
  570. package/src/components/integrations/IntegrationBadges.tsx +91 -0
  571. package/src/components/integrations/IntegrationsSettings.tsx +55 -0
  572. package/src/components/integrations/ProjectIntegrations.tsx +481 -0
  573. package/src/components/integrations/ServiceAccountDialog.tsx +422 -0
  574. package/src/components/integrations/ServiceAccountList.tsx +305 -0
  575. package/src/components/integrations/SystemImportDialog.tsx +436 -0
  576. package/src/components/integrations/TestAccountDialog.tsx +162 -0
  577. package/src/components/integrations/index.ts +6 -0
  578. package/src/components/layout/AppSidebar.tsx +284 -0
  579. package/src/components/layout/FlowSidebar.tsx +435 -0
  580. package/src/components/layout/GlobalCommandPalette.tsx +410 -0
  581. package/src/components/layout/MenuBar.tsx +227 -0
  582. package/src/components/layout/StatusBar.tsx +226 -0
  583. package/src/components/monitoring/ErrorDashboard.tsx +274 -0
  584. package/src/components/monitoring/ErrorDetailPanel.tsx +200 -0
  585. package/src/components/monitoring/ErrorFilters.tsx +219 -0
  586. package/src/components/monitoring/ErrorHistoryList.tsx +141 -0
  587. package/src/components/monitoring/ErrorStats.tsx +249 -0
  588. package/src/components/remote/RemoteFileBrowser.tsx +249 -0
  589. package/src/components/remote/RemoteServerDialog.tsx +234 -0
  590. package/src/components/remote/RemoteServerList.tsx +366 -0
  591. package/src/components/remote/index.ts +7 -0
  592. package/src/components/settings/CLISettings.tsx +522 -0
  593. package/src/components/settings/CustomCLIDialog.tsx +548 -0
  594. package/src/components/settings/IntegrationsSettings.tsx +51 -0
  595. package/src/components/settings/ProjectSettings.tsx +441 -0
  596. package/src/components/settings/ProjectsSettings.tsx +541 -0
  597. package/src/components/settings/SearchSettings.tsx +272 -0
  598. package/src/components/settings/SettingsPage.tsx +68 -0
  599. package/src/components/settings/index.ts +5 -0
  600. package/src/components/swarm/ExecutionPanel.tsx +284 -0
  601. package/src/components/swarm/LogViewer.tsx +196 -0
  602. package/src/components/swarm/ProgressIndicator.tsx +111 -0
  603. package/src/components/swarm/index.ts +3 -0
  604. package/src/components/tasks/ArchiveTable.tsx +203 -0
  605. package/src/components/tasks/KanbanBoard.tsx +264 -0
  606. package/src/components/tasks/TaskCard.tsx +138 -0
  607. package/src/components/tasks/TaskColumn.tsx +81 -0
  608. package/src/components/tasks/TaskDialog.tsx +274 -0
  609. package/src/components/tasks/index.ts +5 -0
  610. package/src/components/tasks/types.ts +43 -0
  611. package/src/components/ui/alert-dialog.tsx +154 -0
  612. package/src/components/ui/alert.tsx +65 -0
  613. package/src/components/ui/badge.tsx +45 -0
  614. package/src/components/ui/button.tsx +58 -0
  615. package/src/components/ui/card.tsx +91 -0
  616. package/src/components/ui/checkbox.tsx +29 -0
  617. package/src/components/ui/collapsible.tsx +31 -0
  618. package/src/components/ui/command.tsx +184 -0
  619. package/src/components/ui/confirm-dialog.tsx +55 -0
  620. package/src/components/ui/dialog.tsx +142 -0
  621. package/src/components/ui/dropdown-menu.tsx +254 -0
  622. package/src/components/ui/input.tsx +20 -0
  623. package/src/components/ui/label.tsx +22 -0
  624. package/src/components/ui/markdown.tsx +100 -0
  625. package/src/components/ui/progress.tsx +27 -0
  626. package/src/components/ui/resizable-sidebar.tsx +156 -0
  627. package/src/components/ui/resizable.tsx +54 -0
  628. package/src/components/ui/right-resizable-sidebar.tsx +158 -0
  629. package/src/components/ui/scroll-area.tsx +64 -0
  630. package/src/components/ui/select.tsx +185 -0
  631. package/src/components/ui/separator.tsx +25 -0
  632. package/src/components/ui/sheet.tsx +136 -0
  633. package/src/components/ui/sidebar.tsx +726 -0
  634. package/src/components/ui/skeleton.tsx +13 -0
  635. package/src/components/ui/slider.tsx +56 -0
  636. package/src/components/ui/switch.tsx +29 -0
  637. package/src/components/ui/table.tsx +113 -0
  638. package/src/components/ui/tabs.tsx +63 -0
  639. package/src/components/ui/textarea.tsx +17 -0
  640. package/src/components/ui/tooltip.tsx +60 -0
  641. package/src/config/api.ts +83 -0
  642. package/src/constants/error-codes.ts +255 -0
  643. package/src/constants/stages.ts +27 -0
  644. package/src/context/ErrorContext.tsx +185 -0
  645. package/src/context/theme-provider.tsx +63 -0
  646. package/src/hooks/use-mobile.tsx +19 -0
  647. package/src/hooks/useAI.ts +206 -0
  648. package/src/hooks/useAgentSession.ts +431 -0
  649. package/src/hooks/useAlerts.ts +935 -0
  650. package/src/hooks/useArchivedChanges.ts +39 -0
  651. package/src/hooks/useAsyncError.ts +45 -0
  652. package/src/hooks/useChangeGit.ts +727 -0
  653. package/src/hooks/useChanges.ts +20 -0
  654. package/src/hooks/useClaude.ts +130 -0
  655. package/src/hooks/useDocs.ts +182 -0
  656. package/src/hooks/useErrorDashboard.ts +243 -0
  657. package/src/hooks/useErrorHandler.ts +150 -0
  658. package/src/hooks/useExecutionHistory.ts +55 -0
  659. package/src/hooks/useFlowChanges.ts +850 -0
  660. package/src/hooks/useFlowItems.ts +205 -0
  661. package/src/hooks/useGit.ts +427 -0
  662. package/src/hooks/useHideCompletedSpecs.ts +15 -0
  663. package/src/hooks/useInstance.ts +40 -0
  664. package/src/hooks/useIntegrations.ts +737 -0
  665. package/src/hooks/useLeannStatus.ts +93 -0
  666. package/src/hooks/useNetworkStatus.ts +167 -0
  667. package/src/hooks/useProjects.ts +353 -0
  668. package/src/hooks/useRemoteServers.ts +383 -0
  669. package/src/hooks/useSSEConnection.ts +346 -0
  670. package/src/hooks/useSpecs.ts +39 -0
  671. package/src/hooks/useSwarm.ts +462 -0
  672. package/src/hooks/useTasks.ts +137 -0
  673. package/src/hooks/useURLSync.ts +122 -0
  674. package/src/hooks/useWebSocket.ts +262 -0
  675. package/src/lib/utils.ts +121 -0
  676. package/src/main.tsx +22 -0
  677. package/src/stores/errorStore.ts +301 -0
  678. package/src/stores/offlineStore.ts +266 -0
  679. package/src/stores/sseStore.ts +247 -0
  680. package/src/stores/useHideCompletedStore.ts +21 -0
  681. package/src/styles/index.css +87 -0
  682. package/src/styles/theme.css +102 -0
  683. package/src/types/ai.ts +191 -0
  684. package/src/types/errors.ts +253 -0
  685. package/src/types/flow.ts +382 -0
  686. package/src/types/index.ts +614 -0
  687. package/src/utils/error-logger.ts +399 -0
  688. package/src/utils/error-statistics.ts +305 -0
  689. package/src/utils/logger.ts +280 -0
  690. package/src/utils/task-routing.ts +795 -0
  691. package/src/vite-env.d.ts +1 -0
  692. package/test-results/.last-run.json +4 -0
  693. package/tmp/check-docker-final.ts +48 -0
  694. package/tmp/check-docker-tasks.ts +58 -0
  695. package/tmp/check-docker-tasks2.ts +48 -0
  696. package/tmp/check-docker-tasks3.ts +42 -0
  697. package/tmp/check-mobile-tasks.ts +57 -0
  698. package/tmp/check-zywiki-tasks.ts +49 -0
  699. package/tmp/sync-mobile.ts +11 -0
  700. package/tmp/sync-zywiki.ts +68 -0
  701. package/tmp/test-docker-parser.ts +15 -0
  702. package/tmp/test-mobile-parser.ts +28 -0
  703. package/tmp/test-parser.ts +27 -0
  704. package/tmp/test-unnumbered.ts +35 -0
  705. package/zyflow.db +0 -0
@@ -0,0 +1,1202 @@
1
+ /**
2
+ * Git 서비스 메인 모듈
3
+ * OpenSpec Change: integrate-git-workflow
4
+ *
5
+ * ZyFlow에 Git 워크플로우를 통합하여 프로젝트 동기화,
6
+ * 브랜치 관리, 커밋/푸시 자동화를 지원합니다.
7
+ */
8
+
9
+ export * from './commands.js'
10
+ export * from './status.js'
11
+ export * from './change-workflow.js'
12
+ export * from './github.js'
13
+
14
+ import { Router } from 'express'
15
+ import {
16
+ gitPull,
17
+ gitPush,
18
+ gitFetch,
19
+ gitCommit,
20
+ gitAdd,
21
+ gitBranches,
22
+ gitCheckout,
23
+ gitCreateBranch,
24
+ gitDeleteBranch,
25
+ gitStash,
26
+ gitLog,
27
+ gitDiff,
28
+ gitMerge,
29
+ gitMergeAbort,
30
+ gitCheckoutConflict,
31
+ gitConflictFiles,
32
+ gitShowConflict,
33
+ gitMergeContinue,
34
+ gitSyncStatus,
35
+ } from './commands.js'
36
+ import { loadConfig, getProjectById } from '../config.js'
37
+ import { getGitStatus, checkRemoteUpdates, detectPotentialConflicts } from './status.js'
38
+ import {
39
+ startChangeBranch,
40
+ commitForChange,
41
+ pushChangeBranch,
42
+ getCurrentChangeBranch,
43
+ listChangeBranches,
44
+ checkUncommittedChanges,
45
+ hasChangeBranch,
46
+ getChangeBranchName,
47
+ type CommitMessageStage,
48
+ } from './change-workflow.js'
49
+ import {
50
+ checkGhCliAuth,
51
+ getRepoInfo,
52
+ createPRForChange,
53
+ getCurrentPR,
54
+ listPullRequests,
55
+ } from './github.js'
56
+ import { getActiveProject } from '../config.js'
57
+
58
+ export const gitRouter = Router()
59
+
60
+ // ==================== 프로젝트별 Git Sync Status API ====================
61
+
62
+ // GET /api/git/projects/sync-status - 모든 프로젝트의 Git 동기화 상태
63
+ gitRouter.get('/projects/sync-status', async (_req, res) => {
64
+ try {
65
+ const config = await loadConfig()
66
+ const results: Record<string, {
67
+ currentBranch: string
68
+ ahead: number
69
+ behind: number
70
+ hasRemote: boolean
71
+ lastFetched: number | null
72
+ } | null> = {}
73
+
74
+ // 모든 프로젝트에 대해 병렬로 상태 확인
75
+ await Promise.all(
76
+ config.projects.map(async (project) => {
77
+ try {
78
+ const status = await gitSyncStatus(project.path)
79
+ results[project.id] = status
80
+ } catch {
81
+ results[project.id] = null
82
+ }
83
+ })
84
+ )
85
+
86
+ res.json({ success: true, data: results })
87
+ } catch (error) {
88
+ console.error('Error getting projects sync status:', error)
89
+ res.status(500).json({ success: false, error: 'Failed to get projects sync status' })
90
+ }
91
+ })
92
+
93
+ // GET /api/git/projects/:projectId/sync-status - 특정 프로젝트의 Git 동기화 상태
94
+ gitRouter.get('/projects/:projectId/sync-status', async (req, res) => {
95
+ try {
96
+ const project = await getProjectById(req.params.projectId)
97
+ if (!project) {
98
+ return res.status(404).json({ success: false, error: 'Project not found' })
99
+ }
100
+
101
+ const status = await gitSyncStatus(project.path)
102
+ res.json({ success: true, data: status })
103
+ } catch (error) {
104
+ console.error('Error getting project sync status:', error)
105
+ res.status(500).json({ success: false, error: 'Failed to get project sync status' })
106
+ }
107
+ })
108
+
109
+ // POST /api/git/projects/:projectId/fetch - 특정 프로젝트 fetch
110
+ gitRouter.post('/projects/:projectId/fetch', async (req, res) => {
111
+ try {
112
+ const project = await getProjectById(req.params.projectId)
113
+ if (!project) {
114
+ return res.status(404).json({ success: false, error: 'Project not found' })
115
+ }
116
+
117
+ const result = await gitFetch(project.path, { all: true })
118
+ if (!result.success) {
119
+ return res.status(400).json({ success: false, error: result.error || result.stderr })
120
+ }
121
+
122
+ // fetch 후 상태 다시 확인
123
+ const status = await gitSyncStatus(project.path)
124
+ res.json({ success: true, data: { message: 'Fetch successful', status } })
125
+ } catch (error) {
126
+ console.error('Error fetching project:', error)
127
+ res.status(500).json({ success: false, error: 'Failed to fetch project' })
128
+ }
129
+ })
130
+
131
+ // POST /api/git/projects/:projectId/pull - 특정 프로젝트 pull
132
+ gitRouter.post('/projects/:projectId/pull', async (req, res) => {
133
+ try {
134
+ const project = await getProjectById(req.params.projectId)
135
+ if (!project) {
136
+ return res.status(404).json({ success: false, error: 'Project not found' })
137
+ }
138
+
139
+ const result = await gitPull(project.path)
140
+ if (!result.success) {
141
+ return res.status(400).json({
142
+ success: false,
143
+ error: result.error || result.stderr,
144
+ stderr: result.stderr,
145
+ })
146
+ }
147
+
148
+ // pull 후 상태 다시 확인
149
+ const status = await gitSyncStatus(project.path)
150
+ res.json({ success: true, data: { message: result.stdout || 'Already up to date.', status } })
151
+ } catch (error) {
152
+ console.error('Error pulling project:', error)
153
+ res.status(500).json({ success: false, error: 'Failed to pull project' })
154
+ }
155
+ })
156
+
157
+ // 헬퍼: 활성 프로젝트 경로 가져오기
158
+ async function getProjectPath(): Promise<string | null> {
159
+ const project = await getActiveProject()
160
+ return project?.path ?? null
161
+ }
162
+
163
+ // ==================== Git Status API ====================
164
+
165
+ // GET /api/git/status - 현재 Git 상태
166
+ gitRouter.get('/status', async (_req, res) => {
167
+ try {
168
+ const projectPath = await getProjectPath()
169
+ if (!projectPath) {
170
+ return res.status(400).json({ success: false, error: 'No active project' })
171
+ }
172
+
173
+ const status = await getGitStatus(projectPath)
174
+ res.json({ success: true, data: status })
175
+ } catch (error) {
176
+ console.error('Error getting git status:', error)
177
+ res.status(500).json({ success: false, error: 'Failed to get git status' })
178
+ }
179
+ })
180
+
181
+ // GET /api/git/remote-updates - 원격 업데이트 확인
182
+ gitRouter.get('/remote-updates', async (_req, res) => {
183
+ try {
184
+ const projectPath = await getProjectPath()
185
+ if (!projectPath) {
186
+ return res.status(400).json({ success: false, error: 'No active project' })
187
+ }
188
+
189
+ const updates = await checkRemoteUpdates(projectPath)
190
+ res.json({ success: true, data: updates })
191
+ } catch (error) {
192
+ console.error('Error checking remote updates:', error)
193
+ res.status(500).json({ success: false, error: 'Failed to check remote updates' })
194
+ }
195
+ })
196
+
197
+ // GET /api/git/potential-conflicts - 충돌 가능성 감지
198
+ gitRouter.get('/potential-conflicts', async (_req, res) => {
199
+ try {
200
+ const projectPath = await getProjectPath()
201
+ if (!projectPath) {
202
+ return res.status(400).json({ success: false, error: 'No active project' })
203
+ }
204
+
205
+ const conflicts = await detectPotentialConflicts(projectPath)
206
+ res.json({ success: true, data: conflicts })
207
+ } catch (error) {
208
+ console.error('Error detecting conflicts:', error)
209
+ res.status(500).json({ success: false, error: 'Failed to detect conflicts' })
210
+ }
211
+ })
212
+
213
+ // ==================== Git Commands API ====================
214
+
215
+ // POST /api/git/pull - Pull 실행
216
+ gitRouter.post('/pull', async (_req, res) => {
217
+ try {
218
+ const projectPath = await getProjectPath()
219
+ if (!projectPath) {
220
+ return res.status(400).json({ success: false, error: 'No active project' })
221
+ }
222
+
223
+ const result = await gitPull(projectPath)
224
+ if (!result.success) {
225
+ return res.status(400).json({
226
+ success: false,
227
+ error: result.error || result.stderr,
228
+ stderr: result.stderr,
229
+ })
230
+ }
231
+
232
+ res.json({ success: true, data: { message: result.stdout || 'Already up to date.' } })
233
+ } catch (error) {
234
+ console.error('Error pulling:', error)
235
+ res.status(500).json({ success: false, error: 'Failed to pull' })
236
+ }
237
+ })
238
+
239
+ // POST /api/git/push - Push 실행
240
+ gitRouter.post('/push', async (req, res) => {
241
+ try {
242
+ const projectPath = await getProjectPath()
243
+ if (!projectPath) {
244
+ return res.status(400).json({ success: false, error: 'No active project' })
245
+ }
246
+
247
+ const { remote, branch, force } = req.body
248
+ const result = await gitPush(projectPath, { remote, branch, force })
249
+
250
+ if (!result.success) {
251
+ return res.status(400).json({
252
+ success: false,
253
+ error: result.error || result.stderr,
254
+ stderr: result.stderr,
255
+ })
256
+ }
257
+
258
+ res.json({ success: true, data: { message: result.stdout || 'Push successful.' } })
259
+ } catch (error) {
260
+ console.error('Error pushing:', error)
261
+ res.status(500).json({ success: false, error: 'Failed to push' })
262
+ }
263
+ })
264
+
265
+ // POST /api/git/fetch - Fetch 실행
266
+ gitRouter.post('/fetch', async (req, res) => {
267
+ try {
268
+ const projectPath = await getProjectPath()
269
+ if (!projectPath) {
270
+ return res.status(400).json({ success: false, error: 'No active project' })
271
+ }
272
+
273
+ const { remote, all } = req.body
274
+ const result = await gitFetch(projectPath, { remote, all })
275
+
276
+ if (!result.success) {
277
+ return res.status(400).json({
278
+ success: false,
279
+ error: result.error || result.stderr,
280
+ })
281
+ }
282
+
283
+ res.json({ success: true, data: { message: 'Fetch successful.' } })
284
+ } catch (error) {
285
+ console.error('Error fetching:', error)
286
+ res.status(500).json({ success: false, error: 'Failed to fetch' })
287
+ }
288
+ })
289
+
290
+ // POST /api/git/commit - Commit 실행
291
+ gitRouter.post('/commit', async (req, res) => {
292
+ try {
293
+ const projectPath = await getProjectPath()
294
+ if (!projectPath) {
295
+ return res.status(400).json({ success: false, error: 'No active project' })
296
+ }
297
+
298
+ const { message, all, files } = req.body
299
+
300
+ if (!message) {
301
+ return res.status(400).json({ success: false, error: 'Commit message is required' })
302
+ }
303
+
304
+ // 파일 지정 시 먼저 add
305
+ if (files && Array.isArray(files) && files.length > 0) {
306
+ const addResult = await gitAdd(projectPath, files)
307
+ if (!addResult.success) {
308
+ return res.status(400).json({
309
+ success: false,
310
+ error: addResult.error || addResult.stderr,
311
+ })
312
+ }
313
+ }
314
+
315
+ const result = await gitCommit(projectPath, message, { all })
316
+
317
+ if (!result.success) {
318
+ return res.status(400).json({
319
+ success: false,
320
+ error: result.error || result.stderr,
321
+ stderr: result.stderr,
322
+ })
323
+ }
324
+
325
+ res.json({ success: true, data: { message: result.stdout } })
326
+ } catch (error) {
327
+ console.error('Error committing:', error)
328
+ res.status(500).json({ success: false, error: 'Failed to commit' })
329
+ }
330
+ })
331
+
332
+ // POST /api/git/add - Stage 파일
333
+ gitRouter.post('/add', async (req, res) => {
334
+ try {
335
+ const projectPath = await getProjectPath()
336
+ if (!projectPath) {
337
+ return res.status(400).json({ success: false, error: 'No active project' })
338
+ }
339
+
340
+ const { files } = req.body
341
+ const result = await gitAdd(projectPath, files || '.')
342
+
343
+ if (!result.success) {
344
+ return res.status(400).json({
345
+ success: false,
346
+ error: result.error || result.stderr,
347
+ })
348
+ }
349
+
350
+ res.json({ success: true, data: { message: 'Files staged.' } })
351
+ } catch (error) {
352
+ console.error('Error staging:', error)
353
+ res.status(500).json({ success: false, error: 'Failed to stage files' })
354
+ }
355
+ })
356
+
357
+ // POST /api/git/stash - Stash 관리
358
+ gitRouter.post('/stash', async (req, res) => {
359
+ try {
360
+ const projectPath = await getProjectPath()
361
+ if (!projectPath) {
362
+ return res.status(400).json({ success: false, error: 'No active project' })
363
+ }
364
+
365
+ const { pop, message } = req.body
366
+ const result = await gitStash(projectPath, { pop, message })
367
+
368
+ if (!result.success) {
369
+ return res.status(400).json({
370
+ success: false,
371
+ error: result.error || result.stderr,
372
+ })
373
+ }
374
+
375
+ res.json({ success: true, data: { message: result.stdout || 'Stash operation successful.' } })
376
+ } catch (error) {
377
+ console.error('Error stashing:', error)
378
+ res.status(500).json({ success: false, error: 'Failed to stash' })
379
+ }
380
+ })
381
+
382
+ // ==================== Git Branch API ====================
383
+
384
+ // GET /api/git/branches - 브랜치 목록
385
+ gitRouter.get('/branches', async (req, res) => {
386
+ try {
387
+ const projectPath = await getProjectPath()
388
+ if (!projectPath) {
389
+ return res.status(400).json({ success: false, error: 'No active project' })
390
+ }
391
+
392
+ const { all, remote } = req.query
393
+ const result = await gitBranches(projectPath, {
394
+ all: all === 'true',
395
+ remote: remote === 'true',
396
+ })
397
+
398
+ if (!result.success) {
399
+ return res.status(400).json({
400
+ success: false,
401
+ error: result.error || result.stderr,
402
+ })
403
+ }
404
+
405
+ const branches = result.stdout.split('\n').filter(Boolean)
406
+
407
+ // 현재 브랜치 확인
408
+ const status = await getGitStatus(projectPath)
409
+
410
+ res.json({
411
+ success: true,
412
+ data: {
413
+ branches,
414
+ currentBranch: status.branch,
415
+ },
416
+ })
417
+ } catch (error) {
418
+ console.error('Error listing branches:', error)
419
+ res.status(500).json({ success: false, error: 'Failed to list branches' })
420
+ }
421
+ })
422
+
423
+ // POST /api/git/checkout - 브랜치 전환
424
+ gitRouter.post('/checkout', async (req, res) => {
425
+ try {
426
+ const projectPath = await getProjectPath()
427
+ if (!projectPath) {
428
+ return res.status(400).json({ success: false, error: 'No active project' })
429
+ }
430
+
431
+ const { branch, create } = req.body
432
+
433
+ if (!branch) {
434
+ return res.status(400).json({ success: false, error: 'Branch name is required' })
435
+ }
436
+
437
+ // 변경사항 확인
438
+ const status = await getGitStatus(projectPath)
439
+ if (status.isDirty) {
440
+ return res.status(400).json({
441
+ success: false,
442
+ error: 'You have uncommitted changes. Please commit or stash them first.',
443
+ hasUncommittedChanges: true,
444
+ })
445
+ }
446
+
447
+ const result = await gitCheckout(projectPath, branch, { create })
448
+
449
+ if (!result.success) {
450
+ return res.status(400).json({
451
+ success: false,
452
+ error: result.error || result.stderr,
453
+ })
454
+ }
455
+
456
+ res.json({
457
+ success: true,
458
+ data: { message: `Switched to branch '${branch}'`, branch },
459
+ })
460
+ } catch (error) {
461
+ console.error('Error checking out:', error)
462
+ res.status(500).json({ success: false, error: 'Failed to checkout branch' })
463
+ }
464
+ })
465
+
466
+ // POST /api/git/branch - 브랜치 생성
467
+ gitRouter.post('/branch', async (req, res) => {
468
+ try {
469
+ const projectPath = await getProjectPath()
470
+ if (!projectPath) {
471
+ return res.status(400).json({ success: false, error: 'No active project' })
472
+ }
473
+
474
+ const { name, baseBranch, checkout } = req.body
475
+
476
+ if (!name) {
477
+ return res.status(400).json({ success: false, error: 'Branch name is required' })
478
+ }
479
+
480
+ const result = await gitCreateBranch(projectPath, name, baseBranch)
481
+
482
+ if (!result.success) {
483
+ return res.status(400).json({
484
+ success: false,
485
+ error: result.error || result.stderr,
486
+ })
487
+ }
488
+
489
+ // checkout 옵션이 있으면 바로 전환
490
+ if (checkout) {
491
+ const checkoutResult = await gitCheckout(projectPath, name)
492
+ if (!checkoutResult.success) {
493
+ return res.status(400).json({
494
+ success: false,
495
+ error: checkoutResult.error || checkoutResult.stderr,
496
+ })
497
+ }
498
+ }
499
+
500
+ res.json({
501
+ success: true,
502
+ data: { message: `Branch '${name}' created.`, branch: name },
503
+ })
504
+ } catch (error) {
505
+ console.error('Error creating branch:', error)
506
+ res.status(500).json({ success: false, error: 'Failed to create branch' })
507
+ }
508
+ })
509
+
510
+ // DELETE /api/git/branch/:name - 브랜치 삭제
511
+ gitRouter.delete('/branch/:name', async (req, res) => {
512
+ try {
513
+ const projectPath = await getProjectPath()
514
+ if (!projectPath) {
515
+ return res.status(400).json({ success: false, error: 'No active project' })
516
+ }
517
+
518
+ const { name } = req.params
519
+ const { force } = req.query
520
+
521
+ const result = await gitDeleteBranch(projectPath, name, { force: force === 'true' })
522
+
523
+ if (!result.success) {
524
+ return res.status(400).json({
525
+ success: false,
526
+ error: result.error || result.stderr,
527
+ })
528
+ }
529
+
530
+ res.json({ success: true, data: { message: `Branch '${name}' deleted.` } })
531
+ } catch (error) {
532
+ console.error('Error deleting branch:', error)
533
+ res.status(500).json({ success: false, error: 'Failed to delete branch' })
534
+ }
535
+ })
536
+
537
+ // ==================== Git Log & Diff API ====================
538
+
539
+ // GET /api/git/log - 커밋 로그
540
+ gitRouter.get('/log', async (req, res) => {
541
+ try {
542
+ const projectPath = await getProjectPath()
543
+ if (!projectPath) {
544
+ return res.status(400).json({ success: false, error: 'No active project' })
545
+ }
546
+
547
+ const { limit, oneline } = req.query
548
+ const result = await gitLog(projectPath, {
549
+ limit: limit ? parseInt(limit as string, 10) : 10,
550
+ oneline: oneline === 'true',
551
+ })
552
+
553
+ if (!result.success) {
554
+ return res.status(400).json({
555
+ success: false,
556
+ error: result.error || result.stderr,
557
+ })
558
+ }
559
+
560
+ const commits = result.stdout.split('\n').filter(Boolean)
561
+ res.json({ success: true, data: { commits } })
562
+ } catch (error) {
563
+ console.error('Error getting log:', error)
564
+ res.status(500).json({ success: false, error: 'Failed to get log' })
565
+ }
566
+ })
567
+
568
+ // GET /api/git/diff - Diff 조회
569
+ gitRouter.get('/diff', async (req, res) => {
570
+ try {
571
+ const projectPath = await getProjectPath()
572
+ if (!projectPath) {
573
+ return res.status(400).json({ success: false, error: 'No active project' })
574
+ }
575
+
576
+ const { staged, files } = req.query
577
+ const result = await gitDiff(projectPath, {
578
+ staged: staged === 'true',
579
+ files: files ? (files as string).split(',') : undefined,
580
+ })
581
+
582
+ if (!result.success) {
583
+ return res.status(400).json({
584
+ success: false,
585
+ error: result.error || result.stderr,
586
+ })
587
+ }
588
+
589
+ res.json({ success: true, data: { diff: result.stdout } })
590
+ } catch (error) {
591
+ console.error('Error getting diff:', error)
592
+ res.status(500).json({ success: false, error: 'Failed to get diff' })
593
+ }
594
+ })
595
+
596
+ // ==================== Change-Git Workflow API ====================
597
+
598
+ // POST /api/git/change/start - Change 브랜치 생성 및 전환
599
+ gitRouter.post('/change/start', async (req, res) => {
600
+ try {
601
+ const projectPath = await getProjectPath()
602
+ if (!projectPath) {
603
+ return res.status(400).json({ success: false, error: 'No active project' })
604
+ }
605
+
606
+ const { changeId, baseBranch, stashChanges, force } = req.body
607
+
608
+ if (!changeId) {
609
+ return res.status(400).json({ success: false, error: 'changeId is required' })
610
+ }
611
+
612
+ const result = await startChangeBranch(projectPath, changeId, {
613
+ baseBranch,
614
+ stashChanges,
615
+ force,
616
+ })
617
+
618
+ if (!result.success) {
619
+ return res.status(400).json({
620
+ success: false,
621
+ error: result.error,
622
+ hasUncommittedChanges: result.error?.includes('uncommitted changes'),
623
+ })
624
+ }
625
+
626
+ res.json({
627
+ success: true,
628
+ data: {
629
+ branch: result.branch,
630
+ created: result.created,
631
+ stashed: result.stashed,
632
+ message: result.created
633
+ ? `Created and switched to branch '${result.branch}'`
634
+ : `Switched to branch '${result.branch}'`,
635
+ },
636
+ })
637
+ } catch (error) {
638
+ console.error('Error starting change branch:', error)
639
+ res.status(500).json({ success: false, error: 'Failed to start change branch' })
640
+ }
641
+ })
642
+
643
+ // GET /api/git/change/current - 현재 Change 브랜치 정보
644
+ gitRouter.get('/change/current', async (_req, res) => {
645
+ try {
646
+ const projectPath = await getProjectPath()
647
+ if (!projectPath) {
648
+ return res.status(400).json({ success: false, error: 'No active project' })
649
+ }
650
+
651
+ const result = await getCurrentChangeBranch(projectPath)
652
+
653
+ res.json({
654
+ success: true,
655
+ data: {
656
+ isChangeBranch: result.isChangeBranch,
657
+ changeId: result.changeId,
658
+ branch: result.branch,
659
+ },
660
+ })
661
+ } catch (error) {
662
+ console.error('Error getting current change branch:', error)
663
+ res.status(500).json({ success: false, error: 'Failed to get current change branch' })
664
+ }
665
+ })
666
+
667
+ // GET /api/git/change/branches - Change 브랜치 목록
668
+ gitRouter.get('/change/branches', async (_req, res) => {
669
+ try {
670
+ const projectPath = await getProjectPath()
671
+ if (!projectPath) {
672
+ return res.status(400).json({ success: false, error: 'No active project' })
673
+ }
674
+
675
+ const result = await listChangeBranches(projectPath)
676
+
677
+ if (!result.success) {
678
+ return res.status(400).json({
679
+ success: false,
680
+ error: result.error,
681
+ })
682
+ }
683
+
684
+ res.json({
685
+ success: true,
686
+ data: { branches: result.branches },
687
+ })
688
+ } catch (error) {
689
+ console.error('Error listing change branches:', error)
690
+ res.status(500).json({ success: false, error: 'Failed to list change branches' })
691
+ }
692
+ })
693
+
694
+ // GET /api/git/change/:changeId/exists - Change 브랜치 존재 여부 확인
695
+ gitRouter.get('/change/:changeId/exists', async (req, res) => {
696
+ try {
697
+ const projectPath = await getProjectPath()
698
+ if (!projectPath) {
699
+ return res.status(400).json({ success: false, error: 'No active project' })
700
+ }
701
+
702
+ const { changeId } = req.params
703
+ const exists = await hasChangeBranch(projectPath, changeId)
704
+ const branchName = getChangeBranchName(changeId)
705
+
706
+ res.json({
707
+ success: true,
708
+ data: {
709
+ exists,
710
+ branchName,
711
+ changeId,
712
+ },
713
+ })
714
+ } catch (error) {
715
+ console.error('Error checking change branch:', error)
716
+ res.status(500).json({ success: false, error: 'Failed to check change branch' })
717
+ }
718
+ })
719
+
720
+ // POST /api/git/change/commit - Change 작업 커밋 (템플릿 적용)
721
+ gitRouter.post('/change/commit', async (req, res) => {
722
+ try {
723
+ const projectPath = await getProjectPath()
724
+ if (!projectPath) {
725
+ return res.status(400).json({ success: false, error: 'No active project' })
726
+ }
727
+
728
+ const { changeId, stage, description, files, all, template } = req.body
729
+
730
+ if (!changeId) {
731
+ return res.status(400).json({ success: false, error: 'changeId is required' })
732
+ }
733
+ if (!stage) {
734
+ return res.status(400).json({ success: false, error: 'stage is required' })
735
+ }
736
+ if (!description) {
737
+ return res.status(400).json({ success: false, error: 'description is required' })
738
+ }
739
+
740
+ const result = await commitForChange(projectPath, changeId, {
741
+ stage: stage as CommitMessageStage,
742
+ description,
743
+ files,
744
+ all,
745
+ template,
746
+ })
747
+
748
+ if (!result.success) {
749
+ return res.status(400).json({
750
+ success: false,
751
+ error: result.error || result.stderr,
752
+ stderr: result.stderr,
753
+ })
754
+ }
755
+
756
+ res.json({
757
+ success: true,
758
+ data: {
759
+ message: result.stdout,
760
+ formattedMessage: result.formattedMessage,
761
+ },
762
+ })
763
+ } catch (error) {
764
+ console.error('Error committing for change:', error)
765
+ res.status(500).json({ success: false, error: 'Failed to commit for change' })
766
+ }
767
+ })
768
+
769
+ // POST /api/git/change/push - Change 브랜치 푸시
770
+ gitRouter.post('/change/push', async (req, res) => {
771
+ try {
772
+ const projectPath = await getProjectPath()
773
+ if (!projectPath) {
774
+ return res.status(400).json({ success: false, error: 'No active project' })
775
+ }
776
+
777
+ const { changeId, setUpstream, force } = req.body
778
+
779
+ if (!changeId) {
780
+ return res.status(400).json({ success: false, error: 'changeId is required' })
781
+ }
782
+
783
+ const result = await pushChangeBranch(projectPath, changeId, {
784
+ setUpstream,
785
+ force,
786
+ })
787
+
788
+ if (!result.success) {
789
+ return res.status(400).json({
790
+ success: false,
791
+ error: result.error || result.stderr,
792
+ stderr: result.stderr,
793
+ })
794
+ }
795
+
796
+ res.json({
797
+ success: true,
798
+ data: { message: result.stdout || 'Push successful' },
799
+ })
800
+ } catch (error) {
801
+ console.error('Error pushing change branch:', error)
802
+ res.status(500).json({ success: false, error: 'Failed to push change branch' })
803
+ }
804
+ })
805
+
806
+ // GET /api/git/uncommitted - 커밋되지 않은 변경사항 확인
807
+ gitRouter.get('/uncommitted', async (_req, res) => {
808
+ try {
809
+ const projectPath = await getProjectPath()
810
+ if (!projectPath) {
811
+ return res.status(400).json({ success: false, error: 'No active project' })
812
+ }
813
+
814
+ const result = await checkUncommittedChanges(projectPath)
815
+
816
+ res.json({
817
+ success: true,
818
+ data: result,
819
+ })
820
+ } catch (error) {
821
+ console.error('Error checking uncommitted changes:', error)
822
+ res.status(500).json({ success: false, error: 'Failed to check uncommitted changes' })
823
+ }
824
+ })
825
+
826
+ // ==================== GitHub PR API ====================
827
+
828
+ // GET /api/git/github/auth - gh CLI 인증 상태 확인
829
+ gitRouter.get('/github/auth', async (_req, res) => {
830
+ try {
831
+ const projectPath = await getProjectPath()
832
+ if (!projectPath) {
833
+ return res.status(400).json({ success: false, error: 'No active project' })
834
+ }
835
+
836
+ const authStatus = await checkGhCliAuth(projectPath)
837
+ const repoInfo = authStatus.authenticated ? await getRepoInfo(projectPath) : null
838
+
839
+ res.json({
840
+ success: true,
841
+ data: {
842
+ authenticated: authStatus.authenticated,
843
+ user: authStatus.user,
844
+ repo: repoInfo,
845
+ error: authStatus.error,
846
+ },
847
+ })
848
+ } catch (error) {
849
+ console.error('Error checking GitHub auth:', error)
850
+ res.status(500).json({ success: false, error: 'Failed to check GitHub auth' })
851
+ }
852
+ })
853
+
854
+ // GET /api/git/github/pr/current - 현재 브랜치의 PR 정보
855
+ gitRouter.get('/github/pr/current', async (_req, res) => {
856
+ try {
857
+ const projectPath = await getProjectPath()
858
+ if (!projectPath) {
859
+ return res.status(400).json({ success: false, error: 'No active project' })
860
+ }
861
+
862
+ const pr = await getCurrentPR(projectPath)
863
+
864
+ res.json({
865
+ success: true,
866
+ data: { pr },
867
+ })
868
+ } catch (error) {
869
+ console.error('Error getting current PR:', error)
870
+ res.status(500).json({ success: false, error: 'Failed to get current PR' })
871
+ }
872
+ })
873
+
874
+ // GET /api/git/github/pr/list - PR 목록 조회
875
+ gitRouter.get('/github/pr/list', async (req, res) => {
876
+ try {
877
+ const projectPath = await getProjectPath()
878
+ if (!projectPath) {
879
+ return res.status(400).json({ success: false, error: 'No active project' })
880
+ }
881
+
882
+ const { state, limit } = req.query
883
+ const result = await listPullRequests(projectPath, {
884
+ state: state as 'open' | 'closed' | 'all',
885
+ limit: limit ? parseInt(limit as string, 10) : 10,
886
+ })
887
+
888
+ if (!result.success) {
889
+ return res.status(400).json({ success: false, error: result.error })
890
+ }
891
+
892
+ res.json({
893
+ success: true,
894
+ data: { prs: result.prs },
895
+ })
896
+ } catch (error) {
897
+ console.error('Error listing PRs:', error)
898
+ res.status(500).json({ success: false, error: 'Failed to list PRs' })
899
+ }
900
+ })
901
+
902
+ // POST /api/git/github/pr/create - Change에서 PR 생성
903
+ gitRouter.post('/github/pr/create', async (req, res) => {
904
+ try {
905
+ const projectPath = await getProjectPath()
906
+ if (!projectPath) {
907
+ return res.status(400).json({ success: false, error: 'No active project' })
908
+ }
909
+
910
+ const { changeId, changeTitle, baseBranch, draft, description } = req.body
911
+
912
+ if (!changeId || !changeTitle) {
913
+ return res.status(400).json({
914
+ success: false,
915
+ error: 'changeId and changeTitle are required',
916
+ })
917
+ }
918
+
919
+ const result = await createPRForChange(projectPath, changeId, changeTitle, {
920
+ baseBranch,
921
+ draft,
922
+ description,
923
+ })
924
+
925
+ if (!result.success) {
926
+ return res.status(400).json({
927
+ success: false,
928
+ error: result.error,
929
+ })
930
+ }
931
+
932
+ res.json({
933
+ success: true,
934
+ data: {
935
+ pr: result.pr,
936
+ url: result.url,
937
+ },
938
+ })
939
+ } catch (error) {
940
+ console.error('Error creating PR:', error)
941
+ res.status(500).json({ success: false, error: 'Failed to create PR' })
942
+ }
943
+ })
944
+
945
+ // ==================== Conflict Resolution API ====================
946
+
947
+ // GET /api/git/conflicts - 현재 충돌 파일 목록 조회
948
+ gitRouter.get('/conflicts', async (_req, res) => {
949
+ try {
950
+ const projectPath = await getProjectPath()
951
+ if (!projectPath) {
952
+ return res.status(400).json({ success: false, error: 'No active project' })
953
+ }
954
+
955
+ const result = await gitConflictFiles(projectPath)
956
+ const files = result.stdout.split('\n').filter(Boolean)
957
+ const status = await getGitStatus(projectPath)
958
+
959
+ res.json({
960
+ success: true,
961
+ data: {
962
+ hasConflicts: files.length > 0 || status.hasConflicts,
963
+ files: files.length > 0 ? files : status.conflictFiles,
964
+ },
965
+ })
966
+ } catch (error) {
967
+ console.error('Error getting conflict files:', error)
968
+ res.status(500).json({ success: false, error: 'Failed to get conflict files' })
969
+ }
970
+ })
971
+
972
+ // GET /api/git/conflicts/:file - 특정 충돌 파일 내용 조회
973
+ gitRouter.get('/conflicts/:file(*)', async (req, res) => {
974
+ try {
975
+ const projectPath = await getProjectPath()
976
+ if (!projectPath) {
977
+ return res.status(400).json({ success: false, error: 'No active project' })
978
+ }
979
+
980
+ const { file } = req.params
981
+ const result = await gitShowConflict(projectPath, file)
982
+
983
+ if (!result.success) {
984
+ return res.status(400).json({
985
+ success: false,
986
+ error: result.error || result.stderr,
987
+ })
988
+ }
989
+
990
+ res.json({
991
+ success: true,
992
+ data: {
993
+ file,
994
+ content: result.stdout,
995
+ },
996
+ })
997
+ } catch (error) {
998
+ console.error('Error getting conflict content:', error)
999
+ res.status(500).json({ success: false, error: 'Failed to get conflict content' })
1000
+ }
1001
+ })
1002
+
1003
+ // POST /api/git/conflicts/resolve - 충돌 파일 해결 (ours/theirs 선택)
1004
+ gitRouter.post('/conflicts/resolve', async (req, res) => {
1005
+ try {
1006
+ const projectPath = await getProjectPath()
1007
+ if (!projectPath) {
1008
+ return res.status(400).json({ success: false, error: 'No active project' })
1009
+ }
1010
+
1011
+ const { file, strategy } = req.body
1012
+
1013
+ if (!file) {
1014
+ return res.status(400).json({ success: false, error: 'file is required' })
1015
+ }
1016
+ if (!strategy || !['ours', 'theirs'].includes(strategy)) {
1017
+ return res.status(400).json({
1018
+ success: false,
1019
+ error: 'strategy must be "ours" or "theirs"',
1020
+ })
1021
+ }
1022
+
1023
+ const result = await gitCheckoutConflict(projectPath, file, strategy)
1024
+
1025
+ if (!result.success) {
1026
+ return res.status(400).json({
1027
+ success: false,
1028
+ error: result.error || result.stderr,
1029
+ })
1030
+ }
1031
+
1032
+ // 해결된 파일을 staging
1033
+ const addResult = await gitAdd(projectPath, [file])
1034
+ if (!addResult.success) {
1035
+ return res.status(400).json({
1036
+ success: false,
1037
+ error: addResult.error || addResult.stderr,
1038
+ })
1039
+ }
1040
+
1041
+ res.json({
1042
+ success: true,
1043
+ data: {
1044
+ file,
1045
+ strategy,
1046
+ message: `Conflict resolved using ${strategy} version`,
1047
+ },
1048
+ })
1049
+ } catch (error) {
1050
+ console.error('Error resolving conflict:', error)
1051
+ res.status(500).json({ success: false, error: 'Failed to resolve conflict' })
1052
+ }
1053
+ })
1054
+
1055
+ // POST /api/git/conflicts/mark-resolved - 수동 편집 후 충돌 해결 마킹
1056
+ gitRouter.post('/conflicts/mark-resolved', async (req, res) => {
1057
+ try {
1058
+ const projectPath = await getProjectPath()
1059
+ if (!projectPath) {
1060
+ return res.status(400).json({ success: false, error: 'No active project' })
1061
+ }
1062
+
1063
+ const { file } = req.body
1064
+
1065
+ if (!file) {
1066
+ return res.status(400).json({ success: false, error: 'file is required' })
1067
+ }
1068
+
1069
+ // 파일을 staging 영역에 추가
1070
+ const addResult = await gitAdd(projectPath, [file])
1071
+
1072
+ if (!addResult.success) {
1073
+ return res.status(400).json({
1074
+ success: false,
1075
+ error: addResult.error || addResult.stderr,
1076
+ })
1077
+ }
1078
+
1079
+ res.json({
1080
+ success: true,
1081
+ data: {
1082
+ file,
1083
+ message: 'Conflict marked as resolved',
1084
+ },
1085
+ })
1086
+ } catch (error) {
1087
+ console.error('Error marking conflict resolved:', error)
1088
+ res.status(500).json({ success: false, error: 'Failed to mark conflict resolved' })
1089
+ }
1090
+ })
1091
+
1092
+ // POST /api/git/merge/abort - Merge 중단
1093
+ gitRouter.post('/merge/abort', async (_req, res) => {
1094
+ try {
1095
+ const projectPath = await getProjectPath()
1096
+ if (!projectPath) {
1097
+ return res.status(400).json({ success: false, error: 'No active project' })
1098
+ }
1099
+
1100
+ const result = await gitMergeAbort(projectPath)
1101
+
1102
+ if (!result.success) {
1103
+ return res.status(400).json({
1104
+ success: false,
1105
+ error: result.error || result.stderr,
1106
+ })
1107
+ }
1108
+
1109
+ res.json({
1110
+ success: true,
1111
+ data: { message: 'Merge aborted successfully' },
1112
+ })
1113
+ } catch (error) {
1114
+ console.error('Error aborting merge:', error)
1115
+ res.status(500).json({ success: false, error: 'Failed to abort merge' })
1116
+ }
1117
+ })
1118
+
1119
+ // POST /api/git/merge/continue - 충돌 해결 후 Merge 계속
1120
+ gitRouter.post('/merge/continue', async (_req, res) => {
1121
+ try {
1122
+ const projectPath = await getProjectPath()
1123
+ if (!projectPath) {
1124
+ return res.status(400).json({ success: false, error: 'No active project' })
1125
+ }
1126
+
1127
+ // 남은 충돌이 있는지 확인
1128
+ const conflictResult = await gitConflictFiles(projectPath)
1129
+ const remainingConflicts = conflictResult.stdout.split('\n').filter(Boolean)
1130
+
1131
+ if (remainingConflicts.length > 0) {
1132
+ return res.status(400).json({
1133
+ success: false,
1134
+ error: 'There are still unresolved conflicts',
1135
+ remainingConflicts,
1136
+ })
1137
+ }
1138
+
1139
+ const result = await gitMergeContinue(projectPath)
1140
+
1141
+ if (!result.success) {
1142
+ return res.status(400).json({
1143
+ success: false,
1144
+ error: result.error || result.stderr,
1145
+ })
1146
+ }
1147
+
1148
+ res.json({
1149
+ success: true,
1150
+ data: { message: 'Merge completed successfully' },
1151
+ })
1152
+ } catch (error) {
1153
+ console.error('Error continuing merge:', error)
1154
+ res.status(500).json({ success: false, error: 'Failed to continue merge' })
1155
+ }
1156
+ })
1157
+
1158
+ // POST /api/git/merge - Merge 실행
1159
+ gitRouter.post('/merge', async (req, res) => {
1160
+ try {
1161
+ const projectPath = await getProjectPath()
1162
+ if (!projectPath) {
1163
+ return res.status(400).json({ success: false, error: 'No active project' })
1164
+ }
1165
+
1166
+ const { branch, noCommit, noFf } = req.body
1167
+
1168
+ if (!branch) {
1169
+ return res.status(400).json({ success: false, error: 'branch is required' })
1170
+ }
1171
+
1172
+ const result = await gitMerge(projectPath, branch, { noCommit, noFf })
1173
+
1174
+ if (!result.success) {
1175
+ // 충돌 발생 시
1176
+ if (result.stderr?.includes('CONFLICT') || result.stdout?.includes('CONFLICT')) {
1177
+ const conflictResult = await gitConflictFiles(projectPath)
1178
+ const conflictFiles = conflictResult.stdout.split('\n').filter(Boolean)
1179
+
1180
+ return res.status(409).json({
1181
+ success: false,
1182
+ error: 'Merge conflicts detected',
1183
+ hasConflicts: true,
1184
+ conflictFiles,
1185
+ })
1186
+ }
1187
+
1188
+ return res.status(400).json({
1189
+ success: false,
1190
+ error: result.error || result.stderr,
1191
+ })
1192
+ }
1193
+
1194
+ res.json({
1195
+ success: true,
1196
+ data: { message: result.stdout || 'Merge successful' },
1197
+ })
1198
+ } catch (error) {
1199
+ console.error('Error merging:', error)
1200
+ res.status(500).json({ success: false, error: 'Failed to merge' })
1201
+ }
1202
+ })