npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

agent-e2e

v0.1.6

Published

AI-driven UI automated testing CLI — explore sites, generate test configs, replay without LLM

Readme

Agent-E2E

AI 驱动的 UI 自动化测试 CLI —— 一次探索,无限回放,零 Token 复测。

给一个 URL,Agent 自主探索站点、理解业务逻辑、生成结构化测试规格;此后每次回放都是纯机械执行,不再消耗 LLM Token。

爬虫发现页面,Agent-E2E 发现测试场景。


背景:回归测试的困境

每次上线前,团队都面临同一个问题:这次改动会不会把别的地方搞挂?

回归测试是回答这个问题的唯一方式。但现实是——

  • 不做:多数团队的真实现状。靠人肉点点点,或者干脆赌一把直接上线,等用户反馈来发现问题。省了测试的钱,赔了故障的钱
  • 手动做:测试人员对着几十个页面重复点击、填表、验证,枯燥且低效。关键路径覆盖一遍要半天,改一行代码又得重来
  • 自动化做:要么上 RPA 平台(UiPath、影刀等),采购费动辄数万,还需要专人搭流程、维护机器人,杀鸡用牛刀;要么写 Selenium/Playwright 脚本,一个登录流程的自动化可能要半天,写完还要持续维护——DOM 一变,测试代码跟着改,维护成本有时比手动还高

归根结底,回归测试是一件极其机械但又不得不做的事。它的本质就是"按照上次的路径再走一遍,看看结果有没有变"——这恰恰是机器最擅长的事情。

问题不在于"要不要自动化",而在于自动化的门槛太高

Agent-E2E 的核心思路是:让 AI 承担"理解业务、设计测试"的高门槛工作,然后把成果沉淀为结构化配置,交给机器无限次零成本回放。 AI 只在第一次探索时介入,此后的每一次回归测试都不需要 AI、不消耗 Token、不依赖人工。


方案对比

三种自动化测试方案对比

                 RPA 平台            传统自动化框架          AI Agent + MCP          Agent-E2E
              (UiPath/影刀)       (Selenium/Playwright)  (Claude Code+DevTools)  (Harness/Loop/Engine)
────────────────────────────────────────────────────────────────────────────────────────────────
测试创建方式  GUI 拖拽搭流程      手写代码/录制回放       每次靠 LLM 即时决策     LLM 探索一次,
              + 专人维护机器人                                                    生成配置后脱离

每次回放成本  ¥0(平台执行)      ¥0(纯脚本)           ¥¥¥(全程 LLM)        ¥0(纯机械执行)

采购/开发成本 ¥¥¥(平台授权费     高:写代码 + 配环境     低:按 Token 付费       低:一次探索费用
              动辄数万/年)                                                      后续零成本

维护成本      高:流程截图失效     高:DOM 变更=改代码     低:LLM 自适应          低:改 JSON 配置
              需重新录制                                  但每次都要付费          或 Chat 对话修改

执行速度      中等                 快                      慢(MCP 开销 +         快(agent-browser
                                                          LLM 推理延迟)         直连进程通信)

浏览器控制    平台内置引擎         WebDriver / CDP         MCP Server 中转        agent-browser CLI
              (黑盒封装)         (代码调用)            (JSON-RPC + LLM)     (execFile 直连)

断言可靠性    截图比对 /           确定性断言              LLM 判断               确定性断言注册表
              规则匹配(脆弱)                             (幻觉风险)           (LLM 不做裁判)

业务理解能力  无(纯录制回放)     无(纯机械)            强(但一次性消耗)      强(沉淀为配置,
                                                                                可复用/可编辑)

上手门槛      中:学平台操作       高:学 API + 写代码     低:自然语言驱动        极低:给 URL 就行
              + 采购流程           + 配环境                但需理解 MCP/prompt     不写代码、不学 API

适合场景      业务流程自动化       已知流程、稳定 DOM      一次性验证、探索        持续回归测试、
              (非测试专用)                                                      定时复测、CI/CD

