automagik-forge 0.1.11 → 0.1.13

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 (301) hide show
  1. package/.cargo/config.toml +13 -0
  2. package/.claude/commands/commit.md +376 -0
  3. package/.claude/commands/prompt.md +871 -0
  4. package/.env.example +20 -0
  5. package/.github/actions/setup-node/action.yml +29 -0
  6. package/.github/images/automagik-logo.png +0 -0
  7. package/.github/workflows/pre-release.yml +470 -0
  8. package/.github/workflows/publish.yml +145 -0
  9. package/.github/workflows/test.yml +63 -0
  10. package/.mcp.json +57 -0
  11. package/AGENT.md +40 -0
  12. package/CLAUDE.md +40 -0
  13. package/CODE-OF-CONDUCT.md +89 -0
  14. package/Cargo.toml +19 -0
  15. package/Dockerfile +43 -0
  16. package/LICENSE +201 -0
  17. package/Makefile +97 -0
  18. package/README.md +447 -143
  19. package/backend/.sqlx/query-01b7e2bac1261d8be3d03c03df3e5220590da6c31c77f161074fc62752d63881.json +12 -0
  20. package/backend/.sqlx/query-03f2b02ba6dc5ea2b3cf6b1004caea0ad6bcc10ebd63f441d321a389f026e263.json +12 -0
  21. package/backend/.sqlx/query-0923b77d137a29fc54d399a873ff15fc4af894490bc65a4d344a7575cb0d8643.json +12 -0
  22. package/backend/.sqlx/query-0f808bcdb63c5f180836e448dd64c435c51758b2fc54a52ce9e67495b1ab200e.json +68 -0
  23. package/backend/.sqlx/query-1268afe9ca849daa6722e3df7ca8e9e61f0d37052e782bb5452ab8e1018d9b63.json +12 -0
  24. package/backend/.sqlx/query-1b082630a9622f8667ee7a9aba2c2d3176019a68c6bb83d33008594821415a57.json +12 -0
  25. package/backend/.sqlx/query-1c7b06ba1e112abf6b945a2ff08a0b40ec23f3738c2e7399f067b558cf8d490e.json +12 -0
  26. package/backend/.sqlx/query-1f619f01f46859a64ded531dd0ef61abacfe62e758abe7030a6aa745140b95ca.json +104 -0
  27. package/backend/.sqlx/query-1fca1ce14b4b20205364cd1f1f45ebe1d2e30cd745e59e189d56487b5639dfbb.json +12 -0
  28. package/backend/.sqlx/query-212828320e8d871ab9d83705a040b23bcf0393dc7252177fc539a74657f578ef.json +32 -0
  29. package/backend/.sqlx/query-290ce5c152be8d36e58ff42570f9157beb07ab9e77a03ec6fc30b4f56f9b8f6b.json +56 -0
  30. package/backend/.sqlx/query-2b471d2c2e8ffbe0cd42d2a91b814c0d79f9d09200f147e3cea33ba4ce673c8a.json +68 -0
  31. package/backend/.sqlx/query-354a48c705bb9bb2048c1b7f10fcb714e23f9db82b7a4ea6932486197b2ede6a.json +92 -0
  32. package/backend/.sqlx/query-36c9e3dd10648e94b949db5c91a774ecb1e10a899ef95da74066eccedca4d8b2.json +12 -0
  33. package/backend/.sqlx/query-36e4ba7bbd81b402d5a20b6005755eafbb174c8dda442081823406ac32809a94.json +56 -0
  34. package/backend/.sqlx/query-3a5b3c98a55ca183ab20c74708e3d7e579dda37972c059e7515c4ceee4bd8dd3.json +62 -0
  35. package/backend/.sqlx/query-3d0a1cabf2a52e9d90cdfd29c509ca89aeb448d0c1d2446c65cd43db40735e86.json +62 -0
  36. package/backend/.sqlx/query-3d6bd16fbce59efe30b7f67ea342e0e4ea6d1432389c02468ad79f1f742d4031.json +56 -0
  37. package/backend/.sqlx/query-4049ca413b285a05aca6b25385e9c8185575f01e9069e4e8581aa45d713f612f.json +32 -0
  38. package/backend/.sqlx/query-412bacd3477d86369082e90f52240407abce436cb81292d42b2dbe1e5c18eea1.json +104 -0
  39. package/backend/.sqlx/query-417a8b1ff4e51de82aea0159a3b97932224dc325b23476cb84153d690227fd8b.json +62 -0
  40. package/backend/.sqlx/query-461cc1b0bb6fd909afc9dd2246e8526b3771cfbb0b22ae4b5d17b51af587b9e2.json +56 -0
  41. package/backend/.sqlx/query-58408c7a8cdeeda0bef359f1f9bd91299a339dc2b191462fc58c9736a56d5227.json +92 -0
  42. package/backend/.sqlx/query-5a886026d75d515c01f347cc203c8d99dd04c61dc468e2e4c5aa548436d13834.json +62 -0
  43. package/backend/.sqlx/query-5b902137b11022d2e1a5c4f6a9c83fec1a856c6a710aff831abd2382ede76b43.json +12 -0
  44. package/backend/.sqlx/query-5ed1238e52e59bb5f76c0f153fd99a14093f7ce2585bf9843585608f17ec575b.json +104 -0
  45. package/backend/.sqlx/query-6e8b860b14decfc2227dc57213f38442943d3fbef5c8418fd6b634c6e0f5e2ea.json +104 -0
  46. package/backend/.sqlx/query-6ec414276994c4ccb2433eaa5b1b342168557d17ddf5a52dac84cb1b59b9de8f.json +68 -0
  47. package/backend/.sqlx/query-6ecfa16d0cf825aacf233544b5baf151e9adfdca26c226ad71020d291fd802d5.json +62 -0
  48. package/backend/.sqlx/query-72509d252c39fce77520aa816cb2acbc1fb35dc2605e7be893610599b2427f2e.json +62 -0
  49. package/backend/.sqlx/query-75239b2da188f749707d77f3c1544332ca70db3d6d6743b2601dc0d167536437.json +62 -0
  50. package/backend/.sqlx/query-83d10e29f8478aff33434f9ac67068e013b888b953a2657e2bb72a6f619d04f2.json +50 -0
  51. package/backend/.sqlx/query-8610803360ea18b9b9d078a6981ea56abfbfe84e6354fc1d5ae4c622e01410ed.json +68 -0
  52. package/backend/.sqlx/query-86d03eb70eef39c59296416867f2ee66c9f7cd8b7f961fbda2f89fc0a1c442c2.json +12 -0
  53. package/backend/.sqlx/query-87d0feb5a6b442bad9c60068ea7569599cc6fc91a0e2692ecb42e93b03201b9d.json +68 -0
  54. package/backend/.sqlx/query-8a67b3b3337248f06a57bdf8a908f7ef23177431eaed82dc08c94c3e5944340e.json +12 -0
  55. package/backend/.sqlx/query-8f01ebd64bdcde6a090479f14810d73ba23020e76fd70854ac57f2da251702c3.json +12 -0
  56. package/backend/.sqlx/query-90fd607fcb2dca72239ff25e618e21e174b195991eaa33722cbf5f76da84cfab.json +62 -0
  57. package/backend/.sqlx/query-92e8bdbcd80c5ff3db7a35cf79492048803ef305cbdef0d0a1fe5dc881ca8c71.json +104 -0
  58. package/backend/.sqlx/query-93a1605f90e9672dad29b472b6ad85fa9a55ea3ffa5abcb8724b09d61be254ca.json +20 -0
  59. package/backend/.sqlx/query-9472c8fb477958167f5fae40b85ac44252468c5226b2cdd7770f027332eed6d7.json +104 -0
  60. package/backend/.sqlx/query-96036c4f9e0f48bdc5a4a4588f0c5f288ac7aaa5425cac40fc33f337e1a351f2.json +56 -0
  61. package/backend/.sqlx/query-9edb2c01e91fd0f0fe7b56e988c7ae0393150f50be3f419a981e035c0121dfc7.json +104 -0
  62. package/backend/.sqlx/query-a157cf00616f703bfba21927f1eb1c9eec2a81c02da15f66efdba0b6c375de1b.json +26 -0
  63. package/backend/.sqlx/query-a31fff84f3b8e532fd1160447d89d700f06ae08821fee00c9a5b60492b05259c.json +62 -0
  64. package/backend/.sqlx/query-a5ba908419fb3e456bdd2daca41ba06cc3212ffffb8520fc7dbbcc8b60ada314.json +12 -0
  65. package/backend/.sqlx/query-a6d2961718dbc3b1a925e549f49a159c561bef58c105529275f274b27e2eba5b.json +104 -0
  66. package/backend/.sqlx/query-a9e93d5b09b29faf66e387e4d7596a792d81e75c4d3726e83c2963e8d7c9b56f.json +104 -0
  67. package/backend/.sqlx/query-ac5247c8d7fb86e4650c4b0eb9420031614c831b7b085083bac20c1af314c538.json +12 -0
  68. package/backend/.sqlx/query-afef9467be74c411c4cb119a8b2b1aea53049877dfc30cc60b486134ba4b4c9f.json +68 -0
  69. package/backend/.sqlx/query-b2b2c6b4d0b1a347b5c4cb63c3a46a265d4db53be9554989a814b069d0af82f2.json +62 -0
  70. package/backend/.sqlx/query-c50d2ff0b12e5bcc81e371089ee2d007e233e7db93aefba4fef08e7aa68f5ab7.json +20 -0
  71. package/backend/.sqlx/query-c614e6056b244ca07f1b9d44e7edc9d5819225c6f8d9e077070c6e518a17f50b.json +12 -0
  72. package/backend/.sqlx/query-c67259be8bf4ee0cfd32167b2aa3b7fe9192809181a8171bf1c2d6df731967ae.json +12 -0
  73. package/backend/.sqlx/query-d2d0a1b985ebbca6a2b3e882a221a219f3199890fa640afc946ef1a792d6d8de.json +12 -0
  74. package/backend/.sqlx/query-d30aa5786757f32bf2b9c5fe51a45e506c71c28c5994e430d9b0546adb15ffa2.json +20 -0
  75. package/backend/.sqlx/query-d3b9ea1de1576af71b312924ce7f4ea8ae5dbe2ac138ea3b4470f2d5cd734846.json +12 -0
  76. package/backend/.sqlx/query-ed8456646fa69ddd412441955f06ff22bfb790f29466450735e0b8bb1bc4ec94.json +12 -0
  77. package/backend/Cargo.toml +71 -0
  78. package/backend/build.rs +32 -0
  79. package/backend/migrations/20250617183714_init.sql +44 -0
  80. package/backend/migrations/20250620212427_execution_processes.sql +25 -0
  81. package/backend/migrations/20250620214100_remove_stdout_stderr_from_task_attempts.sql +28 -0
  82. package/backend/migrations/20250621120000_relate_activities_to_execution_processes.sql +23 -0
  83. package/backend/migrations/20250623120000_executor_sessions.sql +17 -0
  84. package/backend/migrations/20250623130000_add_executor_type_to_execution_processes.sql +4 -0
  85. package/backend/migrations/20250625000000_add_dev_script_to_projects.sql +4 -0
  86. package/backend/migrations/20250701000000_add_branch_to_task_attempts.sql +2 -0
  87. package/backend/migrations/20250701000001_add_pr_tracking_to_task_attempts.sql +5 -0
  88. package/backend/migrations/20250701120000_add_assistant_message_to_executor_sessions.sql +2 -0
  89. package/backend/migrations/20250708000000_add_base_branch_to_task_attempts.sql +2 -0
  90. package/backend/migrations/20250709000000_add_worktree_deleted_flag.sql +2 -0
  91. package/backend/migrations/20250710000000_add_setup_completion.sql +3 -0
  92. package/backend/migrations/20250715154859_add_task_templates.sql +25 -0
  93. package/backend/migrations/20250716143725_add_default_templates.sql +174 -0
  94. package/backend/migrations/20250716161432_update_executor_names_to_kebab_case.sql +20 -0
  95. package/backend/migrations/20250716170000_add_parent_task_to_tasks.sql +7 -0
  96. package/backend/migrations/20250717000000_drop_task_attempt_activities.sql +9 -0
  97. package/backend/migrations/20250719000000_add_cleanup_script_to_projects.sql +2 -0
  98. package/backend/migrations/20250720000000_add_cleanupscript_to_process_type_constraint.sql +25 -0
  99. package/backend/migrations/20250723000000_add_wish_to_tasks.sql +7 -0
  100. package/backend/migrations/20250724000000_remove_unique_wish_constraint.sql +5 -0
  101. package/backend/scripts/toast-notification.ps1 +23 -0
  102. package/backend/sounds/abstract-sound1.wav +0 -0
  103. package/backend/sounds/abstract-sound2.wav +0 -0
  104. package/backend/sounds/abstract-sound3.wav +0 -0
  105. package/backend/sounds/abstract-sound4.wav +0 -0
  106. package/backend/sounds/cow-mooing.wav +0 -0
  107. package/backend/sounds/phone-vibration.wav +0 -0
  108. package/backend/sounds/rooster.wav +0 -0
  109. package/backend/src/app_state.rs +218 -0
  110. package/backend/src/bin/generate_types.rs +189 -0
  111. package/backend/src/bin/mcp_task_server.rs +191 -0
  112. package/backend/src/execution_monitor.rs +1193 -0
  113. package/backend/src/executor.rs +1053 -0
  114. package/backend/src/executors/amp.rs +697 -0
  115. package/backend/src/executors/ccr.rs +91 -0
  116. package/backend/src/executors/charm_opencode.rs +113 -0
  117. package/backend/src/executors/claude.rs +887 -0
  118. package/backend/src/executors/cleanup_script.rs +124 -0
  119. package/backend/src/executors/dev_server.rs +53 -0
  120. package/backend/src/executors/echo.rs +79 -0
  121. package/backend/src/executors/gemini/config.rs +67 -0
  122. package/backend/src/executors/gemini/streaming.rs +363 -0
  123. package/backend/src/executors/gemini.rs +765 -0
  124. package/backend/src/executors/mod.rs +23 -0
  125. package/backend/src/executors/opencode_ai.rs +113 -0
  126. package/backend/src/executors/setup_script.rs +130 -0
  127. package/backend/src/executors/sst_opencode/filter.rs +184 -0
  128. package/backend/src/executors/sst_opencode/tools.rs +139 -0
  129. package/backend/src/executors/sst_opencode.rs +756 -0
  130. package/backend/src/lib.rs +45 -0
  131. package/backend/src/main.rs +324 -0
  132. package/backend/src/mcp/mod.rs +1 -0
  133. package/backend/src/mcp/task_server.rs +850 -0
  134. package/backend/src/middleware/mod.rs +3 -0
  135. package/backend/src/middleware/model_loaders.rs +242 -0
  136. package/backend/src/models/api_response.rs +36 -0
  137. package/backend/src/models/config.rs +375 -0
  138. package/backend/src/models/execution_process.rs +430 -0
  139. package/backend/src/models/executor_session.rs +225 -0
  140. package/backend/src/models/mod.rs +12 -0
  141. package/backend/src/models/project.rs +356 -0
  142. package/backend/src/models/task.rs +345 -0
  143. package/backend/src/models/task_attempt.rs +1214 -0
  144. package/backend/src/models/task_template.rs +146 -0
  145. package/backend/src/openapi.rs +93 -0
  146. package/backend/src/routes/auth.rs +297 -0
  147. package/backend/src/routes/config.rs +385 -0
  148. package/backend/src/routes/filesystem.rs +228 -0
  149. package/backend/src/routes/health.rs +16 -0
  150. package/backend/src/routes/mod.rs +9 -0
  151. package/backend/src/routes/projects.rs +562 -0
  152. package/backend/src/routes/stream.rs +244 -0
  153. package/backend/src/routes/task_attempts.rs +1172 -0
  154. package/backend/src/routes/task_templates.rs +229 -0
  155. package/backend/src/routes/tasks.rs +353 -0
  156. package/backend/src/services/analytics.rs +216 -0
  157. package/backend/src/services/git_service.rs +1321 -0
  158. package/backend/src/services/github_service.rs +307 -0
  159. package/backend/src/services/mod.rs +13 -0
  160. package/backend/src/services/notification_service.rs +263 -0
  161. package/backend/src/services/pr_monitor.rs +214 -0
  162. package/backend/src/services/process_service.rs +940 -0
  163. package/backend/src/utils/path.rs +96 -0
  164. package/backend/src/utils/shell.rs +19 -0
  165. package/backend/src/utils/text.rs +24 -0
  166. package/backend/src/utils/worktree_manager.rs +578 -0
  167. package/backend/src/utils.rs +125 -0
  168. package/backend/test.db +0 -0
  169. package/build-npm-package.sh +61 -0
  170. package/dev_assets_seed/config.json +19 -0
  171. package/frontend/.eslintrc.json +25 -0
  172. package/frontend/.prettierrc.json +8 -0
  173. package/frontend/components.json +17 -0
  174. package/frontend/index.html +19 -0
  175. package/frontend/package-lock.json +7321 -0
  176. package/frontend/package.json +61 -0
  177. package/frontend/postcss.config.js +6 -0
  178. package/frontend/public/android-chrome-192x192.png +0 -0
  179. package/frontend/public/android-chrome-512x512.png +0 -0
  180. package/frontend/public/apple-touch-icon.png +0 -0
  181. package/frontend/public/automagik-forge-logo-dark.svg +3 -0
  182. package/frontend/public/automagik-forge-logo.svg +3 -0
  183. package/frontend/public/automagik-forge-screenshot-overview.png +0 -0
  184. package/frontend/public/favicon-16x16.png +0 -0
  185. package/frontend/public/favicon-32x32.png +0 -0
  186. package/frontend/public/favicon.ico +0 -0
  187. package/frontend/public/site.webmanifest +1 -0
  188. package/frontend/public/viba-kanban-favicon.png +0 -0
  189. package/frontend/src/App.tsx +157 -0
  190. package/frontend/src/components/DisclaimerDialog.tsx +106 -0
  191. package/frontend/src/components/GitHubLoginDialog.tsx +314 -0
  192. package/frontend/src/components/OnboardingDialog.tsx +185 -0
  193. package/frontend/src/components/PrivacyOptInDialog.tsx +130 -0
  194. package/frontend/src/components/ProvidePatDialog.tsx +98 -0
  195. package/frontend/src/components/TaskTemplateManager.tsx +336 -0
  196. package/frontend/src/components/config-provider.tsx +119 -0
  197. package/frontend/src/components/context/TaskDetailsContextProvider.tsx +470 -0
  198. package/frontend/src/components/context/taskDetailsContext.ts +125 -0
  199. package/frontend/src/components/keyboard-shortcuts-demo.tsx +35 -0
  200. package/frontend/src/components/layout/navbar.tsx +86 -0
  201. package/frontend/src/components/logo.tsx +44 -0
  202. package/frontend/src/components/projects/ProjectCard.tsx +155 -0
  203. package/frontend/src/components/projects/project-detail.tsx +251 -0
  204. package/frontend/src/components/projects/project-form-fields.tsx +238 -0
  205. package/frontend/src/components/projects/project-form.tsx +301 -0
  206. package/frontend/src/components/projects/project-list.tsx +200 -0
  207. package/frontend/src/components/projects/projects-page.tsx +20 -0
  208. package/frontend/src/components/tasks/BranchSelector.tsx +169 -0
  209. package/frontend/src/components/tasks/DeleteFileConfirmationDialog.tsx +94 -0
  210. package/frontend/src/components/tasks/EditorSelectionDialog.tsx +119 -0
  211. package/frontend/src/components/tasks/TaskCard.tsx +154 -0
  212. package/frontend/src/components/tasks/TaskDetails/CollapsibleToolbar.tsx +33 -0
  213. package/frontend/src/components/tasks/TaskDetails/DiffCard.tsx +109 -0
  214. package/frontend/src/components/tasks/TaskDetails/DiffChunkSection.tsx +135 -0
  215. package/frontend/src/components/tasks/TaskDetails/DiffFile.tsx +296 -0
  216. package/frontend/src/components/tasks/TaskDetails/DiffTab.tsx +32 -0
  217. package/frontend/src/components/tasks/TaskDetails/DisplayConversationEntry.tsx +392 -0
  218. package/frontend/src/components/tasks/TaskDetails/LogsTab/Conversation.tsx +256 -0
  219. package/frontend/src/components/tasks/TaskDetails/LogsTab/ConversationEntry.tsx +56 -0
  220. package/frontend/src/components/tasks/TaskDetails/LogsTab/NormalizedConversationViewer.tsx +92 -0
  221. package/frontend/src/components/tasks/TaskDetails/LogsTab/Prompt.tsx +22 -0
  222. package/frontend/src/components/tasks/TaskDetails/LogsTab/SetupScriptRunning.tsx +49 -0
  223. package/frontend/src/components/tasks/TaskDetails/LogsTab.tsx +186 -0
  224. package/frontend/src/components/tasks/TaskDetails/ProcessesTab.tsx +288 -0
  225. package/frontend/src/components/tasks/TaskDetails/RelatedTasksTab.tsx +216 -0
  226. package/frontend/src/components/tasks/TaskDetails/TabNavigation.tsx +93 -0
  227. package/frontend/src/components/tasks/TaskDetailsHeader.tsx +169 -0
  228. package/frontend/src/components/tasks/TaskDetailsPanel.tsx +126 -0
  229. package/frontend/src/components/tasks/TaskDetailsToolbar.tsx +302 -0
  230. package/frontend/src/components/tasks/TaskFollowUpSection.tsx +130 -0
  231. package/frontend/src/components/tasks/TaskFormDialog.tsx +400 -0
  232. package/frontend/src/components/tasks/TaskKanbanBoard.tsx +180 -0
  233. package/frontend/src/components/tasks/Toolbar/CreateAttempt.tsx +259 -0
  234. package/frontend/src/components/tasks/Toolbar/CreatePRDialog.tsx +243 -0
  235. package/frontend/src/components/tasks/Toolbar/CurrentAttempt.tsx +899 -0
  236. package/frontend/src/components/tasks/index.ts +2 -0
  237. package/frontend/src/components/theme-provider.tsx +82 -0
  238. package/frontend/src/components/theme-toggle.tsx +36 -0
  239. package/frontend/src/components/ui/alert.tsx +59 -0
  240. package/frontend/src/components/ui/auto-expanding-textarea.tsx +70 -0
  241. package/frontend/src/components/ui/badge.tsx +36 -0
  242. package/frontend/src/components/ui/button.tsx +56 -0
  243. package/frontend/src/components/ui/card.tsx +86 -0
  244. package/frontend/src/components/ui/checkbox.tsx +44 -0
  245. package/frontend/src/components/ui/chip.tsx +25 -0
  246. package/frontend/src/components/ui/dialog.tsx +124 -0
  247. package/frontend/src/components/ui/dropdown-menu.tsx +198 -0
  248. package/frontend/src/components/ui/file-search-textarea.tsx +292 -0
  249. package/frontend/src/components/ui/folder-picker.tsx +279 -0
  250. package/frontend/src/components/ui/input.tsx +25 -0
  251. package/frontend/src/components/ui/label.tsx +24 -0
  252. package/frontend/src/components/ui/loader.tsx +26 -0
  253. package/frontend/src/components/ui/markdown-renderer.tsx +75 -0
  254. package/frontend/src/components/ui/select.tsx +160 -0
  255. package/frontend/src/components/ui/separator.tsx +31 -0
  256. package/frontend/src/components/ui/shadcn-io/kanban/index.tsx +185 -0
  257. package/frontend/src/components/ui/table.tsx +117 -0
  258. package/frontend/src/components/ui/tabs.tsx +53 -0
  259. package/frontend/src/components/ui/textarea.tsx +22 -0
  260. package/frontend/src/components/ui/tooltip.tsx +28 -0
  261. package/frontend/src/hooks/useNormalizedConversation.ts +440 -0
  262. package/frontend/src/index.css +225 -0
  263. package/frontend/src/lib/api.ts +630 -0
  264. package/frontend/src/lib/keyboard-shortcuts.ts +266 -0
  265. package/frontend/src/lib/responsive-config.ts +70 -0
  266. package/frontend/src/lib/types.ts +39 -0
  267. package/frontend/src/lib/utils.ts +10 -0
  268. package/frontend/src/main.tsx +50 -0
  269. package/frontend/src/pages/McpServers.tsx +418 -0
  270. package/frontend/src/pages/Settings.tsx +610 -0
  271. package/frontend/src/pages/project-tasks.tsx +575 -0
  272. package/frontend/src/pages/projects.tsx +18 -0
  273. package/frontend/src/vite-env.d.ts +1 -0
  274. package/frontend/tailwind.config.js +125 -0
  275. package/frontend/tsconfig.json +26 -0
  276. package/frontend/tsconfig.node.json +10 -0
  277. package/frontend/vite.config.ts +33 -0
  278. package/npx-cli/README.md +159 -0
  279. package/npx-cli/automagik-forge-0.0.55.tgz +0 -0
  280. package/npx-cli/automagik-forge-0.1.0.tgz +0 -0
  281. package/{dist/linux-x64/automagik-forge.zip → npx-cli/automagik-forge-0.1.10.tgz} +0 -0
  282. package/npx-cli/package.json +17 -0
  283. package/npx-cli/vibe-kanban-0.0.55.tgz +0 -0
  284. package/package.json +23 -13
  285. package/pnpm-workspace.yaml +2 -0
  286. package/rust-toolchain.toml +11 -0
  287. package/rustfmt.toml +3 -0
  288. package/scripts/load-env.js +43 -0
  289. package/scripts/mcp_test.js +374 -0
  290. package/scripts/prepare-db.js +45 -0
  291. package/scripts/setup-dev-environment.js +274 -0
  292. package/scripts/start-mcp-sse.js +70 -0
  293. package/scripts/test-debug.js +32 -0
  294. package/scripts/test-mcp-sse.js +138 -0
  295. package/scripts/test-simple.js +44 -0
  296. package/scripts/test-wish-final.js +179 -0
  297. package/scripts/test-wish-system.js +221 -0
  298. package/shared/types.ts +182 -0
  299. package/test-npm-package.sh +42 -0
  300. package/dist/linux-x64/automagik-forge-mcp.zip +0 -0
  301. /package/{bin → npx-cli/bin}/cli.js +0 -0
