# @crvouga/mockingbird-service-tempo 中文文档

规范地址：https://npmcn.com/package/%40crvouga/mockingbird-service-tempo/

版本：0\.10\.0
npm 元数据更新时间：2026-11-11T02:39:43.795Z
中文译文更新时间：2026-11-11T09:44:36.189Z
软件包许可：MIT

本文由上游 README 翻译，可能存在偏差，请结合原文核对 API、命令与配置。版权与许可归原作者所有。

原始 npm 页面：https://www.npmjs.com/package/%40crvouga/mockingbird-service-tempo
原文对照：https://npmcn.com/package/%40crvouga/mockingbird-service-tempo/?lang=original
项目主页：https://github.com/crvouga/mockingbird/tree/main/packages/service/tempo#readme
源码仓库：https://github.com/crvouga/mockingbird

## 关键信息（来自 npm 元数据）

- 包体积（解压后）：4.5 MB，18 个文件
- 模块格式：ES Module
- TypeScript 类型：包内自带
- 运行依赖：2 个
- 首次发布：2026-10-11T01:56:30.419Z
- 最新版本发布：2026-11-11T02:39:43.463Z
- 近 30 天下载量：2381（2026-10-11 至 2026-11-09，npm 官方下载统计）
- 已发布版本数：16（近 12 个月 16 个）

## 中文简介

Grafana Tempo的模拟器:OTLP/HTTP 追踪摄入(JSON和protobuf),追踪QL搜索,由ID进行追踪和在一个租户范围商店上发现标记名称.

## 安装

```sh
npm install @crvouga/mockingbird-service-tempo
```

也可以使用：`pnpm add @crvouga/mockingbird-service-tempo`、`yarn add @crvouga/mockingbird-service-tempo`、`bun add @crvouga/mockingbird-service-tempo`

## README

# @crvouga/mockingbird-service-tempo (英语)

