@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 @@
1
+ {"version":3,"file":"admin.js","sourceRoot":"","sources":["../../../src/platform/gitlab/admin.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,229 @@
1
+ import { NoteSchema, IssueNoteSchema, MergeRequestSchema, IssueDetailSchema, IssueListItemSchema, MergeRequestListItemSchema, ProjectMemberSchema, UserLookupSchema, DiscussionSchema, MergeRequestDiscussionSchema, } from "./schemas.js";
2
+ import { gitlabRequest, gitlabRequestArray, GITLAB_API } from "./http.js";
3
+ import { config } from "../../config.js";
4
+ import { log } from "../../logger.js";
5
+ const BOT = { kind: "bot" };
6
+ export function postNote(projectId, iid, body) {
7
+ // ponytail: GitLab routes issue-type work item notes through the Issues API
8
+ // (/projects/:id/issues/:iid/notes). The Work Items API notes endpoint
9
+ // (/projects/:id/work_items/:iid/notes) 404s on this instance even for
10
+ // issue-type work items (verified on GitLab 19.2). The webhook fires with
11
+ // noteable_type "Issue" and the issue's _links.notes points here, so this
12
+ // is the correct path for every work item this bot handles today. Switch
13
+ // to a type-dispatched call if/when this bot handles non-issue work item
14
+ // types (epic/objective/etc.) that genuinely need the Work Items API.
15
+ return gitlabRequest(`/projects/${projectId}/issues/${iid}/notes`, {
16
+ method: "POST",
17
+ body: JSON.stringify({ body }),
18
+ }, NoteSchema, BOT);
19
+ }
20
+ export async function listIssueNotes(projectId, iid) {
21
+ // ponytail: per_page=100 + no pagination loop. 100 is the API max; a work
22
+ // item crossing that is rare for this bot — walk X-Next-Page if one ever
23
+ // does. activity_filter=only_comments drops system notes (label/state/
24
+ // milestone changes) server-side, so no client-side system filter needed.
25
+ // sort=asc gives chronological order for the transcript.
26
+ return gitlabRequestArray(`/projects/${projectId}/issues/${iid}/notes?sort=asc&per_page=100&activity_filter=only_comments`, { method: "GET" }, IssueNoteSchema, BOT);
27
+ }
28
+ export function createMergeRequest(projectId, body) {
29
+ return gitlabRequest(`/projects/${projectId}/merge_requests`, {
30
+ method: "POST",
31
+ body: JSON.stringify(body),
32
+ }, MergeRequestSchema, BOT);
33
+ }
34
+ export function updateMergeRequest(projectId, mrIid, body) {
35
+ return gitlabRequest(`/projects/${projectId}/merge_requests/${mrIid}`, {
36
+ method: "PUT",
37
+ body: JSON.stringify(body),
38
+ }, MergeRequestSchema, BOT);
39
+ }
40
+ // GET /projects/:id/issues/:iid. Used by the /reset authorization check to
41
+ // read the issue's current author + assignees (live, at reset time).
42
+ export function fetchIssue(projectId, iid) {
43
+ return gitlabRequest(`/projects/${projectId}/issues/${iid}`, { method: "GET" }, IssueDetailSchema, BOT);
44
+ }
45
+ // GET /projects/:id/members/all/:user_id — inherited membership, resolves
46
+ // group-level roles. Like the throwing variant below but maps a 404 (not a
47
+ // member) to null so the caller can distinguish "no role" from a lookup
48
+ // failure. Non-404 errors throw (fail-closed). Raw fetch so a 404 does not
49
+ // throw. Used by the trigger-authorization gate.
50
+ export async function fetchProjectMemberOrNull(projectId, userId) {
51
+ const url = `${GITLAB_API}/projects/${projectId}/members/all/${userId}`;
52
+ const res = await fetch(url, { headers: { "PRIVATE-TOKEN": config.PLATFORM_TOKEN } });
53
+ if (res.status === 404)
54
+ return null;
55
+ if (!res.ok) {
56
+ const body = await res.text();
57
+ throw new Error(`GitLab ${res.status} ${url}: ${body}`);
58
+ }
59
+ const parsed = ProjectMemberSchema.safeParse(await res.json());
60
+ if (!parsed.success) {
61
+ log.error("gitlab response schema mismatch", { url, issues: parsed.error.issues });
62
+ throw new Error(`GitLab schema mismatch for ${url}`);
63
+ }
64
+ return parsed.data;
65
+ }
66
+ // GET /users?username=<login> — resolve a username to its stable numeric id.
67
+ // Exact match (case-insensitive) is required: GitLab's search is prefix-based,
68
+ // so "alice" also matches "alice-bot". Returns null on no exact match. This is
69
+ // the single forge-coupling point for access-rule add; when the Platform port
70
+ // lands (wi-19), this becomes a port method (GitLab/ForgeJo/Gitea/GitHub each
71
+ // implement resolveUser) and this function is replaced by that call.
72
+ export async function findUserByUsername(username) {
73
+ const target = username.trim().toLowerCase();
74
+ if (!target)
75
+ return null;
76
+ const users = await gitlabRequest(`/users?username=${encodeURIComponent(username.trim())}`, { method: "GET" }, UserLookupSchema.array(), BOT);
77
+ return users.find((u) => u.username.toLowerCase() === target) ?? null;
78
+ }
79
+ // Map a triggering note id → its discussion id, so a Step-0 error reply can be
80
+ // posted in the same thread as the mention. Walks
81
+ // GET /projects/:id/issues/:iid/discussions paginated (per_page=100), capped
82
+ // at ~10 pages. Returns the discussion id whose notes[].id === noteId, or
83
+ // null on miss/exhaustion/error. Errors are swallowed (null) — the caller
84
+ // falls back to a top-level note; never throws.
85
+ export async function findNoteDiscussionId(projectId, iid, noteId) {
86
+ const MAX_PAGES = 10;
87
+ try {
88
+ for (let page = 1; page <= MAX_PAGES; page++) {
89
+ const discussions = await gitlabRequestArray(`/projects/${projectId}/issues/${iid}/discussions?per_page=100&page=${page}`, { method: "GET" }, DiscussionSchema, BOT);
90
+ if (discussions.length === 0)
91
+ break;
92
+ const hit = discussions.find((d) => d.notes.some((n) => n.id === noteId));
93
+ if (hit)
94
+ return hit.id;
95
+ if (discussions.length < 100)
96
+ break;
97
+ }
98
+ }
99
+ catch (e) {
100
+ log.warn("findNoteDiscussionId failed", { projectId, iid, noteId, err: e });
101
+ }
102
+ return null;
103
+ }
104
+ // POST /projects/:id/issues/:iid/discussions/:discussion_id/notes — reply in
105
+ // the same thread as the triggering note.
106
+ export function postDiscussionReply(projectId, iid, discussionId, body) {
107
+ return gitlabRequest(`/projects/${projectId}/issues/${iid}/discussions/${discussionId}/notes`, { method: "POST", body: JSON.stringify({ body }) }, NoteSchema, BOT);
108
+ }
109
+ // Post a Step-0 error reply. If triggeringNoteId is set, resolve its discussion
110
+ // and reply in-thread; on miss/error fall back to a top-level note. If
111
+ // triggeringNoteId is undefined (e.g. work-item-creation mention), post
112
+ // top-level directly. Swallows + logs internal errors — never throws. A
113
+ // silent drop would be worse than a top-level fallback for an error message.
114
+ export async function postErrorReply(projectId, iid, triggeringNoteId, body) {
115
+ try {
116
+ if (triggeringNoteId !== undefined) {
117
+ const discussionId = await findNoteDiscussionId(projectId, iid, triggeringNoteId);
118
+ if (discussionId) {
119
+ await postDiscussionReply(projectId, iid, discussionId, body);
120
+ return;
121
+ }
122
+ }
123
+ await postNote(projectId, iid, body);
124
+ }
125
+ catch (e) {
126
+ log.warn("postErrorReply failed", { projectId, iid, triggeringNoteId, err: e });
127
+ }
128
+ }
129
+ // GET /projects/:id/repository/branches/:branch — verifies a /base <branch>
130
+ // exists on the remote before the first-run clone tries it. Returns true on
131
+ // 200, false on 404 (branch missing), rethrows on other statuses (fail-closed:
132
+ // a 5xx during the gate denies the mention rather than dispatching a run that
133
+ // would clone off the wrong base). Direct fetch (not gitlabVoid, which returns
134
+ // void) so the boolean result is preserved. Branch name is URL-encoded per
135
+ // GitLab's path-param rule (slashes in branch names like release/2.0 must be
136
+ // encoded so the path segment isn't split).
137
+ export async function branchExists(projectId, branch) {
138
+ const url = `${GITLAB_API}/projects/${projectId}/repository/branches/${encodeURIComponent(branch)}`;
139
+ const res = await fetch(url, { headers: { "PRIVATE-TOKEN": config.PLATFORM_TOKEN } });
140
+ if (res.status === 404)
141
+ return false;
142
+ if (!res.ok) {
143
+ const body = await res.text();
144
+ throw new Error(`GitLab ${res.status} ${url}: ${body}`);
145
+ }
146
+ return true;
147
+ }
148
+ // GET /projects/:id/issues/:iid — return just the work item's state, or null
149
+ // when the work item no longer exists (404 / deleted). Used by the volume GC
150
+ // liveness pass to reclaim volumes for closed or deleted work items instead
151
+ // of waiting out the inactivity TTL. A deleted work item can never run again,
152
+ // so its volume is freed immediately; closed items are freed to match the
153
+ // close-hook behavior. Non-404 errors throw (fail-closed: the sweep leaves
154
+ // the row for the TTL path rather than purging on an unverifiable read).
155
+ // Raw fetch (not gitlabRequest) so a 404 maps to null instead of a throw.
156
+ export async function fetchIssueStateOrNull(projectId, iid) {
157
+ const url = `${GITLAB_API}/projects/${projectId}/issues/${iid}`;
158
+ const res = await fetch(url, { headers: { "PRIVATE-TOKEN": config.PLATFORM_TOKEN } });
159
+ if (res.status === 404)
160
+ return null;
161
+ if (!res.ok) {
162
+ const body = await res.text();
163
+ throw new Error(`GitLab ${res.status} ${url}: ${body}`);
164
+ }
165
+ const json = (await res.json());
166
+ return json.state === "opened" || json.state === "closed" ? json.state : null;
167
+ }
168
+ // Walk a list of branch names in order; return the first that exists remotely,
169
+ // or null if none do. Used to resolve the BASE_BRANCHES env fallback (and is
170
+ // the engine behind both the clone slot-2 target and the build-mode mrTarget
171
+ // when no /base was set for the work item). 5xx on any branch rethrows
172
+ // (fail-closed, consistent with the /base Step-0 gate) — the caller treats a
173
+ // throw as "none verifiable" and posts a retry note rather than silently
174
+ // skipping an unverifiable branch. 404 on a branch is the normal "try next"
175
+ // signal, not an error.
176
+ export async function firstExistingBranch(projectId, branches) {
177
+ for (const b of branches) {
178
+ if (await branchExists(projectId, b))
179
+ return b;
180
+ }
181
+ return null;
182
+ }
183
+ // ponytail: per_page=100 + no pagination walk. A project crossing 100 open
184
+ // issues is rare for this bot's scope; walk X-Next-Page if one ever does.
185
+ export async function listIssues(projectId, opts = {}) {
186
+ const params = new URLSearchParams();
187
+ params.set("scope", "all");
188
+ if (opts.state)
189
+ params.set("state", opts.state);
190
+ if (opts.search)
191
+ params.set("search", opts.search);
192
+ if (opts.labels)
193
+ params.set("labels", opts.labels);
194
+ params.set("per_page", String(opts.perPage ?? 100));
195
+ if (opts.page)
196
+ params.set("page", String(opts.page));
197
+ return gitlabRequest(`/projects/${projectId}/issues?${params.toString()}`, { method: "GET" }, IssueListItemSchema.array(), BOT);
198
+ }
199
+ export function getIssueFull(projectId, iid) {
200
+ return gitlabRequest(`/projects/${projectId}/issues/${iid}`, { method: "GET" }, IssueListItemSchema, BOT);
201
+ }
202
+ export async function listMergeRequests(projectId, opts = {}) {
203
+ const params = new URLSearchParams();
204
+ if (opts.state)
205
+ params.set("state", opts.state);
206
+ if (opts.search)
207
+ params.set("search", opts.search);
208
+ if (opts.sourceBranch)
209
+ params.set("source_branch", opts.sourceBranch);
210
+ params.set("per_page", String(opts.perPage ?? 100));
211
+ if (opts.page)
212
+ params.set("page", String(opts.page));
213
+ return gitlabRequest(`/projects/${projectId}/merge_requests?${params.toString()}`, { method: "GET" }, MergeRequestListItemSchema.array(), BOT);
214
+ }
215
+ // GET /projects/:id/merge_requests/:iid/discussions — MR discussions include
216
+ // diff-anchored annotations (DiffNote with position), general threads, and
217
+ // system notes. Used by the get_merge_request_discussions MCP tool so an agent
218
+ // reviewing an MR can pull review comments as context.
219
+ // ponytail: per_page=100 + no pagination walk. 100 is the API max; an MR
220
+ // crossing that is rare — walk X-Next-Page if one ever does (page param lets
221
+ // the agent page further explicitly).
222
+ export async function listMergeRequestDiscussions(projectId, mrIid, opts = {}) {
223
+ const params = new URLSearchParams();
224
+ params.set("per_page", String(opts.perPage ?? 100));
225
+ if (opts.page)
226
+ params.set("page", String(opts.page));
227
+ return gitlabRequestArray(`/projects/${projectId}/merge_requests/${mrIid}/discussions?${params.toString()}`, { method: "GET" }, MergeRequestDiscussionSchema, BOT);
228
+ }
229
+ //# sourceMappingURL=api.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api.js","sourceRoot":"","sources":["../../../src/platform/gitlab/api.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,79 @@
1
+ // GitLab attachment discovery + fetch. GitLab embeds uploads as Markdown
2
+ // `![alt](/uploads/<secret>/<filename>)` (relative, project upload) or
3
+ // `[text](<host>/uploads/...)` (absolute). Bare `/uploads/...` URLs outside
4
+ // markdown also appear (older clients). The secret is a 32-char hex string per
5
+ // GitLab's Markdown uploads API. Discovery is GitLab-specific; the extraction
6
+ // engine lives in ../../attachments.ts.
7
+ import { runtime } from "../../runtime-state.js";
8
+ import { gitlabFetchRaw, gitlabUpload } from "./http.js";
9
+ import { UploadSchema } from "./schemas.js";
10
+ import { MD_LINK, safeDecode, stripCodeSpans, } from "../../attachments.js";
11
+ const UPLOAD_PATH = /\/uploads\/([0-9a-f]{32})\/([^)\s]+)/i;
12
+ export function findAttachmentRefs(body) {
13
+ // Strip code spans so upload refs inside them aren't matched.
14
+ const stripped = stripCodeSpans(body);
15
+ const refs = [];
16
+ const seen = new Set();
17
+ // Markdown image/link form first: ![alt](url) and [text](url).
18
+ for (const m of stripped.matchAll(MD_LINK)) {
19
+ const url = m[2] ?? "";
20
+ const hit = UPLOAD_PATH.exec(url);
21
+ if (!hit)
22
+ continue;
23
+ const secret = hit[1] ?? "";
24
+ const filename = safeDecode(hit[2] ?? "");
25
+ if (!secret)
26
+ continue;
27
+ const key = `${secret}/${filename}`;
28
+ if (seen.has(key))
29
+ continue;
30
+ seen.add(key);
31
+ refs.push({
32
+ raw: m[0] ?? "",
33
+ secret,
34
+ filename,
35
+ absolute: /^https?:\/\//i.test(url),
36
+ });
37
+ }
38
+ // Bare `/uploads/...` URLs not wrapped in markdown (older clients). Avoid
39
+ // double-counting ones already captured by a markdown link above.
40
+ for (const m of stripped.matchAll(new RegExp(UPLOAD_PATH.source, "g"))) {
41
+ const secret = m[1] ?? "";
42
+ const filename = safeDecode(m[2] ?? "");
43
+ if (!secret)
44
+ continue;
45
+ const key = `${secret}/${filename}`;
46
+ if (seen.has(key))
47
+ continue;
48
+ seen.add(key);
49
+ refs.push({
50
+ raw: m[0] ?? "",
51
+ secret,
52
+ filename,
53
+ absolute: false,
54
+ });
55
+ }
56
+ return refs;
57
+ }
58
+ /** Fetch one GitLab upload's full bytes. */
59
+ export async function downloadAttachment(projectId, ref) {
60
+ // GitLab's download-by-secret endpoint: GET /projects/:id/uploads/:secret/:filename.
61
+ // Works for both relative (project) and absolute (host-prefixed) refs — the
62
+ // endpoint path is the same; the host is in config.PLATFORM_URL.
63
+ const path = `/projects/${projectId}/uploads/${ref.secret}/${encodeURIComponent(ref.filename)}`;
64
+ const { bytes, contentType } = await gitlabFetchRaw(path, { kind: "bot" }, runtime().attachmentMaxBytes);
65
+ return { bytes, contentType };
66
+ }
67
+ // Outbound upload via the Markdown uploads API. GitLab accepts multipart field
68
+ // `file` at POST /projects/:id/uploads and returns the server-rendered markdown.
69
+ export async function uploadAttachment(projectId, file) {
70
+ const form = new FormData();
71
+ form.append("file", new Blob([file.bytes], { type: file.contentType }), file.filename);
72
+ const r = await gitlabUpload(`/projects/${projectId}/uploads`, form, UploadSchema, { kind: "bot" });
73
+ return {
74
+ markdown: r.markdown,
75
+ url: r.full_path ?? r.url,
76
+ filename: file.filename,
77
+ };
78
+ }
79
+ //# sourceMappingURL=attachments.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"attachments.js","sourceRoot":"","sources":["../../../src/platform/gitlab/attachments.ts"],"names":[],"mappings":"AAAA,yEAAyE;AACzE,uEAAuE;AACvE,4EAA4E;AAC5E,+EAA+E;AAC/E,8EAA8E;AAC9E,wCAAwC;AAExC,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACzD,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EACL,OAAO,EACP,UAAU,EACV,cAAc,GAEf,MAAM,sBAAsB,CAAC;AAG9B,MAAM,WAAW,GAAG,uCAAuC,CAAC;AAE5D,MAAM,UAAU,kBAAkB,CAAC,IAAY;IAC7C,8DAA8D;IAC9D,MAAM,QAAQ,GAAG,cAAc,CAAC,IAAI,CAAC,CAAC;IACtC,MAAM,IAAI,GAAoB,EAAE,CAAC;IACjC,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,+DAA+D;IAC/D,KAAK,MAAM,CAAC,IAAI,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;QAC3C,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QACvB,MAAM,GAAG,GAAG,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAClC,IAAI,CAAC,GAAG;YAAE,SAAS;QACnB,MAAM,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAC5B,MAAM,QAAQ,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;QAC1C,IAAI,CAAC,MAAM;YAAE,SAAS;QACtB,MAAM,GAAG,GAAG,GAAG,MAAM,IAAI,QAAQ,EAAE,CAAC;QACpC,IAAI,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC;YAAE,SAAS;QAC5B,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACd,IAAI,CAAC,IAAI,CAAC;YACR,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE;YACf,MAAM;YACN,QAAQ;YACR,QAAQ,EAAE,eAAe,CAAC,IAAI,CAAC,GAAG,CAAC;SACpC,CAAC,CAAC;IACL,CAAC;IACD,0EAA0E;IAC1E,kEAAkE;IAClE,KAAK,MAAM,CAAC,IAAI,QAAQ,CAAC,QAAQ,CAAC,IAAI,MAAM,CAAC,WAAW,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,EAAE,CAAC;QACvE,MAAM,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAC1B,MAAM,QAAQ,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;QACxC,IAAI,CAAC,MAAM;YAAE,SAAS;QACtB,MAAM,GAAG,GAAG,GAAG,MAAM,IAAI,QAAQ,EAAE,CAAC;QACpC,IAAI,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC;YAAE,SAAS;QAC5B,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACd,IAAI,CAAC,IAAI,CAAC;YACR,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE;YACf,MAAM;YACN,QAAQ;YACR,QAAQ,EAAE,KAAK;SAChB,CAAC,CAAC;IACL,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,4CAA4C;AAC5C,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,SAAiB,EACjB,GAAkB;IAElB,qFAAqF;IACrF,4EAA4E;IAC5E,iEAAiE;IACjE,MAAM,IAAI,GAAG,aAAa,SAAS,YAAY,GAAG,CAAC,MAAM,IAAI,kBAAkB,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;IAChG,MAAM,EAAE,KAAK,EAAE,WAAW,EAAE,GAAG,MAAM,cAAc,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,CAAC,kBAAkB,CAAC,CAAC;IACzG,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,CAAC;AAChC,CAAC;AAED,+EAA+E;AAC/E,iFAAiF;AACjF,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,SAAiB,EACjB,IAAgB;IAEhB,MAAM,IAAI,GAAG,IAAI,QAAQ,EAAE,CAAC;IAC5B,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,IAAI,IAAI,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,WAAW,EAAE,CAAC,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;IACvF,MAAM,CAAC,GAAG,MAAM,YAAY,CAAC,aAAa,SAAS,UAAU,EAAE,IAAI,EAAE,YAAY,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IACpG,OAAO;QACL,QAAQ,EAAE,CAAC,CAAC,QAAQ;QACpB,GAAG,EAAE,CAAC,CAAC,SAAS,IAAI,CAAC,CAAC,GAAG;QACzB,QAAQ,EAAE,IAAI,CAAC,QAAQ;KACxB,CAAC;AACJ,CAAC"}
@@ -0,0 +1,165 @@
1
+ import { log } from "../../logger.js";
2
+ import { config } from "../../config.js";
3
+ import { TailAccumulator } from "../types.js";
4
+ const API = `${config.PLATFORM_URL.replace(/\/$/, "")}/api/v4`;
5
+ // Schema-validated fetch with consistent error handling. Returns parsed data
6
+ // or throws a generic Error (schema details stay server-side in logs).
7
+ export async function gitlabRequest(path, init, schema, auth) {
8
+ const url = path.startsWith("http") ? path : `${API}${path}`;
9
+ const headers = {
10
+ "Content-Type": "application/json",
11
+ ...(auth.kind === "bot"
12
+ ? { "PRIVATE-TOKEN": config.PLATFORM_TOKEN }
13
+ : { Authorization: `Bearer ${auth.token}` }),
14
+ };
15
+ const res = await fetch(url, { ...init, headers });
16
+ if (!res.ok) {
17
+ const body = await res.text();
18
+ throw new Error(`GitLab ${res.status} ${url}: ${body}`);
19
+ }
20
+ const json = await res.json();
21
+ const parsed = schema.safeParse(json);
22
+ if (!parsed.success) {
23
+ log.error("gitlab response schema mismatch", { url, issues: parsed.error.issues });
24
+ throw new Error(`GitLab schema mismatch for ${url}`);
25
+ }
26
+ return parsed.data;
27
+ }
28
+ // Array variant — GitLab list endpoints return an array; non-array responses
29
+ // are treated as a schema mismatch (same as returning [] today, but now throws
30
+ // instead of silently returning empty — matches the Tier 1 fix for gitlab.ts).
31
+ export async function gitlabRequestArray(path, init, schema, auth) {
32
+ const url = path.startsWith("http") ? path : `${API}${path}`;
33
+ const headers = {
34
+ "Content-Type": "application/json",
35
+ ...(auth.kind === "bot"
36
+ ? { "PRIVATE-TOKEN": config.PLATFORM_TOKEN }
37
+ : { Authorization: `Bearer ${auth.token}` }),
38
+ };
39
+ const res = await fetch(url, { ...init, headers });
40
+ if (!res.ok) {
41
+ const body = await res.text();
42
+ throw new Error(`GitLab ${res.status} ${url}: ${body}`);
43
+ }
44
+ const json = await res.json();
45
+ if (!Array.isArray(json)) {
46
+ log.error("gitlab expected array response", { url });
47
+ throw new Error(`GitLab expected array response from ${url}`);
48
+ }
49
+ const parsed = schema.array().safeParse(json);
50
+ if (!parsed.success) {
51
+ log.error("gitlab response schema mismatch", { url, issues: parsed.error.issues });
52
+ throw new Error(`GitLab schema mismatch for ${url}`);
53
+ }
54
+ return parsed.data;
55
+ }
56
+ // Raw-bytes variant — binary download (attachment bytes), no JSON parse.
57
+ // Returns the bytes + Content-Type. Honors `maxBytes` by aborting the body
58
+ // stream past the limit (avoids downloading a 200MB PDF just to reject it);
59
+ // throws an OversizedError when the cap is exceeded so the caller can classify
60
+ // the rejection (oversized is user-actionable, distinct from a fetch failure).
61
+ // Not used for the JSON endpoints above; those stay schema-validated.
62
+ export class OversizedError extends Error {
63
+ bytesSoFar;
64
+ maxBytes;
65
+ constructor(bytesSoFar, maxBytes) {
66
+ super(`attachment exceeds ${maxBytes} bytes (got ${bytesSoFar})`);
67
+ this.name = "OversizedError";
68
+ this.bytesSoFar = bytesSoFar;
69
+ this.maxBytes = maxBytes;
70
+ }
71
+ }
72
+ // `overflow` controls what happens past `maxBytes`:
73
+ // "abort" (default) — cancel the stream and throw OversizedError (attachments:
74
+ // an over-cap attachment is rejected, not partially read).
75
+ // "tail" — keep reading and retain only the last maxBytes (job logs: the
76
+ // failure is at the end, so the tail is what matters). Bounded memory.
77
+ export async function gitlabFetchRaw(path, auth, maxBytes, overflow = "abort") {
78
+ const url = path.startsWith("http") ? path : `${API}${path}`;
79
+ const headers = {
80
+ ...(auth.kind === "bot"
81
+ ? { "PRIVATE-TOKEN": config.PLATFORM_TOKEN }
82
+ : { Authorization: `Bearer ${auth.token}` }),
83
+ };
84
+ const res = await fetch(url, { method: "GET", headers });
85
+ if (!res.ok) {
86
+ const body = await res.text();
87
+ throw new Error(`GitLab ${res.status} ${url}: ${body}`);
88
+ }
89
+ const contentType = res.headers.get("content-type") ?? "application/octet-stream";
90
+ if (res.body === null) {
91
+ return { bytes: Buffer.alloc(0), contentType, totalBytes: 0 };
92
+ }
93
+ const reader = res.body.getReader();
94
+ if (overflow === "tail") {
95
+ const acc = new TailAccumulator(maxBytes);
96
+ for (;;) {
97
+ const { done, value } = await reader.read();
98
+ if (done)
99
+ break;
100
+ if (value)
101
+ acc.push(value);
102
+ }
103
+ return { ...acc.result(), contentType };
104
+ }
105
+ const chunks = [];
106
+ let total = 0;
107
+ for (;;) {
108
+ const { done, value } = await reader.read();
109
+ if (done)
110
+ break;
111
+ if (value) {
112
+ total += value.byteLength;
113
+ if (total > maxBytes) {
114
+ await reader.cancel().catch(() => { });
115
+ throw new OversizedError(total, maxBytes);
116
+ }
117
+ chunks.push(Buffer.from(value));
118
+ }
119
+ }
120
+ const bytes = Buffer.concat(chunks);
121
+ return { bytes, contentType, totalBytes: bytes.byteLength };
122
+ }
123
+ // Void variant — same fetch+error handling, no schema, for calls that return
124
+ // no body (DELETE, PUT, POST with 409/404-as-success). okStatuses lets callers
125
+ // accept specific non-2xx statuses as success (e.g. [409] for "already a member",
126
+ // [404] for "already deleted").
127
+ export async function gitlabVoid(path, init, auth, opts = {}) {
128
+ const url = path.startsWith("http") ? path : `${API}${path}`;
129
+ const headers = {
130
+ "Content-Type": "application/json",
131
+ ...(auth.kind === "bot"
132
+ ? { "PRIVATE-TOKEN": config.PLATFORM_TOKEN }
133
+ : { Authorization: `Bearer ${auth.token}` }),
134
+ };
135
+ const res = await fetch(url, { ...init, headers });
136
+ if (opts.okStatuses?.includes(res.status))
137
+ return;
138
+ if (!res.ok) {
139
+ const body = await res.text();
140
+ throw new Error(`GitLab ${res.status} ${url}: ${body}`);
141
+ }
142
+ }
143
+ // Multipart upload variant — schema-validated JSON response. The caller passes a
144
+ // prebuilt FormData; we must NOT set Content-Type so fetch adds the multipart
145
+ // boundary. Auth is header-only (same as the JSON helpers).
146
+ export async function gitlabUpload(path, form, schema, auth) {
147
+ const url = path.startsWith("http") ? path : `${API}${path}`;
148
+ const headers = auth.kind === "bot"
149
+ ? { "PRIVATE-TOKEN": config.PLATFORM_TOKEN }
150
+ : { Authorization: `Bearer ${auth.token}` };
151
+ const res = await fetch(url, { method: "POST", headers, body: form });
152
+ if (!res.ok) {
153
+ const body = await res.text();
154
+ throw new Error(`GitLab ${res.status} ${url}: ${body}`);
155
+ }
156
+ const json = await res.json();
157
+ const parsed = schema.safeParse(json);
158
+ if (!parsed.success) {
159
+ log.error("gitlab upload response schema mismatch", { url, issues: parsed.error.issues });
160
+ throw new Error(`GitLab schema mismatch for ${url}`);
161
+ }
162
+ return parsed.data;
163
+ }
164
+ export { API as GITLAB_API };
165
+ //# sourceMappingURL=http.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http.js","sourceRoot":"","sources":["../../../src/platform/gitlab/http.ts"],"names":[],"mappings":"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"}