mcp-cognition-engine 1.0.0-alpha.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 (158) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +281 -0
  3. package/dist/cli.d.ts +18 -0
  4. package/dist/cli.d.ts.map +1 -0
  5. package/dist/cli.js +66 -0
  6. package/dist/cli.js.map +1 -0
  7. package/dist/cognition-engine/ast-constraint-solver.d.ts +67 -0
  8. package/dist/cognition-engine/ast-constraint-solver.d.ts.map +1 -0
  9. package/dist/cognition-engine/ast-constraint-solver.js +294 -0
  10. package/dist/cognition-engine/ast-constraint-solver.js.map +1 -0
  11. package/dist/cognition-engine/constraint-validator.d.ts +35 -0
  12. package/dist/cognition-engine/constraint-validator.d.ts.map +1 -0
  13. package/dist/cognition-engine/constraint-validator.js +55 -0
  14. package/dist/cognition-engine/constraint-validator.js.map +1 -0
  15. package/dist/cognition-engine/graph-traverser.d.ts +43 -0
  16. package/dist/cognition-engine/graph-traverser.d.ts.map +1 -0
  17. package/dist/cognition-engine/graph-traverser.js +205 -0
  18. package/dist/cognition-engine/graph-traverser.js.map +1 -0
  19. package/dist/cognition-engine/index.d.ts +51 -0
  20. package/dist/cognition-engine/index.d.ts.map +1 -0
  21. package/dist/cognition-engine/index.js +60 -0
  22. package/dist/cognition-engine/index.js.map +1 -0
  23. package/dist/cognition-engine/intent-recognizer.d.ts +25 -0
  24. package/dist/cognition-engine/intent-recognizer.d.ts.map +1 -0
  25. package/dist/cognition-engine/intent-recognizer.js +226 -0
  26. package/dist/cognition-engine/intent-recognizer.js.map +1 -0
  27. package/dist/cognition-engine/types.d.ts +96 -0
  28. package/dist/cognition-engine/types.d.ts.map +1 -0
  29. package/dist/cognition-engine/types.js +17 -0
  30. package/dist/cognition-engine/types.js.map +1 -0
  31. package/dist/conflict/arbitrator.d.ts +24 -0
  32. package/dist/conflict/arbitrator.d.ts.map +1 -0
  33. package/dist/conflict/arbitrator.js +43 -0
  34. package/dist/conflict/arbitrator.js.map +1 -0
  35. package/dist/index.d.ts +17 -0
  36. package/dist/index.d.ts.map +1 -0
  37. package/dist/index.js +90 -0
  38. package/dist/index.js.map +1 -0
  39. package/dist/legacy-engine/ast-diff.d.ts +23 -0
  40. package/dist/legacy-engine/ast-diff.d.ts.map +1 -0
  41. package/dist/legacy-engine/ast-diff.js +146 -0
  42. package/dist/legacy-engine/ast-diff.js.map +1 -0
  43. package/dist/legacy-engine/ast-node.d.ts +24 -0
  44. package/dist/legacy-engine/ast-node.d.ts.map +1 -0
  45. package/dist/legacy-engine/ast-node.js +52 -0
  46. package/dist/legacy-engine/ast-node.js.map +1 -0
  47. package/dist/legacy-engine/parsers.d.ts +34 -0
  48. package/dist/legacy-engine/parsers.d.ts.map +1 -0
  49. package/dist/legacy-engine/parsers.js +134 -0
  50. package/dist/legacy-engine/parsers.js.map +1 -0
  51. package/dist/legacy-engine/regex-fallback.d.ts +23 -0
  52. package/dist/legacy-engine/regex-fallback.d.ts.map +1 -0
  53. package/dist/legacy-engine/regex-fallback.js +40 -0
  54. package/dist/legacy-engine/regex-fallback.js.map +1 -0
  55. package/dist/legacy-engine/rule-generator.d.ts +31 -0
  56. package/dist/legacy-engine/rule-generator.d.ts.map +1 -0
  57. package/dist/legacy-engine/rule-generator.js +54 -0
  58. package/dist/legacy-engine/rule-generator.js.map +1 -0
  59. package/dist/legacy-engine/rule-matcher.d.ts +28 -0
  60. package/dist/legacy-engine/rule-matcher.d.ts.map +1 -0
  61. package/dist/legacy-engine/rule-matcher.js +79 -0
  62. package/dist/legacy-engine/rule-matcher.js.map +1 -0
  63. package/dist/legacy-engine/token-controller.d.ts +31 -0
  64. package/dist/legacy-engine/token-controller.d.ts.map +1 -0
  65. package/dist/legacy-engine/token-controller.js +66 -0
  66. package/dist/legacy-engine/token-controller.js.map +1 -0
  67. package/dist/middleware/response-validation.d.ts +27 -0
  68. package/dist/middleware/response-validation.d.ts.map +1 -0
  69. package/dist/middleware/response-validation.js +50 -0
  70. package/dist/middleware/response-validation.js.map +1 -0
  71. package/dist/modes/confirm.d.ts +29 -0
  72. package/dist/modes/confirm.d.ts.map +1 -0
  73. package/dist/modes/confirm.js +27 -0
  74. package/dist/modes/confirm.js.map +1 -0
  75. package/dist/modes/silent.d.ts +24 -0
  76. package/dist/modes/silent.d.ts.map +1 -0
  77. package/dist/modes/silent.js +24 -0
  78. package/dist/modes/silent.js.map +1 -0
  79. package/dist/resources/cognition-resources.d.ts +28 -0
  80. package/dist/resources/cognition-resources.d.ts.map +1 -0
  81. package/dist/resources/cognition-resources.js +124 -0
  82. package/dist/resources/cognition-resources.js.map +1 -0
  83. package/dist/storage/client.d.ts +26 -0
  84. package/dist/storage/client.d.ts.map +1 -0
  85. package/dist/storage/client.js +45 -0
  86. package/dist/storage/client.js.map +1 -0
  87. package/dist/storage/cognition-repository.d.ts +55 -0
  88. package/dist/storage/cognition-repository.d.ts.map +1 -0
  89. package/dist/storage/cognition-repository.js +287 -0
  90. package/dist/storage/cognition-repository.js.map +1 -0
  91. package/dist/storage/cognition-types.d.ts +96 -0
  92. package/dist/storage/cognition-types.d.ts.map +1 -0
  93. package/dist/storage/cognition-types.js +41 -0
  94. package/dist/storage/cognition-types.js.map +1 -0
  95. package/dist/storage/conflict-repo.d.ts +41 -0
  96. package/dist/storage/conflict-repo.d.ts.map +1 -0
  97. package/dist/storage/conflict-repo.js +67 -0
  98. package/dist/storage/conflict-repo.js.map +1 -0
  99. package/dist/storage/diff-log-repo.d.ts +48 -0
  100. package/dist/storage/diff-log-repo.d.ts.map +1 -0
  101. package/dist/storage/diff-log-repo.js +51 -0
  102. package/dist/storage/diff-log-repo.js.map +1 -0
  103. package/dist/storage/metric-repo.d.ts +20 -0
  104. package/dist/storage/metric-repo.d.ts.map +1 -0
  105. package/dist/storage/metric-repo.js +36 -0
  106. package/dist/storage/metric-repo.js.map +1 -0
  107. package/dist/storage/rule-repo.d.ts +66 -0
  108. package/dist/storage/rule-repo.d.ts.map +1 -0
  109. package/dist/storage/rule-repo.js +188 -0
  110. package/dist/storage/rule-repo.js.map +1 -0
  111. package/dist/tools/analyze-workspace.d.ts +26 -0
  112. package/dist/tools/analyze-workspace.d.ts.map +1 -0
  113. package/dist/tools/analyze-workspace.js +147 -0
  114. package/dist/tools/analyze-workspace.js.map +1 -0
  115. package/dist/tools/capture-diff.d.ts +26 -0
  116. package/dist/tools/capture-diff.d.ts.map +1 -0
  117. package/dist/tools/capture-diff.js +58 -0
  118. package/dist/tools/capture-diff.js.map +1 -0
  119. package/dist/tools/cognition-tools.d.ts +60 -0
  120. package/dist/tools/cognition-tools.d.ts.map +1 -0
  121. package/dist/tools/cognition-tools.js +170 -0
  122. package/dist/tools/cognition-tools.js.map +1 -0
  123. package/dist/tools/config-tools.d.ts +29 -0
  124. package/dist/tools/config-tools.d.ts.map +1 -0
  125. package/dist/tools/config-tools.js +58 -0
  126. package/dist/tools/config-tools.js.map +1 -0
  127. package/dist/tools/confirm-rule.d.ts +32 -0
  128. package/dist/tools/confirm-rule.d.ts.map +1 -0
  129. package/dist/tools/confirm-rule.js +64 -0
  130. package/dist/tools/confirm-rule.js.map +1 -0
  131. package/dist/tools/injection-approval.d.ts +43 -0
  132. package/dist/tools/injection-approval.d.ts.map +1 -0
  133. package/dist/tools/injection-approval.js +102 -0
  134. package/dist/tools/injection-approval.js.map +1 -0
  135. package/dist/tools/list-rules.d.ts +24 -0
  136. package/dist/tools/list-rules.d.ts.map +1 -0
  137. package/dist/tools/list-rules.js +20 -0
  138. package/dist/tools/list-rules.js.map +1 -0
  139. package/dist/tools/query-rules.d.ts +25 -0
  140. package/dist/tools/query-rules.d.ts.map +1 -0
  141. package/dist/tools/query-rules.js +65 -0
  142. package/dist/tools/query-rules.js.map +1 -0
  143. package/dist/tools/resolve-conflict.d.ts +33 -0
  144. package/dist/tools/resolve-conflict.d.ts.map +1 -0
  145. package/dist/tools/resolve-conflict.js +35 -0
  146. package/dist/tools/resolve-conflict.js.map +1 -0
  147. package/dist/types.d.ts +190 -0
  148. package/dist/types.d.ts.map +1 -0
  149. package/dist/types.js +50 -0
  150. package/dist/types.js.map +1 -0
  151. package/docs/api-reference.md +1229 -0
  152. package/docs/community/feedback-playbook.md +94 -0
  153. package/docs/integration-snippets.md +100 -0
  154. package/docs/mcp-integration-guide.md +151 -0
  155. package/docs/phase4-mcp-feedback.md +155 -0
  156. package/docs/trust-governance-protocol.md +72 -0
  157. package/package.json +74 -0
  158. package/prisma/schema.prisma +145 -0
