Skip to content

3.3 Project Interface V2

Note: This document is about the creation and usage of ProjectInterface.

In this document, PI refers to ProjectInterface and Client refers to the tool that can process PI.

Introduction

The so-called ProjectInterface is a standardized project structure declaration for MaaFramework. It currently consists of a single file, interface.json. By defining a PI, you can leverage various derivative tools of MaaFramework. Therefore, even if you intend to integrate solely using a general-purpose programming language, it is recommended to define a PI containing the basic information.

TIP

You can find general UI and other tools that use PI in the Community Projects section.

Version Notes

Due to the rapid iteration of business development, the release schedule of MaaFramework cannot be properly aligned with the iteration pace of the PI. Therefore, PI will have its own separate version control, and its version number will not be completely synchronized with the MaaFramework release version number.

We have designated the version number for the independent release (January 30, 2026) as v2.1.0. Subsequent additions and fixes will be marked with version numbers in the documentation.

DateVersionChanges
2026-01-30v2.1.0Standalone release
2026-01-30v2.2.0Added attach_resource_path and import fields
2026-02-23v2.3.0Added checkbox multi-select type, option.controller, option.resource, global/resource/controller-level options, focus.display display channel tag, preset field, import supports importing preset
2026-03-05v2.3.1Clarified option applicability filtering

interface.json

TIP

This file can be validated and receive hints via the schema file.

When opening the project template folder with VSCode, the schema and file will be automatically associated.

