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,630 @@
1
+ // Import all necessary types from shared types
2
+ import {
3
+ BranchStatus,
4
+ Config,
5
+ CreateFollowUpAttempt,
6
+ CreateProject,
7
+ CreateTask,
8
+ CreateTaskAndStart,
9
+ CreateTaskAttempt,
10
+ CreateTaskTemplate,
11
+ DeviceStartResponse,
12
+ DirectoryEntry,
13
+ type EditorType,
14
+ ExecutionProcess,
15
+ ExecutionProcessSummary,
16
+ GitBranch,
17
+ ProcessLogsResponse,
18
+ Project,
19
+ ProjectWithBranch,
20
+ Task,
21
+ TaskAttempt,
22
+ TaskAttemptState,
23
+ TaskTemplate,
24
+ TaskWithAttemptStatus,
25
+ UpdateProject,
26
+ UpdateTask,
27
+ UpdateTaskTemplate,
28
+ WorktreeDiff,
29
+ } from 'shared/types';
30
+
31
+ export const makeRequest = async (url: string, options: RequestInit = {}) => {
32
+ const headers = {
33
+ 'Content-Type': 'application/json',
34
+ ...(options.headers || {}),
35
+ };
36
+
37
+ return fetch(url, {
38
+ ...options,
39
+ headers,
40
+ });
41
+ };
42
+
43
+ export interface ApiResponse<T> {
44
+ success: boolean;
45
+ data?: T;
46
+ message?: string;
47
+ }
48
+
49
+ export interface FollowUpResponse {
50
+ message: string;
51
+ actual_attempt_id: string;
52
+ created_new_attempt: boolean;
53
+ }
54
+
55
+ // Additional interface for file search results
56
+ export interface FileSearchResult {
57
+ path: string;
58
+ name: string;
59
+ }
60
+
61
+ // Directory listing response
62
+ export interface DirectoryListResponse {
63
+ entries: DirectoryEntry[];
64
+ current_path: string;
65
+ }
66
+
67
+ export class ApiError extends Error {
68
+ constructor(
69
+ message: string,
70
+ public status?: number,
71
+ public response?: Response
72
+ ) {
73
+ super(message);
74
+ this.name = 'ApiError';
75
+ }
76
+ }
77
+
78
+ const handleApiResponse = async <T>(response: Response): Promise<T> => {
79
+ if (!response.ok) {
80
+ let errorMessage = `Request failed with status ${response.status}`;
81
+
82
+ try {
83
+ const errorData = await response.json();
84
+ if (errorData.message) {
85
+ errorMessage = errorData.message;
86
+ }
87
+ } catch {
88
+ // Fallback to status text if JSON parsing fails
89
+ errorMessage = response.statusText || errorMessage;
90
+ }
91
+
92
+ console.error('[API Error]', {
93
+ message: errorMessage,
94
+ status: response.status,
95
+ response,
96
+ endpoint: response.url,
97
+ timestamp: new Date().toISOString(),
98
+ });
99
+ throw new ApiError(errorMessage, response.status, response);
100
+ }
101
+
102
+ const result: ApiResponse<T> = await response.json();
103
+
104
+ if (!result.success) {
105
+ console.error('[API Error]', {
106
+ message: result.message || 'API request failed',
107
+ status: response.status,
108
+ response,
109
+ endpoint: response.url,
110
+ timestamp: new Date().toISOString(),
111
+ });
112
+ throw new ApiError(result.message || 'API request failed');
113
+ }
114
+
115
+ return result.data as T;
116
+ };
117
+
118
+ // Project Management APIs
119
+ export const projectsApi = {
120
+ getAll: async (): Promise<Project[]> => {
121
+ const response = await makeRequest('/api/projects');
122
+ return handleApiResponse<Project[]>(response);
123
+ },
124
+
125
+ getById: async (id: string): Promise<Project> => {
126
+ const response = await makeRequest(`/api/projects/${id}`);
127
+ return handleApiResponse<Project>(response);
128
+ },
129
+
130
+ getWithBranch: async (id: string): Promise<ProjectWithBranch> => {
131
+ const response = await makeRequest(`/api/projects/${id}/with-branch`);
132
+ return handleApiResponse<ProjectWithBranch>(response);
133
+ },
134
+
135
+ create: async (data: CreateProject): Promise<Project> => {
136
+ const response = await makeRequest('/api/projects', {
137
+ method: 'POST',
138
+ body: JSON.stringify(data),
139
+ });
140
+ return handleApiResponse<Project>(response);
141
+ },
142
+
143
+ update: async (id: string, data: UpdateProject): Promise<Project> => {
144
+ const response = await makeRequest(`/api/projects/${id}`, {
145
+ method: 'PUT',
146
+ body: JSON.stringify(data),
147
+ });
148
+ return handleApiResponse<Project>(response);
149
+ },
150
+
151
+ delete: async (id: string): Promise<void> => {
152
+ const response = await makeRequest(`/api/projects/${id}`, {
153
+ method: 'DELETE',
154
+ });
155
+ return handleApiResponse<void>(response);
156
+ },
157
+
158
+ openEditor: async (id: string): Promise<void> => {
159
+ const response = await makeRequest(`/api/projects/${id}/open-editor`, {
160
+ method: 'POST',
161
+ body: JSON.stringify(null),
162
+ });
163
+ return handleApiResponse<void>(response);
164
+ },
165
+
166
+ getBranches: async (id: string): Promise<GitBranch[]> => {
167
+ const response = await makeRequest(`/api/projects/${id}/branches`);
168
+ return handleApiResponse<GitBranch[]>(response);
169
+ },
170
+
171
+ searchFiles: async (
172
+ id: string,
173
+ query: string
174
+ ): Promise<FileSearchResult[]> => {
175
+ const response = await makeRequest(
176
+ `/api/projects/${id}/search?q=${encodeURIComponent(query)}`
177
+ );
178
+ return handleApiResponse<FileSearchResult[]>(response);
179
+ },
180
+ };
181
+
182
+ // Task Management APIs
183
+ export const tasksApi = {
184
+ getAll: async (projectId: string): Promise<TaskWithAttemptStatus[]> => {
185
+ const response = await makeRequest(`/api/projects/${projectId}/tasks`);
186
+ return handleApiResponse<TaskWithAttemptStatus[]>(response);
187
+ },
188
+
189
+ getById: async (projectId: string, taskId: string): Promise<Task> => {
190
+ const response = await makeRequest(
191
+ `/api/projects/${projectId}/tasks/${taskId}`
192
+ );
193
+ return handleApiResponse<Task>(response);
194
+ },
195
+
196
+ create: async (projectId: string, data: CreateTask): Promise<Task> => {
197
+ const response = await makeRequest(`/api/projects/${projectId}/tasks`, {
198
+ method: 'POST',
199
+ body: JSON.stringify(data),
200
+ });
201
+ return handleApiResponse<Task>(response);
202
+ },
203
+
204
+ createAndStart: async (
205
+ projectId: string,
206
+ data: CreateTaskAndStart
207
+ ): Promise<TaskWithAttemptStatus> => {
208
+ const response = await makeRequest(
209
+ `/api/projects/${projectId}/tasks/create-and-start`,
210
+ {
211
+ method: 'POST',
212
+ body: JSON.stringify(data),
213
+ }
214
+ );
215
+ return handleApiResponse<TaskWithAttemptStatus>(response);
216
+ },
217
+
218
+ update: async (
219
+ projectId: string,
220
+ taskId: string,
221
+ data: UpdateTask
222
+ ): Promise<Task> => {
223
+ const response = await makeRequest(
224
+ `/api/projects/${projectId}/tasks/${taskId}`,
225
+ {
226
+ method: 'PUT',
227
+ body: JSON.stringify(data),
228
+ }
229
+ );
230
+ return handleApiResponse<Task>(response);
231
+ },
232
+
233
+ delete: async (projectId: string, taskId: string): Promise<void> => {
234
+ const response = await makeRequest(
235
+ `/api/projects/${projectId}/tasks/${taskId}`,
236
+ {
237
+ method: 'DELETE',
238
+ }
239
+ );
240
+ return handleApiResponse<void>(response);
241
+ },
242
+
243
+ getChildren: async (
244
+ projectId: string,
245
+ taskId: string,
246
+ attemptId: string
247
+ ): Promise<Task[]> => {
248
+ const response = await makeRequest(
249
+ `/api/projects/${projectId}/tasks/${taskId}/attempts/${attemptId}/children`
250
+ );
251
+ return handleApiResponse<Task[]>(response);
252
+ },
253
+ };
254
+
255
+ // Task Attempts APIs
256
+ export const attemptsApi = {
257
+ getAll: async (projectId: string, taskId: string): Promise<TaskAttempt[]> => {
258
+ const response = await makeRequest(
259
+ `/api/projects/${projectId}/tasks/${taskId}/attempts`
260
+ );
261
+ return handleApiResponse<TaskAttempt[]>(response);
262
+ },
263
+
264
+ create: async (
265
+ projectId: string,
266
+ taskId: string,
267
+ data: CreateTaskAttempt
268
+ ): Promise<TaskAttempt> => {
269
+ const response = await makeRequest(
270
+ `/api/projects/${projectId}/tasks/${taskId}/attempts`,
271
+ {
272
+ method: 'POST',
273
+ body: JSON.stringify(data),
274
+ }
275
+ );
276
+ return handleApiResponse<TaskAttempt>(response);
277
+ },
278
+
279
+ getState: async (
280
+ projectId: string,
281
+ taskId: string,
282
+ attemptId: string
283
+ ): Promise<TaskAttemptState> => {
284
+ const response = await makeRequest(
285
+ `/api/projects/${projectId}/tasks/${taskId}/attempts/${attemptId}`
286
+ );
287
+ return handleApiResponse<TaskAttemptState>(response);
288
+ },
289
+
290
+ stop: async (
291
+ projectId: string,
292
+ taskId: string,
293
+ attemptId: string
294
+ ): Promise<void> => {
295
+ const response = await makeRequest(
296
+ `/api/projects/${projectId}/tasks/${taskId}/attempts/${attemptId}/stop`,
297
+ {
298
+ method: 'POST',
299
+ }
300
+ );
301
+ return handleApiResponse<void>(response);
302
+ },
303
+
304
+ followUp: async (
305
+ projectId: string,
306
+ taskId: string,
307
+ attemptId: string,
308
+ data: CreateFollowUpAttempt
309
+ ): Promise<void> => {
310
+ const response = await makeRequest(
311
+ `/api/projects/${projectId}/tasks/${taskId}/attempts/${attemptId}/follow-up`,
312
+ {
313
+ method: 'POST',
314
+ body: JSON.stringify(data),
315
+ }
316
+ );
317
+ return handleApiResponse<void>(response);
318
+ },
319
+
320
+ getDiff: async (
321
+ projectId: string,
322
+ taskId: string,
323
+ attemptId: string
324
+ ): Promise<WorktreeDiff> => {
325
+ const response = await makeRequest(
326
+ `/api/projects/${projectId}/tasks/${taskId}/attempts/${attemptId}/diff`
327
+ );
328
+ return handleApiResponse<WorktreeDiff>(response);
329
+ },
330
+
331
+ deleteFile: async (
332
+ projectId: string,
333
+ taskId: string,
334
+ attemptId: string,
335
+ fileToDelete: string
336
+ ): Promise<void> => {
337
+ const response = await makeRequest(
338
+ `/api/projects/${projectId}/tasks/${taskId}/attempts/${attemptId}/delete-filefile_path=${encodeURIComponent(
339
+ fileToDelete
340
+ )}`,
341
+ {
342
+ method: 'POST',
343
+ }
344
+ );
345
+ return handleApiResponse<void>(response);
346
+ },
347
+
348
+ openEditor: async (
349
+ projectId: string,
350
+ taskId: string,
351
+ attemptId: string,
352
+ editorType?: EditorType
353
+ ): Promise<void> => {
354
+ const response = await makeRequest(
355
+ `/api/projects/${projectId}/tasks/${taskId}/attempts/${attemptId}/open-editor`,
356
+ {
357
+ method: 'POST',
358
+ body: JSON.stringify(editorType ? { editor_type: editorType } : null),
359
+ }
360
+ );
361
+ return handleApiResponse<void>(response);
362
+ },
363
+
364
+ getBranchStatus: async (
365
+ projectId: string,
366
+ taskId: string,
367
+ attemptId: string
368
+ ): Promise<BranchStatus> => {
369
+ const response = await makeRequest(
370
+ `/api/projects/${projectId}/tasks/${taskId}/attempts/${attemptId}/branch-status`
371
+ );
372
+ return handleApiResponse<BranchStatus>(response);
373
+ },
374
+
375
+ merge: async (
376
+ projectId: string,
377
+ taskId: string,
378
+ attemptId: string
379
+ ): Promise<void> => {
380
+ const response = await makeRequest(
381
+ `/api/projects/${projectId}/tasks/${taskId}/attempts/${attemptId}/merge`,
382
+ {
383
+ method: 'POST',
384
+ }
385
+ );
386
+ return handleApiResponse<void>(response);
387
+ },
388
+
389
+ rebase: async (
390
+ projectId: string,
391
+ taskId: string,
392
+ attemptId: string,
393
+ newBaseBranch?: string
394
+ ): Promise<void> => {
395
+ const response = await makeRequest(
396
+ `/api/projects/${projectId}/tasks/${taskId}/attempts/${attemptId}/rebase`,
397
+ {
398
+ method: 'POST',
399
+ headers: {
400
+ 'Content-Type': 'application/json',
401
+ },
402
+ body: JSON.stringify({
403
+ new_base_branch: newBaseBranch || null,
404
+ }),
405
+ }
406
+ );
407
+ return handleApiResponse<void>(response);
408
+ },
409
+
410
+ createPR: async (
411
+ projectId: string,
412
+ taskId: string,
413
+ attemptId: string,
414
+ data: {
415
+ title: string;
416
+ body: string | null;
417
+ base_branch: string | null;
418
+ }
419
+ ): Promise<string> => {
420
+ const response = await makeRequest(
421
+ `/api/projects/${projectId}/tasks/${taskId}/attempts/${attemptId}/create-pr`,
422
+ {
423
+ method: 'POST',
424
+ body: JSON.stringify(data),
425
+ }
426
+ );
427
+ return handleApiResponse<string>(response);
428
+ },
429
+
430
+ startDevServer: async (
431
+ projectId: string,
432
+ taskId: string,
433
+ attemptId: string
434
+ ): Promise<void> => {
435
+ const response = await makeRequest(
436
+ `/api/projects/${projectId}/tasks/${taskId}/attempts/${attemptId}/start-dev-server`,
437
+ {
438
+ method: 'POST',
439
+ }
440
+ );
441
+ return handleApiResponse<void>(response);
442
+ },
443
+
444
+ getExecutionProcesses: async (
445
+ projectId: string,
446
+ taskId: string,
447
+ attemptId: string
448
+ ): Promise<ExecutionProcessSummary[]> => {
449
+ const response = await makeRequest(
450
+ `/api/projects/${projectId}/tasks/${taskId}/attempts/${attemptId}/execution-processes`
451
+ );
452
+ return handleApiResponse<ExecutionProcessSummary[]>(response);
453
+ },
454
+
455
+ stopExecutionProcess: async (
456
+ projectId: string,
457
+ taskId: string,
458
+ attemptId: string,
459
+ processId: string
460
+ ): Promise<void> => {
461
+ const response = await makeRequest(
462
+ `/api/projects/${projectId}/tasks/${taskId}/attempts/${attemptId}/execution-processes/${processId}/stop`,
463
+ {
464
+ method: 'POST',
465
+ }
466
+ );
467
+ return handleApiResponse<void>(response);
468
+ },
469
+
470
+ getDetails: async (attemptId: string): Promise<TaskAttempt> => {
471
+ const response = await makeRequest(`/api/attempts/${attemptId}/details`);
472
+ return handleApiResponse<TaskAttempt>(response);
473
+ },
474
+
475
+ getAllLogs: async (
476
+ projectId: string,
477
+ taskId: string,
478
+ attemptId: string
479
+ ): Promise<ProcessLogsResponse[]> => {
480
+ const response = await makeRequest(
481
+ `/api/projects/${projectId}/tasks/${taskId}/attempts/${attemptId}/logs`
482
+ );
483
+ return handleApiResponse(response);
484
+ },
485
+ };
486
+
487
+ // Execution Process APIs
488
+ export const executionProcessesApi = {
489
+ getDetails: async (processId: string): Promise<ExecutionProcess> => {
490
+ const response = await makeRequest(`/api/execution-processes/${processId}`);
491
+ return handleApiResponse<ExecutionProcess>(response);
492
+ },
493
+ };
494
+
495
+ // File System APIs
496
+ export const fileSystemApi = {
497
+ list: async (path?: string): Promise<DirectoryListResponse> => {
498
+ const queryParam = path ? `?path=${encodeURIComponent(path)}` : '';
499
+ const response = await makeRequest(`/api/filesystem/list${queryParam}`);
500
+ return handleApiResponse<DirectoryListResponse>(response);
501
+ },
502
+ };
503
+
504
+ // Config APIs
505
+ export const configApi = {
506
+ getConfig: async (): Promise<Config> => {
507
+ const response = await makeRequest('/api/config');
508
+ return handleApiResponse<Config>(response);
509
+ },
510
+ saveConfig: async (config: Config): Promise<Config> => {
511
+ const response = await makeRequest('/api/config', {
512
+ method: 'POST',
513
+ body: JSON.stringify(config),
514
+ });
515
+ return handleApiResponse<Config>(response);
516
+ },
517
+ };
518
+
519
+ // GitHub Device Auth APIs
520
+ export const githubAuthApi = {
521
+ checkGithubToken: async (): Promise<boolean | undefined> => {
522
+ try {
523
+ const response = await makeRequest('/api/auth/github/check');
524
+ const result: ApiResponse<null> = await response.json();
525
+ if (!result.success && result.message === 'github_token_invalid') {
526
+ return false;
527
+ }
528
+ return result.success;
529
+ } catch (err) {
530
+ // On network/server error, return undefined (unknown)
531
+ return undefined;
532
+ }
533
+ },
534
+ start: async (): Promise<DeviceStartResponse> => {
535
+ const response = await makeRequest('/api/auth/github/device/start', {
536
+ method: 'POST',
537
+ });
538
+ return handleApiResponse<DeviceStartResponse>(response);
539
+ },
540
+ poll: async (device_code: string): Promise<string> => {
541
+ const response = await makeRequest('/api/auth/github/device/poll', {
542
+ method: 'POST',
543
+ body: JSON.stringify({ device_code }),
544
+ headers: { 'Content-Type': 'application/json' },
545
+ });
546
+ return handleApiResponse<string>(response);
547
+ },
548
+ };
549
+
550
+ // Task Templates APIs
551
+ export const templatesApi = {
552
+ list: async (): Promise<TaskTemplate[]> => {
553
+ const response = await makeRequest('/api/templates');
554
+ return handleApiResponse<TaskTemplate[]>(response);
555
+ },
556
+
557
+ listGlobal: async (): Promise<TaskTemplate[]> => {
558
+ const response = await makeRequest('/api/templates/global');
559
+ return handleApiResponse<TaskTemplate[]>(response);
560
+ },
561
+
562
+ listByProject: async (projectId: string): Promise<TaskTemplate[]> => {
563
+ const response = await makeRequest(`/api/projects/${projectId}/templates`);
564
+ return handleApiResponse<TaskTemplate[]>(response);
565
+ },
566
+
567
+ get: async (templateId: string): Promise<TaskTemplate> => {
568
+ const response = await makeRequest(`/api/templates/${templateId}`);
569
+ return handleApiResponse<TaskTemplate>(response);
570
+ },
571
+
572
+ create: async (data: CreateTaskTemplate): Promise<TaskTemplate> => {
573
+ const response = await makeRequest('/api/templates', {
574
+ method: 'POST',
575
+ body: JSON.stringify(data),
576
+ });
577
+ return handleApiResponse<TaskTemplate>(response);
578
+ },
579
+
580
+ update: async (
581
+ templateId: string,
582
+ data: UpdateTaskTemplate
583
+ ): Promise<TaskTemplate> => {
584
+ const response = await makeRequest(`/api/templates/${templateId}`, {
585
+ method: 'PUT',
586
+ body: JSON.stringify(data),
587
+ });
588
+ return handleApiResponse<TaskTemplate>(response);
589
+ },
590
+
591
+ delete: async (templateId: string): Promise<void> => {
592
+ const response = await makeRequest(`/api/templates/${templateId}`, {
593
+ method: 'DELETE',
594
+ });
595
+ return handleApiResponse<void>(response);
596
+ },
597
+ };
598
+
599
+ // MCP Servers APIs
600
+ export const mcpServersApi = {
601
+ load: async (executor: string): Promise<any> => {
602
+ const response = await makeRequest(
603
+ `/api/mcp-servers?executor=${encodeURIComponent(executor)}`
604
+ );
605
+ return handleApiResponse<any>(response);
606
+ },
607
+ save: async (executor: string, serversConfig: any): Promise<void> => {
608
+ const response = await makeRequest(
609
+ `/api/mcp-servers?executor=${encodeURIComponent(executor)}`,
610
+ {
611
+ method: 'POST',
612
+ body: JSON.stringify(serversConfig),
613
+ }
614
+ );
615
+ if (!response.ok) {
616
+ const errorData = await response.json();
617
+ console.error('[API Error] Failed to save MCP servers', {
618
+ message: errorData.message,
619
+ status: response.status,
620
+ response,
621
+ timestamp: new Date().toISOString(),
622
+ });
623
+ throw new ApiError(
624
+ errorData.message || 'Failed to save MCP servers',
625
+ response.status,
626
+ response
627
+ );
628
+ }
629
+ },
630
+ };