hrygo/heluo-forge--packages-forge-devops ↗★ 7

@heluo/forge-devops

Enterprise DevOps host plugin for Heluo Forge: policy-gated reads, fixed argv adapters and offline-testable delivery flow

包名
@heluo/forge-devops
兼容性
待验证
Harness 依赖范围
>=0.2.1-rc.2
版本
0.1.0
最近更新
2026年11月13日

安装

$npx -p @deepseek-ai/dsh dsh plugin --profile web add 'github:hrygo/heluo-forge#a2786f5e1152fb52c08cebeccaad7dd13dcbcb09&path:packages/forge-devops'

配置(配置页优先,环境变量兜底)

一句话:插件自己找 dop;只有找不到时才需要你指定位置。 四个配置项逐字段取第一个有值的层——配置页 > 环境变量 > 自动发现,页面对 dop 入口标出来源,覆盖关系也标出来(配置压过环境变量时挂「覆盖环境变量」),不静默替换。

配置页(设置 → 企业 DevOps)

进入路径两次点击:首页 → 左下「设置」→ 侧栏「企业 DevOps」。

页面上只有两项:dop 入口与超时。地址与事实来源不出现在页面上(怎么设见下一节)。

页面是状态而不是必填表单:命中自动发现时,两张入口卡默认只读,显示命中的可执行文件与来源(配置 / 环境变量 / 自动发现 / 未找到);用户正常情况下只读不填,只有未命中时才落进「填入路径」。

想做的事操作结果
覆盖为手动指定点「改为手动指定」,粘贴 dop 可执行文件的完整地址(资源管理器里右键文件 →「复制文件地址」)保存时逐字段校验:文件存在、是普通文件(POSIX 还要执行位)。Windows 上不按扩展名拦截:.exe、无后缀 shim、.cmd / .ps1 都能存(见「能保存 ≠ 一定能跑起来」)
回落到自动发现点「重置为自动发现」,或把输入框清空,再点「保存」该键从配置里删除,回落下一层(入口:环境变量 → 自动发现;超时:环境变量 → 缺省 20000);清空即回落,不必卸载重装
重新扫描点「重新自动发现」发现只在装配期跑一次;只有这个动作会重扫,工具调用永不触发扫描
保存页脚「保存」只提交页面上改动过的项;写入活动 profile 的补丁层(forge-devops 条目的 config: 段),页面没展示的键在补丁层里逐字保留;期间被别的窗口改过则提示「配置已被其它窗口改动 · 刷新后重试」,不覆盖对方改动
查看其它候选展开「自动发现命中 · 另有 N 个候选」多份安装时按 PATH 优先静默取首个,其余候选可展开查看,不自动选用

保存成功后读面立即按新配置重建(无需重启);写进 profile 补丁的值重启后仍然有效。发现结果不回写配置:换机器或改 PATH 后点「重新自动发现」即可跟随,页面不会把自动发现的等值写盘。当前 profile 没有挂载配置面(settings / config-editor)时,页面降级为只读并给出环境变量出口,而不是渲染一个存不进去的表单。

企业研发(设置 → 企业研发,r15 新增)

本包在设置页还有第二个分区:id devops-readiness、order 29。它只汇总本机可见性,页面顶部固定声明「本页只汇总本机可见性,不代表业务授权」。六行各读各的源,一行失败只影响自己:

行事实来源状态
企业身份GET /api/forge-iam/view 的 state已登录 / 未登录 / 登录中 / 过期 / 不可达 / 未知;未装该插件即「未安装」
公共参数无恒「未知」——尚无可核验的公共维护权限与接口
本机配置devops 与 gitee 快照里 origin === 'config' 的键名列出键名,不列值
DevOps本包快照的 ready 与 dopBin 的来源已配置 / 未配置 / 未安装(不写"通过")
Giteegitee 快照的 ready已配置 / 未配置 / 未安装
业务写权限无恒「未知」——本页不判断授权

