diff --git a/.agent/config/.env.agent.template b/.agent/config/.env.agent.template index 32d275f..b51b31f 100644 --- a/.agent/config/.env.agent.template +++ b/.agent/config/.env.agent.template @@ -13,9 +13,12 @@ AGENT_OPERATING_MODE="TEST" AGENT_PYTHON_PATH="python" # 1. Gitea Wiki (지식 동기화용) -WIKI_REPO_URL="https://git.variet.net/Variet/[YOUR_PROJECT_NAME].wiki.git" +GITEA_API_URL="https://git.variet.net/api/v1" +GITEA_USERNAME="[YOUR_GITEA_USERNAME]" +GITEA_API_TOKEN="[YOUR_GITEA_TOKEN]" +WIKI_REPO_URL="https://${GITEA_USERNAME}:${GITEA_API_TOKEN}@git.variet.net/Variet/[YOUR_PROJECT_NAME].wiki.git" # 2. Vikunja Task Board (업무 완료 보고용) VIKUNJA_API_URL="https://tasks.variet.net/api/v1" VIKUNJA_PROJECT_ID="[YOUR_PROJECT_ID]" -VIKUNJA_TOKEN="[YOUR_TOKEN_IF_NEEDED]" +VIKUNJA_API_TOKEN="[YOUR_VIKUNJA_TOKEN]" diff --git a/.agent/scripts/extract_skills.js b/.agent/scripts/extract_skills.js new file mode 100644 index 0000000..302d09d --- /dev/null +++ b/.agent/scripts/extract_skills.js @@ -0,0 +1,51 @@ +const fs = require('fs'); +const path = require('path'); + +const vendorDir = path.join(__dirname, '../vendor'); +const activeSkillsDir = path.join(__dirname, '../skills'); + +const targets = [ + { src: path.join(vendorDir, 'superpowers/skills'), type: 'directory_of_skills' }, + { src: path.join(vendorDir, 'obsidian-skills/skills'), type: 'directory_of_skills' } +]; + +let copiedCount = 0; + +if (!fs.existsSync(activeSkillsDir)) { + fs.mkdirSync(activeSkillsDir, { recursive: true }); +} + +targets.forEach(target => { + if (fs.existsSync(target.src)) { + const items = fs.readdirSync(target.src); + items.forEach(item => { + const srcPath = path.join(target.src, item); + const destPath = path.join(activeSkillsDir, item); + + if (fs.statSync(srcPath).isDirectory()) { + // Ensure SKILL.md exists before copying + if (fs.existsSync(path.join(srcPath, 'SKILL.md'))) { + // Node 16.7+ standard copy + fs.cpSync(srcPath, destPath, { recursive: true, force: true }); + copiedCount++; + } + } + }); + } +}); + +// Create .gitignore to avoid committing flattened skills to the root repo +// This keeps the Zero-Pollution architecture intact! +const gitignorePath = path.join(activeSkillsDir, '.gitignore'); +const gitignoreContent = [ + '# Auto-generated by extract_skills.js', + '*', // Ignore everything by default + '!.gitignore', // Track this file + '!ui-ux-pro-max/', // Keep manually copied ones + '!browser_use/', // Keep if explicitly placed + '!mini-swe/' +].join('\n'); + +fs.writeFileSync(gitignorePath, gitignoreContent, 'utf8'); + +console.log(`Successfully extracted and flattened ${copiedCount} internal skills to .agent/skills/`); diff --git a/.agent/scripts/sync_vikunja.js b/.agent/scripts/sync_vikunja.js new file mode 100644 index 0000000..77cf7bf --- /dev/null +++ b/.agent/scripts/sync_vikunja.js @@ -0,0 +1,91 @@ +const fs = require('fs'); +const path = require('path'); + +// 1. Get arguments +const args = process.argv.slice(2); +if (args.length < 2) { + console.error("Usage: node sync_vikunja.js "); + process.exit(1); +} + +const taskId = args[0]; +const message = args[1]; + +// 2. Load configuration from .env.agent +const envPath = path.join(__dirname, '../config/.env.agent'); +if (!fs.existsSync(envPath)) { + console.error("Error: .agent/config/.env.agent file not found. Please create it from the template."); + process.exit(1); +} + +const envContent = fs.readFileSync(envPath, 'utf8'); +const env = {}; +envContent.split('\n').forEach(line => { + const match = line.match(/^([^#=]+)="?(.*?)"?$/); + if (match) { + env[match[1].trim()] = match[2].trim(); + } +}); + +const apiUrl = env.VIKUNJA_API_URL; +const apiToken = env.VIKUNJA_API_TOKEN; + +if (!apiUrl || !apiToken || apiUrl.includes('[YOUR_')) { + console.error("Error: VIKUNJA_API_URL or VIKUNJA_API_TOKEN is not configured correctly in .env.agent."); + process.exit(1); +} + +if (env.AGENT_OPERATING_MODE === "TEST") { + console.log("⚠️ TEST Mode Active: Skipping Vikunja Webhook connection."); + process.exit(0); +} + +// 3. Helper to make API calls using native fetch (Node 18+) +async function markTaskDoneAndComment(taskId, message) { + try { + console.log(`Connecting to Vikunja API for Task ${taskId}...`); + + // Update task status to done + const patchRes = await fetch(`${apiUrl}/tasks/${taskId}`, { + method: 'POST', // Vikunja uses POST to task endpoint for updates + headers: { + 'Authorization': `Bearer ${apiToken}`, + 'Content-Type': 'application/json' + }, + body: JSON.stringify({ done: true }) + }); + + if (!patchRes.ok) { + throw new Error(`Failed to mark task as done: ${patchRes.statusText}`); + } + + console.log(`✅ Task ${taskId} successfully marked as Done.`); + + // Add comment + const commentRes = await fetch(`${apiUrl}/tasks/${taskId}/comments`, { + method: 'PUT', + headers: { + 'Authorization': `Bearer ${apiToken}`, + 'Content-Type': 'application/json' + }, + body: JSON.stringify({ + text: `[Agent Automator] Phase completed.\nReason/Hash: ${message}` + }) + }); + + if (!commentRes.ok) { + console.error(`Warning: Task marked as done, but failed to attach comment: ${commentRes.statusText}`); + } else { + console.log("✅ Comment attached successfully."); + } + + } catch (error) { + console.error("❌ Failed to sync with Vikunja:"); + // Mask the token if it somehow leaks via error message + const secureErr = error.message.replace(new RegExp(apiToken, 'g'), "********"); + console.error(secureErr); + process.exit(1); + } +} + +markTaskDoneAndComment(taskId, message); diff --git a/.agent/scripts/sync_wiki.js b/.agent/scripts/sync_wiki.js new file mode 100644 index 0000000..71c1a0c --- /dev/null +++ b/.agent/scripts/sync_wiki.js @@ -0,0 +1,77 @@ +const fs = require('fs'); +const path = require('path'); +const { execSync } = require('child_process'); + +// 1. Load configuration from .env.agent +const envPath = path.join(__dirname, '../config/.env.agent'); +if (!fs.existsSync(envPath)) { + console.error("Error: .agent/config/.env.agent file not found. Please create it from the template."); + process.exit(1); +} + +const envContent = fs.readFileSync(envPath, 'utf8'); +const env = {}; +envContent.split('\n').forEach(line => { + // Basic dotenv parser supporting basic key="value" formats + const match = line.match(/^([^#=]+)="?(.*?)"?$/); + if (match) { + env[match[1].trim()] = match[2].trim(); + } +}); + +// 2. Resolve Wiki URL (handle simple interpolations) +let wikiUrl = env.WIKI_REPO_URL; +if (!wikiUrl) { + console.error("Error: WIKI_REPO_URL is not defined in .env.agent."); + process.exit(1); +} + +if (wikiUrl.includes('${GITEA_USERNAME}')) { + wikiUrl = wikiUrl.replace('${GITEA_USERNAME}', env.GITEA_USERNAME || ''); +} +if (wikiUrl.includes('${GITEA_API_TOKEN}')) { + wikiUrl = wikiUrl.replace('${GITEA_API_TOKEN}', env.GITEA_API_TOKEN || ''); +} + +if (wikiUrl.includes('[YOUR_')) { + console.error("Warning: WIKI_REPO_URL looks like it contains placeholder tags ([YOUR_...]). Ensure the config is set up correctly."); + // We let it proceed in case it's a test environment with dummy tags +} + +// 3. Execute Git commands in the Wiki directory +const wikiDir = path.join(__dirname, '../../.knowledge/project_wiki'); + +if (!fs.existsSync(path.join(wikiDir, '.git'))) { + console.error(`Error: .git repository not found inside ${wikiDir}. Wiki must be initialized via git first.`); + process.exit(1); +} + +try { + console.log("Adding Wiki changes..."); + execSync('git add .', { cwd: wikiDir, stdio: 'inherit' }); + + // Check if there are changes to commit + const status = execSync('git status --porcelain', { cwd: wikiDir }).toString(); + if (status.trim().length > 0) { + console.log("Committing changes..."); + execSync('git commit -m "docs(agent): Auto-sync Wiki from Antigravity Agent"', { cwd: wikiDir, stdio: 'inherit' }); + } else { + console.log("No changes to commit in Wiki."); + } + + console.log("Pushing to Gitea Wiki repository..."); + // WARNING: Output masking is not actively done here; this relies on the underlying tool to obscure tokens if echoed, + // but execSync with 'inherit' might leak the URL if git fails. We mask it manually for display, but git handles the URL internally. + execSync(`git push "${wikiUrl}" main`, { cwd: wikiDir, stdio: 'pipe' }); + console.log("✅ Wiki synchronization completed successfully."); +} catch (e) { + console.error("❌ Failed to sync wiki."); + // Mask API tokens in error messages + const errorMessage = e.message.replace(new RegExp(env.GITEA_API_TOKEN || 'dummy', 'g'), '********'); + console.error(errorMessage); + if (e.stderr) { + const stderrStr = e.stderr.toString().replace(new RegExp(env.GITEA_API_TOKEN || 'dummy', 'g'), '********'); + console.error(stderrStr); + } + process.exit(1); +} diff --git a/.agent/scripts/translate_gsd.js b/.agent/scripts/translate_gsd.js new file mode 100644 index 0000000..70376ab --- /dev/null +++ b/.agent/scripts/translate_gsd.js @@ -0,0 +1,93 @@ +const fs = require('fs'); +const path = require('path'); + +const skillDir = 'C:\\Users\\Certes\\.gemini\\antigravity\\skills'; + +const translations = { + "Manage parallel workstreams — list, create, switch, status, progress, complete, and resume": "병렬 작업 스트림 관리 — 목록, 생성, 전환, 상태, 진행률, 완료 및 재개", + "Validate built features through conversational UAT": "대화형 UAT를 통해 구현된 기능 검증", + "Retroactively audit and fill Nyquist validation gaps for a completed phase": "완료된 단계에 대한 검증 누락 사후 감사 및 보완", + "Update GSD to latest version with changelog display": "GSD를 최신 버전으로 업데이트하고 변경 사항 표시", + "Retroactive 6-pillar visual audit of implemented frontend code": "구현된 프론트엔드 코드에 대한 6개 요소 시각적 사후 감사", + "Generate UI design contract (UI-SPEC.md) for frontend phases": "프론트엔드 단계를 위한 UI 디자인 명세서(UI-SPEC.md) 생성", + "Manage persistent context threads for cross-session work": "교차 세션 작업을 위한 영구 컨텍스트 스레드 관리", + "Display project statistics — phases, plans, requirements, git metrics, and timeline": "프로젝트 통계 표시 — 단계, 계획, 요구사항, Git 지표 및 타임라인", + "Create PR, run review, and prepare for merge after verification passes": "검증 통과 후 PR 생성, 리뷰 실행 및 병합 준비", + "Configure GSD workflow toggles and model profile": "GSD 워크플로우 옵션 및 모델 프로필 구성", + "Switch model profile for GSD agents (quality/balanced/budget/inherit)": "GSD 요원의 모델 프로필 전환 (고품질/균형/예산/상속)", + "Generate a session report with token usage estimates, work summary, and outcomes": "토큰 사용량, 작업 요약 및 결과를 포함한 세션 보고서 생성", + "Review and promote backlog items to active milestone": "백로그 항목을 검토하고 활성 마일스톤으로 승격", + "Request cross-AI peer review of phase plans from external AI CLIs": "외부 AI CLI에 단계 계획에 대한 교차 AI 동료 리뷰 요청", + "Resume work from previous session with full context restoration": "전체 컨텍스트 복원과 함께 이전 세션에서 작업 재개", + "Research how to implement a phase (standalone - usually use /gsd-plan-phase instead)": "단계를 구현하는 방법 리서치 (단독 실행 - 보통 /gsd-plan-phase 사용)", + "Remove a GSD workspace and clean up worktrees": "GSD 워크스페이스 제거 및 워크트리 정리", + "Remove a future phase from roadmap and renumber subsequent phases": "로드맵에서 향후 단계를 제거하고 이후 단계 번호 재지정", + "Reapply local modifications after a GSD update": "GSD 업데이트 후 로컬 수정 사항 재적용", + "Execute a quick task with GSD guarantees (atomic commits, state tracking) but skip optional agents": "GSD 보장(원자적 커밋, 상태 추적)을 사용하여 빠른 작업을 실행하되 선택적 요원 생략", + "Check project progress, show context, and route to next action (execute or plan)": "프로젝트 진행 상황 확인, 컨텍스트 표시 및 다음 작업(실행 또는 계획)으로 라우팅", + "Generate developer behavioral profile and create Claude-discoverable artifacts": "개발자 행동 프로필을 생성하고 AI가 인지할 수 있는 문서 작성", + "Create a clean PR branch by filtering out .planning/ commits — ready for code review": ".planning/ 커밋을 필터링하여 깔끔한 PR 브랜치 생성 — 코드 리뷰 준비", + "Capture a forward-looking idea with trigger conditions — surfaces automatically at the right milestone": "향후 아이디어를 트리거 조건과 함께 캡처 — 적절한 마일스톤에서 자동 표시", + "Create detailed phase plan (PLAN.md) with verification loop": "검증 루프를 포함한 상세 단계 계획(PLAN.md) 생성", + "Create phases to close all gaps identified by milestone audit": "마일스톤 감사에서 식별된 모든 격차를 해소하기 위한 단계 생성", + "Create context handoff when pausing work mid-phase": "작업 중단 시 컨텍스트 인수인계 파일 생성", + "Zero-friction idea capture. Append, list, or promote notes to todos.": "방해 없는 아이디어 캡처. 메모 추가, 나열 또는 할 일로 승격.", + "Automatically advance to the next logical step in the GSD workflow": "GSD 워크플로우의 다음 논리적 단계로 자동 진행", + "Create an isolated workspace with repo copies and independent .planning/": "외부 레포 사본 및 독립적인 .planning/을 갖춘 격리된 워크스페이스 생성", + "Initialize a new project with deep context gathering and PROJECT.md": "심층 컨텍스트 수집 및 PROJECT.md와 함께 새 프로젝트 초기화", + "Start a new milestone cycle — update PROJECT.md and route to requirements": "새로운 마일스톤 주기 시작 — PROJECT.md 업데이트 및 요구사항 재정의", + "Generate a comprehensive project summary from milestone artifacts for team onboarding and review": "팀 온보딩 및 리뷰를 위해 마일스톤 산출물에서 종합적인 프로젝트 요약 생성", + "Analyze codebase with parallel mapper agents to produce .planning/codebase/ documents": "병렬 매퍼 요원으로 코드베이스를 분석하여 .planning/codebase/ 문서 생성", + "Interactive command center for managing multiple phases from one terminal": "하나의 터미널에서 여러 단계를 관리하는 대화형 명령 센터", + "List active GSD workspaces and their status": "활성 GSD 워크스페이스 및 상태 나열", + "Surface the agent's assumptions about a phase approach before planning": "계획 전 단계적 접근 방식에 대한 요원의 가정을 미리 표시", + "Join the GSD Discord community": "GSD 디스코드 커뮤니티 참가", + "Insert urgent work as decimal phase (e.g., 72.1) between existing phases": "기존 단계 사이에 소수점 단계(예: 72.1)로 긴급 작업 삽입", + "Show available GSD commands and usage guide": "사용 가능한 GSD 명령어 및 사용 가이드 표시", + "Diagnose planning directory health and optionally repair issues": "계획 디렉토리 상태 진단 및 선택적으로 문제 복구", + "Post-mortem investigation for failed GSD workflows — analyzes git history, artifacts, and state to diagnose what went wrong": "실패한 GSD 워크플로우에 대한 사후 조사 — git 기록, 문서 및 상태 분석", + "Execute a trivial task inline — no subagents, no planning overhead": "인라인으로 사소한 작업 실행 — 서브 에이전트 및 계획 오버헤드 없음", + "Execute all plans in a phase with wave-based parallelization": "웨이브(Wave) 기반 병렬 처리를 사용하여 단계의 모든 계획 실행", + "Route freeform text to the right GSD command automatically": "자유 형식 텍스트를 적절한 GSD 명령으로 자동 라우팅", + "Systematic debugging with persistent state across context resets": "컨텍스트가 리셋되어도 상태를 유지하는 체계적인 디버깅", + "Gather phase context through adaptive questioning before planning. Use --auto to skip interactive questions (the agent picks recommended defaults).": "계획 전 심층 질문을 통해 단계 컨텍스트 수집. 대화형 건너뛰기(--auto) 가능.", + "Archive completed milestone and prepare for next version": "완료된 마일스톤 보관 및 다음 버전 준비", + "List pending todos and select one to work on": "보류 중인 할 일 목록 표시 및 작업할 항목 선택", + "Cross-phase audit of all outstanding UAT and verification items": "모든 미결 UAT 및 검증 항목에 대한 전체 단계 교차 감사", + "Audit milestone completion against original intent before archiving": "보관 전 원래 의도와 비교하여 마일스톤 달성 여부 감사", + "Capture idea or task as todo from current conversation context": "현재 대화 컨텍스트에서 아이디어 또는 작업을 할 일로 캡처", + "Generate tests for a completed phase based on UAT criteria and implementation": "UAT 기준 및 구현을 기반으로 완료된 단계에 대한 테스트 생성", + "Add phase to end of current milestone in roadmap": "로드맵의 현재 마일스톤 끝에 새 단계 추가", + "Add an idea to the backlog parking lot (999.x numbering)": "백로그 주차장(999.x 넘버링)에 아이디어 추가", + "Run all remaining phases autonomously — discuss→plan→execute per phase": "모든 남은 단계를 완전히 자율적으로 실행 (논의→계획→실행 루프)", + "Archive accumulated phase directories from completed milestones": "완료된 마일스톤에서 쌓인 단계 디렉토리 보관 및 정리" +}; + +let modifiedCount = 0; + +try { + const dirs = fs.readdirSync(skillDir); + for (const d of dirs) { + if (d.startsWith('gsd-')) { + const skillPath = path.join(skillDir, d, 'SKILL.md'); + if (fs.existsSync(skillPath)) { + const content = fs.readFileSync(skillPath, 'utf8'); + let newContent = content; + for (const [eng, kor] of Object.entries(translations)) { + // Escape regex special chars in english text + const escapedEng = eng.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); + const regex = new RegExp(`^description:\\s*${escapedEng}\\s*$`, 'm'); + newContent = newContent.replace(regex, `description: ${kor}`); + } + if (newContent !== content) { + fs.writeFileSync(skillPath, newContent, 'utf8'); + modifiedCount++; + } + } + } + } + console.log(`Successfully translated ${modifiedCount} SKILL.md files.`); +} catch (e) { + console.error(e); + process.exit(1); +} diff --git a/.agent/scripts/translate_gsd.py b/.agent/scripts/translate_gsd.py new file mode 100644 index 0000000..e5e5708 --- /dev/null +++ b/.agent/scripts/translate_gsd.py @@ -0,0 +1,86 @@ +import os +import glob +import re + +skill_dir = r"C:\Users\Certes\.gemini\antigravity\skills" + +translations = { + "Manage parallel workstreams — list, create, switch, status, progress, complete, and resume": "병렬 작업 스트림 관리 — 목록, 생성, 전환, 상태, 진행률, 완료 및 재개", + "Validate built features through conversational UAT": "대화형 UAT를 통해 구현된 기능 검증", + "Retroactively audit and fill Nyquist validation gaps for a completed phase": "완료된 단계에 대한 검증 누락 사후 감사 및 보완", + "Update GSD to latest version with changelog display": "GSD를 최신 버전으로 업데이트하고 변경 사항 표시", + "Retroactive 6-pillar visual audit of implemented frontend code": "구현된 프론트엔드 코드에 대한 6개 요소 시각적 사후 감사", + "Generate UI design contract (UI-SPEC.md) for frontend phases": "프론트엔드 단계를 위한 UI 디자인 명세서(UI-SPEC.md) 생성", + "Manage persistent context threads for cross-session work": "교차 세션 작업을 위한 영구 컨텍스트 스레드 관리", + "Display project statistics — phases, plans, requirements, git metrics, and timeline": "프로젝트 통계 표시 — 단계, 계획, 요구사항, Git 지표 및 타임라인", + "Create PR, run review, and prepare for merge after verification passes": "검증 통과 후 PR 생성, 리뷰 실행 및 병합 준비", + "Configure GSD workflow toggles and model profile": "GSD 워크플로우 옵션 및 모델 프로필 구성", + "Switch model profile for GSD agents (quality/balanced/budget/inherit)": "GSD 요원의 모델 프로필 전환 (고품질/균형/예산/상속)", + "Generate a session report with token usage estimates, work summary, and outcomes": "토큰 사용량, 작업 요약 및 결과를 포함한 세션 보고서 생성", + "Review and promote backlog items to active milestone": "백로그 항목을 검토하고 활성 마일스톤으로 승격", + "Request cross-AI peer review of phase plans from external AI CLIs": "외부 AI CLI에 단계 계획에 대한 교차 AI 동료 리뷰 요청", + "Resume work from previous session with full context restoration": "전체 컨텍스트 복원과 함께 이전 세션에서 작업 재개", + "Research how to implement a phase (standalone - usually use /gsd-plan-phase instead)": "단계를 구현하는 방법 리서치 (단독 실행 - 보통 /gsd-plan-phase 사용)", + "Remove a GSD workspace and clean up worktrees": "GSD 워크스페이스 제거 및 워크트리 정리", + "Remove a future phase from roadmap and renumber subsequent phases": "로드맵에서 향후 단계를 제거하고 이후 단계 번호 재지정", + "Reapply local modifications after a GSD update": "GSD 업데이트 후 로컬 수정 사항 재적용", + "Execute a quick task with GSD guarantees (atomic commits, state tracking) but skip optional agents": "GSD 보장(원자적 커밋, 상태 추적)을 사용하여 빠른 작업을 실행하되 선택적 요원 생략", + "Check project progress, show context, and route to next action (execute or plan)": "프로젝트 진행 상황 확인, 컨텍스트 표시 및 다음 작업(실행 또는 계획)으로 라우팅", + "Generate developer behavioral profile and create Claude-discoverable artifacts": "개발자 행동 프로필을 생성하고 AI가 인지할 수 있는 문서 작성", + "Create a clean PR branch by filtering out .planning/ commits — ready for code review": ".planning/ 커밋을 필터링하여 깔끔한 PR 브랜치 생성 — 코드 리뷰 준비", + "Capture a forward-looking idea with trigger conditions — surfaces automatically at the right milestone": "향후 아이디어를 트리거 조건과 함께 캡처 — 적절한 마일스톤에서 자동 표시", + "Create detailed phase plan (PLAN.md) with verification loop": "검증 루프를 포함한 상세 단계 계획(PLAN.md) 생성", + "Create phases to close all gaps identified by milestone audit": "마일스톤 감사에서 식별된 모든 격차를 해소하기 위한 단계 생성", + "Create context handoff when pausing work mid-phase": "작업 중단 시 컨텍스트 인수인계 파일 생성", + "Zero-friction idea capture. Append, list, or promote notes to todos.": "방해 없는 아이디어 캡처. 메모 추가, 나열 또는 할 일로 승격.", + "Automatically advance to the next logical step in the GSD workflow": "GSD 워크플로우의 다음 논리적 단계로 자동 진행", + "Create an isolated workspace with repo copies and independent .planning/": "외부 레포 사본 및 독립적인 .planning/을 갖춘 격리된 워크스페이스 생성", + "Initialize a new project with deep context gathering and PROJECT.md": "심층 컨텍스트 수집 및 PROJECT.md와 함께 새 프로젝트 초기화", + "Start a new milestone cycle — update PROJECT.md and route to requirements": "새로운 마일스톤 주기 시작 — PROJECT.md 업데이트 및 요구사항 재정의", + "Generate a comprehensive project summary from milestone artifacts for team onboarding and review": "팀 온보딩 및 리뷰를 위해 마일스톤 산출물에서 종합적인 프로젝트 요약 생성", + "Analyze codebase with parallel mapper agents to produce .planning/codebase/ documents": "병렬 매퍼 요원으로 코드베이스를 분석하여 .planning/codebase/ 문서 생성", + "Interactive command center for managing multiple phases from one terminal": "하나의 터미널에서 여러 단계를 관리하는 대화형 명령 센터", + "List active GSD workspaces and their status": "활성 GSD 워크스페이스 및 상태 나열", + "Surface the agent's assumptions about a phase approach before planning": "계획 전 단계적 접근 방식에 대한 요원의 가정을 미리 표시", + "Join the GSD Discord community": "GSD 디스코드 커뮤니티 참가", + "Insert urgent work as decimal phase (e.g., 72.1) between existing phases": "기존 단계 사이에 소수점 단계(예: 72.1)로 긴급 작업 삽입", + "Show available GSD commands and usage guide": "사용 가능한 GSD 명령어 및 사용 가이드 표시", + "Diagnose planning directory health and optionally repair issues": "계획 디렉토리 상태 진단 및 선택적으로 문제 복구", + "Post-mortem investigation for failed GSD workflows — analyzes git history, artifacts, and state to diagnose what went wrong": "실패한 GSD 워크플로우에 대한 사후 조사 — git 기록, 문서 및 상태 분석", + "Execute a trivial task inline — no subagents, no planning overhead": "인라인으로 사소한 작업 실행 — 서브 에이전트 및 계획 오버헤드 없음", + "Execute all plans in a phase with wave-based parallelization": "웨이브(Wave) 기반 병렬 처리를 사용하여 단계의 모든 계획 실행", + "Route freeform text to the right GSD command automatically": "자유 형식 텍스트를 적절한 GSD 명령으로 자동 라우팅", + "Systematic debugging with persistent state across context resets": "컨텍스트가 리셋되어도 상태를 유지하는 체계적인 디버깅", + "Gather phase context through adaptive questioning before planning. Use --auto to skip interactive questions (the agent picks recommended defaults).": "계획 전 심층 질문을 통해 단계 컨텍스트 수집. 대화형 건너뛰기(--auto) 가능.", + "Archive completed milestone and prepare for next version": "완료된 마일스톤 보관 및 다음 버전 준비", + "List pending todos and select one to work on": "보류 중인 할 일 목록 표시 및 작업할 항목 선택", + "Cross-phase audit of all outstanding UAT and verification items": "모든 미결 UAT 및 검증 항목에 대한 전체 단계 교차 감사", + "Audit milestone completion against original intent before archiving": "보관 전 원래 의도와 비교하여 마일스톤 달성 여부 감사", + "Capture idea or task as todo from current conversation context": "현재 대화 컨텍스트에서 아이디어 또는 작업을 할 일로 캡처", + "Generate tests for a completed phase based on UAT criteria and implementation": "UAT 기준 및 구현을 기반으로 완료된 단계에 대한 테스트 생성", + "Add phase to end of current milestone in roadmap": "로드맵의 현재 마일스톤 끝에 새 단계 추가", + "Add an idea to the backlog parking lot (999.x numbering)": "백로그 주차장(999.x 넘버링)에 아이디어 추가", + "Run all remaining phases autonomously — discuss→plan→execute per phase": "모든 남은 단계를 완전히 자율적으로 실행 (논의→계획→실행 루프)", + "Archive accumulated phase directories from completed milestones": "완료된 마일스톤에서 쌓인 단계 디렉토리 보관 및 정리" +} + +modified_count = 0 + +for filepath in glob.glob(os.path.join(skill_dir, "gsd-*", "SKILL.md")): + try: + with open(filepath, 'r', encoding='utf-8') as f: + content = f.read() + + new_content = content + for eng, kor in translations.items(): + pattern = re.compile(r"^description:\s*" + re.escape(eng) + r"\s*$", re.MULTILINE) + new_content = pattern.sub(f"description: {kor}", new_content) + + if new_content != content: + with open(filepath, 'w', encoding='utf-8') as f: + f.write(new_content) + modified_count += 1 + except Exception as e: + print(f"Error processing {filepath}: {e}") + +print(f"Successfully translated {modified_count} SKILL.md files.") diff --git a/.agent/scripts/translate_skills.js b/.agent/scripts/translate_skills.js new file mode 100644 index 0000000..fb77a38 --- /dev/null +++ b/.agent/scripts/translate_skills.js @@ -0,0 +1,53 @@ +const fs = require('fs'); +const path = require('path'); + +const skillsDir = path.join(__dirname, '../skills'); + +// Translation Dictionary (Folder Name -> Korean Description) +const translations = { + 'brainstorming': '창의적인 작업(기능 추가, 컴포넌트 설계) 시작 전 필수 사용. 구현 전 의도와 요구사항을 파악하고 기획합니다.', + 'defuddle': 'URL 링크를 통해 웹페이지 문서의 군더더기를 제거하고 깔끔한 마크다운 정보만 추출하여 분석합니다.', + 'dispatching-parallel-agents': '상태 공유나 순차적 의존성이 없는 2개 이상의 독립적인 작업을 병렬로 처리할 때 사용합니다.', + 'executing-plans': '작성된 구현 계획서(PLAN)를 바탕으로 단계별 코드 작성을 실행하고 리뷰 체크포인트를 수행합니다.', + 'finishing-a-development-branch': '구현 및 테스트가 100% 완료된 후, 브랜치 병합(Merge/PR)을 결정하거나 정리하는 마무리 스킬입니다.', + 'json-canvas': 'JSON Canvas 형식의 시각적 마인드맵, 노드, 다이어그램, 플로우차트 파일(.canvas)을 생성하고 편집합니다.', + 'obsidian-bases': '옵시디언의 데이터베이스 뷰, 필터, 수식, 요약 기능 등을 포함하는 Base 파일(.base)을 통제합니다.', + 'obsidian-cli': '옵시디언 CLI 환경을 제어해 노트를 검색/생성하고, 플러그인을 디버깅하거나 에러를 캡처합니다.', + 'obsidian-markdown': '위키링크([[ ]]), 콜아웃, 프로퍼티(YAML) 등 옵시디언에 특화된 마크다운 문법(.md)을 완벽하게 작성합니다.', + 'receiving-code-review': '코드 리뷰 피드백을 수신했을 때, 무지성으로 반영하기 전 기술적인 타당성과 엣지 케이스를 검증합니다.', + 'requesting-code-review': '주요 기능 구현이 끝났을 때, 코드를 메인(Main)에 병합하기 전 엄격한 품질 검증(코드 리뷰)을 스스로 요청합니다.', + 'subagent-driven-development': '구현 계획서 내의 독립적인 작업(Task)들을 여러 하위 에이전트(Subagent)에게 병렬로 위임하여 개발을 가속합니다.', + 'systematic-debugging': '버그, 테스트 실패, 예기치 않은 동작 발생 시, 해결책을 던지기 전 체계적인 디버깅 루프를 가동합니다.', + 'test-driven-development': '실제 운영 코드를 작성하기 전, 무조건 먼저 실패하는 테스트 코드(TDD)를 작성하여 기능 명세를 강제합니다.', + 'using-git-worktrees': '대규모 리팩토링이나 새로운 기능을 시작할 때 메인 환경을 오염시키지 않도록 격리된 Git Worktree를 생성합니다.', + 'using-superpowers': '대화 시작 시 1회 필수 가동 스킬. 에이전트가 어떤 스킬과 자원을 보유하고 있는지 파악하고 환경을 준비합니다.', + 'verification-before-completion': '작업을 최종 완료 처리하기 전, 테스트와 검증 명령어 라인을 강제로 실행하여 완벽한 성공 여부를 증명합니다.', + 'writing-plans': '본격적인 코드 작성에 돌입하기 전, 복잡한 요구사항에 대한 아키텍처 스펙과 다단계 구현 계획서를 수립합니다.', + 'writing-skills': '현재 CLI 시스템에 새로운 스킬 룰을 구축하거나, 기존 스킬 문서를 수정 및 디버깅할 때 사용합니다.' +}; + +let translatedCount = 0; + +if (fs.existsSync(skillsDir)) { + const folders = fs.readdirSync(skillsDir); + + folders.forEach(folder => { + const skillPath = path.join(skillsDir, folder, 'SKILL.md'); + + if (translations[folder] && fs.existsSync(skillPath)) { + let content = fs.readFileSync(skillPath, 'utf8'); + + // Regex to match existing description in YAML frontmatter (with or without quotes) + // It matches 'description:' followed by anything until the end of the line + const newContent = content.replace(/^description:\s*(?:".*?"|.*)$/m, `description: ${translations[folder]}`); + + if (content !== newContent) { + fs.writeFileSync(skillPath, newContent, 'utf8'); + console.log(`[Translated] ${folder}`); + translatedCount++; + } + } + }); +} + +console.log(`\n🎉 번역 완료: 총 ${translatedCount}개의 스킬 설명이 로컬라이징 되었습니다.`); diff --git a/.agent/skills/.gitignore b/.agent/skills/.gitignore new file mode 100644 index 0000000..432a63a --- /dev/null +++ b/.agent/skills/.gitignore @@ -0,0 +1,6 @@ +# Auto-generated by extract_skills.js +* +!.gitignore +!ui-ux-pro-max/ +!browser_use/ +!mini-swe/ \ No newline at end of file diff --git a/.agent/skills/ui-ux-pro-max/SKILL.md b/.agent/skills/ui-ux-pro-max/SKILL.md index 72ac2c3..7fd72c8 100644 --- a/.agent/skills/ui-ux-pro-max/SKILL.md +++ b/.agent/skills/ui-ux-pro-max/SKILL.md @@ -1,6 +1,6 @@ --- name: ui-ux-pro-max -description: UI/UX design intelligence. 50 styles, 21 palettes, 50 font pairings, 20 charts, 9 stacks. +description: UI/UX 디자인 AI. 50종의 스타일, 21종의 컬러 팔레트, 디자인 시스템 적용 --- # ui-ux-pro-max diff --git a/.agent/skills/browser_use b/.agent/vendor/browser_use similarity index 100% rename from .agent/skills/browser_use rename to .agent/vendor/browser_use diff --git a/.agent/skills/mini-swe b/.agent/vendor/mini-swe similarity index 100% rename from .agent/skills/mini-swe rename to .agent/vendor/mini-swe diff --git a/.agent/skills/obsidian-skills b/.agent/vendor/obsidian-skills similarity index 100% rename from .agent/skills/obsidian-skills rename to .agent/vendor/obsidian-skills diff --git a/.agent/skills/superpowers b/.agent/vendor/superpowers similarity index 100% rename from .agent/skills/superpowers rename to .agent/vendor/superpowers diff --git a/.agent/workflows/agent_lifecycle_sop.md b/.agent/workflows/agent_lifecycle_sop.md index 841ce3b..a492b3e 100644 --- a/.agent/workflows/agent_lifecycle_sop.md +++ b/.agent/workflows/agent_lifecycle_sop.md @@ -1,7 +1,3 @@ ---- -description: Universal Agent Lifecycle SOP ---- - # 🤖 The Antigravity Agent Lifecycle SOP (Final Master) 이 문서는 `new_gene` 템플릿 환경에서 코딩을 수행하는 모든 AI 에이전트(Antigravity, Claude Code, Gemini CLI 등)가 **무조건 준수해야 하는 최우선 행동 강령(Single Source of Truth)** 입니다. 과거 `antig_web`의 위대한 유산(Devlog, 오답노트)과 8대 최첨단 기민성 오픈소스가 완전히 결합된 최종 보루입니다. @@ -37,5 +33,5 @@ description: Universal Agent Lifecycle SOP 작업(Task/Phase)이 끝나고 "마무리/끝" 지시를 받으면 아래 절차로 에이전트 활동을 종료합니다. 1. **Devlog (일일 개발 일지) 작성:** 단순 코드 외에 '설계 결정(왜 A 대신 B를 택했나)', '미완료 사항', '트러블슈팅'이 있었다면, 반드시 **`.knowledge/project_wiki/devlog/YYYY-MM-DD.md`** 에 양방향 링크(`[[문서명]]`)를 써서 기록합니다 (기존 과거 Devlog 시스템 완벽 계승). -2. **Wiki 자동 동기화:** 코드의 아키텍처나 API가 변경된 경우, `obsidian-skills` 프롬프트를 바탕으로 `.knowledge/project_wiki/` 내부 문서를 최신화하고 `git push`를 날려 인간의 웹 뷰(Gitea Wiki)를 갱신합니다. -3. **Vikunja 하이라키 동기화 (PROJECT 모드 한정):** `.agent/config/.env.agent` 의 `AGENT_OPERATING_MODE`가 `PROJECT`일 경우에 한하여, 로컬의 Get-Shit-Done(GSD) `.planning/` 단계에서 한 에픽(Phase)이 완전히 끝났을 때 해당 커밋 해시와 작업 내역을 묶어 **Vikunja 웹 대시보드**에 1회 매핑 및 `Done` 처리 하십시오. (마이크로 태스크의 잦은 복사 금지. TEST 모드일 경우 이 동기화를 강제로 스킵합니다). +2. **Wiki 자동 동기화:** 아키텍처나 API가 변경된 경우 `.knowledge/project_wiki/` 내부 문서를 최신화한 뒤, 반드시 터미널에서 `node .agent/scripts/sync_wiki.js` 스크립트를 실행하여 Gitea Wiki 원격 저장소에 Push 하십시오 (토큰 노출 방지를 위해 날것의 curl이나 git push 금지). +3. **Vikunja 하이라키 동기화 (PROJECT 모드 한정):** `.env.agent` 의 `AGENT_OPERATING_MODE`가 `PROJECT`일 경우에 한하여, 로컬의 Get-Shit-Done(GSD) `.planning/` 단계에서 한 에픽(Phase)이 완전히 끝났을 때 터미널에서 `node .agent/scripts/sync_vikunja.js "작업명/ID" "완료 사유/커밋해시"` 스크립트를 실행해 Vikunja 웹 대시보드에 1회 매핑 및 `Done` 처리를 수행하십시오. (TEST 모드일 경우 이 동기화를 강제로 스킵합니다). diff --git a/.gitignore b/.gitignore index 6f81fff..5a94dce 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,5 @@ .claude/ .gemini/ *.log +.agent/config/.env.agent +.knowledge/project_wiki/ diff --git a/.gitmodules b/.gitmodules index 47972a5..fb7cc0a 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,5 +1,5 @@ [submodule ".agent/skills/superpowers"] - path = .agent/skills/superpowers + path = .agent/vendor/superpowers url = https://github.com/obra/superpowers.git branch = main [submodule ".agent/knowledge/everything_claude"] @@ -11,7 +11,7 @@ url = https://github.com/hesreallyhim/awesome-claude-code.git branch = main [submodule ".agent/skills/obsidian-skills"] - path = .agent/skills/obsidian-skills + path = .agent/vendor/obsidian-skills url = https://github.com/kepano/obsidian-skills.git branch = main [submodule ".agent/services/claude-mem"] @@ -23,10 +23,10 @@ url = https://github.com/modelcontextprotocol/servers.git branch = main [submodule ".agent/skills/browser_use"] - path = .agent/skills/browser_use + path = .agent/vendor/browser_use url = https://github.com/browser-use/browser-use.git branch = main [submodule ".agent/skills/mini-swe"] - path = .agent/skills/mini-swe + path = .agent/vendor/mini-swe url = https://github.com/swe-agent/swe-agent.git branch = main