@dewtech/dare-cli 3.9.0 → 3.11.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 (254) hide show
  1. package/README.md +5 -0
  2. package/dist/__tests__/ci-pr-regression.test.d.ts +2 -0
  3. package/dist/__tests__/ci-pr-regression.test.d.ts.map +1 -0
  4. package/dist/__tests__/ci-pr-regression.test.js +76 -0
  5. package/dist/__tests__/ci-pr-regression.test.js.map +1 -0
  6. package/dist/__tests__/dashboard-front.test.d.ts +2 -0
  7. package/dist/__tests__/dashboard-front.test.d.ts.map +1 -0
  8. package/dist/__tests__/dashboard-front.test.js +37 -0
  9. package/dist/__tests__/dashboard-front.test.js.map +1 -0
  10. package/dist/__tests__/dashboard-regression.test.d.ts +2 -0
  11. package/dist/__tests__/dashboard-regression.test.d.ts.map +1 -0
  12. package/dist/__tests__/dashboard-regression.test.js +68 -0
  13. package/dist/__tests__/dashboard-regression.test.js.map +1 -0
  14. package/dist/__tests__/drift-regression.test.d.ts +2 -0
  15. package/dist/__tests__/drift-regression.test.d.ts.map +1 -0
  16. package/dist/__tests__/drift-regression.test.js +118 -0
  17. package/dist/__tests__/drift-regression.test.js.map +1 -0
  18. package/dist/__tests__/dynamic-dag-regression.test.d.ts +2 -0
  19. package/dist/__tests__/dynamic-dag-regression.test.d.ts.map +1 -0
  20. package/dist/__tests__/dynamic-dag-regression.test.js +464 -0
  21. package/dist/__tests__/dynamic-dag-regression.test.js.map +1 -0
  22. package/dist/__tests__/ide-command-parity.test.js +1 -0
  23. package/dist/__tests__/ide-command-parity.test.js.map +1 -1
  24. package/dist/__tests__/project-generator.test.js +10 -1
  25. package/dist/__tests__/project-generator.test.js.map +1 -1
  26. package/dist/__tests__/semantic-regression.test.d.ts +2 -0
  27. package/dist/__tests__/semantic-regression.test.d.ts.map +1 -0
  28. package/dist/__tests__/semantic-regression.test.js +248 -0
  29. package/dist/__tests__/semantic-regression.test.js.map +1 -0
  30. package/dist/bin/dare.js +2 -0
  31. package/dist/bin/dare.js.map +1 -1
  32. package/dist/commands/__tests__/dashboard-command.test.d.ts +2 -0
  33. package/dist/commands/__tests__/dashboard-command.test.d.ts.map +1 -0
  34. package/dist/commands/__tests__/dashboard-command.test.js +62 -0
  35. package/dist/commands/__tests__/dashboard-command.test.js.map +1 -0
  36. package/dist/commands/__tests__/execute.telemetry.spec.js +3 -0
  37. package/dist/commands/__tests__/execute.telemetry.spec.js.map +1 -1
  38. package/dist/commands/__tests__/gate-flags.test.d.ts +2 -0
  39. package/dist/commands/__tests__/gate-flags.test.d.ts.map +1 -0
  40. package/dist/commands/__tests__/gate-flags.test.js +58 -0
  41. package/dist/commands/__tests__/gate-flags.test.js.map +1 -0
  42. package/dist/commands/__tests__/graph-drift.test.d.ts +2 -0
  43. package/dist/commands/__tests__/graph-drift.test.d.ts.map +1 -0
  44. package/dist/commands/__tests__/graph-drift.test.js +169 -0
  45. package/dist/commands/__tests__/graph-drift.test.js.map +1 -0
  46. package/dist/commands/__tests__/persist-viz.test.d.ts +2 -0
  47. package/dist/commands/__tests__/persist-viz.test.d.ts.map +1 -0
  48. package/dist/commands/__tests__/persist-viz.test.js +178 -0
  49. package/dist/commands/__tests__/persist-viz.test.js.map +1 -0
  50. package/dist/commands/__tests__/refine-apply.test.d.ts +2 -0
  51. package/dist/commands/__tests__/refine-apply.test.d.ts.map +1 -0
  52. package/dist/commands/__tests__/refine-apply.test.js +118 -0
  53. package/dist/commands/__tests__/refine-apply.test.js.map +1 -0
  54. package/dist/commands/__tests__/replan-splice.test.d.ts +2 -0
  55. package/dist/commands/__tests__/replan-splice.test.d.ts.map +1 -0
  56. package/dist/commands/__tests__/replan-splice.test.js +295 -0
  57. package/dist/commands/__tests__/replan-splice.test.js.map +1 -0
  58. package/dist/commands/dag.d.ts.map +1 -1
  59. package/dist/commands/dag.js +2 -0
  60. package/dist/commands/dag.js.map +1 -1
  61. package/dist/commands/dashboard.d.ts +17 -0
  62. package/dist/commands/dashboard.d.ts.map +1 -0
  63. package/dist/commands/dashboard.js +77 -0
  64. package/dist/commands/dashboard.js.map +1 -0
  65. package/dist/commands/execute.d.ts.map +1 -1
  66. package/dist/commands/execute.js +117 -2
  67. package/dist/commands/execute.js.map +1 -1
  68. package/dist/commands/graph.d.ts.map +1 -1
  69. package/dist/commands/graph.js +232 -1
  70. package/dist/commands/graph.js.map +1 -1
  71. package/dist/commands/guard.d.ts.map +1 -1
  72. package/dist/commands/guard.js +27 -3
  73. package/dist/commands/guard.js.map +1 -1
  74. package/dist/commands/refine.d.ts +2 -0
  75. package/dist/commands/refine.d.ts.map +1 -1
  76. package/dist/commands/refine.js +71 -20
  77. package/dist/commands/refine.js.map +1 -1
  78. package/dist/commands/review.d.ts.map +1 -1
  79. package/dist/commands/review.js +36 -5
  80. package/dist/commands/review.js.map +1 -1
  81. package/dist/dag-runner/__tests__/maxdepth-config.test.d.ts +2 -0
  82. package/dist/dag-runner/__tests__/maxdepth-config.test.d.ts.map +1 -0
  83. package/dist/dag-runner/__tests__/maxdepth-config.test.js +28 -0
  84. package/dist/dag-runner/__tests__/maxdepth-config.test.js.map +1 -0
  85. package/dist/dag-runner/__tests__/sub-dag.test.d.ts +2 -0
  86. package/dist/dag-runner/__tests__/sub-dag.test.d.ts.map +1 -0
  87. package/dist/dag-runner/__tests__/sub-dag.test.js +127 -0
  88. package/dist/dag-runner/__tests__/sub-dag.test.js.map +1 -0
  89. package/dist/dag-runner/graph-ingest.d.ts.map +1 -1
  90. package/dist/dag-runner/graph-ingest.js +13 -7
  91. package/dist/dag-runner/graph-ingest.js.map +1 -1
  92. package/dist/dag-runner/run_dag.d.ts +2 -0
  93. package/dist/dag-runner/run_dag.d.ts.map +1 -1
  94. package/dist/dag-runner/run_dag.js.map +1 -1
  95. package/dist/dag-runner/state-store.d.ts +2 -0
  96. package/dist/dag-runner/state-store.d.ts.map +1 -1
  97. package/dist/dag-runner/state-store.js +44 -8
  98. package/dist/dag-runner/state-store.js.map +1 -1
  99. package/dist/dag-runner/sub-dag.d.ts +23 -0
  100. package/dist/dag-runner/sub-dag.d.ts.map +1 -0
  101. package/dist/dag-runner/sub-dag.js +117 -0
  102. package/dist/dag-runner/sub-dag.js.map +1 -0
  103. package/dist/dashboard/__tests__/dashboard-routes.test.d.ts +2 -0
  104. package/dist/dashboard/__tests__/dashboard-routes.test.d.ts.map +1 -0
  105. package/dist/dashboard/__tests__/dashboard-routes.test.js +102 -0
  106. package/dist/dashboard/__tests__/dashboard-routes.test.js.map +1 -0
  107. package/dist/dashboard/routes.d.ts +8 -0
  108. package/dist/dashboard/routes.d.ts.map +1 -0
  109. package/dist/dashboard/routes.js +70 -0
  110. package/dist/dashboard/routes.js.map +1 -0
  111. package/dist/graphrag/__tests__/drift-config.test.d.ts +2 -0
  112. package/dist/graphrag/__tests__/drift-config.test.d.ts.map +1 -0
  113. package/dist/graphrag/__tests__/drift-config.test.js +33 -0
  114. package/dist/graphrag/__tests__/drift-config.test.js.map +1 -0
  115. package/dist/graphrag/__tests__/drift.test.d.ts +2 -0
  116. package/dist/graphrag/__tests__/drift.test.d.ts.map +1 -0
  117. package/dist/graphrag/__tests__/drift.test.js +152 -0
  118. package/dist/graphrag/__tests__/drift.test.js.map +1 -0
  119. package/dist/graphrag/__tests__/hybrid-integration.test.d.ts +2 -0
  120. package/dist/graphrag/__tests__/hybrid-integration.test.d.ts.map +1 -0
  121. package/dist/graphrag/__tests__/hybrid-integration.test.js +158 -0
  122. package/dist/graphrag/__tests__/hybrid-integration.test.js.map +1 -0
  123. package/dist/graphrag/__tests__/hybrid.test.d.ts +2 -0
  124. package/dist/graphrag/__tests__/hybrid.test.d.ts.map +1 -0
  125. package/dist/graphrag/__tests__/hybrid.test.js +71 -0
  126. package/dist/graphrag/__tests__/hybrid.test.js.map +1 -0
  127. package/dist/graphrag/__tests__/incremental-index.test.d.ts +2 -0
  128. package/dist/graphrag/__tests__/incremental-index.test.d.ts.map +1 -0
  129. package/dist/graphrag/__tests__/incremental-index.test.js +135 -0
  130. package/dist/graphrag/__tests__/incremental-index.test.js.map +1 -0
  131. package/dist/graphrag/__tests__/no-heavy-dep-in-core.test.d.ts +2 -0
  132. package/dist/graphrag/__tests__/no-heavy-dep-in-core.test.d.ts.map +1 -0
  133. package/dist/graphrag/__tests__/no-heavy-dep-in-core.test.js +48 -0
  134. package/dist/graphrag/__tests__/no-heavy-dep-in-core.test.js.map +1 -0
  135. package/dist/graphrag/__tests__/requirement-hash.test.d.ts +2 -0
  136. package/dist/graphrag/__tests__/requirement-hash.test.d.ts.map +1 -0
  137. package/dist/graphrag/__tests__/requirement-hash.test.js +74 -0
  138. package/dist/graphrag/__tests__/requirement-hash.test.js.map +1 -0
  139. package/dist/graphrag/__tests__/semantic-config.test.d.ts +2 -0
  140. package/dist/graphrag/__tests__/semantic-config.test.d.ts.map +1 -0
  141. package/dist/graphrag/__tests__/semantic-config.test.js +39 -0
  142. package/dist/graphrag/__tests__/semantic-config.test.js.map +1 -0
  143. package/dist/graphrag/__tests__/vector-persistence.test.d.ts +2 -0
  144. package/dist/graphrag/__tests__/vector-persistence.test.d.ts.map +1 -0
  145. package/dist/graphrag/__tests__/vector-persistence.test.js +112 -0
  146. package/dist/graphrag/__tests__/vector-persistence.test.js.map +1 -0
  147. package/dist/graphrag/__tests__/vector-search.test.d.ts +2 -0
  148. package/dist/graphrag/__tests__/vector-search.test.d.ts.map +1 -0
  149. package/dist/graphrag/__tests__/vector-search.test.js +36 -0
  150. package/dist/graphrag/__tests__/vector-search.test.js.map +1 -0
  151. package/dist/graphrag/drift.d.ts +22 -0
  152. package/dist/graphrag/drift.d.ts.map +1 -0
  153. package/dist/graphrag/drift.js +204 -0
  154. package/dist/graphrag/drift.js.map +1 -0
  155. package/dist/graphrag/embeddings.d.ts +15 -0
  156. package/dist/graphrag/embeddings.d.ts.map +1 -0
  157. package/dist/graphrag/embeddings.js +107 -0
  158. package/dist/graphrag/embeddings.js.map +1 -0
  159. package/dist/graphrag/graph-rag.d.ts +17 -1
  160. package/dist/graphrag/graph-rag.d.ts.map +1 -1
  161. package/dist/graphrag/graph-rag.js +170 -2
  162. package/dist/graphrag/graph-rag.js.map +1 -1
  163. package/dist/graphrag/hybrid.d.ts +8 -0
  164. package/dist/graphrag/hybrid.d.ts.map +1 -0
  165. package/dist/graphrag/hybrid.js +203 -0
  166. package/dist/graphrag/hybrid.js.map +1 -0
  167. package/dist/graphrag/incremental-index.d.ts +18 -0
  168. package/dist/graphrag/incremental-index.d.ts.map +1 -0
  169. package/dist/graphrag/incremental-index.js +159 -0
  170. package/dist/graphrag/incremental-index.js.map +1 -0
  171. package/dist/graphrag/index.d.ts +1 -1
  172. package/dist/graphrag/index.d.ts.map +1 -1
  173. package/dist/graphrag/json-graph.d.ts +2 -1
  174. package/dist/graphrag/json-graph.d.ts.map +1 -1
  175. package/dist/graphrag/json-graph.js +14 -0
  176. package/dist/graphrag/json-graph.js.map +1 -1
  177. package/dist/graphrag/knowledge-graph.d.ts +5 -0
  178. package/dist/graphrag/knowledge-graph.d.ts.map +1 -1
  179. package/dist/graphrag/neo4j-graph.d.ts +2 -1
  180. package/dist/graphrag/neo4j-graph.d.ts.map +1 -1
  181. package/dist/graphrag/neo4j-graph.js +40 -5
  182. package/dist/graphrag/neo4j-graph.js.map +1 -1
  183. package/dist/graphrag/requirement-ingest.d.ts +4 -1
  184. package/dist/graphrag/requirement-ingest.d.ts.map +1 -1
  185. package/dist/graphrag/requirement-ingest.js +18 -8
  186. package/dist/graphrag/requirement-ingest.js.map +1 -1
  187. package/dist/graphrag/types.d.ts +1 -0
  188. package/dist/graphrag/types.d.ts.map +1 -1
  189. package/dist/graphrag/vector-search.d.ts +10 -0
  190. package/dist/graphrag/vector-search.d.ts.map +1 -0
  191. package/dist/graphrag/vector-search.js +38 -0
  192. package/dist/graphrag/vector-search.js.map +1 -0
  193. package/dist/http/__tests__/shared-app.test.d.ts +2 -0
  194. package/dist/http/__tests__/shared-app.test.d.ts.map +1 -0
  195. package/dist/http/__tests__/shared-app.test.js +57 -0
  196. package/dist/http/__tests__/shared-app.test.js.map +1 -0
  197. package/dist/http/app.d.ts +15 -0
  198. package/dist/http/app.d.ts.map +1 -0
  199. package/dist/http/app.js +32 -0
  200. package/dist/http/app.js.map +1 -0
  201. package/dist/mcp-server/server.d.ts.map +1 -1
  202. package/dist/mcp-server/server.js +13 -16
  203. package/dist/mcp-server/server.js.map +1 -1
  204. package/dist/reporters/__tests__/github-reporter.test.d.ts +2 -0
  205. package/dist/reporters/__tests__/github-reporter.test.d.ts.map +1 -0
  206. package/dist/reporters/__tests__/github-reporter.test.js +93 -0
  207. package/dist/reporters/__tests__/github-reporter.test.js.map +1 -0
  208. package/dist/reporters/ci-gate.d.ts +27 -0
  209. package/dist/reporters/ci-gate.d.ts.map +1 -0
  210. package/dist/reporters/ci-gate.js +100 -0
  211. package/dist/reporters/ci-gate.js.map +1 -0
  212. package/dist/reporters/github.d.ts +36 -0
  213. package/dist/reporters/github.d.ts.map +1 -0
  214. package/dist/reporters/github.js +142 -0
  215. package/dist/reporters/github.js.map +1 -0
  216. package/dist/telemetry/__tests__/aggregator.test.d.ts +2 -0
  217. package/dist/telemetry/__tests__/aggregator.test.d.ts.map +1 -0
  218. package/dist/telemetry/__tests__/aggregator.test.js +164 -0
  219. package/dist/telemetry/__tests__/aggregator.test.js.map +1 -0
  220. package/dist/telemetry/aggregator.d.ts +43 -0
  221. package/dist/telemetry/aggregator.d.ts.map +1 -0
  222. package/dist/telemetry/aggregator.js +282 -0
  223. package/dist/telemetry/aggregator.js.map +1 -0
  224. package/dist/utils/UpdateApplier.d.ts.map +1 -1
  225. package/dist/utils/UpdateApplier.js +3 -1
  226. package/dist/utils/UpdateApplier.js.map +1 -1
  227. package/dist/utils/excalidraw-renderer.d.ts.map +1 -1
  228. package/dist/utils/excalidraw-renderer.js +1 -0
  229. package/dist/utils/excalidraw-renderer.js.map +1 -1
  230. package/dist/utils/graph-renderer.d.ts +2 -0
  231. package/dist/utils/graph-renderer.d.ts.map +1 -1
  232. package/dist/utils/graph-renderer.js +188 -14
  233. package/dist/utils/graph-renderer.js.map +1 -1
  234. package/dist/utils/project-generator.d.ts.map +1 -1
  235. package/dist/utils/project-generator.js +34 -5
  236. package/dist/utils/project-generator.js.map +1 -1
  237. package/dist/verification/__tests__/decay-policy.test.js +1 -0
  238. package/dist/verification/__tests__/decay-policy.test.js.map +1 -1
  239. package/dist/verification/__tests__/telemetry.test.js +3 -0
  240. package/dist/verification/__tests__/telemetry.test.js.map +1 -1
  241. package/dist/verification/config.d.ts +82 -0
  242. package/dist/verification/config.d.ts.map +1 -1
  243. package/dist/verification/config.js +148 -0
  244. package/dist/verification/config.js.map +1 -1
  245. package/dist/verification/types.d.ts +2 -0
  246. package/dist/verification/types.d.ts.map +1 -1
  247. package/package.json +3 -2
  248. package/templates/.github/workflows/dare-pr.yml +26 -0
  249. package/templates/dashboard/app.js +184 -0
  250. package/templates/dashboard/index.html +63 -0
  251. package/templates/dashboard/style.css +134 -0
  252. package/templates/ide/antigravity/.agents/skills/dare-dashboard/SKILL.md +18 -0
  253. package/templates/ide/claude/.claude/commands/dare-dashboard.md +18 -0
  254. package/templates/ide/cursor/.cursor/commands/dare-dashboard.md +18 -0
