@dxos/plugin-github 0.7.4 → 0.14.0

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 (642) hide show
  1. package/LICENSE +102 -5
  2. package/PLUGIN.mdl +784 -0
  3. package/dist/lib/GitHubCapabilities.mjs +10 -0
  4. package/dist/lib/GitHubCapabilities.mjs.map +1 -0
  5. package/dist/lib/GitHubEvents.mjs +15 -0
  6. package/dist/lib/GitHubEvents.mjs.map +1 -0
  7. package/dist/lib/GitHubOperation.mjs +384 -0
  8. package/dist/lib/GitHubOperation.mjs.map +1 -0
  9. package/dist/lib/GitHubPlugin.mjs +16 -0
  10. package/dist/lib/GitHubPlugin.mjs.map +1 -0
  11. package/dist/lib/Walkthrough.mjs +59 -0
  12. package/dist/lib/Walkthrough.mjs.map +1 -0
  13. package/dist/lib/capabilities.browser.mjs +54 -0
  14. package/dist/lib/capabilities.browser.mjs.map +1 -0
  15. package/dist/lib/capabilities.mjs +54 -0
  16. package/dist/lib/capabilities.mjs.map +1 -0
  17. package/dist/lib/capabilities.node.mjs +30 -0
  18. package/dist/lib/capabilities.node.mjs.map +1 -0
  19. package/dist/lib/capabilities.tauri.mjs +54 -0
  20. package/dist/lib/capabilities.tauri.mjs.map +1 -0
  21. package/dist/lib/capabilities.workerd.mjs +30 -0
  22. package/dist/lib/capabilities.workerd.mjs.map +1 -0
  23. package/dist/lib/chunk-ImportPullRequestDialog.mjs +116 -0
  24. package/dist/lib/chunk-ImportPullRequestDialog.mjs.map +1 -0
  25. package/dist/lib/chunk-PLUGIN.mjs +6 -0
  26. package/dist/lib/chunk-PLUGIN.mjs.map +1 -0
  27. package/dist/lib/chunk-PullRequestArticle.mjs +1506 -0
  28. package/dist/lib/chunk-PullRequestArticle.mjs.map +1 -0
  29. package/dist/lib/chunk-PullRequestArticle2.mjs +2 -0
  30. package/dist/lib/chunk-PullRequestCardMenu.mjs +123 -0
  31. package/dist/lib/chunk-PullRequestCardMenu.mjs.map +1 -0
  32. package/dist/lib/chunk-PullRequestsArticle.mjs +594 -0
  33. package/dist/lib/chunk-PullRequestsArticle.mjs.map +1 -0
  34. package/dist/lib/chunk-WalkthroughArticle.mjs +26 -0
  35. package/dist/lib/chunk-WalkthroughArticle.mjs.map +1 -0
  36. package/dist/lib/chunk-add-pull-request-comment.mjs +19 -0
  37. package/dist/lib/chunk-add-pull-request-comment.mjs.map +1 -0
  38. package/dist/lib/chunk-add-pull-request-review-comment.mjs +25 -0
  39. package/dist/lib/chunk-add-pull-request-review-comment.mjs.map +1 -0
  40. package/dist/lib/chunk-app-graph-builder.mjs +39 -0
  41. package/dist/lib/chunk-app-graph-builder.mjs.map +1 -0
  42. package/dist/lib/chunk-connector.mjs +70 -0
  43. package/dist/lib/chunk-connector.mjs.map +1 -0
  44. package/dist/lib/chunk-constants.mjs +11 -0
  45. package/dist/lib/chunk-constants.mjs.map +1 -0
  46. package/dist/lib/chunk-errors.mjs +29 -0
  47. package/dist/lib/chunk-errors.mjs.map +1 -0
  48. package/dist/lib/chunk-generate-walkthrough.mjs +86 -0
  49. package/dist/lib/chunk-generate-walkthrough.mjs.map +1 -0
  50. package/dist/lib/chunk-generate.mjs +719 -0
  51. package/dist/lib/chunk-generate.mjs.map +1 -0
  52. package/dist/lib/chunk-get-pull-request-diff.mjs +25 -0
  53. package/dist/lib/chunk-get-pull-request-diff.mjs.map +1 -0
  54. package/dist/lib/chunk-get-pull-request-status.mjs +29 -0
  55. package/dist/lib/chunk-get-pull-request-status.mjs.map +1 -0
  56. package/dist/lib/chunk-get-repositories.mjs +32 -0
  57. package/dist/lib/chunk-get-repositories.mjs.map +1 -0
  58. package/dist/lib/chunk-github-api.mjs +375 -0
  59. package/dist/lib/chunk-github-api.mjs.map +1 -0
  60. package/dist/lib/chunk-github-link.mjs +59 -0
  61. package/dist/lib/chunk-github-link.mjs.map +1 -0
  62. package/dist/lib/chunk-import-pull-request-from-snapshot.mjs +25 -0
  63. package/dist/lib/chunk-import-pull-request-from-snapshot.mjs.map +1 -0
  64. package/dist/lib/chunk-import-pull-request.mjs +171 -0
  65. package/dist/lib/chunk-import-pull-request.mjs.map +1 -0
  66. package/dist/lib/chunk-link-resolver.mjs +109 -0
  67. package/dist/lib/chunk-link-resolver.mjs.map +1 -0
  68. package/dist/lib/chunk-markdown-extension.mjs +92 -0
  69. package/dist/lib/chunk-markdown-extension.mjs.map +1 -0
  70. package/dist/lib/chunk-materialize-target.mjs +36 -0
  71. package/dist/lib/chunk-materialize-target.mjs.map +1 -0
  72. package/dist/lib/chunk-operation-handler.mjs +12 -0
  73. package/dist/lib/chunk-operation-handler.mjs.map +1 -0
  74. package/dist/lib/chunk-page-action.mjs +22 -0
  75. package/dist/lib/chunk-page-action.mjs.map +1 -0
  76. package/dist/lib/chunk-pull-request.mjs +58 -0
  77. package/dist/lib/chunk-pull-request.mjs.map +1 -0
  78. package/dist/lib/chunk-pull-request2.mjs +110 -0
  79. package/dist/lib/chunk-pull-request2.mjs.map +1 -0
  80. package/dist/lib/chunk-react-surface.mjs +233 -0
  81. package/dist/lib/chunk-react-surface.mjs.map +1 -0
  82. package/dist/lib/chunk-refresh-pull-requests.mjs +49 -0
  83. package/dist/lib/chunk-refresh-pull-requests.mjs.map +1 -0
  84. package/dist/lib/chunk-rolldown-runtime.mjs +13 -0
  85. package/dist/lib/chunk-schema.mjs +15 -0
  86. package/dist/lib/chunk-schema.mjs.map +1 -0
  87. package/dist/lib/chunk-skill-definition.mjs +10 -0
  88. package/dist/lib/chunk-skill-definition.mjs.map +1 -0
  89. package/dist/lib/chunk-submit-pull-request-approval.mjs +56 -0
  90. package/dist/lib/chunk-submit-pull-request-approval.mjs.map +1 -0
  91. package/dist/lib/chunk-sync-pull-request.mjs +26 -0
  92. package/dist/lib/chunk-sync-pull-request.mjs.map +1 -0
  93. package/dist/lib/chunk-sync.mjs +481 -0
  94. package/dist/lib/chunk-sync.mjs.map +1 -0
  95. package/dist/lib/chunk-useOpenObject.mjs +43 -0
  96. package/dist/lib/chunk-useOpenObject.mjs.map +1 -0
  97. package/dist/lib/extensions.mjs +132 -0
  98. package/dist/lib/extensions.mjs.map +1 -0
  99. package/dist/lib/index.mjs +4 -0
  100. package/dist/lib/meta.mjs +47 -0
  101. package/dist/lib/meta.mjs.map +1 -0
  102. package/dist/lib/ns/Extensions.mjs +18 -0
  103. package/dist/lib/ns/Extensions.mjs.map +1 -0
  104. package/dist/lib/operations.mjs +23 -0
  105. package/dist/lib/operations.mjs.map +1 -0
  106. package/dist/lib/plugin.mjs +9 -0
  107. package/dist/lib/plugin.mjs.map +1 -0
  108. package/dist/lib/skills.mjs +44 -0
  109. package/dist/lib/skills.mjs.map +1 -0
  110. package/dist/lib/testing.mjs +189 -0
  111. package/dist/lib/testing.mjs.map +1 -0
  112. package/dist/lib/translations.mjs +136 -0
  113. package/dist/lib/translations.mjs.map +1 -0
  114. package/dist/lib/types.mjs +5 -0
  115. package/dist/types/dx.config.d.ts +28 -0
  116. package/dist/types/dx.config.d.ts.map +1 -0
  117. package/dist/types/src/Extensions.d.ts +2 -0
  118. package/dist/types/src/Extensions.d.ts.map +1 -0
  119. package/dist/types/src/GitHubPlugin.d.ts +37 -0
  120. package/dist/types/src/GitHubPlugin.d.ts.map +1 -0
  121. package/dist/types/src/GitHubPlugin.workerd.test.d.ts +2 -0
  122. package/dist/types/src/GitHubPlugin.workerd.test.d.ts.map +1 -0
  123. package/dist/types/src/approval.d.ts +21 -0
  124. package/dist/types/src/approval.d.ts.map +1 -0
  125. package/dist/types/src/approval.test.d.ts +2 -0
  126. package/dist/types/src/approval.test.d.ts.map +1 -0
  127. package/dist/types/src/capabilities/app-graph-builder.d.ts +9 -0
  128. package/dist/types/src/capabilities/app-graph-builder.d.ts.map +1 -0
  129. package/dist/types/src/capabilities/connector.d.ts +17 -0
  130. package/dist/types/src/capabilities/connector.d.ts.map +1 -0
  131. package/dist/types/src/capabilities/gen/browser.d.ts +13 -0
  132. package/dist/types/src/capabilities/gen/browser.d.ts.map +1 -0
  133. package/dist/types/src/capabilities/gen/node.d.ts +13 -0
  134. package/dist/types/src/capabilities/gen/node.d.ts.map +1 -0
  135. package/dist/types/src/capabilities/gen/tauri.d.ts +13 -0
  136. package/dist/types/src/capabilities/gen/tauri.d.ts.map +1 -0
  137. package/dist/types/src/capabilities/gen/workerd.d.ts +13 -0
  138. package/dist/types/src/capabilities/gen/workerd.d.ts.map +1 -0
  139. package/dist/types/src/capabilities/index.d.ts +13 -0
  140. package/dist/types/src/capabilities/index.d.ts.map +1 -0
  141. package/dist/types/src/capabilities/link-resolver.d.ts +10 -0
  142. package/dist/types/src/capabilities/link-resolver.d.ts.map +1 -0
  143. package/dist/types/src/capabilities/markdown-extension.d.ts +14 -0
  144. package/dist/types/src/capabilities/markdown-extension.d.ts.map +1 -0
  145. package/dist/types/src/capabilities/operation-handler.d.ts +5 -0
  146. package/dist/types/src/capabilities/operation-handler.d.ts.map +1 -0
  147. package/dist/types/src/capabilities/page-action.d.ts +5 -0
  148. package/dist/types/src/capabilities/page-action.d.ts.map +1 -0
  149. package/dist/types/src/capabilities/react-surface.d.ts +5 -0
  150. package/dist/types/src/capabilities/react-surface.d.ts.map +1 -0
  151. package/dist/types/src/capabilities/schema.d.ts +12 -0
  152. package/dist/types/src/capabilities/schema.d.ts.map +1 -0
  153. package/dist/types/src/capabilities/skill-definition.d.ts +5 -0
  154. package/dist/types/src/capabilities/skill-definition.d.ts.map +1 -0
  155. package/dist/types/src/cards/GitHubCard.d.ts +11 -0
  156. package/dist/types/src/cards/GitHubCard.d.ts.map +1 -0
  157. package/dist/types/src/cards/GitHubCard.stories.d.ts +45 -0
  158. package/dist/types/src/cards/GitHubCard.stories.d.ts.map +1 -0
  159. package/dist/types/src/cards/PullRequestCard.d.ts +9 -0
  160. package/dist/types/src/cards/PullRequestCard.d.ts.map +1 -0
  161. package/dist/types/src/cards/index.d.ts +3 -0
  162. package/dist/types/src/cards/index.d.ts.map +1 -0
  163. package/dist/types/src/components/CommentComposer/CommentComposer.d.ts +30 -0
  164. package/dist/types/src/components/CommentComposer/CommentComposer.d.ts.map +1 -0
  165. package/dist/types/src/components/CommentComposer/index.d.ts +2 -0
  166. package/dist/types/src/components/CommentComposer/index.d.ts.map +1 -0
  167. package/dist/types/src/components/PullRequestFiles/DiffStat.d.ts +8 -0
  168. package/dist/types/src/components/PullRequestFiles/DiffStat.d.ts.map +1 -0
  169. package/dist/types/src/components/PullRequestFiles/FileTree.d.ts +17 -0
  170. package/dist/types/src/components/PullRequestFiles/FileTree.d.ts.map +1 -0
  171. package/dist/types/src/components/PullRequestFiles/PullRequestFiles.d.ts +23 -0
  172. package/dist/types/src/components/PullRequestFiles/PullRequestFiles.d.ts.map +1 -0
  173. package/dist/types/src/components/PullRequestFiles/files.d.ts +39 -0
  174. package/dist/types/src/components/PullRequestFiles/files.d.ts.map +1 -0
  175. package/dist/types/src/components/PullRequestFiles/files.test.d.ts +2 -0
  176. package/dist/types/src/components/PullRequestFiles/files.test.d.ts.map +1 -0
  177. package/dist/types/src/components/PullRequestFiles/index.d.ts +5 -0
  178. package/dist/types/src/components/PullRequestFiles/index.d.ts.map +1 -0
  179. package/dist/types/src/components/PullRequestOverview/ArtifactPill.d.ts +21 -0
  180. package/dist/types/src/components/PullRequestOverview/ArtifactPill.d.ts.map +1 -0
  181. package/dist/types/src/components/PullRequestOverview/CheckRunList.d.ts +18 -0
  182. package/dist/types/src/components/PullRequestOverview/CheckRunList.d.ts.map +1 -0
  183. package/dist/types/src/components/PullRequestOverview/CheckRunList.test.d.ts +2 -0
  184. package/dist/types/src/components/PullRequestOverview/CheckRunList.test.d.ts.map +1 -0
  185. package/dist/types/src/components/PullRequestOverview/PullRequestDetails.d.ts +10 -0
  186. package/dist/types/src/components/PullRequestOverview/PullRequestDetails.d.ts.map +1 -0
  187. package/dist/types/src/components/PullRequestOverview/PullRequestOverview.d.ts +16 -0
  188. package/dist/types/src/components/PullRequestOverview/PullRequestOverview.d.ts.map +1 -0
  189. package/dist/types/src/components/PullRequestOverview/RelatedCards.d.ts +28 -0
  190. package/dist/types/src/components/PullRequestOverview/RelatedCards.d.ts.map +1 -0
  191. package/dist/types/src/components/PullRequestOverview/index.d.ts +6 -0
  192. package/dist/types/src/components/PullRequestOverview/index.d.ts.map +1 -0
  193. package/dist/types/src/components/PullRequestStatus/PullRequestStatus.d.ts +20 -0
  194. package/dist/types/src/components/PullRequestStatus/PullRequestStatus.d.ts.map +1 -0
  195. package/dist/types/src/components/PullRequestStatus/index.d.ts +2 -0
  196. package/dist/types/src/components/PullRequestStatus/index.d.ts.map +1 -0
  197. package/dist/types/src/components/WalkthroughView/WalkthroughView.d.ts +18 -0
  198. package/dist/types/src/components/WalkthroughView/WalkthroughView.d.ts.map +1 -0
  199. package/dist/types/src/components/WalkthroughView/extensions.d.ts +16 -0
  200. package/dist/types/src/components/WalkthroughView/extensions.d.ts.map +1 -0
  201. package/dist/types/src/components/WalkthroughView/index.d.ts +3 -0
  202. package/dist/types/src/components/WalkthroughView/index.d.ts.map +1 -0
  203. package/dist/types/src/components/index.d.ts +5 -8
  204. package/dist/types/src/components/index.d.ts.map +1 -1
  205. package/dist/types/src/constants.d.ts +7 -0
  206. package/dist/types/src/constants.d.ts.map +1 -0
  207. package/dist/types/src/containers/ImportPullRequestDialog/ImportPullRequestDialog.d.ts +6 -0
  208. package/dist/types/src/containers/ImportPullRequestDialog/ImportPullRequestDialog.d.ts.map +1 -0
  209. package/dist/types/src/containers/ImportPullRequestDialog/index.d.ts +3 -0
  210. package/dist/types/src/containers/ImportPullRequestDialog/index.d.ts.map +1 -0
  211. package/dist/types/src/containers/PullRequestArticle/PullRequestArticle.d.ts +15 -0
  212. package/dist/types/src/containers/PullRequestArticle/PullRequestArticle.d.ts.map +1 -0
  213. package/dist/types/src/containers/PullRequestArticle/failure.d.ts +10 -0
  214. package/dist/types/src/containers/PullRequestArticle/failure.d.ts.map +1 -0
  215. package/dist/types/src/containers/PullRequestArticle/failure.test.d.ts +2 -0
  216. package/dist/types/src/containers/PullRequestArticle/failure.test.d.ts.map +1 -0
  217. package/dist/types/src/containers/PullRequestArticle/index.d.ts +2 -0
  218. package/dist/types/src/containers/PullRequestArticle/index.d.ts.map +1 -0
  219. package/dist/types/src/containers/PullRequestCardMenu/PullRequestCardMenu.d.ts +14 -0
  220. package/dist/types/src/containers/PullRequestCardMenu/PullRequestCardMenu.d.ts.map +1 -0
  221. package/dist/types/src/containers/PullRequestCardMenu/index.d.ts +2 -0
  222. package/dist/types/src/containers/PullRequestCardMenu/index.d.ts.map +1 -0
  223. package/dist/types/src/containers/PullRequestsArticle/PullRequestsArticle.d.ts +13 -0
  224. package/dist/types/src/containers/PullRequestsArticle/PullRequestsArticle.d.ts.map +1 -0
  225. package/dist/types/src/containers/PullRequestsArticle/arrange.d.ts +44 -0
  226. package/dist/types/src/containers/PullRequestsArticle/arrange.d.ts.map +1 -0
  227. package/dist/types/src/containers/PullRequestsArticle/arrange.test.d.ts +2 -0
  228. package/dist/types/src/containers/PullRequestsArticle/arrange.test.d.ts.map +1 -0
  229. package/dist/types/src/containers/PullRequestsArticle/format.d.ts +3 -0
  230. package/dist/types/src/containers/PullRequestsArticle/format.d.ts.map +1 -0
  231. package/dist/types/src/containers/PullRequestsArticle/index.d.ts +2 -0
  232. package/dist/types/src/containers/PullRequestsArticle/index.d.ts.map +1 -0
  233. package/dist/types/src/containers/WalkthroughArticle/WalkthroughArticle.d.ts +13 -0
  234. package/dist/types/src/containers/WalkthroughArticle/WalkthroughArticle.d.ts.map +1 -0
  235. package/dist/types/src/containers/WalkthroughArticle/index.d.ts +2 -0
  236. package/dist/types/src/containers/WalkthroughArticle/index.d.ts.map +1 -0
  237. package/dist/types/src/containers/index.d.ts +7 -0
  238. package/dist/types/src/containers/index.d.ts.map +1 -0
  239. package/dist/types/src/errors.d.ts +157 -0
  240. package/dist/types/src/errors.d.ts.map +1 -0
  241. package/dist/types/src/extensions/index.d.ts +3 -0
  242. package/dist/types/src/extensions/index.d.ts.map +1 -0
  243. package/dist/types/src/extensions/links.d.ts +21 -0
  244. package/dist/types/src/extensions/links.d.ts.map +1 -0
  245. package/dist/types/src/extensions/links.test.d.ts +2 -0
  246. package/dist/types/src/extensions/links.test.d.ts.map +1 -0
  247. package/dist/types/src/extensions/references.d.ts +23 -0
  248. package/dist/types/src/extensions/references.d.ts.map +1 -0
  249. package/dist/types/src/extensions/references.test.d.ts +2 -0
  250. package/dist/types/src/extensions/references.test.d.ts.map +1 -0
  251. package/dist/types/src/github-link.d.ts +29 -0
  252. package/dist/types/src/github-link.d.ts.map +1 -0
  253. package/dist/types/src/hooks/index.d.ts +5 -2
  254. package/dist/types/src/hooks/index.d.ts.map +1 -1
  255. package/dist/types/src/hooks/useOpenObject.d.ts +9 -0
  256. package/dist/types/src/hooks/useOpenObject.d.ts.map +1 -0
  257. package/dist/types/src/hooks/usePullRequestChecks.d.ts +10 -0
  258. package/dist/types/src/hooks/usePullRequestChecks.d.ts.map +1 -0
  259. package/dist/types/src/hooks/usePullRequestDiff.d.ts +12 -0
  260. package/dist/types/src/hooks/usePullRequestDiff.d.ts.map +1 -0
  261. package/dist/types/src/hooks/usePullRequestFiles.d.ts +22 -0
  262. package/dist/types/src/hooks/usePullRequestFiles.d.ts.map +1 -0
  263. package/dist/types/src/hooks/useSyncPullRequest.d.ts +10 -0
  264. package/dist/types/src/hooks/useSyncPullRequest.d.ts.map +1 -0
  265. package/dist/types/src/index.d.ts +3 -3
  266. package/dist/types/src/index.d.ts.map +1 -1
  267. package/dist/types/src/meta.d.ts +34 -11
  268. package/dist/types/src/meta.d.ts.map +1 -1
  269. package/dist/types/src/operations/add-pull-request-comment.d.ts +5 -0
  270. package/dist/types/src/operations/add-pull-request-comment.d.ts.map +1 -0
  271. package/dist/types/src/operations/add-pull-request-review-comment.d.ts +5 -0
  272. package/dist/types/src/operations/add-pull-request-review-comment.d.ts.map +1 -0
  273. package/dist/types/src/operations/generate-walkthrough.d.ts +11 -0
  274. package/dist/types/src/operations/generate-walkthrough.d.ts.map +1 -0
  275. package/dist/types/src/operations/get-pull-request-diff.d.ts +5 -0
  276. package/dist/types/src/operations/get-pull-request-diff.d.ts.map +1 -0
  277. package/dist/types/src/operations/get-pull-request-status.d.ts +5 -0
  278. package/dist/types/src/operations/get-pull-request-status.d.ts.map +1 -0
  279. package/dist/types/src/operations/get-repositories.d.ts +13 -0
  280. package/dist/types/src/operations/get-repositories.d.ts.map +1 -0
  281. package/dist/types/src/operations/import-pull-request-from-snapshot.d.ts +12 -0
  282. package/dist/types/src/operations/import-pull-request-from-snapshot.d.ts.map +1 -0
  283. package/dist/types/src/operations/import-pull-request.d.ts +63 -0
  284. package/dist/types/src/operations/import-pull-request.d.ts.map +1 -0
  285. package/dist/types/src/operations/import-pull-request.test.d.ts +2 -0
  286. package/dist/types/src/operations/import-pull-request.test.d.ts.map +1 -0
  287. package/dist/types/src/operations/index.d.ts +3 -0
  288. package/dist/types/src/operations/index.d.ts.map +1 -0
  289. package/dist/types/src/operations/materialize-target.d.ts +12 -0
  290. package/dist/types/src/operations/materialize-target.d.ts.map +1 -0
  291. package/dist/types/src/operations/pull-request.d.ts +48 -0
  292. package/dist/types/src/operations/pull-request.d.ts.map +1 -0
  293. package/dist/types/src/operations/pull-request.test.d.ts +2 -0
  294. package/dist/types/src/operations/pull-request.test.d.ts.map +1 -0
  295. package/dist/types/src/operations/refresh-pull-requests.d.ts +5 -0
  296. package/dist/types/src/operations/refresh-pull-requests.d.ts.map +1 -0
  297. package/dist/types/src/operations/refresh.d.ts +37 -0
  298. package/dist/types/src/operations/refresh.d.ts.map +1 -0
  299. package/dist/types/src/operations/refresh.test.d.ts +2 -0
  300. package/dist/types/src/operations/refresh.test.d.ts.map +1 -0
  301. package/dist/types/src/operations/submit-pull-request-approval.d.ts +5 -0
  302. package/dist/types/src/operations/submit-pull-request-approval.d.ts.map +1 -0
  303. package/dist/types/src/operations/sync-pull-request.d.ts +5 -0
  304. package/dist/types/src/operations/sync-pull-request.d.ts.map +1 -0
  305. package/dist/types/src/operations/sync.d.ts +123 -0
  306. package/dist/types/src/operations/sync.d.ts.map +1 -0
  307. package/dist/types/src/operations/sync.test.d.ts +2 -0
  308. package/dist/types/src/operations/sync.test.d.ts.map +1 -0
  309. package/dist/types/src/plugin.d.ts +4 -0
  310. package/dist/types/src/plugin.d.ts.map +1 -0
  311. package/dist/types/src/plugin.test.d.ts +2 -0
  312. package/dist/types/src/plugin.test.d.ts.map +1 -0
  313. package/dist/types/src/pull-request-body.d.ts +37 -0
  314. package/dist/types/src/pull-request-body.d.ts.map +1 -0
  315. package/dist/types/src/pull-request-body.test.d.ts +2 -0
  316. package/dist/types/src/pull-request-body.test.d.ts.map +1 -0
  317. package/dist/types/src/pull-request.d.ts +28 -0
  318. package/dist/types/src/pull-request.d.ts.map +1 -0
  319. package/dist/types/src/pull-request.test.d.ts +2 -0
  320. package/dist/types/src/pull-request.test.d.ts.map +1 -0
  321. package/dist/types/src/services/github-api.d.ts +332 -0
  322. package/dist/types/src/services/github-api.d.ts.map +1 -0
  323. package/dist/types/src/services/index.d.ts +2 -0
  324. package/dist/types/src/services/index.d.ts.map +1 -0
  325. package/dist/types/src/skills/GitHubSkill.d.ts +12 -0
  326. package/dist/types/src/skills/GitHubSkill.d.ts.map +1 -0
  327. package/dist/types/src/skills/index.d.ts +2 -0
  328. package/dist/types/src/skills/index.d.ts.map +1 -0
  329. package/dist/types/src/stories/Generate.stories.d.ts +27 -0
  330. package/dist/types/src/stories/Generate.stories.d.ts.map +1 -0
  331. package/dist/types/src/stories/Links.stories.d.ts +23 -0
  332. package/dist/types/src/stories/Links.stories.d.ts.map +1 -0
  333. package/dist/types/src/stories/PullRequestArticle.stories.d.ts +359 -0
  334. package/dist/types/src/stories/PullRequestArticle.stories.d.ts.map +1 -0
  335. package/dist/types/src/stories/PullRequestFiles.stories.d.ts +365 -0
  336. package/dist/types/src/stories/PullRequestFiles.stories.d.ts.map +1 -0
  337. package/dist/types/src/stories/PullRequestOverview.stories.d.ts +367 -0
  338. package/dist/types/src/stories/PullRequestOverview.stories.d.ts.map +1 -0
  339. package/dist/types/src/stories/PullRequestsArticle.stories.d.ts +357 -0
  340. package/dist/types/src/stories/PullRequestsArticle.stories.d.ts.map +1 -0
  341. package/dist/types/src/stories/Walkthrough.stories.d.ts +380 -0
  342. package/dist/types/src/stories/Walkthrough.stories.d.ts.map +1 -0
  343. package/dist/types/src/stories/github.d.ts +23 -0
  344. package/dist/types/src/stories/github.d.ts.map +1 -0
  345. package/dist/types/src/stories/github.test.d.ts +2 -0
  346. package/dist/types/src/stories/github.test.d.ts.map +1 -0
  347. package/dist/types/src/stories/walkthrough-fixture.d.ts +8 -0
  348. package/dist/types/src/stories/walkthrough-fixture.d.ts.map +1 -0
  349. package/dist/types/src/testing/fixtures.d.ts +14 -0
  350. package/dist/types/src/testing/fixtures.d.ts.map +1 -0
  351. package/dist/types/src/testing/index.d.ts +4 -0
  352. package/dist/types/src/testing/index.d.ts.map +1 -0
  353. package/dist/types/src/testing/plugin.d.ts +4 -0
  354. package/dist/types/src/testing/plugin.d.ts.map +1 -0
  355. package/dist/types/src/testing/pull-request-13348.d.ts +6 -0
  356. package/dist/types/src/testing/pull-request-13348.d.ts.map +1 -0
  357. package/dist/types/src/translations.d.ts +339 -53
  358. package/dist/types/src/translations.d.ts.map +1 -1
  359. package/dist/types/src/types/GitHubCapabilities.d.ts +13 -0
  360. package/dist/types/src/types/GitHubCapabilities.d.ts.map +1 -0
  361. package/dist/types/src/types/GitHubEvents.d.ts +8 -0
  362. package/dist/types/src/types/GitHubEvents.d.ts.map +1 -0
  363. package/dist/types/src/types/GitHubOperation.d.ts +281 -0
  364. package/dist/types/src/types/GitHubOperation.d.ts.map +1 -0
  365. package/dist/types/src/types/PullRequestsView.d.ts +35 -0
  366. package/dist/types/src/types/PullRequestsView.d.ts.map +1 -0
  367. package/dist/types/src/types/Walkthrough.d.ts +31 -0
  368. package/dist/types/src/types/Walkthrough.d.ts.map +1 -0
  369. package/dist/types/src/types/Walkthrough.test.d.ts +2 -0
  370. package/dist/types/src/types/Walkthrough.test.d.ts.map +1 -0
  371. package/dist/types/src/types/index.d.ts +5 -0
  372. package/dist/types/src/types/index.d.ts.map +1 -0
  373. package/dist/types/src/walkthrough/fill.d.ts +28 -0
  374. package/dist/types/src/walkthrough/fill.d.ts.map +1 -0
  375. package/dist/types/src/walkthrough/fill.test.d.ts +2 -0
  376. package/dist/types/src/walkthrough/fill.test.d.ts.map +1 -0
  377. package/dist/types/src/walkthrough/generate.d.ts +67 -0
  378. package/dist/types/src/walkthrough/generate.d.ts.map +1 -0
  379. package/dist/types/src/walkthrough/generate.test.d.ts +2 -0
  380. package/dist/types/src/walkthrough/generate.test.d.ts.map +1 -0
  381. package/dist/types/src/walkthrough/generated.d.ts +20 -0
  382. package/dist/types/src/walkthrough/generated.d.ts.map +1 -0
  383. package/dist/types/src/walkthrough/generated.test.d.ts +2 -0
  384. package/dist/types/src/walkthrough/generated.test.d.ts.map +1 -0
  385. package/dist/types/src/walkthrough/headings.d.ts +8 -0
  386. package/dist/types/src/walkthrough/headings.d.ts.map +1 -0
  387. package/dist/types/src/walkthrough/headings.test.d.ts +2 -0
  388. package/dist/types/src/walkthrough/headings.test.d.ts.map +1 -0
  389. package/dist/types/src/walkthrough/index.d.ts +9 -0
  390. package/dist/types/src/walkthrough/index.d.ts.map +1 -0
  391. package/dist/types/src/walkthrough/patch.d.ts +48 -0
  392. package/dist/types/src/walkthrough/patch.d.ts.map +1 -0
  393. package/dist/types/src/walkthrough/plan.d.ts +55 -0
  394. package/dist/types/src/walkthrough/plan.d.ts.map +1 -0
  395. package/dist/types/src/walkthrough/plan.test.d.ts +2 -0
  396. package/dist/types/src/walkthrough/plan.test.d.ts.map +1 -0
  397. package/dist/types/src/walkthrough/prompt.d.ts +33 -0
  398. package/dist/types/src/walkthrough/prompt.d.ts.map +1 -0
  399. package/dist/types/src/walkthrough/prompt.test.d.ts +2 -0
  400. package/dist/types/src/walkthrough/prompt.test.d.ts.map +1 -0
  401. package/dist/types/src/walkthrough/score.d.ts +43 -0
  402. package/dist/types/src/walkthrough/score.d.ts.map +1 -0
  403. package/dist/types/src/walkthrough/score.test.d.ts +2 -0
  404. package/dist/types/src/walkthrough/score.test.d.ts.map +1 -0
  405. package/dist/types/tsconfig.tsbuildinfo +1 -0
  406. package/dx.config.ts +39 -0
  407. package/package.json +167 -48
  408. package/src/Extensions.ts +7 -0
  409. package/src/GitHubPlugin.ts +15 -0
  410. package/src/GitHubPlugin.workerd.test.ts +23 -0
  411. package/src/approval.test.ts +40 -0
  412. package/src/approval.ts +39 -0
  413. package/src/capabilities/app-graph-builder.ts +47 -0
  414. package/src/capabilities/connector.ts +95 -0
  415. package/src/capabilities/gen/browser.ts +82 -0
  416. package/src/capabilities/gen/node.ts +43 -0
  417. package/src/capabilities/gen/tauri.ts +82 -0
  418. package/src/capabilities/gen/workerd.ts +43 -0
  419. package/src/capabilities/index.ts +71 -0
  420. package/src/capabilities/link-resolver.ts +137 -0
  421. package/src/capabilities/markdown-extension.ts +146 -0
  422. package/src/capabilities/operation-handler.ts +16 -0
  423. package/src/capabilities/page-action.ts +32 -0
  424. package/src/capabilities/react-surface.ts +98 -0
  425. package/src/capabilities/schema.ts +16 -0
  426. package/src/capabilities/skill-definition.ts +14 -0
  427. package/src/cards/GitHubCard.stories.tsx +165 -0
  428. package/src/cards/GitHubCard.tsx +93 -0
  429. package/src/cards/PullRequestCard.tsx +23 -0
  430. package/src/cards/index.ts +6 -0
  431. package/src/components/CommentComposer/CommentComposer.tsx +109 -0
  432. package/src/components/CommentComposer/index.ts +5 -0
  433. package/src/components/PullRequestFiles/DiffStat.tsx +15 -0
  434. package/src/components/PullRequestFiles/FileTree.tsx +102 -0
  435. package/src/components/PullRequestFiles/PullRequestFiles.tsx +87 -0
  436. package/src/components/PullRequestFiles/files.test.ts +59 -0
  437. package/src/components/PullRequestFiles/files.ts +115 -0
  438. package/src/components/PullRequestFiles/index.ts +8 -0
  439. package/src/components/PullRequestOverview/ArtifactPill.tsx +82 -0
  440. package/src/components/PullRequestOverview/CheckRunList.test.ts +29 -0
  441. package/src/components/PullRequestOverview/CheckRunList.tsx +141 -0
  442. package/src/components/PullRequestOverview/PullRequestDetails.tsx +15 -0
  443. package/src/components/PullRequestOverview/PullRequestOverview.tsx +110 -0
  444. package/src/components/PullRequestOverview/RelatedCards.tsx +147 -0
  445. package/src/components/PullRequestOverview/index.ts +9 -0
  446. package/src/components/PullRequestStatus/PullRequestStatus.tsx +84 -0
  447. package/src/components/PullRequestStatus/index.ts +5 -0
  448. package/src/components/WalkthroughView/WalkthroughView.tsx +62 -0
  449. package/src/components/WalkthroughView/extensions.ts +53 -0
  450. package/src/components/WalkthroughView/index.ts +6 -0
  451. package/src/components/index.ts +6 -9
  452. package/src/constants.ts +12 -0
  453. package/src/containers/ImportPullRequestDialog/ImportPullRequestDialog.tsx +160 -0
  454. package/src/containers/ImportPullRequestDialog/index.ts +7 -0
  455. package/src/containers/PullRequestArticle/PullRequestArticle.tsx +573 -0
  456. package/src/containers/PullRequestArticle/failure.test.ts +42 -0
  457. package/src/containers/PullRequestArticle/failure.ts +16 -0
  458. package/src/containers/PullRequestArticle/index.ts +5 -0
  459. package/src/containers/PullRequestCardMenu/PullRequestCardMenu.tsx +134 -0
  460. package/src/containers/PullRequestCardMenu/index.ts +5 -0
  461. package/src/containers/PullRequestsArticle/PullRequestsArticle.tsx +361 -0
  462. package/src/containers/PullRequestsArticle/arrange.test.ts +122 -0
  463. package/src/containers/PullRequestsArticle/arrange.ts +245 -0
  464. package/src/containers/PullRequestsArticle/format.ts +31 -0
  465. package/src/containers/PullRequestsArticle/index.ts +5 -0
  466. package/src/containers/WalkthroughArticle/WalkthroughArticle.tsx +31 -0
  467. package/src/containers/WalkthroughArticle/index.ts +5 -0
  468. package/src/containers/index.ts +11 -0
  469. package/src/errors.ts +61 -0
  470. package/src/extensions/index.ts +6 -0
  471. package/src/extensions/links.test.ts +133 -0
  472. package/src/extensions/links.ts +91 -0
  473. package/src/extensions/references.test.ts +83 -0
  474. package/src/extensions/references.ts +100 -0
  475. package/src/github-link.ts +70 -0
  476. package/src/hooks/index.ts +6 -3
  477. package/src/hooks/useOpenObject.ts +48 -0
  478. package/src/hooks/usePullRequestChecks.ts +81 -0
  479. package/src/hooks/usePullRequestDiff.ts +57 -0
  480. package/src/hooks/usePullRequestFiles.ts +98 -0
  481. package/src/hooks/useSyncPullRequest.ts +51 -0
  482. package/src/index.ts +4 -6
  483. package/src/meta.ts +8 -13
  484. package/src/operations/add-pull-request-comment.ts +31 -0
  485. package/src/operations/add-pull-request-review-comment.ts +32 -0
  486. package/src/operations/generate-walkthrough.ts +124 -0
  487. package/src/operations/get-pull-request-diff.ts +37 -0
  488. package/src/operations/get-pull-request-status.ts +44 -0
  489. package/src/operations/get-repositories.ts +53 -0
  490. package/src/operations/import-pull-request-from-snapshot.ts +48 -0
  491. package/src/operations/import-pull-request.test.ts +151 -0
  492. package/src/operations/import-pull-request.ts +149 -0
  493. package/src/operations/index.ts +30 -0
  494. package/src/operations/materialize-target.ts +60 -0
  495. package/src/operations/pull-request.test.ts +120 -0
  496. package/src/operations/pull-request.ts +141 -0
  497. package/src/operations/refresh-pull-requests.ts +69 -0
  498. package/src/operations/refresh.test.ts +112 -0
  499. package/src/operations/refresh.ts +111 -0
  500. package/src/operations/submit-pull-request-approval.ts +41 -0
  501. package/src/operations/sync-pull-request.ts +34 -0
  502. package/src/operations/sync.test.ts +453 -0
  503. package/src/operations/sync.ts +807 -0
  504. package/src/plugin.test.ts +40 -0
  505. package/src/plugin.ts +37 -0
  506. package/src/pull-request-body.test.ts +61 -0
  507. package/src/pull-request-body.ts +144 -0
  508. package/src/pull-request.test.ts +67 -0
  509. package/src/pull-request.ts +80 -0
  510. package/src/services/github-api.ts +735 -0
  511. package/src/services/index.ts +5 -0
  512. package/src/skills/GitHubSkill.ts +46 -0
  513. package/src/skills/index.ts +5 -0
  514. package/src/stories/Generate.stories.tsx +152 -0
  515. package/src/stories/Links.stories.tsx +153 -0
  516. package/src/stories/PullRequestArticle.stories.tsx +107 -0
  517. package/src/stories/PullRequestFiles.stories.tsx +69 -0
  518. package/src/stories/PullRequestOverview.stories.tsx +114 -0
  519. package/src/stories/PullRequestsArticle.stories.tsx +170 -0
  520. package/src/stories/Walkthrough.stories.tsx +110 -0
  521. package/src/stories/github.test.ts +65 -0
  522. package/src/stories/github.ts +70 -0
  523. package/src/stories/walkthrough-fixture.ts +115 -0
  524. package/src/testing/fixtures.ts +99 -0
  525. package/src/testing/index.ts +7 -0
  526. package/src/testing/plugin.ts +25 -0
  527. package/src/testing/pull-request-13348.ts +104 -0
  528. package/src/testing/pull-request-13363.patch +2981 -0
  529. package/src/translations.ts +135 -63
  530. package/src/types/GitHubCapabilities.ts +27 -0
  531. package/src/types/GitHubEvents.ts +16 -0
  532. package/src/types/GitHubOperation.ts +397 -0
  533. package/src/types/PullRequestsView.ts +45 -0
  534. package/src/types/Walkthrough.test.ts +75 -0
  535. package/src/types/Walkthrough.ts +66 -0
  536. package/src/types/index.ts +8 -0
  537. package/src/vite-env.d.ts +15 -0
  538. package/src/walkthrough/fill.test.ts +337 -0
  539. package/src/walkthrough/fill.ts +246 -0
  540. package/src/walkthrough/generate.test.ts +219 -0
  541. package/src/walkthrough/generate.ts +248 -0
  542. package/src/walkthrough/generated.test.ts +70 -0
  543. package/src/walkthrough/generated.ts +70 -0
  544. package/src/walkthrough/headings.test.ts +40 -0
  545. package/src/walkthrough/headings.ts +39 -0
  546. package/src/walkthrough/index.ts +12 -0
  547. package/src/walkthrough/patch.ts +154 -0
  548. package/src/walkthrough/plan.test.ts +178 -0
  549. package/src/walkthrough/plan.ts +251 -0
  550. package/src/walkthrough/prompt.test.ts +100 -0
  551. package/src/walkthrough/prompt.ts +147 -0
  552. package/src/walkthrough/score.test.ts +272 -0
  553. package/src/walkthrough/score.ts +430 -0
  554. package/README.md +0 -15
  555. package/dist/lib/browser/chunk-S4MPSBA5.mjs +0 -21
  556. package/dist/lib/browser/chunk-S4MPSBA5.mjs.map +0 -7
  557. package/dist/lib/browser/index.css +0 -7
  558. package/dist/lib/browser/index.css.map +0 -7
  559. package/dist/lib/browser/index.mjs +0 -1535
  560. package/dist/lib/browser/index.mjs.map +0 -7
  561. package/dist/lib/browser/meta.json +0 -1
  562. package/dist/lib/browser/meta.mjs +0 -11
  563. package/dist/lib/browser/meta.mjs.map +0 -7
  564. package/dist/types/src/GithubPlugin.d.ts +0 -4
  565. package/dist/types/src/GithubPlugin.d.ts.map +0 -1
  566. package/dist/types/src/components/EmbeddedMain/EmbeddedMain.d.ts +0 -4
  567. package/dist/types/src/components/EmbeddedMain/EmbeddedMain.d.ts.map +0 -1
  568. package/dist/types/src/components/EmbeddedMain/GfmPreview.d.ts +0 -9
  569. package/dist/types/src/components/EmbeddedMain/GfmPreview.d.ts.map +0 -1
  570. package/dist/types/src/components/EmbeddedMain/index.d.ts +0 -2
  571. package/dist/types/src/components/EmbeddedMain/index.d.ts.map +0 -1
  572. package/dist/types/src/components/ExportDialog.d.ts +0 -8
  573. package/dist/types/src/components/ExportDialog.d.ts.map +0 -1
  574. package/dist/types/src/components/GithubApiProviders/GitHubSettings.d.ts +0 -3
  575. package/dist/types/src/components/GithubApiProviders/GitHubSettings.d.ts.map +0 -1
  576. package/dist/types/src/components/GithubApiProviders/OctokitProvider.d.ts +0 -15
  577. package/dist/types/src/components/GithubApiProviders/OctokitProvider.d.ts.map +0 -1
  578. package/dist/types/src/components/GithubApiProviders/index.d.ts +0 -3
  579. package/dist/types/src/components/GithubApiProviders/index.d.ts.map +0 -1
  580. package/dist/types/src/components/GithubEchoResolverProviders/DocumentTreeItem.d.ts +0 -6
  581. package/dist/types/src/components/GithubEchoResolverProviders/DocumentTreeItem.d.ts.map +0 -1
  582. package/dist/types/src/components/GithubEchoResolverProviders/ResolverContext.d.ts +0 -7
  583. package/dist/types/src/components/GithubEchoResolverProviders/ResolverContext.d.ts.map +0 -1
  584. package/dist/types/src/components/GithubEchoResolverProviders/ResolverDialog.d.ts +0 -6
  585. package/dist/types/src/components/GithubEchoResolverProviders/ResolverDialog.d.ts.map +0 -1
  586. package/dist/types/src/components/GithubEchoResolverProviders/ResolverProps.d.ts +0 -16
  587. package/dist/types/src/components/GithubEchoResolverProviders/ResolverProps.d.ts.map +0 -1
  588. package/dist/types/src/components/GithubEchoResolverProviders/ResolverTree.d.ts +0 -3
  589. package/dist/types/src/components/GithubEchoResolverProviders/ResolverTree.d.ts.map +0 -1
  590. package/dist/types/src/components/GithubEchoResolverProviders/SpacePickerTreeItem.d.ts +0 -11
  591. package/dist/types/src/components/GithubEchoResolverProviders/SpacePickerTreeItem.d.ts.map +0 -1
  592. package/dist/types/src/components/GithubEchoResolverProviders/index.d.ts +0 -3
  593. package/dist/types/src/components/GithubEchoResolverProviders/index.d.ts.map +0 -1
  594. package/dist/types/src/components/GithubEchoResolverProviders/spaceResolvers.d.ts +0 -6
  595. package/dist/types/src/components/GithubEchoResolverProviders/spaceResolvers.d.ts.map +0 -1
  596. package/dist/types/src/components/ImportDialog.d.ts +0 -7
  597. package/dist/types/src/components/ImportDialog.d.ts.map +0 -1
  598. package/dist/types/src/components/Issue.d.ts +0 -5
  599. package/dist/types/src/components/Issue.d.ts.map +0 -1
  600. package/dist/types/src/components/Loading/Loading.d.ts +0 -15
  601. package/dist/types/src/components/Loading/Loading.d.ts.map +0 -1
  602. package/dist/types/src/components/Loading/Loading.stories.d.ts +0 -40
  603. package/dist/types/src/components/Loading/Loading.stories.d.ts.map +0 -1
  604. package/dist/types/src/components/Loading/index.d.ts +0 -2
  605. package/dist/types/src/components/Loading/index.d.ts.map +0 -1
  606. package/dist/types/src/components/MarkdownActions.d.ts +0 -7
  607. package/dist/types/src/components/MarkdownActions.d.ts.map +0 -1
  608. package/dist/types/src/components/UrlDialog.d.ts +0 -6
  609. package/dist/types/src/components/UrlDialog.d.ts.map +0 -1
  610. package/dist/types/src/hooks/useDocGhId.d.ts +0 -6
  611. package/dist/types/src/hooks/useDocGhId.d.ts.map +0 -1
  612. package/dist/types/src/hooks/useGhIdFromUrl.d.ts +0 -2
  613. package/dist/types/src/hooks/useGhIdFromUrl.d.ts.map +0 -1
  614. package/dist/types/src/types.d.ts +0 -30
  615. package/dist/types/src/types.d.ts.map +0 -1
  616. package/src/GithubPlugin.tsx +0 -127
  617. package/src/components/EmbeddedMain/EmbeddedMain.tsx +0 -294
  618. package/src/components/EmbeddedMain/GfmPreview.tsx +0 -110
  619. package/src/components/EmbeddedMain/embedded.css +0 -3
  620. package/src/components/EmbeddedMain/index.ts +0 -5
  621. package/src/components/ExportDialog.tsx +0 -157
  622. package/src/components/GithubApiProviders/GitHubSettings.tsx +0 -72
  623. package/src/components/GithubApiProviders/OctokitProvider.tsx +0 -60
  624. package/src/components/GithubApiProviders/index.ts +0 -6
  625. package/src/components/GithubEchoResolverProviders/DocumentTreeItem.tsx +0 -26
  626. package/src/components/GithubEchoResolverProviders/ResolverContext.tsx +0 -137
  627. package/src/components/GithubEchoResolverProviders/ResolverDialog.tsx +0 -34
  628. package/src/components/GithubEchoResolverProviders/ResolverProps.ts +0 -23
  629. package/src/components/GithubEchoResolverProviders/ResolverTree.tsx +0 -86
  630. package/src/components/GithubEchoResolverProviders/SpacePickerTreeItem.tsx +0 -105
  631. package/src/components/GithubEchoResolverProviders/index.ts +0 -6
  632. package/src/components/GithubEchoResolverProviders/spaceResolvers.ts +0 -86
  633. package/src/components/ImportDialog.tsx +0 -72
  634. package/src/components/Issue.tsx +0 -62
  635. package/src/components/Loading/Loading.stories.tsx +0 -32
  636. package/src/components/Loading/Loading.tsx +0 -70
  637. package/src/components/Loading/index.ts +0 -5
  638. package/src/components/MarkdownActions.tsx +0 -136
  639. package/src/components/UrlDialog.tsx +0 -52
  640. package/src/hooks/useDocGhId.ts +0 -38
  641. package/src/hooks/useGhIdFromUrl.ts +0 -26
  642. package/src/types.ts +0 -51