Overall Structure

  • interface_version number
    The interface version number, currently 2, fixed and required. Used to identify the ProjectInterface protocol version.

  • languages object
    Multi-language support configuration. Keys are language codes, values are paths to corresponding translation files. If not specified, only Chinese is supported by default.
    File paths are relative to the directory containing interface.json.

    jsonc
    "languages": {
        "zh_cn": "interface_zh.json",
        "en_us": "interface_en.json"
    }
  • name string
    The unique project identifier, used as the project ID.

  • label string
    The project display name, shown in the user interface. Supports internationalized strings (starting with $). If not set, the value of the name field is displayed. Optional.

    jsonc
    {
      "name": "MyProject",
      "label": "$project_name"  // Internationalized project name
    }
  • title string
    The window title. The Client will display this content directly without additional decoration. Optional, defaults to a combination of name and version. Supports internationalization (starting with $).

  • icon string
    The application icon file path, relative to the project root directory. If not specified, the default icon is used. Supports internationalization (starting with $).

  • mirrorchyan_rid string
    MirrorChyan resource package identifier, used for resource management and distribution.

  • mirrorchyan_multiplatform boolean
    Whether multi-platform is supported, affecting resource package packaging and distribution strategies.

  • github string
    The project's GitHub repository URL, used for version update checking and issue feedback.
    Software Update Convention:
    After painful lessons from version history, we expect general-purpose UIs to only provide update functionality for this GitHub release, not separate updates for the UI itself or MaaFW.
    Resource authors should package their specified UI/MaaFW when releasing, ensuring that a specific resource version on the user side corresponds to a unique UI and MaaFW version, avoiding various issues caused by version mixing.

  • version string
    The project version number. The Client can display it to users and use it for version update checking.

  • contact string
    Contact information, displayed on the "About" page. Supports file paths, URLs, or direct text. Content supports Markdown format. Supports internationalization (starting with $).

  • license string
    Project license information, displayed on the "About" page. Supports file paths, URLs, or direct text. Content supports Markdown format. Supports internationalization (starting with $).

  • welcome string
    Welcome message, displayed in a popup when the user first uses the application, can also be used as an announcement. Supports file paths, URLs, or direct text. Content supports Markdown format. The system records the displayed content and will show the popup again when the content is updated. Supports internationalization (starting with $).

  • description string
    Project description information, displayed on the "About" page. Supports file paths, URLs, or direct text. Content supports Markdown format. Supports internationalization (starting with $).

  • controller object[]
    Controller configuration, an array of objects containing preset controller information.

    • name string
      Unique name identifier, used as the controller ID.

    • label string
      Display name, shown in the user interface. Supports internationalized strings (starting with $). If not set, the value of the name field is displayed.

    • description string
      Detailed controller description. Supports file paths, URLs, or direct text. Content supports Markdown format. Optional. Supports internationalization (starting with $).

    • icon string
      Controller icon file path, relative to the project root directory. Optional. Supports internationalization (starting with $).

    • type 'Adb' | 'Win32' | 'PlayCover' | 'Gamepad' | 'WlRoots'
      Controller type; valid values are Adb, Win32 (Windows only), PlayCover (macOS only), Gamepad (Windows only), and WlRoots (Linux only).

    • display_short_side number
      The short side length of the default scaled resolution, used for screen adaptation. Optional, defaults to 720. Mutually exclusive with display_long_side and display_raw.

    • display_long_side number
      The long side length of the default scaled resolution, used for screen adaptation. Optional. Mutually exclusive with display_short_side and display_raw.

    • display_raw boolean
      Whether to use the original resolution for screenshots without scaling. Optional, defaults to false. Mutually exclusive with scaled resolution settings.

    • permission_required boolean
      Whether this controller requires running with administrator privileges. Optional, defaults to false.
      Before running tasks, if the current process is not elevated, it will prompt and try to restart itself as an administrator.

    • attach_resource_path string[] 💡 v2.2.0
      Optional. An array of additional resource paths. These paths will be loaded after resource.path has finished loading.

    • option string[] 💡 v2.3.0
      Optional. Controller-level option configuration, an array of strings. Array elements should correspond to the key names in the outer option configuration. The parameters generated by this option will participate in the pipeline override of all tasks that use this controller, serving as controller-level parameter passing.
      If a referenced option does not satisfy the current controller/resource constraints, that option's pipeline_override (including nested option.option) must not be merged. 💡 v2.3.1

    • adb object
      Specific configuration for the Adb controller.

      Note: In V2 protocol, the input/screencap methods for Adb controllers are automatically detected and selected by MaaFramework, no manual configuration required.

    • win32 object
      Specific configuration for the Win32 controller.

      • class_regex string
        Optional. The regular expression used to search for window class names by the Win32 controller.

      • window_regex string
        Optional. The regular expression used to search for window titles by the Win32 controller.

      • mouse string
        Optional. The mouse control method for the Win32 controller. If not provided, the default is used. See Control Methods for details.

      • keyboard string
        Optional. The keyboard control method for the Win32 controller. If not provided, the default is used. See Control Methods for details.

      • screencap string
        Optional. The screenshot method for the Win32 controller. If not provided, the default is used. See Control Methods for details.

    • playcover object
      Specific configuration for the PlayCover controller (macOS only). Used to control iOS applications running via PlayCover. See Control Methods for details.

      • uuid string
        Optional. The Bundle Identifier of the target application. If not provided, the default maa.playcover will be used. This is only used as a controller identifier and is unrelated to the application being controlled.
    • gamepad object
      Specific configuration for the Gamepad controller (Windows only). Used to create a virtual gamepad for game control. Requires ViGEm Bus Driver to be installed. See Control Methods for details.

      • class_regex string
        Optional. The regular expression used to search for window class names by the Win32 controller.

      • window_regex string
        Optional. The regular expression used to search for window titles by the Win32 controller.

      • gamepad_type string
        Optional. The virtual gamepad type. Valid values are Xbox360, DualShock4 (or DS4). If not provided, Xbox360 is used by default.

      • screencap string
        Optional. The screenshot method. If not provided, the default is used. Only effective when window regex is configured. See Control Methods for details.

    • wlroots object
      Specific configuration for the WlRoots controller.

  • resource object[]
    Resource configuration, an array of objects containing information about resource loading.

    • name string
      Unique name identifier, used as the resource package ID.

    • label string
      Display name, shown in the user interface. Supports internationalized strings (starting with $). If not set, the value of the name field is displayed. Optional.

    • description string
      Detailed resource description. Supports file paths, URLs, or direct text. Content supports Markdown format. Optional.

    • icon string
      Resource icon file path, relative to the project root directory. Optional. Supports internationalization (starting with $).

    • path string[]
      An array of paths to load. If multiple paths are provided, they will be loaded sequentially; resources loaded later will override those loaded earlier.
      File paths are relative to the directory containing interface.json.
      Note: Resources include not only pipeline but also image and model. Therefore, do not specify the pipeline directory directly.

    • controller string[]
      Optional. Specifies the list of controller types supported by this resource package. Array elements should correspond to the name field in the controller configuration. If not specified, all controller types are supported.

      When a user selects a controller, only resource packages that support that controller will be displayed in the user interface for selection. This allows providing specially optimized resource packages for different controller types.

    • option string[]
      Optional. Resource-level option configuration, an array of strings. Array elements should correspond to the key names in the outer option configuration. The parameters generated by this option will participate in the pipeline override of all tasks, serving as resource-level parameter passing.
      If a referenced option does not satisfy the current controller/resource constraints, that option's pipeline_override (including nested option.option) must not be merged. 💡 v2.3.1

      jsonc
      "resource": [
          {
              "name": "AndroidSpecificResource",
              "label": "$AndroidSpecificResource",
              "controller": ["Android"],
              "path": ["resource_android"]
          },
          {
              "name": "GeneralResource",
              "label": "$GeneralResource",
              "path": ["resource"]
          }
      ]
  • 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.

    • child_exec string
      The subprocess path, an executable file available in the system path. For example, if the Python path exists in the environment variables (system or user), you can simply write "python".
      CWD is the directory containing interface.json.

    • child_args string[]
      Optional. An array of arguments for the subprocess.

    • identifier string
      Optional. A connection identifier used to create a communication socket. If provided, it will be used; otherwise, one is created automatically.

    Single Agent Example:

    jsonc
    "agent": {
        "child_exec": "python",
        "child_args": [
            "./agent/main.py",              // Note: CWD is the directory containing interface.json
            "--test-mode"                   // Fixed string, passed as-is
        ]
    }

    Multiple Agents Example:

    jsonc
    "agent": [
        {
            "child_exec": "python",
            "child_args": ["./agent/recognition.py"]
        },
        {
            "child_exec": "python",
            "child_args": ["./agent/action.py"]
        }
    ]
  • task object[]
    Task configuration, an array of objects containing information about executable tasks.

    • name string
      Unique task identifier, used as the task ID.

    • label string
      Task display name, shown in the user interface. Supports internationalized strings (starting with $). If not set, the value of the name field is displayed. Optional.

    • entry string
      The task entry, which is the name of the Task in the pipeline.

    • default_check boolean
      Whether this task is selected by default. Optional, defaults to false. The Client will use this value to determine whether to check this task by default during initialization.

    • description string
      Detailed task description to help users understand the task's functionality. Supports file paths, URLs, or direct text. Content supports Markdown format. Optional.

    • icon string
      Task icon file path, relative to the project root directory. Used for display in the user interface. Optional. Supports internationalization (starting with $).

    • resource string[]
      Optional. Specifies the list of resource packages supported by this task. Array elements should correspond to the name field in the resource configuration. If not specified, this task is available in all resource packages.

      When a user selects a resource package, the Client may hide tasks that do not support that resource package, or display them in a disabled (grayed-out) state to inform the user. This allows providing specialized task configurations for different resource packages, such as event tasks that are only available in specific resource packages.

      jsonc
      "task": [
          {
              "name": "EventTask",
              "label": "$EventTask",
              "entry": "ActivityTask",
              "resource": ["Official"],
              "description": "Event task only available in the Official resource package"
          },
          {
              "name": "CommonTask",
              "label": "$CommonTask",
              "entry": "CommonTask"
          }
      ]
    • controller string[]
      Optional. Specifies the list of controller types supported by this task. Array elements should correspond to the name field in the controller configuration. If not specified, this task is available for all controller types.

      When a user selects a controller, the Client may hide tasks that do not support that controller, or display them in a disabled (grayed-out) state to inform the user. This allows providing specialized task configurations for different controller types, such as tasks that are only available for Adb controllers or Win32 controllers.

      jsonc
      "task": [
          {
              "name": "AndroidOnlyTask",
              "label": "$AndroidOnlyTask",
              "entry": "AndroidSpecificTask",
              "controller": ["Android"],
              "description": "Task only available for Android controllers"
          },
          {
              "name": "Win32OnlyTask",
              "label": "$Win32OnlyTask",
              "entry": "Win32SpecificTask",
              "controller": ["Win32Emulator"],
              "description": "Task only available for Win32 controllers"
          },
          {
              "name": "CommonTask",
              "label": "$CommonTask",
              "entry": "CommonTask"
          }
      ]
    • pipeline_override pipeline
      Optional. Task parameters that override the loaded resources when executing the task. This structure is exactly the same as the JSON file in the pipeline and must include the task name part, for example:

      jsonc
      "pipeline_override": {
          "Quit": {
              "enabled": true
          }
      }
    • option string[]
      Optional. Task configuration options, an array containing keys from subsequent option objects. The Client will prompt the user to make selections based on these.

      The Client can display the options in the order provided in the option array.

  • option record<string, object>
    Definition of configuration options, an object mapping containing information about each option.

    • key
      Unique name identifier; tasks will reference this name.

    • type string
      The option type. Optional, defaults to "select". Valid values:

      • "select": Dropdown selection box, user selects one from predefined options
      • "checkbox": Multi-select box, user selects multiple from predefined options 💡 v2.3.0
      • "input": User input field, allows manual input
      • "switch": Toggle switch, Yes or No
    • controller string[] 💡 v2.3.0
      Optional. Specifies the list of controller types this option applies to. Array elements should correspond to the name field in the controller configuration. If not specified, this option is available for all controller types.
      When a user selects a controller, the Client may hide options that do not apply to that controller, or display them in a disabled (grayed-out) state to inform the user.
      If the current controller is not in this list, the option is treated as inactive: all pipeline_override generated by this option and its sub-options (option.option) must be excluded from merging. 💡 v2.3.1

    • resource string[] 💡 v2.3.0
      Optional. Specifies the list of resource packages this option applies to. Array elements should correspond to the name field in the resource configuration. If not specified, this option is available for all resource packages.
      When a user selects a resource package, the Client may hide options that do not apply to that resource package, or display them in a disabled (grayed-out) state to inform the user.
      If the current resource package is not in this list, the option is treated as inactive: all pipeline_override generated by this option and its sub-options (option.option) must be excluded from merging. 💡 v2.3.1

    • label string
      Option display label, shown in the user interface. Supports internationalized strings (starting with $). Optional.

    • description string
      Detailed option description to help users understand the option's purpose. Supports file paths, URLs, or direct text. Content supports Markdown format. Optional. Supports internationalization (starting with $).

    • icon string
      Option icon file path, relative to the project root directory. Optional. Supports internationalization (starting with $).

    • cases object[]
      Used only when type is "select", "checkbox", or "switch". Available options, an array of objects containing information about each option.

      Note: When type is "checkbox", the user can select multiple cases simultaneously. The pipeline_override of all selected cases will be merged in the order they appear in the cases array — regardless of the order in which the user checked them.

      Note: When type is "switch", only two cases are supported, and the following rules must be followed:

      • If case.name is one of "Yes", "yes", "Y", or "y", that case will be recognized as the Yes option
      • If case.name is one of "No", "no", "N", or "n", that case will be recognized as the No option
      • The Client will match the user's Y/N input based on the case's name, and other inputs will prompt the user to re-enter

      It is recommended to use "Yes" and "No" as the names of the two cases to ensure consistency across different Clients.

      The Client can display the options in the order provided in the cases array.

      • name string
        Unique option identifier, used as the option ID.

      • label string
        Option display name, shown in the user interface. Supports internationalized strings (starting with $). If not set, the value of the name field is displayed. Optional.

      • description string
        Detailed option description. Supports file paths, URLs, or direct text. Content supports Markdown format. Optional. Supports internationalization (starting with $).

      • icon string
        Option icon file path, relative to the project root directory. Optional. Supports internationalization (starting with $).

      • option string[]
        Sub-option list. Optional. These sub-options are only displayed when the user selects the current option. These sub-options are also defined in the outer option and support unlimited nesting.

      • pipeline_override pipeline
        Same as the pipeline_override in the task. It takes effect when the option is activated.

    • inputs object[]
      Used only when type is "input". Input configuration, an array of objects defining user-inputtable fields.

      • name string
        Unique input field identifier, used as the input field ID.

      • label string
        Input field display name, shown in the user interface. Supports internationalized strings (starting with $). If not set, the value of the name field is displayed. Optional.

      • description string
        Detailed input field description to help users understand input requirements. Supports file paths, URLs, or direct text. Content supports Markdown format. Optional. Supports internationalization (starting with $).

      • default string
        Default value for the input field. Optional.

      • pipeline_type string
        The data type of the input field in pipeline_override. Valid values: "string", "int", "bool". When using variable substitution in pipeline_override, type conversion is performed according to this type.

      • verify string
        Regular expression used to validate whether user input is valid. Optional.

      • pattern_msg string
        Message displayed when regex validation of user input fails. Optional. Supports internationalization (starting with $).

    • pipeline_override pipeline
      Used when the option type is "input", as a substitution template for user input content. Supports using {name} format in strings to reference input field values. Optional.

    • default_case string | string[]
      Default option name. Optional.

      • When type is "select" or "switch": provide a single string; the Client uses it as the initial selected value.
      • When type is "checkbox": provide a string array; the Client uses it as the initial set of selected values. 💡 v2.3.0
  • global_option string[] 💡 v2.3.0
    Optional. Global option configuration, an array of strings. Array elements should correspond to key names in the option configuration.
    The parameters generated by this option will participate in the pipeline override of all tasks, regardless of which resource package or controller the user has selected.
    Unlike resource.option and controller.option, global options do not depend on any resource package or controller selection.
    However, options referenced by global_option must still satisfy their own resource / controller constraints; otherwise, no pipeline_override is applied. 💡 v2.3.1

    jsonc
    "global_option": [
        "BattleMode",
        "AutoDodge"
    ]
  • 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.
    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
    Optional. Preset configurations, an array of objects. Each preset is a snapshot of predefined task checkbox states and option values. Users can apply a preset with a single click to quickly switch between different usage scenarios.

    • name string
      Unique identifier, used as the preset ID.

    • label string
      Display name, shown in the user interface. Supports internationalized strings (starting with $). If not set, the value of the name field is displayed. Optional.

    • description string
      Detailed preset description to help users understand the applicable scenario. Supports file paths, URLs, or direct text. Content supports Markdown format. Optional. Supports internationalization (starting with $).

    • icon string
      Preset icon file path, relative to the project root directory. Optional. Supports internationalization (starting with $).

    • task object[]
      List of task configurations included in this preset.

      • name string
        Required. The task name corresponding to task[].name at the top level.

      • enabled boolean
        Optional, defaults to true. Whether this task is checked in the preset.

      • option record<string, OptionValue>
        Optional. Preset values for each option of this task. Keys are option key names from the top-level option. The OptionValue type depends on the corresponding option.type:

        option.typeOptionValue typeExample
        select / switchstring (case.name)"x3" / "Yes"
        checkboxstring[] (array of case.name)["AutoBattle", "AutoPickup"]
        inputrecord<string, string> (input field name → value){ "ChapterNumber": "4" }

    Preset Example:

    jsonc
    "preset": [
        {
            "name": "DailyRoutine",
            "label": "$DailyRoutine",
            "description": "Daily routine: Wilderness + Insight + 3-9 + Claim Rewards",
            "icon": "preset_daily.png",
            "task": [
                { "name": "Collect Wilderness", "enabled": true },
                { "name": "Daily Insight (Will Analysis)", "enabled": true },
                {
                    "name": "Standard Combat",
                    "enabled": true,
                    "option": {
                        "BattleStage": "3-9 Dire (Lark)",    // select type: fill case.name
                        "RepeatCount": "x3",                  // select type: fill case.name
                        "DrainAllSanity": "No",               // switch type: fill case.name
                        "EnableFeatures": ["AutoBattle", "AutoPickup"]  // checkbox type: fill case.name array
                    }
                },
                { "name": "Claim Rewards", "enabled": true },
                { "name": "Event: Stage 17 Hard (Event Ended)", "enabled": false }
            ]
        },
        {
            "name": "RealtimeAssist",
            "label": "$RealtimeAssist",
            "description": "Background assist mode, only runs auto-assist tasks",
            "task": [
                {
                    "name": "Standard Combat",
                    "enabled": true,
                    "option": {
                        "EnableFeatures": ["AutoBattle", "AutoPickup", "AutoHeal"]
                    }
                }
            ]
        }
    ]

    Managing presets across files via import:

    Preset configurations can be split into separate files via import for easier management and reuse. For example:

    jsonc
    // interface.json
    {
        "import": [
            "preset_daily.json",
            "preset_realtime.json"
        ],
        "preset": [
            // Presets can also be defined directly in the main file and will be merged with imported presets
        ]
    }
    jsonc
    // preset_daily.json
    {
        "preset": [
            {
                "name": "DailyRoutine",
                "label": "$DailyRoutine",
                "description": "Daily routine package",
                "task": [
                    { "name": "Collect Wilderness", "enabled": true },
                    { "name": "Claim Rewards", "enabled": true }
                ]
            }
        ]
    }

