mcp-adr-analysis-server 2.0.8 → 2.0.10

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 (62) hide show
  1. package/dist/src/index.d.ts +8 -0
  2. package/dist/src/index.d.ts.map +1 -1
  3. package/dist/src/index.js +434 -5
  4. package/dist/src/index.js.map +1 -1
  5. package/dist/src/resources/index.d.ts.map +1 -1
  6. package/dist/src/resources/index.js +71 -1
  7. package/dist/src/resources/index.js.map +1 -1
  8. package/dist/src/tools/human-override-tool.d.ts +42 -0
  9. package/dist/src/tools/human-override-tool.d.ts.map +1 -0
  10. package/dist/src/tools/human-override-tool.js +431 -0
  11. package/dist/src/tools/human-override-tool.js.map +1 -0
  12. package/dist/src/tools/smart-git-push-tool.d.ts +5 -1
  13. package/dist/src/tools/smart-git-push-tool.d.ts.map +1 -1
  14. package/dist/src/tools/smart-git-push-tool.js +75 -30
  15. package/dist/src/tools/smart-git-push-tool.js.map +1 -1
  16. package/dist/src/tools/smart-score-tool.d.ts +138 -0
  17. package/dist/src/tools/smart-score-tool.d.ts.map +1 -0
  18. package/dist/src/tools/smart-score-tool.js +602 -0
  19. package/dist/src/tools/smart-score-tool.js.map +1 -0
  20. package/dist/src/tools/todo-management-tool.d.ts +184 -6
  21. package/dist/src/tools/todo-management-tool.d.ts.map +1 -1
  22. package/dist/src/tools/todo-management-tool.js +819 -42
  23. package/dist/src/tools/todo-management-tool.js.map +1 -1
  24. package/dist/src/tools/tool-chain-orchestrator.d.ts +164 -0
  25. package/dist/src/tools/tool-chain-orchestrator.d.ts.map +1 -0
  26. package/dist/src/tools/tool-chain-orchestrator.js +738 -0
  27. package/dist/src/tools/tool-chain-orchestrator.js.map +1 -0
  28. package/dist/src/tools/troubleshoot-guided-workflow-tool.d.ts +150 -0
  29. package/dist/src/tools/troubleshoot-guided-workflow-tool.d.ts.map +1 -0
  30. package/dist/src/tools/troubleshoot-guided-workflow-tool.js +520 -0
  31. package/dist/src/tools/troubleshoot-guided-workflow-tool.js.map +1 -0
  32. package/dist/src/types/knowledge-graph-schemas.d.ts +481 -0
  33. package/dist/src/types/knowledge-graph-schemas.d.ts.map +1 -0
  34. package/dist/src/types/knowledge-graph-schemas.js +59 -0
  35. package/dist/src/types/knowledge-graph-schemas.js.map +1 -0
  36. package/dist/src/utils/enhanced-sensitive-detector.js +1 -1
  37. package/dist/src/utils/enhanced-sensitive-detector.js.map +1 -1
  38. package/dist/src/utils/json-safe.d.ts +38 -0
  39. package/dist/src/utils/json-safe.d.ts.map +1 -0
  40. package/dist/src/utils/json-safe.js +86 -0
  41. package/dist/src/utils/json-safe.js.map +1 -0
  42. package/dist/src/utils/knowledge-graph-manager.d.ts +28 -0
  43. package/dist/src/utils/knowledge-graph-manager.d.ts.map +1 -0
  44. package/dist/src/utils/knowledge-graph-manager.js +192 -0
  45. package/dist/src/utils/knowledge-graph-manager.js.map +1 -0
  46. package/dist/src/utils/mcp-response-validator.d.ts +30 -0
  47. package/dist/src/utils/mcp-response-validator.d.ts.map +1 -0
  48. package/dist/src/utils/mcp-response-validator.js +197 -0
  49. package/dist/src/utils/mcp-response-validator.js.map +1 -0
  50. package/dist/src/utils/project-health-scoring.d.ts +177 -0
  51. package/dist/src/utils/project-health-scoring.d.ts.map +1 -0
  52. package/dist/src/utils/project-health-scoring.js +370 -0
  53. package/dist/src/utils/project-health-scoring.js.map +1 -0
  54. package/dist/src/utils/release-readiness-detector.d.ts +2 -0
  55. package/dist/src/utils/release-readiness-detector.d.ts.map +1 -1
  56. package/dist/src/utils/release-readiness-detector.js +4 -2
  57. package/dist/src/utils/release-readiness-detector.js.map +1 -1
  58. package/dist/src/utils/todo-file-watcher.d.ts +26 -0
  59. package/dist/src/utils/todo-file-watcher.d.ts.map +1 -0
  60. package/dist/src/utils/todo-file-watcher.js +163 -0
  61. package/dist/src/utils/todo-file-watcher.js.map +1 -0
  62. package/package.json +1 -1
