@ashlr/hub 2.2.0

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 (477) hide show
  1. package/CHANGELOG.md +1158 -0
  2. package/LICENSE +21 -0
  3. package/README.md +833 -0
  4. package/bin/ashlr +8 -0
  5. package/dist/api/core.d.ts +28 -0
  6. package/dist/api/core.js +42 -0
  7. package/dist/api/core.js.map +1 -0
  8. package/dist/api/index.d.ts +9 -0
  9. package/dist/api/index.js +9 -0
  10. package/dist/api/index.js.map +1 -0
  11. package/dist/api/plugin.d.ts +12 -0
  12. package/dist/api/plugin.js +13 -0
  13. package/dist/api/plugin.js.map +1 -0
  14. package/dist/api/types.d.ts +9 -0
  15. package/dist/api/types.js +9 -0
  16. package/dist/api/types.js.map +1 -0
  17. package/dist/cli/args.d.ts +20 -0
  18. package/dist/cli/args.js +23 -0
  19. package/dist/cli/args.js.map +1 -0
  20. package/dist/cli/ask.d.ts +22 -0
  21. package/dist/cli/ask.js +240 -0
  22. package/dist/cli/ask.js.map +1 -0
  23. package/dist/cli/audit.d.ts +26 -0
  24. package/dist/cli/audit.js +199 -0
  25. package/dist/cli/audit.js.map +1 -0
  26. package/dist/cli/backlog.d.ts +26 -0
  27. package/dist/cli/backlog.js +322 -0
  28. package/dist/cli/backlog.js.map +1 -0
  29. package/dist/cli/completions.d.ts +18 -0
  30. package/dist/cli/completions.js +156 -0
  31. package/dist/cli/completions.js.map +1 -0
  32. package/dist/cli/daemon.d.ts +31 -0
  33. package/dist/cli/daemon.js +334 -0
  34. package/dist/cli/daemon.js.map +1 -0
  35. package/dist/cli/demo-sandbox.d.ts +78 -0
  36. package/dist/cli/demo-sandbox.js +227 -0
  37. package/dist/cli/demo-sandbox.js.map +1 -0
  38. package/dist/cli/demo.d.ts +76 -0
  39. package/dist/cli/demo.js +285 -0
  40. package/dist/cli/demo.js.map +1 -0
  41. package/dist/cli/digest.d.ts +46 -0
  42. package/dist/cli/digest.js +352 -0
  43. package/dist/cli/digest.js.map +1 -0
  44. package/dist/cli/doctor-init.d.ts +28 -0
  45. package/dist/cli/doctor-init.js +335 -0
  46. package/dist/cli/doctor-init.js.map +1 -0
  47. package/dist/cli/genome.d.ts +62 -0
  48. package/dist/cli/genome.js +1061 -0
  49. package/dist/cli/genome.js.map +1 -0
  50. package/dist/cli/gh.d.ts +27 -0
  51. package/dist/cli/gh.js +322 -0
  52. package/dist/cli/gh.js.map +1 -0
  53. package/dist/cli/goals.d.ts +55 -0
  54. package/dist/cli/goals.js +667 -0
  55. package/dist/cli/goals.js.map +1 -0
  56. package/dist/cli/health.d.ts +56 -0
  57. package/dist/cli/health.js +407 -0
  58. package/dist/cli/health.js.map +1 -0
  59. package/dist/cli/help.d.ts +51 -0
  60. package/dist/cli/help.js +436 -0
  61. package/dist/cli/help.js.map +1 -0
  62. package/dist/cli/inbox.d.ts +28 -0
  63. package/dist/cli/inbox.js +589 -0
  64. package/dist/cli/inbox.js.map +1 -0
  65. package/dist/cli/index.d.ts +41 -0
  66. package/dist/cli/index.js +1208 -0
  67. package/dist/cli/index.js.map +1 -0
  68. package/dist/cli/knowledge.d.ts +33 -0
  69. package/dist/cli/knowledge.js +575 -0
  70. package/dist/cli/knowledge.js.map +1 -0
  71. package/dist/cli/mcp.d.ts +26 -0
  72. package/dist/cli/mcp.js +487 -0
  73. package/dist/cli/mcp.js.map +1 -0
  74. package/dist/cli/models.d.ts +26 -0
  75. package/dist/cli/models.js +435 -0
  76. package/dist/cli/models.js.map +1 -0
  77. package/dist/cli/new.d.ts +32 -0
  78. package/dist/cli/new.js +565 -0
  79. package/dist/cli/new.js.map +1 -0
  80. package/dist/cli/notify.d.ts +20 -0
  81. package/dist/cli/notify.js +188 -0
  82. package/dist/cli/notify.js.map +1 -0
  83. package/dist/cli/onboard.d.ts +85 -0
  84. package/dist/cli/onboard.js +305 -0
  85. package/dist/cli/onboard.js.map +1 -0
  86. package/dist/cli/open.d.ts +38 -0
  87. package/dist/cli/open.js +86 -0
  88. package/dist/cli/open.js.map +1 -0
  89. package/dist/cli/orient.d.ts +14 -0
  90. package/dist/cli/orient.js +110 -0
  91. package/dist/cli/orient.js.map +1 -0
  92. package/dist/cli/picker.d.ts +21 -0
  93. package/dist/cli/picker.js +177 -0
  94. package/dist/cli/picker.js.map +1 -0
  95. package/dist/cli/plugins.d.ts +21 -0
  96. package/dist/cli/plugins.js +394 -0
  97. package/dist/cli/plugins.js.map +1 -0
  98. package/dist/cli/preflight.d.ts +29 -0
  99. package/dist/cli/preflight.js +131 -0
  100. package/dist/cli/preflight.js.map +1 -0
  101. package/dist/cli/pulse.d.ts +26 -0
  102. package/dist/cli/pulse.js +482 -0
  103. package/dist/cli/pulse.js.map +1 -0
  104. package/dist/cli/reflect.d.ts +42 -0
  105. package/dist/cli/reflect.js +381 -0
  106. package/dist/cli/reflect.js.map +1 -0
  107. package/dist/cli/run.d.ts +29 -0
  108. package/dist/cli/run.js +687 -0
  109. package/dist/cli/run.js.map +1 -0
  110. package/dist/cli/sandbox.d.ts +20 -0
  111. package/dist/cli/sandbox.js +345 -0
  112. package/dist/cli/sandbox.js.map +1 -0
  113. package/dist/cli/seams.d.ts +41 -0
  114. package/dist/cli/seams.js +167 -0
  115. package/dist/cli/seams.js.map +1 -0
  116. package/dist/cli/serve.d.ts +25 -0
  117. package/dist/cli/serve.js +249 -0
  118. package/dist/cli/serve.js.map +1 -0
  119. package/dist/cli/ship.d.ts +33 -0
  120. package/dist/cli/ship.js +433 -0
  121. package/dist/cli/ship.js.map +1 -0
  122. package/dist/cli/spec.d.ts +19 -0
  123. package/dist/cli/spec.js +478 -0
  124. package/dist/cli/spec.js.map +1 -0
  125. package/dist/cli/swarm.d.ts +42 -0
  126. package/dist/cli/swarm.js +1365 -0
  127. package/dist/cli/swarm.js.map +1 -0
  128. package/dist/cli/telemetry.d.ts +26 -0
  129. package/dist/cli/telemetry.js +364 -0
  130. package/dist/cli/telemetry.js.map +1 -0
  131. package/dist/cli/tui.d.ts +17 -0
  132. package/dist/cli/tui.js +52 -0
  133. package/dist/cli/tui.js.map +1 -0
  134. package/dist/cli/ui.d.ts +53 -0
  135. package/dist/cli/ui.js +66 -0
  136. package/dist/cli/ui.js.map +1 -0
  137. package/dist/cli/update.d.ts +38 -0
  138. package/dist/cli/update.js +682 -0
  139. package/dist/cli/update.js.map +1 -0
  140. package/dist/cli/vercel.d.ts +20 -0
  141. package/dist/cli/vercel.js +193 -0
  142. package/dist/cli/vercel.js.map +1 -0
  143. package/dist/cli/verify-safety.d.ts +96 -0
  144. package/dist/cli/verify-safety.js +509 -0
  145. package/dist/cli/verify-safety.js.map +1 -0
  146. package/dist/cli/wire.d.ts +22 -0
  147. package/dist/cli/wire.js +205 -0
  148. package/dist/cli/wire.js.map +1 -0
  149. package/dist/core/classify.d.ts +51 -0
  150. package/dist/core/classify.js +450 -0
  151. package/dist/core/classify.js.map +1 -0
  152. package/dist/core/config.d.ts +63 -0
  153. package/dist/core/config.js +474 -0
  154. package/dist/core/config.js.map +1 -0
  155. package/dist/core/daemon/loop.d.ts +74 -0
  156. package/dist/core/daemon/loop.js +618 -0
  157. package/dist/core/daemon/loop.js.map +1 -0
  158. package/dist/core/daemon/state.d.ts +66 -0
  159. package/dist/core/daemon/state.js +197 -0
  160. package/dist/core/daemon/state.js.map +1 -0
  161. package/dist/core/dashboard.d.ts +40 -0
  162. package/dist/core/dashboard.js +463 -0
  163. package/dist/core/dashboard.js.map +1 -0
  164. package/dist/core/digest/build.d.ts +51 -0
  165. package/dist/core/digest/build.js +230 -0
  166. package/dist/core/digest/build.js.map +1 -0
  167. package/dist/core/digest/deliver.d.ts +47 -0
  168. package/dist/core/digest/deliver.js +230 -0
  169. package/dist/core/digest/deliver.js.map +1 -0
  170. package/dist/core/digest/store.d.ts +57 -0
  171. package/dist/core/digest/store.js +223 -0
  172. package/dist/core/digest/store.js.map +1 -0
  173. package/dist/core/doctor-fix.d.ts +21 -0
  174. package/dist/core/doctor-fix.js +440 -0
  175. package/dist/core/doctor-fix.js.map +1 -0
  176. package/dist/core/doctor.d.ts +18 -0
  177. package/dist/core/doctor.js +806 -0
  178. package/dist/core/doctor.js.map +1 -0
  179. package/dist/core/env-bridge.d.ts +64 -0
  180. package/dist/core/env-bridge.js +103 -0
  181. package/dist/core/env-bridge.js.map +1 -0
  182. package/dist/core/genome/capture.d.ts +49 -0
  183. package/dist/core/genome/capture.js +352 -0
  184. package/dist/core/genome/capture.js.map +1 -0
  185. package/dist/core/genome/consolidate.d.ts +38 -0
  186. package/dist/core/genome/consolidate.js +426 -0
  187. package/dist/core/genome/consolidate.js.map +1 -0
  188. package/dist/core/genome/export.d.ts +29 -0
  189. package/dist/core/genome/export.js +102 -0
  190. package/dist/core/genome/export.js.map +1 -0
  191. package/dist/core/genome/playbook.d.ts +33 -0
  192. package/dist/core/genome/playbook.js +320 -0
  193. package/dist/core/genome/playbook.js.map +1 -0
  194. package/dist/core/genome/recall.d.ts +45 -0
  195. package/dist/core/genome/recall.js +293 -0
  196. package/dist/core/genome/recall.js.map +1 -0
  197. package/dist/core/genome/store.d.ts +62 -0
  198. package/dist/core/genome/store.js +711 -0
  199. package/dist/core/genome/store.js.map +1 -0
  200. package/dist/core/git.d.ts +34 -0
  201. package/dist/core/git.js +115 -0
  202. package/dist/core/git.js.map +1 -0
  203. package/dist/core/goals/advance.d.ts +82 -0
  204. package/dist/core/goals/advance.js +263 -0
  205. package/dist/core/goals/advance.js.map +1 -0
  206. package/dist/core/goals/planner.d.ts +58 -0
  207. package/dist/core/goals/planner.js +233 -0
  208. package/dist/core/goals/planner.js.map +1 -0
  209. package/dist/core/goals/store.d.ts +128 -0
  210. package/dist/core/goals/store.js +442 -0
  211. package/dist/core/goals/store.js.map +1 -0
  212. package/dist/core/inbox/apply.d.ts +36 -0
  213. package/dist/core/inbox/apply.js +407 -0
  214. package/dist/core/inbox/apply.js.map +1 -0
  215. package/dist/core/inbox/notify-proposal.d.ts +13 -0
  216. package/dist/core/inbox/notify-proposal.js +21 -0
  217. package/dist/core/inbox/notify-proposal.js.map +1 -0
  218. package/dist/core/inbox/store.d.ts +67 -0
  219. package/dist/core/inbox/store.js +258 -0
  220. package/dist/core/inbox/store.js.map +1 -0
  221. package/dist/core/index-engine.d.ts +62 -0
  222. package/dist/core/index-engine.js +486 -0
  223. package/dist/core/index-engine.js.map +1 -0
  224. package/dist/core/integrations/desktop-notify.d.ts +18 -0
  225. package/dist/core/integrations/desktop-notify.js +42 -0
  226. package/dist/core/integrations/desktop-notify.js.map +1 -0
  227. package/dist/core/integrations/editors.d.ts +50 -0
  228. package/dist/core/integrations/editors.js +216 -0
  229. package/dist/core/integrations/editors.js.map +1 -0
  230. package/dist/core/integrations/github.d.ts +66 -0
  231. package/dist/core/integrations/github.js +332 -0
  232. package/dist/core/integrations/github.js.map +1 -0
  233. package/dist/core/integrations/identity.d.ts +29 -0
  234. package/dist/core/integrations/identity.js +359 -0
  235. package/dist/core/integrations/identity.js.map +1 -0
  236. package/dist/core/integrations/notify.d.ts +23 -0
  237. package/dist/core/integrations/notify.js +96 -0
  238. package/dist/core/integrations/notify.js.map +1 -0
  239. package/dist/core/integrations/vercel.d.ts +37 -0
  240. package/dist/core/integrations/vercel.js +192 -0
  241. package/dist/core/integrations/vercel.js.map +1 -0
  242. package/dist/core/knowledge/ask.d.ts +34 -0
  243. package/dist/core/knowledge/ask.js +325 -0
  244. package/dist/core/knowledge/ask.js.map +1 -0
  245. package/dist/core/knowledge/graph.d.ts +51 -0
  246. package/dist/core/knowledge/graph.js +564 -0
  247. package/dist/core/knowledge/graph.js.map +1 -0
  248. package/dist/core/knowledge/index.d.ts +74 -0
  249. package/dist/core/knowledge/index.js +586 -0
  250. package/dist/core/knowledge/index.js.map +1 -0
  251. package/dist/core/learn/playbooks.d.ts +84 -0
  252. package/dist/core/learn/playbooks.js +241 -0
  253. package/dist/core/learn/playbooks.js.map +1 -0
  254. package/dist/core/learn/reflect.d.ts +87 -0
  255. package/dist/core/learn/reflect.js +435 -0
  256. package/dist/core/learn/reflect.js.map +1 -0
  257. package/dist/core/learn/store.d.ts +51 -0
  258. package/dist/core/learn/store.js +165 -0
  259. package/dist/core/learn/store.js.map +1 -0
  260. package/dist/core/learn/tuning.d.ts +48 -0
  261. package/dist/core/learn/tuning.js +201 -0
  262. package/dist/core/learn/tuning.js.map +1 -0
  263. package/dist/core/lifecycle/scaffold.d.ts +43 -0
  264. package/dist/core/lifecycle/scaffold.js +260 -0
  265. package/dist/core/lifecycle/scaffold.js.map +1 -0
  266. package/dist/core/lifecycle/ship.d.ts +48 -0
  267. package/dist/core/lifecycle/ship.js +513 -0
  268. package/dist/core/lifecycle/ship.js.map +1 -0
  269. package/dist/core/lifecycle/templates.d.ts +20 -0
  270. package/dist/core/lifecycle/templates.js +605 -0
  271. package/dist/core/lifecycle/templates.js.map +1 -0
  272. package/dist/core/mcp-gateway.d.ts +59 -0
  273. package/dist/core/mcp-gateway.js +385 -0
  274. package/dist/core/mcp-gateway.js.map +1 -0
  275. package/dist/core/mcp-native.d.ts +53 -0
  276. package/dist/core/mcp-native.js +507 -0
  277. package/dist/core/mcp-native.js.map +1 -0
  278. package/dist/core/mcp-registry.d.ts +36 -0
  279. package/dist/core/mcp-registry.js +180 -0
  280. package/dist/core/mcp-registry.js.map +1 -0
  281. package/dist/core/observability/budget-alert.d.ts +18 -0
  282. package/dist/core/observability/budget-alert.js +90 -0
  283. package/dist/core/observability/budget-alert.js.map +1 -0
  284. package/dist/core/observability/estimate.d.ts +27 -0
  285. package/dist/core/observability/estimate.js +188 -0
  286. package/dist/core/observability/estimate.js.map +1 -0
  287. package/dist/core/observability/forecast.d.ts +19 -0
  288. package/dist/core/observability/forecast.js +101 -0
  289. package/dist/core/observability/forecast.js.map +1 -0
  290. package/dist/core/observability/governance.d.ts +28 -0
  291. package/dist/core/observability/governance.js +101 -0
  292. package/dist/core/observability/governance.js.map +1 -0
  293. package/dist/core/observability/otlp.d.ts +88 -0
  294. package/dist/core/observability/otlp.js +217 -0
  295. package/dist/core/observability/otlp.js.map +1 -0
  296. package/dist/core/observability/rollup.d.ts +35 -0
  297. package/dist/core/observability/rollup.js +311 -0
  298. package/dist/core/observability/rollup.js.map +1 -0
  299. package/dist/core/observability/telemetry-sink.d.ts +63 -0
  300. package/dist/core/observability/telemetry-sink.js +350 -0
  301. package/dist/core/observability/telemetry-sink.js.map +1 -0
  302. package/dist/core/observability/usage-source.d.ts +60 -0
  303. package/dist/core/observability/usage-source.js +347 -0
  304. package/dist/core/observability/usage-source.js.map +1 -0
  305. package/dist/core/onboard.d.ts +27 -0
  306. package/dist/core/onboard.js +288 -0
  307. package/dist/core/onboard.js.map +1 -0
  308. package/dist/core/orient.d.ts +23 -0
  309. package/dist/core/orient.js +135 -0
  310. package/dist/core/orient.js.map +1 -0
  311. package/dist/core/phantom.d.ts +23 -0
  312. package/dist/core/phantom.js +279 -0
  313. package/dist/core/phantom.js.map +1 -0
  314. package/dist/core/plugins/host-api.d.ts +29 -0
  315. package/dist/core/plugins/host-api.js +113 -0
  316. package/dist/core/plugins/host-api.js.map +1 -0
  317. package/dist/core/plugins/integrity.d.ts +36 -0
  318. package/dist/core/plugins/integrity.js +73 -0
  319. package/dist/core/plugins/integrity.js.map +1 -0
  320. package/dist/core/plugins/manifest.d.ts +31 -0
  321. package/dist/core/plugins/manifest.js +316 -0
  322. package/dist/core/plugins/manifest.js.map +1 -0
  323. package/dist/core/plugins/registry.d.ts +87 -0
  324. package/dist/core/plugins/registry.js +415 -0
  325. package/dist/core/plugins/registry.js.map +1 -0
  326. package/dist/core/plugins/types.d.ts +182 -0
  327. package/dist/core/plugins/types.js +40 -0
  328. package/dist/core/plugins/types.js.map +1 -0
  329. package/dist/core/plugins/wrappers.d.ts +40 -0
  330. package/dist/core/plugins/wrappers.js +229 -0
  331. package/dist/core/plugins/wrappers.js.map +1 -0
  332. package/dist/core/portfolio/backlog.d.ts +40 -0
  333. package/dist/core/portfolio/backlog.js +177 -0
  334. package/dist/core/portfolio/backlog.js.map +1 -0
  335. package/dist/core/portfolio/scanners.d.ts +21 -0
  336. package/dist/core/portfolio/scanners.js +600 -0
  337. package/dist/core/portfolio/scanners.js.map +1 -0
  338. package/dist/core/providers.d.ts +34 -0
  339. package/dist/core/providers.js +250 -0
  340. package/dist/core/providers.js.map +1 -0
  341. package/dist/core/quality/conventions.d.ts +35 -0
  342. package/dist/core/quality/conventions.js +267 -0
  343. package/dist/core/quality/conventions.js.map +1 -0
  344. package/dist/core/quality/fixes.d.ts +56 -0
  345. package/dist/core/quality/fixes.js +209 -0
  346. package/dist/core/quality/fixes.js.map +1 -0
  347. package/dist/core/quality/health.d.ts +69 -0
  348. package/dist/core/quality/health.js +350 -0
  349. package/dist/core/quality/health.js.map +1 -0
  350. package/dist/core/quality/store.d.ts +56 -0
  351. package/dist/core/quality/store.js +195 -0
  352. package/dist/core/quality/store.js.map +1 -0
  353. package/dist/core/readiness.d.ts +112 -0
  354. package/dist/core/readiness.js +431 -0
  355. package/dist/core/readiness.js.map +1 -0
  356. package/dist/core/run/agent-loop.d.ts +40 -0
  357. package/dist/core/run/agent-loop.js +291 -0
  358. package/dist/core/run/agent-loop.js.map +1 -0
  359. package/dist/core/run/budget.d.ts +47 -0
  360. package/dist/core/run/budget.js +113 -0
  361. package/dist/core/run/budget.js.map +1 -0
  362. package/dist/core/run/engines.d.ts +75 -0
  363. package/dist/core/run/engines.js +199 -0
  364. package/dist/core/run/engines.js.map +1 -0
  365. package/dist/core/run/model-manager.d.ts +64 -0
  366. package/dist/core/run/model-manager.js +339 -0
  367. package/dist/core/run/model-manager.js.map +1 -0
  368. package/dist/core/run/orchestrator.d.ts +100 -0
  369. package/dist/core/run/orchestrator.js +1515 -0
  370. package/dist/core/run/orchestrator.js.map +1 -0
  371. package/dist/core/run/provider-client.d.ts +46 -0
  372. package/dist/core/run/provider-client.js +796 -0
  373. package/dist/core/run/provider-client.js.map +1 -0
  374. package/dist/core/run/retry.d.ts +19 -0
  375. package/dist/core/run/retry.js +68 -0
  376. package/dist/core/run/retry.js.map +1 -0
  377. package/dist/core/run/router.d.ts +50 -0
  378. package/dist/core/run/router.js +257 -0
  379. package/dist/core/run/router.js.map +1 -0
  380. package/dist/core/run/self-heal.d.ts +52 -0
  381. package/dist/core/run/self-heal.js +181 -0
  382. package/dist/core/run/self-heal.js.map +1 -0
  383. package/dist/core/run/streaming.d.ts +31 -0
  384. package/dist/core/run/streaming.js +122 -0
  385. package/dist/core/run/streaming.js.map +1 -0
  386. package/dist/core/run/verify.d.ts +30 -0
  387. package/dist/core/run/verify.js +204 -0
  388. package/dist/core/run/verify.js.map +1 -0
  389. package/dist/core/sandbox/audit.d.ts +31 -0
  390. package/dist/core/sandbox/audit.js +169 -0
  391. package/dist/core/sandbox/audit.js.map +1 -0
  392. package/dist/core/sandbox/policy.d.ts +61 -0
  393. package/dist/core/sandbox/policy.js +211 -0
  394. package/dist/core/sandbox/policy.js.map +1 -0
  395. package/dist/core/sandbox/worktree.d.ts +175 -0
  396. package/dist/core/sandbox/worktree.js +673 -0
  397. package/dist/core/sandbox/worktree.js.map +1 -0
  398. package/dist/core/seams/backlog.d.ts +47 -0
  399. package/dist/core/seams/backlog.js +47 -0
  400. package/dist/core/seams/backlog.js.map +1 -0
  401. package/dist/core/seams/daemon-coordinator.d.ts +72 -0
  402. package/dist/core/seams/daemon-coordinator.js +76 -0
  403. package/dist/core/seams/daemon-coordinator.js.map +1 -0
  404. package/dist/core/seams/genome.d.ts +45 -0
  405. package/dist/core/seams/genome.js +53 -0
  406. package/dist/core/seams/genome.js.map +1 -0
  407. package/dist/core/seams/identity.d.ts +40 -0
  408. package/dist/core/seams/identity.js +44 -0
  409. package/dist/core/seams/identity.js.map +1 -0
  410. package/dist/core/seams/inbox.d.ts +60 -0
  411. package/dist/core/seams/inbox.js +66 -0
  412. package/dist/core/seams/inbox.js.map +1 -0
  413. package/dist/core/seams/index.d.ts +20 -0
  414. package/dist/core/seams/index.js +21 -0
  415. package/dist/core/seams/index.js.map +1 -0
  416. package/dist/core/seams/portfolio.d.ts +50 -0
  417. package/dist/core/seams/portfolio.js +61 -0
  418. package/dist/core/seams/portfolio.js.map +1 -0
  419. package/dist/core/seams/registry.d.ts +42 -0
  420. package/dist/core/seams/registry.js +128 -0
  421. package/dist/core/seams/registry.js.map +1 -0
  422. package/dist/core/seams/run-swarm.d.ts +66 -0
  423. package/dist/core/seams/run-swarm.js +74 -0
  424. package/dist/core/seams/run-swarm.js.map +1 -0
  425. package/dist/core/seams/types.d.ts +123 -0
  426. package/dist/core/seams/types.js +35 -0
  427. package/dist/core/seams/types.js.map +1 -0
  428. package/dist/core/spec/spec-store.d.ts +62 -0
  429. package/dist/core/spec/spec-store.js +359 -0
  430. package/dist/core/spec/spec-store.js.map +1 -0
  431. package/dist/core/swarm/gate.d.ts +45 -0
  432. package/dist/core/swarm/gate.js +114 -0
  433. package/dist/core/swarm/gate.js.map +1 -0
  434. package/dist/core/swarm/planner.d.ts +32 -0
  435. package/dist/core/swarm/planner.js +293 -0
  436. package/dist/core/swarm/planner.js.map +1 -0
  437. package/dist/core/swarm/rollback.d.ts +56 -0
  438. package/dist/core/swarm/rollback.js +266 -0
  439. package/dist/core/swarm/rollback.js.map +1 -0
  440. package/dist/core/swarm/runner.d.ts +62 -0
  441. package/dist/core/swarm/runner.js +1263 -0
  442. package/dist/core/swarm/runner.js.map +1 -0
  443. package/dist/core/swarm/sign.d.ts +71 -0
  444. package/dist/core/swarm/sign.js +362 -0
  445. package/dist/core/swarm/sign.js.map +1 -0
  446. package/dist/core/swarm/store.d.ts +52 -0
  447. package/dist/core/swarm/store.js +195 -0
  448. package/dist/core/swarm/store.js.map +1 -0
  449. package/dist/core/tidy.d.ts +32 -0
  450. package/dist/core/tidy.js +354 -0
  451. package/dist/core/tidy.js.map +1 -0
  452. package/dist/core/tools-registry.d.ts +16 -0
  453. package/dist/core/tools-registry.js +308 -0
  454. package/dist/core/tools-registry.js.map +1 -0
  455. package/dist/core/types.d.ts +2545 -0
  456. package/dist/core/types.js +9 -0
  457. package/dist/core/types.js.map +1 -0
  458. package/dist/core/web/api.d.ts +53 -0
  459. package/dist/core/web/api.js +698 -0
  460. package/dist/core/web/api.js.map +1 -0
  461. package/dist/core/web/public/app.js +1906 -0
  462. package/dist/core/web/public/index.html +721 -0
  463. package/dist/core/web/public/styles.css +2007 -0
  464. package/dist/core/web/server.d.ts +18 -0
  465. package/dist/core/web/server.js +122 -0
  466. package/dist/core/web/server.js.map +1 -0
  467. package/dist/core/web/static.d.ts +18 -0
  468. package/dist/core/web/static.js +122 -0
  469. package/dist/core/web/static.js.map +1 -0
  470. package/dist/tui/app.d.ts +33 -0
  471. package/dist/tui/app.js +350 -0
  472. package/dist/tui/app.js.map +1 -0
  473. package/dist/tui/render.d.ts +20 -0
  474. package/dist/tui/render.js +558 -0
  475. package/dist/tui/render.js.map +1 -0
  476. package/package.json +80 -0
  477. package/schema/config.schema.json +223 -0
