@identikey/coding-mcp 2.0.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 (93) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +134 -0
  3. package/build/common/apiClient.d.ts +14 -0
  4. package/build/common/apiClient.d.ts.map +1 -0
  5. package/build/common/apiClient.js +68 -0
  6. package/build/common/personaClient.d.ts +48 -0
  7. package/build/common/personaClient.d.ts.map +1 -0
  8. package/build/common/personaClient.js +101 -0
  9. package/build/common/promptBuilder.d.ts +10 -0
  10. package/build/common/promptBuilder.d.ts.map +1 -0
  11. package/build/common/promptBuilder.js +14 -0
  12. package/build/common/providerConfig.d.ts +23 -0
  13. package/build/common/providerConfig.d.ts.map +1 -0
  14. package/build/common/providerConfig.js +43 -0
  15. package/build/common/tokenFormatter.d.ts +12 -0
  16. package/build/common/tokenFormatter.d.ts.map +1 -0
  17. package/build/common/tokenFormatter.js +24 -0
  18. package/build/core/CommandDispatcher.d.ts +81 -0
  19. package/build/core/CommandDispatcher.d.ts.map +1 -0
  20. package/build/core/CommandDispatcher.js +242 -0
  21. package/build/core/ToolCommand.d.ts +188 -0
  22. package/build/core/ToolCommand.d.ts.map +1 -0
  23. package/build/core/ToolCommand.js +63 -0
  24. package/build/core/ToolRegistry.d.ts +80 -0
  25. package/build/core/ToolRegistry.d.ts.map +1 -0
  26. package/build/core/ToolRegistry.js +279 -0
  27. package/build/index.d.ts +8 -0
  28. package/build/index.d.ts.map +1 -0
  29. package/build/index.js +329 -0
  30. package/build/infra/eventBus.d.ts +120 -0
  31. package/build/infra/eventBus.d.ts.map +1 -0
  32. package/build/infra/eventBus.js +138 -0
  33. package/build/personas/ada/index.d.ts +15 -0
  34. package/build/personas/ada/index.d.ts.map +1 -0
  35. package/build/personas/ada/index.js +121 -0
  36. package/build/personas/atlas/index.d.ts +13 -0
  37. package/build/personas/atlas/index.d.ts.map +1 -0
  38. package/build/personas/atlas/index.js +65 -0
  39. package/build/personas/charles/index.d.ts +18 -0
  40. package/build/personas/charles/index.d.ts.map +1 -0
  41. package/build/personas/charles/index.js +190 -0
  42. package/build/personas/hermes/index.d.ts +13 -0
  43. package/build/personas/hermes/index.d.ts.map +1 -0
  44. package/build/personas/hermes/index.js +61 -0
  45. package/build/personas/iris/index.d.ts +13 -0
  46. package/build/personas/iris/index.d.ts.map +1 -0
  47. package/build/personas/iris/index.js +61 -0
  48. package/build/personas/router.d.ts +18 -0
  49. package/build/personas/router.d.ts.map +1 -0
  50. package/build/personas/router.js +302 -0
  51. package/build/personas/sentinel/index.d.ts +13 -0
  52. package/build/personas/sentinel/index.d.ts.map +1 -0
  53. package/build/personas/sentinel/index.js +62 -0
  54. package/build/personas/types.d.ts +91 -0
  55. package/build/personas/types.d.ts.map +1 -0
  56. package/build/personas/types.js +60 -0
  57. package/build/personas/xavier/index.d.ts +14 -0
  58. package/build/personas/xavier/index.d.ts.map +1 -0
  59. package/build/personas/xavier/index.js +80 -0
  60. package/build/prompts/architectPrompts.d.ts +5 -0
  61. package/build/prompts/architectPrompts.d.ts.map +1 -0
  62. package/build/prompts/architectPrompts.js +58 -0
  63. package/build/prompts/codeadvicePrompts.d.ts +5 -0
  64. package/build/prompts/codeadvicePrompts.d.ts.map +1 -0
  65. package/build/prompts/codeadvicePrompts.js +13 -0
  66. package/build/prompts/researcherPrompts.d.ts +2 -0
  67. package/build/prompts/researcherPrompts.d.ts.map +1 -0
  68. package/build/prompts/researcherPrompts.js +39 -0
  69. package/build/tools/architect.d.ts +32 -0
  70. package/build/tools/architect.d.ts.map +1 -0
  71. package/build/tools/architect.js +75 -0
  72. package/build/tools/ask.d.ts +39 -0
  73. package/build/tools/ask.d.ts.map +1 -0
  74. package/build/tools/ask.js +139 -0
  75. package/build/tools/codeReview.d.ts +22 -0
  76. package/build/tools/codeReview.d.ts.map +1 -0
  77. package/build/tools/codeReview.js +35 -0
  78. package/build/tools/codeadvice.d.ts +29 -0
  79. package/build/tools/codeadvice.d.ts.map +1 -0
  80. package/build/tools/codeadvice.js +56 -0
  81. package/build/tools/discover.d.ts +24 -0
  82. package/build/tools/discover.d.ts.map +1 -0
  83. package/build/tools/discover.js +220 -0
  84. package/build/tools/persona.d.ts +48 -0
  85. package/build/tools/persona.d.ts.map +1 -0
  86. package/build/tools/persona.js +108 -0
  87. package/build/tools/researcher.d.ts +61 -0
  88. package/build/tools/researcher.d.ts.map +1 -0
  89. package/build/tools/researcher.js +346 -0
  90. package/build/tools/screenshot.d.ts +28 -0
  91. package/build/tools/screenshot.d.ts.map +1 -0
  92. package/build/tools/screenshot.js +46 -0
  93. package/package.json +56 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 kleneway
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,134 @@
1
+ # 🤖 Cursor Tools MCP Server
2
+
3
+ An MCP (Model Context Protocol) server providing powerful tools with expert personas for intelligent assistance:
4
+
5
+ ## Core Tools
6
+ - **Ask**: Natural language queries automatically routed to the best expert
7
+ - **Discover**: Explore available expert personas and their specialties
8
+ - **Persona**: Direct access to specific expert personas
9
+ - **Screenshot**: Capture screenshots from URLs
10
+ - **Architect**: Comprehensive architectural code reviews
11
+ - **Code Review**: Git diff analysis and improvement suggestions
12
+
13
+ ## ✨ Features
14
+
15
+ ### 🎨 Code Architect
16
+
17
+ Call advanced reasoning LLMs to generate plans and instructions for coding agents.
18
+
19
+ ### 📸 Screenshot Buddy
20
+
21
+ Take UI design screenshots and use them with the composer agent.
22
+
23
+ ### 🔍 Code Review
24
+
25
+ Use git diffs to trigger code reviews.
26
+
27
+ ### 🎭 Persona System
28
+
29
+ Transform AI responses with distinct personalities:
30
+ - **Charles**: Distinguished British architect with dry wit
31
+ - **Ada**: Pragmatic performance engineer, metrics-focused
32
+
33
+ ### 📊 Code Advice
34
+
35
+ Get focused guidance on specific coding problems.
36
+
37
+ ### 🔬 Researcher
38
+
39
+ Deep-dive analysis for complex technical questions.
40
+
41
+ ## 🚀 Getting Started
42
+
43
+ ### 1. Environment Setup
44
+
45
+ First, you'll need to set up your environment variables. Create a file at `src/env/keys.ts`:
46
+
47
+ ```typescript
48
+ export const OPENAI_API_KEY = "your_key_here";
49
+ // Add any other keys you need
50
+ ```
51
+
52
+ > ⚠️ **Security Note**: Storing API keys directly in source code is not recommended for production environments. This is only for local development and learning purposes. You can set the env var inline in the Cursor MCP interface as well.
53
+
54
+ ### 2. Installation
55
+
56
+ ```bash
57
+ npm install
58
+ # or
59
+ yarn install
60
+ ```
61
+
62
+ ### 3. Build the Server
63
+
64
+ ```bash
65
+ npm run build
66
+ ```
67
+
68
+ ### 4. Adding to Cursor
69
+
70
+ This project is designed to be used as an MCP server in Cursor. Here's how to set it up:
71
+
72
+ 1. Open Cursor
73
+ 2. Go to `Cursor Settings > Features > MCP`
74
+ 3. Click `+ Add New MCP Server`
75
+ 4. Fill out the form:
76
+ - **Name**: AI Development Assistant
77
+ - **Type**: stdio
78
+ - **Command**: `node /path/to/your/project/dist/index.js`
79
+
80
+ > 📘 **Pro Tip**: You might need to use the full path to your project's built index.js file.
81
+
82
+ After adding the server, you should see your tools listed under "Available Tools". If not, try clicking the refresh button in the top right corner of the MCP server section.
83
+
84
+ For more details about MCP setup, check out the [Cursor MCP Documentation](https://docs.cursor.com/advanced/model-context-protocol).
85
+
86
+ ## 🛠️ Using the Tools
87
+
88
+ Once configured, you can use these tools directly in Cursor's Composer. The AI will automatically suggest using relevant tools, or you can explicitly request them by name or description.
89
+
90
+ For example, try typing in Composer:
91
+
92
+ - "Review this code for best practices"
93
+ - "Help me architect a new feature"
94
+ - "Analyze this UI screenshot"
95
+
96
+ The agent will ask for your approval before making any tool calls.
97
+
98
+ > 📘 **Pro Tip**: You can update your .cursorrules file with instructions on how to use the tools for certain scenarios, and the agent will use the tools automatically.
99
+
100
+ ## 📁 Project Structure
101
+
102
+ ```
103
+ src/
104
+ ├── tools/
105
+ │ ├── architect.ts # Code structure generator
106
+ │ ├── screenshot.ts # Screenshot analysis tool
107
+ │ └── codeReview.ts # Code review tool
108
+ ├── env/
109
+ │ └── keys.ts # Environment configuration (add your API keys here!)
110
+ └── index.ts # Main entry point
111
+ ```
112
+
113
+ ## 🤝 Contributing
114
+
115
+ Contributions welcome! Please feel free to submit a Pull Request.
116
+
117
+ ## 📝 License
118
+
119
+ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
120
+
121
+ ## 🐛 Issues & Support
122
+
123
+ Found a bug or need help? Open an issue with:
124
+
125
+ 1. What you were trying to do
126
+ 2. What happened instead
127
+ 3. Steps to reproduce
128
+ 4. Your environment details
129
+
130
+ ---
131
+
132
+ I'll be honest though, this is a tutorial demo, and not a production-ready tool so I likely won't be fixing issues. But feel free to fork it and make it your own!
133
+
134
+ Made with ❤️ by developers, for developers
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Generic AI provider API client utilities
3
+ */
4
+ import { type AIProvider, type ReasoningEffort } from "./providerConfig.js";
5
+ export interface AICallConfig {
6
+ systemPrompt: string;
7
+ task: string;
8
+ code: string;
9
+ analysisType: "comprehensive" | "advice" | "research" | "review";
10
+ reasoningEffort: ReasoningEffort;
11
+ provider: AIProvider;
12
+ }
13
+ export declare function callAIProvider(config: AICallConfig): Promise<string>;
14
+ //# sourceMappingURL=apiClient.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"apiClient.d.ts","sourceRoot":"","sources":["../../src/common/apiClient.ts"],"names":[],"mappings":"AAAA;;GAEG;AAMH,OAAO,EAIL,KAAK,UAAU,EACf,KAAK,eAAe,EACrB,MAAM,qBAAqB,CAAC;AAI7B,MAAM,WAAW,YAAY;IAC3B,YAAY,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,eAAe,GAAG,QAAQ,GAAG,UAAU,GAAG,QAAQ,CAAC;IACjE,eAAe,EAAE,eAAe,CAAC;IACjC,QAAQ,EAAE,UAAU,CAAC;CACtB;AAoDD,wBAAsB,cAAc,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC,CAe1E"}
@@ -0,0 +1,68 @@
1
+ /**
2
+ * Generic AI provider API client utilities
3
+ */
4
+ import OpenAI from "openai";
5
+ import { xai } from "@ai-sdk/xai";
6
+ import { generateText } from "ai";
7
+ import { OPENAI_API_KEY, validateProvider } from "./providerConfig.js";
8
+ import { formatTokenInfo } from "./tokenFormatter.js";
9
+ import { buildUserPrompt } from "./promptBuilder.js";
10
+ async function callXaiProvider(config) {
11
+ const userPrompt = buildUserPrompt({
12
+ task: config.task,
13
+ code: config.code,
14
+ analysisType: config.analysisType,
15
+ });
16
+ const result = await generateText({
17
+ model: xai("grok-4"),
18
+ messages: [
19
+ { role: "system", content: config.systemPrompt },
20
+ { role: "user", content: userPrompt },
21
+ ],
22
+ // Note: xAI doesn't support reasoningEffort parameter
23
+ });
24
+ const tokenInfo = formatTokenInfo("xai", result.usage, config.reasoningEffort);
25
+ return result.text + tokenInfo;
26
+ }
27
+ async function callOpenAIProvider(config) {
28
+ const openai = new OpenAI({
29
+ apiKey: OPENAI_API_KEY,
30
+ });
31
+ const userPrompt = buildUserPrompt({
32
+ task: config.task,
33
+ code: config.code,
34
+ analysisType: config.analysisType,
35
+ });
36
+ const response = await openai.chat.completions.create({
37
+ model: "gpt-5",
38
+ messages: [
39
+ { role: "system", content: config.systemPrompt },
40
+ { role: "user", content: userPrompt },
41
+ ],
42
+ reasoning_effort: config.reasoningEffort, // GPT-5 supports this
43
+ });
44
+ const assistantMessage = response.choices?.[0]?.message?.content ?? "No response from model.";
45
+ const usage = {
46
+ totalTokens: response.usage?.total_tokens,
47
+ reasoning_tokens: response.usage?.reasoning_tokens,
48
+ };
49
+ const tokenInfo = formatTokenInfo("openai", usage, config.reasoningEffort);
50
+ return assistantMessage + tokenInfo;
51
+ }
52
+ export async function callAIProvider(config) {
53
+ validateProvider(config.provider);
54
+ if (config.provider === "xai") {
55
+ // xAI doesn't support reasoning_effort, so create config without it
56
+ const xaiConfig = {
57
+ ...config,
58
+ reasoningEffort: undefined // Remove for xAI
59
+ };
60
+ return callXaiProvider(xaiConfig);
61
+ }
62
+ else if (config.provider === "openai") {
63
+ return callOpenAIProvider(config);
64
+ }
65
+ else {
66
+ throw new Error(`Unsupported provider: ${config.provider}`);
67
+ }
68
+ }
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Persona-aware AI client that enhances API calls with personality layers
3
+ */
4
+ import { type AIProvider, type ReasoningEffort } from "./providerConfig.js";
5
+ export interface PersonaCallConfig {
6
+ /** System prompt to use as base */
7
+ systemPrompt: string;
8
+ /** User's task or question */
9
+ task: string;
10
+ /** Code or context to analyze */
11
+ code: string;
12
+ /** Type of analysis being performed */
13
+ analysisType: "comprehensive" | "advice" | "research" | "review";
14
+ /** Reasoning effort level */
15
+ reasoningEffort: ReasoningEffort;
16
+ /**
17
+ * AI provider override (generally avoid passing; provider is auto-selected
18
+ * based on persona traits, analysis type, and reasoning effort)
19
+ */
20
+ providerOverride?: AIProvider;
21
+ /** Persona ID to use */
22
+ personaId: string;
23
+ /** Conversation context if available */
24
+ conversationContext?: string[];
25
+ /** Response tone control */
26
+ toneStyle?: "concise" | "detailed" | "humorous" | "straight";
27
+ /** Output format preference */
28
+ outputFormat?: "tldr" | "detailed" | "dual";
29
+ /** Target audience level */
30
+ audienceLevel?: "beginner" | "intermediate" | "expert" | "auto";
31
+ /** Include visual diagrams */
32
+ includeDiagrams?: boolean;
33
+ /** User constraints for empathy */
34
+ userConstraints?: string;
35
+ }
36
+ /**
37
+ * Call AI provider with optional persona enhancement
38
+ */
39
+ export declare function callAIWithPersona(config: PersonaCallConfig): Promise<string>;
40
+ /**
41
+ * Helper to list available personas
42
+ */
43
+ export declare function getAvailablePersonas(): Array<{
44
+ id: string;
45
+ name: string;
46
+ description: string;
47
+ }>;
48
+ //# sourceMappingURL=personaClient.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"personaClient.d.ts","sourceRoot":"","sources":["../../src/common/personaClient.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EAGL,KAAK,UAAU,EACf,KAAK,eAAe,EACrB,MAAM,qBAAqB,CAAC;AAG7B,MAAM,WAAW,iBAAiB;IAChC,mCAAmC;IACnC,YAAY,EAAE,MAAM,CAAC;IAErB,8BAA8B;IAC9B,IAAI,EAAE,MAAM,CAAC;IAEb,iCAAiC;IACjC,IAAI,EAAE,MAAM,CAAC;IAEb,uCAAuC;IACvC,YAAY,EAAE,eAAe,GAAG,QAAQ,GAAG,UAAU,GAAG,QAAQ,CAAC;IAEjE,6BAA6B;IAC7B,eAAe,EAAE,eAAe,CAAC;IAEjC;;;OAGG;IACH,gBAAgB,CAAC,EAAE,UAAU,CAAC;IAE9B,wBAAwB;IACxB,SAAS,EAAE,MAAM,CAAC;IAElB,wCAAwC;IACxC,mBAAmB,CAAC,EAAE,MAAM,EAAE,CAAC;IAE/B,4BAA4B;IAC5B,SAAS,CAAC,EAAE,SAAS,GAAG,UAAU,GAAG,UAAU,GAAG,UAAU,CAAC;IAE7D,+BAA+B;IAC/B,YAAY,CAAC,EAAE,MAAM,GAAG,UAAU,GAAG,MAAM,CAAC;IAE5C,4BAA4B;IAC5B,aAAa,CAAC,EAAE,UAAU,GAAG,cAAc,GAAG,QAAQ,GAAG,MAAM,CAAC;IAEhE,8BAA8B;IAC9B,eAAe,CAAC,EAAE,OAAO,CAAC;IAE1B,mCAAmC;IACnC,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED;;GAEG;AACH,wBAAsB,iBAAiB,CACrC,MAAM,EAAE,iBAAiB,GACxB,OAAO,CAAC,MAAM,CAAC,CAsGjB;AAED;;GAEG;AACH,wBAAgB,oBAAoB,IAAI,KAAK,CAAC;IAC5C,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;CACrB,CAAC,CAMD"}
@@ -0,0 +1,101 @@
1
+ /**
2
+ * Persona-aware AI client that enhances API calls with personality layers
3
+ */
4
+ import { callAIProvider } from "./apiClient.js";
5
+ import { chooseProvider, getDefaultProvider, } from "./providerConfig.js";
6
+ import { PersonaRegistry } from "../personas/types.js";
7
+ /**
8
+ * Call AI provider with optional persona enhancement
9
+ */
10
+ export async function callAIWithPersona(config) {
11
+ const { systemPrompt, task, code, analysisType, reasoningEffort, personaId, conversationContext, } = config;
12
+ let enhancedSystemPrompt = systemPrompt;
13
+ let enhancedTask = task;
14
+ let response;
15
+ let selectedProvider = getDefaultProvider();
16
+ let effectiveReasoningEffort = reasoningEffort;
17
+ // If persona is specified, apply persona enhancements
18
+ if (personaId) {
19
+ const persona = PersonaRegistry.get(personaId);
20
+ if (!persona) {
21
+ throw new Error(`Persona '${personaId}' not found in registry`);
22
+ }
23
+ // Auto-select provider with persona preference and optional override
24
+ selectedProvider = chooseProvider({
25
+ analysisType,
26
+ reasoningEffort: effectiveReasoningEffort,
27
+ personaPreferredProvider: config.providerOverride
28
+ ? undefined
29
+ : persona.traits.preferredProvider,
30
+ textHint: task,
31
+ });
32
+ if (config.providerOverride) {
33
+ selectedProvider = config.providerOverride;
34
+ }
35
+ // Use persona's preferred reasoning effort if available
36
+ if (persona.traits.providerPreferences?.reasoning &&
37
+ selectedProvider === "openai") {
38
+ effectiveReasoningEffort = persona.traits.providerPreferences.reasoning;
39
+ }
40
+ // Build persona context
41
+ const context = {
42
+ task,
43
+ analysisType,
44
+ reasoningEffort: effectiveReasoningEffort,
45
+ conversationContext,
46
+ toneStyle: config.toneStyle,
47
+ outputFormat: config.outputFormat,
48
+ audienceLevel: config.audienceLevel,
49
+ includeDiagrams: config.includeDiagrams,
50
+ userConstraints: config.userConstraints,
51
+ providerOverride: config.providerOverride,
52
+ };
53
+ // Enhance prompts with persona
54
+ enhancedSystemPrompt = persona.enhanceSystemPrompt(systemPrompt, context);
55
+ enhancedTask = persona.enhanceUserPrompt(task, context);
56
+ // Call AI provider with enhanced prompts
57
+ response = await callAIProvider({
58
+ systemPrompt: enhancedSystemPrompt,
59
+ task: enhancedTask,
60
+ code,
61
+ analysisType,
62
+ reasoningEffort: effectiveReasoningEffort,
63
+ provider: selectedProvider,
64
+ });
65
+ // Post-process response if persona has custom processing
66
+ if (persona.processResponse) {
67
+ response = persona.processResponse(response, context);
68
+ }
69
+ // Format output according to persona preferences
70
+ if (persona.formatOutput) {
71
+ response = persona.formatOutput(response, context);
72
+ }
73
+ }
74
+ else {
75
+ // No persona specified, auto-select provider
76
+ selectedProvider = chooseProvider({
77
+ analysisType,
78
+ reasoningEffort: effectiveReasoningEffort,
79
+ textHint: task,
80
+ });
81
+ response = await callAIProvider({
82
+ systemPrompt: enhancedSystemPrompt,
83
+ task: enhancedTask,
84
+ code,
85
+ analysisType,
86
+ reasoningEffort: effectiveReasoningEffort,
87
+ provider: selectedProvider,
88
+ });
89
+ }
90
+ return response;
91
+ }
92
+ /**
93
+ * Helper to list available personas
94
+ */
95
+ export function getAvailablePersonas() {
96
+ return PersonaRegistry.list().map((p) => ({
97
+ id: p.id,
98
+ name: p.name,
99
+ description: p.description,
100
+ }));
101
+ }
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Prompt construction utilities
3
+ */
4
+ export interface PromptConfig {
5
+ task: string;
6
+ code: string;
7
+ analysisType: "comprehensive" | "advice" | "research" | "review";
8
+ }
9
+ export declare function buildUserPrompt(config: PromptConfig): string;
10
+ //# sourceMappingURL=promptBuilder.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"promptBuilder.d.ts","sourceRoot":"","sources":["../../src/common/promptBuilder.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,eAAe,GAAG,QAAQ,GAAG,UAAU,GAAG,QAAQ,CAAC;CAClE;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,YAAY,GAAG,MAAM,CAY5D"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Prompt construction utilities
3
+ */
4
+ export function buildUserPrompt(config) {
5
+ const { task, code, analysisType } = config;
6
+ const analysisRequest = analysisType === "comprehensive"
7
+ ? "Please provide a comprehensive architectural analysis."
8
+ : analysisType === "research"
9
+ ? "Please synthesize the research findings with proper source attribution."
10
+ : analysisType === "review"
11
+ ? "Please provide a thorough code review with constructive feedback."
12
+ : "Please provide quick, actionable advice.";
13
+ return `Task: ${task}\n\nCode:\n${code}\n\n${analysisRequest}`;
14
+ }
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Provider configuration and validation utilities
3
+ */
4
+ export declare const OPENAI_API_KEY: string | undefined;
5
+ export declare const XAI_API_KEY: string | undefined;
6
+ export declare const AI_PROVIDER: string;
7
+ export type AIProvider = "xai" | "openai";
8
+ export type ReasoningEffort = "low" | "medium" | "high";
9
+ export declare function validateProvider(provider: AIProvider): void;
10
+ export declare function getDefaultProvider(): AIProvider;
11
+ /**
12
+ * Heuristic provider selector. Prefers persona's choice; otherwise:
13
+ * - "openai" for comprehensive or high-effort reasoning tasks
14
+ * - "xai" for quick/advice-style prompts
15
+ * - falls back to env default
16
+ */
17
+ export declare function chooseProvider(params: {
18
+ analysisType: "comprehensive" | "advice" | "research" | "review";
19
+ reasoningEffort?: ReasoningEffort;
20
+ personaPreferredProvider?: AIProvider;
21
+ textHint?: string;
22
+ }): AIProvider;
23
+ //# sourceMappingURL=providerConfig.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"providerConfig.d.ts","sourceRoot":"","sources":["../../src/common/providerConfig.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,eAAO,MAAM,cAAc,oBAA6B,CAAC;AACzD,eAAO,MAAM,WAAW,oBAA0B,CAAC;AACnD,eAAO,MAAM,WAAW,QAAmC,CAAC;AAE5D,MAAM,MAAM,UAAU,GAAG,KAAK,GAAG,QAAQ,CAAC;AAC1C,MAAM,MAAM,eAAe,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;AAExD,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,UAAU,GAAG,IAAI,CAW3D;AAED,wBAAgB,kBAAkB,IAAI,UAAU,CAE/C;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE;IACrC,YAAY,EAAE,eAAe,GAAG,QAAQ,GAAG,UAAU,GAAG,QAAQ,CAAC;IACjE,eAAe,CAAC,EAAE,eAAe,CAAC;IAClC,wBAAwB,CAAC,EAAE,UAAU,CAAC;IACtC,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,GAAG,UAAU,CA0Bb"}
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Provider configuration and validation utilities
3
+ */
4
+ export const OPENAI_API_KEY = process.env.OPENAI_API_KEY;
5
+ export const XAI_API_KEY = process.env.XAI_API_KEY;
6
+ export const AI_PROVIDER = process.env.AI_PROVIDER || "xai";
7
+ export function validateProvider(provider) {
8
+ if (provider === "xai" && !XAI_API_KEY) {
9
+ throw new Error("XAI_API_KEY environment variable is required for xAI provider");
10
+ }
11
+ if (provider === "openai" && !OPENAI_API_KEY) {
12
+ throw new Error("OPENAI_API_KEY environment variable is required for OpenAI provider");
13
+ }
14
+ }
15
+ export function getDefaultProvider() {
16
+ return AI_PROVIDER;
17
+ }
18
+ /**
19
+ * Heuristic provider selector. Prefers persona's choice; otherwise:
20
+ * - "openai" for comprehensive or high-effort reasoning tasks
21
+ * - "xai" for quick/advice-style prompts
22
+ * - falls back to env default
23
+ */
24
+ export function chooseProvider(params) {
25
+ const { analysisType, reasoningEffort, personaPreferredProvider, textHint } = params;
26
+ if (personaPreferredProvider)
27
+ return personaPreferredProvider;
28
+ const hint = (textHint || "").toLowerCase();
29
+ const strongReasoning = analysisType === "comprehensive" ||
30
+ analysisType === "review" ||
31
+ analysisType === "research" ||
32
+ reasoningEffort === "high" ||
33
+ /(architecture|design|spec|deep|rigor|formal)/.test(hint);
34
+ if (strongReasoning)
35
+ return "openai";
36
+ const quick = /(quick|concise|tl;dr|fast|simple|bug|fix|snippet)/.test(hint) ||
37
+ analysisType === "advice" ||
38
+ reasoningEffort === "low" ||
39
+ reasoningEffort === "medium";
40
+ if (quick)
41
+ return "xai";
42
+ return getDefaultProvider();
43
+ }
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Token usage formatting utilities
3
+ */
4
+ import type { AIProvider, ReasoningEffort } from "./providerConfig.js";
5
+ export interface TokenUsage {
6
+ totalTokens?: number;
7
+ reasoning_tokens?: number;
8
+ }
9
+ export declare function formatXaiTokenInfo(usage: TokenUsage | undefined, reasoningEffort: ReasoningEffort): string;
10
+ export declare function formatOpenAITokenInfo(usage: TokenUsage | undefined, reasoningEffort: ReasoningEffort): string;
11
+ export declare function formatTokenInfo(provider: AIProvider, usage: TokenUsage | undefined, reasoningEffort: ReasoningEffort): string;
12
+ //# sourceMappingURL=tokenFormatter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tokenFormatter.d.ts","sourceRoot":"","sources":["../../src/common/tokenFormatter.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAEvE,MAAM,WAAW,UAAU;IACzB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,UAAU,GAAG,SAAS,EAC7B,eAAe,EAAE,eAAe,GAC/B,MAAM,CAQR;AAED,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,UAAU,GAAG,SAAS,EAC7B,eAAe,EAAE,eAAe,GAC/B,MAAM,CAUR;AAED,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,UAAU,EACpB,KAAK,EAAE,UAAU,GAAG,SAAS,EAC7B,eAAe,EAAE,eAAe,GAC/B,MAAM,CAIR"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Token usage formatting utilities
3
+ */
4
+ export function formatXaiTokenInfo(usage, reasoningEffort) {
5
+ const baseInfo = `Provider: xAI Grok-4 | Reasoning effort: ${reasoningEffort}`;
6
+ if (usage?.totalTokens) {
7
+ return `\n\n---\n*Tokens used: ${usage.totalTokens} | ${baseInfo}*`;
8
+ }
9
+ return `\n\n---\n*${baseInfo}*`;
10
+ }
11
+ export function formatOpenAITokenInfo(usage, reasoningEffort) {
12
+ const baseInfo = `Provider: OpenAI GPT-5 | Reasoning effort: ${reasoningEffort}`;
13
+ const reasoningTokens = usage?.reasoning_tokens ?? 0;
14
+ const totalTokens = usage?.totalTokens ?? 0;
15
+ if (reasoningTokens > 0) {
16
+ return `\n\n---\n*Reasoning tokens used: ${reasoningTokens} | Total tokens: ${totalTokens} | ${baseInfo}*`;
17
+ }
18
+ return `\n\n---\n*${baseInfo}*`;
19
+ }
20
+ export function formatTokenInfo(provider, usage, reasoningEffort) {
21
+ return provider === "xai"
22
+ ? formatXaiTokenInfo(usage, reasoningEffort)
23
+ : formatOpenAITokenInfo(usage, reasoningEffort);
24
+ }
@@ -0,0 +1,81 @@
1
+ /**
2
+ * Command Dispatcher - Replaces the monolithic switch statement
3
+ * Routes MCP requests to appropriate tool commands with structured error handling
4
+ */
5
+ import { CallToolRequest } from "@modelcontextprotocol/sdk/types.js";
6
+ import { MCPToolResponse } from './ToolCommand.js';
7
+ import { ToolRegistry } from './ToolRegistry.js';
8
+ import { type EventBus } from '../infra/eventBus.js';
9
+ export interface DispatcherConfig {
10
+ /** Default execution timeout in milliseconds */
11
+ defaultTimeout?: number;
12
+ /** Enable execution tracing */
13
+ enableTracing?: boolean;
14
+ /** Maximum concurrent executions */
15
+ maxConcurrentExecutions?: number;
16
+ }
17
+ export declare class CommandDispatcher {
18
+ private readonly registry;
19
+ private readonly eventBus;
20
+ private readonly config;
21
+ private activeExecutions;
22
+ private executionCounter;
23
+ constructor(registry: ToolRegistry, eventBusInstance?: EventBus, config?: DispatcherConfig);
24
+ /**
25
+ * Dispatch an MCP tool request to the appropriate command
26
+ */
27
+ dispatch(request: CallToolRequest): Promise<MCPToolResponse>;
28
+ /**
29
+ * Execute a tool with timeout and validation
30
+ */
31
+ private executeWithTimeout;
32
+ /**
33
+ * Execute a promise with timeout
34
+ */
35
+ private withTimeout;
36
+ /**
37
+ * Normalize errors to ToolError instances
38
+ */
39
+ private normalizeError;
40
+ /**
41
+ * Format successful result as MCP response
42
+ */
43
+ private formatMCPResponse;
44
+ /**
45
+ * Format error as MCP response
46
+ */
47
+ private formatErrorResponse;
48
+ /**
49
+ * Check if result is already in MCP response format
50
+ */
51
+ private isMCPResponse;
52
+ /**
53
+ * Generate unique request ID
54
+ */
55
+ private generateRequestId;
56
+ /**
57
+ * Get active executions for monitoring
58
+ */
59
+ getActiveExecutions(): ReadonlyMap<string, {
60
+ toolName: string;
61
+ startTime: number;
62
+ }>;
63
+ /**
64
+ * Get dispatcher statistics
65
+ */
66
+ getStats(): {
67
+ activeExecutions: number;
68
+ totalExecutions: number;
69
+ averageExecutionTime: number;
70
+ errorRate: number;
71
+ };
72
+ /**
73
+ * Create dispatcher with default configuration
74
+ */
75
+ static create(registry: ToolRegistry, config?: DispatcherConfig): CommandDispatcher;
76
+ }
77
+ /**
78
+ * Create a simple dispatch function for MCP server integration
79
+ */
80
+ export declare function createDispatchHandler(registry: ToolRegistry, config?: DispatcherConfig): (request: CallToolRequest) => Promise<MCPToolResponse>;
81
+ //# sourceMappingURL=CommandDispatcher.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CommandDispatcher.d.ts","sourceRoot":"","sources":["../../src/core/CommandDispatcher.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,eAAe,EAAE,MAAM,oCAAoC,CAAC;AACrE,OAAO,EASL,eAAe,EAChB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAY,KAAK,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAG/D,MAAM,WAAW,gBAAgB;IAC/B,gDAAgD;IAChD,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,+BAA+B;IAC/B,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,oCAAoC;IACpC,uBAAuB,CAAC,EAAE,MAAM,CAAC;CAClC;AAED,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAe;IACxC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAW;IACpC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA6B;IACpD,OAAO,CAAC,gBAAgB,CAA8D;IACtF,OAAO,CAAC,gBAAgB,CAAK;gBAG3B,QAAQ,EAAE,YAAY,EACtB,gBAAgB,CAAC,EAAE,QAAQ,EAC3B,MAAM,GAAE,gBAAqB;IAW/B;;OAEG;IACG,QAAQ,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,eAAe,CAAC;IAiFlE;;OAEG;YACW,kBAAkB;IAiEhC;;OAEG;YACW,WAAW;IAczB;;OAEG;IACH,OAAO,CAAC,cAAc;IAYtB;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAezB;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAa3B;;OAEG;IACH,OAAO,CAAC,aAAa;IASrB;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAIzB;;OAEG;IACH,mBAAmB,IAAI,WAAW,CAAC,MAAM,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC;IAInF;;OAEG;IACH,QAAQ,IAAI;QACV,gBAAgB,EAAE,MAAM,CAAC;QACzB,eAAe,EAAE,MAAM,CAAC;QACxB,oBAAoB,EAAE,MAAM,CAAC;QAC7B,SAAS,EAAE,MAAM,CAAC;KACnB;IAWD;;OAEG;IACH,MAAM,CAAC,MAAM,CAAC,QAAQ,EAAE,YAAY,EAAE,MAAM,CAAC,EAAE,gBAAgB,GAAG,iBAAiB;CAGpF;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,YAAY,EACtB,MAAM,CAAC,EAAE,gBAAgB,GACxB,CAAC,OAAO,EAAE,eAAe,KAAK,OAAO,CAAC,eAAe,CAAC,CAGxD"}