01 / 选择插件类型
| 类型 | 用途 | 使用入口 |
|---|---|---|
| PROCESS | ARM64 命令、SDK、本地服务及受限 Harness 扩展 | 工具中心导入并安装 |
| WEB | 静态页面及白名单原生能力 | 设置 → 应用功能插件 → 外部 Web 插件 |
| v1 兼容工具 | 原有清单与安装配方 | 原工具详情、启动和卸载入口 |
本地包使用 LOCAL + LOCAL_PACKAGE 并标记 offlineOnly=true。在线 Registry 工具仍通过工具中心管理。v2 本地包不能覆盖内置或在线工具。
PROCESS 的权限和资源声明用于校验、展示与冲突检查,不构成恶意脚本隔离。PRoot 进程仍以 App UID 运行,脚本可以修改该身份可写的路径;WEB 页面能力另由原生代理授权。
02 / 插件包格式
本地插件使用 ZIP 容器,扩展名为 .txplugin。根目录必须直接包含 manifest.json 和 payload/。
hello-arm64.txplugin
├── manifest.json
└── payload/
├── archives/ # SDK、NDK、Flutter 等归档
├── scripts/ # 安装、验证脚本
├── config/ # 配置模板
└── bin/ # ARM64 文件
- 只允许
manifest.json和payload/,不得包含绝对路径或..。 manifest.json最大 1 MiB;PROCESS 解压合计最大 8 GiB,最多 20,001 个条目。- v2 严格拒绝未知字段,包版本目录不可覆盖。
plugin.integrity必须精确列出所有 payload 普通文件及小写 SHA-256;键相对于 payload,例如bin/hello。- WEB 使用更小的容量和文件类型限制,见下方页面包说明。
03 / 编写 v2 PROCESS 清单
下面的完整示例使用空 payload/,安装时生成可执行脚本。携带文件的工程由作者 CLI 生成完整性清单。
{
"schemaVersion": 2,
"id": "hello-arm64",
"name": "Hello ARM64",
"description": "TaiXu 本地插件示例",
"version": "1.0.0",
"launchType": "command",
"architectures": ["ARM64"],
"source": "LOCAL",
"offlineOnly": true,
"installMethod": "LOCAL_PACKAGE",
"installSteps": [
"printf '#!/bin/sh\\necho hello\\n' > \"$TAIXU_TOOL_DIR/bin/hello\"; chmod 755 \"$TAIXU_TOOL_DIR/bin/hello\""
],
"launchCommand": "hello",
"verifyCommand": "hello",
"commandLinks": ["hello"],
"plugin": {
"id": "example.hello",
"api": {"minimum": 1, "maximum": 1},
"execution": "PROCESS",
"extensions": [{"id": "launch", "point": "PROCESS"}],
"dependencies": [],
"capabilities": [],
"resources": [],
"integrity": {}
}
}
| 字段 | 当前约束 |
|---|---|
id | 工具存储键:小写字母、数字和连字符。 |
plugin.id | 独立的点分身份;第三方不能使用 taixu.* 或 legacy.*。 |
version | 严格 SemVer,如 1.0.0;升级须递增。 |
plugin.api | 声明兼容 API 范围,当前示例为 1~1。 |
commandLinks | 链接到工具私有 bin/ 目录;每个入口都必须能验证。 |
plugin.integrity | 文件集合及内容哈希必须完全匹配。 |
04 / 从零制作 Hello 插件
也可以把脚本放在 payload/bin/hello,并用下面的步骤替换上例的 installSteps:
#!/bin/sh
echo "hello from TaiXu"
安装步骤必须创建工具目录并恢复执行权限:
"installSteps": [
"test -f \"$TAIXU_PLUGIN_PAYLOAD/bin/hello\"",
"mkdir -p \"$TAIXU_TOOL_DIR/bin\"",
"cp \"$TAIXU_PLUGIN_PAYLOAD/bin/hello\" \"$TAIXU_TOOL_DIR/bin/hello\"",
"chmod 755 \"$TAIXU_TOOL_DIR/bin/hello\""
]
安装器提供 TAIXU_TOOL_ID、TAIXU_TOOL_DIR、TAIXU_TOOL_DATA 和本地插件专用的 TAIXU_PLUGIN_PAYLOAD。v2 按原始字节校验,不自动修复脚本换行或 BOM;请保存为 UTF-8、LF 换行。
05 / 用作者 CLI 校验与打包
在项目仓库中构建纯 JVM 作者工具,再对插件工程执行:
.\gradlew.bat :plugin:cli:installDist
.\plugin\cli\build\install\taixu-plugin\bin\taixu-plugin.bat pack .\hello-arm64 --write-manifest
.\plugin\cli\build\install\taixu-plugin\bin\taixu-plugin.bat check .\hello-arm64
.\plugin\cli\build\install\taixu-plugin\bin\taixu-plugin.bat inspect .\hello-arm64\dist\hello-arm64-1.0.0.txplugin
Linux / macOS 使用 ./gradlew 与同目录无 .bat 后缀的可执行脚本。pack 重算 payload 哈希;--write-manifest 同时更新工程清单。默认输出到插件工程的 dist/,校验与打包不会执行安装脚本或调用模型。
大型插件使用支持 Zip64 的工具;对已经压缩的 .zip、.tar.gz 和 .deb 条目优先使用 Store/NoCompression。
修改 payload 后必须同步更新哈希并递增版本,不能直接替换已导入的同版本文件。建议重新通过 CLI 打包,避免清单与实际字节不一致。
- v2 按严格 SemVer 排序,支持预发布优先级;build metadata 不影响版本优先级。
- 升级不能改变插件身份、切换 PROCESS / WEB 或降为 v1。
- 插件依赖范围下界包含、上界不包含;依赖必须先安装,不会自动下载。
- 缺失依赖、循环、资源冲突或破坏已安装依赖者的升级会被拒绝;被依赖插件不能卸载。
- 导入只是选择安装候选;PROCESS 的启动和卸载按实际安装版本读取配置。
06 / 制作 Web 页面包
WEB 使用同一 v2 容器,plugin.execution=WEB,扩展固定为 [{"id":"main","point":"PAGE"}]。默认静态入口是 payload/index.html,导入后即可从外部 Web 插件页面打开,无需 Linux 配方安装。
- 静态 payload 最多 63 个普通文件、合计 2 MiB;含清单解压总量最多 3 MiB,归档最多 129 个条目。
- 文件名与目录使用普通 ASCII;不能包含查询串、百分号编码或保留的根
theme.css。 - 不接受安装步骤、Shell 命令、环境变量、旧权限字段、全局资源或插件依赖。
- 可声明 APP_INFO、CLIPBOARD_WRITE、INSTALL_APK、LOGCAT 白名单能力;原生侧确认后调用,剪贴板写入和 APK 安装每次确认。
- 升级或移除后旧页面授权失效;能力授权不随导入自动授予。
还支持固定的受管理 PRoot 来源与已安装服务来源,具体字段和限制请按完整规范选用,包不能自行提供任意地址、端口或命令。
查看完整 WEB 示例与消息协议 ↗07 / 精简 RootFS 与大型依赖
不要假设系统带有 unzip、xz、file、readelf、jq、Python 或 Node。优先使用 .tar.gz,并通过 SHA-256 校验归档。
archive="$TAIXU_PLUGIN_PAYLOAD/archives/flutter-arm64.tar.gz"
test -s "$archive"
printf '%s %s\n' "<SHA256>" "$archive" | sha256sum -c -
rm -rf /opt/flutter.staging
mkdir -p /opt/flutter.staging
tar -xzf "$archive" -C /opt/flutter.staging
不依赖 file/readelf 的 AArch64 检查:
elf_bytes() { od -An -t x1 "$@" 2>/dev/null | tr -d ' \n'; }
is_aarch64_elf() {
test "$(elf_bytes -j 18 -N 2 "$1")" = "b700"
}
- ZIP 解压后必须显式
chmod。 - 查找可能为符号链接的工具时使用
\( -type f -o -type l \)。 - 不要把可能展开为多个路径的 glob 直接交给
test -x。 - ARM64 架构相同不代表 Android/Bionic 与 Linux/glibc ABI 兼容。
08 / 实时百分比与安装日志
插件脚本可以输出单调递增的结构化相对进度,应用会映射到完整安装进度条:
[TAIXU_PROGRESS:47] [EXTRACT] 正在解压 Android NDK r29
[TAIXU_PROGRESS:75] [COMMAND] 正在配置 ADB
[TAIXU_PROGRESS:98] [VERIFY] 正在执行最终验证
推荐使用 [COPY]、[EXTRACT]、[COMMAND]、[VERIFY] 标签。不要启用 set -x,它可能把 Token、代理或环境变量写入日志。
09 / 超时、空间与回滚边界
- 安装脚本默认超时 15 分钟,验证命令默认超时 60 秒。
- 大包需要同时容纳私有插件副本、沙盒 payload 副本、staging 和最终目录。
- 框架事务只快照
/opt/taixu/tools/<id>。 /opt/android-sdk、/opt/flutter、/root/.gradle等全局路径必须由插件自行 staging 和清理。- 日志出现
ROLLED_BACK不代表所有全局文件都已恢复。 verifyCommand应返回 0;不要依赖旧插件兼容用的命令入口兜底。
v2 全局资源当前只接受 RETAIN,禁止自定义卸载脚本;卸载由框架清理工具目录、可选数据与命令入口。声明的全局目录不会自动删除。安装与升级基于同一发行版的实际安装收据复核依赖和资源,失败后保留旧版本运行配置。
10 / 发布前检查
- CLI check / pack / inspect 均通过,完整性清单与所有 payload 文件精确对应。
- 身份、SemVer、API 范围和扩展类型正确;满足 PROCESS 或 WEB 各自容量限制。
- PROCESS:ARM64、启动入口和依赖正确;不依赖未声明的可选命令。
- PROCESS:执行位与 ABI 已核对,离线安装、验证和启动通过;失败时 staging 可清理。
- WEB:默认静态入口可打开,原生能力确认、拒绝、撤销与升级失效均验证。
- 重复导入、新版本升级和卸载或移除均验证。
- 安装进度单调递增,日志与页面资源不包含凭据。
- 大型包已核算私有副本、payload、staging 和最终目录的总空间。
