@su-record/vibe 0.1.2 → 0.1.4

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 (59) hide show
  1. package/README.md +13 -6
  2. package/bin/vibe +20 -2
  3. package/package.json +5 -6
  4. package/scripts/install-mcp.js +31 -5
  5. package/mcp/dist/__tests__/complexity.test.js +0 -126
  6. package/mcp/dist/__tests__/memory.test.js +0 -120
  7. package/mcp/dist/__tests__/python-dart-complexity.test.js +0 -146
  8. package/mcp/dist/index.js +0 -230
  9. package/mcp/dist/lib/ContextCompressor.js +0 -305
  10. package/mcp/dist/lib/MemoryManager.js +0 -334
  11. package/mcp/dist/lib/ProjectCache.js +0 -126
  12. package/mcp/dist/lib/PythonParser.js +0 -241
  13. package/mcp/dist/tools/browser/browserPool.js +0 -76
  14. package/mcp/dist/tools/browser/browserUtils.js +0 -135
  15. package/mcp/dist/tools/browser/inspectNetworkRequests.js +0 -140
  16. package/mcp/dist/tools/browser/monitorConsoleLogs.js +0 -97
  17. package/mcp/dist/tools/convention/analyzeComplexity.js +0 -248
  18. package/mcp/dist/tools/convention/applyQualityRules.js +0 -102
  19. package/mcp/dist/tools/convention/checkCouplingCohesion.js +0 -233
  20. package/mcp/dist/tools/convention/complexityMetrics.js +0 -133
  21. package/mcp/dist/tools/convention/dartComplexity.js +0 -117
  22. package/mcp/dist/tools/convention/getCodingGuide.js +0 -64
  23. package/mcp/dist/tools/convention/languageDetector.js +0 -50
  24. package/mcp/dist/tools/convention/pythonComplexity.js +0 -109
  25. package/mcp/dist/tools/convention/suggestImprovements.js +0 -257
  26. package/mcp/dist/tools/convention/validateCodeQuality.js +0 -177
  27. package/mcp/dist/tools/memory/autoSaveContext.js +0 -79
  28. package/mcp/dist/tools/memory/database.js +0 -123
  29. package/mcp/dist/tools/memory/deleteMemory.js +0 -39
  30. package/mcp/dist/tools/memory/listMemories.js +0 -38
  31. package/mcp/dist/tools/memory/memoryConfig.js +0 -27
  32. package/mcp/dist/tools/memory/memorySQLite.js +0 -138
  33. package/mcp/dist/tools/memory/memoryUtils.js +0 -34
  34. package/mcp/dist/tools/memory/migrate.js +0 -113
  35. package/mcp/dist/tools/memory/prioritizeMemory.js +0 -109
  36. package/mcp/dist/tools/memory/recallMemory.js +0 -40
  37. package/mcp/dist/tools/memory/restoreSessionContext.js +0 -69
  38. package/mcp/dist/tools/memory/saveMemory.js +0 -34
  39. package/mcp/dist/tools/memory/searchMemories.js +0 -37
  40. package/mcp/dist/tools/memory/startSession.js +0 -100
  41. package/mcp/dist/tools/memory/updateMemory.js +0 -46
  42. package/mcp/dist/tools/planning/analyzeRequirements.js +0 -166
  43. package/mcp/dist/tools/planning/createUserStories.js +0 -119
  44. package/mcp/dist/tools/planning/featureRoadmap.js +0 -202
  45. package/mcp/dist/tools/planning/generatePrd.js +0 -156
  46. package/mcp/dist/tools/prompt/analyzePrompt.js +0 -145
  47. package/mcp/dist/tools/prompt/enhancePrompt.js +0 -105
  48. package/mcp/dist/tools/semantic/findReferences.js +0 -195
  49. package/mcp/dist/tools/semantic/findSymbol.js +0 -200
  50. package/mcp/dist/tools/thinking/analyzeProblem.js +0 -50
  51. package/mcp/dist/tools/thinking/breakDownProblem.js +0 -140
  52. package/mcp/dist/tools/thinking/createThinkingChain.js +0 -39
  53. package/mcp/dist/tools/thinking/formatAsPlan.js +0 -73
  54. package/mcp/dist/tools/thinking/stepByStepAnalysis.js +0 -58
  55. package/mcp/dist/tools/thinking/thinkAloudProcess.js +0 -75
  56. package/mcp/dist/tools/time/getCurrentTime.js +0 -61
  57. package/mcp/dist/tools/ui/previewUiAscii.js +0 -232
  58. package/mcp/dist/types/tool.js +0 -2
  59. package/mcp/package.json +0 -53