@@ -0,0 +1,1229 @@
1
+ # API Reference
2
+
3
+ Auto-generated from JSDoc comments. Generated: 2026-06-15
4
+
5
+ ---
6
+
7
+ ## Module: `cognition-engine/ast-constraint-solver`
8
+
9
+ > Copyright 2026 熊高锐 Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. /
10
+
11
+ ### `parseConstraintDsl`
12
+
13
+ Copyright 2026 熊高锐 Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. /
14
+
15
+ ```typescript
16
+ /**
17
+ * @file AST Constraint Solver
18
+ * Transforms cognition AstTemplate DSL into executable AST constraints.
19
+ * Outputs structured validation results and transform patches.
20
+ * NEVER generates natural language — all output is machine-readable.
21
+ *
22
+ * Reuses: legacy-engine/ast-node.ts (computeSignature), legacy-engine/parsers.ts (parseToAST)
23
+ */
24
+
25
+ import { computeSignature } from "../legacy-engine/ast-node.js";
26
+ import { parseToAST } from "../legacy-engine/parsers.js";
27
+ import type { ASTNode, NodeSignature } from "../types.js";
28
+ import type { CognitionNodeData } from "../storage/cognition-types.js";
29
+ import type {
30
+ AstConstraint,
31
+ FieldConstraint,
32
+ ValidationResult,
33
+ ValidationFailure,
34
+ TransformPatch,
35
+ TransformOp,
36
+ } from "./types.js";
37
+
38
+ // ── DSL Parser ────────────────────────────────────────────
39
+
40
+ /**
41
+ * Parse templateDsl JSON string into AstConstraint array.
42
+ */
43
+ export function parseConstraintDsl
44
+ ```
45
+
46
+ ### `bindConstraints`
47
+
48
+ Map of placeholder → bound value
49
+
50
+ ```typescript
51
+ bindings: Record<string, string>;
52
+ }
53
+
54
+ /**
55
+ * Bind {{placeholder}} values in a constraint to actual AST node text.
56
+ * Walks the AST to find nodes matching each constraint's nodeType,
57
+ * then extracts text values for placeholders.
58
+ */
59
+ export function bindConstraints
60
+ ```
61
+
62
+ ### `validateConstraints`
63
+
64
+ Extract a field value from an AST node.
65
+
66
+ ```typescript
67
+ function extractFieldValue(ast: ASTNode, nodeType: string, field: string): string | null {
68
+ const matchingNodes = findNodesByType(ast, nodeType);
69
+ if (matchingNodes.length === 0) return null;
70
+
71
+ const node = matchingNodes[0];
72
+ // Check if any child's type matches the field name
73
+ for (const child of node.children) {
74
+ if (child.type === field) {
75
+ return child.text;
76
+ }
77
+ }
78
+ // Fallback: return node text itself
79
+ return field === "name" ? node.text : null;
80
+ }
81
+
82
+ function findNodesByType(node: ASTNode, type: string): ASTNode[] {
83
+ const results: ASTNode[] = [];
84
+ if (node.type === type) results.push(node);
85
+ for (const child of node.children) {
86
+ results.push(...findNodesByType(child, type));
87
+ }
88
+ return results;
89
+ }
90
+
91
+ // ── Constraint Validation ─────────────────────────────────
92
+
93
+ /**
94
+ * Validate an AST against a set of bound constraints.
95
+ *
96
+ * @param constraints Parsed + bound AstConstraint array
97
+ * @param nodeId Source cognition node ID (for traceability)
98
+ * @param templateDsl Original template DSL string
99
+ * @param ast Target AST to validate
100
+ * @returns Structured validation result
101
+ */
102
+ export function validateConstraints
103
+ ```
104
+
105
+ ### `generatePatchFromFailures`
106
+
107
+ Generate a transform patch from validation failures.
108
+
109
+ ```typescript
110
+ export function generatePatchFromFailures
111
+ ```
112
+
113
+ ### `solveConstraints`
114
+
115
+ Run the full constraint-solving pipeline:
116
  1. Parse templateDSL from cognition nodes
