#157 by GitHub stars
eze-is/web-access
所有联网操作必须通过此 skill 处理,包括:搜索、网页抓取、登录后操作、网络交互等。 触发场景:用户要求搜索信息、查看网页内容、访问需要登录的网站、操作网页界面、抓取社交媒体内容(小红书、微博、推特等)、读取动态渲染页面、以及任何需要真实浏览器环境的网络任务。
History
Review weekly changes to SKILL.md before updating. Dates mark the weeks in which we observed each version; checks apply to the recorded commits.
View weekly changes
SKILL.md
Week of Nov 2, 2026 · +0 / −0 lines
Before Network or broad shell → After Network or broad shell
d173a75978ce → d173a75978ce
Diff text is unavailable under the recorded licenses. Line counts and the GitHub link remain available.
Week of Oct 26, 2026 · Line counts unavailable
Before Not checked yet → After Network or broad shell
First observation → d173a75978ce
No earlier version was observed for comparison.
Verified commit d173a75978ceb2c63fa0b27f7408cd2bf7fe4310
git clone --filter=blob:none --no-checkout https://github.com/eze-is/web-access.git .hotskills/eze-is-web-access && git -C .hotskills/eze-is-web-access checkout --detach d173a75978ceb2c63fa0b27f7408cd2bf7fe4310
# Copy each selected skill directory from .hotskills/eze-is-web-access into .claude/skills/<skill-name>/git clone --filter=blob:none --no-checkout https://github.com/eze-is/web-access.git .hotskills/eze-is-web-access && git -C .hotskills/eze-is-web-access checkout --detach d173a75978ceb2c63fa0b27f7408cd2bf7fe4310
# Copy each selected skill directory from .hotskills/eze-is-web-access into .agents/skills/<skill-name>/git clone --filter=blob:none --no-checkout https://github.com/eze-is/web-access.git .hotskills/eze-is-web-access && git -C .hotskills/eze-is-web-access checkout --detach d173a75978ceb2c63fa0b27f7408cd2bf7fe4310
# Copy each selected skill directory from .hotskills/eze-is-web-access into .gemini/skills/<skill-name>/Heat
6.6- Star growth, last 7 daysAhead of 70% of tracked repositories
- Star growth, last 24 hoursAhead of 83% of tracked repositories
- Rank movement, last 7 daysAhead of 74% of tracked repositories
- Commits, last 30 daysAhead of 86% of tracked repositories
- Accounts asking about it through MCP, last 7 daysNot available
- Hot votes this weekAhead of 0% of tracked repositories
Heat never changes the order by stars, and sponsorship never touches it. How heat works
Stars over time
Individual skills in this repository
How it works
web-access
When your agent uses it
所有联网操作必须通过此 skill 处理,包括:搜索、网页抓取、登录后操作、网络交互等。 触发场景:用户要求搜索信息、查看网页内容、访问需要登录的网站、操作网页界面、抓取社交媒体内容(小红书、微博、推特等)、读取动态渲染页面、以及任何需要真实浏览器环境的网络任务。
What it loads into context
Frontmatter
133 tokensAlways available to the agent
SKILL.md
6,083 tokensWhen the skill is activated
Reference documents
14,786 tokensLoaded on request
Token counts are estimates. Scripts run separately; they are not counted as reference context.
The playbook
- 前置检查
- 浏览哲学与工作流
- 联网工具选择
- 浏览器 CDP 模式
- 并行调研:子 Agent 分治策略
- 信息核实类任务
- 站点经验
- References 索引
Scripts executed separately
scripts/browser-discovery.mjsscripts/browser-discovery.test.mjsscripts/browser-probe.mjsscripts/browser-probe.test.mjsscripts/cdp-connection.mjsscripts/cdp-connection.test.mjsscripts/cdp-proxy.mjsscripts/cdp-proxy.test.mjsscripts/check-deps.mjsscripts/check-deps.test.mjsscripts/find-url.mjsscripts/match-site.mjsscripts/page-frames.mjsscripts/page-frames.test.mjsscripts/proxy-maintenance.mjsscripts/proxy-maintenance.test.mjsscripts/user-data.mjsscripts/user-data.test.mjs
Files
.claude-plugin/marketplace.jsonasset463 bytes.claude-plugin/plugin.jsonasset474 bytes.gitignoreasset100 bytesAGENTS.mddoc3,095 bytesCLAUDE.mddoc3,095 bytesGEMINI.mddoc3,095 bytesREADME.mddoc19,042 bytesSKILL.mdcore23,211 bytesSKILL.mdcore23,211 bytesSKILL.mdcore23,211 bytesSKILL.mdcore23,211 bytesSKILL.mdcore23,211 bytesSKILL.mdcore23,211 bytesSKILL.mdcore23,211 bytesreferences/cdp-api.mddoc12,327 bytesreferences/migration-2.5.3.mddoc4,505 bytesreferences/migration-2.6.mddoc7,638 bytesscripts/browser-discovery.mjsruns13,059 bytesscripts/browser-discovery.test.mjsruns27,293 bytesscripts/browser-probe.mjsruns9,800 bytesscripts/browser-probe.test.mjsruns19,095 bytesscripts/cdp-connection.mjsruns7,316 bytesscripts/cdp-connection.test.mjsruns13,162 bytesscripts/cdp-proxy.mjsruns29,053 bytesscripts/cdp-proxy.test.mjsruns29,702 bytesscripts/check-deps.mjsruns12,485 bytesscripts/check-deps.test.mjsruns26,716 bytesscripts/find-url.mjsruns11,412 bytesscripts/match-site.mjsruns1,574 bytesscripts/page-frames.mjsruns10,475 bytesscripts/page-frames.test.mjsruns20,614 bytesscripts/proxy-maintenance.mjsruns11,301 bytesscripts/proxy-maintenance.test.mjsruns31,348 bytesscripts/user-data.mjsruns5,764 bytesscripts/user-data.test.mjsruns10,249 bytestemplates/config.env.templateasset1,492 bytes
No excerpt is shown for this license. Read the source on GitHub.
View the complete source on GitHubSkills included
- web-access
Repository facts
- License
- No license detected
- Created
- Mar 18, 2026
- Last pushed
- Oct 14, 2026
- Forks
- 660
- Open issues
- 24
- Project activity
- Active
Rank over the last 12 weeks
Now #157 · best #134 · down 7 in 30 days
- #153 from Oct 24 to Oct 25
- #153 on Oct 28
- #155 on Oct 29
- #157 from Oct 30 to Nov 1
- #158 from Nov 2 to Nov 3
- #157 since Nov 4
46 earlier periods
- #132 on Aug 2
- #132 on Aug 7
- #131 from Aug 8 to Aug 9
- #133 on Aug 10
- #134 on Aug 11
- #135 from Aug 12 to Aug 16
- #136 from Aug 17 to Aug 21
- #134 on Aug 22
- #137 from Aug 23 to Aug 24
- #136 from Aug 25 to Aug 26
- #137 from Aug 27 to Aug 29
- #136 on Aug 30
- #137 on Aug 31
- #138 on Sep 1
- #137 on Sep 2
- #138 on Sep 3
- #137 on Sep 4
- #138 from Sep 5 to Sep 6
- #139 from Sep 7 to Sep 8
- #140 from Sep 9 to Sep 10
- #139 on Sep 11
- #140 on Sep 12
- #141 from Sep 13 to Sep 14
- #142 on Sep 15
- #141 on Sep 16
- #142 on Sep 17
- #143 from Sep 18 to Sep 19
- #144 from Sep 20 to Sep 22
- #145 from Sep 23 to Sep 24
- #146 from Sep 25 to Sep 27
- #147 on Sep 28
- #148 from Sep 29 to Sep 30
- #149 on Oct 1
- #150 on Oct 2
- #149 on Oct 3
- #150 on Oct 5
- #148 on Oct 6
- #150 from Oct 7 to Oct 8
- #151 from Oct 9 to Oct 10
- #152 from Oct 11 to Oct 13
- #153 on Oct 14
- #152 on Oct 15
- #151 on Oct 16
- #152 from Oct 17 to Oct 18
- #153 from Oct 19 to Oct 21
- #154 from Oct 22 to Oct 23
Before you install
Network or broad shellAutomated signals, not a guarantee
Checked Nov 2, 2026
Not fully analyzed: some files were too long, unreadable or missing. This never lowers the level.
Show 6 notes
SKILL.md:1Analysis incomplete: Referenced executable target unavailable; not analyzedSKILL.md:1Analysis incomplete: Referenced executable target unavailable; not analyzedSKILL.md:1Analysis incomplete: Referenced executable target unavailable; not analyzedSKILL.md:1Analysis incomplete: Referenced executable target unavailable; not analyzedSKILL.md:1Analysis incomplete: Referenced executable target unavailable; not analyzedSKILL.md:1Analysis incomplete: Referenced executable target unavailable; not analyzed
- No broad tool permissions
- 2 dangerous shell commandsin 1 file: scripts/browser-probe.test.mjs:85
- 262 network referencesin 12 files: scripts/proxy-maintenance.test.mjs:67 README.md:4 scripts/check-deps.test.mjs:154 and 9 more
- No hidden or obfuscated text
- No instruction overrides
- 18 executable scriptsin 18 files: scripts/browser-discovery.mjs:1 scripts/browser-discovery.test.mjs:1 scripts/browser-probe.mjs:1 and 15 more
- No access to secrets
- No requests to vote in Hot
Show all 282 signals by file
.claude-plugin/plugin.json
- Network accessline 6
"name": "一泽 Eze" }, "homepage": "https://github.com/eze-is/web-access", - Network accessline 7
}, "homepage": "https://github.com/eze-is/web-access", "repository": "https://github.com/eze-is/web-access", - Network accessline 8
"homepage": "https://github.com/eze-is/web-access", - Network accessline 9
"repository": "https://github.com/eze-is/web-access",
README.md
- Network accessline 4
<div> <div align="center"> <a href="https://openaitx.github.io/view.html?user=eze-is&project=web-access&lang=en">English</a> - Network accessline 5
<div align="center"> <a href="https://openaitx.github.io/view.html?user=eze-is&project=web-access&lang=en">English</a> | <a href="https://openaitx.github.io/view.html?user=eze-is&project=web-access&lang=zh-CN">简体中文</a> - Network accessline 6
<a href="https://openaitx.github.io/view.html?user=eze-is&project=web-access&lang=en">English</a> - Network accessline 7
| <a href="https://openaitx.github.io/view.html?user=eze-is&project=web-access&lang=zh-CN">简体中文</a> - Network accessline 8
| <a href="https://openaitx.github.io/view.html?user=eze-is&project=web-access&lang=zh-TW">繁體中文</a> - Network accessline 9
| <a href="https://openaitx.github.io/view.html?user=eze-is&project=web-access&lang=ja">日本語</a> - Network accessline 10
| <a href="https://openaitx.github.io/view.html?user=eze-is&project=web-access&lang=ko">한국어</a> - Network accessline 11
| <a href="https://openaitx.github.io/view.html?user=eze-is&project=web-access&lang=fr">Français</a> - Network accessline 12
| <a href="https://openaitx.github.io/view.html?user=eze-is&project=web-access&lang=de">Deutsch</a> - Network accessline 13
| <a href="https://openaitx.github.io/view.html?user=eze-is&project=web-access&lang=es">Español</a> - Network accessline 14
| <a href="https://openaitx.github.io/view.html?user=eze-is&project=web-access&lang=pt">Português</a> - Network accessline 15
| <a href="https://openaitx.github.io/view.html?user=eze-is&project=web-access&lang=ru">Русский</a> - Network accessline 21
<img width="879" height="376" alt="image" src="https://github.com/user-attachments/assets/a87fd816-a0b5-4264-b01c-9466eae90723" /> - Network accessline 23
<p align="center"> <b>给 AI Agent 装上完整联网能力的 Skill。</b><br/> <a href="https://web-access.eze.is">🌐 官网</a> · <a href="https://mp.weixin.qq.com/s/rps5YVB6TchT9npAaIWKCw">📖 设计详解</a> · <a href="#安装">⚡ 快速安装</a> - Network accessline 24
<b>给 AI Agent 装上完整联网能力的 Skill。</b><br/> <a href="https://web-access.eze.is">🌐 官网</a> · <a href="https://mp.weixin.qq.com/s/rps5YVB6TchT9npAaIWKCw">📖 设计详解</a> · <a href="#安装">⚡ 快速安装</a> </p> - Network accessline 25
<a href="https://web-access.eze.is">🌐 官网</a> · <a href="https://mp.weixin.qq.com/s/rps5YVB6TchT9npAaIWKCw">📖 设计详解</a> · <a href="#安装">⚡ 快速安装</a> - Network accessline 30
> 推荐必读:[Web Access:一个 Skill,拉满 Agent 联网和浏览器能力](https://mp.weixin.qq.com/s/rps5YVB6TchT9npAaIWKCw) ,完整介绍了 Web-Access Skill 的开发细节与 Agent Skill 设计哲学,帮助你也能写出类似通用、高上限的 Skill - Network accessline 35
> > ```text > 我要把 web-access 升级到 v2.6。升级前请先迁移我的数据:找到当前 web-access skill 的安装目录,把其中的 config.env 复制到 ~/.web-access/config.env,把 references/site-patterns/ 整个文件夹(含子文件夹)复制到 ~/.web-access/site-patterns/(Windows 上 ~ 指 %USERPROFILE%),已存在的文件不要覆盖;确认复制 - Network accessline 36
> ```text > 我要把 web-access 升级到 v2.6。升级前请先迁移我的数据:找到当前 web-access skill 的安装目录,把其中的 config.env 复制到 ~/.web-access/config.env,把 references/site-patterns/ 整个文件夹(含子文件夹)复制到 ~/.web-access/site-patterns/(Windows 上 ~ 指 %USERPROFILE%),已存在的文件不要覆盖;确认复制成功 - Network accessline 37
> 我要把 web-access 升级到 v2.6。升级前请先迁移我的数据:找到当前 web-access skill 的安装目录,把其中的 config.env 复制到 ~/.web-access/config.env,把 references/site-patterns/ 整个文件夹(含子文件夹)复制到 ~/.web-access/site-patterns/(Windows 上 ~ 指 %USERPROFILE%),已存在的文件不要覆盖;确认复制成功后再按 https: - Network accessline 46
| 能力 | 说明 | |------|------| | 联网工具自动选择 | WebSearch / WebFetch / curl / Jina / CDP,按场景自主判断,可任意组合 | - Network accessline 47
|------|------| | 联网工具自动选择 | WebSearch / WebFetch / curl / Jina / CDP,按场景自主判断,可任意组合 | | CDP Proxy 浏览器操作 | 直连用户日常浏览器(Chrome / Edge / Brave / Arc / Dia 等任意 Chromium 内核浏览器),天然携带登录态,支持动态页面、交互操作、视频截帧 | - Network accessline 48
| 联网工具自动选择 | WebSearch / WebFetch / curl / Jina / CDP,按场景自主判断,可任意组合 | - Network accessline 117
> [skills CLI](https://github.com/vercel-labs/skills) 是开源的 Agent Skill 包管理器,自动检测你的 Agent 环境并安装到正确位置。 - Network accessline 122
帮我安装这个 skill:https://github.com/eze-is/web-access - Network accessline 128
claude plugin marketplace add https://github.com/eze-is/web-access - Network accessline 135
git clone https://github.com/eze-is/web-access ~/.claude/skills/web-access - Network accessline 226
# 页面操作 curl -s -X POST --data-raw 'https://example.com' http://localhost:3456/new # 新建 tab(v2.5.3 起 URL 走 POST body) - Network accessline 227
curl -s -X POST --data-raw 'https://example.com' http://localhost:3456/new # 新建 tab(v2.5.3 起 URL 走 POST body) - Network accessline 228
curl -s -X POST "http://localhost:3456/eval?target=ID" -d 'document.title' # 执行 JS - Network accessline 229
curl -s -X POST "http://localhost:3456/click?target=ID" -d 'button.submit' # JS 点击 - Network accessline 230
curl -s -X POST "http://localhost:3456/clickAt?target=ID" -d '.upload-btn' # 真实鼠标点击 - Network accessline 231
curl -s -X POST "http://localhost:3456/setFiles?target=ID" \ - Network accessline 232
-d '{"selector":"input[type=file]","files":["/path/to/file.png"]}' # 文件上传 curl -s "http://localhost:3456/screenshot?target=ID&file=/tmp/shot.png" # 截图 curl -s "http://localhost:3456/scroll?target=ID&direction=bottom" # - Network accessline 233
curl -s "http://localhost:3456/screenshot?target=ID&file=/tmp/shot.png" # 截图 - Network accessline 234
curl -s "http://localhost:3456/scroll?target=ID&direction=bottom" # 滚动 - Network accessline 235
curl -s "http://localhost:3456/close?target=ID" # 关闭 tab - Network accessline 236
curl -s "http://localhost:3456/health" # 查看状态(含 managedTabs 数量) - Network accessline 263
MIT · 作者:[一泽 Eze](https://github.com/eze-is) · [官网](https://web-access.eze.is) - Network accessline 267
[](https://star-history.com/#eze-is/web-access&Date) - Network accessline 271
[](https://skill-history.com/eze-is/web-access) - Network accessline 273
<img width="1280" height="306" alt="image" src="https://github.com/user-attachments/assets/2afa25c2-3730-413e-b40f-94e52567249d" />
SKILL.md
- Network accessline 8
author: 一泽Eze version: "2.6.0" github: https://github.com/eze-is/web-access - Network accessline 9
version: "2.6.0" github: https://github.com/eze-is/web-access --- - Network accessline 10
github: https://github.com/eze-is/web-access - Network accessline 81
浏览器 CDP 不要求 URL 已知——可从任意入口出发,通过页面内搜索、点击、跳转等方式找到目标内容。WebSearch、WebFetch、curl 均不处理登录态。 - Network accessline 83
**Jina**(可选预处理层,可与 WebFetch/curl 组合使用,由于其特性可节省 tokens 消耗,请积极在任务合适时组合使用):第三方网络服务,可将网页转为 Markdown,大幅节省 token 但可能有信息损耗。调用方式为 `r.jina.ai/example.com`(URL 前加前缀,不保留原网址 http 前缀),限 20 RPM。适合文章、博客、文档、PDF 等以正文为核心的页面;对数据面板、商品页等非文章结构页面可能提取到错误区块。 - Network accessline 141
所有操作通过 curl 调用 HTTP API: - Network accessline 144
# 列出用户已打开的 tab curl -s http://localhost:3456/targets - Network accessline 145
curl -s http://localhost:3456/targets - Network accessline 147
# 创建新后台 tab(自动等待加载)— URL 走 POST body,避免目标 URL 含 query 时被切分 curl -s -X POST --data-raw 'https://example.com' http://localhost:3456/new - Network accessline 148
curl -s -X POST --data-raw 'https://example.com' http://localhost:3456/new - Network accessline 150
# 页面信息 curl -s "http://localhost:3456/info?target=ID" - Network accessline 151
curl -s "http://localhost:3456/info?target=ID" - Network accessline 153
# 执行任意 JS:可读写 DOM、提取数据、操控元素、触发状态变更、提交表单、调用内部方法 curl -s -X POST "http://localhost:3456/eval?target=ID" -d 'document.title' - Network accessline 154
curl -s -X POST "http://localhost:3456/eval?target=ID" -d 'document.title' - Network accessline 156
# 捕获页面渲染状态(含视频当前帧) curl -s "http://localhost:3456/screenshot?target=ID&file=/tmp/shot.png" - Network accessline 157
curl -s "http://localhost:3456/screenshot?target=ID&file=/tmp/shot.png" - Network accessline 159
# 导航(URL 走 POST body,target 走 query)、后退 curl -s -X POST --data-raw 'https://example.com' "http://localhost:3456/navigate?target=ID" - Network accessline 160
curl -s -X POST --data-raw 'https://example.com' "http://localhost:3456/navigate?target=ID" - Network accessline 161
curl -s "http://localhost:3456/back?target=ID" - Network accessline 163
# 点击(POST body 为 CSS 选择器)— JS el.click(),简单快速,覆盖大多数场景 curl -s -X POST "http://localhost:3456/click?target=ID" -d 'button.submit' - Network accessline 164
curl -s -X POST "http://localhost:3456/click?target=ID" -d 'button.submit' - Network accessline 166
# 真实鼠标点击 — CDP Input.dispatchMouseEvent,算用户手势,能触发文件对话框 curl -s -X POST "http://localhost:3456/clickAt?target=ID" -d 'button.upload' - Network accessline 167
curl -s -X POST "http://localhost:3456/clickAt?target=ID" -d 'button.upload' - Network accessline 169
# 按视口坐标真实点击 — 可点中跨站 iframe 里的元素,不激活标签页 curl -s "http://localhost:3456/clickXY?target=ID&x=120&y=90" - Network accessline 170
curl -s "http://localhost:3456/clickXY?target=ID&x=120&y=90" - Network accessline 172
# 页面里的 iframe — 列出 frameId(跨站 iframe 标 crossProcess),再在其中执行 JS curl -s "http://localhost:3456/frames?target=ID" - Network accessline 173
curl -s "http://localhost:3456/frames?target=ID" - Network accessline 174
curl -s -X POST "http://localhost:3456/eval?target=ID&frame=FRAME_ID" -d 'document.body.innerText' - Network accessline 176
# 文件上传 — 直接设置 file input 的本地文件路径,绕过文件对话框 curl -s -X POST "http://localhost:3456/setFiles?target=ID" -d '{"selector":"input[type=file]","files":["/path/to/file.png"]}' - Network accessline 177
curl -s -X POST "http://localhost:3456/setFiles?target=ID" -d '{"selector":"input[type=file]","files":["/path/to/file.png"]}' - Network accessline 179
# 滚动(触发懒加载) curl -s "http://localhost:3456/scroll?target=ID&y=3000" - Network accessline 180
curl -s "http://localhost:3456/scroll?target=ID&y=3000" - Network accessline 181
curl -s "http://localhost:3456/scroll?target=ID&direction=bottom" - Network accessline 183
# 关闭 tab curl -s "http://localhost:3456/close?target=ID" - Network accessline 184
curl -s "http://localhost:3456/close?target=ID"
references/cdp-api.md
- Network accessline 5
- 地址:`http://localhost:3456` - Network accessline 15
curl -s http://localhost:3456/health - Network accessline 46
curl -s http://localhost:3456/targets - Network accessline 52
curl -s -X POST --data-raw 'https://example.com' http://localhost:3456/new - Network accessline 54
[Credential-related source omitted] - Network accessline 61
curl -s "http://localhost:3456/close?target=TARGET_ID" - Network accessline 67
curl -s -X POST --data-raw 'https://example.com' "http://localhost:3456/navigate?target=ID" - Network accessline 76
curl -s "http://localhost:3456/back?target=ID" - Network accessline 82
curl -s "http://localhost:3456/info?target=ID" - Network accessline 88
curl -s -X POST "http://localhost:3456/eval?target=ID" -d 'document.title' - Network accessline 93
curl -s -X POST "http://localhost:3456/eval?target=ID&frame=FRAME_ID" -d 'document.body.innerText' - Network accessline 111
curl -s "http://localhost:3456/frames?target=ID" - Network accessline 124
curl -s "http://localhost:3456/clickXY?target=ID&x=120&y=90" - Network accessline 130
curl -s -X POST "http://localhost:3456/setFiles?target=ID" -d '{"selector":"input[type=file]","files":["/path/to/file1.png","/path/to/file2.png"]}' - Network accessline 136
curl -s "http://localhost:3456/scroll?target=ID&y=3000" - Network accessline 137
curl -s "http://localhost:3456/scroll?target=ID&direction=bottom" - Network accessline 143
curl -s "http://localhost:3456/screenshot?target=ID&file=/tmp/shot.png"
references/migration-2.5.3.md
- Network accessline 6
- curl -s "http://localhost:3456/new?url=https://example.com" - Network accessline 7
+ curl -s -X POST --data-raw 'https://example.com' http://localhost:3456/new - Network accessline 9
- curl -s "http://localhost:3456/navigate?target=ID&url=https://example.com" - Network accessline 10
+ curl -s -X POST --data-raw 'https://example.com' "http://localhost:3456/navigate?target=ID" - Network accessline 22
GET /new?url=https://xhs.com/explore/x?a=1&b=2 - Network accessline 25
proxy 解析结果: - `q.url = "https://xhs.com/explore/x?a=1"` ← 被截断 - Network accessline 26
- `q.url = "https://xhs.com/explore/x?a=1"` ← 被截断 - Network accessline 37
| 场景 | 旧(v2.5.2) | 新(v2.5.3) | |---|---|---| | 简单 URL | `curl ".../new?url=https://example.com"` | `curl -X POST --data-raw 'https://example.com' .../new` | - Network accessline 38
[Credential-related source omitted] - Network accessline 39
| 简单 URL | `curl ".../new?url=https://example.com"` | `curl -X POST --data-raw 'https://example.com' .../new` | - Network accessline 40
[Credential-related source omitted] - Network accessline 41
| URL 含 `#` fragment | `curl ".../new?url=https://app/page#sec"` ⚠<U+FE0F> fragment 丢失 | `curl -X POST --data-raw 'https://app/page#sec' .../new` ✓ | - Network accessline 45
| 旧 | 新 | |---|---| | `curl ".../navigate?target=ID&url=URL"` | `curl -X POST --data-raw 'URL' ".../navigate?target=ID"` | - Network accessline 47
| `curl ".../navigate?target=ID&url=URL"` | `curl -X POST --data-raw 'URL' ".../navigate?target=ID"` |
scripts/browser-discovery.mjs
- Executable scriptline 1
Executable file
scripts/browser-discovery.test.mjs
- Executable scriptline 1
Executable file
scripts/browser-probe.mjs
- Executable scriptline 1
#!/usr/bin/env node
scripts/browser-probe.test.mjs
scripts/cdp-connection.mjs
- Executable scriptline 1
Executable file
scripts/cdp-connection.test.mjs
- Executable scriptline 1
Executable file
scripts/cdp-proxy.mjs
- Executable scriptline 1
#!/usr/bin/env node - Network accessline 169
await sendCDP('Fetch.enable', { patterns: [ { urlPattern: `http://127.0.0.1:${chromePort}/*`, requestStage: 'Request' }, - Network accessline 170
patterns: [ { urlPattern: `http://127.0.0.1:${chromePort}/*`, requestStage: 'Request' }, { urlPattern: `http://localhost:${chromePort}/*`, requestStage: 'Request' }, - Network accessline 171
{ urlPattern: `http://127.0.0.1:${chromePort}/*`, requestStage: 'Request' }, - Network accessline 172
{ urlPattern: `http://localhost:${chromePort}/*`, requestStage: 'Request' }, - Network accessline 253
const server = http.createServer(async (req, res) => { const parsed = new URL(req.url, `http://localhost:${PORT}`); - Network accessline 254
const parsed = new URL(req.url, `http://localhost:${PORT}`); - Network accessline 340
error: 'v2.5.3 起 /new 改为 POST 传 URL(避免目标 URL 含 query 时被错误切分)', migration: 'references/migration-2.5.3.md', example: "curl -X POST --data-raw 'https://example.com' http://localhost:3456/new", - Network accessline 341
migration: 'references/migration-2.5.3.md', example: "curl -X POST --data-raw 'https://example.com' http://localhost:3456/new", })); - Network accessline 342
example: "curl -X POST --data-raw 'https://example.com' http://localhost:3456/new", - Network accessline 379
error: 'v2.5.3 起 /navigate 改为 POST 传 URL(避免目标 URL 含 query 时被错误切分)', migration: 'references/migration-2.5.3.md', example: "curl -X POST --data-raw 'https://example.com' 'http://localhost:3456/navigate?target=ID'", - Network accessline 380
migration: 'references/migration-2.5.3.md', example: "curl -X POST --data-raw 'https://example.com' 'http://localhost:3456/navigate?target=ID'", })); - Network accessline 381
example: "curl -X POST --data-raw 'https://example.com' 'http://localhost:3456/navigate?target=ID'", - Network accessline 663
let existing; try { const response = await fetch(`http://127.0.0.1:${PORT}/health`, { signal: AbortSignal.timeout(2000) }); - Network accessline 664
try { const response = await fetch(`http://127.0.0.1:${PORT}/health`, { signal: AbortSignal.timeout(2000) }); if (response.ok) existing = await response.json(); - Network accessline 665
const response = await fetch(`http://127.0.0.1:${PORT}/health`, { signal: AbortSignal.timeout(2000) }); - Network accessline 673
throw error; } lifecycleLog(`运行在 http://127.0.0.1:${PORT},revision=${RUNNING_REVISION}`); - Network accessline 674
} lifecycleLog(`运行在 http://127.0.0.1:${PORT},revision=${RUNNING_REVISION}`); cleanupTimer = setInterval(cleanupIdleTabs, CLEANUP_INTERVAL); - Network accessline 675
lifecycleLog(`运行在 http://127.0.0.1:${PORT},revision=${RUNNING_REVISION}`);
scripts/cdp-proxy.test.mjs
- Executable scriptline 1
Executable file - Network accessline 113
return { model: { content: [55, 65, 355, 65, 355, 315, 55, 315] } }; case 'Page.getFrameTree': return { frameTree: { frame: { id: 'user-page' }, childFrames: [{ frame: { id: 'local-frame', url: 'http://localhost/same' } }] } } - Network accessline 114
case 'Page.getFrameTree': return { frameTree: { frame: { id: 'user-page' }, childFrames: [{ frame: { id: 'local-frame', url: 'http://localhost/same' } }] } }; case 'Page.createIsolatedWorld': - Network accessline 115
return { frameTree: { frame: { id: 'user-page' }, childFrames: [{ frame: { id: 'local-frame', url: 'http://localhost/same' } }] } }; - Network accessline 146
if (message.method === 'Target.getTargets') { result = { targetInfos: [{ targetId: 'user-page', type: 'page', title: 'Fake page', url: 'about:blank' }] }; if (process.env.TEST_FRAMES === '1') result.targetInfos.push({ targetId: - Network accessline 147
result = { targetInfos: [{ targetId: 'user-page', type: 'page', title: 'Fake page', url: 'about:blank' }] }; if (process.env.TEST_FRAMES === '1') result.targetInfos.push({ targetId: 'oopif-frame', type: 'iframe', url: 'http://127.0.0. - Network accessline 148
if (process.env.TEST_FRAMES === '1') result.targetInfos.push({ targetId: 'oopif-frame', type: 'iframe', url: 'http://127.0.0.1/child' }); - Network accessline 154
if (message.params.expression.includes('JSON.stringify({ ready:')) { const ready = fs.existsSync(path.join(root, 'page-release')) ? 'complete' : 'loading'; result = { result: { value: JSON.stringify({ ready, url: 'https://fa - Network accessline 155
const ready = fs.existsSync(path.join(root, 'page-release')) ? 'complete' : 'loading'; result = { result: { value: JSON.stringify({ ready, url: 'https://fake.example/page' }) } }; } else result = { result: { value: 'fake value - Network accessline 156
result = { result: { value: JSON.stringify({ ready, url: 'https://fake.example/page' }) } }; - Network accessline 346
const health = await f.ready(entry); assert.equal((await requestJson(f.port, '/shutdown')).status, 403); assert.equal((await requestJson(f.port, '/shutdown', { method: 'POST', headers: { Origin: 'https://example.com' }, body: { instance - Network accessline 347
assert.equal((await requestJson(f.port, '/shutdown')).status, 403); assert.equal((await requestJson(f.port, '/shutdown', { method: 'POST', headers: { Origin: 'https://example.com' }, body: { instanceId: health.instanceId } })).status, 403 - Network accessline 348
assert.equal((await requestJson(f.port, '/shutdown', { method: 'POST', headers: { Origin: 'https://example.com' }, body: { instanceId: health.instanceId } })).status, 403); - Network accessline 432
const entry = f.spawn(); const health = await f.ready(entry); const navigation = beginRequest(f.port, '/navigate?target=user-page', { method: 'POST', body: 'https://fake.example/page' }); - Network accessline 433
const health = await f.ready(entry); const navigation = beginRequest(f.port, '/navigate?target=user-page', { method: 'POST', body: 'https://fake.example/page' }); const aborted = navigation.done.catch(error => error); - Network accessline 434
const navigation = beginRequest(f.port, '/navigate?target=user-page', { method: 'POST', body: 'https://fake.example/page' }); - Network accessline 499
assert.equal(frames.status, 200); assert.deepEqual(frames.body.map(frame => [frame.frameId, frame.crossProcess, frame.url]), [ ['local-frame', false, 'http://localhost/same'], - Network accessline 500
assert.deepEqual(frames.body.map(frame => [frame.frameId, frame.crossProcess, frame.url]), [ ['local-frame', false, 'http://localhost/same'], ['oopif-frame', true, 'http://127.0.0.1/child'], - Network accessline 501
['local-frame', false, 'http://localhost/same'], - Network accessline 502
['oopif-frame', true, 'http://127.0.0.1/child'],
scripts/check-deps.mjs
- Executable scriptline 1
#!/usr/bin/env node - Network accessline 22
const PROXY_SCRIPT = path.join(ROOT, 'scripts', 'cdp-proxy.mjs'); const PROXY_PORT = Number(process.env.CDP_PROXY_PORT || 3456); const HEALTH_URL = `http://127.0.0.1:${PROXY_PORT}/health`; - Network accessline 23
const PROXY_PORT = Number(process.env.CDP_PROXY_PORT || 3456); const HEALTH_URL = `http://127.0.0.1:${PROXY_PORT}/health`; const USER_DATA = userDataPaths(); - Network accessline 24
const HEALTH_URL = `http://127.0.0.1:${PROXY_PORT}/health`; - Network accessline 84
function httpGetJson(url, timeoutMs = 3000) { return fetch(url, { signal: AbortSignal.timeout(timeoutMs) }) - Network accessline 85
return fetch(url, { signal: AbortSignal.timeout(timeoutMs) }) - Network accessline 122
async function ensureProxy(expectedBrowserId, browserOverride, health) { const targetsUrl = `http://127.0.0.1:${PROXY_PORT}/targets`; - Network accessline 123
const targetsUrl = `http://127.0.0.1:${PROXY_PORT}/targets`;
scripts/check-deps.test.mjs
- Executable scriptline 1
Executable file - Network accessline 154
const requests = []; const server = http.createServer((req, res) => { requests.push(req.url); - Network accessline 155
const server = http.createServer((req, res) => { requests.push(req.url); res.setHeader('content-type', 'application/json'); - Network accessline 156
requests.push(req.url); - Network accessline 186
assert.deepEqual(await f.events(), []); assert.ok(proxy.requests.length > 0); assert.ok(proxy.requests.every(request => request === '/health')); - Network accessline 187
assert.ok(proxy.requests.length > 0); assert.ok(proxy.requests.every(request => request === '/health')); }); - Network accessline 188
assert.ok(proxy.requests.every(request => request === '/health')); - Network accessline 204
assert.match(result.stdout, /正在维护/); assert.deepEqual(await f.events(), []); assert.ok(proxy.requests.every(request => request === '/health')); - Network accessline 205
assert.deepEqual(await f.events(), []); assert.ok(proxy.requests.every(request => request === '/health')); }); - Network accessline 206
assert.ok(proxy.requests.every(request => request === '/health')); - Network accessline 227
assert.match(result.stdout, /浏览器不一致/); assert.deepEqual(await f.events(), []); assert.equal((await (await fetch(`http://127.0.0.1:${proxy.port}/health`)).json()).connected, true); - Network accessline 228
assert.deepEqual(await f.events(), []); assert.equal((await (await fetch(`http://127.0.0.1:${proxy.port}/health`)).json()).connected, true); assert.ok(proxy.requests.every(request => request === '/health')); - Network accessline 229
assert.equal((await (await fetch(`http://127.0.0.1:${proxy.port}/health`)).json()).connected, true); - Network accessline 230
assert.ok(proxy.requests.every(request => request === '/health')); - Network accessline 243
assert.match(result.stdout, /无法确认当前连接的浏览器/); assert.deepEqual(await f.events(), []); assert.equal((await (await fetch(`http://127.0.0.1:${proxy.port}/health`)).json()).connected, true); - Network accessline 244
assert.deepEqual(await f.events(), []); assert.equal((await (await fetch(`http://127.0.0.1:${proxy.port}/health`)).json()).connected, true); assert.ok(proxy.requests.every(request => request === '/health')); - Network accessline 245
assert.equal((await (await fetch(`http://127.0.0.1:${proxy.port}/health`)).json()).connected, true); - Network accessline 246
assert.ok(proxy.requests.every(request => request === '/health')); - Network accessline 253
success(await f.run(proxy.port)); assert.deepEqual(await f.events(), []); assert.ok(proxy.requests.every(request => request === '/health')); - Network accessline 254
assert.deepEqual(await f.events(), []); assert.ok(proxy.requests.every(request => request === '/health')); }); - Network accessline 255
assert.ok(proxy.requests.every(request => request === '/health')); - Network accessline 261
success(await f.run(proxy.port)); assert.deepEqual(await f.events(), []); assert.ok(proxy.requests.includes('/targets')); - Network accessline 262
assert.deepEqual(await f.events(), []); assert.ok(proxy.requests.includes('/targets')); assert.equal((await (await fetch(`http://127.0.0.1:${proxy.port}/health`)).json()).connected, true); - Network accessline 263
assert.ok(proxy.requests.includes('/targets')); - Network accessline 264
assert.equal((await (await fetch(`http://127.0.0.1:${proxy.port}/health`)).json()).connected, true); - Network accessline 270
success(await f.run(proxy.port)); assert.deepEqual(await f.events(), []); assert.ok(proxy.requests.includes('/targets')); - Network accessline 271
assert.deepEqual(await f.events(), []); assert.ok(proxy.requests.includes('/targets')); const health = await (await fetch(`http://127.0.0.1:${proxy.port}/health`)).json(); - Network accessline 272
assert.ok(proxy.requests.includes('/targets')); - Network accessline 273
const health = await (await fetch(`http://127.0.0.1:${proxy.port}/health`)).json(); - Network accessline 293
assert.match(result.stdout, /连接超时/); assert.deepEqual(await f.events(), []); assert.ok(proxy.requests.includes('/targets')); - Network accessline 294
assert.deepEqual(await f.events(), []); assert.ok(proxy.requests.includes('/targets')); assert.equal((await (await fetch(`http://127.0.0.1:${proxy.port}/health`)).json()).status, 'ok'); - Network accessline 295
assert.ok(proxy.requests.includes('/targets')); - Network accessline 296
assert.equal((await (await fetch(`http://127.0.0.1:${proxy.port}/health`)).json()).status, 'ok'); - Network accessline 304
assert.match(result.stdout, /连接超时/); assert.deepEqual(await f.events(), []); assert.equal((await (await fetch(`http://127.0.0.1:${proxy.port}/health`)).json()).connected, false); - Network accessline 305
assert.deepEqual(await f.events(), []); assert.equal((await (await fetch(`http://127.0.0.1:${proxy.port}/health`)).json()).connected, false); }); - Network accessline 306
assert.equal((await (await fetch(`http://127.0.0.1:${proxy.port}/health`)).json()).connected, false); - Network accessline 318
assert.equal(events.filter(event => event.action === 'spawn').length, 1); assert.deepEqual(events.find(event => event.action === 'spawn').args, ['--browser', 'edge']); const health = await (await fetch(`http://127.0.0.1:${port}/health`) - Network accessline 319
assert.deepEqual(events.find(event => event.action === 'spawn').args, ['--browser', 'edge']); const health = await (await fetch(`http://127.0.0.1:${port}/health`)).json(); assert.equal(health.connected, true); - Network accessline 320
const health = await (await fetch(`http://127.0.0.1:${port}/health`)).json(); - Network accessline 453
const events = await f.events(); assert.deepEqual(events.find(event => event.action === 'spawn').args, []); const health = await (await fetch(`http://127.0.0.1:${port}/health`)).json(); - Network accessline 454
assert.deepEqual(events.find(event => event.action === 'spawn').args, []); const health = await (await fetch(`http://127.0.0.1:${port}/health`)).json(); assert.deepEqual(health.browser, { id: path.join(f.home, 'Dia', 'User Data'), label - Network accessline 455
const health = await (await fetch(`http://127.0.0.1:${port}/health`)).json();
scripts/find-url.mjs
- Executable scriptline 1
#!/usr/bin/env node - Network accessline 160
}); } catch (e) { if (e.code === 'ENOENT') die('未找到 sqlite3 命令。macOS/Linux 通常自带;Windows 可用 `winget install sqlite.sqlite` 或从 https://sqlite.org/download.html 下载后加入 PATH。'); - Network accessline 161
} catch (e) { if (e.code === 'ENOENT') die('未找到 sqlite3 命令。macOS/Linux 通常自带;Windows 可用 `winget install sqlite.sqlite` 或从 https://sqlite.org/download.html 下载后加入 PATH。'); return []; - Network accessline 162
if (e.code === 'ENOENT') die('未找到 sqlite3 命令。macOS/Linux 通常自带;Windows 可用 `winget install sqlite.sqlite` 或从 https://sqlite.org/download.html 下载后加入 PATH。');
scripts/match-site.mjs
- Executable scriptline 1
#!/usr/bin/env node
scripts/page-frames.mjs
- Executable scriptline 1
Executable file
scripts/page-frames.test.mjs
- Executable scriptline 1
Executable file - Network accessline 36
case 'Target.getTargets': return { result: { targetInfos: [ { targetId: 'page-1', type: 'page', url: 'http://localhost/p' }, - Network accessline 37
return { result: { targetInfos: [ { targetId: 'page-1', type: 'page', url: 'http://localhost/p' }, { targetId: 'oopif-frame', type: 'iframe', url: 'http://127.0.0.1/child' }, - Network accessline 38
{ targetId: 'page-1', type: 'page', url: 'http://localhost/p' }, - Network accessline 39
{ targetId: 'oopif-frame', type: 'iframe', url: 'http://127.0.0.1/child' }, - Network accessline 40
{ targetId: 'page-2', type: 'page', url: 'http://other/' }, - Network accessline 42
case 'Page.getFrameTree': return { result: { frameTree: { frame: { id: 'page-1' }, childFrames: [ { frame: { id: 'local-frame', url: 'http://localhost/same-now', name: 'kid' } }, - Network accessline 43
return { result: { frameTree: { frame: { id: 'page-1' }, childFrames: [ { frame: { id: 'local-frame', url: 'http://localhost/same-now', name: 'kid' } }, ] } } }; - Network accessline 44
{ frame: { id: 'local-frame', url: 'http://localhost/same-now', name: 'kid' } }, - Network accessline 47
const nodes = { 'el-local': { frameId: 'local-frame', attributes: ['name', 'kid', 'src', '/same'] }, 'el-oopif': { frameId: 'oopif-frame', attributes: ['id', 'pay', 'src', 'http://127.0.0.1/child', 'style', 'x'] }, - Network accessline 48
'el-local': { frameId: 'local-frame', attributes: ['name', 'kid', 'src', '/same'] }, 'el-oopif': { frameId: 'oopif-frame', attributes: ['id', 'pay', 'src', 'http://127.0.0.1/child', 'style', 'x'] }, 'el-unloaded': { attr - Network accessline 49
'el-oopif': { frameId: 'oopif-frame', attributes: ['id', 'pay', 'src', 'http://127.0.0.1/child', 'style', 'x'] }, - Network accessline 80
const { frames, calls, attached } = fakeBrowser(); assert.deepEqual(await frames.listFrames('page-1'), [ { index: 0, frameId: 'local-frame', crossProcess: false, url: 'http://localhost/same-now', name: 'kid', src: '/same' }, - Network accessline 81
assert.deepEqual(await frames.listFrames('page-1'), [ { index: 0, frameId: 'local-frame', crossProcess: false, url: 'http://localhost/same-now', name: 'kid', src: '/same' }, { index: 1, frameId: 'oopif-frame', crossProcess: true, ur - Network accessline 82
{ index: 0, frameId: 'local-frame', crossProcess: false, url: 'http://localhost/same-now', name: 'kid', src: '/same' }, - Network accessline 83
{ index: 1, frameId: 'oopif-frame', crossProcess: true, url: 'http://127.0.0.1/child', id: 'pay', src: 'http://127.0.0.1/child' }, - Network accessline 311
return alive(params.objectId) ? { result: { model: { content: [0, 0, 300, 0, 300, 250, 0, 250] } } } : dead; case 'Target.getTargets': return { result: { targetInfos: [] } }; case 'Page.getFrameTree': return { result: { frameTre - Network accessline 312
case 'Target.getTargets': return { result: { targetInfos: [] } }; case 'Page.getFrameTree': return { result: { frameTree: { frame: { id: 'page-1' }, childFrames: [{ frame: { id: 'local-frame', url: 'http://localhost/a' } }] } } }; - Network accessline 313
case 'Page.getFrameTree': return { result: { frameTree: { frame: { id: 'page-1' }, childFrames: [{ frame: { id: 'local-frame', url: 'http://localhost/a' } }] } } };
scripts/proxy-maintenance.mjs
- Executable scriptline 1
#!/usr/bin/env node
scripts/proxy-maintenance.test.mjs
- Executable scriptline 1
Executable file - Network accessline 67
for (let i = 0; i < 100; i++) { try { const res = await fetch('http://127.0.0.1:' + process.env.CDP_PROXY_PORT + '/health'); - Network accessline 68
try { const res = await fetch('http://127.0.0.1:' + process.env.CDP_PROXY_PORT + '/health'); const health = await res.json(); - Network accessline 69
const res = await fetch('http://127.0.0.1:' + process.env.CDP_PROXY_PORT + '/health'); - Network accessline 149
for await (const chunk of req) text += chunk; const body = text ? JSON.parse(text) : null; requests.push({ method: req.method, path: req.url, body, origin: req.headers.origin, connection: sockets.get(req.socket) }); - Network accessline 150
const body = text ? JSON.parse(text) : null; requests.push({ method: req.method, path: req.url, body, origin: req.headers.origin, connection: sockets.get(req.socket) }); res.setHeader('content-type', 'application/json'); - Network accessline 151
requests.push({ method: req.method, path: req.url, body, origin: req.headers.origin, connection: sockets.get(req.socket) }); - Network accessline 189
assert.equal(result.code, 0, result.stderr); assert.deepEqual(result.output, { status: 'running', health: oldHealth }); assert.deepEqual(proxy.requests.map(r => r.path), ['/health']); - Network accessline 190
assert.deepEqual(result.output, { status: 'running', health: oldHealth }); assert.deepEqual(proxy.requests.map(r => r.path), ['/health']); assert.deepEqual(await f.events(), []); - Network accessline 191
assert.deepEqual(proxy.requests.map(r => r.path), ['/health']); - Network accessline 213
assert.equal(result.output.status, 'busy'); } assert.ok(proxy.requests.every(req => req.path === '/health')); - Network accessline 214
} assert.ok(proxy.requests.every(req => req.path === '/health')); assert.deepEqual(await f.events(), []); - Network accessline 215
assert.ok(proxy.requests.every(req => req.path === '/health')); - Network accessline 227
assert.equal(result.output.status, 'busy'); } assert.ok(proxy.requests.every(req => req.path === '/health')); - Network accessline 228
} assert.ok(proxy.requests.every(req => req.path === '/health')); assert.deepEqual(await f.events(), []); - Network accessline 229
assert.ok(proxy.requests.every(req => req.path === '/health')); - Network accessline 243
assert.match(result.output.message, /禁止自动强停/); } assert.ok(proxy.requests.every(req => req.path === '/health')); - Network accessline 244
} assert.ok(proxy.requests.every(req => req.path === '/health')); assert.deepEqual(await f.events(), []); - Network accessline 245
assert.ok(proxy.requests.every(req => req.path === '/health')); - Network accessline 254
assert.equal(result.output.status, 'stopped'); assert.equal(result.output.stoppedInstanceId, oldHealth.instanceId); const shutdowns = proxy.requests.filter(req => req.path === '/shutdown'); - Network accessline 255
assert.equal(result.output.stoppedInstanceId, oldHealth.instanceId); const shutdowns = proxy.requests.filter(req => req.path === '/shutdown'); assert.equal(shutdowns.length, 1); - Network accessline 256
const shutdowns = proxy.requests.filter(req => req.path === '/shutdown'); - Network accessline 274
assert.equal(result.code, 2, result.stderr); assert.equal(result.output.status, 'busy'); assert.equal(proxy.requests.filter(r => r.path === '/shutdown').length, 1); - Network accessline 275
assert.equal(result.output.status, 'busy'); assert.equal(proxy.requests.filter(r => r.path === '/shutdown').length, 1); assert.deepEqual(await f.events(), []); - Network accessline 276
assert.equal(proxy.requests.filter(r => r.path === '/shutdown').length, 1); - Network accessline 295
assert.equal(result.output.health.instanceId, replacement.instanceId); if (action === 'restart') assert.equal(result.output.reused, true); assert.equal(proxy.requests.filter(req => req.path === '/shutdown').length, 1); - Network accessline 296
if (action === 'restart') assert.equal(result.output.reused, true); assert.equal(proxy.requests.filter(req => req.path === '/shutdown').length, 1); assert.deepEqual(await f.events(), []); - Network accessline 297
assert.equal(proxy.requests.filter(req => req.path === '/shutdown').length, 1); - Network accessline 318
assert.equal(result.output.expectedBrowserId, 'edge'); assert.equal(result.output.health.instanceId, replacement.instanceId); assert.equal(proxy.requests.filter(req => req.path === '/shutdown').length, 1); - Network accessline 319
assert.equal(result.output.health.instanceId, replacement.instanceId); assert.equal(proxy.requests.filter(req => req.path === '/shutdown').length, 1); assert.deepEqual(await f.events(), []); - Network accessline 320
assert.equal(proxy.requests.filter(req => req.path === '/shutdown').length, 1); - Network accessline 321
assert.deepEqual(await f.events(), []); const health = await (await fetch(`http://127.0.0.1:${proxy.port}/health`)).json(); assert.equal(health.instanceId, replacement.instanceId); - Network accessline 322
const health = await (await fetch(`http://127.0.0.1:${proxy.port}/health`)).json(); - Network accessline 398
assert.equal(result.output.health.instanceId, 'new-instance'); assert.equal((await f.events()).filter(event => event.action === 'startup').length, 1); const health = await (await fetch(`http://127.0.0.1:${proxy.port}/health`)).json( - Network accessline 399
assert.equal((await f.events()).filter(event => event.action === 'startup').length, 1); const health = await (await fetch(`http://127.0.0.1:${proxy.port}/health`)).json(); assert.equal(health.instanceId, 'new-instance'); - Network accessline 400
const health = await (await fetch(`http://127.0.0.1:${proxy.port}/health`)).json(); - Network accessline 482
const result = await f.run(proxy.port, ['restart']); assert.equal(result.code, 1, result.stderr); assert.ok(proxy.requests.every(req => req.path === '/health')); - Network accessline 483
assert.equal(result.code, 1, result.stderr); assert.ok(proxy.requests.every(req => req.path === '/health')); assert.deepEqual(await f.events(), []); - Network accessline 484
assert.ok(proxy.requests.every(req => req.path === '/health')); - Network accessline 513
assert.equal(result.code, 0, `${result.stdout}\n${result.stderr}`); assert.equal(result.output.status, 'stopped'); const connections = proxy.requests.map(request => request.connection); - Network accessline 514
assert.equal(result.output.status, 'stopped'); const connections = proxy.requests.map(request => request.connection); assert.equal(new Set(connections).size, connections.length, JSON.stringify(proxy.requests)); - Network accessline 515
const connections = proxy.requests.map(request => request.connection); - Network accessline 623
assert.equal(result.output.health.instanceId, oldHealth.instanceId); assert.equal(resets, 1); assert.equal(proxy.requests.filter(request => request.path === '/health').length, 2); - Network accessline 624
assert.equal(resets, 1); assert.equal(proxy.requests.filter(request => request.path === '/health').length, 2); assert.deepEqual(await f.events(), []); - Network accessline 625
assert.equal(proxy.requests.filter(request => request.path === '/health').length, 2);
scripts/user-data.mjs
- Executable scriptline 1
Executable file
scripts/user-data.test.mjs
- Executable scriptline 1
Executable file
How the signals fit together
Facts from a static read of the files at the pinned commit. They describe what the code does, not why.
Some files could not be read; the facts below still hold.
Declared and executed: 1 fact
- Contacts sqlite.org, which SKILL.md, the README and the plugin manifest do not mentionscripts/find-url.mjs:162High confidence
Signal confidence: 278 facts
- Network access in prose of documentationREADME.md:4Low confidence
- Network access in prose of documentationREADME.md:5Low confidence
- Network access in prose of documentationREADME.md:6Low confidence
- Network access in prose of documentationREADME.md:7Low confidence
- Network access in prose of documentationREADME.md:8Low confidence
- Network access in prose of documentationREADME.md:9Low confidence
- Network access in prose of documentationREADME.md:10Low confidence
- Network access in prose of documentationREADME.md:11Low confidence
- Network access in prose of documentationREADME.md:12Low confidence
- Network access in prose of documentationREADME.md:13Low confidence
- Network access in prose of documentationREADME.md:14Low confidence
- Network access in prose of documentationREADME.md:15Low confidence
- Network access in prose of documentationREADME.md:21Low confidence
- Network access in prose of documentationREADME.md:23Low confidence
- Network access in prose of documentationREADME.md:24Low confidence
- Network access in prose of documentationREADME.md:25Low confidence
- Network access in prose of documentationREADME.md:30Low confidence
- Network access in prose of documentationREADME.md:35Low confidence
- Network access in prose of documentationREADME.md:36Low confidence
- Network access in prose of documentationREADME.md:37Low confidence
- Network access in prose of documentationREADME.md:46Low confidence
- Network access in prose of documentationREADME.md:47Low confidence
- Network access in prose of documentationREADME.md:48Low confidence
- Network access in prose of documentationREADME.md:117Low confidence
- Network access in code of documentationREADME.md:122Low confidence
- Network access in code of documentationREADME.md:128Low confidence
- Network access in code of documentationREADME.md:135Low confidence
- Network access in code of documentationREADME.md:226Low confidence
- Network access in code of documentationREADME.md:227Low confidence
- Network access in code of documentationREADME.md:228Low confidence
- Network access in code of documentationREADME.md:229Low confidence
- Network access in code of documentationREADME.md:230Low confidence
- Network access in code of documentationREADME.md:231Low confidence
- Network access in code of documentationREADME.md:232Low confidence
- Network access in code of documentationREADME.md:233Low confidence
- Network access in code of documentationREADME.md:234Low confidence
- Network access in code of documentationREADME.md:235Low confidence
- Network access in code of documentationREADME.md:236Low confidence
- Network access in prose of documentationREADME.md:263Low confidence
- Network access in prose of documentationREADME.md:267Low confidence
- Network access in prose of documentationREADME.md:271Low confidence
- Network access in prose of documentationREADME.md:273Low confidence
- Network access in the frontmatter of the SKILL.mdSKILL.md:8Low confidence
- Network access in the frontmatter of the SKILL.mdSKILL.md:9Low confidence
- Network access in the frontmatter of the SKILL.mdSKILL.md:10Low confidence
- Network access in prose of the SKILL.mdSKILL.md:81Low confidence
- Network access in prose of the SKILL.mdSKILL.md:83Low confidence
- Network access in prose of the SKILL.mdSKILL.md:141Low confidence
- Network access in code of the SKILL.mdSKILL.md:144High confidence
- Network access in code of the SKILL.mdSKILL.md:145High confidence
and 228 more
Works with
| Agent | Status | Evidence | Install to |
|---|---|---|---|
| Claude Code | Native | Manifest .claude-plugin/marketplace.json | .claude/skills/<skill-name>/ |
| Codex | Native | Manifest AGENTS.md | .agents/skills/<skill-name>/ |
| Cursor | Compatible | Standard SKILL.md SKILL.md | .cursor/skills/<skill-name>/ |
| Gemini CLI | Native | Path GEMINI.md | .gemini/skills/<skill-name>/ |
| GitHub Copilot | Compatible | Standard SKILL.md SKILL.md | .github/skills/<skill-name>/ |
| OpenCode | Compatible | Standard SKILL.md SKILL.md | .opencode/skills/<skill-name>/ |
- Native The repository ships a manifest, folder or frontmatter field for this agent.
- Compatible A standard SKILL.md that this agent can read.
- Unknown No evidence either way.
Derived automatically from paths, manifests and frontmatter. Not tested on each agent.
Explore alternatives and comparisons
Add this badge to your README
It updates every night and links to this page.
[](https://hotskills.dev/skill/eze-is-web-access/)