只有 DevOps 行可以检查:「检查 DevOps」打 GET /api/forge-devops/cli?refresh=1(唯一会重新扫描的动作,?refresh=1 在客户端只拼一次)。检查态六种:未检查 / 检查中 / 通过 / 失败 / 未知 / 已过期,并带基准短号与时间;子原因是 NO_CLI(未配置)、ENTRY_NOT_EXECUTABLE(不可执行)、ENDPOINT_UNREACHABLE(目标不可达)、POLICY_DENIED(只读被拒)。Gitee 行恒「未执行」并写明未获批准的只读探测本页不发起请求。检查不写配置。

保存回执与来源页脚(r15)

devops 分区保存后显示三行互不覆盖的回执:保存(已保存 / 未保存)、应用(运行时已应用 / 未应用 / 未知)、检查(未检查 / 上次检查时间)。应用这一行读 POST 成功体里的 applied:saveCliConfig 写成功后重算读面,只有运行时合并态里真的出现了新值才回 {ok:true};重建抛错或读面立不起来则降级并回 {ok:false, reason:'CLI_REBUILD_FAILED'}——此时"已保存"仍成立,但页面不会假装生效。页脚一行「分区由 @heluo/forge-devops 提供 · 读取于 」,版本与时刻都来自服务端快照(plugin / readAt),浏览器半不读 package.json。

配置项(配置页 / 环境变量 / 后端推导)

四个键名与代码同源(CLI_FIELDS,camelCase),页面标签、环境变量与工具失败文案指向同一句指引「设置 → 企业 DevOps」。四项按设置方式分三档:

  • 2 项可在配置页设置:dopBin、timeoutMs。
  • 1 项仅环境变量与配置文件:dopEndpoint——页面不渲染它,要设就写环境变量或活动 profile 补丁层的 config: 段。
  • 1 项由后端推导:sourceType——dopBin 解析到可执行文件才推成 enterprise(裸命令名 dop 这类默认值不算就绪),否则 mock;显式配置或环境变量仍优先。

保存只写页面上的两项,其余键在补丁层里逐字保留(不展示的键不会被清空)。

配置项(camelCase)配置页环境变量缺省说明
dopBindop 可执行文件FORGE_DEVOPS_DOP_BIN自动发现;三层都没有则未就绪完整地址,或已在 PATH 内的可执行文件名(如 dop);判定只看「存在且是普通文件」,Windows 上不限扩展名
dopEndpoint—(仅环境变量 / 配置文件)FORGE_DEVOPS_DOP_ENDPOINT留空即不配置绝对 http(s) 地址,地址里不能带用户名密码;凭据不进地址、不进配置页
sourceType—(后端推导)FORGE_DEVOPS_SOURCE_TYPE推导mock(本地模拟)/ enterprise(企业实测):dopBin 从配置 / 环境变量 / 自动发现解析到可执行文件才算 enterprise;报告按此分记事实来源
timeoutMs超时(毫秒)FORGE_DEVOPS_TIMEOUT_MS20000单次调用上限,取值 1000–600000

字段规则的唯一真源是 src/runtime-config.mjs 的 validateConfigField:环境变量层与宿主 loader 的配置校验直接调用它。浏览器半(client.js)不能 import 服务端模块,所以页面只对两项可编辑字段内联了一份子集校验(入口路径只判长度上界 4096,超时只判区间;不做任何后缀判断),存在性、是否目录与 POSIX 执行位一律由服务端在保存时判定(形态判定全仓只有一份,在 src/entry-form.mjs);两面的关系不是靠注释保证,而是由 test/client-rule-parity.test.mjs 的跨面矩阵用例守着——两项逐行对齐,页面没展示的两项断言"页面恒放过、服务端仍拒"(页面收窄不等于服务端放宽;R2-1 就是副本少了上界、失焦放行、保存才 422)。任一解析到的键非法即整包未就绪(CLI_CONFIG_INVALID),不回落下一层——填错的意图若被静默换成别的路径,用户会以为"我配置的那个在生效";页面上两项逐字段报错(找不到这个文件 / 这是目录 / 不是可直接执行的文件 / 路径过长(>4096)/ 超时越界),服务端 422 若点到页面上没有的键,原因落在页脚,不会为一个不存在的输入框聚焦。

自动发现规则

