@ohos-cpf/3rdloop
3rdLibraryLoop 三方库自动化检视命令行工具(嵌入式模式)。
3rdloop CLI 直接复用 3rdLibraryLoop 的核心引擎(LoopEngine / Brain / Orchestrator /
FlexRunner / TestCheck / Knowledge),无需启动 HTTP 服务,即可从终端完整跑一遍
"任务拆解 → 编排执行 → 准出审核"的大循环。
快速开始
# 环境自检
3rdloop doctor
# 提交并阻塞到准出终态(最常用)
3rdloop run "为 libcurl 生成鸿蒙 demo 场景并跑通编译"
# 提交并立即返回 taskId(进程内继续跑,需保持进程存活)
3rdloop submit "分析 sqlite3 的鸿蒙化可行性"
# 等待到终态 / 查询进度 / 中止 / 列表 / 结果
3rdloop wait <taskId> --timeout 30m
3rdloop progress <taskId> --watch
3rdloop abort <taskId>
3rdloop list --status running
3rdloop result <taskId> --json
命令一览
| 命令 | 说明 |
|---|---|
3rdloop run <desc> |
提交任务并阻塞到准出终态(默认行为) |
3rdloop submit <desc> |
提交任务,打印 taskId 后进程内继续执行 |
3rdloop wait <taskId> [--timeout 30m] |
等待任务到终态 |
3rdloop progress <taskId> [--watch] |
查询进度;--watch 持续轮询到终态 |
3rdloop abort <taskId> |
中止任务 |
3rdloop list [--status st] [--limit N] [--older-than 7d] |
列出任务 |
3rdloop result <taskId> [--raw] |
读取最终结果 |
3rdloop step run <desc> [--task-id id] [--step-id N] [--input-report p] [--max-retries N] [--loop N] [--task-dir p] [--specified-skill <SKILL name|目录名>] |
单步执行(FlexRunner 直连,不经拆解/编排/审核) |
3rdloop step status <taskId> [--step-id N] |
查询单步状态/产物/会话 |
3rdloop step result <taskId> [--step-id N] |
读取该步 result.md 内容 |
3rdloop orch run <task-def.json> |
加载任务定义 + 启动编排,阻塞到终态 |
3rdloop orch load <task-def.json> |
仅加载任务定义(落盘 orchestration.json) |
3rdloop orch start <taskId> |
从磁盘恢复 LOADED 状态并启动编排,阻塞到终态 |
3rdloop orch progress <taskId> [--loop N] |
查询编排进度 |
| `3rdloop orch abort | pause |
3rdloop orch tasks |
列出编排任务 |
3rdloop workflows |
列出已注册的固定编排工作流 |
3rd3rdloop run <工作流名> [--flag <值> ...] |
以固定编排执行工作流(阻塞到终态) |
3rdloop run pr-check --pr-url <URL> [--library-type <arkts|flutter|rn|tpccplus>] |
PR 代码检视(等价前端 PR 检视面板,taskId 带 codecheck_ 前缀) |
3rdloop config list|get|set|unset |
命令配置 .env 配置项(默认读写 ~/.3lib/.env) |
3rdloop update [--check] [--registry <url>] |
自更新到 npm 最新版(尊重用户镜像源,无交互确认) |
3rdloop doctor |
环境自检(Node/CLI_TYPE/AI CLI(按类型检测)/.env/SKILL/数据目录/serve 连通性;自动修复:MCP Gateway 装配、免交互权限、火山网关 glm-5.3 / Qwen3.8-Max 模型) |
3rdloop version |
版本信息 |
全局选项
| 选项 | 说明 |
|---|---|
--json |
结构化输出到 stdout(进度/日志走 stderr,脚本可安全解析 stdout) |
-v, --verbose |
详细模式 |
--quiet |
仅输出最终结果 |
--data-dir <p> |
数据目录覆盖(默认 ~/.3lib/3rdloop/db) |
--project <n> |
项目名覆盖(默认取 git 仓库根名) |
--skill-dir <p> |
SKILL 目录覆盖 |
-h, --help |
帮助 |
退出码
| 码 | 含义 |
|---|---|
| 0 | 通过 / 成功 |
| 1 | 错误(参数 / 环境 / 任务不存在) |
| 2 | 任务执行失败(终态 failed / error / 未通过) |
| 3 | wait 超时 |
| 130 | Ctrl+C(SIGINT) |
| 143 | SIGTERM |
单步执行(FlexRunner)
3rdloop step 直接复用通用单步执行器 FlexRunner(不经 Brain 拆解 / Orchestrator
编排 / TestCheck 审核),适合"只跑一个步骤"的精确控制场景:
# 阻塞执行单个步骤(成功退出码 0,失败 2)
3rdloop step run "为 libcurl 的 HTTP 请求生成 ArkTS demo" \
--task-id step_demo_001 --step-id 1 --max-retries 2
# 带输入报告 / 指定产物目录 / 指定大循环轮次
3rdloop step run "根据检视报告修复 XTS 用例" \
--task-id step_fix_001 --input-report output/report.md --loop 1
# 固定执行某个 SKILL(未指定则以无 SKILL 模式直接执行)
3rdloop step run "为 FastBle 生成 XTS 代码" \
--task-id step_skill_001 --specified-skill arkts-library-xts-code
# 查询步骤状态或读取最终产物
3rdloop step status step_demo_001
3rdloop step result step_demo_001 --json
参数
| 参数 | 说明 |
|---|---|
--task-id <id> |
任务 ID(必填,step 命令不自动生成) |
--step-id <N> |
步骤编号(默认 1) |
--input-report <p> |
输入报告/上下文文件路径(可选) |
--max-retries <N> |
最多重试次数(默认 3) |
--loop <N> |
大循环轮次编号(默认 0) |
--task-dir <p> |
产物目录(默认 <data-dir>/task/<taskId>) |
--specified-skill <name> |
固定执行的 SKILL name 或目录名(在 skill 目录内解析);不传则以无 SKILL 模式直接执行 |
行为与差异
- 产物:写入 taskDir 下
stepId{n}_loop{L}_result_{R}.md(R为第几次重试),并同时生成stepId{n}_loop{L}_Summary_{R}.md经验总结与步骤记录stepid_{stepId}_loop{L}.json。 - loop.json:写精简状态(
isSingleExecution: true),因此3rdloop list/3rdloop progress <taskId>/3rdloop result <taskId>都能看到该任务。 - 与
3rdloop run的差异:run走完整大循环(拆解→编排→审核→可重规划, 自动生成 taskId);step只执行一步,适合把已拆好的任务按步骤手动串联。 - 中断:Ctrl+C 会对 FlexRunner 调用
controlExecution('abort')终止当前步骤 并清理 AI CLI serve 子进程,退出码 130。 - 多次执行同一 taskId:不会归档旧任务(与
run的自动归档不同), 每次step run在相同 loop 编号下会覆盖同名产物,建议不同尝试用不同--loop。
编排执行(Orchestrator)
3rdloop orch 对应 HTTP 层 POST /api/orchestrator/load 与 /api/orchestrator/start
接口,直接复用 Orchestrator 核心类做多步骤依赖编排(不经 Brain 拆解 /
TestCheck 审核)。适合已经把任务拆成步骤、且步骤之间存在 nextStepId /
failStepId / dependId 依赖关系的场景。
# ① 加载任务定义 + 启动编排并阻塞到终态(推荐入口)
3rdloop orch run task-def-demo.json
# ② 仅加载任务定义(落盘 orchestration.json,进程退出后仍可 start)
3rdloop orch load task-def-demo.json
# ③ 从磁盘恢复 LOADED 状态并启动(跨进程)
3rdloop orch start task_xxx
# ④ 查询 / 控制 / 列表
3rdloop orch progress task_xxx --loop 0
3rdloop orch abort task_xxx
3rdloop orch pause task_xxx # 恢复:3rdloop orch resume task_xxx
3rdloop orch tasks
任务定义 JSON(task-def.json)
格式与 Orchestrator.loadTask 对齐:
{
"taskId": "task_xxx",
"taskDir": "",
"skillDirectory": "",
"loopCount": 0,
"steps": [
{ "stepId": 1, "taskDescription": "分析三方库接口", "dependId": 0, "nextStepId": 2, "failStepId": 0, "maxRetries": 3 },
{ "stepId": 2, "taskDescription": "生成 demo 场景", "dependId": 1, "nextStepId": 0, "failStepId": 1, "maxRetries": 3 }
]
}
字段说明:
| 字段 | 说明 |
|---|---|
taskId |
任务 ID(必填) |
taskDir |
产物目录(可选,默认 <data-dir>/task/<taskId>) |
skillDirectory |
SKILL 目录(可选,默认 CLI 解析的 skill-dir) |
loopCount |
大循环轮次(默认 0,用于区分各轮产物文件) |
steps[].stepId |
步骤唯一 ID(必填) |
steps[].taskDescription |
步骤任务描述(必填) |
steps[].dependId |
前置依赖(0=入口;支持数组做 fan-in 聚合) |
steps[].nextStepId |
成功后下一步(0=结束) |
steps[].failStepId |
失败后修复步骤(0=失败即终止) |
steps[].maxRetries |
最大重试次数(默认 3) |
steps[].specifiedSkill |
固定执行的 SKILL name 或目录名(可选,在 skillDirectory 内解析);不传则以无 SKILL 模式直接执行 |
语义与限制
- load 可跨进程:
3rdloop orch load会立即落盘orchestration.json(状态loaded),之后任何终端/进程都能3rdloop orch start <taskId>恢复并启动。 - start 仅接受 LOADED:任务处于
completed/failed/running等状态时 拒绝启动(与 HTTPcontroller.start校验一致)。 - progress 读磁盘:
3rdloop orch progress直接读orchestration.json/orchestration_loop{N}.json,不依赖内存实例,历史轮次可用--loop N。 - loop.json:编排结束后写精简状态(
isOrchestration: true),因此3rdloop list/3rdloop result也能看到编排任务。 - 中断:Ctrl+C 会对 Orchestrator 调用
abort()并清理 AI CLI serve 子进程, 退出码 130。 - 跨进程控制限制:
abort/pause/resume优先作用于当前进程内正在 运行的编排实例;无法中断另一进程的运行中任务(v1 与3rdloop run语义一致)。
工作流机制(固定编排)
工作流是将"固定步骤编排"封装为带参数的 CLI 命令入口:3rd3rdloop run <工作流名> 会在运行时
把参数构造为具参 taskDef,并复用 3rdloop orch 链路(orchLoad + orchStart)阻塞执行到终态。
适合把一组固定的 SKILL 串联(如 pr push、code check 等)沉淀为可复用命令。
使用
# 查看已注册工作流
3rdloop workflows
# 查看某个工作流的参数说明
3rd3rdloop run <工作流名> --help
# 正式执行(阻塞到终态;退出码 0=通过 / 2=任务失败)
3rd3rdloop run <工作流名> --flag1 <值> --flag2 <值>
# dry-run:只构造并打印/落盘 taskDef,不触碰引擎(调试新工作流用)
3rd3rdloop run <工作流名> --flag1 <值> --print-taskdef
3rdloop run submit同样支持工作流名(命中时走工作流,未命中保持原任务描述语义)- 产物落默认
<数据目录>/task/{taskId}/;--print-taskdef会额外写task-def.dry.json供人工核对 - 退出码:
0通过 /1参数或环境错误 /2任务执行失败 /130Ctrl+C /143SIGTERM
已注册工作流
pr-check—— PR 代码检视(等价封装前端Web/public/js/codecheck.js的 PR 检视面板):
# 按库类型检视 PR(arkts 为默认,不传 --library-type 即可)
3rdloop run pr-check --pr-url https://gitcode.com/owner/repo/pulls/123 --library-type rn
# dry-run:核对构造出的 taskDef 与前端是否等价(不触碰引擎)
3rdloop run pr-check --pr-url https://gitcode.com/owner/repo/pulls/123 --print-taskdef
与前端协同的两个约定:
-
taskId 前缀
codecheck_:格式codecheck_{owner}_{repo}_{prNum}_{ts36},与前端codecheck.js一致。前端 PR 检视历史页按taskIdPrefix=codecheck_过滤,故 CLI 提交的 检视任务在前端历史页同样可见。 -
SKILL 映射:
arkts→arkts-code-check(默认) /flutter→flutter-code-check/rn→rn-code-check/tpccplus→tpc-cpp-check,与前端_CC_SKILL_MAP同构;单步骤specifiedSkill固定绑定,maxRetries: 3,title格式PR检视|{libraryType}|{prUrl}(供前端历史恢复解析)。 -
参数校验:
--pr-url必填;--library-type非法值(非上述四种)在 dry-run 阶段即报错退出。 -
pr-push—— 三方库自动提 PR(绑定Server/Skills/ohos-lib-pr-pushSKILL):
# 最常用:workspace-dir 缺省取 CLI 命令执行目录(须为 fork 仓库克隆的 git 根)
3rdloop run pr-push
# 显式指定工作区 / 可选参数
3rdloop run pr-push --workspace-dir D:\work\fork-repo --upstream-url https://gitcode.com/CPF-RN/lib
# dry-run:只构造 taskDef 核对(不触碰引擎;SKILL 级 dry-run 用 --dry-run true)
3rdloop run pr-push --workspace-dir D:\work\fork-repo --print-taskdef
| 参数 | 必填 | 说明 |
|---|---|---|
--workspace-dir |
否(默认 CLI 执行目录) | 本地 fork 仓库克隆的 git 根目录;未传时取 process.cwd(),仍须为 git 仓库 |
--upstream-url |
否 | 源仓库(上游)URL;缺省按 SKILL Phase 1.1 推断 |
--base-branch |
否 | PR 目标(上游)分支;缺省先探测上游同名分支,否则上游默认分支 |
--branch-name |
否 | 提交分支名;SKILL 默认使用当前分支,不自动建/切分支 |
--commit-message |
否 | 提交信息;缺省由修改点总结自动生成 |
--changelog |
否 | auto(默认)/true/false,决定是否更新 CHANGELOG |
--dry-run |
否 | SKILL 级 dry-run:true 只总结修改点与生成报告,不执行发布 |
与 pr-check 的关键差异:
specifiedSkill: 'ohos-lib-pr-push',maxRetries: 0:提 PR 是非幂等发布操作, 自动重试可能重复创建 Issue/PR,故恰好执行一次、绝不自动重试(失败恢复由 SKILL 的 "保留已完成产物编号/链接写入报告"逻辑承担)。--workspace-dir默认 = CLI 执行目录:未传时对process.cwd()做 git 仓库校验, 非 git 仓库报错退出码 1。- 报告复制(
afterRun钩子):SKILL 最终报告生成在{workspaceDir}/ohos-lib-pr-push-report.md;编排成功后由 CLI 自动复制到 执行目录同名文件(目标已存在时先改名备份.bak_<ts>),脚本可在执行目录稳定取报告。 失败时保留报告在工作区供人工查看。 - taskId 前缀
prpush_:格式prpush_{ts36}{rand8},无前端协同页面,仅便于list过滤。
如何新增一个工作流
在 cli/workflows/ 目录下新增一个 .js/.mjs 文件,默认导出一个工作流声明对象 即可自动注册,
无需改动任何分发代码:
export default {
name: 'demo prep', // 工作流名,支持多词(空格分隔,分发时最长匹配)
description: '示例:构造一个占位固定编排(仅演示注册约定)',
params: [ // CLI flags schema(驱动参数校验 / --help)
{ flag: 'workspace-dir', required: true, describe: '本地工作区 git 仓库根目录' },
{ flag: 'report-name', required: false, describe: '输出报告名(默认 check-report.md)' },
],
// params: { 'workspace-dir': <值>, ... } → 返回与 Orchestrator.loadTask 对齐的 taskDef
buildTaskDef(params) {
return {
taskId: '', // 缺省时 CLI 自动生成(generateTaskId())
title: 'Demo 固定编排',
skillDirectory: '',
loopCount: 0,
steps: [{
stepId: 1,
taskDescription: `分析工作区修改并输出 ${params['report-name'] || 'check-report.md'} 报告`,
dependId: 0, nextStepId: 0, failStepId: 0, maxRetries: 3,
inputReport: '',
}],
};
},
// afterRun 可选:编排结束后执行的后置动作(成功/失败均调用;入参含 result.passed;
// 抛错只记录不改变退出码)。典型场景:把 SKILL 产出的报告复制到 CLI 执行目录。
async afterRun({ params, taskDef, result, dataDir, cwd }) {
// 仅在任务成功时动作,失败时产物保留在工作区
if (result.passed !== true) return;
},
};
约定与细节:
-
周边机制:
run执行分两段——buildTaskDef(参数 → taskDef,可 dry-run)与afterRun(编排后的后置动作)。后者对成功与失败都会调用,由工作流自身按result.passed决定是否动作;抛出的异常仅记录 stderr,不影响退出码。 -
自动注册:
cli/lib/workflows.js启动时扫描cli/workflows/*.mjs|*.js,每文件默认导出一个工作流。 加载失败 / name 缺失 / 重名的工作流会被跳过并输出警告(不阻断其余工作流)。 -
多词名最长匹配:
3rdloop run pr push ...会先试完整pr push,未注册再退pr。 -
steps 格式:与
3rdloop orch run <task-def.json>的 taskDef 格式 完全一致 (stepId / taskDescription / dependId / nextStepId / failStepId / maxRetries / specifiedSkill / inputReport)。 -
specifiedSkill 建议:与核心引擎约定一致——步骤职责能匹配某可用 SKILL 时,把它写入
specifiedSkill(值为 SKILL name 或目录名),执行层按该 SKILL 执行;未设置的步骤 以无 SKILL 模式直接执行(执行层不做任何 LLM 匹配)。 -
只读环境注入:
buildTaskDef(params, { dataDir, cwd })第二参携带运行时环境 (数据目录、CLI 执行目录等),需要落盘相对路径或"缺省取执行目录"语义时使用。
职责边界
- 工作流注册表只负责"参数 → taskDef"。业务工作流(如
pr-push)与所需 SKILL 由其他项目 开发者按上述约定注册与维护,CLI 核心不预置通用业务工作流;pr-check/pr-push是 当前仓库内已注册的业务工作流范本,新增业务 SKILL 请放在Server/Skills/下(沿用既有 SKILL 约定),工作流文件中以specifiedSkill引用即可。
config 配置命令(.env 配置项)
3rdloop config 提供对 .env 配置项的命令式管理,默认读写用户级 ~/.3lib/.env(跨项目全局生效),无需每次命令携带 flag 或手改 .env 文件。
子命令
| 子命令 | 作用 |
|---|---|
3rdloop config list |
列出全部已知配置项及当前生效值(密钥类脱敏) |
3rdloop config get <KEY> |
查看某项当前生效值(密钥类脱敏) |
3rdloop config set <KEY> <VALUE> |
设置某项并写入 ~/.3lib/.env(密钥不回显) |
3rdloop config unset <KEY> |
删除 ~/.3lib/.env 中的某项(恢复默认) |
读取优先级(与 .env 加载链一致)
系统环境变量 > ~/.3lib/.env(用户级) > 项目根 Server/.env > 内置默认值。
config 命令会模糊识别每项当前来源(env / user-env / project-env / default),在 list/get 输出中标注。
白名单与校验
config 命令内置全部已知配置键的白名单目录(编排并发 / CLI / GitCode / 3LIB_*),每项带默认值、说明与校验器(端口、枚举等)。未知键 set 会报错列出已知项。GIT_TOKEN 等密钥类在 get/list 中脱敏显示。(直连 LLM 配置键(DASHSCOPE_API_KEY / LLM_* / SELECTOR_*)已移除——引擎全链路经 CLI session,无百炼直连依赖。)
示例:配置默认存储路径
# 查看当前生效的数据目录(默认 ~/.3lib/3rdloop/db)
3rdloop config get 3LIB_DATA_DIR
# 将任务产物统一存到团队共享目录(全局生效,无需每次带 --data-dir)
3rdloop config set 3LIB_DATA_DIR "D:\code\team\shared-db"
# 确认生效:doctor 数据目录变为该路径,run 产物落 <dir>/task/<taskId>/
3rdloop doctor
# 恢复默认
3rdloop config unset 3LIB_DATA_DIR
说明
3LIB_ROOT/3LIB_HOME为系统环境变量专用(.env写入不生效),config会拒绝set,请用setx/export配置。- 密钥
set后明文写入~/.3lib/.env(与手写 .env 一致),但 CLI 标准输出不回显明文。 --data-dir/--skill-dir等命令行 flag 仍是最高的单次覆盖,不受config影响。
自更新(3rdloop update)
3rdloop update 检查 npm registry 上的最新版本,发现新版本时直接自动重装(无交互确认):
# 检查并直接更新到 latest
3rdloop update
# 仅检查是否有新版本,不执行更新(适合 CI / 提醒)
3rdloop update --check
# 覆盖 npm registry(默认尊重用户 npm 镜像配置,如 npmmirror)
3rdloop update --registry https://registry.npmjs.org/
更新姿势
| 安装方式 | update 行为 |
|---|---|
正式全局安装(npm i -g @ohos-cpf/3rdloop) |
检查发现新版本后 npm install -g @ohos-cpf/3rdloop@latest 重装 |
--check |
只查询与输出版本差异,不做任何修改 |
安全说明
- 所有 npm 调用(
view/config get/uninstall/install)统一经runNpm(args, opts)封装。 - Windows 兼容:win32 下
npm是npm.cmd批处理 shim,execFileSync('npm')会因 CreateProcess 无法执行批处理而抛spawnSync npm ENOENT;runNpm在 win32 用shell:true让 cmd.exe 按 PATHEXT 解析npm.cmd,POSIX(macOS/Linux)保持shell:false直接调用、行为不变。 - 注入防护:win32 分支对用户可控的
--registry值做 http(s) URL 白名单校验(拒绝空白/引号/&|<>^();%等元字符),其余参数均为代码内常量。 - 更新只替换程序文件,数据目录
~/.3lib/3rdloop/db、~/.3lib/.env配置均不受影响(数据根在设计上不随 npm 包变化)。 - 更新走
npm install -g全量重装,保证引擎与依赖(@opencode-ai/sdk/better-sqlite3/dotenv等)版本自洽,不手动改动node_modules。 - 更新完成后请用
3rdloop version/3rdloop doctor确认新版本与引擎来源。 - 无交互确认:检测到新版本直接重装,脚本/CI 可直接调用(历史
--yes/-y参数仍被接受,无实际作用)。
环境约定
.env加载链:系统环境变量 >~/.3lib/.env(用户级) > 项目根Server/.env。- 数据目录:
~/.3lib/3rdloop/db(Windows:C:\Users\<用户>\.3lib\3rdloop\db,macOS/Linux:~/.3lib/3rdloop/db),跨平台一致、不随执行目录变化、不随 npm 卸载清空;任务写入<数据目录>/task/{taskId}/。 - AI CLI(
CLI_TYPE,默认 deveco-code):3rdloop会自动拉起对应的serve(deveco serve/opencode serve,需在项目上一级目录运行), 退出时负责清理进程树。若已存在运行中的服务则直接复用。
环境变量
CLI 自身配置(3LIB_* 前缀):可用 3rdloop config set <KEY> <VALUE> 配置(写入 ~/.3lib/.env),下表列出默认值。
| 变量 | 作用 | 默认值 |
|---|---|---|
3LIB_DATA_DIR |
数据目录覆盖(等效 --data-dir) |
~/.3lib/3rdloop/db |
3LIB_ROOT |
项目根覆盖(须为系统环境变量,.env 文件不生效) |
自动探测 |
3LIB_HOME |
用户 3lib 主目录(含日志 logs/,须为系统环境变量) |
~/.3lib |
3LIB_SKILL_DIR |
SKILL 目录覆盖(等效 --skill-dir) |
vendor/Server/Skills |
3LIB_TASK_PREFIX |
taskId 前缀(审计用) | 空 |
推荐用 3rdloop config 管理(默认写入 ~/.3lib/.env):
# 配置默认存储路径(全局生效,无需每次带 --data-dir)
3rdloop config set 3LIB_DATA_DIR "D:\code\team\shared-db"
3rdloop config list # 查看全部配置项及当前生效值
> **注意**:提交用的 `--data-dir` / `3LIB_DATA_DIR` 必须与 `wait`/`progress`/`list`/`result` 一致,
> 否则会出现"任务不存在"。跨终端统一最简单的方式是 `setx 3LIB_DATA_DIR` 一人设全局。
引擎凭据变量(`GIT_TOKEN`):按 `.env` 加载链任选一层配置即可。(引擎全链路经 CLI session 驱动 AI,无直连 LLM 凭据变量。)
## 场景一:新用户接入
### 前置条件
- Node.js >= 22
- AI CLI(`opencode serve` 或 `deveco serve` 可运行,按 `CLI_TYPE`)
- GitCode Token(一个 `.env` 即可)
### 接入步骤
```bash
# ① 安装 CLI(正式发布后)
npm i -g @ohos-cpf/3rdloop
# 开发期替代:与后端共用仓库时用 npm link(直引 Server/ 源码,无需生成 vendor)
cd cli && npm install && npm link
# ② 环境自检,缺什么看什么
3rdloop doctor
# ③ 配置 GitCode Token(三选一)
# A. 项目级:在仓库 Server/.env 填 token(推荐,跟仓库走)
# B. 用户级:C:\Users\<用户>\.3lib\.env
# C. 系统环境变量:setx GIT_TOKEN "xxx"
# ④ 跑一个最小任务验证
3rdloop run "冒烟:分析一个三方库的鸿蒙化可行性" --max-loops 1
数据目录默认在用户三义库主目录 ~/.3lib/3rdloop/db(跨平台一致,不随执行目录/ npm 卸载变化);如需自定义位置(如团队共享目录),用 --data-dir 或 3LIB_DATA_DIR 覆盖。
注意:CLI 任务数据默认与 Web 前端(读取仓库根
db/)分离,CLI 提交的任务不会出现在前端任务列表。
场景二:后端更新与软链
开发期(仓库内共享):零副本,直引源码
CLI 在开发期不生成 cli/vendor/,直接引用仓库 Server/ 源码:
- 引擎模块回退:
cli/vendor/Server不存在时,加载../Server(runner.js: resolveVendorServer)。 - SKILL 目录回退:
vendor/Server/Skills不存在时,用仓库Server/Skills(config.js: resolveSkillDir)。
后端代码改完立即可用,无需任何复制步骤:
cd cli
# ① npm link 后全局 3rdloop 与本地一致(直引 Server/ 源码)
npm link
# ② 校验 Server/ 源码引入的外部依赖都在 package.json 声明
# 后端新增第三方库时会在这一步暴露,然后 npm install <新依赖> 补上
npm run verify-deps
# ③ 回归冒烟
npm test
# ④ 确认当前用的引擎来源(vendor 缺失时显示源码回退)
3rdloop doctor
发布期(打包给他人):临时生成 vendor + 自动清理
发布 tarball 必须自包含引擎(npm files 只能打包包内文件),所以发布时才把
Server/ 快照复制进 cli/vendor/,打包完成后自动删除本地副本:
cd cli
npm version patch # 0.1.0 → 0.1.1
npm publish # prepack 自动复制 vendor → 打包 → postpack 自动清理
npm pack / npm publish 的全自动流程:
| 阶段 | 钩子 | 动作 |
|---|---|---|
| 打包前 | prepack |
复制 Server/ → cli/vendor/Server/,写 VERSION,扫描敏感文件 |
| 打包中 | — | tarball 包含完整 vendor(自包含引擎) |
| 打包后 | postpack |
删除本地 cli/vendor/,工作区回归仅一份源码 |
不要手工改动
cli/vendor/Server/—— 它是发布期临时生成物,不入库 (.gitignore已忽略),下次npm pack/publish会重新生成并自动清理。npm run verify-deps同样双模式:有 vendor 扫 vendor,否则回退扫Server/源码。
开发者
cd cli
npm install
npm link # 直引仓库 Server/ 源码,无需 prepack
node bin/3rdloop.mjs doctor
发布前检查:npm run verify-deps(有 vendor 扫 vendor,否则回退扫 Server/ 源码)
校验引擎代码的依赖声明完整性。