├── .dockerignore ├── .github ├── ISSUE_TEMPLATE │ └── 1.BUG_REPORT.yml ├── PULL_REQUEST_TEMPLATE.md └── workflows │ └── build-ide-image.yaml ├── .gitignore ├── CODE_OF_CONDUCT.md ├── Dockerfile ├── LICENSE ├── README.md ├── app ├── client │ ├── git_provider │ │ └── gitness_git_provider.go │ ├── http_client.go │ └── workspace │ │ └── workspace_service.go ├── config │ ├── ai_developer_execution.go │ ├── aws_config.go │ ├── config.go │ ├── db.go │ ├── env.go │ ├── filestore.go │ ├── frontend_workspace.go │ ├── github_oauth.go │ ├── gitness.go │ ├── jwt.go │ ├── local_filestore_config.go │ ├── logger.go │ ├── model.go │ ├── monitoring_slack.go │ ├── new_relic.go │ ├── redis.go │ ├── s3_config.go │ ├── s3_filestore_config.go │ ├── workspace_config.go │ └── workspace_service.go ├── constants │ ├── app_env.go │ ├── asynq_task_names.go │ ├── filestore_type.go │ ├── models.go │ ├── pr_status.go │ ├── pr_type.go │ ├── project_workflows.go │ ├── redis_ttl.go │ ├── story_status.go │ └── story_type.go ├── controllers │ ├── activity_log_controller.go │ ├── auth_controller.go │ ├── design_story_review_controller.go │ ├── execution_controller.go │ ├── execution_output_controller.go │ ├── health.go │ ├── llm_api_key.go │ ├── project_controller.go │ ├── pull_request_comments_controller.go │ ├── pull_request_controller.go │ ├── story_controller.go │ └── user_controller.go ├── db │ └── migrations │ │ ├── 000001_create_users_table.down.sql │ │ ├── 000001_create_users_table.up.sql │ │ ├── 000002_create_organisations_table.down.sql │ │ ├── 000002_create_organisations_table.up.sql │ │ ├── 000003_create_projects_table.down.sql │ │ ├── 000003_create_projects_table.up.sql │ │ ├── 000004_create_stories_table.down.sql │ │ ├── 000004_create_stories_table.up.sql │ │ ├── 000005_create_story_files_table.down.sql │ │ ├── 000005_create_story_files_table.up.sql │ │ ├── 000006_create_story_instructions_table.down.sql │ │ ├── 000006_create_story_instructions_table.up.sql │ │ ├── 000007_create_story_test_cases_table.down.sql │ │ ├── 000007_create_story_test_cases_table.up.sql │ │ ├── 000008_create_executions_table.down.sql │ │ ├── 000008_create_executions_table.up.sql │ │ ├── 000009_create_execution_steps_table.down.sql │ │ ├── 000009_create_execution_steps_table.up.sql │ │ ├── 000010_create_execution_outputs_table.down.sql │ │ ├── 000010_create_execution_outputs_table.up.sql │ │ ├── 000011_create_activity_logs_table.down.sql │ │ ├── 000011_create_activity_logs_table.up.sql │ │ ├── 000012_create_execution_files_table.down.sql │ │ ├── 000012_create_execution_files_table.up.sql │ │ ├── 000013_add_reexecution_to_executions.down.sql │ │ ├── 000013_add_reexecution_to_executions.up.sql │ │ ├── 000014_alter_execution_output_table.down.sql │ │ ├── 000014_alter_execution_output_table.up.sql │ │ ├── 000015_create_pull_request_table.down.sql │ │ ├── 000015_create_pull_request_table.up.sql │ │ ├── 000016_create_pull_request_comments_table.down.sql │ │ ├── 000016_create_pull_request_comments_table.up.sql │ │ ├── 000017_remove_pull_req_exec_output.down.sql │ │ ├── 000017_remove_pull_req_exec_output.up.sql │ │ ├── 000018_add_is_deleted_column_story.down.sql │ │ ├── 000018_add_is_deleted_column_story.up.sql │ │ ├── 000019_remove_pull_req_exec_output.down.sql │ │ ├── 000019_remove_pull_req_exec_output.up.sql │ │ ├── 000020_comment_data_type_change.down.sql │ │ ├── 000020_comment_data_type_change.up.sql │ │ ├── 000021_llm_api_keys.down.sql │ │ ├── 000021_llm_api_keys.up.sql │ │ ├── 000022_add_supercoder_user_and_org.down.sql │ │ ├── 000022_add_supercoder_user_and_org.up.sql │ │ ├── 000023_remove_supercoder_user_and_org.down.sql │ │ ├── 000023_remove_supercoder_user_and_org.up.sql │ │ ├── 000024_alter_stories_table.down.sql │ │ ├── 000024_alter_stories_table.up.sql │ │ ├── 000025_create_design_story_review_table.down.sql │ │ ├── 000025_create_design_story_review_table.up.sql │ │ ├── 000026_update_api_key_length.down.sql │ │ ├── 000026_update_api_key_length.up.sql │ │ ├── 000027_add_frontend_framework_to_project.down.sql │ │ ├── 000027_add_frontend_framework_to_project.up.sql │ │ ├── 000028_add_type_in_story.down.sql │ │ ├── 000028_add_type_in_story.up.sql │ │ ├── 000029_add_prtype_in_pull_requests_table.down.sql │ │ ├── 000029_add_prtype_in_pull_requests_table.up.sql │ │ ├── 000030_inc_length_story_table.down.sql │ │ ├── 000030_inc_length_story_table.up.sql │ │ ├── 000031_rename_framework_in_projects.down.sql │ │ └── 000031_rename_framework_in_projects.up.sql ├── gateways │ ├── websocket.go │ └── websocket_gateway.go ├── llms │ ├── claude.go │ └── open_ai.go ├── middleware │ ├── organisation_authorization.go │ ├── project_authorization.go │ ├── pull_request_authorization.go │ ├── story_authorization.go │ └── user_authorization.go ├── models │ ├── activity_log.go │ ├── design_story_review.go │ ├── dtos │ │ ├── asynq_task │ │ │ ├── create_job_payload.go │ │ │ └── delete_workspace_task.go │ │ ├── gitness │ │ │ └── types.go │ │ └── llm_api_key │ │ │ └── llm_api_key_return.go │ ├── execution.go │ ├── execution_file.go │ ├── execution_output.go │ ├── execution_step.go │ ├── llm_api_key.go │ ├── organisation.go │ ├── project.go │ ├── pull_request.go │ ├── pull_request_comment.go │ ├── story.go │ ├── story_file.go │ ├── story_instruction.go │ ├── story_test_case.go │ ├── types │ │ ├── errors.go │ │ └── json_map.go │ └── user.go ├── monitoring │ └── slack_alerts.go ├── prompts │ ├── nextjs │ │ ├── ai_frontend_developer.txt │ │ ├── ai_frontend_developer_edit_code.txt │ │ └── next_js_build_checker.txt │ └── python │ │ ├── ai_developer_django.txt │ │ └── ai_developer_flask.txt ├── repositories │ ├── activity_log.go │ ├── design_story_review.go │ ├── execution.go │ ├── execution_output.go │ ├── execution_step.go │ ├── llm_api_key.go │ ├── options.go │ ├── organisation.go │ ├── project.go │ ├── project_connection_repository.go │ ├── pull_request.go │ ├── pull_request_comment.go │ ├── repository.go │ ├── story.go │ ├── story_file.go │ ├── story_instruction.go │ ├── story_test_case.go │ └── user.go ├── services │ ├── activity_log_service.go │ ├── auth │ │ ├── auth_provider.go │ │ ├── authenticator.go │ │ ├── email_auth_service.go │ │ ├── github_auth_service.go │ │ └── jwt_authentication_middleware.go │ ├── code_download_service.go │ ├── design_story_review_service.go │ ├── execution_output_service.go │ ├── execution_service.go │ ├── execution_step_service.go │ ├── filestore │ │ ├── filestore.go │ │ └── impl │ │ │ ├── local.go │ │ │ └── s3.go │ ├── git_providers │ │ ├── git_provider.go │ │ └── gitness_git_provider_service.go │ ├── llm_api_key.go │ ├── organisation_service.go │ ├── project_notification_service.go │ ├── project_service.go │ ├── pull_request_comments_service.go │ ├── pull_request_service.go │ ├── story_service.go │ └── user_service.go ├── tasks │ ├── check_execution_status.go │ ├── create_execution_job_task.go │ └── delete_workspace_task_handler.go ├── types │ ├── request │ │ ├── create_comment_request.go │ │ ├── create_design_story_comment_request.go │ │ ├── create_job_request.go │ │ ├── create_pr_request.go │ │ ├── create_project_request.go │ │ ├── create_story_request.go │ │ ├── create_user_request.go │ │ ├── create_worspace_request.go │ │ ├── delete_story_by_id.go │ │ ├── llm_api_key_request.go │ │ ├── merge_pull_request.go │ │ ├── retrieve_code_request.go │ │ ├── update_project_request.go │ │ ├── update_story_request.go │ │ ├── update_story_status_request.go │ │ └── user_signin_request.go │ └── response │ │ ├── create_workspace_response.go │ │ ├── get_all_commits_response.go │ │ ├── get_all_projects_response.go │ │ ├── get_all_pull_requests.go │ │ ├── get_all_stories_by_project_id.go │ │ ├── get_code_for_design_story.go │ │ ├── get_design_stories_by_project_id.go │ │ ├── get_story_by_id_response.go │ │ ├── get_story_response.go │ │ └── user_response.go ├── utils │ ├── api_key.go │ ├── asynq_helper.go │ ├── command_helper.go │ ├── date_time_helper.go │ ├── file_handler.go │ ├── file_service.go │ ├── get_directory_structure.go │ ├── git_command.go │ ├── hash_id_generator.go │ ├── image_utils.go │ └── random_string_generator.go └── workflow_executors │ ├── design_nextjs_workflow_config.go │ ├── python_django_workflow_config.go │ ├── python_flask_workflow_config.go │ ├── step_executors │ ├── code_generation_executor.go │ ├── git_commit_executor.go │ ├── git_make_branch_executor.go │ ├── git_make_pull_request_executor.go │ ├── git_push_executor.go │ ├── graph │ │ ├── execution_state.go │ │ ├── step_graph.go │ │ └── step_node.go │ ├── impl │ │ ├── django_reset_db_step_executor.go │ │ ├── django_server_step_executor.go │ │ ├── flask_reset_db_step_executor.go │ │ ├── flask_sever_test_executor.go │ │ ├── git_commit_executor.go │ │ ├── git_make_branch_executor.go │ │ ├── git_push_executor.go │ │ ├── gitness_make_pull_request_executor.go │ │ ├── next_js_server_test_executor.go │ │ ├── open_ai_code_generation_executor.go │ │ ├── open_ai_next_js_code_generation_executor.go │ │ ├── open_ai_next_js_update_code_file_executor.go │ │ ├── open_ai_update_code_file_executor.go │ │ └── python_poetry_package_install_executor.go │ ├── package_install_executor.go │ ├── reset_db_step_executor.go │ ├── server_start_test_executor.go │ ├── step_executor.go │ ├── steps │ │ ├── base_step.go │ │ ├── code_generate_step.go │ │ ├── git_commit_step.go │ │ ├── git_make_branch_step.go │ │ ├── git_make_pull_request.go │ │ ├── git_push_step.go │ │ ├── package_install_step.go │ │ ├── reset_db_step.go │ │ ├── server_start_test_step.go │ │ ├── step_names.go │ │ ├── step_types.go │ │ ├── update_code_file_step.go │ │ └── workflow_step.go │ └── update_code_executor.go │ ├── workflow_config.go │ ├── workflow_execution_args.go │ └── workflow_executor.go ├── bin └── migrations.sh ├── docker-compose.yaml ├── docker └── nginx │ └── default.conf ├── executor.go ├── go.mod ├── go.sum ├── gui ├── .dockerignore ├── .eslintignore ├── .eslintrc.json ├── .gitignore ├── .prettierrc.js ├── .stylelintignore ├── .stylelintrc.json ├── Dockerfile ├── README.md ├── global.d.ts ├── next.config.mjs ├── package.json ├── postcss.config.mjs ├── prod.Dockerfile ├── public │ ├── arrows │ │ ├── back_arrow.svg │ │ ├── bottom_arrow_grey.svg │ │ ├── bottom_arrow_thin_grey.svg │ │ ├── bottom_arrow_white.svg │ │ ├── left_arrow_grey.svg │ │ └── right_arrow_thin_grey.svg │ ├── fonts │ │ └── proxima-nova-2 │ │ │ ├── Mark-Simonson-Proxima-Nova-Black-Italic.otf │ │ │ ├── Mark-Simonson-Proxima-Nova-Black.otf │ │ │ ├── Mark-Simonson-Proxima-Nova-Bold-Italic.otf │ │ │ ├── Mark-Simonson-Proxima-Nova-Bold.otf │ │ │ ├── Mark-Simonson-Proxima-Nova-Extrabold-Italic.otf │ │ │ ├── Mark-Simonson-Proxima-Nova-Extrabold.otf │ │ │ ├── Mark-Simonson-Proxima-Nova-Light-Italic.otf │ │ │ ├── Mark-Simonson-Proxima-Nova-Light.otf │ │ │ ├── Mark-Simonson-Proxima-Nova-Regular-Italic.otf │ │ │ ├── Mark-Simonson-Proxima-Nova-Regular.otf │ │ │ ├── Mark-Simonson-Proxima-Nova-Semibold-Italic.otf │ │ │ ├── Mark-Simonson-Proxima-Nova-Semibold.otf │ │ │ ├── Mark-Simonson-Proxima-Nova-Thin-Italic.otf │ │ │ └── Mark-Simonson-Proxima-Nova-Thin.otf │ ├── icons │ │ ├── add_icon.svg │ │ ├── application_icons │ │ │ ├── discord_icon.svg │ │ │ └── github_icon.svg │ │ ├── browser_icon.svg │ │ ├── browser_icon_dark.svg │ │ ├── chat_bubble_icon.svg │ │ ├── claude_icon.svg │ │ ├── clock_icon.svg │ │ ├── close_icon.svg │ │ ├── code_add_icon.svg │ │ ├── code_minus_icon.svg │ │ ├── copy_icon.svg │ │ ├── delete_icon.svg │ │ ├── done_dot.svg │ │ ├── edit_icon.svg │ │ ├── empty_files_icon.svg │ │ ├── horizontal_three_dots.svg │ │ ├── in_review_dot.svg │ │ ├── inprogress_dot.svg │ │ ├── logout_icon.svg │ │ ├── move_to_icon.svg │ │ ├── openai_icon.svg │ │ ├── overview_warning_yellow.svg │ │ ├── password_hidden.svg │ │ ├── password_unhidden.svg │ │ ├── play_icon.svg │ │ ├── project_icon.svg │ │ ├── pull_requests │ │ │ ├── pr_closed_icon.svg │ │ │ ├── pr_merged_icon.svg │ │ │ ├── pr_open_grey_icon.svg │ │ │ ├── pr_open_icon.svg │ │ │ ├── pr_open_white_icon.svg │ │ │ └── pr_ready_icon.svg │ │ ├── red_cross_delete_icon.svg │ │ ├── search_icon.svg │ │ ├── selected │ │ │ ├── backend_workbench.svg │ │ │ ├── board.svg │ │ │ ├── code.svg │ │ │ ├── commits.svg │ │ │ ├── design.svg │ │ │ ├── files_changed.svg │ │ │ ├── frontend_workbench.svg │ │ │ ├── instructions.svg │ │ │ ├── models.svg │ │ │ ├── overview.svg │ │ │ ├── pull_requests.svg │ │ │ ├── reports.svg │ │ │ ├── test_cases.svg │ │ │ └── visual_diff.svg │ │ ├── settings_icon.svg │ │ ├── todo_dot.svg │ │ ├── unselected │ │ │ ├── backend_workbench.svg │ │ │ ├── board.svg │ │ │ ├── code.svg │ │ │ ├── commits.svg │ │ │ ├── deploy.svg │ │ │ ├── design.svg │ │ │ ├── files_changed.svg │ │ │ ├── frontend_workbench.svg │ │ │ ├── instructions.svg │ │ │ ├── models.svg │ │ │ ├── overview.svg │ │ │ ├── pull_requests.svg │ │ │ ├── reports.svg │ │ │ ├── test_cases.svg │ │ │ └── visual_diff.svg │ │ ├── upload_icon.svg │ │ ├── vertical_line.svg │ │ └── white_dot.svg │ ├── images │ │ ├── django_image.png │ │ ├── fastapi_image.png │ │ ├── flask_image.png │ │ ├── nextjs_image.png │ │ └── supercoder_image.svg │ └── logos │ │ ├── github_logo.svg │ │ ├── superagi_icon_logo.svg │ │ ├── superagi_logo.svg │ │ └── superagi_logo_round.svg ├── src │ ├── api │ │ ├── DashboardService.tsx │ │ └── apiConfig.tsx │ ├── app │ │ ├── (programmer) │ │ │ ├── board │ │ │ │ ├── board.module.css │ │ │ │ ├── layout.tsx │ │ │ │ └── page.tsx │ │ │ ├── code │ │ │ │ ├── Code.tsx │ │ │ │ └── page.tsx │ │ │ ├── design │ │ │ │ ├── layout.tsx │ │ │ │ ├── page.tsx │ │ │ │ └── review │ │ │ │ │ └── [story_id] │ │ │ │ │ ├── page.tsx │ │ │ │ │ └── review.module.css │ │ │ ├── design_workbench │ │ │ │ ├── layout.tsx │ │ │ │ └── page.tsx │ │ │ ├── layout.tsx │ │ │ ├── pull_request │ │ │ │ ├── PRList │ │ │ │ │ ├── GithubReviewButton.tsx │ │ │ │ │ └── PRList.tsx │ │ │ │ ├── [pr_id] │ │ │ │ │ ├── CommitLogs.tsx │ │ │ │ │ ├── FilesChanged.tsx │ │ │ │ │ ├── OpenTag.ts │ │ │ │ │ └── page.tsx │ │ │ │ ├── layout.tsx │ │ │ │ ├── page.tsx │ │ │ │ └── pr.module.css │ │ │ └── workbench │ │ │ │ ├── layout.tsx │ │ │ │ └── page.tsx │ │ ├── _app.css │ │ ├── constants │ │ │ ├── ActivityLogType.ts │ │ │ ├── BoardConstants.ts │ │ │ ├── NavbarConstants.ts │ │ │ ├── ProjectConstants.ts │ │ │ ├── PullRequestConstants.ts │ │ │ ├── SidebarConstants.ts │ │ │ ├── SkeletonConstants.ts │ │ │ └── UtilsConstants.ts │ │ ├── imagePath.tsx │ │ ├── layout.tsx │ │ ├── logout │ │ │ └── page.tsx │ │ ├── page.tsx │ │ ├── projects │ │ │ ├── layout.tsx │ │ │ ├── page.tsx │ │ │ └── projects.module.css │ │ ├── providers.tsx │ │ ├── settings │ │ │ ├── SettingsOptions │ │ │ │ └── Models.tsx │ │ │ ├── layout.tsx │ │ │ └── page.tsx │ │ └── utils.tsx │ ├── components │ │ ├── BackButton │ │ │ └── BackButton.tsx │ │ ├── CustomContainers │ │ │ ├── CustomContainers.tsx │ │ │ └── container.module.css │ │ ├── CustomDiffEditor │ │ │ ├── MonacoDiffEditor.tsx │ │ │ └── diff.module.css │ │ ├── CustomDrawer │ │ │ ├── CustomDrawer.tsx │ │ │ └── drawer.module.css │ │ ├── CustomDropdown │ │ │ ├── CustomDropdown.tsx │ │ │ └── dropdown.module.css │ │ ├── CustomInput │ │ │ ├── CustomInput.tsx │ │ │ └── input.module.css │ │ ├── CustomLoaders │ │ │ ├── CustomLoaders.tsx │ │ │ ├── Loader.tsx │ │ │ ├── SkeletonLoader.tsx │ │ │ └── loader.module.css │ │ ├── CustomModal │ │ │ ├── CustomModal.tsx │ │ │ └── modal.module.css │ │ ├── CustomSelect │ │ │ ├── CustomSelect.tsx │ │ │ └── select.module.css │ │ ├── CustomSidebar │ │ │ ├── CustomSidebar.tsx │ │ │ └── sidebar.module.css │ │ ├── CustomTabs │ │ │ ├── CustomTabs.tsx │ │ │ └── tabs.module.css │ │ ├── CustomTag │ │ │ ├── CustomTag.tsx │ │ │ └── tag.module.css │ │ ├── CustomTimeline │ │ │ ├── CustomTimeline.tsx │ │ │ └── timeline.module.css │ │ ├── DesignStoryComponents │ │ │ ├── CreateEditDesignStory.tsx │ │ │ ├── DesignStoryDetails.tsx │ │ │ ├── DesignStoryList.tsx │ │ │ ├── FrontendCodeSection.tsx │ │ │ ├── ReviewList.tsx │ │ │ └── desingStory.module.css │ │ ├── DiffViewer │ │ │ ├── DiffViewer.tsx │ │ │ └── diff.module.css │ │ ├── HomeComponents │ │ │ ├── CreateOrEditProjectBody.tsx │ │ │ ├── GithubStarModal.tsx │ │ │ ├── LandingPage.tsx │ │ │ └── home.module.css │ │ ├── ImageComponents │ │ │ ├── CustomImage.tsx │ │ │ ├── CustomImageSelector.tsx │ │ │ ├── CustomTextImage.tsx │ │ │ └── image.module.css │ │ ├── LayoutComponents │ │ │ ├── NavBar.tsx │ │ │ ├── SideBar.tsx │ │ │ └── style.css │ │ ├── RebuildModal │ │ │ └── RebuildModal.tsx │ │ ├── StoryComponents │ │ │ ├── CreateEditStory.tsx │ │ │ ├── InReviewIssue.tsx │ │ │ ├── InputSection.tsx │ │ │ ├── Instructions.tsx │ │ │ ├── Overview.tsx │ │ │ ├── SetupModelModal.tsx │ │ │ ├── StoryDetails.tsx │ │ │ ├── TestCases.tsx │ │ │ └── story.module.css │ │ ├── SyntaxDisplay │ │ │ └── SyntaxDisplay.tsx │ │ └── WorkBenchComponents │ │ │ ├── ActiveWorkbench.tsx │ │ │ ├── Activity.tsx │ │ │ ├── BackendWorkbench.tsx │ │ │ ├── Browser.tsx │ │ │ ├── DesignWorkbench.tsx │ │ │ ├── StoryDetailsWorkbench.tsx │ │ │ └── workbenchComponents.module.css │ ├── context │ │ ├── Boards.tsx │ │ ├── Design.tsx │ │ ├── PullRequests.tsx │ │ ├── SocketContext.tsx │ │ ├── UserContext.tsx │ │ └── Workbench.tsx │ ├── hooks │ │ └── useProjectDropdown.tsx │ ├── middleware.ts │ └── utils │ │ └── SocketUtils.tsx ├── tailwind.config.ts ├── tsconfig.json ├── types │ ├── authTypes.ts │ ├── customComponentTypes.ts │ ├── designStoryTypes.ts │ ├── imageComponentsTypes.ts │ ├── modelsTypes.ts │ ├── navbarTypes.ts │ ├── projectsTypes.ts │ ├── pullRequestsTypes.ts │ ├── settingTypes.ts │ ├── sidebarTypes.ts │ ├── storyTypes.ts │ └── workbenchTypes.ts └── yarn.lock ├── ide ├── node │ ├── Dockerfile │ ├── config.yaml │ └── settings.json └── python │ ├── Dockerfile │ ├── config.yaml │ ├── initialise.sh │ └── settings.json ├── server.go ├── startup-worker.sh ├── startup.sh ├── worker.go └── workspace-service ├── .gitignore ├── Dockerfile ├── app ├── clients │ ├── docker_client.go │ ├── k8s_client.go │ └── k8s_controller_client.go ├── config │ ├── config.go │ ├── env.go │ ├── frontend_workspace_config.go │ ├── new_relic.go │ ├── workspace_jobs.go │ └── workspace_service.go ├── controllers │ ├── health_controller.go │ ├── jobs_controller.go │ └── workspace_controller.go ├── models │ └── dto │ │ ├── create_job.go │ │ ├── create_workspace.go │ │ └── workspace_details.go ├── services │ ├── impl │ │ ├── docker_job_service.go │ │ ├── docker_workspace_service.go │ │ ├── k8s_job_service.go │ │ └── k8s_workspace_service.go │ ├── job_service.go │ └── workspace_service.go └── utils │ └── fs_utils.go ├── go.mod ├── go.sum ├── server.go └── templates ├── django ├── .gitignore ├── .vscode │ └── tasks.json ├── manage.py ├── myapp │ ├── __init__.py │ ├── admin.py │ ├── app.py │ ├── migrations │ │ └── __init__.py │ ├── models.py │ ├── tests.py │ ├── urls.py │ └── views.py ├── project │ ├── __init__.py │ ├── asgi.py │ ├── settings.py │ ├── urls.py │ └── wsgi.py ├── pyproject.toml ├── server_test.txt ├── static │ ├── css │ │ └── styles.css │ └── js │ │ └── scripts.js ├── templates │ ├── about.html │ ├── home.html │ └── registration │ │ └── login.html └── terminal.txt ├── flask ├── .gitignore ├── .vscode │ └── tasks.json ├── __init__.py ├── app.py ├── models │ ├── __init__.py │ └── model.py ├── pyproject.toml ├── static │ ├── css │ │ └── style.css │ └── js │ │ └── main.js └── templates │ └── index.html └── nextjs ├── .eslintrc.json ├── .gitignore ├── README.md ├── app ├── favicon.ico ├── globals.css ├── layout.tsx └── page.tsx ├── next.config.mjs ├── package-lock.json ├── package.json ├── postcss.config.mjs ├── public ├── next.svg └── vercel.svg ├── tailwind.config.ts └── tsconfig.json /.dockerignore: -------------------------------------------------------------------------------- 1 | Dockerfile 2 | docker-compose.yaml 3 | gui 4 | ide 5 | workspace-service 6 | -------------------------------------------------------------------------------- /.github/workflows/build-ide-image.yaml: -------------------------------------------------------------------------------- 1 | name: Build IDE image 2 | 3 | on: 4 | workflow_dispatch: 5 | inputs: 6 | environment: 7 | type: choice 8 | description: 'The ide to build' 9 | options: 10 | - python 11 | - node 12 | 13 | concurrency: 14 | group: build-ide-image 15 | cancel-in-progress: false 16 | 17 | jobs: 18 | build: 19 | runs-on: ubuntu-latest 20 | steps: 21 | - name: Checkout repository 22 | uses: actions/checkout@v2 23 | 24 | - name: Set up QEMU 25 | uses: docker/setup-qemu-action@v3 26 | 27 | - name: Set up Docker Buildx 28 | uses: docker/setup-buildx-action@v3 29 | 30 | - name: Login to Docker Hub 31 | uses: docker/login-action@v3 32 | with: 33 | username: ${{ secrets.DOCKERHUB_USERNAME }} 34 | password: ${{ secrets.DOCKERHUB_TOKEN }} 35 | 36 | - name: Build and push 37 | uses: docker/build-push-action@v6 38 | with: 39 | platforms: linux/amd64,linux/arm64 40 | context: ./ide/${{ github.event.inputs.environment }} 41 | push: true 42 | tags: superagidev/supercoder-${{ github.event.inputs.environment }}-ide:latest -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Binaries for programs and plugins 2 | *.exe 3 | *.exe~ 4 | *.dll 5 | *.so 6 | *.dylib 7 | *.test 8 | 9 | # Output of the go coverage tool, specifically when used with LiteIDE 10 | *.out 11 | 12 | # Dependency directories (remove the comment below if you use vendoring) 13 | vendor/ 14 | 15 | # Go workspace file 16 | go.work 17 | 18 | # IDE and editor directories and files 19 | .idea/ 20 | *.swp 21 | *.swo 22 | *.swn 23 | *~ 24 | 25 | # Mac OS specific 26 | .DS_Store 27 | 28 | # Windows specific 29 | Thumbs.db 30 | 31 | #workspace virtual environment 32 | workspace/venv/ 33 | .env 34 | .envrc 35 | gui/.husky/pre-commit -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 TransformerOptimus 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /app/client/http_client.go: -------------------------------------------------------------------------------- 1 | package client 2 | 3 | import ( 4 | "bytes" 5 | "encoding/json" 6 | "net/http" 7 | ) 8 | 9 | type HttpClient struct { 10 | client *http.Client 11 | } 12 | 13 | func NewHttpClient() *HttpClient { 14 | return &HttpClient{ 15 | client: &http.Client{}, 16 | } 17 | } 18 | 19 | func (hc *HttpClient) Post(url string, payload interface{}, headers map[string]string) (*http.Response, error) { 20 | payloadBytes, err := json.Marshal(payload) 21 | if err != nil { 22 | return nil, err 23 | } 24 | 25 | req, err := http.NewRequest("POST", url, bytes.NewBuffer(payloadBytes)) 26 | if err != nil { 27 | return nil, err 28 | } 29 | 30 | for key, value := range headers { 31 | req.Header.Set(key, value) 32 | } 33 | 34 | return hc.client.Do(req) 35 | } 36 | 37 | func (hc *HttpClient) Get(url string, headers map[string]string) (*http.Response, error) { 38 | req, err := http.NewRequest("GET", url, nil) 39 | if err != nil { 40 | return nil, err 41 | } 42 | 43 | for key, value := range headers { 44 | req.Header.Set(key, value) 45 | } 46 | 47 | return hc.client.Do(req) 48 | } 49 | -------------------------------------------------------------------------------- /app/config/ai_developer_execution.go: -------------------------------------------------------------------------------- 1 | package config 2 | 3 | import "github.com/knadh/koanf/v2" 4 | 5 | type AIDeveloperExecutionConfig struct { 6 | config *koanf.Koanf 7 | } 8 | 9 | func (adec *AIDeveloperExecutionConfig) GetStoryID() int64 { 10 | return config.MustInt64("execution.story.id") 11 | } 12 | func (adec *AIDeveloperExecutionConfig) IsReExecution() bool { 13 | return config.Bool("execution.reexecution") 14 | } 15 | func (adec *AIDeveloperExecutionConfig) GetBranch() string { 16 | return config.String("execution.branch") 17 | } 18 | func (adec *AIDeveloperExecutionConfig) GetPullRequestID() int64 { 19 | return config.Int64("execution.pullrequest.id") 20 | } 21 | func (adec *AIDeveloperExecutionConfig) GetExecutionID() int64 { 22 | return config.Int64("execution.id") 23 | } 24 | 25 | func NewAIDeveloperExecutionConfig(config *koanf.Koanf) *AIDeveloperExecutionConfig { 26 | return &AIDeveloperExecutionConfig{config} 27 | } 28 | -------------------------------------------------------------------------------- /app/config/env.go: -------------------------------------------------------------------------------- 1 | package config 2 | 3 | import ( 4 | "ai-developer/app/constants" 5 | "github.com/knadh/koanf/v2" 6 | "go.uber.org/zap" 7 | ) 8 | 9 | type EnvConfig struct { 10 | config *koanf.Koanf 11 | logger *zap.Logger 12 | } 13 | 14 | func (e EnvConfig) IsDevelopment() bool { 15 | return e.config.String("app.env") == constants.Development 16 | } 17 | 18 | func (e EnvConfig) Domain() string { 19 | var domain string 20 | if !e.IsDevelopment() { 21 | domain = e.config.String("domain") 22 | } 23 | e.logger.Debug("Setting domain for auth", zap.String("domain", domain)) 24 | return domain 25 | } 26 | 27 | func NewEnvConfig(config *koanf.Koanf, logger *zap.Logger) *EnvConfig { 28 | return &EnvConfig{ 29 | config: config, 30 | logger: logger.Named("EnvConfig"), 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /app/config/filestore.go: -------------------------------------------------------------------------------- 1 | package config 2 | 3 | import ( 4 | "github.com/knadh/koanf/v2" 5 | ) 6 | 7 | type FileStoreConfig struct { 8 | config *koanf.Koanf 9 | } 10 | 11 | func (fsc *FileStoreConfig) GetFileStoreType() string { 12 | return fsc.config.String("filestore.type") 13 | } 14 | 15 | func NewFileStoreConfig(config *koanf.Koanf) *FileStoreConfig { 16 | return &FileStoreConfig{config} 17 | } 18 | -------------------------------------------------------------------------------- /app/config/frontend_workspace.go: -------------------------------------------------------------------------------- 1 | package config 2 | 3 | import "fmt" 4 | import "path/filepath" 5 | 6 | func FrontendWorkspacePath(projectHashID string, storyHashId string) string{ 7 | output := filepath.Join(WorkspaceWorkingDirectory(), projectHashID, "frontend" , ".stories" , storyHashId) 8 | fmt.Println("___frontend workspace____",output) 9 | return output 10 | } -------------------------------------------------------------------------------- /app/config/github_oauth.go: -------------------------------------------------------------------------------- 1 | package config 2 | 3 | import "github.com/knadh/koanf/v2" 4 | 5 | type GithubOAuthConfig struct { 6 | config *koanf.Koanf 7 | } 8 | 9 | func (g GithubOAuthConfig) ClientId() string { 10 | return g.config.String("github.client.id") 11 | } 12 | 13 | func (g GithubOAuthConfig) ClientSecret() string { 14 | return g.config.String("github.client.secret") 15 | } 16 | 17 | func (g GithubOAuthConfig) RedirectURL() string { 18 | return g.config.String("github.redirect.url") 19 | } 20 | 21 | func (g GithubOAuthConfig) FrontendURL() string { 22 | return g.config.String("github.frontend.url") 23 | } 24 | 25 | func NewGithubOAuthConfig(config *koanf.Koanf) *GithubOAuthConfig { 26 | return &GithubOAuthConfig{ 27 | config: config, 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /app/config/gitness.go: -------------------------------------------------------------------------------- 1 | package config 2 | 3 | func GitnessURL() string { 4 | return config.String("gitness.url") 5 | } 6 | 7 | func GitnessUser() string { 8 | return config.String("gitness.user") 9 | } 10 | 11 | func GitnessToken() string { 12 | return config.String("gitness.token") 13 | } 14 | 15 | func GitnessHost() string { 16 | return config.String("gitness.host") 17 | } 18 | -------------------------------------------------------------------------------- /app/config/jwt.go: -------------------------------------------------------------------------------- 1 | package config 2 | 3 | import ( 4 | "github.com/knadh/koanf/v2" 5 | "log" 6 | "time" 7 | ) 8 | 9 | type JWTConfig struct { 10 | config *koanf.Koanf 11 | } 12 | 13 | func (j JWTConfig) Secret() string { 14 | return j.config.String("jwt.secret.key") 15 | } 16 | 17 | func (j JWTConfig) ExpiryHours() time.Duration { 18 | expiryHours := j.config.String("jwt.expiry.hours") 19 | expiryDuration, err := time.ParseDuration(expiryHours) 20 | if err != nil { 21 | log.Fatalf("could not parse jwt.expiry_hours: %v", err) 22 | } 23 | return expiryDuration 24 | } 25 | 26 | func NewJWTConfig(config *koanf.Koanf) *JWTConfig { 27 | return &JWTConfig{config: config} 28 | } 29 | 30 | func JWTSecret() string { return config.String("jwt.secret.key") } 31 | 32 | func JWTExpiryHours() time.Duration { 33 | expiryHours := config.String("jwt.expiry.hours") 34 | expiryDuration, err := time.ParseDuration(expiryHours) 35 | if err != nil { 36 | log.Fatalf("could not parse jwt.expiry_hours: %v", err) 37 | } 38 | return expiryDuration 39 | } 40 | -------------------------------------------------------------------------------- /app/config/local_filestore_config.go: -------------------------------------------------------------------------------- 1 | package config 2 | 3 | import ( 4 | "github.com/knadh/koanf/v2" 5 | ) 6 | 7 | type LocalFileStoreConfig struct { 8 | config *koanf.Koanf 9 | } 10 | 11 | func (lfs *LocalFileStoreConfig) GetLocalDir() string { 12 | return lfs.config.String("filestore.local.dir") 13 | } 14 | 15 | func NewLocalFileStoreConfig(config *koanf.Koanf) *LocalFileStoreConfig { 16 | return &LocalFileStoreConfig{config} 17 | } 18 | -------------------------------------------------------------------------------- /app/config/logger.go: -------------------------------------------------------------------------------- 1 | package config 2 | 3 | import ( 4 | "ai-developer/app/constants" 5 | "go.uber.org/zap" 6 | "os" 7 | ) 8 | 9 | var Logger *zap.Logger 10 | 11 | func InitLogger() { 12 | var err error 13 | if env, exists := os.LookupEnv("AI_DEVELOPER_APP_ENV"); env != constants.Production || !exists { 14 | Logger, err = zap.NewDevelopment() 15 | if err != nil { 16 | panic(err) 17 | } 18 | Logger.Info("Logger initialized in development mode") 19 | } else { 20 | Logger, err = zap.NewProduction() 21 | if err != nil { 22 | panic(err) 23 | } 24 | Logger.Info("Logger initialized in production mode") 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /app/config/model.go: -------------------------------------------------------------------------------- 1 | package config 2 | 3 | func OpenAIAPIKey() string { return config.String("openai.api.key") } 4 | 5 | func ClaudeAPIKey() string { return config.String("claude.api.key") } 6 | -------------------------------------------------------------------------------- /app/config/monitoring_slack.go: -------------------------------------------------------------------------------- 1 | package config 2 | 3 | func SlackWebhookURL() string { return config.String("monitoring.slack.url") } 4 | -------------------------------------------------------------------------------- /app/config/new_relic.go: -------------------------------------------------------------------------------- 1 | package config 2 | 3 | // NewRelicLicenseKey returns the New Relic license key. 4 | func NewRelicLicenseKey() string { return config.String("newrelic.license.key") } 5 | 6 | // NewRelicAppName returns the New Relic app name. 7 | func NewRelicAppName() string { return config.String("newrelic.app.name") } 8 | -------------------------------------------------------------------------------- /app/config/redis.go: -------------------------------------------------------------------------------- 1 | package config 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "github.com/redis/go-redis/v9" 7 | ) 8 | 9 | func RedisHost() string { 10 | return config.String("redis.host") 11 | } 12 | 13 | func RedisPort() int { 14 | return config.Int("redis.port") 15 | } 16 | 17 | func RedisDB() int { 18 | return config.Int("redis.db") 19 | } 20 | 21 | func RedisAddress() string { 22 | return fmt.Sprintf("%s:%d", RedisHost(), RedisPort()) 23 | } 24 | 25 | func InitRedis(ctx context.Context) (client *redis.Client) { 26 | fmt.Println("Initializing Redis Client.....") 27 | client = redis.NewClient(&redis.Options{ 28 | Addr: RedisAddress(), 29 | DB: RedisDB(), 30 | }) 31 | 32 | output, err := client.Ping(ctx).Result() 33 | if err != nil { 34 | fmt.Println("Failed to connect to Redis") 35 | panic(err) 36 | } 37 | fmt.Printf("Connected to Redis: %v\n", output) 38 | return client 39 | } 40 | -------------------------------------------------------------------------------- /app/config/s3_config.go: -------------------------------------------------------------------------------- 1 | package config 2 | 3 | func AWSAccessKeyID() string { return config.String("aws.access.key.id") } 4 | 5 | func AWSSecretAccessKey() string { return config.String("aws.secret.access.key") } 6 | 7 | func AWSBucketName() string { return config.String("aws.bucket.name") } 8 | 9 | func AWSRegion() string { return config.String("aws.region") } 10 | -------------------------------------------------------------------------------- /app/config/s3_filestore_config.go: -------------------------------------------------------------------------------- 1 | package config 2 | 3 | import ( 4 | "github.com/knadh/koanf/v2" 5 | ) 6 | 7 | type S3FileStoreConfig struct { 8 | config *koanf.Koanf 9 | } 10 | 11 | func (fsc *S3FileStoreConfig) GetS3Bucket() string { 12 | return fsc.config.String("filestore.s3.bucket") 13 | } 14 | 15 | func (fsc *S3FileStoreConfig) GetS3Path() string { 16 | return fsc.config.String("filestore.s3.path") 17 | } 18 | 19 | func NewS3FileStoreConfig(config *koanf.Koanf) *S3FileStoreConfig { 20 | return &S3FileStoreConfig{config} 21 | } 22 | -------------------------------------------------------------------------------- /app/config/workspace_config.go: -------------------------------------------------------------------------------- 1 | package config 2 | 3 | func WorkspaceWorkingDirectory() string { return config.String("workspace.working.dir") } 4 | func WorkspaceStaticFrontendUrl() string { return config.String("workspace.static.frontend.url") } 5 | -------------------------------------------------------------------------------- /app/config/workspace_service.go: -------------------------------------------------------------------------------- 1 | package config 2 | 3 | import "github.com/knadh/koanf/v2" 4 | 5 | type WorkspaceServiceConfig struct { 6 | config *koanf.Koanf 7 | } 8 | 9 | func (wsc *WorkspaceServiceConfig) GetEndpoint() string { 10 | return config.String("workspace.service.endpoint") 11 | } 12 | 13 | func NewWorkspaceServiceConfig(config *koanf.Koanf) *WorkspaceServiceConfig { 14 | return &WorkspaceServiceConfig{config} 15 | } 16 | -------------------------------------------------------------------------------- /app/constants/app_env.go: -------------------------------------------------------------------------------- 1 | package constants 2 | 3 | const ( 4 | Production = "production" 5 | Development = "development" 6 | ) 7 | -------------------------------------------------------------------------------- /app/constants/asynq_task_names.go: -------------------------------------------------------------------------------- 1 | package constants 2 | 3 | const ( 4 | CreateExecutionJobTaskType = "create:job" 5 | DeleteWorkspaceTaskType = "delete:workspace" 6 | CheckExecutionStatusTaskType = "check:execution_status" 7 | ) 8 | -------------------------------------------------------------------------------- /app/constants/filestore_type.go: -------------------------------------------------------------------------------- 1 | package constants 2 | 3 | const ( 4 | LOCAL = "local" 5 | S3 = "s3" 6 | ) -------------------------------------------------------------------------------- /app/constants/models.go: -------------------------------------------------------------------------------- 1 | package constants 2 | 3 | const ( 4 | GPT_4O = "gpt-4o" 5 | GPT_3_5_Turbo = "gpt-3.5-turbo" 6 | GPT_3_5 = "gpt-3.5" 7 | CLAUDE_3 = "claude-3" 8 | ) 9 | -------------------------------------------------------------------------------- /app/constants/pr_status.go: -------------------------------------------------------------------------------- 1 | package constants 2 | 3 | const ( 4 | Open = "OPEN" 5 | Close = "CLOSE" 6 | Merged = "MERGED" 7 | ) 8 | -------------------------------------------------------------------------------- /app/constants/pr_type.go: -------------------------------------------------------------------------------- 1 | package constants 2 | 3 | const ( 4 | Automated = "automated" 5 | Manual = "manual" 6 | ) 7 | -------------------------------------------------------------------------------- /app/constants/project_workflows.go: -------------------------------------------------------------------------------- 1 | package constants 2 | 3 | const ( 4 | Flask = "flask" 5 | NextJs = "nextjs" 6 | ) 7 | -------------------------------------------------------------------------------- /app/constants/redis_ttl.go: -------------------------------------------------------------------------------- 1 | package constants 2 | 3 | import "time" 4 | 5 | const ( 6 | ProjectConnectionTTL = 6 * time.Hour 7 | ) 8 | -------------------------------------------------------------------------------- /app/constants/story_status.go: -------------------------------------------------------------------------------- 1 | package constants 2 | 3 | const ( 4 | Todo = "TODO" 5 | InProgress = "IN_PROGRESS" 6 | Done = "DONE" 7 | MaxLoopIterationReached = "MAX_LOOP_ITERATION_REACHED" 8 | InReviewLLMKeyNotFound = "IN_REVIEW_LLM_KEY_NOT_FOUND" 9 | InReview = "IN_REVIEW" 10 | ExecutionEnqueued = "IN_PROGRESS_EXECUTION_ENQUEUED" 11 | ) 12 | 13 | func ValidStatuses() map[string]bool { 14 | return map[string]bool{ 15 | Todo: true, 16 | InProgress: true, 17 | Done: true, 18 | MaxLoopIterationReached: true, 19 | InReviewLLMKeyNotFound: true, 20 | InReview: true, 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /app/constants/story_type.go: -------------------------------------------------------------------------------- 1 | package constants 2 | 3 | const ( 4 | Backend = "backend" 5 | Frontend = "frontend" 6 | ) -------------------------------------------------------------------------------- /app/controllers/activity_log_controller.go: -------------------------------------------------------------------------------- 1 | package controllers 2 | 3 | import ( 4 | "ai-developer/app/services" 5 | "github.com/gin-gonic/gin" 6 | "net/http" 7 | "strconv" 8 | ) 9 | 10 | type ActivityLogController struct { 11 | Service *services.ActivityLogService 12 | } 13 | 14 | func NewActivityLogController(service *services.ActivityLogService) *ActivityLogController { 15 | return &ActivityLogController{Service: service} 16 | } 17 | 18 | func (ctrl *ActivityLogController) GetActivityLogsByStoryID(c *gin.Context) { 19 | storyIDParam := c.Param("story_id") 20 | storyID, err := strconv.Atoi(storyIDParam) 21 | if err != nil { 22 | c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid story ID"}) 23 | return 24 | } 25 | 26 | activityLogs, err := ctrl.Service.GetActivityLogsByStoryID(uint(storyID)) 27 | if err != nil { 28 | c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to fetch activity logs"}) 29 | return 30 | } 31 | 32 | c.JSON(http.StatusOK, activityLogs) 33 | } 34 | -------------------------------------------------------------------------------- /app/controllers/execution_controller.go: -------------------------------------------------------------------------------- 1 | package controllers 2 | 3 | import ( 4 | "ai-developer/app/services" 5 | ) 6 | 7 | type ExecutionController struct { 8 | Service *services.ExecutionService 9 | } 10 | 11 | func NewExecutionController(service *services.ExecutionService) *ExecutionController { 12 | return &ExecutionController{Service: service} 13 | } 14 | -------------------------------------------------------------------------------- /app/controllers/execution_output_controller.go: -------------------------------------------------------------------------------- 1 | package controllers 2 | 3 | import ( 4 | "ai-developer/app/services" 5 | "github.com/gin-gonic/gin" 6 | "net/http" 7 | "strconv" 8 | ) 9 | 10 | type ExecutionOutputController struct { 11 | Service *services.ExecutionOutputService 12 | } 13 | 14 | func NewExecutionOutputController(service *services.ExecutionOutputService) *ExecutionOutputController { 15 | return &ExecutionOutputController{Service: service} 16 | } 17 | 18 | func (ctrl *ExecutionOutputController) GetExecutionOutputsByStoryID(c *gin.Context) { 19 | storyIDParam := c.Param("story_id") 20 | storyID, err := strconv.Atoi(storyIDParam) 21 | if err != nil { 22 | c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid story ID"}) 23 | return 24 | } 25 | 26 | executionOutputs, err := ctrl.Service.GetExecutionOutputsByStoryID(uint(storyID)) 27 | if err != nil { 28 | c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) 29 | return 30 | } 31 | 32 | c.JSON(http.StatusOK, executionOutputs) 33 | } 34 | -------------------------------------------------------------------------------- /app/controllers/health.go: -------------------------------------------------------------------------------- 1 | package controllers 2 | 3 | import ( 4 | "github.com/gin-gonic/gin" 5 | "net/http" 6 | ) 7 | 8 | type HealthController struct { 9 | } 10 | 11 | func NewHealth() *HealthController { 12 | return &HealthController{} 13 | } 14 | 15 | func (h *HealthController) Health(c *gin.Context) { 16 | c.JSON(http.StatusOK, gin.H{"status": "OK"}) 17 | } 18 | -------------------------------------------------------------------------------- /app/controllers/pull_request_comments_controller.go: -------------------------------------------------------------------------------- 1 | package controllers 2 | 3 | import ( 4 | "ai-developer/app/services" 5 | "ai-developer/app/types/request" 6 | "github.com/gin-gonic/gin" 7 | "net/http" 8 | ) 9 | 10 | type PullRequestCommentsController struct { 11 | pullRequestCommentService *services.PullRequestCommentsService 12 | } 13 | 14 | func NewPullRequestCommentController(pullRequestCommentService *services.PullRequestCommentsService) *PullRequestCommentsController { 15 | return &PullRequestCommentsController{ 16 | pullRequestCommentService: pullRequestCommentService, 17 | } 18 | } 19 | 20 | func (ctrl *PullRequestCommentsController) CreateCommentForPrID(c *gin.Context) { 21 | var createCommentRequest request.CreateCommentRequest 22 | if err := c.ShouldBindJSON(&createCommentRequest); err != nil { 23 | c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) 24 | return 25 | } 26 | err := ctrl.pullRequestCommentService.CreateComment(createCommentRequest.PullRequestID, createCommentRequest.Comment) 27 | if err != nil { 28 | c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) 29 | return 30 | } 31 | c.JSON(http.StatusOK, gin.H{"status": "OK"}) 32 | return 33 | } 34 | -------------------------------------------------------------------------------- /app/controllers/user_controller.go: -------------------------------------------------------------------------------- 1 | package controllers 2 | 3 | import ( 4 | "ai-developer/app/models" 5 | "ai-developer/app/types/response" 6 | "github.com/gin-gonic/gin" 7 | "go.uber.org/zap" 8 | "net/http" 9 | ) 10 | 11 | type UserController struct { 12 | logger *zap.Logger 13 | } 14 | 15 | func (controller *UserController) GetUserDetails(c *gin.Context) { 16 | userInterface, exists := c.Get("user") 17 | if !exists { 18 | c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{"error": "Unauthorized"}) 19 | return 20 | } 21 | 22 | user, exists := userInterface.(*models.User) 23 | if !exists { 24 | c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{"error": "Unauthorized"}) 25 | return 26 | } 27 | 28 | userDetails := &response.UserResponse{ 29 | Id: user.ID, 30 | Email: user.Email, 31 | Name: user.Name, 32 | OrganisationID: user.OrganisationID, 33 | } 34 | c.JSON(http.StatusOK, userDetails) 35 | } 36 | 37 | func NewUserController(logger *zap.Logger) *UserController { 38 | return &UserController{ 39 | logger: logger.Named("UserController"), 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /app/db/migrations/000001_create_users_table.down.sql: -------------------------------------------------------------------------------- 1 | DROP INDEX IF EXISTS idx_users_email; 2 | 3 | DROP TABLE IF EXISTS users; 4 | -------------------------------------------------------------------------------- /app/db/migrations/000001_create_users_table.up.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE users ( 2 | id SERIAL PRIMARY KEY, 3 | name VARCHAR(100) NOT NULL, 4 | email VARCHAR(100) UNIQUE NOT NULL, 5 | password VARCHAR(100) NOT NULL, 6 | organisation_id INT NOT NULL, 7 | created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP, 8 | updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP 9 | ); 10 | 11 | CREATE INDEX idx_users_organisation_id ON users(organisation_id); 12 | 13 | -------------------------------------------------------------------------------- /app/db/migrations/000002_create_organisations_table.down.sql: -------------------------------------------------------------------------------- 1 | DROP TABLE IF EXISTS organisations; 2 | -------------------------------------------------------------------------------- /app/db/migrations/000002_create_organisations_table.up.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE organisations ( 2 | id SERIAL PRIMARY KEY, 3 | name VARCHAR(100) NOT NULL, 4 | description TEXT, 5 | created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP, 6 | updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP 7 | ); 8 | -------------------------------------------------------------------------------- /app/db/migrations/000003_create_projects_table.down.sql: -------------------------------------------------------------------------------- 1 | DROP TABLE IF EXISTS projects; 2 | -------------------------------------------------------------------------------- /app/db/migrations/000003_create_projects_table.up.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE projects ( 2 | id SERIAL PRIMARY KEY, 3 | name VARCHAR(100) NOT NULL, 4 | framework VARCHAR(100) NOT NULL, 5 | description TEXT, 6 | organisation_id INT NOT NULL, 7 | created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP, 8 | updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP 9 | ); 10 | -------------------------------------------------------------------------------- /app/db/migrations/000004_create_stories_table.down.sql: -------------------------------------------------------------------------------- 1 | DROP TABLE IF EXISTS stories; 2 | -------------------------------------------------------------------------------- /app/db/migrations/000004_create_stories_table.up.sql: -------------------------------------------------------------------------------- 1 | -- up.sql 2 | CREATE TABLE stories ( 3 | id SERIAL PRIMARY KEY, 4 | project_id INTEGER NOT NULL, 5 | title VARCHAR(100) NOT NULL, 6 | description TEXT, 7 | status VARCHAR(50), 8 | created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP, 9 | updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP 10 | ); 11 | 12 | CREATE INDEX idx_stories_project_id ON stories(project_id); 13 | 14 | -------------------------------------------------------------------------------- /app/db/migrations/000005_create_story_files_table.down.sql: -------------------------------------------------------------------------------- 1 | DROP TABLE IF EXISTS story_files; 2 | -------------------------------------------------------------------------------- /app/db/migrations/000005_create_story_files_table.up.sql: -------------------------------------------------------------------------------- 1 | -- up.sql 2 | CREATE TABLE story_files ( 3 | id SERIAL PRIMARY KEY, 4 | story_id INTEGER NOT NULL, 5 | name VARCHAR(100) NOT NULL, 6 | file_path TEXT NOT NULL, 7 | created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP, 8 | updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP 9 | ); 10 | -------------------------------------------------------------------------------- /app/db/migrations/000006_create_story_instructions_table.down.sql: -------------------------------------------------------------------------------- 1 | DROP TABLE IF EXISTS story_instructions; 2 | -------------------------------------------------------------------------------- /app/db/migrations/000006_create_story_instructions_table.up.sql: -------------------------------------------------------------------------------- 1 | -- up.sql 2 | CREATE TABLE story_instructions ( 3 | id SERIAL PRIMARY KEY, 4 | story_id INTEGER NOT NULL, 5 | instruction TEXT NOT NULL, 6 | created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP, 7 | updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP 8 | ); 9 | 10 | CREATE INDEX idx_instructions_story_id ON story_instructions(story_id); 11 | -------------------------------------------------------------------------------- /app/db/migrations/000007_create_story_test_cases_table.down.sql: -------------------------------------------------------------------------------- 1 | DROP TABLE IF EXISTS story_test_cases; -------------------------------------------------------------------------------- /app/db/migrations/000007_create_story_test_cases_table.up.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE story_test_cases ( 2 | id SERIAL PRIMARY KEY, 3 | story_id INT NOT NULL, 4 | test_case TEXT NOT NULL, 5 | created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP, 6 | updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP 7 | ); 8 | 9 | CREATE INDEX idx_test_cases_story_id ON story_test_cases(story_id); 10 | -------------------------------------------------------------------------------- /app/db/migrations/000008_create_executions_table.down.sql: -------------------------------------------------------------------------------- 1 | DROP TABLE IF EXISTS executions; 2 | -------------------------------------------------------------------------------- /app/db/migrations/000008_create_executions_table.up.sql: -------------------------------------------------------------------------------- 1 | -- up.sql 2 | CREATE TABLE executions ( 3 | id SERIAL PRIMARY KEY, 4 | story_id INTEGER NOT NULL, 5 | plan TEXT, 6 | status VARCHAR(100) NOT NULL, 7 | branch_name VARCHAR(100) NOT NULL, 8 | git_commit_id VARCHAR(100), 9 | instruction TEXT NOT NULL, 10 | created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP, 11 | updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP 12 | ); 13 | -------------------------------------------------------------------------------- /app/db/migrations/000009_create_execution_steps_table.down.sql: -------------------------------------------------------------------------------- 1 | DROP TABLE IF EXISTS execution_steps; 2 | -------------------------------------------------------------------------------- /app/db/migrations/000009_create_execution_steps_table.up.sql: -------------------------------------------------------------------------------- 1 | -- up.sql 2 | CREATE TABLE execution_steps ( 3 | id SERIAL PRIMARY KEY, 4 | execution_id INTEGER NOT NULL, 5 | name VARCHAR(100) NOT NULL, 6 | type VARCHAR(50) NOT NULL, 7 | request JSONB, 8 | response JSONB, 9 | status VARCHAR(50) NOT NULL, 10 | created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP, 11 | updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP 12 | ); 13 | -------------------------------------------------------------------------------- /app/db/migrations/000010_create_execution_outputs_table.down.sql: -------------------------------------------------------------------------------- 1 | DROP TABLE IF EXISTS execution_outputs; 2 | -------------------------------------------------------------------------------- /app/db/migrations/000010_create_execution_outputs_table.up.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE execution_outputs ( 2 | id SERIAL PRIMARY KEY, 3 | execution_id INT NOT NULL, 4 | pull_request_title VARCHAR(255) NOT NULL, 5 | pull_request_description TEXT NOT NULL, 6 | pull_request_id VARCHAR(100) NOT NULL, 7 | source_sha VARCHAR(100), 8 | merge_target_sha VARCHAR(100), 9 | merge_base_sha VARCHAR(100), 10 | remote_type VARCHAR(50) NOT NULL, 11 | created_at TIMESTAMP WITH TIME ZONE DEFAULT (CURRENT_TIMESTAMP AT TIME ZONE 'UTC'), 12 | updated_at TIMESTAMP WITH TIME ZONE DEFAULT (CURRENT_TIMESTAMP AT TIME ZONE 'UTC') 13 | ); 14 | -------------------------------------------------------------------------------- /app/db/migrations/000011_create_activity_logs_table.down.sql: -------------------------------------------------------------------------------- 1 | DROP INDEX IF EXISTS idx_activity_logs_type; 2 | 3 | DROP TABLE IF EXISTS activity_logs; 4 | -------------------------------------------------------------------------------- /app/db/migrations/000011_create_activity_logs_table.up.sql: -------------------------------------------------------------------------------- 1 | -- up.sql 2 | CREATE TABLE activity_logs ( 3 | id SERIAL PRIMARY KEY, 4 | execution_id INTEGER NOT NULL, 5 | execution_step_id INTEGER NOT NULL, 6 | log_message TEXT NOT NULL, 7 | type VARCHAR(50) NOT NULL, 8 | created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP, 9 | updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP 10 | ); 11 | 12 | CREATE INDEX idx_activity_logs_type ON activity_logs(type); 13 | -------------------------------------------------------------------------------- /app/db/migrations/000012_create_execution_files_table.down.sql: -------------------------------------------------------------------------------- 1 | DROP TABLE IF EXISTS execution_files; 2 | -------------------------------------------------------------------------------- /app/db/migrations/000012_create_execution_files_table.up.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE execution_files ( 2 | id SERIAL PRIMARY KEY, 3 | execution_id INT NOT NULL, 4 | execution_step_id INT NOT NULL, 5 | file_path TEXT NOT NULL, 6 | created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP, 7 | updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP 8 | ); 9 | -------------------------------------------------------------------------------- /app/db/migrations/000013_add_reexecution_to_executions.down.sql: -------------------------------------------------------------------------------- 1 | ALTER TABLE executions DROP COLUMN re_execution; 2 | -------------------------------------------------------------------------------- /app/db/migrations/000013_add_reexecution_to_executions.up.sql: -------------------------------------------------------------------------------- 1 | ALTER TABLE executions ADD COLUMN re_execution BOOLEAN DEFAULT FALSE NOT NULL; 2 | UPDATE executions SET re_execution = FALSE WHERE re_execution IS NULL; 3 | -------------------------------------------------------------------------------- /app/db/migrations/000014_alter_execution_output_table.down.sql: -------------------------------------------------------------------------------- 1 | ALTER TABLE execution_outputs 2 | ADD COLUMN pull_request_title VARCHAR(255) NOT NULL, 3 | ADD COLUMN pull_request_description TEXT NOT NULL, 4 | ADD COLUMN pull_request_id VARCHAR(100) NOT NULL, 5 | ADD COLUMN source_sha VARCHAR(100), 6 | ADD COLUMN merge_target_sha VARCHAR(100), 7 | ADD COLUMN merge_base_sha VARCHAR(100), 8 | ADD COLUMN remote_type VARCHAR(50) NOT NULL; -------------------------------------------------------------------------------- /app/db/migrations/000014_alter_execution_output_table.up.sql: -------------------------------------------------------------------------------- 1 | ALTER TABLE execution_outputs 2 | DROP COLUMN pull_request_title, 3 | DROP COLUMN pull_request_description, 4 | DROP COLUMN source_sha, 5 | DROP COLUMN merge_target_sha, 6 | DROP COLUMN merge_base_sha, 7 | DROP COLUMN remote_type, 8 | ALTER COLUMN pull_request_id TYPE INT USING pull_request_id::INT; -------------------------------------------------------------------------------- /app/db/migrations/000015_create_pull_request_table.down.sql: -------------------------------------------------------------------------------- 1 | DROP TABLE pull_requests; 2 | -------------------------------------------------------------------------------- /app/db/migrations/000016_create_pull_request_comments_table.down.sql: -------------------------------------------------------------------------------- 1 | DROP TABLE pull_request_comments; 2 | -------------------------------------------------------------------------------- /app/db/migrations/000016_create_pull_request_comments_table.up.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE pull_request_comments ( 2 | id SERIAL PRIMARY KEY, 3 | story_id INT NOT NULL, 4 | pull_request_id INT NOT NULL, 5 | comment VARCHAR(255) NOT NULL, 6 | created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP, 7 | updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP 8 | ); 9 | 10 | CREATE INDEX idx_pull_requests_id_comments ON pull_request_comments(pull_request_id); 11 | -------------------------------------------------------------------------------- /app/db/migrations/000017_remove_pull_req_exec_output.down.sql: -------------------------------------------------------------------------------- 1 | ALTER TABLE execution_outputs ADD COLUMN pull_request_id INTEGER NOT NULL; -------------------------------------------------------------------------------- /app/db/migrations/000017_remove_pull_req_exec_output.up.sql: -------------------------------------------------------------------------------- 1 | ALTER TABLE execution_outputs DROP COLUMN pull_request_id; 2 | -------------------------------------------------------------------------------- /app/db/migrations/000018_add_is_deleted_column_story.down.sql: -------------------------------------------------------------------------------- 1 | ALTER TABLE stories 2 | DROP COLUMN is_deleted; -------------------------------------------------------------------------------- /app/db/migrations/000018_add_is_deleted_column_story.up.sql: -------------------------------------------------------------------------------- 1 | ALTER TABLE stories 2 | ADD COLUMN is_deleted BOOLEAN; -------------------------------------------------------------------------------- /app/db/migrations/000019_remove_pull_req_exec_output.down.sql: -------------------------------------------------------------------------------- 1 | -- +migrate Down 2 | ALTER TABLE projects DROP COLUMN backend_url; 3 | ALTER TABLE projects DROP COLUMN frontend_url; 4 | ALTER TABLE projects DROP COLUMN url; 5 | ALTER TABLE projects DROP COLUMN hash_id; -------------------------------------------------------------------------------- /app/db/migrations/000019_remove_pull_req_exec_output.up.sql: -------------------------------------------------------------------------------- 1 | -- +migrate Up 2 | ALTER TABLE projects ADD COLUMN hash_id VARCHAR(100) NOT NULL UNIQUE; 3 | ALTER TABLE projects ADD COLUMN url VARCHAR(100); 4 | ALTER TABLE projects ADD COLUMN frontend_url VARCHAR(100); 5 | ALTER TABLE projects ADD COLUMN backend_url VARCHAR(100); 6 | -------------------------------------------------------------------------------- /app/db/migrations/000020_comment_data_type_change.down.sql: -------------------------------------------------------------------------------- 1 | ALTER TABLE pull_request_comments 2 | ALTER COLUMN comment TYPE VARCHAR(255); -------------------------------------------------------------------------------- /app/db/migrations/000020_comment_data_type_change.up.sql: -------------------------------------------------------------------------------- 1 | ALTER TABLE pull_request_comments 2 | ALTER COLUMN comment TYPE TEXT; -------------------------------------------------------------------------------- /app/db/migrations/000021_llm_api_keys.down.sql: -------------------------------------------------------------------------------- 1 | DROP TABLE IF EXISTS llm_api_keys; -------------------------------------------------------------------------------- /app/db/migrations/000021_llm_api_keys.up.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE llm_api_keys ( 2 | id SERIAL PRIMARY KEY, 3 | organisation_id INT NOT NULL, 4 | llm_model VARCHAR(100), 5 | llm_api_key VARCHAR(100) NOT NULL 6 | ); 7 | 8 | CREATE INDEX idx_llm_model ON llm_api_keys(llm_model); -------------------------------------------------------------------------------- /app/db/migrations/000022_add_supercoder_user_and_org.down.sql: -------------------------------------------------------------------------------- 1 | DELETE FROM users WHERE id = 1; 2 | DELETE FROM organisations WHERE id = 1; 3 | -------------------------------------------------------------------------------- /app/db/migrations/000022_add_supercoder_user_and_org.up.sql: -------------------------------------------------------------------------------- 1 | INSERT INTO organisations (id, name) VALUES (1, 'SuperCoderOrg'); 2 | INSERT INTO users (id, name, email, password, organisation_id, created_at, updated_at) 3 | VALUES (1, 'SuperCoderUser', 'supercoder@superagi.com', 'password', 1, NOW(), NOW()); -------------------------------------------------------------------------------- /app/db/migrations/000023_remove_supercoder_user_and_org.down.sql: -------------------------------------------------------------------------------- 1 | INSERT INTO organisations (id, name) VALUES (1, 'SuperCoderOrg'); 2 | INSERT INTO users (id, name, email, password, organisation_id, created_at, updated_at) 3 | VALUES (1, 'SuperCoderUser', 'supercoder@superagi.com', 'password', 1, NOW(), NOW()); -------------------------------------------------------------------------------- /app/db/migrations/000023_remove_supercoder_user_and_org.up.sql: -------------------------------------------------------------------------------- 1 | DELETE FROM users WHERE id = 1; 2 | DELETE FROM organisations WHERE id = 1; -------------------------------------------------------------------------------- /app/db/migrations/000024_alter_stories_table.down.sql: -------------------------------------------------------------------------------- 1 | ALTER TABLE stories 2 | DROP COLUMN frontend_url, 3 | DROP COLUMN url, 4 | DROP COLUMN hash_id, 5 | DROP COLUMN review_viewed; -------------------------------------------------------------------------------- /app/db/migrations/000024_alter_stories_table.up.sql: -------------------------------------------------------------------------------- 1 | ALTER TABLE stories 2 | ADD COLUMN hash_id VARCHAR(100), 3 | ADD COLUMN url VARCHAR(100), 4 | ADD COLUMN frontend_url VARCHAR(255), 5 | ADD COLUMN review_viewed BOOLEAN DEFAULT FALSE; -------------------------------------------------------------------------------- /app/db/migrations/000025_create_design_story_review_table.down.sql: -------------------------------------------------------------------------------- 1 | DROP TABLE design_story_reviews; -------------------------------------------------------------------------------- /app/db/migrations/000025_create_design_story_review_table.up.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE design_story_reviews ( 2 | id SERIAL PRIMARY KEY, 3 | story_id INT NOT NULL, 4 | comment TEXT NOT NULL, 5 | created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP, 6 | updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP 7 | ); 8 | 9 | CREATE INDEX idx_design_story_review_comments ON design_story_reviews(story_id); -------------------------------------------------------------------------------- /app/db/migrations/000026_update_api_key_length.down.sql: -------------------------------------------------------------------------------- 1 | ALTER TABLE llm_api_keys ALTER COLUMN llm_api_key TYPE VARCHAR(100); -------------------------------------------------------------------------------- /app/db/migrations/000026_update_api_key_length.up.sql: -------------------------------------------------------------------------------- 1 | ALTER TABLE llm_api_keys ALTER COLUMN llm_api_key TYPE VARCHAR(255); -------------------------------------------------------------------------------- /app/db/migrations/000027_add_frontend_framework_to_project.down.sql: -------------------------------------------------------------------------------- 1 | ALTER TABLE projects 2 | DROP COLUMN frontend_framework; 3 | -------------------------------------------------------------------------------- /app/db/migrations/000027_add_frontend_framework_to_project.up.sql: -------------------------------------------------------------------------------- 1 | -- Add the frontend_framework column without a default value 2 | ALTER TABLE projects 3 | ADD COLUMN frontend_framework VARCHAR(100); 4 | 5 | -- Update existing records to set frontend_framework to 'nextjs' 6 | UPDATE projects 7 | SET frontend_framework = 'nextjs' 8 | WHERE frontend_framework IS NULL; 9 | 10 | -- Alter the column to set NOT NULL constraint 11 | ALTER TABLE projects 12 | ALTER COLUMN frontend_framework SET NOT NULL; 13 | -------------------------------------------------------------------------------- /app/db/migrations/000028_add_type_in_story.down.sql: -------------------------------------------------------------------------------- 1 | ALTER TABLE stories 2 | DROP COLUMN "type"; 3 | -------------------------------------------------------------------------------- /app/db/migrations/000028_add_type_in_story.up.sql: -------------------------------------------------------------------------------- 1 | -- Add the pr_type column without a default value 2 | ALTER TABLE stories 3 | ADD COLUMN "type" VARCHAR(50); 4 | 5 | -- Update existing records to set pr_type to 'automated' 6 | UPDATE stories 7 | SET "type" = 'backend' 8 | WHERE "type" IS NULL; 9 | 10 | -- Alter the column to set NOT NULL constraint 11 | ALTER TABLE stories 12 | ALTER COLUMN "type" SET NOT NULL; 13 | -------------------------------------------------------------------------------- /app/db/migrations/000029_add_prtype_in_pull_requests_table.down.sql: -------------------------------------------------------------------------------- 1 | ALTER TABLE pull_requests 2 | DROP COLUMN pr_type; 3 | -------------------------------------------------------------------------------- /app/db/migrations/000029_add_prtype_in_pull_requests_table.up.sql: -------------------------------------------------------------------------------- 1 | -- Add the pr_type column without a default value 2 | ALTER TABLE pull_requests 3 | ADD COLUMN pr_type VARCHAR(50); 4 | 5 | -- Update existing records to set pr_type to 'automated' 6 | UPDATE pull_requests 7 | SET pr_type = 'automated' 8 | WHERE pr_type IS NULL; 9 | 10 | -- Alter the column to set NOT NULL constraint 11 | ALTER TABLE pull_requests 12 | ALTER COLUMN pr_type SET NOT NULL; 13 | -------------------------------------------------------------------------------- /app/db/migrations/000030_inc_length_story_table.down.sql: -------------------------------------------------------------------------------- 1 | ALTER TABLE stories 2 | ALTER COLUMN url TYPE VARCHAR(100); 3 | 4 | ALTER TABLE stories 5 | ALTER COLUMN frontend_url TYPE VARCHAR(255); -------------------------------------------------------------------------------- /app/db/migrations/000030_inc_length_story_table.up.sql: -------------------------------------------------------------------------------- 1 | ALTER TABLE stories 2 | ALTER COLUMN url TYPE VARCHAR(500); 3 | 4 | ALTER TABLE stories 5 | ALTER COLUMN frontend_url TYPE VARCHAR(500); -------------------------------------------------------------------------------- /app/db/migrations/000031_rename_framework_in_projects.down.sql: -------------------------------------------------------------------------------- 1 | -- Rename BackendFramework back to Framework 2 | ALTER TABLE projects 3 | RENAME COLUMN backend_framework TO framework; -------------------------------------------------------------------------------- /app/db/migrations/000031_rename_framework_in_projects.up.sql: -------------------------------------------------------------------------------- 1 | -- Rename Framework to BackendFramework 2 | ALTER TABLE projects 3 | RENAME COLUMN framework TO backend_framework; -------------------------------------------------------------------------------- /app/gateways/websocket.go: -------------------------------------------------------------------------------- 1 | package gateways 2 | 3 | import ( 4 | socketio "github.com/googollee/go-socket.io" 5 | "go.uber.org/zap" 6 | ) 7 | 8 | func NewSocketIOServer( 9 | workspaceGateway *WorkspaceGateway, 10 | logger *zap.Logger, 11 | ) *socketio.Server { 12 | server := socketio.NewServer(nil) 13 | logger.Named("SocketIO") 14 | server.OnConnect("/", workspaceGateway.OnConnect) 15 | server.OnEvent("/", "workspace-start", workspaceGateway.OnWorkspaceStartEvent) 16 | server.OnEvent("/", "workspace-close", workspaceGateway.OnWorkspaceDeleteEvent) 17 | server.OnDisconnect("/", workspaceGateway.OnDisconnect) 18 | server.OnError("/", func(s socketio.Conn, e error) { 19 | logger.Error("Error in websocket connection", zap.Error(e)) 20 | }) 21 | 22 | return server 23 | } 24 | -------------------------------------------------------------------------------- /app/middleware/user_authorization.go: -------------------------------------------------------------------------------- 1 | package middleware 2 | 3 | import ( 4 | "github.com/gin-gonic/gin" 5 | "go.uber.org/zap" 6 | "strconv" 7 | ) 8 | 9 | type UserAuthorizationMiddleware struct { 10 | logger *zap.Logger 11 | } 12 | 13 | func (middleware *UserAuthorizationMiddleware) Authorize() gin.HandlerFunc { 14 | return func(c *gin.Context) { 15 | authUserId := c.GetUint("user_id") 16 | if authUserId == 0 { 17 | c.AbortWithStatusJSON(401, gin.H{"error": "Unauthorized"}) 18 | return 19 | } 20 | userId, err := strconv.ParseUint(c.Param("userId"), 10, 64) 21 | if err != nil { 22 | c.AbortWithStatusJSON(400, gin.H{"error": "Invalid user ID"}) 23 | return 24 | } 25 | if uint(userId) != authUserId { 26 | c.AbortWithStatusJSON(401, gin.H{"error": "Unauthorized"}) 27 | return 28 | } 29 | } 30 | } 31 | 32 | func NewUserAuthorizationMiddleware(logger *zap.Logger) *UserAuthorizationMiddleware { 33 | return &UserAuthorizationMiddleware{ 34 | logger: logger.Named("UserAuthorizationMiddleware"), 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /app/models/activity_log.go: -------------------------------------------------------------------------------- 1 | package models 2 | 3 | import ( 4 | "time" 5 | ) 6 | 7 | type ActivityLog struct { 8 | ID uint `gorm:"primaryKey"` 9 | ExecutionID uint `gorm:"not null"` 10 | ExecutionStepID uint `gorm:"not null"` 11 | LogMessage string `gorm:"type:text;not null"` 12 | Type string `gorm:"type:varchar(50);not null"` // INFO, ERROR, WARNING, DEBUG 13 | CreatedAt time.Time `gorm:"autoCreateTime"` 14 | UpdatedAt time.Time `gorm:"autoUpdateTime"` 15 | } 16 | 17 | type ActivityLogResponse struct { 18 | Logs []ActivityLog 19 | Status string 20 | } 21 | -------------------------------------------------------------------------------- /app/models/design_story_review.go: -------------------------------------------------------------------------------- 1 | package models 2 | 3 | import ( 4 | "time" 5 | ) 6 | 7 | type DesignStoryReview struct { 8 | ID uint `gorm:"primaryKey"` 9 | StoryID uint `gorm:"not null"` 10 | Comment string `gorm:"type:text"` 11 | CreatedAt time.Time `gorm:"autoCreateTime"` 12 | UpdatedAt time.Time `gorm:"autoUpdateTime"` 13 | } 14 | -------------------------------------------------------------------------------- /app/models/dtos/asynq_task/create_job_payload.go: -------------------------------------------------------------------------------- 1 | package asynq_task 2 | 3 | type CreateJobPayload struct { 4 | StoryID uint 5 | ReExecute bool 6 | PullRequestId uint 7 | } 8 | -------------------------------------------------------------------------------- /app/models/dtos/asynq_task/delete_workspace_task.go: -------------------------------------------------------------------------------- 1 | package asynq_task 2 | 3 | type CreateDeleteWorkspaceTaskPayload struct { 4 | WorkspaceID string `json:"workspace_id"` 5 | } 6 | -------------------------------------------------------------------------------- /app/models/dtos/llm_api_key/llm_api_key_return.go: -------------------------------------------------------------------------------- 1 | package llm_api_key 2 | 3 | type LLMAPIKeyReturn struct { 4 | ModelName string `json:"model_name"` 5 | APIKey string `json:"api_key"` 6 | } 7 | -------------------------------------------------------------------------------- /app/models/execution.go: -------------------------------------------------------------------------------- 1 | package models 2 | 3 | import ( 4 | "time" 5 | ) 6 | 7 | type Execution struct { 8 | ID uint `gorm:"primaryKey"` 9 | StoryID uint `gorm:"not null"` 10 | Plan string `gorm:"type:text"` 11 | Status string `gorm:"type:varchar(100);not null"` 12 | BranchName string `gorm:"type:varchar(100);not null"` 13 | GitCommitID string `gorm:"type:varchar(100)"` 14 | Instruction string `gorm:"type:text;not null"` 15 | ReExecution bool `gorm:"default:false"` 16 | CreatedAt time.Time `gorm:"autoCreateTime"` 17 | UpdatedAt time.Time `gorm:"autoUpdateTime"` 18 | } 19 | -------------------------------------------------------------------------------- /app/models/execution_file.go: -------------------------------------------------------------------------------- 1 | package models 2 | 3 | import ( 4 | "time" 5 | ) 6 | 7 | type ExecutionFile struct { 8 | ID uint `gorm:"primaryKey"` 9 | ExecutionID uint `gorm:"not null"` 10 | ExecutionStepID uint `gorm:"not null"` 11 | FilePath string `gorm:"type:text;not null"` 12 | CreatedAt time.Time `gorm:"autoCreateTime"` 13 | UpdatedAt time.Time `gorm:"autoUpdateTime"` 14 | } 15 | -------------------------------------------------------------------------------- /app/models/execution_output.go: -------------------------------------------------------------------------------- 1 | package models 2 | 3 | import ( 4 | "time" 5 | ) 6 | 7 | type ExecutionOutput struct { 8 | ID uint `gorm:"primaryKey"` 9 | ExecutionID uint `gorm:"not null"` 10 | CreatedAt time.Time `gorm:"autoCreateTime"` 11 | UpdatedAt time.Time `gorm:"autoUpdateTime"` 12 | } 13 | -------------------------------------------------------------------------------- /app/models/execution_step.go: -------------------------------------------------------------------------------- 1 | package models 2 | 3 | import ( 4 | "ai-developer/app/models/types" 5 | "time" 6 | ) 7 | 8 | // ExecutionStep represents a step in the execution workflow. 9 | type ExecutionStep struct { 10 | ID uint `gorm:"primaryKey"` 11 | ExecutionID uint `gorm:"not null"` 12 | Name string `gorm:"type:varchar(100);not null"` // Name of the step (e.g. "GENERATE_CODE") 13 | Type string `gorm:"type:varchar(50);not null"` 14 | Request types.JSONMap `gorm:"type:json"` 15 | Response types.JSONMap `gorm:"type:json"` 16 | Status string `gorm:"type:varchar(50);not null"` // IN_PROGRESS, SUCCESS, FAILURE 17 | CreatedAt time.Time `gorm:"autoCreateTime"` 18 | UpdatedAt time.Time `gorm:"autoUpdateTime"` 19 | } 20 | -------------------------------------------------------------------------------- /app/models/llm_api_key.go: -------------------------------------------------------------------------------- 1 | package models 2 | 3 | type LLMAPIKey struct { 4 | ID uint `gorm:"primaryKey"` 5 | OrganisationID uint `gorm:"not null"` 6 | LLMModel string `gorm:"type:varchar(100)"` 7 | LLMAPIKey string `gorm:"type:varchar(255);not null"` 8 | } 9 | -------------------------------------------------------------------------------- /app/models/organisation.go: -------------------------------------------------------------------------------- 1 | package models 2 | 3 | import ( 4 | "time" 5 | ) 6 | 7 | type Organisation struct { 8 | ID uint `gorm:"primaryKey"` 9 | Name string `gorm:"type:varchar(100);not null"` 10 | Description string `gorm:"type:text"` 11 | CreatedAt time.Time `gorm:"autoCreateTime"` 12 | UpdatedAt time.Time `gorm:"autoUpdateTime"` 13 | } 14 | -------------------------------------------------------------------------------- /app/models/project.go: -------------------------------------------------------------------------------- 1 | package models 2 | 3 | import ( 4 | "time" 5 | ) 6 | 7 | type Project struct { 8 | ID uint `gorm:"primaryKey"` 9 | HashID string `gorm:"type:varchar(100);not null;unique"` 10 | Url string `gorm:"type:varchar(100)"` 11 | FrontendURL string `gorm:"type:varchar(100);"` 12 | BackendURL string `gorm:"type:varchar(100);"` 13 | Name string `gorm:"type:varchar(100);"` 14 | BackendFramework string `gorm:"type:varchar(100);not null"` 15 | FrontendFramework string `gorm:"type:varchar(100);not null"` 16 | Description string `gorm:"type:text"` 17 | OrganisationID uint `gorm:"not null"` 18 | CreatedAt time.Time `gorm:"autoCreateTime"` 19 | UpdatedAt time.Time `gorm:"autoUpdateTime"` 20 | } 21 | -------------------------------------------------------------------------------- /app/models/pull_request.go: -------------------------------------------------------------------------------- 1 | package models 2 | 3 | import ( 4 | "time" 5 | ) 6 | 7 | type PullRequest struct { 8 | ID uint `gorm:"primaryKey"` 9 | StoryID uint `gorm:"not null"` 10 | ExecutionOutputID uint `gorm:"null"` 11 | PullRequestTitle string `gorm:"type:varchar(255);not null"` 12 | PullRequestNumber int `gorm:"not null"` 13 | Status string `gorm:"type:varchar(255);not null"` 14 | PullRequestDescription string `gorm:"type:text;not null"` 15 | PullRequestID string `gorm:"type:varchar(100);not null"` 16 | SourceSHA string `gorm:"type:varchar(100)"` 17 | MergeTargetSHA string `gorm:"type:varchar(100)"` 18 | MergeBaseSHA string `gorm:"type:varchar(100)"` 19 | RemoteType string `gorm:"type:varchar(50);not null"` 20 | CreatedAt time.Time `gorm:"autoCreateTime"` 21 | UpdatedAt time.Time `gorm:"autoUpdateTime"` 22 | MergedAt time.Time `gorm:"autoUpdateTime"` 23 | ClosedAt time.Time `gorm:"autoUpdateTime"` 24 | PRType string `gorm:"type:varchar(50);not null"` 25 | } 26 | -------------------------------------------------------------------------------- /app/models/pull_request_comment.go: -------------------------------------------------------------------------------- 1 | package models 2 | 3 | import ( 4 | "time" 5 | ) 6 | 7 | type PullRequestComments struct { 8 | ID uint `gorm:"primaryKey"` 9 | StoryID uint `gorm:"not null"` 10 | PullRequestID uint `gorm:"not null"` 11 | Comment string `gorm:"type:varchar(255);not null"` 12 | CreatedAt time.Time `gorm:"autoCreateTime"` 13 | UpdatedAt time.Time `gorm:"autoUpdateTime"` 14 | } 15 | -------------------------------------------------------------------------------- /app/models/story.go: -------------------------------------------------------------------------------- 1 | package models 2 | 3 | import ( 4 | "time" 5 | ) 6 | 7 | type Story struct { 8 | ID uint `gorm:"primaryKey"` 9 | ProjectID uint `gorm:"not null"` 10 | Title string `gorm:"type:varchar(100);not null"` 11 | Description string `gorm:"type:text"` 12 | Status string `gorm:"type:varchar(50)"` 13 | IsDeleted bool `gorm:"default:false"` 14 | HashID string `gorm:"type:varchar(100);unique"` 15 | Url string `gorm:"type:varchar(500)"` 16 | FrontendURL string `gorm:"type:varchar(500)"` 17 | ReviewViewed bool `gorm:"default:false"` 18 | CreatedAt time.Time `gorm:"autoCreateTime"` 19 | UpdatedAt time.Time `gorm:"autoUpdateTime"` 20 | Type string `gorm:"type;not null"` 21 | } 22 | -------------------------------------------------------------------------------- /app/models/story_file.go: -------------------------------------------------------------------------------- 1 | package models 2 | 3 | import ( 4 | "time" 5 | ) 6 | 7 | type StoryFile struct { 8 | ID uint `gorm:"primaryKey"` 9 | StoryID uint `gorm:"not null"` 10 | Name string `gorm:"type:varchar(100);not null"` // Name of the file (e.g. "input.txt") Migration to be added 11 | FilePath string `gorm:"type:text;not null"` 12 | CreatedAt time.Time `gorm:"autoCreateTime"` 13 | UpdatedAt time.Time `gorm:"autoUpdateTime"` 14 | } 15 | -------------------------------------------------------------------------------- /app/models/story_instruction.go: -------------------------------------------------------------------------------- 1 | package models 2 | 3 | import ( 4 | "time" 5 | ) 6 | 7 | type StoryInstruction struct { 8 | ID uint `gorm:"primaryKey"` 9 | StoryID uint `gorm:"not null"` 10 | Instruction string `gorm:"type:text;not null"` 11 | CreatedAt time.Time `gorm:"autoCreateTime"` 12 | UpdatedAt time.Time `gorm:"autoUpdateTime"` 13 | } 14 | -------------------------------------------------------------------------------- /app/models/story_test_case.go: -------------------------------------------------------------------------------- 1 | package models 2 | 3 | import ( 4 | "time" 5 | ) 6 | 7 | type StoryTestCase struct { 8 | ID uint `gorm:"primaryKey"` 9 | StoryID uint `gorm:"not null"` 10 | TestCase string `gorm:"type:text;not null"` 11 | CreatedAt time.Time `gorm:"autoCreateTime"` 12 | UpdatedAt time.Time `gorm:"autoUpdateTime"` 13 | } 14 | -------------------------------------------------------------------------------- /app/models/types/errors.go: -------------------------------------------------------------------------------- 1 | package types 2 | 3 | import "errors" 4 | 5 | var ErrInvalidStatus = errors.New("invalid status") 6 | 7 | var ErrStoryDeleted = errors.New("story deleted") 8 | 9 | var ErrInvalidStory = errors.New("invalid story") 10 | 11 | var ErrInvalidStoryStatusTransition = errors.New("invalid story status transition") 12 | 13 | var ErrAnotherStoryAlreadyInProgress = errors.New("another story already in progress") 14 | -------------------------------------------------------------------------------- /app/models/types/json_map.go: -------------------------------------------------------------------------------- 1 | package types 2 | 3 | import ( 4 | "database/sql/driver" 5 | "encoding/json" 6 | "errors" 7 | ) 8 | 9 | // JSONMap is a custom type for handling JSON columns. 10 | type JSONMap map[string]interface{} 11 | 12 | // Value implements the driver.Valuer interface for JSONMap. 13 | func (j JSONMap) Value() (driver.Value, error) { 14 | value, err := json.Marshal(j) 15 | if err != nil { 16 | return nil, err 17 | } 18 | return value, nil 19 | } 20 | 21 | // Scan implements the sql.Scanner interface for JSONMap. 22 | func (j *JSONMap) Scan(value interface{}) error { 23 | bytes, ok := value.([]byte) 24 | if !ok { 25 | return errors.New("type assertion to []byte failed") 26 | } 27 | 28 | return json.Unmarshal(bytes, &j) 29 | } 30 | -------------------------------------------------------------------------------- /app/models/user.go: -------------------------------------------------------------------------------- 1 | package models 2 | 3 | import ( 4 | "time" 5 | ) 6 | 7 | type User struct { 8 | ID uint `gorm:"primaryKey"` 9 | Name string `gorm:"type:varchar(100);not null"` 10 | Email string `gorm:"type:varchar(100);uniqueIndex;not null"` 11 | Password string `gorm:"type:varchar(100);not null"` 12 | OrganisationID uint `gorm:"not null"` 13 | CreatedAt time.Time `gorm:"autoCreateTime"` 14 | UpdatedAt time.Time `gorm:"autoUpdateTime"` 15 | } 16 | -------------------------------------------------------------------------------- /app/repositories/design_story_review.go: -------------------------------------------------------------------------------- 1 | package repositories 2 | 3 | import ( 4 | "ai-developer/app/models" 5 | "gorm.io/gorm" 6 | ) 7 | 8 | type DesignStoryReviewRepository struct { 9 | db *gorm.DB 10 | } 11 | 12 | func NewDesignStoryReviewRepository(db *gorm.DB) *DesignStoryReviewRepository { 13 | return &DesignStoryReviewRepository{db: db} 14 | } 15 | 16 | func (r *DesignStoryReviewRepository) CreateDesignStoryReview(designStoryReview *models.DesignStoryReview) error { 17 | if err := r.db.Create(designStoryReview).Error; err != nil { 18 | return err 19 | } 20 | return nil 21 | } 22 | 23 | func (r *DesignStoryReviewRepository) GetAllDesignReviewsByStoryId(storyId uint) ([]*models.DesignStoryReview, error) { 24 | var designStoryReviews []*models.DesignStoryReview 25 | if err := r.db.Where("story_id = ?", storyId).Find(&designStoryReviews).Error; err != nil { 26 | return nil, err 27 | } 28 | return designStoryReviews, nil 29 | } 30 | -------------------------------------------------------------------------------- /app/repositories/options.go: -------------------------------------------------------------------------------- 1 | package repositories 2 | 3 | import "gorm.io/gorm" 4 | 5 | type RepositoryOption interface { 6 | applyRepositoryOption(*RepositoryOptions) 7 | } 8 | 9 | type RepositoryOptions struct { 10 | db gorm.DB 11 | page int 12 | limit int 13 | } 14 | 15 | type DBOption gorm.DB 16 | 17 | func (o DBOption) applyRepositoryOption(ro *RepositoryOptions) { 18 | ro.db = gorm.DB(o) 19 | } 20 | 21 | type PageOption int 22 | 23 | func (o PageOption) applyRepositoryOption(ro *RepositoryOptions) { 24 | ro.page = int(o) 25 | } 26 | 27 | type LimitOption int 28 | 29 | func (o LimitOption) applyRepositoryOption(ro *RepositoryOptions) { 30 | ro.limit = int(o) 31 | } 32 | 33 | func WithDB(db gorm.DB) DBOption { 34 | return DBOption(db) 35 | } 36 | 37 | func WithPage(page int) PageOption { 38 | return PageOption(page) 39 | } 40 | 41 | func WithLimit(limit int) LimitOption { 42 | return LimitOption(limit) 43 | } 44 | -------------------------------------------------------------------------------- /app/repositories/repository.go: -------------------------------------------------------------------------------- 1 | package repositories 2 | 3 | import "gorm.io/gorm" 4 | 5 | type Repository struct { 6 | db *gorm.DB 7 | } 8 | 9 | func (repo *Repository) getRepositoryOptions(options ...RepositoryOption) *RepositoryOptions { 10 | repositoryOptions := &RepositoryOptions{ 11 | db: *repo.db, 12 | page: 1, 13 | limit: 10, 14 | } 15 | for _, option := range options { 16 | option.applyRepositoryOption(repositoryOptions) 17 | } 18 | return repositoryOptions 19 | } 20 | -------------------------------------------------------------------------------- /app/services/auth/auth_provider.go: -------------------------------------------------------------------------------- 1 | package auth 2 | 3 | import ( 4 | "github.com/gin-gonic/gin" 5 | ) 6 | 7 | type AuthProvider interface { 8 | Authenticate(c *gin.Context) (interface{}, error) 9 | } 10 | -------------------------------------------------------------------------------- /app/services/filestore/filestore.go: -------------------------------------------------------------------------------- 1 | package filestore 2 | 3 | import "io" 4 | 5 | type FileStore interface { 6 | CreateFileFromContent(path string, content []byte) (err error) 7 | ReadFile(path string) (content io.ReadCloser, err error) 8 | ReadFileWithInfo(path string) (content io.ReadCloser, contentLength int64, contentType *string, err error) 9 | DeleteFile(path string) (err error) 10 | } 11 | -------------------------------------------------------------------------------- /app/services/git_providers/git_provider.go: -------------------------------------------------------------------------------- 1 | package git_providers 2 | 3 | import ( 4 | "ai-developer/app/models/dtos/gitness" 5 | ) 6 | 7 | type GitService interface { 8 | CreateProject(name, description string) (*gitness.Project, error) 9 | CreateRepository(projectName, repoName, description string) (*gitness.CreateRepositoryResponse, error) 10 | CreateBranch(projectName, repoName, branchName string) (*gitness.CreateBranchResponse, error) 11 | CreatePullRequest(projectName, repoName, sourceBranch, targetBranch, title, description string) (*gitness.CreatePullRequestResponse, error) 12 | MergePullRequest(projectName, repoName string, pullRequestID int, sourceSHA string) (*gitness.MergePullRequestResponse, error) 13 | FetchPullRequest(projectName, repoName string, pullRequestID int) (*gitness.FetchPullRequestResponse, error) 14 | } 15 | -------------------------------------------------------------------------------- /app/types/request/create_comment_request.go: -------------------------------------------------------------------------------- 1 | package request 2 | 3 | type CreateCommentRequest struct { 4 | PullRequestID uint `json:"pull_request_id"` 5 | Comment string `json:"comment"` 6 | } 7 | -------------------------------------------------------------------------------- /app/types/request/create_design_story_comment_request.go: -------------------------------------------------------------------------------- 1 | package request 2 | 3 | type CreateDesignStoryCommentRequest struct { 4 | StoryID uint `json:"story_id"` 5 | Comment string `json:"comment"` 6 | } 7 | -------------------------------------------------------------------------------- /app/types/request/create_pr_request.go: -------------------------------------------------------------------------------- 1 | package request 2 | 3 | type CreatePRFromCodeEditorRequest struct { 4 | ProjectID int `json:"project_id"` 5 | Title string `json:"title"` 6 | Description string `json:"description"` 7 | } -------------------------------------------------------------------------------- /app/types/request/create_project_request.go: -------------------------------------------------------------------------------- 1 | package request 2 | 3 | type CreateProjectRequest struct { 4 | Name string `json:"name"` 5 | Framework string `json:"framework"` 6 | FrontendFramework string `json:"frontend_framework"` 7 | Description string `json:"description"` 8 | } 9 | -------------------------------------------------------------------------------- /app/types/request/create_story_request.go: -------------------------------------------------------------------------------- 1 | package request 2 | 3 | type CreateStoryRequest struct { 4 | ProjectId int `json:"project_id"` 5 | Summary string `json:"summary"` 6 | Description string `json:"description"` 7 | TestCases []string `json:"test_cases"` 8 | Instructions string `json:"instructions"` 9 | } 10 | -------------------------------------------------------------------------------- /app/types/request/create_user_request.go: -------------------------------------------------------------------------------- 1 | package request 2 | 3 | type CreateUserRequest struct { 4 | Email string `json:"email"` 5 | Password string `json:"password"` 6 | } 7 | -------------------------------------------------------------------------------- /app/types/request/create_worspace_request.go: -------------------------------------------------------------------------------- 1 | package request 2 | 3 | type CreateWorkspaceRequest struct { 4 | StoryHashId string `json:"storyHashId"` 5 | WorkspaceId string `json:"workspaceId"` 6 | RemoteURL string `json:"remoteURL"` 7 | BackendTemplate *string `json:"backendTemplate,omitempty"` 8 | FrontendTemplate *string `json:"frontendTemplate,omitempty"` 9 | GitnessUserName string `json:"gitnessUserName"` 10 | GitnessToken string `json:"gitnessToken"` 11 | } 12 | 13 | func (receiver *CreateWorkspaceRequest) WithBackendTemplate(backendTemplate string) *CreateWorkspaceRequest { 14 | receiver.BackendTemplate = &backendTemplate 15 | return receiver 16 | } 17 | 18 | func (receiver *CreateWorkspaceRequest) WithFrontendTemplate(frontendTemplate string) *CreateWorkspaceRequest { 19 | receiver.FrontendTemplate = &frontendTemplate 20 | return receiver 21 | } 22 | 23 | func NewCreateWorkspaceRequest(workspaceId string) *CreateWorkspaceRequest { 24 | return &CreateWorkspaceRequest{ 25 | WorkspaceId: workspaceId, 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /app/types/request/delete_story_by_id.go: -------------------------------------------------------------------------------- 1 | package request 2 | 3 | type DeleteStoryByID struct { 4 | StoryID int `json:"story_id"` 5 | } 6 | -------------------------------------------------------------------------------- /app/types/request/llm_api_key_request.go: -------------------------------------------------------------------------------- 1 | package request 2 | 3 | type CreateLLMAPIKeyRequest struct { 4 | APIKeys []LLMAPIKey `json:"api_keys" binding:"required,dive,required"` 5 | } 6 | 7 | type LLMAPIKey struct { 8 | LLMModel string `json:"llm_model" binding:"required"` 9 | LLMAPIKey *string `json:"llm_api_key"` 10 | } 11 | -------------------------------------------------------------------------------- /app/types/request/merge_pull_request.go: -------------------------------------------------------------------------------- 1 | package request 2 | 3 | type MergePullRequest struct { 4 | PullRequestID int `json:"pull_request_id"` 5 | } 6 | -------------------------------------------------------------------------------- /app/types/request/retrieve_code_request.go: -------------------------------------------------------------------------------- 1 | package request 2 | 3 | type RetrieveCodeRequest struct { 4 | FileName string `json:"file_name"` 5 | ProjectID uint `json:"project_id"` 6 | StoryID uint `json:"story_id"` 7 | } -------------------------------------------------------------------------------- /app/types/request/update_project_request.go: -------------------------------------------------------------------------------- 1 | package request 2 | 3 | type UpdateProjectRequest struct { 4 | ProjectID int `json:"project_id"` 5 | Name string `json:"name"` 6 | Description string `json:"description"` 7 | } 8 | -------------------------------------------------------------------------------- /app/types/request/update_story_request.go: -------------------------------------------------------------------------------- 1 | package request 2 | 3 | type UpdateStoryRequest struct { 4 | StoryID int `json:"story_id"` 5 | Summary string `json:"summary"` 6 | Description string `json:"description"` 7 | TestCases []string `json:"test_cases"` 8 | Instructions string `json:"instructions"` 9 | } 10 | -------------------------------------------------------------------------------- /app/types/request/update_story_status_request.go: -------------------------------------------------------------------------------- 1 | package request 2 | 3 | type UpdateStoryStatusRequest struct { 4 | StoryId int `json:"story_id"` 5 | StoryStatus string `json:"story_status"` 6 | } 7 | -------------------------------------------------------------------------------- /app/types/request/user_signin_request.go: -------------------------------------------------------------------------------- 1 | package request 2 | 3 | type UserSignInRequest struct { 4 | Email string `json:"email"` 5 | Password string `json:"password"` 6 | } 7 | -------------------------------------------------------------------------------- /app/types/response/create_workspace_response.go: -------------------------------------------------------------------------------- 1 | package response 2 | 3 | type WorkspaceDetails struct { 4 | WorkspaceId string `json:"workspaceId"` 5 | BackendTemplate *string `json:"backendTemplate,omitempty"` 6 | FrontendTemplate *string `json:"frontendTemplate,omitempty"` 7 | WorkspaceUrl *string `json:"workspaceUrl,omitempty"` 8 | FrontendUrl *string `json:"frontendUrl,omitempty"` 9 | BackendUrl *string `json:"backendUrl,omitempty"` 10 | } 11 | 12 | type CreateWorkspaceResponse struct { 13 | Message string `json:"message"` 14 | WorkspaceDetails *WorkspaceDetails `json:"workspace"` 15 | } 16 | -------------------------------------------------------------------------------- /app/types/response/get_all_commits_response.go: -------------------------------------------------------------------------------- 1 | package response 2 | 3 | type GetAllCommitsResponse struct { 4 | Title string `json:"title"` 5 | Commiter string `json:"commiter"` 6 | SHA string `json:"sha"` 7 | Time string `json:"time"` 8 | Date string `json:"date"` 9 | } 10 | -------------------------------------------------------------------------------- /app/types/response/get_all_projects_response.go: -------------------------------------------------------------------------------- 1 | package response 2 | 3 | type GetAllProjectsResponse struct { 4 | ProjectId uint `json:"project_id"` 5 | ProjectName string `json:"project_name"` 6 | ProjectDescription string `json:"project_description"` 7 | ProjectFramework string `json:"project_framework"` 8 | ProjectFrontendFramework string `json:"project_frontend_framework"` 9 | ProjectHashID string `json:"project_hash_id"` 10 | ProjectUrl string `json:"project_url"` 11 | ProjectBackendURL string `json:"project_backend_url"` 12 | ProjectFrontendURL string `json:"project_frontend_url"` 13 | PullRequestCount int `json:"pull_request_count"` 14 | } 15 | -------------------------------------------------------------------------------- /app/types/response/get_all_pull_requests.go: -------------------------------------------------------------------------------- 1 | package response 2 | 3 | type GetAllPullRequests struct { 4 | PullRequestID int `json:"pull_request_id"` 5 | PullRequestDescription string `json:"pull_request_description"` 6 | PullRequestName string `json:"pull_request_name"` 7 | PullRequestNumber int `json:"pull_request_number"` 8 | CreatedOn string `json:"created_on"` 9 | TotalComments int64 `json:"total_comments"` 10 | Status string `json:"status"` 11 | MergedOn string `json:"merged_on"` 12 | ClosedOn string `json:"closed_on"` 13 | } 14 | -------------------------------------------------------------------------------- /app/types/response/get_all_stories_by_project_id.go: -------------------------------------------------------------------------------- 1 | package response 2 | 3 | type GetAllStoriesByProjectIDResponse struct { 4 | Todo []StoryData `json:"TODO"` 5 | InProgress []StoryData `json:"IN_PROGRESS"` 6 | Done []StoryData `json:"DONE"` 7 | InReview []StoryData `json:"IN_REVIEW"` 8 | } 9 | 10 | type StoryData struct { 11 | StoryID int `json:"story_id"` 12 | StoryName string `json:"story_name"` 13 | } 14 | -------------------------------------------------------------------------------- /app/types/response/get_code_for_design_story.go: -------------------------------------------------------------------------------- 1 | package response 2 | 3 | type GetCodeForDesignStory struct { 4 | FileName string `json:"file_name"` 5 | Code string `json:"code"` 6 | } 7 | -------------------------------------------------------------------------------- /app/types/response/get_design_stories_by_project_id.go: -------------------------------------------------------------------------------- 1 | package response 2 | 3 | type GetDesignStoriesOfProjectId struct { 4 | StoryID int `json:"id"` 5 | StoryName string `json:"title"` 6 | StoryInputFileURL string `json:"input_file_url"` 7 | StoryStatus string `json:"status"` 8 | Reason string `json:"reason"` 9 | CreatedAt string `json:"created_on"` 10 | ReviewViewed bool `json:"review_viewed"` 11 | FrontendURL string `json:"frontend_url"` 12 | } 13 | -------------------------------------------------------------------------------- /app/types/response/get_story_by_id_response.go: -------------------------------------------------------------------------------- 1 | package response 2 | 3 | type GetStoryByIdResponse struct { 4 | Overview StoryOverview `json:"overview"` 5 | TestCases []string `json:"test_cases"` 6 | Instructions []string `json:"instructions"` 7 | Status string `json:"status"` 8 | Reason string `json:"reason"` 9 | StoryInputFileUrl string `json:"story_input_file_url"` 10 | } 11 | 12 | type StoryOverview struct { 13 | Name string `json:"name"` 14 | Description string `json:"description"` 15 | } 16 | -------------------------------------------------------------------------------- /app/types/response/get_story_response.go: -------------------------------------------------------------------------------- 1 | package response 2 | 3 | type GetStoryResponse struct { 4 | StoryId int `json:"story_id"` 5 | StoryTitle string `json:"story_title"` 6 | } 7 | -------------------------------------------------------------------------------- /app/types/response/user_response.go: -------------------------------------------------------------------------------- 1 | package response 2 | 3 | type UserResponse struct { 4 | Id uint `json:"id"` 5 | Email string `json:"email"` 6 | Name string `json:"name"` 7 | OrganisationID uint `json:"organisation_id"` 8 | } 9 | -------------------------------------------------------------------------------- /app/utils/api_key.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import ( 4 | "errors" 5 | "github.com/gin-gonic/gin" 6 | "strings" 7 | ) 8 | 9 | // ExtractBearerToken extracts the bearer token from the request header. 10 | func ExtractBearerToken(c *gin.Context) (string, error) { 11 | tokenString := c.GetHeader("Authorization") 12 | if len(tokenString) > len("Bearer ") && strings.HasPrefix(tokenString, "Bearer ") { 13 | return tokenString[len("Bearer "):], nil 14 | } 15 | 16 | cookieHeader := c.Request.Header.Get("Cookie") 17 | accessToken := "" 18 | cookies := strings.Split(cookieHeader, "; ") 19 | for _, cookie := range cookies { 20 | parts := strings.SplitN(cookie, "=", 2) 21 | if len(parts) == 2 && parts[0] == "accessToken" { 22 | accessToken = parts[1] 23 | break 24 | } 25 | } 26 | 27 | if accessToken != "" { 28 | return accessToken, nil 29 | } 30 | 31 | return "", errors.New("Bearer token required") 32 | } 33 | -------------------------------------------------------------------------------- /app/utils/asynq_helper.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import ( 4 | "github.com/hibiken/asynq" 5 | "math" 6 | "time" 7 | ) 8 | 9 | func ExponentialBackoff(n int, e error, task *asynq.Task) time.Duration { 10 | return time.Duration(math.Pow(2, float64(n))) * time.Second 11 | } 12 | -------------------------------------------------------------------------------- /app/utils/command_helper.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "os/exec" 7 | ) 8 | 9 | func RunCommand(name string, dir string, arg ...string) error { 10 | fmt.Println("________________Running command_____________ : ", name, arg, dir) 11 | cmd := exec.Command(name, arg...) 12 | cmd.Dir = dir 13 | 14 | // Set the environment variables 15 | cmd.Env = append(os.Environ(), "PATH="+os.Getenv("PATH")) 16 | 17 | output, err := cmd.CombinedOutput() 18 | if err != nil { 19 | fmt.Println("Error running command: ", string(output)) 20 | return fmt.Errorf("failed to run command: %s", err) 21 | } 22 | fmt.Println("Command output: ", string(output)) 23 | return nil 24 | } 25 | -------------------------------------------------------------------------------- /app/utils/date_time_helper.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import ( 4 | "fmt" 5 | "time" 6 | ) 7 | 8 | func TimeAgo(commitTime, currentTime time.Time) string { 9 | duration := currentTime.Sub(commitTime) 10 | 11 | // Calculate total seconds 12 | totalSeconds := int(duration.Seconds()) 13 | if totalSeconds < 60 { 14 | if totalSeconds == 0 { 15 | totalSeconds = 1 16 | } 17 | return fmt.Sprintf("%ds ago", totalSeconds) 18 | } 19 | 20 | // Calculate total minutes 21 | totalMinutes := int(duration.Minutes()) 22 | if totalMinutes < 60 { 23 | if totalMinutes == 0 { 24 | totalMinutes = 1 25 | } 26 | return fmt.Sprintf("%dm ago", totalMinutes) 27 | } 28 | 29 | // Calculate total hours 30 | totalHours := int(duration.Hours()) 31 | if totalHours < 24 { 32 | if totalHours == 0 { 33 | totalHours = 1 34 | } 35 | return fmt.Sprintf("%dh ago", totalHours) 36 | } 37 | 38 | // Calculate total days 39 | totalDays := int(duration.Hours() / 24) 40 | if totalDays == 0 { 41 | totalDays = 1 42 | } 43 | return fmt.Sprintf("%dd ago", totalDays) 44 | } 45 | -------------------------------------------------------------------------------- /app/utils/file_handler.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import ( 4 | "bytes" 5 | "mime/multipart" 6 | ) 7 | 8 | func ReadFileToBytes(file multipart.File) ([]byte, error) { 9 | fileBytes := bytes.NewBuffer(nil) 10 | if _, err := fileBytes.ReadFrom(file); err != nil { 11 | return nil, err 12 | } 13 | return fileBytes.Bytes(), nil 14 | } 15 | -------------------------------------------------------------------------------- /app/utils/file_service.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "path/filepath" 7 | "strings" 8 | "log" 9 | ) 10 | 11 | func WriteToFile(filename string, content []string) error { 12 | fmt.Println("_________________________________________________________________") 13 | fmt.Println("Writing to file:", filename) 14 | dir := filepath.Dir(filename) 15 | err := os.MkdirAll(dir, os.ModePerm) 16 | if err != nil { 17 | return fmt.Errorf("failed to create directory: %w", err) 18 | } 19 | file, err := os.Create(filename) 20 | if err != nil { 21 | return fmt.Errorf("failed to create file: %w", err) 22 | } 23 | defer file.Close() 24 | _, err = file.WriteString(strings.Join(content, "\n")) 25 | fmt.Println("Content : ", strings.Join(content, "\n")) 26 | if err != nil { 27 | return fmt.Errorf("failed to write to file: %w", err) 28 | } 29 | return nil 30 | } 31 | 32 | func RemoveFile(filePath string) error { 33 | if _, err := os.Stat(filePath); os.IsNotExist(err) { 34 | log.Println("File does not exist", filePath) 35 | return nil 36 | } 37 | if err := os.Remove(filePath); err != nil { 38 | log.Println("Error removing file: ", filePath, err) 39 | return err 40 | } 41 | return nil 42 | } 43 | -------------------------------------------------------------------------------- /app/utils/hash_id_generator.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import ( 4 | "crypto/rand" 5 | "math/big" 6 | "strings" 7 | ) 8 | 9 | type HashIDGenerator struct { 10 | length int 11 | } 12 | 13 | func NewHashIDGenerator(length int) *HashIDGenerator { 14 | return &HashIDGenerator{length: length} 15 | } 16 | 17 | func (g *HashIDGenerator) Generate() string { 18 | const letters = "abcdefghijklmnopqrstuvwxyz" 19 | const alphanum = "abcdefghijklmnopqrstuvwxyz0123456789" 20 | var sb strings.Builder 21 | 22 | // Start with a lowercase letter 23 | sb.WriteByte(letters[g.cryptoRandInt(len(letters))]) 24 | 25 | // Generate the rest of the hash ID 26 | for i := 1; i < g.length; i++ { 27 | sb.WriteByte(alphanum[g.cryptoRandInt(len(alphanum))]) 28 | } 29 | 30 | // Ensure the generated ID does not end with a dash 31 | result := sb.String() 32 | if result[len(result)-1] == '-' { 33 | // Replace the last character if it's a dash 34 | return result[:len(result)-1] + string(letters[g.cryptoRandInt(len(letters))]) 35 | } 36 | 37 | return result 38 | } 39 | 40 | func (g *HashIDGenerator) cryptoRandInt(max int) byte { 41 | nBig, err := rand.Int(rand.Reader, big.NewInt(int64(max))) 42 | if err != nil { 43 | panic(err) // Handle the error according to your application's needs 44 | } 45 | return byte(nBig.Int64()) 46 | } 47 | -------------------------------------------------------------------------------- /app/utils/image_utils.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import ( 4 | "bytes" 5 | "encoding/base64" 6 | "fmt" 7 | "image/jpeg" 8 | "image/png" 9 | "io" 10 | ) 11 | 12 | func EncodeToBase64(filePathCloser io.ReadCloser) (string, string, error) { 13 | defer filePathCloser.Close() 14 | 15 | content, err := io.ReadAll(filePathCloser) 16 | if err != nil { 17 | return "", "", fmt.Errorf("failed to read from ReadCloser: %w", err) 18 | } 19 | imageType, err := determineImageType(content) 20 | if err != nil { 21 | return "", "", fmt.Errorf("failed to determine image type: %w", err) 22 | } 23 | 24 | // Encode the content to Base64 25 | base64Content := base64.StdEncoding.EncodeToString(content) 26 | 27 | return base64Content, imageType, nil 28 | } 29 | 30 | func determineImageType(data []byte) (string, error) { 31 | if _, err := jpeg.DecodeConfig(bytes.NewReader(data)); err == nil { 32 | return "image/jpeg", nil 33 | } 34 | if _, err := png.DecodeConfig(bytes.NewReader(data)); err == nil { 35 | return "image/png", nil 36 | } 37 | return "", fmt.Errorf("unsupported image type") 38 | } 39 | 40 | -------------------------------------------------------------------------------- /app/utils/random_string_generator.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import ( 4 | "crypto/rand" 5 | "math/big" 6 | ) 7 | 8 | const letterBytes = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" 9 | 10 | // RandString generates a random string of the specified length using crypto/rand 11 | func RandString(n int) (string, error) { 12 | b := make([]byte, n) 13 | for i := range b { 14 | num, err := rand.Int(rand.Reader, big.NewInt(int64(len(letterBytes)))) 15 | if err != nil { 16 | return "", err 17 | } 18 | b[i] = letterBytes[num.Int64()] 19 | } 20 | return string(b), nil 21 | } 22 | -------------------------------------------------------------------------------- /app/workflow_executors/step_executors/code_generation_executor.go: -------------------------------------------------------------------------------- 1 | package step_executors 2 | 3 | import "ai-developer/app/workflow_executors/step_executors/steps" 4 | 5 | type CodeGenerationExecutor interface { 6 | StepExecutor 7 | Execute(step steps.GenerateCodeStep) error 8 | } 9 | -------------------------------------------------------------------------------- /app/workflow_executors/step_executors/git_commit_executor.go: -------------------------------------------------------------------------------- 1 | package step_executors 2 | 3 | import "ai-developer/app/workflow_executors/step_executors/steps" 4 | 5 | type GitCommitExecutor interface { 6 | StepExecutor 7 | Execute(step steps.GitCommitStep) error 8 | } 9 | -------------------------------------------------------------------------------- /app/workflow_executors/step_executors/git_make_branch_executor.go: -------------------------------------------------------------------------------- 1 | package step_executors 2 | 3 | import "ai-developer/app/workflow_executors/step_executors/steps" 4 | 5 | type GitMakeBranchExecutor interface { 6 | StepExecutor 7 | Execute(step steps.GitMakeBranchStep) error 8 | } 9 | -------------------------------------------------------------------------------- /app/workflow_executors/step_executors/git_make_pull_request_executor.go: -------------------------------------------------------------------------------- 1 | package step_executors 2 | 3 | import "ai-developer/app/workflow_executors/step_executors/steps" 4 | 5 | type GitMakePullRequestExecutor interface { 6 | StepExecutor 7 | Execute(step steps.GitMakePullRequestStep) error 8 | } 9 | -------------------------------------------------------------------------------- /app/workflow_executors/step_executors/git_push_executor.go: -------------------------------------------------------------------------------- 1 | package step_executors 2 | 3 | import "ai-developer/app/workflow_executors/step_executors/steps" 4 | 5 | type GitPushExecutor interface { 6 | StepExecutor 7 | Execute(step steps.GitPushStep) error 8 | } 9 | -------------------------------------------------------------------------------- /app/workflow_executors/step_executors/graph/execution_state.go: -------------------------------------------------------------------------------- 1 | package graph 2 | 3 | type ExecutionState int 4 | 5 | const ( 6 | ExecutionSuccessState ExecutionState = iota 7 | ExecutionErrorState 8 | ExecutionRetryState 9 | ) 10 | -------------------------------------------------------------------------------- /app/workflow_executors/step_executors/graph/step_node.go: -------------------------------------------------------------------------------- 1 | package graph 2 | 3 | import ( 4 | "ai-developer/app/workflow_executors/step_executors/steps" 5 | ) 6 | 7 | type StepNode struct { 8 | Step steps.WorkflowStep `json:"step"` 9 | Transitions map[ExecutionState]*steps.StepName `json:"transitions"` 10 | } 11 | -------------------------------------------------------------------------------- /app/workflow_executors/step_executors/package_install_executor.go: -------------------------------------------------------------------------------- 1 | package step_executors 2 | 3 | import "ai-developer/app/workflow_executors/step_executors/steps" 4 | 5 | type PackageInstallStepExecutor interface { 6 | StepExecutor 7 | Execute(step steps.PackageInstallStep) error 8 | } 9 | -------------------------------------------------------------------------------- /app/workflow_executors/step_executors/reset_db_step_executor.go: -------------------------------------------------------------------------------- 1 | package step_executors 2 | 3 | import "ai-developer/app/workflow_executors/step_executors/steps" 4 | 5 | type ResetDBStepExecutor interface { 6 | StepExecutor 7 | Execute(step steps.ResetDBStep) error 8 | } 9 | -------------------------------------------------------------------------------- /app/workflow_executors/step_executors/server_start_test_executor.go: -------------------------------------------------------------------------------- 1 | package step_executors 2 | 3 | import "ai-developer/app/workflow_executors/step_executors/steps" 4 | 5 | type ServerStartTestExecutor interface { 6 | StepExecutor 7 | Execute(step steps.ServerStartTestStep) error 8 | } 9 | -------------------------------------------------------------------------------- /app/workflow_executors/step_executors/step_executor.go: -------------------------------------------------------------------------------- 1 | package step_executors 2 | 3 | type StepExecutor interface { 4 | } 5 | -------------------------------------------------------------------------------- /app/workflow_executors/step_executors/steps/base_step.go: -------------------------------------------------------------------------------- 1 | package steps 2 | 3 | import ( 4 | "ai-developer/app/models" 5 | "errors" 6 | ) 7 | 8 | var ErrReiterate = errors.New("reiterate error") 9 | 10 | type BaseStep struct { 11 | Story *models.Story 12 | Project *models.Project 13 | ExecutionStep *models.ExecutionStep 14 | Execution *models.Execution 15 | } 16 | 17 | func (s *BaseStep) WithProject(project *models.Project) *BaseStep { 18 | s.Project = project 19 | return s 20 | } 21 | 22 | func (s *BaseStep) WithStory(story *models.Story) *BaseStep { 23 | s.Story = story 24 | return s 25 | } 26 | 27 | func (s *BaseStep) WithExecutionStep(executionStep *models.ExecutionStep) *BaseStep { 28 | s.ExecutionStep = executionStep 29 | return s 30 | } 31 | 32 | func (s *BaseStep) WithExecution(execution *models.Execution) *BaseStep { 33 | s.Execution = execution 34 | return s 35 | } 36 | -------------------------------------------------------------------------------- /app/workflow_executors/step_executors/steps/code_generate_step.go: -------------------------------------------------------------------------------- 1 | package steps 2 | 3 | type GenerateCodeStep struct { 4 | BaseStep 5 | WorkflowStep 6 | Retry bool 7 | File string 8 | MaxLoopIterations int64 9 | PullRequestID uint 10 | PromptFilePath string 11 | } 12 | 13 | func (s GenerateCodeStep) StepType() string { 14 | return LLM.String() 15 | } 16 | 17 | func (s GenerateCodeStep) StepName() string { 18 | return CODE_GENERATE_STEP.String() 19 | } 20 | 21 | func (s *GenerateCodeStep) WithPullRequestID(pullRequestID uint) { 22 | s.PullRequestID = pullRequestID 23 | } 24 | -------------------------------------------------------------------------------- /app/workflow_executors/step_executors/steps/git_commit_step.go: -------------------------------------------------------------------------------- 1 | package steps 2 | 3 | type GitCommitStep struct { 4 | BaseStep 5 | WorkflowStep 6 | Type string 7 | } 8 | 9 | func (s GitCommitStep) StepType() string { 10 | return GIT.String() 11 | } 12 | 13 | func (s GitCommitStep) StepName() string { 14 | return GIT_COMMIT_STEP.String() 15 | } 16 | -------------------------------------------------------------------------------- /app/workflow_executors/step_executors/steps/git_make_branch_step.go: -------------------------------------------------------------------------------- 1 | package steps 2 | 3 | type GitMakeBranchStep struct { 4 | BaseStep 5 | WorkflowStep 6 | } 7 | 8 | func (s GitMakeBranchStep) StepType() string { 9 | return GIT.String() 10 | } 11 | 12 | func (s GitMakeBranchStep) StepName() string { 13 | return GIT_CREATE_BRANCH_STEP.String() 14 | } 15 | -------------------------------------------------------------------------------- /app/workflow_executors/step_executors/steps/git_make_pull_request.go: -------------------------------------------------------------------------------- 1 | package steps 2 | 3 | type GitMakePullRequestStep struct { 4 | BaseStep 5 | WorkflowStep 6 | Type string 7 | PullRequestID uint 8 | } 9 | 10 | func (s GitMakePullRequestStep) StepType() string { 11 | return GIT.String() 12 | } 13 | 14 | func (s GitMakePullRequestStep) StepName() string { 15 | return GIT_CREATE_PULL_REQUEST_STEP.String() 16 | } 17 | 18 | func (s *GitMakePullRequestStep) WithPullRequestID(pullRequestID uint) { 19 | s.PullRequestID = pullRequestID 20 | } 21 | -------------------------------------------------------------------------------- /app/workflow_executors/step_executors/steps/git_push_step.go: -------------------------------------------------------------------------------- 1 | package steps 2 | 3 | type GitPushStep struct { 4 | BaseStep 5 | WorkflowStep 6 | Type string 7 | } 8 | 9 | func (s GitPushStep) StepType() string { 10 | return COMMAND.String() 11 | } 12 | 13 | func (s GitPushStep) StepName() string { 14 | return GIT_PUSH_STEP.String() 15 | } 16 | -------------------------------------------------------------------------------- /app/workflow_executors/step_executors/steps/package_install_step.go: -------------------------------------------------------------------------------- 1 | package steps 2 | 3 | type PackageInstallStep struct { 4 | BaseStep 5 | WorkflowStep 6 | Type string 7 | } 8 | 9 | func (s PackageInstallStep) StepType() string { 10 | return COMMAND.String() 11 | } 12 | 13 | func (s PackageInstallStep) StepName() string { 14 | return PACKAGE_INSTALL_STEP.String() 15 | } 16 | -------------------------------------------------------------------------------- /app/workflow_executors/step_executors/steps/reset_db_step.go: -------------------------------------------------------------------------------- 1 | package steps 2 | 3 | type ResetDBStep struct { 4 | BaseStep 5 | WorkflowStep 6 | Type string 7 | } 8 | 9 | func (s ResetDBStep) StepType() string { 10 | return COMMAND.String() 11 | } 12 | 13 | func (s ResetDBStep) StepName() string { 14 | return RESET_DB_STEP.String() 15 | } 16 | -------------------------------------------------------------------------------- /app/workflow_executors/step_executors/steps/server_start_test_step.go: -------------------------------------------------------------------------------- 1 | package steps 2 | 3 | type ServerStartTestStep struct { 4 | BaseStep 5 | WorkflowStep 6 | Type string 7 | } 8 | 9 | func (s ServerStartTestStep) StepType() string { 10 | return CODE_TEST.String() 11 | } 12 | 13 | func (s ServerStartTestStep) StepName() string { 14 | return SERVER_START_STEP.String() 15 | } 16 | -------------------------------------------------------------------------------- /app/workflow_executors/step_executors/steps/step_names.go: -------------------------------------------------------------------------------- 1 | package steps 2 | 3 | type StepName string 4 | 5 | var ( 6 | CODE_GENERATE_STEP StepName = "CODE_GENERATE_STEP" 7 | RETRY_CODE_GENERATE_STEP StepName = "RETRY_CODE_GENERATE_STEP" 8 | GIT_COMMIT_STEP StepName = "GIT_COMMIT_STEP" 9 | GIT_CREATE_BRANCH_STEP StepName = "GIT_CREATE_BRANCH_STEP" 10 | GIT_PUSH_STEP StepName = "GIT_PUSH_STEP" 11 | GIT_CREATE_PULL_REQUEST_STEP StepName = "GIT_CREATE_PULL_REQUEST_STEP" 12 | SERVER_START_STEP StepName = "SERVER_START_STEP" 13 | UPDATE_CODE_FILE_STEP StepName = "UPDATE_CODE_FILE_STEP" 14 | RESET_DB_STEP StepName = "RESET_DB_STEP" 15 | CODE_GENERATE_CSS_STEP StepName = "CODE_GENERATE_CSS_STEP" 16 | CODE_GENERATE_LAYOUT_STEP StepName = "CODE_GENERATE_LAYOUT_STEP" 17 | CODE_GENERATE_PAGE_STEP StepName = "CODE_GENERATE_PAGE_STEP" 18 | UPDATE_CODE_CSS_FILE_STEP StepName = "UPDATE_CODE_CSS_FILE_STEP" 19 | UPDATE_CODE_LAYOUT_FILE_STEP StepName = "UPDATE_CODE_LAYOUT_FILE_STEP" 20 | UPDATE_CODE_PAGE_FILE_STEP StepName = "UPDATE_CODE_PAGE_FILE_STEP" 21 | PACKAGE_INSTALL_STEP StepName = "PACKAGE_INSTALL_STEP" 22 | ) 23 | 24 | func (s StepName) String() string { 25 | return string(s) 26 | } 27 | -------------------------------------------------------------------------------- /app/workflow_executors/step_executors/steps/step_types.go: -------------------------------------------------------------------------------- 1 | package steps 2 | 3 | type StepType string 4 | 5 | var ( 6 | GIT StepType = "GIT" 7 | LLM StepType = "LLM" 8 | CODE_TEST StepType = "CODE_TEST" 9 | FILE_OPERATION StepType = "FILE_OPERATION" 10 | COMMAND StepType = "COMMAND" 11 | ) 12 | 13 | func (s StepType) String() string { 14 | return string(s) 15 | } 16 | -------------------------------------------------------------------------------- /app/workflow_executors/step_executors/steps/update_code_file_step.go: -------------------------------------------------------------------------------- 1 | package steps 2 | 3 | type UpdateCodeFileStep struct { 4 | BaseStep 5 | WorkflowStep 6 | File string 7 | Retry bool 8 | Type string 9 | } 10 | 11 | func (s UpdateCodeFileStep) StepType() string { 12 | return FILE_OPERATION.String() 13 | } 14 | 15 | func (s UpdateCodeFileStep) StepName() string { 16 | return UPDATE_CODE_FILE_STEP.String() 17 | } 18 | -------------------------------------------------------------------------------- /app/workflow_executors/step_executors/steps/workflow_step.go: -------------------------------------------------------------------------------- 1 | package steps 2 | 3 | type WorkflowStep interface { 4 | StepType() string 5 | StepName() string 6 | } 7 | -------------------------------------------------------------------------------- /app/workflow_executors/step_executors/update_code_executor.go: -------------------------------------------------------------------------------- 1 | package step_executors 2 | 3 | import "ai-developer/app/workflow_executors/step_executors/steps" 4 | 5 | type UpdateCodeFileExecutor interface { 6 | StepExecutor 7 | Execute(step steps.UpdateCodeFileStep) error 8 | } 9 | -------------------------------------------------------------------------------- /app/workflow_executors/workflow_config.go: -------------------------------------------------------------------------------- 1 | package workflow_executors 2 | 3 | import ( 4 | "ai-developer/app/workflow_executors/step_executors/graph" 5 | ) 6 | 7 | type WorkflowConfig struct { 8 | WorkflowName string 9 | StepGraph *graph.StepGraph 10 | Files []string 11 | } 12 | -------------------------------------------------------------------------------- /app/workflow_executors/workflow_execution_args.go: -------------------------------------------------------------------------------- 1 | package workflow_executors 2 | 3 | type WorkflowExecutionArgs struct { 4 | ExecutionId int64 5 | StoryId int64 6 | IsReExecution bool 7 | Branch string 8 | PullRequestId int64 9 | } 10 | -------------------------------------------------------------------------------- /bin/migrations.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Wait for PostgreSQL to be ready 4 | while ! pg_isready -h "${AI_DEVELOPER_DB_HOST}" -p 5432 -q; do 5 | echo "Waiting for PostgreSQL to be ready..." 6 | sleep 1 7 | done 8 | 9 | echo "Running migrations..." 10 | # Check if AI_DEVELOPER_ENV is set to "production" 11 | if [ "${AI_DEVELOPER_ENV}" = "production" ]; then 12 | # Run migrations in production mode 13 | migrate -path /go/src/packages/ai-developer/app/db/migrations -database "postgres://${AI_DEVELOPER_DB_USER}:${AI_DEVELOPER_DB_PASSWORD}@${AI_DEVELOPER_DB_HOST}:5432/ai-developer?sslmode=enable" up 14 | else 15 | # Run migrations in development mode 16 | migrate -path /go/src/packages/ai-developer/app/db/migrations -database "postgres://${AI_DEVELOPER_DB_USER}:${AI_DEVELOPER_DB_PASSWORD}@${AI_DEVELOPER_DB_HOST}:5432/ai-developer?sslmode=disable" up 17 | fi 18 | -------------------------------------------------------------------------------- /docker/nginx/default.conf: -------------------------------------------------------------------------------- 1 | server { 2 | listen 80; 3 | listen [::]:80; 4 | server_name location; 5 | 6 | location / { 7 | root /workspaces; 8 | try_files $uri $uri/ =404; 9 | index index.html index.htm; 10 | } 11 | 12 | error_page 500 502 503 504 /50x.html; 13 | location = /50x.html { 14 | root /usr/share/nginx/html; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /gui/.dockerignore: -------------------------------------------------------------------------------- 1 | Dockerfile 2 | docker-compose.yaml 3 | gui 4 | ide 5 | workspace-service 6 | *.iml 7 | .idea/ 8 | node_modules/ 9 | .next -------------------------------------------------------------------------------- /gui/.eslintignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | .next/ -------------------------------------------------------------------------------- /gui/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "eslint": { 3 | // Warning: This allows production builds to successfully complete even if 4 | // your project has ESLint errors. 5 | "ignoreDuringBuilds": true 6 | }, 7 | "env": { 8 | "browser": true, 9 | "es2021": true 10 | }, 11 | "extends": [ 12 | "next/core-web-vitals", 13 | "eslint:recommended", 14 | "plugin:@typescript-eslint/recommended", 15 | "plugin:prettier/recommended", 16 | "plugin:tailwindcss/recommended" 17 | ], 18 | "parser": "@typescript-eslint/parser", 19 | "parserOptions": { 20 | "ecmaFeatures": { 21 | "jsx": true 22 | }, 23 | "ecmaVersion": "latest", 24 | "sourceType": "module" 25 | }, 26 | "plugins": ["react", "@typescript-eslint", "prettier", "tailwindcss"], 27 | "rules": { 28 | "prettier/prettier": "error" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /gui/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | .yarn/install-state.gz 8 | 9 | # testing 10 | /coverage 11 | 12 | # next.js 13 | /.next/ 14 | /out/ 15 | 16 | # production 17 | /build 18 | 19 | # misc 20 | .DS_Store 21 | *.pem 22 | 23 | # debug 24 | npm-debug.log* 25 | yarn-debug.log* 26 | yarn-error.log* 27 | 28 | # local env files 29 | .env*.local 30 | 31 | # vercel 32 | .vercel 33 | 34 | # typescript 35 | *.tsbuildinfo 36 | next-env.d.ts 37 | -------------------------------------------------------------------------------- /gui/.prettierrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | semi: true, 3 | singleQuote: true, 4 | trailingComma: 'all', 5 | printWidth: 80, 6 | tabWidth: 2, 7 | plugins: [require('prettier-plugin-tailwindcss')], 8 | }; 9 | -------------------------------------------------------------------------------- /gui/.stylelintignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | .next/ -------------------------------------------------------------------------------- /gui/Dockerfile: -------------------------------------------------------------------------------- 1 | # Use an official Node.js runtime as a parent image 2 | FROM node:18-alpine 3 | 4 | # Set the working directory 5 | WORKDIR /app 6 | 7 | ARG NEXT_PUBLIC_APP_ENV='development' 8 | ENV NEXT_PUBLIC_APP_ENV=$NEXT_PUBLIC_APP_ENV 9 | ARG NEXT_PUBLIC_DOCKER 10 | ENV NEXT_PUBLIC_DOCKER=$NEXT_PUBLIC_DOCKER 11 | 12 | # Copy package.json, package-lock.json, and next.config.mjs into the container 13 | COPY package*.json next.config.mjs ./ 14 | 15 | # Install dependencies 16 | RUN yarn install 17 | 18 | # Copy the rest of your Next.js application 19 | COPY . . 20 | 21 | # Build your Next.js application 22 | #RUN yarn build 23 | 24 | # Start the Next.js application 25 | #CMD ["yarn", "start"] 26 | CMD ["yarn", "dev"] -------------------------------------------------------------------------------- /gui/README.md: -------------------------------------------------------------------------------- 1 | ## Getting Started 2 | 3 | First, run the development server: 4 | 5 | ```bash 6 | yarn install 7 | 8 | npx husky install 9 | 10 | npx husky add .husky/pre-commit "npx lint-staged" 11 | ``` 12 | 13 | then 14 | 15 | ```bash 16 | yarn dev 17 | # or 18 | pnpm dev 19 | # or 20 | bun dev 21 | ``` 22 | 23 | Open [http://localhost:3000](;http://localhost:3000) with your browser to see the result. 24 | -------------------------------------------------------------------------------- /gui/global.d.ts: -------------------------------------------------------------------------------- 1 | interface Window { 2 | clarity: (action: string, key: string, value: string | null) => void; 3 | } 4 | -------------------------------------------------------------------------------- /gui/next.config.mjs: -------------------------------------------------------------------------------- 1 | const localurl = process.env.NEXT_PUBLIC_DOCKER 2 | ? 'http://server:8080/api/:path*' 3 | : 'http://0.0.0.0:8080/api/:path*'; 4 | 5 | let backendUrl = process.env.NEXT_PUBLIC_API_URL+'/api/:path*'; 6 | 7 | console.log("NEXT_PUBLIC_DOCKER", process.env.NEXT_PUBLIC_DOCKER) 8 | console.log("LOCALURL", localurl) 9 | const nextConfig = { 10 | compiler: { 11 | styledComponents: true, 12 | }, 13 | async rewrites() { 14 | return [ 15 | { 16 | source: '/api/:path*', 17 | destination: process.env.NEXT_PUBLIC_APP_ENV === 'development' ? localurl : backendUrl, 18 | }, 19 | ]; 20 | }, 21 | images: { 22 | domains: [], 23 | formats: ['image/webp', 'image/avif'], 24 | remotePatterns: [ 25 | { 26 | protocol: 'https', 27 | hostname: '**', 28 | port: '', 29 | pathname: '**', 30 | }, 31 | ], 32 | }, 33 | reactStrictMode: false, 34 | output: 'standalone', 35 | }; 36 | 37 | export default nextConfig; 38 | -------------------------------------------------------------------------------- /gui/postcss.config.mjs: -------------------------------------------------------------------------------- 1 | /** @type {import('postcss-load-config').Config} */ 2 | const config = { 3 | plugins: { 4 | tailwindcss: {}, 5 | }, 6 | }; 7 | 8 | export default config; 9 | -------------------------------------------------------------------------------- /gui/public/arrows/back_arrow.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /gui/public/arrows/bottom_arrow_grey.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /gui/public/arrows/bottom_arrow_thin_grey.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /gui/public/arrows/bottom_arrow_white.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /gui/public/arrows/left_arrow_grey.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /gui/public/arrows/right_arrow_thin_grey.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /gui/public/fonts/proxima-nova-2/Mark-Simonson-Proxima-Nova-Black-Italic.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TransformerOptimus/SuperCoder/029d3709e061e53ec61ce3e7cb6b6709fe2f0c09/gui/public/fonts/proxima-nova-2/Mark-Simonson-Proxima-Nova-Black-Italic.otf -------------------------------------------------------------------------------- /gui/public/fonts/proxima-nova-2/Mark-Simonson-Proxima-Nova-Black.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TransformerOptimus/SuperCoder/029d3709e061e53ec61ce3e7cb6b6709fe2f0c09/gui/public/fonts/proxima-nova-2/Mark-Simonson-Proxima-Nova-Black.otf -------------------------------------------------------------------------------- /gui/public/fonts/proxima-nova-2/Mark-Simonson-Proxima-Nova-Bold-Italic.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TransformerOptimus/SuperCoder/029d3709e061e53ec61ce3e7cb6b6709fe2f0c09/gui/public/fonts/proxima-nova-2/Mark-Simonson-Proxima-Nova-Bold-Italic.otf -------------------------------------------------------------------------------- /gui/public/fonts/proxima-nova-2/Mark-Simonson-Proxima-Nova-Bold.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TransformerOptimus/SuperCoder/029d3709e061e53ec61ce3e7cb6b6709fe2f0c09/gui/public/fonts/proxima-nova-2/Mark-Simonson-Proxima-Nova-Bold.otf -------------------------------------------------------------------------------- /gui/public/fonts/proxima-nova-2/Mark-Simonson-Proxima-Nova-Extrabold-Italic.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TransformerOptimus/SuperCoder/029d3709e061e53ec61ce3e7cb6b6709fe2f0c09/gui/public/fonts/proxima-nova-2/Mark-Simonson-Proxima-Nova-Extrabold-Italic.otf -------------------------------------------------------------------------------- /gui/public/fonts/proxima-nova-2/Mark-Simonson-Proxima-Nova-Extrabold.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TransformerOptimus/SuperCoder/029d3709e061e53ec61ce3e7cb6b6709fe2f0c09/gui/public/fonts/proxima-nova-2/Mark-Simonson-Proxima-Nova-Extrabold.otf -------------------------------------------------------------------------------- /gui/public/fonts/proxima-nova-2/Mark-Simonson-Proxima-Nova-Light-Italic.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TransformerOptimus/SuperCoder/029d3709e061e53ec61ce3e7cb6b6709fe2f0c09/gui/public/fonts/proxima-nova-2/Mark-Simonson-Proxima-Nova-Light-Italic.otf -------------------------------------------------------------------------------- /gui/public/fonts/proxima-nova-2/Mark-Simonson-Proxima-Nova-Light.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TransformerOptimus/SuperCoder/029d3709e061e53ec61ce3e7cb6b6709fe2f0c09/gui/public/fonts/proxima-nova-2/Mark-Simonson-Proxima-Nova-Light.otf -------------------------------------------------------------------------------- /gui/public/fonts/proxima-nova-2/Mark-Simonson-Proxima-Nova-Regular-Italic.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TransformerOptimus/SuperCoder/029d3709e061e53ec61ce3e7cb6b6709fe2f0c09/gui/public/fonts/proxima-nova-2/Mark-Simonson-Proxima-Nova-Regular-Italic.otf -------------------------------------------------------------------------------- /gui/public/fonts/proxima-nova-2/Mark-Simonson-Proxima-Nova-Regular.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TransformerOptimus/SuperCoder/029d3709e061e53ec61ce3e7cb6b6709fe2f0c09/gui/public/fonts/proxima-nova-2/Mark-Simonson-Proxima-Nova-Regular.otf -------------------------------------------------------------------------------- /gui/public/fonts/proxima-nova-2/Mark-Simonson-Proxima-Nova-Semibold-Italic.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TransformerOptimus/SuperCoder/029d3709e061e53ec61ce3e7cb6b6709fe2f0c09/gui/public/fonts/proxima-nova-2/Mark-Simonson-Proxima-Nova-Semibold-Italic.otf -------------------------------------------------------------------------------- /gui/public/fonts/proxima-nova-2/Mark-Simonson-Proxima-Nova-Semibold.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TransformerOptimus/SuperCoder/029d3709e061e53ec61ce3e7cb6b6709fe2f0c09/gui/public/fonts/proxima-nova-2/Mark-Simonson-Proxima-Nova-Semibold.otf -------------------------------------------------------------------------------- /gui/public/fonts/proxima-nova-2/Mark-Simonson-Proxima-Nova-Thin-Italic.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TransformerOptimus/SuperCoder/029d3709e061e53ec61ce3e7cb6b6709fe2f0c09/gui/public/fonts/proxima-nova-2/Mark-Simonson-Proxima-Nova-Thin-Italic.otf -------------------------------------------------------------------------------- /gui/public/fonts/proxima-nova-2/Mark-Simonson-Proxima-Nova-Thin.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TransformerOptimus/SuperCoder/029d3709e061e53ec61ce3e7cb6b6709fe2f0c09/gui/public/fonts/proxima-nova-2/Mark-Simonson-Proxima-Nova-Thin.otf -------------------------------------------------------------------------------- /gui/public/icons/add_icon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /gui/public/icons/chat_bubble_icon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /gui/public/icons/code_add_icon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /gui/public/icons/code_minus_icon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /gui/public/icons/done_dot.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /gui/public/icons/edit_icon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /gui/public/icons/in_review_dot.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /gui/public/icons/inprogress_dot.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /gui/public/icons/move_to_icon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /gui/public/icons/play_icon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /gui/public/icons/todo_dot.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /gui/public/icons/vertical_line.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /gui/public/icons/white_dot.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /gui/public/images/django_image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TransformerOptimus/SuperCoder/029d3709e061e53ec61ce3e7cb6b6709fe2f0c09/gui/public/images/django_image.png -------------------------------------------------------------------------------- /gui/public/images/fastapi_image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TransformerOptimus/SuperCoder/029d3709e061e53ec61ce3e7cb6b6709fe2f0c09/gui/public/images/fastapi_image.png -------------------------------------------------------------------------------- /gui/public/images/flask_image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TransformerOptimus/SuperCoder/029d3709e061e53ec61ce3e7cb6b6709fe2f0c09/gui/public/images/flask_image.png -------------------------------------------------------------------------------- /gui/public/images/nextjs_image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TransformerOptimus/SuperCoder/029d3709e061e53ec61ce3e7cb6b6709fe2f0c09/gui/public/images/nextjs_image.png -------------------------------------------------------------------------------- /gui/src/api/apiConfig.tsx: -------------------------------------------------------------------------------- 1 | import axios, { AxiosInstance } from 'axios'; 2 | 3 | export const API_BASE_URL = '/api'; 4 | 5 | const api: AxiosInstance = axios.create({ 6 | baseURL: API_BASE_URL, 7 | timeout: 300000, 8 | withCredentials: true, 9 | headers: { 10 | common: { 11 | 'Content-Type': 'application/json', 12 | 'Access-Control-Allow-Origin': '*', 13 | }, 14 | }, 15 | }); 16 | 17 | export default api; 18 | -------------------------------------------------------------------------------- /gui/src/app/(programmer)/board/board.module.css: -------------------------------------------------------------------------------- 1 | .number_tag { 2 | color: #FFF; 3 | font-family: "Proxima Nova", sans-serif; 4 | font-size: 11px; 5 | font-style: normal; 6 | font-weight: 400; 7 | line-height: normal; 8 | border-radius: 4px; 9 | background: var(--white-opacity-12); 10 | display: flex; 11 | padding: 0 3px; 12 | flex-direction: column; 13 | align-items: flex-start; 14 | gap: 10px; 15 | } -------------------------------------------------------------------------------- /gui/src/app/(programmer)/board/layout.tsx: -------------------------------------------------------------------------------- 1 | import { BoardProvider } from '@/context/Boards'; 2 | 3 | export default function BoardLayout({ 4 | children, 5 | }: Readonly<{ children: React.ReactNode }>) { 6 | return ( 7 |
8 | {children} 9 |
10 | ); 11 | } 12 | -------------------------------------------------------------------------------- /gui/src/app/(programmer)/code/page.tsx: -------------------------------------------------------------------------------- 1 | export default function Code() { 2 | return null; 3 | } 4 | -------------------------------------------------------------------------------- /gui/src/app/(programmer)/design/layout.tsx: -------------------------------------------------------------------------------- 1 | import { DesignProvider } from '@/context/Design'; 2 | import React from 'react'; 3 | 4 | export default function DesignLayout({ 5 | children, 6 | }: Readonly<{ children: React.ReactNode }>) { 7 | return ( 8 |
9 | {children} 10 |
11 | ); 12 | } 13 | -------------------------------------------------------------------------------- /gui/src/app/(programmer)/design/review/[story_id]/review.module.css: -------------------------------------------------------------------------------- 1 | .heading_container{ 2 | border-bottom: 1px solid var(--white-opacity-8); 3 | } 4 | 5 | .container{ 6 | border: 1px solid var(--white-opacity-8); 7 | background: var(--white-opacity-8); 8 | } -------------------------------------------------------------------------------- /gui/src/app/(programmer)/design_workbench/layout.tsx: -------------------------------------------------------------------------------- 1 | export default function DesignWorkbenchLayout({ 2 | children, 3 | }: Readonly<{ children: React.ReactNode }>) { 4 | return ( 5 |
6 | {/**/} 7 | {children} 8 | {/**/} 9 |
10 | ); 11 | } 12 | -------------------------------------------------------------------------------- /gui/src/app/(programmer)/pull_request/PRList/GithubReviewButton.tsx: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components'; 2 | 3 | const GithubReviewButton = styled.button` 4 | border-radius: 8px; 5 | border: 1px solid rgba(255, 255, 255, 0.08); 6 | background: linear-gradient( 7 | 0deg, 8 | rgba(0, 0, 0, 0.4) 0%, 9 | rgba(0, 0, 0, 0.4) 100% 10 | ), 11 | #4bac1c; 12 | padding: 8px 12px; 13 | cursor: pointer; 14 | color: #fff; 15 | font-family: 'Proxima Nova', sans-serif; 16 | font-size: 14px; 17 | font-style: normal; 18 | font-weight: 600; 19 | line-height: normal; 20 | height: 100%; 21 | margin: auto 0; 22 | `; 23 | 24 | export default GithubReviewButton; 25 | -------------------------------------------------------------------------------- /gui/src/app/(programmer)/pull_request/[pr_id]/FilesChanged.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import dynamic from 'next/dynamic'; 3 | import { FilesChangedProps } from '../../../../../types/pullRequestsTypes'; 4 | 5 | const MonacoDiffEditor = dynamic( 6 | () => import('@/components/CustomDiffEditor/MonacoDiffEditor'), 7 | { ssr: false }, 8 | ); 9 | 10 | const FilesChanged: React.FC = ({ diff }) => { 11 | const fileDiffs = diff && diff.split(/(?=diff --git a\/)/g); 12 | 13 | return ( 14 |
19 | {diff && 20 | fileDiffs.map((fileDiff, index) => { 21 | // Extract the file name from the diff string 22 | const match = fileDiff.match(/diff --git a\/(.+?) b\/(.+?)\n/); 23 | const fileName = match ? match[1] : `file${index + 1}`; 24 | 25 | return ( 26 | 31 | ); 32 | })} 33 |
34 | ); 35 | }; 36 | 37 | export default FilesChanged; 38 | -------------------------------------------------------------------------------- /gui/src/app/(programmer)/pull_request/[pr_id]/OpenTag.ts: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components'; 2 | 3 | const OpenTag = styled.button` 4 | border-radius: 24px; 5 | background: linear-gradient( 6 | 0deg, 7 | rgba(0, 0, 0, 0.4) 0%, 8 | rgba(0, 0, 0, 0.4) 100% 9 | ), 10 | #4bac1c; 11 | color: #fff; 12 | font-family: 'Proxima Nova', sans-serif; 13 | font-size: 13px; 14 | font-style: normal; 15 | font-weight: 600; 16 | line-height: normal; 17 | display: flex; 18 | padding: 6px; 19 | flex-direction: row; 20 | align-items: center; 21 | gap: 6px; 22 | `; 23 | 24 | export default OpenTag; 25 | -------------------------------------------------------------------------------- /gui/src/app/(programmer)/pull_request/layout.tsx: -------------------------------------------------------------------------------- 1 | import { PullRequestsProvider } from '@/context/PullRequests'; 2 | 3 | export default function PullRequestLayout({ 4 | children, 5 | }: Readonly<{ children: React.ReactNode }>) { 6 | return ( 7 |
8 | {children} 9 |
10 | ); 11 | } 12 | -------------------------------------------------------------------------------- /gui/src/app/(programmer)/pull_request/pr.module.css: -------------------------------------------------------------------------------- 1 | .pr_list_container { 2 | display: flex; 3 | flex-direction: row; 4 | align-items: center; 5 | justify-content: space-between; 6 | align-self: stretch; 7 | padding: 12px 8px; 8 | border-bottom: 1px solid rgb(255 255 255 / 12%); 9 | cursor: pointer; 10 | } 11 | 12 | .pr_list_container:hover, 13 | .pr_list_container.active { 14 | background: rgb(255 255 255 / 8%); 15 | } 16 | 17 | .pr_details_header_container { 18 | padding: 24px 16px; 19 | display: flex; 20 | flex-direction: row; 21 | justify-content: space-between; 22 | width: 100%; 23 | border-bottom: 1px solid rgb(255 255 255 / 12%); 24 | } 25 | 26 | .commit_log_card_container { 27 | display: flex; 28 | padding: 8px; 29 | flex-direction: row; 30 | justify-content: space-between; 31 | align-items: center; 32 | gap: 4px; 33 | flex: 1 0 0; 34 | border-radius: 8px; 35 | background: var(--white-opacity-8); 36 | } 37 | -------------------------------------------------------------------------------- /gui/src/app/(programmer)/workbench/layout.tsx: -------------------------------------------------------------------------------- 1 | import { WorkbenchProvider } from '@/context/Workbench'; 2 | 3 | export default function BoardLayout({ 4 | children, 5 | }: Readonly<{ children: React.ReactNode }>) { 6 | return ( 7 |
8 | {children} 9 |
10 | ); 11 | } 12 | -------------------------------------------------------------------------------- /gui/src/app/constants/ActivityLogType.ts: -------------------------------------------------------------------------------- 1 | export const ActivityLogType = { 2 | ERROR: 'ERROR', 3 | CODE: 'CODE', 4 | INFO: 'INFO', 5 | } -------------------------------------------------------------------------------- /gui/src/app/constants/BoardConstants.ts: -------------------------------------------------------------------------------- 1 | export const storyStatus = { 2 | TODO: 'TODO', 3 | IN_PROGRESS: 'IN_PROGRESS', 4 | DONE: 'DONE', 5 | IN_REVIEW: 'IN_REVIEW', 6 | MAX_LOOP_ITERATIONS: 'MAX_LOOP_ITERATION_REACHED', 7 | LLM_KEY_NOT_FOUND: 'IN_REVIEW_LLM_KEY_NOT_FOUND', 8 | }; 9 | 10 | export const showStoryDetailsDropdown = [ 11 | storyStatus.TODO, 12 | storyStatus.IN_REVIEW, 13 | ]; 14 | 15 | export const storyActions = { 16 | REBUILD: 'Re-Build', 17 | GET_HELP: 'GET_HELP', 18 | GO_TO_SETTINGS: 'GOTO_SETTINGS', 19 | } -------------------------------------------------------------------------------- /gui/src/app/constants/NavbarConstants.ts: -------------------------------------------------------------------------------- 1 | import imagePath from '@/app/imagePath'; 2 | import { NavbarTypes } from '../../../types/navbarTypes'; 3 | 4 | export const navbarOptions: NavbarTypes[] = [ 5 | { 6 | id: 'discord', 7 | text: 'Get help?', 8 | image: imagePath.discordIcon, 9 | url: 'https://discord.com/invite/dXbRe5BHJC', 10 | }, 11 | ]; 12 | -------------------------------------------------------------------------------- /gui/src/app/constants/ProjectConstants.ts: -------------------------------------------------------------------------------- 1 | import imagePath from '@/app/imagePath'; 2 | 3 | export const storyTypes = { 4 | BACKEND: 'BACKEND', 5 | DESIGN: 'DESIGN', 6 | }; 7 | 8 | export const backendFrameworkOptions = [ 9 | { 10 | id: 'flask', 11 | text: 'Flask', 12 | src: imagePath.flaskImage, 13 | available: true, 14 | }, 15 | { 16 | id: 'django', 17 | text: 'Django', 18 | src: imagePath.djangoImage, 19 | available: true, 20 | }, 21 | { 22 | id: 'fast_api', 23 | text: 'Fast API', 24 | src: imagePath.fastAPIImage, 25 | available: false, 26 | }, 27 | ]; 28 | 29 | export const frontendFrameworkOptions = [ 30 | { 31 | id: 'nextjs', 32 | text: 'Next Js', 33 | src: imagePath.nextJsImage, 34 | available: true, 35 | }, 36 | ]; 37 | -------------------------------------------------------------------------------- /gui/src/app/constants/PullRequestConstants.ts: -------------------------------------------------------------------------------- 1 | export const prStatuses = { 2 | OPEN: 'OPEN', 3 | CLOSED: 'CLOSED', 4 | MERGED: 'MERGED', 5 | }; 6 | -------------------------------------------------------------------------------- /gui/src/app/constants/SkeletonConstants.ts: -------------------------------------------------------------------------------- 1 | export const SkeletonTypes = { 2 | PROJECT: 'project', 3 | WORKBENCH: 'workbench', 4 | CODE: 'code', 5 | BOARD: 'board', 6 | PULL_REQUEST: 'pull_request', 7 | }; 8 | -------------------------------------------------------------------------------- /gui/src/app/constants/UtilsConstants.ts: -------------------------------------------------------------------------------- 1 | export const Servers = { 2 | BACKEND: 'backend', 3 | FRONTEND: 'frontend', 4 | }; 5 | -------------------------------------------------------------------------------- /gui/src/app/logout/page.tsx: -------------------------------------------------------------------------------- 1 | 'use client'; 2 | import React, { useEffect } from 'react'; 3 | import { logout } from '@/app/utils'; 4 | 5 | const Logout: React.FC = () => { 6 | useEffect(() => { 7 | logout(); 8 | }, []); 9 | 10 | return ( 11 |
12 | ....Logout 13 |
14 | ); 15 | }; 16 | 17 | export default Logout; 18 | -------------------------------------------------------------------------------- /gui/src/app/page.tsx: -------------------------------------------------------------------------------- 1 | import LandingPage from '@/components/HomeComponents/LandingPage'; 2 | 3 | export default function Home() { 4 | return ( 5 |
6 | 7 |
8 | ); 9 | } 10 | -------------------------------------------------------------------------------- /gui/src/app/projects/layout.tsx: -------------------------------------------------------------------------------- 1 | import React, { ReactNode } from 'react'; 2 | import NavBar from '@/components/LayoutComponents/NavBar'; 3 | import styles from './projects.module.css'; 4 | import { SocketProvider } from '@/context/SocketContext'; 5 | 6 | export default function ProjectsLayout({ 7 | children, 8 | }: Readonly<{ children: ReactNode }>) { 9 | return ( 10 |
11 | 12 |
13 |
{children}
14 |
15 |
16 | ); 17 | } 18 | -------------------------------------------------------------------------------- /gui/src/app/projects/projects.module.css: -------------------------------------------------------------------------------- 1 | .project_content { 2 | background-color: var(--project-bg-color); 3 | border-radius: 8px 0 0; 4 | flex: 1; 5 | } 6 | 7 | .project_container { 8 | background-color: var(--white-opacity-2); 9 | display: flex; 10 | flex-direction: column; 11 | padding: 12px; 12 | height: 140px; 13 | justify-content: space-between; 14 | cursor: pointer; 15 | } 16 | -------------------------------------------------------------------------------- /gui/src/app/providers.tsx: -------------------------------------------------------------------------------- 1 | 'use client'; 2 | 3 | import { NextUIProvider } from '@nextui-org/react'; 4 | import { UserContextProvider } from '@/context/UserContext'; 5 | 6 | export function Providers({ children }: { children: React.ReactNode }) { 7 | return ( 8 | 9 | {children} 10 | 11 | ); 12 | } 13 | -------------------------------------------------------------------------------- /gui/src/app/settings/layout.tsx: -------------------------------------------------------------------------------- 1 | import NavBar from '@/components/LayoutComponents/NavBar'; 2 | import React from 'react'; 3 | import styles from '@/app/projects/projects.module.css'; 4 | import { Toaster } from 'react-hot-toast'; 5 | 6 | export default function SettingsLayout({ 7 | children, 8 | }: Readonly<{ children: React.ReactNode }>) { 9 | return ( 10 |
11 | 12 |
13 |
{children}
14 | 15 |
16 |
17 | ); 18 | } 19 | -------------------------------------------------------------------------------- /gui/src/app/settings/page.tsx: -------------------------------------------------------------------------------- 1 | 'use client'; 2 | import React from 'react'; 3 | import Models from '@/app/settings/SettingsOptions/Models'; 4 | import CustomSidebar from '@/components/CustomSidebar/CustomSidebar'; 5 | import imagePath from '@/app/imagePath'; 6 | import BackButton from '@/components/BackButton/BackButton'; 7 | 8 | export default function Settings() { 9 | const options = [ 10 | { 11 | key: 'models', 12 | text: 'Models', 13 | selected: imagePath.modelsIconSelected, 14 | unselected: imagePath.modelsIconUnselected, 15 | icon_css: 'size-4', 16 | component: , 17 | }, 18 | ]; 19 | 20 | const handleOptionSelect = (key: string) => { 21 | console.log('Selected option:', key); 22 | }; 23 | 24 | return ( 25 |
26 | 27 | 28 | 34 |
35 | ); 36 | } 37 | -------------------------------------------------------------------------------- /gui/src/components/BackButton/BackButton.tsx: -------------------------------------------------------------------------------- 1 | import CustomImage from '@/components/ImageComponents/CustomImage'; 2 | import imagePath from '@/app/imagePath'; 3 | import { useRouter } from 'next/navigation'; 4 | 5 | interface BackButtonProps { 6 | id: string; 7 | url: string; 8 | } 9 | 10 | export default function BackButton({ id, url }: BackButtonProps) { 11 | const router = useRouter(); 12 | 13 | return ( 14 |
router.push(url)} 20 | > 21 | 26 | 27 | Back 28 | 29 |
30 | ); 31 | } 32 | -------------------------------------------------------------------------------- /gui/src/components/CustomContainers/container.module.css: -------------------------------------------------------------------------------- 1 | .container_section { 2 | display: flex; 3 | flex-direction: column; 4 | width: 100%; 5 | position: relative; 6 | border-radius: 8px; 7 | border: 1px solid var(--white-opacity-8); 8 | background: var(--layout-bg-color); 9 | } 10 | 11 | .container_header { 12 | color: #888; 13 | font-family: 'Proxima Nova', sans-serif; 14 | font-size: 14px; 15 | font-style: normal; 16 | font-weight: 400; 17 | line-height: normal; 18 | padding: 8px 12px; 19 | border-bottom: 1px solid var(--white-opacity-8); 20 | background: var(--layout-bg-color); 21 | border-radius: 8px 8px 0 0; 22 | } 23 | 24 | .container_tab_header { 25 | display: flex; 26 | flex-direction: row; 27 | gap: 4px; 28 | padding: 8px; 29 | border-bottom: 1px solid var(--white-opacity-8); 30 | cursor: pointer; 31 | } 32 | 33 | .tab_item, .tab_item_selected { 34 | display: flex; 35 | flex-direction: row; 36 | align-items: center; 37 | justify-content: center; 38 | padding: 4px 8px; 39 | gap: 8px; 40 | border-radius: 8px; 41 | } 42 | 43 | .tab_item_selected { 44 | background: rgb(255 255 255 / 6%); 45 | } 46 | -------------------------------------------------------------------------------- /gui/src/components/CustomDiffEditor/diff.module.css: -------------------------------------------------------------------------------- 1 | .diff_container { 2 | display: flex; 3 | flex-direction: column; 4 | align-items: flex-start; 5 | align-self: stretch; 6 | border-radius: 8px; 7 | border: 1px solid var(--white-opacity-8); 8 | margin-bottom: 20px; 9 | } 10 | 11 | .diff_header { 12 | display: flex; 13 | flex-direction: row; 14 | align-items: center; 15 | gap: 8px; 16 | padding: 12px 10px; 17 | background: var(--white-opacity-8); 18 | color: #fff; 19 | width: 100%; 20 | font-family: 'Space Mono', sans-serif; 21 | font-size: 12px; 22 | font-style: normal; 23 | font-weight: 400; 24 | line-height: normal; 25 | } 26 | 27 | .border_radius_top { 28 | border-radius: 7px 7px 0 0; 29 | } 30 | -------------------------------------------------------------------------------- /gui/src/components/CustomLoaders/CustomLoaders.tsx: -------------------------------------------------------------------------------- 1 | import styles from './loader.module.css'; 2 | import SkeletonLoader from '@/components/CustomLoaders/SkeletonLoader'; 3 | import skeletonLoader from '@/components/CustomLoaders/SkeletonLoader'; 4 | 5 | interface CustomLoadersProps { 6 | type: string; 7 | size?: number; 8 | skeletonType?: string; 9 | } 10 | 11 | export default function CustomLoaders({ 12 | type, 13 | size, 14 | skeletonType, 15 | }: CustomLoadersProps) { 16 | return ( 17 |
18 | {type === 'default' ? ( 19 |
23 | ) : ( 24 | 25 | )} 26 |
27 | ); 28 | } 29 | -------------------------------------------------------------------------------- /gui/src/components/CustomLoaders/Loader.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import styles from './loader.module.css'; 3 | 4 | interface LoaderProps { 5 | size?: number; 6 | text?: string; 7 | } 8 | 9 | const Loader: React.FC = ({ size = 100, text = 'Loading...' }) => { 10 | return ( 11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 | {text} 19 |
20 | ); 21 | }; 22 | 23 | export default Loader; 24 | -------------------------------------------------------------------------------- /gui/src/components/CustomSidebar/sidebar.module.css: -------------------------------------------------------------------------------- 1 | .container { 2 | display: flex; 3 | } 4 | 5 | .sidebar { 6 | width: 250px; 7 | padding: 10px; 8 | display: flex; 9 | flex-direction: column; 10 | gap: 16px; 11 | } 12 | 13 | .sidebar_title { 14 | font-family: "Proxima Nova", sans-serif; 15 | font-size: 16px; 16 | font-style: normal; 17 | font-weight: 600; 18 | line-height: normal; 19 | color: var(--foreground-rgb); 20 | } 21 | 22 | .option { 23 | display: flex; 24 | padding: 8px; 25 | align-items: center; 26 | gap: 4px; 27 | align-self: stretch; 28 | border-radius: 8px; 29 | cursor: pointer; 30 | color: #FFF; 31 | font-family: "Proxima Nova", sans-serif; 32 | font-size: 14px; 33 | font-style: normal; 34 | font-weight: 400; 35 | transition: background-color 0.2s ease-in-out; 36 | } 37 | 38 | .option:hover { 39 | background-color: var(--white-opacity-12); 40 | } 41 | 42 | .active { 43 | background-color: var(--white-opacity-12); 44 | } 45 | 46 | .content { 47 | flex-grow: 1; 48 | padding: 10px; 49 | } -------------------------------------------------------------------------------- /gui/src/components/CustomTag/CustomTag.tsx: -------------------------------------------------------------------------------- 1 | import CustomImage from '@/components/ImageComponents/CustomImage'; 2 | import { CustomTagProps } from '../../../types/customComponentTypes'; 3 | import styles from './tag.module.css'; 4 | 5 | export default function CustomTag({ 6 | text, 7 | icon, 8 | iconClass, 9 | iconBack, 10 | iconBackClass, 11 | color = 'grey', 12 | children, 13 | className = 'rounded-3xl', 14 | }: CustomTagProps) { 15 | const tagCSS = { 16 | grey: styles.grey_tag, 17 | purple: styles.purple_tag, 18 | yellow: styles.yellow_tag, 19 | green: styles.green_tag, 20 | red: styles.red_tag, 21 | }; 22 | 23 | return ( 24 |
28 | {icon && ( 29 | 34 | )} 35 | {text} 36 | {children} 37 | {iconBack && ( 38 | 43 | )} 44 |
45 | ); 46 | } 47 | -------------------------------------------------------------------------------- /gui/src/components/CustomTag/tag.module.css: -------------------------------------------------------------------------------- 1 | .grey_tag, 2 | .purple_tag, 3 | .green_tag, 4 | .red_tag, 5 | .yellow_tag{ 6 | display: flex; 7 | padding: 6px 8px; 8 | align-items: center; 9 | gap: 4px; 10 | color: #fff; 11 | font-family: 'Proxima Nova', sans-serif; 12 | font-size: 13px; 13 | font-style: normal; 14 | font-weight: 500; 15 | line-height: normal; 16 | } 17 | 18 | .grey_tag { 19 | /* To Do Tag */ 20 | background: #474747; 21 | } 22 | 23 | .purple_tag { 24 | /* In Progress Tag */ 25 | background: #A05BD5; 26 | } 27 | 28 | .yellow_tag { 29 | /* In Review */ 30 | background: #AA7C23; 31 | } 32 | 33 | .green_tag { 34 | /* Done Tag */ 35 | background: linear-gradient(0deg, rgb(0 0 0 / 40%) 0%, rgb(0 0 0 / 40%) 100%), 36 | #4bac1c; 37 | } 38 | 39 | .red_tag{ 40 | background: #6d2a29; 41 | } 42 | -------------------------------------------------------------------------------- /gui/src/components/CustomTimeline/CustomTimeline.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import styles from './timeline.module.css'; 3 | 4 | interface TimelineItem { 5 | id: number; 6 | content: string; 7 | timestamp: string; 8 | } 9 | 10 | interface CustomTimelineProps { 11 | items: TimelineItem[]; 12 | } 13 | 14 | export default function CustomTimeline({ items }: CustomTimelineProps) { 15 | return ( 16 |
20 |
21 | {items.map((item) => ( 22 |
23 |
24 |
25 | {item.content} 26 |
{item.timestamp}
27 |
28 |
29 | ))} 30 |
31 | ); 32 | } 33 | -------------------------------------------------------------------------------- /gui/src/components/CustomTimeline/timeline.module.css: -------------------------------------------------------------------------------- 1 | .timeline_container { 2 | display: flex; 3 | flex-direction: column; 4 | align-items: flex-start; 5 | overflow-y: auto; 6 | height: 100%; 7 | width: 100%; 8 | padding: 20px; 9 | position: relative; 10 | } 11 | 12 | .line { 13 | position: absolute; 14 | top: 0; 15 | bottom: 0; 16 | left: 20px; 17 | width: 2px; 18 | background-color: #555; 19 | z-index: 1; 20 | } 21 | 22 | .timeline_item_container { 23 | display: flex; 24 | align-items: flex-start; 25 | margin: 20px 0; 26 | position: relative; 27 | padding-left: 20px; 28 | z-index: 2; 29 | } 30 | 31 | .bullet { 32 | width: 8px; 33 | height: 8px; 34 | background-color: #888; 35 | border-radius: 50%; 36 | position: absolute; 37 | left: -3px; 38 | top: 6px; 39 | z-index: 3; 40 | } 41 | 42 | .content { 43 | background-color: #2e2e2e; 44 | color: #cfcfcf; 45 | padding: 10px 15px; 46 | border-radius: 5px; 47 | word-wrap: break-word; 48 | box-shadow: 0 0 10px rgb(0 0 0 / 50%); 49 | border-left: 3px solid #555; 50 | } 51 | 52 | .timestamp { 53 | margin-left: 10px; 54 | color: #888; 55 | font-size: 0.8em; 56 | align-self: flex-end; 57 | } 58 | -------------------------------------------------------------------------------- /gui/src/components/HomeComponents/home.module.css: -------------------------------------------------------------------------------- 1 | .bg_color { 2 | border-radius: 10px; 3 | background: var(--layout-bg-color); 4 | backdrop-filter: blur(50px); 5 | } 6 | 7 | .card_container { 8 | border-radius: 8px; 9 | background: var(--white-opacity-4); 10 | } 11 | 12 | .gradient_effect { 13 | position: absolute; 14 | border-radius: 424px; 15 | background: var(--landing-page-gradient-color); 16 | filter: blur(220px); 17 | width: 300px; 18 | height: 240px; 19 | top: -100px; 20 | } 21 | 22 | .divider { 23 | background: var(--white-opacity-8); 24 | } -------------------------------------------------------------------------------- /gui/src/components/ImageComponents/CustomImage.tsx: -------------------------------------------------------------------------------- 1 | import Image from 'next/image'; 2 | import { CustomImageProps } from '../../../types/imageComponentsTypes'; 3 | 4 | export default function CustomImage({ 5 | className, 6 | src, 7 | alt, 8 | priority = false, 9 | onClick, 10 | }: CustomImageProps) { 11 | return ( 12 | {alt} 22 | ); 23 | } 24 | -------------------------------------------------------------------------------- /gui/src/components/ImageComponents/CustomTextImage.tsx: -------------------------------------------------------------------------------- 1 | import { CustomTextImageProps } from '../../../types/imageComponentsTypes'; 2 | import CustomImage from '@/components/ImageComponents/CustomImage'; 3 | 4 | export default function CustomTextImage({ 5 | gap, 6 | textCSS, 7 | text, 8 | imageCSS, 9 | src, 10 | alt, 11 | priority, 12 | }: CustomTextImageProps) { 13 | return ( 14 |
15 | 21 | {text} 22 |
23 | ); 24 | } 25 | -------------------------------------------------------------------------------- /gui/src/components/ImageComponents/image.module.css: -------------------------------------------------------------------------------- 1 | .image_option_selected { 2 | border-radius: 12px; 3 | border: 2.296px solid var(--selected-image-border-color); 4 | cursor: pointer; 5 | transition: opacity 0.3s ease-in-out; 6 | } 7 | 8 | .image_option { 9 | opacity: 0.4; 10 | transition: opacity 0.3s ease-in-out; 11 | } 12 | -------------------------------------------------------------------------------- /gui/src/components/LayoutComponents/style.css: -------------------------------------------------------------------------------- 1 | .navbar { 2 | background-color: var(--layout-bg-color); 3 | color: white; 4 | height: 50px; 5 | display: flex; 6 | flex-direction: row; 7 | align-items: center; 8 | padding: 8px; 9 | } 10 | 11 | .sidebar { 12 | background-color: var(--layout-bg-color); 13 | padding: 4px 8px; 14 | display: flex; 15 | flex-direction: column; 16 | align-items: center; 17 | gap: 8px; 18 | } 19 | 20 | .sidebar_item, 21 | .sidebar_item_selected { 22 | border-radius: 8px; 23 | display: flex; 24 | flex-direction: column; 25 | padding: 8px 10px; 26 | gap: 4px; 27 | align-self: stretch; 28 | cursor: pointer; 29 | width: 66px; 30 | } 31 | 32 | .sidebar_item_selected { 33 | background: var(--sidebar-item-selected); 34 | } 35 | 36 | .initial_circle { 37 | display: flex; 38 | width: 32px; 39 | height: 32px; 40 | padding: 0 7px; 41 | justify-content: center; 42 | align-items: center; 43 | gap: 2px; 44 | border-radius: 50px; 45 | background: rgb(255 255 255 / 20%); 46 | } 47 | -------------------------------------------------------------------------------- /gui/src/components/StoryComponents/InputSection.tsx: -------------------------------------------------------------------------------- 1 | import React, { forwardRef } from 'react'; 2 | import { InputSectionProps } from '../../../types/storyTypes'; 3 | 4 | const InputSection = forwardRef< 5 | HTMLTextAreaElement | HTMLInputElement, 6 | InputSectionProps 7 | >(({ id, label, type = 'text', isTextArea = false, placeholder }, ref) => ( 8 |
9 | {label} 10 | 11 | {isTextArea ? ( 12 |