@@ -0,0 +1,70 @@
1
+ #!/usr/bin/env node
2
+
3
+ const { spawn } = require('child_process');
4
+ const path = require('path');
5
+ const { getPorts } = require('./setup-dev-environment');
6
+ const { loadEnv } = require('./load-env');
7
+
8
+ async function startMcpSseServer() {
9
+ try {
10
+ // Load environment variables
11
+ loadEnv();
12
+
13
+ // Get allocated ports
14
+ const ports = await getPorts();
15
+
16
+ // Set environment variables
17
+ process.env.MCP_SSE_PORT = ports.mcpSse.toString();
18
+ process.env.FRONTEND_PORT = ports.frontend.toString();
19
+ process.env.BACKEND_PORT = ports.backend.toString();
20
+
21
+ const mcpBinary = path.join(__dirname, '../target/debug/mcp_task_server');
22
+
23
+ console.log(`Starting MCP SSE server on port ${ports.mcpSse}...`);
24
+
25
+ const mcpProcess = spawn(mcpBinary, ['--mcp-sse'], {
26
+ stdio: 'pipe',
27
+ env: { ...process.env }
28
+ });
29
+
30
+ mcpProcess.stdout.on('data', (data) => {
31
+ console.log(`[MCP-SSE] ${data.toString().trim()}`);
32
+ });
33
+
34
+ mcpProcess.stderr.on('data', (data) => {
35
+ console.error(`[MCP-SSE] ${data.toString().trim()}`);
36
+ });
37
+
38
+ mcpProcess.on('exit', (code) => {
39
+ if (code !== 0) {
40
+ console.warn(`MCP SSE server exited with code ${code}`);
41
+ } else {
42
+ console.log('MCP SSE server shutdown gracefully');
43
+ }
44
+ });
45
+
46
+ // Handle graceful shutdown
47
+ process.on('SIGINT', () => {
48
+ console.log('Shutting down MCP SSE server...');
49
+ mcpProcess.kill('SIGTERM');
50
+ setTimeout(() => {
51
+ mcpProcess.kill('SIGKILL');
52
+ }, 5000);
53
+ });
54
+
55
+ process.on('SIGTERM', () => {
56
+ mcpProcess.kill('SIGTERM');
57
+ });
58
+
59
+ return mcpProcess;
60
+ } catch (error) {
61
+ console.error('Failed to start MCP SSE server:', error);
62
+ process.exit(1);
63
+ }
64
+ }
65
+
66
+ if (require.main === module) {
67
+ startMcpSseServer();
68
+ }
69
+
70
+ module.exports = { startMcpSseServer };
@@ -0,0 +1,32 @@
1
+ #!/usr/bin/env node
2
+
3
+ const { spawn } = require('child_process');
4
+
5
+ console.log('🧪 Debug MCP Server...\n');
6
+
7
+ const mcpProcess = spawn('cargo', ['run', '--manifest-path', 'backend/Cargo.toml', '--', '--mcp'], {
8
+ stdio: ['pipe', 'pipe', 'pipe'],
9
+ env: { ...process.env, PORT: '8894', DISABLE_WORKTREE_ORPHAN_CLEANUP: '1' }
10
+ });
11
+
12
+ console.log('šŸ“¤ Sending initialize...');
13
+ mcpProcess.stdin.write('{"jsonrpc": "2.0", "id": 1, "method": "initialize", "params": {"protocolVersion": "2024-11-05", "capabilities": {}, "clientInfo": {"name": "test", "version": "1.0.0"}}}\n');
14
+
15
+ mcpProcess.stdout.on('data', (data) => {
16
+ console.log('šŸ“„ STDOUT:', data.toString());
17
+ });
18
+
19
+ mcpProcess.stderr.on('data', (data) => {
20
+ console.log('šŸ“„ STDERR:', data.toString());
21
+ });
22
+
23
+ mcpProcess.on('exit', (code) => {
24
+ console.log(`\nšŸ’„ Exit code: ${code}`);
25
+ process.exit(0);
26
+ });
27
+
28
+ // Timeout after 5 seconds
29
+ setTimeout(() => {
30
+ console.log('\nā° Timeout - killing process');
31
+ mcpProcess.kill();
32
+ }, 5000);
@@ -0,0 +1,138 @@
1
+ #!/usr/bin/env node
2
+
3
+ const { spawn } = require('child_process');
4
+ const path = require('path');
5
+
6
+ async function testMcpSseIntegration() {
7
+ console.log('Testing MCP SSE integration...');
8
+
9
+ // Set test environment
10
+ process.env.MCP_SSE_PORT = '8765';
11
+
12
+ const mcpBinary = path.join(__dirname, '../backend/target/debug/automagik-forge-mcp');
13
+
14
+ console.log('Starting MCP SSE server for testing...');
15
+ const mcpProcess = spawn(mcpBinary, ['--mcp-sse'], {
16
+ env: { ...process.env }
17
+ });
18
+
19
+ let serverReady = false;
20
+ let sseEndpointFound = false;
21
+
22
+ mcpProcess.stdout.on('data', (data) => {
23
+ const output = data.toString();
24
+ console.log(`[MCP-SSE] ${output.trim()}`);
25
+
26
+ // Check for SSE server startup message
27
+ if (output.includes('MCP SSE server listening')) {
28
+ serverReady = true;
29
+ sseEndpointFound = true;
30
+ console.log('āœ… SSE server started successfully');
31
+ }
32
+
33
+ // Check for STDIO server startup
34
+ if (output.includes('Starting MCP STDIO server')) {
35
+ console.log('āœ… STDIO server started successfully');
36
+ }
37
+ });
38
+
39
+ mcpProcess.stderr.on('data', (data) => {
40
+ const output = data.toString();
41
+ console.error(`[MCP-SSE ERROR] ${output.trim()}`);
42
+
43
+ // Check for compilation or dependency errors
44
+ if (output.includes('error:') || output.includes('Error:')) {
45
+ console.error('āŒ MCP server failed to start due to compilation/dependency errors');
46
+ }
47
+ });
48
+
49
+ mcpProcess.on('exit', (code) => {
50
+ if (code !== 0) {
51
+ console.error(`āŒ MCP SSE server exited with code ${code}`);
52
+ } else {
53
+ console.log('MCP SSE server exited gracefully');
54
+ }
55
+ });
56
+
57
+ // Wait for server startup
58
+ await new Promise(resolve => {
59
+ const timeout = setTimeout(() => {
60
+ console.log('Server startup timeout reached');
61
+ resolve();
62
+ }, 10000);
63
+
64
+ const checkReady = setInterval(() => {
65
+ if (serverReady) {
66
+ clearTimeout(timeout);
67
+ clearInterval(checkReady);
68
+ resolve();
69
+ }
70
+ }, 100);
71
+ });
72
+
73
+ // Test results
74
+ if (sseEndpointFound) {
75
+ console.log('āœ… MCP SSE server integration test PASSED');
76
+ console.log(' - SSE server started successfully');
77
+ console.log(' - Dual transport mode working');
78
+ console.log(' - Server accessible on http://localhost:8765/sse');
79
+ } else {
80
+ console.log('āŒ MCP SSE server integration test FAILED');
81
+ console.log(' - SSE server did not start properly');
82
+ }
83
+
84
+ // Cleanup
85
+ console.log('Cleaning up test server...');
86
+ mcpProcess.kill('SIGTERM');
87
+
88
+ setTimeout(() => {
89
+ mcpProcess.kill('SIGKILL');
90
+ }, 2000);
91
+ }
92
+
93
+ async function testDevWorkflow() {
94
+ console.log('\nTesting development workflow integration...');
95
+
96
+ // Test port allocation
97
+ const { getPorts } = require('./setup-dev-environment');
98
+
99
+ try {
100
+ const ports = await getPorts();
101
+ console.log('āœ… Port allocation working:');
102
+ console.log(` - Frontend: ${ports.frontend}`);
103
+ console.log(` - Backend: ${ports.backend}`);
104
+ console.log(` - MCP SSE: ${ports.mcpSse}`);
105
+
106
+ if (ports.mcpSse) {
107
+ console.log('āœ… MCP SSE port allocation integrated');
108
+ } else {
109
+ console.log('āŒ MCP SSE port allocation failed');
110
+ }
111
+ } catch (error) {
112
+ console.error('āŒ Port allocation test failed:', error.message);
113
+ }
114
+ }
115
+
116
+ async function main() {
117
+ console.log('🧪 Running MCP SSE Integration Tests\n');
118
+
119
+ // Test 1: SSE server functionality
120
+ await testMcpSseIntegration();
121
+
122
+ // Test 2: Development workflow integration
123
+ await testDevWorkflow();
124
+
125
+ console.log('\nšŸŽÆ Test Summary:');
126
+ console.log('Run these commands to verify full integration:');
127
+ console.log(' 1. pnpm run mcp:build # Build MCP binary');
128
+ console.log(' 2. pnpm run dev # Start full dev environment');
129
+ console.log(' 3. curl http://localhost:$(node scripts/setup-dev-environment.js | jq -r .mcpSse)/sse');
130
+ console.log('');
131
+ console.log('Expected: SSE connection established with MCP server');
132
+ }
133
+
134
+ if (require.main === module) {
135
+ main().catch(console.error);
136
+ }
137
+
138
+ module.exports = { testMcpSseIntegration, testDevWorkflow };
@@ -0,0 +1,44 @@
1
+ #!/usr/bin/env node
2
+
3
+ const { spawn } = require('child_process');
4
+
5
+ console.log('🧪 Simple MCP Test...\n');
6
+
7
+ // Start MCP server
8
+ const mcpProcess = spawn('cargo', ['run', '--manifest-path', 'backend/Cargo.toml', '--', '--mcp'], {
9
+ stdio: ['pipe', 'pipe', 'inherit'],
10
+ env: { ...process.env, PORT: '8892', DISABLE_WORKTREE_ORPHAN_CLEANUP: '1' }
11
+ });
12
+
13
+ let responseCount = 0;
14
+
15
+ mcpProcess.stdout.on('data', (data) => {
16
+ const response = data.toString().trim();
17
+ console.log(`šŸ“„ Response ${++responseCount}:`, response);
18
+
19
+ if (responseCount === 1) {
20
+ // Send initialize after first response
21
+ console.log('šŸ“¤ Sending initialize...');
22
+ mcpProcess.stdin.write(`{"jsonrpc": "2.0", "id": 1, "method": "initialize", "params": {"protocolVersion": "2024-11-05", "capabilities": {}, "clientInfo": {"name": "test", "version": "1.0.0"}}}\n`);
23
+ } else if (responseCount === 2) {
24
+ // Send list_tools after initialize response
25
+ console.log('šŸ“¤ Sending list_tools...');
26
+ mcpProcess.stdin.write(`{"jsonrpc": "2.0", "id": 2, "method": "tools/list", "params": {}}\n`);
27
+ } else if (responseCount === 3) {
28
+ console.log('āœ… Test successful - MCP server responding');
29
+ mcpProcess.kill();
30
+ process.exit(0);
31
+ }
32
+ });
33
+
34
+ mcpProcess.on('exit', (code) => {
35
+ console.log(`\nšŸ”“ MCP server exited with code: ${code}`);
36
+ process.exit(0);
37
+ });
38
+
39
+ // Safety timeout
40
+ setTimeout(() => {
41
+ console.log('\nā° Test timeout');
42
+ mcpProcess.kill();
43
+ process.exit(1);
44
+ }, 10000);
@@ -0,0 +1,179 @@
1
+ #!/usr/bin/env node
2
+
3
+ const { spawn } = require('child_process');
4
+
5
+ console.log('🧪 Testing Wish System - Final Test...\n');
6
+
7
+ let messageId = 1;
8
+ let testData = {
9
+ projectId: null,
10
+ taskId1: null,
11
+ taskId2: null,
12
+ wishId: 'test-refactor-auth'
13
+ };
14
+
15
+ function send(mcpProcess, message) {
16
+ const jsonStr = JSON.stringify(message);
17
+ console.log('šŸ“¤ SEND:', jsonStr);
18
+ mcpProcess.stdin.write(jsonStr + '\n');
19
+ }
20
+
21
+ function testCreateTasks(mcpProcess) {
22
+ console.log('\n=== Testing Task Creation with wish_id ===');
23
+
24
+ // Get existing projects first
25
+ send(mcpProcess, {
26
+ "jsonrpc": "2.0",
27
+ "id": messageId++,
28
+ "method": "tools/call",
29
+ "params": {
30
+ "name": "list_projects",
31
+ "arguments": {}
32
+ }
33
+ });
34
+ }
35
+
36
+ const mcpProcess = spawn('cargo', ['run', '--manifest-path', 'backend/Cargo.toml', '--', '--mcp'], {
37
+ stdio: ['pipe', 'pipe', 'inherit'],
38
+ env: { ...process.env, PORT: '8893', DISABLE_WORKTREE_ORPHAN_CLEANUP: '1' }
39
+ });
40
+
41
+ let step = 0;
42
+ let responses = [];
43
+
44
+ mcpProcess.stdout.on('data', (data) => {
45
+ const response = data.toString().trim();
46
+
47
+ // Skip log lines, only process JSON responses
48
+ if (!response.startsWith('{')) {
49
+ return;
50
+ }
51
+
52
+ console.log(`šŸ“„ RECV:`, response);
53
+ responses.push(response);
54
+
55
+ try {
56
+ const parsed = JSON.parse(response);
57
+
58
+ if (step === 0) {
59
+ // Initialize
60
+ send(mcpProcess, {
61
+ "jsonrpc": "2.0",
62
+ "id": messageId++,
63
+ "method": "initialize",
64
+ "params": {
65
+ "protocolVersion": "2024-11-05",
66
+ "capabilities": {},
67
+ "clientInfo": {"name": "wish-test", "version": "1.0.0"}
68
+ }
69
+ });
70
+ step++;
71
+ } else if (step === 1) {
72
+ // After initialize, get projects
73
+ testCreateTasks(mcpProcess);
74
+ step++;
75
+ } else if (step === 2 && parsed.result?.content) {
76
+ // Parse project list response
77
+ const content = JSON.parse(parsed.result.content[0].text);
78
+ if (content.projects && content.projects.length > 0) {
79
+ testData.projectId = content.projects[0].id;
80
+ console.log(`šŸ’¾ Using project: ${testData.projectId}`);
81
+
82
+ // Create first task with wish_id
83
+ send(mcpProcess, {
84
+ "jsonrpc": "2.0",
85
+ "id": messageId++,
86
+ "method": "tools/call",
87
+ "params": {
88
+ "name": "create_task",
89
+ "arguments": {
90
+ "project_id": testData.projectId,
91
+ "title": "First task in wish",
92
+ "description": "Testing wish system - first task",
93
+ "wish_id": testData.wishId
94
+ }
95
+ }
96
+ });
97
+ step++;
98
+ }
99
+ } else if (step === 3 && parsed.result?.content) {
100
+ // Parse first task creation response
101
+ const content = JSON.parse(parsed.result.content[0].text);
102
+ if (content.task_id) {
103
+ testData.taskId1 = content.task_id;
104
+ console.log(`šŸ’¾ First task created: ${testData.taskId1}`);
105
+
106
+ // Create second task with same wish_id (should succeed for grouping)
107
+ send(mcpProcess, {
108
+ "jsonrpc": "2.0",
109
+ "id": messageId++,
110
+ "method": "tools/call",
111
+ "params": {
112
+ "name": "create_task",
113
+ "arguments": {
114
+ "project_id": testData.projectId,
115
+ "title": "Second task in same wish",
116
+ "description": "Testing wish system - second task in same wish",
117
+ "wish_id": testData.wishId
118
+ }
119
+ }
120
+ });
121
+ step++;
122
+ }
123
+ } else if (step === 4 && parsed.result?.content) {
124
+ // Parse second task creation response
125
+ const content = JSON.parse(parsed.result.content[0].text);
126
+ if (content.task_id) {
127
+ testData.taskId2 = content.task_id;
128
+ console.log(`šŸ’¾ Second task created: ${testData.taskId2}`);
129
+
130
+ // List tasks filtered by wish_id
131
+ send(mcpProcess, {
132
+ "jsonrpc": "2.0",
133
+ "id": messageId++,
134
+ "method": "tools/call",
135
+ "params": {
136
+ "name": "list_tasks",
137
+ "arguments": {
138
+ "project_id": testData.projectId,
139
+ "wish_id": testData.wishId
140
+ }
141
+ }
142
+ });
143
+ step++;
144
+ }
145
+ } else if (step === 5 && parsed.result?.content) {
146
+ // Parse list tasks response
147
+ const content = JSON.parse(parsed.result.content[0].text);
148
+ console.log(`āœ… Found ${content.count} tasks with wish_id '${testData.wishId}'`);
149
+
150
+ if (content.count === 2) {
151
+ console.log('\nšŸŽ‰ WISH SYSTEM TEST SUCCESSFUL!');
152
+ console.log(' āœ… Created multiple tasks with same wish_id');
153
+ console.log(' āœ… Tasks grouped properly by wish_id');
154
+ console.log(' āœ… Filtering by wish_id works correctly');
155
+ } else {
156
+ console.log(`āŒ Expected 2 tasks, got ${content.count}`);
157
+ }
158
+
159
+ setTimeout(() => {
160
+ mcpProcess.kill();
161
+ process.exit(0);
162
+ }, 500);
163
+ }
164
+ } catch (e) {
165
+ console.log('āš ļø Non-JSON response or parsing error:', e.message);
166
+ }
167
+ });
168
+
169
+ mcpProcess.on('exit', (code) => {
170
+ console.log(`\nšŸ”“ MCP server exited with code: ${code}`);
171
+ process.exit(0);
172
+ });
173
+
174
+ // Safety timeout
175
+ setTimeout(() => {
176
+ console.log('\nā° Test timeout');
177
+ mcpProcess.kill();
178
+ process.exit(1);
179
+ }, 20000);
@@ -0,0 +1,221 @@
1
+ #!/usr/bin/env node
2
+
3
+ const { spawn } = require('child_process');
4
+
5
+ console.log('🧪 Testing Wish System Implementation...\n');
6
+
7
+ let messageId = 1;
8
+ let testData = {
9
+ projectId: null,
10
+ taskId1: null,
11
+ taskId2: null,
12
+ wishId: 'test-refactor-auth',
13
+ duplicateWishId: 'test-refactor-auth', // Same wish - should fail
14
+ differentWishId: 'test-feature-dashboard'
15
+ };
16
+
17
+ const testSequence = [
18
+ 'initialize',
19
+ 'initialized_notification',
20
+ 'list_tools',
21
+ 'list_projects',
22
+ 'create_task_with_wish',
23
+ 'create_task_same_wish', // Should succeed - same wish, different task (grouping)
24
+ 'list_tasks_by_wish',
25
+ 'update_task_wish',
26
+ 'test_summary'
27
+ ];
28
+
29
+ let currentStep = 0;
30
+
31
+ const steps = {
32
+ initialize: () => {
33
+ console.log('šŸ“¤ Initializing MCP connection...');
34
+ send({"jsonrpc": "2.0", "id": messageId++, "method": "initialize", "params": {"protocolVersion": "2024-11-05", "capabilities": {}, "clientInfo": {"name": "wish-test", "version": "1.0.0"}}});
35
+ },
36
+
37
+ initialized_notification: () => {
38
+ console.log('šŸ“¤ Sending initialized notification...');
39
+ send({"jsonrpc": "2.0", "method": "notifications/initialized"});
40
+ setTimeout(nextStep, 200);
41
+ },
42
+
43
+ list_tools: () => {
44
+ console.log('šŸ“¤ Listing available tools...');
45
+ send({"jsonrpc": "2.0", "id": messageId++, "method": "tools/list", "params": {}});
46
+ },
47
+
48
+ list_projects: () => {
49
+ console.log('šŸ“¤ Getting existing projects...');
50
+ send({"jsonrpc": "2.0", "id": messageId++, "method": "tools/call", "params": {"name": "list_projects", "arguments": {}}});
51
+ },
52
+
53
+ create_task_with_wish: () => {
54
+ console.log('šŸ“¤ Creating task with wish_id (should succeed)...');
55
+ send({
56
+ "jsonrpc": "2.0",
57
+ "id": messageId++,
58
+ "method": "tools/call",
59
+ "params": {
60
+ "name": "create_task",
61
+ "arguments": {
62
+ "project_id": testData.projectId,
63
+ "title": "First task in wish",
64
+ "description": "Testing wish system - first task",
65
+ "wish_id": testData.wishId
66
+ }
67
+ }
68
+ });
69
+ },
70
+
71
+ create_task_same_wish: () => {
72
+ console.log('šŸ“¤ Creating another task with same wish_id (should succeed)...');
73
+ send({
74
+ "jsonrpc": "2.0",
75
+ "id": messageId++,
76
+ "method": "tools/call",
77
+ "params": {
78
+ "name": "create_task",
79
+ "arguments": {
80
+ "project_id": testData.projectId,
81
+ "title": "Second task in same wish",
82
+ "description": "Testing wish system - second task in same wish",
83
+ "wish_id": testData.wishId
84
+ }
85
+ }
86
+ });
87
+ },
88
+
89
+
90
+ list_tasks_by_wish: () => {
91
+ console.log('šŸ“¤ Listing tasks filtered by wish_id...');
92
+ send({
93
+ "jsonrpc": "2.0",
94
+ "id": messageId++,
95
+ "method": "tools/call",
96
+ "params": {
97
+ "name": "list_tasks",
98
+ "arguments": {
99
+ "project_id": testData.projectId,
100
+ "wish_id": testData.wishId
101
+ }
102
+ }
103
+ });
104
+ },
105
+
106
+ update_task_wish: () => {
107
+ console.log('šŸ“¤ Updating task wish_id...');
108
+ send({
109
+ "jsonrpc": "2.0",
110
+ "id": messageId++,
111
+ "method": "tools/call",
112
+ "params": {
113
+ "name": "update_task",
114
+ "arguments": {
115
+ "task_id": testData.taskId2,
116
+ "wish_id": testData.differentWishId
117
+ }
118
+ }
119
+ });
120
+ },
121
+
122
+ test_summary: () => {
123
+ console.log('\nāœ… Wish System Test Complete!');
124
+ console.log('\nšŸ“Š Test Results:');
125
+ console.log(` āœ… Created tasks with wish_id: ${testData.wishId}`);
126
+ console.log(` āœ… Multiple tasks can share same wish_id (grouping)`);
127
+ console.log(` āœ… Filtered tasks by wish_id successfully`);
128
+ console.log(` āœ… Updated task wish_id successfully`);
129
+ console.log('\nšŸŽ‰ All wish system features working correctly!');
130
+
131
+ setTimeout(() => {
132
+ mcpProcess.kill();
133
+ process.exit(0);
134
+ }, 500);
135
+ }
136
+ };
137
+
138
+ function send(message) {
139
+ mcpProcess.stdin.write(JSON.stringify(message) + '\n');
140
+ }
141
+
142
+ function nextStep() {
143
+ currentStep++;
144
+ if (currentStep < testSequence.length) {
145
+ executeStep();
146
+ }
147
+ }
148
+
149
+ function executeStep() {
150
+ const stepName = testSequence[currentStep];
151
+ console.log(`\nšŸ”„ Step ${currentStep + 1}/${testSequence.length}: ${stepName}`);
152
+
153
+ setTimeout(() => {
154
+ steps[stepName]();
155
+ }, 100);
156
+ }
157
+
158
+ // Start MCP server
159
+ const mcpProcess = spawn('cargo', ['run', '--manifest-path', 'backend/Cargo.toml', '--', '--mcp'], {
160
+ stdio: ['pipe', 'pipe', 'inherit'],
161
+ env: { ...process.env, PORT: '8890', DISABLE_WORKTREE_ORPHAN_CLEANUP: '1' }
162
+ });
163
+
164
+ mcpProcess.stdout.on('data', (data) => {
165
+ const response = data.toString().trim();
166
+ console.log(`šŸ“„ Response:`, response);
167
+
168
+ try {
169
+ const parsed = JSON.parse(response);
170
+
171
+ // Extract useful data from responses
172
+ if (parsed.result?.content) {
173
+ const content = JSON.parse(parsed.result.content[0].text);
174
+
175
+ // Get project ID from list_projects
176
+ if (content.projects && content.projects.length > 0) {
177
+ testData.projectId = content.projects[0].id;
178
+ console.log(`šŸ’¾ Using project: ${testData.projectId}`);
179
+ }
180
+
181
+ // Get task IDs from create_task responses
182
+ if (content.task_id) {
183
+ if (!testData.taskId1) {
184
+ testData.taskId1 = content.task_id;
185
+ console.log(`šŸ’¾ First task: ${testData.taskId1}`);
186
+ } else if (!testData.taskId2) {
187
+ testData.taskId2 = content.task_id;
188
+ console.log(`šŸ’¾ Second task: ${testData.taskId2}`);
189
+ }
190
+ }
191
+
192
+ }
193
+
194
+ nextStep();
195
+ } catch (e) {
196
+ // If not JSON, still continue
197
+ nextStep();
198
+ }
199
+ });
200
+
201
+ mcpProcess.on('exit', (code) => {
202
+ console.log(`\nšŸ”“ MCP server exited with code: ${code}`);
203
+ process.exit(0);
204
+ });
205
+
206
+ mcpProcess.on('error', (error) => {
207
+ console.error('āŒ MCP server error:', error);
208
+ process.exit(1);
209
+ });
210
+
211
+ // Start test sequence
212
+ setTimeout(() => {
213
+ executeStep();
214
+ }, 1000);
215
+
216
+ // Safety timeout
217
+ setTimeout(() => {
218
+ console.log('\nā° Test timeout - killing process');
219
+ mcpProcess.kill();
220
+ process.exit(1);
221
+ }, 30000);