@@ -0,0 +1,152 @@
1
+ import os from 'node:os';
2
+ import path from 'node:path';
3
+ import { beforeEach, afterEach, describe, expect, it } from 'vitest';
4
+ import { JsonGraph } from '../json-graph.js';
5
+ import { detectDrift } from '../drift.js';
6
+ describe('detectDrift', () => {
7
+ let graph;
8
+ beforeEach(async () => {
9
+ const filePath = path.join(os.tmpdir(), `drift-${Date.now()}-${Math.random().toString(16).slice(2)}.json`);
10
+ graph = new JsonGraph(filePath);
11
+ await graph.init();
12
+ });
13
+ afterEach(() => {
14
+ graph.close();
15
+ });
16
+ it('detects_orphan_requirement', () => {
17
+ graph.addNode({
18
+ id: 'requirement:RF-01',
19
+ type: 'requirement',
20
+ label: 'RF-01',
21
+ metadata: { contentHash: 'hash-rf-01', ingestedAt: '2026-01-01T00:00:00.000Z' },
22
+ });
23
+ const report = detectDrift(graph, enabledConfig());
24
+ expect(report.counts['orphan-requirement']).toBe(1);
25
+ expect(report.findings).toContainEqual(expect.objectContaining({
26
+ kind: 'orphan-requirement',
27
+ nodeId: 'requirement:RF-01',
28
+ }));
29
+ });
30
+ it('detects_orphan_code', () => {
31
+ graph.addNode({
32
+ id: 'code_symbol:src/entry/index.ts::main',
33
+ type: 'code_symbol',
34
+ label: 'main',
35
+ metadata: {
36
+ path: 'src/entry/index.ts',
37
+ qualifiedName: 'src/entry/index.ts::main',
38
+ },
39
+ });
40
+ graph.addNode({
41
+ id: 'code_symbol:src/services/auth.ts::authorize',
42
+ type: 'code_symbol',
43
+ label: 'authorize',
44
+ metadata: {
45
+ path: 'src/services/auth.ts',
46
+ qualifiedName: 'src/services/auth.ts::authorize',
47
+ },
48
+ });
49
+ const report = detectDrift(graph, enabledConfig({ ignore: ['**/entry/**', '**/index.ts'] }));
50
+ expect(report.counts['orphan-code']).toBe(1);
51
+ expect(report.findings).toContainEqual(expect.objectContaining({
52
+ kind: 'orphan-code',
53
+ nodeId: 'code_symbol:src/services/auth.ts::authorize',
54
+ }));
55
+ });
56
+ it('detects_stale_when_hash_changed', () => {
57
+ graph.addNode({
58
+ id: 'requirement:RF-02',
59
+ type: 'requirement',
60
+ label: 'RF-02',
61
+ metadata: { contentHash: 'new-hash', ingestedAt: '2026-01-05T00:00:00.000Z' },
62
+ });
63
+ graph.addNode({
64
+ id: 'code_symbol:src/auth.ts::login',
65
+ type: 'code_symbol',
66
+ label: 'login',
67
+ metadata: {
68
+ qualifiedName: 'src/auth.ts::login',
69
+ requirementContentHash: 'old-hash',
70
+ ingestedAt: '2026-01-01T00:00:00.000Z',
71
+ },
72
+ });
73
+ graph.addEdge({
74
+ id: 'implements:login->rf02',
75
+ sourceId: 'code_symbol:src/auth.ts::login',
76
+ targetId: 'requirement:RF-02',
77
+ type: 'implements',
78
+ });
79
+ const report = detectDrift(graph, enabledConfig());
80
+ expect(report.counts.stale).toBe(1);
81
+ expect(report.findings).toContainEqual(expect.objectContaining({
82
+ kind: 'stale',
83
+ nodeId: 'requirement:RF-02',
84
+ }));
85
+ });
86
+ it('counts_staleIndeterminate_without_hash', () => {
87
+ graph.addNode({
88
+ id: 'requirement:RF-03',
89
+ type: 'requirement',
90
+ label: 'RF-03',
91
+ metadata: { ingestedAt: '2026-01-05T00:00:00.000Z' },
92
+ });
93
+ graph.addNode({
94
+ id: 'code_symbol:src/orders.ts::checkout',
95
+ type: 'code_symbol',
96
+ label: 'checkout',
97
+ metadata: { qualifiedName: 'src/orders.ts::checkout', ingestedAt: '2026-01-01T00:00:00.000Z' },
98
+ });
99
+ graph.addEdge({
100
+ id: 'implements:checkout->rf03',
101
+ sourceId: 'code_symbol:src/orders.ts::checkout',
102
+ targetId: 'requirement:RF-03',
103
+ type: 'implements',
104
+ });
105
+ const report = detectDrift(graph, enabledConfig());
106
+ expect(report.staleIndeterminate).toBe(1);
107
+ expect(report.counts.stale).toBe(0);
108
+ });
109
+ it('clean_graph_no_findings', () => {
110
+ graph.addNode({
111
+ id: 'requirement:RF-04',
112
+ type: 'requirement',
113
+ label: 'RF-04',
114
+ metadata: { contentHash: 'stable-hash', ingestedAt: '2026-01-01T00:00:00.000Z' },
115
+ });
116
+ graph.addNode({
117
+ id: 'code_symbol:src/billing.ts::charge',
118
+ type: 'code_symbol',
119
+ label: 'charge',
120
+ metadata: {
121
+ qualifiedName: 'src/billing.ts::charge',
122
+ requirementContentHash: 'stable-hash',
123
+ ingestedAt: '2026-01-02T00:00:00.000Z',
124
+ },
125
+ });
126
+ graph.addEdge({
127
+ id: 'implements:charge->rf04',
128
+ sourceId: 'code_symbol:src/billing.ts::charge',
129
+ targetId: 'requirement:RF-04',
130
+ type: 'implements',
131
+ });
132
+ const report = detectDrift(graph, enabledConfig());
133
+ expect(report.findings).toEqual([]);
134
+ expect(report.counts).toEqual({
135
+ 'orphan-requirement': 0,
136
+ 'orphan-code': 0,
137
+ stale: 0,
138
+ });
139
+ expect(report.staleIndeterminate).toBe(0);
140
+ });
141
+ });
142
+ function enabledConfig(overrides = {}) {
143
+ return {
144
+ enabled: true,
145
+ maxOrphanReqs: 0,
146
+ maxOrphanCode: 0,
147
+ failOnStale: false,
148
+ ignore: [],
149
+ ...overrides,
150
+ };
151
+ }
152
+ //# sourceMappingURL=drift.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"drift.test.js","sourceRoot":"","sources":["../../../src/graphrag/__tests__/drift.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AACrE,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,WAAW,EAAoB,MAAM,aAAa,CAAC;AAE5D,QAAQ,CAAC,aAAa,EAAE,GAAG,EAAE;IAC3B,IAAI,KAAgB,CAAC;IAErB,UAAU,CAAC,KAAK,IAAI,EAAE;QACpB,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CACxB,EAAE,CAAC,MAAM,EAAE,EACX,SAAS,IAAI,CAAC,GAAG,EAAE,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAClE,CAAC;QACF,KAAK,GAAG,IAAI,SAAS,CAAC,QAAQ,CAAC,CAAC;QAChC,MAAM,KAAK,CAAC,IAAI,EAAE,CAAC;IACrB,CAAC,CAAC,CAAC;IAEH,SAAS,CAAC,GAAG,EAAE;QACb,KAAK,CAAC,KAAK,EAAE,CAAC;IAChB,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,4BAA4B,EAAE,GAAG,EAAE;QACpC,KAAK,CAAC,OAAO,CAAC;YACZ,EAAE,EAAE,mBAAmB;YACvB,IAAI,EAAE,aAAa;YACnB,KAAK,EAAE,OAAO;YACd,QAAQ,EAAE,EAAE,WAAW,EAAE,YAAY,EAAE,UAAU,EAAE,0BAA0B,EAAE;SAChF,CAAC,CAAC;QAEH,MAAM,MAAM,GAAG,WAAW,CAAC,KAAK,EAAE,aAAa,EAAE,CAAC,CAAC;QAEnD,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACpD,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,cAAc,CACpC,MAAM,CAAC,gBAAgB,CAAC;YACtB,IAAI,EAAE,oBAAoB;YAC1B,MAAM,EAAE,mBAAmB;SAC5B,CAAC,CACH,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qBAAqB,EAAE,GAAG,EAAE;QAC7B,KAAK,CAAC,OAAO,CAAC;YACZ,EAAE,EAAE,sCAAsC;YAC1C,IAAI,EAAE,aAAa;YACnB,KAAK,EAAE,MAAM;YACb,QAAQ,EAAE;gBACR,IAAI,EAAE,oBAAoB;gBAC1B,aAAa,EAAE,0BAA0B;aAC1C;SACF,CAAC,CAAC;QACH,KAAK,CAAC,OAAO,CAAC;YACZ,EAAE,EAAE,6CAA6C;YACjD,IAAI,EAAE,aAAa;YACnB,KAAK,EAAE,WAAW;YAClB,QAAQ,EAAE;gBACR,IAAI,EAAE,sBAAsB;gBAC5B,aAAa,EAAE,iCAAiC;aACjD;SACF,CAAC,CAAC;QAEH,MAAM,MAAM,GAAG,WAAW,CAAC,KAAK,EAAE,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC,aAAa,EAAE,aAAa,CAAC,EAAE,CAAC,CAAC,CAAC;QAE7F,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC7C,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,cAAc,CACpC,MAAM,CAAC,gBAAgB,CAAC;YACtB,IAAI,EAAE,aAAa;YACnB,MAAM,EAAE,6CAA6C;SACtD,CAAC,CACH,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iCAAiC,EAAE,GAAG,EAAE;QACzC,KAAK,CAAC,OAAO,CAAC;YACZ,EAAE,EAAE,mBAAmB;YACvB,IAAI,EAAE,aAAa;YACnB,KAAK,EAAE,OAAO;YACd,QAAQ,EAAE,EAAE,WAAW,EAAE,UAAU,EAAE,UAAU,EAAE,0BAA0B,EAAE;SAC9E,CAAC,CAAC;QACH,KAAK,CAAC,OAAO,CAAC;YACZ,EAAE,EAAE,gCAAgC;YACpC,IAAI,EAAE,aAAa;YACnB,KAAK,EAAE,OAAO;YACd,QAAQ,EAAE;gBACR,aAAa,EAAE,oBAAoB;gBACnC,sBAAsB,EAAE,UAAU;gBAClC,UAAU,EAAE,0BAA0B;aACvC;SACF,CAAC,CAAC;QACH,KAAK,CAAC,OAAO,CAAC;YACZ,EAAE,EAAE,wBAAwB;YAC5B,QAAQ,EAAE,gCAAgC;YAC1C,QAAQ,EAAE,mBAAmB;YAC7B,IAAI,EAAE,YAAY;SACnB,CAAC,CAAC;QAEH,MAAM,MAAM,GAAG,WAAW,CAAC,KAAK,EAAE,aAAa,EAAE,CAAC,CAAC;QAEnD,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACpC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,cAAc,CACpC,MAAM,CAAC,gBAAgB,CAAC;YACtB,IAAI,EAAE,OAAO;YACb,MAAM,EAAE,mBAAmB;SAC5B,CAAC,CACH,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wCAAwC,EAAE,GAAG,EAAE;QAChD,KAAK,CAAC,OAAO,CAAC;YACZ,EAAE,EAAE,mBAAmB;YACvB,IAAI,EAAE,aAAa;YACnB,KAAK,EAAE,OAAO;YACd,QAAQ,EAAE,EAAE,UAAU,EAAE,0BAA0B,EAAE;SACrD,CAAC,CAAC;QACH,KAAK,CAAC,OAAO,CAAC;YACZ,EAAE,EAAE,qCAAqC;YACzC,IAAI,EAAE,aAAa;YACnB,KAAK,EAAE,UAAU;YACjB,QAAQ,EAAE,EAAE,aAAa,EAAE,yBAAyB,EAAE,UAAU,EAAE,0BAA0B,EAAE;SAC/F,CAAC,CAAC;QACH,KAAK,CAAC,OAAO,CAAC;YACZ,EAAE,EAAE,2BAA2B;YAC/B,QAAQ,EAAE,qCAAqC;YAC/C,QAAQ,EAAE,mBAAmB;YAC7B,IAAI,EAAE,YAAY;SACnB,CAAC,CAAC;QAEH,MAAM,MAAM,GAAG,WAAW,CAAC,KAAK,EAAE,aAAa,EAAE,CAAC,CAAC;QAEnD,MAAM,CAAC,MAAM,CAAC,kBAAkB,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC1C,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACtC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,yBAAyB,EAAE,GAAG,EAAE;QACjC,KAAK,CAAC,OAAO,CAAC;YACZ,EAAE,EAAE,mBAAmB;YACvB,IAAI,EAAE,aAAa;YACnB,KAAK,EAAE,OAAO;YACd,QAAQ,EAAE,EAAE,WAAW,EAAE,aAAa,EAAE,UAAU,EAAE,0BAA0B,EAAE;SACjF,CAAC,CAAC;QACH,KAAK,CAAC,OAAO,CAAC;YACZ,EAAE,EAAE,oCAAoC;YACxC,IAAI,EAAE,aAAa;YACnB,KAAK,EAAE,QAAQ;YACf,QAAQ,EAAE;gBACR,aAAa,EAAE,wBAAwB;gBACvC,sBAAsB,EAAE,aAAa;gBACrC,UAAU,EAAE,0BAA0B;aACvC;SACF,CAAC,CAAC;QACH,KAAK,CAAC,OAAO,CAAC;YACZ,EAAE,EAAE,yBAAyB;YAC7B,QAAQ,EAAE,oCAAoC;YAC9C,QAAQ,EAAE,mBAAmB;YAC7B,IAAI,EAAE,YAAY;SACnB,CAAC,CAAC;QAEH,MAAM,MAAM,GAAG,WAAW,CAAC,KAAK,EAAE,aAAa,EAAE,CAAC,CAAC;QAEnD,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QACpC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC;YAC5B,oBAAoB,EAAE,CAAC;YACvB,aAAa,EAAE,CAAC;YAChB,KAAK,EAAE,CAAC;SACT,CAAC,CAAC;QACH,MAAM,CAAC,MAAM,CAAC,kBAAkB,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAC5C,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,SAAS,aAAa,CAAC,YAAkC,EAAE;IACzD,OAAO;QACL,OAAO,EAAE,IAAI;QACb,aAAa,EAAE,CAAC;QAChB,aAAa,EAAE,CAAC;QAChB,WAAW,EAAE,KAAK;QAClB,MAAM,EAAE,EAAE;QACV,GAAG,SAAS;KACb,CAAC;AACJ,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=hybrid-integration.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hybrid-integration.test.d.ts","sourceRoot":"","sources":["../../../src/graphrag/__tests__/hybrid-integration.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,158 @@
1
+ import os from 'node:os';
2
+ import path from 'node:path';
3
+ import fs from 'fs-extra';
4
+ import request from 'supertest';
5
+ import { afterEach, describe, expect, it, vi } from 'vitest';
6
+ import { createMcpServer } from '../../mcp-server/server.js';
7
+ import { GraphRAG } from '../graph-rag.js';
8
+ const mocks = vi.hoisted(() => ({
9
+ loadEmbedder: vi.fn(),
10
+ hybridSearch: vi.fn(),
11
+ }));
12
+ vi.mock('../embeddings.js', async () => {
13
+ const actual = await vi.importActual('../embeddings.js');
14
+ return {
15
+ ...actual,
16
+ loadEmbedder: mocks.loadEmbedder,
17
+ };
18
+ });
19
+ vi.mock('../hybrid.js', async () => {
20
+ const actual = await vi.importActual('../hybrid.js');
21
+ return {
22
+ ...actual,
23
+ hybridSearch: mocks.hybridSearch,
24
+ };
25
+ });
26
+ async function createFixture(semanticEnabled) {
27
+ const projectRoot = await fs.mkdtemp(path.join(os.tmpdir(), 'hybrid-integration-'));
28
+ await fs.ensureDir(path.join(projectRoot, 'DARE'));
29
+ await fs.writeJson(path.join(projectRoot, 'dare.config.json'), {
30
+ graphrag: {
31
+ backend: 'sqlite',
32
+ semantic: {
33
+ enabled: semanticEnabled,
34
+ model: 'all-MiniLM-L6-v2',
35
+ rrfK: 60,
36
+ },
37
+ },
38
+ });
39
+ const dbPath = path.join(projectRoot, '.dare', 'graph.db');
40
+ const graph = new GraphRAG(dbPath);
41
+ await graph.init();
42
+ graph.addNode({
43
+ id: 'task:alpha',
44
+ type: 'task',
45
+ label: 'Alpha keyword hit',
46
+ description: 'keyword fallback candidate',
47
+ });
48
+ graph.addNode({
49
+ id: 'code_symbol:src/semantic.ts::search',
50
+ type: 'code_symbol',
51
+ label: 'semantic-search',
52
+ description: 'semantic candidate',
53
+ metadata: {
54
+ qualifiedName: 'src/semantic.ts::search',
55
+ path: 'src/semantic.ts',
56
+ symbol: 'search',
57
+ kind: 'function',
58
+ },
59
+ });
60
+ return {
61
+ projectRoot,
62
+ graph,
63
+ async cleanup() {
64
+ await Promise.resolve(graph.close());
65
+ await fs.remove(projectRoot).catch(() => undefined);
66
+ },
67
+ };
68
+ }
69
+ afterEach(() => {
70
+ mocks.loadEmbedder.mockReset();
71
+ mocks.hybridSearch.mockReset();
72
+ vi.restoreAllMocks();
73
+ });
74
+ describe('hybrid integration', () => {
75
+ it('enabled_uses_hybrid', async () => {
76
+ const fixture = await createFixture(true);
77
+ try {
78
+ mocks.loadEmbedder.mockResolvedValue({
79
+ dim: 2,
80
+ async embed() {
81
+ return new Float32Array([1, 0]);
82
+ },
83
+ });
84
+ const semanticNode = fixture.graph.getNode('code_symbol:src/semantic.ts::search');
85
+ mocks.hybridSearch.mockResolvedValue([
86
+ {
87
+ node: semanticNode,
88
+ score: 0.99,
89
+ snippet: 'semantic',
90
+ },
91
+ ]);
92
+ const ranked = await fixture.graph.searchNodesHybrid('semantic target', 5);
93
+ expect(mocks.loadEmbedder).toHaveBeenCalledTimes(1);
94
+ expect(mocks.hybridSearch).toHaveBeenCalledTimes(1);
95
+ expect(ranked[0]?.node.id).toBe('code_symbol:src/semantic.ts::search');
96
+ }
97
+ finally {
98
+ await fixture.cleanup();
99
+ }
100
+ });
101
+ it('disabled_uses_keyword', async () => {
102
+ const fixture = await createFixture(false);
103
+ try {
104
+ const ranked = await fixture.graph.searchNodesHybrid('alpha', 5);
105
+ expect(ranked.map((entry) => entry.node.id)).toContain('task:alpha');
106
+ expect(mocks.loadEmbedder).not.toHaveBeenCalled();
107
+ expect(mocks.hybridSearch).not.toHaveBeenCalled();
108
+ }
109
+ finally {
110
+ await fixture.cleanup();
111
+ }
112
+ });
113
+ it('fallback_when_model_missing', async () => {
114
+ const fixture = await createFixture(true);
115
+ try {
116
+ const { EmbeddingModelMissingError } = await import('../embeddings.js');
117
+ mocks.loadEmbedder.mockRejectedValueOnce(new EmbeddingModelMissingError('@huggingface/transformers'));
118
+ const logSpy = vi.spyOn(console, 'info').mockImplementation(() => undefined);
119
+ const ranked = await fixture.graph.searchNodesHybrid('alpha', 5);
120
+ expect(ranked.map((entry) => entry.node.id)).toContain('task:alpha');
121
+ expect(mocks.hybridSearch).not.toHaveBeenCalled();
122
+ expect(logSpy).toHaveBeenCalled();
123
+ }
124
+ finally {
125
+ await fixture.cleanup();
126
+ }
127
+ });
128
+ it('mcp_graph_locate_hybrid', async () => {
129
+ const fixture = await createFixture(true);
130
+ try {
131
+ mocks.loadEmbedder.mockResolvedValue({
132
+ dim: 2,
133
+ async embed() {
134
+ return new Float32Array([1, 0]);
135
+ },
136
+ });
137
+ const semanticNode = fixture.graph.getNode('code_symbol:src/semantic.ts::search');
138
+ mocks.hybridSearch.mockResolvedValue([
139
+ {
140
+ node: semanticNode,
141
+ score: 0.98,
142
+ snippet: 'semantic locate',
143
+ },
144
+ ]);
145
+ const app = createMcpServer(fixture.projectRoot, { allowLoopbackWithoutToken: true });
146
+ const res = await request(app).post('/graph/locate').send({ seed: 'semantic target' });
147
+ expect(res.status).toBe(200);
148
+ expect(res.body.success).toBe(true);
149
+ const ids = res.body.candidates.map((c) => c.node.id);
150
+ expect(ids).toContain('code_symbol:src/semantic.ts::search');
151
+ expect(mocks.hybridSearch).toHaveBeenCalled();
152
+ }
153
+ finally {
154
+ await fixture.cleanup();
155
+ }
156
+ });
157
+ });
158
+ //# sourceMappingURL=hybrid-integration.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hybrid-integration.test.js","sourceRoot":"","sources":["../../../src/graphrag/__tests__/hybrid-integration.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=hybrid.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hybrid.test.d.ts","sourceRoot":"","sources":["../../../src/graphrag/__tests__/hybrid.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,71 @@
1
+ import os from 'node:os';
2
+ import path from 'node:path';
3
+ import { afterEach, beforeEach, describe, expect, it } from 'vitest';
4
+ import { JsonGraph } from '../json-graph.js';
5
+ import { hybridSearch } from '../hybrid.js';
6
+ function createEmbedder(vector) {
7
+ return {
8
+ dim: vector.length,
9
+ async embed() {
10
+ return vector;
11
+ },
12
+ };
13
+ }
14
+ describe('hybridSearch', () => {
15
+ let graph;
16
+ beforeEach(async () => {
17
+ const file = path.join(os.tmpdir(), `hybrid-${Date.now()}-${Math.random()}.json`);
18
+ graph = new JsonGraph(file);
19
+ await graph.init();
20
+ graph.addNode({
21
+ id: 'node:a',
22
+ type: 'task',
23
+ label: 'Alpha keyword champion',
24
+ description: 'alpha dominates keyword list',
25
+ });
26
+ graph.addNode({
27
+ id: 'node:b',
28
+ type: 'file',
29
+ label: 'Beta semantic winner',
30
+ description: 'vector-only candidate',
31
+ metadata: { vector: [1, 0] },
32
+ });
33
+ graph.addNode({
34
+ id: 'node:c',
35
+ type: 'code_symbol',
36
+ label: 'Gamma balanced candidate',
37
+ description: 'good in keyword and vector',
38
+ metadata: { vector: [0.9, 0.1] },
39
+ });
40
+ graph.addEdge({
41
+ id: 'edge:a-c',
42
+ sourceId: 'node:a',
43
+ targetId: 'node:c',
44
+ type: 'related_to',
45
+ });
46
+ });
47
+ afterEach(() => {
48
+ graph.close();
49
+ });
50
+ it('rrf_combines_three_lists', async () => {
51
+ const embedder = createEmbedder(new Float32Array([1, 0]));
52
+ const ranked = await hybridSearch(graph, embedder, 'keyword', { k: 3, rrfK: 60 });
53
+ expect(ranked.map((item) => item.node.id)).toEqual(['node:c', 'node:a', 'node:b']);
54
+ expect(ranked[0]?.score).toBeGreaterThan(ranked[1]?.score ?? -Infinity);
55
+ expect(ranked[1]?.score).toBeGreaterThan(ranked[2]?.score ?? -Infinity);
56
+ });
57
+ it('fallback_keyword_when_no_embedder', async () => {
58
+ const keywordOnly = graph.searchNodes('keyword', 3);
59
+ const ranked = await hybridSearch(graph, null, 'keyword', { k: 3, rrfK: 60 });
60
+ expect(ranked).toEqual(keywordOnly);
61
+ });
62
+ it('respects_rrfK_and_k', async () => {
63
+ const embedder = createEmbedder(new Float32Array([1, 0]));
64
+ const tight = await hybridSearch(graph, embedder, 'keyword', { k: 2, rrfK: 1 });
65
+ const loose = await hybridSearch(graph, embedder, 'keyword', { k: 2, rrfK: 100 });
66
+ expect(tight).toHaveLength(2);
67
+ expect(loose).toHaveLength(2);
68
+ expect(tight[0]?.score).toBeGreaterThan(loose[0]?.score ?? Infinity);
69
+ });
70
+ });
71
+ //# sourceMappingURL=hybrid.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hybrid.test.js","sourceRoot":"","sources":["../../../src/graphrag/__tests__/hybrid.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=incremental-index.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"incremental-index.test.d.ts","sourceRoot":"","sources":["../../../src/graphrag/__tests__/incremental-index.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,135 @@
1
+ import os from 'node:os';
2
+ import path from 'node:path';
3
+ import { createHash } from 'node:crypto';
4
+ import fs from 'fs-extra';
5
+ import { afterEach, describe, expect, it, vi } from 'vitest';
6
+ import { JsonGraph } from '../json-graph.js';
7
+ import { runIncrementalSemanticIndex } from '../incremental-index.js';
8
+ const cleanupRoots = [];
9
+ async function createFixture(semanticEnabled) {
10
+ const root = await fs.mkdtemp(path.join(os.tmpdir(), 'incremental-index-'));
11
+ cleanupRoots.push(root);
12
+ await fs.writeJson(path.join(root, 'dare.config.json'), {
13
+ graphrag: {
14
+ backend: 'json',
15
+ semantic: {
16
+ enabled: semanticEnabled,
17
+ model: 'all-MiniLM-L6-v2',
18
+ modelHash: 'test-model-hash',
19
+ rrfK: 60,
20
+ },
21
+ },
22
+ });
23
+ const graph = new JsonGraph(path.join(root, '.dare', 'graph.json'));
24
+ await graph.init();
25
+ return { root, graph };
26
+ }
27
+ function hash(text) {
28
+ return createHash('sha256').update(text).digest('hex');
29
+ }
30
+ afterEach(async () => {
31
+ for (const root of cleanupRoots.splice(0, cleanupRoots.length)) {
32
+ await fs.remove(root).catch(() => undefined);
33
+ }
34
+ });
35
+ describe('incremental-index', () => {
36
+ it('unchanged_node_not_reembedded', async () => {
37
+ const { root, graph } = await createFixture(true);
38
+ const nodeId = 'code_symbol:src/orders.ts::checkout';
39
+ const stableHash = hash('stable-node');
40
+ graph.addNode({
41
+ id: nodeId,
42
+ type: 'code_symbol',
43
+ label: 'checkout',
44
+ description: 'src/orders.ts::checkout',
45
+ vector: [0.1, 0.2],
46
+ metadata: {
47
+ qualifiedName: 'src/orders.ts::checkout',
48
+ symbol: 'checkout',
49
+ kind: 'function',
50
+ contentHash: stableHash,
51
+ vectorContentHash: stableHash,
52
+ },
53
+ });
54
+ const embedSpy = vi.fn(async () => new Float32Array([9, 9]));
55
+ const result = await runIncrementalSemanticIndex(graph, root, {
56
+ loadEmbedderFn: async () => ({ dim: 2, embed: embedSpy }),
57
+ });
58
+ expect(result.semanticEnabled).toBe(true);
59
+ expect(result.scanned).toBe(1);
60
+ expect(result.embedded).toBe(0);
61
+ expect(result.skippedUnchanged).toBe(1);
62
+ expect(embedSpy).not.toHaveBeenCalled();
63
+ });
64
+ it('changed_node_reembedded', async () => {
65
+ const { root, graph } = await createFixture(true);
66
+ const nodeId = 'code_symbol:src/orders.ts::checkout';
67
+ const oldHash = hash('checkout-v1');
68
+ const newHash = hash('checkout-v2');
69
+ graph.addNode({
70
+ id: nodeId,
71
+ type: 'code_symbol',
72
+ label: 'checkout',
73
+ description: 'src/orders.ts::checkout',
74
+ vector: [0.01, 0.02],
75
+ metadata: {
76
+ qualifiedName: 'src/orders.ts::checkout',
77
+ symbol: 'checkout',
78
+ kind: 'function',
79
+ contentHash: oldHash,
80
+ vectorContentHash: oldHash,
81
+ },
82
+ });
83
+ graph.addNode({
84
+ id: nodeId,
85
+ type: 'code_symbol',
86
+ label: 'checkout',
87
+ description: 'src/orders.ts::checkout',
88
+ metadata: {
89
+ qualifiedName: 'src/orders.ts::checkout',
90
+ symbol: 'checkout',
91
+ kind: 'function',
92
+ contentHash: newHash,
93
+ vectorContentHash: oldHash,
94
+ },
95
+ });
96
+ const embedSpy = vi.fn(async () => new Float32Array([0.9, 0.1]));
97
+ const result = await runIncrementalSemanticIndex(graph, root, {
98
+ loadEmbedderFn: async () => ({ dim: 2, embed: embedSpy }),
99
+ });
100
+ expect(result.semanticEnabled).toBe(true);
101
+ expect(result.embedded).toBe(1);
102
+ expect(embedSpy).toHaveBeenCalledTimes(1);
103
+ const updated = graph.getNode(nodeId);
104
+ expect(updated?.vector?.[0]).toBeCloseTo(0.9, 5);
105
+ expect(updated?.vector?.[1]).toBeCloseTo(0.1, 5);
106
+ const metadata = updated?.metadata;
107
+ expect(metadata?.contentHash).toBe(newHash);
108
+ expect(metadata?.vectorContentHash).toBe(newHash);
109
+ });
110
+ it('disabled_skips_embedding', async () => {
111
+ const { root, graph } = await createFixture(false);
112
+ graph.addNode({
113
+ id: 'requirement:RF-01',
114
+ type: 'requirement',
115
+ label: 'RF-01',
116
+ metadata: {
117
+ reqId: 'RF-01',
118
+ title: 'Auth MUST',
119
+ contentHash: hash('Auth MUST'),
120
+ },
121
+ });
122
+ const loaderSpy = vi.fn(async () => ({
123
+ dim: 2,
124
+ embed: vi.fn(async () => new Float32Array([1, 0])),
125
+ }));
126
+ const result = await runIncrementalSemanticIndex(graph, root, {
127
+ loadEmbedderFn: loaderSpy,
128
+ });
129
+ expect(result.semanticEnabled).toBe(false);
130
+ expect(result.scanned).toBe(0);
131
+ expect(result.embedded).toBe(0);
132
+ expect(loaderSpy).not.toHaveBeenCalled();
133
+ });
134
+ });
135
+ //# sourceMappingURL=incremental-index.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"incremental-index.test.js","sourceRoot":"","sources":["../../../src/graphrag/__tests__/incremental-index.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=no-heavy-dep-in-core.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"no-heavy-dep-in-core.test.d.ts","sourceRoot":"","sources":["../../../src/graphrag/__tests__/no-heavy-dep-in-core.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,48 @@
1
+ import { readFileSync, readdirSync } from 'node:fs';
2
+ import path from 'node:path';
3
+ import { fileURLToPath } from 'node:url';
4
+ import { describe, expect, it } from 'vitest';
5
+ const pkgRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..', '..', '..');
6
+ const ALLOWED_REL = path.join('src', 'graphrag', 'embeddings.ts');
7
+ const FORBIDDEN = /(?:import|require)\s*\(?['"](?:onnxruntime|@xenova\/transformers|@huggingface\/transformers)|from\s+['"](?:onnxruntime|@xenova\/transformers|@huggingface\/transformers)/;
8
+ function walkTsFiles(dir, base = pkgRoot) {
9
+ const entries = readdirSync(dir, { withFileTypes: true });
10
+ const files = [];
11
+ for (const entry of entries) {
12
+ const full = path.join(dir, entry.name);
13
+ if (entry.isDirectory()) {
14
+ if (entry.name === '__tests__' || entry.name === 'node_modules')
15
+ continue;
16
+ files.push(...walkTsFiles(full, base));
17
+ continue;
18
+ }
19
+ if (!entry.name.endsWith('.ts'))
20
+ continue;
21
+ if (entry.name.endsWith('.test.ts') || entry.name.endsWith('.spec.ts'))
22
+ continue;
23
+ files.push(path.relative(base, full));
24
+ }
25
+ return files;
26
+ }
27
+ function listSourceFiles() {
28
+ return walkTsFiles(path.join(pkgRoot, 'src')).filter((f) => path.normalize(f) !== path.normalize(ALLOWED_REL));
29
+ }
30
+ function findHeavyDependencyImports() {
31
+ return listSourceFiles().filter((rel) => {
32
+ const content = readFileSync(path.join(pkgRoot, rel), 'utf8');
33
+ return FORBIDDEN.test(content);
34
+ });
35
+ }
36
+ describe('no-heavy-dep-in-core', () => {
37
+ it('passes_on_clean_tree', () => {
38
+ const offenders = findHeavyDependencyImports();
39
+ expect(offenders, `embedding runtime imported outside ${ALLOWED_REL}`).toEqual([]);
40
+ });
41
+ it('detects_planted_import', () => {
42
+ const transformersImport = "import { pipeline } from '@huggingface/transformers';";
43
+ const onnxRequire = "const ort = require('onnxruntime');";
44
+ expect(FORBIDDEN.test(transformersImport)).toBe(true);
45
+ expect(FORBIDDEN.test(onnxRequire)).toBe(true);
46
+ });
47
+ });
48
+ //# sourceMappingURL=no-heavy-dep-in-core.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"no-heavy-dep-in-core.test.js","sourceRoot":"","sources":["../../../src/graphrag/__tests__/no-heavy-dep-in-core.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=requirement-hash.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"requirement-hash.test.d.ts","sourceRoot":"","sources":["../../../src/graphrag/__tests__/requirement-hash.test.ts"],"names":[],"mappings":""}