01 / 本地插件与在线插件
| 来源 | 清单 | 资源 |
|---|---|---|
| 在线插件 | REMOTE + SCRIPT | 内置或签名 Registry |
| 本地插件 | LOCAL + LOCAL_PACKAGE | 用户导入的 .txplugin |
导入器会把本地包强制标记为 source=LOCAL、offlineOnly=true、installMethod=LOCAL_PACKAGE。本地插件与在线插件使用相同 ID 时,本地版本优先显示。
permissions 目前用于清单校验与界面展示,不是安装脚本的权限沙箱。插件脚本仍能修改 PRoot 内当前用户可写的路径。
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。- 解包条目累计最大 8 GiB。
- 安装前,payload 会复制到
/opt/taixu/imports/<id>。
03 / 编写 manifest.json
{
"schemaVersion": 1,
"id": "hello-arm64",
"name": "Hello ARM64",
"description": "TaiXu 本地插件示例",
"version": "1.0.0",
"publisher": "Your Name",
"category": "DEVELOPER",
"launchType": "command",
"architectures": ["ARM64"],
"permissions": [],
"source": "LOCAL",
"offlineOnly": true,
"installMethod": "LOCAL_PACKAGE",
"launchCommand": "hello",
"verifyCommand": "hello",
"commandLinks": ["hello"]
}
| 字段 | 当前约束 |
|---|---|
id | 小写字母、数字和连字符,长度 2~64。 |
version | 必须非空,建议使用规范的 x.y.z。 |
launchType | one_shot、command、pty、web 或 service。 |
architectures | 必须包含 ARM64。 |
permissions | NETWORK、WORKSPACE_READ、WORKSPACE_WRITE、LOCAL_WEB。 |
commandLinks | 默认链接到 $TAIXU_TOOL_DIR/bin/<command>。 |
04 / 从零制作 Hello 插件
将脚本放在 payload/bin/hello:
#!/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。
05 / 打包、版本与快速更新
Windows PowerShell
Compress-Archive `
-LiteralPath .\hello-arm64\manifest.json, .\hello-arm64\payload `
-DestinationPath .\hello-arm64.zip -Force
Move-Item .\hello-arm64.zip .\hello-arm64.txplugin
Linux / macOS
cd hello-arm64
zip -r ../hello-arm64.txplugin manifest.json payload
大型插件使用支持 Zip64 的工具;对已经压缩的 .zip、.tar.gz 和 .deb 条目优先使用 Store/NoCompression。
.txplugin 就是 ZIP。只更新清单或脚本时,可以复制旧包并替换少量 ZIP 条目,不必解压、重压缩所有大型归档;替换归档或改变压缩格式时才需要处理对应大文件。
- 相同
id + version会提示已导入,不重复解包或安装。 - 相同 ID 的不同版本当前会共存。
- 当前版本目录按字符串排序,并非完整 SemVer;修复前避免同时使用
1.0.9与1.0.10。 - 确认新包后,界面会连续执行导入与安装。
06 / 精简 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 兼容。
07 / 实时百分比与安装日志
插件脚本可以输出单调递增的结构化相对进度,应用会映射到完整安装进度条:
[TAIXU_PROGRESS:47] [EXTRACT] 正在解压 Android NDK r29
[TAIXU_PROGRESS:75] [COMMAND] 正在配置 ADB
[TAIXU_PROGRESS:98] [VERIFY] 正在执行最终验证
推荐使用 [COPY]、[EXTRACT]、[COMMAND]、[VERIFY] 标签。不要启用 set -x,它可能把 Token、代理或环境变量写入日志。
08 / 超时、空间与回滚边界
- 安装脚本默认超时 15 分钟,验证命令默认超时 60 秒。
- 大包需要同时容纳私有插件副本、沙盒 payload 副本、staging 和最终目录。
- 框架事务只快照
/opt/taixu/tools/<id>。 /opt/android-sdk、/opt/flutter、/root/.gradle等全局路径必须由插件自行 staging 和清理。- 日志出现
ROLLED_BACK不代表所有全局文件都已恢复。 verifyCommand应返回 0;不要依赖旧插件兼容用的命令入口兜底。
09 / 发布前检查
- ZIP 根目录、1 MiB manifest 和 8 GiB 解包限制均满足。
- 本地/在线来源、ID、版本、ARM64、启动类型与权限字段正确。
- 所有大文件都有固定 SHA-256。
- 不依赖未声明的 unzip、xz、file、readelf 等可选命令。
- ELF、符号链接和 ZIP 可执行位均已处理。
- 断网完成导入、安装、验证和启动。
- 全新安装、同版本重复导入、新版本升级和卸载均验证。
- 结构化进度单调递增且日志不包含敏感信息。
- 失败时 staging 可清理,并已核算全部磁盘副本。