> 本地模拟器。 真正的API合同. 部分 [嘲笑鸟](https://github.com/crvouga/mockingbird)。 。 。 .

状态模拟器 **格拉法纳·泰普** 测试套房:OTLP/HTTP跟踪接收器 (单位:千美元)`POST /v1/traces`, JSON and protobuf) 和查询路径 跟踪阅读器呼叫( TraceQL search, 追踪身份,标记名称,超过一个商店。 测试出口跨越其应用方式和 读到它们后,它的制作读者发出请求, 没有多克和通波.

-   行动范围: [支助](https://github.com/crvouga/mockingbird/blob/main/packages/service/tempo/SUPPORT.md)
-   状态 : **进行中的工作**。Tempo没有发布 OpenAPI 文件,也没有实例 合同是写成的`openapi.yaml`跟着格拉法纳 [HTTP API 参考文献](https://grafana.com/docs/tempo/latest/api_docs/) 还有Tempo的消息来源 (原始内容存档于2017-03-10). v3.1.0. [核实了什么](https://npmcn.com/package/%40crvouga/mockingbird-service-tempo/#readme-what-was-verified-and-how) 列出每一个可以 未确认.

## 安装

```bash
npm install -D @crvouga/mockingbird-service-tempo
```

仅限无害环境管理。 节点 22或 Bun 1.2. 无土生属地. 给它服务 `npx mockingbird-tempo serve`, (中文(简体) ), `createServer` 从 `./server` (节点),或 `createRuntime` 带有任意 获取服务器 .

## 使用量

Tempo在两个端口上收听(4318用于OTLP,3200用于查询);模拟器从一个端口同时服务 源代码。 指向出口商的终点和读者的Tempo URL:

```bash
npx mockingbird-tempo serve --port 8930
# OTEL_EXPORTER_OTLP_ENDPOINT=http://127.0.0.1:8930   (the exporter posts /v1/traces)
# TEMPO_URL=http://127.0.0.1:8930                     (the reader calls /api/…)

# Grafana Cloud style credentials, and tenants:
npx mockingbird-tempo serve --basic-auth 123456:fixture-token --multitenancy
```

```ts
import { OTLPTraceExporter } from "@opentelemetry/exporter-trace-otlp-http"
import { resourceFromAttributes } from "@opentelemetry/resources"
import { BasicTracerProvider, SimpleSpanProcessor } from "@opentelemetry/sdk-trace-base"
import { createServer } from "@crvouga/mockingbird-service-tempo/server"

const server = await createServer()

// The OpenTelemetry SDK your application already uses. Only the exporter's URL changes
// (the protobuf exporter works the same way).
const provider = new BasicTracerProvider({
  resource: resourceFromAttributes({ "service.name": "checkout" }),
  spanProcessors: [new SimpleSpanProcessor(new OTLPTraceExporter({ url: `${server.url}/v1/traces` }))],
})
const span = provider.getTracer("checkout").startSpan("POST /checkout", {
  startTime: new Date(1_700_000_000_000),
  attributes: { "user.id": "user-1" },
})
span.end(new Date(1_700_000_001_500))
await provider.forceFlush()

// What the trace reader sends (Tempo's query API is plain HTTP).
const q = encodeURIComponent('{ .user.id = "user-1" }')
const search = await fetch(`${server.url}/api/search?q=${q}&start=1699999990&end=1700000010&limit=50`)
const { traces } = (await search.json()) as { traces: { traceID: string }[] }
const trace = await fetch(`${server.url}/api/traces/${traces[0]?.traceID}`)

await provider.shutdown()
await server.close()
```

### 路线

| 路线 | 行为 |
| --- | --- |
| `POST /v1/traces` | 一个 `ExportTraceServiceRequest` 作为 `application/json` 或者说 `application/x-protobuf` (gzip接受). 成功200个 `{"partialSuccess":{}}` 给JSON 和一个空的原生纸条给原生纸条 错误是 `google.rpc.Status` 在请求的编码中:400码3 一个不解码的有效载荷, `trace ids must be 128 bit, received N bits` 财务报告和审定财务报表 `span ids must be 64 bit and not all zero, received N bits` 为ids Tempo的经销商拒绝(整个出口被拒绝,没有存储)。 其他内容类型是415 `415 unsupported media type, supported: [application/json, application/x-protobuf]` 作为纯文本。 在任何其他检查之前,接受无跨度的出口。 已存储用于跟踪的横跨标识被替换 . |
| `GET /api/search` | `q` (跟踪QL,见下文), `start`编号 :`end` (时间秒), `limit` (违约20), `spss` (每套跨度分秒数,默认为3,最多为100). 答复 `{traces: [...], metrics: {...}}`; 每一个痕迹都有 `traceID`, (中文(简体) ), `rootServiceName`, (中文(简体) ), `rootTraceName`, (中文(简体) ), `startTimeUnixNano` (nanoseconds,一个小数字符串), `durationMs` (数目), `spanSet`编号 :`spanSets` (相匹配的跨度 : `spanID`, (中文(简体) ), `startTimeUnixNano`, (中文(简体) ), `durationNanos`,并属性比较的查询; `matched` )和 `serviceStats`。没有匹配 `{"traces": []}`最新的追踪第一。 两者 `start` 财务报告和审定财务报表 `end` (非零),当窗口重叠时返回一个跟踪:它始于或在此之前 `end` 结束时或之后 `start`,两者均包含纳米秒;其中之一缺失的窗口不适用,如Tempo。 没有 `q` 窗外的每一个痕迹都归了. |
| `GET /api/traces/{traceId}` | 作为Tempo的追踪器 `{"batches": [{resource, scopeSpans: [{scope, spans}]}]}`这是 **没有** OTLP/JSON: (英语) `traceId`, (中文(简体) ), `spanId` 财务报告和审定财务报表 `parentSpanId` 是基础64, `kind` 财务报告和审定财务报表 `status.code` enum 名称 (`SPAN_KIND_SERVER`, (中文(简体) ), `STATUS_CODE_ERROR`),64位整数(时间, `intValue`)是十进制字符串,零值被省略,每个跨度有一个 `status` 对象。 短于32个十六进制字符的微量ID是左加法. 未知的痕迹:404 有一具空出的身体. 非六进制: 400 `trace IDs can only contain hex characters: invalid character 'x' at position N`。 。 。 . |
| `GET /api/v2/search/tags` | `scope` =: `span`, (中文(简体) ), `resource`, (中文(简体) ), `event`, (中文(简体) ), `link`, (中文(简体) ), `instrumentation`, (中文(简体) ), `intrinsic`,或缺席/`none` 为了他们所有人 答复 `{scopes: [{name, tags}], metrics}`: 任何存储跨度上看到的属性名称,每个列表排序,一个没有被忽略的名称的范围. 列出一个在单一范围内看到的名字. `limit` 每个列表都盖上。 未知范围: 400 `invalid scope: <scope>`。 。 。 . |

每400个查询路线是Tempo's:错误文本作为整个正文, `text/plain`。 。 。 . 搜索以 Tempo 的顺序验证 : `invalid start: strconv.ParseUint: parsing "abc": invalid syntax`, (中文(简体) ), `invalid limit: must be a positive number`, (中文(简体) ), `http parameter start must be before end. received start=10 end=5`, (中文(简体) ), `limit N exceeds max limit M`,然后是 TraceQL 查询,168 h 最大范围 财务报告和审定财务报表 `spans per span set exceeds 100. received N`。 。 。 .

### 跟踪QL

评估一个相位过滤器:

-   `{ }`, (中文(简体) ), `{ true }`, (中文(简体) ), `{ false }`
-   属性平等 : `.name`, (中文(简体) ), `span.name` 或者说 `resource.name` (引文如下: `span."user id"` (列入) `=` 字符串、整数、浮点或布尔
-   `&&` 二者之间;每个条件必须维持在相同的范围内

未扫描 `.name` 读取跨度的属性并返回资源。 类型比较 确切的说,除了这些整数和浮数比较数字。 任意时的数组属性匹配 元素确实如此.

其它的都是四百分之一 永远不是更松散的比赛

-   输入 Tempo 的解析器以 Tempo 的措辞和位置拒绝答案, 例如 `invalid TraceQL query: parse error at line 1, col 3: syntax error: unexpected IDENTIFIER` 页:1 `{ user.id = "u" }` (该点已缺失).
-   子集外的有效 TrackQL (`=~`, (中文(简体) ), `!=`, (中文(简体) ), `>`, (中文(简体) ), `||`,诸如 `status` 或者说 `duration`, (中文(简体) ), `event.`编号 :`link.`编号 :`parent.` 范围、管道、横幅操作器、提示) `invalid TraceQL query: <construct> not yet supported (Mockingbird emulates a TraceQL subset)`。 。 。 . 第一部分是Tempo对它缺乏的特性的验证器用途;一个真正的Tempo 评估这些查询.

### 认证和租户

Tempo本身认证了没有人;它前面的网关也认证了. 模拟器同时播放:

| 设置 | 效果 |
| --- | --- |
| 无( 默认) | 本地的Tempo:不需要证明. |
| `bearerTokens` (单位:千美元)`--bearer-token`(中文(简体) ) | `Authorization: Bearer <token>` 在摄入和询问. |
| `basicUsers` (单位:千美元)`--basic-auth user:password`(中文(简体) ) | `Authorization: Basic …`,"格拉法纳云"风格(Intance id and access sord). |
| `unauthorized` | 遗失或错误证书的答复: `{status, body, contentType}` 与 `status` 401 或 403, 默认 401 `Unauthorized` 作为纯文本。 把它设定在你的网关答案. |
| `multitenancy` (单位:千美元)`--multitenancy`(中文(简体) ) | 温柔的 `multitenancy_enabled`数字 : `X-Scope-OrgID` 租户只读写着什么。 没有标题的查询路由是 401 `no org id`; 没有它的导出为 503 `{"code":14,"message":"no org id"}`。 。 。 . `a|b` 在查询中看到两个房客。 关闭,标题被忽略. |
| `leftPadTraceIds` (单位:千美元)`--left-pad-trace-ids`(中文(简体) ) | 温柔的 `left_pad_trace_ids`: 搜索回答 32-特征痕量标识. 关闭( Tempo 的默认值), 引导为 0 . |
| `defaultLimit`, (中文(简体) ), `maxLimit` | 搜索默认值(20)和最大值(262144)结果计数. |

熊克令牌和 Basic 用户可以一起配置;一个请求需要匹配的.

### 管理员(超过标准合同)

| 路线 | 效果 |
| --- | --- |
| `POST /__admin/traces` | `{resourceSpans: [...], tenant?}`:按给定的准确存储OTLP/JSON输出,没有证书,断层或租户头条。 跨度没有 `startTimeUnixNano` 以模拟时钟(`POST /__admin/clock`页:1 `endTimeUnixNano` 结束了。 答复 `{accepted, tenant, traceIds}`。 。 。 . |
| `GET /__admin/traces` | `{traces: [{tenant, traceID, spanCount, rootServiceName, rootTraceName, startTimeUnixNano, durationMs}]}`,最古老的第一. `?tenant=` 缩小它. |
| `GET /__admin/spans` | `{spans: [...]}`:所储存的跨度(电线外形旁的外形). `?traceId=`, (中文(简体) ), `?tenant=`。 。 。 . |
| `GET /__admin/settings`, (中文(简体) ), `PUT /__admin/settings` | 上面的设置, 用于调用命名空间 . `POST /__admin/reset` 返回它们的默认值. |

即时快照( A)`POST /__admin/snapshots`, (中文(简体) ), `POST /__admin/snapshots/:id/restore`检查站, 重置,时钟,请求日记和度量衡是标准合同. 日记记录 一个出口发生, 以及它碰到的追踪编号, 从不横跨内容.

错误预设( E)`POST /__admin/faults {"preset": "<name>", "count"?: n}`· ; `"count": 1` 是一个 一发; `GET /__admin/faults/presets`: `ingest_unavailable` (503,出口商复试), `ingest_rate_limited` (429个) `RATE_LIMITED: …`重审, `ingest_server_error` (500个,已放弃), `ingest_dropped` (连接会死), `query_unavailable` (503个), `query_server_error` (500个) `internal error`, (中文(简体) ), `query_rate_limited` (429个) `too many outstanding requests`, (中文(简体) ), `query_timeout` (504个) `context deadline exceeded`, (中文(简体) ), `query_dropped`, (中文(简体) ), `unauthorized` (单位:千美元) 在每个路线上配置了401). 错误的答案 `google.rpc.Status` 在请求中 编码.

### 命名空间

平行的工人每人得到自己的商店 `x-mockingbird-namespace`时 `/__admin/ns/<name>` 前缀在基准 URL上,或者通过证书: `PUT /__admin/credentials {"credentials": {"<bearer token or Basic username>": "<namespace>"}}`。 。 。 . 租户(`X-Scope-OrgID`)是命名空间内相隔的一堵墙.

### 核实了什么

没有Tempo实例。 每一种行为都从Grafana的文档中读取,或者 Tempo出自(v3.1.0)和OpenTeleometry收集器的OTLP接收器(v.0.153.0,即Tempo) 内嵌:

-   搜索参数、默认、验证顺序和信件: `pkg/api/http.go` (单位:千美元)`ParseSearchRequest`, (中文(简体) ), `modules/frontend/search_handlers.go`, (中文(简体) ), `search_sharder.go`。 。 。 .
-   搜索和标记响应字段及 JSON 类型 : `pkg/tempopb/tempo.proto` 和gogo合唱 `jsonpb` 缺省数(`modules/frontend/combiner/common.go`),以及所记录的例子.
-   最新的第一订单, 重叠窗口, 修剪的痕量标识, `<root span not yet received>`数字 : `pkg/traceql/combine.go`, (中文(简体) ), `tempodb/encoding/vparquet5/block_traceql.go`, (中文(简体) ), `pkg/util/traceid.go`, (中文(简体) ), `modules/frontend/combiner/search.go`。 。 。 .
-   `batches`,基数64的标识,enum名称并按标识进行跟踪排序;无身体的404: `pkg/tempopb/trace_utils.go`, (中文(简体) ), `pkg/model/trace/sort.go`, (中文(简体) ), `modules/frontend/combiner/trace_by_id.go`,以及"Push 横跨 HTTP"中的例子.
-   标记范围、排序和内在列表 : `pkg/api/search_tags.go`, (中文(简体) ), `modules/frontend/tag_handlers.go`, (中文(简体) ), `pkg/search/util.go`, (中文(简体) ), `pkg/collector`。 。 。 .
-   TraceQL 令牌、 属性法和出错位置 : `pkg/traceql/lexer.go`, (中文(简体) ), `parse.go`,以及 预计错误 `parse_test.go`。 。 。 .
-   OTLP的答复和错误:收集器 `receiver/otlpreceiver/otlphttp.go` 财务报告和审定财务报表 `internal/errors/errors.go`; id 检查 `modules/distributor/distributor.go`。 。 。 .
-   `no org id`页:1 `middleware.AuthenticateUser` 用于查询的 Tempo 接收器中间软件 摄取;跨租户读作:"交叉租户查询联合会".

**未核实** (来源,或选择来源于无)

-   错误证书的默认为 401 。 它属于Tempo(格拉法纳)的门户 云体没有文件; 配置 `unauthorized` 来配合你的.
-   在Tempo的解析测试中 解析-错误文本 。 模拟器从不附加goyacc的 `, expecting …` 列表,但测试确认的除外,以及一些位于外部的无效输入 子集作为“尚未支持”而不是作为语法错误报告.
-   不可解码导出的 400 信件文本( 状态、 代码 3 和编码为 接收器的;其解码器的措辞没有复制),并且为错误长度的id 接收器在Tempo的经销商拒绝之前就拒绝.
-   第503条 `no org id` 用于不包含 `X-Scope-OrgID` 多重租户: 接收者映射出纯错误到 `UNAVAILABLE`,没有观察到.
-   `metrics` 搜索和标记中的值(`inspectedBytes`, (中文(简体) ), `inspectedTraces`:合成.
-   `serviceStats`,并属性匹配的跨度列表:取自引擎源代码和 而不是现场回应.
-   未瞄准标记响应中的范围顺序( Tempo's 是无命令的), 开始的痕迹顺序 在同一纳秒(模拟器使用微量id)上,它跟踪到一个 `limit` 保存 : Tempo"取出平行搜索的第一个N结果",模拟器总是保留最新的.
-   404的路径Tempo不服务(`404 page not found`) (中文(简体) ).
-   查询断层的正体预设 `internal error`, (中文(简体) ), `too many outstanding requests` 财务报告和审定财务报表 `context deadline exceeded`。 。 。 .

### 故意不模拟

-   Grafana UI、仪表板、PromQL和度量衡; TraceQL度量衡(`/api/metrics/query_range`(中文(简体) ) 和度量衡生成器.
-   Full TraceQL:只有上面的子集被评价,其他的都是400.
-   标记搜索在 TraceQL 之前(`tags=`, (中文(简体) ), `minDuration`, (中文(简体) ), `maxDuration`),过滤后标签 名称 (`q` 标记路由中),标记值,以及 v1 标记路由:拒绝或缺席.
-   `GET /api/v2/traces/{id}` 财务报告和审定财务报表 `Accept: application/protobuf` 答案是JSON.
-   块角时间范围 : `start`编号 :`end` 由 id 和 标记 进行验证,然后忽略 (模拟器是一个总是重叠的块).
-   尾部取样、摄取限度、保留、收缩、分布式储存以及延迟 摄入和可搜索性之间:存储的跨度一并可见.
-   OTLP/gRPC、Jaeger和Zipkin接收器;OTLP记录和计量.
-   管理、提供、推翻和云资源创造.
-   Span-id 为 Zipkin 风格的共享代号, 以及 Tempo 的根- span并服务 有关痕迹的统计数字分布在几个租户.

发送64位OTLP/JSON值(时间戳, `intValue`作为字符串,如出口商所做的:JSON号码 过去2^53在模拟者看到它之前失去精度. 不符合原生体的值 宽度、 长度和属性值误差的 id 值被拒于100 个深层 和一个400.

## API 密码

| 导出 | 仁爱 | 说明 |
| --- | --- | --- |
| `TempoAPI` | 类 | 进程模拟器 : `fetch(request)`, (中文(简体) ), `reset()`, (中文(简体) ), `inject(payload, tenant?)`, (中文(简体) ), `spans(filter?)`, (中文(简体) ), `traces(tenant?)`选项: `sqlite`, (中文(简体) ), `now`, (中文(简体) ), `namespace`, (中文(简体) ), `settings`。 。 。 . |
| `createRuntime` | 函数 | 全面服务合同(保健、行政管理、命名空间、证书、预设、钟表、检查站)的仿真者。 选项 : `settings`, (中文(简体) ), `clock`, (中文(简体) ), `seed`, (中文(简体) ), `adminPrefix`, (中文(简体) ), `adminKey`, (中文(简体) ), `onLog`, (中文(简体) ), `sqlite`。 。 。 . |
| `TEMPO_PRESETS` | 对象 | 每个命名的断层预设. |
| `TEMPO_NAMESPACE` | 字符串 | 服务名称, `"tempo"`。 。 。 . |
| `DEFAULT_SETTINGS` | 对象 | 命名空间开始的设置 . |
| `SINGLE_TENANT` | 字符串 | Tempo的房客,当多租房关闭, `"single-tenant"`。 。 。 . |
| `ORG_ID_HEADER` | 字符串 | `"x-scope-orgid"`。 。 。 . |
| `ROOT_SPAN_NOT_YET_RECEIVED` | 字符串 | `rootServiceName` 一个没有根茎的痕迹. |
| `INTRINSIC_TAGS` | 数组 | 名称 `intrinsic` 标记范围. |
| `tempoCredential` | 函数 | 请求的无记名符号或基本用户名( 如何将证书映射到命名空间) . |
| `parseTraceQL`, (中文(简体) ), `matchesSpan`, (中文(简体) ), `TraceQLError` | 函数,类 | TraceQL子集:解析一个查询,测试一个跨度的属性对它,以及消息后面的错误 `invalid TraceQL query:` 。 。 。 . |
| `decodeSpans`, (中文(简体) ), `validateIds`, (中文(简体) ), `OtlpError` | 函数,类 | OTLP/JSON出口在Tempo的电线形状、Tempo的ID检查和拒绝出口引起的错误. |
| `decodeTraceRequest`, (中文(简体) ), `encodeRpcStatus`, (中文(简体) ), `decodeRpcStatus`, (中文(简体) ), `ProtobufError` | 函数,类 | 原生植物 `ExportTraceServiceRequest` 解码器和 `google.rpc.Status` 密码. |
| `hexToBase64`, (中文(简体) ), `base64ToHex` | 函数 | 在OTLP的六分法和Tempo的基数64之间转换ID. |
| `document`, (中文(简体) ), `operationIds`, (中文(简体) ), `supportedOperationIds` | 数值 | OpenAPI合同及其操作代号. |
| `createServer`, (中文(简体) ), `serveTarget`, (中文(简体) ), `DEFAULT_PORT` (单位:千美元)`./server`(中文(简体) ) | 节点 | 服务过来 `node:http`; 数据 `serve` CLI目标; 第8930口. |

部分 [嘲笑鸟](https://github.com/crvouga/mockingbird)。 。 。 .

## 常见问题

### @crvouga/mockingbird-service-tempo 是什么？

Grafana Tempo的模拟器:OTLP/HTTP 追踪摄入\(JSON和protobuf\),追踪QL搜索,由ID进行追踪和在一个租户范围商店上发现标记名称\.

### 如何安装 @crvouga/mockingbird-service-tempo？

在项目目录运行 npm install @crvouga/mockingbird-service-tempo，或使用 pnpm add / yarn add / bun add。它还提供命令行工具 mockingbird-tempo，可以用 npx mockingbird-tempo 直接运行。

### @crvouga/mockingbird-service-tempo 支持 TypeScript 吗？

支持。包内自带 TypeScript 类型声明（package\.json 声明了 types 入口），安装后即可获得类型提示，无需再安装 @types 包。

### @crvouga/mockingbird-service-tempo 支持 ESM 还是 CommonJS？

以 ES Module 形式发布，推荐使用 import 引入。在 CommonJS 项目中，Node\.js 20\.19\+ / 22\.12\+ 可以直接 require\(\) 不含顶层 await 的 ES Module，更早的版本需要改用动态 import\(\)。

### @crvouga/mockingbird-service-tempo 可以商用吗？

@crvouga/mockingbird-service-tempo 使用 MIT 许可。宽松许可：允许商业使用、修改和再分发，通常只需在分发时保留原版权与许可声明。以上为概括，不构成法律意见，请以许可原文为准。

### @crvouga/mockingbird-service-tempo 的下载量有多少？

根据 npm 官方下载统计，@crvouga/mockingbird-service-tempo 在 2026/10/11 – 2026/11/09 这 30 天内被下载 2,381 次，日均约 79 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入，适合横向比较热度，不能直接等同于使用人数。

### @crvouga/mockingbird-service-tempo 还在维护吗？

最新版本 0\.10\.0 发布于 2026/11/11（今天）；至今共发布 16 个版本，其中过去 12 个月发布了 16 个；首次发布于 2026/10/11。发布频率只是参考信号：功能稳定的工具可能很少需要更新，建议结合源码仓库的 issue 和提交记录判断。

