작업, 범위, worktree
st task와 --deps로 순서를 지키는 법, --owns로 워커가 고칠 수 있는 범위를 정하는 법, --worktree로 워커마다 git worktree를 주는 법, --fan으로 같은 과제를 여러 워커에게 주고 하나를 고르는 법을 다룹니다.
워커 여럿이 함께 일하려면 무엇을 먼저 할지, 누가 어느 파일을 고칠지 두 가지를 정해야 합니다. st가 둘 다 기억하므로 코디네이터가 머릿속에 담아 둘 필요가 없습니다. 보통은 "스키마 먼저, 그다음 API, 그다음 UI. 서로 남의 폴더는 건드리지 말고"처럼 말만 하면 코디네이터가 아래 명령을 실행합니다.
순서가 있는 일 (st task)
어떤 일은 다른 일이 끝나야 시작할 수 있습니다. 그 순서를 st에 적어 두면 st가 순서를 지킵니다. st 0.3.82 이상에서 됩니다.
st task create schema --task schema.md --agent codex --owns "db/**"
st task create api --task api.md --agent claude --deps schema --owns "internal/api/**"
st task create ui --task ui.md --agent claude --deps api,schema --owns "web/**"
st task list # 작업마다 지금 상태
st task start schema # 앞 작업(--deps)이 안 끝났으면 거절합니다
st task wait # 다음 작업을 시작할 수 있게 되면 돌아옵니다st task create <이름> --task <파일|->는--deps a,b,--agent claude|codex|opencode|pi,--owns,--worktree를 받습니다. 이 설정은 그 작업을 맡는 워커에게 그대로 넘어갑니다.--deps에는 이미 만든 작업만 쓸 수 있습니다. 그래서 작업끼리 서로를 기다리는 고리가 생기지 않습니다.st task start <이름>은 작업을 새 워커에게 맡깁니다.st worker start와 마찬가지로--agent(작업에 정해 둔 에이전트가 없을 때),--split,--cwd를 받습니다.st task list --ready는 지금 시작할 수 있는 작업만 보여 줍니다.
작업은 다음 다섯 상태 가운데 하나에 있습니다.
| 상태 | 뜻 |
|---|---|
waiting | 먼저 끝나야 할 작업이 아직 안 끝남 |
ready | 시작할 수 있음 |
running | 워커가 맡아 하는 중 |
done | 워커가 끝났다고 보고함 |
blocked | 워커가 blocked:로 보고함. 이 작업 뒤에 오는 작업은 계속 기다립니다 |
st task wait의 종료 코드는 다음과 같습니다.
| 코드 | 언제 |
|---|---|
| 0 | 시작할 수 있는 작업이 생겼거나 모두 끝남 |
| 3 | 워커가 묻는 중 |
| 4 | 막힌 작업 때문에 더 진행할 수 있는 작업이 없음 |
| 2 | 시간 초과(--timeout, 기본 15분) |
코디네이터는 모든 작업이 끝날 때까지 st task wait와 st task start를 되풀이합니다.
워커가 고칠 수 있는 범위 (--owns)
워커들은 기본적으로 같은 폴더에서 일합니다. 두 워커가 같은 파일을 동시에 고치면 서로 덮어씁니다. 워커마다 고칠 수 있는 경로를 정해 두면 st가 그 밖의 수정을 일어나기 전에 막습니다. git worktree가 없어도 되고, git을 쓰지 않는 프로젝트에서도 됩니다. st 0.3.82 이상에서 됩니다.
st worker start --agent claude --task auth.md --owns "src/auth/**,docs/auth.md"
st worker own %15 "web/**" # 이미 실행 중인 워커(데려온 워커 포함)
st worker own %15 --clear # 범위 풀기- 경로는 쉼표로 구분합니다. 워커의 폴더를 기준으로 한 상대 경로나 절대 경로를 씁니다.
*는 한 폴더 안에서만,**는 하위 폴더까지 맞고,?는 한 글자에 맞습니다. 와일드카드가 없는 경로는 그 파일 하나, 또는 그 폴더 아래 전부를 뜻합니다. - Claude 워커가 범위 밖의 파일을 Edit나 Write로 고치려 하면, 고치기 전에 훅이 거절하고 이유를 알려 줍니다. 워커는 이를 우회하지 않고, 무엇을 고쳐야 했는지 답에 적어 코디네이터에게 묻습니다.
- 워커의 폴더 밖에 있는 파일(임시 파일 등)은 막지 않습니다.
- 셸 명령으로 쓰는 파일과 Codex 워커는 아직 검사하지 않습니다. 과제 파일에도 범위를 적어 두세요.
워커마다 자기 worktree (--worktree)
워커마다 따로 worktree와 브랜치를 줄 수 있습니다. 그러면 파일도, 빌드와 테스트도 다른 워커와 섞이지 않습니다. st 0.3.83 이상에서 되고, git이 없는 폴더에서는 st 0.3.107 이상에서 됩니다(아래 참고).
st worker start --agent claude --task api.md --worktree
st task create api --task api.md --deps schema --worktree
st worker diff %15 [--stat] # 바꾼 것(커밋했든 안 했든)
st worker merge %15 [--commit] # 그 브랜치를 지금 checkout으로 병합
st worker clean %15 # 병합한 뒤 worktree와 브랜치 지우기- 브랜치 이름은
st/<실행>/<이름>이고, 코디네이터의 checkout이 가리키던 커밋에서 시작합니다. worktree는 저장소 밖~/.sophonz/worktrees/에 만들어지고, 워커는 코디네이터가 있던 것과 같은 하위 폴더에서 일합니다. - git이 관리하지 않지만 worktree에 필요한 파일(
.env.local등)은 저장소 맨 위의.worktreeinclude에 패턴을 한 줄에 하나씩 적어 두면 복사됩니다. - 커밋하지 않은 변경은 병합되지 않습니다. 워커에게 커밋하라고 하거나,
--commit을 붙여 있는 그대로 커밋합니다.--squash는 브랜치를 변경 하나로 묶어 스테이징까지만 하고, 커밋은 직접 하도록 남겨 둡니다. - 충돌이 나면 아무것도 병합하지 않습니다. st가 병합을 되돌리고 충돌한 파일을 알려 줍니다. 그 워커에게 "main을 네 브랜치에 병합하고 충돌을 풀어서 커밋해" 같은 말을 보낸 뒤 다시 병합합니다.
st worker trees는 이 장치의 모든 worktree를 id(<실행>/<워커>)로 보여 줍니다. 워커가 끝났거나 사라진 것도 나옵니다.diff,merge,clean도 그 id를 받습니다.st worker ask <id|tree> ["<질문>"]은 그 worktree에서 읽기 전용 에이전트를 자기 창에 띄우고, 바뀐 내용을 첫 프롬프트에 넣어 물어볼 수 있게 합니다. 워커 자신에게 묻는 것이 아닙니다.- git이 없는 폴더도 worktree를 받습니다. st가 그 폴더를
~/.sophonz/shadow/에 있는 자기 저장소로 스냅숏을 떠서 그것으로 worktree를 만듭니다. 폴더 안에는 아무것도 쓰지 않습니다. 그 폴더의.gitignore가 빼는 것과 의존성·빌드 산출물(node_modules/,target/,dist/등)은 빠집니다. 파일이 20,000개나 2 GB를 넘으면 그 수치를 보여 주며 거절하고,--any-size를 붙이면 진행합니다. 스냅숏은 그것으로 만든 마지막 worktree와 함께 지워집니다. st worker clean은 커밋하지 않았거나 병합하지 않은 변경이 있으면 거절합니다.--force를 주면 그래도 지우고,--keep-branch를 주면 브랜치는 남깁니다.
여러 번 시도해 하나 고르기 (--fan)
설계 방향이나 까다로운 버그처럼 답이 뻔하지 않은 일은, 같은 과제를 여러 워커에게 동시에 주고(--fan) 결과를 비교해 하나를 고를 수 있습니다. st 0.3.84 이상에서 됩니다.
st worker start --fan 3 --agent claude,codex --task fix.md # 워커마다 자기 worktree
st worker fan # 나란히: 각자 무엇을 얼마나 바꿨는지, 끝났는지
st worker pick %15 # 그것을 병합하고 나머지 창과 worktree는 정리--fan에는 2에서 8까지 줄 수 있습니다. 워커는 모두 같은 커밋에서 시작하고, 각자 자기 worktree에서 일합니다.--agent에 여러 개를 주면 차례로 돌아가며 씁니다.st worker fan [<id>]은 같은 과제를 받은 워커들을 묶어서, 워커마다 얼마나 바꿨는지, 커밋하지 않은 변경이 남았는지, 요약은 무엇인지 보여 줍니다.st worker pick <id>는--commit(남은 변경을 먼저 커밋)과--keep(병합만 하고 나머지 워커는 남겨 두기)을 받습니다. 충돌이 나면 아무것도 병합하지 않고 아무것도 지우지 않습니다.- 화면에서 골라도 됩니다. 데스크탑 앱에서는 에이전트 그래프에서 워커를 선택하고
Changes를 누르고, 웹 터미널에서는 사이드바의 워커 창에 붙은Δ를 누릅니다. 그러면 diff와 같은 과제를 받은 다른 워커들이 나란히 나오고,Use this one으로 고릅니다. - worktree가 있는 워커를 하나만 띄웠을 때도 같은 화면이 나오고, 거기서
Merge할 수 있습니다. --machine <장치>를 함께 주면 같은 과제를 받는 워커가 모두 그 장치에서 뜹니다.st worker pick과diff는 아직 이 장치의 워커만 받습니다.
전체 플래그는 st 명령 레퍼런스에 있습니다.