# cli **Repository Path**: unitedrhino/cli ## Basic Information - **Project Name**: cli - **Description**: 联犀内部 cli工具,提供ai skills使用 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 2 - **Created**: 2026-05-11 - **Last Updated**: 2026-09-16 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # ur CLI [![Go Version](https://img.shields.io/badge/go-%3E%3D1.23-blue.svg)](https://go.dev/) 联犀 SaaS + IoT 平台命令行工具 — **为 AI Agent 原生设计**,让人类和 AI Agent 都能在终端中操作联犀平台。统一单一入口 `ur`,通过 `--app` 参数切换应用上下文,覆盖平台管理、物联网、组织管理、能源管理等核心业务域,提供 AI Agent [Skills](./skill/)。 [安装](#安装与快速开始) · [Agent Skills](#agent-skills) · [认证](#认证) · [命令](#命令参考) · [进阶用法](#进阶用法) > **仓库说明**:本项目已从 monorepo(`backend/cli/ur`)迁移为独立仓库。 > - 独立仓库地址:`https://gitee.com/unitedrhino/cli` / `https://github.com/unitedrhino/cli` > - 原 monorepo 中的 `backend/cli/ur` 已废弃,不再维护 --- ## 为什么选 ur CLI? - **为 Agent 原生设计** — `generate-skills` 一键生成结构化 Skill 文档,AI Agent 无需额外适配即可调用联犀 API - **统一入口** — 单个 `ur` 二进制,通过 `--app` 参数或 `UR_APP` 环境变量切换 5 大应用域 - **AI 友好认证** — 先复用 Sandbox 环境或历史 profile,必要时再选择 Device Flow、账号密码或 AK/SK - **全覆盖** — 平台管理、物联网、组织管理、能源管理、控制台 5 大应用域,Swagger 全量 API 自动解析 - **跨平台** — 支持 Linux/macOS/Windows 等主流平台(amd64 / arm64) - **安全可控** — Sandbox 凭据不落盘,敏感值支持环境变量或 stdin,输出默认脱敏 --- ## 功能 | 应用 | `--app` 值 | 覆盖域 | 典型能力 | |------|-----------|--------|---------| | 平台管理 | `platform-manage` | 企业、用户、应用、角色、权限 | 企业 CRUD、用户管理、应用配置、授权分配 | | 物联网 | `iot` | 设备、产品、项目、场景、OTA | 设备管理、物模型、项目场景、OTA 升级、协议网关 | | 组织管理 | `org-manage` | 组织用户、AI 智能体 | 企业内用户/角色/Agent 管理 | | 能源管理 | `org-energy` | 能耗分析、电力集抄、预付费 | 用能概况、实时监控、预付费充值 | | 控制台 | `console` | 个人信息、访问令牌 | 个人资料、访问令牌管理 | --- ## Agent Skills 安装 CLI 后,运行 `generate-skills` 生成 AI Agent 可用的 Skill 文档: ```bash # 为物联网应用生成 Skills ur --app iot generate-skills --output ./skills/ur-iot ``` 生成的 Skill 可直接被 AI Agent 加载,实现零配置调用联犀 API。 | Skill | 说明 | |-------|------| | `ur-api` | 通用 API 调用指南、认证方式、角色权限说明(所有 Skill 的基础) | | `ur-device` | 设备管理 — 设备 CRUD、属性控制、设备分享、物模型 | | `ur-device-analytics` | 设备数据分析 — 属性历史查询、趋势分析、聚合统计、报表生成(物模型驱动) | | `ur-device-debug` | 设备调试 — 日志查询(属性/事件/命令/上下线/异常/诊断/SDK)、实时调试(属性控制/行为调用/事件发送) | | `ur-product` | 产品管理 — 产品定义、物模型、品类管理 | | `ur-project` | 项目管理 — 项目 CRUD、区域管理、场景编辑 | | `ur-system` | 系统管理 — 用户管理、角色权限、菜单资源、字典配置 | | `ur-tenant` | 企业管理 — 企业 CRUD、应用绑定、配额管理 | | `ur-user` | 用户管理 — 个人信息、企业成员、邀请码 | | `ur-ai` | AI 管理 — Agent 配置、告警管理 | | `scene-linkage` | 场景联动 — 规则模板生成与 JSON 校验(if/when/then) | | `thing-model` | 物模型 — 模板生成、JSON 校验、affordance 定义 | | `protocol-script` | 协议脚本 — yaegi 脚本模板、Go 代码校验 | ### Skills 多客户端分发 CLI 使用同一份 `ur-api` 为所有 AI 客户端提供三种分发方式:已知客户端自动探测、任意本机目录登记,以及标准 ZIP 导出。自动探测当前覆盖 Claude Code、Codex 和 WorkBuddy / CodeBuddy;没有固定本机目录的平台可直接导入 ZIP。 ```bash # 查看自动发现与已登记目标 ur skills target detect ur skills target list # 登记任意支持本地 SKILL.md 的客户端目录 ur skills target add workbuddy --dir ~/.codebuddy/skills ur skills target add another-ai --dir /path/to/client/skills # 部署并检查所有目标;重复部署会原子覆盖旧 ur-api,保留其他技能 ur skills install --all ur skills status # 导出标准 ZIP,供扣子等支持技能包上传的平台导入 ur skills export ur skills export --output ~/Downloads # 下载最新 release 的 skills 包并解压(适合离线或由 AI 自行复制) ur skills download ur skills download --output ~/skills-pkg ur skills download --url "https://example.com/ur-api-skills-v0.4.1.zip" # JSON 输出(AI 解析 localPath 后自行拷贝) ur skills download --json ``` `--json` 输出示例: ```json {"event":"skills_downloaded","downloadUrl":"https://github.com/unitedrhino/cli/releases/download/v0.4.1/ur-api-skills-v0.4.1.zip","localPath":"/home/user/.ur/downloads/ur-api","installHint":"请将上述 ur-api 目录整体拷贝到你所用 AI 工具的 skills 目录下(各 AI 工具的 skills 目录由 AI 自行确认,例如 Claude Code 为 ~/.claude/skills/),拷贝后重启 AI 工具生效"} ``` 目标配置保存在 `~/.ur/skill-targets.json`。自动化环境也可用系统路径分隔符设置多个目录:`UR_SKILLS_DIRS=/path/a:/path/b`。WorkBuddy / CodeBuddy 的自定义配置目录通过 `CODEBUDDY_CONFIG_DIR` 自动识别。 项目级目标取决于命令执行位置:CLI 会从当前工作目录向上查找 Git 仓库根,并识别其中已经存在的 `.claude/skills`、`.agents/skills`、`.codebuddy/skills`。运行 `install --all` 前先用 `ur skills target detect` 核对目标;如果只想写入明确目录,使用 `ur skills install --dir <目录>`,该次不会写入其他自动识别或已登记目标。 --- ## 安装与快速开始 ### 环境要求 - **操作系统**:Linux / macOS / Windows 等 - **Go**:1.23+(仅从源码构建时需要) - **网络**:可访问联犀 SaaS API 服务器 ### 快速开始(人类用户) > **AI Assistant 注意**:如果你是 AI Agent 且正在协助用户执行安装,请直接跳转到[快速开始(AI Agent)](#快速开始ai-agent)。 #### 安装 CLI **方式一 — 下载预编译二进制(推荐):** ```bash # 1. 确定平台(注意使用 release 资产中的友好平台名) PLATFORM="Linux-x86_64" # Linux-x86_64 / Linux-aarch64 / macOS-x86_64 / macOS-arm64 / Windows-x86_64 VERSION="v0.4.1" # 2. 下载 wget "https://github.com/unitedrhino/cli/releases/download/${VERSION}/ur-cli-${VERSION}-${PLATFORM}.tar.gz" # 3. 解压完整发布包(包内结构为 -/{ur, skill/}) # ur 二进制必须与 skill/ 目录保持同级,否则 ur skills 相关命令找不到内置 skills mkdir -p ~/.local/lib/ur tar -xzf "ur-cli-${VERSION}-${PLATFORM}.tar.gz" -C ~/.local/lib/ur --strip-components=1 # 4. 把 ur 暴露到 PATH(软链不影响 skill/ 的查找) mkdir -p ~/.local/bin && ln -sf ~/.local/lib/ur/ur ~/.local/bin/ur # Windows: 下载 .zip 包并完整解压,保持 ur.exe 与 skill/ 目录同级, # 再将 ur.exe 所在目录加入系统 PATH ``` **方式二 — 从源码构建:** ```bash git clone https://github.com/unitedrhino/cli.git cd cli go build -ldflags "-X main.version=$(git describe --tags)" -o dist/bin/ur . ``` #### 版本升级与 Skills ```bash # 检查是否有新版本,不安装 ur upgrade --check --json # 升级到最新版本,同时刷新内置 Skills 及自动发现、已登记客户端中的副本 ur upgrade # 即使已是最新版也重新安装;适合恢复缺失的发布资源 ur upgrade --force # 仅升级 CLI,不写入客户端 Skills 目录 ur upgrade --no-skills # 手动把内置 ur-api skill 部署到本机各 AI 工具的 skills 目录 # (ur-api 是一个统一 skill,整体部署,不拆分;部署后重启对应 AI 会话即可发现) ur skills install ur skills install --dry-run # 预览目标,不实际写入 ur skills install --json # JSON 输出 ur skills install --dir # 指定自定义目标目录(支持 ~ 路径展开) ur skills target add --dir # 长期登记任意客户端目录 ur skills status # 核对版本和文件完整性 ur skills export # 导出标准 ZIP 到 ~/.ur/exports/ # 仅下载 skills 包到本地(不部署):AI 自助下载后自行拷贝到所用 AI 工具的 skills 目录, # 对所有 AI 工具通用;详见「Agent Skills」章节 ur skills download ur skills download --output ~/skills-pkg # 指定下载目录(支持 ~ 路径展开) ur skills download --url # 直接指定 skills zip 地址(私有化/离线场景) # 完全跳过自动版本检查 export UR_NO_UPDATE_CHECK=1 # 保留缓存刷新,仅隐藏 CLI 或 Skills 提示 export UR_NO_UPDATE_NOTIFIER=1 export UR_NO_SKILLS_NOTIFIER=1 ``` 业务命令启动时会先读取 `~/.ur/update-state.json`,因此短命令也能稳定返回已缓存的升级信息;缓存超过 24 小时后再异步刷新 Gitee/GitHub Release。显式 JSON 输出会在原对象顶层增加 `_notice.update` 或 `_notice.skills`,已有 `code`、`msg`、`data` 字段保持不变: ```json { "code": 200, "data": {}, "_notice": { "update": { "current": "v0.6.1", "latest": "v0.6.2", "command": "ur upgrade" } } } ``` AI 应先完成当前请求,再根据 `_notice` 简短说明升级;不要把提示原样当作业务结果。`ur upgrade --install-skills` 作为兼容参数继续可用,但从 v0.6.2 起 `ur upgrade` 默认已经同步客户端 Skills。 #### 配置与使用 ```bash # 1. 先检查现有环境或历史 profile;成功时无需重新登录 ur check --json # 仅在缺少认证时,选择一种登录方式(默认 device) ur login --method device # UR_PASSWORD='<原始密码>' ur login --method password --account '<账号>' --tenant-code '<企业编码>' --json # UR_ACCESS_SECRET='' ur login --method aksk --access-key '' --tenant-code '<企业编码>' --json # 2. 验证认证状态 ur check # 3. 开始使用(默认 org-manage 应用上下文) ur api /api/v1/system/user/self/get-one # 4. 切换应用上下文调用 IoT API ur --app iot api /api/v1/things/device/info/get-list \ --body '{"page":{"page":1,"size":10}}' # 5. 生成 AI Agent Skills(可选,推荐) ur generate-skills --output ./my-skills/ ``` --- ### 快速开始(AI Agent) > AI Agent 应先复用 Sandbox 环境或历史 profile;只有缺少认证时才启动新的登录流程。不要在对话中回显敏感值。 **一键安装 + 认证(AI 自动执行)** ```bash # 1. 下载对应平台的 release(AI 根据用户系统自动选择 PLATFORM) VERSION="v0.4.1" PLATFORM="Linux-x86_64" # Linux-x86_64 / Linux-aarch64 / macOS-x86_64 / macOS-arm64 / Windows-x86_64 # Linux / macOS:解压完整发布包(包内为 -/{ur, skill/}), # 保持 ur 二进制与 skill/ 目录同级,再把 ur 暴露到 PATH curl -L "https://github.com/unitedrhino/cli/releases/download/${VERSION}/ur-cli-${VERSION}-${PLATFORM}.tar.gz" -o /tmp/ur-cli.tar.gz mkdir -p ~/.local/lib/ur && tar -xzf /tmp/ur-cli.tar.gz -C ~/.local/lib/ur --strip-components=1 mkdir -p ~/.local/bin && ln -sf ~/.local/lib/ur/ur ~/.local/bin/ur # Windows (PowerShell):完整解压 .zip 包,保持 ur.exe 与 skill/ 同级,再把所在目录加入 PATH # Invoke-WebRequest -Uri "https://github.com/unitedrhino/cli/releases/download/${VERSION}/ur-cli-${VERSION}-${PLATFORM}.zip" -OutFile "ur.zip"; Expand-Archive "ur.zip" -DestinationPath "$env:USERPROFILE\.local\lib\ur" # 2. 先检查 Sandbox 环境或历史 profile ur check --json # 仅当 check 返回缺少认证时,才启动默认 Device Flow ur login --method device --no-wait --json ``` 输出示例: ```json { "status": "authorization_required", "verification_url": "https://saas.unitedrhino.com/#/user/settings?tab=access-tokens&setup=ABC123&redirect=thirdparty", "setup_code": "ABC123", "expires_in": 600 } ``` AI 解析 JSON,向用户发送: > 请在浏览器中打开链接完成 CLI 授权:https://saas.unitedrhino.com/#/user/settings?tab=access-tokens&setup=ABC123&redirect=thirdparty 用户确认在浏览器中点击「完成第三方客户端绑定」后,AI 自动执行: ```bash ur login --method device --setup-code ABC123 --json ``` 输出示例: ```json { "event": "authorization_complete", "status": "ok", "method": "device", "tenant_code": "t1", "access_key": "ak_xxxx" } ``` 如果 Sandbox 已注入账号密码或 AK/SK,可直接使用非交互方式;密码必须是原始密码,AK/SK 不要求 `userID`: ```bash UR_PASSWORD='<原始密码>' ur login --method password \ --account '<账号>' --tenant-code '<企业编码>' --json UR_ACCESS_SECRET='' ur login --method aksk \ --access-key '' --tenant-code '<企业编码>' --json ``` **验证并生成 Skills** ```bash ur check --json ur generate-skills --output ./skills/ ``` --- ## 认证 ur CLI 支持三种登录方式,并兼容 Sandbox 环境变量与旧 profile: | 命令/方式 | 说明 | |-----------|------| | `check --json` | 首先验证当前环境/profile,并输出脱敏的 `auth_source`、`auth_method` | | `login --method device` | Device Flow;未指定 `--method` 时的默认方式 | | `login --method password` | 原始账号密码立即换取 Session Token | | `login --method aksk` | AK/SK 立即验证并保存;不要求 `userID` | | `setup` | 人类终端的账号密码兼容向导 | | `token --decode` | 查看并解码当前存储的访问令牌 | ```bash # 总是先复用现有认证 ur check --json # Agent 模式:分步授权 ur login --method device --no-wait --json # 第 1 步:获取 URL 和绑定码 ur login --method device --setup-code ABC123 # 第 2 步:用户确认后完成轮询 # 账号密码(推荐环境变量或 --password-stdin;不要预先 SHA-256) UR_PASSWORD='<原始密码>' ur login --method password \ --account '<账号>' --tenant-code '<企业编码>' --json # AK/SK(推荐环境变量或 --access-secret-stdin) UR_ACCESS_SECRET='' ur login --method aksk \ --access-key '' --tenant-code '<企业编码>' --json # 验证 ur check --json # 查看当前 token ur token --decode ``` --- ## 命令参考 ### 全局选项 ```bash ur --version # 查看 CLI 版本 ur --app iot # 切换应用上下文(iot / platform-manage / org-manage / org-energy / console) UR_APP=iot ur # 通过环境变量切换 ``` ### API 调用 ```bash # 基本调用 ur api /api/v1/things/device/info/get-list --body '{"page":{"page":1,"size":10}}' # 输出格式控制 ur api ... --format yaml # json(默认)/ raw / yaml ur api ... --transform data.list.0.name # GJSON 路径提取 ur api ... --output result.json # 保存到文件 ur api ... --debug # HTTP 请求/响应详情(敏感头脱敏) ur api ... --fields code,data.total # 字段筛选 ur api ... --summarize # 摘要模式(列表只保留前 5 条) # 自定义请求头 ur api ... -H "X-Custom-Header: value" # 从文件读取 body ur api ... --body-file /tmp/payload.json ``` ### 物模型命令 ```bash ur model template property --json # 生成属性模板 ur model template event --yaml # 生成事件模板 ur model template action --json # 生成行为模板 ur model template full --yaml # 生成完整物模型模板 ur model validate /tmp/model.json # 校验物模型 JSON ur model generate-script model.json --mode property --output script.go ``` ### 场景联动命令 ```bash ur scene template auto # 自动触发场景模板 ur scene template manual # 手动触发场景模板 ur scene validate /tmp/scene.json # 校验场景联动 JSON ``` ### 协议脚本命令 ```bash ur script template up-before # 上行前处理模板 ur script template up-after # 上行后处理模板 ur script template down-before # 下行前处理模板 ur script template down-after # 下行后处理模板 ur script validate /tmp/script.go # 校验协议脚本 ``` ### Schema 与补全 ```bash ur schema # 查看 API schema ur schema --json # JSON 格式输出 ur schema --auth-type admin # 按权限过滤 ur schema /api/v1/things/device/info/create # 查看指定接口 ur completion bash >> ~/.bashrc # bash 补全 ur completion zsh >> ~/.zshrc # zsh 补全 ur completion fish > ~/.config/fish/completions/ur.fish ``` ### 配置管理 ```bash ur setup # 人类终端账号密码兼容向导 ur config --list # 列出所有配置 ur config --use prod # 切换配置 ur check --json # 验证配置、认证来源和连通性 ``` --- ## 进阶用法 ### 应用上下文切换 ```bash # 方式一:--app 参数 ur --app iot api /api/v1/things/device/info/get-list ur --app platform-manage api /api/v1/system/tenant/info/get-list # 方式二:UR_APP 环境变量 UR_APP=iot ur api /api/v1/things/device/info/get-list # 方式三:Sandbox env-only(使用占位符,不读取磁盘 profile 补值) UR_BASE_URL='<平台地址>' UR_APP_ID='<应用ID>' \ UR_TENANT_CODE='<企业编码>' UR_TOKEN='' ur check --json ``` ### 生成 Skills ```bash # 为当前应用生成所有 Skill 文档 ur --app iot generate-skills # 输出到指定目录 ur generate-skills --output ./my-skills/ ``` 生成的 Skill 文档可直接用于 AI Agent 调用联犀 API。 ### 运行时环境变量 无需配置文件,直接通过环境变量认证。设置 `UR_BASE_URL` 后进入 env-only 模式,不读取或改写磁盘 profile;认证组必须完整: ```bash export UR_BASE_URL='<平台地址>' export UR_APP_ID='<应用ID>' export UR_TENANT_CODE='<企业编码>' # 以下三组任选一组,优先级为 Token → AK/SK →账号密码 export UR_TOKEN='' # export UR_ACCESS_KEY='' UR_ACCESS_SECRET='' # export UR_ACCOUNT='<账号>' UR_PASSWORD='<原始密码>' ur check --json ur api /api/v1/things/device/info/get-list ``` AK/SK 模式的 `UR_USER_ID` 可选。旧 `~/.ur/config.json` 中只有账号密码,或同时遗留 Token、AK/SK 的配置会自动兼容;升级时无需迁移、清空或重新执行 `setup`。 --- ## 目录结构 ``` . ├── main.go # CLI 入口 ├── cmd/ │ ├── shared/ # 共享命令逻辑(api / check / schema / login / setup / completion / model / scene / script / generate-skills) │ └── ur/ # 统一入口(--app 参数解析) ├── internal/ │ ├── config/ # CLIApp 类型 + Profile 配置 │ ├── auth/ # Device Flow 认证逻辑 + Token 自动刷新 │ ├── client/ # HTTP 客户端(自动重试 + Debug 日志) │ ├── response/ # 输出格式化(json / raw / yaml + GJSON 提取) │ └── swagger/ # Swagger 解析 ├── skill/ # 预生成的 Skill 文档(供 AI Agent 使用) ├── shell/ │ ├── push.sh # 推送当前分支到 origin + gitee │ ├── pushm.sh # 强制推送当前分支到两个远程 │ └── tag.sh # 打标签并推送到两个远程 ├── scripts/ │ ├── release.sh # 跨平台 Release 构建与发布(封装脚本) │ ├── generate-api-lists.py # 从 swagger 自动生成 skill API 端点列表 │ └── update-skills.sh # 一键更新 skill 并同步到 skills 仓库 ├── skill/ # 预生成的 Skill 文档(供 AI Agent 使用) ├── SKILL_MAINTENANCE.md # Skill 混合维护模式文档(手写骨架 + 自动生成端点) └── references/ # 参考文档 ``` --- ## 开发 ```bash # 运行测试 go test ./... # 单独测试某个包 go test ./internal/auth/... # 查看测试覆盖率 go test -cover ./... ``` --- ## 发布(维护者) ### 前置条件 需要 GitHub 和 Gitee 的 API token,写入项目根目录的 `.env` 文件(已被 `.gitignore` 忽略,不会提交): ```bash # .env 文件内容 GITHUB_TOKEN="ghp_xxxxxxxx" # GitHub Personal Access Token(需要 repo 权限) GITEE_TOKEN="xxxxxxxx" # Gitee 私人令牌 # 可选:设为 all 时尝试向 Gitee 上传全平台资产;默认 common GITEE_RELEASE_ASSET_MODE="common" ``` `release.sh` 启动时会自动加载 `.env`,无需手动 export。 ### 一键发布 ```bash # 语法:bash scripts/release.sh <版本号> bash scripts/release.sh v0.3.7 ``` 脚本会自动完成: 1. 构建 39 个平台的二进制(Linux/macOS/Windows/FreeBSD/OpenBSD/NetBSD/Plan9/Solaris/Illumos/DragonFly/AIX × amd64/arm64/386/arm/mips/riscv64 等) 2. 复制 skill 资源到每个平台的发布目录,写入版本元数据 `_meta.json` 3. 打包 tar.gz(Unix)或 zip(Windows) 4. 生成 SHA256 校验和文件 `sha256sums.txt` 5. 创建 GitHub Release 并上传所有资产 6. 创建 Gitee Release,默认上传校验文件、Skills 包和 Linux x86_64 常用包;完整跨平台资产由 GitHub Release 提供 上传使用超时和 HTTP 状态检查,任一资产失败都会明确报错。认证信息通过文件描述符或标准输入传给 `curl`,不会出现在进程参数中。 ### 手动发布(仅某个平台) 如果只需要发布单个平台,可手动运行对应步骤: ```bash # 临时设置 token export GITHUB_TOKEN="ghp_xxxxxxxx" export GITEE_TOKEN="xxxxxxxx" # 仅构建和发布 bash scripts/release.sh v0.3.7 ``` --- ## 常见问题 ### Q: 升级后原账号密码配置还能使用吗? A: 可以。先运行 `ur check --json`;CLI 会复用历史 profile,Token 过期时用保存的原始账号密码刷新,不要求重新执行 `setup`。 ### Q: Sandbox 设置了环境变量但认证不可用? A: 设置 `UR_BASE_URL` 后不会从 profile 补值。请同时注入 `UR_APP_ID`、`UR_TENANT_CODE`,以及 Token、完整 AK/SK、完整账号密码三组之一。 ### Q: API 返回「权限不足」? A: 使用 `--auth-type` 参数切换权限类型,例如 `--auth-type admin`。 ### Q: 如何切换应用上下文? A: 使用 `--app` 参数:`ur --app iot api ...`,或通过 `UR_APP` 环境变量设置。 ### Q: Token 过期了怎么办? A: 历史 profile 有账号密码时 CLI 会自动刷新;否则按现有凭据选择 `ur login --method device|password|aksk`。