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
package/scripts/mcp_test.js
DELETED
@@ -1,374 +0,0 @@
|
|
1
|
-
const { spawn } = require('child_process');
|
2
|
-
|
3
|
-
console.error('🔄 Starting MCP server for comprehensive endpoint testing...');
|
4
|
-
|
5
|
-
// Test configuration
|
6
|
-
let currentStepIndex = 0;
|
7
|
-
let messageId = 1;
|
8
|
-
let testData = {
|
9
|
-
projectId: null,
|
10
|
-
taskId: null,
|
11
|
-
createdProjectId: null,
|
12
|
-
taskTitle: "Test Task from MCP Script",
|
13
|
-
updatedTaskTitle: "Updated Test Task Title",
|
14
|
-
secondTaskTitle: "Second Test Task",
|
15
|
-
renamedTaskTitle: "Renamed Second Task",
|
16
|
-
};
|
17
|
-
|
18
|
-
const testSequence = [
|
19
|
-
'initialize',
|
20
|
-
'initialized_notification',
|
21
|
-
'list_tools',
|
22
|
-
'list_projects',
|
23
|
-
'create_project',
|
24
|
-
'list_tasks', // empty
|
25
|
-
'create_task',
|
26
|
-
'get_task',
|
27
|
-
'list_tasks', // with task
|
28
|
-
'set_task_status',
|
29
|
-
'list_tasks', // filtered
|
30
|
-
'complete_task',
|
31
|
-
'list_tasks', // completed
|
32
|
-
'create_task', // second task
|
33
|
-
'update_task', // legacy
|
34
|
-
'update_task_title',
|
35
|
-
'update_task_description',
|
36
|
-
'list_tasks', // after updates
|
37
|
-
'delete_task_by_title',
|
38
|
-
'list_tasks', // final
|
39
|
-
'summary'
|
40
|
-
];
|
41
|
-
|
42
|
-
const stepHandlers = {
|
43
|
-
initialize: {
|
44
|
-
description: 'Initialize MCP connection',
|
45
|
-
action: () => {
|
46
|
-
console.log('📤 Sending initialize request...');
|
47
|
-
mcpProcess.stdin.write(`{"jsonrpc": "2.0", "id": ${messageId++}, "method": "initialize", "params": {"protocolVersion": "2024-11-05", "capabilities": {}, "clientInfo": {"name": "test", "version": "1.0.0"}}}\n`);
|
48
|
-
},
|
49
|
-
responseHandler: () => {
|
50
|
-
executeNextStep();
|
51
|
-
}
|
52
|
-
},
|
53
|
-
|
54
|
-
initialized_notification: {
|
55
|
-
description: 'Send initialized notification',
|
56
|
-
action: () => {
|
57
|
-
console.log('📤 Sending initialized notification...');
|
58
|
-
mcpProcess.stdin.write('{"jsonrpc": "2.0", "method": "notifications/initialized"}\n');
|
59
|
-
// Notifications don't have responses, auto-advance
|
60
|
-
setTimeout(() => executeNextStep(), 200);
|
61
|
-
},
|
62
|
-
responseHandler: null
|
63
|
-
},
|
64
|
-
|
65
|
-
list_tools: {
|
66
|
-
description: 'List available MCP tools',
|
67
|
-
action: () => {
|
68
|
-
console.log('📤 Sending tools/list...');
|
69
|
-
mcpProcess.stdin.write(`{"jsonrpc": "2.0", "id": ${messageId++}, "method": "tools/list", "params": {}}\n`);
|
70
|
-
},
|
71
|
-
responseHandler: () => {
|
72
|
-
executeNextStep();
|
73
|
-
}
|
74
|
-
},
|
75
|
-
|
76
|
-
list_projects: {
|
77
|
-
description: 'List all projects',
|
78
|
-
action: () => {
|
79
|
-
console.log('📤 Sending list_projects...');
|
80
|
-
mcpProcess.stdin.write(`{"jsonrpc": "2.0", "id": ${messageId++}, "method": "tools/call", "params": {"name": "list_projects", "arguments": {}}}\n`);
|
81
|
-
},
|
82
|
-
responseHandler: (response) => {
|
83
|
-
try {
|
84
|
-
const parsedResponse = JSON.parse(response);
|
85
|
-
if (parsedResponse.result?.content) {
|
86
|
-
const projectsResponse = JSON.parse(parsedResponse.result.content[0].text);
|
87
|
-
if (projectsResponse.success && projectsResponse.projects.length > 0) {
|
88
|
-
testData.projectId = projectsResponse.projects[0].id;
|
89
|
-
console.log(`💾 Found existing project: ${testData.projectId}`);
|
90
|
-
}
|
91
|
-
}
|
92
|
-
} catch (e) {
|
93
|
-
console.error('⚠️ Could not parse projects response');
|
94
|
-
}
|
95
|
-
executeNextStep();
|
96
|
-
}
|
97
|
-
},
|
98
|
-
|
99
|
-
create_project: {
|
100
|
-
description: 'Create a new test project',
|
101
|
-
action: () => {
|
102
|
-
console.log('📤 Sending create_project...');
|
103
|
-
mcpProcess.stdin.write(`{"jsonrpc": "2.0", "id": ${messageId++}, "method": "tools/call", "params": {"name": "create_project", "arguments": {"name": "Test Project from MCP", "git_repo_path": "/tmp/test-project", "use_existing_repo": false, "setup_script": "echo \\"Setup complete\\"", "dev_script": "echo \\"Dev server started\\""}}}\n`);
|
104
|
-
},
|
105
|
-
responseHandler: (response) => {
|
106
|
-
try {
|
107
|
-
const parsedResponse = JSON.parse(response);
|
108
|
-
if (parsedResponse.result?.content) {
|
109
|
-
const createProjectResponse = JSON.parse(parsedResponse.result.content[0].text);
|
110
|
-
if (createProjectResponse.success && createProjectResponse.project_id) {
|
111
|
-
testData.createdProjectId = createProjectResponse.project_id;
|
112
|
-
console.log(`💾 Created project: ${testData.createdProjectId}`);
|
113
|
-
}
|
114
|
-
}
|
115
|
-
} catch (e) {
|
116
|
-
console.error('⚠️ Could not parse create project response');
|
117
|
-
}
|
118
|
-
executeNextStep();
|
119
|
-
}
|
120
|
-
},
|
121
|
-
|
122
|
-
list_tasks: {
|
123
|
-
description: 'List tasks in project',
|
124
|
-
action: () => {
|
125
|
-
const projectToUse = testData.createdProjectId || testData.projectId;
|
126
|
-
const context = getListTasksContext();
|
127
|
-
|
128
|
-
console.log(`📤 Sending list_tasks (${context})...`);
|
129
|
-
|
130
|
-
let args = { project_id: projectToUse };
|
131
|
-
|
132
|
-
// Add context-specific filters
|
133
|
-
if (context === 'filtered') {
|
134
|
-
args.status = 'in-progress';
|
135
|
-
} else if (context === 'completed') {
|
136
|
-
args.status = 'done';
|
137
|
-
} else if (context === 'empty') {
|
138
|
-
args.include_execution_status = true;
|
139
|
-
}
|
140
|
-
|
141
|
-
mcpProcess.stdin.write(`{"jsonrpc": "2.0", "id": ${messageId++}, "method": "tools/call", "params": {"name": "list_tasks", "arguments": ${JSON.stringify(args)}}}\n`);
|
142
|
-
},
|
143
|
-
responseHandler: () => {
|
144
|
-
executeNextStep();
|
145
|
-
}
|
146
|
-
},
|
147
|
-
|
148
|
-
create_task: {
|
149
|
-
description: 'Create a new task',
|
150
|
-
action: () => {
|
151
|
-
const projectToUse = testData.createdProjectId || testData.projectId;
|
152
|
-
const isSecondTask = getCreateTaskContext() === 'second';
|
153
|
-
const title = isSecondTask ? testData.secondTaskTitle : testData.taskTitle;
|
154
|
-
const description = isSecondTask ?
|
155
|
-
"This is a second task for testing updates" :
|
156
|
-
"This task was created during endpoint testing";
|
157
|
-
|
158
|
-
console.log(`📤 Sending create_task (${isSecondTask ? 'second task' : 'first task'})...`);
|
159
|
-
mcpProcess.stdin.write(`{"jsonrpc": "2.0", "id": ${messageId++}, "method": "tools/call", "params": {"name": "create_task", "arguments": {"project_id": "${projectToUse}", "title": "${title}", "description": "${description}"}}}\n`);
|
160
|
-
},
|
161
|
-
responseHandler: (response) => {
|
162
|
-
try {
|
163
|
-
const parsedResponse = JSON.parse(response);
|
164
|
-
if (parsedResponse.result?.content) {
|
165
|
-
const createTaskResponse = JSON.parse(parsedResponse.result.content[0].text);
|
166
|
-
if (createTaskResponse.success && createTaskResponse.task_id) {
|
167
|
-
testData.taskId = createTaskResponse.task_id;
|
168
|
-
console.log(`💾 Created task: ${testData.taskId}`);
|
169
|
-
}
|
170
|
-
}
|
171
|
-
} catch (e) {
|
172
|
-
console.error('⚠️ Could not parse create task response');
|
173
|
-
}
|
174
|
-
executeNextStep();
|
175
|
-
}
|
176
|
-
},
|
177
|
-
|
178
|
-
get_task: {
|
179
|
-
description: 'Get task details by ID',
|
180
|
-
action: () => {
|
181
|
-
const projectToUse = testData.createdProjectId || testData.projectId;
|
182
|
-
console.log('📤 Sending get_task...');
|
183
|
-
mcpProcess.stdin.write(`{"jsonrpc": "2.0", "id": ${messageId++}, "method": "tools/call", "params": {"name": "get_task", "arguments": {"project_id": "${projectToUse}", "task_id": "${testData.taskId}"}}}\n`);
|
184
|
-
},
|
185
|
-
responseHandler: () => {
|
186
|
-
executeNextStep();
|
187
|
-
}
|
188
|
-
},
|
189
|
-
|
190
|
-
set_task_status: {
|
191
|
-
description: 'Set task status (agent-friendly)',
|
192
|
-
action: () => {
|
193
|
-
const projectToUse = testData.createdProjectId || testData.projectId;
|
194
|
-
console.log('📤 Sending set_task_status (agent-friendly)...');
|
195
|
-
mcpProcess.stdin.write(`{"jsonrpc": "2.0", "id": ${messageId++}, "method": "tools/call", "params": {"name": "set_task_status", "arguments": {"project_id": "${projectToUse}", "task_title": "${testData.taskTitle}", "status": "in-progress"}}}\n`);
|
196
|
-
},
|
197
|
-
responseHandler: () => {
|
198
|
-
executeNextStep();
|
199
|
-
}
|
200
|
-
},
|
201
|
-
|
202
|
-
complete_task: {
|
203
|
-
description: 'Complete task (agent-friendly)',
|
204
|
-
action: () => {
|
205
|
-
const projectToUse = testData.createdProjectId || testData.projectId;
|
206
|
-
console.log('📤 Sending complete_task (agent-friendly)...');
|
207
|
-
mcpProcess.stdin.write(`{"jsonrpc": "2.0", "id": ${messageId++}, "method": "tools/call", "params": {"name": "complete_task", "arguments": {"project_id": "${projectToUse}", "task_title": "${testData.taskTitle}"}}}\n`);
|
208
|
-
},
|
209
|
-
responseHandler: () => {
|
210
|
-
executeNextStep();
|
211
|
-
}
|
212
|
-
},
|
213
|
-
|
214
|
-
update_task: {
|
215
|
-
description: 'Update task (legacy UUID method)',
|
216
|
-
action: () => {
|
217
|
-
const projectToUse = testData.createdProjectId || testData.projectId;
|
218
|
-
console.log('📤 Sending update_task (legacy method)...');
|
219
|
-
mcpProcess.stdin.write(`{"jsonrpc": "2.0", "id": ${messageId++}, "method": "tools/call", "params": {"name": "update_task", "arguments": {"project_id": "${projectToUse}", "task_id": "${testData.taskId}", "title": "${testData.updatedTaskTitle}", "description": "Updated description via legacy method", "status": "in-review"}}}\n`);
|
220
|
-
},
|
221
|
-
responseHandler: () => {
|
222
|
-
executeNextStep();
|
223
|
-
}
|
224
|
-
},
|
225
|
-
|
226
|
-
update_task_title: {
|
227
|
-
description: 'Update task title (agent-friendly)',
|
228
|
-
action: () => {
|
229
|
-
const projectToUse = testData.createdProjectId || testData.projectId;
|
230
|
-
console.log('📤 Sending update_task_title (agent-friendly)...');
|
231
|
-
mcpProcess.stdin.write(`{"jsonrpc": "2.0", "id": ${messageId++}, "method": "tools/call", "params": {"name": "update_task_title", "arguments": {"project_id": "${projectToUse}", "current_title": "${testData.secondTaskTitle}", "new_title": "${testData.renamedTaskTitle}"}}}\n`);
|
232
|
-
},
|
233
|
-
responseHandler: () => {
|
234
|
-
executeNextStep();
|
235
|
-
}
|
236
|
-
},
|
237
|
-
|
238
|
-
update_task_description: {
|
239
|
-
description: 'Update task description (agent-friendly)',
|
240
|
-
action: () => {
|
241
|
-
const projectToUse = testData.createdProjectId || testData.projectId;
|
242
|
-
console.log('📤 Sending update_task_description (agent-friendly)...');
|
243
|
-
mcpProcess.stdin.write(`{"jsonrpc": "2.0", "id": ${messageId++}, "method": "tools/call", "params": {"name": "update_task_description", "arguments": {"project_id": "${projectToUse}", "task_title": "${testData.renamedTaskTitle}", "description": "This description was updated using the agent-friendly endpoint"}}}\n`);
|
244
|
-
},
|
245
|
-
responseHandler: () => {
|
246
|
-
executeNextStep();
|
247
|
-
}
|
248
|
-
},
|
249
|
-
|
250
|
-
delete_task_by_title: {
|
251
|
-
description: 'Delete task by title (agent-friendly)',
|
252
|
-
action: () => {
|
253
|
-
const projectToUse = testData.createdProjectId || testData.projectId;
|
254
|
-
console.log('📤 Sending delete_task_by_title (agent-friendly)...');
|
255
|
-
mcpProcess.stdin.write(`{"jsonrpc": "2.0", "id": ${messageId++}, "method": "tools/call", "params": {"name": "delete_task_by_title", "arguments": {"project_id": "${projectToUse}", "task_title": "${testData.renamedTaskTitle}"}}}\n`);
|
256
|
-
},
|
257
|
-
responseHandler: () => {
|
258
|
-
executeNextStep();
|
259
|
-
}
|
260
|
-
},
|
261
|
-
|
262
|
-
summary: {
|
263
|
-
description: 'Test completion summary',
|
264
|
-
action: () => {
|
265
|
-
console.log('✅ All endpoint tests completed successfully!');
|
266
|
-
console.log('');
|
267
|
-
console.log('📊 Test Summary:');
|
268
|
-
console.log(` - Project ID used: ${testData.projectId || 'N/A'}`);
|
269
|
-
console.log(` - Created project: ${testData.createdProjectId || 'N/A'}`);
|
270
|
-
console.log(` - Task ID tested: ${testData.taskId || 'N/A'}`);
|
271
|
-
console.log(` - Task title: ${testData.taskTitle}`);
|
272
|
-
console.log('');
|
273
|
-
console.log('🎯 Agent-Friendly Endpoints Tested:');
|
274
|
-
console.log(' ✅ set_task_status - Change task status by title');
|
275
|
-
console.log(' ✅ complete_task - Mark task done by title');
|
276
|
-
console.log(' ✅ update_task_title - Change task title');
|
277
|
-
console.log(' ✅ update_task_description - Update task description');
|
278
|
-
console.log(' ✅ delete_task_by_title - Delete task by title');
|
279
|
-
console.log('');
|
280
|
-
console.log('🔧 Legacy Endpoints Tested:');
|
281
|
-
console.log(' ✅ update_task - Update task by ID (more complex)');
|
282
|
-
console.log(' ✅ get_task - Get task details by ID');
|
283
|
-
console.log('');
|
284
|
-
console.log('🎉 All MCP endpoints are working correctly!');
|
285
|
-
console.log('💡 Agents should prefer the title-based endpoints for easier usage');
|
286
|
-
setTimeout(() => mcpProcess.kill(), 500);
|
287
|
-
},
|
288
|
-
responseHandler: null
|
289
|
-
}
|
290
|
-
};
|
291
|
-
|
292
|
-
// Helper functions to determine context
|
293
|
-
function getListTasksContext() {
|
294
|
-
const prevSteps = testSequence.slice(0, currentStepIndex);
|
295
|
-
if (prevSteps[prevSteps.length - 1] === 'create_project') return 'empty';
|
296
|
-
if (prevSteps[prevSteps.length - 1] === 'set_task_status') return 'filtered';
|
297
|
-
if (prevSteps[prevSteps.length - 1] === 'complete_task') return 'completed';
|
298
|
-
if (prevSteps[prevSteps.length - 1] === 'update_task_description') return 'after updates';
|
299
|
-
if (prevSteps[prevSteps.length - 1] === 'delete_task_by_title') return 'final';
|
300
|
-
return 'with task';
|
301
|
-
}
|
302
|
-
|
303
|
-
function getCreateTaskContext() {
|
304
|
-
const prevSteps = testSequence.slice(0, currentStepIndex);
|
305
|
-
const createTaskCount = prevSteps.filter(step => step === 'create_task').length;
|
306
|
-
return createTaskCount > 0 ? 'second' : 'first';
|
307
|
-
}
|
308
|
-
|
309
|
-
// Execute current step
|
310
|
-
function executeCurrentStep() {
|
311
|
-
if (currentStepIndex >= testSequence.length) {
|
312
|
-
console.log('⚠️ All steps completed');
|
313
|
-
return;
|
314
|
-
}
|
315
|
-
|
316
|
-
const stepName = testSequence[currentStepIndex];
|
317
|
-
const stepHandler = stepHandlers[stepName];
|
318
|
-
|
319
|
-
if (!stepHandler) {
|
320
|
-
console.error(`❌ Unknown step: ${stepName}`);
|
321
|
-
return;
|
322
|
-
}
|
323
|
-
|
324
|
-
console.log(`🔄 Step ${currentStepIndex + 1}/${testSequence.length}: ${stepHandler.description}`);
|
325
|
-
|
326
|
-
setTimeout(() => {
|
327
|
-
stepHandler.action();
|
328
|
-
}, 100);
|
329
|
-
}
|
330
|
-
|
331
|
-
// Move to next step
|
332
|
-
function executeNextStep() {
|
333
|
-
currentStepIndex++;
|
334
|
-
executeCurrentStep();
|
335
|
-
}
|
336
|
-
|
337
|
-
// Start MCP process
|
338
|
-
const mcpProcess = spawn('npx', [`--package=${process.argv[2]}`, "automagik-forge", "--mcp"], {
|
339
|
-
stdio: ['pipe', 'pipe', 'inherit'],
|
340
|
-
});
|
341
|
-
|
342
|
-
mcpProcess.stdout.on('data', (data) => {
|
343
|
-
const response = data.toString().trim();
|
344
|
-
const currentStepName = testSequence[currentStepIndex];
|
345
|
-
const stepHandler = stepHandlers[currentStepName];
|
346
|
-
|
347
|
-
console.log(`📥 MCP Response (${currentStepName}):`);
|
348
|
-
console.log(response);
|
349
|
-
|
350
|
-
if (stepHandler?.responseHandler) {
|
351
|
-
stepHandler.responseHandler(response);
|
352
|
-
}
|
353
|
-
});
|
354
|
-
|
355
|
-
mcpProcess.on('exit', (code) => {
|
356
|
-
console.error(`🔴 MCP server exited with code: ${code}`);
|
357
|
-
process.exit(0);
|
358
|
-
});
|
359
|
-
|
360
|
-
mcpProcess.on('error', (error) => {
|
361
|
-
console.error('❌ MCP server error:', error);
|
362
|
-
process.exit(1);
|
363
|
-
});
|
364
|
-
|
365
|
-
// Start the sequence
|
366
|
-
setTimeout(() => {
|
367
|
-
executeCurrentStep();
|
368
|
-
}, 500);
|
369
|
-
|
370
|
-
// Safety timeout
|
371
|
-
setTimeout(() => {
|
372
|
-
console.error('⏰ Test timeout - killing process');
|
373
|
-
mcpProcess.kill();
|
374
|
-
}, 45000);
|
package/scripts/prepare-db.js
DELETED
@@ -1,45 +0,0 @@
|
|
1
|
-
#!/usr/bin/env node
|
2
|
-
|
3
|
-
const { execSync } = require('child_process');
|
4
|
-
const fs = require('fs');
|
5
|
-
const path = require('path');
|
6
|
-
|
7
|
-
console.log('Preparing database for SQLx...');
|
8
|
-
|
9
|
-
// Change to backend directory
|
10
|
-
const backendDir = path.join(__dirname, '..', 'backend');
|
11
|
-
process.chdir(backendDir);
|
12
|
-
|
13
|
-
// Create temporary database file
|
14
|
-
const dbFile = path.join(backendDir, 'prepare_db.sqlite');
|
15
|
-
fs.writeFileSync(dbFile, '');
|
16
|
-
|
17
|
-
try {
|
18
|
-
// Get absolute path (cross-platform)
|
19
|
-
const dbPath = path.resolve(dbFile);
|
20
|
-
const databaseUrl = `sqlite:${dbPath}`;
|
21
|
-
|
22
|
-
console.log(`Using database: ${databaseUrl}`);
|
23
|
-
|
24
|
-
// Run migrations
|
25
|
-
console.log('Running migrations...');
|
26
|
-
execSync('cargo sqlx migrate run', {
|
27
|
-
stdio: 'inherit',
|
28
|
-
env: { ...process.env, DATABASE_URL: databaseUrl }
|
29
|
-
});
|
30
|
-
|
31
|
-
// Prepare queries
|
32
|
-
console.log('Preparing queries...');
|
33
|
-
execSync('cargo sqlx prepare', {
|
34
|
-
stdio: 'inherit',
|
35
|
-
env: { ...process.env, DATABASE_URL: databaseUrl }
|
36
|
-
});
|
37
|
-
|
38
|
-
console.log('Database preparation complete!');
|
39
|
-
|
40
|
-
} finally {
|
41
|
-
// Clean up temporary file
|
42
|
-
if (fs.existsSync(dbFile)) {
|
43
|
-
fs.unlinkSync(dbFile);
|
44
|
-
}
|
45
|
-
}
|
@@ -1,274 +0,0 @@
|
|
1
|
-
#!/usr/bin/env node
|
2
|
-
|
3
|
-
const fs = require("fs");
|
4
|
-
const path = require("path");
|
5
|
-
const net = require("net");
|
6
|
-
const { loadEnv } = require("./load-env");
|
7
|
-
|
8
|
-
const PORTS_FILE = path.join(__dirname, "..", ".dev-ports.json");
|
9
|
-
const DEV_ASSETS_SEED = path.join(__dirname, "..", "dev_assets_seed");
|
10
|
-
const DEV_ASSETS = path.join(__dirname, "..", "dev_assets");
|
11
|
-
|
12
|
-
/**
|
13
|
-
* Check if a port is available
|
14
|
-
*/
|
15
|
-
function isPortAvailable(port) {
|
16
|
-
return new Promise((resolve) => {
|
17
|
-
const sock = net.createConnection({ port, host: "localhost" });
|
18
|
-
sock.on("connect", () => {
|
19
|
-
sock.destroy();
|
20
|
-
resolve(false);
|
21
|
-
});
|
22
|
-
sock.on("error", () => resolve(true));
|
23
|
-
});
|
24
|
-
}
|
25
|
-
|
26
|
-
/**
|
27
|
-
* Find a free port starting from a given port
|
28
|
-
*/
|
29
|
-
async function findFreePort(startPort = 3000) {
|
30
|
-
let port = startPort;
|
31
|
-
while (!(await isPortAvailable(port))) {
|
32
|
-
port++;
|
33
|
-
if (port > 65535) {
|
34
|
-
throw new Error("No available ports found");
|
35
|
-
}
|
36
|
-
}
|
37
|
-
return port;
|
38
|
-
}
|
39
|
-
|
40
|
-
/**
|
41
|
-
* Load existing ports from file
|
42
|
-
*/
|
43
|
-
function loadPorts() {
|
44
|
-
try {
|
45
|
-
if (fs.existsSync(PORTS_FILE)) {
|
46
|
-
const data = fs.readFileSync(PORTS_FILE, "utf8");
|
47
|
-
return JSON.parse(data);
|
48
|
-
}
|
49
|
-
} catch (error) {
|
50
|
-
console.warn("Failed to load existing ports:", error.message);
|
51
|
-
}
|
52
|
-
return null;
|
53
|
-
}
|
54
|
-
|
55
|
-
/**
|
56
|
-
* Save ports to file
|
57
|
-
*/
|
58
|
-
function savePorts(ports) {
|
59
|
-
try {
|
60
|
-
fs.writeFileSync(PORTS_FILE, JSON.stringify(ports, null, 2));
|
61
|
-
} catch (error) {
|
62
|
-
console.error("Failed to save ports:", error.message);
|
63
|
-
throw error;
|
64
|
-
}
|
65
|
-
}
|
66
|
-
|
67
|
-
/**
|
68
|
-
* Verify that saved ports are still available
|
69
|
-
*/
|
70
|
-
async function verifyPorts(ports) {
|
71
|
-
// Check if ports object has all required properties
|
72
|
-
if (!ports.mcpSse) {
|
73
|
-
if (process.argv[2] === "get") {
|
74
|
-
console.log("Port structure outdated, missing mcpSse property, reallocating...");
|
75
|
-
}
|
76
|
-
return false;
|
77
|
-
}
|
78
|
-
|
79
|
-
const frontendAvailable = await isPortAvailable(ports.frontend);
|
80
|
-
const backendAvailable = await isPortAvailable(ports.backend);
|
81
|
-
const mcpSseAvailable = await isPortAvailable(ports.mcpSse);
|
82
|
-
|
83
|
-
if (process.argv[2] === "get" && (!frontendAvailable || !backendAvailable || !mcpSseAvailable)) {
|
84
|
-
console.log(
|
85
|
-
`Port availability check failed: frontend:${ports.frontend}=${frontendAvailable}, backend:${ports.backend}=${backendAvailable}, mcpSse:${ports.mcpSse}=${mcpSseAvailable}`
|
86
|
-
);
|
87
|
-
}
|
88
|
-
|
89
|
-
return frontendAvailable && backendAvailable && mcpSseAvailable;
|
90
|
-
}
|
91
|
-
|
92
|
-
/**
|
93
|
-
* Allocate ports for development
|
94
|
-
*/
|
95
|
-
async function allocatePorts() {
|
96
|
-
// Load .env variables first
|
97
|
-
loadEnv();
|
98
|
-
|
99
|
-
// Check for environment variables first (from .env)
|
100
|
-
const envFrontendPort = process.env.FRONTEND_PORT ? parseInt(process.env.FRONTEND_PORT) : null;
|
101
|
-
const envBackendPort = process.env.BACKEND_PORT ? parseInt(process.env.BACKEND_PORT) : null;
|
102
|
-
const envMcpSsePort = process.env.MCP_SSE_PORT ? parseInt(process.env.MCP_SSE_PORT) : null;
|
103
|
-
|
104
|
-
// If env ports are specified and available, use them
|
105
|
-
if (envFrontendPort && envBackendPort && envMcpSsePort) {
|
106
|
-
const frontendAvailable = await isPortAvailable(envFrontendPort);
|
107
|
-
const backendAvailable = await isPortAvailable(envBackendPort);
|
108
|
-
const mcpSseAvailable = await isPortAvailable(envMcpSsePort);
|
109
|
-
|
110
|
-
if (frontendAvailable && backendAvailable && mcpSseAvailable) {
|
111
|
-
const envPorts = {
|
112
|
-
frontend: envFrontendPort,
|
113
|
-
backend: envBackendPort,
|
114
|
-
mcpSse: envMcpSsePort,
|
115
|
-
timestamp: new Date().toISOString(),
|
116
|
-
};
|
117
|
-
|
118
|
-
if (process.argv[2] === "get") {
|
119
|
-
console.log("Using ports from .env file:");
|
120
|
-
console.log(`Frontend: ${envPorts.frontend}`);
|
121
|
-
console.log(`Backend: ${envPorts.backend}`);
|
122
|
-
console.log(`MCP SSE: ${envPorts.mcpSse}`);
|
123
|
-
}
|
124
|
-
|
125
|
-
savePorts(envPorts);
|
126
|
-
return envPorts;
|
127
|
-
} else {
|
128
|
-
if (process.argv[2] === "get") {
|
129
|
-
console.log("Some .env ports are not available, falling back to dynamic allocation...");
|
130
|
-
}
|
131
|
-
}
|
132
|
-
}
|
133
|
-
|
134
|
-
// Try to load existing ports if no .env ports or they're not available
|
135
|
-
const existingPorts = loadPorts();
|
136
|
-
|
137
|
-
if (existingPorts) {
|
138
|
-
// Verify existing ports are still available
|
139
|
-
if (await verifyPorts(existingPorts)) {
|
140
|
-
if (process.argv[2] === "get") {
|
141
|
-
console.log("Reusing existing dev ports:");
|
142
|
-
console.log(`Frontend: ${existingPorts.frontend}`);
|
143
|
-
console.log(`Backend: ${existingPorts.backend}`);
|
144
|
-
console.log(`MCP SSE: ${existingPorts.mcpSse || 'Not allocated'}`);
|
145
|
-
}
|
146
|
-
return existingPorts;
|
147
|
-
} else {
|
148
|
-
if (process.argv[2] === "get") {
|
149
|
-
console.log(
|
150
|
-
"Existing ports are no longer available, finding new ones..."
|
151
|
-
);
|
152
|
-
}
|
153
|
-
}
|
154
|
-
}
|
155
|
-
|
156
|
-
// Find new free ports as last resort
|
157
|
-
const frontendPort = await findFreePort(3000);
|
158
|
-
const backendPort = await findFreePort(frontendPort + 1);
|
159
|
-
const mcpSsePort = await findFreePort(8765);
|
160
|
-
|
161
|
-
const ports = {
|
162
|
-
frontend: frontendPort,
|
163
|
-
backend: backendPort,
|
164
|
-
mcpSse: mcpSsePort,
|
165
|
-
timestamp: new Date().toISOString(),
|
166
|
-
};
|
167
|
-
|
168
|
-
savePorts(ports);
|
169
|
-
|
170
|
-
if (process.argv[2] === "get") {
|
171
|
-
console.log("Allocated new dev ports:");
|
172
|
-
console.log(`Frontend: ${ports.frontend}`);
|
173
|
-
console.log(`Backend: ${ports.backend}`);
|
174
|
-
console.log(`MCP SSE: ${ports.mcpSse}`);
|
175
|
-
}
|
176
|
-
|
177
|
-
return ports;
|
178
|
-
}
|
179
|
-
|
180
|
-
/**
|
181
|
-
* Get ports (allocate if needed)
|
182
|
-
*/
|
183
|
-
async function getPorts() {
|
184
|
-
const ports = await allocatePorts();
|
185
|
-
copyDevAssets();
|
186
|
-
return ports;
|
187
|
-
}
|
188
|
-
|
189
|
-
/**
|
190
|
-
* Copy dev_assets_seed to dev_assets
|
191
|
-
*/
|
192
|
-
function copyDevAssets() {
|
193
|
-
try {
|
194
|
-
if (!fs.existsSync(DEV_ASSETS)) {
|
195
|
-
// Copy dev_assets_seed to dev_assets
|
196
|
-
fs.cpSync(DEV_ASSETS_SEED, DEV_ASSETS, { recursive: true });
|
197
|
-
|
198
|
-
if (process.argv[2] === "get") {
|
199
|
-
console.log("Copied dev_assets_seed to dev_assets");
|
200
|
-
}
|
201
|
-
}
|
202
|
-
} catch (error) {
|
203
|
-
console.error("Failed to copy dev assets:", error.message);
|
204
|
-
}
|
205
|
-
}
|
206
|
-
|
207
|
-
/**
|
208
|
-
* Clear saved ports
|
209
|
-
*/
|
210
|
-
function clearPorts() {
|
211
|
-
try {
|
212
|
-
if (fs.existsSync(PORTS_FILE)) {
|
213
|
-
fs.unlinkSync(PORTS_FILE);
|
214
|
-
console.log("Cleared saved dev ports");
|
215
|
-
} else {
|
216
|
-
console.log("No saved ports to clear");
|
217
|
-
}
|
218
|
-
} catch (error) {
|
219
|
-
console.error("Failed to clear ports:", error.message);
|
220
|
-
}
|
221
|
-
}
|
222
|
-
|
223
|
-
// CLI interface
|
224
|
-
if (require.main === module) {
|
225
|
-
const command = process.argv[2];
|
226
|
-
|
227
|
-
switch (command) {
|
228
|
-
case "get":
|
229
|
-
getPorts()
|
230
|
-
.then((ports) => {
|
231
|
-
console.log(JSON.stringify(ports));
|
232
|
-
})
|
233
|
-
.catch(console.error);
|
234
|
-
break;
|
235
|
-
|
236
|
-
case "clear":
|
237
|
-
clearPorts();
|
238
|
-
break;
|
239
|
-
|
240
|
-
case "frontend":
|
241
|
-
getPorts()
|
242
|
-
.then((ports) => {
|
243
|
-
console.log(JSON.stringify(ports.frontend, null, 2));
|
244
|
-
})
|
245
|
-
.catch(console.error);
|
246
|
-
break;
|
247
|
-
|
248
|
-
case "backend":
|
249
|
-
getPorts()
|
250
|
-
.then((ports) => {
|
251
|
-
console.log(JSON.stringify(ports.backend, null, 2));
|
252
|
-
})
|
253
|
-
.catch(console.error);
|
254
|
-
break;
|
255
|
-
|
256
|
-
default:
|
257
|
-
console.log("Usage:");
|
258
|
-
console.log(
|
259
|
-
" node setup-dev-environment.js get - Setup dev environment (ports + assets)"
|
260
|
-
);
|
261
|
-
console.log(
|
262
|
-
" node setup-dev-environment.js frontend - Get frontend port only"
|
263
|
-
);
|
264
|
-
console.log(
|
265
|
-
" node setup-dev-environment.js backend - Get backend port only"
|
266
|
-
);
|
267
|
-
console.log(
|
268
|
-
" node setup-dev-environment.js clear - Clear saved ports"
|
269
|
-
);
|
270
|
-
break;
|
271
|
-
}
|
272
|
-
}
|
273
|
-
|
274
|
-
module.exports = { getPorts, clearPorts, findFreePort };
|