@datadog/mobile-react-native-openfeature

中文文档
3.11.0发布于 2026/10/20Apache-2.0TypeScriptESM + CJS构建来源已验证近 30 天下载 3.9万

一个客户端 React 本地模块,用于提供 OpenFeature 集成数据狗特性旗

中文使用文档
文档目录7 节
  1. 设置
  2. 使用量
  3. 初始化数据犬 SDK 和 OpenFeature
  4. RUM 用户背景
  5. 使用 OpenFeature 反应 SDK
  6. 手动配置的 JavaScript 评价
  7. 离线初始化

数据狗 OpenFeature 提供者 原生反应

使用 打开形状 与 数据犬特性旗 用于评价地标,并将评价数据发送给Datadog进行分析和实验.

OpenFeature是供货商中立,由社区驱动的规格和用于特征标志的SDK. 它为跨不同供应商的地物旗评价提供了统一的API. 这使得您可以切换销售商或整合多功能旗系统.

这个软件包提供了由 Datadog's Flags, a DatadogCoreProvider 用于手动提供的 JavaScript 评价的配置,以及离线 代表给 DatadogCoreProvider 同时保留原生追踪. DatadogCoreProvider 和基于规则的解析器从 @datadog/mobile-react-native-openfeature/rules-based 切入点 保留了原生生物规则 解析不使用它的程序.

设置

说明: 此软件包是用于 OpenFeature 反应 SDK。安装和设置核心 @datadog/mobile-react-native SDK使用本土后卫供应商. DatadogCoreProvider 使用相同的软件包依赖性,但不要求 Datadog SDK 初始化或 DdFlags.enable()。 。 。 .

要安装国家预防机制,运行:

npm install @datadog/mobile-react-native @datadog/mobile-react-native-openfeature @openfeature/react-sdk

要安装 Yarn, 请运行 :

yarn add @datadog/mobile-react-native @datadog/mobile-react-native-openfeature @openfeature/react-sdk

使用量

初始化数据犬 SDK 和 OpenFeature

使用以下示例代码片段来初始化"Datadog SDK",启用"地物旗"功能,并设置了"OpenFeature"提供者.

import { CoreConfiguration, DatadogProvider, DdFlags, DdSdkReactNative } from '@datadog/mobile-react-native';
import { DatadogOpenFeatureProvider } from '@datadog/mobile-react-native-openfeature';
import { OpenFeature } from '@openfeature/react-sdk';

(async () => {
    // Follow the core Datadog SDK initialization guide.
    const config = new CoreConfiguration(
        // ...
    );
    await DdSdkReactNative.initialize(config);

    // Enable Datadog Flags feature after the core SDK has been initialized.
    await DdFlags.enable();

    // Set the Datadog provider with OpenFeature.
    const provider = new DatadogOpenFeatureProvider();
    OpenFeature.setProvider(provider);
})();

// Alternatively, if using `<DatadogProvider />` for core SDK initialization.

<DatadogProvider
    configuration={coreConfiguration}
    onInitialized={async () => {
        await DdFlags.enable();

        const provider = new DatadogOpenFeatureProvider();
        OpenFeature.setProvider(provider);
    }}
>
    {/* ... */}
</DatadogProvider>

完成此设置后, 您的应用程序将准备使用 OpenFeature 进行旗下评估 .

说明:在使用Feature Flags SDK时,向Datadog发送旗帜评价数据是自动启用的. 提供 rumIntegrationEnabled 财务报告和审定财务报表 trackExposures 参数 DdFlags.enable() 调用配置 .

RUM 用户背景

使用 enrichWithRumUser() 当您明确想要使用当前 RUM 用户作为其中的一部分时 OpenFeature评价上下文. Datadog OpenFeature 提供者都没有自动丰富上下文. 这将通过 OpenFeature 来保持上下文变化的可见性并避免改变旗帜任务, 除非 您的应用程序选择加入.

