Doramagic 项目包 · 项目说明书
arcjet-js 项目
面向 Next.js 的 Arcjet 运行时安全 SDK,提供机器人防护、速率限制、Prompt 注入检测、PII 屏蔽以及 WAF 能力。
仓库概览与 Monorepo 架构
arcjet-js 是 Arcjet 公司官方维护的 JavaScript / TypeScript SDK Monorepo,主要为 Web 应用提供安全、速率限制、机器人和敏感信息防护等能力。仓库根目录的 README.md 声明了项目目标:在多种 JavaScript 运行时与框架之上提供一致的安全防护 API,支持 Node.js、Bun、Deno 以及各类 Edg...
继续阅读本节完整说明和来源证据。
仓库定位与核心使命
arcjet-js 是 Arcjet 公司官方维护的 JavaScript / TypeScript SDK Monorepo,主要为 Web 应用提供安全、速率限制、机器人和敏感信息防护等能力。仓库根目录的 README.md 声明了项目目标:在多种 JavaScript 运行时与框架之上提供一致的安全防护 API,支持 Node.js、Bun、Deno 以及各类 Edge 运行时。仓库采用 pnpm workspace + Turborepo 组合,实现多个独立可发布的 npm 包统一管理与构建。
资料来源:README.md:1-40
Monorepo 目录与包划分
仓库根 package.json 通过 workspaces 字段声明所有子包路径,配合 pnpm-workspace.yaml 中 packages 列表形成统一命名空间。整体包按职责分为以下几类:
| 包分类 | 代表包 | 作用 |
|---|---|---|
| 核心 SDK | @arcjet/core、@arcjet/headers、@arcjet/ip、@arcjet/sensitive-info-rampart | 提供规则引擎、请求头解析、IP 判定、敏感信息检测等通用能力 |
| 框架适配器 | @arcjet/next、@arcjet/astro、`@arcjet/sveltekit、@arcjet/express | 针对特定框架的集成 |
| 运行时适配器 | @arcjet/bun、@arcjet/deno、@arcjet/node、`@arcjet/netlify-edge(计划中,参见 issue #5152) | 针对运行时的入口封装 |
| 工具包 | @arcjet/analyze-wasm、@arcjet/transport | WASM 分析与传输协议 |
资料来源:package.json:1-60、pnpm-workspace.yaml:1-20
构建编排与工具链
构建层通过 Turborepo 进行编排,根目录 turbo.json 定义 build、test、lint、typecheck 等任务流水线,并使用 dependsOn 声明任务依赖(如 build 依赖 ^build,实现拓扑排序)。TypeScript 共享配置由 tsconfig.base.json 统一维护 target、module、strict 等编译选项,子包通过 extends 复用,保证一致的类型系统与 ESM 输出。
flowchart LR A[源码 src] --> B[turbo build] B --> C[各子包 dist] C --> D[Changesets 版本管理] D --> E[GitHub Actions 发布]
发布流程结合 .changeset/config.json 描述的 Changesets 工作流:开发者提交变更说明,CI 汇总后自动打开 Version PR,合并后由 publish 工作流发布到 npm,README 中强调所有包统一以 @arcjet/ 命名空间发布。
资料来源:turbo.json:1-40、tsconfig.base.json:1-30、.changeset/config.json:1-20
社区驱动的演进方向
仓库结构也在回应社区诉求。Issue #5152 提议新增独立的 Netlify Edge Functions 适配器,意味着未来 packages/ 目录将增加 @arcjet/netlify-edge 子包。Issue #44 提出“零外部依赖 SDK”的愿景,影响核心包的依赖收敛策略。Issue #1781 讨论开发模式日志频率,可能促使 @arcjet/core 中调整 console.warn 调用位置与节流逻辑。Issue #5201 推动从 Dependabot 迁移到 Renovate Dashboard,会体现在根目录的 renovate.json 与 CI 工作流中。最新发布 v1.9.1(2026-07-15)修复了 IP 校验脚本路径与 publish 工作流中 @arcjet/sensitive-info-rampart 包的发布覆盖问题,体现了 Monorepo 多包发布协调的常见痛点。
资料来源:README.md:40-80
资料来源:README.md:1-40
框架 SDK 适配器
Arcjet 在 arcjet-js 仓库中提供了一系列框架 SDK 适配器,作为核心规则引擎(@arcjet/arcjet、@arcjet/core)与各种 JavaScript 运行时及 Web 框架之间的桥梁。每个适配器独立打包为单独的 npm 包,专注于解决特定框架或运行时请求/响应模型与 Arcjet 抽象接口之间的差异。
继续阅读本节完整说明和来源证据。
概述
Arcjet 在 arcjet-js 仓库中提供了一系列框架 SDK 适配器,作为核心规则引擎(@arcjet/arcjet、@arcjet/core)与各种 JavaScript 运行时及 Web 框架之间的桥梁。每个适配器独立打包为单独的 npm 包,专注于解决特定框架或运行时请求/响应模型与 Arcjet 抽象接口之间的差异。
适配器的核心职责包括:
- 将框架原生的请求对象(如 Node
IncomingMessage、FetchRequest、FastifyFastifyRequest、NestJS 装饰器上下文等)转换为 Arcjet 内部统一的"虚拟"请求结构。 - 从底层平台提取客户端 IP、协议、Headers、Cookie 等上下文信息。
- 在需要时包装响应(例如 Fastify 的
reply),以注入决策结果或处理阻断逻辑。 - 暴露与各框架惯用 API 对齐的工厂方法(如
arcjet()、中间件工厂、Guard、装饰器等)。
资料来源:arcjet-next/src/index.ts:1-50、arcjet-node/src/index.ts:1-50、arcjet-bun/src/index.ts:1-50、arcjet-deno/src/index.ts:1-50。
已发布的适配器
下表列出了仓库 main 分支中各适配器对应的主流运行时 / 框架,以及其在 src/index.ts 中暴露的主要入口:
| 适配器包 | 目标运行时 / 框架 | 入口文件中的公共导出 |
|---|---|---|
@arcjet/next | Next.js(App Router、Middleware) | arcjet、withArcjet、createMiddleware |
@arcjet/node | 通用 Node.js(HTTP、Connect、Express) | arcjet、Node 适配器函数 |
@arcjet/bun | Bun 运行时(含 Bun.serve) | arcjet、Bun 适配器函数 |
@arcjet/deno | Deno(含 Deno Deploy) | arcjet、Deno 适配器函数 |
@arcjet/fastify | Fastify | arcjetFastify 插件 |
@arcjet/nest | NestJS | Guard、Interceptor、装饰器 |
每个适配器在其 src/index.ts 中重新导出经过框架特定调整的 arcjet 工厂函数,并提供与框架生命周期挂钩的辅助方法。
资料来源:arcjet-fastify/src/index.ts:1-40、arcjet-nest/src/index.ts:1-40、arcjet-next/src/index.ts:1-40。
适配器共性结构
尽管适配器针对各自框架做了特化,但它们在源码结构上遵循一致的模式:
- 入口文件:每个适配器的
src/index.ts暴露公共 API,作为整个包的对外门面。资料来源:arcjet-node/src/index.ts:1-30。 - 平台抽象:依赖运行时层屏蔽不同平台获取 IP、Headers、Cookies 的差异,使上层规则对适配器无感知。
- 决策回调:适配器负责把 Arcjet 的
ArcjetDecision翻译为框架可识别的响应形态,例如设置 HTTP 状态码、返回自定义 403/429,或将决策附加到请求对象上供下游消费。 - 类型定义:每个适配器都导出与该框架请求/响应类型匹配的 TypeScript 类型,确保调用方在编辑器中获得类型提示。
这种"一个核心 + 多个薄适配器"的设计使得新增框架的支持成本较低——核心规则引擎可以独立演进,而适配器只关心平台绑定。
社区关注的扩展点
仓库的社区讨论也反映出适配器生态仍在持续演进:
- Netlify Edge Functions 适配器(#5152):当前尚未发布 Netlify Edge 专用适配器,社区提议基于其独有的
Request/Context模型新建适配器。该需求与现有arcjet-deno的部分实现存在复用空间。 - 结构化错误(#1855):用户希望在缺失关键 Header 等场景下,由适配器抛出结构化错误(如 400)而非依赖框架默认的 500 行为。该特性会直接影响适配器对错误响应路径的处理。
- 零依赖 SDK(#44):社区长期关注 SDK 依赖数量,目标是在安装某个适配器时只新增"一个依赖",这要求适配器自身尽量轻量化。
- 开发模式日志(#1781):当适配器在本地开发回退到
127.0.0.1时会打印警告,社区建议仅在客户端初始化阶段打印一次以减少日志噪音。
这些讨论都会进一步塑造未来适配器的发布形态,例如新增的 Netlify 适配器有望继承一致的错误处理与日志策略,从而形成统一的"框架 SDK 适配器"约定。
资料来源:arcjet-next/src/index.ts:1-50、arcjet-node/src/index.ts:1-50、arcjet-bun/src/index.ts:1-50、arcjet-deno/src/index.ts:1-50。
Arcjet Guard 与安全规则
@arcjet/guard 是 Arcjet JS SDK 单体仓库中提供的一个轻量化安全守卫包,它把核心 @arcjet/arcjet 的能力裁剪到只保留最常用的请求级保护策略,并以更少的依赖暴露给上层框架适配器(如 Next.js、NestJS、SvelteKit 等)。arcjet-guard 的目标用户是希望在不引入完整 Arcjet 决策栈的前提下,仅使用机器人识...
继续阅读本节完整说明和来源证据。
概述与定位
@arcjet/guard 是 Arcjet JS SDK 单体仓库中提供的一个轻量化安全守卫包,它把核心 @arcjet/arcjet 的能力裁剪到只保留最常用的请求级保护策略,并以更少的依赖暴露给上层框架适配器(如 Next.js、NestJS、SvelteKit 等)。arcjet-guard 的目标用户是希望在不引入完整 Arcjet 决策栈的前提下,仅使用机器人识别、爬虫指纹与基础速率控制这几类规则的开发者。
与主包不同,guard 强调"零依赖(zero dependency)"理念——参见社区议题 #44 *"Zero dependencies for JS SDK"* 中关于移除外部依赖、保持 SDK 体积最小的讨论。
资料来源:arcjet-guard/src/index.ts:1-40、#44
核心组件与架构
arcjet-guard 包由三个核心源码文件组成,分别承担入口导出、HTTP 客户端封装以及规则定义职责:
| 文件 | 职责 | 关键导出 |
|---|---|---|
src/index.ts | 公共 API 入口 | guard()、规则构造器 |
src/client.ts | 封装 arcjet-client 的 HTTP 调用 | createGuardClient() |
src/rules.ts | 安全规则的工厂函数与校验逻辑 | detectBot()、shield()、rateLimit() |
入口文件 index.ts 会重新导出 client.ts 与 rules.ts 中的函数,使得用户可以通过单一导入路径同时获得客户端与规则。client.ts 内部复用 @arcjet/transport 与 @arcjet/protocol,将请求与决策的协议层下沉到共享包,从而避免在 guard 中重复实现 protobuf 序列化逻辑。
资料来源:arcjet-guard/src/index.ts:15-60、arcjet-guard/src/client.ts:1-45、arcjet-guard/src/rules.ts:1-50
安全规则的类型与配置
rules.ts 中定义了 guard 支持的所有内建规则。每条规则返回一个对象,包含该规则的判定逻辑与可在本地预校验的字段约束:
detectBot(options)— 根据protocol/src/well-known-bots.ts中维护的已知 bot 指纹库(Googlebot、Bingbot、AhrefsBot 等)识别自动化流量,并支持白名单模式allow与拦截模式deny。shield()— 防御常见 Web 攻击(如 SQL 注入、跨站脚本扫描器指纹),无须业务侧配置阈值。rateLimit(options)— 基于令牌桶的滑动窗口限流,通过max、window、mode(LIVE/DRY_RUN)控制行为。
每条规则都遵循"显式声明 + 本地快速失败"的原则:在请求未真正抵达决策 API 时,参数错误(例如负数 max)会立即抛出可结构化的错误。这一点与社区议题 #1855 *"Consider building structured errors"* 的诉求方向一致——使上层能够根据错误类型返回 4xx 而不是默认的 5xx。
import { guard, detectBot, shield, rateLimit } from "@arcjet/guard";
const aj = guard({
key: process.env.ARCJET_KEY!,
rules: [
shield({ mode: "LIVE" }),
detectBot({ mode: "LIVE", allow: ["CURL", "GOOGLEBOT"] }),
rateLimit({ mode: "LIVE", max: 5, window: "10s" }),
],
});
资料来源:arcjet-guard/src/rules.ts:20-180、protocol/src/well-known-bots.ts:1-120、#1855
请求保护流程
guard() 返回的对象提供 protect(request) 方法,其完整生命周期如下:
flowchart TD
A[应用入口收到请求] --> B[构造 ArcjetRequest<br/>提取 IP/headers]
B --> C[本地规则预校验]
C -->|参数错误| D[抛出结构化错误]
C -->|通过| E[序列化规则为 Protobuf]
E --> F[通过 arcjet-client 调用决策 API]
F --> G[解析 Decision]
G -->|conclusion=DENY| H[阻止请求并返回 reason]
G -->|conclusion=ALLOW| I[放行至业务处理器]
H --> J[可选: 上报指标]
I --> J在开发模式下,若无法提取客户端 IP,client.ts 会记录一次警告并回退至 127.0.0.1。社区议题 #1781 *"Consider development mode logging frequency"* 指出该日志在开发过程中过于嘈杂,团队正在评估改为仅在客户端初始化时输出一次以降低噪音。
资料来源:arcjet-guard/src/client.ts:30-110、arcjet-guard/src/index.ts:80-140、#1781
框架适配与边界
由于 guard 是平台无关的纯逻辑包,它通过显式的 Request-like 对象接受输入,因此可以被任意适配器包装。社区议题 #5152 *"Create an adapter for Netlify edge functions"* 正是基于这一原则提出的——为 Netlify Edge Functions 提供独立的适配层,把 Web Request/Response 转换为 guard 所需要的形状。这种"轻核心 + 多适配器"的拆分正是 #44 *Zero dependencies* 与 #5201 *Renovate Dashboard* 共同推动的可维护性目标的具体体现。
资料来源:arcjet-guard/README.md:1-80、#5152、#5201
小结
@arcjet/guard 用最小的依赖面提供了三种最常见的安全规则(detectBot、shield、rateLimit),其核心价值在于:把决策逻辑收敛到远程 API、把规则校验保留在本地、并通过 protocol 包共享 bot 指纹等数据资产。对于仅需基础防护的项目而言,guard 是介于"裸 fetch + 自写中间件"和"完整 Arcjet SDK"之间的折中选择。
核心包、WASM 模块与开发者运营
Arcjet JS SDK 是一个面向边缘与无服务器场景的安全分析 SDK,其代码仓库按职责拆分为若干独立包:核心运行时包负责协议、IP 推断与请求头解析,WASM 子包提供敏感信息检测与本地分析算子,整套发布流程与依赖治理则构成了"开发者运营"侧的关注点。本页梳理这些模块的边界、相互依赖以及面向用户的可观察行为。
继续阅读本节完整说明和来源证据。
包结构总览
Arcjet 仓库并非单一 npm 包,而是一个 monorepo,其中可被消费者直接 import 的核心包集中在 analyze、redact、transport、ip、headers 五个目录,对应的 WASM 实现位于 analyze-wasm 与 redact-wasm。这种"纯 JS 包装层 + WASM 内核"的分层,使得高层适配器(如 @arcjet/next、@arcjet/netlify-edge)可以共用同一份业务逻辑,仅替换 I/O 适配部分。
| 目录 | 角色 | 主要导出 |
|---|---|---|
transport | 与 Arcjet Decide API 通信的 HTTP 客户端 | createTransport |
headers | 解析与规范化 HTTP 请求头 | headersFromRequest 等 |
ip | 从请求中推断客户端 IP | parseIp、getClientIp |
analyze | 聚合本地规则与远端判定结果 | analyze |
redact | 文本脱敏的高层封装 | redact |
analyze-wasm / redact-wasm | 基于 Rust 编译的 WASM 模块 | 内部 ESM 绑定 |
资料来源:transport/src/index.ts:1-40、headers/src/index.ts:1-30、ip/src/index.ts:1-40、redact/src/index.ts:1-30。
WASM 模块的角色
analyze-wasm 与 redact-wasm 是 SDK 在客户端侧执行的关键算子。前者负责敏感信息识别(例如令牌、信用卡号、邮箱)所需的本地正则与状态机,后者则负责对日志、错误信息或自定义字符串进行脱敏替换。它们都以 TypeScript 包装的形式发布为 ESM 包,对外仅暴露少量纯函数,避免业务代码直接依赖 WASM 字节码细节。
以 redact 包为例,业务侧只需调用高层 redact(text, options),其内部会惰性加载 redact-wasm 提供的编译产物,从而在 Node、Edge Runtime、浏览器中复用同一份匹配逻辑。资料来源:redact/src/index.ts:20-60、redact-wasm/src/index.ts:1-25。
analyze-wasm 的角色类似:本地优先分析(local-first analysis)会在请求未离开用户进程前完成一部分规则判定,只有命中需要远端介入的路径时才会经由 transport 上报。这种"本地 + 远端"的混合架构,是 Arcjet 强调低延迟与边缘友好的基础。资料来源:analyze-wasm/src/index.ts:1-30。
开发者运营与可观察性
围绕核心包,社区反复讨论的主题集中在三个方向:
- 结构化错误:当前 SDK 在遇到缺失关键请求头、IP 推断失败等场景时倾向抛出通用异常或返回 500 风格的失败。社区提出(参见 #1855)应将错误结构化,使调用方可以依据错误类别决定返回 400 还是 500,从而将"用户配置错误"与"上游故障"区分开来。该讨论直接影响
transport与headers的错误返回路径设计。资料来源:transport/src/index.ts:80-120。 - 开发模式日志频次:开发环境下 IP 推断会因缺少真实请求头而退回到
127.0.0.1,并在每次protect()调用时打印警告。该行为在 #1781 中被反馈为"污染日志",维护团队正在评估是否将警告降频到客户端初始化阶段一次性输出。资料来源:ip/src/index.ts:50-90。 - 零依赖与依赖治理:仓库长期目标是让用户"只增加 1 个依赖"(#44),因此核心包刻意保持零运行时依赖,WASM 包仅引入必要的加载与类型依赖。v1.9.1 中针对
verify-ranges脚本路径与@arcjet/sensitive-info-rampart发布流程的修复,也延续了这一治理思路——发布脚本必须显式包含新引入的子包,避免遗漏。资料来源:ip/src/index.ts:1-20、analyze-wasm/src/index.ts:1-15。
适配器与运行时边界
由于核心包保持平台中立,运行环境差异(Node、Cloudflare Workers、Vercel Edge、Netlify Edge Functions)由各 @arcjet/*-adapter 包承担。headers 包在不同适配器之间充当"请求头语义统一层",它从底层 Request 中抽取 Arcjet 关心的字段(如 x-forwarded-for、cookie、user-agent),并以稳定 schema 交给上层。资料来源:headers/src/index.ts:40-90。
ip 包则依赖 headers 输出的规范化字段,再结合远端代理可信度进行 IP 推断;该步骤既可能出现在适配器初始化阶段,也可能延迟到 protect() 调用时。最终 IP 既会用于本地规则(如速率限制),也会作为 analyze 报告的上下文之一发往 Decide API。资料来源:ip/src/index.ts:60-120。
针对 Netlify Edge Functions 的适配需求,社区在 #5152 中指出需要专门的适配器以匹配其请求/响应生命周期;这一类适配器通常会复用本节列出的核心包,再额外处理 Deno 风格的 Request 与函数签名差异。
流程示意
flowchart LR A[Adapter Request] --> B[headers 包] B --> C[ip 包] C --> D[analyze 本地规则] D -->|需要远端判定| E[transport 包] D -->|涉及敏感信息| F[analyze-wasm / redact-wasm] E --> G[Decide API] F --> G G --> H[ArcjetDecision]
资料来源:analyze-wasm/src/index.ts:10-25、redact/src/index.ts:30-70、transport/src/index.ts:40-90。
小结
核心包提供了"协议无关 + 平台中立"的业务基座,WASM 模块承担了性能敏感的本地分析任务,二者通过稳定的 TypeScript 接口解耦。开发者运营层面的改进——结构化错误、日志降频、零依赖与 Renovate 化依赖更新——则持续提升 SDK 的可调试性与可维护性。下一步值得关注的是结构化错误 API 形态落地,以及 Netlify Edge 适配器的正式发布。
资料来源:transport/src/index.ts:1-40、headers/src/index.ts:1-30、ip/src/index.ts:1-40、redact/src/index.ts:1-30。
失败模式与踩坑日记
保留 Doramagic 在发现、验证和编译中沉淀的项目专属风险,不把社区讨论只当作装饰信息。
用户照着仓库名搜索包或照着包名找仓库时容易走错入口。
可能增加新用户试用和生产接入成本。
安装可能改变本机 AI 工具行为,用户需要知道写入位置和回滚方法。
假设不成立时,用户拿不到承诺的能力。
Pitfall Log / 踩坑日志
项目:arcjet/arcjet-js
摘要:发现 10 个潜在踩坑项,其中 0 个为 high/blocking;最高优先级:身份坑 - 仓库名和安装名不一致。
1. 身份坑 · 仓库名和安装名不一致
- 严重度:medium
- 证据强度:runtime_trace
- 发现:仓库名
arcjet-js与安装入口@arcjet/next不完全一致。 - 对用户的影响:用户照着仓库名搜索包或照着包名找仓库时容易走错入口。
- 复现命令:
npm i @arcjet/next - 证据:identity.distribution | https://www.npmjs.com/package/@arcjet/next | repo=arcjet-js; install=@arcjet/next
2. 安装坑 · 来源证据:arcjet 1.8.0 wont resolve on windows, dist/_virtual/_. folder has a trailing dot
- 严重度:medium
- 证据强度:source_linked
- 发现:GitHub 社区证据显示该项目存在一个安装相关的待验证问题:arcjet 1.8.0 wont resolve on windows, dist/_virtual/_. folder has a trailing dot
- 对用户的影响:可能增加新用户试用和生产接入成本。
- 证据:community_evidence:github | https://github.com/arcjet/arcjet-js/issues/6136 | 来源讨论提到 node 相关条件,需在安装/试用前复核。
3. 配置坑 · 可能修改宿主 AI 配置
- 严重度:medium
- 证据强度:source_linked
- 发现:项目面向 Claude/Cursor/Codex/Gemini/OpenCode 等宿主,或安装命令涉及用户配置目录。
- 对用户的影响:安装可能改变本机 AI 工具行为,用户需要知道写入位置和回滚方法。
- 证据:capability.host_targets | https://www.npmjs.com/package/@arcjet/next | host_targets=mcp_host, claude_code, claude, cursor
4. 能力坑 · 能力判断依赖假设
- 严重度:medium
- 证据强度:source_linked
- 发现:README/documentation is current enough for a first validation pass.
- 对用户的影响:假设不成立时,用户拿不到承诺的能力。
- 证据:capability.assumptions | https://www.npmjs.com/package/@arcjet/next | README/documentation is current enough for a first validation pass.
5. 维护坑 · 维护活跃度未知
- 严重度:medium
- 证据强度:source_linked
- 发现:未记录 last_activity_observed。
- 对用户的影响:新项目、停更项目和活跃项目会被混在一起,推荐信任度下降。
- 证据:evidence.maintainer_signals | https://www.npmjs.com/package/@arcjet/next | last_activity_observed missing
- 严重度:medium
- 证据强度:source_linked
- 发现:no_demo
- 证据:downstream_validation.risk_items | https://www.npmjs.com/package/@arcjet/next | no_demo; severity=medium
7. 安全/权限坑 · 存在评分风险
- 严重度:medium
- 证据强度:source_linked
- 发现:no_demo
- 对用户的影响:风险会影响是否适合普通用户安装。
- 证据:risks.scoring_risks | https://www.npmjs.com/package/@arcjet/next | no_demo; severity=medium
8. 安全/权限坑 · 来源证据:Dependency Dashboard
- 严重度:medium
- 证据强度:source_linked
- 发现:GitHub 社区证据显示该项目存在一个安全/权限相关的待验证问题:Dependency Dashboard
- 对用户的影响:可能影响授权、密钥配置或安全边界。
- 证据:community_evidence:github | https://github.com/arcjet/arcjet-js/issues/5907 | 来源讨论提到 node 相关条件,需在安装/试用前复核。
9. 维护坑 · issue/PR 响应质量未知
- 严重度:low
- 证据强度:source_linked
- 发现:issue_or_pr_quality=unknown。
- 对用户的影响:用户无法判断遇到问题后是否有人维护。
- 证据:evidence.maintainer_signals | https://www.npmjs.com/package/@arcjet/next | issue_or_pr_quality=unknown
10. 维护坑 · 发布节奏不明确
- 严重度:low
- 证据强度:source_linked
- 发现:release_recency=unknown。
- 对用户的影响:安装命令和文档可能落后于代码,用户踩坑概率升高。
- 证据:evidence.maintainer_signals | https://www.npmjs.com/package/@arcjet/next | release_recency=unknown
来源:Doramagic 发现、验证与编译记录