@triflux/remote 10.1.0 → 10.26.0
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/hub/pipe.mjs +239 -121
- package/hub/public/dashboard.html +61 -0
- package/hub/server.mjs +2179 -709
- package/hub/store-adapter.mjs +59 -26
- package/hub/store.mjs +356 -153
- package/hub/team/agent-map.json +26 -7
- package/hub/team/ansi.mjs +245 -146
- package/hub/team/backend.mjs +78 -17
- package/hub/team/build-worker-prompt.mjs +73 -0
- package/hub/team/check-mcp-hub.mjs +49 -0
- package/hub/team/claude-daemon-control.mjs +1130 -0
- package/hub/team/claude-native-bridge.mjs +1011 -0
- package/hub/team/claude-session-projection.mjs +74 -0
- package/hub/team/cli/commands/attach.mjs +57 -37
- package/hub/team/cli/commands/control.mjs +29 -8
- package/hub/team/cli/commands/debug.mjs +95 -74
- package/hub/team/cli/commands/focus.mjs +80 -53
- package/hub/team/cli/commands/interrupt.mjs +18 -6
- package/hub/team/cli/commands/kill.mjs +16 -5
- package/hub/team/cli/commands/list.mjs +31 -24
- package/hub/team/cli/commands/send.mjs +19 -6
- package/hub/team/cli/commands/start/index.mjs +151 -33
- package/hub/team/cli/commands/start/parse-args.mjs +97 -13
- package/hub/team/cli/commands/start/start-headless.mjs +155 -37
- package/hub/team/cli/commands/start/start-in-process.mjs +50 -40
- package/hub/team/cli/commands/start/start-mux.mjs +122 -73
- package/hub/team/cli/commands/start/start-wt.mjs +86 -69
- package/hub/team/cli/commands/status.mjs +43 -14
- package/hub/team/cli/commands/stop.mjs +11 -4
- package/hub/team/cli/commands/task.mjs +8 -3
- package/hub/team/cli/commands/tasks.mjs +13 -13
- package/hub/team/cli/help.mjs +1 -1
- package/hub/team/cli/index.mjs +2 -2
- package/hub/team/cli/manifest.mjs +38 -8
- package/hub/team/cli/render.mjs +52 -30
- package/hub/team/cli/services/attach-fallback.mjs +74 -54
- package/hub/team/cli/services/hub-client.mjs +44 -16
- package/hub/team/cli/services/member-selector.mjs +37 -30
- package/hub/team/cli/services/native-control.mjs +144 -116
- package/hub/team/cli/services/runtime-mode.mjs +61 -4
- package/hub/team/cli/services/state-store.mjs +66 -9
- package/hub/team/cli/services/task-model.mjs +40 -30
- package/hub/team/codex-review.mjs +521 -0
- package/hub/team/conductor-mesh-bridge.mjs +25 -24
- package/hub/team/conductor-registry.mjs +121 -0
- package/hub/team/conductor.mjs +1379 -671
- package/hub/team/consensus-meta.mjs +176 -0
- package/hub/team/dashboard-anchor.mjs +4 -5
- package/hub/team/dashboard-layout.mjs +3 -1
- package/hub/team/dashboard-open.mjs +20 -118
- package/hub/team/dashboard.mjs +76 -28
- package/hub/team/event-log.mjs +18 -10
- package/hub/team/execution-mode.mjs +256 -0
- package/hub/team/extract-completion-payload.mjs +110 -0
- package/hub/team/git-preflight.mjs +286 -0
- package/hub/team/handoff.mjs +49 -18
- package/hub/team/headless-bridge-session.mjs +17 -0
- package/hub/team/headless.mjs +2213 -1156
- package/hub/team/health-probe.mjs +232 -69
- package/hub/team/interactive-native-launcher.mjs +106 -0
- package/hub/team/interactive-native-worker.mjs +80 -0
- package/hub/team/interactive-tui-transport.mjs +465 -0
- package/hub/team/launcher-template.mjs +49 -17
- package/hub/team/lead-control.mjs +91 -4
- package/hub/team/mcp-selector.mjs +145 -0
- package/hub/team/native-supervisor.mjs +90 -26
- package/hub/team/native.mjs +120 -42
- package/hub/team/nativeProxy.mjs +184 -113
- package/hub/team/notify.mjs +147 -78
- package/hub/team/orchestrator.mjs +173 -161
- package/hub/team/pane.mjs +43 -20
- package/hub/team/process-cleanup.mjs +69 -25
- package/hub/team/psmux.mjs +1022 -281
- package/hub/team/recovery-store.mjs +149 -0
- package/hub/team/remote-probe.mjs +68 -52
- package/hub/team/remote-session.mjs +131 -59
- package/hub/team/remote-watcher.mjs +61 -33
- package/hub/team/retry-state-machine.mjs +336 -0
- package/hub/team/routing.mjs +51 -25
- package/hub/team/runtime-strategy.mjs +200 -0
- package/hub/team/schemas/worker-completion.json +39 -0
- package/hub/team/sentinel-capture.mjs +127 -0
- package/hub/team/session-sync.mjs +153 -6
- package/hub/team/session.mjs +574 -611
- package/hub/team/shared.mjs +13 -13
- package/hub/team/staleState.mjs +72 -30
- package/hub/team/swarm-cli.mjs +390 -0
- package/hub/team/swarm-hypervisor.mjs +1544 -193
- package/hub/team/swarm-intent.mjs +216 -0
- package/hub/team/swarm-locks.mjs +140 -25
- package/hub/team/swarm-planner.mjs +121 -21
- package/hub/team/swarm-preflight.mjs +319 -0
- package/hub/team/swarm-reconciler.mjs +128 -23
- package/hub/team/synapse-cli.mjs +458 -0
- package/hub/team/synapse-http.mjs +60 -0
- package/hub/team/synapse-registry.mjs +329 -0
- package/hub/team/terminal-opener.mjs +216 -0
- package/hub/team/tui-core.mjs +292 -0
- package/hub/team/tui-lite.mjs +237 -148
- package/hub/team/tui-remote-adapter.mjs +18 -34
- package/hub/team/tui-synapse.mjs +223 -0
- package/hub/team/tui-viewer.mjs +108 -48
- package/hub/team/tui-widgets.mjs +262 -0
- package/hub/team/tui.mjs +931 -439
- package/hub/team/worker-completion-validator.mjs +84 -0
- package/hub/team/worker-sandbox.mjs +97 -0
- package/hub/team/worker-signal.mjs +263 -0
- package/hub/team/worker-signal.types.d.ts +52 -0
- package/hub/team/worktree-lifecycle.mjs +517 -63
- package/hub/team/wt-manager.mjs +297 -26
- package/hub/tools.mjs +477 -252
- package/hub/tray.mjs +411 -368
- package/hub/workers/antigravity-route-worker.mjs +169 -0
- package/hub/workers/claude-worker.mjs +162 -118
- package/hub/workers/codex-app-server-worker.mjs +1015 -0
- package/hub/workers/codex-mcp.mjs +724 -507
- package/hub/workers/delegator-mcp.mjs +570 -499
- package/hub/workers/factory.mjs +103 -21
- package/hub/workers/gemini-worker.mjs +126 -284
- package/hub/workers/interface.mjs +24 -2
- package/hub/workers/lib/jsonrpc-stdio.mjs +463 -0
- package/hub/workers/worker-utils.mjs +23 -17
- package/package.json +4 -3
- package/scripts/lib/agent-json.mjs +27 -0
- package/scripts/lib/async.mjs +174 -0
- package/scripts/lib/claudemd-scanner.mjs +223 -0
- package/scripts/lib/cli-agy.mjs +62 -0
- package/scripts/lib/cli-claude.mjs +78 -0
- package/scripts/lib/cli-codex.mjs +199 -0
- package/scripts/lib/cli-gemini.mjs +37 -0
- package/scripts/lib/codex-recovery.sh +50 -0
- package/scripts/lib/context.mjs +67 -0
- package/scripts/lib/cross-review-utils.mjs +59 -0
- package/scripts/lib/doctor-env-checks.mjs +121 -0
- package/scripts/lib/dynamic-route-cli.mjs +107 -0
- package/scripts/lib/env-probe.mjs +269 -0
- package/scripts/lib/env.mjs +14 -0
- package/scripts/lib/gemini-profiles.mjs +119 -0
- package/scripts/lib/handoff.mjs +187 -0
- package/scripts/lib/hook-utils.mjs +16 -0
- package/scripts/lib/hub.mjs +48 -0
- package/scripts/lib/keyword-rules.mjs +195 -0
- package/scripts/lib/logger.mjs +105 -0
- package/scripts/lib/mcp-filter.mjs +883 -0
- package/scripts/lib/mcp-gateway-health-check.mjs +159 -0
- package/scripts/lib/mcp-gateway-servers.mjs +70 -0
- package/scripts/lib/mcp-gateway-wrapper-check.mjs +35 -0
- package/scripts/lib/mcp-guard-engine.mjs +2120 -0
- package/scripts/lib/mcp-health.mjs +773 -0
- package/scripts/lib/mcp-manifest.mjs +89 -0
- package/scripts/lib/mcp-server-catalog.mjs +355 -0
- package/scripts/lib/pid.mjs +63 -0
- package/scripts/lib/process-utils.mjs +26 -0
- package/scripts/lib/psmux-info.mjs +224 -0
- package/scripts/lib/quota.mjs +47 -0
- package/scripts/lib/remote-spawn-transfer.mjs +226 -0
- package/scripts/lib/skill-state.mjs +220 -0
- package/scripts/lib/skill-template.mjs +375 -0
- package/scripts/lib/team.mjs +75 -0
- package/scripts/lib/timeout.mjs +66 -0
- package/scripts/lib/tmp.mjs +26 -0
- package/scripts/lib/toml.mjs +113 -0
|
@@ -1,24 +1,31 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
console.log(
|
|
18
|
-
return;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
1
|
+
import { listSessions } from "../../session.mjs";
|
|
2
|
+
import { AMBER, BOLD, DIM, GREEN, RESET } from "../../shared.mjs";
|
|
3
|
+
import {
|
|
4
|
+
isNativeMode,
|
|
5
|
+
isTeamAlive,
|
|
6
|
+
isWtMode,
|
|
7
|
+
} from "../services/runtime-mode.mjs";
|
|
8
|
+
import { loadTeamState } from "../services/state-store.mjs";
|
|
9
|
+
|
|
10
|
+
export function teamList() {
|
|
11
|
+
const state = loadTeamState();
|
|
12
|
+
if (state && isTeamAlive(state) && (isNativeMode(state) || isWtMode(state))) {
|
|
13
|
+
console.log(`\n ${AMBER}${BOLD}⬡ 팀 세션 목록${RESET}\n`);
|
|
14
|
+
console.log(
|
|
15
|
+
` ${GREEN}●${RESET} ${state.sessionName} ${DIM}(${isNativeMode(state) ? "in-process" : "wt"})${RESET}`,
|
|
16
|
+
);
|
|
17
|
+
console.log("");
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const sessions = listSessions();
|
|
22
|
+
if (!sessions.length) {
|
|
23
|
+
console.log(`\n ${DIM}활성 팀 세션 없음${RESET}\n`);
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
console.log(`\n ${AMBER}${BOLD}⬡ 팀 세션 목록${RESET}\n`);
|
|
28
|
+
for (const session of sessions)
|
|
29
|
+
console.log(` ${GREEN}●${RESET} ${session}`);
|
|
30
|
+
console.log("");
|
|
31
|
+
}
|
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
import { injectPrompt } from "../../pane.mjs";
|
|
2
2
|
import { DIM, RESET, WHITE, YELLOW } from "../../shared.mjs";
|
|
3
|
+
import { ok, warn } from "../render.mjs";
|
|
3
4
|
import { resolveMember } from "../services/member-selector.mjs";
|
|
4
5
|
import { nativeRequest } from "../services/native-control.mjs";
|
|
5
|
-
import {
|
|
6
|
+
import {
|
|
7
|
+
isNativeMode,
|
|
8
|
+
isTeamAlive,
|
|
9
|
+
isWtMode,
|
|
10
|
+
} from "../services/runtime-mode.mjs";
|
|
6
11
|
import { loadTeamState } from "../services/state-store.mjs";
|
|
7
|
-
import { ok, warn } from "../render.mjs";
|
|
8
12
|
|
|
9
13
|
export async function teamSend(args = []) {
|
|
10
14
|
const state = loadTeamState();
|
|
@@ -16,17 +20,26 @@ export async function teamSend(args = []) {
|
|
|
16
20
|
const member = resolveMember(state, args[0]);
|
|
17
21
|
const message = args.slice(1).join(" ");
|
|
18
22
|
if (!member || !message) {
|
|
19
|
-
console.log(
|
|
23
|
+
console.log(
|
|
24
|
+
`\n 사용법: ${WHITE}tfx multi send <lead|이름|번호> "메시지"${RESET}\n`,
|
|
25
|
+
);
|
|
20
26
|
return;
|
|
21
27
|
}
|
|
22
28
|
if (isWtMode(state)) {
|
|
23
|
-
console.log(
|
|
29
|
+
console.log(
|
|
30
|
+
`\n ${YELLOW}⚠${RESET} wt 모드는 pane 프롬프트 자동 주입(send)이 지원되지 않습니다.\n ${DIM}수동 전달: 선택한 pane에 직접 붙여넣으세요.${RESET}\n`,
|
|
31
|
+
);
|
|
24
32
|
return;
|
|
25
33
|
}
|
|
26
34
|
|
|
27
35
|
if (isNativeMode(state)) {
|
|
28
|
-
const result = await nativeRequest(state, "/send", {
|
|
29
|
-
|
|
36
|
+
const result = await nativeRequest(state, "/send", {
|
|
37
|
+
member: member.name,
|
|
38
|
+
text: message,
|
|
39
|
+
});
|
|
40
|
+
(result?.ok ? ok : warn)(
|
|
41
|
+
`${member.name}${result?.ok ? "에 메시지 주입 완료" : " 메시지 주입 실패"}`,
|
|
42
|
+
);
|
|
30
43
|
console.log("");
|
|
31
44
|
return;
|
|
32
45
|
}
|
|
@@ -1,31 +1,62 @@
|
|
|
1
1
|
import { decomposeTask } from "../../../orchestrator.mjs";
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
2
|
+
import {
|
|
3
|
+
AMBER,
|
|
4
|
+
BOLD,
|
|
5
|
+
DIM,
|
|
6
|
+
GREEN,
|
|
7
|
+
RED,
|
|
8
|
+
RESET,
|
|
9
|
+
WHITE,
|
|
10
|
+
} from "../../../shared.mjs";
|
|
7
11
|
import { fail, ok, warn } from "../../render.mjs";
|
|
12
|
+
import {
|
|
13
|
+
getDefaultHubUrl,
|
|
14
|
+
getHubInfo,
|
|
15
|
+
startHubDaemon,
|
|
16
|
+
} from "../../services/hub-client.mjs";
|
|
17
|
+
import {
|
|
18
|
+
ensureTmuxOrExit,
|
|
19
|
+
resolveEffectiveMode,
|
|
20
|
+
} from "../../services/runtime-mode.mjs";
|
|
21
|
+
import { saveTeamState } from "../../services/state-store.mjs";
|
|
8
22
|
import { parseTeamArgs } from "./parse-args.mjs";
|
|
23
|
+
import { startHeadlessTeam } from "./start-headless.mjs";
|
|
9
24
|
import { startInProcessTeam } from "./start-in-process.mjs";
|
|
10
25
|
import { startMuxTeam } from "./start-mux.mjs";
|
|
11
|
-
import { startHeadlessTeam } from "./start-headless.mjs";
|
|
12
26
|
import { startWtTeam } from "./start-wt.mjs";
|
|
13
27
|
|
|
14
28
|
function printStartUsage() {
|
|
15
29
|
console.log(`\n ${AMBER}${BOLD}⬡ tfx multi${RESET}\n`);
|
|
16
30
|
console.log(` 사용법: ${WHITE}tfx multi "작업 설명"${RESET}`);
|
|
17
|
-
console.log(
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
console.log(
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
console.log(
|
|
31
|
+
console.log(
|
|
32
|
+
` ${WHITE}tfx multi --agents codex,antigravity --lead claude "작업"${RESET}`,
|
|
33
|
+
);
|
|
34
|
+
console.log(
|
|
35
|
+
` ${WHITE}tfx multi --teammate-mode headless "작업"${RESET} ${DIM}(headless workers)${RESET}`,
|
|
36
|
+
);
|
|
37
|
+
console.log(
|
|
38
|
+
` ${WHITE}tfx multi --dashboard-layout lite "작업"${RESET} ${DIM}(dashboard-lite 기본 뷰)${RESET}`,
|
|
39
|
+
);
|
|
40
|
+
console.log(
|
|
41
|
+
` ${WHITE}tfx multi --dashboard-layout auto "작업"${RESET} ${DIM}(dashboard viewer 레이아웃 자동)${RESET}`,
|
|
42
|
+
);
|
|
43
|
+
console.log(
|
|
44
|
+
` ${WHITE}tfx multi --dashboard-anchor window "작업"${RESET} ${DIM}(dashboard anchor: window|tab, 기본 window)${RESET}`,
|
|
45
|
+
);
|
|
46
|
+
console.log(
|
|
47
|
+
` ${WHITE}tfx multi --teammate-mode wt "작업"${RESET} ${DIM}(Windows Terminal split-pane)${RESET}`,
|
|
48
|
+
);
|
|
49
|
+
console.log(
|
|
50
|
+
` ${WHITE}tfx multi --teammate-mode in-process "작업"${RESET} ${DIM}(mux 불필요)${RESET}\n`,
|
|
51
|
+
);
|
|
24
52
|
}
|
|
25
53
|
|
|
26
54
|
function printWorkerPreview(agents, subtasks) {
|
|
27
55
|
for (let index = 0; index < subtasks.length; index += 1) {
|
|
28
|
-
const preview =
|
|
56
|
+
const preview =
|
|
57
|
+
subtasks[index].length > 44
|
|
58
|
+
? `${subtasks[index].slice(0, 44)}…`
|
|
59
|
+
: subtasks[index];
|
|
29
60
|
console.log(` ${DIM}[${agents[index]}-${index + 1}] ${preview}${RESET}`);
|
|
30
61
|
}
|
|
31
62
|
console.log("");
|
|
@@ -34,16 +65,40 @@ function printWorkerPreview(agents, subtasks) {
|
|
|
34
65
|
function renderTmuxInstallHelp() {
|
|
35
66
|
console.log(`\n ${RED}${BOLD}tmux 미발견${RESET}\n`);
|
|
36
67
|
console.log(" 현재 선택한 모드는 tmux 기반 팀세션이 필요합니다.\n");
|
|
37
|
-
console.log(
|
|
38
|
-
|
|
68
|
+
console.log(
|
|
69
|
+
` 설치:\n Windows: ${WHITE}winget install psmux${RESET}\n macOS: ${WHITE}brew install tmux${RESET}\n Linux: ${WHITE}apt install tmux${RESET}\n`,
|
|
70
|
+
);
|
|
39
71
|
}
|
|
40
72
|
|
|
41
73
|
export { parseTeamArgs };
|
|
42
74
|
|
|
43
75
|
export async function teamStart(args = []) {
|
|
44
|
-
const {
|
|
76
|
+
const {
|
|
77
|
+
agents,
|
|
78
|
+
lead,
|
|
79
|
+
layout,
|
|
80
|
+
teammateMode,
|
|
81
|
+
task: rawTask,
|
|
82
|
+
assigns,
|
|
83
|
+
autoAttach,
|
|
84
|
+
progressive,
|
|
85
|
+
timeoutSec,
|
|
86
|
+
verbose,
|
|
87
|
+
dashboard,
|
|
88
|
+
dashboardLayout,
|
|
89
|
+
dashboardSize,
|
|
90
|
+
dashboardAnchor,
|
|
91
|
+
mcpProfile,
|
|
92
|
+
model,
|
|
93
|
+
cwd,
|
|
94
|
+
nativeBridge,
|
|
95
|
+
nativeBridgeMode,
|
|
96
|
+
nativeBridgeUiOptOut,
|
|
97
|
+
} = parseTeamArgs(args);
|
|
45
98
|
// --assign 사용 시 task를 자동 생성
|
|
46
|
-
const task =
|
|
99
|
+
const task =
|
|
100
|
+
rawTask ||
|
|
101
|
+
(assigns.length > 0 ? assigns.map((a) => a.prompt).join(" + ") : "");
|
|
47
102
|
if (!task) return printStartUsage();
|
|
48
103
|
|
|
49
104
|
console.log(`\n ${AMBER}${BOLD}⬡ tfx multi${RESET}\n`);
|
|
@@ -57,7 +112,12 @@ export async function teamStart(args = []) {
|
|
|
57
112
|
hub = await getHubInfo();
|
|
58
113
|
if (!hub) {
|
|
59
114
|
process.stdout.write(" Hub 시작 중...");
|
|
60
|
-
try {
|
|
115
|
+
try {
|
|
116
|
+
hub = await startHubDaemon();
|
|
117
|
+
} catch (error) {
|
|
118
|
+
if (error?.code === "HUB_SERVER_MISSING")
|
|
119
|
+
fail("hub/server.mjs 없음 — hub 모듈이 설치되지 않음");
|
|
120
|
+
}
|
|
61
121
|
console.log(` ${hub ? `${GREEN}✓${RESET}` : `${RED}✗${RESET}`}`);
|
|
62
122
|
if (!hub) warn("Hub 시작 실패 — 수동으로 실행: tfx hub start");
|
|
63
123
|
} else ok(`Hub: ${DIM}${hub.url}${RESET}`);
|
|
@@ -68,27 +128,81 @@ export async function teamStart(args = []) {
|
|
|
68
128
|
const sessionId = `tfx-multi-${Date.now().toString(36).slice(-4)}${Math.random().toString(36).slice(2, 6)}`;
|
|
69
129
|
const subtasks = decomposeTask(task, agents.length);
|
|
70
130
|
const hubUrl = hub?.url || getDefaultHubUrl();
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
131
|
+
const { mode: effectiveMode, warnings: modeWarnings } =
|
|
132
|
+
resolveEffectiveMode(teammateMode);
|
|
133
|
+
for (const message of modeWarnings) warn(message);
|
|
134
|
+
const effectiveNativeBridge =
|
|
135
|
+
effectiveMode === "headless" && !nativeBridgeUiOptOut ? true : nativeBridge;
|
|
74
136
|
|
|
75
137
|
console.log(` 세션: ${WHITE}${sessionId}${RESET}`);
|
|
76
138
|
console.log(` 모드: ${effectiveMode}`);
|
|
77
139
|
console.log(` 리드: ${AMBER}${lead}${RESET}`);
|
|
78
|
-
console.log(
|
|
140
|
+
console.log(
|
|
141
|
+
` 워커: ${agents.map((agent) => `${AMBER}${agent}${RESET}`).join(", ")}`,
|
|
142
|
+
);
|
|
79
143
|
printWorkerPreview(agents, subtasks);
|
|
80
144
|
|
|
81
145
|
if (effectiveMode === "tmux") {
|
|
82
|
-
try {
|
|
146
|
+
try {
|
|
147
|
+
ensureTmuxOrExit();
|
|
148
|
+
} catch {
|
|
149
|
+
return renderTmuxInstallHelp();
|
|
150
|
+
}
|
|
83
151
|
}
|
|
84
152
|
|
|
85
|
-
const state =
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
153
|
+
const state =
|
|
154
|
+
effectiveMode === "in-process"
|
|
155
|
+
? await startInProcessTeam({
|
|
156
|
+
sessionId,
|
|
157
|
+
task,
|
|
158
|
+
lead,
|
|
159
|
+
agents,
|
|
160
|
+
subtasks,
|
|
161
|
+
hubUrl,
|
|
162
|
+
})
|
|
163
|
+
: effectiveMode === "headless"
|
|
164
|
+
? await startHeadlessTeam({
|
|
165
|
+
sessionId,
|
|
166
|
+
task,
|
|
167
|
+
lead,
|
|
168
|
+
agents,
|
|
169
|
+
subtasks,
|
|
170
|
+
layout,
|
|
171
|
+
assigns,
|
|
172
|
+
autoAttach,
|
|
173
|
+
progressive,
|
|
174
|
+
timeoutSec,
|
|
175
|
+
verbose,
|
|
176
|
+
dashboard,
|
|
177
|
+
dashboardLayout,
|
|
178
|
+
dashboardSize,
|
|
179
|
+
dashboardAnchor,
|
|
180
|
+
mcpProfile,
|
|
181
|
+
model,
|
|
182
|
+
cwd,
|
|
183
|
+
nativeBridge: effectiveNativeBridge,
|
|
184
|
+
nativeBridgeMode,
|
|
185
|
+
})
|
|
186
|
+
: effectiveMode === "wt"
|
|
187
|
+
? await startWtTeam({
|
|
188
|
+
sessionId,
|
|
189
|
+
task,
|
|
190
|
+
lead,
|
|
191
|
+
agents,
|
|
192
|
+
subtasks,
|
|
193
|
+
layout,
|
|
194
|
+
hubUrl,
|
|
195
|
+
})
|
|
196
|
+
: await startMuxTeam({
|
|
197
|
+
sessionId,
|
|
198
|
+
task,
|
|
199
|
+
lead,
|
|
200
|
+
agents,
|
|
201
|
+
subtasks,
|
|
202
|
+
layout,
|
|
203
|
+
hubUrl,
|
|
204
|
+
teammateMode: effectiveMode,
|
|
205
|
+
});
|
|
92
206
|
|
|
93
207
|
if (!state) return fail("in-process supervisor 시작 실패");
|
|
94
208
|
state.sessionId = sessionId;
|
|
@@ -100,7 +214,11 @@ export async function teamStart(args = []) {
|
|
|
100
214
|
console.log(` ${DIM}제어: tfx multi send/control/tasks/status${RESET}\n`);
|
|
101
215
|
} else if (effectiveMode === "wt") {
|
|
102
216
|
ok("Windows Terminal wt 팀 시작 완료");
|
|
103
|
-
console.log(
|
|
104
|
-
|
|
217
|
+
console.log(
|
|
218
|
+
` ${DIM}현재 pane 기준으로 ${state.layout} 분할 생성됨${RESET}`,
|
|
219
|
+
);
|
|
220
|
+
console.log(
|
|
221
|
+
` ${DIM}wt 모드는 자동 프롬프트 주입/Hub direct 제어(send/control)가 제한됩니다.${RESET}\n`,
|
|
222
|
+
);
|
|
105
223
|
}
|
|
106
224
|
}
|
|
@@ -1,14 +1,38 @@
|
|
|
1
1
|
import { resolve } from "node:path";
|
|
2
|
-
import { normalizeLayout, normalizeTeammateMode } from "../../services/runtime-mode.mjs";
|
|
3
|
-
import { parseDashboardLayout } from "../../../dashboard-layout.mjs";
|
|
4
2
|
import { parseDashboardAnchor } from "../../../dashboard-anchor.mjs";
|
|
3
|
+
import { parseDashboardLayout } from "../../../dashboard-layout.mjs";
|
|
4
|
+
import {
|
|
5
|
+
normalizeLayout,
|
|
6
|
+
normalizeTeammateMode,
|
|
7
|
+
} from "../../services/runtime-mode.mjs";
|
|
5
8
|
|
|
6
9
|
// --assign 파싱 시 마지막 콜론 뒤를 role로 인식할 알려진 역할/CLI 이름
|
|
7
10
|
const KNOWN_ROLES = new Set([
|
|
8
|
-
"codex",
|
|
9
|
-
"
|
|
10
|
-
"
|
|
11
|
-
"
|
|
11
|
+
"codex",
|
|
12
|
+
"antigravity",
|
|
13
|
+
"agy",
|
|
14
|
+
"gemini",
|
|
15
|
+
"claude",
|
|
16
|
+
"executor",
|
|
17
|
+
"architect",
|
|
18
|
+
"planner",
|
|
19
|
+
"analyst",
|
|
20
|
+
"critic",
|
|
21
|
+
"debugger",
|
|
22
|
+
"verifier",
|
|
23
|
+
"code-reviewer",
|
|
24
|
+
"security-reviewer",
|
|
25
|
+
"test-engineer",
|
|
26
|
+
"designer",
|
|
27
|
+
"writer",
|
|
28
|
+
"scientist",
|
|
29
|
+
]);
|
|
30
|
+
|
|
31
|
+
const NATIVE_BRIDGE_MODES = new Set([
|
|
32
|
+
"roster",
|
|
33
|
+
"agents",
|
|
34
|
+
"interactive-attach",
|
|
35
|
+
"claude-wrapper",
|
|
12
36
|
]);
|
|
13
37
|
|
|
14
38
|
/**
|
|
@@ -29,7 +53,10 @@ function parseAssignValue(raw) {
|
|
|
29
53
|
|
|
30
54
|
const lastColon = rest.lastIndexOf(":");
|
|
31
55
|
if (lastColon > 0) {
|
|
32
|
-
const candidate = rest
|
|
56
|
+
const candidate = rest
|
|
57
|
+
.slice(lastColon + 1)
|
|
58
|
+
.trim()
|
|
59
|
+
.toLowerCase();
|
|
33
60
|
if (KNOWN_ROLES.has(candidate)) {
|
|
34
61
|
return { cli, prompt: rest.slice(0, lastColon).trim(), role: candidate };
|
|
35
62
|
}
|
|
@@ -39,7 +66,7 @@ function parseAssignValue(raw) {
|
|
|
39
66
|
}
|
|
40
67
|
|
|
41
68
|
export function parseTeamArgs(args = []) {
|
|
42
|
-
let agents = ["codex", "
|
|
69
|
+
let agents = ["codex", "antigravity"];
|
|
43
70
|
let lead = "claude";
|
|
44
71
|
let layout = "2x2";
|
|
45
72
|
let teammateMode = "auto";
|
|
@@ -51,21 +78,32 @@ export function parseTeamArgs(args = []) {
|
|
|
51
78
|
let verbose = false;
|
|
52
79
|
let dashboard = true;
|
|
53
80
|
let dashboardLayout = "lite";
|
|
54
|
-
let dashboardSize = 0.
|
|
81
|
+
let dashboardSize = 0.4;
|
|
55
82
|
let dashboardAnchor = "window";
|
|
56
83
|
let mcpProfile = "";
|
|
57
84
|
let model = "";
|
|
58
85
|
let cwd = "";
|
|
86
|
+
let nativeBridge = false;
|
|
87
|
+
let nativeBridgeMode = "agents";
|
|
88
|
+
let nativeBridgeExplicit = false;
|
|
89
|
+
let nativeBridgeUiRequested = false;
|
|
90
|
+
let nativeBridgeUiOptOut = false;
|
|
59
91
|
|
|
60
92
|
for (let index = 0; index < args.length; index += 1) {
|
|
61
93
|
const current = args[index];
|
|
62
94
|
if (current === "--agents" && args[index + 1]) {
|
|
63
|
-
agents = args[++index]
|
|
95
|
+
agents = args[++index]
|
|
96
|
+
.split(",")
|
|
97
|
+
.map((value) => value.trim().toLowerCase())
|
|
98
|
+
.filter(Boolean);
|
|
64
99
|
} else if (current === "--lead" && args[index + 1]) {
|
|
65
100
|
lead = args[++index].trim().toLowerCase();
|
|
66
101
|
} else if (current === "--layout" && args[index + 1]) {
|
|
67
102
|
layout = args[++index];
|
|
68
|
-
} else if (
|
|
103
|
+
} else if (
|
|
104
|
+
(current === "--teammate-mode" || current === "--mode") &&
|
|
105
|
+
args[index + 1]
|
|
106
|
+
) {
|
|
69
107
|
teammateMode = args[++index];
|
|
70
108
|
} else if (current === "--assign" && args[index + 1]) {
|
|
71
109
|
const parsed = parseAssignValue(args[++index]);
|
|
@@ -83,7 +121,10 @@ export function parseTeamArgs(args = []) {
|
|
|
83
121
|
} else if (current === "--dashboard-layout" && args[index + 1]) {
|
|
84
122
|
dashboardLayout = parseDashboardLayout(args[++index]);
|
|
85
123
|
} else if (current === "--dashboard-size" && args[index + 1]) {
|
|
86
|
-
dashboardSize = Math.min(
|
|
124
|
+
dashboardSize = Math.min(
|
|
125
|
+
0.8,
|
|
126
|
+
Math.max(0.2, parseFloat(args[++index]) || 0.5),
|
|
127
|
+
);
|
|
87
128
|
} else if (current === "--dashboard-anchor" && args[index + 1]) {
|
|
88
129
|
dashboardAnchor = parseDashboardAnchor(args[++index]);
|
|
89
130
|
} else if (current === "--no-progressive") {
|
|
@@ -94,6 +135,37 @@ export function parseTeamArgs(args = []) {
|
|
|
94
135
|
mcpProfile = args[++index].trim();
|
|
95
136
|
} else if ((current === "--model" || current === "-m") && args[index + 1]) {
|
|
96
137
|
model = args[++index].trim();
|
|
138
|
+
} else if (current === "--native-bridge" || current === "-nb") {
|
|
139
|
+
nativeBridge = true;
|
|
140
|
+
nativeBridgeExplicit = true;
|
|
141
|
+
} else if (current === "--native-bridge-ui") {
|
|
142
|
+
if (nativeBridgeUiOptOut) {
|
|
143
|
+
throw new Error(
|
|
144
|
+
"cannot combine --native-bridge-ui and --no-native-bridge-ui",
|
|
145
|
+
);
|
|
146
|
+
}
|
|
147
|
+
nativeBridge = true;
|
|
148
|
+
nativeBridgeMode = "agents";
|
|
149
|
+
nativeBridgeExplicit = true;
|
|
150
|
+
nativeBridgeUiRequested = true;
|
|
151
|
+
} else if (current === "--no-native-bridge-ui") {
|
|
152
|
+
if (nativeBridgeUiRequested) {
|
|
153
|
+
throw new Error(
|
|
154
|
+
"cannot combine --native-bridge-ui and --no-native-bridge-ui",
|
|
155
|
+
);
|
|
156
|
+
}
|
|
157
|
+
nativeBridge = false;
|
|
158
|
+
nativeBridgeUiOptOut = true;
|
|
159
|
+
} else if (current === "--native-bridge-mode") {
|
|
160
|
+
const mode = args[++index];
|
|
161
|
+
if (!NATIVE_BRIDGE_MODES.has(mode)) {
|
|
162
|
+
throw new Error(
|
|
163
|
+
`unknown native bridge mode: ${mode || ""}; expected roster, agents, interactive-attach, or claude-wrapper`,
|
|
164
|
+
);
|
|
165
|
+
}
|
|
166
|
+
nativeBridge = true;
|
|
167
|
+
nativeBridgeMode = mode;
|
|
168
|
+
nativeBridgeExplicit = true;
|
|
97
169
|
} else if (current === "--cwd" && args[index + 1]) {
|
|
98
170
|
let p = args[++index].trim();
|
|
99
171
|
// MSYS/Git Bash 드라이브 문자 변환: /c/... → C:/...
|
|
@@ -108,11 +180,20 @@ export function parseTeamArgs(args = []) {
|
|
|
108
180
|
}
|
|
109
181
|
}
|
|
110
182
|
|
|
183
|
+
const normalizedTeammateMode = normalizeTeammateMode(teammateMode);
|
|
184
|
+
if (
|
|
185
|
+
!nativeBridgeExplicit &&
|
|
186
|
+
!nativeBridgeUiOptOut &&
|
|
187
|
+
normalizedTeammateMode === "headless"
|
|
188
|
+
) {
|
|
189
|
+
nativeBridge = true;
|
|
190
|
+
}
|
|
191
|
+
|
|
111
192
|
return {
|
|
112
193
|
agents,
|
|
113
194
|
lead,
|
|
114
195
|
layout: normalizeLayout(layout),
|
|
115
|
-
teammateMode:
|
|
196
|
+
teammateMode: normalizedTeammateMode,
|
|
116
197
|
task: taskParts.join(" ").trim(),
|
|
117
198
|
assigns,
|
|
118
199
|
autoAttach,
|
|
@@ -126,5 +207,8 @@ export function parseTeamArgs(args = []) {
|
|
|
126
207
|
mcpProfile,
|
|
127
208
|
model,
|
|
128
209
|
cwd,
|
|
210
|
+
nativeBridge,
|
|
211
|
+
nativeBridgeMode,
|
|
212
|
+
nativeBridgeUiOptOut,
|
|
129
213
|
};
|
|
130
214
|
}
|