帮助者将 RUM 用户ID 映射到 targetingKey地图 name, (中文(简体) ), email,和平整的字符串,数字, 或布尔 extraInfo 属性到评价属性。 合并优先级为 extraInfo, (中文(简体) ), 然后是 RUM 用户自己的身份字段,然后是应用程序上下文(最高优先级). targetingKey, (中文(简体) ), name,以及 email 内 extraInfo 遵循与其他属性相同的合并规则; 这些密钥不保留给特定来源。 帮助者不应用针对特定对象的键 校验: 数字或布尔值在合并后被覆盖, 不触发目标键 警告! 警告你们! 最终 targetingKey 必须是字符串(包括空字符串)。 如果一个非字符串值 到达 Datadogs 上下文处理层, 它记录一个 SDK 警告并使用匿名主题 (单位:千美元)''用于评价和跟踪,无论价值是否来自 extraInfo 或 应用。 它不会回落到低位身份或者改写OpenFeature的上下文. 因此应用程序值可以提供不同的目标键(例如设备或会话) 身份证。 当浓缩成功时,一个应用字段设定为 undefined 删除 对应 RUM 值,并在返回上下文中省略。 虚值和嵌入式 RUM 用户 属性不包括在内。 如果没有设置 RUM 用户, 包括之后 clearUserInfo(),帮助者 规范应用程序上下文,而不添加 RUM 值或记录警告。 实际失败 以读取 RUM 用户仍然生成 SDK 警告.

说明: 数字评价属性目前因平台而异: Android将其转换为 字符串( 例如, 42 可以变成 "42.0" 跨越反应原生桥),而iOS保存 数值。 为一致的跨平台设定目标,明确提供一致的格式 应用程序上下文中的字符串,或省去继承的数值属性 undefined。 。 。 .

如果SDK的核心 __ddEnrichEvaluationContextWithRumUser 帮助者失踪或无法调用, enrichWithRumUser() 日志控制台警告并返回原应用程序上下文,但不变, 包括任何 undefined 字段. OpenFeature 初始化和评价可以在没有 RUM 的情况下继续使用应用程序的上下文 数值。 更新核心 SDK 至少更新到 OpenFeature 软件包的版本, 检查复制 安装为 npm ls @datadog/mobile-react-native,并确保测试模拟保存真正的模块 出口(使用量) @datadog/mobile-react-native/jest 或扩展 jest.requireActual) (中文(简体) ). 警告说 即使在 SDK 动词没有配置时仍然可见.

在传递给OpenFeature之前,保留原有的应用程序自有上下文并丰富其内容. 使用导出 EnrichableEvaluationContext 类型为包含 undefined 值; 帮助返回 OpenFeature EvaluationContext。以下实例 假设核心 Datadog SDK 已经初始化,如上所示。 等着 setUserInfo() 在此之前 丰富:新的 RUM 用户只有在承诺解决后才能使用.

import { DdFlags, DdSdkReactNative } from '@datadog/mobile-react-native';
import {
    DatadogOpenFeatureProvider,
    enrichWithRumUser
} from '@datadog/mobile-react-native-openfeature';
import type { EnrichableEvaluationContext } from '@datadog/mobile-react-native-openfeature';
import { OpenFeature } from '@openfeature/react-sdk';

// Keep the application-owned context; do not replace it with the enriched result.
const applicationContext: EnrichableEvaluationContext = {
    region: 'us-east-1',
    email: undefined // Omit the RUM email from the evaluation context.
};

const setUpFlags = async (): Promise<void> => {
    await DdFlags.enable();
    await DdSdkReactNative.setUserInfo({
        id: 'user-123',
        email: '[email protected]',
        extraInfo: { company_name: 'Example, Inc.' }
    });

    await OpenFeature.setContext(enrichWithRumUser(applicationContext));
    await OpenFeature.setProviderAndWait(new DatadogOpenFeatureProvider());
};

void setUpFlags();

enrichWithRumUser() 调用时读取 RUM 用户; 它没有建立活连接 在RUM和OpenFeature之间. 登录或账户切换后,更新 RUM 用户并丰富其内容 原应用程序拥有的上下文 。 登录时等待 clearUserInfo() 在丰富之前; setUserInfo({ id: '' }) 是一个没有,并且是 没有 清除上一个用户.

import { DdSdkReactNative } from '@datadog/mobile-react-native';
import { enrichWithRumUser } from '@datadog/mobile-react-native-openfeature';
import type { EnrichableEvaluationContext } from '@datadog/mobile-react-native-openfeature';
import { OpenFeature } from '@openfeature/react-sdk';

