Desktop Control Default Active
Computer Use 데스크톱 자동화 — get_app_state, click, set_value, 키보드/포인터 액션. 대상에 따라 CDP(브라우저 DOM)와 Computer Use(데스크톱 앱) 사이를 라우팅하는 통합 UI 자동화 스킬입니다.
browser 및 vision-click 스킬을 대체하며, 해당 기능들을 통합 라우팅 시스템으로 흡수합니다.빠른 참조
실행 경로
| 경로 | 조건 | 속도 | 예시 |
|---|---|---|---|
| CDP | 대상이 웹 DOM (페이지 요소, 폼, 버튼) | ~120 ms/액션 | naver.com에서 버튼 클릭 |
| Computer Use | 데스크톱 앱, Chrome 크롬 UI, OS 대화상자, 단축키 | ~1200 ms/액션 | Finder 열기, Cmd+Tab 누르기 |
| CDP + CU | DOM 조회 + 픽셀 클릭 (Canvas, iframe, WebGL) | 가변 | DOM 참조 없는 지도 라벨 클릭 |
액션 클래스
| 클래스 | 계약 | 설명 | 예시 |
|---|---|---|---|
state-read | CU-00 / TX-00 | 현재 UI 상태 읽기 | get_app_state("Finder"), snapshot --interactive |
element-action | CU-01 / TX-01 | 요소 참조로 클릭/상호작용 | click(element_index=730), click e3 |
value-injection | CU-02 / TX-02 | 필드 값 직접 설정 | set_value(element_index=12, value="text") |
keyboard-action | CU-03 | 키 입력 또는 조합 | press_key(key="super+Tab") |
pointer-action | CU-04 | 원시 좌표 클릭 | click(x=812, y=514) |
pointer-action+vision | CU-05 | 비전 기반 좌표 클릭 | "Play 버튼" 비전 조회 후 click(x,y) |
stale-recovery | CU-06 | stale 경고 후 재읽기 | stale 시 get_app_state 재호출 |
secondary-action | CU-10 | 접근성 보조 액션 | perform_secondary_action(el=44, action="AXShowMenu") |
scroll-action | CU-11 | 스크롤 가능한 요소 스크롤 | scroll(element_index=9, direction="down") |
drag-action | CU-12 | 좌표 기반 드래그 | drag(from_x=100, from_y=100, to_x=400, to_y=100) |
인텐트 라우팅
이 스킬은 액션을 수행하기 전에 실행 경로를 결정합니다. 모든 작업의 첫 번째 줄에는 반드시 path=cdp, path=computer-use, 또는 path=cdp+cu를 선언해야 합니다.
결정 테이블
| 대상 | 사용자 인텐트 예시 | 경로 | 액션 클래스 |
|---|---|---|---|
| 웹 페이지 DOM | "네이버에서 foo 검색해줘" | CDP | element-action |
| 웹 페이지 DOM (읽기) | "이 페이지 헤드라인이 뭐야?" | CDP | state-read |
| 데스크톱 앱 창 | "Finder에서 다운로드 열어줘" | CU | element-action |
| Chrome 크롬 UI (비DOM) | "오른쪽 탭으로 전환해줘" | CU | element-action |
| 네이티브 대화상자 입력 | "macOS 대화상자에 입력해줘" | CU | value-injection |
| 전역 단축키 | "Command-Tab 눌러줘" | CU | keyboard-action |
| 임의 픽셀 | "(812, 514) 위치 클릭해줘" | CU | pointer-action |
| Canvas / iframe / WebGL | "Play 버튼 클릭해줘 (DOM 참조 없음)" | CDP+CU | pointer-action+vision |
| DOM 조회 + 포인터 클릭 | "DOM으로 버튼 찾아서 커서로 클릭해줘" | CDP+CU | element-action → pointer-action |
해석 우선순위
- 명시적 선택: 메시지에
$computer-use또는/computer-use가 포함되면 → 즉시 Computer Use 경로. 도구를 사용할 수 없으면precondition failed: computer-use unavailable로 중단. cli-jaw browser snapshot --interactive참조로 대상을 지정할 수 있는가? → CDP.- 비DOM 웹 위젯(Canvas, WebGL, iframe)이
get_app_state스크린샷에 보이는가? → Computer Useclick(x, y). - 대상이 웹페이지 밖(앱 창, 메뉴 바, OS 대화상자)에 있는가? → Computer Use.
- 사용자가 직접 지정한 픽셀 좌표인가? → Computer Use pointer-action.
- DOM으로 위치를 찾아야 하지만 사용자가 실제 커서 클릭을 요구하는가? → Hybrid.
- 앱 이름이 불분명한가? →
get_app_state(app)전에list_apps()호출. - 해당 없음 → 중단 후
needs boss follow-up: ambiguous target보고.
절대 규칙
이 규칙들은 협상 불가입니다. 이 중 하나라도 위반하면 잘못된 트랜스크립트가 생성되거나 액션이 낭비됩니다.
- 액션 전에 경로를 선언하라. 모든 작업의 첫 번째 줄은 반드시
path=cdp,path=computer-use, 또는path=cdp+cu여야 합니다. - 상태 우선 규칙. Computer Use는 항상 각 어시스턴트 턴의 시작에서 상호작용 전에
get_app_state(app)를 호출합니다. stale 경고 시, UI 변경 액션 후, 확신도가 떨어질 때마다 재호출합니다. - 모든 의미 있는 액션은
action_class를 기록한다. 클래스:state-read,element-action,value-injection,keyboard-action,pointer-action,pointer-action+vision. - 무단 폴백 금지. 필요한 경로를 사용할 수 없으면, 중단하고 어떤 전제조건이 실패했는지 보고합니다.
- 커서가 보였다고 주장하지 마라. 현재 빌드에서 커서 오버레이는 최선 노력(best-effort) 방식입니다.
- 불확실할 때는 먼저 스크린샷을 찍어라. 불확실한 상태에서 연속으로 액션을 실행하지 마십시오. 두 개의 연속 액션이 모호한 상태를 생성하면, 다음 호출은 반드시 state-read여야 합니다.
get_app_state(app)를 호출하십시오. 인덱스를 추측하면 무한 수정 루프에 빠집니다. 한 번의 추가 state-read가 항상 한 번의 잘못된 클릭보다 낫습니다.Computer Use 도구 인터페이스
Computer Use 경로는 활성 런타임을 통해 다음 도구들을 노출합니다:
| 도구 | 시그니처 | 용도 |
|---|---|---|
list_apps() | — | 이름을 모를 때 사용 가능한/최근 앱 검색 |
get_app_state | (app) | 세션 시작 또는 갱신; 스크린샷 + 접근성 트리 반환 |
click | (app, element_index) 또는 (app, x, y) | 요소 참조 또는 원시 좌표로 클릭 |
drag | (app, from_x, from_y, to_x, to_y) | 좌표 기반 드래그 |
press_key | (app, key) | 키 또는 조합: Return, Tab, super+c |
scroll | (app, element_index, direction, pages) | 스크롤 가능한 접근성 요소 스크롤 |
set_value | (app, element_index, value) | 편집 가능한 접근성 요소의 값 설정 |
type_text | (app, text) | 현재 포커스에 텍스트 입력 (먼저 포커스를 확인하세요!) |
perform_secondary_action | (app, element_index, action) | 접근성 보조 액션 실행 |
type_text보다 set_value를 우선 사용하세요. type_text(app, text)는 현재 포커스된 곳에 키 입력을 보냅니다 — 최신 상태에서 커서가 의도한 필드에 있음이 증명되지 않으면 취약합니다. set_value(app, element_index, value)는 특정 요소를 대상으로 합니다 — 결정적이고 안정적입니다.CDP 경로 — cli-jaw browser
Chrome DOM으로 접근 가능한 모든 것에 사용: 페이지 텍스트, 폼 필드, 페이지 내 버튼. 웹 콘텐츠에서 Computer Use보다 10배 빠릅니다.
세션 명령어
cli-jaw browser status # 세션이 활성 상태인가?
cli-jaw browser start --agent # 헤드리스 자동화 세션
cli-jaw browser start --headless # 수동 헤드리스 (WSL/CI/Docker)
cli-jaw browser start # 가시 창 (사용자 요청 시에만)
cli-jaw browser navigate "https://example.com" # URL로 이동
cli-jaw browser open "https://example.com" # 새 탭에서 열기
cli-jaw browser tabs # 탭 목록
스냅샷 + 액션
cli-jaw browser snapshot --interactive # 클릭 가능한 요소 목록 (e1, e2, ...)
cli-jaw browser click e3 # 참조로 클릭
cli-jaw browser type e5 "query" --submit # 입력 + Enter
cli-jaw browser press Enter # 폴백 키 입력
cli-jaw browser screenshot # PNG 저장
cli-jaw browser text # 화면 텍스트 덤프
CDP 액션 클래스 매핑
| 명령어 | 액션 클래스 | 계약 |
|---|---|---|
snapshot, text, screenshot | state-read | TX-00 |
click, type ... --submit | element-action | TX-01 |
type <ref> "value" (submit 없이) | value-injection | TX-02 |
press Enter / press Escape | keyboard-action | — |
전제조건
Computer Use 경로
- 플랫폼: macOS 전용.
- 활성 에이전트 런타임이 모든 Computer Use 도구를 노출해야 합니다 (
list_apps,get_app_state,click,drag,press_key,scroll,set_value,type_text,perform_secondary_action). - 제어 앱에 TCC Accessibility 및 AppleEvents 권한이 부여되어야 합니다.
- 패키지 설치에서는 TCC 귀속을 위해
/Applications/Jaw.app및/Applications/Codex Computer Use.app이 필요할 수 있습니다. - 앱 이름을 모르면 먼저
list_apps()를 호출하세요.
CDP 경로
cli-jaw serve가 실행 중이어야 합니다 (cli-jaw browser status로 확인).- 브라우저 세션이 활성 상태여야 합니다 (
cli-jaw browser start --agent로 시작).
precondition failed: <name>을 보고하고 중단합니다. 절대 경로를 무단으로 전환하지 마세요.트랜스크립트 형식
모든 액션은 구조화된 트랜스크립트에 기록됩니다. 보스가 이를 파싱하므로 — path= 줄을 생략하지 마세요.
CDP 트랜스크립트
path=cdp
url=https://example.com
action=click e3
result=ok
Computer Use 트랜스크립트
path=computer-use
app=Google Chrome
action_class=element-action
action=click(element_index=730)
stale_warning=no
result=ok
하이브리드 트랜스크립트
path=cdp+cu
lookup=cli-jaw browser snapshot -> bbox of "Play"
action_class=pointer-action
action=click(x=812, y=514)
result=ok
오류 트랜스크립트
path=computer-use
app=Finder
action_class=element-action
action=click(element_index=34)
stale_warning=yes
result=error: stale element tree
Stale 복구 패턴
stale_warning=yes가 반환되면 요소 트리가 변경된 것입니다. 다음 정확한 순서를 따르세요:
get_app_state(app)— 상태를 재확인하고 대상의 실제 element_index를 확인합니다.action_class=stale-recovery(CU-06)를 한 줄 메모와 함께 기록합니다 (reason=disambiguation).- 새로운 element_index를 사용하여 의도한 액션을 재실행합니다.
- 해당 액션 후
get_app_state(app)를 한 번 더 호출하여 효과를 확인합니다.
# Stale 경고 수신
path=computer-use
app=Google Chrome
action_class=stale-recovery
action=get_app_state("Google Chrome")
stale_warning=no
result=ok (52 elements -- tree changed)
# 새 인덱스로 재시도
path=computer-use
app=Google Chrome
action_class=element-action
action=click(element_index=38) # 같은 대상, 새 인덱스
stale_warning=no
result=ok
Vision-Click 통합
Vision-click은 더 넓은 UI 타겟팅 문제 내의 하나의 특정 전술입니다. 레거시이며, 일반적으로 스크린샷에서의 직접 좌표 클릭으로 대체되었습니다.
결정 순서
cli-jaw browser snapshot --interactive가 참조를 반환했는가? → CDPclick.- Computer Use를 사용할 수 있고 대상이 스크린샷에 보이는가? →
click(x, y)pointer-action 직접 실행 (권장). - 참조 없고 직접 좌표가 부적합 →
cli-jaw browser vision-click(Codex 전용, 레거시).
# CDP vision-click (Chrome 내부, Codex 전용)
cli-jaw browser vision-click "Submit button"
cli-jaw browser vision-click "Play button" --double
# 데스크톱 vision-click (CU-05)
# 1. get_app_state(app)로 스크린샷 캡처
# 2. 비전 모델이 좌표 식별
# 3. Computer Use를 통해 click(x=vx, y=vy)
element_index를 노출하면 그것을 사용하세요.실전 예제: Chrome → Spotify 추적
상태 우선, 요소 타겟팅, stale 복구, CDP 속도 전환을 시연하는 실제 전체 추적 예제입니다.
1. 상태 우선
path=computer-use
app=Google Chrome
action_class=state-read
action=get_app_state("Google Chrome")
stale_warning=no
result=ok (47 elements, focused tab: open.spotify.com)
2. Element-Index 타겟팅 (포커스 의존 입력이 아닌)
# 검색 입력 필드 클릭
path=computer-use
app=Google Chrome
action_class=element-action
action=click(element_index=12)
stale_warning=no
result=ok
# 검색 값을 결정적으로 설정
path=computer-use
app=Google Chrome
action_class=value-injection
action=set_value(element_index=12, value="Daft Punk")
stale_warning=no
result=ok
3. Stale 경고 → 복구
# 검색 결과가 비동기 로드 -- 트리 변경
path=computer-use
app=Google Chrome
action_class=element-action
action=click(element_index=34)
stale_warning=yes
result=error: stale element tree
# 올바른 복구
path=computer-use
app=Google Chrome
action_class=stale-recovery
action=get_app_state("Google Chrome")
result=ok (52 elements -- tree changed)
path=computer-use
app=Google Chrome
action_class=element-action
action=click(element_index=38) # 같은 결과, 새 인덱스
stale_warning=no
result=ok
4. 10배 속도를 위해 CDP로 전환
# 모든 대상이 DOM 노드임을 인식 -- CDP로 전환
path=cdp
url=https://open.spotify.com
action=cli-jaw browser snapshot --interactive
result=ok (ref IDs: e1..e89)
path=cdp
url=https://open.spotify.com
action=click e42 # "Shuffle Play" 버튼
result=ok
일반적인 실패 및 올바른 대응
| 증상 | 올바른 보고 |
|---|---|
| "커서가 안 보여요" | cursor overlay is best-effort in the current build -- action=click(...) succeeded; visible cursor not guaranteed |
| CDP 서버 미실행 | precondition failed: cli-jaw serve not running. Start with 'jaw serve' and retry. |
| Computer Use 도구 누락 | precondition failed: computer-use unavailable |
| cli-jaw CU 앱 누락 (패키지 설치) | precondition failed: /Applications/Codex Computer Use.app missing. Recover: jaw doctor --tcc --fix |
| 액션 시 stale 경고 | get_app_state(app)를 재호출한 후 재시도; stale_warning=yes 기록 |
| 대상에 대한 참조 없음 | 스크린샷에 보이면 Computer Use click(x, y) 사용. 그렇지 않으면 갭 보고. |
| 스냅샷과 클릭 사이 탐색 드리프트 | 스냅샷을 다시 찍고 한 번 재시도; 여전히 어긋나면 보고. |
| CDP 세션이 작업 중 종료 | precondition failed: cdp session terminated |
| 비전 모델이 "일치 없음" 반환 | vision lookup failed for "<query>" -- suggest a more specific description |
| 비GUI 작업이 여기로 라우팅됨 | needs boss follow-up: not GUI automation |
계약 ID 참조
모든 라우팅은 내부 Computer Use 사양에 정의된 기능 계약에 매핑됩니다. 계약 이름이 필요한 경우 트랜스크립트에서 이 ID를 사용하세요.
| 경로 | 계약 | 설명 |
|---|---|---|
| CDP state-read | TX-00 | snapshot/text/screenshot을 통한 페이지 상태 읽기 |
| CDP element-action | TX-01 | DOM 참조로 클릭/입력 |
| CDP value-injection | TX-02 | submit 없이 필드 값 설정 |
| CDP hybrid-lookup | TX-03 | 하이브리드 경로용 DOM 조회 |
| CDP vision-lookup | TX-04 | 비전 기반 좌표 조회 (Codex 전용) |
| CDP error-report | TX-05 | CDP 오류 보고 |
| CU state-read | CU-00 | get_app_state 스크린샷 + 트리 |
| CU element-action | CU-01 | element_index로 클릭 |
| CU value-injection | CU-02 | set_value / type_text |
| CU keyboard-action | CU-03 | press_key 조합 |
| CU pointer-action | CU-04 | 원시 좌표 클릭 |
| CU pointer-action+vision | CU-05 | 비전 기반 좌표 클릭 |
| CU stale-recovery | CU-06 | stale 경고 후 재읽기 |
| CU precondition-fail | CU-07 | 전제조건 실패 보고 |
| CU confirmation-prompt | CU-08 | 파괴적 액션 전 확인 요청 |
| CU transcript-summary | CU-09 | 보스용 사후 액션 요약 |
| CU secondary-action | CU-10 | 접근성 보조 액션 |
| CU scroll-action | CU-11 | 스크롤 가능한 요소 스크롤 |
| CU drag-action | CU-12 | 좌표 기반 드래그 |
"~해줘" 사용 예시
desktop-control 스킬을 트리거하는 자연스러운 한국어 요청입니다. 라우팅 시스템은 한국어와 영어 모두 이해합니다.
"네이버에서 '서울 날씨' 검색해줘"
경로: CDP → naver.com으로 navigate → snapshot --interactive → 검색 필드에 type → 제출 click
"Finder에서 다운로드 폴더 열어줘"
경로: CU → get_app_state("Finder") → 다운로드에서 click(element_index=N) → get_app_state로 확인
"크롬 탭 Gmail로 전환해줘"
경로: CU → get_app_state("Google Chrome") → 접근성 트리에서 Gmail 탭 찾기 → click(element_index=N)
"네이버 지도에서 '스타벅스' 라벨 클릭해줘"
경로: CDP+CU → get_app_state 스크린샷에 라벨이 보이지만 요소 트리에 없음 → 스크린샷 좌표에서 click(x=719, y=388) pointer-action
"시스템 설정에서 다크 모드 켜줘"
경로: CU → list_apps() → get_app_state("System Settings") → 외관으로 이동 → 다크 모드 옵션 click
규칙: 절대 하지 말 것
- "혹시 모르니" 잘못된 경로를 한 번 시도하지 마세요 — TCC 프롬프트를 소모하고 로그를 혼란스럽게 합니다.
- 액션 클래스를 업데이트하지 않고
state-read에서element-action으로 무단 승격하지 마세요. path=줄을 생략하지 마세요. 보스가 이를 파싱합니다.- "페이지를 읽기 위해"
curl/wget을 사용하지 마세요 — 항상 CDP를 사용하세요. - 로그를 확인하기 위해 가시 브라우저 창을 열지 마세요 — Web UI 디버그 콘솔을 사용하세요.
- 참조가 있을 때 좌표 기반 클릭을 시도하지 마세요 — 참조를 사용하세요.
- 커서가 보인다고 가정하지 마세요. 액션 성공/실패만 보고하세요.
- "버튼 위치를 기억하고 있으니"
get_app_state를 건너뛰지 마세요. 요소 인덱스는 상태 변경마다 변합니다. - 이전 액션이 무언가를 변경했다면, 사이에 상태를 재읽기하지 않고 두 개의 Computer Use 액션을 연속 실행하지 마세요.
- 시행착오로 불확실성을 해결하지 마세요. "342를 클릭해보고, 안 되면 357을 시도하지" 같은 것은 금지됩니다 — 스크린샷을 찍으세요.
- 최신 상태에서 포커스가 확인되지 않은 경우 대상 폼 입력의 바로가기로
type_text(app, text)를 사용하지 마세요. - 다른 표현으로 vision-click을 재시도하지 마세요 — 호출당 한 번만 시도하고, 실패 시 보고하고 중단하세요.
관련 스킬
| 스킬 | 관계 |
|---|---|
browser | CDP 명령어 참조 — 이 스킬이 해당 범위를 대체합니다 |
screen-capture | 일반 macOS 스크린샷 / 웹캠 / 비디오 녹화 (변경 없음, 별도 관심사) |
vision-click | 더 이상 자동 활성화되지 않음; 전술로 흡수됨. 저수준 레시피(NDJSON 파싱, DPR 보정)는 cli-jaw skill install vision-click으로 설치 |