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.
Files changed (501) hide show
  1. .github/ISSUE_TEMPLATE/bug_report.md +65 -0
  2. .github/ISSUE_TEMPLATE/feature_request.md +41 -0
  3. .github/PULL_REQUEST_TEMPLATE.md +20 -0
  4. .github/workflows/publish-manual.yml +61 -0
  5. .github/workflows/publish.yml +64 -0
  6. .gitignore +214 -0
  7. CRCA.py +4156 -0
  8. LICENSE +201 -0
  9. MANIFEST.in +43 -0
  10. PKG-INFO +5035 -0
  11. README.md +4959 -0
  12. __init__.py +17 -0
  13. branches/CRCA-Q.py +2728 -0
  14. branches/crca_cg/corposwarm.py +9065 -0
  15. branches/crca_cg/fix_rancher_docker_creds.ps1 +155 -0
  16. branches/crca_cg/package.json +5 -0
  17. branches/crca_cg/test_bolt_integration.py +446 -0
  18. branches/crca_cg/test_corposwarm_comprehensive.py +773 -0
  19. branches/crca_cg/test_new_features.py +163 -0
  20. branches/crca_sd/__init__.py +149 -0
  21. branches/crca_sd/crca_sd_core.py +770 -0
  22. branches/crca_sd/crca_sd_governance.py +1325 -0
  23. branches/crca_sd/crca_sd_mpc.py +1130 -0
  24. branches/crca_sd/crca_sd_realtime.py +1844 -0
  25. branches/crca_sd/crca_sd_tui.py +1133 -0
  26. crca-1.4.0.dist-info/METADATA +5035 -0
  27. crca-1.4.0.dist-info/RECORD +501 -0
  28. crca-1.4.0.dist-info/WHEEL +4 -0
  29. crca-1.4.0.dist-info/licenses/LICENSE +201 -0
  30. docs/CRCA-Q.md +2333 -0
  31. examples/config.yaml.example +25 -0
  32. examples/crca_sd_example.py +513 -0
  33. examples/data_broker_example.py +294 -0
  34. examples/logistics_corporation.py +861 -0
  35. examples/palantir_example.py +299 -0
  36. examples/policy_bench.py +934 -0
  37. examples/pridnestrovia-sd.py +705 -0
  38. examples/pridnestrovia_realtime.py +1902 -0
  39. prompts/__init__.py +10 -0
  40. prompts/default_crca.py +101 -0
  41. pyproject.toml +151 -0
  42. requirements.txt +76 -0
  43. schemas/__init__.py +43 -0
  44. schemas/mcpSchemas.py +51 -0
  45. schemas/policy.py +458 -0
  46. templates/__init__.py +38 -0
  47. templates/base_specialized_agent.py +195 -0
  48. templates/drift_detection.py +325 -0
  49. templates/examples/causal_agent_template.py +309 -0
  50. templates/examples/drag_drop_example.py +213 -0
  51. templates/examples/logistics_agent_template.py +207 -0
  52. templates/examples/trading_agent_template.py +206 -0
  53. templates/feature_mixins.py +253 -0
  54. templates/graph_management.py +442 -0
  55. templates/llm_integration.py +194 -0
  56. templates/module_registry.py +276 -0
  57. templates/mpc_planner.py +280 -0
  58. templates/policy_loop.py +1168 -0
  59. templates/prediction_framework.py +448 -0
  60. templates/statistical_methods.py +778 -0
  61. tests/sanity.yml +31 -0
  62. tests/sanity_check +406 -0
  63. tests/test_core.py +47 -0
  64. tests/test_crca_excel.py +166 -0
  65. tests/test_crca_sd.py +780 -0
  66. tests/test_data_broker.py +424 -0
  67. tests/test_palantir.py +349 -0
  68. tools/__init__.py +38 -0
  69. tools/actuators.py +437 -0
  70. tools/bolt.diy/Dockerfile +103 -0
  71. tools/bolt.diy/app/components/@settings/core/AvatarDropdown.tsx +175 -0
  72. tools/bolt.diy/app/components/@settings/core/ControlPanel.tsx +345 -0
  73. tools/bolt.diy/app/components/@settings/core/constants.tsx +108 -0
  74. tools/bolt.diy/app/components/@settings/core/types.ts +114 -0
  75. tools/bolt.diy/app/components/@settings/index.ts +12 -0
  76. tools/bolt.diy/app/components/@settings/shared/components/TabTile.tsx +151 -0
  77. tools/bolt.diy/app/components/@settings/shared/service-integration/ConnectionForm.tsx +193 -0
  78. tools/bolt.diy/app/components/@settings/shared/service-integration/ConnectionTestIndicator.tsx +60 -0
  79. tools/bolt.diy/app/components/@settings/shared/service-integration/ErrorState.tsx +102 -0
  80. tools/bolt.diy/app/components/@settings/shared/service-integration/LoadingState.tsx +94 -0
  81. tools/bolt.diy/app/components/@settings/shared/service-integration/ServiceHeader.tsx +72 -0
  82. tools/bolt.diy/app/components/@settings/shared/service-integration/index.ts +6 -0
  83. tools/bolt.diy/app/components/@settings/tabs/data/DataTab.tsx +721 -0
  84. tools/bolt.diy/app/components/@settings/tabs/data/DataVisualization.tsx +384 -0
  85. tools/bolt.diy/app/components/@settings/tabs/event-logs/EventLogsTab.tsx +1013 -0
  86. tools/bolt.diy/app/components/@settings/tabs/features/FeaturesTab.tsx +295 -0
  87. tools/bolt.diy/app/components/@settings/tabs/github/GitHubTab.tsx +281 -0
  88. tools/bolt.diy/app/components/@settings/tabs/github/components/GitHubAuthDialog.tsx +173 -0
  89. tools/bolt.diy/app/components/@settings/tabs/github/components/GitHubCacheManager.tsx +367 -0
  90. tools/bolt.diy/app/components/@settings/tabs/github/components/GitHubConnection.tsx +233 -0
  91. tools/bolt.diy/app/components/@settings/tabs/github/components/GitHubErrorBoundary.tsx +105 -0
  92. tools/bolt.diy/app/components/@settings/tabs/github/components/GitHubProgressiveLoader.tsx +266 -0
  93. tools/bolt.diy/app/components/@settings/tabs/github/components/GitHubRepositoryCard.tsx +121 -0
  94. tools/bolt.diy/app/components/@settings/tabs/github/components/GitHubRepositorySelector.tsx +312 -0
  95. tools/bolt.diy/app/components/@settings/tabs/github/components/GitHubStats.tsx +291 -0
  96. tools/bolt.diy/app/components/@settings/tabs/github/components/GitHubUserProfile.tsx +46 -0
  97. tools/bolt.diy/app/components/@settings/tabs/github/components/shared/GitHubStateIndicators.tsx +264 -0
  98. tools/bolt.diy/app/components/@settings/tabs/github/components/shared/RepositoryCard.tsx +361 -0
  99. tools/bolt.diy/app/components/@settings/tabs/github/components/shared/index.ts +11 -0
  100. tools/bolt.diy/app/components/@settings/tabs/gitlab/GitLabTab.tsx +305 -0
  101. tools/bolt.diy/app/components/@settings/tabs/gitlab/components/GitLabAuthDialog.tsx +186 -0
  102. tools/bolt.diy/app/components/@settings/tabs/gitlab/components/GitLabConnection.tsx +253 -0
  103. tools/bolt.diy/app/components/@settings/tabs/gitlab/components/GitLabRepositorySelector.tsx +358 -0
  104. tools/bolt.diy/app/components/@settings/tabs/gitlab/components/RepositoryCard.tsx +79 -0
  105. tools/bolt.diy/app/components/@settings/tabs/gitlab/components/RepositoryList.tsx +142 -0
  106. tools/bolt.diy/app/components/@settings/tabs/gitlab/components/StatsDisplay.tsx +91 -0
  107. tools/bolt.diy/app/components/@settings/tabs/gitlab/components/index.ts +4 -0
  108. tools/bolt.diy/app/components/@settings/tabs/mcp/McpServerList.tsx +99 -0
  109. tools/bolt.diy/app/components/@settings/tabs/mcp/McpServerListItem.tsx +70 -0
  110. tools/bolt.diy/app/components/@settings/tabs/mcp/McpStatusBadge.tsx +37 -0
  111. tools/bolt.diy/app/components/@settings/tabs/mcp/McpTab.tsx +239 -0
  112. tools/bolt.diy/app/components/@settings/tabs/netlify/NetlifyTab.tsx +1393 -0
  113. tools/bolt.diy/app/components/@settings/tabs/netlify/components/NetlifyConnection.tsx +990 -0
  114. tools/bolt.diy/app/components/@settings/tabs/netlify/components/index.ts +1 -0
  115. tools/bolt.diy/app/components/@settings/tabs/notifications/NotificationsTab.tsx +300 -0
  116. tools/bolt.diy/app/components/@settings/tabs/profile/ProfileTab.tsx +181 -0
  117. tools/bolt.diy/app/components/@settings/tabs/providers/cloud/CloudProvidersTab.tsx +308 -0
  118. tools/bolt.diy/app/components/@settings/tabs/providers/local/ErrorBoundary.tsx +68 -0
  119. tools/bolt.diy/app/components/@settings/tabs/providers/local/HealthStatusBadge.tsx +64 -0
  120. tools/bolt.diy/app/components/@settings/tabs/providers/local/LoadingSkeleton.tsx +107 -0
  121. tools/bolt.diy/app/components/@settings/tabs/providers/local/LocalProvidersTab.tsx +556 -0
  122. tools/bolt.diy/app/components/@settings/tabs/providers/local/ModelCard.tsx +106 -0
  123. tools/bolt.diy/app/components/@settings/tabs/providers/local/ProviderCard.tsx +120 -0
  124. tools/bolt.diy/app/components/@settings/tabs/providers/local/SetupGuide.tsx +671 -0
  125. tools/bolt.diy/app/components/@settings/tabs/providers/local/StatusDashboard.tsx +91 -0
  126. tools/bolt.diy/app/components/@settings/tabs/providers/local/types.ts +44 -0
  127. tools/bolt.diy/app/components/@settings/tabs/settings/SettingsTab.tsx +215 -0
  128. tools/bolt.diy/app/components/@settings/tabs/supabase/SupabaseTab.tsx +1089 -0
  129. tools/bolt.diy/app/components/@settings/tabs/vercel/VercelTab.tsx +909 -0
  130. tools/bolt.diy/app/components/@settings/tabs/vercel/components/VercelConnection.tsx +368 -0
  131. tools/bolt.diy/app/components/@settings/tabs/vercel/components/index.ts +1 -0
  132. tools/bolt.diy/app/components/@settings/utils/tab-helpers.ts +54 -0
  133. tools/bolt.diy/app/components/chat/APIKeyManager.tsx +169 -0
  134. tools/bolt.diy/app/components/chat/Artifact.tsx +296 -0
  135. tools/bolt.diy/app/components/chat/AssistantMessage.tsx +192 -0
  136. tools/bolt.diy/app/components/chat/BaseChat.module.scss +47 -0
  137. tools/bolt.diy/app/components/chat/BaseChat.tsx +522 -0
  138. tools/bolt.diy/app/components/chat/Chat.client.tsx +670 -0
  139. tools/bolt.diy/app/components/chat/ChatAlert.tsx +108 -0
  140. tools/bolt.diy/app/components/chat/ChatBox.tsx +334 -0
  141. tools/bolt.diy/app/components/chat/CodeBlock.module.scss +10 -0
  142. tools/bolt.diy/app/components/chat/CodeBlock.tsx +85 -0
  143. tools/bolt.diy/app/components/chat/DicussMode.tsx +17 -0
  144. tools/bolt.diy/app/components/chat/ExamplePrompts.tsx +37 -0
  145. tools/bolt.diy/app/components/chat/FilePreview.tsx +38 -0
  146. tools/bolt.diy/app/components/chat/GitCloneButton.tsx +327 -0
  147. tools/bolt.diy/app/components/chat/ImportFolderButton.tsx +141 -0
  148. tools/bolt.diy/app/components/chat/LLMApiAlert.tsx +109 -0
  149. tools/bolt.diy/app/components/chat/MCPTools.tsx +129 -0
  150. tools/bolt.diy/app/components/chat/Markdown.module.scss +171 -0
  151. tools/bolt.diy/app/components/chat/Markdown.spec.ts +48 -0
  152. tools/bolt.diy/app/components/chat/Markdown.tsx +252 -0
  153. tools/bolt.diy/app/components/chat/Messages.client.tsx +102 -0
  154. tools/bolt.diy/app/components/chat/ModelSelector.tsx +797 -0
  155. tools/bolt.diy/app/components/chat/NetlifyDeploymentLink.client.tsx +51 -0
  156. tools/bolt.diy/app/components/chat/ProgressCompilation.tsx +110 -0
  157. tools/bolt.diy/app/components/chat/ScreenshotStateManager.tsx +33 -0
  158. tools/bolt.diy/app/components/chat/SendButton.client.tsx +39 -0
  159. tools/bolt.diy/app/components/chat/SpeechRecognition.tsx +28 -0
  160. tools/bolt.diy/app/components/chat/StarterTemplates.tsx +38 -0
  161. tools/bolt.diy/app/components/chat/SupabaseAlert.tsx +199 -0
  162. tools/bolt.diy/app/components/chat/SupabaseConnection.tsx +339 -0
  163. tools/bolt.diy/app/components/chat/ThoughtBox.tsx +43 -0
  164. tools/bolt.diy/app/components/chat/ToolInvocations.tsx +409 -0
  165. tools/bolt.diy/app/components/chat/UserMessage.tsx +101 -0
  166. tools/bolt.diy/app/components/chat/VercelDeploymentLink.client.tsx +158 -0
  167. tools/bolt.diy/app/components/chat/chatExportAndImport/ExportChatButton.tsx +49 -0
  168. tools/bolt.diy/app/components/chat/chatExportAndImport/ImportButtons.tsx +96 -0
  169. tools/bolt.diy/app/components/deploy/DeployAlert.tsx +197 -0
  170. tools/bolt.diy/app/components/deploy/DeployButton.tsx +277 -0
  171. tools/bolt.diy/app/components/deploy/GitHubDeploy.client.tsx +171 -0
  172. tools/bolt.diy/app/components/deploy/GitHubDeploymentDialog.tsx +1041 -0
  173. tools/bolt.diy/app/components/deploy/GitLabDeploy.client.tsx +171 -0
  174. tools/bolt.diy/app/components/deploy/GitLabDeploymentDialog.tsx +764 -0
  175. tools/bolt.diy/app/components/deploy/NetlifyDeploy.client.tsx +246 -0
  176. tools/bolt.diy/app/components/deploy/VercelDeploy.client.tsx +235 -0
  177. tools/bolt.diy/app/components/editor/codemirror/BinaryContent.tsx +7 -0
  178. tools/bolt.diy/app/components/editor/codemirror/CodeMirrorEditor.tsx +555 -0
  179. tools/bolt.diy/app/components/editor/codemirror/EnvMasking.ts +80 -0
  180. tools/bolt.diy/app/components/editor/codemirror/cm-theme.ts +192 -0
  181. tools/bolt.diy/app/components/editor/codemirror/indent.ts +68 -0
  182. tools/bolt.diy/app/components/editor/codemirror/languages.ts +112 -0
  183. tools/bolt.diy/app/components/git/GitUrlImport.client.tsx +147 -0
  184. tools/bolt.diy/app/components/header/Header.tsx +42 -0
  185. tools/bolt.diy/app/components/header/HeaderActionButtons.client.tsx +54 -0
  186. tools/bolt.diy/app/components/mandate/MandateSubmission.tsx +167 -0
  187. tools/bolt.diy/app/components/observability/DeploymentStatus.tsx +168 -0
  188. tools/bolt.diy/app/components/observability/EventTimeline.tsx +119 -0
  189. tools/bolt.diy/app/components/observability/FileDiffViewer.tsx +121 -0
  190. tools/bolt.diy/app/components/observability/GovernanceStatus.tsx +197 -0
  191. tools/bolt.diy/app/components/observability/GovernorMetrics.tsx +246 -0
  192. tools/bolt.diy/app/components/observability/LogStream.tsx +244 -0
  193. tools/bolt.diy/app/components/observability/MandateDetails.tsx +201 -0
  194. tools/bolt.diy/app/components/observability/ObservabilityDashboard.tsx +200 -0
  195. tools/bolt.diy/app/components/sidebar/HistoryItem.tsx +187 -0
  196. tools/bolt.diy/app/components/sidebar/Menu.client.tsx +536 -0
  197. tools/bolt.diy/app/components/sidebar/date-binning.ts +59 -0
  198. tools/bolt.diy/app/components/txt +1 -0
  199. tools/bolt.diy/app/components/ui/BackgroundRays/index.tsx +18 -0
  200. tools/bolt.diy/app/components/ui/BackgroundRays/styles.module.scss +246 -0
  201. tools/bolt.diy/app/components/ui/Badge.tsx +53 -0
  202. tools/bolt.diy/app/components/ui/BranchSelector.tsx +270 -0
  203. tools/bolt.diy/app/components/ui/Breadcrumbs.tsx +101 -0
  204. tools/bolt.diy/app/components/ui/Button.tsx +46 -0
  205. tools/bolt.diy/app/components/ui/Card.tsx +55 -0
  206. tools/bolt.diy/app/components/ui/Checkbox.tsx +32 -0
  207. tools/bolt.diy/app/components/ui/CloseButton.tsx +49 -0
  208. tools/bolt.diy/app/components/ui/CodeBlock.tsx +103 -0
  209. tools/bolt.diy/app/components/ui/Collapsible.tsx +9 -0
  210. tools/bolt.diy/app/components/ui/ColorSchemeDialog.tsx +378 -0
  211. tools/bolt.diy/app/components/ui/Dialog.tsx +449 -0
  212. tools/bolt.diy/app/components/ui/Dropdown.tsx +63 -0
  213. tools/bolt.diy/app/components/ui/EmptyState.tsx +154 -0
  214. tools/bolt.diy/app/components/ui/FileIcon.tsx +346 -0
  215. tools/bolt.diy/app/components/ui/FilterChip.tsx +92 -0
  216. tools/bolt.diy/app/components/ui/GlowingEffect.tsx +192 -0
  217. tools/bolt.diy/app/components/ui/GradientCard.tsx +100 -0
  218. tools/bolt.diy/app/components/ui/IconButton.tsx +84 -0
  219. tools/bolt.diy/app/components/ui/Input.tsx +22 -0
  220. tools/bolt.diy/app/components/ui/Label.tsx +20 -0
  221. tools/bolt.diy/app/components/ui/LoadingDots.tsx +27 -0
  222. tools/bolt.diy/app/components/ui/LoadingOverlay.tsx +32 -0
  223. tools/bolt.diy/app/components/ui/PanelHeader.tsx +20 -0
  224. tools/bolt.diy/app/components/ui/PanelHeaderButton.tsx +36 -0
  225. tools/bolt.diy/app/components/ui/Popover.tsx +29 -0
  226. tools/bolt.diy/app/components/ui/Progress.tsx +22 -0
  227. tools/bolt.diy/app/components/ui/RepositoryStats.tsx +87 -0
  228. tools/bolt.diy/app/components/ui/ScrollArea.tsx +41 -0
  229. tools/bolt.diy/app/components/ui/SearchInput.tsx +80 -0
  230. tools/bolt.diy/app/components/ui/SearchResultItem.tsx +134 -0
  231. tools/bolt.diy/app/components/ui/Separator.tsx +22 -0
  232. tools/bolt.diy/app/components/ui/SettingsButton.tsx +35 -0
  233. tools/bolt.diy/app/components/ui/Slider.tsx +73 -0
  234. tools/bolt.diy/app/components/ui/StatusIndicator.tsx +90 -0
  235. tools/bolt.diy/app/components/ui/Switch.tsx +37 -0
  236. tools/bolt.diy/app/components/ui/Tabs.tsx +52 -0
  237. tools/bolt.diy/app/components/ui/TabsWithSlider.tsx +112 -0
  238. tools/bolt.diy/app/components/ui/ThemeSwitch.tsx +29 -0
  239. tools/bolt.diy/app/components/ui/Tooltip.tsx +122 -0
  240. tools/bolt.diy/app/components/ui/index.ts +38 -0
  241. tools/bolt.diy/app/components/ui/use-toast.ts +66 -0
  242. tools/bolt.diy/app/components/workbench/DiffView.tsx +796 -0
  243. tools/bolt.diy/app/components/workbench/EditorPanel.tsx +174 -0
  244. tools/bolt.diy/app/components/workbench/ExpoQrModal.tsx +55 -0
  245. tools/bolt.diy/app/components/workbench/FileBreadcrumb.tsx +150 -0
  246. tools/bolt.diy/app/components/workbench/FileTree.tsx +565 -0
  247. tools/bolt.diy/app/components/workbench/Inspector.tsx +126 -0
  248. tools/bolt.diy/app/components/workbench/InspectorPanel.tsx +146 -0
  249. tools/bolt.diy/app/components/workbench/LockManager.tsx +262 -0
  250. tools/bolt.diy/app/components/workbench/PortDropdown.tsx +91 -0
  251. tools/bolt.diy/app/components/workbench/Preview.tsx +1049 -0
  252. tools/bolt.diy/app/components/workbench/ScreenshotSelector.tsx +293 -0
  253. tools/bolt.diy/app/components/workbench/Search.tsx +257 -0
  254. tools/bolt.diy/app/components/workbench/Workbench.client.tsx +506 -0
  255. tools/bolt.diy/app/components/workbench/terminal/Terminal.tsx +131 -0
  256. tools/bolt.diy/app/components/workbench/terminal/TerminalManager.tsx +68 -0
  257. tools/bolt.diy/app/components/workbench/terminal/TerminalTabs.tsx +277 -0
  258. tools/bolt.diy/app/components/workbench/terminal/theme.ts +36 -0
  259. tools/bolt.diy/app/components/workflow/WorkflowPhase.tsx +109 -0
  260. tools/bolt.diy/app/components/workflow/WorkflowStatus.tsx +60 -0
  261. tools/bolt.diy/app/components/workflow/WorkflowTimeline.tsx +150 -0
  262. tools/bolt.diy/app/entry.client.tsx +7 -0
  263. tools/bolt.diy/app/entry.server.tsx +80 -0
  264. tools/bolt.diy/app/root.tsx +156 -0
  265. tools/bolt.diy/app/routes/_index.tsx +175 -0
  266. tools/bolt.diy/app/routes/api.bug-report.ts +254 -0
  267. tools/bolt.diy/app/routes/api.chat.ts +463 -0
  268. tools/bolt.diy/app/routes/api.check-env-key.ts +41 -0
  269. tools/bolt.diy/app/routes/api.configured-providers.ts +110 -0
  270. tools/bolt.diy/app/routes/api.corporate-swarm-status.ts +55 -0
  271. tools/bolt.diy/app/routes/api.enhancer.ts +137 -0
  272. tools/bolt.diy/app/routes/api.export-api-keys.ts +44 -0
  273. tools/bolt.diy/app/routes/api.git-info.ts +69 -0
  274. tools/bolt.diy/app/routes/api.git-proxy.$.ts +178 -0
  275. tools/bolt.diy/app/routes/api.github-branches.ts +166 -0
  276. tools/bolt.diy/app/routes/api.github-deploy.ts +67 -0
  277. tools/bolt.diy/app/routes/api.github-stats.ts +198 -0
  278. tools/bolt.diy/app/routes/api.github-template.ts +242 -0
  279. tools/bolt.diy/app/routes/api.github-user.ts +287 -0
  280. tools/bolt.diy/app/routes/api.gitlab-branches.ts +143 -0
  281. tools/bolt.diy/app/routes/api.gitlab-deploy.ts +67 -0
  282. tools/bolt.diy/app/routes/api.gitlab-projects.ts +105 -0
  283. tools/bolt.diy/app/routes/api.health.ts +8 -0
  284. tools/bolt.diy/app/routes/api.llmcall.ts +298 -0
  285. tools/bolt.diy/app/routes/api.mandate.ts +351 -0
  286. tools/bolt.diy/app/routes/api.mcp-check.ts +16 -0
  287. tools/bolt.diy/app/routes/api.mcp-update-config.ts +23 -0
  288. tools/bolt.diy/app/routes/api.models.$provider.ts +2 -0
  289. tools/bolt.diy/app/routes/api.models.ts +90 -0
  290. tools/bolt.diy/app/routes/api.netlify-deploy.ts +240 -0
  291. tools/bolt.diy/app/routes/api.netlify-user.ts +142 -0
  292. tools/bolt.diy/app/routes/api.supabase-user.ts +199 -0
  293. tools/bolt.diy/app/routes/api.supabase.query.ts +92 -0
  294. tools/bolt.diy/app/routes/api.supabase.ts +56 -0
  295. tools/bolt.diy/app/routes/api.supabase.variables.ts +32 -0
  296. tools/bolt.diy/app/routes/api.system.diagnostics.ts +142 -0
  297. tools/bolt.diy/app/routes/api.system.disk-info.ts +311 -0
  298. tools/bolt.diy/app/routes/api.system.git-info.ts +332 -0
  299. tools/bolt.diy/app/routes/api.update.ts +21 -0
  300. tools/bolt.diy/app/routes/api.vercel-deploy.ts +497 -0
  301. tools/bolt.diy/app/routes/api.vercel-user.ts +161 -0
  302. tools/bolt.diy/app/routes/api.workflow-status.$proposalId.ts +309 -0
  303. tools/bolt.diy/app/routes/chat.$id.tsx +8 -0
  304. tools/bolt.diy/app/routes/execute.$mandateId.tsx +432 -0
  305. tools/bolt.diy/app/routes/git.tsx +25 -0
  306. tools/bolt.diy/app/routes/observability.$mandateId.tsx +50 -0
  307. tools/bolt.diy/app/routes/webcontainer.connect.$id.tsx +32 -0
  308. tools/bolt.diy/app/routes/webcontainer.preview.$id.tsx +97 -0
  309. tools/bolt.diy/app/routes/workflow.$proposalId.tsx +170 -0
  310. tools/bolt.diy/app/styles/animations.scss +49 -0
  311. tools/bolt.diy/app/styles/components/code.scss +9 -0
  312. tools/bolt.diy/app/styles/components/editor.scss +135 -0
  313. tools/bolt.diy/app/styles/components/resize-handle.scss +30 -0
  314. tools/bolt.diy/app/styles/components/terminal.scss +3 -0
  315. tools/bolt.diy/app/styles/components/toast.scss +23 -0
  316. tools/bolt.diy/app/styles/diff-view.css +72 -0
  317. tools/bolt.diy/app/styles/index.scss +73 -0
  318. tools/bolt.diy/app/styles/variables.scss +255 -0
  319. tools/bolt.diy/app/styles/z-index.scss +37 -0
  320. tools/bolt.diy/app/types/GitHub.ts +182 -0
  321. tools/bolt.diy/app/types/GitLab.ts +103 -0
  322. tools/bolt.diy/app/types/actions.ts +85 -0
  323. tools/bolt.diy/app/types/artifact.ts +5 -0
  324. tools/bolt.diy/app/types/context.ts +26 -0
  325. tools/bolt.diy/app/types/design-scheme.ts +93 -0
  326. tools/bolt.diy/app/types/global.d.ts +13 -0
  327. tools/bolt.diy/app/types/mandate.ts +333 -0
  328. tools/bolt.diy/app/types/model.ts +25 -0
  329. tools/bolt.diy/app/types/netlify.ts +94 -0
  330. tools/bolt.diy/app/types/supabase.ts +54 -0
  331. tools/bolt.diy/app/types/template.ts +8 -0
  332. tools/bolt.diy/app/types/terminal.ts +9 -0
  333. tools/bolt.diy/app/types/theme.ts +1 -0
  334. tools/bolt.diy/app/types/vercel.ts +67 -0
  335. tools/bolt.diy/app/utils/buffer.ts +29 -0
  336. tools/bolt.diy/app/utils/classNames.ts +65 -0
  337. tools/bolt.diy/app/utils/constants.ts +147 -0
  338. tools/bolt.diy/app/utils/debounce.ts +13 -0
  339. tools/bolt.diy/app/utils/debugLogger.ts +1284 -0
  340. tools/bolt.diy/app/utils/diff.spec.ts +11 -0
  341. tools/bolt.diy/app/utils/diff.ts +117 -0
  342. tools/bolt.diy/app/utils/easings.ts +3 -0
  343. tools/bolt.diy/app/utils/fileLocks.ts +96 -0
  344. tools/bolt.diy/app/utils/fileUtils.ts +121 -0
  345. tools/bolt.diy/app/utils/folderImport.ts +73 -0
  346. tools/bolt.diy/app/utils/formatSize.ts +12 -0
  347. tools/bolt.diy/app/utils/getLanguageFromExtension.ts +24 -0
  348. tools/bolt.diy/app/utils/githubStats.ts +9 -0
  349. tools/bolt.diy/app/utils/gitlabStats.ts +54 -0
  350. tools/bolt.diy/app/utils/logger.ts +162 -0
  351. tools/bolt.diy/app/utils/markdown.ts +155 -0
  352. tools/bolt.diy/app/utils/mobile.ts +4 -0
  353. tools/bolt.diy/app/utils/os.ts +4 -0
  354. tools/bolt.diy/app/utils/path.ts +19 -0
  355. tools/bolt.diy/app/utils/projectCommands.ts +197 -0
  356. tools/bolt.diy/app/utils/promises.ts +19 -0
  357. tools/bolt.diy/app/utils/react.ts +6 -0
  358. tools/bolt.diy/app/utils/sampler.ts +49 -0
  359. tools/bolt.diy/app/utils/selectStarterTemplate.ts +255 -0
  360. tools/bolt.diy/app/utils/shell.ts +384 -0
  361. tools/bolt.diy/app/utils/stacktrace.ts +27 -0
  362. tools/bolt.diy/app/utils/stripIndent.ts +23 -0
  363. tools/bolt.diy/app/utils/terminal.ts +11 -0
  364. tools/bolt.diy/app/utils/unreachable.ts +3 -0
  365. tools/bolt.diy/app/vite-env.d.ts +2 -0
  366. tools/bolt.diy/assets/entitlements.mac.plist +25 -0
  367. tools/bolt.diy/assets/icons/icon.icns +0 -0
  368. tools/bolt.diy/assets/icons/icon.ico +0 -0
  369. tools/bolt.diy/assets/icons/icon.png +0 -0
  370. tools/bolt.diy/bindings.js +78 -0
  371. tools/bolt.diy/bindings.sh +33 -0
  372. tools/bolt.diy/docker-compose.yaml +145 -0
  373. tools/bolt.diy/electron/main/index.ts +201 -0
  374. tools/bolt.diy/electron/main/tsconfig.json +30 -0
  375. tools/bolt.diy/electron/main/ui/menu.ts +29 -0
  376. tools/bolt.diy/electron/main/ui/window.ts +54 -0
  377. tools/bolt.diy/electron/main/utils/auto-update.ts +110 -0
  378. tools/bolt.diy/electron/main/utils/constants.ts +4 -0
  379. tools/bolt.diy/electron/main/utils/cookie.ts +40 -0
  380. tools/bolt.diy/electron/main/utils/reload.ts +35 -0
  381. tools/bolt.diy/electron/main/utils/serve.ts +71 -0
  382. tools/bolt.diy/electron/main/utils/store.ts +3 -0
  383. tools/bolt.diy/electron/main/utils/vite-server.ts +44 -0
  384. tools/bolt.diy/electron/main/vite.config.ts +44 -0
  385. tools/bolt.diy/electron/preload/index.ts +22 -0
  386. tools/bolt.diy/electron/preload/tsconfig.json +7 -0
  387. tools/bolt.diy/electron/preload/vite.config.ts +31 -0
  388. tools/bolt.diy/electron-builder.yml +64 -0
  389. tools/bolt.diy/electron-update.yml +4 -0
  390. tools/bolt.diy/eslint.config.mjs +57 -0
  391. tools/bolt.diy/functions/[[path]].ts +12 -0
  392. tools/bolt.diy/icons/angular.svg +1 -0
  393. tools/bolt.diy/icons/astro.svg +8 -0
  394. tools/bolt.diy/icons/chat.svg +1 -0
  395. tools/bolt.diy/icons/expo-brand.svg +1 -0
  396. tools/bolt.diy/icons/expo.svg +4 -0
  397. tools/bolt.diy/icons/logo-text.svg +1 -0
  398. tools/bolt.diy/icons/logo.svg +4 -0
  399. tools/bolt.diy/icons/mcp.svg +1 -0
  400. tools/bolt.diy/icons/nativescript.svg +1 -0
  401. tools/bolt.diy/icons/netlify.svg +10 -0
  402. tools/bolt.diy/icons/nextjs.svg +1 -0
  403. tools/bolt.diy/icons/nuxt.svg +1 -0
  404. tools/bolt.diy/icons/qwik.svg +1 -0
  405. tools/bolt.diy/icons/react.svg +1 -0
  406. tools/bolt.diy/icons/remix.svg +24 -0
  407. tools/bolt.diy/icons/remotion.svg +1 -0
  408. tools/bolt.diy/icons/shadcn.svg +21 -0
  409. tools/bolt.diy/icons/slidev.svg +60 -0
  410. tools/bolt.diy/icons/solidjs.svg +1 -0
  411. tools/bolt.diy/icons/stars.svg +1 -0
  412. tools/bolt.diy/icons/svelte.svg +1 -0
  413. tools/bolt.diy/icons/typescript.svg +1 -0
  414. tools/bolt.diy/icons/vite.svg +1 -0
  415. tools/bolt.diy/icons/vue.svg +1 -0
  416. tools/bolt.diy/load-context.ts +9 -0
  417. tools/bolt.diy/notarize.cjs +31 -0
  418. tools/bolt.diy/package.json +218 -0
  419. tools/bolt.diy/playwright.config.preview.ts +35 -0
  420. tools/bolt.diy/pre-start.cjs +26 -0
  421. tools/bolt.diy/public/apple-touch-icon-precomposed.png +0 -0
  422. tools/bolt.diy/public/apple-touch-icon.png +0 -0
  423. tools/bolt.diy/public/favicon.ico +0 -0
  424. tools/bolt.diy/public/favicon.svg +4 -0
  425. tools/bolt.diy/public/icons/AmazonBedrock.svg +1 -0
  426. tools/bolt.diy/public/icons/Anthropic.svg +4 -0
  427. tools/bolt.diy/public/icons/Cohere.svg +4 -0
  428. tools/bolt.diy/public/icons/Deepseek.svg +5 -0
  429. tools/bolt.diy/public/icons/Default.svg +4 -0
  430. tools/bolt.diy/public/icons/Google.svg +4 -0
  431. tools/bolt.diy/public/icons/Groq.svg +4 -0
  432. tools/bolt.diy/public/icons/HuggingFace.svg +4 -0
  433. tools/bolt.diy/public/icons/Hyperbolic.svg +3 -0
  434. tools/bolt.diy/public/icons/LMStudio.svg +5 -0
  435. tools/bolt.diy/public/icons/Mistral.svg +4 -0
  436. tools/bolt.diy/public/icons/Ollama.svg +4 -0
  437. tools/bolt.diy/public/icons/OpenAI.svg +4 -0
  438. tools/bolt.diy/public/icons/OpenAILike.svg +4 -0
  439. tools/bolt.diy/public/icons/OpenRouter.svg +4 -0
  440. tools/bolt.diy/public/icons/Perplexity.svg +4 -0
  441. tools/bolt.diy/public/icons/Together.svg +4 -0
  442. tools/bolt.diy/public/icons/xAI.svg +5 -0
  443. tools/bolt.diy/public/inspector-script.js +292 -0
  444. tools/bolt.diy/public/logo-dark-styled.png +0 -0
  445. tools/bolt.diy/public/logo-dark.png +0 -0
  446. tools/bolt.diy/public/logo-light-styled.png +0 -0
  447. tools/bolt.diy/public/logo-light.png +0 -0
  448. tools/bolt.diy/public/logo.svg +15 -0
  449. tools/bolt.diy/public/social_preview_index.jpg +0 -0
  450. tools/bolt.diy/scripts/clean.js +45 -0
  451. tools/bolt.diy/scripts/electron-dev.mjs +181 -0
  452. tools/bolt.diy/scripts/setup-env.sh +41 -0
  453. tools/bolt.diy/scripts/update-imports.sh +7 -0
  454. tools/bolt.diy/scripts/update.sh +52 -0
  455. tools/bolt.diy/services/execution-governor/Dockerfile +41 -0
  456. tools/bolt.diy/services/execution-governor/config.ts +42 -0
  457. tools/bolt.diy/services/execution-governor/index.ts +683 -0
  458. tools/bolt.diy/services/execution-governor/metrics.ts +141 -0
  459. tools/bolt.diy/services/execution-governor/package.json +31 -0
  460. tools/bolt.diy/services/execution-governor/priority-queue.ts +139 -0
  461. tools/bolt.diy/services/execution-governor/tsconfig.json +21 -0
  462. tools/bolt.diy/services/execution-governor/types.ts +145 -0
  463. tools/bolt.diy/services/headless-executor/Dockerfile +43 -0
  464. tools/bolt.diy/services/headless-executor/executor.ts +210 -0
  465. tools/bolt.diy/services/headless-executor/index.ts +323 -0
  466. tools/bolt.diy/services/headless-executor/package.json +27 -0
  467. tools/bolt.diy/services/headless-executor/tsconfig.json +21 -0
  468. tools/bolt.diy/services/headless-executor/types.ts +38 -0
  469. tools/bolt.diy/test-workflows.sh +240 -0
  470. tools/bolt.diy/tests/integration/corporate-swarm.test.ts +208 -0
  471. tools/bolt.diy/tests/mandates/budget-limited.json +34 -0
  472. tools/bolt.diy/tests/mandates/complex.json +53 -0
  473. tools/bolt.diy/tests/mandates/constraint-enforced.json +36 -0
  474. tools/bolt.diy/tests/mandates/simple.json +35 -0
  475. tools/bolt.diy/tsconfig.json +37 -0
  476. tools/bolt.diy/types/istextorbinary.d.ts +15 -0
  477. tools/bolt.diy/uno.config.ts +279 -0
  478. tools/bolt.diy/vite-electron.config.ts +76 -0
  479. tools/bolt.diy/vite.config.ts +112 -0
  480. tools/bolt.diy/worker-configuration.d.ts +22 -0
  481. tools/bolt.diy/wrangler.toml +6 -0
  482. tools/code_generator.py +461 -0
  483. tools/file_operations.py +465 -0
  484. tools/mandate_generator.py +337 -0
  485. tools/mcpClientUtils.py +1216 -0
  486. tools/sensors.py +285 -0
  487. utils/Agent_types.py +15 -0
  488. utils/AnyToStr.py +0 -0
  489. utils/HHCS.py +277 -0
  490. utils/__init__.py +30 -0
  491. utils/agent.py +3627 -0
  492. utils/aop.py +2948 -0
  493. utils/canonical.py +143 -0
  494. utils/conversation.py +1195 -0
  495. utils/doctrine_versioning +230 -0
  496. utils/formatter.py +474 -0
  497. utils/ledger.py +311 -0
  498. utils/out_types.py +16 -0
  499. utils/rollback.py +339 -0
  500. utils/router.py +929 -0
  501. utils/tui.py +1908 -0
