openship 0.1.0 → 0.1.1

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 (531) hide show
  1. package/.env.example +19 -3
  2. package/CONTRIBUTING.md +69 -19
  3. package/LICENSE +661 -0
  4. package/README.md +304 -108
  5. package/apps/api/Dockerfile +6 -8
  6. package/apps/api/package.json +25 -21
  7. package/apps/api/src/app.ts +46 -3
  8. package/apps/api/src/config/env.ts +81 -7
  9. package/apps/api/src/lib/auth-mode.ts +42 -0
  10. package/apps/api/src/lib/auth.ts +105 -0
  11. package/apps/api/src/lib/cache.ts +128 -0
  12. package/apps/api/src/lib/cloud-auth-proxy.ts +310 -0
  13. package/apps/api/src/lib/cloud-client.ts +103 -0
  14. package/apps/api/src/lib/compose-parser.ts +138 -0
  15. package/apps/api/src/lib/controller-helpers.ts +90 -0
  16. package/apps/api/src/lib/email-templates.ts +94 -0
  17. package/apps/api/src/lib/encryption.ts +102 -0
  18. package/apps/api/src/lib/local-user.ts +65 -0
  19. package/apps/api/src/lib/mail.ts +48 -0
  20. package/apps/api/src/lib/notifications.ts +195 -0
  21. package/apps/api/src/lib/openship-cloud.ts +101 -0
  22. package/apps/api/src/lib/resources.ts +96 -0
  23. package/apps/api/src/lib/screenshots.ts +189 -0
  24. package/apps/api/src/lib/ssh-manager.ts +369 -0
  25. package/apps/api/src/lib/ssl-scheduler.ts +109 -0
  26. package/apps/api/src/lib/stack-detector.ts +708 -0
  27. package/apps/api/src/lib/system-debug.ts +10 -0
  28. package/apps/api/src/middleware/auth.ts +49 -13
  29. package/apps/api/src/middleware/error-handler.ts +23 -3
  30. package/apps/api/src/middleware/index.ts +2 -0
  31. package/apps/api/src/middleware/internal-auth.ts +40 -0
  32. package/apps/api/src/middleware/local-only.ts +20 -0
  33. package/apps/api/src/middleware/rate-limiter.ts +9 -0
  34. package/apps/api/src/modules/analytics/analytics.controller.ts +111 -0
  35. package/apps/api/src/modules/analytics/analytics.routes.ts +29 -0
  36. package/apps/api/src/modules/analytics/analytics.schema.ts +37 -0
  37. package/apps/api/src/modules/analytics/analytics.service.ts +264 -0
  38. package/apps/api/src/modules/auth/auth.routes.ts +233 -6
  39. package/apps/api/src/modules/billing/billing.routes.ts +8 -0
  40. package/apps/api/src/modules/cloud/cloud.controller.ts +225 -0
  41. package/apps/api/src/modules/cloud/cloud.routes.ts +40 -0
  42. package/apps/api/src/modules/deployments/build.service.ts +791 -0
  43. package/apps/api/src/modules/deployments/deployment-lifecycle.ts +138 -0
  44. package/apps/api/src/modules/deployments/deployment.controller.ts +324 -16
  45. package/apps/api/src/modules/deployments/deployment.routes.ts +33 -7
  46. package/apps/api/src/modules/deployments/deployment.schema.ts +37 -5
  47. package/apps/api/src/modules/deployments/deployment.service.ts +178 -11
  48. package/apps/api/src/modules/deployments/preflight.ts +280 -0
  49. package/apps/api/src/modules/deployments/prepare.service.ts +252 -0
  50. package/apps/api/src/modules/deployments/session-manager.ts +283 -0
  51. package/apps/api/src/modules/deployments/ssl.service.ts +73 -0
  52. package/apps/api/src/modules/domains/domain.controller.ts +59 -7
  53. package/apps/api/src/modules/domains/domain.routes.ts +20 -5
  54. package/apps/api/src/modules/domains/domain.schema.ts +35 -0
  55. package/apps/api/src/modules/domains/domain.service.ts +375 -9
  56. package/apps/api/src/modules/github/github.auth.ts +397 -0
  57. package/apps/api/src/modules/github/github.controller.ts +387 -0
  58. package/apps/api/src/modules/github/github.local-auth.ts +251 -0
  59. package/apps/api/src/modules/github/github.routes.ts +50 -0
  60. package/apps/api/src/modules/github/github.schema.ts +52 -0
  61. package/apps/api/src/modules/github/github.service.ts +592 -0
  62. package/apps/api/src/modules/github/github.types.ts +158 -0
  63. package/apps/api/src/modules/github/github.webhook.ts +186 -0
  64. package/apps/api/src/modules/github/index.ts +16 -0
  65. package/apps/api/src/modules/health/health.routes.ts +35 -0
  66. package/apps/api/src/modules/projects/project.controller.ts +481 -12
  67. package/apps/api/src/modules/projects/project.routes.ts +63 -6
  68. package/apps/api/src/modules/projects/project.schema.ts +104 -6
  69. package/apps/api/src/modules/projects/project.service.ts +502 -11
  70. package/apps/api/src/modules/settings/settings.controller.ts +55 -0
  71. package/apps/api/src/modules/settings/settings.routes.ts +25 -0
  72. package/apps/api/src/modules/settings/settings.service.ts +49 -0
  73. package/apps/api/src/modules/system/filesystem.controller.ts +66 -0
  74. package/apps/api/src/modules/system/index.ts +1 -0
  75. package/apps/api/src/modules/system/server-check.controller.ts +475 -0
  76. package/apps/api/src/modules/system/setup-session.ts +255 -0
  77. package/apps/api/src/modules/system/setup.controller.ts +128 -0
  78. package/apps/api/src/modules/system/system.routes.ts +42 -0
  79. package/apps/api/src/modules/webhooks/webhook.controller.ts +57 -15
  80. package/apps/api/src/modules/webhooks/webhook.routes.ts +11 -8
  81. package/apps/api/src/modules/webhooks/webhook.service.ts +46 -5
  82. package/apps/api/src/modules/webhooks/webhook.types.ts +35 -0
  83. package/apps/api/tsconfig.json +3 -1
  84. package/apps/cli/package.json +8 -10
  85. package/apps/cli/tsconfig.json +2 -1
  86. package/apps/dashboard/Dockerfile +4 -6
  87. package/apps/dashboard/components.json +20 -0
  88. package/apps/dashboard/next-env.d.ts +6 -0
  89. package/apps/dashboard/next.config.mjs +11 -1
  90. package/apps/dashboard/package.json +25 -13
  91. package/apps/dashboard/postcss.config.mjs +5 -0
  92. package/apps/dashboard/public/android-chrome-192x192.png +0 -0
  93. package/apps/dashboard/public/android-chrome-512x512.png +0 -0
  94. package/apps/dashboard/public/apple-touch-icon.png +0 -0
  95. package/apps/dashboard/public/favicon-16x16.png +0 -0
  96. package/apps/dashboard/public/favicon-32x32.png +0 -0
  97. package/apps/dashboard/public/favicon.ico +0 -0
  98. package/apps/dashboard/public/site.webmanifest +19 -0
  99. package/apps/dashboard/src/app/(auth)/forgot-password/page.tsx +114 -0
  100. package/apps/dashboard/src/app/(auth)/layout.tsx +18 -3
  101. package/apps/dashboard/src/app/(auth)/login/page.tsx +215 -6
  102. package/apps/dashboard/src/app/(auth)/providers.tsx +34 -0
  103. package/apps/dashboard/src/app/(auth)/register/page.tsx +171 -5
  104. package/apps/dashboard/src/app/(auth)/reset-password/page.tsx +172 -0
  105. package/apps/dashboard/src/app/(auth)/verify-email/page.tsx +190 -0
  106. package/apps/dashboard/src/app/(dashboard)/(deployment)/build/[id]/page.tsx +162 -0
  107. package/apps/dashboard/src/app/(dashboard)/(deployment)/deploy/[slug]/components/BuildSummary.tsx +166 -0
  108. package/apps/dashboard/src/app/(dashboard)/(deployment)/deploy/[slug]/components/DnsConfiguration.tsx +119 -0
  109. package/apps/dashboard/src/app/(dashboard)/(deployment)/deploy/[slug]/components/DomainSettings.tsx +291 -0
  110. package/apps/dashboard/src/app/(dashboard)/(deployment)/deploy/[slug]/components/Header.tsx +71 -0
  111. package/apps/dashboard/src/app/(dashboard)/(deployment)/deploy/[slug]/components/Sidebar.tsx +270 -0
  112. package/apps/dashboard/src/app/(dashboard)/(deployment)/deploy/[slug]/components/SkeletonLoader.tsx +87 -0
  113. package/apps/dashboard/src/app/(dashboard)/(deployment)/deploy/[slug]/page.tsx +169 -0
  114. package/apps/dashboard/src/app/(dashboard)/(deployment)/layout.tsx +7 -0
  115. package/apps/dashboard/src/app/(dashboard)/billing/page.tsx +1 -8
  116. package/apps/dashboard/src/app/(dashboard)/deployments/components/CommitDetailsModal.tsx +240 -0
  117. package/apps/dashboard/src/app/(dashboard)/deployments/components/DeploymentCard.tsx +121 -0
  118. package/apps/dashboard/src/app/(dashboard)/deployments/components/DeploymentHeader.tsx +89 -0
  119. package/apps/dashboard/src/app/(dashboard)/deployments/components/DeploymentMenu.tsx +182 -0
  120. package/apps/dashboard/src/app/(dashboard)/deployments/components/DeploymentsContent.tsx +324 -0
  121. package/apps/dashboard/src/app/(dashboard)/deployments/components/DeploymentsFilters.tsx +99 -0
  122. package/apps/dashboard/src/app/(dashboard)/deployments/components/DeploymentsList.tsx +31 -0
  123. package/apps/dashboard/src/app/(dashboard)/deployments/components/EmptyState.tsx +101 -0
  124. package/apps/dashboard/src/app/(dashboard)/deployments/components/LoadingSkeleton.tsx +57 -0
  125. package/apps/dashboard/src/app/(dashboard)/deployments/components/ProjectFilter.tsx +109 -0
  126. package/apps/dashboard/src/app/(dashboard)/deployments/components/index.ts +9 -0
  127. package/apps/dashboard/src/app/(dashboard)/deployments/page.tsx +9 -3
  128. package/apps/dashboard/src/app/(dashboard)/deployments/types.ts +44 -0
  129. package/apps/dashboard/src/app/(dashboard)/deployments/utils.ts +176 -0
  130. package/apps/dashboard/src/app/(dashboard)/domains/page.tsx +1 -6
  131. package/apps/dashboard/src/app/(dashboard)/integrations/page.tsx +321 -0
  132. package/apps/dashboard/src/app/(dashboard)/layout.tsx +22 -32
  133. package/apps/dashboard/src/app/(dashboard)/library/components/ConnectPrompt.tsx +187 -0
  134. package/apps/dashboard/src/app/(dashboard)/library/components/LibrarySidebar.tsx +147 -0
  135. package/apps/dashboard/src/app/(dashboard)/library/components/LoadingSkeleton.tsx +39 -0
  136. package/apps/dashboard/src/app/(dashboard)/library/components/LocalProjects.tsx +548 -0
  137. package/apps/dashboard/src/app/(dashboard)/library/components/RepositoryList.tsx +292 -0
  138. package/apps/dashboard/src/app/(dashboard)/library/components/TemplateGrid.tsx +36 -0
  139. package/apps/dashboard/src/app/(dashboard)/library/components/UrlImport.tsx +74 -0
  140. package/apps/dashboard/src/app/(dashboard)/library/page.tsx +121 -0
  141. package/apps/dashboard/src/app/(dashboard)/library/types.ts +26 -0
  142. package/apps/dashboard/src/app/(dashboard)/monitoring/page.tsx +1 -6
  143. package/apps/dashboard/src/app/(dashboard)/page.tsx +485 -0
  144. package/apps/dashboard/src/app/(dashboard)/projects/[id]/[[...slug]]/layout.tsx +22 -0
  145. package/apps/dashboard/src/app/(dashboard)/projects/[id]/[[...slug]]/page.tsx +286 -0
  146. package/apps/dashboard/src/app/(dashboard)/projects/[id]/components/AdvancedSettings.tsx +235 -0
  147. package/apps/dashboard/src/app/(dashboard)/projects/[id]/components/BuildSettings.tsx +174 -0
  148. package/apps/dashboard/src/app/(dashboard)/projects/[id]/components/DeleteConfirmationDialog.tsx +45 -0
  149. package/apps/dashboard/src/app/(dashboard)/projects/[id]/components/DeletionModal.tsx +95 -0
  150. package/apps/dashboard/src/app/(dashboard)/projects/[id]/components/Deployments.tsx +11 -0
  151. package/apps/dashboard/src/app/(dashboard)/projects/[id]/components/DomainSettings.tsx +523 -0
  152. package/apps/dashboard/src/app/(dashboard)/projects/[id]/components/EnvironmentSettings.tsx +246 -0
  153. package/apps/dashboard/src/app/(dashboard)/projects/[id]/components/GeneralSettings.tsx +93 -0
  154. package/apps/dashboard/src/app/(dashboard)/projects/[id]/components/GitInfo.tsx +261 -0
  155. package/apps/dashboard/src/app/(dashboard)/projects/[id]/components/GitSettings.tsx +391 -0
  156. package/apps/dashboard/src/app/(dashboard)/projects/[id]/components/LogsSettings.tsx +133 -0
  157. package/apps/dashboard/src/app/(dashboard)/projects/[id]/components/ProjectNotFound.tsx +95 -0
  158. package/apps/dashboard/src/app/(dashboard)/projects/[id]/components/ProjectsBottomNavigation.tsx +62 -0
  159. package/apps/dashboard/src/app/(dashboard)/projects/[id]/components/ResourceSettings.tsx +333 -0
  160. package/apps/dashboard/src/app/(dashboard)/projects/[id]/components/SettingSection.tsx +66 -0
  161. package/apps/dashboard/src/app/(dashboard)/projects/[id]/components/SettingsNavigation.tsx +27 -0
  162. package/apps/dashboard/src/app/(dashboard)/projects/[id]/components/SleepModeSettings.tsx +134 -0
  163. package/apps/dashboard/src/app/(dashboard)/projects/[id]/components/general/ProductionUrl.tsx +25 -0
  164. package/apps/dashboard/src/app/(dashboard)/projects/[id]/components/general/ProjectIdentity.tsx +159 -0
  165. package/apps/dashboard/src/app/(dashboard)/projects/[id]/components/general/ProjectInfo.tsx +58 -0
  166. package/apps/dashboard/src/app/(dashboard)/projects/[id]/components/general/SkeletonLoader.tsx +170 -0
  167. package/apps/dashboard/src/app/(dashboard)/projects/[id]/components/general/StatsCards.tsx +33 -0
  168. package/apps/dashboard/src/app/(dashboard)/projects/[id]/components/general/TopPaths.tsx +56 -0
  169. package/apps/dashboard/src/app/(dashboard)/projects/[id]/components/general/TrafficChart.tsx +157 -0
  170. package/apps/dashboard/src/app/(dashboard)/projects/[id]/components/general/index.ts +14 -0
  171. package/apps/dashboard/src/app/(dashboard)/projects/[id]/components/logs/LogsActions.tsx +52 -0
  172. package/apps/dashboard/src/app/(dashboard)/projects/[id]/components/logs/ServerLogs.tsx +249 -0
  173. package/apps/dashboard/src/app/(dashboard)/projects/[id]/components/logs/TerminalLogs.tsx +682 -0
  174. package/apps/dashboard/src/app/(dashboard)/projects/[id]/components/logs/logs.css +127 -0
  175. package/apps/dashboard/src/app/(dashboard)/projects/components/DeploymentCard.tsx +73 -0
  176. package/apps/dashboard/src/app/(dashboard)/projects/components/ProjectCard.tsx +330 -0
  177. package/apps/dashboard/src/app/(dashboard)/projects/page.tsx +326 -4
  178. package/apps/dashboard/src/app/(dashboard)/providers.tsx +23 -0
  179. package/apps/dashboard/src/app/(dashboard)/servers/[serverId]/_components/components-tab.tsx +329 -0
  180. package/apps/dashboard/src/app/(dashboard)/servers/[serverId]/_components/overview-tab.tsx +229 -0
  181. package/apps/dashboard/src/app/(dashboard)/servers/[serverId]/_components/terminal-tab.tsx +38 -0
  182. package/apps/dashboard/src/app/(dashboard)/servers/[serverId]/page.tsx +437 -0
  183. package/apps/dashboard/src/app/(dashboard)/servers/new/_components/checking-state.tsx +15 -0
  184. package/apps/dashboard/src/app/(dashboard)/servers/new/_components/choose-mode.tsx +54 -0
  185. package/apps/dashboard/src/app/(dashboard)/servers/new/_components/component-row.tsx +65 -0
  186. package/apps/dashboard/src/app/(dashboard)/servers/new/_components/error-banner.tsx +13 -0
  187. package/apps/dashboard/src/app/(dashboard)/servers/new/_components/installing-panel.tsx +227 -0
  188. package/apps/dashboard/src/app/(dashboard)/servers/new/_components/results-panel.tsx +90 -0
  189. package/apps/dashboard/src/app/(dashboard)/servers/new/_components/setup-header.tsx +56 -0
  190. package/apps/dashboard/src/app/(dashboard)/servers/new/_components/types.ts +13 -0
  191. package/apps/dashboard/src/app/(dashboard)/servers/new/page.tsx +666 -0
  192. package/apps/dashboard/src/app/(dashboard)/servers/page.tsx +283 -0
  193. package/apps/dashboard/src/app/(dashboard)/settings/_components/BuildPreferences.tsx +110 -0
  194. package/apps/dashboard/src/app/(dashboard)/settings/_components/CloudConnection.tsx +147 -0
  195. package/apps/dashboard/src/app/(dashboard)/settings/_components/InstanceInfo.tsx +54 -0
  196. package/apps/dashboard/src/app/(dashboard)/settings/_components/ServerConnection.tsx +407 -0
  197. package/apps/dashboard/src/app/(dashboard)/settings/_components/SettingsSection.tsx +32 -0
  198. package/apps/dashboard/src/app/(dashboard)/settings/page.tsx +62 -3
  199. package/apps/dashboard/src/app/auth/callback/close/page.tsx +23 -0
  200. package/apps/dashboard/src/app/auth/callback/install/page.tsx +40 -0
  201. package/apps/dashboard/src/app/authorize/page.tsx +137 -0
  202. package/apps/dashboard/src/app/globals.css +57 -3
  203. package/apps/dashboard/src/app/layout.tsx +43 -3
  204. package/apps/dashboard/src/components/auth-shell.tsx +66 -0
  205. package/apps/dashboard/src/components/deployments/types.ts +44 -0
  206. package/apps/dashboard/src/components/global-deployments/index.ts +17 -0
  207. package/apps/dashboard/src/components/i18n-provider.tsx +100 -0
  208. package/apps/dashboard/src/components/import-project/BuildSettings.tsx +376 -0
  209. package/apps/dashboard/src/components/import-project/BuildSkeleton.tsx +161 -0
  210. package/apps/dashboard/src/components/import-project/BuildTerminal.tsx +358 -0
  211. package/apps/dashboard/src/components/import-project/ComposeServices.tsx +455 -0
  212. package/apps/dashboard/src/components/import-project/DeploymentProcessing.tsx +510 -0
  213. package/apps/dashboard/src/components/import-project/DockerSettings.tsx +64 -0
  214. package/apps/dashboard/src/components/import-project/EnvironmentVariables.tsx +481 -0
  215. package/apps/dashboard/src/components/import-project/Frameworks.tsx +90 -0
  216. package/apps/dashboard/src/components/import-project/ProjectSettings.tsx +160 -0
  217. package/apps/dashboard/src/components/import-project/types.ts +82 -0
  218. package/apps/dashboard/src/components/integrations/GithubPermissionModal.tsx +173 -0
  219. package/apps/dashboard/src/components/language-switcher.tsx +36 -0
  220. package/apps/dashboard/src/components/logo.tsx +13 -0
  221. package/apps/dashboard/src/components/network-error-handler.tsx +27 -0
  222. package/apps/dashboard/src/components/oauth-buttons.tsx +81 -0
  223. package/apps/dashboard/src/components/overview/ActivityChart.tsx +247 -0
  224. package/apps/dashboard/src/components/overview/ApiRequestsCard.tsx +111 -0
  225. package/apps/dashboard/src/components/overview/CreditsCard.tsx +137 -0
  226. package/apps/dashboard/src/components/overview/DeploymentsChart.tsx +195 -0
  227. package/apps/dashboard/src/components/overview/EmptyState.tsx +126 -0
  228. package/apps/dashboard/src/components/overview/LoadingSkeleton.tsx +92 -0
  229. package/apps/dashboard/src/components/overview/OverviewHeader.tsx +74 -0
  230. package/apps/dashboard/src/components/overview/OverviewHeroChart.tsx +344 -0
  231. package/apps/dashboard/src/components/overview/ProjectsCard.tsx +134 -0
  232. package/apps/dashboard/src/components/overview/QuickLinks.tsx +119 -0
  233. package/apps/dashboard/src/components/overview/SandboxesCard.tsx +150 -0
  234. package/apps/dashboard/src/components/overview/StatsGrid.tsx +166 -0
  235. package/apps/dashboard/src/components/overview/TokenUsageChart.tsx +206 -0
  236. package/apps/dashboard/src/components/overview/UsageStats.tsx +79 -0
  237. package/apps/dashboard/src/components/overview/index.ts +30 -0
  238. package/apps/dashboard/src/components/overview/types.ts +116 -0
  239. package/apps/dashboard/src/components/page-header.tsx +25 -0
  240. package/apps/dashboard/src/components/project-settings/ServerSideSwitch.jsx +60 -0
  241. package/apps/dashboard/src/components/shared/AlertBox.tsx +39 -0
  242. package/apps/dashboard/src/components/shared/CTASection.tsx +45 -0
  243. package/apps/dashboard/src/components/shared/ErrorState.tsx +176 -0
  244. package/apps/dashboard/src/components/shared/FeatureCard.tsx +20 -0
  245. package/apps/dashboard/src/components/shared/MDXComponents.tsx +24 -0
  246. package/apps/dashboard/src/components/shared/MachineSettingsModal.tsx +286 -0
  247. package/apps/dashboard/src/components/shared/Modal.tsx +39 -0
  248. package/apps/dashboard/src/components/shared/OTPInput.tsx +122 -0
  249. package/apps/dashboard/src/components/shared/PageHero.tsx +21 -0
  250. package/apps/dashboard/src/components/shared/PlatformFeatureCard.tsx +27 -0
  251. package/apps/dashboard/src/components/shared/StatCard.tsx +14 -0
  252. package/apps/dashboard/src/components/shared/ValueCard.tsx +20 -0
  253. package/apps/dashboard/src/components/shared/index.ts +8 -0
  254. package/apps/dashboard/src/components/sidebar.tsx +282 -0
  255. package/apps/dashboard/src/components/theme-provider.tsx +96 -0
  256. package/apps/dashboard/src/components/toast.tsx +106 -0
  257. package/apps/dashboard/src/components/ui/CustomCursor.tsx +107 -0
  258. package/apps/dashboard/src/components/ui/CustomSelect.tsx +126 -0
  259. package/apps/dashboard/src/components/ui/DropdownMenu.tsx +174 -0
  260. package/apps/dashboard/src/components/ui/FileIcon.jsx +59 -0
  261. package/apps/dashboard/src/components/ui/IconPickerModal.tsx +273 -0
  262. package/apps/dashboard/src/components/ui/InfoBanner.jsx +39 -0
  263. package/apps/dashboard/src/components/ui/Logo.tsx +14 -0
  264. package/apps/dashboard/src/components/ui/Modal.tsx +117 -0
  265. package/apps/dashboard/src/components/ui/PageContainer.tsx +12 -0
  266. package/apps/dashboard/src/components/ui/SectionContainer.jsx +7 -0
  267. package/apps/dashboard/src/components/ui/SlidingToggle.tsx +128 -0
  268. package/apps/dashboard/src/components/ui/Toast.tsx +29 -0
  269. package/apps/dashboard/src/components/ui/button.tsx +58 -0
  270. package/apps/dashboard/src/components/ui/card.tsx +60 -0
  271. package/apps/dashboard/src/components/ui/input.tsx +20 -0
  272. package/apps/dashboard/src/components/ui/label.tsx +19 -0
  273. package/apps/dashboard/src/components/ui/select.tsx +10 -0
  274. package/apps/dashboard/src/components/ui/textarea.tsx +9 -0
  275. package/apps/dashboard/src/constants/lang-colors.ts +25 -0
  276. package/apps/dashboard/src/constants/mock.ts +38 -0
  277. package/apps/dashboard/src/context/AuthContext.tsx +91 -0
  278. package/apps/dashboard/src/context/CloudContext.tsx +275 -0
  279. package/apps/dashboard/src/context/DeploymentContext.tsx +71 -0
  280. package/apps/dashboard/src/context/GitHubContext.tsx +288 -0
  281. package/apps/dashboard/src/context/ModalContext.tsx +300 -0
  282. package/apps/dashboard/src/context/NetworkContext.tsx +32 -0
  283. package/apps/dashboard/src/context/ProjectSettingsContext.tsx +727 -0
  284. package/apps/dashboard/src/context/ToastContext.tsx +129 -0
  285. package/apps/dashboard/src/context/deployment/index.ts +3 -0
  286. package/apps/dashboard/src/context/deployment/types.ts +183 -0
  287. package/apps/dashboard/src/context/deployment/useDeploymentBuild.ts +547 -0
  288. package/apps/dashboard/src/context/deployment/useDeploymentConfig.ts +176 -0
  289. package/apps/dashboard/src/hooks/useBuildConnection.ts +334 -0
  290. package/apps/dashboard/src/hooks/useMonitorStream.ts +146 -0
  291. package/apps/dashboard/src/hooks/useProjectData.ts +110 -0
  292. package/apps/dashboard/src/hooks/useSSEConnection.ts +465 -0
  293. package/apps/dashboard/src/hooks/useSSEStream.ts +309 -0
  294. package/apps/dashboard/src/hooks/useSessions.ts +104 -0
  295. package/apps/dashboard/src/hooks/useSetupStream.ts +223 -0
  296. package/apps/dashboard/src/i18n/dictionaries/ar.json +218 -0
  297. package/apps/dashboard/src/i18n/dictionaries/en.json +218 -0
  298. package/apps/dashboard/src/i18n/index.ts +16 -0
  299. package/apps/dashboard/src/lib/api/ai.ts +22 -0
  300. package/apps/dashboard/src/lib/api/auth.ts +13 -0
  301. package/apps/dashboard/src/lib/api/client.ts +199 -0
  302. package/apps/dashboard/src/lib/api/cloud.ts +15 -0
  303. package/apps/dashboard/src/lib/api/deploy.ts +58 -0
  304. package/apps/dashboard/src/lib/api/domains.ts +13 -0
  305. package/apps/dashboard/src/lib/api/endpoints.ts +129 -0
  306. package/apps/dashboard/src/lib/api/github.ts +31 -0
  307. package/apps/dashboard/src/lib/api/icons.ts +12 -0
  308. package/apps/dashboard/src/lib/api/index.ts +41 -0
  309. package/apps/dashboard/src/lib/api/projects.ts +153 -0
  310. package/apps/dashboard/src/lib/api/sandbox.ts +14 -0
  311. package/apps/dashboard/src/lib/api/settings.ts +21 -0
  312. package/apps/dashboard/src/lib/api/system.ts +159 -0
  313. package/apps/dashboard/src/lib/auth-client.ts +54 -0
  314. package/apps/dashboard/src/lib/country.ts +25 -0
  315. package/apps/dashboard/src/lib/server/api.ts +140 -0
  316. package/apps/dashboard/src/lib/server/session.ts +103 -0
  317. package/apps/dashboard/src/lib/sseClient.ts +241 -0
  318. package/apps/dashboard/src/lib/sseMessageProcessors.ts +323 -0
  319. package/apps/dashboard/src/lib/utils.ts +6 -0
  320. package/apps/dashboard/src/proxy.ts +46 -0
  321. package/apps/dashboard/src/styles/Toast.module.css +92 -0
  322. package/apps/dashboard/src/styles/fonts.css +93 -0
  323. package/apps/dashboard/src/styles/theme.css +336 -0
  324. package/apps/dashboard/src/types/research.ts +42 -0
  325. package/apps/dashboard/src/utils/SSEParser.js +150 -0
  326. package/apps/dashboard/src/utils/authWindow.ts +143 -0
  327. package/apps/dashboard/src/utils/codeTheme.ts +127 -0
  328. package/apps/dashboard/src/utils/colors.json +2810 -0
  329. package/apps/dashboard/src/utils/date.ts +121 -0
  330. package/apps/dashboard/src/utils/deployment.ts +128 -0
  331. package/apps/dashboard/src/utils/deploymentPhaseDetector.ts +232 -0
  332. package/apps/dashboard/src/utils/extToLang.js +103 -0
  333. package/apps/dashboard/src/utils/github.ts +62 -0
  334. package/apps/dashboard/src/utils/icons.js +46 -0
  335. package/apps/dashboard/src/utils/repoSlug.ts +110 -0
  336. package/apps/dashboard/src/utils/research-api.ts +163 -0
  337. package/apps/dashboard/src/utils/suggestions.ts +84 -0
  338. package/apps/dashboard/src/utils/theme.js +1 -0
  339. package/apps/dashboard/src/utils/ui-helpers.tsx +30 -0
  340. package/apps/dashboard/src/utils/upload.js +12 -0
  341. package/apps/dashboard/tsconfig.json +27 -5
  342. package/apps/desktop/forge.config.json +36 -0
  343. package/apps/desktop/package.json +26 -0
  344. package/apps/desktop/scripts/dev.mjs +58 -0
  345. package/apps/desktop/src/main/index.ts +675 -0
  346. package/apps/desktop/src/main/types/desktop.d.ts +33 -0
  347. package/apps/desktop/src/preload/index.ts +88 -0
  348. package/apps/desktop/src/renderer/index.html +462 -0
  349. package/apps/desktop/src/renderer/onboarding.js +511 -0
  350. package/apps/desktop/src/renderer/styles.css +1139 -0
  351. package/apps/desktop/tsconfig.json +17 -0
  352. package/apps/web/.source/browser.ts +13 -0
  353. package/apps/web/.source/dynamic.ts +8 -0
  354. package/apps/web/.source/server.ts +22 -0
  355. package/apps/web/.source/source.config.mjs +20 -0
  356. package/apps/web/Dockerfile +4 -6
  357. package/apps/web/content/blog/how-ai-builds-work.mdx +55 -0
  358. package/apps/web/content/blog/introducing-openship.mdx +46 -0
  359. package/apps/web/content/blog/self-hosting-cost-breakdown.mdx +59 -0
  360. package/apps/web/content/docs/_meta.json +14 -0
  361. package/apps/web/content/docs/api.mdx +98 -0
  362. package/apps/web/content/docs/cli.mdx +80 -0
  363. package/apps/web/content/docs/first-deployment.mdx +56 -0
  364. package/apps/web/content/docs/index.mdx +27 -0
  365. package/apps/web/content/docs/installation.mdx +65 -0
  366. package/apps/web/content/docs/quickstart.mdx +45 -0
  367. package/apps/web/next-env.d.ts +6 -0
  368. package/apps/web/next.config.mjs +16 -2
  369. package/apps/web/package.json +19 -12
  370. package/apps/web/postcss.config.mjs +5 -0
  371. package/apps/web/public/android-chrome-192x192.png +0 -0
  372. package/apps/web/public/android-chrome-512x512.png +0 -0
  373. package/apps/web/public/apple-touch-icon.png +0 -0
  374. package/apps/web/public/favicon-16x16.png +0 -0
  375. package/apps/web/public/favicon-32x32.png +0 -0
  376. package/apps/web/public/favicon.ico +0 -0
  377. package/apps/web/public/site.webmanifest +1 -0
  378. package/apps/web/source.config.ts +17 -0
  379. package/apps/web/src/app/(marketing)/layout.tsx +7 -22
  380. package/apps/web/src/app/blog/[...slug]/page.tsx +247 -0
  381. package/apps/web/src/app/blog/blog.css +575 -0
  382. package/apps/web/src/app/blog/layout.tsx +50 -0
  383. package/apps/web/src/app/blog/page.tsx +235 -0
  384. package/apps/web/src/app/docs/[[...slug]]/page.tsx +67 -0
  385. package/apps/web/src/app/docs/layout.tsx +62 -0
  386. package/apps/web/src/app/docs/toc-theme.css +71 -0
  387. package/apps/web/src/app/download/page.tsx +396 -0
  388. package/apps/web/src/app/globals.css +20 -3
  389. package/apps/web/src/app/layout.tsx +57 -3
  390. package/apps/web/src/app/page.tsx +47 -6
  391. package/apps/web/src/app/robots.ts +15 -0
  392. package/apps/web/src/app/sitemap.ts +35 -0
  393. package/apps/web/src/components/blog/share-sidebar.tsx +81 -0
  394. package/apps/web/src/components/blog/writer-sidebar.tsx +81 -0
  395. package/apps/web/src/components/landing/ai-native.tsx +169 -0
  396. package/apps/web/src/components/landing/backups.tsx +139 -0
  397. package/apps/web/src/components/landing/cdn.tsx +109 -0
  398. package/apps/web/src/components/landing/coming-soon.tsx +180 -0
  399. package/apps/web/src/components/landing/dark-section.tsx +166 -0
  400. package/apps/web/src/components/landing/dashboard.tsx +407 -0
  401. package/apps/web/src/components/landing/developer-experience.tsx +224 -0
  402. package/apps/web/src/components/landing/dns-domains.tsx +146 -0
  403. package/apps/web/src/components/landing/download-button.tsx +151 -0
  404. package/apps/web/src/components/landing/features/ai-visual.tsx +48 -0
  405. package/apps/web/src/components/landing/features/cloud-visual.tsx +44 -0
  406. package/apps/web/src/components/landing/features/git-visual.tsx +61 -0
  407. package/apps/web/src/components/landing/features/index.tsx +642 -0
  408. package/apps/web/src/components/landing/features/infra-visual.tsx +69 -0
  409. package/apps/web/src/components/landing/features/rollback-visual.tsx +42 -0
  410. package/apps/web/src/components/landing/features/ssl-visual.tsx +41 -0
  411. package/apps/web/src/components/landing/features/stacks-visual.tsx +54 -0
  412. package/apps/web/src/components/landing/final-cta.tsx +116 -0
  413. package/apps/web/src/components/landing/footer.tsx +145 -0
  414. package/apps/web/src/components/landing/hero.tsx +110 -0
  415. package/apps/web/src/components/landing/how-it-works.tsx +210 -0
  416. package/apps/web/src/components/landing/index.ts +21 -0
  417. package/apps/web/src/components/landing/mail-server.tsx +122 -0
  418. package/apps/web/src/components/landing/navbar.tsx +199 -0
  419. package/apps/web/src/components/landing/no-lockin.tsx +185 -0
  420. package/apps/web/src/components/landing/open-source-cta.tsx +151 -0
  421. package/apps/web/src/components/landing/portability.tsx +190 -0
  422. package/apps/web/src/components/landing/pricing.tsx +263 -0
  423. package/apps/web/src/components/landing/scaling.tsx +209 -0
  424. package/apps/web/src/components/landing/why-openship.tsx +291 -0
  425. package/apps/web/src/hooks/use-gsap-scroll.ts +158 -0
  426. package/apps/web/src/hooks/use-platform.ts +86 -0
  427. package/apps/web/src/lib/source.ts +12 -0
  428. package/apps/web/src/styles/fonts.css +84 -0
  429. package/apps/web/src/styles/landing.css +951 -0
  430. package/apps/web/src/styles/theme.css +227 -0
  431. package/apps/web/tsconfig.json +8 -3
  432. package/bun.lock +3260 -0
  433. package/docker-compose.yml +3 -0
  434. package/docs/screenshots/.gitkeep +0 -0
  435. package/docs/screenshots/screen.png +0 -0
  436. package/openship.code-workspace +7 -0
  437. package/package.json +23 -9
  438. package/packages/adapters/docs/ARCHITECTURE.md +160 -0
  439. package/packages/adapters/docs/BUILD-PIPELINE.md +171 -0
  440. package/packages/adapters/docs/CLOUD.md +239 -0
  441. package/packages/adapters/docs/EXECUTOR.md +174 -0
  442. package/packages/adapters/docs/LOG-STREAMING.md +175 -0
  443. package/packages/adapters/docs/SYSTEM.md +191 -0
  444. package/packages/adapters/package.json +14 -9
  445. package/packages/adapters/src/index.ts +144 -4
  446. package/packages/adapters/src/infra/cloud.ts +42 -0
  447. package/packages/adapters/src/infra/index.ts +9 -0
  448. package/packages/adapters/src/infra/noop.ts +27 -0
  449. package/packages/adapters/src/infra/traefik.ts +297 -0
  450. package/packages/adapters/src/infra/types.ts +36 -0
  451. package/packages/adapters/src/platform.ts +255 -0
  452. package/packages/adapters/src/runtime/bare.ts +567 -0
  453. package/packages/adapters/src/runtime/build-pipeline.ts +237 -0
  454. package/packages/adapters/src/runtime/cloud.ts +791 -0
  455. package/packages/adapters/src/runtime/deploy-pipeline.ts +146 -0
  456. package/packages/adapters/src/runtime/docker.ts +443 -0
  457. package/packages/adapters/src/runtime/index.ts +69 -0
  458. package/packages/adapters/src/runtime/local-build.ts +112 -0
  459. package/packages/adapters/src/runtime/transfer.ts +82 -0
  460. package/packages/adapters/src/runtime/types.ts +138 -0
  461. package/packages/adapters/src/system/catalog.ts +188 -0
  462. package/packages/adapters/src/system/checks.ts +228 -0
  463. package/packages/adapters/src/system/components.ts +45 -0
  464. package/packages/adapters/src/system/debug.ts +18 -0
  465. package/packages/adapters/src/system/environment.ts +168 -0
  466. package/packages/adapters/src/system/errors.ts +34 -0
  467. package/packages/adapters/src/system/executor.ts +600 -0
  468. package/packages/adapters/src/system/index.ts +58 -0
  469. package/packages/adapters/src/system/installer.ts +310 -0
  470. package/packages/adapters/src/system/setup.ts +442 -0
  471. package/packages/adapters/src/system/state.ts +96 -0
  472. package/packages/adapters/src/system/types.ts +116 -0
  473. package/packages/adapters/src/toolchain/catalog.ts +439 -0
  474. package/packages/adapters/src/toolchain/checks.ts +181 -0
  475. package/packages/adapters/src/toolchain/index.ts +38 -0
  476. package/packages/adapters/src/toolchain/installer.ts +189 -0
  477. package/packages/adapters/src/toolchain/types.ts +84 -0
  478. package/packages/adapters/src/types.ts +277 -0
  479. package/packages/adapters/tsconfig.json +3 -1
  480. package/packages/core/package.json +9 -9
  481. package/packages/core/src/constants.ts +44 -1
  482. package/packages/core/src/index.ts +2 -0
  483. package/packages/core/src/stacks.ts +778 -0
  484. package/packages/core/src/system.ts +111 -0
  485. package/packages/core/src/types.ts +22 -1
  486. package/packages/core/src/utils.ts +8 -0
  487. package/packages/core/tsconfig.json +3 -1
  488. package/packages/db/drizzle/0000_init.sql +231 -0
  489. package/packages/db/drizzle/0001_add_server_name.sql +1 -0
  490. package/packages/db/drizzle/meta/_journal.json +20 -0
  491. package/packages/db/drizzle.config.ts +10 -0
  492. package/packages/db/package.json +26 -14
  493. package/packages/db/src/client.ts +119 -0
  494. package/packages/db/src/index.ts +57 -8
  495. package/packages/db/src/repos/account.repo.ts +92 -0
  496. package/packages/db/src/repos/deployment.repo.ts +168 -0
  497. package/packages/db/src/repos/domain.repo.ts +102 -0
  498. package/packages/db/src/repos/git-installation.repo.ts +95 -0
  499. package/packages/db/src/repos/index.ts +43 -0
  500. package/packages/db/src/repos/instance-settings.repo.ts +43 -0
  501. package/packages/db/src/repos/project.repo.ts +159 -0
  502. package/packages/db/src/repos/session.repo.ts +82 -0
  503. package/packages/db/src/repos/settings.repo.ts +51 -0
  504. package/packages/db/src/repos/user.repo.ts +94 -0
  505. package/packages/db/src/schema/auth.ts +56 -0
  506. package/packages/db/src/schema/deployment.ts +87 -0
  507. package/packages/db/src/schema/domain.ts +46 -0
  508. package/packages/db/src/schema/github.ts +24 -0
  509. package/packages/db/src/schema/index.ts +6 -0
  510. package/packages/db/src/schema/project.ts +117 -0
  511. package/packages/db/src/schema/settings.ts +103 -0
  512. package/packages/db/tsconfig.json +3 -1
  513. package/packages/ui/package.json +17 -17
  514. package/packages/ui/src/components/status-dot.tsx +1 -1
  515. package/packages/ui/tsconfig.json +7 -2
  516. package/pnpm-workspace.yaml +0 -1
  517. package/{tooling/tsconfig/base.json → tsconfig.base.json} +0 -1
  518. package/turbo.json +4 -0
  519. package/apps/api/src/modules/auth/auth.controller.ts +0 -26
  520. package/apps/api/src/modules/auth/auth.schema.ts +0 -12
  521. package/apps/api/src/modules/auth/auth.service.ts +0 -23
  522. package/apps/dashboard/src/app/page.tsx +0 -6
  523. package/apps/web/src/app/(marketing)/docs/page.tsx +0 -10
  524. package/packages/adapters/src/base-adapter.ts +0 -49
  525. package/packages/adapters/src/docker-adapter.ts +0 -43
  526. package/packages/adapters/src/oblien-adapter.ts +0 -46
  527. package/packages/adapters/src/registry.ts +0 -22
  528. package/packages/db/prisma/schema.prisma +0 -160
  529. package/tooling/tsconfig/nextjs.json +0 -10
  530. package/tooling/tsconfig/node.json +0 -10
  531. package/tooling/tsconfig/package.json +0 -7
