@brierb/brier-cli 0.0.13 → 0.0.14
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/dist/core/runtimes.js
CHANGED
|
@@ -22,15 +22,25 @@ export const RUNTIME_COMMANDS = Object.fromEntries(RUNTIME_REGISTRY.map((r) => [
|
|
|
22
22
|
* AI runtime 单次(非交互)执行参数模板:命令前缀 flags,后面紧跟 prompt。
|
|
23
23
|
* 服务端 task-start 携带 prompt 时,CLI 用它拼出
|
|
24
24
|
* `spawn(<command>, [...flags, prompt])`;未列出的 runtime 按裸参数执行。
|
|
25
|
+
*
|
|
26
|
+
* OpenCode 使用 `--format json` 输出结构化事件(含 sessionID,供跨轮续接);
|
|
27
|
+
* 展示层会从中提取文本事件,JSON 事件本身不被当作最终正文。
|
|
25
28
|
*/
|
|
26
29
|
export const RUNTIME_PROMPT_FLAGS = {
|
|
27
|
-
OpenCode: ['run'],
|
|
30
|
+
OpenCode: ['run', '--format', 'json'],
|
|
28
31
|
'Claude Code': ['-p'],
|
|
29
32
|
'Codex CLI': ['exec'],
|
|
30
33
|
'Gemini CLI': ['-p'],
|
|
31
34
|
Aider: ['--message'],
|
|
32
35
|
Goose: ['run'],
|
|
33
36
|
};
|
|
37
|
+
/**
|
|
38
|
+
* 各 runtime 续接上一会话所需的参数名(值与 resumeSessionId 拼接)。
|
|
39
|
+
* 仅支持原生 resume/session 续接的 runtime 需要登记。
|
|
40
|
+
*/
|
|
41
|
+
export const RUNTIME_RESUME_FLAGS = {
|
|
42
|
+
OpenCode: ['--session'],
|
|
43
|
+
};
|
|
34
44
|
// macOS 自带磁盘分区工具 gpt(8) 位于 /usr/sbin/gpt,命中系统目录视为未安装。
|
|
35
45
|
const SYSTEM_SBIN_RE = /^\/(usr\/)?sbin\//;
|
|
36
46
|
const isExecutable = (file) => {
|
|
@@ -3,7 +3,7 @@ import { chmodSync } from 'node:fs';
|
|
|
3
3
|
import { dirname, join } from 'node:path';
|
|
4
4
|
import { createRequire } from 'node:module';
|
|
5
5
|
import pty from 'node-pty';
|
|
6
|
-
import { logger, resolveRuntimeExecutable, RUNTIME_PROMPT_FLAGS } from '../core/index.js';
|
|
6
|
+
import { logger, resolveRuntimeExecutable, RUNTIME_PROMPT_FLAGS, RUNTIME_RESUME_FLAGS, } from '../core/index.js';
|
|
7
7
|
const require = createRequire(import.meta.url);
|
|
8
8
|
/**
|
|
9
9
|
* 修复 node-pty 的 darwin spawn-helper 可执行权限。
|
|
@@ -31,6 +31,8 @@ const KILL_GRACE_MS = 2_000;
|
|
|
31
31
|
/** dispose 整体等待上限 */
|
|
32
32
|
const DISPOSE_TIMEOUT_MS = 2_000;
|
|
33
33
|
const DISPOSE_POLL_MS = 100;
|
|
34
|
+
/** 交互 CLI 启动后到可接收输入的就绪等待(全屏 TUI 初始化较慢,如 opencode) */
|
|
35
|
+
const PTY_STARTUP_DELAY_MS = 1_200;
|
|
34
36
|
export const createTaskExecutor = (callbacks) => {
|
|
35
37
|
/** pipe 模式子进程(ChildProcess,原有实现) */
|
|
36
38
|
const pipeProcs = new Map();
|
|
@@ -83,13 +85,19 @@ export const createTaskExecutor = (callbacks) => {
|
|
|
83
85
|
};
|
|
84
86
|
/**
|
|
85
87
|
* 拼执行参数:
|
|
86
|
-
* - prompt 模式(AI runtime):命令前缀 flags + prompt 原文
|
|
88
|
+
* - prompt 模式(AI runtime):命令前缀 flags + 续接参数(可选) + prompt 原文
|
|
87
89
|
* - 命令模式:透传服务端给的 args
|
|
88
90
|
*/
|
|
89
91
|
const buildArgs = (task) => {
|
|
90
92
|
if (task.prompt) {
|
|
91
|
-
const
|
|
92
|
-
|
|
93
|
+
const args = [...(RUNTIME_PROMPT_FLAGS[task.runtime] ?? [])];
|
|
94
|
+
if (task.resumeSessionId) {
|
|
95
|
+
const flag = RUNTIME_RESUME_FLAGS[task.runtime];
|
|
96
|
+
if (flag)
|
|
97
|
+
args.push(...flag, task.resumeSessionId);
|
|
98
|
+
}
|
|
99
|
+
args.push(task.prompt);
|
|
100
|
+
return args;
|
|
93
101
|
}
|
|
94
102
|
return task.args ?? [];
|
|
95
103
|
};
|
|
@@ -164,9 +172,25 @@ export const createTaskExecutor = (callbacks) => {
|
|
|
164
172
|
}
|
|
165
173
|
ptyProcs.set(task.taskId, handle);
|
|
166
174
|
logger.info(`Task ${task.taskId} started in pty mode: ${cmd} ${args.join(' ')}`, task.runtime);
|
|
167
|
-
// prompt 作为首条会话消息敲入(补回车触发提交);无 prompt(command
|
|
175
|
+
// prompt 作为首条会话消息敲入(补回车触发提交);无 prompt(command 模式)不注入。
|
|
176
|
+
// 时序:交互 CLI(尤其全屏 TUI,如 opencode)需要时间完成初始化,过早写入会被丢弃,
|
|
177
|
+
// 导致会话一直停在“等待输入”态;延迟到终端就绪后再注入。
|
|
168
178
|
if (initialInput) {
|
|
169
|
-
|
|
179
|
+
const pendingWrite = setTimeout(() => {
|
|
180
|
+
try {
|
|
181
|
+
if (ptyProcs.get(task.taskId) === handle) {
|
|
182
|
+
handle.write(initialInput);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
catch {
|
|
186
|
+
// 会话已结束等情况:忽略注入失败
|
|
187
|
+
}
|
|
188
|
+
}, PTY_STARTUP_DELAY_MS);
|
|
189
|
+
// 会话先于注入结束时取消定时器,避免向已死终端写入
|
|
190
|
+
const clearOnExit = () => {
|
|
191
|
+
clearTimeout(pendingWrite);
|
|
192
|
+
};
|
|
193
|
+
handle.onExit(clearOnExit);
|
|
170
194
|
}
|
|
171
195
|
handle.onData((data) => {
|
|
172
196
|
// pty 只有一路输出(合并 stdout/stderr 的终端字节流),统一按 stdout 上行;
|
package/package.json
CHANGED
package/types/core/runtimes.d.ts
CHANGED
|
@@ -10,8 +10,16 @@ export declare const RUNTIME_COMMANDS: Record<string, string>;
|
|
|
10
10
|
* AI runtime 单次(非交互)执行参数模板:命令前缀 flags,后面紧跟 prompt。
|
|
11
11
|
* 服务端 task-start 携带 prompt 时,CLI 用它拼出
|
|
12
12
|
* `spawn(<command>, [...flags, prompt])`;未列出的 runtime 按裸参数执行。
|
|
13
|
+
*
|
|
14
|
+
* OpenCode 使用 `--format json` 输出结构化事件(含 sessionID,供跨轮续接);
|
|
15
|
+
* 展示层会从中提取文本事件,JSON 事件本身不被当作最终正文。
|
|
13
16
|
*/
|
|
14
17
|
export declare const RUNTIME_PROMPT_FLAGS: Record<string, readonly string[]>;
|
|
18
|
+
/**
|
|
19
|
+
* 各 runtime 续接上一会话所需的参数名(值与 resumeSessionId 拼接)。
|
|
20
|
+
* 仅支持原生 resume/session 续接的 runtime 需要登记。
|
|
21
|
+
*/
|
|
22
|
+
export declare const RUNTIME_RESUME_FLAGS: Record<string, readonly [string]>;
|
|
15
23
|
/**
|
|
16
24
|
* 解析 runtime 的可执行文件**绝对路径**:
|
|
17
25
|
* 1. PATH 中查找(排除系统目录误报,如 /usr/sbin/gpt)
|