# manifest.json ## 功能 `manifest.json` 是扩展包的身份和运行声明。它告诉 BT 这个包是不是 `.bts` 扩展、扩展叫什么、使用什么后端和入口文件、最低 BT 版本、调用大小上限以及运行时模式。扩展是用户信任的本地程序依赖,不声明包级权限。 ## 语法 纯 BT 扩展示例: ```json { "format": "bts", "format_version": 1, "name": "calc", "version": "1.0.0", "summary": "Calculator extension", "description": "calc extension", "author": "", "developer": { "id": "example_team", "name": "Example Team", "homepage": "https://example.com" }, "repository": "https://github.com/example/calc", "license": "MIT", "locales": { "zh-CN": { "summary": "计算器扩展", "description": "提供计算功能。", "developer_name": "示例团队" } }, "kind": "bt", "abi": "bts-bt-1", "bt_min_version": "1.1.0", "api_version": 1, "entry": "src/lib.bt", "bindings": "bindings.json", "limits": { "max_args_bytes": 16777216, "max_result_bytes": 16777216 }, "runtime": { "mode": "thread_local" } } ``` WASM 扩展只需要把后端相关字段改为: ```json { "kind": "wasm", "abi": "bts-wasi-1", "entry": "module.wasm" } ``` WASM shared runtime 配置示例: ```json { "kind": "wasm", "abi": "bts-wasi-1", "entry": "module.wasm", "runtime": { "mode": "shared", "workers": 4, "queue_limit": 1024, "call_timeout_ms": 30000, "idle_ttl_ms": 300000, "max_objects": 65536, "max_worker_objects": 4096, "max_inflight_calls": 64 } } ``` ## 参数 | 字段 | 类型 | 说明 | | ------ | ------ | ------ | | `format` | String | 固定为 `bts`。 | | `format_version` | Number | 包格式版本,使用 `1`。 | | `name` | String | 扩展包名称,只能使用小写字母、数字和下划线,并以小写字母开头。 | | `version` | String | 扩展自身版本,使用三段式 SemVer,例如 `1.0.0`。 | | `summary` | String | 可选英文目录短摘要。 | | `description` | String | 可选说明文本。 | | `author` | String | 可选作者文本。 | | `developer` | Object | 可选稳定开发者身份,包含 `id`、`name` 和可选 `homepage`。 | | `repository` | String | 可选公开源码仓库 URL。 | | `license` | String | 可选 SPDX 许可证表达式。 | | `locales` | Object | 可选本地化展示元数据,键使用 `zh-CN` 等规范 BCP 47 标识。 | | `kind` | String | 后端类型,只能是 `bt` 或 `wasm`。 | | `abi` | String | 后端 ABI,必须和 `kind` 匹配。 | | `bt_min_version` | String | 扩展要求的最低 BT 版本。 | | `api_version` | Number | bindings 语义版本,使用 `1`。 | | `entry` | String | 后端入口文件的包内相对路径。 | | `bindings` | String | bindings 描述文件的包内相对路径。 | | `limits` | Object | 单次调用的参数和返回值编码大小上限。 | | `runtime` | Object | 可选运行时模式配置;缺省等同 `mode: "thread_local"`。 | 每个 `locales.` 对象只接受 `summary`、`description` 和 `developer_name`。语言键必须使用规范 BCP 47 大小写;简体中文统一为 `zh-CN`,与 `README.zh-CN.md` 完全一致。本地化只改变展示文本,不改变扩展名称、API 标识、配置字段或事件名。 ## kind 与 abi | kind | abi | 含义 | | ------ | ------ | ------ | | `bt` | `bts-bt-1` | 入口文件是 BT 源码,函数和对象方法由纯 BT Runner 执行。 | | `wasm` | `bts-wasi-1` | 入口文件是 WASM 模块,调用通过 WASI P1 和 BtValueBinary 完成。 | 如果 `kind` 和 `abi` 不匹配,扩展会在加载阶段报错。 ## runtime 运行时配置 | 字段 | 类型 | 默认值 | 说明 | | ------ | ------ | ------ | ------ | | `mode` | String | `thread_local` | 运行时模式,只能是 `thread_local` 或 `shared`。 | | `workers` | Number | `1` | shared 模式 worker 数量,范围 `1..=64`。 | | `queue_limit` | Number | `1024` | shared 模式等待队列长度,范围 `1..=65536`。 | | `call_timeout_ms` | Number | `30000` | shared 模式单次调用超时,范围 `1..=300000`。 | | `idle_ttl_ms` | Number | `300000` | shared 模式空闲保留时间,范围 `1..=3600000`。 | | `max_objects` | Number | `65536` | shared 模式服务级对象数量上限,范围 `1..=65536`。 | | `max_worker_objects` | Number | `4096` | shared 模式单个 worker 内对象数量上限,范围 `1..=4096`,且不能大于 `max_objects`。 | | `max_inflight_calls` | Number | `64` | shared 模式执行中调用数量上限,范围 `1..=4096`。 | `runtime` 缺失时,扩展继续使用当前线程本地 Runner 缓存,不改变现有扩展行为。`mode=shared` 第一版只允许 `kind=wasm`,纯 BT 扩展声明 shared 会在 manifest 校验阶段报错。 当前版本已经接入项目级 `ExtensionService`。声明 `mode=shared` 的 WASM 扩展会创建独立有界 worker 队列,入口函数可以通过 worker 返回原始值或扩展对象;返回扩展对象时宿主会分配 `host_object_id`,对象方法调用前再路由回创建该对象的 worker 本地对象 ID。队列满、服务关闭、执行中调用超过上限、服务级对象数或单 worker 对象数超过上限时会返回中文错误。 `call_timeout_ms` 不只是调用线程等待上限。shared worker 会启用 Wasmtime epoch interrupt,超时后宿主会标记目标 worker、触发 WASM trap,并在 worker 返回后重建 WASM Store/Instance,避免超时调用永久占用服务容量。服务统计会包含 `workers`、`queued`、`running`、`completed`、`failed`、`timed_out`、`objects` 和每个 worker 的对象数量。 ## 返回值 `manifest.json` 不是脚本函数,没有运行时返回值。校验成功时,BT 会继续读取 bindings 和入口文件;校验失败时,加载过程返回中文错误并停止加载该扩展。 ## 代码示例 纯 BT 扩展入口和 manifest 的对应关系: ```bt fn calc(value) { value } ``` `manifest.entry` 指向包含这段源码的 `src/lib.bt`,`manifest.kind` 写 `bt`,`manifest.abi` 写 `bts-bt-1`。 ## 注意事项 - `entry` 和 `bindings` 必须是包内安全相对路径,不能使用绝对路径、反斜杠、空路径、`.`、`..` 或带盘符的路径。 - `entry` 不能和 `bindings` 指向同一个文件。 - `permissions` 字段已经删除。仍包含该字段的扩展包无法通过 manifest 校验,必须按新版 `.bts` 格式重新构建。 - 所有已安装扩展使用相同宿主 ABI;实际能力由 BT 进程级策略和操作系统账号决定,与包来源或是否被官网收录无关。 - 安装扩展即表示信任其代码。官网只审查自己分发的精确开源版本;本地、私有、修改版和闭源扩展不受限制,也不属于官网审核范围。 - `limits.max_args_bytes` 和 `limits.max_result_bytes` 不能为 `0`,也不能超过宿主硬上限。 - `runtime` 中不能出现未知字段,避免扩展作者误以为未实现的配置已经生效。 - `runtime.mode=shared` 不改变 BT 请求变量生命周期,也不会让普通脚本全局变量跨请求共享。 - `runtime.mode=shared` 已支持扩展对象宿主路由;`close()` 或 `dispose()` 标记为 `lifecycle: "dispose"` 且调用成功后,宿主对象句柄会失效。 - `runtime.mode=shared` 的 `call_timeout_ms` 会触发目标 worker 的 WASM 中断和运行态重建,不能用于长期阻塞宿主 hostcall 的精确取消。 - 扩展名、入口名、参数名和方法名都应遵守 BT 的 snake_case 命名风格。