automagik-forge 0.1.13 → 0.1.14

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/README.md +143 -447
  2. package/dist/linux-x64/automagik-forge-mcp.zip +0 -0
  3. package/{npx-cli/automagik-forge-0.0.55.tgz → dist/linux-x64/automagik-forge.zip} +0 -0
  4. package/package.json +13 -23
  5. package/.cargo/config.toml +0 -13
  6. package/.claude/commands/commit.md +0 -376
  7. package/.claude/commands/prompt.md +0 -871
  8. package/.env.example +0 -20
  9. package/.github/actions/setup-node/action.yml +0 -29
  10. package/.github/images/automagik-logo.png +0 -0
  11. package/.github/workflows/pre-release.yml +0 -470
  12. package/.github/workflows/publish.yml +0 -145
  13. package/.github/workflows/test.yml +0 -63
  14. package/.mcp.json +0 -57
  15. package/AGENT.md +0 -40
  16. package/CLAUDE.md +0 -40
  17. package/CODE-OF-CONDUCT.md +0 -89
  18. package/Cargo.toml +0 -19
  19. package/Dockerfile +0 -43
  20. package/LICENSE +0 -201
  21. package/Makefile +0 -97
  22. package/backend/.sqlx/query-01b7e2bac1261d8be3d03c03df3e5220590da6c31c77f161074fc62752d63881.json +0 -12
  23. package/backend/.sqlx/query-03f2b02ba6dc5ea2b3cf6b1004caea0ad6bcc10ebd63f441d321a389f026e263.json +0 -12
  24. package/backend/.sqlx/query-0923b77d137a29fc54d399a873ff15fc4af894490bc65a4d344a7575cb0d8643.json +0 -12
  25. package/backend/.sqlx/query-0f808bcdb63c5f180836e448dd64c435c51758b2fc54a52ce9e67495b1ab200e.json +0 -68
  26. package/backend/.sqlx/query-1268afe9ca849daa6722e3df7ca8e9e61f0d37052e782bb5452ab8e1018d9b63.json +0 -12
  27. package/backend/.sqlx/query-1b082630a9622f8667ee7a9aba2c2d3176019a68c6bb83d33008594821415a57.json +0 -12
  28. package/backend/.sqlx/query-1c7b06ba1e112abf6b945a2ff08a0b40ec23f3738c2e7399f067b558cf8d490e.json +0 -12
  29. package/backend/.sqlx/query-1f619f01f46859a64ded531dd0ef61abacfe62e758abe7030a6aa745140b95ca.json +0 -104
  30. package/backend/.sqlx/query-1fca1ce14b4b20205364cd1f1f45ebe1d2e30cd745e59e189d56487b5639dfbb.json +0 -12
  31. package/backend/.sqlx/query-212828320e8d871ab9d83705a040b23bcf0393dc7252177fc539a74657f578ef.json +0 -32
  32. package/backend/.sqlx/query-290ce5c152be8d36e58ff42570f9157beb07ab9e77a03ec6fc30b4f56f9b8f6b.json +0 -56
  33. package/backend/.sqlx/query-2b471d2c2e8ffbe0cd42d2a91b814c0d79f9d09200f147e3cea33ba4ce673c8a.json +0 -68
  34. package/backend/.sqlx/query-354a48c705bb9bb2048c1b7f10fcb714e23f9db82b7a4ea6932486197b2ede6a.json +0 -92
  35. package/backend/.sqlx/query-36c9e3dd10648e94b949db5c91a774ecb1e10a899ef95da74066eccedca4d8b2.json +0 -12
  36. package/backend/.sqlx/query-36e4ba7bbd81b402d5a20b6005755eafbb174c8dda442081823406ac32809a94.json +0 -56
  37. package/backend/.sqlx/query-3a5b3c98a55ca183ab20c74708e3d7e579dda37972c059e7515c4ceee4bd8dd3.json +0 -62
  38. package/backend/.sqlx/query-3d0a1cabf2a52e9d90cdfd29c509ca89aeb448d0c1d2446c65cd43db40735e86.json +0 -62
  39. package/backend/.sqlx/query-3d6bd16fbce59efe30b7f67ea342e0e4ea6d1432389c02468ad79f1f742d4031.json +0 -56
  40. package/backend/.sqlx/query-4049ca413b285a05aca6b25385e9c8185575f01e9069e4e8581aa45d713f612f.json +0 -32
  41. package/backend/.sqlx/query-412bacd3477d86369082e90f52240407abce436cb81292d42b2dbe1e5c18eea1.json +0 -104
  42. package/backend/.sqlx/query-417a8b1ff4e51de82aea0159a3b97932224dc325b23476cb84153d690227fd8b.json +0 -62
  43. package/backend/.sqlx/query-461cc1b0bb6fd909afc9dd2246e8526b3771cfbb0b22ae4b5d17b51af587b9e2.json +0 -56
  44. package/backend/.sqlx/query-58408c7a8cdeeda0bef359f1f9bd91299a339dc2b191462fc58c9736a56d5227.json +0 -92
  45. package/backend/.sqlx/query-5a886026d75d515c01f347cc203c8d99dd04c61dc468e2e4c5aa548436d13834.json +0 -62
  46. package/backend/.sqlx/query-5b902137b11022d2e1a5c4f6a9c83fec1a856c6a710aff831abd2382ede76b43.json +0 -12
  47. package/backend/.sqlx/query-5ed1238e52e59bb5f76c0f153fd99a14093f7ce2585bf9843585608f17ec575b.json +0 -104
  48. package/backend/.sqlx/query-6e8b860b14decfc2227dc57213f38442943d3fbef5c8418fd6b634c6e0f5e2ea.json +0 -104
  49. package/backend/.sqlx/query-6ec414276994c4ccb2433eaa5b1b342168557d17ddf5a52dac84cb1b59b9de8f.json +0 -68
  50. package/backend/.sqlx/query-6ecfa16d0cf825aacf233544b5baf151e9adfdca26c226ad71020d291fd802d5.json +0 -62
  51. package/backend/.sqlx/query-72509d252c39fce77520aa816cb2acbc1fb35dc2605e7be893610599b2427f2e.json +0 -62
  52. package/backend/.sqlx/query-75239b2da188f749707d77f3c1544332ca70db3d6d6743b2601dc0d167536437.json +0 -62
  53. package/backend/.sqlx/query-83d10e29f8478aff33434f9ac67068e013b888b953a2657e2bb72a6f619d04f2.json +0 -50
  54. package/backend/.sqlx/query-8610803360ea18b9b9d078a6981ea56abfbfe84e6354fc1d5ae4c622e01410ed.json +0 -68
  55. package/backend/.sqlx/query-86d03eb70eef39c59296416867f2ee66c9f7cd8b7f961fbda2f89fc0a1c442c2.json +0 -12
  56. package/backend/.sqlx/query-87d0feb5a6b442bad9c60068ea7569599cc6fc91a0e2692ecb42e93b03201b9d.json +0 -68
  57. package/backend/.sqlx/query-8a67b3b3337248f06a57bdf8a908f7ef23177431eaed82dc08c94c3e5944340e.json +0 -12
  58. package/backend/.sqlx/query-8f01ebd64bdcde6a090479f14810d73ba23020e76fd70854ac57f2da251702c3.json +0 -12
  59. package/backend/.sqlx/query-90fd607fcb2dca72239ff25e618e21e174b195991eaa33722cbf5f76da84cfab.json +0 -62
  60. package/backend/.sqlx/query-92e8bdbcd80c5ff3db7a35cf79492048803ef305cbdef0d0a1fe5dc881ca8c71.json +0 -104
  61. package/backend/.sqlx/query-93a1605f90e9672dad29b472b6ad85fa9a55ea3ffa5abcb8724b09d61be254ca.json +0 -20
  62. package/backend/.sqlx/query-9472c8fb477958167f5fae40b85ac44252468c5226b2cdd7770f027332eed6d7.json +0 -104
  63. package/backend/.sqlx/query-96036c4f9e0f48bdc5a4a4588f0c5f288ac7aaa5425cac40fc33f337e1a351f2.json +0 -56
  64. package/backend/.sqlx/query-9edb2c01e91fd0f0fe7b56e988c7ae0393150f50be3f419a981e035c0121dfc7.json +0 -104
  65. package/backend/.sqlx/query-a157cf00616f703bfba21927f1eb1c9eec2a81c02da15f66efdba0b6c375de1b.json +0 -26
  66. package/backend/.sqlx/query-a31fff84f3b8e532fd1160447d89d700f06ae08821fee00c9a5b60492b05259c.json +0 -62
  67. package/backend/.sqlx/query-a5ba908419fb3e456bdd2daca41ba06cc3212ffffb8520fc7dbbcc8b60ada314.json +0 -12
  68. package/backend/.sqlx/query-a6d2961718dbc3b1a925e549f49a159c561bef58c105529275f274b27e2eba5b.json +0 -104
  69. package/backend/.sqlx/query-a9e93d5b09b29faf66e387e4d7596a792d81e75c4d3726e83c2963e8d7c9b56f.json +0 -104
  70. package/backend/.sqlx/query-ac5247c8d7fb86e4650c4b0eb9420031614c831b7b085083bac20c1af314c538.json +0 -12
  71. package/backend/.sqlx/query-afef9467be74c411c4cb119a8b2b1aea53049877dfc30cc60b486134ba4b4c9f.json +0 -68
  72. package/backend/.sqlx/query-b2b2c6b4d0b1a347b5c4cb63c3a46a265d4db53be9554989a814b069d0af82f2.json +0 -62
  73. package/backend/.sqlx/query-c50d2ff0b12e5bcc81e371089ee2d007e233e7db93aefba4fef08e7aa68f5ab7.json +0 -20
  74. package/backend/.sqlx/query-c614e6056b244ca07f1b9d44e7edc9d5819225c6f8d9e077070c6e518a17f50b.json +0 -12
  75. package/backend/.sqlx/query-c67259be8bf4ee0cfd32167b2aa3b7fe9192809181a8171bf1c2d6df731967ae.json +0 -12
  76. package/backend/.sqlx/query-d2d0a1b985ebbca6a2b3e882a221a219f3199890fa640afc946ef1a792d6d8de.json +0 -12
  77. package/backend/.sqlx/query-d30aa5786757f32bf2b9c5fe51a45e506c71c28c5994e430d9b0546adb15ffa2.json +0 -20
  78. package/backend/.sqlx/query-d3b9ea1de1576af71b312924ce7f4ea8ae5dbe2ac138ea3b4470f2d5cd734846.json +0 -12
  79. package/backend/.sqlx/query-ed8456646fa69ddd412441955f06ff22bfb790f29466450735e0b8bb1bc4ec94.json +0 -12
  80. package/backend/Cargo.toml +0 -71
  81. package/backend/build.rs +0 -32
  82. package/backend/migrations/20250617183714_init.sql +0 -44
  83. package/backend/migrations/20250620212427_execution_processes.sql +0 -25
  84. package/backend/migrations/20250620214100_remove_stdout_stderr_from_task_attempts.sql +0 -28
  85. package/backend/migrations/20250621120000_relate_activities_to_execution_processes.sql +0 -23
  86. package/backend/migrations/20250623120000_executor_sessions.sql +0 -17
  87. package/backend/migrations/20250623130000_add_executor_type_to_execution_processes.sql +0 -4
  88. package/backend/migrations/20250625000000_add_dev_script_to_projects.sql +0 -4
  89. package/backend/migrations/20250701000000_add_branch_to_task_attempts.sql +0 -2
  90. package/backend/migrations/20250701000001_add_pr_tracking_to_task_attempts.sql +0 -5
  91. package/backend/migrations/20250701120000_add_assistant_message_to_executor_sessions.sql +0 -2
  92. package/backend/migrations/20250708000000_add_base_branch_to_task_attempts.sql +0 -2
  93. package/backend/migrations/20250709000000_add_worktree_deleted_flag.sql +0 -2
  94. package/backend/migrations/20250710000000_add_setup_completion.sql +0 -3
  95. package/backend/migrations/20250715154859_add_task_templates.sql +0 -25
  96. package/backend/migrations/20250716143725_add_default_templates.sql +0 -174
  97. package/backend/migrations/20250716161432_update_executor_names_to_kebab_case.sql +0 -20
  98. package/backend/migrations/20250716170000_add_parent_task_to_tasks.sql +0 -7
  99. package/backend/migrations/20250717000000_drop_task_attempt_activities.sql +0 -9
  100. package/backend/migrations/20250719000000_add_cleanup_script_to_projects.sql +0 -2
  101. package/backend/migrations/20250720000000_add_cleanupscript_to_process_type_constraint.sql +0 -25
  102. package/backend/migrations/20250723000000_add_wish_to_tasks.sql +0 -7
  103. package/backend/migrations/20250724000000_remove_unique_wish_constraint.sql +0 -5
  104. package/backend/scripts/toast-notification.ps1 +0 -23
  105. package/backend/sounds/abstract-sound1.wav +0 -0
  106. package/backend/sounds/abstract-sound2.wav +0 -0
  107. package/backend/sounds/abstract-sound3.wav +0 -0
  108. package/backend/sounds/abstract-sound4.wav +0 -0
  109. package/backend/sounds/cow-mooing.wav +0 -0
  110. package/backend/sounds/phone-vibration.wav +0 -0
  111. package/backend/sounds/rooster.wav +0 -0
  112. package/backend/src/app_state.rs +0 -218
  113. package/backend/src/bin/generate_types.rs +0 -189
  114. package/backend/src/bin/mcp_task_server.rs +0 -191
  115. package/backend/src/execution_monitor.rs +0 -1193
  116. package/backend/src/executor.rs +0 -1053
  117. package/backend/src/executors/amp.rs +0 -697
  118. package/backend/src/executors/ccr.rs +0 -91
  119. package/backend/src/executors/charm_opencode.rs +0 -113
  120. package/backend/src/executors/claude.rs +0 -887
  121. package/backend/src/executors/cleanup_script.rs +0 -124
  122. package/backend/src/executors/dev_server.rs +0 -53
  123. package/backend/src/executors/echo.rs +0 -79
  124. package/backend/src/executors/gemini/config.rs +0 -67
  125. package/backend/src/executors/gemini/streaming.rs +0 -363
  126. package/backend/src/executors/gemini.rs +0 -765
  127. package/backend/src/executors/mod.rs +0 -23
  128. package/backend/src/executors/opencode_ai.rs +0 -113
  129. package/backend/src/executors/setup_script.rs +0 -130
  130. package/backend/src/executors/sst_opencode/filter.rs +0 -184
  131. package/backend/src/executors/sst_opencode/tools.rs +0 -139
  132. package/backend/src/executors/sst_opencode.rs +0 -756
  133. package/backend/src/lib.rs +0 -45
  134. package/backend/src/main.rs +0 -324
  135. package/backend/src/mcp/mod.rs +0 -1
  136. package/backend/src/mcp/task_server.rs +0 -850
  137. package/backend/src/middleware/mod.rs +0 -3
  138. package/backend/src/middleware/model_loaders.rs +0 -242
  139. package/backend/src/models/api_response.rs +0 -36
  140. package/backend/src/models/config.rs +0 -375
  141. package/backend/src/models/execution_process.rs +0 -430
  142. package/backend/src/models/executor_session.rs +0 -225
  143. package/backend/src/models/mod.rs +0 -12
  144. package/backend/src/models/project.rs +0 -356
  145. package/backend/src/models/task.rs +0 -345
  146. package/backend/src/models/task_attempt.rs +0 -1214
  147. package/backend/src/models/task_template.rs +0 -146
  148. package/backend/src/openapi.rs +0 -93
  149. package/backend/src/routes/auth.rs +0 -297
  150. package/backend/src/routes/config.rs +0 -385
  151. package/backend/src/routes/filesystem.rs +0 -228
  152. package/backend/src/routes/health.rs +0 -16
  153. package/backend/src/routes/mod.rs +0 -9
  154. package/backend/src/routes/projects.rs +0 -562
  155. package/backend/src/routes/stream.rs +0 -244
  156. package/backend/src/routes/task_attempts.rs +0 -1172
  157. package/backend/src/routes/task_templates.rs +0 -229
  158. package/backend/src/routes/tasks.rs +0 -353
  159. package/backend/src/services/analytics.rs +0 -216
  160. package/backend/src/services/git_service.rs +0 -1321
  161. package/backend/src/services/github_service.rs +0 -307
  162. package/backend/src/services/mod.rs +0 -13
  163. package/backend/src/services/notification_service.rs +0 -263
  164. package/backend/src/services/pr_monitor.rs +0 -214
  165. package/backend/src/services/process_service.rs +0 -940
  166. package/backend/src/utils/path.rs +0 -96
  167. package/backend/src/utils/shell.rs +0 -19
  168. package/backend/src/utils/text.rs +0 -24
  169. package/backend/src/utils/worktree_manager.rs +0 -578
  170. package/backend/src/utils.rs +0 -125
  171. package/backend/test.db +0 -0
  172. package/build-npm-package.sh +0 -61
  173. package/dev_assets_seed/config.json +0 -19
  174. package/frontend/.eslintrc.json +0 -25
  175. package/frontend/.prettierrc.json +0 -8
  176. package/frontend/components.json +0 -17
  177. package/frontend/index.html +0 -19
  178. package/frontend/package-lock.json +0 -7321
  179. package/frontend/package.json +0 -61
  180. package/frontend/postcss.config.js +0 -6
  181. package/frontend/public/android-chrome-192x192.png +0 -0
  182. package/frontend/public/android-chrome-512x512.png +0 -0
  183. package/frontend/public/apple-touch-icon.png +0 -0
  184. package/frontend/public/automagik-forge-logo-dark.svg +0 -3
  185. package/frontend/public/automagik-forge-logo.svg +0 -3
  186. package/frontend/public/automagik-forge-screenshot-overview.png +0 -0
  187. package/frontend/public/favicon-16x16.png +0 -0
  188. package/frontend/public/favicon-32x32.png +0 -0
  189. package/frontend/public/favicon.ico +0 -0
  190. package/frontend/public/site.webmanifest +0 -1
  191. package/frontend/public/viba-kanban-favicon.png +0 -0
  192. package/frontend/src/App.tsx +0 -157
  193. package/frontend/src/components/DisclaimerDialog.tsx +0 -106
  194. package/frontend/src/components/GitHubLoginDialog.tsx +0 -314
  195. package/frontend/src/components/OnboardingDialog.tsx +0 -185
  196. package/frontend/src/components/PrivacyOptInDialog.tsx +0 -130
  197. package/frontend/src/components/ProvidePatDialog.tsx +0 -98
  198. package/frontend/src/components/TaskTemplateManager.tsx +0 -336
  199. package/frontend/src/components/config-provider.tsx +0 -119
  200. package/frontend/src/components/context/TaskDetailsContextProvider.tsx +0 -470
  201. package/frontend/src/components/context/taskDetailsContext.ts +0 -125
  202. package/frontend/src/components/keyboard-shortcuts-demo.tsx +0 -35
  203. package/frontend/src/components/layout/navbar.tsx +0 -86
  204. package/frontend/src/components/logo.tsx +0 -44
  205. package/frontend/src/components/projects/ProjectCard.tsx +0 -155
  206. package/frontend/src/components/projects/project-detail.tsx +0 -251
  207. package/frontend/src/components/projects/project-form-fields.tsx +0 -238
  208. package/frontend/src/components/projects/project-form.tsx +0 -301
  209. package/frontend/src/components/projects/project-list.tsx +0 -200
  210. package/frontend/src/components/projects/projects-page.tsx +0 -20
  211. package/frontend/src/components/tasks/BranchSelector.tsx +0 -169
  212. package/frontend/src/components/tasks/DeleteFileConfirmationDialog.tsx +0 -94
  213. package/frontend/src/components/tasks/EditorSelectionDialog.tsx +0 -119
  214. package/frontend/src/components/tasks/TaskCard.tsx +0 -154
  215. package/frontend/src/components/tasks/TaskDetails/CollapsibleToolbar.tsx +0 -33
  216. package/frontend/src/components/tasks/TaskDetails/DiffCard.tsx +0 -109
  217. package/frontend/src/components/tasks/TaskDetails/DiffChunkSection.tsx +0 -135
  218. package/frontend/src/components/tasks/TaskDetails/DiffFile.tsx +0 -296
  219. package/frontend/src/components/tasks/TaskDetails/DiffTab.tsx +0 -32
  220. package/frontend/src/components/tasks/TaskDetails/DisplayConversationEntry.tsx +0 -392
  221. package/frontend/src/components/tasks/TaskDetails/LogsTab/Conversation.tsx +0 -256
  222. package/frontend/src/components/tasks/TaskDetails/LogsTab/ConversationEntry.tsx +0 -56
  223. package/frontend/src/components/tasks/TaskDetails/LogsTab/NormalizedConversationViewer.tsx +0 -92
  224. package/frontend/src/components/tasks/TaskDetails/LogsTab/Prompt.tsx +0 -22
  225. package/frontend/src/components/tasks/TaskDetails/LogsTab/SetupScriptRunning.tsx +0 -49
  226. package/frontend/src/components/tasks/TaskDetails/LogsTab.tsx +0 -186
  227. package/frontend/src/components/tasks/TaskDetails/ProcessesTab.tsx +0 -288
  228. package/frontend/src/components/tasks/TaskDetails/RelatedTasksTab.tsx +0 -216
  229. package/frontend/src/components/tasks/TaskDetails/TabNavigation.tsx +0 -93
  230. package/frontend/src/components/tasks/TaskDetailsHeader.tsx +0 -169
  231. package/frontend/src/components/tasks/TaskDetailsPanel.tsx +0 -126
  232. package/frontend/src/components/tasks/TaskDetailsToolbar.tsx +0 -302
  233. package/frontend/src/components/tasks/TaskFollowUpSection.tsx +0 -130
  234. package/frontend/src/components/tasks/TaskFormDialog.tsx +0 -400
  235. package/frontend/src/components/tasks/TaskKanbanBoard.tsx +0 -180
  236. package/frontend/src/components/tasks/Toolbar/CreateAttempt.tsx +0 -259
  237. package/frontend/src/components/tasks/Toolbar/CreatePRDialog.tsx +0 -243
  238. package/frontend/src/components/tasks/Toolbar/CurrentAttempt.tsx +0 -899
  239. package/frontend/src/components/tasks/index.ts +0 -2
  240. package/frontend/src/components/theme-provider.tsx +0 -82
  241. package/frontend/src/components/theme-toggle.tsx +0 -36
  242. package/frontend/src/components/ui/alert.tsx +0 -59
  243. package/frontend/src/components/ui/auto-expanding-textarea.tsx +0 -70
  244. package/frontend/src/components/ui/badge.tsx +0 -36
  245. package/frontend/src/components/ui/button.tsx +0 -56
  246. package/frontend/src/components/ui/card.tsx +0 -86
  247. package/frontend/src/components/ui/checkbox.tsx +0 -44
  248. package/frontend/src/components/ui/chip.tsx +0 -25
  249. package/frontend/src/components/ui/dialog.tsx +0 -124
  250. package/frontend/src/components/ui/dropdown-menu.tsx +0 -198
  251. package/frontend/src/components/ui/file-search-textarea.tsx +0 -292
  252. package/frontend/src/components/ui/folder-picker.tsx +0 -279
  253. package/frontend/src/components/ui/input.tsx +0 -25
  254. package/frontend/src/components/ui/label.tsx +0 -24
  255. package/frontend/src/components/ui/loader.tsx +0 -26
  256. package/frontend/src/components/ui/markdown-renderer.tsx +0 -75
  257. package/frontend/src/components/ui/select.tsx +0 -160
  258. package/frontend/src/components/ui/separator.tsx +0 -31
  259. package/frontend/src/components/ui/shadcn-io/kanban/index.tsx +0 -185
  260. package/frontend/src/components/ui/table.tsx +0 -117
  261. package/frontend/src/components/ui/tabs.tsx +0 -53
  262. package/frontend/src/components/ui/textarea.tsx +0 -22
  263. package/frontend/src/components/ui/tooltip.tsx +0 -28
  264. package/frontend/src/hooks/useNormalizedConversation.ts +0 -440
  265. package/frontend/src/index.css +0 -225
  266. package/frontend/src/lib/api.ts +0 -630
  267. package/frontend/src/lib/keyboard-shortcuts.ts +0 -266
  268. package/frontend/src/lib/responsive-config.ts +0 -70
  269. package/frontend/src/lib/types.ts +0 -39
  270. package/frontend/src/lib/utils.ts +0 -10
  271. package/frontend/src/main.tsx +0 -50
  272. package/frontend/src/pages/McpServers.tsx +0 -418
  273. package/frontend/src/pages/Settings.tsx +0 -610
  274. package/frontend/src/pages/project-tasks.tsx +0 -575
  275. package/frontend/src/pages/projects.tsx +0 -18
  276. package/frontend/src/vite-env.d.ts +0 -1
  277. package/frontend/tailwind.config.js +0 -125
  278. package/frontend/tsconfig.json +0 -26
  279. package/frontend/tsconfig.node.json +0 -10
  280. package/frontend/vite.config.ts +0 -33
  281. package/npx-cli/README.md +0 -159
  282. package/npx-cli/automagik-forge-0.1.0.tgz +0 -0
  283. package/npx-cli/automagik-forge-0.1.10.tgz +0 -0
  284. package/npx-cli/package.json +0 -17
  285. package/npx-cli/vibe-kanban-0.0.55.tgz +0 -0
  286. package/pnpm-workspace.yaml +0 -2
  287. package/rust-toolchain.toml +0 -11
  288. package/rustfmt.toml +0 -3
  289. package/scripts/load-env.js +0 -43
  290. package/scripts/mcp_test.js +0 -374
  291. package/scripts/prepare-db.js +0 -45
  292. package/scripts/setup-dev-environment.js +0 -274
  293. package/scripts/start-mcp-sse.js +0 -70
  294. package/scripts/test-debug.js +0 -32
  295. package/scripts/test-mcp-sse.js +0 -138
  296. package/scripts/test-simple.js +0 -44
  297. package/scripts/test-wish-final.js +0 -179
  298. package/scripts/test-wish-system.js +0 -221
  299. package/shared/types.ts +0 -182
  300. package/test-npm-package.sh +0 -42
  301. /package/{npx-cli/bin → bin}/cli.js +0 -0
