@windsland52/maafw-live 0.0.0-stage → 0.4.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/LICENSE +21 -0
- package/README.md +293 -2
- package/bin/maafw-live.mjs +25 -0
- package/docs/daemon-protocol.md +121 -0
- package/docs/keyframe-retention-contract-v0.md +225 -0
- package/docs/session-unify-v0.md +115 -0
- package/lib/client/daemon.js +276 -0
- package/lib/commands/annotate.js +179 -0
- package/lib/commands/calibrate.js +61 -0
- package/lib/commands/color.js +73 -0
- package/lib/commands/crop.js +228 -0
- package/lib/commands/dispatch.js +121 -0
- package/lib/commands/env.js +409 -0
- package/lib/commands/index.js +70 -0
- package/lib/commands/input.js +257 -0
- package/lib/commands/kf.js +167 -0
- package/lib/commands/probe.js +70 -0
- package/lib/commands/reco.js +440 -0
- package/lib/commands/repl.js +1501 -0
- package/lib/commands/roi-check.js +273 -0
- package/lib/commands/roi-compare.js +388 -0
- package/lib/commands/runtime.js +718 -0
- package/lib/commands/skill.js +169 -0
- package/lib/commands/timing.js +247 -0
- package/lib/commands/version.js +66 -0
- package/lib/daemon/framed.mjs +3680 -0
- package/lib/daemon/reco_child.mjs +287 -0
- package/lib/exec.js +96 -0
- package/lib/flags.js +44 -0
- package/lib/image.js +90 -0
- package/lib/index.js +143 -0
- package/lib/interface/hotkey.js +142 -0
- package/lib/interface/index.js +12 -0
- package/lib/interface/jsonc.js +95 -0
- package/lib/interface/load.js +397 -0
- package/lib/interface/override.js +287 -0
- package/lib/interface/plan.js +279 -0
- package/lib/option-args.js +29 -0
- package/lib/pkg.js +54 -0
- package/lib/protocol.js +94 -0
- package/lib/runtime/actions.js +225 -0
- package/lib/runtime/keyframes.js +73 -0
- package/lib/runtime/log-watch.js +160 -0
- package/lib/runtime/node-source.js +100 -0
- package/lib/runtime/ocr-model.js +45 -0
- package/lib/runtime/pi-env.js +34 -0
- package/lib/runtime/pretask.js +217 -0
- package/lib/runtime/prune.js +28 -0
- package/lib/runtime/receipts.js +57 -0
- package/lib/runtime/reco-args.js +38 -0
- package/lib/runtime/reco-verdict.js +82 -0
- package/lib/runtime/roi-compare.js +198 -0
- package/lib/runtime/session-forward.js +79 -0
- package/lib/runtime/session-ipc.js +471 -0
- package/lib/runtime/session.js +135 -0
- package/lib/runtime/signal-guard.js +35 -0
- package/lib/types/client/daemon.d.ts +86 -0
- package/lib/types/commands/annotate.d.ts +3 -0
- package/lib/types/commands/calibrate.d.ts +7 -0
- package/lib/types/commands/color.d.ts +9 -0
- package/lib/types/commands/crop.d.ts +3 -0
- package/lib/types/commands/dispatch.d.ts +22 -0
- package/lib/types/commands/env.d.ts +21 -0
- package/lib/types/commands/index.d.ts +13 -0
- package/lib/types/commands/input.d.ts +17 -0
- package/lib/types/commands/kf.d.ts +10 -0
- package/lib/types/commands/probe.d.ts +15 -0
- package/lib/types/commands/reco.d.ts +27 -0
- package/lib/types/commands/repl.d.ts +10 -0
- package/lib/types/commands/roi-check.d.ts +3 -0
- package/lib/types/commands/roi-compare.d.ts +3 -0
- package/lib/types/commands/runtime.d.ts +66 -0
- package/lib/types/commands/skill.d.ts +17 -0
- package/lib/types/commands/timing.d.ts +64 -0
- package/lib/types/commands/version.d.ts +3 -0
- package/lib/types/exec.d.ts +31 -0
- package/lib/types/flags.d.ts +62 -0
- package/lib/types/image.d.ts +27 -0
- package/lib/types/index.d.ts +1 -0
- package/lib/types/interface/hotkey.d.ts +36 -0
- package/lib/types/interface/index.d.ts +11 -0
- package/lib/types/interface/jsonc.d.ts +9 -0
- package/lib/types/interface/load.d.ts +190 -0
- package/lib/types/interface/override.d.ts +78 -0
- package/lib/types/interface/plan.d.ts +68 -0
- package/lib/types/option-args.d.ts +19 -0
- package/lib/types/pkg.d.ts +14 -0
- package/lib/types/protocol.d.ts +124 -0
- package/lib/types/runtime/actions.d.ts +248 -0
- package/lib/types/runtime/keyframes.d.ts +43 -0
- package/lib/types/runtime/log-watch.d.ts +28 -0
- package/lib/types/runtime/node-source.d.ts +25 -0
- package/lib/types/runtime/ocr-model.d.ts +8 -0
- package/lib/types/runtime/pi-env.d.ts +24 -0
- package/lib/types/runtime/pretask.d.ts +53 -0
- package/lib/types/runtime/prune.d.ts +4 -0
- package/lib/types/runtime/receipts.d.ts +7 -0
- package/lib/types/runtime/reco-args.d.ts +18 -0
- package/lib/types/runtime/reco-verdict.d.ts +50 -0
- package/lib/types/runtime/roi-compare.d.ts +117 -0
- package/lib/types/runtime/session-forward.d.ts +10 -0
- package/lib/types/runtime/session-ipc.d.ts +117 -0
- package/lib/types/runtime/session.d.ts +77 -0
- package/lib/types/runtime/signal-guard.d.ts +19 -0
- package/lib/types/update-check.d.ts +20 -0
- package/lib/types/usage.d.ts +3 -0
- package/lib/update-check.js +97 -0
- package/lib/usage.js +50 -0
- package/package.json +94 -4
- package/skills/README.md +51 -0
- package/skills/maafw-live/SKILL.md +293 -0
- package/skills/maafw-live/references/examples.md +238 -0
- package/skills/maafw-live/references/pitfalls.md +211 -0
- package/skills/maafw-live/references/workflows.md +164 -0
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
export interface InterfaceProblem {
|
|
2
|
+
message: string;
|
|
3
|
+
}
|
|
4
|
+
/** 控制器的显示声明;映射为 daemon connect 的 shortSide / longSide / rawSize。 */
|
|
5
|
+
export interface DisplayDecl {
|
|
6
|
+
shortSide?: number;
|
|
7
|
+
longSide?: number;
|
|
8
|
+
raw?: boolean;
|
|
9
|
+
expand?: [number, number];
|
|
10
|
+
}
|
|
11
|
+
export interface Win32Decl {
|
|
12
|
+
classRegex?: string;
|
|
13
|
+
windowRegex?: string;
|
|
14
|
+
screencap?: string;
|
|
15
|
+
mouse?: string;
|
|
16
|
+
keyboard?: string;
|
|
17
|
+
}
|
|
18
|
+
export interface GamepadDecl {
|
|
19
|
+
classRegex?: string;
|
|
20
|
+
windowRegex?: string;
|
|
21
|
+
gamepadType?: string;
|
|
22
|
+
screencap?: string;
|
|
23
|
+
}
|
|
24
|
+
/** MacOS 控制器声明(PI schema:`macos.{title_regex,screencap,input}`) */
|
|
25
|
+
export interface MacOSDecl {
|
|
26
|
+
titleRegex?: string;
|
|
27
|
+
screencap?: string;
|
|
28
|
+
input?: string;
|
|
29
|
+
}
|
|
30
|
+
export interface InterfaceController {
|
|
31
|
+
name: string;
|
|
32
|
+
/** Adb / Win32 / Gamepad / MacOS / PlayCover / Linux */
|
|
33
|
+
type: string;
|
|
34
|
+
display?: DisplayDecl;
|
|
35
|
+
win32?: Win32Decl;
|
|
36
|
+
gamepad?: GamepadDecl;
|
|
37
|
+
macos?: MacOSDecl;
|
|
38
|
+
/** v2.2.0:在 resource.path 之后追加加载的资源目录(相对 interface.json 所在目录) */
|
|
39
|
+
attachResourcePath: string[];
|
|
40
|
+
/** v2.3.0:控制器级配置项名单(override 链第三级) */
|
|
41
|
+
option?: string[];
|
|
42
|
+
/** Linux 控制器声明(PI schema):`use_win32_vk_code` 决定服务端按 Win32 VK 还是 evdev 解释键码;
|
|
43
|
+
* `screencap`/`input`/`pipewire_source` 等交给 daemon 按 maa-support-extension 规则组 config JSON */
|
|
44
|
+
linux?: {
|
|
45
|
+
useWin32VkCode?: boolean;
|
|
46
|
+
screencap?: string;
|
|
47
|
+
input?: string;
|
|
48
|
+
pipewireSource?: string;
|
|
49
|
+
};
|
|
50
|
+
/** `permission_required`(schema 字段):控制器需要管理员/root 权限运行——连接失败时的排查提示 */
|
|
51
|
+
permissionRequired?: boolean;
|
|
52
|
+
/** 原始条目(未裁剪):PI_CONTROLLER 要传"被选中那条的完整对象",不能按本工具用到的字段重建 */
|
|
53
|
+
raw?: unknown;
|
|
54
|
+
}
|
|
55
|
+
export interface InterfaceResource {
|
|
56
|
+
name: string;
|
|
57
|
+
/** 资源根目录(含 pipeline / image / model),相对 interface.json 所在目录,声明顺序即加载顺序 */
|
|
58
|
+
paths: string[];
|
|
59
|
+
/** 只对这些控制器生效;空数组 = 全部 */
|
|
60
|
+
controllers: string[];
|
|
61
|
+
/** v2.3.0:资源级配置项名单(override 链第二级) */
|
|
62
|
+
option?: string[];
|
|
63
|
+
/** v2.6.0:资源完整性校验值(仅加载 path 后的 MaaResourceGetHash;不匹配只警告不阻断) */
|
|
64
|
+
hash?: string;
|
|
65
|
+
/** 原始条目(未裁剪):PI_RESOURCE 要传"被选中那条的完整对象" */
|
|
66
|
+
raw?: unknown;
|
|
67
|
+
}
|
|
68
|
+
export interface InterfaceTask {
|
|
69
|
+
name: string;
|
|
70
|
+
/** pipeline 入口节点名;缺省时入口即任务名 */
|
|
71
|
+
entry?: string;
|
|
72
|
+
/** 只在这些控制器下可用(隐藏/禁用语义);空 = 全部 */
|
|
73
|
+
controller?: string[];
|
|
74
|
+
/** 只在这些资源下可用;空 = 全部 */
|
|
75
|
+
resource?: string[];
|
|
76
|
+
/** 配置项键名(按展示顺序);对应 InterfaceOption 字典的键 */
|
|
77
|
+
option?: string[];
|
|
78
|
+
/** task 级覆盖:键=节点名、值=字段覆盖(与 case 级同构,但**没有** `{字段名}` 替换语义) */
|
|
79
|
+
pipelineOverride?: Record<string, unknown>;
|
|
80
|
+
}
|
|
81
|
+
/** input option 的输入字段:`{name}` 占位引用的就是这里的 `name`。 */
|
|
82
|
+
export interface InputField {
|
|
83
|
+
name: string;
|
|
84
|
+
/** 初始值。协议只把它定义成"默认值",没说 Client 在无人输入时该不该拿它替换——本工具用。 */
|
|
85
|
+
default?: string;
|
|
86
|
+
/** 替换时的转型类型;枚举只有 `string` / `int` / `bool`(**没有** float) */
|
|
87
|
+
pipelineType?: string;
|
|
88
|
+
/** 正则校验(协议把它归给 Client 的输入校验职责) */
|
|
89
|
+
verify?: string;
|
|
90
|
+
/** `password`(v2.10.0):值为密码——不得把原文写进输出/日志,与 `default` 互斥(schema 已禁) */
|
|
91
|
+
password?: boolean;
|
|
92
|
+
}
|
|
93
|
+
/** hotkey option 的快捷键字段(v2.8.0):持久化值是人类可读字符串,如 `E` / `Ctrl+A`(末段为主键)。 */
|
|
94
|
+
export interface HotkeyField {
|
|
95
|
+
name: string;
|
|
96
|
+
default?: string;
|
|
97
|
+
}
|
|
98
|
+
/** option 字典条目:switch/select/checkbox 的 case 携带 pipeline_override。 */
|
|
99
|
+
export interface OptionCase {
|
|
100
|
+
name: string;
|
|
101
|
+
pipelineOverride?: Record<string, unknown>;
|
|
102
|
+
/** 选中该 case 后生效的子配置项 */
|
|
103
|
+
option?: string[];
|
|
104
|
+
}
|
|
105
|
+
export interface InterfaceOption {
|
|
106
|
+
name: string;
|
|
107
|
+
type: string;
|
|
108
|
+
cases: OptionCase[];
|
|
109
|
+
/**
|
|
110
|
+
* input / hotkey 专用的覆盖模板:**整个 option 一份**,值里含 `{字段名}` 占位。
|
|
111
|
+
*
|
|
112
|
+
* 与 `cases[].pipeline_override` 是协议里两处不同字段(select/switch/checkbox 走 case,
|
|
113
|
+
* input/hotkey 走这里)。只建模前者会永远读不到后者的模板。
|
|
114
|
+
*/
|
|
115
|
+
pipelineOverride?: Record<string, unknown>;
|
|
116
|
+
/** input 的输入字段(`inputs[]`) */
|
|
117
|
+
inputs?: InputField[];
|
|
118
|
+
/** hotkey 的快捷键字段(`hotkeys[]`,v2.8.0)——容器不是 inputs */
|
|
119
|
+
hotkeys?: HotkeyField[];
|
|
120
|
+
/** 初始选中:switch/select 单 case 名;checkbox 为 case 名数组 */
|
|
121
|
+
defaultCase?: string | string[];
|
|
122
|
+
/** 适用性过滤(v2.3.1:不满足的 option 不得产生 pipeline_override) */
|
|
123
|
+
controller?: string[];
|
|
124
|
+
resource?: string[];
|
|
125
|
+
/** checkbox 最少选中数(v2.10.1,默认 0) */
|
|
126
|
+
minCount?: number;
|
|
127
|
+
/** checkbox 最多选中数(v2.10.1,缺省 = 不限) */
|
|
128
|
+
maxCount?: number;
|
|
129
|
+
}
|
|
130
|
+
/** preset:任务与 option 取值的快照(v2.3.0),应用时覆盖 default_case。 */
|
|
131
|
+
export interface InterfacePreset {
|
|
132
|
+
name: string;
|
|
133
|
+
task: Array<{
|
|
134
|
+
name: string;
|
|
135
|
+
enabled?: boolean;
|
|
136
|
+
option?: Record<string, unknown>;
|
|
137
|
+
}>;
|
|
138
|
+
}
|
|
139
|
+
/** PI `agent` 声明:宿主侧子进程(如 uv run python agent/main.py),经 agent 协议注册 custom
|
|
140
|
+
* action / recognition。daemon 的 run 会 spawn 并桥接(bind_resource + sink 注册 + connect)。 */
|
|
141
|
+
export interface InterfaceAgent {
|
|
142
|
+
exec: string;
|
|
143
|
+
args: string[];
|
|
144
|
+
/**
|
|
145
|
+
* `identifier`(schema 字段):连接标识符——项目声明固定值时 daemon 把它原样交给
|
|
146
|
+
* `Client` 并追加为子进程末参(socket 同名)。注意语义是"上次断线可重连",不是
|
|
147
|
+
* "本次独占":固定 identifier 残留旧 socket 时 connect 会等满超时才败(上游已知坑)。
|
|
148
|
+
*/
|
|
149
|
+
identifier?: string;
|
|
150
|
+
}
|
|
151
|
+
/** PI `pretask` 声明(v2.7.0+):连接 Controller **之前**跑一次的子进程。 */
|
|
152
|
+
export interface InterfacePretask {
|
|
153
|
+
name?: string;
|
|
154
|
+
/** 必填:可执行程序(字符串,不是数组) */
|
|
155
|
+
exec: string;
|
|
156
|
+
/** 追加在 exec 之后的参数 */
|
|
157
|
+
args: string[];
|
|
158
|
+
/** 这些 option 的取值会被序列化成末位 JSON 参数(不参与 pipeline_override) */
|
|
159
|
+
option: string[];
|
|
160
|
+
/** v2.8.1 过滤:空/缺省 = 全部控制器适用 */
|
|
161
|
+
controller?: string[];
|
|
162
|
+
/** v2.8.1 过滤:空/缺省 = 全部资源适用 */
|
|
163
|
+
resource?: string[];
|
|
164
|
+
}
|
|
165
|
+
export interface LoadedInterface {
|
|
166
|
+
/** interface.json 绝对路径;未找到为 null */
|
|
167
|
+
file: string | null;
|
|
168
|
+
/** 所在目录——resource.path 与 attach_resource_path 的相对基准 */
|
|
169
|
+
dir: string | null;
|
|
170
|
+
version: number | null;
|
|
171
|
+
/** 顶层 `version` 字符串(**项目**版本,与 interface_version 无关):PI_VERSION 就是它 */
|
|
172
|
+
projectVersion: string | null;
|
|
173
|
+
name: string | null;
|
|
174
|
+
controllers: InterfaceController[];
|
|
175
|
+
resources: InterfaceResource[];
|
|
176
|
+
tasks: InterfaceTask[];
|
|
177
|
+
/** option 字典(主文件 + import 合并,后导入覆盖同名) */
|
|
178
|
+
options: Record<string, InterfaceOption>;
|
|
179
|
+
presets: InterfacePreset[];
|
|
180
|
+
/** 全局配置项键名(override 链最低级) */
|
|
181
|
+
globalOption: string[];
|
|
182
|
+
/** controller 启动前任务;连接前按声明序执行(非零退出即中止本次连接) */
|
|
183
|
+
pretask: InterfacePretask[];
|
|
184
|
+
/** agent 子进程声明;run 时由 daemon 桥接(spawn 子进程 + bind_resource + sink 注册 + connect,
|
|
185
|
+
* 见 framed.mjs setupAgents)。此处只负责读出 exec/args。 */
|
|
186
|
+
agents: InterfaceAgent[];
|
|
187
|
+
problems: InterfaceProblem[];
|
|
188
|
+
}
|
|
189
|
+
export declare function findInterfaceFile(dir: string): string | null;
|
|
190
|
+
export declare function loadInterface(dir: string): LoadedInterface;
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* pipeline_override 合成(PI v2)。
|
|
3
|
+
*
|
|
4
|
+
* **输出是分层数组,不是预合并对象**(上游语义,MaaFramework @8061d5b 已核):
|
|
5
|
+
* `RuntimeParam::Task.pipeline_override` 是 `json::array`,Configurator 把 task 基底放
|
|
6
|
+
* `[0]`、每个 option case / input 模板各占一层;`Context::override_pipeline` 逐层
|
|
7
|
+
* `parse_node(node, layer, default=上一层结果)`——缺失字段继承前值,`recognition`/`action`
|
|
8
|
+
* 的 `param` 在同 type 时按键继承。**边界在层间**:上一层把 recognition.type 换成别种,
|
|
9
|
+
* param 就不能继承上一层的字段。若我们客户端先摊平成一个对象,跨层"换 type"后的
|
|
10
|
+
* param 会被错认为"同 type 继承"——只有分层数组能保边界。
|
|
11
|
+
*
|
|
12
|
+
* 层序(与上游 Configurator 一致,后者覆盖先者):
|
|
13
|
+
* 1. **task 级 `pipeline_override`** 作 `[0]`(上游同样放数组首位)。
|
|
14
|
+
* 2. **option 四级链**:global_option → resource.option → controller.option → task.option,
|
|
15
|
+
* 每个生效 case / input 模板各占一层;进链前先按 option 的 controller/resource
|
|
16
|
+
* 条件过滤(v2.3.0 / v2.3.1)。checkbox 多选按 cases 声明序各成一层;
|
|
17
|
+
* 嵌套 option 紧跟其父 case 之后。
|
|
18
|
+
* 3. **input / hotkey 的模板替换**:`option.<键>.pipeline_override` 是**整个 option 一份**
|
|
19
|
+
* 的模板,里面有 `{字段名}` 占位——注意它与 `cases[].pipeline_override` 是协议里两处不同字段。
|
|
20
|
+
*
|
|
21
|
+
* 取值优先级(**协议未规定**,本工具自定):CLI `--option` > preset > `default_case`。
|
|
22
|
+
* preset 是把 GUI 用户选择搬进来的通道;CLI 表示"这一跑就按这个",所以压过 preset。
|
|
23
|
+
* input 字段还有第三档来源:`inputs[].default`(协议把它定义成默认值,本工具在无人输入时拿它替换)。
|
|
24
|
+
*/
|
|
25
|
+
import type { InterfaceOption, LoadedInterface } from './load.js';
|
|
26
|
+
export interface OverrideInput {
|
|
27
|
+
loaded: LoadedInterface;
|
|
28
|
+
controllerName: string | null;
|
|
29
|
+
resourceName: string | null;
|
|
30
|
+
taskName: string | null;
|
|
31
|
+
presetName?: string | null;
|
|
32
|
+
/** CLI 按次取值:option 键 → case 名(select/switch 单值;checkbox 数组) */
|
|
33
|
+
optionCases?: Record<string, string | string[]>;
|
|
34
|
+
/** CLI 按次取值:option 键 → { 字段名: 原文 }(input / hotkey 的字段映射) */
|
|
35
|
+
optionFields?: Record<string, Record<string, string>>;
|
|
36
|
+
}
|
|
37
|
+
export interface OverrideResult {
|
|
38
|
+
/** 分层 override:逐元素交给框架 `override_pipeline`,层间字段继承(数组尾=最高优先级) */
|
|
39
|
+
override: Record<string, unknown>[];
|
|
40
|
+
/** 需要人工注意的事项(选项无取值、preset 未找到等) */
|
|
41
|
+
warns: string[];
|
|
42
|
+
/** 人类可读的生效记录:option=值(级别) */
|
|
43
|
+
applied: string[];
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* 把调用方的覆盖(`--override`)追加到分层数组尾部 = 最高优先级。
|
|
47
|
+
* 对象 = 一层;数组 = 逐层(框架本来就接受数组,逐层继承,别在这里预合并)。
|
|
48
|
+
* 四级链、`run --override`、`timing --override` 共用这一个追加口——三处曾经各写一份,
|
|
49
|
+
* 代价是同一个参数在不同命令里表现不同。
|
|
50
|
+
*/
|
|
51
|
+
export declare function appendOverride(layers: Record<string, unknown>[], ov: Record<string, unknown> | Record<string, unknown>[] | undefined): void;
|
|
52
|
+
export interface OptionValueCtx {
|
|
53
|
+
/** 命中的 preset 任务条目(`preset[].task[]`):取值快照 */
|
|
54
|
+
presetTask?: {
|
|
55
|
+
option?: Record<string, unknown>;
|
|
56
|
+
};
|
|
57
|
+
/** CLI 按次取值:case 名 */
|
|
58
|
+
optionCases?: Record<string, string | string[]>;
|
|
59
|
+
/** CLI 按次取值:字段映射 */
|
|
60
|
+
optionFields?: Record<string, Record<string, string>>;
|
|
61
|
+
}
|
|
62
|
+
export type ResolvedOptionValue = {
|
|
63
|
+
kind: 'cases';
|
|
64
|
+
cases: string[];
|
|
65
|
+
via: string;
|
|
66
|
+
} | {
|
|
67
|
+
kind: 'fields';
|
|
68
|
+
fields: Record<string, string>;
|
|
69
|
+
via: string;
|
|
70
|
+
};
|
|
71
|
+
/**
|
|
72
|
+
* 解析一个 option 的当前取值(**唯一一份实现**):pipeline_override 合成与 pretask 的末位 JSON
|
|
73
|
+
* 都走这里,两边各写一套迟早会在"preset 的 input 值是对象还是字符串"上分叉。
|
|
74
|
+
*
|
|
75
|
+
* 优先级(协议未规定,本地约定):CLI > preset > 声明里的初始值(`default_case` / `inputs[].default`)。
|
|
76
|
+
*/
|
|
77
|
+
export declare function resolveOptionValue(o: InterfaceOption, ctx: OptionValueCtx): ResolvedOptionValue | null;
|
|
78
|
+
export declare function computePipelineOverride(input: OverrideInput): OverrideResult;
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import type { LoadedInterface } from './load.js';
|
|
2
|
+
/** daemon device_list 的条目:adb 的 id 是 address,win32 的 id 是 hwnd。 */
|
|
3
|
+
export interface DeviceLike {
|
|
4
|
+
kind?: string;
|
|
5
|
+
id?: string;
|
|
6
|
+
name?: string;
|
|
7
|
+
cls?: string;
|
|
8
|
+
}
|
|
9
|
+
export interface PlanOverrides {
|
|
10
|
+
controller?: string;
|
|
11
|
+
win32?: {
|
|
12
|
+
hwnd?: string | null;
|
|
13
|
+
};
|
|
14
|
+
gamepad?: {
|
|
15
|
+
hwnd?: string | null;
|
|
16
|
+
};
|
|
17
|
+
adb?: {
|
|
18
|
+
address?: string | null;
|
|
19
|
+
};
|
|
20
|
+
/** 手动 target(--target):playcover=<address>/<uuid>;macos=<窗口 id 或标题子串>;linux=<config JSON> */
|
|
21
|
+
manualTarget?: string | null;
|
|
22
|
+
}
|
|
23
|
+
export interface ControllerPlan {
|
|
24
|
+
ok: boolean;
|
|
25
|
+
code?: string;
|
|
26
|
+
error?: string;
|
|
27
|
+
controllerName: string | null;
|
|
28
|
+
/** 直接展开给 daemon 的 connect 参数 */
|
|
29
|
+
connect: Record<string, unknown>;
|
|
30
|
+
/** 失败时的候选设备,供调用方提示用户显式指定 */
|
|
31
|
+
candidates?: DeviceLike[];
|
|
32
|
+
notes?: string[];
|
|
33
|
+
}
|
|
34
|
+
export interface ResourcePlan {
|
|
35
|
+
paths: string[];
|
|
36
|
+
names: string[];
|
|
37
|
+
/** 本次实际选中的 resource 名(attach_resource_path 之外的来源条目) */
|
|
38
|
+
selected: string | null;
|
|
39
|
+
/** 需要人工注意的事项:多个条目都适用时说明选了哪一个(resource[] 是互斥单选,选了就只能用一个) */
|
|
40
|
+
notes?: string[];
|
|
41
|
+
/**
|
|
42
|
+
* v2.6.0 资源完整性校验:声明了 resource.hash 时给出。`pathDirs` 是**只有** `path[]`
|
|
43
|
+
* 的那段(不含 attach),`attachDirs` 是控制器 `attach_resource_path`——校验时机是
|
|
44
|
+
* 加载完 path 后、加载 attach 之前,两段必须分开才能只在边界处读 `res.hash`。
|
|
45
|
+
*/
|
|
46
|
+
hashCheck?: {
|
|
47
|
+
resourceName: string;
|
|
48
|
+
expected: string;
|
|
49
|
+
pathDirs: string[];
|
|
50
|
+
attachDirs: string[];
|
|
51
|
+
};
|
|
52
|
+
/** --resource 指到的值没匹配上任何条目,且不是磁盘上存在的目录:拒绝启动
|
|
53
|
+
* (打错一个字 = selected=null = 资源级 option/pretask 过滤全部跳过,比报错更贵)。 */
|
|
54
|
+
error?: string;
|
|
55
|
+
}
|
|
56
|
+
export declare function planController(loaded: LoadedInterface, overrides: PlanOverrides, devices: DeviceLike[]): ControllerPlan;
|
|
57
|
+
/**
|
|
58
|
+
* 解析资源路径:resource[] 是互斥单选(Client 语义)——不传 override 时取第一个适用于
|
|
59
|
+
* 所选控制器的条目,条目自身多路径按声明顺序叠加(如"B 服"= base + bilibili);
|
|
60
|
+
* attach_resource_path 在选中控制器后追加。override(--resource)先按资源名匹配,
|
|
61
|
+
* 匹配不上再按文件系统路径解释(原有行为)。
|
|
62
|
+
*
|
|
63
|
+
* 有多个条目都适用时,选中的那个与备选一起进 notes——"取第一个"是语义,但静默取第一个
|
|
64
|
+
* 会让用错资源包的人查不出原因。
|
|
65
|
+
*/
|
|
66
|
+
export declare function resolveResourcePaths(loaded: LoadedInterface, controllerName?: string, override?: string,
|
|
67
|
+
/** `--resource` 当目录路径时的解析基准(CLI 的 ctx.cwd;缺省 = process.cwd()) */
|
|
68
|
+
cwd?: string): ResourcePlan;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `run --option` 的 argv 解析。
|
|
3
|
+
*
|
|
4
|
+
* 只做**切分**,不判 option 类型、不查 case 是否存在——类型、适用性、case 名合法性只有 interface
|
|
5
|
+
* 知道,判定收口在 `computePipelineOverride` 一处,CLI 与 REPL 各写一套就会分叉。
|
|
6
|
+
*
|
|
7
|
+
* 两种写法:
|
|
8
|
+
* - `<键>=<值>`:select / switch 的 case 名;checkbox 用逗号分隔多个 case
|
|
9
|
+
* - `<键>.<字段>=<值>`:input 的输入字段(占位符 `{字段名}` 引用的就是它)
|
|
10
|
+
*/
|
|
11
|
+
export interface OptionArgs {
|
|
12
|
+
/** option 键 → case 名(单值或数组) */
|
|
13
|
+
cases: Record<string, string | string[]>;
|
|
14
|
+
/** option 键 → { 字段名: 原文 } */
|
|
15
|
+
fields: Record<string, Record<string, string>>;
|
|
16
|
+
/** 写法非法时的原因(调用方决定怎么报) */
|
|
17
|
+
error?: string;
|
|
18
|
+
}
|
|
19
|
+
export declare function parseOptionArgs(list: unknown): OptionArgs;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export interface PackageInfo {
|
|
2
|
+
name: string;
|
|
3
|
+
version: string;
|
|
4
|
+
description?: string;
|
|
5
|
+
}
|
|
6
|
+
export declare function cliPackage(): PackageInfo;
|
|
7
|
+
/**
|
|
8
|
+
* 运行中**实际加载**的 maa-node 版本(PI_CLIENT_MAAFW_VERSION)。
|
|
9
|
+
*
|
|
10
|
+
* 为什么不用 package.json 的声明值:那里写的是范围(^5.14.2),而 agent 侧拿这个变量是要判协议
|
|
11
|
+
* 兼容的——报范围等于没报。maa-node 不导出 `version`,也不保证导出 package.json,
|
|
12
|
+
* 所以从入口向上找包根。拿不到返回空串(调用方据此不注入,而不是编一个)。
|
|
13
|
+
*/
|
|
14
|
+
export declare function maaNodeVersion(): string;
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLI 协议层:统一 JSON 信封 + 命令契约 + 退出码语义。
|
|
3
|
+
*
|
|
4
|
+
* 信封结构抄 create-maa-project 的 `--report`——它已被真实消费方验证过,
|
|
5
|
+
* 属于本生态的既有事实标准。目的:让「技能 / 脚本 / CI / 人」消费同一份稳定结构,
|
|
6
|
+
* 不必各自解析文本输出,也不必各自发明字段名。
|
|
7
|
+
*
|
|
8
|
+
* 注意(这是本文件的唯一不变量):信封字段只增不改。技能会按字段名读取,
|
|
9
|
+
* 改名等于静默破坏所有消费方。
|
|
10
|
+
*/
|
|
11
|
+
import type { ParseArgsOptionsConfig } from 'node:util';
|
|
12
|
+
import type { GlobalFlags } from './flags.js';
|
|
13
|
+
/** 信封结构版本。字段增删时递增,消费方可据此拒绝不认识的形状。 */
|
|
14
|
+
export declare const SCHEMA_VERSION = 1;
|
|
15
|
+
/**
|
|
16
|
+
* 退出码语义。
|
|
17
|
+
*
|
|
18
|
+
* 关键区分:`FAIL` 是「命令没跑成」,`FINDINGS` 是「跑成了,但发现了问题」。
|
|
19
|
+
* 技能与 CI 必须能分开这两种情况——reco 识别未命中不是执行失败,
|
|
20
|
+
* 但也不该返回 0 让调用方以为一切正常。
|
|
21
|
+
*/
|
|
22
|
+
export declare const EXIT: {
|
|
23
|
+
/** 命令正常完成,未发现问题 */
|
|
24
|
+
readonly OK: 0;
|
|
25
|
+
/** 命令自身失败(未预期异常、IO 错误) */
|
|
26
|
+
readonly FAIL: 1;
|
|
27
|
+
/** 参数 / 用法错误 */
|
|
28
|
+
readonly USAGE: 2;
|
|
29
|
+
/** 命令正常跑完,但发现了问题(reco 未命中、run 调用级失败、观测类命令的警告等) */
|
|
30
|
+
readonly FINDINGS: 3;
|
|
31
|
+
/** 前置环境缺失(缺 maa-node / 缺 checkout / 缺设备) */
|
|
32
|
+
readonly ENV: 4;
|
|
33
|
+
/** 被 SIGINT(Ctrl-C)中断:128+2 */
|
|
34
|
+
readonly SIGINT: 130;
|
|
35
|
+
/** 被 SIGTERM 中断:128+15 */
|
|
36
|
+
readonly SIGTERM: 143;
|
|
37
|
+
};
|
|
38
|
+
export type ExitCode = (typeof EXIT)[keyof typeof EXIT];
|
|
39
|
+
export interface CliError {
|
|
40
|
+
message: string;
|
|
41
|
+
/** 稳定的机器可读标识,供技能分支判断;不要用 message 做判断 */
|
|
42
|
+
code: string;
|
|
43
|
+
hint?: string;
|
|
44
|
+
}
|
|
45
|
+
export interface Envelope {
|
|
46
|
+
schemaVersion: number;
|
|
47
|
+
command: string;
|
|
48
|
+
/** 命令本身是否执行成功。FINDINGS 仍算 ok=true——它跑成了,只是有发现 */
|
|
49
|
+
ok: boolean;
|
|
50
|
+
exitCode: number;
|
|
51
|
+
/** 本次操作的项目根,无法确定时为 null */
|
|
52
|
+
root: string | null;
|
|
53
|
+
written: string[];
|
|
54
|
+
removed: string[];
|
|
55
|
+
skipped: string[];
|
|
56
|
+
/** 需要人工跟进的事项(如「先跑 maa project sync」) */
|
|
57
|
+
pending: string[];
|
|
58
|
+
suggestedCommands: string[];
|
|
59
|
+
warnings: string[];
|
|
60
|
+
/** 命令特定载荷 */
|
|
61
|
+
data: unknown;
|
|
62
|
+
error: CliError | null;
|
|
63
|
+
}
|
|
64
|
+
/** 命令返回的结果。信封字段在此给默认值,命令只填关心的部分。 */
|
|
65
|
+
export interface CommandResult {
|
|
66
|
+
exitCode: ExitCode;
|
|
67
|
+
data?: unknown;
|
|
68
|
+
/** 非 --json 时逐行打印的内容。命令自己决定怎么排版 */
|
|
69
|
+
human?: string[];
|
|
70
|
+
warnings?: string[];
|
|
71
|
+
written?: string[];
|
|
72
|
+
removed?: string[];
|
|
73
|
+
skipped?: string[];
|
|
74
|
+
pending?: string[];
|
|
75
|
+
suggestedCommands?: string[];
|
|
76
|
+
error?: CliError;
|
|
77
|
+
root?: string | null;
|
|
78
|
+
}
|
|
79
|
+
export interface CommandContext {
|
|
80
|
+
/** 命令名之后的位置参数 */
|
|
81
|
+
positionals: string[];
|
|
82
|
+
/** 已解析的全部选项(含全局选项) */
|
|
83
|
+
values: Record<string, unknown>;
|
|
84
|
+
flags: GlobalFlags;
|
|
85
|
+
/** 已解析并校验过存在性的工作目录(绝对路径) */
|
|
86
|
+
cwd: string;
|
|
87
|
+
/**
|
|
88
|
+
* 复用既有 daemon 客户端(REPL / 命名会话 dispatch 时注入)。一次性命令路径此字段为空,
|
|
89
|
+
* `withDaemon` 才会新起一个 daemon、用完即关——两条路径跑的是同一份 Command.run。
|
|
90
|
+
*/
|
|
91
|
+
client?: import('./client/daemon.js').DaemonClient;
|
|
92
|
+
}
|
|
93
|
+
export interface Command {
|
|
94
|
+
name: string;
|
|
95
|
+
/** 一行说明,用于顶层 help 列表 */
|
|
96
|
+
summary: string;
|
|
97
|
+
/** 完整用法行,如 `maafw-live env [--deep] [--maafw <dir>]` */
|
|
98
|
+
usage: string;
|
|
99
|
+
/** 命令私有选项;全局选项由入口自动合并 */
|
|
100
|
+
options?: ParseArgsOptionsConfig;
|
|
101
|
+
/**
|
|
102
|
+
* 需要会话态才能工作的命令(会话 daemon 才有帧流 / 事件环 / 在跑任务)。
|
|
103
|
+
* `true` 整命令要;谓词形态按子命令分(frame get 要、frame status 不要;kf promote 要、
|
|
104
|
+
* kf list 不要)。一次性形态下入口直接退 2 + 指向 `--session <name>` 的提示,
|
|
105
|
+
* 不让"看起来成功了"的空跑存在(stop 停空 daemon、frame get 恒 NO_FRAME 这类)。
|
|
106
|
+
*/
|
|
107
|
+
requiresSession?: boolean | ((ctx: CommandContext) => boolean);
|
|
108
|
+
run(ctx: CommandContext): Promise<CommandResult>;
|
|
109
|
+
}
|
|
110
|
+
export declare function toEnvelope(command: string, r: CommandResult): Envelope;
|
|
111
|
+
export interface EmitOptions {
|
|
112
|
+
json: boolean;
|
|
113
|
+
color: boolean;
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* 输出命令结果。
|
|
117
|
+
*
|
|
118
|
+
* --json 时只输出信封(stdout 保持纯 JSON,可被管道解析);
|
|
119
|
+
* 否则输出命令自己的 human 渲染 + 警告 + 建议命令。
|
|
120
|
+
* 错误与警告一律走 stderr,避免污染 stdout 的 JSON。
|
|
121
|
+
*/
|
|
122
|
+
export declare function emit(command: string, r: CommandResult, o: EmitOptions): void;
|
|
123
|
+
/** 失败结果的快捷构造 */
|
|
124
|
+
export declare function fail(code: string, message: string, hint?: string, exitCode?: ExitCode): CommandResult;
|