macOS 단일 사용자 코딩 에이전트 오케스트레이터입니다. Notion 데이터베이스를 work queue로,
로컬 claude CLI를 멀티 턴 코딩 에이전트로, Telegram을 UI로 사용해
태스크 등록 → 자동 구현 → PR → 리뷰/CI → 머지의 전 흐름을 자동화합니다.
OpenAI Symphony 명세의 layer-neutral 부분(Configuration / Orchestrator / Workspace / Tracker /
Observability)을 그대로 따르고, Codex app-server 자리만
claude --session-id <uuid> / --resume <uuid> 멀티 턴 호출로 대체합니다.
Notion 페이지 = 작업 단위, 페이지 본문 = 첫 turn prompt, Status property = state machine,
Unique ID property = Telegram task_id.
- 멀티 턴 Claude Code 세션 —
--session-id/--resume로 thread 영속,--output-format stream-json을 라인 단위 파싱 - 5가지 continuation 트리거 — Telegram
/continue, Notion 댓글, PR 리뷰 코멘트, CI 실패 자동 재시도, Approval 응답 - Approval 패턴 —
acceptEdits기본, 거부된 명령은 Telegram inline keyboard로 사용자 승인 - 단일 인스턴스 영속성 — launchd LaunchAgent + SQLite 단일 파일, 분산 인프라 없음
- 토큰 격리 — Notion/Telegram/GitHub 토큰은 cymphony 본체에서만 사용.
claudesubprocess에는 일절 노출하지 않음 (호스트 환경 그대로 상속)
- macOS 13 이상
- Go 1.22 이상 (빌드용)
claudeCLI v2.1.80 이상 — 사전에claude명령으로 인증 완료ghCLI — 사전에gh auth login완료- SQLite 라이브러리는 pure Go 드라이버(
modernc.org/sqlite)로 처리하므로 별도 시스템 라이브러리 불필요
새 데이터베이스를 만들고 다음 property를 설정합니다.
| Property | Type | 비고 |
|---|---|---|
| Title | Title | 작업 제목 |
| ID | Unique ID | prefix TASK 권장. Telegram에서 /continue 42 형태로 호출 |
| Status | Select | Backlog / Todo / In Progress / Awaiting User / In Review / CI Failed / Approved / Done / Blocked / Cancelled |
| Repo | Text | owner/repo 형식 |
| Branch | Text | cymphony가 자동 채움 |
| PR URL | URL | cymphony가 자동 채움 |
| Assignee | Select | agent / me 등. cymphony는 Assignee = agent만 픽업 |
| Priority | Select | High / Medium / Low |
| Time Limit | Number | 작업당 최대 실행 시간 (분). 기본 30 |
| Session ID | Text | cymphony가 자동 채움 (Claude --session-id UUID) |
| Turn Count | Number | cymphony가 turn 종료마다 증분 |
In Progress / Awaiting User / In Review / CI Failed 같은 cymphony 내부 상태는
사용자가 Notion에서 직접 변경하지 않는 것을 권장합니다.
Notion Internal Integration을 만들고 데이터베이스 페이지에서 Connect → 통합 추가로 연결한 뒤,
발급된 API key를 아래 §3의 config.yaml의 secrets: 섹션에 적습니다.
@BotFather에서/newbot으로 봇 생성 → bot token 확보- 봇과 직접 채팅 시작 (아무 메시지나 한 번 보냄)
https://api.telegram.org/bot<TOKEN>/getUpdates를 브라우저로 열어chat.id확인
sudo mkdir -p /usr/local/etc/cymphony
sudo chown "$USER" /usr/local/etc/cymphony
chmod 700 /usr/local/etc/cymphony비밀 정보는 별도 파일이 아니라 §6에서 만들 config.yaml의 secrets: 섹션에 적습니다.
GitHub PAT은 별도 저장하지 않습니다 — gh CLI 호스트 인증을 그대로 사용합니다.
sudo mkdir -p /usr/local/var/cymphony/{workspaces,logs}
sudo chown -R "$USER" /usr/local/var/cymphonymake build
sudo make install # /usr/local/bin/cymphony 로 복사
make install-launchd # ~/Library/LaunchAgents/com.cymphony.agent.plist 등록 + loadcp config.example.yaml /usr/local/etc/cymphony/config.yaml
chmod 600 /usr/local/etc/cymphony/config.yaml # 비밀 정보가 들어 있으니 필수
$EDITOR /usr/local/etc/cymphony/config.yamlsecrets: 섹션에 Notion API key / database ID, Telegram bot token / chat ID를
채워 넣습니다. 설정 키 전체와 기본값은 config.example.yaml 참조.
launchctl start com.cymphony.agent
tail -f /usr/local/var/cymphony/logs/cymphony.log이후 Notion 데이터베이스에 Status = Todo, Assignee = agent 페이지를 만들면 폴링 주기 안에 픽업됩니다.
/status— 진행 중 작업 목록 (NotionTASK-NID로 표시)/new <title>— 모바일에서 즉석 태스크 생성 (StatusTodo로 등록)/continue <task_id> <message>— 진행 중 작업에 추가 지시 (continuation turn 트리거)/cancel <task_id>— 진행 중 작업 취소 (StatusCancelled로 전이)/logs <task_id>— 가장 최근 turn 로그의 마지막 N줄
task_id는 Notion Unique ID property 값입니다 (예: TASK-42 또는 prefix를 안 쓸 경우 42).
PR 생성, Approval 요청, CI 실패 등에는 inline keyboard 버튼으로 응답합니다.
/usr/local/bin/cymphony 바이너리
/usr/local/etc/cymphony/
└── config.yaml 설정 + secrets: 섹션 (chmod 600 필수)
/usr/local/var/cymphony/
├── workspaces/<page-id>/ per-task git clone
├── logs/cymphony.log 메인 launchd stdout/stderr
├── logs/<page-id>/<turn-index>.jsonl turn별 stream-json 원본
└── cymphony.db SQLite 영속성 (단일 파일)
~/Library/LaunchAgents/
└── com.cymphony.agent.plist LaunchAgent
- docs/ARCHITECTURE.md — 시스템 구성, layer 분리, 데이터 흐름, Symphony SPEC ↔ cymphony 매핑, 멀티 턴 라이프사이클
- docs/WORKFLOW.md — Claude에게 주입되는 작업 규약 (브랜치 / 커밋 / PR 본문 / 절대 금지)
- config.example.yaml — 설정 키 전체와 기본값
- 로그는 launchd가
StandardOutPath/StandardErrorPath로 redirect합니다. 수동 재시작은launchctl kickstart -k gui/$(id -u)/com.cymphony.agent. Time Limit초과 시 cymphony가 SIGTERM → 30초 grace → SIGKILL 순으로 subprocess를 종료합니다.- 워크스페이스 GC는 매일 04:00에 동작하며
workspace_retention_days(기본 7일) 지난 디렉토리만 삭제합니다. claudesubprocess가 거부한 명령은 turn 결과로 surface되어 Telegram 승인 절차를 거칩니다 —bypassPermissions모드로 강제 통과시키지 않는 것을 권장.