From 421e9a1316c0e61f0f1382bd5c0b8585b2547f62 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 27 Feb 2026 13:01:50 +0000 Subject: [PATCH 1/2] Initial plan From 22b8bc5b57da94de9cbdb16c07f1f5fa8c04d9be Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 27 Feb 2026 13:07:24 +0000 Subject: [PATCH 2/2] docs: add onboarding docs and setup scripts (fix missing files from #6) Co-authored-by: redsunjin <17919877+redsunjin@users.noreply.github.com> --- .env.example | 18 ++ README.md | 378 ++++------------------------------------- USER_GUIDE.md | 190 +++++++++++++++++++++ docs/PLAN.md | 380 ++++++++++++++++++++++++++++++++++++++++++ package.json | 5 +- scripts/configure.js | 85 ++++++++++ scripts/setup_env.ps1 | 53 ++++++ scripts/setup_env.sh | 55 ++++++ 8 files changed, 819 insertions(+), 345 deletions(-) create mode 100644 .env.example create mode 100644 USER_GUIDE.md create mode 100644 docs/PLAN.md create mode 100644 scripts/configure.js create mode 100644 scripts/setup_env.ps1 create mode 100755 scripts/setup_env.sh diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..198e490 --- /dev/null +++ b/.env.example @@ -0,0 +1,18 @@ +# Maestro Coding — 환경변수 예시 +# 이 파일을 복사하여 .env 파일을 만들고 실제 값으로 채워주세요. +# cp .env.example .env +# +# ⚠️ 실제 .env 파일은 절대 Git에 커밋하지 마세요! + +# git merge / git reset을 실행할 메인 레포지토리의 로컬 경로 (필수 권장) +MAIN_REPO_PATH=/path/to/your/main/repo + +# 서버 리스닝 포트 (기본: 8080) +PORT=8080 + +# 인증 토큰 — 설정 시 요청에 Authorization: Bearer 헤더 필요 +# 빈 값으로 두면 인증 없이 동작합니다. +MAESTRO_SERVER_TOKEN=your-secret-token-here + +# 프론트엔드가 연결할 WebSocket 주소 (기본: ws://localhost:8080) +VITE_WS_URL=ws://localhost:8080 diff --git a/README.md b/README.md index 89991ad..be695ef 100644 --- a/README.md +++ b/README.md @@ -1,373 +1,63 @@ # Maestro Coding -

- - Demo - -

+코딩을 지휘하다 — AI 에이전트와 함께하는 코드 심포니 🎼 -## 🎼 '마에스트로 코딩(Maestro Coding)' +## 컨셉 (Concept) -### 1. 핵심 메시지 (Core Message) +Maestro는 AI 에이전트가 생성하거나 수정한 코드 변경을 "승인 노트" 형태로 제시하고, 사람이 빠르게 승인/반려하여 안전하게 병합하도록 돕는 개발 보조 도구입니다. -* **Before:** 여러 에이전트와 창을 띄워놓고 쏟아지는 PR과 커밋 알림에 쫓기며 클릭질하는 스트레스 넘치는 개발자. -* **After:** 바흐의 선율 속에서, 투명하게 오버레이된 건반형 대시보드를 통해 리드미컬하게 다수의 에이전트를 지휘하는 우아한 개발자. -* **Slogan:** "코딩을 지휘하다, AI 에이전트와 함께하는 코드 심포니." +## 만든 목적 (Purpose) -### 2. 단계별 콘텐츠 전개 전략 +- AI 에이전트 자동 생성 코드를 인간이 빠르게 확인하고 승인할 수 있도록 가시화 +- 승인(merge) 워크플로우를 단순화하여 생산성 향상 +- 로컬 개발 환경에서 안전하게 에이전트와 협업할 수 있는 도구 제공 -#### Phase 1: 시각적 쾌감을 극대화한 숏폼 (YouTube Shorts / Reels) +## 주요 기능 (At a glance) -바흐의 음악과 UI의 타격감을 동기화하여 개발자들의 로망을 자극하는 30~60초 분량의 영상입니다. +- 에이전트가 `POST /api/request`로 승인 요청 전송 +- Maestro 서버는 WebSocket으로 대시보드에 알림 브로드캐스트 +- 사용자가 대시보드에서 APPROVE / REJECT / UNDO 조작 가능 +- 승인 시 서버에서 로컬 `git merge`를 수행 -* **오디오:** 바흐의 인벤션(Invention)이나 평균율 클라비어 곡집처럼 규칙적이고 경쾌한 피아노/하프시코드 연주곡. -* **화면 구성 (분할 화면):** - * **상단/배경:** 다크 모드의 세련된 개발 환경. 투명한 '건반형 대시보드' 위로 에이전트들의 코드 리뷰 요청(Diff 요약본)이 위에서 아래로 리듬 게임의 노트처럼 떨어집니다. - * **하단/실사:** 여유롭게 커피를 마시며, 키보드 특정 키(예: A, S, D, F)를 음악 비트에 맞춰 가볍게 탭(Tap)하는 손. - - -* **포인트:** 키를 누를 때마다 화면의 코드 노드가 경쾌한 파동을 일으키며 'Merged(승인)' 상태로 변하고, 브랜치들이 메인 트리에 깔끔하게 합쳐지는 애니메이션을 연출합니다. - -#### Phase 2: 기술 블로그 아티클 (The Architecture of Flow) - -영상을 보고 "저거 어떻게 세팅한 거지?"라고 궁금해할 개발자들을 위한 딥다이브 콘텐츠입니다. - -* **주제:** Git Worktree와 다중 AI 에이전트를 활용한 병렬 개발 워크플로우 구축기. -* **내용:** - * 왜 디렉토리를 복사하지 않고 Git Worktree를 사용하여 여러 에이전트를 독립적으로 띄웠는지에 대한 기술적 이점 설명. - * 에이전트들의 승인 대기 상태를 가로채서(Intercept) 하나의 중앙 대시보드(건반 패널)로 모으는 이벤트 루프 아키텍처. - * 알림의 파편화를 막고 컨텍스트 스위칭을 최소화한 UX 설계 철학. - - - -#### Phase 3: 인터랙티브 웹 데모 및 오픈소스/컴포넌트 공개 - -단순한 영상 콘텐츠로 끝내는 것이 아니라, 직접 경험해 볼 수 있는 미니 데모를 제공하여 기술력을 증명합니다. - -* 웹 브라우저에서 바흐 음악과 함께 가짜(Mock) 에이전트 커밋들이 내려오고, 사용자가 직접 키보드로 승인해 보는 리듬 게임 형태의 랜딩 페이지 제작. -* 이 '건반형 승인 대시보드'를 AI 보조 코딩을 위해 설계된 전체 풀스택 프레임워크 내에서 언제든 꺼내 쓸 수 있는 핵심 **재사용 UI/UX 컴포넌트**로 패키징하여 소개합니다. - ---- - -## 🔌 `maestro-server.js` 동작 원리 - -프론트엔드 데모만으로는 실제 에이전트 승인 요청을 받을 수 없습니다. -`maestro-server.js`는 **에이전트 ↔ 대시보드** 사이를 연결하는 경량 Node.js 서버입니다. - -### 전체 아키텍처 흐름 - -``` -┌─────────────────────────────────────────────────────────────────────┐ -│ Maestro 시스템 전체 흐름 │ -│ │ -│ AI 에이전트 │ -│ (Codex / Claude / │ -│ 터미널 스크립트 등) │ -│ │ │ -│ │ ① 작업 완료 후 │ -│ │ POST /api/request │ -│ ▼ │ -│ ┌─────────────────────────────────────────────────┐ │ -│ │ maestro-server.js (포트 8080) │ │ -│ │ │ │ -│ │ HTTP 서버 WebSocket 서버 │ │ -│ │ ┌──────────────┐ ┌──────────────────┐ │ │ -│ │ │POST /api/req │──②──▶ │broadcast() │ │ │ -│ │ │GET /health │ │AGENT_TASK_READY │ │ │ -│ │ └──────────────┘ └────────┬─────────┘ │ │ -│ │ │ │ │ -│ │ Git 실행 (execFile) ◀──⑤────── │ │ │ -│ │ git merge / reset │ │ │ -│ └───────────────────────────────────┼─────────────┘ │ -│ │ ③ WebSocket │ -│ ▼ ws://localhost:8080 │ -│ ┌────────────────────────┐ │ -│ │ 브라우저 대시보드 │ │ -│ │ (React / App.jsx) │ │ -│ │ │ │ -│ │ 노트가 레인으로 떨어짐 🎵 │ │ -│ │ │ │ -│ │ 키보드 D/F/J/K 입력 ④ │ │ -│ └────────────────────────┘ │ -└─────────────────────────────────────────────────────────────────────┘ -``` - -### 단계별 이벤트 흐름 - -| 단계 | 주체 | 동작 | -|------|------|------| -| ① | AI 에이전트 | 작업(커밋) 완료 후 `POST /api/request` 로 승인 요청 전송 | -| ② | 서버 | JSON 파싱 → `AGENT_TASK_READY` 이벤트를 연결된 모든 대시보드로 브로드캐스트 | -| ③ | 대시보드 | WebSocket 메시지 수신 → 해당 레인에 노트(음표)가 화면 위에서 아래로 낙하 | -| ④ | 사용자 | 키보드(`D` `F` `J` `K`)로 노트 승인 → `APPROVE` 이벤트를 서버로 전송 | -| ⑤ | 서버 | `git merge ` 실행 → 성공 시 `MERGE_SUCCESS` 응답 | - -> **`Ctrl+Z` 롤백 흐름:** 사용자가 `Ctrl+Z`를 누르면 `UNDO` 이벤트가 서버로 전송되고, 서버는 `git reset --hard HEAD~1`을 실행합니다. - ---- - -### 실행 방법 +## 빠른 시작 (Quick Start) ```bash -# 1. 의존성 설치 (ws 패키지 포함) +# 1. 레포지토리 클론 +git clone https://github.com/redsunjin/maestro-coding.git +cd maestro-coding + +# 2. 의존성 설치 npm install -# 2. 서버 시작 +# 3. 설정 파일(.env) 준비 — 대화형 설정 사용 +npm run configure +# 또는 직접 .env.example을 복사해 편집 +cp .env.example .env + +# 4. 서버 실행 npm run server -# 또는 -node maestro-server.js -# 3. 프론트엔드 개발 서버 (별도 터미널) +# 5. 프론트엔드 개발 서버 실행 (별도 터미널) npm run dev ``` -서버가 시작되면 대시보드에서 "지휘 시작" 버튼을 눌렀을 때 자동으로 `ws://localhost:8080`에 연결을 시도합니다. -연결에 성공하면 헤더에 **🔴 LIVE** 배지가 표시됩니다. 연결 실패 시에는 자동으로 Mock 모드로 동작합니다. - -#### 환경 변수 - -| 변수 | 기본값 | 설명 | -|------|--------|------| -| `PORT` | `8080` | 서버 리스닝 포트 | -| `MAIN_REPO_PATH` | `process.cwd()` | `git merge`/`git reset` 을 실행할 메인 레포지토리 경로 | -| `VITE_WS_URL` | `ws://localhost:8080` | 프론트엔드가 연결할 WebSocket 주소 (`.env` 파일에 설정) | - -예시: -```bash -MAIN_REPO_PATH=/home/user/my-project PORT=9090 node maestro-server.js -``` - ---- - -### HTTP API 레퍼런스 - -#### `POST /api/request` — 에이전트 승인 요청 - -에이전트(또는 완료 훅 스크립트)가 작업 완료 시 이 엔드포인트로 요청을 보냅니다. - -**요청 본문 (`application/json`)** - -```json -{ - "requestId": "req_abc123", - "agentId": "agent_backend_01", - "branchName": "feature/jwt-optimization", - "projectId": "proj_b2c", - "laneIndex": 2, - "diffSummary": { - "title": "JWT 검증 로직 최적화", - "impact": "Medium", - "shortDescription": "auth.js 45-60 라인 수정. 예외 처리 추가." - } -} -``` - -| 필드 | 필수 | 설명 | -|------|------|------| -| `agentId` | 권장 | 에이전트 식별자 | -| `branchName` | 권장 | 실제 git merge 대상 브랜치 이름 | -| `projectId` | 선택 | 프론트엔드 탭 선택에 사용 (`proj_b2c`, `proj_admin`, `proj_api`) | -| `laneIndex` | 선택 | UI 레인 번호 1~4. 생략 시 서버가 랜덤 배정 | -| `diffSummary` | 선택 | 생략 시 `title` / `description` 최상위 필드를 대체 사용 | - -**curl 예시** +에이전트(또는 훅)에서 승인 요청 전송 예시: ```bash curl -X POST http://localhost:8080/api/request \ -H 'Content-Type: application/json' \ - -d '{ - "agentId": "my_agent", - "branchName": "feature/my-branch", - "laneIndex": 1, - "diffSummary": { - "title": "작업 완료", - "shortDescription": "변경 내용 요약" - } - }' -``` - -**응답** - -```json -{ "success": true, "requestId": "req_1748392839201" } -``` - -#### `GET /health` — 서버 상태 확인 - -```bash -curl http://localhost:8080/health -# {"status":"ok","clients":1} -``` - ---- - -### WebSocket 이벤트 목록 - -#### 서버 → 대시보드 (수신 이벤트) - -| 이벤트 | 설명 | -|--------|------| -| `AGENT_TASK_READY` | 에이전트 승인 요청. 이 이벤트의 페이로드가 노트(음표)로 화면에 표시됩니다. | -| `MERGE_SUCCESS` | `git merge` 성공. 노트가 화면에서 사라집니다. | -| `MERGE_FAILED` | `git merge` 실패. 서버 로그를 확인하세요. | -| `UNDO_SUCCESS` | `git reset --hard HEAD~1` 성공. | -| `UNDO_FAILED` | 롤백 실패. | -| `AGENT_RESTARTED` | 반려(REJECT) 처리 완료 확인. | - -#### 대시보드 → 서버 (송신 이벤트) - -| 액션 | 설명 | -|------|------| -| `APPROVE` | 노트 승인. `branchName`이 있으면 `git merge` 실행. | -| `REJECT` | 노트 반려. `feedback` 필드로 에이전트에 수정 지시 전달 가능. | -| `UNDO` | 직전 병합 롤백 (`git reset --hard HEAD~1`). | - ---- - -## 🤖 실제 AI 개발툴과 연동하기 - -> **"API 통해서 네트워크 타고 갔다 오는 게 맞나요? 실제 개발툴하고 통신이 되는 건가요?"** -> **네, 맞습니다.** `localhost:8080`을 통한 진짜 HTTP/WebSocket 통신입니다. -> AI 도구가 작업을 마치는 순간, 실제로 승인 요청이 대시보드에 날아옵니다. - -### 전체 통신 흐름 (네트워크 레벨) - -``` -[AI 개발툴 (Cursor / Claude Code / aider 등)] - │ - │ ① 작업 완료 → 훅 스크립트 실행 - │ hooks/notify-maestro.sh - │ - │ ② 진짜 HTTP POST 요청 (로컬호스트) - ▼ - POST http://localhost:8080/api/request - │ - │ ③ JSON 파싱 → WebSocket 브로드캐스트 - ▼ - ws://localhost:8080 ───────────────────▶ [브라우저 대시보드] - │ - 노트가 레인으로 떨어짐 🎵 - │ - D / F / J / K 키 입력 ④ - │ - ◀───────────────── WebSocket APPROVE ──────┘ - │ - │ ⑤ git merge - ▼ - 브랜치가 메인으로 실제 병합됩니다 ✅ -``` - -> **"로컬호스트니까 사실상 인터넷은 아니지 않나요?"** -> 맞습니다 — 같은 머신 안의 루프백(loopback) 통신입니다. 덕분에 외부 서버 없이, 인터넷 연결 없이도 동작합니다. -> 원격 에이전트(다른 PC, 클라우드 서버 등)가 필요하다면 ngrok 등으로 터널링하면 됩니다. - ---- - -### 방법 1 — Claude Code 훅 (가장 쉬움 ⭐) - -Claude Code는 에이전트가 작업을 마칠 때 자동으로 쉘 명령을 실행하는 **Stop 훅**을 지원합니다. - -**설정 방법 (프로젝트 루트에서):** - -```bash -# .claude 디렉토리가 없으면 생성 -mkdir -p .claude - -# 훅 설정 파일 복사 -cp hooks/claude-settings-example.json .claude/settings.json -``` - -**.claude/settings.json 내용:** - -```json -{ - "hooks": { - "Stop": [ - { - "matcher": "", - "hooks": [ - { - "type": "command", - "command": "sh hooks/notify-maestro.sh" - } - ] - } - ] - } -} -``` - -이후 Claude Code에서 작업이 완료될 때마다 **자동으로** 대시보드에 승인 요청이 나타납니다. - ---- - -### 방법 2 — 터미널에서 직접 호출 - -어떤 AI 도구든, 어떤 스크립트든 작업 완료 후 한 줄만 추가하면 됩니다: - -```bash -# 가장 간단한 형태 (브랜치·커밋 메시지 자동 감지) -sh hooks/notify-maestro.sh - -# 명시적으로 정보를 전달하는 형태 -sh hooks/notify-maestro.sh feature/auth "JWT 검증 로직 추가" "auth.js 45-60 수정" - -# 환경변수로 제어 -AGENT_ID=my_agent LANE_INDEX=2 sh hooks/notify-maestro.sh + -d '{"agentId":"local_agent","branchName":"feature/x","diffSummary":{"title":"작업 완료","shortDescription":"변경요약"}}' ``` ---- - -### 방법 3 — aider, 기타 CLI 에이전트 래퍼 - -`aider`처럼 반복 실행되는 AI 에이전트라면 완료 후 훅을 래퍼 스크립트로 감쌀 수 있습니다: - -```bash -#!/bin/bash -# run-agent.sh — aider 실행 후 Maestro 에 알림 - -aider --model gpt-4o "$@" -EXIT_CODE=$? - -if [ $EXIT_CODE -eq 0 ]; then - sh hooks/notify-maestro.sh -fi -``` - ---- - -### 방법 4 — git post-commit 훅 +## 설치 가이드 (Installation) -커밋이 생성될 때마다 자동으로 승인 요청을 보내려면: - -```bash -# .git/hooks/post-commit 파일에 추가 -echo '#!/bin/sh' > .git/hooks/post-commit -echo 'sh "$(git rev-parse --show-toplevel)/hooks/notify-maestro.sh"' >> .git/hooks/post-commit -chmod +x .git/hooks/post-commit -``` - ---- - -### 실제 동작 확인 (30초 테스트) - -```bash -# 터미널 1: 서버 시작 -npm run server - -# 터미널 2: 브라우저에서 대시보드 열고 "지휘 시작" 클릭 -npm run dev - -# 터미널 3: 승인 요청 직접 발사 — 대시보드에 노트가 나타나는지 확인! -sh hooks/notify-maestro.sh feature/test-branch "테스트 커밋" "실제 통신 확인" -``` +자세한 설치/사용법은 [USER_GUIDE.md](USER_GUIDE.md)를 참고하세요. -브라우저 대시보드에 노트가 나타나면, **실제 HTTP → WebSocket 통신**이 작동하는 것입니다. -이제 `D` `F` `J` `K` 키를 누르면 서버에서 `git merge` 가 실행됩니다. 🎼 +## 기획 문서 / 아키텍처 ---- +기획 및 아키텍처 문서는 [`docs/PLAN.md`](docs/PLAN.md)에 보관되어 있습니다. -### 3. 성공적인 연출을 위한 UX 디테일 +## 기여 방법 (Contributing) -* **Diff 하이라이트의 추상화:** 승인 화면에서 코드를 한 줄 한 줄 읽게 하면 리듬이 깨집니다. 에이전트가 "어떤 의도"로 "어느 로직"을 건드렸는지만 3줄 이내의 자연어나 미니 맵 형태로 보여주어 직관적인 판단을 돕습니다. -* **되감기(Undo) 기능:** 리듬에 맞춰 빠르게 승인하다 실수했을 때, 음악의 리와인드 효과음과 함께 방금 병합한 커밋을 취소하는 단축키(`Ctrl+Z` 등)를 지원하여 심리적 안정감을 제공합니다. +- 이 레포는 오픈 실험용입니다. 기여하려면 이슈를 남기고 PR을 보내주세요. +- 민감 정보(토큰 등)는 절대 커밋하지 마세요. `.env`를 사용하세요. diff --git a/USER_GUIDE.md b/USER_GUIDE.md new file mode 100644 index 0000000..5068082 --- /dev/null +++ b/USER_GUIDE.md @@ -0,0 +1,190 @@ +# 사용자 가이드 (User Guide) + +이 문서는 로컬에서 Maestro를 설치하고, 에이전트(예: VS Code, 훅 스크립트)와 연동해 승인 플로우를 테스트하는 방법을 단계별로 안내합니다. + +**목차** +- [요구사항 (Prerequisites)](#요구사항-prerequisites) +- [빠른 설치 & 실행](#빠른-설치--실행) +- [환경변수(.env) 설정 방법](#환경변수env-설정-방법) +- [에이전트 연동 예제](#에이전트-연동-예제) +- [승인(Approve) 시나리오 테스트](#승인approve-시나리오-테스트) +- [롤백(UNDO) 사용법](#롤백undo-사용법) +- [보안 권장사항](#보안-권장사항) + +--- + +## 요구사항 (Prerequisites) + +- Node.js (v16+ 권장) +- Git (로컬에 병합 가능한 레포가 있어야 함) + +--- + +## 빠른 설치 & 실행 + +**1. 소스 클론** + +```bash +git clone https://github.com/redsunjin/maestro-coding.git +cd maestro-coding +``` + +**2. 의존성 설치** + +```bash +npm install +``` + +**3. 환경 설정** + +대화형 설정 스크립트를 실행하거나, 직접 `.env` 파일을 만들 수 있습니다. + +```bash +# 대화형 설정 (권장) +npm run configure + +# 또는 셸 스크립트로 설정 +npm run setup +# Windows PowerShell 사용자 +# scripts/setup_env.ps1 +``` + +**4. 서버 실행** + +```bash +npm run server +``` + +**5. 프론트엔드 개발 서버 실행 (별도 터미널)** + +```bash +npm run dev +``` + +브라우저에서 대시보드를 열고 **"지휘 시작"** 버튼을 클릭하면 `ws://localhost:8080`에 자동 연결됩니다. + +--- + +## 환경변수(.env) 설정 방법 + +프로젝트 루트에 `.env` 파일을 생성하고 다음 변수를 설정합니다. +`.env.example`을 복사하여 시작할 수 있습니다: + +```bash +cp .env.example .env +``` + +| 변수 | 기본값 | 설명 | +|------|--------|------| +| `MAIN_REPO_PATH` | `process.cwd()` | `git merge`/`git reset`을 실행할 메인 레포지토리 경로 (필수 권장) | +| `PORT` | `8080` | 서버 리스닝 포트 | +| `MAESTRO_SERVER_TOKEN` | (없음) | 인증 토큰 (설정 시 요청에 `Authorization: Bearer ` 헤더 필요) | +| `VITE_WS_URL` | `ws://localhost:8080` | 프론트엔드가 연결할 WebSocket 주소 | + +예시 `.env`: + +``` +MAIN_REPO_PATH=/home/user/projects/my-main-repo +PORT=8080 +MAESTRO_SERVER_TOKEN=very-secret-token +VITE_WS_URL=ws://localhost:8080 +``` + +> ⚠️ `.env` 파일에는 실제 토큰이나 경로 등 민감 정보가 포함될 수 있습니다. +> **절대로 `.env`를 Git에 커밋하지 마세요.** `.gitignore`에 이미 포함되어 있습니다. + +--- + +## 에이전트 연동 예제 + +### 방법 1 — curl로 승인 요청 직접 전송 + +```bash +curl -X POST http://localhost:8080/api/request \ + -H 'Content-Type: application/json' \ + -H 'Authorization: Bearer ' \ + -d '{ + "agentId": "local_agent", + "branchName": "feature/my-feature", + "laneIndex": 1, + "diffSummary": { + "title": "작업 완료", + "shortDescription": "변경 내용 요약" + } + }' +``` + +토큰 인증을 사용하지 않는다면 `Authorization` 헤더를 생략하세요. + +### 방법 2 — Claude Code 훅 (Stop Hook) + +Claude Code가 작업을 마칠 때 자동으로 승인 요청을 보내도록 설정합니다. + +```bash +mkdir -p .claude +cp hooks/claude-settings-example.json .claude/settings.json +``` + +이후 Claude Code에서 작업이 완료될 때마다 대시보드에 승인 요청이 자동으로 나타납니다. + +### 방법 3 — 훅 스크립트 직접 실행 + +```bash +# 기본 실행 (브랜치·커밋 메시지 자동 감지) +sh hooks/notify-maestro.sh + +# 명시적 정보 전달 +sh hooks/notify-maestro.sh feature/auth "JWT 검증 로직 추가" "auth.js 45-60 수정" + +# 환경변수로 제어 +AGENT_ID=my_agent LANE_INDEX=2 sh hooks/notify-maestro.sh +``` + +### 방법 4 — git post-commit 훅 + +```bash +echo '#!/bin/sh' > .git/hooks/post-commit +echo 'sh "$(git rev-parse --show-toplevel)/hooks/notify-maestro.sh"' >> .git/hooks/post-commit +chmod +x .git/hooks/post-commit +``` + +--- + +## 승인(Approve) 시나리오 테스트 + +**30초 빠른 테스트:** + +```bash +# 터미널 1: 서버 시작 +npm run server + +# 터미널 2: 프론트엔드 개발 서버 시작, 브라우저에서 "지휘 시작" 클릭 +npm run dev + +# 터미널 3: 승인 요청 전송 — 대시보드에 노트가 나타나는지 확인! +sh hooks/notify-maestro.sh feature/test-branch "테스트 커밋" "실제 통신 확인" +``` + +브라우저 대시보드에 노트가 나타나면 `D` `F` `J` `K` 키로 승인하거나 반려할 수 있습니다. +승인 시 서버가 `git merge `을 실행합니다. + +--- + +## 롤백(UNDO) 사용법 + +대시보드에서 잘못 승인한 경우 **`Ctrl+Z`** 를 눌러 직전 병합을 취소할 수 있습니다. + +- 서버는 `git reset --hard HEAD~1`을 실행합니다. +- 성공 시 `UNDO_SUCCESS`, 실패 시 `UNDO_FAILED` 이벤트가 대시보드로 전달됩니다. + +> ⚠️ `git reset --hard`는 복구가 어렵습니다. 중요한 작업 전에는 반드시 백업 브랜치를 만들어두세요. + +--- + +## 보안 권장사항 + +1. **토큰 사용:** `MAESTRO_SERVER_TOKEN` 환경변수를 설정하면 인증되지 않은 요청을 차단합니다. 로컬 전용이더라도 설정을 권장합니다. +2. **`.env` 파일 보호:** 실제 토큰이나 경로가 포함된 `.env`는 절대 Git에 커밋하지 마세요. `.gitignore`에 이미 포함되어 있습니다. +3. **로컬 환경 한정:** Maestro 서버는 기본적으로 로컬호스트에서만 동작합니다. 외부에 공개하려면 방화벽 설정과 HTTPS/WSS를 반드시 적용하세요. +4. **git 명령어 경로 검증:** `MAIN_REPO_PATH`에 신뢰할 수 있는 경로만 설정하세요. 악의적인 브랜치 이름으로 인한 명령어 인젝션을 방지하기 위해 서버는 입력값을 검증합니다. +5. **의존성 관리:** `npm audit`로 취약점을 주기적으로 점검하세요. diff --git a/docs/PLAN.md b/docs/PLAN.md new file mode 100644 index 0000000..0c0db3a --- /dev/null +++ b/docs/PLAN.md @@ -0,0 +1,380 @@ +# 기획 / 아키텍처 문서 보관소 (PLAN) + +이 파일은 기존 README.md(기획 문서)를 보관하는 용도로 사용합니다. +프로젝트 초기 기획, 아키텍처, 실험 메모, 설계 결정 사항 등 변경·보존해야 하는 문서를 이곳으로 옮겨주세요. + +--- + +# Maestro Coding + +

+ + Demo + +

+ +## 🎼 '마에스트로 코딩(Maestro Coding)' + +### 1. 핵심 메시지 (Core Message) + +* **Before:** 여러 에이전트와 창을 띄워놓고 쏟아지는 PR과 커밋 알림에 쫓기며 클릭질하는 스트레스 넘치는 개발자. +* **After:** 바흐의 선율 속에서, 투명하게 오버레이된 건반형 대시보드를 통해 리드미컬하게 다수의 에이전트를 지휘하는 우아한 개발자. +* **Slogan:** "코딩을 지휘하다, AI 에이전트와 함께하는 코드 심포니." + +### 2. 단계별 콘텐츠 전개 전략 + +#### Phase 1: 시각적 쾌감을 극대화한 숏폼 (YouTube Shorts / Reels) + +바흐의 음악과 UI의 타격감을 동기화하여 개발자들의 로망을 자극하는 30~60초 분량의 영상입니다. + +* **오디오:** 바흐의 인벤션(Invention)이나 평균율 클라비어 곡집처럼 규칙적이고 경쾌한 피아노/하프시코드 연주곡. +* **화면 구성 (분할 화면):** + * **상단/배경:** 다크 모드의 세련된 개발 환경. 투명한 '건반형 대시보드' 위로 에이전트들의 코드 리뷰 요청(Diff 요약본)이 위에서 아래로 리듬 게임의 노트처럼 떨어집니다. + * **하단/실사:** 여유롭게 커피를 마시며, 키보드 특정 키(예: A, S, D, F)를 음악 비트에 맞춰 가볍게 탭(Tap)하는 손. + + +* **포인트:** 키를 누를 때마다 화면의 코드 노드가 경쾌한 파동을 일으키며 'Merged(승인)' 상태로 변하고, 브랜치들이 메인 트리에 깔끔하게 합쳐지는 애니메이션을 연출합니다. + +#### Phase 2: 기술 블로그 아티클 (The Architecture of Flow) + +영상을 보고 "저거 어떻게 세팅한 거지?"라고 궁금해할 개발자들을 위한 딥다이브 콘텐츠입니다. + +* **주제:** Git Worktree와 다중 AI 에이전트를 활용한 병렬 개발 워크플로우 구축기. +* **내용:** + * 왜 디렉토리를 복사하지 않고 Git Worktree를 사용하여 여러 에이전트를 독립적으로 띄웠는지에 대한 기술적 이점 설명. + * 에이전트들의 승인 대기 상태를 가로채서(Intercept) 하나의 중앙 대시보드(건반 패널)로 모으는 이벤트 루프 아키텍처. + * 알림의 파편화를 막고 컨텍스트 스위칭을 최소화한 UX 설계 철학. + + + +#### Phase 3: 인터랙티브 웹 데모 및 오픈소스/컴포넌트 공개 + +단순한 영상 콘텐츠로 끝내는 것이 아니라, 직접 경험해 볼 수 있는 미니 데모를 제공하여 기술력을 증명합니다. + +* 웹 브라우저에서 바흐 음악과 함께 가짜(Mock) 에이전트 커밋들이 내려오고, 사용자가 직접 키보드로 승인해 보는 리듬 게임 형태의 랜딩 페이지 제작. +* 이 '건반형 승인 대시보드'를 AI 보조 코딩을 위해 설계된 전체 풀스택 프레임워크 내에서 언제든 꺼내 쓸 수 있는 핵심 **재사용 UI/UX 컴포넌트**로 패키징하여 소개합니다. + +--- + +## 🔌 `maestro-server.js` 동작 원리 + +프론트엔드 데모만으로는 실제 에이전트 승인 요청을 받을 수 없습니다. +`maestro-server.js`는 **에이전트 ↔ 대시보드** 사이를 연결하는 경량 Node.js 서버입니다. + +### 전체 아키텍처 흐름 + +``` +┌─────────────────────────────────────────────────────────────────────┐ +│ Maestro 시스템 전체 흐름 │ +│ │ +│ AI 에이전트 │ +│ (Codex / Claude / │ +│ 터미널 스크립트 등) │ +│ │ │ +│ │ ① 작업 완료 후 │ +│ │ POST /api/request │ +│ ▼ │ +│ ┌─────────────────────────────────────────────────┐ │ +│ │ maestro-server.js (포트 8080) │ │ +│ │ │ │ +│ │ HTTP 서버 WebSocket 서버 │ │ +│ │ ┌──────────────┐ ┌──────────────────┐ │ │ +│ │ │POST /api/req │──②──▶ │broadcast() │ │ │ +│ │ │GET /health │ │AGENT_TASK_READY │ │ │ +│ │ └──────────────┘ └────────┬─────────┘ │ │ +│ │ │ │ │ +│ │ Git 실행 (execFile) ◀──⑤────── │ │ │ +│ │ git merge / reset │ │ │ +│ └───────────────────────────────────┼─────────────┘ │ +│ │ ③ WebSocket │ +│ ▼ ws://localhost:8080 │ +│ ┌────────────────────────┐ │ +│ │ 브라우저 대시보드 │ │ +│ │ (React / App.jsx) │ │ +│ │ │ │ +│ │ 노트가 레인으로 떨어짐 🎵 │ │ +│ │ │ │ +│ │ 키보드 D/F/J/K 입력 ④ │ │ +│ └────────────────────────┘ │ +└─────────────────────────────────────────────────────────────────────┘ +``` + +### 단계별 이벤트 흐름 + +| 단계 | 주체 | 동작 | +|------|------|------| +| ① | AI 에이전트 | 작업(커밋) 완료 후 `POST /api/request` 로 승인 요청 전송 | +| ② | 서버 | JSON 파싱 → `AGENT_TASK_READY` 이벤트를 연결된 모든 대시보드로 브로드캐스트 | +| ③ | 대시보드 | WebSocket 메시지 수신 → 해당 레인에 노트(음표)가 화면 위에서 아래로 낙하 | +| ④ | 사용자 | 키보드(`D` `F` `J` `K`)로 노트 승인 → `APPROVE` 이벤트를 서버로 전송 | +| ⑤ | 서버 | `git merge ` 실행 → 성공 시 `MERGE_SUCCESS` 응답 | + +> **`Ctrl+Z` 롤백 흐름:** 사용자가 `Ctrl+Z`를 누르면 `UNDO` 이벤트가 서버로 전송되고, 서버는 `git reset --hard HEAD~1`을 실행합니다. + +--- + +### 실행 방법 + +```bash +# 1. 의존성 설치 (ws 패키지 포함) +npm install + +# 2. 서버 시작 +npm run server +# 또는 +node maestro-server.js + +# 3. 프론트엔드 개발 서버 (별도 터미널) +npm run dev +``` + +서버가 시작되면 대시보드에서 "지휘 시작" 버튼을 눌렀을 때 자동으로 `ws://localhost:8080`에 연결을 시도합니다. +연결에 성공하면 헤더에 **🔴 LIVE** 배지가 표시됩니다. 연결 실패 시에는 자동으로 Mock 모드로 동작합니다. + +#### 환경 변수 + +| 변수 | 기본값 | 설명 | +|------|--------|------| +| `PORT` | `8080` | 서버 리스닝 포트 | +| `MAIN_REPO_PATH` | `process.cwd()` | `git merge`/`git reset` 을 실행할 메인 레포지토리 경로 | +| `VITE_WS_URL` | `ws://localhost:8080` | 프론트엔드가 연결할 WebSocket 주소 (`.env` 파일에 설정) | + +예시: +```bash +MAIN_REPO_PATH=/home/user/my-project PORT=9090 node maestro-server.js +``` + +--- + +### HTTP API 레퍼런스 + +#### `POST /api/request` — 에이전트 승인 요청 + +에이전트(또는 완료 훅 스크립트)가 작업 완료 시 이 엔드포인트로 요청을 보냅니다. + +**요청 본문 (`application/json`)** + +```json +{ + "requestId": "req_abc123", + "agentId": "agent_backend_01", + "branchName": "feature/jwt-optimization", + "projectId": "proj_b2c", + "laneIndex": 2, + "diffSummary": { + "title": "JWT 검증 로직 최적화", + "impact": "Medium", + "shortDescription": "auth.js 45-60 라인 수정. 예외 처리 추가." + } +} +``` + +| 필드 | 필수 | 설명 | +|------|------|------| +| `agentId` | 권장 | 에이전트 식별자 | +| `branchName` | 권장 | 실제 git merge 대상 브랜치 이름 | +| `projectId` | 선택 | 프론트엔드 탭 선택에 사용 (`proj_b2c`, `proj_admin`, `proj_api`) | +| `laneIndex` | 선택 | UI 레인 번호 1~4. 생략 시 서버가 랜덤 배정 | +| `diffSummary` | 선택 | 생략 시 `title` / `description` 최상위 필드를 대체 사용 | + +**curl 예시** + +```bash +curl -X POST http://localhost:8080/api/request \ + -H 'Content-Type: application/json' \ + -d '{ + "agentId": "my_agent", + "branchName": "feature/my-branch", + "laneIndex": 1, + "diffSummary": { + "title": "작업 완료", + "shortDescription": "변경 내용 요약" + } + }' +``` + +**응답** + +```json +{ "success": true, "requestId": "req_1748392839201" } +``` + +#### `GET /health` — 서버 상태 확인 + +```bash +curl http://localhost:8080/health +# {"status":"ok","clients":1} +``` + +--- + +### WebSocket 이벤트 목록 + +#### 서버 → 대시보드 (수신 이벤트) + +| 이벤트 | 설명 | +|--------|------| +| `AGENT_TASK_READY` | 에이전트 승인 요청. 이 이벤트의 페이로드가 노트(음표)로 화면에 표시됩니다. | +| `MERGE_SUCCESS` | `git merge` 성공. 노트가 화면에서 사라집니다. | +| `MERGE_FAILED` | `git merge` 실패. 서버 로그를 확인하세요. | +| `UNDO_SUCCESS` | `git reset --hard HEAD~1` 성공. | +| `UNDO_FAILED` | 롤백 실패. | +| `AGENT_RESTARTED` | 반려(REJECT) 처리 완료 확인. | + +#### 대시보드 → 서버 (송신 이벤트) + +| 액션 | 설명 | +|------|------| +| `APPROVE` | 노트 승인. `branchName`이 있으면 `git merge` 실행. | +| `REJECT` | 노트 반려. `feedback` 필드로 에이전트에 수정 지시 전달 가능. | +| `UNDO` | 직전 병합 롤백 (`git reset --hard HEAD~1`). | + +--- + +## 🤖 실제 AI 개발툴과 연동하기 + +> **"API 통해서 네트워크 타고 갔다 오는 게 맞나요? 실제 개발툴하고 통신이 되는 건가요?"** +> **네, 맞습니다.** `localhost:8080`을 통한 진짜 HTTP/WebSocket 통신입니다. +> AI 도구가 작업을 마치는 순간, 실제로 승인 요청이 대시보드에 날아옵니다. + +### 전체 통신 흐름 (네트워크 레벨) + +``` +[AI 개발툴 (Cursor / Claude Code / aider 등)] + │ + │ ① 작업 완료 → 훅 스크립트 실행 + │ hooks/notify-maestro.sh + │ + │ ② 진짜 HTTP POST 요청 (로컬호스트) + ▼ + POST http://localhost:8080/api/request + │ + │ ③ JSON 파싱 → WebSocket 브로드캐스트 + ▼ + ws://localhost:8080 ───────────────────▶ [브라우저 대시보드] + │ + 노트가 레인으로 떨어짐 🎵 + │ + D / F / J / K 키 입력 ④ + │ + ◀───────────────── WebSocket APPROVE ──────┘ + │ + │ ⑤ git merge + ▼ + 브랜치가 메인으로 실제 병합됩니다 ✅ +``` + +> **"로컬호스트니까 사실상 인터넷은 아니지 않나요?"** +> 맞습니다 — 같은 머신 안의 루프백(loopback) 통신입니다. 덕분에 외부 서버 없이, 인터넷 연결 없이도 동작합니다. +> 원격 에이전트(다른 PC, 클라우드 서버 등)가 필요하다면 ngrok 등으로 터널링하면 됩니다. + +--- + +### 방법 1 — Claude Code 훅 (가장 쉬움 ⭐) + +Claude Code는 에이전트가 작업을 마칠 때 자동으로 쉘 명령을 실행하는 **Stop 훅**을 지원합니다. + +**설정 방법 (프로젝트 루트에서):** + +```bash +# .claude 디렉토리가 없으면 생성 +mkdir -p .claude + +# 훅 설정 파일 복사 +cp hooks/claude-settings-example.json .claude/settings.json +``` + +**.claude/settings.json 내용:** + +```json +{ + "hooks": { + "Stop": [ + { + "matcher": "", + "hooks": [ + { + "type": "command", + "command": "sh hooks/notify-maestro.sh" + } + ] + } + ] + } +} +``` + +이후 Claude Code에서 작업이 완료될 때마다 **자동으로** 대시보드에 승인 요청이 나타납니다. + +--- + +### 방법 2 — 터미널에서 직접 호출 + +어떤 AI 도구든, 어떤 스크립트든 작업 완료 후 한 줄만 추가하면 됩니다: + +```bash +# 가장 간단한 형태 (브랜치·커밋 메시지 자동 감지) +sh hooks/notify-maestro.sh + +# 명시적으로 정보를 전달하는 형태 +sh hooks/notify-maestro.sh feature/auth "JWT 검증 로직 추가" "auth.js 45-60 수정" + +# 환경변수로 제어 +AGENT_ID=my_agent LANE_INDEX=2 sh hooks/notify-maestro.sh +``` + +--- + +### 방법 3 — aider, 기타 CLI 에이전트 래퍼 + +`aider`처럼 반복 실행되는 AI 에이전트라면 완료 후 훅을 래퍼 스크립트로 감쌀 수 있습니다: + +```bash +#!/bin/bash +# run-agent.sh — aider 실행 후 Maestro 에 알림 + +aider --model gpt-4o "$@" +EXIT_CODE=$? + +if [ $EXIT_CODE -eq 0 ]; then + sh hooks/notify-maestro.sh +fi +``` + +--- + +### 방법 4 — git post-commit 훅 + +커밋이 생성될 때마다 자동으로 승인 요청을 보내려면: + +```bash +# .git/hooks/post-commit 파일에 추가 +echo '#!/bin/sh' > .git/hooks/post-commit +echo 'sh "$(git rev-parse --show-toplevel)/hooks/notify-maestro.sh"' >> .git/hooks/post-commit +chmod +x .git/hooks/post-commit +``` + +--- + +### 실제 동작 확인 (30초 테스트) + +```bash +# 터미널 1: 서버 시작 +npm run server + +# 터미널 2: 브라우저에서 대시보드 열고 "지휘 시작" 클릭 +npm run dev + +# 터미널 3: 승인 요청 직접 발사 — 대시보드에 노트가 나타나는지 확인! +sh hooks/notify-maestro.sh feature/test-branch "테스트 커밋" "실제 통신 확인" +``` + +브라우저 대시보드에 노트가 나타나면, **실제 HTTP → WebSocket 통신**이 작동하는 것입니다. +이제 `D` `F` `J` `K` 키를 누르면 서버에서 `git merge` 가 실행됩니다. 🎼 + +--- + +### 3. 성공적인 연출을 위한 UX 디테일 + +* **Diff 하이라이트의 추상화:** 승인 화면에서 코드를 한 줄 한 줄 읽게 하면 리듬이 깨집니다. 에이전트가 "어떤 의도"로 "어느 로직"을 건드렸는지만 3줄 이내의 자연어나 미니 맵 형태로 보여주어 직관적인 판단을 돕습니다. +* **되감기(Undo) 기능:** 리듬에 맞춰 빠르게 승인하다 실수했을 때, 음악의 리와인드 효과음과 함께 방금 병합한 커밋을 취소하는 단축키(`Ctrl+Z` 등)를 지원하여 심리적 안정감을 제공합니다. diff --git a/package.json b/package.json index f3e19b6..b370dad 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,9 @@ "dev": "vite", "build": "vite build", "preview": "vite preview", - "server": "node maestro-server.js" + "server": "node maestro-server.js", + "setup": "sh scripts/setup_env.sh", + "configure": "node scripts/configure.js" }, "dependencies": { "lucide-react": "^0.511.0", @@ -17,6 +19,7 @@ "devDependencies": { "@tailwindcss/vite": "^4.1.6", "@vitejs/plugin-react": "^4.4.1", + "prompts": "^2.4.2", "tailwindcss": "^4.1.6", "vite": "^6.3.5", "ws": "^8.19.0" diff --git a/scripts/configure.js b/scripts/configure.js new file mode 100644 index 0000000..ab3d590 --- /dev/null +++ b/scripts/configure.js @@ -0,0 +1,85 @@ +#!/usr/bin/env node +// scripts/configure.js +// Maestro Coding — 환경변수(.env) 대화형 설정 스크립트 (Node.js) +// +// 사용법: +// node scripts/configure.js +// 또는 +// npm run configure + +import prompts from 'prompts'; +import { existsSync, writeFileSync } from 'fs'; +import { resolve, dirname } from 'path'; +import { fileURLToPath } from 'url'; + +const __dirname = dirname(fileURLToPath(import.meta.url)); +const ROOT_DIR = resolve(__dirname, '..'); +const ENV_FILE = resolve(ROOT_DIR, '.env'); + +console.log('\n🎼 Maestro Coding — 환경 설정 스크립트 (Node.js)'); +console.log('=================================================\n'); + +if (existsSync(ENV_FILE)) { + const { overwrite } = await prompts({ + type: 'confirm', + name: 'overwrite', + message: '.env 파일이 이미 존재합니다. 덮어쓰시겠습니까?', + initial: false, + }); + if (!overwrite) { + console.log('\n취소되었습니다. 기존 .env 파일을 유지합니다.'); + process.exit(0); + } +} + +const response = await prompts( + [ + { + type: 'text', + name: 'MAIN_REPO_PATH', + message: 'MAIN_REPO_PATH — git merge를 실행할 레포 경로', + initial: process.cwd(), + }, + { + type: 'text', + name: 'PORT', + message: 'PORT — 서버 리스닝 포트', + initial: '8080', + validate: (v) => (/^\d+$/.test(v) && parseInt(v) > 0 && parseInt(v) < 65536) || '유효한 포트 번호를 입력하세요 (1-65535)', + }, + { + type: 'password', + name: 'MAESTRO_SERVER_TOKEN', + message: 'MAESTRO_SERVER_TOKEN — 인증 토큰 (빈 값으로 두면 인증 없음)', + }, + { + type: 'text', + name: 'VITE_WS_URL', + message: 'VITE_WS_URL — 프론트엔드가 연결할 WebSocket 주소', + initial: (_, values) => `ws://localhost:${values.PORT || 8080}`, + }, + ], + { + onCancel: () => { + console.log('\n취소되었습니다.'); + process.exit(1); + }, + } +); + +const envContent = [ + '# Maestro Coding — 환경변수 (자동 생성)', + '# ⚠️ 이 파일은 절대 Git에 커밋하지 마세요!', + '', + `MAIN_REPO_PATH=${response.MAIN_REPO_PATH}`, + `PORT=${response.PORT}`, + `MAESTRO_SERVER_TOKEN=${response.MAESTRO_SERVER_TOKEN || ''}`, + `VITE_WS_URL=${response.VITE_WS_URL}`, + '', +].join('\n'); + +writeFileSync(ENV_FILE, envContent, 'utf8'); + +console.log(`\n✅ .env 파일이 생성되었습니다: ${ENV_FILE}`); +console.log('\n서버를 시작하려면:'); +console.log(' npm run server\n'); diff --git a/scripts/setup_env.ps1 b/scripts/setup_env.ps1 new file mode 100644 index 0000000..3b03495 --- /dev/null +++ b/scripts/setup_env.ps1 @@ -0,0 +1,53 @@ +# scripts/setup_env.ps1 +# Maestro Coding — 환경변수(.env) 대화형 설정 스크립트 (PowerShell) +# +# 사용법: +# .\scripts\setup_env.ps1 + +$ErrorActionPreference = "Stop" + +$rootDir = Split-Path -Parent $PSScriptRoot +$envFile = Join-Path $rootDir ".env" + +Write-Host "" +Write-Host "🎼 Maestro Coding — 환경 설정 스크립트 (PowerShell)" +Write-Host "======================================================" + +if (Test-Path $envFile) { + Write-Host "" + $overwrite = Read-Host ".env 파일이 이미 존재합니다. 덮어쓰시겠습니까? [y/N]" + if ($overwrite -notmatch '^[yY]') { + Write-Host "취소되었습니다. 기존 .env 파일을 유지합니다." + exit 0 + } +} + +Write-Host "" +$mainRepoPath = Read-Host "MAIN_REPO_PATH (git merge를 실행할 레포 경로) [기본: 현재 디렉토리]" +if ([string]::IsNullOrWhiteSpace($mainRepoPath)) { $mainRepoPath = (Get-Location).Path } + +$port = Read-Host "PORT (서버 포트) [기본: 8080]" +if ([string]::IsNullOrWhiteSpace($port)) { $port = "8080" } + +$token = Read-Host "MAESTRO_SERVER_TOKEN (인증 토큰, 빈 값으로 두면 인증 없음)" + +$wsUrl = Read-Host "VITE_WS_URL (WebSocket 주소) [기본: ws://localhost:$port]" +if ([string]::IsNullOrWhiteSpace($wsUrl)) { $wsUrl = "ws://localhost:$port" } + +$content = @" +# Maestro Coding — 환경변수 (자동 생성) +# ⚠️ 이 파일은 절대 Git에 커밋하지 마세요! + +MAIN_REPO_PATH=$mainRepoPath +PORT=$port +MAESTRO_SERVER_TOKEN=$token +VITE_WS_URL=$wsUrl +"@ + +Set-Content -Path $envFile -Value $content -Encoding UTF8 + +Write-Host "" +Write-Host "✅ .env 파일이 생성되었습니다: $envFile" +Write-Host "" +Write-Host "서버를 시작하려면:" +Write-Host " npm run server" diff --git a/scripts/setup_env.sh b/scripts/setup_env.sh new file mode 100755 index 0000000..afacee7 --- /dev/null +++ b/scripts/setup_env.sh @@ -0,0 +1,55 @@ +#!/usr/bin/env bash +# scripts/setup_env.sh +# Maestro Coding — 환경변수(.env) 대화형 설정 스크립트 (Bash) +# +# 사용법: +# sh scripts/setup_env.sh +# 또는 +# npm run setup + +set -e + +ROOT_DIR="$(cd "$(dirname "$0")/.." && pwd)" +ENV_FILE="$ROOT_DIR/.env" +EXAMPLE_FILE="$ROOT_DIR/.env.example" + +echo "" +echo "🎼 Maestro Coding — 환경 설정 스크립트" +echo "=======================================" + +if [ -f "$ENV_FILE" ]; then + echo "" + read -r -p ".env 파일이 이미 존재합니다. 덮어쓰시겠습니까? [y/N] " OVERWRITE + case "$OVERWRITE" in + [yY][eE][sS]|[yY]) ;; + *) echo "취소되었습니다. 기존 .env 파일을 유지합니다."; exit 0 ;; + esac +fi + +echo "" +read -r -p "MAIN_REPO_PATH (git merge를 실행할 레포 경로) [기본: 현재 디렉토리]: " MAIN_REPO_PATH +MAIN_REPO_PATH="${MAIN_REPO_PATH:-$(pwd)}" + +read -r -p "PORT (서버 포트) [기본: 8080]: " PORT +PORT="${PORT:-8080}" + +read -r -p "MAESTRO_SERVER_TOKEN (인증 토큰, 빈 값으로 두면 인증 없음): " MAESTRO_SERVER_TOKEN + +read -r -p "VITE_WS_URL (WebSocket 주소) [기본: ws://localhost:${PORT}]: " VITE_WS_URL +VITE_WS_URL="${VITE_WS_URL:-ws://localhost:${PORT}}" + +cat > "$ENV_FILE" << ENVEOF +# Maestro Coding — 환경변수 (자동 생성) +# ⚠️ 이 파일은 절대 Git에 커밋하지 마세요! + +MAIN_REPO_PATH=${MAIN_REPO_PATH} +PORT=${PORT} +MAESTRO_SERVER_TOKEN=${MAESTRO_SERVER_TOKEN} +VITE_WS_URL=${VITE_WS_URL} +ENVEOF + +echo "" +echo "✅ .env 파일이 생성되었습니다: $ENV_FILE" +echo "" +echo "서버를 시작하려면:" +echo " npm run server"