@quickchatai/pi-quickreview 0.0.0-stage → 1.1.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 (689) 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 +1067 -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 +74 -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 +372 -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 +226 -0
  282. package/dist/src/engine/pisdk.d.ts.map +1 -0
  283. package/dist/src/engine/pisdk.js +552 -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 +32 -0
  382. package/dist/src/githubAuth.d.ts.map +1 -0
  383. package/dist/src/githubAuth.js +116 -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 +93 -0
  394. package/dist/src/guards.d.ts.map +1 -0
  395. package/dist/src/guards.js +306 -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/include.d.ts +435 -0
  414. package/dist/src/include.d.ts.map +1 -0
  415. package/dist/src/include.js +1692 -0
  416. package/dist/src/include.js.map +1 -0
  417. package/dist/src/launchvocab.d.ts +36 -0
  418. package/dist/src/launchvocab.d.ts.map +1 -0
  419. package/dist/src/launchvocab.js +59 -0
  420. package/dist/src/launchvocab.js.map +1 -0
  421. package/dist/src/ledgercarry.d.ts +24 -0
  422. package/dist/src/ledgercarry.d.ts.map +1 -0
  423. package/dist/src/ledgercarry.js +109 -0
  424. package/dist/src/ledgercarry.js.map +1 -0
  425. package/dist/src/lensids.d.ts +7 -0
  426. package/dist/src/lensids.d.ts.map +1 -0
  427. package/dist/src/lensids.js +53 -0
  428. package/dist/src/lensids.js.map +1 -0
  429. package/dist/src/lensplanning.d.ts +8 -0
  430. package/dist/src/lensplanning.d.ts.map +1 -0
  431. package/dist/src/lensplanning.js +126 -0
  432. package/dist/src/lensplanning.js.map +1 -0
  433. package/dist/src/lensresult.d.ts +94 -0
  434. package/dist/src/lensresult.d.ts.map +1 -0
  435. package/dist/src/lensresult.js +162 -0
  436. package/dist/src/lensresult.js.map +1 -0
  437. package/dist/src/lenstuning.d.ts +97 -0
  438. package/dist/src/lenstuning.d.ts.map +1 -0
  439. package/dist/src/lenstuning.js +326 -0
  440. package/dist/src/lenstuning.js.map +1 -0
  441. package/dist/src/lintconfig.d.ts +31 -0
  442. package/dist/src/lintconfig.d.ts.map +1 -0
  443. package/dist/src/lintconfig.js +543 -0
  444. package/dist/src/lintconfig.js.map +1 -0
  445. package/dist/src/live/events.d.ts +188 -0
  446. package/dist/src/live/events.d.ts.map +1 -0
  447. package/dist/src/live/events.js +136 -0
  448. package/dist/src/live/events.js.map +1 -0
  449. package/dist/src/live/writer.d.ts +54 -0
  450. package/dist/src/live/writer.d.ts.map +1 -0
  451. package/dist/src/live/writer.js +516 -0
  452. package/dist/src/live/writer.js.map +1 -0
  453. package/dist/src/localreview.d.ts +128 -0
  454. package/dist/src/localreview.d.ts.map +1 -0
  455. package/dist/src/localreview.js +426 -0
  456. package/dist/src/localreview.js.map +1 -0
  457. package/dist/src/loosenedtests.d.ts +13 -0
  458. package/dist/src/loosenedtests.d.ts.map +1 -0
  459. package/dist/src/loosenedtests.js +188 -0
  460. package/dist/src/loosenedtests.js.map +1 -0
  461. package/dist/src/memoryport.d.ts +264 -0
  462. package/dist/src/memoryport.d.ts.map +1 -0
  463. package/dist/src/memoryport.js +445 -0
  464. package/dist/src/memoryport.js.map +1 -0
  465. package/dist/src/migrations.d.ts +106 -0
  466. package/dist/src/migrations.d.ts.map +1 -0
  467. package/dist/src/migrations.js +373 -0
  468. package/dist/src/migrations.js.map +1 -0
  469. package/dist/src/oneshot.d.ts +12 -0
  470. package/dist/src/oneshot.d.ts.map +1 -0
  471. package/dist/src/oneshot.js +8 -0
  472. package/dist/src/oneshot.js.map +1 -0
  473. package/dist/src/packing.d.ts +11 -0
  474. package/dist/src/packing.d.ts.map +1 -0
  475. package/dist/src/packing.js +31 -0
  476. package/dist/src/packing.js.map +1 -0
  477. package/dist/src/passes.d.ts +16 -0
  478. package/dist/src/passes.d.ts.map +1 -0
  479. package/dist/src/passes.js +104 -0
  480. package/dist/src/passes.js.map +1 -0
  481. package/dist/src/passtasks.d.ts +68 -0
  482. package/dist/src/passtasks.d.ts.map +1 -0
  483. package/dist/src/passtasks.js +360 -0
  484. package/dist/src/passtasks.js.map +1 -0
  485. package/dist/src/pathinside.d.ts +5 -0
  486. package/dist/src/pathinside.d.ts.map +1 -0
  487. package/dist/src/pathinside.js +9 -0
  488. package/dist/src/pathinside.js.map +1 -0
  489. package/dist/src/pibuiltins.d.ts +36 -0
  490. package/dist/src/pibuiltins.d.ts.map +1 -0
  491. package/dist/src/pibuiltins.js +83 -0
  492. package/dist/src/pibuiltins.js.map +1 -0
  493. package/dist/src/plankey.d.ts +4 -0
  494. package/dist/src/plankey.d.ts.map +1 -0
  495. package/dist/src/plankey.js +10 -0
  496. package/dist/src/plankey.js.map +1 -0
  497. package/dist/src/planner.d.ts +375 -0
  498. package/dist/src/planner.d.ts.map +1 -0
  499. package/dist/src/planner.js +722 -0
  500. package/dist/src/planner.js.map +1 -0
  501. package/dist/src/plugin/args.d.ts +19 -0
  502. package/dist/src/plugin/args.d.ts.map +1 -0
  503. package/dist/src/plugin/args.js +107 -0
  504. package/dist/src/plugin/args.js.map +1 -0
  505. package/dist/src/plugin/index.d.ts +3 -0
  506. package/dist/src/plugin/index.d.ts.map +1 -0
  507. package/dist/src/plugin/index.js +14 -0
  508. package/dist/src/plugin/index.js.map +1 -0
  509. package/dist/src/plugin/login.d.ts +39 -0
  510. package/dist/src/plugin/login.d.ts.map +1 -0
  511. package/dist/src/plugin/login.js +73 -0
  512. package/dist/src/plugin/login.js.map +1 -0
  513. package/dist/src/plugin/review.d.ts +27 -0
  514. package/dist/src/plugin/review.d.ts.map +1 -0
  515. package/dist/src/plugin/review.js +298 -0
  516. package/dist/src/plugin/review.js.map +1 -0
  517. package/dist/src/plugin/runner.d.ts +6 -0
  518. package/dist/src/plugin/runner.d.ts.map +1 -0
  519. package/dist/src/plugin/runner.js +65 -0
  520. package/dist/src/plugin/runner.js.map +1 -0
  521. package/dist/src/plugin/scan.d.ts +79 -0
  522. package/dist/src/plugin/scan.d.ts.map +1 -0
  523. package/dist/src/plugin/scan.js +348 -0
  524. package/dist/src/plugin/scan.js.map +1 -0
  525. package/dist/src/plugin/session.d.ts +56 -0
  526. package/dist/src/plugin/session.d.ts.map +1 -0
  527. package/dist/src/plugin/session.js +2 -0
  528. package/dist/src/plugin/session.js.map +1 -0
  529. package/dist/src/plugin/setup.d.ts +19 -0
  530. package/dist/src/plugin/setup.d.ts.map +1 -0
  531. package/dist/src/plugin/setup.js +142 -0
  532. package/dist/src/plugin/setup.js.map +1 -0
  533. package/dist/src/plugin/versiongate.d.ts +26 -0
  534. package/dist/src/plugin/versiongate.d.ts.map +1 -0
  535. package/dist/src/plugin/versiongate.js +83 -0
  536. package/dist/src/plugin/versiongate.js.map +1 -0
  537. package/dist/src/postingkey.d.ts +8 -0
  538. package/dist/src/postingkey.d.ts.map +1 -0
  539. package/dist/src/postingkey.js +25 -0
  540. package/dist/src/postingkey.js.map +1 -0
  541. package/dist/src/postingpolicy.d.ts +108 -0
  542. package/dist/src/postingpolicy.d.ts.map +1 -0
  543. package/dist/src/postingpolicy.js +341 -0
  544. package/dist/src/postingpolicy.js.map +1 -0
  545. package/dist/src/pr-identity.d.ts +3 -0
  546. package/dist/src/pr-identity.d.ts.map +1 -0
  547. package/dist/src/pr-identity.js +9 -0
  548. package/dist/src/pr-identity.js.map +1 -0
  549. package/dist/src/prdelta.d.ts +181 -0
  550. package/dist/src/prdelta.d.ts.map +1 -0
  551. package/dist/src/prdelta.js +501 -0
  552. package/dist/src/prdelta.js.map +1 -0
  553. package/dist/src/pricing.d.ts +94 -0
  554. package/dist/src/pricing.d.ts.map +1 -0
  555. package/dist/src/pricing.js +209 -0
  556. package/dist/src/pricing.js.map +1 -0
  557. package/dist/src/priorfindings.d.ts +167 -0
  558. package/dist/src/priorfindings.d.ts.map +1 -0
  559. package/dist/src/priorfindings.js +445 -0
  560. package/dist/src/priorfindings.js.map +1 -0
  561. package/dist/src/priortasks.d.ts +31 -0
  562. package/dist/src/priortasks.d.ts.map +1 -0
  563. package/dist/src/priortasks.js +119 -0
  564. package/dist/src/priortasks.js.map +1 -0
  565. package/dist/src/profilelookup.d.ts +59 -0
  566. package/dist/src/profilelookup.d.ts.map +1 -0
  567. package/dist/src/profilelookup.js +98 -0
  568. package/dist/src/profilelookup.js.map +1 -0
  569. package/dist/src/profileoverrides.d.ts +91 -0
  570. package/dist/src/profileoverrides.d.ts.map +1 -0
  571. package/dist/src/profileoverrides.js +313 -0
  572. package/dist/src/profileoverrides.js.map +1 -0
  573. package/dist/src/profiles.d.ts +144 -0
  574. package/dist/src/profiles.d.ts.map +1 -0
  575. package/dist/src/profiles.js +604 -0
  576. package/dist/src/profiles.js.map +1 -0
  577. package/dist/src/promptdoc.d.ts +3 -0
  578. package/dist/src/promptdoc.d.ts.map +1 -0
  579. package/dist/src/promptdoc.js +18 -0
  580. package/dist/src/promptdoc.js.map +1 -0
  581. package/dist/src/prtarget.d.ts +70 -0
  582. package/dist/src/prtarget.d.ts.map +1 -0
  583. package/dist/src/prtarget.js +181 -0
  584. package/dist/src/prtarget.js.map +1 -0
  585. package/dist/src/recheckorder.d.ts +32 -0
  586. package/dist/src/recheckorder.d.ts.map +1 -0
  587. package/dist/src/recheckorder.js +5 -0
  588. package/dist/src/recheckorder.js.map +1 -0
  589. package/dist/src/reviewapi.d.ts +207 -0
  590. package/dist/src/reviewapi.d.ts.map +1 -0
  591. package/dist/src/reviewapi.js +939 -0
  592. package/dist/src/reviewapi.js.map +1 -0
  593. package/dist/src/reviewbotfindings.d.ts +33 -0
  594. package/dist/src/reviewbotfindings.d.ts.map +1 -0
  595. package/dist/src/reviewbotfindings.js +80 -0
  596. package/dist/src/reviewbotfindings.js.map +1 -0
  597. package/dist/src/reviewconfig.d.ts +741 -0
  598. package/dist/src/reviewconfig.d.ts.map +1 -0
  599. package/dist/src/reviewconfig.js +797 -0
  600. package/dist/src/reviewconfig.js.map +1 -0
  601. package/dist/src/reviewdelta.d.ts +51 -0
  602. package/dist/src/reviewdelta.d.ts.map +1 -0
  603. package/dist/src/reviewdelta.js +119 -0
  604. package/dist/src/reviewdelta.js.map +1 -0
  605. package/dist/src/reviewdest.d.ts +86 -0
  606. package/dist/src/reviewdest.d.ts.map +1 -0
  607. package/dist/src/reviewdest.js +142 -0
  608. package/dist/src/reviewdest.js.map +1 -0
  609. package/dist/src/reviewerstub.d.ts +12 -0
  610. package/dist/src/reviewerstub.d.ts.map +1 -0
  611. package/dist/src/reviewerstub.js +28 -0
  612. package/dist/src/reviewerstub.js.map +1 -0
  613. package/dist/src/reviewhost.d.ts +58 -0
  614. package/dist/src/reviewhost.d.ts.map +1 -0
  615. package/dist/src/reviewhost.js +135 -0
  616. package/dist/src/reviewhost.js.map +1 -0
  617. package/dist/src/reviewpost.d.ts +79 -0
  618. package/dist/src/reviewpost.d.ts.map +1 -0
  619. package/dist/src/reviewpost.js +233 -0
  620. package/dist/src/reviewpost.js.map +1 -0
  621. package/dist/src/reviewrender.d.ts +154 -0
  622. package/dist/src/reviewrender.d.ts.map +1 -0
  623. package/dist/src/reviewrender.js +480 -0
  624. package/dist/src/reviewrender.js.map +1 -0
  625. package/dist/src/reviewstate.d.ts +62 -0
  626. package/dist/src/reviewstate.d.ts.map +1 -0
  627. package/dist/src/reviewstate.js +167 -0
  628. package/dist/src/reviewstate.js.map +1 -0
  629. package/dist/src/reviewstore.d.ts +17 -0
  630. package/dist/src/reviewstore.d.ts.map +1 -0
  631. package/dist/src/reviewstore.js +105 -0
  632. package/dist/src/reviewstore.js.map +1 -0
  633. package/dist/src/round-progress.d.ts +120 -0
  634. package/dist/src/round-progress.d.ts.map +1 -0
  635. package/dist/src/round-progress.js +172 -0
  636. package/dist/src/round-progress.js.map +1 -0
  637. package/dist/src/round-stage-deadlines.d.ts +12 -0
  638. package/dist/src/round-stage-deadlines.d.ts.map +1 -0
  639. package/dist/src/round-stage-deadlines.js +10 -0
  640. package/dist/src/round-stage-deadlines.js.map +1 -0
  641. package/dist/src/session-command.d.ts +19 -0
  642. package/dist/src/session-command.d.ts.map +1 -0
  643. package/dist/src/session-command.js +20 -0
  644. package/dist/src/session-command.js.map +1 -0
  645. package/dist/src/settledread.d.ts +61 -0
  646. package/dist/src/settledread.d.ts.map +1 -0
  647. package/dist/src/settledread.js +135 -0
  648. package/dist/src/settledread.js.map +1 -0
  649. package/dist/src/severity.d.ts +167 -0
  650. package/dist/src/severity.d.ts.map +1 -0
  651. package/dist/src/severity.js +364 -0
  652. package/dist/src/severity.js.map +1 -0
  653. package/dist/src/severityrank.d.ts +8 -0
  654. package/dist/src/severityrank.d.ts.map +1 -0
  655. package/dist/src/severityrank.js +16 -0
  656. package/dist/src/severityrank.js.map +1 -0
  657. package/dist/src/standing-review.d.ts +45 -0
  658. package/dist/src/standing-review.d.ts.map +1 -0
  659. package/dist/src/standing-review.js +43 -0
  660. package/dist/src/standing-review.js.map +1 -0
  661. package/dist/src/storerows.d.ts +225 -0
  662. package/dist/src/storerows.d.ts.map +1 -0
  663. package/dist/src/storerows.js +7 -0
  664. package/dist/src/storerows.js.map +1 -0
  665. package/dist/src/styleguide.d.ts +25 -0
  666. package/dist/src/styleguide.d.ts.map +1 -0
  667. package/dist/src/styleguide.js +272 -0
  668. package/dist/src/styleguide.js.map +1 -0
  669. package/dist/src/sweepstatus.d.ts +42 -0
  670. package/dist/src/sweepstatus.d.ts.map +1 -0
  671. package/dist/src/sweepstatus.js +97 -0
  672. package/dist/src/sweepstatus.js.map +1 -0
  673. package/dist/src/templates.d.ts +243 -0
  674. package/dist/src/templates.d.ts.map +1 -0
  675. package/dist/src/templates.js +847 -0
  676. package/dist/src/templates.js.map +1 -0
  677. package/dist/src/types.d.ts +639 -0
  678. package/dist/src/types.d.ts.map +1 -0
  679. package/dist/src/types.js +90 -0
  680. package/dist/src/types.js.map +1 -0
  681. package/dist/src/unifieddiff.d.ts +22 -0
  682. package/dist/src/unifieddiff.d.ts.map +1 -0
  683. package/dist/src/unifieddiff.js +176 -0
  684. package/dist/src/unifieddiff.js.map +1 -0
  685. package/dist/src/yieldloop.d.ts +2 -0
  686. package/dist/src/yieldloop.d.ts.map +1 -0
  687. package/dist/src/yieldloop.js +14 -0
  688. package/dist/src/yieldloop.js.map +1 -0
  689. package/package.json +60 -4