发现是只读的、有界的文件系统探测,零子进程,只在装配期与页面「重新自动发现」时跑:

  • 名字:Windows 上按优先级试 6 个候选名——dop.exe → dop(裸名)→ dop.cmd → dop.ps1 → dop.bat → dop.com(大小写不敏感);macOS / Linux 认无后缀的 dop,并要求执行位。名字表的下标就是优先级:同一位置或不同目录同时存在原生 .exe 与脚本形态时,found[0] 恒为 .exe。
  • 位置:PATH 的每一项;再加少量候选目录(Windows:%ProgramFiles%\{tool}、%ProgramFiles(x86)%\{tool}、%ProgramFiles%\heluo、%LOCALAPPDATA%\Programs\{tool}、%USERPROFILE%\.{tool}\bin;POSIX:/usr/local/bin、/opt/{tool}/bin)。不递归遍历。
  • 预算:最多 200 个目录、250ms 截止(是上限而不是目标,正常机器只碰几个目录)。
  • 不按扩展名拒收:只要存在且是普通文件(POSIX 另需执行位)就进候选,rejected 恒为空数组。于是候选里可能出现 dop.cmd 这类存得下但启动不了的入口,能不能真正跑起来交给运行期提示(见下一节),发现阶段不替用户预先否掉。真实文件名与路径在候选里照原样显示,不从显示值里删后缀。
  • 只读、只纳入真实存在的文件:不执行文件、不解析其内容、不写任何东西;发现结果也不回写配置。

能保存 ≠ 一定能跑起来(Windows 包装脚本)

保存与发现都不再按扩展名拦截,但启动方式一点没松:唯一出口仍是 execFile + shell: false + 固定 argv(src/cli-runner.mjs),不引入 shell、不拼接命令行字符串。于是 Windows 上有两类「存得下、跑不起来」的入口:

  • npm 生成的无后缀 shim(npm 的全局安装目录,Windows 上通常是 %APPDATA%\npm\dop;也可能是 Git Bash 版本):启动通常报 ENOENT;
  • .cmd / .ps1 / .bat 包装脚本:启动通常报 EINVAL。

两者原因相同:这份调用方式要求直接 exec 一个可执行体,而脚本本身要靠 cmd.exe / PowerShell 解释——这是启动方式的限制,与路径写法无关,改后缀、补引号、换目录都不解决。所以第一次真正调用这条 CLI 时,失败信封里给的是可行动的提示:把配置改指该 CLI 的原生可执行文件(Windows 上即 .exe),或改用提供原生二进制的安装方式。该提示不含盘符、绝对路径与 endpoint(它要进工具输出与日志);贴地址前建议先在资源管理器里看一眼后缀。

ready 只表示「入口已解析」,不编码「已验证可运行」:页面上两项都绿的时候,仍可能在第一次调用时起不来。区分方法看失败信封——detail.spawnFailed: true 表示进程根本没起来(不是业务失败),读调用按失败记录且不重放。

找不到时

fail closed 语义不变,但文案改成人话:只读工具仍以 NO_READER 失败(原因码不加码),detail.reason 给细因(CLI_NOT_FOUND / CLI_CONFIG_INVALID)、detail.searched 给已查类别(配置 / 环境变量 / PATH / 候选目录)、detail.next 给页面入口;流程面仍可达,但只产出 blocked 卡且零子进程调用。整条信封不含盘符、绝对路径与平台地址——它要进工具输出与日志。

配置页(设置 → 企业 DevOps)

进入路径两次点击:首页 → 左下「设置」→ 侧栏「企业 DevOps」。

页面上只有两项:dop 入口与超时。地址与事实来源不出现在页面上(怎么设见下一节)。

页面是状态而不是必填表单:命中自动发现时,两张入口卡默认只读,显示命中的可执行文件与来源(配置 / 环境变量 / 自动发现 / 未找到);用户正常情况下只读不填,只有未命中时才落进「填入路径」。