Option Override Order 💡 v2.3.0

The pipeline_override generated by each level of option is merged in the following order — later-merged fields override earlier ones with the same key name:

  1. global_option — global options, applied first, lowest priority
  2. resource.option — resource-level options
  3. controller.option — controller-level options
  4. task.option — task-level options, applied last, highest priority

In other words: task.option > controller.option > resource.option > global_option.

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

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:

If both global_option and a task.option reference the same option, and that option's cases make different overrides to the same pipeline node, the task-level override will take final effect.

Option Examples

Select Type Option Example

jsonc
{
  "option": {
    "BattleStage": {
      "type": "select",
      "label": "$SelectBattleStage",
      "description": "Select the stage to farm",
      "default_case": "3-9 Dire",
      "cases": [
        {
          "name": "3-9 Dire (Lark)",
          "label": "$3-9Dire",
          "description": "Farm Lark",
          "icon": "lark.png",
          "option": [
            "UseSanityPotion",
            "AfterFarmingXXX"
          ],
          "pipeline_override": {
            "EnterTheShow": {
              "next": "MainChapter_3"
            }
          }
        }
      ]
    }
  }
}

Input Type Option Example

jsonc
{
  "option": {
    "CustomStage": {
      "type": "input",
      "label": "Custom Stage",
      "description": "Choose which stage to play",
      "icon": "wrench.png",
      "inputs": [
        {
          "name": "ChapterNumber",
          "label": "$ChapterNumber",
          "description": "Stage chapter number, use Arabic numerals",
          "default": "4",
          "pipeline_type": "string",
          "verify": "^\\d+$"
        },
        {
          "name": "Timeout",
          "label": "$Timeout",
          "description": "Wait timeout duration",
          "default": "20000",
          "pipeline_type": "int",
          "verify": "^\\d+$"
        }
      ],
      "pipeline_override": {
        "EnterTheShow": {
          "next": "MainChapter_{ChapterNumber}",
          "timeout": "{Timeout}"
        }
      }
    }
  }
}

