@triflux/core 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.
- package/hooks/agy-session-hook.mjs +11 -56
- package/hooks/codex-session-hook.mjs +11 -101
- package/hub/bridge.mjs +65 -1250
- package/hub/cli-adapter-base.mjs +12 -90
- package/hub/codex-adapter.mjs +0 -1
- package/hub/codex-preflight.mjs +5 -28
- package/hub/index.mjs +3 -19
- package/hub/lib/process-utils.mjs +1 -156
- package/hub/lib/spawn-trace.mjs +3 -2
- package/hub/lib/timeout-defaults.mjs +0 -1
- package/hub/team/claude-daemon-control.mjs +1 -2
- package/hub/team/claude-session-projection.mjs +5 -73
- package/hub/team/nativeProxy.mjs +759 -0
- package/hub/team/session-context.mjs +1 -1
- package/hud/cli-policy.mjs +0 -22
- package/hud/constants.mjs +13 -26
- package/hud/hud-qos-status.mjs +42 -54
- package/hud/providers/gemini.mjs +125 -20
- package/hud/renderers.mjs +101 -122
- package/hud/utils.mjs +10 -6
- package/package.json +2 -6
- package/scripts/lib/agent-route-policy.mjs +143 -62
- package/scripts/lib/cli-claude.mjs +0 -14
- package/scripts/lib/env-probe.mjs +2 -131
- package/scripts/lib/gemini-profiles.mjs +2 -69
- package/scripts/lib/legacy-mcp-cleanup.mjs +283 -0
- package/scripts/lib/machine-profile.mjs +3 -17
- package/scripts/lib/mcp-filter.mjs +109 -53
- package/scripts/lib/mcp-guard-engine.mjs +40 -98
- package/scripts/lib/mcp-health.mjs +2 -2
- package/scripts/lib/mcp-server-catalog.mjs +2 -2
- package/scripts/lib/psmux-info.mjs +11 -59
- package/scripts/lib/session-presence.mjs +2 -100
- package/scripts/lib/skill-template.mjs +0 -245
- package/hub/adaptive-diagnostic.mjs +0 -350
- package/hub/adaptive-inject.mjs +0 -224
- package/hub/adaptive-memory.mjs +0 -277
- package/hub/adaptive.mjs +0 -172
- package/hub/assign-callbacks.mjs +0 -170
- package/hub/delegator/contracts.mjs +0 -38
- package/hub/delegator/index.mjs +0 -14
- package/hub/delegator/schema/delegator-tools.schema.json +0 -250
- package/hub/delegator/service.mjs +0 -336
- package/hub/delegator/tool-definitions.mjs +0 -35
- package/hub/dynamic-routing-engine.mjs +0 -511
- package/hub/hitl.mjs +0 -202
- package/hub/lib/known-errors.json +0 -72
- package/hub/lib/memory-store.mjs +0 -1001
- package/hub/lib/phase-manager.mjs +0 -493
- package/hub/lib/risk-tier.mjs +0 -53
- package/hub/lib/ssh-command.mjs +0 -231
- package/hub/lib/staged-file-detect.mjs +0 -43
- package/hub/lib/state-snapshot.mjs +0 -293
- package/hub/lib/tfx-route-args.mjs +0 -353
- package/hub/lib/trace-recorder.mjs +0 -153
- package/hub/lib/uuidv7.mjs +0 -45
- package/hub/memory-doctor.mjs +0 -640
- package/hub/middleware/quota-middleware.mjs +0 -70
- package/hub/middleware/request-logger.mjs +0 -191
- package/hub/paths.mjs +0 -24
- package/hub/pipeline/index.mjs +0 -163
- package/hub/pipeline/state.mjs +0 -191
- package/hub/pipeline/transitions.mjs +0 -131
- package/hub/reflexion.mjs +0 -290
- package/hub/role-contract.mjs +0 -314
- package/hub/router.mjs +0 -2026
- package/hub/routing-snapshot.mjs +0 -261
- package/hub/session-fingerprint.mjs +0 -418
- package/hub/state.mjs +0 -300
- package/hub/team/synapse-http.mjs +0 -311
- package/hub/team-bridge.mjs +0 -27
- package/mesh/index.mjs +0 -69
- package/mesh/mesh-budget.mjs +0 -137
- package/mesh/mesh-heartbeat.mjs +0 -100
- package/mesh/mesh-protocol.mjs +0 -96
- package/mesh/mesh-queue.mjs +0 -163
- package/mesh/mesh-registry.mjs +0 -78
- package/mesh/mesh-router.mjs +0 -77
- package/scripts/lib/claudemd-scanner.mjs +0 -223
- package/scripts/lib/context.mjs +0 -67
- package/scripts/lib/dynamic-route-cli.mjs +0 -107
- package/scripts/lib/handoff.mjs +0 -187
- package/scripts/lib/logger.mjs +0 -122
- package/scripts/lib/stealth-fetch.mjs +0 -176
package/hub/bridge.mjs
CHANGED
|
@@ -1,452 +1,47 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
// hub/bridge.mjs
|
|
4
|
-
//
|
|
5
|
-
// Named Pipe/Unix Socket 제어 채널을 우선 사용하고,
|
|
6
|
-
// 연결이 없을 때만 HTTP /bridge/* 엔드포인트로 내려간다.
|
|
3
|
+
// hub/bridge.mjs: tfx-route.sh 와 tfx-live 가 부르는 로컬 제어 CLI.
|
|
4
|
+
// 팀 하위 명령은 nativeProxy 를 직접 호출하고 Claude daemon, retry, intervene 은 로컬 모듈만 쓴다.
|
|
7
5
|
|
|
8
|
-
import {
|
|
9
|
-
import { randomUUID } from "node:crypto";
|
|
10
|
-
import {
|
|
11
|
-
existsSync,
|
|
12
|
-
mkdirSync,
|
|
13
|
-
openSync,
|
|
14
|
-
readFileSync,
|
|
15
|
-
writeFileSync,
|
|
16
|
-
} from "node:fs";
|
|
17
|
-
import net from "node:net";
|
|
18
|
-
import { homedir } from "node:os";
|
|
19
|
-
import { join } from "node:path";
|
|
20
|
-
import { fileURLToPath } from "node:url";
|
|
6
|
+
import { readFileSync } from "node:fs";
|
|
21
7
|
import { parseArgs as nodeParseArgs } from "node:util";
|
|
22
8
|
|
|
23
|
-
import { getPipelineStateDbPath } from "./pipeline/state.mjs";
|
|
24
9
|
import {
|
|
25
10
|
createRetryStateMachine,
|
|
26
11
|
loadSnapshot,
|
|
27
12
|
saveSnapshot,
|
|
28
13
|
} from "./team/retry-state-machine.mjs";
|
|
29
14
|
|
|
30
|
-
const HUB_PID_FILE = join(homedir(), ".claude", "cache", "tfx-hub", "hub.pid");
|
|
31
|
-
const HUB_TOKEN_FILE = join(homedir(), ".claude", ".tfx-hub-token");
|
|
32
|
-
const PROJECT_ROOT = fileURLToPath(new URL("..", import.meta.url));
|
|
33
|
-
const HUB_DEFAULT_PORT = 27888;
|
|
34
|
-
const LOOPBACK_HOSTS = new Set(["127.0.0.1", "localhost", "::1"]);
|
|
35
|
-
|
|
36
|
-
function formatHostForUrl(host) {
|
|
37
|
-
return host.includes(":") ? `[${host}]` : host;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
function normalizeLoopbackHost(host) {
|
|
41
|
-
if (typeof host !== "string") return "127.0.0.1";
|
|
42
|
-
const candidate = host.trim();
|
|
43
|
-
return LOOPBACK_HOSTS.has(candidate) ? candidate : "127.0.0.1";
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
function normalizeToken(raw) {
|
|
47
|
-
if (raw == null) return null;
|
|
48
|
-
const token = String(raw).trim();
|
|
49
|
-
return token || null;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
// Hub 인증 토큰 읽기 (파일 없으면 null → 하위 호환)
|
|
53
|
-
function readHubToken() {
|
|
54
|
-
const envToken = normalizeToken(process.env.TFX_HUB_TOKEN);
|
|
55
|
-
if (envToken) return envToken;
|
|
56
|
-
try {
|
|
57
|
-
return normalizeToken(readFileSync(HUB_TOKEN_FILE, "utf8"));
|
|
58
|
-
} catch {
|
|
59
|
-
return null;
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
export function getHubUrl() {
|
|
64
|
-
if (process.env.TFX_HUB_URL)
|
|
65
|
-
return process.env.TFX_HUB_URL.replace(/\/mcp$/, "");
|
|
66
|
-
|
|
67
|
-
const envPort = Number.parseInt(String(process.env.TFX_HUB_PORT ?? ""), 10);
|
|
68
|
-
const port =
|
|
69
|
-
Number.isFinite(envPort) && envPort > 0 ? envPort : HUB_DEFAULT_PORT;
|
|
70
|
-
let host = "127.0.0.1";
|
|
71
|
-
|
|
72
|
-
if (existsSync(HUB_PID_FILE)) {
|
|
73
|
-
try {
|
|
74
|
-
const info = JSON.parse(readFileSync(HUB_PID_FILE, "utf8"));
|
|
75
|
-
host = normalizeLoopbackHost(info?.host);
|
|
76
|
-
} catch {
|
|
77
|
-
// 무시
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
return `http://${formatHostForUrl(host)}:${port}`;
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
export function getHubPipePath() {
|
|
85
|
-
if (process.env.TFX_HUB_PIPE) return process.env.TFX_HUB_PIPE;
|
|
86
|
-
|
|
87
|
-
if (!existsSync(HUB_PID_FILE)) return null;
|
|
88
|
-
try {
|
|
89
|
-
const info = JSON.parse(readFileSync(HUB_PID_FILE, "utf8"));
|
|
90
|
-
return info.pipe_path || info.pipePath || null;
|
|
91
|
-
} catch {
|
|
92
|
-
return null;
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
const HUB_OPERATIONS = Object.freeze({
|
|
97
|
-
register: {
|
|
98
|
-
transport: "command",
|
|
99
|
-
action: "register",
|
|
100
|
-
httpPath: "/bridge/register",
|
|
101
|
-
},
|
|
102
|
-
heartbeat: {
|
|
103
|
-
transport: "command",
|
|
104
|
-
action: "heartbeat",
|
|
105
|
-
httpPath: "/bridge/heartbeat",
|
|
106
|
-
},
|
|
107
|
-
result: {
|
|
108
|
-
transport: "command",
|
|
109
|
-
action: "result",
|
|
110
|
-
httpPath: "/bridge/result",
|
|
111
|
-
},
|
|
112
|
-
control: {
|
|
113
|
-
transport: "command",
|
|
114
|
-
action: "control",
|
|
115
|
-
httpPath: "/bridge/control",
|
|
116
|
-
},
|
|
117
|
-
handoff: {
|
|
118
|
-
transport: "command",
|
|
119
|
-
action: "handoff",
|
|
120
|
-
httpPath: "/bridge/handoff",
|
|
121
|
-
},
|
|
122
|
-
publish: {
|
|
123
|
-
transport: "command",
|
|
124
|
-
action: "publish",
|
|
125
|
-
httpPath: "/bridge/publish",
|
|
126
|
-
},
|
|
127
|
-
takeoverRole: {
|
|
128
|
-
transport: "command",
|
|
129
|
-
action: "takeover_role",
|
|
130
|
-
httpPath: "/bridge/takeover-role",
|
|
131
|
-
},
|
|
132
|
-
sendInput: {
|
|
133
|
-
transport: "command",
|
|
134
|
-
action: "send_input",
|
|
135
|
-
httpPath: "/bridge/send-input",
|
|
136
|
-
},
|
|
137
|
-
context: { transport: "query", action: "drain", httpPath: "/bridge/context" },
|
|
138
|
-
deregister: {
|
|
139
|
-
transport: "command",
|
|
140
|
-
action: "deregister",
|
|
141
|
-
httpPath: "/bridge/deregister",
|
|
142
|
-
},
|
|
143
|
-
assignAsync: {
|
|
144
|
-
transport: "command",
|
|
145
|
-
action: "assign",
|
|
146
|
-
httpPath: "/bridge/assign/async",
|
|
147
|
-
},
|
|
148
|
-
assignResult: {
|
|
149
|
-
transport: "command",
|
|
150
|
-
action: "assign_result",
|
|
151
|
-
httpPath: "/bridge/assign/result",
|
|
152
|
-
},
|
|
153
|
-
assignStatus: {
|
|
154
|
-
transport: "query",
|
|
155
|
-
action: "assign_status",
|
|
156
|
-
httpPath: "/bridge/assign/status",
|
|
157
|
-
},
|
|
158
|
-
assignRetry: {
|
|
159
|
-
transport: "command",
|
|
160
|
-
action: "assign_retry",
|
|
161
|
-
httpPath: "/bridge/assign/retry",
|
|
162
|
-
},
|
|
163
|
-
teamInfo: {
|
|
164
|
-
transport: "query",
|
|
165
|
-
action: "team_info",
|
|
166
|
-
httpPath: "/bridge/team/info",
|
|
167
|
-
},
|
|
168
|
-
teamTaskList: {
|
|
169
|
-
transport: "query",
|
|
170
|
-
action: "team_task_list",
|
|
171
|
-
httpPath: "/bridge/team/task-list",
|
|
172
|
-
},
|
|
173
|
-
teamTaskUpdate: {
|
|
174
|
-
transport: "command",
|
|
175
|
-
action: "team_task_update",
|
|
176
|
-
httpPath: "/bridge/team/task-update",
|
|
177
|
-
},
|
|
178
|
-
teamSendMessage: {
|
|
179
|
-
transport: "command",
|
|
180
|
-
action: "team_send_message",
|
|
181
|
-
httpPath: "/bridge/team/send-message",
|
|
182
|
-
},
|
|
183
|
-
pipelineState: {
|
|
184
|
-
transport: "query",
|
|
185
|
-
action: "pipeline_state",
|
|
186
|
-
httpPath: "/bridge/pipeline/state",
|
|
187
|
-
},
|
|
188
|
-
pipelineAdvance: {
|
|
189
|
-
transport: "command",
|
|
190
|
-
action: "pipeline_advance",
|
|
191
|
-
httpPath: "/bridge/pipeline/advance",
|
|
192
|
-
},
|
|
193
|
-
pipelineInit: {
|
|
194
|
-
transport: "command",
|
|
195
|
-
action: "pipeline_init",
|
|
196
|
-
httpPath: "/bridge/pipeline/init",
|
|
197
|
-
},
|
|
198
|
-
pipelineList: {
|
|
199
|
-
transport: "query",
|
|
200
|
-
action: "pipeline_list",
|
|
201
|
-
httpPath: "/bridge/pipeline/list",
|
|
202
|
-
},
|
|
203
|
-
hubStatus: {
|
|
204
|
-
transport: "query",
|
|
205
|
-
action: "status",
|
|
206
|
-
httpPath: "/status",
|
|
207
|
-
httpMethod: "GET",
|
|
208
|
-
},
|
|
209
|
-
delegatorDelegate: {
|
|
210
|
-
transport: "command",
|
|
211
|
-
action: "delegator_delegate",
|
|
212
|
-
httpPath: "/bridge/delegator/delegate",
|
|
213
|
-
},
|
|
214
|
-
delegatorReply: {
|
|
215
|
-
transport: "command",
|
|
216
|
-
action: "delegator_reply",
|
|
217
|
-
httpPath: "/bridge/delegator/reply",
|
|
218
|
-
},
|
|
219
|
-
delegatorStatus: {
|
|
220
|
-
transport: "query",
|
|
221
|
-
action: "delegator_status",
|
|
222
|
-
httpPath: "/bridge/delegator/status",
|
|
223
|
-
},
|
|
224
|
-
"hitl-request": {
|
|
225
|
-
transport: "command",
|
|
226
|
-
action: "hitl_request",
|
|
227
|
-
httpPath: "/bridge/hitl/request",
|
|
228
|
-
},
|
|
229
|
-
"hitl-submit": {
|
|
230
|
-
transport: "command",
|
|
231
|
-
action: "hitl_submit",
|
|
232
|
-
httpPath: "/bridge/hitl/submit",
|
|
233
|
-
},
|
|
234
|
-
"hitl-pending": {
|
|
235
|
-
transport: "query",
|
|
236
|
-
action: "hitl_pending",
|
|
237
|
-
httpPath: "/bridge/hitl/pending",
|
|
238
|
-
},
|
|
239
|
-
});
|
|
240
|
-
|
|
241
|
-
export async function requestJson(
|
|
242
|
-
path,
|
|
243
|
-
{ method = "POST", body, timeoutMs = 5000 } = {},
|
|
244
|
-
) {
|
|
245
|
-
const controller = new AbortController();
|
|
246
|
-
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
247
|
-
|
|
248
|
-
try {
|
|
249
|
-
const headers = {};
|
|
250
|
-
const token = readHubToken();
|
|
251
|
-
if (token) {
|
|
252
|
-
headers.Authorization = `Bearer ${token}`;
|
|
253
|
-
}
|
|
254
|
-
if (body !== undefined) {
|
|
255
|
-
headers["Content-Type"] = "application/json";
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
const res = await fetch(`${getHubUrl()}${path}`, {
|
|
259
|
-
method,
|
|
260
|
-
headers,
|
|
261
|
-
body: body === undefined ? undefined : JSON.stringify(body),
|
|
262
|
-
signal: controller.signal,
|
|
263
|
-
});
|
|
264
|
-
clearTimeout(timer);
|
|
265
|
-
return await res.json();
|
|
266
|
-
} catch {
|
|
267
|
-
clearTimeout(timer);
|
|
268
|
-
return null;
|
|
269
|
-
}
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
export async function post(path, body, timeoutMs = 5000) {
|
|
273
|
-
return await requestJson(path, { method: "POST", body, timeoutMs });
|
|
274
|
-
}
|
|
275
|
-
|
|
276
|
-
export async function connectPipe(timeoutMs = 1200) {
|
|
277
|
-
const pipePath = getHubPipePath();
|
|
278
|
-
if (!pipePath) return null;
|
|
279
|
-
|
|
280
|
-
return await new Promise((resolve) => {
|
|
281
|
-
const socket = net.createConnection(pipePath);
|
|
282
|
-
const timer = setTimeout(() => {
|
|
283
|
-
try {
|
|
284
|
-
socket.destroy();
|
|
285
|
-
} catch {}
|
|
286
|
-
resolve(null);
|
|
287
|
-
}, timeoutMs);
|
|
288
|
-
|
|
289
|
-
socket.once("connect", () => {
|
|
290
|
-
clearTimeout(timer);
|
|
291
|
-
socket.setEncoding("utf8");
|
|
292
|
-
resolve(socket);
|
|
293
|
-
});
|
|
294
|
-
|
|
295
|
-
socket.once("error", () => {
|
|
296
|
-
clearTimeout(timer);
|
|
297
|
-
try {
|
|
298
|
-
socket.destroy();
|
|
299
|
-
} catch {}
|
|
300
|
-
resolve(null);
|
|
301
|
-
});
|
|
302
|
-
});
|
|
303
|
-
}
|
|
304
|
-
|
|
305
|
-
async function pipeRequest(type, action, payload, timeoutMs = 3000) {
|
|
306
|
-
const socket = await connectPipe(Math.min(timeoutMs, 1500));
|
|
307
|
-
if (!socket) return null;
|
|
308
|
-
|
|
309
|
-
return await new Promise((resolve) => {
|
|
310
|
-
const requestId = randomUUID();
|
|
311
|
-
let buffer = "";
|
|
312
|
-
let settled = false;
|
|
313
|
-
const timer = setTimeout(() => {
|
|
314
|
-
finish(null);
|
|
315
|
-
}, timeoutMs);
|
|
316
|
-
|
|
317
|
-
const finish = (result) => {
|
|
318
|
-
if (settled) return;
|
|
319
|
-
settled = true;
|
|
320
|
-
clearTimeout(timer);
|
|
321
|
-
try {
|
|
322
|
-
socket.end();
|
|
323
|
-
} catch {}
|
|
324
|
-
resolve(result);
|
|
325
|
-
};
|
|
326
|
-
|
|
327
|
-
socket.on("data", (chunk) => {
|
|
328
|
-
buffer += chunk;
|
|
329
|
-
let newlineIndex = buffer.indexOf("\n");
|
|
330
|
-
while (newlineIndex >= 0) {
|
|
331
|
-
const line = buffer.slice(0, newlineIndex).trim();
|
|
332
|
-
buffer = buffer.slice(newlineIndex + 1);
|
|
333
|
-
newlineIndex = buffer.indexOf("\n");
|
|
334
|
-
if (!line) continue;
|
|
335
|
-
|
|
336
|
-
let frame;
|
|
337
|
-
try {
|
|
338
|
-
frame = JSON.parse(line);
|
|
339
|
-
} catch {
|
|
340
|
-
continue;
|
|
341
|
-
}
|
|
342
|
-
|
|
343
|
-
if (frame?.type !== "response" || frame.request_id !== requestId)
|
|
344
|
-
continue;
|
|
345
|
-
finish({
|
|
346
|
-
ok: frame.ok,
|
|
347
|
-
error: frame.error,
|
|
348
|
-
data: frame.data,
|
|
349
|
-
});
|
|
350
|
-
return;
|
|
351
|
-
}
|
|
352
|
-
});
|
|
353
|
-
|
|
354
|
-
socket.on("error", () => finish(null));
|
|
355
|
-
socket.write(
|
|
356
|
-
JSON.stringify({
|
|
357
|
-
type,
|
|
358
|
-
request_id: requestId,
|
|
359
|
-
payload: { action, ...payload },
|
|
360
|
-
}) + "\n",
|
|
361
|
-
);
|
|
362
|
-
});
|
|
363
|
-
}
|
|
364
|
-
|
|
365
|
-
async function pipeCommand(action, payload, timeoutMs = 3000) {
|
|
366
|
-
return await pipeRequest("command", action, payload, timeoutMs);
|
|
367
|
-
}
|
|
368
|
-
|
|
369
|
-
async function pipeQuery(action, payload, timeoutMs = 3000) {
|
|
370
|
-
return await pipeRequest("query", action, payload, timeoutMs);
|
|
371
|
-
}
|
|
372
|
-
|
|
373
15
|
export function parseArgs(argv) {
|
|
374
16
|
const { values, positionals } = nodeParseArgs({
|
|
375
17
|
args: argv,
|
|
376
18
|
options: {
|
|
377
|
-
agent: { type: "string" },
|
|
378
|
-
"agent-id": { type: "string" },
|
|
379
|
-
cli: { type: "string" },
|
|
380
|
-
timeout: { type: "string" },
|
|
381
|
-
topics: { type: "string" },
|
|
382
|
-
capabilities: { type: "string" },
|
|
383
|
-
file: { type: "string" },
|
|
384
|
-
payload: { type: "string" },
|
|
385
|
-
"payload-file": { type: "string" },
|
|
386
|
-
topic: { type: "string" },
|
|
387
|
-
trace: { type: "string" },
|
|
388
|
-
correlation: { type: "string" },
|
|
389
|
-
"exit-code": { type: "string" },
|
|
390
|
-
max: { type: "string" },
|
|
391
|
-
out: { type: "string" },
|
|
392
19
|
team: { type: "string" },
|
|
393
20
|
"task-id": { type: "string" },
|
|
394
|
-
"job-id": { type: "string" },
|
|
395
21
|
owner: { type: "string" },
|
|
396
22
|
status: { type: "string" },
|
|
397
23
|
statuses: { type: "string" },
|
|
398
24
|
claim: { type: "boolean" },
|
|
399
25
|
actor: { type: "string" },
|
|
400
|
-
command: { type: "string" },
|
|
401
|
-
role: { type: "string" },
|
|
402
|
-
"session-id": { type: "string" },
|
|
403
|
-
cwd: { type: "string" },
|
|
404
|
-
"worktree-path": { type: "string" },
|
|
405
|
-
branch: { type: "string" },
|
|
406
|
-
host: { type: "string" },
|
|
407
|
-
"session-kind": { type: "string" },
|
|
408
|
-
"is-remote": { type: "string" },
|
|
409
|
-
"tmux-session": { type: "string" },
|
|
410
|
-
"tmux-pane": { type: "string" },
|
|
411
|
-
"omx-session-id": { type: "string" },
|
|
412
|
-
"codex-session-id": { type: "string" },
|
|
413
|
-
reason: { type: "string" },
|
|
414
|
-
type: { type: "string" },
|
|
415
26
|
from: { type: "string" },
|
|
416
27
|
to: { type: "string" },
|
|
417
28
|
text: { type: "string" },
|
|
418
|
-
task: { type: "string" },
|
|
419
|
-
"supervisor-agent": { type: "string" },
|
|
420
|
-
"worker-agent": { type: "string" },
|
|
421
|
-
priority: { type: "string" },
|
|
422
|
-
"ttl-ms": { type: "string" },
|
|
423
|
-
"timeout-ms": { type: "string" },
|
|
424
|
-
"max-retries": { type: "string" },
|
|
425
|
-
attempt: { type: "string" },
|
|
426
|
-
result: { type: "string" },
|
|
427
|
-
error: { type: "string" },
|
|
428
|
-
metadata: { type: "string" },
|
|
429
|
-
"requested-by": { type: "string" },
|
|
430
29
|
summary: { type: "string" },
|
|
431
30
|
color: { type: "string" },
|
|
432
31
|
limit: { type: "string" },
|
|
433
32
|
"include-internal": { type: "boolean" },
|
|
434
33
|
subject: { type: "string" },
|
|
435
34
|
description: { type: "string" },
|
|
436
|
-
"fix-max": { type: "string" },
|
|
437
|
-
"ralph-max": { type: "string" },
|
|
438
35
|
"active-form": { type: "string" },
|
|
439
36
|
"add-blocks": { type: "string" },
|
|
440
37
|
"add-blocked-by": { type: "string" },
|
|
441
38
|
"metadata-patch": { type: "string" },
|
|
442
39
|
"if-match-mtime-ms": { type: "string" },
|
|
443
|
-
|
|
40
|
+
payload: { type: "string" },
|
|
41
|
+
"payload-file": { type: "string" },
|
|
42
|
+
"session-id": { type: "string" },
|
|
43
|
+
reason: { type: "string" },
|
|
444
44
|
mode: { type: "string" },
|
|
445
|
-
prompt: { type: "string" },
|
|
446
|
-
reply: { type: "string" },
|
|
447
|
-
done: { type: "boolean" },
|
|
448
|
-
"mcp-profile": { type: "string" },
|
|
449
|
-
"session-key": { type: "string" },
|
|
450
45
|
snapshot: { type: "string" },
|
|
451
46
|
"snapshot-file": { type: "string" },
|
|
452
47
|
event: { type: "string" },
|
|
@@ -486,201 +81,6 @@ export function readBridgePayload(args = {}, stdin) {
|
|
|
486
81
|
return {};
|
|
487
82
|
}
|
|
488
83
|
|
|
489
|
-
function normalizeBridgePayload(payload) {
|
|
490
|
-
if (!payload || typeof payload !== "object" || Array.isArray(payload)) {
|
|
491
|
-
return {};
|
|
492
|
-
}
|
|
493
|
-
return payload;
|
|
494
|
-
}
|
|
495
|
-
|
|
496
|
-
function buildHandoffBody(from, to, payload) {
|
|
497
|
-
const normalizedPayload = normalizeBridgePayload(payload);
|
|
498
|
-
return {
|
|
499
|
-
...normalizedPayload,
|
|
500
|
-
from,
|
|
501
|
-
to,
|
|
502
|
-
payload: normalizedPayload,
|
|
503
|
-
};
|
|
504
|
-
}
|
|
505
|
-
|
|
506
|
-
function buildPublishBody(from, to, type, payload) {
|
|
507
|
-
const normalizedPayload = normalizeBridgePayload(payload);
|
|
508
|
-
return {
|
|
509
|
-
...normalizedPayload,
|
|
510
|
-
from,
|
|
511
|
-
to,
|
|
512
|
-
type,
|
|
513
|
-
message_type: type,
|
|
514
|
-
payload: normalizedPayload,
|
|
515
|
-
};
|
|
516
|
-
}
|
|
517
|
-
|
|
518
|
-
// Hub 자동 재시작 (Pipe+HTTP 모두 실패 시 1회 시도, 최대 4초 대기)
|
|
519
|
-
async function tryRestartHub() {
|
|
520
|
-
const serverPath = join(PROJECT_ROOT, "hub", "server.mjs");
|
|
521
|
-
if (!existsSync(serverPath)) return false;
|
|
522
|
-
|
|
523
|
-
if (existsSync(HUB_PID_FILE)) {
|
|
524
|
-
try {
|
|
525
|
-
const info = JSON.parse(readFileSync(HUB_PID_FILE, "utf8"));
|
|
526
|
-
if (info.pid) {
|
|
527
|
-
try {
|
|
528
|
-
process.kill(info.pid, 0);
|
|
529
|
-
return false;
|
|
530
|
-
} catch (e) {
|
|
531
|
-
// still alive
|
|
532
|
-
if (e.code === "EPERM") return false;
|
|
533
|
-
} // alive, no permission
|
|
534
|
-
}
|
|
535
|
-
} catch {} // corrupt PID file, proceed with restart
|
|
536
|
-
}
|
|
537
|
-
|
|
538
|
-
try {
|
|
539
|
-
const logDir = join(process.cwd(), ".tfx", "logs");
|
|
540
|
-
if (!existsSync(logDir)) mkdirSync(logDir, { recursive: true });
|
|
541
|
-
const logFile = join(logDir, "hub-restart.log");
|
|
542
|
-
const logFd = openSync(logFile, "a");
|
|
543
|
-
const child = spawn(process.execPath, [serverPath], {
|
|
544
|
-
detached: true,
|
|
545
|
-
stdio: ["ignore", "ignore", logFd],
|
|
546
|
-
windowsHide: true,
|
|
547
|
-
});
|
|
548
|
-
child.unref();
|
|
549
|
-
} catch {
|
|
550
|
-
return false;
|
|
551
|
-
}
|
|
552
|
-
|
|
553
|
-
for (let i = 0; i < 8; i++) {
|
|
554
|
-
await new Promise((r) => setTimeout(r, 500));
|
|
555
|
-
try {
|
|
556
|
-
const res = await fetch(`${getHubUrl()}/status`, {
|
|
557
|
-
signal: AbortSignal.timeout(1000),
|
|
558
|
-
});
|
|
559
|
-
if (res.ok) {
|
|
560
|
-
const data = await res.json();
|
|
561
|
-
if (data?.hub?.state === "healthy") return true;
|
|
562
|
-
}
|
|
563
|
-
} catch {}
|
|
564
|
-
}
|
|
565
|
-
return false;
|
|
566
|
-
}
|
|
567
|
-
|
|
568
|
-
async function requestHub(operation, body, timeoutMs = 3000, fallback = null) {
|
|
569
|
-
const viaPipe =
|
|
570
|
-
operation.transport === "command"
|
|
571
|
-
? await pipeCommand(operation.action, body, timeoutMs)
|
|
572
|
-
: await pipeQuery(operation.action, body, timeoutMs);
|
|
573
|
-
if (viaPipe) {
|
|
574
|
-
return { transport: "pipe", result: viaPipe };
|
|
575
|
-
}
|
|
576
|
-
|
|
577
|
-
const viaHttp = operation.httpPath
|
|
578
|
-
? await requestJson(operation.httpPath, {
|
|
579
|
-
method: operation.httpMethod || "POST",
|
|
580
|
-
body: operation.httpMethod === "GET" ? undefined : body,
|
|
581
|
-
timeoutMs: Math.max(timeoutMs, 5000),
|
|
582
|
-
})
|
|
583
|
-
: null;
|
|
584
|
-
if (viaHttp) {
|
|
585
|
-
return { transport: "http", result: viaHttp };
|
|
586
|
-
}
|
|
587
|
-
|
|
588
|
-
// Hub 재시작 시도 → Pipe/HTTP 재시도
|
|
589
|
-
if (await tryRestartHub()) {
|
|
590
|
-
const retryPipe =
|
|
591
|
-
operation.transport === "command"
|
|
592
|
-
? await pipeCommand(operation.action, body, timeoutMs)
|
|
593
|
-
: await pipeQuery(operation.action, body, timeoutMs);
|
|
594
|
-
if (retryPipe) {
|
|
595
|
-
return { transport: "pipe", result: retryPipe };
|
|
596
|
-
}
|
|
597
|
-
const retryHttp = operation.httpPath
|
|
598
|
-
? await requestJson(operation.httpPath, {
|
|
599
|
-
method: operation.httpMethod || "POST",
|
|
600
|
-
body: operation.httpMethod === "GET" ? undefined : body,
|
|
601
|
-
timeoutMs: Math.max(timeoutMs, 5000),
|
|
602
|
-
})
|
|
603
|
-
: null;
|
|
604
|
-
if (retryHttp) {
|
|
605
|
-
return { transport: "http", result: retryHttp };
|
|
606
|
-
}
|
|
607
|
-
}
|
|
608
|
-
|
|
609
|
-
if (!fallback) return null;
|
|
610
|
-
const viaFallback = await fallback();
|
|
611
|
-
if (!viaFallback) return null;
|
|
612
|
-
return { transport: "fallback", result: viaFallback };
|
|
613
|
-
}
|
|
614
|
-
|
|
615
|
-
function unavailableResult() {
|
|
616
|
-
return { ok: false, reason: "hub_unavailable" };
|
|
617
|
-
}
|
|
618
|
-
|
|
619
|
-
function nonEmptyString(value, fallback = "") {
|
|
620
|
-
const normalized = String(value ?? "").trim();
|
|
621
|
-
return normalized || fallback;
|
|
622
|
-
}
|
|
623
|
-
|
|
624
|
-
function readBoolean(value) {
|
|
625
|
-
return ["1", "true", "yes"].includes(nonEmptyString(value).toLowerCase());
|
|
626
|
-
}
|
|
627
|
-
|
|
628
|
-
function sessionAgentId(sessionId) {
|
|
629
|
-
return `codex-session-${sessionId.replace(/[^A-Za-z0-9._-]/g, "_")}`;
|
|
630
|
-
}
|
|
631
|
-
|
|
632
|
-
export function buildInteractiveSessionRegistrationPayload(args = {}) {
|
|
633
|
-
const sessionId = nonEmptyString(args["session-id"]);
|
|
634
|
-
if (!sessionId) return null;
|
|
635
|
-
|
|
636
|
-
const cwd = nonEmptyString(args.cwd, process.cwd());
|
|
637
|
-
const worktreePath = nonEmptyString(args["worktree-path"], cwd);
|
|
638
|
-
const host = nonEmptyString(args.host, "local");
|
|
639
|
-
const sessionKind = nonEmptyString(args["session-kind"], "interactive");
|
|
640
|
-
const agentId = nonEmptyString(args.agent, sessionAgentId(sessionId));
|
|
641
|
-
const metadata = {
|
|
642
|
-
pid: process.ppid,
|
|
643
|
-
registered_at: Date.now(),
|
|
644
|
-
cwd,
|
|
645
|
-
worktree_path: worktreePath,
|
|
646
|
-
branch: nonEmptyString(args.branch),
|
|
647
|
-
host,
|
|
648
|
-
session_kind: sessionKind,
|
|
649
|
-
is_remote: readBoolean(args["is-remote"]),
|
|
650
|
-
...(nonEmptyString(args["tmux-session"])
|
|
651
|
-
? { tmux_session: nonEmptyString(args["tmux-session"]) }
|
|
652
|
-
: {}),
|
|
653
|
-
...(nonEmptyString(args["tmux-pane"])
|
|
654
|
-
? { tmux_pane: nonEmptyString(args["tmux-pane"]) }
|
|
655
|
-
: {}),
|
|
656
|
-
...(nonEmptyString(args["omx-session-id"])
|
|
657
|
-
? { omx_session_id: nonEmptyString(args["omx-session-id"]) }
|
|
658
|
-
: {}),
|
|
659
|
-
...(nonEmptyString(args["codex-session-id"])
|
|
660
|
-
? { codex_session_id: nonEmptyString(args["codex-session-id"]) }
|
|
661
|
-
: {}),
|
|
662
|
-
};
|
|
663
|
-
|
|
664
|
-
return {
|
|
665
|
-
sessionId,
|
|
666
|
-
cwd,
|
|
667
|
-
worktreePath,
|
|
668
|
-
branch: nonEmptyString(args.branch),
|
|
669
|
-
host,
|
|
670
|
-
sessionKind,
|
|
671
|
-
isRemote: readBoolean(args["is-remote"]),
|
|
672
|
-
agent_id: agentId,
|
|
673
|
-
cli: nonEmptyString(args.cli, "codex"),
|
|
674
|
-
capabilities: args.capabilities
|
|
675
|
-
? String(args.capabilities).split(",")
|
|
676
|
-
: ["code"],
|
|
677
|
-
topics: args.topics ? String(args.topics).split(",") : [],
|
|
678
|
-
heartbeat_ttl_ms: 300000,
|
|
679
|
-
session_id: sessionId,
|
|
680
|
-
metadata,
|
|
681
|
-
};
|
|
682
|
-
}
|
|
683
|
-
|
|
684
84
|
function emitJson(payload) {
|
|
685
85
|
if (payload !== undefined) {
|
|
686
86
|
console.log(JSON.stringify(payload));
|
|
@@ -688,613 +88,79 @@ function emitJson(payload) {
|
|
|
688
88
|
return payload?.ok !== false;
|
|
689
89
|
}
|
|
690
90
|
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
async function cmdRegister(args) {
|
|
697
|
-
const interactiveSession = buildInteractiveSessionRegistrationPayload(args);
|
|
698
|
-
if (interactiveSession) {
|
|
699
|
-
const result = await requestJson("/synapse/register", {
|
|
700
|
-
body: interactiveSession,
|
|
701
|
-
timeoutMs: 3000,
|
|
702
|
-
});
|
|
703
|
-
return emitJson(result || unavailableResult());
|
|
704
|
-
}
|
|
705
|
-
|
|
706
|
-
const agentId = args.agent;
|
|
707
|
-
const timeoutSec = parseInt(args.timeout || "600", 10);
|
|
708
|
-
const rawCli = args.cli || "other";
|
|
709
|
-
const outcome = await requestHub(HUB_OPERATIONS.register, {
|
|
710
|
-
agent_id: agentId,
|
|
711
|
-
cli: normalizeCliForStore(rawCli),
|
|
712
|
-
timeout_sec: timeoutSec,
|
|
713
|
-
heartbeat_ttl_ms: (timeoutSec + 120) * 1000,
|
|
714
|
-
topics: args.topics ? args.topics.split(",") : [],
|
|
715
|
-
capabilities: args.capabilities ? args.capabilities.split(",") : ["code"],
|
|
716
|
-
metadata: {
|
|
717
|
-
cli: rawCli,
|
|
718
|
-
pid: process.ppid,
|
|
719
|
-
registered_at: Date.now(),
|
|
720
|
-
},
|
|
721
|
-
});
|
|
722
|
-
const result = outcome?.result;
|
|
723
|
-
|
|
724
|
-
if (result?.ok) {
|
|
725
|
-
return emitJson({
|
|
726
|
-
ok: true,
|
|
727
|
-
agent_id: agentId,
|
|
728
|
-
lease_id: result.data?.lease_id,
|
|
729
|
-
presence_generation: result.data?.presence_generation,
|
|
730
|
-
lease_expires_ms: result.data?.lease_expires_ms,
|
|
731
|
-
pipe_path: result.data?.pipe_path || getHubPipePath(),
|
|
732
|
-
hub_instance_id: result.data?.hub_instance_id,
|
|
733
|
-
store_fingerprint: result.data?.store_fingerprint,
|
|
734
|
-
});
|
|
735
|
-
}
|
|
736
|
-
|
|
737
|
-
return emitJson(result || unavailableResult());
|
|
738
|
-
}
|
|
739
|
-
|
|
740
|
-
async function cmdHeartbeat(args) {
|
|
741
|
-
const outcome = await requestHub(HUB_OPERATIONS.heartbeat, {
|
|
742
|
-
agent_id: args.agent,
|
|
743
|
-
ttl_ms: args["ttl-ms"] != null ? Number(args["ttl-ms"]) : undefined,
|
|
744
|
-
presence_generation:
|
|
745
|
-
args.generation != null ? Number(args.generation) : undefined,
|
|
746
|
-
hub_instance_id: args["hub-instance-id"],
|
|
747
|
-
store_fingerprint: args["store-fingerprint"],
|
|
748
|
-
});
|
|
749
|
-
return emitJson(outcome?.result || unavailableResult());
|
|
750
|
-
}
|
|
751
|
-
|
|
752
|
-
async function cmdResult(args) {
|
|
753
|
-
let output = "";
|
|
754
|
-
if (args.file && existsSync(args.file)) {
|
|
755
|
-
output = readFileSync(args.file, "utf8").slice(0, 49152);
|
|
756
|
-
}
|
|
757
|
-
|
|
758
|
-
const defaultPayload = {
|
|
759
|
-
agent_id: args.agent,
|
|
760
|
-
exit_code: parseInt(args["exit-code"] || "0", 10),
|
|
761
|
-
output_length: output.length,
|
|
762
|
-
output_preview: output.slice(0, 4096),
|
|
763
|
-
output_file: args.file || null,
|
|
764
|
-
completed_at: Date.now(),
|
|
765
|
-
};
|
|
766
|
-
|
|
767
|
-
const outcome = await requestHub(HUB_OPERATIONS.result, {
|
|
768
|
-
agent_id: args.agent,
|
|
769
|
-
topic: args.topic || "task.result",
|
|
770
|
-
payload: args.payload
|
|
771
|
-
? parseJsonSafe(args.payload, defaultPayload)
|
|
772
|
-
: defaultPayload,
|
|
773
|
-
trace_id: args.trace || undefined,
|
|
774
|
-
correlation_id: args.correlation || undefined,
|
|
775
|
-
});
|
|
776
|
-
const result = outcome?.result;
|
|
777
|
-
|
|
778
|
-
if (result?.ok) {
|
|
779
|
-
return emitJson({ ok: true, message_id: result.data?.message_id });
|
|
780
|
-
}
|
|
781
|
-
|
|
782
|
-
return emitJson(result || unavailableResult());
|
|
783
|
-
}
|
|
784
|
-
|
|
785
|
-
async function cmdControl(args) {
|
|
786
|
-
const outcome = await requestHub(HUB_OPERATIONS.control, {
|
|
787
|
-
from_agent: args.from || "lead",
|
|
788
|
-
to_agent: args.to,
|
|
789
|
-
command: args.command,
|
|
790
|
-
reason: args.reason || "",
|
|
791
|
-
payload: args.payload ? parseJsonSafe(args.payload, {}) : {},
|
|
792
|
-
trace_id: args.trace || undefined,
|
|
793
|
-
correlation_id: args.correlation || undefined,
|
|
794
|
-
ttl_ms: args["ttl-ms"] != null ? Number(args["ttl-ms"]) : undefined,
|
|
795
|
-
});
|
|
796
|
-
const result = outcome?.result;
|
|
797
|
-
return emitJson(result || unavailableResult());
|
|
798
|
-
}
|
|
799
|
-
|
|
800
|
-
async function cmdHandoff(args) {
|
|
801
|
-
const from = args.from || args[1];
|
|
802
|
-
const to = args.to || args[2];
|
|
803
|
-
const payload = parseJsonSafe(args.payload || args[3] || "{}", {});
|
|
804
|
-
const outcome = await requestHub(
|
|
805
|
-
HUB_OPERATIONS.handoff,
|
|
806
|
-
buildHandoffBody(from, to, payload),
|
|
807
|
-
);
|
|
808
|
-
const result = outcome?.result;
|
|
809
|
-
return emitJson(result || unavailableResult());
|
|
810
|
-
}
|
|
811
|
-
|
|
812
|
-
async function cmdPublish(args) {
|
|
813
|
-
const from = args.from || args[1];
|
|
814
|
-
const to = args.to || args[2];
|
|
815
|
-
const type = args.type || args[3] || "event";
|
|
816
|
-
const payload = parseJsonSafe(args.payload || args[4] || "{}", {});
|
|
817
|
-
const outcome = await requestHub(
|
|
818
|
-
HUB_OPERATIONS.publish,
|
|
819
|
-
buildPublishBody(from, to, type, payload),
|
|
820
|
-
);
|
|
821
|
-
const result = outcome?.result;
|
|
822
|
-
return emitJson(result || unavailableResult());
|
|
823
|
-
}
|
|
824
|
-
|
|
825
|
-
async function cmdTakeoverRole(args) {
|
|
826
|
-
const role = args.role || args[1] || "cto";
|
|
827
|
-
const agentId = args.agent || args["agent-id"] || args[2];
|
|
828
|
-
const outcome = await requestHub(HUB_OPERATIONS.takeoverRole, {
|
|
829
|
-
role,
|
|
830
|
-
agent_id: agentId,
|
|
831
|
-
reason: args.reason || "manual",
|
|
832
|
-
requested_by: args["requested-by"] || "bridge",
|
|
833
|
-
hub_instance_id: args["hub-instance-id"],
|
|
834
|
-
store_fingerprint: args["store-fingerprint"],
|
|
835
|
-
});
|
|
836
|
-
const result = outcome?.result;
|
|
837
|
-
return emitJson(result || unavailableResult());
|
|
838
|
-
}
|
|
839
|
-
|
|
840
|
-
async function cmdSendInput(args) {
|
|
841
|
-
const outcome = await requestHub(HUB_OPERATIONS.sendInput, {
|
|
842
|
-
session_id: args["session-id"],
|
|
843
|
-
text: args.text,
|
|
844
|
-
});
|
|
845
|
-
const result = outcome?.result;
|
|
846
|
-
return emitJson(result || unavailableResult());
|
|
847
|
-
}
|
|
848
|
-
|
|
849
|
-
async function cmdContext(args) {
|
|
850
|
-
const outcome = await requestHub(HUB_OPERATIONS.context, {
|
|
851
|
-
agent_id: args.agent,
|
|
852
|
-
presence_generation:
|
|
853
|
-
args.generation != null ? Number(args.generation) : undefined,
|
|
854
|
-
topics: args.topics ? args.topics.split(",") : undefined,
|
|
855
|
-
max_messages: parseInt(args.max || "10", 10),
|
|
856
|
-
auto_ack: true,
|
|
857
|
-
});
|
|
858
|
-
const result = outcome?.result;
|
|
859
|
-
|
|
860
|
-
if (result?.ok && result.data?.messages?.length) {
|
|
861
|
-
const parts = result.data.messages.map((message, index) => {
|
|
862
|
-
const payload =
|
|
863
|
-
typeof message.payload === "string"
|
|
864
|
-
? message.payload
|
|
865
|
-
: JSON.stringify(message.payload, null, 2);
|
|
866
|
-
return `=== Context ${index + 1}: ${message.from_agent || "unknown"} (${message.topic || "unknown"}) ===\n${payload}`;
|
|
867
|
-
});
|
|
868
|
-
const combined = parts.join("\n\n");
|
|
869
|
-
|
|
870
|
-
if (args.out) {
|
|
871
|
-
writeFileSync(args.out, combined, "utf8");
|
|
872
|
-
return emitJson({
|
|
873
|
-
ok: true,
|
|
874
|
-
count: result.data.messages.length,
|
|
875
|
-
file: args.out,
|
|
876
|
-
});
|
|
877
|
-
} else {
|
|
878
|
-
return emitJson({
|
|
879
|
-
ok: true,
|
|
880
|
-
count: result.data.messages.length,
|
|
881
|
-
context: combined,
|
|
882
|
-
});
|
|
883
|
-
}
|
|
884
|
-
}
|
|
885
|
-
|
|
886
|
-
if (result?.ok) {
|
|
887
|
-
if (args.out) {
|
|
888
|
-
return emitJson({ ok: true, count: 0 });
|
|
889
|
-
}
|
|
890
|
-
return emitJson({ ok: true, count: 0, context: "" });
|
|
891
|
-
}
|
|
892
|
-
|
|
893
|
-
return emitJson(result || unavailableResult());
|
|
894
|
-
}
|
|
895
|
-
|
|
896
|
-
async function cmdDeregister(args) {
|
|
897
|
-
const outcome = await requestHub(HUB_OPERATIONS.deregister, {
|
|
898
|
-
agent_id: args.agent,
|
|
899
|
-
presence_generation:
|
|
900
|
-
args.generation != null ? Number(args.generation) : undefined,
|
|
901
|
-
hub_instance_id: args["hub-instance-id"],
|
|
902
|
-
store_fingerprint: args["store-fingerprint"],
|
|
903
|
-
});
|
|
904
|
-
const result = outcome?.result;
|
|
905
|
-
|
|
906
|
-
return emitJson(result || unavailableResult());
|
|
907
|
-
}
|
|
908
|
-
|
|
909
|
-
async function cmdAssignAsync(args) {
|
|
910
|
-
const outcome = await requestHub(HUB_OPERATIONS.assignAsync, {
|
|
911
|
-
supervisor_agent: args["supervisor-agent"],
|
|
912
|
-
worker_agent: args["worker-agent"],
|
|
913
|
-
task: args.task,
|
|
914
|
-
topic: args.topic || "assign.job",
|
|
915
|
-
payload: args.payload ? parseJsonSafe(args.payload, {}) : {},
|
|
916
|
-
priority: args.priority != null ? Number(args.priority) : undefined,
|
|
917
|
-
ttl_ms: args["ttl-ms"] != null ? Number(args["ttl-ms"]) : undefined,
|
|
918
|
-
timeout_ms:
|
|
919
|
-
args["timeout-ms"] != null ? Number(args["timeout-ms"]) : undefined,
|
|
920
|
-
max_retries:
|
|
921
|
-
args["max-retries"] != null ? Number(args["max-retries"]) : undefined,
|
|
922
|
-
trace_id: args.trace || undefined,
|
|
923
|
-
correlation_id: args.correlation || undefined,
|
|
924
|
-
});
|
|
925
|
-
const result = outcome?.result;
|
|
926
|
-
return emitJson(result || unavailableResult());
|
|
927
|
-
}
|
|
928
|
-
|
|
929
|
-
async function cmdAssignResult(args) {
|
|
930
|
-
const outcome = await requestHub(HUB_OPERATIONS.assignResult, {
|
|
931
|
-
job_id: args["job-id"],
|
|
932
|
-
worker_agent: args["worker-agent"],
|
|
933
|
-
status: args.status,
|
|
934
|
-
attempt: args.attempt != null ? Number(args.attempt) : undefined,
|
|
935
|
-
result: args.result ? parseJsonSafe(args.result, null) : undefined,
|
|
936
|
-
error: args.error ? parseJsonSafe(args.error, null) : undefined,
|
|
937
|
-
payload: args.payload ? parseJsonSafe(args.payload, {}) : {},
|
|
938
|
-
metadata: args.metadata ? parseJsonSafe(args.metadata, {}) : {},
|
|
939
|
-
});
|
|
940
|
-
const result = outcome?.result;
|
|
941
|
-
return emitJson(result || unavailableResult());
|
|
942
|
-
}
|
|
943
|
-
|
|
944
|
-
async function cmdAssignStatus(args) {
|
|
945
|
-
const outcome = await requestHub(HUB_OPERATIONS.assignStatus, {
|
|
946
|
-
job_id: args["job-id"],
|
|
947
|
-
});
|
|
948
|
-
const result = outcome?.result;
|
|
949
|
-
return emitJson(result || unavailableResult());
|
|
950
|
-
}
|
|
951
|
-
|
|
952
|
-
async function cmdAssignRetry(args) {
|
|
953
|
-
const outcome = await requestHub(HUB_OPERATIONS.assignRetry, {
|
|
954
|
-
job_id: args["job-id"],
|
|
955
|
-
reason: args.reason,
|
|
956
|
-
requested_by: args["requested-by"],
|
|
957
|
-
});
|
|
958
|
-
const result = outcome?.result;
|
|
959
|
-
return emitJson(result || unavailableResult());
|
|
91
|
+
function splitList(value) {
|
|
92
|
+
return value
|
|
93
|
+
.split(",")
|
|
94
|
+
.map((item) => item.trim())
|
|
95
|
+
.filter(Boolean);
|
|
960
96
|
}
|
|
961
97
|
|
|
962
98
|
async function cmdTeamInfo(args) {
|
|
963
|
-
const
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
body,
|
|
971
|
-
3000,
|
|
972
|
-
async () => {
|
|
973
|
-
const { teamInfo } = await import("./team/nativeProxy.mjs");
|
|
974
|
-
return await teamInfo(body);
|
|
975
|
-
},
|
|
99
|
+
const { teamInfo } = await import("./team/nativeProxy.mjs");
|
|
100
|
+
return emitJson(
|
|
101
|
+
await teamInfo({
|
|
102
|
+
team_name: args.team,
|
|
103
|
+
include_members: true,
|
|
104
|
+
include_paths: true,
|
|
105
|
+
}),
|
|
976
106
|
);
|
|
977
|
-
const result = outcome?.result;
|
|
978
|
-
return emitJson(result || unavailableResult());
|
|
979
107
|
}
|
|
980
108
|
|
|
981
109
|
async function cmdTeamTaskList(args) {
|
|
982
|
-
const
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
include_internal: !!args["include-internal"],
|
|
992
|
-
limit: parseInt(args.limit || "200", 10),
|
|
993
|
-
};
|
|
994
|
-
const outcome = await requestHub(
|
|
995
|
-
HUB_OPERATIONS.teamTaskList,
|
|
996
|
-
body,
|
|
997
|
-
3000,
|
|
998
|
-
async () => {
|
|
999
|
-
const { teamTaskList } = await import("./team/nativeProxy.mjs");
|
|
1000
|
-
return await teamTaskList(body);
|
|
1001
|
-
},
|
|
110
|
+
const { teamTaskList } = await import("./team/nativeProxy.mjs");
|
|
111
|
+
return emitJson(
|
|
112
|
+
await teamTaskList({
|
|
113
|
+
team_name: args.team,
|
|
114
|
+
owner: args.owner,
|
|
115
|
+
statuses: args.statuses ? splitList(args.statuses) : [],
|
|
116
|
+
include_internal: !!args["include-internal"],
|
|
117
|
+
limit: parseInt(args.limit || "200", 10),
|
|
118
|
+
}),
|
|
1002
119
|
);
|
|
1003
|
-
const result = outcome?.result;
|
|
1004
|
-
return emitJson(result || unavailableResult());
|
|
1005
120
|
}
|
|
1006
121
|
|
|
1007
122
|
async function cmdTeamTaskUpdate(args) {
|
|
1008
|
-
const
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
.filter(Boolean)
|
|
1022
|
-
: undefined,
|
|
1023
|
-
add_blocked_by: args["add-blocked-by"]
|
|
1024
|
-
? args["add-blocked-by"]
|
|
1025
|
-
.split(",")
|
|
1026
|
-
.map((value) => value.trim())
|
|
1027
|
-
.filter(Boolean)
|
|
1028
|
-
: undefined,
|
|
1029
|
-
metadata_patch: args["metadata-patch"]
|
|
1030
|
-
? parseJsonSafe(args["metadata-patch"], null)
|
|
1031
|
-
: undefined,
|
|
1032
|
-
if_match_mtime_ms:
|
|
1033
|
-
args["if-match-mtime-ms"] != null
|
|
1034
|
-
? Number(args["if-match-mtime-ms"])
|
|
123
|
+
const { teamTaskUpdate } = await import("./team/nativeProxy.mjs");
|
|
124
|
+
return emitJson(
|
|
125
|
+
await teamTaskUpdate({
|
|
126
|
+
team_name: args.team,
|
|
127
|
+
task_id: args["task-id"],
|
|
128
|
+
claim: !!args.claim,
|
|
129
|
+
owner: args.owner,
|
|
130
|
+
status: args.status,
|
|
131
|
+
subject: args.subject,
|
|
132
|
+
description: args.description,
|
|
133
|
+
activeForm: args["active-form"],
|
|
134
|
+
add_blocks: args["add-blocks"]
|
|
135
|
+
? splitList(args["add-blocks"])
|
|
1035
136
|
: undefined,
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
137
|
+
add_blocked_by: args["add-blocked-by"]
|
|
138
|
+
? splitList(args["add-blocked-by"])
|
|
139
|
+
: undefined,
|
|
140
|
+
metadata_patch: args["metadata-patch"]
|
|
141
|
+
? parseJsonSafe(args["metadata-patch"], null)
|
|
142
|
+
: undefined,
|
|
143
|
+
if_match_mtime_ms:
|
|
144
|
+
args["if-match-mtime-ms"] != null
|
|
145
|
+
? Number(args["if-match-mtime-ms"])
|
|
146
|
+
: undefined,
|
|
147
|
+
actor: args.actor,
|
|
148
|
+
}),
|
|
1046
149
|
);
|
|
1047
|
-
const result = outcome?.result;
|
|
1048
|
-
return emitJson(result || unavailableResult());
|
|
1049
150
|
}
|
|
1050
151
|
|
|
1051
152
|
async function cmdTeamSendMessage(args) {
|
|
1052
|
-
const
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
body,
|
|
1063
|
-
3000,
|
|
1064
|
-
async () => {
|
|
1065
|
-
const { teamSendMessage } = await import("./team/nativeProxy.mjs");
|
|
1066
|
-
return await teamSendMessage(body);
|
|
1067
|
-
},
|
|
1068
|
-
);
|
|
1069
|
-
const result = outcome?.result;
|
|
1070
|
-
return emitJson(result || unavailableResult());
|
|
1071
|
-
}
|
|
1072
|
-
|
|
1073
|
-
function getHubDbPath() {
|
|
1074
|
-
return getPipelineStateDbPath(PROJECT_ROOT);
|
|
1075
|
-
}
|
|
1076
|
-
|
|
1077
|
-
async function cmdPipelineState(args) {
|
|
1078
|
-
const outcome = await requestHub(
|
|
1079
|
-
HUB_OPERATIONS.pipelineState,
|
|
1080
|
-
{ team_name: args.team },
|
|
1081
|
-
3000,
|
|
1082
|
-
async () => {
|
|
1083
|
-
try {
|
|
1084
|
-
const { default: Database } = await import("better-sqlite3");
|
|
1085
|
-
const { ensurePipelineTable, readPipelineState } = await import(
|
|
1086
|
-
"./pipeline/state.mjs"
|
|
1087
|
-
);
|
|
1088
|
-
const dbPath = getHubDbPath();
|
|
1089
|
-
if (!existsSync(dbPath)) {
|
|
1090
|
-
return { ok: false, error: "hub_db_not_found" };
|
|
1091
|
-
}
|
|
1092
|
-
const db = new Database(dbPath, { readonly: true });
|
|
1093
|
-
ensurePipelineTable(db);
|
|
1094
|
-
const state = readPipelineState(db, args.team);
|
|
1095
|
-
db.close();
|
|
1096
|
-
return state
|
|
1097
|
-
? { ok: true, data: state }
|
|
1098
|
-
: { ok: false, error: "pipeline_not_found" };
|
|
1099
|
-
} catch (e) {
|
|
1100
|
-
return { ok: false, error: e.message };
|
|
1101
|
-
}
|
|
1102
|
-
},
|
|
1103
|
-
);
|
|
1104
|
-
const result = outcome?.result;
|
|
1105
|
-
return emitJson(result || unavailableResult());
|
|
1106
|
-
}
|
|
1107
|
-
|
|
1108
|
-
// Best-effort phase-manager bridge (silent on failure — pipeline 동작 영향 X)
|
|
1109
|
-
async function writePhaseSafely(runId, phase, status) {
|
|
1110
|
-
if (!runId) return;
|
|
1111
|
-
try {
|
|
1112
|
-
const mod = await import("./lib/phase-manager.mjs");
|
|
1113
|
-
if (typeof mod?.writePhase === "function") {
|
|
1114
|
-
await mod.writePhase(runId, phase, status);
|
|
1115
|
-
}
|
|
1116
|
-
if (typeof mod?.syncToGstack === "function") {
|
|
1117
|
-
const slug = process.cwd().split(/[\\/]/).pop();
|
|
1118
|
-
await mod.syncToGstack(runId, slug);
|
|
1119
|
-
}
|
|
1120
|
-
} catch {
|
|
1121
|
-
/* silent — phase tracking is best-effort */
|
|
1122
|
-
}
|
|
1123
|
-
}
|
|
1124
|
-
|
|
1125
|
-
async function writePhaseSafelyFromLegacy(runId, legacyStatus) {
|
|
1126
|
-
if (!runId || !legacyStatus) return;
|
|
1127
|
-
try {
|
|
1128
|
-
const mod = await import("./lib/phase-manager.mjs");
|
|
1129
|
-
if (typeof mod?.coerceLegacyPhase !== "function") return;
|
|
1130
|
-
const coerced = mod.coerceLegacyPhase(legacyStatus);
|
|
1131
|
-
if (!coerced) return;
|
|
1132
|
-
if (coerced === "complete") {
|
|
1133
|
-
const current =
|
|
1134
|
-
typeof mod.readPhase === "function" ? await mod.readPhase(runId) : null;
|
|
1135
|
-
const lastPhase = current?.phase || current?.lastPhase;
|
|
1136
|
-
if (lastPhase) await mod.writePhase(runId, lastPhase, "complete");
|
|
1137
|
-
return;
|
|
1138
|
-
}
|
|
1139
|
-
await mod.writePhase(runId, coerced, "active");
|
|
1140
|
-
if (typeof mod?.syncToGstack === "function") {
|
|
1141
|
-
const slug = process.cwd().split(/[\\/]/).pop();
|
|
1142
|
-
await mod.syncToGstack(runId, slug);
|
|
1143
|
-
}
|
|
1144
|
-
} catch {
|
|
1145
|
-
/* silent */
|
|
1146
|
-
}
|
|
1147
|
-
}
|
|
1148
|
-
|
|
1149
|
-
async function cmdPipelineAdvance(args) {
|
|
1150
|
-
const body = {
|
|
1151
|
-
team_name: args.team,
|
|
1152
|
-
phase: args.status, // --status를 phase로 재활용
|
|
1153
|
-
};
|
|
1154
|
-
const outcome = await requestHub(
|
|
1155
|
-
HUB_OPERATIONS.pipelineAdvance,
|
|
1156
|
-
body,
|
|
1157
|
-
3000,
|
|
1158
|
-
async () => {
|
|
1159
|
-
try {
|
|
1160
|
-
const { default: Database } = await import("better-sqlite3");
|
|
1161
|
-
const { createPipeline } = await import("./pipeline/index.mjs");
|
|
1162
|
-
const dbPath = getHubDbPath();
|
|
1163
|
-
if (!existsSync(dbPath)) {
|
|
1164
|
-
return { ok: false, error: "hub_db_not_found" };
|
|
1165
|
-
}
|
|
1166
|
-
const db = new Database(dbPath);
|
|
1167
|
-
const pipeline = createPipeline(db, args.team);
|
|
1168
|
-
const advanceResult = pipeline.advance(args.status);
|
|
1169
|
-
db.close();
|
|
1170
|
-
return advanceResult;
|
|
1171
|
-
} catch (e) {
|
|
1172
|
-
return { ok: false, error: e.message };
|
|
1173
|
-
}
|
|
1174
|
-
},
|
|
1175
|
-
);
|
|
1176
|
-
const result = outcome?.result;
|
|
1177
|
-
if (args.team && args.status && result?.ok !== false) {
|
|
1178
|
-
void writePhaseSafelyFromLegacy(args.team, args.status);
|
|
1179
|
-
}
|
|
1180
|
-
return emitJson(result || unavailableResult());
|
|
1181
|
-
}
|
|
1182
|
-
|
|
1183
|
-
async function cmdPipelineInit(args) {
|
|
1184
|
-
const outcome = await requestHub(HUB_OPERATIONS.pipelineInit, {
|
|
1185
|
-
team_name: args.team,
|
|
1186
|
-
fix_max: args["fix-max"] != null ? Number(args["fix-max"]) : undefined,
|
|
1187
|
-
ralph_max:
|
|
1188
|
-
args["ralph-max"] != null ? Number(args["ralph-max"]) : undefined,
|
|
1189
|
-
});
|
|
1190
|
-
const result = outcome?.result;
|
|
1191
|
-
if (args.team && result?.ok !== false) {
|
|
1192
|
-
void writePhaseSafely(args.team, "Strategy", "active");
|
|
1193
|
-
}
|
|
1194
|
-
return emitJson(result || unavailableResult());
|
|
1195
|
-
}
|
|
1196
|
-
|
|
1197
|
-
async function cmdPipelineList() {
|
|
1198
|
-
const outcome = await requestHub(HUB_OPERATIONS.pipelineList, {});
|
|
1199
|
-
const result = outcome?.result;
|
|
1200
|
-
return emitJson(result || unavailableResult());
|
|
1201
|
-
}
|
|
1202
|
-
|
|
1203
|
-
async function cmdPing() {
|
|
1204
|
-
const outcome = await requestHub(
|
|
1205
|
-
HUB_OPERATIONS.hubStatus,
|
|
1206
|
-
{ scope: "hub" },
|
|
1207
|
-
2000,
|
|
1208
|
-
);
|
|
1209
|
-
|
|
1210
|
-
if (outcome?.transport === "pipe" && outcome.result?.ok) {
|
|
1211
|
-
return emitJson({
|
|
1212
|
-
ok: true,
|
|
1213
|
-
hub: outcome.result.data?.hub?.state || "healthy",
|
|
1214
|
-
pipe_path: getHubPipePath(),
|
|
1215
|
-
transport: "pipe",
|
|
1216
|
-
});
|
|
1217
|
-
}
|
|
1218
|
-
|
|
1219
|
-
if (outcome?.transport === "http" && outcome.result) {
|
|
1220
|
-
const data = outcome.result;
|
|
1221
|
-
return emitJson({
|
|
1222
|
-
ok: true,
|
|
1223
|
-
hub: data.hub?.state,
|
|
1224
|
-
sessions: data.sessions,
|
|
1225
|
-
pipe_path: data.pipe?.path || data.pipe_path || null,
|
|
1226
|
-
transport: "http",
|
|
1227
|
-
});
|
|
1228
|
-
}
|
|
1229
|
-
|
|
1230
|
-
return emitJson(unavailableResult());
|
|
1231
|
-
}
|
|
1232
|
-
|
|
1233
|
-
async function cmdDelegatorDelegate(args) {
|
|
1234
|
-
const body = {
|
|
1235
|
-
prompt: args.text || args.prompt,
|
|
1236
|
-
provider: args.provider || "auto",
|
|
1237
|
-
mode: args.mode || "sync",
|
|
1238
|
-
agent_type: args.agent || "executor",
|
|
1239
|
-
mcp_profile: args["mcp-profile"] || "auto",
|
|
1240
|
-
session_key: args["session-key"] || undefined,
|
|
1241
|
-
timeout_ms:
|
|
1242
|
-
args["timeout-ms"] != null ? Number(args["timeout-ms"]) : undefined,
|
|
1243
|
-
};
|
|
1244
|
-
const timeoutMs = body.mode === "async" ? 10000 : 120000;
|
|
1245
|
-
const outcome = await requestHub(
|
|
1246
|
-
HUB_OPERATIONS.delegatorDelegate,
|
|
1247
|
-
body,
|
|
1248
|
-
timeoutMs,
|
|
1249
|
-
);
|
|
1250
|
-
return emitJson(outcome?.result || unavailableResult());
|
|
1251
|
-
}
|
|
1252
|
-
|
|
1253
|
-
async function cmdDelegatorReply(args) {
|
|
1254
|
-
const body = {
|
|
1255
|
-
job_id: args["job-id"],
|
|
1256
|
-
reply: args.text || args.reply,
|
|
1257
|
-
done: !!args.done,
|
|
1258
|
-
};
|
|
1259
|
-
const outcome = await requestHub(HUB_OPERATIONS.delegatorReply, body, 120000);
|
|
1260
|
-
return emitJson(outcome?.result || unavailableResult());
|
|
1261
|
-
}
|
|
1262
|
-
|
|
1263
|
-
async function cmdDelegatorStatus(args) {
|
|
1264
|
-
const body = {
|
|
1265
|
-
job_id: args["job-id"],
|
|
1266
|
-
};
|
|
1267
|
-
const outcome = await requestHub(HUB_OPERATIONS.delegatorStatus, body, 5000);
|
|
1268
|
-
return emitJson(outcome?.result || unavailableResult());
|
|
1269
|
-
}
|
|
1270
|
-
|
|
1271
|
-
async function cmdHitlRequest(args) {
|
|
1272
|
-
const body = {
|
|
1273
|
-
kind: args[1],
|
|
1274
|
-
prompt: args[2],
|
|
1275
|
-
requester_agent: args[3] || "cli",
|
|
1276
|
-
};
|
|
1277
|
-
const outcome = await requestHub(
|
|
1278
|
-
HUB_OPERATIONS["hitl-request"],
|
|
1279
|
-
body,
|
|
1280
|
-
120000,
|
|
153
|
+
const { teamSendMessage } = await import("./team/nativeProxy.mjs");
|
|
154
|
+
return emitJson(
|
|
155
|
+
await teamSendMessage({
|
|
156
|
+
team_name: args.team,
|
|
157
|
+
from: args.from,
|
|
158
|
+
to: args.to || "team-lead",
|
|
159
|
+
text: args.text,
|
|
160
|
+
summary: args.summary,
|
|
161
|
+
color: args.color || "blue",
|
|
162
|
+
}),
|
|
1281
163
|
);
|
|
1282
|
-
return emitJson(outcome?.result || unavailableResult());
|
|
1283
|
-
}
|
|
1284
|
-
|
|
1285
|
-
async function cmdHitlSubmit(args) {
|
|
1286
|
-
const body = {
|
|
1287
|
-
request_id: args[1],
|
|
1288
|
-
action: args[2] || "accept",
|
|
1289
|
-
content: args[3],
|
|
1290
|
-
};
|
|
1291
|
-
const outcome = await requestHub(HUB_OPERATIONS["hitl-submit"], body, 120000);
|
|
1292
|
-
return emitJson(outcome?.result || unavailableResult());
|
|
1293
|
-
}
|
|
1294
|
-
|
|
1295
|
-
async function cmdHitlPending() {
|
|
1296
|
-
const outcome = await requestHub(HUB_OPERATIONS["hitl-pending"], {}, 5000);
|
|
1297
|
-
return emitJson(outcome?.result || unavailableResult());
|
|
1298
164
|
}
|
|
1299
165
|
|
|
1300
166
|
async function loadDaemonControl() {
|
|
@@ -1915,8 +781,7 @@ async function cmdRetryStatus(args) {
|
|
|
1915
781
|
return true;
|
|
1916
782
|
}
|
|
1917
783
|
|
|
1918
|
-
// intervene-run은
|
|
1919
|
-
// process/daemon/pane 사다리를 실행할 수 있도록 순수 로컬 모듈만 호출한다.
|
|
784
|
+
// intervene-run은 순수 로컬 모듈만 호출한다.
|
|
1920
785
|
async function cmdInterveneRun(args) {
|
|
1921
786
|
try {
|
|
1922
787
|
const payload = readBridgePayload(args);
|
|
@@ -1982,34 +847,6 @@ export async function main(argv = process.argv.slice(2)) {
|
|
|
1982
847
|
const args = parseArgs(argv.slice(1));
|
|
1983
848
|
|
|
1984
849
|
switch (cmd) {
|
|
1985
|
-
case "register":
|
|
1986
|
-
return await cmdRegister(args);
|
|
1987
|
-
case "heartbeat":
|
|
1988
|
-
return await cmdHeartbeat(args);
|
|
1989
|
-
case "result":
|
|
1990
|
-
return await cmdResult(args);
|
|
1991
|
-
case "control":
|
|
1992
|
-
return await cmdControl(args);
|
|
1993
|
-
case "handoff":
|
|
1994
|
-
return await cmdHandoff(args);
|
|
1995
|
-
case "publish":
|
|
1996
|
-
return await cmdPublish(args);
|
|
1997
|
-
case "takeover-role":
|
|
1998
|
-
return await cmdTakeoverRole(args);
|
|
1999
|
-
case "send-input":
|
|
2000
|
-
return await cmdSendInput(args);
|
|
2001
|
-
case "context":
|
|
2002
|
-
return await cmdContext(args);
|
|
2003
|
-
case "deregister":
|
|
2004
|
-
return await cmdDeregister(args);
|
|
2005
|
-
case "assign-async":
|
|
2006
|
-
return await cmdAssignAsync(args);
|
|
2007
|
-
case "assign-result":
|
|
2008
|
-
return await cmdAssignResult(args);
|
|
2009
|
-
case "assign-status":
|
|
2010
|
-
return await cmdAssignStatus(args);
|
|
2011
|
-
case "assign-retry":
|
|
2012
|
-
return await cmdAssignRetry(args);
|
|
2013
850
|
case "team-info":
|
|
2014
851
|
return await cmdTeamInfo(args);
|
|
2015
852
|
case "team-task-list":
|
|
@@ -2018,28 +855,6 @@ export async function main(argv = process.argv.slice(2)) {
|
|
|
2018
855
|
return await cmdTeamTaskUpdate(args);
|
|
2019
856
|
case "team-send-message":
|
|
2020
857
|
return await cmdTeamSendMessage(args);
|
|
2021
|
-
case "pipeline-state":
|
|
2022
|
-
return await cmdPipelineState(args);
|
|
2023
|
-
case "pipeline-advance":
|
|
2024
|
-
return await cmdPipelineAdvance(args);
|
|
2025
|
-
case "pipeline-init":
|
|
2026
|
-
return await cmdPipelineInit(args);
|
|
2027
|
-
case "pipeline-list":
|
|
2028
|
-
return await cmdPipelineList(args);
|
|
2029
|
-
case "ping":
|
|
2030
|
-
return await cmdPing(args);
|
|
2031
|
-
case "delegator-delegate":
|
|
2032
|
-
return await cmdDelegatorDelegate(args);
|
|
2033
|
-
case "delegator-reply":
|
|
2034
|
-
return await cmdDelegatorReply(args);
|
|
2035
|
-
case "delegator-status":
|
|
2036
|
-
return await cmdDelegatorStatus(args);
|
|
2037
|
-
case "hitl-request":
|
|
2038
|
-
return await cmdHitlRequest(args);
|
|
2039
|
-
case "hitl-submit":
|
|
2040
|
-
return await cmdHitlSubmit(args);
|
|
2041
|
-
case "hitl-pending":
|
|
2042
|
-
return await cmdHitlPending(args);
|
|
2043
858
|
case "daemon-probe":
|
|
2044
859
|
return await cmdDaemonProbe(args);
|
|
2045
860
|
case "daemon-attach":
|
|
@@ -2056,7 +871,7 @@ export async function main(argv = process.argv.slice(2)) {
|
|
|
2056
871
|
return await cmdInterveneRun(args);
|
|
2057
872
|
default:
|
|
2058
873
|
console.error(
|
|
2059
|
-
"사용법: bridge.mjs <
|
|
874
|
+
"사용법: bridge.mjs <team-info|team-task-list|team-task-update|team-send-message|daemon-probe|daemon-attach|daemon-wait|daemon-interrupt|retry-run|retry-status|intervene-run> [--옵션]",
|
|
2060
875
|
);
|
|
2061
876
|
process.exit(1);
|
|
2062
877
|
}
|