maoda-commander-tt 0.0.62 → 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 CHANGED
@@ -60,7 +60,7 @@ tt-cli/
60
60
  │ ├── modules/ # 领域逻辑:不依赖 commander,返回 Result<T>
61
61
  │ │ ├── ark/ git/ pippit/ static-deploy/ video-generation/ xyq/ xyq-tasks/
62
62
  │ ├── bedrock/ # 与业务无关的基础设施
63
- │ │ ├── config/ cross-app-settings/ download/ pkg/ process/ uuid/
63
+ │ │ ├── cross-app-settings/ download/ process/ uuid/
64
64
  │ └── constants/ # 兼容性常量(已弃用的内置回退值)
65
65
  ├── scripts/release.mjs # 发布脚本
66
66
  ├── ops/static-deploy/ # 服务器侧部署说明
@@ -106,21 +106,27 @@ tt tool get-config example.key
106
106
  保留其他配置。无效文件或检测到写入冲突时失败并保留原内容。成功返回 key、configured、
107
107
  revision,不回显 value。
108
108
 
109
+ ## 抖音视频解析
110
+
111
+ `tt pippit douyin-video '<抖音链接或完整分享文案>'` 返回解析后的视频地址。
112
+ 鉴权与 XYQ 共用配置中的 `sessionid_pippitcn_web` Cookie,并自动获取 UID;
113
+ 只需提供有效 Cookie,无需另外配置 token、UID 或 workspace。
114
+
109
115
  ## 后台启动 Codex
110
116
 
111
- `tt codex`、`tt ai run` 和本地图片 worker 共用可执行文件查找顺序:
117
+ `tt codex`、`tt codex-exec` 和本地图片 worker 共用可执行文件查找顺序:
112
118
  `/Applications/ChatGPT.app/Contents/Resources/codex` →
113
119
  `/Applications/Codex.app/Contents/Resources/codex` → PATH 中的 `codex`。
114
120
  App 内路径不存在、不是文件或不可执行时跳到下一项;启动后的执行失败不重试下一项。
115
121
 
116
122
  ```bash
117
123
  tt codex "我的具体 prompt"
118
- tt codex -C /path/to/repo -m gpt-5.6-sol -r ultra "我的具体 prompt"
124
+ tt codex -C /path/to/repo -m gpt-6-astra -r high "我的具体 prompt"
119
125
  tt codex --help
120
126
  ```
121
127
 
122
- 默认工作目录 `/Users/bytedance/work/autogen`,默认模型 `gpt-6-astra`,默认推理强度
123
- `high`。模型可选 `gpt-6-astra`、`gpt-5.6-sol`;推理强度可选
128
+ 默认工作目录 `/Users/bytedance/work/autogen`,默认模型 `gpt-6-sol`,默认推理强度
129
+ `ultra`。模型可选 `gpt-6-sol`、`gpt-6-astra`、`gpt-5.6-sol`;推理强度可选
124
130
  `low`、`medium`、`high`、`xhigh`、`max`、`ultra`。
125
131
 
126
132
  macOS/Linux 下通过 `nohup` 启动后台 worker,由 worker 运行 `codex app-server`,
@@ -140,27 +146,27 @@ App 可发现 app-server 会话,但 App 侧边栏是否按项目分组还取
140
146
  项目归属同步。服务端绑定 projectId 不等同于旧版 App 侧边栏已同步;tt 不修改 App
141
147
  私有状态文件或数据库来强制分组。
142
148
 
143
- ## 后台启动 Traex
149
+ ## 同步执行 Codex
144
150
 
145
151
  ```bash
146
- tt traex "我的具体 prompt"
147
- tt traex -C /path/to/repo -m gpt-6-astra -r high "我的具体 prompt"
148
- tt traex --help
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
149
155
  ```
150
156
 
151
- 默认目录 `/Users/bytedance/work/autogen`,默认模型 `gpt-5.6-sol`,默认推理强度
152
- `xhigh`。模型可选 `gpt-5.6-sol`、`gpt-6-astra`;推理强度按 Traex
153
- 支持范围提供 `low`、`medium`、`high`、`xhigh`。需要本机已安装并登录 `traex`。
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
+ 相对路径基于调用目录解析,不存在的目录直接报错。
154
163
 
