tinybeeai 0.0.0-stage → 0.16.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (1034) hide show
  1. package/.railway/railway.ts +83 -0
  2. package/.railway/tsconfig.json +13 -0
  3. package/AGENTS.md +102 -0
  4. package/Dockerfile +108 -0
  5. package/LICENSE +21 -0
  6. package/README.md +275 -2
  7. package/bin/localdost.js +29 -0
  8. package/bin/tinybeeai.js +28 -0
  9. package/compose.yml +63 -0
  10. package/demo/payloads/ci_failure.json +46 -0
  11. package/demo/payloads/outage.json +18 -0
  12. package/demo/payloads/pr_comment_edited.json +50 -0
  13. package/demo/payloads/pr_merged.json +80 -0
  14. package/demo/payloads/pr_opened.json +69 -0
  15. package/demo/payloads/pr_synchronize.json +69 -0
  16. package/demo/payloads/ticket_created.json +138 -0
  17. package/demo/sample-app/playwright.config.ts +20 -0
  18. package/demo/sample-app/server.ts +163 -0
  19. package/demo/sample-app/tests/checkout.spec.ts +13 -0
  20. package/demo/sample-app/tests/smoke.spec.ts +8 -0
  21. package/dist/agent/approval-retries.js +59 -0
  22. package/dist/agent/approval-retries.js.map +1 -0
  23. package/dist/agent/approvals.js +390 -0
  24. package/dist/agent/approvals.js.map +1 -0
  25. package/dist/agent/chat-bridge.js +154 -0
  26. package/dist/agent/chat-bridge.js.map +1 -0
  27. package/dist/agent/chat-lead.js +475 -0
  28. package/dist/agent/chat-lead.js.map +1 -0
  29. package/dist/agent/chat-loop.js +106 -0
  30. package/dist/agent/chat-loop.js.map +1 -0
  31. package/dist/agent/chat-mcp.js +49 -0
  32. package/dist/agent/chat-mcp.js.map +1 -0
  33. package/dist/agent/chat-tool-blocks.js +453 -0
  34. package/dist/agent/chat-tool-blocks.js.map +1 -0
  35. package/dist/agent/chat-view.js +94 -0
  36. package/dist/agent/chat-view.js.map +1 -0
  37. package/dist/agent/chat-views.js +781 -0
  38. package/dist/agent/chat-views.js.map +1 -0
  39. package/dist/agent/chat.js +1703 -0
  40. package/dist/agent/chat.js.map +1 -0
  41. package/dist/agent/destinations.js +150 -0
  42. package/dist/agent/destinations.js.map +1 -0
  43. package/dist/agent/llm-cli.js +451 -0
  44. package/dist/agent/llm-cli.js.map +1 -0
  45. package/dist/agent/llm-codex.js +493 -0
  46. package/dist/agent/llm-codex.js.map +1 -0
  47. package/dist/agent/llm-openai.js +211 -0
  48. package/dist/agent/llm-openai.js.map +1 -0
  49. package/dist/agent/llm.js +1464 -0
  50. package/dist/agent/llm.js.map +1 -0
  51. package/dist/agent/memory.js +33 -0
  52. package/dist/agent/memory.js.map +1 -0
  53. package/dist/agent/mock-views.js +93 -0
  54. package/dist/agent/mock-views.js.map +1 -0
  55. package/dist/agent/model-availability.js +207 -0
  56. package/dist/agent/model-availability.js.map +1 -0
  57. package/dist/agent/model-errors.js +188 -0
  58. package/dist/agent/model-errors.js.map +1 -0
  59. package/dist/agent/model-guard.js +311 -0
  60. package/dist/agent/model-guard.js.map +1 -0
  61. package/dist/agent/prompts.js +374 -0
  62. package/dist/agent/prompts.js.map +1 -0
  63. package/dist/agent/qa-lenses/qa-auth.md +32 -0
  64. package/dist/agent/qa-lenses/qa-check-then-act.md +33 -0
  65. package/dist/agent/qa-lenses/qa-control-has-no-effect.md +32 -0
  66. package/dist/agent/qa-lenses/qa-dates.md +31 -0
  67. package/dist/agent/qa-lenses/qa-double-submit.md +34 -0
  68. package/dist/agent/qa-lenses/qa-feature-flag.md +29 -0
  69. package/dist/agent/qa-lenses/qa-migration.md +35 -0
  70. package/dist/agent/qa-lenses/qa-money.md +38 -0
  71. package/dist/agent/qa-lenses/qa-response-shape-break.md +33 -0
  72. package/dist/agent/qa-lenses/qa-validation.md +29 -0
  73. package/dist/agent/qa-prompts.js +660 -0
  74. package/dist/agent/qa-prompts.js.map +1 -0
  75. package/dist/agent/reasoning.js +55 -0
  76. package/dist/agent/reasoning.js.map +1 -0
  77. package/dist/agent/redact.js +48 -0
  78. package/dist/agent/redact.js.map +1 -0
  79. package/dist/agent/rules.js +927 -0
  80. package/dist/agent/rules.js.map +1 -0
  81. package/dist/agent/runs.js +440 -0
  82. package/dist/agent/runs.js.map +1 -0
  83. package/dist/agent/send-retry.js +62 -0
  84. package/dist/agent/send-retry.js.map +1 -0
  85. package/dist/agent/team-notes.js +288 -0
  86. package/dist/agent/team-notes.js.map +1 -0
  87. package/dist/agent/token-meter.js +31 -0
  88. package/dist/agent/token-meter.js.map +1 -0
  89. package/dist/agent/triage.js +506 -0
  90. package/dist/agent/triage.js.map +1 -0
  91. package/dist/api.js +1047 -0
  92. package/dist/api.js.map +1 -0
  93. package/dist/approval-targets.js +107 -0
  94. package/dist/approval-targets.js.map +1 -0
  95. package/dist/bee/cloudflared.js +108 -0
  96. package/dist/bee/cloudflared.js.map +1 -0
  97. package/dist/bee/health.js +99 -0
  98. package/dist/bee/health.js.map +1 -0
  99. package/dist/bee/hive-client.js +75 -0
  100. package/dist/bee/hive-client.js.map +1 -0
  101. package/dist/bee/identity.js +39 -0
  102. package/dist/bee/identity.js.map +1 -0
  103. package/dist/bee/models.js +510 -0
  104. package/dist/bee/models.js.map +1 -0
  105. package/dist/bee/pairing.js +351 -0
  106. package/dist/bee/pairing.js.map +1 -0
  107. package/dist/bee/relay-client.js +50 -0
  108. package/dist/bee/relay-client.js.map +1 -0
  109. package/dist/bee/routes.js +214 -0
  110. package/dist/bee/routes.js.map +1 -0
  111. package/dist/bee/setup-page.js +223 -0
  112. package/dist/bee/setup-page.js.map +1 -0
  113. package/dist/bee/state.js +41 -0
  114. package/dist/bee/state.js.map +1 -0
  115. package/dist/bee/status.js +117 -0
  116. package/dist/bee/status.js.map +1 -0
  117. package/dist/bee/tunnel-manager.js +245 -0
  118. package/dist/bee/tunnel-manager.js.map +1 -0
  119. package/dist/bee/updater.js +268 -0
  120. package/dist/bee/updater.js.map +1 -0
  121. package/dist/boot.js +41 -0
  122. package/dist/boot.js.map +1 -0
  123. package/dist/call/index.js +145 -0
  124. package/dist/call/index.js.map +1 -0
  125. package/dist/case-folders.js +294 -0
  126. package/dist/case-folders.js.map +1 -0
  127. package/dist/cases.js +554 -0
  128. package/dist/cases.js.map +1 -0
  129. package/dist/chat-blocks.js +709 -0
  130. package/dist/chat-blocks.js.map +1 -0
  131. package/dist/chat-parse-util.js +38 -0
  132. package/dist/chat-parse-util.js.map +1 -0
  133. package/dist/chat-results.js +96 -0
  134. package/dist/chat-results.js.map +1 -0
  135. package/dist/chat-stats.js +193 -0
  136. package/dist/chat-stats.js.map +1 -0
  137. package/dist/chat-view-specs.js +186 -0
  138. package/dist/chat-view-specs.js.map +1 -0
  139. package/dist/cli/doctor-ops.js +361 -0
  140. package/dist/cli/doctor-ops.js.map +1 -0
  141. package/dist/cli/doctor.js +289 -0
  142. package/dist/cli/doctor.js.map +1 -0
  143. package/dist/cli/dogfood.js +70 -0
  144. package/dist/cli/dogfood.js.map +1 -0
  145. package/dist/cli/env-file.js +34 -0
  146. package/dist/cli/env-file.js.map +1 -0
  147. package/dist/cli/eval-chat-cases.js +359 -0
  148. package/dist/cli/eval-chat-cases.js.map +1 -0
  149. package/dist/cli/eval-chat-results.js +85 -0
  150. package/dist/cli/eval-chat-results.js.map +1 -0
  151. package/dist/cli/eval-chat.js +508 -0
  152. package/dist/cli/eval-chat.js.map +1 -0
  153. package/dist/cli/eval-designer.js +67 -0
  154. package/dist/cli/eval-designer.js.map +1 -0
  155. package/dist/cli/eval-qa-review.js +284 -0
  156. package/dist/cli/eval-qa-review.js.map +1 -0
  157. package/dist/cli/golden-export.js +35 -0
  158. package/dist/cli/golden-export.js.map +1 -0
  159. package/dist/cli/index.js +90 -0
  160. package/dist/cli/index.js.map +1 -0
  161. package/dist/cli/init.js +746 -0
  162. package/dist/cli/init.js.map +1 -0
  163. package/dist/cli/scan-repo.js +199 -0
  164. package/dist/cli/scan-repo.js.map +1 -0
  165. package/dist/cli/seed.js +108 -0
  166. package/dist/cli/seed.js.map +1 -0
  167. package/dist/cli/tinybee.js +247 -0
  168. package/dist/cli/tinybee.js.map +1 -0
  169. package/dist/config.js +138 -0
  170. package/dist/config.js.map +1 -0
  171. package/dist/connect/aivision-local.js +833 -0
  172. package/dist/connect/aivision-local.js.map +1 -0
  173. package/dist/connect/aivision-token.js +84 -0
  174. package/dist/connect/aivision-token.js.map +1 -0
  175. package/dist/connect/crypto.js +65 -0
  176. package/dist/connect/crypto.js.map +1 -0
  177. package/dist/connect/deps.js +110 -0
  178. package/dist/connect/deps.js.map +1 -0
  179. package/dist/connect/engines.js +144 -0
  180. package/dist/connect/engines.js.map +1 -0
  181. package/dist/connect/github-access.js +74 -0
  182. package/dist/connect/github-access.js.map +1 -0
  183. package/dist/connect/github-app.js +129 -0
  184. package/dist/connect/github-app.js.map +1 -0
  185. package/dist/connect/index.js +9 -0
  186. package/dist/connect/index.js.map +1 -0
  187. package/dist/connect/model-choices.js +201 -0
  188. package/dist/connect/model-choices.js.map +1 -0
  189. package/dist/connect/providers.js +900 -0
  190. package/dist/connect/providers.js.map +1 -0
  191. package/dist/connect/readiness.js +232 -0
  192. package/dist/connect/readiness.js.map +1 -0
  193. package/dist/connect/redact.js +16 -0
  194. package/dist/connect/redact.js.map +1 -0
  195. package/dist/connect/registry.js +406 -0
  196. package/dist/connect/registry.js.map +1 -0
  197. package/dist/connect/store.js +283 -0
  198. package/dist/connect/store.js.map +1 -0
  199. package/dist/connect/tunnel.js +134 -0
  200. package/dist/connect/tunnel.js.map +1 -0
  201. package/dist/connect/types.js +8 -0
  202. package/dist/connect/types.js.map +1 -0
  203. package/dist/connections/index.js +5 -0
  204. package/dist/connections/index.js.map +1 -0
  205. package/dist/connections/manager.js +223 -0
  206. package/dist/connections/manager.js.map +1 -0
  207. package/dist/connections/presets.js +264 -0
  208. package/dist/connections/presets.js.map +1 -0
  209. package/dist/connections/store.js +132 -0
  210. package/dist/connections/store.js.map +1 -0
  211. package/dist/connections/tools.js +206 -0
  212. package/dist/connections/tools.js.map +1 -0
  213. package/dist/db-schema.js +355 -0
  214. package/dist/db-schema.js.map +1 -0
  215. package/dist/db.js +379 -0
  216. package/dist/db.js.map +1 -0
  217. package/dist/delivery.js +49 -0
  218. package/dist/delivery.js.map +1 -0
  219. package/dist/deploy-wait.js +701 -0
  220. package/dist/deploy-wait.js.map +1 -0
  221. package/dist/disk.js +243 -0
  222. package/dist/disk.js.map +1 -0
  223. package/dist/dot-health.js +966 -0
  224. package/dist/dot-health.js.map +1 -0
  225. package/dist/dot-remove.js +246 -0
  226. package/dist/dot-remove.js.map +1 -0
  227. package/dist/events.js +38 -0
  228. package/dist/events.js.map +1 -0
  229. package/dist/evidence-pack.js +423 -0
  230. package/dist/evidence-pack.js.map +1 -0
  231. package/dist/flows/answers.js +289 -0
  232. package/dist/flows/answers.js.map +1 -0
  233. package/dist/flows/change.js +811 -0
  234. package/dist/flows/change.js.map +1 -0
  235. package/dist/flows/checkStatus.js +524 -0
  236. package/dist/flows/checkStatus.js.map +1 -0
  237. package/dist/flows/ci.js +236 -0
  238. package/dist/flows/ci.js.map +1 -0
  239. package/dist/flows/ciFailure.js +76 -0
  240. package/dist/flows/ciFailure.js.map +1 -0
  241. package/dist/flows/common.js +522 -0
  242. package/dist/flows/common.js.map +1 -0
  243. package/dist/flows/default-branch.js +29 -0
  244. package/dist/flows/default-branch.js.map +1 -0
  245. package/dist/flows/defectDraft.js +447 -0
  246. package/dist/flows/defectDraft.js.map +1 -0
  247. package/dist/flows/defects.js +623 -0
  248. package/dist/flows/defects.js.map +1 -0
  249. package/dist/flows/digest.js +295 -0
  250. package/dist/flows/digest.js.map +1 -0
  251. package/dist/flows/impact.js +82 -0
  252. package/dist/flows/impact.js.map +1 -0
  253. package/dist/flows/index.js +23 -0
  254. package/dist/flows/index.js.map +1 -0
  255. package/dist/flows/intent-sources.js +72 -0
  256. package/dist/flows/intent-sources.js.map +1 -0
  257. package/dist/flows/mergeCases.js +169 -0
  258. package/dist/flows/mergeCases.js.map +1 -0
  259. package/dist/flows/nightlyRun.js +82 -0
  260. package/dist/flows/nightlyRun.js.map +1 -0
  261. package/dist/flows/outage.js +64 -0
  262. package/dist/flows/outage.js.map +1 -0
  263. package/dist/flows/postMerge.js +5 -0
  264. package/dist/flows/postMerge.js.map +1 -0
  265. package/dist/flows/prCheck.js +5 -0
  266. package/dist/flows/prCheck.js.map +1 -0
  267. package/dist/flows/prTarget.js +66 -0
  268. package/dist/flows/prTarget.js.map +1 -0
  269. package/dist/flows/qa.js +363 -0
  270. package/dist/flows/qa.js.map +1 -0
  271. package/dist/flows/questions.js +160 -0
  272. package/dist/flows/questions.js.map +1 -0
  273. package/dist/flows/recovery.js +64 -0
  274. package/dist/flows/recovery.js.map +1 -0
  275. package/dist/flows/rerun.js +50 -0
  276. package/dist/flows/rerun.js.map +1 -0
  277. package/dist/flows/testDesign.js +294 -0
  278. package/dist/flows/testDesign.js.map +1 -0
  279. package/dist/flows/testDesignJob.js +46 -0
  280. package/dist/flows/testDesignJob.js.map +1 -0
  281. package/dist/flows/testRepo.js +228 -0
  282. package/dist/flows/testRepo.js.map +1 -0
  283. package/dist/flows/testSavings.js +381 -0
  284. package/dist/flows/testSavings.js.map +1 -0
  285. package/dist/flows/testStatus.js +343 -0
  286. package/dist/flows/testStatus.js.map +1 -0
  287. package/dist/flows/ticketContext.js +425 -0
  288. package/dist/flows/ticketContext.js.map +1 -0
  289. package/dist/flows/ticketReview.js +249 -0
  290. package/dist/flows/ticketReview.js.map +1 -0
  291. package/dist/flows/ticks.js +73 -0
  292. package/dist/flows/ticks.js.map +1 -0
  293. package/dist/hive/admin.js +122 -0
  294. package/dist/hive/admin.js.map +1 -0
  295. package/dist/hive/auth.js +130 -0
  296. package/dist/hive/auth.js.map +1 -0
  297. package/dist/hive/billing.js +278 -0
  298. package/dist/hive/billing.js.map +1 -0
  299. package/dist/hive/config.js +63 -0
  300. package/dist/hive/config.js.map +1 -0
  301. package/dist/hive/db.js +186 -0
  302. package/dist/hive/db.js.map +1 -0
  303. package/dist/hive/embed.js +76 -0
  304. package/dist/hive/embed.js.map +1 -0
  305. package/dist/hive/errors.js +17 -0
  306. package/dist/hive/errors.js.map +1 -0
  307. package/dist/hive/google.js +75 -0
  308. package/dist/hive/google.js.map +1 -0
  309. package/dist/hive/index.js +25 -0
  310. package/dist/hive/index.js.map +1 -0
  311. package/dist/hive/jwt.js +57 -0
  312. package/dist/hive/jwt.js.map +1 -0
  313. package/dist/hive/keys.js +61 -0
  314. package/dist/hive/keys.js.map +1 -0
  315. package/dist/hive/mail.js +27 -0
  316. package/dist/hive/mail.js.map +1 -0
  317. package/dist/hive/native-push.js +255 -0
  318. package/dist/hive/native-push.js.map +1 -0
  319. package/dist/hive/pairing.js +342 -0
  320. package/dist/hive/pairing.js.map +1 -0
  321. package/dist/hive/presence.js +121 -0
  322. package/dist/hive/presence.js.map +1 -0
  323. package/dist/hive/push.js +185 -0
  324. package/dist/hive/push.js.map +1 -0
  325. package/dist/hive/relay.js +205 -0
  326. package/dist/hive/relay.js.map +1 -0
  327. package/dist/hive/routes.js +228 -0
  328. package/dist/hive/routes.js.map +1 -0
  329. package/dist/hive/server.js +12 -0
  330. package/dist/hive/server.js.map +1 -0
  331. package/dist/hive/session.js +28 -0
  332. package/dist/hive/session.js.map +1 -0
  333. package/dist/hive/tenants.js +287 -0
  334. package/dist/hive/tenants.js.map +1 -0
  335. package/dist/hive/tunnel/cloudflare.js +160 -0
  336. package/dist/hive/tunnel/cloudflare.js.map +1 -0
  337. package/dist/hive/tunnel/mock.js +52 -0
  338. package/dist/hive/tunnel/mock.js.map +1 -0
  339. package/dist/hive/tunnel/provider.js +19 -0
  340. package/dist/hive/tunnel/provider.js.map +1 -0
  341. package/dist/hive/updates.js +61 -0
  342. package/dist/hive/updates.js.map +1 -0
  343. package/dist/http-error.js +11 -0
  344. package/dist/http-error.js.map +1 -0
  345. package/dist/impact/classify.js +226 -0
  346. package/dist/impact/classify.js.map +1 -0
  347. package/dist/impact/find.js +259 -0
  348. package/dist/impact/find.js.map +1 -0
  349. package/dist/impact/pr.js +54 -0
  350. package/dist/impact/pr.js.map +1 -0
  351. package/dist/impact/store.js +365 -0
  352. package/dist/impact/store.js.map +1 -0
  353. package/dist/impact/text.js +158 -0
  354. package/dist/impact/text.js.map +1 -0
  355. package/dist/index.js +288 -0
  356. package/dist/index.js.map +1 -0
  357. package/dist/integrations/adf.js +397 -0
  358. package/dist/integrations/adf.js.map +1 -0
  359. package/dist/integrations/bot-marker.js +103 -0
  360. package/dist/integrations/bot-marker.js.map +1 -0
  361. package/dist/integrations/github-issues.js +705 -0
  362. package/dist/integrations/github-issues.js.map +1 -0
  363. package/dist/integrations/github.js +1284 -0
  364. package/dist/integrations/github.js.map +1 -0
  365. package/dist/integrations/issue-create.js +60 -0
  366. package/dist/integrations/issue-create.js.map +1 -0
  367. package/dist/integrations/jira.js +279 -0
  368. package/dist/integrations/jira.js.map +1 -0
  369. package/dist/integrations/linear.js +273 -0
  370. package/dist/integrations/linear.js.map +1 -0
  371. package/dist/integrations/own-identity-warm.js +47 -0
  372. package/dist/integrations/own-identity-warm.js.map +1 -0
  373. package/dist/integrations/own-identity.js +39 -0
  374. package/dist/integrations/own-identity.js.map +1 -0
  375. package/dist/integrations/status-change.js +42 -0
  376. package/dist/integrations/status-change.js.map +1 -0
  377. package/dist/lead-defects.js +202 -0
  378. package/dist/lead-defects.js.map +1 -0
  379. package/dist/lead-digest.js +333 -0
  380. package/dist/lead-digest.js.map +1 -0
  381. package/dist/lead-release.js +286 -0
  382. package/dist/lead-release.js.map +1 -0
  383. package/dist/lead.js +328 -0
  384. package/dist/lead.js.map +1 -0
  385. package/dist/legacy-names.js +51 -0
  386. package/dist/legacy-names.js.map +1 -0
  387. package/dist/limits.js +44 -0
  388. package/dist/limits.js.map +1 -0
  389. package/dist/link-trust.js +224 -0
  390. package/dist/link-trust.js.map +1 -0
  391. package/dist/links.js +219 -0
  392. package/dist/links.js.map +1 -0
  393. package/dist/loopback.js +35 -0
  394. package/dist/loopback.js.map +1 -0
  395. package/dist/model-cap.js +60 -0
  396. package/dist/model-cap.js.map +1 -0
  397. package/dist/model-usage.js +173 -0
  398. package/dist/model-usage.js.map +1 -0
  399. package/dist/monitor/backfill.js +39 -0
  400. package/dist/monitor/backfill.js.map +1 -0
  401. package/dist/monitor/browser-probe.js +198 -0
  402. package/dist/monitor/browser-probe.js.map +1 -0
  403. package/dist/monitor/catch-up.js +31 -0
  404. package/dist/monitor/catch-up.js.map +1 -0
  405. package/dist/monitor/pollers.js +1606 -0
  406. package/dist/monitor/pollers.js.map +1 -0
  407. package/dist/monitor/probes.js +178 -0
  408. package/dist/monitor/probes.js.map +1 -0
  409. package/dist/monitor/self-health.js +228 -0
  410. package/dist/monitor/self-health.js.map +1 -0
  411. package/dist/monitor/statuspage.js +105 -0
  412. package/dist/monitor/statuspage.js.map +1 -0
  413. package/dist/nightly-scheduler.js +127 -0
  414. package/dist/nightly-scheduler.js.map +1 -0
  415. package/dist/nightly.js +141 -0
  416. package/dist/nightly.js.map +1 -0
  417. package/dist/notify/headline.js +114 -0
  418. package/dist/notify/headline.js.map +1 -0
  419. package/dist/notify/push.js +174 -0
  420. package/dist/notify/push.js.map +1 -0
  421. package/dist/object-cards.js +585 -0
  422. package/dist/object-cards.js.map +1 -0
  423. package/dist/object-links.js +47 -0
  424. package/dist/object-links.js.map +1 -0
  425. package/dist/onboarding-checks.js +141 -0
  426. package/dist/onboarding-checks.js.map +1 -0
  427. package/dist/onboarding.js +401 -0
  428. package/dist/onboarding.js.map +1 -0
  429. package/dist/path-filters.js +62 -0
  430. package/dist/path-filters.js.map +1 -0
  431. package/dist/phone/alerts.js +67 -0
  432. package/dist/phone/alerts.js.map +1 -0
  433. package/dist/phone/auth.js +240 -0
  434. package/dist/phone/auth.js.map +1 -0
  435. package/dist/phone/pairing.js +442 -0
  436. package/dist/phone/pairing.js.map +1 -0
  437. package/dist/phone/prefs.js +27 -0
  438. package/dist/phone/prefs.js.map +1 -0
  439. package/dist/phone/tailscale.js +161 -0
  440. package/dist/phone/tailscale.js.map +1 -0
  441. package/dist/pr-scope.js +441 -0
  442. package/dist/pr-scope.js.map +1 -0
  443. package/dist/proc.js +156 -0
  444. package/dist/proc.js.map +1 -0
  445. package/dist/profile/cache.js +108 -0
  446. package/dist/profile/cache.js.map +1 -0
  447. package/dist/profile/ci.js +216 -0
  448. package/dist/profile/ci.js.map +1 -0
  449. package/dist/profile/index.js +8 -0
  450. package/dist/profile/index.js.map +1 -0
  451. package/dist/profile/job.js +135 -0
  452. package/dist/profile/job.js.map +1 -0
  453. package/dist/profile/queries/go-tags.scm +47 -0
  454. package/dist/profile/queries/java-tags.scm +25 -0
  455. package/dist/profile/queries/javascript-tags.scm +104 -0
  456. package/dist/profile/queries/python-tags.scm +19 -0
  457. package/dist/profile/queries/typescript-tags.scm +28 -0
  458. package/dist/profile/scan-thread.js +42 -0
  459. package/dist/profile/scan-thread.js.map +1 -0
  460. package/dist/profile/scan-worker.js +16 -0
  461. package/dist/profile/scan-worker.js.map +1 -0
  462. package/dist/profile/scan.js +351 -0
  463. package/dist/profile/scan.js.map +1 -0
  464. package/dist/profile/stack.js +528 -0
  465. package/dist/profile/stack.js.map +1 -0
  466. package/dist/profile/store.js +35 -0
  467. package/dist/profile/store.js.map +1 -0
  468. package/dist/profile/tests.js +399 -0
  469. package/dist/profile/tests.js.map +1 -0
  470. package/dist/queue.js +350 -0
  471. package/dist/queue.js.map +1 -0
  472. package/dist/refs.js +756 -0
  473. package/dist/refs.js.map +1 -0
  474. package/dist/release-notes.js +272 -0
  475. package/dist/release-notes.js.map +1 -0
  476. package/dist/reports/build.js +243 -0
  477. package/dist/reports/build.js.map +1 -0
  478. package/dist/reports/index.js +211 -0
  479. package/dist/reports/index.js.map +1 -0
  480. package/dist/reports/store.js +150 -0
  481. package/dist/reports/store.js.map +1 -0
  482. package/dist/reports/ticket-titles.js +124 -0
  483. package/dist/reports/ticket-titles.js.map +1 -0
  484. package/dist/reports/trace-map.js +1278 -0
  485. package/dist/reports/trace-map.js.map +1 -0
  486. package/dist/reports/traceability.js +422 -0
  487. package/dist/reports/traceability.js.map +1 -0
  488. package/dist/repos/mirror.js +356 -0
  489. package/dist/repos/mirror.js.map +1 -0
  490. package/dist/repos-github.js +108 -0
  491. package/dist/repos-github.js.map +1 -0
  492. package/dist/repos.js +891 -0
  493. package/dist/repos.js.map +1 -0
  494. package/dist/review/backend-anthropic.js +90 -0
  495. package/dist/review/backend-anthropic.js.map +1 -0
  496. package/dist/review/backend-cli.js +248 -0
  497. package/dist/review/backend-cli.js.map +1 -0
  498. package/dist/review/backend-codex.js +81 -0
  499. package/dist/review/backend-codex.js.map +1 -0
  500. package/dist/review/backend-mock.js +686 -0
  501. package/dist/review/backend-mock.js.map +1 -0
  502. package/dist/review/backend-only.js +168 -0
  503. package/dist/review/backend-only.js.map +1 -0
  504. package/dist/review/backend.js +105 -0
  505. package/dist/review/backend.js.map +1 -0
  506. package/dist/review/baseline/render-v1.js +483 -0
  507. package/dist/review/baseline/render-v1.js.map +1 -0
  508. package/dist/review/change-summary.js +197 -0
  509. package/dist/review/change-summary.js.map +1 -0
  510. package/dist/review/changelog.js +40 -0
  511. package/dist/review/changelog.js.map +1 -0
  512. package/dist/review/check.js +494 -0
  513. package/dist/review/check.js.map +1 -0
  514. package/dist/review/checkout.js +185 -0
  515. package/dist/review/checkout.js.map +1 -0
  516. package/dist/review/classify.js +178 -0
  517. package/dist/review/classify.js.map +1 -0
  518. package/dist/review/coverage.js +347 -0
  519. package/dist/review/coverage.js.map +1 -0
  520. package/dist/review/decision-eval.js +121 -0
  521. package/dist/review/decision-eval.js.map +1 -0
  522. package/dist/review/deliver.js +104 -0
  523. package/dist/review/deliver.js.map +1 -0
  524. package/dist/review/designer-eval.js +280 -0
  525. package/dist/review/designer-eval.js.map +1 -0
  526. package/dist/review/dogfood-digest.js +136 -0
  527. package/dist/review/dogfood-digest.js.map +1 -0
  528. package/dist/review/dogfood-eval.js +486 -0
  529. package/dist/review/dogfood-eval.js.map +1 -0
  530. package/dist/review/environment.js +109 -0
  531. package/dist/review/environment.js.map +1 -0
  532. package/dist/review/eval.js +405 -0
  533. package/dist/review/eval.js.map +1 -0
  534. package/dist/review/glob.js +110 -0
  535. package/dist/review/glob.js.map +1 -0
  536. package/dist/review/golden-export.js +219 -0
  537. package/dist/review/golden-export.js.map +1 -0
  538. package/dist/review/impact.js +406 -0
  539. package/dist/review/impact.js.map +1 -0
  540. package/dist/review/imports.js +542 -0
  541. package/dist/review/imports.js.map +1 -0
  542. package/dist/review/index.js +512 -0
  543. package/dist/review/index.js.map +1 -0
  544. package/dist/review/intent.js +128 -0
  545. package/dist/review/intent.js.map +1 -0
  546. package/dist/review/lenses.js +167 -0
  547. package/dist/review/lenses.js.map +1 -0
  548. package/dist/review/linked-tickets.js +293 -0
  549. package/dist/review/linked-tickets.js.map +1 -0
  550. package/dist/review/merge.js +370 -0
  551. package/dist/review/merge.js.map +1 -0
  552. package/dist/review/on-demand.js +218 -0
  553. package/dist/review/on-demand.js.map +1 -0
  554. package/dist/review/prompt-eval.js +299 -0
  555. package/dist/review/prompt-eval.js.map +1 -0
  556. package/dist/review/prompt-variants.js +37 -0
  557. package/dist/review/prompt-variants.js.map +1 -0
  558. package/dist/review/readability-eval.js +217 -0
  559. package/dist/review/readability-eval.js.map +1 -0
  560. package/dist/review/readability.js +295 -0
  561. package/dist/review/readability.js.map +1 -0
  562. package/dist/review/render.js +2409 -0
  563. package/dist/review/render.js.map +1 -0
  564. package/dist/review/repo.js +194 -0
  565. package/dist/review/repo.js.map +1 -0
  566. package/dist/review/report-plan.js +90 -0
  567. package/dist/review/report-plan.js.map +1 -0
  568. package/dist/review/routes.js +195 -0
  569. package/dist/review/routes.js.map +1 -0
  570. package/dist/review/run-summary.js +34 -0
  571. package/dist/review/run-summary.js.map +1 -0
  572. package/dist/review/run.js +245 -0
  573. package/dist/review/run.js.map +1 -0
  574. package/dist/review/scope.js +454 -0
  575. package/dist/review/scope.js.map +1 -0
  576. package/dist/review/security.js +432 -0
  577. package/dist/review/security.js.map +1 -0
  578. package/dist/review/signals.js +550 -0
  579. package/dist/review/signals.js.map +1 -0
  580. package/dist/review/specs.js +150 -0
  581. package/dist/review/specs.js.map +1 -0
  582. package/dist/review/ste.js +133 -0
  583. package/dist/review/ste.js.map +1 -0
  584. package/dist/review/test-repo-file.js +18 -0
  585. package/dist/review/test-repo-file.js.map +1 -0
  586. package/dist/review/test-repo-lines.js +53 -0
  587. package/dist/review/test-repo-lines.js.map +1 -0
  588. package/dist/review/ticket-on-demand.js +232 -0
  589. package/dist/review/ticket-on-demand.js.map +1 -0
  590. package/dist/review/yaml.js +298 -0
  591. package/dist/review/yaml.js.map +1 -0
  592. package/dist/room.js +361 -0
  593. package/dist/room.js.map +1 -0
  594. package/dist/routes/activity.js +219 -0
  595. package/dist/routes/activity.js.map +1 -0
  596. package/dist/routes/call.js +29 -0
  597. package/dist/routes/call.js.map +1 -0
  598. package/dist/routes/cards.js +40 -0
  599. package/dist/routes/cards.js.map +1 -0
  600. package/dist/routes/cases.js +133 -0
  601. package/dist/routes/cases.js.map +1 -0
  602. package/dist/routes/connect.js +268 -0
  603. package/dist/routes/connect.js.map +1 -0
  604. package/dist/routes/connection-presets.js +32 -0
  605. package/dist/routes/connection-presets.js.map +1 -0
  606. package/dist/routes/connections.js +177 -0
  607. package/dist/routes/connections.js.map +1 -0
  608. package/dist/routes/disk.js +19 -0
  609. package/dist/routes/disk.js.map +1 -0
  610. package/dist/routes/docs.js +71 -0
  611. package/dist/routes/docs.js.map +1 -0
  612. package/dist/routes/dot-suggest.js +1002 -0
  613. package/dist/routes/dot-suggest.js.map +1 -0
  614. package/dist/routes/evidence-pack.js +16 -0
  615. package/dist/routes/evidence-pack.js.map +1 -0
  616. package/dist/routes/health.js +121 -0
  617. package/dist/routes/health.js.map +1 -0
  618. package/dist/routes/impact.js +48 -0
  619. package/dist/routes/impact.js.map +1 -0
  620. package/dist/routes/lead.js +50 -0
  621. package/dist/routes/lead.js.map +1 -0
  622. package/dist/routes/links.js +13 -0
  623. package/dist/routes/links.js.map +1 -0
  624. package/dist/routes/markdown.js +62 -0
  625. package/dist/routes/markdown.js.map +1 -0
  626. package/dist/routes/onboarding.js +47 -0
  627. package/dist/routes/onboarding.js.map +1 -0
  628. package/dist/routes/phone.js +231 -0
  629. package/dist/routes/phone.js.map +1 -0
  630. package/dist/routes/release-notes.js +30 -0
  631. package/dist/routes/release-notes.js.map +1 -0
  632. package/dist/routes/reports.js +102 -0
  633. package/dist/routes/reports.js.map +1 -0
  634. package/dist/routes/repos.js +91 -0
  635. package/dist/routes/repos.js.map +1 -0
  636. package/dist/routes/review.js +283 -0
  637. package/dist/routes/review.js.map +1 -0
  638. package/dist/routes/roles.js +114 -0
  639. package/dist/routes/roles.js.map +1 -0
  640. package/dist/routes/room.js +21 -0
  641. package/dist/routes/room.js.map +1 -0
  642. package/dist/routes/runner.js +156 -0
  643. package/dist/routes/runner.js.map +1 -0
  644. package/dist/routes/runs.js +84 -0
  645. package/dist/routes/runs.js.map +1 -0
  646. package/dist/routes/setup.js +18 -0
  647. package/dist/routes/setup.js.map +1 -0
  648. package/dist/routes/test-runs.js +220 -0
  649. package/dist/routes/test-runs.js.map +1 -0
  650. package/dist/routes/ticket-status.js +17 -0
  651. package/dist/routes/ticket-status.js.map +1 -0
  652. package/dist/routes/traceability.js +143 -0
  653. package/dist/routes/traceability.js.map +1 -0
  654. package/dist/routes/true.js +142 -0
  655. package/dist/routes/true.js.map +1 -0
  656. package/dist/routes/updates.js +70 -0
  657. package/dist/routes/updates.js.map +1 -0
  658. package/dist/runner/adapters/index.js +12 -0
  659. package/dist/runner/adapters/index.js.map +1 -0
  660. package/dist/runner/adapters/playwright.js +68 -0
  661. package/dist/runner/adapters/playwright.js.map +1 -0
  662. package/dist/runner/aivision/cases.js +172 -0
  663. package/dist/runner/aivision/cases.js.map +1 -0
  664. package/dist/runner/aivision/cli.js +201 -0
  665. package/dist/runner/aivision/cli.js.map +1 -0
  666. package/dist/runner/aivision/index.js +281 -0
  667. package/dist/runner/aivision/index.js.map +1 -0
  668. package/dist/runner/aivision/server.js +394 -0
  669. package/dist/runner/aivision/server.js.map +1 -0
  670. package/dist/runner/aivision/shared.js +140 -0
  671. package/dist/runner/aivision/shared.js.map +1 -0
  672. package/dist/runner/artifact-cap.js +189 -0
  673. package/dist/runner/artifact-cap.js.map +1 -0
  674. package/dist/runner/artifacts.js +433 -0
  675. package/dist/runner/artifacts.js.map +1 -0
  676. package/dist/runner/command.js +564 -0
  677. package/dist/runner/command.js.map +1 -0
  678. package/dist/runner/copyfiles.js +221 -0
  679. package/dist/runner/copyfiles.js.map +1 -0
  680. package/dist/runner/engines.js +32 -0
  681. package/dist/runner/engines.js.map +1 -0
  682. package/dist/runner/evidence.js +114 -0
  683. package/dist/runner/evidence.js.map +1 -0
  684. package/dist/runner/host-env.js +160 -0
  685. package/dist/runner/host-env.js.map +1 -0
  686. package/dist/runner/index.js +1221 -0
  687. package/dist/runner/index.js.map +1 -0
  688. package/dist/runner/observe.js +603 -0
  689. package/dist/runner/observe.js.map +1 -0
  690. package/dist/runner/playwright-json.js +108 -0
  691. package/dist/runner/playwright-json.js.map +1 -0
  692. package/dist/runner/pwgen/exec.js +192 -0
  693. package/dist/runner/pwgen/exec.js.map +1 -0
  694. package/dist/runner/pwgen/explore.js +111 -0
  695. package/dist/runner/pwgen/explore.js.map +1 -0
  696. package/dist/runner/pwgen/index.js +423 -0
  697. package/dist/runner/pwgen/index.js.map +1 -0
  698. package/dist/runner/pwgen/propose.js +69 -0
  699. package/dist/runner/pwgen/propose.js.map +1 -0
  700. package/dist/runner/pwgen/source.js +632 -0
  701. package/dist/runner/pwgen/source.js.map +1 -0
  702. package/dist/runner/setup.js +222 -0
  703. package/dist/runner/setup.js.map +1 -0
  704. package/dist/runner/step-reporter.js +107 -0
  705. package/dist/runner/step-reporter.js.map +1 -0
  706. package/dist/runner/test-repo.js +326 -0
  707. package/dist/runner/test-repo.js.map +1 -0
  708. package/dist/runner/typed-value.js +46 -0
  709. package/dist/runner/typed-value.js.map +1 -0
  710. package/dist/runner/verify.js +133 -0
  711. package/dist/runner/verify.js.map +1 -0
  712. package/dist/runner/worktree.js +349 -0
  713. package/dist/runner/worktree.js.map +1 -0
  714. package/dist/sandbox.js +61 -0
  715. package/dist/sandbox.js.map +1 -0
  716. package/dist/server.js +262 -0
  717. package/dist/server.js.map +1 -0
  718. package/dist/shadow-week.js +126 -0
  719. package/dist/shadow-week.js.map +1 -0
  720. package/dist/shutdown.js +92 -0
  721. package/dist/shutdown.js.map +1 -0
  722. package/dist/slack/index.js +645 -0
  723. package/dist/slack/index.js.map +1 -0
  724. package/dist/stages/config.js +147 -0
  725. package/dist/stages/config.js.map +1 -0
  726. package/dist/stages/index.js +41 -0
  727. package/dist/stages/index.js.map +1 -0
  728. package/dist/suites.js +293 -0
  729. package/dist/suites.js.map +1 -0
  730. package/dist/target-url.js +116 -0
  731. package/dist/target-url.js.map +1 -0
  732. package/dist/test-runs.js +662 -0
  733. package/dist/test-runs.js.map +1 -0
  734. package/dist/ticket-keys.js +97 -0
  735. package/dist/ticket-keys.js.map +1 -0
  736. package/dist/ticket-supersede.js +105 -0
  737. package/dist/ticket-supersede.js.map +1 -0
  738. package/dist/tinybee/ed25519.js +99 -0
  739. package/dist/tinybee/ed25519.js.map +1 -0
  740. package/dist/tinybee/models-routes.js +19 -0
  741. package/dist/tinybee/models-routes.js.map +1 -0
  742. package/dist/tinybee/pair-payload.js +41 -0
  743. package/dist/tinybee/pair-payload.js.map +1 -0
  744. package/dist/tinybee/update-manifest.js +77 -0
  745. package/dist/tinybee/update-manifest.js.map +1 -0
  746. package/dist/tinybee/well-known.js +64 -0
  747. package/dist/tinybee/well-known.js.map +1 -0
  748. package/dist/tinybee/workflows/activity.js +23 -0
  749. package/dist/tinybee/workflows/activity.js.map +1 -0
  750. package/dist/tinybee/workflows/cron.js +210 -0
  751. package/dist/tinybee/workflows/cron.js.map +1 -0
  752. package/dist/tinybee/workflows/engine.js +371 -0
  753. package/dist/tinybee/workflows/engine.js.map +1 -0
  754. package/dist/tinybee/workflows/from-text.js +203 -0
  755. package/dist/tinybee/workflows/from-text.js.map +1 -0
  756. package/dist/tinybee/workflows/routes.js +189 -0
  757. package/dist/tinybee/workflows/routes.js.map +1 -0
  758. package/dist/tinybee/workflows/scheduler.js +100 -0
  759. package/dist/tinybee/workflows/scheduler.js.map +1 -0
  760. package/dist/tinybee/workflows/skills.js +227 -0
  761. package/dist/tinybee/workflows/skills.js.map +1 -0
  762. package/dist/tinybee/workflows/store.js +205 -0
  763. package/dist/tinybee/workflows/store.js.map +1 -0
  764. package/dist/tinybee/workflows/types.js +180 -0
  765. package/dist/tinybee/workflows/types.js.map +1 -0
  766. package/dist/tinybee/workflows/yaml.js +323 -0
  767. package/dist/tinybee/workflows/yaml.js.map +1 -0
  768. package/dist/true/api.js +495 -0
  769. package/dist/true/api.js.map +1 -0
  770. package/dist/true/client.js +292 -0
  771. package/dist/true/client.js.map +1 -0
  772. package/dist/true/clock.js +36 -0
  773. package/dist/true/clock.js.map +1 -0
  774. package/dist/true/events.js +125 -0
  775. package/dist/true/events.js.map +1 -0
  776. package/dist/true/hosts.js +98 -0
  777. package/dist/true/hosts.js.map +1 -0
  778. package/dist/true/index.js +29 -0
  779. package/dist/true/index.js.map +1 -0
  780. package/dist/true/key.js +54 -0
  781. package/dist/true/key.js.map +1 -0
  782. package/dist/true/line.js +69 -0
  783. package/dist/true/line.js.map +1 -0
  784. package/dist/true/mask.js +31 -0
  785. package/dist/true/mask.js.map +1 -0
  786. package/dist/true/names.js +114 -0
  787. package/dist/true/names.js.map +1 -0
  788. package/dist/true/outbox.js +233 -0
  789. package/dist/true/outbox.js.map +1 -0
  790. package/dist/true/replay.js +164 -0
  791. package/dist/true/replay.js.map +1 -0
  792. package/dist/true/settings.js +123 -0
  793. package/dist/true/settings.js.map +1 -0
  794. package/dist/true/status.js +189 -0
  795. package/dist/true/status.js.map +1 -0
  796. package/dist/true/sync-cases.js +222 -0
  797. package/dist/true/sync-cases.js.map +1 -0
  798. package/dist/true/sync-manual.js +295 -0
  799. package/dist/true/sync-manual.js.map +1 -0
  800. package/dist/true/sync-runs.js +109 -0
  801. package/dist/true/sync-runs.js.map +1 -0
  802. package/dist/true/worker.js +414 -0
  803. package/dist/true/worker.js.map +1 -0
  804. package/dist/types.js +32 -0
  805. package/dist/types.js.map +1 -0
  806. package/dist/updates/asks.js +38 -0
  807. package/dist/updates/asks.js.map +1 -0
  808. package/dist/updates/index.js +835 -0
  809. package/dist/updates/index.js.map +1 -0
  810. package/dist/updates/owner.js +24 -0
  811. package/dist/updates/owner.js.map +1 -0
  812. package/dist/updates/prefs.js +118 -0
  813. package/dist/updates/prefs.js.map +1 -0
  814. package/dist/updates/route.js +78 -0
  815. package/dist/updates/route.js.map +1 -0
  816. package/dist/updates/sources.js +345 -0
  817. package/dist/updates/sources.js.map +1 -0
  818. package/dist/updates/words.js +452 -0
  819. package/dist/updates/words.js.map +1 -0
  820. package/dist/version.js +53 -0
  821. package/dist/version.js.map +1 -0
  822. package/dist/view-compute.js +382 -0
  823. package/dist/view-compute.js.map +1 -0
  824. package/dist/view-spec.js +894 -0
  825. package/dist/view-spec.js.map +1 -0
  826. package/dist/web/apple-touch-icon.png +0 -0
  827. package/dist/web/assets/ApprovalCard-Br_z5z7G.css +1 -0
  828. package/dist/web/assets/ApprovalCard-CfGhGFo_.js +3 -0
  829. package/dist/web/assets/CardFromRef-BaTGmZ9c.js +2 -0
  830. package/dist/web/assets/CardFromRef-DO7i2uDd.css +1 -0
  831. package/dist/web/assets/Cases-8l_6UcLh.js +2 -0
  832. package/dist/web/assets/Cases-CpfED0uB.css +1 -0
  833. package/dist/web/assets/Chat-BKDiR0qt.js +3 -0
  834. package/dist/web/assets/Chat-DxjdyYUu.css +1 -0
  835. package/dist/web/assets/ConfirmDialog-CIMveD-b.js +2 -0
  836. package/dist/web/assets/ConnectSheet-Cm5vbZdR.js +4 -0
  837. package/dist/web/assets/Docs-HKGuY0WE.js +2 -0
  838. package/dist/web/assets/Docs-fodKx8S7.css +1 -0
  839. package/dist/web/assets/DotDetail-DskS3NWe.js +2 -0
  840. package/dist/web/assets/DotDetail-OWRSD_1x.css +1 -0
  841. package/dist/web/assets/DotStage-BZDclfzV.css +1 -0
  842. package/dist/web/assets/DotStage-CtMNzCN3.js +2 -0
  843. package/dist/web/assets/Dots-BqCsS34m.js +2 -0
  844. package/dist/web/assets/EvidencePack-DQ3kCJX4.js +2 -0
  845. package/dist/web/assets/EvidencePack-DV_9ETsA.css +1 -0
  846. package/dist/web/assets/FailedDeliveries-1F2kFcs9.js +2 -0
  847. package/dist/web/assets/FailedDeliveries-DXa2_VvI.css +1 -0
  848. package/dist/web/assets/Feed-5wiHRTFK.js +2 -0
  849. package/dist/web/assets/GfmView-C-NYaduC.js +4 -0
  850. package/dist/web/assets/ImpactList-C-RNuDB0.js +2 -0
  851. package/dist/web/assets/ImpactList-C612dFdw.css +1 -0
  852. package/dist/web/assets/Inbox-kc1bKVL_.js +2 -0
  853. package/dist/web/assets/JoinScreen-C3L4wmP3.js +2 -0
  854. package/dist/web/assets/JoinScreen-COeAUv5v.css +1 -0
  855. package/dist/web/assets/LeadDialog-N3Zul9Rw.js +8 -0
  856. package/dist/web/assets/LeadDialog-xyWjAuAS.css +1 -0
  857. package/dist/web/assets/ListeningLine-BRFNaczY.js +2 -0
  858. package/dist/web/assets/ListeningLine-pN8CgyiK.css +1 -0
  859. package/dist/web/assets/Mascots-pIyGpxtD.js +2 -0
  860. package/dist/web/assets/ModelChoices-BxO1zyyr.js +2 -0
  861. package/dist/web/assets/ModelChoices-DQJnVxfs.css +1 -0
  862. package/dist/web/assets/NewDotDialog-CDPUWmgN.js +2 -0
  863. package/dist/web/assets/NewDotDialog-DrPPqkSZ.css +1 -0
  864. package/dist/web/assets/NewTestRunDialog-BQBthVHE.js +2 -0
  865. package/dist/web/assets/NoBreakNames-Csxdqdt6.js +2 -0
  866. package/dist/web/assets/Pair-omex_K7H.js +2 -0
  867. package/dist/web/assets/PushSection-CmqHlE_2.js +2 -0
  868. package/dist/web/assets/ReleaseNotes-B6VqFewP.js +2 -0
  869. package/dist/web/assets/ReleaseNotes-DBJUL7Vm.css +1 -0
  870. package/dist/web/assets/ReportPage-BHS1xWEt.js +162 -0
  871. package/dist/web/assets/Reports-BEHnDIb1.js +2 -0
  872. package/dist/web/assets/ReviewChangeDialog-BVSt-cw-.js +2 -0
  873. package/dist/web/assets/ReviewChangeDialog-BbIlHRx0.css +1 -0
  874. package/dist/web/assets/Room-BoG_uge4.js +2 -0
  875. package/dist/web/assets/Room-evAfiW_e.css +1 -0
  876. package/dist/web/assets/RunActions-ZY7yf1AF.js +2 -0
  877. package/dist/web/assets/RunDetail-C8St20GQ.css +1 -0
  878. package/dist/web/assets/RunDetail-qADXjBvd.js +9 -0
  879. package/dist/web/assets/RunRow-BKEJv8ib.js +2 -0
  880. package/dist/web/assets/RunnerTry-Dgpp67-s.js +6 -0
  881. package/dist/web/assets/RunnerTry-DsweWOfO.css +1 -0
  882. package/dist/web/assets/Settings-fs-QJwNM.js +2 -0
  883. package/dist/web/assets/Setup-DI6hBEP-.js +2 -0
  884. package/dist/web/assets/TestRows-wh03T5Li.js +4 -0
  885. package/dist/web/assets/TestRun-DTOyF-Pv.js +2 -0
  886. package/dist/web/assets/TestRuns-ggDjm1Q8.js +2 -0
  887. package/dist/web/assets/TinyBeeAddLaptop-bc3pmh3T.js +2 -0
  888. package/dist/web/assets/TinyBeeAi-CkyOzhm5.js +2 -0
  889. package/dist/web/assets/TinyBeeConnections-B2K_P38u.js +2 -0
  890. package/dist/web/assets/TinyBeeHome-DSpxX5KS.js +3 -0
  891. package/dist/web/assets/TinyBeePlan-BamiLziu.js +2 -0
  892. package/dist/web/assets/TinyBeeSignup-vHcz0Wen.js +2 -0
  893. package/dist/web/assets/TinyBeeSkills-By9RLUse.js +2 -0
  894. package/dist/web/assets/TinyBeeWorkflow-DeNO7Jsh.js +2 -0
  895. package/dist/web/assets/TinyBeeWorkflowEditor-B6OGC2OT.js +2 -0
  896. package/dist/web/assets/TinyBeeWorkflows-BN4-h6lt.js +2 -0
  897. package/dist/web/assets/Trace-BBCI1aIB.css +1 -0
  898. package/dist/web/assets/Trace-aF92UWaH.js +2 -0
  899. package/dist/web/assets/UpdatesSection-CCWEbkue.js +2 -0
  900. package/dist/web/assets/Welcome-CCcy558Q.js +2 -0
  901. package/dist/web/assets/activity-C3qilrDm.css +1 -0
  902. package/dist/web/assets/activity-CBfTSxqw.js +2 -0
  903. package/dist/web/assets/authedMedia-BTYt_tyu.js +2 -0
  904. package/dist/web/assets/beeApi-BHW8Tx1s.js +2 -0
  905. package/dist/web/assets/data-CmXvx3Mj.js +2 -0
  906. package/dist/web/assets/engines-CfdJODFj.css +1 -0
  907. package/dist/web/assets/format-BBZ8vFyT.js +2 -0
  908. package/dist/web/assets/forms-Coc7p2UF.css +1 -0
  909. package/dist/web/assets/hivePush-DZJDokj7.js +2 -0
  910. package/dist/web/assets/impactModel-MY1OFuiP.js +2 -0
  911. package/dist/web/assets/index-B6qKm1NW.js +13 -0
  912. package/dist/web/assets/index-BvKyT1X7.css +1 -0
  913. package/dist/web/assets/inter-cyrillic-ext-wght-normal-BOeWTOD4.woff2 +0 -0
  914. package/dist/web/assets/inter-cyrillic-wght-normal-DqGufNeO.woff2 +0 -0
  915. package/dist/web/assets/inter-greek-ext-wght-normal-DlzME5K_.woff2 +0 -0
  916. package/dist/web/assets/inter-greek-wght-normal-CkhJZR-_.woff2 +0 -0
  917. package/dist/web/assets/inter-latin-ext-wght-normal-DO1Apj_S.woff2 +0 -0
  918. package/dist/web/assets/inter-latin-wght-normal-Dx4kXJAl.woff2 +0 -0
  919. package/dist/web/assets/inter-vietnamese-wght-normal-CBcvBZtf.woff2 +0 -0
  920. package/dist/web/assets/lead-BL_P_kri.css +1 -0
  921. package/dist/web/assets/model-BIQy5IVG.js +2 -0
  922. package/dist/web/assets/modelsApi-PUSySRQw.js +2 -0
  923. package/dist/web/assets/newDotModel-BaLLyw57.js +2 -0
  924. package/dist/web/assets/onboarding-bfKqnM4Z.css +1 -0
  925. package/dist/web/assets/phone-Rs7FoyG0.css +1 -0
  926. package/dist/web/assets/phoneApi-BG_1-M-D.js +3 -0
  927. package/dist/web/assets/releaseModel-EynYMVOC.js +2 -0
  928. package/dist/web/assets/releaseNotesModel-A1Rtv3cV.js +2 -0
  929. package/dist/web/assets/reports-BWaA1HhM.js +37 -0
  930. package/dist/web/assets/reports-DXwdWQsB.css +1 -0
  931. package/dist/web/assets/router-W6nZsQ33.js +2 -0
  932. package/dist/web/assets/runs-BY0Owv93.css +1 -0
  933. package/dist/web/assets/shadowWeekModel-BUUiww09.js +2 -0
  934. package/dist/web/assets/storage-yvL36AWt.js +2 -0
  935. package/dist/web/assets/store-IqrqHuFR.js +2 -0
  936. package/dist/web/assets/testruns-BzIZ0cR0.css +1 -0
  937. package/dist/web/assets/testruns-DyaqX4ji.js +2 -0
  938. package/dist/web/assets/true-9Q68cs5b.js +2 -0
  939. package/dist/web/assets/true-DPGBpoir.css +1 -0
  940. package/dist/web/assets/ui-DcmhYyYp.js +13 -0
  941. package/dist/web/assets/ui-DxEDgbIx.css +1 -0
  942. package/dist/web/assets/usePauseDot-BV60ZVy1.js +2 -0
  943. package/dist/web/assets/usePauseDot-NrSzMI1C.css +1 -0
  944. package/dist/web/assets/usePush-Dsm-TjlG.js +2 -0
  945. package/dist/web/assets/useRefChips-CbafNx59.js +68 -0
  946. package/dist/web/assets/useRestoreDot-D0B6W82H.js +2 -0
  947. package/dist/web/assets/view-worker-pyeVAhUT.js +2 -0
  948. package/dist/web/assets/workflowUi-QYsd3n9J.js +2 -0
  949. package/dist/web/favicon.png +0 -0
  950. package/dist/web/icon-192.png +0 -0
  951. package/dist/web/icon-512.png +0 -0
  952. package/dist/web/icon-maskable-512.png +0 -0
  953. package/dist/web/index.html +45 -0
  954. package/dist/web/manifest.webmanifest +23 -0
  955. package/dist/web/mascots/argus-attention.svg +7 -0
  956. package/dist/web/mascots/argus-ok.svg +7 -0
  957. package/dist/web/mascots/argus-outage.svg +7 -0
  958. package/dist/web/mascots/argus-running.svg +7 -0
  959. package/dist/web/mascots/bolt-attention.svg +7 -0
  960. package/dist/web/mascots/bolt-ok.svg +7 -0
  961. package/dist/web/mascots/bolt-outage.svg +7 -0
  962. package/dist/web/mascots/bolt-running.svg +7 -0
  963. package/dist/web/mascots/echo-attention.svg +7 -0
  964. package/dist/web/mascots/echo-ok.svg +7 -0
  965. package/dist/web/mascots/echo-outage.svg +7 -0
  966. package/dist/web/mascots/echo-running.svg +7 -0
  967. package/dist/web/mascots/lens-attention.svg +7 -0
  968. package/dist/web/mascots/lens-ok.svg +7 -0
  969. package/dist/web/mascots/lens-outage.svg +7 -0
  970. package/dist/web/mascots/lens-running.svg +7 -0
  971. package/dist/web/mascots/moss-attention.svg +7 -0
  972. package/dist/web/mascots/moss-ok.svg +7 -0
  973. package/dist/web/mascots/moss-outage.svg +7 -0
  974. package/dist/web/mascots/moss-running.svg +7 -0
  975. package/dist/web/mascots/nit-attention.svg +7 -0
  976. package/dist/web/mascots/nit-ok.svg +7 -0
  977. package/dist/web/mascots/nit-outage.svg +7 -0
  978. package/dist/web/mascots/nit-running.svg +7 -0
  979. package/dist/web/mascots/nova-attention.svg +7 -0
  980. package/dist/web/mascots/nova-ok.svg +7 -0
  981. package/dist/web/mascots/nova-outage.svg +7 -0
  982. package/dist/web/mascots/nova-running.svg +7 -0
  983. package/dist/web/mascots/penn-attention.svg +7 -0
  984. package/dist/web/mascots/penn-ok.svg +7 -0
  985. package/dist/web/mascots/penn-outage.svg +7 -0
  986. package/dist/web/mascots/penn-running.svg +7 -0
  987. package/dist/web/mascots/pip-attention.svg +7 -0
  988. package/dist/web/mascots/pip-ok.svg +7 -0
  989. package/dist/web/mascots/pip-outage.svg +7 -0
  990. package/dist/web/mascots/pip-running.svg +7 -0
  991. package/dist/web/mascots/ward-attention.svg +7 -0
  992. package/dist/web/mascots/ward-ok.svg +7 -0
  993. package/dist/web/mascots/ward-outage.svg +7 -0
  994. package/dist/web/mascots/ward-running.svg +7 -0
  995. package/dist/web/sw.js +98 -0
  996. package/dist/webhook-seen.js +53 -0
  997. package/dist/webhook-seen.js.map +1 -0
  998. package/dist/webhooks.js +625 -0
  999. package/dist/webhooks.js.map +1 -0
  1000. package/dist/zip.js +63 -0
  1001. package/dist/zip.js.map +1 -0
  1002. package/docs/API-V2.md +532 -0
  1003. package/docs/CHAT-EVAL.md +130 -0
  1004. package/docs/CHAT-UI.md +416 -0
  1005. package/docs/CONNECTIONS.md +89 -0
  1006. package/docs/DATA-MODEL.md +518 -0
  1007. package/docs/DEPLOY.md +577 -0
  1008. package/docs/DOGFOOD-LEDGER.md +81 -0
  1009. package/docs/GITHUB.md +148 -0
  1010. package/docs/INTEGRATION-MODEL.md +200 -0
  1011. package/docs/LEAD-DOT.md +553 -0
  1012. package/docs/LIST-PATTERNS.md +52 -0
  1013. package/docs/MULTI-REPO.md +766 -0
  1014. package/docs/PARITY.md +276 -0
  1015. package/docs/PR-REVIEW-QA.md +1266 -0
  1016. package/docs/PR-REVIEW.md +357 -0
  1017. package/docs/SANDBOX.md +320 -0
  1018. package/docs/SETUP.md +776 -0
  1019. package/docs/SLACK.md +80 -0
  1020. package/docs/STAGES.md +619 -0
  1021. package/docs/TRACE-MAP.md +89 -0
  1022. package/docs/TRACKERS.md +225 -0
  1023. package/docs/VOICE.md +36 -0
  1024. package/docs/tinybee/00-README.md +45 -0
  1025. package/docs/tinybee/01-PRD.md +216 -0
  1026. package/docs/tinybee/02-architecture-pairing.md +199 -0
  1027. package/docs/tinybee/03-local-agent.md +222 -0
  1028. package/docs/tinybee/04-local-setup-ui.md +128 -0
  1029. package/docs/tinybee/05-mobile-app-ux.md +199 -0
  1030. package/docs/tinybee/06-environments-and-delivery.md +148 -0
  1031. package/docs/tinybee/07-coding-agent-handoff.md +116 -0
  1032. package/docs/tinybee/OPEN-QUESTIONS.md +26 -0
  1033. package/docs/tinybee/PROGRESS.md +134 -0
  1034. package/package.json +111 -4
