bc-code-intelligence-mcp 1.7.1 → 1.7.2
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.
- package/dist/cli.js +45 -44
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +330 -302
- package/dist/index.js.map +1 -1
- package/dist/layers/embedded-layer.d.ts +4 -4
- package/dist/layers/embedded-layer.d.ts.map +1 -1
- package/dist/layers/embedded-layer.js +118 -96
- package/dist/layers/embedded-layer.js.map +1 -1
- package/dist/layers/git-layer.d.ts +3 -3
- package/dist/layers/git-layer.d.ts.map +1 -1
- package/dist/layers/git-layer.js +115 -98
- package/dist/layers/git-layer.js.map +1 -1
- package/dist/layers/project-layer.d.ts +2 -2
- package/dist/layers/project-layer.d.ts.map +1 -1
- package/dist/layers/project-layer.js +44 -40
- package/dist/layers/project-layer.js.map +1 -1
- package/dist/sdk/bc-code-intel-client.d.ts +1 -1
- package/dist/sdk/bc-code-intel-client.js +40 -40
- package/dist/tools/ask_bc_expert/handler.d.ts.map +1 -1
- package/dist/tools/ask_bc_expert/handler.js +71 -50
- package/dist/tools/ask_bc_expert/handler.js.map +1 -1
- package/dist/types/bc-knowledge.d.ts +1 -1
- package/dist/types/bc-knowledge.d.ts.map +1 -1
- package/dist/types/bc-knowledge.js +105 -33
- package/dist/types/bc-knowledge.js.map +1 -1
- package/dist/types/config-types.d.ts +9 -9
- package/dist/types/config-types.d.ts.map +1 -1
- package/dist/types/config-types.js +38 -38
- package/dist/types/config-types.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,26 +1,26 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { Server } from
|
|
3
|
-
import { StdioServerTransport } from
|
|
4
|
-
import { CallToolRequestSchema, ErrorCode, ListToolsRequestSchema, McpError, ListPromptsRequestSchema, GetPromptRequestSchema, } from
|
|
5
|
-
import { fileURLToPath } from
|
|
6
|
-
import { dirname, join } from
|
|
7
|
-
import { readFileSync, existsSync } from
|
|
8
|
-
import { allTools, debugTools } from
|
|
9
|
-
import { createToolHandlers, createDebugToolHandlers } from
|
|
10
|
-
import { KnowledgeService } from
|
|
11
|
-
import { CodeAnalysisService } from
|
|
12
|
-
import { MethodologyService } from
|
|
13
|
-
import { WorkflowService } from
|
|
14
|
-
import { WorkflowSessionManager } from
|
|
15
|
-
import { RelevanceIndexService } from
|
|
16
|
-
import { getDomainList } from
|
|
17
|
-
import { MultiContentLayerService } from
|
|
18
|
-
import { SpecialistSessionManager } from
|
|
19
|
-
import { SpecialistDiscoveryService } from
|
|
20
|
-
import { WorkflowSpecialistRouter } from
|
|
21
|
-
import { ConfigurationLoader } from
|
|
22
|
-
import { ConfigurationValidator } from
|
|
23
|
-
import { LayerSourceType } from
|
|
2
|
+
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
3
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
4
|
+
import { CallToolRequestSchema, ErrorCode, ListToolsRequestSchema, McpError, ListPromptsRequestSchema, GetPromptRequestSchema, } from "@modelcontextprotocol/sdk/types.js";
|
|
5
|
+
import { fileURLToPath } from "url";
|
|
6
|
+
import { dirname, join } from "path";
|
|
7
|
+
import { readFileSync, existsSync } from "fs";
|
|
8
|
+
import { allTools, debugTools, } from "./tools/index.js";
|
|
9
|
+
import { createToolHandlers, createDebugToolHandlers, } from "./tools/handlers.js";
|
|
10
|
+
import { KnowledgeService } from "./services/knowledge-service.js";
|
|
11
|
+
import { CodeAnalysisService } from "./services/code-analysis-service.js";
|
|
12
|
+
import { MethodologyService } from "./services/methodology-service.js";
|
|
13
|
+
import { WorkflowService } from "./services/workflow-service.js";
|
|
14
|
+
import { WorkflowSessionManager } from "./services/workflow-v2/workflow-session-manager.js";
|
|
15
|
+
import { RelevanceIndexService } from "./services/relevance-index-service.js";
|
|
16
|
+
import { getDomainList } from "./types/bc-knowledge.js";
|
|
17
|
+
import { MultiContentLayerService } from "./services/multi-content-layer-service.js";
|
|
18
|
+
import { SpecialistSessionManager } from "./services/specialist-session-manager.js";
|
|
19
|
+
import { SpecialistDiscoveryService } from "./services/specialist-discovery.js";
|
|
20
|
+
import { WorkflowSpecialistRouter } from "./services/workflow-specialist-router.js";
|
|
21
|
+
import { ConfigurationLoader } from "./config/config-loader.js";
|
|
22
|
+
import { ConfigurationValidator } from "./config/config-validator.js";
|
|
23
|
+
import { LayerSourceType, } from "./types/index.js";
|
|
24
24
|
/**
|
|
25
25
|
* BC Code Intelligence MCP Server
|
|
26
26
|
*
|
|
@@ -52,21 +52,21 @@ class BCCodeIntelligenceServer {
|
|
|
52
52
|
try {
|
|
53
53
|
const __filename = fileURLToPath(import.meta.url);
|
|
54
54
|
const __dirname = dirname(__filename);
|
|
55
|
-
const packagePath = join(__dirname,
|
|
55
|
+
const packagePath = join(__dirname, "..", "package.json");
|
|
56
56
|
console.error(`🔍 Looking for package.json at: ${packagePath}`);
|
|
57
57
|
console.error(` Exists: ${existsSync(packagePath)}`);
|
|
58
58
|
if (!existsSync(packagePath)) {
|
|
59
59
|
console.error(`⚠️ package.json not found at expected location`);
|
|
60
|
-
return
|
|
60
|
+
return "1.0.0"; // fallback
|
|
61
61
|
}
|
|
62
|
-
const packageJson = JSON.parse(readFileSync(packagePath,
|
|
63
|
-
const version = packageJson.version ||
|
|
62
|
+
const packageJson = JSON.parse(readFileSync(packagePath, "utf8"));
|
|
63
|
+
const version = packageJson.version || "1.0.0";
|
|
64
64
|
console.error(` Version: ${version}`);
|
|
65
65
|
return version;
|
|
66
66
|
}
|
|
67
67
|
catch (error) {
|
|
68
68
|
console.error(`⚠️ Error reading package.json:`, error instanceof Error ? error.message : String(error));
|
|
69
|
-
return
|
|
69
|
+
return "1.0.0"; // fallback
|
|
70
70
|
}
|
|
71
71
|
}
|
|
72
72
|
constructor() {
|
|
@@ -76,20 +76,20 @@ class BCCodeIntelligenceServer {
|
|
|
76
76
|
console.error(`[startup] Node version: ${process.version}`);
|
|
77
77
|
// Initialize MCP server with capabilities declaration (required by SDK 1.x)
|
|
78
78
|
this.server = new Server({
|
|
79
|
-
name:
|
|
79
|
+
name: "bc-code-intelligence-mcp",
|
|
80
80
|
version: this.getPackageVersion(),
|
|
81
81
|
}, {
|
|
82
82
|
capabilities: {
|
|
83
83
|
tools: {},
|
|
84
|
-
prompts: {}
|
|
85
|
-
}
|
|
84
|
+
prompts: {},
|
|
85
|
+
},
|
|
86
86
|
});
|
|
87
87
|
// Initialize configuration loader
|
|
88
88
|
this.configLoader = new ConfigurationLoader();
|
|
89
89
|
// Initialize workspace tool handlers (these work before services are initialized)
|
|
90
90
|
const workspaceContext = {
|
|
91
91
|
setWorkspaceInfo: this.setWorkspaceInfo.bind(this),
|
|
92
|
-
getWorkspaceInfo: this.getWorkspaceInfo.bind(this)
|
|
92
|
+
getWorkspaceInfo: this.getWorkspaceInfo.bind(this),
|
|
93
93
|
};
|
|
94
94
|
this.toolHandlers = createToolHandlers({}, workspaceContext);
|
|
95
95
|
// Services will be initialized asynchronously in run()
|
|
@@ -111,7 +111,7 @@ class BCCodeIntelligenceServer {
|
|
|
111
111
|
const { name, arguments: args } = request.params;
|
|
112
112
|
try {
|
|
113
113
|
// Workspace tools are always available (no interception)
|
|
114
|
-
if ([
|
|
114
|
+
if (["set_workspace_info", "get_workspace_info"].includes(name)) {
|
|
115
115
|
const handler = this.toolHandlers.get(name);
|
|
116
116
|
if (!handler) {
|
|
117
117
|
throw new McpError(ErrorCode.MethodNotFound, `Unknown workspace tool: ${name}`);
|
|
@@ -121,8 +121,9 @@ class BCCodeIntelligenceServer {
|
|
|
121
121
|
// Intercept all other tools if services not initialized
|
|
122
122
|
if (!this.servicesInitialized) {
|
|
123
123
|
return {
|
|
124
|
-
content: [
|
|
125
|
-
|
|
124
|
+
content: [
|
|
125
|
+
{
|
|
126
|
+
type: "text",
|
|
126
127
|
text: `⚠️ **Workspace Not Configured**
|
|
127
128
|
|
|
128
129
|
The BC Code Intelligence server needs workspace information to load project-specific configuration and knowledge layers.
|
|
@@ -152,8 +153,9 @@ Place a configuration file at:
|
|
|
152
153
|
|
|
153
154
|
Use absolute paths in the config for git/local layers.
|
|
154
155
|
|
|
155
|
-
Currently only embedded knowledge is loaded. Call \`set_workspace_info\` to enable project layers and MCP ecosystem awareness
|
|
156
|
-
}
|
|
156
|
+
Currently only embedded knowledge is loaded. Call \`set_workspace_info\` to enable project layers and MCP ecosystem awareness.`,
|
|
157
|
+
},
|
|
158
|
+
],
|
|
157
159
|
};
|
|
158
160
|
}
|
|
159
161
|
// Try debug tool handlers first (if enabled)
|
|
@@ -180,236 +182,236 @@ Currently only embedded knowledge is loaded. Call \`set_workspace_info\` to enab
|
|
|
180
182
|
* Setup prompts for workflow pipelines
|
|
181
183
|
*/
|
|
182
184
|
setupPrompts() {
|
|
183
|
-
console.error(
|
|
185
|
+
console.error("🎯 Setting up MCP Prompts for workflow pipelines...");
|
|
184
186
|
// Define workflow prompts that guide users through structured pipelines
|
|
185
187
|
const workflowPrompts = [
|
|
186
188
|
{
|
|
187
|
-
name:
|
|
188
|
-
description:
|
|
189
|
+
name: "code_optimization",
|
|
190
|
+
description: "Optimize existing Business Central code using systematic analysis phases",
|
|
189
191
|
arguments: [
|
|
190
192
|
{
|
|
191
|
-
name:
|
|
192
|
-
description:
|
|
193
|
-
required: false // No more required fields - specialist will ask conversationally
|
|
194
|
-
}
|
|
195
|
-
]
|
|
193
|
+
name: "code_location",
|
|
194
|
+
description: "Path to the code file or description of the code to optimize",
|
|
195
|
+
required: false, // No more required fields - specialist will ask conversationally
|
|
196
|
+
},
|
|
197
|
+
],
|
|
196
198
|
},
|
|
197
199
|
{
|
|
198
|
-
name:
|
|
199
|
-
description:
|
|
200
|
+
name: "architecture_review",
|
|
201
|
+
description: "Conduct comprehensive architecture review of Business Central solution",
|
|
200
202
|
arguments: [
|
|
201
203
|
{
|
|
202
|
-
name:
|
|
203
|
-
description:
|
|
204
|
-
required: false // Specialist will ask about scope naturally
|
|
205
|
-
}
|
|
206
|
-
]
|
|
204
|
+
name: "scope",
|
|
205
|
+
description: "Scope of review (module, solution, or specific components)",
|
|
206
|
+
required: false, // Specialist will ask about scope naturally
|
|
207
|
+
},
|
|
208
|
+
],
|
|
207
209
|
},
|
|
208
210
|
{
|
|
209
|
-
name:
|
|
210
|
-
description:
|
|
211
|
+
name: "security_audit",
|
|
212
|
+
description: "Perform security analysis and compliance check for Business Central implementation",
|
|
211
213
|
arguments: [
|
|
212
214
|
{
|
|
213
|
-
name:
|
|
214
|
-
description:
|
|
215
|
-
required: false // Specialist will gather this in conversation
|
|
216
|
-
}
|
|
217
|
-
]
|
|
215
|
+
name: "audit_scope",
|
|
216
|
+
description: "Security audit scope (permissions, data access, API security, etc.)",
|
|
217
|
+
required: false, // Specialist will gather this in conversation
|
|
218
|
+
},
|
|
219
|
+
],
|
|
218
220
|
},
|
|
219
221
|
{
|
|
220
|
-
name:
|
|
221
|
-
description:
|
|
222
|
+
name: "perf_review",
|
|
223
|
+
description: "Analyze and optimize Business Central performance issues",
|
|
222
224
|
arguments: [
|
|
223
225
|
{
|
|
224
|
-
name:
|
|
225
|
-
description:
|
|
226
|
-
required: false
|
|
227
|
-
}
|
|
228
|
-
]
|
|
226
|
+
name: "performance_concern",
|
|
227
|
+
description: "Description of performance issue or area to analyze",
|
|
228
|
+
required: false,
|
|
229
|
+
},
|
|
230
|
+
],
|
|
229
231
|
},
|
|
230
232
|
{
|
|
231
|
-
name:
|
|
232
|
-
description:
|
|
233
|
+
name: "integration_design",
|
|
234
|
+
description: "Design robust integration patterns for Business Central",
|
|
233
235
|
arguments: [
|
|
234
236
|
{
|
|
235
|
-
name:
|
|
236
|
-
description:
|
|
237
|
-
required: false
|
|
238
|
-
}
|
|
239
|
-
]
|
|
237
|
+
name: "integration_type",
|
|
238
|
+
description: "Type of integration (API, data sync, external service, etc.)",
|
|
239
|
+
required: false,
|
|
240
|
+
},
|
|
241
|
+
],
|
|
240
242
|
},
|
|
241
243
|
{
|
|
242
|
-
name:
|
|
243
|
-
description:
|
|
244
|
+
name: "upgrade_planning",
|
|
245
|
+
description: "Plan Business Central version upgrade with risk assessment",
|
|
244
246
|
arguments: [
|
|
245
247
|
{
|
|
246
|
-
name:
|
|
247
|
-
description:
|
|
248
|
-
required: false
|
|
248
|
+
name: "current_version",
|
|
249
|
+
description: "Current Business Central version",
|
|
250
|
+
required: false,
|
|
249
251
|
},
|
|
250
252
|
{
|
|
251
|
-
name:
|
|
252
|
-
description:
|
|
253
|
-
required: false
|
|
254
|
-
}
|
|
255
|
-
]
|
|
253
|
+
name: "target_version",
|
|
254
|
+
description: "Target Business Central version",
|
|
255
|
+
required: false,
|
|
256
|
+
},
|
|
257
|
+
],
|
|
256
258
|
},
|
|
257
259
|
{
|
|
258
|
-
name:
|
|
259
|
-
description:
|
|
260
|
+
name: "testing_strategy",
|
|
261
|
+
description: "Develop comprehensive testing strategy for Business Central solutions",
|
|
260
262
|
arguments: [
|
|
261
263
|
{
|
|
262
|
-
name:
|
|
263
|
-
description:
|
|
264
|
-
required: false
|
|
265
|
-
}
|
|
266
|
-
]
|
|
264
|
+
name: "testing_scope",
|
|
265
|
+
description: "Scope of testing (unit, integration, user acceptance, etc.)",
|
|
266
|
+
required: false,
|
|
267
|
+
},
|
|
268
|
+
],
|
|
267
269
|
},
|
|
268
270
|
{
|
|
269
|
-
name:
|
|
270
|
-
description:
|
|
271
|
+
name: "dev_onboarding",
|
|
272
|
+
description: "Guide new developer through Business Central development onboarding",
|
|
271
273
|
arguments: [
|
|
272
274
|
{
|
|
273
|
-
name:
|
|
274
|
-
description:
|
|
275
|
-
required: false
|
|
275
|
+
name: "experience_level",
|
|
276
|
+
description: "Developer experience level (beginner, intermediate, expert)",
|
|
277
|
+
required: false,
|
|
276
278
|
},
|
|
277
279
|
{
|
|
278
|
-
name:
|
|
279
|
-
description:
|
|
280
|
-
required: false
|
|
281
|
-
}
|
|
282
|
-
]
|
|
280
|
+
name: "focus_area",
|
|
281
|
+
description: "Primary focus area for onboarding (development, customization, integration)",
|
|
282
|
+
required: false,
|
|
283
|
+
},
|
|
284
|
+
],
|
|
283
285
|
},
|
|
284
286
|
{
|
|
285
|
-
name:
|
|
286
|
-
description:
|
|
287
|
+
name: "app_takeover",
|
|
288
|
+
description: "Analyze and orient developer taking over an unfamiliar Business Central app",
|
|
287
289
|
arguments: [
|
|
288
290
|
{
|
|
289
|
-
name:
|
|
290
|
-
description:
|
|
291
|
-
required: false
|
|
291
|
+
name: "app_source",
|
|
292
|
+
description: "Source of the app (path, repository, AppSource, or description)",
|
|
293
|
+
required: false,
|
|
292
294
|
},
|
|
293
295
|
{
|
|
294
|
-
name:
|
|
295
|
-
description:
|
|
296
|
-
required: false
|
|
297
|
-
}
|
|
298
|
-
]
|
|
296
|
+
name: "takeover_context",
|
|
297
|
+
description: "Context for takeover (maintenance, enhancement, migration, or handoff scenario)",
|
|
298
|
+
required: false,
|
|
299
|
+
},
|
|
300
|
+
],
|
|
299
301
|
},
|
|
300
302
|
{
|
|
301
|
-
name:
|
|
302
|
-
description:
|
|
303
|
+
name: "spec_analysis",
|
|
304
|
+
description: "Analyze requirements and specifications to determine development readiness",
|
|
303
305
|
arguments: [
|
|
304
306
|
{
|
|
305
|
-
name:
|
|
306
|
-
description:
|
|
307
|
-
required: false
|
|
307
|
+
name: "spec_source",
|
|
308
|
+
description: "Source of specifications (document, user story, requirements, or description)",
|
|
309
|
+
required: false,
|
|
308
310
|
},
|
|
309
311
|
{
|
|
310
|
-
name:
|
|
311
|
-
description:
|
|
312
|
-
required: false
|
|
313
|
-
}
|
|
314
|
-
]
|
|
312
|
+
name: "analysis_focus",
|
|
313
|
+
description: "Analysis focus (completeness, feasibility, technical-gaps, or dependencies)",
|
|
314
|
+
required: false,
|
|
315
|
+
},
|
|
316
|
+
],
|
|
315
317
|
},
|
|
316
318
|
{
|
|
317
|
-
name:
|
|
318
|
-
description:
|
|
319
|
+
name: "bug_investigation",
|
|
320
|
+
description: "Systematically investigate and resolve Business Central bugs and issues",
|
|
319
321
|
arguments: [
|
|
320
322
|
{
|
|
321
|
-
name:
|
|
322
|
-
description:
|
|
323
|
-
required: false
|
|
323
|
+
name: "bug_context",
|
|
324
|
+
description: "Available context (call-stack, repro-steps, snapshot, sandbox-access, or description)",
|
|
325
|
+
required: false,
|
|
324
326
|
},
|
|
325
327
|
{
|
|
326
|
-
name:
|
|
327
|
-
description:
|
|
328
|
-
required: false
|
|
329
|
-
}
|
|
330
|
-
]
|
|
328
|
+
name: "issue_severity",
|
|
329
|
+
description: "Issue severity level (critical, high, medium, low)",
|
|
330
|
+
required: false,
|
|
331
|
+
},
|
|
332
|
+
],
|
|
331
333
|
},
|
|
332
334
|
{
|
|
333
|
-
name:
|
|
334
|
-
description:
|
|
335
|
+
name: "monolith_to_modules",
|
|
336
|
+
description: "Refactor monolithic Business Central code into modular architecture using SOLID principles",
|
|
335
337
|
arguments: [
|
|
336
338
|
{
|
|
337
|
-
name:
|
|
338
|
-
description:
|
|
339
|
-
required: false
|
|
339
|
+
name: "current_structure",
|
|
340
|
+
description: "Current code structure (monolithic-object, large-codeunit, tightly-coupled, or description)",
|
|
341
|
+
required: false,
|
|
340
342
|
},
|
|
341
343
|
{
|
|
342
|
-
name:
|
|
343
|
-
description:
|
|
344
|
-
required: false
|
|
345
|
-
}
|
|
346
|
-
]
|
|
344
|
+
name: "modularization_goal",
|
|
345
|
+
description: "Modularization goal (dependency-injection, interface-patterns, loose-coupling, or testability)",
|
|
346
|
+
required: false,
|
|
347
|
+
},
|
|
348
|
+
],
|
|
347
349
|
},
|
|
348
350
|
{
|
|
349
|
-
name:
|
|
350
|
-
description:
|
|
351
|
+
name: "data_flow_tracing",
|
|
352
|
+
description: "Trace data flow and dependencies across Business Central objects and codeunits",
|
|
351
353
|
arguments: [
|
|
352
354
|
{
|
|
353
|
-
name:
|
|
354
|
-
description:
|
|
355
|
-
required: false
|
|
355
|
+
name: "trace_target",
|
|
356
|
+
description: "What to trace (field-usage, table-relationships, posting-flow, or process-chain)",
|
|
357
|
+
required: false,
|
|
356
358
|
},
|
|
357
359
|
{
|
|
358
|
-
name:
|
|
359
|
-
description:
|
|
360
|
-
required: false
|
|
361
|
-
}
|
|
362
|
-
]
|
|
360
|
+
name: "trace_scope",
|
|
361
|
+
description: "Tracing scope (single-object, module-level, cross-module, or end-to-end)",
|
|
362
|
+
required: false,
|
|
363
|
+
},
|
|
364
|
+
],
|
|
363
365
|
},
|
|
364
366
|
{
|
|
365
|
-
name:
|
|
366
|
-
description:
|
|
367
|
+
name: "full_review",
|
|
368
|
+
description: "Conduct comprehensive review and analysis without implementation changes",
|
|
367
369
|
arguments: [
|
|
368
370
|
{
|
|
369
|
-
name:
|
|
370
|
-
description:
|
|
371
|
-
required: false
|
|
371
|
+
name: "review_target",
|
|
372
|
+
description: "What to review (code, architecture, documentation, processes)",
|
|
373
|
+
required: false,
|
|
372
374
|
},
|
|
373
375
|
{
|
|
374
|
-
name:
|
|
375
|
-
description:
|
|
376
|
-
required: false
|
|
377
|
-
}
|
|
378
|
-
]
|
|
379
|
-
}
|
|
376
|
+
name: "review_depth",
|
|
377
|
+
description: "Review depth (surface, detailed, comprehensive)",
|
|
378
|
+
required: false,
|
|
379
|
+
},
|
|
380
|
+
],
|
|
381
|
+
},
|
|
380
382
|
];
|
|
381
383
|
// Register prompt list handler
|
|
382
384
|
this.server.setRequestHandler(ListPromptsRequestSchema, async () => ({
|
|
383
|
-
prompts: workflowPrompts.map(p => ({
|
|
385
|
+
prompts: workflowPrompts.map((p) => ({
|
|
384
386
|
name: p.name,
|
|
385
387
|
description: p.description,
|
|
386
|
-
arguments: p.arguments
|
|
387
|
-
}))
|
|
388
|
+
arguments: p.arguments,
|
|
389
|
+
})),
|
|
388
390
|
}));
|
|
389
391
|
// Register get prompt handler for all workflows
|
|
390
392
|
this.server.setRequestHandler(GetPromptRequestSchema, async (request) => {
|
|
391
393
|
const { name, arguments: args } = request.params;
|
|
392
|
-
const prompt = workflowPrompts.find(p => p.name === name);
|
|
394
|
+
const prompt = workflowPrompts.find((p) => p.name === name);
|
|
393
395
|
if (!prompt) {
|
|
394
396
|
throw new McpError(ErrorCode.InvalidRequest, `Unknown prompt: ${name}`);
|
|
395
397
|
}
|
|
396
398
|
try {
|
|
397
399
|
// Convert workflow name to type and create start request
|
|
398
400
|
const workflowTypeMap = {
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
401
|
+
code_optimization: "new-bc-app",
|
|
402
|
+
architecture_review: "enhance-bc-app",
|
|
403
|
+
security_audit: "debug-bc-issues",
|
|
404
|
+
perf_review: "debug-bc-issues",
|
|
405
|
+
integration_design: "add-ecosystem-features",
|
|
406
|
+
upgrade_planning: "upgrade-bc-version",
|
|
407
|
+
testing_strategy: "modernize-bc-code",
|
|
408
|
+
dev_onboarding: "onboard-developer",
|
|
409
|
+
app_takeover: "enhance-bc-app",
|
|
410
|
+
spec_analysis: "review-bc-code",
|
|
411
|
+
bug_investigation: "debug-bc-issues",
|
|
412
|
+
monolith_to_modules: "modernize-bc-code",
|
|
413
|
+
data_flow_tracing: "review-bc-code",
|
|
414
|
+
full_review: "review-bc-code",
|
|
413
415
|
};
|
|
414
416
|
const workflowType = workflowTypeMap[name];
|
|
415
417
|
if (!workflowType) {
|
|
@@ -417,22 +419,30 @@ Currently only embedded knowledge is loaded. Call \`set_workspace_info\` to enab
|
|
|
417
419
|
}
|
|
418
420
|
const startRequest = {
|
|
419
421
|
workflow_type: workflowType,
|
|
420
|
-
project_context: args?.code_location ||
|
|
421
|
-
args?.
|
|
422
|
-
args?.
|
|
423
|
-
|
|
422
|
+
project_context: args?.code_location ||
|
|
423
|
+
args?.scope ||
|
|
424
|
+
args?.audit_scope ||
|
|
425
|
+
args?.performance_concern ||
|
|
426
|
+
args?.integration_type ||
|
|
427
|
+
args?.testing_scope ||
|
|
428
|
+
args?.review_target ||
|
|
429
|
+
"General workflow request",
|
|
424
430
|
bc_version: args?.target_version || args?.current_version,
|
|
425
|
-
additional_context: args
|
|
431
|
+
additional_context: args,
|
|
426
432
|
};
|
|
427
433
|
// Start the workflow session
|
|
428
434
|
const session = await this.workflowService.startWorkflow(startRequest);
|
|
429
435
|
// Get the initial guidance for this workflow
|
|
430
436
|
const initialGuidance = await this.workflowService.getPhaseGuidance(session.id);
|
|
431
437
|
// Enhance with specialist routing
|
|
432
|
-
const userContext = args?.code_location ||
|
|
433
|
-
args?.
|
|
434
|
-
args?.
|
|
435
|
-
|
|
438
|
+
const userContext = args?.code_location ||
|
|
439
|
+
args?.scope ||
|
|
440
|
+
args?.audit_scope ||
|
|
441
|
+
args?.performance_concern ||
|
|
442
|
+
args?.integration_type ||
|
|
443
|
+
args?.testing_scope ||
|
|
444
|
+
args?.review_target ||
|
|
445
|
+
"General workflow request";
|
|
436
446
|
const enhancedResult = await this.workflowSpecialistRouter.enhanceWorkflowPrompt(name, userContext, initialGuidance);
|
|
437
447
|
// Construct explicit prompt that bypasses VS Code prompt creation
|
|
438
448
|
const promptContent = `# ${prompt.description}
|
|
@@ -444,27 +454,27 @@ ${enhancedResult.enhancedContent}
|
|
|
444
454
|
## 🎯 Next Actions
|
|
445
455
|
|
|
446
456
|
**Use these MCP tools immediately to proceed:**
|
|
447
|
-
${enhancedResult.routingOptions.map(option => `- ${option.replace(
|
|
457
|
+
${enhancedResult.routingOptions.map((option) => `- ${option.replace("🎯 Start session with", "**Use MCP tool:**")}`).join("\n")}
|
|
448
458
|
|
|
449
459
|
**Remember:** You have access to 20+ MCP tools from bc-code-intelligence-mcp. Use them actively for specialist consultation and knowledge access.`;
|
|
450
460
|
return {
|
|
451
461
|
description: `Starting ${workflowType} workflow with specialist guidance`,
|
|
452
462
|
messages: [
|
|
453
463
|
{
|
|
454
|
-
role:
|
|
464
|
+
role: "user",
|
|
455
465
|
content: {
|
|
456
|
-
type:
|
|
457
|
-
text: promptContent
|
|
458
|
-
}
|
|
459
|
-
}
|
|
460
|
-
]
|
|
466
|
+
type: "text",
|
|
467
|
+
text: promptContent,
|
|
468
|
+
},
|
|
469
|
+
},
|
|
470
|
+
],
|
|
461
471
|
};
|
|
462
472
|
}
|
|
463
473
|
catch (error) {
|
|
464
474
|
throw new McpError(ErrorCode.InternalError, `Failed to start workflow: ${error instanceof Error ? error.message : String(error)}`);
|
|
465
475
|
}
|
|
466
476
|
});
|
|
467
|
-
console.error(
|
|
477
|
+
console.error("✅ MCP Prompts configured for workflow orchestration");
|
|
468
478
|
}
|
|
469
479
|
/**
|
|
470
480
|
* Initialize all services with configuration
|
|
@@ -479,14 +489,16 @@ ${enhancedResult.routingOptions.map(option => `- ${option.replace('🎯 Start se
|
|
|
479
489
|
const __filename = fileURLToPath(import.meta.url);
|
|
480
490
|
const __dirname = dirname(__filename);
|
|
481
491
|
const legacyConfig = {
|
|
482
|
-
knowledge_base_path: process.env[
|
|
483
|
-
indexes_path: process.env[
|
|
484
|
-
|
|
492
|
+
knowledge_base_path: process.env["BCKB_KB_PATH"] || join(__dirname, "../embedded-knowledge"),
|
|
493
|
+
indexes_path: process.env["BCKB_INDEXES_PATH"] ||
|
|
494
|
+
join(__dirname, "../embedded-knowledge/indexes"),
|
|
495
|
+
workflows_path: process.env["BCKB_WORKFLOWS_PATH"] ||
|
|
496
|
+
join(__dirname, "../embedded-knowledge/workflows"),
|
|
485
497
|
cache_size: this.configuration.cache.max_size_mb * 1024, // Convert MB to entries approximation
|
|
486
498
|
max_search_results: 20,
|
|
487
|
-
default_bc_version:
|
|
499
|
+
default_bc_version: "BC22",
|
|
488
500
|
enable_fuzzy_search: true,
|
|
489
|
-
search_threshold: 0.6
|
|
501
|
+
search_threshold: 0.6,
|
|
490
502
|
};
|
|
491
503
|
// Initialize specialist services using a dedicated MultiContentLayerService FIRST
|
|
492
504
|
this.layerService = new MultiContentLayerService();
|
|
@@ -502,15 +514,15 @@ ${enhancedResult.routingOptions.map(option => `- ${option.replace('🎯 Start se
|
|
|
502
514
|
case LayerSourceType.EMBEDDED: {
|
|
503
515
|
// Embedded layer - ALWAYS use the server's embedded knowledge directory
|
|
504
516
|
// The 'path' field is ignored for embedded layers since they reference the built-in knowledge
|
|
505
|
-
const embeddedPath = join(__dirname,
|
|
517
|
+
const embeddedPath = join(__dirname, "../embedded-knowledge");
|
|
506
518
|
console.error(`📋 Embedded layer using built-in knowledge: ${embeddedPath}`);
|
|
507
|
-
const { EmbeddedKnowledgeLayer } = await import(
|
|
519
|
+
const { EmbeddedKnowledgeLayer } = await import("./layers/embedded-layer.js");
|
|
508
520
|
layer = new EmbeddedKnowledgeLayer(embeddedPath);
|
|
509
521
|
break;
|
|
510
522
|
}
|
|
511
523
|
case LayerSourceType.LOCAL: {
|
|
512
524
|
// Local filesystem layer - use ProjectKnowledgeLayer
|
|
513
|
-
const { ProjectKnowledgeLayer } = await import(
|
|
525
|
+
const { ProjectKnowledgeLayer } = await import("./layers/project-layer.js");
|
|
514
526
|
layer = new ProjectKnowledgeLayer(layerConfig.source.path);
|
|
515
527
|
// Override name and priority from config
|
|
516
528
|
layer.name = layerConfig.name;
|
|
@@ -519,13 +531,13 @@ ${enhancedResult.routingOptions.map(option => `- ${option.replace('🎯 Start se
|
|
|
519
531
|
}
|
|
520
532
|
case LayerSourceType.GIT: {
|
|
521
533
|
// Git repository layer
|
|
522
|
-
const { GitKnowledgeLayer } = await import(
|
|
534
|
+
const { GitKnowledgeLayer } = await import("./layers/git-layer.js");
|
|
523
535
|
const gitSource = layerConfig.source; // GitLayerSource
|
|
524
536
|
layer = new GitKnowledgeLayer(layerConfig.name, layerConfig.priority, {
|
|
525
537
|
type: LayerSourceType.GIT,
|
|
526
538
|
url: gitSource.url,
|
|
527
539
|
branch: gitSource.branch,
|
|
528
|
-
subpath: gitSource.subpath
|
|
540
|
+
subpath: gitSource.subpath,
|
|
529
541
|
}, layerConfig.auth);
|
|
530
542
|
break;
|
|
531
543
|
}
|
|
@@ -591,7 +603,7 @@ ${enhancedResult.routingOptions.map(option => `- ${option.replace('🎯 Start se
|
|
|
591
603
|
// Create tool handlers with all service dependencies
|
|
592
604
|
const workspaceContext = {
|
|
593
605
|
setWorkspaceInfo: this.setWorkspaceInfo.bind(this),
|
|
594
|
-
getWorkspaceInfo: this.getWorkspaceInfo.bind(this)
|
|
606
|
+
getWorkspaceInfo: this.getWorkspaceInfo.bind(this),
|
|
595
607
|
};
|
|
596
608
|
const handlerServices = {
|
|
597
609
|
knowledgeService: this.knowledgeService,
|
|
@@ -602,16 +614,16 @@ ${enhancedResult.routingOptions.map(option => `- ${option.replace('🎯 Start se
|
|
|
602
614
|
sessionManager: this.specialistSessionManager,
|
|
603
615
|
discoveryService: this.specialistDiscoveryService,
|
|
604
616
|
configLoader: this.configLoader,
|
|
605
|
-
workflowSessionManager: this.workflowSessionManager
|
|
617
|
+
workflowSessionManager: this.workflowSessionManager,
|
|
606
618
|
};
|
|
607
619
|
this.toolHandlers = createToolHandlers(handlerServices, workspaceContext);
|
|
608
620
|
// Initialize debug tool handlers ONLY if enabled (reduces token overhead)
|
|
609
621
|
if (this.configuration.developer.enable_diagnostic_tools) {
|
|
610
622
|
this.debugToolHandlers = createDebugToolHandlers(handlerServices);
|
|
611
|
-
console.error(
|
|
623
|
+
console.error("🔧 Configuration diagnostic tools enabled");
|
|
612
624
|
}
|
|
613
625
|
else {
|
|
614
|
-
console.error(
|
|
626
|
+
console.error("💡 Tip: Set developer.enable_diagnostic_tools=true for git layer diagnostics");
|
|
615
627
|
}
|
|
616
628
|
// Report final totals
|
|
617
629
|
const specialists = await this.layerService.getAllSpecialists();
|
|
@@ -654,8 +666,8 @@ ${enhancedResult.routingOptions.map(option => `- ${option.replace('🎯 Start se
|
|
|
654
666
|
server_version: this.getPackageVersion(),
|
|
655
667
|
layers_active: this.layerService?.getLayers().length || 0,
|
|
656
668
|
configuration_loaded: !!this.configuration,
|
|
657
|
-
total_topics: this.layerService?.getAllTopicIds().length || 0
|
|
658
|
-
}
|
|
669
|
+
total_topics: this.layerService?.getAllTopicIds().length || 0,
|
|
670
|
+
},
|
|
659
671
|
};
|
|
660
672
|
if (includeTopicAnalytics && this.layerService) {
|
|
661
673
|
analytics.topic_analytics = await this.generateTopicAnalytics();
|
|
@@ -664,7 +676,8 @@ ${enhancedResult.routingOptions.map(option => `- ${option.replace('🎯 Start se
|
|
|
664
676
|
analytics.layer_performance = this.generateLayerPerformanceAnalytics();
|
|
665
677
|
}
|
|
666
678
|
if (includeConfigurationInsights && this.configuration) {
|
|
667
|
-
analytics.configuration_insights =
|
|
679
|
+
analytics.configuration_insights =
|
|
680
|
+
await this.generateConfigurationInsights();
|
|
668
681
|
}
|
|
669
682
|
return analytics;
|
|
670
683
|
}
|
|
@@ -689,7 +702,8 @@ ${enhancedResult.routingOptions.map(option => `- ${option.replace('🎯 Start se
|
|
|
689
702
|
domainDistribution[domain] = (domainDistribution[domain] || 0) + 1;
|
|
690
703
|
}
|
|
691
704
|
if (difficulty) {
|
|
692
|
-
difficultyDistribution[difficulty] =
|
|
705
|
+
difficultyDistribution[difficulty] =
|
|
706
|
+
(difficultyDistribution[difficulty] || 0) + 1;
|
|
693
707
|
}
|
|
694
708
|
}
|
|
695
709
|
}
|
|
@@ -701,15 +715,16 @@ ${enhancedResult.routingOptions.map(option => `- ${option.replace('🎯 Start se
|
|
|
701
715
|
override_statistics: {
|
|
702
716
|
total_overrides: Object.keys(overrideStats).length,
|
|
703
717
|
override_percentage: allTopicIds.length > 0
|
|
704
|
-
? ((Object.keys(overrideStats).length / allTopicIds.length) *
|
|
705
|
-
|
|
718
|
+
? ((Object.keys(overrideStats).length / allTopicIds.length) *
|
|
719
|
+
100).toFixed(1) + "%"
|
|
720
|
+
: "0%",
|
|
706
721
|
},
|
|
707
722
|
coverage_insights: {
|
|
708
723
|
domains_covered: Object.keys(domainDistribution).length,
|
|
709
724
|
difficulty_levels: Object.keys(difficultyDistribution).length,
|
|
710
|
-
most_common_domain: Object.entries(domainDistribution).sort(([, a], [, b]) => b - a)[0]?.[0] ||
|
|
711
|
-
most_common_difficulty: Object.entries(difficultyDistribution).sort(([, a], [, b]) => b - a)[0]?.[0] ||
|
|
712
|
-
}
|
|
725
|
+
most_common_domain: Object.entries(domainDistribution).sort(([, a], [, b]) => b - a)[0]?.[0] || "N/A",
|
|
726
|
+
most_common_difficulty: Object.entries(difficultyDistribution).sort(([, a], [, b]) => b - a)[0]?.[0] || "N/A",
|
|
727
|
+
},
|
|
713
728
|
};
|
|
714
729
|
}
|
|
715
730
|
/**
|
|
@@ -718,16 +733,18 @@ ${enhancedResult.routingOptions.map(option => `- ${option.replace('🎯 Start se
|
|
|
718
733
|
generateLayerPerformanceAnalytics() {
|
|
719
734
|
const layerStats = this.layerService.getLayerStatistics();
|
|
720
735
|
const layerMetrics = this.layerService.getStatistics();
|
|
721
|
-
const formattedMetrics = layerMetrics.map(stats => {
|
|
736
|
+
const formattedMetrics = layerMetrics.map((stats) => {
|
|
722
737
|
return {
|
|
723
738
|
name: stats.name,
|
|
724
739
|
priority: stats.priority,
|
|
725
740
|
enabled: stats.enabled,
|
|
726
741
|
topic_count: stats.topicCount,
|
|
727
742
|
index_count: stats.indexCount,
|
|
728
|
-
memory_usage_mb: stats.memoryUsage?.total
|
|
743
|
+
memory_usage_mb: stats.memoryUsage?.total
|
|
744
|
+
? (stats.memoryUsage.total / (1024 * 1024)).toFixed(2)
|
|
745
|
+
: "N/A",
|
|
729
746
|
load_time_ms: stats.loadTimeMs || 0,
|
|
730
|
-
type:
|
|
747
|
+
type: "MultiContentLayer",
|
|
731
748
|
};
|
|
732
749
|
});
|
|
733
750
|
const totalTopics = layerMetrics.reduce((sum, stats) => sum + stats.topicCount, 0);
|
|
@@ -736,16 +753,19 @@ ${enhancedResult.routingOptions.map(option => `- ${option.replace('🎯 Start se
|
|
|
736
753
|
total_layers: layerMetrics.length,
|
|
737
754
|
total_topics: totalTopics,
|
|
738
755
|
total_indexes: layerMetrics.reduce((sum, stats) => sum + stats.indexCount, 0),
|
|
739
|
-
total_memory_mb:
|
|
756
|
+
total_memory_mb: "N/A", // Memory tracking not implemented in new system
|
|
740
757
|
},
|
|
741
758
|
layer_metrics: formattedMetrics,
|
|
742
759
|
performance_insights: {
|
|
743
|
-
fastest_layer: formattedMetrics.sort((a, b) => a.load_time_ms - b.load_time_ms)[0]
|
|
744
|
-
|
|
760
|
+
fastest_layer: formattedMetrics.sort((a, b) => a.load_time_ms - b.load_time_ms)[0]
|
|
761
|
+
?.name || "N/A",
|
|
762
|
+
most_topics: formattedMetrics.sort((a, b) => b.topic_count - a.topic_count)[0]
|
|
763
|
+
?.name || "N/A",
|
|
745
764
|
layer_efficiency: layerMetrics.length > 0
|
|
746
|
-
? (totalTopics / layerMetrics.length).toFixed(1) +
|
|
747
|
-
|
|
748
|
-
|
|
765
|
+
? (totalTopics / layerMetrics.length).toFixed(1) +
|
|
766
|
+
" topics/layer avg"
|
|
767
|
+
: "N/A",
|
|
768
|
+
},
|
|
749
769
|
};
|
|
750
770
|
}
|
|
751
771
|
/**
|
|
@@ -759,46 +779,49 @@ ${enhancedResult.routingOptions.map(option => `- ${option.replace('🎯 Start se
|
|
|
759
779
|
overall_score: validation.score,
|
|
760
780
|
is_valid: validation.valid,
|
|
761
781
|
error_count: validation.errors.length,
|
|
762
|
-
warning_count: validation.warnings.length
|
|
782
|
+
warning_count: validation.warnings.length,
|
|
763
783
|
},
|
|
764
784
|
layer_configuration: {
|
|
765
785
|
total_layers: this.configuration.layers.length,
|
|
766
|
-
enabled_layers: this.configuration.layers.filter(l => l.enabled)
|
|
786
|
+
enabled_layers: this.configuration.layers.filter((l) => l.enabled)
|
|
787
|
+
.length,
|
|
767
788
|
layer_types: this.configuration.layers.reduce((acc, layer) => {
|
|
768
789
|
acc[layer.source.type] = (acc[layer.source.type] || 0) + 1;
|
|
769
790
|
return acc;
|
|
770
791
|
}, {}),
|
|
771
|
-
priority_distribution: this.configuration.layers
|
|
792
|
+
priority_distribution: this.configuration.layers
|
|
793
|
+
.map((l) => l.priority)
|
|
794
|
+
.sort((a, b) => a - b),
|
|
772
795
|
},
|
|
773
|
-
optimization_recommendations: []
|
|
796
|
+
optimization_recommendations: [],
|
|
774
797
|
};
|
|
775
798
|
// Generate optimization recommendations
|
|
776
|
-
if (this.configuration.layers.filter(l => l.enabled).length < 2) {
|
|
799
|
+
if (this.configuration.layers.filter((l) => l.enabled).length < 2) {
|
|
777
800
|
insights.optimization_recommendations.push({
|
|
778
|
-
type:
|
|
779
|
-
message:
|
|
780
|
-
impact:
|
|
801
|
+
type: "layer_diversity",
|
|
802
|
+
message: "Consider adding more layer types (git, local overrides) for better customization",
|
|
803
|
+
impact: "medium",
|
|
781
804
|
});
|
|
782
805
|
}
|
|
783
806
|
if (this.configuration.performance.max_concurrent_loads < 3) {
|
|
784
807
|
insights.optimization_recommendations.push({
|
|
785
|
-
type:
|
|
786
|
-
message:
|
|
787
|
-
impact:
|
|
808
|
+
type: "performance",
|
|
809
|
+
message: "Increase max_concurrent_loads for better performance on modern systems",
|
|
810
|
+
impact: "low",
|
|
788
811
|
});
|
|
789
812
|
}
|
|
790
813
|
if (!this.configuration.security.validate_sources) {
|
|
791
814
|
insights.optimization_recommendations.push({
|
|
792
|
-
type:
|
|
793
|
-
message:
|
|
794
|
-
impact:
|
|
815
|
+
type: "security",
|
|
816
|
+
message: "Enable source validation for better security",
|
|
817
|
+
impact: "high",
|
|
795
818
|
});
|
|
796
819
|
}
|
|
797
820
|
if (validation.warnings.length > 0) {
|
|
798
821
|
insights.optimization_recommendations.push({
|
|
799
|
-
type:
|
|
822
|
+
type: "configuration",
|
|
800
823
|
message: `Address ${validation.warnings.length} configuration warnings`,
|
|
801
|
-
impact:
|
|
824
|
+
impact: "medium",
|
|
802
825
|
});
|
|
803
826
|
}
|
|
804
827
|
return insights;
|
|
@@ -806,7 +829,7 @@ ${enhancedResult.routingOptions.map(option => `- ${option.replace('🎯 Start se
|
|
|
806
829
|
async run() {
|
|
807
830
|
try {
|
|
808
831
|
// Ultra-early diagnostics for platform issues
|
|
809
|
-
console.error(
|
|
832
|
+
console.error("=== BC Code Intelligence MCP Server Startup Diagnostics ===");
|
|
810
833
|
console.error(`Platform: ${process.platform}`);
|
|
811
834
|
console.error(`Node version: ${process.version}`);
|
|
812
835
|
console.error(`Architecture: ${process.arch}`);
|
|
@@ -816,20 +839,20 @@ ${enhancedResult.routingOptions.map(option => `- ${option.replace('🎯 Start se
|
|
|
816
839
|
console.error(`🚀 BC Code Intelligence MCP Server v${version} starting...`);
|
|
817
840
|
// CRITICAL FIX for Issue #31: Connect transport BEFORE heavy initialization
|
|
818
841
|
// This allows the MCP handshake to complete quickly, preventing timeouts
|
|
819
|
-
console.error(
|
|
842
|
+
console.error("🔌 Connecting MCP transport (fast handshake)...");
|
|
820
843
|
const transport = new StdioServerTransport();
|
|
821
844
|
await this.server.connect(transport);
|
|
822
|
-
console.error(
|
|
845
|
+
console.error("✅ MCP transport connected - handshake complete");
|
|
823
846
|
// Now perform heavy initialization in background
|
|
824
|
-
console.error(
|
|
847
|
+
console.error("📦 Starting service initialization (deferred after handshake)...");
|
|
825
848
|
// Verify embedded knowledge path BEFORE any service initialization
|
|
826
849
|
const __filename = fileURLToPath(import.meta.url);
|
|
827
850
|
const __dirname = dirname(__filename);
|
|
828
|
-
const embeddedPath = join(__dirname,
|
|
851
|
+
const embeddedPath = join(__dirname, "..", "embedded-knowledge");
|
|
829
852
|
console.error(`Embedded knowledge path: ${embeddedPath}`);
|
|
830
853
|
console.error(`Embedded knowledge exists: ${existsSync(embeddedPath)}`);
|
|
831
854
|
if (existsSync(embeddedPath)) {
|
|
832
|
-
const expectedDirs = [
|
|
855
|
+
const expectedDirs = ["domains", "specialists", "workflows"];
|
|
833
856
|
for (const dir of expectedDirs) {
|
|
834
857
|
const dirPath = join(embeddedPath, dir);
|
|
835
858
|
console.error(` ${dir}/: ${existsSync(dirPath)}`);
|
|
@@ -837,10 +860,11 @@ ${enhancedResult.routingOptions.map(option => `- ${option.replace('🎯 Start se
|
|
|
837
860
|
}
|
|
838
861
|
// Try to load user-level configuration first (company layers)
|
|
839
862
|
// If no user config exists, fall back to embedded-only mode
|
|
840
|
-
console.error(
|
|
863
|
+
console.error("📦 Checking for user-level configuration (company layers)...");
|
|
841
864
|
try {
|
|
842
865
|
const userConfigResult = await this.configLoader.loadConfiguration();
|
|
843
|
-
if (userConfigResult.config.layers &&
|
|
866
|
+
if (userConfigResult.config.layers &&
|
|
867
|
+
userConfigResult.config.layers.length > 1) {
|
|
844
868
|
// User has configured layers (embedded + company/git layers)
|
|
845
869
|
console.error(`✅ Found user-level configuration with ${userConfigResult.config.layers.length} layers`);
|
|
846
870
|
this.configuration = userConfigResult.config;
|
|
@@ -850,27 +874,29 @@ ${enhancedResult.routingOptions.map(option => `- ${option.replace('🎯 Start se
|
|
|
850
874
|
catch (configError) {
|
|
851
875
|
// CRITICAL FIX: If user config initialization fails (e.g. git layer auth failure),
|
|
852
876
|
// fall back to embedded-only mode instead of crashing the server
|
|
853
|
-
console.error(
|
|
854
|
-
|
|
877
|
+
console.error("❌ Failed to initialize with user configuration:", configError instanceof Error
|
|
878
|
+
? configError.message
|
|
879
|
+
: String(configError));
|
|
880
|
+
console.error("🔄 Falling back to embedded-only mode...");
|
|
855
881
|
await this.initializeEmbeddedOnly();
|
|
856
882
|
}
|
|
857
883
|
}
|
|
858
884
|
else {
|
|
859
885
|
// No user config or only embedded layer - use embedded-only mode
|
|
860
|
-
console.error(
|
|
886
|
+
console.error("📦 No user-level configuration found, loading embedded knowledge only...");
|
|
861
887
|
await this.initializeEmbeddedOnly();
|
|
862
888
|
}
|
|
863
889
|
}
|
|
864
890
|
catch (error) {
|
|
865
|
-
console.error(
|
|
891
|
+
console.error("⚠️ Failed to load user configuration, falling back to embedded-only:", error instanceof Error ? error.message : String(error));
|
|
866
892
|
await this.initializeEmbeddedOnly();
|
|
867
893
|
}
|
|
868
894
|
console.error(`✅ BC Code Intelligence MCP Server v${this.getPackageVersion()} started successfully`);
|
|
869
895
|
console.error(`💡 To enable project-specific layers, call set_workspace_info with your project path`);
|
|
870
896
|
}
|
|
871
897
|
catch (error) {
|
|
872
|
-
console.error(
|
|
873
|
-
console.error(
|
|
898
|
+
console.error("💥 Fatal error during server startup:", error);
|
|
899
|
+
console.error("Error stack:", error instanceof Error ? error.stack : "No stack trace");
|
|
874
900
|
process.exit(1);
|
|
875
901
|
}
|
|
876
902
|
}
|
|
@@ -880,23 +906,23 @@ ${enhancedResult.routingOptions.map(option => `- ${option.replace('🎯 Start se
|
|
|
880
906
|
async initializeEmbeddedOnly() {
|
|
881
907
|
const __filename = fileURLToPath(import.meta.url);
|
|
882
908
|
const __dirname = dirname(__filename);
|
|
883
|
-
const embeddedPath = join(__dirname,
|
|
909
|
+
const embeddedPath = join(__dirname, "../embedded-knowledge");
|
|
884
910
|
// Initialize minimal layer service with only embedded
|
|
885
911
|
this.layerService = new MultiContentLayerService();
|
|
886
|
-
const { EmbeddedKnowledgeLayer } = await import(
|
|
912
|
+
const { EmbeddedKnowledgeLayer } = await import("./layers/embedded-layer.js");
|
|
887
913
|
const embeddedLayer = new EmbeddedKnowledgeLayer(embeddedPath);
|
|
888
914
|
this.layerService.addLayer(embeddedLayer);
|
|
889
915
|
await this.layerService.initialize();
|
|
890
916
|
// Initialize minimal services for embedded-only mode
|
|
891
917
|
const legacyConfig = {
|
|
892
918
|
knowledge_base_path: embeddedPath,
|
|
893
|
-
indexes_path: join(embeddedPath,
|
|
894
|
-
workflows_path: join(embeddedPath,
|
|
919
|
+
indexes_path: join(embeddedPath, "indexes"),
|
|
920
|
+
workflows_path: join(embeddedPath, "workflows"),
|
|
895
921
|
cache_size: 1000,
|
|
896
922
|
max_search_results: 20,
|
|
897
|
-
default_bc_version:
|
|
923
|
+
default_bc_version: "BC22",
|
|
898
924
|
enable_fuzzy_search: true,
|
|
899
|
-
search_threshold: 0.6
|
|
925
|
+
search_threshold: 0.6,
|
|
900
926
|
};
|
|
901
927
|
this.knowledgeService = new KnowledgeService(legacyConfig);
|
|
902
928
|
await this.knowledgeService.initialize();
|
|
@@ -909,9 +935,9 @@ ${enhancedResult.routingOptions.map(option => `- ${option.replace('🎯 Start se
|
|
|
909
935
|
const sessionStorageConfig = this.layerService.getSessionStorageConfig();
|
|
910
936
|
this.specialistSessionManager = new SpecialistSessionManager(this.layerService, sessionStorageConfig);
|
|
911
937
|
this.specialistDiscoveryService = new SpecialistDiscoveryService(this.layerService);
|
|
912
|
-
// Note: Services and tools are initialized, but servicesInitialized = false
|
|
938
|
+
// Note: Services and tools are initialized, but servicesInitialized = false
|
|
913
939
|
// This prevents tools from being called until workspace is set
|
|
914
|
-
console.error(
|
|
940
|
+
console.error("✅ Embedded knowledge loaded. Workspace-specific services pending set_workspace_info.");
|
|
915
941
|
}
|
|
916
942
|
/**
|
|
917
943
|
* Initialize with user-level configuration (company layers from ~/.bc-code-intel/config.yaml)
|
|
@@ -925,7 +951,7 @@ ${enhancedResult.routingOptions.map(option => `- ${option.replace('🎯 Start se
|
|
|
925
951
|
const topics = this.layerService.getAllTopicIds();
|
|
926
952
|
const layers = this.layerService.getLayers();
|
|
927
953
|
console.error(`✅ User configuration loaded: ${topics.length} topics from ${layers.length} layers, ${specialists.length} specialists`);
|
|
928
|
-
layers.forEach(layer => {
|
|
954
|
+
layers.forEach((layer) => {
|
|
929
955
|
const topicCount = layer.getTopicIds().length;
|
|
930
956
|
console.error(` 📚 ${layer.name}: ${topicCount} topics (priority ${layer.priority})`);
|
|
931
957
|
});
|
|
@@ -936,14 +962,14 @@ ${enhancedResult.routingOptions.map(option => `- ${option.replace('🎯 Start se
|
|
|
936
962
|
async setWorkspaceInfo(path, availableMcps = []) {
|
|
937
963
|
try {
|
|
938
964
|
// Normalize and validate path
|
|
939
|
-
const { resolve } = await import(
|
|
940
|
-
const { existsSync } = await import(
|
|
965
|
+
const { resolve } = await import("path");
|
|
966
|
+
const { existsSync } = await import("fs");
|
|
941
967
|
const resolvedPath = resolve(path);
|
|
942
968
|
if (!existsSync(resolvedPath)) {
|
|
943
969
|
return {
|
|
944
970
|
success: false,
|
|
945
971
|
message: `Path does not exist: ${resolvedPath}`,
|
|
946
|
-
reloaded: false
|
|
972
|
+
reloaded: false,
|
|
947
973
|
};
|
|
948
974
|
}
|
|
949
975
|
// Check if this is the same workspace
|
|
@@ -956,13 +982,13 @@ ${enhancedResult.routingOptions.map(option => `- ${option.replace('🎯 Start se
|
|
|
956
982
|
}
|
|
957
983
|
return {
|
|
958
984
|
success: true,
|
|
959
|
-
message: `Workspace root already set to: ${resolvedPath}${availableMcps.length > 0 ? ` | Updated MCP ecosystem: ${availableMcps.length} servers` :
|
|
960
|
-
reloaded: false
|
|
985
|
+
message: `Workspace root already set to: ${resolvedPath}${availableMcps.length > 0 ? ` | Updated MCP ecosystem: ${availableMcps.length} servers` : ""}`,
|
|
986
|
+
reloaded: false,
|
|
961
987
|
};
|
|
962
988
|
}
|
|
963
989
|
console.error(`📁 Setting workspace root to: ${resolvedPath}`);
|
|
964
990
|
if (availableMcps.length > 0) {
|
|
965
|
-
console.error(`🔧 MCP Ecosystem: ${availableMcps.join(
|
|
991
|
+
console.error(`🔧 MCP Ecosystem: ${availableMcps.join(", ")}`);
|
|
966
992
|
}
|
|
967
993
|
// Change working directory
|
|
968
994
|
process.chdir(resolvedPath);
|
|
@@ -975,8 +1001,8 @@ ${enhancedResult.routingOptions.map(option => `- ${option.replace('🎯 Start se
|
|
|
975
1001
|
// Load configuration with workspace context (merges user + project configs)
|
|
976
1002
|
const configResult = await this.configLoader.loadConfiguration(resolvedPath);
|
|
977
1003
|
if (configResult.validation_errors.length > 0) {
|
|
978
|
-
console.error(
|
|
979
|
-
configResult.validation_errors.forEach(error => {
|
|
1004
|
+
console.error("⚠️ Configuration validation errors:");
|
|
1005
|
+
configResult.validation_errors.forEach((error) => {
|
|
980
1006
|
console.error(` - ${error.field}: ${error.message}`);
|
|
981
1007
|
});
|
|
982
1008
|
}
|
|
@@ -985,19 +1011,21 @@ ${enhancedResult.routingOptions.map(option => `- ${option.replace('🎯 Start se
|
|
|
985
1011
|
this.servicesInitialized = true;
|
|
986
1012
|
const specialists = await this.layerService.getAllSpecialists();
|
|
987
1013
|
const topics = this.layerService.getAllTopicIds();
|
|
988
|
-
const mcpInfo = availableMcps.length > 0
|
|
1014
|
+
const mcpInfo = availableMcps.length > 0
|
|
1015
|
+
? ` | MCP Ecosystem: ${availableMcps.length} servers`
|
|
1016
|
+
: "";
|
|
989
1017
|
return {
|
|
990
1018
|
success: true,
|
|
991
1019
|
message: `Workspace configured successfully. Loaded ${topics.length} topics from ${this.layerService.getLayers().length} layers, ${specialists.length} specialists available.${mcpInfo}`,
|
|
992
|
-
reloaded: true
|
|
1020
|
+
reloaded: true,
|
|
993
1021
|
};
|
|
994
1022
|
}
|
|
995
1023
|
catch (error) {
|
|
996
|
-
console.error(
|
|
1024
|
+
console.error("❌ Error setting workspace info:", error);
|
|
997
1025
|
return {
|
|
998
1026
|
success: false,
|
|
999
1027
|
message: `Failed to set workspace info: ${error instanceof Error ? error.message : String(error)}`,
|
|
1000
|
-
reloaded: false
|
|
1028
|
+
reloaded: false,
|
|
1001
1029
|
};
|
|
1002
1030
|
}
|
|
1003
1031
|
}
|
|
@@ -1007,7 +1035,7 @@ ${enhancedResult.routingOptions.map(option => `- ${option.replace('🎯 Start se
|
|
|
1007
1035
|
getWorkspaceInfo() {
|
|
1008
1036
|
return {
|
|
1009
1037
|
workspace_root: this.workspaceRoot,
|
|
1010
|
-
available_mcps: this.availableMcps
|
|
1038
|
+
available_mcps: this.availableMcps,
|
|
1011
1039
|
};
|
|
1012
1040
|
}
|
|
1013
1041
|
/**
|
|
@@ -1030,7 +1058,7 @@ ${enhancedResult.routingOptions.map(option => `- ${option.replace('🎯 Start se
|
|
|
1030
1058
|
async function main() {
|
|
1031
1059
|
try {
|
|
1032
1060
|
// Ultra-early platform diagnostics (before any server initialization)
|
|
1033
|
-
console.error(
|
|
1061
|
+
console.error("=== Pre-Initialization Platform Check ===");
|
|
1034
1062
|
console.error(`Node.js: ${process.version}`);
|
|
1035
1063
|
console.error(`Platform: ${process.platform} (${process.arch})`);
|
|
1036
1064
|
console.error(`PWD: ${process.cwd()}`);
|
|
@@ -1039,7 +1067,7 @@ async function main() {
|
|
|
1039
1067
|
const workspaceArg = process.argv[2];
|
|
1040
1068
|
if (workspaceArg) {
|
|
1041
1069
|
console.error(`Workspace argument provided: "${workspaceArg}"`);
|
|
1042
|
-
const { resolve } = await import(
|
|
1070
|
+
const { resolve } = await import("path");
|
|
1043
1071
|
const resolvedPath = resolve(workspaceArg);
|
|
1044
1072
|
console.error(`Resolved to: ${resolvedPath}`);
|
|
1045
1073
|
// Override process.cwd() for config/layer discovery
|
|
@@ -1050,48 +1078,48 @@ async function main() {
|
|
|
1050
1078
|
await server.run();
|
|
1051
1079
|
}
|
|
1052
1080
|
catch (error) {
|
|
1053
|
-
console.error(
|
|
1054
|
-
console.error(
|
|
1055
|
-
name: error instanceof Error ? error.name :
|
|
1081
|
+
console.error("💥 Fatal error in main():", error);
|
|
1082
|
+
console.error("Error details:", {
|
|
1083
|
+
name: error instanceof Error ? error.name : "Unknown",
|
|
1056
1084
|
message: error instanceof Error ? error.message : String(error),
|
|
1057
|
-
stack: error instanceof Error ? error.stack :
|
|
1085
|
+
stack: error instanceof Error ? error.stack : "No stack trace",
|
|
1058
1086
|
});
|
|
1059
1087
|
process.exit(1);
|
|
1060
1088
|
}
|
|
1061
1089
|
}
|
|
1062
1090
|
// Handle process termination
|
|
1063
|
-
process.on(
|
|
1064
|
-
console.error(
|
|
1091
|
+
process.on("SIGINT", async () => {
|
|
1092
|
+
console.error("BC Code Intelligence MCP Server shutting down (SIGINT)...");
|
|
1065
1093
|
process.exit(0);
|
|
1066
1094
|
});
|
|
1067
|
-
process.on(
|
|
1068
|
-
console.error(
|
|
1095
|
+
process.on("SIGTERM", async () => {
|
|
1096
|
+
console.error("BC Code Intelligence MCP Server shutting down (SIGTERM)...");
|
|
1069
1097
|
process.exit(0);
|
|
1070
1098
|
});
|
|
1071
1099
|
// Catch unhandled promise rejections (common cause of silent crashes)
|
|
1072
|
-
process.on(
|
|
1073
|
-
console.error(
|
|
1074
|
-
console.error(
|
|
1075
|
-
console.error(
|
|
1100
|
+
process.on("unhandledRejection", (reason, promise) => {
|
|
1101
|
+
console.error("💥 Unhandled Promise Rejection:");
|
|
1102
|
+
console.error("Reason:", reason);
|
|
1103
|
+
console.error("Promise:", promise);
|
|
1076
1104
|
if (reason instanceof Error) {
|
|
1077
|
-
console.error(
|
|
1105
|
+
console.error("Stack:", reason.stack);
|
|
1078
1106
|
}
|
|
1079
1107
|
process.exit(1);
|
|
1080
1108
|
});
|
|
1081
1109
|
// Catch uncaught exceptions
|
|
1082
|
-
process.on(
|
|
1083
|
-
console.error(
|
|
1084
|
-
console.error(
|
|
1085
|
-
console.error(
|
|
1110
|
+
process.on("uncaughtException", (error) => {
|
|
1111
|
+
console.error("💥 Uncaught Exception:");
|
|
1112
|
+
console.error("Error:", error);
|
|
1113
|
+
console.error("Stack:", error.stack);
|
|
1086
1114
|
process.exit(1);
|
|
1087
1115
|
});
|
|
1088
1116
|
// Run server if this is the main module
|
|
1089
1117
|
// Check both direct execution (index.js) and binary execution (bc-code-intelligence-mcp, bc-code-intel-server)
|
|
1090
|
-
if (process.argv[1]?.endsWith(
|
|
1091
|
-
process.argv[1]?.endsWith(
|
|
1092
|
-
process.argv[1]?.endsWith(
|
|
1118
|
+
if (process.argv[1]?.endsWith("index.js") ||
|
|
1119
|
+
process.argv[1]?.endsWith("bc-code-intelligence-mcp") ||
|
|
1120
|
+
process.argv[1]?.endsWith("bc-code-intel-server")) {
|
|
1093
1121
|
main().catch((error) => {
|
|
1094
|
-
console.error(
|
|
1122
|
+
console.error("Fatal error in BC Code Intelligence MCP Server:", error);
|
|
1095
1123
|
process.exit(1);
|
|
1096
1124
|
});
|
|
1097
1125
|
}
|