1
117
  2. Parse file content to AST
2
118
  3. Bind {{placeholder}} values
3
119
  4. Validate constraints
4
120
  5. Generate transform patches
121
+
122
+ ```typescript
123
+ export async function solveConstraints
124
+ ```
125
+
126
+ **Parameters:**
127
+
128
+ | Name | Description |
129
+ |------|-------------|
130
+ | `cognitionNodes` | Nodes with astTemplate to check |
131
+ | `fileContent` | Source code to validate against |
132
+ | `language` | Language for AST parsing |
133
+
134
+ **Returns:** Validation + patch results
135
+
136
+ ---
137
+
138
+ ## Module: `cognition-engine/constraint-validator`
139
+
140
+ > Copyright 2026 熊高锐 Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. / Reuses Phase 3 AstTemplate DSL parser for dual-mode validation. /
141
+
142
+ ### `validateCode`
143
+
144
+ Copyright 2026 熊高锐 Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. /
145
+
146
+ ```typescript
147
+ /**
148
+ * @file Constraint Validator — Trust & Governance Layer
149
+ * Reuses Phase 3 AstTemplate DSL parser for dual-mode validation.
150
+ */
151
+ import { parseConstraintDsl, validateConstraints } from "../cognition-engine/ast-constraint-solver.js";
152
+ import { CognitionRepository } from "../storage/cognition-repository.js";
153
+
154
+ export type ValidationMode = "REJECT" | "WARN";
155
+ export type RuleLevel = "GLOBAL" | "PROJECT";
156
+
157
+ export interface ConstraintViolation {
158
+ ruleId: string;
159
+ ruleLevel: RuleLevel;
160
+ mode: ValidationMode;
161
+ constraintPath: string;
162
+ expected: string;
163
+ actual: string;
164
+ message: string;
165
+ }
166
+
167
+ export interface ValidationReport {
168
+ passed: boolean;
169
+ violations: ConstraintViolation[];
170
+ hardBlocks: number;
171
+ softWarnings: number;
172
+ }
173
+
174
+ /** Validate code content against constraints. */
175
+ export async function validateCode
176
+ ```
177
+
178
+ ---
179
+
180
+ ## Module: `cognition-engine/index`
181
+
182
+ > Copyright 2026 熊高锐 Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. /
183
+
184
+ ### `analyzeCodeContext`
185
+
186
+ Copyright 2026 熊高锐 Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. /
187
+
188
+ ```typescript
189
+ /**
190
+ * @file Cognition Engine — unified entry point.
191
+ *
192
+ * The cognition engine replaces the legacy rule-matcher with a
193
+ * three-component pipeline:
194
+ *
195
+ * 1. IntentRecognizer — classifies diff type (REFACTOR / BUGFIX / BOILERPLATE)
196
+ * 2. GraphTraverser — weighted BFS over cognition graph
197
+ * 3. AstConstraintSolver — transforms templates into AST-level checks
198
+ *
199
+ * Usage:
200
+ * import { analyzeCodeContext } from "./cognition-engine/index.js";
201
+ * const result = await analyzeCodeContext(lang, path, content);
202
+ */
203
+
204
+ export { recognizeIntent } from "./intent-recognizer.js";
205
+ export type { IntentResult, IntentType } from "./types.js";
206
+
207
+ export { GraphTraverser } from "./graph-traverser.js";
208
+ export type { TraversalOptions, TraversalResult, ScoredCognitionNode } from "./types.js";
209
+
210
+ export {
211
+ solveConstraints,
212
+ parseConstraintDsl,
213
+ bindConstraints,
214
+ validateConstraints,
215
+ generatePatchFromFailures,
216
+ } from "./ast-constraint-solver.js";
217
+ export type { AstConstraint, FieldConstraint, ValidationResult, TransformPatch } from "./types.js";
218
+
219
+ import { recognizeIntent } from "./intent-recognizer.js";
220
+ import { GraphTraverser } from "./graph-traverser.js";
221
+ import { solveConstraints } from "./ast-constraint-solver.js";
222
+ import type { TraversalResult, ValidationResult, TransformPatch, IntentResult } from "./types.js";
223
+
224
+ /**
225
+ * Full pipeline: analyze diff → traverse graph → solve AST constraints.
226
+ * The one-shot entry point for the cognition engine.
227
+ */
228
+ export async function analyzeCodeContext
229
+ ```
230
+
231
+ ---
232
+
233
+ ## Module: `cognition-engine/intent-recognizer`
234
+
235
+ > Copyright 2026 熊高锐 Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. /
236
+
237
+ ### `recognizeIntent`
238
+
239
+ Copyright 2026 熊高锐 Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. /
240
+
241
+ ```typescript
242
+ /**
243
+ * @file Intent Recognizer
244
+ * Analyzes code diffs and classifies the developer intent behind them.
245
+ * Maps to three intent levels: REFACTOR, BUGFIX, BOILERPLATE.
246
+ * The result biases Graph Traverser traversal strategy.
247
+ *
248
+ * Reuses: legacy-engine/parsers.ts (parseToAST) for optional AST analysis
249
+ */
250
+
251
+ import { parseToAST } from "../legacy-engine/parsers.js";
252
+ import type { ASTNode } from "../types.js";
253
+ import type { IntentResult, IntentType } from "./types.js";
254
+
255
+ // ── Constants ─────────────────────────────────────────────
256
+
257
+ const REFACTOR_THRESHOLD = { minFiles: 2, minAddedRatio: 0.3, minNodeTypes: 3 };
258
+ const BUGFIX_THRESHOLD = { maxFiles: 2, maxChangedLines: 50, errorKeywordRatio: 0.1 };
259
+ const BOILERPLATE_THRESHOLD = { addRemoveRatio: 5.0, minAddedLines: 20 };
260
+
261
+ const ERROR_KEYWORDS = [
262
+ "error", "undefined", "null", "catch", "throw", "try",
263
+ "fail", "invalid", "missing", "fallback", "guard", "check",
264
+ "assert", "validate", "optional", "??", "?. ", "??=",
265
+ ];
266
+
267
+ const REFACTOR_KEYWORDS = [
268
+ "extract", "rename", "move", "split", "merge", "inline",
269
+ "abstract", "interface", "type",
270
+ ];
271
+
272
+ // ── Diff Parsing ──────────────────────────────────────────
273
+
274
+ interface DiffStats {
275
+ filesChanged: number;
276
+ addedLines: number;
277
+ removedLines: number;
278
+ perFile: Map<string, { added: number; removed: number }>;
279
+ hunks: number;
280
+ }
281
+
282
+ function parseDiffStats(diffContent: string): DiffStats {
283
+ const stats: DiffStats = {
284
+ filesChanged: 0,
285
+ addedLines: 0,
286
+ removedLines: 0,
287
+ perFile: new Map(),
288
+ hunks: 0,
289
+ };
290
+
291
+ let currentFile = "unknown";
292
+ for (const line of diffContent.split("\n")) {
293
+ if (line.startsWith("diff --git ")) {
294
+ stats.filesChanged++;
295
+ const match = line.match(/diff --git a\/(.+) b\//);
296
+ if (match) currentFile = match[1];
297
+ if (!stats.perFile.has(currentFile)) {
298
+ stats.perFile.set(currentFile, { added: 0, removed: 0 });
299
+ }
300
+ } else if (line.startsWith("@@ ")) {
301
+ stats.hunks++;
302
+ } else if (line.startsWith("+") && !line.startsWith("+++")) {
303
+ stats.addedLines++;
304
+ const pf = stats.perFile.get(currentFile);
305
+ if (pf) pf.added++;
306
+ } else if (line.startsWith("-") && !line.startsWith("---")) {
307
+ stats.removedLines++;
308
+ const pf = stats.perFile.get(currentFile);
309
+ if (pf) pf.removed++;
310
+ }
311
+ }
312
+ return stats;
313
+ }
314
+
315
+ // ── Node Type Analysis ────────────────────────────────────
316
+
317
+ async function analyzeNodeTypes(
318
+ diffContent: string,
319
+ filePath?: string,
320
+ ): Promise<string[]> {
321
+ const nodeTypes = new Set<string>();
322
+ const lines = diffContent.split("\n");
323
+
324
+ // Try AST analysis on file content (best effort)
325
+ if (filePath) {
326
+ for (const line of lines) {
327
+ if (line.startsWith("+") && !line.startsWith("+++")) {
328
+ const code = line.slice(1).trim();
329
+ if (code.length > 3) {
330
+ try {
331
+ const lang = filePath.endsWith(".ts") || filePath.endsWith(".tsx")
332
+ ? "typescript" : filePath.endsWith(".py") ? "python" : "javascript";
333
+ const result = await parseToAST(code, lang);
334
+ collectNodeTypes(result.ast, nodeTypes);
335
+ } catch {
336
+ // Silently continue — AST analysis is best-effort
337
+ }
338
+ }
339
+ }
340
+ }
341
+ }
342
+
343
+ // Fallback: keyword-based detection
344
+ const allText = lines.filter(l => l.startsWith("+") || l.startsWith("-")).join(" ").toLowerCase();
345
+ if (!nodeTypes.size) {
346
+ const keywordMap: Record<string, string[]> = {
347
+ function_declaration: ["function", "=>", "=>"],
348
+ class_declaration: ["class "],
349
+ variable_declaration: ["const ", "let ", "var "],
350
+ if_statement: ["if ", "else "],
351
+ try_statement: ["try ", "catch ", "finally"],
352
+ import_statement: ["import ", "require("],
353
+ export_statement: ["export "],
354
+ interface_declaration: ["interface "],
355
+ type_alias: ["type ", "| ", "& "],
356
+ return_statement: ["return "],
357
+ };
358
+ for (const [nt, keywords] of Object.entries(keywordMap)) {
359
+ if (keywords.some(k => allText.includes(k))) {
360
+ nodeTypes.add(nt);
361
+ }
362
+ }
363
+ }
364
+
365
+ return [...nodeTypes];
366
+ }
367
+
368
+ function collectNodeTypes(node: ASTNode, types: Set<string>): void {
369
+ types.add(node.type);
370
+ for (const child of node.children) {
371
+ collectNodeTypes(child, types);
372
+ }
373
+ }
374
+
375
+ // ── Intent Classification ─────────────────────────────────
376
+
377
+ function classifyIntent(
378
+ stats: DiffStats,
379
+ nodeTypes: string[],
380
+ diffContent: string,
381
+ ): { intent: IntentType; confidence: number; reasoning: string[] } {
382
+ const totalChanged = stats.addedLines + stats.removedLines;
383
+ const addRemoveRatio = stats.removedLines > 0
384
+ ? stats.addedLines / stats.removedLines
385
+ : stats.addedLines > 0 ? Infinity : 0;
386
+ const allText = diffContent.toLowerCase();
387
+ const errorHits = ERROR_KEYWORDS.filter(k => allText.includes(k)).length;
388
+ const errorRatio = allText.length > 0 ? errorHits / (allText.split("\n").length) : 0;
389
+ const refactorHits = REFACTOR_KEYWORDS.filter(k => allText.includes(k)).length;
390
+ const uniqueNodeTypes = new Set(nodeTypes);
391
+
392
+ const reasoning: string[] = [];
393
+ let scores = { refactor: 0, bugfix: 0, boilerplate: 0 };
394
+
395
+ // REFACTOR signals
396
+ if (stats.filesChanged >= REFACTOR_THRESHOLD.minFiles) {
397
+ scores.refactor += 0.3;
398
+ reasoning.push(`multi-file change (${stats.filesChanged} files)`);
399
+ }
400
+ if (uniqueNodeTypes.size >= REFACTOR_THRESHOLD.minNodeTypes) {
401
+ scores.refactor += 0.2;
402
+ reasoning.push(`diverse AST types affected (${uniqueNodeTypes.size} types)`);
403
+ }
404
+ if (refactorHits > 2) {
405
+ scores.refactor += 0.2;
406
+ reasoning.push('refactoring keywords detected');
407
+ }
408
+ if (stats.hunks > 3 && stats.filesChanged > 1) {
409
+ scores.refactor += 0.3;
410
+ reasoning.push('cross-module structural changes');
411
+ }
412
+
413
+ // BUGFIX signals
414
+ if (totalChanged <= BUGFIX_THRESHOLD.maxChangedLines) {
415
+ scores.bugfix += 0.2;
416
+ reasoning.push(`small change footprint (${totalChanged} lines)`);
417
+ }
418
+ if (stats.filesChanged <= BUGFIX_THRESHOLD.maxFiles) {
419
+ scores.bugfix += 0.1;
420
+ }
421
+ if (errorRatio >= BUGFIX_THRESHOLD.errorKeywordRatio) {
422
+ scores.bugfix += 0.3;
423
+ reasoning.push('error-handling keywords present');
424
+ }
425
+ if (uniqueNodeTypes.has("try_statement") || uniqueNodeTypes.has("if_statement")) {
426
+ scores.bugfix += 0.2;
427
+ reasoning.push(`conditional / guard patterns`);
428
+ }
429
+
430
+ // BOILERPLATE signals
431
+ if (addRemoveRatio >= BOILERPLATE_THRESHOLD.addRemoveRatio) {
432
+ scores.boilerplate += 0.3;
433
+ reasoning.push(`high add/remove ratio (${addRemoveRatio.toFixed(1)})`);
434
+ }
435
+ if (stats.addedLines >= BOILERPLATE_THRESHOLD.minAddedLines && stats.removedLines < 5) {
436
+ scores.boilerplate += 0.3;
437
+ reasoning.push('net-new code addition');
438
+ }
439
+ if (uniqueNodeTypes.size <= 2 && stats.addedLines > 10) {
440
+ scores.boilerplate += 0.2;
441
+ reasoning.push('repetitive / template-like structure');
442
+ }
443
+
444
+ const maxScore = Math.max(scores.refactor, scores.bugfix, scores.boilerplate);
445
+ if (maxScore === 0) {
446
+ return { intent: "BUGFIX", confidence: 0.3, reasoning: ["no clear signal"] };
447
+ }
448
+
449
+ let intent: IntentType;
450
+ if (scores.refactor >= maxScore && scores.refactor >= 0.4) intent = "REFACTOR";
451
+ else if (scores.boilerplate >= maxScore && scores.boilerplate >= 0.3) intent = "BOILERPLATE";
452
+ else intent = "BUGFIX";
453
+
454
+ const confidence = Math.min(0.95, maxScore + 0.2);
455
+
456
+ if (reasoning.length === 0) reasoning.push("default classification");
457
+ return { intent, confidence, reasoning };
458
+ }
459
+
460
+ // ── Public API ────────────────────────────────────────────
461
+
462
+ /**
463
+ * Analyze a code diff and classify the developer intent.
464
+ *
465
+ * @param diffContent Unified diff text (from git diff output)
466
+ * @param filePath Optional file path for AST analysis
467
+ * @returns Structured intent classification
468
+ */
469
+ export async function recognizeIntent
470
+ ```
471
+
472
+ ---
473
+
474
+ ## Module: `cognition-engine/types`
475
+
476
+ > Copyright 2026 熊高锐 Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. /
477
+
478
+ ### `AstConstraint`
479
+
480
+ Copyright 2026 熊高锐 Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. /
481
+
482
+ ```typescript
483
+ /**
484
+ * @file Cognition Engine — type definitions.
485
+ * These types are specific to the cognition engine pipeline.
486
+ * Shared types consumed by tools live in ../types.js.
487
+ */
488
+
489
+ import type {
490
+ CognitionNodeData,
491
+ CognitionEdgeData,
492
+ CognitionTypeStr,
493
+ EdgeRelationStr,
494
+ } from "../storage/cognition-types.js";
495
+
496
+ // ── Intent Recognition ────────────────────────────────────
497
+
498
+ export type IntentType = "REFACTOR" | "BUGFIX" | "BOILERPLATE";
499
+
500
+ export interface IntentResult {
501
+ intent: IntentType;
502
+ confidence: number; // 0.0 – 1.0
503
+ reasoning: string[];
504
+ /** Diff statistics used for classification. */
505
+ stats: {
506
+ addedLines: number;
507
+ removedLines: number;
508
+ filesChanged: number;
509
+ nodeTypeChanges: string[];
510
+ };
511
+ }
512
+
513
+ // ── Graph Traversal ───────────────────────────────────────
514
+
515
+ export interface TraversalOptions {
516
+ /** Max BFS depth. Default 5. */
517
+ maxDepth?: number;
518
+ /** Minimum relevance score [0, 1] to include in results. */
519
+ minRelevance?: number;
520
+ /** Optional intent hint to bias edge weights. */
521
+ intentHint?: IntentType;
522
+ /** If set, only include nodes at these abstraction levels. */
523
+ abstractionLevelFilter?: number[];
524
+ /** Hard timeout in ms. Default 500. */
525
+ maxDurationMs?: number;
526
+ }
527
+
528
+ export interface ScoredCognitionNode {
529
+ node: CognitionNodeData;
530
+ relevanceScore: number;
531
+ /** Path trace: how this node was reached (edge trail). */
532
+ trace: string[];
533
+ }
534
+
535
+ export interface TraversalResult {
536
+ nodes: ScoredCognitionNode[];
537
+ edges: CognitionEdgeData[];
538
+ durationMs: number;
539
+ truncated: boolean;
540
+ }
541
+
542
+ // ── AST Constraint Solving ────────────────────────────────
543
+
544
+ /** DSL constraint: must be JSON-serializable for storage. */
545
+ export interface AstConstraint
546
+ ```
547
+
548
+ ---
549
+
550
+ ## Module: `legacy-engine/parsers`
551
+
552
+ ### `parseToAST`
553
+
554
+ Copyright 2026 熊高锐 Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. /
555
+
556
+ ```typescript
557
+ /**
558
+ * @deprecated LEGACY ENGINE MODULE — Preserved for reference only.
559
+ * Do NOT modify. The new cognition-engine module replaces this entire subsystem.
560
+ * See src/cognition-engine/ for the replacement.
561
+ */
562
+
563
+ import { fileURLToPath } from "node:url";
564
+ import path from "node:path";
565
+ import { ASTNode, AtomicOp, DiffResult } from "../types.js";
566
+ import { computeDiff } from "./ast-diff.js";
567
+ import { regexDiff } from "./regex-fallback.js";
568
+
569
+ // ── Path Resolution ──────────────────────────────────────────
570
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
571
+ const projectRoot = path.resolve(__dirname, "../..");
572
+
573
+ const WASM_PATHS: Record<string, string> = {
574
+ javascript: path.join(projectRoot, "node_modules", "tree-sitter-javascript", "tree-sitter-javascript.wasm"),
575
+ typescript: path.join(projectRoot, "node_modules", "tree-sitter-typescript", "tree-sitter-typescript.wasm"),
576
+ tsx: path.join(projectRoot, "node_modules", "tree-sitter-typescript", "tree-sitter-tsx.wasm"),
577
+ python: path.join(projectRoot, "node_modules", "tree-sitter-python", "tree-sitter-python.wasm"),
578
+ };
579
+
580
+ function getLanguageForFile(filePath: string): string {
581
+ const ext = path.extname(filePath).toLowerCase();
582
+ if (ext === ".tsx") return "tsx";
583
+ if (ext === ".ts") return "typescript";
584
+ if (ext === ".js" || ext === ".jsx" || ext === ".mjs" || ext === ".cjs") return "javascript";
585
+ if (ext === ".py") return "python";
586
+ return "javascript"; // default fallback
587
+ }
588
+
589
+ // ── Tree-sitter WASM Initialization ──────────────────────────
590
+ let tsInitialized = false;
591
+ let tsFailed = false;
592
+ const grammarCache = new Map<string, any>();
593
+ let ParserModule: any = null;
594
+
595
+ async function ensureTreeSitter(): Promise<boolean> {
596
+ if (tsInitialized) return true;
597
+ if (tsFailed) return false;
598
+ try {
599
+ ParserModule = await import("web-tree-sitter");
600
+ await ParserModule.Parser.init();
601
+ tsInitialized = true;
602
+ return true;
603
+ } catch (err) {
604
+ tsFailed = true;
605
+ console.error("[parsers] web-tree-sitter init failed:", err);
606
+ return false;
607
+ }
608
+ }
609
+
610
+ async function loadGrammar(language: string): Promise<any> {
611
+ if (grammarCache.has(language)) return grammarCache.get(language);
612
+ const wasmPath = WASM_PATHS[language];
613
+ if (!wasmPath) throw new Error(`No WASM path for language: ${language}`);
614
+
615
+ const fs = await import("node:fs");
616
+ if (!fs.existsSync(wasmPath)) {
617
+ throw new Error(`WASM file not found: ${wasmPath}`);
618
+ }
619
+
620
+ const lang = await ParserModule.Language.load(wasmPath);
621
+ grammarCache.set(language, lang);
622
+ return lang;
623
+ }
624
+
625
+ // ── Tree-sitter → ASTNode Conversion ────────────────────────
626
+ function treeSitterToAST(node: any): ASTNode {
627
+ return {
628
+ type: node.type,
629
+ text: node.text,
630
+ startByte: node.startIndex,
631
+ endByte: node.endIndex,
632
+ children: node.namedChildren.map((c: any) => treeSitterToAST(c)),
633
+ };
634
+ }
635
+
636
+ // ── Public API ───────────────────────────────────────────────
637
+
638
+ export interface ParserResult {
639
+ ast: ASTNode;
640
+ language: string;
641
+ parseSuccess: boolean;
642
+ }
643
+
644
+ /** Parse code to AST using web-tree-sitter, falling back to line-based AST on failure. */
645
+ export async function parseToAST
646
+ ```
647
+
648
+ ### `computeDiffWithFallback`
649
+
650
+ Compute diff with automatic AST → regex fallback chain.
651
+
652
+ ```typescript
653
+ export async function computeDiffWithFallback
654
+ ```
655
+
656
+ ---
657
+
658
+ ## Module: `resources/cognition-resources`
659
+
660
+ > Copyright 2026 熊高锐 Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. /
661
+
662
+ ### `readCognitionSchema`
663
+
664
+ Copyright 2026 熊高锐 Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. /
665
+
666
+ ```typescript
667
+ /**
668
+ * @file Cognition Engine MCP Resources
669
+ * Exposes three resources for Agent discovery:
670
+ * cognition://schema — Graph data model JSON Schema
671
+ * cognition://stats — Graph statistics (node/edge counts)
672
+ * cognition://docs — Integration documentation
673
+ */
674
+
675
+ import { readFileSync } from "node:fs";
676
+ import { join, dirname } from "node:path";
677
+ import { fileURLToPath } from "node:url";
678
+ import { getPrismaClient } from "../storage/client.js";
679
+
680
+ const __dirname = dirname(fileURLToPath(import.meta.url));
681
+ const projectRoot = join(__dirname, "../..");
682
+
683
+ // ── Resource Definitions ───────────────────────────────────
684
+
685
+ export const RESOURCES = [
686
+ {
687
+ uri: "cognition://schema",
688
+ name: "Cognition Graph Schema",
689
+ description: "JSON Schema of the cognition graph data model, including CognitionNode, CognitionEdge, and AstTemplate tables and their relationships.",
690
+ mimeType: "application/json",
691
+ },
692
+ {
693
+ uri: "cognition://stats",
694
+ name: "Cognition Engine Statistics",
695
+ description: "Current graph statistics: node count, edge count, feedback event count, and average traversal latency. Useful for health checks and capacity planning.",
696
+ mimeType: "application/json",
697
+ },
698
+ {
699
+ uri: "cognition://docs",
700
+ name: "Cognition Engine Documentation",
701
+ description: "Full MCP tool documentation from docs/phase4-mcp-feedback.md. Agents can read this to learn how to use cognition_query, cognition_validate, and cognition_feedback.",
702
+ mimeType: "text/markdown",
703
+ },
704
+ {
705
+ uri: "cognition://rules-changelog",
706
+ name: "Rules Changelog",
707
+ description: "Versioned changelog of global rule changes. Returns version = SHA-256 prefix of updated_at field. Agents must read this before making rule modifications.",
708
+ mimeType: "application/json",
709
+ },
710
+ ];
711
+
712
+ // ── Resource Readers ──────────────────────────────────────
713
+
714
+ /** Return the JSON schema for the cognition graph data model. */
715
+ export async function readCognitionSchema
716
+ ```
717
+
718
+ ### `readCognitionStats`
719
+
720
+ Return current graph statistics with approval rate.
721
+
722
+ ```typescript
723
+ export async function readCognitionStats
724
+ ```
725
+
726
+ ### `readCognitionDocs`
727
+
728
+ Return the integration documentation markdown.
729
+
730
+ ```typescript
731
+ export async function readCognitionDocs
732
+ ```
733
+
734
+ ---
735
+
736
+ ## Module: `storage/client`
737
+
738
+ ### `resetPrismaClient`
739
+
740
+ Copyright 2026 熊高锐 Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. /
741
+
742
+ ```typescript
743
+ import { PrismaClient } from "@prisma/client";
744
+
745
+ let client: PrismaClient | null = null;
746
+
747
+ export function getPrismaClient(): PrismaClient {
748
+ if (!client) {
749
+ client = new PrismaClient({ log: ["warn", "error"] });
750
+ // Enable SQLite WAL mode for concurrent read/write performance (P1)
751
+ client.$queryRawUnsafe("PRAGMA journal_mode=WAL").catch(() => {});
752
+ }
753
+ return client;
754
+ }
755
+
756
+ export async function disconnectPrisma(): Promise<void> {
757
+ if (client) {
758
+ await client.$disconnect();
759
+ client = null;
760
+ }
761
+ }
762
+
763
+ /**
764
+ * Reset the Prisma client singleton, optionally with a new DATABASE_URL.
765
+ * Used by vitest setup to give each worker an isolated database file,
766
+ * preventing cross-worker FK race conditions.
767
+ * Calling with no URL re-creates the client with the current env var value.
768
+ */
769
+ export async function resetPrismaClient
770
+ ```
771
+
772
+ ---
773
+
774
+ ## Module: `storage/cognition-repository`
775
+
776
+ ### `computeSemanticHash`
777
+
778
+ Copyright 2026 熊高锐 Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. /
779
+
780
+ ```typescript
781
+ import { Prisma } from "@prisma/client";
782
+ import { getPrismaClient } from "./client.js";
783
+ import {
784
+ CognitionTypeStr,
785
+ EdgeRelationStr,
786
+ CognitionNodeInput,
787
+ CognitionEdgeInput,
788
+ AstTemplateInput,
789
+ CognitionNodeData,
790
+ CognitionEdgeData,
791
+ AstTemplateData,
792
+ SubgraphResult,
793
+ COGNITION_TYPES,
794
+ EDGE_RELATIONS,
795
+ } from "./cognition-types.js";
796
+
797
+ // ── Helpers ────────────────────────────────────────────────
798
+
799
+ /** Simple hash for semantic dedup. Consistent with ast-node.ts legacy style. */
800
+ function simpleHash(s: string): string {
801
+ if (!s) return "0";
802
+ let hash = 0;
803
+ for (let i = 0; i < s.length; i++) {
804
+ hash = ((hash << 5) - hash) + s.charCodeAt(i);
805
+ hash |= 0;
806
+ }
807
+ return Math.abs(hash).toString(16);
808
+ }
809
+
810
+ /** Generate a semantic hash from type + payload for deduplication. */
811
+ export function computeSemanticHash
812
+ ```
813
+
814
+ ### `isValidCognitionType`
815
+
816
+ Validate that a type string is a valid CognitionType.
817
+
818
+ ```typescript
819
+ export function isValidCognitionType
820
+ ```
821
+
822
+ ### `isValidEdgeRelation`
823
+
824
+ Validate that a relation string is a valid EdgeRelation.
825
+
826
+ ```typescript
827
+ export function isValidEdgeRelation
828
+ ```
829
+
830
+ ---
831
+
832
+ ## Module: `storage/cognition-types`
833
+
834
+ ### `COGNITION_TYPES`
835
+
836
+ Copyright 2026 熊高锐 Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. /
837
+
838
+ ```typescript
839
+ // ── Cognition Graph Type Definitions ───────────────────────
840
+ // Independent from src/types.ts. Do NOT modify existing types.
841
+ // Use String for JSON fields (SQLite limitation, consistent with codebase conventions).
842
+
843
+ /** Valid cognition node type values. */
844
+ export const COGNITION_TYPES
845
+ ```
846
+
847
+ ### `EDGE_RELATIONS`
848
+
849
+ Valid edge relation values.
850
+
851
+ ```typescript
852
+ export const EDGE_RELATIONS
853
+ ```
854
+
855
+ ### `ABSTRACTION_LEVELS`
856
+
857
+ Abstraction levels for cognition nodes.
858
+
859
+ ```typescript
860
+ export const ABSTRACTION_LEVELS
861
+ ```
862
+
863
+ ### `SubgraphResult`
864
+
865
+ Structured data only (AST template JSON, constraint expressions). NEVER natural language.
866
+
867
+ ```typescript
868
+ payload: Record<string, unknown>;
869
+ metadata?: Record<string, unknown>;
870
+ }
871
+
872
+ export interface CognitionEdgeInput {
873
+ sourceId: string;
874
+ targetId: string;
875
+ relation: EdgeRelationStr;
876
+ weight?: number;
877
+ metadata?: Record<string, unknown>;
878
+ }
879
+
880
+ export interface AstTemplateInput {
881
+ nodeId: string;
882
+ language: string;
883
+ /** DSL/JSON pattern for AST-level validation or transformation. NEVER natural language. */
884
+ templateDsl: string;
885
+ /** JSON Schema for validating templateDsl content. */
886
+ validationSchema?: Record<string, unknown>;
887
+ }
888
+
889
+ // ── Output types (for read operations) ─────────────────────
890
+
891
+ export interface CognitionNodeData {
892
+ id: string;
893
+ type: CognitionTypeStr;
894
+ semanticHash: string;
895
+ abstractionLevel: number;
896
+ payload: Record<string, unknown>;
897
+ metadata: Record<string, unknown> | null;
898
+ createdAt: Date;
899
+ updatedAt: Date;
900
+ astTemplate: AstTemplateData | null;
901
+ }
902
+
903
+ export interface CognitionEdgeData {
904
+ id: string;
905
+ sourceId: string;
906
+ targetId: string;
907
+ relation: EdgeRelationStr;
908
+ weight: number;
909
+ metadata: Record<string, unknown> | null;
910
+ createdAt: Date;
911
+ }
912
+
913
+ export interface AstTemplateData {
914
+ id: string;
915
+ nodeId: string;
916
+ language: string;
917
+ templateDsl: string;
918
+ validationSchema: Record<string, unknown> | null;
919
+ createdAt: Date;
920
+ }
921
+
922
+ /** Result of a subgraph traversal. */
923
+ export interface SubgraphResult
924
+ ```
925
+
926
+ ---
927
+
928
+ ## Module: `tools/cognition-tools`
929
+
930
+ > Copyright 2026 熊高锐 Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. /
931
+
932
+ ### `handleCognitionQuery`
933
+
934
+ Copyright 2026 熊高锐 Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. /
935
+
936
+ ```typescript
937
+ /**
938
+ * @file Cognition engine MCP Tool handlers.
939
+ * Three new tools for the MCP protocol:
940
+ * cognition_query — Query the cognition graph
941
+ * cognition_validate — Validate code against AST templates
942
+ * cognition_feedback — Provide feedback to update edge weights
943
+ *
944
+ * These are independent from legacy tools in this directory.
945
+ */
946
+
947
+ import { GraphTraverser } from "../cognition-engine/graph-traverser.js";
948
+ import { recognizeIntent } from "../cognition-engine/intent-recognizer.js";
949
+ import { solveConstraints } from "../cognition-engine/ast-constraint-solver.js";
950
+ import { CognitionRepository } from "../storage/cognition-repository.js";
951
+ import type { TraversalOptions } from "../cognition-engine/types.js";
952
+
953
+ // ── Input Types ─────────────────────────────────────────────
954
+
955
+ interface CognitionQueryInput {
956
+ contextHash: string;
957
+ intentHint?: "REFACTOR" | "BUGFIX" | "BOILERPLATE";
958
+ maxDepth?: number;
959
+ }
960
+
961
+ interface CognitionValidateInput {
962
+ nodeId: string;
963
+ targetFileContent: string;
964
+ }
965
+
966
+ interface CognitionFeedbackInput {
967
+ nodeId: string;
968
+ edgeId?: string;
969
+ outcome: "ACCEPTED" | "REJECTED" | "MODIFIED";
970
+ comment?: string;
971
+ }
972
+
973
+ // ── Handlers ────────────────────────────────────────────────
974
+
975
+ /**
976
+ * cognition_query — Traverse the cognition graph starting from a context hash.
977
+ * If intentHint is omitted, first runs intent recognition on the content hash string.
978
+ */
979
+ export async function handleCognitionQuery
980
+ ```
981
+
982
+ ### `handleCognitionValidate`
983
+
984
+ cognition_validate — Validate code content against a cognition node's AST template.
985
+
986
+ ```typescript
987
+ export async function handleCognitionValidate
988
+ ```
989
+
990
+ ### `handleCognitionFeedback`
991
+
992
+ cognition_feedback — Record user feedback and adjust edge weights.
993
+
994
+ ```typescript
995
+ export async function handleCognitionFeedback
996
+ ```
997
+
998
+ ---
999
+
1000
+ ## Module: `tools/config-tools`
1001
+
1002
+ > Copyright 2026 熊高锐 Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. / Updates threshold values stored as CognitionNode(type=HEURISTIC). Old nodes marked with supersededBy field in metadata. Requires X-Expert-Mode header (simulated via input check). /
1003
+
1004
+ ### `handleUpdateConfig`
1005
+
1006
+ Copyright 2026 熊高锐 Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. /
1007
+
1008
+ ```typescript
1009
+ /**
1010
+ * @file Config Hot Update Tool
1011
+ * Updates threshold values stored as CognitionNode(type=HEURISTIC).
1012
+ * Old nodes marked with supersededBy field in metadata.
1013
+ * Requires X-Expert-Mode header (simulated via input check).
1014
+ */
1015
+ import { CognitionRepository, computeSemanticHash } from "../storage/cognition-repository.js";
1016
+ import { COGNITION_TYPES } from "../storage/cognition-types.js";
1017
+
1018
+ interface UpdateConfigInput {
1019
+ key: string;
1020
+ value: number;
1021
+ expertMode?: boolean;
1022
+ }
1023
+
1024
+ /** Handle cognition_update_config MCP Tool call. */
1025
+ export async function handleUpdateConfig
1026
+ ```
1027
+
1028
+ ---
1029
+
1030
+ ## Module: `tools/injection-approval`
1031
+
1032
+ > Copyright 2026 熊高锐 Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. / Manages proposal-based approval workflow with TTL. Proposal lifecycle: implicit CREATE (via query/validate) -> explicit APPROVE/REJECT/OVERRIDE. /
1033
+
1034
+ ### `createProposal`
1035
+
1036
+ Copyright 2026 熊高锐 Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. /
1037
+
1038
+ ```typescript
1039
+ /**
1040
+ * @file Injection Approval Tool
1041
+ * Manages proposal-based approval workflow with TTL.
1042
+ * Proposal lifecycle: implicit CREATE (via query/validate) -> explicit APPROVE/REJECT/OVERRIDE.
1043
+ */
1044
+
1045
+ import { CognitionRepository } from "../storage/cognition-repository.js";
1046
+ import { getPrismaClient } from "../storage/client.js";
1047
+ import { writeFileSync, existsSync, mkdirSync } from "node:fs";
1048
+ import { join, dirname } from "node:path";
1049
+ import { fileURLToPath } from "node:url";
1050
+
1051
+ const __dirname = dirname(fileURLToPath(import.meta.url));
1052
+ const LOG_DIR = join(__dirname, "../../logs");
1053
+ const TTL_MS = 5 * 60 * 1000; // 5 minutes
1054
+
1055
+ interface Proposal {
1056
+ proposalId: string;
1057
+ contextHash: string;
1058
+ createdAt: number;
1059
+ expiresAt: number;
1060
+ status: "PENDING" | "APPROVED" | "REJECTED" | "OVERRIDDEN" | "EXPIRED";
1061
+ nodeIds: string[];
1062
+ }
1063
+
1064
+ const proposals = new Map<string, Proposal>();
1065
+
1066
+ function generateId(): string {
1067
+ return "prop_" + Math.random().toString(36).substring(2, 10) + Date.now().toString(36);
1068
+ }
1069
+
1070
+ /** Create a new proposal implicitly (called after query/validate). */
1071
+ export function createProposal
1072
+ ```
1073
+
1074
+ ### `handleApproveInjection`
1075
+
1076
+ Handle cognition_approve_injection MCP Tool call.
1077
+
1078
+ ```typescript
1079
+ export async function handleApproveInjection
1080
+ ```
1081
+
1082
+ ### `getProposalStats`
1083
+
1084
+ Record audit event (async, non-blocking).
1085
+
1086
+ ```typescript
1087
+ async function recordAuditLog(eventType: string, props: Record<string, unknown>): Promise<void> {
1088
+ try {
1089
+ const prisma = getPrismaClient();
1090
+ await prisma.metricEvent.create({ data: { eventType, properties: JSON.stringify({ ...props, timestamp: new Date().toISOString() }) } });
1091
+ } catch {
1092
+ // Fallback to local log file
1093
+ try {
1094
+ if (!existsSync(LOG_DIR)) mkdirSync(LOG_DIR, { recursive: true });
1095
+ writeFileSync(join(LOG_DIR, "fallback.log"), JSON.stringify({ eventType, props, timestamp: new Date().toISOString() }) + "\n", { flag: "a" });
1096
+ } catch { /* silent */ }
1097
+ }
1098
+ }
1099
+
1100
+ /** Get proposal stats. */
1101
+ export function getProposalStats
1102
+ ```
1103
+
1104
+ ---
1105
+
1106
+ ## Module: `types`
1107
+
1108
+ ### `ASTNode`
1109
+
1110
+ Copyright 2026 熊高锐 Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. /
1111
+
1112
+ ```typescript
1113
+ export interface ASTNode
1114
+ ```
1115
+
1116
+ ### `SKIP_PATTERNS`
1117
+
1118
+ Optional file content for pattern matching. If empty, content-based matching is skipped.
1119
+
1120
+ ```typescript
1121
+ fileContent?: string;
1122
+ }
1123
+
1124
+ export interface ScoredRule {
1125
+ rule: Rule;
1126
+ score: number;
1127
+ matchReasons: string[];
1128
+ }
1129
+
1130
+ export interface MatchResult {
1131
+ rules: ScoredRule[];
1132
+ totalTokens: number;
1133
+ truncated: boolean;
1134
+ queryDurationMs: number;
1135
+ }
1136
+
1137
+ export type ConflictResolution = "keep_a" | "keep_b" | "merge" | "skip";
1138
+
1139
+ export interface ConflictInfo {
1140
+ id: string;
1141
+ ruleA: Rule;
1142
+ ruleB: Rule;
1143
+ scopeKey: string;
1144
+ resolution?: ConflictResolution;
1145
+ createdAt: Date;
1146
+ }
1147
+
1148
+ export interface CaptureDiffInput {
1149
+ filePath: string;
1150
+ originalContent: string;
1151
+ modifiedContent: string;
1152
+ language: string;
1153
+ projectId?: string;
1154
+ }
1155
+
1156
+ export interface QueryRulesInput {
1157
+ language: string;
1158
+ filePath: string;
1159
+ projectId?: string;
1160
+ tags?: string[];
1161
+ taskId?: string;
1162
+ }
1163
+
1164
+ export interface ConfirmRuleInput {
1165
+ ruleId: string;
1166
+ action: "accept" | "reject" | "edit" | "skip";
1167
+ editedPattern?: string;
1168
+ editedSuggestion?: string;
1169
+ }
1170
+
1171
+ export interface ResolveConflictInput {
1172
+ conflictId: string;
1173
+ resolution: ConflictResolution;
1174
+ batchAllSession?: boolean;
1175
+ }
1176
+
1177
+ export interface ListRulesInput {
1178
+ language?: string;
1179
+ scope?: RuleScope;
1180
+ status?: RuleStatus;
1181
+ projectId?: string;
1182
+ limit?: number;
1183
+ offset?: number;
1184
+ }
1185
+
1186
+ export const DEFAULT_WEIGHTS = {
1187
+ typeWeight: 0.4,
1188
+ timeWeight: 0.3,
1189
+ matchWeight: 0.3,
1190
+ timeDecayLambda: 0.01,
1191
+ } as const;
1192
+
1193
+ export const SCOPE_PRIORITIES: Record<RuleScope, number> = {
1194
+ project: 1.0,
1195
+ user: 0.8,
1196
+ global: 0.5,
1197
+ };
1198
+
1199
+ export const TOKEN_LIMITS = {
1200
+ maxInjectionTokens: 2000,
1201
+ maxSingleRuleTokens: 100,
1202
+ maxRulesPerProject: 2000,
1203
+ maxRulesGlobal: 3000,
1204
+ } as const;
1205
+
1206
+ export const RULE_GENERATION_THRESHOLDS = {
1207
+ minDistinctFiles: 3,
1208
+ minRepeatsInDays: 5,
1209
+ repeatWindowDays: 7,
1210
+ } as const;
1211
+
1212
+ export interface AnalyzeWorkspaceInput {
1213
+ baseCommit: string;
1214
+ headCommit?: string;
1215
+ paths?: string[];
1216
+ taskId?: string;
1217
+ /** Concurrent analysis: max files processed in parallel. Defaults to 5 or CPU core count. */
1218
+ concurrency?: number;
1219
+ fileContents?: { path: string; originalContent?: string; modifiedContent: string }[];
1220
+ }
1221
+
1222
+ export interface AnalyzeResult {
1223
+ analyzedFiles: number;
1224
+ skippedFiles: number;
1225
+ generatedRules: { rule: RuleSpec; filePath: string }[];
1226
+ conflicts: { ruleA: RuleSpec; ruleB: RuleSpec; reason: string }[];
1227
+ errors: { filePath: string; error: string }[];
1228
+ }
1229
+
1230
+ /** File extensions to skip in workspace analysis */
1231
+ export const SKIP_PATTERNS
1232
+ ```
1233
+
1234
+ ---