triflux 3.2.0-dev.9 → 3.3.0-dev.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/scripts/setup.mjs CHANGED
@@ -16,10 +16,17 @@ const CODEX_DIR = join(homedir(), ".codex");
16
16
  const CODEX_CONFIG_PATH = join(CODEX_DIR, "config.toml");
17
17
 
18
18
  const REQUIRED_CODEX_PROFILES = [
19
+ {
20
+ name: "high",
21
+ lines: [
22
+ 'model = "gpt-5.4"',
23
+ 'model_reasoning_effort = "high"',
24
+ ],
25
+ },
19
26
  {
20
27
  name: "xhigh",
21
28
  lines: [
22
- 'model = "gpt-5.3-codex"',
29
+ 'model = "gpt-5.4"',
23
30
  'model_reasoning_effort = "xhigh"',
24
31
  ],
25
32
  },
@@ -50,16 +57,21 @@ const SYNC_MAP = [
50
57
  dst: join(CLAUDE_DIR, "scripts", "tfx-route-worker.mjs"),
51
58
  label: "tfx-route-worker.mjs",
52
59
  },
53
- {
54
- src: join(PLUGIN_ROOT, "hub", "workers", "codex-mcp.mjs"),
55
- dst: join(CLAUDE_DIR, "scripts", "hub", "workers", "codex-mcp.mjs"),
56
- label: "hub/workers/codex-mcp.mjs",
57
- },
58
- {
59
- src: join(PLUGIN_ROOT, "hub", "workers", "interface.mjs"),
60
- dst: join(CLAUDE_DIR, "scripts", "hub", "workers", "interface.mjs"),
61
- label: "hub/workers/interface.mjs",
62
- },
60
+ {
61
+ src: join(PLUGIN_ROOT, "hub", "workers", "codex-mcp.mjs"),
62
+ dst: join(CLAUDE_DIR, "scripts", "hub", "workers", "codex-mcp.mjs"),
63
+ label: "hub/workers/codex-mcp.mjs",
64
+ },
65
+ {
66
+ src: join(PLUGIN_ROOT, "hub", "workers", "delegator-mcp.mjs"),
67
+ dst: join(CLAUDE_DIR, "scripts", "hub", "workers", "delegator-mcp.mjs"),
68
+ label: "hub/workers/delegator-mcp.mjs",
69
+ },
70
+ {
71
+ src: join(PLUGIN_ROOT, "hub", "workers", "interface.mjs"),
72
+ dst: join(CLAUDE_DIR, "scripts", "hub", "workers", "interface.mjs"),
73
+ label: "hub/workers/interface.mjs",
74
+ },
63
75
  {
64
76
  src: join(PLUGIN_ROOT, "hub", "workers", "gemini-worker.mjs"),
65
77
  dst: join(CLAUDE_DIR, "scripts", "hub", "workers", "gemini-worker.mjs"),
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env bash
2
- # tfx-route.sh v2.2 — CLI 라우팅 래퍼 (triflux)
2
+ # tfx-route.sh v2.3 — CLI 라우팅 래퍼 (triflux)
3
3
  #
4
4
  # v1.x: cli-route.sh (jq+python3+node 혼재, 동기 후처리 ~1s)
5
5
  # v2.0: tfx-route.sh 리네임
@@ -9,7 +9,7 @@
9
9
  # - Gemini health check 지수 백오프 (30×1s → 5×exp)
10
10
  # - 컨텍스트 파일 5번째 인자 지원
11
11
  #
12
- VERSION="2.2"
12
+ VERSION="2.3"
13
13
  #
14
14
  # 사용법:
15
15
  # tfx-route.sh <agent_type> <prompt> [mcp_profile] [timeout_sec] [context_file]
@@ -226,8 +226,9 @@ route_agent() {
226
226
  CLI_TYPE="claude-native"; CLI_CMD=""; CLI_ARGS=""
227
227
  CLI_EFFORT="n/a"; DEFAULT_TIMEOUT=300; RUN_MODE="fg"; OPUS_OVERSIGHT="false" ;;
228
228
  verifier)
229
- CLI_TYPE="claude-native"; CLI_CMD=""; CLI_ARGS=""
230
- CLI_EFFORT="n/a"; DEFAULT_TIMEOUT=300; RUN_MODE="fg"; OPUS_OVERSIGHT="false" ;;
229
+ CLI_TYPE="codex"; CLI_CMD="codex"
230
+ CLI_ARGS="exec --profile thorough ${codex_base} review"
231
+ CLI_EFFORT="thorough"; DEFAULT_TIMEOUT=1200; RUN_MODE="fg"; OPUS_OVERSIGHT="false" ;;
231
232
  test-engineer)
232
233
  CLI_TYPE="claude-native"; CLI_CMD=""; CLI_ARGS=""
233
234
  CLI_EFFORT="n/a"; DEFAULT_TIMEOUT=300; RUN_MODE="bg"; OPUS_OVERSIGHT="false" ;;
@@ -253,6 +254,8 @@ route_agent() {
253
254
  TFX_CLI_MODE="${TFX_CLI_MODE:-auto}"
254
255
  TFX_NO_CLAUDE_NATIVE="${TFX_NO_CLAUDE_NATIVE:-0}"
255
256
  TFX_CODEX_TRANSPORT="${TFX_CODEX_TRANSPORT:-auto}"
257
+ TFX_WORKER_INDEX="${TFX_WORKER_INDEX:-}"
258
+ TFX_SEARCH_TOOL="${TFX_SEARCH_TOOL:-}"
256
259
  case "$TFX_NO_CLAUDE_NATIVE" in
257
260
  0|1) ;;
258
261
  *)
