@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,669 @@
1
+ import fs from 'fs/promises';
2
+ import fsSync from 'fs';
3
+ import path from 'path';
4
+ import os from 'os';
5
+ import { log } from '../config.js';
6
+ import { resolveProjectPaths } from '../projectRegistry.js';
7
+ // ============================================================================
8
+ // Path Resolution
9
+ // ============================================================================
10
+ /**
11
+ * Find the .decibel root directory by walking up from the start path
12
+ */
13
+ export function findDecibelRoot(start) {
14
+ const startPath = start || process.env.DECIBEL_PROJECT_ROOT || process.cwd();
15
+ let current = path.resolve(startPath);
16
+ while (true) {
17
+ const candidate = path.join(current, '.decibel');
18
+ if (fsSync.existsSync(candidate) && fsSync.statSync(candidate).isDirectory()) {
19
+ return candidate;
20
+ }
21
+ const parent = path.dirname(current);
22
+ if (parent === current) {
23
+ return undefined;
24
+ }
25
+ current = parent;
26
+ }
27
+ }
28
+ /**
29
+ * Get the project name from the .decibel root's parent directory
30
+ */
31
+ export function getProjectNameFromRoot(decibelRoot) {
32
+ const projectDir = path.dirname(decibelRoot);
33
+ return path.basename(projectDir);
34
+ }
35
+ /**
36
+ * Get global data root (DECIBEL_MCP_ROOT or ~/.decibel)
37
+ */
38
+ export function getGlobalRoot() {
39
+ return process.env.DECIBEL_MCP_ROOT || path.join(os.homedir(), '.decibel');
40
+ }
41
+ // ============================================================================
42
+ // YAML Parsing
43
+ // ============================================================================
44
+ /**
45
+ * Parse simple YAML content (single-level key-value with array support)
46
+ * This is a lightweight parser for our specific schema needs
47
+ */
48
+ function parseSimpleYaml(content) {
49
+ const result = {};
50
+ const lines = content.split('\n');
51
+ for (const line of lines) {
52
+ const trimmed = line.trim();
53
+ // Skip empty lines and comments
54
+ if (!trimmed || trimmed.startsWith('#'))
55
+ continue;
56
+ const colonIndex = trimmed.indexOf(':');
57
+ if (colonIndex <= 0)
58
+ continue;
59
+ const key = trimmed.slice(0, colonIndex).trim();
60
+ let value = trimmed.slice(colonIndex + 1).trim();
61
+ // Handle arrays: [item1, item2]
62
+ if (value.startsWith('[') && value.endsWith(']')) {
63
+ const inner = value.slice(1, -1);
64
+ result[key] = inner
65
+ .split(',')
66
+ .map(s => s.trim())
67
+ .filter(s => s.length > 0);
68
+ }
69
+ else if (value === '' || value === '~' || value === 'null') {
70
+ result[key] = undefined;
71
+ }
72
+ else if (value === 'true') {
73
+ result[key] = true;
74
+ }
75
+ else if (value === 'false') {
76
+ result[key] = false;
77
+ }
78
+ else {
79
+ // Remove quotes if present
80
+ if ((value.startsWith('"') && value.endsWith('"')) ||
81
+ (value.startsWith("'") && value.endsWith("'"))) {
82
+ value = value.slice(1, -1);
83
+ }
84
+ result[key] = value;
85
+ }
86
+ }
87
+ return result;
88
+ }
89
+ // ============================================================================
90
+ // Data Loaders
91
+ // ============================================================================
92
+ /**
93
+ * Load all issues from the .decibel/sentinel/issues directory
94
+ */
95
+ export async function loadIssues(decibelRoot) {
96
+ const issuesDir = path.join(decibelRoot, 'sentinel', 'issues');
97
+ const issues = [];
98
+ try {
99
+ const files = await fs.readdir(issuesDir);
100
+ for (const file of files) {
101
+ if (!file.endsWith('.yml') && !file.endsWith('.yaml'))
102
+ continue;
103
+ const filePath = path.join(issuesDir, file);
104
+ try {
105
+ const content = await fs.readFile(filePath, 'utf-8');
106
+ const parsed = parseSimpleYaml(content);
107
+ const issue = {
108
+ id: parsed.id || file.replace(/\.ya?ml$/, ''),
109
+ title: parsed.title || '',
110
+ project: parsed.project,
111
+ status: parsed.status || 'open',
112
+ priority: parsed.priority || 'medium',
113
+ epic_id: parsed.epic_id,
114
+ tags: parsed.tags,
115
+ created_at: parsed.created_at,
116
+ updated_at: parsed.updated_at,
117
+ _file: filePath,
118
+ };
119
+ issues.push(issue);
120
+ }
121
+ catch (err) {
122
+ log(`Data Inspector: Failed to parse issue file ${file}: ${err}`);
123
+ }
124
+ }
125
+ }
126
+ catch {
127
+ // Directory doesn't exist, return empty array
128
+ }
129
+ return issues;
130
+ }
131
+ /**
132
+ * Load all epics from the .decibel/sentinel/epics directory
133
+ */
134
+ export async function loadEpics(decibelRoot) {
135
+ const epicsDir = path.join(decibelRoot, 'sentinel', 'epics');
136
+ const epics = [];
137
+ try {
138
+ const files = await fs.readdir(epicsDir);
139
+ for (const file of files) {
140
+ if (!file.endsWith('.yml') && !file.endsWith('.yaml'))
141
+ continue;
142
+ const filePath = path.join(epicsDir, file);
143
+ try {
144
+ const content = await fs.readFile(filePath, 'utf-8');
145
+ const parsed = parseSimpleYaml(content);
146
+ const epic = {
147
+ id: parsed.id || file.replace(/\.ya?ml$/, ''),
148
+ title: parsed.title || '',
149
+ project: parsed.project,
150
+ status: parsed.status || 'open',
151
+ owner: parsed.owner,
152
+ tags: parsed.tags,
153
+ created_at: parsed.created_at,
154
+ updated_at: parsed.updated_at,
155
+ _file: filePath,
156
+ };
157
+ epics.push(epic);
158
+ }
159
+ catch (err) {
160
+ log(`Data Inspector: Failed to parse epic file ${file}: ${err}`);
161
+ }
162
+ }
163
+ }
164
+ catch {
165
+ // Directory doesn't exist, return empty array
166
+ }
167
+ return epics;
168
+ }
169
+ /**
170
+ * Load all ADRs from the .decibel/architect/adrs directory
171
+ */
172
+ export async function loadADRs(decibelRoot) {
173
+ const adrsDir = path.join(decibelRoot, 'architect', 'adrs');
174
+ const adrs = [];
175
+ try {
176
+ const files = await fs.readdir(adrsDir);
177
+ for (const file of files) {
178
+ if (!file.endsWith('.yml') && !file.endsWith('.yaml'))
179
+ continue;
180
+ const filePath = path.join(adrsDir, file);
181
+ try {
182
+ const content = await fs.readFile(filePath, 'utf-8');
183
+ const parsed = parseSimpleYaml(content);
184
+ const adr = {
185
+ id: parsed.id || file.replace(/\.ya?ml$/, ''),
186
+ scope: parsed.scope,
187
+ project: parsed.project,
188
+ title: parsed.title || '',
189
+ status: parsed.status || 'proposed',
190
+ related_issues: parsed.related_issues,
191
+ related_epics: parsed.related_epics,
192
+ created_at: parsed.created_at,
193
+ updated_at: parsed.updated_at,
194
+ _file: filePath,
195
+ };
196
+ adrs.push(adr);
197
+ }
198
+ catch (err) {
199
+ log(`Data Inspector: Failed to parse ADR file ${file}: ${err}`);
200
+ }
201
+ }
202
+ }
203
+ catch {
204
+ // Directory doesn't exist, return empty array
205
+ }
206
+ return adrs;
207
+ }
208
+ /**
209
+ * Load all data into a DataIndex
210
+ */
211
+ export async function loadDataIndex(decibelRoot) {
212
+ const [issues, epics, adrs] = await Promise.all([
213
+ loadIssues(decibelRoot),
214
+ loadEpics(decibelRoot),
215
+ loadADRs(decibelRoot),
216
+ ]);
217
+ return {
218
+ issues,
219
+ epics,
220
+ adrs,
221
+ decibelRoot,
222
+ projectName: getProjectNameFromRoot(decibelRoot),
223
+ };
224
+ }
225
+ // ============================================================================
226
+ // Validation
227
+ // ============================================================================
228
+ const VALID_ISSUE_STATUSES = ['open', 'in_progress', 'done', 'blocked'];
229
+ const VALID_PRIORITIES = ['low', 'medium', 'high'];
230
+ const VALID_EPIC_STATUSES = ['open', 'in_progress', 'done', 'blocked'];
231
+ const VALID_ADR_STATUSES = ['proposed', 'accepted', 'superseded', 'deprecated'];
232
+ const VALID_ADR_SCOPES = ['project', 'global'];
233
+ /**
234
+ * Validate all data and return validation errors
235
+ */
236
+ export function validateSchema(issues, epics, adrs) {
237
+ const errors = [];
238
+ // Validate issues
239
+ for (const issue of issues) {
240
+ if (!issue.id) {
241
+ errors.push({
242
+ severity: 'error',
243
+ type: 'issue',
244
+ id: issue._file || 'unknown',
245
+ file: issue._file,
246
+ field: 'id',
247
+ message: 'Missing required field: id',
248
+ });
249
+ }
250
+ if (!issue.title) {
251
+ errors.push({
252
+ severity: 'warn',
253
+ type: 'issue',
254
+ id: issue.id || issue._file || 'unknown',
255
+ file: issue._file,
256
+ field: 'title',
257
+ message: 'Missing field: title',
258
+ });
259
+ }
260
+ if (issue.status && !VALID_ISSUE_STATUSES.includes(issue.status)) {
261
+ errors.push({
262
+ severity: 'warn',
263
+ type: 'issue',
264
+ id: issue.id,
265
+ file: issue._file,
266
+ field: 'status',
267
+ message: `Invalid status '${issue.status}'. Must be one of: ${VALID_ISSUE_STATUSES.join(', ')}`,
268
+ });
269
+ }
270
+ if (issue.priority && !VALID_PRIORITIES.includes(issue.priority)) {
271
+ errors.push({
272
+ severity: 'warn',
273
+ type: 'issue',
274
+ id: issue.id,
275
+ file: issue._file,
276
+ field: 'priority',
277
+ message: `Invalid priority '${issue.priority}'. Must be one of: ${VALID_PRIORITIES.join(', ')}`,
278
+ });
279
+ }
280
+ }
281
+ // Validate epics
282
+ for (const epic of epics) {
283
+ if (!epic.id) {
284
+ errors.push({
285
+ severity: 'error',
286
+ type: 'epic',
287
+ id: epic._file || 'unknown',
288
+ file: epic._file,
289
+ field: 'id',
290
+ message: 'Missing required field: id',
291
+ });
292
+ }
293
+ if (!epic.title) {
294
+ errors.push({
295
+ severity: 'warn',
296
+ type: 'epic',
297
+ id: epic.id || epic._file || 'unknown',
298
+ file: epic._file,
299
+ field: 'title',
300
+ message: 'Missing field: title',
301
+ });
302
+ }
303
+ if (epic.status && !VALID_EPIC_STATUSES.includes(epic.status)) {
304
+ errors.push({
305
+ severity: 'warn',
306
+ type: 'epic',
307
+ id: epic.id,
308
+ file: epic._file,
309
+ field: 'status',
310
+ message: `Invalid status '${epic.status}'. Must be one of: ${VALID_EPIC_STATUSES.join(', ')}`,
311
+ });
312
+ }
313
+ }
314
+ // Validate ADRs
315
+ for (const adr of adrs) {
316
+ if (!adr.id) {
317
+ errors.push({
318
+ severity: 'error',
319
+ type: 'adr',
320
+ id: adr._file || 'unknown',
321
+ file: adr._file,
322
+ field: 'id',
323
+ message: 'Missing required field: id',
324
+ });
325
+ }
326
+ if (!adr.title) {
327
+ errors.push({
328
+ severity: 'warn',
329
+ type: 'adr',
330
+ id: adr.id || adr._file || 'unknown',
331
+ file: adr._file,
332
+ field: 'title',
333
+ message: 'Missing field: title',
334
+ });
335
+ }
336
+ if (adr.status && !VALID_ADR_STATUSES.includes(adr.status)) {
337
+ errors.push({
338
+ severity: 'warn',
339
+ type: 'adr',
340
+ id: adr.id,
341
+ file: adr._file,
342
+ field: 'status',
343
+ message: `Invalid status '${adr.status}'. Must be one of: ${VALID_ADR_STATUSES.join(', ')}`,
344
+ });
345
+ }
346
+ if (adr.scope && !VALID_ADR_SCOPES.includes(adr.scope)) {
347
+ errors.push({
348
+ severity: 'warn',
349
+ type: 'adr',
350
+ id: adr.id,
351
+ file: adr._file,
352
+ field: 'scope',
353
+ message: `Invalid scope '${adr.scope}'. Must be one of: ${VALID_ADR_SCOPES.join(', ')}`,
354
+ });
355
+ }
356
+ }
357
+ return errors;
358
+ }
359
+ // ============================================================================
360
+ // Orphan Detection
361
+ // ============================================================================
362
+ /**
363
+ * Find orphaned records (broken references)
364
+ */
365
+ export function findOrphans(issues, epics, adrs) {
366
+ const issueIds = new Set(issues.map(i => i.id));
367
+ const epicIds = new Set(epics.map(e => e.id));
368
+ // Find epics with no issues
369
+ const issuesByEpic = new Map();
370
+ for (const issue of issues) {
371
+ if (issue.epic_id) {
372
+ issuesByEpic.set(issue.epic_id, (issuesByEpic.get(issue.epic_id) || 0) + 1);
373
+ }
374
+ }
375
+ const epicsWithNoIssues = epics
376
+ .filter(epic => !issuesByEpic.has(epic.id))
377
+ .map(epic => ({ id: epic.id, title: epic.title }));
378
+ // Find issues with missing epics
379
+ const issuesWithMissingEpic = issues
380
+ .filter(issue => issue.epic_id && !epicIds.has(issue.epic_id))
381
+ .map(issue => ({
382
+ id: issue.id,
383
+ title: issue.title,
384
+ epic_id: issue.epic_id,
385
+ }));
386
+ // Find ADRs with missing issues
387
+ const adrsWithMissingIssues = [];
388
+ for (const adr of adrs) {
389
+ if (adr.related_issues && adr.related_issues.length > 0) {
390
+ const missing = adr.related_issues.filter(issueId => !issueIds.has(issueId));
391
+ if (missing.length > 0) {
392
+ adrsWithMissingIssues.push({ id: adr.id, title: adr.title, missing });
393
+ }
394
+ }
395
+ }
396
+ // Find ADRs with missing epics
397
+ const adrsWithMissingEpics = [];
398
+ for (const adr of adrs) {
399
+ if (adr.related_epics && adr.related_epics.length > 0) {
400
+ const missing = adr.related_epics.filter(epicId => !epicIds.has(epicId));
401
+ if (missing.length > 0) {
402
+ adrsWithMissingEpics.push({ id: adr.id, title: adr.title, missing });
403
+ }
404
+ }
405
+ }
406
+ return {
407
+ epicsWithNoIssues,
408
+ issuesWithMissingEpic,
409
+ adrsWithMissingIssues,
410
+ adrsWithMissingEpics,
411
+ };
412
+ }
413
+ // ============================================================================
414
+ // Stale Detection
415
+ // ============================================================================
416
+ /**
417
+ * Parse an ISO date string safely
418
+ */
419
+ function parseDate(dateStr) {
420
+ if (!dateStr)
421
+ return null;
422
+ try {
423
+ const date = new Date(dateStr);
424
+ return isNaN(date.getTime()) ? null : date;
425
+ }
426
+ catch {
427
+ return null;
428
+ }
429
+ }
430
+ /**
431
+ * Find stale records (not updated in N days)
432
+ */
433
+ export function findStale(issues, epics, adrs, days = 21) {
434
+ const now = Date.now();
435
+ const threshold = days * 24 * 60 * 60 * 1000; // days in milliseconds
436
+ const isStale = (dateStr) => {
437
+ const date = parseDate(dateStr);
438
+ if (!date)
439
+ return false; // Can't determine staleness without a date
440
+ return (now - date.getTime()) > threshold;
441
+ };
442
+ // Filter stale issues (only open/in_progress ones - done issues should be stale)
443
+ const staleIssues = issues
444
+ .filter(issue => (issue.status === 'open' || issue.status === 'in_progress') &&
445
+ isStale(issue.updated_at || issue.created_at))
446
+ .map(issue => ({
447
+ id: issue.id,
448
+ title: issue.title,
449
+ updated_at: issue.updated_at || issue.created_at || 'unknown',
450
+ }));
451
+ // Filter stale epics (only open/in_progress ones)
452
+ const staleEpics = epics
453
+ .filter(epic => (epic.status === 'open' || epic.status === 'in_progress') &&
454
+ isStale(epic.updated_at || epic.created_at))
455
+ .map(epic => ({
456
+ id: epic.id,
457
+ title: epic.title,
458
+ updated_at: epic.updated_at || epic.created_at || 'unknown',
459
+ }));
460
+ // Filter stale ADRs (only proposed/accepted - not superseded/deprecated)
461
+ const staleADRs = adrs
462
+ .filter(adr => (adr.status === 'proposed' || adr.status === 'accepted') &&
463
+ isStale(adr.updated_at || adr.created_at))
464
+ .map(adr => ({
465
+ id: adr.id,
466
+ title: adr.title,
467
+ updated_at: adr.updated_at || adr.created_at || 'unknown',
468
+ }));
469
+ return {
470
+ issues: staleIssues,
471
+ epics: staleEpics,
472
+ adrs: staleADRs,
473
+ };
474
+ }
475
+ // ============================================================================
476
+ // Summary Generation
477
+ // ============================================================================
478
+ /**
479
+ * Generate a summary of the data
480
+ */
481
+ export function generateSummary(issues, epics, adrs) {
482
+ return {
483
+ issues: {
484
+ total: issues.length,
485
+ open: issues.filter(i => i.status === 'open').length,
486
+ in_progress: issues.filter(i => i.status === 'in_progress').length,
487
+ done: issues.filter(i => i.status === 'done').length,
488
+ blocked: issues.filter(i => i.status === 'blocked').length,
489
+ },
490
+ epics: {
491
+ total: epics.length,
492
+ open: epics.filter(e => e.status === 'open').length,
493
+ in_progress: epics.filter(e => e.status === 'in_progress').length,
494
+ done: epics.filter(e => e.status === 'done').length,
495
+ blocked: epics.filter(e => e.status === 'blocked').length,
496
+ },
497
+ adrs: {
498
+ total: adrs.length,
499
+ proposed: adrs.filter(a => a.status === 'proposed').length,
500
+ accepted: adrs.filter(a => a.status === 'accepted').length,
501
+ superseded: adrs.filter(a => a.status === 'superseded').length,
502
+ deprecated: adrs.filter(a => a.status === 'deprecated').length,
503
+ },
504
+ };
505
+ }
506
+ // ============================================================================
507
+ // Main Scan Function
508
+ // ============================================================================
509
+ /**
510
+ * Execute the data scan
511
+ */
512
+ export async function scanData(input) {
513
+ const { projectId, scope, validate = false, flag = [], days = 21 } = input;
514
+ // For 'runtime' scope, just return a placeholder (not implemented yet)
515
+ if (scope === 'runtime') {
516
+ return {
517
+ scope,
518
+ projectName: 'unknown',
519
+ error: 'Runtime scan not yet implemented. Use scope "data" or "all".',
520
+ };
521
+ }
522
+ // Find .decibel root - use projectId if provided, otherwise walk up from cwd
523
+ let decibelRoot;
524
+ let projectName;
525
+ if (projectId) {
526
+ try {
527
+ const resolved = resolveProjectPaths(projectId);
528
+ decibelRoot = resolved.decibelPath;
529
+ projectName = resolved.id;
530
+ }
531
+ catch (err) {
532
+ return {
533
+ scope,
534
+ projectName: projectId,
535
+ error: `Failed to resolve project "${projectId}": ${err instanceof Error ? err.message : String(err)}`,
536
+ };
537
+ }
538
+ }
539
+ else {
540
+ decibelRoot = findDecibelRoot();
541
+ if (!decibelRoot) {
542
+ return {
543
+ scope,
544
+ projectName: 'unknown',
545
+ error: `No .decibel directory found above ${process.cwd()}. Data inspector cannot run.`,
546
+ };
547
+ }
548
+ projectName = getProjectNameFromRoot(decibelRoot);
549
+ }
550
+ // Load all data
551
+ const { issues, epics, adrs } = await loadDataIndex(decibelRoot);
552
+ // Build output
553
+ const output = {
554
+ scope,
555
+ projectName,
556
+ decibelRoot,
557
+ summary: generateSummary(issues, epics, adrs),
558
+ };
559
+ // Run validation if requested
560
+ if (validate || flag.includes('invalid')) {
561
+ output.validation = validateSchema(issues, epics, adrs);
562
+ }
563
+ // Run orphan detection if flagged
564
+ if (flag.includes('orphans')) {
565
+ output.orphans = findOrphans(issues, epics, adrs);
566
+ }
567
+ // Run stale detection if flagged
568
+ if (flag.includes('stale')) {
569
+ output.stale = findStale(issues, epics, adrs, days);
570
+ }
571
+ return output;
572
+ }
573
+ // ============================================================================
574
+ // Output Formatting
575
+ // ============================================================================
576
+ /**
577
+ * Format the scan output as a human-readable string
578
+ */
579
+ export function formatScanOutput(output) {
580
+ const lines = [];
581
+ lines.push('SENTINEL DATA INSPECTOR');
582
+ lines.push(` Project: ${output.projectName}`);
583
+ if (output.decibelRoot) {
584
+ lines.push(` .decibel root: ${output.decibelRoot}`);
585
+ }
586
+ if (output.error) {
587
+ lines.push('');
588
+ lines.push('ERROR');
589
+ lines.push(` ${output.error}`);
590
+ return lines.join('\n');
591
+ }
592
+ if (output.summary) {
593
+ lines.push('');
594
+ lines.push('SUMMARY');
595
+ const { issues, epics, adrs } = output.summary;
596
+ const issueBreakdown = [
597
+ `open: ${issues.open}`,
598
+ `in_progress: ${issues.in_progress}`,
599
+ `done: ${issues.done}`,
600
+ `blocked: ${issues.blocked}`,
601
+ ].filter(s => !s.includes(': 0')).join(', ');
602
+ lines.push(` Issues: ${issues.total}${issueBreakdown ? ` (${issueBreakdown})` : ''}`);
603
+ const epicBreakdown = [
604
+ `open: ${epics.open}`,
605
+ `in_progress: ${epics.in_progress}`,
606
+ `done: ${epics.done}`,
607
+ `blocked: ${epics.blocked}`,
608
+ ].filter(s => !s.includes(': 0')).join(', ');
609
+ lines.push(` Epics: ${epics.total}${epicBreakdown ? ` (${epicBreakdown})` : ''}`);
610
+ const adrBreakdown = [
611
+ `proposed: ${adrs.proposed}`,
612
+ `accepted: ${adrs.accepted}`,
613
+ `superseded: ${adrs.superseded}`,
614
+ `deprecated: ${adrs.deprecated}`,
615
+ ].filter(s => !s.includes(': 0')).join(', ');
616
+ lines.push(` ADRs: ${adrs.total}${adrBreakdown ? ` (${adrBreakdown})` : ''}`);
617
+ }
618
+ if (output.validation && output.validation.length > 0) {
619
+ lines.push('');
620
+ lines.push('VALIDATION');
621
+ for (const err of output.validation) {
622
+ const prefix = err.severity === 'error' ? '[ERROR]' : '[WARN]';
623
+ const typeLabel = err.type.charAt(0).toUpperCase() + err.type.slice(1);
624
+ lines.push(` ${prefix} ${typeLabel} ${err.id}: ${err.message}`);
625
+ }
626
+ }
627
+ if (output.orphans) {
628
+ const { epicsWithNoIssues, issuesWithMissingEpic, adrsWithMissingIssues, adrsWithMissingEpics } = output.orphans;
629
+ const hasOrphans = epicsWithNoIssues.length > 0 ||
630
+ issuesWithMissingEpic.length > 0 ||
631
+ adrsWithMissingIssues.length > 0 ||
632
+ adrsWithMissingEpics.length > 0;
633
+ if (hasOrphans) {
634
+ lines.push('');
635
+ lines.push('ORPHANS');
636
+ for (const epic of epicsWithNoIssues) {
637
+ lines.push(` [EPIC] ${epic.id} (no issues attached)`);
638
+ }
639
+ for (const issue of issuesWithMissingEpic) {
640
+ lines.push(` [ISSUE] ${issue.id} references missing epic ${issue.epic_id}`);
641
+ }
642
+ for (const adr of adrsWithMissingIssues) {
643
+ lines.push(` [ADR] ${adr.id} references missing issues: ${adr.missing.join(', ')}`);
644
+ }
645
+ for (const adr of adrsWithMissingEpics) {
646
+ lines.push(` [ADR] ${adr.id} references missing epics: ${adr.missing.join(', ')}`);
647
+ }
648
+ }
649
+ }
650
+ if (output.stale) {
651
+ const { issues, epics, adrs } = output.stale;
652
+ const hasStale = issues.length > 0 || epics.length > 0 || adrs.length > 0;
653
+ if (hasStale) {
654
+ lines.push('');
655
+ lines.push('STALE');
656
+ for (const issue of issues) {
657
+ lines.push(` [ISSUE] ${issue.id} last updated ${issue.updated_at}`);
658
+ }
659
+ for (const epic of epics) {
660
+ lines.push(` [EPIC] ${epic.id} last updated ${epic.updated_at}`);
661
+ }
662
+ for (const adr of adrs) {
663
+ lines.push(` [ADR] ${adr.id} last updated ${adr.updated_at}`);
664
+ }
665
+ }
666
+ }
667
+ return lines.join('\n');
668
+ }
669
+ //# sourceMappingURL=data-inspector.js.map