// The same application-owned context as in the setup example.
const applicationContext: EnrichableEvaluationContext = {
    region: 'us-east-1',
    email: undefined
};

export const onLogin = async (): Promise<void> => {
    await DdSdkReactNative.setUserInfo({
        id: 'user-456',
        email: '[email protected]'
    });
    await OpenFeature.setContext(enrichWithRumUser(applicationContext));
};

export const onLogout = async (): Promise<void> => {
    await DdSdkReactNative.clearUserInfo();
    // No RUM targeting key remains; the provider uses the anonymous subject ('').
    await OpenFeature.setContext(enrichWithRumUser(applicationContext));
};

在设置旗下后将这些处理器连接到应用程序的认证流中 。 此登录 实例假设应用程序上下文没有自己的目标键;明确提供 应用程序值即使在 RUM 用户被清除后仍然具有权威性 .

不要通过 OpenFeature.getContext() 返回到 enrichWithRumUser()上下文中已包含 来自 RUM 用户的值, 因此这些值将作为应用程序自定义的覆盖处理 并且可以阻止新的 RUM 用户替换它们. 保留原应用程序上下文 单独,如上所示.

rumIntegrationEnabled 只控制特性旗评价事件是否发送到 RUM 。 这个 不启用或禁用 enrichWithRumUser()对于离线供应商,继续跟踪 预计算配置上下文要求.

以 OpenFeature 域隔离 RUM 上下文

警告: 以上例子使用全球OpenFeature上下文. 全球 setContext() (单位:千美元) 覆盖没有明确域名背景的域内供应商,包括其他供应商 供养者. 如果 RUM 用户属性只能到达 Datadog 提供者,则使用专用域.

作为上述全球设置的替代办法,登记明确的背景和提供者 域名。 把这个设置进去 featureFlags.ts。此示例使用当前 RUM 用户;等待任何 setUserInfo() 先打电话:

import { DdFlags } from '@datadog/mobile-react-native';
import {
    DatadogOpenFeatureProvider,
    enrichWithRumUser
} from '@datadog/mobile-react-native-openfeature';
import { OpenFeature } from '@openfeature/react-sdk';

export const DATADOG_DOMAIN = 'datadog';
// Retain and export the application-owned context, not the enriched result.
export const applicationContext = { region: 'us-east-1', email: undefined };

export const setUpDatadogDomain = async (): Promise<void> => {
    await DdFlags.enable();
    await OpenFeature.setContext(
        DATADOG_DOMAIN,
        enrichWithRumUser(applicationContext)
    );
    await OpenFeature.setProviderAndWait(
        DATADOG_DOMAIN,
        new DatadogOpenFeatureProvider()
    );
};

// In your app bootstrap, await setUpDatadogDomain() after core SDK initialization.

消费者必须使用相同的领域:进口 DATADOG_DOMAIN 从您的设置模块和使用 <OpenFeatureProvider domain={DATADOG_DOMAIN}>,如下文反应示例,或使用 OpenFeature.getClient(DATADOG_DOMAIN) 为直属客户。 没有域的客户端不使用 此域的提供者 .

过 DATADOG_DOMAIN 改为 每个 后续上下文更新: OpenFeature.setContext(DATADOG_DOMAIN, enrichWithRumUser(applicationContext))。这既包括 上方的登录和登录处理器 setContext() 调用以下反应示例。 全球 更新不会替换一个明确的域名上下文,所以略去域名会让 Datadog 打开 上一个用户的上下文。 在登录时, 设置域上的重新浓缩应用程序上下文 而不是打电话 clearContext(DATADOG_DOMAIN)将重新继承全球背景.

使用 OpenFeature 反应 SDK

关于使用OpenFeature React SDK的完整细节,包括旗帜评价,评价上下文管理和高级设置选项,参见OpenFeature React SDK 文档。 。 。 .

此示例使用专用 Datadog 域名并保留应用程序上下文 featureFlags.ts 见上文。 等着 setUpDatadogDomain() 核心 SDK 初始化之后及之前 制作应用程序. 使用域范围登录和登录处理器来重新丰富RUM用户改变时的上下文. 如果您选择全局设置, 请在上下文更新和 domain 道具从 OpenFeatureProvider 始终如一.

