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,553 @@
1
+ # Lead QA dot (KAT-405)
2
+
3
+ Built in 0.15.0. This page is the build spec; [API-V2.md](API-V2.md#lead-qa-dot-kat-405) lists the fields and routes, and [SETUP.md](SETUP.md#lead-qa-dot) says how to make a lead.
4
+
5
+ The Lead QA dot is a dot with no repos, tracker or site checks of its own. It names member dots and gives the QA team one place for team health, a daily team digest, questions about every member, shared test cases, one bug report per bug, and a release call. Everything it shows is built by code from rows the members already store. The model only words chat answers. The lead files and comments nothing. Its only outward post is the scheduled daily digest to its Slack channel, which is code text like every member's digest. Bug reports, ticket comments and PR comments still go through a member's Inbox.
6
+
7
+ The build is four pieces in three waves. Piece 1 (the lead dot and team health) comes first. Pieces 2 (team data and the release call) and 4 (one bug, one draft) can then run in parallel. Piece 3 (ask the lead and the daily digest) needs piece 2.
8
+
9
+ ## Decision context
10
+
11
+ On 2026-10-22 Huy chose one dot per job for the QA team. The four dots already run on the live server:
12
+
13
+ | Dot | Jobs on (stages) | Scope |
14
+ |---|---|---|
15
+ | Ticket Reviewer | analyst, designer | tracker katalon-studio/product, label pod:agentic |
16
+ | PR Reviewer | reviewer | the 4 pod app repos |
17
+ | Regression Runner | regression | Tests repo duonghaijoe/true-dogfood-tests, deploy wait |
18
+ | Site Watcher | watcher | site check on the QA tenant |
19
+
20
+ docs/STAGES.md section 1.1 records the older choice of one dot per product area with stages. It rejected one dot per role because the ticket, its cases, the PR and the results crossed dots. The lead dot answers that objection: the context crosses dots through the lead's member list. Piece 1 updates section 1.1 with the 2026-10-22 decision and a link to this spec.
21
+
22
+ Facts read at origin/main that shape the design:
23
+
24
+ - Cases are per dot. `casesForTicket(dotId, ref)` in src/flows/testDesign.ts filters `test_cases` by one `dotId`, and so does `linkRunResults` in src/test-runs.ts. Ticket Reviewer designs the cases, so today PR Reviewer (`designedCasesFor` in src/runner/aivision/index.ts) and Regression Runner (`activeCasesOf` in src/flows/mergeCases.ts) never find them or write their results.
25
+ - Links and traceability are per dot. `linksOfWatch(w.id)`, `loadEvidence(w)` and `ticketCatalog(w)` read one watch id. Ticket rows come from Ticket Reviewer's `ticket_review` runs. PR to ticket links and test results come from PR Reviewer and Regression Runner.
26
+ - Ticket refs are per dot. `mentionInScope` in src/review/linked-tickets.ts keeps a GitHub issue ref only when its repo is the dot's tracker repo or one of its own repos. PR Reviewer has no tracker, so `linkedRefs` drops every katalon-studio/product ticket.
27
+ - Bug targets are per dot. `defectTarget` in src/flows/defects.ts files into the dot's tracker, and with no tracker into the repo the bug was found in. PR Reviewer and Regression Runner have no tracker.
28
+ - The defect guard is per dot. `pendingApprovals`, `pendingBySig` and `rejectedFor` in src/flows/defectDraft.ts, and `supersedeOlder` in src/agent/approvals.ts, filter by one `watchId`. Two members that find one bug make two Inbox items.
29
+ - A dot with no repo, tracker or probe matches no event in `watchMatches` (src/webhooks.ts), and its health reads "Not watching: nothing set up" (`notWatchingReason` in src/dot-health.ts). A lead needs its own health branch.
30
+ - The digest scheduler in src/index.ts enqueues a `digest` job per dot at `digestHour`. The lead reuses that job kind, so `JobKind` and its exhaustive maps do not grow.
31
+ - `pickDot` in src/slack/index.ts returns the first dot in table order whose `slackChannel` matches, after the name and thread checks.
32
+ - docs/STAGES.md plans a Release guard (`release_check`, task 12) that writes readiness per milestone and "never says release or hold".
33
+
34
+ ## What the tester sees
35
+
36
+ Words follow the word map in the word map of the simplicity work (a manual tester is the reader). A member is named by its name. Its job reads as Ticket review, Test cases, PR check, After merge, Site check, or Release check, never as a stage key, and every view uses the same job words. The dot's instructions read as Goal. The team message is the daily digest, the word the app already uses. Status words are Failing, Needs you, Healthy and Not watching, with the dot health icons. In the wireframes `[x]` is the cross, `[!]` the warning, `[v]` the check and `[-]` the clock.
37
+
38
+ Every line in the wireframes is the text the rules below produce. A row's need is the member's own `statusReason`, so it reads the same as on the member's page.
39
+
40
+ ### Lead page, desktop
41
+
42
+ The page replaces the dot health panel for a lead. The member table uses rows with dividers and a status icon per row, with no accent stripes. The Release call section sits below it.
43
+
44
+ ```
45
+ +------------------------------------------------------------------------------------------+
46
+ | Lead QA [Digest now] [Ask] [Settings] |
47
+ | Team of 4 dots. Daily digest at 09:00 in chat and #qa-agentic. |
48
+ +------------------------------------------------------------------------------------------+
49
+ | Team health: [x] Failing |
50
+ | Regression Runner: the last merge found a bug. |
51
+ | |
52
+ | Dot Job Status Needs a person |
53
+ | -------------------------------------------------------------------------------------- |
54
+ | [x] Regression Runner After merge Failing The last merge found a |
55
+ | bug. [Open] |
56
+ | [!] PR Reviewer PR check Needs you 2 items to review. [Open] |
57
+ | [!] Ticket Reviewer Ticket review, Test cases Needs you 1 ticket with |
58
+ | questions. [Open] |
59
+ | [v] Site Watcher Site check Healthy Nothing needs you. [Open] |
60
+ | |
61
+ | 3 items wait in the Inbox across the team. [Open the Inbox] |
62
+ +------------------------------------------------------------------------------------------+
63
+ | Release call Milestone [ 2026.11 v ] |
64
+ | [x] Not ready. 14 of 19 requirements passing, 1 failing, 3 not tested, 1 partly tested |
65
+ | [x] #4301 Export results to CSV: the after-merge test "exports all rows" fails. [Open] |
66
+ | [x] Bug #4318 is open against #4307 Bulk edit. [Open] |
67
+ | [!] 3 requirements have no test result yet: #4302, #4305, #4311. [Open] |
68
+ | [!] 1 bug report for #4309 waits in the Inbox of PR Reviewer. [Open] |
69
+ | > Details [See every ticket] |
70
+ +------------------------------------------------------------------------------------------+
71
+ ```
72
+
73
+ - Team health word: the rule in job 1. The line under it names the member that set it, with the member's reason after the colon.
74
+ - Row: member name, its job, its status word, the one thing that needs a person, and Open (the member's page, or the button the member's health answer gives). Long text wraps with no ellipsis.
75
+ - Digest now: makes the team digest now and shows it in this chat only (job 2). Ask: opens the lead chat (job 3).
76
+ - A paused or archived member shows its row with "Paused" or "Archived" in the Needs a person column and does not count toward the team word.
77
+ - Details under the release call: counts per status, the member each reason came from, and the rule that set the answer.
78
+
79
+ ### Lead page, phone
80
+
81
+ ```
82
+ +--------------------------------------+
83
+ | < Dots Lead QA |
84
+ +--------------------------------------+
85
+ | [x] Failing |
86
+ | Regression Runner: the last merge |
87
+ | found a bug. |
88
+ | [Digest now] [Ask] |
89
+ +--------------------------------------+
90
+ | [x] Regression Runner > |
91
+ | After merge . The last merge |
92
+ | found a bug. |
93
+ | [!] PR Reviewer > |
94
+ | PR check . 2 items to review. |
95
+ | [!] Ticket Reviewer > |
96
+ | Ticket review, Test cases . |
97
+ | 1 ticket with questions. |
98
+ | [v] Site Watcher > |
99
+ | Site check . Nothing needs you. |
100
+ +--------------------------------------+
101
+ | Release 2026.11 [Change] |
102
+ | [x] Not ready |
103
+ | 14 of 19 requirements passing, |
104
+ | 1 failing, 3 not tested, 1 partly |
105
+ | tested |
106
+ | - #4301 fails after merge |
107
+ | - Bug #4318 open on #4307 |
108
+ | - 3 requirements not tested yet |
109
+ | [See the reasons] |
110
+ +--------------------------------------+
111
+ ```
112
+
113
+ A row tap opens the member page. The phone shows three release reasons at most and links to the full list.
114
+
115
+ ### Daily team digest
116
+
117
+ One message, posted to the lead's web chat and to the lead's Slack channel when `slackChannel` is set. The same text is saved as a digest report page. Every line, the second line included, comes from code.
118
+
119
+ ```
120
+ +----------------------------------------------------------------------------------+
121
+ | Lead QA . daily digest . Thu 23 Oct |
122
+ | 2 things broke and 3 wait for a person. Release 2026.11 is not ready. |
123
+ | |
124
+ | What broke |
125
+ | - PR #412 Bulk edit: after merge, the test "exports all rows" fails. |
126
+ | A bug report waits. PR author: @dev-an. (Regression Runner) [Review] |
127
+ | - The QA site was down 12 min at 09:40 and is back up. (Site Watcher) |
128
+ | |
129
+ | Waits for a person |
130
+ | - 2 bug reports in the Inbox of PR Reviewer: PR #412, PR #415. [Open Inbox] |
131
+ | - 4 test cases to test by hand after PR #409, assigned to @qa-sam. [Open] |
132
+ | - #4310 has 2 open questions for its author, @pm-lee. (Ticket Reviewer) |
133
+ | |
134
+ | Not tested |
135
+ | - 3 requirements of 2026.11 have no test result: #4302, #4305, #4311. [See them]|
136
+ | |
137
+ | Release 2026.11: Not ready |
138
+ | - #4301 Export results to CSV fails after merge. |
139
+ | - Bug #4318 is open against #4307. [Open the release call] |
140
+ | |
141
+ | > Details |
142
+ +----------------------------------------------------------------------------------+
143
+ ```
144
+
145
+ - The second line is a code template: "N things broke and M wait for a person." plus "Release <milestone> is <answer>." when a milestone is open.
146
+ - "Who" is the person a line can name from stored data: the PR author (`TriggerEvent.pr.author`), the ticket author, or the assignee of a manual test run item (`RunItem.assignee`). With no name the line says which member's Inbox holds it.
147
+ - Details holds each member's own tester digest text and the counts.
148
+
149
+ ### Release call in chat
150
+
151
+ The answer is built by code with no model call. In Slack it is the same text with buttons as links. It uses readiness words only (Ready, Ready with risk, Not ready), so the STAGES.md rule "never says release or hold" still holds.
152
+
153
+ ```
154
+ +--------------------------------------------------------------------------+
155
+ | You: Can we release 2026.11? |
156
+ | |
157
+ | Lead QA: Not ready. 14 of 19 requirements passing, 1 failing, |
158
+ | 3 not tested, 1 partly tested. 2 things block it. |
159
+ | |
160
+ | [x] Not ready Milestone 2026.11 |
161
+ | Why |
162
+ | [x] #4301 Export results to CSV fails after merge. [Open] |
163
+ | [x] Bug #4318 is open against #4307 Bulk edit. [Open] |
164
+ | Also |
165
+ | [!] 3 requirements have no test result yet. [See them] |
166
+ | [!] 1 bug report for #4309 waits in the Inbox. [Review] |
167
+ | |
168
+ | > Details: counts per status, the checks each reason comes from |
169
+ +--------------------------------------------------------------------------+
170
+ ```
171
+
172
+ ### Merged bug report in the Inbox
173
+
174
+ ```
175
+ +--------------------------------------------------------------------------+
176
+ | Inbox 3 waiting |
177
+ +--------------------------------------------------------------------------+
178
+ | File this bug? |
179
+ | Bulk edit drops the last row when you export to CSV |
180
+ | |
181
+ | Found by PR Reviewer (PR #412, 10:02) and Regression Runner (after |
182
+ | merge of PR #412, 11:47). One bug report: it is filed once. |
183
+ | Goes to: katalon-studio/product. Linked to #4307. |
184
+ | |
185
+ | Expected: 25 rows in the file. Actual: 24 rows. |
186
+ | |
187
+ | [File the bug] [Edit] [Don't file] |
188
+ | > Details: both checks, both test logs, signature 3f9a1c2e7b04 |
189
+ +--------------------------------------------------------------------------+
190
+ ```
191
+
192
+ The Inbox shows the item once, under the member that drafted first. The second member's check says "Same bug as the report PR Reviewer drafted. Added to it." with a link. "Goes to" is the team tracker (job 5).
193
+
194
+ ### Wireframe check (0.16.0)
195
+
196
+ 0.15.0 shipped the lead without laying its screens next to the wireframes above. The 0.16.0 check (KAT-405, screenshots at 1280x800 and 390x844 in light and dark) found these gaps and fixed them:
197
+
198
+ - The headings of the member table (Dot, Job, Status, Needs a person) sat off their columns, because the last column was `auto` in the rows and empty in the heading. Both now share one column template.
199
+ - The title row had six buttons. It now has the three of the wireframe (Digest now, Ask, Settings) at the right of the title; Pause and Remove dot sit in a row at the foot of the page, and Edit goal is Settings.
200
+ - A phone showed the avatar, the name and six buttons before the status. It now starts with the status word and its reason, then the three buttons, then the members. The top bar names the dot, so the page keeps its heading for a screen reader only.
201
+ - The Release call title and the milestone picker are one row with the label beside the picker. The answer reads "Not ready." with a full stop, as in the wireframe. On a phone a reason is one tap row with a chevron, three show, and the button says See the reasons and opens the rest in place (the trace page lists tickets, not a bug report that waits in an Inbox); once they all show, the button is See every ticket. Save as a report page moved under Details.
202
+ - A chat answer cut its blockers to three in a card narrower than 560 px, while its first line said "4 things block it". The chat block never cuts a reason, and Open stays on the line of its reason down to 480 px.
203
+ - A team that passes every requirement read "No tickets. No milestone is open." It now answers Ready for its newest milestone. The digest still asks for the open milestone only.
204
+ - The header of the lead's chat read "All good" for a failing team. It takes the word of the team.
205
+ - The member digests under Details of the digest page ran together ("Ticket ReviewerNothing needs you."). Each member is a paragraph of its own, and the chat message has the Details fold of the wireframe (`update.details`).
206
+ - The Open button of a team row followed the wireframe only in part: it now goes to the link the member's own health answer gives. The name of the member, and on a phone the whole row, open the member page ("A row tap opens the member page").
207
+ - A bug report in the Inbox asks "File this bug?" above its title and names the tickets it is linked to next to where it files ("Files in katalon-studio/product. Linked to #4307."). A release answer in the chat says See them on a group of tickets and Review on a bug report that waits in an Inbox, as the chat wireframe does.
208
+
209
+ The second pass of the check (the same screenshots after the fixes, read by a reviewer) found these and fixed them:
210
+
211
+ - A healthy member read "#4301 is in the release and has no test cases yet" under a team that read Ready. A member judged a ticket from its own rows only, and the check that tests the ticket belongs to PR Reviewer. A member of a lead now reads the tests, PRs and bugs of its whole team for its own tickets, and the cases of the whole team, so the member page, the team row and the release call agree (`withTeamEvidence` in src/dot-health.ts). A member's kept health answer drops when any teammate's drops.
212
+ - The Team health table in the lead's chat ran past its card and, on a phone, showed only Dot and Job. A chat table of up to four text columns now wraps its text and fits the card, and under 520 px each row stacks its Job, Status and Needs a person under the name.
213
+ - A team that is Not watching still showed a green Ready and a main Digest now button. The release call now says the answer is from the last results, reads in a muted colour, and Digest now is a plain button.
214
+ - The card beside the lead's chat said "Nothing to review" while the team held items in its Inboxes. It counts the Inboxes of the members, as the team panel does.
215
+ - The digest page said "risk low, confidence 100%" above "3 things broke". The risk now follows the facts (`riskOf` in src/lead-digest.ts) and a digest shows no confidence figure.
216
+ - Details of the digest has a heading, a heading per member, and the groups (Needs you, For your info) in italics; "Open the release call" stands on its own line; a comment on a GitHub ticket reads "issue #4301", not "PR #4301".
217
+ - The release answer in the chat started with "Lead QA:" under a header that names Lead QA. Only a Slack answer names the dot.
218
+ - The Inbox named a bug report group "github:acme/product", and a linked ticket of another repo as a bare "#4301". It names the repo, and keeps the repo of a ticket that is not in the repo the bug files in. On a phone the main button of a card has a row of its own and the others share the next.
219
+ - On a phone the buttons of the lead page showed only after the team loaded, and the report page of a digest wrapped its bar into four rows and cut its title in the top bar after one line. The buttons show from the first frame, the bar is two rows, and the top bar title wraps to a second line before it is cut.
220
+
221
+ Where a wireframe differs from the words the app already uses, the words of the app win: the Inbox card says "Files in" where the wireframe says "Goes to", and its buttons say "File in <place>" and "Don't file" where the wireframe says "File the bug". The release reason on the page reads "#4301 Export results to CSV fails after merge." as in the chat and digest wireframes; only the page wireframe adds the test title.
222
+
223
+ ## Data model
224
+
225
+ ### Fields on Watch (src/types.ts)
226
+
227
+ ```ts
228
+ export type DotKind = 'dot' | 'lead';
229
+
230
+ export interface Watch {
231
+ // existing fields unchanged
232
+ /**
233
+ * 'lead': a Lead QA dot (KAT-405). It holds no repos, tracker, site checks or runner and reads its members' rows.
234
+ * Unset: 'dot'. Set by POST /api/dots only; a PATCH that changes it is refused.
235
+ */
236
+ kind?: DotKind;
237
+ /** The member dots of a lead, in the order the team panel lists them. Only on a lead. 1 to 8 ids. */
238
+ memberIds?: string[];
239
+ }
240
+ ```
241
+
242
+ `kind` (text) and `memberIds` (json) join `SCHEMA.watches` in src/db-schema.ts, and `db.ts` adds the columns at boot with its existing `ALTER TABLE ... ADD COLUMN` loop. Both join `WATCH_FIELDS` in src/api.ts.
243
+
244
+ ### New types
245
+
246
+ ```ts
247
+ export interface TeamMemberHealth {
248
+ id: string;
249
+ name: string;
250
+ /** "PR check", "Ticket review, Test cases": the job words of the stages that are on. */
251
+ job: string;
252
+ status: HealthStatus;
253
+ /** Set when a person paused or archived the member. Such a member does not count toward the team word. */
254
+ away?: 'paused' | 'archived';
255
+ /** The one thing that needs a person, or "Nothing needs you." */
256
+ need: string;
257
+ /** The button for `need`, from the member's health answer; null when nothing needs a person. */
258
+ action: HealthAction | null;
259
+ }
260
+
261
+ export interface TeamHealth {
262
+ status: HealthStatus;
263
+ /** "Regression Runner: the last merge found a bug." */
264
+ statusReason: string;
265
+ members: TeamMemberHealth[];
266
+ /** Live Inbox items across the members. */
267
+ inbox: number;
268
+ builtAt: string;
269
+ }
270
+
271
+ export type ReleaseAnswer = 'ready' | 'ready_with_risk' | 'not_ready' | 'no_tickets';
272
+
273
+ export interface ReleaseReason {
274
+ level: 'blocker' | 'risk';
275
+ text: string;
276
+ /** Ticket, bug or PR the reason names. */
277
+ ref?: string;
278
+ href?: string;
279
+ /** The member whose data gave the reason. */
280
+ memberId: string;
281
+ }
282
+
283
+ export interface ReleaseCall {
284
+ milestone: string;
285
+ answer: ReleaseAnswer;
286
+ /** "14 of 19 requirements passing, 1 failing, 3 not tested" (readinessSummary, unchanged). */
287
+ summary: string;
288
+ counts: ReadinessCounts;
289
+ reasons: ReleaseReason[];
290
+ /** Every milestone of the members' trackers, for the picker. */
291
+ milestones: string[];
292
+ builtAt: string;
293
+ }
294
+ ```
295
+
296
+ `DotHealth` gains `team?: TeamHealth`. For a lead, `healthOf` returns the team status, team reason and the lead's own pause or archive state, with `team` set, `suggestion` null and the eight tiles as `not_set_up`. The client draws the team panel whenever `team` is set, so the dot list and the sidebar read one status word for every dot.
297
+
298
+ ### Validation
299
+
300
+ POST /api/dots and PATCH /api/dots/:id run one new check, `leadError(fields, w?)`, in the chain that already holds `stagesError` and `modelCapError`.
301
+
302
+ | Rule | Error |
303
+ |---|---|
304
+ | `kind` is `dot` or `lead`, and only POST sets it | 400 `kind must be dot or lead.` / 400 `A dot cannot change kind. Make a new lead.` |
305
+ | A lead has 1 to 8 `memberIds`, each a known dot, no repeats | 400 `A lead names 1 to 8 dots.` / 400 `No dot with id <id>.` |
306
+ | A lead cannot be a member, and a lead cannot name itself | 400 `<name> is a lead. A lead cannot be a member of another lead.` |
307
+ | A member has at most one lead | 409 `<name> is already in <lead name>. Remove it there first.` |
308
+ | An archived dot cannot be added | 400 `<name> is archived. Restore it first.` |
309
+ | A lead holds no `repo`, `repos`, `tracker`, `probes`, `statusPages`, `baseUrl`, runner command, `review` or `stages` | 400 `A lead has no repos, tracker or site checks of its own. Set them on a member.` |
310
+ | `memberIds` on a dot of kind `dot` | 400 `Only a lead has members.` |
311
+
312
+ The at-most-one-lead check scans live and archived leads, so restoring a lead never gives a member two leads. A save of `memberIds` publishes a `dot` event for the lead and for every member added or removed, which drops their kept health answers and the lead index (below).
313
+
314
+ `memberIds` follows the editor rules of other non-runner fields: an admin or an editor may change it, a member may not.
315
+
316
+ ### Lead index (src/lead.ts, new)
317
+
318
+ - `leadOf(dotId): Watch | undefined`: the lead whose `memberIds` holds the dot. A map kept in memory, rebuilt on a `dot` event and at boot.
319
+ - `teamIds(dotId): string[]`: the lead's `memberIds` when the dot has a lead, else `[dotId]`. Shared case lookup, ticket scope, the bug target and the defect merge use it.
320
+ - `membersOf(lead): Watch[]`: live member rows in `memberIds` order. Ids of deleted dots drop out.
321
+ - `teamTracker(dotId): Watch | undefined`: the first member in `memberIds` order that has a tracker. Undefined for a dot with no lead.
322
+ - `isLead(w)`: `w.kind === 'lead'`.
323
+
324
+ ### Removing members and leads
325
+
326
+ - `deleteDot` in src/dot-remove.ts removes the deleted dot's id from its lead's `memberIds`.
327
+ - Deleting the only member of a lead is refused with 409 `<name> is the only dot of <lead name>. Add another dot to the lead, or delete the lead first.` A lead therefore always keeps 1 to 8 `memberIds`.
328
+ - Deleting a member that owns test cases also deletes the `run_items` of the other team members whose `caseId` is one of its cases, and recounts those test runs (piece 2). The delete summary counts these items, so the confirm dialog says "Also removes 6 test run items of Regression Runner."
329
+ - Archiving a member keeps its id, and the row reads Archived. Archiving hands its pending merged bug drafts to the next source (job 5).
330
+ - Deleting or archiving a lead changes no member.
331
+
332
+ ### Lead-only guards
333
+
334
+ Routes that need a repo, tracker, site or runner answer 409 `<lead name> is a lead. Ask a member for this.` for a lead: POST /api/dots/:id/site-check, PUT and POST /api/dots/:id/review, GET /api/dots/:id/pulls, POST /api/dots/:id/cases (a lead owns no cases), and POST /api/runner/try with a lead's `dotId`. The dot dialog for a lead shows name, members, digest hour, Slack channel, daily model cap, and the Goal (mission, tell me when, never). It hides repos, tracker, site checks, runner, jobs and rules.
335
+
336
+ ## Jobs
337
+
338
+ ### 1. Team health
339
+
340
+ Reuses: `healthFor(w)` in src/routes/health.ts (30 s cache per dot, dropped on run, approval and dot events), `STATUS_WORD` and `STATUS_ICON` in client/src/features/health/healthModel.ts, `HealthWord`, `useRereadEvery`, the stage registry in src/stages/index.ts for job words, and `liveCount` in src/agent/approvals.ts for the Inbox count.
341
+
342
+ New code:
343
+
344
+ - `teamHealth(lead, now)` in src/lead.ts. Pure over the members' `DotHealth` answers and a fixed clock, so each rule has a unit test.
345
+ - Team word rule. The team takes the worst word in this order: Failing, then Needs you, then Not watching, then Healthy. It reads only members with no `away`. The order differs from the single-dot order on purpose: a member that is Not watching for a reason such as an expired AI sign-in, a GitHub limit, or site checks off never hides a Failing or Needs you member. When every member is away, the team is Not watching with "Every dot of the team is paused or archived." With no live member left (a deleted dot that the index has not dropped yet), the team is Not watching with "The team has no dots. Add one in the lead settings."
346
+ - Team reason: `<member name>: <member statusReason>`, with the first letter of the reason lowered, for the first member in `memberIds` order that has the team word. With more than one, "(and N more)" follows. Healthy reads "Nothing needs you."
347
+ - Row `need`: the member's `statusReason` when its word is not Healthy, else its `suggestion.text`, else "Nothing needs you." Row `action`: `statusFix`, else the suggestion's action, else null. The name of the member and a phone row go to `#/dots/<id>`; the Open button goes to the action's link (an app route or a tracker address) when it has one, else to `#/dots/<id>`. A member reads the tests of its team for its own tickets, so a suggestion such as "no test cases yet" never contradicts the release call.
348
+ - `healthOf(lead)` returns the team branch above. GET /api/dots/health includes leads, so the dot list shows the team word with no extra request.
349
+ - The lead's kept answer drops when any member's answer drops: the `subscribe` hook in src/routes/health.ts also deletes `leadOf(watchId)` and every member of that lead from the cache, since a member reads the tests of its team.
350
+ - Dots page header: the "need you", setup-fix and waiting counts in client/src/pages/Dots.tsx skip leads (`d.kind !== 'lead'`). A lead row repeats its members' words, so counting it would show one broken merge as "2 need you".
351
+ - Client: `TeamPanel.tsx` in client/src/features/health, rendered by client/src/pages/DotDetail.tsx when `health.team` is set. It reuses `health.css` row styles and the words of `healthModel.ts`. In the dot list a lead row shows "Team of 4" as its scope line (`scopeSummary` gains a lead branch).
352
+
353
+ ### 2. Daily team digest
354
+
355
+ Reuses: the scheduler in src/index.ts (`digestDue`, `enqueue({ kind: 'digest' })`, the `digest:<id>:<day>` dedupe key), `testerDigest(area, runs, approvals)` in src/updates/words.ts per member, `mergedWithBugsLines` and `ticketsWithoutCriteriaLines` in src/flows/digest.ts, `saveDigestReport`, the update router in src/updates (chat message, Slack channel or DM, phone push), `redactCode` and `renderVerdictRefs`.
356
+
357
+ New code:
358
+
359
+ - The `digest` handler in src/flows/digest.ts branches first: `if (isLead(watch)) return runTeamDigest(job, watch)`. Member digests do not change.
360
+ - `teamDigestFacts(lead, now)` in src/lead-digest.ts builds the sections from member rows, with no model:
361
+ - What broke: each member's `testerDigest` need lines for bugs and outages in the window, tagged with the member name and the PR author when known.
362
+ - Waits for a person: live Inbox items per member (count, refs), manual test run items in state `untested` or `retest` and their `assignee`, and ticket reviews with open questions (ticket author when the review stored one).
363
+ - Not tested: team trace rows (job 6) of the nearest open milestone (`nearestOpenMilestone`) with status Not tested, Partly tested or Out of date, up to 6 keys and a link to the rest.
364
+ - Release: the release call (job 6) for that milestone, its answer and two reasons at most.
365
+ - The opener is the code template under the digest wireframe. The digest makes no model call, so its text is templated like every member digest and the update router posts it at the same level.
366
+ - Scheduled delivery: one update of kind `daily_digest` through the update router, which posts to the lead's chat and to the lead's Slack target (`slackChannel` or `updates.slack`). Clearing both stops the Slack post. The `digest:<id>:<day>` job key sends it once per day.
367
+ - On demand: POST /api/dots/:id/digest enqueues the same job with an `AskOrigin` of the person who asked and the dedupe key `digest-now:<leadId>:<10-minute slot>`, so a double click makes one digest. `ruleLevel` in src/updates/route.ts gains one rule above the digest rule: a `daily_digest` that carries an `origin` takes the `thread` level. An on-demand digest therefore replies only in the chat or Slack thread where it was asked. It never posts to the lead's channel and never pushes to phones.
368
+ - The digest run is a `digest` run of the lead, so the Activity feed, the report page and `lastDigestAt` work unchanged.
369
+
370
+ ### 3. Ask the lead
371
+
372
+ Reuses: `runChat`, `CHAT_TOOLS`, `dispatchChatTool`, `resolveWatch`, `plannedFirstTool` and `summarizeToolResult` in src/agent/chat.ts; `requestReview` for PRs and commits; the ticket review and design request paths; `recordAsk` and the update router; `pickDot` and `handleMention` in src/slack/index.ts.
373
+
374
+ New code:
375
+
376
+ - Chat context: `ChatToolContext` gains `team?: Watch[]`. `runChat` sets it when the chat's dot is a lead.
377
+ - Read tools for all members. In a lead chat, these tools take `dotId` as a member id or `all`, and `all` is the default: `list_runs`, `get_run`, `list_tickets_reviewed`, `pending_approvals`, `open_prs`, `runs_in_progress`, `recent_defects`, `list_cases`, `pass_rate`, `test_results`, `flaky_by_spec`, `probe_status`, `get_memory`. A wrapper `forTeam(name, input, ctx)` runs the tool once per member, adds `dot: <member name>` to each row, merges newest first, and keeps the existing row limit per call. A `dotId` outside the team returns "That dot is not in <lead name>."
378
+ - External calls in `forTeam`. Every tool above reads the database only, except `open_prs`, which calls GitHub `listPulls` once per repo. In a lead chat `open_prs` collects the repos of all members, drops repeats, and calls at most 12 per tool call. Past 12 the result says "Skipped N repos. Ask about one dot to see them."
379
+ - `get_ticket` does not fan out. In a lead chat it goes to the one member whose tracker holds the ticket (`teamTracker`), so it makes one tracker call.
380
+ - Two new read tools, in the lead chat only. `team_status` returns `TeamHealth`. `release_call { milestone? }` returns `ReleaseCall`, and the chat shows it as a `release_call` block (new kind in src/chat-blocks.ts and the client block renderer).
381
+ - Routing of action requests. In a lead chat, `rerun_tests`, `review_pr`, `review_ticket` and `design_tests` go through `routeToMember(tool, input, lead)`:
382
+
383
+ | Request | Member picked |
384
+ |---|---|
385
+ | `review_pr` on an open PR | the member with the PR check job whose repos hold the PR's repo |
386
+ | `review_pr` on a merged PR, a commit or a range | the member with the After merge job for that repo; with none, the PR check member |
387
+ | `review_ticket` | the member with the Ticket review job whose tracker holds the ticket |
388
+ | `design_tests` | the member with the Test cases job for that ticket |
389
+ | `rerun_tests` | the member with the After merge job, else the PR check member |
390
+
391
+ A PR number with no repo is matched to the newest member run that names that number. When two repos or two members fit, the tool returns the choices and the model asks which. When no member fits: "No dot in <lead name> does PR checks. Add one in the lead settings."
392
+ - The tool result carries `routedTo` and `ask`. `summarizeToolResult` prints "Asked PR Reviewer to check PR #12 again", and the chat shows that line. The member's own rules, cap and dedupe apply to the job, unchanged.
393
+ - Results come back to the lead chat. `AskOrigin` (web) gains `scope: 'lead'` and `leadId`. `toChat` in src/updates/index.ts writes such an update into the lead's chat with "From PR Reviewer" in front, the same way `scope: 'all'` works today.
394
+ - Slack. `pickDot` keeps its order: a named dot first, then the remembered thread. For the channel match it prefers a lead: when several live dots share the channel, the lead among them wins, else the first in table order as today. A mention of "Lead QA" or an unnamed message in the lead's channel reaches the lead even when a member uses the same channel. A message that names a member still reaches that member. The routed result replies in the same thread through the existing Slack origin.
395
+ - Rule-based paths stay first. `pickChatView` gains a release question rule ("release", "ship" or "go live" with a known milestone title or "next release"), answered by `release_call` with no model call. `plannedFirstTool` routes review requests through `routeToMember`.
396
+ - The lead's `dailyModelCap` counts the lead chat's model calls. Routed jobs count toward the member's cap, as today.
397
+
398
+ ### 4. Shared test cases
399
+
400
+ Reuses: `casesForTicket`, `designedCasesFor`, `activeCasesOf`, `caseForTest`, `linkRunResults`, `caseDetail`, `linkedRefs`.
401
+
402
+ New code:
403
+
404
+ - `casesForTicket(dotIds: string | string[], ref)` runs `WHERE dotId IN (...)`. Callers that look up cases for a check pass `teamIds(watch.id)`: `designedCasesFor` (PR check AI-Vision cases), `activeCasesOf` (after-merge cases), and the lookups in src/agent/chat.ts. `designTestCases` writes new cases under its own dot id and checks for existing ones over `teamIds`, so Ticket Reviewer never writes a second copy of a case the team already has. Within the team, the first case per key wins.
405
+ - `linkRunResults` loads cases over `teamIds(run.watchId)`, with the run's own dot's cases first, so a key that two members use maps to the run's own case. Results of automated and AI-Vision tests that map to a team case are written on that case.
406
+ - Ticket scope. `mentionInScope` in src/review/linked-tickets.ts also accepts a ref whose repo is a tracker repo of any dot in `teamIds(watch.id)`. `linkedRefs` applies it to mentions and stored "closes" links alike, so PR Reviewer keeps katalon-studio/product tickets.
407
+ - PR Reviewer: a PR that closes or names a ticket of the team (`linkedRefs`) gets Ticket Reviewer's designed cases as AI-Vision cases, and the PR report lists them as "Test cases from Ticket Reviewer".
408
+ - Regression Runner: a merge that closes or names the ticket adds Ticket Reviewer's manual cases to its "After merge" test run (`mergeRun`). Automated cases with a spec get their results through `linkRunResults`.
409
+ - A run item keeps the dot id of its test run and points at a case of another member. Test run routes accept an item whose case belongs to a dot in `teamIds(item.dotId)`; today they assume one dot. Results are written on the case, so Ticket Reviewer's case page shows manual, automated and AI-Vision results from PR Reviewer and Regression Runner.
410
+ - Deleting a member that owns cases removes the other members' run items that point at those cases (see Removing members and leads).
411
+ - A bug report that maps a failing test to a case names the case and its owner dot.
412
+
413
+ ### 5. One bug, one draft
414
+
415
+ Reuses: `defectSig`, `bugSignature`, `bugSignatureAlts`, the three-layer guard in src/flows/defectDraft.ts, `draftDefects` and `defectTarget` in src/flows/defects.ts, `closeApproval`, `closePendingApprovals` in src/dot-remove.ts, and the Inbox approval card.
416
+
417
+ New code:
418
+
419
+ - `teamDraftFor(watch, candidate, now)` in src/lead-defects.ts. It looks at pending `issue_create` and `file_defect` drafts of the other members of `teamIds(watch.id)` created in the last 24 hours. A draft matches when either holds:
420
+ 1. the same `sig` or `bugSig`, alternates included; or
421
+ 2. the same failing test title (normalized with `normalizeScenario`, exported from src/review/render.ts) and at least one shared ticket ref in `meta.relates`.
422
+ - New meta on bug drafts: `testTitle`, written by both draft paths, so rule 2 can match.
423
+ - Both draft paths call `teamDraftFor` right after their own layer 1. On a match the member drafts nothing. It appends itself to the found draft's `meta.sources` (`{ watchId, runId, at, pr?, head?, bugKey, sig, bugSig }`), adds a "Seen again" line with its check link to the draft body under Details, publishes the approval event, and records the bug link as `drafted` with the Inbox URL. Its check gets the step "Same bug as the report PR Reviewer drafted. Added to it."
424
+ - Team bug target. `defectTarget(watch, repo)` for a member with a lead and no tracker of its own uses the tracker of `teamTracker(watch.id)`, so PR Reviewer and Regression Runner bugs go to katalon-studio/product with Ticket Reviewer's GitHub access. A member with its own tracker keeps it. A dot with no lead files as before.
425
+ - The first draft is the one that files. Approving it files once, into the team target. Rejecting it counts as a rejection for every source: `rejectedFor` also reads the `bugKey` of each entry in `meta.sources` across `teamIds`. Only a person's rejection counts. A draft closed by archiving carries `meta.closedBy: 'archive'`, and `rejectedFor` skips it.
426
+ - Archiving a drafter. `closePendingApprovals` hands a merged draft to the next source in `meta.sources` whose dot is live: the draft's `watchId` becomes that dot's id and the Inbox shows it under that member. Only a draft with no other live source closes, with `meta.closedBy: 'archive'`. No member loses a bug because another member was archived.
427
+ - A draft that already went out: `filedKeyFor` and `priorDefect` read across `teamIds`, so a later member's find becomes a "Seen again" ticket comment draft on the filed issue through the existing layer 3.
428
+ - The Inbox card shows "Found by A (PR #412, 10:02) and B (after merge of PR #412, 11:47)" from `meta.sources`. The draft's dot shows the first live member's name.
429
+ - No model call. The match reads the approvals table by `watchId IN (...)` and `status = 'pending'`.
430
+
431
+ ### 6. Release call
432
+
433
+ Reuses: `buildAll`, `testStatuses`, `readinessOf`, `readinessSummary`, `nearestOpenMilestone`, `milestoneDate`, `testStats` (flaky tests), and the readiness page (`saveReadinessReport`).
434
+
435
+ New code:
436
+
437
+ - Team trace scope. `ticketCatalog`, `indexLinks`, `loadEvidence` and `confirmedKey` take a list of watch ids. `buildAll(w)` passes `[w.id]` for a dot and `memberIds` for a lead. A ticket is classified with the tracker of the member whose ticket review read it. Defect links of every member join the rows, so a bug PR Reviewer filed into the team tracker counts as an open bug on its ticket. GET /api/dots/:id/traceability then works for a lead with no other change.
438
+ - `releaseCall(lead, milestone?)` in src/lead-release.ts, read-only and with no model. The milestone defaults to `nearestOpenMilestone` over the team rows. Rules, first match wins:
439
+
440
+ | Answer | When |
441
+ |---|---|
442
+ | No tickets | no requirement row has this milestone |
443
+ | Not ready | a row of the milestone is Failing; or an open bug is linked to a row of the milestone; or the latest after-merge check of a member found a bug (main is broken) |
444
+ | Ready with risk | a row is Not tested, Partly tested or Out of date; or a bug report for a row waits in an Inbox; or a test of the milestone's rows was flaky 3 or more times this week (`FLAKY_SUGGEST_AT`); or a member is Not watching, so its data may be old |
445
+ | Ready | none of the above |
446
+
447
+ - Reasons: one per row or bug, blockers first, each naming the ticket, the member it came from, and a link. The page shows six, the phone three, and "See every ticket" opens the team traceability filtered to the milestone.
448
+ - Shown on the lead page (Release call section with a milestone picker), in the digest, and in chat through `release_call` and the release question view.
449
+ - Never posts. "Save as a report page" reuses `saveReadinessReport` with the team scope and writes a local page only.
450
+ - Release guard. The release call answers a person's question with readiness words and does not replace the planned Release guard. Task 12 in docs/STAGES.md stays as planned for a single dot. When it lands, its readiness rules call `releaseCall` so a dot and a lead never give two answers for one milestone. Piece 1's STAGES.md update records this and keeps the rule "never says release or hold".
451
+
452
+ ## API routes
453
+
454
+ | Route | Change |
455
+ |---|---|
456
+ | POST /api/dots | accepts `kind: 'lead'` and `memberIds`; runs `leadError` |
457
+ | PATCH /api/dots/:id | accepts `memberIds` on a lead; refuses a change of `kind` |
458
+ | DELETE /api/dots/:id | 409 for the only member of a lead; the summary counts other members' run items it removes |
459
+ | GET /api/dots, GET /api/dots/:id | `dotView` includes `kind` and `memberIds`, and for a member `leadId` |
460
+ | GET /api/dots/:id/health | a lead returns team status with `team: TeamHealth` |
461
+ | GET /api/dots/health | leads included, each with `team` |
462
+ | GET /api/dots/:id/team | new: `TeamHealth` alone, for the team panel's minute reread |
463
+ | POST /api/dots/:id/digest | new: makes the team digest now and replies where it was asked. 202 `{ jobId }`, or 200 `{ duplicate: true }` inside the same 10-minute slot. 409 for a dot that is not a lead |
464
+ | GET /api/dots/:id/release?milestone= | new: `ReleaseCall`. 409 for a dot that is not a lead |
465
+ | GET /api/dots/:id/traceability, /readiness, POST /readiness/report | work for a lead over the team scope |
466
+ | POST /api/chat with a lead's `dotId` | lead chat: team read tools, routing, `release_call` |
467
+ | Routes listed under Lead-only guards | 409 for a lead |
468
+
469
+ A paired phone may call the GET routes and POST /api/dots/:id/digest. src/phone/auth.ts gains the digest route in its list of allowed writes. The digest costs no model call and replies only to the phone that asked.
470
+
471
+ ## Limits
472
+
473
+ | What | Limit |
474
+ |---|---|
475
+ | Members per lead | 1 to 8. The only member cannot be deleted |
476
+ | Leads per member | 1 |
477
+ | Team health | no model call, no tracker call. Reuses each member's 30 s answer; the lead answer is kept 30 s and dropped on any member event |
478
+ | Team digest | no model call |
479
+ | Team digest jobs | 1 scheduled per day per lead by `digest:<id>:<day>`, the only one that posts to Slack. On demand at most 1 per 10-minute slot, replied only where asked |
480
+ | Lead chat | each turn counts on the lead's cap. `forTeam` runs at most 8 member reads per tool call. Its only external calls are `open_prs`, at most 12 GitHub `listPulls` per tool call. `get_ticket` makes 1 tracker call through one member |
481
+ | Routed actions | 3 per chat turn. Each is a member job under the member's rules, cap, dedupe and deploy wait |
482
+ | Bug merge window | 24 h, the same as `APPROVAL_TTL_MS` by default |
483
+ | Release call | no model call. Kept 30 s per lead and milestone |
484
+ | Queue | no new job kind. The digest is a `digest` job of the lead, under `LOCALDOST_QUEUE_CONCURRENCY` |
485
+
486
+ ## Migration
487
+
488
+ None for existing dots. A dot with no `kind` is a `dot`, and nothing reads `memberIds` on it. The new columns are added at boot by the existing column loop in src/db.ts. `migrateStages` leaves a lead with every stage off, because it has nothing to derive them from. The four live dots change only when Huy makes the lead and names them. They keep their own digests, rules and Slack channels. Once they are members, PR Reviewer and Regression Runner file new bugs into the team tracker (job 5).
489
+
490
+ ## Build pieces
491
+
492
+ Dependency waves for parallel agents. Each piece is one PR with a changelog entry, under the localdost versioning rule.
493
+
494
+ | Wave | Piece | Contents | Needs |
495
+ |---|---|---|---|
496
+ | 1 | 1. Lead dot and team health | `kind`, `memberIds`, schema, `leadError`, src/lead.ts index with `teamTracker`, lead-only guards, `deleteDot` member and only-member rules, team health (server and `TeamPanel`), Dots header counts skip leads, dot list and dialog for a lead, STAGES.md 1.1 and Release guard update | none |
497
+ | 2 | 2. Team data and release call | `teamIds` case lookup and `linkRunResults` (job 4), team ticket scope in `mentionInScope`, run item cleanup on member delete, team trace scope, `releaseCall`, GET release route, Release call section on the lead page and phone | 1 |
498
+ | 2 | 4. One bug, one draft | `teamDraftFor`, `meta.testTitle`, `meta.sources`, team bug target in `defectTarget`, cross-team `rejectedFor` that skips archive closes, hand-off in `closePendingApprovals`, `filedKeyFor` and `priorDefect`, Inbox card sources line | 1 |
499
+ | 3 | 3. Ask the lead and team digest | `ctx.team`, `forTeam` with the `open_prs` cap, `get_ticket` routing, `team_status`, `release_call` tool and block, `routeToMember`, `AskOrigin` lead scope, `pickDot` lead preference, release question view, `runTeamDigest`, `ruleLevel` origin rule for `daily_digest`, POST digest route | 1, 2 |
500
+
501
+ ## Tests
502
+
503
+ Unit tests over fixed inputs, route tests through Fastify `inject`, and client tests with the existing health test setup. Each piece ships its own rows.
504
+
505
+ Piece 1:
506
+
507
+ - `leadError`: every row of the validation table, including a lead named as a member, a member already in another lead (archived lead too), and a lead that sends `repos`.
508
+ - PATCH that changes `kind` returns 400. A PATCH from a member role that changes `memberIds` returns 403.
509
+ - `teamHealth`: one case per team word; a Failing member beats a member that is Not watching for an expired sign-in; a Needs you member beats a member that is Not watching for a GitHub limit; a paused member left out of the word; all members away gives Not watching; no live member gives "The team has no dots."; reason picks the first member in `memberIds` order, lowers the first letter, and adds "(and 1 more)"; `need` falls back to the suggestion, then to "Nothing needs you."
510
+ - The lead's cached answer drops when a member's run changes status.
511
+ - GET /api/dots/health includes a lead with `team` set. A lead never reads "Not watching: nothing set up".
512
+ - Deleting a member removes its id from the lead. Deleting the only member returns 409. Archiving keeps the id and the row reads Archived.
513
+ - Each lead-only guard route returns 409 for a lead.
514
+ - Client: `TeamPanel` renders the four status words with icons, the Open buttons, and an away row; a long member name and a long need wrap with no ellipsis; the phone layout at 375 px wide has no side scroll. The Dots header counts one Failing member with its lead as "1 need you". Screenshot both widths and compare them with the wireframes in this spec.
515
+
516
+ Piece 2:
517
+
518
+ - `casesForTicket` with a list finds Ticket Reviewer's case from PR Reviewer and Regression Runner of the same lead. A dot with no lead finds only its own cases. A dot in another lead finds none.
519
+ - `linkRunResults`: an AI-Vision result of PR Reviewer and an automated spec result of Regression Runner on a Ticket Reviewer case each write a result row on that case. A key both members use maps to the run's own case.
520
+ - `linkedRefs` on PR Reviewer keeps a katalon-studio/product ref that the PR closes or names. The same PR on a dot with no lead drops it, as today.
521
+ - An after-merge check of a merge that closes the ticket adds Ticket Reviewer's manual cases to its test run, and the item route accepts the case.
522
+ - Deleting Ticket Reviewer removes Regression Runner's run items that point at its cases, recounts that test run, and the summary counts them.
523
+ - `designTestCases` still writes under Ticket Reviewer and does not copy a case that exists in the team.
524
+ - Team `buildAll`: a ticket from Ticket Reviewer, a PR link from PR Reviewer and a post-merge result from Regression Runner join into one row with the right status.
525
+ - `releaseCall`: one case per answer and per rule line; blockers come before risks; the milestone defaults to the nearest open one; No tickets for an unknown milestone.
526
+ - GET /api/dots/:id/release returns 409 for a dot that is not a lead.
527
+
528
+ Piece 4:
529
+
530
+ - Same `bugSig` from two members within 24 h: one Inbox item with two `sources`, and the second check records `drafted` with the Inbox link.
531
+ - Same test title and shared ticket with different signatures: merged. Same test title with no shared ticket: two drafts. Beyond 24 h: two drafts.
532
+ - Same signature in one member keeps the existing layer 1 behavior.
533
+ - `defectTarget` of PR Reviewer in a lead returns `github:katalon-studio/product`. With no lead it returns the app repo, as today.
534
+ - Approving the merged draft files one issue into the team tracker. Rejecting it stops both members from drafting that bug again.
535
+ - Archiving the first drafter hands the merged draft to the second source: one pending item remains, under the second member, and neither member is blocked from drafting the bug. Archiving a dot whose draft has no other source closes it, and `rejectedFor` ignores that close.
536
+ - A sibling's draft already filed: the later find becomes a "Seen again" comment draft.
537
+ - A dot with no lead drafts exactly as before (regression guard over the existing defect tests).
538
+
539
+ Piece 3:
540
+
541
+ - `forTeam` merges `list_runs` and `pending_approvals` across members with a `dot` column and keeps the row limit. A `dotId` outside the team is refused.
542
+ - `open_prs` in a lead chat with 14 repos across members calls `listPulls` 12 times and says "Skipped 2 repos". `get_ticket` calls the tracker once, through Ticket Reviewer.
543
+ - `routeToMember`: each row of the routing table; PR #12 found in one repo; PR #12 in two repos returns choices; no fitting member returns the "Add one" line.
544
+ - "check PR #12 again" in the lead chat queues a review on PR Reviewer, shows "Asked PR Reviewer to check PR #12 again", and the result posts in the lead chat with "From PR Reviewer".
545
+ - A Slack mention of Lead QA answers in its thread and routes the same way. An unnamed message in a channel the lead shares with a member reaches the lead; a message that names the member reaches the member.
546
+ - "Can we release 2026.11?" answers through the view with zero model calls (model usage rows unchanged).
547
+ - Digest: facts built from fixture rows of four members; the opener is the code template; zero model usage rows; one message to chat and one Slack post per scheduled day. POST digest twice in one slot queues once. An on-demand digest replies in the asker's chat only: no Slack post and no phone push.
548
+ - Chat eval (docs/CHAT-EVAL.md): add lead questions for team status, a release question, and a routed rerun.
549
+
550
+ ## Open questions for Huy
551
+
552
+ - Name. The role preset `qa-lead` in src/routes/roles.ts is labeled "QA lead" and makes one dot that does everything. A new dot type called "Lead QA" next to it in the New dot dialog reads as the same thing. Proposal: keep "Lead QA" for the team dot and rename the preset to "All-in-one QA".
553
+ - Member digests. The four members keep their own daily digests, so the team gets five messages a day. Changing members' posting is out of scope here. Huy can set the members to weekly digests by hand once the lead digest runs.