@@ -0,0 +1,60 @@
1
+ //
2
+ // Copyright 2026 DXOS.org
3
+ //
4
+
5
+ import * as Effect from 'effect/Effect';
6
+
7
+ import * as Operation from '@dxos/compute/Operation';
8
+ import { Database, Filter, Obj, Query, Ref } from '@dxos/echo';
9
+ import { TaskSet } from '@dxos/types';
10
+
11
+ import { GitHubOperation } from '#types';
12
+
13
+ import { GITHUB_SOURCE } from '../constants.ts';
14
+
15
+ const fkFor = (id: string) => ({ source: GITHUB_SOURCE, id });
16
+
17
+ /**
18
+ * Find-or-create the empty local root Project for a GitHub repo so a `Cursor`
19
+ * can reference it as its `spec.target`. Idempotent: keyed by the repo's
20
+ * GitHub foreign id (`remoteTarget.id`), it returns the existing Project
21
+ * when one already carries that key. The repo's data is filled in lazily by the
22
+ * sync operation; here we only stamp the foreign key + a display name.
23
+ */
24
+ const handler: Operation.WithHandler<typeof GitHubOperation.MaterializeGitHubTarget> =
25
+ GitHubOperation.MaterializeGitHubTarget.pipe(
26
+ Operation.withHandler(
27
+ Effect.fnUntraced(function* ({ connection, remoteTarget }) {
28
+ if (!remoteTarget) {
29
+ return yield* Effect.die(new Error('GitHub materializeTarget requires a remoteTarget (repo descriptor).'));
30
+ }
31
+ // TODO(wittjosiah): the operation should just depend on `Database.Service` and
32
+ // have it provided by the OperationInvoker — composer's invoker is wired
33
+ // without a `databaseResolver`, so we derive the db from the connection ref's
34
+ // target and provide `Database.layer(db)` ourselves.
35
+ const db = connection.target ? Obj.getDatabase(connection.target) : undefined;
36
+ if (!db) {
37
+ return yield* Effect.die(new Error('No database for connection ref.'));
38
+ }
39
+
40
+ return yield* Effect.gen(function* () {
41
+ const existing = yield* Database.query(
42
+ Query.select(Filter.foreignKeys(TaskSet.TaskSet, [fkFor(remoteTarget.id)])),
43
+ ).run;
44
+ if (existing.length > 0) {
45
+ return { target: Ref.make(existing[0]) };
46
+ }
47
+
48
+ const created = yield* Database.add(
49
+ TaskSet.make({
50
+ [Obj.Meta]: { keys: [fkFor(remoteTarget.id)] },
51
+ name: remoteTarget.name,
52
+ }),
53
+ );
54
+ return { target: Ref.make(created) };
55
+ }).pipe(Effect.provide(Database.layer(db)));
56
+ }),
57
+ ),
58
+ );
59
+
60
+ export default handler;
@@ -0,0 +1,120 @@
1
+ //
2
+ // Copyright 2026 DXOS.org
3
+ //
4
+
5
+ import { describe, expect, test } from 'vitest';
6
+
7
+ import { summarizeCheckRuns, summarizeReviews, toCheckRun } from './pull-request.ts';
8
+
9
+ describe('summarizeCheckRuns', () => {
10
+ test('no runs is none', () => {
11
+ expect(summarizeCheckRuns([])).toEqual({ ci: 'none', checks: { total: 0, passed: 0, failed: 0, pending: 0 } });
12
+ });
13
+
14
+ test('all completed without failure is success, skipped and neutral included', () => {
15
+ const { ci, checks } = summarizeCheckRuns([
16
+ { name: 'build', status: 'completed', conclusion: 'success' },
17
+ { name: 'lint', status: 'completed', conclusion: 'skipped' },
18
+ { name: 'docs', status: 'completed', conclusion: 'neutral' },
19
+ ]);
20
+ expect(ci).toEqual('success');
21
+ expect(checks).toEqual({ total: 3, passed: 3, failed: 0, pending: 0 });
22
+ });
23
+
24
+ test('an unfinished run is pending', () => {
25
+ const { ci } = summarizeCheckRuns([
26
+ { name: 'build', status: 'completed', conclusion: 'success' },
27
+ { name: 'test', status: 'in_progress', conclusion: null },
28
+ ]);
29
+ expect(ci).toEqual('pending');
30
+ });
31
+
32
+ test('a stale run does not count as passed', () => {
33
+ const { ci, checks } = summarizeCheckRuns([
34
+ { name: 'build', status: 'completed', conclusion: 'success' },
35
+ { name: 'test', status: 'completed', conclusion: 'stale' },
36
+ ]);
37
+ expect(ci).toEqual('failure');
38
+ expect(checks).toEqual({ total: 2, passed: 1, failed: 1, pending: 0 });
39
+ });
40
+
41
+ test('a failure wins over pending runs', () => {
42
+ const { ci, checks } = summarizeCheckRuns([
43
+ { name: 'build', status: 'completed', conclusion: 'timed_out' },
44
+ { name: 'test', status: 'queued' },
45
+ ]);
46
+ expect(ci).toEqual('failure');
47
+ expect(checks).toEqual({ total: 2, passed: 0, failed: 1, pending: 1 });
48
+ });
49
+ });
50
+
51
+ describe('toCheckRun', () => {
52
+ test('folds a conclusion into the outcome the list shows', () => {
53
+ expect(toCheckRun({ name: 'test', status: 'completed', conclusion: 'timed_out' }).outcome).toEqual('failure');
54
+ expect(toCheckRun({ name: 'cli', status: 'completed', conclusion: 'skipped' }).outcome).toEqual('skipped');
55
+ expect(toCheckRun({ name: 'e2e', status: 'in_progress', conclusion: null }).outcome).toEqual('pending');
56
+ expect(toCheckRun({ name: 'build', status: 'completed', conclusion: 'success' }).outcome).toEqual('success');
57
+ });
58
+
59
+ test("links the provider's page over GitHub's", () => {
60
+ const run = toCheckRun({
61
+ name: 'Check / check',
62
+ status: 'completed',
63
+ conclusion: 'success',
64
+ html_url: 'https://github.com/dxos/dxos/runs/1',
65
+ details_url: 'https://depot.dev/orgs/acme/workflows/abc?job=1',
66
+ started_at: '2026-09-23T12:47:05Z',
67
+ completed_at: '2026-09-23T12:51:13Z',
68
+ });
69
+ expect(run).toEqual({
70
+ name: 'Check / check',
71
+ outcome: 'success',
72
+ conclusion: 'success',
73
+ url: 'https://depot.dev/orgs/acme/workflows/abc?job=1',
74
+ startedAt: '2026-09-23T12:47:05Z',
75
+ completedAt: '2026-09-23T12:51:13Z',
76
+ });
77
+ });
78
+ });
79
+
80
+ describe('summarizeReviews', () => {
81
+ const review = (id: number, login: string, state: string) => ({ id, state, user: { login } });
82
+
83
+ test('no reviews is none', () => {
84
+ expect(summarizeReviews([])).toEqual({ review: 'none', approvals: 0 });
85
+ });
86
+
87
+ test('a comment alone is no verdict', () => {
88
+ expect(summarizeReviews([review(1, 'alice', 'COMMENTED')])).toEqual({ review: 'none', approvals: 0 });
89
+ });
90
+
91
+ test('approvals are counted per reviewer', () => {
92
+ expect(
93
+ summarizeReviews([review(1, 'alice', 'APPROVED'), review(2, 'alice', 'APPROVED'), review(3, 'bob', 'APPROVED')]),
94
+ ).toEqual({ review: 'approved', approvals: 2 });
95
+ });
96
+
97
+ test('an outstanding request for changes outweighs approvals', () => {
98
+ expect(summarizeReviews([review(1, 'alice', 'APPROVED'), review(2, 'bob', 'CHANGES_REQUESTED')])).toEqual({
99
+ review: 'changes_requested',
100
+ approvals: 1,
101
+ });
102
+ });
103
+
104
+ test("a reviewer's later approval clears their request, and a later comment does not undo it", () => {
105
+ expect(
106
+ summarizeReviews([
107
+ review(1, 'bob', 'CHANGES_REQUESTED'),
108
+ review(2, 'bob', 'APPROVED'),
109
+ review(3, 'bob', 'COMMENTED'),
110
+ ]),
111
+ ).toEqual({ review: 'approved', approvals: 1 });
112
+ });
113
+
114
+ test('a dismissed review withdraws the verdict', () => {
115
+ expect(summarizeReviews([review(1, 'bob', 'APPROVED'), review(2, 'bob', 'DISMISSED')])).toEqual({
116
+ review: 'none',
117
+ approvals: 0,
118
+ });
119
+ });
120
+ });
@@ -0,0 +1,141 @@
1
+ //
2
+ // Copyright 2026 DXOS.org
3
+ //
4
+
5
+ import * as Effect from 'effect/Effect';
6
+ import * as Layer from 'effect/Layer';
7
+
8
+ import { Database, Filter, Obj, type Ref } from '@dxos/echo';
9
+ import { Connection } from '@dxos/link';
10
+ import { type PullRequest } from '@dxos/types';
11
+
12
+ import { type GitHubOperation } from '#types';
13
+
14
+ import { GITHUB_PROVIDER_ID } from '../constants.ts';
15
+ import { GitHubPullRequestUnstoredError } from '../errors.ts';
16
+ import { GitHubApi } from '../services/index.ts';
17
+
18
+ /**
19
+ * The GitHub connection whose token requests are sent with: the first one holding a token. Shared by
20
+ * the handlers and by the UI that sends the user to reconnect, so both name the same connection.
21
+ */
22
+ export const githubConnection = () =>
23
+ Effect.gen(function* () {
24
+ const connections = yield* Database.query(Filter.type(Connection.Connection)).run;
25
+ for (const connection of connections) {
26
+ if (connection.connectorId !== GITHUB_PROVIDER_ID) {
27
+ continue;
28
+ }
29
+ const accessToken = yield* Database.load(connection.accessToken);
30
+ if (accessToken.token) {
31
+ return { connection, token: accessToken.token };
32
+ }
33
+ }
34
+
35
+ return undefined;
36
+ });
37
+
38
+ /**
39
+ * The token of {@link githubConnection}, or empty for anonymous — which reaches any public pull
40
+ * request, and is the only option in a space that has not connected GitHub.
41
+ */
42
+ export const githubToken = () => githubConnection().pipe(Effect.map((selected) => selected?.token ?? ''));
43
+
44
+ /**
45
+ * The stored pull request behind an operation's input and credentials for its space.
46
+ *
47
+ * The invoker carries no database resolver, so handlers derive one from the pull request itself; a
48
+ * preview card's in-memory pull request has none and cannot be acted on.
49
+ */
50
+ export const resolvePullRequest = (ref: Ref.Ref<PullRequest.PullRequest>) =>
51
+ Effect.gen(function* () {
52
+ const pullRequest = ref.target;
53
+ const db = pullRequest ? Obj.getDatabase(pullRequest) : undefined;
54
+ if (!pullRequest || !db) {
55
+ return yield* Effect.die(new GitHubPullRequestUnstoredError());
56
+ }
57
+ const token = yield* githubToken().pipe(Effect.provide(Database.layer(db)));
58
+ return { pullRequest, db, credentials: Layer.succeed(GitHubApi.GitHubCredentials, { token }) };
59
+ });
60
+
61
+ // `stale` is a completed run GitHub never re-ran, which branch protection does not count as passing.
62
+ const FAILED_CONCLUSIONS = new Set([
63
+ 'failure',
64
+ 'cancelled',
65
+ 'timed_out',
66
+ 'action_required',
67
+ 'startup_failure',
68
+ 'stale',
69
+ ]);
70
+
71
+ /** One check run as the article lists it: its outcome folded the way {@link summarizeCheckRuns} counts it. */
72
+ export const toCheckRun = (run: GitHubApi.GitHubCheckRun): GitHubOperation.CheckRun => {
73
+ const outcome: GitHubOperation.CheckOutcome =
74
+ run.status !== 'completed'
75
+ ? 'pending'
76
+ : run.conclusion && FAILED_CONCLUSIONS.has(run.conclusion)
77
+ ? 'failure'
78
+ : run.conclusion === 'skipped'
79
+ ? 'skipped'
80
+ : run.conclusion === 'neutral'
81
+ ? 'neutral'
82
+ : 'success';
83
+ const url = run.details_url ?? run.html_url;
84
+ return {
85
+ name: run.name,
86
+ outcome,
87
+ ...(run.conclusion ? { conclusion: run.conclusion } : {}),
88
+ ...(url ? { url } : {}),
89
+ ...(run.started_at ? { startedAt: run.started_at } : {}),
90
+ ...(run.completed_at ? { completedAt: run.completed_at } : {}),
91
+ };
92
+ };
93
+
94
+ /** Folds a commit's check runs into one outcome: any failure fails, then any unfinished run is pending. */
95
+ export const summarizeCheckRuns = (
96
+ runs: readonly GitHubApi.GitHubCheckRun[],
97
+ ): { ci: GitHubOperation.CiState; checks: GitHubOperation.CheckCounts } => {
98
+ const checks = { total: runs.length, passed: 0, failed: 0, pending: 0 };
99
+ for (const run of runs) {
100
+ if (run.status !== 'completed') {
101
+ checks.pending++;
102
+ } else if (run.conclusion && FAILED_CONCLUSIONS.has(run.conclusion)) {
103
+ checks.failed++;
104
+ } else {
105
+ checks.passed++;
106
+ }
107
+ }
108
+
109
+ const ci: GitHubOperation.CiState =
110
+ checks.total === 0 ? 'none' : checks.failed > 0 ? 'failure' : checks.pending > 0 ? 'pending' : 'success';
111
+ return { ci, checks };
112
+ };
113
+
114
+ /** Review states that set a reviewer's standing verdict; a comment leaves the previous one in place. */
115
+ const VERDICT_STATES = new Set(['APPROVED', 'CHANGES_REQUESTED', 'DISMISSED']);
116
+
117
+ /**
118
+ * Folds a pull request's reviews into where they stand, from each reviewer's latest verdict — the
119
+ * way GitHub reads them: a later approval clears that reviewer's request for changes, and a dismissal
120
+ * withdraws whichever verdict it replaced.
121
+ */
122
+ export const summarizeReviews = (
123
+ reviews: readonly GitHubApi.GitHubSubmittedReview[],
124
+ ): { review: GitHubOperation.ReviewState; approvals: number } => {
125
+ const verdicts = new Map<string, string>();
126
+ for (const review of reviews) {
127
+ const login = review.user?.login;
128
+ if (login && VERDICT_STATES.has(review.state)) {
129
+ verdicts.set(login, review.state);
130
+ }
131
+ }
132
+
133
+ const states = [...verdicts.values()];
134
+ const approvals = states.filter((state) => state === 'APPROVED').length;
135
+ const review: GitHubOperation.ReviewState = states.includes('CHANGES_REQUESTED')
136
+ ? 'changes_requested'
137
+ : approvals > 0
138
+ ? 'approved'
139
+ : 'none';
140
+ return { review, approvals };
141
+ };
@@ -0,0 +1,69 @@
1
+ //
2
+ // Copyright 2026 DXOS.org
3
+ //
4
+
5
+ import * as Clock from 'effect/Clock';
6
+ import * as Effect from 'effect/Effect';
7
+ import * as FetchHttpClient from 'effect/http/FetchHttpClient';
8
+
9
+ import * as Operation from '@dxos/compute/Operation';
10
+ import { log } from '@dxos/log';
11
+
12
+ import { GitHubOperation } from '#types';
13
+
14
+ import { githubToken } from './pull-request.ts';
15
+ import { ensureRefreshTrigger, queryInFlightPullRequests, refreshPullRequest, selectRefreshBatch } from './refresh.ts';
16
+
17
+ /** Bounded so a space with many open pull requests does not burst GitHub's secondary rate limit. */
18
+ const REFRESH_CONCURRENCY = 2;
19
+
20
+ /** The hourly `REFRESH_CRON` period, so each scheduled run lands in its own batch window. */
21
+ const REFRESH_INTERVAL_MS = 60 * 60 * 1000;
22
+
23
+ const handler: Operation.WithHandler<typeof GitHubOperation.RefreshPullRequests> =
24
+ GitHubOperation.RefreshPullRequests.pipe(
25
+ Operation.withHandler(
26
+ Effect.fn(function* () {
27
+ // Collapses any duplicate a racing peer created, so the space keeps one schedule.
28
+ yield* ensureRefreshTrigger();
29
+ const inFlight = yield* queryInFlightPullRequests();
30
+ if (inFlight.length === 0) {
31
+ return { checked: 0, updated: 0, failed: 0 };
32
+ }
33
+
34
+ const window = Math.floor((yield* Clock.currentTimeMillis) / REFRESH_INTERVAL_MS);
35
+ const pullRequests = selectRefreshBatch(inFlight, window);
36
+
37
+ const token = yield* githubToken();
38
+ const results = yield* Effect.forEach(
39
+ pullRequests,
40
+ (pullRequest) =>
41
+ // One deleted or unreachable pull request must not fail the run: EDGE disables a trigger
42
+ // after repeated failures, which would stop refreshing every other one.
43
+ refreshPullRequest(pullRequest, token).pipe(
44
+ Effect.map((updated) => (updated.length > 0 ? 'updated' : 'unchanged')),
45
+ Effect.catchDefect((cause) =>
46
+ Effect.sync(() => {
47
+ log.warn('pull request refresh failed', {
48
+ owner: pullRequest.owner,
49
+ repo: pullRequest.repo,
50
+ number: pullRequest.number,
51
+ cause,
52
+ });
53
+ return 'failed' as const;
54
+ }),
55
+ ),
56
+ ),
57
+ { concurrency: REFRESH_CONCURRENCY },
58
+ );
59
+
60
+ return {
61
+ checked: pullRequests.length,
62
+ updated: results.filter((result) => result === 'updated').length,
63
+ failed: results.filter((result) => result === 'failed').length,
64
+ };
65
+ }, Effect.provide(FetchHttpClient.layer)),
66
+ ),
67
+ );
68
+
69
+ export default handler;
@@ -0,0 +1,112 @@
1
+ //
2
+ // Copyright 2026 DXOS.org
3
+ //
4
+
5
+ import * as Effect from 'effect/Effect';
6
+ import { afterEach, beforeEach, describe, test } from 'vitest';
7
+
8
+ import * as Trigger from '@dxos/compute/Trigger';
9
+ import { Database, Filter, Obj, Ref } from '@dxos/echo';
10
+ import { EchoTestBuilder } from '@dxos/echo-client/testing';
11
+ import * as EffectEx from '@dxos/effect/EffectEx';
12
+ import { PullRequest } from '@dxos/types';
13
+
14
+ import { GitHubOperation } from '#types';
15
+
16
+ import { REFRESH_CRON, ensureRefreshTrigger, queryInFlightPullRequests, selectRefreshBatch } from './refresh.ts';
17
+
18
+ describe('pull request refresh', () => {
19
+ let builder: EchoTestBuilder;
20
+
21
+ beforeEach(async () => {
22
+ builder = await new EchoTestBuilder().open();
23
+ });
24
+
25
+ afterEach(async () => {
26
+ await builder.close();
27
+ });
28
+
29
+ const setup = async () => {
30
+ const { db, graph } = await builder.createDatabase();
31
+ graph.registry.add([Trigger.Trigger, PullRequest.PullRequest]);
32
+ return db;
33
+ };
34
+
35
+ const run = <T>(db: Database.Database, effect: Effect.Effect<T, never, Database.Service>) =>
36
+ effect.pipe(Effect.provide(Database.layer(db)), EffectEx.runAndForwardErrors);
37
+
38
+ test('a space gets one remote timer trigger, however often it is ensured', async ({ expect }) => {
39
+ const db = await setup();
40
+ const first = await run(db, ensureRefreshTrigger());
41
+ const second = await run(db, ensureRefreshTrigger());
42
+
43
+ expect(second.id).toBe(first.id);
44
+ const triggers = await db.query(Filter.type(Trigger.Trigger)).run();
45
+ expect(triggers).toHaveLength(1);
46
+ expect(first.remote).toBe(true);
47
+ expect(first.enabled).toBe(true);
48
+ expect(first.spec).toEqual({ kind: 'timer', cron: REFRESH_CRON });
49
+ expect(first.runnable?.uri).toBe(GitHubOperation.RefreshPullRequests.meta.key.toString());
50
+ });
51
+
52
+ test('a disabled refresh trigger is left disabled', async ({ expect }) => {
53
+ const db = await setup();
54
+ const trigger = await run(db, ensureRefreshTrigger());
55
+ Obj.update(trigger, (trigger) => {
56
+ trigger.enabled = false;
57
+ });
58
+
59
+ const ensured = await run(db, ensureRefreshTrigger());
60
+ expect(ensured.id).toBe(trigger.id);
61
+ expect(ensured.enabled).toBe(false);
62
+ });
63
+
64
+ test('only pull requests GitHub can still change are refreshed', async ({ expect }) => {
65
+ const db = await setup();
66
+ const make = (number: number, state: PullRequest.State) =>
67
+ db.add(PullRequest.make({ owner: 'dxos', repo: 'dxos', number, title: `#${number}`, state }));
68
+ make(1, 'open');
69
+ make(2, 'draft');
70
+ make(3, 'closed');
71
+ make(4, 'merged');
72
+
73
+ const inFlight = await run(db, queryInFlightPullRequests());
74
+ expect(inFlight.map((pullRequest) => pullRequest.number).sort()).toEqual([1, 2]);
75
+ });
76
+
77
+ test('duplicates a racing peer created collapse to the lowest-id trigger', async ({ expect }) => {
78
+ const db = await setup();
79
+ const make = () =>
80
+ db.add(
81
+ Trigger.make({
82
+ enabled: true,
83
+ remote: true,
84
+ spec: Trigger.specTimer(REFRESH_CRON),
85
+ runnable: Ref.fromURI(GitHubOperation.RefreshPullRequests.meta.key),
86
+ input: {},
87
+ }),
88
+ );
89
+ const ids = [make().id, make().id].sort();
90
+
91
+ const kept = await run(db, ensureRefreshTrigger());
92
+ expect(kept.id).toBe(ids[0]);
93
+ const triggers = await db.query(Filter.type(Trigger.Trigger)).run();
94
+ expect(triggers.map((trigger) => trigger.id)).toEqual([ids[0]]);
95
+ });
96
+
97
+ test('successive runs walk every open pull request in bounded batches', async ({ expect }) => {
98
+ const db = await setup();
99
+ const pullRequests = Array.from({ length: 5 }, (_, index) =>
100
+ db.add(PullRequest.make({ owner: 'dxos', repo: 'dxos', number: index, title: `#${index}`, state: 'open' })),
101
+ );
102
+
103
+ expect(selectRefreshBatch(pullRequests, 0, 10)).toHaveLength(5);
104
+ const seen = new Set<string>();
105
+ for (let window = 0; window < 3; window++) {
106
+ const batch = selectRefreshBatch(pullRequests, window, 2);
107
+ expect(batch).toHaveLength(2);
108
+ batch.forEach((pullRequest) => seen.add(pullRequest.id));
109
+ }
110
+ expect(seen.size).toBe(5);
111
+ });
112
+ });
@@ -0,0 +1,111 @@
1
+ //
2
+ // Copyright 2026 DXOS.org
3
+ //
4
+
5
+ import * as Effect from 'effect/Effect';
6
+
7
+ import * as Trigger from '@dxos/compute/Trigger';
8
+ import { Database, Filter, Obj, Ref } from '@dxos/echo';
9
+ import { PullRequest } from '@dxos/types';
10
+
11
+ import { GitHubOperation } from '#types';
12
+
13
+ import { pullRequestChanges } from '../pull-request.ts';
14
+ import { fetchPullRequestWithFallback } from './import-pull-request.ts';
15
+
16
+ /**
17
+ * How often the space's refresh trigger polls its open pull requests: hourly, at an off-the-hour minute
18
+ * so the fleet of spaces does not land on EDGE's busiest tick, and because every open pull request
19
+ * costs a GitHub request against the connection's rate limit.
20
+ */
21
+ export const REFRESH_CRON = '17 * * * *';
22
+
23
+ /** States GitHub can still move a pull request out of; a closed or merged one is settled. */
24
+ const IN_FLIGHT_STATES: readonly PullRequest.State[] = ['open', 'draft'];
25
+
26
+ /**
27
+ * Re-read one stored pull request from GitHub and write back the fields that changed.
28
+ *
29
+ * Uses the anonymous fallback, so a public pull request still refreshes behind a revoked token.
30
+ * Returns the names of the changed fields.
31
+ */
32
+ export const refreshPullRequest = Effect.fn('refreshPullRequest')(function* (
33
+ pullRequest: PullRequest.PullRequest,
34
+ token: string,
35
+ ) {
36
+ const pull = yield* fetchPullRequestWithFallback(pullRequest, token);
37
+ const changes = pullRequestChanges(pullRequest, pull);
38
+ const updated = Object.keys(changes);
39
+ if (updated.length > 0) {
40
+ Obj.update(pullRequest, (pullRequest) => {
41
+ Object.assign(pullRequest, changes);
42
+ });
43
+ }
44
+
45
+ return updated;
46
+ });
47
+
48
+ /** Code-unit order, so every peer and EDGE agree on it regardless of locale. */
49
+ const byId = (left: { id: string }, right: { id: string }): number =>
50
+ left.id < right.id ? -1 : left.id > right.id ? 1 : 0;
51
+
52
+ /** Most pull requests one run refreshes, so a run stays within GitHub's rate limit and EDGE's subrequest budget. */
53
+ export const REFRESH_BATCH_SIZE = 20;
54
+
55
+ /**
56
+ * The slice of `pullRequests` the run in window `window` refreshes: consecutive windows walk the list in
57
+ * id order and wrap, so every pull request is refreshed once every `ceil(count / size)` runs without
58
+ * storing a cursor.
59
+ */
60
+ export const selectRefreshBatch = (
61
+ pullRequests: readonly PullRequest.PullRequest[],
62
+ window: number,
63
+ size = REFRESH_BATCH_SIZE,
64
+ ): PullRequest.PullRequest[] => {
65
+ if (pullRequests.length <= size) {
66
+ return [...pullRequests];
67
+ }
68
+ const ordered = [...pullRequests].sort(byId);
69
+ const start = (window * size) % ordered.length;
70
+ return Array.from({ length: size }, (_, index) => ordered[(start + index) % ordered.length]);
71
+ };
72
+
73
+ /** The space's pull requests GitHub may still change. */
74
+ export const queryInFlightPullRequests = () =>
75
+ Database.query(Filter.type(PullRequest.PullRequest)).run.pipe(
76
+ Effect.map((pullRequests) => pullRequests.filter((pullRequest) => IN_FLIGHT_STATES.includes(pullRequest.state))),
77
+ Effect.orDie,
78
+ );
79
+
80
+ const isRefreshTrigger = (trigger: Trigger.Trigger): boolean =>
81
+ trigger.runnable?.uri === GitHubOperation.RefreshPullRequests.meta.key.toString();
82
+
83
+ /**
84
+ * Give the space its one pull-request refresh trigger, unless it has one already — including one the
85
+ * user disabled, which stays disabled.
86
+ *
87
+ * Peers that race to create it each add their own, so every caller converges on the same keeper (the
88
+ * lowest id) and removes the rest. The trigger runs on EDGE, so pull requests keep refreshing while no
89
+ * client has the space open.
90
+ */
91
+ export const ensureRefreshTrigger = Effect.fn('ensureRefreshTrigger')(function* () {
92
+ const triggers = yield* Database.query(Filter.type(Trigger.Trigger)).run.pipe(Effect.orDie);
93
+ const [keeper, ...duplicates] = triggers.filter(isRefreshTrigger).sort(byId);
94
+ for (const duplicate of duplicates) {
95
+ yield* Database.remove(duplicate);
96
+ }
97
+ if (keeper) {
98
+ return keeper;
99
+ }
100
+
101
+ return yield* Database.add(
102
+ Trigger.make({
103
+ enabled: true,
104
+ remote: true,
105
+ spec: Trigger.specTimer(REFRESH_CRON),
106
+ // Statically defined in the registry, so referred to by key rather than copied into the space.
107
+ runnable: Ref.fromURI(GitHubOperation.RefreshPullRequests.meta.key),
108
+ input: {},
109
+ }),
110
+ );
111
+ });
@@ -0,0 +1,41 @@
1
+ //
2
+ // Copyright 2026 DXOS.org
3
+ //
4
+
5
+ import * as Effect from 'effect/Effect';
6
+ import * as FetchHttpClient from 'effect/http/FetchHttpClient';
7
+ import * as Option from 'effect/Option';
8
+
9
+ import * as Operation from '@dxos/compute/Operation';
10
+
11
+ import { GitHubOperation } from '#types';
12
+
13
+ import { approvalCommentBody, isApprovalRefused } from '../approval.ts';
14
+ import { GitHubApi } from '../services/index.ts';
15
+ import { resolvePullRequest } from './pull-request.ts';
16
+
17
+ const handler: Operation.WithHandler<typeof GitHubOperation.SubmitPullRequestApproval> =
18
+ GitHubOperation.SubmitPullRequestApproval.pipe(
19
+ Operation.withHandler(
20
+ Effect.fn(function* ({ pullRequest: ref, body }) {
21
+ const { pullRequest, credentials } = yield* resolvePullRequest(ref);
22
+ const { owner, repo, number } = pullRequest;
23
+ const review = yield* GitHubApi.approvePullRequest(owner, repo, number, body).pipe(
24
+ Effect.provide(credentials),
25
+ Effect.asSome,
26
+ // Only a refusal to review becomes a comment; every other failure stays a failure.
27
+ Effect.catchIf(isApprovalRefused, () => Effect.succeedNone),
28
+ );
29
+ if (Option.isSome(review)) {
30
+ return { reviewId: review.value.id, commented: false };
31
+ }
32
+
33
+ const comment = yield* GitHubApi.createIssueComment(owner, repo, number, approvalCommentBody(body)).pipe(
34
+ Effect.provide(credentials),
35
+ );
36
+ return { commentId: comment.id, url: comment.html_url ?? undefined, commented: true };
37
+ }, Effect.provide(FetchHttpClient.layer)),
38
+ ),
39
+ );
40
+
41
+ export default handler;