import { useEffect } from 'react';
import { enrichWithRumUser } from '@datadog/mobile-react-native-openfeature';
import { OpenFeature, OpenFeatureProvider, useFlag } from '@openfeature/react-sdk';
import { applicationContext, DATADOG_DOMAIN } from './featureFlags';

function AppWithProviders() {
    useEffect(() => {
        // Enrich the retained application context, never OpenFeature.getContext().
        void OpenFeature.setContext(
            DATADOG_DOMAIN,
            enrichWithRumUser(applicationContext)
        );
    }, []);

    // Use the same domain for flag evaluation and context updates.
    return (
        <OpenFeatureProvider domain={DATADOG_DOMAIN}>
            <App />
        </OpenFeatureProvider>
    );
}

function App() {
    const { value: isNewFeatureEnabled } = useFlag('new-feature-enabled', false);

    return (
        <View>
            {isNewFeatureEnabled && <NewFeatureComponent />}

            {/* ... */}
        </View>
    )
}

export default AppWithProviders;

手动配置的 JavaScript 评价

使用 DatadogCoreProvider 用于评估手动提供的预计算或基于规则的配置 Java脚本. 提供者不获取配置或发送曝光或 RUM 事件 。  应用程序管理配置的交付、存储和更新.

import {
    DatadogCoreProvider,
    coreConfigurationFromString
} from '@datadog/mobile-react-native-openfeature/rules-based';
import { OpenFeature } from '@openfeature/react-sdk';

const provider = new DatadogCoreProvider();
// `wire` is a ConfigurationWire string delivered by your application.
// This parser supports both precomputed and rules-based configurations.
provider.setConfiguration(coreConfigurationFromString(wire));

// For precomputed data, supply the exact context the configuration was computed for.
// For rules, supply the context you want to evaluate locally.
const context = { targetingKey: 'user-123', country: 'US' };
await OpenFeature.setProviderAndWait('datadog-core', provider, context);

const client = OpenFeature.getClient('datadog-core');
const enabled = client.getBooleanValue('new-feature', false);

// Replace configuration whenever your application receives an update.
provider.setConfiguration(coreConfigurationFromString(updatedWire));

您也可以提供解析器 FlagsConfiguration 直接说 这两个入境点都导出这种类型. getConfiguration() 返回所提供的配置,或 undefined 如果没有设置配置. 使用 coreConfigurationFromString 而不是本地离线供应商 仅预计算 configurationFromString 帮手.

  • 匹配预计算数据优先于规则. 如果上下文不符,则 评估人员在可用时使用规则。 否则,评价会以 INVALID_CONTEXT,或 PARSE_ERROR 如果无法解析规则.
  • 与 DatadogOfflineOpenFeatureProvider,一个空的 OpenFeature 上下文为文字. 没错 不采用预计算配置的嵌入上下文 。 因此,清理背景可以 使一个预计算的唯一提供者输入 ERROR. 使用同一域名进行注册, 评估,以及随后 OpenFeature.setContext('datadog-core', context) 打电话.
  • 在注册提供者前装入配置 。 配置缺失原因初始化为 失败 PROVIDER_NOT_READY生成无法使用的配置 PARSE_ERROR如果初始化 失败, 在装入有效配置前等待完成 .
  • 替换可用的配置发射 ConfigurationChanged。无法使用的替换输出 Error。在出错后装入可用的配置 Ready,然后是 ConfigurationChanged。 。 。 .

离线初始化

使用 DatadogOfflineOpenFeatureProvider 评价人工提供的预计算或基于规则的 具有本土曝光或RUM跟踪的配置. 提供者不获取配置; 提供它 setConfiguration。用于没有跟踪的评价,使用 DatadogCoreProvider。 。 。 .

基于规则的评价要求 @datadog/mobile-react-native 财务报告和审定财务报表 @datadog/mobile-react-native-openfeature 3.1.0. 或较后. 将两个软件包一起更新以使用 本土跟踪/评估桥. 有了更古老的SDK 缺乏桥梁,预估 配置保留了先前的行为,但规则配置产生警告和 GENERAL 错误而不是被默默地忽略 。 无法解析报表的配置 PARSE_ERROR,作为 DatadogCoreProvider 已经.

