@su-record/vibe 2.3.2 → 2.4.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.
- package/.claude/settings.json +35 -35
- package/.claude/settings.local.json +30 -24
- 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 -345
- package/LICENSE +21 -21
- package/README.md +817 -744
- 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 +260 -245
- package/commands/vibe.reason.md +223 -223
- package/commands/vibe.review.md +213 -200
- package/commands/vibe.run.md +842 -838
- package/commands/vibe.spec.md +405 -419
- package/commands/vibe.utils.md +101 -101
- package/commands/vibe.verify.md +282 -282
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +422 -385
- package/dist/cli/index.js.map +1 -1
- package/dist/lib/MemoryManager.js +92 -92
- 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/orchestrator/agentDiscovery.d.ts +18 -0
- package/dist/orchestrator/agentDiscovery.d.ts.map +1 -0
- package/dist/orchestrator/agentDiscovery.js +174 -0
- package/dist/orchestrator/agentDiscovery.js.map +1 -0
- package/dist/orchestrator/backgroundAgent.d.ts +31 -0
- package/dist/orchestrator/backgroundAgent.d.ts.map +1 -0
- package/dist/orchestrator/backgroundAgent.js +325 -0
- package/dist/orchestrator/backgroundAgent.js.map +1 -0
- package/dist/orchestrator/index.d.ts +58 -0
- package/dist/orchestrator/index.d.ts.map +1 -0
- package/dist/orchestrator/index.js +115 -0
- package/dist/orchestrator/index.js.map +1 -0
- package/dist/orchestrator/orchestrator.d.ts +82 -0
- package/dist/orchestrator/orchestrator.d.ts.map +1 -0
- package/dist/orchestrator/orchestrator.js +257 -0
- package/dist/orchestrator/orchestrator.js.map +1 -0
- package/dist/orchestrator/parallelResearch.d.ts +19 -0
- package/dist/orchestrator/parallelResearch.d.ts.map +1 -0
- package/dist/orchestrator/parallelResearch.js +214 -0
- package/dist/orchestrator/parallelResearch.js.map +1 -0
- package/dist/orchestrator/types.d.ts +109 -0
- package/dist/orchestrator/types.d.ts.map +1 -0
- package/dist/orchestrator/types.js +5 -0
- package/dist/orchestrator/types.js.map +1 -0
- package/dist/tools/analytics/getUsageAnalytics.js +12 -12
- 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 -121
- package/package.json +75 -73
- package/skills/git-worktree.md +178 -178
- package/skills/priority-todos.md +236 -236
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;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agent Discovery - .claude/agents/ 폴더에서 에이전트 동적 탐색
|
|
3
|
+
*/
|
|
4
|
+
import { DiscoveredAgent, AgentDiscoveryArgs } from './types.js';
|
|
5
|
+
import { ToolResult } from '../types/tool.js';
|
|
6
|
+
/**
|
|
7
|
+
* 에이전트 동적 탐색
|
|
8
|
+
*/
|
|
9
|
+
export declare function discoverAgents(args: AgentDiscoveryArgs): Promise<ToolResult>;
|
|
10
|
+
/**
|
|
11
|
+
* 특정 에이전트 로드
|
|
12
|
+
*/
|
|
13
|
+
export declare function loadAgent(agentName: string, projectPath?: string): Promise<DiscoveredAgent | null>;
|
|
14
|
+
/**
|
|
15
|
+
* 카테고리별 에이전트 목록
|
|
16
|
+
*/
|
|
17
|
+
export declare function listAgentsByCategory(category: string, projectPath?: string): Promise<DiscoveredAgent[]>;
|
|
18
|
+
//# sourceMappingURL=agentDiscovery.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agentDiscovery.d.ts","sourceRoot":"","sources":["../../src/orchestrator/agentDiscovery.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH,OAAO,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AACjE,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAqD9C;;GAEG;AACH,wBAAsB,cAAc,CAAC,IAAI,EAAE,kBAAkB,GAAG,OAAO,CAAC,UAAU,CAAC,CA0GlF;AAED;;GAEG;AACH,wBAAsB,SAAS,CAAC,SAAS,EAAE,MAAM,EAAE,WAAW,GAAE,MAAsB,GAAG,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC,CAYvH;AAED;;GAEG;AACH,wBAAsB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,EAAE,WAAW,GAAE,MAAsB,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC,CAQ5H"}
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agent Discovery - .claude/agents/ 폴더에서 에이전트 동적 탐색
|
|
3
|
+
*/
|
|
4
|
+
import { promises as fs } from 'fs';
|
|
5
|
+
import path from 'path';
|
|
6
|
+
import { glob } from 'glob';
|
|
7
|
+
// 에이전트 디렉토리 우선순위: .claude/agents > agents
|
|
8
|
+
const AGENTS_DIRS = ['.claude/agents', 'agents'];
|
|
9
|
+
/**
|
|
10
|
+
* 에이전트 마크다운 파일에서 메타데이터 추출
|
|
11
|
+
*/
|
|
12
|
+
function parseAgentMarkdown(content, filePath) {
|
|
13
|
+
const lines = content.split('\n');
|
|
14
|
+
let name = path.basename(filePath, '.md');
|
|
15
|
+
let description = '';
|
|
16
|
+
// 첫 번째 # 헤더에서 이름 추출
|
|
17
|
+
for (const line of lines) {
|
|
18
|
+
if (line.startsWith('# ')) {
|
|
19
|
+
name = line.slice(2).trim();
|
|
20
|
+
break;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
// 첫 번째 일반 텍스트 단락에서 설명 추출
|
|
24
|
+
let inDescription = false;
|
|
25
|
+
for (const line of lines) {
|
|
26
|
+
if (line.startsWith('# ') || line.startsWith('## ')) {
|
|
27
|
+
if (inDescription)
|
|
28
|
+
break;
|
|
29
|
+
inDescription = true;
|
|
30
|
+
continue;
|
|
31
|
+
}
|
|
32
|
+
if (inDescription && line.trim() && !line.startsWith('#') && !line.startsWith('```')) {
|
|
33
|
+
description = line.trim();
|
|
34
|
+
break;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
return { name, description };
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* 카테고리 추출 (폴더명 기반)
|
|
41
|
+
*/
|
|
42
|
+
function extractCategory(filePath, basePath) {
|
|
43
|
+
const relativePath = path.relative(basePath, filePath);
|
|
44
|
+
const parts = relativePath.split(path.sep);
|
|
45
|
+
// agents/review/xxx.md -> review
|
|
46
|
+
// agents/research/xxx.md -> research
|
|
47
|
+
if (parts.length > 1) {
|
|
48
|
+
return parts[0];
|
|
49
|
+
}
|
|
50
|
+
return 'general';
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* 에이전트 동적 탐색
|
|
54
|
+
*/
|
|
55
|
+
export async function discoverAgents(args) {
|
|
56
|
+
const { projectPath = process.cwd(), category, pattern } = args;
|
|
57
|
+
try {
|
|
58
|
+
// 에이전트 디렉토리 찾기 (우선순위대로)
|
|
59
|
+
let agentsBasePath = null;
|
|
60
|
+
for (const dir of AGENTS_DIRS) {
|
|
61
|
+
const candidatePath = path.join(projectPath, dir);
|
|
62
|
+
try {
|
|
63
|
+
await fs.access(candidatePath);
|
|
64
|
+
agentsBasePath = candidatePath;
|
|
65
|
+
break;
|
|
66
|
+
}
|
|
67
|
+
catch {
|
|
68
|
+
// 다음 경로 시도
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
if (!agentsBasePath) {
|
|
72
|
+
return {
|
|
73
|
+
content: [{
|
|
74
|
+
type: 'text',
|
|
75
|
+
text: `No agents directory found. Searched: ${AGENTS_DIRS.join(', ')}. Create agents in .claude/agents/ or agents/ folder.`
|
|
76
|
+
}]
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
// 패턴 구성
|
|
80
|
+
let searchPattern = '**/*.md';
|
|
81
|
+
if (category) {
|
|
82
|
+
searchPattern = `${category}/**/*.md`;
|
|
83
|
+
}
|
|
84
|
+
if (pattern) {
|
|
85
|
+
searchPattern = pattern;
|
|
86
|
+
}
|
|
87
|
+
// 에이전트 파일 검색
|
|
88
|
+
const agentFiles = await glob(searchPattern, {
|
|
89
|
+
cwd: agentsBasePath,
|
|
90
|
+
absolute: true
|
|
91
|
+
});
|
|
92
|
+
if (agentFiles.length === 0) {
|
|
93
|
+
return {
|
|
94
|
+
content: [{
|
|
95
|
+
type: 'text',
|
|
96
|
+
text: `No agents found matching pattern: ${searchPattern}`
|
|
97
|
+
}]
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
// 에이전트 정보 수집
|
|
101
|
+
const agents = [];
|
|
102
|
+
for (const filePath of agentFiles) {
|
|
103
|
+
try {
|
|
104
|
+
const content = await fs.readFile(filePath, 'utf-8');
|
|
105
|
+
const metadata = parseAgentMarkdown(content, filePath);
|
|
106
|
+
const agentCategory = extractCategory(filePath, agentsBasePath);
|
|
107
|
+
agents.push({
|
|
108
|
+
name: metadata.name || path.basename(filePath, '.md'),
|
|
109
|
+
path: path.relative(projectPath, filePath),
|
|
110
|
+
category: agentCategory,
|
|
111
|
+
description: metadata.description || '',
|
|
112
|
+
content
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
catch (error) {
|
|
116
|
+
// 개별 파일 에러는 무시하고 계속 진행
|
|
117
|
+
console.error(`Failed to read agent file: ${filePath}`, error);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
// 카테고리별 그룹핑
|
|
121
|
+
const byCategory = agents.reduce((acc, agent) => {
|
|
122
|
+
if (!acc[agent.category]) {
|
|
123
|
+
acc[agent.category] = [];
|
|
124
|
+
}
|
|
125
|
+
acc[agent.category].push(agent);
|
|
126
|
+
return acc;
|
|
127
|
+
}, {});
|
|
128
|
+
// 결과 포맷팅
|
|
129
|
+
let summary = `## Discovered Agents (${agents.length} total)\n\n`;
|
|
130
|
+
for (const [cat, catAgents] of Object.entries(byCategory)) {
|
|
131
|
+
summary += `### ${cat} (${catAgents.length})\n`;
|
|
132
|
+
for (const agent of catAgents) {
|
|
133
|
+
summary += `- **${agent.name}**: ${agent.description || 'No description'}\n`;
|
|
134
|
+
summary += ` Path: ${agent.path}\n`;
|
|
135
|
+
}
|
|
136
|
+
summary += '\n';
|
|
137
|
+
}
|
|
138
|
+
return {
|
|
139
|
+
content: [{ type: 'text', text: summary }],
|
|
140
|
+
agents // 추가 데이터로 에이전트 목록 포함
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
catch (error) {
|
|
144
|
+
return {
|
|
145
|
+
content: [{
|
|
146
|
+
type: 'text',
|
|
147
|
+
text: `Failed to discover agents: ${error instanceof Error ? error.message : String(error)}`
|
|
148
|
+
}]
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* 특정 에이전트 로드
|
|
154
|
+
*/
|
|
155
|
+
export async function loadAgent(agentName, projectPath = process.cwd()) {
|
|
156
|
+
const result = await discoverAgents({ projectPath });
|
|
157
|
+
if ('agents' in result) {
|
|
158
|
+
const agents = result.agents;
|
|
159
|
+
return agents.find(a => a.name.toLowerCase() === agentName.toLowerCase() ||
|
|
160
|
+
a.path.includes(agentName)) || null;
|
|
161
|
+
}
|
|
162
|
+
return null;
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* 카테고리별 에이전트 목록
|
|
166
|
+
*/
|
|
167
|
+
export async function listAgentsByCategory(category, projectPath = process.cwd()) {
|
|
168
|
+
const result = await discoverAgents({ projectPath, category });
|
|
169
|
+
if ('agents' in result) {
|
|
170
|
+
return result.agents;
|
|
171
|
+
}
|
|
172
|
+
return [];
|
|
173
|
+
}
|
|
174
|
+
//# sourceMappingURL=agentDiscovery.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agentDiscovery.js","sourceRoot":"","sources":["../../src/orchestrator/agentDiscovery.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Background Agent - 백그라운드 에이전트 관리
|
|
3
|
+
* oh-my-opencode의 BackgroundManager 패턴 참고
|
|
4
|
+
*/
|
|
5
|
+
import { BackgroundAgentArgs } from './types.js';
|
|
6
|
+
import { ToolResult } from '../types/tool.js';
|
|
7
|
+
/**
|
|
8
|
+
* 백그라운드 에이전트 시작
|
|
9
|
+
*/
|
|
10
|
+
export declare function launchBackgroundAgent(args: BackgroundAgentArgs): Promise<ToolResult>;
|
|
11
|
+
/**
|
|
12
|
+
* 백그라운드 에이전트 결과 조회
|
|
13
|
+
*/
|
|
14
|
+
export declare function getBackgroundAgentResult(sessionId: string): Promise<ToolResult>;
|
|
15
|
+
/**
|
|
16
|
+
* 백그라운드 에이전트 취소
|
|
17
|
+
*/
|
|
18
|
+
export declare function cancelBackgroundAgent(sessionId: string): ToolResult;
|
|
19
|
+
/**
|
|
20
|
+
* 활성 세션 목록
|
|
21
|
+
*/
|
|
22
|
+
export declare function listActiveSessions(): ToolResult;
|
|
23
|
+
/**
|
|
24
|
+
* 세션 히스토리 조회
|
|
25
|
+
*/
|
|
26
|
+
export declare function getSessionHistory(limit?: number): ToolResult;
|
|
27
|
+
/**
|
|
28
|
+
* 여러 백그라운드 에이전트 동시 실행
|
|
29
|
+
*/
|
|
30
|
+
export declare function launchParallelAgents(agentConfigs: BackgroundAgentArgs[]): Promise<ToolResult>;
|
|
31
|
+
//# sourceMappingURL=backgroundAgent.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"backgroundAgent.d.ts","sourceRoot":"","sources":["../../src/orchestrator/backgroundAgent.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACL,mBAAmB,EAKpB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AA2B9C;;GAEG;AACH,wBAAsB,qBAAqB,CAAC,IAAI,EAAE,mBAAmB,GAAG,OAAO,CAAC,UAAU,CAAC,CAqK1F;AAED;;GAEG;AACH,wBAAsB,wBAAwB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CA2CrF;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,SAAS,EAAE,MAAM,GAAG,UAAU,CAoBnE;AAED;;GAEG;AACH,wBAAgB,kBAAkB,IAAI,UAAU,CA4B/C;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,GAAE,MAAW,GAAG,UAAU,CAyBhE;AAED;;GAEG;AACH,wBAAsB,oBAAoB,CACxC,YAAY,EAAE,mBAAmB,EAAE,GAClC,OAAO,CAAC,UAAU,CAAC,CA0CrB"}
|