{"id":51144952,"url":"https://github.com/dong-park/pharos","last_synced_at":"2026-06-26T02:01:08.326Z","repository":{"id":351038000,"uuid":"1209273831","full_name":"dong-park/pharos","owner":"dong-park","description":"xterm.js + Tauri로 만든 macOS 터미널 멀티플렉서. Claude Code · Codex 같은 AI 에이전트 세션을 한 창에서 오갑니다.","archived":false,"fork":false,"pushed_at":"2026-06-25T07:13:42.000Z","size":124977,"stargazers_count":0,"open_issues_count":10,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-25T08:20:44.598Z","etag":null,"topics":["ai-agent","claude-code","multiplexer","tauri","terminal","xterm"],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dong-park.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-04-13T09:04:17.000Z","updated_at":"2026-06-25T07:13:45.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/dong-park/pharos","commit_stats":null,"previous_names":["dong-park/pharos"],"tags_count":14,"template":false,"template_full_name":null,"purl":"pkg:github/dong-park/pharos","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dong-park%2Fpharos","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dong-park%2Fpharos/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dong-park%2Fpharos/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dong-park%2Fpharos/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dong-park","download_url":"https://codeload.github.com/dong-park/pharos/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dong-park%2Fpharos/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34799570,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-26T02:00:06.560Z","response_time":106,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ai-agent","claude-code","multiplexer","tauri","terminal","xterm"],"created_at":"2026-06-26T02:01:07.585Z","updated_at":"2026-06-26T02:01:08.316Z","avatar_url":"https://github.com/dong-park.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Pharos\n\n\u003e **Harbor master for your async agents** — a quiet lighthouse over your terminals, sweeping every session, signaling when one needs you.\n\nTauri 기반 터미널 멀티플렉서. macOS 네이티브 앱으로 동작하며 **Claude Code / Codex / ssh·tmux** 세션을 하나의 창에서 오가며 쓰도록 설계됨. 터미널 위에 얹히는 조용한 보조 레이어 — Zed·Warp 같은 톤.\n\n## 핵심 개념\n\n```\n┌───── TitleBar ─────────────────────────────────────────────┐\n│  워크스페이스 이름                             ⎇ branch   │\n├──────────┬─────────────────────────────────────────────────┤\n│ ● ws1 C  │                                                 │\n│ ● ws2 X  │         터미널 (xterm.js, 분할/탭)              │\n│ ● ws3 $  │                                                 │\n│ ● ws4 ⇢  │                                                 │\n│          ├─────────────────────────────────────────────────┤\n│  [⌘/ ]   │  [C] Claude · ctx 48% · 🔨 BUILD ━━━░ 45%  ⌘/ │\n└──────────┴─────────────────────────────────────────────────┘\n```\n\n- **사이드바**: 워크스페이스 리스트. 각 행에 상태 dot (running/waiting/idle/done), 소스 칩 (C/X/$/⇢/▦), phase, 대기 시간, hairline progress 바.\n- **StatusBar**: source · ctx % · dev-flow phase + progress · 응답 대기 카운트.\n- **Activity 탭** (⌘Shift+A): 자동 감지 + CLI push 모든 이벤트의 타임라인. 마크다운 복사, kind/text 필터, 이 워크스페이스/전체 토글.\n\n## 자동 감지 (detector)\n\n백그라운드 감지 모듈이 터미널 출력을 감시해 상태를 자동 갱신:\n\n- **State** (1s 주기): 활동 있으면 `running`, 없으면 `idle`. 터미널 tail에 `(y/n)` / `Do you want to proceed?` / Claude 승인 메뉴 보이면 `waiting`.\n- **Source** (1s 주기): Claude `⏺ Tool(...)` 시그니처 · Codex 배너 · tmux 마커 · shell 프롬프트 downgrade.\n\n수동 CLI 푸시는 언제든 가능하고 `done` 상태만 detector가 건드리지 않음.\n\n## CLI 자동화 primitives\n\n`pharos` 바이너리로 외부 스크립트/에이전트에서 제어 가능.\n\n```bash\n# fleet 요약 — 지금 뭐 돌고 뭐 기다리는지\npharos identify\n# { byState: { running:1, waiting:2, idle:3 },\n#   bySource: { claude:3, shell:2, ssh:1 }, ... }\n\n# 타임라인 — 지난 30분 동안 전 워크스페이스 이벤트\npharos list-events --since 30m --all --limit 50\n\n# 블로킹 대기 — Claude가 작업 마칠 때까지\nWS=$(pharos wait --not-state running --timeout 300)\necho \"finished: $WS\"\n\n# 특정 워크스페이스 승인 프롬프트 대기\npharos wait --state waiting --workspace $WS --timeout 60\n\n# 섹션별 help (50+ 명령)\npharos help state       # Atlas 상태 명령만\npharos help timeline    # 이벤트 로그\npharos help wait        # blocking 사용법\n```\n\n전체 명령은 `pharos` 또는 `pharos help \u003csection\u003e`. 섹션: window / workspace / panes / terminal / status / state / timeline / history / memo / notify / theme / log / system / wait.\n\n주요 CLI 카테고리:\n- **Status**: `set-status` · `set-progress` · `report-pr` · `report-review` · `report-meta-block`\n- **Atlas state**: `report-source` · `set-state` · `report-ctx` / `clear-ctx`\n- **Timeline**: `list-events [--kind --since --all --limit]` · `clear-events`\n- **History (dev-flow)**: `history add` · `history list` · `history clear`\n- **Blocking**: `wait [--state --source --phase --not-* --progress-min --workspace --timeout]`\n- **Trust**: `trust-directory` · `untrust-directory` · `check-trust` · `list-trusted`\n\n### 오케스트레이션 예제\n\ndev-flow 여러 세션을 가로질러 동기화:\n\n```bash\n# 이 Pharos가 내가 필요한 feature를 지원하는지 확인\npharos version | jq -e '.features | contains([\"wait-phase\",\"identify-distributions\"])' \\\n  || { echo \"Pharos 구버전 — 업그레이드 필요\"; exit 1; }\n\n# fleet 스냅샷 한 눈에\npharos identify | jq '{running: .byState.running, waiting: .byState.waiting, byPhase}'\n\n# 특정 워크스페이스 BUILD → REVIEW 전환까지 블록 (10분 timeout)\nWS=$(pharos wait --phase REVIEW --workspace my-feature --timeout 600) \\\n  \u0026\u0026 echo \"review ready: $WS\"\n\n# 다른 워크스페이스에서 Claude가 승인 프롬프트 띄우면 자동으로 yes\nwhile WS=$(pharos wait --state waiting --timeout 3600); do\n  pharos send --workspace \"$WS\" -e \"yes\"\ndone\n\n# 빌드 75% 넘을 때 배포 준비 시작\npharos wait --phase BUILD --progress-min 0.75 --workspace main --timeout 1200\n./prepare-deploy.sh\n```\n\n## dev-flow 통합\n\n`/dev-flow` 스킬이 `pharos set-status phase` / `set-progress` / `workspace-memo-append`을 호출하면 사이드바·StatusBar·Activity 탭에 실시간 반영. Spec→Plan→Build→Test→Review→Ship 파이프라인의 각 단계가 시각화됨.\n\n## Blueprint pane — 앱 전체 기획 산출물\n\n솔로 개발자가 **앱 한 개의 기획**(요구사항·기능명세·유저플로우)을 `.blueprint.json` 한 파일로 정리하고, 각 `feature`의 구현을 `/dev`로 zoom-in하는 워크플로. AI 생성·SaaS 협업·외부 공유는 영속적 비목표 — local-first, git-friendly, 사람이 직접 쓰는 구조화된 기획.\n\n`feature[].id`가 `/dev` 호출 단위와 1:1 매핑되도록 설계.\n\n### CLI (offline, daemon 미경유)\n\n```bash\n# 빈 골격 생성 (mobile-booking 템플릿)\npharos blueprint init feature-x.blueprint.json --template mobile-booking\n\n# 구조 + cross-reference 검증 (dangling ref · 중복 ID 등)\npharos blueprint validate feature-x.blueprint.json\n# 미사용 ID / 고립 screen 같은 lint warning도 error로 승격하려면:\npharos --strict blueprint validate feature-x.blueprint.json\n\n# 마크다운으로 뽑기 (PR description · README 등에 붙여넣기)\npharos blueprint export feature-x.blueprint.json --format md\n```\n\n### Pane 안에서 보기\n\n```bash\npharos new-pane --type blueprint \\\n  --file \"$PWD/feature-x.blueprint.json\" \\\n  --view requirements    # requirements | spec | flow\n```\n\n좌측 사이드바에 3개 뷰 탭(요구사항 / 기능명세서 / 유저플로우). 각 카드에 다른 항목으로 점프하는 추적성 chip — 예: requirement 카드의 `FEAT-x` chip을 클릭하면 기능명세서 뷰로 이동 + 그 feature 카드 하이라이트.\n\n외부 에디터로 파일을 수정하면 1초 이내 자동 갱신 (mtime polling, 심볼릭 링크는 안전을 위해 거부).\n\n\u003e **경로 제약**: pane이 여는 `.blueprint.json`은 `$HOME` 아래에 있어야 합니다. Tauri webview의 fs scope가 `$HOME/**`로 제한되어 있어 `/tmp` 같은 home 밖 경로는 missing-file 상태로 떨어집니다. CLI(`pharos blueprint init/validate/export`)는 daemon 미경유라 어디서든 동작합니다.\n\n### 최소 JSON 형식\n\n```jsonc\n{\n  \"schemaVersion\": 2,\n  \"name\": \"기능 이름\",\n  \"requirements\": [\n    { \"id\": \"REQ-1\", \"title\": \"...\", \"description\": \"...\", \"priority\": \"high\", \"status\": \"todo\", \"progress\": 0 }\n  ],\n  \"features\": [\n    { \"id\": \"FEAT-x\", \"title\": \"...\", \"requirementIds\": [\"REQ-1\"], \"parentId\": null }\n  ],\n  \"flows\": [{\n    \"id\": \"FLOW-main\", \"title\": \"...\", \"featureIds\": [\"FEAT-x\"],\n    \"steps\": [\n      { \"id\": \"S1\", \"description\": \"...\", \"screenId\": \"SCR-home\", \"featureIds\": [\"FEAT-x\"], \"lane\": \"Search\" }\n    ]\n  }],\n  \"screens\": [\n    { \"id\": \"SCR-home\", \"name\": \"홈\", \"role\": \"search-entry\", \"featureIds\": [\"FEAT-x\"] }\n  ]\n}\n```\n\n`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` 안내를 표시합니다.\n\n`requirementIds` / `featureIds` / `screenId`는 다른 항목의 `id`를 가리키는 참조 — `validate`가 dangling을 잡습니다.\n\n### 권위 파일\n\n| 용도 | 경로 |\n|------|------|\n| TS 타입 (가장 권위 있는 모델) | `src/blueprint/types.ts` |\n| 실제 예시 파일 | `examples/booking.blueprint.json` |\n| JSON Schema 문서 (외부 IDE hint, 런타임 미사용) | `schemas/pharos.blueprint.v2.schema.json` |\n| 검증 규칙 구현 | `cli/src/blueprint.rs` `check_blueprint` |\n\n### 비목표\n\nAI 생성 · SaaS 협업/공유 링크 · 비주얼 wireframe view (MVP 제외, 후행) · HTML/PNG export · Figma 식 자유 드래그.\n\n## Android 디버그 패널\n\n`Cmd+Alt+A` — 포커스된 pane 옆에 Android 패널 분할. `adb`(Android SDK platform-tools)가 PATH 또는 `~/Library/Android/sdk/platform-tools`에 있으면 자동 탐지.\n\n디바이스 행 액션:\n- **Mirror** — `adb screencap` PNG 폴링 (~4 fps), tap/swipe/text/Back/Home/Recents, 프레임 PNG 저장\n- **Embed** — scrcpy 서버로 H.264 스트림을 패널 안에 디코드 (60 fps, WebCodecs). 툴바 `↓ embed-jar` 한 번 눌러서 jar 자동 다운로드\n- **scrcpy** — 시스템 `scrcpy` 바이너리를 외부 윈도우로 띄움 (의존성 있을 때)\n- **Logs** — 200~5000 라인 스냅샷 + 라이브 테일, 텍스트/우선순위(V/D/I/W/E/F) 필터, 라인 클릭 → 클립보드\n- **Apps** — 패키지 검색 + Launch/Stop, \"Install APK\"로 로컬 .apk 설치\n- **Files** — `/sdcard` 트리 탐색 (breadcrumb), Pull/Push, .apk 파일 행에서 디바이스 직접 설치\n- **Shell** — `adb shell` 원샷 러너, 히스토리(↑/↓)와 프리셋 (dumpsys/getprop/ps 등)\n\nscrcpy 임베드 사용은 `src-tauri/resources/SCRCPY_SERVER.md` 참조 — 패널 툴바의 `↓ embed-jar` 버튼이 같은 작업을 자동화.\n\n### AVD 부팅 · 성능\n\n디바이스가 하나도 연결돼 있지 않으면 패널이 정의된 AVD 목록을 띄우고, 행 클릭으로 원클릭 부팅(`android_launch_avd`). pharos는 `-gpu`를 넘기지 **않으므로**, 그래픽 가속 모드는 전적으로 AVD `config.ini`의 `hw.gpu.mode`가 결정한다.\n\n\u003e ⚠️ **에뮬레이터가 느리면 GPU부터 의심.** Apple Silicon에서 `hw.gpu.mode = auto`가 host(Metal)를 못 잡고 SwiftShader(소프트웨어 렌더링)로 떨어지면 극심하게 느려진다. `~/.android/avd/\u003cname\u003e.avd/config.ini`에서 `hw.gpu.mode = host`로 못박고(+ `hw.ramSize` 4096 이상), 콜드부트(`-no-snapshot-load`)하면 해결. 부팅 로그의 `gles_mode_selected:host` / `GLES: ... Apple M.. Metal`로 적용을 확인할 수 있다. 한 번 software로 뜬 인스턴스는 끄기 전까지 계속 software이므로, 설정만 바꾸지 말고 반드시 재부팅한다.\n\n## 개발\n\n```bash\nyarn install\nyarn tauri dev          # Tauri 앱 개발 모드\nyarn test               # TS 유닛 테스트 (vitest)\nyarn check              # cargo check + tsc --noEmit + vitest\n\n# CLI 빌드 (cli/ crate, workspace member)\ncargo build -p pharos-cli --release\n# → target/release/pharos  (워크스페이스 공통 target, cli/target 아님)\n```\n\n### 프로젝트 구조\n\n```\nsrc/\n  App.tsx                 detector 부트스트랩, 이벤트 구독\n  components/\n    Sidebar.tsx           워크스페이스 리스트 + 인라인 검색 + 컨텍스트 메뉴\n    TitleBar / StatusBar / MemoPanel(+Activity 탭)\n    Terminal / SplitView  xterm.js 래퍼 + 분할 관리\n  store/\n    workspace / pane / status / events / activityView / ...\n  stateDetector / sourceDetector  폴링 루프\n  socketHandler.ts        CLI ↔ 앱 명령 라우팅\n  transcriptSearch.ts     xterm 버퍼 크로스 워크스페이스 grep\n\ncli/src/main.rs           pharos CLI 바이너리 (tokio + Unix socket)\nsrc-tauri/src/            Rust: PTY 스폰, SSH, 소켓 서버\n```\n\n### Claude Code SKILLs\n\n본 repo는 글로벌 `~/.claude/{skills,commands}` 로 어떤 파일도 install하지\n않는다. pharos에서 codex/claude 시블링 pane으로 작업을 위임하는\n`dispatch-pane` SKILL을 포함해 모든 글로벌 SKILL은 별도\n[`claude-config`](https://github.com/dong-park/claude-config) repo가 단일\n진실원으로 관리한다.\n\n과거에 `scripts/install-claude.sh` 로 글로벌 `~/.claude/` 에 symlink을 만든\n사용자는 한 번 정리:\n\n```bash\nrm -f ~/.claude/skills/{dev,pharos,dispatch-pane} \\\n      ~/.claude/commands/{dev,pharos}.md\n```\n\n이후 글로벌 SKILL은 `claude-config` repo의 `install.sh` 로만 가져온다.\n\n### 하네스 동기화 (앱 관리)\n\n최초 설치(`install.sh`) 이후로는 **GUI 앱이 하네스를 직접 동기화**한다. 실행할 때마다\n`~/.claude`의 CLAUDE.md 블록·skills/hooks/commands 심링크를 repo 소스와 대조해\n버전이 바뀌었으면 자동 재적용한다(마커 안만 건드리고 사용자 콘텐츠는 보존).\n**Settings → Harness**에서 컴포넌트(guidelines/pharos/fable/skills/hooks/commands)를\n개별로 켜고 끌 수 있다. 하네스 업데이트를 받으려고 `install.sh`를 다시 돌릴 필요 없이\n앱만 재시작하면 된다.\n\n## 디자인 레퍼런스\n\nAtlas 핸드오프 (`pharos/project/Pharos Terminal Redesign.html`) 기반. 구현 세부는 [`TODO.md`](./TODO.md)의 \"Atlas 디자인 구현 요약\" 참조.\n\n## 라이선스\n\n내부 프로젝트. 별도 라이선스 파일 없음.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdong-park%2Fpharos","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdong-park%2Fpharos","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdong-park%2Fpharos/lists"}