@@ -0,0 +1,87 @@
1
+ import { PageContainer } from "@/components/ui/PageContainer";
2
+
3
+ const Shimmer = ({ className }: { className?: string }) => (
4
+ <div className={`bg-muted animate-pulse rounded-lg ${className ?? ""}`} />
5
+ );
6
+
7
+ const SkeletonLoader = () => (
8
+ <div className="min-h-screen bg-background">
9
+ <PageContainer>
10
+ <div className="grid lg:grid-cols-[1fr_340px] gap-6">
11
+ {/* Main column */}
12
+ <div className="space-y-5">
13
+ {/* Project Settings */}
14
+ <div className="bg-card rounded-2xl border border-border/50 p-5 space-y-4">
15
+ <div className="flex items-center gap-3">
16
+ <Shimmer className="w-8 h-8 rounded-lg" />
17
+ <Shimmer className="h-5 w-32" />
18
+ </div>
19
+ <Shimmer className="h-10 rounded-xl" />
20
+ <div className="grid grid-cols-3 gap-3">
21
+ {[1, 2, 3, 4, 5, 6].map((i) => (
22
+ <Shimmer key={i} className="h-14 rounded-lg" />
23
+ ))}
24
+ </div>
25
+ <Shimmer className="h-10 rounded-xl" />
26
+ </div>
27
+
28
+ {/* Build Settings */}
29
+ <div className="bg-card rounded-2xl border border-border/50 p-5 space-y-4">
30
+ <div className="flex items-center gap-3">
31
+ <Shimmer className="w-8 h-8 rounded-lg" />
32
+ <Shimmer className="h-5 w-28" />
33
+ </div>
34
+ {[1, 2, 3].map((i) => (
35
+ <div key={i}>
36
+ <Shimmer className="h-4 w-24 mb-2" />
37
+ <Shimmer className="h-10 rounded-xl" />
38
+ </div>
39
+ ))}
40
+ </div>
41
+
42
+ {/* Environment Variables */}
43
+ <div className="bg-card rounded-2xl border border-border/50 p-5 space-y-4">
44
+ <div className="flex items-center gap-3">
45
+ <Shimmer className="w-8 h-8 rounded-lg" />
46
+ <Shimmer className="h-5 w-40" />
47
+ </div>
48
+ {[1, 2].map((i) => (
49
+ <div key={i} className="flex gap-3">
50
+ <Shimmer className="flex-1 h-10 rounded-xl" />
51
+ <Shimmer className="flex-1 h-10 rounded-xl" />
52
+ <Shimmer className="w-10 h-10 rounded-xl" />
53
+ </div>
54
+ ))}
55
+ </div>
56
+
57
+ {/* Project Name */}
58
+ <div className="bg-card rounded-2xl border border-border/50 p-5 space-y-4">
59
+ <Shimmer className="h-4 w-24" />
60
+ <Shimmer className="h-10 rounded-xl" />
61
+ <Shimmer className="h-4 w-56" />
62
+ </div>
63
+ </div>
64
+
65
+ {/* Sidebar */}
66
+ <div className="space-y-4">
67
+ <div className="bg-card rounded-2xl border border-border/50 p-4">
68
+ <div className="flex items-center gap-3">
69
+ <Shimmer className="w-8 h-8 rounded-lg" />
70
+ <div className="flex-1 space-y-1.5">
71
+ <Shimmer className="h-4 w-32" />
72
+ <Shimmer className="h-3 w-20" />
73
+ </div>
74
+ </div>
75
+ </div>
76
+ <div className="bg-card rounded-2xl border border-border/50 p-4 space-y-3">
77
+ <Shimmer className="h-4 w-16" />
78
+ <Shimmer className="h-9 rounded-xl" />
79
+ </div>
80
+ <Shimmer className="h-10 rounded-xl" />
81
+ </div>
82
+ </div>
83
+ </PageContainer>
84
+ </div>
85
+ );
86
+
87
+ export default SkeletonLoader;
@@ -0,0 +1,169 @@
1
+ "use client";
2
+
3
+ import React, { useState, useEffect, useRef } from "react";
4
+ import { useRouter, useParams, useSearchParams } from "next/navigation";
5
+ import ProjectSettings from "@/components/import-project/ProjectSettings";
6
+ import BuildSettings from "@/components/import-project/BuildSettings";
7
+ import DockerSettings from "@/components/import-project/DockerSettings";
8
+ import ComposeServices from "@/components/import-project/ComposeServices";
9
+ import EnvironmentVariables from "@/components/import-project/EnvironmentVariables";
10
+ import Sidebar from "./components/Sidebar";
11
+ import { decodeSlug } from "@/utils/repoSlug";
12
+ import { useDeployment } from "@/context/DeploymentContext";
13
+ import SkeletonLoader from "./components/SkeletonLoader";
14
+ import ErrorState from "@/components/shared/ErrorState";
15
+ import { PageContainer } from "@/components/ui/PageContainer";
16
+
17
+ interface DeployError {
18
+ type: 'invalid_url' | 'repo_not_found' | 'initialization_failed';
19
+ message: string;
20
+ details?: string;
21
+ }
22
+
23
+ const ProjectName: React.FC = () => {
24
+ const { config, updateConfig } = useDeployment();
25
+ return (
26
+ <div className="bg-card rounded-2xl border border-border/50">
27
+ <div className="px-5 py-5">
28
+ <label className="text-[15px] font-semibold text-foreground mb-2 block">
29
+ Project Name
30
+ </label>
31
+ <input
32
+ type="text"
33
+ value={config.projectName}
34
+ onChange={(e) => updateConfig({ projectName: e.target.value })}
35
+ placeholder="my-awesome-project"
36
+ className="w-full px-4 py-2.5 bg-muted/30 border border-border/50 rounded-xl text-sm text-foreground placeholder:text-muted-foreground/50 focus:outline-none focus:ring-2 focus:ring-primary/20 transition-all"
37
+ />
38
+ <p className="text-sm text-muted-foreground mt-1.5">
39
+ A unique identifier for your deployment
40
+ </p>
41
+ </div>
42
+ </div>
43
+ );
44
+ };
45
+
46
+ const DeployRepository: React.FC = () => {
47
+ const params = useParams();
48
+ const router = useRouter();
49
+ const slug = params.slug as string;
50
+ const { config, initializeFromRepo, initializeFromLocal } = useDeployment();
51
+ const searchParams = useSearchParams();
52
+ const force = searchParams.get("force") || undefined;
53
+
54
+ const [loading, setLoading] = useState<boolean>(true);
55
+ const [error, setError] = useState<DeployError | null>(null);
56
+ const hasInitialized = useRef<boolean>(false);
57
+
58
+ useEffect(() => {
59
+ const initialize = async () => {
60
+ if (hasInitialized.current || !slug) return;
61
+ hasInitialized.current = true;
62
+
63
+ const decoded = decodeSlug(slug);
64
+
65
+ if (!decoded) {
66
+ setError({
67
+ type: 'invalid_url',
68
+ message: 'Invalid Repository URL',
69
+ details: 'The repository URL format is not recognized. Please check the URL and try again.'
70
+ });
71
+ setLoading(false);
72
+ return;
73
+ }
74
+
75
+ let result;
76
+ if (decoded.kind === "local") {
77
+ result = await initializeFromLocal(decoded.path);
78
+ } else {
79
+ result = await initializeFromRepo(decoded.owner, decoded.repo, force);
80
+ }
81
+
82
+ if (!result.success) {
83
+ // If build is already in progress, redirect to build page (handled elsewhere)
84
+ if ('buildInProgress' in result && result.buildInProgress) {
85
+ setLoading(false);
86
+ return;
87
+ }
88
+
89
+ // Handle specific error cases
90
+ if (result.error) {
91
+ setError({
92
+ type: result.errorType === 'api_error' ? 'repo_not_found' : 'initialization_failed',
93
+ message: decoded.kind === 'local' ? 'Failed to Load Project' : 'Failed to Load Repository',
94
+ details: result.error
95
+ });
96
+ } else {
97
+ setError({
98
+ type: 'initialization_failed',
99
+ message: decoded.kind === 'local' ? 'Failed to Load Project' : 'Failed to Load Repository',
100
+ details: decoded.kind === 'local'
101
+ ? 'We couldn\'t scan this folder. Make sure the path is correct and accessible.'
102
+ : 'We couldn\'t load this repository. It might be private, doesn\'t exist, or you don\'t have access to it.'
103
+ });
104
+ }
105
+ }
106
+
107
+ setLoading(false);
108
+ };
109
+
110
+ initialize();
111
+ }, [slug, initializeFromRepo, force, router]);
112
+
113
+ if (loading) {
114
+ return <SkeletonLoader />;
115
+ }
116
+
117
+ if (error) {
118
+ return (
119
+ <ErrorState
120
+ type="repo-not-found"
121
+ error={{
122
+ message: error.message,
123
+ details: error.details
124
+ }}
125
+ />
126
+ );
127
+ }
128
+
129
+ if (!config.repo || !config.owner) {
130
+ return null;
131
+ }
132
+
133
+ return (
134
+ <div className="min-h-screen bg-background">
135
+ <PageContainer>
136
+ <div className="grid lg:grid-cols-[1fr_340px] gap-6">
137
+ <div className="space-y-5">
138
+ {/* App flow: framework picker + build settings */}
139
+ {config.projectType === "app" && (
140
+ <>
141
+ <ProjectSettings />
142
+ <BuildSettings />
143
+ </>
144
+ )}
145
+
146
+ {/* Docker flow: single Dockerfile, just port */}
147
+ {config.projectType === "docker" && (
148
+ <DockerSettings />
149
+ )}
150
+
151
+ {/* Services flow: compose parsed services (env is per-service) */}
152
+ {config.projectType === "services" && (
153
+ <ComposeServices />
154
+ )}
155
+
156
+ {/* Global env vars — app & docker only (compose has per-service env) */}
157
+ {config.projectType !== "services" && (
158
+ <EnvironmentVariables />
159
+ )}
160
+ <ProjectName />
161
+ </div>
162
+ <Sidebar />
163
+ </div>
164
+ </PageContainer>
165
+ </div>
166
+ );
167
+ };
168
+
169
+ export default DeployRepository;
@@ -0,0 +1,7 @@
1
+ "use client";
2
+
3
+ import { DeploymentProvider } from "@/context/DeploymentContext";
4
+
5
+ export default function DeploymentLayout({ children }: { children: React.ReactNode }) {
6
+ return <DeploymentProvider>{children}</DeploymentProvider>;
7
+ }
@@ -1,10 +1,3 @@
1
1
  export default function BillingPage() {
2
- return (
3
- <div>
4
- <h1 className="text-2xl font-bold">Billing</h1>
5
- <p className="mt-2 text-gray-600">
6
- Manage your subscription, usage, and payment methods.
7
- </p>
8
- </div>
9
- );
2
+ return <div />;
10
3
  }
