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,89 @@
1
+ # Traceability map (KAT-189)
2
+
3
+ The Traceability page gets three views of the same data: Table (today), Map, and Heatmap. The Map is a collapsible tree of the product, like the True Platform IA map. Every node carries its requirements, tests, defects, latest screenshot, and an agent skill. Every node and heatmap cell drills down.
4
+
5
+ ## Data: the observed app under test
6
+
7
+ The map shows the app as the dot's test runs saw it, the way a tester walks it. It is not derived from the repo. Three sources, in order:
8
+
9
+ 1. **Observed pages (source of truth).** Every page or state a Playwright test or an AI-Vision case visited: URL, page title, main headings and landmarks from the accessibility snapshot, the real screenshot, the actions taken there (click, fill, assert, AI-Vision step text), the test that did it, and its result. URLs are normalized to route patterns (`/runs/0mv0dp...` becomes `/runs/:id`; query strings dropped; hash routes kept as paths).
10
+ 2. **Requirements.** A ticket sits on a page only on evidence: a test linked to it visited the page, its text names the route, or a file one of its PRs changed is the page's source or lies in the page's product area (repo profile). A run on the ticket's PR that visited the page is not evidence, since a full suite visits every page. A ticket with no evidence sits in Requirements without a page only. That section sits under the app of the dot the ticket belongs to (the dot that reviewed or linked it); in All dots each app has its own, and a ticket of two dots appears under both apps once each. A page's status comes from its own tests and requirements.
11
+ 3. **Repo code.** The repo scan maps a route pattern to its source files and API routes, shown in the drawer. Its page routes, and the routes its specs open, also make coverage gap nodes when no run visited them (see Coverage gaps on the map). API routes never make a node.
12
+
13
+ Pages that the code, a requirement, or a probe names but no run has visited show as **Needs tests** or **Not run yet** nodes: that is the coverage gap.
14
+
15
+ ### Capture
16
+
17
+ Every run that runs tests writes `observations.jsonl` among its artifacts (`src/runner/observe.ts`), one line per page or state change:
18
+
19
+ `{ at, attempt, source, test, title, project?, url, route, host, from?, pageTitle?, headings[], landmarks[], dialog?, action?, steps?, requests?, screenshot?, result?, error? }`
20
+
21
+ - **Playwright:** the runner passes `--trace=on`, so the repo's own specs need no edits. After each attempt it reads every test's `trace.zip`: the main-frame DOM snapshots give the URL, page title, headings, landmarks, and an open dialog; the "navigated to" logs and step titles give the step that led to the page (`action`) and the steps taken there (with the error of a failed one); the network log gives the requests the page made; the last screencast frame of the first visit is the screenshot. Traces of tests that passed are deleted once read, so a run keeps the traces it kept before (tests that did not pass).
22
+ - **AI-Vision:** each case step maps to the same line shape: the step's URL when the server sends one, else the case's start URL, the step text, its error, and its screenshot. The CLI backends report no steps, so each case is one line at its start URL.
23
+ - One screenshot per route per test, stored as a run artifact (`a1-obs-<test>-<route>.jpeg`). URLs are stored without their query string.
24
+
25
+ ### Tree
26
+
27
+ App (from the base URL host; local servers a test run starts on a random loopback port that no dot names are one app, Local test servers) > section (the product area of the repo profile that lists the route, else the first path segment, named from the most common heading on those pages; a section with one page is that page, so the map does not say the same thing twice) > page (route pattern) > state (a distinct heading set or dialog on the same route, when tests open one). Each node: status, counts (requirements, tests passed of total, open bugs), the latest real screenshot, the tests and their last result, requirements, defects, dot presence, and the agent skill.
28
+
29
+ The agent skill for a page is written from observations: how to reach it (the URL and the clicks tests used), what is on it (headings, landmarks), which tests cover it, open bugs, and gotchas from failed steps.
30
+
31
+ ## API
32
+
33
+ - `GET /api/dots/:id/trace/map` returns `{ tree: TraceMapNode, stats, milestones, observed }`. `TraceMapNode = { id, kind: 'root'|'app'|'section'|'page'|'state', name, route?, pageTitle?, status, counts: { requirements, tests: {passed, failed, total}, defects: {open, total} }, screenshot?: url, dots?, children: TraceMapNode[] }`. The status is one of `covered`, `partly`, `failing`, `needs_tests`, `not_run`; `counts.gaps: { needsTests, notRun }` counts the pages at or below the node with each gap. A map with one app has the app as its root; several apps sit under a `root` node. Stats count nodes by status. `observed` is false until a run records a page.
34
+ - `GET /api/dots/:id/trace/map/:nodeId` returns the drill-down: the node with the URLs, headings, and landmarks runs saw, requirement rows (same shape as `TraceRow`), tests with title, last result and run link, defects with links, screenshots (one per test per route, the latest, with the test's `result`; up to 12, newest first), `gaps` (the pages at or below the node that need tests or a run, with the specs that cover them), `code: { files, api }` from the repo scan, and the skill markdown.
35
+ - `POST /api/dots/:id/trace/map/:nodeId/run` queues a `rerun` job with the spec files that cover the node (Run tests); 409 when no test covers it. `POST /api/trace/map/:nodeId/run` uses the node's first dot.
36
+ - Requirement rows with no title (a key a PR names before a ticket review read it) get their title from the dot's tracker (Jira, Linear, or GitHub Issues), cached in `ticket_titles` for a day; a failed read is tried again after ten minutes, and the row keeps its fallback text until a read works (KAT-190).
37
+ - `GET /api/dots/:id/trace/map/skill.md` returns the whole map as one agent skill: a router section (tree with status) and one section per page and state.
38
+
39
+ ## Agent skill per node
40
+
41
+ Markdown an agent can follow without exploring the app first, written from observations: how to reach it (app base URL, route, the URLs runs saw, and the steps tests took from the page before), what is on it (page title, headings, landmarks, states, requests), the tests that cover it with their spec files and last results, open defects with repro lines, known gotchas from failed steps on the page and failed tests, the latest screenshot URL, its requirements, and the source files and API routes from the repo scan. Generated from data only, no model call. The chat tools (when the chat tools PR lands) can read it through the same endpoint.
42
+
43
+ ## Map view
44
+
45
+ An IA map on a canvas, top down: a card on top, and when it is open its children sit in a panel below it, side by side, wrapping into rows. An open child is a block of its own, so the app reads across its areas with each area's pages in a grid under it. The wrap width comes from the viewport: the layout takes the widest zoom from 100% down to 60% at which the whole map fits, and Fit never goes below 60% just to show the full height (a taller map starts at the top and pans down).
46
+
47
+ It opens at depth 2: the app and its areas (or the apps and their areas under an All dots root). A press on a card with children expands it in place and fits the view to it; a press on the open focus closes it again. A breadcrumb above the canvas goes back up a level, closing what was drilled into below it; the top crumb opens the map at depth 2 again. A leaf card, or the Details button on any card, opens the side drawer. Expand all, Collapse all and Depth 1/2/3 stay. A search or status filter cuts the tree down to the matches and opens the path to each.
48
+
49
+ The canvas draws at most 300 cards: an open node shows its first 24 children, breadth first, and a '+N more' box stands for the rest; a press on it shows 100 more. The breadcrumb row says how many nodes are shown of the total.
50
+
51
+ Each card has a fixed 72 by 45 thumbnail area on the left (object-fit cover, rounded). The box shows a small page icon until the screenshot has loaded and decoded, then the image fades in, so nothing moves. With no screenshot, or a file that does not load, the box keeps the page icon and no outline or fill; the app logs a file that does not load once. The map payload names only screenshot files still on disk: a file the artifact cap deleted is left out, the node takes its newest screenshot still on disk, and the server logs the first missing file once and three lines to its right: kind and name, the status icon and word, and three counters (requirements, tests passed of total, open bugs) in monospace tabular numbers, then the dots that visited it. Nodes are sized so nothing clips or wraps from 60% to 150% zoom; a long name ends in an ellipsis. List shows the same nodes as an outline list (also the screen-reader friendly reading).
52
+
53
+ Status icons: each state has its own shape and color (a check in a circle for Covered, a half-filled circle for Partly covered, an octagon with a cross for Failing, a dashed circle with a plus for Needs tests, a rounded square with a play mark for Not run yet). Where an element is short of room it shows the icon alone and keeps the word for screen readers; the element's own width decides (CSS container queries).
54
+
55
+ ## Heatmap view
56
+
57
+ A treemap. The top level has a tile per area, grouped under a header per app when there are several. A tile's size is its tests (or requirements, by the Size toggle), with a floor so an area with no tests still has a tile; its fill and icon are its coverage status. Each tile shows the icon, the area name and a short count, and the status word where it has room. The coverage gaps (Needs tests, Not run yet) get a stronger fill, a dashed inner edge in the text color and a bigger floor, so they stand out. A press on a tile with pages drills into them as the next level, with a breadcrumb back up and a Details button for the level's drawer; a tile with nothing under it opens the drawer (a gap opens the tests filtered to it). A legend names the five states.
58
+
59
+ Table shows the same level as rows: Requirements, Tests, Passing, Failing, Not run, Open bugs, Needs tests, Not run yet. Cell shade scales with the value inside its column, using existing color tokens (bugs and failing use the danger scale, tests and passing use the success scale, requirements the neutral accent). Each cell shows the number. Clicking a cell opens the drawer on that node and tab, filtered to that column. A toggle switches columns to milestones, with cells showing open bugs per area per milestone.
60
+
61
+ ## Rules
62
+
63
+ - Tokens only, light and dark both work. Visible labeled controls, no hidden overflow menus. Rows, not cards. Plain QA words.
64
+ - Phone width works: below 640px the filters (Dot, status, search, depth, List) fold into one row with a Filters button that opens a sheet, so the view starts near the top. The phone gets the same canvas, with pan, pinch and the minimap; the Heatmap table scrolls sideways inside its own box.
65
+ - No colored borders or stripes on list items or cards; selection reads from the background.
66
+ - Tests: unit tests for the mapping rules and status roll-up, component tests for Map and Heatmap drill-down, one Playwright `@smoke` test that opens Map, clicks a node, and sees the drawer.
67
+ - Controls never wrap their label: buttons, tabs, filter pills, status chips, and counters use `white-space: nowrap`. If a label cannot fit, drop the font one size step rather than wrap. Align by eye (optical alignment), not to the pixel.
68
+
69
+ ## Canvas and dot presence (KAT-211)
70
+
71
+ The Map view is a canvas: drag to pan, wheel or pinch to zoom, buttons for zoom in, zoom out, and Fit, plus a small minimap in a corner. Node positions come from a left-to-right tree layout; a person can drag a node, and the position is kept per viewer in localStorage (wrapped in try/catch). One canvas can show every dot's repos: a "Dot" filter with "All dots" as the default gives the big picture.
72
+
73
+ Each section, page, and state node shows the avatars of the dots whose runs visited it (or whose requirement, probe, or code it is, for a gap node). When a dot has a run in progress that has reached the page, or that is on a PR whose changed files hold the page's source files (from the repo scan), the node shows a live marker with the stage name (for example "Reviewing PR #34"). Clicking an avatar opens that dot; clicking a node opens the drawer as before. Data: add `dots: { id, name, avatar, running?: { runId, label } }[]` to `TraceMapNode`, and the map route accepts no dot id (`GET /api/trace/map`) for the all-dots canvas.
74
+
75
+ Repo-derived areas (an earlier draft) are superseded by the observed tree above and removed.
76
+
77
+ ## Coverage gaps on the map (Huy, 2026-10-09)
78
+
79
+ A page or path that the code or a requirement has always shows on the map, even when no run has visited it. Its indicator says what to do next, with a distinct dot and word (never color alone):
80
+
81
+ | Indicator | Meaning | Next step |
82
+ |---|---|---|
83
+ | **Needs tests** | Known from code (routes) or a requirement, and no test covers it | Write a test |
84
+ | **Not run yet** | A test covers it, but no run has executed that test, or not since the last change to the page's code | Run the tests |
85
+ | Covered / Partly covered / Failing | Observed in runs, as before | As before |
86
+
87
+ Gap nodes sit where their route pattern belongs in the tree, drawn with a dashed outline and no screenshot. The status filter and the heatmap get "Needs tests" and "Not run yet" columns, and clicking one lists those pages with a Write tests or Run tests action.
88
+
89
+ How it is built: a test covers a page when a scanned spec opens its route, or when a requirement that names the route links the spec. A page's code changed when a merge (`post_merge` run) changed one of its source files after the latest observation of the page; a failing page stays Failing. A section with no visited page is Needs tests when any page in it needs tests, else Not run yet. The dots: a ring for Needs tests, a half-filled dot for Not run yet. Write tests opens the dot's chat with a draft that names the page and its skill; Run tests calls the run endpoint above. Requirements no route places sit in a "Requirements without a page" section, Not run yet when they link specs.
@@ -0,0 +1,225 @@
1
+ # Jira, Linear, and GitHub Issues
2
+
3
+ A dot with a tracker reviews each new ticket like a QA engineer in refinement. It scores the ticket from 0 to 100 for how ready it is. A ticket under 30 gets one line in the daily digest. Any other ticket gets a review: risks, open questions, gaps in the acceptance criteria, test ideas, and existing tests that the change may break, found by a code search in the watched repo. The dot then drafts a ticket comment. It also designs manual test cases from the review and stores them as drafts linked to the ticket, without repeating the cases it already has for that ticket. Mark each draft ready on the Test cases page.
4
+
5
+ Ticket comments default to `ask`, so each draft waits in the Inbox until you approve, edit, or reject it. Change the rule for `ticket_comment` in the dot's Settings when you want the dot to comment on its own.
6
+
7
+ Without credentials, a tracker runs in demo mode: the dot reviews tickets from webhook payloads and writes its comments to the outbox.
8
+
9
+ | | Jira Cloud | Linear |
10
+ |---|---|---|
11
+ | Credentials | `JIRA_BASE_URL`, `JIRA_EMAIL`, `JIRA_API_TOKEN` | `LINEAR_API_KEY` |
12
+ | Webhook | `/hooks/jira`, signed with `JIRA_WEBHOOK_SECRET` | `/hooks/linear`, signed with `LINEAR_WEBHOOK_SECRET` |
13
+ | Polling | `LOCALDOST_POLL=1` or `pollJira: true` | `LOCALDOST_POLL=1` or `pollLinear: true` |
14
+ | Triggers | Issue created; issue updated when the description or the acceptance criteria changed | Issue created |
15
+ | Dot tracker field | `{ "kind": "jira", "baseUrl": "...", "projectKeys": ["SHOP"] }` | `{ "kind": "linear", "teamKeys": ["ENG"], "projectName": "Checkout" }` |
16
+ | Loop guard | Signed marker from the dot's own account; `JIRA_BOT_ACCOUNT_ID` | Signed marker from the dot's own account; `LINEAR_BOT_USER_ID` |
17
+
18
+ Connect either tracker from the Setup page: press **Connect** on its row, paste the credentials the flow asks for, press **Test**, then **Connect**, and pick the projects or team. The variables in the table are the environment route, and they win over values saved in the app.
19
+
20
+ A ticket reaches a dot when its Jira project key or Linear team key is in the dot's tracker field. Webhook and poll events for the same ticket share one dedupe key, so a ticket is reviewed once. A ticket edited while its review still waits in the queue (it has not started, or the dot is at its daily model cap) keeps one review: the newer edit replaces the queued job of the same ticket for the same dot, so the review reads the newest text and posts one draft. A review that already runs is not stopped, and the edit queues a follow-up. A backfilled review never replaces a queued one. A late or repeated delivery for an older edit than the queued review (the ticket text carries the tracker's update time) starts nothing and stops nothing, so the review reads the newest text. A review a person asked to run again keeps its `rerunOf` link when a later edit replaces it, and **Rerun** on a review of a ticket whose review still waits replaces the queued one the same way, so the queue never holds two reviews of one ticket for one dot (KAT-408).
21
+
22
+ ## Jira
23
+
24
+ 1. Create an API token in your Atlassian account settings (the flow links there). In Setup, press **Connect** on the Jira row and enter the site, for example `acme.atlassian.net`, your Atlassian email, and the token. Press **Test**, then **Connect**, and pick the projects. With environment variables instead, set `JIRA_EMAIL`, `JIRA_API_TOKEN`, and `JIRA_BASE_URL`. `localdost init --tracker jira --jira-url <url> --jira-project SHOP` writes the references for you.
25
+ 2. As a Jira admin, open Settings, System, WebHooks, and create a webhook:
26
+ - URL: `https://<your-host>/hooks/jira`
27
+ - Events: Issue created. Add Issue updated to re-review a ticket when its description changes.
28
+ - JQL filter, optional: `project = SHOP`
29
+ - Secret: a random string, copied to `JIRA_WEBHOOK_SECRET`. With it unset, `/hooks/jira` answers 503 and queues nothing. Jira then signs each delivery with `X-Hub-Signature: sha256=<hex>`.
30
+ 3. Set the dot's tracker to `{ "kind": "jira", "baseUrl": "https://acme.atlassian.net", "projectKeys": ["SHOP"] }`.
31
+
32
+ localdost reads issues through REST API v3 and posts comments as Atlassian Document Format. When your acceptance criteria live in a custom field, set `JIRA_AC_FIELD` to its id, for example `customfield_10042`. Otherwise the dot reads them from the description.
33
+
34
+ ### Jira polling
35
+
36
+ With no URL that Jira Cloud can reach, use polling instead of the webhook. With `LOCALDOST_POLL=1` or `pollJira: true` on the dot, the poller searches Jira every `POLL_JIRA_SEC` seconds (default 60) through the connected Jira account with `project in (<the dot's keys>) AND updated >= <cursor>`. It queues a ticket review for each issue created since the last poll, and for each issue whose description or acceptance criteria field changed since then. The first poll after boot records a cursor and queues nothing. The open tickets that were there before a new dot started are reviewed by a separate backfill, see [Open tickets from before the dot started](#open-tickets-from-before-the-dot-started). After a gap of over an hour (the server was down, or a laptop host slept) the poll searches from the old cursor, the 1000 most recently updated tickets first, and queues the tickets created or edited since, newest first, at most 5 per dot (KAT-363). Each of those events carries `catchUp: { since, gapMs, source: "Jira" }`, and its run starts with a "Caught up after a gap" step.
37
+
38
+ Polling uses the webhook's dedupe key for a new issue (`jira:<key>:created`), so a webhook and polling can run together. An edit is keyed by the time of the edit. Polling skips edits by the bot account (`JIRA_BOT_ACCOUNT_ID`, else the account that owns the token), and it skips an issue whose newest comment came from the bot account after the change (`JIRA_BOT_ACCOUNT_ID`, else the account that owns the token), because the dot has already answered it.
39
+
40
+ A poll reads up to 1000 issues, oldest first, in pages of 100. The search is rounded to the minute, so a larger burst (or many issues with the same timestamp) can fill a window. The cursor then stays at the window start and remembers the issues it has handled by key and update time. The next poll reads deeper (up to 3000 issues), skips those, and queues the rest, so every ticket gets one review. Beyond 3000 changes in one window, the poll logs a warning and moves on.
41
+
42
+ A webhook still reacts in seconds; polling reacts within a minute. Use a tunnel from [DEPLOY.md](DEPLOY.md) when you want the webhook and the server runs on your machine.
43
+
44
+ To stop the dot from reviewing events its own account caused, set `JIRA_BOT_ACCOUNT_ID` to the account id of the user that owns `JIRA_API_TOKEN`. That skips everything the account does. Without it, the dot skips only the issues and comments it wrote itself (see [Loop guard](#loop-guard)), so a person who owns the token still gets their tickets reviewed.
45
+
46
+ ## Linear
47
+
48
+ 1. Create a personal API key in Linear: Settings, Security and access, New API key. The Linear flow in Setup links there. Paste the key, press **Test**, then **Connect**, and pick the team and project. With environment variables instead, export it as `LINEAR_API_KEY`. `localdost init --tracker linear --linear-team ENG` writes the reference.
49
+ 2. Pick webhooks or polling.
50
+ 3. Set the dot's tracker to `{ "kind": "linear", "teamKeys": ["ENG"] }`. Add `"projectName": "Checkout"` to narrow polling to one project. The same project is where the dot files its defects, see [Defects the dot files](#defects-the-dot-files).
51
+
52
+ ### Webhooks
53
+
54
+ Create a webhook in Linear Settings, API, Webhooks:
55
+
56
+ - URL: `https://<your-host>/hooks/linear`
57
+ - Resource types: Issues
58
+ - Copy the signing secret to `LINEAR_WEBHOOK_SECRET`. With it unset, `/hooks/linear` answers 503 and queues nothing.
59
+
60
+ localdost checks the `Linear-Signature` header and rejects a delivery whose `webhookTimestamp` is more than 60 seconds off the server clock. Only issue creates trigger a review.
61
+
62
+ ### Polling
63
+
64
+ With `LOCALDOST_POLL=1` or `pollLinear: true`, the poller asks Linear every `POLL_LINEAR_SEC` seconds (default 60) for issues created in the dot's teams since the last poll. The first poll after boot records a cursor and queues nothing. The open tickets that were there before a new dot started are reviewed by a separate backfill, see [Open tickets from before the dot started](#open-tickets-from-before-the-dot-started). After a restart of under an hour, polling catches up from the stored cursor. After a longer gap (KAT-363) the poll reads the issues created since the old cursor, up to 250 of them, and queues the newest first, at most 5 per dot. Each of those events carries `catchUp: { since, gapMs, source: "Linear" }`, and its run starts with a "Caught up after a gap" step.
65
+
66
+ Polling skips issues created by `LINEAR_BOT_USER_ID` and the issues the dot wrote itself (see [Loop guard](#loop-guard)); a person who owns the API key still gets their tickets reviewed. When more than 250 issues were created since the last poll, the poll reads 250 and the cursor stays behind the issues it did not read, so the next polls continue. `LINEAR_API_URL` changes the GraphQL endpoint that polling and `localdost doctor` use.
67
+
68
+ A Linear webhook and Linear polling can run together for the same team. Both use the dedupe key `linear:<identifier>:created`, so each issue is reviewed once.
69
+
70
+ ## GitHub Issues
71
+
72
+ A dot can use the issues of a GitHub repo as its tracker. It reviews the requirements (native issue types **Feature**, **Story** and **Task**, or the labels below when an issue has no type), tracks the defects (type **Bug**), and ignores any other type. Each requirement gets a review, links to its PRs, a test status, and a row in the traceability view.
73
+
74
+ It needs the GitHub connection from [GITHUB.md](GITHUB.md) with the Issues permission (read and write), and the App subscribed to the Issues event. An App created with **Create GitHub App** in Setup has both. An App created before this change needs the permission and the event added in its GitHub settings, and each installation must accept the new permission.
75
+
76
+ Set the dot's tracker to `{ "kind": "github" }`. The dot then reviews the issues of its own repo. `localdost init --tracker github --tracker-repos katalon-studio/product --require-labels pod:agentic --milestone 2026.11` writes the same fields. The other fields are optional:
77
+
78
+ | Field | Default | Effect |
79
+ |---|---|---|
80
+ | `repos` | The dot's repo | Repos (`owner/name`) whose issues the dot reviews. When it names repos, the dot files its defects in the first one |
81
+ | `issueTypes.requirement` | `Feature`, `Story`, `Task` | Issue types reviewed as requirements |
82
+ | `issueTypes.defect` | `Bug` | Issue types reviewed as defects |
83
+ | `labels.requirement` | `requirement`, `story`, `feature`, `enhancement` | Labels that mark a requirement on an issue with no type |
84
+ | `labels.defect` | `bug`, `defect` | Labels that mark a defect on an issue with no type |
85
+ | `labels.ignore` | none | Issues with one of these labels are never reviewed |
86
+ | `labels.require` | none | Review only issues that carry at least one of these labels (any case), whatever their type. The first one also goes on every defect the dot files |
87
+ | `milestones` | all | Only review issues in these milestones |
88
+ | `statusLabels` | off | Draft a `qa: passing` or `qa: failing` label on a requirement issue when its test status changes (see Test status below) |
89
+
90
+ An issue with an issue type is classed by the type alone, so a type that is neither a requirement nor a defect type is skipped. Issue types exist only in organizations; in a personal repo, or an org that does not use types, the labels decide. An issue with neither a matching type nor a matching label is skipped. Closed issues are skipped.
91
+
92
+ `labels.require` is for a repo that several teams share. With `"labels": { "require": ["pod:agentic"] }` an issue is in scope only when it carries `pod:agentic`, and the type or label rules above then decide how it is reviewed. An issue with no type and a required label is a requirement, unless a defect label or the `localdost` label of the dot's own defects says it is a bug. An issue with no required label is out of scope, whatever its type. Adding the label to an issue later brings it in. The test status, the traceability view and the defect links read the same rule. Every issue the dot skips for its scope (a missing required label, a type, a milestone, a skip label) is written to the log with the reason, for example `Agentic pod: skipped issue katalon-studio/product#412: it has none of the required labels (pod:agentic); it has pod:other`. An issue in scope whose event starts no review, such as a label that is not one of the scope labels, is logged as `no new review for` that issue, with the reason. The setup flow's Tracker step saves the labels it asks for in this field and counts the issues with the same rule.
93
+
94
+ A review starts when an issue in scope is opened, when its body or title is edited, when a label, type, or milestone brings it into scope, or when someone with write access comments `/localdost review` on it. The command reviews any issue that is not ignored, whatever its type or milestone; with `labels.require` it still needs one of the required labels, so a member of another pod cannot start a review of an issue that is not the dot's. An issue opened with a label is reviewed once, and an edit that repeats earlier text queues nothing.
95
+
96
+ Acceptance criteria come from the first of: a section under an "Acceptance criteria" heading, the task list items (`- [ ]`), or the issue form sections whose label names criteria (for example `### Acceptance criteria` or `### Expected behavior`).
97
+
98
+ The review also reads the newest 20 comments of the issue, the parent issue and the sub-issues. A comment from an owner, member or collaborator of the repo can answer a question the review would otherwise ask. A comment from anyone else is background and never answers. The code checks it against the list of comments the review read: a summary line that credits only writers with no role (by their @login, the link of their comment, or a quote of 6 words or more that the ticket text does not hold) is cut whatever its wording, and the review asks the question again and names the writer (KAT-401). A line that only restates the issue stays, even when a stranger's comment repeats the issue.
99
+
100
+ The review comment carries the marker `<!-- localdost:ticket-review -->`, and a re-review edits that comment in place. Ticket comments keep the default rule `ask`, so each draft waits in the Inbox.
101
+
102
+ The review also reads the issue timeline and records links: PRs and issues that mention it, sub-issues, and blocking issues. A PR check records the issues the PR closes, from closing keywords in the title and body (`Fixes #12`, `closes acme/shop#7`, an issue URL) and from the PR's linked issues in the Development sidebar, plus Jira and Linear keys in the title, branch, or body. `GET /api/links?ref=acme/shop%2312` lists the links of one issue or PR.
103
+
104
+ Webhook and poll events share dedupe keys: `github-issue:<owner/name>#<n>:created` and `github-issue:<owner/name>#<n>:edited:<hash>`. With `LOCALDOST_POLL=1` or `pollGithub: true`, the poller reads issues updated in each tracker repo every `POLL_GITHUB_SEC` seconds. Polling does not act on `/localdost review` comments (see [Review again when someone answers](#review-again-when-someone-answers) for the comments it does read). After a gap of over an hour with no poll (a server that was down or asleep), the poll catches up instead of dropping the gap (KAT-363): it reads the 100 most recently updated issues since the old cursor, tells what changed from the issue state it recorded (an opened issue, an edit, an added label, type or milestone), and queues them newest first, at most 5 per dot after the tracker's scope (required labels, types, milestone), so another pod's issues do not use them up. Each run starts with a "Caught up after a gap" step. Issues and comments the dot wrote itself (see [Loop guard](#loop-guard)), issues opened by the localdost App, and edits by `GITHUB_BOT_LOGIN` are never reviewed.
105
+
106
+ ### Review again when someone answers
107
+
108
+ The review of a ticket ends with questions for the person who filed it. When someone answers them in a comment, the dot reviews the ticket again and says which questions are answered now (KAT-393). It works for GitHub Issues trackers, through the poller and through the `issue_comment` webhook, with the same rules:
109
+
110
+ - The dot reviewed the issue, and its last finished review left open questions. A ticket reviewed without questions, or never reviewed, is not looked at again.
111
+ - The issue is open and still in the dot's scope (required labels, skip labels, milestones), the dot is not paused or archived, and its Ticket analyst stage is on.
112
+ - A person wrote the comment. A bot, a comment the dot wrote (its signed marker, by its own account), an empty comment, and a bare `/localdost review` do not count. The same account without the marker counts, since a person may share it.
113
+ - The comment is newer than the last review, which read every comment that existed when it started.
114
+ - The writer is the author of the issue, or has write access to the repo (`GET /repos/{owner}/{repo}/collaborators/{login}/permission`, asked once per login and poll). A stranger's comment starts nothing, and the review never treats it as an answer.
115
+
116
+ A comment that counts queues one `ticket_review` job that waits for a quiet window of 10 minutes. Every counting comment that arrives while it waits joins it and pushes it back by 10 minutes from the new comment, so a burst of comments is one review. Once the review has started, the next counting comment starts a new burst. A dot makes at most 3 of these reviews per issue per day, counted from the local midnight of the server; a comment over that limit is stored as an event with `skipped` and the reason, and starts nothing: nothing reads it again, and the reason says that a person with write access can comment `/localdost review` to ask for one. The job key is `github-issue:<owner/name>#<n>:answered:<comment id>:<dot id>:ticket_review`, so a comment read twice (the 30 second overlap of the poll, or a webhook and a poll) counts once.
117
+
118
+ The poller keeps its own cursor for comments, `github-issue-comments:<owner/name>`. The first poll of a repo records it and reads nothing, and a repo where no dot has a reviewed ticket with open questions costs no request. One request reads the new comments of the whole repo (`GET /repos/{owner}/{repo}/issues/comments?sort=created&direction=asc&since=`, up to 300 per poll, the rest on the next poll).
119
+
120
+ When GitHub fails while the dot judges a comment (the issue read or the write-access check answers 5xx, times out, or hits a rate limit), the comment is not judged, and it is not counted as an answer of "no". The poller keeps its comment cursor where it was, so the next poll reads the comment again, for up to 60 minutes after the cursor; after that the cursor moves on and the warning `could not be checked on GitHub` stays in the log. A delivery of the `issue_comment` webhook is sent once, so the server asks again by itself, after 30 seconds, 5 minutes and 20 minutes, and then gives up with a warning. A comment judged on an earlier try is absorbed by its job key, so a review is never queued twice. A 404 on the issue, or a write-access answer of "no", is an answer, and the comment is ignored.
121
+
122
+ What the second review does. It reads the issue as it is then, and it trusts the issue author and the writers it checked, whatever their role in the repo (the first review calls a comment from an outsider background only). The model gets the questions of the last review, numbered, and says which ones the comments answer in `answeredQuestions` (`question`, `by`, `quote`). The code checks every entry: it must name one of those questions (word for word, or close enough that no other question fits better), and its writer must be the issue author, a writer the poll checked, or a team member among the commenters. An entry that fails is dropped, and its question stays open. A quote is cut to 15 words. The posted comment gains a section, **Answered since the last review**, before **Questions**, listing each answered question with who answered and the quote, and the line "2 questions from the last review are answered now."; the comment is edited in place like any re-review. The run says **Someone answered** and then **Questions answered** (or **No question answered yet**). A ticket too thin to review is reviewed anyway after an answer, and a ticket closed before the review starts gets a run that says so and makes no model call. `ticket.change.field` of the job is `answer`, and `answers` on the trigger holds the logins, the comment ids and the time of the last one.
123
+
124
+ ### Defects filed as issues
125
+
126
+ A test that failed on every attempt (the first run and both retries) in a `pr_check` or `post_merge` run whose verdict is a product failure drafts one `issue_create` action. Flaky tests, test failures, and environment failures never draft one. The default rule for **Create issues** is **Ask**, so the draft waits in the Inbox. The same action files into Jira (`POST /rest/api/3/issue`, Markdown converted to ADF, type `Bug` unless the draft names another) and Linear (`issueCreate` on the team, labels matched by name), whichever tracker the dot has. A dot with no tracker files into its repo's issues.
127
+
128
+ The draft carries the scenario as the title, the steps, expected and actual results, the error text with secrets masked, links to the run and, when the app has a public URL, to the trace and the failure screenshot, the suspected PR, and `Relates to #N` for each requirement the PR is linked to (Features, Stories and Tasks; a Bug is left out). Labels are the first `labels.defect` (default `bug`) plus `localdost`. The issue type is the first `issueTypes.defect` (default `Bug`); a repo that rejects the type gets the issue again with labels only. The milestone is the one of the first linked requirement that has one.
129
+
130
+ Where the defect lands: when the tracker names `repos`, every defect is filed in the first of them, unless the bug was found in a repo the tracker names too, which keeps it. A team that tracks its bugs in one repo (for example `katalon-studio/product`) sets `repos` and its code repos stay free of defect issues. The body then names the repo and the PR it came from (`Found while testing PR katalon-studio/web#12.`, and `Relates to katalon-studio/web#12.` on a defect from a review, or `Likely cause: PR ...` on one from a failing test), so the PR timeline links back. The labels are the first `labels.defect`, `localdost`, and the first `labels.require`, so the team's board picks the defect up. A defect that carries a required label also carries the defect label and the issue type, both from the first of `labels.defect` and `issueTypes.defect`, so it is never read back as a requirement; a dot with no `labels.require` files as before. The Inbox card says `Files in katalon-studio/product.`, and the PR comment says `Defect: drafted for katalon-studio/product, waiting in the Inbox.` A tracker with no `repos` files each defect in the repo the bug was found in. The duplicate check below reads the issues of the repo the defect lands in.
131
+
132
+ What a defect says (KAT-377): the title states what went wrong with both values (`Discount applied at checkout: $120.00 instead of $108.00`). The body opens with the impact and when it was found, then the severity and how often the test failed, the steps to reproduce, Expected and Actual, the evidence (screenshot, video, the check), the likely cause, the test case it belongs to, and what it relates to. The steps are the names the failing test gave its own `test.step` blocks, or the steps of the test case that automates it. When neither exists the steps say "Run the automated test in For developers." and the issue gets the label `needs-manual-steps`. The run command, the test file, the trace, the commit, the error text and the bug signature sit under For developers: a `<details>` fold on GitHub, an `expand` node on Jira (the Markdown fold becomes ADF), and a plain heading on Linear, which shows the tags as text, so the Linear body keeps the signature line in view. A hidden marker `<!-- localdost:defect sig=... -->` stays at the end for the duplicate check.
133
+
134
+ The body ends with `<!-- localdost:defect sig=<hash> -->`, a hash of the test id and the first line of its error. Before a draft is made:
135
+
136
+ - a pending draft with the same signature means no second draft;
137
+ - an open issue that carries the marker (GitHub issue search, or an issue this dot filed earlier for Jira and Linear) turns the draft into a comment on that issue, "Seen again in run <link>", under the `ticket_comment` rule. Jira and Linear issues are not checked for being closed;
138
+ - a draft the person rejected for the same bug on the same PR is not drafted again.
139
+
140
+ GitHub search can lag a few minutes behind a new issue. The dot also remembers the issues it filed, so a repeat right after filing still finds the first issue.
141
+
142
+ ### Test status
143
+
144
+ `GET /api/tickets/status?dotId=<id>` lists the test status of every issue or ticket a dot tracks, and `&ref=acme/shop%2312` answers for one. The status is computed on read from the links and the runs, and cached in the issue's row as `testStatus`:
145
+
146
+ | Status | Rule |
147
+ |---|---|
148
+ | Not tested | No linked PR has a run, and no spec links to the issue |
149
+ | Passing | The latest run of every linked PR passed, and every linked spec passed in its latest run |
150
+ | Failing | A linked PR, spec, or What to test item failed in its latest run, or an open defect links to the issue |
151
+ | Partly tested | Some What to test items of the linked PRs have not run, or a linked PR or spec has no result yet |
152
+ | Out of date | A linked PR has a newer head than its latest result |
153
+
154
+ A run that did not run its tests, or ended as an environment failure, gives no result. A defect is an issue localdost filed with `Relates to` the requirement, or an issue that mentions it and has a defect type or label. Whether a defect is still open comes from the issue poller or the `issues` webhook; until one of them reads the issue, a defect localdost just filed on GitHub counts as open, and a Jira or Linear defect is listed without counting.
155
+
156
+ With `statusLabels: true` on the GitHub tracker, a requirement issue whose status turns Passing or Failing gets a draft that sets the label `qa: passing` or `qa: failing` (the other one is removed). The draft is a `ticket_comment` action, so the default rule `ask` puts it in the Inbox, and a newer status closes an older pending draft. Other statuses write no label, so an issue keeps its last label until it is Passing or Failing again.
157
+
158
+ ### Traceability view
159
+
160
+ **Traceability** in the sidebar (under **More** on a phone) shows one table per dot, one row per requirement. It reads the same data for GitHub, Jira, and Linear:
161
+
162
+ | Column | Shows |
163
+ |---|---|
164
+ | Issue | The issue or ticket key and title. Select it to open the detail drawer |
165
+ | Type | The issue type (`Feature`, `Story`), or `Requirement` when a label made it one |
166
+ | PRs | The PRs linked to it, each with its latest verdict on hover |
167
+ | Tests | Tests passed out of tests linked: the What to test items of its PRs and the specs that name it |
168
+ | Defects | Open defects linked to it |
169
+ | Status | A dot and one of Not tested, Passing, Failing, Partly tested, Out of date, by the rules in Test status |
170
+
171
+ A line above the table sums up the requirements in plain words, for example `14 of 18 requirements passing, 2 failing, 1 not tested, 1 out of date`. The filters **Milestone**, **Status**, and **Repo** narrow the table and the line, except that the Status filter leaves the line alone. The milestone and repo come from the issue; a Jira or Linear ticket has the milestone and repo it carried in its last review.
172
+
173
+ The detail drawer shows the issue summary and acceptance criteria, the linked PRs with their last verdict, the linked tests with their latest result, the defects, and the QA review comment.
174
+
175
+ A ticket appears once the dot has read it: GitHub issues through the poller or the `issues` webhook, Jira and Linear tickets through their first review. A Bug, an issue of another type, a Jira or Linear Task, and a ticket with no matching type or label never appear as rows. With `labels.require`, neither does an issue without a required label.
176
+
177
+ **Export CSV** downloads the table with the filters you set. The file follows RFC 4180: fields with a comma, a quote, or a line break are quoted, and rows end in CRLF. A cell that starts with `=`, `+`, `-`, or `@` gets a leading single quote, so a spreadsheet shows it as text and never runs it as a formula.
178
+
179
+ **Save as report** saves the readiness of the chosen milestone as a report page of kind **Readiness**. Saving it again updates the same page. The page holds the summary line, the table, and a short note on why each requirement that is not Passing is where it is.
180
+
181
+ | Route | Returns |
182
+ |---|---|
183
+ | `GET /api/dots/:id/traceability?milestone=&status=&repo=` | Rows, the milestone and repo options, and the summary counts |
184
+ | `GET /api/dots/:id/traceability.csv?milestone=&status=&repo=` | The same rows as CSV |
185
+ | `GET /api/dots/:id/traceability/issue?ref=` | One requirement with its detail |
186
+ | `GET /api/dots/:id/readiness?milestone=` | The summary line and counts for a milestone |
187
+ | `POST /api/dots/:id/readiness/report` | Saves the readiness page, body `{ "milestone": "2026.11" }` |
188
+
189
+ The **Release notes** page in Reports (KAT-391, `GET /api/v2/release-notes`) reads the same ticket data. It groups the release note of each merged PR by the milestone of the issue the PR names, and shows the issue's title and link, so an issue the dot has not read yet appears under No milestone with its key only. Unlike the traceability table, it lists a Bug or a Task a PR names too. The fields are in [API-V2.md](API-V2.md#release-notes-kat-391).
190
+
191
+ ## Open tickets from before the dot started
192
+
193
+ A new dot reviews the open tickets that were there before it started (KAT-381), so its first day is not empty. On the first poll of a tracker, and on the next poll after a dot is made on a tracker that was polled already, the dot picks the open tickets in its scope: the most recently updated ones, at most `backfillLimit` of them in all, however many repos the tracker names. The tracker sets the limit, for example `{ "kind": "github", "repos": ["katalon-studio/product"], "labels": { "require": ["pod:agentic"] }, "backfillLimit": 40 }`. The default is 25, the most is 100, and 0 turns the backfill off. It works the same for GitHub Issues, Jira (open means a status category other than Done) and Linear (a state that is not completed or canceled).
194
+
195
+ The reviews start one at a time, oldest update first. A dot starts the next one when the review before it is done and its daily model cap is not reached, so 25 tickets never fill the queue ahead of a PR check, and a dot at its cap holds no job for each of them. The list is stored in the poll cursor store under `ticket-backfill:<dot id>:<scope>`. That row is also the mark that the dot picked: a second poll and a restart pick nothing again, and a restart in the middle goes on with the tickets left.
196
+
197
+ Each review is an ordinary new-ticket event marked `backfill`. It uses the dedupe key of a new ticket, so a ticket the dot reviewed when it was opened is not reviewed twice. Nobody asked for these reviews, so the comment (and a status label) waits in the Inbox for your approval when the ticket comment rule is ask first or act, and act does not post it on its own. A dot set to hand off hands the review off, and a dot set to act when asked skips it, so nothing is posted under either rule. The run starts with the step "Ticket from before the dot started", and Activity shows one line, "Reviewing 25 open tickets from before the dot started", until the last review starts. A ticket that closed, left the scope, was deleted, or that the Jira account can no longer see (Jira answers such a key with HTTP 400) is dropped before its turn, and the next one starts. While the dot is at its daily model cap and no review runs, the line says "25 open tickets from before the dot started wait for the daily limit". If you take a repo off the tracker, or change the tracker to another kind, the tickets left for the old scope are dropped on the next scheduler step.
198
+
199
+ A dot that was running for over an hour before its first poll is not new, so an upgrade or a re-enabled poller never replays its tickets. A tracker that names `backfillLimit` itself asks for the backfill, and it runs for a dot of any age. A dot with `backfillLimit: 0` picks nothing, and setting a limit later picks the tickets then. Lowering the limit, or setting it to 0, also cuts a list that is already going: the dot starts no more than the new limit counts, and a review already waiting in the queue ends without a model call when the limit is 0. A ticket that was cut is not picked again when you raise the limit later, because the dot already picked its set once.
200
+
201
+ After an upgrade, a dot that is more than an hour old reviews none of its open tickets until you add `backfillLimit` to its tracker (for example `"backfillLimit": 25`) and save the dot. It picks its tickets on the next poll.
202
+
203
+ ## Review a ticket on demand
204
+
205
+ Ask a dot to review any ticket now: paste a Jira, Linear, or GitHub issue link (or a key such as `TAD-3`) in chat with "check this", or send `POST /api/dots/:id/review { "ticket": "<url or key>" }`. The dot reads the ticket through the connected tracker and runs the same ticket review a new ticket gets, including the comment draft under the dot's rules (ask first by default). A review someone asks for runs even when the ticket scores too thin for the automatic path. When the tracker is not connected, or the link is on another Jira site, the dot says so. A GitHub issue link works when the issue's repo is the dot's repo or one of its GitHub Issues tracker repos (`owner/name#12` and, with one tracker repo, `#12` work as keys).
206
+
207
+ ## Defects the dot files
208
+
209
+ A bug the PR review finds becomes a defect in the dot's tracker, through the `file_defect` rule (default **Ask**, so each one waits in the Inbox). See [PR-REVIEW.md](PR-REVIEW.md#defects).
210
+
211
+ | | Linear | Jira | GitHub Issues |
212
+ |---|---|---|---|
213
+ | Where | The first team in `teamKeys`, in the project named by `projectName` when set | A Bug in the first key of `projectKeys` | The dot's repo |
214
+ | Label | `localdost` | `localdost` | `localdost` |
215
+ | Open defects read | Open issues (state not completed or canceled) of the team, and of the project when set, the 100 last updated | JQL `project = KEY AND statusCategory != Done AND labels = "localdost"`, 100 | Open issues labeled `localdost`, pull requests left out, 100 |
216
+
217
+ **Linear project.** The project is looked up by name inside the team, ignoring case. When the team has no such project, filing fails with `Linear project "<name>" not found in team <KEY>` and the approval stays in the Inbox so you can fix `projectName` and retry. Without `projectName`, the issue has no project.
218
+
219
+ **The `localdost` label.** Linear uses the team's `localdost` label, else a workspace label of that name, and creates the label in the team when neither exists. If the label cannot be read or created, the issue is filed without it. Jira sends `labels: ["localdost"]` in the create call, and retries without the label when the project's create screen has no Labels field. GitHub sends `labels: ["localdost"]`, and retries without them when the API rejects the labels (a token without triage access, for example).
220
+
221
+ **No duplicates.** Before it drafts a defect, the dot compares the bug with the open issues above. A match gets a comment with the new evidence and the head commit, once per issue and head commit, instead of a second defect. The comment is a `ticket_comment` action: with the default **Ask** rule it waits in the Inbox, and on GitHub it is a plain comment, not the sticky review comment. A tracker that cannot be read, or demo mode, falls back to drafting a new defect. Jira needs the Browse and Create permissions on the project; the new-issue search uses `POST /rest/api/3/search/jql`.
222
+
223
+ ## Loop guard
224
+
225
+ Every issue, ticket, and comment the dot posts ends with a hidden marker, `<!-- localdost:bot sig=... -->`. The signature is an HMAC of the text, made with the server secret (`LOCALDOST_SECRET_KEY`, or `secret.key` in the data folder). A webhook or poll skips content only when the signature is valid and the author is the dot's own account: the GitHub App (or the user of `GITHUB_TOKEN`), `LINEAR_BOT_USER_ID` or the Linear user the API key belongs to, the Jira account of `JIRA_BOT_ACCOUNT_ID` or the one `GET /myself` returns. Pasting a marker into an issue, a description, or a comment does nothing, because a person cannot produce the signature and a copy of a real marker comes from a different author. If you replace `secret.key` or change `LOCALDOST_SECRET_KEY`, older markers stop counting.
package/docs/VOICE.md ADDED
@@ -0,0 +1,36 @@
1
+ # Voice
2
+
3
+ You can talk to a dot in two ways: push-to-talk in Chat, and a call from the dot's page. A call runs in browser mode or in realtime mode. The server decides the mode when the call starts.
4
+
5
+ | | Browser mode | Realtime mode |
6
+ |---|---|---|
7
+ | Needs | A browser with speech recognition | An OpenAI key (Voice row in Setup, or `OPENAI_API_KEY`) and `LOCALDOST_TOKEN` on the server |
8
+ | Speech in | Web Speech API recognition in the browser | OpenAI Realtime over WebRTC, transcribed with `whisper-1` |
9
+ | Answer | The normal chat endpoint, with the dot's tools and memory | The realtime model, with the dot's call instructions |
10
+ | Speech out | `speechSynthesis` in the browser | The realtime model's voice |
11
+ | Audio goes to | Your browser vendor, depending on the browser | OpenAI |
12
+
13
+ ## Browser mode
14
+
15
+ Browser mode needs no key. The call loops three steps: the browser's speech recognition turns your words into text, the text goes to `POST /api/chat` like a typed message, and `speechSynthesis` reads the reply aloud. The mic closes while the dot thinks or speaks, so the dot does not hear itself. Because the answer comes from the normal chat, the dot can list runs, rerun tests, and use its MCP tools during the call.
16
+
17
+ Chat also has a push-to-talk mic button and a read-aloud switch that use the same browser features.
18
+
19
+ Browser support varies. Chrome, Edge, and Safari support speech recognition, and Chrome and Edge send the audio to their vendor's servers for it. In a browser without it, the mic button shows a note and you type instead. A browser also needs a secure page (HTTPS or `localhost`) before it opens the mic.
20
+
21
+ ## Realtime mode
22
+
23
+ In Setup, press **Connect** on the Voice row, paste an OpenAI API key, press **Test**, then **Connect**. Or set `OPENAI_API_KEY` on the server, which wins over a saved key. When a call starts, the app calls `POST /api/call/session`. The server asks OpenAI for a client secret that expires after 10 minutes and returns it to the app. The browser then opens a WebRTC call straight to OpenAI with that secret. `OPENAI_API_KEY` never leaves the server.
24
+
25
+ | Variable | Default |
26
+ |---|---|
27
+ | `OPENAI_REALTIME_MODEL` | `gpt-realtime-2.1` |
28
+ | `OPENAI_REALTIME_VOICE` | `marin` |
29
+
30
+ The realtime model gets short call instructions: the dot's name, mission, what it must never do, and its custom instructions. It has no tools in this version, so it cannot read runs or rerun tests. Use browser mode or chat for that.
31
+
32
+ Realtime mode also needs `LOCALDOST_TOKEN`. Without a token, anyone who reaches the server could mint OpenAI tokens on your account, so the server hides `OPENAI_API_KEY` from the call route and every call uses browser mode. When OpenAI refuses the request or cannot be reached, the call falls back to browser mode, and the server logs the reason.
33
+
34
+ ## Call receipts
35
+
36
+ When a call ends, the app sends the transcript to `POST /api/call/receipt`. The server stores it in the dot's chat as one message with the call length and every turn, so you can read the call later.
@@ -0,0 +1,45 @@
1
+ # TinyBeeAI — Product Documentation Set (v0.1 draft, 2026-10-24)
2
+
3
+ Working name: **TinyBeeAI**. Vocabulary: **Bee** = local agent on the laptop · **Hive** = our cloud control plane · **Tenant** = one user's isolated space at `<slug>.tinybee.app`.
4
+
5
+ | File | What it covers | Read it if you are… |
6
+ |---|---|---|
7
+ | `01-PRD.md` | Problem, vision, goals/non-goals, personas, tenancy model, pricing & free month, user journeys, functional + non-functional requirements, metrics, risks, release plan, open questions | Everyone; the source of truth for scope |
8
+ | `02-architecture-pairing.md` | Components and ownership matrix, data paths, keys/identity, detailed QR pairing sequence, tunnel provisioning (Cloudflare), OAuth connection flow, model access paths, presence/push, updates, security checklist | Backend / infra engineers |
9
+ | `03-local-agent.md` | The Bee: process model, installer, health check, storage, workflow engine & YAML schema, agent runtime & tool registry, local API, tunnel manager, Hive client, menu bar app, updates, edge cases | Desktop / agent engineers |
10
+ | `04-local-setup-ui.md` | The laptop setup page and menu bar app: screen-by-screen flow, copy, states, accessibility | Designers, desktop engineers |
11
+ | `05-mobile-app-ux.md` | Mobile app: principles, IA, onboarding & pairing screens, Home, Chat, Workflows (list, skills, guided editor, run detail), Connections, Activity, More, degraded states, notifications, visual system, analytics | Designers, mobile engineers |
12
+ | `06-environments-and-delivery.md` | Environments (local / staging `dots.testllms.com` on Railway, tenants `dots-<slug>.testllms.com` / prod), Railway services, env vars, PWA → APK/IPA via Capacitor, CI pipeline, test strategy, staging hygiene, observability | Everyone shipping code |
13
+ | `07-coding-agent-handoff.md` | Instructions for the coding agent: read order, ground rules, repo layout to add, 8 delivery phases with acceptance criteria, Definition of Done, reporting | **The coding agent — start here** |
14
+
15
+ ## The promise in one paragraph
16
+ A user downloads the app, picks an address, installs the Bee on a spare Mac, scans one QR code, and within a minute has a private, always-on AI agent at `https://<slug>.tinybee.app` that they configure entirely from their phone. Their account credentials and data stay on their laptop; we only provide identity, the address, the secure tunnel, notifications and (optionally) metered model access — which is why the first month is free and the plans are cheap.
17
+
18
+ ## Key decisions already taken in this draft
19
+ - macOS only (Apple Silicon + Intel). Windows is **not supported** and not scheduled. Single native binary, **no Docker** for end users.
20
+ - One Bee per tenant in v1.
21
+ - Hive stores **no user content, no third-party tokens, no workflow bodies**.
22
+ - Cloudflare Tunnel behind a provider interface (swappable for Tailscale/own relay).
23
+ - Sends/writes require approval by default; reads are automatic.
24
+ - Trial lapse → Bee keeps running locally; only remote access and push pause.
25
+
26
+ ## Relationship to localdost (this repo)
27
+ localdost is the local agent app: one Node process + SQLite, "dots" that watch and act, a rule gate per action kind, and approvals in a phone Inbox. In TinyBee terms, **a running localdost instance is the Bee**. The TinyBee layer adds what localdost does not have yet: Hive (tenant identity, pairing, Cloudflare tunnel provisioning, push relay, metering) and the consumer mobile app with QR pairing. Map when reading these docs:
28
+
29
+ | TinyBee doc term | localdost term |
30
+ |---|---|
31
+ | Bee | the localdost server process |
32
+ | Workflow | a dot + its Watch |
33
+ | Skill | role preset |
34
+ | Permission scope (auto / ask / deny) | rule gate (act / act when asked / ask first / hand to you) |
35
+ | Approval card | Inbox item |
36
+ | Connection | integration credential (GitHub, Jira, Linear…) |
37
+
38
+ ## How this repo is used
39
+ The human owner writes and maintains these docs; a coding agent implements them in this repository (`07-coding-agent-handoff.md`). Build and test target is the staging PWA at `https://dots.testllms.com` (Railway); APK/IPA are packaged from the same client with Capacitor after PWA verification (`06-environments-and-delivery.md`).
40
+
41
+ ## Suggested next steps
42
+ 1. Review open questions at the end of `01-PRD.md` and `05-mobile-app-ux.md`.
43
+ 2. Prototype pairing end-to-end (install → QR → tunnel → `/health` from phone) before any workflow features; it is the riskiest and most differentiating part.
44
+ 3. Begin Google OAuth app verification immediately (long lead time).
45
+ 4. Low-fi mobile wireframes for onboarding, Home and the guided editor; usability-test the pairing flow with 5 non-technical users.