@@ -1,470 +0,0 @@
1
- import {
2
- Dispatch,
3
- FC,
4
- ReactNode,
5
- SetStateAction,
6
- useCallback,
7
- useEffect,
8
- useMemo,
9
- useRef,
10
- useState,
11
- } from 'react';
12
- import type {
13
- EditorType,
14
- ExecutionProcess,
15
- ExecutionProcessSummary,
16
- Task,
17
- TaskAttempt,
18
- TaskAttemptState,
19
- TaskWithAttemptStatus,
20
- WorktreeDiff,
21
- } from 'shared/types.ts';
22
- import { attemptsApi, executionProcessesApi, tasksApi } from '@/lib/api.ts';
23
- import {
24
- TaskAttemptDataContext,
25
- TaskAttemptLoadingContext,
26
- TaskAttemptStoppingContext,
27
- TaskBackgroundRefreshContext,
28
- TaskDeletingFilesContext,
29
- TaskDetailsContext,
30
- TaskDiffContext,
31
- TaskExecutionStateContext,
32
- TaskRelatedTasksContext,
33
- TaskSelectedAttemptContext,
34
- } from './taskDetailsContext.ts';
35
- import type { AttemptData } from '@/lib/types.ts';
36
-
37
- const TaskDetailsProvider: FC<{
38
- task: TaskWithAttemptStatus;
39
- projectId: string;
40
- children: ReactNode;
41
- setShowEditorDialog: Dispatch<SetStateAction<boolean>>;
42
- projectHasDevScript?: boolean;
43
- }> = ({
44
- task,
45
- projectId,
46
- children,
47
- setShowEditorDialog,
48
- projectHasDevScript,
49
- }) => {
50
- const [loading, setLoading] = useState(false);
51
- const [isStopping, setIsStopping] = useState(false);
52
- const [selectedAttempt, setSelectedAttempt] = useState<TaskAttempt | null>(
53
- null
54
- );
55
- const [deletingFiles, setDeletingFiles] = useState<Set<string>>(new Set());
56
- const [fileToDelete, setFileToDelete] = useState<string | null>(null);
57
-
58
- // Diff-related state
59
- const [diff, setDiff] = useState<WorktreeDiff | null>(null);
60
- const [diffLoading, setDiffLoading] = useState(true);
61
- const [diffError, setDiffError] = useState<string | null>(null);
62
- const [isBackgroundRefreshing, setIsBackgroundRefreshing] = useState(false);
63
-
64
- // Related tasks state
65
- const [relatedTasks, setRelatedTasks] = useState<Task[] | null>(null);
66
- const [relatedTasksLoading, setRelatedTasksLoading] = useState(true);
67
- const [relatedTasksError, setRelatedTasksError] = useState<string | null>(
68
- null
69
- );
70
-
71
- const [executionState, setExecutionState] = useState<TaskAttemptState | null>(
72
- null
73
- );
74
-
75
- const [attemptData, setAttemptData] = useState<AttemptData>({
76
- processes: [],
77
- runningProcessDetails: {},
78
- allLogs: [], // new field for all logs
79
- });
80
-
81
- const relatedTasksLoadingRef = useRef(false);
82
-
83
- const fetchRelatedTasks = useCallback(async () => {
84
- if (!projectId || !task?.id || !selectedAttempt?.id) {
85
- setRelatedTasks(null);
86
- setRelatedTasksLoading(false);
87
- return;
88
- }
89
-
90
- // Prevent multiple concurrent requests
91
- if (relatedTasksLoadingRef.current) {
92
- return;
93
- }
94
-
95
- relatedTasksLoadingRef.current = true;
96
- setRelatedTasksLoading(true);
97
- setRelatedTasksError(null);
98
-
99
- try {
100
- const children = await tasksApi.getChildren(
101
- projectId,
102
- task.id,
103
- selectedAttempt.id
104
- );
105
- setRelatedTasks(children);
106
- } catch (err) {
107
- console.error('Failed to load related tasks:', err);
108
- setRelatedTasksError('Failed to load related tasks');
109
- } finally {
110
- relatedTasksLoadingRef.current = false;
111
- setRelatedTasksLoading(false);
112
- }
113
- }, [projectId, task?.id, selectedAttempt?.id]);
114
-
115
- const fetchDiff = useCallback(
116
- async (isBackgroundRefresh = false) => {
117
- if (!projectId || !selectedAttempt?.id || !selectedAttempt?.task_id) {
118
- setDiff(null);
119
- setDiffLoading(false);
120
- return;
121
- }
122
-
123
- if (isBackgroundRefresh) {
124
- setIsBackgroundRefreshing(true);
125
- } else {
126
- setDiffLoading(true);
127
- }
128
- setDiffError(null);
129
-
130
- try {
131
- const result = await attemptsApi.getDiff(
132
- projectId,
133
- selectedAttempt.task_id,
134
- selectedAttempt.id
135
- );
136
-
137
- if (result !== undefined) {
138
- setDiff(result);
139
- }
140
- } catch (err) {
141
- console.error('Failed to load diff:', err);
142
- setDiffError('Failed to load diff');
143
- } finally {
144
- if (isBackgroundRefresh) {
145
- setIsBackgroundRefreshing(false);
146
- } else {
147
- setDiffLoading(false);
148
- }
149
- }
150
- },
151
- [projectId, selectedAttempt?.id, selectedAttempt?.task_id]
152
- );
153
-
154
- useEffect(() => {
155
- if (selectedAttempt && task) {
156
- fetchRelatedTasks();
157
- } else if (task && !selectedAttempt) {
158
- // If we have a task but no selectedAttempt, wait a bit then clear loading state
159
- // This happens when a task has no attempts yet
160
- const timeout = setTimeout(() => {
161
- setRelatedTasks(null);
162
- setRelatedTasksLoading(false);
163
- }, 1000); // Wait 1 second for attempts to load
164
-
165
- return () => clearTimeout(timeout);
166
- }
167
- }, [selectedAttempt, task, fetchRelatedTasks]);
168
-
169
- const fetchExecutionState = useCallback(
170
- async (attemptId: string, taskId: string) => {
171
- if (!task) return;
172
-
173
- try {
174
- const result = await attemptsApi.getState(projectId, taskId, attemptId);
175
-
176
- if (result !== undefined) {
177
- setExecutionState((prev) => {
178
- if (JSON.stringify(prev) === JSON.stringify(result)) return prev;
179
- return result;
180
- });
181
- }
182
- } catch (err) {
183
- console.error('Failed to fetch execution state:', err);
184
- }
185
- },
186
- [task, projectId]
187
- );
188
-
189
- const handleOpenInEditor = useCallback(
190
- async (editorType?: EditorType) => {
191
- if (!task || !selectedAttempt) return;
192
-
193
- try {
194
- const result = await attemptsApi.openEditor(
195
- projectId,
196
- selectedAttempt.task_id,
197
- selectedAttempt.id,
198
- editorType
199
- );
200
-
201
- if (result === undefined && !editorType) {
202
- setShowEditorDialog(true);
203
- }
204
- } catch (err) {
205
- console.error('Failed to open editor:', err);
206
- if (!editorType) {
207
- setShowEditorDialog(true);
208
- }
209
- }
210
- },
211
- [task, projectId, selectedAttempt, setShowEditorDialog]
212
- );
213
-
214
- const fetchAttemptData = useCallback(
215
- async (attemptId: string, taskId: string) => {
216
- if (!task) return;
217
-
218
- try {
219
- const [processesResult, allLogsResult] = await Promise.all([
220
- attemptsApi.getExecutionProcesses(projectId, taskId, attemptId),
221
- attemptsApi.getAllLogs(projectId, taskId, attemptId),
222
- ]);
223
-
224
- if (processesResult !== undefined && allLogsResult !== undefined) {
225
- const runningProcesses = processesResult.filter(
226
- (process) => process.status === 'running'
227
- );
228
-
229
- const runningProcessDetails: Record<string, ExecutionProcess> = {};
230
-
231
- // Fetch details for running processes
232
- for (const process of runningProcesses) {
233
- const result = await executionProcessesApi.getDetails(process.id);
234
-
235
- if (result !== undefined) {
236
- runningProcessDetails[process.id] = result;
237
- }
238
- }
239
-
240
- // Also fetch setup script process details if it exists in the processes
241
- const setupProcess = processesResult.find(
242
- (process) => process.process_type === 'setupscript'
243
- );
244
- if (setupProcess && !runningProcessDetails[setupProcess.id]) {
245
- const result = await executionProcessesApi.getDetails(
246
- setupProcess.id
247
- );
248
-
249
- if (result !== undefined) {
250
- runningProcessDetails[setupProcess.id] = result;
251
- }
252
- }
253
-
254
- setAttemptData((prev: AttemptData) => {
255
- const newData = {
256
- processes: processesResult,
257
- runningProcessDetails,
258
- allLogs: allLogsResult,
259
- };
260
- if (JSON.stringify(prev) === JSON.stringify(newData)) return prev;
261
- return newData;
262
- });
263
- }
264
- } catch (err) {
265
- console.error('Failed to fetch attempt data:', err);
266
- }
267
- },
268
- [task, projectId]
269
- );
270
-
271
- useEffect(() => {
272
- if (selectedAttempt && task) {
273
- fetchAttemptData(selectedAttempt.id, selectedAttempt.task_id);
274
- fetchExecutionState(selectedAttempt.id, selectedAttempt.task_id);
275
- }
276
- }, [selectedAttempt, task, fetchAttemptData, fetchExecutionState]);
277
-
278
- const isAttemptRunning = useMemo(() => {
279
- if (!selectedAttempt || isStopping) {
280
- return false;
281
- }
282
-
283
- return attemptData.processes.some(
284
- (process: ExecutionProcessSummary) =>
285
- (process.process_type === 'codingagent' ||
286
- process.process_type === 'setupscript' ||
287
- process.process_type === 'cleanupscript') &&
288
- process.status === 'running'
289
- );
290
- }, [selectedAttempt, attemptData.processes, isStopping]);
291
-
292
- useEffect(() => {
293
- if (!isAttemptRunning || !task) return;
294
-
295
- const interval = setInterval(() => {
296
- if (selectedAttempt) {
297
- fetchAttemptData(selectedAttempt.id, selectedAttempt.task_id);
298
- fetchExecutionState(selectedAttempt.id, selectedAttempt.task_id);
299
- }
300
- }, 5000);
301
-
302
- return () => clearInterval(interval);
303
- }, [
304
- isAttemptRunning,
305
- task,
306
- selectedAttempt,
307
- fetchAttemptData,
308
- fetchExecutionState,
309
- ]);
310
-
311
- // Refresh diff when coding agent is running and making changes
312
- useEffect(() => {
313
- if (!executionState || !selectedAttempt) return;
314
-
315
- const isCodingAgentRunning =
316
- executionState.execution_state === 'CodingAgentRunning';
317
-
318
- if (isCodingAgentRunning) {
319
- // Immediately refresh diff when coding agent starts running
320
- fetchDiff(true);
321
-
322
- // Then refresh diff every 2 seconds while coding agent is active
323
- const interval = setInterval(() => {
324
- fetchDiff(true);
325
- }, 2000);
326
-
327
- return () => {
328
- clearInterval(interval);
329
- };
330
- }
331
- }, [executionState, selectedAttempt, fetchDiff]);
332
-
333
- // Refresh diff when coding agent completes or changes state
334
- useEffect(() => {
335
- if (!executionState?.execution_state || !selectedAttempt) return;
336
-
337
- fetchDiff();
338
- }, [
339
- executionState?.execution_state,
340
- executionState?.has_changes,
341
- selectedAttempt,
342
- fetchDiff,
343
- ]);
344
-
345
- const value = useMemo(
346
- () => ({
347
- task,
348
- projectId,
349
- handleOpenInEditor,
350
- projectHasDevScript,
351
- }),
352
- [task, projectId, handleOpenInEditor, projectHasDevScript]
353
- );
354
-
355
- const taskAttemptLoadingValue = useMemo(
356
- () => ({ loading, setLoading }),
357
- [loading]
358
- );
359
-
360
- const selectedAttemptValue = useMemo(
361
- () => ({ selectedAttempt, setSelectedAttempt }),
362
- [selectedAttempt]
363
- );
364
-
365
- const attemptStoppingValue = useMemo(
366
- () => ({ isStopping, setIsStopping }),
367
- [isStopping]
368
- );
369
-
370
- const deletingFilesValue = useMemo(
371
- () => ({
372
- deletingFiles,
373
- fileToDelete,
374
- setFileToDelete,
375
- setDeletingFiles,
376
- }),
377
- [deletingFiles, fileToDelete]
378
- );
379
-
380
- const diffValue = useMemo(
381
- () => ({
382
- setDiffError,
383
- fetchDiff,
384
- diff,
385
- diffError,
386
- diffLoading,
387
- setDiff,
388
- setDiffLoading,
389
- }),
390
- [fetchDiff, diff, diffError, diffLoading]
391
- );
392
-
393
- const backgroundRefreshingValue = useMemo(
394
- () => ({
395
- isBackgroundRefreshing,
396
- }),
397
- [isBackgroundRefreshing]
398
- );
399
-
400
- const attemptDataValue = useMemo(
401
- () => ({
402
- attemptData,
403
- setAttemptData,
404
- fetchAttemptData,
405
- isAttemptRunning,
406
- }),
407
- [attemptData, fetchAttemptData, isAttemptRunning]
408
- );
409
-
410
- const executionStateValue = useMemo(
411
- () => ({
412
- executionState,
413
- fetchExecutionState,
414
- }),
415
- [executionState, fetchExecutionState]
416
- );
417
-
418
- const relatedTasksValue = useMemo(
419
- () => ({
420
- relatedTasks,
421
- setRelatedTasks,
422
- relatedTasksLoading,
423
- setRelatedTasksLoading,
424
- relatedTasksError,
425
- setRelatedTasksError,
426
- fetchRelatedTasks,
427
- totalRelatedCount:
428
- (task?.parent_task_attempt ? 1 : 0) + (relatedTasks?.length || 0),
429
- }),
430
- [
431
- relatedTasks,
432
- relatedTasksLoading,
433
- relatedTasksError,
434
- fetchRelatedTasks,
435
- task?.parent_task_attempt,
436
- ]
437
- );
438
-
439
- return (
440
- <TaskDetailsContext.Provider value={value}>
441
- <TaskAttemptLoadingContext.Provider value={taskAttemptLoadingValue}>
442
- <TaskSelectedAttemptContext.Provider value={selectedAttemptValue}>
443
- <TaskAttemptStoppingContext.Provider value={attemptStoppingValue}>
444
- <TaskDeletingFilesContext.Provider value={deletingFilesValue}>
445
- <TaskDiffContext.Provider value={diffValue}>
446
- <TaskAttemptDataContext.Provider value={attemptDataValue}>
447
- <TaskExecutionStateContext.Provider
448
- value={executionStateValue}
449
- >
450
- <TaskBackgroundRefreshContext.Provider
451
- value={backgroundRefreshingValue}
452
- >
453
- <TaskRelatedTasksContext.Provider
454
- value={relatedTasksValue}
455
- >
456
- {children}
457
- </TaskRelatedTasksContext.Provider>
458
- </TaskBackgroundRefreshContext.Provider>
459
- </TaskExecutionStateContext.Provider>
460
- </TaskAttemptDataContext.Provider>
461
- </TaskDiffContext.Provider>
462
- </TaskDeletingFilesContext.Provider>
463
- </TaskAttemptStoppingContext.Provider>
464
- </TaskSelectedAttemptContext.Provider>
465
- </TaskAttemptLoadingContext.Provider>
466
- </TaskDetailsContext.Provider>
467
- );
468
- };
469
-
470
- export default TaskDetailsProvider;
@@ -1,125 +0,0 @@
1
- import { createContext, Dispatch, SetStateAction } from 'react';
2
- import type {
3
- EditorType,
4
- Task,
5
- TaskAttempt,
6
- TaskAttemptState,
7
- TaskWithAttemptStatus,
8
- WorktreeDiff,
9
- } from 'shared/types.ts';
10
- import { AttemptData } from '@/lib/types.ts';
11
-
12
- export interface TaskDetailsContextValue {
13
- task: TaskWithAttemptStatus;
14
- projectId: string;
15
- handleOpenInEditor: (editorType?: EditorType) => Promise<void>;
16
- projectHasDevScript?: boolean;
17
- }
18
-
19
- export const TaskDetailsContext = createContext<TaskDetailsContextValue>(
20
- {} as TaskDetailsContextValue
21
- );
22
-
23
- interface TaskAttemptLoadingContextValue {
24
- loading: boolean;
25
- setLoading: Dispatch<SetStateAction<boolean>>;
26
- }
27
-
28
- export const TaskAttemptLoadingContext =
29
- createContext<TaskAttemptLoadingContextValue>(
30
- {} as TaskAttemptLoadingContextValue
31
- );
32
-
33
- interface TaskAttemptDataContextValue {
34
- attemptData: AttemptData;
35
- setAttemptData: Dispatch<SetStateAction<AttemptData>>;
36
- fetchAttemptData: (attemptId: string, taskId: string) => Promise<void> | void;
37
- isAttemptRunning: boolean;
38
- }
39
-
40
- export const TaskAttemptDataContext =
41
- createContext<TaskAttemptDataContextValue>({} as TaskAttemptDataContextValue);
42
-
43
- interface TaskSelectedAttemptContextValue {
44
- selectedAttempt: TaskAttempt | null;
45
- setSelectedAttempt: Dispatch<SetStateAction<TaskAttempt | null>>;
46
- }
47
-
48
- export const TaskSelectedAttemptContext =
49
- createContext<TaskSelectedAttemptContextValue>(
50
- {} as TaskSelectedAttemptContextValue
51
- );
52
-
53
- interface TaskAttemptStoppingContextValue {
54
- isStopping: boolean;
55
- setIsStopping: Dispatch<SetStateAction<boolean>>;
56
- }
57
-
58
- export const TaskAttemptStoppingContext =
59
- createContext<TaskAttemptStoppingContextValue>(
60
- {} as TaskAttemptStoppingContextValue
61
- );
62
-
63
- interface TaskDeletingFilesContextValue {
64
- deletingFiles: Set<string>;
65
- setDeletingFiles: Dispatch<SetStateAction<Set<string>>>;
66
- fileToDelete: string | null;
67
- setFileToDelete: Dispatch<SetStateAction<string | null>>;
68
- }
69
-
70
- export const TaskDeletingFilesContext =
71
- createContext<TaskDeletingFilesContextValue>(
72
- {} as TaskDeletingFilesContextValue
73
- );
74
-
75
- interface TaskDiffContextValue {
76
- setDiffError: Dispatch<SetStateAction<string | null>>;
77
- fetchDiff: (isBackgroundRefresh?: boolean) => Promise<void>;
78
- diff: WorktreeDiff | null;
79
- diffError: string | null;
80
- diffLoading: boolean;
81
- setDiff: Dispatch<SetStateAction<WorktreeDiff | null>>;
82
- setDiffLoading: Dispatch<SetStateAction<boolean>>;
83
- }
84
-
85
- export const TaskDiffContext = createContext<TaskDiffContextValue>(
86
- {} as TaskDiffContextValue
87
- );
88
-
89
- interface TaskBackgroundRefreshContextValue {
90
- isBackgroundRefreshing: boolean;
91
- }
92
-
93
- export const TaskBackgroundRefreshContext =
94
- createContext<TaskBackgroundRefreshContextValue>(
95
- {} as TaskBackgroundRefreshContextValue
96
- );
97
-
98
- interface TaskExecutionStateContextValue {
99
- executionState: TaskAttemptState | null;
100
- fetchExecutionState: (
101
- attemptId: string,
102
- taskId: string
103
- ) => Promise<void> | void;
104
- }
105
-
106
- export const TaskExecutionStateContext =
107
- createContext<TaskExecutionStateContextValue>(
108
- {} as TaskExecutionStateContextValue
109
- );
110
-
111
- interface TaskRelatedTasksContextValue {
112
- relatedTasks: Task[] | null;
113
- setRelatedTasks: Dispatch<SetStateAction<Task[] | null>>;
114
- relatedTasksLoading: boolean;
115
- setRelatedTasksLoading: Dispatch<SetStateAction<boolean>>;
116
- relatedTasksError: string | null;
117
- setRelatedTasksError: Dispatch<SetStateAction<string | null>>;
118
- fetchRelatedTasks: () => Promise<void>;
119
- totalRelatedCount: number;
120
- }
121
-
122
- export const TaskRelatedTasksContext =
123
- createContext<TaskRelatedTasksContextValue>(
124
- {} as TaskRelatedTasksContextValue
125
- );
@@ -1,35 +0,0 @@
1
- import { useKeyboardShortcuts } from '@/lib/keyboard-shortcuts';
2
- import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
3
-
4
- export function KeyboardShortcutsDemo() {
5
- const shortcuts = useKeyboardShortcuts({
6
- navigate: undefined,
7
- currentPath: '/demo',
8
- hasOpenDialog: false,
9
- closeDialog: () => {},
10
- onC: () => {},
11
- });
12
-
13
- return (
14
- <Card className="w-full max-w-md">
15
- <CardHeader>
16
- <CardTitle>Keyboard Shortcuts</CardTitle>
17
- </CardHeader>
18
- <CardContent>
19
- <div className="space-y-2">
20
- {Object.values(shortcuts).map((shortcut) => (
21
- <div
22
- key={shortcut.key}
23
- className="flex justify-between items-center"
24
- >
25
- <span className="text-sm">{shortcut.description}</span>
26
- <kbd className="px-2 py-1 text-xs bg-muted rounded border">
27
- {shortcut.key === 'KeyC' ? 'C' : shortcut.key}
28
- </kbd>
29
- </div>
30
- ))}
31
- </div>
32
- </CardContent>
33
- </Card>
34
- );
35
- }
@@ -1,86 +0,0 @@
1
- import { Link, useLocation } from 'react-router-dom';
2
- import { Button } from '@/components/ui/button';
3
- import {
4
- FolderOpen,
5
- Settings,
6
- BookOpen,
7
- Server,
8
- MessageCircleQuestion,
9
- } from 'lucide-react';
10
- import { Logo } from '@/components/logo';
11
-
12
- export function Navbar() {
13
- const location = useLocation();
14
-
15
- return (
16
- <div className="border-b">
17
- <div className="w-full px-4 sm:px-6 lg:px-8">
18
- <div className="flex items-center justify-between h-16">
19
- <div className="flex items-center space-x-6">
20
- <Logo />
21
- <div className="flex items-center space-x-1">
22
- <Button
23
- asChild
24
- variant={
25
- location.pathname === '/projects' ? 'default' : 'ghost'
26
- }
27
- size="sm"
28
- >
29
- <Link to="/projects">
30
- <FolderOpen className="mr-2 h-4 w-4" />
31
- Projects
32
- </Link>
33
- </Button>
34
- <Button
35
- asChild
36
- variant={
37
- location.pathname === '/mcp-servers' ? 'default' : 'ghost'
38
- }
39
- size="sm"
40
- >
41
- <Link to="/mcp-servers">
42
- <Server className="mr-2 h-4 w-4" />
43
- MCP Servers
44
- </Link>
45
- </Button>
46
- <Button
47
- asChild
48
- variant={
49
- location.pathname === '/settings' ? 'default' : 'ghost'
50
- }
51
- size="sm"
52
- >
53
- <Link to="/settings">
54
- <Settings className="mr-2 h-4 w-4" />
55
- Settings
56
- </Link>
57
- </Button>
58
- </div>
59
- </div>
60
- <div className="flex items-center space-x-1">
61
- <Button asChild variant="ghost" size="sm">
62
- <a
63
- href="/docs"
64
- target="_blank"
65
- rel="noopener noreferrer"
66
- >
67
- <BookOpen className="mr-2 h-4 w-4" />
68
- API Docs
69
- </a>
70
- </Button>
71
- <Button asChild variant="ghost" size="sm">
72
- <a
73
- href="https://github.com/namastexlabs/automagik-forge/issues"
74
- target="_blank"
75
- rel="noopener noreferrer"
76
- >
77
- <MessageCircleQuestion className="mr-2 h-4 w-4" />
78
- Support
79
- </a>
80
- </Button>
81
- </div>
82
- </div>
83
- </div>
84
- </div>
85
- );
86
- }