核心优势

  • Explore Once, Replay Forever — LLM 只在首次探索时介入,Automation Engine 承担 95% 以上的实际工作(页面遍历、断言生成、交互枚举),LLM 仅做关键决策(启动、登录兜底、结束)。此后每次回放零 Token、零人工
  • 三层探索架构:Harness → LLM Loop → Automation Engine — 传统 AI Agent 是"LLM 驱动循环 + Harness 治理",Agent-E2E 在工具执行层内嵌了一个 Automation Engine,让 LLM 说一句"打开 URL",引擎自动完成整站遍历:
    • Harness(外层治理) — 包裹 Loop 控制边界:Budget(100 步 / 5 次连续失败 / 5 分钟超时)、Dedup(动作指纹去重)、Recovery(浏览器崩溃重启 session)、Graceful Shutdown(Ctrl+C 保存进度)
    • LLM Loop(中层决策)callLLMtool_callsexecuteTool 分发。LLM 选工具(browser_open/finish_exploration),通常只需 1~5 次调用
    • Automation Engine(内层引擎)executeTool("browser_open") 内部触发完整自动化流水线:
      • drainFrontierDeterministically — BFS 遍历同域页面(深度可配,--depth 默认 5)
      • syncCurrentPage — 每页 4 轮 JS 注入:渲染稳定检测 → 展开折叠导航菜单 → 提取表单/链接/交互候选 → 可见文本/标题探测
      • enqueueLinkCandidates — 按区域限流发现链接(导航区 96 / 内容区 24 / 表格区 4 / 未知区 12)
      • enrichSafeInteractions — 自动尝试 4 类无副作用交互(详情展开、弹层打开、分页翻页、查询筛选)
      • createBaselineAssertions — 自动生成确定性断言(url_contains、title_contains、text_visible、element_visible)
      • maybeAutoLoginWithProvidedAuth — 检测登录表单并完成确定性登录,失败时才交给 LLM
  • 确定性断言,拒绝幻觉 — 8 种断言类型(url_contains/url_equals/title_contains/title_equals/text_visible/text_not_visible/element_visible/element_count)全部由确定性函数判定,LLM 不做裁判
  • agent-browser 直连 — 跳过 MCP/WebDriver 中间层,通过 execFile 直接与浏览器进程通信,零 WebSocket 长连接维护
  • SiteConfig 即资产 — 探索产物是可读、可编辑、可版本管理的 JSON,团队可以 review、可以 Chat 补充、可以 Git 追踪变更
  • 纯 CLI,天然可组合 — 没有 GUI,没有平台,一行命令就是全部:
    • CI/CD 原生集成 — GitHub Actions / GitLab CI 里加一行 agent-e2e run <site-id> 就能跑回归
    • PR 卡点 — 每次 PR 自动触发测试,失败则阻断合并
    • AI Agent 友好 — Claude Code、Cursor 等 AI 编程工具可以直接调用 CLI,形成"AI 写代码 → AI 跑测试 → AI 修 Bug"闭环
    • crontab 一行搞定定时复测 — 不需要额外的调度平台
# GitHub Actions 示例
- name: Run E2E Tests
  run: |
    npx agent-e2e run my-site --concurrency 3
    # 退出码非 0 = 有测试失败,自动阻断 PR 合并

架构

三层探索架构

传统 AI Agent 架构是"LLM 驱动循环 + Harness 治理"——每一步都由 LLM 决策,Harness 只做边界控制。Agent-E2E 在工具执行层内嵌了 Automation Engine,LLM 说一句"打开 URL",引擎自动完成整站遍历:

