diff --git a/.agents/AGENT.md b/.agents/AGENT.md index b36d0c9..d49ce4e 100644 --- a/.agents/AGENT.md +++ b/.agents/AGENT.md @@ -19,6 +19,10 @@ description: 모든 작업에 자동 적용되는 에이전트 행동 규칙. 7. NEVER truncate error messages — always show the full error output 8. NEVER use `curl` in PowerShell — always use `curl.exe` 9. NEVER run `npm` directly — use `cmd /c npm` to avoid execution policy issues +10. NEVER run `python` directly — use `C:\ProgramData\miniforge3\envs\gravity_web\python.exe` +11. NEVER use `python -c "..."` inline one-liners in PowerShell — write a `.py` file instead +12. NEVER start server without killing existing port process first (EADDRINUSE) +13. NEVER use `send_command_input Terminate` to stop servers — use `Stop-Process` or `taskkill /F` via `run_command` instead (Terminate hangs the agent) ## ALWAYS (필수) diff --git a/.agents/references/known-issues.md b/.agents/references/known-issues.md index 4ffa546..71db3fe 100644 --- a/.agents/references/known-issues.md +++ b/.agents/references/known-issues.md @@ -46,4 +46,46 @@ ## 프로젝트별 이슈 -(세션 진행 중 발견되는 이슈를 여기에 추가) +### [2026-03-08] Python 실행 — Windows Store 리다이렉트 +- **증상**: `python` 명령이 Microsoft Store 페이지를 열거나 빈 출력 반환 +- **원인**: Windows 기본 `python`이 App Execution Alias(Microsoft Store 리다이렉트)로 설정됨 +- **해결**: **`C:\ProgramData\miniforge3\envs\gravity_web\python.exe`** 전체 경로 사용 +- **주의**: 워크플로우 내 모든 `python` 호출을 전체 경로로 교체할 것 + +### [2026-03-08] PowerShell inline Python — 따옴표 깨짐 +- **증상**: `python -c "import json; ..."` 또는 파이프 `| python -c "..."` 에서 SyntaxError +- **원인**: PowerShell이 쌍따옴표/홑따옴표/중괄호를 자체 해석하여 Python에 전달 시 깨짐 +- **해결**: `.py` 스크립트 파일을 `/tmp/`에 생성 후 전체 경로 Python으로 실행 +- **주의**: **절대** `python -c` 인라인 실행 금지. `curl.exe ... | python -c` 조합은 100% 실패 + +### [2026-03-08] 서버 포트 — EADDRINUSE +- **증상**: `node index.js` 시작 시 `Error: listen EADDRINUSE: address already in use :::3300` +- **원인**: 이전 서버 프로세스가 종료되지 않은 상태에서 재시작 +- **해결**: 서버 시작 전 기존 프로세스를 포트 기반으로 종료 + ```powershell + $p = Get-NetTCPConnection -LocalPort 3300 -ErrorAction SilentlyContinue + if ($p) { Stop-Process -Id $p.OwningProcess -Force; Start-Sleep 1 } + ``` +- **주의**: `Stop-Process -Name node` 는 다른 Node 프로세스까지 죽일 수 있으므로 포트 기반 종료 권장 + +--- + +## Antigravity SDK/API 제한사항 + +### [2026-03-08] Trajectory API — 341개 제한, 페이지네이션 불가 +- **증상**: `GetCascadeTrajectory` RPC가 항상 처음 341개 스텝만 반환 +- **원인**: API 서버 측 하드 제한. `startStepIndex`, `endStepIndex`, `stepIndexRange` 파라미터 모두 무시됨 +- **해결**: 서버 사이드 `message-accumulator.js`로 cascades diff를 누적하여 step 341+ 이후 메시지 보존 +- **주의**: trajectory만으로는 전체 대화 히스토리를 표시할 수 없음 + +### [2026-03-08] Cascade API — 명령 승인 대기 상태 미제공 +- **증상**: `run_command(SafeToAutoRun=false)` 대기 중에도 cascade status는 `CASCADE_RUN_STATUS_RUNNING` 유지 +- **원인**: Cascade API에 command approval 관련 별도 필드 없음 +- **해결**: stepCount 변화 정체(6초)로 추정 + 헤더에 영구적 승인/거절 버튼 추가 +- **주의**: 자동 감지는 정확하지 않음. 사용자가 직접 버튼 클릭이 더 신뢰성 있음 + +### [2026-03-08] broadcastToAll 미정의 버그 +- **증상**: bridge WS 이벤트가 브라우저에 전혀 전달되지 않음 (실시간 업데이트 불가) +- **원인**: `index.js`에서 `broadcastToAll()` 함수를 호출하지만 정의가 누락되어 있었음 +- **해결**: `broadcastToAll` 함수 정의 추가 (wsClients 순회하여 JSON 전송) +- **주의**: JS는 미정의 함수 호출 시 런타임 에러만 발생하고 서버는 죽지 않아 발견이 어려움 diff --git a/.agents/workflows/check-gitea.md b/.agents/workflows/check-gitea.md index 2d16c5e..367dd8b 100644 --- a/.agents/workflows/check-gitea.md +++ b/.agents/workflows/check-gitea.md @@ -26,15 +26,15 @@ $issues | ForEach-Object { Write-Host "#$($_.number) $($_.title)" } 3. Wiki 페이지 목록: ```powershell -python .agents\workflows\helpers\wiki_helper.py list +C:\ProgramData\miniforge3\envs\gravity_web\python.exe .agents\workflows\helpers\wiki_helper.py list ``` 4. Wiki 페이지 읽기: ```powershell -python .agents\workflows\helpers\wiki_helper.py read "Architecture" +C:\ProgramData\miniforge3\envs\gravity_web\python.exe .agents\workflows\helpers\wiki_helper.py read "Architecture" ``` 5. Wiki 페이지 업데이트: ```powershell -python .agents\workflows\helpers\wiki_helper.py update "페이지-제목" /tmp/wiki_content.md +C:\ProgramData\miniforge3\envs\gravity_web\python.exe .agents\workflows\helpers\wiki_helper.py update "페이지-제목" /tmp/wiki_content.md ``` diff --git a/.agents/workflows/check-vikunja.md b/.agents/workflows/check-vikunja.md index 244d3a8..61fcb0c 100644 --- a/.agents/workflows/check-vikunja.md +++ b/.agents/workflows/check-vikunja.md @@ -12,27 +12,27 @@ description: Vikunja API로 gravity_web 프로젝트 태스크 현황을 조회 1. 전체 목록: ```powershell -python .agents\workflows\helpers\vikunja_helper.py list +C:\ProgramData\miniforge3\envs\gravity_web\python.exe .agents\workflows\helpers\vikunja_helper.py list ``` 2. TODO만: ```powershell -python .agents\workflows\helpers\vikunja_helper.py list todo +C:\ProgramData\miniforge3\envs\gravity_web\python.exe .agents\workflows\helpers\vikunja_helper.py list todo ``` 3. DONE만: ```powershell -python .agents\workflows\helpers\vikunja_helper.py list done +C:\ProgramData\miniforge3\envs\gravity_web\python.exe .agents\workflows\helpers\vikunja_helper.py list done ``` 4. 태스크 완료 처리 (**⚠️ 반드시 이 방법 사용 — 직접 API 호출 금지**): ```powershell -python .agents\workflows\helpers\vikunja_helper.py done {TASK_ID} +C:\ProgramData\miniforge3\envs\gravity_web\python.exe .agents\workflows\helpers\vikunja_helper.py done {TASK_ID} ``` 5. 새 태스크 생성: ```powershell -python .agents\workflows\helpers\vikunja_helper.py create "제목" "설명" --labels Backend,Priority:High +C:\ProgramData\miniforge3\envs\gravity_web\python.exe .agents\workflows\helpers\vikunja_helper.py create "제목" "설명" --labels Backend,Priority:High ``` > [!CAUTION] diff --git a/.agents/workflows/end.md b/.agents/workflows/end.md index 5c47945..d9241e9 100644 --- a/.agents/workflows/end.md +++ b/.agents/workflows/end.md @@ -83,9 +83,9 @@ git log --oneline -20 | 커밋 유형 | Vikunja 액션 | |-----------|-------------| -| 기존 태스크 해당 작업 **완료** | `python .agents\workflows\helpers\vikunja_helper.py done {ID}` | -| 신규 작업 완료 (기존 태스크 없음) | `python .agents\workflows\helpers\vikunja_helper.py create "제목" "설명" --done --labels Backend,Priority:High` | -| 작업 중 발견된 **미완료 TODO** | `python .agents\workflows\helpers\vikunja_helper.py create "제목" "설명" --labels Backend,Priority:Mid` | +| 기존 태스크 해당 작업 **완료** | `C:\ProgramData\miniforge3\envs\gravity_web\python.exe .agents\workflows\helpers\vikunja_helper.py done {ID}` | +| 신규 작업 완료 (기존 태스크 없음) | `C:\ProgramData\miniforge3\envs\gravity_web\python.exe .agents\workflows\helpers\vikunja_helper.py create "제목" "설명" --done --labels Backend,Priority:High` | +| 작업 중 발견된 **미완료 TODO** | `C:\ProgramData\miniforge3\envs\gravity_web\python.exe .agents\workflows\helpers\vikunja_helper.py create "제목" "설명" --labels Backend,Priority:Mid` | > [!IMPORTANT] > 모든 커밋이 기존 또는 신규 태스크에 매핑되었는지 확인. @@ -99,7 +99,7 @@ git log --oneline -20 | 프론트엔드 변경 | Architecture | ```powershell -python .agents\workflows\helpers\wiki_helper.py update "Architecture" /tmp/wiki_content.md +C:\ProgramData\miniforge3\envs\gravity_web\python.exe .agents\workflows\helpers\wiki_helper.py update "Architecture" /tmp/wiki_content.md ``` --- diff --git a/.agents/workflows/services.md b/.agents/workflows/services.md index 7b458f7..df34b27 100644 --- a/.agents/workflows/services.md +++ b/.agents/workflows/services.md @@ -13,10 +13,41 @@ description: Gravity Web 프로젝트 연동 서비스 URL, API 키, 프로젝 |------|-----| | **Node.js** | 시스템 설치 (`node`, `npm`) | | **Python (helper)** | `C:\ProgramData\miniforge3\envs\gravity_web\python.exe` | -| **프로젝트 루트** | `c:\Users\Certes\Desktop\gravity_web` | +| **프로젝트 루트** | `c:\Users\Cafe-Variet-E495\Desktop\gravity_web\gravity_web` | | **Shell** | PowerShell (`curl` = `Invoke-WebRequest` 별칭이므로 반드시 **`curl.exe`** 사용) | | **서버 실행** | `cd server && cmd /c node index.js` (port 3300) | +### Python 실행 규칙 + +```powershell +# ✅ 항상 전체 경로 사용 (python은 Windows Store 리다이렉트됨) +$PYTHON = "C:\ProgramData\miniforge3\envs\gravity_web\python.exe" +& $PYTHON .agents\workflows\helpers\vikunja_helper.py list todo +``` + +```powershell +# ❌ 금지: bare python / inline one-liner +python script.py # PATH 문제 +python -c "import json; ..." # PowerShell 이스케이핑 깨짐 +curl.exe ... | python -c "..." # 파이프 + 인라인 = 100% 실패 +``` + +> [!WARNING] +> PowerShell에서 **inline Python one-liner는 절대 사용 금지**. 따옴표/특수문자가 깨집니다. +> 반드시 `.py` 파일을 `/tmp/` 에 만들어서 실행하세요. + +### 서버 시작/종료 패턴 + +```powershell +# 서버 시작 전 기존 프로세스 정리 (EADDRINUSE 방지) +$existing = Get-NetTCPConnection -LocalPort 3300 -ErrorAction SilentlyContinue +if ($existing) { + Stop-Process -Id (Get-Process -Id $existing.OwningProcess).Id -Force + Start-Sleep -Seconds 1 +} +cmd /c "cd server && node index.js" +``` + ## Gitea (Git Repository) | 항목 | 값 | @@ -43,7 +74,7 @@ description: Gravity Web 프로젝트 연동 서비스 URL, API 키, 프로젝 > 태스크 목록은 항상 라이브 조회를 사용합니다. 하드코딩된 매핑은 유지하지 않습니다. ```powershell -python .agents\workflows\helpers\vikunja_helper.py list todo +C:\ProgramData\miniforge3\envs\gravity_web\python.exe .agents\workflows\helpers\vikunja_helper.py list todo ``` ## 기타 서비스 diff --git a/.agents/workflows/start.md b/.agents/workflows/start.md index 7e9eebb..e52f911 100644 --- a/.agents/workflows/start.md +++ b/.agents/workflows/start.md @@ -48,7 +48,7 @@ git log --oneline -5 ### 3. Vikunja TODO 태스크 ```powershell -python .agents\workflows\helpers\vikunja_helper.py list todo +C:\ProgramData\miniforge3\envs\gravity_web\python.exe .agents\workflows\helpers\vikunja_helper.py list todo ``` ### 4. 종합 보고 diff --git a/docs/devlog/2026-03-08.md b/docs/devlog/2026-03-08.md new file mode 100644 index 0000000..28fd62e --- /dev/null +++ b/docs/devlog/2026-03-08.md @@ -0,0 +1,5 @@ +# 2026-03-08 Devlog + +| # | 시간 | 작업 설명 | 커밋 | 상태 | +|---|------|----------|------|------| +| 1 | 08:42~13:58 | 실시간 동기화 아키텍처 구현 (message-accumulator, cascade polling, 승인 버튼) | `pending` | 🔧 | diff --git a/docs/devlog/entries/20260308-001.md b/docs/devlog/entries/20260308-001.md new file mode 100644 index 0000000..5cdc087 --- /dev/null +++ b/docs/devlog/entries/20260308-001.md @@ -0,0 +1,30 @@ +# 실시간 동기화 아키텍처 구현 + +- **시간**: 2026-03-08 08:42~13:58 +- **Commit**: `pending` +- **Vikunja**: #251 → done + +## 결정 사항 + +### Trajectory API 한계 → Message Accumulator 패턴 +- Trajectory API가 341개로 하드캡, 페이지네이션 파라미터 무시됨 +- Cascades API가 최신 task/notify만 제공 (1개씩) +- **해결**: 서버사이드 `message-accumulator.js`로 cascade 스냅샷을 3초마다 diff하여 새 메시지 누적 저장 +- 초기 로드: trajectory(341) + accumulated messages 합산 + +### 실시간 Push vs Polling +- Bridge WS 이벤트(step_changed)에 의존만으로는 누락 발생 가능 +- **3초 interval polling**을 백업으로 추가하여 안정성 보장 +- WS 이벤트 + polling 이중 구조 + +### 승인 버튼: 자동 감지 vs 수동 +- Cascade API에 command approval 대기 필드 없음 (status는 항상 RUNNING) +- stepCount 정체 감지(6초)로 추정 시도 → 불안정 +- **최종 결정**: 헤더에 영구적 ✅ 승인 / ❌ 거절 버튼 추가 (always accessible) + +## 미완료 + +- [ ] 승인 버튼 자동 감지 안정화 (isWaiting 정확도 개선) +- [ ] inline 승인 버튼(chat 내부)과 헤더 버튼 간 상태 동기화 +- [ ] 대화 중간 메시지 누락 문제 (서버 재시작 시 accumulator 초기화) +- [ ] isWaiting→isRunning 전환 시 DOM 리렌더링으로 인한 스크롤 점프 미세 조정 diff --git a/public/css/style.css b/public/css/style.css index 01fa664..c7a13b9 100644 --- a/public/css/style.css +++ b/public/css/style.css @@ -182,6 +182,37 @@ body { padding: 0 8px 8px; } +/* 프로젝트 그룹 헤더 */ +.project-group-header { + display: flex; + align-items: center; + gap: 8px; + padding: 10px 12px 4px; + font-size: 11px; + font-weight: 600; + color: var(--text-muted); + text-transform: uppercase; + letter-spacing: 0.05em; +} + +.project-group-dot { + width: 8px; + height: 8px; + border-radius: 50%; + flex-shrink: 0; +} + +/* 이전 메시지 로더 */ +.load-more-indicator { + text-align: center; + color: var(--text-muted); + font-size: 11px; + padding: 12px 0; + opacity: 0.6; + border-bottom: 1px solid var(--border-subtle); + margin-bottom: 8px; +} + /* Session Card */ .session-card { display: flex; @@ -392,6 +423,56 @@ body { .chat-actions { display: flex; gap: 6px; + align-items: center; +} + +.approve-controls { + display: flex; + gap: 4px; + margin-left: 8px; + padding-left: 8px; + border-left: 1px solid var(--border); +} + +.btn-approve, +.btn-reject { + font-size: 12px; + padding: 4px 10px; + border: 1px solid transparent; + border-radius: 6px; + cursor: pointer; + font-weight: 500; + transition: all 0.2s; +} + +.btn-approve { + background: rgba(34, 197, 94, 0.15); + color: #22c55e; + border-color: rgba(34, 197, 94, 0.3); +} + +.btn-approve:hover { + background: rgba(34, 197, 94, 0.3); +} + +.btn-approve:disabled { + opacity: 0.4; + cursor: not-allowed; +} + +.btn-reject { + background: rgba(239, 68, 68, 0.15); + color: #ef4444; + border-color: rgba(239, 68, 68, 0.3); +} + +.btn-reject:hover { + background: rgba(239, 68, 68, 0.3); +} + +.btn-reject:disabled { + opacity: 0.4; + cursor: not-allowed; } /* Chat Messages */ diff --git a/public/index.html b/public/index.html index cc85e11..5d8a135 100644 --- a/public/index.html +++ b/public/index.html @@ -1,5 +1,6 @@ +
@@ -7,9 +8,12 @@ - + +