Checkbox Type Option Example 💡 v2.3.0

jsonc
{
  "option": {
    "BattleFeatures": {
      "type": "checkbox",
      "label": "$BattleFeatures",
      "description": "Select the battle features to enable, multiple selections allowed",
      "default_case": ["NormalStrike", "ChargedStrike"],
      "cases": [
        {
          "name": "NormalStrike",
          "label": "$NormalStrike",
          "description": "Enable normal strike",
          "pipeline_override": {
            "NormalMatch": {
              "enabled": true
            }
          }
        },
        {
          "name": "ChargedStrike",
          "label": "$ChargedStrike",
          "description": "Enable charged strike",
          "pipeline_override": {
            "ChargedMatch": {
              "enabled": true
            }
          }
        },
        {
          "name": "ComboStrike",
          "label": "$ComboStrike",
          "description": "Enable combo strike",
          "pipeline_override": {
            "ComboMatch": {
              "enabled": true
            }
          }
        }
      ]
    }
  }
}

Note: In checkbox type, the pipeline_override of multiple selected cases is merged in the definition order of the cases array — regardless of the order in which the user checked them.

Internationalization Support

For all string fields that support internationalization, if the string starts with $, it indicates that the string is an internationalized string. The Client needs to read the actual value from the translation file before displaying it.

