@su-record/vibe 0.1.3 → 0.1.7

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 (73) hide show
  1. package/.claude/commands/vibe.analyze.md +123 -0
  2. package/.claude/commands/vibe.diagram.md +174 -0
  3. package/.claude/commands/vibe.plan.md +75 -0
  4. package/.claude/commands/vibe.run.md +151 -0
  5. package/.claude/commands/vibe.spec.md +273 -0
  6. package/.claude/commands/vibe.tasks.md +77 -0
  7. package/.claude/commands/vibe.ui.md +133 -0
  8. package/.claude/commands/vibe.verify.md +128 -0
  9. package/.claude/settings.local.json +14 -0
  10. package/README.md +170 -108
  11. package/bin/vibe +113 -226
  12. package/package.json +7 -7
  13. package/scripts/install-mcp.js +16 -6
  14. package/skills/quality/bdd-contract-testing.md +388 -0
  15. package/templates/contract-backend-template.md +517 -0
  16. package/templates/contract-frontend-template.md +594 -0
  17. package/templates/feature-template.md +259 -0
  18. package/templates/spec-template.md +60 -3
  19. package/mcp/dist/__tests__/complexity.test.js +0 -126
  20. package/mcp/dist/__tests__/memory.test.js +0 -120
  21. package/mcp/dist/__tests__/python-dart-complexity.test.js +0 -146
  22. package/mcp/dist/index.js +0 -230
  23. package/mcp/dist/lib/ContextCompressor.js +0 -305
  24. package/mcp/dist/lib/MemoryManager.js +0 -334
  25. package/mcp/dist/lib/ProjectCache.js +0 -126
  26. package/mcp/dist/lib/PythonParser.js +0 -241
  27. package/mcp/dist/tools/browser/browserPool.js +0 -76
  28. package/mcp/dist/tools/browser/browserUtils.js +0 -135
  29. package/mcp/dist/tools/browser/inspectNetworkRequests.js +0 -140
  30. package/mcp/dist/tools/browser/monitorConsoleLogs.js +0 -97
  31. package/mcp/dist/tools/convention/analyzeComplexity.js +0 -248
  32. package/mcp/dist/tools/convention/applyQualityRules.js +0 -102
  33. package/mcp/dist/tools/convention/checkCouplingCohesion.js +0 -233
  34. package/mcp/dist/tools/convention/complexityMetrics.js +0 -133
  35. package/mcp/dist/tools/convention/dartComplexity.js +0 -117
  36. package/mcp/dist/tools/convention/getCodingGuide.js +0 -64
  37. package/mcp/dist/tools/convention/languageDetector.js +0 -50
  38. package/mcp/dist/tools/convention/pythonComplexity.js +0 -109
  39. package/mcp/dist/tools/convention/suggestImprovements.js +0 -257
  40. package/mcp/dist/tools/convention/validateCodeQuality.js +0 -177
  41. package/mcp/dist/tools/memory/autoSaveContext.js +0 -79
  42. package/mcp/dist/tools/memory/database.js +0 -123
  43. package/mcp/dist/tools/memory/deleteMemory.js +0 -39
  44. package/mcp/dist/tools/memory/listMemories.js +0 -38
  45. package/mcp/dist/tools/memory/memoryConfig.js +0 -27
  46. package/mcp/dist/tools/memory/memorySQLite.js +0 -138
  47. package/mcp/dist/tools/memory/memoryUtils.js +0 -34
  48. package/mcp/dist/tools/memory/migrate.js +0 -113
  49. package/mcp/dist/tools/memory/prioritizeMemory.js +0 -109
  50. package/mcp/dist/tools/memory/recallMemory.js +0 -40
  51. package/mcp/dist/tools/memory/restoreSessionContext.js +0 -69
  52. package/mcp/dist/tools/memory/saveMemory.js +0 -34
  53. package/mcp/dist/tools/memory/searchMemories.js +0 -37
  54. package/mcp/dist/tools/memory/startSession.js +0 -100
  55. package/mcp/dist/tools/memory/updateMemory.js +0 -46
  56. package/mcp/dist/tools/planning/analyzeRequirements.js +0 -166
  57. package/mcp/dist/tools/planning/createUserStories.js +0 -119
  58. package/mcp/dist/tools/planning/featureRoadmap.js +0 -202
  59. package/mcp/dist/tools/planning/generatePrd.js +0 -156
  60. package/mcp/dist/tools/prompt/analyzePrompt.js +0 -145
  61. package/mcp/dist/tools/prompt/enhancePrompt.js +0 -105
  62. package/mcp/dist/tools/semantic/findReferences.js +0 -195
  63. package/mcp/dist/tools/semantic/findSymbol.js +0 -200
  64. package/mcp/dist/tools/thinking/analyzeProblem.js +0 -50
  65. package/mcp/dist/tools/thinking/breakDownProblem.js +0 -140
  66. package/mcp/dist/tools/thinking/createThinkingChain.js +0 -39
  67. package/mcp/dist/tools/thinking/formatAsPlan.js +0 -73
  68. package/mcp/dist/tools/thinking/stepByStepAnalysis.js +0 -58
  69. package/mcp/dist/tools/thinking/thinkAloudProcess.js +0 -75
  70. package/mcp/dist/tools/time/getCurrentTime.js +0 -61
  71. package/mcp/dist/tools/ui/previewUiAscii.js +0 -232
  72. package/mcp/dist/types/tool.js +0 -2
  73. package/mcp/package.json +0 -53
