@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,88 @@
1
+ import { z } from "zod";
2
+ import { getProject, listTokens } from "../../token-store.js";
3
+ import { listAccessTargets, isAccessAllowed } from "../../access-grant-store.js";
4
+ // Helpers shared by MCP tools. Kept tiny: one success helper, one error helper,
5
+ // and the cross-project scope resolver that every cross-project-capable tool
6
+ // uses before touching GitLab.
7
+ // Shared `project` argument for cross-project-capable tools. Absent = the run's
8
+ // own project; a number = a project id; a string = a path_with_namespace (or a
9
+ // numeric string id). Tools spread this into their inputSchema.
10
+ export const projectArg = z
11
+ .union([z.number().int().positive(), z.string().min(1).max(255)])
12
+ .optional()
13
+ .describe("Target project: a numeric project id or a path_with_namespace. Omit for the current project. " +
14
+ "Only the current project and projects it has been granted access to are readable.");
15
+ export function textResult(text) {
16
+ return { content: [{ type: "text", text }] };
17
+ }
18
+ export function errorResult(message) {
19
+ return { content: [{ type: "text", text: message }], isError: true };
20
+ }
21
+ // Normalize a thrown driver error into a tool error result. An operation the
22
+ // active forge does not support (e.g. GitHub wikis, non-code search scopes)
23
+ // reads as "not supported on this platform" rather than an opaque failure.
24
+ export function toolError(tool, e) {
25
+ if (e instanceof Error && e.name === "UnsupportedError") {
26
+ return errorResult(`${tool} failed: not supported on this platform (${e.message}).`);
27
+ }
28
+ return errorResult(`${tool} failed: ${e instanceof Error ? e.message : String(e)}`);
29
+ }
30
+ // Resolve an optional client-supplied `project` selector into a project the
31
+ // caller is allowed to read. Scope enforcement lives here, not in GitLab:
32
+ // - absent -> the run's own project (always allowed)
33
+ // - number -> target id
34
+ // - string -> an enrolled project's path_with_namespace
35
+ // Allowed iff it is the run's own project, or a live directed grant
36
+ // (source -> target) exists and the target is still enrolled. The grant is
37
+ // read on every call, so a revoked grant stops working immediately, even
38
+ // mid-session. An unauthorized/unresolvable target returns an error result —
39
+ // the caller must never fall through to a GitLab request.
40
+ export function resolveTargetProject(ctx, selector) {
41
+ if (selector === undefined || selector === null || selector === "") {
42
+ const own = getProject(ctx.projectId);
43
+ if (!own)
44
+ return { ok: false, message: `Project ${ctx.projectId} is no longer enrolled.` };
45
+ return { ok: true, target: { projectId: own.projectId, projectPath: own.projectPath } };
46
+ }
47
+ let targetId;
48
+ if (typeof selector === "number") {
49
+ targetId = selector;
50
+ }
51
+ else if (typeof selector === "string") {
52
+ if (/^\d+$/.test(selector)) {
53
+ targetId = Number(selector);
54
+ }
55
+ else {
56
+ const p = listTokens().find((t) => t.projectPath === selector);
57
+ if (!p)
58
+ return { ok: false, message: `No enrolled project matches '${selector}'.` };
59
+ targetId = p.projectId;
60
+ }
61
+ }
62
+ else {
63
+ return { ok: false, message: "`project` must be a project id or path_with_namespace." };
64
+ }
65
+ const target = getProject(targetId);
66
+ if (!target)
67
+ return { ok: false, message: `Project ${targetId} is not enrolled.` };
68
+ if (!isAccessAllowed(ctx.projectId, targetId)) {
69
+ return {
70
+ ok: false,
71
+ message: `Access denied: project ${ctx.projectId} has not been granted access to ` +
72
+ `${target.projectPath} (${targetId}). Ask an admin to grant it in the Access panel.`,
73
+ };
74
+ }
75
+ return { ok: true, target: { projectId: target.projectId, projectPath: target.projectPath } };
76
+ }
77
+ // Own project + granted targets (resolved, enrolled only). Used by the
78
+ // list_accessible_projects tool and by peer-sync to pre-seed the git exclude.
79
+ export function listAccessibleProjects(ctx) {
80
+ const own = getProject(ctx.projectId);
81
+ const out = own ? [{ projectId: own.projectId, projectPath: own.projectPath }] : [];
82
+ for (const t of listAccessTargets(ctx.projectId)) {
83
+ if (t.projectId !== ctx.projectId)
84
+ out.push(t);
85
+ }
86
+ return out;
87
+ }
88
+ //# sourceMappingURL=_helpers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"_helpers.js","sourceRoot":"","sources":["../../../src/mcp/tools/_helpers.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,117 @@
1
+ import { z } from "zod";
2
+ import { getPlatform } from "../../platform/index.js";
3
+ import { config } from "../../config.js";
4
+ import { runtime } from "../../runtime-state.js";
5
+ import { OUT_DIR, INCOMING_DIR, readFileFromVolume, writeFileToVolume, ExistsError } from "../volume-files.js";
6
+ import { resolveBuilderImage } from "../../settings-store.js";
7
+ import { safeDownloadFilename } from "../../attachments.js";
8
+ import { log } from "../../logger.js";
9
+ import { textResult, errorResult, toolError } from "./_helpers.js";
10
+ // Download a work-item attachment from the forge into the git-excluded staging
11
+ // dir so the agent can handle it with its own tools (including OCR). The
12
+ // reference must match exactly one discovered attachment; the agent passes the
13
+ // markdown link or bare URL as it appears in the note.
14
+ export const downloadWorkItemAttachment = {
15
+ name: "download_work_item_attachment",
16
+ description: "Download an attachment from this work item's description or discussion into the workspace so you can read it. " +
17
+ "Pass the attachment's Markdown link or URL exactly as it appears. The file is saved under " +
18
+ `\`${INCOMING_DIR}/\` (git-excluded) and the tool returns its local path. ` +
19
+ "Image/PDF OCR is available on the saved file (`tesseract`, `pdftotext`, `pdftoppm` are installed).",
20
+ inputSchema: {
21
+ reference: z
22
+ .string()
23
+ .min(1)
24
+ .describe("The attachment reference exactly as it appears in the work item or a comment (e.g. `![shot](/uploads/abc/shot.png)`)."),
25
+ },
26
+ async handler(ctx, args) {
27
+ const reference = String(args.reference ?? "");
28
+ let ref;
29
+ try {
30
+ const matches = getPlatform().attachments.findRefs(reference);
31
+ if (matches.length === 0) {
32
+ return errorResult(`download_work_item_attachment: no attachment matched \`${reference}\`. Pass the link exactly as it appears in the work item.`);
33
+ }
34
+ if (matches.length > 1) {
35
+ return errorResult(`download_work_item_attachment: \`${reference}\` matched ${matches.length} attachments; pass a single attachment link.`);
36
+ }
37
+ ref = matches[0];
38
+ const bytes = await getPlatform().attachments.download(ctx.projectId, ref);
39
+ const filename = safeDownloadFilename(ref.filename);
40
+ // Avoid clobbering a prior download of the same reference.
41
+ let relPath = `${INCOMING_DIR}/${filename}`;
42
+ for (let attempt = 1;; attempt++) {
43
+ try {
44
+ await writeFileToVolume(ctx.workItemId, relPath, bytes.bytes, resolveBuilderImage(ctx.projectId) || config.BUILDER_IMAGE);
45
+ break;
46
+ }
47
+ catch (e) {
48
+ if (!(e instanceof ExistsError) || attempt >= 100)
49
+ throw e;
50
+ const dot = filename.lastIndexOf(".");
51
+ const base = dot > 0 ? filename.slice(0, dot) : filename;
52
+ const ext = dot > 0 ? filename.slice(dot) : "";
53
+ relPath = `${INCOMING_DIR}/${base}-${attempt}${ext}`;
54
+ }
55
+ }
56
+ log.info("attachment downloaded", { workItemId: ctx.workItemId, filename, bytes: bytes.bytes.byteLength });
57
+ return textResult(JSON.stringify({
58
+ reference,
59
+ filename,
60
+ path: `/workspace/${relPath}`,
61
+ bytes: bytes.bytes.byteLength,
62
+ contentType: bytes.contentType,
63
+ }, null, 2));
64
+ }
65
+ catch (e) {
66
+ return toolError("download_work_item_attachment", e);
67
+ }
68
+ },
69
+ };
70
+ // Upload a file from the run volume to the work item as an attachment and post
71
+ // it as a comment (with an optional caption). Files must live under /workspace;
72
+ // agent-produced throwaway output should go in .devbot-out/, which is
73
+ // git-excluded so it can never be committed. Forges without an upload API
74
+ // (GitHub) return "not supported on this platform" via toolError.
75
+ export const uploadWorkItemAttachment = {
76
+ name: "upload_work_item_attachment",
77
+ description: "Upload a file from the workspace to this work item as an attachment and post it as a comment. " +
78
+ `Use this to share screenshots, test logs, or command output with the user. Files must be inside /workspace; ` +
79
+ `write scratch output to the ${OUT_DIR}/ directory (git-excluded, never committed). ` +
80
+ "`path` is relative to /workspace (or absolute under it); `caption` is optional Markdown posted above the attachment.",
81
+ inputSchema: {
82
+ path: z
83
+ .string()
84
+ .min(1)
85
+ .describe(`File to upload, relative to /workspace (e.g. "${OUT_DIR}/shot.png") or absolute under /workspace.`),
86
+ caption: z.string().max(2000).optional().describe("Optional Markdown caption posted above the attachment."),
87
+ },
88
+ async handler(ctx, args) {
89
+ const path = String(args.path ?? "");
90
+ const caption = typeof args.caption === "string" ? args.caption.trim() : "";
91
+ let uploaded;
92
+ try {
93
+ const file = await readFileFromVolume(ctx.workItemId, path, runtime().attachmentMaxBytes, resolveBuilderImage(ctx.projectId) || config.BUILDER_IMAGE);
94
+ uploaded = await getPlatform().attachments.upload(ctx.projectId, ctx.workItemNumber, {
95
+ filename: file.filename,
96
+ bytes: file.bytes,
97
+ contentType: file.contentType,
98
+ });
99
+ }
100
+ catch (e) {
101
+ return toolError("upload_work_item_attachment", e);
102
+ }
103
+ // The bytes are already on the forge at this point. If posting the comment
104
+ // fails, return the markdown so the agent can still include it in its final
105
+ // reply rather than orphaning the upload silently.
106
+ const body = caption ? `${caption}\n\n${uploaded.markdown}` : uploaded.markdown;
107
+ try {
108
+ await getPlatform().workItems.postComment(ctx.projectId, ctx.workItemNumber, body);
109
+ }
110
+ catch (e) {
111
+ return errorResult(`upload_work_item_attachment: file uploaded but posting the comment failed ` +
112
+ `(${e instanceof Error ? e.message : String(e)}). Include this Markdown in your reply: ${uploaded.markdown}`);
113
+ }
114
+ return textResult(JSON.stringify({ filename: uploaded.filename, markdown: uploaded.markdown, url: uploaded.url }, null, 2));
115
+ },
116
+ };
117
+ //# sourceMappingURL=attachments.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"attachments.js","sourceRoot":"","sources":["../../../src/mcp/tools/attachments.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,105 @@
1
+ import { z } from "zod";
2
+ import { getPlatform } from "../../platform/index.js";
3
+ import { textResult, errorResult, toolError, resolveTargetProject, projectArg } from "./_helpers.js";
4
+ const MAX_LOG_BYTES = 200_000;
5
+ // CI/CD. On every forge these map to the normalized PipelineRun/Job shapes:
6
+ // GitLab pipelines/jobs/trace, ForgeJo/Gitea and GitHub Actions runs/jobs/logs.
7
+ // `scope` is GitLab-only; the other drivers throw UnsupportedError, rendered by
8
+ // toolError as "not supported on this platform". `username` maps to the forge's
9
+ // actor filter (GitLab `username`, Gitea/GitHub `actor`).
10
+ export const listPipelines = {
11
+ name: "list_pipelines",
12
+ description: "List a project's CI/CD runs (GitLab pipelines / ForgeJo-Gitea-GitHub Actions workflow runs). Filter by ref, status, or username (the run's actor). `scope` is GitLab-only. Defaults to the current project; pass `project` for an authorized other project.",
13
+ inputSchema: {
14
+ ref: z.string().optional().describe("Branch or tag to filter runs."),
15
+ status: z.string().optional().describe("Run status filter."),
16
+ scope: z.string().optional().describe("Run scope filter (GitLab only)."),
17
+ username: z.string().optional().describe("Only runs triggered by this username."),
18
+ page: z.number().int().positive().optional().describe("1-based page number (100 per page)."),
19
+ project: projectArg,
20
+ },
21
+ async handler(ctx, args) {
22
+ const t = resolveTargetProject(ctx, args.project);
23
+ if (!t.ok)
24
+ return errorResult(t.message);
25
+ try {
26
+ const p = await getPlatform().ci.listPipelines(t.target.projectId, {
27
+ ...(args.ref ? { ref: args.ref } : {}),
28
+ ...(args.status ? { status: args.status } : {}),
29
+ ...(args.scope ? { scope: args.scope } : {}),
30
+ ...(args.username ? { username: args.username } : {}),
31
+ ...(args.page ? { page: args.page } : {}),
32
+ });
33
+ return textResult(JSON.stringify(p, null, 2));
34
+ }
35
+ catch (e) {
36
+ return toolError("list_pipelines", e);
37
+ }
38
+ },
39
+ };
40
+ export const getPipeline = {
41
+ name: "get_pipeline",
42
+ description: "Fetch a single CI/CD run by id. Defaults to the current project; pass `project` for an authorized other project.",
43
+ inputSchema: {
44
+ pipeline_id: z.number().int().positive().describe("Pipeline/run id."),
45
+ project: projectArg,
46
+ },
47
+ async handler(ctx, args) {
48
+ const t = resolveTargetProject(ctx, args.project);
49
+ if (!t.ok)
50
+ return errorResult(t.message);
51
+ try {
52
+ const p = await getPlatform().ci.getPipeline(t.target.projectId, args.pipeline_id);
53
+ return textResult(JSON.stringify(p, null, 2));
54
+ }
55
+ catch (e) {
56
+ return toolError("get_pipeline", e);
57
+ }
58
+ },
59
+ };
60
+ export const listPipelineJobs = {
61
+ name: "list_pipeline_jobs",
62
+ description: "List the jobs of a CI/CD run. `scope` (e.g. failed) is GitLab-only. Defaults to the current project; pass `project` for an authorized other project.",
63
+ inputSchema: {
64
+ pipeline_id: z.number().int().positive().describe("Pipeline/run id."),
65
+ scope: z.string().optional().describe("Job status scope filter (GitLab only)."),
66
+ page: z.number().int().positive().optional().describe("1-based page number (100 per page)."),
67
+ project: projectArg,
68
+ },
69
+ async handler(ctx, args) {
70
+ const t = resolveTargetProject(ctx, args.project);
71
+ if (!t.ok)
72
+ return errorResult(t.message);
73
+ try {
74
+ const jobs = await getPlatform().ci.listPipelineJobs(t.target.projectId, args.pipeline_id, {
75
+ ...(args.scope ? { scope: args.scope } : {}),
76
+ ...(args.page ? { page: args.page } : {}),
77
+ });
78
+ return textResult(JSON.stringify(jobs, null, 2));
79
+ }
80
+ catch (e) {
81
+ return toolError("list_pipeline_jobs", e);
82
+ }
83
+ },
84
+ };
85
+ export const getJobLog = {
86
+ name: "get_job_log",
87
+ description: "Fetch a job's raw trace/log text. When the log exceeds the 200 KB read cap the tail is kept and the omitted head is marked. Defaults to the current project; pass `project` for an authorized other project.",
88
+ inputSchema: {
89
+ job_id: z.number().int().positive().describe("Job id."),
90
+ project: projectArg,
91
+ },
92
+ async handler(ctx, args) {
93
+ const t = resolveTargetProject(ctx, args.project);
94
+ if (!t.ok)
95
+ return errorResult(t.message);
96
+ try {
97
+ const f = await getPlatform().ci.getJobLog(t.target.projectId, args.job_id, MAX_LOG_BYTES);
98
+ return textResult(f.content);
99
+ }
100
+ catch (e) {
101
+ return toolError("get_job_log", e);
102
+ }
103
+ },
104
+ };
105
+ //# sourceMappingURL=cicd.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cicd.js","sourceRoot":"","sources":["../../../src/mcp/tools/cicd.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,34 @@
1
+ import { getPlatform } from "../../platform/index.js";
2
+ import { textResult, errorResult, resolveTargetProject, listAccessibleProjects as listAccessible, projectArg } from "./_helpers.js";
3
+ // List the projects this run can read: its own project plus every project it
4
+ // has been granted access to. Resolved entirely from DevBot's enrollment +
5
+ // grant tables — never lists all managed projects, and never calls the forge.
6
+ export const listAccessibleProjects = {
7
+ name: "list_accessible_projects",
8
+ description: "List the projects this run can read. Always includes the current project; includes other projects only when an admin has granted access. Returns projectId and path. Use a returned `project` selector with the other tools.",
9
+ inputSchema: {},
10
+ async handler(ctx) {
11
+ return textResult(JSON.stringify(listAccessible(ctx), null, 2));
12
+ },
13
+ };
14
+ // Fetch project metadata.
15
+ export const getProject = {
16
+ name: "get_project",
17
+ description: "Fetch metadata for a project: id, path, web URL, HTTPS clone URL, and default branch. Defaults to the current project; pass `project` for an authorized other project.",
18
+ inputSchema: {
19
+ project: projectArg,
20
+ },
21
+ async handler(ctx, args) {
22
+ const t = resolveTargetProject(ctx, args.project);
23
+ if (!t.ok)
24
+ return errorResult(t.message);
25
+ try {
26
+ const p = await getPlatform().repository.getRepo(t.target.projectId);
27
+ return textResult(JSON.stringify(p, null, 2));
28
+ }
29
+ catch (e) {
30
+ return errorResult(`get_project failed: ${e instanceof Error ? e.message : String(e)}`);
31
+ }
32
+ },
33
+ };
34
+ //# sourceMappingURL=discovery.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"discovery.js","sourceRoot":"","sources":["../../../src/mcp/tools/discovery.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAEtD,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,oBAAoB,EAAE,sBAAsB,IAAI,cAAc,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAEpI,6EAA6E;AAC7E,2EAA2E;AAC3E,8EAA8E;AAC9E,MAAM,CAAC,MAAM,sBAAsB,GAAS;IAC1C,IAAI,EAAE,0BAA0B;IAChC,WAAW,EACT,8NAA8N;IAChO,WAAW,EAAE,EAAE;IACf,KAAK,CAAC,OAAO,CAAC,GAAG;QACf,OAAO,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,cAAc,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IAClE,CAAC;CACF,CAAC;AAEF,0BAA0B;AAC1B,MAAM,CAAC,MAAM,UAAU,GAAS;IAC9B,IAAI,EAAE,aAAa;IACnB,WAAW,EACT,wKAAwK;IAC1K,WAAW,EAAE;QACX,OAAO,EAAE,UAAU;KACpB;IACD,KAAK,CAAC,OAAO,CAAC,GAAG,EAAE,IAAI;QACrB,MAAM,CAAC,GAAG,oBAAoB,CAAC,GAAG,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;QAClD,IAAI,CAAC,CAAC,CAAC,EAAE;YAAE,OAAO,WAAW,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;QACzC,IAAI,CAAC;YACH,MAAM,CAAC,GAAG,MAAM,WAAW,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;YACrE,OAAO,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;QAChD,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,OAAO,WAAW,CAAC,uBAAuB,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QAC1F,CAAC;IACH,CAAC;CACF,CAAC"}
@@ -0,0 +1,56 @@
1
+ import { z } from "zod";
2
+ import { getPlatform } from "../../platform/index.js";
3
+ import { textResult, errorResult, resolveTargetProject, projectArg } from "./_helpers.js";
4
+ // List issues in the current project (or a granted target). The target is
5
+ // resolved from the token's project + the live directed-grant set; the forge
6
+ // call only happens after the scope check passes.
7
+ export const listIssues = {
8
+ name: "list_issues",
9
+ description: "List issues in the current project. Returns id, number, title, state, web_url, labels, assignees. Filter by state or search by title/description. Pass `project` to read an authorized other project.",
10
+ inputSchema: {
11
+ state: z.enum(["open", "closed", "all"]).optional().describe("Issue state filter. Defaults to all."),
12
+ search: z.string().optional().describe("Search term matched against issue title and description."),
13
+ labels: z.string().optional().describe("Comma-separated label names; issues must have all of them."),
14
+ page: z.number().int().positive().optional().describe("1-based page number (100 per page)."),
15
+ project: projectArg,
16
+ },
17
+ async handler(ctx, args) {
18
+ const t = resolveTargetProject(ctx, args.project);
19
+ if (!t.ok)
20
+ return errorResult(t.message);
21
+ try {
22
+ const issues = await getPlatform().workItems.listWorkItems(t.target.projectId, {
23
+ ...(args.state ? { state: args.state } : {}),
24
+ ...(args.search ? { search: args.search } : {}),
25
+ ...(args.labels ? { labels: args.labels } : {}),
26
+ ...(args.page ? { page: args.page } : {}),
27
+ });
28
+ return textResult(JSON.stringify(issues, null, 2));
29
+ }
30
+ catch (e) {
31
+ return errorResult(`list_issues failed: ${e instanceof Error ? e.message : String(e)}`);
32
+ }
33
+ },
34
+ };
35
+ // Fetch a single issue by number (the project-internal number, not the global id).
36
+ export const getIssue = {
37
+ name: "get_issue",
38
+ description: "Fetch a single issue by its project-internal number. Returns full issue metadata: title, description, state, labels, assignees, milestone, references. Pass `project` to read an authorized other project.",
39
+ inputSchema: {
40
+ number: z.number().int().positive().describe("The issue's project-internal number (the number shown in the issue URL)."),
41
+ project: projectArg,
42
+ },
43
+ async handler(ctx, args) {
44
+ const t = resolveTargetProject(ctx, args.project);
45
+ if (!t.ok)
46
+ return errorResult(t.message);
47
+ try {
48
+ const issue = await getPlatform().workItems.getWorkItemSummary(t.target.projectId, args.number);
49
+ return textResult(JSON.stringify(issue, null, 2));
50
+ }
51
+ catch (e) {
52
+ return errorResult(`get_issue failed: ${e instanceof Error ? e.message : String(e)}`);
53
+ }
54
+ },
55
+ };
56
+ //# sourceMappingURL=issues.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"issues.js","sourceRoot":"","sources":["../../../src/mcp/tools/issues.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,67 @@
1
+ import { z } from "zod";
2
+ import { getPlatform } from "../../platform/index.js";
3
+ import { textResult, errorResult, resolveTargetProject, projectArg } from "./_helpers.js";
4
+ export const listMergeRequests = {
5
+ name: "list_merge_requests",
6
+ description: "List merge/pull requests in the current project. Returns id, number, title, state, source/target branch, web_url. Filter by state or search. Pass `project` to read an authorized other project.",
7
+ inputSchema: {
8
+ state: z
9
+ .enum(["open", "closed", "merged", "all"])
10
+ .optional()
11
+ .describe("Merge/pull request state filter. Defaults to all."),
12
+ search: z.string().optional().describe("Search term matched against MR title and description."),
13
+ source_branch: z.string().optional().describe("Filter by source branch name."),
14
+ page: z.number().int().positive().optional().describe("1-based page number (100 per page)."),
15
+ project: projectArg,
16
+ },
17
+ async handler(ctx, args) {
18
+ const t = resolveTargetProject(ctx, args.project);
19
+ if (!t.ok)
20
+ return errorResult(t.message);
21
+ try {
22
+ const mrs = await getPlatform().changeRequests.list(t.target.projectId, {
23
+ ...(args.state ? { state: args.state } : {}),
24
+ ...(args.search ? { search: args.search } : {}),
25
+ ...(args.source_branch ? { sourceBranch: args.source_branch } : {}),
26
+ ...(args.page ? { page: args.page } : {}),
27
+ });
28
+ return textResult(JSON.stringify(mrs, null, 2));
29
+ }
30
+ catch (e) {
31
+ return errorResult(`list_merge_requests failed: ${e instanceof Error ? e.message : String(e)}`);
32
+ }
33
+ },
34
+ };
35
+ // Fetch review discussions for a single CR by number. Target resolved from the
36
+ // token + live grants.
37
+ export const getMergeRequestDiscussions = {
38
+ name: "get_merge_request_discussions",
39
+ description: "Fetch discussions for a merge/pull request by its project-internal number. Returns review comments (with file/line position when anchored), general threads, and system notes. Each note carries author and body. Use this to get review context. Pass `project` to read an authorized other project.",
40
+ inputSchema: {
41
+ number: z.number().int().positive().describe("The merge/pull request's project-internal number (the number shown in its URL)."),
42
+ diff_only: z
43
+ .boolean()
44
+ .optional()
45
+ .describe("If true, keep only discussions containing at least one anchored (diff) note. Defaults to false (all discussions)."),
46
+ page: z.number().int().positive().optional().describe("1-based page number (100 per page)."),
47
+ project: projectArg,
48
+ },
49
+ async handler(ctx, args) {
50
+ const t = resolveTargetProject(ctx, args.project);
51
+ if (!t.ok)
52
+ return errorResult(t.message);
53
+ try {
54
+ const discussions = await getPlatform().changeRequests.listReviewDiscussions(t.target.projectId, args.number, {
55
+ ...(args.page ? { page: args.page } : {}),
56
+ });
57
+ const filtered = args.diff_only
58
+ ? discussions.filter((d) => d.notes.some((n) => n.position))
59
+ : discussions;
60
+ return textResult(JSON.stringify(filtered, null, 2));
61
+ }
62
+ catch (e) {
63
+ return errorResult(`get_merge_request_discussions failed: ${e instanceof Error ? e.message : String(e)}`);
64
+ }
65
+ },
66
+ };
67
+ //# sourceMappingURL=merge_requests.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"merge_requests.js","sourceRoot":"","sources":["../../../src/mcp/tools/merge_requests.ts"],"names":[],"mappings":"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"}