For example:

jsonc
{
  "name": "MyDemo3",
  "label": "$MyDemo3",
  "controller": [
    {
      "name": "Android",
      "label": "$Android"
    }
  ]
}

Corresponding translation file (e.g., interface_en.json):

jsonc
{
  "MyDemo3": "My Demo 3",
  "Android": "Android Device"
}

Resource Override

If a later-loaded resource contains a task with the same name as one already loaded, the tasks will be merged. Generally, the top-level keys of the new task will replace those of the old task. For example:

Old Task

jsonc
{
    "task1": {
        "enabled": false,
        "recognition": "DirectHit",
        "next": [ "T1", "T2" ]
    }
}

New Task

jsonc
{
    "task1": {
        "enabled": true,
        "action": "Click",
        "next": [ "T2", "T3" ]
    }
}

Merged Task

jsonc
{
    "task1": {
        "enabled": true,
        "recognition": "DirectHit",
        "action": "Click",
        "next": [ "T2", "T3" ]       // Direct replacement; inner arrays/lists are not merged.
    }
}

Node Notification Handling

MaaFramework sends node notifications via callback functions during task execution. The Client needs to implement the corresponding handling logic to display task execution status to users.

Callback Function Signature

The Client needs to register a callback function to receive notifications. For the function signature, refer to MaaDef.h:

