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/bin/triflux.mjs +1516 -1386
- package/hooks/hooks.json +22 -0
- package/hooks/keyword-rules.json +4 -4
- package/hooks/pipeline-stop.mjs +54 -0
- package/hub/bridge.mjs +120 -13
- package/hub/pipe.mjs +23 -0
- package/hub/pipeline/index.mjs +121 -0
- package/hub/pipeline/state.mjs +164 -0
- package/hub/pipeline/transitions.mjs +114 -0
- package/hub/router.mjs +322 -1
- package/hub/schema.sql +49 -2
- package/hub/server.mjs +173 -8
- package/hub/store.mjs +259 -1
- package/hub/team/cli-team-control.mjs +381 -381
- package/hub/team/cli-team-start.mjs +474 -470
- package/hub/team/cli-team-status.mjs +238 -238
- package/hub/team/cli.mjs +86 -86
- package/hub/team/native.mjs +144 -6
- package/hub/team/nativeProxy.mjs +51 -38
- package/hub/team/orchestrator.mjs +15 -20
- package/hub/team/pane.mjs +101 -90
- package/hub/team/psmux.mjs +721 -72
- package/hub/team/session.mjs +450 -450
- package/hub/tools.mjs +223 -63
- package/hub/workers/delegator-mcp.mjs +900 -0
- package/hub/workers/factory.mjs +3 -0
- package/hub/workers/interface.mjs +2 -2
- package/hud/hud-qos-status.mjs +89 -144
- package/package.json +1 -1
- package/scripts/__tests__/keyword-detector.test.mjs +11 -11
- package/scripts/__tests__/smoke.test.mjs +34 -0
- package/scripts/hub-ensure.mjs +21 -3
- package/scripts/preflight-cache.mjs +72 -0
- package/scripts/setup.mjs +23 -11
- package/scripts/tfx-route.sh +74 -15
- package/skills/{tfx-team → tfx-multi}/SKILL.md +115 -32
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.
|
|
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", "
|
|
60
|
-
dst: join(CLAUDE_DIR, "scripts", "hub", "workers", "
|
|
61
|
-
label: "hub/workers/
|
|
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"),
|
package/scripts/tfx-route.sh
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
|
-
# tfx-route.sh v2.
|
|
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.
|
|
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="
|
|
230
|
-
|
|
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
|
|
416
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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-
|
|
2
|
+
name: tfx-multi
|
|
3
3
|
description: 멀티-CLI 팀 모드. Claude Native Agent Teams + Codex/Gemini 멀티모델 오케스트레이션.
|
|
4
4
|
triggers:
|
|
5
|
-
- tfx-
|
|
5
|
+
- tfx-multi
|
|
6
6
|
argument-hint: '"작업 설명" | --agents codex,gemini "작업" | --tmux "작업" | status | stop'
|
|
7
7
|
---
|
|
8
8
|
|
|
9
|
-
# tfx-
|
|
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
|
-
>
|
|
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-
|
|
20
|
-
/tfx-
|
|
21
|
-
/tfx-
|
|
22
|
-
/tfx-
|
|
23
|
-
/tfx-
|
|
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
|
|
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-
|
|
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-
|
|
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
|
-
|
|
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
|
-
|
|
177
|
-
-
|
|
178
|
-
- 실행
|
|
179
|
-
-
|
|
180
|
-
-
|
|
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으로 다음
|
|
211
|
-
|
|
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("
|
|
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`와
|
|
226
|
-
6. Hub
|
|
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-
|
|
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-
|
|
257
|
-
|
|
258
|
-
|
|
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
|
|
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-
|
|
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` 조회 실패 |
|
|
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
|
|
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,
|
|
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 모드용) |
|