@triflux/remote 10.50.2 → 10.52.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 (134) hide show
  1. package/cto/brief.mjs +0 -20
  2. package/cto/collect.mjs +1 -200
  3. package/cto/current.schema.json +2 -23
  4. package/cto/hygiene.mjs +2 -61
  5. package/cto/lake-root.mjs +0 -56
  6. package/cto/status.mjs +5 -187
  7. package/hub/index.mjs +0 -17
  8. package/hub/team/agent-map.json +0 -1
  9. package/hub/team/agents-row-attach.py +120 -0
  10. package/hub/team/agents-row.mjs +200 -0
  11. package/hub/team/ansi.mjs +1 -35
  12. package/hub/team/backend.mjs +9 -145
  13. package/hub/team/claude-daemon-control.mjs +1 -2
  14. package/hub/team/claude-session-projection.mjs +5 -73
  15. package/hub/team/cli/commands/attach.mjs +1 -17
  16. package/hub/team/cli/commands/control.mjs +12 -38
  17. package/hub/team/cli/commands/debug.mjs +2 -39
  18. package/hub/team/cli/commands/focus.mjs +5 -31
  19. package/hub/team/cli/commands/interrupt.mjs +6 -25
  20. package/hub/team/cli/commands/kill.mjs +1 -30
  21. package/hub/team/cli/commands/list.mjs +0 -16
  22. package/hub/team/cli/commands/send.mjs +6 -26
  23. package/hub/team/cli/commands/start/index.mjs +42 -133
  24. package/hub/team/cli/commands/start/parse-args.mjs +15 -40
  25. package/hub/team/cli/commands/start/start-headless.mjs +138 -105
  26. package/hub/team/cli/commands/start/start-mux.mjs +2 -7
  27. package/hub/team/cli/commands/status.mjs +2 -57
  28. package/hub/team/cli/commands/stop.mjs +14 -19
  29. package/hub/team/cli/help.mjs +4 -5
  30. package/hub/team/cli/manifest.mjs +5 -1
  31. package/hub/team/cli/render.mjs +0 -12
  32. package/hub/team/cli/services/runtime-mode.mjs +27 -98
  33. package/hub/team/cli/services/state-store.mjs +5 -20
  34. package/hub/team/handoff.mjs +3 -34
  35. package/hub/team/headless.mjs +108 -1296
  36. package/hub/team/orchestrator.mjs +4 -30
  37. package/hub/team/pane.mjs +6 -28
  38. package/hub/team/psmux.mjs +3 -34
  39. package/hub/team/remote-session.mjs +1 -2
  40. package/hub/team/session-context.mjs +1 -1
  41. package/hub/team/session.mjs +7 -91
  42. package/hub/team/tui-core.mjs +1 -1
  43. package/hub/team/tui-viewer.mjs +11 -58
  44. package/hub/team/tui.mjs +8 -306
  45. package/hub/team/uds-orchestrator.mjs +2 -580
  46. package/hub/team/wt-manager.mjs +2 -2
  47. package/hub/workers/factory.mjs +6 -84
  48. package/hub/workers/interface.mjs +1 -7
  49. package/hub/workers/lib/jsonrpc-core.mjs +11 -0
  50. package/hub/workers/lib/jsonrpc-ws-uds.mjs +5 -8
  51. package/package.json +3 -8
  52. package/scripts/lib/agent-route-policy.mjs +143 -62
  53. package/scripts/lib/cli-claude.mjs +0 -14
  54. package/scripts/lib/env-probe.mjs +2 -131
  55. package/scripts/lib/gemini-profiles.mjs +2 -69
  56. package/scripts/lib/legacy-mcp-cleanup.mjs +283 -0
  57. package/scripts/lib/machine-profile.mjs +3 -17
  58. package/scripts/lib/mcp-filter.mjs +109 -53
  59. package/scripts/lib/mcp-guard-engine.mjs +40 -98
  60. package/scripts/lib/mcp-health.mjs +2 -2
  61. package/scripts/lib/mcp-server-catalog.mjs +2 -2
  62. package/scripts/lib/psmux-info.mjs +11 -59
  63. package/scripts/lib/skill-template.mjs +0 -245
  64. package/hub/hub-lifecycle.mjs +0 -248
  65. package/hub/pipe.mjs +0 -825
  66. package/hub/promote-penalties.mjs +0 -138
  67. package/hub/public/dashboard.html +0 -416
  68. package/hub/schema.sql +0 -209
  69. package/hub/server.mjs +0 -3048
  70. package/hub/store-adapter.mjs +0 -182
  71. package/hub/store.mjs +0 -1736
  72. package/hub/team/build-worker-prompt.mjs +0 -92
  73. package/hub/team/check-mcp-hub.mjs +0 -49
  74. package/hub/team/claude-native-bridge.mjs +0 -987
  75. package/hub/team/cli/commands/start/start-in-process.mjs +0 -50
  76. package/hub/team/cli/commands/start/start-wt.mjs +0 -86
  77. package/hub/team/cli/services/hub-client.mjs +0 -264
  78. package/hub/team/cli/services/native-control.mjs +0 -145
  79. package/hub/team/codex-review.mjs +0 -520
  80. package/hub/team/conductor-mesh-bridge.mjs +0 -122
  81. package/hub/team/conductor-registry.mjs +0 -121
  82. package/hub/team/conductor.mjs +0 -1529
  83. package/hub/team/consensus-meta.mjs +0 -176
  84. package/hub/team/cto-auto-collect.mjs +0 -115
  85. package/hub/team/cto-pull.mjs +0 -31
  86. package/hub/team/daemon-pty-tmux-bridge.mjs +0 -146
  87. package/hub/team/dashboard.mjs +0 -322
  88. package/hub/team/event-log.mjs +0 -84
  89. package/hub/team/execution-mode.mjs +0 -324
  90. package/hub/team/extract-completion-payload.mjs +0 -110
  91. package/hub/team/headless-bridge-session.mjs +0 -17
  92. package/hub/team/health-probe.mjs +0 -435
  93. package/hub/team/interactive-native-launcher.mjs +0 -119
  94. package/hub/team/interactive-native-worker.mjs +0 -80
  95. package/hub/team/interactive-tui-transport.mjs +0 -479
  96. package/hub/team/launcher-template.mjs +0 -144
  97. package/hub/team/lead-control.mjs +0 -191
  98. package/hub/team/mcp-selector.mjs +0 -145
  99. package/hub/team/native-supervisor.mjs +0 -460
  100. package/hub/team/native.mjs +0 -727
  101. package/hub/team/recovery-store.mjs +0 -149
  102. package/hub/team/remote-probe.mjs +0 -292
  103. package/hub/team/remote-watcher.mjs +0 -506
  104. package/hub/team/runtime-strategy.mjs +0 -200
  105. package/hub/team/schemas/worker-completion.json +0 -39
  106. package/hub/team/sentinel-capture.mjs +0 -127
  107. package/hub/team/session-sync.mjs +0 -316
  108. package/hub/team/swarm-cli.mjs +0 -390
  109. package/hub/team/swarm-hypervisor.mjs +0 -2206
  110. package/hub/team/swarm-intent.mjs +0 -216
  111. package/hub/team/swarm-locks.mjs +0 -335
  112. package/hub/team/swarm-planner.mjs +0 -371
  113. package/hub/team/swarm-preflight.mjs +0 -366
  114. package/hub/team/swarm-reconciler.mjs +0 -242
  115. package/hub/team/synapse-cli.mjs +0 -458
  116. package/hub/team/synapse-http.mjs +0 -311
  117. package/hub/team/synapse-registry.mjs +0 -618
  118. package/hub/team/tui-remote-adapter.mjs +0 -377
  119. package/hub/team/tui-synapse.mjs +0 -223
  120. package/hub/team/worker-completion-validator.mjs +0 -79
  121. package/hub/team/worker-sandbox.mjs +0 -125
  122. package/hub/team/worktree-lifecycle.mjs +0 -639
  123. package/hub/team/wt-templates.json +0 -43
  124. package/hub/tools.mjs +0 -900
  125. package/hub/workers/antigravity-route-worker.mjs +0 -179
  126. package/hub/workers/codex-app-server-worker.mjs +0 -1067
  127. package/hub/workers/delegator-mcp.mjs +0 -1098
  128. package/hub/workers/lib/jsonrpc-stdio.mjs +0 -204
  129. package/scripts/lib/claudemd-scanner.mjs +0 -223
  130. package/scripts/lib/context.mjs +0 -67
  131. package/scripts/lib/dynamic-route-cli.mjs +0 -107
  132. package/scripts/lib/handoff.mjs +0 -187
  133. package/scripts/lib/logger.mjs +0 -122
  134. package/scripts/lib/stealth-fetch.mjs +0 -176
