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.
- package/README.md +143 -447
- package/dist/linux-x64/automagik-forge-mcp.zip +0 -0
- package/{npx-cli/automagik-forge-0.0.55.tgz → dist/linux-x64/automagik-forge.zip} +0 -0
- package/package.json +13 -23
- package/.cargo/config.toml +0 -13
- package/.claude/commands/commit.md +0 -376
- package/.claude/commands/prompt.md +0 -871
- package/.env.example +0 -20
- package/.github/actions/setup-node/action.yml +0 -29
- package/.github/images/automagik-logo.png +0 -0
- package/.github/workflows/pre-release.yml +0 -470
- package/.github/workflows/publish.yml +0 -145
- package/.github/workflows/test.yml +0 -63
- package/.mcp.json +0 -57
- package/AGENT.md +0 -40
- package/CLAUDE.md +0 -40
- package/CODE-OF-CONDUCT.md +0 -89
- package/Cargo.toml +0 -19
- package/Dockerfile +0 -43
- package/LICENSE +0 -201
- package/Makefile +0 -97
- package/backend/.sqlx/query-01b7e2bac1261d8be3d03c03df3e5220590da6c31c77f161074fc62752d63881.json +0 -12
- package/backend/.sqlx/query-03f2b02ba6dc5ea2b3cf6b1004caea0ad6bcc10ebd63f441d321a389f026e263.json +0 -12
- package/backend/.sqlx/query-0923b77d137a29fc54d399a873ff15fc4af894490bc65a4d344a7575cb0d8643.json +0 -12
- package/backend/.sqlx/query-0f808bcdb63c5f180836e448dd64c435c51758b2fc54a52ce9e67495b1ab200e.json +0 -68
- package/backend/.sqlx/query-1268afe9ca849daa6722e3df7ca8e9e61f0d37052e782bb5452ab8e1018d9b63.json +0 -12
- package/backend/.sqlx/query-1b082630a9622f8667ee7a9aba2c2d3176019a68c6bb83d33008594821415a57.json +0 -12
- package/backend/.sqlx/query-1c7b06ba1e112abf6b945a2ff08a0b40ec23f3738c2e7399f067b558cf8d490e.json +0 -12
- package/backend/.sqlx/query-1f619f01f46859a64ded531dd0ef61abacfe62e758abe7030a6aa745140b95ca.json +0 -104
- package/backend/.sqlx/query-1fca1ce14b4b20205364cd1f1f45ebe1d2e30cd745e59e189d56487b5639dfbb.json +0 -12
- package/backend/.sqlx/query-212828320e8d871ab9d83705a040b23bcf0393dc7252177fc539a74657f578ef.json +0 -32
- package/backend/.sqlx/query-290ce5c152be8d36e58ff42570f9157beb07ab9e77a03ec6fc30b4f56f9b8f6b.json +0 -56
- package/backend/.sqlx/query-2b471d2c2e8ffbe0cd42d2a91b814c0d79f9d09200f147e3cea33ba4ce673c8a.json +0 -68
- package/backend/.sqlx/query-354a48c705bb9bb2048c1b7f10fcb714e23f9db82b7a4ea6932486197b2ede6a.json +0 -92
- package/backend/.sqlx/query-36c9e3dd10648e94b949db5c91a774ecb1e10a899ef95da74066eccedca4d8b2.json +0 -12
- package/backend/.sqlx/query-36e4ba7bbd81b402d5a20b6005755eafbb174c8dda442081823406ac32809a94.json +0 -56
- package/backend/.sqlx/query-3a5b3c98a55ca183ab20c74708e3d7e579dda37972c059e7515c4ceee4bd8dd3.json +0 -62
- package/backend/.sqlx/query-3d0a1cabf2a52e9d90cdfd29c509ca89aeb448d0c1d2446c65cd43db40735e86.json +0 -62
- package/backend/.sqlx/query-3d6bd16fbce59efe30b7f67ea342e0e4ea6d1432389c02468ad79f1f742d4031.json +0 -56
- package/backend/.sqlx/query-4049ca413b285a05aca6b25385e9c8185575f01e9069e4e8581aa45d713f612f.json +0 -32
- package/backend/.sqlx/query-412bacd3477d86369082e90f52240407abce436cb81292d42b2dbe1e5c18eea1.json +0 -104
- package/backend/.sqlx/query-417a8b1ff4e51de82aea0159a3b97932224dc325b23476cb84153d690227fd8b.json +0 -62
- package/backend/.sqlx/query-461cc1b0bb6fd909afc9dd2246e8526b3771cfbb0b22ae4b5d17b51af587b9e2.json +0 -56
- package/backend/.sqlx/query-58408c7a8cdeeda0bef359f1f9bd91299a339dc2b191462fc58c9736a56d5227.json +0 -92
- package/backend/.sqlx/query-5a886026d75d515c01f347cc203c8d99dd04c61dc468e2e4c5aa548436d13834.json +0 -62
- package/backend/.sqlx/query-5b902137b11022d2e1a5c4f6a9c83fec1a856c6a710aff831abd2382ede76b43.json +0 -12
- package/backend/.sqlx/query-5ed1238e52e59bb5f76c0f153fd99a14093f7ce2585bf9843585608f17ec575b.json +0 -104
- package/backend/.sqlx/query-6e8b860b14decfc2227dc57213f38442943d3fbef5c8418fd6b634c6e0f5e2ea.json +0 -104
- package/backend/.sqlx/query-6ec414276994c4ccb2433eaa5b1b342168557d17ddf5a52dac84cb1b59b9de8f.json +0 -68
- package/backend/.sqlx/query-6ecfa16d0cf825aacf233544b5baf151e9adfdca26c226ad71020d291fd802d5.json +0 -62
- package/backend/.sqlx/query-72509d252c39fce77520aa816cb2acbc1fb35dc2605e7be893610599b2427f2e.json +0 -62
- package/backend/.sqlx/query-75239b2da188f749707d77f3c1544332ca70db3d6d6743b2601dc0d167536437.json +0 -62
- package/backend/.sqlx/query-83d10e29f8478aff33434f9ac67068e013b888b953a2657e2bb72a6f619d04f2.json +0 -50
- package/backend/.sqlx/query-8610803360ea18b9b9d078a6981ea56abfbfe84e6354fc1d5ae4c622e01410ed.json +0 -68
- package/backend/.sqlx/query-86d03eb70eef39c59296416867f2ee66c9f7cd8b7f961fbda2f89fc0a1c442c2.json +0 -12
- package/backend/.sqlx/query-87d0feb5a6b442bad9c60068ea7569599cc6fc91a0e2692ecb42e93b03201b9d.json +0 -68
- package/backend/.sqlx/query-8a67b3b3337248f06a57bdf8a908f7ef23177431eaed82dc08c94c3e5944340e.json +0 -12
- package/backend/.sqlx/query-8f01ebd64bdcde6a090479f14810d73ba23020e76fd70854ac57f2da251702c3.json +0 -12
- package/backend/.sqlx/query-90fd607fcb2dca72239ff25e618e21e174b195991eaa33722cbf5f76da84cfab.json +0 -62
- package/backend/.sqlx/query-92e8bdbcd80c5ff3db7a35cf79492048803ef305cbdef0d0a1fe5dc881ca8c71.json +0 -104
- package/backend/.sqlx/query-93a1605f90e9672dad29b472b6ad85fa9a55ea3ffa5abcb8724b09d61be254ca.json +0 -20
- package/backend/.sqlx/query-9472c8fb477958167f5fae40b85ac44252468c5226b2cdd7770f027332eed6d7.json +0 -104
- package/backend/.sqlx/query-96036c4f9e0f48bdc5a4a4588f0c5f288ac7aaa5425cac40fc33f337e1a351f2.json +0 -56
- package/backend/.sqlx/query-9edb2c01e91fd0f0fe7b56e988c7ae0393150f50be3f419a981e035c0121dfc7.json +0 -104
- package/backend/.sqlx/query-a157cf00616f703bfba21927f1eb1c9eec2a81c02da15f66efdba0b6c375de1b.json +0 -26
- package/backend/.sqlx/query-a31fff84f3b8e532fd1160447d89d700f06ae08821fee00c9a5b60492b05259c.json +0 -62
- package/backend/.sqlx/query-a5ba908419fb3e456bdd2daca41ba06cc3212ffffb8520fc7dbbcc8b60ada314.json +0 -12
- package/backend/.sqlx/query-a6d2961718dbc3b1a925e549f49a159c561bef58c105529275f274b27e2eba5b.json +0 -104
- package/backend/.sqlx/query-a9e93d5b09b29faf66e387e4d7596a792d81e75c4d3726e83c2963e8d7c9b56f.json +0 -104
- package/backend/.sqlx/query-ac5247c8d7fb86e4650c4b0eb9420031614c831b7b085083bac20c1af314c538.json +0 -12
- package/backend/.sqlx/query-afef9467be74c411c4cb119a8b2b1aea53049877dfc30cc60b486134ba4b4c9f.json +0 -68
- package/backend/.sqlx/query-b2b2c6b4d0b1a347b5c4cb63c3a46a265d4db53be9554989a814b069d0af82f2.json +0 -62
- package/backend/.sqlx/query-c50d2ff0b12e5bcc81e371089ee2d007e233e7db93aefba4fef08e7aa68f5ab7.json +0 -20
- package/backend/.sqlx/query-c614e6056b244ca07f1b9d44e7edc9d5819225c6f8d9e077070c6e518a17f50b.json +0 -12
- package/backend/.sqlx/query-c67259be8bf4ee0cfd32167b2aa3b7fe9192809181a8171bf1c2d6df731967ae.json +0 -12
- package/backend/.sqlx/query-d2d0a1b985ebbca6a2b3e882a221a219f3199890fa640afc946ef1a792d6d8de.json +0 -12
- package/backend/.sqlx/query-d30aa5786757f32bf2b9c5fe51a45e506c71c28c5994e430d9b0546adb15ffa2.json +0 -20
- package/backend/.sqlx/query-d3b9ea1de1576af71b312924ce7f4ea8ae5dbe2ac138ea3b4470f2d5cd734846.json +0 -12
- package/backend/.sqlx/query-ed8456646fa69ddd412441955f06ff22bfb790f29466450735e0b8bb1bc4ec94.json +0 -12
- package/backend/Cargo.toml +0 -71
- package/backend/build.rs +0 -32
- package/backend/migrations/20250617183714_init.sql +0 -44
- package/backend/migrations/20250620212427_execution_processes.sql +0 -25
- package/backend/migrations/20250620214100_remove_stdout_stderr_from_task_attempts.sql +0 -28
- package/backend/migrations/20250621120000_relate_activities_to_execution_processes.sql +0 -23
- package/backend/migrations/20250623120000_executor_sessions.sql +0 -17
- package/backend/migrations/20250623130000_add_executor_type_to_execution_processes.sql +0 -4
- package/backend/migrations/20250625000000_add_dev_script_to_projects.sql +0 -4
- package/backend/migrations/20250701000000_add_branch_to_task_attempts.sql +0 -2
- package/backend/migrations/20250701000001_add_pr_tracking_to_task_attempts.sql +0 -5
- package/backend/migrations/20250701120000_add_assistant_message_to_executor_sessions.sql +0 -2
- package/backend/migrations/20250708000000_add_base_branch_to_task_attempts.sql +0 -2
- package/backend/migrations/20250709000000_add_worktree_deleted_flag.sql +0 -2
- package/backend/migrations/20250710000000_add_setup_completion.sql +0 -3
- package/backend/migrations/20250715154859_add_task_templates.sql +0 -25
- package/backend/migrations/20250716143725_add_default_templates.sql +0 -174
- package/backend/migrations/20250716161432_update_executor_names_to_kebab_case.sql +0 -20
- package/backend/migrations/20250716170000_add_parent_task_to_tasks.sql +0 -7
- package/backend/migrations/20250717000000_drop_task_attempt_activities.sql +0 -9
- package/backend/migrations/20250719000000_add_cleanup_script_to_projects.sql +0 -2
- package/backend/migrations/20250720000000_add_cleanupscript_to_process_type_constraint.sql +0 -25
- package/backend/migrations/20250723000000_add_wish_to_tasks.sql +0 -7
- package/backend/migrations/20250724000000_remove_unique_wish_constraint.sql +0 -5
- package/backend/scripts/toast-notification.ps1 +0 -23
- package/backend/sounds/abstract-sound1.wav +0 -0
- package/backend/sounds/abstract-sound2.wav +0 -0
- package/backend/sounds/abstract-sound3.wav +0 -0
- package/backend/sounds/abstract-sound4.wav +0 -0
- package/backend/sounds/cow-mooing.wav +0 -0
- package/backend/sounds/phone-vibration.wav +0 -0
- package/backend/sounds/rooster.wav +0 -0
- package/backend/src/app_state.rs +0 -218
- package/backend/src/bin/generate_types.rs +0 -189
- package/backend/src/bin/mcp_task_server.rs +0 -191
- package/backend/src/execution_monitor.rs +0 -1193
- package/backend/src/executor.rs +0 -1053
- package/backend/src/executors/amp.rs +0 -697
- package/backend/src/executors/ccr.rs +0 -91
- package/backend/src/executors/charm_opencode.rs +0 -113
- package/backend/src/executors/claude.rs +0 -887
- package/backend/src/executors/cleanup_script.rs +0 -124
- package/backend/src/executors/dev_server.rs +0 -53
- package/backend/src/executors/echo.rs +0 -79
- package/backend/src/executors/gemini/config.rs +0 -67
- package/backend/src/executors/gemini/streaming.rs +0 -363
- package/backend/src/executors/gemini.rs +0 -765
- package/backend/src/executors/mod.rs +0 -23
- package/backend/src/executors/opencode_ai.rs +0 -113
- package/backend/src/executors/setup_script.rs +0 -130
- package/backend/src/executors/sst_opencode/filter.rs +0 -184
- package/backend/src/executors/sst_opencode/tools.rs +0 -139
- package/backend/src/executors/sst_opencode.rs +0 -756
- package/backend/src/lib.rs +0 -45
- package/backend/src/main.rs +0 -324
- package/backend/src/mcp/mod.rs +0 -1
- package/backend/src/mcp/task_server.rs +0 -850
- package/backend/src/middleware/mod.rs +0 -3
- package/backend/src/middleware/model_loaders.rs +0 -242
- package/backend/src/models/api_response.rs +0 -36
- package/backend/src/models/config.rs +0 -375
- package/backend/src/models/execution_process.rs +0 -430
- package/backend/src/models/executor_session.rs +0 -225
- package/backend/src/models/mod.rs +0 -12
- package/backend/src/models/project.rs +0 -356
- package/backend/src/models/task.rs +0 -345
- package/backend/src/models/task_attempt.rs +0 -1214
- package/backend/src/models/task_template.rs +0 -146
- package/backend/src/openapi.rs +0 -93
- package/backend/src/routes/auth.rs +0 -297
- package/backend/src/routes/config.rs +0 -385
- package/backend/src/routes/filesystem.rs +0 -228
- package/backend/src/routes/health.rs +0 -16
- package/backend/src/routes/mod.rs +0 -9
- package/backend/src/routes/projects.rs +0 -562
- package/backend/src/routes/stream.rs +0 -244
- package/backend/src/routes/task_attempts.rs +0 -1172
- package/backend/src/routes/task_templates.rs +0 -229
- package/backend/src/routes/tasks.rs +0 -353
- package/backend/src/services/analytics.rs +0 -216
- package/backend/src/services/git_service.rs +0 -1321
- package/backend/src/services/github_service.rs +0 -307
- package/backend/src/services/mod.rs +0 -13
- package/backend/src/services/notification_service.rs +0 -263
- package/backend/src/services/pr_monitor.rs +0 -214
- package/backend/src/services/process_service.rs +0 -940
- package/backend/src/utils/path.rs +0 -96
- package/backend/src/utils/shell.rs +0 -19
- package/backend/src/utils/text.rs +0 -24
- package/backend/src/utils/worktree_manager.rs +0 -578
- package/backend/src/utils.rs +0 -125
- package/backend/test.db +0 -0
- package/build-npm-package.sh +0 -61
- package/dev_assets_seed/config.json +0 -19
- package/frontend/.eslintrc.json +0 -25
- package/frontend/.prettierrc.json +0 -8
- package/frontend/components.json +0 -17
- package/frontend/index.html +0 -19
- package/frontend/package-lock.json +0 -7321
- package/frontend/package.json +0 -61
- package/frontend/postcss.config.js +0 -6
- package/frontend/public/android-chrome-192x192.png +0 -0
- package/frontend/public/android-chrome-512x512.png +0 -0
- package/frontend/public/apple-touch-icon.png +0 -0
- package/frontend/public/automagik-forge-logo-dark.svg +0 -3
- package/frontend/public/automagik-forge-logo.svg +0 -3
- package/frontend/public/automagik-forge-screenshot-overview.png +0 -0
- package/frontend/public/favicon-16x16.png +0 -0
- package/frontend/public/favicon-32x32.png +0 -0
- package/frontend/public/favicon.ico +0 -0
- package/frontend/public/site.webmanifest +0 -1
- package/frontend/public/viba-kanban-favicon.png +0 -0
- package/frontend/src/App.tsx +0 -157
- package/frontend/src/components/DisclaimerDialog.tsx +0 -106
- package/frontend/src/components/GitHubLoginDialog.tsx +0 -314
- package/frontend/src/components/OnboardingDialog.tsx +0 -185
- package/frontend/src/components/PrivacyOptInDialog.tsx +0 -130
- package/frontend/src/components/ProvidePatDialog.tsx +0 -98
- package/frontend/src/components/TaskTemplateManager.tsx +0 -336
- package/frontend/src/components/config-provider.tsx +0 -119
- package/frontend/src/components/context/TaskDetailsContextProvider.tsx +0 -470
- package/frontend/src/components/context/taskDetailsContext.ts +0 -125
- package/frontend/src/components/keyboard-shortcuts-demo.tsx +0 -35
- package/frontend/src/components/layout/navbar.tsx +0 -86
- package/frontend/src/components/logo.tsx +0 -44
- package/frontend/src/components/projects/ProjectCard.tsx +0 -155
- package/frontend/src/components/projects/project-detail.tsx +0 -251
- package/frontend/src/components/projects/project-form-fields.tsx +0 -238
- package/frontend/src/components/projects/project-form.tsx +0 -301
- package/frontend/src/components/projects/project-list.tsx +0 -200
- package/frontend/src/components/projects/projects-page.tsx +0 -20
- package/frontend/src/components/tasks/BranchSelector.tsx +0 -169
- package/frontend/src/components/tasks/DeleteFileConfirmationDialog.tsx +0 -94
- package/frontend/src/components/tasks/EditorSelectionDialog.tsx +0 -119
- package/frontend/src/components/tasks/TaskCard.tsx +0 -154
- package/frontend/src/components/tasks/TaskDetails/CollapsibleToolbar.tsx +0 -33
- package/frontend/src/components/tasks/TaskDetails/DiffCard.tsx +0 -109
- package/frontend/src/components/tasks/TaskDetails/DiffChunkSection.tsx +0 -135
- package/frontend/src/components/tasks/TaskDetails/DiffFile.tsx +0 -296
- package/frontend/src/components/tasks/TaskDetails/DiffTab.tsx +0 -32
- package/frontend/src/components/tasks/TaskDetails/DisplayConversationEntry.tsx +0 -392
- package/frontend/src/components/tasks/TaskDetails/LogsTab/Conversation.tsx +0 -256
- package/frontend/src/components/tasks/TaskDetails/LogsTab/ConversationEntry.tsx +0 -56
- package/frontend/src/components/tasks/TaskDetails/LogsTab/NormalizedConversationViewer.tsx +0 -92
- package/frontend/src/components/tasks/TaskDetails/LogsTab/Prompt.tsx +0 -22
- package/frontend/src/components/tasks/TaskDetails/LogsTab/SetupScriptRunning.tsx +0 -49
- package/frontend/src/components/tasks/TaskDetails/LogsTab.tsx +0 -186
- package/frontend/src/components/tasks/TaskDetails/ProcessesTab.tsx +0 -288
- package/frontend/src/components/tasks/TaskDetails/RelatedTasksTab.tsx +0 -216
- package/frontend/src/components/tasks/TaskDetails/TabNavigation.tsx +0 -93
- package/frontend/src/components/tasks/TaskDetailsHeader.tsx +0 -169
- package/frontend/src/components/tasks/TaskDetailsPanel.tsx +0 -126
- package/frontend/src/components/tasks/TaskDetailsToolbar.tsx +0 -302
- package/frontend/src/components/tasks/TaskFollowUpSection.tsx +0 -130
- package/frontend/src/components/tasks/TaskFormDialog.tsx +0 -400
- package/frontend/src/components/tasks/TaskKanbanBoard.tsx +0 -180
- package/frontend/src/components/tasks/Toolbar/CreateAttempt.tsx +0 -259
- package/frontend/src/components/tasks/Toolbar/CreatePRDialog.tsx +0 -243
- package/frontend/src/components/tasks/Toolbar/CurrentAttempt.tsx +0 -899
- package/frontend/src/components/tasks/index.ts +0 -2
- package/frontend/src/components/theme-provider.tsx +0 -82
- package/frontend/src/components/theme-toggle.tsx +0 -36
- package/frontend/src/components/ui/alert.tsx +0 -59
- package/frontend/src/components/ui/auto-expanding-textarea.tsx +0 -70
- package/frontend/src/components/ui/badge.tsx +0 -36
- package/frontend/src/components/ui/button.tsx +0 -56
- package/frontend/src/components/ui/card.tsx +0 -86
- package/frontend/src/components/ui/checkbox.tsx +0 -44
- package/frontend/src/components/ui/chip.tsx +0 -25
- package/frontend/src/components/ui/dialog.tsx +0 -124
- package/frontend/src/components/ui/dropdown-menu.tsx +0 -198
- package/frontend/src/components/ui/file-search-textarea.tsx +0 -292
- package/frontend/src/components/ui/folder-picker.tsx +0 -279
- package/frontend/src/components/ui/input.tsx +0 -25
- package/frontend/src/components/ui/label.tsx +0 -24
- package/frontend/src/components/ui/loader.tsx +0 -26
- package/frontend/src/components/ui/markdown-renderer.tsx +0 -75
- package/frontend/src/components/ui/select.tsx +0 -160
- package/frontend/src/components/ui/separator.tsx +0 -31
- package/frontend/src/components/ui/shadcn-io/kanban/index.tsx +0 -185
- package/frontend/src/components/ui/table.tsx +0 -117
- package/frontend/src/components/ui/tabs.tsx +0 -53
- package/frontend/src/components/ui/textarea.tsx +0 -22
- package/frontend/src/components/ui/tooltip.tsx +0 -28
- package/frontend/src/hooks/useNormalizedConversation.ts +0 -440
- package/frontend/src/index.css +0 -225
- package/frontend/src/lib/api.ts +0 -630
- package/frontend/src/lib/keyboard-shortcuts.ts +0 -266
- package/frontend/src/lib/responsive-config.ts +0 -70
- package/frontend/src/lib/types.ts +0 -39
- package/frontend/src/lib/utils.ts +0 -10
- package/frontend/src/main.tsx +0 -50
- package/frontend/src/pages/McpServers.tsx +0 -418
- package/frontend/src/pages/Settings.tsx +0 -610
- package/frontend/src/pages/project-tasks.tsx +0 -575
- package/frontend/src/pages/projects.tsx +0 -18
- package/frontend/src/vite-env.d.ts +0 -1
- package/frontend/tailwind.config.js +0 -125
- package/frontend/tsconfig.json +0 -26
- package/frontend/tsconfig.node.json +0 -10
- package/frontend/vite.config.ts +0 -33
- package/npx-cli/README.md +0 -159
- package/npx-cli/automagik-forge-0.1.0.tgz +0 -0
- package/npx-cli/automagik-forge-0.1.10.tgz +0 -0
- package/npx-cli/package.json +0 -17
- package/npx-cli/vibe-kanban-0.0.55.tgz +0 -0
- package/pnpm-workspace.yaml +0 -2
- package/rust-toolchain.toml +0 -11
- package/rustfmt.toml +0 -3
- package/scripts/load-env.js +0 -43
- package/scripts/mcp_test.js +0 -374
- package/scripts/prepare-db.js +0 -45
- package/scripts/setup-dev-environment.js +0 -274
- package/scripts/start-mcp-sse.js +0 -70
- package/scripts/test-debug.js +0 -32
- package/scripts/test-mcp-sse.js +0 -138
- package/scripts/test-simple.js +0 -44
- package/scripts/test-wish-final.js +0 -179
- package/scripts/test-wish-system.js +0 -221
- package/shared/types.ts +0 -182
- package/test-npm-package.sh +0 -42
- /package/{npx-cli/bin → bin}/cli.js +0 -0
@@ -1,146 +0,0 @@
|
|
1
|
-
use chrono::{DateTime, Utc};
|
2
|
-
use serde::{Deserialize, Serialize};
|
3
|
-
use sqlx::{FromRow, SqlitePool};
|
4
|
-
use ts_rs::TS;
|
5
|
-
use utoipa::ToSchema;
|
6
|
-
use uuid::Uuid;
|
7
|
-
|
8
|
-
#[derive(Debug, Clone, FromRow, Serialize, Deserialize, TS, ToSchema)]
|
9
|
-
#[ts(export)]
|
10
|
-
pub struct TaskTemplate {
|
11
|
-
pub id: Uuid,
|
12
|
-
pub project_id: Option<Uuid>, // None for global templates
|
13
|
-
pub title: String,
|
14
|
-
pub description: Option<String>,
|
15
|
-
pub template_name: String,
|
16
|
-
pub created_at: DateTime<Utc>,
|
17
|
-
pub updated_at: DateTime<Utc>,
|
18
|
-
}
|
19
|
-
|
20
|
-
#[derive(Debug, Deserialize, TS, ToSchema)]
|
21
|
-
#[ts(export)]
|
22
|
-
pub struct CreateTaskTemplate {
|
23
|
-
pub project_id: Option<Uuid>,
|
24
|
-
pub title: String,
|
25
|
-
pub description: Option<String>,
|
26
|
-
pub template_name: String,
|
27
|
-
}
|
28
|
-
|
29
|
-
#[derive(Debug, Deserialize, TS, ToSchema)]
|
30
|
-
#[ts(export)]
|
31
|
-
pub struct UpdateTaskTemplate {
|
32
|
-
pub title: Option<String>,
|
33
|
-
pub description: Option<String>,
|
34
|
-
pub template_name: Option<String>,
|
35
|
-
}
|
36
|
-
|
37
|
-
impl TaskTemplate {
|
38
|
-
pub async fn find_all(pool: &SqlitePool) -> Result<Vec<Self>, sqlx::Error> {
|
39
|
-
sqlx::query_as!(
|
40
|
-
TaskTemplate,
|
41
|
-
r#"SELECT id as "id!: Uuid", project_id as "project_id?: Uuid", title, description, template_name, created_at as "created_at!: DateTime<Utc>", updated_at as "updated_at!: DateTime<Utc>"
|
42
|
-
FROM task_templates
|
43
|
-
ORDER BY project_id IS NULL DESC, template_name ASC"#
|
44
|
-
)
|
45
|
-
.fetch_all(pool)
|
46
|
-
.await
|
47
|
-
}
|
48
|
-
|
49
|
-
pub async fn find_by_project_id(
|
50
|
-
pool: &SqlitePool,
|
51
|
-
project_id: Option<Uuid>,
|
52
|
-
) -> Result<Vec<Self>, sqlx::Error> {
|
53
|
-
if let Some(pid) = project_id {
|
54
|
-
// Return only project-specific templates
|
55
|
-
sqlx::query_as::<_, TaskTemplate>(
|
56
|
-
r#"SELECT id, project_id, title, description, template_name, created_at, updated_at
|
57
|
-
FROM task_templates
|
58
|
-
WHERE project_id = ?
|
59
|
-
ORDER BY template_name ASC"#,
|
60
|
-
)
|
61
|
-
.bind(pid)
|
62
|
-
.fetch_all(pool)
|
63
|
-
.await
|
64
|
-
} else {
|
65
|
-
// Return only global templates
|
66
|
-
sqlx::query_as!(
|
67
|
-
TaskTemplate,
|
68
|
-
r#"SELECT id as "id!: Uuid", project_id as "project_id?: Uuid", title, description, template_name, created_at as "created_at!: DateTime<Utc>", updated_at as "updated_at!: DateTime<Utc>"
|
69
|
-
FROM task_templates
|
70
|
-
WHERE project_id IS NULL
|
71
|
-
ORDER BY template_name ASC"#
|
72
|
-
)
|
73
|
-
.fetch_all(pool)
|
74
|
-
.await
|
75
|
-
}
|
76
|
-
}
|
77
|
-
|
78
|
-
pub async fn find_by_id(pool: &SqlitePool, id: Uuid) -> Result<Option<Self>, sqlx::Error> {
|
79
|
-
sqlx::query_as!(
|
80
|
-
TaskTemplate,
|
81
|
-
r#"SELECT id as "id!: Uuid", project_id as "project_id?: Uuid", title, description, template_name, created_at as "created_at!: DateTime<Utc>", updated_at as "updated_at!: DateTime<Utc>"
|
82
|
-
FROM task_templates
|
83
|
-
WHERE id = $1"#,
|
84
|
-
id
|
85
|
-
)
|
86
|
-
.fetch_optional(pool)
|
87
|
-
.await
|
88
|
-
}
|
89
|
-
|
90
|
-
pub async fn create(pool: &SqlitePool, data: &CreateTaskTemplate) -> Result<Self, sqlx::Error> {
|
91
|
-
let id = Uuid::new_v4();
|
92
|
-
sqlx::query_as!(
|
93
|
-
TaskTemplate,
|
94
|
-
r#"INSERT INTO task_templates (id, project_id, title, description, template_name)
|
95
|
-
VALUES ($1, $2, $3, $4, $5)
|
96
|
-
RETURNING id as "id!: Uuid", project_id as "project_id?: Uuid", title, description, template_name, created_at as "created_at!: DateTime<Utc>", updated_at as "updated_at!: DateTime<Utc>""#,
|
97
|
-
id,
|
98
|
-
data.project_id,
|
99
|
-
data.title,
|
100
|
-
data.description,
|
101
|
-
data.template_name
|
102
|
-
)
|
103
|
-
.fetch_one(pool)
|
104
|
-
.await
|
105
|
-
}
|
106
|
-
|
107
|
-
pub async fn update(
|
108
|
-
pool: &SqlitePool,
|
109
|
-
id: Uuid,
|
110
|
-
data: &UpdateTaskTemplate,
|
111
|
-
) -> Result<Self, sqlx::Error> {
|
112
|
-
// Get existing template first
|
113
|
-
let existing = Self::find_by_id(pool, id)
|
114
|
-
.await?
|
115
|
-
.ok_or(sqlx::Error::RowNotFound)?;
|
116
|
-
|
117
|
-
// Use let bindings to create longer-lived values
|
118
|
-
let title = data.title.as_ref().unwrap_or(&existing.title);
|
119
|
-
let description = data.description.as_ref().or(existing.description.as_ref());
|
120
|
-
let template_name = data
|
121
|
-
.template_name
|
122
|
-
.as_ref()
|
123
|
-
.unwrap_or(&existing.template_name);
|
124
|
-
|
125
|
-
sqlx::query_as!(
|
126
|
-
TaskTemplate,
|
127
|
-
r#"UPDATE task_templates
|
128
|
-
SET title = $2, description = $3, template_name = $4, updated_at = datetime('now', 'subsec')
|
129
|
-
WHERE id = $1
|
130
|
-
RETURNING id as "id!: Uuid", project_id as "project_id?: Uuid", title, description, template_name, created_at as "created_at!: DateTime<Utc>", updated_at as "updated_at!: DateTime<Utc>""#,
|
131
|
-
id,
|
132
|
-
title,
|
133
|
-
description,
|
134
|
-
template_name
|
135
|
-
)
|
136
|
-
.fetch_one(pool)
|
137
|
-
.await
|
138
|
-
}
|
139
|
-
|
140
|
-
pub async fn delete(pool: &SqlitePool, id: Uuid) -> Result<u64, sqlx::Error> {
|
141
|
-
let result = sqlx::query!("DELETE FROM task_templates WHERE id = $1", id)
|
142
|
-
.execute(pool)
|
143
|
-
.await?;
|
144
|
-
Ok(result.rows_affected())
|
145
|
-
}
|
146
|
-
}
|
package/backend/src/openapi.rs
DELETED
@@ -1,93 +0,0 @@
|
|
1
|
-
use utoipa::OpenApi;
|
2
|
-
|
3
|
-
#[derive(OpenApi)]
|
4
|
-
#[openapi(
|
5
|
-
info(
|
6
|
-
title = "Automagik Forge API",
|
7
|
-
version = "1.0.0",
|
8
|
-
description = "A task and project management API for Automagik Forge",
|
9
|
-
contact(
|
10
|
-
name = "Automagik Forge Team",
|
11
|
-
url = "https://github.com/your-org/automagik-forge"
|
12
|
-
)
|
13
|
-
),
|
14
|
-
paths(
|
15
|
-
crate::routes::health::health_check,
|
16
|
-
crate::routes::projects::get_projects,
|
17
|
-
crate::routes::projects::get_project,
|
18
|
-
crate::routes::projects::create_project,
|
19
|
-
crate::routes::projects::update_project,
|
20
|
-
crate::routes::projects::delete_project,
|
21
|
-
crate::routes::tasks::get_project_tasks,
|
22
|
-
crate::routes::tasks::get_task,
|
23
|
-
crate::routes::tasks::create_task,
|
24
|
-
crate::routes::tasks::update_task,
|
25
|
-
crate::routes::tasks::delete_task,
|
26
|
-
crate::routes::task_attempts::get_task_attempts,
|
27
|
-
crate::routes::task_attempts::create_task_attempt,
|
28
|
-
crate::routes::task_templates::list_templates,
|
29
|
-
crate::routes::task_templates::list_project_templates,
|
30
|
-
crate::routes::task_templates::list_global_templates,
|
31
|
-
crate::routes::task_templates::get_template,
|
32
|
-
crate::routes::task_templates::create_template,
|
33
|
-
crate::routes::task_templates::update_template,
|
34
|
-
crate::routes::task_templates::delete_template,
|
35
|
-
// Auth routes
|
36
|
-
crate::routes::auth::device_start,
|
37
|
-
crate::routes::auth::device_poll,
|
38
|
-
crate::routes::auth::github_check_token,
|
39
|
-
// Config routes
|
40
|
-
crate::routes::config::get_config,
|
41
|
-
crate::routes::config::update_config,
|
42
|
-
crate::routes::config::get_config_constants,
|
43
|
-
crate::routes::config::get_mcp_servers,
|
44
|
-
crate::routes::config::update_mcp_servers,
|
45
|
-
// Filesystem routes
|
46
|
-
crate::routes::filesystem::list_directory,
|
47
|
-
crate::routes::filesystem::validate_git_path,
|
48
|
-
crate::routes::filesystem::create_git_repo,
|
49
|
-
),
|
50
|
-
components(
|
51
|
-
schemas(
|
52
|
-
crate::models::project::Project,
|
53
|
-
crate::models::project::CreateProject,
|
54
|
-
crate::models::project::UpdateProject,
|
55
|
-
crate::models::project::ProjectWithBranch,
|
56
|
-
crate::models::project::GitBranch,
|
57
|
-
crate::models::task::Task,
|
58
|
-
crate::models::task::TaskStatus,
|
59
|
-
crate::models::task::TaskWithAttemptStatus,
|
60
|
-
crate::models::task::CreateTask,
|
61
|
-
crate::models::task::UpdateTask,
|
62
|
-
crate::models::task_attempt::TaskAttempt,
|
63
|
-
crate::models::task_attempt::TaskAttemptStatus,
|
64
|
-
crate::models::task_attempt::CreateTaskAttempt,
|
65
|
-
crate::models::task_template::TaskTemplate,
|
66
|
-
crate::models::task_template::CreateTaskTemplate,
|
67
|
-
crate::models::task_template::UpdateTaskTemplate,
|
68
|
-
crate::executor::ExecutorConfig,
|
69
|
-
crate::executor::NormalizedConversation,
|
70
|
-
crate::executor::NormalizedEntry,
|
71
|
-
crate::executor::NormalizedEntryType,
|
72
|
-
crate::executor::ActionType,
|
73
|
-
// Auth schemas
|
74
|
-
crate::routes::auth::DeviceStartResponse,
|
75
|
-
// Config schemas
|
76
|
-
crate::routes::config::ConfigConstants,
|
77
|
-
// Filesystem schemas
|
78
|
-
crate::routes::filesystem::DirectoryEntry,
|
79
|
-
crate::routes::filesystem::DirectoryListResponse,
|
80
|
-
)
|
81
|
-
),
|
82
|
-
tags(
|
83
|
-
(name = "health", description = "Health check operations"),
|
84
|
-
(name = "projects", description = "Project management operations"),
|
85
|
-
(name = "tasks", description = "Task management operations"),
|
86
|
-
(name = "task_attempts", description = "Task execution attempt operations"),
|
87
|
-
(name = "task_templates", description = "Task template operations"),
|
88
|
-
(name = "auth", description = "Authentication operations"),
|
89
|
-
(name = "config", description = "Configuration operations"),
|
90
|
-
(name = "filesystem", description = "File system operations"),
|
91
|
-
)
|
92
|
-
)]
|
93
|
-
pub struct ApiDoc;
|
@@ -1,297 +0,0 @@
|
|
1
|
-
use axum::{
|
2
|
-
extract::{Request, State},
|
3
|
-
middleware::Next,
|
4
|
-
response::{Json as ResponseJson, Response},
|
5
|
-
routing::{get, post},
|
6
|
-
Json, Router,
|
7
|
-
};
|
8
|
-
use ts_rs::TS;
|
9
|
-
use utoipa::ToSchema;
|
10
|
-
|
11
|
-
use crate::{app_state::AppState, models::ApiResponse};
|
12
|
-
|
13
|
-
pub fn auth_router() -> Router<AppState> {
|
14
|
-
Router::new()
|
15
|
-
.route("/auth/github/device/start", post(device_start))
|
16
|
-
.route("/auth/github/device/poll", post(device_poll))
|
17
|
-
.route("/auth/github/check", get(github_check_token))
|
18
|
-
}
|
19
|
-
|
20
|
-
#[derive(serde::Deserialize, ToSchema)]
|
21
|
-
struct DeviceStartRequest {}
|
22
|
-
|
23
|
-
#[derive(serde::Serialize, TS, ToSchema)]
|
24
|
-
#[ts(export)]
|
25
|
-
pub struct DeviceStartResponse {
|
26
|
-
pub device_code: String,
|
27
|
-
pub user_code: String,
|
28
|
-
pub verification_uri: String,
|
29
|
-
pub expires_in: u32,
|
30
|
-
pub interval: u32,
|
31
|
-
}
|
32
|
-
|
33
|
-
#[derive(serde::Deserialize, ToSchema)]
|
34
|
-
pub struct DevicePollRequest {
|
35
|
-
device_code: String,
|
36
|
-
}
|
37
|
-
|
38
|
-
/// POST /auth/github/device/start
|
39
|
-
#[utoipa::path(
|
40
|
-
post,
|
41
|
-
path = "/auth/github/device/start",
|
42
|
-
tag = "auth",
|
43
|
-
summary = "Start GitHub OAuth device flow",
|
44
|
-
description = "Initiates GitHub OAuth device authorization flow, returning device and user codes",
|
45
|
-
responses(
|
46
|
-
(status = 200, description = "Device authorization flow started successfully", body = ApiResponse<DeviceStartResponse>),
|
47
|
-
(status = 500, description = "Failed to contact GitHub or parse response", body = ApiResponse<String>)
|
48
|
-
)
|
49
|
-
)]
|
50
|
-
pub async fn device_start() -> ResponseJson<ApiResponse<DeviceStartResponse>> {
|
51
|
-
let client_id = std::env::var("GITHUB_CLIENT_ID").unwrap_or_else(|_| "Ov23li2nd1KF5nCPbgoj".to_string());
|
52
|
-
|
53
|
-
let params = [("client_id", client_id.as_str()), ("scope", "user:email,repo")];
|
54
|
-
let client = reqwest::Client::new();
|
55
|
-
let res = client
|
56
|
-
.post("https://github.com/login/device/code")
|
57
|
-
.header("Accept", "application/json")
|
58
|
-
.form(¶ms)
|
59
|
-
.send()
|
60
|
-
.await;
|
61
|
-
let res = match res {
|
62
|
-
Ok(r) => r,
|
63
|
-
Err(e) => {
|
64
|
-
return ResponseJson(ApiResponse::error(&format!(
|
65
|
-
"Failed to contact GitHub: {e}"
|
66
|
-
)));
|
67
|
-
}
|
68
|
-
};
|
69
|
-
let json: serde_json::Value = match res.json().await {
|
70
|
-
Ok(j) => j,
|
71
|
-
Err(e) => {
|
72
|
-
return ResponseJson(ApiResponse::error(&format!(
|
73
|
-
"Failed to parse GitHub response: {e}"
|
74
|
-
)));
|
75
|
-
}
|
76
|
-
};
|
77
|
-
if let (
|
78
|
-
Some(device_code),
|
79
|
-
Some(user_code),
|
80
|
-
Some(verification_uri),
|
81
|
-
Some(expires_in),
|
82
|
-
Some(interval),
|
83
|
-
) = (
|
84
|
-
json.get("device_code").and_then(|v| v.as_str()),
|
85
|
-
json.get("user_code").and_then(|v| v.as_str()),
|
86
|
-
json.get("verification_uri").and_then(|v| v.as_str()),
|
87
|
-
json.get("expires_in").and_then(|v| v.as_u64()),
|
88
|
-
json.get("interval").and_then(|v| v.as_u64()),
|
89
|
-
) {
|
90
|
-
ResponseJson(ApiResponse::success(DeviceStartResponse {
|
91
|
-
device_code: device_code.to_string(),
|
92
|
-
user_code: user_code.to_string(),
|
93
|
-
verification_uri: verification_uri.to_string(),
|
94
|
-
expires_in: expires_in.try_into().unwrap_or(600),
|
95
|
-
interval: interval.try_into().unwrap_or(5),
|
96
|
-
}))
|
97
|
-
} else {
|
98
|
-
ResponseJson(ApiResponse::error(&format!("GitHub error: {}", json)))
|
99
|
-
}
|
100
|
-
}
|
101
|
-
|
102
|
-
/// POST /auth/github/device/poll
|
103
|
-
#[utoipa::path(
|
104
|
-
post,
|
105
|
-
path = "/auth/github/device/poll",
|
106
|
-
tag = "auth",
|
107
|
-
summary = "Poll GitHub OAuth device flow",
|
108
|
-
description = "Polls GitHub for OAuth device flow completion and saves access token",
|
109
|
-
request_body = DevicePollRequest,
|
110
|
-
responses(
|
111
|
-
(status = 200, description = "GitHub login successful or still pending", body = ApiResponse<String>),
|
112
|
-
(status = 400, description = "OAuth error or invalid device code", body = ApiResponse<String>)
|
113
|
-
)
|
114
|
-
)]
|
115
|
-
pub async fn device_poll(
|
116
|
-
State(app_state): State<AppState>,
|
117
|
-
Json(payload): Json<DevicePollRequest>,
|
118
|
-
) -> ResponseJson<ApiResponse<String>> {
|
119
|
-
let client_id = std::env::var("GITHUB_CLIENT_ID").unwrap_or_else(|_| "Ov23li2nd1KF5nCPbgoj".to_string());
|
120
|
-
|
121
|
-
let params = [
|
122
|
-
("client_id", client_id.as_str()),
|
123
|
-
("device_code", payload.device_code.as_str()),
|
124
|
-
("grant_type", "urn:ietf:params:oauth:grant-type:device_code"),
|
125
|
-
];
|
126
|
-
let client = reqwest::Client::new();
|
127
|
-
let res = client
|
128
|
-
.post("https://github.com/login/oauth/access_token")
|
129
|
-
.header("Accept", "application/json")
|
130
|
-
.form(¶ms)
|
131
|
-
.send()
|
132
|
-
.await;
|
133
|
-
let res = match res {
|
134
|
-
Ok(r) => r,
|
135
|
-
Err(e) => {
|
136
|
-
return ResponseJson(ApiResponse::error(&format!(
|
137
|
-
"Failed to contact GitHub: {e}"
|
138
|
-
)));
|
139
|
-
}
|
140
|
-
};
|
141
|
-
let json: serde_json::Value = match res.json().await {
|
142
|
-
Ok(j) => j,
|
143
|
-
Err(e) => {
|
144
|
-
return ResponseJson(ApiResponse::error(&format!(
|
145
|
-
"Failed to parse GitHub response: {e}"
|
146
|
-
)));
|
147
|
-
}
|
148
|
-
};
|
149
|
-
if let Some(error) = json.get("error").and_then(|v| v.as_str()) {
|
150
|
-
// Not authorized yet, or other error
|
151
|
-
return ResponseJson(ApiResponse::error(error));
|
152
|
-
}
|
153
|
-
let access_token = json.get("access_token").and_then(|v| v.as_str());
|
154
|
-
if let Some(access_token) = access_token {
|
155
|
-
// Fetch user info
|
156
|
-
let user_res = client
|
157
|
-
.get("https://api.github.com/user")
|
158
|
-
.bearer_auth(access_token)
|
159
|
-
.header("User-Agent", "automagik-forge-app")
|
160
|
-
.send()
|
161
|
-
.await;
|
162
|
-
let user_json: serde_json::Value = match user_res {
|
163
|
-
Ok(res) => match res.json().await {
|
164
|
-
Ok(json) => json,
|
165
|
-
Err(e) => {
|
166
|
-
return ResponseJson(ApiResponse::error(&format!(
|
167
|
-
"Failed to parse GitHub user response: {e}"
|
168
|
-
)));
|
169
|
-
}
|
170
|
-
},
|
171
|
-
Err(e) => {
|
172
|
-
return ResponseJson(ApiResponse::error(&format!(
|
173
|
-
"Failed to fetch user info: {e}"
|
174
|
-
)));
|
175
|
-
}
|
176
|
-
};
|
177
|
-
let username = user_json
|
178
|
-
.get("login")
|
179
|
-
.and_then(|v| v.as_str())
|
180
|
-
.map(|s| s.to_string());
|
181
|
-
// Fetch user emails
|
182
|
-
let emails_res = client
|
183
|
-
.get("https://api.github.com/user/emails")
|
184
|
-
.bearer_auth(access_token)
|
185
|
-
.header("User-Agent", "automagik-forge-app")
|
186
|
-
.send()
|
187
|
-
.await;
|
188
|
-
let emails_json: serde_json::Value = match emails_res {
|
189
|
-
Ok(res) => match res.json().await {
|
190
|
-
Ok(json) => json,
|
191
|
-
Err(e) => {
|
192
|
-
return ResponseJson(ApiResponse::error(&format!(
|
193
|
-
"Failed to parse GitHub emails response: {e}"
|
194
|
-
)));
|
195
|
-
}
|
196
|
-
},
|
197
|
-
Err(e) => {
|
198
|
-
return ResponseJson(ApiResponse::error(&format!(
|
199
|
-
"Failed to fetch user emails: {e}"
|
200
|
-
)));
|
201
|
-
}
|
202
|
-
};
|
203
|
-
let primary_email = emails_json
|
204
|
-
.as_array()
|
205
|
-
.and_then(|arr| {
|
206
|
-
arr.iter()
|
207
|
-
.find(|email| {
|
208
|
-
email
|
209
|
-
.get("primary")
|
210
|
-
.and_then(|v| v.as_bool())
|
211
|
-
.unwrap_or(false)
|
212
|
-
})
|
213
|
-
.and_then(|email| email.get("email").and_then(|v| v.as_str()))
|
214
|
-
})
|
215
|
-
.map(|s| s.to_string());
|
216
|
-
// Save to config
|
217
|
-
{
|
218
|
-
let mut config = app_state.get_config().write().await;
|
219
|
-
config.github.username = username.clone();
|
220
|
-
config.github.primary_email = primary_email.clone();
|
221
|
-
config.github.token = Some(access_token.to_string());
|
222
|
-
config.github_login_acknowledged = true; // Also acknowledge the GitHub login step
|
223
|
-
let config_path = crate::utils::config_path();
|
224
|
-
if config.save(&config_path).is_err() {
|
225
|
-
return ResponseJson(ApiResponse::error("Failed to save config"));
|
226
|
-
}
|
227
|
-
}
|
228
|
-
app_state.update_sentry_scope().await;
|
229
|
-
// Identify user in PostHog
|
230
|
-
let mut props = serde_json::Map::new();
|
231
|
-
if let Some(ref username) = username {
|
232
|
-
props.insert(
|
233
|
-
"username".to_string(),
|
234
|
-
serde_json::Value::String(username.clone()),
|
235
|
-
);
|
236
|
-
}
|
237
|
-
if let Some(ref email) = primary_email {
|
238
|
-
props.insert(
|
239
|
-
"email".to_string(),
|
240
|
-
serde_json::Value::String(email.clone()),
|
241
|
-
);
|
242
|
-
}
|
243
|
-
{
|
244
|
-
let props = serde_json::Value::Object(props);
|
245
|
-
app_state
|
246
|
-
.track_analytics_event("$identify", Some(props))
|
247
|
-
.await;
|
248
|
-
}
|
249
|
-
|
250
|
-
ResponseJson(ApiResponse::success("GitHub login successful".to_string()))
|
251
|
-
} else {
|
252
|
-
ResponseJson(ApiResponse::error("No access token yet"))
|
253
|
-
}
|
254
|
-
}
|
255
|
-
|
256
|
-
/// GET /auth/github/check
|
257
|
-
#[utoipa::path(
|
258
|
-
get,
|
259
|
-
path = "/auth/github/check",
|
260
|
-
tag = "auth",
|
261
|
-
summary = "Check GitHub token validity",
|
262
|
-
description = "Validates the stored GitHub access token by making a test API call",
|
263
|
-
responses(
|
264
|
-
(status = 200, description = "GitHub token is valid"),
|
265
|
-
(status = 400, description = "GitHub token is invalid or missing")
|
266
|
-
)
|
267
|
-
)]
|
268
|
-
pub async fn github_check_token(State(app_state): State<AppState>) -> ResponseJson<ApiResponse<()>> {
|
269
|
-
let config = app_state.get_config().read().await;
|
270
|
-
let token = config.github.token.clone();
|
271
|
-
drop(config);
|
272
|
-
if let Some(token) = token {
|
273
|
-
let client = reqwest::Client::new();
|
274
|
-
let res = client
|
275
|
-
.get("https://api.github.com/user")
|
276
|
-
.bearer_auth(&token)
|
277
|
-
.header("User-Agent", "automagik-forge-app")
|
278
|
-
.send()
|
279
|
-
.await;
|
280
|
-
match res {
|
281
|
-
Ok(r) if r.status().is_success() => ResponseJson(ApiResponse::success(())),
|
282
|
-
_ => ResponseJson(ApiResponse::error("github_token_invalid")),
|
283
|
-
}
|
284
|
-
} else {
|
285
|
-
ResponseJson(ApiResponse::error("github_token_invalid"))
|
286
|
-
}
|
287
|
-
}
|
288
|
-
|
289
|
-
/// Middleware to set Sentry user context for every request
|
290
|
-
pub async fn sentry_user_context_middleware(
|
291
|
-
State(app_state): State<AppState>,
|
292
|
-
req: Request,
|
293
|
-
next: Next,
|
294
|
-
) -> Response {
|
295
|
-
app_state.update_sentry_scope().await;
|
296
|
-
next.run(req).await
|
297
|
-
}
|