@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,195 @@
1
+ // Semantic code analysis tool - Find References (v1.3)
2
+ // With ProjectCache for 25x performance improvement
3
+ import { Node } from 'ts-morph';
4
+ import * as path from 'path';
5
+ import { ProjectCache } from '../../lib/ProjectCache.js';
6
+ import { readFile } from 'fs/promises';
7
+ export const findReferencesDefinition = {
8
+ name: 'find_references',
9
+ description: '어디서 쓰|참조|사용처|find usage|references|where used - Find symbol references',
10
+ inputSchema: {
11
+ type: 'object',
12
+ properties: {
13
+ symbolName: { type: 'string', description: 'Name of the symbol to find references for' },
14
+ filePath: { type: 'string', description: 'File path where the symbol is defined' },
15
+ line: { type: 'number', description: 'Line number of the symbol definition' },
16
+ projectPath: { type: 'string', description: 'Project directory path' }
17
+ },
18
+ required: ['symbolName', 'projectPath']
19
+ },
20
+ annotations: {
21
+ title: 'Find References',
22
+ audience: ['user', 'assistant']
23
+ }
24
+ };
25
+ export async function findReferences(args) {
26
+ const { symbolName, filePath, line, projectPath } = args;
27
+ try {
28
+ // Use cached project for performance
29
+ const projectCache = ProjectCache.getInstance();
30
+ const project = projectCache.getOrCreate(projectPath);
31
+ const allReferences = [];
32
+ // Check for Python files
33
+ const glob = await import('glob');
34
+ const pythonFiles = glob.globSync(path.join(projectPath, '**/*.py'), {
35
+ ignore: ['**/node_modules/**', '**/.git/**', '**/venv/**', '**/__pycache__/**']
36
+ });
37
+ // Parse Python files for references
38
+ for (const pyFile of pythonFiles) {
39
+ try {
40
+ const content = await readFile(pyFile, 'utf-8');
41
+ const lines = content.split('\n');
42
+ lines.forEach((line, index) => {
43
+ if (line.includes(symbolName)) {
44
+ const column = line.indexOf(symbolName);
45
+ allReferences.push({
46
+ filePath: pyFile,
47
+ line: index + 1,
48
+ column: column,
49
+ text: line.trim().substring(0, 100),
50
+ isDefinition: /^(def|class)\s/.test(line.trim())
51
+ });
52
+ }
53
+ });
54
+ }
55
+ catch (error) {
56
+ console.error(`Error parsing Python file ${pyFile}:`, error);
57
+ }
58
+ }
59
+ // If specific file and line provided, use precise reference finding
60
+ if (filePath && line) {
61
+ const sourceFile = project.getSourceFile(filePath);
62
+ if (sourceFile) {
63
+ const position = sourceFile.compilerNode.getPositionOfLineAndCharacter(line - 1, 0);
64
+ const node = sourceFile.getDescendantAtPos(position);
65
+ if (node) {
66
+ const symbol = node.getSymbol();
67
+ if (symbol) {
68
+ const references = project.getLanguageService().findReferencesAtPosition(sourceFile, position);
69
+ if (references) {
70
+ for (const ref of references) {
71
+ for (const reference of ref.getReferences()) {
72
+ const refSourceFile = reference.getSourceFile();
73
+ const refNode = reference.getNode();
74
+ const start = refNode.getStartLinePos();
75
+ const pos = refSourceFile.getLineAndColumnAtPos(start);
76
+ allReferences.push({
77
+ filePath: refSourceFile.getFilePath(),
78
+ line: pos.line,
79
+ column: pos.column,
80
+ text: refNode.getParent()?.getText().substring(0, 100) || refNode.getText(),
81
+ isDefinition: reference.isDefinition() || false
82
+ });
83
+ }
84
+ }
85
+ }
86
+ }
87
+ }
88
+ }
89
+ }
90
+ else {
91
+ // Fallback: search by name across all files
92
+ for (const sourceFile of project.getSourceFiles()) {
93
+ const filePath = sourceFile.getFilePath();
94
+ // Skip node_modules and other irrelevant paths
95
+ if (filePath.includes('node_modules') || filePath.includes('.git')) {
96
+ continue;
97
+ }
98
+ // Find all identifiers matching the symbol name
99
+ sourceFile.forEachDescendant((node) => {
100
+ if (Node.isIdentifier(node) && node.getText() === symbolName) {
101
+ const start = node.getStartLinePos();
102
+ const pos = sourceFile.getLineAndColumnAtPos(start);
103
+ const parent = node.getParent();
104
+ // Determine if this is a definition
105
+ const isDefinition = isSymbolDefinition(node);
106
+ allReferences.push({
107
+ filePath: filePath,
108
+ line: pos.line,
109
+ column: pos.column,
110
+ text: parent?.getText().substring(0, 100) || node.getText(),
111
+ isDefinition
112
+ });
113
+ }
114
+ });
115
+ }
116
+ }
117
+ const definitions = allReferences.filter(r => r.isDefinition);
118
+ const usages = allReferences.filter(r => !r.isDefinition);
119
+ return {
120
+ content: [{
121
+ type: 'text',
122
+ text: `Found ${allReferences.length} references (${definitions.length} defs, ${usages.length} uses):\n${allReferences.slice(0, 20).map(r => `${r.isDefinition ? 'DEF' : 'USE'}: ${r.filePath}:${r.line}`).join('\n')}`
123
+ }]
124
+ };
125
+ }
126
+ catch (error) {
127
+ return {
128
+ content: [{
129
+ type: 'text',
130
+ text: `Error finding references: ${error instanceof Error ? error.message : 'Unknown error'}`
131
+ }]
132
+ };
133
+ }
134
+ }
135
+ function isSymbolDefinition(node) {
136
+ const parent = node.getParent();
137
+ if (!parent)
138
+ return false;
139
+ // Check if this is a declaration
140
+ return Node.isFunctionDeclaration(parent) ||
141
+ Node.isClassDeclaration(parent) ||
142
+ Node.isInterfaceDeclaration(parent) ||
143
+ Node.isTypeAliasDeclaration(parent) ||
144
+ Node.isVariableDeclaration(parent) ||
145
+ Node.isMethodDeclaration(parent) ||
146
+ Node.isPropertyDeclaration(parent) ||
147
+ Node.isParameterDeclaration(parent);
148
+ }
149
+ function groupReferencesByFile(references) {
150
+ const grouped = {};
151
+ for (const ref of references) {
152
+ if (!grouped[ref.filePath]) {
153
+ grouped[ref.filePath] = [];
154
+ }
155
+ grouped[ref.filePath].push(ref);
156
+ }
157
+ // Sort references within each file by line number
158
+ for (const filePath in grouped) {
159
+ grouped[filePath].sort((a, b) => a.line - b.line);
160
+ }
161
+ return grouped;
162
+ }
163
+ function formatReferenceResults(result) {
164
+ let output = `# Reference Search Results\n\n`;
165
+ output += `**Symbol:** ${result.symbol}\n`;
166
+ output += `**Total References:** ${result.totalReferences}\n`;
167
+ output += `**Files:** ${result.filesCount}\n`;
168
+ output += `**Definitions:** ${result.definitions.length}\n`;
169
+ output += `**Usages:** ${result.usages.length}\n\n`;
170
+ if (result.totalReferences === 0) {
171
+ output += `No references found for "${result.symbol}".\n`;
172
+ return output;
173
+ }
174
+ // Show definitions first
175
+ if (result.definitions.length > 0) {
176
+ output += `## Definitions\n\n`;
177
+ result.definitions.forEach((def, index) => {
178
+ output += `${index + 1}. **${def.filePath}:${def.line}:${def.column}**\n`;
179
+ output += ` \`\`\`typescript\n ${def.text}\n \`\`\`\n\n`;
180
+ });
181
+ }
182
+ // Show usages grouped by file
183
+ output += `## Usages by File\n\n`;
184
+ for (const [filePath, refs] of Object.entries(result.references)) {
185
+ const usages = refs.filter(r => !r.isDefinition);
186
+ if (usages.length === 0)
187
+ continue;
188
+ output += `### ${filePath} (${usages.length} usages)\n\n`;
189
+ usages.forEach((ref) => {
190
+ output += `- **Line ${ref.line}:** \`${ref.text.substring(0, 60)}...\`\n`;
191
+ });
192
+ output += `\n`;
193
+ }
194
+ return output;
195
+ }
@@ -0,0 +1,200 @@
1
+ // Semantic code analysis tool - Find Symbol (v1.3)
2
+ // With ProjectCache for 25x performance improvement
3
+ import { Node } from 'ts-morph';
4
+ import * as path from 'path';
5
+ import { PythonParser } from '../../lib/PythonParser.js';
6
+ import { ProjectCache } from '../../lib/ProjectCache.js';
7
+ import { readFile } from 'fs/promises';
8
+ export const findSymbolDefinition = {
9
+ name: 'find_symbol',
10
+ description: '함수 찾아|클래스 어디|변수 위치|find function|where is|locate - Find symbol definitions',
11
+ inputSchema: {
12
+ type: 'object',
13
+ properties: {
14
+ symbolName: { type: 'string', description: 'Name of the symbol to find' },
15
+ projectPath: { type: 'string', description: 'Project directory path' },
16
+ symbolType: {
17
+ type: 'string',
18
+ enum: ['all', 'function', 'class', 'interface', 'variable', 'type'],
19
+ description: 'Type of symbol to search for'
20
+ }
21
+ },
22
+ required: ['symbolName', 'projectPath']
23
+ },
24
+ annotations: {
25
+ title: 'Find Symbol',
26
+ audience: ['user', 'assistant']
27
+ }
28
+ };
29
+ export async function findSymbol(args) {
30
+ const { symbolName, projectPath, symbolType = 'all' } = args;
31
+ try {
32
+ // Use cached project for performance
33
+ const projectCache = ProjectCache.getInstance();
34
+ const project = projectCache.getOrCreate(projectPath);
35
+ const symbols = [];
36
+ // Check for Python files
37
+ const glob = await import('glob');
38
+ const pythonFiles = glob.globSync(path.join(projectPath, '**/*.py'), {
39
+ ignore: ['**/node_modules/**', '**/.git/**', '**/venv/**', '**/__pycache__/**']
40
+ });
41
+ // Parse Python files
42
+ for (const pyFile of pythonFiles) {
43
+ try {
44
+ const content = await readFile(pyFile, 'utf-8');
45
+ const pythonSymbols = await PythonParser.findSymbols(content);
46
+ for (const pySymbol of pythonSymbols) {
47
+ if (pySymbol.name.includes(symbolName) &&
48
+ (symbolType === 'all' || symbolType === pySymbol.kind)) {
49
+ symbols.push({
50
+ name: pySymbol.name,
51
+ kind: pySymbol.kind,
52
+ filePath: pyFile,
53
+ line: pySymbol.line,
54
+ column: pySymbol.column,
55
+ preview: pySymbol.docstring?.substring(0, 100) || `${pySymbol.kind} ${pySymbol.name}`
56
+ });
57
+ }
58
+ }
59
+ }
60
+ catch (error) {
61
+ // Skip files that can't be parsed
62
+ console.error(`Error parsing Python file ${pyFile}:`, error);
63
+ }
64
+ }
65
+ // Search through all source files
66
+ for (const sourceFile of project.getSourceFiles()) {
67
+ const filePath = sourceFile.getFilePath();
68
+ // Skip node_modules and other irrelevant paths
69
+ if (filePath.includes('node_modules') || filePath.includes('.git')) {
70
+ continue;
71
+ }
72
+ // Find matching symbols based on type
73
+ sourceFile.forEachDescendant((node) => {
74
+ const nodeSymbol = extractSymbolInfo(node, symbolName, symbolType);
75
+ if (nodeSymbol) {
76
+ const start = node.getStartLinePos();
77
+ const pos = sourceFile.getLineAndColumnAtPos(start);
78
+ symbols.push({
79
+ name: nodeSymbol.name,
80
+ kind: nodeSymbol.kind,
81
+ filePath: filePath,
82
+ line: pos.line,
83
+ column: pos.column,
84
+ preview: node.getText().substring(0, 100)
85
+ });
86
+ }
87
+ });
88
+ }
89
+ // Sort by relevance (exact matches first)
90
+ symbols.sort((a, b) => {
91
+ const aExact = a.name === symbolName ? 0 : 1;
92
+ const bExact = b.name === symbolName ? 0 : 1;
93
+ return aExact - bExact;
94
+ });
95
+ return {
96
+ content: [{
97
+ type: 'text',
98
+ text: `Found ${symbols.length} symbols:\n${symbols.slice(0, 20).map(s => `${s.name} (${s.kind}) - ${s.filePath}:${s.line}`).join('\n')}`
99
+ }]
100
+ };
101
+ }
102
+ catch (error) {
103
+ return {
104
+ content: [{
105
+ type: 'text',
106
+ text: `Error finding symbol: ${error instanceof Error ? error.message : 'Unknown error'}`
107
+ }]
108
+ };
109
+ }
110
+ }
111
+ function extractSymbolInfo(node, symbolName, symbolType) {
112
+ const kind = node.getKind();
113
+ // Function declarations and expressions
114
+ if (symbolType === 'all' || symbolType === 'function') {
115
+ if (Node.isFunctionDeclaration(node) || Node.isMethodDeclaration(node)) {
116
+ const name = node.getName();
117
+ if (name && name.includes(symbolName)) {
118
+ return { name, kind: 'function' };
119
+ }
120
+ }
121
+ if (Node.isVariableDeclaration(node)) {
122
+ const name = node.getName();
123
+ const initializer = node.getInitializer();
124
+ if (name && name.includes(symbolName) &&
125
+ (Node.isArrowFunction(initializer) || Node.isFunctionExpression(initializer))) {
126
+ return { name, kind: 'function' };
127
+ }
128
+ }
129
+ }
130
+ // Class declarations
131
+ if (symbolType === 'all' || symbolType === 'class') {
132
+ if (Node.isClassDeclaration(node)) {
133
+ const name = node.getName();
134
+ if (name && name.includes(symbolName)) {
135
+ return { name, kind: 'class' };
136
+ }
137
+ }
138
+ }
139
+ // Interface declarations
140
+ if (symbolType === 'all' || symbolType === 'interface') {
141
+ if (Node.isInterfaceDeclaration(node)) {
142
+ const name = node.getName();
143
+ if (name && name.includes(symbolName)) {
144
+ return { name, kind: 'interface' };
145
+ }
146
+ }
147
+ }
148
+ // Type aliases
149
+ if (symbolType === 'all' || symbolType === 'type') {
150
+ if (Node.isTypeAliasDeclaration(node)) {
151
+ const name = node.getName();
152
+ if (name && name.includes(symbolName)) {
153
+ return { name, kind: 'type' };
154
+ }
155
+ }
156
+ }
157
+ // Variables
158
+ if (symbolType === 'all' || symbolType === 'variable') {
159
+ if (Node.isVariableDeclaration(node)) {
160
+ const name = node.getName();
161
+ const initializer = node.getInitializer();
162
+ if (name && name.includes(symbolName) &&
163
+ !Node.isArrowFunction(initializer) && !Node.isFunctionExpression(initializer)) {
164
+ return { name, kind: 'variable' };
165
+ }
166
+ }
167
+ }
168
+ return null;
169
+ }
170
+ function generateSummary(symbols, query) {
171
+ if (symbols.length === 0) {
172
+ return `No symbols found matching "${query}"`;
173
+ }
174
+ const byKind = {};
175
+ symbols.forEach(s => {
176
+ byKind[s.kind] = (byKind[s.kind] || 0) + 1;
177
+ });
178
+ const summary = Object.entries(byKind)
179
+ .map(([kind, count]) => `${count} ${kind}${count > 1 ? 's' : ''}`)
180
+ .join(', ');
181
+ return `Found ${symbols.length} symbols: ${summary}`;
182
+ }
183
+ function formatSymbolResults(result) {
184
+ let output = `# Symbol Search Results\n\n`;
185
+ output += `**Query:** ${result.query}\n`;
186
+ output += `**Type:** ${result.type}\n`;
187
+ output += `**Results:** ${result.resultsCount} symbols found\n\n`;
188
+ if (result.symbols.length === 0) {
189
+ output += `No symbols found matching "${result.query}".\n`;
190
+ return output;
191
+ }
192
+ output += `## Found Symbols\n\n`;
193
+ result.symbols.forEach((symbol, index) => {
194
+ output += `### ${index + 1}. ${symbol.name} (${symbol.kind})\n`;
195
+ output += `**Location:** ${symbol.filePath}:${symbol.line}:${symbol.column}\n`;
196
+ output += `**Preview:**\n\`\`\`typescript\n${symbol.preview}\n\`\`\`\n\n`;
197
+ });
198
+ output += `\n## Summary\n${result.summary}`;
199
+ return output;
200
+ }
@@ -0,0 +1,50 @@
1
+ // Sequential thinking tool - completely independent
2
+ export const analyzeProblemDefinition = {
3
+ name: 'analyze_problem',
4
+ description: '문제 분석|어떻게 접근|분석해줘|analyze this|how to approach|break this down - Break down complex problem into structured steps',
5
+ inputSchema: {
6
+ type: 'object',
7
+ properties: {
8
+ problem: { type: 'string', description: 'Problem to analyze' },
9
+ domain: { type: 'string', description: 'Problem domain' }
10
+ },
11
+ required: ['problem']
12
+ },
13
+ annotations: {
14
+ title: 'Analyze Problem',
15
+ audience: ['user', 'assistant']
16
+ }
17
+ };
18
+ export async function analyzeProblem(args) {
19
+ const { problem, domain = 'general' } = args;
20
+ const problemAnalysis = {
21
+ action: 'analyze_problem',
22
+ problem,
23
+ domain,
24
+ analysis: {
25
+ breakdown: [
26
+ 'Define the problem clearly',
27
+ 'Identify key constraints and requirements',
28
+ 'Break down into smaller sub-problems',
29
+ 'Determine solution approach',
30
+ 'Plan implementation steps'
31
+ ],
32
+ considerations: [
33
+ 'What are the inputs and expected outputs?',
34
+ 'Are there any edge cases to consider?',
35
+ 'What are the performance requirements?',
36
+ 'How will this integrate with existing systems?'
37
+ ],
38
+ nextSteps: [
39
+ 'Research existing solutions',
40
+ 'Create detailed implementation plan',
41
+ 'Identify potential risks and mitigation strategies',
42
+ 'Define success criteria'
43
+ ]
44
+ },
45
+ status: 'success'
46
+ };
47
+ return {
48
+ content: [{ type: 'text', text: `Problem: ${problem}\nDomain: ${domain}\n\nBreakdown:\n${problemAnalysis.analysis.breakdown.map((b, i) => `${i + 1}. ${b}`).join('\n')}\n\nConsiderations:\n${problemAnalysis.analysis.considerations.map(c => `- ${c}`).join('\n')}\n\nNext Steps:\n${problemAnalysis.analysis.nextSteps.map(n => `- ${n}`).join('\n')}` }]
49
+ };
50
+ }
@@ -0,0 +1,140 @@
1
+ // Sequential thinking tool - completely independent
2
+ import { Project, ScriptKind } from "ts-morph";
3
+ const AST_PROJECT = new Project({
4
+ useInMemoryFileSystem: true,
5
+ compilerOptions: { allowJs: true, skipLibCheck: true }
6
+ });
7
+ export const breakDownProblemDefinition = {
8
+ name: 'break_down_problem',
9
+ description: '나눠서|단계별로|세분화|break down|divide|split into parts - Break complex problems into sub-problems',
10
+ inputSchema: {
11
+ type: 'object',
12
+ properties: {
13
+ problem: { type: 'string', description: 'Complex problem to break down' },
14
+ maxDepth: { type: 'number', description: 'Maximum breakdown depth' },
15
+ approach: { type: 'string', description: 'Breakdown approach', enum: ['sequential', 'hierarchical', 'dependency-based'] }
16
+ },
17
+ required: ['problem']
18
+ },
19
+ annotations: {
20
+ title: 'Break Down Problem',
21
+ audience: ['user', 'assistant']
22
+ }
23
+ };
24
+ export async function breakDownProblem(args) {
25
+ const { problem: breakdownProblem, maxDepth = 3, approach = 'hierarchical' } = args;
26
+ // 코드로 추정되는 입력이면 AST 기반 구조 분해 시도
27
+ let codeStructureSubProblems = null;
28
+ if (breakdownProblem.includes('function') || breakdownProblem.includes('class') || breakdownProblem.includes('=>')) {
29
+ try {
30
+ const sourceFile = AST_PROJECT.createSourceFile('temp.ts', breakdownProblem, {
31
+ overwrite: true,
32
+ scriptKind: ScriptKind.TS
33
+ });
34
+ const funcs = sourceFile.getFunctions();
35
+ const classes = sourceFile.getClasses();
36
+ const vars = sourceFile.getVariableDeclarations();
37
+ codeStructureSubProblems = [];
38
+ funcs.forEach((f, i) => {
39
+ codeStructureSubProblems.push({
40
+ id: `codeFunc${i + 1}`,
41
+ title: `함수 분석: ${f.getName() || '익명함수'}`,
42
+ description: f.getText().slice(0, 100) + (f.getText().length > 100 ? '...' : ''),
43
+ complexity: 'medium',
44
+ priority: 'high',
45
+ dependencies: []
46
+ });
47
+ });
48
+ classes.forEach((c, i) => {
49
+ codeStructureSubProblems.push({
50
+ id: `codeClass${i + 1}`,
51
+ title: `클래스 분석: ${c.getName() || '익명클래스'}`,
52
+ description: c.getText().slice(0, 100) + (c.getText().length > 100 ? '...' : ''),
53
+ complexity: 'high',
54
+ priority: 'high',
55
+ dependencies: []
56
+ });
57
+ });
58
+ vars.forEach((v, i) => {
59
+ codeStructureSubProblems.push({
60
+ id: `codeVar${i + 1}`,
61
+ title: `변수 분석: ${v.getName()}`,
62
+ description: v.getText().slice(0, 100) + (v.getText().length > 100 ? '...' : ''),
63
+ complexity: 'low',
64
+ priority: 'medium',
65
+ dependencies: []
66
+ });
67
+ });
68
+ if (codeStructureSubProblems.length === 0)
69
+ codeStructureSubProblems = null;
70
+ }
71
+ catch (e) {
72
+ codeStructureSubProblems = null;
73
+ }
74
+ }
75
+ const generateSubProblems = (parentProblem, depth, maxDepth) => {
76
+ if (depth >= maxDepth)
77
+ return null;
78
+ const subProblems = [
79
+ {
80
+ id: `${depth}.1`,
81
+ title: `Understanding ${parentProblem}`,
82
+ description: `Analyze and understand the core aspects of ${parentProblem}`,
83
+ complexity: 'low',
84
+ priority: 'high',
85
+ dependencies: []
86
+ },
87
+ {
88
+ id: `${depth}.2`,
89
+ title: `Planning solution for ${parentProblem}`,
90
+ description: `Create detailed plan to solve ${parentProblem}`,
91
+ complexity: 'medium',
92
+ priority: 'high',
93
+ dependencies: [`${depth}.1`]
94
+ },
95
+ {
96
+ id: `${depth}.3`,
97
+ title: `Implementing solution for ${parentProblem}`,
98
+ description: `Execute the planned solution for ${parentProblem}`,
99
+ complexity: 'high',
100
+ priority: 'medium',
101
+ dependencies: [`${depth}.2`]
102
+ }
103
+ ];
104
+ if (depth < maxDepth - 1) {
105
+ subProblems.forEach((subProblem) => {
106
+ subProblem.subProblems = generateSubProblems(subProblem.title, depth + 1, maxDepth);
107
+ });
108
+ }
109
+ return subProblems;
110
+ };
111
+ const problemBreakdown = {
112
+ action: 'break_down_problem',
113
+ problem: breakdownProblem,
114
+ approach,
115
+ maxDepth,
116
+ breakdown: {
117
+ rootProblem: {
118
+ id: '0',
119
+ title: breakdownProblem,
120
+ description: `Root problem: ${breakdownProblem}`,
121
+ complexity: 'high',
122
+ subProblems: codeStructureSubProblems || generateSubProblems(breakdownProblem, 1, maxDepth)
123
+ }
124
+ },
125
+ executionOrder: approach === 'dependency-based' ?
126
+ ['Understanding phase', 'Planning phase', 'Implementation phase'] :
127
+ approach === 'sequential' ?
128
+ ['Step 1', 'Step 2', 'Step 3', '...'] :
129
+ ['Top-level analysis', 'Mid-level breakdown', 'Detailed tasks'],
130
+ status: 'success'
131
+ };
132
+ const formatSubProblems = (subs, indent = 0) => {
133
+ if (!subs)
134
+ return '';
135
+ return subs.map(s => `${' '.repeat(indent)}- ${s.title} (${s.complexity}, ${s.priority})${s.subProblems ? '\n' + formatSubProblems(s.subProblems, indent + 1) : ''}`).join('\n');
136
+ };
137
+ return {
138
+ content: [{ type: 'text', text: `Problem: ${breakdownProblem}\nApproach: ${approach}\nMax Depth: ${maxDepth}\n\nBreakdown:\n${formatSubProblems(problemBreakdown.breakdown.rootProblem.subProblems)}\n\nExecution: ${problemBreakdown.executionOrder.join(' → ')}` }]
139
+ };
140
+ }
@@ -0,0 +1,39 @@
1
+ // Sequential thinking tool - completely independent
2
+ export const createThinkingChainDefinition = {
3
+ name: 'create_thinking_chain',
4
+ description: '생각 과정|사고 흐름|연쇄적으로|thinking process|chain of thought|reasoning chain - Create sequential thinking chain',
5
+ inputSchema: {
6
+ type: 'object',
7
+ properties: {
8
+ topic: { type: 'string', description: 'Topic to think about' },
9
+ steps: { type: 'number', description: 'Number of thinking steps' }
10
+ },
11
+ required: ['topic']
12
+ },
13
+ annotations: {
14
+ title: 'Create Thinking Chain',
15
+ audience: ['user', 'assistant']
16
+ }
17
+ };
18
+ export async function createThinkingChain(args) {
19
+ const { topic, steps = 5 } = args;
20
+ const thinkingChain = {
21
+ action: 'create_thinking_chain',
22
+ topic,
23
+ steps,
24
+ chain: Array.from({ length: steps }, (_, i) => ({
25
+ step: i + 1,
26
+ title: `Step ${i + 1}: Analyze ${topic}`,
27
+ content: `Think about ${topic} from perspective ${i + 1}`,
28
+ questions: [
29
+ `What are the key aspects of ${topic}?`,
30
+ `How does this relate to the overall problem?`,
31
+ `What are the potential implications?`
32
+ ]
33
+ })),
34
+ status: 'success'
35
+ };
36
+ return {
37
+ content: [{ type: 'text', text: `Topic: ${topic}\nSteps: ${steps}\n\n${thinkingChain.chain.map(s => `${s.step}. ${s.title}\n ${s.content}\n Q: ${s.questions.join(', ')}`).join('\n\n')}` }]
38
+ };
39
+ }