@triflux/remote 10.50.1 → 10.51.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.
Files changed (120) hide show
  1. package/cto/brief.mjs +0 -12
  2. package/cto/collect.mjs +16 -247
  3. package/cto/current.schema.json +4 -20
  4. package/cto/events.mjs +13 -294
  5. package/cto/hygiene.mjs +26 -346
  6. package/cto/lake-root.mjs +114 -16
  7. package/cto/status.mjs +33 -128
  8. package/hub/index.mjs +0 -8
  9. package/hub/store-adapter.mjs +1 -1
  10. package/hub/team/agent-map.json +0 -1
  11. package/hub/team/ansi.mjs +1 -35
  12. package/hub/team/backend.mjs +9 -145
  13. package/hub/team/cli/commands/attach.mjs +1 -17
  14. package/hub/team/cli/commands/control.mjs +12 -38
  15. package/hub/team/cli/commands/debug.mjs +1 -37
  16. package/hub/team/cli/commands/focus.mjs +5 -31
  17. package/hub/team/cli/commands/interrupt.mjs +6 -25
  18. package/hub/team/cli/commands/kill.mjs +1 -30
  19. package/hub/team/cli/commands/list.mjs +0 -16
  20. package/hub/team/cli/commands/send.mjs +6 -26
  21. package/hub/team/cli/commands/start/index.mjs +41 -133
  22. package/hub/team/cli/commands/start/parse-args.mjs +15 -40
  23. package/hub/team/cli/commands/start/start-headless.mjs +138 -105
  24. package/hub/team/cli/commands/start/start-mux.mjs +0 -3
  25. package/hub/team/cli/commands/status.mjs +2 -57
  26. package/hub/team/cli/commands/stop.mjs +14 -19
  27. package/hub/team/cli/help.mjs +4 -5
  28. package/hub/team/cli/manifest.mjs +5 -1
  29. package/hub/team/cli/render.mjs +0 -12
  30. package/hub/team/cli/services/hub-client.mjs +2 -88
  31. package/hub/team/cli/services/runtime-mode.mjs +27 -98
  32. package/hub/team/handoff.mjs +3 -34
  33. package/hub/team/headless.mjs +14 -755
  34. package/hub/team/orchestrator.mjs +4 -30
  35. package/hub/team/pane.mjs +6 -28
  36. package/hub/team/psmux.mjs +16 -403
  37. package/hub/team/remote-session.mjs +1 -2
  38. package/hub/team/session.mjs +8 -119
  39. package/hub/team/swarm-intent.mjs +0 -198
  40. package/hub/team/terminal-opener.mjs +11 -35
  41. package/hub/team/tui-core.mjs +1 -1
  42. package/hub/team/tui-viewer.mjs +2 -2
  43. package/hub/team/tui.mjs +8 -269
  44. package/hub/team/wt-manager.mjs +2 -2
  45. package/hub/workers/factory.mjs +4 -37
  46. package/hub/workers/lib/jsonrpc-ws-uds.mjs +0 -2
  47. package/package.json +1 -1
  48. package/scripts/lib/agent-route-policy.mjs +162 -14
  49. package/scripts/lib/claudemd-scanner.mjs +2 -199
  50. package/scripts/lib/cli-claude.mjs +0 -2
  51. package/scripts/lib/context.mjs +3 -19
  52. package/scripts/lib/env-probe.mjs +5 -64
  53. package/scripts/lib/gemini-profiles.mjs +2 -69
  54. package/scripts/lib/legacy-mcp-cleanup.mjs +14 -3
  55. package/scripts/lib/machine-profile.mjs +3 -17
  56. package/scripts/lib/mcp-filter.mjs +109 -53
  57. package/scripts/lib/mcp-health.mjs +2 -2
  58. package/scripts/lib/mcp-server-catalog.mjs +2 -2
  59. package/scripts/lib/psmux-info.mjs +25 -104
  60. package/scripts/lib/skill-template.mjs +0 -271
  61. package/cto/hygiene-actions.mjs +0 -355
  62. package/cto/hygiene-notify.mjs +0 -170
  63. package/hub/team/build-worker-prompt.mjs +0 -92
  64. package/hub/team/check-mcp-hub.mjs +0 -49
  65. package/hub/team/claude-native-bridge.mjs +0 -987
  66. package/hub/team/cli/commands/start/start-in-process.mjs +0 -50
  67. package/hub/team/cli/commands/start/start-wt.mjs +0 -86
  68. package/hub/team/cli/services/native-control.mjs +0 -145
  69. package/hub/team/codex-review.mjs +0 -520
  70. package/hub/team/conductor-mesh-bridge.mjs +0 -122
  71. package/hub/team/conductor.mjs +0 -1529
  72. package/hub/team/consensus-meta.mjs +0 -176
  73. package/hub/team/cto-pull.mjs +0 -31
  74. package/hub/team/daemon-pty-tmux-bridge.mjs +0 -146
  75. package/hub/team/dashboard.mjs +0 -322
  76. package/hub/team/event-log.mjs +0 -84
  77. package/hub/team/execution-mode.mjs +0 -324
  78. package/hub/team/extract-completion-payload.mjs +0 -110
  79. package/hub/team/headless-bridge-session.mjs +0 -17
  80. package/hub/team/health-probe.mjs +0 -435
  81. package/hub/team/interactive-native-launcher.mjs +0 -119
  82. package/hub/team/interactive-native-worker.mjs +0 -80
  83. package/hub/team/interactive-tui-transport.mjs +0 -479
  84. package/hub/team/launcher-template.mjs +0 -144
  85. package/hub/team/mcp-selector.mjs +0 -145
  86. package/hub/team/native-supervisor.mjs +0 -460
  87. package/hub/team/native.mjs +0 -727
  88. package/hub/team/recovery-store.mjs +0 -149
  89. package/hub/team/remote-probe.mjs +0 -292
  90. package/hub/team/remote-watcher.mjs +0 -506
  91. package/hub/team/runtime-strategy.mjs +0 -200
  92. package/hub/team/schemas/worker-completion.json +0 -39
  93. package/hub/team/sentinel-capture.mjs +0 -127
  94. package/hub/team/swarm-cli.mjs +0 -390
  95. package/hub/team/swarm-hypervisor.mjs +0 -2206
  96. package/hub/team/swarm-locks.mjs +0 -335
  97. package/hub/team/swarm-planner.mjs +0 -371
  98. package/hub/team/swarm-preflight.mjs +0 -366
  99. package/hub/team/swarm-reconciler.mjs +0 -242
  100. package/hub/team/tui-remote-adapter.mjs +0 -377
  101. package/hub/team/worker-completion-validator.mjs +0 -79
  102. package/hub/team/worktree-lifecycle.mjs +0 -639
  103. package/hub/team/wt-templates.json +0 -43
  104. package/hub/workers/antigravity-route-worker.mjs +0 -179
  105. package/hub/workers/gemini-worker.mjs +0 -217
  106. package/scripts/lib/agent-json.mjs +0 -27
  107. package/scripts/lib/async.mjs +0 -174
  108. package/scripts/lib/cli-agy.mjs +0 -85
  109. package/scripts/lib/cli-codex.mjs +0 -62
  110. package/scripts/lib/cli-gemini.mjs +0 -37
  111. package/scripts/lib/dynamic-route-cli.mjs +0 -107
  112. package/scripts/lib/env.mjs +0 -14
  113. package/scripts/lib/hub.mjs +0 -48
  114. package/scripts/lib/pid.mjs +0 -63
  115. package/scripts/lib/quota.mjs +0 -47
  116. package/scripts/lib/skill-state.mjs +0 -220
  117. package/scripts/lib/team.mjs +0 -75
  118. package/scripts/lib/timeout.mjs +0 -66
  119. package/scripts/lib/tmp.mjs +0 -26
  120. package/scripts/lib/toml.mjs +0 -132
