@quickchatai/pi-quickreview 0.0.0-stage → 1.2.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 (697) hide show
  1. package/LICENSE +23 -0
  2. package/README.md +75 -2
  3. package/assets/agents/pass-abstraction.md +64 -0
  4. package/assets/agents/pass-ask-human.md +134 -0
  5. package/assets/agents/pass-backcompat.md +67 -0
  6. package/assets/agents/pass-baseline.md +61 -0
  7. package/assets/agents/pass-behaviour-delta.md +64 -0
  8. package/assets/agents/pass-bounds.md +36 -0
  9. package/assets/agents/pass-claims.md +31 -0
  10. package/assets/agents/pass-concurrency.md +168 -0
  11. package/assets/agents/pass-consistency.md +57 -0
  12. package/assets/agents/pass-contracts.md +30 -0
  13. package/assets/agents/pass-data-safety.md +54 -0
  14. package/assets/agents/pass-deferred.md +35 -0
  15. package/assets/agents/pass-delivery.md +37 -0
  16. package/assets/agents/pass-duplication.md +60 -0
  17. package/assets/agents/pass-intent.md +63 -0
  18. package/assets/agents/pass-lint-conformance.md +46 -0
  19. package/assets/agents/pass-maintainability.md +67 -0
  20. package/assets/agents/pass-placement.md +68 -0
  21. package/assets/agents/pass-prod-risk.md +24 -0
  22. package/assets/agents/pass-rollout.md +32 -0
  23. package/assets/agents/pass-roundtrip.md +46 -0
  24. package/assets/agents/pass-security.md +31 -0
  25. package/assets/agents/pass-simplicity.md +68 -0
  26. package/assets/agents/pass-statelessness.md +27 -0
  27. package/assets/agents/pass-style.md +37 -0
  28. package/assets/agents/pass-sweep.md +57 -0
  29. package/assets/agents/pass-tests.md +58 -0
  30. package/assets/agents/pass-ui.md +23 -0
  31. package/assets/agents/pass-validate.md +50 -0
  32. package/assets/agents/pass-widened.md +46 -0
  33. package/assets/agents/scan/pass-scan.md +86 -0
  34. package/assets/config.example.toml +1099 -0
  35. package/assets/deploy/reviewer/AGENTS.override.md +12 -0
  36. package/assets/profiles/default/README.md +21 -0
  37. package/assets/profiles/default/addenda/.gitkeep +0 -0
  38. package/assets/profiles/default/profile.toml +17 -0
  39. package/assets/profiles/example-django/README.md +21 -0
  40. package/assets/profiles/example-django/addenda/10-migration-discipline.md +13 -0
  41. package/assets/profiles/example-django/addenda/20-new-column-nullability.md +12 -0
  42. package/assets/profiles/example-django/addenda/30-test-doctrine.md +12 -0
  43. package/assets/profiles/example-django/addenda/40-orm-usage.md +19 -0
  44. package/assets/profiles/example-django/addenda/50-declared-shape.md +10 -0
  45. package/assets/profiles/example-django/addenda/60-config-placement.md +14 -0
  46. package/assets/profiles/example-django/heuristics.toml +24 -0
  47. package/assets/profiles/example-django/profile.toml +9 -0
  48. package/assets/profiles/fast/README.md +24 -0
  49. package/assets/profiles/fast/profile.toml +59 -0
  50. package/assets/profiles/minimal/README.md +17 -0
  51. package/assets/profiles/minimal/addenda/.gitkeep +0 -0
  52. package/assets/profiles/minimal/profile.toml +8 -0
  53. package/assets/profiles/snappy/README.md +24 -0
  54. package/assets/profiles/snappy/addenda/10-race-as-question.md +6 -0
  55. package/assets/profiles/snappy/profile.toml +46 -0
  56. package/assets/prompts/companion-day-open.md +46 -0
  57. package/assets/prompts/companion-first-run.md +104 -0
  58. package/assets/prompts/companion.md +821 -0
  59. package/assets/prompts/conversation-system.md +117 -0
  60. package/assets/prompts/eod-sweep.md +120 -0
  61. package/assets/prompts/onboarding.md +113 -0
  62. package/assets/prompts/pass-common.md +52 -0
  63. package/assets/prompts/pass-quality-common.md +22 -0
  64. package/assets/prompts/round-first.md +874 -0
  65. package/assets/prompts/round-follow-up.md +991 -0
  66. package/assets/prompts/round-re-review.md +889 -0
  67. package/assets/prompts/round-recheck.md +196 -0
  68. package/assets/prompts/round-staleness.md +856 -0
  69. package/assets/schemas/review-result.v1.json +391 -0
  70. package/assets/schemas/scan-result.v1.json +421 -0
  71. package/assets/schemas/version.v1.json +57 -0
  72. package/assets/seed-manifest.json +19 -0
  73. package/assets/seeds/agents/pass-baseline.md +61 -0
  74. package/assets/seeds/agents/pass-contracts.md +30 -0
  75. package/assets/seeds/agents/pass-data-safety.md +54 -0
  76. package/assets/seeds/agents/pass-delivery.md +37 -0
  77. package/assets/seeds/agents/pass-prod-risk.md +24 -0
  78. package/assets/seeds/agents/pass-security.md +31 -0
  79. package/assets/seeds/agents/pass-statelessness.md +27 -0
  80. package/assets/seeds/agents/pass-ui.md +23 -0
  81. package/assets/seeds/agents/pass-validate.md +50 -0
  82. package/assets/seeds/prompts/conversation-system.md +117 -0
  83. package/assets/seeds/prompts/eod-sweep.md +120 -0
  84. package/assets/seeds/prompts/pass-common.md +52 -0
  85. package/dist/extensions/bash-guard.d.ts +467 -0
  86. package/dist/extensions/bash-guard.d.ts.map +1 -0
  87. package/dist/extensions/bash-guard.js +3058 -0
  88. package/dist/extensions/bash-guard.js.map +1 -0
  89. package/dist/extensions/finding-clusters.d.ts +33 -0
  90. package/dist/extensions/finding-clusters.d.ts.map +1 -0
  91. package/dist/extensions/finding-clusters.js +218 -0
  92. package/dist/extensions/finding-clusters.js.map +1 -0
  93. package/dist/extensions/ledger-pin.d.ts +76 -0
  94. package/dist/extensions/ledger-pin.d.ts.map +1 -0
  95. package/dist/extensions/ledger-pin.js +331 -0
  96. package/dist/extensions/ledger-pin.js.map +1 -0
  97. package/dist/extensions/lens.d.ts +43 -0
  98. package/dist/extensions/lens.d.ts.map +1 -0
  99. package/dist/extensions/lens.js +150 -0
  100. package/dist/extensions/lens.js.map +1 -0
  101. package/dist/extensions/pi-tool.d.ts +22 -0
  102. package/dist/extensions/pi-tool.d.ts.map +1 -0
  103. package/dist/extensions/pi-tool.js +20 -0
  104. package/dist/extensions/pi-tool.js.map +1 -0
  105. package/dist/extensions/quickreview.d.ts +21 -0
  106. package/dist/extensions/quickreview.d.ts.map +1 -0
  107. package/dist/extensions/quickreview.js +132 -0
  108. package/dist/extensions/quickreview.js.map +1 -0
  109. package/dist/src/anchors.d.ts +54 -0
  110. package/dist/src/anchors.d.ts.map +1 -0
  111. package/dist/src/anchors.js +127 -0
  112. package/dist/src/anchors.js.map +1 -0
  113. package/dist/src/assetroot.d.ts +16 -0
  114. package/dist/src/assetroot.d.ts.map +1 -0
  115. package/dist/src/assetroot.js +77 -0
  116. package/dist/src/assetroot.js.map +1 -0
  117. package/dist/src/authwatch.d.ts +61 -0
  118. package/dist/src/authwatch.d.ts.map +1 -0
  119. package/dist/src/authwatch.js +210 -0
  120. package/dist/src/authwatch.js.map +1 -0
  121. package/dist/src/budget.d.ts +15 -0
  122. package/dist/src/budget.d.ts.map +1 -0
  123. package/dist/src/budget.js +32 -0
  124. package/dist/src/budget.js.map +1 -0
  125. package/dist/src/casebudget.d.ts +3 -0
  126. package/dist/src/casebudget.d.ts.map +1 -0
  127. package/dist/src/casebudget.js +3 -0
  128. package/dist/src/casebudget.js.map +1 -0
  129. package/dist/src/cigate.d.ts +116 -0
  130. package/dist/src/cigate.d.ts.map +1 -0
  131. package/dist/src/cigate.js +176 -0
  132. package/dist/src/cigate.js.map +1 -0
  133. package/dist/src/codespan.d.ts +46 -0
  134. package/dist/src/codespan.d.ts.map +1 -0
  135. package/dist/src/codespan.js +75 -0
  136. package/dist/src/codespan.js.map +1 -0
  137. package/dist/src/contextpack.d.ts +56 -0
  138. package/dist/src/contextpack.d.ts.map +1 -0
  139. package/dist/src/contextpack.js +195 -0
  140. package/dist/src/contextpack.js.map +1 -0
  141. package/dist/src/contract.d.ts +8 -0
  142. package/dist/src/contract.d.ts.map +1 -0
  143. package/dist/src/contract.js +21 -0
  144. package/dist/src/contract.js.map +1 -0
  145. package/dist/src/coverage.d.ts +32 -0
  146. package/dist/src/coverage.d.ts.map +1 -0
  147. package/dist/src/coverage.js +85 -0
  148. package/dist/src/coverage.js.map +1 -0
  149. package/dist/src/datafence.d.ts +19 -0
  150. package/dist/src/datafence.d.ts.map +1 -0
  151. package/dist/src/datafence.js +60 -0
  152. package/dist/src/datafence.js.map +1 -0
  153. package/dist/src/dedup.d.ts +65 -0
  154. package/dist/src/dedup.d.ts.map +1 -0
  155. package/dist/src/dedup.js +459 -0
  156. package/dist/src/dedup.js.map +1 -0
  157. package/dist/src/depsources.d.ts +304 -0
  158. package/dist/src/depsources.d.ts.map +1 -0
  159. package/dist/src/depsources.js +3367 -0
  160. package/dist/src/depsources.js.map +1 -0
  161. package/dist/src/diffinput.d.ts +10 -0
  162. package/dist/src/diffinput.d.ts.map +1 -0
  163. package/dist/src/diffinput.js +172 -0
  164. package/dist/src/diffinput.js.map +1 -0
  165. package/dist/src/doubtwords.d.ts +10 -0
  166. package/dist/src/doubtwords.d.ts.map +1 -0
  167. package/dist/src/doubtwords.js +13 -0
  168. package/dist/src/doubtwords.js.map +1 -0
  169. package/dist/src/ecosystem.d.ts +148 -0
  170. package/dist/src/ecosystem.d.ts.map +1 -0
  171. package/dist/src/ecosystem.js +338 -0
  172. package/dist/src/ecosystem.js.map +1 -0
  173. package/dist/src/engine/agentdir.d.ts +5 -0
  174. package/dist/src/engine/agentdir.d.ts.map +1 -0
  175. package/dist/src/engine/agentdir.js +21 -0
  176. package/dist/src/engine/agentdir.js.map +1 -0
  177. package/dist/src/engine/auth.d.ts +214 -0
  178. package/dist/src/engine/auth.d.ts.map +1 -0
  179. package/dist/src/engine/auth.js +374 -0
  180. package/dist/src/engine/auth.js.map +1 -0
  181. package/dist/src/engine/budget.d.ts +60 -0
  182. package/dist/src/engine/budget.d.ts.map +1 -0
  183. package/dist/src/engine/budget.js +113 -0
  184. package/dist/src/engine/budget.js.map +1 -0
  185. package/dist/src/engine/capfd.d.ts +6 -0
  186. package/dist/src/engine/capfd.d.ts.map +1 -0
  187. package/dist/src/engine/capfd.js +21 -0
  188. package/dist/src/engine/capfd.js.map +1 -0
  189. package/dist/src/engine/caseout.d.ts +66 -0
  190. package/dist/src/engine/caseout.d.ts.map +1 -0
  191. package/dist/src/engine/caseout.js +107 -0
  192. package/dist/src/engine/caseout.js.map +1 -0
  193. package/dist/src/engine/context.d.ts +57 -0
  194. package/dist/src/engine/context.d.ts.map +1 -0
  195. package/dist/src/engine/context.js +212 -0
  196. package/dist/src/engine/context.js.map +1 -0
  197. package/dist/src/engine/envmap.d.ts +13 -0
  198. package/dist/src/engine/envmap.d.ts.map +1 -0
  199. package/dist/src/engine/envmap.js +377 -0
  200. package/dist/src/engine/envmap.js.map +1 -0
  201. package/dist/src/engine/extfiles.d.ts +7 -0
  202. package/dist/src/engine/extfiles.d.ts.map +1 -0
  203. package/dist/src/engine/extfiles.js +23 -0
  204. package/dist/src/engine/extfiles.js.map +1 -0
  205. package/dist/src/engine/keyroute.d.ts +21 -0
  206. package/dist/src/engine/keyroute.d.ts.map +1 -0
  207. package/dist/src/engine/keyroute.js +58 -0
  208. package/dist/src/engine/keyroute.js.map +1 -0
  209. package/dist/src/engine/lens/cache-group.d.ts +20 -0
  210. package/dist/src/engine/lens/cache-group.d.ts.map +1 -0
  211. package/dist/src/engine/lens/cache-group.js +31 -0
  212. package/dist/src/engine/lens/cache-group.js.map +1 -0
  213. package/dist/src/engine/lens/cache-run.d.ts +65 -0
  214. package/dist/src/engine/lens/cache-run.d.ts.map +1 -0
  215. package/dist/src/engine/lens/cache-run.js +159 -0
  216. package/dist/src/engine/lens/cache-run.js.map +1 -0
  217. package/dist/src/engine/lens/deadline.d.ts +54 -0
  218. package/dist/src/engine/lens/deadline.d.ts.map +1 -0
  219. package/dist/src/engine/lens/deadline.js +111 -0
  220. package/dist/src/engine/lens/deadline.js.map +1 -0
  221. package/dist/src/engine/lens/engine-tools.d.ts +13 -0
  222. package/dist/src/engine/lens/engine-tools.d.ts.map +1 -0
  223. package/dist/src/engine/lens/engine-tools.js +37 -0
  224. package/dist/src/engine/lens/engine-tools.js.map +1 -0
  225. package/dist/src/engine/lens/env.d.ts +23 -0
  226. package/dist/src/engine/lens/env.d.ts.map +1 -0
  227. package/dist/src/engine/lens/env.js +42 -0
  228. package/dist/src/engine/lens/env.js.map +1 -0
  229. package/dist/src/engine/lens/launch-plan.d.ts +63 -0
  230. package/dist/src/engine/lens/launch-plan.d.ts.map +1 -0
  231. package/dist/src/engine/lens/launch-plan.js +203 -0
  232. package/dist/src/engine/lens/launch-plan.js.map +1 -0
  233. package/dist/src/engine/lens/leaf-cache.d.ts +22 -0
  234. package/dist/src/engine/lens/leaf-cache.d.ts.map +1 -0
  235. package/dist/src/engine/lens/leaf-cache.js +115 -0
  236. package/dist/src/engine/lens/leaf-cache.js.map +1 -0
  237. package/dist/src/engine/lens/permits.d.ts +14 -0
  238. package/dist/src/engine/lens/permits.d.ts.map +1 -0
  239. package/dist/src/engine/lens/permits.js +18 -0
  240. package/dist/src/engine/lens/permits.js.map +1 -0
  241. package/dist/src/engine/lens/registry.d.ts +55 -0
  242. package/dist/src/engine/lens/registry.d.ts.map +1 -0
  243. package/dist/src/engine/lens/registry.js +140 -0
  244. package/dist/src/engine/lens/registry.js.map +1 -0
  245. package/dist/src/engine/lens/round-lens.d.ts +16 -0
  246. package/dist/src/engine/lens/round-lens.d.ts.map +1 -0
  247. package/dist/src/engine/lens/round-lens.js +46 -0
  248. package/dist/src/engine/lens/round-lens.js.map +1 -0
  249. package/dist/src/engine/lens/runlens.d.ts +103 -0
  250. package/dist/src/engine/lens/runlens.d.ts.map +1 -0
  251. package/dist/src/engine/lens/runlens.js +538 -0
  252. package/dist/src/engine/lens/runlens.js.map +1 -0
  253. package/dist/src/engine/lens/section.d.ts +19 -0
  254. package/dist/src/engine/lens/section.d.ts.map +1 -0
  255. package/dist/src/engine/lens/section.js +40 -0
  256. package/dist/src/engine/lens/section.js.map +1 -0
  257. package/dist/src/engine/lens/semaphore.d.ts +13 -0
  258. package/dist/src/engine/lens/semaphore.d.ts.map +1 -0
  259. package/dist/src/engine/lens/semaphore.js +44 -0
  260. package/dist/src/engine/lens/semaphore.js.map +1 -0
  261. package/dist/src/engine/lens/tool.d.ts +34 -0
  262. package/dist/src/engine/lens/tool.d.ts.map +1 -0
  263. package/dist/src/engine/lens/tool.js +345 -0
  264. package/dist/src/engine/lens/tool.js.map +1 -0
  265. package/dist/src/engine/lens/wave.d.ts +63 -0
  266. package/dist/src/engine/lens/wave.d.ts.map +1 -0
  267. package/dist/src/engine/lens/wave.js +95 -0
  268. package/dist/src/engine/lens/wave.js.map +1 -0
  269. package/dist/src/engine/livesessions.d.ts +21 -0
  270. package/dist/src/engine/livesessions.d.ts.map +1 -0
  271. package/dist/src/engine/livesessions.js +57 -0
  272. package/dist/src/engine/livesessions.js.map +1 -0
  273. package/dist/src/engine/livewire.d.ts +18 -0
  274. package/dist/src/engine/livewire.d.ts.map +1 -0
  275. package/dist/src/engine/livewire.js +31 -0
  276. package/dist/src/engine/livewire.js.map +1 -0
  277. package/dist/src/engine/openable.d.ts +37 -0
  278. package/dist/src/engine/openable.d.ts.map +1 -0
  279. package/dist/src/engine/openable.js +120 -0
  280. package/dist/src/engine/openable.js.map +1 -0
  281. package/dist/src/engine/pisdk.d.ts +235 -0
  282. package/dist/src/engine/pisdk.d.ts.map +1 -0
  283. package/dist/src/engine/pisdk.js +577 -0
  284. package/dist/src/engine/pisdk.js.map +1 -0
  285. package/dist/src/engine/port.d.ts +144 -0
  286. package/dist/src/engine/port.d.ts.map +1 -0
  287. package/dist/src/engine/port.js +16 -0
  288. package/dist/src/engine/port.js.map +1 -0
  289. package/dist/src/engine/prompts.d.ts +159 -0
  290. package/dist/src/engine/prompts.d.ts.map +1 -0
  291. package/dist/src/engine/prompts.js +339 -0
  292. package/dist/src/engine/prompts.js.map +1 -0
  293. package/dist/src/engine/render.d.ts +10 -0
  294. package/dist/src/engine/render.d.ts.map +1 -0
  295. package/dist/src/engine/render.js +23 -0
  296. package/dist/src/engine/render.js.map +1 -0
  297. package/dist/src/engine/reviewruntime.d.ts +13 -0
  298. package/dist/src/engine/reviewruntime.d.ts.map +1 -0
  299. package/dist/src/engine/reviewruntime.js +35 -0
  300. package/dist/src/engine/reviewruntime.js.map +1 -0
  301. package/dist/src/engine/reviewsdk.d.ts +75 -0
  302. package/dist/src/engine/reviewsdk.d.ts.map +1 -0
  303. package/dist/src/engine/reviewsdk.js +180 -0
  304. package/dist/src/engine/reviewsdk.js.map +1 -0
  305. package/dist/src/engine/round.d.ts +166 -0
  306. package/dist/src/engine/round.d.ts.map +1 -0
  307. package/dist/src/engine/round.js +543 -0
  308. package/dist/src/engine/round.js.map +1 -0
  309. package/dist/src/engine/roundagents.d.ts +17 -0
  310. package/dist/src/engine/roundagents.d.ts.map +1 -0
  311. package/dist/src/engine/roundagents.js +49 -0
  312. package/dist/src/engine/roundagents.js.map +1 -0
  313. package/dist/src/engine/roundevents.d.ts +110 -0
  314. package/dist/src/engine/roundevents.d.ts.map +1 -0
  315. package/dist/src/engine/roundevents.js +276 -0
  316. package/dist/src/engine/roundevents.js.map +1 -0
  317. package/dist/src/engine/roundsdk.d.ts +33 -0
  318. package/dist/src/engine/roundsdk.d.ts.map +1 -0
  319. package/dist/src/engine/roundsdk.js +76 -0
  320. package/dist/src/engine/roundsdk.js.map +1 -0
  321. package/dist/src/engine/sdkruntime.d.ts +23 -0
  322. package/dist/src/engine/sdkruntime.d.ts.map +1 -0
  323. package/dist/src/engine/sdkruntime.js +340 -0
  324. package/dist/src/engine/sdkruntime.js.map +1 -0
  325. package/dist/src/engine/select.d.ts +16 -0
  326. package/dist/src/engine/select.d.ts.map +1 -0
  327. package/dist/src/engine/select.js +32 -0
  328. package/dist/src/engine/select.js.map +1 -0
  329. package/dist/src/engine/sessionwrap.d.ts +4 -0
  330. package/dist/src/engine/sessionwrap.d.ts.map +1 -0
  331. package/dist/src/engine/sessionwrap.js +31 -0
  332. package/dist/src/engine/sessionwrap.js.map +1 -0
  333. package/dist/src/engine/toolfence.d.ts +90 -0
  334. package/dist/src/engine/toolfence.d.ts.map +1 -0
  335. package/dist/src/engine/toolfence.js +378 -0
  336. package/dist/src/engine/toolfence.js.map +1 -0
  337. package/dist/src/engine/tooluid.d.ts +128 -0
  338. package/dist/src/engine/tooluid.d.ts.map +1 -0
  339. package/dist/src/engine/tooluid.js +401 -0
  340. package/dist/src/engine/tooluid.js.map +1 -0
  341. package/dist/src/envstrip.d.ts +10 -0
  342. package/dist/src/envstrip.d.ts.map +1 -0
  343. package/dist/src/envstrip.js +15 -0
  344. package/dist/src/envstrip.js.map +1 -0
  345. package/dist/src/escalationprompt.d.ts +22 -0
  346. package/dist/src/escalationprompt.d.ts.map +1 -0
  347. package/dist/src/escalationprompt.js +54 -0
  348. package/dist/src/escalationprompt.js.map +1 -0
  349. package/dist/src/execfn.d.ts +29 -0
  350. package/dist/src/execfn.d.ts.map +1 -0
  351. package/dist/src/execfn.js +55 -0
  352. package/dist/src/execfn.js.map +1 -0
  353. package/dist/src/finding-chain.d.ts +40 -0
  354. package/dist/src/finding-chain.d.ts.map +1 -0
  355. package/dist/src/finding-chain.js +76 -0
  356. package/dist/src/finding-chain.js.map +1 -0
  357. package/dist/src/finding-row.d.ts +24 -0
  358. package/dist/src/finding-row.d.ts.map +1 -0
  359. package/dist/src/finding-row.js +26 -0
  360. package/dist/src/finding-row.js.map +1 -0
  361. package/dist/src/findingkey.d.ts +99 -0
  362. package/dist/src/findingkey.d.ts.map +1 -0
  363. package/dist/src/findingkey.js +210 -0
  364. package/dist/src/findingkey.js.map +1 -0
  365. package/dist/src/findingsrecord.d.ts +175 -0
  366. package/dist/src/findingsrecord.d.ts.map +1 -0
  367. package/dist/src/findingsrecord.js +410 -0
  368. package/dist/src/findingsrecord.js.map +1 -0
  369. package/dist/src/followup-mode.d.ts +4 -0
  370. package/dist/src/followup-mode.d.ts.map +1 -0
  371. package/dist/src/followup-mode.js +6 -0
  372. package/dist/src/followup-mode.js.map +1 -0
  373. package/dist/src/gate.d.ts +199 -0
  374. package/dist/src/gate.d.ts.map +1 -0
  375. package/dist/src/gate.js +315 -0
  376. package/dist/src/gate.js.map +1 -0
  377. package/dist/src/ghcred.d.ts +58 -0
  378. package/dist/src/ghcred.d.ts.map +1 -0
  379. package/dist/src/ghcred.js +139 -0
  380. package/dist/src/ghcred.js.map +1 -0
  381. package/dist/src/githubAuth.d.ts +70 -0
  382. package/dist/src/githubAuth.d.ts.map +1 -0
  383. package/dist/src/githubAuth.js +183 -0
  384. package/dist/src/githubAuth.js.map +1 -0
  385. package/dist/src/githubcore.d.ts +20 -0
  386. package/dist/src/githubcore.d.ts.map +1 -0
  387. package/dist/src/githubcore.js +20 -0
  388. package/dist/src/githubcore.js.map +1 -0
  389. package/dist/src/glob.d.ts +11 -0
  390. package/dist/src/glob.d.ts.map +1 -0
  391. package/dist/src/glob.js +69 -0
  392. package/dist/src/glob.js.map +1 -0
  393. package/dist/src/guards.d.ts +106 -0
  394. package/dist/src/guards.d.ts.map +1 -0
  395. package/dist/src/guards.js +365 -0
  396. package/dist/src/guards.js.map +1 -0
  397. package/dist/src/heartbeat.d.ts +29 -0
  398. package/dist/src/heartbeat.d.ts.map +1 -0
  399. package/dist/src/heartbeat.js +87 -0
  400. package/dist/src/heartbeat.js.map +1 -0
  401. package/dist/src/heuristics.d.ts +247 -0
  402. package/dist/src/heuristics.d.ts.map +1 -0
  403. package/dist/src/heuristics.js +927 -0
  404. package/dist/src/heuristics.js.map +1 -0
  405. package/dist/src/homes.d.ts +181 -0
  406. package/dist/src/homes.d.ts.map +1 -0
  407. package/dist/src/homes.js +242 -0
  408. package/dist/src/homes.js.map +1 -0
  409. package/dist/src/hunkheader.d.ts +11 -0
  410. package/dist/src/hunkheader.d.ts.map +1 -0
  411. package/dist/src/hunkheader.js +18 -0
  412. package/dist/src/hunkheader.js.map +1 -0
  413. package/dist/src/identity.d.ts +34 -0
  414. package/dist/src/identity.d.ts.map +1 -0
  415. package/dist/src/identity.js +67 -0
  416. package/dist/src/identity.js.map +1 -0
  417. package/dist/src/include.d.ts +435 -0
  418. package/dist/src/include.d.ts.map +1 -0
  419. package/dist/src/include.js +1692 -0
  420. package/dist/src/include.js.map +1 -0
  421. package/dist/src/launchvocab.d.ts +36 -0
  422. package/dist/src/launchvocab.d.ts.map +1 -0
  423. package/dist/src/launchvocab.js +59 -0
  424. package/dist/src/launchvocab.js.map +1 -0
  425. package/dist/src/ledgercarry.d.ts +24 -0
  426. package/dist/src/ledgercarry.d.ts.map +1 -0
  427. package/dist/src/ledgercarry.js +109 -0
  428. package/dist/src/ledgercarry.js.map +1 -0
  429. package/dist/src/lensids.d.ts +7 -0
  430. package/dist/src/lensids.d.ts.map +1 -0
  431. package/dist/src/lensids.js +53 -0
  432. package/dist/src/lensids.js.map +1 -0
  433. package/dist/src/lensplanning.d.ts +8 -0
  434. package/dist/src/lensplanning.d.ts.map +1 -0
  435. package/dist/src/lensplanning.js +126 -0
  436. package/dist/src/lensplanning.js.map +1 -0
  437. package/dist/src/lensresult.d.ts +94 -0
  438. package/dist/src/lensresult.d.ts.map +1 -0
  439. package/dist/src/lensresult.js +162 -0
  440. package/dist/src/lensresult.js.map +1 -0
  441. package/dist/src/lenstuning.d.ts +97 -0
  442. package/dist/src/lenstuning.d.ts.map +1 -0
  443. package/dist/src/lenstuning.js +326 -0
  444. package/dist/src/lenstuning.js.map +1 -0
  445. package/dist/src/lintconfig.d.ts +31 -0
  446. package/dist/src/lintconfig.d.ts.map +1 -0
  447. package/dist/src/lintconfig.js +543 -0
  448. package/dist/src/lintconfig.js.map +1 -0
  449. package/dist/src/live/events.d.ts +188 -0
  450. package/dist/src/live/events.d.ts.map +1 -0
  451. package/dist/src/live/events.js +136 -0
  452. package/dist/src/live/events.js.map +1 -0
  453. package/dist/src/live/writer.d.ts +54 -0
  454. package/dist/src/live/writer.d.ts.map +1 -0
  455. package/dist/src/live/writer.js +516 -0
  456. package/dist/src/live/writer.js.map +1 -0
  457. package/dist/src/localreview.d.ts +128 -0
  458. package/dist/src/localreview.d.ts.map +1 -0
  459. package/dist/src/localreview.js +426 -0
  460. package/dist/src/localreview.js.map +1 -0
  461. package/dist/src/loosenedtests.d.ts +13 -0
  462. package/dist/src/loosenedtests.d.ts.map +1 -0
  463. package/dist/src/loosenedtests.js +188 -0
  464. package/dist/src/loosenedtests.js.map +1 -0
  465. package/dist/src/memoryport.d.ts +264 -0
  466. package/dist/src/memoryport.d.ts.map +1 -0
  467. package/dist/src/memoryport.js +445 -0
  468. package/dist/src/memoryport.js.map +1 -0
  469. package/dist/src/migrations.d.ts +106 -0
  470. package/dist/src/migrations.d.ts.map +1 -0
  471. package/dist/src/migrations.js +373 -0
  472. package/dist/src/migrations.js.map +1 -0
  473. package/dist/src/modelroute.d.ts +38 -0
  474. package/dist/src/modelroute.d.ts.map +1 -0
  475. package/dist/src/modelroute.js +105 -0
  476. package/dist/src/modelroute.js.map +1 -0
  477. package/dist/src/oneshot.d.ts +12 -0
  478. package/dist/src/oneshot.d.ts.map +1 -0
  479. package/dist/src/oneshot.js +8 -0
  480. package/dist/src/oneshot.js.map +1 -0
  481. package/dist/src/packing.d.ts +11 -0
  482. package/dist/src/packing.d.ts.map +1 -0
  483. package/dist/src/packing.js +31 -0
  484. package/dist/src/packing.js.map +1 -0
  485. package/dist/src/passes.d.ts +16 -0
  486. package/dist/src/passes.d.ts.map +1 -0
  487. package/dist/src/passes.js +104 -0
  488. package/dist/src/passes.js.map +1 -0
  489. package/dist/src/passtasks.d.ts +68 -0
  490. package/dist/src/passtasks.d.ts.map +1 -0
  491. package/dist/src/passtasks.js +360 -0
  492. package/dist/src/passtasks.js.map +1 -0
  493. package/dist/src/pathinside.d.ts +5 -0
  494. package/dist/src/pathinside.d.ts.map +1 -0
  495. package/dist/src/pathinside.js +9 -0
  496. package/dist/src/pathinside.js.map +1 -0
  497. package/dist/src/pibuiltins.d.ts +36 -0
  498. package/dist/src/pibuiltins.d.ts.map +1 -0
  499. package/dist/src/pibuiltins.js +83 -0
  500. package/dist/src/pibuiltins.js.map +1 -0
  501. package/dist/src/plankey.d.ts +4 -0
  502. package/dist/src/plankey.d.ts.map +1 -0
  503. package/dist/src/plankey.js +10 -0
  504. package/dist/src/plankey.js.map +1 -0
  505. package/dist/src/planner.d.ts +375 -0
  506. package/dist/src/planner.d.ts.map +1 -0
  507. package/dist/src/planner.js +722 -0
  508. package/dist/src/planner.js.map +1 -0
  509. package/dist/src/plugin/args.d.ts +19 -0
  510. package/dist/src/plugin/args.d.ts.map +1 -0
  511. package/dist/src/plugin/args.js +107 -0
  512. package/dist/src/plugin/args.js.map +1 -0
  513. package/dist/src/plugin/index.d.ts +3 -0
  514. package/dist/src/plugin/index.d.ts.map +1 -0
  515. package/dist/src/plugin/index.js +14 -0
  516. package/dist/src/plugin/index.js.map +1 -0
  517. package/dist/src/plugin/login.d.ts +42 -0
  518. package/dist/src/plugin/login.d.ts.map +1 -0
  519. package/dist/src/plugin/login.js +82 -0
  520. package/dist/src/plugin/login.js.map +1 -0
  521. package/dist/src/plugin/review.d.ts +27 -0
  522. package/dist/src/plugin/review.d.ts.map +1 -0
  523. package/dist/src/plugin/review.js +302 -0
  524. package/dist/src/plugin/review.js.map +1 -0
  525. package/dist/src/plugin/runner.d.ts +6 -0
  526. package/dist/src/plugin/runner.d.ts.map +1 -0
  527. package/dist/src/plugin/runner.js +65 -0
  528. package/dist/src/plugin/runner.js.map +1 -0
  529. package/dist/src/plugin/scan.d.ts +79 -0
  530. package/dist/src/plugin/scan.d.ts.map +1 -0
  531. package/dist/src/plugin/scan.js +348 -0
  532. package/dist/src/plugin/scan.js.map +1 -0
  533. package/dist/src/plugin/session.d.ts +56 -0
  534. package/dist/src/plugin/session.d.ts.map +1 -0
  535. package/dist/src/plugin/session.js +2 -0
  536. package/dist/src/plugin/session.js.map +1 -0
  537. package/dist/src/plugin/setup.d.ts +19 -0
  538. package/dist/src/plugin/setup.d.ts.map +1 -0
  539. package/dist/src/plugin/setup.js +142 -0
  540. package/dist/src/plugin/setup.js.map +1 -0
  541. package/dist/src/plugin/versiongate.d.ts +26 -0
  542. package/dist/src/plugin/versiongate.d.ts.map +1 -0
  543. package/dist/src/plugin/versiongate.js +83 -0
  544. package/dist/src/plugin/versiongate.js.map +1 -0
  545. package/dist/src/postingkey.d.ts +8 -0
  546. package/dist/src/postingkey.d.ts.map +1 -0
  547. package/dist/src/postingkey.js +25 -0
  548. package/dist/src/postingkey.js.map +1 -0
  549. package/dist/src/postingpolicy.d.ts +108 -0
  550. package/dist/src/postingpolicy.d.ts.map +1 -0
  551. package/dist/src/postingpolicy.js +341 -0
  552. package/dist/src/postingpolicy.js.map +1 -0
  553. package/dist/src/pr-identity.d.ts +3 -0
  554. package/dist/src/pr-identity.d.ts.map +1 -0
  555. package/dist/src/pr-identity.js +9 -0
  556. package/dist/src/pr-identity.js.map +1 -0
  557. package/dist/src/prdelta.d.ts +181 -0
  558. package/dist/src/prdelta.d.ts.map +1 -0
  559. package/dist/src/prdelta.js +501 -0
  560. package/dist/src/prdelta.js.map +1 -0
  561. package/dist/src/pricing.d.ts +94 -0
  562. package/dist/src/pricing.d.ts.map +1 -0
  563. package/dist/src/pricing.js +209 -0
  564. package/dist/src/pricing.js.map +1 -0
  565. package/dist/src/priorfindings.d.ts +167 -0
  566. package/dist/src/priorfindings.d.ts.map +1 -0
  567. package/dist/src/priorfindings.js +445 -0
  568. package/dist/src/priorfindings.js.map +1 -0
  569. package/dist/src/priortasks.d.ts +31 -0
  570. package/dist/src/priortasks.d.ts.map +1 -0
  571. package/dist/src/priortasks.js +119 -0
  572. package/dist/src/priortasks.js.map +1 -0
  573. package/dist/src/profilelookup.d.ts +59 -0
  574. package/dist/src/profilelookup.d.ts.map +1 -0
  575. package/dist/src/profilelookup.js +98 -0
  576. package/dist/src/profilelookup.js.map +1 -0
  577. package/dist/src/profileoverrides.d.ts +91 -0
  578. package/dist/src/profileoverrides.d.ts.map +1 -0
  579. package/dist/src/profileoverrides.js +313 -0
  580. package/dist/src/profileoverrides.js.map +1 -0
  581. package/dist/src/profiles.d.ts +144 -0
  582. package/dist/src/profiles.d.ts.map +1 -0
  583. package/dist/src/profiles.js +604 -0
  584. package/dist/src/profiles.js.map +1 -0
  585. package/dist/src/promptdoc.d.ts +3 -0
  586. package/dist/src/promptdoc.d.ts.map +1 -0
  587. package/dist/src/promptdoc.js +18 -0
  588. package/dist/src/promptdoc.js.map +1 -0
  589. package/dist/src/prtarget.d.ts +70 -0
  590. package/dist/src/prtarget.d.ts.map +1 -0
  591. package/dist/src/prtarget.js +181 -0
  592. package/dist/src/prtarget.js.map +1 -0
  593. package/dist/src/recheckorder.d.ts +32 -0
  594. package/dist/src/recheckorder.d.ts.map +1 -0
  595. package/dist/src/recheckorder.js +5 -0
  596. package/dist/src/recheckorder.js.map +1 -0
  597. package/dist/src/reviewapi.d.ts +207 -0
  598. package/dist/src/reviewapi.d.ts.map +1 -0
  599. package/dist/src/reviewapi.js +939 -0
  600. package/dist/src/reviewapi.js.map +1 -0
  601. package/dist/src/reviewbotfindings.d.ts +33 -0
  602. package/dist/src/reviewbotfindings.d.ts.map +1 -0
  603. package/dist/src/reviewbotfindings.js +80 -0
  604. package/dist/src/reviewbotfindings.js.map +1 -0
  605. package/dist/src/reviewconfig.d.ts +753 -0
  606. package/dist/src/reviewconfig.d.ts.map +1 -0
  607. package/dist/src/reviewconfig.js +805 -0
  608. package/dist/src/reviewconfig.js.map +1 -0
  609. package/dist/src/reviewdelta.d.ts +51 -0
  610. package/dist/src/reviewdelta.d.ts.map +1 -0
  611. package/dist/src/reviewdelta.js +119 -0
  612. package/dist/src/reviewdelta.js.map +1 -0
  613. package/dist/src/reviewdest.d.ts +86 -0
  614. package/dist/src/reviewdest.d.ts.map +1 -0
  615. package/dist/src/reviewdest.js +142 -0
  616. package/dist/src/reviewdest.js.map +1 -0
  617. package/dist/src/reviewerstub.d.ts +12 -0
  618. package/dist/src/reviewerstub.d.ts.map +1 -0
  619. package/dist/src/reviewerstub.js +28 -0
  620. package/dist/src/reviewerstub.js.map +1 -0
  621. package/dist/src/reviewhost.d.ts +58 -0
  622. package/dist/src/reviewhost.d.ts.map +1 -0
  623. package/dist/src/reviewhost.js +135 -0
  624. package/dist/src/reviewhost.js.map +1 -0
  625. package/dist/src/reviewpost.d.ts +79 -0
  626. package/dist/src/reviewpost.d.ts.map +1 -0
  627. package/dist/src/reviewpost.js +233 -0
  628. package/dist/src/reviewpost.js.map +1 -0
  629. package/dist/src/reviewrender.d.ts +154 -0
  630. package/dist/src/reviewrender.d.ts.map +1 -0
  631. package/dist/src/reviewrender.js +480 -0
  632. package/dist/src/reviewrender.js.map +1 -0
  633. package/dist/src/reviewstate.d.ts +62 -0
  634. package/dist/src/reviewstate.d.ts.map +1 -0
  635. package/dist/src/reviewstate.js +167 -0
  636. package/dist/src/reviewstate.js.map +1 -0
  637. package/dist/src/reviewstore.d.ts +17 -0
  638. package/dist/src/reviewstore.d.ts.map +1 -0
  639. package/dist/src/reviewstore.js +105 -0
  640. package/dist/src/reviewstore.js.map +1 -0
  641. package/dist/src/round-progress.d.ts +120 -0
  642. package/dist/src/round-progress.d.ts.map +1 -0
  643. package/dist/src/round-progress.js +172 -0
  644. package/dist/src/round-progress.js.map +1 -0
  645. package/dist/src/round-stage-deadlines.d.ts +12 -0
  646. package/dist/src/round-stage-deadlines.d.ts.map +1 -0
  647. package/dist/src/round-stage-deadlines.js +10 -0
  648. package/dist/src/round-stage-deadlines.js.map +1 -0
  649. package/dist/src/session-command.d.ts +19 -0
  650. package/dist/src/session-command.d.ts.map +1 -0
  651. package/dist/src/session-command.js +20 -0
  652. package/dist/src/session-command.js.map +1 -0
  653. package/dist/src/settledread.d.ts +61 -0
  654. package/dist/src/settledread.d.ts.map +1 -0
  655. package/dist/src/settledread.js +135 -0
  656. package/dist/src/settledread.js.map +1 -0
  657. package/dist/src/severity.d.ts +167 -0
  658. package/dist/src/severity.d.ts.map +1 -0
  659. package/dist/src/severity.js +364 -0
  660. package/dist/src/severity.js.map +1 -0
  661. package/dist/src/severityrank.d.ts +8 -0
  662. package/dist/src/severityrank.d.ts.map +1 -0
  663. package/dist/src/severityrank.js +16 -0
  664. package/dist/src/severityrank.js.map +1 -0
  665. package/dist/src/standing-review.d.ts +45 -0
  666. package/dist/src/standing-review.d.ts.map +1 -0
  667. package/dist/src/standing-review.js +43 -0
  668. package/dist/src/standing-review.js.map +1 -0
  669. package/dist/src/storerows.d.ts +225 -0
  670. package/dist/src/storerows.d.ts.map +1 -0
  671. package/dist/src/storerows.js +7 -0
  672. package/dist/src/storerows.js.map +1 -0
  673. package/dist/src/styleguide.d.ts +25 -0
  674. package/dist/src/styleguide.d.ts.map +1 -0
  675. package/dist/src/styleguide.js +272 -0
  676. package/dist/src/styleguide.js.map +1 -0
  677. package/dist/src/sweepstatus.d.ts +42 -0
  678. package/dist/src/sweepstatus.d.ts.map +1 -0
  679. package/dist/src/sweepstatus.js +97 -0
  680. package/dist/src/sweepstatus.js.map +1 -0
  681. package/dist/src/templates.d.ts +243 -0
  682. package/dist/src/templates.d.ts.map +1 -0
  683. package/dist/src/templates.js +847 -0
  684. package/dist/src/templates.js.map +1 -0
  685. package/dist/src/types.d.ts +639 -0
  686. package/dist/src/types.d.ts.map +1 -0
  687. package/dist/src/types.js +90 -0
  688. package/dist/src/types.js.map +1 -0
  689. package/dist/src/unifieddiff.d.ts +22 -0
  690. package/dist/src/unifieddiff.d.ts.map +1 -0
  691. package/dist/src/unifieddiff.js +176 -0
  692. package/dist/src/unifieddiff.js.map +1 -0
  693. package/dist/src/yieldloop.d.ts +2 -0
  694. package/dist/src/yieldloop.d.ts.map +1 -0
  695. package/dist/src/yieldloop.js +14 -0
  696. package/dist/src/yieldloop.js.map +1 -0
  697. package/package.json +60 -4
