tfx-live
Skill7 starsChanged 13 days agoMITView on GitHub
Claude·Codex·agy 세션을 실시간으로 생성·질의·대기·압축·종료하거나, tmux/daemon UDS 연결과 peer 중계를 운영할 때 사용한다.
In this repository12 other files it gives its agents.
- AGENTS.mdAGENTS.md
- CLAUDE.mdCLAUDE.md
- tfx-autoSkill
- tfx-doctorSkill
- tfx-harnessSkill
- tfx-leadSkill
- tfx-remoteSkill
- tfx-researchSkill
- tfx-reviewSkill
- tfx-setupSkill
- tfx-shipSkill
- tfx-wtSkill
The file
Files
tfx-live
tfx-live는 Claude Code와 Codex 세션을 tmux 또는 daemon UDS로, agy 세션을 로컬 tmux로 제어한다.
tfx-live --help와 tfx-live <동사> --help로 사용법을 확인한다.
전송 경로
- Claude
--short또는--session-id는 기본auto로 UDS를 먼저 시도한다.--session이 있고 입력 미전송이 확인된 UDS 실패라면 tmux로 전환하고~/.claude/cache/triflux/tfx-live/bug-reports/uds-fallback-*.json을 남긴다. 컨텍스트 가드 거부 시에는 전환하지 않는다. - Codex
ask는 Codex 큐(app-serverthread/queue/add)가 기본이다. 아래 "Codex ask 메시지 전송" 순서를 따른다. 기존 Codex thread의 UDS 연결은--transport uds --thread <id|auto>를 명시한다. - daemon 참조가 없는 Claude는 tmux가 기본이다.
- 어댑터가 설치된 로컬 Claude, Codex, agy 대상은 native 피어를 먼저 쓴다. Claude끼리는
SendMessage(to: "<이름>"), 그 밖의 로컬 Claude, Codex, agy 대상은<홈 절대경로>/.claude/scripts/tfx-peer send --to '<cli>:<정확한 이름>' --message '<본문>'을 쓴다. native 전송 실패는 그대로 반환하며 tmux 입력으로 전환하지 않는다. 어댑터 미설치 폴백은 없다. - Claude 대상의 SendMessage 이름은
tfx-live list-sessions --cli claude결과의name이다.start직후의 첫 지시도 결과의sendMessageTo로 보낸다. 이름을 못 찾으면 실패를 확인하고 이름을 다시 찾는다. 로컬 Claude끼리ask하면reason: "use-send-message"와sendMessageTo를 반환한다. 원격 세션은tfx-live ask로 보낸다. - 같은 기기의 agy 끼리는
~/.local/bin/agy.patch.json의sha256이 실제agy바이너리 해시와 같고patches에peer-wake가 있을 때만tfx-peer send --to 'agy:<이름>'또는send_message(대화 ID)를 쓰고, 아니면tfx-live ask를 쓴다(쉬는 세션이 깨지 않는 공개 이슈 #1022 때문). 첫 입력 전 새 agy 세션은conversationId가 없으므로 첫 지시는tfx-live ask --cli agy --session <세션> --prompt '<본문>' --no-wait로 보내고 대화 ID가 생긴 뒤부터 native 피어를 쓴다.tfx-live send --via-tmux의 agy 대상 전송은 tmux 경로를 유지한다. tfx-live send는 로컬 Claude, Codex, agy 대상에 기본으로reason: "use-tfx-peer"를 돌려주고tfx-peer send로 안내한다.--via-tmux를 붙일 때만 tmux 경로로 보내며 본문 첫 줄에[tfx-peer from=<cli>:<보낸 이름> msg=<id>], 끝에 발신 CLI에 맞는 회신 안내를 붙인다. 원격은 지원하지 않는다.- Claude의
SendMessage에서to: "codex:<이름>",to: "agy:<이름>",to: "antigravity:<이름>"은 mods가 native 피어 경로(tfx-peer send)로 전달한다. - UDS 결과는
matchedCompletion === true일 때만done: true다. timeout이나 연결 종료는 완료가 아니다. - bridge 선택 순서는
--bridge,$TFX_BRIDGE,$TFX_REPO_ROOT/hub/bridge.mjs, 번들된hub/bridge.mjs다.
tfx-live start --cli codex --session cx1 --cwd ~/Projects --name "10.8 구현 검토"
"$HOME/.claude/scripts/tfx-peer" send --to 'codex:10.8 구현 검토' --message '현재 변경사항을 요약해줘'
"$HOME/.claude/scripts/tfx-peer" send --to 'agy:10.8 구현' --message '추가 검토 사항을 반영해줘'
tfx-live stop --cli codex --session cx1macOS의 iTerm2에서 로컬 tmux start는 프로젝트별 창에 attach 탭이나 pane을 자동 배치한다. LC_TERMINAL=iTerm2 또는 TERM_PROGRAM=iTerm.app일 때만 적용하며 원격·headless 경로는 유지한다. 프로젝트 키는 git 공통 디렉터리의 실제 경로이므로 같은 저장소의 worktree는 함께 묶이고, git 밖에서는 cwd의 실제 경로를 쓴다. 기존 소유 프로젝트 창, 로컬 리드 창 순으로 찾고 리드 ID가 없으면 현재 focus session의 창을 읽기 전용 anchor로 쓴다. 기본 preserve에서는 새 창을 만들지 않는다. 기본 그룹은 프로젝트 키이며 --group NAME으로 바꾼다. peer는 실행마다 참여자들을 한 그룹에 모으며 --group을 주면 그 값을 쓴다. 제목은 --name, 자동 이름, 세션 이름 순이며 새 pane의 custom command를 꺼 이후 Cmd+D가 같은 tmux에 중복 attach하지 않게 한다. stop은 registry와 소유 표식이 일치하는 ID만 닫는다. 기존 AppleScript 경로에서도 같은 TFX 세션 표식이 없는 사용자 view는 닫지 않는다. 연동 실패는 시작·종료를 막지 않고 itermWarning에 남긴다.
새 세션 이름은 <월>.<일> <주제>로 짓는다. start --name을 생략하면 자동으로 만들고 nameGenerated: true를 보고한다. --resume 또는 --resume-last는 --name을 명시한 경우에만 이름을 적용한다. 승계 세션에는 기존 이름 뒤에 2, 이후 3을 붙인다. 이름 적용을 요청한 경우 결과의 nameApplied: false는 미적용을 뜻한다. agy의 namePending: true는 첫 일반 ask에서 적용할 이름이 보류됐다는 뜻이다. Codex start는 /rename 제출을 입력창이 빌 때까지 확인하고, 이름으로 찾은 thread UUID를 threadId로 돌려주며 tmux 세션 옵션 @tfx_codex_thread에 남긴다. 로컬 Codex --resume-last는 Codex가 고른 thread를 사후에 찾는다. 띄운 뒤 공유 app-server daemon에 로드된 같은 cwd의 thread 중 rollout에 그 시각 이후의 resume 기록(thread_settings_applied)이 생긴 것이 정확히 하나이고 1.5초 뒤에도 같을 때만 threadId로 쓴다. 이 확인은 5초 안에 끝난다. TUI가 daemon을 쓰지 않거나 같은 cwd에서 동시에 resume이 일어나면 null이다. 기존 Codex UDS thread는 tfx-live rename --cli codex --transport uds --thread ID --name "<이름>"으로 이름을 바꾼다.
Claude 프로젝트 MCP 승인 화면이 뜨면 start는 화면에 답하지 않고 ready: false, blockedBy: "claude-mcp-approval", 할 일을 적은 warning을 반환한다. 세션은 남아 있으므로 tmux 세션에 붙어 직접 고른 뒤 지시를 보낸다. Codex 훅 검토 화면도 선택 항목과 관계없이 키를 보내지 않고 ready: false, blockedBy: "codex-hooks-review"와 trust를 자동 승인하지 않았다는 warning을 반환한다. --resume, --resume-last, 명시 launcher와 --remote에서도 세션을 남기므로 attach 후 훅을 직접 검토한다.
Claude, agy, Codex(Trust this folder?와 Do you trust the contents of this directory)의 폴더 신뢰 화면은 기본으로 자동 승인한다. Codex는 신뢰 결정을 설정에 기록하므로 이후 같은 폴더의 실행에도 적용된다. start --no-auto-trust를 주면 이 화면에도 키를 보내지 않고 같은 형식으로 blockedBy(claude-trust-folder, agy-trust-folder, codex-trust-folder)를 반환한다. --resume, --resume-last, --remote에도 똑같이 적용된다.
Codex start --model은 astra, sol, terra, luna 가족 별칭을 호출 호스트의 기존 model-family-resolver로 실제 모델 ID로 바꾼다. 호출 호스트의 ~/.config/triflux/models.json 가족 고정값을 우선하고, Codex 모델 캐시, 마지막 해석 결과, 내장 기본값 순으로 고른다. --remote도 호출 호스트에서 해석한 ID를 보내며 원격 호스트의 고정값은 사용하지 않는다. 실제 모델 ID를 명시하면 그대로 전달한다. 모델 해석은 전역 프로필이나 설정 파일을 바꾸지 않고 --effort는 별도로 전달한다.
로컬 Codex 새 thread는 생성 RPC에 approvalPolicy: "never", sandbox: "danger-full-access"를 명시한다. start --sandbox를 주면 승인 정책은 on-request, sandbox는 workspace-write로 제한한다. 재개할 때 --sandbox를 생략하면 기존 thread 권한을 보존한다. remote TUI resume은 권한 CLI 플래그를 거부하므로 attach 명령에 bypass나 sandbox 플래그를 추가하지 않는다.
Codex 관리 plain/new/resume/resume-last TUI 명령과 tfx-route exec/review 워커는 공식 --dangerously-bypass-hook-trust가 기본이다. 해당 invocation만 대상으로 하며 일반 codex 명령, 전역 config, 저장된 훅 신뢰 기록은 바꾸지 않는다. 활성 훅은 사전 확인 없이 샌드박스 밖에서 실행될 수 있다. 기존 features.hooks=false와 sandbox/approval 정책은 유지하고, --sandbox만으로 hook-trust bypass를 끄지는 않는다.
관리 기본값을 끄려면 tfx-live start --cli codex --session NAME --no-bypass-hook-trust 또는 tfx lead ROLE --cli codex --no-bypass-hook-trust를 쓴다. 실행 환경의 TFX_CODEX_BYPASS_HOOK_TRUST=0은 route 워커와 live/lead에 공통 적용된다. 미설정과 그 외 값은 켬이며 CLI opt-out은 환경 값 1보다 우선한다. 사용자 launcher 내부와 명시 플래그는 재작성하지 않는다. remote-spawn은 Claude 진입이고, 내부 Codex는 해당 호스트의 tfx-route 정책을 따른다. tx 같은 셸 래퍼가 내부에서 같은 플래그를 추가한다면 --no-bypass-hook-trust로 TFX 관리 추가를 끈다.
공유 daemon의 prepared-thread TUI attach에는 관리 hook-trust bypass 플래그를 제외한다. CLI가 플래그를 수락해도 daemon에 실제 적용된다는 근거는 없으므로 features.hooks=false RPC와 ready: false, blockedBy: "codex-hooks-review" 폴백을 유지한다. bypass_hook_trust나 camelCase RPC/config 필드를 합성하지 않는다. 기본/opt-out과 관계없이 시작 훅 검토 화면에는 메뉴 키, rename, 업무 입력을 보내지 않고 세션을 남긴다. tmux 세션에 attach해 훅을 직접 검토한 뒤 진행한다. builtin 훅과 legacy notify는 일반 사용자·플러그인 훅 비활성화 보장에서 제외한다.
로컬 daemon start 결과의 approvalPolicy, sandbox는 TUI attach 뒤 같은 thread에 설정 덮어쓰기 없이 보낸 thread/resume 응답이다. 요청의 sandbox는 danger-full-access, workspace-write 형식이고 응답의 sandbox.type은 dangerFullAccess, workspaceWrite 형식이다. permissionsVerified는 daemon 설정이 준비한 권한과 일치하는지 나타낸다. 응답 실패나 필드 누락, 다른 thread 응답은 권한 값을 null로 보고한다. 권한 불일치는 읽은 값을 그대로 보고한다. 두 경우 모두 ready: false, permissionWarning을 반환하고 세션은 남긴다. 이 readback은 다음 TUI 턴의 실제 도구 실행까지 확인한 결과는 아니다.
공유 daemon에 이미 로드된 Codex thread는 per-thread hooks override를 지원하지 않아 start --resume을 거부하고 기존 설정을 보존한다. 기존 TUI에서 진행 중인 턴이 끝난 뒤 /permissions를 입력하고 Full Access를 선택해 확인한다. pane을 닫았다면 오류에 나온 codex resume <threadId>는 운영자가 같은 history를 다시 여는 수동 복구 명령이다. 같은 cwd에서 열고 /permissions를 다시 선택한다. 이 명령을 에이전트가 직접 실행하는 권한은 아니다. 아직 loaded 상태면 tfx-live start --resume은 다시 거부되므로 반복하지 않는다. thread/settings/update readback만으로 다음 TUI 턴 권한이 적용됐다고 판단하지 않는다. 새 thread를 만들거나 공유 daemon을 재시작하지 않는다.
창 배치(macOS)
호출자가 매번 배치를 결정할 필요는 없다. Jev는 작업·역할·사람 입력 가능성과 기존 워커의 작업·worktree, window/tab/session ID·cols/rows·관리 태그로 만든 후보 ID만 고른다. 사용자 채팅 초안, 터미널 출력, 키 입력 본문은 읽거나 전송하지 않는다. 비활성·장애·낮은 신뢰도·잘못된 ID는 이유가 있는 규칙 폴백이다.
- 기본 focus preserve는 현재 window/tab/session과 다른 앱의 입력 대상을 유지한다. 각 창의 선택 탭 전체를 split/reconcile spec에서 제외하고 비활성 non-tmux 탭만 조작한다. 새 탭은
select=False로 만들며 생성 후 focus 복원에 의존하지 않는다. 명시start --focus또는tfx lead ... --focus만 목적 있는 전환을 허용한다. 중요 역할은attention으로 표시하고 자동 focus를 요청하지 않는다. - 최소 가독성은 human/lead/communication 100 cols × 24 rows, standard 80 × 20, low-human compact 60 × 10이다. 가용 크기가 작으면 추가 분할 대신 독립 비활성 탭을 쓰고, 창 자체도 작으면
verified: false로 보고한다. start --task '<요약>'과 lead의--task를 전달한다. 이름만 있으면taskInformation: insufficient이고 background 자동 후보를 주지 않는다. 실제 task나 명시--human low/--background가 있을 때만 background 후보를 허용하며 lead/high-human/communication은 자동으로 숨기지 않는다.- 명시
--layout tab|window|split-vertical|split-horizontal|background|off|legacy에서도 preserve가 우선이다. 안전한 split이 없거나 window가 요청되면 비활성 탭 또는 background로 폴백하고 이유를 반환한다.--background,--no-auto-layout,--layout off,TFX_ITERM_LAYOUT=0은 UI 없이 tmux를 유지한다. legacy 생성은--layout legacy --focus일 때만 허용한다.TFX_ITERM_WATCH=0은 watcher만 끈다. - 설치된 iTerm Python runtime/API를 재사용한다.
TFX_ITERM_PYTHON으로 경로를 지정할 수 있다. 없거나 연결이 실패하면 경고와 attach 가능한 background로 남기고 UI를 생성하지 않는다.inspect의background항목에 작업 정보·결정·attach 명령을 포함하며nativeSessionId: null로 native view registry와 구분한다. 기존list-sessions --cli <종류>와tmux attach-session -t '=세션'으로 찾는다. registry의runtimeState: not_checked는 실행 상태를 확인하지 않았다는 뜻이다. - 프로젝트·호스트별 단일 watcher는 종료·이동·resize를 debounce한다. 모든 프로젝트는 같은 host의 전역 mutation lock 다음 프로젝트 lock 순서로 잠그고 대기 뒤 inventory를 다시 읽는다. watcher의 state 읽기·pin 저장도 같은 lock을 쓴다. 수동 이동 pin은 state에 유지하며
reconcile --reset-pins로만 해제한다.--dry-run은 pin을 해제하지 않는다. 사람이 옮긴 pane을 다른 탭과 임의로 합치지 않는다. - 일반 셸/다른 프로젝트가 섞인 탭, tmux integration tab, 선택 탭, 명시 배치 탭은 재배치하지 않는다. 과밀한 관리 탭의 자동 분리도 비활성 탭을 사용한다. 자기 적용 결과는 fingerprint와 새 기준 위치로 흡수하며 관리 view가 없으면 watcher는 종료한다.
tfx-live inspect --cwd '<경로>',tfx-live reconcile --dry-run --cwd '<경로>'은 계획을 반환한다. 실제 적용은tfx-live reconcile --cwd '<경로>'이다.decision,applied,verified는 각각 판단·UI 적용·실측이다.focus.requested/effective/transitioned/reason은 요청·유효 정책·전환 여부·미적용 이유를 구분한다. 부분 실패는 실제 inventory를 포함하고 자동 UI 재생성을 하지 않는다. watcher의 마지막 JSON은 사용자별 private temp의iterm-layout/*.last.json에 있다.
agy 세션
tfx-live start --cli agy --session ag1 --cwd ~/Projects --name "10.11 구현 검토" --effort low --unset-env 'TOSSINVEST_*,PRIVATE_KEY'
tfx-live ask --cli agy --session ag1 --prompt "현재 변경사항을 요약해줘" --no-wait
tfx-live wait --cli agy --session ag1 --request-id <requestId> --timeout 120
tfx-live list-sessions --cli agy --cwd ~/Projects
tfx-live stop --cli agy --session ag1start는 --model ID, --effort low|medium|high|xhigh|max, --sandbox를 agy에 넘긴다. --sandbox의 실효는 미검증이다. --resume ID와 --resume-last 1로 대화를 재개한다. 준비 뒤 /rename <이름>의 확인 문구가 보이면 nameApplied: true다. 새 대화는 첫 메시지 전 /rename이 실패하므로 이름을 tmux 옵션 @tfx_agy_name에 남기고 nameApplied: false, namePending: true로 보류한다. 첫 일반 ask는 제출 확인 뒤 현재 대화 DB에 사용자 step이 생길 때까지 최대 5초 기다리고, 유휴를 기다리지 않고 /rename을 보낸다. 확인 문구가 보이면 옵션을 지우고 nameApplied: true를 반환하며, 실패하면 옵션을 남기고 nameApplied: false를 반환한다. --no-wait에도 적용한다. 열린 presence lock에서 찾은 대화 ID는 conversationId로 보고한다.
agy ask의 기본 --if-busy queue는 바쁜 턴에도 바로 전송한다. agy 자체 대기열에 쌓이며 앞 입력을 덮어쓰지 않는다. wait|fail|interrupt도 선택할 수 있다. ask --no-wait는 inputSent: true, requestId와 함께 유휴 시 status: "submitted", 바쁠 때 status: "queued"를 반환한다. queue 정책은 agy 전용이다. 슬래시 명령은 중계 표식 없이 보내고 바빠도 즉시 실행한다. DB step을 만들지 않아 wait로 추적하지 않으며, --no-wait 여부와 무관하게 제출 확인 뒤 status: "submitted", slashCommand: true로 반환한다. /clear는 대화 ID를 바꾼다.
wait는 node:sqlite(Node 22.13+)로 대화 DB의 사용자 입력 표식과 뒤따르는 step 상태를 읽는다. 요청 뒤부터 다음 사용자 입력 전까지 모델 응답 step이 하나 이상 있고 그 구간의 모든 step이 끝났으며, pane이 유휴 상태이거나 다음 요청이 시작됐으면 완료다. 같은 구간의 마지막 비어 있지 않은 모델 텍스트를 응답으로 쓴다. Escape로 취소된 step도 완료 상태로 기록된다. 네트워크 오류처럼 턴이 오류 step으로 끝나고 모델 응답이 뒤따르지 않으면 status: "failed"와 화면 문구 error를 반환한다. agy는 이 오류에서 스스로 재시도하지 않으므로 같은 요청을 다시 보낸다. --timeout 0은 한 번만 확인한다. /clear는 대화 ID를 바꾸며 진행 중 wait는 처음 연 DB를 계속 본다. agy 설정의 toolPermission에 따라 도구 승인 화면이 뜰 수 있다. 승인을 기다리는 동안 턴이 멈추고 wait는 working으로 남는다. tfx-live는 agy에 --dangerously-skip-permissions를 쓰지 않는다. agy에는 compact가 없으므로 /clear 또는 handoff를 쓴다. peer relay는 로컬에서만 지원한다. --remote, converse, goal-driven은 지원하지 않는다.
start --unset-env 'PREFIX_*,EXACT_NAME'은 모든 CLI에 쓸 수 있다. 쉼표로 구분한 환경변수 이름과 끝의 *로 지정한 접두만 허용한다. tmux pane 셸의 환경에서 변수를 지우고 CLI를 실행하며 resume에도 적용한다. 로컬에서는 준비 후 CLI 프로세스 환경을 확인한다. macOS는 ps -E 출력에 PATH=가 있고 Linux는 /proc/PID/environ이 비어 있지 않을 때만 환경을 읽은 것으로 판정한다. 일치하는 변수가 실제로 남은 경우에만 생성한 세션을 종료하고 오류를 낸다. 환경을 읽지 못하면 세션을 유지하고 unsetEnvVerified: false, unsetEnvWarning: "CLI environment unreadable; removal not verified"를 반환한다. 결과의 unsetEnv는 요청 목록이고 unsetEnvVerified는 확인 여부다. 원격에서는 확인하지 않아 false이고 Windows에서는 이 옵션을 지원하지 않는다.
리드 운영
세션을 띄운 리드가 생성, 컨텍스트 관리, 수동 compact, 종료를 책임진다. 작업 연속성과 소유권을 먼저 판단하고 컨텍스트 비율은 개입 시점으로 쓴다. --resume은 이전 사용량을 유지하므로 재개 직후 compact 필요 여부를 확인한다.
| 동작 | 적용 조건과 실행 |
| compact | 같은 목표와 담당이 이어지고 파일과 git에서 상태를 복구할 수 있을 때. Claude와 Codex는 tfx-live compact --then "다음 지시" --no-wait로 압축 제출을 확인하고 다음 지시를 미리 넣는다. 압축 뒤에 필요한 파일 경로와 검증 명령도 --then에 싣는다. agy는 수동 compact가 없어 handoff한다. |
| clear | 무관한 작업으로 전환하거나 같은 문제를 두 번 넘게 고쳐도 실패할 때, 스펙에서 구현으로 또는 작성자에서 리뷰어로 바뀔 때. 미완료 상태를 정리한 뒤 Claude는 /rename과 /clear를 리드가 tfx-live ask --session <대상> 으로 보낸다(relay 태그 없이). 리드 자기 세션은 tfx-lead 스킬의 "자기 세션 제어" 절을 따라 tfx_control 도구를 쓴다. Codex는 작업 종료 뒤 /new <이름>, agy는 /clear를 쓴다. |
| handoff | 담당·CLI·모델·소유자가 바뀌거나 긴 작업이 창을 넘길 때. 인계 파일에 목표, 완료 조건, 체크아웃과 변경 상태, 확정 결정, 증거 경로, PASS/FAIL/SKIP, 미완료 작업과 프로세스, 다음 행동과 소유자, predecessorSessionId를 적는다. 승계 세션이 경로를 확인하면 이전 세션을 닫는다. |
| close | 결과와 인계를 확인한 즉시 닫는다. Claude 백그라운드는 claude stop <id>, tmux는 tfx-live stop --session, Claude 팀원은 shutdown, Codex 서브에이전트는 close_agent(Codex 0.162.1 의 도구 목록에는 없다), agy 서브에이전트는 /agents 패널의 K를 쓴다. |
Claude TUI는 바쁠 때 들어온 입력을 대기열에 넣고 현재 턴(압축 포함)이 끝나면 순서대로 처리한다. transcript에는 queue-operation의 enqueue와 dequeue로 남는다. Codex 큐의 기록 성공과 실제 처리 완료는 별개다. 리드는 compact를 보내고 --then으로 다음 지시를 넣는 것을 기본 절차로 쓴다.
두 번째 compact 전에는 handoff가 맞는지 점검한다. compact 횟수는 고정하지 않는다.
대상별 제어 지원
리드(Claude)는 compact, clear, exit 를 triflux mod 도구 tfx_control 하나로 보낸다. /tfx-lead <역할> 을 실행한 세션의 메인 대화에서만 쓸 수 있다. target 으로 대상을 고르고, 안 되는 조합은 도구가 이유와 대안을 오류로 돌려준다. 자기 세션의 인자와 절차는 tfx-lead 스킬의 "자기 세션 제어" 절이다.
| target | compact | clear | exit | 받는 쪽 검증 | 조건과 이유 |
self | 됨 | 됨 | 됨(handoff 필수) | 해당 없음 | 턴이 끝난 뒤 mod 가 $.command.run 으로 실행한다. tmux 안팎 같다 |
claude:<이름>, 이 기기 tmux 에서 찾음 | 됨(바쁘면 유휴까지 기다림) | 됨 | 됨 | 없음. 같은 사용자의 tmux 접근 권한뿐 | tfx-live list-sessions --cli claude 의 name 이나 tmux 세션 이름과 맞으면 tfx-live compact --if-busy wait, ask --via-tmux, stop 으로 보낸다. 나중에 adopt 한 세션도 이 경로다 |
claude:<이름>, 피어 경로(tmux 에서 못 찾음), tfx-live start --lead-session <ID> 로 띄움 | 됨 | 됨 | 됨(handoff 필수) | 발신 리드 검사, plugin 출처, 띄운 리드 묶기 | [tfx-control] {...} 표식 피어 메시지를 보내고, 받는 쪽 triflux mod 가 자기를 띄운 리드의 요청일 때만 자기 턴이 끝난 뒤 실행한다. 도구 결과는 전송만 확인한 것이다. "[tfx_control] /<action> 완료" 알림이 오면 실행됐다. 완료 알림이 오지 않으면 받는 쪽 mod 없음 |
claude:<이름>, 피어 경로, 리드가 띄우지 않음(claude --bg, 사용자가 연 세션, adopt 한 세션) | 안 됨 | 안 됨 | 안 됨 | 저장된 리드 없음 | 띄울 때 TFX_LEAD_SESSION_ID 가 넘어가지 않아 받는 쪽이 모두 거부하고 "리드가 띄운 세션이 아니다" 를 알린다. 선착순 묶기는 넣지 않는다. tmux 안이면 위 tmux 경로를 쓴다 |
codex:<tmux 세션> | 됨(instructions 안 됨) | 됨(/new) | 됨(tfx-live stop) | 없음. 받는 쪽 mod 가 없어 tmux 접근 권한뿐 | tmux 직접 입력만 된다. /new 뒤 인계 줄과 then 도 tmux 로 보낸다. queue 는 슬래시를 실행하지 않아 tmux 밖 Codex 는 안 됨 |
agy:<tmux 세션> | 안 됨 | 됨 | 됨(tfx-live stop) | 없음. tmux 접근 권한뿐 | agy 에는 compact 가 없다. /clear 나 handoff 를 쓴다 |
subagent:<이름> | 안 됨 | 안 됨 | 안 됨 | 해당 없음 | 슬래시 입력창이 없고 mod API 에 서브에이전트를 압축하거나 멈추는 함수가 없다. 끝내기는 결과를 받고 닫는다(백그라운드는 TaskStop, 팀원은 tfx-lead 스킬 3절 "끝난 팀원 닫기" 절차). 문맥 줄이기는 요약을 넘겨 새 서브에이전트를 띄운다 |
- 리드 세션 ID 는
action: "whoami"로 얻는다. Claude 워커는tfx-live start --cli claude ... --lead-session <ID>로 띄운다. 그 값은 워커 환경의TFX_LEAD_SESSION_ID로 넘어가고 받는 쪽 mod 가 저장한다. - 리드를 넘길 때는 원 리드가 워커마다
action: "rebind",target: "claude:<이름>",lead: "<새 리드 세션 ID>"를 보낸다. 받는 쪽은 지금 묶인 리드에게서 온 rebind 만 받는다. 원 리드가 이미 죽었으면 tmux 안 워커는 tmux 경로로 제어하고, tmux 밖 워커는 다시 띄운다. - clear 에
handoff를 주면 "인계 파일 <경로> 를 읽고 이어간다." 와then을 차례로 넣는다. 피어 경로에서는 받는 쪽이 이 문장을 사용자 프롬프트로 올리지 않고[tfx-control from <리드 이름>]머리말을 붙인 자기 세션 피어 메시지로 넣는다. - 서브에이전트가 이 도구를 호출하면 어떤 대상이든 거부된다.
리드 역할 절차(역할별 모델, 지시서, 교차 리뷰, 릴리스 조율)는 tfx-lead 스킬을 따른다.
Codex ask 메시지 전송
로컬 세션끼리 주고받는 메시지는 <홈 절대경로>/.claude/scripts/tfx-peer send를 쓴다. 다음은 원격 세션이나 명시적으로 사용자 입력을 전달하는 tfx-live ask의 동작이다.
- 기본은 app-server 실험 API
thread/queue/add로 쌓는 것이다. 공유 daemon에 로드된 thread는 그 daemon에 직접 보내며queueVia: "shared-daemon"을 반환한다. 공유 daemon에 없는 별도 TUI와 stale daemon socket의 연결 실패는 기존 stdio app-server 경로를 쓰며queueVia: "app-server"다. 연결 뒤 initialize나 loaded 목록 검증 실패는 이 경로로 전환하지 않는다. 프롬프트는 두 경로 모두 프로세스 인자에 보이지 않는다. stdio add가 없는 Codex에서는codex queue --thread <UUID> --message로 보내며, 이때 프롬프트가 argv에 보이고queueVia: "codex-queue-argv"와queueFallbackReason이 남는다.queued는 큐 기록만 뜻하며 모델 응답 완료가 아니다. 실제 처리는 아래wait결과로 구분한다. - 첫 줄 머리말은
[from <보낸 세션 이름>] [tfx-live req=<id>]다. 이름은--from,$TFX_LIVE_FROM, Claude 세션 기록, Codexsession_index순으로 찾고 없으면 머리말 없이 표식만 붙인다. Codex TUI는 Claude처럼 접어 보여 주지 않고 사용자 입력으로 그대로 표시한다. - thread는
--thread UUID,start가 남긴@tfx_codex_thread, Codex 세션 레지스트리, pane 프로세스의resume <UUID>인자, pane cwd와 같은 rollout 하나 순으로 찾는다. cwd 대응은 그 cwd의 Codex TUI가 하나일 때만 쓰고 exec 워커와 서브에이전트 thread는 뺀다. 이름으로는 보내지 않는다(codex queue의 이름 조회가 실패한다). - tmux 직접 입력은 queue를 못 쓸 때만 쓴다: 원격 호스트, thread를 못 찾음(
start밖에서resume --last로 띄운 세션,start --resume-last의threadId: null, 같은 cwd의 TUI 여럿 포함),codex queue오류(0.160 미만 포함). 결과에transport: "tmux",transportRequested: "queue",fallbackReason이 남는다. 시간 초과처럼 queue가 이미 쌓았을 수도 있는 오류는status: "unknown"으로 끝내고 재전송하지 않는다. - 슬래시 명령(
/rename,/compact,/new)과 interrupt(Escape)는 tmux 직접 입력 전용이다. queue로 보낸 슬래시 명령은 실행되지 않고 일반 텍스트로 모델에 들어간다./명령으로 시작하는 프롬프트(절대 경로는 제외)와--if-busy fail|interrupt는 tmux로 보내고transportReason을 남긴다. 슬래시 명령에는 표식을 붙이지 않으므로wait로 추적할 수 없다.
보내는 쪽이 Codex여도 로컬 피어 전송은 <홈 절대경로>/.claude/scripts/tfx-peer send를 쓴다. Codex 협업 도구(spawn_agent, send_message, followup_task)는 자기가 띄운 하위 에이전트(/root/...)를 대상으로 한다. 다른 최상위 Codex 세션에 닿는지는 확인하지 않았다. Codex 0.162.1 에서 모델에 노출된 협업 도구는 spawn_agent, wait_agent, send_message, followup_task, list_agents, interrupt_agent이고 close_agent와 send_input은 없었다. send_message는 하위 에이전트의 턴을 시작하지 않고 다음 followup_task 턴에 함께 전달된다.
결과의 status는 queued(쌓임), working(TUI가 가져가 턴 시작), completed, failed로 나뉘고 delivered, deliveredAt, turnId가 배달을 구분한다. queue는 바쁜 세션에도 쌓으므로 --if-busy wait는 의미가 없다.
tfx-live queue --cli codex --session cx1
tfx-live queue --cli codex --session cx1 --request-id <requestId> --delete all
tfx-live queue --cli codex --thread <UUID> --delete <queuedMessageId>queue는 TUI가 아직 가져가지 않은 항목을 보고 지운다. Codex app-server의 실험 API thread/queue/list·thread/queue/delete를 stdio로 호출하며 큐 저장소 파일은 건드리지 않는다. 목록 항목은 id(ask 결과의 queuedMessageId와 같다), requestId, text다. 삭제 결과의 missing은 이미 TUI가 가져갔거나 없는 항목이다. 유휴 TUI는 쌓인 항목을 곧 가져가므로 지울 수 있는 것은 사실상 바쁜 세션과 닫힌 세션의 항목이다. 가져간 뒤의 처리 여부는 wait로 확인한다.
네이티브 goal
tfx-live goal set --session cl1 --condition "관련 단위 테스트가 모두 통과한다"
tfx-live goal set --session cx1 --cli codex --condition "관련 단위 테스트가 모두 통과한다" --budget 100000
tfx-live goal status --session cx1
tfx-live goal clear --session cx1--cli를 생략하면 세션 프로세스에서 추정한다. 로컬 Claude와 Codex만 지원하며 --remote와 agy는 거부한다. --budget은 Codex set의 daemon 경로에서만 받고 Claude와 tmux 폴백에서는 오류로 거부한다.
Claude는 tmux로 /goal <조건>과 /goal clear를 보내고 transcript의 마지막 goal_status로 상태를 읽는다. 별도 평가자의 완료는 complete, 수동 해제는 none이며 judgedBy: "evaluator"와 평가 이유를 보고한다. transcript를 찾지 못하면 상태는 null이고 경고를 남긴다. set/clear 뒤 새 sentinel을 최대 15초 확인하며 없으면 confirmed: false와 경고를 반환한다. 이미 해제된 goal의 clear는 입력 없이 alreadyCleared: true로 답한다. set은 기본 --if-busy wait, clear는 미충족 goal이 턴을 계속 이어 가도 끊을 수 있게 기본 --if-busy interrupt다. 평가자가 해제하지 않고 멈춘 goal은 active로 남으므로 리드가 goal clear로 정리한다.
Codex는 공유 daemon UDS의 thread/goal/*를 우선 쓴다. --codex-socket PATH|default로 소켓을 고르고 기존 thread 해석 순서와 --thread UUID를 따른다. 새 goal은 origin: "user"로 clear 후 active set한다. 소켓이 없거나 thread가 미적재면 set/clear는 tmux 슬래시로, status는 $CODEX_HOME/goals_1.sqlite의 읽기 전용 조회로 폴백한다. node:sqlite를 지원하지 않는 Node에서는 상태를 null로 두고 경고한다. 결과에 transport: "daemon"|"tmux"|"sqlite"와 폴백 이유를 남긴다. tmux 폴백의 set/clear는 sqlite로 최대 15초 확인하고, 확인하지 못하면 재전송을 막으려고 오류 대신 confirmed: false와 경고를 반환한다. Codex의 judgedBy: "model", complete는 모델 자기 판정이므로 리드의 교차 검증이 필요하다.
Claude와 Codex는 네이티브 goal을 우선 쓰고, goal-driven은 agy처럼 네이티브 goal이 없을 때 쓰는 방식이다. 현재 agy의 goal-driven 실행은 지원하지 않는다.
컨텍스트 판단
Claude의 분모는 공식 모델 창과 실행 한도 중 작은 값이다. Codex의 분모는 rollout이 보고한 실행 창이고, 없을 때만 공식 창이다. 아래 비율은 공식 권고가 아닌 [추론] 운영값이다. 모델 문서가 바뀌면 한도도 갱신한다.
| CLI | 준비와 경고 | compact | 신규 배정 중지·handoff | 전송 거부 |
| Claude Code 1M 모델 | 60% | 75% | 85% | 90% |
| Codex rollout 실행 창 | 60% | - | - | 85% |
| Codex 실행 창 없음(1.05M 분모) | 15% | 18% | 20% | 22% |
| agy | 12% | 없음 | 15% | 18% |
Claude는 85% 도달 시 바로 handoff를 지시한다. Codex 실행 창 행의 compact와 handoff 비율은 아직 정하지 않았다. agy 행은 운영 지침이며 agy도 tfx-live 전송 대상이지만 컨텍스트 비율은 자동으로 읽지 못해 null로 보고하고 가드를 건너뛴다. model_context_window와 model_auto_compact_token_limit은 올리지 않는다.
결과에는 estimatedContextTokens, contextLimitTokens, contextLimitSource, contextPct가 포함된다. Claude 실행 한도는 executionContextLimitTokens로 별도 보고하며 CLAUDE_CODE_DISABLE_1M_CONTEXT=1이면 200,000이다. Codex는 rollout token_count의 model_context_window를 executionContextLimitTokens로 보고한다. 이 값이 있으면 모델 표에 없는 모델이라도 그 창으로 판정하고, 없으면 1,050,000 표 값을 분모로 쓴다. 한도를 모르면 비율은 null로 두고 경고만 한다. 사용량이 없는 probe는 context: null이다. 컨텍스트를 확인하려면 직접 tfx-live probe를 실행한다. interrupt, 자동 ask의 daemon probe, stop --short는 transcript를 읽지 않는다.
ask의 --warn-context-pct와 --max-context-pct는 경고·거부 비율을 덮어쓰며 0이면 해당 가드를 끈다. 기본값은 표의 경고·전송 거부 열이다. Codex는 executionContextLimitTokens가 있으면 실행 창 행을, 없으면 1.05M 분모 행을 쓴다. 거부 결과는 status: "failed", done: false, context-limit, 컨텍스트 필드와 적용한 거부 비율 thresholdPct를 돌려준다. 경고의 thresholdPct는 적용한 경고 비율이다. 자세한 근거와 실측은 clone 의 docs/research/tfx-live-context-policy-2026-10.md에 있다(설치본에는 없다).
수동 compact와 종료
tfx-live compact --cli claude --session cl1 --instructions "변경 파일과 검증 명령을 보존하라" --then "인계 파일을 읽고 검증을 이어가라" --no-wait
tfx-live compact --cli codex --session cx1 --then "src/main.mjs를 확인하고 지정된 단위 테스트를 실행하라" --no-wait
tfx-live wait --cli codex --session cx1 --request-id <then.requestId> --timeout 120
tfx-live stop --cli claude --short <8hex>
tfx-live stop --cli claude --session-id <id>
tfx-live stop --session cl1리드 자기 세션의 compact, clear, exit 는 tmux 안팎 모두 triflux mod 도구 tfx_control 을 먼저 쓴다(tfx-lead 스킬 "자기 세션 제어" 절). 아래 경로는 mod 가 없는 세션의 대안이다. tmux 안에서 도는 Claude 세션은 자기 자신도 compact 할 수 있다. 자기 턴이 도는 동안에는 세션이 바쁘므로, 백그라운드로 띄우고 --if-busy wait로 턴이 끝나기를 기다리게 한다. 기본 fail로 두면 턴이 끝나기 전에 거부된다. 결과는 파일에 남겨 다음 턴에 확인한다. 사용자에게 /compact 입력을 부탁하기 전에 이 방법을 쓴다.
tfx-live compact --session "$TMUX_PANE" --if-busy wait --busy-timeout 600 --instructions "상태 파일 경로와 남은 일을 보존하라" --then "상태 파일을 다시 읽고 이어가라" --no-wait > "${TMPDIR:-/tmp}/tfx-self-compact.json" 2>&1 &compact --session S [--cli claude|codex] [--instructions TEXT] [--then PROMPT] [--no-wait]는 로컬 tmux에서 /compact를 중계 표식 없이 보낸다. CLI 기본값은 Claude다. --instructions는 Claude에서만 받으며 Codex는 인자를 받지 않아 거부한다. 기본 --if-busy fail이며 바쁜 세션에는 compact를 전송하지 않는다. UDS compact는 지원하지 않는다.
--no-wait는 압축 진행 표시 또는 새 완료 기록으로 제출을 확인한 뒤 반환한다. Codex에서 확인되지 않으면 Enter를 한 번 더 보내고, 그래도 확인되지 않으면 --then을 보내지 않고 오류로 끝낸다. --then은 일반 텍스트 지시만 받으며 슬래시 명령은 거부한다. 제출 확인 직후 Claude에는 표식을 붙여 tmux로 보내고 화면의 queued messages 또는 transcript의 enqueue로 확인한다. Claude 압축이 먼저 끝나 지시가 이미 처리에 들어갔으면 then.queued: false, delivered: true로 보고한다. Codex에는 기존 queue 경로로만 보내며 tmux로 전환하지 않는다. 결과의 then.requestId로 wait --request-id에서 압축 뒤 응답을 받는다.
--no-wait가 없으면 Claude의 새 compact_boundary, Codex rollout의 새 compacted까지 기다린다. 결과에 compact: {submitted: true, done}과 then: {requestId, queued, transport}를 추가하고 기존 compacted, preTokens, postTokens를 유지한다. 토큰 수는 기록에 있는 값만 보고하며 Codex의 압축 후 token_count가 아직 없으면 postTokens는 null이다. 시간 안에 완료 기록이 없으면 compacted: false, timedOut: true다.
stop --short와 stop --session-id는 claude stop <id>를 호출하고 stopped: true, conversationKept: true를 반환한다. claude attach로 대화를 재개할 수 있다. /exit, ←, Ctrl+Z는 백그라운드 세션의 연결만 끊는다. macOS의 sysctl -n kern.memorystatus_vm_pressure_level이 2 이상이면 새 세션을 띄우기 전 정리한다. 원격 배정 전에는 tfx-remote probe <host>의 ready와 warnings를 확인한다.
요청과 완료 확인
tfx-live ask --cli claude --transport uds --short <8hex> --prompt "진행 상황을 보고해줘" --no-wait
tfx-live wait --cli claude --short <8hex> --request-id <requestId> --timeout 120 --poll-interval 500
tfx-live ask --cli claude --session cl1 --prompt "진행 상황을 보고해줘" --no-wait
tfx-live wait --cli claude --session cl1 --request-id <requestId> --timeout 120
tfx-live ask --cli codex --session cx1 --prompt "진행 상황을 보고해줘" --no-wait
tfx-live wait --cli codex --session cx1 --request-id <requestId> --timeout 120ask --no-wait는 Claude와 tmux에서 status: "submitted", Codex queue에서 status: "queued"와 함께 inputSent: true, done: false, submittedAt, target, requestId를 반환한다. ask, peer, converse, goal-driven은 [tfx-live req=<requestId>]를 프롬프트 앞에 붙인다. --no-relay-tag로 제거하면 wait --request-id가 해당 요청을 찾을 수 없다. 슬래시 명령(/rename, /clear 등)은 CLI와 상관없이 표식 없이 보낸다. 응답 턴이 없는 Claude 내장 명령(/rename, /clear, /compact, /model, /effort, /color)은 기다리지 않고 status: "submitted"로 반환한다. 압축 완료까지 기다리려면 compact 명령을 쓴다.
wait는 Claude transcript에서 표식을 user 메시지, queue-operation의 enqueue content, queued command attachment에서 찾는다. 표식이 소비된 턴이 끝난 뒤 마지막 assistant 텍스트를 응답으로 쓴다. 표식 없는 wait는 최신 user turn을 본다. isSidechain과 합성 API 오류 메시지는 정상 응답에서 제외한다. 요청을 소비한 턴에서 합성 오류가 나타나면 오류 문구와 status: "failed"를 반환한다. daemon의 idle만으로 완료를 단정하지 않는다. timeout은 status: "working", timedOut: true, done: false다.
tmux로 띄운 대화형 Claude는 wait --session <tmux 대상>을 쓴다. pane에 붙은 Claude 세션 기록(~/.claude/sessions)에서 sessionId를 찾아 같은 transcript 규칙으로 판정하고, daemon의 idle 대신 세션 기록의 status: "idle"을 쓴다. transcript는 처음 찾은 것을 끝까지 쓰므로 대기 중 /clear로 바뀐 세션은 따라가지 않는다. 로컬 전용이다.
Codex wait는 --session 또는 --thread UUID의 rollout에서 표식이 든 user 메시지의 turn_id를 찾고, 같은 턴의 task_complete.last_agent_message를 응답으로 쓴다. turn_aborted는 status: "failed"다. 표식이 아직 없으면 status: "queued", timedOut: true다. --timeout 0은 한 번만 확인한다.
명시한 --config-dir은 정확히 일치하는 daemon만 선택한다. CLAUDE_CONFIG_DIR도 해당 env 디렉터리로 제한한다. stale endpoint 복구는 같은 source configDir 안에서만 재시도한다. attach 전 예외는 inputSent: false이므로 auto의 tmux fallback이 가능하다. attach 뒤 전송 여부가 불명확하면 status: "unknown"으로 보고하고 재전송하지 않는다.
직접 tmux capture-pane과 tmux send-keys를 쓸 때는 전송·pane 진단에 한정한다. Claude pane에 C-c를 보내지 않는다. 자동 세션 탐색에는 tmr ls --json으로 pane 별 에이전트, 상태, 클라이언트 수, 마지막 활동을 본다. tmr 이 없으면 아래 tfx-live list-sessions와 tmux ls -F '#{session_name} #{session_attached}'를 쓴다. tmr 은 macOS(arm64) 에서 tfx setup 이 설치를 묻는다.
세션 탐색과 연결
tfx-live probe는 Claude daemon을 찾는다. tfx-live list-sessions --cli codex [--cwd DIR]는 기존 Codex tmux pane을 찾고 target, cwd, command, threadId, name 등을 보고한다. --cwd는 pane 경로와 정확히 일치해야 한다. tfx-live list-sessions --cli claude [--cwd DIR]는 살아 있는 Claude pane만 찾는다. --remote와 --transport uds는 Claude tmux 탐색에 쓸 수 없다.
ask와 tmux interrupt는 세션명, name:window, name:window.pane을 받는다. start와 tmux stop --session은 세션명만 받는다. stop은 pane·window 대상과 %12, @3 같은 ID를 거부한다. --remote HOST는 대상을 그대로 원격에 전달한다.
tmux ask는 pane의 작업 상태와 Codex model: loading을 확인한다. tmux의 --if-busy wait|fail|interrupt 기본값은 wait다. --busy-timeout 기본값은 --timeout이고 --poll-interval은 밀리초다. timeout이면 프롬프트를 보내지 않는다. interrupt는 Escape 후 idle을 기다린다. 기존 입력 초안이 있으면 붙여넣기와 합쳐질 수 있으므로 전송 전 pane을 확인한다.
Codex UDS 스레드
공유 daemon 소켓 기본값은 $CODEX_HOME/app-server-control/app-server-control.sock이며 CODEX_HOME이 없으면 ~/.codex 아래를 쓴다. --codex-socket PATH|default로 기존 소켓을 선택한다. 없으면 codex app-server daemon start로 시작한다.
tfx-live list-sessions --cli codex --transport uds --cwd ~/Projects/my-worktree
tfx-live ask --cli codex --transport uds --thread auto --cwd ~/Projects/my-worktree --prompt "현재 변경사항을 요약해줘" --if-busy wait --timeout 120--thread auto는 선택 조건에 맞는 로드된 thread가 정확히 하나일 때만 쓴다. 여러 개면 목록에서 ID를 골라 --thread ID를 지정한다. UDS의 --if-busy wait|fail|steer 기본값은 wait다. thread/resume으로 알림을 구독한 뒤 turn/start를 호출하고 반환된 turn ID의 완료만 인정한다. 완료 응답은 final_answer를 우선하고 중간 commentary는 따로 반환한다. --max-turn은 활동 연장 상한을 지정한다. Codex UDS interrupt는 지원하지 않으므로 tmux pane이 있으면 interrupt --session <target>을 쓴다.
peer
tfx-live peer --cli-a codex --cli-b claude --session-a cx-peer --session-b cl-peer --cwd ~/Projects --mode freeform --seed "변경을 함께 검토해줘" --rounds 2 --timeout 180
tfx-live peer --cli-a codex --transport-a uds --thread-a <id|auto> --cli-b claude --transport-b uds --short-b <8hex> --cwd ~/Projects/my-worktree --mode freeform --seed "변경을 검토해줘"
tfx-live peer --via message --cli-a claude --cli-b claude --session-a cl-a --session-b cl-b --attach-a --attach-b --seed "변경을 함께 검토해줘" --rounds 3
tfx-live peer --cli-a codex --cli-b claude --cli-c agy --session-c peerC --mode freeform --seed "변경을 함께 검토해줘" --rounds 2
tfx-live peer --cli-a codex --cli-b claude --mode debate --seed "변경을 검토하고 수정한 입장을 제시해줘" --rounds 2peer는 이전 응답을 반대쪽의 다음 프롬프트로 전달한다. 기존 tmux pane은 --attach-a·--attach-b로 연결하며 종료하지 않는다. UDS 쪽도 기존 세션으로 취급한다. Codex 쪽은 ask와 같이 queue가 기본이고 응답은 rollout에서 읽는다. thread를 못 찾으면 tmux 직접 입력으로 바꾸고 hop에 fallbackReason을 남긴다. --remote이거나 --if-busy fail|interrupt이면 처음부터 tmux로 보낸다. --if-busy-a·--if-busy-b로 각 쪽의 정책을 정한다. 소유한 세션을 실제 종료한 경우에만 stoppedA·stoppedB가 참이다.
--cli-c를 지정하면 A, B, C 순서로 진행하며 한 라운드는 세 hop이다. C의 기본 세션은 peerC이며 --session-c, --model-c, --effort-c, --attach-c, --transport-c, --if-busy-c, --short-c, --session-id-c, --thread-c, --codex-socket-c, --bridge-c를 받는다. 각 hop과 마지막 closure에는 다른 두 참여자의 최근 답을 Participant A, Participant B, Participant C로 표시한다. C의 연결과 종료 여부는 attachedC, stoppedC로 보고한다. C는 relay에서만 쓴다.
--mode debate는 첫 hop에 seed를 보내고 이후에는 다른 참여자의 최근 답을 검토하여 동의와 이견의 이유 및 수정한 입장을 요구한다. 2자와 3자 모두에서 쓰며 답의 길이는 제한하지 않는다. 마지막 hop은 기존과 같은 closure 차례다.
Claude끼리는 --via message를 쓴다. tfx-live는 양쪽에 상대 세션 이름과 끝낼 조건을 한 번씩 보내고 status: "started"로 바로 끝난다. 그 뒤 두 세션은 SendMessage로 직접 주고받는다. 왕복 횟수는 --rounds를 지시문으로만 전하므로 tfx-live가 강제하지 않는다. transcript도 남기지 않는다. A는 끝나면 합의 JSON을 --report-to 세션에 SendMessage로 보낸다. --report-to가 없으면 tfx-live를 호출한 Claude 세션에 보내고, 그 세션도 찾지 못하면 A 세션 화면에 남긴다. 띄운 세션은 대화가 이어지도록 종료하지 않으므로 끝나면 stop으로 닫는다. 로컬 tmux 대화형 Claude만 지원하고 세션 이름을 찾지 못하면 실패한다.
진단
tfx-live --help
tfx-live probe
tfx-live list-sessions --cli codexauto가 tmux로 전환되면 ~/.claude/cache/triflux/tfx-live/bug-reports/uds-fallback-*.json을 확인한다. 테스트에서는 $TFX_LIVE_BUG_REPORT_DIR로 위치를 바꿀 수 있다.
원격 native peer 발신과 회신
- Darwin과 POSIX Linux에서 양쪽에 같은 원격 peer 프로토콜을 지원하는
tfx-peer래퍼가 설치되어 있을 때 쓴다. 등록 OS 값은 대소문자만 정규화하여Darwin,macOS,Linux도 허용한다. 미상 OS와 Windows 송수신 조합은 전송 전에 거부한다. - 발신 호스트에서
remote-send --host m5 --reply-host m2 --to 'codex:<이름 또는 UUID>' --message '<본문>'을 실행한다.m5는 목적지,m2는 수신 호스트에서 발신 호스트를 찾을 등록 별명이다. 발신 호스트의 사용자 상태hosts.json에는 목적지m5, 수신 호스트에는 회신 목적지m2가 호스트 이름 또는aliases로 등록되어 있어야 한다. 각 호스트의 자기 항목은 필요 없다. 송신은 실제 SSH 목적지만 조회하고, 수신은 역방향 회신 목적지만 조회한다. 원본 저장소의 legacy hosts로 폴백하거나 설정을 자동 복사하지 않는다. --from 'claude:<이름 또는 UUID>',--from 'codex:<이름 또는 UUID>',--from 'agy:<이름 또는 UUID>'을 명시할 수 있다. 우선순위는--from,TFX_LIVE_FROM, 발신 호스트의 자동 탐색이다. 발신 세션을 판별하지 못하면 SSH 전에--from을 요구한다.remote-send에는--host와--reply-host가 모두 필요하다. 로컬send에는--remote,--host,--reply-host를 붙일 수 없으며self도 원격 플래그를 거부한다.- 수신 본문은 원래 발신 CLI, 표시 이름,
origin호스트와 가능한 대화 UUID를 보존한다. 회신 안내의--host는 원래 발신 호스트,--reply-host는 원래 목적지다. UUID가 있으면 표시 이름보다 정확한 대화 UUID로 회신한다. 수신 환경을 발신 환경처럼 바꾸지 않는다. - SSH 대상은 등록된 주소와 사용자만 쓴다. 원격 명령은 고정된
_receive진입점이고 본문과 메타데이터는 크기 제한 JSON stdin으로 전달한다.remote-send와_receive는 기존send자동 승인 범위에 포함하지 않는다. 전역 allow, 동의 파일과 설정을 바꾸지 않으며 원격 전송은 별도 실행 권한을 따른다._receive는 내부 수신용이다. 발신 표시와 호스트 별명은 인증 신원이나 권한 근거가 아니다. 기존 수신 세션의 소유권, PID, socket, thread, conversation 검사를 그대로 적용한다. - SSH는 한 번만 실행한다. 기록 전 확정 거부는
rejected, 기록 후 응답 유실과 timeout은unknown, adapter의 부분 기록은partial로 반환한다.retrySafe:false,modelReceipt:false와 발신 호스트의correlationId를 유지하며 adapter의msgId도 보존한다. 자동 재전송과 tmux 또는 사용자 턴 폴백은 없다.sent와written도 모델 수신이나 완료를 뜻하지 않는다. - 같은 호스트 Claude끼리는 기존
SendMessage를 쓴다. 원격 peer 수신은 목적지의 기존 native adapter로 전달하고,tfx-live ask의 사용자 입력 경로와 구분한다. 기존tfx-live send의 원격 미지원 계약은 그대로다.
"$HOME/.claude/scripts/tfx-peer" remote-send --host m5 --reply-host m2 --to 'codex:10.30 구현' --message '변경사항을 공유합니다'
"$HOME/.claude/scripts/tfx-peer" remote-send --from 'agy:10.30 발신' --host m5 --reply-host m2 --to 'claude:10.30 리드' --message '결과 파일을 확인해 주세요'
# m5의 수신 본문에 표시되는 회신 예시
"$HOME/.claude/scripts/tfx-peer" remote-send --host m2 --reply-host m5 --to 'codex:<원래 발신 UUID>' --message '확인했습니다'선택적 전역 native peer 어댑터
Windows는 Claude 대상 전달만 지원하고 자동 승인용 래퍼나 Codex 규칙을 설치하지 않는다. PowerShell에서 다음처럼 직접 실행한다.
node "$env:APPDATA\npm\node_modules\triflux\bin\tfx-peer.mjs" send --to 'claude:<이름>' --message '<본문>'npm의 tfx-peer.cmd shim은 cmd.exe가 본문을 다시 해석해 %, &, 줄바꿈을 깨뜨리므로 쓰지 않는다. tfx-live start로 띄운 Codex는 승인과 샌드박스를 끈 상태라 이 규칙 없이 실행할 수 있다. Windows의 Codex 대상 전달은 지원하지 않는다.
macOS/Linux는 triflux setup에서 별도 동의하면 ~/.claude/scripts/tfx-peer send --to 'codex:<정확한 이름>' --message '<본문>', --to 'claude:<정확한 이름>', --to 'agy:<정확한 이름>'을 쓴다. ~는 셸 예시이고 실제 호출과 회신 안내는 setup이 출력한 홈의 절대경로 래퍼 send를 쓴다. 위 <홈 절대경로>도 실제 값으로 바꾼다. node, bash, tfx-live send를 이 승인으로 실행하지 않는다. Claude끼리는 기존 native SendMessage를 우선 사용한다. native peer 실패는 사용자 입력으로 fallback하지 않는다.
macOS/Linux 설치는 현재 사용자 또는 root 소유이고 other-write가 없는 안정적인 package, Node, tmux 경로만 허용한다. group-write는 허용하지만 개발 checkout, symlink packageRoot, 바뀐 런타임 계약은 거부한다. Claude key/socket/auth의 0600 검사는 별도로 유지한다. setup이 확인한 tmux 디렉터리만 래퍼의 고정 PATH에 넣고 호출자 PATH나 PSMUX override를 받지 않는다. 거절·비대화형·CI·postinstall에서는 승인 파일을 쓰지 않으며 update는 미설정·거절·철회를 조용히 보존한다. 재승인은 triflux setup에서 명시적으로 선택한다.
Claude 수신은 collapsed native peer UI지만 UDS 또는 named pipe 쓰기 후 결과 written에는 같은 연결의 인증·거절 ACK가 없다. 수신이나 모델 완료로 읽지 않는다. Codex는 same-daemon agent_message raw injection과 non-user wake를 쓴다. sent는 유효한 turn ID와 inProgress 또는 completed wake 응답을 받은 상태이며 turnId, turnStatus를 반환한다. 모델 수신과 작업 완료는 뜻하지 않으며 modelReceipt: false를 유지한다. injection 뒤 wake가 실패하거나 턴 응답이 없으면 partial로 반환하고 자동 재전송하지 않는다. agy는 대화별 .system_generated/messages/ 파일 저장소 쓰기(written)이고 peer-wake 패치가 적용된 로컬 세션은 유휴 중에도 바로 깨어난다. 로컬 tfx-live start --cli codex와 resume은 검사한 소켓의 realpath로 공유 app-server 데몬에 붙는다. --remote 세션의 셸은 데몬에서 돌아서 -C로 작업 디렉터리를 지정한다. 소켓이 없으면 codex app-server daemon start 안내와 함께 실패한다. 손으로 띄운 Codex는 tfx-live adopt --session <tmux 대상>으로 연결한다. 리드가 그 pane에 nonce 메시지를 tmux로 한 번 입력하고, 그 메시지를 받은 공유 데몬 thread를 pane에 기록한다. 이 한 번은 상대 기록에 사용자 발화로 남는다. -c 설정 덮어쓰기나 --no-daemon으로 띄운 Codex는 공유 데몬 밖에서 돌아 adopt가 실패하므로 tfx-live start --cli codex --resume <thread>로 다시 띄운다. 송신 socket은 일회성이므로 native SendMessage 회신은 지원하지 않는다(ENOENT 가능). 본문의 발신 머리말과 회신 안내를 따른다. macOS/Linux의 Claude, Codex, agy 발신은 홈의 실제 절대경로 래퍼 tfx-peer, unknown 발신은 회신: 경로 불명(보낸 세션을 판별하지 못함)을 안내한다. Windows에서 Claude 대상으로 회신할 때는 위 node 호출을 안내한다. tfx-peer 본문은 8000자까지 받으며 긴 본문은 파일 경로로 보낸다. 머리말과 회신 줄은 그 제한에 포함하지 않는다. partial/unknown 또는 timeout은 중복 가능성 때문에 자동 재시도하지 않는다.
철회할 때 Claude settings.json의 해당 Bash(<실제 절대경로>/tfx-peer send:*) allow, ~/.codex/rules/triflux-native-peer.rules, ~/.claude/scripts/tfx-peer, **~/.claude/scripts/tfx-peer-consent.json**을 확인해 이 어댑터 항목만 제거한다. partial 설치 충돌이면 같은 경로의 tfx-peer-consent.json.lock도 확인한다. 다른 설정이나 deny는 건드리지 않는다. 전역 승인 대신 기존 수동 ~/.codex/rules/tfx-live.rules를 쓰더라도 이는 native peer 전송과 다르다. 원격 자동 권한 변경은 지원하지 않는다.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

