opencode-telos 1.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 (568) hide show
  1. package/README.md +927 -0
  2. package/dist/code-intelligence/analyzer.d.ts +9 -0
  3. package/dist/code-intelligence/analyzer.d.ts.map +1 -0
  4. package/dist/code-intelligence/analyzer.js +321 -0
  5. package/dist/code-intelligence/analyzer.js.map +1 -0
  6. package/dist/code-intelligence/ast/cache.d.ts +16 -0
  7. package/dist/code-intelligence/ast/cache.d.ts.map +1 -0
  8. package/dist/code-intelligence/ast/cache.js +44 -0
  9. package/dist/code-intelligence/ast/cache.js.map +1 -0
  10. package/dist/code-intelligence/ast/common.d.ts +8 -0
  11. package/dist/code-intelligence/ast/common.d.ts.map +1 -0
  12. package/dist/code-intelligence/ast/common.js +42 -0
  13. package/dist/code-intelligence/ast/common.js.map +1 -0
  14. package/dist/code-intelligence/ast/component.d.ts +10 -0
  15. package/dist/code-intelligence/ast/component.d.ts.map +1 -0
  16. package/dist/code-intelligence/ast/component.js +38 -0
  17. package/dist/code-intelligence/ast/component.js.map +1 -0
  18. package/dist/code-intelligence/ast/fallback.d.ts +9 -0
  19. package/dist/code-intelligence/ast/fallback.d.ts.map +1 -0
  20. package/dist/code-intelligence/ast/fallback.js +38 -0
  21. package/dist/code-intelligence/ast/fallback.js.map +1 -0
  22. package/dist/code-intelligence/ast/index.d.ts +5 -0
  23. package/dist/code-intelligence/ast/index.d.ts.map +1 -0
  24. package/dist/code-intelligence/ast/index.js +5 -0
  25. package/dist/code-intelligence/ast/index.js.map +1 -0
  26. package/dist/code-intelligence/ast/ir.d.ts +72 -0
  27. package/dist/code-intelligence/ast/ir.d.ts.map +1 -0
  28. package/dist/code-intelligence/ast/ir.js +2 -0
  29. package/dist/code-intelligence/ast/ir.js.map +1 -0
  30. package/dist/code-intelligence/ast/metrics.d.ts +25 -0
  31. package/dist/code-intelligence/ast/metrics.d.ts.map +1 -0
  32. package/dist/code-intelligence/ast/metrics.js +38 -0
  33. package/dist/code-intelligence/ast/metrics.js.map +1 -0
  34. package/dist/code-intelligence/ast/registry.d.ts +5 -0
  35. package/dist/code-intelligence/ast/registry.d.ts.map +1 -0
  36. package/dist/code-intelligence/ast/registry.js +22 -0
  37. package/dist/code-intelligence/ast/registry.js.map +1 -0
  38. package/dist/code-intelligence/ast/tree-sitter.d.ts +8 -0
  39. package/dist/code-intelligence/ast/tree-sitter.d.ts.map +1 -0
  40. package/dist/code-intelligence/ast/tree-sitter.js +247 -0
  41. package/dist/code-intelligence/ast/tree-sitter.js.map +1 -0
  42. package/dist/code-intelligence/ast/typescript.d.ts +8 -0
  43. package/dist/code-intelligence/ast/typescript.d.ts.map +1 -0
  44. package/dist/code-intelligence/ast/typescript.js +147 -0
  45. package/dist/code-intelligence/ast/typescript.js.map +1 -0
  46. package/dist/index.d.ts +10 -0
  47. package/dist/index.d.ts.map +1 -0
  48. package/dist/index.js +18 -0
  49. package/dist/index.js.map +1 -0
  50. package/dist/mcp/server.d.ts +27 -0
  51. package/dist/mcp/server.d.ts.map +1 -0
  52. package/dist/mcp/server.js +67 -0
  53. package/dist/mcp/server.js.map +1 -0
  54. package/dist/opencode/hooks.d.ts +9 -0
  55. package/dist/opencode/hooks.d.ts.map +1 -0
  56. package/dist/opencode/hooks.js +583 -0
  57. package/dist/opencode/hooks.js.map +1 -0
  58. package/dist/opencode/router/categories.d.ts +31 -0
  59. package/dist/opencode/router/categories.d.ts.map +1 -0
  60. package/dist/opencode/router/categories.js +165 -0
  61. package/dist/opencode/router/categories.js.map +1 -0
  62. package/dist/opencode/router/embeddings.d.ts +41 -0
  63. package/dist/opencode/router/embeddings.d.ts.map +1 -0
  64. package/dist/opencode/router/embeddings.js +136 -0
  65. package/dist/opencode/router/embeddings.js.map +1 -0
  66. package/dist/opencode/router/graph-state-snapshot.d.ts +35 -0
  67. package/dist/opencode/router/graph-state-snapshot.d.ts.map +1 -0
  68. package/dist/opencode/router/graph-state-snapshot.js +129 -0
  69. package/dist/opencode/router/graph-state-snapshot.js.map +1 -0
  70. package/dist/opencode/router/index.d.ts +21 -0
  71. package/dist/opencode/router/index.d.ts.map +1 -0
  72. package/dist/opencode/router/index.js +23 -0
  73. package/dist/opencode/router/index.js.map +1 -0
  74. package/dist/opencode/router/intent-classifier.d.ts +35 -0
  75. package/dist/opencode/router/intent-classifier.d.ts.map +1 -0
  76. package/dist/opencode/router/intent-classifier.js +108 -0
  77. package/dist/opencode/router/intent-classifier.js.map +1 -0
  78. package/dist/opencode/router/semantic-nudge.d.ts +42 -0
  79. package/dist/opencode/router/semantic-nudge.d.ts.map +1 -0
  80. package/dist/opencode/router/semantic-nudge.js +73 -0
  81. package/dist/opencode/router/semantic-nudge.js.map +1 -0
  82. package/dist/opencode/router/state-gate.d.ts +25 -0
  83. package/dist/opencode/router/state-gate.d.ts.map +1 -0
  84. package/dist/opencode/router/state-gate.js +178 -0
  85. package/dist/opencode/router/state-gate.js.map +1 -0
  86. package/dist/opencode/router/tool-embeddings.d.ts +36 -0
  87. package/dist/opencode/router/tool-embeddings.d.ts.map +1 -0
  88. package/dist/opencode/router/tool-embeddings.js +140 -0
  89. package/dist/opencode/router/tool-embeddings.js.map +1 -0
  90. package/dist/opencode/router/tool-registry.d.ts +45 -0
  91. package/dist/opencode/router/tool-registry.d.ts.map +1 -0
  92. package/dist/opencode/router/tool-registry.js +103 -0
  93. package/dist/opencode/router/tool-registry.js.map +1 -0
  94. package/dist/opencode/router/tool-taxonomy.d.ts +51 -0
  95. package/dist/opencode/router/tool-taxonomy.d.ts.map +1 -0
  96. package/dist/opencode/router/tool-taxonomy.js +250 -0
  97. package/dist/opencode/router/tool-taxonomy.js.map +1 -0
  98. package/dist/opencode/router/tools-composite.d.ts +21 -0
  99. package/dist/opencode/router/tools-composite.d.ts.map +1 -0
  100. package/dist/opencode/router/tools-composite.js +684 -0
  101. package/dist/opencode/router/tools-composite.js.map +1 -0
  102. package/dist/opencode/shell-hooks.d.ts +7 -0
  103. package/dist/opencode/shell-hooks.d.ts.map +1 -0
  104. package/dist/opencode/shell-hooks.js +96 -0
  105. package/dist/opencode/shell-hooks.js.map +1 -0
  106. package/dist/opencode/system-prompt.d.ts +10 -0
  107. package/dist/opencode/system-prompt.d.ts.map +1 -0
  108. package/dist/opencode/system-prompt.js +600 -0
  109. package/dist/opencode/system-prompt.js.map +1 -0
  110. package/dist/opencode/tools.d.ts +8 -0
  111. package/dist/opencode/tools.d.ts.map +1 -0
  112. package/dist/opencode/tools.js +3731 -0
  113. package/dist/opencode/tools.js.map +1 -0
  114. package/dist/opencode/workflows/chains.d.ts +52 -0
  115. package/dist/opencode/workflows/chains.d.ts.map +1 -0
  116. package/dist/opencode/workflows/chains.js +170 -0
  117. package/dist/opencode/workflows/chains.js.map +1 -0
  118. package/dist/opencode/workflows/executor.d.ts +52 -0
  119. package/dist/opencode/workflows/executor.d.ts.map +1 -0
  120. package/dist/opencode/workflows/executor.js +130 -0
  121. package/dist/opencode/workflows/executor.js.map +1 -0
  122. package/dist/opencode/workflows/index.d.ts +14 -0
  123. package/dist/opencode/workflows/index.d.ts.map +1 -0
  124. package/dist/opencode/workflows/index.js +15 -0
  125. package/dist/opencode/workflows/index.js.map +1 -0
  126. package/dist/opencode/workflows/tools-workflow.d.ts +24 -0
  127. package/dist/opencode/workflows/tools-workflow.d.ts.map +1 -0
  128. package/dist/opencode/workflows/tools-workflow.js +85 -0
  129. package/dist/opencode/workflows/tools-workflow.js.map +1 -0
  130. package/dist/opencode/workflows/types.d.ts +32 -0
  131. package/dist/opencode/workflows/types.d.ts.map +1 -0
  132. package/dist/opencode/workflows/types.js +13 -0
  133. package/dist/opencode/workflows/types.js.map +1 -0
  134. package/dist/sdd/analysis/compliance.d.ts +30 -0
  135. package/dist/sdd/analysis/compliance.d.ts.map +1 -0
  136. package/dist/sdd/analysis/compliance.js +251 -0
  137. package/dist/sdd/analysis/compliance.js.map +1 -0
  138. package/dist/sdd/analysis/scalability.d.ts +15 -0
  139. package/dist/sdd/analysis/scalability.d.ts.map +1 -0
  140. package/dist/sdd/analysis/scalability.js +72 -0
  141. package/dist/sdd/analysis/scalability.js.map +1 -0
  142. package/dist/sdd/analysis/security.d.ts +25 -0
  143. package/dist/sdd/analysis/security.d.ts.map +1 -0
  144. package/dist/sdd/analysis/security.js +94 -0
  145. package/dist/sdd/analysis/security.js.map +1 -0
  146. package/dist/sdd/brownfield/scanner.d.ts +31 -0
  147. package/dist/sdd/brownfield/scanner.d.ts.map +1 -0
  148. package/dist/sdd/brownfield/scanner.js +228 -0
  149. package/dist/sdd/brownfield/scanner.js.map +1 -0
  150. package/dist/sdd/cache/manager.d.ts +237 -0
  151. package/dist/sdd/cache/manager.d.ts.map +1 -0
  152. package/dist/sdd/cache/manager.js +770 -0
  153. package/dist/sdd/cache/manager.js.map +1 -0
  154. package/dist/sdd/cache/snapshot-store.d.ts +39 -0
  155. package/dist/sdd/cache/snapshot-store.d.ts.map +1 -0
  156. package/dist/sdd/cache/snapshot-store.js +156 -0
  157. package/dist/sdd/cache/snapshot-store.js.map +1 -0
  158. package/dist/sdd/changes/manager.d.ts +58 -0
  159. package/dist/sdd/changes/manager.d.ts.map +1 -0
  160. package/dist/sdd/changes/manager.js +235 -0
  161. package/dist/sdd/changes/manager.js.map +1 -0
  162. package/dist/sdd/cicd/generators.d.ts +16 -0
  163. package/dist/sdd/cicd/generators.d.ts.map +1 -0
  164. package/dist/sdd/cicd/generators.js +1042 -0
  165. package/dist/sdd/cicd/generators.js.map +1 -0
  166. package/dist/sdd/code-quality/complexity.d.ts +38 -0
  167. package/dist/sdd/code-quality/complexity.d.ts.map +1 -0
  168. package/dist/sdd/code-quality/complexity.js +161 -0
  169. package/dist/sdd/code-quality/complexity.js.map +1 -0
  170. package/dist/sdd/code-quality/conventions.d.ts +33 -0
  171. package/dist/sdd/code-quality/conventions.d.ts.map +1 -0
  172. package/dist/sdd/code-quality/conventions.js +193 -0
  173. package/dist/sdd/code-quality/conventions.js.map +1 -0
  174. package/dist/sdd/code-quality/dependencies.d.ts +27 -0
  175. package/dist/sdd/code-quality/dependencies.d.ts.map +1 -0
  176. package/dist/sdd/code-quality/dependencies.js +142 -0
  177. package/dist/sdd/code-quality/dependencies.js.map +1 -0
  178. package/dist/sdd/code-quality/import-analyzer.d.ts +49 -0
  179. package/dist/sdd/code-quality/import-analyzer.d.ts.map +1 -0
  180. package/dist/sdd/code-quality/import-analyzer.js +213 -0
  181. package/dist/sdd/code-quality/import-analyzer.js.map +1 -0
  182. package/dist/sdd/code-quality/metrics.d.ts +35 -0
  183. package/dist/sdd/code-quality/metrics.d.ts.map +1 -0
  184. package/dist/sdd/code-quality/metrics.js +172 -0
  185. package/dist/sdd/code-quality/metrics.js.map +1 -0
  186. package/dist/sdd/code-quality/smells.d.ts +38 -0
  187. package/dist/sdd/code-quality/smells.d.ts.map +1 -0
  188. package/dist/sdd/code-quality/smells.js +319 -0
  189. package/dist/sdd/code-quality/smells.js.map +1 -0
  190. package/dist/sdd/code-quality/symbol-parser.d.ts +28 -0
  191. package/dist/sdd/code-quality/symbol-parser.d.ts.map +1 -0
  192. package/dist/sdd/code-quality/symbol-parser.js +230 -0
  193. package/dist/sdd/code-quality/symbol-parser.js.map +1 -0
  194. package/dist/sdd/code-quality/usage-tracker.d.ts +59 -0
  195. package/dist/sdd/code-quality/usage-tracker.d.ts.map +1 -0
  196. package/dist/sdd/code-quality/usage-tracker.js +402 -0
  197. package/dist/sdd/code-quality/usage-tracker.js.map +1 -0
  198. package/dist/sdd/code-quality/utils.d.ts +6 -0
  199. package/dist/sdd/code-quality/utils.d.ts.map +1 -0
  200. package/dist/sdd/code-quality/utils.js +14 -0
  201. package/dist/sdd/code-quality/utils.js.map +1 -0
  202. package/dist/sdd/codegen/generator.d.ts +42 -0
  203. package/dist/sdd/codegen/generator.d.ts.map +1 -0
  204. package/dist/sdd/codegen/generator.js +1023 -0
  205. package/dist/sdd/codegen/generator.js.map +1 -0
  206. package/dist/sdd/constitution/validator.d.ts +37 -0
  207. package/dist/sdd/constitution/validator.d.ts.map +1 -0
  208. package/dist/sdd/constitution/validator.js +192 -0
  209. package/dist/sdd/constitution/validator.js.map +1 -0
  210. package/dist/sdd/cost/estimator.d.ts +31 -0
  211. package/dist/sdd/cost/estimator.d.ts.map +1 -0
  212. package/dist/sdd/cost/estimator.js +92 -0
  213. package/dist/sdd/cost/estimator.js.map +1 -0
  214. package/dist/sdd/coverage/tracker.d.ts +47 -0
  215. package/dist/sdd/coverage/tracker.d.ts.map +1 -0
  216. package/dist/sdd/coverage/tracker.js +251 -0
  217. package/dist/sdd/coverage/tracker.js.map +1 -0
  218. package/dist/sdd/disaster/recovery.d.ts +11 -0
  219. package/dist/sdd/disaster/recovery.d.ts.map +1 -0
  220. package/dist/sdd/disaster/recovery.js +55 -0
  221. package/dist/sdd/disaster/recovery.js.map +1 -0
  222. package/dist/sdd/discovery/adaptive.d.ts +14 -0
  223. package/dist/sdd/discovery/adaptive.d.ts.map +1 -0
  224. package/dist/sdd/discovery/adaptive.js +145 -0
  225. package/dist/sdd/discovery/adaptive.js.map +1 -0
  226. package/dist/sdd/discovery/briefing-analyzer.d.ts +66 -0
  227. package/dist/sdd/discovery/briefing-analyzer.d.ts.map +1 -0
  228. package/dist/sdd/discovery/briefing-analyzer.js +672 -0
  229. package/dist/sdd/discovery/briefing-analyzer.js.map +1 -0
  230. package/dist/sdd/discovery/briefing.d.ts +109 -0
  231. package/dist/sdd/discovery/briefing.d.ts.map +1 -0
  232. package/dist/sdd/discovery/briefing.js +617 -0
  233. package/dist/sdd/discovery/briefing.js.map +1 -0
  234. package/dist/sdd/discovery/graph-builder.d.ts +10 -0
  235. package/dist/sdd/discovery/graph-builder.d.ts.map +1 -0
  236. package/dist/sdd/discovery/graph-builder.js +510 -0
  237. package/dist/sdd/discovery/graph-builder.js.map +1 -0
  238. package/dist/sdd/documentation/generator.d.ts +7 -0
  239. package/dist/sdd/documentation/generator.d.ts.map +1 -0
  240. package/dist/sdd/documentation/generator.js +119 -0
  241. package/dist/sdd/documentation/generator.js.map +1 -0
  242. package/dist/sdd/domain/types.d.ts +460 -0
  243. package/dist/sdd/domain/types.d.ts.map +1 -0
  244. package/dist/sdd/domain/types.js +25 -0
  245. package/dist/sdd/domain/types.js.map +1 -0
  246. package/dist/sdd/drift/detector.d.ts +28 -0
  247. package/dist/sdd/drift/detector.d.ts.map +1 -0
  248. package/dist/sdd/drift/detector.js +379 -0
  249. package/dist/sdd/drift/detector.js.map +1 -0
  250. package/dist/sdd/drift/exclusion.d.ts +54 -0
  251. package/dist/sdd/drift/exclusion.d.ts.map +1 -0
  252. package/dist/sdd/drift/exclusion.js +179 -0
  253. package/dist/sdd/drift/exclusion.js.map +1 -0
  254. package/dist/sdd/drift/signals.d.ts +52 -0
  255. package/dist/sdd/drift/signals.d.ts.map +1 -0
  256. package/dist/sdd/drift/signals.js +470 -0
  257. package/dist/sdd/drift/signals.js.map +1 -0
  258. package/dist/sdd/enforcement/interceptor.d.ts +47 -0
  259. package/dist/sdd/enforcement/interceptor.d.ts.map +1 -0
  260. package/dist/sdd/enforcement/interceptor.js +365 -0
  261. package/dist/sdd/enforcement/interceptor.js.map +1 -0
  262. package/dist/sdd/enforcement/workflow-tracker.d.ts +66 -0
  263. package/dist/sdd/enforcement/workflow-tracker.d.ts.map +1 -0
  264. package/dist/sdd/enforcement/workflow-tracker.js +229 -0
  265. package/dist/sdd/enforcement/workflow-tracker.js.map +1 -0
  266. package/dist/sdd/graph/engine.d.ts +44 -0
  267. package/dist/sdd/graph/engine.d.ts.map +1 -0
  268. package/dist/sdd/graph/engine.js +203 -0
  269. package/dist/sdd/graph/engine.js.map +1 -0
  270. package/dist/sdd/graph/index.d.ts +160 -0
  271. package/dist/sdd/graph/index.d.ts.map +1 -0
  272. package/dist/sdd/graph/index.js +624 -0
  273. package/dist/sdd/graph/index.js.map +1 -0
  274. package/dist/sdd/graph/integrity-guard.d.ts +129 -0
  275. package/dist/sdd/graph/integrity-guard.d.ts.map +1 -0
  276. package/dist/sdd/graph/integrity-guard.js +263 -0
  277. package/dist/sdd/graph/integrity-guard.js.map +1 -0
  278. package/dist/sdd/graph/integrity.d.ts +79 -0
  279. package/dist/sdd/graph/integrity.d.ts.map +1 -0
  280. package/dist/sdd/graph/integrity.js +462 -0
  281. package/dist/sdd/graph/integrity.js.map +1 -0
  282. package/dist/sdd/graph/pruner.d.ts +27 -0
  283. package/dist/sdd/graph/pruner.d.ts.map +1 -0
  284. package/dist/sdd/graph/pruner.js +203 -0
  285. package/dist/sdd/graph/pruner.js.map +1 -0
  286. package/dist/sdd/graph/traverse.d.ts +43 -0
  287. package/dist/sdd/graph/traverse.d.ts.map +1 -0
  288. package/dist/sdd/graph/traverse.js +265 -0
  289. package/dist/sdd/graph/traverse.js.map +1 -0
  290. package/dist/sdd/incidents/manager.d.ts +10 -0
  291. package/dist/sdd/incidents/manager.d.ts.map +1 -0
  292. package/dist/sdd/incidents/manager.js +63 -0
  293. package/dist/sdd/incidents/manager.js.map +1 -0
  294. package/dist/sdd/knowledge/transfer.d.ts +24 -0
  295. package/dist/sdd/knowledge/transfer.d.ts.map +1 -0
  296. package/dist/sdd/knowledge/transfer.js +94 -0
  297. package/dist/sdd/knowledge/transfer.js.map +1 -0
  298. package/dist/sdd/migrations/fixes.d.ts +2 -0
  299. package/dist/sdd/migrations/fixes.d.ts.map +1 -0
  300. package/dist/sdd/migrations/fixes.js +159 -0
  301. package/dist/sdd/migrations/fixes.js.map +1 -0
  302. package/dist/sdd/migrations/index.d.ts +2 -0
  303. package/dist/sdd/migrations/index.d.ts.map +1 -0
  304. package/dist/sdd/migrations/index.js +5 -0
  305. package/dist/sdd/migrations/index.js.map +1 -0
  306. package/dist/sdd/migrations/migration-runner.d.ts +41 -0
  307. package/dist/sdd/migrations/migration-runner.d.ts.map +1 -0
  308. package/dist/sdd/migrations/migration-runner.js +91 -0
  309. package/dist/sdd/migrations/migration-runner.js.map +1 -0
  310. package/dist/sdd/monitoring/setup.d.ts +40 -0
  311. package/dist/sdd/monitoring/setup.d.ts.map +1 -0
  312. package/dist/sdd/monitoring/setup.js +177 -0
  313. package/dist/sdd/monitoring/setup.js.map +1 -0
  314. package/dist/sdd/monitoring/telemetry.d.ts +18 -0
  315. package/dist/sdd/monitoring/telemetry.d.ts.map +1 -0
  316. package/dist/sdd/monitoring/telemetry.js +37 -0
  317. package/dist/sdd/monitoring/telemetry.js.map +1 -0
  318. package/dist/sdd/patterns/anti-patterns.d.ts +21 -0
  319. package/dist/sdd/patterns/anti-patterns.d.ts.map +1 -0
  320. package/dist/sdd/patterns/anti-patterns.js +286 -0
  321. package/dist/sdd/patterns/anti-patterns.js.map +1 -0
  322. package/dist/sdd/patterns/ast-clones.d.ts +23 -0
  323. package/dist/sdd/patterns/ast-clones.d.ts.map +1 -0
  324. package/dist/sdd/patterns/ast-clones.js +171 -0
  325. package/dist/sdd/patterns/ast-clones.js.map +1 -0
  326. package/dist/sdd/patterns/config-drift.d.ts +16 -0
  327. package/dist/sdd/patterns/config-drift.d.ts.map +1 -0
  328. package/dist/sdd/patterns/config-drift.js +322 -0
  329. package/dist/sdd/patterns/config-drift.js.map +1 -0
  330. package/dist/sdd/patterns/contradictions.d.ts +38 -0
  331. package/dist/sdd/patterns/contradictions.d.ts.map +1 -0
  332. package/dist/sdd/patterns/contradictions.js +237 -0
  333. package/dist/sdd/patterns/contradictions.js.map +1 -0
  334. package/dist/sdd/patterns/learner.d.ts +49 -0
  335. package/dist/sdd/patterns/learner.d.ts.map +1 -0
  336. package/dist/sdd/patterns/learner.js +226 -0
  337. package/dist/sdd/patterns/learner.js.map +1 -0
  338. package/dist/sdd/permissions/access.d.ts +69 -0
  339. package/dist/sdd/permissions/access.d.ts.map +1 -0
  340. package/dist/sdd/permissions/access.js +333 -0
  341. package/dist/sdd/permissions/access.js.map +1 -0
  342. package/dist/sdd/persistence/repository.d.ts +60 -0
  343. package/dist/sdd/persistence/repository.d.ts.map +1 -0
  344. package/dist/sdd/persistence/repository.js +96 -0
  345. package/dist/sdd/persistence/repository.js.map +1 -0
  346. package/dist/sdd/persistence/sqlite.d.ts +122 -0
  347. package/dist/sdd/persistence/sqlite.d.ts.map +1 -0
  348. package/dist/sdd/persistence/sqlite.js +602 -0
  349. package/dist/sdd/persistence/sqlite.js.map +1 -0
  350. package/dist/sdd/persistence/yaml.d.ts +41 -0
  351. package/dist/sdd/persistence/yaml.d.ts.map +1 -0
  352. package/dist/sdd/persistence/yaml.js +382 -0
  353. package/dist/sdd/persistence/yaml.js.map +1 -0
  354. package/dist/sdd/promises/classifier.d.ts +48 -0
  355. package/dist/sdd/promises/classifier.d.ts.map +1 -0
  356. package/dist/sdd/promises/classifier.js +215 -0
  357. package/dist/sdd/promises/classifier.js.map +1 -0
  358. package/dist/sdd/promises/tracker.d.ts +20 -0
  359. package/dist/sdd/promises/tracker.d.ts.map +1 -0
  360. package/dist/sdd/promises/tracker.js +204 -0
  361. package/dist/sdd/promises/tracker.js.map +1 -0
  362. package/dist/sdd/quality/scorer.d.ts +44 -0
  363. package/dist/sdd/quality/scorer.d.ts.map +1 -0
  364. package/dist/sdd/quality/scorer.js +216 -0
  365. package/dist/sdd/quality/scorer.js.map +1 -0
  366. package/dist/sdd/rollback/manager.d.ts +45 -0
  367. package/dist/sdd/rollback/manager.d.ts.map +1 -0
  368. package/dist/sdd/rollback/manager.js +266 -0
  369. package/dist/sdd/rollback/manager.js.map +1 -0
  370. package/dist/sdd/session/handoff.d.ts +52 -0
  371. package/dist/sdd/session/handoff.d.ts.map +1 -0
  372. package/dist/sdd/session/handoff.js +264 -0
  373. package/dist/sdd/session/handoff.js.map +1 -0
  374. package/dist/sdd/sla/tracker.d.ts +11 -0
  375. package/dist/sdd/sla/tracker.d.ts.map +1 -0
  376. package/dist/sdd/sla/tracker.js +52 -0
  377. package/dist/sdd/sla/tracker.js.map +1 -0
  378. package/dist/sdd/sync/git-sync.d.ts +61 -0
  379. package/dist/sdd/sync/git-sync.d.ts.map +1 -0
  380. package/dist/sdd/sync/git-sync.js +297 -0
  381. package/dist/sdd/sync/git-sync.js.map +1 -0
  382. package/dist/sdd/toggle/state.d.ts +8 -0
  383. package/dist/sdd/toggle/state.d.ts.map +1 -0
  384. package/dist/sdd/toggle/state.js +32 -0
  385. package/dist/sdd/toggle/state.js.map +1 -0
  386. package/dist/sdd/transactions/manager.d.ts +12 -0
  387. package/dist/sdd/transactions/manager.d.ts.map +1 -0
  388. package/dist/sdd/transactions/manager.js +80 -0
  389. package/dist/sdd/transactions/manager.js.map +1 -0
  390. package/dist/sdd/validation/coverage-index.d.ts +117 -0
  391. package/dist/sdd/validation/coverage-index.d.ts.map +1 -0
  392. package/dist/sdd/validation/coverage-index.js +251 -0
  393. package/dist/sdd/validation/coverage-index.js.map +1 -0
  394. package/dist/sdd/validation/executable.d.ts +26 -0
  395. package/dist/sdd/validation/executable.d.ts.map +1 -0
  396. package/dist/sdd/validation/executable.js +122 -0
  397. package/dist/sdd/validation/executable.js.map +1 -0
  398. package/dist/sdd/validation/smart-validator.d.ts +53 -0
  399. package/dist/sdd/validation/smart-validator.d.ts.map +1 -0
  400. package/dist/sdd/validation/smart-validator.js +347 -0
  401. package/dist/sdd/validation/smart-validator.js.map +1 -0
  402. package/dist/sdd/validation/validator.d.ts +39 -0
  403. package/dist/sdd/validation/validator.d.ts.map +1 -0
  404. package/dist/sdd/validation/validator.js +512 -0
  405. package/dist/sdd/validation/validator.js.map +1 -0
  406. package/dist/sdd/workflow/exporter.d.ts +36 -0
  407. package/dist/sdd/workflow/exporter.d.ts.map +1 -0
  408. package/dist/sdd/workflow/exporter.js +112 -0
  409. package/dist/sdd/workflow/exporter.js.map +1 -0
  410. package/dist/sdd/workflows/ab-testing.d.ts +18 -0
  411. package/dist/sdd/workflows/ab-testing.d.ts.map +1 -0
  412. package/dist/sdd/workflows/ab-testing.js +67 -0
  413. package/dist/sdd/workflows/ab-testing.js.map +1 -0
  414. package/dist/sdd/workflows/bug-fix.d.ts +13 -0
  415. package/dist/sdd/workflows/bug-fix.d.ts.map +1 -0
  416. package/dist/sdd/workflows/bug-fix.js +65 -0
  417. package/dist/sdd/workflows/bug-fix.js.map +1 -0
  418. package/dist/sdd/workflows/data-migration.d.ts +14 -0
  419. package/dist/sdd/workflows/data-migration.d.ts.map +1 -0
  420. package/dist/sdd/workflows/data-migration.js +68 -0
  421. package/dist/sdd/workflows/data-migration.js.map +1 -0
  422. package/dist/sdd/workflows/deprecation.d.ts +15 -0
  423. package/dist/sdd/workflows/deprecation.d.ts.map +1 -0
  424. package/dist/sdd/workflows/deprecation.js +68 -0
  425. package/dist/sdd/workflows/deprecation.js.map +1 -0
  426. package/dist/sdd/workflows/feature-flags.d.ts +14 -0
  427. package/dist/sdd/workflows/feature-flags.d.ts.map +1 -0
  428. package/dist/sdd/workflows/feature-flags.js +73 -0
  429. package/dist/sdd/workflows/feature-flags.js.map +1 -0
  430. package/dist/sdd/workflows/hotfix.d.ts +13 -0
  431. package/dist/sdd/workflows/hotfix.d.ts.map +1 -0
  432. package/dist/sdd/workflows/hotfix.js +67 -0
  433. package/dist/sdd/workflows/hotfix.js.map +1 -0
  434. package/dist/sdd/workflows/multi-tenancy.d.ts +13 -0
  435. package/dist/sdd/workflows/multi-tenancy.d.ts.map +1 -0
  436. package/dist/sdd/workflows/multi-tenancy.js +68 -0
  437. package/dist/sdd/workflows/multi-tenancy.js.map +1 -0
  438. package/dist/sdd/workflows/onboarding.d.ts +7 -0
  439. package/dist/sdd/workflows/onboarding.d.ts.map +1 -0
  440. package/dist/sdd/workflows/onboarding.js +43 -0
  441. package/dist/sdd/workflows/onboarding.js.map +1 -0
  442. package/dist/sdd/workflows/refactoring.d.ts +14 -0
  443. package/dist/sdd/workflows/refactoring.d.ts.map +1 -0
  444. package/dist/sdd/workflows/refactoring.js +73 -0
  445. package/dist/sdd/workflows/refactoring.js.map +1 -0
  446. package/dist/server/events.d.ts +64 -0
  447. package/dist/server/events.d.ts.map +1 -0
  448. package/dist/server/events.js +149 -0
  449. package/dist/server/events.js.map +1 -0
  450. package/dist/server/server.d.ts +33 -0
  451. package/dist/server/server.d.ts.map +1 -0
  452. package/dist/server/server.js +1019 -0
  453. package/dist/server/server.js.map +1 -0
  454. package/marketplace.json +39 -0
  455. package/package.json +65 -0
  456. package/src/code-intelligence/analyzer.ts +350 -0
  457. package/src/code-intelligence/ast/cache.ts +61 -0
  458. package/src/code-intelligence/ast/common.ts +62 -0
  459. package/src/code-intelligence/ast/component.ts +39 -0
  460. package/src/code-intelligence/ast/fallback.ts +44 -0
  461. package/src/code-intelligence/ast/index.ts +4 -0
  462. package/src/code-intelligence/ast/ir.ts +91 -0
  463. package/src/code-intelligence/ast/metrics.ts +65 -0
  464. package/src/code-intelligence/ast/registry.ts +28 -0
  465. package/src/code-intelligence/ast/tree-sitter.ts +226 -0
  466. package/src/code-intelligence/ast/typescript.ts +140 -0
  467. package/src/index.ts +22 -0
  468. package/src/mcp/server.ts +77 -0
  469. package/src/opencode/hooks.ts +728 -0
  470. package/src/opencode/router/categories.ts +192 -0
  471. package/src/opencode/router/embeddings.ts +149 -0
  472. package/src/opencode/router/graph-state-snapshot.ts +163 -0
  473. package/src/opencode/router/index.ts +44 -0
  474. package/src/opencode/router/intent-classifier.ts +140 -0
  475. package/src/opencode/router/semantic-nudge.ts +89 -0
  476. package/src/opencode/router/state-gate.ts +192 -0
  477. package/src/opencode/router/tool-embeddings.ts +162 -0
  478. package/src/opencode/router/tool-registry.ts +135 -0
  479. package/src/opencode/router/tool-taxonomy.ts +284 -0
  480. package/src/opencode/router/tools-composite.ts +685 -0
  481. package/src/opencode/shell-hooks.ts +115 -0
  482. package/src/opencode/system-prompt.ts +617 -0
  483. package/src/opencode/tools.ts +4102 -0
  484. package/src/opencode/workflows/chains.ts +205 -0
  485. package/src/opencode/workflows/executor.ts +172 -0
  486. package/src/opencode/workflows/index.ts +21 -0
  487. package/src/opencode/workflows/tools-workflow.ts +91 -0
  488. package/src/opencode/workflows/types.ts +42 -0
  489. package/src/sdd/analysis/compliance.ts +279 -0
  490. package/src/sdd/analysis/scalability.ts +97 -0
  491. package/src/sdd/analysis/security.ts +135 -0
  492. package/src/sdd/brownfield/scanner.ts +276 -0
  493. package/src/sdd/cache/manager.ts +899 -0
  494. package/src/sdd/cache/snapshot-store.ts +185 -0
  495. package/src/sdd/changes/manager.ts +326 -0
  496. package/src/sdd/cicd/generators.ts +1095 -0
  497. package/src/sdd/code-quality/complexity.ts +235 -0
  498. package/src/sdd/code-quality/conventions.ts +220 -0
  499. package/src/sdd/code-quality/dependencies.ts +203 -0
  500. package/src/sdd/code-quality/import-analyzer.ts +294 -0
  501. package/src/sdd/code-quality/metrics.ts +232 -0
  502. package/src/sdd/code-quality/smells.ts +415 -0
  503. package/src/sdd/code-quality/symbol-parser.ts +335 -0
  504. package/src/sdd/code-quality/usage-tracker.ts +527 -0
  505. package/src/sdd/code-quality/utils.ts +13 -0
  506. package/src/sdd/codegen/generator.ts +1181 -0
  507. package/src/sdd/constitution/validator.ts +253 -0
  508. package/src/sdd/cost/estimator.ts +147 -0
  509. package/src/sdd/coverage/tracker.ts +342 -0
  510. package/src/sdd/disaster/recovery.ts +79 -0
  511. package/src/sdd/discovery/adaptive.ts +167 -0
  512. package/src/sdd/discovery/briefing-analyzer.ts +802 -0
  513. package/src/sdd/discovery/briefing.ts +770 -0
  514. package/src/sdd/discovery/graph-builder.ts +598 -0
  515. package/src/sdd/documentation/generator.ts +158 -0
  516. package/src/sdd/domain/types.ts +658 -0
  517. package/src/sdd/drift/detector.ts +465 -0
  518. package/src/sdd/drift/exclusion.ts +223 -0
  519. package/src/sdd/drift/signals.ts +577 -0
  520. package/src/sdd/enforcement/interceptor.ts +444 -0
  521. package/src/sdd/enforcement/workflow-tracker.ts +263 -0
  522. package/src/sdd/graph/engine.ts +277 -0
  523. package/src/sdd/graph/index.ts +700 -0
  524. package/src/sdd/graph/integrity-guard.ts +348 -0
  525. package/src/sdd/graph/integrity.ts +628 -0
  526. package/src/sdd/graph/pruner.ts +221 -0
  527. package/src/sdd/graph/traverse.ts +331 -0
  528. package/src/sdd/incidents/manager.ts +87 -0
  529. package/src/sdd/knowledge/transfer.ts +140 -0
  530. package/src/sdd/migrations/fixes.ts +154 -0
  531. package/src/sdd/migrations/index.ts +14 -0
  532. package/src/sdd/migrations/migration-runner.ts +118 -0
  533. package/src/sdd/monitoring/setup.ts +237 -0
  534. package/src/sdd/monitoring/telemetry.ts +44 -0
  535. package/src/sdd/patterns/anti-patterns.ts +333 -0
  536. package/src/sdd/patterns/ast-clones.ts +214 -0
  537. package/src/sdd/patterns/config-drift.ts +346 -0
  538. package/src/sdd/patterns/contradictions.ts +323 -0
  539. package/src/sdd/patterns/learner.ts +266 -0
  540. package/src/sdd/permissions/access.ts +478 -0
  541. package/src/sdd/persistence/repository.ts +166 -0
  542. package/src/sdd/persistence/sqlite.ts +703 -0
  543. package/src/sdd/persistence/yaml.ts +409 -0
  544. package/src/sdd/promises/classifier.ts +253 -0
  545. package/src/sdd/promises/tracker.ts +258 -0
  546. package/src/sdd/quality/scorer.ts +263 -0
  547. package/src/sdd/rollback/manager.ts +361 -0
  548. package/src/sdd/session/handoff.ts +354 -0
  549. package/src/sdd/sla/tracker.ts +68 -0
  550. package/src/sdd/sync/git-sync.ts +401 -0
  551. package/src/sdd/toggle/state.ts +38 -0
  552. package/src/sdd/transactions/manager.ts +93 -0
  553. package/src/sdd/validation/coverage-index.ts +339 -0
  554. package/src/sdd/validation/executable.ts +127 -0
  555. package/src/sdd/validation/smart-validator.ts +470 -0
  556. package/src/sdd/validation/validator.ts +641 -0
  557. package/src/sdd/workflow/exporter.ts +169 -0
  558. package/src/sdd/workflows/ab-testing.ts +90 -0
  559. package/src/sdd/workflows/bug-fix.ts +81 -0
  560. package/src/sdd/workflows/data-migration.ts +86 -0
  561. package/src/sdd/workflows/deprecation.ts +87 -0
  562. package/src/sdd/workflows/feature-flags.ts +91 -0
  563. package/src/sdd/workflows/hotfix.ts +83 -0
  564. package/src/sdd/workflows/multi-tenancy.ts +84 -0
  565. package/src/sdd/workflows/onboarding.ts +82 -0
  566. package/src/sdd/workflows/refactoring.ts +90 -0
  567. package/src/server/events.ts +184 -0
  568. package/src/server/server.ts +1088 -0