┌─ Explorer ──────────────────────────────────────────────────────┐
│                                                                 │
│  ┌─ Harness(外层治理:控制 Loop 边界)──────────────────────┐  │
│  │  Preflight ──→ 探索前检查浏览器/URL/LLM 是否可用         │  │
│  │  Budget ──→ 超步数(100)/超失败(5)/超时(5min) → 停止       │  │
│  │  Dedup  ──→ 重复动作指纹 → 跳过                           │  │
│  │  Recovery → 浏览器崩溃 → 重启 session                     │  │
│  │  Shutdown → Ctrl+C → 保存已探索进度                       │  │
│  │                                                           │  │
│  │  ┌─ LLM Loop(中层决策:1~5 次调用)──────────────────┐  │  │
│  │  │  while (!finished)                                 │  │  │
│  │  │    callLLM() ──→ tool_calls ──→ executeTool 分发    │  │  │
│  │  │    · browser_open  → 触发 Automation Engine        │  │  │
│  │  │    · browser_click/fill → LLM 补充特有交互          │  │  │
│  │  │    · finish_exploration → 保存 SiteConfig 结束     │  │  │
│  │  │                                                    │  │  │
│  │  │  ┌─ Automation Engine(内层引擎:完成 95% 工作)─┐ │  │  │
│  │  │  │                                               │ │  │  │
│  │  │  │  drainFrontierDeterministically (BFS 遍历)     │ │  │  │
│  │  │  │    · 深度可配(--depth,默认 5)               │ │  │  │
│  │  │  │    · 链接限流(nav:96/content:24/table:4)     │ │  │  │
│  │  │  │                                               │ │  │  │
│  │  │  │  每页自动执行:                                │ │  │  │
│  │  │  │  ┌───────────────────────────────────────────┐│ │  │  │
│  │  │  │  │ 1. waitForPageReadiness  — 渲染稳定检测   ││ │  │  │
│  │  │  │  │ 2. expandNavigationControls — 展开折叠菜单││ │  │  │
│  │  │  │  │ 3. inspectCurrentPage — 提取表单/链接/候选││ │  │  │
│  │  │  │  │ 4. createBaselineAssertions — 生成断言    ││ │  │  │
│  │  │  │  │ 5. enrichSafeInteractions — 枚举安全交互  ││ │  │  │
│  │  │  │  │    (详情展开/弹层/分页/查询筛选)          ││ │  │  │
│  │  │  │  │ 6. enqueueLinkCandidates — 新链接入队     ││ │  │  │
│  │  │  │  └───────────────────────────────────────────┘│ │  │  │
│  │  │  │                                               │ │  │  │
│  │  │  │  maybeAutoLoginWithProvidedAuth — 自动登录     │ │  │  │
│  │  │  └───────────────────────────────────────────────┘ │  │  │
│  │  └────────────────────────────────────────────────────┘  │  │
│  └───────────────────────────────────────────────────────────┘  │
└─────────────────────────────────────────────────────────────────┘
                          │
                          ▼
┌─ SiteConfig (JSON) ─────────────────────────────────────────────┐
│  结构化测试规格:pages · interactions · steps · assertions      │
│  Automation Engine 自动生成 + LLM 可补充 + 人可编辑 + Chat 修改 │
└──────────────┬──────────────────────────────┬───────────────────┘
               │                              │
               ▼                              ▼
┌─ Runner(零 LLM)──────────┐  ┌─ Chat Refiner ──────────────┐
│  纯机械回放                 │  │  自然语言对话修改配置        │
│  · 并发执行 (p-limit)      │  │  · 14 个工具(增删改查配置  │
│  · 断点续跑(原子写入)     │  │    + 浏览器验证 + 跑测试)  │
│  · 元素定位降级             │  │  · 修改后自动保存           │
│    ref → selector → role   │  │  · 即时验证:改完直接跑     │
│  · 8 种确定性断言           │  └─────────────────────────────┘
│  · 基础设施故障检测         │
│    连续 3 页失败 → 终止     │
│  · 认证运行规划             │
│    shared-session /         │
│    run-state /              │
│    per-session-profile      │
└──────────────┬──────────────┘
               ▼
┌─ Reporter ──────────────────────────────────────────────────────┐
│  单文件 HTML(内联 CSS,无外部依赖)                            │
│  · 通过率仪表盘 + 覆盖率指标 + 性能统计                        │
│  · 失败项:步骤 + 断言 + 截图                                  │
│  · 表单待补充清单 + 慢页面清单                                  │
│  · 自动轮转保留最近 N 份                                        │
└─────────────────────────────────────────────────────────────────┘
               │
               ▼
