@decibelsystems/tools 2.0.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 (478) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +342 -0
  3. package/dist/agentic/compiler.d.ts +21 -0
  4. package/dist/agentic/compiler.d.ts.map +1 -0
  5. package/dist/agentic/compiler.js +267 -0
  6. package/dist/agentic/compiler.js.map +1 -0
  7. package/dist/agentic/golden.d.ts +25 -0
  8. package/dist/agentic/golden.d.ts.map +1 -0
  9. package/dist/agentic/golden.js +255 -0
  10. package/dist/agentic/golden.js.map +1 -0
  11. package/dist/agentic/index.d.ts +17 -0
  12. package/dist/agentic/index.d.ts.map +1 -0
  13. package/dist/agentic/index.js +153 -0
  14. package/dist/agentic/index.js.map +1 -0
  15. package/dist/agentic/linter.d.ts +20 -0
  16. package/dist/agentic/linter.d.ts.map +1 -0
  17. package/dist/agentic/linter.js +340 -0
  18. package/dist/agentic/linter.js.map +1 -0
  19. package/dist/agentic/renderer.d.ts +17 -0
  20. package/dist/agentic/renderer.d.ts.map +1 -0
  21. package/dist/agentic/renderer.js +277 -0
  22. package/dist/agentic/renderer.js.map +1 -0
  23. package/dist/agentic/types.d.ts +199 -0
  24. package/dist/agentic/types.d.ts.map +1 -0
  25. package/dist/agentic/types.js +8 -0
  26. package/dist/agentic/types.js.map +1 -0
  27. package/dist/architectAdrs.d.ts +32 -0
  28. package/dist/architectAdrs.d.ts.map +1 -0
  29. package/dist/architectAdrs.js +162 -0
  30. package/dist/architectAdrs.js.map +1 -0
  31. package/dist/client/facade-client.d.ts +41 -0
  32. package/dist/client/facade-client.d.ts.map +1 -0
  33. package/dist/client/facade-client.js +243 -0
  34. package/dist/client/facade-client.js.map +1 -0
  35. package/dist/client/index.d.ts +4 -0
  36. package/dist/client/index.d.ts.map +1 -0
  37. package/dist/client/index.js +18 -0
  38. package/dist/client/index.js.map +1 -0
  39. package/dist/client/transports.d.ts +78 -0
  40. package/dist/client/transports.d.ts.map +1 -0
  41. package/dist/client/transports.js +258 -0
  42. package/dist/client/transports.js.map +1 -0
  43. package/dist/client/types.d.ts +49 -0
  44. package/dist/client/types.d.ts.map +1 -0
  45. package/dist/client/types.js +8 -0
  46. package/dist/client/types.js.map +1 -0
  47. package/dist/config.d.ts +8 -0
  48. package/dist/config.d.ts.map +1 -0
  49. package/dist/config.js +19 -0
  50. package/dist/config.js.map +1 -0
  51. package/dist/daemon.d.ts +77 -0
  52. package/dist/daemon.d.ts.map +1 -0
  53. package/dist/daemon.js +374 -0
  54. package/dist/daemon.js.map +1 -0
  55. package/dist/daemonConfig.d.ts +43 -0
  56. package/dist/daemonConfig.d.ts.map +1 -0
  57. package/dist/daemonConfig.js +113 -0
  58. package/dist/daemonConfig.js.map +1 -0
  59. package/dist/dataRoot.d.ts +5 -0
  60. package/dist/dataRoot.d.ts.map +1 -0
  61. package/dist/dataRoot.js +23 -0
  62. package/dist/dataRoot.js.map +1 -0
  63. package/dist/decibelPaths.d.ts +42 -0
  64. package/dist/decibelPaths.d.ts.map +1 -0
  65. package/dist/decibelPaths.js +150 -0
  66. package/dist/decibelPaths.js.map +1 -0
  67. package/dist/facades/definitions.d.ts +6 -0
  68. package/dist/facades/definitions.d.ts.map +1 -0
  69. package/dist/facades/definitions.js +450 -0
  70. package/dist/facades/definitions.js.map +1 -0
  71. package/dist/facades/index.d.ts +27 -0
  72. package/dist/facades/index.d.ts.map +1 -0
  73. package/dist/facades/index.js +124 -0
  74. package/dist/facades/index.js.map +1 -0
  75. package/dist/facades/types.d.ts +38 -0
  76. package/dist/facades/types.d.ts.map +1 -0
  77. package/dist/facades/types.js +8 -0
  78. package/dist/facades/types.js.map +1 -0
  79. package/dist/httpServer.d.ts +66 -0
  80. package/dist/httpServer.d.ts.map +1 -0
  81. package/dist/httpServer.js +1723 -0
  82. package/dist/httpServer.js.map +1 -0
  83. package/dist/kernel.d.ts +87 -0
  84. package/dist/kernel.d.ts.map +1 -0
  85. package/dist/kernel.js +256 -0
  86. package/dist/kernel.js.map +1 -0
  87. package/dist/lib/agent-services/assumptions.d.ts +16 -0
  88. package/dist/lib/agent-services/assumptions.d.ts.map +1 -0
  89. package/dist/lib/agent-services/assumptions.js +284 -0
  90. package/dist/lib/agent-services/assumptions.js.map +1 -0
  91. package/dist/lib/agent-services/context-pack.d.ts +6 -0
  92. package/dist/lib/agent-services/context-pack.d.ts.map +1 -0
  93. package/dist/lib/agent-services/context-pack.js +354 -0
  94. package/dist/lib/agent-services/context-pack.js.map +1 -0
  95. package/dist/lib/agent-services/drift-guard.d.ts +14 -0
  96. package/dist/lib/agent-services/drift-guard.d.ts.map +1 -0
  97. package/dist/lib/agent-services/drift-guard.js +355 -0
  98. package/dist/lib/agent-services/drift-guard.js.map +1 -0
  99. package/dist/lib/agent-services/index.d.ts +5 -0
  100. package/dist/lib/agent-services/index.d.ts.map +1 -0
  101. package/dist/lib/agent-services/index.js +10 -0
  102. package/dist/lib/agent-services/index.js.map +1 -0
  103. package/dist/lib/benchmark.d.ts +110 -0
  104. package/dist/lib/benchmark.d.ts.map +1 -0
  105. package/dist/lib/benchmark.js +338 -0
  106. package/dist/lib/benchmark.js.map +1 -0
  107. package/dist/lib/supabase.d.ts +123 -0
  108. package/dist/lib/supabase.d.ts.map +1 -0
  109. package/dist/lib/supabase.js +91 -0
  110. package/dist/lib/supabase.js.map +1 -0
  111. package/dist/license.d.ts +30 -0
  112. package/dist/license.d.ts.map +1 -0
  113. package/dist/license.js +131 -0
  114. package/dist/license.js.map +1 -0
  115. package/dist/projectPaths.d.ts +27 -0
  116. package/dist/projectPaths.d.ts.map +1 -0
  117. package/dist/projectPaths.js +86 -0
  118. package/dist/projectPaths.js.map +1 -0
  119. package/dist/projectRegistry.d.ts +97 -0
  120. package/dist/projectRegistry.d.ts.map +1 -0
  121. package/dist/projectRegistry.js +374 -0
  122. package/dist/projectRegistry.js.map +1 -0
  123. package/dist/sentinelIssues.d.ts +65 -0
  124. package/dist/sentinelIssues.d.ts.map +1 -0
  125. package/dist/sentinelIssues.js +297 -0
  126. package/dist/sentinelIssues.js.map +1 -0
  127. package/dist/server.d.ts +3 -0
  128. package/dist/server.d.ts.map +1 -0
  129. package/dist/server.js +195 -0
  130. package/dist/server.js.map +1 -0
  131. package/dist/test.d.ts +7 -0
  132. package/dist/test.d.ts.map +1 -0
  133. package/dist/test.js +77 -0
  134. package/dist/test.js.map +1 -0
  135. package/dist/tools/agentic/index.d.ts +7 -0
  136. package/dist/tools/agentic/index.d.ts.map +1 -0
  137. package/dist/tools/agentic/index.js +203 -0
  138. package/dist/tools/agentic/index.js.map +1 -0
  139. package/dist/tools/architect/index.d.ts +11 -0
  140. package/dist/tools/architect/index.d.ts.map +1 -0
  141. package/dist/tools/architect/index.js +506 -0
  142. package/dist/tools/architect/index.js.map +1 -0
  143. package/dist/tools/architect.d.ts +19 -0
  144. package/dist/tools/architect.d.ts.map +1 -0
  145. package/dist/tools/architect.js +88 -0
  146. package/dist/tools/architect.js.map +1 -0
  147. package/dist/tools/auditor/index.d.ts +10 -0
  148. package/dist/tools/auditor/index.d.ts.map +1 -0
  149. package/dist/tools/auditor/index.js +310 -0
  150. package/dist/tools/auditor/index.js.map +1 -0
  151. package/dist/tools/auditor.d.ts +149 -0
  152. package/dist/tools/auditor.d.ts.map +1 -0
  153. package/dist/tools/auditor.js +775 -0
  154. package/dist/tools/auditor.js.map +1 -0
  155. package/dist/tools/bench/index.d.ts +3 -0
  156. package/dist/tools/bench/index.d.ts.map +1 -0
  157. package/dist/tools/bench/index.js +220 -0
  158. package/dist/tools/bench/index.js.map +1 -0
  159. package/dist/tools/bench.d.ts +89 -0
  160. package/dist/tools/bench.d.ts.map +1 -0
  161. package/dist/tools/bench.js +826 -0
  162. package/dist/tools/bench.js.map +1 -0
  163. package/dist/tools/context/index.d.ts +11 -0
  164. package/dist/tools/context/index.d.ts.map +1 -0
  165. package/dist/tools/context/index.js +482 -0
  166. package/dist/tools/context/index.js.map +1 -0
  167. package/dist/tools/context.d.ts +146 -0
  168. package/dist/tools/context.d.ts.map +1 -0
  169. package/dist/tools/context.js +481 -0
  170. package/dist/tools/context.js.map +1 -0
  171. package/dist/tools/coordinator/coordinator.d.ts +168 -0
  172. package/dist/tools/coordinator/coordinator.d.ts.map +1 -0
  173. package/dist/tools/coordinator/coordinator.js +535 -0
  174. package/dist/tools/coordinator/coordinator.js.map +1 -0
  175. package/dist/tools/coordinator/index.d.ts +12 -0
  176. package/dist/tools/coordinator/index.d.ts.map +1 -0
  177. package/dist/tools/coordinator/index.js +381 -0
  178. package/dist/tools/coordinator/index.js.map +1 -0
  179. package/dist/tools/corpus/index.d.ts +5 -0
  180. package/dist/tools/corpus/index.d.ts.map +1 -0
  181. package/dist/tools/corpus/index.js +105 -0
  182. package/dist/tools/corpus/index.js.map +1 -0
  183. package/dist/tools/corpus.d.ts +33 -0
  184. package/dist/tools/corpus.d.ts.map +1 -0
  185. package/dist/tools/corpus.js +180 -0
  186. package/dist/tools/corpus.js.map +1 -0
  187. package/dist/tools/crit.d.ts +63 -0
  188. package/dist/tools/crit.d.ts.map +1 -0
  189. package/dist/tools/crit.js +159 -0
  190. package/dist/tools/crit.js.map +1 -0
  191. package/dist/tools/data-inspector.d.ts +189 -0
  192. package/dist/tools/data-inspector.d.ts.map +1 -0
  193. package/dist/tools/data-inspector.js +669 -0
  194. package/dist/tools/data-inspector.js.map +1 -0
  195. package/dist/tools/deck.d.ts +11 -0
  196. package/dist/tools/deck.d.ts.map +1 -0
  197. package/dist/tools/deck.js +188 -0
  198. package/dist/tools/deck.js.map +1 -0
  199. package/dist/tools/designer/index.d.ts +11 -0
  200. package/dist/tools/designer/index.d.ts.map +1 -0
  201. package/dist/tools/designer/index.js +442 -0
  202. package/dist/tools/designer/index.js.map +1 -0
  203. package/dist/tools/designer/lateral-tools.d.ts +6 -0
  204. package/dist/tools/designer/lateral-tools.d.ts.map +1 -0
  205. package/dist/tools/designer/lateral-tools.js +190 -0
  206. package/dist/tools/designer/lateral-tools.js.map +1 -0
  207. package/dist/tools/designer.d.ts +122 -0
  208. package/dist/tools/designer.d.ts.map +1 -0
  209. package/dist/tools/designer.js +495 -0
  210. package/dist/tools/designer.js.map +1 -0
  211. package/dist/tools/dojo/index.d.ts +13 -0
  212. package/dist/tools/dojo/index.d.ts.map +1 -0
  213. package/dist/tools/dojo/index.js +613 -0
  214. package/dist/tools/dojo/index.js.map +1 -0
  215. package/dist/tools/dojo.d.ts +254 -0
  216. package/dist/tools/dojo.d.ts.map +1 -0
  217. package/dist/tools/dojo.js +933 -0
  218. package/dist/tools/dojo.js.map +1 -0
  219. package/dist/tools/dojoBench.d.ts +49 -0
  220. package/dist/tools/dojoBench.d.ts.map +1 -0
  221. package/dist/tools/dojoBench.js +205 -0
  222. package/dist/tools/dojoBench.js.map +1 -0
  223. package/dist/tools/dojoGraduated.d.ts +50 -0
  224. package/dist/tools/dojoGraduated.d.ts.map +1 -0
  225. package/dist/tools/dojoGraduated.js +174 -0
  226. package/dist/tools/dojoGraduated.js.map +1 -0
  227. package/dist/tools/dojoPolicy.d.ts +65 -0
  228. package/dist/tools/dojoPolicy.d.ts.map +1 -0
  229. package/dist/tools/dojoPolicy.js +263 -0
  230. package/dist/tools/dojoPolicy.js.map +1 -0
  231. package/dist/tools/feedback/index.d.ts +5 -0
  232. package/dist/tools/feedback/index.d.ts.map +1 -0
  233. package/dist/tools/feedback/index.js +153 -0
  234. package/dist/tools/feedback/index.js.map +1 -0
  235. package/dist/tools/feedback.d.ts +61 -0
  236. package/dist/tools/feedback.d.ts.map +1 -0
  237. package/dist/tools/feedback.js +209 -0
  238. package/dist/tools/feedback.js.map +1 -0
  239. package/dist/tools/forecast/index.d.ts +8 -0
  240. package/dist/tools/forecast/index.d.ts.map +1 -0
  241. package/dist/tools/forecast/index.js +283 -0
  242. package/dist/tools/forecast/index.js.map +1 -0
  243. package/dist/tools/forecast.d.ts +147 -0
  244. package/dist/tools/forecast.d.ts.map +1 -0
  245. package/dist/tools/forecast.js +417 -0
  246. package/dist/tools/forecast.js.map +1 -0
  247. package/dist/tools/friction/index.d.ts +7 -0
  248. package/dist/tools/friction/index.d.ts.map +1 -0
  249. package/dist/tools/friction/index.js +265 -0
  250. package/dist/tools/friction/index.js.map +1 -0
  251. package/dist/tools/friction.d.ts +82 -0
  252. package/dist/tools/friction.d.ts.map +1 -0
  253. package/dist/tools/friction.js +331 -0
  254. package/dist/tools/friction.js.map +1 -0
  255. package/dist/tools/git/index.d.ts +9 -0
  256. package/dist/tools/git/index.d.ts.map +1 -0
  257. package/dist/tools/git/index.js +237 -0
  258. package/dist/tools/git/index.js.map +1 -0
  259. package/dist/tools/git-sentinel/index.d.ts +7 -0
  260. package/dist/tools/git-sentinel/index.d.ts.map +1 -0
  261. package/dist/tools/git-sentinel/index.js +178 -0
  262. package/dist/tools/git-sentinel/index.js.map +1 -0
  263. package/dist/tools/git-sentinel.d.ts +78 -0
  264. package/dist/tools/git-sentinel.d.ts.map +1 -0
  265. package/dist/tools/git-sentinel.js +391 -0
  266. package/dist/tools/git-sentinel.js.map +1 -0
  267. package/dist/tools/git.d.ts +134 -0
  268. package/dist/tools/git.d.ts.map +1 -0
  269. package/dist/tools/git.js +374 -0
  270. package/dist/tools/git.js.map +1 -0
  271. package/dist/tools/guardian/index.d.ts +8 -0
  272. package/dist/tools/guardian/index.d.ts.map +1 -0
  273. package/dist/tools/guardian/index.js +171 -0
  274. package/dist/tools/guardian/index.js.map +1 -0
  275. package/dist/tools/guardian.d.ts +62 -0
  276. package/dist/tools/guardian.d.ts.map +1 -0
  277. package/dist/tools/guardian.js +332 -0
  278. package/dist/tools/guardian.js.map +1 -0
  279. package/dist/tools/hygiene/codebase-scanner.d.ts +38 -0
  280. package/dist/tools/hygiene/codebase-scanner.d.ts.map +1 -0
  281. package/dist/tools/hygiene/codebase-scanner.js +411 -0
  282. package/dist/tools/hygiene/codebase-scanner.js.map +1 -0
  283. package/dist/tools/hygiene/config-scanner.d.ts +33 -0
  284. package/dist/tools/hygiene/config-scanner.d.ts.map +1 -0
  285. package/dist/tools/hygiene/config-scanner.js +482 -0
  286. package/dist/tools/hygiene/config-scanner.js.map +1 -0
  287. package/dist/tools/hygiene/coverage-scanner.d.ts +41 -0
  288. package/dist/tools/hygiene/coverage-scanner.d.ts.map +1 -0
  289. package/dist/tools/hygiene/coverage-scanner.js +331 -0
  290. package/dist/tools/hygiene/coverage-scanner.js.map +1 -0
  291. package/dist/tools/hygiene/index.d.ts +7 -0
  292. package/dist/tools/hygiene/index.d.ts.map +1 -0
  293. package/dist/tools/hygiene/index.js +291 -0
  294. package/dist/tools/hygiene/index.js.map +1 -0
  295. package/dist/tools/hygiene/oracle-hygiene.d.ts +68 -0
  296. package/dist/tools/hygiene/oracle-hygiene.d.ts.map +1 -0
  297. package/dist/tools/hygiene/oracle-hygiene.js +324 -0
  298. package/dist/tools/hygiene/oracle-hygiene.js.map +1 -0
  299. package/dist/tools/index.d.ts +6 -0
  300. package/dist/tools/index.d.ts.map +1 -0
  301. package/dist/tools/index.js +130 -0
  302. package/dist/tools/index.js.map +1 -0
  303. package/dist/tools/lateral.d.ts +114 -0
  304. package/dist/tools/lateral.d.ts.map +1 -0
  305. package/dist/tools/lateral.js +536 -0
  306. package/dist/tools/lateral.js.map +1 -0
  307. package/dist/tools/learnings/index.d.ts +5 -0
  308. package/dist/tools/learnings/index.d.ts.map +1 -0
  309. package/dist/tools/learnings/index.js +138 -0
  310. package/dist/tools/learnings/index.js.map +1 -0
  311. package/dist/tools/learnings.d.ts +41 -0
  312. package/dist/tools/learnings.d.ts.map +1 -0
  313. package/dist/tools/learnings.js +149 -0
  314. package/dist/tools/learnings.js.map +1 -0
  315. package/dist/tools/oracle/index.d.ts +6 -0
  316. package/dist/tools/oracle/index.d.ts.map +1 -0
  317. package/dist/tools/oracle/index.js +217 -0
  318. package/dist/tools/oracle/index.js.map +1 -0
  319. package/dist/tools/oracle.d.ts +90 -0
  320. package/dist/tools/oracle.d.ts.map +1 -0
  321. package/dist/tools/oracle.js +529 -0
  322. package/dist/tools/oracle.js.map +1 -0
  323. package/dist/tools/policy.d.ts +119 -0
  324. package/dist/tools/policy.d.ts.map +1 -0
  325. package/dist/tools/policy.js +406 -0
  326. package/dist/tools/policy.js.map +1 -0
  327. package/dist/tools/provenance/index.d.ts +4 -0
  328. package/dist/tools/provenance/index.d.ts.map +1 -0
  329. package/dist/tools/provenance/index.js +63 -0
  330. package/dist/tools/provenance/index.js.map +1 -0
  331. package/dist/tools/provenance.d.ts +75 -0
  332. package/dist/tools/provenance.d.ts.map +1 -0
  333. package/dist/tools/provenance.js +224 -0
  334. package/dist/tools/provenance.js.map +1 -0
  335. package/dist/tools/rateLimiter.d.ts +45 -0
  336. package/dist/tools/rateLimiter.d.ts.map +1 -0
  337. package/dist/tools/rateLimiter.js +91 -0
  338. package/dist/tools/rateLimiter.js.map +1 -0
  339. package/dist/tools/registry/index.d.ts +10 -0
  340. package/dist/tools/registry/index.d.ts.map +1 -0
  341. package/dist/tools/registry/index.js +506 -0
  342. package/dist/tools/registry/index.js.map +1 -0
  343. package/dist/tools/registry.d.ts +3 -0
  344. package/dist/tools/registry.d.ts.map +1 -0
  345. package/dist/tools/registry.js +189 -0
  346. package/dist/tools/registry.js.map +1 -0
  347. package/dist/tools/roadmap/index.d.ts +11 -0
  348. package/dist/tools/roadmap/index.d.ts.map +1 -0
  349. package/dist/tools/roadmap/index.js +364 -0
  350. package/dist/tools/roadmap/index.js.map +1 -0
  351. package/dist/tools/roadmap.d.ts +103 -0
  352. package/dist/tools/roadmap.d.ts.map +1 -0
  353. package/dist/tools/roadmap.js +407 -0
  354. package/dist/tools/roadmap.js.map +1 -0
  355. package/dist/tools/senken.d.ts +11 -0
  356. package/dist/tools/senken.d.ts.map +1 -0
  357. package/dist/tools/senken.js +482 -0
  358. package/dist/tools/senken.js.map +1 -0
  359. package/dist/tools/sentinel/index.d.ts +21 -0
  360. package/dist/tools/sentinel/index.d.ts.map +1 -0
  361. package/dist/tools/sentinel/index.js +1067 -0
  362. package/dist/tools/sentinel/index.js.map +1 -0
  363. package/dist/tools/sentinel-scan-data.d.ts +90 -0
  364. package/dist/tools/sentinel-scan-data.d.ts.map +1 -0
  365. package/dist/tools/sentinel-scan-data.js +122 -0
  366. package/dist/tools/sentinel-scan-data.js.map +1 -0
  367. package/dist/tools/sentinel.d.ts +156 -0
  368. package/dist/tools/sentinel.d.ts.map +1 -0
  369. package/dist/tools/sentinel.js +603 -0
  370. package/dist/tools/sentinel.js.map +1 -0
  371. package/dist/tools/shared/index.d.ts +5 -0
  372. package/dist/tools/shared/index.d.ts.map +1 -0
  373. package/dist/tools/shared/index.js +8 -0
  374. package/dist/tools/shared/index.js.map +1 -0
  375. package/dist/tools/shared/project.d.ts +17 -0
  376. package/dist/tools/shared/project.d.ts.map +1 -0
  377. package/dist/tools/shared/project.js +36 -0
  378. package/dist/tools/shared/project.js.map +1 -0
  379. package/dist/tools/shared/response.d.ts +15 -0
  380. package/dist/tools/shared/response.d.ts.map +1 -0
  381. package/dist/tools/shared/response.js +77 -0
  382. package/dist/tools/shared/response.js.map +1 -0
  383. package/dist/tools/shared/runTracker.d.ts +87 -0
  384. package/dist/tools/shared/runTracker.d.ts.map +1 -0
  385. package/dist/tools/shared/runTracker.js +225 -0
  386. package/dist/tools/shared/runTracker.js.map +1 -0
  387. package/dist/tools/shared/validation.d.ts +10 -0
  388. package/dist/tools/shared/validation.d.ts.map +1 -0
  389. package/dist/tools/shared/validation.js +26 -0
  390. package/dist/tools/shared/validation.js.map +1 -0
  391. package/dist/tools/studio/cloud-spine.d.ts +27 -0
  392. package/dist/tools/studio/cloud-spine.d.ts.map +1 -0
  393. package/dist/tools/studio/cloud-spine.js +845 -0
  394. package/dist/tools/studio/cloud-spine.js.map +1 -0
  395. package/dist/tools/studio/index.d.ts +154 -0
  396. package/dist/tools/studio/index.d.ts.map +1 -0
  397. package/dist/tools/studio/index.js +541 -0
  398. package/dist/tools/studio/index.js.map +1 -0
  399. package/dist/tools/testSpec.d.ts +122 -0
  400. package/dist/tools/testSpec.d.ts.map +1 -0
  401. package/dist/tools/testSpec.js +525 -0
  402. package/dist/tools/testSpec.js.map +1 -0
  403. package/dist/tools/toolsIndex.d.ts +5 -0
  404. package/dist/tools/toolsIndex.d.ts.map +1 -0
  405. package/dist/tools/toolsIndex.js +37 -0
  406. package/dist/tools/toolsIndex.js.map +1 -0
  407. package/dist/tools/types.d.ts +47 -0
  408. package/dist/tools/types.d.ts.map +1 -0
  409. package/dist/tools/types.js +7 -0
  410. package/dist/tools/types.js.map +1 -0
  411. package/dist/tools/vector/index.d.ts +13 -0
  412. package/dist/tools/vector/index.d.ts.map +1 -0
  413. package/dist/tools/vector/index.js +592 -0
  414. package/dist/tools/vector/index.js.map +1 -0
  415. package/dist/tools/vector.d.ts +189 -0
  416. package/dist/tools/vector.d.ts.map +1 -0
  417. package/dist/tools/vector.js +570 -0
  418. package/dist/tools/vector.js.map +1 -0
  419. package/dist/tools/velocity/index.d.ts +9 -0
  420. package/dist/tools/velocity/index.d.ts.map +1 -0
  421. package/dist/tools/velocity/index.js +306 -0
  422. package/dist/tools/velocity/index.js.map +1 -0
  423. package/dist/tools/velocity.d.ts +143 -0
  424. package/dist/tools/velocity.d.ts.map +1 -0
  425. package/dist/tools/velocity.js +628 -0
  426. package/dist/tools/velocity.js.map +1 -0
  427. package/dist/tools/voice/index.d.ts +8 -0
  428. package/dist/tools/voice/index.d.ts.map +1 -0
  429. package/dist/tools/voice/index.js +203 -0
  430. package/dist/tools/voice/index.js.map +1 -0
  431. package/dist/tools/voice.d.ts +291 -0
  432. package/dist/tools/voice.d.ts.map +1 -0
  433. package/dist/tools/voice.js +734 -0
  434. package/dist/tools/voice.js.map +1 -0
  435. package/dist/tools/workflow/index.d.ts +8 -0
  436. package/dist/tools/workflow/index.d.ts.map +1 -0
  437. package/dist/tools/workflow/index.js +199 -0
  438. package/dist/tools/workflow/index.js.map +1 -0
  439. package/dist/tools/workflow.d.ts +123 -0
  440. package/dist/tools/workflow.d.ts.map +1 -0
  441. package/dist/tools/workflow.js +647 -0
  442. package/dist/tools/workflow.js.map +1 -0
  443. package/dist/transports/bridge.d.ts +22 -0
  444. package/dist/transports/bridge.d.ts.map +1 -0
  445. package/dist/transports/bridge.js +177 -0
  446. package/dist/transports/bridge.js.map +1 -0
  447. package/dist/transports/http.d.ts +9 -0
  448. package/dist/transports/http.d.ts.map +1 -0
  449. package/dist/transports/http.js +35 -0
  450. package/dist/transports/http.js.map +1 -0
  451. package/dist/transports/index.d.ts +6 -0
  452. package/dist/transports/index.d.ts.map +1 -0
  453. package/dist/transports/index.js +8 -0
  454. package/dist/transports/index.js.map +1 -0
  455. package/dist/transports/mcp.d.ts +9 -0
  456. package/dist/transports/mcp.d.ts.map +1 -0
  457. package/dist/transports/mcp.js +51 -0
  458. package/dist/transports/mcp.js.map +1 -0
  459. package/dist/transports/stdio.d.ts +9 -0
  460. package/dist/transports/stdio.d.ts.map +1 -0
  461. package/dist/transports/stdio.js +26 -0
  462. package/dist/transports/stdio.js.map +1 -0
  463. package/dist/transports/types.d.ts +27 -0
  464. package/dist/transports/types.d.ts.map +1 -0
  465. package/dist/transports/types.js +8 -0
  466. package/dist/transports/types.js.map +1 -0
  467. package/dist/types/agent-services.d.ts +193 -0
  468. package/dist/types/agent-services.d.ts.map +1 -0
  469. package/dist/types/agent-services.js +8 -0
  470. package/dist/types/agent-services.js.map +1 -0
  471. package/dist/types/index.d.ts +2 -0
  472. package/dist/types/index.d.ts.map +1 -0
  473. package/dist/types/index.js +7 -0
  474. package/dist/types/index.js.map +1 -0
  475. package/package.json +72 -0
  476. package/templates/AGENT.md +87 -0
  477. package/templates/com.decibel.daemon.plist +47 -0
  478. package/templates/sentinel/ISSUE_TEMPLATE.md +20 -0
