@contorium/mcp 0.8.1

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 (187) hide show
  1. package/README.md +97 -0
  2. package/bin/contorium-mcp.js +34 -0
  3. package/dist/autoContext.d.ts +2 -0
  4. package/dist/autoContext.js +2 -0
  5. package/dist/bootstrapCli.d.ts +2 -0
  6. package/dist/bootstrapCli.js +21 -0
  7. package/dist/conflicts.d.ts +19 -0
  8. package/dist/conflicts.js +49 -0
  9. package/dist/dashboardEnsure.d.ts +10 -0
  10. package/dist/dashboardEnsure.js +41 -0
  11. package/dist/intelligence.d.ts +16 -0
  12. package/dist/intelligence.js +38 -0
  13. package/dist/intentGraph.d.ts +20 -0
  14. package/dist/intentGraph.js +51 -0
  15. package/dist/mcpBootstrap.d.ts +8 -0
  16. package/dist/mcpBootstrap.js +81 -0
  17. package/dist/memoryStore.d.ts +18 -0
  18. package/dist/memoryStore.js +57 -0
  19. package/dist/paths.d.ts +12 -0
  20. package/dist/paths.js +66 -0
  21. package/dist/runtimeState.d.ts +14 -0
  22. package/dist/runtimeState.js +36 -0
  23. package/dist/server.d.ts +3 -0
  24. package/dist/server.js +567 -0
  25. package/dist/stateBuilder.d.ts +16 -0
  26. package/dist/stateBuilder.js +40 -0
  27. package/dist/understanding.d.ts +1 -0
  28. package/dist/understanding.js +1 -0
  29. package/dist/workspace.d.ts +12 -0
  30. package/dist/workspace.js +40 -0
  31. package/dist/workspaceConfig.d.ts +14 -0
  32. package/dist/workspaceConfig.js +80 -0
  33. package/node_modules/@contora/state-core/dist/adapterSync.d.ts +29 -0
  34. package/node_modules/@contora/state-core/dist/adapterSync.d.ts.map +1 -0
  35. package/node_modules/@contora/state-core/dist/adapterSync.js +142 -0
  36. package/node_modules/@contora/state-core/dist/adapters.d.ts +20 -0
  37. package/node_modules/@contora/state-core/dist/adapters.d.ts.map +1 -0
  38. package/node_modules/@contora/state-core/dist/adapters.js +24 -0
  39. package/node_modules/@contora/state-core/dist/bootstrap/bootstrapState.d.ts +6 -0
  40. package/node_modules/@contora/state-core/dist/bootstrap/bootstrapState.d.ts.map +1 -0
  41. package/node_modules/@contora/state-core/dist/bootstrap/bootstrapState.js +116 -0
  42. package/node_modules/@contora/state-core/dist/bootstrapArtifacts.d.ts +18 -0
  43. package/node_modules/@contora/state-core/dist/bootstrapArtifacts.d.ts.map +1 -0
  44. package/node_modules/@contora/state-core/dist/bootstrapArtifacts.js +43 -0
  45. package/node_modules/@contora/state-core/dist/bootstrapState.d.ts +6 -0
  46. package/node_modules/@contora/state-core/dist/bootstrapState.d.ts.map +1 -0
  47. package/node_modules/@contora/state-core/dist/bootstrapState.js +60 -0
  48. package/node_modules/@contora/state-core/dist/dashboardActivity.d.ts +12 -0
  49. package/node_modules/@contora/state-core/dist/dashboardActivity.d.ts.map +1 -0
  50. package/node_modules/@contora/state-core/dist/dashboardActivity.js +58 -0
  51. package/node_modules/@contora/state-core/dist/dualMode.d.ts +11 -0
  52. package/node_modules/@contora/state-core/dist/dualMode.d.ts.map +1 -0
  53. package/node_modules/@contora/state-core/dist/dualMode.js +38 -0
  54. package/node_modules/@contora/state-core/dist/gitScan.d.ts +7 -0
  55. package/node_modules/@contora/state-core/dist/gitScan.d.ts.map +1 -0
  56. package/node_modules/@contora/state-core/dist/gitScan.js +39 -0
  57. package/node_modules/@contora/state-core/dist/index.d.ts +44 -0
  58. package/node_modules/@contora/state-core/dist/index.d.ts.map +1 -0
  59. package/node_modules/@contora/state-core/dist/index.js +141 -0
  60. package/node_modules/@contora/state-core/dist/minimalSnapshot.d.ts +4 -0
  61. package/node_modules/@contora/state-core/dist/minimalSnapshot.d.ts.map +1 -0
  62. package/node_modules/@contora/state-core/dist/minimalSnapshot.js +60 -0
  63. package/node_modules/@contora/state-core/dist/scanner/gitScan.d.ts +7 -0
  64. package/node_modules/@contora/state-core/dist/scanner/gitScan.d.ts.map +1 -0
  65. package/node_modules/@contora/state-core/dist/scanner/gitScan.js +42 -0
  66. package/node_modules/@contora/state-core/dist/scanner/workspaceScanner.d.ts +4 -0
  67. package/node_modules/@contora/state-core/dist/scanner/workspaceScanner.d.ts.map +1 -0
  68. package/node_modules/@contora/state-core/dist/scanner/workspaceScanner.js +148 -0
  69. package/node_modules/@contora/state-core/dist/semiAutoHandoff.d.ts +46 -0
  70. package/node_modules/@contora/state-core/dist/semiAutoHandoff.d.ts.map +1 -0
  71. package/node_modules/@contora/state-core/dist/semiAutoHandoff.js +227 -0
  72. package/node_modules/@contora/state-core/dist/sourceMetadata.d.ts +4 -0
  73. package/node_modules/@contora/state-core/dist/sourceMetadata.d.ts.map +1 -0
  74. package/node_modules/@contora/state-core/dist/sourceMetadata.js +27 -0
  75. package/node_modules/@contora/state-core/dist/state-builder/buildFromScan.d.ts +5 -0
  76. package/node_modules/@contora/state-core/dist/state-builder/buildFromScan.d.ts.map +1 -0
  77. package/node_modules/@contora/state-core/dist/state-builder/buildFromScan.js +33 -0
  78. package/node_modules/@contora/state-core/dist/state-builder/normalization.d.ts +5 -0
  79. package/node_modules/@contora/state-core/dist/state-builder/normalization.d.ts.map +1 -0
  80. package/node_modules/@contora/state-core/dist/state-builder/normalization.js +107 -0
  81. package/node_modules/@contora/state-core/dist/state-builder/rebuildFromScan.d.ts +4 -0
  82. package/node_modules/@contora/state-core/dist/state-builder/rebuildFromScan.d.ts.map +1 -0
  83. package/node_modules/@contora/state-core/dist/state-builder/rebuildFromScan.js +22 -0
  84. package/node_modules/@contora/state-core/dist/state-builder/snapshot.d.ts +5 -0
  85. package/node_modules/@contora/state-core/dist/state-builder/snapshot.d.ts.map +1 -0
  86. package/node_modules/@contora/state-core/dist/state-builder/snapshot.js +53 -0
  87. package/node_modules/@contora/state-core/dist/state-builder/store.d.ts +7 -0
  88. package/node_modules/@contora/state-core/dist/state-builder/store.d.ts.map +1 -0
  89. package/node_modules/@contora/state-core/dist/state-builder/store.js +99 -0
  90. package/node_modules/@contora/state-core/dist/state-builder/types.d.ts +18 -0
  91. package/node_modules/@contora/state-core/dist/state-builder/types.d.ts.map +1 -0
  92. package/node_modules/@contora/state-core/dist/state-builder/types.js +20 -0
  93. package/node_modules/@contora/state-core/dist/types.d.ts +42 -0
  94. package/node_modules/@contora/state-core/dist/types.d.ts.map +1 -0
  95. package/node_modules/@contora/state-core/dist/types.js +3 -0
  96. package/node_modules/@contora/state-core/dist/understanding/buildUnderstanding.d.ts +22 -0
  97. package/node_modules/@contora/state-core/dist/understanding/buildUnderstanding.d.ts.map +1 -0
  98. package/node_modules/@contora/state-core/dist/understanding/buildUnderstanding.js +87 -0
  99. package/node_modules/@contora/state-core/dist/understanding/changeDetector.d.ts +7 -0
  100. package/node_modules/@contora/state-core/dist/understanding/changeDetector.d.ts.map +1 -0
  101. package/node_modules/@contora/state-core/dist/understanding/changeDetector.js +68 -0
  102. package/node_modules/@contora/state-core/dist/understanding/chpHandoff.d.ts +49 -0
  103. package/node_modules/@contora/state-core/dist/understanding/chpHandoff.d.ts.map +1 -0
  104. package/node_modules/@contora/state-core/dist/understanding/chpHandoff.js +214 -0
  105. package/node_modules/@contora/state-core/dist/understanding/extractor.d.ts +21 -0
  106. package/node_modules/@contora/state-core/dist/understanding/extractor.d.ts.map +1 -0
  107. package/node_modules/@contora/state-core/dist/understanding/extractor.js +173 -0
  108. package/node_modules/@contora/state-core/dist/understanding/formatCanonicalExport.d.ts +30 -0
  109. package/node_modules/@contora/state-core/dist/understanding/formatCanonicalExport.d.ts.map +1 -0
  110. package/node_modules/@contora/state-core/dist/understanding/formatCanonicalExport.js +363 -0
  111. package/node_modules/@contora/state-core/dist/understanding/formatHandoff.d.ts +20 -0
  112. package/node_modules/@contora/state-core/dist/understanding/formatHandoff.d.ts.map +1 -0
  113. package/node_modules/@contora/state-core/dist/understanding/formatHandoff.js +57 -0
  114. package/node_modules/@contora/state-core/dist/understanding/graphBuilder.d.ts +9 -0
  115. package/node_modules/@contora/state-core/dist/understanding/graphBuilder.d.ts.map +1 -0
  116. package/node_modules/@contora/state-core/dist/understanding/graphBuilder.js +107 -0
  117. package/node_modules/@contora/state-core/dist/understanding/handoffBuilder.d.ts +12 -0
  118. package/node_modules/@contora/state-core/dist/understanding/handoffBuilder.d.ts.map +1 -0
  119. package/node_modules/@contora/state-core/dist/understanding/handoffBuilder.js +101 -0
  120. package/node_modules/@contora/state-core/dist/understanding/impactAnalyzer.d.ts +5 -0
  121. package/node_modules/@contora/state-core/dist/understanding/impactAnalyzer.d.ts.map +1 -0
  122. package/node_modules/@contora/state-core/dist/understanding/impactAnalyzer.js +58 -0
  123. package/node_modules/@contora/state-core/dist/understanding/intentFusion.d.ts +9 -0
  124. package/node_modules/@contora/state-core/dist/understanding/intentFusion.d.ts.map +1 -0
  125. package/node_modules/@contora/state-core/dist/understanding/intentFusion.js +54 -0
  126. package/node_modules/@contora/state-core/dist/understanding/knowledgeGraph/closureConstants.d.ts +24 -0
  127. package/node_modules/@contora/state-core/dist/understanding/knowledgeGraph/closureConstants.d.ts.map +1 -0
  128. package/node_modules/@contora/state-core/dist/understanding/knowledgeGraph/closureConstants.js +33 -0
  129. package/node_modules/@contora/state-core/dist/understanding/knowledgeGraph/confidence.d.ts +20 -0
  130. package/node_modules/@contora/state-core/dist/understanding/knowledgeGraph/confidence.d.ts.map +1 -0
  131. package/node_modules/@contora/state-core/dist/understanding/knowledgeGraph/confidence.js +53 -0
  132. package/node_modules/@contora/state-core/dist/understanding/knowledgeGraph/gitFrequency.d.ts +5 -0
  133. package/node_modules/@contora/state-core/dist/understanding/knowledgeGraph/gitFrequency.d.ts.map +1 -0
  134. package/node_modules/@contora/state-core/dist/understanding/knowledgeGraph/gitFrequency.js +19 -0
  135. package/node_modules/@contora/state-core/dist/understanding/knowledgeGraph/hotspotBuilder.d.ts +13 -0
  136. package/node_modules/@contora/state-core/dist/understanding/knowledgeGraph/hotspotBuilder.d.ts.map +1 -0
  137. package/node_modules/@contora/state-core/dist/understanding/knowledgeGraph/hotspotBuilder.js +101 -0
  138. package/node_modules/@contora/state-core/dist/understanding/knowledgeGraph/intentFunctionMapper.d.ts +22 -0
  139. package/node_modules/@contora/state-core/dist/understanding/knowledgeGraph/intentFunctionMapper.d.ts.map +1 -0
  140. package/node_modules/@contora/state-core/dist/understanding/knowledgeGraph/intentFunctionMapper.js +106 -0
  141. package/node_modules/@contora/state-core/dist/understanding/knowledgeGraph/knowledgeGraphBuilder.d.ts +23 -0
  142. package/node_modules/@contora/state-core/dist/understanding/knowledgeGraph/knowledgeGraphBuilder.d.ts.map +1 -0
  143. package/node_modules/@contora/state-core/dist/understanding/knowledgeGraph/knowledgeGraphBuilder.js +415 -0
  144. package/node_modules/@contora/state-core/dist/understanding/knowledgeGraph/normalize.d.ts +11 -0
  145. package/node_modules/@contora/state-core/dist/understanding/knowledgeGraph/normalize.d.ts.map +1 -0
  146. package/node_modules/@contora/state-core/dist/understanding/knowledgeGraph/normalize.js +136 -0
  147. package/node_modules/@contora/state-core/dist/understanding/knowledgeGraph/rebuildTrigger.d.ts +13 -0
  148. package/node_modules/@contora/state-core/dist/understanding/knowledgeGraph/rebuildTrigger.d.ts.map +1 -0
  149. package/node_modules/@contora/state-core/dist/understanding/knowledgeGraph/rebuildTrigger.js +34 -0
  150. package/node_modules/@contora/state-core/dist/understanding/knowledgeGraph/snapshotBuilder.d.ts +17 -0
  151. package/node_modules/@contora/state-core/dist/understanding/knowledgeGraph/snapshotBuilder.d.ts.map +1 -0
  152. package/node_modules/@contora/state-core/dist/understanding/knowledgeGraph/snapshotBuilder.js +73 -0
  153. package/node_modules/@contora/state-core/dist/understanding/knowledgeGraph/store.d.ts +7 -0
  154. package/node_modules/@contora/state-core/dist/understanding/knowledgeGraph/store.d.ts.map +1 -0
  155. package/node_modules/@contora/state-core/dist/understanding/knowledgeGraph/store.js +127 -0
  156. package/node_modules/@contora/state-core/dist/understanding/knowledgeGraph/types.d.ts +116 -0
  157. package/node_modules/@contora/state-core/dist/understanding/knowledgeGraph/types.d.ts.map +1 -0
  158. package/node_modules/@contora/state-core/dist/understanding/knowledgeGraph/types.js +6 -0
  159. package/node_modules/@contora/state-core/dist/understanding/miniGraph.d.ts +4 -0
  160. package/node_modules/@contora/state-core/dist/understanding/miniGraph.d.ts.map +1 -0
  161. package/node_modules/@contora/state-core/dist/understanding/miniGraph.js +18 -0
  162. package/node_modules/@contora/state-core/dist/understanding/store.d.ts +24 -0
  163. package/node_modules/@contora/state-core/dist/understanding/store.d.ts.map +1 -0
  164. package/node_modules/@contora/state-core/dist/understanding/store.js +243 -0
  165. package/node_modules/@contora/state-core/dist/understanding/symbolValidator.d.ts +9 -0
  166. package/node_modules/@contora/state-core/dist/understanding/symbolValidator.d.ts.map +1 -0
  167. package/node_modules/@contora/state-core/dist/understanding/symbolValidator.js +51 -0
  168. package/node_modules/@contora/state-core/dist/understanding/timelineTracker.d.ts +3 -0
  169. package/node_modules/@contora/state-core/dist/understanding/timelineTracker.d.ts.map +1 -0
  170. package/node_modules/@contora/state-core/dist/understanding/timelineTracker.js +129 -0
  171. package/node_modules/@contora/state-core/dist/understanding/treeSitterParser.d.ts +24 -0
  172. package/node_modules/@contora/state-core/dist/understanding/treeSitterParser.d.ts.map +1 -0
  173. package/node_modules/@contora/state-core/dist/understanding/treeSitterParser.js +56 -0
  174. package/node_modules/@contora/state-core/dist/understanding/types.d.ts +136 -0
  175. package/node_modules/@contora/state-core/dist/understanding/types.d.ts.map +1 -0
  176. package/node_modules/@contora/state-core/dist/understanding/types.js +5 -0
  177. package/node_modules/@contora/state-core/dist/understanding/understandingGraphBuilder.d.ts +23 -0
  178. package/node_modules/@contora/state-core/dist/understanding/understandingGraphBuilder.d.ts.map +1 -0
  179. package/node_modules/@contora/state-core/dist/understanding/understandingGraphBuilder.js +67 -0
  180. package/node_modules/@contora/state-core/dist/version.d.ts +3 -0
  181. package/node_modules/@contora/state-core/dist/version.d.ts.map +1 -0
  182. package/node_modules/@contora/state-core/dist/version.js +21 -0
  183. package/node_modules/@contora/state-core/dist/workspaceScanner.d.ts +4 -0
  184. package/node_modules/@contora/state-core/dist/workspaceScanner.d.ts.map +1 -0
  185. package/node_modules/@contora/state-core/dist/workspaceScanner.js +112 -0
  186. package/node_modules/@contora/state-core/package.json +49 -0
  187. package/package.json +61 -0
