Harbor master for your async agents — a quiet lighthouse over your terminals, sweeping every session, signaling when one needs you.
Tauri 기반 터미널 멀티플렉서. macOS 네이티브 앱으로 동작하며 Claude Code / Codex / ssh·tmux 세션을 하나의 창에서 오가며 쓰도록 설계됨. 터미널 위에 얹히는 조용한 보조 레이어 — Zed·Warp 같은 톤.
┌───── TitleBar ─────────────────────────────────────────────┐
│ 워크스페이스 이름 ⎇ branch │
├──────────┬─────────────────────────────────────────────────┤
│ ● ws1 C │ │
│ ● ws2 X │ 터미널 (xterm.js, 분할/탭) │
│ ● ws3 $ │ │
│ ● ws4 ⇢ │ │
│ ├─────────────────────────────────────────────────┤
│ [⌘/ ] │ [C] Claude · ctx 48% · 🔨 BUILD ━━━░ 45% ⌘/ │
└──────────┴─────────────────────────────────────────────────┘
- 사이드바: 워크스페이스 리스트. 각 행에 상태 dot (running/waiting/idle/done), 소스 칩 (C/X/$/⇢/▦), phase, 대기 시간, hairline progress 바.
- StatusBar: source · ctx % · dev-flow phase + progress · 응답 대기 카운트.
- Activity 탭 (⌘Shift+A): 자동 감지 + CLI push 모든 이벤트의 타임라인. 마크다운 복사, kind/text 필터, 이 워크스페이스/전체 토글.
백그라운드 감지 모듈이 터미널 출력을 감시해 상태를 자동 갱신:
- State (1s 주기): 활동 있으면
running, 없으면idle. 터미널 tail에(y/n)/Do you want to proceed?/ Claude 승인 메뉴 보이면waiting. - Source (1s 주기): Claude
⏺ Tool(...)시그니처 · Codex 배너 · tmux 마커 · shell 프롬프트 downgrade.
수동 CLI 푸시는 언제든 가능하고 done 상태만 detector가 건드리지 않음.
pharos 바이너리로 외부 스크립트/에이전트에서 제어 가능.
# fleet 요약 — 지금 뭐 돌고 뭐 기다리는지
pharos identify
# { byState: { running:1, waiting:2, idle:3 },
# bySource: { claude:3, shell:2, ssh:1 }, ... }
# 타임라인 — 지난 30분 동안 전 워크스페이스 이벤트
pharos list-events --since 30m --all --limit 50
# 블로킹 대기 — Claude가 작업 마칠 때까지
WS=$(pharos wait --not-state running --timeout 300)
echo "finished: $WS"
# 특정 워크스페이스 승인 프롬프트 대기
pharos wait --state waiting --workspace $WS --timeout 60
# 섹션별 help (50+ 명령)
pharos help state # Atlas 상태 명령만
pharos help timeline # 이벤트 로그
pharos help wait # blocking 사용법전체 명령은 pharos 또는 pharos help <section>. 섹션: window / workspace / panes / terminal / status / state / timeline / history / memo / notify / theme / log / system / wait.
주요 CLI 카테고리:
- Status:
set-status·set-progress·report-pr·report-review·report-meta-block - Atlas state:
report-source·set-state·report-ctx/clear-ctx - Timeline:
list-events [--kind --since --all --limit]·clear-events - History (dev-flow):
history add·history list·history clear - Blocking:
wait [--state --source --phase --not-* --progress-min --workspace --timeout] - Trust:
trust-directory·untrust-directory·check-trust·list-trusted
dev-flow 여러 세션을 가로질러 동기화:
# 이 Pharos가 내가 필요한 feature를 지원하는지 확인
pharos version | jq -e '.features | contains(["wait-phase","identify-distributions"])' \
|| { echo "Pharos 구버전 — 업그레이드 필요"; exit 1; }
# fleet 스냅샷 한 눈에
pharos identify | jq '{running: .byState.running, waiting: .byState.waiting, byPhase}'
# 특정 워크스페이스 BUILD → REVIEW 전환까지 블록 (10분 timeout)
WS=$(pharos wait --phase REVIEW --workspace my-feature --timeout 600) \
&& echo "review ready: $WS"
# 다른 워크스페이스에서 Claude가 승인 프롬프트 띄우면 자동으로 yes
while WS=$(pharos wait --state waiting --timeout 3600); do
pharos send --workspace "$WS" -e "yes"
done
# 빌드 75% 넘을 때 배포 준비 시작
pharos wait --phase BUILD --progress-min 0.75 --workspace main --timeout 1200
./prepare-deploy.sh/dev-flow 스킬이 pharos set-status phase / set-progress / workspace-memo-append을 호출하면 사이드바·StatusBar·Activity 탭에 실시간 반영. Spec→Plan→Build→Test→Review→Ship 파이프라인의 각 단계가 시각화됨.
솔로 개발자가 앱 한 개의 기획(요구사항·기능명세·유저플로우)을 .blueprint.json 한 파일로 정리하고, 각 feature의 구현을 /dev로 zoom-in하는 워크플로. AI 생성·SaaS 협업·외부 공유는 영속적 비목표 — local-first, git-friendly, 사람이 직접 쓰는 구조화된 기획.
feature[].id가 /dev 호출 단위와 1:1 매핑되도록 설계.
# 빈 골격 생성 (mobile-booking 템플릿)
pharos blueprint init feature-x.blueprint.json --template mobile-booking
# 구조 + cross-reference 검증 (dangling ref · 중복 ID 등)
pharos blueprint validate feature-x.blueprint.json
# 미사용 ID / 고립 screen 같은 lint warning도 error로 승격하려면:
pharos --strict blueprint validate feature-x.blueprint.json
# 마크다운으로 뽑기 (PR description · README 등에 붙여넣기)
pharos blueprint export feature-x.blueprint.json --format mdpharos new-pane --type blueprint \
--file "$PWD/feature-x.blueprint.json" \
--view requirements # requirements | spec | flow좌측 사이드바에 3개 뷰 탭(요구사항 / 기능명세서 / 유저플로우). 각 카드에 다른 항목으로 점프하는 추적성 chip — 예: requirement 카드의 FEAT-x chip을 클릭하면 기능명세서 뷰로 이동 + 그 feature 카드 하이라이트.
외부 에디터로 파일을 수정하면 1초 이내 자동 갱신 (mtime polling, 심볼릭 링크는 안전을 위해 거부).
경로 제약: pane이 여는
.blueprint.json은$HOME아래에 있어야 합니다. Tauri webview의 fs scope가$HOME/**로 제한되어 있어/tmp같은 home 밖 경로는 missing-file 상태로 떨어집니다. CLI(pharos blueprint init/validate/export)는 daemon 미경유라 어디서든 동작합니다.
requirements[]의 priority(high|med|low) / status(todo|in-progress|done) / progress(0-100), features[]의 parentId(트리), flows[].steps[].lane(swim-lane 그룹화)은 모두 optional. schemaVersion: 1 파일은 더 이상 지원하지 않으며, pane은 schemaUnsupported 안내를 표시합니다.
requirementIds / featureIds / screenId는 다른 항목의 id를 가리키는 참조 — validate가 dangling을 잡습니다.
| 용도 | 경로 |
|---|---|
| TS 타입 (가장 권위 있는 모델) | src/blueprint/types.ts |
| 실제 예시 파일 | examples/booking.blueprint.json |
| JSON Schema 문서 (외부 IDE hint, 런타임 미사용) | schemas/pharos.blueprint.v2.schema.json |
| 검증 규칙 구현 | cli/src/blueprint.rs check_blueprint |
AI 생성 · SaaS 협업/공유 링크 · 비주얼 wireframe view (MVP 제외, 후행) · HTML/PNG export · Figma 식 자유 드래그.
Cmd+Alt+A — 포커스된 pane 옆에 Android 패널 분할. adb(Android SDK platform-tools)가 PATH 또는 ~/Library/Android/sdk/platform-tools에 있으면 자동 탐지.
디바이스 행 액션:
- Mirror —
adb screencapPNG 폴링 (~4 fps), tap/swipe/text/Back/Home/Recents, 프레임 PNG 저장 - Embed — scrcpy 서버로 H.264 스트림을 패널 안에 디코드 (60 fps, WebCodecs). 툴바
↓ embed-jar한 번 눌러서 jar 자동 다운로드 - scrcpy — 시스템
scrcpy바이너리를 외부 윈도우로 띄움 (의존성 있을 때) - Logs — 200~5000 라인 스냅샷 + 라이브 테일, 텍스트/우선순위(V/D/I/W/E/F) 필터, 라인 클릭 → 클립보드
- Apps — 패키지 검색 + Launch/Stop, "Install APK"로 로컬 .apk 설치
- Files —
/sdcard트리 탐색 (breadcrumb), Pull/Push, .apk 파일 행에서 디바이스 직접 설치 - Shell —
adb shell원샷 러너, 히스토리(↑/↓)와 프리셋 (dumpsys/getprop/ps 등)
scrcpy 임베드 사용은 src-tauri/resources/SCRCPY_SERVER.md 참조 — 패널 툴바의 ↓ embed-jar 버튼이 같은 작업을 자동화.
디바이스가 하나도 연결돼 있지 않으면 패널이 정의된 AVD 목록을 띄우고, 행 클릭으로 원클릭 부팅(android_launch_avd). pharos는 -gpu를 넘기지 않으므로, 그래픽 가속 모드는 전적으로 AVD config.ini의 hw.gpu.mode가 결정한다.
⚠️ 에뮬레이터가 느리면 GPU부터 의심. Apple Silicon에서hw.gpu.mode = auto가 host(Metal)를 못 잡고 SwiftShader(소프트웨어 렌더링)로 떨어지면 극심하게 느려진다.~/.android/avd/<name>.avd/config.ini에서hw.gpu.mode = host로 못박고(+hw.ramSize4096 이상), 콜드부트(-no-snapshot-load)하면 해결. 부팅 로그의gles_mode_selected:host/GLES: ... Apple M.. Metal로 적용을 확인할 수 있다. 한 번 software로 뜬 인스턴스는 끄기 전까지 계속 software이므로, 설정만 바꾸지 말고 반드시 재부팅한다.
yarn install
yarn tauri dev # Tauri 앱 개발 모드
yarn test # TS 유닛 테스트 (vitest)
yarn check # cargo check + tsc --noEmit + vitest
# CLI 빌드 (cli/ crate, workspace member)
cargo build -p pharos-cli --release
# → target/release/pharos (워크스페이스 공통 target, cli/target 아님)src/
App.tsx detector 부트스트랩, 이벤트 구독
components/
Sidebar.tsx 워크스페이스 리스트 + 인라인 검색 + 컨텍스트 메뉴
TitleBar / StatusBar / MemoPanel(+Activity 탭)
Terminal / SplitView xterm.js 래퍼 + 분할 관리
store/
workspace / pane / status / events / activityView / ...
stateDetector / sourceDetector 폴링 루프
socketHandler.ts CLI ↔ 앱 명령 라우팅
transcriptSearch.ts xterm 버퍼 크로스 워크스페이스 grep
cli/src/main.rs pharos CLI 바이너리 (tokio + Unix socket)
src-tauri/src/ Rust: PTY 스폰, SSH, 소켓 서버
본 repo는 글로벌 ~/.claude/{skills,commands} 로 어떤 파일도 install하지
않는다. pharos에서 codex/claude 시블링 pane으로 작업을 위임하는
dispatch-pane SKILL을 포함해 모든 글로벌 SKILL은 별도
claude-config repo가 단일
진실원으로 관리한다.
과거에 scripts/install-claude.sh 로 글로벌 ~/.claude/ 에 symlink을 만든
사용자는 한 번 정리:
rm -f ~/.claude/skills/{dev,pharos,dispatch-pane} \
~/.claude/commands/{dev,pharos}.md이후 글로벌 SKILL은 claude-config repo의 install.sh 로만 가져온다.
최초 설치(install.sh) 이후로는 GUI 앱이 하네스를 직접 동기화한다. 실행할 때마다
~/.claude의 CLAUDE.md 블록·skills/hooks/commands 심링크를 repo 소스와 대조해
버전이 바뀌었으면 자동 재적용한다(마커 안만 건드리고 사용자 콘텐츠는 보존).
Settings → Harness에서 컴포넌트(guidelines/pharos/fable/skills/hooks/commands)를
개별로 켜고 끌 수 있다. 하네스 업데이트를 받으려고 install.sh를 다시 돌릴 필요 없이
앱만 재시작하면 된다.
Atlas 핸드오프 (pharos/project/Pharos Terminal Redesign.html) 기반. 구현 세부는 TODO.md의 "Atlas 디자인 구현 요약" 참조.
내부 프로젝트. 별도 라이선스 파일 없음.
{ "schemaVersion": 2, "name": "기능 이름", "requirements": [ { "id": "REQ-1", "title": "...", "description": "...", "priority": "high", "status": "todo", "progress": 0 } ], "features": [ { "id": "FEAT-x", "title": "...", "requirementIds": ["REQ-1"], "parentId": null } ], "flows": [{ "id": "FLOW-main", "title": "...", "featureIds": ["FEAT-x"], "steps": [ { "id": "S1", "description": "...", "screenId": "SCR-home", "featureIds": ["FEAT-x"], "lane": "Search" } ] }], "screens": [ { "id": "SCR-home", "name": "홈", "role": "search-entry", "featureIds": ["FEAT-x"] } ] }