@su-record/vibe 0.1.0

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 (88) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +448 -0
  3. package/agents/backend-python-expert.md +453 -0
  4. package/agents/database-postgres-expert.md +538 -0
  5. package/agents/frontend-flutter-expert.md +487 -0
  6. package/agents/frontend-react-expert.md +424 -0
  7. package/agents/quality-reviewer.md +542 -0
  8. package/agents/specification-agent.md +505 -0
  9. package/bin/sutory +332 -0
  10. package/bin/vibe +338 -0
  11. package/mcp/dist/__tests__/complexity.test.js +126 -0
  12. package/mcp/dist/__tests__/memory.test.js +120 -0
  13. package/mcp/dist/__tests__/python-dart-complexity.test.js +146 -0
  14. package/mcp/dist/index.js +230 -0
  15. package/mcp/dist/lib/ContextCompressor.js +305 -0
  16. package/mcp/dist/lib/MemoryManager.js +334 -0
  17. package/mcp/dist/lib/ProjectCache.js +126 -0
  18. package/mcp/dist/lib/PythonParser.js +241 -0
  19. package/mcp/dist/tools/browser/browserPool.js +76 -0
  20. package/mcp/dist/tools/browser/browserUtils.js +135 -0
  21. package/mcp/dist/tools/browser/inspectNetworkRequests.js +140 -0
  22. package/mcp/dist/tools/browser/monitorConsoleLogs.js +97 -0
  23. package/mcp/dist/tools/convention/analyzeComplexity.js +248 -0
  24. package/mcp/dist/tools/convention/applyQualityRules.js +102 -0
  25. package/mcp/dist/tools/convention/checkCouplingCohesion.js +233 -0
  26. package/mcp/dist/tools/convention/complexityMetrics.js +133 -0
  27. package/mcp/dist/tools/convention/dartComplexity.js +117 -0
  28. package/mcp/dist/tools/convention/getCodingGuide.js +64 -0
  29. package/mcp/dist/tools/convention/languageDetector.js +50 -0
  30. package/mcp/dist/tools/convention/pythonComplexity.js +109 -0
  31. package/mcp/dist/tools/convention/suggestImprovements.js +257 -0
  32. package/mcp/dist/tools/convention/validateCodeQuality.js +177 -0
  33. package/mcp/dist/tools/memory/autoSaveContext.js +79 -0
  34. package/mcp/dist/tools/memory/database.js +123 -0
  35. package/mcp/dist/tools/memory/deleteMemory.js +39 -0
  36. package/mcp/dist/tools/memory/listMemories.js +38 -0
  37. package/mcp/dist/tools/memory/memoryConfig.js +27 -0
  38. package/mcp/dist/tools/memory/memorySQLite.js +138 -0
  39. package/mcp/dist/tools/memory/memoryUtils.js +34 -0
  40. package/mcp/dist/tools/memory/migrate.js +113 -0
  41. package/mcp/dist/tools/memory/prioritizeMemory.js +109 -0
  42. package/mcp/dist/tools/memory/recallMemory.js +40 -0
  43. package/mcp/dist/tools/memory/restoreSessionContext.js +69 -0
  44. package/mcp/dist/tools/memory/saveMemory.js +34 -0
  45. package/mcp/dist/tools/memory/searchMemories.js +37 -0
  46. package/mcp/dist/tools/memory/startSession.js +100 -0
  47. package/mcp/dist/tools/memory/updateMemory.js +46 -0
  48. package/mcp/dist/tools/planning/analyzeRequirements.js +166 -0
  49. package/mcp/dist/tools/planning/createUserStories.js +119 -0
  50. package/mcp/dist/tools/planning/featureRoadmap.js +202 -0
  51. package/mcp/dist/tools/planning/generatePrd.js +156 -0
  52. package/mcp/dist/tools/prompt/analyzePrompt.js +145 -0
  53. package/mcp/dist/tools/prompt/enhancePrompt.js +105 -0
  54. package/mcp/dist/tools/semantic/findReferences.js +195 -0
  55. package/mcp/dist/tools/semantic/findSymbol.js +200 -0
  56. package/mcp/dist/tools/thinking/analyzeProblem.js +50 -0
  57. package/mcp/dist/tools/thinking/breakDownProblem.js +140 -0
  58. package/mcp/dist/tools/thinking/createThinkingChain.js +39 -0
  59. package/mcp/dist/tools/thinking/formatAsPlan.js +73 -0
  60. package/mcp/dist/tools/thinking/stepByStepAnalysis.js +58 -0
  61. package/mcp/dist/tools/thinking/thinkAloudProcess.js +75 -0
  62. package/mcp/dist/tools/time/getCurrentTime.js +61 -0
  63. package/mcp/dist/tools/ui/previewUiAscii.js +232 -0
  64. package/mcp/dist/types/tool.js +2 -0
  65. package/mcp/package.json +53 -0
  66. package/package.json +49 -0
  67. package/scripts/install-mcp.js +48 -0
  68. package/scripts/install.sh +70 -0
  69. package/skills/core/communication-guide.md +104 -0
  70. package/skills/core/development-philosophy.md +53 -0
  71. package/skills/core/quick-start.md +121 -0
  72. package/skills/languages/dart-flutter.md +509 -0
  73. package/skills/languages/python-fastapi.md +386 -0
  74. package/skills/languages/typescript-nextjs.md +441 -0
  75. package/skills/languages/typescript-react-native.md +446 -0
  76. package/skills/languages/typescript-react.md +525 -0
  77. package/skills/quality/checklist.md +276 -0
  78. package/skills/quality/testing-strategy.md +437 -0
  79. package/skills/standards/anti-patterns.md +369 -0
  80. package/skills/standards/code-structure.md +291 -0
  81. package/skills/standards/complexity-metrics.md +312 -0
  82. package/skills/standards/naming-conventions.md +198 -0
  83. package/skills/tools/mcp-hi-ai-guide.md +665 -0
  84. package/skills/tools/mcp-workflow.md +51 -0
  85. package/templates/constitution-template.md +193 -0
  86. package/templates/plan-template.md +237 -0
  87. package/templates/spec-template.md +142 -0
  88. package/templates/tasks-template.md +132 -0
