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,833 @@
1
+ // AI-Vision on this machine (KAT-82): finds a running AI-Vision server and a local checkout, connects
2
+ // to a running server without input, starts the server from the checkout on request, and attaches
3
+ // the AI-Vision MCP preset and vision tests to dots that made no choice of their own.
4
+ //
5
+ // A detected server lives in runtime values (setRuntimeValue), so it never overrides a URL the user
6
+ // saved or set in the environment, and it disappears when the server stops answering.
7
+ import { execFileSync, spawn } from 'node:child_process';
8
+ import { existsSync, readdirSync, readFileSync } from 'node:fs';
9
+ import { connect } from 'node:net';
10
+ import { homedir } from 'node:os';
11
+ import path from 'node:path';
12
+ import { ROOT, config, log, setting, settingSource } from '../config.js';
13
+ import { isLoopbackHost, resolveListenHost } from '../loopback.js';
14
+ import { getConnection, listConnections, createConnection } from '../connections/store.js';
15
+ import { connectionFromPreset, presetOf } from '../connections/presets.js';
16
+ import { refreshConnection } from '../connections/manager.js';
17
+ import { list, update } from '../db.js';
18
+ import { aivisionTokenFor, originOf, setManagedTokenSource, tokenForManagedStart, TOKEN_KEY } from './aivision-token.js';
19
+ import { fetchT } from './deps.js';
20
+ import { getMeta, runtimeValue, setMeta, setRuntimeValue, storedValue } from './store.js';
21
+ export const SERVER_ENTRY = 'apps/playground/demo/aivision-server.mts';
22
+ export const MCP_ENTRY = 'apps/playground/demo/veesan-mcp.mts';
23
+ // Tests set LOCALDOST_AIVISION_DEFAULT_PORT to a closed port, so a real AI-Vision server on the same machine
24
+ // (the self-hosted CI runner has one on 5880) never answers their probes.
25
+ export const DEFAULT_PORT = ((p) => (Number.isInteger(p) && p > 0 && p < 65536 ? p : 5880))(Number(process.env.LOCALDOST_AIVISION_DEFAULT_PORT));
26
+ /** AI-Vision always runs on this model, whatever the dot's Codex model or an inherited VEESAN_MODEL_NAME says. */
27
+ export const AIVISION_MODEL = 'gpt-5.6-luna';
28
+ const RECHECK_MS = 3 * 60_000;
29
+ const PROBE_TIMEOUT_MS = 2500;
30
+ const START_TIMEOUT_MS = 120_000;
31
+ const LOG_LINES = 200;
32
+ /** lsof lists the listening pids on the port, ps gives each its group. macOS and Linux. */
33
+ function lsofListeners(port) {
34
+ if (process.platform === 'win32')
35
+ return undefined;
36
+ const run = (cmd, args) => {
37
+ try {
38
+ return execFileSync(cmd, args, { encoding: 'utf8', timeout: 2000, stdio: ['ignore', 'pipe', 'ignore'] });
39
+ }
40
+ catch (err) {
41
+ // lsof exits 1 with no output when nothing listens: that is an answer, not a failure.
42
+ const e = err;
43
+ return e.status === 1 && !e.code && !(e.stdout ?? '').trim() ? '' : undefined;
44
+ }
45
+ };
46
+ const out = run('lsof', ['-nP', `-iTCP:${port}`, '-sTCP:LISTEN', '-t']);
47
+ if (out === undefined)
48
+ return undefined;
49
+ const pids = [...new Set(out.split(/\s+/).filter(Boolean).map(Number))];
50
+ if (pids.some((n) => !Number.isInteger(n) || n <= 0))
51
+ return undefined;
52
+ const procs = [];
53
+ for (const pid of pids) {
54
+ const pgid = Number(run('ps', ['-o', 'pgid=', '-p', String(pid)])?.trim());
55
+ if (!Number.isInteger(pgid) || pgid <= 0)
56
+ return undefined;
57
+ procs.push({ pid, pgid });
58
+ }
59
+ return procs;
60
+ }
61
+ const defaultHooks = {
62
+ home: () => homedir(),
63
+ localdostRoot: () => ROOT,
64
+ // detached: the server and the processes npx starts share one group, so stop() can end them all.
65
+ spawn: (cmd, args, opts) => spawn(cmd, args, { cwd: opts.cwd, env: opts.env, detached: true, stdio: ['ignore', 'pipe', 'pipe'] }),
66
+ platform: () => process.platform,
67
+ exists: (p) => existsSync(p),
68
+ listeners: lsofListeners,
69
+ };
70
+ const hooks = { ...defaultHooks };
71
+ /** Test hook: override some hooks, or reset all with no argument. */
72
+ export function setLocalHooks(patch) {
73
+ Object.assign(hooks, patch ? patch : defaultHooks);
74
+ }
75
+ let local = {};
76
+ let child;
77
+ let logLines = [];
78
+ let timer;
79
+ let inflight;
80
+ let lastRun = 0;
81
+ let auto = false;
82
+ // ---------- detection ----------
83
+ function normalizeUrl(raw) {
84
+ try {
85
+ const u = new URL((raw ?? '').trim());
86
+ if ((u.protocol !== 'http:' && u.protocol !== 'https:') || u.username || u.password)
87
+ return undefined;
88
+ return `${u.origin}${u.pathname.replace(/\/+$/, '')}`;
89
+ }
90
+ catch {
91
+ return undefined;
92
+ }
93
+ }
94
+ /** Where a server may listen: AIVISION_PORT, then VEESAN_ENGINE_URL, then the default port. */
95
+ export function candidateUrls() {
96
+ const out = [];
97
+ const port = Number(setting('AIVISION_PORT'));
98
+ if (Number.isInteger(port) && port > 0 && port < 65536)
99
+ out.push(`http://127.0.0.1:${port}`);
100
+ const engine = normalizeUrl(setting('VEESAN_ENGINE_URL'));
101
+ if (engine)
102
+ out.push(engine);
103
+ out.push(`http://127.0.0.1:${DEFAULT_PORT}`);
104
+ return [...new Set(out)];
105
+ }
106
+ /** The server localdost started, the token it got, and the origin that token is bound to. */
107
+ let managedToken;
108
+ /** True while the process group localdost started still runs. A server that replaced it on the port is not it. */
109
+ function managedAlive() {
110
+ const proc = child;
111
+ if (!proc || !local.managed)
112
+ return undefined;
113
+ return (proc.exitCode === null && proc.signalCode === null) || groupAlive(proc) ? proc : undefined;
114
+ }
115
+ /**
116
+ * True only when every process LISTENING on the managed port belongs to the process group localdost
117
+ * started. A live group is not enough: the child can close its listener and another program bind the
118
+ * same port, and that program must get no credentials. Anything unclear (nothing listens, lsof
119
+ * fails, a foreign pid) counts as foreign.
120
+ */
121
+ function managedOwnsPort(proc) {
122
+ const port = Number(new URL(local.managed?.url ?? 'http://invalid').port);
123
+ if (!proc.pid || !Number.isInteger(port) || port <= 0)
124
+ return false;
125
+ const procs = hooks.listeners(port);
126
+ return !!procs && procs.length > 0 && procs.every((l) => l.pgid === proc.pid);
127
+ }
128
+ setManagedTokenSource(() => {
129
+ const m = managedToken;
130
+ if (!m || managedAlive() !== m.proc)
131
+ return undefined;
132
+ const { proc, token } = m;
133
+ // The token is read only when a request to this origin asks for it, and the listener is checked then.
134
+ return {
135
+ origin: m.origin,
136
+ get token() {
137
+ return managedAlive() === proc && managedOwnsPort(proc) ? token : '';
138
+ },
139
+ };
140
+ });
141
+ /** True when localdost started the server at this address itself, it still runs, and it still holds the port. */
142
+ export function isManagedUrl(url) {
143
+ const proc = managedAlive();
144
+ return !!proc && !!originOf(url) && originOf(local.managed?.url) === originOf(url) && managedOwnsPort(proc);
145
+ }
146
+ async function healthOnce(url, token) {
147
+ // No redirects: a token header never follows to another host.
148
+ // platform=web: localdost runs web vision tests, so checks for desktop or Android modes do not count.
149
+ return fetchT(`${url}/aivision/health?platform=web`, { redirect: 'manual', headers: token ? { 'x-veesan-internal': token } : {} }, PROBE_TIMEOUT_MS);
150
+ }
151
+ /**
152
+ * One health check. Undefined when nothing that looks like AI-Vision answers. The token comes from
153
+ * aivisionTokenFor only: a detected address is never bound, so it gets none.
154
+ */
155
+ export async function probeServer(url) {
156
+ try {
157
+ // Ask without credentials first; the token goes only to a server that asked for sign-in.
158
+ let res = await healthOnce(url, undefined);
159
+ if (res.status === 401 || res.status === 403) {
160
+ const token = aivisionTokenFor(url);
161
+ if (token)
162
+ res = await healthOnce(url, token);
163
+ if (res.status === 401 || res.status === 403)
164
+ return { url, needsToken: true };
165
+ }
166
+ // A 5xx that still answers as AI-Vision is a server with a failed check, not a missing one.
167
+ if (!res.ok && res.status < 500)
168
+ return undefined;
169
+ const body = (await res.json().catch(() => undefined));
170
+ if (!body || typeof body !== 'object' || (!Array.isArray(body.checks) && typeof body.ok !== 'boolean'))
171
+ return undefined;
172
+ // On an error status only the full health shape counts: a gateway's `{ ok: false }` is not AI-Vision.
173
+ if (!res.ok && !Array.isArray(body.checks))
174
+ return undefined;
175
+ const out = { url };
176
+ if (typeof body.version === 'string' && body.version)
177
+ out.version = body.version.slice(0, 40);
178
+ const failed = (Array.isArray(body.checks) ? body.checks : [])
179
+ .filter((c) => !!c && typeof c === 'object' && c.ok === false)
180
+ .map((c) => (typeof c.id === 'string' ? c.id.slice(0, 40) : 'check'))
181
+ .slice(0, 10);
182
+ if (!res.ok || body.ok === false || body.healthy === false || failed.length) {
183
+ out.unhealthy = true;
184
+ if (failed.length)
185
+ out.failedChecks = failed;
186
+ }
187
+ return out;
188
+ }
189
+ catch {
190
+ return undefined;
191
+ }
192
+ }
193
+ export function isCheckout(dir) {
194
+ return !!dir && path.isAbsolute(dir) && hooks.exists(path.join(dir, SERVER_ENTRY));
195
+ }
196
+ function aivisionDirs(parent, all) {
197
+ try {
198
+ return readdirSync(parent, { withFileTypes: true })
199
+ .filter((d) => (d.isDirectory() || d.isSymbolicLink()) && (all || /aivision/i.test(d.name)))
200
+ .map((d) => path.join(parent, d.name))
201
+ .sort()
202
+ .slice(0, 200);
203
+ }
204
+ catch {
205
+ return [];
206
+ }
207
+ }
208
+ /** AIVISION_CHECKOUT, then ~/code/*aivision*, then folders next to the localdost checkout. */
209
+ export function findCheckout() {
210
+ // Only a folder the user named counts here; a runtime value is this function's own earlier answer.
211
+ const named = userOwns('AIVISION_CHECKOUT') ? setting('AIVISION_CHECKOUT')?.trim() : undefined;
212
+ if (isCheckout(named))
213
+ return path.normalize(named).replace(/\/+$/, '');
214
+ const root = path.resolve(hooks.localdostRoot());
215
+ const candidates = [...aivisionDirs(path.join(hooks.home(), 'code'), false), ...aivisionDirs(path.dirname(root), true)];
216
+ return candidates.find((d) => path.resolve(d) !== root && isCheckout(d));
217
+ }
218
+ function checkoutVersion(dir) {
219
+ if (!dir)
220
+ return undefined;
221
+ try {
222
+ const v = JSON.parse(readFileSync(path.join(dir, 'package.json'), 'utf8')).version;
223
+ return typeof v === 'string' ? v.slice(0, 40) : undefined;
224
+ }
225
+ catch {
226
+ return undefined;
227
+ }
228
+ }
229
+ /** True when the user chose the value (saved on Setup or set in the environment). */
230
+ function userOwns(key) {
231
+ return settingSource(key) === 'env' || storedValue(key)?.value !== undefined;
232
+ }
233
+ /** Probes, finds the checkout, and updates the runtime values. Runs one at a time. */
234
+ export function refreshLocal(opts = {}) {
235
+ if (inflight)
236
+ return inflight;
237
+ if (!opts.force && Date.now() - lastRun < 5000)
238
+ return Promise.resolve(local);
239
+ inflight = (async () => {
240
+ try {
241
+ reapChild();
242
+ const checkout = findCheckout();
243
+ let server;
244
+ // The first server that lets localdost in wins; one that asks for sign-in is kept only as a fallback.
245
+ let locked;
246
+ for (const url of candidateUrls()) {
247
+ const found = await probeServer(url);
248
+ if (found && !found.needsToken && !found.unhealthy) {
249
+ server = found;
250
+ break;
251
+ }
252
+ locked ??= found;
253
+ }
254
+ server ??= locked;
255
+ if (server && !server.version) {
256
+ const v = checkoutVersion(checkout);
257
+ if (v)
258
+ server.version = v;
259
+ }
260
+ const next = { checkedAt: new Date().toISOString() };
261
+ if (server)
262
+ next.server = server;
263
+ if (checkout)
264
+ next.checkout = checkout;
265
+ if (local.managed)
266
+ next.managed = local.managed;
267
+ local = next;
268
+ // A server that refuses localdost (sign-in needed, no working token) or reports a failed check is
269
+ // shown, never connected.
270
+ const usable = server && !server.needsToken && !server.unhealthy ? server.url : null;
271
+ // A value the user chose always wins, so a runtime value left from earlier detection goes.
272
+ setRuntimeValue('AIVISION_SERVER_URL', userOwns('AIVISION_SERVER_URL') ? null : usable);
273
+ setRuntimeValue('AIVISION_CHECKOUT', userOwns('AIVISION_CHECKOUT') ? null : (checkout ?? null));
274
+ if (setting('AIVISION_SERVER_URL'))
275
+ autoAttach();
276
+ return local;
277
+ }
278
+ finally {
279
+ lastRun = Date.now();
280
+ inflight = undefined;
281
+ }
282
+ })();
283
+ return inflight;
284
+ }
285
+ export function localState() {
286
+ return local;
287
+ }
288
+ /** True when the active URL is one localdost found, not one the user entered. */
289
+ export function detectedActive() {
290
+ return !userOwns('AIVISION_SERVER_URL') && !!runtimeValue('AIVISION_SERVER_URL');
291
+ }
292
+ export function localView() {
293
+ const v = { ...local, startUrl: `http://127.0.0.1:${startPort()}` };
294
+ // The log explains a failed start, and a managed server that runs but reports a failed check.
295
+ if (local.managed?.state === 'failed' || (local.managed?.state === 'running' && local.server?.unhealthy))
296
+ v.logTail = logLines.slice(-15);
297
+ const conn = aivisionConnectionId();
298
+ const dots = list('watches').filter((w) => !w.archived);
299
+ v.dots = {
300
+ mcp: conn ? dots.filter((w) => w.connections?.includes(conn)).length : 0,
301
+ cases: dots.filter((w) => w.runner?.aivision && w.runner.aivision.enabled !== false).length,
302
+ };
303
+ return v;
304
+ }
305
+ // ---------- background checks ----------
306
+ /** Boot hook (src/index.ts): check now, then every few minutes. Tests never call it. */
307
+ export function startLocalChecks() {
308
+ auto = true;
309
+ void refreshLocal({ force: true }).catch((err) => log.warn('aivision: detection failed', String(err)));
310
+ if (!timer) {
311
+ timer = setInterval(() => void refreshLocal({ force: true }).catch(() => undefined), RECHECK_MS);
312
+ timer.unref();
313
+ }
314
+ }
315
+ /** Setup load: re-check when the background checks run. */
316
+ export function refreshOnView() {
317
+ return auto ? refreshLocal() : undefined;
318
+ }
319
+ // ---------- managed server ----------
320
+ const ENV_ALLOW = [
321
+ /^(HOME|PATH|USER|LOGNAME|SHELL|LANG|TERM|TMPDIR|TZ|TMP|TEMP)$/,
322
+ /^LC_/,
323
+ /^XDG_(CONFIG|DATA|CACHE|STATE)_HOME$/,
324
+ /^(HTTPS_PROXY|HTTP_PROXY|NO_PROXY|https_proxy|http_proxy|no_proxy|NODE_EXTRA_CA_CERTS|SSL_CERT_FILE|SSL_CERT_DIR)$/,
325
+ /^(VEESAN|AIVISION|MIDSCENE|PUPPETEER)_[A-Z0-9_]+$/,
326
+ /^(OPENAI_API_KEY|OPENAI_BASE_URL|CODEX_HOME)$/,
327
+ ];
328
+ const MAC_CHROME = '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome';
329
+ /** Allowlisted env for the server, with defaults for a Mac signed in to Codex. */
330
+ export function serverEnv(port, src = process.env) {
331
+ const out = {};
332
+ for (const [k, v] of Object.entries(src))
333
+ if (v !== undefined && v !== '' && ENV_ALLOW.some((re) => re.test(k)))
334
+ out[k] = v;
335
+ // The access token goes through the gate: one saved without an address, or for this same origin.
336
+ delete out[TOKEN_KEY];
337
+ const token = tokenForManagedStart(`http://127.0.0.1:${port}`);
338
+ if (token)
339
+ out[TOKEN_KEY] = token;
340
+ // Values saved on the Setup page count too, for the names the allowlist passes.
341
+ const key = setting('OPENAI_API_KEY');
342
+ if (key && !out.OPENAI_API_KEY)
343
+ out.OPENAI_API_KEY = key;
344
+ out.AIVISION_PORT = String(port);
345
+ if (!out.VEESAN_MODEL_BASE_URL && !out.OPENAI_API_KEY)
346
+ out.VEESAN_MODEL_BASE_URL = 'codex://';
347
+ out.VEESAN_MODEL_NAME = AIVISION_MODEL;
348
+ if (!out.PUPPETEER_EXECUTABLE_PATH && hooks.platform() === 'darwin' && hooks.exists(MAC_CHROME))
349
+ out.PUPPETEER_EXECUTABLE_PATH = MAC_CHROME;
350
+ return out;
351
+ }
352
+ /** Secret values handed to the child; its log lines are cleaned of them before anyone sees them. */
353
+ let logSecrets = [];
354
+ /** Env names whose values are never secret; everything else the child gets is hidden in its log. */
355
+ const SAFE_ENV = /^(PATH|HOME|USER|LOGNAME|SHELL|LANG|TERM|TMPDIR|TZ|TMP|TEMP|LC_[A-Z_]+|XDG_(CONFIG|DATA|CACHE|STATE)_HOME|AIVISION_PORT|VEESAN_MODEL_BASE_URL|VEESAN_MODEL_NAME|PUPPETEER_EXECUTABLE_PATH|NODE_EXTRA_CA_CERTS|SSL_CERT_FILE|SSL_CERT_DIR|NO_PROXY|no_proxy)$/;
356
+ const SECRET_SHAPE = /\b(sk-[A-Za-z0-9_-]{8,}|gh[pousr]_[A-Za-z0-9]{8,}|github_pat_[A-Za-z0-9_]{8,}|xox[abpr]-[A-Za-z0-9-]{8,}|eyJ[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+)/g;
357
+ const AUTH_HEADER = /\b(Bearer|Basic)\s+[A-Za-z0-9._~+/=-]{8,}/gi;
358
+ const URL_CREDENTIALS = /(\b[a-z][a-z0-9+.-]*:\/\/)[^\s/:@]+:[^\s/@]+@/gi;
359
+ export function redactLine(line, secrets = logSecrets) {
360
+ let out = line;
361
+ for (const v of secrets)
362
+ if (v.length >= 6)
363
+ out = out.split(v).join('[hidden]');
364
+ return out.replace(SECRET_SHAPE, '[hidden]').replace(AUTH_HEADER, '$1 [hidden]').replace(URL_CREDENTIALS, '$1[hidden]@');
365
+ }
366
+ /**
367
+ * Text after the last newline, per stream: a line is redacted only once it is whole, so a secret
368
+ * split across chunks, or with the other stream's output in between, is still caught.
369
+ */
370
+ let logRest = { out: '', err: '' };
371
+ function keepLine(line) {
372
+ if (line.trim())
373
+ logLines.push(redactLine(line).slice(0, 400));
374
+ }
375
+ /**
376
+ * Where to cut a long line without a newline: leave the last stretch, as long as the longest secret,
377
+ * unread, and move the cut before any secret that crosses it, so no secret is split in two pieces.
378
+ */
379
+ export function safeCut(text, secrets = logSecrets) {
380
+ const longest = secrets.reduce((n, v) => Math.max(n, v.length), 0);
381
+ let cut = Math.max(0, text.length - Math.min(4000, Math.max(256, longest)));
382
+ const spans = [];
383
+ for (const v of secrets) {
384
+ if (v.length < 6)
385
+ continue;
386
+ for (let i = text.indexOf(v); i !== -1; i = text.indexOf(v, i + 1))
387
+ spans.push([i, i + v.length]);
388
+ }
389
+ for (const re of [SECRET_SHAPE, AUTH_HEADER, URL_CREDENTIALS])
390
+ for (const m of text.matchAll(re))
391
+ spans.push([m.index, m.index + m[0].length]);
392
+ for (const [a, b] of spans.sort((x, y) => y[0] - x[0]))
393
+ if (a < cut && b > cut)
394
+ cut = a;
395
+ return cut;
396
+ }
397
+ function pushLog(chunk, stream) {
398
+ const parts = (logRest[stream] + chunk).split(/\r?\n/);
399
+ let rest = parts.pop() ?? '';
400
+ for (const line of parts)
401
+ keepLine(line);
402
+ // A child that never prints a newline still has its output kept, in bounded pieces.
403
+ if (rest.length > 8000) {
404
+ const cut = safeCut(rest);
405
+ keepLine(rest.slice(0, cut));
406
+ rest = rest.slice(cut);
407
+ }
408
+ logRest[stream] = rest;
409
+ if (logLines.length > LOG_LINES)
410
+ logLines = logLines.slice(-LOG_LINES);
411
+ }
412
+ function flushLog() {
413
+ keepLine(logRest.out);
414
+ keepLine(logRest.err);
415
+ logRest = { out: '', err: '' };
416
+ if (logLines.length > LOG_LINES)
417
+ logLines = logLines.slice(-LOG_LINES);
418
+ }
419
+ export function managedLog() {
420
+ return [...logLines];
421
+ }
422
+ function startPort() {
423
+ const port = Number(setting('AIVISION_PORT'));
424
+ return Number.isInteger(port) && port > 0 && port < 65536 ? port : DEFAULT_PORT;
425
+ }
426
+ /**
427
+ * Starts the server from the detected checkout as a child of localdost. Resolves once it is starting;
428
+ * the server connects when its health check answers. Throws with a plain message when it cannot start.
429
+ */
430
+ let startInflight;
431
+ export function startManaged() {
432
+ // A Stop still waiting for the old server to go holds its port: start after it.
433
+ if (stopInflight)
434
+ return stopInflight.then(() => startManaged());
435
+ // One start at a time, and never a second child while the first still runs.
436
+ reapChild();
437
+ if (child)
438
+ return Promise.resolve(local);
439
+ startInflight ??= doStart().finally(() => {
440
+ startInflight = undefined;
441
+ });
442
+ return startInflight;
443
+ }
444
+ /** Forgets a managed server whose launcher exited and whose process group is gone. */
445
+ function reapChild() {
446
+ if (!child || (child.exitCode === null && child.signalCode === null) || groupAlive(child))
447
+ return;
448
+ child = undefined;
449
+ if (local.managed && local.managed.state !== 'stopped' && local.managed.state !== 'failed')
450
+ finish('failed', 'AI-Vision stopped.');
451
+ }
452
+ /** Bumped by Stop: a start still looking around when Stop came never spawns. */
453
+ let startGen = 0;
454
+ async function doStart() {
455
+ const gen = startGen;
456
+ const cur = await refreshLocal({ force: true });
457
+ if (gen !== startGen)
458
+ return local;
459
+ if (cur.server && !cur.server.unhealthy && !cur.server.needsToken)
460
+ return cur;
461
+ // A failing or sign-in server elsewhere (VEESAN_ENGINE_URL) does not stop a local start, but one
462
+ // that answers on the port Start would use is this one.
463
+ if (cur.server && (await probeServer(`http://127.0.0.1:${startPort()}`)))
464
+ return local;
465
+ if (gen !== startGen)
466
+ return local;
467
+ const checkout = cur.checkout;
468
+ if (!checkout)
469
+ throw new Error('No AI-Vision checkout was found on this Mac.');
470
+ if (stray && ((stray.exitCode === null && stray.signalCode === null) || groupAlive(stray))) {
471
+ throw new Error(`An earlier AI-Vision (process group ${stray.pid ?? 'unknown'}) is still running. Stop it by hand, then start again.`);
472
+ }
473
+ stray = undefined;
474
+ const port = startPort();
475
+ const url = `http://127.0.0.1:${port}`;
476
+ // Another program on the port would answer for the new server and get its token.
477
+ if (await portInUse(port))
478
+ throw new Error(`Another program uses port ${port}. Stop it, or set AIVISION_PORT to a free port.`);
479
+ if (gen !== startGen)
480
+ return local;
481
+ logLines = [];
482
+ logRest = { out: '', err: '' };
483
+ const childEnv = serverEnv(port);
484
+ // Every value handed to the child counts as secret except names known to hold none.
485
+ logSecrets = Object.entries(childEnv)
486
+ .filter(([k, v]) => v && !SAFE_ENV.test(k))
487
+ .map(([, v]) => v);
488
+ let proc;
489
+ try {
490
+ proc = hooks.spawn('npx', ['tsx', SERVER_ENTRY], { cwd: checkout, env: childEnv });
491
+ }
492
+ catch (err) {
493
+ throw new Error(`AI-Vision did not start: ${err instanceof Error ? err.message : String(err)}`, { cause: err });
494
+ }
495
+ child = proc;
496
+ const sent = childEnv[TOKEN_KEY];
497
+ managedToken = sent ? { proc, token: sent, origin: originOf(url) } : undefined;
498
+ const managed = { state: 'starting', checkout, url, startedAt: new Date().toISOString() };
499
+ if (proc.pid)
500
+ managed.pid = proc.pid;
501
+ local = { ...local, managed };
502
+ proc.stdout?.setEncoding('utf8').on('data', (d) => pushLog(d, 'out'));
503
+ proc.stderr?.setEncoding('utf8').on('data', (d) => pushLog(d, 'err'));
504
+ proc.on('error', (err) => {
505
+ pushLog(`${String(err)}\n`, 'err');
506
+ flushLog();
507
+ // A spawn error (ENOENT) may come without an exit event: free the slot so Start works again.
508
+ if (child === proc)
509
+ child = undefined;
510
+ finish('failed', `AI-Vision did not start: ${err.message}`);
511
+ });
512
+ // close comes after the last output, so the tail of a line without a newline is kept too.
513
+ proc.on('close', () => flushLog());
514
+ proc.on('exit', (code, signal) => {
515
+ if (child !== proc)
516
+ return;
517
+ if (local.managed?.state === 'stopped') {
518
+ child = undefined;
519
+ return;
520
+ }
521
+ // npx can exit while the server it started runs on in the same group: keep the handle, so Stop
522
+ // and shutdown still end that group. reapChild notices when the group is gone.
523
+ if (groupAlive(proc)) {
524
+ log.info('aivision: the launcher exited; the server it started still runs');
525
+ // Watch the group closely, so the handle goes as soon as the group does and a reused pid is
526
+ // never signalled.
527
+ const watch = setInterval(() => {
528
+ if (child !== proc)
529
+ clearInterval(watch);
530
+ else if (!groupAlive(proc)) {
531
+ clearInterval(watch);
532
+ reapChild();
533
+ // Check again, after any check already running, so the dead server's address stops being
534
+ // used now, not at the next check.
535
+ void (inflight ?? Promise.resolve())
536
+ .catch(() => undefined)
537
+ .then(() => refreshLocal({ force: true }))
538
+ .catch(() => undefined);
539
+ }
540
+ }, 1000);
541
+ watch.unref();
542
+ return;
543
+ }
544
+ child = undefined;
545
+ finish('failed', `AI-Vision stopped (${signal ?? `exit ${code ?? 'unknown'}`}).`);
546
+ void refreshLocal({ force: true }).catch(() => undefined);
547
+ });
548
+ void waitHealthy(proc, url);
549
+ return local;
550
+ }
551
+ function finish(state, error) {
552
+ if (!local.managed)
553
+ return;
554
+ const m = { ...local.managed, state };
555
+ if (error)
556
+ m.error = error;
557
+ else
558
+ delete m.error;
559
+ local = { ...local, managed: m };
560
+ }
561
+ async function waitHealthy(proc, url) {
562
+ const until = Date.now() + START_TIMEOUT_MS;
563
+ while (Date.now() < until && child === proc) {
564
+ await new Promise((r) => setTimeout(r, 1000));
565
+ if (child !== proc)
566
+ return;
567
+ const found = await probeServer(url);
568
+ // Stop may have come while the probe ran: a stopped server never turns back to running.
569
+ if (child !== proc)
570
+ return;
571
+ if (found && !found.unhealthy) {
572
+ // Connect first, then report running. A server that asks for sign-in runs, but stays unconnected
573
+ // until a token is saved; the sheet says so and keeps Stop.
574
+ await refreshLocal({ force: true });
575
+ if (child === proc)
576
+ finish('running');
577
+ return;
578
+ }
579
+ if (found && local.managed?.state === 'starting') {
580
+ // It answers, with a failed check (warming up, for example): running, with Stop, and polled on
581
+ // until it passes, so it connects as soon as it does.
582
+ await refreshLocal({ force: true });
583
+ if (child === proc)
584
+ finish('running');
585
+ }
586
+ }
587
+ if (child === proc && local.managed?.state === 'starting') {
588
+ finish('failed', 'AI-Vision did not answer within 2 minutes.');
589
+ // A server that outlives the kill blocks the next Start, as after a failed Stop.
590
+ // Start waits for this cleanup, as it waits for a Stop.
591
+ const cleanup = stopChild(proc)
592
+ .then((gone) => {
593
+ if (!gone)
594
+ stray = proc;
595
+ return gone;
596
+ })
597
+ .finally(() => {
598
+ if (stopInflight === cleanup)
599
+ stopInflight = undefined;
600
+ });
601
+ stopInflight = cleanup;
602
+ }
603
+ }
604
+ /** True when something accepts a connection on the loopback port. */
605
+ function portInUse(port) {
606
+ return new Promise((resolve) => {
607
+ const sock = connect({ host: '127.0.0.1', port });
608
+ const done = (used) => {
609
+ sock.destroy();
610
+ resolve(used);
611
+ };
612
+ sock.setTimeout(PROBE_TIMEOUT_MS, () => done(true));
613
+ sock.once('connect', () => done(true));
614
+ sock.once('error', () => done(false));
615
+ });
616
+ }
617
+ /** The group outlives its leader while any process in it runs. */
618
+ function groupAlive(proc) {
619
+ if (!proc.pid)
620
+ return false;
621
+ try {
622
+ process.kill(-proc.pid, 0);
623
+ return true;
624
+ }
625
+ catch (err) {
626
+ return err.code === 'EPERM';
627
+ }
628
+ }
629
+ /**
630
+ * SIGTERM to the whole process group, SIGKILL to the group after 3 seconds. Resolves true once every
631
+ * process in the group is gone (npx can exit before the server it started), false after 5 seconds.
632
+ */
633
+ function stopChild(proc) {
634
+ const kill = (sig) => {
635
+ try {
636
+ if (proc.pid)
637
+ process.kill(-proc.pid, sig);
638
+ else
639
+ proc.kill(sig);
640
+ }
641
+ catch {
642
+ try {
643
+ proc.kill(sig);
644
+ }
645
+ catch {
646
+ /* already gone */
647
+ }
648
+ }
649
+ };
650
+ const exited = () => proc.exitCode !== null || proc.signalCode !== null;
651
+ const gone = () => exited() && !groupAlive(proc);
652
+ if (gone())
653
+ return Promise.resolve(true);
654
+ return new Promise((resolve) => {
655
+ const startedAt = Date.now();
656
+ let hard = false;
657
+ kill('SIGTERM');
658
+ const tick = setInterval(() => {
659
+ if (gone()) {
660
+ clearInterval(tick);
661
+ resolve(true);
662
+ return;
663
+ }
664
+ const waited = Date.now() - startedAt;
665
+ if (!hard && waited >= 3000) {
666
+ hard = true;
667
+ kill('SIGKILL');
668
+ }
669
+ if (waited >= 5000) {
670
+ clearInterval(tick);
671
+ resolve(false);
672
+ }
673
+ }, 50);
674
+ });
675
+ }
676
+ /** Stops a server localdost started. A server started elsewhere is left alone. */
677
+ /** Set while Stop waits for the old server's processes to go; a Start waits for it. */
678
+ let stopInflight;
679
+ /** A server Stop could not end. Start refuses while its process group still runs. */
680
+ let stray;
681
+ export async function stopManaged() {
682
+ startGen++;
683
+ const pending = startInflight;
684
+ if (pending && !child)
685
+ await pending.catch(() => undefined);
686
+ const proc = child;
687
+ if (!proc) {
688
+ // A second Stop while the first still waits returns once the first is done.
689
+ if (stopInflight)
690
+ await stopInflight;
691
+ return local;
692
+ }
693
+ finish('stopped');
694
+ const run = local.managed;
695
+ child = undefined;
696
+ // Wait until it is gone, so shutdown does not exit before the kill lands.
697
+ const stopping = stopChild(proc).finally(() => {
698
+ if (stopInflight === stopping)
699
+ stopInflight = undefined;
700
+ });
701
+ stopInflight = stopping;
702
+ const gone = await stopping;
703
+ // Start waits for this Stop, so the run is still the one stopped; check anyway.
704
+ if (local.managed !== run)
705
+ return local;
706
+ if (!gone) {
707
+ const pid = proc.pid ? ` (process group ${proc.pid})` : '';
708
+ log.warn(`aivision: the managed server did not stop${pid}`);
709
+ stray = proc;
710
+ finish('failed', `AI-Vision did not stop within 5 seconds${pid}. Stop it by hand.`);
711
+ return local;
712
+ }
713
+ // A check that probed the server before it went would set its address and server again after
714
+ // this cleanup: let it land first, so Stop has the last word.
715
+ if (inflight)
716
+ await inflight.catch(() => undefined);
717
+ if (detectedActive() && runtimeValue('AIVISION_SERVER_URL') === local.managed?.url)
718
+ setRuntimeValue('AIVISION_SERVER_URL', null);
719
+ local = { ...local };
720
+ delete local.server;
721
+ return local;
722
+ }
723
+ /** Shutdown hook: stop the managed server and the timer. */
724
+ export async function shutdownLocal() {
725
+ if (timer)
726
+ clearInterval(timer);
727
+ timer = undefined;
728
+ auto = false;
729
+ await stopManaged();
730
+ }
731
+ // ---------- auto-attach ----------
732
+ function aivisionConnectionId() {
733
+ return listConnections().find((c) => c.preset === 'aivision')?.id;
734
+ }
735
+ let stdioSkipLogged = false;
736
+ /**
737
+ * Background detection has no request to judge, so it applies the same rule the manual routes do
738
+ * for a stdio connection (it runs a command on this machine): a token is set, LOCALDOST_ALLOW_STDIO=1,
739
+ * or the server listens on loopback only. A HOST that resolveListenHost refuses counts as open to
740
+ * the network.
741
+ */
742
+ function stdioAllowedInBackground() {
743
+ if (config.token || process.env.LOCALDOST_ALLOW_STDIO === '1')
744
+ return true;
745
+ try {
746
+ return isLoopbackHost(resolveListenHost(config.host, config.token));
747
+ }
748
+ catch {
749
+ return false;
750
+ }
751
+ }
752
+ /**
753
+ * For every dot without an explicit choice: attaches the AI-Vision MCP preset, and turns on vision
754
+ * tests when the dot has a repo and a base URL. Each dot is handled once per kind, so a choice the
755
+ * user makes afterwards (detach, turn off) stays.
756
+ */
757
+ export function autoAttach() {
758
+ const done = { mcp: [], cases: [] };
759
+ const meta = getMeta('aivision');
760
+ const seen = { ...(meta.autoDots ?? {}) };
761
+ let connId = aivisionConnectionId();
762
+ const checkout = setting('AIVISION_CHECKOUT')?.trim();
763
+ if (!connId && checkout && hooks.exists(path.join(checkout, MCP_ENTRY))) {
764
+ if (!stdioAllowedInBackground()) {
765
+ // Creating it would run a command from background detection, past the gate the manual routes enforce.
766
+ if (!stdioSkipLogged) {
767
+ stdioSkipLogged = true;
768
+ log.info('aivision: AI-Vision MCP connection not created: it runs a command, and stdio needs LOCALDOST_TOKEN, LOCALDOST_ALLOW_STDIO=1, or a loopback-only server');
769
+ }
770
+ }
771
+ else {
772
+ const { input } = connectionFromPreset('aivision', { checkout });
773
+ if (input) {
774
+ const conn = createConnection(input);
775
+ connId = conn.id;
776
+ void refreshConnection(conn.id).catch(() => undefined);
777
+ }
778
+ }
779
+ }
780
+ let changed = false;
781
+ for (const w of list('watches')) {
782
+ if (w.archived)
783
+ continue;
784
+ const handled = new Set(seen[w.id] ?? []);
785
+ const patch = {};
786
+ if (connId && !handled.has('mcp')) {
787
+ const has = (w.connections ?? []).some((id) => presetOf(getConnection(id))?.id === 'aivision');
788
+ if (!has) {
789
+ patch.connections = [...(w.connections ?? []), connId];
790
+ done.mcp.push(w.id);
791
+ }
792
+ handled.add('mcp');
793
+ }
794
+ if (!handled.has('cases') && w.repo && w.baseUrl) {
795
+ if (!w.runner?.aivision) {
796
+ patch.runner = { ...w.runner, aivision: { backend: 'server', enabled: true } };
797
+ done.cases.push(w.id);
798
+ }
799
+ handled.add('cases');
800
+ }
801
+ if (Object.keys(patch).length)
802
+ update('watches', w.id, { ...patch, updatedAt: new Date().toISOString() });
803
+ if (handled.size !== (seen[w.id]?.length ?? 0)) {
804
+ seen[w.id] = [...handled].sort();
805
+ changed = true;
806
+ }
807
+ }
808
+ if (changed)
809
+ setMeta('aivision', { autoDots: seen });
810
+ if (done.mcp.length || done.cases.length)
811
+ log.info(`aivision: attached to ${done.mcp.length} dot(s), vision tests on for ${done.cases.length} dot(s)`);
812
+ return done;
813
+ }
814
+ /** Test hook: forget the detection state. */
815
+ export function resetLocal() {
816
+ local = {};
817
+ stdioSkipLogged = false;
818
+ logLines = [];
819
+ lastRun = 0;
820
+ inflight = undefined;
821
+ if (timer)
822
+ clearInterval(timer);
823
+ timer = undefined;
824
+ auto = false;
825
+ child = undefined;
826
+ managedToken = undefined;
827
+ startInflight = undefined;
828
+ stopInflight = undefined;
829
+ stray = undefined;
830
+ setRuntimeValue('AIVISION_SERVER_URL', null);
831
+ setRuntimeValue('AIVISION_CHECKOUT', null);
832
+ }
833
+ //# sourceMappingURL=aivision-local.js.map