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,342 @@
1
+ import type { TaskGroup, Task, TasksFile } from '../src/types/index.js'
2
+
3
+ /**
4
+ * Extended TaskGroup with hierarchy info for 3-level structure
5
+ * ## 1. Major Section (majorOrder=1, majorTitle="데이터베이스 및 기반")
6
+ * ### 1.1 Sub Section (majorOrder=1, subOrder=1, title="1.1 DB 스키마 확장")
7
+ * - [ ] 1.1.1 Task (taskOrder=1)
8
+ */
9
+ interface ExtendedTaskGroup extends TaskGroup {
10
+ majorOrder?: number // "## 1." -> 1
11
+ majorTitle?: string // "## 1. 데이터베이스 및 기반" -> "데이터베이스 및 기반"
12
+ subOrder?: number // "### 1.1" -> 1 (second part)
13
+ groupTitle?: string // 그룹 제목 (title과 동일하지만 명시적)
14
+ groupOrder?: number // 그룹 순서 (majorOrder와 동일하지만 명시적)
15
+ }
16
+
17
+ /**
18
+ * Parse tasks.md content into structured data
19
+ *
20
+ * Supports multiple formats:
21
+ * - 3-level: "## 1. Major" > "### 1.1 Sub" > "- [ ] 1.1.1 Task"
22
+ * - 2-level: "## 1. Section" > "- [ ] Task"
23
+ * - Phase: "## Phase 0:" > "### 0.1 Sub" > "- [ ] 0.1.1 Task"
24
+ * - Plain: "## Section" > "- [ ] Task"
25
+ * - 4-level headers: "#### 1.1 Sub" treated as subsection
26
+ */
27
+ export function parseTasksFile(changeId: string, content: string): TasksFile {
28
+ return parseTasksFileOriginal(changeId, content)
29
+ }
30
+
31
+ /**
32
+ * 기존 파서 로직 (fallback용)
33
+ */
34
+ function parseTasksFileOriginal(changeId: string, content: string): TasksFile {
35
+ const lines = content.split('\n')
36
+ const groups: ExtendedTaskGroup[] = []
37
+ let currentGroup: ExtendedTaskGroup | null = null
38
+ let currentMajorOrder = 0
39
+ let currentMajorTitle = ''
40
+ let groupCounter = 0
41
+ let taskCounter = 0
42
+ // Track if we have a pending major section without subsections
43
+ let pendingMajorGroup: ExtendedTaskGroup | null = null
44
+
45
+ for (let i = 0; i < lines.length; i++) {
46
+ const line = lines[i]
47
+ const lineNumber = i + 1
48
+
49
+ // Match major group headers: "## 1. Section Name"
50
+ const numberedGroupMatch = line.match(/^##\s+(\d+)\.\s+(.+)$/)
51
+ // Match phase format: "## Phase 0: Section Name"
52
+ const phaseGroupMatch = line.match(/^##\s+Phase\s+(\d+):\s*(.+)$/i)
53
+ // Match plain format: "## Section Name" (not starting with #)
54
+ const plainGroupMatch = line.match(/^##\s+([^#].*)$/)
55
+
56
+ // Match subsection headers: "### 1.1 Subsection" or "#### 1.1 Subsection"
57
+ const subsectionMatch = line.match(/^#{3,4}\s+([\d.]+)\s+(.+)$/)
58
+ // Match plain subsection: "### Subsection Name" (no number)
59
+ const plainSubsectionMatch = line.match(/^###\s+([^#\d].*)$/)
60
+
61
+ if (numberedGroupMatch) {
62
+ // Flush pending major group if it has tasks
63
+ if (pendingMajorGroup && pendingMajorGroup.tasks.length > 0) {
64
+ groups.push(pendingMajorGroup)
65
+ }
66
+
67
+ currentMajorOrder = parseInt(numberedGroupMatch[1])
68
+ currentMajorTitle = numberedGroupMatch[2].trim()
69
+
70
+ // Create a pending group for tasks that come directly under ##
71
+ const groupId = `group-${currentMajorOrder}`
72
+ pendingMajorGroup = {
73
+ id: groupId,
74
+ title: currentMajorTitle,
75
+ tasks: [],
76
+ majorOrder: currentMajorOrder,
77
+ majorTitle: currentMajorTitle,
78
+ subOrder: 1,
79
+ groupTitle: currentMajorTitle,
80
+ groupOrder: currentMajorOrder
81
+ }
82
+ currentGroup = pendingMajorGroup
83
+ taskCounter = 0
84
+ continue
85
+ }
86
+
87
+ if (phaseGroupMatch) {
88
+ // Flush pending major group
89
+ if (pendingMajorGroup && pendingMajorGroup.tasks.length > 0) {
90
+ groups.push(pendingMajorGroup)
91
+ }
92
+
93
+ currentMajorOrder = parseInt(phaseGroupMatch[1])
94
+ currentMajorTitle = `Phase ${phaseGroupMatch[1]}: ${phaseGroupMatch[2].trim()}`
95
+
96
+ // Create pending group for Phase
97
+ const groupId = `group-phase-${phaseGroupMatch[1]}`
98
+ pendingMajorGroup = {
99
+ id: groupId,
100
+ title: currentMajorTitle,
101
+ tasks: [],
102
+ majorOrder: currentMajorOrder,
103
+ majorTitle: currentMajorTitle,
104
+ subOrder: 1,
105
+ groupTitle: currentMajorTitle,
106
+ groupOrder: currentMajorOrder
107
+ }
108
+ currentGroup = pendingMajorGroup
109
+ taskCounter = 0
110
+ continue
111
+ }
112
+
113
+ // Subsection with number: "### 1.1 Name" or "#### 1.1 Name"
114
+ if (subsectionMatch) {
115
+ // If we have a pending major group, add it before processing subsections
116
+ if (pendingMajorGroup) {
117
+ groups.push(pendingMajorGroup)
118
+ pendingMajorGroup = null
119
+ }
120
+
121
+ const subsectionNumber = subsectionMatch[1] // "1.1" or "0.1" or "1."
122
+ const parts = subsectionNumber.split('.')
123
+ const majorNum = parseInt(parts[0]) // 1 or 0
124
+ // Handle trailing dot case: "1." splits to ["1", ""] - parseInt("") returns NaN
125
+ const subNum = parts.length > 1 && parts[1] ? parseInt(parts[1]) : 1
126
+
127
+ // Use current major info if available, otherwise derive from subsection number
128
+ const effectiveMajorOrder = currentMajorOrder !== 0 || currentMajorTitle ? currentMajorOrder : majorNum
129
+ const effectiveMajorTitle = currentMajorTitle || `Section ${majorNum}`
130
+
131
+ const groupId = `group-${subsectionNumber.replace(/\./g, '-')}`
132
+ const groupTitle = `${subsectionNumber} ${subsectionMatch[2].trim()}`
133
+
134
+ currentGroup = {
135
+ id: groupId,
136
+ title: groupTitle,
137
+ tasks: [],
138
+ majorOrder: effectiveMajorOrder,
139
+ majorTitle: effectiveMajorTitle,
140
+ subOrder: subNum,
141
+ groupTitle: groupTitle,
142
+ groupOrder: effectiveMajorOrder
143
+ }
144
+ groups.push(currentGroup)
145
+ taskCounter = 0
146
+ continue
147
+ }
148
+
149
+ // Plain subsection: "### Subsection Name" (no number)
150
+ // These are often just labels/headers without tasks (e.g., "### 준비 작업 (Week 1)")
151
+ // Don't create a group for them - just update context for any #### subsections that follow
152
+ if (plainSubsectionMatch && !subsectionMatch) {
153
+ // Flush pending major group if needed
154
+ if (pendingMajorGroup && pendingMajorGroup.tasks.length > 0) {
155
+ groups.push(pendingMajorGroup)
156
+ }
157
+ pendingMajorGroup = null
158
+
159
+ // Don't create a group - just skip this header
160
+ // Tasks that follow will be captured by #### subsections or numbered tasks
161
+ taskCounter = 0
162
+ continue
163
+ }
164
+
165
+ // Plain ## header (fallback) - "## Section Name"
166
+ if (plainGroupMatch && !numberedGroupMatch && !phaseGroupMatch) {
167
+ if (line.startsWith('# ') && !line.startsWith('## ')) continue
168
+
169
+ // Flush pending major group
170
+ if (pendingMajorGroup && pendingMajorGroup.tasks.length > 0) {
171
+ groups.push(pendingMajorGroup)
172
+ }
173
+
174
+ groupCounter++
175
+ currentMajorOrder = groupCounter
176
+ currentMajorTitle = plainGroupMatch[1].trim()
177
+
178
+ const groupId = `group-${groupCounter}`
179
+ pendingMajorGroup = {
180
+ id: groupId,
181
+ title: currentMajorTitle,
182
+ tasks: [],
183
+ majorOrder: currentMajorOrder,
184
+ majorTitle: currentMajorTitle,
185
+ subOrder: 1,
186
+ groupTitle: currentMajorTitle,
187
+ groupOrder: currentMajorOrder
188
+ }
189
+ currentGroup = pendingMajorGroup
190
+ taskCounter = 0
191
+ continue
192
+ }
193
+
194
+ // Match task items - two formats:
195
+ // 1. "- [ ] 1.1.1 Task" - numbered task
196
+ // 2. "- [ ] Task" - unnumbered task (auto-generate ID)
197
+ const numberedTaskMatch = line.match(/^-\s+\[([ xX])\]\s+([\d.]+)\s+(.+)$/)
198
+ const plainTaskMatch = line.match(/^-\s+\[([ xX])\]\s+(.+)$/)
199
+
200
+ if (numberedTaskMatch && currentGroup) {
201
+ const completed = numberedTaskMatch[1].toLowerCase() === 'x'
202
+ const taskNumber = numberedTaskMatch[2]
203
+ const taskTitle = numberedTaskMatch[3].trim()
204
+ const taskId = `task-${taskNumber.replace(/\./g, '-')}`
205
+
206
+ const task: Task = {
207
+ id: taskId,
208
+ title: taskTitle,
209
+ completed,
210
+ groupId: currentGroup.id,
211
+ lineNumber,
212
+ }
213
+
214
+ currentGroup.tasks.push(task)
215
+ taskCounter++
216
+ } else if (plainTaskMatch && currentGroup && !numberedTaskMatch) {
217
+ const completed = plainTaskMatch[1].toLowerCase() === 'x'
218
+ const taskTitle = plainTaskMatch[2].trim()
219
+ taskCounter++
220
+ const taskId = `task-${currentGroup.id}-${taskCounter}`
221
+
222
+ const task: Task = {
223
+ id: taskId,
224
+ title: taskTitle,
225
+ completed,
226
+ groupId: currentGroup.id,
227
+ lineNumber,
228
+ }
229
+
230
+ currentGroup.tasks.push(task)
231
+ }
232
+ }
233
+
234
+ // Flush any remaining pending group
235
+ if (pendingMajorGroup) {
236
+ groups.push(pendingMajorGroup)
237
+ }
238
+
239
+ return { changeId, groups }
240
+ }
241
+
242
+ /**
243
+ * Toggle task completion status in file content
244
+ */
245
+ export function toggleTaskInFile(
246
+ content: string,
247
+ taskId: string
248
+ ): { newContent: string; task: Task } {
249
+ const lines = content.split('\n')
250
+
251
+ let foundTask: Task | null = null
252
+ let currentGroupId = ''
253
+ let groupCounter = 0
254
+ let taskCounter = 0
255
+
256
+ // Check if taskId is numbered (task-1-1) or auto-generated (task-group-xxx-n)
257
+ const isNumberedTask = /^task-[\d-]+$/.test(taskId) && !taskId.includes('group')
258
+ const taskNumber = isNumberedTask
259
+ ? taskId.replace('task-', '').replace(/-/g, '.')
260
+ : null
261
+
262
+ for (let i = 0; i < lines.length; i++) {
263
+ const line = lines[i]
264
+
265
+ // Track current group - multiple formats
266
+ const numberedGroupMatch = line.match(/^##\s+(\d+)\.\s+(.+)$/)
267
+ const phaseGroupMatch = line.match(/^##\s+Phase\s+(\d+):\s*(.+)$/i)
268
+ const subsectionMatch = line.match(/^###\s+([\d.]+)\s+(.+)$/)
269
+ const plainGroupMatch = line.match(/^##\s+(.+)$/)
270
+
271
+ if (numberedGroupMatch) {
272
+ currentGroupId = `group-${numberedGroupMatch[1]}`
273
+ taskCounter = 0
274
+ } else if (phaseGroupMatch) {
275
+ currentGroupId = `group-phase-${phaseGroupMatch[1]}`
276
+ taskCounter = 0
277
+ } else if (subsectionMatch) {
278
+ currentGroupId = `group-${subsectionMatch[1].replace(/\./g, '-')}`
279
+ taskCounter = 0
280
+ } else if (plainGroupMatch && !numberedGroupMatch && !phaseGroupMatch && !line.startsWith('# ')) {
281
+ groupCounter++
282
+ currentGroupId = `group-${groupCounter}`
283
+ taskCounter = 0
284
+ }
285
+
286
+ // Try numbered task match first
287
+ const numberedTaskMatch = line.match(/^(-\s+\[)([ xX])(\]\s+)([\d.]+)(\s+.+)$/)
288
+ if (numberedTaskMatch) {
289
+ taskCounter++
290
+ if (isNumberedTask && numberedTaskMatch[4] === taskNumber) {
291
+ const wasCompleted = numberedTaskMatch[2].toLowerCase() === 'x'
292
+ const newCompleted = !wasCompleted
293
+ const newCheckmark = newCompleted ? 'x' : ' '
294
+
295
+ lines[i] = `${numberedTaskMatch[1]}${newCheckmark}${numberedTaskMatch[3]}${numberedTaskMatch[4]}${numberedTaskMatch[5]}`
296
+
297
+ foundTask = {
298
+ id: taskId,
299
+ title: numberedTaskMatch[5].trim(),
300
+ completed: newCompleted,
301
+ groupId: currentGroupId,
302
+ lineNumber: i + 1,
303
+ }
304
+ break
305
+ }
306
+ continue
307
+ }
308
+
309
+ // Try plain task match (unnumbered)
310
+ const plainTaskMatch = line.match(/^(-\s+\[)([ xX])(\]\s+)(.+)$/)
311
+ if (plainTaskMatch && currentGroupId) {
312
+ taskCounter++
313
+ const generatedTaskId = `task-${currentGroupId}-${taskCounter}`
314
+
315
+ if (!isNumberedTask && generatedTaskId === taskId) {
316
+ const wasCompleted = plainTaskMatch[2].toLowerCase() === 'x'
317
+ const newCompleted = !wasCompleted
318
+ const newCheckmark = newCompleted ? 'x' : ' '
319
+
320
+ lines[i] = `${plainTaskMatch[1]}${newCheckmark}${plainTaskMatch[3]}${plainTaskMatch[4]}`
321
+
322
+ foundTask = {
323
+ id: taskId,
324
+ title: plainTaskMatch[4].trim(),
325
+ completed: newCompleted,
326
+ groupId: currentGroupId,
327
+ lineNumber: i + 1,
328
+ }
329
+ break
330
+ }
331
+ }
332
+ }
333
+
334
+ if (!foundTask) {
335
+ throw new Error(`Task not found: ${taskId}`)
336
+ }
337
+
338
+ return {
339
+ newContent: lines.join('\n'),
340
+ task: foundTask,
341
+ }
342
+ }
@@ -0,0 +1,367 @@
1
+ /**
2
+ * Remote File Watcher for SSH projects
3
+ * 원격 프로젝트의 tasks.md 파일 변경을 폴링으로 감지하고 DB 동기화 및 WebSocket 알림
4
+ */
5
+
6
+ import { join } from 'path'
7
+ import type { WSEvent } from './websocket.js'
8
+ import { broadcast } from './websocket.js'
9
+ import { syncRemoteChangeTasksForProject } from './sync-tasks.js'
10
+
11
+ // Polling intervals (ms)
12
+ const POLL_INTERVAL_MIN = 10_000 // 10 seconds (burst mode)
13
+ const POLL_INTERVAL_DEFAULT = 30_000 // 30 seconds (normal mode)
14
+ const POLL_INTERVAL_MAX = 60_000 // 60 seconds (idle mode)
15
+ const BURST_MODE_DURATION = 120_000 // 2 minutes in burst mode after change detected
16
+ const IDLE_THRESHOLD = 300_000 // 5 minutes without changes -> idle mode
17
+
18
+ interface WatchedProject {
19
+ projectId: string
20
+ projectPath: string
21
+ serverId: string
22
+ mtimeCache: Map<string, number> // changeId -> mtime (ms)
23
+ pollInterval: number
24
+ timer: NodeJS.Timeout | null
25
+ lastChangeAt: number
26
+ lastPollAt: number
27
+ errorCount: number
28
+ }
29
+
30
+ const watchedProjects = new Map<string, WatchedProject>()
31
+
32
+ // Remote plugin functions (loaded dynamically)
33
+ let remotePlugin: {
34
+ getRemoteServerById: (serverId: string) => Promise<unknown>
35
+ listDirectory: (server: unknown, path: string) => Promise<{ entries: Array<{ name: string; type: string }> }>
36
+ readRemoteFile: (server: unknown, path: string) => Promise<string>
37
+ getSFTP: (server: unknown) => Promise<{ stat: (path: string) => Promise<{ mtime: number }> }>
38
+ } | null = null
39
+
40
+ async function loadRemotePlugin() {
41
+ if (remotePlugin) return remotePlugin
42
+
43
+ try {
44
+ const plugin = await import('@zyflow/remote-plugin')
45
+ remotePlugin = {
46
+ getRemoteServerById: plugin.getRemoteServerById,
47
+ listDirectory: plugin.listDirectory,
48
+ readRemoteFile: plugin.readRemoteFile,
49
+ getSFTP: plugin.getSFTP,
50
+ }
51
+ return remotePlugin
52
+ } catch {
53
+ console.error('[RemoteWatcher] Remote plugin not installed')
54
+ return null
55
+ }
56
+ }
57
+
58
+ /**
59
+ * Start watching a remote project for tasks.md changes
60
+ */
61
+ export async function startRemoteWatcher(
62
+ project: { id: string; path: string },
63
+ serverId: string
64
+ ): Promise<void> {
65
+ // Stop existing watcher for this project if any
66
+ if (watchedProjects.has(project.id)) {
67
+ stopRemoteWatcher(project.id)
68
+ }
69
+
70
+ const plugin = await loadRemotePlugin()
71
+ if (!plugin) {
72
+ console.log('[RemoteWatcher] Cannot start - remote plugin not available')
73
+ return
74
+ }
75
+
76
+ const state: WatchedProject = {
77
+ projectId: project.id,
78
+ projectPath: project.path,
79
+ serverId,
80
+ mtimeCache: new Map(),
81
+ pollInterval: POLL_INTERVAL_DEFAULT,
82
+ timer: null,
83
+ lastChangeAt: 0,
84
+ lastPollAt: 0,
85
+ errorCount: 0,
86
+ }
87
+
88
+ watchedProjects.set(project.id, state)
89
+
90
+ console.log(`[RemoteWatcher] Started watching project: ${project.id}`)
91
+
92
+ // Start first poll immediately
93
+ await pollRemoteChanges(state)
94
+
95
+ // Schedule next poll
96
+ scheduleNextPoll(state)
97
+ }
98
+
99
+ /**
100
+ * Stop watching a remote project
101
+ */
102
+ export function stopRemoteWatcher(projectId: string): void {
103
+ const state = watchedProjects.get(projectId)
104
+ if (state) {
105
+ if (state.timer) {
106
+ clearTimeout(state.timer)
107
+ state.timer = null
108
+ }
109
+ watchedProjects.delete(projectId)
110
+ console.log(`[RemoteWatcher] Stopped watching project: ${projectId}`)
111
+ }
112
+ }
113
+
114
+ /**
115
+ * Stop all remote watchers
116
+ */
117
+ export function stopAllRemoteWatchers(): void {
118
+ for (const [projectId] of watchedProjects) {
119
+ stopRemoteWatcher(projectId)
120
+ }
121
+ console.log('[RemoteWatcher] All watchers stopped')
122
+ }
123
+
124
+ /**
125
+ * Get status of all remote watchers
126
+ */
127
+ export function getRemoteWatcherStatus(): Array<{
128
+ projectId: string
129
+ projectPath: string
130
+ serverId: string
131
+ pollInterval: number
132
+ lastPollAt: number
133
+ lastChangeAt: number
134
+ errorCount: number
135
+ watchedChanges: number
136
+ }> {
137
+ return Array.from(watchedProjects.values()).map(state => ({
138
+ projectId: state.projectId,
139
+ projectPath: state.projectPath,
140
+ serverId: state.serverId,
141
+ pollInterval: state.pollInterval,
142
+ lastPollAt: state.lastPollAt,
143
+ lastChangeAt: state.lastChangeAt,
144
+ errorCount: state.errorCount,
145
+ watchedChanges: state.mtimeCache.size,
146
+ }))
147
+ }
148
+
149
+ /**
150
+ * Schedule the next poll
151
+ */
152
+ function scheduleNextPoll(state: WatchedProject): void {
153
+ if (state.timer) {
154
+ clearTimeout(state.timer)
155
+ }
156
+
157
+ state.timer = setTimeout(async () => {
158
+ await pollRemoteChanges(state)
159
+ scheduleNextPoll(state)
160
+ }, state.pollInterval)
161
+ }
162
+
163
+ /**
164
+ * Adjust poll interval based on activity
165
+ */
166
+ function adjustPollInterval(state: WatchedProject, changesDetected: boolean): void {
167
+ const now = Date.now()
168
+
169
+ if (changesDetected) {
170
+ // Enter burst mode
171
+ state.pollInterval = POLL_INTERVAL_MIN
172
+ state.lastChangeAt = now
173
+ } else if (state.lastChangeAt > 0 && now - state.lastChangeAt < BURST_MODE_DURATION) {
174
+ // Stay in burst mode
175
+ state.pollInterval = POLL_INTERVAL_MIN
176
+ } else if (state.lastChangeAt > 0 && now - state.lastChangeAt > IDLE_THRESHOLD) {
177
+ // Enter idle mode
178
+ state.pollInterval = POLL_INTERVAL_MAX
179
+ } else {
180
+ // Normal mode
181
+ state.pollInterval = POLL_INTERVAL_DEFAULT
182
+ }
183
+ }
184
+
185
+ /**
186
+ * Main polling logic - check remote tasks.md files for changes
187
+ */
188
+ async function pollRemoteChanges(state: WatchedProject): Promise<void> {
189
+ const plugin = await loadRemotePlugin()
190
+ if (!plugin) return
191
+
192
+ state.lastPollAt = Date.now()
193
+
194
+ try {
195
+ // Get SSH server connection
196
+ const server = await plugin.getRemoteServerById(state.serverId)
197
+ if (!server) {
198
+ throw new Error(`Server not found: ${state.serverId}`)
199
+ }
200
+
201
+ let changesDetected = false
202
+
203
+ // Get SFTP for stat operations
204
+ const sftp = await plugin.getSFTP(server)
205
+
206
+ // 1. Poll MoAI SPECs directory (.moai/specs/)
207
+ const moaiSpecsDir = join(state.projectPath, '.moai/specs')
208
+ try {
209
+ const moaiListing = await plugin.listDirectory(server, moaiSpecsDir)
210
+
211
+ for (const entry of moaiListing.entries) {
212
+ if (entry.type !== 'directory' && entry.type !== 'd' && entry.type !== 'Directory') continue
213
+ if (!entry.name.match(/^SPEC-[A-Z]+-\d+$/)) continue
214
+
215
+ const specId = entry.name
216
+ const planPath = join(moaiSpecsDir, specId, 'plan.md')
217
+ const cacheKey = `moai:${specId}`
218
+
219
+ try {
220
+ const stat = await sftp.stat(planPath)
221
+ const currentMtime = stat.mtime * 1000
222
+
223
+ const cachedMtime = state.mtimeCache.get(cacheKey)
224
+
225
+ if (cachedMtime === undefined) {
226
+ state.mtimeCache.set(cacheKey, currentMtime)
227
+ } else if (currentMtime !== cachedMtime) {
228
+ console.log(`[RemoteWatcher] Detected MoAI SPEC change in ${specId}`)
229
+ changesDetected = true
230
+ state.mtimeCache.set(cacheKey, currentMtime)
231
+
232
+ // Broadcast WebSocket event for SPEC update
233
+ const event: WSEvent = {
234
+ type: 'spec:updated' as const,
235
+ payload: {
236
+ specId,
237
+ projectPath: state.projectPath,
238
+ },
239
+ timestamp: Date.now(),
240
+ }
241
+ broadcast(event)
242
+ }
243
+ } catch {
244
+ // plan.md doesn't exist, continue
245
+ }
246
+ }
247
+ } catch {
248
+ // .moai/specs/ might not exist
249
+ }
250
+
251
+ // 2. Poll OpenSpec changes directory (openspec/changes/)
252
+ const changesDir = join(state.projectPath, 'openspec/changes')
253
+ let listing: { entries: Array<{ name: string; type: string }> }
254
+
255
+ try {
256
+ listing = await plugin.listDirectory(server, changesDir)
257
+ } catch {
258
+ // Directory might not exist - adjust interval and return
259
+ adjustPollInterval(state, changesDetected)
260
+ return
261
+ }
262
+
263
+ for (const entry of listing.entries) {
264
+ if (entry.type !== 'directory' || entry.name === 'archive') continue
265
+
266
+ const changeId = entry.name
267
+ const tasksPath = join(changesDir, changeId, 'tasks.md')
268
+
269
+ try {
270
+ // Check file mtime using SFTP stat
271
+ let currentMtime: number
272
+
273
+ try {
274
+ const stat = await sftp.stat(tasksPath)
275
+ currentMtime = stat.mtime * 1000 // Convert to ms
276
+ } catch {
277
+ continue // File doesn't exist
278
+ }
279
+
280
+ const cachedMtime = state.mtimeCache.get(changeId)
281
+
282
+ if (cachedMtime === undefined) {
283
+ // First time seeing this file - just cache it
284
+ state.mtimeCache.set(changeId, currentMtime)
285
+ } else if (currentMtime !== cachedMtime) {
286
+ // File changed!
287
+ console.log(`[RemoteWatcher] Detected change in ${changeId}`)
288
+ changesDetected = true
289
+
290
+ // Update cache
291
+ state.mtimeCache.set(changeId, currentMtime)
292
+
293
+ // Sync to database
294
+ try {
295
+ const result = await syncRemoteChangeTasksForProject(
296
+ changeId,
297
+ state.projectPath,
298
+ server,
299
+ state.projectId
300
+ )
301
+
302
+ console.log(`[RemoteWatcher] Synced ${changeId}: created=${result.tasksCreated}, updated=${result.tasksUpdated}`)
303
+
304
+ // Broadcast WebSocket event
305
+ const event: WSEvent = {
306
+ type: 'change:synced' as const,
307
+ payload: {
308
+ changeId,
309
+ projectPath: state.projectPath,
310
+ tasksCreated: result.tasksCreated,
311
+ tasksUpdated: result.tasksUpdated,
312
+ tasksArchived: 0,
313
+ },
314
+ timestamp: Date.now(),
315
+ }
316
+
317
+ broadcast(event)
318
+ } catch (syncError) {
319
+ console.error(`[RemoteWatcher] Sync error for ${changeId}:`, syncError)
320
+ }
321
+ }
322
+ } catch (fileError) {
323
+ // Individual file error - continue with others
324
+ // Don't log to avoid spam for missing files
325
+ }
326
+ }
327
+
328
+ // Reset error count on successful poll
329
+ state.errorCount = 0
330
+
331
+ // Adjust interval based on activity
332
+ adjustPollInterval(state, changesDetected)
333
+
334
+ } catch (error) {
335
+ state.errorCount++
336
+ // Exponential backoff with ceiling at 5 minutes
337
+ const backoff = Math.min(5000 * Math.pow(2, state.errorCount), 300000)
338
+
339
+ console.error(
340
+ `[RemoteWatcher] Poll error for ${state.projectId} (${state.errorCount} consecutive errors):`,
341
+ (error as any).message || error
342
+ )
343
+ console.log(`[RemoteWatcher] Next poll in ${backoff}ms`)
344
+
345
+ // Stop watcher after 5 consecutive failures
346
+ if (state.errorCount >= 5) {
347
+ console.error(
348
+ `[RemoteWatcher] Too many consecutive failures (${state.errorCount}), stopping watcher for ${state.projectId}`
349
+ )
350
+ stopRemoteWatcher(state.projectId)
351
+
352
+ // Broadcast error to UI
353
+ const event: WSEvent = {
354
+ type: 'watcher:error' as const,
355
+ payload: {
356
+ projectId: state.projectId,
357
+ error: 'Remote watcher stopped due to connection failures',
358
+ },
359
+ timestamp: Date.now(),
360
+ }
361
+ broadcast(event)
362
+ return
363
+ }
364
+
365
+ state.pollInterval = backoff
366
+ }
367
+ }