@@ -267,6 +270,20 @@ case "$TFX_CODEX_TRANSPORT" in
267
270
  exit 1
268
271
  ;;
269
272
  esac
273
+ case "$TFX_WORKER_INDEX" in
274
+ "") ;;
275
+ *[!0-9]*|0)
276
+ echo "ERROR: TFX_WORKER_INDEX 값은 1 이상의 정수여야 합니다. (현재: $TFX_WORKER_INDEX)" >&2
277
+ exit 1
278
+ ;;
279
+ esac
280
+ case "$TFX_SEARCH_TOOL" in
281
+ ""|brave-search|tavily|exa) ;;
282
+ *)
283
+ echo "ERROR: TFX_SEARCH_TOOL 값은 brave-search, tavily, exa 중 하나여야 합니다. (현재: $TFX_SEARCH_TOOL)" >&2
284
+ exit 1
285
+ ;;
286
+ esac
270
287
  CODEX_MCP_TRANSPORT_EXIT_CODE=70
271
288
 
272
289
  apply_cli_mode() {
@@ -408,23 +425,60 @@ get_mcp_hint() {
408
425
 
409
426
  has_server() { echo ",$servers," | grep -q ",$1,"; }
410
427
 
428
+ get_search_tool_order() {
429
+ local available=()
430
+ local ordered=()
431
+ local tool
432
+
433
+ for tool in brave-search tavily exa; do
434
+ has_server "$tool" && available+=("$tool")
435
+ done
436
+
437
+ if [[ ${#available[@]} -eq 0 ]]; then
438
+ return 0
439
+ fi
440
+
441
+ if [[ -n "$TFX_SEARCH_TOOL" ]]; then
442
+ for tool in "${available[@]}"; do
443
+ [[ "$tool" == "$TFX_SEARCH_TOOL" ]] && ordered+=("$tool")
444
+ done
445
+ for tool in "${available[@]}"; do
446
+ [[ "$tool" != "$TFX_SEARCH_TOOL" ]] && ordered+=("$tool")
447
+ done
448
+ elif [[ -n "$TFX_WORKER_INDEX" && ${#available[@]} -gt 1 ]]; then
449
+ local offset=$(( (TFX_WORKER_INDEX - 1) % ${#available[@]} ))
450
+ local i idx
451
+ for ((i=0; i<${#available[@]}; i++)); do
452
+ idx=$(( (offset + i) % ${#available[@]} ))
453
+ ordered+=("${available[$idx]}")
454
+ done
455
+ else
456
+ ordered=("${available[@]}")
457
+ fi
458
+
459
+ printf '%s\n' "${ordered[*]}"
460
+ }
461
+
462
+ local ordered_tools=()
463
+ read -r -a ordered_tools <<< "$(get_search_tool_order)"
464
+ local ordered_tools_csv=""
465
+ if [[ ${#ordered_tools[@]} -gt 0 ]]; then
466
+ ordered_tools_csv=$(printf '%s, ' "${ordered_tools[@]}")
467
+ ordered_tools_csv="${ordered_tools_csv%, }"
468
+ fi
469
+
411
470
  local hint=""
412
471
  case "$profile" in
413
472
  implement)
414
473
  has_server "context7" && hint+="context7으로 라이브러리 문서를 조회하세요. "
415
- if has_server "brave-search"; then hint+="웹 검색은 brave-search를 사용하세요. "
416
- elif has_server "exa"; then hint+="웹 검색은 exa를 사용하세요. "
417
- elif has_server "tavily"; then hint+="웹 검색은 tavily를 사용하세요. "
474
+ if [[ ${#ordered_tools[@]} -gt 0 ]]; then
475
+ hint+="웹 검색은 ${ordered_tools[0]}를 사용하세요. "
418
476
  fi
419
- hint+="검색 도구 실패 시 재시도하지 말고 다음 도구로 전환하세요."
477
+ hint+="검색 도구 실패 시 402, 429, 432, 433, quota 에러에서 재시도하지 말고 다음 도구로 전환하세요."
420
478
  ;;
421
479
  analyze)
422
480
  has_server "context7" && hint+="context7으로 관련 문서를 조회하세요. "
423
- local search_tools=""
424
- has_server "brave-search" && search_tools+="brave-search, "
425
- has_server "tavily" && search_tools+="tavily, "
426
- has_server "exa" && search_tools+="exa, "
427
- [[ -n "$search_tools" ]] && hint+="웹 검색 우선순위: ${search_tools%, }. 402 에러 시 즉시 다음 도구로 전환. "
481
+ [[ -n "$ordered_tools_csv" ]] && hint+="웹 검색 우선순위: ${ordered_tools_csv}. 402, 429, 432, 433, quota 에러 시 즉시 다음 도구로 전환. "
428
482
  has_server "playwright" && hint+="모든 검색 실패 시 playwright로 직접 방문 (최대 3 URL). "
429
483
  hint+="검색 깊이를 제한하고 결과를 빠르게 요약하세요."
430
484
  ;;
@@ -433,7 +487,9 @@ get_mcp_hint() {
433
487
  ;;
434
488
  docs)
435
489
  has_server "context7" && hint+="context7으로 공식 문서를 참조하세요. "
436
- has_server "brave-search" && hint+="추가 검색은 brave-search를 사용하세요. "
490
+ if [[ ${#ordered_tools[@]} -gt 0 ]]; then
491
+ hint+="추가 검색은 ${ordered_tools[0]}를 사용하세요. "
492
+ fi
437
493
  hint+="검색 결과의 출처 URL을 함께 제시하세요."
438
494
  ;;
439
495
  minimal|none) ;;
@@ -446,7 +502,7 @@ get_gemini_mcp_servers() {
446
502
  local profile="$1"
447
503
  case "$profile" in
448
504
  implement) echo "context7 brave-search" ;;
449
- analyze) echo "context7 brave-search exa" ;;
505
+ analyze) echo "context7 brave-search exa tavily" ;;
450
506
  review) echo "sequential-thinking" ;;
451
507
  docs) echo "context7 brave-search" ;;
452
508
  *) echo "" ;;
@@ -782,6 +838,9 @@ ${ctx_content}
782
838
  # 메타정보 (stderr)
783
839
  echo "[tfx-route] v${VERSION} type=$CLI_TYPE agent=$AGENT_TYPE effort=$CLI_EFFORT mode=$RUN_MODE timeout=${TIMEOUT_SEC}s" >&2
784
840
  echo "[tfx-route] opus_oversight=$OPUS_OVERSIGHT mcp_profile=$MCP_PROFILE" >&2
841
+ if [[ -n "$TFX_WORKER_INDEX" || -n "$TFX_SEARCH_TOOL" ]]; then
842
+ echo "[tfx-route] worker_index=${TFX_WORKER_INDEX:-auto} search_tool=${TFX_SEARCH_TOOL:-auto}" >&2
843
+ fi
785
844
  if [[ "$CLI_TYPE" == "codex" ]]; then
786
845
  echo "[tfx-route] codex_transport_request=$TFX_CODEX_TRANSPORT" >&2
787
846
  fi
@@ -1,26 +1,32 @@
1
1
  ---
2
- name: tfx-team
2
+ name: tfx-multi
3
3
  description: 멀티-CLI 팀 모드. Claude Native Agent Teams + Codex/Gemini 멀티모델 오케스트레이션.
4
4
  triggers:
5
- - tfx-team
5
+ - tfx-multi
6
6
  argument-hint: '"작업 설명" | --agents codex,gemini "작업" | --tmux "작업" | status | stop'
7
7
  ---
8
8
 
9
- # tfx-team v2.2슬림 래퍼 + 네비게이션 복원 기반 멀티-CLI 팀 오케스트레이터
9
+ # tfx-multi v3파이프라인 기반 멀티-CLI 팀 오케스트레이터
10
10
 
11
11
  > Claude Code Native Teams의 Shift+Down 네비게이션을 복원한다.
12
12
  > Codex/Gemini 워커마다 최소 프롬프트(~100 토큰)의 슬림 Agent 래퍼를 spawn하여 네비게이션에 등록하고,
13
13
  > 실제 작업은 `tfx-route.sh`가 수행한다. task 상태는 `team_task_list`를 truth source로 검증한다.
14
- > v2.2 현재 슬림 래퍼 Agent로 Shift+Down 네비게이션 복원, Opus 토큰 77% 절감.
14
+ > v3`--quick`(기본, v2.2 호환) + `--thorough`(전체 파이프라인: plan→prd→exec→verify→fix loop).
15
+
16
+ > **[필수] Lead 웹 서치 직접 사용 금지**
17
+ > Lead(Claude Opus)는 brave-search, exa, tavily 등 웹 서치 MCP 도구를 직접 호출하지 마라.
18
+ > 리서치/검색 태스크는 반드시 `scientist` 또는 `document-specialist` 역할의 Codex 워커에 위임하라.
19
+ > Lead가 MCP 검색 도구에 직접 접근 가능하더라도, 위임해야 Claude 토큰을 절약할 수 있다.
15
20
 
16
21
  ## 사용법
17
22
 
18
23
  ```
19
- /tfx-team "인증 리팩터링 + UI 개선 + 보안 리뷰"
20
- /tfx-team --agents codex,gemini "프론트+백엔드"
21
- /tfx-team --tmux "작업" # 레거시 tmux 모드
22
- /tfx-team status
23
- /tfx-team stop
24
+ /tfx-multi "인증 리팩터링 + UI 개선 + 보안 리뷰" # --quick (기본)
25
+ /tfx-multi --thorough "인증 리팩터링 + UI 개선 + 보안 리뷰" # 전체 파이프라인
26
+ /tfx-multi --agents codex,gemini "프론트+백엔드"
27
+ /tfx-multi --tmux "작업" # 레거시 tmux 모드
28
+ /tfx-multi status
29
+ /tfx-multi stop
24
30
  ```
25
31
 
26
32
  ## 실행 워크플로우
@@ -56,11 +62,11 @@ argument-hint: '"작업 설명" | --agents codex,gemini "작업" | --tmux "작
56
62
  ```
57
63
 
58
64
  **제어 커맨드 감지:**
59
- - `status`, `stop`, `kill`, `attach`, `list`, `send` → `Bash("node bin/triflux.mjs team {cmd}")` 직행
65
+ - `status`, `stop`, `kill`, `attach`, `list`, `send` → `Bash("node bin/triflux.mjs multi {cmd}")` 직행
60
66
  (`bin/triflux.mjs` 절대경로는 triflux 패키지 루트 기준)
61
67
  - 그 외 → Phase 2 트리아지
62
68
 
63
- **--tmux 감지:** 입력에 `--tmux`가 포함되면 Phase 3-tmux로 분기.
69
+ **--tmux/--psmux 감지:** 입력에 `--tmux` 또는 `--psmux`가 포함되면 Phase 3-mux로 분기. psmux가 primary (Windows).
64
70
 
65
71
  ### Phase 2: 트리아지 (tfx-auto와 동일)
66
72
 
@@ -96,6 +102,32 @@ Bash("codex exec --full-auto --skip-git-repo-check '다음 작업을 분석하
96
102
 
97
103
  Codex 분류 건너뜀 → Opus가 직접 N개 서브태스크 분해.
98
104
 
105
+ ### Phase 2.5–2.6: 파이프라인 Plan/PRD (`--thorough` 전용)
106
+
107
+ > `--quick`(기본) 모드에서는 이 단계를 건너뛰고 Phase 3으로 직행한다.
108
+ > `--thorough` 모드에서만 실행된다.
109
+
110
+ ```
111
+ [--thorough 모드 감지]
112
+
113
+ Phase 2.5: Plan (Codex architect)
114
+ 1. Hub pipeline 초기화:
115
+ Bash("node hub/bridge.mjs pipeline-advance --team ${teamName} --status plan")
116
+ — 또는 createPipeline(db, teamName) 직접 호출
117
+ 2. Codex architect로 작업 분석 + 접근법 설계:
118
+ bash ~/.claude/scripts/tfx-route.sh architect "${task}" analyze
119
+ 3. 결과를 파이프라인 artifact에 저장:
120
+ pipeline.setArtifact('plan_path', planOutputPath)
121
+ 4. pipeline advance: plan → prd
122
+
123
+ Phase 2.6: PRD (Codex analyst)
124
+ 1. Codex analyst로 수용 기준 확정:
125
+ bash ~/.claude/scripts/tfx-route.sh analyst "${task}" analyze
126
+ 2. 결과를 파이프라인 artifact에 저장:
127
+ pipeline.setArtifact('prd_path', prdOutputPath)
128
+ 3. pipeline advance: prd → exec
129
+ ```
130
+
99
131
  ### Phase 3: Native Teams 실행 (v2.1 개편)
100
132
 
101
133
  트리아지 결과를 Claude Code 네이티브 Agent Teams로 실행한다.
@@ -107,7 +139,7 @@ teamName = "tfx-" + Date.now().toString(36).slice(-6)
107
139
 
108
140
  TeamCreate({
109
141
  team_name: teamName,
110
- description: "tfx-team: {원본 작업 요약}"
142
+ description: "tfx-multi: {원본 작업 요약}"
111
143
  })
112
144
  ```
113
145
 
@@ -165,7 +197,22 @@ status는 "completed"만 사용. 실패 여부는 `metadata.result`로 구분.
165
197
  > Windows 호환 경로, 타임아웃, 후처리(토큰 추적/이슈 로깅)가 모두 누락된다.
166
198
  > 반드시 `bash ~/.claude/scripts/tfx-route.sh {role} '{subtask}' {mcp_profile}`을 통해 실행해야 한다.
167
199
 
168
- **핵심 차이 vs v2:** 프롬프트 ~100 토큰 (v2의 ~500), task claim/complete/report는 tfx-route.sh Hub bridge가 수행.
200
+ **Bash timeout 동적 상속:** Bash timeout은 tfx-route.sh의 role/profile별 timeout + 60초 여유를 ms로 변환하여 동적 상속한다. `getRouteTimeout(role, mcpProfile)` 기준: analyze/review 프로필 또는 architect/analyst 역할은 3600초, 외 기본 1080초(18분).
201
+
202
+ **핵심 차이 vs v2:** 프롬프트 ~100 토큰 (v2의 ~500), task claim/complete/report는 tfx-route.sh가 Named Pipe(우선)/HTTP(fallback) 경유로 수행.
203
+
204
+ #### 인터럽트 프로토콜
205
+
206
+ 워커가 Bash 실행 전에 SendMessage로 시작을 보고하면 턴 경계가 생겨 리드가 방향 전환 메시지를 보낼 수 있다.
207
+
208
+ ```
209
+ 1. TaskUpdate(taskId, status: in_progress) — task claim
210
+ 2. SendMessage(to: team-lead, "작업 시작: {agentName}") — 시작 보고 (턴 경계 생성)
211
+ 3. Bash(command: tfx-route.sh ..., timeout: {bashTimeoutMs}) — 1회 실행
212
+ 4. TaskUpdate(status: completed, metadata: {result}) + SendMessage → 종료
213
+ ```
214
+
215
+ 리드는 워커의 Step 2 시점에 턴 경계를 인식하고, 필요 시 방향 전환/중단 메시지를 보낼 수 있다.
169
216
 
170
217
  `tfx-route.sh` 팀 통합 동작(이미 구현됨, `TFX_TEAM_*` 기반):
171
218
  - `TFX_TEAM_NAME`: 팀 식별자
@@ -173,11 +220,12 @@ status는 "completed"만 사용. 실패 여부는 `metadata.result`로 구분.
173
220
  - `TFX_TEAM_AGENT_NAME`: 워커 표기 이름
174
221
  - `TFX_TEAM_LEAD_NAME`: 리드 수신자 이름 (기본 `team-lead`)
175
222
 
176
- Bridge 연동:
177
- - 실행 시작`POST /bridge/team/task-update`로 `claim + in_progress`
178
- - 실행 종료 `POST /bridge/team/task-update`로 `completed|failed`
179
- - 리드 보고 `POST /bridge/team/send-message`
180
- - 이벤트 채널 `POST /bridge/result` (`topic=task.result`) 발행
223
+ Hub 통신 (Named Pipe 우선, HTTP fallback):
224
+ - `bridge.mjs`가 Named Pipe(`\\.\pipe\triflux-{pid}`) 우선 연결, 실패 HTTP `/bridge/*` fallback
225
+ - 실행 시작: `node hub/bridge.mjs team-task-update --team {name} --task-id {id} --claim --status in_progress`
226
+ - 실행 종료: `node hub/bridge.mjs team-task-update --team {name} --task-id {id} --status completed|failed`
227
+ - 리드 보고: `node hub/bridge.mjs team-send-message --team {name} --from {agent} --to team-lead --text "..."`
228
+ - 결과 발행: `node hub/bridge.mjs result --agent {id} --topic task.result --file {output}`
181
229
 
182
230
  #### Step 3d: claude 타입만 Agent 직접 실행
183
231
 
@@ -207,8 +255,38 @@ Agent({
207
255
  ```
208
256
  "팀 '{teamName}' 생성 완료.
209
257
  Codex/Gemini 워커가 슬림 래퍼 Agent로 네비게이션에 등록되었습니다.
210
- Shift+Down으로 다음 워커 (마지막→리드 wrap), Shift+Tab으로 이전 워커 전환이 가능합니다.
211
- (Shift+Up은 Claude Code 미지원 — 대부분 터미널에서 scroll-up으로 먹힘)"
258
+ Shift+Down으로 다음 워커로 전환 (마지막→리드 wrap). Shift+Tab으로 이전 워커 전환."
259
+ ```
260
+
261
+ ### Phase 3.5–3.7: Verify/Fix Loop (`--thorough` 전용)
262
+
263
+ > `--quick`(기본) 모드에서는 이 단계를 건너뛰고 Phase 4로 직행한다.
264
+ > `--thorough` 모드에서만 실행된다.
265
+
266
+ ```
267
+ Phase 3.5: Verify (Codex review)
268
+ 1. pipeline advance: exec → verify
269
+ 2. Codex verifier로 결과 검증:
270
+ bash ~/.claude/scripts/tfx-route.sh verifier "결과 검증: ${task}" review
271
+ — verifier는 Codex --profile thorough review로 실행됨
272
+ 3. 검증 결과를 파이프라인 artifact에 저장:
273
+ pipeline.setArtifact('verify_report', verifyOutputPath)
274
+ 4. 통과 → pipeline advance: verify → complete → Phase 5 (cleanup)
275
+ 5. 실패 → Phase 3.6
276
+
277
+ Phase 3.6: Fix (Codex executor, max 3회)
278
+ 1. pipeline advance: verify → fix
279
+ — fix_attempt 자동 증가, fix_max(3) 초과 시 전이 거부
280
+ 2. fix_attempt > fix_max → Phase 3.7 (ralph loop) 또는 failed 보고 → Phase 5
281
+ 3. Codex executor로 실패 항목 수정:
282
+ bash ~/.claude/scripts/tfx-route.sh executor "실패 항목 수정: ${failedItems}" implement
283
+ 4. pipeline advance: fix → exec (재실행)
284
+ 5. → Phase 3 (exec) → Phase 3.5 (verify) 재실행
285
+
286
+ Phase 3.7: Ralph Loop (fix 3회 초과 시)
287
+ 1. ralph_iteration 증가 (pipeline.restart())
288
+ 2. ralph_iteration > ralph_max(10) → 최종 failed → Phase 5
289
+ 3. fix_attempt 리셋, 전체 파이프라인 재시작 (Phase 2.5 plan부터)
212
290
  ```
213
291
 
214
292
  ### Phase 4: 결과 수집 (truth source = team_task_list)
@@ -217,17 +295,17 @@ Shift+Down으로 다음 워커 (마지막→리드 wrap), Shift+Tab으로 이전
217
295
  2. `team_task_list`를 최종 truth source로 조회한다.
218
296
 
219
297
  ```bash
220
- Bash("curl -sf http://127.0.0.1:27888/bridge/team/task-list -H \"Content-Type: application/json\" -d \"{\\\"team_name\\\":\\\"${teamName}\\\"}\"")
298
+ Bash("node hub/bridge.mjs team-task-list --team ${teamName}")
221
299
  ```
222
300
 
223
301
  3. `completed` 상태이지만 `metadata.result == "failed"`인 task가 있으면 Claude fallback으로 재시도한다.
224
302
  4. 재시도 후 다시 `team_task_list`를 조회해 최종 상태를 확정한다.
225
- 5. `send-message`와 `/bridge/result(task.result)` 이벤트는 진행 관찰 채널로 사용하고, 최종 판정은 반드시 `team_task_list` 기준으로 한다.
226
- 6. Hub bridge의 `task-update`에서는 `status: "failed"`를 그대로 사용한다 (Hub API는 자체 상태 관리). Claude Code `TaskUpdate`만 `"completed"` + `metadata.result`로 구분한다.
303
+ 5. `send-message`와 `result(task.result)` 이벤트는 진행 관찰 채널로 사용하고, 최종 판정은 반드시 `team_task_list` 기준으로 한다.
304
+ 6. Hub `task-update`에서는 `status: "failed"`를 그대로 사용한다 (Hub API는 자체 상태 관리). Claude Code `TaskUpdate`만 `"completed"` + `metadata.result`로 구분한다.
227
305
 
228
306
  종합 보고서 예시:
229
307
  ```markdown
230
- ## tfx-team 실행 결과
308
+ ## tfx-multi 실행 결과
231
309
 
232
310
  | # | Worker | CLI | 작업 | 상태 |
233
311
  |---|--------|-----|------|------|
@@ -253,9 +331,12 @@ Bash("curl -sf http://127.0.0.1:27888/bridge/team/task-list -H \"Content-Type: a
253
331
  ```
254
332
  5. 종합 보고서를 출력한다.
255
333
 
256
- ### Phase 3-tmux: 레거시 tmux 모드
257
- --tmux 플래그 시 기존 v1 방식으로 실행: Bash("node {PKG_ROOT}/bin/triflux.mjs team --no-attach --agents {agents} \\\"{task}\\\"")
258
- 이후 사용자에게 tmux 세션 연결 안내.
334
+ ### Phase 3-mux: 레거시 psmux/tmux 모드
335
+ `--tmux` 또는 `--psmux` 플래그 시 pane 기반 실행. `detectMultiplexer()`가 psmux tmux → wsl-tmux git-bash-tmux 순으로 자동 감지.
336
+ Windows에서는 **psmux가 1순위** (ADR-001).
337
+
338
+ Bash("node {PKG_ROOT}/bin/triflux.mjs multi --no-attach --agents {agents} \\\"{task}\\\"")
339
+ 이후 사용자에게 세션 연결 안내.
259
340
 
260
341
  ## 에이전트 매핑
261
342
  > 에이전트 매핑: codex/gemini → tfx-route.sh, claude → Agent(subagent_type) 직접 실행. 상세는 Phase 3c/3d 참조.
@@ -265,31 +346,33 @@ Bash("curl -sf http://127.0.0.1:27888/bridge/team/task-list -H \"Content-Type: a
265
346
  - **CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1** — settings.json env에 설정 (`tfx setup`이 자동 설정)
266
347
  - **codex/gemini CLI** — 해당 에이전트 사용 시
267
348
  - **tfx setup** — tfx-route.sh 동기화 + AGENT_TEAMS 자동 설정 (사전 실행 권장)
268
- - **Hub bridge 활성 상태** — 기본 `http://127.0.0.1:27888` (`/bridge/team/*`, `/bridge/result` 사용)
349
+ - **Hub 활성 상태** — Named Pipe(`\\.\pipe\triflux-{pid}`) 우선, HTTP `127.0.0.1:27888` fallback. `bridge.mjs`가 자동 선택. Hub 미실행 시 nativeProxy fallback.
350
+ - **멀티플렉서** — psmux(Windows 1순위) / tmux / wsl-tmux / git-bash-tmux 자동 감지 (`--tmux`/`--psmux` 모드)
269
351
  - **출력 정책** — preflight는 비동기/요약 출력이 기본이며, 실패 시에만 상세 출력
270
352
 
271
353
  ## 에러 처리
272
354
 
273
355
  | 에러 | 처리 |
274
356
  |------|------|
275
- | TeamCreate 실패 / Agent Teams 비활성 | `--tmux` 폴백 (Phase 3-tmux로 전환) |
357
+ | TeamCreate 실패 / Agent Teams 비활성 | `--psmux/--tmux` 폴백 (Phase 3-mux로 전환) |
276
358
  | tfx-route.sh 없음 | `tfx setup` 실행 안내 |
277
359
  | CLI 미설치 (codex/gemini) | 해당 서브태스크를 claude 워커로 대체 |
278
360
  | Codex 분류 실패 | Opus 직접 분류+분해 |
279
361
  | Bash 실행 실패 (Lead) | task를 `completed` + `metadata.result: "failed"`로 마킹 후 Claude fallback 재시도 |
280
- | `team_task_list` 조회 실패 | `/bridge/result`/stdout로 임시 관찰 후 bridge 복구 뒤 상태 재검증 |
362
+ | `team_task_list` 조회 실패 | Named Pipe/stdout로 임시 관찰 후 Hub 복구 뒤 상태 재검증 |
281
363
  | claude fallback 실패 | 실패 task 목록/원인 요약 후 사용자 승인 대기 |
282
364
 
283
365
  > **[중요] TaskUpdate 상태값 제약:** Claude Code API는 `pending`, `in_progress`, `completed`, `deleted`만 지원한다.
284
366
  > `failed` 상태는 존재하지 않으므로 절대 사용하지 마라. 실패는 `status: "completed"` + `metadata: {result: "failed"}`로 표현한다.
285
- > Hub bridge API(`/bridge/team/task-update`)는 자체 상태 관리이므로 `"failed"` 사용 가능.
367
+ > Hub API(`bridge.mjs team-task-update`)는 자체 상태 관리이므로 `"failed"` 사용 가능.
286
368
 
287
369
  ## 관련
288
370
 
289
371
  | 항목 | 설명 |
290
372
  |------|------|
291
- | `scripts/tfx-route.sh` | 팀 통합 라우터 (`TFX_TEAM_*`, task claim/complete, send-message, `/bridge/result`) |
373
+ | `scripts/tfx-route.sh` | 팀 통합 라우터 (`TFX_TEAM_*`, task claim/complete, send-message, Named Pipe/HTTP bridge) |
292
374
  | `hub/team/native.mjs` | Native Teams 래퍼 (프롬프트 템플릿, 팀 설정 빌더) |
293
375
  | `hub/team/cli.mjs` | tmux 팀 CLI (`--tmux` 레거시 모드) |
376
+ | `hub/pipeline/` | 파이프라인 상태 기계 (transitions, state, index) — `--thorough` 모드 |
294
377
  | `tfx-auto` | one-shot 실행 오케스트레이터 (병행 유지) |
295
378
  | `tfx-hub` | MCP 메시지 버스 관리 (tmux 모드용) |