triflux 7.5.1 → 8.2.1
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 +40 -1
- package/hub/lib/process-utils.mjs +86 -0
- package/hub/server.mjs +48 -1
- package/hub/team/ansi.mjs +161 -19
- package/hub/team/backend.mjs +1 -1
- package/hub/team/cli/commands/start/index.mjs +3 -2
- package/hub/team/cli/commands/start/parse-args.mjs +9 -0
- package/hub/team/cli/commands/start/start-headless.mjs +6 -3
- package/hub/team/cli/help.mjs +2 -0
- package/hub/team/dashboard-layout.mjs +31 -0
- package/hub/team/headless.mjs +146 -33
- package/hub/team/psmux.mjs +181 -7
- package/hub/team/tui-viewer.mjs +354 -90
- package/hub/team/tui.mjs +856 -67
- package/package.json +1 -1
- package/scripts/remote-spawn.mjs +723 -85
- package/scripts/tfx-route.sh +17 -8
- package/skills/remote-spawn/SKILL.md +173 -31
- package/skills/remote-spawn/references/hosts.json +16 -0
package/scripts/tfx-route.sh
CHANGED
|
@@ -29,6 +29,15 @@ VERSION="2.5"
|
|
|
29
29
|
|
|
30
30
|
set -euo pipefail
|
|
31
31
|
|
|
32
|
+
# ── timeout 명령 호환성 — Windows에서 TIMEOUT.exe 대신 Git Bash coreutils timeout 사용 ──
|
|
33
|
+
if command -v /usr/bin/timeout >/dev/null 2>&1; then
|
|
34
|
+
TIMEOUT_BIN="/usr/bin/timeout"
|
|
35
|
+
elif command -v gtimeout >/dev/null 2>&1; then
|
|
36
|
+
TIMEOUT_BIN="gtimeout" # macOS homebrew
|
|
37
|
+
else
|
|
38
|
+
TIMEOUT_BIN="timeout" # Linux 기본
|
|
39
|
+
fi
|
|
40
|
+
|
|
32
41
|
# ── Async Job 디렉토리 ──
|
|
33
42
|
TFX_JOBS_DIR="${TMPDIR:-/tmp}/tfx-jobs"
|
|
34
43
|
|
|
@@ -1120,9 +1129,9 @@ run_stream_worker() {
|
|
|
1120
1129
|
)
|
|
1121
1130
|
|
|
1122
1131
|
if [[ "$use_tee_flag" == "true" ]]; then
|
|
1123
|
-
printf '%s' "$prompt" |
|
|
1132
|
+
printf '%s' "$prompt" | "$TIMEOUT_BIN" "$TIMEOUT_SEC" "${worker_cmd[@]}" 2>"$STDERR_LOG" | tee "$STDOUT_LOG" &
|
|
1124
1133
|
else
|
|
1125
|
-
printf '%s' "$prompt" |
|
|
1134
|
+
printf '%s' "$prompt" | "$TIMEOUT_BIN" "$TIMEOUT_SEC" "${worker_cmd[@]}" >"$STDOUT_LOG" 2>"$STDERR_LOG" &
|
|
1126
1135
|
fi
|
|
1127
1136
|
worker_pid=$!
|
|
1128
1137
|
|
|
@@ -1144,9 +1153,9 @@ _gemini_run_once() {
|
|
|
1144
1153
|
local -a g_args=("$@")
|
|
1145
1154
|
|
|
1146
1155
|
if [[ "$use_tee_flag" == "true" ]]; then
|
|
1147
|
-
|
|
1156
|
+
"$TIMEOUT_BIN" "$TIMEOUT_SEC" "$CLI_CMD" "${g_args[@]}" "$prompt" 2>"$STDERR_LOG" | tee "$STDOUT_LOG" &
|
|
1148
1157
|
else
|
|
1149
|
-
|
|
1158
|
+
"$TIMEOUT_BIN" "$TIMEOUT_SEC" "$CLI_CMD" "${g_args[@]}" "$prompt" >"$STDOUT_LOG" 2>"$STDERR_LOG" &
|
|
1150
1159
|
fi
|
|
1151
1160
|
echo "$!"
|
|
1152
1161
|
}
|
|
@@ -1285,9 +1294,9 @@ run_codex_exec() {
|
|
|
1285
1294
|
fi
|
|
1286
1295
|
|
|
1287
1296
|
if [[ "$use_tee_flag" == "true" ]]; then
|
|
1288
|
-
|
|
1297
|
+
"$TIMEOUT_BIN" "$TIMEOUT_SEC" "$CLI_CMD" "${codex_args[@]}" "$prompt" 2>"$STDERR_LOG" | tee "$STDOUT_LOG" &
|
|
1289
1298
|
else
|
|
1290
|
-
|
|
1299
|
+
"$TIMEOUT_BIN" "$TIMEOUT_SEC" "$CLI_CMD" "${codex_args[@]}" "$prompt" >"$STDOUT_LOG" 2>"$STDERR_LOG" &
|
|
1291
1300
|
fi
|
|
1292
1301
|
worker_pid=$!
|
|
1293
1302
|
|
|
@@ -1379,9 +1388,9 @@ run_codex_mcp() {
|
|
|
1379
1388
|
esac
|
|
1380
1389
|
|
|
1381
1390
|
if [[ "$use_tee_flag" == "true" ]]; then
|
|
1382
|
-
|
|
1391
|
+
"$TIMEOUT_BIN" "$TIMEOUT_SEC" "$node_bin" "${mcp_args[@]}" 2>"$STDERR_LOG" | tee "$STDOUT_LOG" &
|
|
1383
1392
|
else
|
|
1384
|
-
|
|
1393
|
+
"$TIMEOUT_BIN" "$TIMEOUT_SEC" "$node_bin" "${mcp_args[@]}" >"$STDOUT_LOG" 2>"$STDERR_LOG" &
|
|
1385
1394
|
fi
|
|
1386
1395
|
worker_pid=$!
|
|
1387
1396
|
|
|
@@ -1,63 +1,205 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: remote-spawn
|
|
3
|
-
description:
|
|
3
|
+
description: >
|
|
4
|
+
원격/로컬 머신에 Claude 세션을 psmux 기반으로 spawn하고 관리합니다.
|
|
5
|
+
자동 핸드오프, 추가 프롬프트 전송, 세션 재부착, 원격 환경 자동 감지를 지원합니다.
|
|
6
|
+
이 스킬은 다음 상황에서 반드시 사용하세요:
|
|
7
|
+
원격 실행, 세션 spawn, 다른 머신에서 작업, 원격 Claude, 세션 전달, 핸드오프 전달,
|
|
8
|
+
원격 세션에 프롬프트 보내기, 세션 목록, 세션 재부착.
|
|
9
|
+
로컬 호스트 별칭이 references/hosts.json에 등록되어 있으면 호스트명 언급만으로도 트리거됩니다.
|
|
4
10
|
triggers:
|
|
5
11
|
- remote-spawn
|
|
6
|
-
argument-hint: "[--host <
|
|
12
|
+
argument-hint: "[--host <name>] [--send <session> <prompt>] [--list] [--attach] <prompt or natural language>"
|
|
7
13
|
---
|
|
8
14
|
|
|
9
|
-
# remote-spawn — 원격/로컬 Claude 세션
|
|
15
|
+
# remote-spawn — 원격/로컬 Claude 세션 관리
|
|
10
16
|
|
|
11
|
-
>
|
|
17
|
+
> psmux 세션 기반으로 Claude를 원격/로컬에서 실행하고 관리합니다.
|
|
18
|
+
> 대화 컨텍스트를 자동으로 핸드오프하고, 자연어로 세션을 제어할 수 있습니다.
|
|
12
19
|
|
|
13
|
-
##
|
|
20
|
+
## 입력 해석
|
|
14
21
|
|
|
22
|
+
사용자 입력을 아래 순서로 매칭한다. 매칭되면 해당 동작 실행.
|
|
23
|
+
|
|
24
|
+
```
|
|
25
|
+
"ultra4에서 보안 리뷰 해" → spawn(host=ultra4, prompt="보안 리뷰 해")
|
|
26
|
+
"세션 목록 보여줘" → list
|
|
27
|
+
"ultra4 세션에 테스트도 해달라고 전달해" → send(session=auto-detect, prompt="테스트도 해달라고")
|
|
28
|
+
"아까 그 세션 다시 열어" → attach(session=most-recent)
|
|
29
|
+
"로컬에서 리팩터링 이어서" → spawn(local, prompt="리팩터링 이어서")
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
### 호스트 감지
|
|
33
|
+
|
|
34
|
+
1. `--host <name>` 명시 → 그대로 사용
|
|
35
|
+
2. `references/hosts.json` 에 등록된 별칭/키워드 매칭 → 호스트 자동 해석
|
|
36
|
+
3. "원격에서", "다른 머신에서" → hosts.json의 default 호스트 사용
|
|
37
|
+
4. 매칭 없음 + --local 없음 → 사용자에게 "어떤 호스트에서 실행할까요?" 질문
|
|
38
|
+
|
|
39
|
+
`references/hosts.json`이 없으면 --host를 명시적으로 요구한다.
|
|
40
|
+
|
|
41
|
+
### 동작 분류
|
|
42
|
+
|
|
43
|
+
| 패턴 | 동작 | 설명 |
|
|
44
|
+
|------|------|------|
|
|
45
|
+
| 호스트 + 프롬프트 | **spawn** | 원격 Claude 세션 생성 |
|
|
46
|
+
| --local / "로컬에서" | **spawn local** | 로컬 Claude 세션 생성 |
|
|
47
|
+
| "전달해", "보내줘", --send | **send** | 기존 세션에 프롬프트 전송 |
|
|
48
|
+
| "목록", "세션 리스트", --list | **list** | 활성 세션 목록 |
|
|
49
|
+
| "다시 열어", "재부착", --attach | **attach** | WT 탭에 세션 재부착 |
|
|
50
|
+
| "환경 확인", --probe | **probe** | 원격 환경 프로브 (강제 갱신) |
|
|
51
|
+
|
|
52
|
+
## 실행 워크플로우
|
|
53
|
+
|
|
54
|
+
### spawn — 세션 생성 (핵심)
|
|
55
|
+
|
|
56
|
+
spawn은 3단계로 동작한다:
|
|
57
|
+
|
|
58
|
+
**1단계: 핸드오프 생성 (자동)**
|
|
59
|
+
|
|
60
|
+
사용자가 프롬프트만 준 경우, 현재 대화 맥락에서 핸드오프를 자동 생성한다.
|
|
61
|
+
핸드오프는 원격 Claude가 작업을 이해하는 데 필요한 최소 컨텍스트다.
|
|
62
|
+
|
|
63
|
+
핸드오프 구조:
|
|
15
64
|
```
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
65
|
+
## 작업 컨텍스트
|
|
66
|
+
- 현재 프로젝트: {프로젝트 경로}
|
|
67
|
+
- 작업 중인 파일: {최근 수정 파일 목록}
|
|
68
|
+
- 진행 상황: {현재 대화에서 완료한 것}
|
|
69
|
+
|
|
70
|
+
## 태스크
|
|
71
|
+
{사용자 프롬프트 또는 추출된 작업 지시}
|
|
72
|
+
|
|
73
|
+
## 참고
|
|
74
|
+
- {관련 결정 사항이나 제약}
|
|
19
75
|
```
|
|
20
76
|
|
|
21
|
-
|
|
77
|
+
핸드오프 생성 후 임시 파일에 저장: `.omc/handoff-{uuid8}.md`
|
|
22
78
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
3. **세션 Spawn**: `scripts/remote-spawn.mjs` 호출
|
|
79
|
+
사용자가 명시적으로 `--handoff <file>` 을 준 경우, 자동 생성 대신 해당 파일 사용.
|
|
80
|
+
사용자가 `/mp`로 생성한 핸드오프가 있으면 그것을 우선 사용.
|
|
26
81
|
|
|
27
|
-
|
|
82
|
+
**2단계: 환경 확인**
|
|
28
83
|
|
|
29
|
-
|
|
84
|
+
원격 호스트의 프로브 결과를 확인한다. 캐시가 있으면 캐시 사용.
|
|
30
85
|
|
|
31
86
|
```bash
|
|
32
|
-
node scripts/remote-spawn.mjs --
|
|
87
|
+
node scripts/remote-spawn.mjs --probe {host}
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
프로브 결과에 따른 분기:
|
|
91
|
+
|
|
92
|
+
| claudePath | 동작 |
|
|
93
|
+
|------------|------|
|
|
94
|
+
| 유효한 경로 | 정상 진행 |
|
|
95
|
+
| null | 설치 안내 출력 후 사용자 확인 대기 |
|
|
96
|
+
|
|
97
|
+
**claude 미설치 시 안내 메시지:**
|
|
98
|
+
|
|
99
|
+
```
|
|
100
|
+
{host}에 Claude Code가 설치되어 있지 않습니다.
|
|
101
|
+
|
|
102
|
+
설치 방법:
|
|
103
|
+
macOS/Linux: npm install -g @anthropic-ai/claude-code
|
|
104
|
+
Windows: winget install Anthropic.ClaudeCode
|
|
105
|
+
|
|
106
|
+
설치 후 `--probe {host}` 로 환경을 갱신하세요.
|
|
107
|
+
또는 이 호스트에서 다른 CLI(codex, gemini)로 작업하시겠습니까?
|
|
33
108
|
```
|
|
34
|
-
- 새 WT 탭에서 Claude 실행
|
|
35
|
-
- `--dir` 미지정 시 현재 디렉토리
|
|
36
109
|
|
|
37
|
-
|
|
110
|
+
**3단계: 세션 실행**
|
|
38
111
|
|
|
39
112
|
```bash
|
|
40
|
-
node scripts/remote-spawn.mjs --host
|
|
113
|
+
node scripts/remote-spawn.mjs --host {host} --dir {dir} --prompt {prompt} --handoff {handoff_file}
|
|
41
114
|
```
|
|
42
|
-
- WT 탭에서 SSH 세션 열고 원격 Claude 실행
|
|
43
|
-
- `--dir` 미지정 시 `~`
|
|
44
|
-
- 원격 Claude는 자기 환경(CLAUDE.md, 훅, MCP)을 이미 알고 있으므로 태스크만 전달
|
|
45
115
|
|
|
46
|
-
|
|
116
|
+
실행 후 세션 이름을 사용자에게 알려준다:
|
|
117
|
+
```
|
|
118
|
+
spawned: tfx-spawn-ultra4-a1b2c3d4
|
|
119
|
+
WT 탭에서 Claude@ultra4 세션이 열립니다.
|
|
120
|
+
추가 프롬프트: /remote-spawn --send tfx-spawn-ultra4-a1b2c3d4 "다음 작업"
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
### send — 프롬프트 전송
|
|
47
124
|
|
|
48
|
-
|
|
125
|
+
사용자가 세션 이름을 명시하지 않으면, 해당 호스트의 가장 최근 세션을 자동 감지한다.
|
|
49
126
|
|
|
50
|
-
|
|
51
|
-
|
|
127
|
+
```bash
|
|
128
|
+
# 세션 이름 명시
|
|
129
|
+
node scripts/remote-spawn.mjs --send tfx-spawn-ultra4-a1b2c3d4 --prompt "{prompt}"
|
|
130
|
+
|
|
131
|
+
# 호스트명으로 자동 감지
|
|
132
|
+
node scripts/remote-spawn.mjs --list # tfx-spawn-ultra4-* 필터링
|
|
133
|
+
# → 가장 최근 세션에 전송
|
|
134
|
+
node scripts/remote-spawn.mjs --send {detected_session} --prompt "{prompt}"
|
|
135
|
+
```
|
|
52
136
|
|
|
53
|
-
|
|
137
|
+
### list — 세션 목록
|
|
54
138
|
|
|
55
139
|
```bash
|
|
56
|
-
node scripts/remote-spawn.mjs --
|
|
140
|
+
node scripts/remote-spawn.mjs --list
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
결과를 표 형태로 정리해서 보여준다:
|
|
144
|
+
```
|
|
145
|
+
| 세션 | 호스트 | 상태 |
|
|
146
|
+
|------|--------|------|
|
|
147
|
+
| tfx-spawn-ultra4-a1b2c3d4 | ultra4 | active |
|
|
148
|
+
| tfx-spawn-m2-e5f6g7h8 | m2 | active |
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
### attach — 재부착
|
|
152
|
+
|
|
153
|
+
```bash
|
|
154
|
+
node scripts/remote-spawn.mjs --attach {session_name}
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
세션 이름 미지정 시 가장 최근 세션을 사용한다.
|
|
158
|
+
|
|
159
|
+
### probe — 환경 확인
|
|
160
|
+
|
|
161
|
+
```bash
|
|
162
|
+
node scripts/remote-spawn.mjs --probe {host}
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
결과를 사람이 읽기 좋게 정리:
|
|
166
|
+
```
|
|
167
|
+
ultra4 환경:
|
|
168
|
+
OS: Windows (win32)
|
|
169
|
+
Shell: pwsh
|
|
170
|
+
Home: C:\Users\SSAFY
|
|
171
|
+
Claude: C:\Users\SSAFY\.local\bin\claude.exe
|
|
57
172
|
```
|
|
58
173
|
|
|
59
174
|
## 전제 조건
|
|
60
175
|
|
|
61
|
-
-
|
|
62
|
-
-
|
|
63
|
-
-
|
|
176
|
+
- **psmux** 설치 (권장, 전체 기능). 미설치 시 기존 WT+SSH fallback.
|
|
177
|
+
- `remoteControlAtStartup: true` 설정 (`triflux setup` 자동)
|
|
178
|
+
- 원격 호스트: SSH config 등록 + Claude Code 설치
|
|
179
|
+
- 로컬: Windows Terminal
|
|
180
|
+
|
|
181
|
+
## 호스트 설정
|
|
182
|
+
|
|
183
|
+
`references/hosts.json`에 개인 호스트 별칭을 등록한다.
|
|
184
|
+
이 파일은 프로젝트에 커밋하지 않고 로컬에서만 관리한다 (.gitignore 추가).
|
|
185
|
+
|
|
186
|
+
```json
|
|
187
|
+
{
|
|
188
|
+
"hosts": {
|
|
189
|
+
"ultra4": {
|
|
190
|
+
"description": "Windows 데스크탑",
|
|
191
|
+
"aliases": ["울트라", "데스크탑"],
|
|
192
|
+
"default_dir": "~/Desktop/Projects"
|
|
193
|
+
},
|
|
194
|
+
"m2": {
|
|
195
|
+
"description": "MacBook Pro",
|
|
196
|
+
"aliases": ["맥북", "맥"],
|
|
197
|
+
"default_dir": "~/projects"
|
|
198
|
+
}
|
|
199
|
+
},
|
|
200
|
+
"default_host": "ultra4",
|
|
201
|
+
"triggers": ["원격에서", "다른 머신에서", "다른 컴퓨터에서"]
|
|
202
|
+
}
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
이 파일이 없으면 호스트 자동 감지가 비활성화되고, --host를 명시해야 한다.
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{
|
|
2
|
+
"hosts": {
|
|
3
|
+
"ultra4": {
|
|
4
|
+
"description": "Windows 데스크탑 (SSAFY)",
|
|
5
|
+
"aliases": ["울트라", "데스크탑"],
|
|
6
|
+
"default_dir": "~/Desktop/Projects"
|
|
7
|
+
},
|
|
8
|
+
"m2": {
|
|
9
|
+
"description": "MacBook Pro",
|
|
10
|
+
"aliases": ["맥북", "맥"],
|
|
11
|
+
"default_dir": "~/projects"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"default_host": "ultra4",
|
|
15
|
+
"triggers": ["원격에서", "다른 머신에서", "다른 컴퓨터에서"]
|
|
16
|
+
}
|