devpush 0.0.0-stage → 1.0.0-beta.3

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 (456) hide show
  1. package/README.md +6 -2
  2. package/agent-release.json +37 -0
  3. package/dist/package/LICENSE.md +21 -0
  4. package/dist/package/migrate.mjs +182 -0
  5. package/dist/package/plugins.mjs +125 -0
  6. package/dist/package/vite.mjs +439 -0
  7. package/package.json +170 -4
  8. package/public/apple-touch-icon.png +0 -0
  9. package/public/favicon.svg +1 -0
  10. package/public/logo-email.png +0 -0
  11. package/public/robots.txt +3 -0
  12. package/public/social.png +0 -0
  13. package/src/cloudflare-runtime.d.ts +78 -0
  14. package/src/components/about-dialog.tsx +70 -0
  15. package/src/components/copy-button.tsx +74 -0
  16. package/src/components/logo-mark.tsx +20 -0
  17. package/src/components/pending-collection.tsx +103 -0
  18. package/src/components/resource-avatar.tsx +65 -0
  19. package/src/components/route-error-state.tsx +95 -0
  20. package/src/components/section-navigation.tsx +39 -0
  21. package/src/components/settings-layout.tsx +111 -0
  22. package/src/components/storage-capabilities.tsx +11 -0
  23. package/src/components/table-pager.tsx +101 -0
  24. package/src/components/ui/alert-dialog.tsx +180 -0
  25. package/src/components/ui/alert.tsx +78 -0
  26. package/src/components/ui/avatar.tsx +58 -0
  27. package/src/components/ui/badge.tsx +49 -0
  28. package/src/components/ui/button-group.tsx +38 -0
  29. package/src/components/ui/button.tsx +67 -0
  30. package/src/components/ui/card.tsx +82 -0
  31. package/src/components/ui/chart.tsx +307 -0
  32. package/src/components/ui/checkbox.tsx +30 -0
  33. package/src/components/ui/combobox.tsx +256 -0
  34. package/src/components/ui/dialog.tsx +163 -0
  35. package/src/components/ui/dropdown-menu.tsx +110 -0
  36. package/src/components/ui/empty.tsx +65 -0
  37. package/src/components/ui/field.tsx +192 -0
  38. package/src/components/ui/input-group.tsx +118 -0
  39. package/src/components/ui/input-otp.tsx +70 -0
  40. package/src/components/ui/input.tsx +19 -0
  41. package/src/components/ui/label.tsx +24 -0
  42. package/src/components/ui/pagination.tsx +34 -0
  43. package/src/components/ui/popover.tsx +86 -0
  44. package/src/components/ui/select.tsx +145 -0
  45. package/src/components/ui/skeleton.tsx +19 -0
  46. package/src/components/ui/sonner.tsx +47 -0
  47. package/src/components/ui/switch.tsx +31 -0
  48. package/src/components/ui/table.tsx +81 -0
  49. package/src/components/ui/textarea.tsx +18 -0
  50. package/src/components/ui/tooltip.tsx +55 -0
  51. package/src/features/admin/admin-settings.tsx +1048 -0
  52. package/src/features/auth/current-user-context-query.ts +11 -0
  53. package/src/features/auth/login-form.tsx +442 -0
  54. package/src/features/auth/sign-out-menu-item.tsx +42 -0
  55. package/src/features/deployments/deployment-actions.tsx +336 -0
  56. package/src/features/deployments/deployment-alias-badge.tsx +35 -0
  57. package/src/features/deployments/deployment-detail.tsx +596 -0
  58. package/src/features/deployments/deployment-filters.ts +66 -0
  59. package/src/features/deployments/deployment-list.tsx +465 -0
  60. package/src/features/deployments/deployment-visit-links.tsx +104 -0
  61. package/src/features/deployments/deployments-page.tsx +376 -0
  62. package/src/features/logs/log-scroll-area.tsx +69 -0
  63. package/src/features/notifications/email-preferences.tsx +232 -0
  64. package/src/features/onboarding/profile-onboarding.tsx +162 -0
  65. package/src/features/plugins/contributions.tsx +118 -0
  66. package/src/features/projects/backup-job-logs.tsx +143 -0
  67. package/src/features/projects/backup-policy-delete-dialog.tsx +82 -0
  68. package/src/features/projects/backup-restore-actions.tsx +573 -0
  69. package/src/features/projects/backup-status-icon.tsx +33 -0
  70. package/src/features/projects/backup-target-list.tsx +222 -0
  71. package/src/features/projects/backup-timestamp.tsx +32 -0
  72. package/src/features/projects/backup-volume-picker.tsx +158 -0
  73. package/src/features/projects/compose-service-input.tsx +64 -0
  74. package/src/features/projects/deploy-readiness.ts +28 -0
  75. package/src/features/projects/environment-dot.tsx +91 -0
  76. package/src/features/projects/log-keyword-filter.tsx +48 -0
  77. package/src/features/projects/manual-deploy-dialog.tsx +563 -0
  78. package/src/features/projects/pending-section.ts +26 -0
  79. package/src/features/projects/project-backup-details-pending.tsx +305 -0
  80. package/src/features/projects/project-backup-details.tsx +936 -0
  81. package/src/features/projects/project-backup-policy.tsx +644 -0
  82. package/src/features/projects/project-backup-utils.ts +190 -0
  83. package/src/features/projects/project-backups-pending.tsx +136 -0
  84. package/src/features/projects/project-backups.tsx +876 -0
  85. package/src/features/projects/project-environment-settings.tsx +1128 -0
  86. package/src/features/projects/project-heading.tsx +68 -0
  87. package/src/features/projects/project-layout.tsx +188 -0
  88. package/src/features/projects/project-logs.tsx +461 -0
  89. package/src/features/projects/project-overview.tsx +280 -0
  90. package/src/features/projects/project-route-pending.tsx +1064 -0
  91. package/src/features/projects/project-routing-settings.tsx +663 -0
  92. package/src/features/projects/project-settings-section.tsx +64 -0
  93. package/src/features/projects/project-settings-utils.ts +101 -0
  94. package/src/features/projects/project-settings.tsx +1472 -0
  95. package/src/features/projects/repository-picker-dialog.tsx +404 -0
  96. package/src/features/repositories/new-project-dialog-launcher.tsx +44 -0
  97. package/src/features/repositories/new-project-dialog.tsx +1204 -0
  98. package/src/features/repositories/new-project-pending.tsx +28 -0
  99. package/src/features/repositories/repository-list-pending.tsx +59 -0
  100. package/src/features/servers/server-availability-alert.tsx +44 -0
  101. package/src/features/servers/server-availability.ts +29 -0
  102. package/src/features/servers/server-avatar.tsx +52 -0
  103. package/src/features/servers/server-detail-pending.tsx +315 -0
  104. package/src/features/servers/server-detail.tsx +855 -0
  105. package/src/features/servers/server-metric-chart-pending.tsx +38 -0
  106. package/src/features/servers/server-metric-chart.tsx +182 -0
  107. package/src/features/servers/server-metric-format.ts +50 -0
  108. package/src/features/servers/server-metrics-pending.tsx +75 -0
  109. package/src/features/servers/server-metrics.tsx +136 -0
  110. package/src/features/servers/team-servers.tsx +432 -0
  111. package/src/features/settings/settings-route-pending.tsx +406 -0
  112. package/src/features/teams/backup-storage-settings.tsx +483 -0
  113. package/src/features/teams/navigation.ts +51 -0
  114. package/src/features/teams/new-team-dialog.tsx +132 -0
  115. package/src/features/teams/pending-section.ts +19 -0
  116. package/src/features/teams/team-header.tsx +1286 -0
  117. package/src/features/teams/team-heading.tsx +57 -0
  118. package/src/features/teams/team-home.tsx +391 -0
  119. package/src/features/teams/team-invite.tsx +155 -0
  120. package/src/features/teams/team-route-pending.tsx +505 -0
  121. package/src/features/teams/team-settings.tsx +1555 -0
  122. package/src/features/teams/use-workspace-updates.ts +126 -0
  123. package/src/features/users/api-keys-settings.tsx +544 -0
  124. package/src/features/users/api-scope-selection.tsx +269 -0
  125. package/src/features/users/connected-apps-settings.tsx +449 -0
  126. package/src/features/users/mcp-consent.tsx +220 -0
  127. package/src/features/users/profile-picture.tsx +171 -0
  128. package/src/features/users/user-settings.tsx +1064 -0
  129. package/src/lib/account-settings-schema.ts +78 -0
  130. package/src/lib/action-feedback.ts +81 -0
  131. package/src/lib/admin-search-schema.ts +8 -0
  132. package/src/lib/agent-release.d.mts +21 -0
  133. package/src/lib/agent-release.mjs +90 -0
  134. package/src/lib/allowlist-schema.ts +79 -0
  135. package/src/lib/api-key-schema.ts +176 -0
  136. package/src/lib/auth/client.ts +20 -0
  137. package/src/lib/avatar-schema.ts +11 -0
  138. package/src/lib/backup-cron.ts +118 -0
  139. package/src/lib/backup-database.ts +41 -0
  140. package/src/lib/backup-feature.ts +2 -0
  141. package/src/lib/backup-paths.ts +7 -0
  142. package/src/lib/backup-policy-schema.ts +85 -0
  143. package/src/lib/backup-resource-schema.ts +12 -0
  144. package/src/lib/backup-restore-schema.ts +15 -0
  145. package/src/lib/backup-storage-schema.ts +55 -0
  146. package/src/lib/deferred-module.ts +38 -0
  147. package/src/lib/deployment-logs-query.ts +63 -0
  148. package/src/lib/display-name.ts +7 -0
  149. package/src/lib/error-message.ts +119 -0
  150. package/src/lib/form-errors.ts +10 -0
  151. package/src/lib/internal-redirect.ts +25 -0
  152. package/src/lib/manual-deploy-options-query.ts +21 -0
  153. package/src/lib/notification-preferences.ts +43 -0
  154. package/src/lib/onboarding.ts +11 -0
  155. package/src/lib/operation-logs-query.ts +51 -0
  156. package/src/lib/page-head.ts +14 -0
  157. package/src/lib/project-context-query.ts +257 -0
  158. package/src/lib/project-creation-schema.ts +64 -0
  159. package/src/lib/project-env-schema.ts +23 -0
  160. package/src/lib/project-environments-schema.ts +56 -0
  161. package/src/lib/project-routing-schema.ts +94 -0
  162. package/src/lib/project-runtime-config.ts +131 -0
  163. package/src/lib/project-settings-schema.ts +75 -0
  164. package/src/lib/public-api-schema.ts +128 -0
  165. package/src/lib/public-error.ts +337 -0
  166. package/src/lib/query.ts +13 -0
  167. package/src/lib/repository-selection-query.ts +11 -0
  168. package/src/lib/resource-cache.ts +30 -0
  169. package/src/lib/runtime-id.ts +19 -0
  170. package/src/lib/search.ts +14 -0
  171. package/src/lib/server-context-query.ts +43 -0
  172. package/src/lib/server-name-schema.ts +11 -0
  173. package/src/lib/settings-conflict.ts +45 -0
  174. package/src/lib/settings-version.ts +7 -0
  175. package/src/lib/team-context-query.ts +126 -0
  176. package/src/lib/team-context-schema.ts +8 -0
  177. package/src/lib/team-forms-schema.ts +45 -0
  178. package/src/lib/team-role.ts +13 -0
  179. package/src/lib/team-settings-schema.ts +48 -0
  180. package/src/lib/urls.ts +3 -0
  181. package/src/lib/use-avatar-input.ts +61 -0
  182. package/src/lib/use-refresh-error.ts +18 -0
  183. package/src/lib/use-settings-version.ts +23 -0
  184. package/src/lib/utils.ts +6 -0
  185. package/src/lib/validation.ts +5 -0
  186. package/src/lib/workspace-updates.ts +53 -0
  187. package/src/package/config.ts +10 -0
  188. package/src/package/env.mjs +54 -0
  189. package/src/package/migrate-api.d.ts +5 -0
  190. package/src/package/migrate.ts +56 -0
  191. package/src/package/plugins.ts +141 -0
  192. package/src/package/sqlite.mjs +2 -0
  193. package/src/package/vite-api.d.ts +5 -0
  194. package/src/package/vite.ts +324 -0
  195. package/src/package/watch-guard.cjs +26 -0
  196. package/src/plugins/client.ts +57 -0
  197. package/src/plugins/contract.ts +188 -0
  198. package/src/plugins/default.server.ts +4 -0
  199. package/src/plugins/default.ui.ts +4 -0
  200. package/src/plugins/operations.ts +45 -0
  201. package/src/plugins/server.ts +197 -0
  202. package/src/plugins/version.ts +1 -0
  203. package/src/routeTree.gen.ts +1275 -0
  204. package/src/router.tsx +46 -0
  205. package/src/routes/$teamSlug.index.tsx +53 -0
  206. package/src/routes/$teamSlug.new-project.tsx +13 -0
  207. package/src/routes/$teamSlug.projects.$projectName.backups.$backupId.tsx +40 -0
  208. package/src/routes/$teamSlug.projects.$projectName.backups.tsx +82 -0
  209. package/src/routes/$teamSlug.projects.$projectName.deployments.$deploymentId.tsx +52 -0
  210. package/src/routes/$teamSlug.projects.$projectName.deployments.tsx +86 -0
  211. package/src/routes/$teamSlug.projects.$projectName.logs.tsx +55 -0
  212. package/src/routes/$teamSlug.projects.$projectName.settings.tsx +51 -0
  213. package/src/routes/$teamSlug.projects.$projectName.tsx +106 -0
  214. package/src/routes/$teamSlug.projects.tsx +40 -0
  215. package/src/routes/$teamSlug.servers.$serverId.tsx +31 -0
  216. package/src/routes/$teamSlug.servers.index.tsx +59 -0
  217. package/src/routes/$teamSlug.servers.tsx +7 -0
  218. package/src/routes/$teamSlug.settings.tsx +56 -0
  219. package/src/routes/$teamSlug.tsx +86 -0
  220. package/src/routes/[.]well-known.oauth-authorization-server.api.auth.ts +13 -0
  221. package/src/routes/[.]well-known.oauth-protected-resource.mcp.ts +6 -0
  222. package/src/routes/__root.tsx +155 -0
  223. package/src/routes/admin.tsx +55 -0
  224. package/src/routes/api/agents/certificates.ts +21 -0
  225. package/src/routes/api/agents/credentials/rotate.ts +22 -0
  226. package/src/routes/api/agents/heartbeat.ts +42 -0
  227. package/src/routes/api/agents/job-logs.ts +22 -0
  228. package/src/routes/api/agents/jobs/complete.ts +22 -0
  229. package/src/routes/api/agents/jobs/next.ts +29 -0
  230. package/src/routes/api/agents/jobs/progress.ts +32 -0
  231. package/src/routes/api/agents/jobs/status.ts +22 -0
  232. package/src/routes/api/agents/register.ts +45 -0
  233. package/src/routes/api/agents/runtime-logs.ts +22 -0
  234. package/src/routes/api/agents/switch.ts +25 -0
  235. package/src/routes/api/auth/$.ts +38 -0
  236. package/src/routes/api/cron/backups.ts +33 -0
  237. package/src/routes/api/cron/maintenance.ts +30 -0
  238. package/src/routes/api/github/install.callback.ts +51 -0
  239. package/src/routes/api/github/install.ts +41 -0
  240. package/src/routes/api/github/webhook.ts +11 -0
  241. package/src/routes/api/health.ts +19 -0
  242. package/src/routes/api/install/agent.$token.ts +50 -0
  243. package/src/routes/api/install/agent.binary.ts +83 -0
  244. package/src/routes/api/install/agent.checksum.ts +45 -0
  245. package/src/routes/api/install/agent.ts +26 -0
  246. package/src/routes/api/plugins/$.ts +11 -0
  247. package/src/routes/api/v1/$.ts +15 -0
  248. package/src/routes/api/workspaces/updates.ts +8 -0
  249. package/src/routes/auth.login.tsx +50 -0
  250. package/src/routes/deployments.$deploymentId.unavailable.tsx +21 -0
  251. package/src/routes/index.tsx +23 -0
  252. package/src/routes/invites.$token.tsx +35 -0
  253. package/src/routes/mcp.ts +13 -0
  254. package/src/routes/oauth.consent.tsx +54 -0
  255. package/src/routes/onboarding.tsx +37 -0
  256. package/src/routes/onboarding.workspace.tsx +44 -0
  257. package/src/routes/settings.tsx +30 -0
  258. package/src/routes/uploads/avatars/$fileName.ts +44 -0
  259. package/src/server/admin/access.ts +67 -0
  260. package/src/server/admin/functions.ts +122 -0
  261. package/src/server/admin/service.ts +260 -0
  262. package/src/server/agents/backup-state.ts +210 -0
  263. package/src/server/agents/certificates.ts +96 -0
  264. package/src/server/agents/claims.ts +116 -0
  265. package/src/server/agents/cleanup.ts +52 -0
  266. package/src/server/agents/compatibility.ts +116 -0
  267. package/src/server/agents/completion.ts +83 -0
  268. package/src/server/agents/container-cleanup-state.ts +51 -0
  269. package/src/server/agents/deployment-state.ts +111 -0
  270. package/src/server/agents/job-payloads.ts +159 -0
  271. package/src/server/agents/jobs.ts +1293 -0
  272. package/src/server/agents/protocol.ts +400 -0
  273. package/src/server/agents/reconciliation.ts +43 -0
  274. package/src/server/agents/runtime-logs.ts +337 -0
  275. package/src/server/agents/runtime-state.ts +125 -0
  276. package/src/server/api/admission.ts +12 -0
  277. package/src/server/api/authorization.ts +115 -0
  278. package/src/server/api/credentials.ts +569 -0
  279. package/src/server/api/cursors.ts +72 -0
  280. package/src/server/api/errors.ts +24 -0
  281. package/src/server/api/functions.ts +60 -0
  282. package/src/server/api/handler.ts +274 -0
  283. package/src/server/api/mutation-operations.ts +913 -0
  284. package/src/server/api/operation-context.ts +139 -0
  285. package/src/server/api/operation-contract.ts +1099 -0
  286. package/src/server/api/operations.ts +64 -0
  287. package/src/server/api/read-operations.ts +891 -0
  288. package/src/server/api/retention.ts +33 -0
  289. package/src/server/auth/access.ts +109 -0
  290. package/src/server/auth/auth-methods.ts +28 -0
  291. package/src/server/auth/better-auth.ts +518 -0
  292. package/src/server/auth/context.ts +28 -0
  293. package/src/server/auth/email-change.ts +47 -0
  294. package/src/server/auth/email-delivery.ts +51 -0
  295. package/src/server/auth/provider-identity.ts +19 -0
  296. package/src/server/auth/provider-tokens.ts +27 -0
  297. package/src/server/auth/session.server.ts +19 -0
  298. package/src/server/backups/database-commands.ts +40 -0
  299. package/src/server/backups/destination.ts +12 -0
  300. package/src/server/backups/feature.ts +6 -0
  301. package/src/server/backups/policy-validation.ts +51 -0
  302. package/src/server/backups/queue-state.ts +137 -0
  303. package/src/server/backups/service.ts +918 -0
  304. package/src/server/backups/storage-functions.ts +42 -0
  305. package/src/server/backups/storage-state.ts +67 -0
  306. package/src/server/backups/storage.ts +237 -0
  307. package/src/server/config.ts +274 -0
  308. package/src/server/db/atomic.ts +16 -0
  309. package/src/server/db/d1-connection.ts +83 -0
  310. package/src/server/db/errors.ts +17 -0
  311. package/src/server/db/index.cloudflare.ts +15 -0
  312. package/src/server/db/index.ts +35 -0
  313. package/src/server/db/libsql-connection.ts +72 -0
  314. package/src/server/db/log-schema.ts +102 -0
  315. package/src/server/db/migrate-libsql.ts +29 -0
  316. package/src/server/db/migrate-sqlite.ts +47 -0
  317. package/src/server/db/migration-history.ts +12 -0
  318. package/src/server/db/migrations-logs/0000_initial.sql +48 -0
  319. package/src/server/db/migrations-logs/0001_runtime_log_order.sql +2 -0
  320. package/src/server/db/migrations-logs/meta/0000_snapshot.json +327 -0
  321. package/src/server/db/migrations-logs/meta/0001_snapshot.json +329 -0
  322. package/src/server/db/migrations-logs/meta/_journal.json +20 -0
  323. package/src/server/db/migrations-sqlite/0000_initial.sql +894 -0
  324. package/src/server/db/migrations-sqlite/0001_agent_indexes.sql +5 -0
  325. package/src/server/db/migrations-sqlite/meta/0000_snapshot.json +5816 -0
  326. package/src/server/db/migrations-sqlite/meta/0001_snapshot.json +5841 -0
  327. package/src/server/db/migrations-sqlite/meta/_journal.json +20 -0
  328. package/src/server/db/oauth-schema.ts +216 -0
  329. package/src/server/db/remote-config.ts +47 -0
  330. package/src/server/db/schema.ts +1218 -0
  331. package/src/server/db/sqlite-connection.ts +94 -0
  332. package/src/server/db/sqlite-files.ts +27 -0
  333. package/src/server/db/sqlite-params.ts +19 -0
  334. package/src/server/db/worker-connection.ts +47 -0
  335. package/src/server/deleted-resources.ts +133 -0
  336. package/src/server/deletion-recovery.ts +272 -0
  337. package/src/server/email/layout.tsx +85 -0
  338. package/src/server/email/notification-template.tsx +62 -0
  339. package/src/server/email/otp-template.tsx +48 -0
  340. package/src/server/email/service.ts +251 -0
  341. package/src/server/email/team-invite-template.tsx +59 -0
  342. package/src/server/email/theme.ts +10 -0
  343. package/src/server/github/http.ts +14 -0
  344. package/src/server/github/install-state.ts +48 -0
  345. package/src/server/github/service.ts +831 -0
  346. package/src/server/github/webhook-handler.ts +198 -0
  347. package/src/server/github/webhooks.ts +205 -0
  348. package/src/server/http/auth.ts +11 -0
  349. package/src/server/http/error-diagnostics.ts +66 -0
  350. package/src/server/http/plugin-request.ts +15 -0
  351. package/src/server/http/proxy-request.ts +53 -0
  352. package/src/server/http/public-errors.ts +48 -0
  353. package/src/server/http/rate-limit.ts +59 -0
  354. package/src/server/http/request-body.ts +54 -0
  355. package/src/server/http/request-ip.ts +54 -0
  356. package/src/server/http/security-headers.ts +36 -0
  357. package/src/server/install/agent-binary.ts +230 -0
  358. package/src/server/install/agent-script.ts +565 -0
  359. package/src/server/install/release-binary.ts +65 -0
  360. package/src/server/logs/budget.ts +72 -0
  361. package/src/server/logs/cleanup.ts +64 -0
  362. package/src/server/logs/deployments.ts +98 -0
  363. package/src/server/logs/operations.ts +145 -0
  364. package/src/server/logs/retention.ts +39 -0
  365. package/src/server/maintenance.ts +61 -0
  366. package/src/server/mcp/connections.ts +358 -0
  367. package/src/server/mcp/functions.ts +63 -0
  368. package/src/server/mcp/handler.ts +295 -0
  369. package/src/server/mcp/oauth-discovery.cloudflare.ts +6 -0
  370. package/src/server/mcp/oauth-discovery.ts +8 -0
  371. package/src/server/mcp/oauth-provider.ts +220 -0
  372. package/src/server/mcp/urls.ts +20 -0
  373. package/src/server/notifications/functions.ts +51 -0
  374. package/src/server/notifications/observe.ts +303 -0
  375. package/src/server/notifications/outbox.ts +335 -0
  376. package/src/server/notifications/preferences.ts +131 -0
  377. package/src/server/notifications/query.ts +16 -0
  378. package/src/server/plugins/scope.ts +17 -0
  379. package/src/server/plugins/server-context.ts +157 -0
  380. package/src/server/plugins/services.server.ts +10 -0
  381. package/src/server/plugins/workspace-access.ts +74 -0
  382. package/src/server/projects/backup-policy-state.ts +68 -0
  383. package/src/server/projects/backups.ts +219 -0
  384. package/src/server/projects/compose-metadata.ts +174 -0
  385. package/src/server/projects/configuration-state.ts +90 -0
  386. package/src/server/projects/context.ts +909 -0
  387. package/src/server/projects/creation-state.ts +46 -0
  388. package/src/server/projects/deletion-state.ts +69 -0
  389. package/src/server/projects/deployment-config.ts +139 -0
  390. package/src/server/projects/deployment-logs.ts +97 -0
  391. package/src/server/projects/deployments.ts +1123 -0
  392. package/src/server/projects/domain-state.ts +71 -0
  393. package/src/server/projects/environment-branches.ts +75 -0
  394. package/src/server/projects/environment-state.ts +158 -0
  395. package/src/server/projects/environments.ts +424 -0
  396. package/src/server/projects/functions.ts +748 -0
  397. package/src/server/projects/generated-hostname.ts +77 -0
  398. package/src/server/projects/hostnames.ts +244 -0
  399. package/src/server/projects/mappers.ts +457 -0
  400. package/src/server/projects/names.ts +41 -0
  401. package/src/server/projects/project-env-vars.ts +28 -0
  402. package/src/server/projects/queue-state.ts +118 -0
  403. package/src/server/projects/repository.ts +368 -0
  404. package/src/server/projects/route-state.ts +37 -0
  405. package/src/server/projects/runtime-logs.ts +97 -0
  406. package/src/server/projects/settings-context.ts +58 -0
  407. package/src/server/projects/settings.ts +738 -0
  408. package/src/server/projects/types.ts +355 -0
  409. package/src/server/realtime/agent-events.ts +32 -0
  410. package/src/server/realtime/node-broadcaster.ts +71 -0
  411. package/src/server/realtime/node-handler.ts +55 -0
  412. package/src/server/realtime/service.ts +125 -0
  413. package/src/server/realtime/workspace-object.cloudflare.ts +62 -0
  414. package/src/server/realtime/workspace-object.ts +3 -0
  415. package/src/server/resources/color.ts +13 -0
  416. package/src/server/runtime/background.ts +21 -0
  417. package/src/server/runtime/node-asset-cache-plugin.ts +12 -0
  418. package/src/server/runtime/node-scheduler-plugin.ts +17 -0
  419. package/src/server/runtime/node-scheduler.ts +51 -0
  420. package/src/server/runtime/platform-env.cloudflare.ts +17 -0
  421. package/src/server/runtime/platform-env.ts +19 -0
  422. package/src/server/runtime/scheduled-task-error.ts +9 -0
  423. package/src/server/scheduled-tasks.ts +28 -0
  424. package/src/server/secrets/crypto.ts +56 -0
  425. package/src/server/servers/functions.ts +233 -0
  426. package/src/server/servers/lifecycle.ts +122 -0
  427. package/src/server/servers/metric-history-schema.ts +24 -0
  428. package/src/server/servers/metric-history.ts +55 -0
  429. package/src/server/servers/monitoring.ts +592 -0
  430. package/src/server/servers/service.ts +1211 -0
  431. package/src/server/servers/status.ts +32 -0
  432. package/src/server/servers/switch.ts +96 -0
  433. package/src/server/settings-version.ts +43 -0
  434. package/src/server/storage/capabilities.ts +6 -0
  435. package/src/server/storage/local-object-store.cloudflare.ts +7 -0
  436. package/src/server/storage/local-object-store.ts +50 -0
  437. package/src/server/storage/object-store.ts +160 -0
  438. package/src/server/teams/creation.ts +51 -0
  439. package/src/server/teams/delete-policy.ts +13 -0
  440. package/src/server/teams/deletion-state.ts +80 -0
  441. package/src/server/teams/functions.ts +324 -0
  442. package/src/server/teams/invitations.ts +38 -0
  443. package/src/server/teams/membership.ts +86 -0
  444. package/src/server/teams/queries.ts +261 -0
  445. package/src/server/teams/service.ts +1127 -0
  446. package/src/server/teams/types.ts +101 -0
  447. package/src/server/uploads/avatar.ts +133 -0
  448. package/src/server/users/deletion-state.ts +93 -0
  449. package/src/server/users/functions.ts +160 -0
  450. package/src/server/users/onboarding.ts +17 -0
  451. package/src/server/users/service.ts +644 -0
  452. package/src/server.ts +55 -0
  453. package/src/styles/shadcn.css +653 -0
  454. package/src/styles/theme.css +76 -0
  455. package/src/styles.css +177 -0
  456. package/wrangler.template.jsonc +37 -0