想做的事操作结果
覆盖为手动指定点「改为手动指定」,粘贴 dop 可执行文件的完整地址(资源管理器里右键文件 →「复制文件地址」)保存时逐字段校验:文件存在、是普通文件(POSIX 还要执行位)。Windows 上不按扩展名拦截:.exe、无后缀 shim、.cmd / .ps1 都能存(见「能保存 ≠ 一定能跑起来」)
回落到自动发现点「重置为自动发现」,或把输入框清空,再点「保存」该键从配置里删除,回落下一层(入口:环境变量 → 自动发现;超时:环境变量 → 缺省 20000);清空即回落,不必卸载重装
重新扫描点「重新自动发现」发现只在装配期跑一次;只有这个动作会重扫,工具调用永不触发扫描
保存页脚「保存」只提交页面上改动过的项;写入活动 profile 的补丁层(forge-devops 条目的 config: 段),页面没展示的键在补丁层里逐字保留;期间被别的窗口改过则提示「配置已被其它窗口改动 · 刷新后重试」,不覆盖对方改动
查看其它候选展开「自动发现命中 · 另有 N 个候选」多份安装时按 PATH 优先静默取首个,其余候选可展开查看,不自动选用

保存成功后读面立即按新配置重建(无需重启);写进 profile 补丁的值重启后仍然有效。发现结果不回写配置:换机器或改 PATH 后点「重新自动发现」即可跟随,页面不会把自动发现的等值写盘。当前 profile 没有挂载配置面(settings / config-editor)时,页面降级为只读并给出环境变量出口,而不是渲染一个存不进去的表单。

配置项(配置页 / 环境变量 / 后端推导)

四个键名与代码同源(CLI_FIELDS,camelCase),页面标签、环境变量与工具失败文案指向同一句指引「设置 → 企业 DevOps」。四项按设置方式分三档:

  • 2 项可在配置页设置:dopBin、timeoutMs。
  • 1 项仅环境变量与配置文件:dopEndpoint——页面不渲染它,要设就写环境变量或活动 profile 补丁层的 config: 段。
  • 1 项由后端推导:sourceType——dopBin 解析到可执行文件才推成 enterprise(裸命令名 dop 这类默认值不算就绪),否则 mock;显式配置或环境变量仍优先。

保存只写页面上的两项,其余键在补丁层里逐字保留(不展示的键不会被清空)。

配置项(camelCase)配置页环境变量缺省说明
dopBindop 可执行文件FORGE_DEVOPS_DOP_BIN自动发现;三层都没有则未就绪完整地址,或已在 PATH 内的可执行文件名(如 dop);判定只看「存在且是普通文件」,Windows 上不限扩展名
dopEndpoint—(仅环境变量 / 配置文件)FORGE_DEVOPS_DOP_ENDPOINT留空即不配置绝对 http(s) 地址,地址里不能带用户名密码;凭据不进地址、不进配置页
sourceType—(后端推导)FORGE_DEVOPS_SOURCE_TYPE推导mock(本地模拟)/ enterprise(企业实测):dopBin 从配置 / 环境变量 / 自动发现解析到可执行文件才算 enterprise;报告按此分记事实来源
timeoutMs超时(毫秒)FORGE_DEVOPS_TIMEOUT_MS20000单次调用上限,取值 1000–600000

字段规则的唯一真源是 src/runtime-config.mjs 的 validateConfigField:环境变量层与宿主 loader 的配置校验直接调用它。浏览器半(client.js)不能 import 服务端模块,所以页面只对两项可编辑字段内联了一份子集校验(入口路径只判长度上界 4096,超时只判区间;不做任何后缀判断),存在性、是否目录与 POSIX 执行位一律由服务端在保存时判定(形态判定全仓只有一份,在 src/entry-form.mjs);两面的关系不是靠注释保证,而是由 test/client-rule-parity.test.mjs 的跨面矩阵用例守着——两项逐行对齐,页面没展示的两项断言"页面恒放过、服务端仍拒"(页面收窄不等于服务端放宽;R2-1 就是副本少了上界、失焦放行、保存才 422)。任一解析到的键非法即整包未就绪(CLI_CONFIG_INVALID),不回落下一层——填错的意图若被静默换成别的路径,用户会以为"我配置的那个在生效";页面上两项逐字段报错(找不到这个文件 / 这是目录 / 不是可直接执行的文件 / 路径过长(>4096)/ 超时越界),服务端 422 若点到页面上没有的键,原因落在页脚,不会为一个不存在的输入框聚焦。