@@ -0,0 +1,240 @@
1
+ "use client";
2
+
3
+ import React, { useState } from "react";
4
+ import { X, Github, GitCommit, ExternalLink, User, Calendar } from "lucide-react";
5
+ import { formatDate } from "@/utils/date";
6
+ import FileIcon from "@/components/ui/FileIcon";
7
+ import type { Deployment } from "../types";
8
+
9
+ interface CommitDetailsModalProps {
10
+ deployment: Deployment;
11
+ isOpen: boolean;
12
+ onClose: () => void;
13
+ }
14
+
15
+ export const CommitDetailsModal: React.FC<CommitDetailsModalProps> = ({
16
+ deployment,
17
+ isOpen,
18
+ onClose,
19
+ }) => {
20
+ const [expandedSection, setExpandedSection] = useState<'added' | 'modified' | 'removed' | null>('modified');
21
+
22
+ if (!isOpen) return null;
23
+
24
+ const hasCommitData = deployment.commit && deployment.commit.hash && deployment.commit.hash !== 'N/A';
25
+ const commitUrl = deployment.owner && deployment.repo && deployment.commit?.hash
26
+ ? `https://github.com/${deployment.owner}/${deployment.repo}/commit/${deployment.commit.hash}`
27
+ : null;
28
+
29
+ const changedFiles = deployment.commit?.changedFiles || [];
30
+
31
+ return (
32
+ <>
33
+ {/* Backdrop */}
34
+ <div
35
+ className="fixed inset-0 bg-black/50 backdrop-blur-sm z-50 transition-opacity"
36
+ onClick={onClose}
37
+ />
38
+
39
+ {/* Modal */}
40
+ <div className="fixed inset-0 z-50 flex items-center justify-center p-4 pointer-events-none">
41
+ <div
42
+ className="bg-card rounded-2xl shadow-2xl max-w-3xl w-full max-h-[85vh] overflow-hidden pointer-events-auto animate-in zoom-in-95 duration-200 border border-border/50"
43
+ onClick={(e) => e.stopPropagation()}
44
+ >
45
+ {/* Header */}
46
+ <div className="sticky top-0 bg-card border-b border-border/50 px-6 py-5 flex items-center justify-between z-10">
47
+ <div className="flex items-center gap-3">
48
+ <div className="w-10 h-10 rounded-xl bg-primary/10 flex items-center justify-center">
49
+ <GitCommit className="w-5 h-5 text-primary" />
50
+ </div>
51
+ <div>
52
+ <h2 className="text-xl font-bold text-foreground">Commit Details</h2>
53
+ {hasCommitData && (
54
+ <p className="text-sm text-muted-foreground font-mono">{deployment.commit.hash}</p>
55
+ )}
56
+ </div>
57
+ </div>
58
+ <button
59
+ onClick={onClose}
60
+ className="w-10 h-10 rounded-full hover:bg-muted flex items-center justify-center transition-colors"
61
+ >
62
+ <X className="w-5 h-5 text-muted-foreground" />
63
+ </button>
64
+ </div>
65
+
66
+ {/* Content */}
67
+ <div className="overflow-y-auto max-h-[calc(85vh-88px)] p-6">
68
+ {hasCommitData ? (
69
+ <div className="space-y-6">
70
+ {/* Commit Message */}
71
+ <div className="bg-primary/5 rounded-2xl p-5 border border-primary/10">
72
+ <div className="flex items-start gap-3">
73
+ <div className="w-10 h-10 rounded-xl bg-card flex items-center justify-center flex-shrink-0 shadow-sm border border-border/50">
74
+ <GitCommit className="w-5 h-5 text-primary" />
75
+ </div>
76
+ <div className="flex-1 min-w-0">
77
+ <p className="text-base font-semibold text-foreground mb-2">
78
+ {deployment.commit.message}
79
+ </p>
80
+ <div className="flex items-center gap-3 text-sm text-muted-foreground">
81
+ <div className="flex items-center gap-1.5">
82
+ <User className="w-4 h-4" />
83
+ <span>{deployment.commit.author}</span>
84
+ </div>
85
+ <span className="text-muted-foreground/30">•</span>
86
+ <div className="flex items-center gap-1.5">
87
+ <Calendar className="w-4 h-4" />
88
+ <span>{formatDate(deployment.commit.timestamp, undefined, undefined, true)}</span>
89
+ </div>
90
+ </div>
91
+ </div>
92
+ </div>
93
+ </div>
94
+
95
+ {/* Deployment Info */}
96
+ <div className="grid grid-cols-2 gap-4">
97
+ <div className="bg-muted/40 border border-border/50 rounded-xl p-4">
98
+ <p className="text-xs font-semibold text-muted-foreground uppercase tracking-wide mb-2">
99
+ Project
100
+ </p>
101
+ <p className="text-base font-medium text-foreground">
102
+ {deployment.projectName || 'Unknown Project'}
103
+ </p>
104
+ </div>
105
+ <div className="bg-muted/40 border border-border/50 rounded-xl p-4">
106
+ <p className="text-xs font-semibold text-muted-foreground uppercase tracking-wide mb-2">
107
+ Domain
108
+ </p>
109
+ <p className="text-base font-medium text-foreground truncate">
110
+ {deployment.domain || 'No domain'}
111
+ </p>
112
+ </div>
113
+ <div className="bg-muted/40 border border-border/50 rounded-xl p-4">
114
+ <p className="text-xs font-semibold text-muted-foreground uppercase tracking-wide mb-2">
115
+ Status
116
+ </p>
117
+ <span className={`inline-flex items-center gap-1.5 px-3 py-1 rounded-full text-xs font-medium ${
118
+ deployment.status === 'success' ? 'bg-emerald-500/10 text-emerald-600' :
119
+ deployment.status === 'failed' ? 'bg-red-500/10 text-red-600' :
120
+ deployment.status === 'building' ? 'bg-blue-500/10 text-blue-600' :
121
+ 'bg-muted text-muted-foreground'
122
+ }`}>
123
+ {deployment.status.charAt(0).toUpperCase() + deployment.status.slice(1)}
124
+ </span>
125
+ </div>
126
+ <div className="bg-muted/40 border border-border/50 rounded-xl p-4">
127
+ <p className="text-xs font-semibold text-muted-foreground uppercase tracking-wide mb-2">
128
+ Environment
129
+ </p>
130
+ <p className="text-base font-medium text-foreground">
131
+ {deployment.environment || 'production'}
132
+ </p>
133
+ </div>
134
+ </div>
135
+
136
+ {/* Changed Files */}
137
+ {changedFiles && changedFiles.length > 0 && (
138
+ <div>
139
+ <h3 className="text-base font-bold text-foreground mb-3 flex items-center gap-2">
140
+ Changed Files ({changedFiles.length})
141
+ </h3>
142
+ <div className="bg-muted/40 rounded-xl border border-border/50 p-4">
143
+ <div className="space-y-2">
144
+ {changedFiles.map((file: any, idx: number) => {
145
+ const fileTypeConfig: Record<string, { bg: string; text: string; label: string }> = {
146
+ added: { bg: 'bg-emerald-500/10', text: 'text-emerald-600', label: '+ Added' },
147
+ modified: { bg: 'bg-blue-500/10', text: 'text-blue-600', label: '~ Modified' },
148
+ removed: { bg: 'bg-red-500/10', text: 'text-red-600', label: '- Removed' },
149
+ };
150
+ const typeConfig = fileTypeConfig[file.type] || fileTypeConfig.modified;
151
+
152
+ return (
153
+ <div
154
+ key={idx}
155
+ className="flex items-center gap-3 p-3 bg-card rounded-lg border border-border/50 hover:bg-muted/60 transition-colors"
156
+ >
157
+ <FileIcon fileName={file.name} language={file.language} style={{}} />
158
+ <span className="text-sm text-foreground flex-1 min-w-0 truncate font-mono">
159
+ {file.name}
160
+ </span>
161
+ <span className={`px-2.5 py-1 rounded-full text-xs font-medium ${typeConfig.bg} ${typeConfig.text}`}>
162
+ {typeConfig.label}
163
+ </span>
164
+ </div>
165
+ );
166
+ })}
167
+ </div>
168
+ </div>
169
+ </div>
170
+ )}
171
+
172
+ {/* Action Buttons */}
173
+ <div className="flex gap-3 pt-4 border-t border-border/50">
174
+ {commitUrl && (
175
+ <a
176
+ href={commitUrl}
177
+ target="_blank"
178
+ rel="noopener noreferrer"
179
+ className="flex-1 inline-flex items-center justify-center gap-2 px-5 py-3 bg-foreground text-background rounded-xl font-medium text-sm hover:opacity-90 transition-all"
180
+ >
181
+ <Github className="w-4 h-4" />
182
+ View on GitHub
183
+ </a>
184
+ )}
185
+ {deployment.domain && deployment.status === 'success' && (
186
+ <a
187
+ href={`https://${deployment.domain}`}
188
+ target="_blank"
189
+ rel="noopener noreferrer"
190
+ className="flex-1 inline-flex items-center justify-center gap-2 px-5 py-3 bg-primary text-primary-foreground rounded-xl font-medium text-sm hover:opacity-90 transition-all"
191
+ >
192
+ <ExternalLink className="w-4 h-4" />
193
+ Visit Site
194
+ </a>
195
+ )}
196
+ </div>
197
+ </div>
198
+ ) : (
199
+ /* Manual Deployment */
200
+ <div className="text-center py-12">
201
+ <div className="w-16 h-16 rounded-full bg-muted flex items-center justify-center mx-auto mb-4">
202
+ <GitCommit className="w-8 h-8 text-muted-foreground/50" />
203
+ </div>
204
+ <h3 className="text-lg font-semibold text-foreground mb-2">
205
+ Manual Deployment
206
+ </h3>
207
+ <p className="text-sm text-muted-foreground max-w-md mx-auto mb-6">
208
+ This deployment was triggered manually and doesn't have commit information.
209
+ </p>
210
+ <div className="bg-muted/40 rounded-xl border border-border/50 p-4 max-w-md mx-auto">
211
+ <div className="space-y-3 text-left">
212
+ <div>
213
+ <p className="text-xs font-semibold text-muted-foreground uppercase tracking-wide mb-1">
214
+ Deployment ID
215
+ </p>
216
+ <code className="text-sm text-foreground font-mono">{deployment.id}</code>
217
+ </div>
218
+ <div>
219
+ <p className="text-xs font-semibold text-muted-foreground uppercase tracking-wide mb-1">
220
+ Created
221
+ </p>
222
+ <p className="text-sm text-foreground">{formatDate(deployment.createdAt)}</p>
223
+ </div>
224
+ <div>
225
+ <p className="text-xs font-semibold text-muted-foreground uppercase tracking-wide mb-1">
226
+ Type
227
+ </p>
228
+ <p className="text-sm text-foreground capitalize">{deployment.type || 'Manual'}</p>
229
+ </div>
230
+ </div>
231
+ </div>
232
+ </div>
233
+ )}
234
+ </div>
235
+ </div>
236
+ </div>
237
+ </>
238
+ );
239
+ };
240
+
@@ -0,0 +1,121 @@
1
+ "use client";
2
+
3
+ import React, { useState } from "react";
4
+ import { useRouter } from "next/navigation";
5
+ import { DeploymentMenu } from "./DeploymentMenu";
6
+ import { CommitDetailsModal } from "./CommitDetailsModal";
7
+ import type { Deployment } from "../types";
8
+ import { formatDistanceToNow, formatBuildTime, getStatusConfig } from "../utils";
9
+ import { GitBranch, Clock, ExternalLink, MoreVertical } from "lucide-react";
10
+ import { getFrameworkConfig } from "@/components/import-project/Frameworks";
11
+
12
+ interface DeploymentCardProps {
13
+ deployment: Deployment;
14
+ onStatusChange?: () => void;
15
+ }
16
+
17
+ export const DeploymentCard: React.FC<DeploymentCardProps> = ({ deployment, onStatusChange }) => {
18
+ const router = useRouter();
19
+ const [isCommitModalOpen, setIsCommitModalOpen] = useState(false);
20
+ const statusConfig = getStatusConfig(deployment.status);
21
+ const frameworkConfig = getFrameworkConfig(deployment.framework);
22
+
23
+ const hasCommitData = deployment.commit?.hash && deployment.commit.hash !== "N/A";
24
+ const hasCommitMessage = deployment.commit?.message && deployment.commit.message !== "Manual deployment";
25
+
26
+ return (
27
+ <div
28
+ className="px-4 py-3.5 flex items-center gap-4 hover:bg-muted/40 transition-colors cursor-pointer group"
29
+ onClick={() => router.push(`/build/${deployment.id}`)}
30
+ >
31
+ {/* Framework icon */}
32
+ <div className="w-10 h-10 rounded-xl bg-muted/60 flex items-center justify-center shrink-0 group-hover:bg-muted transition-colors">
33
+ {frameworkConfig.icon ? (
34
+ frameworkConfig.icon("hsl(var(--foreground))")
35
+ ) : (
36
+ <span className="text-xs font-mono font-bold text-muted-foreground">
37
+ {(deployment.framework || "?").slice(0, 2).toUpperCase()}
38
+ </span>
39
+ )}
40
+ </div>
41
+
42
+ {/* Main info */}
43
+ <div className="flex-1 min-w-0">
44
+ <div className="flex items-center gap-2 mb-0.5">
45
+ <p className="text-sm font-medium text-foreground truncate">
46
+ {deployment.projectName || "Unknown Project"}
47
+ </p>
48
+ <span
49
+ className={`inline-flex items-center gap-1 px-2 py-0.5 rounded-full text-[10px] font-medium shrink-0 ${statusConfig.bgColor}`}
50
+ style={{ color: statusConfig.color }}
51
+ >
52
+ <span className="w-1.5 h-1.5 rounded-full" style={{ backgroundColor: statusConfig.color }} />
53
+ {statusConfig.label}
54
+ </span>
55
+ </div>
56
+ <div className="flex items-center gap-2 mt-0.5">
57
+ <p className="text-xs text-muted-foreground truncate max-w-[280px]">
58
+ {hasCommitMessage ? deployment.commit.message : "Manual deploy"}
59
+ </p>
60
+ <span className="text-muted-foreground/40">·</span>
61
+ <span className="text-xs text-muted-foreground shrink-0">
62
+ {formatDistanceToNow(new Date(deployment.createdAt))}
63
+ </span>
64
+ {deployment.buildTime ? (
65
+ <>
66
+ <span className="text-muted-foreground/40">·</span>
67
+ <span className="text-xs text-muted-foreground shrink-0 flex items-center gap-1">
68
+ <Clock className="size-3" />
69
+ {formatBuildTime(deployment.buildTime)}
70
+ </span>
71
+ </>
72
+ ) : null}
73
+ {deployment.branch && (
74
+ <>
75
+ <span className="text-muted-foreground/40 hidden sm:inline">·</span>
76
+ <span className="text-xs text-muted-foreground shrink-0 items-center gap-1 hidden sm:flex">
77
+ <GitBranch className="size-3" />
78
+ {deployment.branch}
79
+ </span>
80
+ </>
81
+ )}
82
+ </div>
83
+ </div>
84
+
85
+ {/* Right side — commit hash + actions */}
86
+ <div className="flex items-center gap-2 shrink-0">
87
+ {hasCommitData && (
88
+ <button
89
+ onClick={(e) => {
90
+ e.stopPropagation();
91
+ if (deployment.owner && deployment.repo) {
92
+ window.open(
93
+ `https://github.com/${deployment.owner}/${deployment.repo}/commit/${deployment.commit.fullHash || deployment.commit.hash}`,
94
+ "_blank",
95
+ );
96
+ } else {
97
+ setIsCommitModalOpen(true);
98
+ }
99
+ }}
100
+ className="inline-flex items-center gap-1.5 px-2.5 py-1.5 rounded-lg text-xs text-muted-foreground hover:text-foreground hover:bg-muted transition-colors font-mono"
101
+ >
102
+ {deployment.commit.hash.slice(0, 7)}
103
+ {deployment.owner && deployment.repo && <ExternalLink className="size-3" />}
104
+ </button>
105
+ )}
106
+
107
+ <DeploymentMenu
108
+ deployment={deployment}
109
+ triggerClassName="w-8 h-8 flex items-center justify-center rounded-lg text-muted-foreground/50 hover:text-foreground hover:bg-muted transition-colors"
110
+ onStatusChange={onStatusChange}
111
+ />
112
+ </div>
113
+
114
+ <CommitDetailsModal
115
+ deployment={deployment}
116
+ isOpen={isCommitModalOpen}
117
+ onClose={() => setIsCommitModalOpen(false)}
118
+ />
119
+ </div>
120
+ );
121
+ };