@@ -0,0 +1,86 @@
1
+ /**
2
+ * JSON-Safe String Utilities
3
+ *
4
+ * Utilities for safely escaping strings in JSON-RPC 2.0 responses
5
+ * to prevent parse errors in MCP communication
6
+ */
7
+ /**
8
+ * Escape a string to be JSON-safe for MCP responses
9
+ * Only escapes actual control characters and problematic JSON chars
10
+ */
11
+ export function jsonSafe(str) {
12
+ if (str == null) {
13
+ return '';
14
+ }
15
+ return String(str)
16
+ // Escape backslashes first (before escaping quotes)
17
+ .replace(/\\/g, '\\\\')
18
+ // Escape double quotes
19
+ .replace(/"/g, '\\"')
20
+ // Only escape actual control characters (not regex \b)
21
+ .replace(/\n/g, '\\n')
22
+ .replace(/\r/g, '\\r')
23
+ .replace(/\t/g, '\\t')
24
+ // Escape other potentially problematic control characters (but not \b word boundary)
25
+ .replace(/[\u0000-\u0008\u000B\u000C\u000E-\u001F\u007F-\u009F]/g, (char) => {
26
+ const code = char.charCodeAt(0);
27
+ switch (code) {
28
+ case 0x08: return '\\b'; // actual backspace character
29
+ case 0x0C: return '\\f'; // form feed
30
+ default:
31
+ return '\\u' + ('0000' + code.toString(16)).slice(-4);
32
+ }
33
+ });
34
+ }
35
+ /**
36
+ * Escape an array of strings to be JSON-safe
37
+ */
38
+ export function jsonSafeArray(arr) {
39
+ return arr.map(jsonSafe);
40
+ }
41
+ /**
42
+ * Safely join an array of strings with JSON-safe escaping
43
+ */
44
+ export function jsonSafeJoin(arr, separator = '\n') {
45
+ return jsonSafeArray(arr).join(separator);
46
+ }
47
+ /**
48
+ * Create a JSON-safe markdown list from an array of items
49
+ */
50
+ export function jsonSafeMarkdownList(items, prefix = '- ') {
51
+ return jsonSafeArray(items)
52
+ .filter(item => item.length > 0)
53
+ .map(item => `${prefix}${item}`)
54
+ .join('\n');
55
+ }
56
+ /**
57
+ * Safely escape file paths for JSON output - minimal escaping for display
58
+ * Only normalizes path separators and escapes quotes
59
+ */
60
+ export function jsonSafeFilePath(filePath) {
61
+ if (!filePath) {
62
+ return '';
63
+ }
64
+ // For file paths, only escape quotes and backslashes, normalize separators
65
+ return String(filePath)
66
+ .replace(/\\/g, '/') // Normalize Windows paths
67
+ .replace(/"/g, '\\"'); // Only escape quotes for JSON safety
68
+ }
69
+ /**
70
+ * Safely escape user input content that might contain dangerous characters
71
+ * Use this for content that comes from external sources or user input
72
+ */
73
+ export function jsonSafeUserInput(str) {
74
+ return jsonSafe(str);
75
+ }
76
+ /**
77
+ * Safely escape error messages that might contain quotes or special chars
78
+ */
79
+ export function jsonSafeError(error) {
80
+ if (!error) {
81
+ return 'Unknown error';
82
+ }
83
+ const message = error instanceof Error ? error.message : String(error);
84
+ return jsonSafe(message);
85
+ }
86
+ //# sourceMappingURL=json-safe.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"json-safe.js","sourceRoot":"","sources":["../../../src/utils/json-safe.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;;GAGG;AACH,MAAM,UAAU,QAAQ,CAAC,GAA8B;IACrD,IAAI,GAAG,IAAI,IAAI,EAAE,CAAC;QAChB,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,OAAO,MAAM,CAAC,GAAG,CAAC;QAChB,oDAAoD;SACnD,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC;QACvB,uBAAuB;SACtB,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC;QACrB,uDAAuD;SACtD,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC;SACrB,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC;SACrB,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC;QACtB,qFAAqF;SACpF,OAAO,CAAC,wDAAwD,EAAE,CAAC,IAAI,EAAE,EAAE;QAC1E,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;QAChC,QAAQ,IAAI,EAAE,CAAC;YACb,KAAK,IAAI,CAAC,CAAC,OAAO,KAAK,CAAC,CAAC,6BAA6B;YACtD,KAAK,IAAI,CAAC,CAAC,OAAO,KAAK,CAAC,CAAC,YAAY;YACrC;gBACE,OAAO,KAAK,GAAG,CAAC,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;QAC1D,CAAC;IACH,CAAC,CAAC,CAAC;AACP,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,aAAa,CAAC,GAAkC;IAC9D,OAAO,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;AAC3B,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,YAAY,CAAC,GAAkC,EAAE,YAAoB,IAAI;IACvF,OAAO,aAAa,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;AAC5C,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,oBAAoB,CAAC,KAAoC,EAAE,SAAiB,IAAI;IAC9F,OAAO,aAAa,CAAC,KAAK,CAAC;SACxB,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC;SAC/B,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,MAAM,GAAG,IAAI,EAAE,CAAC;SAC/B,IAAI,CAAC,IAAI,CAAC,CAAC;AAChB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,gBAAgB,CAAC,QAAmC;IAClE,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,2EAA2E;IAC3E,OAAO,MAAM,CAAC,QAAQ,CAAC;SACpB,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,0BAA0B;SAC9C,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,qCAAqC;AAChE,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,iBAAiB,CAAC,GAA8B;IAC9D,OAAO,QAAQ,CAAC,GAAG,CAAC,CAAC;AACvB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,aAAa,CAAC,KAAc;IAC1C,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,eAAe,CAAC;IACzB,CAAC;IAED,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACvE,OAAO,QAAQ,CAAC,OAAO,CAAC,CAAC;AAC3B,CAAC"}
@@ -0,0 +1,28 @@
1
+ import { IntentSnapshot, TodoSyncState, KnowledgeGraphSnapshot } from '../types/knowledge-graph-schemas.js';
2
+ export declare class KnowledgeGraphManager {
3
+ private cacheDir;
4
+ private snapshotsFile;
5
+ private syncStateFile;
6
+ constructor();
7
+ ensureCacheDirectory(): Promise<void>;
8
+ loadKnowledgeGraph(): Promise<KnowledgeGraphSnapshot>;
9
+ saveKnowledgeGraph(snapshot: KnowledgeGraphSnapshot): Promise<void>;
10
+ createIntent(humanRequest: string, parsedGoals: string[], priority?: 'high' | 'medium' | 'low'): Promise<string>;
11
+ addToolExecution(intentId: string, toolName: string, parameters: Record<string, any>, result: Record<string, any>, success: boolean, todoTasksCreated?: string[], todoTasksModified?: string[], error?: string): Promise<void>;
12
+ updateIntentStatus(intentId: string, status: 'planning' | 'executing' | 'completed' | 'failed'): Promise<void>;
13
+ updateTodoSnapshot(intentId: string, todoContent: string): Promise<void>;
14
+ getSyncState(): Promise<TodoSyncState>;
15
+ updateSyncState(updates: Partial<TodoSyncState>): Promise<void>;
16
+ getIntentById(intentId: string): Promise<IntentSnapshot | null>;
17
+ getActiveIntents(): Promise<IntentSnapshot[]>;
18
+ getIntentsByStatus(status: 'planning' | 'executing' | 'completed' | 'failed'): Promise<IntentSnapshot[]>;
19
+ private getDefaultSyncState;
20
+ private updateAnalytics;
21
+ calculateTodoMdHash(todoPath: string): Promise<string>;
22
+ detectTodoChanges(todoPath: string): Promise<{
23
+ hasChanges: boolean;
24
+ currentHash: string;
25
+ lastHash: string;
26
+ }>;
27
+ }
28
+ //# sourceMappingURL=knowledge-graph-manager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"knowledge-graph-manager.d.ts","sourceRoot":"","sources":["../../../src/utils/knowledge-graph-manager.ts"],"names":[],"mappings":"AAGA,OAAO,EACL,cAAc,EAEd,aAAa,EACb,sBAAsB,EAGvB,MAAM,qCAAqC,CAAC;AAG7C,qBAAa,qBAAqB;IAChC,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,aAAa,CAAS;IAC9B,OAAO,CAAC,aAAa,CAAS;;IASxB,oBAAoB,IAAI,OAAO,CAAC,IAAI,CAAC;IAQrC,kBAAkB,IAAI,OAAO,CAAC,sBAAsB,CAAC;IA2BrD,kBAAkB,CAAC,QAAQ,EAAE,sBAAsB,GAAG,OAAO,CAAC,IAAI,CAAC;IAKnE,YAAY,CAChB,YAAY,EAAE,MAAM,EACpB,WAAW,EAAE,MAAM,EAAE,EACrB,QAAQ,GAAE,MAAM,GAAG,QAAQ,GAAG,KAAgB,GAC7C,OAAO,CAAC,MAAM,CAAC;IAwBZ,gBAAgB,CACpB,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC/B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC3B,OAAO,EAAE,OAAO,EAChB,gBAAgB,GAAE,MAAM,EAAO,EAC/B,iBAAiB,GAAE,MAAM,EAAO,EAChC,KAAK,CAAC,EAAE,MAAM,GACb,OAAO,CAAC,IAAI,CAAC;IA0BV,kBAAkB,CACtB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,UAAU,GAAG,WAAW,GAAG,WAAW,GAAG,QAAQ,GACxD,OAAO,CAAC,IAAI,CAAC;IAaV,kBAAkB,CAAC,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAYxE,YAAY,IAAI,OAAO,CAAC,aAAa,CAAC;IAUtC,eAAe,CAAC,OAAO,EAAE,OAAO,CAAC,aAAa,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAU/D,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC;IAK/D,gBAAgB,IAAI,OAAO,CAAC,cAAc,EAAE,CAAC;IAK7C,kBAAkB,CAAC,MAAM,EAAE,UAAU,GAAG,WAAW,GAAG,WAAW,GAAG,QAAQ,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC;YAKhG,mBAAmB;IAWjC,OAAO,CAAC,eAAe;IAwBjB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAStD,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC;QACjD,UAAU,EAAE,OAAO,CAAC;QACpB,WAAW,EAAE,MAAM,CAAC;QACpB,QAAQ,EAAE,MAAM,CAAC;KAClB,CAAC;CAUH"}
@@ -0,0 +1,192 @@
1
+ import * as fs from 'fs/promises';
2
+ import path from 'path';
3
+ import crypto from 'crypto';
4
+ import { TodoSyncStateSchema, KnowledgeGraphSnapshotSchema } from '../types/knowledge-graph-schemas.js';
5
+ import { loadConfig } from './config.js';
6
+ export class KnowledgeGraphManager {
7
+ cacheDir;
8
+ snapshotsFile;
9
+ syncStateFile;
10
+ constructor() {
11
+ const config = loadConfig();
12
+ this.cacheDir = path.join(config.projectPath, '.mcp-adr-cache');
13
+ this.snapshotsFile = path.join(this.cacheDir, 'knowledge-graph-snapshots.json');
14
+ this.syncStateFile = path.join(this.cacheDir, 'todo-sync-state.json');
15
+ }
16
+ async ensureCacheDirectory() {
17
+ try {
18
+ await fs.access(this.cacheDir);
19
+ }
20
+ catch {
21
+ await fs.mkdir(this.cacheDir, { recursive: true });
22
+ }
23
+ }
24
+ async loadKnowledgeGraph() {
25
+ await this.ensureCacheDirectory();
26
+ try {
27
+ const data = await fs.readFile(this.snapshotsFile, 'utf-8');
28
+ const parsed = JSON.parse(data);
29
+ return KnowledgeGraphSnapshotSchema.parse(parsed);
30
+ }
31
+ catch {
32
+ const defaultSnapshot = {
33
+ version: '1.0.0',
34
+ timestamp: new Date().toISOString(),
35
+ intents: [],
36
+ todoSyncState: await this.getDefaultSyncState(),
37
+ analytics: {
38
+ totalIntents: 0,
39
+ completedIntents: 0,
40
+ activeIntents: 0,
41
+ averageGoalCompletion: 0,
42
+ mostUsedTools: [],
43
+ successfulPatterns: []
44
+ }
45
+ };
46
+ await this.saveKnowledgeGraph(defaultSnapshot);
47
+ return defaultSnapshot;
48
+ }
49
+ }
50
+ async saveKnowledgeGraph(snapshot) {
51
+ await this.ensureCacheDirectory();
52
+ await fs.writeFile(this.snapshotsFile, JSON.stringify(snapshot, null, 2));
53
+ }
54
+ async createIntent(humanRequest, parsedGoals, priority = 'medium') {
55
+ const intentId = crypto.randomUUID();
56
+ const timestamp = new Date().toISOString();
57
+ const intent = {
58
+ intentId,
59
+ humanRequest,
60
+ parsedGoals,
61
+ priority,
62
+ timestamp,
63
+ toolChain: [],
64
+ currentStatus: 'planning',
65
+ todoMdSnapshot: ''
66
+ };
67
+ const kg = await this.loadKnowledgeGraph();
68
+ kg.intents.push(intent);
69
+ kg.analytics.totalIntents = kg.intents.length;
70
+ kg.analytics.activeIntents = kg.intents.filter(i => i.currentStatus !== 'completed').length;
71
+ await this.saveKnowledgeGraph(kg);
72
+ return intentId;
73
+ }
74
+ async addToolExecution(intentId, toolName, parameters, result, success, todoTasksCreated = [], todoTasksModified = [], error) {
75
+ const kg = await this.loadKnowledgeGraph();
76
+ const intent = kg.intents.find(i => i.intentId === intentId);
77
+ if (!intent) {
78
+ throw new Error(`Intent ${intentId} not found`);
79
+ }
80
+ const execution = {
81
+ toolName,
82
+ parameters,
83
+ result,
84
+ todoTasksCreated,
85
+ todoTasksModified,
86
+ executionTime: new Date().toISOString(),
87
+ success,
88
+ error
89
+ };
90
+ intent.toolChain.push(execution);
91
+ intent.currentStatus = success ? 'executing' : 'failed';
92
+ this.updateAnalytics(kg);
93
+ await this.saveKnowledgeGraph(kg);
94
+ }
95
+ async updateIntentStatus(intentId, status) {
96
+ const kg = await this.loadKnowledgeGraph();
97
+ const intent = kg.intents.find(i => i.intentId === intentId);
98
+ if (!intent) {
99
+ throw new Error(`Intent ${intentId} not found`);
100
+ }
101
+ intent.currentStatus = status;
102
+ this.updateAnalytics(kg);
103
+ await this.saveKnowledgeGraph(kg);
104
+ }
105
+ async updateTodoSnapshot(intentId, todoContent) {
106
+ const kg = await this.loadKnowledgeGraph();
107
+ const intent = kg.intents.find(i => i.intentId === intentId);
108
+ if (!intent) {
109
+ throw new Error(`Intent ${intentId} not found`);
110
+ }
111
+ intent.todoMdSnapshot = todoContent;
112
+ await this.saveKnowledgeGraph(kg);
113
+ }
114
+ async getSyncState() {
115
+ try {
116
+ const data = await fs.readFile(this.syncStateFile, 'utf-8');
117
+ const parsed = JSON.parse(data);
118
+ return TodoSyncStateSchema.parse(parsed);
119
+ }
120
+ catch {
121
+ return this.getDefaultSyncState();
122
+ }
123
+ }
124
+ async updateSyncState(updates) {
125
+ const current = await this.getSyncState();
126
+ const updated = { ...current, ...updates };
127
+ await fs.writeFile(this.syncStateFile, JSON.stringify(updated, null, 2));
128
+ const kg = await this.loadKnowledgeGraph();
129
+ kg.todoSyncState = updated;
130
+ await this.saveKnowledgeGraph(kg);
131
+ }
132
+ async getIntentById(intentId) {
133
+ const kg = await this.loadKnowledgeGraph();
134
+ return kg.intents.find(i => i.intentId === intentId) || null;
135
+ }
136
+ async getActiveIntents() {
137
+ const kg = await this.loadKnowledgeGraph();
138
+ return kg.intents.filter(i => i.currentStatus !== 'completed' && i.currentStatus !== 'failed');
139
+ }
140
+ async getIntentsByStatus(status) {
141
+ const kg = await this.loadKnowledgeGraph();
142
+ return kg.intents.filter(i => i.currentStatus === status);
143
+ }
144
+ async getDefaultSyncState() {
145
+ return {
146
+ lastSyncTimestamp: new Date().toISOString(),
147
+ todoMdHash: '',
148
+ knowledgeGraphHash: '',
149
+ syncStatus: 'synced',
150
+ lastModifiedBy: 'tool',
151
+ version: 1
152
+ };
153
+ }
154
+ updateAnalytics(kg) {
155
+ const intents = kg.intents;
156
+ kg.analytics.totalIntents = intents.length;
157
+ kg.analytics.completedIntents = intents.filter(i => i.currentStatus === 'completed').length;
158
+ kg.analytics.activeIntents = intents.filter(i => i.currentStatus !== 'completed' && i.currentStatus !== 'failed').length;
159
+ if (kg.analytics.totalIntents > 0) {
160
+ kg.analytics.averageGoalCompletion = kg.analytics.completedIntents / kg.analytics.totalIntents;
161
+ }
162
+ const toolUsage = new Map();
163
+ intents.forEach(intent => {
164
+ intent.toolChain.forEach(execution => {
165
+ toolUsage.set(execution.toolName, (toolUsage.get(execution.toolName) || 0) + 1);
166
+ });
167
+ });
168
+ kg.analytics.mostUsedTools = Array.from(toolUsage.entries())
169
+ .map(([toolName, usageCount]) => ({ toolName, usageCount }))
170
+ .sort((a, b) => b.usageCount - a.usageCount)
171
+ .slice(0, 10);
172
+ }
173
+ async calculateTodoMdHash(todoPath) {
174
+ try {
175
+ const content = await fs.readFile(todoPath, 'utf-8');
176
+ return crypto.createHash('sha256').update(content).digest('hex');
177
+ }
178
+ catch {
179
+ return '';
180
+ }
181
+ }
182
+ async detectTodoChanges(todoPath) {
183
+ const syncState = await this.getSyncState();
184
+ const currentHash = await this.calculateTodoMdHash(todoPath);
185
+ return {
186
+ hasChanges: currentHash !== syncState.todoMdHash,
187
+ currentHash,
188
+ lastHash: syncState.todoMdHash
189
+ };
190
+ }
191
+ }
192
+ //# sourceMappingURL=knowledge-graph-manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"knowledge-graph-manager.js","sourceRoot":"","sources":["../../../src/utils/knowledge-graph-manager.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * MCP Response Validator
3
+ *
4
+ * Validates and sanitizes MCP tool responses to prevent JSON-RPC 2.0 parse errors
5
+ */
6
+ export interface McpToolResponse {
7
+ content: Array<{
8
+ type: 'text' | 'image' | 'resource';
9
+ text?: string;
10
+ data?: string;
11
+ mimeType?: string;
12
+ }>;
13
+ isError?: boolean;
14
+ }
15
+ /**
16
+ * Validate and sanitize an MCP tool response
17
+ */
18
+ export declare function validateMcpResponse(response: any): McpToolResponse;
19
+ /**
20
+ * Validate that a response can be safely serialized as JSON-RPC 2.0
21
+ */
22
+ export declare function validateJsonRpcSerialization(response: any): {
23
+ valid: boolean;
24
+ error?: string;
25
+ };
26
+ /**
27
+ * Safe wrapper for MCP tool functions
28
+ */
29
+ export declare function safeMcpToolWrapper<T extends any[], R>(toolFunction: (...args: T) => Promise<R>, toolName: string): (...args: T) => Promise<McpToolResponse>;
30
+ //# sourceMappingURL=mcp-response-validator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-response-validator.d.ts","sourceRoot":"","sources":["../../../src/utils/mcp-response-validator.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,KAAK,CAAC;QACb,IAAI,EAAE,MAAM,GAAG,OAAO,GAAG,UAAU,CAAC;QACpC,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,QAAQ,CAAC,EAAE,MAAM,CAAC;KACnB,CAAC,CAAC;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,GAAG,GAAG,eAAe,CAuClE;AAsHD;;GAEG;AACH,wBAAgB,4BAA4B,CAAC,QAAQ,EAAE,GAAG,GAAG;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CA0B9F;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,CAAC,SAAS,GAAG,EAAE,EAAE,CAAC,EACnD,YAAY,EAAE,CAAC,GAAG,IAAI,EAAE,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,EACxC,QAAQ,EAAE,MAAM,IAEF,GAAG,MAAM,CAAC,KAAG,OAAO,CAAC,eAAe,CAAC,CAkBpD"}
@@ -0,0 +1,197 @@
1
+ /**
2
+ * MCP Response Validator
3
+ *
4
+ * Validates and sanitizes MCP tool responses to prevent JSON-RPC 2.0 parse errors
5
+ */
6
+ /**
7
+ * Validate and sanitize an MCP tool response
8
+ */
9
+ export function validateMcpResponse(response) {
10
+ try {
11
+ // Ensure response has the correct structure
12
+ if (!response || typeof response !== 'object') {
13
+ return createErrorResponse('Invalid response structure');
14
+ }
15
+ // Ensure content array exists
16
+ if (!Array.isArray(response.content)) {
17
+ return createErrorResponse('Response must have content array');
18
+ }
19
+ // Validate and sanitize each content item
20
+ const sanitizedContent = response.content.map((item, index) => {
21
+ try {
22
+ return sanitizeContentItem(item, index);
23
+ }
24
+ catch (error) {
25
+ console.error(`Error sanitizing content item ${index}:`, error);
26
+ return {
27
+ type: 'text',
28
+ text: `[Error: Could not render content item ${index}]`
29
+ };
30
+ }
31
+ });
32
+ // Test JSON serialization
33
+ const testSerialization = JSON.stringify({ content: sanitizedContent });
34
+ // Verify it can be parsed back
35
+ JSON.parse(testSerialization);
36
+ return {
37
+ content: sanitizedContent,
38
+ isError: response.isError || false
39
+ };
40
+ }
41
+ catch (error) {
42
+ console.error('Response validation failed:', error);
43
+ return createErrorResponse(`Response validation failed: ${error instanceof Error ? error.message : String(error)}`);
44
+ }
45
+ }
46
+ /**
47
+ * Sanitize a single content item
48
+ */
49
+ function sanitizeContentItem(item, index) {
50
+ if (!item || typeof item !== 'object') {
51
+ throw new Error(`Content item ${index} is not an object`);
52
+ }
53
+ const type = item.type;
54
+ if (!type || !['text', 'image', 'resource'].includes(type)) {
55
+ throw new Error(`Content item ${index} has invalid type: ${type}`);
56
+ }
57
+ switch (type) {
58
+ case 'text':
59
+ return {
60
+ type: 'text',
61
+ text: sanitizeTextContent(item.text || '')
62
+ };
63
+ case 'image':
64
+ return {
65
+ type: 'image',
66
+ data: sanitizeBase64Content(item.data || ''),
67
+ mimeType: sanitizeMimeType(item.mimeType || 'image/png')
68
+ };
69
+ case 'resource':
70
+ return {
71
+ type: 'resource',
72
+ data: sanitizeTextContent(item.data || ''),
73
+ mimeType: sanitizeMimeType(item.mimeType || 'text/plain')
74
+ };
75
+ default:
76
+ throw new Error(`Unsupported content type: ${type}`);
77
+ }
78
+ }
79
+ /**
80
+ * Sanitize text content for JSON-RPC safety
81
+ */
82
+ function sanitizeTextContent(text) {
83
+ if (typeof text !== 'string') {
84
+ text = String(text);
85
+ }
86
+ // Remove or escape problematic characters
87
+ return text
88
+ // Escape backslashes first
89
+ .replace(/\\/g, '\\\\')
90
+ // Escape double quotes
91
+ .replace(/"/g, '\\"')
92
+ // Handle control characters
93
+ .replace(/\n/g, '\\n')
94
+ .replace(/\r/g, '\\r')
95
+ .replace(/\t/g, '\\t')
96
+ // Remove or escape other control characters
97
+ .replace(/[\u0000-\u0008\u000B\u000C\u000E-\u001F\u007F-\u009F]/g, (char) => {
98
+ const code = char.charCodeAt(0);
99
+ switch (code) {
100
+ case 0x08: return '\\b';
101
+ case 0x0C: return '\\f';
102
+ default:
103
+ // Replace with safe placeholder for other control chars
104
+ return `[CTRL:${code.toString(16).padStart(2, '0')}]`;
105
+ }
106
+ })
107
+ // Limit length to prevent oversized responses
108
+ .slice(0, 1000000); // 1MB limit
109
+ }
110
+ /**
111
+ * Sanitize base64 content
112
+ */
113
+ function sanitizeBase64Content(data) {
114
+ if (typeof data !== 'string') {
115
+ return '';
116
+ }
117
+ // Validate base64 format and remove invalid characters
118
+ return data.replace(/[^A-Za-z0-9+/=]/g, '').slice(0, 10000000); // 10MB limit
119
+ }
120
+ /**
121
+ * Sanitize MIME type
122
+ */
123
+ function sanitizeMimeType(mimeType) {
124
+ if (typeof mimeType !== 'string') {
125
+ return 'text/plain';
126
+ }
127
+ // Only allow safe MIME types
128
+ const allowedMimeTypes = [
129
+ 'text/plain', 'text/html', 'text/markdown', 'text/css', 'text/javascript',
130
+ 'application/json', 'application/xml', 'application/yaml',
131
+ 'image/png', 'image/jpeg', 'image/gif', 'image/svg+xml', 'image/webp'
132
+ ];
133
+ const sanitized = mimeType.toLowerCase().trim();
134
+ return allowedMimeTypes.includes(sanitized) ? sanitized : 'text/plain';
135
+ }
136
+ /**
137
+ * Create a safe error response
138
+ */
139
+ function createErrorResponse(message) {
140
+ return {
141
+ content: [{
142
+ type: 'text',
143
+ text: sanitizeTextContent(`Error: ${message}`)
144
+ }],
145
+ isError: true
146
+ };
147
+ }
148
+ /**
149
+ * Validate that a response can be safely serialized as JSON-RPC 2.0
150
+ */
151
+ export function validateJsonRpcSerialization(response) {
152
+ try {
153
+ // Test full JSON-RPC 2.0 structure
154
+ const jsonRpcResponse = {
155
+ jsonrpc: '2.0',
156
+ id: 1,
157
+ result: response
158
+ };
159
+ const serialized = JSON.stringify(jsonRpcResponse);
160
+ // Verify it can be parsed back
161
+ const parsed = JSON.parse(serialized);
162
+ // Verify structure is preserved
163
+ if (!parsed.result || !Array.isArray(parsed.result.content)) {
164
+ return { valid: false, error: 'Structure not preserved after serialization' };
165
+ }
166
+ return { valid: true };
167
+ }
168
+ catch (error) {
169
+ return {
170
+ valid: false,
171
+ error: `JSON-RPC serialization failed: ${error instanceof Error ? error.message : String(error)}`
172
+ };
173
+ }
174
+ }
175
+ /**
176
+ * Safe wrapper for MCP tool functions
177
+ */
178
+ export function safeMcpToolWrapper(toolFunction, toolName) {
179
+ return async (...args) => {
180
+ try {
181
+ const result = await toolFunction(...args);
182
+ const validated = validateMcpResponse(result);
183
+ // Double-check JSON-RPC compatibility
184
+ const jsonRpcCheck = validateJsonRpcSerialization(validated);
185
+ if (!jsonRpcCheck.valid) {
186
+ console.error(`JSON-RPC validation failed for ${toolName}:`, jsonRpcCheck.error);
187
+ return createErrorResponse(`Tool response not JSON-RPC compatible: ${jsonRpcCheck.error}`);
188
+ }
189
+ return validated;
190
+ }
191
+ catch (error) {
192
+ console.error(`Error in ${toolName}:`, error);
193
+ return createErrorResponse(`Tool execution failed: ${error instanceof Error ? error.message : String(error)}`);
194
+ }
195
+ };
196
+ }
197
+ //# sourceMappingURL=mcp-response-validator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-response-validator.js","sourceRoot":"","sources":["../../../src/utils/mcp-response-validator.ts"],"names":[],"mappings":"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"}