Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
114 changes: 113 additions & 1 deletion docs/en_us/3.3-ProjectInterfaceV2.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ We have designated the version number for the independent release (January 30, 2
| 2026-03-09 | v2.4.0 | Added top-level `group` declarations and `task.group` task grouping |
| 2026-03-23 | v2.5.0 | Convention for `PI_*` environment variables when the Client starts Agent subprocesses (UI / Client metadata and the selected controller and resource with i18n resolved) |
| 2026-04-18 | v2.6.0 | Added `resource.hash` resource integrity check field |
| 2026-05-06 | v2.7.0 | Added the `pretask` field for running custom programs before Controller startup, with support for passing option values as the last argument |

## `interface.json`

Expand Down Expand Up @@ -251,6 +252,115 @@ We have designated the version number for the independent release (January 30, 2
]
```

- **pretask** `object | object[]` **💡 v2.7.0**
_Optional._ Pre-task configuration to run before Controller startup. It can be a single object or an array of objects. The Client should start these programs in order before creating or connecting the Controller, and wait for each program to finish. If a pre-task fails to start or exits with a non-zero code, the Client should abort the current startup and report the error to the user.
The pre-task's CWD is the directory containing interface.json.
The same `pretask` field may appear in files loaded through the top-level `import` array; the Client should merge all resulting pre-tasks into one ordered list: first those from the main `interface.json` (a single object counts as one entry), then those from each imported file in the order listed in `import`, appending each file's own `pretask` entries in array order (or the single object, if not an array). Execution order follows that merged list.

- **exec** `string`
_Required._ The program to execute. It may be an executable available in the system `PATH`, such as `"python"`.

- **args** `string[]`
_Optional._ Fixed arguments passed to `exec` in order.

- **name** `string`
_Optional._ A unique identifier for this pre-task. It is recommended to keep it unique within the project so the Client can distinguish entries in configuration files and logs. When `name` is omitted, the Client may fall back to `exec` as the identifier.

- **label** `string`
_Optional._ Display name shown by the Client in its UI. Supports internationalized strings (starting with `$`). If not set, the Client may fall back to `name` or `exec`.

- **description** `string`
_Optional._ Detailed description shown by the Client (e.g. tooltip). Supports internationalized strings, file paths, or URLs. The content supports Markdown (same semantics as `task.description`).

- **icon** `string`
_Optional._ Icon path displayed by the Client in its UI, relative to the directory containing interface.json. Supports internationalized strings.

- **option** `string[]`
_Optional._ Pre-task configuration options, an array whose elements should correspond to key names in the outer `option` configuration. The Client will prompt the user to make selections for these options.
If `option` is set, the Client should serialize the current values of these options as a **single-line compact JSON string**, and automatically append it as the last argument after `args`. If `option` is omitted or empty, this JSON argument is not appended.
The JSON object uses option key names as field names, and the value type is the same as `OptionValue` in `preset.task[].option`: `select` / `switch` use a `case.name` string, `checkbox` uses an array of `case.name` strings, and `input` uses an object from input field `name` to string value. Sub-options (`option.option`) activated by the user's selection should also be included under their own option key names; options that do not satisfy the current `controller` / `resource` constraints should not be included.
`pretask.option` is only used to generate arguments for the pre-task process; it does not participate in `pipeline_override` merging.

**Single pretask example:**

```jsonc
"pretask": {
"exec": "python",
"args": [
"./scripts/prepare.py",
"--before-controller"
],
"option": [
"StartupConfig"
]
}
```

If the selected option values are:

```json
{
"StartupConfig": "CleanCache"
}
```

Then the arguments actually passed by the Client are equivalent to:

```jsonc
[
"./scripts/prepare.py",
"--before-controller",
"{\"StartupConfig\":\"CleanCache\"}"
]
```

**Multiple pretask example:**

```jsonc
"pretask": [
{
"exec": "python",
"args": ["./scripts/check_env.py"]
},
{
"exec": "./tools/bootstrap",
"args": ["--fast"],
"option": ["StartupConfig"]
}
]
```

**Managing pretask across files via `import`:**

Pre-task entries can be split into separate files via `import`, same as `task` / `preset`. For example:

```jsonc
// interface.json
{
"import": [
"pretask_common.json"
],
"pretask": {
"exec": "python",
"args": ["./scripts/main_prepare.py"]
}
}
```

```jsonc
// pretask_common.json
{
"pretask": [
{
"exec": "python",
"args": ["./scripts/check_env.py"]
}
]
}
```

After merge, the Client runs `main_prepare.py` first, then `check_env.py`, before starting the Controller.

- **agent** `object | object[]`
Agent configuration; it can be a single object or an array of objects, containing information about the subprocess(es) (AgentServer). Supports configuring multiple Agents simultaneously for more complex automation scenarios.
From **v2.5.0** onward, the Client should also inject environment variables with the `PI_` prefix when starting this subprocess, as described in [Agent subprocess environment variables](#agent-subprocess-env-v25) below.
Expand Down Expand Up @@ -583,7 +693,7 @@ PI_RESOURCE={"name":"官服","label":"官服","path":["./resource"]}

- **import** `string[]` **💡 v2.2.0**
_Optional._ An array of paths to other PI files to import. File paths are relative to the directory containing interface.json.
Supports importing `task`, `option`, and `preset` **💡 v2.3.0** fields from these files.
Supports importing `task`, `option`, `preset` **💡 v2.3.0**, and `pretask` **💡 v2.7.0** fields from these files.
The Client will load these files sequentially and merge their contents with the current file, enabling configuration splitting and reuse.

- **preset** `object[]` **💡 v2.3.0**
Expand Down Expand Up @@ -709,6 +819,8 @@ In other words: `task.option` > `controller.option` > `resource.option` > `globa

Before applying the merge order above, inactive options must be filtered out. Any option that does not satisfy the current `controller` / `resource` constraints (including options referenced by `global_option`, `resource.option`, `controller.option`, `task.option`, and nested `option.option`) must not generate `pipeline_override`. **💡 v2.3.1**

`pretask.option` does not participate in the override order above; it only serializes the current option values as the last argument for the pre-task process. **💡 v2.7.0**

The reasoning behind this design is that more specific configuration (task-level) should have higher priority, while more general configuration (global-level) serves as the fallback default.

**Example:**
Expand Down
114 changes: 113 additions & 1 deletion docs/zh_cn/3.3-ProjectInterfaceV2协议.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
| 2026-3-9 | v2.4.0 | 新增顶层 `group` 分组声明与 `task.group` 任务分组字段 |
| 2026-3-23 | v2.5.0 | 约定 Client 启动 Agent 子进程时注入 `PI_*` 环境变量,传递 UI / Client 属性及当前选中的控制器与资源(i18n 已解析) |
| 2026-4-18 | v2.6.0 | 新增 `resource.hash` 资源完整性校验字段 |
| 2026-5-6 | v2.7.0 | 新增 `pretask` 字段,用于在 Controller 启动前执行自定义程序,并支持将 option 取值作为最后一个参数传入 |

## `interface.json`

Expand Down Expand Up @@ -252,6 +253,115 @@
]
```

- pretask `object | object[]` **💡 v2.7.0**
可选。Controller 启动前执行的预任务配置,可以是单个对象或对象数组。Client 应在创建或连接 Controller 前按顺序启动这些程序,并等待其执行结束。若预任务启动失败或返回非零退出码,Client 应中止本次启动并向用户报告错误。
预任务的 CWD 为 interface.json 所在目录。
同一 `pretask` 字段也可出现在由顶层 `import` 加载的其他 PI 片段文件中;Client 应将各处的预任务合并为一条有序列表:先执行主 `interface.json` 中的条目(单个对象视为一项),再按 `import` 数组顺序依次追加各被引用文件中的 `pretask`(若为数组则按数组顺序;若为单个对象则视为一项)。实际执行顺序与该合并后的列表一致。

- exec `string`
必须。要执行的程序路径,可以是系统 `PATH` 中的可执行文件,例如 `"python"`。

- args `string[]`
可选。固定参数数组,按顺序传递给 `exec`。

- name `string`
可选。预任务的唯一标识符,建议项目内不重复,便于 Client 在配置文件、日志中区分不同预任务。Client 可在 `name` 缺省时回退到 `exec` 作为标识。

- label `string`
可选。预任务在 Client UI 中展示的名称,支持国际化字符串(以 `$` 开头)。若不设置,Client 可回退到 `name` 或 `exec`。

- description `string`
可选。预任务的详细说明,用于 Client UI 中的提示/Tooltip。支持国际化字符串、文件路径或 URL,内容支持 Markdown 格式(与 `task.description` 相同语义)。

- icon `string`
可选。预任务在 Client UI 中显示的图标路径,相对于 interface.json 所在目录。支持国际化字符串。

- option `string[]`
可选。预任务配置项,为一个数组,数组元素应与外层 `option` 配置中的键名对应。Client 会根据这些配置项让用户进行选择。
若设置了 `option`,Client 应将这些 option 的当前取值序列化为**单行紧凑 JSON 字符串**,并自动追加为最后一个参数,位于 `args` 之后。若未设置或为空,则不追加该 JSON 参数。
该 JSON 对象以 option 键名为字段名,取值类型与 `preset.task[].option` 中的 `OptionValue` 一致:`select` / `switch` 为 `case.name` 字符串,`checkbox` 为 `case.name` 字符串数组,`input` 为输入字段 `name` 到字符串值的对象。因用户选择而激活的子配置项(`option.option`)也应以其自身 option 键名加入该对象;不满足当前 `controller` / `resource` 限制的 option 不应加入。
`pretask.option` 仅用于生成传给预任务进程的参数,不参与 `pipeline_override` 合并。

**单个 pretask 示例:**

```jsonc
"pretask": {
"exec": "python",
"args": [
"./scripts/prepare.py",
"--before-controller"
],
"option": [
"启动前配置"
]
}
```

若用户选择后的 option 取值为:

```json
{
"启动前配置": "清理缓存"
}
```

则 Client 实际传入的参数等价于:

```jsonc
[
"./scripts/prepare.py",
"--before-controller",
"{\"启动前配置\":\"清理缓存\"}"
]
```

**多个 pretask 示例:**

```jsonc
"pretask": [
{
"exec": "python",
"args": ["./scripts/check_env.py"]
},
{
"exec": "./tools/bootstrap",
"args": ["--fast"],
"option": ["启动前配置"]
}
]
```

**通过 `import` 分文件管理 pretask:**

与 `task`、`preset` 类似,预任务也可拆到独立文件中由 `import` 引用。例如:

```jsonc
// interface.json
{
"import": [
"pretask_common.json"
],
"pretask": {
"exec": "python",
"args": ["./scripts/main_prepare.py"]
}
}
```

```jsonc
// pretask_common.json
{
"pretask": [
{
"exec": "python",
"args": ["./scripts/check_env.py"]
}
]
}
```

合并后,Client 应先执行 `main_prepare.py`,再执行 `check_env.py`,然后再启动 Controller。

- agent `object | object[]`
代理配置,可以是单个对象或对象数组,含有子进程(AgentServer)的信息。支持同时配置多个 Agent 以实现更复杂的自动化场景。
自 **v2.5.0** 起,Client 在启动该子进程时还应按约定注入以 `PI_` 为前缀的环境变量,详见下文 [Agent 子进程环境变量](#agent-subprocess-env-v25) 小节。
Expand Down Expand Up @@ -581,7 +691,7 @@ PI_RESOURCE={"name":"官服","label":"官服","path":["./resource"]}

- import `string[]` **💡 v2.2.0**
可选。导入其他 PI 文件的路径数组。文件相对路径为 interface.json 同目录下的相对路径。
支持导入这些文件中的 `task`、`option``preset` **💡 v2.3.0** 字段。
支持导入这些文件中的 `task`、`option``preset` **💡 v2.3.0** 以及 `pretask` **💡 v2.7.0** 字段。
Client 会依次加载这些文件,并将它们的内容与当前文件进行合并,从而实现配置的拆分和复用。

- preset `object[]` **💡 v2.3.0**
Expand Down Expand Up @@ -707,6 +817,8 @@ PI_RESOURCE={"name":"官服","label":"官服","path":["./resource"]}

在进入上述合并顺序前,需先过滤“未激活”的 option。任何不满足当前 `controller` / `resource` 条件的 option(包括来自 `global_option`、`resource.option`、`controller.option`、`task.option` 以及嵌套 `option.option`)都不得产生 `pipeline_override`。 **💡 v2.3.1**

`pretask.option` 不参与上述覆盖顺序;它只会将 option 的当前取值序列化为预任务进程的最后一个参数。 **💡 v2.7.0**

这样设计的理由是:越具体的配置(任务级)应当具有越高的优先级,越通用的配置(全局级)则作为兜底默认值。

**示例:**
Expand Down
72 changes: 70 additions & 2 deletions tools/interface.schema.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "MaaFramework Project Interface V2",
"description": "MaaFramework 项目接口配置文件 V2 版本的 JSON Schema。💡 v2.5.0:Client 启动 agent 子进程时应按文档约定注入 PI_* 环境变量(见 Project Interface 文档 Agent 子进程环境变量 / Agent subprocess environment variables 章节)",
"description": "MaaFramework 项目接口配置文件 V2 版本的 JSON Schema。",
"type": "object",
"definitions": {
"i18nString": {
Expand Down Expand Up @@ -837,6 +837,58 @@
],
"additionalProperties": false
},
"pretaskConfig": {
"type": "object",
"title": "预任务配置",
"description": "💡 v2.7.0 Controller 启动前执行的自定义程序配置。Client 应在创建或连接 Controller 前运行该程序;若配置 option,则将 option 取值序列化为紧凑 JSON 字符串并追加为最后一个参数",
"properties": {
"exec": {
"type": "string",
"title": "预任务程序路径",
"description": "要执行的程序路径,可以是系统 PATH 中的可执行文件。CWD 为 interface.json 所在目录"
},
"args": {
"type": "array",
"title": "预任务参数",
"description": "可选。固定参数数组,按顺序传递给 exec",
"items": {
"type": "string"
}
},
"name": {
"type": "string",
"title": "预任务唯一标识",
"description": "可选。建议项目内不重复,便于 Client 在配置文件、日志中区分不同预任务;缺省时 Client 可回退到 exec"
},
"label": {
"$ref": "#/definitions/i18nString",
"title": "预任务显示名称",
"description": "可选。Client UI 中展示的名称,支持国际化字符串。缺省时 Client 可回退到 name 或 exec"
},
"description": {
"$ref": "#/definitions/i18nString",
"title": "预任务详细描述",
"description": "可选。Client UI 中的提示/Tooltip。支持国际化字符串、文件路径或 URL,内容支持 Markdown"
},
"icon": {
"$ref": "#/definitions/i18nString",
"title": "预任务图标路径",
"description": "可选。Client UI 中显示的图标路径,相对于 interface.json 所在目录,支持国际化字符串"
},
"option": {
"type": "array",
"title": "预任务选项配置",
"description": "可选。数组元素应与外层 option 配置中的键名对应。Client 会收集这些 option 的当前取值并序列化为紧凑 JSON 字符串,追加为最后一个参数;该 option 不参与 pipeline_override 合并",
"items": {
"type": "string"
}
}
},
"required": [
"exec"
],
"additionalProperties": false
},
"agentConfig": {
"type": "object",
"title": "代理配置",
Expand Down Expand Up @@ -973,6 +1025,22 @@
"$ref": "#/definitions/groupItem"
}
},
"pretask": {
"description": "💡 v2.7.0 可选。Controller 启动前执行的预任务配置。若配置 option,Client 应将 option 取值序列化为最后一个参数",
"oneOf": [
{
"$ref": "#/definitions/pretaskConfig"
},
{
"type": "array",
"title": "预任务配置数组",
"description": "多个预任务配置。Client 应在 Controller 启动前按数组顺序执行",
"items": {
"$ref": "#/definitions/pretaskConfig"
}
}
]
},
"agent": {
"description": "💡 v2.5.0:启动各子进程时 Client 应注入 PI_* 环境变量,详见 Project Interface 文档",
"oneOf": [
Expand Down Expand Up @@ -1016,7 +1084,7 @@
"import": {
"type": "array",
"title": "导入其他 PI 文件",
"description": "可选。导入其他 PI 文件的路径数组。文件相对路径为 interface.json 同目录下的相对路径。支持导入这些文件中的 task、option、preset(💡 v2.3.0)字段",
"description": "可选。导入其他 PI 文件的路径数组。文件相对路径为 interface.json 同目录下的相对路径。支持导入这些文件中的 task、option、preset(💡 v2.3.0)、pretask(💡 v2.7.0)字段",
"items": {
"type": "string"
}
Expand Down