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,83 @@
1
+ // Railway Infrastructure as Code for localdost. Preview with `railway config plan`, then run
2
+ // `railway config apply --yes`. docs/DEPLOY.md has the full recipe. The project is `localdost`
3
+ // (workspace "Huy Dao's Projects", next to `superapp`); both services below live in it.
4
+ //
5
+ // There is no build target here. Railway builds the root Dockerfile, and its last stage is the
6
+ // `runner` target (Playwright image with browsers), so hosted test runs work.
7
+ // No `source` either: `railway up` or a GitHub link supplies the code.
8
+ import { defineRailway, preserve, project, service, volume } from 'railway/iac';
9
+
10
+ export default defineRailway(() => {
11
+ // SQLite, VAPID keys, saved credentials, and run artifacts live here.
12
+ const data = volume('qadots-data', { sizeMB: 5120 });
13
+
14
+ const qadots = service('qadots', {
15
+ start: 'node dist/index.js',
16
+ healthcheck: '/',
17
+ healthcheckTimeout: 60,
18
+ // SQLite needs exactly one replica.
19
+ replicas: 1,
20
+ deploy: {
21
+ // Refuse to start without the volume, so a missing mount cannot silently write to the container disk.
22
+ requiredMountPath: '/data',
23
+ // Restart a crashed server a few times, then stop and show the failure instead of looping.
24
+ restartPolicyType: 'ON_FAILURE',
25
+ restartPolicyMaxRetries: 5,
26
+ // Seconds the old instance gets to finish SQLite writes after SIGTERM.
27
+ drainingSeconds: 10,
28
+ },
29
+ env: {
30
+ HOST: '0.0.0.0',
31
+ PORT: '4319',
32
+ QADOTS_DATA_DIR: '/data',
33
+ QADOTS_POLL: '1',
34
+ QADOTS_LLM: 'anthropic',
35
+ // Railway mounts volumes as root. The container starts as root, and its entrypoint gives /data
36
+ // to the qadots user and drops to it before the server starts (KAT-209).
37
+ RAILWAY_RUN_UID: '0',
38
+ // Secrets are set with `railway variable set NAME --stdin`; apply keeps the stored value.
39
+ QADOTS_TOKEN: preserve(),
40
+ GITHUB_TOKEN: preserve(),
41
+ ANTHROPIC_API_KEY: preserve(),
42
+ LINEAR_API_KEY: preserve(),
43
+ // TinyBee: this service is the staging Bee (`bee-dev`). The Hive URL is the private address of the hive service.
44
+ TINYBEE_ENV: 'staging',
45
+ TINYBEE_HIVE_URL: 'http://hive.railway.internal:4330',
46
+ },
47
+ volumeMounts: { '/data': data },
48
+ });
49
+
50
+ // TinyBee (docs/tinybee/06-environments-and-delivery.md section 1.1). The `qadots` service above doubles as
51
+ // `bee-dev`, the cloud-hosted Bee of tenant `dev`; the Hive control plane is a service of its own. The PWA
52
+ // reaches Hive through the Bee's /api/hive proxy (TINYBEE_HIVE_URL), so one origin serves both.
53
+ const hiveData = volume('hive-data', { sizeMB: 1024 });
54
+ const hive = service('hive', {
55
+ start: 'node dist/hive/index.js',
56
+ healthcheck: '/api/hive/health',
57
+ healthcheckTimeout: 60,
58
+ replicas: 1,
59
+ deploy: {
60
+ requiredMountPath: '/data',
61
+ restartPolicyType: 'ON_FAILURE',
62
+ restartPolicyMaxRetries: 5,
63
+ drainingSeconds: 10,
64
+ },
65
+ env: {
66
+ HOST: '0.0.0.0',
67
+ PORT: '4330',
68
+ TINYBEE_ENV: 'staging',
69
+ TINYBEE_TENANT_HOST: 'dots-{slug}.testllms.com',
70
+ HIVE_DATA_DIR: '/data',
71
+ RAILWAY_RUN_UID: '0',
72
+ // Set with `railway variable set NAME --stdin --service hive`. Unset CF_* keeps the mock tunnel provider.
73
+ HIVE_JWT_PRIVATE_KEY: preserve(),
74
+ HIVE_JWT_KID: preserve(),
75
+ CF_ACCOUNT_ID: preserve(),
76
+ CF_ZONE_ID: preserve(),
77
+ CF_API_TOKEN: preserve(),
78
+ },
79
+ volumeMounts: { '/data': hiveData },
80
+ });
81
+
82
+ return project('localdost', { resources: [data, qadots, hiveData, hive] });
83
+ });
@@ -0,0 +1,13 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2023",
4
+ "lib": ["ES2023"],
5
+ "module": "NodeNext",
6
+ "moduleResolution": "NodeNext",
7
+ "strict": true,
8
+ "noEmit": true,
9
+ "skipLibCheck": true,
10
+ "types": []
11
+ },
12
+ "include": ["railway.ts"]
13
+ }
package/AGENTS.md ADDED
@@ -0,0 +1,102 @@
1
+ # Set up localdost for a repo
2
+
3
+ These are the steps a coding agent follows when a person asks it to set up localdost for their repo, and to host it when they ask for that. Run each step, read its output, and fix what it reports before the next step. The person's repo is the "target repo" below. localdost itself lives in a separate checkout.
4
+
5
+ ## Safety rules
6
+
7
+ - Never ask the person to paste a token, key, or password into the chat. When a step needs a secret, ask them to export it in their own shell, or to run the login command themselves.
8
+ - Never print a secret. Do not run `printenv` or `env` without a variable name, `railway variable list --kv`, or `gh auth token` on its own. Pipe a secret straight into the command that needs it (`gh auth token | railway variable set GITHUB_TOKEN --stdin --service localdost`).
9
+ - Never write a secret into a file. `.env.localdost` holds only references: `${env:NAME}` reads the person's shell, `${cmd:gh auth token}` runs a command at start. Keep it that way.
10
+ - Never commit `.env.localdost` or `.localdost/data/`. `localdost init` adds both to `.gitignore`. `.localdost/config.json` holds no secrets and is safe to commit.
11
+ - Set `LOCALDOST_TOKEN` before the server is reachable from the internet (a tunnel, a cloud host). Without it the API has no auth.
12
+ - Leave the dot's rules at their defaults. Ticket comments ask first. Change a rule to `act` only when the person asks for it.
13
+ - Logins open a browser: `gh auth login`, `claude auth login`, `railway login`. Ask the person to run them, then continue.
14
+
15
+ ## Steps
16
+
17
+ ### 1. Install localdost
18
+
19
+ localdost needs Node 24. If `~/localdost` does not exist, clone and build it once, then put the `localdost` command on the PATH:
20
+
21
+ ```bash
22
+ git clone https://github.com/duonghaijoe/localdost ~/localdost
23
+ cd ~/localdost
24
+ npm ci
25
+ npm run build
26
+ npm link
27
+ ```
28
+
29
+ When `npm link` is not allowed, use `node ~/localdost/bin/localdost.js` wherever this file says `localdost`.
30
+
31
+ ### 2. Init in the target repo
32
+
33
+ ```bash
34
+ cd <target repo>
35
+ localdost init --yes
36
+ ```
37
+
38
+ `init` reads the GitHub repo and default branch from `git remote get-url origin`, the test command and Playwright config from `package.json`, checks `gh auth token`, checks the Claude CLI login with a `claude -p` round trip (else uses `ANTHROPIC_API_KEY` from the shell), and picks Linear or Jira when `LINEAR_API_KEY` or `JIRA_*` is exported. It writes `.env.localdost` and `.localdost/config.json`, and creates the first dot in `.localdost/data/`. Running it again updates the same dot.
39
+
40
+ Pass flags for what it cannot detect:
41
+
42
+ | Need | Flag |
43
+ |---|---|
44
+ | Linear team | `--tracker linear --linear-team ENG` |
45
+ | Jira project | `--tracker jira --jira-url https://acme.atlassian.net --jira-project SHOP` |
46
+ | GitHub Issues | `--tracker github`, with `--tracker-repos owner/name` for the repo whose issues the dot reviews and where it files defects, `--require-labels pod:agentic` to review only issues with that label, and `--milestone 2026.11` |
47
+ | No tracker | `--tracker none` |
48
+ | A test command other than `npx playwright test` | `--command "npx playwright test --project=chromium"` |
49
+ | The app URL the tests run against | `--base-url http://localhost:3000` |
50
+ | A fixed port | `--port 4319` (default: 4319, or the next free port) |
51
+
52
+ The test command runs without a shell, so `&&` and pipes do not work in it. Put install and build steps in the dot's Setup steps (`runner.setup`), for example `npm ci && npx playwright install chromium && npm run build`, and use **Try it** in the dot dialog to check both.
53
+
54
+ ### 3. Doctor
55
+
56
+ ```bash
57
+ localdost doctor
58
+ ```
59
+
60
+ It prints one line per service. `FAIL` lines carry a `fix:` command. Run each fix, or ask the person to run it when it is a login or needs a key, then run `localdost doctor` again. Repeat until it exits 0. `warn` lines are optional services (Slack, voice, Docker, a public URL) and do not block. `localdost doctor --json` gives the same checks as JSON.
61
+
62
+ ### 4. Start
63
+
64
+ ```bash
65
+ localdost start
66
+ ```
67
+
68
+ Run it in the background. It loads `.env.localdost`, resolves the references, and serves the app on `http://localhost:<PORT>`. Check that `curl -s http://localhost:<PORT>/api/dots` lists the dot. GitHub and the tracker are polled every 60 seconds, so no webhook is needed. The first poll of a new dot takes its 5 most recently updated open PRs, and their PR comment and check wait for approval unless the repo's PR scope names authors, a team or issue labels; after that, only new work.
69
+
70
+ ### 5. Deploy, only when the person asks to host it
71
+
72
+ Skip this step unless the person asked to host or deploy localdost (for example "and host it on Railway"). Do not create cloud projects, services, or volumes on your own. When they did ask, follow the Railway section of `~/localdost/docs/DEPLOY.md`. It needs Railway CLI 5.42.1 or newer (`railway --version`). Run from `~/localdost`:
73
+
74
+ ```bash
75
+ cd ~/localdost
76
+ railway login # the person runs this one, it opens a browser
77
+ railway init --name localdost
78
+ railway config plan # preview what .railway/railway.ts creates
79
+ railway config apply --yes # service, 5 GB volume at /data, non-secret variables
80
+
81
+ # Secrets from stdin, never printed. Set only the ones the person has.
82
+ openssl rand -hex 24 | railway variable set LOCALDOST_TOKEN --stdin --skip-deploys --service localdost
83
+ gh auth token | railway variable set GITHUB_TOKEN --stdin --skip-deploys --service localdost
84
+ printenv ANTHROPIC_API_KEY | railway variable set ANTHROPIC_API_KEY --stdin --skip-deploys --service localdost
85
+ printenv LINEAR_API_KEY | railway variable set LINEAR_API_KEY --stdin --skip-deploys --service localdost
86
+
87
+ railway up --detach --service localdost
88
+ railway domain --port 4319 --service localdost
89
+ ```
90
+
91
+ Then create the dot on the hosted server with the domain `railway domain` printed:
92
+
93
+ ```bash
94
+ railway run --service localdost node bin/localdost.js init --yes --dir <target repo> --server https://<railway domain>
95
+ railway run --service localdost node bin/localdost.js doctor --dir <target repo>
96
+ ```
97
+
98
+ Test runs work on Railway: the default image is the `runner` target with browsers, and the first run of each cloned repo installs its dependencies. The real limits are memory and disk. Chromium needs at least 2 GB of RAM, and the volume is 5 GB. Tell the person both.
99
+
100
+ ## Done
101
+
102
+ Tell the person, in a few lines: the URL, the dot name, the doctor result, and any `warn` line they may want to fix. Do not include any secret value.
package/Dockerfile ADDED
@@ -0,0 +1,108 @@
1
+ # syntax=docker/dockerfile:1
2
+ #
3
+ # localdost image. Two targets:
4
+ # app Node 24 slim. Serves the API and the PWA. No browsers, so demo and local
5
+ # Playwright runs need either the runner target or docker runner mode.
6
+ # runner The same app on the pinned Playwright image, so local and demo runs have
7
+ # Chromium, Firefox, and WebKit installed. It is the last stage, so a plain
8
+ # `docker build` and Railway (which builds the last stage) produce it.
9
+ #
10
+ # docker build --target app -t qadots:app .
11
+ # docker build --target runner -t qadots:runner .
12
+ #
13
+ # Keep runner last. Reordering the stages changes what Railway deploys (test/runner-default-install.test.ts).
14
+ #
15
+ # PLAYWRIGHT_VERSION must match node_modules/@playwright/test. A mismatch fails at run
16
+ # time with "Executable doesn't exist". Renovate bumps both together (renovate.json).
17
+
18
+ ARG NODE_VERSION=24
19
+ ARG PLAYWRIGHT_VERSION=1.63.0
20
+
21
+ # All dependencies, for the build and for the runner target.
22
+ FROM node:${NODE_VERSION}-bookworm-slim AS deps
23
+ WORKDIR /app
24
+ ENV PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD=1
25
+ COPY package.json package-lock.json .npmrc ./
26
+ RUN npm ci --no-audit --no-fund
27
+
28
+ # Server (tsc to dist/) and client (vite to dist/web).
29
+ FROM deps AS build
30
+ COPY tsconfig.json tsconfig.client.json vite.config.ts ./
31
+ COPY src ./src
32
+ COPY client ./client
33
+ COPY scripts/copy-assets.mjs ./scripts/
34
+ RUN npx tsc -p tsconfig.json && node scripts/copy-assets.mjs && npx vite build
35
+
36
+ # Production dependencies only, for the app target.
37
+ FROM node:${NODE_VERSION}-bookworm-slim AS prod-deps
38
+ WORKDIR /app
39
+ ENV PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD=1
40
+ COPY package.json package-lock.json .npmrc ./
41
+ RUN npm ci --omit=dev --no-audit --no-fund
42
+
43
+ # App target. LOCALDOST_DATA_DIR holds the SQLite database, VAPID keys, and artifacts.
44
+ FROM node:${NODE_VERSION}-bookworm-slim AS app
45
+ # HOST=0.0.0.0 needs LOCALDOST_TOKEN: without a token the server refuses a non-loopback address.
46
+ ENV NODE_ENV=production \
47
+ HOST=0.0.0.0 \
48
+ PORT=4319 \
49
+ LOCALDOST_DATA_DIR=/data
50
+ # git: GitHub checkouts for local runs. tini: reaps Playwright and git child processes.
51
+ RUN apt-get update \
52
+ && apt-get install -y --no-install-recommends ca-certificates git tini \
53
+ && rm -rf /var/lib/apt/lists/*
54
+ WORKDIR /app
55
+ COPY --from=prod-deps --chown=root:root /app/node_modules ./node_modules
56
+ COPY --from=build --chown=root:root /app/dist ./dist
57
+ COPY --chown=root:root package.json ./
58
+ # demo/ holds the sample shop and payloads for LOCALDOST_DEMO=1. The client is in dist/web.
59
+ COPY --chown=root:root demo ./demo
60
+ # Guides for the in-app docs viewer (#/docs).
61
+ COPY --chown=root:root docs ./docs
62
+ COPY --chown=root:root README.md ./
63
+ RUN mkdir -p /data && chown node:node /data
64
+ USER node
65
+ # /data is the volume (compose.yml and docs/DEPLOY.md mount it). No VOLUME line: Railway's builder refuses it.
66
+ EXPOSE 4319
67
+ # /api/setup sits behind the bearer token when LOCALDOST_TOKEN is set, so the probe sends it.
68
+ HEALTHCHECK --interval=30s --timeout=5s --start-period=20s --retries=3 \
69
+ CMD ["node", "-e", "fetch('http://127.0.0.1:'+(process.env.PORT||4319)+'/api/setup',{headers:process.env.LOCALDOST_TOKEN?{authorization:'Bearer '+process.env.LOCALDOST_TOKEN}:{}}).then(r=>process.exit(r.ok?0:1),()=>process.exit(1))"]
70
+ ENTRYPOINT ["/usr/bin/tini", "--"]
71
+ CMD ["node", "dist/index.js"]
72
+
73
+ # Runner target, and the default because it is the last stage. Railway builds the last stage.
74
+ # The Playwright v1.63 noble image ships Node 24 and the browsers in /ms-playwright.
75
+ FROM mcr.microsoft.com/playwright:v${PLAYWRIGHT_VERSION}-noble AS runner
76
+ # HOST=0.0.0.0 needs LOCALDOST_TOKEN: without a token the server refuses a non-loopback address.
77
+ ENV NODE_ENV=production \
78
+ HOST=0.0.0.0 \
79
+ PORT=4319 \
80
+ LOCALDOST_DATA_DIR=/data \
81
+ PLAYWRIGHT_BROWSERS_PATH=/ms-playwright
82
+ RUN apt-get update \
83
+ && apt-get install -y --no-install-recommends ca-certificates git tini \
84
+ && rm -rf /var/lib/apt/lists/*
85
+ # The server and the test runs it spawns run as qadots, which owns /app and /data. The browsers in
86
+ # /ms-playwright stay owned by root and are made readable by every user.
87
+ RUN useradd --system --create-home --home-dir /home/qadots --uid 10001 --shell /usr/sbin/nologin qadots \
88
+ && mkdir -p /app /data \
89
+ && chown qadots:qadots /app /data \
90
+ && chmod -R a+rX /ms-playwright
91
+ WORKDIR /app
92
+ # Full node_modules: the runner spawns `npx playwright test`, and generated specs import @playwright/test from here.
93
+ COPY --from=deps --chown=qadots:qadots /app/node_modules ./node_modules
94
+ COPY --from=build --chown=qadots:qadots /app/dist ./dist
95
+ COPY --chown=qadots:qadots package.json ./
96
+ COPY --chown=qadots:qadots demo ./demo
97
+ # Guides for the in-app docs viewer (#/docs).
98
+ COPY --chown=qadots:qadots docs ./docs
99
+ COPY --chown=qadots:qadots README.md ./
100
+ # Railway mounts the volume as root and starts the container as root (RAILWAY_RUN_UID=0). The
101
+ # entrypoint then hands /data to qadots and drops to that user. Docker and Compose start as qadots.
102
+ COPY --chmod=0755 scripts/docker-entrypoint.sh /usr/local/bin/qadots-entrypoint
103
+ USER qadots
104
+ EXPOSE 4319
105
+ HEALTHCHECK --interval=30s --timeout=5s --start-period=20s --retries=3 \
106
+ CMD ["node", "-e", "fetch('http://127.0.0.1:'+(process.env.PORT||4319)+'/api/setup',{headers:process.env.LOCALDOST_TOKEN?{authorization:'Bearer '+process.env.LOCALDOST_TOKEN}:{}}).then(r=>process.exit(r.ok?0:1),()=>process.exit(1))"]
107
+ ENTRYPOINT ["/usr/bin/tini", "--", "/usr/local/bin/qadots-entrypoint"]
108
+ CMD ["node", "dist/index.js"]
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Huy Tieu
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,276 @@
1
- # Temporary Holding Version
1
+ <div align="center">
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ # localdost
4
+
5
+ ### Always-on QA agents that watch every merge, ticket, and prod URL
6
+
7
+ [Get started](#get-started) · [Overview](#overview) · [Architecture](#architecture) · [Features](#features) · [Docs](#docs) · [Contributing](#contributing)
8
+
9
+ [![CI](https://github.com/duonghaijoe/localdost/actions/workflows/ci.yml/badge.svg)](https://github.com/duonghaijoe/localdost/actions/workflows/ci.yml)
10
+ [![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
11
+ [![Status: alpha](https://img.shields.io/badge/status-alpha-orange.svg)](#features)
12
+
13
+ Self-hosted. Runs with no accounts in demo mode. Bring your own Claude login or Anthropic key for real verdicts.
14
+
15
+ </div>
16
+
17
+ ![localdost catching a checkout bug on a real PR, merge and phone alert](docs/demos/hero.gif)
18
+
19
+ <sub>Real runs on a demo shop, sped up and trimmed as captioned. Full walkthrough: [localdost-walkthrough.mp4](docs/demos/localdost-walkthrough.mp4). Recording notes: [docs/demos](docs/demos/README.md).</sub>
20
+
21
+ ## Overview
22
+
23
+ localdost gives your team a few QA helpers that never sleep. Each helper is a **dot**. A dot reads every pull request, every merge, every new ticket, and your health checks, runs your tests, and tells you on your phone when something needs you. Think of a colleague who reads every PR and every new Jira ticket, and texts you only when checkout breaks.
24
+
25
+ Every outward action, such as a PR comment, a check run, or a ticket comment, passes a rule gate first. You decide per action kind whether the dot acts, acts only when asked, asks first, or hands the job to you. Approvals wait in the Inbox of the phone app.
26
+
27
+ localdost is one Node process and one SQLite file on your machine or your server. Without credentials, every integration runs in demo mode: outward actions go to an outbox that you can read in the app, and a mock model writes canned verdicts.
28
+
29
+ ### Dots and Watches
30
+
31
+ A dot holds one **Watch**: a GitHub repo, a Jira or Linear project, the production URLs it is responsible for, and a test command. The Watch also carries the dot's mission, when to notify you, and what it must never do, in your own words. Role presets (product area, QA lead, release guard, ticket reviewer, prod watcher) fill in the mission and the rules for a common job and switch on the stages it needs. One server runs many dots, and each dot has its own memory, rules, and chat.
32
+
33
+ ### PR review with what to test
34
+
35
+ On every PR and every merge, the dot scopes the changed lines, maps them to impact areas, collects signals (untouched tests, removed assertions, changed routes, selector drift), and applies ten QA lenses such as money, auth, dates, and migrations. A reviewer model pass and a verifier model pass then produce risks with code citations and a **What to test** checklist. The review lands in one sticky PR comment and in a check run with line annotations. Ticking a checklist item in the comment records a manual test result on the run. Details: [docs/PR-REVIEW.md](docs/PR-REVIEW.md).
36
+
37
+ ![PR review: specs run live, the review flags a double discount, the sticky comment on GitHub](docs/demos/pr-review.gif)
38
+
39
+ ### Live test runs
40
+
41
+ After a merge, the dot picks the Playwright specs that match the changed paths plus your smoke tests, runs them, and retries failures to separate flaky tests from real breaks. The run page streams each step live, shows browser frames during the run, and keeps screenshots, traces, videos, and the JSON report. Runs execute in your checkout, in a Docker container, or against the bundled sample shop. Details: [docs/SANDBOX.md](docs/SANDBOX.md).
42
+
43
+ ![After a merge: the full suite, retries, and the failing spec opened from the push](docs/demos/merge-alert.gif)
44
+
45
+ ### AI-Vision cases
46
+
47
+ A dot can also run natural-language browser cases next to Playwright, on an AI-Vision server (Veesan) or the open-source Midscene CLI. Each What to test item from the PR review that has no existing test becomes one case, and test ideas from a ticket review of a ticket the PR names fill the rest. The cases run on `pr_check` and `post_merge`, and their verdicts, screenshots, and report links merge into the same run and checklist as the Playwright results. Details: [docs/SANDBOX.md](docs/SANDBOX.md#ai-vision-cases).
48
+
49
+ ### Ticket review
50
+
51
+ A new Jira or Linear ticket gets a score for how ready it is. Tickets that score 30 or more get a review: risks, open questions, gaps in the acceptance criteria, test ideas, and existing tests that the change may break. The dot drafts a ticket comment, and by default the draft waits in your Inbox. It also checks the test cases and automated specs you already have, from any ticket, that the new ticket changes: a case that needs an update gets a draft version, a case the ticket makes obsolete gets a retire draft in your Inbox, and nothing is changed until you decide. Details: [docs/TRACKERS.md](docs/TRACKERS.md).
52
+
53
+ ![Ticket review: the draft is edited and approved in the Inbox, then read back from Linear](docs/demos/ticket-approval.gif)
54
+
55
+ ### Outage watch
56
+
57
+ HTTP probes and browser probes check your production URLs on an interval. Three failures in a row open an outage: the dot looks at merges from the last 24 hours, names a suspected cause, and pushes a high-urgency alert. A recovery notice follows when the probe passes again. Atlassian Statuspage URLs of your vendors feed the same flow. A daily digest sums up runs, flaky specs, tickets, and incidents.
58
+
59
+ ### Ask-first rules and the Inbox
60
+
61
+ Each action kind has one of four levels: `act`, `act_when_asked`, `ask`, or `hand_off`. The defaults let a dot run tests, post PR comments and check runs, and send pushes on its own. Ticket comments, new issues, MCP tools that change data, and report edits ask first. Reverts go to a person. An auto-review pass can move an `act` to `ask` when a draft looks risky. In the Inbox you approve, edit, or reject the exact draft. A pending approval expires after 24 hours.
62
+
63
+ ### Phone app with chat and calls
64
+
65
+ The app is a React PWA that you add to your Home Screen. It has Dots, Feed, Inbox, Chat, Reports, and Settings. Chat with a dot about its runs, ask it to rerun tests, or ask whether prod is up. Push-to-talk and read-aloud use browser speech. With `OPENAI_API_KEY` set, a call uses OpenAI Realtime over WebRTC instead. Details: [docs/VOICE.md](docs/VOICE.md).
66
+
67
+ ### Slack
68
+
69
+ Mention the bot in a thread and the dot named in the message, or the dot that owns the channel, answers in the thread. Outage and digest notices post to the dot's channel. Slack connects over Socket Mode, so it needs no public URL. Details: [docs/SLACK.md](docs/SLACK.md).
70
+
71
+ ### MCP connections
72
+
73
+ Connect any MCP server over HTTP or stdio and attach it to a dot. Read-only tools run directly in chat. A tool that changes data is an outward action and goes through the rule gate like a PR comment. Presets add an AI-Vision server (Veesan) or the open-source Midscene MCP server in one step, with only the env var names they declare, so a dot's chat can find cases, start a run after approval, and read the verdicts. Details: [docs/CONNECTIONS.md](docs/CONNECTIONS.md).
74
+
75
+ ### Reports
76
+
77
+ Save any run or digest as a report page. Edit it in the app, or chat with the dot about the page and let it propose edits, which ask first by default.
78
+
79
+ ## Architecture
80
+
81
+ ```mermaid
82
+ flowchart LR
83
+ subgraph Triggers
84
+ GHW[GitHub webhook]
85
+ GHP[GitHub poller]
86
+ TRW[Jira and Linear webhooks]
87
+ LNP[Linear poller]
88
+ PRB[HTTP and browser probes]
89
+ STP[Statuspage poller]
90
+ SCH[Digest scheduler]
91
+ end
92
+ GHW --> NRM[webhooks.ts: verify, normalize, dedupe]
93
+ GHP --> NRM
94
+ TRW --> NRM
95
+ LNP --> NRM
96
+ NRM --> Q[(SQLite job queue)]
97
+ PRB --> Q
98
+ STP --> Q
99
+ SCH --> Q
100
+ Q --> FL[Flows: pr_check, post_merge, ci_failure, ticket_review, outage, recovery, digest, rerun]
101
+ FL --> REV[Review prep: scope, signals, lenses, impact]
102
+ REV --> LLM[Model backend: claude-cli, codex-cli, anthropic, mock]
103
+ FL --> LLM
104
+ FL --> RUN[Test runner: local, docker, demo, AI-Vision]
105
+ RUN --> ART[(Artifacts in the data folder)]
106
+ FL --> GATE{Rules gate}
107
+ GATE -- act --> EXT[GitHub, Jira, Linear, Slack]
108
+ GATE -- ask --> INB[Inbox approvals]
109
+ GATE -- no credentials --> OUT[(Outbox)]
110
+ FL --> PUSH[Web push and ntfy]
111
+ FL --> BUS[Live event bus]
112
+ BUS --> SSE[GET /api/live]
113
+ SSE --> PWA[React PWA]
114
+ PWA --> CHAT[POST /api/chat]
115
+ CHAT --> LLM
116
+ CHAT --> MCP[MCP connections]
117
+ PWA --> CALL[POST /api/call/session]
118
+ ```
119
+
120
+ Every trigger becomes a `TriggerEvent` with a dedupe key, so a webhook delivery and a poll of the same commit or ticket queue one job. The queue lives in SQLite and runs two jobs at a time. Each running job holds a lease. When the server stops mid-run, the run ends as interrupted and you can rerun it. The server code is in `src/`, the PWA in `client/`, and the build contract in [SPEC.md](SPEC.md).
121
+
122
+ ## Get started
123
+
124
+ localdost needs Node 24.
125
+
126
+ ### Demo in one command
127
+
128
+ ```bash
129
+ git clone https://github.com/duonghaijoe/localdost && cd localdost && npm install && npm run demo
130
+ ```
131
+
132
+ Open http://localhost:4319. The demo seeds a dot named "Checkout" that watches `demo/shop-web`, Jira project `SHOP`, and a sample shop on http://localhost:4320. In the app, open Settings and press a Simulate button: PR merged, PR opened, ticket created, outage, or CI failure. A simulated merge runs real Playwright tests against the sample shop. One spec passes and one fails on a seeded bug, and the dot reports the failure with a verdict. The same simulations work from a shell:
133
+
134
+ ```bash
135
+ curl -X POST http://localhost:4319/api/simulate/pr_merged
136
+ ```
137
+
138
+ ### Start a team server
139
+
140
+ One person sets a team server up, once. It takes four commands and ends in the setup flow of the app:
141
+
142
+ ```bash
143
+ git clone https://github.com/duonghaijoe/localdost && cd localdost
144
+ npm ci
145
+ npm run build
146
+ LOCALDOST_TOKEN=$(openssl rand -hex 24) LOCALDOST_PUBLIC_URL=https://localdost.example.com npm start
147
+ ```
148
+
149
+ `LOCALDOST_TOKEN` is the token every person needs to open the server. Keep it where you can read it again. `LOCALDOST_PUBLIC_URL` is the https address your team opens, and the address GitHub sends webhooks to. Leave it out and the dot polls GitHub instead, which works but misses CI failures, preview deployments, and `/localdost review` comments. With no preview of a PR, its tests run against the dot's base URL (a build of shared QA work), and the report says so; the dot setting `prTestTarget` can skip those tests instead, see [PR tests without a preview](docs/SETUP.md#pr-tests-without-a-preview). With a token set, `npm start` listens on all interfaces. Put https in front of it, or use a tunnel. [docs/DEPLOY.md](docs/DEPLOY.md) covers Railway, Docker Compose, and a tunnel to your own machine.
150
+
151
+ Back up the data folder before the pilot starts: the database, `secret.key`, and `vapid.json`. A backup without `secret.key` cannot decrypt the tokens saved in Setup. [Back up and restore](docs/DEPLOY.md#back-up-and-restore) has the commands for Docker Compose, Node with a start script, Railway, and Kubernetes, and `localdost doctor --restore-check <folder>` checks a backup. [Upgrade](docs/DEPLOY.md#upgrade) covers a new tag: pick it, read the CHANGELOG, wait until `localdost doctor --idle` exits 0, back up, switch, and roll back from that backup if needed.
152
+
153
+ Open the address. A new server shows the Join screen, which also asks **Admin? Enter the server token**: paste `LOCALDOST_TOKEN` and the **setup flow** opens: Welcome (a team server or your laptop, with a check of the token and the public URL), Event delivery, Model, GitHub, Repos with a role and a PR scope each, Tracker (GitHub Issues first), Tests per repo, Slack, Rules with a shadow week, Create dot, and a first review that posts nothing until you say so. A reload keeps you in the flow, and the **Getting started** link in the sidebar brings you back to it until you finish or close it. Each step is described in [docs/SETUP.md](docs/SETUP.md#start-a-team-server).
154
+
155
+ ### Connect your services in the app
156
+
157
+ Start the server, open the app, and open **Setup**. Each service has a **Connect** button: sign in to the model with your Claude subscription or an Anthropic API key, connect GitHub with the GitHub CLI login, a GitHub App that Setup creates for you, or a token, and paste keys for Linear, Jira, Slack, and voice. **Test** checks each one before you save it. Saved keys are encrypted in the data folder and never sent back to the browser. Environment variables still work and win over saved values. The guides open inside the app: [docs/SETUP.md](docs/SETUP.md).
158
+
159
+ ### Set up with a coding agent in one prompt
160
+
161
+ Open a coding agent (Claude Code, Codex, Cursor) in the repo you want a dot for, and paste:
162
+
163
+ ```text
164
+ Set up localdost for this repo. Clone https://github.com/duonghaijoe/localdost to ~/localdost if it is not there, then follow ~/localdost/AGENTS.md. Never ask me to paste a secret into the chat: tell me which command to run or which variable to export.
165
+ ```
166
+
167
+ The agent follows [AGENTS.md](AGENTS.md): it builds localdost, runs `localdost init --yes` in your repo, fixes what `localdost doctor` reports, and starts the server. It stops for you at each browser login (`gh auth login`, `claude auth login`). Add "and host it on Railway" to the prompt to deploy it too.
168
+
169
+ The same steps by hand:
170
+
171
+ ```bash
172
+ cd ~/localdost && npm ci && npm run build && npm link # once
173
+ cd ~/code/your-repo
174
+ localdost init # detects the repo, tests, GitHub, Claude, tracker; writes .env.localdost with no secrets
175
+ localdost doctor # one line per service with a fix command; exits 1 until the required ones work
176
+ localdost start # http://localhost:4319
177
+ ```
178
+
179
+ `localdost init` turns on poll mode, so GitHub and Linear work without a public webhook URL.
180
+
181
+ ### Docker or Railway
182
+
183
+ ```bash
184
+ LOCALDOST_TOKEN=$(openssl rand -hex 24) docker compose up -d --build
185
+ ```
186
+
187
+ The image listens on all interfaces, so it needs `LOCALDOST_TOKEN` and refuses to start without one. Keep the token in `.env` next to `compose.yml` so you can read it again. Railway, Docker Compose with test runs, and a cloudflared tunnel to your own machine are in [docs/DEPLOY.md](docs/DEPLOY.md).
188
+
189
+ ### Network and token
190
+
191
+ Without `LOCALDOST_TOKEN`, the server listens on `127.0.0.1` only, whatever the default `HOST` would be. In that state `/api` also answers only requests whose `Host` header names a loopback address, so a tunnel or a DNS-rebinding page gets 403. A non-loopback `HOST` such as `0.0.0.0` without a token stops the server at boot. With a token set and `HOST` unset, the server listens on `0.0.0.0`, and every `/api` call needs `Authorization: Bearer <token>`. Set the token before you open the server to your LAN, a tunnel, or the internet.
192
+
193
+ ### Docs
194
+
195
+ | Topic | Doc |
196
+ |---|---|
197
+ | The setup flow of a team server, connecting services in the app, every setting, model backends, poll mode, troubleshooting | [docs/SETUP.md](docs/SETUP.md) |
198
+ | GitHub App, PAT, or polling | [docs/GITHUB.md](docs/GITHUB.md) |
199
+ | Jira and Linear | [docs/TRACKERS.md](docs/TRACKERS.md) |
200
+ | Slack | [docs/SLACK.md](docs/SLACK.md) |
201
+ | MCP connections | [docs/CONNECTIONS.md](docs/CONNECTIONS.md) |
202
+ | Test runners, live view, artifacts, fork safety | [docs/SANDBOX.md](docs/SANDBOX.md) |
203
+ | Voice | [docs/VOICE.md](docs/VOICE.md) |
204
+ | PR review for users | [docs/PR-REVIEW.md](docs/PR-REVIEW.md) |
205
+ | Hosting | [docs/DEPLOY.md](docs/DEPLOY.md) |
206
+ | HTTP API | [docs/API-V2.md](docs/API-V2.md) and [SPEC.md](SPEC.md) |
207
+ | PR review design | [docs/PR-REVIEW-QA.md](docs/PR-REVIEW-QA.md) |
208
+
209
+ ## Data and privacy
210
+
211
+ localdost sends no telemetry. It keeps its state in the data folder (`LOCALDOST_DATA_DIR`, default `data/`, or `.localdost/data` under `localdost start`): the SQLite database, the web push keys, run artifacts, review checkouts, and "Not a risk" eval candidates. Data leaves the machine only for the services you configure:
212
+
213
+ | Recipient | When | What it receives |
214
+ |---|---|---|
215
+ | Anthropic | `LOCALDOST_LLM=claude-cli` or `anthropic` | Prompts: diffs, PR descriptions, ticket text, test results and log tails, dot memory, chat messages. The PR review masks common secret shapes in diff lines first. The `claude` CLI runs with its built-in tools off; a chat turn attaches only the local localdost chat tools as an MCP server. The PR review starts it with an allowlisted environment. Other calls remove the GitHub, Jira, Linear, ntfy, and push credentials and `LOCALDOST_TOKEN` from its environment |
216
+ | OpenAI | `LOCALDOST_LLM=codex-cli` | The same prompts as the Anthropic row, through the `codex` CLI and your ChatGPT login. The CLI runs read-only, with shell, browser, and plugins off, no MCP server except the local localdost chat tools in a chat turn, and an allowlisted environment |
217
+ | Your AI-Vision server, or the model behind Midscene | `runner.aivision` is set on a dot | Case titles and steps from the PR review and ticket test ideas, the start URL. The engine drives a browser against that URL and sends screenshots to its own model |
218
+ | GitHub, Jira, Linear | Their credentials are set | API reads with your credentials, plus the comments, check runs, and statuses the dot posts |
219
+ | Slack | `SLACK_APP_TOKEN` and `SLACK_BOT_TOKEN` are set | Chat answers and notices |
220
+ | Your browser's push service (Apple, Google, or Mozilla) | You turn on alerts in the app | Notification title and body |
221
+ | ntfy.sh, or your `NTFY_URL` | `NTFY_TOPIC` is set | Notification title, body, and a link |
222
+ | OpenAI | `OPENAI_API_KEY` is set and you start a call | Call audio and the dot's call instructions |
223
+ | Your browser vendor | A voice call in browser mode | Speech recognition audio, depending on the browser |
224
+ | MCP servers you add | A chat uses one of their tools | The tool input |
225
+ | mcr.microsoft.com and the npm registry | Docker runner mode | Image pulls and `npm ci` inside the test container |
226
+
227
+ The mock model (`LOCALDOST_LLM=mock`) sends nothing anywhere. Demo mode with no credentials stays on the machine, except the browser push service when you turn on alerts.
228
+
229
+ ## Features
230
+
231
+ The status column says how each part was checked. **Verified live** means it ran against the real service during dogfooding. **Real run, local** means automated tests run it for real on the machine with no outside service. **Fixture-tested** means unit tests run it against recorded payloads, fakes, or mocks. **No automated test** means only the code exists.
232
+
233
+ | Area | What it does | Status |
234
+ |---|---|---|
235
+ | Claude CLI backend | Verdicts, scores, reviews, and chat through `claude -p` with your Claude login | Verified live |
236
+ | Codex CLI backend | Verdicts, scores, reviews, chat, and the PR review through `codex exec` with your ChatGPT login | Verified live (analyze and a QA review pass on an eval fixture) |
237
+ | Anthropic API backend | The same through `ANTHROPIC_API_KEY` | Fixture-tested |
238
+ | GitHub PAT | Polling of commits and PRs, commit statuses | Verified live |
239
+ | GitHub PAT | Sticky PR comments, job logs, contents reads | Fixture-tested |
240
+ | GitHub App | Installation tokens, check runs with annotations | Fixture-tested |
241
+ | GitHub webhooks | Signatures, normalizers, checklist ticks from comment edits | Fixture-tested |
242
+ | Linear API | Personal API key, polling for new issues, issue reads | Verified live |
243
+ | Linear webhooks and comments | Signature and timestamp check, ticket comments | Fixture-tested |
244
+ | Jira Cloud | Webhooks, REST v3 reads, ADF comments | Fixture-tested |
245
+ | PR review | Scoping, signals, lenses, impact, reviewer and verifier passes, sticky comment, check run | Fixture-tested: 17 eval fixtures through the mock backend, 5 of them golden cases from real misses. `npm run eval:qa-review` runs them against a live model |
246
+ | Ticket review | Score, review, gated comment | Fixture-tested |
247
+ | Impact on existing tests | Finds the cases and specs a ticket changes, drafts a new case version or a retire draft | Fixture-tested: 4 stories through the mock backend |
248
+ | Demo runner and local runner | Real Playwright runs, live steps, browser frames, artifacts | Real run, local (e2e suite against the sample shop) |
249
+ | Docker runner | Tests in a Playwright container with a read-only mount | Fixture-tested (fork guard). No test against a Docker daemon |
250
+ | AI-Vision runner | Natural-language cases from the PR review and ticket test ideas on an AI-Vision server, its CLI, or the Midscene CLI | Verified live against a local AI-Vision server; fixture-tested (fake server and fake CLI) |
251
+ | Browser probes | Playwright page load, selector wait, screenshot on failure | Real run, local |
252
+ | HTTP probes, Statuspage, outage and recovery | Interval checks, three-strike outage, recovery notice | Fixture-tested |
253
+ | Rules gate and Inbox | Four levels, auto-review, approvals with edit and expiry | Fixture-tested, plus e2e in the demo |
254
+ | PWA | Dots, Feed, Run, Inbox, Chat, Reports, Settings, Setup screens | Real run, local (Playwright e2e at phone and desktop sizes) |
255
+ | Web push and ntfy | Alerts to the phone | No automated test |
256
+ | Slack | Socket Mode mentions, notices | Fixture-tested (fake Web API client) |
257
+ | MCP connections | HTTP and stdio servers, tool calls through the gate | Fixture-tested (in-memory transport) |
258
+ | MCP presets | AI-Vision and Midscene presets, env name passthrough, read-only tool lists | Verified live over stdio with the AI-Vision MCP server; Midscene preset not run |
259
+ | Voice | Browser speech, OpenAI Realtime token minting | Fixture-tested (mocked OpenAI) |
260
+ | Reports | Save a run as a page, edit, chat proposals | Fixture-tested, plus e2e |
261
+
262
+ localdost is alpha software. Expect breaking changes to the database schema and the API before 1.0.
263
+
264
+ ## Credits
265
+
266
+ localdost follows the product shape of [OpenDots](https://github.com/CopilotKit/OpenDots) by CopilotKit: a team of specialist dots with rules, an Inbox, chat, calls, Slack, and MCP connections. This README borrows its layout. [docs/PARITY.md](docs/PARITY.md) maps each OpenDots feature to its localdost version.
267
+
268
+ The PR review adapts the review prompt structure, change scoping, file classifiers, five review lenses, and the script-check rules from [OpenQodex](https://github.com/openqodex/openqodex), under the Apache License 2.0. [NOTICE](NOTICE) lists the adapted files, and [LICENSES/Apache-2.0.txt](LICENSES/Apache-2.0.txt) holds the license text.
269
+
270
+ ## Contributing
271
+
272
+ Read [CONTRIBUTING.md](CONTRIBUTING.md) for the dev setup, the test commands, and the writing rules. Report security issues as described in [SECURITY.md](SECURITY.md). Everyone in the project follows the [Code of Conduct](CODE_OF_CONDUCT.md).
273
+
274
+ ## License
275
+
276
+ MIT. See [LICENSE](LICENSE). Material adapted from OpenQodex stays under the Apache License 2.0, as [NOTICE](NOTICE) describes.
@@ -0,0 +1,29 @@
1
+ #!/usr/bin/env node
2
+ // localdost CLI entry. In a checkout with dev dependencies it runs the TypeScript source through
3
+ // tsx, so the CLI never runs a stale build. In an install without src/ or tsx (the Docker image,
4
+ // `npm ci --omit=dev`) it runs the compiled CLI from dist/.
5
+ import { existsSync } from 'node:fs';
6
+ import { fileURLToPath, pathToFileURL } from 'node:url';
7
+
8
+ const root = fileURLToPath(new URL('..', import.meta.url));
9
+ const source = `${root}src/cli/index.ts`;
10
+ const built = `${root}dist/cli/index.js`;
11
+
12
+ let register;
13
+ if (existsSync(source) && !process.env.LOCALDOST_USE_DIST) {
14
+ try {
15
+ ({ register } = await import('tsx/esm/api'));
16
+ } catch {
17
+ /* no dev dependencies: use dist */
18
+ }
19
+ }
20
+
21
+ if (register) {
22
+ register();
23
+ await import(pathToFileURL(source).href);
24
+ } else if (existsSync(built)) {
25
+ await import(pathToFileURL(built).href);
26
+ } else {
27
+ console.error('localdost: no build found. Run `npm ci && npm run build` in the localdost folder.');
28
+ process.exit(1);
29
+ }