ARTICLE DETAIL

资讯详情

深耕商务建站与企业官网运营的一线实战洞察。

OpenCLI 贡献实战指南:从零编写站点 Adapter、Pipeline 与 func() 双范式及工程规范

OpenCLI 贡献实战指南:从零编写站点 Adapter、Pipeline 与 func() 双范式及工程规范 OpenCLI 贡献实战指南从零编写站点 Adapter、Pipeline 与 func() 双范式及工程规范【免费下载链接】OpenCLIMake Any Website into CLI Use your logged-in browser by AI agent.项目地址: https://gitcode.com/gh_mirrors/ope/OpenCLI本指南以 OpenCLI 官方贡献文档为主体系统讲解如何为这一「把任意网站变成 CLI」的项目新增一个站点适配器先完成环境搭建与构建验证再分别掌握Pipeline数据抓取与func()复杂浏览器交互两种适配器编写范式并落地参数设计、测试、代码风格与提交规范。读完你将具备独立向仓库提交一个全新站点命令如opencli mysite trending的完整能力并理解适配器在底层注册表与执行引擎中的工作方式。一、快速开始环境搭建与首次构建贡献者第一步是 Fork 并克隆仓库完成依赖安装、构建与自检。OpenCLI 是标准的 npm 项目package.json要求 Node.js20.18.1采用 ESM 模块体系# 1. Fork clone git clone gitgithub.com:your-username/opencli.git cd opencli # 2. Install dependencies npm install # 3. Build npm run build # 4. Run a few checks npx tsc --noEmit npm test # 5. Link globally (optional, for testing opencli command) npm link结合 package.json 的 scripts 可以进一步理解每一步的含义npm run build是一条链式命令先由clean-dist清空dist/再copy-yaml复制 YAML 配置最后build-manifest触发tsc --build编译 TypeScript 并生成命令清单cli-manifest.jsonnpx tsc --noEmit对应npm run typecheck仅做类型检查不产出文件是提交前最快的类型把关手段npm test实际执行vitest run --project unit --project extension --project adapter即「本地默认门禁」 单元测试 扩展测试 适配器测试三层详见测试npm link将本地包软链到全局之后即可直接使用opencli命令调试自己开发的适配器。二、理解适配器注册机制registry 公共 API 与 StrategyOpenCLI 的全部适配器使用 TypeScript 编写通过jackwener/opencli/registry这一公共入口注册命令。该入口对应源码 src/registry-api.ts它只重新导出核心注册 API不引入序列化等传递性副作用目的是避免插件在动态加载discoverPlugins()时发生循环依赖死锁。真正承载注册逻辑的是 src/registry.ts其中定义了核心概念Strategy枚举src/registry.tsPUBLIC、LOCAL、COOKIE、INTERCEPT、UI五种策略用于声明命令的数据获取方式与鉴权依赖Arg接口src/registry.ts声明命令参数支持type、default、required、positional、choices等字段cli(opts)注册函数src/registry.ts接收命令定义并写入全局注册表随后可通过fullName()site/name格式在注册表中取回registerCommand()归一化逻辑src/registry.ts会把strategy解码为执行路径实际读取的browser、navigateBefore字段——例如COOKIE策略且声明了domain时会自动推导出「命令执行前先预导航到https://domain」同时自动处理aliases别名映射。此外注册表使用globalThis上的单一 Mapsrc/registry.ts确保通过npm link/ peerDependency 加载的插件不会因模块实例分裂而注册到不同的 Map 上。三、Pipeline Adapter数据抓取命令的推荐范式对于「拉取数据」类命令列表、排行、搜索、行情推荐使用pipeline声明式写法。创建一个类似clis/site/command.js的文件import { cli, Strategy } from jackwener/opencli/registry; cli({ site: mysite, name: trending, description: Trending posts on MySite, domain: www.mysite.com, strategy: Strategy.PUBLIC, access: read, browser: false, args: [ { name: query, positional: true, required: true, help: Search keyword }, { name: limit, type: int, default: 20, help: Number of items }, ], columns: [rank, title, score, url], pipeline: [ { fetch: { url: https://api.mysite.com/trending } }, { map: { rank: ${{ index 1 }}, title: ${{ item.title }}, score: ${{ item.score }}, url: ${{ item.url }}, }}, { limit: ${{ args.limit }} }, ], });要点说明strategy: Strategy.PUBLICbrowser: false表示该命令无需浏览器直接由 Node 侧fetch获取公开数据pipeline数组按顺序执行数据流步骤${{ ... }}是模板表达式可访问item当前行、index行号、args命令参数等上下文columns声明输出列必须与最终map产出的字段一致。3.1 真实示例hackernews/top.js仓库中 clis/hackernews/top.js 是一个完整的 pipeline 实战案例——它先用fetch拿到 Hacker News 的 top stories ID 列表再对每个 ID 并发拉取详情最后过滤、映射、截断输出pipeline: [ { fetch: { url: https://hacker-news.firebaseio.com/v0/topstories.json } }, { limit: ${{ Math.min((args.limit ? args.limit : 20) 10, 50) }} }, { map: { id: ${{ item }} } }, { fetch: { url: https://hacker-news.firebaseio.com/v0/item/${{ item.id }}.json } }, { filter: item.title !item.deleted !item.dead }, { map: { rank: ${{ index 1 }}, id: ${{ item.id }}, title: ${{ item.title }}, score: ${{ item.score }}, author: ${{ item.by }}, comments: ${{ item.descendants }}, url: ${{ item.url }}, } }, { limit: ${{ args.limit }} }, ],这段代码展示了 pipeline 的两个高级能力步骤间数据流第二次fetch的 URL 引用了前一步map产出的item.id实现「逐条展开详情」表达式动态计算limit步骤用Math.min先多取 10 条以留出过滤余量最后再严格截断到args.limit。3.2 pipeline 步骤从哪来pipeline 的步骤名并非写死的字符串而是来自可动态扩展的步骤注册表 src/pipeline/registry.ts核心步骤包括navigate、fetch、click、type、fill、wait、press、snapshot、evaluate、select、map、filter、sort、limit、intercept、tap、download等。第三方插件也可通过registerStep()注册自定义步骤。opencli validate会依据该注册表实时校验步骤名拼写避免手写白名单产生过期快照。四、func() Adapter复杂浏览器交互范式当命令需要在浏览器内执行点击、填表、发布、抓取需登录数据等复杂交互时使用func()回调。创建一个类似clis/site/command.js的文件import { cli, Strategy } from jackwener/opencli/registry; cli({ site: mysite, name: search, description: Search MySite, domain: www.mysite.com, strategy: Strategy.COOKIE, args: [ { name: query, positional: true, required: true, help: Search query }, { name: limit, type: int, default: 10, help: Max results }, ], columns: [title, url, date], func: async (page, kwargs) { const { query, limit 10 } kwargs; await page.goto(https://www.mysite.com); const data await page.evaluate(async (q: string) { const res await fetch(/api/search?q encodeURIComponent(q), { credentials: include }); return (await res.json()).results; }, query); return data.slice(0, Number(limit)).map((item: any) ({ title: item.title, url: item.url, date: item.created_at, })); }, });要点说明browser字段决定func签名browser: false时签名是(kwargs, debug?)browser: true时签名是(page, kwargs, debug?)。把两者搞反是高频踩坑点——此时kwargs实际收到的是 debug 标志所有外部参数会静默回退到默认值详见 skills/opencli-adapter-author/SKILL.md 中的关键约定page是IPage类型src/registry-api.ts提供goto、evaluate等页面操作能力Strategy.COOKIE配合domain时引擎会在执行前自动预导航到https://www.mysite.com确保带 cookie 的登录态可用。4.1 共享参数校验工具对于搜索类命令clis/_shared/search-adapter.js提供了一组可直接复用的参数校验与容错函数requireSearchQuery关键词非空校验、requireBoundedInteger整数范围校验、requireNonNegativeInteger、unwrapBrowserResult、requireRows结果形状校验、toHttpsUrl等。它们配合jackwener/opencli/errors抛出ArgumentError/CommandExecutionError/EmptyResultError等类型化错误保证失败路径可控、可被上层优雅处理。4.2 完整的 adapter 编写工作流如果希望覆盖「侦察 → API 发现 → 字段解码 → verify」的完整流程可以安装仓库自带的opencli-adapter-authorskill。该 skill 强调先定 strategy 再写代码优先选择契约稳定的PUBLIC_API/COOKIE_API只有公开接口不可用、UI/DOM 语义不稳定时才承担PAGE_FETCH/INTERCEPT这类无契约内部接口的维护成本并强制在写代码前产出一段 strategy note含 Contract 等级与 Evidence。五、验证你的 Adapter编写完成后通过以下命令验证# Validate adapter opencli validate # Test your command opencli site command --limit 3 -f json # Verbose mode for debugging opencli site command -vopencli validate的执行逻辑在 src/validate.ts它会遍历全局注册表并对每个命令做多项检查description 缺失→ warning浏览器命令未声明domain→ warning登录态浏览器上下文可能无法工作pipeline 步骤名拼写错误→ warning并提示最近似的合法步骤名白名单实时取自步骤注册表既无func也无pipeline→ error命令无法执行参数名重复→ errorpositional 参数出现在命名参数之后→ warning见下文参数设计规范。输出形如opencli validate: PASS与Checked N command(s)、Errors / Warnings计数逐条列出问题命令与具体原因。六、Arg Design Convention参数设计规范OpenCLI 的参数设计有一条核心原则主目标参数用 positional配置参数用命名选项--flag。判断标准不是「谁写在文件前面」而是「用户会怎么敲这条命令」——opencli xueqiu stock SH600519比opencli xueqiu stock --symbol SH600519自然得多。Arg typePositional?ExamplesMain target (query, symbol, id, url, username)✅positional: truesearch 茅台,stock SH600519,download BV1xxxConfiguration (limit, format, sort, page, type, filters)❌ Named--flag--limit 10,--format json,--sort hot,--location seattle不要仅仅因为某个参数在文件里排在第一个就把它改成 positional。如果参数是可选的、行为类似过滤器、或用于选择模式/配置它通常应该保持为命名选项。pipeline 与 func() 两种写法均遵循同一套规范args: [ { name: query, positional: true, required: true, help: Search query }, // ← primary arg { name: limit, type: int, default: 20, help: Max results }, // ← config arg ]Arg接口还支持choices枚举取值、valueRequired等字段源码 src/registry.ts 中有完整定义。另外注意 src/validate.ts 的检查positional 参数应集中放在命名参数之前且参数名不可重复。七、Testing三层门禁与定位指南完整测试指南见 TESTING.md本地常用的命令如下npm test # Default local gate: unit extension adapter tests npm run test:adapter # Adapter-only project (useful while iterating on adapters) npx vitest run tests/e2e/ # E2E tests npx vitest run # All tests测试架构由 vitest.config.ts 定义分为多个 project层位置运行方式用途单元测试src/**/*.test.tsnpm test内部模块、pipeline、runtimeAdapter 测试clis/**/*.test.{ts,js}npm test/npm run test:adapteradapter 命令与数据归一化E2E 测试tests/e2e/*.test.tsnpx vitest run tests/e2e/真实 CLI 命令执行烟雾测试tests/smoke/*.test.tsnpx vitest run tests/smoke/外部 API 与注册完整性对于新增 adapter建议按 TESTING.md 的决策流程补测试browser: false的命令加入tests/e2e/public-commands.test.tsbrowser: true但公开数据加入tests/e2e/browser-public.test.ts站点反爬/地域限制导致空数据时 warn pass需登录的命令加入tests/e2e/browser-auth.test.ts验证 graceful failure不 crash、不 hang、错误信息可控。八、Code Style代码风格贡献代码须遵守以下风格约定TypeScript strict mode—— 尽量避免anyES Modules—— 导入路径使用.js扩展名对应 TypeScript 输出命名文件kebab-case变量/函数camelCase类型/类PascalCase无默认导出—— 统一使用命名导出。九、Commit Convention提交信息约定使用 Conventional Commits 规范常用 scope 为站点名如twitter、reddit或模块名如browser、pipeline、enginefeat(twitter): add thread command fix(browser): handle CDP timeout gracefully docs: update CONTRIBUTING.md test(reddit): add e2e test for save command chore: bump vitest to v4十、提交 Pull Request创建功能分支git checkout -b feat/mysite-trending完成修改并在相关时补充测试运行适用的检查项npx tsc --noEmit # Type check npm test # Default local gate: unit extension adapter npm run test:adapter # Adapter-only project (optional while iterating on adapters) opencli validate # Adapter validation使用 conventional commit 格式提交Push 并打开 PR十一、License通过贡献代码即表示你同意你的贡献将依据 Apache-2.0 License 授权。仓库根目录还提供 README.md项目总览与 CONTRIBUTING.md本文依据文档以及面向新站点适配器的完整开发方法论 skills/opencli-adapter-author/SKILL.md可作为持续深入参考。【免费下载链接】OpenCLIMake Any Website into CLI Use your logged-in browser by AI agent.项目地址: https://gitcode.com/gh_mirrors/ope/OpenCLI创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表
PREV
查看更多资讯
NEXT
返回资讯列表