devpush 0.0.0-stage → 1.0.0-beta.4

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 +22 -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 +168 -3
  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,188 @@
1
+ import type { WorkspaceOperation, WorkspaceActor } from './operations'
2
+
3
+ export interface DeploymentServer {
4
+ id: string
5
+ teamId: string
6
+ teamSlug: string
7
+ teamStatus: string
8
+ handle: string
9
+ status: string
10
+ publicAddress: string | null
11
+ publicIpv4: string | null
12
+ publicIpv6: string | null
13
+ agentCapabilities?: string[] | null
14
+ }
15
+
16
+ export type GeneratedHostnameInput = {
17
+ server: DeploymentServer
18
+ projectName: string
19
+ } & (
20
+ | { kind: 'project' }
21
+ | { kind: 'environment'; environmentSlug: string }
22
+ | { kind: 'branch'; branch: string }
23
+ | { kind: 'deployment'; deploymentId: string }
24
+ )
25
+
26
+ export interface GeneratedHostname {
27
+ hostname: string
28
+ https: boolean
29
+ }
30
+
31
+ export type CertificateResult =
32
+ | { status: 'configuration'; dnsNames: string[] }
33
+ | { status: 'pending'; retryAfter: number }
34
+ | { status: 'ready'; certificatePem: string; expiresAt: string }
35
+
36
+ interface DeploymentWorkspace {
37
+ createdAt: number
38
+ personalOwnerId?: string | null
39
+ image?: string | null
40
+ color?: string
41
+ id: string
42
+ slug: string
43
+ name: string
44
+ status: string
45
+ serverCount: number
46
+ /** Latest server creation/deletion timestamp, independent of heartbeats. */
47
+ serverCountChangedAt?: number
48
+ memberCount: number
49
+ }
50
+
51
+ export type { WorkspaceOperation, WorkspaceActor } from './operations'
52
+
53
+ export interface PreparedNotification {
54
+ from: string
55
+ to: string
56
+ subject: string
57
+ text: string
58
+ html: string
59
+ }
60
+
61
+ export interface PluginContext {
62
+ defer?: (work: () => Promise<unknown>) => void
63
+ /** Render once before persisting a retryable transactional notification. */
64
+ prepareNotification?: (input: {
65
+ userId: string
66
+ subject: string
67
+ message: string
68
+ action?: { label: string; url: string }
69
+ }) => Promise<PreparedNotification | null>
70
+ /** Generic transactional delivery: recipient policy belongs to the caller. */
71
+ notifyUser?: (input: {
72
+ userId: string
73
+ subject: string
74
+ message: string
75
+ action?: { label: string; url: string }
76
+ idempotencyKey: string
77
+ prepared?: PreparedNotification
78
+ }) => Promise<boolean>
79
+ listWorkspaceOwners?: (teamId: string) => Promise<string[]>
80
+ readWorkspace?: (teamId: string) => Promise<DeploymentWorkspace | null>
81
+ authorizeWorkspace?: (
82
+ userId: string,
83
+ teamSlug: string,
84
+ ) => Promise<{ id: string; slug: string; name: string; role: string } | null>
85
+ hasServerRouting: (serverId: string) => Promise<boolean>
86
+ readServer: (serverId: string) => Promise<DeploymentServer | null>
87
+ listServers: (input: {
88
+ afterId?: string
89
+ limit: number
90
+ }) => Promise<DeploymentServer[]>
91
+ }
92
+
93
+ export interface RuntimeLogLimits {
94
+ bytesPerMinute: number
95
+ bytesPerDay: number
96
+ rowsPerDay: number
97
+ }
98
+
99
+ export interface PluginServices {
100
+ /** Optional installation policy; core authenticates and scopes logs before applying it. */
101
+ runtimeLogLimits?: (teamId: string) => RuntimeLogLimits
102
+
103
+ workspaceAccess?: {
104
+ run: <T>(
105
+ input: {
106
+ teamId: string
107
+ operation: WorkspaceOperation
108
+ actor: WorkspaceActor
109
+ },
110
+ action: () => Promise<T>,
111
+ ) => Promise<T>
112
+ }
113
+ handleRequest?: (
114
+ request: Request,
115
+ session: { userId: string; email: string } | null,
116
+ ) => Promise<Response>
117
+
118
+ generateHostname?: (
119
+ input: GeneratedHostnameInput,
120
+ ) => Promise<GeneratedHostname>
121
+ serverLifecycle?: {
122
+ reconcile: (server: DeploymentServer) => Promise<void>
123
+ maintain: () => Promise<void>
124
+ }
125
+ certificates?: {
126
+ request: (input: {
127
+ server: DeploymentServer
128
+ csrPem?: string
129
+ installedCertificateSha256?: string
130
+ }) => Promise<CertificateResult>
131
+ }
132
+ }
133
+
134
+ export function validatePluginServices(value: unknown): PluginServices {
135
+ if (!value || typeof value !== 'object' || Array.isArray(value))
136
+ throw new Error('Plugin services must be an object.')
137
+ const services = value as Record<string, unknown>
138
+ const allowed = new Set([
139
+ 'generateHostname',
140
+ 'serverLifecycle',
141
+ 'certificates',
142
+ 'workspaceAccess',
143
+ 'handleRequest',
144
+ 'runtimeLogLimits',
145
+ ])
146
+ if (Object.keys(value).some((key) => !allowed.has(key)))
147
+ throw new Error('Unknown devpush plugin service.')
148
+ if (
149
+ services.generateHostname !== undefined &&
150
+ typeof services.generateHostname !== 'function'
151
+ )
152
+ throw new Error('Invalid generated hostname service.')
153
+ if (
154
+ services.serverLifecycle !== undefined &&
155
+ !hasMethods(services.serverLifecycle, ['reconcile', 'maintain'])
156
+ )
157
+ throw new Error('Invalid server lifecycle service.')
158
+ if (
159
+ services.certificates !== undefined &&
160
+ !hasMethods(services.certificates, ['request'])
161
+ )
162
+ throw new Error('Invalid certificate service.')
163
+ if (
164
+ services.workspaceAccess !== undefined &&
165
+ !hasMethods(services.workspaceAccess, ['run'])
166
+ )
167
+ throw new Error('Invalid workspace access service.')
168
+ if (
169
+ services.handleRequest !== undefined &&
170
+ typeof services.handleRequest !== 'function'
171
+ )
172
+ throw new Error('Invalid plugin request service.')
173
+ if (
174
+ services.runtimeLogLimits !== undefined &&
175
+ typeof services.runtimeLogLimits !== 'function'
176
+ )
177
+ throw new Error('Invalid runtime log limits service.')
178
+ return Object.freeze(value)
179
+ }
180
+
181
+ function hasMethods(value: unknown, methods: ReadonlyArray<string>) {
182
+ if (!value || typeof value !== 'object' || Array.isArray(value)) return false
183
+ const record = value as Record<string, unknown>
184
+ return (
185
+ Object.keys(record).every((key) => methods.includes(key)) &&
186
+ methods.every((key) => typeof record[key] === 'function')
187
+ )
188
+ }
@@ -0,0 +1,4 @@
1
+ import type { ServerPluginEntry } from './server'
2
+
3
+ const plugins: readonly ServerPluginEntry[] = []
4
+ export default plugins
@@ -0,0 +1,4 @@
1
+ import type { ClientPluginEntry } from './client'
2
+
3
+ const plugins: readonly ClientPluginEntry[] = []
4
+ export default plugins
@@ -0,0 +1,45 @@
1
+ import type { TeamRole } from '../lib/team-role'
2
+
3
+ /** Generic workspace effects; product policies remain in plugins. */
4
+ export const workspaceOperations = [
5
+ 'workspace.update',
6
+ 'workspace.delete',
7
+ 'workspace.leave',
8
+ 'member.invite',
9
+ 'member.accept',
10
+ 'member.role',
11
+ 'member.remove',
12
+ 'member.revoke',
13
+ 'owner.transfer',
14
+ 'project.create',
15
+ 'project.update',
16
+ 'project.delete',
17
+ 'environment.update',
18
+ 'variable.update',
19
+ 'domain.update',
20
+ 'domain.verify',
21
+ 'deployment.create',
22
+ 'backup.policy.save',
23
+ 'backup.policy.delete',
24
+ 'backup.storage.save',
25
+ 'backup.storage.delete',
26
+ 'backup.run',
27
+ 'backup.restore',
28
+ 'backup.claim',
29
+ 'restore.claim',
30
+ 'server.create',
31
+ 'server.delete',
32
+ 'server.update',
33
+ 'server.enable',
34
+ 'server.disable',
35
+ 'server.enroll',
36
+ 'credential.create',
37
+ 'credential.rotate',
38
+ ] as const
39
+ export type WorkspaceOperation = (typeof workspaceOperations)[number]
40
+ export type WorkspaceActor =
41
+ | { kind: 'user'; userId: string; roleCeiling?: TeamRole }
42
+ | {
43
+ kind: 'system'
44
+ source: 'github.push' | 'backup.schedule' | 'agent' | 'maintenance'
45
+ }
@@ -0,0 +1,197 @@
1
+ import { pluginApiVersion } from './version'
2
+ import { validatePluginServices } from './contract'
3
+ import type {
4
+ PluginContext,
5
+ PluginServices,
6
+ WorkspaceOperation,
7
+ WorkspaceActor,
8
+ } from './contract'
9
+
10
+ export type {
11
+ CertificateResult,
12
+ DeploymentServer,
13
+ GeneratedHostnameInput,
14
+ RuntimeLogLimits,
15
+ WorkspaceActor,
16
+ WorkspaceOperation,
17
+ PluginContext,
18
+ PluginServices,
19
+ PreparedNotification,
20
+ } from './contract'
21
+
22
+ export interface ServerPlugin {
23
+ apiVersion: typeof pluginApiVersion
24
+ create: (
25
+ environment: Readonly<Record<string, string | undefined>>,
26
+ context: PluginContext,
27
+ ) => PluginServices
28
+ }
29
+ export interface ServerPluginEntry {
30
+ id: string
31
+ implementation: ServerPlugin
32
+ }
33
+
34
+ export function defineServerPlugin(
35
+ create: ServerPlugin['create'],
36
+ ): Readonly<ServerPlugin> {
37
+ if (typeof create !== 'function')
38
+ throw new Error('Plugin create must be a function.')
39
+ return Object.freeze({ apiVersion: pluginApiVersion, create })
40
+ }
41
+
42
+ /** Compose trusted static plugins. Core permissions still precede every policy. */
43
+ export function composeServerPlugins(
44
+ entries: readonly ServerPluginEntry[],
45
+ environment: Readonly<Record<string, string | undefined>>,
46
+ context: PluginContext,
47
+ ): PluginServices {
48
+ const environmentSnapshot = Object.freeze({ ...environment })
49
+ const ids = new Set<string>()
50
+ const services = entries.map(({ id, implementation }) => {
51
+ if (ids.has(id)) throw new Error(`Duplicate server plugin: ${id}`)
52
+ ids.add(id)
53
+ if (
54
+ (implementation.apiVersion as number) !== pluginApiVersion ||
55
+ typeof implementation.create !== 'function'
56
+ )
57
+ throw new Error(`Incompatible server plugin: ${id}`)
58
+ return {
59
+ id,
60
+ value: validatePluginServices(
61
+ implementation.create(environmentSnapshot, context),
62
+ ),
63
+ }
64
+ })
65
+ function exclusive<
66
+ TKey extends 'generateHostname' | 'certificates' | 'runtimeLogLimits',
67
+ >(key: TKey): PluginServices[TKey] {
68
+ const providers = services.filter(({ value }) => value[key])
69
+ if (providers.length > 1)
70
+ throw new Error(
71
+ `Conflicting ${key} providers: ${providers.map(({ id }) => id).join(', ')}`,
72
+ )
73
+ return providers[0]?.value[key]
74
+ }
75
+ const policies = services.flatMap(({ id, value }) =>
76
+ value.workspaceAccess ? [{ id, policy: value.workspaceAccess }] : [],
77
+ )
78
+ const lifecycle = services.flatMap(({ value }) =>
79
+ value.serverLifecycle ? [value.serverLifecycle] : [],
80
+ )
81
+ return {
82
+ generateHostname: exclusive('generateHostname'),
83
+ certificates: exclusive('certificates'),
84
+ runtimeLogLimits: exclusive('runtimeLogLimits'),
85
+ ...(policies.length
86
+ ? {
87
+ workspaceAccess: {
88
+ async run<T>(
89
+ input: {
90
+ teamId: string
91
+ operation: WorkspaceOperation
92
+ actor: WorkspaceActor
93
+ },
94
+ action: () => Promise<T>,
95
+ ) {
96
+ const policyInput = Object.freeze({
97
+ ...input,
98
+ actor: Object.freeze({ ...input.actor }),
99
+ })
100
+ let actionSucceeded = false
101
+ const invoke = async (index: number): Promise<T> => {
102
+ const entry = policies[index]
103
+ if (!entry) {
104
+ const value = await action()
105
+ actionSucceeded = true
106
+ return value
107
+ }
108
+ let calls = 0
109
+ let closed = false
110
+ let downstream: Promise<T> | undefined
111
+ try {
112
+ await entry.policy.run(policyInput, () => {
113
+ if (calls !== 0)
114
+ throw new Error(
115
+ `Plugin ${entry.id} invoked its mutation more than once.`,
116
+ )
117
+ if (closed)
118
+ throw new Error(
119
+ `Plugin ${entry.id} invoked its mutation after returning.`,
120
+ )
121
+ calls++
122
+ downstream = invoke(index + 1)
123
+ // Await it below even when a faulty provider forgets to do so.
124
+ void downstream.catch(() => {})
125
+ return downstream
126
+ })
127
+ } catch (error) {
128
+ closed = true
129
+ if (downstream) await downstream.catch(() => {})
130
+ if (actionSucceeded && error instanceof WorkspacePolicyError)
131
+ throw new Error(
132
+ `Plugin ${entry.id} rejected an already completed mutation.`,
133
+ )
134
+ throw error
135
+ } finally {
136
+ closed = true
137
+ }
138
+ if (!downstream)
139
+ throw new Error(
140
+ `Plugin ${entry.id} did not invoke or reject its mutation.`,
141
+ )
142
+ return downstream
143
+ }
144
+ return invoke(0)
145
+ },
146
+ },
147
+ }
148
+ : {}),
149
+ ...(lifecycle.length
150
+ ? {
151
+ serverLifecycle: {
152
+ async reconcile(server) {
153
+ for (const service of lifecycle) await service.reconcile(server)
154
+ },
155
+ async maintain() {
156
+ const results = await Promise.allSettled(
157
+ lifecycle.map((service) =>
158
+ Promise.resolve().then(() => service.maintain()),
159
+ ),
160
+ )
161
+ const failures = results.filter(
162
+ (result) => result.status === 'rejected',
163
+ )
164
+ if (failures.length)
165
+ throw new AggregateError(
166
+ failures.map((result) => result.reason),
167
+ 'Plugin maintenance failed.',
168
+ )
169
+ },
170
+ },
171
+ }
172
+ : {}),
173
+ async handleRequest(request, session) {
174
+ const id = /^\/api\/plugins\/([^/]+)(?:\/|$)/.exec(
175
+ new URL(request.url).pathname,
176
+ )?.[1]
177
+ const handler = services.find((service) => service.id === id)?.value
178
+ .handleRequest
179
+ return handler
180
+ ? handler(request, session)
181
+ : new Response('Not found', { status: 404 })
182
+ },
183
+ }
184
+ }
185
+
186
+ /** A deliberate policy refusal. Provider/internal errors must use ordinary errors. */
187
+ export class WorkspacePolicyError extends Error {
188
+ name = 'WorkspacePolicyError'
189
+ constructor(
190
+ readonly reason: 'restricted' | 'limit' | 'busy',
191
+ readonly publicDetails?: { message: string; recoveryUrl?: string },
192
+ ) {
193
+ super('Workspace policy rejected the operation.')
194
+ }
195
+ }
196
+
197
+ export { workspaceOperations } from './operations'
@@ -0,0 +1 @@
1
+ export const pluginApiVersion = 3