@@ -0,0 +1,628 @@
1
+ import type {
2
+ KnowledgeGraph,
3
+ AnyNode,
4
+ Relationship,
5
+ RelationshipType,
6
+ } from "../domain/types.js"
7
+ import {
8
+ getNode,
9
+ addRelationship,
10
+ removeRelationship,
11
+ getOutgoing,
12
+ getIncoming,
13
+ } from "./engine.js"
14
+
15
+ // ─── Types ─────────────────────────────────────────────────────────
16
+
17
+ export interface IntegrityReport {
18
+ orphan_nodes: OrphanInfo[]
19
+ disconnected_groups: DisconnectedGroup[]
20
+ redundant_relationships: RedundantRelationship[]
21
+ fixes_applied: IntegrityFix[]
22
+ summary: IntegritySummary
23
+ }
24
+
25
+ /**
26
+ * Options for controlling graph integrity check scope.
27
+ */
28
+ export interface IntegrityCheckOptions {
29
+ /** Auto-fix detected issues. */
30
+ auto_fix?: boolean
31
+ /** Only check these specific node IDs and their neighbors. */
32
+ focusNodeIds?: string[]
33
+ /** Skip these check types. */
34
+ skipChecks?: Array<"orphans" | "disconnected" | "redundant">
35
+ /** Only check nodes that changed since a specific timestamp. */
36
+ changedSince?: string
37
+ /** Maximum disconnected groups to report. */
38
+ maxGroups?: number
39
+ /** Maximum orphans to report. */
40
+ maxOrphans?: number
41
+ /** Cache for disconnected group detection (graph_hash → result). */
42
+ connectivityCache?: Map<string, { connected: boolean; groups: DisconnectedGroup[]; timestamp: number }>
43
+ }
44
+
45
+ export interface OrphanInfo {
46
+ node_id: string
47
+ node_name: string
48
+ node_type: string
49
+ }
50
+
51
+ export interface DisconnectedGroup {
52
+ group_id: number
53
+ node_ids: string[]
54
+ node_names: string[]
55
+ size: number
56
+ suggested_connection: {
57
+ target_id: string
58
+ target_name: string
59
+ relationship_type: RelationshipType
60
+ } | null
61
+ }
62
+
63
+ export interface RedundantRelationship {
64
+ relationship_id: string
65
+ from: string
66
+ to: string
67
+ type: string
68
+ reason: "duplicate" | "self_loop" | "reversed_exists"
69
+ }
70
+
71
+ export interface IntegrityFix {
72
+ action: "connected_orphan" | "merged_group" | "removed_duplicate" | "removed_self_loop" | "removed_reversed"
73
+ details: string
74
+ relationship?: { from: string; to: string; type: string }
75
+ }
76
+
77
+ export interface IntegritySummary {
78
+ total_nodes: number
79
+ total_relationships: number
80
+ orphans_found: number
81
+ disconnected_groups_found: number
82
+ redundant_relationships_found: number
83
+ fixes_applied: number
84
+ graph_connected: boolean
85
+ }
86
+
87
+ // ─── Main Entry Point ──────────────────────────────────────────────
88
+
89
+ /**
90
+ * Runs a full integrity check on the graph and optionally fixes issues.
91
+ * This should be called after any graph mutation (add/remove node or relationship).
92
+ */
93
+ export function ensureGraphIntegrity(
94
+ graph: KnowledgeGraph,
95
+ options: IntegrityCheckOptions = {},
96
+ ): IntegrityReport {
97
+ const autoFix = options.auto_fix ?? true
98
+
99
+ const report: IntegrityReport = {
100
+ orphan_nodes: [],
101
+ disconnected_groups: [],
102
+ redundant_relationships: [],
103
+ fixes_applied: [],
104
+ summary: {
105
+ total_nodes: graph.nodes.length,
106
+ total_relationships: graph.relationships.length,
107
+ orphans_found: 0,
108
+ disconnected_groups_found: 0,
109
+ redundant_relationships_found: 0,
110
+ fixes_applied: 0,
111
+ graph_connected: false,
112
+ },
113
+ }
114
+
115
+ // Build focus node set for targeted checks
116
+ const focusSet = options.focusNodeIds ? new Set(options.focusNodeIds) : null
117
+ const skipChecks = new Set(options.skipChecks || [])
118
+
119
+ // Filter graph to focus nodes if specified
120
+ const graphToCheck = focusSet ? filterGraphToFocus(graph, focusSet) : graph
121
+
122
+ // Step 1: Detect and fix redundant relationships first (before connectivity)
123
+ if (!skipChecks.has("redundant")) {
124
+ report.redundant_relationships = detectRedundantRelationships(graphToCheck)
125
+ report.summary.redundant_relationships_found = report.redundant_relationships.length
126
+
127
+ if (autoFix) {
128
+ for (const redundant of report.redundant_relationships) {
129
+ removeRedundantRelationship(graph, redundant)
130
+ report.fixes_applied.push({
131
+ action: redundant.reason === "self_loop" ? "removed_self_loop" : redundant.reason === "duplicate" ? "removed_duplicate" : "removed_reversed",
132
+ details: `Removed ${redundant.reason}: ${redundant.from} → ${redundant.to} (${redundant.type})`,
133
+ relationship: { from: redundant.from, to: redundant.to, type: redundant.type },
134
+ })
135
+ }
136
+ }
137
+ }
138
+
139
+ // Step 2: Detect orphan nodes (no relationships at all)
140
+ if (!skipChecks.has("orphans")) {
141
+ report.orphan_nodes = detectOrphanNodes(graphToCheck)
142
+ if (options.maxOrphans && report.orphan_nodes.length > options.maxOrphans) {
143
+ report.orphan_nodes = report.orphan_nodes.slice(0, options.maxOrphans)
144
+ }
145
+ report.summary.orphans_found = report.orphan_nodes.length
146
+
147
+ if (autoFix) {
148
+ for (const orphan of report.orphan_nodes) {
149
+ const fix = connectOrphanNode(graph, orphan)
150
+ if (fix) report.fixes_applied.push(fix)
151
+ }
152
+ }
153
+ }
154
+
155
+ // Step 3: Detect disconnected subgraphs
156
+ if (!skipChecks.has("disconnected")) {
157
+ // Check connectivity cache
158
+ const graphHash = `${graphToCheck.nodes.length}:${graphToCheck.relationships.length}`
159
+ const cachedConnectivity = options?.connectivityCache?.get(graphHash)
160
+ const cacheMaxAge = 30000 // 30 seconds
161
+
162
+ if (cachedConnectivity && (Date.now() - cachedConnectivity.timestamp) < cacheMaxAge) {
163
+ report.disconnected_groups = options.maxGroups ? cachedConnectivity.groups.slice(0, options.maxGroups) : cachedConnectivity.groups
164
+ report.summary.disconnected_groups_found = cachedConnectivity.groups.length
165
+ report.summary.graph_connected = cachedConnectivity.connected
166
+ } else {
167
+ const { mainGroup, disconnectedGroups } = detectDisconnectedGroups(graphToCheck)
168
+ if (options.maxGroups && disconnectedGroups.length > options.maxGroups) {
169
+ report.disconnected_groups = disconnectedGroups.slice(0, options.maxGroups)
170
+ } else {
171
+ report.disconnected_groups = disconnectedGroups
172
+ }
173
+ report.summary.disconnected_groups_found = disconnectedGroups.length
174
+ report.summary.graph_connected = disconnectedGroups.length === 0
175
+
176
+ // Store in cache
177
+ if (options?.connectivityCache) {
178
+ options.connectivityCache.set(graphHash, {
179
+ connected: disconnectedGroups.length === 0,
180
+ groups: disconnectedGroups,
181
+ timestamp: Date.now(),
182
+ })
183
+ }
184
+ }
185
+
186
+ if (autoFix) {
187
+ for (const group of report.disconnected_groups) {
188
+ const fix = connectDisconnectedGroup(graph, group, { nodeIds: new Set(graph.nodes.map(n => n.id)), representative: graph.project_id })
189
+ if (fix) report.fixes_applied.push(fix)
190
+ }
191
+ }
192
+ }
193
+
194
+ report.summary.fixes_applied = report.fixes_applied.length
195
+ return report
196
+ }
197
+
198
+ /**
199
+ * Filter a graph to only include focus nodes and their immediate neighbors.
200
+ */
201
+ function filterGraphToFocus(graph: KnowledgeGraph, focusIds: Set<string>): KnowledgeGraph {
202
+ const neighborIds = new Set<string>()
203
+ for (const rel of graph.relationships) {
204
+ if (focusIds.has(rel.from)) neighborIds.add(rel.to)
205
+ if (focusIds.has(rel.to)) neighborIds.add(rel.from)
206
+ }
207
+ const includeIds = new Set([...focusIds, ...neighborIds])
208
+
209
+ return {
210
+ ...graph,
211
+ nodes: graph.nodes.filter(n => includeIds.has(n.id)),
212
+ relationships: graph.relationships.filter(r => includeIds.has(r.from) && includeIds.has(r.to)),
213
+ }
214
+ }
215
+
216
+ // ─── Redundant Relationship Detection ──────────────────────────────
217
+
218
+ function detectRedundantRelationships(graph: KnowledgeGraph): RedundantRelationship[] {
219
+ const redundants: RedundantRelationship[] = []
220
+ const seen = new Set<string>()
221
+
222
+ for (const rel of graph.relationships) {
223
+ // Self-loops are always redundant
224
+ if (rel.from === rel.to) {
225
+ redundants.push({
226
+ relationship_id: rel.id,
227
+ from: rel.from,
228
+ to: rel.to,
229
+ type: rel.type,
230
+ reason: "self_loop",
231
+ })
232
+ continue
233
+ }
234
+
235
+ // Exact duplicates (same from, to, type)
236
+ const key = `${rel.from}||${rel.to}||${rel.type}`
237
+ if (seen.has(key)) {
238
+ redundants.push({
239
+ relationship_id: rel.id,
240
+ from: rel.from,
241
+ to: rel.to,
242
+ type: rel.type,
243
+ reason: "duplicate",
244
+ })
245
+ continue
246
+ }
247
+ seen.add(key)
248
+
249
+ // Reversed relationship exists (A→B and B→A with same type)
250
+ const reverseKey = `${rel.to}||${rel.from}||${rel.type}`
251
+ if (seen.has(reverseKey)) {
252
+ // Only flag if the relationship is not bidirectional by design
253
+ if (!isBidirectionalType(rel.type)) {
254
+ redundants.push({
255
+ relationship_id: rel.id,
256
+ from: rel.from,
257
+ to: rel.to,
258
+ type: rel.type,
259
+ reason: "reversed_exists",
260
+ })
261
+ }
262
+ }
263
+ }
264
+
265
+ return redundants
266
+ }
267
+
268
+ function isBidirectionalType(type: string): boolean {
269
+ // Some relationship types are naturally bidirectional
270
+ const bidirectional = new Set([
271
+ "contradicts",
272
+ "supersedes",
273
+ "blocked_by",
274
+ ])
275
+ return bidirectional.has(type)
276
+ }
277
+
278
+ function removeRedundantRelationship(
279
+ graph: KnowledgeGraph,
280
+ redundant: RedundantRelationship,
281
+ ): void {
282
+ // Find and remove the actual relationship object
283
+ const idx = graph.relationships.findIndex(
284
+ (r) => r.from === redundant.from && r.to === redundant.to && r.type === redundant.type,
285
+ )
286
+ if (idx !== -1) {
287
+ graph.relationships.splice(idx, 1)
288
+ graph.metadata.updated_at = new Date().toISOString()
289
+ }
290
+ }
291
+
292
+ // ─── Orphan Node Detection ─────────────────────────────────────────
293
+
294
+ function detectOrphanNodes(graph: KnowledgeGraph): OrphanInfo[] {
295
+ const orphans: OrphanInfo[] = []
296
+ const relatedIds = new Set<string>()
297
+
298
+ for (const rel of graph.relationships) {
299
+ relatedIds.add(rel.from)
300
+ relatedIds.add(rel.to)
301
+ }
302
+
303
+ for (const node of graph.nodes) {
304
+ if (relatedIds.has(node.id)) continue
305
+ orphans.push({
306
+ node_id: node.id,
307
+ node_name: node.name,
308
+ node_type: node.type,
309
+ })
310
+ }
311
+
312
+ return orphans
313
+ }
314
+
315
+ function connectOrphanNode(
316
+ graph: KnowledgeGraph,
317
+ orphan: OrphanInfo,
318
+ ): IntegrityFix | null {
319
+ const projectId = graph.project_id
320
+ const projectNode = getNode(graph, projectId)
321
+
322
+ if (!projectNode) return null
323
+
324
+ // Strategy: connect to project root with "contains" relationship
325
+ try {
326
+ addRelationship(graph, projectId, orphan.node_id, "contains")
327
+ return {
328
+ action: "connected_orphan",
329
+ details: `Connected orphan "${orphan.node_name}" (${orphan.node_type}) to project root`,
330
+ relationship: { from: projectId, to: orphan.node_id, type: "contains" },
331
+ }
332
+ } catch {
333
+ // Relationship might already exist
334
+ return null
335
+ }
336
+ }
337
+
338
+ // ─── Disconnected Group Detection ──────────────────────────────────
339
+
340
+ interface SubgraphInfo {
341
+ nodeIds: Set<string>
342
+ representative: string // A node ID from this group
343
+ }
344
+
345
+ function detectDisconnectedGroups(
346
+ graph: KnowledgeGraph,
347
+ ): { mainGroup: SubgraphInfo; disconnectedGroups: DisconnectedGroup[] } {
348
+ const projectId = graph.project_id
349
+ const visited = new Set<string>()
350
+ const allGroups: SubgraphInfo[] = []
351
+
352
+ // Build adjacency list for BFS
353
+ const adj = new Map<string, Set<string>>()
354
+ for (const node of graph.nodes) {
355
+ adj.set(node.id, new Set())
356
+ }
357
+ for (const rel of graph.relationships) {
358
+ adj.get(rel.from)?.add(rel.to)
359
+ adj.get(rel.to)?.add(rel.from)
360
+ }
361
+
362
+ // Find all connected components via BFS
363
+ for (const node of graph.nodes) {
364
+ if (visited.has(node.id)) continue
365
+
366
+ const group = new Set<string>()
367
+ const queue = [node.id]
368
+ visited.add(node.id)
369
+
370
+ while (queue.length > 0) {
371
+ const current = queue.shift()!
372
+ group.add(current)
373
+
374
+ for (const neighbor of adj.get(current) || []) {
375
+ if (!visited.has(neighbor)) {
376
+ visited.add(neighbor)
377
+ queue.push(neighbor)
378
+ }
379
+ }
380
+ }
381
+
382
+ allGroups.push({ nodeIds: group, representative: node.id })
383
+ }
384
+
385
+ // The main group is the one containing the project root
386
+ const mainGroup = allGroups.find((g) => g.nodeIds.has(projectId)) || allGroups[0]
387
+
388
+ // All other groups are disconnected
389
+ const disconnectedGroups: DisconnectedGroup[] = []
390
+ let groupId = 0
391
+
392
+ for (const group of allGroups) {
393
+ if (group === mainGroup) continue
394
+ if (group.nodeIds.size === 0) continue
395
+
396
+ groupId++
397
+ const nodeIds = [...group.nodeIds]
398
+ const nodeNames = nodeIds
399
+ .map((id) => getNode(graph, id))
400
+ .filter(Boolean)
401
+ .map((n) => n!.name)
402
+
403
+ // Find the best connection target for this group
404
+ const suggestedConnection = findBestConnectionTarget(graph, group, mainGroup)
405
+
406
+ disconnectedGroups.push({
407
+ group_id: groupId,
408
+ node_ids: nodeIds,
409
+ node_names: nodeNames,
410
+ size: group.nodeIds.size,
411
+ suggested_connection: suggestedConnection,
412
+ })
413
+ }
414
+
415
+ return { mainGroup, disconnectedGroups }
416
+ }
417
+
418
+ function findBestConnectionTarget(
419
+ graph: KnowledgeGraph,
420
+ group: SubgraphInfo,
421
+ mainGroup: SubgraphInfo,
422
+ ): DisconnectedGroup["suggested_connection"] {
423
+ // Strategy 1: Find nodes in the group that share a type with nodes in the main group
424
+ // and suggest connecting them
425
+ const groupNodes = [...group.nodeIds]
426
+ .map((id) => getNode(graph, id))
427
+ .filter(Boolean) as AnyNode[]
428
+
429
+ const mainNodes = [...mainGroup.nodeIds]
430
+ .map((id) => getNode(graph, id))
431
+ .filter(Boolean) as AnyNode[]
432
+
433
+ // Try to find a semantic connection
434
+ for (const groupNode of groupNodes) {
435
+ for (const mainNode of mainNodes) {
436
+ const relType = suggestRelationshipType(groupNode, mainNode)
437
+ if (relType) {
438
+ return {
439
+ target_id: mainNode.id,
440
+ target_name: mainNode.name,
441
+ relationship_type: relType,
442
+ }
443
+ }
444
+ }
445
+ }
446
+
447
+ // Fallback: connect to project root
448
+ const projectId = graph.project_id
449
+ return {
450
+ target_id: projectId,
451
+ target_name: "Project Root",
452
+ relationship_type: "contains",
453
+ }
454
+ }
455
+
456
+ function suggestRelationshipType(
457
+ source: AnyNode,
458
+ target: AnyNode,
459
+ ): RelationshipType | null {
460
+ const s = source.type
461
+ const t = target.type
462
+
463
+ // Semantic connection rules based on node types
464
+ const rules: Array<[string, string, RelationshipType]> = [
465
+ // Features use entities and architecture
466
+ ["feature", "entity", "uses"],
467
+ ["feature", "architecture_component", "uses"],
468
+ ["feature", "requirement", "satisfied_by"],
469
+ // Requirements
470
+ ["requirement", "feature", "implemented_by"],
471
+ ["requirement", "task", "implemented_by"],
472
+ // Endpoints expose entities
473
+ ["endpoint", "entity", "exposes"],
474
+ ["api", "endpoint", "contains"],
475
+ // Entities persist to database
476
+ ["entity", "database", "persists_to"],
477
+ ["entity", "table", "persists_to"],
478
+ // Architecture depends on
479
+ ["architecture_component", "architecture_component", "depends_on"],
480
+ // Business rules
481
+ ["business_rule", "feature", "constrains"],
482
+ ["business_rule", "requirement", "constrains"],
483
+ // Decisions influence
484
+ ["decision", "feature", "influences"],
485
+ ["decision", "architecture_component", "influences"],
486
+ // Tasks implement
487
+ ["task", "requirement", "implements"],
488
+ ["task", "feature", "implements"],
489
+ // Files contain symbols
490
+ ["file", "symbol", "contains"],
491
+ // Changes affect
492
+ ["change", "feature", "affects"],
493
+ ["change", "entity", "affects"],
494
+ // Tests test
495
+ ["test", "requirement", "tests"],
496
+ ["test", "feature", "tests"],
497
+ ]
498
+
499
+ // Check both directions
500
+ for (const [fromType, toType, relType] of rules) {
501
+ if (s === fromType && t === toType) return relType
502
+ if (s === toType && t === fromType) {
503
+ // Reverse the relationship direction
504
+ return relType
505
+ }
506
+ }
507
+
508
+ // Default: use "contains" from parent to child based on hierarchy
509
+ const hierarchy = getHierarchyLevel(s)
510
+ const targetHierarchy = getHierarchyLevel(t)
511
+ if (hierarchy < targetHierarchy) return "contains"
512
+ if (hierarchy > targetHierarchy) return "belongs_to"
513
+
514
+ return null
515
+ }
516
+
517
+ function getHierarchyLevel(type: string): number {
518
+ // Higher number = more specific/leaf node
519
+ const levels: Record<string, number> = {
520
+ project: 0,
521
+ domain: 1,
522
+ architecture_component: 2,
523
+ database: 2,
524
+ feature: 3,
525
+ requirement: 3,
526
+ entity: 3,
527
+ api: 3,
528
+ business_rule: 3,
529
+ decision: 3,
530
+ endpoint: 4,
531
+ table: 4,
532
+ field: 5,
533
+ task: 4,
534
+ test: 4,
535
+ file: 4,
536
+ symbol: 5,
537
+ change: 2,
538
+ constitution: 1,
539
+ }
540
+ return levels[type] ?? 3
541
+ }
542
+
543
+ function connectDisconnectedGroup(
544
+ graph: KnowledgeGraph,
545
+ group: DisconnectedGroup,
546
+ mainGroup: SubgraphInfo,
547
+ ): IntegrityFix | null {
548
+ if (!group.suggested_connection) return null
549
+
550
+ // Connect the first node of the disconnected group to the suggested target
551
+ const sourceNodeId = group.node_ids[0]
552
+ const targetId = group.suggested_connection.target_id
553
+ const relType = group.suggested_connection.relationship_type
554
+
555
+ // Verify both nodes exist
556
+ if (!getNode(graph, sourceNodeId) || !getNode(graph, targetId)) return null
557
+
558
+ try {
559
+ addRelationship(graph, sourceNodeId, targetId, relType)
560
+ return {
561
+ action: "merged_group",
562
+ details: `Merged disconnected group (${group.size} nodes: ${group.node_names.slice(0, 3).join(", ")}${group.size > 3 ? "..." : ""}) → "${group.suggested_connection.target_name}" via ${relType}`,
563
+ relationship: { from: sourceNodeId, to: targetId, type: relType },
564
+ }
565
+ } catch {
566
+ return null
567
+ }
568
+ }
569
+
570
+ // ─── Formatting ────────────────────────────────────────────────────
571
+
572
+ export function formatIntegrityReport(report: IntegrityReport): string {
573
+ const lines: string[] = []
574
+
575
+ const emoji = report.summary.graph_connected ? "✅" : "⚠️"
576
+ lines.push(`${emoji} Graph Integrity Report\n`)
577
+
578
+ lines.push(`**Nodes:** ${report.summary.total_nodes}`)
579
+ lines.push(`**Relationships:** ${report.summary.total_relationships}`)
580
+ lines.push(`**Connected:** ${report.summary.graph_connected ? "Yes" : "No"}`)
581
+ lines.push("")
582
+
583
+ if (report.summary.fixes_applied > 0) {
584
+ lines.push(`### 🔧 Fixes Applied (${report.summary.fixes_applied})`)
585
+ for (const fix of report.fixes_applied) {
586
+ lines.push(`- **${fix.action}:** ${fix.details}`)
587
+ }
588
+ lines.push("")
589
+ }
590
+
591
+ if (report.orphan_nodes.length > 0 && report.summary.fixes_applied === 0) {
592
+ lines.push(`### 🔴 Orphan Nodes (${report.orphan_nodes.length})`)
593
+ for (const orphan of report.orphan_nodes.slice(0, 10)) {
594
+ lines.push(`- **${orphan.node_name}** (${orphan.node_type}) [${orphan.node_id}]`)
595
+ }
596
+ if (report.orphan_nodes.length > 10) {
597
+ lines.push(`- ... and ${report.orphan_nodes.length - 10} more`)
598
+ }
599
+ lines.push("")
600
+ }
601
+
602
+ if (report.disconnected_groups.length > 0 && report.summary.fixes_applied === 0) {
603
+ lines.push(`### 🏝️ Disconnected Groups (${report.disconnected_groups.length})`)
604
+ for (const group of report.disconnected_groups) {
605
+ const names = group.node_names.slice(0, 5).join(", ")
606
+ const extra = group.node_names.length > 5 ? ` ... (+${group.node_names.length - 5})` : ""
607
+ lines.push(`- **Group ${group.group_id}** (${group.size} nodes): ${names}${extra}`)
608
+ if (group.suggested_connection) {
609
+ lines.push(` → Suggested: connect to "${group.suggested_connection.target_name}" via ${group.suggested_connection.relationship_type}`)
610
+ }
611
+ }
612
+ lines.push("")
613
+ }
614
+
615
+ if (report.redundant_relationships.length > 0 && report.summary.fixes_applied === 0) {
616
+ lines.push(`### 🔄 Redundant Relationships (${report.redundant_relationships.length})`)
617
+ for (const r of report.redundant_relationships.slice(0, 10)) {
618
+ lines.push(`- ${r.from} → ${r.to} (${r.type}): ${r.reason}`)
619
+ }
620
+ lines.push("")
621
+ }
622
+
623
+ if (report.summary.fixes_applied === 0 && report.summary.graph_connected) {
624
+ lines.push("✅ Graph is fully connected. No issues found.")
625
+ }
626
+
627
+ return lines.join("\n")
628
+ }