@@ -0,0 +1,126 @@
1
+ import { describe, test, expect } from 'vitest';
2
+ import { analyzeComplexity, analyzeComplexityDefinition } from '../tools/convention/analyzeComplexity.js';
3
+ describe('Code Complexity Analysis', () => {
4
+ describe('analyzeComplexity', () => {
5
+ test('should analyze simple function with low complexity', async () => {
6
+ const simpleCode = `
7
+ function add(a, b) {
8
+ return a + b;
9
+ }
10
+ `;
11
+ const result = await analyzeComplexity({ code: simpleCode, metrics: 'all' });
12
+ const parsed = JSON.parse(result.content[0].text.replace('Complexity Analysis:\n', ''));
13
+ expect(parsed.status).toBe('success');
14
+ expect(parsed.results.cyclomaticComplexity).toBeDefined();
15
+ expect(parsed.results.cognitiveComplexity).toBeDefined();
16
+ expect(parsed.results.halsteadMetrics).toBeDefined();
17
+ expect(parsed.results.cyclomaticComplexity.status).toBe('pass');
18
+ });
19
+ test('should detect high cyclomatic complexity', async () => {
20
+ const complexCode = `
21
+ function complexFunction(x) {
22
+ if (x > 0) {
23
+ if (x < 10) {
24
+ for (let i = 0; i < x; i++) {
25
+ if (i % 2 === 0) {
26
+ while (i < 5) {
27
+ if (i === 3) {
28
+ return i;
29
+ }
30
+ i++;
31
+ }
32
+ }
33
+ }
34
+ }
35
+ }
36
+ return x;
37
+ }
38
+ `;
39
+ const result = await analyzeComplexity({ code: complexCode, metrics: 'all' });
40
+ const parsed = JSON.parse(result.content[0].text.replace('Complexity Analysis:\n', ''));
41
+ expect(parsed.results.cyclomaticComplexity.value).toBeGreaterThan(5);
42
+ expect(parsed.issues.length).toBeGreaterThan(0);
43
+ });
44
+ test('should calculate AST-based complexity', async () => {
45
+ const code = `
46
+ function test() {
47
+ if (true) return 1;
48
+ for (let i = 0; i < 10; i++) {
49
+ console.log(i);
50
+ }
51
+ }
52
+ `;
53
+ const result = await analyzeComplexity({ code, metrics: 'cyclomatic' });
54
+ const parsed = JSON.parse(result.content[0].text.replace('Complexity Analysis:\n', ''));
55
+ expect(parsed.results.astCyclomaticComplexity).toBeDefined();
56
+ expect(parsed.results.astCyclomaticComplexity.value).toBeGreaterThan(1);
57
+ });
58
+ test('should calculate cognitive complexity with nesting', async () => {
59
+ const code = `
60
+ function nested() {
61
+ if (a) {
62
+ if (b) {
63
+ if (c) {
64
+ return true;
65
+ }
66
+ }
67
+ }
68
+ }
69
+ `;
70
+ const result = await analyzeComplexity({ code, metrics: 'cognitive' });
71
+ const parsed = JSON.parse(result.content[0].text.replace('Complexity Analysis:\n', ''));
72
+ expect(parsed.results.cognitiveComplexity.value).toBeGreaterThan(0);
73
+ });
74
+ test('should calculate Halstead metrics', async () => {
75
+ const code = `
76
+ function calculate(x, y) {
77
+ const sum = x + y;
78
+ const product = x * y;
79
+ return sum + product;
80
+ }
81
+ `;
82
+ const result = await analyzeComplexity({ code, metrics: 'halstead' });
83
+ const parsed = JSON.parse(result.content[0].text.replace('Complexity Analysis:\n', ''));
84
+ expect(parsed.results.halsteadMetrics).toBeDefined();
85
+ expect(parsed.results.halsteadMetrics.vocabulary).toBeGreaterThan(0);
86
+ expect(parsed.results.halsteadMetrics.difficulty).toBeGreaterThan(0);
87
+ });
88
+ test('should provide recommendations for complex code', async () => {
89
+ const veryComplexCode = `
90
+ function veryComplex(a, b, c, d, e) {
91
+ if (a) {
92
+ if (b) {
93
+ for (let i = 0; i < 10; i++) {
94
+ if (c) {
95
+ while (d) {
96
+ if (e) {
97
+ return true;
98
+ }
99
+ }
100
+ }
101
+ }
102
+ }
103
+ }
104
+ return false;
105
+ }
106
+ `;
107
+ const result = await analyzeComplexity({ code: veryComplexCode, metrics: 'all' });
108
+ const parsed = JSON.parse(result.content[0].text.replace('Complexity Analysis:\n', ''));
109
+ expect(parsed.recommendations).toBeDefined();
110
+ expect(parsed.recommendations.length).toBeGreaterThan(0);
111
+ expect(parsed.overallScore).toBeLessThan(100);
112
+ });
113
+ });
114
+ describe('Tool Definition', () => {
115
+ test('should have correct definition', () => {
116
+ expect(analyzeComplexityDefinition.name).toBe('analyze_complexity');
117
+ expect(analyzeComplexityDefinition.description).toContain('IMPORTANT');
118
+ expect(analyzeComplexityDefinition.inputSchema.required).toContain('code');
119
+ });
120
+ test('should include keyword triggers', () => {
121
+ const desc = analyzeComplexityDefinition.description;
122
+ expect(desc).toContain('복잡도');
123
+ expect(desc).toContain('complexity');
124
+ });
125
+ });
126
+ });
@@ -0,0 +1,120 @@
1
+ import { describe, test, expect, beforeEach, afterEach } from 'vitest';
2
+ import { saveMemory, saveMemoryDefinition } from '../tools/memory/saveMemory.js';
3
+ import { recallMemory } from '../tools/memory/recallMemory.js';
4
+ import { listMemories } from '../tools/memory/listMemories.js';
5
+ import { deleteMemory } from '../tools/memory/deleteMemory.js';
6
+ import { memoryDB } from '../tools/memory/database.js';
7
+ import { clearAllMemories } from '../tools/memory/memorySQLite.js';
8
+ import { promises as fs } from 'fs';
9
+ import path from 'path';
10
+ const TEST_MEMORY_DIR = path.join(process.cwd(), 'memories');
11
+ describe('Memory Management Tools', () => {
12
+ beforeEach(async () => {
13
+ // Ensure fresh database for each test
14
+ try {
15
+ // Close existing connection if any
16
+ memoryDB.close();
17
+ }
18
+ catch (error) {
19
+ // Ignore
20
+ }
21
+ // Clean up test files
22
+ try {
23
+ await fs.rm(TEST_MEMORY_DIR, { recursive: true, force: true });
24
+ }
25
+ catch (error) {
26
+ // Ignore
27
+ }
28
+ // Clear all memories (this will recreate DB if needed)
29
+ try {
30
+ clearAllMemories();
31
+ }
32
+ catch (error) {
33
+ // Database might not exist yet, will be created on first use
34
+ }
35
+ });
36
+ afterEach(async () => {
37
+ // Close database connection
38
+ try {
39
+ memoryDB.close();
40
+ }
41
+ catch (error) {
42
+ // Ignore
43
+ }
44
+ });
45
+ describe('saveMemory', () => {
46
+ test('should save memory successfully', async () => {
47
+ const result = await saveMemory({
48
+ key: 'test-key',
49
+ value: 'test-value',
50
+ category: 'project'
51
+ });
52
+ expect(result.content[0].text).toContain('success');
53
+ expect(result.content[0].text).toContain('test-key');
54
+ });
55
+ test('should create memory database if not exists', async () => {
56
+ await saveMemory({ key: 'test-key', value: 'test-value' });
57
+ // Check if database file exists
58
+ const dbPath = path.join(TEST_MEMORY_DIR, 'memories.db');
59
+ const dbExists = await fs.access(dbPath).then(() => true).catch(() => false);
60
+ expect(dbExists).toBe(true);
61
+ });
62
+ });
63
+ describe('recallMemory', () => {
64
+ test('should recall saved memory', async () => {
65
+ await saveMemory({ key: 'recall-test', value: 'recall-value' });
66
+ const result = await recallMemory({ key: 'recall-test' });
67
+ const parsedResult = JSON.parse(result.content[0].text.replace('Memory recalled:\n', ''));
68
+ expect(parsedResult.value).toBe('recall-value');
69
+ expect(parsedResult.key).toBe('recall-test');
70
+ });
71
+ test('should return not found for non-existent key', async () => {
72
+ const result = await recallMemory({ key: 'non-existent' });
73
+ expect(result.content[0].text).toContain('not found');
74
+ });
75
+ });
76
+ describe('listMemories', () => {
77
+ test('should list all memories', async () => {
78
+ await saveMemory({ key: 'key1', value: 'value1', category: 'project' });
79
+ await saveMemory({ key: 'key2', value: 'value2', category: 'code' });
80
+ const result = await listMemories({ summary: false });
81
+ const parsed = JSON.parse(result.content[0].text.replace('Memory list:\n', ''));
82
+ expect(parsed.memories.length).toBe(2);
83
+ expect(parsed.total).toBe(2);
84
+ });
85
+ test('should filter memories by category', async () => {
86
+ await saveMemory({ key: 'project1', value: 'val1', category: 'project' });
87
+ await saveMemory({ key: 'code1', value: 'val2', category: 'code' });
88
+ const result = await listMemories({ category: 'project', summary: false });
89
+ const parsed = JSON.parse(result.content[0].text.replace('Memory list:\n', ''));
90
+ expect(parsed.total).toBe(1);
91
+ expect(parsed.memories[0].key).toBe('project1');
92
+ });
93
+ test('should return empty array when no memories exist', async () => {
94
+ const result = await listMemories({ summary: false });
95
+ const parsed = JSON.parse(result.content[0].text.replace('Memory list:\n', ''));
96
+ expect(parsed.memories).toEqual([]);
97
+ expect(parsed.total).toBe(0);
98
+ });
99
+ });
100
+ describe('deleteMemory', () => {
101
+ test('should delete existing memory', async () => {
102
+ await saveMemory({ key: 'delete-me', value: 'temporary' });
103
+ const deleteResult = await deleteMemory({ key: 'delete-me' });
104
+ expect(deleteResult.content[0].text).toContain('success');
105
+ const recallResult = await recallMemory({ key: 'delete-me' });
106
+ expect(recallResult.content[0].text).toContain('not found');
107
+ });
108
+ });
109
+ describe('Tool Definition', () => {
110
+ test('should have correct structure', () => {
111
+ expect(saveMemoryDefinition.name).toBe('save_memory');
112
+ expect(saveMemoryDefinition.description).toContain('IMPORTANT');
113
+ expect(saveMemoryDefinition.inputSchema.required).toContain('key');
114
+ });
115
+ test('should include keyword triggers', () => {
116
+ expect(saveMemoryDefinition.description).toContain('기억해');
117
+ expect(saveMemoryDefinition.description).toContain('remember');
118
+ });
119
+ });
120
+ });
@@ -0,0 +1,146 @@
1
+ /**
2
+ * Tests for Python and Dart/Flutter code complexity analysis
3
+ */
4
+ import { describe, it, expect } from 'vitest';
5
+ import { detectLanguage } from '../tools/convention/languageDetector.js';
6
+ import { calculatePythonComplexity, calculatePythonCognitiveComplexity } from '../tools/convention/pythonComplexity.js';
7
+ import { calculateDartComplexity, calculateDartCognitiveComplexity } from '../tools/convention/dartComplexity.js';
8
+ import { analyzeComplexity } from '../tools/convention/analyzeComplexity.js';
9
+ describe('Language Detection', () => {
10
+ it('should detect Python code', () => {
11
+ const pythonCode = `
12
+ def calculate_sum(numbers):
13
+ total = 0
14
+ for num in numbers:
15
+ total += num
16
+ return total
17
+ `;
18
+ expect(detectLanguage(pythonCode)).toBe('python');
19
+ });
20
+ it('should detect Dart/Flutter code', () => {
21
+ const dartCode = `
22
+ class MyWidget extends StatelessWidget {
23
+ @override
24
+ Widget build(BuildContext context) {
25
+ return Container(
26
+ child: Text('Hello'),
27
+ );
28
+ }
29
+ }
30
+ `;
31
+ expect(detectLanguage(dartCode)).toBe('dart');
32
+ });
33
+ it('should detect TypeScript code', () => {
34
+ const tsCode = `
35
+ interface User {
36
+ name: string;
37
+ age: number;
38
+ }
39
+
40
+ function greet(user: User): void {
41
+ console.log(\`Hello, \${user.name}\`);
42
+ }
43
+ `;
44
+ expect(detectLanguage(tsCode)).toBe('typescript');
45
+ });
46
+ });
47
+ describe('Python Complexity Analysis', () => {
48
+ it('should calculate Python cyclomatic complexity', () => {
49
+ const pythonCode = `
50
+ def complex_function(x, y, z):
51
+ if x > 0:
52
+ if y > 0:
53
+ return x + y
54
+ elif y < 0:
55
+ return x - y
56
+ elif z > 0:
57
+ for i in range(10):
58
+ if i % 2 == 0:
59
+ print(i)
60
+ return 0
61
+ `;
62
+ const result = calculatePythonComplexity(pythonCode);
63
+ expect(result.value).toBeGreaterThan(5);
64
+ expect(result.status).toBeDefined();
65
+ });
66
+ it('should calculate Python cognitive complexity', () => {
67
+ const pythonCode = `
68
+ def nested_function(items):
69
+ for item in items:
70
+ if item > 0:
71
+ if item % 2 == 0:
72
+ print("Even positive")
73
+ return items
74
+ `;
75
+ const result = calculatePythonCognitiveComplexity(pythonCode);
76
+ expect(result.value).toBeGreaterThan(0);
77
+ });
78
+ });
79
+ describe('Dart Complexity Analysis', () => {
80
+ it('should calculate Dart cyclomatic complexity', () => {
81
+ const dartCode = `
82
+ Widget buildWidget(bool condition) {
83
+ if (condition) {
84
+ return Text('Yes');
85
+ } else {
86
+ return Text('No');
87
+ }
88
+ }
89
+ `;
90
+ const result = calculateDartComplexity(dartCode);
91
+ expect(result.value).toBeGreaterThan(1);
92
+ });
93
+ it('should calculate Dart cognitive complexity', () => {
94
+ const dartCode = `
95
+ class MyWidget extends StatelessWidget {
96
+ @override
97
+ Widget build(BuildContext context) {
98
+ return condition1
99
+ ? Text('A')
100
+ : condition2
101
+ ? Text('B')
102
+ : Text('C');
103
+ }
104
+ }
105
+ `;
106
+ const result = calculateDartCognitiveComplexity(dartCode);
107
+ expect(result.value).toBeGreaterThanOrEqual(0); // Ternary operators may not be counted
108
+ });
109
+ });
110
+ describe('Integrated Complexity Analysis', () => {
111
+ it('should analyze Python code with auto-detection', async () => {
112
+ const pythonCode = `
113
+ def fibonacci(n):
114
+ if n <= 1:
115
+ return n
116
+ return fibonacci(n-1) + fibonacci(n-2)
117
+ `;
118
+ const result = await analyzeComplexity({ code: pythonCode });
119
+ expect(result.content[0].text).toContain('Python');
120
+ expect(result.content[0].text).toContain('cyclomaticComplexity');
121
+ });
122
+ it('should analyze Dart code with auto-detection', async () => {
123
+ const dartCode = `
124
+ class Counter extends StatefulWidget {
125
+ @override
126
+ _CounterState createState() => _CounterState();
127
+ }
128
+ `;
129
+ const result = await analyzeComplexity({ code: dartCode });
130
+ expect(result.content[0].text).toContain('Dart');
131
+ });
132
+ it('should analyze TypeScript code', async () => {
133
+ const tsCode = `
134
+ function complexFunc(a: number, b: number): number {
135
+ if (a > b) {
136
+ return a;
137
+ } else if (a < b) {
138
+ return b;
139
+ }
140
+ return 0;
141
+ }
142
+ `;
143
+ const result = await analyzeComplexity({ code: tsCode });
144
+ expect(result.content[0].text).toContain('TypeScript');
145
+ });
146
+ });
@@ -0,0 +1,230 @@
1
+ #!/usr/bin/env node
2
+ import { Server } from '@modelcontextprotocol/sdk/server/index.js';
3
+ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
4
+ import { CallToolRequestSchema, ListToolsRequestSchema, ErrorCode, McpError } from '@modelcontextprotocol/sdk/types.js';
5
+ // Import all tool definitions and handlers
6
+ import { getCurrentTimeDefinition, getCurrentTime } from './tools/time/getCurrentTime.js';
7
+ // Semantic code analysis tools (Serena-inspired)
8
+ import { findSymbolDefinition, findSymbol } from './tools/semantic/findSymbol.js';
9
+ import { findReferencesDefinition, findReferences } from './tools/semantic/findReferences.js';
10
+ import { createThinkingChainDefinition, createThinkingChain } from './tools/thinking/createThinkingChain.js';
11
+ import { analyzeProblemDefinition, analyzeProblem } from './tools/thinking/analyzeProblem.js';
12
+ import { stepByStepAnalysisDefinition, stepByStepAnalysis } from './tools/thinking/stepByStepAnalysis.js';
13
+ import { breakDownProblemDefinition, breakDownProblem } from './tools/thinking/breakDownProblem.js';
14
+ import { thinkAloudProcessDefinition, thinkAloudProcess } from './tools/thinking/thinkAloudProcess.js';
15
+ import { formatAsPlanDefinition, formatAsPlan } from './tools/thinking/formatAsPlan.js';
16
+ import { monitorConsoleLogsDefinition, monitorConsoleLogs } from './tools/browser/monitorConsoleLogs.js';
17
+ import { inspectNetworkRequestsDefinition, inspectNetworkRequests } from './tools/browser/inspectNetworkRequests.js';
18
+ import { saveMemoryDefinition, saveMemory } from './tools/memory/saveMemory.js';
19
+ import { recallMemoryDefinition, recallMemory } from './tools/memory/recallMemory.js';
20
+ import { listMemoriesDefinition, listMemories } from './tools/memory/listMemories.js';
21
+ import { deleteMemoryDefinition, deleteMemory } from './tools/memory/deleteMemory.js';
22
+ import { searchMemoriesDefinition, searchMemoriesHandler } from './tools/memory/searchMemories.js';
23
+ import { updateMemoryDefinition, updateMemory } from './tools/memory/updateMemory.js';
24
+ import { autoSaveContextDefinition, autoSaveContext } from './tools/memory/autoSaveContext.js';
25
+ import { restoreSessionContextDefinition, restoreSessionContext } from './tools/memory/restoreSessionContext.js';
26
+ import { prioritizeMemoryDefinition, prioritizeMemory } from './tools/memory/prioritizeMemory.js';
27
+ import { startSessionDefinition, startSession } from './tools/memory/startSession.js';
28
+ import { getCodingGuideDefinition, getCodingGuide } from './tools/convention/getCodingGuide.js';
29
+ import { applyQualityRulesDefinition, applyQualityRules } from './tools/convention/applyQualityRules.js';
30
+ import { validateCodeQualityDefinition, validateCodeQuality } from './tools/convention/validateCodeQuality.js';
31
+ import { analyzeComplexityDefinition, analyzeComplexity } from './tools/convention/analyzeComplexity.js';
32
+ import { checkCouplingCohesionDefinition, checkCouplingCohesion } from './tools/convention/checkCouplingCohesion.js';
33
+ import { suggestImprovementsDefinition, suggestImprovements } from './tools/convention/suggestImprovements.js';
34
+ import { generatePrdDefinition, generatePrd } from './tools/planning/generatePrd.js';
35
+ import { createUserStoriesDefinition, createUserStories } from './tools/planning/createUserStories.js';
36
+ import { analyzeRequirementsDefinition, analyzeRequirements } from './tools/planning/analyzeRequirements.js';
37
+ import { featureRoadmapDefinition, featureRoadmap } from './tools/planning/featureRoadmap.js';
38
+ import { enhancePromptDefinition, enhancePrompt } from './tools/prompt/enhancePrompt.js';
39
+ import { analyzePromptDefinition, analyzePrompt } from './tools/prompt/analyzePrompt.js';
40
+ import { previewUiAsciiDefinition, previewUiAscii } from './tools/ui/previewUiAscii.js';
41
+ // Collect all tool definitions
42
+ const tools = [
43
+ // Time Utility Tools
44
+ getCurrentTimeDefinition,
45
+ // Semantic Code Analysis Tools (Serena-inspired)
46
+ findSymbolDefinition,
47
+ findReferencesDefinition,
48
+ // Sequential Thinking Tools
49
+ createThinkingChainDefinition,
50
+ analyzeProblemDefinition,
51
+ stepByStepAnalysisDefinition,
52
+ breakDownProblemDefinition,
53
+ thinkAloudProcessDefinition,
54
+ formatAsPlanDefinition,
55
+ // Browser Development Tools
56
+ monitorConsoleLogsDefinition,
57
+ inspectNetworkRequestsDefinition,
58
+ // Memory Management Tools
59
+ saveMemoryDefinition,
60
+ recallMemoryDefinition,
61
+ listMemoriesDefinition,
62
+ deleteMemoryDefinition,
63
+ searchMemoriesDefinition,
64
+ updateMemoryDefinition,
65
+ autoSaveContextDefinition,
66
+ restoreSessionContextDefinition,
67
+ prioritizeMemoryDefinition,
68
+ startSessionDefinition,
69
+ // Convention Tools
70
+ getCodingGuideDefinition,
71
+ applyQualityRulesDefinition,
72
+ validateCodeQualityDefinition,
73
+ analyzeComplexityDefinition,
74
+ checkCouplingCohesionDefinition,
75
+ suggestImprovementsDefinition,
76
+ // Planning Tools
77
+ generatePrdDefinition,
78
+ createUserStoriesDefinition,
79
+ analyzeRequirementsDefinition,
80
+ featureRoadmapDefinition,
81
+ // Prompt Enhancement Tools
82
+ enhancePromptDefinition,
83
+ analyzePromptDefinition,
84
+ // UI Preview Tools
85
+ previewUiAsciiDefinition
86
+ ];
87
+ function createServer() {
88
+ const server = new Server({
89
+ name: 'Hi-AI',
90
+ version: '1.3.0',
91
+ }, {
92
+ capabilities: {
93
+ tools: {},
94
+ prompts: {},
95
+ resources: {},
96
+ },
97
+ });
98
+ server.setRequestHandler(ListToolsRequestSchema, async () => {
99
+ return { tools };
100
+ });
101
+ server.setRequestHandler(CallToolRequestSchema, async (request, extra) => {
102
+ const { name, arguments: args } = request.params;
103
+ try {
104
+ switch (name) {
105
+ // Time Utility Tools
106
+ case 'get_current_time':
107
+ return await getCurrentTime(args);
108
+ // Semantic Code Analysis Tools
109
+ case 'find_symbol':
110
+ return await findSymbol(args);
111
+ case 'find_references':
112
+ return await findReferences(args);
113
+ // Sequential Thinking Tools
114
+ case 'create_thinking_chain':
115
+ return await createThinkingChain(args);
116
+ case 'analyze_problem':
117
+ return await analyzeProblem(args);
118
+ case 'step_by_step_analysis':
119
+ return await stepByStepAnalysis(args);
120
+ case 'break_down_problem':
121
+ return await breakDownProblem(args);
122
+ case 'think_aloud_process':
123
+ return await thinkAloudProcess(args);
124
+ case 'format_as_plan':
125
+ return await formatAsPlan(args);
126
+ // Browser Development Tools
127
+ case 'monitor_console_logs':
128
+ return await monitorConsoleLogs(args);
129
+ case 'inspect_network_requests':
130
+ return await inspectNetworkRequests(args);
131
+ // Memory Management Tools
132
+ case 'save_memory':
133
+ return await saveMemory(args);
134
+ case 'recall_memory':
135
+ return await recallMemory(args);
136
+ case 'list_memories':
137
+ return await listMemories(args);
138
+ case 'delete_memory':
139
+ return await deleteMemory(args);
140
+ case 'search_memories':
141
+ return await searchMemoriesHandler(args);
142
+ case 'update_memory':
143
+ return await updateMemory(args);
144
+ case 'auto_save_context':
145
+ return await autoSaveContext(args);
146
+ case 'restore_session_context':
147
+ return await restoreSessionContext(args);
148
+ case 'prioritize_memory':
149
+ return await prioritizeMemory(args);
150
+ case 'start_session':
151
+ return await startSession(args);
152
+ // Convention Tools
153
+ case 'get_coding_guide':
154
+ return await getCodingGuide(args);
155
+ case 'apply_quality_rules':
156
+ return await applyQualityRules(args);
157
+ case 'validate_code_quality':
158
+ return await validateCodeQuality(args);
159
+ case 'analyze_complexity':
160
+ return await analyzeComplexity(args);
161
+ case 'check_coupling_cohesion':
162
+ return await checkCouplingCohesion(args);
163
+ case 'suggest_improvements':
164
+ return await suggestImprovements(args);
165
+ // Planning Tools
166
+ case 'generate_prd':
167
+ return await generatePrd(args);
168
+ case 'create_user_stories':
169
+ return await createUserStories(args);
170
+ case 'analyze_requirements':
171
+ return await analyzeRequirements(args);
172
+ case 'feature_roadmap':
173
+ return await featureRoadmap(args);
174
+ // Prompt Enhancement Tools
175
+ case 'enhance_prompt':
176
+ return await enhancePrompt(args);
177
+ case 'analyze_prompt':
178
+ return await analyzePrompt(args);
179
+ // UI Preview Tools
180
+ case 'preview_ui_ascii':
181
+ return await previewUiAscii(args);
182
+ default:
183
+ throw new McpError(ErrorCode.MethodNotFound, `Unknown tool: ${name}`);
184
+ }
185
+ }
186
+ catch (error) {
187
+ throw new McpError(ErrorCode.InternalError, `Error executing tool: ${error instanceof Error ? error.message : 'Unknown error'}`);
188
+ }
189
+ });
190
+ return server;
191
+ }
192
+ // Default export for Smithery platform
193
+ export default function ({ sessionId, config }) {
194
+ // Return the configured server instance
195
+ return createServer();
196
+ }
197
+ async function main() {
198
+ const server = createServer();
199
+ const transport = new StdioServerTransport();
200
+ // Handle process termination gracefully
201
+ process.on('SIGINT', async () => {
202
+ await server.close();
203
+ process.exit(0);
204
+ });
205
+ process.on('SIGTERM', async () => {
206
+ await server.close();
207
+ process.exit(0);
208
+ });
209
+ // Handle EPIPE errors that occur with sidecar proxy
210
+ process.on('uncaughtException', (error) => {
211
+ if (error.message && error.message.includes('EPIPE')) {
212
+ // Gracefully handle EPIPE errors
213
+ console.error('Connection closed by client');
214
+ return;
215
+ }
216
+ console.error('Uncaught exception:', error);
217
+ process.exit(1);
218
+ });
219
+ process.on('unhandledRejection', (reason, promise) => {
220
+ console.error('Unhandled Rejection at:', promise, 'reason:', reason);
221
+ });
222
+ await server.connect(transport);
223
+ }
224
+ // Only run main when not being imported by Smithery
225
+ if (process.argv[1]?.includes('hi-ai') || process.argv[1]?.endsWith('index.js')) {
226
+ main().catch((error) => {
227
+ console.error('Server initialization failed:', error);
228
+ process.exit(1);
229
+ });
230
+ }