@@ -0,0 +1,415 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.buildProjectKnowledgeGraph = buildProjectKnowledgeGraph;
4
+ const intentFunctionMapper_js_1 = require("./intentFunctionMapper.js");
5
+ const normalize_js_1 = require("./normalize.js");
6
+ const hotspotBuilder_js_1 = require("./hotspotBuilder.js");
7
+ const snapshotBuilder_js_1 = require("./snapshotBuilder.js");
8
+ const confidence_js_1 = require("./confidence.js");
9
+ const MAX_INTENTS = 6;
10
+ const MAX_FUNCTIONS = 80;
11
+ function norm(p) {
12
+ return p.replace(/\\/g, '/');
13
+ }
14
+ function basename(p) {
15
+ const parts = norm(p).split('/').filter(Boolean);
16
+ return parts[parts.length - 1] ?? p;
17
+ }
18
+ function moduleFromPath(file) {
19
+ const parts = norm(file).split('/').filter(Boolean);
20
+ if (parts.length <= 1) {
21
+ return parts[0] ?? 'root';
22
+ }
23
+ if (parts[0] === 'packages' && parts[1]) {
24
+ return parts[1];
25
+ }
26
+ if (parts[0] === 'src' && parts[1]) {
27
+ return parts[1];
28
+ }
29
+ return parts[0];
30
+ }
31
+ function intentId(name, idx) {
32
+ return `intent_${idx}_${name.slice(0, 24).replace(/\W+/g, '_')}`;
33
+ }
34
+ function moduleId(name) {
35
+ return `mod::${name}`;
36
+ }
37
+ function fileId(file) {
38
+ return `file::${norm(file)}`;
39
+ }
40
+ function fnNodeId(file, name, kind) {
41
+ return `${norm(file)}::${kind}::${name}`;
42
+ }
43
+ function collectIntents(args) {
44
+ const out = [];
45
+ const seen = new Set();
46
+ const add = (text) => {
47
+ const t = text.trim();
48
+ if (t.length < 4 || seen.has(t.toLowerCase())) {
49
+ return;
50
+ }
51
+ seen.add(t.toLowerCase());
52
+ out.push({ id: intentId(t, out.length), text: t });
53
+ };
54
+ if (args.goal) {
55
+ add(args.goal);
56
+ }
57
+ const focusBase = args.intent.focus.split('—')[0]?.trim() ?? args.intent.focus;
58
+ if (focusBase && focusBase.toLowerCase() !== args.goal.toLowerCase()) {
59
+ add(focusBase);
60
+ }
61
+ for (const mod of args.built?.active_modules ?? []) {
62
+ const label = mod.includes('/') ? basename(mod) : mod;
63
+ if (/doc|mcp|auth|ui|test|build/i.test(label) || label.length > 3) {
64
+ add(`${label} integration`.replace(/ integration integration/, ' integration'));
65
+ }
66
+ }
67
+ for (const action of args.built?.next_actions ?? []) {
68
+ if (/documentation|mcp|auth|build|test/i.test(action)) {
69
+ add(action);
70
+ }
71
+ }
72
+ return out.slice(0, MAX_INTENTS);
73
+ }
74
+ function edgeConfidence(type, weight) {
75
+ if (type === 'supports_intent') {
76
+ return weight;
77
+ }
78
+ if (type === 'calls') {
79
+ return 0.8;
80
+ }
81
+ return 0.95;
82
+ }
83
+ function mappingByFn(mappings) {
84
+ const out = new Map();
85
+ for (const m of mappings) {
86
+ const prev = out.get(m.functionId);
87
+ if (!prev || prev.score < m.score) {
88
+ out.set(m.functionId, m);
89
+ }
90
+ }
91
+ return out;
92
+ }
93
+ function buildIntentTrees(intents, nodes, edges, mappings) {
94
+ const nodeById = new Map(nodes.map((n) => [n.id, n]));
95
+ const childrenOf = (id, type) => edges
96
+ .filter((e) => e.source === id && (!type || e.type === type))
97
+ .sort((a, b) => b.weight - a.weight)
98
+ .map((e) => e.target);
99
+ const fnToIntent = new Map();
100
+ const confidenceByFn = mappingByFn(mappings);
101
+ for (const m of mappings) {
102
+ if (!fnToIntent.has(m.functionId) || (mappings.find((x) => x.functionId === m.functionId)?.score ?? 0) < m.score) {
103
+ fnToIntent.set(m.functionId, m.intentId);
104
+ }
105
+ }
106
+ const trees = [];
107
+ for (const intent of intents) {
108
+ const intentModules = childrenOf(intent.id, 'supports_intent');
109
+ const modChildren = [];
110
+ for (const modNodeId of intentModules) {
111
+ const modNode = nodeById.get(modNodeId);
112
+ if (!modNode) {
113
+ continue;
114
+ }
115
+ const fileNodes = childrenOf(modNodeId, 'contains');
116
+ const fileChildren = [];
117
+ for (const fId of fileNodes) {
118
+ const fNode = nodeById.get(fId);
119
+ if (!fNode || fNode.type !== 'file') {
120
+ continue;
121
+ }
122
+ const fnIds = childrenOf(fId, 'contains').filter((id) => {
123
+ const n = nodeById.get(id);
124
+ return n && (n.type === 'function' || n.type === 'class') && fnToIntent.get(id) === intent.id;
125
+ });
126
+ const fnChildren = fnIds.slice(0, 8).map((id) => {
127
+ const n = nodeById.get(id);
128
+ const map = confidenceByFn.get(id);
129
+ const callIds = childrenOf(id, 'calls').slice(0, 6);
130
+ return {
131
+ id: n.id,
132
+ type: n.type,
133
+ name: n.name + (n.type === 'function' ? '()' : ''),
134
+ path: n.path,
135
+ confidence: map?.confidence,
136
+ children: callIds.map((cid) => {
137
+ const c = nodeById.get(cid);
138
+ return {
139
+ id: c.id,
140
+ type: c.type,
141
+ name: c.name + (c.type === 'function' ? '()' : ''),
142
+ path: c.path,
143
+ children: [],
144
+ };
145
+ }),
146
+ };
147
+ });
148
+ if (fnChildren.length) {
149
+ fileChildren.push({
150
+ id: fNode.id,
151
+ type: 'file',
152
+ name: basename(fNode.path ?? fNode.name),
153
+ path: fNode.path,
154
+ children: fnChildren,
155
+ });
156
+ }
157
+ }
158
+ if (fileChildren.length) {
159
+ modChildren.push({
160
+ id: modNode.id,
161
+ type: 'module',
162
+ name: modNode.name,
163
+ children: fileChildren,
164
+ });
165
+ }
166
+ }
167
+ if (modChildren.length) {
168
+ trees.push({
169
+ id: intent.id,
170
+ type: 'intent',
171
+ name: intent.text,
172
+ expanded: trees.length === 0,
173
+ children: modChildren,
174
+ });
175
+ }
176
+ }
177
+ return trees;
178
+ }
179
+ function buildReasonTraces(functions, mappings, edges, editCounts, intentById) {
180
+ const intentForFn = new Map();
181
+ for (const m of mappings) {
182
+ const prev = intentForFn.get(m.functionId);
183
+ if (!prev || prev.score < m.score) {
184
+ intentForFn.set(m.functionId, m);
185
+ }
186
+ }
187
+ const depCount = (fnId) => edges.filter((e) => e.source === fnId && e.type === 'calls').length +
188
+ edges.filter((e) => e.target === fnId && e.type === 'calls').length;
189
+ const out = [];
190
+ for (const fn of functions) {
191
+ const edits = editCounts.get(norm(fn.file)) ?? 0;
192
+ const deps = depCount(fn.id);
193
+ const map = intentForFn.get(fn.id);
194
+ const reasons = [];
195
+ if (edits >= 3) {
196
+ reasons.push(`edited ${edits} times in recent activity`);
197
+ }
198
+ else if (edits > 0) {
199
+ reasons.push('recently edited file');
200
+ }
201
+ if (map) {
202
+ reasons.push(`linked to active intent (confidence ${Math.round(map.confidence * 100)}%)`);
203
+ if (map.signals.length) {
204
+ reasons.push(map.signals.join(', '));
205
+ }
206
+ }
207
+ if (deps >= 4) {
208
+ reasons.push(`high dependency count (${deps})`);
209
+ }
210
+ if (!reasons.length) {
211
+ continue;
212
+ }
213
+ const intent = map ? intentById.get(map.intentId) : undefined;
214
+ out.push({
215
+ targetId: fn.id,
216
+ targetName: fn.name,
217
+ targetType: 'function',
218
+ reasons,
219
+ editCount: edits,
220
+ dependencyCount: deps,
221
+ linkedIntent: intent?.text,
222
+ confidence: map?.confidence,
223
+ });
224
+ }
225
+ return out
226
+ .sort((a, b) => b.editCount - a.editCount || b.dependencyCount - a.dependencyCount)
227
+ .slice(0, 10);
228
+ }
229
+ /**
230
+ * Build Project Knowledge Graph from L1/L2 sources only.
231
+ * L3 (intelligence / intent-graph / AI speculation) must never feed this builder.
232
+ */
233
+ function buildProjectKnowledgeGraph(input) {
234
+ const now = input.now ?? Date.now();
235
+ const editCounts = input.editCounts ?? new Map();
236
+ for (const f of input.change.changed_files) {
237
+ const k = norm(f);
238
+ editCounts.set(k, (editCounts.get(k) ?? 0) + 1);
239
+ }
240
+ const intents = collectIntents(input);
241
+ const intentById = new Map(intents.map((i) => [i.id, i]));
242
+ const nodes = [];
243
+ const edges = [];
244
+ const moduleSet = new Set();
245
+ for (const intent of intents) {
246
+ nodes.push({
247
+ id: intent.id,
248
+ type: 'intent',
249
+ name: intent.text,
250
+ updatedAt: now,
251
+ });
252
+ }
253
+ for (const n of input.graph.nodes) {
254
+ if (n.kind === 'module') {
255
+ const mod = moduleFromPath(n.file);
256
+ moduleSet.add(mod);
257
+ }
258
+ }
259
+ for (const f of input.change.changed_files) {
260
+ moduleSet.add(moduleFromPath(f));
261
+ }
262
+ for (const mod of input.built?.active_modules ?? []) {
263
+ moduleSet.add(basename(mod) || mod);
264
+ }
265
+ for (const mod of moduleSet) {
266
+ nodes.push({
267
+ id: moduleId(mod),
268
+ type: 'module',
269
+ name: mod,
270
+ path: mod,
271
+ updatedAt: now,
272
+ });
273
+ }
274
+ const fileNodes = new Set();
275
+ const functions = [];
276
+ for (const n of input.graph.nodes) {
277
+ if (n.kind === 'module') {
278
+ const fid = fileId(n.file);
279
+ if (!fileNodes.has(fid)) {
280
+ fileNodes.add(fid);
281
+ nodes.push({
282
+ id: fid,
283
+ type: 'file',
284
+ name: basename(n.file),
285
+ path: norm(n.file),
286
+ updatedAt: now,
287
+ });
288
+ }
289
+ const mod = moduleId(moduleFromPath(n.file));
290
+ edges.push({
291
+ source: mod,
292
+ target: fid,
293
+ type: 'contains',
294
+ weight: 1,
295
+ confidence: edgeConfidence('contains', 1),
296
+ });
297
+ }
298
+ if (n.kind === 'function' || n.kind === 'class') {
299
+ const fid = fileId(n.file);
300
+ if (!fileNodes.has(fid)) {
301
+ fileNodes.add(fid);
302
+ nodes.push({
303
+ id: fid,
304
+ type: 'file',
305
+ name: basename(n.file),
306
+ path: norm(n.file),
307
+ updatedAt: now,
308
+ });
309
+ const mod = moduleId(moduleFromPath(n.file));
310
+ edges.push({
311
+ source: mod,
312
+ target: fid,
313
+ type: 'contains',
314
+ weight: 1,
315
+ confidence: edgeConfidence('contains', 1),
316
+ });
317
+ }
318
+ nodes.push({
319
+ id: n.id,
320
+ type: n.kind,
321
+ name: n.name,
322
+ path: norm(n.file),
323
+ metadata: n.line ? { line: n.line } : undefined,
324
+ updatedAt: now,
325
+ });
326
+ edges.push({
327
+ source: fid,
328
+ target: n.id,
329
+ type: 'contains',
330
+ weight: 1,
331
+ confidence: edgeConfidence('contains', 1),
332
+ });
333
+ if (n.kind === 'function') {
334
+ const callTargets = input.graph.edges
335
+ .filter((e) => e.from === n.id && e.kind === 'calls')
336
+ .map((e) => input.graph.nodes.find((x) => x.id === e.to)?.name)
337
+ .filter((x) => !!x);
338
+ functions.push({
339
+ id: n.id,
340
+ name: n.name,
341
+ file: norm(n.file),
342
+ moduleHint: moduleFromPath(n.file),
343
+ callTargets,
344
+ });
345
+ }
346
+ }
347
+ }
348
+ for (const e of input.graph.edges) {
349
+ if (e.kind === 'calls') {
350
+ edges.push({
351
+ source: e.from,
352
+ target: e.to,
353
+ type: 'calls',
354
+ weight: 0.8,
355
+ confidence: edgeConfidence('calls', 0.8),
356
+ });
357
+ }
358
+ }
359
+ const ctx = {
360
+ recentEditFiles: new Set(input.change.changed_files.map(norm)),
361
+ gitFrequency: input.gitFrequency,
362
+ };
363
+ const rawMappings = (0, intentFunctionMapper_js_1.mapIntentsToFunctions)(intents, functions.slice(0, MAX_FUNCTIONS), ctx);
364
+ const { canonical: intentMappings, inference: inferenceMappings } = (0, confidence_js_1.splitMappingsByCanonicalThreshold)(rawMappings);
365
+ for (const m of intentMappings) {
366
+ const fn = functions.find((f) => f.id === m.functionId);
367
+ if (!fn) {
368
+ continue;
369
+ }
370
+ const mod = moduleId(fn.moduleHint ?? moduleFromPath(fn.file));
371
+ edges.push({
372
+ source: m.intentId,
373
+ target: mod,
374
+ type: 'supports_intent',
375
+ weight: m.score,
376
+ confidence: m.confidence,
377
+ });
378
+ }
379
+ const canonicalEdges = (0, confidence_js_1.filterCanonicalEdges)(edges);
380
+ const reasonTraces = buildReasonTraces(functions, [...intentMappings, ...inferenceMappings], canonicalEdges, editCounts, intentById);
381
+ const intentTrees = buildIntentTrees(intents, nodes, canonicalEdges, intentMappings);
382
+ const hotspots = (0, hotspotBuilder_js_1.buildHotspots)({
383
+ nodes,
384
+ edges: canonicalEdges,
385
+ intentMappings,
386
+ editCounts,
387
+ gitFrequency: input.gitFrequency ?? new Map(),
388
+ now,
389
+ });
390
+ const snapshot = (0, snapshotBuilder_js_1.buildKnowledgeSnapshot)({
391
+ nodes,
392
+ edges: canonicalEdges,
393
+ intentMappings,
394
+ hotspots,
395
+ nextActions: input.built?.next_actions ?? [],
396
+ now,
397
+ });
398
+ return {
399
+ meta: (0, normalize_js_1.buildGraphMetadata)({
400
+ workspaceRoot: input.workspaceRoot ?? 'unknown',
401
+ now,
402
+ sourceVersion: input.sourceVersion,
403
+ rebuildTrigger: input.rebuildTrigger,
404
+ lastCommitHash: input.lastCommitHash,
405
+ }),
406
+ nodes,
407
+ edges: canonicalEdges,
408
+ intentMappings,
409
+ inferenceMappings,
410
+ reasonTraces,
411
+ intentTrees,
412
+ hotspots,
413
+ snapshot,
414
+ };
415
+ }
@@ -0,0 +1,11 @@
1
+ import { type GraphMetadata, type ProjectKnowledgeGraph } from './types.js';
2
+ export declare function buildGraphMetadata(args: {
3
+ workspaceRoot: string;
4
+ now: number;
5
+ sourceVersion?: string;
6
+ rebuildTrigger?: string;
7
+ lastCommitHash?: string;
8
+ }): GraphMetadata;
9
+ /** schemaVersion switch — upgrade legacy graphs on read. */
10
+ export declare function normalizeKnowledgeGraph(raw: unknown, workspaceRoot?: string): ProjectKnowledgeGraph | undefined;
11
+ //# sourceMappingURL=normalize.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"normalize.d.ts","sourceRoot":"","sources":["../../../src/understanding/knowledgeGraph/normalize.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,aAAa,EAIlB,KAAK,qBAAqB,EAC3B,MAAM,YAAY,CAAC;AAgBpB,wBAAgB,kBAAkB,CAAC,IAAI,EAAE;IACvC,aAAa,EAAE,MAAM,CAAC;IACtB,GAAG,EAAE,MAAM,CAAC;IACZ,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB,GAAG,aAAa,CAYhB;AAgBD,4DAA4D;AAC5D,wBAAgB,uBAAuB,CACrC,GAAG,EAAE,OAAO,EACZ,aAAa,CAAC,EAAE,MAAM,GACrB,qBAAqB,GAAG,SAAS,CAuCnC"}
@@ -0,0 +1,136 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.buildGraphMetadata = buildGraphMetadata;
4
+ exports.normalizeKnowledgeGraph = normalizeKnowledgeGraph;
5
+ const types_js_1 = require("./types.js");
6
+ const version_js_1 = require("../../version.js");
7
+ const snapshotBuilder_js_1 = require("./snapshotBuilder.js");
8
+ const hotspotBuilder_js_1 = require("./hotspotBuilder.js");
9
+ const closureConstants_js_1 = require("./closureConstants.js");
10
+ const confidence_js_1 = require("./confidence.js");
11
+ function workspaceIdFromRoot(root) {
12
+ let h = 0;
13
+ const s = root.replace(/\\/g, '/');
14
+ for (let i = 0; i < s.length; i++) {
15
+ h = (Math.imul(31, h) + s.charCodeAt(i)) | 0;
16
+ }
17
+ return Math.abs(h).toString(16).slice(0, 12);
18
+ }
19
+ function buildGraphMetadata(args) {
20
+ return {
21
+ version: types_js_1.KNOWLEDGE_ENGINE_VERSION,
22
+ schemaVersion: types_js_1.KNOWLEDGE_SCHEMA_VERSION,
23
+ closureVersion: closureConstants_js_1.CLOSURE_VERSION,
24
+ generatedAt: args.now,
25
+ workspaceId: workspaceIdFromRoot(args.workspaceRoot),
26
+ graphBuildId: `graph_${args.now.toString(36)}`,
27
+ sourceVersion: args.sourceVersion ?? (0, version_js_1.getContoriumPackageVersion)(),
28
+ rebuildTrigger: args.rebuildTrigger,
29
+ lastCommitHash: args.lastCommitHash,
30
+ };
31
+ }
32
+ function withEdgeConfidence(edges) {
33
+ return edges.map((e) => ({
34
+ ...e,
35
+ confidence: e.confidence ?? (e.type === 'supports_intent' ? e.weight : 0.85),
36
+ }));
37
+ }
38
+ function withMappingConfidence(mappings) {
39
+ return mappings.map((m) => ({
40
+ ...m,
41
+ confidence: m.confidence ?? m.score,
42
+ }));
43
+ }
44
+ /** schemaVersion switch — upgrade legacy graphs on read. */
45
+ function normalizeKnowledgeGraph(raw, workspaceRoot) {
46
+ if (!raw || typeof raw !== 'object') {
47
+ return undefined;
48
+ }
49
+ const r = raw;
50
+ if (r.meta && typeof r.meta === 'object') {
51
+ const kg = raw;
52
+ const schema = (kg.meta.schemaVersion ?? types_js_1.KNOWLEDGE_SCHEMA_VERSION).toString();
53
+ if (schema !== types_js_1.KNOWLEDGE_SCHEMA_VERSION) {
54
+ return upgradeSchema(kg, workspaceRoot);
55
+ }
56
+ return {
57
+ ...kg,
58
+ edges: (0, confidence_js_1.filterCanonicalEdges)(withEdgeConfidence(kg.edges ?? [])),
59
+ intentMappings: withMappingConfidence(kg.intentMappings ?? []),
60
+ inferenceMappings: kg.inferenceMappings ?? [],
61
+ hotspots: (kg.hotspots ?? []).map((h) => ({
62
+ ...h,
63
+ lifecycle: h.lifecycle ?? 'active',
64
+ })),
65
+ snapshot: kg.snapshot ??
66
+ (0, snapshotBuilder_js_1.buildKnowledgeSnapshot)({
67
+ nodes: kg.nodes,
68
+ edges: kg.edges,
69
+ intentMappings: kg.intentMappings,
70
+ hotspots: kg.hotspots ?? [],
71
+ nextActions: [],
72
+ now: kg.meta.generatedAt,
73
+ }),
74
+ };
75
+ }
76
+ if (r.version === 1) {
77
+ return migrateLegacyV1(raw, workspaceRoot);
78
+ }
79
+ return undefined;
80
+ }
81
+ function upgradeSchema(kg, workspaceRoot) {
82
+ return normalizeKnowledgeGraph({
83
+ ...kg,
84
+ meta: { ...kg.meta, schemaVersion: types_js_1.KNOWLEDGE_SCHEMA_VERSION },
85
+ }, workspaceRoot);
86
+ }
87
+ function migrateLegacyV1(legacy, workspaceRoot) {
88
+ const edges = (legacy.edges ?? []).map((e) => ({
89
+ source: e.source,
90
+ target: e.target,
91
+ type: e.type,
92
+ weight: e.weight,
93
+ confidence: e.confidence ?? (e.type === 'supports_intent' ? e.weight : 0.85),
94
+ }));
95
+ const intentMappings = (legacy.intentMappings ?? []).map((m) => ({
96
+ intentId: m.intentId,
97
+ functionId: m.functionId,
98
+ score: m.score,
99
+ confidence: m.confidence ?? m.score,
100
+ signals: m.signals,
101
+ }));
102
+ const { canonical, inference } = (0, confidence_js_1.splitMappingsByCanonicalThreshold)(intentMappings);
103
+ const partial = {
104
+ nodes: legacy.nodes ?? [],
105
+ edges: (0, confidence_js_1.filterCanonicalEdges)(edges),
106
+ intentMappings: canonical,
107
+ inferenceMappings: inference,
108
+ reasonTraces: legacy.reasonTraces ?? [],
109
+ intentTrees: legacy.intentTrees ?? [],
110
+ };
111
+ const hotspots = (0, hotspotBuilder_js_1.buildHotspots)({
112
+ nodes: partial.nodes,
113
+ edges: partial.edges,
114
+ intentMappings: partial.intentMappings,
115
+ editCounts: new Map(),
116
+ gitFrequency: new Map(),
117
+ now: legacy.generatedAt,
118
+ });
119
+ const snapshot = (0, snapshotBuilder_js_1.buildKnowledgeSnapshot)({
120
+ nodes: partial.nodes,
121
+ edges: partial.edges,
122
+ intentMappings: partial.intentMappings,
123
+ hotspots,
124
+ nextActions: [],
125
+ now: legacy.generatedAt,
126
+ });
127
+ return {
128
+ meta: buildGraphMetadata({
129
+ workspaceRoot: workspaceRoot ?? 'unknown',
130
+ now: legacy.generatedAt,
131
+ }),
132
+ ...partial,
133
+ hotspots,
134
+ snapshot,
135
+ };
136
+ }
@@ -0,0 +1,13 @@
1
+ export type KnowledgeRebuildTrigger = 'git_commit' | 'file_batch' | 'intent_change' | 'idle' | 'initial' | 'change';
2
+ export interface RebuildTriggerInput {
3
+ changedFileCount: number;
4
+ intentChanged: boolean;
5
+ lastBuildAt?: number;
6
+ now: number;
7
+ hasNewCommit?: boolean;
8
+ isInitial?: boolean;
9
+ }
10
+ /** When to rebuild knowledge.json (Closure §9.3). */
11
+ export declare function resolveKnowledgeRebuildTrigger(input: RebuildTriggerInput): KnowledgeRebuildTrigger;
12
+ export declare function shouldRebuildKnowledgeGraph(input: RebuildTriggerInput): boolean;
13
+ //# sourceMappingURL=rebuildTrigger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rebuildTrigger.d.ts","sourceRoot":"","sources":["../../../src/understanding/knowledgeGraph/rebuildTrigger.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,uBAAuB,GAC/B,YAAY,GACZ,YAAY,GACZ,eAAe,GACf,MAAM,GACN,SAAS,GACT,QAAQ,CAAC;AAEb,MAAM,WAAW,mBAAmB;IAClC,gBAAgB,EAAE,MAAM,CAAC;IACzB,aAAa,EAAE,OAAO,CAAC;IACvB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,qDAAqD;AACrD,wBAAgB,8BAA8B,CAAC,KAAK,EAAE,mBAAmB,GAAG,uBAAuB,CAiBlG;AAED,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,mBAAmB,GAAG,OAAO,CAS/E"}
@@ -0,0 +1,34 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.resolveKnowledgeRebuildTrigger = resolveKnowledgeRebuildTrigger;
4
+ exports.shouldRebuildKnowledgeGraph = shouldRebuildKnowledgeGraph;
5
+ const closureConstants_js_1 = require("./closureConstants.js");
6
+ /** When to rebuild knowledge.json (Closure §9.3). */
7
+ function resolveKnowledgeRebuildTrigger(input) {
8
+ if (input.isInitial) {
9
+ return 'initial';
10
+ }
11
+ if (input.hasNewCommit) {
12
+ return 'git_commit';
13
+ }
14
+ if (input.changedFileCount >= closureConstants_js_1.REBUILD_FILE_THRESHOLD) {
15
+ return 'file_batch';
16
+ }
17
+ if (input.intentChanged) {
18
+ return 'intent_change';
19
+ }
20
+ if (input.lastBuildAt != null && input.now - input.lastBuildAt >= closureConstants_js_1.REBUILD_IDLE_MS) {
21
+ return 'idle';
22
+ }
23
+ return 'change';
24
+ }
25
+ function shouldRebuildKnowledgeGraph(input) {
26
+ if (input.isInitial || !input.lastBuildAt) {
27
+ return true;
28
+ }
29
+ const trigger = resolveKnowledgeRebuildTrigger(input);
30
+ if (trigger === 'idle' && input.changedFileCount === 0) {
31
+ return true;
32
+ }
33
+ return input.changedFileCount > 0 || input.intentChanged || !!input.hasNewCommit;
34
+ }
@@ -0,0 +1,17 @@
1
+ import type { HotspotNode, IntentFunctionMapping, KnowledgeEdge, KnowledgeNode, KnowledgeSnapshot } from './types.js';
2
+ export interface SnapshotBuildInput {
3
+ nodes: KnowledgeNode[];
4
+ edges: KnowledgeEdge[];
5
+ intentMappings: IntentFunctionMapping[];
6
+ hotspots: HotspotNode[];
7
+ nextActions: string[];
8
+ now: number;
9
+ }
10
+ /**
11
+ * Snapshot Layer — compression projection from canonical graph only (Closure §9).
12
+ * snapshot = compression(graph, weight); never a second truth source.
13
+ */
14
+ export declare function buildKnowledgeSnapshot(input: SnapshotBuildInput): KnowledgeSnapshot;
15
+ /** Filter graph relations by minimum confidence (MCP / export projection). */
16
+ export declare function filterMappingsByConfidence(mappings: IntentFunctionMapping[], minConfidence: number): IntentFunctionMapping[];
17
+ //# sourceMappingURL=snapshotBuilder.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"snapshotBuilder.d.ts","sourceRoot":"","sources":["../../../src/understanding/knowledgeGraph/snapshotBuilder.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EACV,WAAW,EACX,qBAAqB,EACrB,aAAa,EACb,aAAa,EACb,iBAAiB,EAClB,MAAM,YAAY,CAAC;AAEpB,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,aAAa,EAAE,CAAC;IACvB,KAAK,EAAE,aAAa,EAAE,CAAC;IACvB,cAAc,EAAE,qBAAqB,EAAE,CAAC;IACxC,QAAQ,EAAE,WAAW,EAAE,CAAC;IACxB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,GAAG,EAAE,MAAM,CAAC;CACb;AAkBD;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,kBAAkB,GAAG,iBAAiB,CAqDnF;AAED,8EAA8E;AAC9E,wBAAgB,0BAA0B,CACxC,QAAQ,EAAE,qBAAqB,EAAE,EACjC,aAAa,EAAE,MAAM,GACpB,qBAAqB,EAAE,CAEzB"}