ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

OpenCLI 的 Manus 适配器实战指南:用 Connect-RPC 把 manus.im 变成纯读 CLI

OpenCLI 的 Manus 适配器实战指南:用 Connect-RPC 把 manus.im 变成纯读 CLI OpenCLI 的 Manus 适配器实战指南用 Connect-RPC 把 manus.im 变成纯读 CLI【免费下载链接】OpenCLIMake Any Website into CLI Use your logged-in browser by AI agent.项目地址: https://gitcode.com/gh_mirrors/ope/OpenCLI导读Manusmanus.im是一款主打Hands On AI的自主智能体 Web 应用用户可以在浏览器中让它执行多步骤任务并消耗账户信用额度credits。OpenCLI 以浏览器适配器Browser Adapter的方式为其提供了一套纯只读的命令行接口你无需抓取 DOM、无需逆向前端 JS就能在终端里查询账户快照、会话列表、会话详情、信用额度、连接器与技能。读完本文你将掌握该适配器的认证机制Cookie 复用 Connect-RPC、全部 6 个命令的用法与参数、底层实现原理以及它刻意不暴露破坏性操作的工程考量。一、适配器定位与整体架构OpenCLI 中每个网站适配器位于 clis/ 目录下Manus 适配器集中在 clis/manus/包含 6 个业务命令文件status.js、list.js、read.js、credits.js、connectors.js、skills.js、共享工具 clis/manus/_utils.js、站点登录注册 clis/manus/auth.js 以及完整测试 clis/manus/manus.test.js。适配器使用Cookie 策略Strategy.COOKIE它不持有 Manus 的账号密码而是复用用户在 OpenCLI Browser Bridge 中已经登录的浏览器会话。所有命令都声明为access: read、browser: true、siteSession: persistent即只读取数据、不修改任何远程状态。终端 (opencli manus ...) │ ▼ OpenCLI Browser Bridge已登录 manus.im 的浏览器页面 │ 注入 callManusAPI()读取 session_id cookie ▼ https://api.manus.im/ Connect-RPC POST JSON二、认证机制Cookie 复用 Connect-RPC Bearer2.1 登录与身份校验适配器通过 clis/manus/auth.js 调用通用站点认证模块registerSiteAuthCommands定义于 clis/_shared/site-auth.js自动注册opencli manus login与opencli manus whoami两个命令login打开https://manus.im/login等待用户在浏览器中完成登录whoami返回user_id与name两列身份信息。其身份校验流程verifyManusIdentity分两步检查https://manus.im域名下是否存在auth_session、manus_token、_session、session等会话 Cookie请求https://manus.im/api/auth/session携带凭据探测用户身份若无id/userId字段则判定为未登录抛出AuthRequiredError。2.2 核心session_id 复用为 Bearer Token真正被业务命令使用的是名为session_id的 Cookie它内部是一个约 357 字节的 JWT。共享工具 clis/manus/_utils.js 中定义了三个关键常量export const MANUS_DOMAIN manus.im; export const MANUS_URL https://manus.im/app; export const API_HOST https://api.manus.im;并注入一段浏览器端 IIFEMANUS_API_CALL_JS其中callManusAPI(rpcPath, body)完成整条 RPC 调用链const jwt document.cookie.split(session_id)[1]?.split(;)[0]; const r await fetch(https://api.manus.im/ rpcPath, { method: POST, credentials: include, headers: { Content-Type: application/json, Authorization: Bearer jwt, Connect-Protocol-Version: 1, }, body: JSON.stringify(body || {}), });要点Bearer 认证JWT 直接作为Authorization: Bearer token请求头Connect-RPC 协议请求头Connect-Protocol-Version: 1路径为包名.Service/Method风格POST JSON body同源语义由于fetch是在manus.im域名的页面上下文中执行配合credentials: include能复用 Cookie 会话失败标记无 Cookie 返回{ __authRequired: true }HTTP 非 2xx 返回{ __httpError: status, message }JSON 解析失败返回{ __error: invalid_json }——这些标记会被下游requireObject等守卫识别并转换为对应的 OpenCLI 异常类型AuthRequiredError/CommandExecutionError。每个业务命令执行前还会调用ensureOnManus(page)先读取window.location.href判断是否已在manus.im域名下否则跳转到https://manus.im/app并等待 2 秒确保脚本运行在正确的站点上下文中。三、命令总览适配器注册的全部命令均只读命令说明默认/参数manus status账户快照邮箱、显示名、用户 ID、会员层级、核心信用数字无参数manus list [--limit N] [--archived]列出最近会话id可直接回传read使用默认隐藏已归档会话--limit默认 20manus read uid展示单个会话的字段级详情用list输出的id查找uid为位置参数manus credits完整信用额度拆分无参数manus connectors [--limit N]列出可用连接器Apify、GitHub、Outlook、Slack 等--limit默认 50manus skills列出技能区分用户添加sourceuser与系统sourcesystem无参数clis/manus/manus.test.js 的第 1 组用例验证了这 6 个命令均以access: read、domain: manus.im、siteSession: persistent注册到命令注册表。四、命令详解与示例输出4.1manus status账户快照对应 clis/manus/status.js。它通过Promise.all并发调用两个 RPCuser.v1.UserService/UserInfouser.v1.UserService/GetAvailableCredits合并输出为Field / Value两列$ opencli manus status Field: Email Value: zhongyuelin990405gmail.com Field: Display Name Value: Lin Zhongyue Field: Membership Tier Value: 60 Field: Total Credits Value: 12311 Field: Periodic Credits Value: 12000 Field: Refresh Credits Value: 300源码同时会输出User ID与Next Refresh字段。注意Email/Display Name/User ID/Membership Tier来自UserInfoTotal/Periodic/Refresh Credits与Next Refresh来自GetAvailableCredits——两条 RPC 的返回在浏览器内合并后一次交回。4.2manus list会话列表对应 clis/manus/list.js调用session.v1.SessionService/ListSessions请求体为{ page: 1, pageSize: limit }。--limit正整数默认 20上限 200经validatedLimit()校验拒绝负数、零、NaN、非整数超出范围抛ArgumentError--archived布尔开关默认 false不传时在客户端过滤掉isArchived: true的会话输出列为id / Title / Status / Last Message / Last Updated / CreditsStatus会去掉SESSION_STATUS_前缀并转小写如stoppedCredits即该会话消耗的costedCredits结果为空时抛EmptyResultError。$ opencli manus list --limit 3 id: 8UcpCxMFLrNk63ZJmzALfV Title: 制作技术方案路演风格PPT的详细要求 Status: stopped id: YOpdpcVj7vPFD4gsBfEwVu Title: Defining Empire: … Status: stopped测试用例还验证了--limit 0、-5、1.5都会被拒绝以及--limit 1会真实反映到注入脚本的pageSize: 1上见 clis/manus/manus.test.js 的 list 测试组。4.3manus read uid会话详情对应 clis/manus/read.js。uid是必填位置参数缺失抛ArgumentError。实现上调用与list相同的ListSessionspageSize: 100在浏览器内按uid精确匹配后返回字段级详情$ opencli manus read 8UcpCxMFLrNk63ZJmzALfV Field: UID Value: 8UcpCxMFLrNk63ZJmzALfV Field: Title Value: 制作技术方案路演风格PPT的详细要求 Field: Status Value: SESSION_STATUS_STOPPED Field: Mode Value: AGENT_TASK_MODE_HIGH_EFFORT Field: Credits Value: 4564完整输出还包括Created、Updated、Last Display Message。若 100 条内找不到匹配 uid抛EmptyResultErrorSession not found。4.4manus credits信用额度拆分对应 clis/manus/credits.js仅调用GetAvailableCredits一个 RPC输出 8 个字段字段含义Total Credits当前总余额Free Credits免费额度Periodic Credits周期发放额度Pro Monthly CreditsPro 月度额度Refresh Credits本次可刷新额度Max Refresh Credits刷新额度上限Next Refresh下次刷新时间Refresh Interval刷新周期如daily若返回对象中四个核心键totalCredits/freeCredits/periodicCredits/refreshCredits全部缺失则判定为畸形响应并抛错。4.5manus connectors连接器列表对应 clis/manus/connectors.js调用connectors.v1.ConnectorsService/ListConnectors输出UID / Name / Brief三列。--limit默认 50、上限 500。连接器示例包括 Apify、GitHub、Outlook、Slack 等。4.6manus skills技能列表对应 clis/manus/skills.js调用skill.v1.SkillService/ListSkills输出ID / Name / Description / Source四列userAddedSkills数组 →Source: user用户添加的技能systemSkills或skills数组 →Source: system系统技能兼容两种响应键名两类都缺失则判定为畸形响应全部为空则抛EmptyResultError。五、底层实现要点API-first 与失败关闭5.1 为什么不抓 DOM原文档明确说明适配器是API-first实现——每个命令只发一次status 为并发两次Connect-RPC POST 到api.manus.im而不是解析页面 DOM。这样即便 Manus 前端 UI 换肤、改版只要后端 RPC 契约不变CLI 依然可用天然对前端重绘免疫。5.2 统一响应守卫clis/manus/_utils.js 提供了一组失败关闭fail-closed的守卫函数所有命令共用unwrapEvaluateResult(payload)识别并剥离 Browser Bridge 的{ session, data }信封向下取datarequireObject/requireArray/requireString依次检查__authRequired→AuthRequiredError、__httpError→ 带 HTTP 状态码的CommandExecutionError、__error→ 通用CommandExecutionError再校验类型是否匹配畸形载荷一律报错而非静默吞掉validatedLimit(raw, fallback, max)参数校验与服务端 Buf Validate 规则保持一致先本地报错以省去一次无效网络往返。5.3 域名安全校验isManusUrl(url)要求协议为https:且主机名严格等于manus.im或www.manus.im用于ensureOnManus判断当前页面是否处于正确站点。测试覆盖了https://manus.im.evil.com、http://manus.im等被拒绝的边界情况。六、刻意不暴露的操作设计边界原文档指出以下命令不在 CLI 范围内manus open uid/app/session/uid返回 404Manus 的/app是纯 React SPA没有按会话粒度的 URL 路由manus new-task prompt、manus chat uid message、manus pause/resume/cancel uid属于破坏性状态变更且没有稳定的 post-stateURL 从不变化、无确认对话框可供断言验证结果manus delete uid/manus archive uid同理。这是值得借鉴的适配器设计原则只暴露能通过稳定可验证状态确认结果的命令。在 Manus 官方暴露按会话的 URL 路由或确认对话框之前这些操作被有意排除避免 CLI 在无法验证执行结果的情况下误导用户。七、已知限制与注意事项manus read的 100 条上限read通过ListSessionspageSize100在进程内过滤查找。如果目标会话不在最近 100 条之内命令会报告not found。这是当前实现明确声明的限制。枚举原始值Status如SESSION_STATUS_STOPPED与Mode如AGENT_TASK_MODE_HIGH_EFFORT直接透传 RPC 原始枚举字符串Membership Tier是数字层级码如60。脚本化消费这些字段时需按枚举值处理而不是按显示文案。list的过滤是客户端行为默认隐藏归档会话是在拿到sessions数组后由filter(s !s.isArchived)完成的pageSize仍可能包含已归档项因此--archived只是显示层开关。八、测试与验证clis/manus/manus.test.js 使用 vitest 对适配器做了系统验证覆盖6 个命令的注册信息access/domain/siteSessionstatus合并输出与信封解包、身份缺失时报错list默认过滤归档、--archived返回全部、--limit注入pageSize、非法 limit 拒绝、畸形载荷报错read命中/未命中/缺参/畸形载荷四种路径credits8 字段输出与畸形载荷拒绝connectors的 limit 截断与畸形行拒绝skills的sourceuser归属与畸形载荷拒绝__authRequired→AuthRequiredError、__httpError→CommandExecutionError的错误映射isManusUrl的合法/非法 URL 判定。运行npm test或项目文档 TESTING.md 中说明的测试命令即可执行这些用例你也可以在本地用opencli manus command直接体验全部命令。九、相关源码速查关注点文件共享工具常量、RPC 注入、守卫、limit 校验clis/manus/_utils.js登录 / 身份校验clis/manus/auth.js通用站点认证注册器clis/_shared/site-auth.js账户快照clis/manus/status.js会话列表clis/manus/list.js会话详情clis/manus/read.js信用额度clis/manus/credits.js连接器clis/manus/connectors.js技能clis/manus/skills.js单元测试clis/manus/manus.test.js从这套实现可以提炼出可复用的适配器模式Cookie 复用 Connect-RPC Bearer、浏览器内注入 RPC 调用、统一信封解包与失败关闭守卫、严格参数校验、以及无稳定 post-state 即不做破坏性操作的能力边界。无论是接入新的 AI 智能体平台还是设计只读 CLI 工具这套方法论都值得直接借鉴。【免费下载链接】OpenCLIMake Any Website into CLI Use your logged-in browser by AI agent.项目地址: https://gitcode.com/gh_mirrors/ope/OpenCLI创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进