@wascartech/devbot 0.0.0-stage → 2.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 (376) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +638 -2
  3. package/dist/access-grant-store.js +99 -0
  4. package/dist/access-grant-store.js.map +1 -0
  5. package/dist/access-resolve.js +11 -0
  6. package/dist/access-resolve.js.map +1 -0
  7. package/dist/access-rule-store.js +99 -0
  8. package/dist/access-rule-store.js.map +1 -0
  9. package/dist/admin/access-routes.js +73 -0
  10. package/dist/admin/access-routes.js.map +1 -0
  11. package/dist/admin/access-rule-routes.js +107 -0
  12. package/dist/admin/access-rule-routes.js.map +1 -0
  13. package/dist/admin/custom-repos-routes.js +93 -0
  14. package/dist/admin/custom-repos-routes.js.map +1 -0
  15. package/dist/admin/env-routes.js +74 -0
  16. package/dist/admin/env-routes.js.map +1 -0
  17. package/dist/admin/global-settings-routes.js +254 -0
  18. package/dist/admin/global-settings-routes.js.map +1 -0
  19. package/dist/admin/mcp-cleanup.js +12 -0
  20. package/dist/admin/mcp-cleanup.js.map +1 -0
  21. package/dist/admin/mcp-routes.js +169 -0
  22. package/dist/admin/mcp-routes.js.map +1 -0
  23. package/dist/admin/query-params.js +80 -0
  24. package/dist/admin/query-params.js.map +1 -0
  25. package/dist/admin/routes.js +150 -0
  26. package/dist/admin/routes.js.map +1 -0
  27. package/dist/admin/run-history-routes.js +44 -0
  28. package/dist/admin/run-history-routes.js.map +1 -0
  29. package/dist/admin/run-routes.js +99 -0
  30. package/dist/admin/run-routes.js.map +1 -0
  31. package/dist/admin/settings-routes.js +119 -0
  32. package/dist/admin/settings-routes.js.map +1 -0
  33. package/dist/admin/stats-routes.js +51 -0
  34. package/dist/admin/stats-routes.js.map +1 -0
  35. package/dist/admin/task-routes.js +213 -0
  36. package/dist/admin/task-routes.js.map +1 -0
  37. package/dist/admin/test-routes.js +38 -0
  38. package/dist/admin/test-routes.js.map +1 -0
  39. package/dist/admin/volume-routes.js +82 -0
  40. package/dist/admin/volume-routes.js.map +1 -0
  41. package/dist/admin/webhook-routes.js +174 -0
  42. package/dist/admin/webhook-routes.js.map +1 -0
  43. package/dist/agents.js +48 -0
  44. package/dist/agents.js.map +1 -0
  45. package/dist/assignee-value.js +6 -0
  46. package/dist/assignee-value.js.map +1 -0
  47. package/dist/attachments.js +76 -0
  48. package/dist/attachments.js.map +1 -0
  49. package/dist/auto-commands.js +88 -0
  50. package/dist/auto-commands.js.map +1 -0
  51. package/dist/auto-features.js +32 -0
  52. package/dist/auto-features.js.map +1 -0
  53. package/dist/base-branch-store.js +40 -0
  54. package/dist/base-branch-store.js.map +1 -0
  55. package/dist/base-branches.js +9 -0
  56. package/dist/base-branches.js.map +1 -0
  57. package/dist/build-workflow.js +116 -0
  58. package/dist/build-workflow.js.map +1 -0
  59. package/dist/change-request-lifecycle.js +16 -0
  60. package/dist/change-request-lifecycle.js.map +1 -0
  61. package/dist/change-request-store.js +72 -0
  62. package/dist/change-request-store.js.map +1 -0
  63. package/dist/ci-failure.js +80 -0
  64. package/dist/ci-failure.js.map +1 -0
  65. package/dist/cli.js +3 -0
  66. package/dist/cli.js.map +1 -0
  67. package/dist/config.js +17 -0
  68. package/dist/config.js.map +1 -0
  69. package/dist/conflict-fix.js +178 -0
  70. package/dist/conflict-fix.js.map +1 -0
  71. package/dist/cookie.js +70 -0
  72. package/dist/cookie.js.map +1 -0
  73. package/dist/crypto-util.js +40 -0
  74. package/dist/crypto-util.js.map +1 -0
  75. package/dist/custom-repos-store.js +90 -0
  76. package/dist/custom-repos-store.js.map +1 -0
  77. package/dist/custom-repos-sync.js +118 -0
  78. package/dist/custom-repos-sync.js.map +1 -0
  79. package/dist/db.js +12 -0
  80. package/dist/db.js.map +1 -0
  81. package/dist/devbot-scripts.js +18 -0
  82. package/dist/devbot-scripts.js.map +1 -0
  83. package/dist/devcontainer.js +150 -0
  84. package/dist/devcontainer.js.map +1 -0
  85. package/dist/env-config-store.js +132 -0
  86. package/dist/env-config-store.js.map +1 -0
  87. package/dist/error-log-store.js +193 -0
  88. package/dist/error-log-store.js.map +1 -0
  89. package/dist/git.js +605 -0
  90. package/dist/git.js.map +1 -0
  91. package/dist/global-queue.js +127 -0
  92. package/dist/global-queue.js.map +1 -0
  93. package/dist/global-settings-store.js +307 -0
  94. package/dist/global-settings-store.js.map +1 -0
  95. package/dist/help.js +41 -0
  96. package/dist/help.js.map +1 -0
  97. package/dist/http-csp.js +15 -0
  98. package/dist/http-csp.js.map +1 -0
  99. package/dist/http-util.js +40 -0
  100. package/dist/http-util.js.map +1 -0
  101. package/dist/idempotency.js +50 -0
  102. package/dist/idempotency.js.map +1 -0
  103. package/dist/lifecycle.js +234 -0
  104. package/dist/lifecycle.js.map +1 -0
  105. package/dist/logger.js +33 -0
  106. package/dist/logger.js.map +1 -0
  107. package/dist/lsp-servers.js +81 -0
  108. package/dist/lsp-servers.js.map +1 -0
  109. package/dist/mcp/auth.js +62 -0
  110. package/dist/mcp/auth.js.map +1 -0
  111. package/dist/mcp/effective-mcp.js +42 -0
  112. package/dist/mcp/effective-mcp.js.map +1 -0
  113. package/dist/mcp/oauth-refresh.js +138 -0
  114. package/dist/mcp/oauth-refresh.js.map +1 -0
  115. package/dist/mcp/peer-sync.js +109 -0
  116. package/dist/mcp/peer-sync.js.map +1 -0
  117. package/dist/mcp/registry.js +54 -0
  118. package/dist/mcp/registry.js.map +1 -0
  119. package/dist/mcp/runner-bridge.js +93 -0
  120. package/dist/mcp/runner-bridge.js.map +1 -0
  121. package/dist/mcp/server.js +173 -0
  122. package/dist/mcp/server.js.map +1 -0
  123. package/dist/mcp/tools/_helpers.js +88 -0
  124. package/dist/mcp/tools/_helpers.js.map +1 -0
  125. package/dist/mcp/tools/attachments.js +117 -0
  126. package/dist/mcp/tools/attachments.js.map +1 -0
  127. package/dist/mcp/tools/cicd.js +105 -0
  128. package/dist/mcp/tools/cicd.js.map +1 -0
  129. package/dist/mcp/tools/discovery.js +34 -0
  130. package/dist/mcp/tools/discovery.js.map +1 -0
  131. package/dist/mcp/tools/issues.js +56 -0
  132. package/dist/mcp/tools/issues.js.map +1 -0
  133. package/dist/mcp/tools/merge_requests.js +67 -0
  134. package/dist/mcp/tools/merge_requests.js.map +1 -0
  135. package/dist/mcp/tools/metadata.js +127 -0
  136. package/dist/mcp/tools/metadata.js.map +1 -0
  137. package/dist/mcp/tools/peer_sync.js +43 -0
  138. package/dist/mcp/tools/peer_sync.js.map +1 -0
  139. package/dist/mcp/tools/repository.js +178 -0
  140. package/dist/mcp/tools/repository.js.map +1 -0
  141. package/dist/mcp/tools/work_tracking.js +125 -0
  142. package/dist/mcp/tools/work_tracking.js.map +1 -0
  143. package/dist/mcp/tools/workitems.js +30 -0
  144. package/dist/mcp/tools/workitems.js.map +1 -0
  145. package/dist/mcp/volume-files.js +187 -0
  146. package/dist/mcp/volume-files.js.map +1 -0
  147. package/dist/mcp-auth-store.js +134 -0
  148. package/dist/mcp-auth-store.js.map +1 -0
  149. package/dist/mcp-config-store.js +83 -0
  150. package/dist/mcp-config-store.js.map +1 -0
  151. package/dist/mention.js +512 -0
  152. package/dist/mention.js.map +1 -0
  153. package/dist/migrate.js +438 -0
  154. package/dist/migrate.js.map +1 -0
  155. package/dist/mr-assignee.js +71 -0
  156. package/dist/mr-assignee.js.map +1 -0
  157. package/dist/mr-content.js +90 -0
  158. package/dist/mr-content.js.map +1 -0
  159. package/dist/oauth-routes.js +54 -0
  160. package/dist/oauth-routes.js.map +1 -0
  161. package/dist/onboarding-allowlist.js +32 -0
  162. package/dist/onboarding-allowlist.js.map +1 -0
  163. package/dist/opencode.js +291 -0
  164. package/dist/opencode.js.map +1 -0
  165. package/dist/outbound-webhook-store.js +229 -0
  166. package/dist/outbound-webhook-store.js.map +1 -0
  167. package/dist/outbound-webhook.js +314 -0
  168. package/dist/outbound-webhook.js.map +1 -0
  169. package/dist/path-sandbox.js +200 -0
  170. package/dist/path-sandbox.js.map +1 -0
  171. package/dist/platform/git-auth.js +34 -0
  172. package/dist/platform/git-auth.js.map +1 -0
  173. package/dist/platform/gitealike/attachments.js +62 -0
  174. package/dist/platform/gitealike/attachments.js.map +1 -0
  175. package/dist/platform/gitealike/base.js +935 -0
  176. package/dist/platform/gitealike/base.js.map +1 -0
  177. package/dist/platform/gitealike/forgejo.js +16 -0
  178. package/dist/platform/gitealike/forgejo.js.map +1 -0
  179. package/dist/platform/gitealike/gitea.js +16 -0
  180. package/dist/platform/gitealike/gitea.js.map +1 -0
  181. package/dist/platform/gitealike/http.js +152 -0
  182. package/dist/platform/gitealike/http.js.map +1 -0
  183. package/dist/platform/gitealike/schemas.js +284 -0
  184. package/dist/platform/gitealike/schemas.js.map +1 -0
  185. package/dist/platform/github/attachments.js +52 -0
  186. package/dist/platform/github/attachments.js.map +1 -0
  187. package/dist/platform/github/http.js +153 -0
  188. package/dist/platform/github/http.js.map +1 -0
  189. package/dist/platform/github/index.js +936 -0
  190. package/dist/platform/github/index.js.map +1 -0
  191. package/dist/platform/github/schemas.js +308 -0
  192. package/dist/platform/github/schemas.js.map +1 -0
  193. package/dist/platform/github/zip.js +85 -0
  194. package/dist/platform/github/zip.js.map +1 -0
  195. package/dist/platform/gitlab/admin.js +105 -0
  196. package/dist/platform/gitlab/admin.js.map +1 -0
  197. package/dist/platform/gitlab/api.js +229 -0
  198. package/dist/platform/gitlab/api.js.map +1 -0
  199. package/dist/platform/gitlab/attachments.js +79 -0
  200. package/dist/platform/gitlab/attachments.js.map +1 -0
  201. package/dist/platform/gitlab/http.js +165 -0
  202. package/dist/platform/gitlab/http.js.map +1 -0
  203. package/dist/platform/gitlab/index.js +630 -0
  204. package/dist/platform/gitlab/index.js.map +1 -0
  205. package/dist/platform/gitlab/oauth.js +58 -0
  206. package/dist/platform/gitlab/oauth.js.map +1 -0
  207. package/dist/platform/gitlab/read.js +182 -0
  208. package/dist/platform/gitlab/read.js.map +1 -0
  209. package/dist/platform/gitlab/schemas-read.js +274 -0
  210. package/dist/platform/gitlab/schemas-read.js.map +1 -0
  211. package/dist/platform/gitlab/schemas.js +251 -0
  212. package/dist/platform/gitlab/schemas.js.map +1 -0
  213. package/dist/platform/gitlab/signature.js +52 -0
  214. package/dist/platform/gitlab/signature.js.map +1 -0
  215. package/dist/platform/index.js +38 -0
  216. package/dist/platform/index.js.map +1 -0
  217. package/dist/platform/port.js +26 -0
  218. package/dist/platform/port.js.map +1 -0
  219. package/dist/platform/types.js +80 -0
  220. package/dist/platform/types.js.map +1 -0
  221. package/dist/podman.js +119 -0
  222. package/dist/podman.js.map +1 -0
  223. package/dist/project-sync.js +69 -0
  224. package/dist/project-sync.js.map +1 -0
  225. package/dist/prompt.js +47 -0
  226. package/dist/prompt.js.map +1 -0
  227. package/dist/queue-store.js +236 -0
  228. package/dist/queue-store.js.map +1 -0
  229. package/dist/queue.js +129 -0
  230. package/dist/queue.js.map +1 -0
  231. package/dist/redact.js +23 -0
  232. package/dist/redact.js.map +1 -0
  233. package/dist/run-files.js +297 -0
  234. package/dist/run-files.js.map +1 -0
  235. package/dist/run-filters.js +54 -0
  236. package/dist/run-filters.js.map +1 -0
  237. package/dist/run-history-store.js +229 -0
  238. package/dist/run-history-store.js.map +1 -0
  239. package/dist/run-log-sink.js +270 -0
  240. package/dist/run-log-sink.js.map +1 -0
  241. package/dist/run-log.js +97 -0
  242. package/dist/run-log.js.map +1 -0
  243. package/dist/run-usage.js +29 -0
  244. package/dist/run-usage.js.map +1 -0
  245. package/dist/run-view.js +112 -0
  246. package/dist/run-view.js.map +1 -0
  247. package/dist/runner.js +1094 -0
  248. package/dist/runner.js.map +1 -0
  249. package/dist/runtime-apply.js +26 -0
  250. package/dist/runtime-apply.js.map +1 -0
  251. package/dist/runtime-settings.js +71 -0
  252. package/dist/runtime-settings.js.map +1 -0
  253. package/dist/runtime-state.js +19 -0
  254. package/dist/runtime-state.js.map +1 -0
  255. package/dist/server.js +119 -0
  256. package/dist/server.js.map +1 -0
  257. package/dist/settings-store.js +320 -0
  258. package/dist/settings-store.js.map +1 -0
  259. package/dist/status.js +121 -0
  260. package/dist/status.js.map +1 -0
  261. package/dist/stop.js +56 -0
  262. package/dist/stop.js.map +1 -0
  263. package/dist/sweeps.js +87 -0
  264. package/dist/sweeps.js.map +1 -0
  265. package/dist/task-log.js +279 -0
  266. package/dist/task-log.js.map +1 -0
  267. package/dist/task-view.js +62 -0
  268. package/dist/task-view.js.map +1 -0
  269. package/dist/token-store.js +68 -0
  270. package/dist/token-store.js.map +1 -0
  271. package/dist/types/access.js +74 -0
  272. package/dist/types/access.js.map +1 -0
  273. package/dist/types/custom-repos.js +28 -0
  274. package/dist/types/custom-repos.js.map +1 -0
  275. package/dist/types/env-config.js +25 -0
  276. package/dist/types/env-config.js.map +1 -0
  277. package/dist/types/env.js +190 -0
  278. package/dist/types/env.js.map +1 -0
  279. package/dist/types/global-settings.js +178 -0
  280. package/dist/types/global-settings.js.map +1 -0
  281. package/dist/types/lsp-servers.js +145 -0
  282. package/dist/types/lsp-servers.js.map +1 -0
  283. package/dist/types/mcp-config.js +77 -0
  284. package/dist/types/mcp-config.js.map +1 -0
  285. package/dist/types/opencode.js +59 -0
  286. package/dist/types/opencode.js.map +1 -0
  287. package/dist/types/outbound-webhook.js +56 -0
  288. package/dist/types/outbound-webhook.js.map +1 -0
  289. package/dist/types/project-settings.js +114 -0
  290. package/dist/types/project-settings.js.map +1 -0
  291. package/dist/types/provider-registry.js +37 -0
  292. package/dist/types/provider-registry.js.map +1 -0
  293. package/dist/types/runtime-settings.js +78 -0
  294. package/dist/types/runtime-settings.js.map +1 -0
  295. package/dist/usage-stats.js +159 -0
  296. package/dist/usage-stats.js.map +1 -0
  297. package/dist/version.js +19 -0
  298. package/dist/version.js.map +1 -0
  299. package/dist/volume-gc.js +193 -0
  300. package/dist/volume-gc.js.map +1 -0
  301. package/dist/volume-manage.js +191 -0
  302. package/dist/volume-manage.js.map +1 -0
  303. package/dist/volume-store.js +122 -0
  304. package/dist/volume-store.js.map +1 -0
  305. package/dist/webhook.js +1106 -0
  306. package/dist/webhook.js.map +1 -0
  307. package/dist/work-item-auto-store.js +75 -0
  308. package/dist/work-item-auto-store.js.map +1 -0
  309. package/dist/work-item-branch-store.js +37 -0
  310. package/dist/work-item-branch-store.js.map +1 -0
  311. package/migrations/0001_initial.sql +59 -0
  312. package/migrations/0002_queue_status.sql +15 -0
  313. package/migrations/0003_work_item_base_branch.sql +14 -0
  314. package/migrations/0004_project_settings.sql +15 -0
  315. package/migrations/0005_global_settings.sql +34 -0
  316. package/migrations/0006_model_variants.sql +8 -0
  317. package/migrations/0007_container_error_logs.sql +21 -0
  318. package/migrations/0008_project_access_grants.sql +16 -0
  319. package/migrations/0009_drop_imported_legacy.sql +4 -0
  320. package/migrations/0010_container_error_log_model.sql +6 -0
  321. package/migrations/0011_container_error_log_title.sql +5 -0
  322. package/migrations/0012_pending_task_cancel.sql +6 -0
  323. package/migrations/0013_builder_image.sql +6 -0
  324. package/migrations/0014_build_workflow.sql +7 -0
  325. package/migrations/0015_access_rules.sql +24 -0
  326. package/migrations/0016_trigger_policy.sql +17 -0
  327. package/migrations/0017_attachment_upload.sql +8 -0
  328. package/migrations/0018_work_item_branch.sql +11 -0
  329. package/migrations/0019_auto_push_mr.sql +18 -0
  330. package/migrations/0020_outbound_webhooks.sql +47 -0
  331. package/migrations/0021_runtime_settings.sql +12 -0
  332. package/migrations/0022_auto_resolve_conflicts.sql +17 -0
  333. package/migrations/0023_ci_fail_auto_report.sql +27 -0
  334. package/migrations/0024_work_item_auto_override.sql +22 -0
  335. package/migrations/0025_run_history.sql +37 -0
  336. package/migrations/0026_run_history_task_seq.sql +6 -0
  337. package/migrations/0027_custom_repos.sql +11 -0
  338. package/migrations/0028_run_usage.sql +14 -0
  339. package/migrations/0029_drop_ocr_langs.sql +6 -0
  340. package/migrations/0030_mr_assignee.sql +9 -0
  341. package/migrations/0031_lsp_servers.sql +14 -0
  342. package/opencode-config/managed/devbot-agent-policy.md +61 -0
  343. package/opencode-config/managed/opencode.json +77 -0
  344. package/opencode-config/opencode.json +211 -0
  345. package/opencode-config/plugins/devbot-path-guard.js +224 -0
  346. package/package.json +158 -4
  347. package/public/assets/DashboardSidebarCollapse-rIuzCmVm.js +1 -0
  348. package/public/assets/DashboardToolbar-DFCUqZ4Z.js +1 -0
  349. package/public/assets/ErrorLogModal.vue_vue_type_script_setup_true_lang-BCyNIf1E.js +1 -0
  350. package/public/assets/ErrorLogsPage-DyYK2Rop.js +1 -0
  351. package/public/assets/LogSlideover.vue_vue_type_script_setup_true_lang-33xie7TE.js +1 -0
  352. package/public/assets/OverviewPage-CFfa0uwg.js +1 -0
  353. package/public/assets/PageGrid-CBROIU87.js +1 -0
  354. package/public/assets/PeriodRangePicker.vue_vue_type_script_setup_true_lang-DiFUNem7.js +1 -0
  355. package/public/assets/ProjectDetailPage-CreyvUit.js +1 -0
  356. package/public/assets/ProjectsPage-CFx8-elJ.js +1 -0
  357. package/public/assets/RunDetailSlideover.vue_vue_type_script_setup_true_lang-DopYYmCT.js +1 -0
  358. package/public/assets/RunsPage-CRnnXU4P.js +1 -0
  359. package/public/assets/Select-Bvx32Diz.js +1 -0
  360. package/public/assets/SelectMenu-BjMxc4VB.js +1 -0
  361. package/public/assets/SettingsPage-Bb6LM3wO.js +60 -0
  362. package/public/assets/TimeCell.vue_vue_type_script_setup_true_lang-DW_UB0Fu.js +1 -0
  363. package/public/assets/UsagePage-BLMDEsv-.js +332 -0
  364. package/public/assets/UsagePage-DodEeAjB.css +1 -0
  365. package/public/assets/VolumesPage-CxcLc3L2.js +1 -0
  366. package/public/assets/WebhookConfigPanel.vue_vue_type_script_setup_true_lang-B2V2GF6b.js +1 -0
  367. package/public/assets/WorkItemCell.vue_vue_type_script_setup_true_lang-BQn6vTjd.js +1 -0
  368. package/public/assets/index-BMbMibyb.js +4 -0
  369. package/public/assets/index-C5RBBrPj.js +30 -0
  370. package/public/assets/index-CgX29UgC.css +1 -0
  371. package/public/assets/usage-format-jsb31_O8.js +1 -0
  372. package/public/assets/useManagedProjects-8rtjRqVJ.js +1 -0
  373. package/public/assets/useRouteTab-DfwrcMic.js +1 -0
  374. package/public/favicon.ico +0 -0
  375. package/public/favicon.png +0 -0
  376. package/public/index.html +15 -0
