@ashlr/hub 3.4.0 → 3.5.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 (304) hide show
  1. package/CHANGELOG.md +107 -1
  2. package/README.md +3 -0
  3. package/dist/build-identity.json +2 -2
  4. package/dist/cli/index.js +11 -0
  5. package/dist/cli/index.js.map +1 -1
  6. package/dist/cli/local-runtime.js +40 -9
  7. package/dist/cli/local-runtime.js.map +1 -1
  8. package/dist/core/fleet/external-skill-audit.js +1 -1
  9. package/dist/core/fleet/external-skill-audit.js.map +1 -1
  10. package/dist/core/local-eval/classify.d.ts +57 -0
  11. package/dist/core/local-eval/classify.js +121 -0
  12. package/dist/core/local-eval/classify.js.map +1 -0
  13. package/dist/core/local-eval/configuration.d.ts +37 -0
  14. package/dist/core/local-eval/configuration.js +171 -0
  15. package/dist/core/local-eval/configuration.js.map +1 -0
  16. package/dist/core/local-eval/index.d.ts +15 -0
  17. package/dist/core/local-eval/index.js +16 -0
  18. package/dist/core/local-eval/index.js.map +1 -0
  19. package/dist/core/local-eval/main.d.ts +31 -0
  20. package/dist/core/local-eval/main.js +174 -0
  21. package/dist/core/local-eval/main.js.map +1 -0
  22. package/dist/core/local-eval/report.d.ts +25 -0
  23. package/dist/core/local-eval/report.js +157 -0
  24. package/dist/core/local-eval/report.js.map +1 -0
  25. package/dist/core/local-eval/runner.d.ts +55 -0
  26. package/dist/core/local-eval/runner.js +290 -0
  27. package/dist/core/local-eval/runner.js.map +1 -0
  28. package/dist/core/local-eval/tasks.d.ts +22 -0
  29. package/dist/core/local-eval/tasks.js +303 -0
  30. package/dist/core/local-eval/tasks.js.map +1 -0
  31. package/dist/core/local-eval/trace.d.ts +67 -0
  32. package/dist/core/local-eval/trace.js +309 -0
  33. package/dist/core/local-eval/trace.js.map +1 -0
  34. package/dist/core/local-eval/types.d.ts +262 -0
  35. package/dist/core/local-eval/types.js +23 -0
  36. package/dist/core/local-eval/types.js.map +1 -0
  37. package/dist/core/local-runtime/llama/anthropic-proxy-host.d.ts +68 -0
  38. package/dist/core/local-runtime/llama/anthropic-proxy-host.js +120 -0
  39. package/dist/core/local-runtime/llama/anthropic-proxy-host.js.map +1 -0
  40. package/dist/core/local-runtime/llama/anthropic-proxy-process.d.ts +15 -0
  41. package/dist/core/local-runtime/llama/anthropic-proxy-process.js +21 -0
  42. package/dist/core/local-runtime/llama/anthropic-proxy-process.js.map +1 -0
  43. package/dist/core/local-runtime/llama/anthropic-proxy.d.ts +2 -1
  44. package/dist/core/local-runtime/llama/anthropic-proxy.js +14 -6
  45. package/dist/core/local-runtime/llama/anthropic-proxy.js.map +1 -1
  46. package/dist/core/local-runtime/llama/anthropic-shim.d.ts +33 -0
  47. package/dist/core/local-runtime/llama/anthropic-shim.js +59 -0
  48. package/dist/core/local-runtime/llama/anthropic-shim.js.map +1 -1
  49. package/dist/core/local-runtime/llama/config.d.ts +123 -6
  50. package/dist/core/local-runtime/llama/config.js +196 -6
  51. package/dist/core/local-runtime/llama/config.js.map +1 -1
  52. package/dist/core/local-runtime/llama/index.d.ts +15 -0
  53. package/dist/core/local-runtime/llama/index.js +13 -0
  54. package/dist/core/local-runtime/llama/index.js.map +1 -1
  55. package/dist/core/local-runtime/llama/paths.d.ts +17 -0
  56. package/dist/core/local-runtime/llama/paths.js +25 -0
  57. package/dist/core/local-runtime/llama/paths.js.map +1 -1
  58. package/dist/core/local-runtime/llama/proxy-invocation.d.ts +101 -0
  59. package/dist/core/local-runtime/llama/proxy-invocation.js +134 -0
  60. package/dist/core/local-runtime/llama/proxy-invocation.js.map +1 -0
  61. package/dist/core/local-runtime/llama/proxy-launchd.d.ts +83 -0
  62. package/dist/core/local-runtime/llama/proxy-launchd.js +216 -0
  63. package/dist/core/local-runtime/llama/proxy-launchd.js.map +1 -0
  64. package/dist/core/local-runtime/llama/shapes.d.ts +2 -1
  65. package/dist/core/local-runtime/llama/shapes.js +2 -1
  66. package/dist/core/local-runtime/llama/shapes.js.map +1 -1
  67. package/dist/core/verse/adapters/claude.js +16 -0
  68. package/dist/core/verse/adapters/claude.js.map +1 -1
  69. package/dist/core/verse/adapters/codex.js +60 -2
  70. package/dist/core/verse/adapters/codex.js.map +1 -1
  71. package/dist/core/verse/adapters/grok.js +13 -0
  72. package/dist/core/verse/adapters/grok.js.map +1 -1
  73. package/dist/core/verse/control-api.d.ts +8 -9
  74. package/dist/core/verse/control-api.js +14 -114
  75. package/dist/core/verse/control-api.js.map +1 -1
  76. package/dist/core/verse/github-api.d.ts +50 -0
  77. package/dist/core/verse/github-api.js +211 -0
  78. package/dist/core/verse/github-api.js.map +1 -0
  79. package/dist/core/verse/github-proposal.d.ts +64 -0
  80. package/dist/core/verse/github-proposal.js +186 -0
  81. package/dist/core/verse/github-proposal.js.map +1 -0
  82. package/dist/core/verse/github-repo.d.ts +104 -0
  83. package/dist/core/verse/github-repo.js +476 -0
  84. package/dist/core/verse/github-repo.js.map +1 -0
  85. package/dist/core/verse/github-types.d.ts +174 -0
  86. package/dist/core/verse/github-types.js +31 -0
  87. package/dist/core/verse/github-types.js.map +1 -0
  88. package/dist/core/verse/mcp-cli-health.d.ts +149 -0
  89. package/dist/core/verse/mcp-cli-health.js +227 -0
  90. package/dist/core/verse/mcp-cli-health.js.map +1 -0
  91. package/dist/core/verse/mcp-control-api.d.ts +68 -0
  92. package/dist/core/verse/mcp-control-api.js +322 -0
  93. package/dist/core/verse/mcp-control-api.js.map +1 -0
  94. package/dist/core/verse/mcp-mutation.d.ts +187 -0
  95. package/dist/core/verse/mcp-mutation.js +471 -0
  96. package/dist/core/verse/mcp-mutation.js.map +1 -0
  97. package/dist/core/verse/mcp-scope.d.ts +114 -0
  98. package/dist/core/verse/mcp-scope.js +149 -0
  99. package/dist/core/verse/mcp-scope.js.map +1 -0
  100. package/dist/core/verse/mcp-seat-view.d.ts +197 -0
  101. package/dist/core/verse/mcp-seat-view.js +322 -0
  102. package/dist/core/verse/mcp-seat-view.js.map +1 -0
  103. package/dist/core/verse/path-guard.d.ts +115 -0
  104. package/dist/core/verse/path-guard.js +171 -0
  105. package/dist/core/verse/path-guard.js.map +1 -0
  106. package/dist/core/verse/seats.js +30 -2
  107. package/dist/core/verse/seats.js.map +1 -1
  108. package/dist/core/verse/session-engine.js +60 -1
  109. package/dist/core/verse/session-engine.js.map +1 -1
  110. package/dist/core/verse/session-store.js +20 -0
  111. package/dist/core/verse/session-store.js.map +1 -1
  112. package/dist/core/verse/types.d.ts +225 -1
  113. package/dist/core/verse/types.js +26 -0
  114. package/dist/core/verse/types.js.map +1 -1
  115. package/dist/core/verse/verse-api.d.ts +16 -1
  116. package/dist/core/verse/verse-api.js +338 -16
  117. package/dist/core/verse/verse-api.js.map +1 -1
  118. package/dist/core/verse/workspaces.d.ts +130 -0
  119. package/dist/core/verse/workspaces.js +501 -0
  120. package/dist/core/verse/workspaces.js.map +1 -0
  121. package/dist/core/web/api.js +23 -0
  122. package/dist/core/web/api.js.map +1 -1
  123. package/dist/core/web/public/next/assets/App-BbVoUCIi.js +7 -0
  124. package/dist/core/web/public/next/assets/App-BbVoUCIi.js.map +1 -0
  125. package/dist/core/web/public/next/assets/App-Cgi6j1Gk.css +1 -0
  126. package/dist/core/web/public/next/assets/ApprovalsSection-BW9iVjUa.js +2 -0
  127. package/dist/core/web/public/next/assets/ApprovalsSection-BW9iVjUa.js.map +1 -0
  128. package/dist/core/web/public/next/assets/ApprovalsSection-Su-NUTis.css +1 -0
  129. package/dist/core/web/public/next/assets/AutonomySection-CRqHUhED.js +2 -0
  130. package/dist/core/web/public/next/assets/AutonomySection-CRqHUhED.js.map +1 -0
  131. package/dist/core/web/public/next/assets/AutonomySection-Cpk_oEhc.css +1 -0
  132. package/dist/core/web/public/next/assets/ChatSection-5irrh6Jw.js +80 -0
  133. package/dist/core/web/public/next/assets/ChatSection-5irrh6Jw.js.map +1 -0
  134. package/dist/core/web/public/next/assets/ChatSection-LQiAn6Eu.css +1 -0
  135. package/dist/core/web/public/next/assets/ConfirmDialog-CXevY3Au.js +2 -0
  136. package/dist/core/web/public/next/assets/ConfirmDialog-CXevY3Au.js.map +1 -0
  137. package/dist/core/web/public/next/assets/{ConfirmDialog-cYuivhCX.css → ConfirmDialog-Dx15x0Ho.css} +1 -1
  138. package/dist/core/web/public/next/assets/Dialog-Bn0CgEGz.js +2 -0
  139. package/dist/core/web/public/next/assets/Dialog-Bn0CgEGz.js.map +1 -0
  140. package/dist/core/web/public/next/assets/Dialog-tQ8kFulD.css +1 -0
  141. package/dist/core/web/public/next/assets/DiffViewer-C8HHTnVE.css +1 -0
  142. package/dist/core/web/public/next/assets/DiffViewer-QKyisN2L.js +7 -0
  143. package/dist/core/web/public/next/assets/DiffViewer-QKyisN2L.js.map +1 -0
  144. package/dist/core/web/public/next/assets/{MutationTokenDialog-jWLLCxWn.css → MutationTokenDialog-CrfJ0PdD.css} +1 -1
  145. package/dist/core/web/public/next/assets/MutationTokenDialog-DbSHPy3w.js +2 -0
  146. package/dist/core/web/public/next/assets/MutationTokenDialog-DbSHPy3w.js.map +1 -0
  147. package/dist/core/web/public/next/assets/ResourcePoolConsoleApp-C-PCgCzo.js +7 -0
  148. package/dist/core/web/public/next/assets/ResourcePoolConsoleApp-C-PCgCzo.js.map +1 -0
  149. package/dist/core/web/public/next/assets/ResourcePoolConsoleApp-CM_8pJs6.css +1 -0
  150. package/dist/core/web/public/next/assets/RouteErrorBoundary-Dw8ZjmkS.js +2 -0
  151. package/dist/core/web/public/next/assets/RouteErrorBoundary-Dw8ZjmkS.js.map +1 -0
  152. package/dist/core/web/public/next/assets/RouteErrorBoundary-ekyMXAK8.css +1 -0
  153. package/dist/core/web/public/next/assets/SettingsSection-BII7TTSD.css +1 -0
  154. package/dist/core/web/public/next/assets/SettingsSection-CWxtTNlD.js +2 -0
  155. package/dist/core/web/public/next/assets/SettingsSection-CWxtTNlD.js.map +1 -0
  156. package/dist/core/web/public/next/assets/UniverseConsoleApp-Bk5HipM0.js +2 -0
  157. package/dist/core/web/public/next/assets/UniverseConsoleApp-Bk5HipM0.js.map +1 -0
  158. package/dist/core/web/public/next/assets/UniverseConsoleApp-Dh7A-hLD.css +1 -0
  159. package/dist/core/web/public/next/assets/UniverseView-Bqa8DH57.css +1 -0
  160. package/dist/core/web/public/next/assets/UniverseView-D8k9q0ce.js +9 -0
  161. package/dist/core/web/public/next/assets/UniverseView-D8k9q0ce.js.map +1 -0
  162. package/dist/core/web/public/next/assets/UsageSection-B2E06ZH1.js +2 -0
  163. package/dist/core/web/public/next/assets/UsageSection-B2E06ZH1.js.map +1 -0
  164. package/dist/core/web/public/next/assets/UsageSection-DwgNOYvi.css +1 -0
  165. package/dist/core/web/public/next/assets/VerseConsoleApp-CRfZUV-T.js +3 -0
  166. package/dist/core/web/public/next/assets/VerseConsoleApp-CRfZUV-T.js.map +1 -0
  167. package/dist/core/web/public/next/assets/VerseConsoleApp-D2E3mU9a.css +1 -0
  168. package/dist/core/web/public/next/assets/charts-CsrtT4rk.css +1 -0
  169. package/dist/core/web/public/next/assets/charts-DSUpczxG.js +2 -0
  170. package/dist/core/web/public/next/assets/charts-DSUpczxG.js.map +1 -0
  171. package/dist/core/web/public/next/assets/fleet-model-ClBbQ0Uj.js +2 -0
  172. package/dist/core/web/public/next/assets/fleet-model-ClBbQ0Uj.js.map +1 -0
  173. package/dist/core/web/public/next/assets/format-BNYWGJat.js +2 -0
  174. package/dist/core/web/public/next/assets/format-BNYWGJat.js.map +1 -0
  175. package/dist/core/web/public/next/assets/global-C4jfYHrj.js +2 -0
  176. package/dist/core/web/public/next/assets/global-C4jfYHrj.js.map +1 -0
  177. package/dist/core/web/public/next/assets/global-D463gG1X.css +1 -0
  178. package/dist/core/web/public/next/assets/icons-BxOX8-XB.js +2 -0
  179. package/dist/core/web/public/next/assets/icons-BxOX8-XB.js.map +1 -0
  180. package/dist/core/web/public/next/assets/index-BMRIET7F.js +11 -0
  181. package/dist/core/web/public/next/assets/index-BMRIET7F.js.map +1 -0
  182. package/dist/core/web/public/next/assets/queries-AxnVa02h.js +2 -0
  183. package/dist/core/web/public/next/assets/queries-AxnVa02h.js.map +1 -0
  184. package/dist/core/web/public/next/assets/use-guarded-action-BO6c94Wp.js +2 -0
  185. package/dist/core/web/public/next/assets/use-guarded-action-BO6c94Wp.js.map +1 -0
  186. package/dist/core/web/public/next/assets/verse-model-CvtK6vP6.js +2 -0
  187. package/dist/core/web/public/next/assets/verse-model-CvtK6vP6.js.map +1 -0
  188. package/dist/core/web/public/next/assets/workspace-model-cE4LkKpE.js +2 -0
  189. package/dist/core/web/public/next/assets/workspace-model-cE4LkKpE.js.map +1 -0
  190. package/dist/core/web/public/next/index.html +1 -1
  191. package/dist/release-dependency-inventory.json +1 -1
  192. package/docs/README.md +4 -0
  193. package/node_modules/marked/README.md +8 -0
  194. package/node_modules/marked/bin/main.js +12 -11
  195. package/node_modules/marked/lib/marked.d.ts +88 -25
  196. package/node_modules/marked/lib/marked.esm.js +50 -44
  197. package/node_modules/marked/lib/marked.esm.js.map +3 -3
  198. package/node_modules/marked/lib/marked.umd.js +50 -44
  199. package/node_modules/marked/lib/marked.umd.js.map +3 -3
  200. package/node_modules/marked/man/marked.1 +1 -1
  201. package/node_modules/marked/package.json +21 -21
  202. package/package.json +13 -8
  203. package/dist/cli/activation.d.ts +0 -41
  204. package/dist/cli/activation.js +0 -485
  205. package/dist/cli/activation.js.map +0 -1
  206. package/dist/core/fleet/generated-repair-resolution.d.ts +0 -36
  207. package/dist/core/fleet/generated-repair-resolution.js +0 -245
  208. package/dist/core/fleet/generated-repair-resolution.js.map +0 -1
  209. package/dist/core/local-runtime/llama/port.d.ts +0 -17
  210. package/dist/core/local-runtime/llama/port.js +0 -47
  211. package/dist/core/local-runtime/llama/port.js.map +0 -1
  212. package/dist/core/local-runtime/llama/proxy-host.d.ts +0 -54
  213. package/dist/core/local-runtime/llama/proxy-host.js +0 -159
  214. package/dist/core/local-runtime/llama/proxy-host.js.map +0 -1
  215. package/dist/core/local-runtime/llama/proxy-process.d.ts +0 -148
  216. package/dist/core/local-runtime/llama/proxy-process.js +0 -250
  217. package/dist/core/local-runtime/llama/proxy-process.js.map +0 -1
  218. package/dist/core/local-runtime/llama/proxy-record.d.ts +0 -40
  219. package/dist/core/local-runtime/llama/proxy-record.js +0 -133
  220. package/dist/core/local-runtime/llama/proxy-record.js.map +0 -1
  221. package/dist/core/local-runtime/llama/proxy-supervisor.d.ts +0 -118
  222. package/dist/core/local-runtime/llama/proxy-supervisor.js +0 -511
  223. package/dist/core/local-runtime/llama/proxy-supervisor.js.map +0 -1
  224. package/dist/core/web/public/next/assets/App-BCKqSppK.css +0 -1
  225. package/dist/core/web/public/next/assets/App-LuILXjWG.js +0 -16
  226. package/dist/core/web/public/next/assets/App-LuILXjWG.js.map +0 -1
  227. package/dist/core/web/public/next/assets/ApprovalsSection-B_Xor8JH.js +0 -2
  228. package/dist/core/web/public/next/assets/ApprovalsSection-B_Xor8JH.js.map +0 -1
  229. package/dist/core/web/public/next/assets/ApprovalsSection-CRP59wSb.css +0 -1
  230. package/dist/core/web/public/next/assets/AutonomySection-BB8RD-tv.css +0 -1
  231. package/dist/core/web/public/next/assets/AutonomySection-BEwITtPJ.js +0 -2
  232. package/dist/core/web/public/next/assets/AutonomySection-BEwITtPJ.js.map +0 -1
  233. package/dist/core/web/public/next/assets/ChatSection-DrxqhBPK.css +0 -1
  234. package/dist/core/web/public/next/assets/ChatSection-bRAzlMth.js +0 -77
  235. package/dist/core/web/public/next/assets/ChatSection-bRAzlMth.js.map +0 -1
  236. package/dist/core/web/public/next/assets/ConfirmDialog-BqkZdPs_.js +0 -2
  237. package/dist/core/web/public/next/assets/ConfirmDialog-BqkZdPs_.js.map +0 -1
  238. package/dist/core/web/public/next/assets/Dialog-CPmedg4S.js +0 -2
  239. package/dist/core/web/public/next/assets/Dialog-CPmedg4S.js.map +0 -1
  240. package/dist/core/web/public/next/assets/Dialog-DxN7RgB5.css +0 -1
  241. package/dist/core/web/public/next/assets/DiffViewer-DmPJbeM_.js +0 -7
  242. package/dist/core/web/public/next/assets/DiffViewer-DmPJbeM_.js.map +0 -1
  243. package/dist/core/web/public/next/assets/DiffViewer-hN7X6wGT.css +0 -1
  244. package/dist/core/web/public/next/assets/Epistemic-DiyMyeaN.css +0 -1
  245. package/dist/core/web/public/next/assets/Epistemic-M3SxLHjq.js +0 -2
  246. package/dist/core/web/public/next/assets/Epistemic-M3SxLHjq.js.map +0 -1
  247. package/dist/core/web/public/next/assets/Meter-CGBsbXUX.css +0 -1
  248. package/dist/core/web/public/next/assets/Meter-D_X7c9U3.js +0 -2
  249. package/dist/core/web/public/next/assets/Meter-D_X7c9U3.js.map +0 -1
  250. package/dist/core/web/public/next/assets/MutationTokenDialog-Ba5ZHu-8.js +0 -2
  251. package/dist/core/web/public/next/assets/MutationTokenDialog-Ba5ZHu-8.js.map +0 -1
  252. package/dist/core/web/public/next/assets/RefreshIndicator-O7jUBOmX.css +0 -1
  253. package/dist/core/web/public/next/assets/RefreshIndicator-vHGpmyzb.js +0 -2
  254. package/dist/core/web/public/next/assets/RefreshIndicator-vHGpmyzb.js.map +0 -1
  255. package/dist/core/web/public/next/assets/ResourcePoolConsoleApp-B5g6JEVk.js +0 -7
  256. package/dist/core/web/public/next/assets/ResourcePoolConsoleApp-B5g6JEVk.js.map +0 -1
  257. package/dist/core/web/public/next/assets/ResourcePoolConsoleApp-DLl4DbGG.css +0 -1
  258. package/dist/core/web/public/next/assets/RouteErrorBoundary-BIpdnxp-.css +0 -1
  259. package/dist/core/web/public/next/assets/RouteErrorBoundary-CroxuKoi.js +0 -2
  260. package/dist/core/web/public/next/assets/RouteErrorBoundary-CroxuKoi.js.map +0 -1
  261. package/dist/core/web/public/next/assets/SettingsSection-DGJMdUh2.css +0 -1
  262. package/dist/core/web/public/next/assets/SettingsSection-p-7FCGfn.js +0 -2
  263. package/dist/core/web/public/next/assets/SettingsSection-p-7FCGfn.js.map +0 -1
  264. package/dist/core/web/public/next/assets/Skeleton-4qq4HuJO.js +0 -2
  265. package/dist/core/web/public/next/assets/Skeleton-4qq4HuJO.js.map +0 -1
  266. package/dist/core/web/public/next/assets/Skeleton-D2JaTXyv.css +0 -1
  267. package/dist/core/web/public/next/assets/StatusBadge-BbEdqEGn.js +0 -2
  268. package/dist/core/web/public/next/assets/StatusBadge-BbEdqEGn.js.map +0 -1
  269. package/dist/core/web/public/next/assets/StatusBadge-TpDqZf6K.css +0 -1
  270. package/dist/core/web/public/next/assets/TableView-R6Yeztp1.css +0 -1
  271. package/dist/core/web/public/next/assets/TableView-nyYs7Sv1.js +0 -2
  272. package/dist/core/web/public/next/assets/TableView-nyYs7Sv1.js.map +0 -1
  273. package/dist/core/web/public/next/assets/UniverseConsoleApp-CiZZxRPV.css +0 -1
  274. package/dist/core/web/public/next/assets/UniverseConsoleApp-DjTpQUrA.js +0 -2
  275. package/dist/core/web/public/next/assets/UniverseConsoleApp-DjTpQUrA.js.map +0 -1
  276. package/dist/core/web/public/next/assets/UniverseView-BtApwayT.js +0 -9
  277. package/dist/core/web/public/next/assets/UniverseView-BtApwayT.js.map +0 -1
  278. package/dist/core/web/public/next/assets/UniverseView-gBxl6yum.css +0 -1
  279. package/dist/core/web/public/next/assets/UsageSection-Db99N6ao.js +0 -2
  280. package/dist/core/web/public/next/assets/UsageSection-Db99N6ao.js.map +0 -1
  281. package/dist/core/web/public/next/assets/UsageSection-UUYDidOg.css +0 -1
  282. package/dist/core/web/public/next/assets/VerseConsoleApp-COa3J2dO.js +0 -3
  283. package/dist/core/web/public/next/assets/VerseConsoleApp-COa3J2dO.js.map +0 -1
  284. package/dist/core/web/public/next/assets/VerseConsoleApp-mOAXvWa6.css +0 -1
  285. package/dist/core/web/public/next/assets/fleet-model-DXCfVtNW.js +0 -2
  286. package/dist/core/web/public/next/assets/fleet-model-DXCfVtNW.js.map +0 -1
  287. package/dist/core/web/public/next/assets/format-fggwu_Rs.js +0 -2
  288. package/dist/core/web/public/next/assets/format-fggwu_Rs.js.map +0 -1
  289. package/dist/core/web/public/next/assets/global-BeRYd1Bu.css +0 -1
  290. package/dist/core/web/public/next/assets/global-CNVapoV1.js +0 -2
  291. package/dist/core/web/public/next/assets/global-CNVapoV1.js.map +0 -1
  292. package/dist/core/web/public/next/assets/index-BkUlX2Se.js +0 -51
  293. package/dist/core/web/public/next/assets/index-BkUlX2Se.js.map +0 -1
  294. package/dist/core/web/public/next/assets/index-YNTgDG2b.js +0 -2
  295. package/dist/core/web/public/next/assets/index-YNTgDG2b.js.map +0 -1
  296. package/dist/core/web/public/next/assets/queries-C9XS4SYq.js +0 -2
  297. package/dist/core/web/public/next/assets/queries-C9XS4SYq.js.map +0 -1
  298. package/dist/core/web/public/next/assets/use-guarded-action-Bqa2v0a-.css +0 -1
  299. package/dist/core/web/public/next/assets/use-guarded-action-Bql1nA-z.js +0 -2
  300. package/dist/core/web/public/next/assets/use-guarded-action-Bql1nA-z.js.map +0 -1
  301. package/dist/core/web/public/next/assets/verse-model-IrNQKtER.js +0 -2
  302. package/dist/core/web/public/next/assets/verse-model-IrNQKtER.js.map +0 -1
  303. package/node_modules/which/CHANGELOG.md +0 -166
  304. /package/node_modules/marked/{LICENSE.md → LICENSE} +0 -0