┌─ 基础设施层 ────────────────────────────────────────────────────┐
│  agent-browser (execFile 直连)     LLM Client (原生 fetch)      │
│  32 个浏览器操作函数                分类重试: 429退避/500重试    │
│  SSL 降级重试 / 瞬态故障重试        /超时重试/400不重试          │
│  window.open 拦截                  60s 超时 / 无 SDK 依赖       │
└─────────────────────────────────────────────────────────────────┘

核心数据流

首次探索                                          后续回放
(LLM 1~5 次调用 + Automation Engine BFS 遍历)     (零 LLM,纯机械执行)
─────────────────────────────────                 ─────────────────────────

用户 URL ──→ Preflight 检查 ──→ callLLM ──→ tool_calls
                                  │
                    executeTool("browser_open")
                                  │
                    drainFrontierDeterministically (BFS)
                    · 每页: JS注入 → 链接发现 → 断言生成 → 交互枚举
                    · 深度可配置 (--depth, 默认 5)
                                  │
                    maybeAutoLoginWithProvidedAuth
                                  │
                    executeTool("finish_exploration")
                                  │
                                  ▼
                             SiteConfig
                                  │
                  ┌───────────────┴───────────────┐
                  ▼                               ▼
                Runner ──→ RunResult ──→ HTML Report
                  │                               │
             Chat 补充 ←──── 查看报告 ←───────────┘
           (可选,按需)

安装

npm install -g agent-e2e

安装后会自动下载 Chrome 浏览器(通过 agent-browser install)。

本地开发

git clone https://github.com/autumnice/agent-e2e.git
cd agent-e2e
npm install
npm run build
npm link

快速开始

# 1. 配置 LLM(首次)
agent-e2e config

# 2. 探索 + 回放(首次消耗 Token,生成 SiteConfig)
agent-e2e run https://example.com

# 3. 后续回放(零 Token,纯机械执行)
agent-e2e run example-com

# 4. Chat 补充配置(可选,如补充表单、修改断言)
agent-e2e chat example-com

私有站点首次探索可显式提供登录凭证:

agent-e2e run https://internal.example.com --username demo --password '***'

--username/--password 只作为本次命令的内存态 bootstrap 输入使用,不会进入 LLM prompt,也不会默认明文落盘。登录成功后,运行时会优先把认证提升为站点级引用:

  • 标准用户名密码表单:优先提升为 vault
  • 无法安全托管到 vault 时:回退为站点级 state
  • SSO / OAuth / 2FA / 已登录浏览器:推荐显式使用 auth importauth profile

Explorer / Chat 只会看到“存在可用认证来源”的声明,以及 ${auth.username} / ${auth.password} 占位符,不接触真实凭证。历史明文 auth 配置会在运行时尝试一次性迁移到 vaultstate;迁移失败时会 fail-closed 阻断执行并给出迁移原因。

复杂登录站点推荐先把认证路径显式建模:

# 已登录浏览器导入为站点级 state(推荐 SSO / OAuth / 2FA / 已登录 Chrome 场景)
agent-e2e auth import https://internal.example.com

# 直接绑定 Chrome profile(profile name 或 profile path)
agent-e2e auth profile internal-example-com --profile Default

# 查看当前站点类型判断、推荐路径、fan-out 计划与最近真实运行记忆
agent-e2e auth doctor internal-example-com --concurrency 4

说明:

  • auth import 底层调用 agent-browser --auto-connect state save;需要本机存在已登录的 Chrome,并开启远程调试
  • auth profile --profile Default 这类 profile name 会按 per-session-profile 规划并发
  • auth profile --profile /path/to/profile 这类 profile path 默认 correctness-first 串行
  • 已证明 vault -> run-state 不可用的站点,会改用 run-profile:先用 vault 生成完整 profile 模板,再复制给并发页面

