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,216 @@
1
+ import { useContext, useEffect, useState } from 'react';
2
+ import { useNavigate } from 'react-router-dom';
3
+ import {
4
+ TaskDetailsContext,
5
+ TaskRelatedTasksContext,
6
+ } from '@/components/context/taskDetailsContext.ts';
7
+ import { attemptsApi, tasksApi } from '@/lib/api.ts';
8
+ import type { Task, TaskAttempt } from 'shared/types.ts';
9
+ import {
10
+ AlertCircle,
11
+ CheckCircle,
12
+ Clock,
13
+ XCircle,
14
+ ArrowUp,
15
+ ArrowDown,
16
+ } from 'lucide-react';
17
+
18
+ function RelatedTasksTab() {
19
+ const { task, projectId } = useContext(TaskDetailsContext);
20
+ const { relatedTasks, relatedTasksLoading, relatedTasksError } = useContext(
21
+ TaskRelatedTasksContext
22
+ );
23
+ const navigate = useNavigate();
24
+
25
+ // State for parent task details
26
+ const [parentTaskDetails, setParentTaskDetails] = useState<{
27
+ task: Task;
28
+ attempt: TaskAttempt;
29
+ } | null>(null);
30
+ const [parentTaskLoading, setParentTaskLoading] = useState(false);
31
+
32
+ const handleTaskClick = (relatedTask: any) => {
33
+ navigate(`/projects/${projectId}/tasks/${relatedTask.id}`);
34
+ };
35
+
36
+ const hasParent = task?.parent_task_attempt;
37
+ const children = relatedTasks || [];
38
+
39
+ // Fetch parent task details when component mounts
40
+ useEffect(() => {
41
+ const fetchParentTaskDetails = async () => {
42
+ if (!task?.parent_task_attempt) {
43
+ setParentTaskDetails(null);
44
+ return;
45
+ }
46
+
47
+ setParentTaskLoading(true);
48
+ try {
49
+ const attemptData = await attemptsApi.getDetails(
50
+ task.parent_task_attempt
51
+ );
52
+ const parentTask = await tasksApi.getById(
53
+ projectId,
54
+ attemptData.task_id
55
+ );
56
+ setParentTaskDetails({
57
+ task: parentTask,
58
+ attempt: attemptData,
59
+ });
60
+ } catch (error) {
61
+ console.error('Error fetching parent task details:', error);
62
+ setParentTaskDetails(null);
63
+ } finally {
64
+ setParentTaskLoading(false);
65
+ }
66
+ };
67
+
68
+ fetchParentTaskDetails();
69
+ }, [task?.parent_task_attempt, projectId]);
70
+
71
+ const handleParentClick = async () => {
72
+ if (task?.parent_task_attempt) {
73
+ try {
74
+ const attemptData = await attemptsApi.getDetails(
75
+ task.parent_task_attempt
76
+ );
77
+ navigate(
78
+ `/projects/${projectId}/tasks/${attemptData.task_id}?attempt=${task.parent_task_attempt}`
79
+ );
80
+ } catch (error) {
81
+ console.error('Error navigating to parent task:', error);
82
+ }
83
+ }
84
+ };
85
+
86
+ const getStatusIcon = (status: string) => {
87
+ switch (status) {
88
+ case 'done':
89
+ return <CheckCircle className="h-4 w-4 text-green-500" />;
90
+ case 'inprogress':
91
+ return <Clock className="h-4 w-4 text-blue-500" />;
92
+ case 'cancelled':
93
+ return <XCircle className="h-4 w-4 text-red-500" />;
94
+ case 'inreview':
95
+ return <AlertCircle className="h-4 w-4 text-yellow-500" />;
96
+ default:
97
+ return <Clock className="h-4 w-4 text-gray-500" />;
98
+ }
99
+ };
100
+
101
+ if (relatedTasksLoading) {
102
+ return (
103
+ <div className="flex items-center justify-center p-8">
104
+ <div className="animate-spin rounded-full h-8 w-8 border-b-2 border-primary"></div>
105
+ </div>
106
+ );
107
+ }
108
+
109
+ if (relatedTasksError) {
110
+ return (
111
+ <div className="flex items-center justify-center p-8">
112
+ <div className="text-center">
113
+ <AlertCircle className="h-12 w-12 text-red-500 mx-auto mb-4" />
114
+ <p className="text-red-600">{relatedTasksError}</p>
115
+ </div>
116
+ </div>
117
+ );
118
+ }
119
+
120
+ const totalRelatedTasks = (hasParent ? 1 : 0) + children.length;
121
+
122
+ if (totalRelatedTasks === 0) {
123
+ return (
124
+ <div className="flex items-center justify-center p-8">
125
+ <div className="text-center">
126
+ <div className="text-muted-foreground">
127
+ <p>No related tasks found.</p>
128
+ <p className="text-sm mt-2">
129
+ This task doesn't have any parent task or subtasks.
130
+ </p>
131
+ </div>
132
+ </div>
133
+ </div>
134
+ );
135
+ }
136
+
137
+ return (
138
+ <div className="space-y-6 p-4">
139
+ {/* Parent Task */}
140
+ {hasParent && (
141
+ <div>
142
+ <h3 className="text-sm font-medium text-muted-foreground mb-2 flex items-center gap-2">
143
+ <ArrowUp className="h-4 w-4" />
144
+ Parent Task
145
+ </h3>
146
+ <button
147
+ onClick={handleParentClick}
148
+ className="w-full bg-card border border-border rounded-lg p-4 hover:bg-accent/50 transition-colors cursor-pointer text-left"
149
+ >
150
+ {parentTaskLoading ? (
151
+ <div className="flex items-center gap-4">
152
+ <div className="animate-spin rounded-full h-4 w-4 border-b-2 border-primary"></div>
153
+ <div className="text-muted-foreground">
154
+ Loading parent task...
155
+ </div>
156
+ </div>
157
+ ) : parentTaskDetails ? (
158
+ <div className="flex items-center gap-4">
159
+ <div className="flex-1">
160
+ <div className="font-medium text-foreground">
161
+ {parentTaskDetails.task.title}
162
+ </div>
163
+ <div className="text-sm text-muted-foreground">
164
+ {new Date(
165
+ parentTaskDetails.attempt.created_at
166
+ ).toLocaleDateString()}{' '}
167
+ {new Date(
168
+ parentTaskDetails.attempt.created_at
169
+ ).toLocaleTimeString([], {
170
+ hour: '2-digit',
171
+ minute: '2-digit',
172
+ })}
173
+ </div>
174
+ </div>
175
+ </div>
176
+ ) : (
177
+ <div className="flex items-center gap-4">
178
+ <div className="text-muted-foreground">
179
+ Parent task (failed to load details)
180
+ </div>
181
+ </div>
182
+ )}
183
+ </button>
184
+ </div>
185
+ )}
186
+
187
+ {/* Child Tasks */}
188
+ {children.length > 0 && (
189
+ <div>
190
+ <h3 className="text-sm font-medium text-muted-foreground mb-2 flex items-center gap-2">
191
+ <ArrowDown className="h-4 w-4" />
192
+ Child Tasks ({children.length})
193
+ </h3>
194
+ <div className="space-y-3">
195
+ {children.map((childTask) => (
196
+ <button
197
+ key={childTask.id}
198
+ onClick={() => handleTaskClick(childTask)}
199
+ className="w-full bg-card border border-border rounded-lg p-4 hover:bg-accent/50 transition-colors cursor-pointer text-left"
200
+ >
201
+ <div className="flex items-center gap-4">
202
+ {getStatusIcon(childTask.status)}
203
+ <span className="font-medium text-foreground">
204
+ {childTask.title}
205
+ </span>
206
+ </div>
207
+ </button>
208
+ ))}
209
+ </div>
210
+ </div>
211
+ )}
212
+ </div>
213
+ );
214
+ }
215
+
216
+ export default RelatedTasksTab;
@@ -0,0 +1,93 @@
1
+ import { GitCompare, MessageSquare, Network, Cog } from 'lucide-react';
2
+ import { useContext } from 'react';
3
+ import {
4
+ TaskAttemptDataContext,
5
+ TaskDiffContext,
6
+ TaskRelatedTasksContext,
7
+ } from '@/components/context/taskDetailsContext.ts';
8
+
9
+ type Props = {
10
+ activeTab: 'logs' | 'diffs' | 'related' | 'processes';
11
+ setActiveTab: (tab: 'logs' | 'diffs' | 'related' | 'processes') => void;
12
+ };
13
+
14
+ function TabNavigation({ activeTab, setActiveTab }: Props) {
15
+ const { diff } = useContext(TaskDiffContext);
16
+ const { totalRelatedCount } = useContext(TaskRelatedTasksContext);
17
+ const { attemptData } = useContext(TaskAttemptDataContext);
18
+ return (
19
+ <div className="border-b bg-muted/30">
20
+ <div className="flex px-4">
21
+ <button
22
+ onClick={() => {
23
+ setActiveTab('logs');
24
+ }}
25
+ className={`flex items-center px-4 py-2 text-sm font-medium border-b-2 transition-colors ${
26
+ activeTab === 'logs'
27
+ ? 'border-primary text-primary bg-background'
28
+ : 'border-transparent text-muted-foreground hover:text-foreground hover:bg-muted/50'
29
+ }`}
30
+ >
31
+ <MessageSquare className="h-4 w-4 mr-2" />
32
+ Logs
33
+ </button>
34
+ <button
35
+ onClick={() => {
36
+ setActiveTab('diffs');
37
+ }}
38
+ className={`flex items-center px-4 py-2 text-sm font-medium border-b-2 transition-colors ${
39
+ activeTab === 'diffs'
40
+ ? 'border-primary text-primary bg-background'
41
+ : 'border-transparent text-muted-foreground hover:text-foreground hover:bg-muted/50'
42
+ }`}
43
+ >
44
+ <GitCompare className="h-4 w-4 mr-2" />
45
+ Diffs
46
+ {diff && diff.files.length > 0 && (
47
+ <span className="ml-2 px-1.5 py-0.5 text-xs bg-primary/10 text-primary rounded-full">
48
+ {diff.files.length}
49
+ </span>
50
+ )}
51
+ </button>
52
+ <button
53
+ onClick={() => {
54
+ setActiveTab('related');
55
+ }}
56
+ className={`flex items-center px-4 py-2 text-sm font-medium border-b-2 transition-colors ${
57
+ activeTab === 'related'
58
+ ? 'border-primary text-primary bg-background'
59
+ : 'border-transparent text-muted-foreground hover:text-foreground hover:bg-muted/50'
60
+ }`}
61
+ >
62
+ <Network className="h-4 w-4 mr-2" />
63
+ Related Tasks
64
+ {totalRelatedCount > 0 && (
65
+ <span className="ml-2 px-1.5 py-0.5 text-xs bg-primary/10 text-primary rounded-full">
66
+ {totalRelatedCount}
67
+ </span>
68
+ )}
69
+ </button>
70
+ <button
71
+ onClick={() => {
72
+ setActiveTab('processes');
73
+ }}
74
+ className={`flex items-center px-4 py-2 text-sm font-medium border-b-2 transition-colors ${
75
+ activeTab === 'processes'
76
+ ? 'border-primary text-primary bg-background'
77
+ : 'border-transparent text-muted-foreground hover:text-foreground hover:bg-muted/50'
78
+ }`}
79
+ >
80
+ <Cog className="h-4 w-4 mr-2" />
81
+ Processes
82
+ {attemptData.processes && attemptData.processes.length > 0 && (
83
+ <span className="ml-2 px-1.5 py-0.5 text-xs bg-primary/10 text-primary rounded-full">
84
+ {attemptData.processes.length}
85
+ </span>
86
+ )}
87
+ </button>
88
+ </div>
89
+ </div>
90
+ );
91
+ }
92
+
93
+ export default TabNavigation;
@@ -0,0 +1,169 @@
1
+ import { memo, useContext, useState } from 'react';
2
+ import { ChevronDown, ChevronUp, Edit, Trash2, X } from 'lucide-react';
3
+ import { Button } from '@/components/ui/button';
4
+ import { Chip } from '@/components/ui/chip';
5
+ import {
6
+ Tooltip,
7
+ TooltipContent,
8
+ TooltipProvider,
9
+ TooltipTrigger,
10
+ } from '@/components/ui/tooltip';
11
+ import type { TaskStatus, TaskWithAttemptStatus } from 'shared/types';
12
+ import { TaskDetailsContext } from '@/components/context/taskDetailsContext.ts';
13
+
14
+ interface TaskDetailsHeaderProps {
15
+ onClose: () => void;
16
+ onEditTask?: (task: TaskWithAttemptStatus) => void;
17
+ onDeleteTask?: (taskId: string) => void;
18
+ }
19
+
20
+ const statusLabels: Record<TaskStatus, string> = {
21
+ todo: 'To Do',
22
+ inprogress: 'In Progress',
23
+ inreview: 'In Review',
24
+ done: 'Done',
25
+ cancelled: 'Cancelled',
26
+ };
27
+
28
+ const getTaskStatusDotColor = (status: TaskStatus): string => {
29
+ switch (status) {
30
+ case 'todo':
31
+ return 'bg-gray-400';
32
+ case 'inprogress':
33
+ return 'bg-blue-500';
34
+ case 'inreview':
35
+ return 'bg-yellow-500';
36
+ case 'done':
37
+ return 'bg-green-500';
38
+ case 'cancelled':
39
+ return 'bg-red-500';
40
+ default:
41
+ return 'bg-gray-400';
42
+ }
43
+ };
44
+
45
+ function TaskDetailsHeader({
46
+ onClose,
47
+ onEditTask,
48
+ onDeleteTask,
49
+ }: TaskDetailsHeaderProps) {
50
+ const { task } = useContext(TaskDetailsContext);
51
+ const [isDescriptionExpanded, setIsDescriptionExpanded] = useState(false);
52
+
53
+ return (
54
+ <div>
55
+ {/* Title and Task Actions */}
56
+ <div className="p-4 pb-2">
57
+ <div className="flex items-start justify-between">
58
+ <div className="flex-1 min-w-0">
59
+ <h2 className="text-lg font-bold mb-1 line-clamp-2">
60
+ {task.title}
61
+ </h2>
62
+ <div className="flex items-center gap-2 text-sm text-muted-foreground">
63
+ <Chip dotColor={getTaskStatusDotColor(task.status)}>
64
+ {statusLabels[task.status]}
65
+ </Chip>
66
+ </div>
67
+ </div>
68
+ <div className="flex items-center gap-1">
69
+ {onEditTask && (
70
+ <TooltipProvider>
71
+ <Tooltip>
72
+ <TooltipTrigger asChild>
73
+ <Button
74
+ variant="ghost"
75
+ size="icon"
76
+ onClick={() => onEditTask(task)}
77
+ >
78
+ <Edit className="h-4 w-4" />
79
+ </Button>
80
+ </TooltipTrigger>
81
+ <TooltipContent>
82
+ <p>Edit task</p>
83
+ </TooltipContent>
84
+ </Tooltip>
85
+ </TooltipProvider>
86
+ )}
87
+ {onDeleteTask && (
88
+ <TooltipProvider>
89
+ <Tooltip>
90
+ <TooltipTrigger asChild>
91
+ <Button
92
+ variant="ghost"
93
+ size="icon"
94
+ onClick={() => onDeleteTask(task.id)}
95
+ >
96
+ <Trash2 className="h-4 w-4 text-red-500" />
97
+ </Button>
98
+ </TooltipTrigger>
99
+ <TooltipContent>
100
+ <p>Delete task</p>
101
+ </TooltipContent>
102
+ </Tooltip>
103
+ </TooltipProvider>
104
+ )}
105
+ <TooltipProvider>
106
+ <Tooltip>
107
+ <TooltipTrigger asChild>
108
+ <Button variant="ghost" size="icon" onClick={onClose}>
109
+ <X className="h-4 w-4" />
110
+ </Button>
111
+ </TooltipTrigger>
112
+ <TooltipContent>
113
+ <p>Close panel</p>
114
+ </TooltipContent>
115
+ </Tooltip>
116
+ </TooltipProvider>
117
+ </div>
118
+ </div>
119
+
120
+ {/* Description */}
121
+ <div className="mt-2">
122
+ <div className="p-2 bg-muted/20 rounded border-l-2 border-muted max-h-48 overflow-y-auto">
123
+ {task.description ? (
124
+ <div>
125
+ <p
126
+ className={`text-xs whitespace-pre-wrap text-muted-foreground ${
127
+ !isDescriptionExpanded && task.description.length > 150
128
+ ? 'line-clamp-3'
129
+ : ''
130
+ }`}
131
+ >
132
+ {task.description}
133
+ </p>
134
+ {task.description.length > 150 && (
135
+ <Button
136
+ variant="ghost"
137
+ size="sm"
138
+ onClick={() =>
139
+ setIsDescriptionExpanded(!isDescriptionExpanded)
140
+ }
141
+ className="mt-1 p-0 h-auto text-xs text-muted-foreground hover:text-foreground"
142
+ >
143
+ {isDescriptionExpanded ? (
144
+ <>
145
+ <ChevronUp className="h-3 w-3 mr-1" />
146
+ Show less
147
+ </>
148
+ ) : (
149
+ <>
150
+ <ChevronDown className="h-3 w-3 mr-1" />
151
+ Show more
152
+ </>
153
+ )}
154
+ </Button>
155
+ )}
156
+ </div>
157
+ ) : (
158
+ <p className="text-xs text-muted-foreground italic">
159
+ No description provided
160
+ </p>
161
+ )}
162
+ </div>
163
+ </div>
164
+ </div>
165
+ </div>
166
+ );
167
+ }
168
+
169
+ export default memo(TaskDetailsHeader);
@@ -0,0 +1,126 @@
1
+ import { useEffect, useState } from 'react';
2
+ import TaskDetailsHeader from './TaskDetailsHeader';
3
+ import { TaskFollowUpSection } from './TaskFollowUpSection';
4
+ import { EditorSelectionDialog } from './EditorSelectionDialog';
5
+ import {
6
+ getBackdropClasses,
7
+ getTaskPanelClasses,
8
+ } from '@/lib/responsive-config';
9
+ import type { TaskWithAttemptStatus } from 'shared/types';
10
+ import DiffTab from '@/components/tasks/TaskDetails/DiffTab.tsx';
11
+ import LogsTab from '@/components/tasks/TaskDetails/LogsTab.tsx';
12
+ import RelatedTasksTab from '@/components/tasks/TaskDetails/RelatedTasksTab.tsx';
13
+ import ProcessesTab from '@/components/tasks/TaskDetails/ProcessesTab.tsx';
14
+ import DeleteFileConfirmationDialog from '@/components/tasks/DeleteFileConfirmationDialog.tsx';
15
+ import TabNavigation from '@/components/tasks/TaskDetails/TabNavigation.tsx';
16
+ import CollapsibleToolbar from '@/components/tasks/TaskDetails/CollapsibleToolbar.tsx';
17
+ import TaskDetailsProvider from '../context/TaskDetailsContextProvider.tsx';
18
+
19
+ interface TaskDetailsPanelProps {
20
+ task: TaskWithAttemptStatus | null;
21
+ projectHasDevScript?: boolean;
22
+ projectId: string;
23
+ onClose: () => void;
24
+ onEditTask?: (task: TaskWithAttemptStatus) => void;
25
+ onDeleteTask?: (taskId: string) => void;
26
+ isDialogOpen?: boolean;
27
+ }
28
+
29
+ export function TaskDetailsPanel({
30
+ task,
31
+ projectHasDevScript,
32
+ projectId,
33
+ onClose,
34
+ onEditTask,
35
+ onDeleteTask,
36
+ isDialogOpen = false,
37
+ }: TaskDetailsPanelProps) {
38
+ const [showEditorDialog, setShowEditorDialog] = useState(false);
39
+
40
+ // Tab and collapsible state
41
+ const [activeTab, setActiveTab] = useState<
42
+ 'logs' | 'diffs' | 'related' | 'processes'
43
+ >('logs');
44
+
45
+ // Reset to logs tab when task changes
46
+ useEffect(() => {
47
+ if (task?.id) {
48
+ setActiveTab('logs');
49
+ }
50
+ }, [task?.id]);
51
+
52
+ // Handle ESC key locally to prevent global navigation
53
+ useEffect(() => {
54
+ if (isDialogOpen) return;
55
+
56
+ const handleKeyDown = (event: KeyboardEvent) => {
57
+ if (event.key === 'Escape') {
58
+ event.preventDefault();
59
+ event.stopPropagation();
60
+ onClose();
61
+ }
62
+ };
63
+
64
+ document.addEventListener('keydown', handleKeyDown, true);
65
+ return () => document.removeEventListener('keydown', handleKeyDown, true);
66
+ }, [onClose, isDialogOpen]);
67
+
68
+ return (
69
+ <>
70
+ {!task ? null : (
71
+ <TaskDetailsProvider
72
+ key={task.id}
73
+ task={task}
74
+ projectId={projectId}
75
+ setShowEditorDialog={setShowEditorDialog}
76
+ projectHasDevScript={projectHasDevScript}
77
+ >
78
+ {/* Backdrop - only on smaller screens (overlay mode) */}
79
+ <div className={getBackdropClasses()} onClick={onClose} />
80
+
81
+ {/* Panel */}
82
+ <div className={getTaskPanelClasses()}>
83
+ <div className="flex flex-col h-full">
84
+ <TaskDetailsHeader
85
+ onClose={onClose}
86
+ onEditTask={onEditTask}
87
+ onDeleteTask={onDeleteTask}
88
+ />
89
+
90
+ <CollapsibleToolbar />
91
+
92
+ <TabNavigation
93
+ activeTab={activeTab}
94
+ setActiveTab={setActiveTab}
95
+ />
96
+
97
+ {/* Tab Content */}
98
+ <div
99
+ className={`flex-1 flex flex-col min-h-0 ${activeTab === 'logs' ? 'p-4' : 'pt-4'}`}
100
+ >
101
+ {activeTab === 'diffs' ? (
102
+ <DiffTab />
103
+ ) : activeTab === 'related' ? (
104
+ <RelatedTasksTab />
105
+ ) : activeTab === 'processes' ? (
106
+ <ProcessesTab />
107
+ ) : (
108
+ <LogsTab />
109
+ )}
110
+ </div>
111
+
112
+ <TaskFollowUpSection />
113
+ </div>
114
+ </div>
115
+
116
+ <EditorSelectionDialog
117
+ isOpen={showEditorDialog}
118
+ onClose={() => setShowEditorDialog(false)}
119
+ />
120
+
121
+ <DeleteFileConfirmationDialog />
122
+ </TaskDetailsProvider>
123
+ )}
124
+ </>
125
+ );
126
+ }