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,255 @@
|
|
|
1
|
+
import ignore from 'ignore';
|
|
2
|
+
import type { ProviderInfo } from '~/types/model';
|
|
3
|
+
import type { Template } from '~/types/template';
|
|
4
|
+
import { STARTER_TEMPLATES } from './constants';
|
|
5
|
+
|
|
6
|
+
const starterTemplateSelectionPrompt = (templates: Template[]) => `
|
|
7
|
+
You are an experienced developer who helps people choose the best starter template for their projects.
|
|
8
|
+
IMPORTANT: Vite is preferred
|
|
9
|
+
IMPORTANT: Only choose shadcn templates if the user explicitly asks for shadcn.
|
|
10
|
+
|
|
11
|
+
Available templates:
|
|
12
|
+
<template>
|
|
13
|
+
<name>blank</name>
|
|
14
|
+
<description>Empty starter for simple scripts and trivial tasks that don't require a full template setup</description>
|
|
15
|
+
<tags>basic, script</tags>
|
|
16
|
+
</template>
|
|
17
|
+
${templates
|
|
18
|
+
.map(
|
|
19
|
+
(template) => `
|
|
20
|
+
<template>
|
|
21
|
+
<name>${template.name}</name>
|
|
22
|
+
<description>${template.description}</description>
|
|
23
|
+
${template.tags ? `<tags>${template.tags.join(', ')}</tags>` : ''}
|
|
24
|
+
</template>
|
|
25
|
+
`,
|
|
26
|
+
)
|
|
27
|
+
.join('\n')}
|
|
28
|
+
|
|
29
|
+
Response Format:
|
|
30
|
+
<selection>
|
|
31
|
+
<templateName>{selected template name}</templateName>
|
|
32
|
+
<title>{a proper title for the project}</title>
|
|
33
|
+
</selection>
|
|
34
|
+
|
|
35
|
+
Examples:
|
|
36
|
+
|
|
37
|
+
<example>
|
|
38
|
+
User: I need to build a todo app
|
|
39
|
+
Response:
|
|
40
|
+
<selection>
|
|
41
|
+
<templateName>react-basic-starter</templateName>
|
|
42
|
+
<title>Simple React todo application</title>
|
|
43
|
+
</selection>
|
|
44
|
+
</example>
|
|
45
|
+
|
|
46
|
+
<example>
|
|
47
|
+
User: Write a script to generate numbers from 1 to 100
|
|
48
|
+
Response:
|
|
49
|
+
<selection>
|
|
50
|
+
<templateName>blank</templateName>
|
|
51
|
+
<title>script to generate numbers from 1 to 100</title>
|
|
52
|
+
</selection>
|
|
53
|
+
</example>
|
|
54
|
+
|
|
55
|
+
Instructions:
|
|
56
|
+
1. For trivial tasks and simple scripts, always recommend the blank template
|
|
57
|
+
2. For more complex projects, recommend templates from the provided list
|
|
58
|
+
3. Follow the exact XML format
|
|
59
|
+
4. Consider both technical requirements and tags
|
|
60
|
+
5. If no perfect match exists, recommend the closest option
|
|
61
|
+
|
|
62
|
+
Important: Provide only the selection tags in your response, no additional text.
|
|
63
|
+
MOST IMPORTANT: YOU DONT HAVE TIME TO THINK JUST START RESPONDING BASED ON HUNCH
|
|
64
|
+
`;
|
|
65
|
+
|
|
66
|
+
const templates: Template[] = STARTER_TEMPLATES.filter((t) => !t.name.includes('shadcn'));
|
|
67
|
+
|
|
68
|
+
const parseSelectedTemplate = (llmOutput: string): { template: string; title: string } | null => {
|
|
69
|
+
try {
|
|
70
|
+
// Extract content between <templateName> tags
|
|
71
|
+
const templateNameMatch = llmOutput.match(/<templateName>(.*?)<\/templateName>/);
|
|
72
|
+
const titleMatch = llmOutput.match(/<title>(.*?)<\/title>/);
|
|
73
|
+
|
|
74
|
+
if (!templateNameMatch) {
|
|
75
|
+
return null;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
return { template: templateNameMatch[1].trim(), title: titleMatch?.[1].trim() || 'Untitled Project' };
|
|
79
|
+
} catch (error) {
|
|
80
|
+
console.error('Error parsing template selection:', error);
|
|
81
|
+
return null;
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
export const selectStarterTemplate = async (options: { message: string; model: string; provider: ProviderInfo }) => {
|
|
86
|
+
const { message, model, provider } = options;
|
|
87
|
+
const requestBody = {
|
|
88
|
+
message,
|
|
89
|
+
model,
|
|
90
|
+
provider,
|
|
91
|
+
system: starterTemplateSelectionPrompt(templates),
|
|
92
|
+
};
|
|
93
|
+
const response = await fetch('/api/llmcall', {
|
|
94
|
+
method: 'POST',
|
|
95
|
+
body: JSON.stringify(requestBody),
|
|
96
|
+
});
|
|
97
|
+
const respJson: { text: string } = await response.json();
|
|
98
|
+
console.log(respJson);
|
|
99
|
+
|
|
100
|
+
const { text } = respJson;
|
|
101
|
+
const selectedTemplate = parseSelectedTemplate(text);
|
|
102
|
+
|
|
103
|
+
if (selectedTemplate) {
|
|
104
|
+
return selectedTemplate;
|
|
105
|
+
} else {
|
|
106
|
+
console.log('No template selected, using blank template');
|
|
107
|
+
|
|
108
|
+
return {
|
|
109
|
+
template: 'blank',
|
|
110
|
+
title: '',
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
const getGitHubRepoContent = async (repoName: string): Promise<{ name: string; path: string; content: string }[]> => {
|
|
116
|
+
try {
|
|
117
|
+
// Instead of directly fetching from GitHub, use our own API endpoint as a proxy
|
|
118
|
+
const response = await fetch(`/api/github-template?repo=${encodeURIComponent(repoName)}`);
|
|
119
|
+
|
|
120
|
+
if (!response.ok) {
|
|
121
|
+
throw new Error(`HTTP error! status: ${response.status}`);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// Our API will return the files in the format we need
|
|
125
|
+
const files = (await response.json()) as any;
|
|
126
|
+
|
|
127
|
+
return files;
|
|
128
|
+
} catch (error) {
|
|
129
|
+
console.error('Error fetching release contents:', error);
|
|
130
|
+
throw error;
|
|
131
|
+
}
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
export async function getTemplates(templateName: string, title?: string) {
|
|
135
|
+
const template = STARTER_TEMPLATES.find((t) => t.name == templateName);
|
|
136
|
+
|
|
137
|
+
if (!template) {
|
|
138
|
+
return null;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
const githubRepo = template.githubRepo;
|
|
142
|
+
const files = await getGitHubRepoContent(githubRepo);
|
|
143
|
+
|
|
144
|
+
let filteredFiles = files;
|
|
145
|
+
|
|
146
|
+
/*
|
|
147
|
+
* ignoring common unwanted files
|
|
148
|
+
* exclude .git
|
|
149
|
+
*/
|
|
150
|
+
filteredFiles = filteredFiles.filter((x) => x.path.startsWith('.git') == false);
|
|
151
|
+
|
|
152
|
+
/*
|
|
153
|
+
* exclude lock files
|
|
154
|
+
* WE NOW INCLUDE LOCK FILES FOR IMPROVED INSTALL TIMES
|
|
155
|
+
*/
|
|
156
|
+
{
|
|
157
|
+
/*
|
|
158
|
+
*const comminLockFiles = ['package-lock.json', 'yarn.lock', 'pnpm-lock.yaml'];
|
|
159
|
+
*filteredFiles = filteredFiles.filter((x) => comminLockFiles.includes(x.name) == false);
|
|
160
|
+
*/
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
// exclude .bolt
|
|
164
|
+
filteredFiles = filteredFiles.filter((x) => x.path.startsWith('.bolt') == false);
|
|
165
|
+
|
|
166
|
+
// check for ignore file in .bolt folder
|
|
167
|
+
const templateIgnoreFile = files.find((x) => x.path.startsWith('.bolt') && x.name == 'ignore');
|
|
168
|
+
|
|
169
|
+
const filesToImport = {
|
|
170
|
+
files: filteredFiles,
|
|
171
|
+
ignoreFile: [] as typeof filteredFiles,
|
|
172
|
+
};
|
|
173
|
+
|
|
174
|
+
if (templateIgnoreFile) {
|
|
175
|
+
// redacting files specified in ignore file
|
|
176
|
+
const ignorepatterns = templateIgnoreFile.content.split('\n').map((x) => x.trim());
|
|
177
|
+
const ig = ignore().add(ignorepatterns);
|
|
178
|
+
|
|
179
|
+
// filteredFiles = filteredFiles.filter(x => !ig.ignores(x.path))
|
|
180
|
+
const ignoredFiles = filteredFiles.filter((x) => ig.ignores(x.path));
|
|
181
|
+
|
|
182
|
+
filesToImport.files = filteredFiles;
|
|
183
|
+
filesToImport.ignoreFile = ignoredFiles;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
const assistantMessage = `
|
|
187
|
+
Bolt is initializing your project with the required files using the ${template.name} template.
|
|
188
|
+
<boltArtifact id="imported-files" title="${title || 'Create initial files'}" type="bundled">
|
|
189
|
+
${filesToImport.files
|
|
190
|
+
.map(
|
|
191
|
+
(file) =>
|
|
192
|
+
`<boltAction type="file" filePath="${file.path}">
|
|
193
|
+
${file.content}
|
|
194
|
+
</boltAction>`,
|
|
195
|
+
)
|
|
196
|
+
.join('\n')}
|
|
197
|
+
</boltArtifact>
|
|
198
|
+
`;
|
|
199
|
+
let userMessage = ``;
|
|
200
|
+
const templatePromptFile = files.filter((x) => x.path.startsWith('.bolt')).find((x) => x.name == 'prompt');
|
|
201
|
+
|
|
202
|
+
if (templatePromptFile) {
|
|
203
|
+
userMessage = `
|
|
204
|
+
TEMPLATE INSTRUCTIONS:
|
|
205
|
+
${templatePromptFile.content}
|
|
206
|
+
|
|
207
|
+
---
|
|
208
|
+
`;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
if (filesToImport.ignoreFile.length > 0) {
|
|
212
|
+
userMessage =
|
|
213
|
+
userMessage +
|
|
214
|
+
`
|
|
215
|
+
STRICT FILE ACCESS RULES - READ CAREFULLY:
|
|
216
|
+
|
|
217
|
+
The following files are READ-ONLY and must never be modified:
|
|
218
|
+
${filesToImport.ignoreFile.map((file) => `- ${file.path}`).join('\n')}
|
|
219
|
+
|
|
220
|
+
Permitted actions:
|
|
221
|
+
✓ Import these files as dependencies
|
|
222
|
+
✓ Read from these files
|
|
223
|
+
✓ Reference these files
|
|
224
|
+
|
|
225
|
+
Strictly forbidden actions:
|
|
226
|
+
❌ Modify any content within these files
|
|
227
|
+
❌ Delete these files
|
|
228
|
+
❌ Rename these files
|
|
229
|
+
❌ Move these files
|
|
230
|
+
❌ Create new versions of these files
|
|
231
|
+
❌ Suggest changes to these files
|
|
232
|
+
|
|
233
|
+
Any attempt to modify these protected files will result in immediate termination of the operation.
|
|
234
|
+
|
|
235
|
+
If you need to make changes to functionality, create new files instead of modifying the protected ones listed above.
|
|
236
|
+
---
|
|
237
|
+
`;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
userMessage += `
|
|
241
|
+
---
|
|
242
|
+
template import is done, and you can now use the imported files,
|
|
243
|
+
edit only the files that need to be changed, and you can create new files as needed.
|
|
244
|
+
NO NOT EDIT/WRITE ANY FILES THAT ALREADY EXIST IN THE PROJECT AND DOES NOT NEED TO BE MODIFIED
|
|
245
|
+
---
|
|
246
|
+
Now that the Template is imported please continue with my original request
|
|
247
|
+
|
|
248
|
+
IMPORTANT: Dont Forget to install the dependencies before running the app by using \`npm install && npm run dev\`
|
|
249
|
+
`;
|
|
250
|
+
|
|
251
|
+
return {
|
|
252
|
+
assistantMessage,
|
|
253
|
+
userMessage,
|
|
254
|
+
};
|
|
255
|
+
}
|
|
@@ -0,0 +1,384 @@
|
|
|
1
|
+
import type { WebContainer, WebContainerProcess } from '@webcontainer/api';
|
|
2
|
+
import type { ITerminal } from '~/types/terminal';
|
|
3
|
+
import { withResolvers } from './promises';
|
|
4
|
+
import { atom } from 'nanostores';
|
|
5
|
+
import { expoUrlAtom } from '~/lib/stores/qrCodeStore';
|
|
6
|
+
|
|
7
|
+
export async function newShellProcess(webcontainer: WebContainer, terminal: ITerminal) {
|
|
8
|
+
const args: string[] = [];
|
|
9
|
+
|
|
10
|
+
// we spawn a JSH process with a fallback cols and rows in case the process is not attached yet to a visible terminal
|
|
11
|
+
const process = await webcontainer.spawn('/bin/jsh', ['--osc', ...args], {
|
|
12
|
+
terminal: {
|
|
13
|
+
cols: terminal.cols ?? 80,
|
|
14
|
+
rows: terminal.rows ?? 15,
|
|
15
|
+
},
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
const input = process.input.getWriter();
|
|
19
|
+
const output = process.output;
|
|
20
|
+
|
|
21
|
+
const jshReady = withResolvers<void>();
|
|
22
|
+
|
|
23
|
+
let isInteractive = false;
|
|
24
|
+
output.pipeTo(
|
|
25
|
+
new WritableStream({
|
|
26
|
+
write(data) {
|
|
27
|
+
if (!isInteractive) {
|
|
28
|
+
const [, osc] = data.match(/\x1b\]654;([^\x07]+)\x07/) || [];
|
|
29
|
+
|
|
30
|
+
if (osc === 'interactive') {
|
|
31
|
+
// wait until we see the interactive OSC
|
|
32
|
+
isInteractive = true;
|
|
33
|
+
|
|
34
|
+
jshReady.resolve();
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
terminal.write(data);
|
|
39
|
+
|
|
40
|
+
// Capture terminal output for debugging
|
|
41
|
+
try {
|
|
42
|
+
import('~/utils/debugLogger')
|
|
43
|
+
.then(({ captureTerminalLog }) => {
|
|
44
|
+
// Clean the data by removing ANSI escape sequences for logging
|
|
45
|
+
const cleanData = data.replace(/\x1b\[[0-9;]*[mG]/g, '').trim();
|
|
46
|
+
|
|
47
|
+
if (cleanData) {
|
|
48
|
+
captureTerminalLog(cleanData, 'output');
|
|
49
|
+
}
|
|
50
|
+
})
|
|
51
|
+
.catch(() => {
|
|
52
|
+
// Ignore if debug logger is not available
|
|
53
|
+
});
|
|
54
|
+
} catch {
|
|
55
|
+
// Ignore errors in debug logging
|
|
56
|
+
}
|
|
57
|
+
},
|
|
58
|
+
}),
|
|
59
|
+
);
|
|
60
|
+
|
|
61
|
+
terminal.onData((data) => {
|
|
62
|
+
// console.log('terminal onData', { data, isInteractive });
|
|
63
|
+
|
|
64
|
+
if (isInteractive) {
|
|
65
|
+
input.write(data);
|
|
66
|
+
|
|
67
|
+
// Capture terminal input for debugging
|
|
68
|
+
try {
|
|
69
|
+
import('~/utils/debugLogger')
|
|
70
|
+
.then(({ captureTerminalLog }) => {
|
|
71
|
+
// Clean the data and check if it's a command (not just cursor movement)
|
|
72
|
+
const cleanData = data.replace(/\x1b\[[0-9;]*[A-Z]/g, '').trim();
|
|
73
|
+
|
|
74
|
+
if (cleanData && cleanData !== '\r' && cleanData !== '\n') {
|
|
75
|
+
captureTerminalLog(cleanData, 'input');
|
|
76
|
+
}
|
|
77
|
+
})
|
|
78
|
+
.catch(() => {
|
|
79
|
+
// Ignore if debug logger is not available
|
|
80
|
+
});
|
|
81
|
+
} catch {
|
|
82
|
+
// Ignore errors in debug logging
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
await jshReady.promise;
|
|
88
|
+
|
|
89
|
+
return process;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
export type ExecutionResult = { output: string; exitCode: number } | undefined;
|
|
93
|
+
|
|
94
|
+
export class BoltShell {
|
|
95
|
+
#initialized: (() => void) | undefined;
|
|
96
|
+
#readyPromise: Promise<void>;
|
|
97
|
+
#webcontainer: WebContainer | undefined;
|
|
98
|
+
#terminal: ITerminal | undefined;
|
|
99
|
+
#process: WebContainerProcess | undefined;
|
|
100
|
+
executionState = atom<
|
|
101
|
+
{ sessionId: string; active: boolean; executionPrms?: Promise<any>; abort?: () => void } | undefined
|
|
102
|
+
>();
|
|
103
|
+
#outputStream: ReadableStreamDefaultReader<string> | undefined;
|
|
104
|
+
#shellInputStream: WritableStreamDefaultWriter<string> | undefined;
|
|
105
|
+
|
|
106
|
+
constructor() {
|
|
107
|
+
this.#readyPromise = new Promise((resolve) => {
|
|
108
|
+
this.#initialized = resolve;
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
ready() {
|
|
113
|
+
return this.#readyPromise;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
async init(webcontainer: WebContainer, terminal: ITerminal) {
|
|
117
|
+
this.#webcontainer = webcontainer;
|
|
118
|
+
this.#terminal = terminal;
|
|
119
|
+
|
|
120
|
+
// Use all three streams from tee: one for terminal, one for command execution, one for Expo URL detection
|
|
121
|
+
const { process, commandStream, expoUrlStream } = await this.newBoltShellProcess(webcontainer, terminal);
|
|
122
|
+
this.#process = process;
|
|
123
|
+
this.#outputStream = commandStream.getReader();
|
|
124
|
+
|
|
125
|
+
// Start background Expo URL watcher immediately
|
|
126
|
+
this._watchExpoUrlInBackground(expoUrlStream);
|
|
127
|
+
|
|
128
|
+
await this.waitTillOscCode('interactive');
|
|
129
|
+
this.#initialized?.();
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
async newBoltShellProcess(webcontainer: WebContainer, terminal: ITerminal) {
|
|
133
|
+
const args: string[] = [];
|
|
134
|
+
const process = await webcontainer.spawn('/bin/jsh', ['--osc', ...args], {
|
|
135
|
+
terminal: {
|
|
136
|
+
cols: terminal.cols ?? 80,
|
|
137
|
+
rows: terminal.rows ?? 15,
|
|
138
|
+
},
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
const input = process.input.getWriter();
|
|
142
|
+
this.#shellInputStream = input;
|
|
143
|
+
|
|
144
|
+
// Tee the output so we can have three independent readers
|
|
145
|
+
const [streamA, streamB] = process.output.tee();
|
|
146
|
+
const [streamC, streamD] = streamB.tee();
|
|
147
|
+
|
|
148
|
+
const jshReady = withResolvers<void>();
|
|
149
|
+
let isInteractive = false;
|
|
150
|
+
streamA.pipeTo(
|
|
151
|
+
new WritableStream({
|
|
152
|
+
write(data) {
|
|
153
|
+
if (!isInteractive) {
|
|
154
|
+
const [, osc] = data.match(/\x1b\]654;([^\x07]+)\x07/) || [];
|
|
155
|
+
|
|
156
|
+
if (osc === 'interactive') {
|
|
157
|
+
isInteractive = true;
|
|
158
|
+
jshReady.resolve();
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
terminal.write(data);
|
|
163
|
+
},
|
|
164
|
+
}),
|
|
165
|
+
);
|
|
166
|
+
|
|
167
|
+
terminal.onData((data) => {
|
|
168
|
+
if (isInteractive) {
|
|
169
|
+
input.write(data);
|
|
170
|
+
}
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
await jshReady.promise;
|
|
174
|
+
|
|
175
|
+
// Return all streams for use in init
|
|
176
|
+
return { process, terminalStream: streamA, commandStream: streamC, expoUrlStream: streamD };
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
// Dedicated background watcher for Expo URL
|
|
180
|
+
private async _watchExpoUrlInBackground(stream: ReadableStream<string>) {
|
|
181
|
+
const reader = stream.getReader();
|
|
182
|
+
let buffer = '';
|
|
183
|
+
const expoUrlRegex = /(exp:\/\/[^\s]+)/;
|
|
184
|
+
|
|
185
|
+
while (true) {
|
|
186
|
+
const { value, done } = await reader.read();
|
|
187
|
+
|
|
188
|
+
if (done) {
|
|
189
|
+
break;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
buffer += value || '';
|
|
193
|
+
|
|
194
|
+
const expoUrlMatch = buffer.match(expoUrlRegex);
|
|
195
|
+
|
|
196
|
+
if (expoUrlMatch) {
|
|
197
|
+
const cleanUrl = expoUrlMatch[1]
|
|
198
|
+
.replace(/[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]/g, '')
|
|
199
|
+
.replace(/[^\x20-\x7E]+$/g, '');
|
|
200
|
+
expoUrlAtom.set(cleanUrl);
|
|
201
|
+
buffer = buffer.slice(buffer.indexOf(expoUrlMatch[1]) + expoUrlMatch[1].length);
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
if (buffer.length > 2048) {
|
|
205
|
+
buffer = buffer.slice(-2048);
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
get terminal() {
|
|
211
|
+
return this.#terminal;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
get process() {
|
|
215
|
+
return this.#process;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
async executeCommand(sessionId: string, command: string, abort?: () => void): Promise<ExecutionResult> {
|
|
219
|
+
if (!this.process || !this.terminal) {
|
|
220
|
+
return undefined;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
const state = this.executionState.get();
|
|
224
|
+
|
|
225
|
+
if (state?.active && state.abort) {
|
|
226
|
+
state.abort();
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
/*
|
|
230
|
+
* interrupt the current execution
|
|
231
|
+
* this.#shellInputStream?.write('\x03');
|
|
232
|
+
*/
|
|
233
|
+
this.terminal.input('\x03');
|
|
234
|
+
await this.waitTillOscCode('prompt');
|
|
235
|
+
|
|
236
|
+
if (state && state.executionPrms) {
|
|
237
|
+
await state.executionPrms;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
//start a new execution
|
|
241
|
+
this.terminal.input(command.trim() + '\n');
|
|
242
|
+
|
|
243
|
+
//wait for the execution to finish
|
|
244
|
+
const executionPromise = this.getCurrentExecutionResult();
|
|
245
|
+
this.executionState.set({ sessionId, active: true, executionPrms: executionPromise, abort });
|
|
246
|
+
|
|
247
|
+
const resp = await executionPromise;
|
|
248
|
+
this.executionState.set({ sessionId, active: false });
|
|
249
|
+
|
|
250
|
+
if (resp) {
|
|
251
|
+
try {
|
|
252
|
+
resp.output = cleanTerminalOutput(resp.output);
|
|
253
|
+
} catch (error) {
|
|
254
|
+
console.log('failed to format terminal output', error);
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
return resp;
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
async getCurrentExecutionResult(): Promise<ExecutionResult> {
|
|
262
|
+
const { output, exitCode } = await this.waitTillOscCode('exit');
|
|
263
|
+
return { output, exitCode };
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
onQRCodeDetected?: (qrCode: string) => void;
|
|
267
|
+
|
|
268
|
+
async waitTillOscCode(waitCode: string) {
|
|
269
|
+
let fullOutput = '';
|
|
270
|
+
let exitCode: number = 0;
|
|
271
|
+
let buffer = ''; // <-- Add a buffer to accumulate output
|
|
272
|
+
|
|
273
|
+
if (!this.#outputStream) {
|
|
274
|
+
return { output: fullOutput, exitCode };
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
const tappedStream = this.#outputStream;
|
|
278
|
+
|
|
279
|
+
// Regex for Expo URL
|
|
280
|
+
const expoUrlRegex = /(exp:\/\/[^\s]+)/;
|
|
281
|
+
|
|
282
|
+
while (true) {
|
|
283
|
+
const { value, done } = await tappedStream.read();
|
|
284
|
+
|
|
285
|
+
if (done) {
|
|
286
|
+
break;
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
const text = value || '';
|
|
290
|
+
fullOutput += text;
|
|
291
|
+
buffer += text; // <-- Accumulate in buffer
|
|
292
|
+
|
|
293
|
+
// Extract Expo URL from buffer and set store
|
|
294
|
+
const expoUrlMatch = buffer.match(expoUrlRegex);
|
|
295
|
+
|
|
296
|
+
if (expoUrlMatch) {
|
|
297
|
+
// Remove any trailing ANSI escape codes or non-printable characters
|
|
298
|
+
const cleanUrl = expoUrlMatch[1]
|
|
299
|
+
.replace(/[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]/g, '')
|
|
300
|
+
.replace(/[^\x20-\x7E]+$/g, '');
|
|
301
|
+
expoUrlAtom.set(cleanUrl);
|
|
302
|
+
|
|
303
|
+
// Remove everything up to and including the URL from the buffer to avoid duplicate matches
|
|
304
|
+
buffer = buffer.slice(buffer.indexOf(expoUrlMatch[1]) + expoUrlMatch[1].length);
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
// Check if command completion signal with exit code
|
|
308
|
+
const [, osc, , , code] = text.match(/\x1b\]654;([^\x07=]+)=?((-?\d+):(\d+))?\x07/) || [];
|
|
309
|
+
|
|
310
|
+
if (osc === 'exit') {
|
|
311
|
+
exitCode = parseInt(code, 10);
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
if (osc === waitCode) {
|
|
315
|
+
break;
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
return { output: fullOutput, exitCode };
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
/**
|
|
324
|
+
* Cleans and formats terminal output while preserving structure and paths
|
|
325
|
+
* Handles ANSI, OSC, and various terminal control sequences
|
|
326
|
+
*/
|
|
327
|
+
export function cleanTerminalOutput(input: string): string {
|
|
328
|
+
// Step 1: Remove OSC sequences (including those with parameters)
|
|
329
|
+
const removeOsc = input
|
|
330
|
+
.replace(/\x1b\](\d+;[^\x07\x1b]*|\d+[^\x07\x1b]*)\x07/g, '')
|
|
331
|
+
.replace(/\](\d+;[^\n]*|\d+[^\n]*)/g, '');
|
|
332
|
+
|
|
333
|
+
// Step 2: Remove ANSI escape sequences and color codes more thoroughly
|
|
334
|
+
const removeAnsi = removeOsc
|
|
335
|
+
// Remove all escape sequences with parameters
|
|
336
|
+
.replace(/\u001b\[[\?]?[0-9;]*[a-zA-Z]/g, '')
|
|
337
|
+
.replace(/\x1b\[[\?]?[0-9;]*[a-zA-Z]/g, '')
|
|
338
|
+
// Remove color codes
|
|
339
|
+
.replace(/\u001b\[[0-9;]*m/g, '')
|
|
340
|
+
.replace(/\x1b\[[0-9;]*m/g, '')
|
|
341
|
+
// Clean up any remaining escape characters
|
|
342
|
+
.replace(/\u001b/g, '')
|
|
343
|
+
.replace(/\x1b/g, '');
|
|
344
|
+
|
|
345
|
+
// Step 3: Clean up carriage returns and newlines
|
|
346
|
+
const cleanNewlines = removeAnsi
|
|
347
|
+
.replace(/\r\n/g, '\n')
|
|
348
|
+
.replace(/\r/g, '\n')
|
|
349
|
+
.replace(/\n{3,}/g, '\n\n');
|
|
350
|
+
|
|
351
|
+
// Step 4: Add newlines at key breakpoints while preserving paths
|
|
352
|
+
const formatOutput = cleanNewlines
|
|
353
|
+
// Preserve prompt line
|
|
354
|
+
.replace(/^([~\/][^\n❯]+)❯/m, '$1\n❯')
|
|
355
|
+
// Add newline before command output indicators
|
|
356
|
+
.replace(/(?<!^|\n)>/g, '\n>')
|
|
357
|
+
// Add newline before error keywords without breaking paths
|
|
358
|
+
.replace(/(?<!^|\n|\w)(error|failed|warning|Error|Failed|Warning):/g, '\n$1:')
|
|
359
|
+
// Add newline before 'at' in stack traces without breaking paths
|
|
360
|
+
.replace(/(?<!^|\n|\/)(at\s+(?!async|sync))/g, '\nat ')
|
|
361
|
+
// Ensure 'at async' stays on same line
|
|
362
|
+
.replace(/\bat\s+async/g, 'at async')
|
|
363
|
+
// Add newline before npm error indicators
|
|
364
|
+
.replace(/(?<!^|\n)(npm ERR!)/g, '\n$1');
|
|
365
|
+
|
|
366
|
+
// Step 5: Clean up whitespace while preserving intentional spacing
|
|
367
|
+
const cleanSpaces = formatOutput
|
|
368
|
+
.split('\n')
|
|
369
|
+
.map((line) => line.trim())
|
|
370
|
+
.filter((line) => line.length > 0)
|
|
371
|
+
.join('\n');
|
|
372
|
+
|
|
373
|
+
// Step 6: Final cleanup
|
|
374
|
+
return cleanSpaces
|
|
375
|
+
.replace(/\n{3,}/g, '\n\n') // Replace multiple newlines with double newlines
|
|
376
|
+
.replace(/:\s+/g, ': ') // Normalize spacing after colons
|
|
377
|
+
.replace(/\s{2,}/g, ' ') // Remove multiple spaces
|
|
378
|
+
.replace(/^\s+|\s+$/g, '') // Trim start and end
|
|
379
|
+
.replace(/\u0000/g, ''); // Remove null characters
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
export function newBoltShellProcess() {
|
|
383
|
+
return new BoltShell();
|
|
384
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cleans webcontainer URLs from stack traces to show relative paths instead
|
|
3
|
+
*/
|
|
4
|
+
export function cleanStackTrace(stackTrace: string): string {
|
|
5
|
+
// Function to clean a single URL
|
|
6
|
+
const cleanUrl = (url: string): string => {
|
|
7
|
+
const regex = /^https?:\/\/[^\/]+\.webcontainer-api\.io(\/.*)?$/;
|
|
8
|
+
|
|
9
|
+
if (!regex.test(url)) {
|
|
10
|
+
return url;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const pathRegex = /^https?:\/\/[^\/]+\.webcontainer-api\.io\/(.*?)$/;
|
|
14
|
+
const match = url.match(pathRegex);
|
|
15
|
+
|
|
16
|
+
return match?.[1] || '';
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
// Split the stack trace into lines and process each line
|
|
20
|
+
return stackTrace
|
|
21
|
+
.split('\n')
|
|
22
|
+
.map((line) => {
|
|
23
|
+
// Match any URL in the line that contains webcontainer-api.io
|
|
24
|
+
return line.replace(/(https?:\/\/[^\/]+\.webcontainer-api\.io\/[^\s\)]+)/g, (match) => cleanUrl(match));
|
|
25
|
+
})
|
|
26
|
+
.join('\n');
|
|
27
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export function stripIndents(value: string): string;
|
|
2
|
+
export function stripIndents(strings: TemplateStringsArray, ...values: any[]): string;
|
|
3
|
+
export function stripIndents(arg0: string | TemplateStringsArray, ...values: any[]) {
|
|
4
|
+
if (typeof arg0 !== 'string') {
|
|
5
|
+
const processedString = arg0.reduce((acc, curr, i) => {
|
|
6
|
+
acc += curr + (values[i] ?? '');
|
|
7
|
+
return acc;
|
|
8
|
+
}, '');
|
|
9
|
+
|
|
10
|
+
return _stripIndents(processedString);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
return _stripIndents(arg0);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function _stripIndents(value: string) {
|
|
17
|
+
return value
|
|
18
|
+
.split('\n')
|
|
19
|
+
.map((line) => line.trim())
|
|
20
|
+
.join('\n')
|
|
21
|
+
.trimStart()
|
|
22
|
+
.replace(/[\r\n]$/, '');
|
|
23
|
+
}
|