回放阶段不会再为每个页面机械地重复登录。Runner 会根据认证源与最近一次真实运行证据,自动选择运行期 fan-out 策略:

  • shared-session:整轮复用一条共享会话;适用于串行运行,或其它 fan-out 都被真实证据证伪的站点
  • run-state:先预热一条代表会话,再导出本次 run 的临时 state 给并发页面复用;适用于 state / session / vault
  • run-profile:先用 vault 预热完整 profile 模板,再复制独立 profile 给并发页面复用;适用于依赖完整 browser state、但可由 vault 登录的站点
  • per-session-profile:每个页面会话独立消费同一个 profile name;适用于 profile(name)

精确结果可以通过 agent-e2e auth doctor <site-id> --concurrency <n> 查看;真实运行后,planner 还会把 plannedFanout / actualFanout 与 run-state 能力记忆回写到站点配置中,后续直接避开已证伪路径。

命令

agent-e2e config                                                    # 交互式配置引导
agent-e2e config set <key> <value>                                  # 单项修改
agent-e2e config show                                               # 查看生效配置、数据路径与可设置项(apiKey 脱敏)
agent-e2e help [command]                                            # 友好帮助入口,例如 help run
agent-e2e list                                                      # 列出已配置站点
agent-e2e run <url|site-id> [--concurrency 3] [--depth 5] [--username <u> --password <p>] [--repair-allowed-domains] [--skip-url-preflight] [--skip-llm-preflight]
agent-e2e explore <url> [--depth 5] [--username <u> --password <p>] [--skip-url-preflight] [--skip-llm-preflight] # 重新探索
agent-e2e auth import <url|site-id>                                 # 导入已登录浏览器状态为站点级 state
agent-e2e auth profile <url|site-id> --profile <name|path>          # 配置站点使用 Chrome profile
agent-e2e auth doctor <url|site-id> [--concurrency 3]               # 诊断站点认证源与 fan-out 规划
agent-e2e auth clear <url|site-id>                                  # 清理站点认证引用与托管副产物
agent-e2e allowed-domains inspect <url|site-id>                     # 查看资源域白名单候选与证据
agent-e2e allowed-domains approve <url|site-id> <host>              # 确认候选域并加入 allowedDomains
agent-e2e allowed-domains reject <url|site-id> <host>               # 拒绝候选域,后续降低提示噪声
agent-e2e allowed-domains remove <url|site-id> <host>               # 从 allowedDomains 移除域
agent-e2e chat <url|site-id>                                        # 聊天模式补充配置
agent-e2e schedule <url|site-id> --cron "0 9 * * 1"                 # 生成 crontab 行

说明:

  • run:新 URL 先探索再回放;已有站点直接回放;默认按 auto-static 策略自动学习低风险静态资源域
  • run 在探索完成后会继续打印回放阶段、逐页进度与报告生成阶段,避免“看起来卡住”
  • explore:显式重新探索站点
  • auth import:把当前已登录浏览器状态收口为站点级 imported state
  • auth profile:把站点绑定到 agent-browser --profile <name|path> 能力
  • auth doctor:输出站点类型判断、推荐路径、planner fan-out 结果、并发限制原因和最近真实运行记忆
  • auth clear:清理站点认证源引用,以及站点托管的 state / session / vault 副产物
  • allowed-domains:维护报告中发现的资源域候选;低风险静态资源可自动写入,API / WebSocket / iframe / SSO 等默认只进入候选,需 CLI 或 chat 确认
  • chat:补充页面、交互、hook,并可即时执行测试;内置 annotated screenshot、console/errors、network/har、diff、inspect、stream、资源域白名单确认等同 session 诊断入口
  • schedule:仅生成 crontab 行,不内置调度器
  • help--help 的友好别名,支持 agent-e2e help run / agent-e2e help config set
  • --skip-url-preflight:只跳过目标 URL 可达性预检,不影响浏览器与其它安全约束
  • --skip-llm-preflight:只跳过 LLM 可用性预检,适合已知代理或离线调试场景
  • 显式提供 --username/--password 时,Explorer 会优先尝试标准用户名/密码登录表单的确定性自动登录;识别失败时再交给 LLM 处理
  • 一旦进入业务域,Explorer 会沿同域 frontier 做确定性页面遍历,优先把页面清单和基础渲染 interaction 全部沉淀下来
  • Explorer 对慢页 / SPA 不依赖单次 wait --fn;改为分层 readiness 轮询,并自动展开通用导航折叠项(如 aria-expanded="false" 的菜单树)
  • 若起始 URL 是 http://、但业务实际稳定落在同域 https://,Explorer 会自动把 SiteConfig.baseUrl 收敛到真实业务 origin,避免 secure cookie 在回放时丢失
  • Runner 的登录态复用遵循 agent-browser 原生用法,但不会把所有站点都压成同一种并发路径;会按 shared-session / run-state / run-profile / per-session-profile 策略做规划,并把真实运行证据回写为后续记忆
  • text_visible / text_not_visible 断言在页内直接求值,只回传短摘录,避免大型后台页面把整页 body 文本拉回本地造成执行抖动
  • 对私有/测试环境,如果页面初次打开遇到 ERR_BLOCKED_BY_CLIENT、证书或 SSL 错误,或 Chromium 落到 chrome-error://chromewebdata/ 内部错误页,browserOpen 会自动做一次 https + --ignore-https-errors 的安全降级重试

