maoda-commander-tt 0.0.63 → 0.0.64
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/README.md +20 -29
- package/dist/{chunk-VCLWIPCG.js → chunk-2VUM57PV.js} +83 -11
- package/dist/chunk-2VUM57PV.js.map +1 -0
- package/dist/{chunk-ZOHU5FLF.js → chunk-BXUN4KVN.js} +287 -280
- package/dist/chunk-BXUN4KVN.js.map +1 -0
- package/dist/codex-worker-main.js +1 -1
- package/dist/image-worker-main.js +1 -1
- package/dist/index.d.ts +43 -1
- package/dist/index.js +4 -2
- package/dist/main.js +2 -2
- package/dist/traex-worker-main.js +1 -1
- package/package.json +2 -2
- package/dist/chunk-VCLWIPCG.js.map +0 -1
- package/dist/chunk-ZOHU5FLF.js.map +0 -1
package/README.md
CHANGED
|
@@ -114,19 +114,19 @@ revision,不回显 value。
|
|
|
114
114
|
|
|
115
115
|
## 后台启动 Codex
|
|
116
116
|
|
|
117
|
-
`tt codex`、`tt
|
|
117
|
+
`tt codex`、`tt codex-exec` 和本地图片 worker 共用可执行文件查找顺序:
|
|
118
118
|
`/Applications/ChatGPT.app/Contents/Resources/codex` →
|
|
119
119
|
`/Applications/Codex.app/Contents/Resources/codex` → PATH 中的 `codex`。
|
|
120
120
|
App 内路径不存在、不是文件或不可执行时跳到下一项;启动后的执行失败不重试下一项。
|
|
121
121
|
|
|
122
122
|
```bash
|
|
123
123
|
tt codex "我的具体 prompt"
|
|
124
|
-
tt codex -C /path/to/repo -m gpt-
|
|
124
|
+
tt codex -C /path/to/repo -m gpt-6-astra -r high "我的具体 prompt"
|
|
125
125
|
tt codex --help
|
|
126
126
|
```
|
|
127
127
|
|
|
128
|
-
默认工作目录 `/Users/bytedance/work/autogen`,默认模型 `gpt-6-
|
|
129
|
-
`
|
|
128
|
+
默认工作目录 `/Users/bytedance/work/autogen`,默认模型 `gpt-6-sol`,默认推理强度
|
|
129
|
+
`ultra`。模型可选 `gpt-6-sol`、`gpt-6-astra`、`gpt-5.6-sol`;推理强度可选
|
|
130
130
|
`low`、`medium`、`high`、`xhigh`、`max`、`ultra`。
|
|
131
131
|
|
|
132
132
|
macOS/Linux 下通过 `nohup` 启动后台 worker,由 worker 运行 `codex app-server`,
|
|
@@ -146,27 +146,27 @@ App 可发现 app-server 会话,但 App 侧边栏是否按项目分组还取
|
|
|
146
146
|
项目归属同步。服务端绑定 projectId 不等同于旧版 App 侧边栏已同步;tt 不修改 App
|
|
147
147
|
私有状态文件或数据库来强制分组。
|
|
148
148
|
|
|
149
|
-
##
|
|
149
|
+
## 同步执行 Codex
|
|
150
150
|
|
|
151
151
|
```bash
|
|
152
|
-
tt
|
|
153
|
-
tt
|
|
154
|
-
tt
|
|
152
|
+
tt codex-exec "我的具体 prompt"
|
|
153
|
+
tt codex-exec -C /path/to/workdir -m gpt-6-astra -r high --json "我的具体 prompt"
|
|
154
|
+
tt codex-exec --help
|
|
155
155
|
```
|
|
156
156
|
|
|
157
|
-
|
|
158
|
-
`
|
|
159
|
-
|
|
157
|
+
`tt codex-exec` 直接运行 `codex exec`,等待本轮完成后返回。参数与 `tt codex` 对齐:
|
|
158
|
+
完整非空提示词必填,`-m/--model` 默认 `gpt-6-sol`,`-r/--reasoning` 默认 `ultra`,
|
|
159
|
+
模型与推理强度使用相同枚举。未传 `-C/--cd` 时,每次在系统临时目录下新建独立空目录作为工作目录,
|
|
160
|
+
成功、失败或 Ctrl-C 结束后删除目录及其中全部文件产物。需要保留文件必须指定 `-C`,
|
|
161
|
+
显式指定的目录及产物保留;路径必须非空且已存在,可指定空目录,无需 Git 仓库。
|
|
162
|
+
相对路径基于调用目录解析,不存在的目录直接报错。
|
|
160
163
|
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
`reasoning` 和 `projectId: null`。Traex 暂不支持项目接口,因此仅传工作目录,
|
|
168
|
-
不调用 `project/list` 或传入 `thread/start.projectId`。App 显示及项目分组可能
|
|
169
|
-
延迟,`launched` 只代表服务端已接受任务,不代表执行完成或已在 App 中显示。
|
|
164
|
+
无沙箱且不请求审批,继承本机 Codex 配置、登录态与会话持久化,不保证 App 项目归属。
|
|
165
|
+
普通模式 stdout 透传原生最终回答文本,stderr 透传原生执行过程。
|
|
166
|
+
`--json` 将 stdout 切换为 Codex 原生 JSONL 事件流,stderr 为诊断。
|
|
167
|
+
不添加 tt envelope、事件包装或心跳,等待原生执行结束并保留其退出码。
|
|
168
|
+
tt 参数校验、启动或清理失败写入 stderr,退出码为 1;清理失败不撤回已透传到 stdout 的内容。
|
|
169
|
+
Ctrl-C 终止本次执行,显式 `-C` 中已产生的改动不回滚;SIGKILL 或进程崩溃无法保证临时目录清理。
|
|
170
170
|
|
|
171
171
|
## 发布到 npm
|
|
172
172
|
|
|
@@ -377,15 +377,6 @@ loopback HTTP 除外),客户端不跟随重定向,以免将 token 发送
|
|
|
377
377
|
若公开目标已删除,但目录清单刷新或私有暂存清理失败,命令返回错误和非零退出码,
|
|
378
378
|
同时保留 `data.state: "deleted"`;AI 应据此排查后续步骤,不能把它理解为目标仍在。
|
|
379
379
|
|
|
380
|
-
## Shell 快捷方式
|
|
381
|
-
|
|
382
|
-
```bash
|
|
383
|
-
# 在 ~/work/web-proxy 中先执行 w2 start,成功后执行 pnpm gateway
|
|
384
|
-
tt sc w2
|
|
385
|
-
```
|
|
386
|
-
|
|
387
|
-
命令日志直接输出到当前终端,gateway 在前台运行。
|
|
388
|
-
|
|
389
380
|
## AI 图片生成
|
|
390
381
|
|
|
391
382
|
图片、音频与视频统一采用异步提交:默认返回 `taskId`,`status` 单次查询,
|
|
@@ -211,16 +211,87 @@ function describeSignal(signal) {
|
|
|
211
211
|
return signal ? `, signal: ${signal}` : "";
|
|
212
212
|
}
|
|
213
213
|
|
|
214
|
-
// src/bedrock/process/
|
|
214
|
+
// src/bedrock/process/passthrough-process.ts
|
|
215
|
+
import { spawn as spawn4 } from "node:child_process";
|
|
216
|
+
import { constants } from "node:os";
|
|
215
217
|
import { err as err4, ok as ok4 } from "rockbed/error";
|
|
218
|
+
var FORWARDED_SIGNALS = ["SIGINT", "SIGTERM", "SIGHUP"];
|
|
219
|
+
var TERMINATION_GRACE_MS = 2e3;
|
|
220
|
+
function runPassthroughProcess(command, args, options = {}) {
|
|
221
|
+
return new Promise((resolve) => {
|
|
222
|
+
let child;
|
|
223
|
+
try {
|
|
224
|
+
child = spawn4(command, [...args], {
|
|
225
|
+
cwd: options.cwd,
|
|
226
|
+
env: options.env ? { ...process.env, ...options.env } : process.env,
|
|
227
|
+
shell: false,
|
|
228
|
+
stdio: [options.input === void 0 ? "ignore" : "pipe", "inherit", "inherit"]
|
|
229
|
+
});
|
|
230
|
+
} catch (error) {
|
|
231
|
+
resolve(err4(1, `\u542F\u52A8\u5B50\u8FDB\u7A0B\u5931\u8D25${describeErrorCode(error)}`));
|
|
232
|
+
return;
|
|
233
|
+
}
|
|
234
|
+
let failure;
|
|
235
|
+
let brokenInput = false;
|
|
236
|
+
let closed = false;
|
|
237
|
+
let killTimer;
|
|
238
|
+
const isRunning = () => child.pid !== void 0 && child.exitCode === null && child.signalCode === null;
|
|
239
|
+
const stop = (signal = "SIGTERM") => {
|
|
240
|
+
if (closed || !isRunning()) return;
|
|
241
|
+
if (!killTimer) {
|
|
242
|
+
killTimer = setTimeout(() => {
|
|
243
|
+
if (isRunning()) child.kill("SIGKILL");
|
|
244
|
+
}, TERMINATION_GRACE_MS);
|
|
245
|
+
}
|
|
246
|
+
child.kill(signal);
|
|
247
|
+
};
|
|
248
|
+
const fail = (message) => {
|
|
249
|
+
failure ??= err4(1, message);
|
|
250
|
+
stop();
|
|
251
|
+
};
|
|
252
|
+
const signalHandlers = FORWARDED_SIGNALS.map((signal) => {
|
|
253
|
+
const handler = () => stop(signal);
|
|
254
|
+
process.on(signal, handler);
|
|
255
|
+
return { signal, handler };
|
|
256
|
+
});
|
|
257
|
+
child.on("error", (error) => fail(`\u5B50\u8FDB\u7A0B\u6267\u884C\u5931\u8D25${describeErrorCode(error)}`));
|
|
258
|
+
child.on("exit", () => clearTimeout(killTimer));
|
|
259
|
+
child.on("close", (code, signal) => {
|
|
260
|
+
closed = true;
|
|
261
|
+
clearTimeout(killTimer);
|
|
262
|
+
for (const { signal: parentSignal, handler } of signalHandlers) process.off(parentSignal, handler);
|
|
263
|
+
const exitCode = code ?? (signal ? 128 + constants.signals[signal] : 1);
|
|
264
|
+
if (!failure && brokenInput && exitCode === 0) failure = err4(1, "\u5199\u5165\u5B50\u8FDB\u7A0B stdin \u5931\u8D25 (EPIPE)");
|
|
265
|
+
resolve(failure ?? ok4({ exitCode }));
|
|
266
|
+
});
|
|
267
|
+
child.stdin?.on("error", (error) => {
|
|
268
|
+
if (error.code === "EPIPE") brokenInput = true;
|
|
269
|
+
else fail(`\u5199\u5165\u5B50\u8FDB\u7A0B stdin \u5931\u8D25${describeErrorCode(error)}`);
|
|
270
|
+
});
|
|
271
|
+
if (options.input !== void 0) {
|
|
272
|
+
try {
|
|
273
|
+
child.stdin?.end(options.input);
|
|
274
|
+
} catch (error) {
|
|
275
|
+
fail(`\u5199\u5165\u5B50\u8FDB\u7A0B stdin \u5931\u8D25${describeErrorCode(error)}`);
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
});
|
|
279
|
+
}
|
|
280
|
+
function describeErrorCode(error) {
|
|
281
|
+
if (!error || typeof error !== "object" || !("code" in error)) return "";
|
|
282
|
+
return typeof error.code === "string" && /^[A-Z][A-Z0-9_]*$/.test(error.code) ? ` (${error.code})` : "";
|
|
283
|
+
}
|
|
216
284
|
|
|
217
|
-
// src/bedrock/process/detached-
|
|
218
|
-
import { spawn as spawn4 } from "node:child_process";
|
|
285
|
+
// src/bedrock/process/detached-process.ts
|
|
219
286
|
import { err as err5, ok as ok5 } from "rockbed/error";
|
|
287
|
+
|
|
288
|
+
// src/bedrock/process/detached-worker.ts
|
|
289
|
+
import { spawn as spawn5 } from "node:child_process";
|
|
290
|
+
import { err as err6, ok as ok6 } from "rockbed/error";
|
|
220
291
|
function startDetachedWorker(args, options) {
|
|
221
|
-
if (process.platform === "win32") return Promise.resolve(
|
|
292
|
+
if (process.platform === "win32") return Promise.resolve(err6(1, "\u540E\u53F0 nohup \u542F\u52A8\u4EC5\u652F\u6301 macOS/Linux"));
|
|
222
293
|
return new Promise((resolve) => {
|
|
223
|
-
const child =
|
|
294
|
+
const child = spawn5("nohup", [process.execPath, ...args], {
|
|
224
295
|
cwd: options.cwd,
|
|
225
296
|
detached: true,
|
|
226
297
|
stdio: ["ignore", "ignore", "ignore", "ipc"],
|
|
@@ -235,14 +306,14 @@ function startDetachedWorker(args, options) {
|
|
|
235
306
|
child.unref();
|
|
236
307
|
resolve(result);
|
|
237
308
|
};
|
|
238
|
-
const timer = setTimeout(() => finish(
|
|
239
|
-
child.once("error", (error) => finish(
|
|
240
|
-
child.once("exit", (code, signal) => finish(
|
|
309
|
+
const timer = setTimeout(() => finish(err6(1, "\u7B49\u5F85\u540E\u53F0\u63D0\u4EA4\u786E\u8BA4\u8D85\u65F6\uFF1B\u4EFB\u52A1\u53EF\u80FD\u5DF2\u521B\u5EFA\uFF0C\u8BF7\u5148\u5728\u5BF9\u5E94 App \u4E2D\u68C0\u67E5\uFF0C\u52FF\u76F4\u63A5\u91CD\u8BD5")), options.readyTimeoutMs ?? 45e3);
|
|
310
|
+
child.once("error", (error) => finish(err6(1, `\u540E\u53F0\u542F\u52A8\u5931\u8D25: ${error.message}`)));
|
|
311
|
+
child.once("exit", (code, signal) => finish(err6(1, `\u540E\u53F0\u8FDB\u7A0B\u5728\u63D0\u4EA4\u786E\u8BA4\u524D\u9000\u51FA (${signal ?? code ?? "unknown"})`)));
|
|
241
312
|
child.on("message", (message) => {
|
|
242
313
|
if (!message || typeof message !== "object") return;
|
|
243
314
|
const reply = message;
|
|
244
|
-
if (reply.ready === true && reply.data !== void 0) finish(
|
|
245
|
-
else if (typeof reply.error === "string") finish(
|
|
315
|
+
if (reply.ready === true && reply.data !== void 0) finish(ok6({ pid: child.pid, data: reply.data }));
|
|
316
|
+
else if (typeof reply.error === "string") finish(err6(1, reply.error));
|
|
246
317
|
});
|
|
247
318
|
});
|
|
248
319
|
}
|
|
@@ -251,9 +322,10 @@ export {
|
|
|
251
322
|
runProcess,
|
|
252
323
|
captureProcess,
|
|
253
324
|
openUrl,
|
|
325
|
+
runPassthroughProcess,
|
|
254
326
|
startDetachedWorker,
|
|
255
327
|
runJsonRpcProcess,
|
|
256
328
|
startBackgroundProcess,
|
|
257
329
|
runJsonLineProcess
|
|
258
330
|
};
|
|
259
|
-
//# sourceMappingURL=chunk-
|
|
331
|
+
//# sourceMappingURL=chunk-2VUM57PV.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/bedrock/process/json-rpc-process.ts","../src/bedrock/process/background-process.ts","../src/bedrock/process/run-process.ts","../src/bedrock/process/passthrough-process.ts","../src/bedrock/process/detached-process.ts","../src/bedrock/process/detached-worker.ts"],"sourcesContent":["import { spawn } from \"node:child_process\";\nimport { createInterface } from \"node:readline\";\nimport { err, ok, type Result } from \"rockbed/error\";\n\nexport interface IJsonRpcNotification {\n readonly method: string;\n readonly params?: unknown;\n}\n\nexport interface IJsonRpcConnection {\n request<T>(method: string, params: unknown): Promise<Result<T>>;\n notify(method: string, params?: unknown): void;\n waitForNotification(predicate: (notification: IJsonRpcNotification) => boolean): Promise<Result<IJsonRpcNotification>>;\n}\n\n/** Own a stdio JSON-RPC process, discard diagnostics, and release it when the callback finishes. */\nexport async function runJsonRpcProcess<T>(\n command: string,\n args: readonly string[],\n options: { readonly cwd: string; readonly execute: (connection: IJsonRpcConnection) => Promise<Result<T>>; readonly requestTimeoutMs?: number },\n): Promise<Result<T>> {\n const child = spawn(command, [...args], { cwd: options.cwd, stdio: [\"pipe\", \"pipe\", \"ignore\"], shell: false });\n const lines = createInterface({ input: child.stdout });\n let sequence = 0;\n let closed: string | undefined;\n const pending = new Map<number, (result: Result<unknown>) => void>();\n const subscribers = new Set<(result: Result<IJsonRpcNotification>) => void>();\n const fail = (message: string): void => {\n if (closed) return;\n closed = message;\n for (const resolve of pending.values()) resolve(err(1, message));\n pending.clear();\n for (const resolve of [...subscribers]) resolve(err(1, message));\n subscribers.clear();\n };\n const send = (message: unknown): void => {\n if (!closed) child.stdin.write(`${JSON.stringify(message)}\\n`, (error) => { if (error) fail(`写入子进程失败: ${error.message}`); });\n };\n child.on(\"error\", (error) => fail(`启动 ${command} 失败: ${error.message}`));\n child.stdin.on(\"error\", (error) => fail(`子进程输入流失败: ${error.message}`));\n child.on(\"close\", (code, signal) => fail(`子进程连接已关闭 (${signal ?? code ?? \"unknown\"})`));\n lines.on(\"line\", (line) => {\n let message: { id?: number | string; method?: string; params?: unknown; result?: unknown; error?: { message?: string } };\n try { message = JSON.parse(line); } catch { return; }\n if (!message || typeof message !== \"object\") return;\n if (message.id !== undefined && message.method) {\n // This unattended client cannot answer interactive server requests.\n send({ id: message.id, error: { code: -32601, message: \"Unattended client cannot handle interactive requests\" } });\n } else if (typeof message.id === \"number\") {\n const resolve = pending.get(message.id);\n pending.delete(message.id);\n resolve?.(message.error ? err(1, message.error.message ?? \"JSON-RPC request failed\") : ok(message.result));\n } else if (typeof message.method === \"string\") {\n for (const subscriber of [...subscribers]) subscriber(ok({ method: message.method, params: message.params }));\n }\n });\n const connection: IJsonRpcConnection = {\n request: <R>(method: string, params: unknown): Promise<Result<R>> => {\n if (closed) return Promise.resolve(err(1, closed));\n return new Promise((resolve) => {\n const id = ++sequence;\n const timer = setTimeout(() => {\n pending.delete(id);\n resolve(err(1, `${method} 请求超时;远端可能已接收,请勿自动重试`));\n }, options.requestTimeoutMs ?? 15_000);\n pending.set(id, (result) => { clearTimeout(timer); resolve(result as Result<R>); });\n send({ id, method, params });\n });\n },\n notify: (method, params) => send({ method, ...(params === undefined ? {} : { params }) }),\n waitForNotification: (predicate) => {\n if (closed) return Promise.resolve(err(1, closed));\n return new Promise((resolve) => {\n const subscriber = (result: Result<IJsonRpcNotification>): void => {\n if (!result.ok || predicate(result.value)) { subscribers.delete(subscriber); resolve(result); }\n };\n subscribers.add(subscriber);\n });\n },\n };\n try {\n return await options.execute(connection);\n } catch (error) {\n return err(1, error instanceof Error ? error.message : String(error));\n } finally {\n fail(\"子进程连接已结束\");\n lines.close();\n child.stdin.end();\n // Allow graceful shutdown first, but never leave a stuck server behind.\n if (child.exitCode === null && child.signalCode === null) {\n const timer = setTimeout(() => child.kill(\"SIGKILL\"), 2000);\n timer.unref();\n child.once(\"close\", () => clearTimeout(timer));\n }\n }\n}\n","import { spawn } from \"node:child_process\";\nimport { createInterface } from \"node:readline\";\nimport { err, ok, type Result } from \"rockbed/error\";\n\nexport interface IBackgroundProcessOptions {\n readonly cwd?: string;\n readonly env?: NodeJS.ProcessEnv;\n readonly readyTimeoutMs?: number;\n}\n\n/** Detach only after the child explicitly acknowledges ownership over IPC. */\nexport function startBackgroundProcess(\n command: string,\n args: readonly string[],\n options: IBackgroundProcessOptions = {},\n): Promise<Result<void>> {\n return new Promise((resolve) => {\n const child = spawn(command, [...args], {\n cwd: options.cwd,\n env: options.env ? { ...process.env, ...options.env } : process.env,\n detached: true,\n stdio: [\"ignore\", \"ignore\", \"ignore\", \"ipc\"],\n });\n let settled = false;\n const finish = (result: Result<void>): void => {\n if (settled) return;\n settled = true;\n clearTimeout(timer);\n if (child.connected) child.disconnect();\n child.unref();\n resolve(result);\n };\n const timer = setTimeout(() => finish(err(1, \"后台进程未在限定时间内确认接管;可能仍在启动,请查询原任务\")), options.readyTimeoutMs ?? 15_000);\n child.on(\"error\", (error) => finish(err(1, `启动后台进程失败: ${error.message}`)));\n child.on(\"exit\", (code) => finish(err(1, `后台进程在确认接管前退出 (${code ?? \"signal\"})`)));\n child.on(\"message\", (message: unknown) => {\n if (!message || typeof message !== \"object\") return;\n const reply = message as { ready?: boolean; error?: string };\n if (reply.ready === true) finish(ok());\n else if (typeof reply.error === \"string\") finish(err(1, reply.error));\n });\n });\n}\n\n/** Stream JSONL without retaining potentially large or sensitive model output. */\nexport function runJsonLineProcess(\n command: string,\n args: readonly string[],\n options: { readonly cwd?: string; readonly onEvent: (event: unknown) => void },\n): Promise<Result<void>> {\n return new Promise((resolve) => {\n const child = spawn(command, [...args], { cwd: options.cwd, stdio: [\"ignore\", \"pipe\", \"ignore\"] });\n const lines = createInterface({ input: child.stdout! });\n lines.on(\"line\", (line) => {\n try { options.onEvent(JSON.parse(line)); } catch { /* Non-JSON diagnostics are not task results. */ }\n });\n child.on(\"error\", (error) => resolve(err(1, `启动 JSONL 子进程失败: ${error.message}`)));\n child.on(\"close\", (code, signal) => {\n lines.close();\n resolve(code === 0 ? ok() : err(1, `JSONL 子进程退出 (${signal ?? code ?? \"unknown\"})`));\n });\n });\n}\n","import { spawn } from \"node:child_process\";\nimport { err, ok, type Result } from \"rockbed/error\";\n\nexport interface IRunProcessOptions {\n readonly cwd?: string;\n /** 在 `process.env` 之上叠加的环境变量。 */\n readonly env?: NodeJS.ProcessEnv;\n /** 通过 shell 执行,允许 `a && b` 这类命令行。 */\n readonly shell?: boolean;\n /** `inherit`(默认)把子进程 stdio 透传到当前终端;`ignore` 完全静默。 */\n readonly stdio?: \"inherit\" | \"ignore\";\n}\n\nexport interface ICaptureProcessOptions {\n readonly cwd?: string;\n readonly env?: NodeJS.ProcessEnv;\n readonly shell?: boolean;\n}\n\nexport interface IProcessOutput {\n readonly stdout: string;\n readonly stderr: string;\n}\n\n/**\n * 运行子进程并等待退出,stdio 透传或忽略。退出码非 0 视为可预期失败。\n */\nexport function runProcess(\n command: string,\n args: readonly string[] = [],\n options: IRunProcessOptions = {},\n): Promise<Result<void>> {\n const child = spawn(command, [...args], {\n cwd: options.cwd ?? process.cwd(),\n env: options.env ? { ...process.env, ...options.env } : process.env,\n shell: options.shell ?? false,\n stdio: options.stdio ?? \"inherit\",\n });\n const label = describeCommand(command, args);\n\n return new Promise((resolve) => {\n child.on(\"error\", (error) => {\n resolve(err(1, `执行 ${label} 失败: ${error.message}`));\n });\n child.on(\"close\", (code, signal) => {\n if (code === 0) {\n resolve(ok());\n return;\n }\n resolve(err(code ?? 1, `执行 ${label} 失败${describeSignal(signal)}`));\n });\n });\n}\n\n/**\n * 运行子进程并捕获 stdout/stderr。退出码非 0 时把 stderr 附在失败消息里。\n */\nexport function captureProcess(\n command: string,\n args: readonly string[] = [],\n options: ICaptureProcessOptions = {},\n): Promise<Result<IProcessOutput>> {\n const child = spawn(command, [...args], {\n cwd: options.cwd ?? process.cwd(),\n env: options.env ? { ...process.env, ...options.env } : process.env,\n shell: options.shell ?? false,\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n });\n const label = describeCommand(command, args);\n let stdout = \"\";\n let stderr = \"\";\n\n child.stdout?.on(\"data\", (chunk: Buffer) => {\n stdout += chunk.toString();\n });\n child.stderr?.on(\"data\", (chunk: Buffer) => {\n stderr += chunk.toString();\n });\n\n return new Promise((resolve) => {\n child.on(\"error\", (error) => {\n resolve(err(1, `执行 ${label} 失败: ${error.message}`));\n });\n child.on(\"close\", (code, signal) => {\n if (code === 0) {\n resolve(ok({ stdout, stderr }));\n return;\n }\n const stderrText = stderr.trim() ? `\\n${stderr.trim()}` : \"\";\n resolve(\n err(\n code ?? 1,\n `执行 ${label} 失败${describeSignal(signal)}${stderrText}`,\n ),\n );\n });\n });\n}\n\n/**\n * 用系统默认程序打开 URL(macOS `open`、Windows `start`、其他 `xdg-open`)。\n */\nexport function openUrl(url: string): Promise<Result<void>> {\n const [command, args] =\n process.platform === \"darwin\"\n ? [\"open\", [url]]\n : process.platform === \"win32\"\n ? [\"cmd\", [\"/c\", \"start\", \"\", url]]\n : [\"xdg-open\", [url]];\n return runProcess(command, args, { stdio: \"ignore\" });\n}\n\nfunction describeCommand(command: string, args: readonly string[]): string {\n return [command, ...args].join(\" \").trim();\n}\n\nfunction describeSignal(signal: NodeJS.Signals | null): string {\n return signal ? `, signal: ${signal}` : \"\";\n}\n","import { spawn, type ChildProcess } from \"node:child_process\";\nimport { constants } from \"node:os\";\nimport { err, ok, type Result } from \"rockbed/error\";\n\nexport interface IPassthroughProcessOptions {\n readonly cwd?: string;\n /** Overlay the current process environment. */\n readonly env?: NodeJS.ProcessEnv;\n /** When supplied, write this value to stdin and close it, including an empty string. */\n readonly input?: string;\n}\n\nexport interface IPassthroughProcessResult {\n readonly exitCode: number;\n}\n\nconst FORWARDED_SIGNALS = [\"SIGINT\", \"SIGTERM\", \"SIGHUP\"] as const;\nconst TERMINATION_GRACE_MS = 2_000;\n\n/** Inherit native output and return the native exit status after the foreground child closes. */\nexport function runPassthroughProcess(\n command: string,\n args: readonly string[],\n options: IPassthroughProcessOptions = {},\n): Promise<Result<IPassthroughProcessResult>> {\n return new Promise((resolve) => {\n let child: ChildProcess;\n try {\n child = spawn(command, [...args], {\n cwd: options.cwd,\n env: options.env ? { ...process.env, ...options.env } : process.env,\n shell: false,\n stdio: [options.input === undefined ? \"ignore\" : \"pipe\", \"inherit\", \"inherit\"],\n });\n } catch (error) {\n resolve(err(1, `启动子进程失败${describeErrorCode(error)}`));\n return;\n }\n\n let failure: Result<IPassthroughProcessResult> | undefined;\n let brokenInput = false;\n let closed = false;\n let killTimer: ReturnType<typeof setTimeout> | undefined;\n const isRunning = (): boolean => child.pid !== undefined && child.exitCode === null && child.signalCode === null;\n const stop = (signal: NodeJS.Signals = \"SIGTERM\"): void => {\n if (closed || !isRunning()) return;\n if (!killTimer) {\n // A foreground invocation owns its child until it closes; keep the timer referenced.\n killTimer = setTimeout(() => {\n if (isRunning()) child.kill(\"SIGKILL\");\n }, TERMINATION_GRACE_MS);\n }\n child.kill(signal);\n };\n const fail = (message: string): void => {\n failure ??= err(1, message);\n stop();\n };\n const signalHandlers = FORWARDED_SIGNALS.map((signal) => {\n const handler = (): void => stop(signal);\n process.on(signal, handler);\n return { signal, handler };\n });\n\n child.on(\"error\", (error) => fail(`子进程执行失败${describeErrorCode(error)}`));\n child.on(\"exit\", () => clearTimeout(killTimer));\n child.on(\"close\", (code, signal) => {\n closed = true;\n clearTimeout(killTimer);\n for (const { signal: parentSignal, handler } of signalHandlers) process.off(parentSignal, handler);\n const exitCode = code ?? (signal ? 128 + constants.signals[signal] : 1);\n // Native input rejection commonly closes stdin early. Preserve its own failure status.\n if (!failure && brokenInput && exitCode === 0) failure = err(1, \"写入子进程 stdin 失败 (EPIPE)\");\n resolve(failure ?? ok({ exitCode }));\n });\n child.stdin?.on(\"error\", (error: NodeJS.ErrnoException) => {\n if (error.code === \"EPIPE\") brokenInput = true;\n else fail(`写入子进程 stdin 失败${describeErrorCode(error)}`);\n });\n if (options.input !== undefined) {\n try { child.stdin?.end(options.input); }\n catch (error) { fail(`写入子进程 stdin 失败${describeErrorCode(error)}`); }\n }\n });\n}\n\n/** System codes help diagnosis without disclosing command arguments or prompt contents. */\nfunction describeErrorCode(error: unknown): string {\n if (!error || typeof error !== \"object\" || !(\"code\" in error)) return \"\";\n return typeof error.code === \"string\" && /^[A-Z][A-Z0-9_]*$/.test(error.code) ? ` (${error.code})` : \"\";\n}\n","import { spawn } from \"node:child_process\";\nimport { constants } from \"node:fs\";\nimport { access, stat } from \"node:fs/promises\";\nimport { delimiter, resolve } from \"node:path\";\nimport { err, ok, type Result } from \"rockbed/error\";\n\n/** Fire-and-forget Unix process: ignore SIGHUP and discard all terminal IO. */\nexport async function startDetachedProcess(\n command: string,\n args: readonly string[],\n options: { readonly cwd: string },\n): Promise<Result<{ readonly pid: number }>> {\n if (process.platform === \"win32\") return err(1, \"后台 nohup 启动仅支持 macOS/Linux\");\n // Check the target before launching nohup, whose spawn event alone cannot detect ENOENT.\n const candidates = command.includes(\"/\")\n ? [resolve(options.cwd, command)]\n : (process.env.PATH ?? \"\").split(delimiter).map((dir) => resolve(options.cwd, dir, command));\n let executable: string | undefined;\n for (const candidate of candidates) {\n try {\n await access(candidate, constants.X_OK);\n if ((await stat(candidate)).isFile()) {\n executable = candidate;\n break;\n }\n } catch { /* Try the next PATH entry. */ }\n }\n if (!executable) return err(1, `找不到可执行文件: ${command}`);\n\n return new Promise((resolveResult) => {\n const child = spawn(\"nohup\", [executable, ...args], {\n cwd: options.cwd,\n detached: true,\n stdio: \"ignore\",\n shell: false,\n });\n child.once(\"error\", (error) => resolveResult(err(1, `后台启动失败: ${error.message}`)));\n child.once(\"spawn\", () => {\n child.unref();\n resolveResult(ok({ pid: child.pid! }));\n });\n });\n}\n","import { spawn } from \"node:child_process\";\nimport { err, ok, type Result } from \"rockbed/error\";\n\n/** Launch a Node worker under nohup; wait only for its submission acknowledgement. */\nexport function startDetachedWorker<T>(\n args: readonly string[],\n options: { readonly cwd: string; readonly readyTimeoutMs?: number },\n): Promise<Result<{ readonly pid: number; readonly data: T }>> {\n if (process.platform === \"win32\") return Promise.resolve(err(1, \"后台 nohup 启动仅支持 macOS/Linux\"));\n return new Promise((resolve) => {\n const child = spawn(\"nohup\", [process.execPath, ...args], {\n cwd: options.cwd, detached: true, stdio: [\"ignore\", \"ignore\", \"ignore\", \"ipc\"], shell: false,\n });\n let settled = false;\n const finish = (result: Result<{ readonly pid: number; readonly data: T }>): void => {\n if (settled) return;\n settled = true;\n clearTimeout(timer);\n if (child.connected) child.disconnect();\n child.unref();\n resolve(result);\n };\n const timer = setTimeout(() => finish(err(1, \"等待后台提交确认超时;任务可能已创建,请先在对应 App 中检查,勿直接重试\")), options.readyTimeoutMs ?? 45_000);\n child.once(\"error\", (error) => finish(err(1, `后台启动失败: ${error.message}`)));\n child.once(\"exit\", (code, signal) => finish(err(1, `后台进程在提交确认前退出 (${signal ?? code ?? \"unknown\"})`)));\n child.on(\"message\", (message: unknown) => {\n if (!message || typeof message !== \"object\") return;\n const reply = message as { ready?: boolean; data?: T; error?: string };\n if (reply.ready === true && reply.data !== undefined) finish(ok({ pid: child.pid!, data: reply.data }));\n else if (typeof reply.error === \"string\") finish(err(1, reply.error));\n });\n });\n}\n"],"mappings":";AAAA,SAAS,aAAa;AACtB,SAAS,uBAAuB;AAChC,SAAS,KAAK,UAAuB;AAcrC,eAAsB,kBACpB,SACA,MACA,SACoB;AACpB,QAAM,QAAQ,MAAM,SAAS,CAAC,GAAG,IAAI,GAAG,EAAE,KAAK,QAAQ,KAAK,OAAO,CAAC,QAAQ,QAAQ,QAAQ,GAAG,OAAO,MAAM,CAAC;AAC7G,QAAM,QAAQ,gBAAgB,EAAE,OAAO,MAAM,OAAO,CAAC;AACrD,MAAI,WAAW;AACf,MAAI;AACJ,QAAM,UAAU,oBAAI,IAA+C;AACnE,QAAM,cAAc,oBAAI,IAAoD;AAC5E,QAAM,OAAO,CAAC,YAA0B;AACtC,QAAI,OAAQ;AACZ,aAAS;AACT,eAAW,WAAW,QAAQ,OAAO,EAAG,SAAQ,IAAI,GAAG,OAAO,CAAC;AAC/D,YAAQ,MAAM;AACd,eAAW,WAAW,CAAC,GAAG,WAAW,EAAG,SAAQ,IAAI,GAAG,OAAO,CAAC;AAC/D,gBAAY,MAAM;AAAA,EACpB;AACA,QAAM,OAAO,CAAC,YAA2B;AACvC,QAAI,CAAC,OAAQ,OAAM,MAAM,MAAM,GAAG,KAAK,UAAU,OAAO,CAAC;AAAA,GAAM,CAAC,UAAU;AAAE,UAAI,MAAO,MAAK,+CAAY,MAAM,OAAO,EAAE;AAAA,IAAG,CAAC;AAAA,EAC7H;AACA,QAAM,GAAG,SAAS,CAAC,UAAU,KAAK,gBAAM,OAAO,kBAAQ,MAAM,OAAO,EAAE,CAAC;AACvE,QAAM,MAAM,GAAG,SAAS,CAAC,UAAU,KAAK,qDAAa,MAAM,OAAO,EAAE,CAAC;AACrE,QAAM,GAAG,SAAS,CAAC,MAAM,WAAW,KAAK,qDAAa,UAAU,QAAQ,SAAS,GAAG,CAAC;AACrF,QAAM,GAAG,QAAQ,CAAC,SAAS;AACzB,QAAI;AACJ,QAAI;AAAE,gBAAU,KAAK,MAAM,IAAI;AAAA,IAAG,QAAQ;AAAE;AAAA,IAAQ;AACpD,QAAI,CAAC,WAAW,OAAO,YAAY,SAAU;AAC7C,QAAI,QAAQ,OAAO,UAAa,QAAQ,QAAQ;AAE9C,WAAK,EAAE,IAAI,QAAQ,IAAI,OAAO,EAAE,MAAM,QAAQ,SAAS,uDAAuD,EAAE,CAAC;AAAA,IACnH,WAAW,OAAO,QAAQ,OAAO,UAAU;AACzC,YAAM,UAAU,QAAQ,IAAI,QAAQ,EAAE;AACtC,cAAQ,OAAO,QAAQ,EAAE;AACzB,gBAAU,QAAQ,QAAQ,IAAI,GAAG,QAAQ,MAAM,WAAW,yBAAyB,IAAI,GAAG,QAAQ,MAAM,CAAC;AAAA,IAC3G,WAAW,OAAO,QAAQ,WAAW,UAAU;AAC7C,iBAAW,cAAc,CAAC,GAAG,WAAW,EAAG,YAAW,GAAG,EAAE,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,OAAO,CAAC,CAAC;AAAA,IAC9G;AAAA,EACF,CAAC;AACD,QAAM,aAAiC;AAAA,IACrC,SAAS,CAAI,QAAgB,WAAwC;AACnE,UAAI,OAAQ,QAAO,QAAQ,QAAQ,IAAI,GAAG,MAAM,CAAC;AACjD,aAAO,IAAI,QAAQ,CAAC,YAAY;AAC9B,cAAM,KAAK,EAAE;AACb,cAAM,QAAQ,WAAW,MAAM;AAC7B,kBAAQ,OAAO,EAAE;AACjB,kBAAQ,IAAI,GAAG,GAAG,MAAM,qHAAsB,CAAC;AAAA,QACjD,GAAG,QAAQ,oBAAoB,IAAM;AACrC,gBAAQ,IAAI,IAAI,CAAC,WAAW;AAAE,uBAAa,KAAK;AAAG,kBAAQ,MAAmB;AAAA,QAAG,CAAC;AAClF,aAAK,EAAE,IAAI,QAAQ,OAAO,CAAC;AAAA,MAC7B,CAAC;AAAA,IACH;AAAA,IACA,QAAQ,CAAC,QAAQ,WAAW,KAAK,EAAE,QAAQ,GAAI,WAAW,SAAY,CAAC,IAAI,EAAE,OAAO,EAAG,CAAC;AAAA,IACxF,qBAAqB,CAAC,cAAc;AAClC,UAAI,OAAQ,QAAO,QAAQ,QAAQ,IAAI,GAAG,MAAM,CAAC;AACjD,aAAO,IAAI,QAAQ,CAAC,YAAY;AAC9B,cAAM,aAAa,CAAC,WAA+C;AACjE,cAAI,CAAC,OAAO,MAAM,UAAU,OAAO,KAAK,GAAG;AAAE,wBAAY,OAAO,UAAU;AAAG,oBAAQ,MAAM;AAAA,UAAG;AAAA,QAChG;AACA,oBAAY,IAAI,UAAU;AAAA,MAC5B,CAAC;AAAA,IACH;AAAA,EACF;AACA,MAAI;AACF,WAAO,MAAM,QAAQ,QAAQ,UAAU;AAAA,EACzC,SAAS,OAAO;AACd,WAAO,IAAI,GAAG,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;AAAA,EACtE,UAAE;AACA,SAAK,kDAAU;AACf,UAAM,MAAM;AACZ,UAAM,MAAM,IAAI;AAEhB,QAAI,MAAM,aAAa,QAAQ,MAAM,eAAe,MAAM;AACxD,YAAM,QAAQ,WAAW,MAAM,MAAM,KAAK,SAAS,GAAG,GAAI;AAC1D,YAAM,MAAM;AACZ,YAAM,KAAK,SAAS,MAAM,aAAa,KAAK,CAAC;AAAA,IAC/C;AAAA,EACF;AACF;;;AC/FA,SAAS,SAAAA,cAAa;AACtB,SAAS,mBAAAC,wBAAuB;AAChC,SAAS,OAAAC,MAAK,MAAAC,WAAuB;AAS9B,SAAS,uBACd,SACA,MACA,UAAqC,CAAC,GACf;AACvB,SAAO,IAAI,QAAQ,CAAC,YAAY;AAC9B,UAAM,QAAQH,OAAM,SAAS,CAAC,GAAG,IAAI,GAAG;AAAA,MACtC,KAAK,QAAQ;AAAA,MACb,KAAK,QAAQ,MAAM,EAAE,GAAG,QAAQ,KAAK,GAAG,QAAQ,IAAI,IAAI,QAAQ;AAAA,MAChE,UAAU;AAAA,MACV,OAAO,CAAC,UAAU,UAAU,UAAU,KAAK;AAAA,IAC7C,CAAC;AACD,QAAI,UAAU;AACd,UAAM,SAAS,CAAC,WAA+B;AAC7C,UAAI,QAAS;AACb,gBAAU;AACV,mBAAa,KAAK;AAClB,UAAI,MAAM,UAAW,OAAM,WAAW;AACtC,YAAM,MAAM;AACZ,cAAQ,MAAM;AAAA,IAChB;AACA,UAAM,QAAQ,WAAW,MAAM,OAAOE,KAAI,GAAG,gLAA+B,CAAC,GAAG,QAAQ,kBAAkB,IAAM;AAChH,UAAM,GAAG,SAAS,CAAC,UAAU,OAAOA,KAAI,GAAG,qDAAa,MAAM,OAAO,EAAE,CAAC,CAAC;AACzE,UAAM,GAAG,QAAQ,CAAC,SAAS,OAAOA,KAAI,GAAG,6EAAiB,QAAQ,QAAQ,GAAG,CAAC,CAAC;AAC/E,UAAM,GAAG,WAAW,CAAC,YAAqB;AACxC,UAAI,CAAC,WAAW,OAAO,YAAY,SAAU;AAC7C,YAAM,QAAQ;AACd,UAAI,MAAM,UAAU,KAAM,QAAOC,IAAG,CAAC;AAAA,eAC5B,OAAO,MAAM,UAAU,SAAU,QAAOD,KAAI,GAAG,MAAM,KAAK,CAAC;AAAA,IACtE,CAAC;AAAA,EACH,CAAC;AACH;AAGO,SAAS,mBACd,SACA,MACA,SACuB;AACvB,SAAO,IAAI,QAAQ,CAAC,YAAY;AAC9B,UAAM,QAAQF,OAAM,SAAS,CAAC,GAAG,IAAI,GAAG,EAAE,KAAK,QAAQ,KAAK,OAAO,CAAC,UAAU,QAAQ,QAAQ,EAAE,CAAC;AACjG,UAAM,QAAQC,iBAAgB,EAAE,OAAO,MAAM,OAAQ,CAAC;AACtD,UAAM,GAAG,QAAQ,CAAC,SAAS;AACzB,UAAI;AAAE,gBAAQ,QAAQ,KAAK,MAAM,IAAI,CAAC;AAAA,MAAG,QAAQ;AAAA,MAAmD;AAAA,IACtG,CAAC;AACD,UAAM,GAAG,SAAS,CAAC,UAAU,QAAQC,KAAI,GAAG,sDAAmB,MAAM,OAAO,EAAE,CAAC,CAAC;AAChF,UAAM,GAAG,SAAS,CAAC,MAAM,WAAW;AAClC,YAAM,MAAM;AACZ,cAAQ,SAAS,IAAIC,IAAG,IAAID,KAAI,GAAG,yCAAgB,UAAU,QAAQ,SAAS,GAAG,CAAC;AAAA,IACpF,CAAC;AAAA,EACH,CAAC;AACH;;;AC9DA,SAAS,SAAAE,cAAa;AACtB,SAAS,OAAAC,MAAK,MAAAC,WAAuB;AA0B9B,SAAS,WACd,SACA,OAA0B,CAAC,GAC3B,UAA8B,CAAC,GACR;AACvB,QAAM,QAAQF,OAAM,SAAS,CAAC,GAAG,IAAI,GAAG;AAAA,IACtC,KAAK,QAAQ,OAAO,QAAQ,IAAI;AAAA,IAChC,KAAK,QAAQ,MAAM,EAAE,GAAG,QAAQ,KAAK,GAAG,QAAQ,IAAI,IAAI,QAAQ;AAAA,IAChE,OAAO,QAAQ,SAAS;AAAA,IACxB,OAAO,QAAQ,SAAS;AAAA,EAC1B,CAAC;AACD,QAAM,QAAQ,gBAAgB,SAAS,IAAI;AAE3C,SAAO,IAAI,QAAQ,CAAC,YAAY;AAC9B,UAAM,GAAG,SAAS,CAAC,UAAU;AAC3B,cAAQC,KAAI,GAAG,gBAAM,KAAK,kBAAQ,MAAM,OAAO,EAAE,CAAC;AAAA,IACpD,CAAC;AACD,UAAM,GAAG,SAAS,CAAC,MAAM,WAAW;AAClC,UAAI,SAAS,GAAG;AACd,gBAAQC,IAAG,CAAC;AACZ;AAAA,MACF;AACA,cAAQD,KAAI,QAAQ,GAAG,gBAAM,KAAK,gBAAM,eAAe,MAAM,CAAC,EAAE,CAAC;AAAA,IACnE,CAAC;AAAA,EACH,CAAC;AACH;AAKO,SAAS,eACd,SACA,OAA0B,CAAC,GAC3B,UAAkC,CAAC,GACF;AACjC,QAAM,QAAQD,OAAM,SAAS,CAAC,GAAG,IAAI,GAAG;AAAA,IACtC,KAAK,QAAQ,OAAO,QAAQ,IAAI;AAAA,IAChC,KAAK,QAAQ,MAAM,EAAE,GAAG,QAAQ,KAAK,GAAG,QAAQ,IAAI,IAAI,QAAQ;AAAA,IAChE,OAAO,QAAQ,SAAS;AAAA,IACxB,OAAO,CAAC,UAAU,QAAQ,MAAM;AAAA,EAClC,CAAC;AACD,QAAM,QAAQ,gBAAgB,SAAS,IAAI;AAC3C,MAAI,SAAS;AACb,MAAI,SAAS;AAEb,QAAM,QAAQ,GAAG,QAAQ,CAAC,UAAkB;AAC1C,cAAU,MAAM,SAAS;AAAA,EAC3B,CAAC;AACD,QAAM,QAAQ,GAAG,QAAQ,CAAC,UAAkB;AAC1C,cAAU,MAAM,SAAS;AAAA,EAC3B,CAAC;AAED,SAAO,IAAI,QAAQ,CAAC,YAAY;AAC9B,UAAM,GAAG,SAAS,CAAC,UAAU;AAC3B,cAAQC,KAAI,GAAG,gBAAM,KAAK,kBAAQ,MAAM,OAAO,EAAE,CAAC;AAAA,IACpD,CAAC;AACD,UAAM,GAAG,SAAS,CAAC,MAAM,WAAW;AAClC,UAAI,SAAS,GAAG;AACd,gBAAQC,IAAG,EAAE,QAAQ,OAAO,CAAC,CAAC;AAC9B;AAAA,MACF;AACA,YAAM,aAAa,OAAO,KAAK,IAAI;AAAA,EAAK,OAAO,KAAK,CAAC,KAAK;AAC1D;AAAA,QACED;AAAA,UACE,QAAQ;AAAA,UACR,gBAAM,KAAK,gBAAM,eAAe,MAAM,CAAC,GAAG,UAAU;AAAA,QACtD;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACH,CAAC;AACH;AAKO,SAAS,QAAQ,KAAoC;AAC1D,QAAM,CAAC,SAAS,IAAI,IAClB,QAAQ,aAAa,WACjB,CAAC,QAAQ,CAAC,GAAG,CAAC,IACd,QAAQ,aAAa,UACnB,CAAC,OAAO,CAAC,MAAM,SAAS,IAAI,GAAG,CAAC,IAChC,CAAC,YAAY,CAAC,GAAG,CAAC;AAC1B,SAAO,WAAW,SAAS,MAAM,EAAE,OAAO,SAAS,CAAC;AACtD;AAEA,SAAS,gBAAgB,SAAiB,MAAiC;AACzE,SAAO,CAAC,SAAS,GAAG,IAAI,EAAE,KAAK,GAAG,EAAE,KAAK;AAC3C;AAEA,SAAS,eAAe,QAAuC;AAC7D,SAAO,SAAS,aAAa,MAAM,KAAK;AAC1C;;;ACtHA,SAAS,SAAAE,cAAgC;AACzC,SAAS,iBAAiB;AAC1B,SAAS,OAAAC,MAAK,MAAAC,WAAuB;AAcrC,IAAM,oBAAoB,CAAC,UAAU,WAAW,QAAQ;AACxD,IAAM,uBAAuB;AAGtB,SAAS,sBACd,SACA,MACA,UAAsC,CAAC,GACK;AAC5C,SAAO,IAAI,QAAQ,CAAC,YAAY;AAC9B,QAAI;AACJ,QAAI;AACF,cAAQF,OAAM,SAAS,CAAC,GAAG,IAAI,GAAG;AAAA,QAChC,KAAK,QAAQ;AAAA,QACb,KAAK,QAAQ,MAAM,EAAE,GAAG,QAAQ,KAAK,GAAG,QAAQ,IAAI,IAAI,QAAQ;AAAA,QAChE,OAAO;AAAA,QACP,OAAO,CAAC,QAAQ,UAAU,SAAY,WAAW,QAAQ,WAAW,SAAS;AAAA,MAC/E,CAAC;AAAA,IACH,SAAS,OAAO;AACd,cAAQC,KAAI,GAAG,6CAAU,kBAAkB,KAAK,CAAC,EAAE,CAAC;AACpD;AAAA,IACF;AAEA,QAAI;AACJ,QAAI,cAAc;AAClB,QAAI,SAAS;AACb,QAAI;AACJ,UAAM,YAAY,MAAe,MAAM,QAAQ,UAAa,MAAM,aAAa,QAAQ,MAAM,eAAe;AAC5G,UAAM,OAAO,CAAC,SAAyB,cAAoB;AACzD,UAAI,UAAU,CAAC,UAAU,EAAG;AAC5B,UAAI,CAAC,WAAW;AAEd,oBAAY,WAAW,MAAM;AAC3B,cAAI,UAAU,EAAG,OAAM,KAAK,SAAS;AAAA,QACvC,GAAG,oBAAoB;AAAA,MACzB;AACA,YAAM,KAAK,MAAM;AAAA,IACnB;AACA,UAAM,OAAO,CAAC,YAA0B;AACtC,kBAAYA,KAAI,GAAG,OAAO;AAC1B,WAAK;AAAA,IACP;AACA,UAAM,iBAAiB,kBAAkB,IAAI,CAAC,WAAW;AACvD,YAAM,UAAU,MAAY,KAAK,MAAM;AACvC,cAAQ,GAAG,QAAQ,OAAO;AAC1B,aAAO,EAAE,QAAQ,QAAQ;AAAA,IAC3B,CAAC;AAED,UAAM,GAAG,SAAS,CAAC,UAAU,KAAK,6CAAU,kBAAkB,KAAK,CAAC,EAAE,CAAC;AACvE,UAAM,GAAG,QAAQ,MAAM,aAAa,SAAS,CAAC;AAC9C,UAAM,GAAG,SAAS,CAAC,MAAM,WAAW;AAClC,eAAS;AACT,mBAAa,SAAS;AACtB,iBAAW,EAAE,QAAQ,cAAc,QAAQ,KAAK,eAAgB,SAAQ,IAAI,cAAc,OAAO;AACjG,YAAM,WAAW,SAAS,SAAS,MAAM,UAAU,QAAQ,MAAM,IAAI;AAErE,UAAI,CAAC,WAAW,eAAe,aAAa,EAAG,WAAUA,KAAI,GAAG,2DAAwB;AACxF,cAAQ,WAAWC,IAAG,EAAE,SAAS,CAAC,CAAC;AAAA,IACrC,CAAC;AACD,UAAM,OAAO,GAAG,SAAS,CAAC,UAAiC;AACzD,UAAI,MAAM,SAAS,QAAS,eAAc;AAAA,UACrC,MAAK,oDAAiB,kBAAkB,KAAK,CAAC,EAAE;AAAA,IACvD,CAAC;AACD,QAAI,QAAQ,UAAU,QAAW;AAC/B,UAAI;AAAE,cAAM,OAAO,IAAI,QAAQ,KAAK;AAAA,MAAG,SAChC,OAAO;AAAE,aAAK,oDAAiB,kBAAkB,KAAK,CAAC,EAAE;AAAA,MAAG;AAAA,IACrE;AAAA,EACF,CAAC;AACH;AAGA,SAAS,kBAAkB,OAAwB;AACjD,MAAI,CAAC,SAAS,OAAO,UAAU,YAAY,EAAE,UAAU,OAAQ,QAAO;AACtE,SAAO,OAAO,MAAM,SAAS,YAAY,oBAAoB,KAAK,MAAM,IAAI,IAAI,KAAK,MAAM,IAAI,MAAM;AACvG;;;ACtFA,SAAS,OAAAC,MAAK,MAAAC,WAAuB;;;ACJrC,SAAS,SAAAC,cAAa;AACtB,SAAS,OAAAC,MAAK,MAAAC,WAAuB;AAG9B,SAAS,oBACd,MACA,SAC6D;AAC7D,MAAI,QAAQ,aAAa,QAAS,QAAO,QAAQ,QAAQD,KAAI,GAAG,+DAA4B,CAAC;AAC7F,SAAO,IAAI,QAAQ,CAAC,YAAY;AAC9B,UAAM,QAAQD,OAAM,SAAS,CAAC,QAAQ,UAAU,GAAG,IAAI,GAAG;AAAA,MACxD,KAAK,QAAQ;AAAA,MAAK,UAAU;AAAA,MAAM,OAAO,CAAC,UAAU,UAAU,UAAU,KAAK;AAAA,MAAG,OAAO;AAAA,IACzF,CAAC;AACD,QAAI,UAAU;AACd,UAAM,SAAS,CAAC,WAAqE;AACnF,UAAI,QAAS;AACb,gBAAU;AACV,mBAAa,KAAK;AAClB,UAAI,MAAM,UAAW,OAAM,WAAW;AACtC,YAAM,MAAM;AACZ,cAAQ,MAAM;AAAA,IAChB;AACA,UAAM,QAAQ,WAAW,MAAM,OAAOC,KAAI,GAAG,6MAAwC,CAAC,GAAG,QAAQ,kBAAkB,IAAM;AACzH,UAAM,KAAK,SAAS,CAAC,UAAU,OAAOA,KAAI,GAAG,yCAAW,MAAM,OAAO,EAAE,CAAC,CAAC;AACzE,UAAM,KAAK,QAAQ,CAAC,MAAM,WAAW,OAAOA,KAAI,GAAG,6EAAiB,UAAU,QAAQ,SAAS,GAAG,CAAC,CAAC;AACpG,UAAM,GAAG,WAAW,CAAC,YAAqB;AACxC,UAAI,CAAC,WAAW,OAAO,YAAY,SAAU;AAC7C,YAAM,QAAQ;AACd,UAAI,MAAM,UAAU,QAAQ,MAAM,SAAS,OAAW,QAAOC,IAAG,EAAE,KAAK,MAAM,KAAM,MAAM,MAAM,KAAK,CAAC,CAAC;AAAA,eAC7F,OAAO,MAAM,UAAU,SAAU,QAAOD,KAAI,GAAG,MAAM,KAAK,CAAC;AAAA,IACtE,CAAC;AAAA,EACH,CAAC;AACH;","names":["spawn","createInterface","err","ok","spawn","err","ok","spawn","err","ok","err","ok","spawn","err","ok"]}
|