155
- 与 `tt codex` 一样,通过 `nohup` 后台 worker 运行 `traex app-server`,固定
156
- `danger-full-access` 和 `never`,收到 `turn/start` 确认后立即返回一行 JSON。
157
- 保留本机 Traex 配置、登录态及会话持久化,终端 IO 丢弃,不生成任务日志,
158
- 不提供任务跟踪。后台 worker 保持连接到本轮结束后退出。
159
-
160
- 返回 `status: "launched"`、worker `pid`、`threadId`、`turnId`、`cwd`、`model`、
161
- `reasoning` 和 `projectId: null`。Traex 暂不支持项目接口,因此仅传工作目录,
162
- 不调用 `project/list` 或传入 `thread/start.projectId`。App 显示及项目分组可能
163
- 延迟,`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 或进程崩溃无法保证临时目录清理。
164
170
 
165
171
  ## 发布到 npm
166
172
 
@@ -279,20 +285,17 @@ tt deploy --delete demo
279
285
 
280
286
  ### 本机配置与接口鉴权
281
287
 
282
- 在 `~/.config/maoda-commander-tt/maoda-commander-tt.json` 的已有配置中增加
283
- `staticDeploy` 字段,保留其他字段。将示例 token 替换为已配置到服务器的固定 token:
288
+ 部署与 `tt tool get-config` / `tt tool set-config` 使用同一份跨应用设置,默认文件为
289
+ `~/.cli_settings/settings.json`;环境变量 `TT_CROSS_APP_SETTINGS_FILE` 可覆盖路径。
290
+ 配置以下两个独立的字符串键,点号是键名的一部分,不使用嵌套的 `staticDeploy` 对象:
284
291
 
285
- ```json
286
- {
287
- "staticDeploy": {
288
- "apiUrl": "https://www.imaoda.com/api/tt",
289
- "token": "<你的固定部署 token>"
290
- }
291
- }
292
- ```
292
+ | 键 | 值 |
293
+ | --- | --- |
294
+ | `staticDeploy.apiUrl` | `https://www.imaoda.com/api/tt` |
295
+ | `staticDeploy.token` | 与服务器一致的固定部署 token |
293
296
 
294
- `apiUrl` 指向部署 API,命令自动为请求添加 `Authorization: Bearer <token>`。
295
- 固定 token 只保存在本机配置中,不打包到 npm,也不放进命令行参数、公开目录或
297
+ `staticDeploy.apiUrl` 指向部署 API,命令自动为请求添加 `Authorization: Bearer <token>`。
298
+ 固定 token 只保存在跨应用设置中,不打包到 npm,也不放进部署命令参数、公开目录或
296
299
  返回结果。部署不需要本机 SSH 权限;换电脑时配置同一 API 地址及 token 即可。
297
300
  本机需要 Node.js 22.13.0 或更高版本和 `tar`。API 只接受 HTTPS(本机测试的
298
301
  loopback HTTP 除外),客户端不跟随重定向,以免将 token 发送到其他地址。
@@ -300,7 +303,7 @@ loopback HTTP 除外),客户端不跟随重定向,以免将 token 发送
300
303
  服务器使用 `TT_DEPLOY_TOKEN` 验证部署、删除和目录查询请求;`TT_DEPLOY_ROOT` 和
301
304
  `TT_DEPLOY_BASE_URL` 决定落盘根目录和公开 URL,不由调用端任意指定。
302
305
  当前限制为每次归档 50 MiB、最多 2 个并发操作。收到 token 的人可以部署、覆盖或删除
303
- 这个根目录下的项目;需要更换时同时更新服务器和本机配置。
306
+ 这个根目录下的项目;需要更换时同时更新服务器和跨应用设置。
304
307
 
305
308
  服务器需要预先配置 API 和 nginx 路由,参见 [部署运维说明](ops/static-deploy/README.md)。
306
309
  当前服务器在静态入口上
@@ -374,15 +377,6 @@ loopback HTTP 除外),客户端不跟随重定向,以免将 token 发送
374
377
  若公开目标已删除,但目录清单刷新或私有暂存清理失败,命令返回错误和非零退出码,
375
378
  同时保留 `data.state: "deleted"`;AI 应据此排查后续步骤,不能把它理解为目标仍在。
376
379
 
377
- ## Shell 快捷方式
378
-
379
- ```bash
380
- # 在 ~/work/web-proxy 中先执行 w2 start,成功后执行 pnpm gateway
381
- tt sc w2
382
- ```
383
-
384
- 命令日志直接输出到当前终端,gateway 在前台运行。
385
-
386
380
  ## AI 图片生成
387
381
 
388
382
  图片、音频与视频统一采用异步提交:默认返回 `taskId`,`status` 单次查询,
@@ -211,16 +211,87 @@ function describeSignal(signal) {
211
211
  return signal ? `, signal: ${signal}` : "";
212
212
  }
213
213
 
214
- // src/bedrock/process/detached-process.ts
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-worker.ts
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(err5(1, "\u540E\u53F0 nohup \u542F\u52A8\u4EC5\u652F\u6301 macOS/Linux"));
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 = spawn4("nohup", [process.execPath, ...args], {
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(err5(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);
239
- child.once("error", (error) => finish(err5(1, `\u540E\u53F0\u542F\u52A8\u5931\u8D25: ${error.message}`)));
240
- child.once("exit", (code, signal) => finish(err5(1, `\u540E\u53F0\u8FDB\u7A0B\u5728\u63D0\u4EA4\u786E\u8BA4\u524D\u9000\u51FA (${signal ?? code ?? "unknown"})`)));
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(ok5({ pid: child.pid, data: reply.data }));
245
- else if (typeof reply.error === "string") finish(err5(1, reply.error));
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-VCLWIPCG.js.map
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":"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","names":["spawn","createInterface","err","ok","spawn","err","ok","spawn","err","ok","err","ok","spawn","err","ok"]}