@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,564 @@
1
+ /**
2
+ * graph.ts — Knowledge Graph + Impact analysis for enrolled repos.
3
+ *
4
+ * INVARIANTS (docs/contracts/CONTRACT-M25.md):
5
+ * 1. READ-ONLY: never modifies any enrolled repo; analysis only.
6
+ * 2. ENROLLMENT-SCOPED: default repos = listEnrolled() (DEFAULT EMPTY => empty graph).
7
+ * 3. BOUNDED: caps file walk depth, file count, and skips node_modules/.git/dist/binaries.
8
+ * 4. NEVER THROWS: all functions catch internally; callers get empty structures on error.
9
+ * 5. LOCAL-ONLY: no network calls; pure filesystem analysis.
10
+ * 6. NO SECRETS: skips .env/key files; does not emit secret-shaped content.
11
+ *
12
+ * buildGraph(repos?): construct KnowledgeGraph from persisted index + package.json manifests
13
+ * + import/require statements. Nodes: repos, key modules, shared deps.
14
+ * Edges: imports/depends/shared-dep. CrossRepo: same dep across repos, duplicated modules.
15
+ *
16
+ * impact(target, repos?): find all references to a file path or symbol across enrolled repos
17
+ * via the persisted index + grep-style scan. Returns ImpactResult with references + dependents.
18
+ */
19
+ import fs from 'node:fs';
20
+ import path from 'node:path';
21
+ import { listEnrolled, isEnrolled } from '../sandbox/policy.js';
22
+ import { SECRET_PATTERNS, scrubSecrets as scrubSecretsParity } from './index.js';
23
+ // ---------------------------------------------------------------------------
24
+ // Constants — bounds
25
+ // ---------------------------------------------------------------------------
26
+ /** Max files to scan per repo during import analysis. */
27
+ const MAX_FILES_PER_REPO = 2000;
28
+ /** Max bytes to read from a single file for import extraction. */
29
+ const MAX_FILE_BYTES = 256 * 1024; // 256 KB
30
+ /** Max recursion depth during directory walk. */
31
+ const MAX_WALK_DEPTH = 10;
32
+ /** Max references to collect for an impact query (keeps output bounded). */
33
+ const MAX_REFERENCES = 500;
34
+ /** Directories to skip unconditionally. */
35
+ const SKIP_DIRS = new Set([
36
+ 'node_modules', '.git', 'dist', '.next', '.turbo', 'coverage',
37
+ '__pycache__', 'build', 'out', '.cache', '.parcel-cache', 'vendor',
38
+ '.venv', 'venv', 'target', '.idea', '.vscode',
39
+ ]);
40
+ /** File extensions considered source code (import-bearing). */
41
+ const SOURCE_EXTS = new Set([
42
+ '.ts', '.tsx', '.js', '.jsx', '.mjs', '.cjs',
43
+ '.py', '.rb', '.go', '.rs', '.java', '.kt',
44
+ ]);
45
+ /** Binary / compiled extensions to skip entirely. */
46
+ const BINARY_EXTS = new Set([
47
+ '.png', '.jpg', '.jpeg', '.gif', '.webp', '.svg', '.ico',
48
+ '.woff', '.woff2', '.ttf', '.eot',
49
+ '.mp3', '.mp4', '.wav', '.ogg',
50
+ '.zip', '.tar', '.gz', '.bz2', '.rar',
51
+ '.bin', '.exe', '.dll', '.so', '.dylib',
52
+ '.lock', '.map',
53
+ ]);
54
+ /** Secret-adjacent filenames to skip when reading. */
55
+ const SECRET_FILES = new Set([
56
+ '.env', '.env.local', '.env.production', '.env.development', '.env.test',
57
+ '.env.staging', '.envrc',
58
+ 'credentials.json', 'secrets.json', 'secret.json',
59
+ 'id_rsa', 'id_ed25519', 'id_ecdsa', 'id_dsa',
60
+ '.npmrc', '.netrc',
61
+ 'service-account.json', 'serviceaccount.json',
62
+ ]);
63
+ // ---------------------------------------------------------------------------
64
+ // Path helpers
65
+ // ---------------------------------------------------------------------------
66
+ /** Derive a stable short ID from an absolute path (basename). */
67
+ function repoId(absPath) {
68
+ return `repo:${path.basename(absPath)}`;
69
+ }
70
+ /** Returns true if the file should be skipped entirely (binary, secret, skip-dir). */
71
+ function shouldSkipFile(filePath) {
72
+ const base = path.basename(filePath);
73
+ if (SECRET_FILES.has(base))
74
+ return true;
75
+ const ext = path.extname(filePath).toLowerCase();
76
+ if (BINARY_EXTS.has(ext))
77
+ return true;
78
+ return false;
79
+ }
80
+ /** Returns true if the directory entry should not be descended into. */
81
+ function shouldSkipDir(name) {
82
+ return SKIP_DIRS.has(name) || name.startsWith('.');
83
+ }
84
+ // ---------------------------------------------------------------------------
85
+ // Filesystem helpers — always safe, never throw
86
+ // ---------------------------------------------------------------------------
87
+ function safeReadFile(filePath) {
88
+ try {
89
+ if (shouldSkipFile(filePath))
90
+ return null;
91
+ const stat = fs.statSync(filePath);
92
+ if (!stat.isFile())
93
+ return null;
94
+ if (stat.size > MAX_FILE_BYTES)
95
+ return null;
96
+ return fs.readFileSync(filePath, 'utf8');
97
+ }
98
+ catch {
99
+ return null;
100
+ }
101
+ }
102
+ function safeReaddir(dir) {
103
+ try {
104
+ return fs.readdirSync(dir, { withFileTypes: true });
105
+ }
106
+ catch {
107
+ return [];
108
+ }
109
+ }
110
+ // ---------------------------------------------------------------------------
111
+ // Directory walker — bounded, read-only, never throws
112
+ // ---------------------------------------------------------------------------
113
+ /**
114
+ * Walk a repo directory and collect all source file paths up to MAX_FILES_PER_REPO.
115
+ * Skips SKIP_DIRS, hidden dirs, binaries, and secret files.
116
+ */
117
+ function walkSourceFiles(repoPath) {
118
+ const results = [];
119
+ function walk(dir, depth) {
120
+ if (depth > MAX_WALK_DEPTH)
121
+ return;
122
+ if (results.length >= MAX_FILES_PER_REPO)
123
+ return;
124
+ for (const dirent of safeReaddir(dir)) {
125
+ if (results.length >= MAX_FILES_PER_REPO)
126
+ return;
127
+ // Skip symlinks (files + dirs) so the walk cannot escape the repo boundary.
128
+ if (dirent.isSymbolicLink())
129
+ continue;
130
+ if (dirent.isDirectory()) {
131
+ if (shouldSkipDir(dirent.name))
132
+ continue;
133
+ walk(path.join(dir, dirent.name), depth + 1);
134
+ }
135
+ else if (dirent.isFile()) {
136
+ const filePath = path.join(dir, dirent.name);
137
+ if (shouldSkipFile(filePath))
138
+ continue;
139
+ const ext = path.extname(dirent.name).toLowerCase();
140
+ if (SOURCE_EXTS.has(ext)) {
141
+ results.push(filePath);
142
+ }
143
+ }
144
+ }
145
+ }
146
+ try {
147
+ walk(repoPath, 0);
148
+ }
149
+ catch {
150
+ // bounded walk never propagates errors
151
+ }
152
+ return results;
153
+ }
154
+ function readPackageJson(repoPath) {
155
+ try {
156
+ const pkgPath = path.join(repoPath, 'package.json');
157
+ const raw = safeReadFile(pkgPath);
158
+ if (!raw)
159
+ return null;
160
+ return JSON.parse(raw);
161
+ }
162
+ catch {
163
+ return null;
164
+ }
165
+ }
166
+ /** Collect all dependency names from a package.json. */
167
+ function collectDeps(pkg) {
168
+ return [
169
+ ...Object.keys(pkg.dependencies ?? {}),
170
+ ...Object.keys(pkg.devDependencies ?? {}),
171
+ ...Object.keys(pkg.peerDependencies ?? {}),
172
+ ];
173
+ }
174
+ // ---------------------------------------------------------------------------
175
+ // Import/require extraction — regex-based, fast, bounded
176
+ // ---------------------------------------------------------------------------
177
+ /**
178
+ * Extract import/require targets from a source file's text.
179
+ * Returns both external package names and relative path imports.
180
+ * Never throws.
181
+ */
182
+ function extractImports(source) {
183
+ const imports = [];
184
+ try {
185
+ // ES module: import ... from 'target' / import 'target'
186
+ const esImportRe = /\bimport\s+(?:[^'"]*\s+from\s+)?['"]([^'"]+)['"]/g;
187
+ let m;
188
+ while ((m = esImportRe.exec(source)) !== null) {
189
+ if (m[1])
190
+ imports.push(m[1]);
191
+ }
192
+ // CommonJS: require('target')
193
+ const cjsRe = /\brequire\s*\(\s*['"]([^'"]+)['"]\s*\)/g;
194
+ while ((m = cjsRe.exec(source)) !== null) {
195
+ if (m[1])
196
+ imports.push(m[1]);
197
+ }
198
+ // Dynamic import: import('target')
199
+ const dynRe = /\bimport\s*\(\s*['"]([^'"]+)['"]\s*\)/g;
200
+ while ((m = dynRe.exec(source)) !== null) {
201
+ if (m[1])
202
+ imports.push(m[1]);
203
+ }
204
+ // Python: from target import / import target
205
+ const pyFromRe = /^from\s+([\w.]+)\s+import/gm;
206
+ while ((m = pyFromRe.exec(source)) !== null) {
207
+ if (m[1])
208
+ imports.push(m[1]);
209
+ }
210
+ const pyImportRe = /^import\s+([\w.,\s]+)/gm;
211
+ while ((m = pyImportRe.exec(source)) !== null) {
212
+ if (m[1]) {
213
+ for (const part of m[1].split(',')) {
214
+ const trimmed = part.trim().split(' ')[0];
215
+ if (trimmed)
216
+ imports.push(trimmed);
217
+ }
218
+ }
219
+ }
220
+ }
221
+ catch {
222
+ // regex errors are non-fatal
223
+ }
224
+ return imports;
225
+ }
226
+ /**
227
+ * Classify an import string:
228
+ * - 'relative': starts with ./ or ../
229
+ * - 'package': external npm/pip package name
230
+ */
231
+ function importKind(imp) {
232
+ return imp.startsWith('.') ? 'relative' : 'package';
233
+ }
234
+ /** Extract just the package name (before any slash for scoped/sub-path). */
235
+ function packageName(imp) {
236
+ if (imp.startsWith('@')) {
237
+ // scoped: @scope/name/sub => @scope/name
238
+ const parts = imp.split('/');
239
+ return parts.slice(0, 2).join('/');
240
+ }
241
+ return imp.split('/')[0] ?? imp;
242
+ }
243
+ // ---------------------------------------------------------------------------
244
+ // Secret-scrubbing helper (for display; not stored in graph)
245
+ // ---------------------------------------------------------------------------
246
+ // H6 (PART B.1 — scrub PARITY): graph.ts delegates to index.ts's full
247
+ // SECRET_PATTERNS set so the two scrubs are at PARITY. Previously this was the
248
+ // WEAKER scrub (H4 §6.8 FINDING) — ONE assignment-style regex that missed bare
249
+ // JWT / AKIA / base64 / hex blobs. graph.ts imports { SECRET_PATTERNS,
250
+ // scrubSecrets } from './index.js' and uses index's scrubSecrets at the
251
+ // `detail:` emit site, so graph.ts and index.ts redact the SAME shapes
252
+ // (JWT / AKIA / base64 / hex / Stripe sk_live_) — see
253
+ // docs/contracts/CONTRACT-H6.md §B.1. This flips the pinned H4 §6.8 assertions
254
+ // DELIBERATELY (§B.4): they now assert the bare blobs ARE redacted.
255
+ //
256
+ // PARITY DIRECTION (H6 review finding, §B.1): "parity" means graph.ts adopts
257
+ // index.ts's SUPERSET of high-entropy shapes (bare JWT / AKIA / base64 / hex /
258
+ // sk_live_). The OLD graph regex additionally matched bare LOW-entropy
259
+ // assignments like `token=abc123` / `auth=xyz`; index.ts's compound-name +
260
+ // high-entropy patterns intentionally do NOT, so those narrow shapes are
261
+ // dropped in this direction. This is safe because the ONLY string graph.ts
262
+ // scrubs is the structurally-constrained `detail` string
263
+ // `${dep} shared across N repos: basename@version` (dep names + repo@version,
264
+ // never free-form text), so a bare `token=…` literal cannot occur there.
265
+ //
266
+ // SECRET_PATTERNS is LOAD-BEARING here (not decorative): scrubSecrets() asserts
267
+ // the imported parity array is non-empty before delegating, so a wiped/empty
268
+ // upstream pattern set surfaces as a throw at the graph.ts call site rather than
269
+ // a silent no-op. `ashlr verify-safety` CHECK 4 pins the real `./index.js`
270
+ // parity import (scrubSecrets + SECRET_PATTERNS) — live code, not a vestigial
271
+ // assignment-regex string — see verify-safety.ts CHECK 4 + docs/contracts/CONTRACT-H6.md §B.1.
272
+ /** Parity scrub: delegates to index.ts's exported scrubSecrets over the shared
273
+ * SECRET_PATTERNS so graph.ts redacts the identical pattern set. The explicit
274
+ * SECRET_PATTERNS length guard makes the shared array load-bearing: an empty
275
+ * upstream pattern set throws here instead of silently passing raw text. */
276
+ function scrubSecrets(text) {
277
+ // Defense-in-depth: the shared pattern set must be non-empty for parity to
278
+ // hold. A zero-length array would mean index.ts's scrub silently became a
279
+ // no-op; refuse to emit an unscrubbed detail string in that case.
280
+ if (SECRET_PATTERNS.length === 0) {
281
+ throw new Error('graph.ts scrub parity broken: shared SECRET_PATTERNS is empty');
282
+ }
283
+ return scrubSecretsParity(text);
284
+ }
285
+ function analyseRepo(repoPath) {
286
+ const label = path.basename(repoPath);
287
+ const pkg = readPackageJson(repoPath);
288
+ const deps = pkg ? collectDeps(pkg) : [];
289
+ const moduleImports = new Map();
290
+ const sourceFiles = walkSourceFiles(repoPath);
291
+ for (const filePath of sourceFiles) {
292
+ const src = safeReadFile(filePath);
293
+ if (!src)
294
+ continue;
295
+ const relPath = path.relative(repoPath, filePath);
296
+ const pkgImports = new Set();
297
+ for (const imp of extractImports(src)) {
298
+ if (importKind(imp) === 'package') {
299
+ pkgImports.add(packageName(imp));
300
+ }
301
+ }
302
+ if (pkgImports.size > 0) {
303
+ moduleImports.set(relPath, pkgImports);
304
+ }
305
+ }
306
+ return {
307
+ repoPath,
308
+ repoLabel: label,
309
+ packageName: pkg?.name ?? null,
310
+ deps,
311
+ moduleImports,
312
+ sourceFiles,
313
+ };
314
+ }
315
+ // ---------------------------------------------------------------------------
316
+ // buildGraph — public API
317
+ // ---------------------------------------------------------------------------
318
+ /**
319
+ * Build a KnowledgeGraph from enrolled repos (or the provided list).
320
+ *
321
+ * Nodes:
322
+ * - kind:'repo' — each enrolled repo
323
+ * - kind:'module' — key source files within a repo (those that import packages)
324
+ * - kind:'dep' — external dependencies (package names)
325
+ *
326
+ * Edges:
327
+ * - kind:'depends' — repo -> dep (from package.json)
328
+ * - kind:'imports' — module -> dep (from import statements)
329
+ * - kind:'shared-dep' — dep -> dep node (already in graph; used for cross-repo detection)
330
+ *
331
+ * CrossRepo:
332
+ * - kind:'shared-dep' when a dep appears in 2+ repos
333
+ * - kind:'duplicate-module' when the same relative module path exists in 2+ repos
334
+ *
335
+ * BOUNDED, READ-ONLY, NEVER THROWS.
336
+ */
337
+ export function buildGraph(repos) {
338
+ const graph = { nodes: [], edges: [], crossRepo: [] };
339
+ try {
340
+ const targetRepos = repos ?? listEnrolled();
341
+ if (targetRepos.length === 0)
342
+ return graph;
343
+ const nodeIds = new Set();
344
+ const edgeKeys = new Set();
345
+ function addNode(id, kind, label) {
346
+ if (!nodeIds.has(id)) {
347
+ nodeIds.add(id);
348
+ graph.nodes.push({ id, kind, label });
349
+ }
350
+ }
351
+ function addEdge(from, to, kind) {
352
+ const key = `${from}||${to}||${kind}`;
353
+ if (!edgeKeys.has(key)) {
354
+ edgeKeys.add(key);
355
+ graph.edges.push({ from, to, kind });
356
+ }
357
+ }
358
+ // Analyse all repos
359
+ const analyses = [];
360
+ for (const repoPath of targetRepos) {
361
+ try {
362
+ // ENROLLMENT-SCOPED (docs/contracts/CONTRACT-M25.md invariant 3): only ever walk enrolled
363
+ // repos — an explicit repos list from the CLI (--repo / positional) is
364
+ // validated here so a non-enrolled directory is never read.
365
+ if (!isEnrolled(repoPath))
366
+ continue;
367
+ if (!fs.existsSync(repoPath))
368
+ continue;
369
+ const analysis = analyseRepo(repoPath);
370
+ analyses.push(analysis);
371
+ }
372
+ catch {
373
+ // one bad repo must not crash the whole graph
374
+ }
375
+ }
376
+ // dep name -> set of repo ids that declare it
377
+ const depToRepos = new Map();
378
+ // module relPath -> set of repo ids that have it
379
+ const moduleToRepos = new Map();
380
+ for (const analysis of analyses) {
381
+ const rId = repoId(analysis.repoPath);
382
+ addNode(rId, 'repo', analysis.repoLabel);
383
+ // Edges: repo -> declared dep (from package.json)
384
+ for (const dep of analysis.deps) {
385
+ const depId = `dep:${dep}`;
386
+ addNode(depId, 'dep', dep);
387
+ addEdge(rId, depId, 'depends');
388
+ if (!depToRepos.has(dep))
389
+ depToRepos.set(dep, new Set());
390
+ depToRepos.get(dep).add(rId);
391
+ }
392
+ // Edges: module -> imported package dep
393
+ for (const [relPath, pkgImports] of analysis.moduleImports) {
394
+ const moduleId = `module:${analysis.repoLabel}/${relPath}`;
395
+ addNode(moduleId, 'module', relPath);
396
+ addEdge(rId, moduleId, 'contains');
397
+ for (const imp of pkgImports) {
398
+ const depId = `dep:${imp}`;
399
+ addNode(depId, 'dep', imp);
400
+ addEdge(moduleId, depId, 'imports');
401
+ // Also track dep->repo for cross-repo detection
402
+ if (!depToRepos.has(imp))
403
+ depToRepos.set(imp, new Set());
404
+ depToRepos.get(imp).add(rId);
405
+ }
406
+ if (!moduleToRepos.has(relPath))
407
+ moduleToRepos.set(relPath, new Set());
408
+ moduleToRepos.get(relPath).add(rId);
409
+ }
410
+ }
411
+ // Cross-repo: shared deps (appear in 2+ repos)
412
+ for (const [dep, repoSet] of depToRepos) {
413
+ if (repoSet.size >= 2) {
414
+ // Find the version strings for detail
415
+ const repoVersions = [];
416
+ for (const analysis of analyses) {
417
+ if (repoSet.has(repoId(analysis.repoPath))) {
418
+ const pkg = readPackageJson(analysis.repoPath);
419
+ const version = pkg?.dependencies?.[dep] ??
420
+ pkg?.devDependencies?.[dep] ??
421
+ pkg?.peerDependencies?.[dep] ??
422
+ '*';
423
+ repoVersions.push(`${path.basename(analysis.repoPath)}@${version}`);
424
+ }
425
+ }
426
+ graph.crossRepo.push({
427
+ kind: 'shared-dep',
428
+ detail: scrubSecrets(`${dep} shared across ${repoSet.size} repos: ${repoVersions.join(', ')}`),
429
+ repos: Array.from(repoSet),
430
+ });
431
+ }
432
+ }
433
+ // Cross-repo: duplicate module paths (same relPath in 2+ repos)
434
+ for (const [relPath, repoSet] of moduleToRepos) {
435
+ if (repoSet.size >= 2) {
436
+ graph.crossRepo.push({
437
+ kind: 'duplicate-module',
438
+ detail: `Module path "${relPath}" exists in ${repoSet.size} repos`,
439
+ repos: Array.from(repoSet),
440
+ });
441
+ }
442
+ }
443
+ }
444
+ catch {
445
+ // top-level safety net: always return a valid (possibly partial) graph
446
+ }
447
+ return graph;
448
+ }
449
+ // ---------------------------------------------------------------------------
450
+ // impact — public API
451
+ // ---------------------------------------------------------------------------
452
+ /**
453
+ * Find all references to a file path or symbol across enrolled repos.
454
+ *
455
+ * For a file target: searches for import/require of that file (by basename and
456
+ * relative paths) and any text occurrence of the path.
457
+ * For a symbol target (no path separators, no extension): searches for usage
458
+ * occurrences in source files via text scan.
459
+ *
460
+ * Returns references (repo/file:line) and a list of dependent module names.
461
+ * BOUNDED (MAX_REFERENCES cap). READ-ONLY. NEVER THROWS.
462
+ */
463
+ export function impact(target, repos) {
464
+ const result = { target, references: [], dependents: [] };
465
+ try {
466
+ if (!target || target.trim().length === 0)
467
+ return result;
468
+ const targetRepos = repos ?? listEnrolled();
469
+ if (targetRepos.length === 0)
470
+ return result;
471
+ const cleanTarget = target.trim();
472
+ // A target is a FILE PATH only when it has a path separator OR ends with a
473
+ // real file extension (.ts/.tsx/.js/.py/…). A bare dotted symbol like
474
+ // `React.useState` or `obj.method` has no path separator and no trailing
475
+ // file extension, so it falls through to word-boundary SYMBOL matching.
476
+ const FILE_EXT_RE = /\.[a-z0-9]{1,5}$/i;
477
+ const isFilePath = cleanTarget.includes('/') || cleanTarget.includes('\\') ||
478
+ FILE_EXT_RE.test(cleanTarget);
479
+ const targetBasename = path.basename(cleanTarget);
480
+ // For searching: strip extension for module-name matching
481
+ const targetNoExt = targetBasename.replace(/\.[^.]+$/, '');
482
+ const dependentSet = new Set();
483
+ for (const repoPath of targetRepos) {
484
+ try {
485
+ // ENROLLMENT-SCOPED (docs/contracts/CONTRACT-M25.md invariant 3): never walk a directory
486
+ // that is not enrolled, even if passed explicitly via --repo.
487
+ if (!isEnrolled(repoPath))
488
+ continue;
489
+ if (!fs.existsSync(repoPath))
490
+ continue;
491
+ const sourceFiles = walkSourceFiles(repoPath);
492
+ for (const filePath of sourceFiles) {
493
+ if (result.references.length >= MAX_REFERENCES)
494
+ break;
495
+ // Skip the target file itself if it's a file path
496
+ if (isFilePath) {
497
+ const absTarget = path.isAbsolute(cleanTarget)
498
+ ? cleanTarget
499
+ : path.join(repoPath, cleanTarget);
500
+ if (filePath === absTarget)
501
+ continue;
502
+ }
503
+ const src = safeReadFile(filePath);
504
+ if (!src)
505
+ continue;
506
+ const lines = src.split('\n');
507
+ for (let i = 0; i < lines.length; i++) {
508
+ if (result.references.length >= MAX_REFERENCES)
509
+ break;
510
+ const line = lines[i];
511
+ if (!line)
512
+ continue;
513
+ let matched = false;
514
+ if (isFilePath) {
515
+ // File path target: look for imports that reference this file
516
+ // Match by basename (without ext) in import strings
517
+ if (line.includes(targetBasename) ||
518
+ (targetNoExt && line.includes(targetNoExt) &&
519
+ (line.includes('import') || line.includes('require') || line.includes('from')))) {
520
+ matched = true;
521
+ }
522
+ }
523
+ else {
524
+ // Symbol target: look for usage of the symbol name in source
525
+ // Use word-boundary-style matching to avoid partial matches
526
+ const symbolRe = new RegExp(`\\b${escapeRegex(cleanTarget)}\\b`);
527
+ if (symbolRe.test(line)) {
528
+ matched = true;
529
+ }
530
+ }
531
+ if (matched) {
532
+ const relFile = path.relative(repoPath, filePath);
533
+ const repo = path.basename(repoPath);
534
+ result.references.push({
535
+ repo,
536
+ file: relFile,
537
+ line: i + 1,
538
+ });
539
+ // Track this file as a dependent module
540
+ const modName = relFile.replace(/\.[^.]+$/, '');
541
+ dependentSet.add(`${repo}/${modName}`);
542
+ }
543
+ }
544
+ }
545
+ }
546
+ catch {
547
+ // one bad repo must not crash the whole impact
548
+ }
549
+ }
550
+ result.dependents = Array.from(dependentSet);
551
+ }
552
+ catch {
553
+ // top-level safety net
554
+ }
555
+ return result;
556
+ }
557
+ // ---------------------------------------------------------------------------
558
+ // Internal utility
559
+ // ---------------------------------------------------------------------------
560
+ /** Escape a string for use in a RegExp. */
561
+ function escapeRegex(s) {
562
+ return s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
563
+ }
564
+ //# sourceMappingURL=graph.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"graph.js","sourceRoot":"","sources":["../../../src/core/knowledge/graph.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,74 @@
1
+ /**
2
+ * knowledge/index.ts — Portfolio Knowledge Index (M25)
3
+ *
4
+ * INVARIANTS (non-negotiable):
5
+ * 1. LOCAL-ONLY: embeddings run against local Ollama only. Never send chunks
6
+ * to a cloud endpoint — this file has no allowCloud path at all.
7
+ * 2. READ-ONLY: never mutates any enrolled repo. Writes go to knowledgeDir()
8
+ * only (~/.ashlr/knowledge/<repo-hash>/).
9
+ * 3. ENROLLMENT-SCOPED: default repo set is listEnrolled() (DEFAULT EMPTY →
10
+ * returns {repos:0, chunks:0}; never scans arbitrary paths).
11
+ * 4. BOUNDED: caps file count, total bytes read, and wall-clock time per repo;
12
+ * skips node_modules / .git / dist / build / binaries / lockfiles.
13
+ * 5. NO SECRETS: skips .env* / *.pem / *.key / *.p12 files outright; scrubs
14
+ * secret-shaped tokens from chunk text before storing or embedding.
15
+ * 6. INCREMENTAL: re-indexes only files whose mtime > last index timestamp.
16
+ * Never throws — all errors are silently swallowed per the contract.
17
+ */
18
+ import type { KnowledgeChunk } from '../types.js';
19
+ /**
20
+ * Patterns for secret-shaped tokens: API keys, JWTs, long hex/base64 strings.
21
+ * Applied to chunk text before storing or embedding.
22
+ *
23
+ * EXPORTED (read-only) so the `ashlr verify-safety` self-check (H4) can run the
24
+ * REAL pattern set against a synthesized secret rather than a drifting private
25
+ * copy. Treat as a frozen constant — callers must never mutate it.
26
+ */
27
+ export declare const SECRET_PATTERNS: RegExp[];
28
+ /**
29
+ * Scrub secret-shaped tokens from a chunk of text. Returns sanitized text.
30
+ *
31
+ * EXPORTED (pure, read-only) so the H4 `ashlr verify-safety` self-check can
32
+ * invoke the REAL redaction function — not a copy — against a synthesized
33
+ * secret, so any weakening of the function body (or its pattern set) is caught.
34
+ */
35
+ export declare function scrubSecrets(text: string): string;
36
+ /** Root on-disk directory for the knowledge index: ~/.ashlr/knowledge */
37
+ export declare function knowledgeDir(): string;
38
+ /**
39
+ * Load persisted knowledge chunks, optionally scoped to one repo (absolute path).
40
+ * Returns [] when nothing is indexed or on any read error.
41
+ * NEVER scans repo source — reads only the persisted index under knowledgeDir().
42
+ */
43
+ export declare function loadChunks(repo?: string): KnowledgeChunk[];
44
+ /**
45
+ * Build (or incrementally update) the knowledge index for enrolled repos.
46
+ *
47
+ * - `opts.repos`: explicit repo list; defaults to `listEnrolled()` (DEFAULT EMPTY).
48
+ * - `opts.allowCloud`: ignored here — this file is LOCAL-ONLY. Cloud flag is
49
+ * only meaningful in ask.ts for synthesis; indexing is always local.
50
+ *
51
+ * Guarantees:
52
+ * - Never mutates any enrolled repo (writes only to knowledgeDir()).
53
+ * - Skips secret files; scrubs secret tokens from chunk text.
54
+ * - Incremental: re-indexes only files changed since last run (by mtime).
55
+ * - Bounded: file count, byte, and time caps per repo.
56
+ * - Never throws.
57
+ */
58
+ /** M32: per-repo progress event emitted by buildKnowledge (best-effort). */
59
+ export interface KnowledgeProgress {
60
+ repo: string;
61
+ repoIndex: number;
62
+ repoCount: number;
63
+ newChunks: number;
64
+ }
65
+ export declare function buildKnowledge(opts?: {
66
+ repos?: string[];
67
+ allowCloud?: boolean;
68
+ /** M32: called after each repo finishes indexing. Wrapped — a throwing
69
+ * callback can never violate buildKnowledge's never-throws contract. */
70
+ onProgress?: (ev: KnowledgeProgress) => void;
71
+ }): Promise<{
72
+ repos: number;
73
+ chunks: number;
74
+ }>;