@@ -0,0 +1,62 @@
1
+ import { Button, Link, Section, Text } from '@react-email/components'
2
+ import { EmailLayout } from './layout'
3
+ import { emailTheme } from './theme'
4
+
5
+ export function NotificationEmailTemplate({
6
+ title,
7
+ message,
8
+ to,
9
+ action,
10
+ }: {
11
+ title: string
12
+ message: string
13
+ to: string
14
+ action?: { label: string; url: string }
15
+ }) {
16
+ return (
17
+ <EmailLayout title={title} preview={title} to={to} allowIgnore={false}>
18
+ {message
19
+ .split('\n')
20
+ .filter(Boolean)
21
+ .map((paragraph, index) => (
22
+ <Text
23
+ key={index}
24
+ className="text-[16px] leading-[24px]"
25
+ style={{ color: emailTheme.foreground }}
26
+ >
27
+ {paragraph}
28
+ </Text>
29
+ ))}
30
+ {action ? (
31
+ <>
32
+ <Section className="my-[28px] text-center">
33
+ <Button
34
+ className="rounded-lg px-[18px] py-[10px] text-[14px] font-medium no-underline"
35
+ href={action.url}
36
+ style={{
37
+ backgroundColor: emailTheme.primary,
38
+ color: emailTheme.primaryForeground,
39
+ }}
40
+ >
41
+ {action.label}
42
+ </Button>
43
+ </Section>
44
+ <Text
45
+ className="text-[14px] leading-[24px]"
46
+ style={{ color: emailTheme.mutedForeground }}
47
+ >
48
+ If the button does not work, copy and paste this link into your
49
+ browser:{' '}
50
+ <Link
51
+ className="break-all underline"
52
+ href={action.url}
53
+ style={{ color: emailTheme.mutedLink }}
54
+ >
55
+ {action.url}
56
+ </Link>
57
+ </Text>
58
+ </>
59
+ ) : null}
60
+ </EmailLayout>
61
+ )
62
+ }
@@ -0,0 +1,48 @@
1
+ import { Section, Text } from '@react-email/components'
2
+ import { EmailLayout } from './layout'
3
+ import { emailTheme } from './theme'
4
+
5
+ type OtpEmailTemplateProps = {
6
+ otp: string
7
+ preview: string
8
+ to: string
9
+ }
10
+
11
+ export function OtpEmailTemplate({ otp, preview, to }: OtpEmailTemplateProps) {
12
+ return (
13
+ <EmailLayout title={'Sign in to devpush'} preview={preview} to={to}>
14
+ <Text
15
+ className="text-[16px] leading-[24px]"
16
+ style={{ color: emailTheme.foreground }}
17
+ >
18
+ Enter this temporary verification code to continue:
19
+ </Text>
20
+
21
+ <Section className="mt-[24px] mb-[24px] text-center">
22
+ <pre
23
+ className="inline-block rounded-lg border-0 text-[24px] font-medium"
24
+ style={{
25
+ backgroundColor: emailTheme.muted,
26
+ color: emailTheme.foreground,
27
+ fontFamily:
28
+ 'ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace',
29
+ letterSpacing: '6px',
30
+ lineHeight: 1,
31
+ marginBottom: 0,
32
+ marginTop: 0,
33
+ padding: '12px 4px 12px 12px',
34
+ }}
35
+ >
36
+ {otp}
37
+ </pre>
38
+ </Section>
39
+
40
+ <Text
41
+ className="text-[16px] leading-[24px]"
42
+ style={{ color: emailTheme.foreground }}
43
+ >
44
+ This code will expire in 5 minutes.
45
+ </Text>
46
+ </EmailLayout>
47
+ )
48
+ }
@@ -0,0 +1,251 @@
1
+ import { safeErrorDiagnostics } from '#devpush/server/http/error-diagnostics'
2
+ import { config } from '#devpush/server/config'
3
+
4
+ type EmailPayload = {
5
+ from?: string
6
+ html: string
7
+ subject: string
8
+ text: string
9
+ to: string
10
+ }
11
+
12
+ export async function sendEmail(
13
+ { from = config.EMAIL_FROM, html, subject, text, to }: EmailPayload,
14
+ idempotencyKey?: string,
15
+ ) {
16
+ if (!from) {
17
+ throw new Error('EMAIL_FROM is not configured.')
18
+ }
19
+
20
+ if (!config.RESEND_API_KEY) {
21
+ throw new Error('RESEND_API_KEY is not configured.')
22
+ }
23
+
24
+ try {
25
+ const response = await fetch('https://api.resend.com/emails', {
26
+ method: 'POST',
27
+ signal: AbortSignal.timeout(10_000),
28
+ headers: {
29
+ Authorization: `Bearer ${config.RESEND_API_KEY}`,
30
+ 'Content-Type': 'application/json',
31
+ ...(idempotencyKey ? { 'Idempotency-Key': idempotencyKey } : {}),
32
+ },
33
+ body: JSON.stringify({
34
+ from,
35
+ html,
36
+ subject,
37
+ text,
38
+ to,
39
+ }),
40
+ })
41
+ // Only provider acceptance matters here; never retain or surface its body.
42
+ await response.body?.cancel().catch(() => undefined)
43
+ if (!response.ok) {
44
+ console.warn('Email provider rejected delivery.', {
45
+ status: response.status,
46
+ })
47
+ throw new Error('Email provider rejected delivery.')
48
+ }
49
+ } catch (error) {
50
+ console.warn('Email delivery failed.', safeErrorDiagnostics(error))
51
+ throw new Error('Unable to deliver email.')
52
+ }
53
+ }
54
+
55
+ export async function sendOtpEmail(email: string, otp: string) {
56
+ const message = await buildOtpEmailMessage(email, otp)
57
+
58
+ await sendEmail({
59
+ to: email,
60
+ subject: message.subject,
61
+ html: message.html,
62
+ text: message.text,
63
+ })
64
+ }
65
+
66
+ export async function sendEmailChangeEmail({
67
+ currentEmail,
68
+ newEmail,
69
+ verifyUrl,
70
+ }: {
71
+ currentEmail: string
72
+ newEmail: string
73
+ verifyUrl: string
74
+ }) {
75
+ const message = await buildEmailChangeMessage({
76
+ currentEmail,
77
+ newEmail,
78
+ verifyUrl,
79
+ })
80
+
81
+ await sendEmail({
82
+ to: currentEmail,
83
+ subject: message.subject,
84
+ html: message.html,
85
+ text: message.text,
86
+ })
87
+ }
88
+
89
+ export async function buildEmailChangeMessage({
90
+ currentEmail,
91
+ newEmail,
92
+ verifyUrl,
93
+ }: {
94
+ currentEmail: string
95
+ newEmail: string
96
+ verifyUrl: string
97
+ }) {
98
+ return {
99
+ subject: 'Confirm your devpush email change',
100
+ html: await renderNotificationEmail({
101
+ title: 'Confirm your devpush email change',
102
+ to: currentEmail,
103
+ message: `Confirm that you want to use ${newEmail} for devpush.\nAfter confirmation, we will ask you to verify the new address.`,
104
+ action: { label: 'Confirm email change', url: verifyUrl },
105
+ }),
106
+ text: `Confirm that you want to use ${newEmail} for devpush.
107
+
108
+ Confirm email change: ${verifyUrl}
109
+
110
+ This request was made from ${currentEmail}. After confirmation, we will ask you to verify the new address.`,
111
+ }
112
+ }
113
+
114
+ export async function sendEmailVerificationEmail({
115
+ email,
116
+ verifyUrl,
117
+ }: {
118
+ email: string
119
+ verifyUrl: string
120
+ }) {
121
+ const message = await buildEmailVerificationMessage({ email, verifyUrl })
122
+
123
+ await sendEmail({
124
+ to: email,
125
+ subject: message.subject,
126
+ html: message.html,
127
+ text: message.text,
128
+ })
129
+ }
130
+
131
+ export async function buildEmailVerificationMessage({
132
+ email,
133
+ verifyUrl,
134
+ }: {
135
+ email: string
136
+ verifyUrl: string
137
+ }) {
138
+ return {
139
+ subject: 'Verify your devpush email address',
140
+ html: await renderNotificationEmail({
141
+ title: 'Verify your devpush email address',
142
+ to: email,
143
+ message: 'Verify your email address for devpush.',
144
+ action: { label: 'Verify email address', url: verifyUrl },
145
+ }),
146
+ text: `Verify your email address for devpush.
147
+
148
+ Verify email address: ${verifyUrl}
149
+
150
+ This email was intended for ${email}. If you think this is a mistake, you can safely ignore this email.`,
151
+ }
152
+ }
153
+
154
+ export async function buildOtpEmailMessage(email: string, otp: string) {
155
+ const [{ render }, { OtpEmailTemplate }] = await Promise.all([
156
+ import('@react-email/render'),
157
+ import('#devpush/server/email/otp-template'),
158
+ ])
159
+ const subject = `Your temporary code is ${otp}`
160
+ const html = await render(
161
+ OtpEmailTemplate({ otp, preview: subject, to: email }),
162
+ )
163
+
164
+ return {
165
+ subject,
166
+ html,
167
+ text: `Your temporary code is ${otp}
168
+
169
+ Sign in to devpush
170
+
171
+ Enter this temporary verification code to continue:
172
+
173
+ ${otp}
174
+
175
+ This code will expire in 5 minutes.
176
+
177
+ This email was intended for ${email}. If you think this is a mistake, you can safely ignore this email.`,
178
+ }
179
+ }
180
+
181
+ export async function renderNotificationEmail(input: {
182
+ title: string
183
+ message: string
184
+ to: string
185
+ action?: { label: string; url: string }
186
+ }) {
187
+ const [{ render }, { NotificationEmailTemplate }] = await Promise.all([
188
+ import('@react-email/render'),
189
+ import('./notification-template'),
190
+ ])
191
+ return render(NotificationEmailTemplate(input))
192
+ }
193
+
194
+ export async function sendTeamInviteEmail({
195
+ email,
196
+ inviteUrl,
197
+ teamName,
198
+ }: {
199
+ email: string
200
+ inviteUrl: string
201
+ teamName: string
202
+ }) {
203
+ const message = await buildTeamInviteEmailMessage({
204
+ email,
205
+ inviteUrl,
206
+ teamName,
207
+ })
208
+
209
+ await sendEmail({
210
+ to: email,
211
+ subject: message.subject,
212
+ html: message.html,
213
+ text: message.text,
214
+ })
215
+ }
216
+
217
+ export async function buildTeamInviteEmailMessage({
218
+ email,
219
+ inviteUrl,
220
+ teamName,
221
+ }: {
222
+ email: string
223
+ inviteUrl: string
224
+ teamName: string
225
+ }) {
226
+ const [{ render }, { TeamInviteEmailTemplate }] = await Promise.all([
227
+ import('@react-email/render'),
228
+ import('#devpush/server/email/team-invite-template'),
229
+ ])
230
+ const subject = `Join ${teamName} on devpush`
231
+ const html = await render(
232
+ TeamInviteEmailTemplate({
233
+ inviteUrl,
234
+ preview: subject,
235
+ teamName,
236
+ to: email,
237
+ }),
238
+ )
239
+
240
+ return {
241
+ subject,
242
+ html,
243
+ text: `Join ${teamName} on devpush
244
+
245
+ You have been invited to join ${teamName} on devpush.
246
+
247
+ Accept invitation: ${inviteUrl}
248
+
249
+ This email was intended for ${email}. If you think this is a mistake, you can safely ignore this email.`,
250
+ }
251
+ }
@@ -0,0 +1,59 @@
1
+ import { Button, Link, Section, Text } from '@react-email/components'
2
+ import { EmailLayout } from './layout'
3
+ import { emailTheme } from './theme'
4
+
5
+ type TeamInviteEmailTemplateProps = {
6
+ inviteUrl: string
7
+ preview: string
8
+ teamName: string
9
+ to: string
10
+ }
11
+
12
+ export function TeamInviteEmailTemplate({
13
+ inviteUrl,
14
+ preview,
15
+ teamName,
16
+ to,
17
+ }: TeamInviteEmailTemplateProps) {
18
+ return (
19
+ <EmailLayout
20
+ title={`Join ${teamName} on devpush`}
21
+ preview={preview}
22
+ to={to}
23
+ >
24
+ <Text
25
+ className="text-[16px] leading-[24px]"
26
+ style={{ color: emailTheme.foreground }}
27
+ >
28
+ You have been invited to join {teamName} on devpush.
29
+ </Text>
30
+
31
+ <Section className="mt-[28px] mb-[28px] text-center">
32
+ <Button
33
+ className="rounded-lg px-[18px] py-[10px] text-center text-[14px] font-medium no-underline"
34
+ href={inviteUrl}
35
+ style={{
36
+ backgroundColor: emailTheme.primary,
37
+ color: emailTheme.primaryForeground,
38
+ }}
39
+ >
40
+ Accept invitation
41
+ </Button>
42
+ </Section>
43
+
44
+ <Text
45
+ className="text-[14px] leading-[24px]"
46
+ style={{ color: emailTheme.mutedForeground }}
47
+ >
48
+ If the button does not work, copy and paste this link into your browser:{' '}
49
+ <Link
50
+ className="break-all underline"
51
+ href={inviteUrl}
52
+ style={{ color: emailTheme.mutedLink }}
53
+ >
54
+ {inviteUrl}
55
+ </Link>
56
+ </Text>
57
+ </EmailLayout>
58
+ )
59
+ }
@@ -0,0 +1,10 @@
1
+ // Email-safe sRGB equivalents of the light Taupe tokens in styles/theme.css.
2
+ export const emailTheme = {
3
+ background: '#ffffff',
4
+ foreground: '#0c0a09',
5
+ primary: '#1d1816',
6
+ primaryForeground: '#fbfaf9',
7
+ muted: '#f3f1f1',
8
+ mutedForeground: '#7c6d67',
9
+ mutedLink: '#7c6d67',
10
+ } as const
@@ -0,0 +1,14 @@
1
+ import { readRequestText } from '#devpush/server/http/request-body'
2
+ /** Fixed-provider requests must not hold auth, enrollment or scheduler work indefinitely. */
3
+ export function fetchGitHub(url: string, init: RequestInit = {}) {
4
+ const timeout = AbortSignal.timeout(10_000)
5
+ return fetch(url, {
6
+ ...init,
7
+ signal: init.signal ? AbortSignal.any([init.signal, timeout]) : timeout,
8
+ })
9
+ }
10
+
11
+ /** GitHub pages/contents have known sizes; never buffer an unlimited provider body. */
12
+ export async function readGitHubJson<T>(response: Response): Promise<T> {
13
+ return JSON.parse(await readRequestText(response, 4 * 1024 * 1024)) as T
14
+ }
@@ -0,0 +1,48 @@
1
+ import { jwtVerify, SignJWT } from 'jose'
2
+
3
+ import { config } from '#devpush/server/config'
4
+ import { getSafeRedirectPath } from '#devpush/lib/internal-redirect'
5
+
6
+ const audience = 'devpush:github-installation'
7
+ const issuer = 'devpush'
8
+
9
+ export async function createGitHubInstallState({
10
+ next,
11
+ userId,
12
+ }: {
13
+ next: string
14
+ userId: string
15
+ }) {
16
+ return new SignJWT({ next: getSafeRedirectPath(next), userId })
17
+ .setProtectedHeader({ alg: 'HS256' })
18
+ .setAudience(audience)
19
+ .setIssuer(issuer)
20
+ .setIssuedAt()
21
+ .setExpirationTime('15m')
22
+ .setJti(crypto.randomUUID())
23
+ .sign(secret())
24
+ }
25
+
26
+ export async function verifyGitHubInstallState({
27
+ state,
28
+ userId,
29
+ }: {
30
+ state: string
31
+ userId: string
32
+ }) {
33
+ const { payload } = await jwtVerify(state, secret(), {
34
+ algorithms: ['HS256'],
35
+ audience,
36
+ issuer,
37
+ })
38
+
39
+ if (payload.userId !== userId || typeof payload.next !== 'string') {
40
+ throw new Error('Invalid GitHub installation state.')
41
+ }
42
+
43
+ return getSafeRedirectPath(payload.next)
44
+ }
45
+
46
+ function secret() {
47
+ return new TextEncoder().encode(config.BETTER_AUTH_SECRET)
48
+ }