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,20 @@
1
+ -- Migration to update executor type names from snake_case/camelCase to kebab-case
2
+ -- This handles the change from charmopencode -> charm-opencode and setup_script -> setup-script
3
+
4
+ -- Update task_attempts.executor column
5
+ UPDATE task_attempts
6
+ SET executor = 'charm-opencode'
7
+ WHERE executor = 'charmopencode';
8
+
9
+ UPDATE task_attempts
10
+ SET executor = 'setup-script'
11
+ WHERE executor = 'setup_script';
12
+
13
+ -- Update execution_processes.executor_type column
14
+ UPDATE execution_processes
15
+ SET executor_type = 'charm-opencode'
16
+ WHERE executor_type = 'charmopencode';
17
+
18
+ UPDATE execution_processes
19
+ SET executor_type = 'setup-script'
20
+ WHERE executor_type = 'setup_script';
@@ -0,0 +1,7 @@
1
+ PRAGMA foreign_keys = ON;
2
+
3
+ -- Add parent_task_attempt column to tasks table
4
+ ALTER TABLE tasks ADD COLUMN parent_task_attempt BLOB REFERENCES task_attempts(id);
5
+
6
+ -- Create index for parent_task_attempt lookups
7
+ CREATE INDEX idx_tasks_parent_task_attempt ON tasks(parent_task_attempt);
@@ -0,0 +1,9 @@
1
+ -- Migration to drop task_attempt_activities table
2
+ -- This removes the task attempt activity tracking functionality
3
+
4
+ -- Drop indexes first
5
+ DROP INDEX IF EXISTS idx_task_attempt_activities_execution_process_id;
6
+ DROP INDEX IF EXISTS idx_task_attempt_activities_created_at;
7
+
8
+ -- Drop the table
9
+ DROP TABLE IF EXISTS task_attempt_activities;
@@ -0,0 +1,2 @@
1
+ -- Add cleanup_script column to projects table
2
+ ALTER TABLE projects ADD COLUMN cleanup_script TEXT;
@@ -0,0 +1,25 @@
1
+ -- 1. Add the replacement column with the wider CHECK
2
+ ALTER TABLE execution_processes
3
+ ADD COLUMN process_type_new TEXT NOT NULL DEFAULT 'setupscript'
4
+ CHECK (process_type_new IN ('setupscript',
5
+ 'cleanupscript', -- new value 🎉
6
+ 'codingagent',
7
+ 'devserver'));
8
+
9
+ -- 2. Copy existing values across
10
+ UPDATE execution_processes
11
+ SET process_type_new = process_type;
12
+
13
+ -- 3. Drop any indexes that mention the old column
14
+ DROP INDEX IF EXISTS idx_execution_processes_type;
15
+
16
+ -- 4. Remove the old column (requires 3.35+)
17
+ ALTER TABLE execution_processes DROP COLUMN process_type;
18
+
19
+ -- 5. Rename the new column back to the canonical name
20
+ ALTER TABLE execution_processes
21
+ RENAME COLUMN process_type_new TO process_type;
22
+
23
+ -- 6. Re-create the index
24
+ CREATE INDEX idx_execution_processes_type
25
+ ON execution_processes(process_type);
@@ -0,0 +1,7 @@
1
+ PRAGMA foreign_keys = ON;
2
+
3
+ -- Add wish_id column to tasks table as required field
4
+ ALTER TABLE tasks ADD COLUMN wish_id TEXT NOT NULL DEFAULT '';
5
+
6
+ -- Create index for wish_id lookups
7
+ CREATE INDEX idx_tasks_wish_id ON tasks(wish_id);
@@ -0,0 +1,5 @@
1
+ PRAGMA foreign_keys = ON;
2
+
3
+ -- Remove the unique constraint index for wish_id that was incorrectly added
4
+ -- wish_id is meant for grouping tasks, not uniqueness
5
+ DROP INDEX IF EXISTS unique_wish_per_project;
@@ -0,0 +1,23 @@
1
+ param(
2
+ [Parameter(Mandatory=$true)]
3
+ [string]$Title,
4
+
5
+ [Parameter(Mandatory=$true)]
6
+ [string]$Message,
7
+
8
+ [Parameter(Mandatory=$false)]
9
+ [string]$AppName = "Automagik Forge"
10
+ )
11
+
12
+ [Windows.UI.Notifications.ToastNotificationManager, Windows.UI.Notifications, ContentType = WindowsRuntime] | Out-Null
13
+ $Template = [Windows.UI.Notifications.ToastNotificationManager]::GetTemplateContent([Windows.UI.Notifications.ToastTemplateType]::ToastText02)
14
+ $RawXml = [xml] $Template.GetXml()
15
+ ($RawXml.toast.visual.binding.text|where {$_.id -eq "1"}).AppendChild($RawXml.CreateTextNode($Title)) | Out-Null
16
+ ($RawXml.toast.visual.binding.text|where {$_.id -eq "2"}).AppendChild($RawXml.CreateTextNode($Message)) | Out-Null
17
+ $SerializedXml = New-Object Windows.Data.Xml.Dom.XmlDocument
18
+ $SerializedXml.LoadXml($RawXml.OuterXml)
19
+ $Toast = [Windows.UI.Notifications.ToastNotification]::new($SerializedXml)
20
+ $Toast.Tag = $AppName
21
+ $Toast.Group = $AppName
22
+ $Notifier = [Windows.UI.Notifications.ToastNotificationManager]::CreateToastNotifier($AppName)
23
+ $Notifier.Show($Toast)
Binary file
Binary file
@@ -0,0 +1,218 @@
1
+ use std::{collections::HashMap, sync::Arc, time::Duration};
2
+
3
+ #[cfg(unix)]
4
+ use nix::{sys::signal::Signal, unistd::Pid};
5
+ use tokio::sync::{Mutex, RwLock as TokioRwLock};
6
+ use uuid::Uuid;
7
+
8
+ use crate::services::{generate_user_id, AnalyticsConfig, AnalyticsService};
9
+
10
+ #[derive(Debug)]
11
+ pub enum ExecutionType {
12
+ SetupScript,
13
+ CleanupScript,
14
+ CodingAgent,
15
+ DevServer,
16
+ }
17
+
18
+ #[derive(Debug)]
19
+ pub struct RunningExecution {
20
+ pub task_attempt_id: Uuid,
21
+ pub _execution_type: ExecutionType,
22
+ pub child: command_group::AsyncGroupChild,
23
+ }
24
+
25
+ #[derive(Debug, Clone)]
26
+ pub struct AppState {
27
+ running_executions: Arc<Mutex<HashMap<Uuid, RunningExecution>>>,
28
+ pub db_pool: sqlx::SqlitePool,
29
+ config: Arc<tokio::sync::RwLock<crate::models::config::Config>>,
30
+ pub analytics: Arc<TokioRwLock<AnalyticsService>>,
31
+ user_id: String,
32
+ }
33
+
34
+ impl AppState {
35
+ pub async fn new(
36
+ db_pool: sqlx::SqlitePool,
37
+ config: Arc<tokio::sync::RwLock<crate::models::config::Config>>,
38
+ ) -> Self {
39
+ // Initialize analytics with user preferences
40
+ let user_enabled = {
41
+ let config_guard = config.read().await;
42
+ config_guard.analytics_enabled.unwrap_or(true)
43
+ };
44
+
45
+ let analytics_config = AnalyticsConfig::new(user_enabled);
46
+ let analytics = Arc::new(TokioRwLock::new(AnalyticsService::new(analytics_config)));
47
+
48
+ Self {
49
+ running_executions: Arc::new(Mutex::new(HashMap::new())),
50
+ db_pool,
51
+ config,
52
+ analytics,
53
+ user_id: generate_user_id(),
54
+ }
55
+ }
56
+
57
+ pub async fn update_analytics_config(&self, user_enabled: bool) {
58
+ // Check if analytics was disabled before this update
59
+ let was_analytics_disabled = {
60
+ let analytics = self.analytics.read().await;
61
+ !analytics.is_enabled()
62
+ };
63
+
64
+ let new_config = AnalyticsConfig::new(user_enabled);
65
+ let new_service = AnalyticsService::new(new_config);
66
+ let mut analytics = self.analytics.write().await;
67
+ *analytics = new_service;
68
+
69
+ // If analytics was disabled and is now enabled, fire a session_start event
70
+ if was_analytics_disabled && analytics.is_enabled() {
71
+ analytics.track_event(&self.user_id, "session_start", None);
72
+ }
73
+ }
74
+
75
+ // Running executions getters
76
+ pub async fn has_running_execution(&self, attempt_id: Uuid) -> bool {
77
+ let executions = self.running_executions.lock().await;
78
+ executions
79
+ .values()
80
+ .any(|exec| exec.task_attempt_id == attempt_id)
81
+ }
82
+
83
+ pub async fn get_running_executions_for_monitor(&self) -> Vec<(Uuid, Uuid, bool, Option<i64>)> {
84
+ let mut executions = self.running_executions.lock().await;
85
+ let mut completed_executions = Vec::new();
86
+
87
+ for (execution_id, running_exec) in executions.iter_mut() {
88
+ match running_exec.child.try_wait() {
89
+ Ok(Some(status)) => {
90
+ let success = status.success();
91
+ let exit_code = status.code().map(|c| c as i64);
92
+ completed_executions.push((
93
+ *execution_id,
94
+ running_exec.task_attempt_id,
95
+ success,
96
+ exit_code,
97
+ ));
98
+ }
99
+ Ok(None) => {
100
+ // Still running
101
+ }
102
+ Err(e) => {
103
+ tracing::error!("Error checking process status: {}", e);
104
+ completed_executions.push((
105
+ *execution_id,
106
+ running_exec.task_attempt_id,
107
+ false,
108
+ None,
109
+ ));
110
+ }
111
+ }
112
+ }
113
+
114
+ // Remove completed executions from the map
115
+ for (execution_id, _, _, _) in &completed_executions {
116
+ executions.remove(execution_id);
117
+ }
118
+
119
+ completed_executions
120
+ }
121
+
122
+ // Running executions setters
123
+ pub async fn add_running_execution(&self, execution_id: Uuid, execution: RunningExecution) {
124
+ let mut executions = self.running_executions.lock().await;
125
+ executions.insert(execution_id, execution);
126
+ }
127
+
128
+ pub async fn stop_running_execution_by_id(
129
+ &self,
130
+ execution_id: Uuid,
131
+ ) -> Result<bool, Box<dyn std::error::Error + Send + Sync>> {
132
+ let mut executions = self.running_executions.lock().await;
133
+ let Some(exec) = executions.get_mut(&execution_id) else {
134
+ return Ok(false);
135
+ };
136
+
137
+ // hit the whole process group, not just the leader
138
+ #[cfg(unix)]
139
+ {
140
+ use nix::{sys::signal::killpg, unistd::getpgid};
141
+
142
+ let pgid = getpgid(Some(Pid::from_raw(exec.child.id().unwrap() as i32)))?;
143
+ for sig in [Signal::SIGINT, Signal::SIGTERM, Signal::SIGKILL] {
144
+ killpg(pgid, sig)?;
145
+ tokio::time::sleep(Duration::from_secs(2)).await;
146
+ if exec.child.try_wait()?.is_some() {
147
+ break; // gone!
148
+ }
149
+ }
150
+ }
151
+
152
+ // final fallback – command_group already targets the group
153
+ exec.child.kill().await.ok();
154
+ exec.child.wait().await.ok(); // reap
155
+
156
+ // only NOW remove it
157
+ executions.remove(&execution_id);
158
+ Ok(true)
159
+ }
160
+
161
+ // Config getters
162
+ pub async fn get_sound_alerts_enabled(&self) -> bool {
163
+ let config = self.config.read().await;
164
+ config.sound_alerts
165
+ }
166
+
167
+ pub async fn get_push_notifications_enabled(&self) -> bool {
168
+ let config = self.config.read().await;
169
+ config.push_notifications
170
+ }
171
+
172
+ pub async fn get_sound_file(&self) -> crate::models::config::SoundFile {
173
+ let config = self.config.read().await;
174
+ config.sound_file.clone()
175
+ }
176
+
177
+ pub fn get_config(&self) -> &Arc<tokio::sync::RwLock<crate::models::config::Config>> {
178
+ &self.config
179
+ }
180
+
181
+ pub async fn track_analytics_event(
182
+ &self,
183
+ event_name: &str,
184
+ properties: Option<serde_json::Value>,
185
+ ) {
186
+ let analytics = self.analytics.read().await;
187
+ if analytics.is_enabled() {
188
+ analytics.track_event(&self.user_id, event_name, properties);
189
+ } else {
190
+ tracing::debug!("Analytics disabled, skipping event: {}", event_name);
191
+ }
192
+ }
193
+
194
+ pub async fn update_sentry_scope(&self) {
195
+ let config = self.get_config().read().await;
196
+ let username = config.github.username.clone();
197
+ let email = config.github.primary_email.clone();
198
+ drop(config);
199
+
200
+ let sentry_user = if username.is_some() || email.is_some() {
201
+ sentry::User {
202
+ id: Some(self.user_id.clone()),
203
+ username,
204
+ email,
205
+ ..Default::default()
206
+ }
207
+ } else {
208
+ sentry::User {
209
+ id: Some(self.user_id.clone()),
210
+ ..Default::default()
211
+ }
212
+ };
213
+
214
+ sentry::configure_scope(|scope| {
215
+ scope.set_user(Some(sentry_user));
216
+ });
217
+ }
218
+ }
@@ -0,0 +1,189 @@
1
+ use std::{env, fs, path::Path};
2
+
3
+ use ts_rs::TS;
4
+ // in [build-dependencies]
5
+
6
+ fn generate_constants() -> String {
7
+ r#"// Generated constants
8
+ export const EXECUTOR_TYPES: string[] = [
9
+ "echo",
10
+ "claude",
11
+ "claude-plan",
12
+ "amp",
13
+ "gemini",
14
+ "charm-opencode",
15
+ "claude-code-router",
16
+ "sst-opencode",
17
+ "opencode-ai"
18
+ ];
19
+
20
+ export const EDITOR_TYPES: EditorType[] = [
21
+ "vscode",
22
+ "cursor",
23
+ "windsurf",
24
+ "intellij",
25
+ "zed",
26
+ "custom"
27
+ ];
28
+
29
+ export const EXECUTOR_LABELS: Record<string, string> = {
30
+ "echo": "Echo (Test Mode)",
31
+ "claude": "Claude Code",
32
+ "claude-plan": "Claude Code Plan",
33
+ "amp": "Amp",
34
+ "gemini": "Gemini",
35
+ "charm-opencode": "Charm Opencode",
36
+ "claude-code-router": "Claude Code Router",
37
+ "sst-opencode": "SST Opencode",
38
+ "opencode-ai": "OpenCode AI"
39
+ };
40
+
41
+ export const EDITOR_LABELS: Record<string, string> = {
42
+ "vscode": "VS Code",
43
+ "cursor": "Cursor",
44
+ "windsurf": "Windsurf",
45
+ "intellij": "IntelliJ IDEA",
46
+ "zed": "Zed",
47
+ "custom": "Custom"
48
+ };
49
+
50
+ export const SOUND_FILES: SoundFile[] = [
51
+ "abstract-sound1",
52
+ "abstract-sound2",
53
+ "abstract-sound3",
54
+ "abstract-sound4",
55
+ "cow-mooing",
56
+ "phone-vibration",
57
+ "rooster"
58
+ ];
59
+
60
+ export const SOUND_LABELS: Record<string, string> = {
61
+ "abstract-sound1": "Gentle Chime",
62
+ "abstract-sound2": "Soft Bell",
63
+ "abstract-sound3": "Digital Tone",
64
+ "abstract-sound4": "Subtle Alert",
65
+ "cow-mooing": "Cow Mooing",
66
+ "phone-vibration": "Phone Vibration",
67
+ "rooster": "Rooster Call"
68
+ };"#
69
+ .to_string()
70
+ }
71
+
72
+ fn generate_types_content() -> String {
73
+ // 4. Friendly banner
74
+ const HEADER: &str =
75
+ "// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs).\n\
76
+ // Do not edit this file manually.\n\
77
+ // Auto-generated from Rust backend types using ts-rs\n\n";
78
+
79
+ // 5. Add `export` if it’s missing, then join
80
+ let decls = [
81
+ automagik_forge::models::ApiResponse::<()>::decl(),
82
+ automagik_forge::models::config::Config::decl(),
83
+ automagik_forge::models::config::ThemeMode::decl(),
84
+ automagik_forge::models::config::EditorConfig::decl(),
85
+ automagik_forge::models::config::GitHubConfig::decl(),
86
+ automagik_forge::models::config::EditorType::decl(),
87
+ automagik_forge::models::config::EditorConstants::decl(),
88
+ automagik_forge::models::config::SoundFile::decl(),
89
+ automagik_forge::models::config::SoundConstants::decl(),
90
+ automagik_forge::routes::config::ConfigConstants::decl(),
91
+ automagik_forge::executor::ExecutorConfig::decl(),
92
+ automagik_forge::executor::ExecutorConstants::decl(),
93
+ automagik_forge::models::project::CreateProject::decl(),
94
+ automagik_forge::models::project::Project::decl(),
95
+ automagik_forge::models::project::ProjectWithBranch::decl(),
96
+ automagik_forge::models::project::UpdateProject::decl(),
97
+ automagik_forge::models::project::SearchResult::decl(),
98
+ automagik_forge::models::project::SearchMatchType::decl(),
99
+ automagik_forge::models::project::GitBranch::decl(),
100
+ automagik_forge::models::project::CreateBranch::decl(),
101
+ automagik_forge::models::task::CreateTask::decl(),
102
+ automagik_forge::models::task::CreateTaskAndStart::decl(),
103
+ automagik_forge::models::task::TaskStatus::decl(),
104
+ automagik_forge::models::task::Task::decl(),
105
+ automagik_forge::models::task::TaskWithAttemptStatus::decl(),
106
+ automagik_forge::models::task::UpdateTask::decl(),
107
+ automagik_forge::models::task_template::TaskTemplate::decl(),
108
+ automagik_forge::models::task_template::CreateTaskTemplate::decl(),
109
+ automagik_forge::models::task_template::UpdateTaskTemplate::decl(),
110
+ automagik_forge::models::task_attempt::TaskAttemptStatus::decl(),
111
+ automagik_forge::models::task_attempt::TaskAttempt::decl(),
112
+ automagik_forge::models::task_attempt::CreateTaskAttempt::decl(),
113
+ automagik_forge::models::task_attempt::UpdateTaskAttempt::decl(),
114
+ automagik_forge::models::task_attempt::CreateFollowUpAttempt::decl(),
115
+ automagik_forge::routes::filesystem::DirectoryEntry::decl(),
116
+ automagik_forge::routes::filesystem::DirectoryListResponse::decl(),
117
+ automagik_forge::routes::auth::DeviceStartResponse::decl(),
118
+ automagik_forge::routes::task_attempts::ProcessLogsResponse::decl(),
119
+ automagik_forge::models::task_attempt::DiffChunkType::decl(),
120
+ automagik_forge::models::task_attempt::DiffChunk::decl(),
121
+ automagik_forge::models::task_attempt::FileDiff::decl(),
122
+ automagik_forge::models::task_attempt::WorktreeDiff::decl(),
123
+ automagik_forge::models::task_attempt::BranchStatus::decl(),
124
+ automagik_forge::models::task_attempt::ExecutionState::decl(),
125
+ automagik_forge::models::task_attempt::TaskAttemptState::decl(),
126
+ automagik_forge::models::execution_process::ExecutionProcess::decl(),
127
+ automagik_forge::models::execution_process::ExecutionProcessSummary::decl(),
128
+ automagik_forge::models::execution_process::ExecutionProcessStatus::decl(),
129
+ automagik_forge::models::execution_process::ExecutionProcessType::decl(),
130
+ automagik_forge::models::execution_process::CreateExecutionProcess::decl(),
131
+ automagik_forge::models::execution_process::UpdateExecutionProcess::decl(),
132
+ automagik_forge::models::executor_session::ExecutorSession::decl(),
133
+ automagik_forge::models::executor_session::CreateExecutorSession::decl(),
134
+ automagik_forge::models::executor_session::UpdateExecutorSession::decl(),
135
+ automagik_forge::executor::NormalizedConversation::decl(),
136
+ automagik_forge::executor::NormalizedEntry::decl(),
137
+ automagik_forge::executor::NormalizedEntryType::decl(),
138
+ automagik_forge::executor::ActionType::decl(),
139
+ ];
140
+
141
+ let body = decls
142
+ .into_iter()
143
+ .map(|d| {
144
+ let trimmed = d.trim_start();
145
+ if trimmed.starts_with("export") {
146
+ d
147
+ } else {
148
+ format!("export {trimmed}")
149
+ }
150
+ })
151
+ .collect::<Vec<_>>()
152
+ .join("\n\n");
153
+
154
+ let constants = generate_constants();
155
+ format!("{HEADER}{body}\n\n{constants}")
156
+ }
157
+
158
+ fn main() {
159
+ let args: Vec<String> = env::args().collect();
160
+ let check_mode = args.iter().any(|arg| arg == "--check");
161
+
162
+ // 1. Make sure ../shared exists
163
+ let shared_path = Path::new("../shared");
164
+ fs::create_dir_all(shared_path).expect("cannot create ../shared");
165
+
166
+ println!("Generating TypeScript types…");
167
+
168
+ // 2. Let ts-rs write its per-type files here (handy for debugging)
169
+ env::set_var("TS_RS_EXPORT_DIR", shared_path.to_str().unwrap());
170
+
171
+ let generated = generate_types_content();
172
+ let types_path = shared_path.join("types.ts");
173
+
174
+ if check_mode {
175
+ // Read the current file
176
+ let current = fs::read_to_string(&types_path).unwrap_or_default();
177
+ if current == generated {
178
+ println!("✅ shared/types.ts is up to date.");
179
+ std::process::exit(0);
180
+ } else {
181
+ eprintln!("❌ shared/types.ts is not up to date. Please run 'npm run generate-types' and commit the changes.");
182
+ std::process::exit(1);
183
+ }
184
+ } else {
185
+ // Write the file as before
186
+ fs::write(&types_path, generated).expect("unable to write types.ts");
187
+ println!("✅ TypeScript types generated in ../shared/");
188
+ }
189
+ }