配置

全局配置文件默认位于 ~/.agent-e2e/config.json

{
  "llm": {
    "baseUrl": "https://api.openai.com/v1",
    "apiKey": "sk-...",
    "model": "gpt-4o"
  },
  "reports": {
    "maxPerSite": 7
  }
}

说明:

  • reports.maxPerSite 表示“每个站点最多保留最近 N 次运行产物”
  • 运行产物包含:HTML 报告、_runs/ 下的机器结果 JSON、对应截图目录
  • 报告目录当前不支持单独配置;如需迁移路径,请设置 AGENT_E2E_HOME
  • 新站点默认启用安全基线:contentBoundaries=trueallowedDomains 默认收敛到 baseUrl 精确主机、allowedDomainPolicy=auto-staticmaxOutput=12000
  • 运行时会把疑似被安全边界阻断的资源域记录为结构化候选;低风险 HTTPS 静态资源域可自动写入,写入和未写入都会在 HTML 报告和 _runs/*.json 里展示
  • 可按站点配置细化 allowedDomainsallowedDomainPolicyactionPolicyconfirmActionsmaxOutput,但 skip preflight 不会放宽这些安全限制

支持环境变量覆盖:

  • AGENT_E2E_HOME
  • AGENT_E2E_LLM_BASE_URL
  • AGENT_E2E_LLM_API_KEY
  • AGENT_E2E_LLM_MODEL

数据目录

~/.agent-e2e/
├── config.json
├── sites/
│   ├── <site-id>.json
│   └── <site-id>.auth-state.json   # 仅当站点当前使用 managed state 时存在
└── reports/
    └── <site-id>/
        ├── <run-id>.html
        ├── _runs/<run-id>.json
        └── screenshots/<run-id>/

说明:

  • <run-id>.html 是给人看的报告
  • _runs/<run-id>.json 是 Runner 的机器结果与续跑状态文件,不面向普通阅读,但保留给自动化集成与恢复逻辑使用
  • <site-id>.json 会保存站点认证引用以及 runtimeAuth 运行记忆,例如最近一次 plannedFanout / actualFanout 与 run-state 能力结论
  • <site-id>.auth-state.json 只在站点当前使用 state 认证源时存在,不会把真实账号密码写入站点配置
  • session 持久态保存在 ~/.agent-browser/sessions/vaultprofileagent-browser / Chrome 自身管理,站点配置里只保存引用
  • reports/<site-id>/_runs/<run-id>.json.auth-state.json 这类 run-scoped 临时 state 仅在 run-state fan-out 时短暂存在,完成后会自动清理

调试

  • 查看当前配置:agent-e2e config show
  • 查看命令帮助:agent-e2e helpagent-e2e help run
  • chat 会话中可直接调用 annotated screenshot、console/errors、network requests/har、diff、inspect、stream status;人工接管后仍回到同一 session 继续
  • 仅验证构建产物:node dist/cli.js --help
  • 本地门禁:npm run typecheck && npm test && npm run build

License

MIT