@@ -1,76 +0,0 @@
1
- // Browser instance pool for efficient resource management
2
- import puppeteer from 'puppeteer-core';
3
- import { getBrowserLaunchOptions } from './browserUtils.js';
4
- class BrowserPool {
5
- browser = null;
6
- lastUsed = 0;
7
- IDLE_TIMEOUT = 5 * 60 * 1000; // 5 minutes
8
- cleanupTimer = null;
9
- /**
10
- * Get or create browser instance
11
- */
12
- async getBrowser() {
13
- // If browser exists and is connected, return it
14
- if (this.browser && this.browser.isConnected()) {
15
- this.lastUsed = Date.now();
16
- this.scheduleCleanup();
17
- return this.browser;
18
- }
19
- // Create new browser instance
20
- const options = getBrowserLaunchOptions();
21
- this.browser = await puppeteer.launch(options);
22
- this.lastUsed = Date.now();
23
- this.scheduleCleanup();
24
- return this.browser;
25
- }
26
- /**
27
- * Schedule automatic cleanup of idle browser
28
- */
29
- scheduleCleanup() {
30
- // Clear existing timer
31
- if (this.cleanupTimer) {
32
- clearTimeout(this.cleanupTimer);
33
- }
34
- // Set new timer
35
- this.cleanupTimer = setTimeout(async () => {
36
- const idleTime = Date.now() - this.lastUsed;
37
- if (idleTime >= this.IDLE_TIMEOUT) {
38
- await this.closeBrowser();
39
- }
40
- }, this.IDLE_TIMEOUT);
41
- }
42
- /**
43
- * Manually close browser instance
44
- */
45
- async closeBrowser() {
46
- if (this.cleanupTimer) {
47
- clearTimeout(this.cleanupTimer);
48
- this.cleanupTimer = null;
49
- }
50
- if (this.browser && this.browser.isConnected()) {
51
- await this.browser.close();
52
- this.browser = null;
53
- }
54
- }
55
- /**
56
- * Get a new page from the browser pool
57
- */
58
- async getPage() {
59
- const browser = await this.getBrowser();
60
- return await browser.newPage();
61
- }
62
- }
63
- // Singleton instance
64
- export const browserPool = new BrowserPool();
65
- // Cleanup on process exit
66
- process.on('exit', () => {
67
- browserPool.closeBrowser();
68
- });
69
- process.on('SIGINT', async () => {
70
- await browserPool.closeBrowser();
71
- process.exit(0);
72
- });
73
- process.on('SIGTERM', async () => {
74
- await browserPool.closeBrowser();
75
- process.exit(0);
76
- });
@@ -1,135 +0,0 @@
1
- // Browser utility functions for finding Chrome/Chromium executables
2
- import { existsSync } from 'fs';
3
- import { execSync } from 'child_process';
4
- import { platform } from 'os';
5
- /**
6
- * Finds Chrome or Chromium executable path on the system
7
- */
8
- export function findChromePath() {
9
- const platformName = platform();
10
- // Platform-specific paths for Chrome
11
- const chromePaths = {
12
- win32: [
13
- process.env.LOCALAPPDATA + '\\Google\\Chrome\\Application\\chrome.exe',
14
- process.env.PROGRAMFILES + '\\Google\\Chrome\\Application\\chrome.exe',
15
- process.env['PROGRAMFILES(X86)'] + '\\Google\\Chrome\\Application\\chrome.exe',
16
- 'C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe',
17
- 'C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe',
18
- ],
19
- darwin: [
20
- '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome',
21
- '/Applications/Google Chrome Canary.app/Contents/MacOS/Google Chrome Canary',
22
- '/Applications/Chromium.app/Contents/MacOS/Chromium',
23
- ],
24
- linux: [
25
- '/usr/bin/google-chrome-stable',
26
- '/usr/bin/google-chrome',
27
- '/usr/bin/chromium-browser',
28
- '/usr/bin/chromium',
29
- '/snap/bin/chromium',
30
- ]
31
- };
32
- // Platform-specific paths for Edge (as fallback)
33
- const edgePaths = {
34
- win32: [
35
- process.env['PROGRAMFILES(X86)'] + '\\Microsoft\\Edge\\Application\\msedge.exe',
36
- process.env.PROGRAMFILES + '\\Microsoft\\Edge\\Application\\msedge.exe',
37
- 'C:\\Program Files (x86)\\Microsoft\\Edge\\Application\\msedge.exe',
38
- 'C:\\Program Files\\Microsoft\\Edge\\Application\\msedge.exe',
39
- ],
40
- darwin: [
41
- '/Applications/Microsoft Edge.app/Contents/MacOS/Microsoft Edge',
42
- ],
43
- linux: [
44
- '/usr/bin/microsoft-edge',
45
- '/usr/bin/microsoft-edge-stable',
46
- ]
47
- };
48
- // Platform-specific paths for Brave (as fallback)
49
- const bravePaths = {
50
- win32: [
51
- process.env.LOCALAPPDATA + '\\BraveSoftware\\Brave-Browser\\Application\\brave.exe',
52
- process.env.PROGRAMFILES + '\\BraveSoftware\\Brave-Browser\\Application\\brave.exe',
53
- process.env['PROGRAMFILES(X86)'] + '\\BraveSoftware\\Brave-Browser\\Application\\brave.exe',
54
- ],
55
- darwin: [
56
- '/Applications/Brave Browser.app/Contents/MacOS/Brave Browser',
57
- ],
58
- linux: [
59
- '/usr/bin/brave-browser',
60
- '/usr/bin/brave',
61
- '/snap/bin/brave',
62
- ]
63
- };
64
- // Check user-specified path first
65
- if (process.env.CHROME_PATH && existsSync(process.env.CHROME_PATH)) {
66
- return process.env.CHROME_PATH;
67
- }
68
- // Get paths for current platform
69
- const currentPlatform = platformName === 'win32' ? 'win32' :
70
- platformName === 'darwin' ? 'darwin' : 'linux';
71
- const allPaths = [
72
- ...(chromePaths[currentPlatform] || []),
73
- ...(edgePaths[currentPlatform] || []),
74
- ...(bravePaths[currentPlatform] || [])
75
- ];
76
- // Find first existing path
77
- for (const path of allPaths) {
78
- if (path && existsSync(path)) {
79
- return path;
80
- }
81
- }
82
- // Try to find Chrome using 'which' command on Unix systems
83
- if (platformName !== 'win32') {
84
- try {
85
- const chromePath = execSync('which google-chrome || which chromium || which chromium-browser', {
86
- encoding: 'utf8'
87
- }).trim();
88
- if (chromePath && existsSync(chromePath)) {
89
- return chromePath;
90
- }
91
- }
92
- catch {
93
- // Command failed, continue to next method
94
- }
95
- }
96
- // Try to find Chrome using 'where' command on Windows
97
- if (platformName === 'win32') {
98
- try {
99
- const chromePath = execSync('where chrome', { encoding: 'utf8' }).trim().split('\n')[0];
100
- if (chromePath && existsSync(chromePath)) {
101
- return chromePath;
102
- }
103
- }
104
- catch {
105
- // Command failed, continue
106
- }
107
- }
108
- return undefined;
109
- }
110
- /**
111
- * Get launch options for puppeteer with proper browser configuration
112
- */
113
- export function getBrowserLaunchOptions(additionalOptions = {}) {
114
- const executablePath = findChromePath();
115
- if (!executablePath) {
116
- throw new Error('Chrome/Chromium browser not found. Please install Chrome or set CHROME_PATH environment variable.\n' +
117
- 'Download Chrome from: https://www.google.com/chrome/\n' +
118
- 'Or set environment variable: export CHROME_PATH="/path/to/chrome"');
119
- }
120
- return {
121
- headless: true,
122
- executablePath,
123
- args: [
124
- '--no-sandbox',
125
- '--disable-setuid-sandbox',
126
- '--disable-dev-shm-usage',
127
- '--disable-accelerated-2d-canvas',
128
- '--no-first-run',
129
- '--no-zygote',
130
- '--single-process', // For Windows compatibility
131
- '--disable-gpu'
132
- ],
133
- ...additionalOptions
134
- };
135
- }
@@ -1,140 +0,0 @@
1
- // Browser development tool - completely independent
2
- import puppeteer from 'puppeteer-core';
3
- import { getBrowserLaunchOptions } from './browserUtils.js';
4
- export const inspectNetworkRequestsDefinition = {
5
- name: 'inspect_network_requests',
6
- description: '네트워크|API 호출|요청 확인|network|API calls|check requests|network traffic - Inspect network requests',
7
- inputSchema: {
8
- type: 'object',
9
- properties: {
10
- url: { type: 'string', description: 'URL to inspect' },
11
- filterType: { type: 'string', description: 'Request type filter', enum: ['all', 'xhr', 'fetch', 'websocket', 'failed'] },
12
- includeHeaders: { type: 'boolean', description: 'Include request/response headers' }
13
- },
14
- required: ['url']
15
- },
16
- annotations: {
17
- title: 'Inspect Network Requests',
18
- audience: ['user', 'assistant']
19
- }
20
- };
21
- export async function inspectNetworkRequests(args) {
22
- const { url: inspectUrl, filterType = 'all', includeHeaders = false } = args;
23
- try {
24
- // Get browser launch options with proper executable path
25
- const launchOptions = getBrowserLaunchOptions();
26
- const browser = await puppeteer.launch(launchOptions);
27
- const page = await browser.newPage();
28
- const networkRequests = [];
29
- let requestId = 0;
30
- const requestTimings = new Map();
31
- // Capture network requests
32
- page.on('request', request => {
33
- const startTime = Date.now();
34
- const id = `req_${String(requestId++).padStart(3, '0')}`;
35
- const requestUrl = request.url();
36
- requestTimings.set(requestUrl, startTime);
37
- networkRequests.push({
38
- id,
39
- url: requestUrl,
40
- method: request.method(),
41
- type: request.resourceType(),
42
- responseTime: 0,
43
- size: 0,
44
- timestamp: new Date().toISOString(),
45
- headers: includeHeaders ? {
46
- request: request.headers()
47
- } : undefined
48
- });
49
- });
50
- page.on('response', async (response) => {
51
- const requestUrl = response.url();
52
- const request = networkRequests.find(req => req.url === requestUrl);
53
- const startTime = requestTimings.get(requestUrl);
54
- if (request) {
55
- request.status = response.status();
56
- request.statusText = response.statusText();
57
- request.responseTime = startTime ? Date.now() - startTime : 0;
58
- request.failed = !response.ok();
59
- if (includeHeaders && request.headers) {
60
- request.headers.response = response.headers();
61
- }
62
- // Estimate response size
63
- try {
64
- const buffer = await response.buffer();
65
- request.size = buffer.length;
66
- }
67
- catch {
68
- request.size = 0;
69
- }
70
- }
71
- });
72
- page.on('requestfailed', request => {
73
- const requestUrl = request.url();
74
- const failedRequest = networkRequests.find(req => req.url === requestUrl);
75
- if (failedRequest) {
76
- failedRequest.failed = true;
77
- failedRequest.status = 0;
78
- failedRequest.statusText = request.failure()?.errorText || 'Failed';
79
- }
80
- });
81
- // Navigate to URL and wait for network to be idle
82
- await page.goto(inspectUrl, { waitUntil: 'networkidle0', timeout: 30000 });
83
- // Wait a bit for any remaining requests
84
- await new Promise(resolve => setTimeout(resolve, 2000));
85
- await browser.close();
86
- const filteredRequests = networkRequests.filter(req => {
87
- switch (filterType) {
88
- case 'xhr':
89
- return req.type === 'xhr';
90
- case 'fetch':
91
- return req.type === 'fetch';
92
- case 'websocket':
93
- return req.type === 'websocket';
94
- case 'failed':
95
- return req.failed || (req.status !== undefined && req.status >= 400);
96
- default:
97
- return true;
98
- }
99
- });
100
- const networkInspectionResult = {
101
- action: 'inspect_network_requests',
102
- url: inspectUrl,
103
- filterType,
104
- includeHeaders,
105
- requests: filteredRequests,
106
- summary: {
107
- totalRequests: filteredRequests.length,
108
- successful: filteredRequests.filter(r => r.status !== undefined && r.status >= 200 && r.status < 300).length,
109
- failed: filteredRequests.filter(r => r.failed || (r.status !== undefined && r.status >= 400)).length,
110
- averageResponseTime: filteredRequests.reduce((sum, r) => sum + r.responseTime, 0) / filteredRequests.length,
111
- totalDataTransferred: filteredRequests.reduce((sum, r) => sum + r.size, 0),
112
- requestTypes: {
113
- xhr: filteredRequests.filter(r => r.type === 'xhr').length,
114
- fetch: filteredRequests.filter(r => r.type === 'fetch').length,
115
- websocket: filteredRequests.filter(r => r.type === 'websocket').length
116
- }
117
- },
118
- status: 'success'
119
- };
120
- // Compact summary format
121
- const failed = filteredRequests.filter(r => r.failed || (r.status !== undefined && r.status >= 400));
122
- const errorSummary = failed.length > 0
123
- ? `\nErrors: ${failed.slice(0, 3).map(r => `${r.method} ${new URL(r.url).pathname} (${r.status})`).join(', ')}${failed.length > 3 ? ` +${failed.length - 3}` : ''}`
124
- : '';
125
- return {
126
- content: [{
127
- type: 'text',
128
- text: `${networkInspectionResult.summary.totalRequests} reqs | ${networkInspectionResult.summary.successful} OK, ${networkInspectionResult.summary.failed} fail | Avg: ${networkInspectionResult.summary.averageResponseTime.toFixed(0)}ms | ${(networkInspectionResult.summary.totalDataTransferred / 1024).toFixed(1)}KB${errorSummary}`
129
- }]
130
- };
131
- }
132
- catch (error) {
133
- const errorMessage = error instanceof Error ? error.message : 'Unknown error';
134
- const helpMessage = errorMessage.includes('Chrome') ?
135
- '\n\nTroubleshooting:\n1. Install Chrome: https://www.google.com/chrome/\n2. Or set CHROME_PATH environment variable\n3. Or install puppeteer instead of puppeteer-core' : '';
136
- return {
137
- content: [{ type: 'text', text: `Error inspecting network requests: ${errorMessage}${helpMessage}` }]
138
- };
139
- }
140
- }
@@ -1,97 +0,0 @@
1
- // Browser development tool - completely independent
2
- import puppeteer from 'puppeteer-core';
3
- import { getBrowserLaunchOptions } from './browserUtils.js';
4
- export const monitorConsoleLogsDefinition = {
5
- name: 'monitor_console_logs',
6
- description: '콘솔 로그|에러 확인|로그 봐줘|console|check logs|debug output|console errors - Monitor browser console',
7
- inputSchema: {
8
- type: 'object',
9
- properties: {
10
- url: { type: 'string', description: 'URL to monitor' },
11
- logLevel: { type: 'string', description: 'Log level to capture', enum: ['all', 'error', 'warn', 'info', 'debug'] },
12
- duration: { type: 'number', description: 'Monitoring duration in seconds' }
13
- },
14
- required: ['url']
15
- },
16
- annotations: {
17
- title: 'Monitor Console Logs',
18
- audience: ['user', 'assistant']
19
- }
20
- };
21
- export async function monitorConsoleLogs(args) {
22
- const { url: monitorUrl, logLevel = 'all', duration = 30 } = args;
23
- try {
24
- // Get browser launch options with proper executable path
25
- const launchOptions = getBrowserLaunchOptions();
26
- const browser = await puppeteer.launch(launchOptions);
27
- const page = await browser.newPage();
28
- const logs = [];
29
- // Capture console events
30
- page.on('console', msg => {
31
- const msgLevel = msg.type();
32
- if (logLevel === 'all' || msgLevel === logLevel) {
33
- logs.push({
34
- timestamp: new Date().toISOString(),
35
- level: msgLevel,
36
- message: msg.text(),
37
- source: msg.location()?.url || 'unknown'
38
- });
39
- }
40
- });
41
- // Capture page errors
42
- page.on('pageerror', error => {
43
- if (logLevel === 'all' || logLevel === 'error') {
44
- logs.push({
45
- timestamp: new Date().toISOString(),
46
- level: 'error',
47
- message: error.message,
48
- source: error.stack?.split('\n')[0] || 'unknown'
49
- });
50
- }
51
- });
52
- // Navigate to URL and wait for specified duration
53
- await page.goto(monitorUrl, { waitUntil: 'networkidle0', timeout: 30000 });
54
- await new Promise(resolve => setTimeout(resolve, duration * 1000));
55
- await browser.close();
56
- const consoleMonitorResult = {
57
- action: 'monitor_console_logs',
58
- url: monitorUrl,
59
- logLevel,
60
- duration,
61
- capturedLogs: logs,
62
- summary: {
63
- totalLogs: logs.length,
64
- errors: logs.filter(l => l.level === 'error').length,
65
- warnings: logs.filter(l => l.level === 'warn').length,
66
- infos: logs.filter(l => l.level === 'info').length,
67
- debugs: logs.filter(l => l.level === 'debug').length,
68
- logs: logs.filter(l => l.level === 'log').length
69
- },
70
- monitoringStatus: 'completed',
71
- status: 'success'
72
- };
73
- // Compact summary with errors only
74
- const errors = logs.filter(l => l.level === 'error');
75
- const warnings = logs.filter(l => l.level === 'warn');
76
- const errorSummary = errors.length > 0
77
- ? `\nErrors: ${errors.slice(0, 3).map(l => l.message.substring(0, 50)).join(', ')}${errors.length > 3 ? ` +${errors.length - 3}` : ''}`
78
- : '';
79
- const warnSummary = warnings.length > 0 && errors.length === 0
80
- ? `\nWarnings: ${warnings.slice(0, 3).map(l => l.message.substring(0, 50)).join(', ')}${warnings.length > 3 ? ` +${warnings.length - 3}` : ''}`
81
- : '';
82
- return {
83
- content: [{
84
- type: 'text',
85
- text: `${logs.length} logs | ${consoleMonitorResult.summary.errors}E ${consoleMonitorResult.summary.warnings}W ${consoleMonitorResult.summary.infos}I | ${duration}s${errorSummary}${warnSummary}`
86
- }]
87
- };
88
- }
89
- catch (error) {
90
- const errorMessage = error instanceof Error ? error.message : 'Unknown error';
91
- const helpMessage = errorMessage.includes('Chrome') ?
92
- '\n\nTroubleshooting:\n1. Install Chrome: https://www.google.com/chrome/\n2. Or set CHROME_PATH environment variable\n3. Or install puppeteer instead of puppeteer-core' : '';
93
- return {
94
- content: [{ type: 'text', text: `Error monitoring console logs: ${errorMessage}${helpMessage}` }]
95
- };
96
- }
97
- }