OpenCLI 接入 ONES 项目 API:基于 Browser Bridge 的任务查询与工时填报实战指南
2026/9/20 5:27:35 网站建设 项目流程
  • 开发工具
  • CLI
  • 人工智能
  • AI 应用
  • 浏览器控制
  • GUI 自动化

【免费下载链接】OpenCLI

Make Any Website into CLI & Use your logged-in browser by AI agent.

项目地址:https://gitcode.com/gh_mirrors/ope/OpenCLI
点击查看免费下载

本文是 OpenCLI 中 ONES 适配器(docs/adapters/browser/ones.md)的完整实战指南。ONES(ones.cn)是国内团队常用的研发协同平台,其旧版 Project API 部署形态多样,OpenCLI 通过Browser Bridge模式复用你已在 Chrome 中登录的 ONES 会话,以 CLI 方式完成登录、身份查询、任务列表、任务详情与工时填报等日常操作。读完本文,你将掌握 ONES 适配器的全部命令、环境变量与调用链原理,并能把它接入 AI Agent 自动化工作流。

适配器定位与工作原理

ONES 适配器在 OpenCLI 中注册为ones站点,采用Strategy.COOKIE策略,属于Browser Bridge模式(browser: true),目标域名ones.cn,且支持通过ONES_BASE_URL指向自建部署(self-hosted)。

从源码注释看,该适配器面向旧版 ONES Project API(clis/ones/common.js),所有请求都拼接在固定前缀/project/api/project之下。其核心思路是:不在 Node.js 进程内直接发 HTTP 请求,而是把fetch调用注入到浏览器页面上下文执行,并携带credentials: 'include',从而复用 Chrome 中已登录的 Cookie 会话:

const init = { method, headers: { ...headers }, credentials: 'include' }; const res = await fetch(url, init);

这段逻辑位于 clis/ones/common.js 的onesFetchInPageWithMeta,通过page.evaluate在页面内发起请求。请求头默认携带Referer(指向ONES_BASE_URL),保证与页面同源;若检测到ONES_USER_ID+ONES_AUTH_TOKEN环境变量,还会附加Ones-User-Id/Ones-Auth-Token头(与纯 Cookie 二选一或并存,取决于你的部署)。

Browser Bridge 的全局原理参见 docs/guide/browser-bridge.md:CLI 通过 WebSocket(localhost:19825)连接 micro-daemon,daemon 再经 Chrome 扩展在页面上下文执行 JS,整体链路为opencli → daemon → Chrome 扩展 → 已登录页面

前置条件与必备环境变量

前置条件

条件说明
Chrome 已启动并登录 ONES命令复用的是 Chrome 中的登录会话,目标实例必须在浏览器中处于登录态
安装 Browser Bridge 扩展安装与验证步骤见 Browser Bridge 安装指南,可用opencli doctor检查连通性
设置ONES_BASE_URL必须与 Chrome 中打开的 ONES 实例同源,且不带结尾斜杠

环境变量清单

以下是适配器实际读取的全部环境变量(依据 clis/ones/common.js、clis/ones/login.js、clis/ones/tasks.js、clis/ones/task-helpers.js):

