triflux 10.9.12 → 10.9.13
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 +55 -0
- package/hub/server.mjs +19 -3
- package/hub/team/git-preflight.mjs +286 -0
- package/hub/team/swarm-intent.mjs +216 -0
- package/hub/team/swarm-locks.mjs +65 -9
- package/hub/team/swarm-reconciler.mjs +80 -0
- package/hub/team/synapse-cli.mjs +207 -0
- package/hub/team/synapse-registry.mjs +275 -0
- package/hub/team/worktree-lifecycle.mjs +48 -1
- package/hub/workers/gemini-worker.mjs +5 -1
- package/package.json +1 -1
- package/scripts/__tests__/tfx-doctor-diagnose.test.mjs +9 -0
- package/scripts/doctor-diagnose.mjs +65 -1
- package/scripts/headless-guard.mjs +2 -11
- package/scripts/lib/process-utils.mjs +26 -0
- package/scripts/session-stale-cleanup.mjs +1 -9
- package/scripts/tfx-route-worker.mjs +21 -1
- package/scripts/tfx-route.sh +37 -8
package/scripts/tfx-route.sh
CHANGED
|
@@ -88,14 +88,29 @@ cleanup_workers() {
|
|
|
88
88
|
}
|
|
89
89
|
|
|
90
90
|
# ── config.toml sandbox/approval_mode 감지 ──
|
|
91
|
-
# config.toml에 이미 설정되어 있으면 CLI 플래그 중복 시 Codex가 에러를
|
|
91
|
+
# config.toml에 이미 설정되어 있으면 CLI 플래그 중복 시 Codex가 에러를 던짐.
|
|
92
|
+
# 단, [mcp_servers.*.tools.*] 섹션 내부의 approval_mode는 tool 단위 승인 설정으로
|
|
93
|
+
# top-level sandbox/approval_mode와 의미가 다르다. 이 값이 "approve"이면
|
|
94
|
+
# codex exec이 non-TTY subprocess에서 승인 대기로 stall하므로 감지 대상에서 제외.
|
|
95
|
+
# (refs: tellang/triflux#66, Yeachan-Heo/oh-my-codex#1478)
|
|
92
96
|
_CODEX_CONFIG="${HOME}/.codex/config.toml"
|
|
93
97
|
_CODEX_HAS_SANDBOX=""
|
|
94
|
-
if [[ -f "$_CODEX_CONFIG" ]] &&
|
|
98
|
+
if [[ -f "$_CODEX_CONFIG" ]] && awk '
|
|
99
|
+
/^\[{1,2}mcp_servers\..*\.tools\./ { in_mcp_tool=1; next }
|
|
100
|
+
/^\[/ { in_mcp_tool=0; next }
|
|
101
|
+
!in_mcp_tool && /^[[:space:]]*(sandbox|approval_mode)[[:space:]]*=/ { found=1; exit }
|
|
102
|
+
END { exit !found }
|
|
103
|
+
' "$_CODEX_CONFIG" 2>/dev/null; then
|
|
95
104
|
_CODEX_HAS_SANDBOX="1"
|
|
96
105
|
fi
|
|
97
106
|
|
|
98
107
|
build_codex_base() {
|
|
108
|
+
# Escape hatch: TFX_FORCE_CODEX_BYPASS=1이면 감지 결과와 무관하게 항상 bypass.
|
|
109
|
+
# CI/디버깅/긴급 상황에서 config.toml 상태에 상관없이 non-TTY codex exec를 보장.
|
|
110
|
+
if [[ "${TFX_FORCE_CODEX_BYPASS:-0}" == "1" ]]; then
|
|
111
|
+
echo "--dangerously-bypass-approvals-and-sandbox --skip-git-repo-check"
|
|
112
|
+
return
|
|
113
|
+
fi
|
|
99
114
|
if [[ -n "$_CODEX_HAS_SANDBOX" ]]; then
|
|
100
115
|
echo "--skip-git-repo-check"
|
|
101
116
|
else
|
|
@@ -897,8 +912,9 @@ TFX_CODEX_TRANSPORT="${TFX_CODEX_TRANSPORT:-auto}"
|
|
|
897
912
|
# Preflight 캐시 일괄 로드 — CLI/Hub 가용성 + Codex 요금제를 환경변수로 내보냄
|
|
898
913
|
# 하위 프로세스(스킬 포함)가 TFX_CODEX_OK, TFX_GEMINI_OK, TFX_HUB_OK로 즉시 참조 가능
|
|
899
914
|
if [[ -z "${TFX_PREFLIGHT_LOADED:-}" ]]; then
|
|
900
|
-
# eval 제거 —
|
|
901
|
-
|
|
915
|
+
# eval 제거 — \x1e (ASCII 30, Record Separator) delimited read로 인젝션 위험 차단
|
|
916
|
+
# F05: `|`에서 `\x1e`로 변경 — 계정 tier/agent 이름 등 값에 `|` 포함 시 필드 분리 오류 방지
|
|
917
|
+
IFS=$'\x1e' read -r _pf_codex _pf_gemini _pf_hub _pf_plan _pf_agents < <(
|
|
902
918
|
"$NODE_BIN" -e '
|
|
903
919
|
try {
|
|
904
920
|
const c = JSON.parse(require("fs").readFileSync(require("path").join(require("os").homedir(),".claude","cache","tfx-preflight.json"),"utf8"));
|
|
@@ -909,8 +925,8 @@ if [[ -z "${TFX_PREFLIGHT_LOADED:-}" ]]; then
|
|
|
909
925
|
(c?.codex_plan?.plan && c.codex_plan.plan !== "unknown" && c.codex_plan.plan !== "api") ? c.codex_plan.plan : "",
|
|
910
926
|
Array.isArray(c?.available_agents) ? c.available_agents.join(",") : ""
|
|
911
927
|
];
|
|
912
|
-
process.stdout.write(parts.join("
|
|
913
|
-
} catch { process.stdout.write("0
|
|
928
|
+
process.stdout.write(parts.join("\x1e"));
|
|
929
|
+
} catch { process.stdout.write("0\x1e0\x1e0\x1e\x1e"); }
|
|
914
930
|
' 2>/dev/null
|
|
915
931
|
) || true
|
|
916
932
|
export TFX_CODEX_OK="${_pf_codex:-0}"
|
|
@@ -1699,7 +1715,14 @@ FALLBACK_EOF
|
|
|
1699
1715
|
|
|
1700
1716
|
run_stream_worker "gemini" "$FULL_PROMPT" "$use_tee" "${gemini_worker_args[@]}" || exit_code=$?
|
|
1701
1717
|
if [[ "$exit_code" -ne 0 && "$exit_code" -ne 124 ]]; then
|
|
1702
|
-
|
|
1718
|
+
# stderr 내용을 fallback 전에 보존하여 디버깅 가능하게 함
|
|
1719
|
+
local gemini_stderr_bytes=0
|
|
1720
|
+
[[ -f "$STDERR_LOG" ]] && gemini_stderr_bytes=$(wc -c < "$STDERR_LOG" 2>/dev/null | tr -d ' ')
|
|
1721
|
+
echo "[tfx-route] Gemini stream wrapper 실패(exit=${exit_code}, stderr=${gemini_stderr_bytes}B). claude-native fallback." >&2
|
|
1722
|
+
if [[ "$gemini_stderr_bytes" -gt 0 ]]; then
|
|
1723
|
+
echo "[tfx-route] Gemini stderr 보존:" >&2
|
|
1724
|
+
tail -c 2048 "$STDERR_LOG" >&2
|
|
1725
|
+
fi
|
|
1703
1726
|
cat > "$STDOUT_LOG" <<EOF
|
|
1704
1727
|
$(emit_claude_native_metadata)
|
|
1705
1728
|
EOF
|
|
@@ -1721,7 +1744,13 @@ EOF
|
|
|
1721
1744
|
|
|
1722
1745
|
run_stream_worker "claude" "$FULL_PROMPT" "$use_tee" "${claude_worker_args[@]}" || exit_code=$?
|
|
1723
1746
|
if [[ "$exit_code" -ne 0 && "$exit_code" -ne 124 ]]; then
|
|
1724
|
-
|
|
1747
|
+
local claude_stderr_bytes=0
|
|
1748
|
+
[[ -f "$STDERR_LOG" ]] && claude_stderr_bytes=$(wc -c < "$STDERR_LOG" 2>/dev/null | tr -d ' ')
|
|
1749
|
+
echo "[tfx-route] Claude stream wrapper 실패(exit=${exit_code}, stderr=${claude_stderr_bytes}B). native metadata로 fallback합니다." >&2
|
|
1750
|
+
if [[ "$claude_stderr_bytes" -gt 0 ]]; then
|
|
1751
|
+
echo "[tfx-route] Claude stderr 보존:" >&2
|
|
1752
|
+
tail -c 2048 "$STDERR_LOG" >&2
|
|
1753
|
+
fi
|
|
1725
1754
|
cat > "$STDOUT_LOG" <<EOF
|
|
1726
1755
|
$(emit_claude_native_metadata)
|
|
1727
1756
|
EOF
|