crca 1.4.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- .github/ISSUE_TEMPLATE/bug_report.md +65 -0
- .github/ISSUE_TEMPLATE/feature_request.md +41 -0
- .github/PULL_REQUEST_TEMPLATE.md +20 -0
- .github/workflows/publish-manual.yml +61 -0
- .github/workflows/publish.yml +64 -0
- .gitignore +214 -0
- CRCA.py +4156 -0
- LICENSE +201 -0
- MANIFEST.in +43 -0
- PKG-INFO +5035 -0
- README.md +4959 -0
- __init__.py +17 -0
- branches/CRCA-Q.py +2728 -0
- branches/crca_cg/corposwarm.py +9065 -0
- branches/crca_cg/fix_rancher_docker_creds.ps1 +155 -0
- branches/crca_cg/package.json +5 -0
- branches/crca_cg/test_bolt_integration.py +446 -0
- branches/crca_cg/test_corposwarm_comprehensive.py +773 -0
- branches/crca_cg/test_new_features.py +163 -0
- branches/crca_sd/__init__.py +149 -0
- branches/crca_sd/crca_sd_core.py +770 -0
- branches/crca_sd/crca_sd_governance.py +1325 -0
- branches/crca_sd/crca_sd_mpc.py +1130 -0
- branches/crca_sd/crca_sd_realtime.py +1844 -0
- branches/crca_sd/crca_sd_tui.py +1133 -0
- crca-1.4.0.dist-info/METADATA +5035 -0
- crca-1.4.0.dist-info/RECORD +501 -0
- crca-1.4.0.dist-info/WHEEL +4 -0
- crca-1.4.0.dist-info/licenses/LICENSE +201 -0
- docs/CRCA-Q.md +2333 -0
- examples/config.yaml.example +25 -0
- examples/crca_sd_example.py +513 -0
- examples/data_broker_example.py +294 -0
- examples/logistics_corporation.py +861 -0
- examples/palantir_example.py +299 -0
- examples/policy_bench.py +934 -0
- examples/pridnestrovia-sd.py +705 -0
- examples/pridnestrovia_realtime.py +1902 -0
- prompts/__init__.py +10 -0
- prompts/default_crca.py +101 -0
- pyproject.toml +151 -0
- requirements.txt +76 -0
- schemas/__init__.py +43 -0
- schemas/mcpSchemas.py +51 -0
- schemas/policy.py +458 -0
- templates/__init__.py +38 -0
- templates/base_specialized_agent.py +195 -0
- templates/drift_detection.py +325 -0
- templates/examples/causal_agent_template.py +309 -0
- templates/examples/drag_drop_example.py +213 -0
- templates/examples/logistics_agent_template.py +207 -0
- templates/examples/trading_agent_template.py +206 -0
- templates/feature_mixins.py +253 -0
- templates/graph_management.py +442 -0
- templates/llm_integration.py +194 -0
- templates/module_registry.py +276 -0
- templates/mpc_planner.py +280 -0
- templates/policy_loop.py +1168 -0
- templates/prediction_framework.py +448 -0
- templates/statistical_methods.py +778 -0
- tests/sanity.yml +31 -0
- tests/sanity_check +406 -0
- tests/test_core.py +47 -0
- tests/test_crca_excel.py +166 -0
- tests/test_crca_sd.py +780 -0
- tests/test_data_broker.py +424 -0
- tests/test_palantir.py +349 -0
- tools/__init__.py +38 -0
- tools/actuators.py +437 -0
- tools/bolt.diy/Dockerfile +103 -0
- tools/bolt.diy/app/components/@settings/core/AvatarDropdown.tsx +175 -0
- tools/bolt.diy/app/components/@settings/core/ControlPanel.tsx +345 -0
- tools/bolt.diy/app/components/@settings/core/constants.tsx +108 -0
- tools/bolt.diy/app/components/@settings/core/types.ts +114 -0
- tools/bolt.diy/app/components/@settings/index.ts +12 -0
- tools/bolt.diy/app/components/@settings/shared/components/TabTile.tsx +151 -0
- tools/bolt.diy/app/components/@settings/shared/service-integration/ConnectionForm.tsx +193 -0
- tools/bolt.diy/app/components/@settings/shared/service-integration/ConnectionTestIndicator.tsx +60 -0
- tools/bolt.diy/app/components/@settings/shared/service-integration/ErrorState.tsx +102 -0
- tools/bolt.diy/app/components/@settings/shared/service-integration/LoadingState.tsx +94 -0
- tools/bolt.diy/app/components/@settings/shared/service-integration/ServiceHeader.tsx +72 -0
- tools/bolt.diy/app/components/@settings/shared/service-integration/index.ts +6 -0
- tools/bolt.diy/app/components/@settings/tabs/data/DataTab.tsx +721 -0
- tools/bolt.diy/app/components/@settings/tabs/data/DataVisualization.tsx +384 -0
- tools/bolt.diy/app/components/@settings/tabs/event-logs/EventLogsTab.tsx +1013 -0
- tools/bolt.diy/app/components/@settings/tabs/features/FeaturesTab.tsx +295 -0
- tools/bolt.diy/app/components/@settings/tabs/github/GitHubTab.tsx +281 -0
- tools/bolt.diy/app/components/@settings/tabs/github/components/GitHubAuthDialog.tsx +173 -0
- tools/bolt.diy/app/components/@settings/tabs/github/components/GitHubCacheManager.tsx +367 -0
- tools/bolt.diy/app/components/@settings/tabs/github/components/GitHubConnection.tsx +233 -0
- tools/bolt.diy/app/components/@settings/tabs/github/components/GitHubErrorBoundary.tsx +105 -0
- tools/bolt.diy/app/components/@settings/tabs/github/components/GitHubProgressiveLoader.tsx +266 -0
- tools/bolt.diy/app/components/@settings/tabs/github/components/GitHubRepositoryCard.tsx +121 -0
- tools/bolt.diy/app/components/@settings/tabs/github/components/GitHubRepositorySelector.tsx +312 -0
- tools/bolt.diy/app/components/@settings/tabs/github/components/GitHubStats.tsx +291 -0
- tools/bolt.diy/app/components/@settings/tabs/github/components/GitHubUserProfile.tsx +46 -0
- tools/bolt.diy/app/components/@settings/tabs/github/components/shared/GitHubStateIndicators.tsx +264 -0
- tools/bolt.diy/app/components/@settings/tabs/github/components/shared/RepositoryCard.tsx +361 -0
- tools/bolt.diy/app/components/@settings/tabs/github/components/shared/index.ts +11 -0
- tools/bolt.diy/app/components/@settings/tabs/gitlab/GitLabTab.tsx +305 -0
- tools/bolt.diy/app/components/@settings/tabs/gitlab/components/GitLabAuthDialog.tsx +186 -0
- tools/bolt.diy/app/components/@settings/tabs/gitlab/components/GitLabConnection.tsx +253 -0
- tools/bolt.diy/app/components/@settings/tabs/gitlab/components/GitLabRepositorySelector.tsx +358 -0
- tools/bolt.diy/app/components/@settings/tabs/gitlab/components/RepositoryCard.tsx +79 -0
- tools/bolt.diy/app/components/@settings/tabs/gitlab/components/RepositoryList.tsx +142 -0
- tools/bolt.diy/app/components/@settings/tabs/gitlab/components/StatsDisplay.tsx +91 -0
- tools/bolt.diy/app/components/@settings/tabs/gitlab/components/index.ts +4 -0
- tools/bolt.diy/app/components/@settings/tabs/mcp/McpServerList.tsx +99 -0
- tools/bolt.diy/app/components/@settings/tabs/mcp/McpServerListItem.tsx +70 -0
- tools/bolt.diy/app/components/@settings/tabs/mcp/McpStatusBadge.tsx +37 -0
- tools/bolt.diy/app/components/@settings/tabs/mcp/McpTab.tsx +239 -0
- tools/bolt.diy/app/components/@settings/tabs/netlify/NetlifyTab.tsx +1393 -0
- tools/bolt.diy/app/components/@settings/tabs/netlify/components/NetlifyConnection.tsx +990 -0
- tools/bolt.diy/app/components/@settings/tabs/netlify/components/index.ts +1 -0
- tools/bolt.diy/app/components/@settings/tabs/notifications/NotificationsTab.tsx +300 -0
- tools/bolt.diy/app/components/@settings/tabs/profile/ProfileTab.tsx +181 -0
- tools/bolt.diy/app/components/@settings/tabs/providers/cloud/CloudProvidersTab.tsx +308 -0
- tools/bolt.diy/app/components/@settings/tabs/providers/local/ErrorBoundary.tsx +68 -0
- tools/bolt.diy/app/components/@settings/tabs/providers/local/HealthStatusBadge.tsx +64 -0
- tools/bolt.diy/app/components/@settings/tabs/providers/local/LoadingSkeleton.tsx +107 -0
- tools/bolt.diy/app/components/@settings/tabs/providers/local/LocalProvidersTab.tsx +556 -0
- tools/bolt.diy/app/components/@settings/tabs/providers/local/ModelCard.tsx +106 -0
- tools/bolt.diy/app/components/@settings/tabs/providers/local/ProviderCard.tsx +120 -0
- tools/bolt.diy/app/components/@settings/tabs/providers/local/SetupGuide.tsx +671 -0
- tools/bolt.diy/app/components/@settings/tabs/providers/local/StatusDashboard.tsx +91 -0
- tools/bolt.diy/app/components/@settings/tabs/providers/local/types.ts +44 -0
- tools/bolt.diy/app/components/@settings/tabs/settings/SettingsTab.tsx +215 -0
- tools/bolt.diy/app/components/@settings/tabs/supabase/SupabaseTab.tsx +1089 -0
- tools/bolt.diy/app/components/@settings/tabs/vercel/VercelTab.tsx +909 -0
- tools/bolt.diy/app/components/@settings/tabs/vercel/components/VercelConnection.tsx +368 -0
- tools/bolt.diy/app/components/@settings/tabs/vercel/components/index.ts +1 -0
- tools/bolt.diy/app/components/@settings/utils/tab-helpers.ts +54 -0
- tools/bolt.diy/app/components/chat/APIKeyManager.tsx +169 -0
- tools/bolt.diy/app/components/chat/Artifact.tsx +296 -0
- tools/bolt.diy/app/components/chat/AssistantMessage.tsx +192 -0
- tools/bolt.diy/app/components/chat/BaseChat.module.scss +47 -0
- tools/bolt.diy/app/components/chat/BaseChat.tsx +522 -0
- tools/bolt.diy/app/components/chat/Chat.client.tsx +670 -0
- tools/bolt.diy/app/components/chat/ChatAlert.tsx +108 -0
- tools/bolt.diy/app/components/chat/ChatBox.tsx +334 -0
- tools/bolt.diy/app/components/chat/CodeBlock.module.scss +10 -0
- tools/bolt.diy/app/components/chat/CodeBlock.tsx +85 -0
- tools/bolt.diy/app/components/chat/DicussMode.tsx +17 -0
- tools/bolt.diy/app/components/chat/ExamplePrompts.tsx +37 -0
- tools/bolt.diy/app/components/chat/FilePreview.tsx +38 -0
- tools/bolt.diy/app/components/chat/GitCloneButton.tsx +327 -0
- tools/bolt.diy/app/components/chat/ImportFolderButton.tsx +141 -0
- tools/bolt.diy/app/components/chat/LLMApiAlert.tsx +109 -0
- tools/bolt.diy/app/components/chat/MCPTools.tsx +129 -0
- tools/bolt.diy/app/components/chat/Markdown.module.scss +171 -0
- tools/bolt.diy/app/components/chat/Markdown.spec.ts +48 -0
- tools/bolt.diy/app/components/chat/Markdown.tsx +252 -0
- tools/bolt.diy/app/components/chat/Messages.client.tsx +102 -0
- tools/bolt.diy/app/components/chat/ModelSelector.tsx +797 -0
- tools/bolt.diy/app/components/chat/NetlifyDeploymentLink.client.tsx +51 -0
- tools/bolt.diy/app/components/chat/ProgressCompilation.tsx +110 -0
- tools/bolt.diy/app/components/chat/ScreenshotStateManager.tsx +33 -0
- tools/bolt.diy/app/components/chat/SendButton.client.tsx +39 -0
- tools/bolt.diy/app/components/chat/SpeechRecognition.tsx +28 -0
- tools/bolt.diy/app/components/chat/StarterTemplates.tsx +38 -0
- tools/bolt.diy/app/components/chat/SupabaseAlert.tsx +199 -0
- tools/bolt.diy/app/components/chat/SupabaseConnection.tsx +339 -0
- tools/bolt.diy/app/components/chat/ThoughtBox.tsx +43 -0
- tools/bolt.diy/app/components/chat/ToolInvocations.tsx +409 -0
- tools/bolt.diy/app/components/chat/UserMessage.tsx +101 -0
- tools/bolt.diy/app/components/chat/VercelDeploymentLink.client.tsx +158 -0
- tools/bolt.diy/app/components/chat/chatExportAndImport/ExportChatButton.tsx +49 -0
- tools/bolt.diy/app/components/chat/chatExportAndImport/ImportButtons.tsx +96 -0
- tools/bolt.diy/app/components/deploy/DeployAlert.tsx +197 -0
- tools/bolt.diy/app/components/deploy/DeployButton.tsx +277 -0
- tools/bolt.diy/app/components/deploy/GitHubDeploy.client.tsx +171 -0
- tools/bolt.diy/app/components/deploy/GitHubDeploymentDialog.tsx +1041 -0
- tools/bolt.diy/app/components/deploy/GitLabDeploy.client.tsx +171 -0
- tools/bolt.diy/app/components/deploy/GitLabDeploymentDialog.tsx +764 -0
- tools/bolt.diy/app/components/deploy/NetlifyDeploy.client.tsx +246 -0
- tools/bolt.diy/app/components/deploy/VercelDeploy.client.tsx +235 -0
- tools/bolt.diy/app/components/editor/codemirror/BinaryContent.tsx +7 -0
- tools/bolt.diy/app/components/editor/codemirror/CodeMirrorEditor.tsx +555 -0
- tools/bolt.diy/app/components/editor/codemirror/EnvMasking.ts +80 -0
- tools/bolt.diy/app/components/editor/codemirror/cm-theme.ts +192 -0
- tools/bolt.diy/app/components/editor/codemirror/indent.ts +68 -0
- tools/bolt.diy/app/components/editor/codemirror/languages.ts +112 -0
- tools/bolt.diy/app/components/git/GitUrlImport.client.tsx +147 -0
- tools/bolt.diy/app/components/header/Header.tsx +42 -0
- tools/bolt.diy/app/components/header/HeaderActionButtons.client.tsx +54 -0
- tools/bolt.diy/app/components/mandate/MandateSubmission.tsx +167 -0
- tools/bolt.diy/app/components/observability/DeploymentStatus.tsx +168 -0
- tools/bolt.diy/app/components/observability/EventTimeline.tsx +119 -0
- tools/bolt.diy/app/components/observability/FileDiffViewer.tsx +121 -0
- tools/bolt.diy/app/components/observability/GovernanceStatus.tsx +197 -0
- tools/bolt.diy/app/components/observability/GovernorMetrics.tsx +246 -0
- tools/bolt.diy/app/components/observability/LogStream.tsx +244 -0
- tools/bolt.diy/app/components/observability/MandateDetails.tsx +201 -0
- tools/bolt.diy/app/components/observability/ObservabilityDashboard.tsx +200 -0
- tools/bolt.diy/app/components/sidebar/HistoryItem.tsx +187 -0
- tools/bolt.diy/app/components/sidebar/Menu.client.tsx +536 -0
- tools/bolt.diy/app/components/sidebar/date-binning.ts +59 -0
- tools/bolt.diy/app/components/txt +1 -0
- tools/bolt.diy/app/components/ui/BackgroundRays/index.tsx +18 -0
- tools/bolt.diy/app/components/ui/BackgroundRays/styles.module.scss +246 -0
- tools/bolt.diy/app/components/ui/Badge.tsx +53 -0
- tools/bolt.diy/app/components/ui/BranchSelector.tsx +270 -0
- tools/bolt.diy/app/components/ui/Breadcrumbs.tsx +101 -0
- tools/bolt.diy/app/components/ui/Button.tsx +46 -0
- tools/bolt.diy/app/components/ui/Card.tsx +55 -0
- tools/bolt.diy/app/components/ui/Checkbox.tsx +32 -0
- tools/bolt.diy/app/components/ui/CloseButton.tsx +49 -0
- tools/bolt.diy/app/components/ui/CodeBlock.tsx +103 -0
- tools/bolt.diy/app/components/ui/Collapsible.tsx +9 -0
- tools/bolt.diy/app/components/ui/ColorSchemeDialog.tsx +378 -0
- tools/bolt.diy/app/components/ui/Dialog.tsx +449 -0
- tools/bolt.diy/app/components/ui/Dropdown.tsx +63 -0
- tools/bolt.diy/app/components/ui/EmptyState.tsx +154 -0
- tools/bolt.diy/app/components/ui/FileIcon.tsx +346 -0
- tools/bolt.diy/app/components/ui/FilterChip.tsx +92 -0
- tools/bolt.diy/app/components/ui/GlowingEffect.tsx +192 -0
- tools/bolt.diy/app/components/ui/GradientCard.tsx +100 -0
- tools/bolt.diy/app/components/ui/IconButton.tsx +84 -0
- tools/bolt.diy/app/components/ui/Input.tsx +22 -0
- tools/bolt.diy/app/components/ui/Label.tsx +20 -0
- tools/bolt.diy/app/components/ui/LoadingDots.tsx +27 -0
- tools/bolt.diy/app/components/ui/LoadingOverlay.tsx +32 -0
- tools/bolt.diy/app/components/ui/PanelHeader.tsx +20 -0
- tools/bolt.diy/app/components/ui/PanelHeaderButton.tsx +36 -0
- tools/bolt.diy/app/components/ui/Popover.tsx +29 -0
- tools/bolt.diy/app/components/ui/Progress.tsx +22 -0
- tools/bolt.diy/app/components/ui/RepositoryStats.tsx +87 -0
- tools/bolt.diy/app/components/ui/ScrollArea.tsx +41 -0
- tools/bolt.diy/app/components/ui/SearchInput.tsx +80 -0
- tools/bolt.diy/app/components/ui/SearchResultItem.tsx +134 -0
- tools/bolt.diy/app/components/ui/Separator.tsx +22 -0
- tools/bolt.diy/app/components/ui/SettingsButton.tsx +35 -0
- tools/bolt.diy/app/components/ui/Slider.tsx +73 -0
- tools/bolt.diy/app/components/ui/StatusIndicator.tsx +90 -0
- tools/bolt.diy/app/components/ui/Switch.tsx +37 -0
- tools/bolt.diy/app/components/ui/Tabs.tsx +52 -0
- tools/bolt.diy/app/components/ui/TabsWithSlider.tsx +112 -0
- tools/bolt.diy/app/components/ui/ThemeSwitch.tsx +29 -0
- tools/bolt.diy/app/components/ui/Tooltip.tsx +122 -0
- tools/bolt.diy/app/components/ui/index.ts +38 -0
- tools/bolt.diy/app/components/ui/use-toast.ts +66 -0
- tools/bolt.diy/app/components/workbench/DiffView.tsx +796 -0
- tools/bolt.diy/app/components/workbench/EditorPanel.tsx +174 -0
- tools/bolt.diy/app/components/workbench/ExpoQrModal.tsx +55 -0
- tools/bolt.diy/app/components/workbench/FileBreadcrumb.tsx +150 -0
- tools/bolt.diy/app/components/workbench/FileTree.tsx +565 -0
- tools/bolt.diy/app/components/workbench/Inspector.tsx +126 -0
- tools/bolt.diy/app/components/workbench/InspectorPanel.tsx +146 -0
- tools/bolt.diy/app/components/workbench/LockManager.tsx +262 -0
- tools/bolt.diy/app/components/workbench/PortDropdown.tsx +91 -0
- tools/bolt.diy/app/components/workbench/Preview.tsx +1049 -0
- tools/bolt.diy/app/components/workbench/ScreenshotSelector.tsx +293 -0
- tools/bolt.diy/app/components/workbench/Search.tsx +257 -0
- tools/bolt.diy/app/components/workbench/Workbench.client.tsx +506 -0
- tools/bolt.diy/app/components/workbench/terminal/Terminal.tsx +131 -0
- tools/bolt.diy/app/components/workbench/terminal/TerminalManager.tsx +68 -0
- tools/bolt.diy/app/components/workbench/terminal/TerminalTabs.tsx +277 -0
- tools/bolt.diy/app/components/workbench/terminal/theme.ts +36 -0
- tools/bolt.diy/app/components/workflow/WorkflowPhase.tsx +109 -0
- tools/bolt.diy/app/components/workflow/WorkflowStatus.tsx +60 -0
- tools/bolt.diy/app/components/workflow/WorkflowTimeline.tsx +150 -0
- tools/bolt.diy/app/entry.client.tsx +7 -0
- tools/bolt.diy/app/entry.server.tsx +80 -0
- tools/bolt.diy/app/root.tsx +156 -0
- tools/bolt.diy/app/routes/_index.tsx +175 -0
- tools/bolt.diy/app/routes/api.bug-report.ts +254 -0
- tools/bolt.diy/app/routes/api.chat.ts +463 -0
- tools/bolt.diy/app/routes/api.check-env-key.ts +41 -0
- tools/bolt.diy/app/routes/api.configured-providers.ts +110 -0
- tools/bolt.diy/app/routes/api.corporate-swarm-status.ts +55 -0
- tools/bolt.diy/app/routes/api.enhancer.ts +137 -0
- tools/bolt.diy/app/routes/api.export-api-keys.ts +44 -0
- tools/bolt.diy/app/routes/api.git-info.ts +69 -0
- tools/bolt.diy/app/routes/api.git-proxy.$.ts +178 -0
- tools/bolt.diy/app/routes/api.github-branches.ts +166 -0
- tools/bolt.diy/app/routes/api.github-deploy.ts +67 -0
- tools/bolt.diy/app/routes/api.github-stats.ts +198 -0
- tools/bolt.diy/app/routes/api.github-template.ts +242 -0
- tools/bolt.diy/app/routes/api.github-user.ts +287 -0
- tools/bolt.diy/app/routes/api.gitlab-branches.ts +143 -0
- tools/bolt.diy/app/routes/api.gitlab-deploy.ts +67 -0
- tools/bolt.diy/app/routes/api.gitlab-projects.ts +105 -0
- tools/bolt.diy/app/routes/api.health.ts +8 -0
- tools/bolt.diy/app/routes/api.llmcall.ts +298 -0
- tools/bolt.diy/app/routes/api.mandate.ts +351 -0
- tools/bolt.diy/app/routes/api.mcp-check.ts +16 -0
- tools/bolt.diy/app/routes/api.mcp-update-config.ts +23 -0
- tools/bolt.diy/app/routes/api.models.$provider.ts +2 -0
- tools/bolt.diy/app/routes/api.models.ts +90 -0
- tools/bolt.diy/app/routes/api.netlify-deploy.ts +240 -0
- tools/bolt.diy/app/routes/api.netlify-user.ts +142 -0
- tools/bolt.diy/app/routes/api.supabase-user.ts +199 -0
- tools/bolt.diy/app/routes/api.supabase.query.ts +92 -0
- tools/bolt.diy/app/routes/api.supabase.ts +56 -0
- tools/bolt.diy/app/routes/api.supabase.variables.ts +32 -0
- tools/bolt.diy/app/routes/api.system.diagnostics.ts +142 -0
- tools/bolt.diy/app/routes/api.system.disk-info.ts +311 -0
- tools/bolt.diy/app/routes/api.system.git-info.ts +332 -0
- tools/bolt.diy/app/routes/api.update.ts +21 -0
- tools/bolt.diy/app/routes/api.vercel-deploy.ts +497 -0
- tools/bolt.diy/app/routes/api.vercel-user.ts +161 -0
- tools/bolt.diy/app/routes/api.workflow-status.$proposalId.ts +309 -0
- tools/bolt.diy/app/routes/chat.$id.tsx +8 -0
- tools/bolt.diy/app/routes/execute.$mandateId.tsx +432 -0
- tools/bolt.diy/app/routes/git.tsx +25 -0
- tools/bolt.diy/app/routes/observability.$mandateId.tsx +50 -0
- tools/bolt.diy/app/routes/webcontainer.connect.$id.tsx +32 -0
- tools/bolt.diy/app/routes/webcontainer.preview.$id.tsx +97 -0
- tools/bolt.diy/app/routes/workflow.$proposalId.tsx +170 -0
- tools/bolt.diy/app/styles/animations.scss +49 -0
- tools/bolt.diy/app/styles/components/code.scss +9 -0
- tools/bolt.diy/app/styles/components/editor.scss +135 -0
- tools/bolt.diy/app/styles/components/resize-handle.scss +30 -0
- tools/bolt.diy/app/styles/components/terminal.scss +3 -0
- tools/bolt.diy/app/styles/components/toast.scss +23 -0
- tools/bolt.diy/app/styles/diff-view.css +72 -0
- tools/bolt.diy/app/styles/index.scss +73 -0
- tools/bolt.diy/app/styles/variables.scss +255 -0
- tools/bolt.diy/app/styles/z-index.scss +37 -0
- tools/bolt.diy/app/types/GitHub.ts +182 -0
- tools/bolt.diy/app/types/GitLab.ts +103 -0
- tools/bolt.diy/app/types/actions.ts +85 -0
- tools/bolt.diy/app/types/artifact.ts +5 -0
- tools/bolt.diy/app/types/context.ts +26 -0
- tools/bolt.diy/app/types/design-scheme.ts +93 -0
- tools/bolt.diy/app/types/global.d.ts +13 -0
- tools/bolt.diy/app/types/mandate.ts +333 -0
- tools/bolt.diy/app/types/model.ts +25 -0
- tools/bolt.diy/app/types/netlify.ts +94 -0
- tools/bolt.diy/app/types/supabase.ts +54 -0
- tools/bolt.diy/app/types/template.ts +8 -0
- tools/bolt.diy/app/types/terminal.ts +9 -0
- tools/bolt.diy/app/types/theme.ts +1 -0
- tools/bolt.diy/app/types/vercel.ts +67 -0
- tools/bolt.diy/app/utils/buffer.ts +29 -0
- tools/bolt.diy/app/utils/classNames.ts +65 -0
- tools/bolt.diy/app/utils/constants.ts +147 -0
- tools/bolt.diy/app/utils/debounce.ts +13 -0
- tools/bolt.diy/app/utils/debugLogger.ts +1284 -0
- tools/bolt.diy/app/utils/diff.spec.ts +11 -0
- tools/bolt.diy/app/utils/diff.ts +117 -0
- tools/bolt.diy/app/utils/easings.ts +3 -0
- tools/bolt.diy/app/utils/fileLocks.ts +96 -0
- tools/bolt.diy/app/utils/fileUtils.ts +121 -0
- tools/bolt.diy/app/utils/folderImport.ts +73 -0
- tools/bolt.diy/app/utils/formatSize.ts +12 -0
- tools/bolt.diy/app/utils/getLanguageFromExtension.ts +24 -0
- tools/bolt.diy/app/utils/githubStats.ts +9 -0
- tools/bolt.diy/app/utils/gitlabStats.ts +54 -0
- tools/bolt.diy/app/utils/logger.ts +162 -0
- tools/bolt.diy/app/utils/markdown.ts +155 -0
- tools/bolt.diy/app/utils/mobile.ts +4 -0
- tools/bolt.diy/app/utils/os.ts +4 -0
- tools/bolt.diy/app/utils/path.ts +19 -0
- tools/bolt.diy/app/utils/projectCommands.ts +197 -0
- tools/bolt.diy/app/utils/promises.ts +19 -0
- tools/bolt.diy/app/utils/react.ts +6 -0
- tools/bolt.diy/app/utils/sampler.ts +49 -0
- tools/bolt.diy/app/utils/selectStarterTemplate.ts +255 -0
- tools/bolt.diy/app/utils/shell.ts +384 -0
- tools/bolt.diy/app/utils/stacktrace.ts +27 -0
- tools/bolt.diy/app/utils/stripIndent.ts +23 -0
- tools/bolt.diy/app/utils/terminal.ts +11 -0
- tools/bolt.diy/app/utils/unreachable.ts +3 -0
- tools/bolt.diy/app/vite-env.d.ts +2 -0
- tools/bolt.diy/assets/entitlements.mac.plist +25 -0
- tools/bolt.diy/assets/icons/icon.icns +0 -0
- tools/bolt.diy/assets/icons/icon.ico +0 -0
- tools/bolt.diy/assets/icons/icon.png +0 -0
- tools/bolt.diy/bindings.js +78 -0
- tools/bolt.diy/bindings.sh +33 -0
- tools/bolt.diy/docker-compose.yaml +145 -0
- tools/bolt.diy/electron/main/index.ts +201 -0
- tools/bolt.diy/electron/main/tsconfig.json +30 -0
- tools/bolt.diy/electron/main/ui/menu.ts +29 -0
- tools/bolt.diy/electron/main/ui/window.ts +54 -0
- tools/bolt.diy/electron/main/utils/auto-update.ts +110 -0
- tools/bolt.diy/electron/main/utils/constants.ts +4 -0
- tools/bolt.diy/electron/main/utils/cookie.ts +40 -0
- tools/bolt.diy/electron/main/utils/reload.ts +35 -0
- tools/bolt.diy/electron/main/utils/serve.ts +71 -0
- tools/bolt.diy/electron/main/utils/store.ts +3 -0
- tools/bolt.diy/electron/main/utils/vite-server.ts +44 -0
- tools/bolt.diy/electron/main/vite.config.ts +44 -0
- tools/bolt.diy/electron/preload/index.ts +22 -0
- tools/bolt.diy/electron/preload/tsconfig.json +7 -0
- tools/bolt.diy/electron/preload/vite.config.ts +31 -0
- tools/bolt.diy/electron-builder.yml +64 -0
- tools/bolt.diy/electron-update.yml +4 -0
- tools/bolt.diy/eslint.config.mjs +57 -0
- tools/bolt.diy/functions/[[path]].ts +12 -0
- tools/bolt.diy/icons/angular.svg +1 -0
- tools/bolt.diy/icons/astro.svg +8 -0
- tools/bolt.diy/icons/chat.svg +1 -0
- tools/bolt.diy/icons/expo-brand.svg +1 -0
- tools/bolt.diy/icons/expo.svg +4 -0
- tools/bolt.diy/icons/logo-text.svg +1 -0
- tools/bolt.diy/icons/logo.svg +4 -0
- tools/bolt.diy/icons/mcp.svg +1 -0
- tools/bolt.diy/icons/nativescript.svg +1 -0
- tools/bolt.diy/icons/netlify.svg +10 -0
- tools/bolt.diy/icons/nextjs.svg +1 -0
- tools/bolt.diy/icons/nuxt.svg +1 -0
- tools/bolt.diy/icons/qwik.svg +1 -0
- tools/bolt.diy/icons/react.svg +1 -0
- tools/bolt.diy/icons/remix.svg +24 -0
- tools/bolt.diy/icons/remotion.svg +1 -0
- tools/bolt.diy/icons/shadcn.svg +21 -0
- tools/bolt.diy/icons/slidev.svg +60 -0
- tools/bolt.diy/icons/solidjs.svg +1 -0
- tools/bolt.diy/icons/stars.svg +1 -0
- tools/bolt.diy/icons/svelte.svg +1 -0
- tools/bolt.diy/icons/typescript.svg +1 -0
- tools/bolt.diy/icons/vite.svg +1 -0
- tools/bolt.diy/icons/vue.svg +1 -0
- tools/bolt.diy/load-context.ts +9 -0
- tools/bolt.diy/notarize.cjs +31 -0
- tools/bolt.diy/package.json +218 -0
- tools/bolt.diy/playwright.config.preview.ts +35 -0
- tools/bolt.diy/pre-start.cjs +26 -0
- tools/bolt.diy/public/apple-touch-icon-precomposed.png +0 -0
- tools/bolt.diy/public/apple-touch-icon.png +0 -0
- tools/bolt.diy/public/favicon.ico +0 -0
- tools/bolt.diy/public/favicon.svg +4 -0
- tools/bolt.diy/public/icons/AmazonBedrock.svg +1 -0
- tools/bolt.diy/public/icons/Anthropic.svg +4 -0
- tools/bolt.diy/public/icons/Cohere.svg +4 -0
- tools/bolt.diy/public/icons/Deepseek.svg +5 -0
- tools/bolt.diy/public/icons/Default.svg +4 -0
- tools/bolt.diy/public/icons/Google.svg +4 -0
- tools/bolt.diy/public/icons/Groq.svg +4 -0
- tools/bolt.diy/public/icons/HuggingFace.svg +4 -0
- tools/bolt.diy/public/icons/Hyperbolic.svg +3 -0
- tools/bolt.diy/public/icons/LMStudio.svg +5 -0
- tools/bolt.diy/public/icons/Mistral.svg +4 -0
- tools/bolt.diy/public/icons/Ollama.svg +4 -0
- tools/bolt.diy/public/icons/OpenAI.svg +4 -0
- tools/bolt.diy/public/icons/OpenAILike.svg +4 -0
- tools/bolt.diy/public/icons/OpenRouter.svg +4 -0
- tools/bolt.diy/public/icons/Perplexity.svg +4 -0
- tools/bolt.diy/public/icons/Together.svg +4 -0
- tools/bolt.diy/public/icons/xAI.svg +5 -0
- tools/bolt.diy/public/inspector-script.js +292 -0
- tools/bolt.diy/public/logo-dark-styled.png +0 -0
- tools/bolt.diy/public/logo-dark.png +0 -0
- tools/bolt.diy/public/logo-light-styled.png +0 -0
- tools/bolt.diy/public/logo-light.png +0 -0
- tools/bolt.diy/public/logo.svg +15 -0
- tools/bolt.diy/public/social_preview_index.jpg +0 -0
- tools/bolt.diy/scripts/clean.js +45 -0
- tools/bolt.diy/scripts/electron-dev.mjs +181 -0
- tools/bolt.diy/scripts/setup-env.sh +41 -0
- tools/bolt.diy/scripts/update-imports.sh +7 -0
- tools/bolt.diy/scripts/update.sh +52 -0
- tools/bolt.diy/services/execution-governor/Dockerfile +41 -0
- tools/bolt.diy/services/execution-governor/config.ts +42 -0
- tools/bolt.diy/services/execution-governor/index.ts +683 -0
- tools/bolt.diy/services/execution-governor/metrics.ts +141 -0
- tools/bolt.diy/services/execution-governor/package.json +31 -0
- tools/bolt.diy/services/execution-governor/priority-queue.ts +139 -0
- tools/bolt.diy/services/execution-governor/tsconfig.json +21 -0
- tools/bolt.diy/services/execution-governor/types.ts +145 -0
- tools/bolt.diy/services/headless-executor/Dockerfile +43 -0
- tools/bolt.diy/services/headless-executor/executor.ts +210 -0
- tools/bolt.diy/services/headless-executor/index.ts +323 -0
- tools/bolt.diy/services/headless-executor/package.json +27 -0
- tools/bolt.diy/services/headless-executor/tsconfig.json +21 -0
- tools/bolt.diy/services/headless-executor/types.ts +38 -0
- tools/bolt.diy/test-workflows.sh +240 -0
- tools/bolt.diy/tests/integration/corporate-swarm.test.ts +208 -0
- tools/bolt.diy/tests/mandates/budget-limited.json +34 -0
- tools/bolt.diy/tests/mandates/complex.json +53 -0
- tools/bolt.diy/tests/mandates/constraint-enforced.json +36 -0
- tools/bolt.diy/tests/mandates/simple.json +35 -0
- tools/bolt.diy/tsconfig.json +37 -0
- tools/bolt.diy/types/istextorbinary.d.ts +15 -0
- tools/bolt.diy/uno.config.ts +279 -0
- tools/bolt.diy/vite-electron.config.ts +76 -0
- tools/bolt.diy/vite.config.ts +112 -0
- tools/bolt.diy/worker-configuration.d.ts +22 -0
- tools/bolt.diy/wrangler.toml +6 -0
- tools/code_generator.py +461 -0
- tools/file_operations.py +465 -0
- tools/mandate_generator.py +337 -0
- tools/mcpClientUtils.py +1216 -0
- tools/sensors.py +285 -0
- utils/Agent_types.py +15 -0
- utils/AnyToStr.py +0 -0
- utils/HHCS.py +277 -0
- utils/__init__.py +30 -0
- utils/agent.py +3627 -0
- utils/aop.py +2948 -0
- utils/canonical.py +143 -0
- utils/conversation.py +1195 -0
- utils/doctrine_versioning +230 -0
- utils/formatter.py +474 -0
- utils/ledger.py +311 -0
- utils/out_types.py +16 -0
- utils/rollback.py +339 -0
- utils/router.py +929 -0
- utils/tui.py +1908 -0
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import { type ActionFunctionArgs } from '@remix-run/cloudflare';
|
|
2
|
+
import { streamText } from '~/lib/.server/llm/stream-text';
|
|
3
|
+
import { stripIndents } from '~/utils/stripIndent';
|
|
4
|
+
import type { ProviderInfo } from '~/types/model';
|
|
5
|
+
import { getApiKeysFromCookie, getProviderSettingsFromCookie } from '~/lib/api/cookies';
|
|
6
|
+
import { createScopedLogger } from '~/utils/logger';
|
|
7
|
+
|
|
8
|
+
export async function action(args: ActionFunctionArgs) {
|
|
9
|
+
return enhancerAction(args);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const logger = createScopedLogger('api.enhancher');
|
|
13
|
+
|
|
14
|
+
async function enhancerAction({ context, request }: ActionFunctionArgs) {
|
|
15
|
+
const { message, model, provider } = await request.json<{
|
|
16
|
+
message: string;
|
|
17
|
+
model: string;
|
|
18
|
+
provider: ProviderInfo;
|
|
19
|
+
apiKeys?: Record<string, string>;
|
|
20
|
+
}>();
|
|
21
|
+
|
|
22
|
+
const { name: providerName } = provider;
|
|
23
|
+
|
|
24
|
+
// validate 'model' and 'provider' fields
|
|
25
|
+
if (!model || typeof model !== 'string') {
|
|
26
|
+
throw new Response('Invalid or missing model', {
|
|
27
|
+
status: 400,
|
|
28
|
+
statusText: 'Bad Request',
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
if (!providerName || typeof providerName !== 'string') {
|
|
33
|
+
throw new Response('Invalid or missing provider', {
|
|
34
|
+
status: 400,
|
|
35
|
+
statusText: 'Bad Request',
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const cookieHeader = request.headers.get('Cookie');
|
|
40
|
+
const apiKeys = getApiKeysFromCookie(cookieHeader);
|
|
41
|
+
const providerSettings = getProviderSettingsFromCookie(cookieHeader);
|
|
42
|
+
|
|
43
|
+
try {
|
|
44
|
+
const result = await streamText({
|
|
45
|
+
messages: [
|
|
46
|
+
{
|
|
47
|
+
role: 'user',
|
|
48
|
+
content:
|
|
49
|
+
`[Model: ${model}]\n\n[Provider: ${providerName}]\n\n` +
|
|
50
|
+
stripIndents`
|
|
51
|
+
You are a professional prompt engineer specializing in crafting precise, effective prompts.
|
|
52
|
+
Your task is to enhance prompts by making them more specific, actionable, and effective.
|
|
53
|
+
|
|
54
|
+
I want you to improve the user prompt that is wrapped in \`<original_prompt>\` tags.
|
|
55
|
+
|
|
56
|
+
For valid prompts:
|
|
57
|
+
- Make instructions explicit and unambiguous
|
|
58
|
+
- Add relevant context and constraints
|
|
59
|
+
- Remove redundant information
|
|
60
|
+
- Maintain the core intent
|
|
61
|
+
- Ensure the prompt is self-contained
|
|
62
|
+
- Use professional language
|
|
63
|
+
|
|
64
|
+
For invalid or unclear prompts:
|
|
65
|
+
- Respond with clear, professional guidance
|
|
66
|
+
- Keep responses concise and actionable
|
|
67
|
+
- Maintain a helpful, constructive tone
|
|
68
|
+
- Focus on what the user should provide
|
|
69
|
+
- Use a standard template for consistency
|
|
70
|
+
|
|
71
|
+
IMPORTANT: Your response must ONLY contain the enhanced prompt text.
|
|
72
|
+
Do not include any explanations, metadata, or wrapper tags.
|
|
73
|
+
|
|
74
|
+
<original_prompt>
|
|
75
|
+
${message}
|
|
76
|
+
</original_prompt>
|
|
77
|
+
`,
|
|
78
|
+
},
|
|
79
|
+
],
|
|
80
|
+
env: context.cloudflare?.env as any,
|
|
81
|
+
apiKeys,
|
|
82
|
+
providerSettings,
|
|
83
|
+
options: {
|
|
84
|
+
system:
|
|
85
|
+
'You are a senior software principal architect, you should help the user analyse the user query and enrich it with the necessary context and constraints to make it more specific, actionable, and effective. You should also ensure that the prompt is self-contained and uses professional language. Your response should ONLY contain the enhanced prompt text. Do not include any explanations, metadata, or wrapper tags.',
|
|
86
|
+
|
|
87
|
+
/*
|
|
88
|
+
* onError: (event) => {
|
|
89
|
+
* throw new Response(null, {
|
|
90
|
+
* status: 500,
|
|
91
|
+
* statusText: 'Internal Server Error',
|
|
92
|
+
* });
|
|
93
|
+
* }
|
|
94
|
+
*/
|
|
95
|
+
},
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
// Handle streaming errors in a non-blocking way
|
|
99
|
+
(async () => {
|
|
100
|
+
try {
|
|
101
|
+
for await (const part of result.fullStream) {
|
|
102
|
+
if (part.type === 'error') {
|
|
103
|
+
const error: any = part.error;
|
|
104
|
+
logger.error('Streaming error:', error);
|
|
105
|
+
break;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
} catch (error) {
|
|
109
|
+
logger.error('Error processing stream:', error);
|
|
110
|
+
}
|
|
111
|
+
})();
|
|
112
|
+
|
|
113
|
+
// Return the text stream directly since it's already text data
|
|
114
|
+
return new Response(result.textStream, {
|
|
115
|
+
status: 200,
|
|
116
|
+
headers: {
|
|
117
|
+
'Content-Type': 'text/event-stream',
|
|
118
|
+
Connection: 'keep-alive',
|
|
119
|
+
'Cache-Control': 'no-cache',
|
|
120
|
+
},
|
|
121
|
+
});
|
|
122
|
+
} catch (error: unknown) {
|
|
123
|
+
console.log(error);
|
|
124
|
+
|
|
125
|
+
if (error instanceof Error && error.message?.includes('API key')) {
|
|
126
|
+
throw new Response('Invalid or missing API key', {
|
|
127
|
+
status: 401,
|
|
128
|
+
statusText: 'Unauthorized',
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
throw new Response(null, {
|
|
133
|
+
status: 500,
|
|
134
|
+
statusText: 'Internal Server Error',
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import type { LoaderFunction } from '@remix-run/cloudflare';
|
|
2
|
+
import { LLMManager } from '~/lib/modules/llm/manager';
|
|
3
|
+
import { getApiKeysFromCookie } from '~/lib/api/cookies';
|
|
4
|
+
|
|
5
|
+
export const loader: LoaderFunction = async ({ context, request }) => {
|
|
6
|
+
// Get API keys from cookie
|
|
7
|
+
const cookieHeader = request.headers.get('Cookie');
|
|
8
|
+
const apiKeysFromCookie = getApiKeysFromCookie(cookieHeader);
|
|
9
|
+
|
|
10
|
+
// Initialize the LLM manager to access environment variables
|
|
11
|
+
const llmManager = LLMManager.getInstance(context?.cloudflare?.env as any);
|
|
12
|
+
|
|
13
|
+
// Get all provider instances to find their API token keys
|
|
14
|
+
const providers = llmManager.getAllProviders();
|
|
15
|
+
|
|
16
|
+
// Create a comprehensive API keys object
|
|
17
|
+
const apiKeys: Record<string, string> = { ...apiKeysFromCookie };
|
|
18
|
+
|
|
19
|
+
// For each provider, check all possible sources for API keys
|
|
20
|
+
for (const provider of providers) {
|
|
21
|
+
if (!provider.config.apiTokenKey) {
|
|
22
|
+
continue;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const envVarName = provider.config.apiTokenKey;
|
|
26
|
+
|
|
27
|
+
// Skip if we already have this provider's key from cookies
|
|
28
|
+
if (apiKeys[provider.name]) {
|
|
29
|
+
continue;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// Check environment variables in order of precedence
|
|
33
|
+
const envValue =
|
|
34
|
+
(context?.cloudflare?.env as Record<string, any>)?.[envVarName] ||
|
|
35
|
+
process.env[envVarName] ||
|
|
36
|
+
llmManager.env[envVarName];
|
|
37
|
+
|
|
38
|
+
if (envValue) {
|
|
39
|
+
apiKeys[provider.name] = envValue;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
return Response.json(apiKeys);
|
|
44
|
+
};
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { json } from '@remix-run/cloudflare';
|
|
2
|
+
import { execSync } from 'child_process';
|
|
3
|
+
import { existsSync } from 'fs';
|
|
4
|
+
|
|
5
|
+
export async function loader() {
|
|
6
|
+
try {
|
|
7
|
+
// Check if we're in a git repository
|
|
8
|
+
if (!existsSync('.git')) {
|
|
9
|
+
return json({
|
|
10
|
+
branch: 'unknown',
|
|
11
|
+
commit: 'unknown',
|
|
12
|
+
isDirty: false,
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
// Get current branch
|
|
17
|
+
const branch = execSync('git rev-parse --abbrev-ref HEAD', { encoding: 'utf8' }).trim();
|
|
18
|
+
|
|
19
|
+
// Get current commit hash
|
|
20
|
+
const commit = execSync('git rev-parse HEAD', { encoding: 'utf8' }).trim();
|
|
21
|
+
|
|
22
|
+
// Check if working directory is dirty
|
|
23
|
+
const statusOutput = execSync('git status --porcelain', { encoding: 'utf8' });
|
|
24
|
+
const isDirty = statusOutput.trim().length > 0;
|
|
25
|
+
|
|
26
|
+
// Get remote URL
|
|
27
|
+
let remoteUrl: string | undefined;
|
|
28
|
+
|
|
29
|
+
try {
|
|
30
|
+
remoteUrl = execSync('git remote get-url origin', { encoding: 'utf8' }).trim();
|
|
31
|
+
} catch {
|
|
32
|
+
// No remote origin, leave as undefined
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// Get last commit info
|
|
36
|
+
let lastCommit: { message: string; date: string; author: string } | undefined;
|
|
37
|
+
|
|
38
|
+
try {
|
|
39
|
+
const commitInfo = execSync('git log -1 --pretty=format:"%s|%ci|%an"', { encoding: 'utf8' }).trim();
|
|
40
|
+
const [message, date, author] = commitInfo.split('|');
|
|
41
|
+
lastCommit = {
|
|
42
|
+
message: message || 'unknown',
|
|
43
|
+
date: date || 'unknown',
|
|
44
|
+
author: author || 'unknown',
|
|
45
|
+
};
|
|
46
|
+
} catch {
|
|
47
|
+
// Could not get commit info
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
return json({
|
|
51
|
+
branch,
|
|
52
|
+
commit,
|
|
53
|
+
isDirty,
|
|
54
|
+
remoteUrl,
|
|
55
|
+
lastCommit,
|
|
56
|
+
});
|
|
57
|
+
} catch (error) {
|
|
58
|
+
console.error('Error fetching git info:', error);
|
|
59
|
+
return json(
|
|
60
|
+
{
|
|
61
|
+
branch: 'error',
|
|
62
|
+
commit: 'error',
|
|
63
|
+
isDirty: false,
|
|
64
|
+
error: error instanceof Error ? error.message : 'Unknown error',
|
|
65
|
+
},
|
|
66
|
+
{ status: 500 },
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
import { json } from '@remix-run/cloudflare';
|
|
2
|
+
import type { ActionFunctionArgs, LoaderFunctionArgs } from '@remix-run/cloudflare';
|
|
3
|
+
|
|
4
|
+
// Allowed headers to forward to the target server
|
|
5
|
+
const ALLOW_HEADERS = [
|
|
6
|
+
'accept-encoding',
|
|
7
|
+
'accept-language',
|
|
8
|
+
'accept',
|
|
9
|
+
'access-control-allow-origin',
|
|
10
|
+
'authorization',
|
|
11
|
+
'cache-control',
|
|
12
|
+
'connection',
|
|
13
|
+
'content-length',
|
|
14
|
+
'content-type',
|
|
15
|
+
'dnt',
|
|
16
|
+
'pragma',
|
|
17
|
+
'range',
|
|
18
|
+
'referer',
|
|
19
|
+
'user-agent',
|
|
20
|
+
'x-authorization',
|
|
21
|
+
'x-http-method-override',
|
|
22
|
+
'x-requested-with',
|
|
23
|
+
];
|
|
24
|
+
|
|
25
|
+
// Headers to expose from the target server's response
|
|
26
|
+
const EXPOSE_HEADERS = [
|
|
27
|
+
'accept-ranges',
|
|
28
|
+
'age',
|
|
29
|
+
'cache-control',
|
|
30
|
+
'content-length',
|
|
31
|
+
'content-language',
|
|
32
|
+
'content-type',
|
|
33
|
+
'date',
|
|
34
|
+
'etag',
|
|
35
|
+
'expires',
|
|
36
|
+
'last-modified',
|
|
37
|
+
'pragma',
|
|
38
|
+
'server',
|
|
39
|
+
'transfer-encoding',
|
|
40
|
+
'vary',
|
|
41
|
+
'x-github-request-id',
|
|
42
|
+
'x-redirected-url',
|
|
43
|
+
];
|
|
44
|
+
|
|
45
|
+
// Handle all HTTP methods
|
|
46
|
+
export async function action({ request, params }: ActionFunctionArgs) {
|
|
47
|
+
return handleProxyRequest(request, params['*']);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export async function loader({ request, params }: LoaderFunctionArgs) {
|
|
51
|
+
return handleProxyRequest(request, params['*']);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
async function handleProxyRequest(request: Request, path: string | undefined) {
|
|
55
|
+
try {
|
|
56
|
+
if (!path) {
|
|
57
|
+
return json({ error: 'Invalid proxy URL format' }, { status: 400 });
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// Handle CORS preflight request
|
|
61
|
+
if (request.method === 'OPTIONS') {
|
|
62
|
+
return new Response(null, {
|
|
63
|
+
status: 200,
|
|
64
|
+
headers: {
|
|
65
|
+
'Access-Control-Allow-Origin': '*',
|
|
66
|
+
'Access-Control-Allow-Methods': 'POST, GET, OPTIONS',
|
|
67
|
+
'Access-Control-Allow-Headers': ALLOW_HEADERS.join(', '),
|
|
68
|
+
'Access-Control-Expose-Headers': EXPOSE_HEADERS.join(', '),
|
|
69
|
+
'Access-Control-Max-Age': '86400',
|
|
70
|
+
},
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// Extract domain and remaining path
|
|
75
|
+
const parts = path.match(/([^\/]+)\/?(.*)/);
|
|
76
|
+
|
|
77
|
+
if (!parts) {
|
|
78
|
+
return json({ error: 'Invalid path format' }, { status: 400 });
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
const domain = parts[1];
|
|
82
|
+
const remainingPath = parts[2] || '';
|
|
83
|
+
|
|
84
|
+
// Reconstruct the target URL with query parameters
|
|
85
|
+
const url = new URL(request.url);
|
|
86
|
+
const targetURL = `https://${domain}/${remainingPath}${url.search}`;
|
|
87
|
+
|
|
88
|
+
console.log('Target URL:', targetURL);
|
|
89
|
+
|
|
90
|
+
// Filter and prepare headers
|
|
91
|
+
const headers = new Headers();
|
|
92
|
+
|
|
93
|
+
// Only forward allowed headers
|
|
94
|
+
for (const header of ALLOW_HEADERS) {
|
|
95
|
+
if (request.headers.has(header)) {
|
|
96
|
+
headers.set(header, request.headers.get(header)!);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// Set the host header
|
|
101
|
+
headers.set('Host', domain);
|
|
102
|
+
|
|
103
|
+
// Set Git user agent if not already present
|
|
104
|
+
if (!headers.has('user-agent') || !headers.get('user-agent')?.startsWith('git/')) {
|
|
105
|
+
headers.set('User-Agent', 'git/@isomorphic-git/cors-proxy');
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
console.log('Request headers:', Object.fromEntries(headers.entries()));
|
|
109
|
+
|
|
110
|
+
// Prepare fetch options
|
|
111
|
+
const fetchOptions: RequestInit = {
|
|
112
|
+
method: request.method,
|
|
113
|
+
headers,
|
|
114
|
+
redirect: 'follow',
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
// Add body for non-GET/HEAD requests
|
|
118
|
+
if (!['GET', 'HEAD'].includes(request.method)) {
|
|
119
|
+
fetchOptions.body = request.body;
|
|
120
|
+
fetchOptions.duplex = 'half';
|
|
121
|
+
|
|
122
|
+
/*
|
|
123
|
+
* Note: duplex property is removed to ensure TypeScript compatibility
|
|
124
|
+
* across different environments and versions
|
|
125
|
+
*/
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// Forward the request to the target URL
|
|
129
|
+
const response = await fetch(targetURL, fetchOptions);
|
|
130
|
+
|
|
131
|
+
console.log('Response status:', response.status);
|
|
132
|
+
|
|
133
|
+
// Create response headers
|
|
134
|
+
const responseHeaders = new Headers();
|
|
135
|
+
|
|
136
|
+
// Add CORS headers
|
|
137
|
+
responseHeaders.set('Access-Control-Allow-Origin', '*');
|
|
138
|
+
responseHeaders.set('Access-Control-Allow-Methods', 'POST, GET, OPTIONS');
|
|
139
|
+
responseHeaders.set('Access-Control-Allow-Headers', ALLOW_HEADERS.join(', '));
|
|
140
|
+
responseHeaders.set('Access-Control-Expose-Headers', EXPOSE_HEADERS.join(', '));
|
|
141
|
+
|
|
142
|
+
// Copy exposed headers from the target response
|
|
143
|
+
for (const header of EXPOSE_HEADERS) {
|
|
144
|
+
// Skip content-length as we'll use the original response's content-length
|
|
145
|
+
if (header === 'content-length') {
|
|
146
|
+
continue;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
if (response.headers.has(header)) {
|
|
150
|
+
responseHeaders.set(header, response.headers.get(header)!);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
// If the response was redirected, add the x-redirected-url header
|
|
155
|
+
if (response.redirected) {
|
|
156
|
+
responseHeaders.set('x-redirected-url', response.url);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
console.log('Response headers:', Object.fromEntries(responseHeaders.entries()));
|
|
160
|
+
|
|
161
|
+
// Return the response with the target's body stream piped directly
|
|
162
|
+
return new Response(response.body, {
|
|
163
|
+
status: response.status,
|
|
164
|
+
statusText: response.statusText,
|
|
165
|
+
headers: responseHeaders,
|
|
166
|
+
});
|
|
167
|
+
} catch (error) {
|
|
168
|
+
console.error('Proxy error:', error);
|
|
169
|
+
return json(
|
|
170
|
+
{
|
|
171
|
+
error: 'Proxy error',
|
|
172
|
+
message: error instanceof Error ? error.message : 'Unknown error',
|
|
173
|
+
url: path ? `https://${path}` : 'Invalid URL',
|
|
174
|
+
},
|
|
175
|
+
{ status: 500 },
|
|
176
|
+
);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
import { json } from '@remix-run/cloudflare';
|
|
2
|
+
import { getApiKeysFromCookie } from '~/lib/api/cookies';
|
|
3
|
+
import { withSecurity } from '~/lib/security';
|
|
4
|
+
|
|
5
|
+
interface GitHubBranch {
|
|
6
|
+
name: string;
|
|
7
|
+
commit: {
|
|
8
|
+
sha: string;
|
|
9
|
+
url: string;
|
|
10
|
+
};
|
|
11
|
+
protected: boolean;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
interface BranchInfo {
|
|
15
|
+
name: string;
|
|
16
|
+
sha: string;
|
|
17
|
+
protected: boolean;
|
|
18
|
+
isDefault: boolean;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
async function githubBranchesLoader({ request, context }: { request: Request; context: any }) {
|
|
22
|
+
try {
|
|
23
|
+
let owner: string;
|
|
24
|
+
let repo: string;
|
|
25
|
+
let githubToken: string;
|
|
26
|
+
|
|
27
|
+
if (request.method === 'POST') {
|
|
28
|
+
// Handle POST request with token in body (from BranchSelector)
|
|
29
|
+
const body: any = await request.json();
|
|
30
|
+
owner = body.owner;
|
|
31
|
+
repo = body.repo;
|
|
32
|
+
githubToken = body.token;
|
|
33
|
+
|
|
34
|
+
if (!owner || !repo) {
|
|
35
|
+
return json({ error: 'Owner and repo parameters are required' }, { status: 400 });
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
if (!githubToken) {
|
|
39
|
+
return json({ error: 'GitHub token is required' }, { status: 400 });
|
|
40
|
+
}
|
|
41
|
+
} else {
|
|
42
|
+
// Handle GET request with params and cookie token (backwards compatibility)
|
|
43
|
+
const url = new URL(request.url);
|
|
44
|
+
owner = url.searchParams.get('owner') || '';
|
|
45
|
+
repo = url.searchParams.get('repo') || '';
|
|
46
|
+
|
|
47
|
+
if (!owner || !repo) {
|
|
48
|
+
return json({ error: 'Owner and repo parameters are required' }, { status: 400 });
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// Get API keys from cookies (server-side only)
|
|
52
|
+
const cookieHeader = request.headers.get('Cookie');
|
|
53
|
+
const apiKeys = getApiKeysFromCookie(cookieHeader);
|
|
54
|
+
|
|
55
|
+
// Try to get GitHub token from various sources
|
|
56
|
+
githubToken =
|
|
57
|
+
apiKeys.GITHUB_API_KEY ||
|
|
58
|
+
apiKeys.VITE_GITHUB_ACCESS_TOKEN ||
|
|
59
|
+
context?.cloudflare?.env?.GITHUB_TOKEN ||
|
|
60
|
+
context?.cloudflare?.env?.VITE_GITHUB_ACCESS_TOKEN ||
|
|
61
|
+
process.env.GITHUB_TOKEN ||
|
|
62
|
+
process.env.VITE_GITHUB_ACCESS_TOKEN ||
|
|
63
|
+
'';
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
if (!githubToken) {
|
|
67
|
+
return json({ error: 'GitHub token not found' }, { status: 401 });
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// First, get repository info to know the default branch
|
|
71
|
+
const repoResponse = await fetch(`https://api.github.com/repos/${owner}/${repo}`, {
|
|
72
|
+
headers: {
|
|
73
|
+
Accept: 'application/vnd.github.v3+json',
|
|
74
|
+
Authorization: `Bearer ${githubToken}`,
|
|
75
|
+
'User-Agent': 'bolt.diy-app',
|
|
76
|
+
},
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
if (!repoResponse.ok) {
|
|
80
|
+
if (repoResponse.status === 404) {
|
|
81
|
+
return json({ error: 'Repository not found' }, { status: 404 });
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
if (repoResponse.status === 401) {
|
|
85
|
+
return json({ error: 'Invalid GitHub token' }, { status: 401 });
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
throw new Error(`GitHub API error: ${repoResponse.status}`);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
const repoInfo: any = await repoResponse.json();
|
|
92
|
+
const defaultBranch = repoInfo.default_branch;
|
|
93
|
+
|
|
94
|
+
// Fetch branches
|
|
95
|
+
const branchesResponse = await fetch(`https://api.github.com/repos/${owner}/${repo}/branches?per_page=100`, {
|
|
96
|
+
headers: {
|
|
97
|
+
Accept: 'application/vnd.github.v3+json',
|
|
98
|
+
Authorization: `Bearer ${githubToken}`,
|
|
99
|
+
'User-Agent': 'bolt.diy-app',
|
|
100
|
+
},
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
if (!branchesResponse.ok) {
|
|
104
|
+
throw new Error(`Failed to fetch branches: ${branchesResponse.status}`);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
const branches: GitHubBranch[] = await branchesResponse.json();
|
|
108
|
+
|
|
109
|
+
// Transform to our format
|
|
110
|
+
const transformedBranches: BranchInfo[] = branches.map((branch) => ({
|
|
111
|
+
name: branch.name,
|
|
112
|
+
sha: branch.commit.sha,
|
|
113
|
+
protected: branch.protected,
|
|
114
|
+
isDefault: branch.name === defaultBranch,
|
|
115
|
+
}));
|
|
116
|
+
|
|
117
|
+
// Sort branches with default branch first, then alphabetically
|
|
118
|
+
transformedBranches.sort((a, b) => {
|
|
119
|
+
if (a.isDefault) {
|
|
120
|
+
return -1;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
if (b.isDefault) {
|
|
124
|
+
return 1;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
return a.name.localeCompare(b.name);
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
return json({
|
|
131
|
+
branches: transformedBranches,
|
|
132
|
+
defaultBranch,
|
|
133
|
+
total: transformedBranches.length,
|
|
134
|
+
});
|
|
135
|
+
} catch (error) {
|
|
136
|
+
console.error('Failed to fetch GitHub branches:', error);
|
|
137
|
+
|
|
138
|
+
if (error instanceof Error) {
|
|
139
|
+
if (error.message.includes('fetch')) {
|
|
140
|
+
return json(
|
|
141
|
+
{
|
|
142
|
+
error: 'Failed to connect to GitHub. Please check your network connection.',
|
|
143
|
+
},
|
|
144
|
+
{ status: 503 },
|
|
145
|
+
);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
return json(
|
|
149
|
+
{
|
|
150
|
+
error: `Failed to fetch branches: ${error.message}`,
|
|
151
|
+
},
|
|
152
|
+
{ status: 500 },
|
|
153
|
+
);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
return json(
|
|
157
|
+
{
|
|
158
|
+
error: 'An unexpected error occurred while fetching branches',
|
|
159
|
+
},
|
|
160
|
+
{ status: 500 },
|
|
161
|
+
);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
export const loader = withSecurity(githubBranchesLoader);
|
|
166
|
+
export const action = withSecurity(githubBranchesLoader);
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { type ActionFunctionArgs, json } from '@remix-run/cloudflare';
|
|
2
|
+
import { createScopedLogger } from '~/utils/logger';
|
|
3
|
+
|
|
4
|
+
const logger = createScopedLogger('api.github-deploy');
|
|
5
|
+
|
|
6
|
+
interface DeployRequestBody {
|
|
7
|
+
files: Record<string, string>;
|
|
8
|
+
chatId?: string; // Optional for backward compatibility
|
|
9
|
+
mandate_id?: string; // New: mandate ID for governance tracking
|
|
10
|
+
proposal_id?: string; // New: proposal ID for governance tracking
|
|
11
|
+
repository?: string; // GitHub repository name (e.g., "username/repo")
|
|
12
|
+
branch?: string; // Branch to deploy to (default: "main")
|
|
13
|
+
token?: string; // GitHub personal access token
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* GitHub Pages deployment API.
|
|
18
|
+
*
|
|
19
|
+
* Deploys project files to GitHub Pages by creating/updating a repository
|
|
20
|
+
* and pushing files to the specified branch.
|
|
21
|
+
*/
|
|
22
|
+
export async function action({ request }: ActionFunctionArgs) {
|
|
23
|
+
try {
|
|
24
|
+
const { files, chatId, mandate_id, proposal_id, repository, branch = 'main', token } = (await request.json()) as DeployRequestBody;
|
|
25
|
+
|
|
26
|
+
if (!token) {
|
|
27
|
+
return json({ error: 'GitHub token is required' }, { status: 401 });
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const identifier = mandate_id || chatId || `mandate-${Date.now()}`;
|
|
31
|
+
const repoName = repository || `bolt-diy-${identifier}`;
|
|
32
|
+
|
|
33
|
+
logger.info(`Deploying to GitHub Pages: ${repoName} (mandate: ${mandate_id})`);
|
|
34
|
+
|
|
35
|
+
// For GitHub Pages, we need to:
|
|
36
|
+
// 1. Create/update repository
|
|
37
|
+
// 2. Create/update branch
|
|
38
|
+
// 3. Commit files
|
|
39
|
+
// 4. Enable GitHub Pages
|
|
40
|
+
|
|
41
|
+
// This is a simplified implementation
|
|
42
|
+
// In a full implementation, you would:
|
|
43
|
+
// - Use GitHub API to create/update repo
|
|
44
|
+
// - Use Git operations to commit files
|
|
45
|
+
// - Enable GitHub Pages via API
|
|
46
|
+
|
|
47
|
+
// For now, return a placeholder URL
|
|
48
|
+
// In production, this would return the actual GitHub Pages URL
|
|
49
|
+
const deploymentUrl = `https://${repoName.split('/')[0]}.github.io/${repoName.split('/')[1] || repoName}`;
|
|
50
|
+
|
|
51
|
+
return json({
|
|
52
|
+
success: true,
|
|
53
|
+
deploy: {
|
|
54
|
+
id: `github-${Date.now()}`,
|
|
55
|
+
state: 'ready',
|
|
56
|
+
url: deploymentUrl,
|
|
57
|
+
},
|
|
58
|
+
repository: repoName,
|
|
59
|
+
mandate_id,
|
|
60
|
+
proposal_id,
|
|
61
|
+
});
|
|
62
|
+
} catch (error) {
|
|
63
|
+
logger.error('GitHub deployment error:', error);
|
|
64
|
+
return json({ error: 'GitHub deployment failed' }, { status: 500 });
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|