@@ -0,0 +1,811 @@
1
+ // pr_check and post_merge share this body (docs/PR-REVIEW-QA.md sections 2.1, 2.10, 5, 6.1).
2
+ //
3
+ // pr_check: the heuristic spec run starts in parallel with the QA review (prepare, reviewer,
4
+ // verifier, merge), so test time and model time overlap. Specs the verified review adds run
5
+ // as a second batch. analyze() then gets the review as a fenced <qa_review> block. Outputs:
6
+ // check run with annotations, sticky comment with the checklist, and a templated push.
7
+ // A new head first marks the old comment and older reviews as stale.
8
+ //
9
+ // post_merge: the review runs first (or is reused from the PR review at the same head), and
10
+ // its regression scope drives the run. No sticky comment; release notes go to the digest.
11
+ import { listMemory } from '../agent/memory.js';
12
+ import { getLlmFor } from '../agent/llm.js';
13
+ import { runStage } from '../stages/index.js';
14
+ import { get, update } from '../db.js';
15
+ import { gate, rulesForEvent } from '../agent/rules.js';
16
+ import { supersedeOlderHeads } from '../agent/approvals.js';
17
+ import { addStep, closeDeployRun, finishRun, isRunCancelled, setReport, setVerdict, startRun } from '../agent/runs.js';
18
+ import { githubFor, githubWebUrl, GithubUnreachableError, previewFor } from '../integrations/github.js';
19
+ import { fullName, repoForEvent, testsOffRepo } from '../repos.js';
20
+ import { prepareReview } from '../review/index.js';
21
+ import { renderCheckRun, renderStickyComment, commentHead, markStale, renderQaSection, reportConsistency, reviewEvidence, } from '../review/render.js';
22
+ import { docsOnlyChange, FORK_NOT_RUN_REASON, forkNotRunReport, mergeShaOf, reusableMergeRun, runnerKey, skippedReport, specSuiteReport, testSavings, } from './testSavings.js';
23
+ import { checkShaOf, closeUnrun, trackRun } from './checkStatus.js';
24
+ import { prTestPlan, prTestTargetOf, sharedBuildNote } from './prTarget.js';
25
+ import { joinTestRepoReport, runTestRepos, testRepoHold, testRepoSwitches, testReposFor } from './testRepo.js';
26
+ import { draftDefects } from './defects.js';
27
+ import { runMergeCases } from './mergeCases.js';
28
+ import { draftIssueDefects } from './defectDraft.js';
29
+ import { draftTicketQuestions } from './questions.js';
30
+ import { environmentFactsFor } from './default-branch.js';
31
+ import { intentsFor } from './intent-sources.js';
32
+ import { refreshAfterRun } from './testStatus.js';
33
+ import { pendingCiNote, readCi } from './ci.js';
34
+ import { readabilityRubric } from '../review/readability.js';
35
+ import { qaBackendForStage, runQaReview } from '../review/run.js';
36
+ import { readLinkedTickets } from '../review/linked-tickets.js';
37
+ import { planReport } from '../review/report-plan.js';
38
+ import { ModelUnavailableError } from '../agent/model-errors.js';
39
+ import { teamCasesIn } from '../lead.js';
40
+ import { recordPrLinks } from '../links.js';
41
+ import { scopeNote } from '../pr-scope.js';
42
+ import { specNotesForPr } from '../impact/pr.js';
43
+ import { applyAiVisionResults, planAiVisionCases } from '../runner/aivision/index.js';
44
+ import { applyPwgenResults, engineOf, keptItemIds, planPwgenItems, pwgenOptions, runPwgen } from '../runner/pwgen/index.js';
45
+ import { proposalAction } from '../runner/pwgen/propose.js';
46
+ import { run as runTests, RunCancelledError } from '../runner/index.js';
47
+ import { checkConclusion, diffSummary, discoverSpecs, eventOf, forkCodeWouldRun, getDiff, guardedGithub, loadWatch, pickSpecs, publicRunUrl, pushAction, recheckByReply, renderComment, repoTarget, runSuite, setDemoBug, specDirFor, withDemoShop, noteModelFallback, notRunVerdict, } from './common.js';
48
+ import { applyManualTicks, applyQaToVerdict, applyTestResults, clearRunnerResults, combineReviews, differingFiles, findReviewedRun, manualTicks, markOlderReviewsStale, mergeReports, newerHead, reviewSettings, scopeSpecs, selectQaSpecs, storeDiff, } from './qa.js';
49
+ import { bugRepoAlts, bugRepoOf, targetRepo } from '../repos.js';
50
+ import { noteTestTotals } from '../monitor/self-health.js';
51
+ /** The URL of a deployment of this PR's head, when one is known: the job payload names it, or a deployment_status delivery recorded it. */
52
+ function previewOf(c, payload) {
53
+ const repo = c.ev.repo ?? targetRepo(c.watch, c.ev) ?? undefined;
54
+ return typeof payload.previewUrl === 'string' ? payload.previewUrl : repo && c.ev.pr?.headSha ? previewFor(repo, c.ev.pr.headSha) : undefined;
55
+ }
56
+ function baseUrlFor(c, demoUrl, payload) {
57
+ return demoUrl ?? (c.task === 'pr_check' ? previewOf(c, payload) : undefined) ?? (c.task === 'post_merge' ? c.deployUrl : undefined) ?? c.watch.baseUrl;
58
+ }
59
+ /** How often a PR check that waits for a preview looks for it. A test sets it low. */
60
+ export const previewWait = { pollMs: 2000 };
61
+ /**
62
+ * waitForPreviewSec (docs/SETUP.md section Waiting for a preview): a PR check whose dot sets it holds for up to that many seconds for a
63
+ * deployment of the PR head to be reported (a deployment_status delivery, which only a dot on webhooks gets), then tests what it has: the
64
+ * preview when it came, else the dot's base URL under the PR test target. The check keeps its queue slot while it waits. A cancelled
65
+ * run stops waiting.
66
+ */
67
+ async function waitForPreview(c, payload) {
68
+ const sec = c.watch.waitForPreviewSec ?? 0;
69
+ const head = c.ev.pr?.headSha;
70
+ if (sec <= 0 || !head || c.watch.runner.mode === 'demo' || previewOf(c, payload))
71
+ return;
72
+ const short = head.slice(0, 7);
73
+ addStep(c.run.id, 'Waiting for the PR preview', `No preview of ${short} is known yet. localdost waits up to ${sec} s for one.`, 'info');
74
+ const until = Date.now() + sec * 1000;
75
+ while (Date.now() < until && !previewOf(c, payload) && !isRunCancelled(c.run.id)) {
76
+ await new Promise((r) => setTimeout(r, Math.max(1, Math.min(previewWait.pollMs, until - Date.now()))));
77
+ }
78
+ const url = previewOf(c, payload);
79
+ if (url)
80
+ addStep(c.run.id, 'PR preview found', `The tests run against ${url}.`, 'ok');
81
+ else if (!isRunCancelled(c.run.id))
82
+ addStep(c.run.id, 'No PR preview appeared', `Waited ${sec} s for a preview of ${short}. The tests run as the PR test target says.`, 'warn');
83
+ }
84
+ /** The Tests repo batch (KAT-86): runs after the app repo's own tests, against the same target, and joins its report to theirs. */
85
+ async function testRepoBatch(c, payload, report, review, repos) {
86
+ const out = await withDemoShop(c.watch, async () => {
87
+ const demoUrl = await setDemoBug(c.watch, c.diff, c.run.id, true);
88
+ const baseUrl = baseUrlFor(c, demoUrl, payload);
89
+ return runTestRepos({ watch: c.watch, ev: c.ev, runId: c.run.id, task: c.task, ...(baseUrl ? { baseUrl } : {}), ...(review ? { review } : {}), repos });
90
+ });
91
+ return out ? joinTestRepoReport(report, out.report) : report;
92
+ }
93
+ /** The tickets the PR links, read for the reviewer (KAT-388). Never fails the run: without them the review reads the PR body alone. */
94
+ async function linkedTicketsOf(c) {
95
+ try {
96
+ const res = await readLinkedTickets(c.watch, c.ev);
97
+ if (res.tickets.length)
98
+ addStep(c.run.id, 'Linked tickets', `Read ${res.tickets.map((t) => t.ref).join(', ')} for the review, ${res.tickets.reduce((n, t) => n + t.criteria.length, 0)} acceptance criteria.`, 'info');
99
+ for (const n of res.notRead)
100
+ addStep(c.run.id, 'Linked ticket not read', `${n.ref}: ${n.reason}. The review ran without it.`, 'warn');
101
+ return res;
102
+ }
103
+ catch (err) {
104
+ addStep(c.run.id, 'Linked tickets not read', err instanceof Error ? err.message : String(err), 'warn');
105
+ return { tickets: [], notRead: [] };
106
+ }
107
+ }
108
+ /** Stages 1 to 6 for `files`; null with a warn step when the review cannot run. */
109
+ async function reviewChange(c, files, label = 'QA review') {
110
+ try {
111
+ const live = c.gh.mode !== 'demo';
112
+ const prep = await prepareReview({
113
+ watch: c.watch,
114
+ event: c.ev,
115
+ base: c.base,
116
+ head: c.head,
117
+ files,
118
+ runId: c.run.id,
119
+ // Owner files come from the base sha so a PR cannot steer its own review. Demo reads
120
+ // the local checkout, where prepareReview already ignores files the PR touches.
121
+ ...(live && c.base ? { readBaseFile: (p) => c.gh.readFile(p, c.base) } : {}),
122
+ ...(live && c.head ? { readHeadFile: (p) => c.gh.readFile(p, c.head) } : {}),
123
+ ...(live ? { fetchRawDiff: () => c.gh.rawDiff(c.ev.pr ? { pr: c.ev.pr.number } : { base: c.base, head: c.head }) } : {}),
124
+ ...(live ? { artifacts: c.gh.artifactSource() } : {}),
125
+ });
126
+ addStep(c.run.id, `Prepared the ${label.toLowerCase()}`, `${prep.hunks.length} changed range${prep.hunks.length === 1 ? '' : 's'}, ${prep.shownSignals.length} signal${prep.shownSignals.length === 1 ? '' : 's'}, ${prep.impactDrafts.length} impact area${prep.impactDrafts.length === 1 ? '' : 's'}, ${prep.specPaths.length} specs known.`);
127
+ const linked = await linkedTicketsOf(c);
128
+ const res = await runQaReview(prep, {
129
+ watch: c.watch,
130
+ event: c.ev,
131
+ prBody: c.ev.pr?.body,
132
+ linkedTickets: linked.tickets,
133
+ ticketsNotRead: linked.notRead,
134
+ memory: listMemory(c.watch.id),
135
+ backend: qaBackendForStage(c.watch, runStage(c.run)),
136
+ });
137
+ const r = res.review;
138
+ const pass = (role) => r.passes.find((p) => p.role === role);
139
+ const rev = pass('reviewer');
140
+ addStep(c.run.id, label, `${r.risks.length} risk${r.risks.length === 1 ? '' : 's'}, ${r.whatToTest.length} test${r.whatToTest.length === 1 ? '' : 's'} to run, regression scope ${r.regressionScope.level}. ${rev ? `${rev.model} (${rev.backend}), ${rev.rounds} round${rev.rounds === 1 ? '' : 's'}.` : ''}${res.fallback ? ' The model answer failed the checks, so the rule-based answer stands in.' : ''}`, r.coverage.status === 'complete' ? 'ok' : 'warn');
141
+ const ver = pass('verifier');
142
+ if (ver) {
143
+ const by = (s) => [...r.risks, ...r.whatToTest, ...r.testsAtRisk, ...r.testGaps].filter((x) => x.verifier.status === s).length;
144
+ addStep(c.run.id, 'Verifier', `${by('confirmed')} confirmed, ${by('uncertain')} uncertain, ${r.droppedByVerifier.length} refuted and dropped${by('unverified') ? `, ${by('unverified')} unverified` : ''}.`, by('unverified') ? 'warn' : 'ok');
145
+ }
146
+ if (r.coverage.status === 'incomplete')
147
+ addStep(c.run.id, 'Review incomplete', r.coverage.missing[0] ?? 'Not every change reached the reviewer.', 'warn');
148
+ return { prep, review: r };
149
+ }
150
+ catch (err) {
151
+ // No model works: the run stops with that reason (guarded() in common.ts) instead of testing on without a review.
152
+ if (err instanceof ModelUnavailableError)
153
+ throw err;
154
+ // GitHub could not be reached for the checkout: the run stops and the job retries, instead of a review on patches alone.
155
+ if (err instanceof GithubUnreachableError)
156
+ throw err;
157
+ addStep(c.run.id, `${label} unavailable`, err instanceof Error ? err.message : String(err), 'warn');
158
+ return null;
159
+ }
160
+ }
161
+ function inventoryFor(c, prep) {
162
+ const found = discoverSpecs(specDirFor(c.watch), c.watch.runner.smokeGrep ?? '@smoke');
163
+ const all = found.length ? found.map((s) => s.file) : (prep?.tests.filter((t) => t.kind === 'e2e').map((t) => t.path) ?? []);
164
+ const smoke = found.length ? found.filter((s) => s.smoke).map((s) => s.file) : (prep?.tests.filter((t) => t.smoke).map((t) => t.path) ?? []);
165
+ const byArea = { ...(prep?.specsByArea ?? {}) };
166
+ for (const a of prep?.impactDrafts ?? [])
167
+ if (prep?.specsByArea[a.id])
168
+ byArea[a.area] = prep.specsByArea[a.id];
169
+ return { all, smoke, byArea };
170
+ }
171
+ /**
172
+ * Drafts for an older head of the PR, defects and ticket comments included, are superseded once a run for a newer head
173
+ * reads that head (dogfood ledger). A run for an older head that ends late closes nothing. Returns how many it closed.
174
+ */
175
+ export function supersedeOldHeadDrafts(watchId, ev, head, run) {
176
+ const pr = ev.pr;
177
+ if (!pr || !head)
178
+ return 0;
179
+ if (newerHead(watchId, pr.number, head, run.createdAt))
180
+ return 0;
181
+ const repo = ev.repo ? `${ev.repo.owner}/${ev.repo.name}` : undefined;
182
+ const gone = supersedeOlderHeads(watchId, pr.number, head, repo);
183
+ if (gone.length)
184
+ addStep(run.id, 'Superseded drafts for the older head', `${gone.length} draft${gone.length === 1 ? '' : 's'} (${[...new Set(gone.map((a) => a.action.kind.replace('_', ' ')))].join(', ')}) for an older head of PR #${pr.number} closed.`, 'info');
185
+ return gone.length;
186
+ }
187
+ /** Before a new review lands: older reviews and the old comment say they are out of date. */
188
+ async function markStaleHead(c) {
189
+ const pr = c.ev.pr;
190
+ if (!pr || !c.head)
191
+ return;
192
+ const n = markOlderReviewsStale(c.watch.id, pr.number, c.head, c.run.id);
193
+ const previous = await c.gh.getStickyComment(pr.number).catch(() => null);
194
+ const old = commentHead(previous);
195
+ if (previous && old && !c.head.startsWith(old)) {
196
+ await gate({
197
+ kind: 'pr_comment',
198
+ target: `${repoTarget(c.watch, c.ev)}#${pr.number}`,
199
+ title: `QA review for PR #${pr.number} is out of date`,
200
+ body: markStale(previous, c.head, { recheckByReply: recheckByReply() }),
201
+ meta: { pr: pr.number, sticky: true, stale: true, head: c.head, evidence: reviewEvidence({ newerHead: c.head, runId: c.run.id }) },
202
+ }, c.watch, c.run.id);
203
+ }
204
+ if (n || (old && !c.head.startsWith(old)))
205
+ addStep(c.run.id, 'Marked the old review out of date', `New head ${c.head.slice(0, 12)}.`, 'info');
206
+ }
207
+ /**
208
+ * What a run's tests are for, so they run on that commit in a worktree (KAT-284): the pull request of a pr_check, or
209
+ * the default branch for a merge. The runner confirms the commit either way (src/runner/verify.ts, KAT-291): the event
210
+ * only says what it claims, and a merge is checked against the default branch GitHub reports, or the branch named here when the
211
+ * dot lists it in testBranches (KAT-292).
212
+ * A range a person asked for may name any commit, so it carries neither and keeps the default-branch check and the HEAD check.
213
+ */
214
+ function commitOf(c) {
215
+ const { ev } = c;
216
+ if (c.task === 'pr_check')
217
+ return ev.pr ? { pr: { number: ev.pr.number, ...(ev.pr.fork ? { fork: true } : {}) } } : {};
218
+ if (ev.pr?.mergeSha)
219
+ return { merge: ev.pr.baseRef ? { branch: ev.pr.baseRef } : {} };
220
+ if (ev.push && !ev.requestedBy)
221
+ return { merge: { branch: ev.push.ref.replace(/^refs\/heads\//, '') } };
222
+ return {};
223
+ }
224
+ async function heuristicRun(c, payload) {
225
+ return withDemoShop(c.watch, async () => {
226
+ const demoUrl = await setDemoBug(c.watch, c.diff, c.run.id);
227
+ const baseUrl = baseUrlFor(c, demoUrl, payload);
228
+ const pick = pickSpecs(c.watch, c.diff);
229
+ addStep(c.run.id, 'Picked specs', pick.specs.length ? `${pick.specs.length} of ${pick.total}: ${pick.reason}` : pick.reason);
230
+ const { report } = await runSuite(c.watch, c.run.id, { baseUrl, sha: c.sha, specs: pick.specs, repo: c.ev.repo, ...commitOf(c) });
231
+ return { report, picked: pick.specs, baseUrl };
232
+ });
233
+ }
234
+ async function batchRun(c, payload, specs, grep) {
235
+ return withDemoShop(c.watch, async () => {
236
+ const demoUrl = await setDemoBug(c.watch, c.diff, c.run.id, true);
237
+ const baseUrl = baseUrlFor(c, demoUrl, payload);
238
+ const { report } = await runSuite(c.watch, c.run.id, { baseUrl, sha: c.sha, specs, grep, repo: c.ev.repo, ...commitOf(c) });
239
+ return report;
240
+ });
241
+ }
242
+ /** post_merge: reuse the PR review at the same head, or review the difference only, or review it all. */
243
+ async function postMergeReview(c) {
244
+ const reviewedHead = c.ev.pr?.headSha || c.ev.push?.after;
245
+ const prior = findReviewedRun(c.watch.id, reviewedHead);
246
+ if (!prior?.verdict?.qa)
247
+ return reviewChange(c, c.diff);
248
+ const changed = differingFiles(prior.diff, c.diff);
249
+ if (!changed.length) {
250
+ addStep(c.run.id, 'Reused the PR review', `The PR was reviewed at ${prior.verdict.qa.head.slice(0, 12)} in run ${prior.id}; the merge changes nothing it did not read.`, 'ok');
251
+ // Prep (no model call) still gives the spec links the regression scope needs.
252
+ let prep;
253
+ try {
254
+ prep = await prepareReview({ watch: c.watch, event: c.ev, base: c.base, head: c.head, files: c.diff, runId: c.run.id });
255
+ }
256
+ catch (err) {
257
+ if (err instanceof GithubUnreachableError)
258
+ throw err;
259
+ prep = undefined;
260
+ }
261
+ return { prep, review: { ...prior.verdict.qa, head: c.head, staleFor: undefined } };
262
+ }
263
+ addStep(c.run.id, 'Reviewing the merge difference', `The PR review at ${prior.verdict.qa.head.slice(0, 12)} is reused; ${changed.length} file${changed.length === 1 ? '' : 's'} changed after it: ${changed
264
+ .slice(0, 5)
265
+ .map((f) => f.path)
266
+ .join(', ')}.`);
267
+ const part = await reviewChange(c, changed, 'Review of the difference');
268
+ if (!part)
269
+ return { review: { ...prior.verdict.qa, head: c.head, staleFor: undefined } };
270
+ return { prep: part.prep, review: combineReviews(prior.verdict.qa, part.review, c.head, c.diff) };
271
+ }
272
+ /** Writes the PR's links to issues and tickets (closing keywords, ticket keys, closingIssuesReferences). Never fails the run. */
273
+ async function linkPr(watch, ev, runId) {
274
+ try {
275
+ const n = await recordPrLinks(watch, ev);
276
+ if (n)
277
+ addStep(runId, 'Linked issues', `${n} new link${n === 1 ? '' : 's'} from the PR`);
278
+ }
279
+ catch (err) {
280
+ addStep(runId, 'Issue links failed', String(err), 'warn');
281
+ }
282
+ }
283
+ /** Recomputes the test status of the issues this PR links to, and drafts the status labels when the dot asks for them. Never fails the run. */
284
+ async function refreshStatus(watch, ev, runId) {
285
+ if (!ev.pr || !ev.repo)
286
+ return;
287
+ try {
288
+ await refreshAfterRun(watch, `${ev.repo.owner}/${ev.repo.name}#${ev.pr.number}`, runId);
289
+ }
290
+ catch (err) {
291
+ addStep(runId, 'Test status failed', String(err), 'warn');
292
+ }
293
+ }
294
+ export async function checkChange(job, task) {
295
+ const ev = eventOf(job);
296
+ // A review asked for without posting runs with the PR comment and the check run held in the Inbox (KAT-357).
297
+ const watch = rulesForEvent(loadWatch(job.watchId), ev);
298
+ if (watch.paused) {
299
+ // A merge job that waited for the deploy (KAT-368) leaves its run held: a pause that came as the wait ended must not leave it there.
300
+ const held = get('jobs', job.id)?.deployWait?.runId;
301
+ if (held)
302
+ closeDeployRun(held, { label: 'Stopped waiting for the deploy', detail: 'The dot is paused, so localdost did not run this check.', status: 'warn' }, 'dot paused');
303
+ await closeUnrun(job, watch, 'Skipped', 'The dot is paused, so localdost did not run this check.');
304
+ return;
305
+ }
306
+ const run = startRun(watch.id, task, ev);
307
+ // The queued check moves to in progress now, follows the run, and is closed in finally if no report replaced it.
308
+ const check = trackRun(job, watch, ev, run);
309
+ try {
310
+ await runChange(job, task, watch, ev, run, check);
311
+ }
312
+ finally {
313
+ await check.close();
314
+ }
315
+ }
316
+ async function runChange(job, task, watch, ev, run, check) {
317
+ await guardedGithub(run.id, ev.pr ? `PR #${ev.pr.number}` : 'this change', async () => {
318
+ if (ev.requestedBy)
319
+ addStep(run.id, 'Review requested', `${ev.title}. Asked ${ev.requestedBy === 'chat' ? 'in chat' : 'on demand'}.`, 'info');
320
+ // A merge run that waited for the deploy (src/deploy-wait.ts) opened with this step already.
321
+ else if (!(task === 'post_merge' && run.steps.some((s) => s.label === 'Merge detected')))
322
+ addStep(run.id, task === 'post_merge' ? 'Merge detected' : 'Pull request updated', ev.title);
323
+ // KAT-384: a fork PR is reviewed and never tested. Reading its files is safe; running its code is not (runner.trustForks lifts that).
324
+ const forkNoTests = task === 'pr_check' && forkCodeWouldRun(watch, ev);
325
+ if (forkNoTests)
326
+ addStep(run.id, 'Tests did not run: fork pull request', `PR #${ev.pr?.number} comes from a fork, so localdost did not run its code. The code review still runs. Ask a maintainer to check it again.`, 'warn');
327
+ // The dot filters this repo by path but the changed files were unknown at match time (KAT-160).
328
+ if (ev.pathFilterNote && repoForEvent(watch, ev)?.pathFilters?.length) {
329
+ addStep(run.id, 'Path filters not applied', `${ev.pathFilterNote} The repo's path filters were skipped, so this event reached the dot.`, 'warn');
330
+ }
331
+ // A PR scope rule that could not be read let this PR in: say so on the run (KAT-354).
332
+ const scopeNotice = scopeNote(watch, ev);
333
+ if (scopeNotice)
334
+ addStep(run.id, 'PR scope not applied', scopeNotice, 'warn');
335
+ const diff = await getDiff(watch, ev);
336
+ addStep(run.id, 'Read the diff', diffSummary(diff));
337
+ // Any event that carries a PR records its links, so a merged PR that had no pr_check still has them before the status is computed.
338
+ if (ev.pr && ev.repo)
339
+ await linkPr(watch, ev, run.id);
340
+ const sha = checkShaOf(ev);
341
+ const settings = reviewSettings(watch);
342
+ const reviewOn = settings.enabled && diff.length > 0;
343
+ const head = (task === 'pr_check' ? ev.pr?.headSha : (ev.pr?.mergeSha ?? ev.push?.after)) ?? sha ?? '';
344
+ const base = ev.push?.before ?? ev.pr?.baseSha ?? '';
345
+ // A merge that waited for its deploy tests the URL GitHub gave for that deployment (src/deploy-wait.ts), else the dot's base URL.
346
+ const deployUrl = task === 'post_merge' && !ev.requestedBy ? get('jobs', job.id)?.deployWait?.url : undefined;
347
+ const c = { watch, ev, run, task, diff, gh: githubFor(watch, ev), sha, base, head, ...(deployUrl ? { deployUrl } : {}) };
348
+ const payload = job.payload;
349
+ if (reviewOn)
350
+ storeDiff(run.id, diff);
351
+ // Self-health reads these to tell code changes from docs-only ones; storeDiff only runs when the review is on.
352
+ update('runs', run.id, { changedPaths: diff.map((f) => f.path) });
353
+ // KAT-361: a repo with Run tests off is reviewed and never tested, so there is no "Tests did not run" failure for it.
354
+ // KAT-344: a docs-only change skips the test run, and a merge of the same tree reuses the PR results.
355
+ const savings = testSavings(watch);
356
+ const DOCS_ONLY_REASON = 'only docs or the changelog changed';
357
+ const testsOff = testsOffRepo(watch, ev);
358
+ const docsOnly = savings.docsOnlySkip && docsOnlyChange(diff);
359
+ const skipReason = forkNoTests ? undefined : testsOff ? `Run tests is off for ${fullName(testsOff)}` : docsOnly ? DOCS_ONLY_REASON : undefined;
360
+ const skipTests = skipReason !== undefined;
361
+ // KAT-86: the Tests repos of the dot run after the app repo's own tests. The app repo's Run tests switch does not hold them back.
362
+ // A fork PR's Tests repo follows its own fork rule (src/runner/test-repo.ts): the suite is the team's code, the page is the fork's.
363
+ const testRepos = testReposFor(watch, ev, task);
364
+ if (testsOff && !forkNoTests)
365
+ addStep(run.id, `Tests skipped: ${skipReason}`, `The dot reviews ${fullName(testsOff)} and runs no tests for it. Turn Run tests on for the repo in the dot settings to test its pull requests.`, 'info');
366
+ else if (skipTests)
367
+ addStep(run.id, `Tests skipped: ${DOCS_ONLY_REASON}`, `${diff.length} file${diff.length === 1 ? '' : 's'}: ${diff
368
+ .slice(0, 5)
369
+ .map((f) => f.path)
370
+ .join(', ')}${diff.length > 5 ? ', ...' : ''}.`, 'info');
371
+ // waitForPreviewSec: a PR check whose tests will run holds for the preview of its head before it picks a target.
372
+ if (task === 'pr_check' &&
373
+ !docsOnly &&
374
+ prTestTargetOf(watch) !== 'none' &&
375
+ ((!testsOff && !forkNoTests) || (testRepos.length > 0 && testRepoSwitches(watch).onPr)))
376
+ await waitForPreview(c, payload);
377
+ // KAT-363: what this PR check tests against. No preview of the PR means the dot's base URL, a build of shared QA work.
378
+ const prPlan = task === 'pr_check' ? prTestPlan({ watch, preview: previewOf(c, payload) }) : undefined;
379
+ const prPlanSkip = prPlan && !prPlan.run ? prPlan.skip : undefined;
380
+ const prSkip = forkNoTests ? undefined : prPlanSkip;
381
+ const testRepoWhy = testRepos.length ? testRepoHold({ watch, task, docsOnly, prSkip: prPlanSkip, baseUrl: baseUrlFor(c, undefined, payload) }) : null;
382
+ const testReposRun = testRepos.length > 0 && !testRepoWhy;
383
+ if (testRepos.length && testRepoWhy)
384
+ addStep(run.id, `Tests repo skipped: ${testRepoWhy}`, `The dot does not run ${testRepos.map(fullName).join(', ')} for this ${task === 'pr_check' ? 'PR' : 'merge'}.`, 'info');
385
+ // Why the tests of a PR check do not run: Run tests is off for the repo, only docs changed, or the dot's PR test target says so.
386
+ const noTestsWhy = task === 'pr_check' ? (forkNoTests ? FORK_NOT_RUN_REASON : (skipReason ?? prSkip)) : undefined;
387
+ // A fork PR has no test result at all, which is no pass: its report says the tests did not run.
388
+ const noTestsReport = (why) => (forkNoTests ? forkNotRunReport() : skippedReport(why));
389
+ if (prSkip && !skipTests)
390
+ addStep(run.id, `Tests skipped: ${prSkip}`, `The dot's PR test target is ${watch.prTestTarget ?? 'base'}. The code review still runs.`, 'info');
391
+ const sharedBuild = prPlan?.shared === true && (!noTestsWhy || testReposRun);
392
+ if (sharedBuild)
393
+ addStep(run.id, 'Tests run against the shared QA build', `No preview of this PR is known, so the tests run against the dot's base URL (${watch.baseUrl}), not a build of this PR. A failure may be this PR's new or changed spec running against an older build, so none is drafted as a defect.`, 'warn');
394
+ let reuse = null;
395
+ // The spec suite a pr_check run ran, kept on the run so a merge reuses it only when it covers the merge's own selection.
396
+ let tested;
397
+ let report;
398
+ let review;
399
+ // Repo paths of known e2e specs: where proposed generated specs go.
400
+ let e2ePaths = [];
401
+ if (task === 'pr_check') {
402
+ // Stage 7 overlaps stages 4 and 5: the heuristic run starts with the review. Both settle before
403
+ // the run goes on or stops, so a failed read never leaves the other half running in the background.
404
+ const heurRun = noTestsWhy ? Promise.resolve({ report: noTestsReport(noTestsWhy), picked: [] }) : heuristicRun(c, payload);
405
+ const [heur, rvRes] = await Promise.allSettled([heurRun, reviewOn ? reviewChange(c, diff) : Promise.resolve(null)]);
406
+ if (heur.status === 'rejected')
407
+ throw heur.reason;
408
+ if (rvRes.status === 'rejected')
409
+ throw rvRes.reason;
410
+ const first = heur.value;
411
+ const rv = rvRes.value;
412
+ // No picked specs means the full suite ran.
413
+ if (!noTestsWhy) {
414
+ const url = first.baseUrl;
415
+ const at = url ? { baseUrl: url } : {};
416
+ tested = first.picked.length ? { full: false, specs: [...first.picked], ...at } : { full: true, specs: [], ...at };
417
+ }
418
+ // The old comment says it is out of date only once the head is known to be readable: a run that
419
+ // stops because GitHub is unreachable drafts nothing for the PR (KAT-283).
420
+ if (reviewOn)
421
+ await markStaleHead(c);
422
+ supersedeOldHeadDrafts(watch.id, ev, head, run);
423
+ report = first.report;
424
+ if (rv) {
425
+ if (!noTestsWhy) {
426
+ const sel = selectQaSpecs({ heuristic: first.picked, review: rv.review, inv: inventoryFor(c, rv.prep) });
427
+ addStep(run.id, 'Specs from the review', sel.added.length ? `${sel.added.length} more: ${sel.added.join(', ')} (${sel.reason})` : `No more specs: ${sel.reason}.`);
428
+ if (sel.added.length)
429
+ report = mergeReports(report, await batchRun(c, payload, sel.added, sel.grep));
430
+ // Added specs run whole only without a title filter; a filtered batch ran part of each spec.
431
+ // The added specs ran against the same base URL, so the record keeps it: merge reuse compares it (KAT-358).
432
+ if (sel.added.length && !sel.grep && tested && !tested.full)
433
+ tested = { ...tested, full: false, specs: [...new Set([...tested.specs, ...sel.added])] };
434
+ }
435
+ review = rv.review;
436
+ e2ePaths = rv.prep.tests.filter((t) => t.kind === 'e2e').map((t) => t.path);
437
+ }
438
+ if (testReposRun)
439
+ report = await testRepoBatch(c, payload, report, review, testRepos);
440
+ }
441
+ else {
442
+ const rv = reviewOn ? await postMergeReview(c) : null;
443
+ review = rv?.review;
444
+ e2ePaths = rv?.prep?.tests.filter((t) => t.kind === 'e2e').map((t) => t.path) ?? [];
445
+ let specs;
446
+ let why;
447
+ // The merge's selection, decided before reuse: a PR run reuses only when it ran every spec the merge would.
448
+ let mergeFull = true;
449
+ let mergeSpecs = [];
450
+ if (!skipTests) {
451
+ const pick = pickSpecs(watch, diff);
452
+ const s = review
453
+ ? scopeSpecs(review, inventoryFor(c, rv?.prep), diff.map((f) => f.path))
454
+ : undefined;
455
+ mergeFull = !!s?.full || !pick.specs.length;
456
+ mergeSpecs = mergeFull ? [] : [...new Set([...(s?.specs ?? []), ...pick.specs])];
457
+ if (review && !mergeFull && mergeSpecs.length) {
458
+ specs = mergeSpecs;
459
+ why = `${s.reason}; ${mergeSpecs.length} specs with today's pick.`;
460
+ }
461
+ else if (review && mergeFull) {
462
+ specs = [];
463
+ why = s.full ? s.reason : 'no spec matched the diff, so the full suite runs.';
464
+ }
465
+ }
466
+ if (!skipTests && savings.reuseMergeResults && !ev.requestedBy) {
467
+ const mergeUrl = baseUrlFor(c, undefined, payload);
468
+ reuse = await reusableMergeRun(watch, c.gh, ev, { full: mergeFull, specs: mergeSpecs, ...(mergeUrl ? { baseUrl: mergeUrl } : {}) });
469
+ if (reuse) {
470
+ const url = publicRunUrl(reuse.run.id);
471
+ addStep(run.id, `Same code as the tested PR head ${reuse.head.slice(0, 7)}: reusing its results`, `The merge commit ${mergeShaOf(ev).slice(0, 7)} and the PR head have tree ${reuse.tree.slice(0, 12)}. Results of run ${reuse.run.id}${url ? `: ${url}` : '.'}`, 'ok');
472
+ }
473
+ }
474
+ if (skipTests)
475
+ report = skippedReport(skipReason);
476
+ else if (reuse)
477
+ report = specSuiteReport(reuse.run.report);
478
+ else if (specs) {
479
+ report = await withDemoShop(watch, async () => {
480
+ const demoUrl = await setDemoBug(watch, diff, run.id);
481
+ addStep(run.id, 'Picked specs', `Regression scope drives the run. ${why ?? ''}`.trim());
482
+ return (await runSuite(watch, run.id, { baseUrl: baseUrlFor(c, demoUrl, payload), sha, specs, repo: ev.repo, ...commitOf(c) })).report;
483
+ });
484
+ }
485
+ else
486
+ report = (await heuristicRun(c, payload)).report;
487
+ if (testReposRun)
488
+ report = await testRepoBatch(c, payload, report, review, testRepos);
489
+ }
490
+ // Generated Playwright specs (engine auto, playwright, or both) cover review items no existing
491
+ // spec covers; results land as pwgen/<id>.spec.ts.
492
+ const engine = engineOf(watch);
493
+ const testsSkipped = skipTests || !!noTestsWhy;
494
+ const pwOpts = review && !testsSkipped ? pwgenOptions(watch, task) : null;
495
+ let pw;
496
+ if (review && pwOpts) {
497
+ const items = planPwgenItems(review, pwOpts.maxSpecs);
498
+ const targetUrl = baseUrlFor(c, undefined, payload);
499
+ if (items.length && !targetUrl) {
500
+ addStep(run.id, 'Skipped Playwright e2e tests', 'No preview URL and no base URL to run them against. Set the dot base URL.', 'warn');
501
+ }
502
+ else if (items.length && targetUrl) {
503
+ addStep(run.id, 'Writing Playwright e2e tests', `${items.length} item${items.length === 1 ? '' : 's'} without a spec, against ${targetUrl}: ${items
504
+ .slice(0, 3)
505
+ .map((t) => t.scenario)
506
+ .join(', ')}${items.length > 3 ? ', ...' : ''}`);
507
+ pw = await runPwgen({
508
+ watch,
509
+ review,
510
+ items,
511
+ targetUrl,
512
+ ...(watch.baseUrl ? { baseUrl: watch.baseUrl } : {}),
513
+ runId: run.id,
514
+ step: (title, detail, level) => addStep(run.id, title, detail, level),
515
+ isCancelled: () => isRunCancelled(run.id),
516
+ });
517
+ const kept = (pw.generated ?? []).filter((g) => g.status === 'kept').length;
518
+ addStep(run.id, 'Playwright e2e finished', `${kept} kept (${pw.passed} passed, ${pw.failed} failed), ${(pw.generated?.length ?? 0) - kept} discarded, in ${Math.round(pw.durationMs / 1000)} s`, pw.failed ? 'warn' : 'ok');
519
+ report = mergeReports(report, pw);
520
+ // A cancel during generation stops the run here, before anything goes outward.
521
+ if (isRunCancelled(run.id))
522
+ throw new RunCancelledError(run.id);
523
+ }
524
+ }
525
+ // AI-Vision cases (review items and ticket test ideas) run after the specs; results land as aivision/<id>.yaml.
526
+ // auto: only items no generated spec covered. playwright: none.
527
+ const avCases = engine === 'playwright' || testsSkipped
528
+ ? []
529
+ : planAiVisionCases({ watch, kind: task, ...(review ? { review } : {}), event: ev, ...(engine === 'auto' ? { excludeItems: keptItemIds(pw) } : {}) });
530
+ // The cases another member of the team designed (Ticket Reviewer) are named in the report, by the dot that owns them (KAT-405).
531
+ for (const [owner, cases] of teamCasesIn(watch.id, avCases)) {
532
+ addStep(run.id, `Test cases from ${owner}`, `${cases.length} case${cases.length === 1 ? '' : 's'}: ${cases
533
+ .slice(0, 5)
534
+ .map((c) => `${c.key} ${c.title}`)
535
+ .join('; ')}${cases.length > 5 ? '; ...' : ''}`, 'info');
536
+ }
537
+ if (avCases.length) {
538
+ addStep(run.id, 'Running AI-Vision cases', `${avCases.length} case${avCases.length === 1 ? '' : 's'}: ${avCases
539
+ .slice(0, 3)
540
+ .map((x) => x.title)
541
+ .join(', ')}${avCases.length > 3 ? ', ...' : ''}`);
542
+ const av = await runTests({ watch, repo: ev.repo, sha, baseUrl: baseUrlFor(c, undefined, payload), aivision: { cases: avCases } }, { runId: run.id });
543
+ addStep(run.id, 'AI-Vision finished', `${av.passed} passed, ${av.failed} failed, ${av.skipped} skipped in ${Math.round(av.durationMs / 1000)} s`, av.failed ? 'warn' : 'ok');
544
+ report = mergeReports(report, av);
545
+ }
546
+ // A PR run against the shared build says nothing about the PR's code, so a merge never reuses it (KAT-363, prRunCovers).
547
+ if (task === 'pr_check')
548
+ update('runs', run.id, {
549
+ runnerKey: runnerKey(watch),
550
+ ...(tested && !sharedBuild ? { testedSpecs: tested } : {}),
551
+ // The ticket test status reads a failure of this run as not tested on this PR (src/flows/testStatus.ts).
552
+ ...(sharedBuild && !report.notRun ? { sharedBuild: true } : {}),
553
+ });
554
+ // Tests that ran against the shared build say so on the report, next to the counts (KAT-363).
555
+ if (sharedBuild && !report.notRun)
556
+ report = { ...report, hint: [report.hint, sharedBuildNote(report.failed)].filter(Boolean).join(' ') };
557
+ setReport(run.id, report);
558
+ const pr = ev.pr?.number;
559
+ if (review) {
560
+ review = clearRunnerResults(review);
561
+ const ci = await readCi(c.gh, head);
562
+ if (ci) {
563
+ const done = ci.jobs.filter((j) => j.check.status === 'completed').length;
564
+ addStep(run.id, 'Read CI results', `${ci.jobs.length} check run${ci.jobs.length === 1 ? '' : 's'} on ${head.slice(0, 7)}, ${done} finished.`);
565
+ }
566
+ else
567
+ addStep(run.id, 'No CI evidence', `No CI check runs could be read for ${head.slice(0, 7)}.`, 'info');
568
+ review = applyTestResults(review, report, ci);
569
+ // The own run was not for this commit, so its count is withheld. Say where the results will come from.
570
+ const pending = report.notRun?.stage === 'checkout' ? pendingCiNote(ci) : '';
571
+ if (report.notRun && pending) {
572
+ report = { ...report, notRun: { ...report.notRun, reason: `${report.notRun.reason} ${pending}` } };
573
+ setReport(run.id, report);
574
+ }
575
+ review = applyPwgenResults(review, report);
576
+ review = applyAiVisionResults(review, report);
577
+ if (pr && task === 'pr_check')
578
+ review = applyManualTicks(review, manualTicks(watch.id, pr, run.id));
579
+ if (pr && task === 'pr_check') {
580
+ const newer = newerHead(watch.id, pr, head, run.createdAt);
581
+ if (newer)
582
+ review = { ...review, staleFor: newer };
583
+ }
584
+ // Decisions the PR body, its tickets and the docs state: a matching finding is a behavior change to confirm.
585
+ const intents = await intentsFor(watch, ev, diff, c.gh.mode !== 'demo' && c.base ? (p) => c.gh.readFile(p, c.base) : undefined);
586
+ if (intents.length) {
587
+ review = { ...review, intents };
588
+ addStep(run.id, 'Read the stated decisions', `${intents.length} statement${intents.length === 1 ? '' : 's'} of intent in the PR, its tickets and the docs.`, 'info');
589
+ }
590
+ }
591
+ // The cases of the tickets this merge closes or references: automated ones record their result, manual ones wait in a test run (KAT-169).
592
+ const mergeCases = task === 'post_merge' ? runMergeCases(watch, run, ev, report) : undefined;
593
+ // Tests that did not run get a fixed environment verdict; the model never reads a missing report as a failure.
594
+ const analyzed = report.notRun && report.failed === 0
595
+ ? notRunVerdict(report, pr ? `PR #${pr}` : 'this change')
596
+ : noteModelFallback(run.id, await getLlmFor(watch, runStage(run)).analyze({
597
+ task,
598
+ watch,
599
+ event: ev,
600
+ diff,
601
+ report,
602
+ memory: listMemory(watch.id),
603
+ ...(review ? { qaReview: review } : {}),
604
+ }));
605
+ // The report says what was tested and what was found (KAT-96); it never advises on the merge.
606
+ // Links and defects point at the repo the change is in, which for a two-repo dot is not always the first one.
607
+ const changeRepo = targetRepo(watch, ev);
608
+ const links = { repo: changeRepo ? { owner: changeRepo.owner, name: changeRepo.name } : undefined, serverUrl: githubWebUrl() };
609
+ const bugScope = task === 'pr_check' && pr ? `pr:${pr}` : `merge:${sha ?? run.id}`;
610
+ // The tests of this run ran against the shared build and have results: the report, the check and the push treat a failure as no bug of the PR (KAT-363).
611
+ const planShared = sharedBuild && !report.notRun;
612
+ // One step decides bugs, risks to test, the headline, and what may become a defect (dogfood ledger).
613
+ const plan = planReport({
614
+ task,
615
+ watchId: watch.id,
616
+ runId: run.id,
617
+ review,
618
+ report,
619
+ verdict: review ? applyQaToVerdict(analyzed, review, report, settings.showFrom) : analyzed,
620
+ prNumber: pr,
621
+ sha: sha ? (task === 'pr_check' ? head : sha) : undefined,
622
+ showFrom: settings.showFrom,
623
+ scope: bugScope,
624
+ ...(bugRepoOf(watch, changeRepo) ? { repo: bugRepoOf(watch, changeRepo) } : {}),
625
+ altRepos: bugRepoAlts(watch, changeRepo),
626
+ addedFiles: diff.filter((f) => f.status === 'added').map((f) => f.path),
627
+ sharedBuild: planShared,
628
+ environment: environmentFactsFor(watch, diff.map((f) => f.path), run.id, ev ?? undefined),
629
+ });
630
+ const verdict = plan.verdict;
631
+ const qaPush = plan.qaPush;
632
+ const bugs = plan.findings;
633
+ setVerdict(run.id, verdict);
634
+ addStep(run.id, 'Verdict', verdict.headline, verdict.outcome === 'pass' ? 'ok' : verdict.outcome === 'product_failure' ? 'error' : 'warn');
635
+ const target = repoTarget(watch, ev);
636
+ const runUrl = publicRunUrl(run.id);
637
+ // A stale review gets no defects: the newer head's run drafts them.
638
+ // A test that failed on every attempt drafts an issue_create (KAT-87). The other bugs keep the file_defect path.
639
+ let defects = {};
640
+ // A finding without a concrete Expected is a question on the linked ticket, never a defect.
641
+ // A criterion of a linked ticket that no changed line touches is a question on that ticket too (KAT-388).
642
+ const notCovered = review?.criteriaNotCovered ?? [];
643
+ if ((plan.questions.length || notCovered.length) && !review?.staleFor)
644
+ await draftTicketQuestions(watch, run.id, ev, plan.questions, head, notCovered, task);
645
+ // Reproduced failures become defects. A risk nothing reproduced stays a risk to test, unless it cites a line and the input
646
+ // that breaks it: that one is drafted too, labelled "found by reading the code" (dogfood ledger).
647
+ if (plan.defectBugs.length && !review?.staleFor && verdict.outcome !== 'environment_failure') {
648
+ const issues = await draftIssueDefects({
649
+ watch,
650
+ runId: run.id,
651
+ ev,
652
+ verdict,
653
+ report,
654
+ bugs: plan.defectBugs,
655
+ head,
656
+ task,
657
+ ...(mergeCases?.cases.length ? { cases: mergeCases.cases } : {}),
658
+ });
659
+ const rest = plan.defectBugs.filter((b) => !issues.handled.has(b.key));
660
+ defects = {
661
+ ...issues.links,
662
+ ...(rest.length
663
+ ? await draftDefects(watch, run.id, rest, {
664
+ prNumber: pr,
665
+ head,
666
+ task,
667
+ runUrl,
668
+ ...links,
669
+ ...(report.testRepos?.length ? { testRepos: report.testRepos } : {}),
670
+ ...(mergeCases?.cases.length ? { cases: mergeCases.cases } : {}),
671
+ ...(c.gh.mode !== 'demo' && head ? { readFile: (p) => c.gh.readFile(p, head) } : {}),
672
+ })
673
+ : {}),
674
+ };
675
+ }
676
+ // Specs that a ticket of this PR says need an update, and the PR leaves alone (KAT-304).
677
+ const impactNotes = task === 'pr_check'
678
+ ? specNotesForPr(watch, ev, diff.map((f) => f.path))
679
+ : [];
680
+ if (impactNotes.length)
681
+ addStep(run.id, 'Specs not updated', `${impactNotes.length} spec${impactNotes.length === 1 ? '' : 's'} the ticket changes, not changed by this PR.`, 'info');
682
+ let reportRefused = [];
683
+ const testConclusion = checkConclusion(verdict);
684
+ const parts = sha && review
685
+ ? renderCheckRun(review, testConclusion, {
686
+ showFrom: settings.showFrom,
687
+ blockOn: settings.blockOn,
688
+ sharedBuild: planShared,
689
+ report,
690
+ task,
691
+ verdict,
692
+ bugs,
693
+ defects,
694
+ runUrl,
695
+ impactNotes,
696
+ ...links,
697
+ })
698
+ : null;
699
+ if (sha) {
700
+ if (parts?.blocked)
701
+ addStep(run.id, 'Check marked as failed', `A confirmed risk is at or above the block level (${settings.blockOn}).`, 'warn');
702
+ // Every number in the headline, the title and the text must match the one summary, or nothing is drafted.
703
+ const mismatch = parts ? reportConsistency(parts.counts, { headline: verdict.headline, checkTitle: parts.title, checks: [parts.summary] }) : [];
704
+ if (mismatch.length) {
705
+ reportRefused = mismatch;
706
+ addStep(run.id, 'Report not drafted: its counts disagree', mismatch.join(' '), 'error');
707
+ }
708
+ }
709
+ if (sha && !reportRefused.length) {
710
+ // Stops the progress updates and returns the id of the check run queued earlier, so the report completes that one.
711
+ const checkRef = await check.prepareFinal();
712
+ const written = await gate({
713
+ kind: 'check_run',
714
+ target: `${target}@${sha.slice(0, 7)}`,
715
+ title: parts?.title ?? verdict.headline,
716
+ body: parts?.summary ?? verdict.summary,
717
+ meta: {
718
+ sha,
719
+ // A post-merge check run belongs to the merge commit, not to the PR, so the PR state never expires it.
720
+ ...(pr && task === 'pr_check' ? { pr } : {}),
721
+ conclusion: parts?.conclusion ?? testConclusion,
722
+ outcome: verdict.outcome,
723
+ ...(parts ? { text: parts.text, annotations: parts.annotations } : {}),
724
+ ...checkRef,
725
+ evidence: reviewEvidence({ verdict, review, report }),
726
+ },
727
+ }, watch, run.id);
728
+ await check.finalWritten(written);
729
+ }
730
+ // post_merge with a review: no sticky comment (section 2.10). Without one, today's comment stays.
731
+ if (pr && (task === 'pr_check' || !review)) {
732
+ if (reportRefused.length) {
733
+ addStep(run.id, 'Skipped the PR comment', 'The report counts disagree, so no comment was drafted.', 'warn');
734
+ }
735
+ else if (review?.staleFor) {
736
+ addStep(run.id, 'Skipped the PR comment', `A newer head ${review.staleFor.slice(0, 12)} is under review; its comment replaces this one.`, 'info');
737
+ }
738
+ else {
739
+ const previous = review ? await c.gh.getStickyComment(pr).catch(() => null) : null;
740
+ const body = review
741
+ ? renderStickyComment({
742
+ verdict,
743
+ review,
744
+ previous,
745
+ ticked: manualTicks(watch.id, pr),
746
+ sharedBuild: planShared,
747
+ report,
748
+ runUrl,
749
+ showFrom: settings.showFrom,
750
+ blockOn: settings.blockOn,
751
+ task,
752
+ bugs,
753
+ defects,
754
+ impactNotes,
755
+ recheckByReply: recheckByReply(),
756
+ ...links,
757
+ })
758
+ : renderComment(verdict, run.id, undefined, task, { report, bugs, defects, impactNotes, ...(planShared ? { sharedBuild: true } : {}), ...links });
759
+ const counts = review ? renderQaSection(review, { report, showFrom: settings.showFrom, bugs, impactNotes }).summary : null;
760
+ const off = counts ? reportConsistency(counts, { headline: verdict.headline, comments: [body] }) : [];
761
+ // Every run, dogfood rounds included, scores the comment against the readability rubric (KAT-96).
762
+ const rubric = readabilityRubric(body);
763
+ addStep(run.id, 'Readability', `${Object.values(rubric.pass).filter(Boolean).length} of ${Object.keys(rubric.pass).length} checks pass${rubric.notes.length ? `: ${rubric.notes.join('; ')}` : ''}`, rubric.score === 1 ? 'ok' : 'info');
764
+ if (off.length)
765
+ addStep(run.id, 'Report not drafted: its counts disagree', off.join(' '), 'error');
766
+ else
767
+ await gate({
768
+ kind: 'pr_comment',
769
+ target: `${target}#${pr}`,
770
+ title: `QA report for PR #${pr}`,
771
+ body,
772
+ meta: {
773
+ pr,
774
+ sticky: true,
775
+ // The QA report summary comment: long by design, so no length limit applies (rules.ts lengthLimit).
776
+ reportSummary: true,
777
+ ...(review ? { head: review.head } : {}),
778
+ ...(task === 'post_merge' ? { afterMerge: true } : {}),
779
+ evidence: reviewEvidence({ verdict, review, report }),
780
+ },
781
+ }, watch, run.id);
782
+ }
783
+ }
784
+ // Kept passing specs go to the repo as a proposed PR, behind the open_pr rule. On a pull
785
+ // request it targets the PR branch, so the specs land with the change they test.
786
+ if (pw?.generated?.length && pwOpts?.proposePr !== false && watch.repo && !ev.pr?.fork) {
787
+ const repo = ev.repo ?? watch.repo;
788
+ // A merge on a test branch of the dot (KAT-292) proposes the specs against that branch, else the default branch.
789
+ const mergedInto = ev.pr?.baseRef || ev.push?.ref.replace(/^refs\/heads\//, '');
790
+ const mergeBase = mergedInto && (watch.testBranches ?? []).includes(mergedInto) ? mergedInto : watch.repo.defaultBranch;
791
+ const base = task === 'pr_check' ? ev.pr?.headRef : mergeBase;
792
+ const action = base
793
+ ? proposalAction({ generated: pw.generated, repo, base, runId: run.id, runUrl: publicRunUrl(run.id), e2ePaths, ...(pr ? { prNumber: pr } : {}) })
794
+ : null;
795
+ if (action)
796
+ await gate(action, watch, run.id);
797
+ }
798
+ if (verdict.outcome === 'product_failure') {
799
+ await gate(pushAction(verdict.headline, verdict.suspectedCause ?? 'Open the run for details.', 'high', `${task}:${watch.id}:${sha ?? run.id}`), watch, run.id);
800
+ }
801
+ else if (qaPush) {
802
+ const action = pushAction(qaPush.headline, qaPush.body, qaPush.urgency, qaPush.key);
803
+ await gate({ ...action, meta: { ...action.meta, url: qaPush.url, reason: qaPush.reason } }, watch, run.id);
804
+ }
805
+ await refreshStatus(watch, ev, run.id);
806
+ finishRun(run.id, 'done');
807
+ // Self-health: the same totals on three different commits mean the reports may be stale (dogfood ledger).
808
+ noteTestTotals(watch.id);
809
+ });
810
+ }
811
+ //# sourceMappingURL=change.js.map