# manifest.json

## 功能

`manifest.json` 是扩展包的身份和运行声明。它告诉 BT：这个包是不是 `.bts` 扩展、扩展叫什么、用什么后端运行、入口文件在哪里、最低 BT 版本是多少、需要哪些权限、单次调用允许传输多大的参数和返回值，以及扩展运行时模式。

## 语法

纯 BT 扩展示例：

```json
{
    "format": "bts",
    "format_version": 1,
    "name": "calc",
    "version": "1.0.0",
    "description": "calc extension",
    "author": "",
    "kind": "bt",
    "abi": "bts-bt-1",
    "bt_min_version": "1.1.0",
    "api_version": 1,
    "entry": "src/lib.bt",
    "bindings": "bindings.json",
    "permissions": [],
    "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`。 |
| `description` | String | 可选说明文本。 |
| `author` | String | 可选作者文本。 |
| `kind` | String | 后端类型，只能是 `bt` 或 `wasm`。 |
| `abi` | String | 后端 ABI，必须和 `kind` 匹配。 |
| `bt_min_version` | String | 扩展要求的最低 BT 版本。 |
| `api_version` | Number | bindings 语义版本，使用 `1`。 |
| `entry` | String | 后端入口文件的包内相对路径。 |
| `bindings` | String | bindings 描述文件的包内相对路径。 |
| `permissions` | Array | 扩展声明的能力权限数组。只写需要的权限；不需要的权限不要写。 |
| `limits` | Object | 单次调用的参数和返回值编码大小上限。 |
| `runtime` | Object | 可选运行时模式配置；缺省等同 `mode: "thread_local"`。 |

## 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 的对象数量。

## 权限说明

| 权限 | 说明 |
| ------ | ------ |
| `fs_read` | 允许声明读取文件路径参数。 |
| `fs_write` | 允许声明写入文件路径参数。 |
| `net` | 预留给网络通信能力声明。 |
| `http` | 预留给 HTTP 客户端能力声明。 |
| `process` | 预留给进程能力声明。 |
| `env` | 预留给环境变量能力声明。 |

`permissions` 只能使用字符串数组，例如 `["fs_read", "fs_write"]`。权限必须和运行进程的权限配置同时允许。扩展声明了某项权限，但运行进程禁止该能力时，扩展会加载失败。

## 返回值

`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` 指向同一个文件。
- `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 命名风格。