@@ -0,0 +1,210 @@
1
+ // Passive pi auth-failure detection: no smoke calls — watch the session
2
+ // JSONLs pi already writes and raise when sessions start failing with
3
+ // token-expired API errors. The live signature:
4
+ // "errorMessage":"Provided authentication token is expired."
5
+ // The scanner tail-reads recently-modified *.jsonl under the pi sessions dir
6
+ // (one nesting level: pi groups sessions by cwd) — cheap enough for a 60s
7
+ // tick, and entirely observational: it never talks to any API.
8
+ // Only a record's own `errorMessage` FIELD is tested — never the raw line:
9
+ // reviewer sessions store tool results verbatim (diffs, file reads, CI logs),
10
+ // and a PR touching OAuth code puts "invalid_grant" in them as plain text.
11
+ import { closeSync, openSync, readSync, readdirSync, statSync } from "node:fs";
12
+ import { join, sep } from "node:path";
13
+ export const PI_AUTH_ERROR_RE = /authentication token is expired|invalid_grant|401 unauthorized/i;
14
+ /** True when a JSONL line is a record carrying an auth-failure `errorMessage`
15
+ * field — at any depth, since a subagent's failed message arrives nested in
16
+ * its tool result. Text inside string values (tool output, quoted JSON) never
17
+ * matches: it is data, not a key. Non-JSON lines never match. */
18
+ export function lineHasAuthError(line) {
19
+ if (!line.includes("errorMessage"))
20
+ return false;
21
+ let record;
22
+ try {
23
+ record = JSON.parse(line);
24
+ }
25
+ catch {
26
+ return false;
27
+ }
28
+ const visit = (x, depth) => {
29
+ if (depth > 12 || typeof x !== "object" || x === null)
30
+ return false;
31
+ if (Array.isArray(x))
32
+ return x.some((y) => visit(y, depth + 1));
33
+ const r = x;
34
+ const msg = r["errorMessage"];
35
+ if (typeof msg === "string" && PI_AUTH_ERROR_RE.test(msg))
36
+ return true;
37
+ return Object.values(r).some((v) => visit(v, depth + 1));
38
+ };
39
+ return visit(record, 0);
40
+ }
41
+ /** Only the tail is read: session JSONLs grow large, and a live auth failure
42
+ * is by definition near the end of the file. */
43
+ export const AUTH_TAIL_BYTES = 128 * 1024;
44
+ /** The complete lines of `path` not yet scanned: from `from` (clamped into the
45
+ * last `bytes`) up to the last newline. Returns the text and the offset the
46
+ * NEXT read starts at — just past that newline, so a line still being written
47
+ * is read whole, exactly once, next time rather than split or counted twice. */
48
+ function readFrom(path, from, bytes) {
49
+ const fd = openSync(path, "r");
50
+ try {
51
+ const size = statSync(path).size;
52
+ // A file that shrank was rewritten: its old offset means nothing.
53
+ const start = Math.max(from > size ? 0 : from, size - bytes, 0);
54
+ const buf = Buffer.alloc(size - start);
55
+ readSync(fd, buf, 0, buf.length, start);
56
+ // Only COMPLETE lines are tested: a trailing partial line is left for the
57
+ // next scan, so testing it now too would count the same error twice.
58
+ const lastNl = buf.lastIndexOf(0x0a);
59
+ if (lastNl < 0)
60
+ return { text: "", next: start };
61
+ return { text: buf.subarray(0, lastNl + 1).toString("utf8"), next: start + lastNl + 1 };
62
+ }
63
+ finally {
64
+ closeSync(fd);
65
+ }
66
+ }
67
+ /** Scan *.jsonl files modified at/after `sinceMs` (dir + one sublevel) for
68
+ * auth-error signatures. Unreadable files are skipped — observation must
69
+ * never throw into the daemon tick — and counted (`scanPiAuth`'s `unread`),
70
+ * so a caller keeps them inside its next window.
71
+ *
72
+ * `seen` (path → byte offset, updated in place) makes the scan read only what
73
+ * was appended since the last scan, so an old error still inside the tail
74
+ * never matches again after a re-login and the flag can clear. A file not in
75
+ * `seen` is read tail-only.
76
+ *
77
+ * `seen` is also pruned: an entry under `sessionsDir` whose file
78
+ * the listing no longer shows — archived, or its whole session dir gone — is
79
+ * dropped, so the map tracks the live tree instead of every file that ever
80
+ * existed. Only a listing that answered prunes: an entry under a directory
81
+ * that could not be read stays (its file is unknown, never gone). */
82
+ export function scanPiAuthErrors(sessionsDir, sinceMs, seen) {
83
+ return scanPiAuth(sessionsDir, sinceMs, seen).hits;
84
+ }
85
+ /** `scanPiAuthErrors`, with how many observations failed (a directory that
86
+ * could not be listed, an entry that could not be stat'd, a file that could
87
+ * not be read): those were not seen, so they are not "quiet". */
88
+ function scanPiAuth(sessionsDir, sinceMs, seen) {
89
+ const hits = [];
90
+ let unread = 0;
91
+ /** Every path the listing showed, and the dirs it could not list. */
92
+ const present = new Set();
93
+ const unlisted = [];
94
+ const visit = (dir, depth) => {
95
+ let names = [];
96
+ try {
97
+ names = readdirSync(dir);
98
+ }
99
+ catch (err) {
100
+ if (err.code !== "ENOENT") {
101
+ unlisted.push(dir);
102
+ unread++;
103
+ }
104
+ return;
105
+ }
106
+ for (const name of names) {
107
+ const path = join(dir, name);
108
+ present.add(path);
109
+ let st;
110
+ try {
111
+ st = statSync(path);
112
+ }
113
+ catch (err) {
114
+ // Gone since the listing: nothing to see. Anything else is unknown —
115
+ // its offsets (a directory's, or the file's own) are kept.
116
+ if (err.code !== "ENOENT") {
117
+ unlisted.push(path);
118
+ unread++;
119
+ }
120
+ continue;
121
+ }
122
+ if (st.isDirectory()) {
123
+ if (depth < 1)
124
+ visit(path, depth + 1);
125
+ else
126
+ unlisted.push(path); // deeper than the scan reads: unknown
127
+ continue;
128
+ }
129
+ if (!name.endsWith(".jsonl") || st.mtimeMs < sinceMs)
130
+ continue;
131
+ try {
132
+ const { text, next } = readFrom(path, seen?.get(path) ?? 0, AUTH_TAIL_BYTES);
133
+ seen?.set(path, next);
134
+ if (text.split("\n").some(lineHasAuthError))
135
+ hits.push({ file: path, mtimeMs: st.mtimeMs });
136
+ }
137
+ catch {
138
+ unread++;
139
+ }
140
+ }
141
+ };
142
+ visit(sessionsDir, 0);
143
+ if (seen) {
144
+ const under = `${sessionsDir}${sep}`;
145
+ for (const path of [...seen.keys()]) {
146
+ if (!path.startsWith(under) || present.has(path))
147
+ continue;
148
+ if (unlisted.some((d) => path === d || path.startsWith(`${d}${sep}`)))
149
+ continue;
150
+ seen.delete(path);
151
+ }
152
+ }
153
+ return { hits, unread };
154
+ }
155
+ /** How long a detection keeps the status flag up with no fresh errors. */
156
+ export const AUTH_FLAG_FRESH_MS = 30 * 60 * 1000;
157
+ /**
158
+ * Stateful watcher for the daemon tick. Each scan covers files modified since
159
+ * the previous scan (first scan looks 10 minutes back). `status()` reports
160
+ * the flag while the last detection is fresh (< AUTH_FLAG_FRESH_MS) — the
161
+ * flag clears itself once the errors stop.
162
+ */
163
+ export class PiAuthWatch {
164
+ now;
165
+ sinceMs;
166
+ lastErrorAt = null;
167
+ totalHits = 0;
168
+ /** Per-file offset already scanned — a match is a NEW error line, never an
169
+ * old one the tail still holds. */
170
+ seen = new Map();
171
+ sessionsDirs;
172
+ constructor(
173
+ /** One root, or several: each is scanned the same way (dir + one sublevel). */
174
+ sessionsDirs, now = () => new Date()) {
175
+ this.now = now;
176
+ this.sessionsDirs = typeof sessionsDirs === "string" ? [sessionsDirs] : [...sessionsDirs];
177
+ this.sinceMs = this.now().getTime() - 10 * 60 * 1000;
178
+ }
179
+ /** How many files the scan is tracking an offset for — the live tree's
180
+ * session files it has read, never every file that ever existed. */
181
+ trackedFiles() {
182
+ return this.seen.size;
183
+ }
184
+ /** Returns the NEW hits found this scan (empty array when quiet). */
185
+ scan() {
186
+ const started = this.now().getTime();
187
+ const scans = this.sessionsDirs.map((dir) => scanPiAuth(dir, this.sinceMs, this.seen));
188
+ const hits = scans.flatMap((x) => x.hits);
189
+ // Next scan starts at this scan's start, minus a minute of overlap so a
190
+ // write racing the scan is never missed; the per-file offsets keep the
191
+ // overlap from re-reading (and re-counting) bytes already scanned. A scan
192
+ // that could not read something keeps its window: what it missed stays
193
+ // eligible until a scan reads it (the offsets still stop a re-count).
194
+ if (scans.every((x) => x.unread === 0))
195
+ this.sinceMs = started - 60 * 1000;
196
+ if (hits.length > 0) {
197
+ this.lastErrorAt = started;
198
+ this.totalHits += hits.length;
199
+ }
200
+ return hits;
201
+ }
202
+ status() {
203
+ if (this.lastErrorAt === null)
204
+ return undefined;
205
+ if (this.now().getTime() - this.lastErrorAt > AUTH_FLAG_FRESH_MS)
206
+ return undefined;
207
+ return { last_at: new Date(this.lastErrorAt).toISOString(), hits: this.totalHits };
208
+ }
209
+ }
210
+ //# sourceMappingURL=authwatch.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"authwatch.js","sourceRoot":"","sources":["../../src/authwatch.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ export type Bounded<T> = {
2
+ kind: "done";
3
+ value: T;
4
+ } | {
5
+ kind: "budget";
6
+ };
7
+ /**
8
+ * `work`'s answer, or `{ kind: "budget" }` once `ms` has passed — whichever
9
+ * comes first; the timer is cleared either way and never holds the process
10
+ * open. The work is NOT cancelled (a read already in the kernel cannot be): it
11
+ * runs on, and its late answer or rejection is dropped. A rejection BEFORE the
12
+ * budget is the caller's to catch.
13
+ */
14
+ export declare function withinBudget<T>(work: Promise<T>, ms: number): Promise<Bounded<T>>;
15
+ //# sourceMappingURL=budget.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"budget.d.ts","sourceRoot":"","sources":["../../src/budget.ts"],"names":[],"mappings":"AAMA,MAAM,MAAM,OAAO,CAAC,CAAC,IAAI;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,CAAC,CAAA;CAAE,GAAG;IAAE,IAAI,EAAE,QAAQ,CAAA;CAAE,CAAC;AAEzE;;;;;;GAMG;AACH,wBAAsB,YAAY,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAgBvF"}
@@ -0,0 +1,32 @@
1
+ // A bounded wait. A round end waits for its transcripts and its
2
+ // integrity re-hash, and a dispatch for its integrity baseline, at most so
3
+ // long — then goes on without the answer. A filesystem read that never
4
+ // returns must cost a bounded wait and an honest "unknown", never a verdict
5
+ // that is not applied or a dispatch pump that never moves again.
6
+ /**
7
+ * `work`'s answer, or `{ kind: "budget" }` once `ms` has passed — whichever
8
+ * comes first; the timer is cleared either way and never holds the process
9
+ * open. The work is NOT cancelled (a read already in the kernel cannot be): it
10
+ * runs on, and its late answer or rejection is dropped. A rejection BEFORE the
11
+ * budget is the caller's to catch.
12
+ */
13
+ export async function withinBudget(work, ms) {
14
+ let timer;
15
+ const budget = new Promise((resolve) => {
16
+ timer = setTimeout(() => resolve({ kind: "budget" }), Math.max(0, ms));
17
+ timer.unref?.();
18
+ });
19
+ // Keeps a loser's late rejection handled.
20
+ work.catch(() => undefined);
21
+ try {
22
+ return await Promise.race([
23
+ work.then((value) => ({ kind: "done", value })),
24
+ budget,
25
+ ]);
26
+ }
27
+ finally {
28
+ if (timer !== undefined)
29
+ clearTimeout(timer);
30
+ }
31
+ }
32
+ //# sourceMappingURL=budget.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"budget.js","sourceRoot":"","sources":["../../src/budget.ts"],"names":[],"mappings":"AAAA,gEAAgE;AAChE,2EAA2E;AAC3E,uEAAuE;AACvE,4EAA4E;AAC5E,iEAAiE;AAIjE;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAI,IAAgB,EAAE,EAAU;IAChE,IAAI,KAAgD,CAAC;IACrD,MAAM,MAAM,GAAG,IAAI,OAAO,CAAa,CAAC,OAAO,EAAE,EAAE;QACjD,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;QACvE,KAAK,CAAC,KAAK,EAAE,EAAE,CAAC;IAClB,CAAC,CAAC,CAAC;IACH,0CAA0C;IAC1C,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;IAC5B,IAAI,CAAC;QACH,OAAO,MAAM,OAAO,CAAC,IAAI,CAAC;YACxB,IAAI,CAAC,IAAI,CAAC,CAAC,KAAK,EAAc,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC;YAC3D,MAAM;SACP,CAAC,CAAC;IACL,CAAC;YAAS,CAAC;QACT,IAAI,KAAK,KAAK,SAAS;YAAE,YAAY,CAAC,KAAK,CAAC,CAAC;IAC/C,CAAC;AACH,CAAC"}
@@ -0,0 +1,3 @@
1
+ /** Time reserved for a leaf pi process to stop after cancellation. */
2
+ export declare const CASE_STOP_GRACE_MS = 5000;
3
+ //# sourceMappingURL=casebudget.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"casebudget.d.ts","sourceRoot":"","sources":["../../src/casebudget.ts"],"names":[],"mappings":"AAAA,sEAAsE;AACtE,eAAO,MAAM,kBAAkB,OAAQ,CAAC"}
@@ -0,0 +1,3 @@
1
+ /** Time reserved for a leaf pi process to stop after cancellation. */
2
+ export const CASE_STOP_GRACE_MS = 5_000;
3
+ //# sourceMappingURL=casebudget.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"casebudget.js","sourceRoot":"","sources":["../../src/casebudget.ts"],"names":[],"mappings":"AAAA,sEAAsE;AACtE,MAAM,CAAC,MAAM,kBAAkB,GAAG,KAAK,CAAC"}
@@ -0,0 +1,116 @@
1
+ /**
2
+ * One check at a head, as GitHub's check-runs / statuses APIs report it.
3
+ *
4
+ * `source` says which of the two APIs it came from, and the adapter
5
+ * (`github.ts listChecks`) is its ONLY writer. It is the carrier the
6
+ * latest-run rule keys on: a check-run can supersede an older
7
+ * check-run of its name; a commit status never supersedes anything and is
8
+ * never superseded. Without the kind on the row, a status and a check-run of
9
+ * one name are told apart only by whether `started_at` happens to be set —
10
+ * and a check-run GitHub reports with a null start then reads as a status.
11
+ */
12
+ export interface CheckSummary {
13
+ name: string;
14
+ /** `check_run` from the check-runs API; `status` from the combined status
15
+ * endpoint (which already dedupes statuses per context). */
16
+ source: "check_run" | "status";
17
+ /** `queued` | `in_progress` | `completed` (statuses map onto these). */
18
+ status: string;
19
+ /** `success` | `failure` | `cancelled` | `timed_out` | `skipped` | … */
20
+ conclusion: string | null;
21
+ /** When the run started — the recency key for latest-run-per-name
22
+ * among check-runs. Set on check-runs (nullable in GitHub's schema)
23
+ * and never on commit statuses: the adapter does not carry a time for
24
+ * them, and `latestRunPerName` does not collapse them at all. */
25
+ started_at?: string | null;
26
+ }
27
+ /**
28
+ * The four things CI can be at a head:
29
+ *
30
+ * - `green` every check completed and at least one really succeeded
31
+ * - `red` something completed badly — failure, cancelled, timed out,
32
+ * action_required, stale. No special-casing: an infra
33
+ * cancellation blocks exactly like a failing test.
34
+ * - `pending` a check is still queued or running — not green *yet*
35
+ * - `none` no check reported at this head at all
36
+ */
37
+ export type CiState = "green" | "red" | "pending" | "none";
38
+ /**
39
+ * Only the most recent run of each check name counts. GitHub auto-cancels
40
+ * superseded workflow runs, leaving permanent `completed/cancelled` husks
41
+ * beside the run that actually finished; counting every run would classify
42
+ * such a head red forever and no withheld approval could ever release.
43
+ *
44
+ * The rule, exactly, keyed on `source`:
45
+ *
46
+ * - Only CHECK-RUNS collapse. Among check-runs of one name that carry a
47
+ * `started_at`, the latest start wins; an equal start resolves to the
48
+ * later list position. A check-run WITHOUT a timestamp (null in GitHub's
49
+ * schema) never competes with a timestamped one in either direction — it
50
+ * stands beside that name's latest timestamped run and counts on its own;
51
+ * among untimestamped check-runs of one name the later list position wins.
52
+ * A missing timestamp is unknown, never "older than everything".
53
+ * - A COMMIT STATUS is never collapsed with anything — not with a check-run
54
+ * of its name, not with another status. The combined status endpoint
55
+ * already dedupes per context, and a status under the same context as a
56
+ * check-run is a second check, not a superseded run.
57
+ *
58
+ * Why the kind and not the timestamp decides: collapsing a status with a
59
+ * same-named check-run lets one hide the other. A failing status could lose
60
+ * to a passing check-run, or an untimestamped check-run (queued, or failed
61
+ * with a null start) could lose to a passing status listed after it — either
62
+ * way red or pending reads green. `scripts/pr-checks.sh` reads check-runs and commit statuses and applies
63
+ * both clauses. Keep the two in step (`tests/fences-cigate.test.ts`).
64
+ */
65
+ export declare function latestRunPerName(checks: readonly CheckSummary[]): CheckSummary[];
66
+ /**
67
+ * Classify the checks at one head. Pure — both the gate guard and the shell
68
+ * mirror answer from this table, so "green" means the same thing on every
69
+ * posting route.
70
+ *
71
+ * A suite whose every check is skipped or neutral is not green: it reports
72
+ * `red`, because there is no evidence this PR's code passed anything.
73
+ */
74
+ export declare function classifyCi(allChecks: readonly CheckSummary[]): CiState;
75
+ /**
76
+ * One check's outcome — the per-check half of `classifyCi`, and the one
77
+ * reading of a check anything else (the escalation's failing-check rule)
78
+ * may use. `failed` is every finished conclusion that is neither a success
79
+ * nor inert: failure, cancelled, timed_out, action_required, stale, …
80
+ */
81
+ export declare function checkOutcome(c: CheckSummary): "pending" | "success" | "inert" | "failed";
82
+ /**
83
+ * Does this CI state make APPROVE unavailable?
84
+ *
85
+ * `none` blocks only when `noChecksIsRed` says so: in a repo that normally
86
+ * runs CI, a head with zero check-runs — a conflicted PR, or CI that has not
87
+ * started — carries no execution evidence, so approval waits for checks to
88
+ * appear and pass. The flag is off by default so a repo with no CI at all is
89
+ * never permanently wedged.
90
+ */
91
+ export declare function ciBlocksApproval(state: CiState, opts?: {
92
+ noChecksIsRed?: boolean;
93
+ }): boolean;
94
+ /** Plain-words reason, for the note and the logs. */
95
+ export declare function ciStateReason(state: CiState): string;
96
+ /**
97
+ * The paragraph a withheld review carries. It says the two things the author
98
+ * needs — that the review is finished and found nothing blocking, and that the
99
+ * approval is waiting on CI and on nothing else — so the work is never
100
+ * invisible while CI is broken.
101
+ */
102
+ export declare function withheldApprovalNote(state: CiState, headSha: string): string;
103
+ /** The review payload as it appears inside a `create_review` intent. */
104
+ export interface CiReviewBody {
105
+ commit_id?: string;
106
+ event?: string;
107
+ body?: string;
108
+ comments?: unknown[];
109
+ }
110
+ /**
111
+ * APPROVE → COMMENT, findings untouched, with the withheld note appended.
112
+ * Never REQUEST_CHANGES: there is nothing for the author to change on the
113
+ * review's account, and the fault may be the base branch or infra.
114
+ */
115
+ export declare function withholdApproval(body: CiReviewBody, state: CiState, headSha: string): CiReviewBody;
116
+ //# sourceMappingURL=cigate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cigate.d.ts","sourceRoot":"","sources":["../../src/cigate.ts"],"names":[],"mappings":"AA2BA;;;;;;;;;;GAUG;AACH,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb;gEAC4D;IAC5D,MAAM,EAAE,WAAW,GAAG,QAAQ,CAAC;IAC/B,wEAAwE;IACxE,MAAM,EAAE,MAAM,CAAC;IACf,wEAAwE;IACxE,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B;;;qEAGiE;IACjE,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B;AAED;;;;;;;;;GASG;AACH,MAAM,MAAM,OAAO,GAAG,OAAO,GAAG,KAAK,GAAG,SAAS,GAAG,MAAM,CAAC;AAS3D;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,SAAS,YAAY,EAAE,GAAG,YAAY,EAAE,CAwBhF;AAED;;;;;;;GAOG;AACH,wBAAgB,UAAU,CAAC,SAAS,EAAE,SAAS,YAAY,EAAE,GAAG,OAAO,CAatE;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,CAAC,EAAE,YAAY,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,GAAG,QAAQ,CAOxF;AAED;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,GAAE;IAAE,aAAa,CAAC,EAAE,OAAO,CAAA;CAAO,GAAG,OAAO,CAGhG;AAED,qDAAqD;AACrD,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAWpD;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAO5E;AAED,wEAAwE;AACxE,MAAM,WAAW,YAAY;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,OAAO,EAAE,CAAC;CACtB;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,YAAY,EAClB,KAAK,EAAE,OAAO,EACd,OAAO,EAAE,MAAM,GACd,YAAY,CAMd"}
@@ -0,0 +1,176 @@
1
+ // Red CI hard-gates APPROVE.
2
+ //
3
+ // The rule: no green CI at this head ⇒ APPROVE is unavailable, regardless of
4
+ // findings. Infra problems block as well — deliberately simpler and stricter
5
+ // than judging whether a failure is attributable to the PR, because a rule
6
+ // that is argued case by case in prose makes the verdict depend on which
7
+ // reviewer ran. The code is still reviewed and the findings still posted;
8
+ // only the verdict is gated.
9
+ //
10
+ // Where the rule lives:
11
+ //
12
+ // round-*.md Decide step ─► the session withholds the approval itself and
13
+ // posts the full review as a COMMENT
14
+ // guards.ts (guard 4) ─► the gate rewrites an APPROVE review to COMMENT
15
+ // this module ─► the classifier both halves share
16
+ // ciretry.ts ─► the retry (the bot's half)
17
+ //
18
+ // The retry is what makes the gate safe: a PR whose approval is withheld needs
19
+ // something to notice when CI goes green, or an infra flake becomes a
20
+ // permanently stuck PR. `approval_withheld` (state.ts) is the mark, the
21
+ // `ci_completed` webhook is the trigger, and `retryWithheldApproval`
22
+ // (src/ciretry.ts) re-queues the PR so its session can decide again — at
23
+ // which point the approval is simply available.
24
+ //
25
+ // Nothing here triggers, re-runs or cancels CI: every call in this module is a
26
+ // GET, exactly as the no-exec policy requires (`gh pr checks` / `gh api` only).
27
+ /** Conclusions that are neither a success nor a failure: a path-filtered job
28
+ * skipped, an advisory check. They neither make CI green nor make it red. */
29
+ const INERT_CONCLUSIONS = new Set(["skipped", "neutral"]);
30
+ /** Not-yet-finished statuses. Anything else is treated as completed. */
31
+ const UNFINISHED = new Set(["queued", "in_progress", "waiting", "pending", "requested"]);
32
+ /**
33
+ * Only the most recent run of each check name counts. GitHub auto-cancels
34
+ * superseded workflow runs, leaving permanent `completed/cancelled` husks
35
+ * beside the run that actually finished; counting every run would classify
36
+ * such a head red forever and no withheld approval could ever release.
37
+ *
38
+ * The rule, exactly, keyed on `source`:
39
+ *
40
+ * - Only CHECK-RUNS collapse. Among check-runs of one name that carry a
41
+ * `started_at`, the latest start wins; an equal start resolves to the
42
+ * later list position. A check-run WITHOUT a timestamp (null in GitHub's
43
+ * schema) never competes with a timestamped one in either direction — it
44
+ * stands beside that name's latest timestamped run and counts on its own;
45
+ * among untimestamped check-runs of one name the later list position wins.
46
+ * A missing timestamp is unknown, never "older than everything".
47
+ * - A COMMIT STATUS is never collapsed with anything — not with a check-run
48
+ * of its name, not with another status. The combined status endpoint
49
+ * already dedupes per context, and a status under the same context as a
50
+ * check-run is a second check, not a superseded run.
51
+ *
52
+ * Why the kind and not the timestamp decides: collapsing a status with a
53
+ * same-named check-run lets one hide the other. A failing status could lose
54
+ * to a passing check-run, or an untimestamped check-run (queued, or failed
55
+ * with a null start) could lose to a passing status listed after it — either
56
+ * way red or pending reads green. `scripts/pr-checks.sh` reads check-runs and commit statuses and applies
57
+ * both clauses. Keep the two in step (`tests/fences-cigate.test.ts`).
58
+ */
59
+ export function latestRunPerName(checks) {
60
+ const kept = [];
61
+ const timedRuns = new Map();
62
+ const untimedRuns = new Map();
63
+ checks.forEach((check, idx) => {
64
+ if (check.source !== "check_run") {
65
+ kept.push({ check, idx }); // a status is never collapsed, in either direction
66
+ return;
67
+ }
68
+ const at = check.started_at || null; // "" carries no time either
69
+ if (at === null) {
70
+ untimedRuns.set(check.name, { check, idx });
71
+ return;
72
+ }
73
+ const prev = timedRuns.get(check.name);
74
+ if (!prev || at >= prev.at)
75
+ timedRuns.set(check.name, { check, idx, at });
76
+ });
77
+ return [...kept, ...timedRuns.values(), ...untimedRuns.values()]
78
+ .sort((x, y) => x.idx - y.idx)
79
+ .map((e) => e.check);
80
+ }
81
+ /**
82
+ * Classify the checks at one head. Pure — both the gate guard and the shell
83
+ * mirror answer from this table, so "green" means the same thing on every
84
+ * posting route.
85
+ *
86
+ * A suite whose every check is skipped or neutral is not green: it reports
87
+ * `red`, because there is no evidence this PR's code passed anything.
88
+ */
89
+ export function classifyCi(allChecks) {
90
+ const checks = latestRunPerName(allChecks);
91
+ if (checks.length === 0)
92
+ return "none";
93
+ let pending = false;
94
+ let succeeded = false;
95
+ for (const c of checks) {
96
+ const outcome = checkOutcome(c);
97
+ if (outcome === "failed")
98
+ return "red";
99
+ if (outcome === "pending")
100
+ pending = true;
101
+ if (outcome === "success")
102
+ succeeded = true;
103
+ }
104
+ if (pending)
105
+ return "pending";
106
+ return succeeded ? "green" : "red";
107
+ }
108
+ /**
109
+ * One check's outcome — the per-check half of `classifyCi`, and the one
110
+ * reading of a check anything else (the escalation's failing-check rule)
111
+ * may use. `failed` is every finished conclusion that is neither a success
112
+ * nor inert: failure, cancelled, timed_out, action_required, stale, …
113
+ */
114
+ export function checkOutcome(c) {
115
+ const status = (c.status ?? "").toLowerCase();
116
+ const conclusion = (c.conclusion ?? "").toLowerCase();
117
+ if (UNFINISHED.has(status) || (status !== "completed" && conclusion === ""))
118
+ return "pending";
119
+ if (conclusion === "success")
120
+ return "success";
121
+ if (INERT_CONCLUSIONS.has(conclusion))
122
+ return "inert";
123
+ return "failed";
124
+ }
125
+ /**
126
+ * Does this CI state make APPROVE unavailable?
127
+ *
128
+ * `none` blocks only when `noChecksIsRed` says so: in a repo that normally
129
+ * runs CI, a head with zero check-runs — a conflicted PR, or CI that has not
130
+ * started — carries no execution evidence, so approval waits for checks to
131
+ * appear and pass. The flag is off by default so a repo with no CI at all is
132
+ * never permanently wedged.
133
+ */
134
+ export function ciBlocksApproval(state, opts = {}) {
135
+ if (state === "none")
136
+ return opts.noChecksIsRed === true;
137
+ return state === "red" || state === "pending";
138
+ }
139
+ /** Plain-words reason, for the note and the logs. */
140
+ export function ciStateReason(state) {
141
+ switch (state) {
142
+ case "red":
143
+ return "CI is not green at this head";
144
+ case "pending":
145
+ return "CI has not finished at this head";
146
+ case "green":
147
+ return "CI is green at this head";
148
+ case "none":
149
+ return "no CI reported at this head";
150
+ }
151
+ }
152
+ /**
153
+ * The paragraph a withheld review carries. It says the two things the author
154
+ * needs — that the review is finished and found nothing blocking, and that the
155
+ * approval is waiting on CI and on nothing else — so the work is never
156
+ * invisible while CI is broken.
157
+ */
158
+ export function withheldApprovalNote(state, headSha) {
159
+ return (`_**No blockers were found in this review.** Approval is withheld because ` +
160
+ `${ciStateReason(state)} (\`${headSha.slice(0, 7)}\`) — nothing above asks you to change anything, ` +
161
+ "and the failures may well be infrastructure or the base branch rather than this PR. " +
162
+ "The approval is waiting on green CI alone, and is re-attempted automatically once CI is green at this head._");
163
+ }
164
+ /**
165
+ * APPROVE → COMMENT, findings untouched, with the withheld note appended.
166
+ * Never REQUEST_CHANGES: there is nothing for the author to change on the
167
+ * review's account, and the fault may be the base branch or infra.
168
+ */
169
+ export function withholdApproval(body, state, headSha) {
170
+ return {
171
+ ...body,
172
+ event: "COMMENT",
173
+ body: `${body.body ?? ""}\n\n${withheldApprovalNote(state, headSha)}`,
174
+ };
175
+ }
176
+ //# sourceMappingURL=cigate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cigate.js","sourceRoot":"","sources":["../../src/cigate.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Author-controlled text rendered as Markdown DATA. A leaf module (no imports)
3
+ * so any renderer can use it without pulling in the prompt templates — the
4
+ * round prompts (`templates.ts`) and the escalation note (`escalation.ts`)
5
+ * both render repository paths, and both must keep them literal.
6
+ */
7
+ /** The longest run of backticks in `text` (0 when none) — what a fence or a
8
+ * code span must out-length so nothing inside can close it (CommonMark). */
9
+ export declare function longestBacktickRun(text: string): number;
10
+ /** The backtick fence for a block of `text`: one longer than any backtick run
11
+ * inside it, and at least three, so nothing inside can close it. */
12
+ export declare function backtickFence(text: string): string;
13
+ /** Control characters (newlines included) as visible `\\uXXXX` escapes, so
14
+ * author-controlled text can never start a new line of prompt. */
15
+ export declare function flatControls(text: string): string;
16
+ /**
17
+ * A repository path as an inline code span that stays DATA. Git paths may hold
18
+ * backticks, pipes and newlines, and they are author-controlled: rendered raw
19
+ * they could close the span, split a plan-table row, or open a new line of
20
+ * daemon-authored prompt text. Control characters are shown as `\uXXXX`,
21
+ * and the fence is one backtick longer than any run inside the name
22
+ * (CommonMark), padded with a space when CommonMark would otherwise strip one
23
+ * of the name's own, so the name reads back exactly otherwise. Pipes are escaped
24
+ * only for a TABLE cell (`table`): GFM un-escapes `\|` there, even inside a
25
+ * code span, but everywhere else the backslash would read back as part of
26
+ * the path.
27
+ */
28
+ export declare function codePath(path: string, opts?: {
29
+ table?: boolean;
30
+ }): string;
31
+ /**
32
+ * Author-derived text quoted inside a daemon-authored `("…")` in prompt text.
33
+ * It must not be able to close that quotation or start a new line of
34
+ * instructions: control characters collapse to a space and a double quote
35
+ * becomes a single one. No length cap — the caller owns the length (the round
36
+ * memory query is clamped at its own 600-character budget, and quoting it
37
+ * must not silently cut what the daemon actually asked).
38
+ */
39
+ export declare function promptQuoted(text: string): string;
40
+ /**
41
+ * A PR title quoted inside daemon-authored prompt text (`("{{title}}")` in the
42
+ * conversation system prompt and the round templates): `promptQuoted`, capped
43
+ * at 256 characters as GitHub caps titles.
44
+ */
45
+ export declare function promptTitle(title: string): string;
46
+ //# sourceMappingURL=codespan.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codespan.d.ts","sourceRoot":"","sources":["../../src/codespan.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;4EAC4E;AAC5E,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAIvD;AAED;oEACoE;AACpE,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAElD;AAQD;kEACkE;AAClE,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEjD;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,GAAE;IAAE,KAAK,CAAC,EAAE,OAAO,CAAA;CAAO,GAAG,MAAM,CAU7E;AAED;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEjD;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAEjD"}