c
typedef void(MAA_CALL* MaaEventCallback)(
    void* handle,
    const char* message,
    const char* details_json,
    void* trans_arg
);
  • message: Message type identifier (e.g., Node.Action.Starting, Node.Recognition.Succeeded, etc.)
  • details_json: JSON string containing specific data

Message Template Mechanism

Resource authors can configure message templates in the Pipeline using the focus field. The focus field is a dictionary where keys are message types and values are template strings or template objects. Template strings support file paths, URLs, or direct text, content supports Markdown format, and support internationalization (starting with $). When the Client receives a callback, it should perform placeholder replacement based on the template and display the result to users via the specified channel.

Two Forms of focus Values

Shorthand (plain string): Equivalent to display: "log" — content is only shown in the run log.

jsonc
"focus": {
    "Node.Action.Starting": "{name} starts execution"
}

Full form (object): Use the display field to specify the display channel. 💡 v2.3.0

jsonc
"focus": {
    "Node.Action.Starting": {
        "content": "{name} starts execution",
        "display": "toast"
    }
}
display Values 💡 v2.3.0
ValueDescriptionBehavior
"log"Run log (default)Appended to the log stream, non-interrupting
"toast"In-app lightweight notificationBriefly appears then auto-dismisses, non-blocking
"notification"System-level notificationPushed to OS notification center, received even when app is in background
"dialog"Non-blocking dialogPopup message box, task pipeline continues running in the background
"modal"Blocking popupTask is paused until the user confirms — suitable for scenarios requiring manual intervention