基于规则的配置

使用 coreConfigurationFromString 从 /rules-based 解析基于规则的切入点 包含预计算数据和规则的配置或配置. configurationFromString 只支持预计算配置。 规则在当地评价 当前上下文,这样您就可以在不获取其他属性的情况下更改用户或目标属性 配置 :

import { DdFlags } from '@datadog/mobile-react-native';
import { DatadogOfflineOpenFeatureProvider } from '@datadog/mobile-react-native-openfeature';
import { coreConfigurationFromString } from '@datadog/mobile-react-native-openfeature/rules-based';
import { OpenFeature } from '@openfeature/react-sdk';

await DdFlags.enable();
const domain = 'offline-rules';
const provider = new DatadogOfflineOpenFeatureProvider({ clientName: domain });
provider.setConfiguration(coreConfigurationFromString(rulesWire));
await OpenFeature.setProviderAndWait(domain, provider, {
    targetingKey: 'user-123',
    country: 'CA'
});
const client = OpenFeature.getClient(domain);
const initialValue = client.getBooleanValue('new-feature', false);

await OpenFeature.setContext(domain, { targetingKey: 'user-123', country: 'US' });
const updatedValue = client.getBooleanValue('new-feature', false);

变化上下文可以选择不同的规则和值. 将成功的评价发送给 原生跟踪路径一次,具有评估值,变种,分配,有效上下文. 本地SDK按主题、旗帜、分配和变体(和分序ID)来简化曝光度 (原始内容存档于2018-09-21). Android. 替换一个配置不会重置此调值 . 土著 trackExposures 财务报告和审定财务报表 rumIntegrationEnabled 设置仍然适用。 这个名字 FlagsClient 共享同一评价员,包括在直接访问时与 DdFlags.getClient(domain)。 。 。 .

对于包含预计算数据和规则的配置,匹配预计算数据需要 优先级。 提供者在预计算上下文不匹配时使用规则. 如果其中任一部分为 畸形,提供者仍然可以使用有效部分. 空有效上下文在出现时采用预计算上下文. 没有上下文,规则有 无目标密钥:对目标密钥返回有困难的评价 TARGETING_KEY_MISSING。通过 targetingKey: '' 为了一个匿名的话题.

预计算配置

已发布的预计算唯一设置仍然支持 :

import { DdFlags } from '@datadog/mobile-react-native';
import {
    DatadogOfflineOpenFeatureProvider,
    configurationFromString
} from '@datadog/mobile-react-native-openfeature';
import { OpenFeature } from '@openfeature/react-sdk';

await DdFlags.enable();

const provider = new DatadogOfflineOpenFeatureProvider();

// `wire` is a ConfigurationWire string you fetched yourself.
provider.setConfiguration(configurationFromString(wire));

// Set the provider after loading the configuration so it is ready with real flag values.
await OpenFeature.setProviderAndWait(provider);

// Evaluate flags — no network request is made.
const client = OpenFeature.getClient();
const isNewFeatureEnabled = client.getBooleanValue('new-feature-enabled', false);

配置带有其计算的评价背景,提供者采用 自动。 预计算配置是 单主体快照:只能服务 与计算的背景相对应。 如上所示,使用基于规则的配置 按内容评价.

警告: 执行 没有 调用 OpenFeature.setContext 带有 不同 离线背景 预计算流量。 不符合配置内嵌上下文的运行时上下文 (在SDK环境正常化之后,而不是原始的深度平等)无法实现(离线) 从不获取),所以提供者输入 OpenFeature ERROR 状态和评价退后 给您的 编码默认值 (评价) errorCode: INVALID_CONTEXT) (中文(简体) ). 供应商追偿 READY 当有效上下文为空或再次匹配快照时。 请注意,空白 { targetingKey: '' } 实值 没有 "空"——一个空字符串是一个真实(匿名)的目标键,a 与快照匹配的单独主题; 使用 clearContext() (或略去上下文)退后 到嵌入的上下文.

