# @displayxr/inline3d 中文文档

规范地址：https://npmcn.com/package/%40displayxr/inline3d/

版本：1\.52\.3
npm 元数据更新时间：2026-11-11T21:58:43.266Z
中文译文更新时间：2026-11-12T12:19:18.334Z
软件包许可：Apache-2\.0

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

原始 npm 页面：https://www.npmjs.com/package/%40displayxr/inline3d
原文对照：https://npmcn.com/package/%40displayxr/inline3d/?lang=original
项目主页：https://displayxr.github.io/displayxr-web/
源码仓库：https://github.com/DisplayXR/displayxr-web

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

- 包体积（解压后）：3.1 MB，100 个文件
- 模块格式：ES Module
- TypeScript 类型：包内自带
- Node.js 要求：\>=18
- 运行依赖：0 个
- peer 依赖：three \>=0\.150\.0，playcanvas \>=2\.22\.3 \<3，meshoptimizer \>=1\.0\.0，@sparkjsdev/spark \>=2\.0\.0
- 首次发布：2026-07-20T03:55:24.809Z
- 最新版本发布：2026-11-11T21:58:42.946Z
- 近 30 天下载量：4017（2026-10-13 至 2026-11-11，npm 官方下载统计）
- 已发布版本数：88（近 12 个月 88 个）

## 中文简介

将 HTML 转换为空间显示上的3D 窗口,在普通网页内,用于显示XR 浏览器。 无依赖性; 渐进增强(回到平原 2D 其他任何地方).

## 安装

```sh
npm install @displayxr/inline3d
```

也可以使用：`pnpm add @displayxr/inline3d`、`yarn add @displayxr/inline3d`、`bun add @displayxr/inline3d`

## README

# 显示xr-web