@@ -0,0 +1,826 @@
1
+ /**
2
+ * Decibel Benchmark MCP Tool
3
+ *
4
+ * First-class benchmarking tool for the decibel toolchain.
5
+ * Runs benchmark suites with kind support (micro/integration),
6
+ * baseline persistence, and regression detection.
7
+ *
8
+ * Usage:
9
+ * - decibel_bench: Run TypeScript/JavaScript benchmark suites
10
+ * - dojo_bench: Specialized for Dojo experiments (Python discovery)
11
+ */
12
+ import { spawn } from 'child_process';
13
+ import fs from 'fs/promises';
14
+ import { existsSync } from 'fs';
15
+ import path from 'path';
16
+ import { log } from '../config.js';
17
+ import { resolveProjectRoot } from '../projectPaths.js';
18
+ import { enforceToolAccess } from './dojoPolicy.js';
19
+ import { checkRateLimit, recordRequestStart, recordRequestEnd } from './rateLimiter.js';
20
+ import { formatTable, formatMarkdown, } from '../lib/benchmark.js';
21
+ // ============================================================================
22
+ // Helper: Build context with policy enforcement
23
+ // ============================================================================
24
+ async function buildBenchContext(projectId, callerRole = 'human', toolName, agentId) {
25
+ // Check rate limits
26
+ const rateLimitResult = checkRateLimit(callerRole);
27
+ if (!rateLimitResult.allowed) {
28
+ throw new Error(`Rate limit: ${rateLimitResult.reason}`);
29
+ }
30
+ // Enforce policy
31
+ enforceToolAccess(toolName, callerRole);
32
+ // Record request start
33
+ recordRequestStart(callerRole);
34
+ // Resolve paths
35
+ const project = await resolveProjectRoot(projectId);
36
+ // Audit log for AI callers
37
+ if (callerRole !== 'human') {
38
+ log(`bench-audit: [${new Date().toISOString()}] agent=${agentId || 'unknown'} role=${callerRole} tool=${toolName} project=${projectId}`);
39
+ }
40
+ return { projectRoot: project.root };
41
+ }
42
+ // ============================================================================
43
+ // Python Benchmark Runner (for Dojo experiments)
44
+ // ============================================================================
45
+ /**
46
+ * Generate Python script to discover and run benchmarks from experiments
47
+ */
48
+ export function generatePythonBenchRunner(experimentPath, kind, iterations, warmup, thresholdNs, baselinePath, regressionTolerance) {
49
+ return `#!/usr/bin/env python3
50
+ """Benchmark runner for Dojo experiments - auto-generated"""
51
+
52
+ import json
53
+ import sys
54
+ import time
55
+ import statistics
56
+ import importlib.util
57
+ import os
58
+ from pathlib import Path
59
+
60
+ def discover_benchmarks(experiment_path: str) -> dict:
61
+ """Discover benchmarks from experiment module"""
62
+ run_py = Path(experiment_path) / "run.py"
63
+ if not run_py.exists():
64
+ return None
65
+
66
+ spec = importlib.util.spec_from_file_location("exp", str(run_py))
67
+ module = importlib.util.module_from_spec(spec)
68
+
69
+ # Add experiment path to sys.path for imports
70
+ sys.path.insert(0, str(Path(experiment_path)))
71
+
72
+ try:
73
+ spec.loader.exec_module(module)
74
+ except Exception as e:
75
+ print(json.dumps({"error": f"Failed to load module: {e}"}))
76
+ sys.exit(1)
77
+
78
+ # Try function first
79
+ if hasattr(module, 'dojo_benchmark'):
80
+ try:
81
+ return module.dojo_benchmark()
82
+ except Exception as e:
83
+ print(json.dumps({"error": f"dojo_benchmark() failed: {e}"}))
84
+ sys.exit(1)
85
+
86
+ # Try dict
87
+ if hasattr(module, 'DOJO_BENCHMARKS'):
88
+ return module.DOJO_BENCHMARKS
89
+
90
+ return None
91
+
92
+ def calculate_stddev(times: list) -> float:
93
+ if len(times) < 2:
94
+ return 0
95
+ return statistics.stdev(times)
96
+
97
+ def calculate_stability(stddev: float, mean: float) -> str:
98
+ if mean == 0:
99
+ return "high"
100
+ cv = stddev / mean
101
+ if cv < 0.1:
102
+ return "high"
103
+ elif cv < 0.3:
104
+ return "medium"
105
+ return "low"
106
+
107
+ def run_benchmark(fn, iterations: int, warmup: int, threshold_ns: int, kind: str) -> dict:
108
+ """Run a single benchmark"""
109
+ # Warmup
110
+ for _ in range(warmup):
111
+ fn()
112
+
113
+ # Measure
114
+ times = []
115
+ for _ in range(iterations):
116
+ start = time.perf_counter_ns()
117
+ fn()
118
+ elapsed = time.perf_counter_ns() - start
119
+ times.append(elapsed)
120
+
121
+ times.sort()
122
+ mean = statistics.mean(times)
123
+ stddev = calculate_stddev(times)
124
+ stability = calculate_stability(stddev, mean)
125
+ p99 = times[int(len(times) * 0.99)]
126
+
127
+ return {
128
+ "p50_ns": times[int(len(times) * 0.50)],
129
+ "p95_ns": times[int(len(times) * 0.95)],
130
+ "p99_ns": p99,
131
+ "max_ns": times[-1],
132
+ "min_ns": times[0],
133
+ "mean_ns": int(mean),
134
+ "stddev_ns": int(stddev),
135
+ "iterations": iterations,
136
+ "stability": stability,
137
+ "threshold_p99_ns": threshold_ns,
138
+ "passed": p99 < threshold_ns,
139
+ "kind": kind,
140
+ }
141
+
142
+ def get_verdict(results: list, has_regressions: bool) -> str:
143
+ """Determine verdict"""
144
+ if has_regressions:
145
+ return "SLOW"
146
+ all_passed = all(r["passed"] for r in results)
147
+ if all_passed:
148
+ return "FAST"
149
+ pass_rate = sum(1 for r in results if r["passed"]) / len(results)
150
+ if pass_rate >= 0.8:
151
+ return "OK"
152
+ return "SLOW"
153
+
154
+ def get_platform():
155
+ """Get platform fingerprint"""
156
+ import platform
157
+ import subprocess
158
+
159
+ git_sha = None
160
+ git_branch = None
161
+ try:
162
+ git_sha = subprocess.check_output(['git', 'rev-parse', 'HEAD'],
163
+ stderr=subprocess.DEVNULL).decode().strip()
164
+ git_branch = subprocess.check_output(['git', 'rev-parse', '--abbrev-ref', 'HEAD'],
165
+ stderr=subprocess.DEVNULL).decode().strip()
166
+ except:
167
+ pass
168
+
169
+ return {
170
+ "git_sha": git_sha,
171
+ "git_branch": git_branch,
172
+ "node_version": f"python{sys.version_info.major}.{sys.version_info.minor}",
173
+ "os_arch": f"{platform.system().lower()}-{platform.machine()}",
174
+ "cpu_model": platform.processor() or "unknown",
175
+ "timestamp": time.strftime("%Y-%m-%dT%H:%M:%S.000Z", time.gmtime())
176
+ }
177
+
178
+ def main():
179
+ experiment_path = ${JSON.stringify(experimentPath)}
180
+ kind = ${JSON.stringify(kind)}
181
+ iterations = ${iterations}
182
+ warmup = ${warmup}
183
+ threshold_ns = ${thresholdNs}
184
+ baseline_path = ${baselinePath ? JSON.stringify(baselinePath) : 'None'}
185
+ regression_tolerance = ${regressionTolerance ?? 0.10}
186
+
187
+ benchmarks = discover_benchmarks(experiment_path)
188
+
189
+ if benchmarks is None:
190
+ print(json.dumps({
191
+ "status": "no_benchmarks",
192
+ "message": "No DOJO_BENCHMARKS or dojo_benchmark() found"
193
+ }))
194
+ sys.exit(0)
195
+
196
+ if not benchmarks:
197
+ print(json.dumps({
198
+ "status": "no_benchmarks",
199
+ "message": "Benchmark dict is empty"
200
+ }))
201
+ sys.exit(0)
202
+
203
+ results = []
204
+ for name, fn in benchmarks.items():
205
+ result = run_benchmark(fn, iterations, warmup, threshold_ns, kind)
206
+ result["id"] = name
207
+ results.append(result)
208
+
209
+ # Load baseline for regression detection
210
+ baseline = None
211
+ regressions = []
212
+ if baseline_path and os.path.exists(baseline_path):
213
+ try:
214
+ with open(baseline_path) as f:
215
+ baseline = json.load(f)
216
+ except:
217
+ pass
218
+
219
+ if baseline and "results" in baseline:
220
+ for result in results:
221
+ if result["id"] in baseline["results"]:
222
+ base = baseline["results"][result["id"]]
223
+ delta_pct = (result["p99_ns"] - base["p99_ns"]) / base["p99_ns"]
224
+ regressions.append({
225
+ "id": result["id"],
226
+ "baseline_p99_ns": base["p99_ns"],
227
+ "current_p99_ns": result["p99_ns"],
228
+ "delta_pct": delta_pct,
229
+ "regressed": delta_pct > regression_tolerance,
230
+ "tolerance_pct": regression_tolerance
231
+ })
232
+
233
+ has_regressions = any(r["regressed"] for r in regressions)
234
+ verdict = get_verdict(results, has_regressions)
235
+ platform = get_platform()
236
+
237
+ report = {
238
+ "suite_id": Path(experiment_path).name,
239
+ "kind": kind,
240
+ "results": results,
241
+ "regressions": regressions,
242
+ "verdict": verdict,
243
+ "platform": platform,
244
+ "baseline_used": baseline_path if baseline else None,
245
+ "has_regressions": has_regressions,
246
+ "timestamp": time.strftime("%Y-%m-%dT%H:%M:%S.000Z", time.gmtime())
247
+ }
248
+
249
+ output = {
250
+ "status": "regression_detected" if has_regressions else "success",
251
+ "report": report
252
+ }
253
+
254
+ print(json.dumps(output))
255
+
256
+ if __name__ == "__main__":
257
+ main()
258
+ `;
259
+ }
260
+ // ============================================================================
261
+ // Formatting
262
+ // ============================================================================
263
+ function formatBenchTable(report) {
264
+ return formatTable(report);
265
+ }
266
+ function formatBenchMarkdown(report) {
267
+ return formatMarkdown(report);
268
+ }
269
+ // ============================================================================
270
+ // Type Guards
271
+ // ============================================================================
272
+ export function isDecibelBenchError(result) {
273
+ return (typeof result === 'object' &&
274
+ result !== null &&
275
+ 'error' in result &&
276
+ 'exitCode' in result);
277
+ }
278
+ export function isBenchCompareError(result) {
279
+ return (typeof result === 'object' &&
280
+ result !== null &&
281
+ 'error' in result &&
282
+ 'exitCode' in result);
283
+ }
284
+ // ============================================================================
285
+ // Kind Defaults
286
+ // ============================================================================
287
+ const KIND_DEFAULTS = {
288
+ micro: {
289
+ iterations: 10000,
290
+ warmup: 1000,
291
+ threshold_p99_ns: 100_000, // 100μs
292
+ },
293
+ integration: {
294
+ iterations: 100,
295
+ warmup: 10,
296
+ threshold_p99_ns: 500_000_000, // 500ms
297
+ },
298
+ };
299
+ // ============================================================================
300
+ // decibel_bench: Run TS/JS benchmark suites
301
+ // ============================================================================
302
+ /**
303
+ * Run a benchmark suite from a TS/JS file
304
+ * Discovers benchmarks via BENCHMARKS export or benchmarks() function
305
+ */
306
+ export async function decibelBench(input) {
307
+ const callerRole = input.caller_role || 'human';
308
+ try {
309
+ const { projectRoot } = await buildBenchContext(input.project_id, callerRole, 'decibel_bench', input.agent_id);
310
+ // Determine kind and defaults
311
+ const kind = input.kind || 'micro';
312
+ const defaults = KIND_DEFAULTS[kind];
313
+ // Build baseline path
314
+ const baselineDir = path.join(projectRoot, '.decibel', 'benchmarks');
315
+ const baselinePath = path.join(baselineDir, `${input.suite_id}-baseline.json`);
316
+ // Build options
317
+ const options = {
318
+ kind,
319
+ iterations: input.iterations ?? defaults.iterations,
320
+ warmup: input.warmup ?? defaults.warmup,
321
+ threshold_p99_ns: input.threshold_p99_ns ?? defaults.threshold_p99_ns,
322
+ regression_tolerance: input.regression_tolerance ?? 0.10,
323
+ };
324
+ if (input.check_regression) {
325
+ options.baseline_path = baselinePath;
326
+ }
327
+ if (input.save_baseline) {
328
+ options.save_baseline = true;
329
+ options.baseline_path = baselinePath;
330
+ }
331
+ log(`decibel-bench: Running ${kind} benchmark suite ${input.suite_id}`);
332
+ // Try to discover benchmarks from project
333
+ // Look for common locations: bench/, benchmarks/, __bench__/
334
+ const benchDirs = ['bench', 'benchmarks', '__bench__', 'src/bench', 'src/benchmarks'];
335
+ let suitePath = null;
336
+ for (const dir of benchDirs) {
337
+ const candidate = path.join(projectRoot, dir, `${input.suite_id}.ts`);
338
+ if (existsSync(candidate)) {
339
+ suitePath = candidate;
340
+ break;
341
+ }
342
+ const candidateJs = path.join(projectRoot, dir, `${input.suite_id}.js`);
343
+ if (existsSync(candidateJs)) {
344
+ suitePath = candidateJs;
345
+ break;
346
+ }
347
+ }
348
+ // Also check if suite_id is a direct path
349
+ if (!suitePath && existsSync(path.join(projectRoot, input.suite_id))) {
350
+ suitePath = path.join(projectRoot, input.suite_id);
351
+ }
352
+ if (!suitePath) {
353
+ return {
354
+ error: `Benchmark suite not found: ${input.suite_id}`,
355
+ exitCode: 1,
356
+ stderr: `Searched in: ${benchDirs.join(', ')}`,
357
+ };
358
+ }
359
+ // Use Node.js to run the benchmark via dynamic import
360
+ // Generate a runner script that imports and executes
361
+ const runnerScript = `
362
+ const path = require('path');
363
+ const fs = require('fs');
364
+
365
+ async function main() {
366
+ try {
367
+ // Try to import the suite
368
+ const suitePath = ${JSON.stringify(suitePath)};
369
+ const suiteModule = require(suitePath);
370
+
371
+ // Discover benchmarks
372
+ let benchmarks = null;
373
+
374
+ if (typeof suiteModule.benchmarks === 'function') {
375
+ benchmarks = suiteModule.benchmarks();
376
+ } else if (suiteModule.BENCHMARKS) {
377
+ benchmarks = suiteModule.BENCHMARKS;
378
+ } else if (suiteModule.default && typeof suiteModule.default === 'object') {
379
+ benchmarks = suiteModule.default;
380
+ }
381
+
382
+ if (!benchmarks || Object.keys(benchmarks).length === 0) {
383
+ console.log(JSON.stringify({
384
+ status: 'no_benchmarks',
385
+ message: 'No BENCHMARKS export or benchmarks() function found'
386
+ }));
387
+ return;
388
+ }
389
+
390
+ // Run benchmarks
391
+ const kind = ${JSON.stringify(kind)};
392
+ const iterations = ${options.iterations};
393
+ const warmup = ${options.warmup};
394
+ const thresholdNs = ${options.threshold_p99_ns};
395
+
396
+ const results = [];
397
+
398
+ for (const [name, fn] of Object.entries(benchmarks)) {
399
+ // Warmup
400
+ for (let i = 0; i < warmup; i++) {
401
+ const r = fn();
402
+ if (r instanceof Promise) await r;
403
+ }
404
+
405
+ // Measure
406
+ const times = [];
407
+ for (let i = 0; i < iterations; i++) {
408
+ const start = process.hrtime.bigint();
409
+ const r = fn();
410
+ if (r instanceof Promise) await r;
411
+ const end = process.hrtime.bigint();
412
+ times.push(Number(end - start));
413
+ }
414
+
415
+ times.sort((a, b) => a - b);
416
+ const mean = times.reduce((a, b) => a + b, 0) / times.length;
417
+ const stddev = times.length < 2 ? 0 : Math.sqrt(
418
+ times.map(t => Math.pow(t - mean, 2)).reduce((a, b) => a + b, 0) / (times.length - 1)
419
+ );
420
+ const cv = mean > 0 ? stddev / mean : 0;
421
+ const stability = cv < 0.1 ? 'high' : cv < 0.3 ? 'medium' : 'low';
422
+ const p99 = times[Math.floor(times.length * 0.99)];
423
+
424
+ results.push({
425
+ id: name,
426
+ kind,
427
+ p50_ns: times[Math.floor(times.length * 0.50)],
428
+ p95_ns: times[Math.floor(times.length * 0.95)],
429
+ p99_ns: p99,
430
+ max_ns: times[times.length - 1],
431
+ min_ns: times[0],
432
+ mean_ns: Math.round(mean),
433
+ stddev_ns: Math.round(stddev),
434
+ iterations,
435
+ stability,
436
+ threshold_p99_ns: thresholdNs,
437
+ passed: p99 < thresholdNs,
438
+ });
439
+ }
440
+
441
+ // Check baseline for regressions
442
+ const baselinePath = ${input.check_regression ? JSON.stringify(baselinePath) : 'null'};
443
+ const regressionTolerance = ${options.regression_tolerance};
444
+ let baseline = null;
445
+ const regressions = [];
446
+
447
+ if (baselinePath && fs.existsSync(baselinePath)) {
448
+ try {
449
+ baseline = JSON.parse(fs.readFileSync(baselinePath, 'utf-8'));
450
+ } catch {}
451
+ }
452
+
453
+ if (baseline && baseline.results) {
454
+ for (const result of results) {
455
+ if (baseline.results[result.id]) {
456
+ const base = baseline.results[result.id];
457
+ const deltaPct = (result.p99_ns - base.p99_ns) / base.p99_ns;
458
+ regressions.push({
459
+ id: result.id,
460
+ baseline_p99_ns: base.p99_ns,
461
+ current_p99_ns: result.p99_ns,
462
+ delta_pct: deltaPct,
463
+ regressed: deltaPct > regressionTolerance,
464
+ tolerance_pct: regressionTolerance
465
+ });
466
+ }
467
+ }
468
+ }
469
+
470
+ const hasRegressions = regressions.some(r => r.regressed);
471
+ const allPassed = results.every(r => r.passed);
472
+ const passRate = results.filter(r => r.passed).length / results.length;
473
+ const verdict = hasRegressions ? 'SLOW' : allPassed ? 'FAST' : passRate >= 0.8 ? 'OK' : 'SLOW';
474
+
475
+ // Platform info
476
+ const os = require('os');
477
+ const { execSync } = require('child_process');
478
+ let gitSha, gitBranch;
479
+ try {
480
+ gitSha = execSync('git rev-parse HEAD', { encoding: 'utf-8', stdio: ['pipe', 'pipe', 'pipe'] }).trim();
481
+ gitBranch = execSync('git rev-parse --abbrev-ref HEAD', { encoding: 'utf-8', stdio: ['pipe', 'pipe', 'pipe'] }).trim();
482
+ } catch {}
483
+
484
+ const platform = {
485
+ git_sha: gitSha,
486
+ git_branch: gitBranch,
487
+ node_version: process.version,
488
+ os_arch: os.platform() + '-' + os.arch(),
489
+ cpu_model: os.cpus()[0]?.model || 'unknown',
490
+ timestamp: new Date().toISOString()
491
+ };
492
+
493
+ const report = {
494
+ suite_id: ${JSON.stringify(input.suite_id)},
495
+ kind,
496
+ results,
497
+ regressions,
498
+ verdict,
499
+ platform,
500
+ baseline_used: baseline ? baselinePath : undefined,
501
+ has_regressions: hasRegressions,
502
+ timestamp: new Date().toISOString()
503
+ };
504
+
505
+ // Save baseline if requested
506
+ const saveBaseline = ${!!input.save_baseline};
507
+ if (saveBaseline) {
508
+ const baselineDir = ${JSON.stringify(baselineDir)};
509
+ const baselineFile = ${JSON.stringify(baselinePath)};
510
+ fs.mkdirSync(baselineDir, { recursive: true });
511
+ const newBaseline = {
512
+ suite_id: ${JSON.stringify(input.suite_id)},
513
+ platform,
514
+ results: Object.fromEntries(
515
+ results.map(r => [r.id, { p99_ns: r.p99_ns, p95_ns: r.p95_ns, mean_ns: r.mean_ns }])
516
+ ),
517
+ created_at: new Date().toISOString()
518
+ };
519
+ fs.writeFileSync(baselineFile, JSON.stringify(newBaseline, null, 2));
520
+ }
521
+
522
+ console.log(JSON.stringify({
523
+ status: hasRegressions ? 'regression_detected' : 'success',
524
+ report
525
+ }));
526
+
527
+ } catch (err) {
528
+ console.log(JSON.stringify({ error: err.message || String(err) }));
529
+ process.exit(1);
530
+ }
531
+ }
532
+
533
+ main();
534
+ `;
535
+ const result = await new Promise((resolve) => {
536
+ const proc = spawn('node', ['-e', runnerScript], {
537
+ cwd: projectRoot,
538
+ env: { ...process.env },
539
+ });
540
+ let stdout = '';
541
+ let stderr = '';
542
+ proc.stdout.on('data', (data) => {
543
+ stdout += data.toString();
544
+ });
545
+ proc.stderr.on('data', (data) => {
546
+ stderr += data.toString();
547
+ });
548
+ proc.on('error', (err) => {
549
+ resolve({ stdout: '', stderr: err.message, exitCode: -1 });
550
+ });
551
+ proc.on('close', (code) => {
552
+ resolve({ stdout, stderr, exitCode: code ?? -1 });
553
+ });
554
+ });
555
+ if (result.exitCode !== 0 && !result.stdout) {
556
+ return {
557
+ error: `Benchmark failed with exit code ${result.exitCode}`,
558
+ exitCode: result.exitCode,
559
+ stderr: result.stderr,
560
+ };
561
+ }
562
+ // Parse output
563
+ let parsed;
564
+ try {
565
+ parsed = JSON.parse(result.stdout.trim());
566
+ }
567
+ catch {
568
+ return {
569
+ error: 'Failed to parse benchmark output',
570
+ exitCode: 1,
571
+ stderr: `Invalid JSON: ${result.stdout}`,
572
+ };
573
+ }
574
+ if (parsed.error) {
575
+ return {
576
+ error: parsed.error,
577
+ exitCode: 1,
578
+ stderr: parsed.error,
579
+ };
580
+ }
581
+ if (parsed.status === 'no_benchmarks') {
582
+ return {
583
+ suite_id: input.suite_id,
584
+ status: 'no_benchmarks',
585
+ message: parsed.message || 'No benchmarks found',
586
+ };
587
+ }
588
+ if (!parsed.report) {
589
+ return {
590
+ error: 'No report in benchmark output',
591
+ exitCode: 1,
592
+ stderr: 'Unexpected output format',
593
+ };
594
+ }
595
+ // Format output
596
+ const outputFormat = input.output_format || 'json';
597
+ let formatted;
598
+ if (outputFormat === 'table') {
599
+ formatted = formatTable(parsed.report);
600
+ }
601
+ else if (outputFormat === 'markdown') {
602
+ formatted = formatMarkdown(parsed.report);
603
+ }
604
+ return {
605
+ suite_id: input.suite_id,
606
+ status: parsed.status,
607
+ report: parsed.report,
608
+ formatted,
609
+ };
610
+ }
611
+ catch (err) {
612
+ const message = err instanceof Error ? err.message : String(err);
613
+ return {
614
+ error: message,
615
+ exitCode: 1,
616
+ stderr: message,
617
+ };
618
+ }
619
+ finally {
620
+ recordRequestEnd(callerRole);
621
+ }
622
+ }
623
+ // ============================================================================
624
+ // decibel_bench_compare: Compare two baselines
625
+ // ============================================================================
626
+ /**
627
+ * Compare two benchmark baselines side-by-side
628
+ */
629
+ export async function decibelBenchCompare(input) {
630
+ const callerRole = input.caller_role || 'human';
631
+ try {
632
+ const { projectRoot } = await buildBenchContext(input.project_id, callerRole, 'decibel_bench_compare', input.agent_id);
633
+ // Resolve baseline paths
634
+ const resolveBaselinePath = (p) => {
635
+ if (path.isAbsolute(p))
636
+ return p;
637
+ // Check in .decibel/benchmarks
638
+ const benchPath = path.join(projectRoot, '.decibel', 'benchmarks', p);
639
+ if (existsSync(benchPath))
640
+ return benchPath;
641
+ if (existsSync(benchPath + '.json'))
642
+ return benchPath + '.json';
643
+ if (existsSync(benchPath + '-baseline.json'))
644
+ return benchPath + '-baseline.json';
645
+ // Check direct path
646
+ const directPath = path.join(projectRoot, p);
647
+ if (existsSync(directPath))
648
+ return directPath;
649
+ return p;
650
+ };
651
+ const pathA = resolveBaselinePath(input.baseline_a);
652
+ const pathB = resolveBaselinePath(input.baseline_b);
653
+ // Load baselines
654
+ let baselineA;
655
+ let baselineB;
656
+ try {
657
+ const contentA = await fs.readFile(pathA, 'utf-8');
658
+ baselineA = JSON.parse(contentA);
659
+ }
660
+ catch (err) {
661
+ return {
662
+ error: `Failed to load baseline A: ${pathA}`,
663
+ exitCode: 1,
664
+ };
665
+ }
666
+ try {
667
+ const contentB = await fs.readFile(pathB, 'utf-8');
668
+ baselineB = JSON.parse(contentB);
669
+ }
670
+ catch (err) {
671
+ return {
672
+ error: `Failed to load baseline B: ${pathB}`,
673
+ exitCode: 1,
674
+ };
675
+ }
676
+ // Compare
677
+ const deltas = [];
678
+ const allIds = new Set([
679
+ ...Object.keys(baselineA.results || {}),
680
+ ...Object.keys(baselineB.results || {}),
681
+ ]);
682
+ for (const id of allIds) {
683
+ const a = baselineA.results?.[id];
684
+ const b = baselineB.results?.[id];
685
+ if (!a || !b)
686
+ continue; // Skip if not in both
687
+ const aPns = a.p99_ns;
688
+ const bPns = b.p99_ns;
689
+ const deltaNs = aPns - bPns;
690
+ const deltaPct = bPns !== 0 ? deltaNs / bPns : 0;
691
+ // Winner: lower p99 is better (faster)
692
+ // a_wins if a is faster (lower), b_wins if b is faster
693
+ const tolerance = 0.02; // 2% tolerance for tie
694
+ let winner;
695
+ if (Math.abs(deltaPct) < tolerance) {
696
+ winner = 'tie';
697
+ }
698
+ else if (aPns < bPns) {
699
+ winner = 'a';
700
+ }
701
+ else {
702
+ winner = 'b';
703
+ }
704
+ deltas.push({
705
+ id,
706
+ a_p99_ns: aPns,
707
+ b_p99_ns: bPns,
708
+ delta_ns: deltaNs,
709
+ delta_pct: deltaPct,
710
+ winner,
711
+ });
712
+ }
713
+ // Summary
714
+ const aWins = deltas.filter(d => d.winner === 'a').length;
715
+ const bWins = deltas.filter(d => d.winner === 'b').length;
716
+ const ties = deltas.filter(d => d.winner === 'tie').length;
717
+ const avgDeltaPct = deltas.length > 0
718
+ ? deltas.reduce((sum, d) => sum + d.delta_pct, 0) / deltas.length
719
+ : 0;
720
+ let overallWinner;
721
+ if (aWins > bWins) {
722
+ overallWinner = 'a';
723
+ }
724
+ else if (bWins > aWins) {
725
+ overallWinner = 'b';
726
+ }
727
+ else {
728
+ overallWinner = 'tie';
729
+ }
730
+ const output = {
731
+ status: 'success',
732
+ baseline_a: pathA,
733
+ baseline_b: pathB,
734
+ deltas,
735
+ summary: {
736
+ a_wins: aWins,
737
+ b_wins: bWins,
738
+ ties,
739
+ overall_winner: overallWinner,
740
+ avg_delta_pct: avgDeltaPct,
741
+ },
742
+ };
743
+ // Format output
744
+ if (input.output_format === 'table' || input.output_format === 'markdown') {
745
+ output.formatted = formatCompareOutput(output, input.output_format);
746
+ }
747
+ return output;
748
+ }
749
+ catch (err) {
750
+ const message = err instanceof Error ? err.message : String(err);
751
+ return {
752
+ error: message,
753
+ exitCode: 1,
754
+ };
755
+ }
756
+ finally {
757
+ recordRequestEnd(callerRole);
758
+ }
759
+ }
760
+ // ============================================================================
761
+ // Compare Formatting
762
+ // ============================================================================
763
+ function formatNsForCompare(ns) {
764
+ if (ns >= 1_000_000) {
765
+ return `${(ns / 1_000_000).toFixed(1)}ms`;
766
+ }
767
+ else if (ns >= 1000) {
768
+ return `${(ns / 1000).toFixed(1)}μs`;
769
+ }
770
+ else {
771
+ return `${ns}ns`;
772
+ }
773
+ }
774
+ function formatCompareOutput(output, format) {
775
+ const lines = [];
776
+ if (format === 'markdown') {
777
+ lines.push('# Benchmark Comparison');
778
+ lines.push('');
779
+ lines.push(`**Baseline A:** ${output.baseline_a}`);
780
+ lines.push(`**Baseline B:** ${output.baseline_b}`);
781
+ lines.push('');
782
+ lines.push('## Results');
783
+ lines.push('');
784
+ lines.push('| Benchmark | A (p99) | B (p99) | Delta | Winner |');
785
+ lines.push('|-----------|---------|---------|-------|--------|');
786
+ for (const d of output.deltas) {
787
+ const deltaSign = d.delta_pct >= 0 ? '+' : '';
788
+ const winnerSymbol = d.winner === 'a' ? '← A' : d.winner === 'b' ? 'B →' : '=';
789
+ lines.push(`| ${d.id} | ${formatNsForCompare(d.a_p99_ns)} | ${formatNsForCompare(d.b_p99_ns)} | ${deltaSign}${(d.delta_pct * 100).toFixed(1)}% | ${winnerSymbol} |`);
790
+ }
791
+ lines.push('');
792
+ lines.push('## Summary');
793
+ lines.push('');
794
+ lines.push(`- **A wins:** ${output.summary.a_wins}`);
795
+ lines.push(`- **B wins:** ${output.summary.b_wins}`);
796
+ lines.push(`- **Ties:** ${output.summary.ties}`);
797
+ lines.push(`- **Overall:** ${output.summary.overall_winner === 'a' ? 'A is faster' : output.summary.overall_winner === 'b' ? 'B is faster' : 'Tie'}`);
798
+ }
799
+ else {
800
+ // Table format
801
+ lines.push('Benchmark Comparison');
802
+ lines.push('='.repeat(60));
803
+ lines.push(`A: ${output.baseline_a}`);
804
+ lines.push(`B: ${output.baseline_b}`);
805
+ lines.push('');
806
+ lines.push('Benchmark A (p99) B (p99) Delta Winner');
807
+ lines.push('─'.repeat(60));
808
+ for (const d of output.deltas) {
809
+ const name = d.id.padEnd(18).slice(0, 18);
810
+ const aPns = formatNsForCompare(d.a_p99_ns).padStart(9);
811
+ const bPns = formatNsForCompare(d.b_p99_ns).padStart(9);
812
+ const deltaSign = d.delta_pct >= 0 ? '+' : '';
813
+ const delta = `${deltaSign}${(d.delta_pct * 100).toFixed(1)}%`.padStart(7);
814
+ const winner = d.winner === 'a' ? ' ← A' : d.winner === 'b' ? ' B →' : ' =';
815
+ lines.push(`${name} ${aPns} ${bPns} ${delta} ${winner}`);
816
+ }
817
+ lines.push('');
818
+ lines.push('Summary:');
819
+ lines.push(` A wins: ${output.summary.a_wins} | B wins: ${output.summary.b_wins} | Ties: ${output.summary.ties}`);
820
+ const overallText = output.summary.overall_winner === 'a' ? 'A is faster' :
821
+ output.summary.overall_winner === 'b' ? 'B is faster' : 'Tie';
822
+ lines.push(` Overall: ${overallText}`);
823
+ }
824
+ return lines.join('\n');
825
+ }
826
+ //# sourceMappingURL=bench.js.map