@@ -1,37 +1,25 @@
1
- import {
2
- detectMultiplexer,
3
- hasWindowsTerminal,
4
- hasWindowsTerminalSession,
5
- sessionExists,
6
- } from "../../session.mjs";
1
+ import { detectMultiplexer, sessionExists } from "../../session.mjs";
7
2
 
8
3
  export function normalizeTeammateMode(mode = "auto", deps = {}) {
9
4
  const platform = deps.platform || process.platform;
10
5
  const env = deps.env || process.env;
11
6
  const detectMux = deps.detectMultiplexer || detectMultiplexer;
12
7
  const raw = String(mode).toLowerCase();
13
- if (raw === "inline" || raw === "native") return "in-process";
14
8
  if (raw === "headless" || raw === "hl") return "headless";
15
- if (raw === "in-process" || raw === "tmux") return raw;
16
- if (raw === "psmux") return platform === "win32" ? "psmux" : "in-process";
17
- if (
18
- raw === "wt" ||
19
- raw === "windows-terminal" ||
20
- raw === "windows_terminal"
21
- ) {
22
- return platform === "win32" ? "wt" : "in-process";
23
- }
24
- if (raw === "auto") {
25
- if (env.TMUX) return "tmux";
26
- const mux = detectMux();
27
- if (platform !== "win32") {
28
- return mux === "tmux" ? "tmux" : "in-process";
29
- }
30
- if (mux === "psmux") return "psmux";
31
- if (mux === "tmux") return "tmux";
32
- return "in-process";
9
+ if (raw === "tmux") return raw;
10
+ if (raw === "psmux" && platform === "win32") return raw;
11
+ if (raw !== "auto") {
12
+ throw new Error(
13
+ `지원하지 않는 teammate mode: ${mode}; auto, headless, tmux${platform === "win32" ? ", psmux" : ""}를 사용하세요.`,
14
+ );
33
15
  }
34
- return "in-process";
16
+ if (env.TMUX) return "tmux";
17
+ const mux = detectMux();
18
+ if (mux === "tmux") return "tmux";
19
+ if (platform === "win32" && mux === "psmux") return "psmux";
20
+ if (platform === "win32" && mux === "git-bash-tmux") return "tmux";
21
+ if (!(deps.isTTY ?? Boolean(process.stdout.isTTY))) return "headless";
22
+ return ensureTmuxOrExit(deps);
35
23
  }
36
24
 
37
25
  export function normalizeLayout(layout = "2x2") {
@@ -43,91 +31,32 @@ export function normalizeLayout(layout = "2x2") {
43
31
  return "2x2";
44
32
  }
45
33
 
46
- export function isNativeMode(state) {
47
- return state?.teammateMode === "in-process" && !!state?.native?.controlUrl;
48
- }
49
-
50
- export function isWtMode(state) {
51
- return state?.teammateMode === "wt";
52
- }
53
-
54
34
  export function isTeamAlive(state) {
55
35
  if (!state) return false;
56
- if (isNativeMode(state)) {
36
+ if (state.teammateMode === "headless" && state.ownerPid) {
57
37
  try {
58
- process.kill(state.native.supervisorPid, 0);
38
+ process.kill(state.ownerPid, 0);
59
39
  return true;
60
40
  } catch {
61
41
  return false;
62
42
  }
63
43
  }
64
- if (isWtMode(state)) {
65
- if (!hasWindowsTerminal()) return false;
66
- if (hasWindowsTerminalSession()) return true;
67
- return Array.isArray(state.members) && state.members.length > 0;
68
- }
69
44
  return sessionExists(state.sessionName);
70
45
  }
71
46
 
72
47
  export function ensureTmuxOrExit(deps = {}) {
73
48
  const platform = deps.platform || process.platform;
74
- const detectMux = deps.detectMultiplexer || detectMultiplexer;
75
- const mux = detectMux();
76
- if (mux && (platform === "win32" || mux === "tmux")) return mux;
77
- const error = new Error("tmux 미발견");
49
+ const mux = (deps.detectMultiplexer || detectMultiplexer)();
50
+ if (
51
+ mux === "tmux" ||
52
+ (platform === "win32" && ["psmux", "git-bash-tmux"].includes(mux))
53
+ )
54
+ return mux;
55
+ const error = new Error(
56
+ platform === "win32"
57
+ ? "멀티플렉서 미발견. psmux를 설치하세요: winget install psmux"
58
+ : `멀티플렉서 미발견. tmux를 설치하세요: ${platform === "darwin" ? "brew install tmux" : "apt install tmux"}`,
59
+ );
78
60
  error.code = "TMUX_REQUIRED";
79
61
  throw error;
80
62
  }
81
-
82
- /**
83
- * teammateMode + 환경 기반 effective mode 결정 (pure function).
84
- *
85
- * - wt → wt.exe 없으면 in-process
86
- * - wt → WT_SESSION 없으면 in-process
87
- * - in-process → non-TTY 감지 시 headless (#114: run_in_background 부모 종료 시 자식 SIGTERM 방지)
88
- * - override: TFX_FORCE_IN_PROCESS=1 로 in-process 유지
89
- *
90
- * @param {string} teammateMode
91
- * @param {{
92
- * hasWt?: () => boolean,
93
- * hasWtSession?: () => boolean,
94
- * isTTY?: boolean,
95
- * env?: Record<string,string|undefined>,
96
- * }} [deps]
97
- * @returns {{ mode: string, warnings: string[] }}
98
- */
99
- export function resolveEffectiveMode(teammateMode, deps = {}) {
100
- const hasWt = deps.hasWt || hasWindowsTerminal;
101
- const hasWtSession = deps.hasWtSession || hasWindowsTerminalSession;
102
- const isTTY =
103
- typeof deps.isTTY === "boolean"
104
- ? deps.isTTY
105
- : Boolean(process.stdout.isTTY);
106
- const env = deps.env || process.env;
107
-
108
- const warnings = [];
109
- let effective = teammateMode;
110
-
111
- if (effective === "wt" && !hasWt()) {
112
- warnings.push("wt.exe 미발견 — in-process 모드로 자동 fallback");
113
- effective = "in-process";
114
- }
115
- if (effective === "wt" && !hasWtSession()) {
116
- warnings.push(
117
- "WT_SESSION 미감지(Windows Terminal 외부) — in-process 모드로 자동 fallback",
118
- );
119
- effective = "in-process";
120
- }
121
- if (
122
- effective === "in-process" &&
123
- !isTTY &&
124
- env.TFX_FORCE_IN_PROCESS !== "1"
125
- ) {
126
- warnings.push(
127
- "non-TTY 환경 감지 (run_in_background 등) — headless 모드로 자동 fallback (#114). 강제 유지: TFX_FORCE_IN_PROCESS=1",
128
- );
129
- effective = "headless";
130
- }
131
-
132
- return { mode: effective, warnings };
133
- }
@@ -13,37 +13,6 @@ const YES_NO = ["yes", "no"];
13
13
  const TOKEN_HARD_CAP = 150;
14
14
  const HANDOFF_MARKER = "--- HANDOFF ---";
15
15
 
16
- /**
17
- * 워커 프롬프트에 삽입할 HANDOFF 블록 생성 지시
18
- */
19
- export const HANDOFF_INSTRUCTION = `
20
- After completing the task, you MUST output a HANDOFF block in exactly this format at the end of your response:
21
-
22
- --- HANDOFF ---
23
- status: ok | partial | failed
24
- lead_action: accept | needs_read | retry | reassign
25
- task: <1-3 word task type>
26
- files_changed: <comma-separated repo-root relative file paths, or "none">
27
- verdict: <one sentence conclusion>
28
- confidence: high | medium | low
29
- risk: low | med | high
30
- detail: <result file path if available, or "none">
31
-
32
- If the task failed, also include:
33
- error_stage: dispatch | execution | timeout
34
- retryable: yes | no
35
- partial_output: yes | no
36
-
37
- Rules:
38
- - The HANDOFF block must start with exactly "--- HANDOFF ---"
39
- - Set status: ok only after you have verified the work (file/diff/test evidence) — unverified claims must use partial or failed.
40
- - Each field must be on its own line as "key: value"
41
- - Report files_changed as repo-root relative paths
42
- - verdict must be a single concise sentence
43
- - Do not skip any required field
44
- - This block owns the final output position; this block must be the last thing you output
45
- `.trim();
46
-
47
16
  /**
48
17
  * CLI 프롬프트 길이 제한을 고려한 축약 HANDOFF 지시
49
18
  */
@@ -61,7 +30,7 @@ Set status: ok only after you have verified the work (file/diff/test evidence)
61
30
  * @param {string} rawText
62
31
  * @returns {object|null} 파싱된 필드 객체, 블록이 없으면 null
63
32
  */
64
- export function parseHandoff(rawText) {
33
+ function parseHandoff(rawText) {
65
34
  if (!rawText || typeof rawText !== "string") return null;
66
35
 
67
36
  // P1 fix: 마지막 HANDOFF 블록을 파싱 (프롬프트 에코로 인한 중복 마커 대응)
@@ -137,7 +106,7 @@ function validateEnum(value, allowed) {
137
106
  * @param {string[]} [context.gitDiffFiles]
138
107
  * @returns {{ handoff: object, valid: boolean, warnings: string[] }}
139
108
  */
140
- export function validateHandoff(parsed, context = {}) {
109
+ function validateHandoff(parsed, context = {}) {
141
110
  const warnings = [];
142
111
  const h = { ...parsed };
143
112
 
@@ -247,7 +216,7 @@ export function validateHandoff(parsed, context = {}) {
247
216
  * @param {string[]} [context.filesChanged]
248
217
  * @returns {object}
249
218
  */
250
- export function buildFallbackHandoff(exitCode, resultFile, cli, context = {}) {
219
+ function buildFallbackHandoff(exitCode, resultFile, cli, context = {}) {
251
220
  const ok = exitCode === 0;
252
221
  const filesChanged = Array.isArray(context.filesChanged)
253
222
  ? context.filesChanged.filter(Boolean)