@@ -1,100 +0,0 @@
1
- // Memory management tool - SQLite based (v1.3)
2
- import { MemoryManager } from '../../lib/MemoryManager.js';
3
- import { promises as fs } from 'fs';
4
- import path from 'path';
5
- const GUIDES_DIR = path.join(process.cwd(), 'guides');
6
- const GUIDES_FILE = path.join(GUIDES_DIR, 'coding_guides.json');
7
- async function ensureGuidesDir() {
8
- try {
9
- await fs.access(GUIDES_DIR);
10
- }
11
- catch {
12
- await fs.mkdir(GUIDES_DIR, { recursive: true });
13
- }
14
- }
15
- async function loadGuides() {
16
- try {
17
- await ensureGuidesDir();
18
- const data = await fs.readFile(GUIDES_FILE, 'utf-8');
19
- return JSON.parse(data);
20
- }
21
- catch {
22
- return [];
23
- }
24
- }
25
- export const startSessionDefinition = {
26
- name: 'start_session',
27
- description: 'hi-ai|hello|안녕|하이아이 - Start session with context',
28
- inputSchema: {
29
- type: 'object',
30
- properties: {
31
- greeting: { type: 'string', description: 'Greeting message that triggered this action (e.g., "하이아이", "hi-ai")' },
32
- loadMemory: { type: 'boolean', description: 'Load relevant project memories (default: true)' },
33
- loadGuides: { type: 'boolean', description: 'Load applicable coding guides (default: true)' },
34
- restoreContext: { type: 'boolean', description: 'Restore previous session context (default: true)' }
35
- },
36
- required: []
37
- },
38
- annotations: {
39
- title: 'Start Session',
40
- audience: ['user', 'assistant']
41
- }
42
- };
43
- export async function startSession(args) {
44
- const { greeting = '', loadMemory = true, loadGuides: shouldLoadGuides = true, restoreContext = true } = args;
45
- try {
46
- const memoryManager = MemoryManager.getInstance();
47
- let summary = `${greeting ? greeting + '! ' : ''}Session started.\n`;
48
- // Load relevant project memories
49
- if (loadMemory) {
50
- const projectMemories = memoryManager.list('project');
51
- const codeMemories = memoryManager.list('code');
52
- const memories = [...projectMemories, ...codeMemories].slice(0, 5);
53
- if (memories.length > 0) {
54
- summary += `\nRecent Project Info:\n`;
55
- memories.forEach(mem => {
56
- const preview = mem.value.substring(0, 80);
57
- summary += ` • ${mem.key}: ${preview}${mem.value.length > 80 ? '...' : ''}\n`;
58
- });
59
- }
60
- }
61
- // Load coding guides
62
- if (shouldLoadGuides) {
63
- const allGuides = await loadGuides();
64
- const guides = allGuides
65
- .sort((a, b) => new Date(b.lastUpdated).getTime() - new Date(a.lastUpdated).getTime())
66
- .slice(0, 3);
67
- if (guides.length > 0) {
68
- summary += `\nActive Coding Guides:\n`;
69
- guides.forEach(guide => {
70
- summary += ` • ${guide.name} (${guide.category}): ${guide.description}\n`;
71
- });
72
- }
73
- }
74
- // Restore context
75
- if (restoreContext) {
76
- const contextMemories = memoryManager.list('context').slice(0, 3);
77
- if (contextMemories.length > 0) {
78
- summary += `\nPrevious Context:\n`;
79
- contextMemories.forEach(ctx => {
80
- try {
81
- const data = JSON.parse(ctx.value);
82
- summary += ` • ${data.urgency?.toUpperCase() || 'MEDIUM'} priority from ${new Date(ctx.timestamp).toLocaleString()}\n`;
83
- }
84
- catch {
85
- summary += ` • Context from ${new Date(ctx.timestamp).toLocaleString()}\n`;
86
- }
87
- });
88
- }
89
- }
90
- summary += '\nReady to continue development! What would you like to work on?';
91
- return {
92
- content: [{ type: 'text', text: summary }]
93
- };
94
- }
95
- catch (error) {
96
- return {
97
- content: [{ type: 'text', text: `${greeting ? greeting + '! ' : ''}Session started.\n\nReady to begin! What can I help you with?` }]
98
- };
99
- }
100
- }
@@ -1,46 +0,0 @@
1
- // Memory management tool - completely independent
2
- import { MemoryManager } from '../../lib/MemoryManager.js';
3
- export const updateMemoryDefinition = {
4
- name: 'update_memory',
5
- description: '수정해|업데이트|바꿔|update|change|modify|edit - Update existing memory',
6
- inputSchema: {
7
- type: 'object',
8
- properties: {
9
- key: { type: 'string', description: 'Memory key to update' },
10
- value: { type: 'string', description: 'New value' },
11
- append: { type: 'boolean', description: 'Append to existing value' }
12
- },
13
- required: ['key', 'value']
14
- },
15
- annotations: {
16
- title: 'Update Memory',
17
- audience: ['user', 'assistant']
18
- }
19
- };
20
- export async function updateMemory(args) {
21
- const { key: updateKey, value: updateValue, append = false } = args;
22
- try {
23
- const mm = MemoryManager.getInstance();
24
- const existingMemory = mm.recall(updateKey);
25
- if (existingMemory) {
26
- const newValue = append ? existingMemory.value + ' ' + updateValue : updateValue;
27
- mm.update(updateKey, newValue);
28
- return {
29
- content: [{
30
- type: 'text',
31
- text: `✓ ${append ? 'Appended to' : 'Updated'} memory: "${updateKey}"`
32
- }]
33
- };
34
- }
35
- else {
36
- return {
37
- content: [{ type: 'text', text: `✗ Memory not found: "${updateKey}". Use save_memory to create new memory.` }]
38
- };
39
- }
40
- }
41
- catch (error) {
42
- return {
43
- content: [{ type: 'text', text: `✗ Error: ${error instanceof Error ? error.message : 'Unknown error'}` }]
44
- };
45
- }
46
- }
@@ -1,166 +0,0 @@
1
- // Planning tool - completely independent
2
- export const analyzeRequirementsDefinition = {
3
- name: 'analyze_requirements',
4
- description: '요구사항 분석|필요한 것들|requirements analysis|what we need|analyze requirements|필수 기능 - Analyze project requirements',
5
- inputSchema: {
6
- type: 'object',
7
- properties: {
8
- requirements: { type: 'string', description: 'List of requirements to analyze' },
9
- stakeholders: { type: 'string', description: 'Project stakeholders (e.g., users, admins, developers)' },
10
- constraints: { type: 'string', description: 'Project constraints (timeline, budget, technical)' },
11
- analysisMethod: { type: 'string', description: 'Analysis method', enum: ['moscow', 'kano', 'value-effort'], default: 'moscow' }
12
- },
13
- required: ['requirements']
14
- },
15
- annotations: {
16
- title: 'Analyze Requirements',
17
- audience: ['user', 'assistant']
18
- }
19
- };
20
- export async function analyzeRequirements(args) {
21
- const { requirements, stakeholders = 'end users, product owner, development team', constraints = 'standard timeline and budget constraints', analysisMethod = 'moscow' } = args;
22
- // Parse requirements
23
- const requirementList = requirements.split(/[,\n]/).map(r => r.trim()).filter(r => r.length > 0);
24
- const stakeholderList = stakeholders.split(',').map(s => s.trim());
25
- const analyzedRequirements = requirementList.map((req, index) => {
26
- const reqId = `REQ-${String(index + 1).padStart(3, '0')}`;
27
- // Determine requirement type
28
- let type = 'functional';
29
- if (req.toLowerCase().includes('performance') || req.toLowerCase().includes('security') || req.toLowerCase().includes('scalability')) {
30
- type = 'non-functional';
31
- }
32
- else if (req.toLowerCase().includes('business') || req.toLowerCase().includes('revenue') || req.toLowerCase().includes('cost')) {
33
- type = 'business';
34
- }
35
- else if (req.toLowerCase().includes('infrastructure') || req.toLowerCase().includes('architecture') || req.toLowerCase().includes('database')) {
36
- type = 'technical';
37
- }
38
- // Determine priority using MoSCoW
39
- let priority = 'should-have';
40
- if (req.toLowerCase().includes('critical') || req.toLowerCase().includes('essential') || req.toLowerCase().includes('required')) {
41
- priority = 'must-have';
42
- }
43
- else if (req.toLowerCase().includes('important') || req.toLowerCase().includes('needed')) {
44
- priority = 'should-have';
45
- }
46
- else if (req.toLowerCase().includes('nice') || req.toLowerCase().includes('optional') || req.toLowerCase().includes('enhancement')) {
47
- priority = 'could-have';
48
- }
49
- else if (req.toLowerCase().includes('future') || req.toLowerCase().includes('later') || req.toLowerCase().includes('v2')) {
50
- priority = 'wont-have';
51
- }
52
- // Assess complexity
53
- let complexity = 'medium';
54
- if (req.length > 100 || req.toLowerCase().includes('complex') || req.toLowerCase().includes('integration') || req.toLowerCase().includes('advanced')) {
55
- complexity = 'high';
56
- }
57
- else if (req.length < 50 || req.toLowerCase().includes('simple') || req.toLowerCase().includes('basic')) {
58
- complexity = 'low';
59
- }
60
- // Assess risk
61
- let risk = 'low';
62
- if (req.toLowerCase().includes('external') || req.toLowerCase().includes('third-party') || req.toLowerCase().includes('new technology')) {
63
- risk = 'high';
64
- }
65
- else if (req.toLowerCase().includes('integration') || req.toLowerCase().includes('performance') || complexity === 'high') {
66
- risk = 'medium';
67
- }
68
- // Estimate effort
69
- let estimatedEffort = '3-5 days';
70
- if (complexity === 'high') {
71
- estimatedEffort = '1-3 weeks';
72
- }
73
- else if (complexity === 'low') {
74
- estimatedEffort = '1-2 days';
75
- }
76
- // Determine relevant stakeholders
77
- const relevantStakeholders = stakeholderList.filter(stakeholder => {
78
- if (type === 'business' && stakeholder.toLowerCase().includes('owner'))
79
- return true;
80
- if (type === 'technical' && stakeholder.toLowerCase().includes('developer'))
81
- return true;
82
- if (type === 'functional' && stakeholder.toLowerCase().includes('user'))
83
- return true;
84
- return true; // Include all by default
85
- });
86
- return {
87
- id: reqId,
88
- title: req.length > 50 ? req.substring(0, 47) + '...' : req,
89
- description: req,
90
- type,
91
- priority,
92
- complexity,
93
- risk,
94
- dependencies: [],
95
- estimatedEffort,
96
- stakeholders: relevantStakeholders
97
- };
98
- });
99
- const analysis = {
100
- action: 'analyze_requirements',
101
- method: analysisMethod,
102
- totalRequirements: analyzedRequirements.length,
103
- requirements: analyzedRequirements,
104
- priorityBreakdown: {
105
- mustHave: analyzedRequirements.filter(r => r.priority === 'must-have').length,
106
- shouldHave: analyzedRequirements.filter(r => r.priority === 'should-have').length,
107
- couldHave: analyzedRequirements.filter(r => r.priority === 'could-have').length,
108
- wontHave: analyzedRequirements.filter(r => r.priority === 'wont-have').length
109
- },
110
- typeBreakdown: {
111
- functional: analyzedRequirements.filter(r => r.type === 'functional').length,
112
- nonFunctional: analyzedRequirements.filter(r => r.type === 'non-functional').length,
113
- business: analyzedRequirements.filter(r => r.type === 'business').length,
114
- technical: analyzedRequirements.filter(r => r.type === 'technical').length
115
- },
116
- riskAssessment: {
117
- high: analyzedRequirements.filter(r => r.risk === 'high').length,
118
- medium: analyzedRequirements.filter(r => r.risk === 'medium').length,
119
- low: analyzedRequirements.filter(r => r.risk === 'low').length
120
- },
121
- recommendations: [
122
- 'Focus on Must-Have requirements for MVP',
123
- 'Validate high-risk requirements early',
124
- 'Consider Should-Have items for post-MVP releases',
125
- 'Review Could-Have items based on resource availability',
126
- 'Plan technical requirements to support functional ones'
127
- ],
128
- constraints: constraints,
129
- status: 'success'
130
- };
131
- // Format output
132
- let formattedOutput = `# Requirements Analysis\n\n`;
133
- formattedOutput += `**Analysis Method:** ${analysisMethod.toUpperCase()} \n`;
134
- formattedOutput += `**Total Requirements:** ${analysis.totalRequirements} \n`;
135
- formattedOutput += `**Constraints:** ${constraints}\n\n`;
136
- formattedOutput += `## Priority Breakdown (MoSCoW)\n`;
137
- formattedOutput += `- **Must Have:** ${analysis.priorityBreakdown.mustHave}\n`;
138
- formattedOutput += `- **Should Have:** ${analysis.priorityBreakdown.shouldHave}\n`;
139
- formattedOutput += `- **Could Have:** ${analysis.priorityBreakdown.couldHave}\n`;
140
- formattedOutput += `- **Won't Have:** ${analysis.priorityBreakdown.wontHave}\n\n`;
141
- formattedOutput += `## Risk Assessment\n`;
142
- formattedOutput += `- **High Risk:** ${analysis.riskAssessment.high} requirements\n`;
143
- formattedOutput += `- **Medium Risk:** ${analysis.riskAssessment.medium} requirements\n`;
144
- formattedOutput += `- **Low Risk:** ${analysis.riskAssessment.low} requirements\n\n`;
145
- formattedOutput += `## Detailed Requirements\n\n`;
146
- // Group by priority
147
- const priorities = ['must-have', 'should-have', 'could-have', 'wont-have'];
148
- priorities.forEach(priority => {
149
- const reqsForPriority = analyzedRequirements.filter(r => r.priority === priority);
150
- if (reqsForPriority.length > 0) {
151
- formattedOutput += `### ${priority.toUpperCase().replace('-', ' ')} (${reqsForPriority.length})\n\n`;
152
- reqsForPriority.forEach(req => {
153
- formattedOutput += `**${req.id}:** ${req.title} \n`;
154
- formattedOutput += `*Type:* ${req.type} | *Complexity:* ${req.complexity} | *Risk:* ${req.risk} | *Effort:* ${req.estimatedEffort} \n`;
155
- formattedOutput += `*Stakeholders:* ${req.stakeholders.join(', ')}\n\n`;
156
- });
157
- }
158
- });
159
- formattedOutput += `## Recommendations\n`;
160
- analysis.recommendations.forEach(rec => {
161
- formattedOutput += `- ${rec}\n`;
162
- });
163
- return {
164
- content: [{ type: 'text', text: formattedOutput }]
165
- };
166
- }
@@ -1,119 +0,0 @@
1
- // Planning tool - completely independent
2
- export const createUserStoriesDefinition = {
3
- name: 'create_user_stories',
4
- description: '스토리|사용자 스토리|user story|user stories|as a user - Generate user stories from requirements',
5
- inputSchema: {
6
- type: 'object',
7
- properties: {
8
- features: { type: 'string', description: 'List of features or requirements to convert to user stories' },
9
- userTypes: { type: 'string', description: 'Types of users (e.g., admin, customer, guest)' },
10
- priority: { type: 'string', description: 'Default priority level', enum: ['high', 'medium', 'low'] },
11
- includeAcceptanceCriteria: { type: 'boolean', description: 'Include acceptance criteria for each story' }
12
- },
13
- required: ['features']
14
- },
15
- annotations: {
16
- title: 'Create User Stories',
17
- audience: ['user', 'assistant']
18
- }
19
- };
20
- export async function createUserStories(args) {
21
- const { features, userTypes = 'user, admin, guest', priority = 'medium', includeAcceptanceCriteria = true } = args;
22
- // Parse features into individual items
23
- const featureList = features.split(/[,\n]/).map(f => f.trim()).filter(f => f.length > 0);
24
- const userTypeList = userTypes.split(',').map(u => u.trim());
25
- const userStories = featureList.map((feature, index) => {
26
- const storyId = `US-${String(index + 1).padStart(3, '0')}`;
27
- // Determine user type based on feature content
28
- let selectedUserType = userTypeList[0];
29
- if (feature.toLowerCase().includes('admin') || feature.toLowerCase().includes('manage')) {
30
- selectedUserType = userTypeList.find(u => u.toLowerCase().includes('admin')) || selectedUserType;
31
- }
32
- else if (feature.toLowerCase().includes('guest') || feature.toLowerCase().includes('browse')) {
33
- selectedUserType = userTypeList.find(u => u.toLowerCase().includes('guest')) || selectedUserType;
34
- }
35
- // Extract functionality and benefit
36
- const functionality = feature;
37
- let benefit = 'to achieve my goals efficiently';
38
- // Try to infer benefit from common patterns
39
- if (feature.toLowerCase().includes('search'))
40
- benefit = 'to find relevant information quickly';
41
- else if (feature.toLowerCase().includes('save') || feature.toLowerCase().includes('store'))
42
- benefit = 'to preserve my data for future use';
43
- else if (feature.toLowerCase().includes('share'))
44
- benefit = 'to collaborate with others effectively';
45
- else if (feature.toLowerCase().includes('track') || feature.toLowerCase().includes('monitor'))
46
- benefit = 'to stay informed about important changes';
47
- else if (feature.toLowerCase().includes('customize') || feature.toLowerCase().includes('configure'))
48
- benefit = 'to tailor the experience to my needs';
49
- // Generate acceptance criteria
50
- const acceptanceCriteria = includeAcceptanceCriteria ? [
51
- `Given I am a ${selectedUserType}, when I access the ${functionality.toLowerCase()} feature, then it should be available and functional`,
52
- `When I use the ${functionality.toLowerCase()} feature, then it should provide clear feedback about the action`,
53
- `The ${functionality.toLowerCase()} feature should handle errors gracefully and provide helpful messages`,
54
- `The feature should be accessible and usable across different devices and browsers`
55
- ] : [];
56
- // Determine priority based on feature content
57
- let storyPriority = priority;
58
- if (feature.toLowerCase().includes('critical') || feature.toLowerCase().includes('security') || feature.toLowerCase().includes('login')) {
59
- storyPriority = 'high';
60
- }
61
- else if (feature.toLowerCase().includes('nice to have') || feature.toLowerCase().includes('optional')) {
62
- storyPriority = 'low';
63
- }
64
- // Estimate effort based on complexity
65
- let estimatedEffort = '3-5 days';
66
- if (feature.length > 100 || feature.toLowerCase().includes('complex') || feature.toLowerCase().includes('integration')) {
67
- estimatedEffort = '1-2 weeks';
68
- }
69
- else if (feature.length < 30 || feature.toLowerCase().includes('simple') || feature.toLowerCase().includes('basic')) {
70
- estimatedEffort = '1-2 days';
71
- }
72
- return {
73
- id: storyId,
74
- title: `${selectedUserType} - ${functionality}`,
75
- story: `As a ${selectedUserType}, I want to ${functionality.toLowerCase()}, so that ${benefit}.`,
76
- userType: selectedUserType,
77
- functionality,
78
- benefit,
79
- acceptanceCriteria,
80
- priority: storyPriority,
81
- estimatedEffort,
82
- dependencies: []
83
- };
84
- });
85
- const result = {
86
- action: 'create_user_stories',
87
- totalStories: userStories.length,
88
- userTypes: userTypeList,
89
- stories: userStories,
90
- summary: {
91
- high: userStories.filter(s => s.priority === 'high').length,
92
- medium: userStories.filter(s => s.priority === 'medium').length,
93
- low: userStories.filter(s => s.priority === 'low').length,
94
- estimatedTotalEffort: `${userStories.length * 3}-${userStories.length * 7} days`
95
- },
96
- status: 'success'
97
- };
98
- // Format output
99
- let formattedOutput = `# User Stories\n\n**Total Stories:** ${result.totalStories} \n**Priority Breakdown:** ${result.summary.high} High, ${result.summary.medium} Medium, ${result.summary.low} Low \n**Estimated Effort:** ${result.summary.estimatedTotalEffort}\n\n`;
100
- userStories.forEach((story, index) => {
101
- formattedOutput += `## ${story.id}: ${story.title}\n\n`;
102
- formattedOutput += `**Story:** ${story.story}\n\n`;
103
- formattedOutput += `**Priority:** ${story.priority.toUpperCase()} \n`;
104
- formattedOutput += `**Estimated Effort:** ${story.estimatedEffort}\n\n`;
105
- if (story.acceptanceCriteria.length > 0) {
106
- formattedOutput += `**Acceptance Criteria:**\n`;
107
- story.acceptanceCriteria.forEach((criteria, i) => {
108
- formattedOutput += `${i + 1}. ${criteria}\n`;
109
- });
110
- formattedOutput += '\n';
111
- }
112
- if (index < userStories.length - 1) {
113
- formattedOutput += '---\n\n';
114
- }
115
- });
116
- return {
117
- content: [{ type: 'text', text: formattedOutput }]
118
- };
119
- }
@@ -1,202 +0,0 @@
1
- // Planning tool - completely independent
2
- export const featureRoadmapDefinition = {
3
- name: 'feature_roadmap',
4
- description: '로드맵|일정|계획표|roadmap|timeline|project plan|development schedule - Generate development roadmap',
5
- inputSchema: {
6
- type: 'object',
7
- properties: {
8
- projectName: { type: 'string', description: 'Name of the project' },
9
- features: { type: 'string', description: 'List of features to include in roadmap' },
10
- timeframe: { type: 'string', description: 'Project timeframe', enum: ['3-months', '6-months', '12-months', 'custom'] },
11
- approach: { type: 'string', description: 'Development approach', enum: ['mvp-first', 'phased-rollout', 'big-bang'], default: 'mvp-first' },
12
- teamSize: { type: 'number', description: 'Development team size' }
13
- },
14
- required: ['projectName', 'features']
15
- },
16
- annotations: {
17
- title: 'Feature Roadmap',
18
- audience: ['user', 'assistant']
19
- }
20
- };
21
- export async function featureRoadmap(args) {
22
- const { projectName, features, timeframe = '6-months', approach = 'mvp-first', teamSize = 3 } = args;
23
- // Parse features
24
- const featureList = features.split(/[,\n]/).map(f => f.trim()).filter(f => f.length > 0);
25
- // Define phases based on approach
26
- let phaseNames = [];
27
- if (approach === 'mvp-first') {
28
- phaseNames = ['MVP Foundation', 'Core Features', 'Advanced Features', 'Optimization & Scaling'];
29
- }
30
- else if (approach === 'phased-rollout') {
31
- phaseNames = ['Phase 1: Core', 'Phase 2: Enhancement', 'Phase 3: Expansion', 'Phase 4: Innovation'];
32
- }
33
- else {
34
- phaseNames = ['Planning & Setup', 'Development Sprint', 'Integration & Testing', 'Launch & Monitoring'];
35
- }
36
- // Calculate phase durations
37
- const totalMonths = timeframe === '3-months' ? 3 : timeframe === '6-months' ? 6 : timeframe === '12-months' ? 12 : 6;
38
- const monthsPerPhase = Math.ceil(totalMonths / phaseNames.length);
39
- // Categorize features by priority and complexity
40
- const roadmapItems = featureList.map((feature, index) => {
41
- const itemId = `F-${String(index + 1).padStart(3, '0')}`;
42
- // Determine priority
43
- let priority = 'medium';
44
- if (feature.toLowerCase().includes('critical') || feature.toLowerCase().includes('core') || feature.toLowerCase().includes('essential')) {
45
- priority = 'high';
46
- }
47
- else if (feature.toLowerCase().includes('enhancement') || feature.toLowerCase().includes('nice') || feature.toLowerCase().includes('optional')) {
48
- priority = 'low';
49
- }
50
- // Determine phase based on priority and approach
51
- let phase = phaseNames[1]; // Default to second phase
52
- if (priority === 'high' || feature.toLowerCase().includes('mvp') || feature.toLowerCase().includes('basic')) {
53
- phase = phaseNames[0];
54
- }
55
- else if (priority === 'low' || feature.toLowerCase().includes('advanced') || feature.toLowerCase().includes('future')) {
56
- phase = phaseNames[Math.min(2, phaseNames.length - 1)];
57
- }
58
- // Estimate duration
59
- let estimatedDuration = '2-3 weeks';
60
- if (feature.length > 100 || feature.toLowerCase().includes('complex') || feature.toLowerCase().includes('integration')) {
61
- estimatedDuration = '4-6 weeks';
62
- }
63
- else if (feature.length < 50 || feature.toLowerCase().includes('simple')) {
64
- estimatedDuration = '1-2 weeks';
65
- }
66
- // Generate deliverables
67
- const deliverables = [
68
- `${feature} implementation`,
69
- `Unit and integration tests`,
70
- `Documentation and user guides`,
71
- `Code review and quality assurance`
72
- ];
73
- // Generate success criteria
74
- const successCriteria = [
75
- `Feature functions as specified`,
76
- `Meets performance requirements`,
77
- `Passes all test cases`,
78
- `User acceptance criteria met`
79
- ];
80
- // Identify potential risks
81
- const risks = [];
82
- if (feature.toLowerCase().includes('external') || feature.toLowerCase().includes('third-party')) {
83
- risks.push('External dependency risk');
84
- }
85
- if (feature.toLowerCase().includes('performance') || feature.toLowerCase().includes('scalability')) {
86
- risks.push('Performance optimization complexity');
87
- }
88
- if (feature.toLowerCase().includes('security') || feature.toLowerCase().includes('authentication')) {
89
- risks.push('Security implementation complexity');
90
- }
91
- if (risks.length === 0) {
92
- risks.push('Standard development risks');
93
- }
94
- return {
95
- id: itemId,
96
- title: feature.length > 50 ? feature.substring(0, 47) + '...' : feature,
97
- description: feature,
98
- phase,
99
- priority,
100
- estimatedDuration,
101
- dependencies: [],
102
- deliverables,
103
- successCriteria,
104
- risks
105
- };
106
- });
107
- // Group features by phase
108
- const phases = phaseNames.map((phaseName, index) => {
109
- const phaseFeatures = roadmapItems.filter(item => item.phase === phaseName);
110
- const phaseGoals = [];
111
- if (index === 0) {
112
- phaseGoals.push('Establish core functionality', 'Validate core assumptions', 'Build foundation for future features');
113
- }
114
- else if (index === 1) {
115
- phaseGoals.push('Enhance user experience', 'Add key differentiating features', 'Improve system reliability');
116
- }
117
- else if (index === 2) {
118
- phaseGoals.push('Scale system capabilities', 'Add advanced features', 'Optimize performance');
119
- }
120
- else {
121
- phaseGoals.push('Continuous improvement', 'Innovation and experimentation', 'Long-term sustainability');
122
- }
123
- const milestones = [
124
- `${phaseName} features delivered`,
125
- `Quality assurance completed`,
126
- `User feedback incorporated`,
127
- `Metrics and KPIs reviewed`
128
- ];
129
- return {
130
- name: phaseName,
131
- duration: `${monthsPerPhase} month${monthsPerPhase > 1 ? 's' : ''}`,
132
- goals: phaseGoals,
133
- features: phaseFeatures,
134
- milestones
135
- };
136
- });
137
- const roadmap = {
138
- action: 'feature_roadmap',
139
- project: projectName,
140
- timeframe,
141
- approach,
142
- teamSize,
143
- phases,
144
- summary: {
145
- totalFeatures: roadmapItems.length,
146
- totalDuration: `${totalMonths} months`,
147
- highPriorityFeatures: roadmapItems.filter(f => f.priority === 'high').length,
148
- mediumPriorityFeatures: roadmapItems.filter(f => f.priority === 'medium').length,
149
- lowPriorityFeatures: roadmapItems.filter(f => f.priority === 'low').length
150
- },
151
- recommendations: [
152
- 'Review and validate priorities with stakeholders',
153
- 'Set up regular milestone reviews and adjustments',
154
- 'Plan for buffer time between phases for testing',
155
- 'Consider team capacity and external dependencies',
156
- 'Establish clear success metrics for each phase'
157
- ],
158
- status: 'success'
159
- };
160
- // Format output
161
- let formattedOutput = `# ${projectName} - Feature Roadmap\n\n`;
162
- formattedOutput += `**Timeframe:** ${timeframe} \n`;
163
- formattedOutput += `**Approach:** ${approach} \n`;
164
- formattedOutput += `**Team Size:** ${teamSize} developers \n`;
165
- formattedOutput += `**Total Features:** ${roadmap.summary.totalFeatures}\n\n`;
166
- formattedOutput += `## Overview\n`;
167
- formattedOutput += `- **High Priority:** ${roadmap.summary.highPriorityFeatures} features\n`;
168
- formattedOutput += `- **Medium Priority:** ${roadmap.summary.mediumPriorityFeatures} features\n`;
169
- formattedOutput += `- **Low Priority:** ${roadmap.summary.lowPriorityFeatures} features\n\n`;
170
- phases.forEach((phase, index) => {
171
- formattedOutput += `## ${phase.name}\n`;
172
- formattedOutput += `**Duration:** ${phase.duration} \n`;
173
- formattedOutput += `**Features:** ${phase.features.length}\n\n`;
174
- formattedOutput += `### Goals\n`;
175
- phase.goals.forEach(goal => {
176
- formattedOutput += `- ${goal}\n`;
177
- });
178
- formattedOutput += '\n';
179
- if (phase.features.length > 0) {
180
- formattedOutput += `### Features\n`;
181
- phase.features.forEach(feature => {
182
- formattedOutput += `**${feature.id}:** ${feature.title} (${feature.priority.toUpperCase()}) \n`;
183
- formattedOutput += `*Duration:* ${feature.estimatedDuration} \n`;
184
- formattedOutput += `*Key Risks:* ${feature.risks.join(', ')}\n\n`;
185
- });
186
- }
187
- formattedOutput += `### Milestones\n`;
188
- phase.milestones.forEach(milestone => {
189
- formattedOutput += `- ${milestone}\n`;
190
- });
191
- if (index < phases.length - 1) {
192
- formattedOutput += '\n---\n\n';
193
- }
194
- });
195
- formattedOutput += `\n## Recommendations\n`;
196
- roadmap.recommendations.forEach(rec => {
197
- formattedOutput += `- ${rec}\n`;
198
- });
199
- return {
200
- content: [{ type: 'text', text: formattedOutput }]
201
- };
202
- }