@triflux/remote 10.25.1 → 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/server.mjs +21 -8
- package/hub/team/agent-map.json +3 -3
- package/hub/team/backend.mjs +3 -9
- package/hub/team/build-worker-prompt.mjs +33 -2
- package/hub/team/claude-daemon-control.mjs +911 -0
- package/hub/team/claude-native-bridge.mjs +238 -11
- package/hub/team/claude-session-projection.mjs +10 -1
- package/hub/team/cli/commands/start/index.mjs +3 -6
- package/hub/team/cli/commands/start/parse-args.mjs +10 -3
- package/hub/team/cli/commands/start/start-headless.mjs +50 -20
- package/hub/team/cli/help.mjs +1 -1
- package/hub/team/cli/services/runtime-mode.mjs +6 -3
- package/hub/team/execution-mode.mjs +27 -12
- package/hub/team/headless.mjs +191 -43
- 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 +28 -6
- package/hub/team/native.mjs +46 -7
- package/hub/team/pane.mjs +0 -5
- package/hub/team/psmux.mjs +3 -3
- package/hub/team/retry-state-machine.mjs +83 -14
- package/hub/team/session.mjs +5 -36
- package/hub/team/swarm-hypervisor.mjs +28 -6
- package/hub/team/swarm-preflight.mjs +3 -1
- package/hub/team/terminal-opener.mjs +1 -1
- package/hub/team/tui-core.mjs +4 -0
- package/hub/team/tui-lite.mjs +3 -2
- package/hub/team/tui-viewer.mjs +4 -4
- package/hub/team/tui.mjs +4 -2
- package/hub/team/worker-sandbox.mjs +4 -0
- package/hub/tools.mjs +4 -1
- package/hub/workers/antigravity-route-worker.mjs +169 -0
- package/hub/workers/delegator-mcp.mjs +58 -314
- package/hub/workers/factory.mjs +7 -4
- package/hub/workers/gemini-worker.mjs +55 -306
- package/hub/workers/interface.mjs +2 -1
- package/hub/workers/worker-utils.mjs +1 -1
- package/package.json +1 -1
- package/scripts/lib/cli-codex.mjs +3 -3
- package/scripts/lib/cli-gemini.mjs +20 -50
- package/scripts/lib/keyword-rules.mjs +1 -1
- package/scripts/lib/mcp-gateway-health-check.mjs +159 -0
- package/scripts/lib/mcp-gateway-wrapper-check.mjs +35 -0
- package/scripts/lib/psmux-info.mjs +50 -5
|
@@ -1,15 +1,12 @@
|
|
|
1
|
-
// hub/workers/gemini-worker.mjs
|
|
2
|
-
//
|
|
1
|
+
// hub/workers/gemini-worker.mjs
|
|
2
|
+
// Deprecated compatibility surface. Direct Gemini CLI execution is removed;
|
|
3
|
+
// old imports now route through Antigravity.
|
|
3
4
|
|
|
4
|
-
import { spawn } from "node:child_process";
|
|
5
5
|
import { existsSync } from "node:fs";
|
|
6
6
|
import { extname } from "node:path";
|
|
7
|
-
import readline from "node:readline";
|
|
8
7
|
|
|
9
|
-
import {
|
|
10
|
-
|
|
11
|
-
const DEFAULT_TIMEOUT_MS = 15 * 60 * 1000;
|
|
12
|
-
const DEFAULT_KILL_GRACE_MS = 1000;
|
|
8
|
+
import { AntigravityRouteWorker } from "./antigravity-route-worker.mjs";
|
|
9
|
+
import { withRetry } from "./worker-utils.mjs";
|
|
13
10
|
|
|
14
11
|
function toStringList(value) {
|
|
15
12
|
if (!Array.isArray(value)) return [];
|
|
@@ -18,7 +15,6 @@ function toStringList(value) {
|
|
|
18
15
|
|
|
19
16
|
/**
|
|
20
17
|
* Windows에서 cmd.exe에 전달할 인자를 안전하게 quoting한다.
|
|
21
|
-
* 빈 문자열은 ""로, 특수문자 포함 시 큰따옴표로 감싼다.
|
|
22
18
|
*/
|
|
23
19
|
function quoteWindowsCmdArg(value) {
|
|
24
20
|
const raw = String(value ?? "").replace(/[\r\n]/g, " ");
|
|
@@ -33,10 +29,6 @@ function quoteWindowsCmdArg(value) {
|
|
|
33
29
|
|
|
34
30
|
/**
|
|
35
31
|
* Windows npm shim(.cmd) spawn 문제를 해결한다.
|
|
36
|
-
* - command -v가 확장자 없는 경로를 반환하면 .exe → .cmd → .bat 순으로 탐색
|
|
37
|
-
* - .cmd/.bat는 CVE-2024-27980 이후 shell:false에서 실행 불가하므로 cmd.exe /d /s /c 경유
|
|
38
|
-
* - .exe는 직접 실행
|
|
39
|
-
* - non-Windows는 그대로 통과
|
|
40
32
|
*/
|
|
41
33
|
function buildSpawnSpec(command, args) {
|
|
42
34
|
if (process.platform !== "win32") {
|
|
@@ -65,48 +57,6 @@ function buildSpawnSpec(command, args) {
|
|
|
65
57
|
return { command: resolved, args, shell: false };
|
|
66
58
|
}
|
|
67
59
|
|
|
68
|
-
function safeJsonParse(line) {
|
|
69
|
-
try {
|
|
70
|
-
return JSON.parse(line);
|
|
71
|
-
} catch {
|
|
72
|
-
return null;
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
function findLastEvent(events, predicate) {
|
|
77
|
-
for (let index = events.length - 1; index >= 0; index -= 1) {
|
|
78
|
-
if (predicate(events[index])) return events[index];
|
|
79
|
-
}
|
|
80
|
-
return null;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
function buildGeminiArgs(options) {
|
|
84
|
-
const args = [];
|
|
85
|
-
|
|
86
|
-
if (options.model) {
|
|
87
|
-
args.push("--model", options.model);
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
if (options.approvalMode) {
|
|
91
|
-
args.push("--approval-mode", options.approvalMode);
|
|
92
|
-
} else if (options.yolo !== false) {
|
|
93
|
-
args.push("--yolo");
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
const allowedMcpServers = toStringList(options.allowedMcpServerNames);
|
|
97
|
-
if (allowedMcpServers.length) {
|
|
98
|
-
args.push("--allowed-mcp-server-names", ...allowedMcpServers);
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
const extraArgs = toStringList(options.extraArgs);
|
|
102
|
-
if (extraArgs.length) args.push(...extraArgs);
|
|
103
|
-
|
|
104
|
-
args.push("--prompt", options.promptArgument ?? "");
|
|
105
|
-
args.push("--output-format", "stream-json");
|
|
106
|
-
|
|
107
|
-
return args;
|
|
108
|
-
}
|
|
109
|
-
|
|
110
60
|
function createWorkerError(message, details = {}) {
|
|
111
61
|
const error = new Error(message);
|
|
112
62
|
Object.assign(error, details);
|
|
@@ -120,7 +70,7 @@ function normalizeRetryOptions(retryOptions) {
|
|
|
120
70
|
return Object.freeze({ ...retryOptions });
|
|
121
71
|
}
|
|
122
72
|
|
|
123
|
-
function
|
|
73
|
+
function isAntigravityRetryable(error) {
|
|
124
74
|
return (
|
|
125
75
|
error?.code === "WORKER_EXIT" &&
|
|
126
76
|
error?.result?.exitCode !== 0 &&
|
|
@@ -128,7 +78,7 @@ function isGeminiRetryable(error) {
|
|
|
128
78
|
);
|
|
129
79
|
}
|
|
130
80
|
|
|
131
|
-
function
|
|
81
|
+
function detectAntigravityCategory(error) {
|
|
132
82
|
const combined =
|
|
133
83
|
`${error?.message || ""}\n${error?.stderr || ""}`.toLowerCase();
|
|
134
84
|
|
|
@@ -141,32 +91,27 @@ function detectGeminiCategory(error) {
|
|
|
141
91
|
}
|
|
142
92
|
if (
|
|
143
93
|
error?.result?.exitCode === 2 ||
|
|
144
|
-
/
|
|
94
|
+
/unknown option|invalid option|config|route script/.test(combined)
|
|
145
95
|
) {
|
|
146
96
|
return "config";
|
|
147
97
|
}
|
|
148
|
-
if (error?.code === "WORKER_EVENT_ERROR") {
|
|
149
|
-
return "input";
|
|
150
|
-
}
|
|
151
98
|
|
|
152
99
|
return "transient";
|
|
153
100
|
}
|
|
154
101
|
|
|
155
|
-
function
|
|
156
|
-
const category =
|
|
157
|
-
const retryable =
|
|
158
|
-
let recovery = "Retry the
|
|
102
|
+
function buildAntigravityErrorInfo(error, attempts) {
|
|
103
|
+
const category = detectAntigravityCategory(error);
|
|
104
|
+
const retryable = isAntigravityRetryable(error);
|
|
105
|
+
let recovery = "Retry the Antigravity route worker after correcting the issue.";
|
|
159
106
|
|
|
160
107
|
if (category === "auth") {
|
|
161
|
-
recovery = "Refresh the
|
|
108
|
+
recovery = "Refresh the Antigravity authentication state and retry.";
|
|
162
109
|
} else if (category === "config") {
|
|
163
|
-
recovery = "Check the
|
|
164
|
-
} else if (category === "input") {
|
|
165
|
-
recovery = "Check the Gemini request payload and streamed event format.";
|
|
110
|
+
recovery = "Check the Antigravity route worker configuration.";
|
|
166
111
|
}
|
|
167
112
|
|
|
168
113
|
return Object.freeze({
|
|
169
|
-
code: error?.code || "
|
|
114
|
+
code: error?.code || "ANTIGRAVITY_EXECUTION_ERROR",
|
|
170
115
|
retryable,
|
|
171
116
|
attempts,
|
|
172
117
|
category,
|
|
@@ -174,260 +119,64 @@ function buildGeminiErrorInfo(error, attempts) {
|
|
|
174
119
|
});
|
|
175
120
|
}
|
|
176
121
|
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
*/
|
|
180
|
-
export class GeminiWorker {
|
|
181
|
-
type = "gemini";
|
|
122
|
+
export class GeminiWorker extends AntigravityRouteWorker {
|
|
123
|
+
type = "antigravity";
|
|
182
124
|
|
|
183
125
|
constructor(options = {}) {
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
this.
|
|
193
|
-
this.timeoutMs =
|
|
194
|
-
Number(options.timeoutMs) > 0
|
|
195
|
-
? Number(options.timeoutMs)
|
|
196
|
-
: DEFAULT_TIMEOUT_MS;
|
|
197
|
-
this.killGraceMs =
|
|
198
|
-
Number(options.killGraceMs) > 0
|
|
199
|
-
? Number(options.killGraceMs)
|
|
200
|
-
: DEFAULT_KILL_GRACE_MS;
|
|
126
|
+
const { command, commandArgs, args, model, approvalMode, yolo, ...rest } =
|
|
127
|
+
options;
|
|
128
|
+
void commandArgs;
|
|
129
|
+
void args;
|
|
130
|
+
void model;
|
|
131
|
+
void approvalMode;
|
|
132
|
+
void yolo;
|
|
133
|
+
super(rest);
|
|
134
|
+
this.command = command || "agy";
|
|
201
135
|
this.retryOptions = normalizeRetryOptions(options.retryOptions);
|
|
202
|
-
this.onEvent =
|
|
203
|
-
typeof options.onEvent === "function" ? options.onEvent : null;
|
|
204
|
-
|
|
205
|
-
this.state = "idle";
|
|
206
|
-
this.child = null;
|
|
207
136
|
this.lastRun = null;
|
|
208
137
|
}
|
|
209
138
|
|
|
210
139
|
getStatus() {
|
|
211
140
|
return {
|
|
212
|
-
type: "
|
|
213
|
-
state: this.
|
|
214
|
-
pid:
|
|
141
|
+
type: "antigravity",
|
|
142
|
+
state: this.children.size > 0 ? "running" : "idle",
|
|
143
|
+
pid: null,
|
|
215
144
|
last_run_at_ms: this.lastRun?.finishedAtMs || null,
|
|
216
145
|
last_exit_code: this.lastRun?.exitCode ?? null,
|
|
217
146
|
};
|
|
218
147
|
}
|
|
219
148
|
|
|
220
|
-
async start() {
|
|
221
|
-
if (this.state === "stopped") {
|
|
222
|
-
this.state = "idle";
|
|
223
|
-
}
|
|
224
|
-
return this.getStatus();
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
async stop() {
|
|
228
|
-
if (!this.child) {
|
|
229
|
-
this.state = "stopped";
|
|
230
|
-
return this.getStatus();
|
|
231
|
-
}
|
|
232
|
-
const child = this.child;
|
|
233
|
-
terminateChild(child, this.killGraceMs);
|
|
234
|
-
await new Promise((resolve) => {
|
|
235
|
-
child.once("close", resolve);
|
|
236
|
-
setTimeout(resolve, this.killGraceMs + 50).unref?.();
|
|
237
|
-
});
|
|
238
|
-
this.child = null;
|
|
239
|
-
this.state = "stopped";
|
|
240
|
-
return this.getStatus();
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
async restart() {
|
|
244
|
-
await this.stop();
|
|
245
|
-
this.state = "idle";
|
|
246
|
-
return this.getStatus();
|
|
247
|
-
}
|
|
248
|
-
|
|
249
149
|
async run(prompt, options = {}) {
|
|
250
|
-
if (this.child) {
|
|
251
|
-
throw createWorkerError("GeminiWorker is already running", {
|
|
252
|
-
code: "WORKER_BUSY",
|
|
253
|
-
});
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
await this.start();
|
|
257
|
-
|
|
258
|
-
const timeoutMs =
|
|
259
|
-
Number(options.timeoutMs) > 0
|
|
260
|
-
? Number(options.timeoutMs)
|
|
261
|
-
: this.timeoutMs;
|
|
262
150
|
const startedAtMs = Date.now();
|
|
263
|
-
const
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
model: options.model || this.model,
|
|
267
|
-
approvalMode: options.approvalMode || this.approvalMode,
|
|
268
|
-
yolo: options.yolo ?? this.yolo,
|
|
269
|
-
allowedMcpServerNames:
|
|
270
|
-
options.allowedMcpServerNames || this.allowedMcpServerNames,
|
|
271
|
-
extraArgs: options.extraArgs || this.extraArgs,
|
|
272
|
-
promptArgument: options.promptArgument ?? "",
|
|
273
|
-
}),
|
|
274
|
-
];
|
|
275
|
-
|
|
276
|
-
const {
|
|
277
|
-
command: spawnCmd,
|
|
278
|
-
args: spawnArgs,
|
|
279
|
-
shell,
|
|
280
|
-
} = buildSpawnSpec(this.command, args);
|
|
281
|
-
const child = spawn(spawnCmd, spawnArgs, {
|
|
282
|
-
cwd: options.cwd || this.cwd,
|
|
283
|
-
env: { ...this.env, ...(options.env || {}) },
|
|
284
|
-
stdio: ["pipe", "pipe", "pipe"],
|
|
285
|
-
windowsHide: true,
|
|
286
|
-
shell,
|
|
287
|
-
});
|
|
288
|
-
|
|
289
|
-
this.child = child;
|
|
290
|
-
this.state = "running";
|
|
291
|
-
|
|
292
|
-
const events = [];
|
|
293
|
-
const stdoutLines = [];
|
|
294
|
-
const stderrLines = [];
|
|
295
|
-
let lastErrorEvent = null;
|
|
296
|
-
let timedOut = false;
|
|
297
|
-
let exitCode = null;
|
|
298
|
-
let exitSignal = null;
|
|
299
|
-
|
|
300
|
-
const stdoutReader = readline.createInterface({
|
|
301
|
-
input: child.stdout,
|
|
302
|
-
crlfDelay: Infinity,
|
|
303
|
-
});
|
|
304
|
-
const stderrReader = readline.createInterface({
|
|
305
|
-
input: child.stderr,
|
|
306
|
-
crlfDelay: Infinity,
|
|
307
|
-
});
|
|
308
|
-
|
|
309
|
-
stdoutReader.on("line", (line) => {
|
|
310
|
-
if (!line) return;
|
|
311
|
-
const event = safeJsonParse(line);
|
|
312
|
-
if (!event) {
|
|
313
|
-
stdoutLines.push(line);
|
|
314
|
-
return;
|
|
315
|
-
}
|
|
316
|
-
|
|
317
|
-
events.push(event);
|
|
318
|
-
if (event.type === "error") lastErrorEvent = event;
|
|
319
|
-
if (this.onEvent) {
|
|
320
|
-
try {
|
|
321
|
-
this.onEvent(event);
|
|
322
|
-
} catch {}
|
|
323
|
-
}
|
|
324
|
-
});
|
|
325
|
-
|
|
326
|
-
stderrReader.on("line", (line) => {
|
|
327
|
-
if (!line) return;
|
|
328
|
-
stderrLines.push(line);
|
|
329
|
-
});
|
|
330
|
-
|
|
331
|
-
const closePromise = new Promise((resolve, reject) => {
|
|
332
|
-
child.once("error", reject);
|
|
333
|
-
child.once("close", (code, signal) => {
|
|
334
|
-
exitCode = code;
|
|
335
|
-
exitSignal = signal;
|
|
336
|
-
resolve();
|
|
337
|
-
});
|
|
338
|
-
});
|
|
339
|
-
|
|
340
|
-
const timeout = setTimeout(() => {
|
|
341
|
-
timedOut = true;
|
|
342
|
-
terminateChild(child, this.killGraceMs);
|
|
343
|
-
}, timeoutMs);
|
|
344
|
-
timeout.unref?.();
|
|
345
|
-
|
|
346
|
-
child.stdin.on("error", () => {});
|
|
347
|
-
child.stdin.end(String(prompt ?? ""));
|
|
348
|
-
|
|
349
|
-
try {
|
|
350
|
-
await closePromise;
|
|
351
|
-
} finally {
|
|
352
|
-
clearTimeout(timeout);
|
|
353
|
-
stdoutReader.close();
|
|
354
|
-
stderrReader.close();
|
|
355
|
-
if (this.child === child) {
|
|
356
|
-
this.child = null;
|
|
357
|
-
}
|
|
358
|
-
this.state = "idle";
|
|
359
|
-
}
|
|
360
|
-
|
|
361
|
-
const resultEvent = findLastEvent(
|
|
362
|
-
events,
|
|
363
|
-
(event) => event?.type === "result",
|
|
364
|
-
);
|
|
365
|
-
const response = [
|
|
366
|
-
extractText(resultEvent),
|
|
367
|
-
...events
|
|
368
|
-
.filter(
|
|
369
|
-
(event) => event?.type === "message" || event?.type === "assistant",
|
|
370
|
-
)
|
|
371
|
-
.map((event) => extractText(event))
|
|
372
|
-
.filter(Boolean),
|
|
373
|
-
...stdoutLines,
|
|
374
|
-
]
|
|
375
|
-
.filter(Boolean)
|
|
376
|
-
.join("\n")
|
|
377
|
-
.trim();
|
|
378
|
-
|
|
379
|
-
const result = {
|
|
380
|
-
type: "gemini",
|
|
151
|
+
const result = await super.run(prompt, options);
|
|
152
|
+
const normalized = {
|
|
153
|
+
type: "antigravity",
|
|
381
154
|
command: this.command,
|
|
382
|
-
args,
|
|
383
|
-
response,
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
exitCode,
|
|
390
|
-
exitSignal,
|
|
391
|
-
timedOut,
|
|
155
|
+
args: toStringList(options.extraArgs),
|
|
156
|
+
response: result.response || result.output || "",
|
|
157
|
+
output: result.output || result.response || "",
|
|
158
|
+
stderr: result.stderr || "",
|
|
159
|
+
exitCode: result.exitCode ?? 1,
|
|
160
|
+
exitSignal: null,
|
|
161
|
+
timedOut: result.exitCode === 124,
|
|
392
162
|
startedAtMs,
|
|
393
163
|
finishedAtMs: Date.now(),
|
|
164
|
+
raw: result.raw || result,
|
|
394
165
|
};
|
|
166
|
+
this.lastRun = normalized;
|
|
395
167
|
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
if (exitCode !== 0) {
|
|
407
|
-
// Build a descriptive message when stderr is empty to aid debugging
|
|
408
|
-
const errMsg = result.stderr
|
|
409
|
-
? `Gemini worker exited with code ${exitCode}`
|
|
410
|
-
: `Gemini worker exited with code ${exitCode} (stderr empty, signal=${exitSignal ?? "none"}, events=${events.length}, stdout=${result.stdout.length}B)`;
|
|
411
|
-
throw createWorkerError(errMsg, {
|
|
412
|
-
code: "WORKER_EXIT",
|
|
413
|
-
result,
|
|
414
|
-
stderr: result.stderr,
|
|
415
|
-
});
|
|
416
|
-
}
|
|
417
|
-
|
|
418
|
-
if (lastErrorEvent) {
|
|
419
|
-
throw createWorkerError("Gemini worker emitted an error event", {
|
|
420
|
-
code: "WORKER_EVENT_ERROR",
|
|
421
|
-
result,
|
|
422
|
-
stderr: result.stderr,
|
|
423
|
-
});
|
|
168
|
+
if (normalized.exitCode !== 0) {
|
|
169
|
+
throw createWorkerError(
|
|
170
|
+
`Antigravity route worker exited with code ${normalized.exitCode}`,
|
|
171
|
+
{
|
|
172
|
+
code: "WORKER_EXIT",
|
|
173
|
+
result: normalized,
|
|
174
|
+
stderr: normalized.stderr,
|
|
175
|
+
},
|
|
176
|
+
);
|
|
424
177
|
}
|
|
425
178
|
|
|
426
|
-
return
|
|
427
|
-
}
|
|
428
|
-
|
|
429
|
-
isReady() {
|
|
430
|
-
return this.state !== "stopped";
|
|
179
|
+
return normalized;
|
|
431
180
|
}
|
|
432
181
|
|
|
433
182
|
async execute(prompt, options = {}) {
|
|
@@ -441,7 +190,7 @@ export class GeminiWorker {
|
|
|
441
190
|
},
|
|
442
191
|
{
|
|
443
192
|
...this.retryOptions,
|
|
444
|
-
shouldRetry: (error) =>
|
|
193
|
+
shouldRetry: (error) => isAntigravityRetryable(error),
|
|
445
194
|
},
|
|
446
195
|
);
|
|
447
196
|
|
|
@@ -453,15 +202,15 @@ export class GeminiWorker {
|
|
|
453
202
|
};
|
|
454
203
|
} catch (error) {
|
|
455
204
|
return {
|
|
456
|
-
output: error.stderr || error.message || "
|
|
205
|
+
output: error.stderr || error.message || "Antigravity worker failed",
|
|
457
206
|
exitCode: error.code === "ETIMEDOUT" ? 124 : 1,
|
|
458
207
|
sessionKey: options.sessionKey || null,
|
|
459
|
-
error:
|
|
208
|
+
error: buildAntigravityErrorInfo(error, attempts || 1),
|
|
460
209
|
raw: error.result || null,
|
|
461
210
|
};
|
|
462
211
|
}
|
|
463
212
|
}
|
|
464
213
|
}
|
|
465
214
|
|
|
466
|
-
/** @visibleForTesting
|
|
215
|
+
/** @visibleForTesting - 테스트 전용 export. 외부 소비 금지. */
|
|
467
216
|
export { buildSpawnSpec, quoteWindowsCmdArg };
|
|
@@ -61,13 +61,14 @@
|
|
|
61
61
|
* @property {() => Promise<void>} start
|
|
62
62
|
* @property {() => Promise<void>} stop
|
|
63
63
|
* @property {() => boolean} isReady
|
|
64
|
-
* @property {'codex'|'codex-app-server'|'gemini'|'claude'|'delegator'} type
|
|
64
|
+
* @property {'codex'|'codex-app-server'|'gemini'|'antigravity'|'claude'|'delegator'} type
|
|
65
65
|
*/
|
|
66
66
|
|
|
67
67
|
export const WORKER_TYPES = Object.freeze([
|
|
68
68
|
"codex",
|
|
69
69
|
"codex-app-server",
|
|
70
70
|
"gemini",
|
|
71
|
+
"antigravity",
|
|
71
72
|
"claude",
|
|
72
73
|
"delegator",
|
|
73
74
|
]);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// hub/workers/worker-utils.mjs — 워커 공통 유틸리티
|
|
2
|
-
// claude-worker,
|
|
2
|
+
// claude-worker, Antigravity route compatibility worker, pipe 등에서 공유하는 순수 유틸 함수 모음.
|
|
3
3
|
|
|
4
4
|
export const DEFAULT_TIMEOUT_MS = 15 * 60 * 1000;
|
|
5
5
|
export const DEFAULT_KILL_GRACE_MS = 1000;
|
package/package.json
CHANGED
|
@@ -33,14 +33,14 @@ const AGENT_PROFILES = {
|
|
|
33
33
|
mcpHint: "implement",
|
|
34
34
|
},
|
|
35
35
|
cleanup: {
|
|
36
|
-
profile: "
|
|
36
|
+
profile: "gpt55_med",
|
|
37
37
|
timeoutSec: 540,
|
|
38
38
|
runMode: "fg",
|
|
39
39
|
opusOversight: false,
|
|
40
40
|
mcpHint: "implement",
|
|
41
41
|
},
|
|
42
42
|
deslop: {
|
|
43
|
-
profile: "
|
|
43
|
+
profile: "gpt55_med",
|
|
44
44
|
timeoutSec: 540,
|
|
45
45
|
runMode: "fg",
|
|
46
46
|
opusOversight: false,
|
|
@@ -157,7 +157,7 @@ const AGENT_PROFILES = {
|
|
|
157
157
|
subcommand: "review",
|
|
158
158
|
},
|
|
159
159
|
spark: {
|
|
160
|
-
profile: "
|
|
160
|
+
profile: "gpt55_low",
|
|
161
161
|
timeoutSec: 180,
|
|
162
162
|
runMode: "fg",
|
|
163
163
|
opusOversight: false,
|
|
@@ -1,39 +1,11 @@
|
|
|
1
|
-
// cli-gemini.mjs — Gemini
|
|
2
|
-
//
|
|
3
|
-
// 책임: Gemini 프로파일/모델/timeout 매핑. resolve_gemini_profile() 의 결과는 Phase 1 에서
|
|
4
|
-
// 통합한다 (Phase 0 은 라벨만 전달).
|
|
5
|
-
//
|
|
6
|
-
// 출처: scripts/tfx-route.sh route_agent() L1045-L1050.
|
|
1
|
+
// cli-gemini.mjs — legacy Gemini adapter alias.
|
|
2
|
+
// The public "gemini" label remains accepted, but the executable plan is AGY.
|
|
7
3
|
|
|
8
|
-
|
|
9
|
-
export const cliType = "gemini";
|
|
10
|
-
export const command = "gemini";
|
|
11
|
-
|
|
12
|
-
const AGENT_PROFILES = {
|
|
13
|
-
designer: {
|
|
14
|
-
profile: "pro31",
|
|
15
|
-
timeoutSec: 900,
|
|
16
|
-
runMode: "bg",
|
|
17
|
-
opusOversight: false,
|
|
18
|
-
mcpHint: "docs",
|
|
19
|
-
},
|
|
20
|
-
gemini: {
|
|
21
|
-
profile: "pro31",
|
|
22
|
-
timeoutSec: 900,
|
|
23
|
-
runMode: "bg",
|
|
24
|
-
opusOversight: false,
|
|
25
|
-
mcpHint: "docs",
|
|
26
|
-
},
|
|
27
|
-
writer: {
|
|
28
|
-
profile: "flash3",
|
|
29
|
-
timeoutSec: 900,
|
|
30
|
-
runMode: "bg",
|
|
31
|
-
opusOversight: false,
|
|
32
|
-
mcpHint: "docs",
|
|
33
|
-
},
|
|
34
|
-
};
|
|
4
|
+
import * as agyAdapter from "./cli-agy.mjs";
|
|
35
5
|
|
|
36
|
-
const
|
|
6
|
+
export const id = "gemini";
|
|
7
|
+
export const cliType = "antigravity";
|
|
8
|
+
export const command = "agy";
|
|
37
9
|
|
|
38
10
|
export function plan({
|
|
39
11
|
agent,
|
|
@@ -45,23 +17,21 @@ export function plan({
|
|
|
45
17
|
if (!agent) {
|
|
46
18
|
throw new Error("[cli-gemini] agent required");
|
|
47
19
|
}
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
args: ["-m", cfg.profile, "-y", "--prompt"],
|
|
56
|
-
timeoutMs: effectiveTimeoutSec * 1000,
|
|
57
|
-
runMode: cfg.runMode,
|
|
58
|
-
opusOversight: cfg.opusOversight,
|
|
59
|
-
mcpProfile: mcpProfile === "auto" ? cfg.mcpHint : mcpProfile,
|
|
60
|
-
promptLength: prompt.length,
|
|
61
|
-
contextFile: contextFile || null,
|
|
62
|
-
};
|
|
20
|
+
return agyAdapter.plan({
|
|
21
|
+
agent: agent === "gemini" ? "antigravity" : agent,
|
|
22
|
+
prompt,
|
|
23
|
+
mcpProfile,
|
|
24
|
+
timeoutSec,
|
|
25
|
+
contextFile,
|
|
26
|
+
});
|
|
63
27
|
}
|
|
64
28
|
|
|
65
29
|
export function describe() {
|
|
66
|
-
return {
|
|
30
|
+
return {
|
|
31
|
+
id,
|
|
32
|
+
cliType,
|
|
33
|
+
command,
|
|
34
|
+
aliases: ["gemini"],
|
|
35
|
+
agents: ["gemini", "designer", "writer", "antigravity", "agy"],
|
|
36
|
+
};
|
|
67
37
|
}
|