@@ -0,0 +1,401 @@
1
+ // The separate tool uid: the image's entrypoint (docker/entrypoint.sh)
2
+ // runs the engine as an unprivileged run uid that holds the GitHub token, with
3
+ // CAP_SETUID/CAP_SETGID as ambient capabilities, and names the uid the model's
4
+ // tools run as in QCR_TOOL_UID/QCR_TOOL_GID. This module is the one place that
5
+ // turns those names into a spawn:
6
+ //
7
+ // - `toolIsolation` wraps a child (pi, or anything else that runs the model's
8
+ // bash) in setpriv, which switches to the tool uid and drops every
9
+ // capability and the ability to gain one back, so the kernel refuses the
10
+ // tools /proc/<this pid>/mem and /environ. Node's own `uid` spawn option is
11
+ // not used: it would leave the ambient capabilities on the child.
12
+ // - `isolatedBashOperations` is the same for the SDK session's bash tool: the
13
+ // model's command is run through setpriv, and stopped through it too (the
14
+ // run uid may not signal a process of another uid).
15
+ // - `checkToolUid` is the gate in front of a host: one that arranges the
16
+ // split passes, one that cannot (a host whose tools are children of a
17
+ // process with no split of its own) refuses rather than run without it,
18
+ // unless the shared uid is accepted.
19
+ //
20
+ // `QCR_TOOL_UID_REQUIRED` is set by the same entrypoint when it could not
21
+ // arrange the separation (it was not started as root): nothing that runs the
22
+ // model's tools is started then, unless QCR_ALLOW_SHARED_TOOL_UID=1 says the
23
+ // shared uid is accepted. Outside the image none of these names is set and
24
+ // nothing changes.
25
+ import { spawn } from "node:child_process";
26
+ import { chmodSync, chownSync, existsSync, lstatSync, readdirSync } from "node:fs";
27
+ import { access } from "node:fs/promises";
28
+ import { dirname, join } from "node:path";
29
+ import { constants as osConstants } from "node:os";
30
+ /** The names the image's entrypoint sets when the model's tools must run as
31
+ * another uid than this process. */
32
+ export const TOOL_UID_ENVS = ["QCR_TOOL_UID", "QCR_TOOL_GID", "QCR_TOOL_UID_REQUIRED"];
33
+ const ID = /^[1-9][0-9]*$/;
34
+ /** What the environment says about the tool uid: the ids to run the tools as, or
35
+ * null where nothing asks for a separation, or why none can be made. Where the
36
+ * ids are named they win, whatever else is set. */
37
+ export function toolIdsOf(env) {
38
+ const uid = env["QCR_TOOL_UID"];
39
+ const gid = env["QCR_TOOL_GID"];
40
+ if (uid || gid) {
41
+ if (!ID.test(uid ?? "") || !ID.test(gid ?? ""))
42
+ return { refused: `QCR_TOOL_UID/QCR_TOOL_GID must be non-zero numeric ids (${uid}:${gid})` };
43
+ return { uid: uid, gid: gid };
44
+ }
45
+ if (env["QCR_TOOL_UID_REQUIRED"] && env["QCR_ALLOW_SHARED_TOOL_UID"] !== "1")
46
+ return {
47
+ refused: "the model's tools would share this process's uid and could read its token through /proc: " +
48
+ "start the container as root with --cap-drop ALL --cap-add SETUID --cap-add SETGID " +
49
+ "(docker/entrypoint.sh drops to QCR_RUN_UID and runs the tools as QCR_TOOL_UID), " +
50
+ "or set QCR_ALLOW_SHARED_TOOL_UID=1 to accept the shared uid",
51
+ };
52
+ return null;
53
+ }
54
+ /** setpriv's switches for the tool uid: its uid and gid with no supplementary
55
+ * groups, no capability, and no way to gain one. Does not include `--`. */
56
+ export function setprivSwitches(ids) {
57
+ return [
58
+ `--reuid=${ids.uid}`,
59
+ `--regid=${ids.gid}`,
60
+ "--clear-groups",
61
+ "--inh-caps=-all",
62
+ "--ambient-caps=-all",
63
+ "--no-new-privs",
64
+ ];
65
+ }
66
+ /** How a child that runs the model's tools is started: through setpriv where the
67
+ * image asks for the tool uid, unchanged where nothing does, refused where the
68
+ * entrypoint could not arrange it. */
69
+ export function toolIsolation(bin, argv, procEnv = process.env) {
70
+ const ids = toolIdsOf(procEnv);
71
+ if (ids === null)
72
+ return { bin, argv, isolated: false };
73
+ if ("refused" in ids)
74
+ return ids;
75
+ // The bot's setid helper where the image names one, else setpriv itself.
76
+ const helper = setidHelperOf(procEnv);
77
+ if (helper !== null && "refused" in helper)
78
+ return helper;
79
+ return {
80
+ bin: helper?.path ?? "setpriv",
81
+ argv: [...setprivSwitches(ids), "--", bin, ...argv],
82
+ isolated: true,
83
+ };
84
+ }
85
+ /** The gate in front of a host that runs the model's tools.
86
+ *
87
+ * A host that starts them itself through the tool uid (`isolated`: the SDK
88
+ * runtime's bash, a debug round's pi) passes where the ids are numeric and
89
+ * non-zero, and is refused where the entrypoint could not arrange the split.
90
+ *
91
+ * A host that cannot (its tools are children of a process that runs in this
92
+ * uid, such as the native lens tool's pi children) refuses wherever the image
93
+ * asks for the separation, unless the shared uid is accepted. `host` words the
94
+ * refusal for the caller. */
95
+ export function checkToolUid(env, host = {
96
+ what: "the SDK runtime",
97
+ instead: "",
98
+ }) {
99
+ if (host.isolated === true) {
100
+ const ids = toolIdsOf(env);
101
+ if (ids !== null && "refused" in ids)
102
+ throw new Error(`${host.what}: ${ids.refused}`);
103
+ return;
104
+ }
105
+ if (env["QCR_ALLOW_SHARED_TOOL_UID"] === "1")
106
+ return;
107
+ if (TOOL_UID_ENVS.some((n) => env[n]))
108
+ throw new Error(`${host.what} runs the model's tools in this process, so it cannot run them as another uid, ` +
109
+ `which this container asks for: ${host.instead === "" ? "" : `${host.instead}, or `}set ` +
110
+ "QCR_ALLOW_SHARED_TOOL_UID=1 to accept the shared uid");
111
+ }
112
+ /**
113
+ * Opens `dir` and everything in it to the tool uid's group: group read and
114
+ * write on files, and group access on directories, each entry handed to the
115
+ * tool gid (`QCR_TOOL_GID`) where that is not this process's own gid (the
116
+ * bot's tools run in a gid of their own; the cli's share the run
117
+ * gid). For a process that runs as the tool uid and needs what the run uid
118
+ * made private (a debug round's pi reading its agent dir); the owner's bits
119
+ * stay. Symbolic links are left as they are, and a missing dir is nothing to
120
+ * share.
121
+ */
122
+ export function shareWithToolGroup(dir, env = process.env) {
123
+ const st = lstatSync(dir, { throwIfNoEntry: false });
124
+ if (st === undefined || st.isSymbolicLink())
125
+ return;
126
+ // An entry another uid owns (the tool uid's own, made under its group-writable
127
+ // umask) is not this process's to change, and needs no sharing.
128
+ if (typeof process.getuid === "function" && st.uid !== process.getuid())
129
+ return;
130
+ const gid = env["QCR_TOOL_GID"];
131
+ if (gid !== undefined && /^[1-9][0-9]*$/.test(gid) && st.gid !== Number(gid))
132
+ chownSync(dir, st.uid, Number(gid));
133
+ if (st.isDirectory()) {
134
+ chmodSync(dir, (st.mode & 0o7777) | 0o070);
135
+ for (const name of readdirSync(dir))
136
+ shareWithToolGroup(join(dir, name), env);
137
+ }
138
+ else if (st.isFile()) {
139
+ chmodSync(dir, (st.mode & 0o7777) | 0o060);
140
+ }
141
+ }
142
+ /**
143
+ * The environment a command run as the tool uid needs on top of the one it was
144
+ * given: git's `safe.directory = *` in the command scope.
145
+ *
146
+ * The repositories the model reads (the worktrees, the base clone) belong to the
147
+ * run uid, and git refuses a repository another uid owns ("dubious ownership").
148
+ * The image's system config says `*`, but a review session pins git's system
149
+ * scope off (src/sessions.ts sessionGitConfigPins), and `safe.directory` is read
150
+ * only from a protected scope: system, global or command. So it rides the
151
+ * command scope (GIT_CONFIG_COUNT/KEY_n/VALUE_n), appended after any entries the
152
+ * env already carries, never in place of them. It widens nothing: the
153
+ * repositories are the run uid's, which the tool uid trusts by construction.
154
+ */
155
+ export function toolUidEnv(env) {
156
+ const given = env["GIT_CONFIG_COUNT"];
157
+ const n = given !== undefined && /^\d{1,3}$/.test(given) ? Number(given) : 0;
158
+ return {
159
+ ...env,
160
+ GIT_CONFIG_COUNT: String(n + 1),
161
+ [`GIT_CONFIG_KEY_${n}`]: "safe.directory",
162
+ [`GIT_CONFIG_VALUE_${n}`]: "*",
163
+ };
164
+ }
165
+ /** The umask a tool-uid command runs under: group-writable files, which is how
166
+ * the run uid and the tool uid (one gid, two uids) share what either writes. */
167
+ export const TOOL_UMASK = 0o002;
168
+ /** The shell program that runs a tool-uid command: it sets the umask and
169
+ * replaces itself with the shell on the command, so the command is still
170
+ * `<shell> -c <command>` (one argument, the same $0) under the same pid, which
171
+ * leads its process group. */
172
+ const UMASK_THEN_RUN = `umask 002 && exec "$0" -c "$1"`;
173
+ /** Where setpriv is looked for: root-owned system dirs, never the model's PATH. */
174
+ const SETPRIV_DIRS = ["/usr/bin", "/bin", "/usr/sbin", "/sbin"];
175
+ const SETPRIV_PATH = SETPRIV_DIRS.join(":");
176
+ /** The setpriv the spawner runs, which holds the ambient SETUID/SETGID: an
177
+ * absolute path in a system dir. A PATH entry the tool uid can write must not
178
+ * be able to plant the binary the next command runs with those capabilities.
179
+ * Null where no system dir has one. */
180
+ export function trustedSetpriv(exists = existsSync, env = process.env) {
181
+ const helper = setidHelperOf(env);
182
+ if (helper !== null)
183
+ return "path" in helper ? helper.path : null;
184
+ return SETPRIV_DIRS.map((d) => join(d, "setpriv")).find(exists) ?? null;
185
+ }
186
+ /**
187
+ * The bot's setid helper, named by `QCR_SETPRIV_BIN`: the image's
188
+ * own copy of setpriv that carries CAP_SETUID/CAP_SETGID as FILE capabilities
189
+ * and only a gate group may run (docker/Dockerfile). The always-on bot runs as
190
+ * its own uid, not root, so `docker exec` into it keeps landing as that uid; it
191
+ * reaches the tool uid through this helper instead of ambient capabilities
192
+ * (docker/entrypoint.sh's daemon mode). The model's tools never get it: they run
193
+ * with no_new_privs, under which a file capability grants nothing, and without
194
+ * the gate group.
195
+ *
196
+ * Trusted only as a root-owned regular file in a root-owned directory, neither
197
+ * writable by group or others: the run uid must not be able to swap the binary
198
+ * it hands its capabilities to. Null where the env names none; `refused` where
199
+ * it names one that fails those checks.
200
+ */
201
+ export function setidHelperOf(env, stat = (p) => lstatSync(p, { throwIfNoEntry: false })) {
202
+ const named = env["QCR_SETPRIV_BIN"]?.trim();
203
+ if (named === undefined || named === "")
204
+ return null;
205
+ const refuse = (why) => ({ refused: `QCR_SETPRIV_BIN ${named}: ${why}` });
206
+ if (!named.startsWith("/"))
207
+ return refuse("not an absolute path");
208
+ const file = stat(named);
209
+ if (file === undefined || !file.isFile())
210
+ return refuse("not a regular file");
211
+ const dir = stat(dirname(named));
212
+ if (dir === undefined || !dir.isDirectory())
213
+ return refuse("its directory is not a directory");
214
+ for (const [what, st] of [
215
+ ["it", file],
216
+ ["its directory", dir],
217
+ ]) {
218
+ if (st.uid !== 0)
219
+ return refuse(`${what} is not owned by root`);
220
+ if ((st.mode & 0o022) !== 0)
221
+ return refuse(`${what} is writable by group or others`);
222
+ }
223
+ return { path: named };
224
+ }
225
+ /** The shell the model's commands run in: pi's own choice on Unix. */
226
+ function shellPath() {
227
+ return existsSync("/bin/bash") ? "/bin/bash" : "sh";
228
+ }
229
+ /** After the shell exits, how long output still arriving on a pipe a descendant
230
+ * holds open is waited for (pi's own grace). */
231
+ const EXIT_STDIO_GRACE_MS = 100;
232
+ /** The stdio of a command: nothing in, its output out, and each of `inherit`
233
+ * handed to it at the SAME fd number. Node closes every descriptor a child is
234
+ * not listed with, so an fd a command (or a script under it) must read has to be
235
+ * named here. */
236
+ export function commandStdio(inherit) {
237
+ const stdio = ["ignore", "pipe", "pipe"];
238
+ for (const fd of inherit) {
239
+ if (!Number.isInteger(fd) || fd < 3)
240
+ throw new Error(`cannot hand a command fd ${fd}`);
241
+ while (stdio.length < fd)
242
+ stdio.push("ignore");
243
+ stdio[fd] = fd;
244
+ }
245
+ return stdio;
246
+ }
247
+ function shellOperations(plan, inherit) {
248
+ const stdio = commandStdio(inherit);
249
+ return {
250
+ exec: async (command, cwd, { onData, signal, timeout, env }) => {
251
+ plan.ready();
252
+ if (signal?.aborted)
253
+ throw new Error("aborted");
254
+ if (timeout !== undefined && !(Number.isFinite(timeout) && timeout > 0))
255
+ throw new Error("Invalid timeout: must be a finite number of seconds");
256
+ try {
257
+ await access(cwd);
258
+ }
259
+ catch {
260
+ throw new Error(`Working directory does not exist: ${cwd}\nCannot execute bash commands.`);
261
+ }
262
+ const { bin, argv } = plan.start(command);
263
+ const given = env ?? process.env;
264
+ const child = spawn(bin, argv, {
265
+ cwd,
266
+ env: plan.env ? plan.env(given) : given,
267
+ detached: true,
268
+ stdio,
269
+ });
270
+ const pgid = child.pid;
271
+ const killGroup = () => {
272
+ if (pgid !== undefined)
273
+ plan.killGroup(pgid);
274
+ };
275
+ let timedOut = false;
276
+ const timer = timeout === undefined
277
+ ? undefined
278
+ : setTimeout(() => {
279
+ timedOut = true;
280
+ killGroup();
281
+ }, timeout * 1000);
282
+ const onAbort = () => killGroup();
283
+ signal?.addEventListener("abort", onAbort, { once: true });
284
+ // an abort during the cwd check fired before the listener existed
285
+ if (signal?.aborted)
286
+ onAbort();
287
+ try {
288
+ child.stdout.on("data", onData);
289
+ child.stderr.on("data", onData);
290
+ const exitCode = await new Promise((resolve, reject) => {
291
+ let exited = false;
292
+ let code = null;
293
+ let idle;
294
+ const done = () => {
295
+ if (idle)
296
+ clearTimeout(idle);
297
+ child.stdout.destroy();
298
+ child.stderr.destroy();
299
+ resolve(code);
300
+ };
301
+ const arm = () => {
302
+ if (idle)
303
+ clearTimeout(idle);
304
+ idle = setTimeout(done, EXIT_STDIO_GRACE_MS);
305
+ };
306
+ child.once("error", reject);
307
+ child.once("exit", (c) => {
308
+ exited = true;
309
+ code = c;
310
+ arm();
311
+ });
312
+ child.once("close", (c) => {
313
+ code = c ?? code;
314
+ done();
315
+ });
316
+ // output still arriving after the exit keeps the wait open
317
+ child.stdout.on("data", () => exited && arm());
318
+ child.stderr.on("data", () => exited && arm());
319
+ });
320
+ if (signal?.aborted)
321
+ throw new Error("aborted");
322
+ if (timedOut)
323
+ throw new Error(`timeout:${timeout}`);
324
+ // A signal-killed shell has no exit code: the shell convention, as pi has it.
325
+ const signalled = child.signalCode ? 128 + (osConstants.signals[child.signalCode] ?? 0) : 1;
326
+ return { exitCode: exitCode ?? signalled };
327
+ }
328
+ finally {
329
+ if (timer)
330
+ clearTimeout(timer);
331
+ signal?.removeEventListener("abort", onAbort);
332
+ }
333
+ },
334
+ };
335
+ }
336
+ /**
337
+ * The SDK bash tool's execution, with the model's command run as the tool uid.
338
+ *
339
+ * The command is `setpriv … -- bash -c <command>` in a process group of its
340
+ * own, the umask set first (TOOL_UMASK) and git's safe.directory in its env
341
+ * (toolUidEnv). A timeout or an abort ends that group through setpriv too: the run uid
342
+ * may not signal a process of another uid (kill(2): the sender's uid must match
343
+ * the target's real or saved uid, and this process holds no CAP_KILL), so pi's
344
+ * own kill of the tree would silently do nothing and the command would run on.
345
+ * The saved uid cannot be left as the run uid to allow it: the tool could then
346
+ * switch back.
347
+ *
348
+ * `inherit` lists descriptors every command gets at the same number (the
349
+ * bot worker's IPC capability).
350
+ */
351
+ export function isolatedBashOperations(ids, setprivBin, inherit = []) {
352
+ const switches = setprivSwitches(ids);
353
+ const setpriv = setprivBin ?? trustedSetpriv();
354
+ const helper = setprivBin === undefined ? setidHelperOf(process.env) : null;
355
+ return shellOperations({
356
+ ready: () => {
357
+ if (helper !== null && "refused" in helper)
358
+ throw new Error(`${helper.refused}: the tool uid cannot be used`);
359
+ if (setpriv === null)
360
+ throw new Error("setpriv is in none of " + SETPRIV_PATH + ": the tool uid cannot be used");
361
+ },
362
+ start: (command) => ({
363
+ bin: setpriv,
364
+ argv: [...switches, "--", shellPath(), "-c", UMASK_THEN_RUN, shellPath(), command],
365
+ }),
366
+ env: toolUidEnv,
367
+ // The group's end, as the tool uid. Best effort: a failure leaves the
368
+ // command running, as pi's own kill does when it cannot signal.
369
+ killGroup: (pgid) => {
370
+ try {
371
+ spawn(setpriv, [...switches, "--", shellPath(), "-c", 'kill -KILL -- "-$0" 2>/dev/null', String(pgid)],
372
+ // the killing shell needs no PATH of the model's
373
+ { stdio: "ignore", env: { PATH: SETPRIV_PATH } })
374
+ .once("error", () => { })
375
+ .unref();
376
+ }
377
+ catch {
378
+ // setpriv could not be started: nothing more can be done from here
379
+ }
380
+ },
381
+ }, inherit);
382
+ }
383
+ /** The same execution with no uid change, for a host whose commands must
384
+ * inherit descriptors (`inherit`): pi's own local operations start a command
385
+ * with nothing but stdio. The command runs in a process group of its own, which
386
+ * a timeout or an abort ends. */
387
+ export function inheritingBashOperations(inherit) {
388
+ return shellOperations({
389
+ ready: () => { },
390
+ start: (command) => ({ bin: shellPath(), argv: ["-c", command] }),
391
+ killGroup: (pgid) => {
392
+ try {
393
+ process.kill(-pgid, "SIGKILL");
394
+ }
395
+ catch {
396
+ // already gone
397
+ }
398
+ },
399
+ }, inherit);
400
+ }
401
+ //# sourceMappingURL=tooluid.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tooluid.js","sourceRoot":"","sources":["../../../src/engine/tooluid.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ export declare const GITHUB_TOKEN_ENVS: readonly ["GITHUB_TOKEN", "GH_TOKEN", "GH_ENTERPRISE_TOKEN"];
2
+ /** Git without any system or global config and never prompting: every
3
+ * environment a reviewer's model or a harness git call runs in carries it. */
4
+ export declare const GIT_ISOLATION_ENV: {
5
+ readonly GIT_CONFIG_NOSYSTEM: "1";
6
+ readonly GIT_CONFIG_SYSTEM: "/dev/null";
7
+ readonly GIT_CONFIG_GLOBAL: "/dev/null";
8
+ readonly GIT_TERMINAL_PROMPT: "0";
9
+ };
10
+ //# sourceMappingURL=envstrip.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"envstrip.d.ts","sourceRoot":"","sources":["../../src/envstrip.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,iBAAiB,8DAA+D,CAAC;AAE9F;8EAC8E;AAC9E,eAAO,MAAM,iBAAiB;;;;;CAKpB,CAAC"}
@@ -0,0 +1,15 @@
1
+ // Env names that carry a GitHub credential. A process that runs a model's
2
+ // tools, or hands an env to a child that does, drops every one of these
3
+ // first: the token never reaches a process the model can read. And git's
4
+ // isolation, which every such env carries. No imports, so engine code, scan
5
+ // and the daemon can all take it.
6
+ export const GITHUB_TOKEN_ENVS = ["GITHUB_TOKEN", "GH_TOKEN", "GH_ENTERPRISE_TOKEN"];
7
+ /** Git without any system or global config and never prompting: every
8
+ * environment a reviewer's model or a harness git call runs in carries it. */
9
+ export const GIT_ISOLATION_ENV = {
10
+ GIT_CONFIG_NOSYSTEM: "1",
11
+ GIT_CONFIG_SYSTEM: "/dev/null",
12
+ GIT_CONFIG_GLOBAL: "/dev/null",
13
+ GIT_TERMINAL_PROMPT: "0",
14
+ };
15
+ //# sourceMappingURL=envstrip.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"envstrip.js","sourceRoot":"","sources":["../../src/envstrip.ts"],"names":[],"mappings":"AAAA,0EAA0E;AAC1E,wEAAwE;AACxE,yEAAyE;AACzE,4EAA4E;AAC5E,kCAAkC;AAClC,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,cAAc,EAAE,UAAU,EAAE,qBAAqB,CAAU,CAAC;AAE9F;8EAC8E;AAC9E,MAAM,CAAC,MAAM,iBAAiB,GAAG;IAC/B,mBAAmB,EAAE,GAAG;IACxB,iBAAiB,EAAE,WAAW;IAC9B,iBAAiB,EAAE,WAAW;IAC9B,mBAAmB,EAAE,GAAG;CAChB,CAAC"}
@@ -0,0 +1,22 @@
1
+ import type { EscalationConfig } from "./reviewconfig.js";
2
+ /**
3
+ * The targets a round order carries, or none.
4
+ *
5
+ * A round order gets this list ONLY when the feature is enabled AND the
6
+ * operator turned session judgement on — so with escalation off (the default)
7
+ * the field is absent, the note below renders `""`, and the round prompt is
8
+ * identical in behaviour to a build without the feature (whitespace aside —
9
+ * see the pin in tests/escalation.test.ts).
10
+ */
11
+ export declare function promptTargetsFor(cfg: EscalationConfig): string[] | undefined;
12
+ /**
13
+ * The round-prompt block, rendered into `{{escalation_note}}` by
14
+ * `packages/pi-plugin/src/templates.ts`.
15
+ *
16
+ * The deterministic rules need no prompt at all: the daemon evaluates and
17
+ * delivers them itself. This block exists only so a session that MAY escalate
18
+ * on its own judgement knows the shape, the bound and — above all — that
19
+ * escalating never changes its job.
20
+ */
21
+ export declare function renderEscalationPromptNote(targets: readonly string[] | undefined): string;
22
+ //# sourceMappingURL=escalationprompt.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"escalationprompt.d.ts","sourceRoot":"","sources":["../../src/escalationprompt.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAE1D;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,gBAAgB,GAAG,MAAM,EAAE,GAAG,SAAS,CAG5E;AAED;;;;;;;;GAQG;AACH,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,GAAG,MAAM,CA4BzF"}
@@ -0,0 +1,54 @@
1
+ /**
2
+ * The targets a round order carries, or none.
3
+ *
4
+ * A round order gets this list ONLY when the feature is enabled AND the
5
+ * operator turned session judgement on — so with escalation off (the default)
6
+ * the field is absent, the note below renders `""`, and the round prompt is
7
+ * identical in behaviour to a build without the feature (whitespace aside —
8
+ * see the pin in tests/escalation.test.ts).
9
+ */
10
+ export function promptTargetsFor(cfg) {
11
+ if (!cfg.enabled || !cfg.session_judgement || cfg.targets.length === 0)
12
+ return undefined;
13
+ return [...cfg.targets];
14
+ }
15
+ /**
16
+ * The round-prompt block, rendered into `{{escalation_note}}` by
17
+ * `packages/pi-plugin/src/templates.ts`.
18
+ *
19
+ * The deterministic rules need no prompt at all: the daemon evaluates and
20
+ * delivers them itself. This block exists only so a session that MAY escalate
21
+ * on its own judgement knows the shape, the bound and — above all — that
22
+ * escalating never changes its job.
23
+ */
24
+ export function renderEscalationPromptNote(targets) {
25
+ if (!targets || targets.length === 0)
26
+ return "";
27
+ return [
28
+ "ESCALATION (optional, and it never changes your job).",
29
+ "",
30
+ "You always decide this PR on the merits and post the review — escalation is a note that goes",
31
+ "out BESIDE your verdict, never instead of it, and never a reason to withhold or defer one.",
32
+ "",
33
+ "If one specific thing in this change genuinely needs a named person's eyes, add an",
34
+ "`escalations` array to your verdict file. Each entry:",
35
+ "",
36
+ "```json",
37
+ '{ "target": "<one of the logins below>",',
38
+ ' "scope": { "kind": "code", "path": "<repo-relative file>", "start_line": 12, "end_line": 30 },',
39
+ ' "question": "<one or two sentences about THAT code>",',
40
+ ' "why": "<why this person>" }',
41
+ "```",
42
+ "",
43
+ `Targets you may name (any other login is dropped by the daemon): ${targets.map((t) => `@${t}`).join(", ")}`,
44
+ "",
45
+ "`scope.kind` is `code` (path plus line range), `migration` (path, optionally the migration",
46
+ 'id) or `decision` (a named decision). There is no way to escalate "the PR" and you must not',
47
+ "try: an entry with no concrete scope, or a question that asks someone to review the change,",
48
+ "is dropped. Think of it exactly as a `[check this]` item with a name on it — the smallest",
49
+ "thing that actually needs a person, phrased so they can answer it in minutes.",
50
+ "",
51
+ "Escalating is rare. Omitting the array entirely is the normal outcome.",
52
+ ].join("\n");
53
+ }
54
+ //# sourceMappingURL=escalationprompt.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"escalationprompt.js","sourceRoot":"","sources":["../../src/escalationprompt.ts"],"names":[],"mappings":"AAMA;;;;;;;;GAQG;AACH,MAAM,UAAU,gBAAgB,CAAC,GAAqB;IACpD,IAAI,CAAC,GAAG,CAAC,OAAO,IAAI,CAAC,GAAG,CAAC,iBAAiB,IAAI,GAAG,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,SAAS,CAAC;IACzF,OAAO,CAAC,GAAG,GAAG,CAAC,OAAO,CAAC,CAAC;AAC1B,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,0BAA0B,CAAC,OAAsC;IAC/E,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IAChD,OAAO;QACL,uDAAuD;QACvD,EAAE;QACF,8FAA8F;QAC9F,4FAA4F;QAC5F,EAAE;QACF,oFAAoF;QACpF,uDAAuD;QACvD,EAAE;QACF,SAAS;QACT,0CAA0C;QAC1C,kGAAkG;QAClG,yDAAyD;QACzD,gCAAgC;QAChC,KAAK;QACL,EAAE;QACF,oEAAoE,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;QAC5G,EAAE;QACF,4FAA4F;QAC5F,6FAA6F;QAC7F,6FAA6F;QAC7F,2FAA2F;QAC3F,+EAA+E;QAC/E,EAAE;QACF,wEAAwE;KACzE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACf,CAAC"}
@@ -0,0 +1,29 @@
1
+ export interface ExecOpts {
2
+ cwd?: string;
3
+ /** Fully-constructed environment. Callers pass an explicit env — never a
4
+ * spread of process.env — so no personal credential can leak into a
5
+ * session. */
6
+ env?: NodeJS.ProcessEnv;
7
+ input?: string;
8
+ timeoutMs?: number;
9
+ /** Stops the command: the child is killed and the call rejects with the
10
+ * signal's AbortError. */
11
+ signal?: AbortSignal;
12
+ }
13
+ export interface ExecResult {
14
+ code: number;
15
+ stdout: string;
16
+ stderr: string;
17
+ }
18
+ export type ExecFn = (cmd: string, args: string[], opts?: ExecOpts) => Promise<ExecResult>;
19
+ export declare class ExecError extends Error {
20
+ readonly cmd: string;
21
+ readonly args: string[];
22
+ readonly result: ExecResult;
23
+ constructor(cmd: string, args: string[], result: ExecResult);
24
+ }
25
+ /** Default ExecFn: spawn, capture, never inherit a shell. */
26
+ export declare const nodeExec: ExecFn;
27
+ /** Run and throw on a non-zero exit. */
28
+ export declare function runOrThrow(exec: ExecFn, cmd: string, args: string[], opts?: ExecOpts): Promise<ExecResult>;
29
+ //# sourceMappingURL=execfn.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"execfn.d.ts","sourceRoot":"","sources":["../../src/execfn.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,QAAQ;IACvB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;;kBAEc;IACd,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACxB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;8BAC0B;IAC1B,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,MAAM,MAAM,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,IAAI,CAAC,EAAE,QAAQ,KAAK,OAAO,CAAC,UAAU,CAAC,CAAC;AAE3F,qBAAa,SAAU,SAAQ,KAAK;IAEhC,QAAQ,CAAC,GAAG,EAAE,MAAM;IACpB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE;IACvB,QAAQ,CAAC,MAAM,EAAE,UAAU;gBAFlB,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,MAAM,EAAE,EACd,MAAM,EAAE,UAAU;CAO9B;AAED,6DAA6D;AAC7D,eAAO,MAAM,QAAQ,EAAE,MA0BnB,CAAC;AAEL,wCAAwC;AACxC,wBAAsB,UAAU,CAC9B,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,MAAM,EAAE,EACd,IAAI,CAAC,EAAE,QAAQ,GACd,OAAO,CAAC,UAAU,CAAC,CAIrB"}
@@ -0,0 +1,55 @@
1
+ // The process-exec primitive every git, tmux and pi command goes through: an
2
+ // injectable ExecFn, so tests can record invocations instead of spawning
3
+ // anything. A leaf with no repo imports, so the review core (the delta reader,
4
+ // packages/pi-plugin/src/prdelta.ts) and the CLI use it without reaching src/tmux.ts.
5
+ import { spawn } from "node:child_process";
6
+ export class ExecError extends Error {
7
+ cmd;
8
+ args;
9
+ result;
10
+ constructor(cmd, args, result) {
11
+ super(`${cmd} ${args.join(" ")} exited ${result.code}: ${result.stderr.trim() || result.stdout.trim()}`);
12
+ this.cmd = cmd;
13
+ this.args = args;
14
+ this.result = result;
15
+ this.name = "ExecError";
16
+ }
17
+ }
18
+ /** Default ExecFn: spawn, capture, never inherit a shell. */
19
+ export const nodeExec = (cmd, args, opts = {}) => new Promise((resolvePromise, reject) => {
20
+ const child = spawn(cmd, args, {
21
+ cwd: opts.cwd,
22
+ env: opts.env,
23
+ stdio: [opts.input === undefined ? "ignore" : "pipe", "pipe", "pipe"],
24
+ ...(opts.signal ? { signal: opts.signal, killSignal: "SIGKILL" } : {}),
25
+ });
26
+ let stdout = "";
27
+ let stderr = "";
28
+ let timer;
29
+ if (opts.timeoutMs)
30
+ timer = setTimeout(() => child.kill("SIGKILL"), opts.timeoutMs);
31
+ child.stdout?.on("data", (d) => (stdout += String(d)));
32
+ child.stderr?.on("data", (d) => (stderr += String(d)));
33
+ child.on("error", (err) => {
34
+ if (timer)
35
+ clearTimeout(timer);
36
+ reject(err);
37
+ });
38
+ child.on("close", (code) => {
39
+ if (timer)
40
+ clearTimeout(timer);
41
+ resolvePromise({ code: code ?? -1, stdout, stderr });
42
+ });
43
+ if (opts.input !== undefined) {
44
+ child.stdin?.write(opts.input);
45
+ child.stdin?.end();
46
+ }
47
+ });
48
+ /** Run and throw on a non-zero exit. */
49
+ export async function runOrThrow(exec, cmd, args, opts) {
50
+ const res = await exec(cmd, args, opts);
51
+ if (res.code !== 0)
52
+ throw new ExecError(cmd, args, res);
53
+ return res;
54
+ }
55
+ //# sourceMappingURL=execfn.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"execfn.js","sourceRoot":"","sources":["../../src/execfn.ts"],"names":[],"mappings":"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"}