@@ -0,0 +1,211 @@
1
+ /**
2
+ * core/verse/github-api.ts — `GET /api/verse/github{,/pr-plan}`
3
+ * (docs/VERSE-WORKSPACES.md §2). The routes that make github.ts reachable
4
+ * from Ashlr Verse.
5
+ *
6
+ * Mounted from src/core/web/api.ts's handleApi() BEFORE the V1 verse handler,
7
+ * for the same reason the V2 control plane is: `isVerseApiPath()` matches every
8
+ * `/api/verse/*` path and 404s what it does not recognise, so a route mounted
9
+ * after it is never reached.
10
+ *
11
+ * SECURITY POSTURE — identical to control-api.ts, minus the POST half:
12
+ * - Both routes are GET-only and sit behind the read-session boundary in
13
+ * server.ts. There is NO mutation here. Nothing in this module opens,
14
+ * closes, merges, comments on, or pushes anything; `createPr` is not
15
+ * imported and `applyProposal` is not called.
16
+ * - Every response goes through sendJson() → sanitizePublicJson().
17
+ * - `?repo=` is refused unless the path is one the operator already brought
18
+ * into Verse — an enrolled repo, or the project path of an existing
19
+ * session (exactly `discoverProjects()`'s answer). The route is therefore
20
+ * not a filesystem probe.
21
+ * - No token, remote URL, launcher argv, or gh stderr can reach a response:
22
+ * github-repo.ts reads only `nameWithOwner`, and gh failures collapse to
23
+ * `prsAvailable: false` plus a fixed sentence.
24
+ */
25
+ import { sendJson } from '../web/api.js';
26
+ import { loadProposal } from '../inbox/store.js';
27
+ import { discoverProjects } from './projects.js';
28
+ import { expandHomePrefix, peekVerseEngine } from './verse-api.js';
29
+ import { describeVersePrPlans } from './github-proposal.js';
30
+ import { readVerseGithubSnapshot } from './github-repo.js';
31
+ const VERSE_PREFIX = '/api/verse';
32
+ export const VERSE_GITHUB_ROUTE = `${VERSE_PREFIX}/github`;
33
+ export const VERSE_GITHUB_PR_PLAN_ROUTE = `${VERSE_PREFIX}/github/pr-plan`;
34
+ const GITHUB_ROUTES = new Set([VERSE_GITHUB_ROUTE, VERSE_GITHUB_PR_PLAN_ROUTE]);
35
+ /** Bound the work one request can ask for. */
36
+ const MAX_REPOS_PER_REQUEST = 12;
37
+ const MAX_PLAN_IDS = 50;
38
+ const MAX_ID_CHARS = 128;
39
+ const MAX_PATH_CHARS = 4_096;
40
+ /** Proposal ids are `prop-<ts>-<hex>`; accept that shape and nothing exotic. */
41
+ const PROPOSAL_ID_RE = /^[A-Za-z0-9._-]+$/;
42
+ /** True for exactly the two GitHub routes. */
43
+ export function isVerseGithubPath(path) {
44
+ return GITHUB_ROUTES.has(path);
45
+ }
46
+ const ERROR_STATUS = {
47
+ VERSE_INVALID: 400,
48
+ VERSE_REFUSED: 409,
49
+ VERSE_TOO_LARGE: 413,
50
+ VERSE_UNAVAILABLE: 503,
51
+ };
52
+ function sendError(res, code, error) {
53
+ sendJson(res, ERROR_STATUS[code], { code, error });
54
+ }
55
+ function queryParam(req, key) {
56
+ const raw = req.url ?? '';
57
+ const qIndex = raw.indexOf('?');
58
+ if (qIndex < 0)
59
+ return null;
60
+ const params = new URLSearchParams(raw.slice(qIndex + 1));
61
+ return params.get(key);
62
+ }
63
+ /**
64
+ * Every root the operator has already brought into Verse: enrolled repos
65
+ * first, then the project path of each live session. Identical to what
66
+ * `GET /api/verse/bootstrap` lists, so the GitHub panel can never show a root
67
+ * the picker does not.
68
+ *
69
+ * `peekVerseEngine()` is used rather than `getVerseEngine()` on purpose — a
70
+ * read must never be the thing that creates the session engine.
71
+ */
72
+ function defaultKnownRoots() {
73
+ let sessions = [];
74
+ try {
75
+ sessions = peekVerseEngine()?.listSessions() ?? [];
76
+ }
77
+ catch {
78
+ sessions = [];
79
+ }
80
+ try {
81
+ return discoverProjects({ sessions }).map((p) => p.path);
82
+ }
83
+ catch {
84
+ return [];
85
+ }
86
+ }
87
+ /**
88
+ * Handle one `/api/verse/github*` request. Returns true when a response was
89
+ * written (including errors); false when `path` is not one of these routes.
90
+ */
91
+ export async function handleVerseGithubApi(_ctx, req, res, path, method, deps = {}) {
92
+ if (!isVerseGithubPath(path))
93
+ return false;
94
+ try {
95
+ if (method !== 'GET') {
96
+ sendJson(res, 404, { error: `not found: ${method} ${path}` });
97
+ return true;
98
+ }
99
+ if (path === VERSE_GITHUB_ROUTE) {
100
+ handleRepos(req, res, deps);
101
+ return true;
102
+ }
103
+ handlePrPlans(req, res, deps);
104
+ return true;
105
+ }
106
+ catch {
107
+ if (!res.headersSent) {
108
+ sendJson(res, 500, { code: 'INTERNAL_ERROR', error: 'internal server error' });
109
+ }
110
+ else if (!res.writableEnded) {
111
+ try {
112
+ res.end();
113
+ }
114
+ catch {
115
+ /* already gone */
116
+ }
117
+ }
118
+ return true;
119
+ }
120
+ }
121
+ // ---------------------------------------------------------------------------
122
+ // GET /api/verse/github[?repo=<absolute path>]
123
+ // ---------------------------------------------------------------------------
124
+ function handleRepos(req, res, deps) {
125
+ const read = deps.read ?? readVerseGithubSnapshot;
126
+ const known = (deps.knownRoots ?? defaultKnownRoots)();
127
+ const requested = queryParam(req, 'repo');
128
+ let roots;
129
+ // Without `?repo=`, this is the cheap index: identity and default branch per
130
+ // root, from local `git` reads only. `gh` is an 8 s-ceilinged synchronous
131
+ // subprocess on a single-threaded server, so a dozen roots' worth of list
132
+ // calls in one request is not something a UI mount may trigger. The panel
133
+ // fills in one root at a time with `?repo=`.
134
+ let includeLists = false;
135
+ if (requested === null) {
136
+ roots = known.slice(0, MAX_REPOS_PER_REQUEST);
137
+ }
138
+ else {
139
+ includeLists = true;
140
+ if (requested.length === 0 || requested.length > MAX_PATH_CHARS) {
141
+ sendError(res, 'VERSE_INVALID', 'repo must be a non-empty path');
142
+ return;
143
+ }
144
+ const resolved = expandHomePrefix(requested);
145
+ if (!known.includes(resolved)) {
146
+ // Not "no such directory" — deliberately the same answer whether the
147
+ // path exists or not, so this route cannot be used to probe the disk.
148
+ sendError(res, 'VERSE_REFUSED', 'repo is not an enrolled project or an open session path');
149
+ return;
150
+ }
151
+ roots = [resolved];
152
+ }
153
+ const snapshot = read(roots, {
154
+ includeLists,
155
+ ...(deps.readOptions ?? {}),
156
+ });
157
+ sendJson(res, 200, snapshot);
158
+ }
159
+ // ---------------------------------------------------------------------------
160
+ // GET /api/verse/github/pr-plan?id=<proposalId>[,<proposalId>…]
161
+ // ---------------------------------------------------------------------------
162
+ function handlePrPlans(req, res, deps) {
163
+ const describe = deps.describePlans ?? describeVersePrPlans;
164
+ const load = deps.loadProposal ?? ((id) => loadProposal(id));
165
+ const raw = queryParam(req, 'id');
166
+ if (raw === null || raw.length === 0) {
167
+ sendError(res, 'VERSE_INVALID', 'id is required');
168
+ return;
169
+ }
170
+ const ids = [];
171
+ for (const part of raw.split(',')) {
172
+ const id = part.trim();
173
+ if (id.length === 0)
174
+ continue;
175
+ if (id.length > MAX_ID_CHARS || !PROPOSAL_ID_RE.test(id)) {
176
+ sendError(res, 'VERSE_INVALID', 'id contains an unsupported character');
177
+ return;
178
+ }
179
+ if (!ids.includes(id))
180
+ ids.push(id);
181
+ if (ids.length > MAX_PLAN_IDS) {
182
+ sendError(res, 'VERSE_INVALID', `at most ${MAX_PLAN_IDS} ids per request`);
183
+ return;
184
+ }
185
+ }
186
+ if (ids.length === 0) {
187
+ sendError(res, 'VERSE_INVALID', 'id is required');
188
+ return;
189
+ }
190
+ const proposals = [];
191
+ for (const id of ids) {
192
+ let proposal = null;
193
+ try {
194
+ proposal = load(id);
195
+ }
196
+ catch {
197
+ proposal = null;
198
+ }
199
+ // An unknown id is silently absent rather than a 404: a client asking for
200
+ // several plans should not lose all of them because one was just applied
201
+ // and rotated out from under it.
202
+ if (proposal)
203
+ proposals.push(proposal);
204
+ }
205
+ const body = {
206
+ plans: describe(proposals),
207
+ observedAt: new Date().toISOString(),
208
+ };
209
+ sendJson(res, 200, body);
210
+ }
211
+ //# sourceMappingURL=github-api.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"github-api.js","sourceRoot":"","sources":["../../../src/core/verse/github-api.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,64 @@
1
+ /**
2
+ * core/verse/github-proposal.ts — the pre-click disclosure for an approved
3
+ * proposal of kind `pr` (docs/VERSE-WORKSPACES.md §2).
4
+ *
5
+ * THE POINT OF THIS FILE. Approving a `pr` proposal is the one action in the
6
+ * hub that reaches outside the machine: `core/inbox/apply.ts` builds a branch
7
+ * in a throwaway worktree and calls `createPr()`, which publishes that branch
8
+ * and opens a real pull request. The Approvals view names the repo and the
9
+ * kind. It does not name the branch it is about to create or the pull request
10
+ * it is about to open, so the operator learns both AFTER the click, from
11
+ * `proposal.result` — a sentence, produced by the thing they already approved.
12
+ * This module computes them BEFORE.
13
+ *
14
+ * ── WHAT APPLY ACTUALLY DOES (verified against src/core/inbox/apply.ts) ────
15
+ * • branch = `ashlr/proposal/${proposal.id}` (apply.ts:52, :125, :254)
16
+ * • createPr(repo, { title: proposal.title,
17
+ * body: proposal.summary,
18
+ * head: branch }) (apply.ts:257-261)
19
+ * • NO `base` is passed, so GitHub resolves the base to the repository's
20
+ * default branch. `predictPrPlan` reproduces that locally from
21
+ * `git symbolic-ref origin/HEAD` and labels it `baseSource: 'predicted'`,
22
+ * because it is our reading of gh's choice, not an instruction to gh.
23
+ * • NO `git push` runs. `gh pr create --head <branch>` publishes the branch
24
+ * as a side effect, which is why `publishesBranch` is true and stated.
25
+ *
26
+ * ── DRIFT ──────────────────────────────────────────────────────────────────
27
+ * `PROPOSAL_BRANCH_PREFIX` is module-private in apply.ts, so the literal is
28
+ * repeated here. test/verse-github-proposal.test.ts reads apply.ts and fails
29
+ * if the two ever diverge — a disclosure that predicts the wrong branch name
30
+ * is worse than none.
31
+ *
32
+ * READ-ONLY. NEVER THROWS. Opens nothing, pushes nothing, spawns only the
33
+ * `git` reads core/git.ts already performs.
34
+ */
35
+ import type { Proposal } from '../types.js';
36
+ import type { VerseGithubPrPlan } from './github-types.js';
37
+ /**
38
+ * Mirrors `PROPOSAL_BRANCH_PREFIX` in src/core/inbox/apply.ts:52, which is not
39
+ * exported. Guarded against drift by test/verse-github-proposal.test.ts.
40
+ */
41
+ export declare const VERSE_PROPOSAL_BRANCH_PREFIX = "ashlr/proposal/";
42
+ /** The subset of `Proposal` a plan needs. Structural, so fixtures stay small. */
43
+ export type VersePrPlanProposal = Pick<Proposal, 'id' | 'kind' | 'repo' | 'title' | 'summary' | 'status'> & Partial<Pick<Proposal, 'result' | 'remoteHandoff' | 'localMergeIntent'>>;
44
+ /** Git facts the plan needs. Defaults to core/git.ts; injected in tests. */
45
+ export interface VersePrPlanGitProbe {
46
+ defaultBranch(path: string): string;
47
+ nameWithOwner(path: string): string | null;
48
+ }
49
+ export interface VersePrPlanOptions {
50
+ git?: VersePrPlanGitProbe;
51
+ }
52
+ /** The branch `applyPr` will create for this proposal id. */
53
+ export declare function verseProposalBranch(proposalId: string): string;
54
+ /**
55
+ * Describe what approving this proposal will do — or, once it has been
56
+ * applied, what it did.
57
+ *
58
+ * Returns `state: 'unavailable'` (and no branch/base) for anything that is not
59
+ * an outward-facing `pr` proposal, so a caller can render the disclosure
60
+ * unconditionally and let the shape decide whether there is anything to show.
61
+ */
62
+ export declare function describeVersePrPlan(proposal: VersePrPlanProposal, opts?: VersePrPlanOptions): VerseGithubPrPlan;
63
+ /** Plans for several proposals, in the order given. Never throws. */
64
+ export declare function describeVersePrPlans(proposals: readonly VersePrPlanProposal[], opts?: VersePrPlanOptions): VerseGithubPrPlan[];
@@ -0,0 +1,186 @@
1
+ /**
2
+ * core/verse/github-proposal.ts — the pre-click disclosure for an approved
3
+ * proposal of kind `pr` (docs/VERSE-WORKSPACES.md §2).
4
+ *
5
+ * THE POINT OF THIS FILE. Approving a `pr` proposal is the one action in the
6
+ * hub that reaches outside the machine: `core/inbox/apply.ts` builds a branch
7
+ * in a throwaway worktree and calls `createPr()`, which publishes that branch
8
+ * and opens a real pull request. The Approvals view names the repo and the
9
+ * kind. It does not name the branch it is about to create or the pull request
10
+ * it is about to open, so the operator learns both AFTER the click, from
11
+ * `proposal.result` — a sentence, produced by the thing they already approved.
12
+ * This module computes them BEFORE.
13
+ *
14
+ * ── WHAT APPLY ACTUALLY DOES (verified against src/core/inbox/apply.ts) ────
15
+ * • branch = `ashlr/proposal/${proposal.id}` (apply.ts:52, :125, :254)
16
+ * • createPr(repo, { title: proposal.title,
17
+ * body: proposal.summary,
18
+ * head: branch }) (apply.ts:257-261)
19
+ * • NO `base` is passed, so GitHub resolves the base to the repository's
20
+ * default branch. `predictPrPlan` reproduces that locally from
21
+ * `git symbolic-ref origin/HEAD` and labels it `baseSource: 'predicted'`,
22
+ * because it is our reading of gh's choice, not an instruction to gh.
23
+ * • NO `git push` runs. `gh pr create --head <branch>` publishes the branch
24
+ * as a side effect, which is why `publishesBranch` is true and stated.
25
+ *
26
+ * ── DRIFT ──────────────────────────────────────────────────────────────────
27
+ * `PROPOSAL_BRANCH_PREFIX` is module-private in apply.ts, so the literal is
28
+ * repeated here. test/verse-github-proposal.test.ts reads apply.ts and fails
29
+ * if the two ever diverge — a disclosure that predicts the wrong branch name
30
+ * is worse than none.
31
+ *
32
+ * READ-ONLY. NEVER THROWS. Opens nothing, pushes nothing, spawns only the
33
+ * `git` reads core/git.ts already performs.
34
+ */
35
+ import { defaultBranch, resolveGitHubOriginAuthority } from '../git.js';
36
+ /**
37
+ * Mirrors `PROPOSAL_BRANCH_PREFIX` in src/core/inbox/apply.ts:52, which is not
38
+ * exported. Guarded against drift by test/verse-github-proposal.test.ts.
39
+ */
40
+ export const VERSE_PROPOSAL_BRANCH_PREFIX = 'ashlr/proposal/';
41
+ const MAX_BODY_PREVIEW_CHARS = 400;
42
+ const MAX_REF_CHARS = 256;
43
+ const MAX_TITLE_CHARS = 512;
44
+ /**
45
+ * Only a real GitHub pull-request URL is ever surfaced as `prUrl`.
46
+ * `proposal.result` also carries gh's failure text on the unhappy path, and
47
+ * that text is not something to hand a UI as a link.
48
+ */
49
+ const PR_URL_RE = /https:\/\/github\.com\/[A-Za-z0-9](?:[A-Za-z0-9-]*[A-Za-z0-9])?\/[A-Za-z0-9_.-]+\/pull\/\d+/;
50
+ const realGit = {
51
+ defaultBranch: (path) => defaultBranch(path),
52
+ nameWithOwner: (path) => resolveGitHubOriginAuthority(path),
53
+ };
54
+ /** The branch `applyPr` will create for this proposal id. */
55
+ export function verseProposalBranch(proposalId) {
56
+ return `${VERSE_PROPOSAL_BRANCH_PREFIX}${proposalId}`;
57
+ }
58
+ function boundedString(value, max) {
59
+ if (typeof value !== 'string')
60
+ return null;
61
+ const trimmed = value.trim();
62
+ if (trimmed.length === 0)
63
+ return null;
64
+ return trimmed.length > max ? trimmed.slice(0, max) : trimmed;
65
+ }
66
+ function extractPrUrl(...candidates) {
67
+ for (const candidate of candidates) {
68
+ if (typeof candidate !== 'string')
69
+ continue;
70
+ const match = PR_URL_RE.exec(candidate);
71
+ if (match)
72
+ return match[0];
73
+ }
74
+ return null;
75
+ }
76
+ function unavailable(proposal, detail) {
77
+ return {
78
+ proposalId: proposal.id,
79
+ state: 'unavailable',
80
+ kind: proposal.kind,
81
+ repoPath: proposal.repo ?? null,
82
+ nameWithOwner: null,
83
+ branch: null,
84
+ branchSource: 'unknown',
85
+ base: null,
86
+ baseSource: 'unknown',
87
+ title: null,
88
+ bodyPreview: null,
89
+ bodyTruncated: false,
90
+ prUrl: null,
91
+ publishesBranch: false,
92
+ detail,
93
+ };
94
+ }
95
+ /**
96
+ * Describe what approving this proposal will do — or, once it has been
97
+ * applied, what it did.
98
+ *
99
+ * Returns `state: 'unavailable'` (and no branch/base) for anything that is not
100
+ * an outward-facing `pr` proposal, so a caller can render the disclosure
101
+ * unconditionally and let the shape decide whether there is anything to show.
102
+ */
103
+ export function describeVersePrPlan(proposal, opts = {}) {
104
+ const git = opts.git ?? realGit;
105
+ if (proposal.kind !== 'pr') {
106
+ return unavailable(proposal, `kind ${proposal.kind} opens no pull request`);
107
+ }
108
+ const repoPath = boundedString(proposal.repo, 4_096);
109
+ if (!repoPath) {
110
+ return unavailable(proposal, 'proposal carries no repository, so no pull request can be opened');
111
+ }
112
+ const handoff = proposal.remoteHandoff;
113
+ const intent = proposal.localMergeIntent;
114
+ // Recorded values win over predicted ones: once apply has run, the plan
115
+ // stops being a forecast and becomes a record of what happened.
116
+ const recordedBranch = boundedString(handoff?.branch, MAX_REF_CHARS)
117
+ ?? boundedString(intent?.branch, MAX_REF_CHARS);
118
+ const branch = recordedBranch ?? verseProposalBranch(proposal.id);
119
+ const branchSource = recordedBranch ? 'recorded' : 'predicted';
120
+ const recordedBase = boundedString(handoff?.base, MAX_REF_CHARS)
121
+ ?? boundedString(intent?.base, MAX_REF_CHARS);
122
+ let base = recordedBase;
123
+ let baseSource = recordedBase ? 'recorded' : 'unknown';
124
+ if (!base) {
125
+ try {
126
+ base = boundedString(git.defaultBranch(repoPath), MAX_REF_CHARS);
127
+ baseSource = base ? 'predicted' : 'unknown';
128
+ }
129
+ catch {
130
+ base = null;
131
+ baseSource = 'unknown';
132
+ }
133
+ }
134
+ let nameWithOwner = null;
135
+ try {
136
+ nameWithOwner = boundedString(git.nameWithOwner(repoPath), 512);
137
+ }
138
+ catch {
139
+ nameWithOwner = null;
140
+ }
141
+ const prUrl = extractPrUrl(handoff?.prUrl, proposal.result);
142
+ const title = boundedString(proposal.title, MAX_TITLE_CHARS);
143
+ const summary = typeof proposal.summary === 'string' ? proposal.summary.trim() : '';
144
+ const bodyTruncated = summary.length > MAX_BODY_PREVIEW_CHARS;
145
+ const bodyPreview = summary.length === 0
146
+ ? null
147
+ : summary.slice(0, MAX_BODY_PREVIEW_CHARS);
148
+ const state = prUrl ? 'opened' : 'ready';
149
+ const target = nameWithOwner ?? repoPath;
150
+ const detail = state === 'opened'
151
+ ? `Opened ${prUrl} from ${branch} into ${base ?? 'the default branch'} on ${target}.`
152
+ : `Approving pushes ${branch} to ${target} and opens a pull request into ${base ?? 'its default branch'}.`;
153
+ return {
154
+ proposalId: proposal.id,
155
+ state,
156
+ kind: proposal.kind,
157
+ repoPath,
158
+ nameWithOwner,
159
+ branch,
160
+ branchSource,
161
+ base,
162
+ baseSource,
163
+ title,
164
+ bodyPreview,
165
+ bodyTruncated,
166
+ prUrl,
167
+ // True for a plan that has not run yet: `gh pr create --head <branch>`
168
+ // publishes the branch. Once the PR exists the push has already happened.
169
+ publishesBranch: state === 'ready',
170
+ detail,
171
+ };
172
+ }
173
+ /** Plans for several proposals, in the order given. Never throws. */
174
+ export function describeVersePrPlans(proposals, opts = {}) {
175
+ const out = [];
176
+ for (const proposal of proposals) {
177
+ try {
178
+ out.push(describeVersePrPlan(proposal, opts));
179
+ }
180
+ catch {
181
+ out.push(unavailable(proposal, 'could not describe this proposal'));
182
+ }
183
+ }
184
+ return out;
185
+ }
186
+ //# sourceMappingURL=github-proposal.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"github-proposal.js","sourceRoot":"","sources":["../../../src/core/verse/github-proposal.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,104 @@
1
+ /**
2
+ * core/verse/github-repo.ts — per-root GitHub surfacing for Ashlr Verse
3
+ * (docs/VERSE-WORKSPACES.md §2). READ-ONLY. NEVER THROWS.
4
+ *
5
+ * ── AUTH ───────────────────────────────────────────────────────────────────
6
+ * The `gh` CLI owns its own credentials, exactly as core/integrations/github.ts
7
+ * does. This module spawns the same binary with the same env hygiene and holds
8
+ * NO token of its own. There is no second credential path here, and no code
9
+ * path in this file reads, stores, or emits one.
10
+ *
11
+ * ── WHY IT SPAWNS `gh` AT ALL, GIVEN github.ts EXISTS ──────────────────────
12
+ * github.ts does the hard part and this module reuses its conventions
13
+ * verbatim (same binary, same 8 s timeout, same env, same never-throw
14
+ * contract). It does not reuse its two list functions, for two reasons that
15
+ * are contract-level rather than stylistic:
16
+ *
17
+ * 1. CI STATE. `listPrs()` requests `number,title,url,state,author` and
18
+ * `PrSummary` has no checks field; `githubStatus().ci` is repo-wide,
19
+ * derived from the last five *workflow runs*, and cannot say which PR is
20
+ * red. §2 asks for "open PRs and their CI state", which needs
21
+ * `statusCheckRollup` on the PR query. github.ts exports no runner to
22
+ * borrow (`runGh` is private), so the query is issued here.
23
+ * 2. FAILURE vs EMPTY. `listPrs()`/`listIssues()` return `[]` both when gh
24
+ * fails and when nothing is open. An operator staring at an empty panel
25
+ * must be able to tell "nothing to do" from "could not look", so this
26
+ * module keeps gh's null and projects it as `prsAvailable` /
27
+ * `issuesAvailable`.
28
+ *
29
+ * Two `gh` calls per root, both list reads. Remote identity and default branch
30
+ * come from core/git.ts and cost no network at all.
31
+ *
32
+ * ── NO URL LEAVES THIS MODULE ──────────────────────────────────────────────
33
+ * `resolveGitHubOriginAuthorityDetails()` returns fetch/push URLs, and a
34
+ * supported GitHub HTTPS transport may carry credentials in its userinfo. Only
35
+ * `nameWithOwner` is read, so no remote URL can reach a response, a log, or an
36
+ * SSE frame. `gh`'s own stderr is never surfaced either — a failure becomes a
37
+ * fixed sentence, not a passthrough of whatever the tool printed.
38
+ */
39
+ import type { VerseGithubChecks, VerseGithubIssue, VerseGithubPr, VerseGithubRepoSnapshot, VerseGithubSnapshot } from './github-types.js';
40
+ /** Run `gh` in `cwd`; trimmed stdout, or null on ANY failure. Never throws. */
41
+ export type VerseGithubGhRunner = (cwd: string, args: readonly string[]) => string | null;
42
+ /** The git facts this module needs. Defaults to core/git.ts. */
43
+ export interface VerseGithubGitProbe {
44
+ isRepo(path: string): boolean;
45
+ defaultBranch(path: string): string;
46
+ /** Lowercase `owner/name`, or null when origin does not resolve to one GitHub repo. */
47
+ nameWithOwner(path: string): string | null;
48
+ }
49
+ export interface VerseGithubReadOptions {
50
+ gh?: VerseGithubGhRunner;
51
+ git?: VerseGithubGitProbe;
52
+ /** 1..100, default 20. */
53
+ prLimit?: number;
54
+ /** 1..100, default 20. */
55
+ issueLimit?: number;
56
+ /** Clock seam for tests. */
57
+ now?: () => Date;
58
+ /** Directory existence seam for tests. */
59
+ isDirectory?: (path: string) => boolean;
60
+ /**
61
+ * Invoke `gh` for the PR and issue lists. Default true.
62
+ *
63
+ * `gh` is a synchronous subprocess with an 8 s ceiling, and the web server
64
+ * is single-threaded: reading N roots' lists in one request blocks it for up
65
+ * to N x 2 x 8 s. A multi-root listing therefore passes false and returns
66
+ * identity only (`listsRequested: false`), which costs nothing but two local
67
+ * `git` reads per root.
68
+ */
69
+ includeLists?: boolean;
70
+ }
71
+ /**
72
+ * Summarise one PR's `statusCheckRollup`.
73
+ *
74
+ * Handles both GraphQL variants gh emits: `CheckRun` (`status`/`conclusion`)
75
+ * and `StatusContext` (`state`). Entries of neither shape are counted as
76
+ * pending rather than silently dropped — an unrecognised check is not a
77
+ * passing one.
78
+ *
79
+ * FAILING WINS OVER PENDING, deliberately diverging from
80
+ * `resolveCiStatus()`'s first-match-wins scan in github.ts: that function
81
+ * summarises the last five workflow *runs* of a repo, where "something is
82
+ * running" is the useful headline. Here the operator is deciding whether to
83
+ * touch a specific PR, and a red check must not be hidden behind a queued one.
84
+ */
85
+ export declare function summarizeCheckRollup(rollup: unknown): VerseGithubChecks;
86
+ /**
87
+ * Parse `gh pr list --json <PR_JSON_FIELDS>` output.
88
+ *
89
+ * Malformed entries are DROPPED, not defaulted — the same choice
90
+ * `listIssues()` makes and the opposite of `listPrs()`, which coerces a
91
+ * missing number to 0. A PR row that cannot name its own number or URL is not
92
+ * something an operator should be offered a link to.
93
+ */
94
+ export declare function parsePrList(parsed: unknown): VerseGithubPr[];
95
+ /** Parse `gh issue list --json <ISSUE_JSON_FIELDS>`. Malformed entries dropped. */
96
+ export declare function parseIssueList(parsed: unknown): VerseGithubIssue[];
97
+ /**
98
+ * Read one workspace root. Never throws, never returns a remote URL, and never
99
+ * mutates anything — the only subprocesses are `git` reads via core/git.ts and
100
+ * two `gh` list reads.
101
+ */
102
+ export declare function readVerseGithubRepo(path: string, opts?: VerseGithubReadOptions): VerseGithubRepoSnapshot;
103
+ /** Read several roots in order, de-duplicated by path. Never throws. */
104
+ export declare function readVerseGithubSnapshot(paths: readonly string[], opts?: VerseGithubReadOptions): VerseGithubSnapshot;