内容
# 哨兵
[](https://www.npmjs.com/package/@trysentinel/qa)
[](https://github.com/we-building-autonomously/sentinel/actions/workflows/sentinel.yml)
[](LICENSE)
**浏览器原生测试框架。** 编码代理擅长编写软件,但不擅长测试软件。 哨兵是缺失的一半:您将任务、用户意图和应用元数据(URL、登录)交给它 - 它像真实用户一样驱动真实浏览器,然后返回**通过/失败判决和评论**,就像手动测试的QA工程师签收一样。
它是质量保证(QA)领域的编码代理:相同的循环(感知→思考→行动→验证),但**浏览器原生**而非代码原生。
```
测试规范(任务 + 意图 + 应用元数据)
│
├─▶ 计划器 将意图转化为可观察的检查点
├─▶ 代理 通过引用地址的DOM工具驱动Chromium(克劳德工具使用循环)
├─▶ 裁判 严格按照检查点对轨迹进行裁决
└─▶ 报告器 JSON + Markdown + 自包含的HTML报告、截图、Playwright跟踪
```
## 为什么使用引用地址的DOM,而不是像素
哨兵在每一步都重新索引页面:注入的脚本为每个**可见的、可交互的**元素添加`data-sn-idx`并发出紧凑的、令牌高效的列表(`[12] <button> "Sign in" role=button`)。模型通过索引寻址元素;执行器将索引解析回Playwright定位器。 这比截图/坐标点击更可靠、更便宜,并且它将模型置于真实的可访问性树中。
## 安装
```bash
npm install -g @trysentinel/qa # 安装CLI + 获取驱动的Chromium
export ANTHROPIC_API_KEY=sk-ant-... # 驱动浏览器的模型
```
这将`sentinel`命令放在您的PATH上。 如果您不喜欢全局安装? `npx @trysentinel/qa <command>`也可以。
安装会为您下载Chromium(约150MB,一次性)。 如果您使用`--ignore-scripts`安装或下载被阻止,请使用`npx playwright install chromium`一次性获取 - `sentinel doctor`如果Chromium缺失,会提示您。
<details>
<summary>从源代码(适用于贡献者)</summary>
```bash
git clone https://github.com/we-building-autonomously/sentinel.git
cd sentinel
npm install # 安装后获取Chromium
npm run build && npm link
```
</details>
## 预检
```bash
sentinel doctor
```
检查Node版本、`ANTHROPIC_API_KEY`、Chromium安装、输出目录可写性和(如果设置了密钥)API可达性。 仅在硬故障时退出非零。
## 运行
```bash
npm run build
node dist/cli.js run specs/example.todomvc.json
# 或,无需构建:
npm run dev -- run specs/example.search.yaml --headed
```
退出代码:`0` 通过 · `1` 失败 · `2` 不确定/错误 - 因此它直接进入CI。
添加 `--fail-on <gates>` (在`run`或`suite`上)以硬失败构建在QA维度违规 **独立于功能判决**,用逗号分隔:`a11y` · `a11y-critical` (仅关键/严重)· `perf` · `visual` · `layout` (水平溢出)· `security` (高/中度缺少头部/cookie发现)· `errors` (任何未捕获的JS异常/控制台错误/ 5xx)· `requests` · `text` · `url` (最终URL缺少必需的子字符串或具有禁止的子字符串)· `state` (缺少cookie/存储条目、错误或未清除)· `downloads` · `clipboard` · `toast` (对应类型的未满足断言)。 例如,`--fail-on visual,errors,layout`在视觉回归、运行时错误或响应式布局溢出时使构建失败。 网关违规还会将其JUnit测试用例转换为`<failure>`,因此CI仪表板与退出代码匹配。
在 **套件** 上, `--fail-on-triage product-defect,blocked,…` (或`actionable`)通过 *分诊类别* 决定通过/失败,因此CI仅在真正的产品缺陷上失败,而当运行被CAPTCHA或关闭的登台框阻止时保持绿色。
**GitHub Actions** 是 一流的: 在工作流中(通过`GITHUB_ACTIONS`自动检测,或强制使用`--github`), 哨兵将渲染的结果表写入 **作业摘要** (`$GITHUB_STEP_SUMMARY`)并发出 **工作流注释** - `::error` 用于产品缺陷,`::warning` 用于阻止/不确定的运行 - 因此失败内联显示在运行和PR上。 与 `--shard` 和 `--junit` 配合使用,以实现完整的CI设置。
添加 `--json` 到 `run` 或 `suite` 以获取稳定的、经过编辑的机器可读结果到stdout(日志输出到stderr),例如 `sentinel run spec.yaml --json | jq .decision`。 添加 `--video` 以记录运行(嵌入到HTML报告中的`.webm`)。
### 快速一次性(无规格文件)
对于临时检查,跳过YAML:
```bash
sentinel try https://app.example.com --task "登录并打开设置" \
--intent "显示设置页面" --user me@x.com --pass '…' \
--expect-text "设置" --forbid-text "未定义"
```
`--expect-text` / `--forbid-text` (可重复)断言页面内容(见下文); `--a11y` 、 `--viewport` 、 `--headed` 、 `--video` 、 `--json` 全部有效。
## 项目配置
在存储库根目录中添加一个`sentinel.config.json`以获取项目范围的默认值 - `model` 、 `judgeModel` 、 `maxSteps` 、 `runsDir` 、 `baselinesDir` 、 `headed` 、 `video` 、超时。 优先级为 **CLI标志→环境→配置文件→内置默认值** ,API密钥永远不会从文件中读取(仅限环境/`.env`):
```json
{ "model": "claude-sonnet-4-6", "maxSteps": 30, "runsDir": "artifacts", "baselinesDir": ".sentinel/baselines" }
```
## 规格格式
```jsonc
{
"title": "用户可以注册",
"task": "创建新帐户并进入仪表盘",
"intent": "注册后,用户会进入显示其电子邮件的身份验证仪表盘",
"app": {
"url": "https://app.example.com",
"auth": { "username": "qa@example.com", "password": "..." }, // 在报告中编辑
"notes": "注册链接在右上角。"
},
"criteria": ["仪表盘显示用户的电子邮件"], // 可选;否则从意图中派生
"maxSteps": 40
}
```
YAML规格也有效(参见`specs/`)。 凭证在运行时传递给代理,但 **从写入磁盘的每个工件中编辑** 。
### 模板
规格中的任何字符串都可以使用`{{token}}`占位符,在每次运行时解析一次:
`{{randomEmail}}` 、 `{{randomString}}` 、 `{{uuid}}` 、 `{{timestamp}}` 和 `{{env.NAME}}` 。 因此,注册测试每次运行都会获得一个 *全新* 的电子邮件(不会出现“电子邮件已占用”的错误),而一个规格可以通过`{{env.APP_URL}}`针对任何环境。 参见`specs/example.signup.yaml`。
### 视觉回归
在规格上设置`"visual": true` (或 `{ "maxDiffRatio": 0.02 }` )以将最终页面与保存的基准截图进行比较。 第一次运行在`baselines/<spec-id>.png`下捕获基准(提交它);后续运行与之进行像素差异比较,并在回归时发出突出显示的`visual-diff.png`在运行目录中(嵌入在HTML报告中)。 尺寸变化被视为回归。
当差异是预期的(重新设计)时,将新的截图提升为基准:
```bash
sentinel approve # 列出具有待定视觉差异的运行
sentinel approve --all # 将它们全部提升到baselines/
sentinel approve runs/<dir> # 提升一个运行
```
### 性能预算
每次运行都会捕获初始页面的加载指标(TTFB、FCP、DOMContentLoaded、load、传输大小),并在报告中显示。 在规格中添加`perfBudget` (毫秒)以使缓慢的加载成为一个发现 - `{ loadMs: 5000, fcpMs: 2500 }` - 超出部分被报告,裁判将其视为值得失败的问题。
### 无障碍审计
在规格上设置`"a11y": true`以对最终页面运行[axe-core](https://github.com/dequelabs/axe-core)无障碍审计。 违规行为(按影响排序:关键→次要)出现在报告和`--json`中,并作为问题传递给裁判。 参见`specs/example.todomvc.json`。
### 内容和网络断言
除了LLM判决外,规格可以声明 **客观的、确定性的** 检查:
- `"expectText": ["订单确认"]` / `"forbidText": ["未定义", "NaN", "{{name}}"]` - 必须/不必须出现在最终页面的确切文本。 `forbidText`捕获一整类裁判可能会忽略的错误:未渲染的模板变量、字符串化的`undefined`/`NaN`/`[object Object]`、泄露的错误字符串。
- `"expectUrl": ["/dashboard"]` / `"forbidUrl": ["/login", "error="]` - **最终页面URL**必须/不必须包含的子字符串。 客观地固定重定向:是否登录到仪表盘并实际离开`/login`? 是否检查是否到达`/order/123`且无`error=`查询?
- `"expectRequests": [{ "url": "/api/save", "method": "POST", "status": 200 }]` - 应用程序必须(或,带有`"min": 0`,必须 **不**)进行匹配的HTTP调用。 捕获乐观UI错误,其中屏幕显示“已保存”,但实际上并未发送任何内容。
`expectRequests`还可以断言有效负载与`"bodyIncludes": "sku-"`(有效负载必须包含的子字符串)。 更多确定性检查:
- `"expectDownloads": [{ "filename": "report-*.csv", "contentIncludes": "sku-1" }]` - 下载的导出文件,其名称/内容匹配(验证文件,而不仅仅是收到一个)。
- `"expectClipboard": "tok_…"` - “复制”按钮复制了此子字符串(通过`navigator.clipboard.writeText`捕获)。
- `"expectToast": "已保存"` - 出现了一个toast/status(`aria-live`)消息 - 即使它在一秒钟内消失,因此它不是一个竞争。
- `"expectState": [{ "scope": "cookie", "key": "cookie_consent", "value": "accepted" }, { "scope": "localStorage", "key": "cart", "absent": true }]` - 断言应用程序在运行后在浏览器中 **持久化**的内容(cookie / `localStorage` / `sessionStorage`):令牌在登录时存储,同意设置一个cookie,购物车键在注销时被清除。 `value`是一个子字符串; `absent: true`要求键消失。 这是LLM裁判无法看到的状态。
所有断言都馈送裁判(未满足的断言是强有力的失败证据) **和** 匹配的确定性`--fail-on`网关。 参见`specs/example.assertions.yaml`以获取一个工作示例。
至关重要的是,这些断言是 **客观的验收标准,而不是仅仅提示**:如果LLM裁判返回`pass`,而任何声明的断言未满足,则判决自动协调为`fail`(相同的机器纠正捕获`pass`与自己的检查点相矛盾)。 伪造的测试是QA工具可能发出的单个最危险的输出,因此客观真相总是覆盖裁判 - 覆盖记录在判决的问题中,置信度上限。
### 安全审计和响应式布局
`"security": true`审计主文档的响应头(CSP、HSTS、X-Frame-Options等) **和** 会话cookie标志(HttpOnly/Secure/SameSite)。 每次运行还会标记 **水平溢出** (内容比视口更宽 - 响应式错误),在报告中显示,并可通过`--fail-on layout`进行网关。 两者都由裁判仅在意图是关于安全/布局时才予以考虑。
### 安全头审计
设置`"security": true`以审计主文档的响应头并标记缺少的防御 - Content-Security-Policy(高)、 `X-Content-Type-Options: nosniff` / X-Frame-Options(或CSP `frame-ancestors`)/ HSTS-on-HTTPS(中)、Referrer-Policy +服务器/堆栈信息泄漏(低)。 发现结果出现在报告和`--json`中; `--fail-on security`在高/中发现时使构建失败。
### 文件上传
规格的`uploads`列出测试可以附加的文件路径:`"uploads": ["./fixtures/avatar.png"]`。 当流程点击文件输入时,Sentinel自动将文件提供给原生选择器(为多步骤上传旋转它们,为多选输入提供所有文件)。 如果没有配置文件,选择器会被干净地取消 - 无论如何,代理都不会在原生对话框上挂起。
### 网络模拟
规格的`mocks`存根匹配请求,以便您可以测试难以触发的真实状态 - 一个API `500`,一个空列表,一个慢/加载响应。 每个模拟都匹配一个URL通配符(可选的方法)并使用`json`/`body` + `status`(+ `delayMs`)实现。 代理被告知哪些端点被存根,以便它将生成的状态视为预期。 参见`specs/example.error-state.yaml`。
### 保护登台环境
要测试具有门控的预览/登台URL,规格的`app`可以携带`headers`(例如Vercel/Cloudflare绕过令牌)、`httpCredentials`(HTTP基本身份验证)和/或`cookies`(功能标志或会话cookie)。 所有值都 **从每个报告中编辑**。 参见`specs/example.staging.yaml`。
### 视口和设备
规格的`viewport`(或`run --viewport …`)测试响应式/移动布局:一个预设(`desktop` / `tablet` / `mobile`),一个Playwright设备名称(`"iPhone 13"`),或`WIDTHxHEIGHT`。 移动预设应用触摸+设备缩放+移动用户代理,代理被告知它处于狭窄布局。 参见`specs/example.mobile.yaml`。
## 搭建规格
不要从头开始编写规格 - 将Sentinel指向一个URL,它将分析页面(标题、表单、主要操作、登录检测)并生成一个有根据的启动规格:
```bash
sentinel init https://app.example.com/login --out specs/login.yaml
```
它会自动填充应用程序名称、标签(发现登录表单时为`auth`)、身份验证块和基于真实表单字段的任务 - 留下明确的TODO供您完善。 不需要API密钥。
使用 `--draft` (和`ANTHROPIC_API_KEY`),模型从页面配置文件中编写 **可立即运行的测试用例**,而不是TODO存根,作为一个套件发出:
```bash
sentinel init https://app.example.com/login --draft --count 4 --out specs/login-suite.yaml
```
## 套件和一次性登录
将许多测试分组到一个应用程序下并并行运行:
```bash
sentinel suite specs/example.suite.yaml --concurrency 3 --junit results.xml
```
套件在`defaults`下声明应用程序`url`/`auth`一次(合并到每个规格中,规格级别优先)并可以声明一个`login`规格,该规格运行 **一次**;其身份验证的`storageState`(cookie + localStorage)然后被其他每个规格重用 - 无需重复登录,速度更快,波动更小(参见`specs/example.authed-suite.yaml`)。 套件写入一个聚合的HTML仪表盘,链接每个运行。
**数据驱动案例。** 给规格一个`cases`列表,以每行运行一次,每行的字段作为`{{tokens}}`和`name`用于`[case]`标题后缀 - 一个定义涵盖许多输入而不是N个复制的规格。 在`sentinel run spec.yaml`和套件内(并与视口矩阵组合)均有效。 参见`specs/example.data-driven.yaml`:
```yaml
task: "使用信用卡 {{card}} 并提交"
expectText: ["{{outcome}}"]
cases:
- { name: visa, card: "4111111111111111", outcome: "订单确认" }
- { name: declined, card: "4000000000000002", outcome: "支付被拒绝" }
```
**模拟** 主题/国际化/无障碍测试:规格可以设置 `emulate: { colorScheme: dark, reducedMotion: reduce, locale: "zh-CN", timezoneId: "Asia/Tokyo" }` 以驱动应用程序在暗模式下,减少运动或给定区域(影响`Intl`日期/数字/货币格式和`navigator.language`)和时区(影响显示的日期/时间)。 激活的模拟也被告知代理,因此它期望本地化/黑暗的UI。 与`visual`(暗模式视觉回归)和`expectText`/`expectState`(本地化副本)自然配对。
**冻结时钟** 以实现确定性的日期/时间UI:`clock: { now: "2026-01-15T09:00:00Z" }` (ISO字符串或纪元毫秒)将浏览器的`Date.now()`/`new Date()`冻结到该瞬间,因此“今天的日期”,相对时间戳(“2小时前”),倒计时和试用期横幅都是可重现的 - 没有更多今天通过而明天失败的测试。 计时器仍然有效,因此应用程序不会停滞。 代理被告知冻结的“现在”。 与`emulate.timezoneId`组合使用。
添加 **矩阵** 以在 **笛卡尔积** 轴上运行每个规格 - `matrix: { viewport: [desktop, mobile], colorScheme: [light, dark], locale: [en-US, fr-FR] }` 运行每个规格8次(每个组合),或在CLI上设置它们为`--viewports`, `--color-schemes`, `--locales`。 每个变体都设置相应的视口/ `emulate.colorScheme` / `emulate.locale` 并在仪表盘和历史记录中显示为`Title [mobile · dark · fr-FR]` - 一个规格涵盖响应式 × 主题 × 国际化在一个套件运行中。
**跨CI工作节点分片。** 对于一个大型套件,将工作分布在并行机器上,使用`--shard i/n`(1为基数,如Playwright/Jest):每个工作节点运行一个确定性、平衡的轮询切片(包括矩阵变体),并且一次性登录仍然在每个工作节点上运行,以便每个节点都有自己的身份验证会话。 空分片退出0(正常的CI结果)。 每个工作节点都编写自己的`--junit`文件,供CI合并。
# .github matrix → 4 parallel jobs:
- run: sentinel suite specs/all.suite.yaml --shard ${{ matrix.i }}/4 --junit results-${{ matrix.i }}.xml
## 状态隔离的设置 / 清除钩子
状态隔离的设置 / 清除钩子是解决 flaky 端到端测试的最大良药。规范可以在运行前(`setup`)和运行后(`teardown`)发送 HTTP 请求,以通过 API 准备和清理自己的数据,而不是依赖应用程序留下的状态:
```yaml
setup: # 在浏览器启动前通过 API 重置/播种;失败会阻止运行
- { method: DELETE, url: "{{env.API}}/test/cart", headers: { Authorization: "Bearer {{env.TOKEN}}" } }
teardown: # 之后尽力清理
- { method: POST, url: "{{env.API}}/test/reset" }
```
URL 和正文会解析为 `{{template}}`(因此它们与每个案例的 `cases` 数据一致),身份验证头/正文会在报告中被删除,设置失败会被归类为 `blocked`(测试无法在准备好的状态下运行)而不是产品缺陷。
您也可以在单个运行中手动捕获/重用身份验证:
```bash
sentinel run login.yaml --save-state auth.json # 捕获一次
sentinel run checkout.yaml --storage-state auth.json # 重用
```
## 双因素(TOTP)登录
给规范一个 base32 身份验证器密钥,值为 `"auth": { …, "totpSecret": "JBSWY3DPEHPK3PXP" }`,代理会获得一个 `get_totp` 工具,根据需要生成当前的 6 位代码 - 因此受 2FA 保护的登录完成,而不是在代码提示时卡住(密钥会从所有报告中删除;短暂的代码不会存储)。
## CI
一个可立即使用的 GitHub Actions 工作流在 `.github/workflows/sentinel.yml` 中(构建 → 单元测试 → 运行套件 → 上传 `runs/` + JUnit → 在检查 UI 中显示结果)。对于密封运行,`Dockerfile` 捆绑了 Chromium 和所有操作系统依赖:
```bash
docker build -t sentinel .
docker run --rm -e ANTHROPIC_API_KEY -v "$PWD/specs:/app/specs" sentinel suite specs/example.suite.yaml
```
对于 GitLab CI,在 CI/CD 变量中保留 `ANTHROPIC_API_KEY` 并发布 JUnit 文件作为测试报告:
```yaml
stages:
- qa
sentinel:
image: mcr.microsoft.com/playwright:v1.50.0-noble
stage: qa
script:
- npm ci
- npm run build
- npx playwright install chromium
- mkdir -p test-results
- node dist/cli.js suite specs/example.suite.yaml --junit test-results/sentinel.xml
artifacts:
when: always
reports:
junit: test-results/sentinel.xml
paths:
- runs/
```
对于 CircleCI,将 `ANTHROPIC_API_KEY` 存储为项目环境变量并上传相同的 JUnit 输出:
```yaml
version: 2.1
jobs:
sentinel:
docker:
- image: mcr.microsoft.com/playwright:v1.50.0-noble
steps:
- checkout
- run: npm ci
- run: npm run build
- run: npx playwright install chromium
- run: mkdir -p test-results
- run: node dist/cli.js suite specs/example.suite.yaml --junit test-results/sentinel.xml
- store_test_results:
path: test-results
- store_artifacts:
path: runs
workflows:
qa:
jobs:
- sentinel
```
## 监视模式
对规范进行迭代并获得即时反馈 - 文件更改时重新运行:
```bash
sentinel watch specs/login.yaml --headed
```
编辑的突发会被去抖动,运行永远不会重叠,Ctrl+C 会干净地停止。适用于单个规范和套件。
## 历史/趋势仪表盘
将过去的所有运行聚合到质量趋势视图(通过率、flakiness、每个规范的成本,并带有最近结果的 sparkline):
```bash
sentinel history # 写入 runs/index.html
sentinel history --dir runs --out reports/trend.html
```
## 通知
在完成后将套件结果发布到 Slack 或任何 webhook:
```bash
sentinel suite specs/example.suite.yaml --notify https://hooks.slack.com/services/T/B/X
# 或在环境中设置 SENTINEL_SLACK_WEBHOOK / SENTINEL_WEBHOOK_URL
```
Slack URL 会获得 Block Kit 消息(红色/绿色标题、计数、成本、**分类汇总** + 每个维度的 **QA汇总**,并且只会调用失败/flaky 规范 - 每个规范都带有其分类类别);任何其他 URL 都会收到结构化的 JSON 有效负载(`suite`、`ok`、`summary`、`costUsd`、`results[]`),您可以将其路由到任何地方。
## 分类
每次运行都会被分类到一个可操作的桶中 - `passed` · `flaky-pass` · `product-defect` · `blocked-external`(CAPTCHA/2FA/email)· `blocked` · `app-unavailable` · `inconclusive` · `skipped` - 因此红色套件会告诉您*该怎么做*(真正的错误 vs. 环境波动),而不仅仅是某些东西失败了。它会在每次运行(报告 + `--json`)中显示,汇总在一个套件中(仪表盘 + Slack),驱动一个分类感知的回归趋势(环境阻塞永远不会被视为回归),映射到 JUnit `<skipped>` 以获取环境阻塞,并且可以通过 `--fail-on-triage` 进行控制。
## 程序化使用
```ts
import { runSpec } from "sentinel";
const report = await runSpec(spec);
if (report.verdict.decision !== "pass") process.exit(1);
```
## 从您的编码代理(MCP + Claude Code 插件)使用它
编码代理编写代码;Sentinel 是检查代码是否真正适用于用户的另一半。Sentinel 通过 **Model Context Protocol** 公开其 QA 环路,因此任何支持 MCP 的代理(Claude Code、Cursor、自定义托管)都可以将其作为工具调用,并获得结构化的判决,以对抗该工具进行自我纠正。
## MCP 服务器
在 stdio 上运行:
```bash
sentinel mcp
```
它注册了一个名为 `sentinel_qa` 的工具,该工具接受 `{ url, task, intent?, user?, pass?, expectText?, forbidText?, a11y? }`,驱动一个真正的浏览器,并返回一个简洁的判决:`decision`(pass/fail/inconclusive)、`confidence`、每个检查点的 `met/unmet/unknown` 及证据、分类类别、捕获的运行时错误、成本和报告目录。
## 注册它
在 `npm install -g @trysentinel/qa` 之后。Claude Code,一行:
```bash
claude mcp add sentinel -- sentinel mcp
```
任何其他 MCP 客户端(Cursor、Windsurf、自定义托管)- 将其添加到其 MCP 配置中:
```json
{
"mcpServers": {
"sentinel": { "command": "sentinel", "args": ["mcp"] }
}
}
```
## 给代理一个规则
将其粘贴到其系统提示 / `CLAUDE.md` / `.cursorrules` 中,以便在声称功能完成之前进行 QA:
```text
在您构建或更改用户在浏览器中可以看到的任何内容后,请勿直接调用
完成,直到您像用户一样验证它:调用 sentinel_qa 工具
使用正在运行的应用程序的 URL 和真实用户执行的任务(例如“注册并进入
仪表盘”)。如果判决是带有分类的 FAIL“product-defect”,请修复
失败的检查点并重新运行,直到通过。“编译”和“工作”是
不同的声明 - sentinel 检查第二个。
```
## Claude Code 插件
此存储库也是一个 Claude Code 插件。它捆绑了 MCP 服务器、`/qa` 斜杠命令和一个 `qa-after-build` 技能,该技能在您构建功能后自动触发:
```bash
claude --plugin-dir /abs/path/sentinel
```
然后 `/sentinel-qa:qa http://localhost:3000 sign up and reach the dashboard` - 或者只是在您完成用户界面更改后,让技能启动。
## 报告到云(可选)
设置 `SENTINEL_CLOUD_URL` + `SENTINEL_API_KEY`,每个代理触发的判决都会出现在您的 [Sentinel Cloud](https://github.com/we-building-autonomously/sentinel) 仪表盘中,按积分计费(不确定的运行免费)。
## 技术栈
TypeScript · Playwright (Chromium) · Anthropic SDK (Claude 工具使用) · Zod · YAML。无需外部自动化服务 - 所有操作都在本地运行。
查看 [ARCHITECTURE.md](./ARCHITECTURE.md) 获取设计和模块映射。
## 贡献
欢迎提出问题和 PR - 从 [CONTRIBUTING.md](./CONTRIBUTING.md) 开始。请根据 [SECURITY.md](./SECURITY.md) 私密报告安全问题,并根据 [Code of Conduct](./CODE_OF_CONDUCT.md) 保持友善。
## License
[MIT](./LICENSE) 由 Sentinel contributors 版权所有。
MCP 配置
以下是此 MCP Server 的配置信息,可直接复制到 Cursor 或其他 MCP 客户端中使用。
mcp.json
连接信息
猜你喜欢
暂无推荐服务器