内入- 3D **网络样本** 和一个小JS SDK为 [显示 XR 浏览器](https://github.com/DisplayXR/displayxr-browser) - 显示XR模拟 [`immersive-web/webxr-samples`](https://github.com/immersive-web/webxr-samples)。这是峡谷 repo 网页开发者克隆以构建用于空间显示的 三维页面,浏览器浏览的站点用于 现场演示.

**{\\fn黑体\\fs22\\bord1\\shad0\\3aHBE\\4aH00\\fscx67\\fscy66\\2cHFFFFFF\\3cH808080}见现场直播:** [https://displayxr.github.io/displayxr-web/ 互联网档案馆的存檔,存档日期2013-12-21](https://displayxr.github.io/displayxr-web/) - 打开 [显示 XR 浏览器](https://github.com/DisplayXR/displayxr-browser/releases) 在空间显示上看到 在3D中; 在任何其他浏览器中, 页面渲染为正常的2D倒置, 因此可以安全查看 随便哪里.

> **新来的还是人工智能编码代理? 读取 [三维显示器的深度和舒适度](https://npmcn.com/package/%40displayxr/inline3d/docs/making-3d-look-right.md) 第一条:** 9条规则来自真实的面板;其余则由SDK默认.

## 安装

SDK发布为 **[`@displayxr/inline3d`](https://www.npmjs.com/package/@displayxr/inline3d)** (无依赖的无害环境管理,船舶本身的类型:

```sh
npm install @displayxr/inline3d
```

```js
import { createInline3D } from '@displayxr/inline3d';
import { EyeCamera, EdgeFeather } from '@displayxr/inline3d/three'; // optional three.js glue
import { addSplat } from '@displayxr/inline3d/splat';               // experimental: 3DGS in a tile
//   …or '@displayxr/inline3d/splat/playcanvas': the same addSplat on PlayCanvas, without the
//   three + Spark download (use it whenever you pass engine: 'playcanvas')
import { addModel } from '@displayxr/inline3d/model';               // experimental: glTF/GLB in a tile
                                                                    //   (Draco / meshopt / KTX2 too —
                                                                    //    you serve the decoder files)
import { addPlayer } from '@displayxr/inline3d/player';             // preview: a media player, built
                                                                    //   on addVideo, with transport
import { SceneViewer } from '@displayxr/inline3d/viewer';           // experimental: framing + orbit
import { handControls } from '@displayxr/inline3d/hands';          // experimental: tracked hands,
                                                                    //   pinch to orbit (or `hands: true`
                                                                    //   on addModel / addSplat)
```

不需要建构步骤或捆绑器——它是简单的ES模块. 也可以导入被绑定的版本 从 CDN (jsDelivr / unpkg) 不包含 npm 的 URL 。 此 repo 中的样本通过相对导入 SDK 路径( r)`./js/inline3d.js`),所以他们直接从GitHub Pages上跑出;在你自己的应用中更喜欢这个软件包.

`three`, (中文(简体) ), `@sparkjsdev/spark`, (中文(简体) ), `playcanvas` 财务报告和审定财务报表 `meshoptimizer` 为: **可选同伴依赖关系** ——核心是无依赖的,只有场景子路径需要它们(`/model` 需求 `playcanvas`, (中文(简体) ), 或者说 `three` 与 `engine: 'three'`) (中文(简体) ). 两个取景器子路径是 **实验**:它们把"一分一分"的"一分一分"变成"一分一分"的"一分一分"的"一分一分一分"的"一分一分一分"的"一分一分一分一分"的"一分一分一分"的"一分一分一分"的"一分一分一分一分"的"一分一分一分一分"的"一分一分一分一分一分"的"一分一分一分一分一分"的"一分一分一分一分一分一分一分一分一分一分一分一分一分一分一分一分一分一分一分一分一分一分一分一分一分一分一分一分一分一分一分一分一分分一分一分一分一分一分一分一分一分一分一分一分一分一分一分一分一分一分一分一分一分一分一分一分一分一分一分分一分一分一分一分 调用(零相差平面、轨道、闲置转盘、单倒转),但 API尚未包含在下面的铸币承诺中.

**第二台平板引擎(预览).** `addSplat(wall, canvas, src, { engine: 'playcanvas' })` 使同样的平板窗口与 [播放 Canvas 游戏](https://playcanvas.com/) 引擎替换为 Spark——相同的手柄,相同的钻机/焦点/相机-挡板行为,相同的 `perf` 预设( 映射到 引擎的节点)——并添加 `setSource(src, { fadeMs })` (交叉资产交换), `feather`页:1 倾斜而放鬆的轨道 二指相接 外加可放鬆回休息的有束缚的缩放 (单位:千美元)`zoom: { min, max, relax }`, (中文(简体) ), [§Zoom 约束和放松](https://npmcn.com/package/%40displayxr/inline3d/docs/playcanvas-adapter.md#zoom-bounds-and-relax), (中文(简体) ), `handle.engine` (引擎对象,用于高级页)和 `handle.setRig('display' | 'camera' | 'auto')`一个活的、可逆的钻机开关, 所以一个持久的瓦片 可以在下方显示 glTF `handle.engine.root` 完全一样 `addModel` {\\fn黑体\\fs20\\shad2\\2ah82\\3ah20\\4ah33\\fscx95\\3ch592001\\be1}然后回到照片上 {\\fn黑体\\fs20\\shad2\\2ah82\\3ah20\\4ah33\\fscx95\\3ch592001\\be1}然后回到照片上 捕获钻机[§setRig 键](https://npmcn.com/package/%40displayxr/inline3d/docs/playcanvas-adapter.md#setrig--switching-between-the-display-rig-and-the-camera-rig-36)),以及 `handle.setVideo(src, { format: 'sbs' | 'tb' | 'mono' })`:一个立体视频 在同一瓷砖上,每个眼睛 自己的一半,没有第二张画布[§set视频](https://npmcn.com/package/%40displayxr/inline3d/docs/playcanvas-adapter.md#setvideo--a-stereo-video-on-the-persistent-handle-36)) (中文(简体) ). 这需要 选项对等点 `playcanvas` (单位:千美元)`>=2.22.3 <3`并读 `.sog`, (中文(简体) ), `.ply` 和流式SOG `lod-meta.json`。 。 。 . **Spark 保留默认**; 从未经过的一页 `engine` 从不装载 `playcanvas`。什么是不同的,为什么: [`docs/playcanvas-adapter.md`](https://npmcn.com/package/%40displayxr/inline3d/docs/playcanvas-adapter.md)。 。 。 . Repo的花样样本(`samples/splat/`)用 Play Canvas 制作并保存 `?engine=spark` 作为 其A/B开关. Bundlers:通过命名-进口模块到达引擎(`js/inline3d-playcanvas-engine.js`, (中文(简体) ), 因此,未使用的~40%的引擎树摇走;其类工人是 Blob URL(CSP) `worker-src blob:`),以及重建需求 `node:worker_threads` 外标。 将引擎固定到一个 准确版本 : `playcanvas@2.24.0` (a) 建议样品装载内容 2.24.0 全部在面板和平板上验证([细节](https://npmcn.com/package/%40displayxr/inline3d/docs/playcanvas-adapter.md)) (中文(简体) ).

**平板效应(审查, `engine: 'playcanvas'`) (中文(简体) ).** 震动作用于花板本身, 以世界位置和时间为键 所以两只眼睛都同意: `addSplat(…, { reveal: 'inflate' | 'sweep' | 'dissolve' | 'fade' | 'assemble' | 'dissolve-in' | 'converge' | 'shimmer' })` (玩一次砖块) 已编织而成;后四件是微粒, `handle.playEffect` 编号 : `setEffect` 编号 : `stopEffect` 编号 : `effects()` (揭示、解开、脉冲、分级、剪辑、自定义的GLSL)和 `setSource(src, { transition: 'crossfade' | 'flip' | 'wavefront', reveal })`闪光 暂时把它们都扔了. [`docs/splat-effects.md`](https://npmcn.com/package/%40displayxr/inline3d/docs/splat-effects.md)。 。 。 .

PlayCanvas后端上的平板和模型渲染使用PlayCanvas引擎(MIT);参见 [`THIRD_PARTY_NOTICES.md`](https://npmcn.com/package/%40displayxr/inline3d/THIRD_PARTY_NOTICES.md)。 。 。 .

**模型默认与 PlayCanvas (1. 12) 一起渲染 .** `addModel(wall, canvas, 'chair.glb')` 负载 带有 PlayCanvas 引擎的 glTF( 可选的对等点) `playcanvas`),点亮以匹配 Khronos glTF 样本查看器:一个模拟中性工作室环境,Khronos PBR中性语气映射, 接触 1. `environment: 'room'` 给三个房间环境取而代之 3条路径). `engine: 'three'` 是1.11 三.js的渲染器,不变(也可导入为 `@displayxr/inline3d/model/three`) (中文(简体) ). 每个引擎只有在一瓷砖要求时才会被导入. 德拉克语Name 和KTX2在两个引擎上使用相同的已装入的解码器文件夹. 设计, 样本查看器 MAE 表格 和抛出的东西: [`docs/playcanvas-model-backend.md`](https://npmcn.com/package/%40displayxr/inline3d/docs/playcanvas-model-backend.md)。 。 。 .

**大场景流 (评论).** 打开 `engine: 'playcanvas'`,一个流出 SOG 流:通过 URL 联 合 国 `lod-meta.json` (或其目录),不是它的字节. 引擎只取块 视图最多需要并绘制 `perf.splatBudget` 他们。 这笔预算是按瓦片分配的 以平板的每个视图显示;它默认为600k 在流出 SOG上. `handle.stats()` 报告什么 是居民。 这是用来拍大片的 有几百万加西人 摄影电梯是 一个完全在屏幕上的密集工作表,所以它从流出中没有任何收益。 如何生产、服务 和预算一,包括测量: [`docs/playcanvas-adapter.md` § 结构化的 SOG](https://npmcn.com/package/%40displayxr/inline3d/docs/playcanvas-adapter.md#streamed-sog-p2)。 。 。 .

**游戏拥有相机(预览).** `addSplat(wall, canvas, src, { engine: 'playcanvas', controls: 'page', onBeforeFrame })` 将相机放到页面上。 打电话 `handle.setCameraPose(matrixWorld, { verticalFovDeg, near, far, convergence? })` 内部 `onBeforeFrame` 而这个框架使得它。 SDK不运行轨道、闲转、合身或聚焦 手势。 它保持了眼睛的数学: 相机相机平台(自动-3D shim's, with `comfortDepth` 0.3默认),运行时间的预测,和单回倒数. 火花拒绝 此模式 。 合同和编号: [`docs/playcanvas-adapter.md` § 控制:'page'](https://npmcn.com/package/%40displayxr/inline3d/docs/playcanvas-adapter.md#controlspage--the-page-owns-the-camera)。 。 。 .

稳定性和Semver覆盖的内容(和被推迟的N-视图/网络组件/CSS-内生路线图) 故意这样做 **没有** 在1.0中: [`docs/sdk-stability.md`](https://npmcn.com/package/%40displayxr/inline3d/docs/sdk-stability.md)。 。 。 .

## 快开始

一个SDK电话转动 `<canvas>` 进入空间显示的 三维窗口。 所有东西都退化成平地2D 非DisplayXR浏览器,所以一个页面可以安全地在任何地方发行.

```js
import { createInline3D } from '@displayxr/inline3d';

const wall = await createInline3D();       // opens an inline-3d session (detects support)
if (!wall.supported) {
  // Not the DisplayXR Browser (or no 3D display) — your page's normal 2D content shows. Done.
} else {
  // Woven 3D. Add content — one call per element:
  wall.addImage(canvas, 'photo-sbs.png');                  // a still side-by-side 3D photo
  wall.addVideo(canvas, videoEl);                          // an SBS 3D video
  wall.addScene(canvas, (views, layer) => { /* render */ });// a live three.js / WebGL stereo scene
}
```

浏览器将每个元素的立体对编织在屏幕上的矩形上;周围的DOM保持平平. 运行时间将每个可见的窗口分批编成每帧一个编织,从而缩放成一堵元素墙.

大部分页面想要默认——a **显示平台**,在画布是虚拟窗口的地方 显示和运行时间放置眼睛。 包括每个场景 框架a _主题_ (一个模型) 或花板取景器,相机,产品英雄) **即使在用户运行时**: 旋转主题, 而不是相机, 和立体声出来 同样一个佛果和飞机。 如果页 已经有一个轨道相机,保持它 并摆出门户从它:

```js
import * as THREE from 'three';
import { displayRig } from '@displayxr/inline3d/three';
// An orbit viewer (OrbitControls): pose the portal at the orbit target, facing the camera, as
// tall as the camera's view there. The target sits on the glass at any window size and zoom.
const rig = {};
function orbitRig() {
  const d = camera.position.distanceTo(controls.target);
  const vH = 2 * d * Math.tan(THREE.MathUtils.degToRad(camera.fov) / 2);
  return displayRig({ position: controls.target, orientation: camera.quaternion, virtualDisplayHeight: vH, out: rig });
}
const handle = wall.addScene(canvas, onFrame, { viewRig: orbitRig() });
// in onFrame, before rendering the eyes: handle.setViewRig(orbitRig());
```

用户视角的场景 _穿越一个世界_ ——第一人称,走过,游戏 映射、编辑器、移植的 VR app —— 可以将自己的相机交给运行时间, 并让目视 追踪那个混蛋 这是 **相机设备**数字 :

```js
import { cameraRigFromCamera } from '@displayxr/inline3d/three';
const handle = wall.addScene(canvas, onFrame, { viewRig: cameraRigFromCamera(THREE, cam, { convergence: 1.2 }) });
handle.setViewRig(cameraRigFromCamera(THREE, cam, { convergence: 1.2, out: rig }));  // per frame
```

没有投影数学在你的页面或SDK中着陆——离轴花纹会停留在运行时间. 见 [视图钻机](https://npmcn.com/package/%40displayxr/inline3d/docs/authoring-inline-3d.md#view-rigs-display-vs-camera) 财务报告和审定财务报表 [`samples/camera-rig/`](https://npmcn.com/package/%40displayxr/inline3d/samples/camera-rig/)。 。 。 .

> **检测 :** 调用 `createInline3D()` 检查 `wall.supported` - 这样做 **没有** 打开门 `navigator.xr.isSessionSupported('inline-3d')`自动探测器解决了 `false` 如果它运行之前 OS编织服务已经捆绑了(通常在页面负载时),一种虚构-负式,默默地将您降为2D. `createInline3D()` 通过实际获取具有权威性的会话来检测.

> **没有人在展示前?** `wall.trackingState` 实值 `'tracking'`, (中文(简体) ), `'searching'` 或者说 `'unknown'`,以及 `wall.on('trackingstatechange', state => …)` 当它移动时告诉你 手柄也同时带有. `'searching'` 意味着没有人被跟踪: 观众离开了 显示3D区域,或者面板处于2D模式。 在 MANAGED 显示器上(默认和Leia) 卖家已经走了2D,所以只用它来暗示。 在曼努尔展示, `createInline3D({ untrackedFallback: 'mono' })` 轻松 `addImage` 编号 : `addVideo` 窗户为您平坦. `'unknown'` 是“无意见” (旧浏览器,或闭会): 正常渲染。 见 [知道没有人被跟踪](https://npmcn.com/package/%40displayxr/inline3d/docs/authoring-inline-3d.md#knowing-when-nobody-is-tracked)。 。 。 .

完整 API + 作者指导 : [`docs/authoring-inline-3d.md`](https://npmcn.com/package/%40displayxr/inline3d/docs/authoring-inline-3d.md)。 。 。 . 在运送导航或重载的页面前,请读 [`docs/woven-canvas-rules.md`](https://npmcn.com/package/%40displayxr/inline3d/docs/woven-canvas-rules.md):如何避免生地相并 并发布海报 `handle.firstWoven`在窗口中互换内容的页面(a) 木马,目录: [`docs/content-lifecycle-rules.md`](https://npmcn.com/package/%40displayxr/inline3d/docs/content-lifecycle-rules.md)。 。 。 . 三.js胶水(离轴) `EyeCamera`(单位:千美元) [`js/inline3d-three.js`](https://npmcn.com/package/%40displayxr/inline3d/js/inline3d-three.js)。 。 。 .

## 这是什么

```
index.html            landing (Pages entry point)
samples/
  camera-rig/         the camera rig — an orbiting scene that sends its OWN camera each frame;
                      convergence + comfort, the attach pattern, C to A/B a display rig
  windows/            mixed 3D windows — still photos + a live video + a real-time three.js scene,
                      each woven with one SDK call, all on one session
  splat/              a 3D Gaussian splat in a tile (PlayCanvas; ?engine=spark), with a 2D plate over it
  model/              a glTF mesh, a mesh+splat scene, and a Draco-COMPRESSED glTF (PlayCanvas; ?engine=three)
  player/             a media player — SDK transport (play/pause/seek/mute), one call, built on
                      addVideo; default (SBS) and format:'mono' side by side
  composition/        the 14-case 2D/3D overlap matrix — demo AND standing hardware regression
                      surface; red cases ship red (see samples/README.md)
vendor/draco/         three's Draco decoder, served for samples/model (compressed glTF needs it)
js/
  inline3d.js         the SDK: createInline3D() → { addImage, addVideo, addScene }, feature-detect,
                      SBS buffer management, and a lazy create/close lifecycle for many windows
  inline3d-three.js   optional three.js helper (EyeCamera: off-axis projection from the session's eyes)
  inline3d-viewer.js  experimental: SceneViewer — framing, orbit, idle turntable, mono fallback,
                      and the placement readback (getSubjectBounds / getPose / depthOffset)
  inline3d-splat.js   experimental: addSplat() — a Gaussian splat window via Spark
                      (`perf` cuts overdraw; a `.sog`'s `camera` block picks the view rig)
  inline3d-splat-playcanvas.js
                      preview: the `engine: 'playcanvas'` backend of addSplat(), loaded on demand
  inline3d-model-entry.js       experimental: addModel() — picks the engine (PlayCanvas default)
  inline3d-model-playcanvas.js  the PlayCanvas model backend (Sample-Viewer lighting, engine decoders)
  inline3d-pc-look.js           PlayCanvas look helpers for both adapters (environments, transmission)
  inline3d-pc-release.js        handle.releaseEntity: content under engine.root out, its programs + container released
  inline3d-pc-shader-cache.js   engine fix: a compiled shader is deleted with the last program using it
  inline3d-model.js             the three.js model backend (engine:'three'; ./model/three)
  inline3d-playcanvas-engine.js named playcanvas imports for both PlayCanvas adapters (tree-shaking)
  inline3d-splat-effects.js     splat shader effects: the runner, the effect registry (PlayCanvas)
  inline3d-splat-live.js        setSource's live outgoing photo: its own camera, layer and target (PlayCanvas)
                      from what the asset declares (you serve the decoder files — see the guide)
  inline3d-player.js  preview: addPlayer() — a media player window built on addVideo (stereo
                      paint, display modes and the fallback are inherited) + an SDK transport bar;
                      attachPlayer() — the same player on a PlayCanvas splat handle's setVideo
docs/
  authoring-inline-3d.md   the authoring guide
  authoring-motion-and-effects.md
                           motion, transitions and per-eye effects — the half of authoring
                           that is not the API
  porting-three-js-apps.md porting an existing three.js app (WebXR or plain) to inline 3D —
                           the WebXR→inline-3d mapping table and the whole render loop
  woven-canvas-rules.md    never show a raw side-by-side frame: the join, the rules,
                           handle.firstWoven / rewoven(), reading the browser's `withheld` log line
  content-lifecycle-rules.md
                           release what a content swap replaces (programs included):
                           handle.releaseEntity, engine facts, the hook-and-plateau pass test
  camera.md                The 3D camera primitive (/camera): openCamera, the mirrored self view,
                           capturePhoto / record with the stereo record inside the file.
  call.md                  3D video calls: the <dxr-call> / mountCall() one-line embed, options,
                           events, headless, theming, React, self-hosting, troubleshooting
  proposals/               browser-side asks the SDK is waiting on
```

## 内入- 3D 模型( 在 SDK 下)

如果您想要原始的 WebXR 显示 SDK 包, 一个内入到3d 元素 :

1.  `const session = await navigator.xr.requestSession('inline-3d')` - 无感应内在会话 (feature-detect由这个解析度是否决定;倒回平原 2D).
2.  `const layer = new XRDisplayLayer(session, canvas)` ——将织物与该元素相接.
3.  每个 XR 帧: 使场景成为 **相邻立体对** 进入画布,重新投影 **离轴** (非对称-frustum / Kooima) 从眼睛的位置,届会报告的框架—— 所以移动你的头看起来 _周围_ 3D内容.

见 [WebXR 内行-3D 解释器](https://github.com/DisplayXR/displayxr-runtime/blob/main/docs/roadmap/webxr-displayxr-explainer.md)。 。 。 .

## 本地预览

任何静态服务器,例如:. `python -m http.server 8080`,然后打开 `http://localhost:8080/`。 。 。 . (过去) `file://` 纯-2D的罚款,但 WebXR 需要 **安全环境** ——使用 `http://localhost` 或者说 `https://`. ) (中文(简体) )

## 常见问题

### @displayxr/inline3d 是什么？

将 HTML 转换为空间显示上的3D 窗口,在普通网页内,用于显示XR 浏览器。 无依赖性; 渐进增强\(回到平原 2D 其他任何地方\)\.

### 如何安装 @displayxr/inline3d？

在项目目录运行 npm install @displayxr/inline3d，或使用 pnpm add / yarn add / bun add。

### @displayxr/inline3d 支持 TypeScript 吗？

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

### @displayxr/inline3d 支持 ESM 还是 CommonJS？

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

### @displayxr/inline3d 需要什么版本的 Node\.js？

package\.json 的 engines 字段要求 Node\.js \>=18。版本不符时 npm 默认只给出警告，开启 engine-strict 后会拒绝安装。

### @displayxr/inline3d 可以商用吗？

@displayxr/inline3d 使用 Apache-2\.0 许可。宽松许可：允许商业使用、修改和再分发，并附带明确的专利授权；分发时需保留许可与 NOTICE 文件，修改过的文件要注明改动。以上为概括，不构成法律意见，请以许可原文为准。

### @displayxr/inline3d 的下载量有多少？

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

### @displayxr/inline3d 还在维护吗？

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