@@ -0,0 +1,209 @@
1
+ /**
2
+ * fixes.ts — Deterministic advisory SAFE FIXES + PROPOSAL emission (M27).
3
+ *
4
+ * HARD SAFETY INVARIANTS (enforced throughout this file):
5
+ * - PROPOSAL-ONLY: emitFixProposals routes each SafeFix to the M23 Approval
6
+ * Inbox via createProposal() as a PENDING proposal (status 'pending', NEVER
7
+ * auto-advanced/applied). The default proposal kind is 'note' (advisory, no
8
+ * diff), origin 'manual'.
9
+ * - READ-ONLY / NO MUTATION: deriveSafeFixes is a pure function of a
10
+ * HealthScore. NEITHER function writes to a user repo, writes CONFIG, pushes,
11
+ * opens a PR, or deploys. There is NO apply path here.
12
+ * - OPTIONAL SANDBOX-PATCH (STRETCH, documented only): if a deterministic fix
13
+ * diff is ever generated, it MUST be produced in an M21 sandbox worktree
14
+ * (src/core/sandbox/*) and attached to a PENDING 'patch' proposal — NEVER
15
+ * written to the real tree, NEVER pushed. The DEFAULT is advisory 'note's.
16
+ * - Bounded: caps fixes emitted per run. Never throws (createProposal best-effort).
17
+ * - No secrets: SafeFix / proposal fields are advisory metadata only.
18
+ */
19
+ import { createProposal } from '../inbox/store.js';
20
+ // ---------------------------------------------------------------------------
21
+ // Bounds
22
+ // ---------------------------------------------------------------------------
23
+ /** Hard cap on advisory fixes derived per repo (bounds inbox noise). */
24
+ const MAX_FIXES_PER_REPO = 10;
25
+ /** Max worst-offenders to mine for fixes (defensive — worstOffenders is already capped upstream). */
26
+ const MAX_OFFENDERS_SCANNED = 20;
27
+ // ---------------------------------------------------------------------------
28
+ // Convention probe -> advisory fix mapping
29
+ // ---------------------------------------------------------------------------
30
+ /**
31
+ * Deterministic mapping from a FAILED ConventionFinding.key to the advisory
32
+ * fix it implies. Each entry yields a stable SafeFix.key, the dimension the fix
33
+ * improves, and a short title. The rationale is composed from the probe's own
34
+ * (already secret-free) detail at derive time. Keys not present here are
35
+ * skipped — we only advise fixes we can phrase concretely.
36
+ */
37
+ const CONVENTION_FIXES = {
38
+ license: { key: 'docs.add-license', dimension: 'docs', title: 'Add a LICENSE file' },
39
+ readme: { key: 'docs.add-readme', dimension: 'docs', title: 'Add or expand the README' },
40
+ gitignore: {
41
+ key: 'conventions.add-gitignore',
42
+ dimension: 'conventions',
43
+ title: 'Add a .gitignore',
44
+ },
45
+ lockfile: {
46
+ key: 'conventions.add-lockfile',
47
+ dimension: 'conventions',
48
+ title: 'Commit a dependency lockfile',
49
+ },
50
+ ci: { key: 'conventions.add-ci', dimension: 'conventions', title: 'Add a CI workflow' },
51
+ testdir: { key: 'tests.add-test', dimension: 'tests', title: 'Add a test suite' },
52
+ };
53
+ // ---------------------------------------------------------------------------
54
+ // WorkItem (worst-offender) -> advisory fix mapping
55
+ // ---------------------------------------------------------------------------
56
+ /** Deterministic, key-safe slug of an arbitrary title (bounded length). */
57
+ function slug(s) {
58
+ return s
59
+ .toLowerCase()
60
+ .replace(/[^a-z0-9]+/g, '-')
61
+ .replace(/^-+|-+$/g, '')
62
+ .slice(0, 48);
63
+ }
64
+ /**
65
+ * Map a worst-offender WorkItem onto a SafeFix when it represents an actionable,
66
+ * concretely-phraseable gap (vulnerable/stale dep, missing test, high TODO debt).
67
+ * Returns null for sources we cannot phrase a safe deterministic advisory for
68
+ * (e.g. open issues, security findings — surfaced in the report, not auto-noted).
69
+ *
70
+ * Deterministic; the per-item `key` is namespaced by source so distinct findings
71
+ * dedupe independently (e.g. one fix per vulnerable dependency).
72
+ */
73
+ function fixFromOffender(item) {
74
+ switch (item.source) {
75
+ case 'dep':
76
+ return {
77
+ repo: item.repo,
78
+ dimension: 'deps',
79
+ key: `deps.upgrade:${slug(item.title)}`,
80
+ title: `Update dependency: ${item.title}`,
81
+ rationale: `A dependency finding is dragging the deps score down: ${item.detail}`,
82
+ proposalKind: 'note',
83
+ };
84
+ case 'test':
85
+ return {
86
+ repo: item.repo,
87
+ dimension: 'tests',
88
+ key: `tests.add-test:${slug(item.title)}`,
89
+ title: `Add test coverage: ${item.title}`,
90
+ rationale: `A test gap is lowering the tests score: ${item.detail}`,
91
+ proposalKind: 'note',
92
+ };
93
+ case 'todo':
94
+ return {
95
+ repo: item.repo,
96
+ dimension: 'codeDebt',
97
+ key: `codeDebt.resolve:${slug(item.title)}`,
98
+ title: `Resolve code-debt marker: ${item.title}`,
99
+ rationale: `An accumulating TODO/FIXME marker is adding code debt: ${item.detail}`,
100
+ proposalKind: 'note',
101
+ };
102
+ default:
103
+ // issue / doc / security offenders are reported but not auto-noted as fixes
104
+ // here — they map onto convention probes (docs) or are advisory-only signals.
105
+ return null;
106
+ }
107
+ }
108
+ // ---------------------------------------------------------------------------
109
+ // deriveSafeFixes — pure, deterministic
110
+ // ---------------------------------------------------------------------------
111
+ /**
112
+ * Derive deterministic, advisory SafeFix[] from a per-repo HealthScore.
113
+ *
114
+ * Walks the score's failed convention probes (ok === false) and worst offenders,
115
+ * mapping each actionable, concretely-phraseable gap into an advisory SafeFix:
116
+ * - missing LICENSE -> { dimension:'docs', key:'docs.add-license' }
117
+ * - missing README -> { dimension:'docs', key:'docs.add-readme' }
118
+ * - missing .gitignore -> { dimension:'conventions', key:'conventions.add-gitignore' }
119
+ * - missing lockfile/CI -> { dimension:'conventions', key:'conventions.add-{lockfile,ci}' }
120
+ * - vulnerable/stale dep -> { dimension:'deps', key:'deps.upgrade:<pkg>' }
121
+ * - missing test -> { dimension:'tests', key:'tests.add-test[:…]' }
122
+ * - high TODO debt -> { dimension:'codeDebt', key:'codeDebt.resolve:…' }
123
+ *
124
+ * Pure function (no I/O), deterministic ordering, deduped by `key`, bounded to
125
+ * MAX_FIXES_PER_REPO. Every SafeFix defaults to proposalKind 'note' (advisory).
126
+ * NEVER mutates anything.
127
+ */
128
+ export function deriveSafeFixes(score) {
129
+ const repo = score.repo;
130
+ // Insertion-ordered dedupe by key. Convention fixes are collected first
131
+ // (highest-leverage, lowest-effort gaps), then offender-derived fixes.
132
+ const byKey = new Map();
133
+ // 1) Failed convention probes -> known advisory fixes.
134
+ for (const finding of score.conventions) {
135
+ if (finding.ok)
136
+ continue;
137
+ const mapped = CONVENTION_FIXES[finding.key];
138
+ if (mapped === undefined)
139
+ continue;
140
+ if (byKey.has(mapped.key))
141
+ continue;
142
+ byKey.set(mapped.key, {
143
+ repo,
144
+ dimension: mapped.dimension,
145
+ key: mapped.key,
146
+ title: mapped.title,
147
+ rationale: finding.detail || `${finding.label} convention is not satisfied.`,
148
+ proposalKind: 'note',
149
+ });
150
+ }
151
+ // 2) Worst-offender WorkItems -> per-finding advisory fixes.
152
+ const offenders = score.worstOffenders.slice(0, MAX_OFFENDERS_SCANNED);
153
+ for (const item of offenders) {
154
+ const fix = fixFromOffender(item);
155
+ if (fix === null)
156
+ continue;
157
+ if (byKey.has(fix.key))
158
+ continue;
159
+ byKey.set(fix.key, fix);
160
+ }
161
+ // Deterministic ordering: convention fixes lead (insertion order); offender
162
+ // fixes preserve the upstream worst-first ordering of worstOffenders.
163
+ return [...byKey.values()].slice(0, MAX_FIXES_PER_REPO);
164
+ }
165
+ // ---------------------------------------------------------------------------
166
+ // emitFixProposals — PENDING inbox proposals (PROPOSAL-ONLY)
167
+ // ---------------------------------------------------------------------------
168
+ /**
169
+ * Emit each SafeFix as a PENDING M23 Approval Inbox proposal.
170
+ *
171
+ * For each fix: createProposal({ repo, origin: 'manual', kind: 'note', title,
172
+ * summary }) — status is assigned 'pending' BY THE STORE and NEVER auto-advanced.
173
+ * Default kind is 'note' (advisory, no diff). M27 does NOT apply patches and does
174
+ * NOT mutate working trees here; this module advances no proposal status, pushes
175
+ * nothing, opens no PR, and deploys nothing — createProposal() is its ONLY effect.
176
+ *
177
+ * (STRETCH, NOT wired by default) A fix with proposalKind 'patch' would require
178
+ * generating its diff in an M21 sandbox worktree and attaching it as a PENDING
179
+ * 'patch' proposal with the sandboxId — never written to the real tree. This
180
+ * build emits NOTES ONLY; any 'patch'-kind SafeFix is downgraded to a 'note'
181
+ * proposal here (no diff is produced), keeping the inbox advisory.
182
+ *
183
+ * Returns the created Proposal[] (pending). Never throws (createProposal is
184
+ * best-effort and returns the in-memory proposal even on persistence failure).
185
+ */
186
+ export function emitFixProposals(fixes) {
187
+ const proposals = [];
188
+ for (const fix of fixes) {
189
+ try {
190
+ const proposal = createProposal({
191
+ repo: fix.repo,
192
+ origin: 'manual',
193
+ // NOTES-ONLY in this build: never attach a diff, never request 'patch'
194
+ // application. A 'patch' SafeFix is recorded as an advisory note here.
195
+ kind: 'note',
196
+ title: `[health] ${fix.title}`,
197
+ summary: `${fix.rationale}\n\n` +
198
+ `Dimension: ${fix.dimension} · fix-key: ${fix.key} · repo: ${fix.repo}\n` +
199
+ `Advisory only — review and apply manually. This proposal mutates nothing.`,
200
+ });
201
+ proposals.push(proposal);
202
+ }
203
+ catch {
204
+ // Best-effort: a single createProposal failure must not abort the batch.
205
+ }
206
+ }
207
+ return proposals;
208
+ }
209
+ //# sourceMappingURL=fixes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fixes.js","sourceRoot":"","sources":["../../../src/core/quality/fixes.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,69 @@
1
+ /**
2
+ * health.ts — Deterministic per-repo + portfolio HEALTH SCORING (M27).
3
+ *
4
+ * HARD SAFETY INVARIANTS (enforced throughout this file):
5
+ * - READ-ONLY: composes the six M22 read-only scanners (SCANNERS) + the
6
+ * read-only convention probes. WRITES NOTHING here (the quality store owns
7
+ * ~/.ashlr/quality snapshots; the CLI owns proposals). NEVER mutates a repo.
8
+ * - ENROLLMENT-SCOPED: computeReport defaults its repo set to listEnrolled()
9
+ * (DEFAULT EMPTY => empty report, no disk scan). When an explicit `repos`
10
+ * list is supplied, EACH entry is filtered through isEnrolled() (resolve()
11
+ * first) and a non-enrolled path HARD-ERRORS. This closes the exact gap the
12
+ * M25 review caught — enforced at the CORE layer here AND again at the CLI.
13
+ * - LOCAL-FIRST / NO LLM: scoring is deterministic and uses NO model. M27
14
+ * ships no LLM narrative path, so this module makes zero connections beyond
15
+ * what the M22 scanners already do.
16
+ * - BOUNDED: reuses the scanners' built-in bounds; caps repos per run
17
+ * (maxRepos) and worst-offenders per repo. No unbounded loops.
18
+ * - Never throws on a per-repo basis: a scanner failure yields [] (scanner
19
+ * contract); computeHealth additionally guards each scanner so a single
20
+ * rejection degrades that dimension to a neutral/penalized state with a
21
+ * note rather than crashing the whole report. computeReport surfaces an
22
+ * enrollment violation as a hard error (the only intentional throw).
23
+ */
24
+ import type { HealthOptions, HealthReport, HealthScore } from '../types.js';
25
+ /**
26
+ * Map a 0..100 score to a letter grade: A>=90, B>=80, C>=70, D>=60, else F.
27
+ * Exported so the report layer derives the average grade with the same rule.
28
+ */
29
+ export declare function gradeFor(score: number): HealthScore['grade'];
30
+ /**
31
+ * Compute the per-repo HealthScore for `repo` (an absolute path).
32
+ *
33
+ * Runs all six SCANNERS (in parallel; each individually bounded + never throws)
34
+ * plus probeConventions(repo), maps their outputs onto the HealthDimensions,
35
+ * scores each dimension 0..100, rolls them up into a weighted overall 0..100 +
36
+ * letter grade, and records the worst offenders (highest WorkItem.score),
37
+ * bounded to MAX_WORST_OFFENDERS.
38
+ *
39
+ * Deterministic, READ-ONLY, NO LLM. Never mutates `repo`. Never throws on a
40
+ * scanner/probe failure (it degrades to a neutral/penalized dimension with a
41
+ * note); the ONLY intentional throw is the enrollment guard below.
42
+ *
43
+ * ENROLLMENT-SCOPED (CORE layer, invariant #2): this per-repo entry point
44
+ * self-defends — `repo` is resolve()'d and filtered through isEnrolled(), and a
45
+ * NON-ENROLLED path HARD-ERRORS before any disk scan. This is defense-in-depth
46
+ * matching computeReport: the CLI already gates the positional --repo, and
47
+ * computeReport already filters via isEnrolled before calling here, so enrolled
48
+ * callers pass through unaffected. The guard closes the single-layer gap class
49
+ * the M25 review caught (the M27 contract requires enrollment at BOTH layers).
50
+ */
51
+ export declare function computeHealth(repo: string): Promise<HealthScore>;
52
+ /**
53
+ * Compute the portfolio-wide HealthReport over enrolled repos.
54
+ *
55
+ * Repo selection:
56
+ * - opts.repos omitted => listEnrolled() (DEFAULT EMPTY => empty report; NO
57
+ * disk scan when nothing is enrolled).
58
+ * - opts.repos provided => EACH entry is resolve()'d and filtered through
59
+ * isEnrolled(); a NON-ENROLLED path HARD-ERRORS
60
+ * (throws) — never silently scanned. (M25 lesson.)
61
+ *
62
+ * Bounded by opts.maxRepos (default DEFAULT_MAX_REPOS). Scores each selected
63
+ * repo via computeHealth (sequentially, mirroring buildBacklog to avoid a
64
+ * gh/npm thundering-herd), ranks worst-first, computes averageScore/grade, and
65
+ * leaves `delta` for the store/CLI layer to fill from loadPreviousReport().
66
+ *
67
+ * Deterministic, READ-ONLY, NO LLM. Never mutates any repo.
68
+ */
69
+ export declare function computeReport(opts?: HealthOptions): Promise<HealthReport>;
@@ -0,0 +1,350 @@
1
+ /**
2
+ * health.ts — Deterministic per-repo + portfolio HEALTH SCORING (M27).
3
+ *
4
+ * HARD SAFETY INVARIANTS (enforced throughout this file):
5
+ * - READ-ONLY: composes the six M22 read-only scanners (SCANNERS) + the
6
+ * read-only convention probes. WRITES NOTHING here (the quality store owns
7
+ * ~/.ashlr/quality snapshots; the CLI owns proposals). NEVER mutates a repo.
8
+ * - ENROLLMENT-SCOPED: computeReport defaults its repo set to listEnrolled()
9
+ * (DEFAULT EMPTY => empty report, no disk scan). When an explicit `repos`
10
+ * list is supplied, EACH entry is filtered through isEnrolled() (resolve()
11
+ * first) and a non-enrolled path HARD-ERRORS. This closes the exact gap the
12
+ * M25 review caught — enforced at the CORE layer here AND again at the CLI.
13
+ * - LOCAL-FIRST / NO LLM: scoring is deterministic and uses NO model. M27
14
+ * ships no LLM narrative path, so this module makes zero connections beyond
15
+ * what the M22 scanners already do.
16
+ * - BOUNDED: reuses the scanners' built-in bounds; caps repos per run
17
+ * (maxRepos) and worst-offenders per repo. No unbounded loops.
18
+ * - Never throws on a per-repo basis: a scanner failure yields [] (scanner
19
+ * contract); computeHealth additionally guards each scanner so a single
20
+ * rejection degrades that dimension to a neutral/penalized state with a
21
+ * note rather than crashing the whole report. computeReport surfaces an
22
+ * enrollment violation as a hard error (the only intentional throw).
23
+ */
24
+ import { resolve } from 'node:path';
25
+ import { SCANNERS } from '../portfolio/scanners.js';
26
+ import { isEnrolled, listEnrolled } from '../sandbox/policy.js';
27
+ import { probeConventions } from './conventions.js';
28
+ // ---------------------------------------------------------------------------
29
+ // Bounds / weights
30
+ // ---------------------------------------------------------------------------
31
+ /** Hard cap on repos scored per run (bounds work). */
32
+ const DEFAULT_MAX_REPOS = 100;
33
+ /** Cap on worst-offender WorkItems retained per repo. */
34
+ const MAX_WORST_OFFENDERS = 5;
35
+ /**
36
+ * Relative weights for the overall 0..100 roll-up. Deterministic; sums are
37
+ * normalized at compute time so they need not total 100 here.
38
+ */
39
+ const DIMENSION_WEIGHTS = {
40
+ tests: 20,
41
+ docs: 10,
42
+ deps: 15,
43
+ security: 25,
44
+ codeDebt: 10,
45
+ issuesCi: 10,
46
+ conventions: 10,
47
+ };
48
+ /** Stable, deterministic order the dimensions are reported in. */
49
+ const DIMENSION_ORDER = [
50
+ 'tests',
51
+ 'docs',
52
+ 'deps',
53
+ 'security',
54
+ 'codeDebt',
55
+ 'issuesCi',
56
+ 'conventions',
57
+ ];
58
+ /**
59
+ * Maps each scanner's WorkSource onto the HealthDimension it feeds.
60
+ * issue -> issuesCi (open GitHub issues + CI signal)
61
+ * todo -> codeDebt (TODO/FIXME/HACK/XXX markers)
62
+ * test -> tests (test-script presence + CI state)
63
+ * dep -> deps (freshness + npm-audit vulnerabilities)
64
+ * doc -> docs (README/LICENSE/CONTRIBUTING presence + thinness)
65
+ * security -> security (binshield findings)
66
+ * The seventh dimension, `conventions`, is fed by probeConventions (not a
67
+ * WorkSource), so it is intentionally absent from this map.
68
+ */
69
+ const SOURCE_TO_DIMENSION = {
70
+ issue: 'issuesCi',
71
+ todo: 'codeDebt',
72
+ test: 'tests',
73
+ dep: 'deps',
74
+ doc: 'docs',
75
+ security: 'security',
76
+ plugin: 'codeDebt', // M33: plugin items map to codeDebt dimension (best-fit)
77
+ };
78
+ /**
79
+ * Per-finding penalty applied to a dimension's 0..100 score. A WorkItem's
80
+ * `value` field is a 1..5 severity proxy (5 = critical); we map it to a point
81
+ * penalty so more/severe findings drive the dimension score down deterministically.
82
+ */
83
+ function findingPenalty(item) {
84
+ // value 1..5 (clamped by the scanners). Penalty grows with severity:
85
+ // 1->6, 2->12, 3->18, 4->24, 5->30 points. Deterministic.
86
+ const v = Math.max(1, Math.min(5, Math.round(item.value)));
87
+ return v * 6;
88
+ }
89
+ /**
90
+ * Penalty for a FAILED convention probe (ok=false), weighted 1..5. A higher
91
+ * `weight` means a more important miss. Mirrors findingPenalty's scale.
92
+ */
93
+ function conventionPenalty(weight) {
94
+ const w = Math.max(1, Math.min(5, Math.round(weight)));
95
+ return w * 6;
96
+ }
97
+ // ---------------------------------------------------------------------------
98
+ // Grade derivation (deterministic)
99
+ // ---------------------------------------------------------------------------
100
+ /**
101
+ * Map a 0..100 score to a letter grade: A>=90, B>=80, C>=70, D>=60, else F.
102
+ * Exported so the report layer derives the average grade with the same rule.
103
+ */
104
+ export function gradeFor(score) {
105
+ if (score >= 90)
106
+ return 'A';
107
+ if (score >= 80)
108
+ return 'B';
109
+ if (score >= 70)
110
+ return 'C';
111
+ if (score >= 60)
112
+ return 'D';
113
+ return 'F';
114
+ }
115
+ // ---------------------------------------------------------------------------
116
+ // Scanner orchestration (bounded, never-throws-per-scanner)
117
+ // ---------------------------------------------------------------------------
118
+ /**
119
+ * Run all six SCANNERS over `repo` in parallel. Each scanner is bounded and
120
+ * never-throws by the M22 contract, but we additionally guard each one so a
121
+ * single rejection degrades to [] rather than crashing the whole report.
122
+ *
123
+ * We attribute a rejection to the dimension it would have fed (by scanner
124
+ * position in SCANNERS) so that dimension can be conservatively penalized +
125
+ * annotated rather than appearing falsely healthy. Returns the flattened
126
+ * WorkItem[] plus the set of WorkSources whose scanner failed outright.
127
+ */
128
+ async function runScanners(repo) {
129
+ const settled = await Promise.allSettled(SCANNERS.map((s) => s(repo)));
130
+ const items = [];
131
+ const failedSources = new Set();
132
+ // SCANNERS order is fixed (M22): [issues, todos, tests, deps, docs, security].
133
+ const ORDER = ['issue', 'todo', 'test', 'dep', 'doc', 'security'];
134
+ settled.forEach((result, idx) => {
135
+ if (result.status === 'fulfilled' && Array.isArray(result.value)) {
136
+ for (const it of result.value)
137
+ items.push(it);
138
+ }
139
+ else if (result.status === 'rejected') {
140
+ const src = ORDER[idx];
141
+ if (src !== undefined)
142
+ failedSources.add(src);
143
+ }
144
+ });
145
+ return { items, failedSources };
146
+ }
147
+ // ---------------------------------------------------------------------------
148
+ // Dimension scoring (deterministic)
149
+ // ---------------------------------------------------------------------------
150
+ /**
151
+ * Score one dimension 0..100 from its feeding WorkItems (and, for the
152
+ * `conventions` dimension, its failed convention probes). The dimension starts
153
+ * perfect (100) and is reduced by a deterministic penalty per finding, floored
154
+ * at 0. Deterministic and pure.
155
+ */
156
+ function scoreDimension(dimension, items, conventionPenaltyTotal, failed, conventionGapCount) {
157
+ const weight = DIMENSION_WEIGHTS[dimension];
158
+ let penalty = conventionPenaltyTotal;
159
+ for (const it of items)
160
+ penalty += findingPenalty(it);
161
+ // A scanner that failed outright is treated as a small fixed penalty + note,
162
+ // not a perfect score (we can't prove the dimension is clean).
163
+ if (failed)
164
+ penalty += 10;
165
+ const score = Math.max(0, Math.min(100, 100 - penalty));
166
+ // The `conventions` dimension is fed by probeConventions (not WorkItems), so
167
+ // its finding count is the failed-probe count, not items.length (which is 0).
168
+ const findingCount = dimension === 'conventions' ? conventionGapCount : items.length;
169
+ let summary;
170
+ if (failed) {
171
+ summary = `scanner unavailable — scored conservatively (${score}/100)`;
172
+ }
173
+ else if (findingCount === 0 && conventionPenaltyTotal === 0) {
174
+ summary = 'no findings — healthy';
175
+ }
176
+ else if (dimension === 'conventions') {
177
+ summary = `${findingCount} convention gap(s) — ${score}/100`;
178
+ }
179
+ else {
180
+ summary = `${findingCount} finding(s) — ${score}/100`;
181
+ }
182
+ return { dimension, score, weight, findingCount, summary };
183
+ }
184
+ // ---------------------------------------------------------------------------
185
+ // computeHealth — per-repo
186
+ // ---------------------------------------------------------------------------
187
+ /**
188
+ * Compute the per-repo HealthScore for `repo` (an absolute path).
189
+ *
190
+ * Runs all six SCANNERS (in parallel; each individually bounded + never throws)
191
+ * plus probeConventions(repo), maps their outputs onto the HealthDimensions,
192
+ * scores each dimension 0..100, rolls them up into a weighted overall 0..100 +
193
+ * letter grade, and records the worst offenders (highest WorkItem.score),
194
+ * bounded to MAX_WORST_OFFENDERS.
195
+ *
196
+ * Deterministic, READ-ONLY, NO LLM. Never mutates `repo`. Never throws on a
197
+ * scanner/probe failure (it degrades to a neutral/penalized dimension with a
198
+ * note); the ONLY intentional throw is the enrollment guard below.
199
+ *
200
+ * ENROLLMENT-SCOPED (CORE layer, invariant #2): this per-repo entry point
201
+ * self-defends — `repo` is resolve()'d and filtered through isEnrolled(), and a
202
+ * NON-ENROLLED path HARD-ERRORS before any disk scan. This is defense-in-depth
203
+ * matching computeReport: the CLI already gates the positional --repo, and
204
+ * computeReport already filters via isEnrolled before calling here, so enrolled
205
+ * callers pass through unaffected. The guard closes the single-layer gap class
206
+ * the M25 review caught (the M27 contract requires enrollment at BOTH layers).
207
+ */
208
+ export async function computeHealth(repo) {
209
+ const abs = resolve(repo);
210
+ // CORE-layer enrollment guard (invariant #2): never disk-scan a non-enrolled
211
+ // path, no matter which caller reaches here. HARD-ERROR before any scanner runs.
212
+ if (!isEnrolled(abs)) {
213
+ throw new Error(`repo not enrolled for health review: ${abs}`);
214
+ }
215
+ // Read-only scanner sweep + convention probe (both never-throw-guarded).
216
+ const { items, failedSources } = await runScanners(abs);
217
+ let conventions;
218
+ try {
219
+ conventions = probeConventions(abs);
220
+ }
221
+ catch {
222
+ conventions = [];
223
+ }
224
+ // Bucket WorkItems by their feeding dimension.
225
+ const byDimension = new Map();
226
+ for (const dim of DIMENSION_ORDER)
227
+ byDimension.set(dim, []);
228
+ for (const it of items) {
229
+ const dim = SOURCE_TO_DIMENSION[it.source];
230
+ // Unknown/foreign source -> ignore (defensive; the union is closed).
231
+ if (dim === undefined)
232
+ continue;
233
+ byDimension.get(dim).push(it);
234
+ }
235
+ // The `conventions` dimension penalty + gap count: derived from failed probes.
236
+ let conventionPenaltyTotal = 0;
237
+ let conventionGapCount = 0;
238
+ for (const finding of conventions) {
239
+ if (!finding.ok) {
240
+ conventionPenaltyTotal += conventionPenalty(finding.weight);
241
+ conventionGapCount += 1;
242
+ }
243
+ }
244
+ // Score every dimension (stable order).
245
+ const dimensions = DIMENSION_ORDER.map((dim) => {
246
+ const dimItems = byDimension.get(dim) ?? [];
247
+ const isConventions = dim === 'conventions';
248
+ return scoreDimension(dim, dimItems, isConventions ? conventionPenaltyTotal : 0, isConventions ? false : failedSources.has(dimensionToSource(dim)), isConventions ? conventionGapCount : 0);
249
+ });
250
+ // Weighted roll-up into the overall 0..100 (weights normalized at compute time).
251
+ const totalWeight = dimensions.reduce((acc, d) => acc + d.weight, 0);
252
+ const weightedSum = dimensions.reduce((acc, d) => acc + d.score * d.weight, 0);
253
+ const overall = totalWeight > 0 ? Math.round(weightedSum / totalWeight) : 0;
254
+ // Worst offenders: highest WorkItem.score first; deterministic tiebreak by id.
255
+ const worstOffenders = [...items]
256
+ .sort((a, b) => (b.score - a.score) || a.id.localeCompare(b.id))
257
+ .slice(0, MAX_WORST_OFFENDERS);
258
+ return {
259
+ repo: abs,
260
+ score: overall,
261
+ grade: gradeFor(overall),
262
+ dimensions,
263
+ conventions,
264
+ worstOffenders,
265
+ ts: new Date().toISOString(),
266
+ };
267
+ }
268
+ /**
269
+ * Inverse of SOURCE_TO_DIMENSION for the six WorkSource-backed dimensions.
270
+ * Only called for non-`conventions` dimensions (conventions has no backing
271
+ * WorkSource), so the default branch is unreachable in practice.
272
+ */
273
+ function dimensionToSource(dimension) {
274
+ switch (dimension) {
275
+ case 'issuesCi':
276
+ return 'issue';
277
+ case 'codeDebt':
278
+ return 'todo';
279
+ case 'tests':
280
+ return 'test';
281
+ case 'deps':
282
+ return 'dep';
283
+ case 'docs':
284
+ return 'doc';
285
+ case 'security':
286
+ case 'conventions':
287
+ default:
288
+ return 'security';
289
+ }
290
+ }
291
+ // ---------------------------------------------------------------------------
292
+ // computeReport — portfolio-wide
293
+ // ---------------------------------------------------------------------------
294
+ /**
295
+ * Compute the portfolio-wide HealthReport over enrolled repos.
296
+ *
297
+ * Repo selection:
298
+ * - opts.repos omitted => listEnrolled() (DEFAULT EMPTY => empty report; NO
299
+ * disk scan when nothing is enrolled).
300
+ * - opts.repos provided => EACH entry is resolve()'d and filtered through
301
+ * isEnrolled(); a NON-ENROLLED path HARD-ERRORS
302
+ * (throws) — never silently scanned. (M25 lesson.)
303
+ *
304
+ * Bounded by opts.maxRepos (default DEFAULT_MAX_REPOS). Scores each selected
305
+ * repo via computeHealth (sequentially, mirroring buildBacklog to avoid a
306
+ * gh/npm thundering-herd), ranks worst-first, computes averageScore/grade, and
307
+ * leaves `delta` for the store/CLI layer to fill from loadPreviousReport().
308
+ *
309
+ * Deterministic, READ-ONLY, NO LLM. Never mutates any repo.
310
+ */
311
+ export async function computeReport(opts) {
312
+ const maxRepos = Math.max(0, opts?.maxRepos ?? DEFAULT_MAX_REPOS);
313
+ // Enrollment-scoped repo selection (CORE-layer enforcement of invariant #2).
314
+ let repos;
315
+ if (opts?.repos !== undefined) {
316
+ repos = [];
317
+ for (const r of opts.repos) {
318
+ const abs = resolve(r);
319
+ if (!isEnrolled(abs)) {
320
+ // HARD-ERROR — never silently scan a non-enrolled path.
321
+ throw new Error(`repo not enrolled for health review: ${abs}`);
322
+ }
323
+ repos.push(abs);
324
+ }
325
+ }
326
+ else {
327
+ repos = listEnrolled();
328
+ }
329
+ // Bound work: never score more than maxRepos in a single run.
330
+ const scoped = repos.slice(0, maxRepos);
331
+ // Score sequentially (mirrors buildBacklog — avoids a gh/npm thundering-herd).
332
+ const scores = [];
333
+ for (const r of scoped) {
334
+ scores.push(await computeHealth(r));
335
+ }
336
+ // Rank worst-first (ascending overall score); deterministic tiebreak by path.
337
+ scores.sort((a, b) => (a.score - b.score) || a.repo.localeCompare(b.repo));
338
+ const averageScore = scores.length > 0
339
+ ? Math.round(scores.reduce((acc, s) => acc + s.score, 0) / scores.length)
340
+ : 0;
341
+ return {
342
+ generatedAt: new Date().toISOString(),
343
+ repos: scoped,
344
+ scores,
345
+ averageScore,
346
+ averageGrade: gradeFor(averageScore),
347
+ delta: {},
348
+ };
349
+ }
350
+ //# sourceMappingURL=health.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"health.js","sourceRoot":"","sources":["../../../src/core/quality/health.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAYpC,OAAO,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AACpD,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAChE,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAEpD,8EAA8E;AAC9E,mBAAmB;AACnB,8EAA8E;AAE9E,sDAAsD;AACtD,MAAM,iBAAiB,GAAG,GAAG,CAAC;AAE9B,yDAAyD;AACzD,MAAM,mBAAmB,GAAG,CAAC,CAAC;AAE9B;;;GAGG;AACH,MAAM,iBAAiB,GAAoC;IACzD,KAAK,EAAE,EAAE;IACT,IAAI,EAAE,EAAE;IACR,IAAI,EAAE,EAAE;IACR,QAAQ,EAAE,EAAE;IACZ,QAAQ,EAAE,EAAE;IACZ,QAAQ,EAAE,EAAE;IACZ,WAAW,EAAE,EAAE;CAChB,CAAC;AAEF,kEAAkE;AAClE,MAAM,eAAe,GAA+B;IAClD,OAAO;IACP,MAAM;IACN,MAAM;IACN,UAAU;IACV,UAAU;IACV,UAAU;IACV,aAAa;CACL,CAAC;AAEX;;;;;;;;;;GAUG;AACH,MAAM,mBAAmB,GAAwC;IAC/D,KAAK,EAAE,UAAU;IACjB,IAAI,EAAE,UAAU;IAChB,IAAI,EAAE,OAAO;IACb,GAAG,EAAE,MAAM;IACX,GAAG,EAAE,MAAM;IACX,QAAQ,EAAE,UAAU;IACpB,MAAM,EAAE,UAAU,EAAE,yDAAyD;CAC9E,CAAC;AAEF;;;;GAIG;AACH,SAAS,cAAc,CAAC,IAAc;IACpC,qEAAqE;IACrE,0DAA0D;IAC1D,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAC3D,OAAO,CAAC,GAAG,CAAC,CAAC;AACf,CAAC;AAED;;;GAGG;AACH,SAAS,iBAAiB,CAAC,MAAc;IACvC,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;IACvD,OAAO,CAAC,GAAG,CAAC,CAAC;AACf,CAAC;AAED,8EAA8E;AAC9E,mCAAmC;AACnC,8EAA8E;AAE9E;;;GAGG;AACH,MAAM,UAAU,QAAQ,CAAC,KAAa;IACpC,IAAI,KAAK,IAAI,EAAE;QAAE,OAAO,GAAG,CAAC;IAC5B,IAAI,KAAK,IAAI,EAAE;QAAE,OAAO,GAAG,CAAC;IAC5B,IAAI,KAAK,IAAI,EAAE;QAAE,OAAO,GAAG,CAAC;IAC5B,IAAI,KAAK,IAAI,EAAE;QAAE,OAAO,GAAG,CAAC;IAC5B,OAAO,GAAG,CAAC;AACb,CAAC;AAED,8EAA8E;AAC9E,4DAA4D;AAC5D,8EAA8E;AAE9E;;;;;;;;;GASG;AACH,KAAK,UAAU,WAAW,CACxB,IAAY;IAEZ,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,UAAU,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACvE,MAAM,KAAK,GAAe,EAAE,CAAC;IAC7B,MAAM,aAAa,GAAG,IAAI,GAAG,EAAc,CAAC;IAE5C,+EAA+E;IAC/E,MAAM,KAAK,GAA0B,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,UAAU,CAAC,CAAC;IAEzF,OAAO,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,GAAG,EAAE,EAAE;QAC9B,IAAI,MAAM,CAAC,MAAM,KAAK,WAAW,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;YACjE,KAAK,MAAM,EAAE,IAAI,MAAM,CAAC,KAAK;gBAAE,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAChD,CAAC;aAAM,IAAI,MAAM,CAAC,MAAM,KAAK,UAAU,EAAE,CAAC;YACxC,MAAM,GAAG,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC;YACvB,IAAI,GAAG,KAAK,SAAS;gBAAE,aAAa,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAChD,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,OAAO,EAAE,KAAK,EAAE,aAAa,EAAE,CAAC;AAClC,CAAC;AAED,8EAA8E;AAC9E,oCAAoC;AACpC,8EAA8E;AAE9E;;;;;GAKG;AACH,SAAS,cAAc,CACrB,SAA0B,EAC1B,KAAiB,EACjB,sBAA8B,EAC9B,MAAe,EACf,kBAA0B;IAE1B,MAAM,MAAM,GAAG,iBAAiB,CAAC,SAAS,CAAC,CAAC;IAE5C,IAAI,OAAO,GAAG,sBAAsB,CAAC;IACrC,KAAK,MAAM,EAAE,IAAI,KAAK;QAAE,OAAO,IAAI,cAAc,CAAC,EAAE,CAAC,CAAC;IAEtD,6EAA6E;IAC7E,+DAA+D;IAC/D,IAAI,MAAM;QAAE,OAAO,IAAI,EAAE,CAAC;IAE1B,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,GAAG,OAAO,CAAC,CAAC,CAAC;IACxD,6EAA6E;IAC7E,8EAA8E;IAC9E,MAAM,YAAY,GAAG,SAAS,KAAK,aAAa,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC;IAErF,IAAI,OAAe,CAAC;IACpB,IAAI,MAAM,EAAE,CAAC;QACX,OAAO,GAAG,gDAAgD,KAAK,OAAO,CAAC;IACzE,CAAC;SAAM,IAAI,YAAY,KAAK,CAAC,IAAI,sBAAsB,KAAK,CAAC,EAAE,CAAC;QAC9D,OAAO,GAAG,uBAAuB,CAAC;IACpC,CAAC;SAAM,IAAI,SAAS,KAAK,aAAa,EAAE,CAAC;QACvC,OAAO,GAAG,GAAG,YAAY,wBAAwB,KAAK,MAAM,CAAC;IAC/D,CAAC;SAAM,CAAC;QACN,OAAO,GAAG,GAAG,YAAY,iBAAiB,KAAK,MAAM,CAAC;IACxD,CAAC;IAED,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,OAAO,EAAE,CAAC;AAC7D,CAAC;AAED,8EAA8E;AAC9E,2BAA2B;AAC3B,8EAA8E;AAE9E;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,IAAY;IAC9C,MAAM,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAE1B,6EAA6E;IAC7E,iFAAiF;IACjF,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QACrB,MAAM,IAAI,KAAK,CAAC,wCAAwC,GAAG,EAAE,CAAC,CAAC;IACjE,CAAC;IAED,yEAAyE;IACzE,MAAM,EAAE,KAAK,EAAE,aAAa,EAAE,GAAG,MAAM,WAAW,CAAC,GAAG,CAAC,CAAC;IAExD,IAAI,WAAgC,CAAC;IACrC,IAAI,CAAC;QACH,WAAW,GAAG,gBAAgB,CAAC,GAAG,CAAC,CAAC;IACtC,CAAC;IAAC,MAAM,CAAC;QACP,WAAW,GAAG,EAAE,CAAC;IACnB,CAAC;IAED,+CAA+C;IAC/C,MAAM,WAAW,GAAG,IAAI,GAAG,EAA+B,CAAC;IAC3D,KAAK,MAAM,GAAG,IAAI,eAAe;QAAE,WAAW,CAAC,GAAG,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;IAC5D,KAAK,MAAM,EAAE,IAAI,KAAK,EAAE,CAAC;QACvB,MAAM,GAAG,GAAG,mBAAmB,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC;QAC3C,qEAAqE;QACrE,IAAI,GAAG,KAAK,SAAS;YAAE,SAAS;QAChC,WAAW,CAAC,GAAG,CAAC,GAAG,CAAE,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACjC,CAAC;IAED,+EAA+E;IAC/E,IAAI,sBAAsB,GAAG,CAAC,CAAC;IAC/B,IAAI,kBAAkB,GAAG,CAAC,CAAC;IAC3B,KAAK,MAAM,OAAO,IAAI,WAAW,EAAE,CAAC;QAClC,IAAI,CAAC,OAAO,CAAC,EAAE,EAAE,CAAC;YAChB,sBAAsB,IAAI,iBAAiB,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;YAC5D,kBAAkB,IAAI,CAAC,CAAC;QAC1B,CAAC;IACH,CAAC;IAED,wCAAwC;IACxC,MAAM,UAAU,GAA2B,eAAe,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE;QACrE,MAAM,QAAQ,GAAG,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;QAC5C,MAAM,aAAa,GAAG,GAAG,KAAK,aAAa,CAAC;QAC5C,OAAO,cAAc,CACnB,GAAG,EACH,QAAQ,EACR,aAAa,CAAC,CAAC,CAAC,sBAAsB,CAAC,CAAC,CAAC,CAAC,EAC1C,aAAa,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,aAAa,CAAC,GAAG,CAAC,iBAAiB,CAAC,GAAG,CAAC,CAAC,EACjE,aAAa,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC,CACvC,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,iFAAiF;IACjF,MAAM,WAAW,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IACrE,MAAM,WAAW,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IAC/E,MAAM,OAAO,GAAG,WAAW,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,WAAW,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAE5E,+EAA+E;IAC/E,MAAM,cAAc,GAAe,CAAC,GAAG,KAAK,CAAC;SAC1C,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;SAC/D,KAAK,CAAC,CAAC,EAAE,mBAAmB,CAAC,CAAC;IAEjC,OAAO;QACL,IAAI,EAAE,GAAG;QACT,KAAK,EAAE,OAAO;QACd,KAAK,EAAE,QAAQ,CAAC,OAAO,CAAC;QACxB,UAAU;QACV,WAAW;QACX,cAAc;QACd,EAAE,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;KAC7B,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,SAAS,iBAAiB,CAAC,SAA0B;IACnD,QAAQ,SAAS,EAAE,CAAC;QAClB,KAAK,UAAU;YACb,OAAO,OAAO,CAAC;QACjB,KAAK,UAAU;YACb,OAAO,MAAM,CAAC;QAChB,KAAK,OAAO;YACV,OAAO,MAAM,CAAC;QAChB,KAAK,MAAM;YACT,OAAO,KAAK,CAAC;QACf,KAAK,MAAM;YACT,OAAO,KAAK,CAAC;QACf,KAAK,UAAU,CAAC;QAChB,KAAK,aAAa,CAAC;QACnB;YACE,OAAO,UAAU,CAAC;IACtB,CAAC;AACH,CAAC;AAED,8EAA8E;AAC9E,iCAAiC;AACjC,8EAA8E;AAE9E;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,IAAoB;IACtD,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,QAAQ,IAAI,iBAAiB,CAAC,CAAC;IAElE,6EAA6E;IAC7E,IAAI,KAAe,CAAC;IACpB,IAAI,IAAI,EAAE,KAAK,KAAK,SAAS,EAAE,CAAC;QAC9B,KAAK,GAAG,EAAE,CAAC;QACX,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YAC3B,MAAM,GAAG,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;YACvB,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;gBACrB,wDAAwD;gBACxD,MAAM,IAAI,KAAK,CAAC,wCAAwC,GAAG,EAAE,CAAC,CAAC;YACjE,CAAC;YACD,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAClB,CAAC;IACH,CAAC;SAAM,CAAC;QACN,KAAK,GAAG,YAAY,EAAE,CAAC;IACzB,CAAC;IAED,8DAA8D;IAC9D,MAAM,MAAM,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC;IAExC,+EAA+E;IAC/E,MAAM,MAAM,GAAkB,EAAE,CAAC;IACjC,KAAK,MAAM,CAAC,IAAI,MAAM,EAAE,CAAC;QACvB,MAAM,CAAC,IAAI,CAAC,MAAM,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC;IACtC,CAAC;IAED,8EAA8E;IAC9E,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;IAE3E,MAAM,YAAY,GAChB,MAAM,CAAC,MAAM,GAAG,CAAC;QACf,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC;QACzE,CAAC,CAAC,CAAC,CAAC;IAER,OAAO;QACL,WAAW,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACrC,KAAK,EAAE,MAAM;QACb,MAAM;QACN,YAAY;QACZ,YAAY,EAAE,QAAQ,CAAC,YAAY,CAAC;QACpC,KAAK,EAAE,EAAE;KACV,CAAC;AACJ,CAAC"}