@su-record/vibe 2.3.0 → 2.3.2
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.
- package/.claude/settings.json +35 -35
- package/.claude/settings.local.json +24 -25
- package/.claude/vibe/constitution.md +184 -184
- package/.claude/vibe/rules/core/communication-guide.md +104 -104
- package/.claude/vibe/rules/core/development-philosophy.md +52 -52
- package/.claude/vibe/rules/core/quick-start.md +120 -120
- package/.claude/vibe/rules/languages/dart-flutter.md +509 -509
- package/.claude/vibe/rules/languages/go.md +396 -396
- package/.claude/vibe/rules/languages/java-spring.md +586 -586
- package/.claude/vibe/rules/languages/kotlin-android.md +491 -491
- package/.claude/vibe/rules/languages/python-django.md +371 -371
- package/.claude/vibe/rules/languages/python-fastapi.md +386 -386
- package/.claude/vibe/rules/languages/rust.md +425 -425
- package/.claude/vibe/rules/languages/swift-ios.md +516 -516
- package/.claude/vibe/rules/languages/typescript-nextjs.md +441 -441
- package/.claude/vibe/rules/languages/typescript-node.md +375 -375
- package/.claude/vibe/rules/languages/typescript-nuxt.md +521 -521
- package/.claude/vibe/rules/languages/typescript-react-native.md +446 -446
- package/.claude/vibe/rules/languages/typescript-react.md +525 -525
- package/.claude/vibe/rules/languages/typescript-vue.md +353 -353
- package/.claude/vibe/rules/quality/bdd-contract-testing.md +388 -388
- package/.claude/vibe/rules/quality/checklist.md +276 -276
- package/.claude/vibe/rules/quality/testing-strategy.md +437 -437
- package/.claude/vibe/rules/standards/anti-patterns.md +369 -369
- package/.claude/vibe/rules/standards/code-structure.md +291 -291
- package/.claude/vibe/rules/standards/complexity-metrics.md +312 -312
- package/.claude/vibe/rules/standards/naming-conventions.md +198 -198
- package/.claude/vibe/setup.sh +31 -31
- package/.claude/vibe/templates/constitution-template.md +184 -184
- package/.claude/vibe/templates/contract-backend-template.md +517 -517
- package/.claude/vibe/templates/contract-frontend-template.md +594 -594
- package/.claude/vibe/templates/feature-template.md +96 -96
- package/.claude/vibe/templates/spec-template.md +199 -199
- package/CLAUDE.md +345 -323
- package/LICENSE +21 -21
- package/README.md +744 -724
- package/agents/compounder.md +261 -261
- package/agents/diagrammer.md +178 -178
- package/agents/e2e-tester.md +266 -266
- package/agents/explorer.md +48 -48
- package/agents/implementer.md +53 -53
- package/agents/research/best-practices-agent.md +139 -139
- package/agents/research/codebase-patterns-agent.md +147 -147
- package/agents/research/framework-docs-agent.md +181 -181
- package/agents/research/security-advisory-agent.md +167 -167
- package/agents/review/architecture-reviewer.md +107 -107
- package/agents/review/complexity-reviewer.md +116 -116
- package/agents/review/data-integrity-reviewer.md +88 -88
- package/agents/review/git-history-reviewer.md +103 -103
- package/agents/review/performance-reviewer.md +86 -86
- package/agents/review/python-reviewer.md +152 -152
- package/agents/review/rails-reviewer.md +139 -139
- package/agents/review/react-reviewer.md +144 -144
- package/agents/review/security-reviewer.md +80 -80
- package/agents/review/simplicity-reviewer.md +140 -140
- package/agents/review/test-coverage-reviewer.md +116 -116
- package/agents/review/typescript-reviewer.md +127 -127
- package/agents/searcher.md +54 -54
- package/agents/simplifier.md +119 -119
- package/agents/tester.md +49 -49
- package/agents/ui-previewer.md +137 -137
- package/commands/vibe.analyze.md +245 -180
- package/commands/vibe.reason.md +223 -183
- package/commands/vibe.review.md +200 -136
- package/commands/vibe.run.md +838 -836
- package/commands/vibe.spec.md +419 -383
- package/commands/vibe.utils.md +101 -101
- package/commands/vibe.verify.md +282 -241
- package/dist/cli/index.js +385 -385
- package/dist/lib/MemoryManager.d.ts.map +1 -1
- package/dist/lib/MemoryManager.js +119 -114
- package/dist/lib/MemoryManager.js.map +1 -1
- package/dist/lib/PythonParser.js +108 -108
- package/dist/lib/gemini-mcp.js +15 -15
- package/dist/lib/gemini-oauth.js +35 -35
- package/dist/lib/gpt-mcp.js +17 -17
- package/dist/lib/gpt-oauth.js +44 -44
- package/dist/tools/analytics/getUsageAnalytics.js +12 -12
- package/dist/tools/index.d.ts +50 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +61 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/memory/createMemoryTimeline.js +10 -10
- package/dist/tools/memory/getMemoryGraph.js +12 -12
- package/dist/tools/memory/getSessionContext.js +9 -9
- package/dist/tools/memory/linkMemories.js +14 -14
- package/dist/tools/memory/listMemories.js +4 -4
- package/dist/tools/memory/recallMemory.js +4 -4
- package/dist/tools/memory/saveMemory.js +4 -4
- package/dist/tools/memory/searchMemoriesAdvanced.js +22 -22
- package/dist/tools/planning/generatePrd.js +46 -46
- package/dist/tools/prompt/enhancePromptGemini.js +160 -160
- package/dist/tools/reasoning/applyReasoningFramework.js +56 -56
- package/dist/tools/semantic/analyzeDependencyGraph.js +12 -12
- package/hooks/hooks.json +121 -103
- package/package.json +73 -69
- package/skills/git-worktree.md +178 -178
- package/skills/priority-todos.md +236 -236
package/dist/lib/PythonParser.js
CHANGED
|
@@ -35,114 +35,114 @@ function getPythonCommand() {
|
|
|
35
35
|
const PYTHON_CMD = getPythonCommand();
|
|
36
36
|
export class PythonParser {
|
|
37
37
|
static cleanupRegistered = false;
|
|
38
|
-
static pythonScript = `
|
|
39
|
-
import ast
|
|
40
|
-
import sys
|
|
41
|
-
import json
|
|
42
|
-
|
|
43
|
-
def analyze_code(code):
|
|
44
|
-
try:
|
|
45
|
-
tree = ast.parse(code)
|
|
46
|
-
symbols = []
|
|
47
|
-
|
|
48
|
-
for node in ast.walk(tree):
|
|
49
|
-
if isinstance(node, ast.FunctionDef):
|
|
50
|
-
symbols.append({
|
|
51
|
-
'name': node.name,
|
|
52
|
-
'kind': 'function',
|
|
53
|
-
'line': node.lineno,
|
|
54
|
-
'column': node.col_offset,
|
|
55
|
-
'endLine': node.end_lineno,
|
|
56
|
-
'docstring': ast.get_docstring(node)
|
|
57
|
-
})
|
|
58
|
-
elif isinstance(node, ast.ClassDef):
|
|
59
|
-
symbols.append({
|
|
60
|
-
'name': node.name,
|
|
61
|
-
'kind': 'class',
|
|
62
|
-
'line': node.lineno,
|
|
63
|
-
'column': node.col_offset,
|
|
64
|
-
'endLine': node.end_lineno,
|
|
65
|
-
'docstring': ast.get_docstring(node)
|
|
66
|
-
})
|
|
67
|
-
elif isinstance(node, ast.Assign):
|
|
68
|
-
for target in node.targets:
|
|
69
|
-
if isinstance(target, ast.Name):
|
|
70
|
-
symbols.append({
|
|
71
|
-
'name': target.id,
|
|
72
|
-
'kind': 'variable',
|
|
73
|
-
'line': node.lineno,
|
|
74
|
-
'column': node.col_offset
|
|
75
|
-
})
|
|
76
|
-
elif isinstance(node, ast.Import) or isinstance(node, ast.ImportFrom):
|
|
77
|
-
for alias in node.names:
|
|
78
|
-
symbols.append({
|
|
79
|
-
'name': alias.name,
|
|
80
|
-
'kind': 'import',
|
|
81
|
-
'line': node.lineno,
|
|
82
|
-
'column': node.col_offset
|
|
83
|
-
})
|
|
84
|
-
|
|
85
|
-
return {'success': True, 'symbols': symbols}
|
|
86
|
-
except SyntaxError as e:
|
|
87
|
-
return {'success': False, 'error': str(e)}
|
|
88
|
-
except Exception as e:
|
|
89
|
-
return {'success': False, 'error': str(e)}
|
|
90
|
-
|
|
91
|
-
def calculate_complexity(code):
|
|
92
|
-
try:
|
|
93
|
-
tree = ast.parse(code)
|
|
94
|
-
|
|
95
|
-
def cyclomatic_complexity(node):
|
|
96
|
-
complexity = 1
|
|
97
|
-
for child in ast.walk(node):
|
|
98
|
-
if isinstance(child, (ast.If, ast.For, ast.While, ast.And, ast.Or, ast.ExceptHandler)):
|
|
99
|
-
complexity += 1
|
|
100
|
-
elif isinstance(child, ast.BoolOp):
|
|
101
|
-
complexity += len(child.values) - 1
|
|
102
|
-
return complexity
|
|
103
|
-
|
|
104
|
-
functions = []
|
|
105
|
-
classes = []
|
|
106
|
-
total_complexity = 1
|
|
107
|
-
|
|
108
|
-
for node in ast.walk(tree):
|
|
109
|
-
if isinstance(node, ast.FunctionDef):
|
|
110
|
-
func_complexity = cyclomatic_complexity(node)
|
|
111
|
-
functions.append({
|
|
112
|
-
'name': node.name,
|
|
113
|
-
'complexity': func_complexity,
|
|
114
|
-
'line': node.lineno
|
|
115
|
-
})
|
|
116
|
-
total_complexity += func_complexity
|
|
117
|
-
elif isinstance(node, ast.ClassDef):
|
|
118
|
-
method_count = sum(1 for n in node.body if isinstance(n, ast.FunctionDef))
|
|
119
|
-
classes.append({
|
|
120
|
-
'name': node.name,
|
|
121
|
-
'methods': method_count,
|
|
122
|
-
'line': node.lineno
|
|
123
|
-
})
|
|
124
|
-
|
|
125
|
-
return {
|
|
126
|
-
'success': True,
|
|
127
|
-
'cyclomaticComplexity': total_complexity,
|
|
128
|
-
'functions': functions,
|
|
129
|
-
'classes': classes
|
|
130
|
-
}
|
|
131
|
-
except Exception as e:
|
|
132
|
-
return {'success': False, 'error': str(e)}
|
|
133
|
-
|
|
134
|
-
if __name__ == '__main__':
|
|
135
|
-
code = sys.stdin.read()
|
|
136
|
-
action = sys.argv[1] if len(sys.argv) > 1 else 'symbols'
|
|
137
|
-
|
|
138
|
-
if action == 'symbols':
|
|
139
|
-
result = analyze_code(code)
|
|
140
|
-
elif action == 'complexity':
|
|
141
|
-
result = calculate_complexity(code)
|
|
142
|
-
else:
|
|
143
|
-
result = {'success': False, 'error': 'Unknown action'}
|
|
144
|
-
|
|
145
|
-
print(json.dumps(result))
|
|
38
|
+
static pythonScript = `
|
|
39
|
+
import ast
|
|
40
|
+
import sys
|
|
41
|
+
import json
|
|
42
|
+
|
|
43
|
+
def analyze_code(code):
|
|
44
|
+
try:
|
|
45
|
+
tree = ast.parse(code)
|
|
46
|
+
symbols = []
|
|
47
|
+
|
|
48
|
+
for node in ast.walk(tree):
|
|
49
|
+
if isinstance(node, ast.FunctionDef):
|
|
50
|
+
symbols.append({
|
|
51
|
+
'name': node.name,
|
|
52
|
+
'kind': 'function',
|
|
53
|
+
'line': node.lineno,
|
|
54
|
+
'column': node.col_offset,
|
|
55
|
+
'endLine': node.end_lineno,
|
|
56
|
+
'docstring': ast.get_docstring(node)
|
|
57
|
+
})
|
|
58
|
+
elif isinstance(node, ast.ClassDef):
|
|
59
|
+
symbols.append({
|
|
60
|
+
'name': node.name,
|
|
61
|
+
'kind': 'class',
|
|
62
|
+
'line': node.lineno,
|
|
63
|
+
'column': node.col_offset,
|
|
64
|
+
'endLine': node.end_lineno,
|
|
65
|
+
'docstring': ast.get_docstring(node)
|
|
66
|
+
})
|
|
67
|
+
elif isinstance(node, ast.Assign):
|
|
68
|
+
for target in node.targets:
|
|
69
|
+
if isinstance(target, ast.Name):
|
|
70
|
+
symbols.append({
|
|
71
|
+
'name': target.id,
|
|
72
|
+
'kind': 'variable',
|
|
73
|
+
'line': node.lineno,
|
|
74
|
+
'column': node.col_offset
|
|
75
|
+
})
|
|
76
|
+
elif isinstance(node, ast.Import) or isinstance(node, ast.ImportFrom):
|
|
77
|
+
for alias in node.names:
|
|
78
|
+
symbols.append({
|
|
79
|
+
'name': alias.name,
|
|
80
|
+
'kind': 'import',
|
|
81
|
+
'line': node.lineno,
|
|
82
|
+
'column': node.col_offset
|
|
83
|
+
})
|
|
84
|
+
|
|
85
|
+
return {'success': True, 'symbols': symbols}
|
|
86
|
+
except SyntaxError as e:
|
|
87
|
+
return {'success': False, 'error': str(e)}
|
|
88
|
+
except Exception as e:
|
|
89
|
+
return {'success': False, 'error': str(e)}
|
|
90
|
+
|
|
91
|
+
def calculate_complexity(code):
|
|
92
|
+
try:
|
|
93
|
+
tree = ast.parse(code)
|
|
94
|
+
|
|
95
|
+
def cyclomatic_complexity(node):
|
|
96
|
+
complexity = 1
|
|
97
|
+
for child in ast.walk(node):
|
|
98
|
+
if isinstance(child, (ast.If, ast.For, ast.While, ast.And, ast.Or, ast.ExceptHandler)):
|
|
99
|
+
complexity += 1
|
|
100
|
+
elif isinstance(child, ast.BoolOp):
|
|
101
|
+
complexity += len(child.values) - 1
|
|
102
|
+
return complexity
|
|
103
|
+
|
|
104
|
+
functions = []
|
|
105
|
+
classes = []
|
|
106
|
+
total_complexity = 1
|
|
107
|
+
|
|
108
|
+
for node in ast.walk(tree):
|
|
109
|
+
if isinstance(node, ast.FunctionDef):
|
|
110
|
+
func_complexity = cyclomatic_complexity(node)
|
|
111
|
+
functions.append({
|
|
112
|
+
'name': node.name,
|
|
113
|
+
'complexity': func_complexity,
|
|
114
|
+
'line': node.lineno
|
|
115
|
+
})
|
|
116
|
+
total_complexity += func_complexity
|
|
117
|
+
elif isinstance(node, ast.ClassDef):
|
|
118
|
+
method_count = sum(1 for n in node.body if isinstance(n, ast.FunctionDef))
|
|
119
|
+
classes.append({
|
|
120
|
+
'name': node.name,
|
|
121
|
+
'methods': method_count,
|
|
122
|
+
'line': node.lineno
|
|
123
|
+
})
|
|
124
|
+
|
|
125
|
+
return {
|
|
126
|
+
'success': True,
|
|
127
|
+
'cyclomaticComplexity': total_complexity,
|
|
128
|
+
'functions': functions,
|
|
129
|
+
'classes': classes
|
|
130
|
+
}
|
|
131
|
+
except Exception as e:
|
|
132
|
+
return {'success': False, 'error': str(e)}
|
|
133
|
+
|
|
134
|
+
if __name__ == '__main__':
|
|
135
|
+
code = sys.stdin.read()
|
|
136
|
+
action = sys.argv[1] if len(sys.argv) > 1 else 'symbols'
|
|
137
|
+
|
|
138
|
+
if action == 'symbols':
|
|
139
|
+
result = analyze_code(code)
|
|
140
|
+
elif action == 'complexity':
|
|
141
|
+
result = calculate_complexity(code)
|
|
142
|
+
else:
|
|
143
|
+
result = {'success': False, 'error': 'Unknown action'}
|
|
144
|
+
|
|
145
|
+
print(json.dumps(result))
|
|
146
146
|
`;
|
|
147
147
|
// Singleton Python script path to avoid recreating it
|
|
148
148
|
static scriptPath = null;
|
package/dist/lib/gemini-mcp.js
CHANGED
|
@@ -161,12 +161,12 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
161
161
|
}
|
|
162
162
|
case 'gemini_analyze_code': {
|
|
163
163
|
const { code, language, focus } = args;
|
|
164
|
-
const sysPrompt = `You are an expert code reviewer. Analyze the given ${language || 'code'} and provide detailed feedback focusing on: ${focus || 'all aspects including performance, security, readability, and best practices'}.
|
|
165
|
-
|
|
166
|
-
Respond in Korean and provide:
|
|
167
|
-
1. 코드 요약
|
|
168
|
-
2. 주요 이슈 (있다면)
|
|
169
|
-
3. 개선 제안
|
|
164
|
+
const sysPrompt = `You are an expert code reviewer. Analyze the given ${language || 'code'} and provide detailed feedback focusing on: ${focus || 'all aspects including performance, security, readability, and best practices'}.
|
|
165
|
+
|
|
166
|
+
Respond in Korean and provide:
|
|
167
|
+
1. 코드 요약
|
|
168
|
+
2. 주요 이슈 (있다면)
|
|
169
|
+
3. 개선 제안
|
|
170
170
|
4. 전체 품질 점수 (1-10)`;
|
|
171
171
|
const result = await geminiApi.chat({
|
|
172
172
|
model: 'gemini-2.5-flash',
|
|
@@ -186,15 +186,15 @@ Respond in Korean and provide:
|
|
|
186
186
|
}
|
|
187
187
|
case 'gemini_review_ui': {
|
|
188
188
|
const { description, context } = args;
|
|
189
|
-
const sysPrompt = `You are a UI/UX expert. Review the given UI description and provide detailed feedback.
|
|
190
|
-
|
|
191
|
-
${context ? `Project context: ${context}` : ''}
|
|
192
|
-
|
|
193
|
-
Respond in Korean and provide:
|
|
194
|
-
1. UI 구조 평가
|
|
195
|
-
2. UX 개선점
|
|
196
|
-
3. 접근성 체크
|
|
197
|
-
4. 모범 사례 비교
|
|
189
|
+
const sysPrompt = `You are a UI/UX expert. Review the given UI description and provide detailed feedback.
|
|
190
|
+
|
|
191
|
+
${context ? `Project context: ${context}` : ''}
|
|
192
|
+
|
|
193
|
+
Respond in Korean and provide:
|
|
194
|
+
1. UI 구조 평가
|
|
195
|
+
2. UX 개선점
|
|
196
|
+
3. 접근성 체크
|
|
197
|
+
4. 모범 사례 비교
|
|
198
198
|
5. 구체적인 개선 제안`;
|
|
199
199
|
const result = await geminiApi.chat({
|
|
200
200
|
model: 'gemini-2.5-flash',
|
package/dist/lib/gemini-oauth.js
CHANGED
|
@@ -212,15 +212,15 @@ export function startOAuthFlow() {
|
|
|
212
212
|
const error = url.searchParams.get('error');
|
|
213
213
|
if (error) {
|
|
214
214
|
res.writeHead(400, { 'Content-Type': 'text/html; charset=utf-8' });
|
|
215
|
-
res.end(`
|
|
216
|
-
<html>
|
|
217
|
-
<head><title>인증 실패</title></head>
|
|
218
|
-
<body style="font-family: sans-serif; text-align: center; padding-top: 50px;">
|
|
219
|
-
<h1>인증 실패</h1>
|
|
220
|
-
<p>오류: ${error}</p>
|
|
221
|
-
<p>이 창을 닫고 다시 시도해주세요.</p>
|
|
222
|
-
</body>
|
|
223
|
-
</html>
|
|
215
|
+
res.end(`
|
|
216
|
+
<html>
|
|
217
|
+
<head><title>인증 실패</title></head>
|
|
218
|
+
<body style="font-family: sans-serif; text-align: center; padding-top: 50px;">
|
|
219
|
+
<h1>인증 실패</h1>
|
|
220
|
+
<p>오류: ${error}</p>
|
|
221
|
+
<p>이 창을 닫고 다시 시도해주세요.</p>
|
|
222
|
+
</body>
|
|
223
|
+
</html>
|
|
224
224
|
`);
|
|
225
225
|
if (!isResolved) {
|
|
226
226
|
isResolved = true;
|
|
@@ -231,14 +231,14 @@ export function startOAuthFlow() {
|
|
|
231
231
|
}
|
|
232
232
|
if (!code || !state) {
|
|
233
233
|
res.writeHead(400, { 'Content-Type': 'text/html; charset=utf-8' });
|
|
234
|
-
res.end(`
|
|
235
|
-
<html>
|
|
236
|
-
<head><title>인증 실패</title></head>
|
|
237
|
-
<body style="font-family: sans-serif; text-align: center; padding-top: 50px;">
|
|
238
|
-
<h1>인증 실패</h1>
|
|
239
|
-
<p>필수 파라미터가 없습니다.</p>
|
|
240
|
-
</body>
|
|
241
|
-
</html>
|
|
234
|
+
res.end(`
|
|
235
|
+
<html>
|
|
236
|
+
<head><title>인증 실패</title></head>
|
|
237
|
+
<body style="font-family: sans-serif; text-align: center; padding-top: 50px;">
|
|
238
|
+
<h1>인증 실패</h1>
|
|
239
|
+
<p>필수 파라미터가 없습니다.</p>
|
|
240
|
+
</body>
|
|
241
|
+
</html>
|
|
242
242
|
`);
|
|
243
243
|
if (!isResolved) {
|
|
244
244
|
isResolved = true;
|
|
@@ -250,16 +250,16 @@ export function startOAuthFlow() {
|
|
|
250
250
|
try {
|
|
251
251
|
const tokens = await exchangeCodeForTokens(code, state);
|
|
252
252
|
res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' });
|
|
253
|
-
res.end(`
|
|
254
|
-
<html>
|
|
255
|
-
<head><title>인증 성공</title></head>
|
|
256
|
-
<body style="font-family: sans-serif; text-align: center; padding-top: 50px;">
|
|
257
|
-
<h1>인증 성공!</h1>
|
|
258
|
-
<p>${tokens.email}로 로그인되었습니다.</p>
|
|
259
|
-
<p>이 창을 닫아도 됩니다.</p>
|
|
260
|
-
<script>setTimeout(() => window.close(), 2000);</script>
|
|
261
|
-
</body>
|
|
262
|
-
</html>
|
|
253
|
+
res.end(`
|
|
254
|
+
<html>
|
|
255
|
+
<head><title>인증 성공</title></head>
|
|
256
|
+
<body style="font-family: sans-serif; text-align: center; padding-top: 50px;">
|
|
257
|
+
<h1>인증 성공!</h1>
|
|
258
|
+
<p>${tokens.email}로 로그인되었습니다.</p>
|
|
259
|
+
<p>이 창을 닫아도 됩니다.</p>
|
|
260
|
+
<script>setTimeout(() => window.close(), 2000);</script>
|
|
261
|
+
</body>
|
|
262
|
+
</html>
|
|
263
263
|
`);
|
|
264
264
|
if (!isResolved) {
|
|
265
265
|
isResolved = true;
|
|
@@ -269,14 +269,14 @@ export function startOAuthFlow() {
|
|
|
269
269
|
}
|
|
270
270
|
catch (err) {
|
|
271
271
|
res.writeHead(500, { 'Content-Type': 'text/html; charset=utf-8' });
|
|
272
|
-
res.end(`
|
|
273
|
-
<html>
|
|
274
|
-
<head><title>인증 실패</title></head>
|
|
275
|
-
<body style="font-family: sans-serif; text-align: center; padding-top: 50px;">
|
|
276
|
-
<h1>인증 실패</h1>
|
|
277
|
-
<p>${err.message}</p>
|
|
278
|
-
</body>
|
|
279
|
-
</html>
|
|
272
|
+
res.end(`
|
|
273
|
+
<html>
|
|
274
|
+
<head><title>인증 실패</title></head>
|
|
275
|
+
<body style="font-family: sans-serif; text-align: center; padding-top: 50px;">
|
|
276
|
+
<h1>인증 실패</h1>
|
|
277
|
+
<p>${err.message}</p>
|
|
278
|
+
</body>
|
|
279
|
+
</html>
|
|
280
280
|
`);
|
|
281
281
|
if (!isResolved) {
|
|
282
282
|
isResolved = true;
|
package/dist/lib/gpt-mcp.js
CHANGED
|
@@ -159,15 +159,15 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
159
159
|
}
|
|
160
160
|
case 'gpt_analyze_architecture': {
|
|
161
161
|
const { code, context } = args;
|
|
162
|
-
const sysPrompt = `You are a senior software architect. Analyze the given code or architecture and provide detailed insights.
|
|
163
|
-
|
|
164
|
-
${context ? `Project context: ${context}` : ''}
|
|
165
|
-
|
|
166
|
-
Respond in Korean and provide:
|
|
167
|
-
1. 아키텍처 요약
|
|
168
|
-
2. 강점
|
|
169
|
-
3. 잠재적 문제점
|
|
170
|
-
4. 개선 제안
|
|
162
|
+
const sysPrompt = `You are a senior software architect. Analyze the given code or architecture and provide detailed insights.
|
|
163
|
+
|
|
164
|
+
${context ? `Project context: ${context}` : ''}
|
|
165
|
+
|
|
166
|
+
Respond in Korean and provide:
|
|
167
|
+
1. 아키텍처 요약
|
|
168
|
+
2. 강점
|
|
169
|
+
3. 잠재적 문제점
|
|
170
|
+
4. 개선 제안
|
|
171
171
|
5. 확장성 평가`;
|
|
172
172
|
const result = await gptApi.chat({
|
|
173
173
|
model: 'gpt-5.2',
|
|
@@ -187,14 +187,14 @@ Respond in Korean and provide:
|
|
|
187
187
|
}
|
|
188
188
|
case 'gpt_debug': {
|
|
189
189
|
const { code, error, language } = args;
|
|
190
|
-
const sysPrompt = `You are an expert debugger. Analyze the given ${language || 'code'} and identify bugs.
|
|
191
|
-
|
|
192
|
-
${error ? `Error/Symptom: ${error}` : ''}
|
|
193
|
-
|
|
194
|
-
Respond in Korean and provide:
|
|
195
|
-
1. 버그 식별
|
|
196
|
-
2. 원인 분석
|
|
197
|
-
3. 수정된 코드
|
|
190
|
+
const sysPrompt = `You are an expert debugger. Analyze the given ${language || 'code'} and identify bugs.
|
|
191
|
+
|
|
192
|
+
${error ? `Error/Symptom: ${error}` : ''}
|
|
193
|
+
|
|
194
|
+
Respond in Korean and provide:
|
|
195
|
+
1. 버그 식별
|
|
196
|
+
2. 원인 분석
|
|
197
|
+
3. 수정된 코드
|
|
198
198
|
4. 예방 방법`;
|
|
199
199
|
const result = await gptApi.chat({
|
|
200
200
|
model: 'gpt-5.2-codex',
|
package/dist/lib/gpt-oauth.js
CHANGED
|
@@ -201,16 +201,16 @@ export function startOAuthFlow() {
|
|
|
201
201
|
const errorDescription = url.searchParams.get('error_description');
|
|
202
202
|
if (error) {
|
|
203
203
|
res.writeHead(400, { 'Content-Type': 'text/html; charset=utf-8' });
|
|
204
|
-
res.end(`
|
|
205
|
-
<html>
|
|
206
|
-
<head><title>인증 실패</title></head>
|
|
207
|
-
<body style="font-family: sans-serif; text-align: center; padding-top: 50px;">
|
|
208
|
-
<h1>인증 실패</h1>
|
|
209
|
-
<p>오류: ${error}</p>
|
|
210
|
-
<p>${errorDescription || ''}</p>
|
|
211
|
-
<p>이 창을 닫고 다시 시도해주세요.</p>
|
|
212
|
-
</body>
|
|
213
|
-
</html>
|
|
204
|
+
res.end(`
|
|
205
|
+
<html>
|
|
206
|
+
<head><title>인증 실패</title></head>
|
|
207
|
+
<body style="font-family: sans-serif; text-align: center; padding-top: 50px;">
|
|
208
|
+
<h1>인증 실패</h1>
|
|
209
|
+
<p>오류: ${error}</p>
|
|
210
|
+
<p>${errorDescription || ''}</p>
|
|
211
|
+
<p>이 창을 닫고 다시 시도해주세요.</p>
|
|
212
|
+
</body>
|
|
213
|
+
</html>
|
|
214
214
|
`);
|
|
215
215
|
if (!isResolved) {
|
|
216
216
|
isResolved = true;
|
|
@@ -222,14 +222,14 @@ export function startOAuthFlow() {
|
|
|
222
222
|
// state 검증
|
|
223
223
|
if (state !== auth.state) {
|
|
224
224
|
res.writeHead(400, { 'Content-Type': 'text/html; charset=utf-8' });
|
|
225
|
-
res.end(`
|
|
226
|
-
<html>
|
|
227
|
-
<head><title>인증 실패</title></head>
|
|
228
|
-
<body style="font-family: sans-serif; text-align: center; padding-top: 50px;">
|
|
229
|
-
<h1>인증 실패</h1>
|
|
230
|
-
<p>State 불일치 - CSRF 공격 가능성</p>
|
|
231
|
-
</body>
|
|
232
|
-
</html>
|
|
225
|
+
res.end(`
|
|
226
|
+
<html>
|
|
227
|
+
<head><title>인증 실패</title></head>
|
|
228
|
+
<body style="font-family: sans-serif; text-align: center; padding-top: 50px;">
|
|
229
|
+
<h1>인증 실패</h1>
|
|
230
|
+
<p>State 불일치 - CSRF 공격 가능성</p>
|
|
231
|
+
</body>
|
|
232
|
+
</html>
|
|
233
233
|
`);
|
|
234
234
|
if (!isResolved) {
|
|
235
235
|
isResolved = true;
|
|
@@ -240,14 +240,14 @@ export function startOAuthFlow() {
|
|
|
240
240
|
}
|
|
241
241
|
if (!code) {
|
|
242
242
|
res.writeHead(400, { 'Content-Type': 'text/html; charset=utf-8' });
|
|
243
|
-
res.end(`
|
|
244
|
-
<html>
|
|
245
|
-
<head><title>인증 실패</title></head>
|
|
246
|
-
<body style="font-family: sans-serif; text-align: center; padding-top: 50px;">
|
|
247
|
-
<h1>인증 실패</h1>
|
|
248
|
-
<p>Authorization code가 없습니다.</p>
|
|
249
|
-
</body>
|
|
250
|
-
</html>
|
|
243
|
+
res.end(`
|
|
244
|
+
<html>
|
|
245
|
+
<head><title>인증 실패</title></head>
|
|
246
|
+
<body style="font-family: sans-serif; text-align: center; padding-top: 50px;">
|
|
247
|
+
<h1>인증 실패</h1>
|
|
248
|
+
<p>Authorization code가 없습니다.</p>
|
|
249
|
+
</body>
|
|
250
|
+
</html>
|
|
251
251
|
`);
|
|
252
252
|
if (!isResolved) {
|
|
253
253
|
isResolved = true;
|
|
@@ -259,16 +259,16 @@ export function startOAuthFlow() {
|
|
|
259
259
|
try {
|
|
260
260
|
const tokens = await exchangeCodeForTokens(code, auth.verifier);
|
|
261
261
|
res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' });
|
|
262
|
-
res.end(`
|
|
263
|
-
<html>
|
|
264
|
-
<head><title>인증 성공</title></head>
|
|
265
|
-
<body style="font-family: sans-serif; text-align: center; padding-top: 50px;">
|
|
266
|
-
<h1>인증 성공!</h1>
|
|
267
|
-
<p>${tokens.email}로 로그인되었습니다.</p>
|
|
268
|
-
<p>이 창을 닫아도 됩니다.</p>
|
|
269
|
-
<script>setTimeout(() => window.close(), 2000);</script>
|
|
270
|
-
</body>
|
|
271
|
-
</html>
|
|
262
|
+
res.end(`
|
|
263
|
+
<html>
|
|
264
|
+
<head><title>인증 성공</title></head>
|
|
265
|
+
<body style="font-family: sans-serif; text-align: center; padding-top: 50px;">
|
|
266
|
+
<h1>인증 성공!</h1>
|
|
267
|
+
<p>${tokens.email}로 로그인되었습니다.</p>
|
|
268
|
+
<p>이 창을 닫아도 됩니다.</p>
|
|
269
|
+
<script>setTimeout(() => window.close(), 2000);</script>
|
|
270
|
+
</body>
|
|
271
|
+
</html>
|
|
272
272
|
`);
|
|
273
273
|
if (!isResolved) {
|
|
274
274
|
isResolved = true;
|
|
@@ -278,14 +278,14 @@ export function startOAuthFlow() {
|
|
|
278
278
|
}
|
|
279
279
|
catch (err) {
|
|
280
280
|
res.writeHead(500, { 'Content-Type': 'text/html; charset=utf-8' });
|
|
281
|
-
res.end(`
|
|
282
|
-
<html>
|
|
283
|
-
<head><title>인증 실패</title></head>
|
|
284
|
-
<body style="font-family: sans-serif; text-align: center; padding-top: 50px;">
|
|
285
|
-
<h1>인증 실패</h1>
|
|
286
|
-
<p>${err.message}</p>
|
|
287
|
-
</body>
|
|
288
|
-
</html>
|
|
281
|
+
res.end(`
|
|
282
|
+
<html>
|
|
283
|
+
<head><title>인증 실패</title></head>
|
|
284
|
+
<body style="font-family: sans-serif; text-align: center; padding-top: 50px;">
|
|
285
|
+
<h1>인증 실패</h1>
|
|
286
|
+
<p>${err.message}</p>
|
|
287
|
+
</body>
|
|
288
|
+
</html>
|
|
289
289
|
`);
|
|
290
290
|
if (!isResolved) {
|
|
291
291
|
isResolved = true;
|
|
@@ -2,18 +2,18 @@
|
|
|
2
2
|
import { MemoryManager } from '../../lib/MemoryManager.js';
|
|
3
3
|
export const getUsageAnalyticsDefinition = {
|
|
4
4
|
name: 'get_usage_analytics',
|
|
5
|
-
description: `도구 사용 분석 및 통계를 조회합니다.
|
|
6
|
-
|
|
7
|
-
키워드: 분석, 통계, 사용량, analytics, statistics, usage
|
|
8
|
-
|
|
9
|
-
**제공 정보:**
|
|
10
|
-
- 메모리 사용 통계
|
|
11
|
-
- 카테고리별 분포
|
|
12
|
-
- 시간별 사용 패턴
|
|
13
|
-
- 그래프 관계 통계
|
|
14
|
-
|
|
15
|
-
사용 예시:
|
|
16
|
-
- "사용 통계 보여줘"
|
|
5
|
+
description: `도구 사용 분석 및 통계를 조회합니다.
|
|
6
|
+
|
|
7
|
+
키워드: 분석, 통계, 사용량, analytics, statistics, usage
|
|
8
|
+
|
|
9
|
+
**제공 정보:**
|
|
10
|
+
- 메모리 사용 통계
|
|
11
|
+
- 카테고리별 분포
|
|
12
|
+
- 시간별 사용 패턴
|
|
13
|
+
- 그래프 관계 통계
|
|
14
|
+
|
|
15
|
+
사용 예시:
|
|
16
|
+
- "사용 통계 보여줘"
|
|
17
17
|
- "메모리 분석"`,
|
|
18
18
|
inputSchema: {
|
|
19
19
|
type: 'object',
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Vibe Tools - CLI 없이 도구만 export
|
|
3
|
+
*
|
|
4
|
+
* 사용법:
|
|
5
|
+
* node -e "require('@su-record/vibe/tools').startSession({}).then(console.log)"
|
|
6
|
+
*/
|
|
7
|
+
export { startSession } from './memory/startSession.js';
|
|
8
|
+
export { autoSaveContext } from './memory/autoSaveContext.js';
|
|
9
|
+
export { saveMemory } from './memory/saveMemory.js';
|
|
10
|
+
export { recallMemory } from './memory/recallMemory.js';
|
|
11
|
+
export { listMemories } from './memory/listMemories.js';
|
|
12
|
+
export { deleteMemory } from './memory/deleteMemory.js';
|
|
13
|
+
export { updateMemory } from './memory/updateMemory.js';
|
|
14
|
+
export { searchMemoriesHandler as searchMemories } from './memory/searchMemories.js';
|
|
15
|
+
export { searchMemoriesAdvanced } from './memory/searchMemoriesAdvanced.js';
|
|
16
|
+
export { linkMemories } from './memory/linkMemories.js';
|
|
17
|
+
export { getMemoryGraph } from './memory/getMemoryGraph.js';
|
|
18
|
+
export { createMemoryTimeline } from './memory/createMemoryTimeline.js';
|
|
19
|
+
export { restoreSessionContext } from './memory/restoreSessionContext.js';
|
|
20
|
+
export { prioritizeMemory } from './memory/prioritizeMemory.js';
|
|
21
|
+
export { getSessionContext } from './memory/getSessionContext.js';
|
|
22
|
+
export { findSymbol } from './semantic/findSymbol.js';
|
|
23
|
+
export { findReferences } from './semantic/findReferences.js';
|
|
24
|
+
export { analyzeDependencyGraph } from './semantic/analyzeDependencyGraph.js';
|
|
25
|
+
export { analyzeComplexity } from './convention/analyzeComplexity.js';
|
|
26
|
+
export { validateCodeQuality } from './convention/validateCodeQuality.js';
|
|
27
|
+
export { checkCouplingCohesion } from './convention/checkCouplingCohesion.js';
|
|
28
|
+
export { suggestImprovements } from './convention/suggestImprovements.js';
|
|
29
|
+
export { applyQualityRules } from './convention/applyQualityRules.js';
|
|
30
|
+
export { getCodingGuide } from './convention/getCodingGuide.js';
|
|
31
|
+
export { createThinkingChain } from './thinking/createThinkingChain.js';
|
|
32
|
+
export { analyzeProblem } from './thinking/analyzeProblem.js';
|
|
33
|
+
export { stepByStepAnalysis } from './thinking/stepByStepAnalysis.js';
|
|
34
|
+
export { formatAsPlan } from './thinking/formatAsPlan.js';
|
|
35
|
+
export { breakDownProblem } from './thinking/breakDownProblem.js';
|
|
36
|
+
export { thinkAloudProcess } from './thinking/thinkAloudProcess.js';
|
|
37
|
+
export { generatePrd } from './planning/generatePrd.js';
|
|
38
|
+
export { createUserStories } from './planning/createUserStories.js';
|
|
39
|
+
export { analyzeRequirements } from './planning/analyzeRequirements.js';
|
|
40
|
+
export { featureRoadmap } from './planning/featureRoadmap.js';
|
|
41
|
+
export { enhancePrompt } from './prompt/enhancePrompt.js';
|
|
42
|
+
export { analyzePrompt } from './prompt/analyzePrompt.js';
|
|
43
|
+
export { previewUiAscii } from './ui/previewUiAscii.js';
|
|
44
|
+
export { getCurrentTime } from './time/getCurrentTime.js';
|
|
45
|
+
export { applyReasoningFramework } from './reasoning/applyReasoningFramework.js';
|
|
46
|
+
export { getUsageAnalytics } from './analytics/getUsageAnalytics.js';
|
|
47
|
+
export { MemoryManager } from '../lib/MemoryManager.js';
|
|
48
|
+
export { ProjectCache } from '../lib/ProjectCache.js';
|
|
49
|
+
export { ContextCompressor } from '../lib/ContextCompressor.js';
|
|
50
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AACxD,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAC9D,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACpD,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AACxD,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AACxD,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AACxD,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AACxD,OAAO,EAAE,qBAAqB,IAAI,cAAc,EAAE,MAAM,4BAA4B,CAAC;AACrF,OAAO,EAAE,sBAAsB,EAAE,MAAM,oCAAoC,CAAC;AAC5E,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AACxD,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAC5D,OAAO,EAAE,oBAAoB,EAAE,MAAM,kCAAkC,CAAC;AACxE,OAAO,EAAE,qBAAqB,EAAE,MAAM,mCAAmC,CAAC;AAC1E,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAChE,OAAO,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AAGlE,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AACtD,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAC9D,OAAO,EAAE,sBAAsB,EAAE,MAAM,sCAAsC,CAAC;AAG9E,OAAO,EAAE,iBAAiB,EAAE,MAAM,mCAAmC,CAAC;AACtE,OAAO,EAAE,mBAAmB,EAAE,MAAM,qCAAqC,CAAC;AAC1E,OAAO,EAAE,qBAAqB,EAAE,MAAM,uCAAuC,CAAC;AAC9E,OAAO,EAAE,mBAAmB,EAAE,MAAM,qCAAqC,CAAC;AAC1E,OAAO,EAAE,iBAAiB,EAAE,MAAM,mCAAmC,CAAC;AACtE,OAAO,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAGhE,OAAO,EAAE,mBAAmB,EAAE,MAAM,mCAAmC,CAAC;AACxE,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAC9D,OAAO,EAAE,kBAAkB,EAAE,MAAM,kCAAkC,CAAC;AACtE,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC1D,OAAO,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AAClE,OAAO,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AAGpE,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AACxD,OAAO,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AACpE,OAAO,EAAE,mBAAmB,EAAE,MAAM,mCAAmC,CAAC;AACxE,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAG9D,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC1D,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAG1D,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAGxD,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAG1D,OAAO,EAAE,uBAAuB,EAAE,MAAM,wCAAwC,CAAC;AAGjF,OAAO,EAAE,iBAAiB,EAAE,MAAM,kCAAkC,CAAC;AAGrE,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AACxD,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AACtD,OAAO,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC"}
|