变量必填作用
ONES_BASE_URL自建/托管实例源,如https://your-team.ones.cn,不带尾部斜杠
ONES_USER_ID(兼容ONES_USER_UUID/Ones_User_Id附加鉴权 HeaderOnes-User-Id,也可用于解析当前用户 UUID
ONES_AUTH_TOKEN(兼容Ones_Auth_Token附加鉴权 HeaderOnes-Auth-Token
ONES_EMAIL/ONES_PHONE/ONES_PASSWORDlogin命令的非交互式凭据来源
ONES_TEAM_UUID(兼容ONES_TEAM_ID设置后tasks/my-tasks/task/worklog可省略--team参数
ONES_MANHOUR_SCALE工时定点整数刻度,默认100000

getOnesBaseUrl()在缺省时会抛出CONFIG类型错误,提示设置ONES_BASE_URL到你的部署源(无尾部斜杠),这也是绝大多数报错的根源。

基本环境配置

# 必填:你的 ONES 实例地址 export ONES_BASE_URL=https://your-instance.example.com # 若你的部署要求附加鉴权 Header(可选) # export ONES_USER_ID=... # export ONES_AUTH_TOKEN=...

登录与身份查询

登录(login)

opencli ones login --email you@company.com --password 'your-password'

login通过 POSTauth/login完成,属于写操作(access: 'write')。支持--email--phone(邮箱优先)+--password,也可全部由ONES_EMAIL/ONES_PHONE/ONES_PASSWORD环境变量提供。密码缺失或邮箱/手机号都未提供时会抛出带明确提示的CONFIG错误。

登录成功后,命令会打印一行stderr 提示(见 clis/ones/login.js),指导你把返回的user.uuiduser.token导出为环境变量,以便后续请求在 Cookie 不生效的部署上继续使用:

export ONES_BASE_URL="https://..." export ONES_USER_ID="<uuid>" export ONES_AUTH_TOKEN="<token>"

输出表格列为uuid/name/email/token_preview,其中 token 仅做截断预览(前 6 位 ++ 后 4 位),避免敏感信息刷屏。

当前用户(me)

opencli ones me

对应 GETusers/me,返回当前登录用户资料,列为uuid/name/email/phone/status。响应兼容两种形态:{ user: {...} }包裹结构或直接返回用户对象,代码会自动归一化(clis/ones/me.js)。

会话概览(token-info)

opencli ones token-info

对应 GETauth/token_info,返回当前用户、所属团队列表与组织信息,列为uuid/name/email/teams/org_name获取 team UUID 的关键入口:用opencli ones token-info -f json查看teams[].uuid,这是后续tasks/my-tasks/task/worklog所需的 8 位团队标识(clis/ones/token-info.js)。

登出(logout)

opencli ones logout

对应 GETauth/logout,使当前 token 失效,输出ok/detail两列,并提醒清理本地的ONES_AUTH_TOKEN(clis/ones/logout.js)。

团队任务列表(tasks)

# 基础用法 opencli ones tasks <teamUUID> --limit 20 # 按项目 / 负责人筛选 opencli ones tasks <teamUUID> --project <projectUUID> --assign <userUUID>

tasks通过 POSTteam/:team/filters/peek拉取工作项,读操作(access: 'read')。参数与默认值如下(clis/ones/tasks.js):

参数类型默认说明
team(位置参数)str无(可用ONES_TEAM_UUID8 位团队 UUID,来自token-info
--projectstr按项目 UUID 过滤(对应字段field_values.field006,即「所属项目」)
--assignstr按负责人用户 UUID 过滤(顶层assign字段)
--limitint30拍平分组后最多返回的行数,上限 500

底层筛选查询体由buildQuery构造:项目用{ in: { 'field_values.field006': [...] } },负责人用{ equal: { assign: ... } };两者可叠加,空筛选时must为空数组。完整请求体由 clis/ones/task-helpers.js 的defaultPeekBody提供,包含sort(按create_time倒序)、include_status_uuidinclude_project_uuid等控制字段。

输出列为title/status/project/uuid/updated/工时。其中「工时」列由formatTaskManhourSummary生成,同时展示评估工时(assess_manhour)、登记工时(total_manhour)与剩余工时(remaining_manhour),前缀分别为「估」「登」「余」,例如估3h 登1.5h 余2h;长标题、长 UUID 会被截断显示,完整数据用-f json查看。

我的任务(my-tasks)

opencli ones my-tasks <teamUUID> --limit 100 opencli ones my-tasks <teamUUID> --mode both

my-tasks同样走filters/peek,但查询以当前用户 UUID 为条件,自动通过users/me(或环境变量)解析「我」的 UUID(resolveOnesUserUuid)。核心参数:

参数类型默认说明
team(位置参数)str无(可用ONES_TEAM_UUID团队 UUID
--limitint100最大行数(上限 500)
--modestrassign取值assign/field004/owner/both

--mode是处理 ONES 部署差异的关键开关(clis/ones/my-tasks.js):

  • assign:按顶层assign字段等值匹配(负责人);
  • field004:按筛选器示例中的field_values.field004匹配(部分部署用该字段表示负责人);
  • owner:按创建者owner字段匹配;
  • both:负责人 ∪ 创建者,执行两次 peek 后按 UUID 去重(dedupeByUuid),再裁剪到--limit

另外存在自动降级机制:默认assign模式若遇到ServerError、错误码801Params is invalid等提示,会自动改用field004查询重试一次,适应字段不一致的实例。

任务详情(task)

opencli ones task <taskUUID> --team <teamUUID>

对应 GETteam/:team/task/:id/info(clis/ones/task.js),id是浏览器 URL 中…/task/<id>段的标识(通常是 16 位工作项 UUID,也可能是编号)。输出列:

uuid/summary/number/status_uuid/assign/owner/project_uuid/updated

其中updatedserver_update_stampformatStamp归一化为YYYY-MM-DD HH:mm:ss格式(自动兼容秒/毫秒/微秒时间戳)。若返回异常,会提示核对 id 长度与 team 是否与浏览器 URL 一致。

工时填报(worklog)

# 今日工时 opencli ones worklog <taskUUID> 2 --team <teamUUID> # 补录历史工时 + 备注 opencli ones worklog <taskUUID> 1.5 --team <teamUUID> --date 2026-03-23 --note "integration"

worklog是写操作(access: 'write'),负责记录/补录工时。参数:

参数类型必填说明
task(位置参数)str工作项 UUID(通常 16 位),来自my-tasks或浏览器 URL
hours(位置参数)str要记录的小时数(如21.5),按ONES_MANHOUR_SCALE换算,合法区间0 < h ≤ 1000
--teamstr否(可用ONES_TEAM_UUID团队 UUID
--datestr记录日期YYYY-MM-DD,默认今天(本地时区),用于补录
--notestr备注,写入description/desc
--ownerstr归属用户 UUID,默认当前登录用户

多端点降级策略

由于 Project API 路径在不同部署间有差异,源码(clis/ones/worklog.js)实现了依次尝试的降级链,共 8 个候选请求:

  1. POST team/:team/items/graphql— GraphQL 变更addManhourmode: "simple"type: "recorded"、参数owner/task/start_time/hours/description全部内联为字面量,无变量引用,见 clis/ones/worklog.test.js 的断言);
  2. POST team/:team/task/:id/manhours/add— REST 形态{ owner, manhour, start_date, end_date, desc }
  3. 同路径的allManhour/startDate/endDate驼峰形态;
  4. 同路径的{ manhours: [entry] }包裹形态(两种字段风格);
  5. POST team/:team/task/:id/manhour/add— 单数manhour路径(两种字段风格);
  6. POST team/:team/tasks/update3{ tasks: [{ uuid, manhours: [entry] }] }批量更新形态。

防假成功校验

每次尝试前,命令先 GETteam/:team/task/:id/info读取total_manhour基线;尝试后再次读取对比,只有total_manhour实际变化(差值 ≥ 1 个刻度单位)才判定成功并返回task/date/hours/owner/endpoint(endpoint 即命中的路径)。若 HTTP 200 但工时未变化,则记录no effect并继续尝试下一个端点,杜绝"接口 200 但没生效"的假成功。全部失败时抛出FETCH_ERROR,附最后一个失败详情。

工时刻度的底层换算

ONES Project API 中的assess_manhour/total_manhour/remaining_manhour大多是定点整数,与网页上的「小时」小数不一致。换算逻辑集中在 clis/ones/task-helpers.js:

export function onesManhourScale() { const raw = Number(process.env.ONES_MANHOUR_SCALE?.trim()); if (Number.isFinite(raw) && raw > 0) return raw; return 1e5; // 默认刻度 }
  • 展示方向raw / scale得到小时数,再格式化为2h1.5h这类短格式;
  • 录入方向hoursToOnesManhourRaw(hours)Math.round(hours * scale)将小时转为 API 整数,最小值为 1;
  • 若你的实例刻度不同,通过ONES_MANHOUR_SCALE覆盖默认值100000(这也是原文档 Notes 中该变量的来源)。

任务列表响应解析(filters/peek)

tasks/my-tasks共用的filters/peek响应解析位于 clis/ones/task-helpers.js 的flattenPeekGroups:响应按groups[]分组,每组含entries[],解析时按组拍平并按--limit截断,超过上限即停止。

条目字段兼容多种部署差异:

  • 标题:优先取summary/name/title/subject,其次从field_values数组([{ field_uuid, value }, ...])中提取首个非空field*值,最后回退到对象形态的field001/field002/field003pickTaskTitle);
  • 状态:优先取顶层status_uuid,否则从field016提取(getTaskStatusRawId),再经resolveTaskListLabels映射为可读状态名;
  • 项目:优先取project_uuid,否则从field006提取(getTaskProjectRawId),再映射为项目名。

由于 ONES 部分接口 HTTP 200 但 body 仍是业务错误(如reason: ServerError),throwIfOnesPeekBusinessError会在filters/peek路径上做二次校验:凡含非空reason/errcode/type且无groups的响应,都会抛出FETCH_ERROR,避免把错误当空列表处理(clis/ones/common.js)。

常见错误与排查

现象原因与处理
Missing ONES_BASE_URL(CONFIG)未设置环境变量;export ONES_BASE_URL=https://your-team.ones.cn(无尾斜杠)
HTTP 401 / UnauthorizedChrome 中打开 ONES 并登录;或先执行opencli ones login后按提示 exportONES_USER_ID/ONES_AUTH_TOKEN;并确认ONES_BASE_URL与浏览器地址一致
team UUID requiredopencli ones token-info -f json查看teams[].uuid,或设置ONES_TEAM_UUID
filters/peek返回ServerError查询条件不合法(如字段 UUID 与实例不符);可尝试opencli ones tasks <team>(空 must),并检查筛选器字段文档
my-tasks结果为空/报字段错误--mode field004--mode both适配你部署的负责人字段
worklog全部端点失败最后失败详情会随错误输出;确认任务 UUID、团队、日期格式,必要时用-f json查看原始响应
工时数字与网页不符检查ONES_MANHOUR_SCALE是否与你实例的刻度一致(默认100000

通用排查手段:所有命令都支持-f json查看原始 JSON;opencli doctor可验证 Browser Bridge 扩展与 daemon 连通性。

小结

ONES 适配器是 OpenCLI「把任意网站变成 CLI」理念在研发协同场景的落地:它利用 Browser Bridge 复用浏览器登录态,绕开了 ONES 部署形态复杂、鉴权方式不一的难题,同时通过多端点降级、防假成功校验、字段兼容解析等机制保证了在旧版 Project API 上的可用性。将其接入 AI Agent 后,即可在自动化流程中完成"查我的任务 → 看任务详情 → 记录工时"的闭环操作,所有身份与团队信息均来自token-infousers/me接口,无需人工维护 Cookie。

  • 开发工具
  • CLI
  • 人工智能
  • AI 应用
  • 浏览器控制
  • GUI 自动化

【免费下载链接】OpenCLI

Make Any Website into CLI & Use your logged-in browser by AI agent.

项目地址:https://gitcode.com/gh_mirrors/ope/OpenCLI
点击查看免费下载

相关推荐

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询