@@ -0,0 +1,796 @@
1
+ import { memo, useMemo, useState, useEffect, useCallback } from 'react';
2
+ import { useStore } from '@nanostores/react';
3
+ import { workbenchStore } from '~/lib/stores/workbench';
4
+ import type { FileMap } from '~/lib/stores/files';
5
+ import type { EditorDocument } from '~/components/editor/codemirror/CodeMirrorEditor';
6
+ import { diffLines, type Change } from 'diff';
7
+ import { getHighlighter } from 'shiki';
8
+ import '~/styles/diff-view.css';
9
+ import { diffFiles, extractRelativePath } from '~/utils/diff';
10
+ import type { FileHistory } from '~/types/actions';
11
+ import { getLanguageFromExtension } from '~/utils/getLanguageFromExtension';
12
+ import { themeStore } from '~/lib/stores/theme';
13
+
14
+ interface CodeComparisonProps {
15
+ beforeCode: string;
16
+ afterCode: string;
17
+ language: string;
18
+ filename: string;
19
+ lightTheme: string;
20
+ darkTheme: string;
21
+ }
22
+
23
+ interface DiffBlock {
24
+ lineNumber: number;
25
+ content: string;
26
+ type: 'added' | 'removed' | 'unchanged';
27
+ correspondingLine?: number;
28
+ charChanges?: Array<{
29
+ value: string;
30
+ type: 'added' | 'removed' | 'unchanged';
31
+ }>;
32
+ }
33
+
34
+ interface FullscreenButtonProps {
35
+ onClick: () => void;
36
+ isFullscreen: boolean;
37
+ }
38
+
39
+ const FullscreenButton = memo(({ onClick, isFullscreen }: FullscreenButtonProps) => (
40
+ <button
41
+ onClick={onClick}
42
+ className="ml-4 p-1 rounded hover:bg-bolt-elements-background-depth-3 text-bolt-elements-textTertiary hover:text-bolt-elements-textPrimary transition-colors"
43
+ title={isFullscreen ? 'Exit Fullscreen' : 'Enter Fullscreen'}
44
+ >
45
+ <div className={isFullscreen ? 'i-ph:corners-in' : 'i-ph:corners-out'} />
46
+ </button>
47
+ ));
48
+
49
+ const FullscreenOverlay = memo(({ isFullscreen, children }: { isFullscreen: boolean; children: React.ReactNode }) => {
50
+ if (!isFullscreen) {
51
+ return <>{children}</>;
52
+ }
53
+
54
+ return (
55
+ <div className="fixed inset-0 z-[9999] bg-black/50 flex items-center justify-center p-6">
56
+ <div className="w-full h-full max-w-[90vw] max-h-[90vh] bg-bolt-elements-background-depth-2 rounded-lg border border-bolt-elements-borderColor shadow-xl overflow-hidden">
57
+ {children}
58
+ </div>
59
+ </div>
60
+ );
61
+ });
62
+
63
+ const MAX_FILE_SIZE = 1024 * 1024; // 1MB
64
+ const BINARY_REGEX = /[\x00-\x08\x0E-\x1F]/;
65
+
66
+ const isBinaryFile = (content: string) => {
67
+ return content.length > MAX_FILE_SIZE || BINARY_REGEX.test(content);
68
+ };
69
+
70
+ const processChanges = (beforeCode: string, afterCode: string) => {
71
+ try {
72
+ if (isBinaryFile(beforeCode) || isBinaryFile(afterCode)) {
73
+ return {
74
+ beforeLines: [],
75
+ afterLines: [],
76
+ hasChanges: false,
77
+ lineChanges: { before: new Set(), after: new Set() },
78
+ unifiedBlocks: [],
79
+ isBinary: true,
80
+ };
81
+ }
82
+
83
+ // Normalize line endings and content
84
+ const normalizeContent = (content: string): string[] => {
85
+ return content
86
+ .replace(/\r\n/g, '\n')
87
+ .split('\n')
88
+ .map((line) => line.trimEnd());
89
+ };
90
+
91
+ const beforeLines = normalizeContent(beforeCode);
92
+ const afterLines = normalizeContent(afterCode);
93
+
94
+ // Early return if files are identical
95
+ if (beforeLines.join('\n') === afterLines.join('\n')) {
96
+ return {
97
+ beforeLines,
98
+ afterLines,
99
+ hasChanges: false,
100
+ lineChanges: { before: new Set(), after: new Set() },
101
+ unifiedBlocks: [],
102
+ isBinary: false,
103
+ };
104
+ }
105
+
106
+ const lineChanges = {
107
+ before: new Set<number>(),
108
+ after: new Set<number>(),
109
+ };
110
+
111
+ const unifiedBlocks: DiffBlock[] = [];
112
+
113
+ // Compare lines directly for more accurate diff
114
+ let i = 0,
115
+ j = 0;
116
+
117
+ while (i < beforeLines.length || j < afterLines.length) {
118
+ if (i < beforeLines.length && j < afterLines.length && beforeLines[i] === afterLines[j]) {
119
+ // Unchanged line
120
+ unifiedBlocks.push({
121
+ lineNumber: j,
122
+ content: afterLines[j],
123
+ type: 'unchanged',
124
+ correspondingLine: i,
125
+ });
126
+ i++;
127
+ j++;
128
+ } else {
129
+ // Look ahead for potential matches
130
+ let matchFound = false;
131
+ const lookAhead = 3; // Number of lines to look ahead
132
+
133
+ // Try to find matching lines ahead
134
+ for (let k = 1; k <= lookAhead && i + k < beforeLines.length && j + k < afterLines.length; k++) {
135
+ if (beforeLines[i + k] === afterLines[j]) {
136
+ // Found match in after lines - mark lines as removed
137
+ for (let l = 0; l < k; l++) {
138
+ lineChanges.before.add(i + l);
139
+ unifiedBlocks.push({
140
+ lineNumber: i + l,
141
+ content: beforeLines[i + l],
142
+ type: 'removed',
143
+ correspondingLine: j,
144
+ charChanges: [{ value: beforeLines[i + l], type: 'removed' }],
145
+ });
146
+ }
147
+ i += k;
148
+ matchFound = true;
149
+ break;
150
+ } else if (beforeLines[i] === afterLines[j + k]) {
151
+ // Found match in before lines - mark lines as added
152
+ for (let l = 0; l < k; l++) {
153
+ lineChanges.after.add(j + l);
154
+ unifiedBlocks.push({
155
+ lineNumber: j + l,
156
+ content: afterLines[j + l],
157
+ type: 'added',
158
+ correspondingLine: i,
159
+ charChanges: [{ value: afterLines[j + l], type: 'added' }],
160
+ });
161
+ }
162
+ j += k;
163
+ matchFound = true;
164
+ break;
165
+ }
166
+ }
167
+
168
+ if (!matchFound) {
169
+ // No match found - try to find character-level changes
170
+ if (i < beforeLines.length && j < afterLines.length) {
171
+ const beforeLine = beforeLines[i];
172
+ const afterLine = afterLines[j];
173
+
174
+ // Find common prefix and suffix
175
+ let prefixLength = 0;
176
+
177
+ while (
178
+ prefixLength < beforeLine.length &&
179
+ prefixLength < afterLine.length &&
180
+ beforeLine[prefixLength] === afterLine[prefixLength]
181
+ ) {
182
+ prefixLength++;
183
+ }
184
+
185
+ let suffixLength = 0;
186
+
187
+ while (
188
+ suffixLength < beforeLine.length - prefixLength &&
189
+ suffixLength < afterLine.length - prefixLength &&
190
+ beforeLine[beforeLine.length - 1 - suffixLength] === afterLine[afterLine.length - 1 - suffixLength]
191
+ ) {
192
+ suffixLength++;
193
+ }
194
+
195
+ const prefix = beforeLine.slice(0, prefixLength);
196
+ const beforeMiddle = beforeLine.slice(prefixLength, beforeLine.length - suffixLength);
197
+ const afterMiddle = afterLine.slice(prefixLength, afterLine.length - suffixLength);
198
+ const suffix = beforeLine.slice(beforeLine.length - suffixLength);
199
+
200
+ if (beforeMiddle || afterMiddle) {
201
+ // There are character-level changes
202
+ if (beforeMiddle) {
203
+ lineChanges.before.add(i);
204
+ unifiedBlocks.push({
205
+ lineNumber: i,
206
+ content: beforeLine,
207
+ type: 'removed',
208
+ correspondingLine: j,
209
+ charChanges: [
210
+ { value: prefix, type: 'unchanged' },
211
+ { value: beforeMiddle, type: 'removed' },
212
+ { value: suffix, type: 'unchanged' },
213
+ ],
214
+ });
215
+ i++;
216
+ }
217
+
218
+ if (afterMiddle) {
219
+ lineChanges.after.add(j);
220
+ unifiedBlocks.push({
221
+ lineNumber: j,
222
+ content: afterLine,
223
+ type: 'added',
224
+ correspondingLine: i - 1,
225
+ charChanges: [
226
+ { value: prefix, type: 'unchanged' },
227
+ { value: afterMiddle, type: 'added' },
228
+ { value: suffix, type: 'unchanged' },
229
+ ],
230
+ });
231
+ j++;
232
+ }
233
+ } else {
234
+ // No character-level changes found, treat as regular line changes
235
+ if (i < beforeLines.length) {
236
+ lineChanges.before.add(i);
237
+ unifiedBlocks.push({
238
+ lineNumber: i,
239
+ content: beforeLines[i],
240
+ type: 'removed',
241
+ correspondingLine: j,
242
+ charChanges: [{ value: beforeLines[i], type: 'removed' }],
243
+ });
244
+ i++;
245
+ }
246
+
247
+ if (j < afterLines.length) {
248
+ lineChanges.after.add(j);
249
+ unifiedBlocks.push({
250
+ lineNumber: j,
251
+ content: afterLines[j],
252
+ type: 'added',
253
+ correspondingLine: i - 1,
254
+ charChanges: [{ value: afterLines[j], type: 'added' }],
255
+ });
256
+ j++;
257
+ }
258
+ }
259
+ } else {
260
+ // Handle remaining lines
261
+ if (i < beforeLines.length) {
262
+ lineChanges.before.add(i);
263
+ unifiedBlocks.push({
264
+ lineNumber: i,
265
+ content: beforeLines[i],
266
+ type: 'removed',
267
+ correspondingLine: j,
268
+ charChanges: [{ value: beforeLines[i], type: 'removed' }],
269
+ });
270
+ i++;
271
+ }
272
+
273
+ if (j < afterLines.length) {
274
+ lineChanges.after.add(j);
275
+ unifiedBlocks.push({
276
+ lineNumber: j,
277
+ content: afterLines[j],
278
+ type: 'added',
279
+ correspondingLine: i - 1,
280
+ charChanges: [{ value: afterLines[j], type: 'added' }],
281
+ });
282
+ j++;
283
+ }
284
+ }
285
+ }
286
+ }
287
+ }
288
+
289
+ // Sort blocks by line number
290
+ const processedBlocks = unifiedBlocks.sort((a, b) => a.lineNumber - b.lineNumber);
291
+
292
+ return {
293
+ beforeLines,
294
+ afterLines,
295
+ hasChanges: lineChanges.before.size > 0 || lineChanges.after.size > 0,
296
+ lineChanges,
297
+ unifiedBlocks: processedBlocks,
298
+ isBinary: false,
299
+ };
300
+ } catch (error) {
301
+ console.error('Error processing changes:', error);
302
+ return {
303
+ beforeLines: [],
304
+ afterLines: [],
305
+ hasChanges: false,
306
+ lineChanges: { before: new Set(), after: new Set() },
307
+ unifiedBlocks: [],
308
+ error: true,
309
+ isBinary: false,
310
+ };
311
+ }
312
+ };
313
+
314
+ const lineNumberStyles =
315
+ 'w-9 shrink-0 pl-2 py-1 text-left font-mono text-bolt-elements-textTertiary border-r border-bolt-elements-borderColor bg-bolt-elements-background-depth-1';
316
+ const lineContentStyles =
317
+ 'px-1 py-1 font-mono whitespace-pre flex-1 group-hover:bg-bolt-elements-background-depth-2 text-bolt-elements-textPrimary';
318
+ const diffPanelStyles = 'h-full overflow-auto diff-panel-content';
319
+
320
+ // Updated color styles for better consistency
321
+ const diffLineStyles = {
322
+ added: 'bg-green-500/10 dark:bg-green-500/20 border-l-4 border-green-500',
323
+ removed: 'bg-red-500/10 dark:bg-red-500/20 border-l-4 border-red-500',
324
+ unchanged: '',
325
+ };
326
+
327
+ const changeColorStyles = {
328
+ added: 'text-green-700 dark:text-green-500 bg-green-500/10 dark:bg-green-500/20',
329
+ removed: 'text-red-700 dark:text-red-500 bg-red-500/10 dark:bg-red-500/20',
330
+ unchanged: 'text-bolt-elements-textPrimary',
331
+ };
332
+
333
+ const renderContentWarning = (type: 'binary' | 'error') => (
334
+ <div className="h-full flex items-center justify-center p-4">
335
+ <div className="text-center text-bolt-elements-textTertiary">
336
+ <div className={`i-ph:${type === 'binary' ? 'file-x' : 'warning-circle'} text-4xl text-red-400 mb-2 mx-auto`} />
337
+ <p className="font-medium text-bolt-elements-textPrimary">
338
+ {type === 'binary' ? 'Binary file detected' : 'Error processing file'}
339
+ </p>
340
+ <p className="text-sm mt-1">
341
+ {type === 'binary' ? 'Diff view is not available for binary files' : 'Could not generate diff preview'}
342
+ </p>
343
+ </div>
344
+ </div>
345
+ );
346
+
347
+ const NoChangesView = memo(
348
+ ({
349
+ beforeCode,
350
+ language,
351
+ highlighter,
352
+ theme,
353
+ }: {
354
+ beforeCode: string;
355
+ language: string;
356
+ highlighter: any;
357
+ theme: string;
358
+ }) => (
359
+ <div className="h-full flex flex-col items-center justify-center p-4">
360
+ <div className="text-center text-bolt-elements-textTertiary">
361
+ <div className="i-ph:files text-4xl text-green-400 mb-2 mx-auto" />
362
+ <p className="font-medium text-bolt-elements-textPrimary">Files are identical</p>
363
+ <p className="text-sm mt-1">Both versions match exactly</p>
364
+ </div>
365
+ <div className="mt-4 w-full max-w-2xl bg-bolt-elements-background-depth-1 rounded-lg border border-bolt-elements-borderColor overflow-hidden">
366
+ <div className="p-2 text-xs font-bold text-bolt-elements-textTertiary border-b border-bolt-elements-borderColor">
367
+ Current Content
368
+ </div>
369
+ <div className="overflow-auto max-h-96">
370
+ {beforeCode.split('\n').map((line, index) => (
371
+ <div key={index} className="flex group min-w-fit">
372
+ <div className={lineNumberStyles}>{index + 1}</div>
373
+ <div className={lineContentStyles}>
374
+ <span className="mr-2"> </span>
375
+ <span
376
+ dangerouslySetInnerHTML={{
377
+ __html: highlighter
378
+ ? highlighter
379
+ .codeToHtml(line, {
380
+ lang: language,
381
+ theme: theme === 'dark' ? 'github-dark' : 'github-light',
382
+ })
383
+ .replace(/<\/?pre[^>]*>/g, '')
384
+ .replace(/<\/?code[^>]*>/g, '')
385
+ : line,
386
+ }}
387
+ />
388
+ </div>
389
+ </div>
390
+ ))}
391
+ </div>
392
+ </div>
393
+ </div>
394
+ ),
395
+ );
396
+
397
+ // Otimização do processamento de diferenças com memoização
398
+ const useProcessChanges = (beforeCode: string, afterCode: string) => {
399
+ return useMemo(() => processChanges(beforeCode, afterCode), [beforeCode, afterCode]);
400
+ };
401
+
402
+ // Componente otimizado para renderização de linhas de código
403
+ const CodeLine = memo(
404
+ ({
405
+ lineNumber,
406
+ content,
407
+ type,
408
+ highlighter,
409
+ language,
410
+ block,
411
+ theme,
412
+ }: {
413
+ lineNumber: number;
414
+ content: string;
415
+ type: 'added' | 'removed' | 'unchanged';
416
+ highlighter: any;
417
+ language: string;
418
+ block: DiffBlock;
419
+ theme: string;
420
+ }) => {
421
+ const bgColor = diffLineStyles[type];
422
+
423
+ const renderContent = () => {
424
+ if (type === 'unchanged' || !block.charChanges) {
425
+ const highlightedCode = highlighter
426
+ ? highlighter
427
+ .codeToHtml(content, { lang: language, theme: theme === 'dark' ? 'github-dark' : 'github-light' })
428
+ .replace(/<\/?pre[^>]*>/g, '')
429
+ .replace(/<\/?code[^>]*>/g, '')
430
+ : content;
431
+ return <span dangerouslySetInnerHTML={{ __html: highlightedCode }} />;
432
+ }
433
+
434
+ return (
435
+ <>
436
+ {block.charChanges.map((change, index) => {
437
+ const changeClass = changeColorStyles[change.type];
438
+
439
+ const highlightedCode = highlighter
440
+ ? highlighter
441
+ .codeToHtml(change.value, {
442
+ lang: language,
443
+ theme: theme === 'dark' ? 'github-dark' : 'github-light',
444
+ })
445
+ .replace(/<\/?pre[^>]*>/g, '')
446
+ .replace(/<\/?code[^>]*>/g, '')
447
+ : change.value;
448
+
449
+ return <span key={index} className={changeClass} dangerouslySetInnerHTML={{ __html: highlightedCode }} />;
450
+ })}
451
+ </>
452
+ );
453
+ };
454
+
455
+ return (
456
+ <div className="flex group min-w-fit">
457
+ <div className={lineNumberStyles}>{lineNumber + 1}</div>
458
+ <div className={`${lineContentStyles} ${bgColor}`}>
459
+ <span className="mr-2 text-bolt-elements-textTertiary">
460
+ {type === 'added' && <span className="text-green-700 dark:text-green-500">+</span>}
461
+ {type === 'removed' && <span className="text-red-700 dark:text-red-500">-</span>}
462
+ {type === 'unchanged' && ' '}
463
+ </span>
464
+ {renderContent()}
465
+ </div>
466
+ </div>
467
+ );
468
+ },
469
+ );
470
+
471
+ // Componente para exibir informações sobre o arquivo
472
+ const FileInfo = memo(
473
+ ({
474
+ filename,
475
+ hasChanges,
476
+ onToggleFullscreen,
477
+ isFullscreen,
478
+ beforeCode,
479
+ afterCode,
480
+ }: {
481
+ filename: string;
482
+ hasChanges: boolean;
483
+ onToggleFullscreen: () => void;
484
+ isFullscreen: boolean;
485
+ beforeCode: string;
486
+ afterCode: string;
487
+ }) => {
488
+ // Calculate additions and deletions from the current document
489
+ const { additions, deletions } = useMemo(() => {
490
+ if (!hasChanges) {
491
+ return { additions: 0, deletions: 0 };
492
+ }
493
+
494
+ const changes = diffLines(beforeCode, afterCode, {
495
+ newlineIsToken: false,
496
+ ignoreWhitespace: true,
497
+ ignoreCase: false,
498
+ });
499
+
500
+ return changes.reduce(
501
+ (acc: { additions: number; deletions: number }, change: Change) => {
502
+ if (change.added) {
503
+ acc.additions += change.value.split('\n').length;
504
+ }
505
+
506
+ if (change.removed) {
507
+ acc.deletions += change.value.split('\n').length;
508
+ }
509
+
510
+ return acc;
511
+ },
512
+ { additions: 0, deletions: 0 },
513
+ );
514
+ }, [hasChanges, beforeCode, afterCode]);
515
+
516
+ const showStats = additions > 0 || deletions > 0;
517
+
518
+ return (
519
+ <div className="flex items-center bg-bolt-elements-background-depth-1 p-2 text-sm text-bolt-elements-textPrimary shrink-0">
520
+ <div className="i-ph:file mr-2 h-4 w-4 shrink-0" />
521
+ <span className="truncate">{filename}</span>
522
+ <span className="ml-auto shrink-0 flex items-center gap-2">
523
+ {hasChanges ? (
524
+ <>
525
+ {showStats && (
526
+ <div className="flex items-center gap-1 text-xs">
527
+ {additions > 0 && <span className="text-green-700 dark:text-green-500">+{additions}</span>}
528
+ {deletions > 0 && <span className="text-red-700 dark:text-red-500">-{deletions}</span>}
529
+ </div>
530
+ )}
531
+ <span className="text-yellow-600 dark:text-yellow-400">Modified</span>
532
+ <span className="text-bolt-elements-textTertiary text-xs">{new Date().toLocaleTimeString()}</span>
533
+ </>
534
+ ) : (
535
+ <span className="text-green-700 dark:text-green-400">No Changes</span>
536
+ )}
537
+ <FullscreenButton onClick={onToggleFullscreen} isFullscreen={isFullscreen} />
538
+ </span>
539
+ </div>
540
+ );
541
+ },
542
+ );
543
+
544
+ // Create and manage a single highlighter instance at the module level
545
+ let highlighterInstance: any = null;
546
+ let highlighterPromise: Promise<any> | null = null;
547
+
548
+ const getSharedHighlighter = async () => {
549
+ if (highlighterInstance) {
550
+ return highlighterInstance;
551
+ }
552
+
553
+ if (highlighterPromise) {
554
+ return highlighterPromise;
555
+ }
556
+
557
+ highlighterPromise = getHighlighter({
558
+ themes: ['github-dark', 'github-light'],
559
+ langs: [
560
+ 'typescript',
561
+ 'javascript',
562
+ 'json',
563
+ 'html',
564
+ 'css',
565
+ 'jsx',
566
+ 'tsx',
567
+ 'python',
568
+ 'php',
569
+ 'java',
570
+ 'c',
571
+ 'cpp',
572
+ 'csharp',
573
+ 'go',
574
+ 'ruby',
575
+ 'rust',
576
+ 'plaintext',
577
+ ],
578
+ });
579
+
580
+ highlighterInstance = await highlighterPromise;
581
+ highlighterPromise = null;
582
+
583
+ // Clear the promise once resolved
584
+ return highlighterInstance;
585
+ };
586
+
587
+ const InlineDiffComparison = memo(({ beforeCode, afterCode, filename, language }: CodeComparisonProps) => {
588
+ const [isFullscreen, setIsFullscreen] = useState(false);
589
+
590
+ // Use state to hold the shared highlighter instance
591
+ const [highlighter, setHighlighter] = useState<any>(null);
592
+ const theme = useStore(themeStore);
593
+
594
+ const toggleFullscreen = useCallback(() => {
595
+ setIsFullscreen((prev) => !prev);
596
+ }, []);
597
+
598
+ const { unifiedBlocks, hasChanges, isBinary, error } = useProcessChanges(beforeCode, afterCode);
599
+
600
+ useEffect(() => {
601
+ // Fetch the shared highlighter instance
602
+ getSharedHighlighter().then(setHighlighter);
603
+
604
+ /*
605
+ * No cleanup needed here for the highlighter instance itself,
606
+ * as it's managed globally. Shiki instances don't typically
607
+ * need disposal unless you are dynamically loading/unloading themes/languages.
608
+ * If you were dynamically loading, you might need a more complex
609
+ * shared instance manager with reference counting or similar.
610
+ * For static themes/langs, a single instance is sufficient.
611
+ */
612
+ }, []); // Empty dependency array ensures this runs only once on mount
613
+
614
+ if (isBinary || error) {
615
+ return renderContentWarning(isBinary ? 'binary' : 'error');
616
+ }
617
+
618
+ // Render a loading state or null while highlighter is not ready
619
+ if (!highlighter) {
620
+ return (
621
+ <div className="h-full flex items-center justify-center">
622
+ <div className="text-bolt-elements-textTertiary">Loading diff...</div>
623
+ </div>
624
+ );
625
+ }
626
+
627
+ return (
628
+ <FullscreenOverlay isFullscreen={isFullscreen}>
629
+ <div className="w-full h-full flex flex-col">
630
+ <FileInfo
631
+ filename={filename}
632
+ hasChanges={hasChanges}
633
+ onToggleFullscreen={toggleFullscreen}
634
+ isFullscreen={isFullscreen}
635
+ beforeCode={beforeCode}
636
+ afterCode={afterCode}
637
+ />
638
+ <div className={diffPanelStyles}>
639
+ {hasChanges ? (
640
+ <div className="overflow-x-auto min-w-full">
641
+ {unifiedBlocks.map((block, index) => (
642
+ <CodeLine
643
+ key={`${block.lineNumber}-${index}`}
644
+ lineNumber={block.lineNumber}
645
+ content={block.content}
646
+ type={block.type}
647
+ highlighter={highlighter} // Pass the shared instance
648
+ language={language}
649
+ block={block}
650
+ theme={theme}
651
+ />
652
+ ))}
653
+ </div>
654
+ ) : (
655
+ <NoChangesView beforeCode={beforeCode} language={language} highlighter={highlighter} theme={theme} />
656
+ )}
657
+ </div>
658
+ </div>
659
+ </FullscreenOverlay>
660
+ );
661
+ });
662
+
663
+ interface DiffViewProps {
664
+ fileHistory: Record<string, FileHistory>;
665
+ setFileHistory: React.Dispatch<React.SetStateAction<Record<string, FileHistory>>>;
666
+ }
667
+
668
+ export const DiffView = memo(({ fileHistory, setFileHistory }: DiffViewProps) => {
669
+ const files = useStore(workbenchStore.files) as FileMap;
670
+ const selectedFile = useStore(workbenchStore.selectedFile);
671
+ const currentDocument = useStore(workbenchStore.currentDocument) as EditorDocument;
672
+ const unsavedFiles = useStore(workbenchStore.unsavedFiles);
673
+
674
+ useEffect(() => {
675
+ if (selectedFile && currentDocument) {
676
+ const file = files[selectedFile];
677
+
678
+ if (!file || !('content' in file)) {
679
+ return;
680
+ }
681
+
682
+ const existingHistory = fileHistory[selectedFile];
683
+ const currentContent = currentDocument.value;
684
+
685
+ // Normalizar o conteúdo para comparação
686
+ const normalizedCurrentContent = currentContent.replace(/\r\n/g, '\n').trim();
687
+ const normalizedOriginalContent = (existingHistory?.originalContent || file.content)
688
+ .replace(/\r\n/g, '\n')
689
+ .trim();
690
+
691
+ // Se não há histórico existente, criar um novo apenas se houver diferenças
692
+ if (!existingHistory) {
693
+ if (normalizedCurrentContent !== normalizedOriginalContent) {
694
+ const newChanges = diffLines(file.content, currentContent);
695
+ setFileHistory((prev) => ({
696
+ ...prev,
697
+ [selectedFile]: {
698
+ originalContent: file.content,
699
+ lastModified: Date.now(),
700
+ changes: newChanges,
701
+ versions: [
702
+ {
703
+ timestamp: Date.now(),
704
+ content: currentContent,
705
+ },
706
+ ],
707
+ changeSource: 'auto-save',
708
+ },
709
+ }));
710
+ }
711
+
712
+ return;
713
+ }
714
+
715
+ // Se já existe histórico, verificar se há mudanças reais desde a última versão
716
+ const lastVersion = existingHistory.versions[existingHistory.versions.length - 1];
717
+ const normalizedLastContent = lastVersion?.content.replace(/\r\n/g, '\n').trim();
718
+
719
+ if (normalizedCurrentContent === normalizedLastContent) {
720
+ return; // Não criar novo histórico se o conteúdo é o mesmo
721
+ }
722
+
723
+ // Verificar se há mudanças significativas usando diffFiles
724
+ const relativePath = extractRelativePath(selectedFile);
725
+ const unifiedDiff = diffFiles(relativePath, existingHistory.originalContent, currentContent);
726
+
727
+ if (unifiedDiff) {
728
+ const newChanges = diffLines(existingHistory.originalContent, currentContent);
729
+
730
+ // Verificar se as mudanças são significativas
731
+ const hasSignificantChanges = newChanges.some(
732
+ (change) => (change.added || change.removed) && change.value.trim().length > 0,
733
+ );
734
+
735
+ if (hasSignificantChanges) {
736
+ const newHistory: FileHistory = {
737
+ originalContent: existingHistory.originalContent,
738
+ lastModified: Date.now(),
739
+ changes: [...existingHistory.changes, ...newChanges].slice(-100), // Limitar histórico de mudanças
740
+ versions: [
741
+ ...existingHistory.versions,
742
+ {
743
+ timestamp: Date.now(),
744
+ content: currentContent,
745
+ },
746
+ ].slice(-10), // Manter apenas as 10 últimas versões
747
+ changeSource: 'auto-save',
748
+ };
749
+
750
+ setFileHistory((prev) => ({ ...prev, [selectedFile]: newHistory }));
751
+ }
752
+ }
753
+ }
754
+ }, [selectedFile, currentDocument?.value, files, setFileHistory, unsavedFiles]);
755
+
756
+ if (!selectedFile || !currentDocument) {
757
+ return (
758
+ <div className="flex w-full h-full justify-center items-center bg-bolt-elements-background-depth-1 text-bolt-elements-textPrimary">
759
+ Select a file to view differences
760
+ </div>
761
+ );
762
+ }
763
+
764
+ const file = files[selectedFile];
765
+ const originalContent = file && 'content' in file ? file.content : '';
766
+ const currentContent = currentDocument.value;
767
+
768
+ const history = fileHistory[selectedFile];
769
+ const effectiveOriginalContent = history?.originalContent || originalContent;
770
+ const language = getLanguageFromExtension(selectedFile.split('.').pop() || '');
771
+
772
+ try {
773
+ return (
774
+ <div className="h-full overflow-hidden">
775
+ <InlineDiffComparison
776
+ beforeCode={effectiveOriginalContent}
777
+ afterCode={currentContent}
778
+ language={language}
779
+ filename={selectedFile}
780
+ lightTheme="github-light"
781
+ darkTheme="github-dark"
782
+ />
783
+ </div>
784
+ );
785
+ } catch (error) {
786
+ console.error('DiffView render error:', error);
787
+ return (
788
+ <div className="flex w-full h-full justify-center items-center bg-bolt-elements-background-depth-1 text-red-400">
789
+ <div className="text-center">
790
+ <div className="i-ph:warning-circle text-4xl mb-2" />
791
+ <p>Failed to render diff view</p>
792
+ </div>
793
+ </div>
794
+ );
795
+ }
796
+ });