display supports arrays so the same message can be pushed to multiple channels simultaneously:

jsonc
"focus": {
    "Node.Action.Succeeded": {
        "content": "✅ {name} executed successfully",
        "display": ["log", "toast"]
    },
    "Node.Action.Failed": {
        "content": "❌ Execution failed, please check the environment",
        "display": ["log", "modal"]
    }
}

Complete Pipeline Configuration Example:

jsonc
{
  "NodeA": {
    "focus": {
      "Node.Recognition.Succeeded": "{name} recognition hit, ready to start execution",
      "Node.Action.Starting": {
        "content": "{name} starts execution, task ID: {task_id}",
        "display": ["log", "toast"]
      },
      "Node.Action.Failed": {
        "content": "{name} execution failed",
        "display": "modal"
      }
    }
  }
}

Callback Function Parameters Example:

c
// message parameter:
"Node.Action.Starting"

// details_json parameter (after parsing):
{
    "task_id": 12345,
    "action_id": 11111,
    "name": "NodeA",
    "focus": {
        "Node.Recognition.Succeeded": "{name} recognition hit, ready to start execution",
        "Node.Action.Starting": {
            "content": "{name} starts execution, task ID: {task_id}",
            "display": ["log", "toast"]
        },
        "Node.Action.Failed": {
            "content": "{name} execution failed",
            "display": "modal"
        }
    }
}

Client Processing Flow

  1. Parse the details_json parameter in the callback function
  2. Check if the parsed object contains a focus field
  3. If present, find the corresponding template (string or object) in focus based on the message parameter
  4. If the template is a string, treat it as content and set display to ["log"]; if it is an object, read content and display separately
  5. Replace placeholders in content (e.g., {name}, {task_id}) with data from details_json
  6. Display the processed text to the user via the channel(s) specified in display (may be multiple) 💡 v2.3.0

Using the example above, upon receiving Node.Action.Starting, the Client should append to the log and show a toast: NodeA starts execution, task ID: 12345

More Message Types

For a complete list of callback messages and detailed descriptions, please refer to Callback Protocol and MaaMsg.h.