@@ -1,322 +0,0 @@
1
- #!/usr/bin/env node
2
- // hub/team/dashboard.mjs — 실시간 팀 상태 표시 (v2.2)
3
- // tmux 의존 제거 — Hub task-list + native-supervisor 기반
4
- //
5
- // 실행:
6
- // node hub/team/dashboard.mjs --session <세션이름> [--interval 2]
7
- // node hub/team/dashboard.mjs --team <팀이름> [--interval 2]
8
- import { get } from "node:http";
9
- import { AMBER, BOLD, DIM, GRAY, GREEN, RED, RESET } from "./shared.mjs";
10
-
11
- /**
12
- * HTTP GET JSON
13
- * @param {string} url
14
- * @returns {Promise<object|null>}
15
- */
16
- function fetchJson(url) {
17
- return new Promise((resolve) => {
18
- const req = get(url, { timeout: 2000 }, (res) => {
19
- let data = "";
20
- res.on("data", (chunk) => (data += chunk));
21
- res.on("end", () => {
22
- try {
23
- resolve(JSON.parse(data));
24
- } catch {
25
- resolve(null);
26
- }
27
- });
28
- });
29
- req.on("error", () => resolve(null));
30
- req.on("timeout", () => {
31
- req.destroy();
32
- resolve(null);
33
- });
34
- });
35
- }
36
-
37
- /**
38
- * HTTP POST JSON (Hub bridge 용)
39
- * @param {string} url
40
- * @param {object} body
41
- * @returns {Promise<object|null>}
42
- */
43
- async function fetchPost(url, body = {}) {
44
- try {
45
- const res = await fetch(url, {
46
- method: "POST",
47
- headers: { "Content-Type": "application/json" },
48
- body: JSON.stringify(body),
49
- signal: AbortSignal.timeout(2000),
50
- });
51
- return await res.json();
52
- } catch {
53
- return null;
54
- }
55
- }
56
-
57
- /**
58
- * 진행률 바 생성
59
- * @param {number} pct — 0~100
60
- * @param {number} width — 바 너비 (기본 8)
61
- * @returns {string}
62
- */
63
- function progressBar(pct, width = 8) {
64
- const filled = Math.round((pct / 100) * width);
65
- const empty = width - filled;
66
- return `${GREEN}${"█".repeat(filled)}${GRAY}${"░".repeat(empty)}${RESET}`;
67
- }
68
-
69
- /**
70
- * 업타임 포맷
71
- * @param {number} ms
72
- * @returns {string}
73
- */
74
- function formatUptime(ms) {
75
- if (ms < 60000) return `${Math.round(ms / 1000)}초`;
76
- if (ms < 3600000) return `${Math.round(ms / 60000)}분`;
77
- return `${Math.round(ms / 3600000)}시간`;
78
- }
79
-
80
- /**
81
- * task 상태 아이콘
82
- * @param {string} status
83
- * @returns {string}
84
- */
85
- function statusIcon(status) {
86
- switch (status) {
87
- case "completed":
88
- return `${GREEN}✓${RESET}`;
89
- case "in_progress":
90
- return `${AMBER}●${RESET}`;
91
- case "failed":
92
- return `${RED}✗${RESET}`;
93
- default:
94
- return `${GRAY}○${RESET}`;
95
- }
96
- }
97
-
98
- /**
99
- * 멤버 목록 구성: Hub tasks + supervisor + teamState 통합
100
- * @param {Array} hubTasks — Hub bridge task-list 결과
101
- * @param {Array} supervisorMembers — native-supervisor 멤버 상태
102
- * @param {object} teamState — team-state.json 내용
103
- * @returns {Array<{name: string, cli: string, status: string, subject: string, preview: string}>}
104
- */
105
- function buildMemberList(hubTasks, supervisorMembers, teamState) {
106
- const members = [];
107
- const supervisorByName = new Map(supervisorMembers.map((m) => [m.name, m]));
108
-
109
- // Hub tasks가 있으면 주 데이터 소스
110
- if (hubTasks.length > 0) {
111
- for (const task of hubTasks) {
112
- const owner = task.owner || task.subject || "";
113
- const sup = supervisorByName.get(owner);
114
- members.push({
115
- name: owner,
116
- cli: task.metadata?.cli || sup?.cli || "",
117
- status: task.status || "pending",
118
- subject: task.subject || "",
119
- preview: sup?.lastPreview || task.description?.slice(0, 80) || "",
120
- });
121
- }
122
- return members;
123
- }
124
-
125
- // Supervisor 데이터 폴백
126
- if (supervisorMembers.length > 0) {
127
- for (const m of supervisorMembers) {
128
- if (m.role === "lead") continue;
129
- members.push({
130
- name: m.name,
131
- cli: m.cli || "",
132
- status:
133
- m.status === "running"
134
- ? "in_progress"
135
- : m.status === "exited"
136
- ? "completed"
137
- : m.status,
138
- subject: "",
139
- preview: m.lastPreview || "",
140
- });
141
- }
142
- return members;
143
- }
144
-
145
- // teamState 폴백 (하위 호환)
146
- const panes = teamState?.panes || {};
147
- for (const [, paneInfo] of Object.entries(panes).filter(
148
- ([, v]) => v.role !== "dashboard" && v.role !== "lead",
149
- )) {
150
- members.push({
151
- name: paneInfo.agentId || paneInfo.name || "?",
152
- cli: paneInfo.cli || "",
153
- status: "unknown",
154
- subject: paneInfo.subtask || "",
155
- preview: "",
156
- });
157
- }
158
- return members;
159
- }
160
-
161
- /**
162
- * 대시보드 렌더링 (v2.2: Hub/supervisor 기반)
163
- * @param {string} sessionName — 세션 또는 팀 이름
164
- * @param {object} opts
165
- * @param {string} opts.hubUrl — Hub URL (기본 http://127.0.0.1:27888)
166
- * @param {string} [opts.teamName] — Hub task-list 조회용 팀 이름
167
- * @param {string} [opts.supervisorUrl] — native-supervisor 제어 URL
168
- * @param {object} [opts.teamState] — team-state.json 내용 (하위 호환)
169
- */
170
- export async function renderDashboard(sessionName, opts = {}) {
171
- const {
172
- hubUrl = "http://127.0.0.1:27888",
173
- teamName,
174
- supervisorUrl,
175
- teamState = {},
176
- } = opts;
177
- const W = 50;
178
- const border = "─".repeat(W);
179
-
180
- // 데이터 수집 (병렬)
181
- const [hubStatus, taskListRes, supervisorRes] = await Promise.all([
182
- fetchJson(`${hubUrl}/status`),
183
- teamName
184
- ? fetchPost(`${hubUrl}/bridge/team/task-list`, { team_name: teamName })
185
- : null,
186
- supervisorUrl ? fetchJson(`${supervisorUrl}/status`) : null,
187
- ]);
188
-
189
- const hubOnline = !!hubStatus;
190
- const hubState = hubOnline
191
- ? `${GREEN}● online${RESET}`
192
- : `${RED}● offline${RESET}`;
193
- const uptime = hubStatus?.hub?.uptime
194
- ? formatUptime(hubStatus.hub.uptime)
195
- : "-";
196
- const queueSize = hubStatus?.hub?.queue_depth ?? 0;
197
-
198
- // Hub task 데이터
199
- const hubTasks = taskListRes?.ok ? taskListRes.data?.tasks || [] : [];
200
- const completedCount = hubTasks.filter(
201
- (t) => t.status === "completed",
202
- ).length;
203
- const totalCount = hubTasks.length;
204
-
205
- // Supervisor 멤버 데이터
206
- const supervisorMembers = supervisorRes?.ok
207
- ? supervisorRes.data?.members || []
208
- : [];
209
-
210
- // 헤더
211
- const progress = totalCount > 0 ? ` ${completedCount}/${totalCount}` : "";
212
- console.log(
213
- `${AMBER}┌─ ${sessionName}${progress} ${GRAY}${"─".repeat(Math.max(0, W - sessionName.length - progress.length - 3))}${AMBER}┐${RESET}`,
214
- );
215
- console.log(
216
- `${AMBER}│${RESET} Hub: ${hubState} Uptime: ${DIM}${uptime}${RESET} Queue: ${DIM}${queueSize}${RESET}`,
217
- );
218
- console.log(`${AMBER}│${RESET}`);
219
-
220
- // 멤버/워커 렌더링
221
- const members = buildMemberList(hubTasks, supervisorMembers, teamState);
222
-
223
- if (members.length === 0) {
224
- console.log(`${AMBER}│${RESET} ${DIM}에이전트 정보 없음${RESET}`);
225
- } else {
226
- for (const m of members) {
227
- const icon = statusIcon(m.status);
228
- const label = `[${m.name}]`;
229
- const cliTag = m.cli
230
- ? m.cli.charAt(0).toUpperCase() + m.cli.slice(1)
231
- : "";
232
-
233
- // 진행률 추정
234
- const pct =
235
- m.status === "completed"
236
- ? 100
237
- : m.status === "in_progress"
238
- ? 50
239
- : m.status === "failed"
240
- ? 100
241
- : 0;
242
-
243
- console.log(
244
- `${AMBER}│${RESET} ${BOLD}${label}${RESET} ${cliTag} ${icon} ${m.status || "pending"} ${progressBar(pct)}`,
245
- );
246
-
247
- // 미리보기: supervisor lastPreview > task subject
248
- const preview = m.preview || m.subject || "";
249
- if (preview) {
250
- const truncated =
251
- preview.length > W - 8 ? preview.slice(0, W - 11) + "..." : preview;
252
- console.log(`${AMBER}│${RESET} ${DIM}> ${truncated}${RESET}`);
253
- }
254
- console.log(`${AMBER}│${RESET}`);
255
- }
256
- }
257
-
258
- // 푸터
259
- console.log(`${AMBER}└${GRAY}${border}${AMBER}┘${RESET}`);
260
- }
261
-
262
- /** team-state.json 로드 (세션별 파일 우선, fallback: team-state.json) */
263
- async function loadTeamState() {
264
- try {
265
- const { existsSync, readFileSync } = await import("node:fs");
266
- const { join } = await import("node:path");
267
- const { homedir } = await import("node:os");
268
- const hubDir = join(homedir(), ".claude", "cache", "tfx-hub");
269
- const sessionId = process.env.CLAUDE_SESSION_ID;
270
- if (sessionId) {
271
- const sessionPath = join(hubDir, `team-state-${sessionId}.json`);
272
- if (existsSync(sessionPath))
273
- return JSON.parse(readFileSync(sessionPath, "utf8"));
274
- }
275
- const legacyPath = join(hubDir, "team-state.json");
276
- if (existsSync(legacyPath))
277
- return JSON.parse(readFileSync(legacyPath, "utf8"));
278
- return {};
279
- } catch {
280
- return {};
281
- }
282
- }
283
-
284
- // ── CLI 실행 ──
285
- if (process.argv[1]?.includes("dashboard.mjs")) {
286
- const sessionIdx = process.argv.indexOf("--session");
287
- const teamIdx = process.argv.indexOf("--team");
288
- const sessionName = sessionIdx !== -1 ? process.argv[sessionIdx + 1] : null;
289
- const teamName = teamIdx !== -1 ? process.argv[teamIdx + 1] : null;
290
- const intervalSec = parseInt(
291
- process.argv[process.argv.indexOf("--interval") + 1] || "2",
292
- 10,
293
- );
294
-
295
- const displayName = sessionName || teamName;
296
- if (!displayName) {
297
- console.error(
298
- "사용법: node dashboard.mjs --session <세션이름> [--team <팀이름>] [--interval 2]",
299
- );
300
- process.exit(1);
301
- }
302
-
303
- // Ctrl+C로 종료
304
- process.on("SIGINT", () => process.exit(0));
305
-
306
- // 갱신 루프
307
- while (true) {
308
- const teamState = await loadTeamState();
309
- const effectiveTeamName = teamName || null;
310
- const supervisorUrl = teamState?.native?.controlUrl || null;
311
-
312
- // 화면 클리어 (ANSI)
313
- process.stdout.write("\x1b[2J\x1b[H");
314
- await renderDashboard(displayName, {
315
- teamName: effectiveTeamName,
316
- supervisorUrl,
317
- teamState,
318
- });
319
- console.log(`${DIM} ${intervalSec}초 간격 갱신 | Ctrl+C로 종료${RESET}`);
320
- await new Promise((r) => setTimeout(r, intervalSec * 1000));
321
- }
322
- }
@@ -1,84 +0,0 @@
1
- // hub/team/event-log.mjs — JSONL 블랙박스 리코더
2
- // Conductor 세션 lifecycle 이벤트를 JSONL 파일에 기록한다.
3
- // 기존 hub/server.mjs의 batch-events.jsonl(MCP 이벤트)과 독립. 공존.
4
-
5
- import { createWriteStream, mkdirSync } from "node:fs";
6
- import { dirname } from "node:path";
7
-
8
- /**
9
- * JSONL event log 팩토리.
10
- * @param {string} filePath — 로그 파일 경로 (.jsonl)
11
- * @param {object} [opts]
12
- * @param {string} [opts.sessionId] — 모든 이벤트에 자동 삽입할 세션 ID
13
- * @returns {{ append, flush, close, filePath }}
14
- */
15
- export function createEventLog(filePath, opts = {}) {
16
- const { sessionId } = opts;
17
-
18
- mkdirSync(dirname(filePath), { recursive: true });
19
- const stream = createWriteStream(filePath, { flags: "a" });
20
-
21
- let closed = false;
22
- let pending = 0;
23
-
24
- /**
25
- * 이벤트를 JSONL 한 줄로 기록.
26
- * @param {string} event — 이벤트 타입 (spawn, health, kill, stateChange, ...)
27
- * @param {object} [data] — 이벤트 페이로드
28
- */
29
- function append(event, data = {}) {
30
- if (closed) return;
31
- const entry = {
32
- ts: new Date().toISOString(),
33
- ...(sessionId ? { session: sessionId } : {}),
34
- event,
35
- ...data,
36
- };
37
- pending += 1;
38
- stream.write(JSON.stringify(entry) + "\n", () => {
39
- pending -= 1;
40
- });
41
- }
42
-
43
- /**
44
- * 버퍼된 이벤트를 디스크에 flush.
45
- * @returns {Promise<void>}
46
- */
47
- function flush() {
48
- if (closed) return Promise.resolve();
49
- return new Promise((resolve, reject) => {
50
- stream.once("error", reject);
51
- stream.write("", () => {
52
- stream.removeListener("error", reject);
53
- resolve();
54
- });
55
- });
56
- }
57
-
58
- /**
59
- * 스트림 종료. flush 후 close.
60
- * @returns {Promise<void>}
61
- */
62
- function close() {
63
- if (closed) return Promise.resolve();
64
- closed = true;
65
- return new Promise((resolve) => {
66
- stream.end(() => resolve());
67
- });
68
- }
69
-
70
- return Object.freeze({
71
- append,
72
- flush,
73
- close,
74
- get filePath() {
75
- return filePath;
76
- },
77
- get pending() {
78
- return pending;
79
- },
80
- get closed() {
81
- return closed;
82
- },
83
- });
84
- }