为同样使用其他 OpenFeature 提供者的混合应用程序推荐的预计算设置, 钩或域 :

  • 将离线提供者捆绑到一个专用的 OpenFeature 域上,并给该域一个明确的 空上下文 登记时OpenFeature.setContext(domain, {}))——本提供者读作: 作为"没有覆盖,使用嵌入上下文". 无自身上下文域 继承 全球环境,所以是一个全球 OpenFeature.setContext (或全球背景不匹配) 以其他方式到达提供者并强迫其进入 ERROR。 。 。 .
  • 使用独有的数据犬 clientName (单位:千美元)new DatadogOfflineOpenFeatureProvider({ clientName }): 单独的 OpenFeature 域,否则共享相同的内在 DdFlags.getClient('default'),以及 共享客户端上的在线提供者会放弃离线配置.

由于您没有设置 OpenFeature 上下文, 请注意 上下文分隔: 观察 OpenFeature 钩子 openFeature 评估背景({} 当未设定时),而 Datadog 曝光跟踪属性 根据配置内嵌上下文进行评价.

注(回收说明): “补救背景恢复”只保留到 有效 上下文为空或匹配快照. OpenFeature.clearContext(domain) 删除域 上下文 回到全球范围 - 如果这一全球背景并非空洞而并非 匹配, 提供者留在 ERROR。 。 。 .

注 (启动顺序): 装入配置为 setConfiguration 在此之前 setProviderAndWait,如上所示。 如果您在任何成功之前注册提供者 setConfiguration初始化为 ERROR 状态(它无法评估);加载 有效配置后恢复到 READY。 。 。 . 不要使用非等待状态 OpenFeature.setProvider(provider) 紧接着 setConfiguration 那个命令 种族(待初始化可以 结算( 拒绝) 恢复后覆盖 状态返回到 ERROR) (中文(简体) ). 首先配置,或 await OpenFeature.setProviderAndWait(...)。 。 。 .

这个供应商依赖于 OpenFeature 静态-context 寿命周期——SDK 拥有 PROVIDER_RECONCILING编号 :PROVIDER_CONTEXT_CHANGED 关于背景变化的活动——和要求 @openfeature/web-sdk ^1.8.0 (该版本的开发并对照核实).

版本与发布记录

@datadog/mobile-react-native-openfeature 共发布 17 个版本,首次发布于 2026/02/18;过去 12 个月发布了 17 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
3.11.0latest2026/10/2021 天前
3.10.02026/10/091 个月前
3.9.02026/10/011 个月前
3.8.02026/09/221 个月前
3.7.02026/09/032 个月前
3.6.02026/08/172 个月前

关于 @datadog/mobile-react-native-openfeature 的常见问题

@datadog/mobile-react-native-openfeature 是什么?

一个客户端 React 本地模块,用于提供 OpenFeature 集成数据狗特性旗

如何安装 @datadog/mobile-react-native-openfeature?

在项目目录运行 npm install @datadog/mobile-react-native-openfeature,或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖:react(>=16.13.1)、react-native(>=0.63.4 <1.0)、@openfeature/web-sdk(^1.8.0)、@datadog/mobile-react-native(^3.1.0)。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖,Yarn 需要手动安装。

@datadog/mobile-react-native-openfeature 支持 TypeScript 吗?

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

@datadog/mobile-react-native-openfeature 支持 ESM 还是 CommonJS?

同时提供 ES Module 与 CommonJS 入口,import 和 require() 都可以使用,打包工具会自动选择合适的版本。

@datadog/mobile-react-native-openfeature 可以商用吗?

@datadog/mobile-react-native-openfeature 使用 Apache-2.0 许可。宽松许可:允许商业使用、修改和再分发,并附带明确的专利授权;分发时需保留许可与 NOTICE 文件,修改过的文件要注明改动。以上为概括,不构成法律意见,请以许可原文为准。

@datadog/mobile-react-native-openfeature 的下载量有多少?

根据 npm 官方下载统计,@datadog/mobile-react-native-openfeature 在 2026/10/12 – 2026/11/10 这 30 天内被下载 39,350 次,日均约 1,312 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@datadog/mobile-react-native-openfeature 还在维护吗?

最新版本 3.11.0 发布于 2026/10/20(21 天前);至今共发布 17 个版本,其中过去 12 个月发布了 17 个;首次发布于 2026/02/18。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。