@@ -0,0 +1,190 @@
1
+ import { z } from "zod";
2
+ const booleanStr = z.coerce
3
+ .string()
4
+ .transform((v) => v === "true" || v === "1");
5
+ export const EnvSchema = z.object({
6
+ // Forge backend this process talks to. One instance ↔ one forge.
7
+ PLATFORM: z.enum(["gitlab", "forgejo", "gitea", "github"]).default("gitlab"),
8
+ PLATFORM_URL: z.string().url(),
9
+ PLATFORM_TOKEN: z.string().min(1),
10
+ // SSH port of the forge host, used only to build the same-host SSH→HTTPS
11
+ // submodule rewrite when SSH is not on 22 (e.g. 2222). PLATFORM_URL is HTTPS,
12
+ // so the SSH port cannot be inferred from it. Unset/empty = default port.
13
+ PLATFORM_SSH_PORT: z.preprocess((v) => (typeof v === "string" && v.trim() === "" ? undefined : v), z.coerce.number().int().positive().optional()),
14
+ PUBLIC_URL: z.string().url().refine((u) => u.startsWith("https:"), { message: "PUBLIC_URL must be https" }),
15
+ PLATFORM_OAUTH_CLIENT_ID: z.string().min(1),
16
+ PLATFORM_OAUTH_CLIENT_SECRET: z.string().min(1),
17
+ // Onboarding authorization gate for every platform. Comma-separated forge
18
+ // usernames allowed to complete WebUI onboarding; any other authenticated
19
+ // user is denied. This replaces the per-forge instance-admin check (which
20
+ // github.com cannot provide) so all drivers share one gate. FAILS CLOSED:
21
+ // when this is unset/empty, onboarding is denied for everyone.
22
+ ONBOARDING_USERS: z.string().default(""),
23
+ // GitHub API base. Defaults to the public github.com API; set only to point
24
+ // at a GitHub Enterprise Server (not officially supported yet) or a test
25
+ // double. Ignored on the other platforms.
26
+ GITHUB_API_URL: z.string().url().default("https://api.github.com"),
27
+ SESSION_KEY: z.string().min(32),
28
+ BOT_USERNAME: z.string().min(1),
29
+ BOT_USER_ID: z.coerce.number().int().positive(),
30
+ BOT_GIT_NAME: z.string().min(1).default("DevBot"),
31
+ BOT_GIT_EMAIL: z.string().email(),
32
+ // LLM providers, models, OpenCode plugins, base branches, and OCR languages live in the WebUI (global settings, devbot.db). Legacy LLM_*/OPENCODE_PLUGINS/BASE_BRANCHES/ATTACHMENT_OCR_LANG env vars are ignored.
33
+ BUILDER_IMAGE: z.string().min(1).default("devbot-builder:latest"),
34
+ PLAN_TIMEOUT_MS: z.coerce.number().int().positive().default(600_000),
35
+ BUILD_TIMEOUT_MS: z.coerce.number().int().positive().default(1_800_000),
36
+ // Kill an agent run that produces no stdout/stderr for this long. A wedged
37
+ // opencode process — or a model looping on a guard-blocked tool call until the
38
+ // total PLAN_/BUILD_TIMEOUT_MS — otherwise just sits "running". Silence is a
39
+ // heuristic: a legitimately quiet long-running bash tool also counts as
40
+ // silence, so keep this comfortably above the longest expected silent command.
41
+ // 0 disables the stall detector (the total timeout still applies). Work item #96.
42
+ RUN_STALL_TIMEOUT_MS: z.coerce.number().int().min(0).default(900_000),
43
+ MAX_QUEUE_PER_WORK_ITEM: z.coerce.number().int().positive().default(3),
44
+ // Max podman builder containers running simultaneously across all work
45
+ // items. Different work items run in parallel up to this limit; beyond it
46
+ // tasks wait in a global FIFO and the thread is notified at milestones
47
+ // (queued / you're next / starting).
48
+ MAX_CONCURRENT_RUNS: z.coerce.number().int().positive().default(4),
49
+ // Max pending tasks in the global FIFO (across all work items) before
50
+ // overflow is dropped with a ⚠️ note. 0 = unbounded (legacy behavior);
51
+ // a positive cap prevents a webhook flood from exhausting memory/disk.
52
+ MAX_GLOBAL_QUEUE: z.coerce.number().int().min(0).default(50),
53
+ // Worker poll cadence (ms) for the DB-backed queue. The sync DatabaseSync
54
+ // driver blocks per query, so this avoids a tight loop starving the event
55
+ // loop. 250ms is responsive enough for human-scale triggers.
56
+ QUEUE_POLL_INTERVAL_MS: z.coerce.number().int().positive().default(250),
57
+ // App-level retry on transient run failures (podman spawn, git network blip).
58
+ // 0 = disabled (posts one error note, matches pre-retry behavior). On a
59
+ // transient failure the same row is requeued with attempts++ (preserving its
60
+ // seq so global FIFO order is unchanged). Linear backoff: RETRY_BACKOFF_MS * attempts.
61
+ MAX_RETRIES: z.coerce.number().int().min(0).default(2),
62
+ RETRY_BACKOFF_MS: z.coerce.number().int().positive().default(5000),
63
+ // ponytail: env booleans must be string-parsed, not Boolean()-coerced;
64
+ // "0" is truthy under coerce.boolean and silently enables features.
65
+ QUEUE_FEEDBACK: booleanStr.default(true),
66
+ // Number of trusted reverse proxy hops in front of the bot. Set to 1 (or
67
+ // more) when behind nginx/Traefik/etc. so Express honors X-Forwarded-* and
68
+ // secure cookies work over TLS-terminated connections. 0 = off.
69
+ TRUST_PROXY: z.coerce.number().int().min(0).default(0),
70
+ PORT: z.coerce.number().int().positive().default(3000),
71
+ // Internal MCP server port. Bind address is MCP_HOST (default 0.0.0.0); the
72
+ // container reaches it via MCP_BASE_URL (host.containers.internal).
73
+ MCP_PORT: z.coerce.number().int().positive().default(3001),
74
+ // Bind address for the internal MCP server. Default 0.0.0.0 is required for
75
+ // rootless podman: the run container's host-gateway can reach neither host
76
+ // loopback (127.0.0.1) nor a host LAN IP — only an all-interfaces bind works.
77
+ // Set 127.0.0.1 for non-rootless deploys (e.g. bot in a container with
78
+ // --network host). Bearer auth (mcp_thread_tokens) gates every /mcp request
79
+ // regardless of bind.
80
+ MCP_HOST: z.string().default("0.0.0.0"),
81
+ // URL the container uses to reach the internal MCP server. Defaults to
82
+ // http://host.containers.internal:<MCP_PORT> (podman's host alias via
83
+ // --add-host). Override for --network host deploys (e.g. http://localhost:3001)
84
+ // or custom networks where the alias doesn't resolve.
85
+ MCP_BASE_URL: z.string().url().optional(),
86
+ DRY_RUN: booleanStr.default(false),
87
+ LOG_LEVEL: z.enum(["debug", "info", "warn", "error"]).default("info"),
88
+ // Instance identifier for HA deploys — prefixes volume names + container
89
+ // names so multiple devbot instances on the same host don't collide.
90
+ // Empty (default) = single-instance, no prefix. Must be [a-zA-Z0-9-]+.
91
+ INSTANCE_ID: z.string().regex(/^[a-zA-Z0-9-]*$/).default(""),
92
+ // ---- Attachments -----------------------------------------------------------
93
+ // DevBot does not read or OCR attachment content host-side. Work-item
94
+ // attachments are listed in the prompt as Markdown links; the agent downloads
95
+ // whole files on demand (the download_work_item_attachment MCP tool) and
96
+ // handles them itself — OCR/PDF extraction runs inside the builder image
97
+ // (tesseract/poppler), not here.
98
+ // Skip files larger than this many bytes (the download is aborted at the
99
+ // limit). Applies to both agent downloads and outbound uploads. 10 MB default
100
+ // balances "most screenshots fit" against "don't stream a 200 MB PDF just to
101
+ // reject it".
102
+ ATTACHMENT_MAX_BYTES: z.coerce.number().int().positive().default(10_000_000),
103
+ // Auto-purge per-work-item volumes inactive for VOLUME_GC_TTL_MS. A volume is
104
+ // eligible when now - last_run_at >= TTL. On purge, a note is posted to the
105
+ // work item (top-level); volumes created before the tracking table existed
106
+ // (orphan rows with no project/iid) are removed silently. The sweep runs on
107
+ // startup and every VOLUME_GC_INTERVAL_MS. Set VOLUME_GC_ENABLED=false to
108
+ // disable both the startup and periodic sweeps.
109
+ VOLUME_GC_TTL_MS: z.coerce.number().int().positive().default(7 * 24 * 60 * 60_000), // 1 week
110
+ VOLUME_GC_INTERVAL_MS: z.coerce.number().int().positive().default(24 * 60 * 60_000), // daily sweep
111
+ VOLUME_GC_ENABLED: booleanStr.default(true),
112
+ // Retention for persisted container/run error logs (container_error_logs).
113
+ // Rows older than this many days are purged at startup and by a daily sweep.
114
+ // Default 30 days; set 0 to disable purging (keep forever).
115
+ ERROR_LOG_RETENTION_DAYS: z.coerce.number().int().min(0).default(30),
116
+ // Periodic reconciliation of enrolled project paths from the live forge. A
117
+ // forge-side rename/transfer is not delivered as a project-level webhook on
118
+ // GitLab/Gitea/ForgeJo (and GitHub's `repository.renamed` is GitHub-only), so
119
+ // the stored path is refreshed from the forge instead. Runs once at startup
120
+ // and every PROJECT_SYNC_INTERVAL_MS. Set PROJECT_SYNC_ENABLED=false to
121
+ // disable both; the WebUI's GET /api/managed still refreshes on load.
122
+ PROJECT_SYNC_ENABLED: booleanStr.default(true),
123
+ PROJECT_SYNC_INTERVAL_MS: z.coerce.number().int().positive().default(24 * 60 * 60_000), // daily
124
+ // ---- MCP OAuth token refresh ----------------------------------------------
125
+ // Host-side refresh of remote MCP server OAuth tokens. opencode refreshes
126
+ // tokens inside the run container, but its rotated tokens are discarded (the
127
+ // runner overwrites mcp-auth.json from the DB each run); refreshing here and
128
+ // persisting the rotation fixes that. When enabled, a sweep runs on startup
129
+ // (only if enabled) and every MCP_REFRESH_INTERVAL_MS. Independently, tokens
130
+ // expiring within a run's TTL are always refreshed before that run starts.
131
+ // Default OFF — opt-in, since it makes DevBot issue outbound token requests.
132
+ MCP_REFRESH_ENABLED: booleanStr.default(false),
133
+ // Sweep cadence. Clamped to at most 8h so a mis-set value cannot let a token
134
+ // expire between two checks. Default 8h; a shorter value checks more often but
135
+ // only actually refreshes entries that are due.
136
+ MCP_REFRESH_INTERVAL_MS: z.coerce.number().int().positive().default(8 * 60 * 60_000),
137
+ // ---- Nested rootless Podman dev containers (work item #17) -----------------
138
+ // When true, build-mode runs launch the per-work-item builder container with
139
+ // the extra userns/capability flags needed for a nested rootless Podman, and
140
+ // mount a private per-work-item podman store volume. Each work item gets an
141
+ // isolated runtime (own images/networks/containers); no host podman socket is
142
+ // mounted. Plan mode and disabled projects keep today's unprivileged launch.
143
+ // Default false because enabling it broadens the builder container's
144
+ // privileges (nested namespaces + mount + mknod) versus the default.
145
+ DEVCONTAINER_ENABLED: booleanStr.default(false),
146
+ // Inner runtime storage driver. "auto" probes for /dev/fuse at startup:
147
+ // fuse-overlayfs when present (layered, disk-efficient; needs --device
148
+ // /dev/fuse), else vfs (portable but full-copy, disk-heavy). Pin explicitly
149
+ // to force one.
150
+ DEVCONTAINER_STORAGE_DRIVER: z.enum(["auto", "fuse-overlayfs", "vfs"]).default("auto"),
151
+ // ---- Outbound webhooks (work item #50) ------------------------------------
152
+ // DevBot POSTs signed JSON events to admin-configured URLs when a run reaches
153
+ // a terminal state or a change request is created/updated. Deliveries are
154
+ // persisted and retried; they never block or alter a run.
155
+ //
156
+ // SSRF posture: block loopback/link-local/private/CGNAT/ULA targets by
157
+ // default. Set true to allow internal endpoints (CI, messaging) — the admin
158
+ // configuring them is already trusted via ONBOARDING_USERS.
159
+ WEBHOOK_ALLOW_PRIVATE_HOSTS: booleanStr.default(false),
160
+ // Per-attempt HTTP timeout for an outbound delivery (ms).
161
+ WEBHOOK_DELIVERY_TIMEOUT_MS: z.coerce.number().int().positive().default(10_000),
162
+ // Total attempts per delivery before it is marked terminally failed.
163
+ WEBHOOK_RETRY_MAX: z.coerce.number().int().positive().default(5),
164
+ // Linear retry backoff base: next_attempt_at = now + base * attempts.
165
+ WEBHOOK_RETRY_BACKOFF_MS: z.coerce.number().int().positive().default(5_000),
166
+ // Worker poll cadence (ms) for claiming due deliveries.
167
+ WEBHOOK_POLL_INTERVAL_MS: z.coerce.number().int().positive().default(1_000),
168
+ // Retention for delivery rows. 0 = keep forever.
169
+ WEBHOOK_RETENTION_DAYS: z.coerce.number().int().min(0).default(30),
170
+ // ---- Git submodules (work item #21) ---------------------------------------
171
+ // When true, first-run clone and every subsequent fetch also initialize and
172
+ // update submodules (`git submodule update --init --recursive`). Best-effort:
173
+ // a submodule that can't be fetched does not abort the run — the affected
174
+ // paths are reported in an informational note and the run proceeds. The bot
175
+ // token is scoped to the forge host only, so external submodule hosts are
176
+ // fetched anonymously. Default true.
177
+ GIT_SUBMODULES_ENABLED: booleanStr.default(true),
178
+ // ---- Run history log files (work item #61) --------------------------------
179
+ // Per-run container output is captured to one file per run (run_history stores
180
+ // only the filename). Files older than this are purged at startup and hourly;
181
+ // the history row survives and the detail view reports "logs expired". 0 =
182
+ // keep forever. This governs the log FILES only — ERROR_LOG_RETENTION_DAYS
183
+ // still governs error-log rows.
184
+ RUN_LOG_TTL_HOURS: z.coerce.number().int().min(0).default(48),
185
+ // Directory for the per-run log files, relative to the process cwd unless
186
+ // absolute. ENV-only: it is a filesystem location, not a runtime knob, so it
187
+ // has no WebUI override (mirrors DRY_RUN / LOG_LEVEL). Default "run-logs".
188
+ RUN_LOG_DIR: z.string().default("run-logs"),
189
+ });
190
+ //# sourceMappingURL=env.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"env.js","sourceRoot":"","sources":["../../src/types/env.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,178 @@
1
+ import { z } from "zod";
2
+ import { findUnknownPlaceholders, WORKFLOW_PLACEHOLDERS, MR_DESCRIPTION_PLACEHOLDERS, } from "../build-workflow.js";
3
+ import { globalMinRoleField, globalRequireAuthorOrAssigneeField } from "./access.js";
4
+ import { RuntimeSettingsSchema, DEFAULT_RUNTIME_SETTINGS } from "./runtime-settings.js";
5
+ import { DEFAULT_LSP_SERVERS, isLspServerId, normalizeLspServers } from "../lsp-servers.js";
6
+ import { ASSIGNEE_RE } from "../assignee-value.js";
7
+ // Build-output automation switches. Both default OFF: a build run only publishes
8
+ // its branch / opens a merge request when explicitly enabled (or when the user
9
+ // asks per-run with /push and /mr). autoMr is meaningful only when autoPush is
10
+ // on — a merge request needs a published branch.
11
+ const autoPushField = z.boolean().default(false);
12
+ const autoMrField = z.boolean().default(false);
13
+ // Detect latent merge conflicts before creating/updating an MR and, when on,
14
+ // delegate resolution to a direct build run. Off by default.
15
+ const autoResolveConflictsField = z.boolean().default(false);
16
+ // CI-failure auto-report switch. Defaults OFF: when on, a failed pipeline on a
17
+ // merge/pull request DevBot created triggers an automatic plan run seeded with
18
+ // the failing job logs. Opt-in, like the build-output switches above.
19
+ const ciFailAutoReportField = z.boolean().default(false);
20
+ // Global LSP allowlist. Unknown ids are a validation error (not silently
21
+ // dropped); duplicates and ordering are normalized to the shipped order. An
22
+ // empty list is the off switch and emits `lsp:false` for the run.
23
+ const lspServersField = z
24
+ .array(z.string())
25
+ .refine((ids) => ids.every(isLspServerId), { message: "unknown LSP server id" })
26
+ .transform(normalizeLspServers)
27
+ .default(() => [...DEFAULT_LSP_SERVERS]);
28
+ // Global (bot-wide) settings and the provider registry. The DB replaced the
29
+ // LLM_*, OPENCODE_PLUGINS, BASE_BRANCHES and ATTACHMENT_OCR_LANG env vars,
30
+ // which are now ignored.
31
+ // Global MCP servers/auth entries reuse the per-project tables with this
32
+ // sentinel project_id. Real forge project ids are positive, so 0 is safe.
33
+ export const GLOBAL_SCOPE_ID = 0;
34
+ export const SETTINGS_STRING_MAX = 2048;
35
+ export const MODEL_STRING_MAX = 256;
36
+ export const VARIANT_STRING_MAX = 64;
37
+ // Per-model price for a custom provider (work item #66). USD per 1M tokens,
38
+ // matching models.dev and opencode's config `cost` block. Injected into the
39
+ // generated opencode.json so opencode computes step cost itself.
40
+ export const ModelCostSchema = z
41
+ .object({
42
+ input: z.number().min(0).default(0),
43
+ output: z.number().min(0).default(0),
44
+ cacheRead: z.number().min(0).default(0),
45
+ cacheWrite: z.number().min(0).default(0),
46
+ })
47
+ .strict();
48
+ const modelCostsField = z.record(z.string(), ModelCostSchema).default({});
49
+ export const PROVIDER_ID_RE = /^[a-z0-9][a-z0-9-_]*$/;
50
+ export const PROVIDER_ID_MAX = 64;
51
+ // Editable build-mode prompt templates. Empty string means "use the built-in
52
+ // default"; unknown `{{...}}` placeholders are a validation error.
53
+ export const TEMPLATE_STRING_MAX = 8192;
54
+ const workflowTemplateField = z
55
+ .string()
56
+ .max(TEMPLATE_STRING_MAX)
57
+ .transform((v) => v.trim())
58
+ .refine((v) => findUnknownPlaceholders(v, WORKFLOW_PLACEHOLDERS).length === 0, {
59
+ message: "unknown placeholder (allowed: {{iid}}, {{branch}}, {{mrTarget}}, {{mrBlock}})",
60
+ })
61
+ .default("");
62
+ const mrDescriptionTemplateField = z
63
+ .string()
64
+ .max(TEMPLATE_STRING_MAX)
65
+ .transform((v) => v.trim())
66
+ .refine((v) => findUnknownPlaceholders(v, MR_DESCRIPTION_PLACEHOLDERS).length === 0, {
67
+ message: "unknown placeholder (allowed: {{iid}}, {{branch}}, {{mrTarget}})",
68
+ })
69
+ .default("");
70
+ // opencode `--variant` values are single CLI tokens (e.g. "high", "xhigh",
71
+ // "max"). Restrict to a safe charset so a value can never break the arg list.
72
+ export const VARIANT_RE = /^[a-zA-Z0-9._-]*$/;
73
+ // Builder image reference (e.g. "devbot-builder:latest", "registry.example.com/
74
+ // team/builder:2.0"). Passed as a bare argument to `podman run`, so it must
75
+ // never start with "-" (option injection) or contain whitespace/quotes/shell
76
+ // metacharacters. Empty = unset (inherit the next level: project -> global ->
77
+ // BUILDER_IMAGE env).
78
+ export const BUILDER_IMAGE_MAX = 512;
79
+ export const BUILDER_IMAGE_RE = /^[a-zA-Z0-9][a-zA-Z0-9._/:@-]*$/;
80
+ const assigneeField = z
81
+ .string()
82
+ .max(255)
83
+ .transform((v) => v.trim())
84
+ .refine((v) => v === "" || ASSIGNEE_RE.test(v), { message: "must be a forge username or empty" })
85
+ .default("");
86
+ const builderImageField = z
87
+ .string()
88
+ .max(BUILDER_IMAGE_MAX)
89
+ .transform((v) => v.trim())
90
+ .refine((v) => v === "" || BUILDER_IMAGE_RE.test(v), {
91
+ message: "must be a valid image reference (letters, digits, dot, dash, underscore, slash, colon, at)",
92
+ })
93
+ .default("");
94
+ // Empty = unset, otherwise must be "provider/model".
95
+ const modelField = z
96
+ .string()
97
+ .max(MODEL_STRING_MAX)
98
+ .transform((v) => v.trim())
99
+ .refine((v) => v === "" || v.includes("/"), { message: "must be 'provider/model' or empty" });
100
+ // Empty = unset (opencode default), otherwise a safe variant token.
101
+ const variantField = z
102
+ .string()
103
+ .max(VARIANT_STRING_MAX)
104
+ .transform((v) => v.trim())
105
+ .refine((v) => VARIANT_RE.test(v), { message: "must be letters, digits, dot, dash or underscore" })
106
+ .default("");
107
+ export const GlobalSettingsSchema = z
108
+ .object({
109
+ planModel: modelField,
110
+ buildModel: modelField,
111
+ planVariant: variantField,
112
+ buildVariant: variantField,
113
+ plugins: z.string().max(SETTINGS_STRING_MAX).transform((v) => v.trim()),
114
+ baseBranches: z.string().max(SETTINGS_STRING_MAX).transform((v) => v.trim()),
115
+ builderImage: builderImageField,
116
+ assignee: assigneeField,
117
+ buildWorkflow: workflowTemplateField,
118
+ mrDescription: mrDescriptionTemplateField,
119
+ minRole: globalMinRoleField,
120
+ requireAuthorOrAssignee: globalRequireAuthorOrAssigneeField,
121
+ autoPush: autoPushField,
122
+ autoMr: autoMrField,
123
+ autoResolveConflicts: autoResolveConflictsField,
124
+ ciFailAutoReport: ciFailAutoReportField,
125
+ lspServers: lspServersField,
126
+ runtime: RuntimeSettingsSchema.default(DEFAULT_RUNTIME_SETTINGS),
127
+ })
128
+ .strict();
129
+ export const DEFAULT_GLOBAL_SETTINGS = {
130
+ planModel: "",
131
+ buildModel: "",
132
+ planVariant: "",
133
+ buildVariant: "",
134
+ plugins: "",
135
+ baseBranches: "dev,master",
136
+ builderImage: "",
137
+ assignee: "",
138
+ buildWorkflow: "",
139
+ mrDescription: "",
140
+ minRole: "write",
141
+ requireAuthorOrAssignee: true,
142
+ autoPush: false,
143
+ autoMr: false,
144
+ autoResolveConflicts: false,
145
+ ciFailAutoReport: false,
146
+ lspServers: [...DEFAULT_LSP_SERVERS],
147
+ runtime: { ...DEFAULT_RUNTIME_SETTINGS },
148
+ };
149
+ // Body for PUT /api/settings/providers/:id. An empty/absent apiKey on edit
150
+ // means "leave unchanged" (the store keeps the existing encrypted key). A new
151
+ // provider requires a non-empty key (enforced in the store).
152
+ export const ProviderBodySchema = z
153
+ .object({
154
+ name: z.string().min(1).max(100).transform((v) => v.trim()),
155
+ npm: z.string().min(1).max(200).transform((v) => v.trim()),
156
+ apiUrl: z.string().url().or(z.literal("")).optional(),
157
+ envVar: z.string().max(100).or(z.literal("")).optional(),
158
+ baseUrl: z.string().url().or(z.literal("")).optional(),
159
+ apiKey: z.string().max(4096).optional(),
160
+ models: z.array(z.string().min(1).max(200)).min(1).max(2000),
161
+ enabled: z.boolean(),
162
+ source: z.enum(["registry", "custom"]),
163
+ modelCosts: modelCostsField,
164
+ })
165
+ .strict();
166
+ // Validate a provider id (used by route path params and custom providers).
167
+ export function isValidProviderId(id) {
168
+ return PROVIDER_ID_RE.test(id) && id.length <= PROVIDER_ID_MAX;
169
+ }
170
+ // Normalize a models.dev model id to a bare id: some providers key models as
171
+ // "<providerId>/<model>" (e.g. "subconscious/glm-5.2") and others as a bare
172
+ // "claude-sonnet-4-6". opencode's `--model` is "<providerId>/<bareId>", so a
173
+ // duplicated prefix must be stripped.
174
+ export function normalizeModelId(providerId, modelId) {
175
+ const prefix = `${providerId}/`;
176
+ return modelId.startsWith(prefix) ? modelId.slice(prefix.length) : modelId;
177
+ }
178
+ //# sourceMappingURL=global-settings.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"global-settings.js","sourceRoot":"","sources":["../../src/types/global-settings.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,145 @@
1
+ // Metadata for the LSP servers DevBot can enable. The shipped opencode.json is
2
+ // the source of truth for which ids exist and how they are launched; this table
3
+ // supplies the UI labels, extension hints, and cost/requirements shown to
4
+ // operators. scripts/check-opencode-lsp.ts pins the two together.
5
+ export const LSP_SERVER_META = [
6
+ {
7
+ id: "typescript",
8
+ label: "TypeScript / JavaScript",
9
+ group: "JavaScript / TypeScript",
10
+ extensions: [".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs", ".mts", ".cts"],
11
+ ram: "150-350 MB",
12
+ toolchain: "Node + TypeScript in the builder image; workspace TypeScript is preferred when present",
13
+ degrades: "starts with the image's TypeScript when the repo has no local install",
14
+ },
15
+ {
16
+ id: "vue",
17
+ label: "Vue",
18
+ group: "JavaScript / TypeScript",
19
+ extensions: [".vue"],
20
+ ram: "200-400 MB",
21
+ toolchain: "vue-language-server in the builder image; project Vue dependencies improve resolution",
22
+ degrades: "starts for .vue files, but unresolved imports are likely without project dependencies",
23
+ },
24
+ {
25
+ id: "eslint",
26
+ label: "ESLint",
27
+ group: "JavaScript / TypeScript",
28
+ extensions: [".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs", ".mts", ".cts", ".vue"],
29
+ ram: "80-200 MB",
30
+ toolchain: "vscode-eslint-language-server in the builder image; a project-local eslint is required for rules",
31
+ degrades: "idles or exits when the repo has no project-local ESLint; the run continues",
32
+ },
33
+ {
34
+ id: "oxlint",
35
+ label: "Oxlint",
36
+ group: "JavaScript / TypeScript",
37
+ extensions: [".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs", ".mts", ".cts", ".vue", ".astro", ".svelte"],
38
+ ram: "30-80 MB",
39
+ toolchain: "oxlint in the builder image",
40
+ degrades: "starts for JS projects even without project lint dependencies",
41
+ },
42
+ {
43
+ id: "pyright",
44
+ label: "Python (Pyright)",
45
+ group: "Python",
46
+ extensions: [".py", ".pyi"],
47
+ ram: "150-300 MB",
48
+ toolchain: "pyright-langserver + system Python in the builder image",
49
+ degrades: "uses system Python; project virtualenvs are not auto-detected",
50
+ },
51
+ {
52
+ id: "rust",
53
+ label: "Rust",
54
+ group: "Rust",
55
+ extensions: [".rs"],
56
+ ram: "300-800 MB",
57
+ toolchain: "rustup stable toolchain + rust-analyzer; a Cargo workspace gives full analysis",
58
+ degrades: "starts for any .rs file; without Cargo.toml it falls back to loose-file mode with limited analysis and still costs RAM",
59
+ },
60
+ {
61
+ id: "kotlin-ls",
62
+ label: "Kotlin",
63
+ group: "Kotlin / JVM",
64
+ extensions: [".kt", ".kts"],
65
+ ram: "250-600 MB",
66
+ toolchain: "kotlin-language-server + headless JVM installed on both architectures",
67
+ degrades: "starts for Kotlin files; Gradle/Maven resolution depends on the project",
68
+ },
69
+ {
70
+ id: "terraform",
71
+ label: "Terraform",
72
+ group: "Infrastructure",
73
+ extensions: [".tf", ".tfvars"],
74
+ ram: "50-150 MB",
75
+ toolchain: "pinned terraform-ls release in the builder image",
76
+ degrades: "starts for .tf files without needing the Terraform CLI",
77
+ },
78
+ {
79
+ id: "dockerfile",
80
+ label: "Dockerfile",
81
+ group: "Infrastructure",
82
+ extensions: [".dockerfile", "Dockerfile"],
83
+ ram: "40-100 MB",
84
+ toolchain: "docker-langserver in the builder image",
85
+ degrades: "starts for Dockerfiles; no daemon is required",
86
+ },
87
+ {
88
+ id: "yaml-ls",
89
+ label: "YAML",
90
+ group: "Config / markup",
91
+ extensions: [".yaml", ".yml"],
92
+ ram: "40-80 MB",
93
+ toolchain: "yaml-language-server in the builder image",
94
+ degrades: "starts for YAML files without project dependencies",
95
+ },
96
+ {
97
+ id: "php intelephense",
98
+ label: "PHP",
99
+ group: "PHP",
100
+ extensions: [".php"],
101
+ ram: "100-250 MB",
102
+ toolchain: "intelephense + PHP in the builder image",
103
+ degrades: "starts for PHP files; Composer dependencies improve resolution",
104
+ },
105
+ {
106
+ id: "bash",
107
+ label: "Shell",
108
+ group: "Shell",
109
+ extensions: [".sh", ".bash", ".zsh", ".ksh"],
110
+ ram: "30-60 MB",
111
+ toolchain: "bash-language-server in the builder image",
112
+ degrades: "starts for shell files without project dependencies",
113
+ },
114
+ {
115
+ id: "json",
116
+ label: "JSON",
117
+ group: "Config / markup",
118
+ extensions: [".json", ".jsonc"],
119
+ ram: "40-80 MB",
120
+ toolchain: "vscode-json-language-server in the builder image",
121
+ degrades: "starts for JSON files without project dependencies",
122
+ },
123
+ {
124
+ id: "css",
125
+ label: "CSS",
126
+ group: "Config / markup",
127
+ extensions: [".css", ".scss", ".less"],
128
+ ram: "40-80 MB",
129
+ toolchain: "vscode-css-language-server in the builder image",
130
+ degrades: "starts for CSS-family files without project dependencies",
131
+ },
132
+ {
133
+ id: "html",
134
+ label: "HTML",
135
+ group: "Config / markup",
136
+ extensions: [".html", ".htm"],
137
+ ram: "40-80 MB",
138
+ toolchain: "vscode-html-language-server in the builder image",
139
+ degrades: "starts for HTML files without project dependencies",
140
+ },
141
+ ];
142
+ export function lspServerMeta(id) {
143
+ return LSP_SERVER_META.find((server) => server.id === id);
144
+ }
145
+ //# sourceMappingURL=lsp-servers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lsp-servers.js","sourceRoot":"","sources":["../../src/types/lsp-servers.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,77 @@
1
+ import { z } from "zod";
2
+ // One entry in the opencode.json `mcp` map. See
3
+ // https://opencode.ai/docs/mcp-servers/
4
+ // Values may carry `{env:VAR}` placeholders — preserved verbatim, resolved
5
+ // inside the container by opencode against the container env.
6
+ export const McpServerConfigSchema = z.discriminatedUnion("type", [
7
+ z
8
+ .object({
9
+ type: z.literal("local"),
10
+ command: z.array(z.string()).min(1),
11
+ enabled: z.boolean().optional(),
12
+ environment: z.record(z.string(), z.string()).optional(),
13
+ cwd: z.string().optional(),
14
+ timeout: z.number().int().positive().optional(),
15
+ })
16
+ .strict(),
17
+ z
18
+ .object({
19
+ type: z.literal("remote"),
20
+ url: z.string().url(),
21
+ enabled: z.boolean().optional(),
22
+ headers: z.record(z.string(), z.string()).optional(),
23
+ oauth: z
24
+ .union([
25
+ z
26
+ .object({
27
+ clientId: z.string(),
28
+ clientSecret: z.string(),
29
+ scope: z.string().optional(),
30
+ })
31
+ .strict(),
32
+ z.literal(false),
33
+ ])
34
+ .optional(),
35
+ timeout: z.number().int().positive().optional(),
36
+ })
37
+ .strict(),
38
+ ]);
39
+ // Name namespace for the mcp map. Reserved: devbot-forge (the bot's own
40
+ // server, injected by the runner — never user-configurable) and
41
+ // chrome-devtools (bundled chrome-devtools-mcp server, always active).
42
+ export const MCP_NAME_RE = /^[a-zA-Z0-9_-]+$/;
43
+ export const MCP_NAME_MAX = 50;
44
+ export const RESERVED_MCP_NAMES = ["devbot-forge", "chrome-devtools"];
45
+ // ---- MCP OAuth auth entry ---------------------------------------------------
46
+ // Shape of one server's entry in opencode's `mcp-auth.json`, authored at
47
+ // `$XDG_DATA_HOME/opencode/mcp-auth.json`. Source of truth:
48
+ // packages/opencode/src/mcp/auth.ts (Schema.Struct { tokens, clientInfo,
49
+ // codeVerifier, oauthState, serverUrl }).
50
+ // We accept a relaxed shape: only `tokens.accessToken` is required; the rest
51
+ // is optional per opencode's own decoder. Transient fields (codeVerifier,
52
+ // oauthState) are accepted so a raw paste of the file round-trips, but they
53
+ // are never useful post-auth and we drop them on write to keep the row tidy.
54
+ export const McpAuthTokensSchema = z
55
+ .object({
56
+ accessToken: z.string(),
57
+ refreshToken: z.string().optional(),
58
+ expiresAt: z.number().optional(), // SECONDS since epoch (opencode compares to Date.now()/1000)
59
+ scope: z.string().optional(),
60
+ })
61
+ .strict();
62
+ export const McpAuthClientInfoSchema = z
63
+ .object({
64
+ clientId: z.string(),
65
+ clientSecret: z.string().optional(),
66
+ clientIdIssuedAt: z.number().optional(),
67
+ clientSecretExpiresAt: z.number().optional(),
68
+ })
69
+ .strict();
70
+ export const McpAuthEntrySchema = z
71
+ .object({
72
+ tokens: McpAuthTokensSchema,
73
+ clientInfo: McpAuthClientInfoSchema.optional(),
74
+ serverUrl: z.string().optional(), // overwritten by the runner with the stored config's url
75
+ })
76
+ .strict();
77
+ //# sourceMappingURL=mcp-config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-config.js","sourceRoot":"","sources":["../../src/types/mcp-config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,gDAAgD;AAChD,0CAA0C;AAC1C,2EAA2E;AAC3E,8DAA8D;AAE9D,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,CAAC,kBAAkB,CAAC,MAAM,EAAE;IAChE,CAAC;SACE,MAAM,CAAC;QACN,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC;QACxB,OAAO,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;QACnC,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;QAC/B,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE;QACxD,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;QAC1B,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE;KAChD,CAAC;SACD,MAAM,EAAE;IACX,CAAC;SACE,MAAM,CAAC;QACN,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC;QACzB,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE;QACrB,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;QAC/B,OAAO,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE;QACpD,KAAK,EAAE,CAAC;aACL,KAAK,CAAC;YACL,CAAC;iBACE,MAAM,CAAC;gBACN,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE;gBACpB,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE;gBACxB,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;aAC7B,CAAC;iBACD,MAAM,EAAE;YACX,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC;SACjB,CAAC;aACD,QAAQ,EAAE;QACb,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE;KAChD,CAAC;SACD,MAAM,EAAE;CACZ,CAAC,CAAC;AAGH,wEAAwE;AACxE,gEAAgE;AAChE,uEAAuE;AACvE,MAAM,CAAC,MAAM,WAAW,GAAG,kBAAkB,CAAC;AAC9C,MAAM,CAAC,MAAM,YAAY,GAAG,EAAE,CAAC;AAC/B,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,cAAc,EAAE,iBAAiB,CAAU,CAAC;AAE/E,gFAAgF;AAChF,yEAAyE;AACzE,4DAA4D;AAC5D,2EAA2E;AAC3E,4CAA4C;AAC5C,6EAA6E;AAC7E,0EAA0E;AAC1E,4EAA4E;AAC5E,6EAA6E;AAC7E,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC;KACjC,MAAM,CAAC;IACN,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE;IACvB,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IACnC,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,EAAE,6DAA6D;IAC/F,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;CAC7B,CAAC;KACD,MAAM,EAAE,CAAC;AAEZ,MAAM,CAAC,MAAM,uBAAuB,GAAG,CAAC;KACrC,MAAM,CAAC;IACN,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE;IACpB,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IACnC,gBAAgB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IACvC,qBAAqB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;CAC7C,CAAC;KACD,MAAM,EAAE,CAAC;AAIZ,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC;KAChC,MAAM,CAAC;IACN,MAAM,EAAE,mBAAmB;IAC3B,UAAU,EAAE,uBAAuB,CAAC,QAAQ,EAAE;IAC9C,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,EAAE,yDAAyD;CAC5F,CAAC;KACD,MAAM,EAAE,CAAC"}