LobeHub CLI 开发指南:命令体系、架构剖析与本地开发实战(@lobehub/cli)
本文基于 LobeHub 仓库中的官方 CLI 技能文档(SKILL.md)及其配套命令参考,系统讲解 @lobehub/cli 的命令分组、目录架构、认证与存储机制,以及如何添加新命令、在本地开发服务器上进行联调的完整流程。读完本篇,你将掌握 lh 命令行工具的整体使用方式(agent、generate、kb、memory、skill 等命令组),并能按项目约定为 CLI 新增一个符合规范的新命令。
一、项目概览:LobeHub CLI 是什么
LobeHub CLI(包名 @lobehub/cli)是一个用于管理和操作 LobeHub 服务(Agent 运营平台)的命令行工具,使用 Commander.js + TypeScript 构建。其核心定位是:把 LobeHub 服务端通过 tRPC 暴露的能力(Agent 管理、内容生成、知识库、记忆、技能插件、模型供应商配置等)以终端命令的形式提供给开发者与自动化脚本。
关键事实(依据 apps/cli/package.json 与 SKILL.md):
| 项目 | 说明 |
|---|---|
| 包路径 | apps/cli/ |
| 包名 | @lobehub/cli(当前版本 0.0.52) |
| 入口 | apps/cli/src/index.ts |
| 可执行命令 | lh、lobe、lobehub(三者是同一 CLI 的别名) |
| 构建工具 | tsdown(build 脚本执行 tsdown) |
| 运行环境 | Node.js(engines 要求 node >= 22.15)/ Bun |
在 入口文件 中可以看到,CLI 启动时通过 createProgram() 创建 Commander 程序并调用 parseAsync(process.argv, { from: 'node' }) 解析参数;解析失败时统一经过 formatError 格式化、尝试 reportDaemonStartupError 上报后以退出码 1 结束。从源码结构看,index.ts 本身非常精简,命令的实际注册逻辑被抽到了 program.ts 中,便于测试与复用。
二、目录架构:一个命令一个文件
LobeHub CLI 的源码采用“按命令分组、每命令一文件”的组织方式,各目录职责如下(摘自 SKILL.md 的架构图):
apps/cli/src/
├── index.ts # Entry point, registers all commands
├── api/
│ ├── client.ts # tRPC client (type-safe backend API)
│ └── http.ts # Raw HTTP utilities
├── auth/
│ ├── credentials.ts # Encrypted credential storage (AES-256-GCM)
│ ├── refresh.ts # Token auto-refresh
│ └── resolveToken.ts # Token resolution (flag > stored)
├── commands/ # All CLI commands (one file per command group)
│ ├── agent.ts # Agent CRUD + run
│ ├── config.ts # whoami, usage
│ ├── connect.ts # Device gateway connection + daemon
│ ├── doc.ts # Document management
│ ├── file.ts # File management
│ ├── generate/ # Content generation (text/image/video/tts/asr)
│ ├── kb.ts # Knowledge base management
│ ├── login.ts # OIDC Device Code Flow auth
│ ├── logout.ts # Clear credentials
│ ├── memory.ts # User memory management
│ ├── message.ts # Message management
│ ├── model.ts # AI model management
│ ├── plugin.ts # Plugin management
│ ├── provider.ts # AI provider management
│ ├── search.ts # Global search
│ ├── skill.ts # Agent skill management
│ ├── status.ts # Gateway connectivity check
│ └── topic.ts # Conversation topic management
├── daemon/
│ └── manager.ts # Background daemon process management
├── tools/
│ ├── shell.ts # Shell command execution (for gateway)
│ └── file.ts # File operations (for gateway)
├── settings/
│ └── index.ts # Persistent settings (~/.lobehub/)
├── utils/
│ ├── logger.ts # Logging (verbose mode)
│ ├── format.ts # Table output, JSON, timeAgo, truncate
│ └── agentStream.ts # SSE streaming for agent runs
└── constants/
└── urls.ts # Official server & gateway URLs
几个值得注意的设计点:
- 类型安全的 API 层:
api/client.ts基于 tRPC client 访问后端,CLI 侧的调用在编译期即可校验请求/响应类型;api/http.ts则提供裸 HTTP 工具作为补充。 - 认证三件套:
auth/credentials.ts负责凭据的加密落盘(AES-256-GCM),auth/refresh.ts实现 Token 自动刷新,auth/resolveToken.ts实现“命令行 flag 优先于本地存储”的 Token 解析顺序。 - daemon 与 gateway:
daemon/manager.ts管理后台守护进程;tools/shell.ts与tools/file.ts是为设备网关(device gateway)提供的本地 Shell/文件工具执行能力,这与lh connect命令(设备网关连接 + daemon)相对应。
三、命令分组总览
CLI 对外暴露的命令组(摘自 SKILL.md 命令表):
| 命令 | 别名 | 说明 |
|---|---|---|
lh login |
- | 通过 OIDC Device Code Flow 认证 |
lh logout |
- | 清除已存储凭据 |
lh connect |
- | 设备网关连接与 daemon 管理 |
lh status |
- | 快速检测网关连通性 |
lh agent |
- | Agent 增删改查、运行、状态 |
lh generate |
gen |
内容生成(text/image/video/tts/asr/download) |
lh doc |
- | 文档 CRUD、批量创建、解析、topic 关联 |
lh file |
- | 文件列表、查看、删除、最近文件 |
lh kb |
- | 知识库 CRUD、文件夹、文档、上传、树视图 |
lh memory |
- | 用户记忆 CRUD + 提取 |
lh message |
- | 消息列表、搜索、删除、统计、热力图 |
lh topic |
- | Topic CRUD + 搜索 + 最近 |
lh skill |
- | 技能 CRUD + 安装(GitHub/URL/market) |
lh model |
- | 模型 CRUD、启停、批量启停、清空 |
lh provider |
- | 供应商 CRUD、配置、测试、启停 |
lh plugin |
- | 插件安装、卸载、更新 |
lh search |
- | 全类型全局搜索 |
lh whoami |
- | 当前用户信息 |
lh usage |
- | 月度/日度用量统计 |
以下各节按命令组给出关键子命令与参数说明(详细参考 references/agent.md 等参考文档)。
3.1 Agent 管理(lh agent,源码 apps/cli/src/commands/agent.ts)
lh agent list —— 列出所有 Agent:
lh agent list [-L <n>] [-k <keyword>] [--json [fields]]
| 选项 | 说明 | 默认值 |
|---|---|---|
-L, --limit <n> |
最大条目数 | 30 |
-k, --keyword <keyword> |
关键字过滤 | - |
--json [fields] |
JSON 输出,可选字段过滤 | - |
表格列:ID、TITLE、DESCRIPTION、MODEL。
lh agent view <agentId> —— 查看 Agent 配置详情(title、description、model、provider、system role、plugins、tools)。
lh agent create —— 创建 Agent,所有选项均为可选:
| 选项 | 说明 |
|---|---|
-t, --title <title> |
Agent 标题 |
-d, --description <desc> |
描述 |
-m, --model <model> |
模型 ID |
-p, --provider <provider> |
供应商 ID |
-s, --system-role <role> |
系统提示词 |
--group <groupId> |
Agent 分组 ID |
lh agent edit <agentId> —— 更新已有 Agent,选项同 create,仅更新指定字段。
lh agent delete <agentId> [--yes] —— 删除,未加 --yes 时需交互确认。
lh agent duplicate <agentId> [-t <title>] —— 复制 Agent,可指定新标题,输出新 Agent ID。
lh agent run —— 启动一次 Agent 运行(SSE 流式输出):
| 选项 | 说明 |
|---|---|
-a, --agent-id <id> |
要运行的 Agent ID |
-s, --slug <slug> |
用 slug 代替 ID |
-p, --prompt <text> |
用户提示词 |
-t, --topic-id <id> |
复用已有 topic |
--no-auto-start |
不自动启动 |
--json |
输出完整 JSON 事件流 |
-v, --verbose |
展示工具调用详情 |
--replay <file> |
从保存的 JSON 文件回放事件(离线调试) |
流式行为由 utils/agentStream.ts 处理:发送 run 请求后实时接收 SSE 事件,逐段显示文本、工具调用状态与操作进度,最后输出 token 用量与费用汇总。--replay <file> 则直接读取保存的 JSON 事件流,可在无服务器连接的情况下离线调试渲染逻辑。
lh agent status <operationId> —— 查看操作状态(running/completed/failed)、步骤数、token 用量、费用与错误信息;--history 附带步骤历史(--history-limit <n> 默认 10)。
3.2 内容生成(lh generate / lh gen,源码 apps/cli/src/commands/generate/)
lh generate (alias: gen)
├── text <prompt> # 文本生成
├── image <prompt> # 图片生成
├── video <prompt> # 视频生成
├── tts <text> # 文本转语音
├── asr <audioFile> # 语音转文本
├── download <generationId> <asyncTaskId> # 等待并下载生成结果
├── status <generationId> <asyncTaskId> # 查询异步任务状态
└── list # 列出生成 topic
注意(来自 references/generate.md):
status与download需要的是asyncTaskId(UUID 格式),而不是生成 ID(gen_xxx)。asyncTaskId在image/video命令输出中 “→ Task” 之后打印。
lh gen text <prompt>(generate/text.ts):
lh gen text "Explain quantum computing" [options]
echo "context" | lh gen text "summarize" --pipe
| 选项 | 说明 | 默认值 |
|---|---|---|
-m, --model <model> |
模型 ID | openai/gpt-4o-mini |
-p, --provider <provider> |
供应商名 | - |
-s, --system <prompt> |
系统提示词 | - |
--temperature <n> |
温度 (0-2) | - |
--max-tokens <n> |
最大输出 token | - |
--stream |
流式输出 | false |
--json |
输出完整 JSON | false |
--pipe |
从 stdin 读取附加上下文 | false |
Pipe 模式把 stdin 内容拼接到 prompt 之前,适合管道处理文件内容:cat README.md | lh gen text "summarize this" --pipe。
lh gen image <prompt>(generate/image.ts)—— 异步任务:提交后返回生成 ID + 异步任务 ID:
| 选项 | 说明 | 默认值 |
|---|---|---|
-m, --model <model> |
模型 ID | dall-e-3 |
-p, --provider <provider> |
供应商名 | openai |
-n, --num <n> |
图片数量 | 1 |
--width <px> / --height <px> |
宽高像素 | - |
--steps <n> |
采样步数 | - |
--seed <n> |
随机种子 | - |
--json |
输出原始 JSON | false |
非 JSON 输出示例:
✓ Image generation started
Batch ID: gb_xxx
1 image(s) queued
Generation gen_xxx → Task 7ad0eb13-xxxx-xxxx-xxxx-xxxxxxxxxxxx
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
这是 asyncTaskId — 用于 status/download
Use "lh generate status <generationId> <asyncTaskId>" to check progress.
典型工作流:
# 1. 提交生成 — 记下输出中的两个 ID
lh gen image "A cute cat"
# Generation gen_abc123 → Task 7ad0eb13-e9a5-4403-8070-1f7fe95b2f95
# 2. 用 generationId + asyncTaskId(UUID) 等待并下载
lh gen download gen_abc123 7ad0eb13-e9a5-4403-8070-1f7fe95b2f95 -o cat.png
lh gen video <prompt>(generate/video.ts)—— 异步任务,且与 image 不同,-m 和 -p 必填(无默认值);其他选项:--aspect-ratio(如 16:9)、--duration <sec>、--resolution(如 720p)、--seed、--json。可先用 lh model list <provider> --type video 找到可用的视频模型,例如:
lh model list volcengine --json | grep -i seedance
lh gen video "A cat on a runway" -m doubao-seedance-2-0-260128 -p volcengine \
--aspect-ratio 9:16 --duration 5 --resolution 1080p
lh gen download gen_abc123 7ad0eb13-e9a5-4403-8070-1f7fe95b2f95 -o result.mp4 --timeout 600
lh gen tts <text>(generate/tts.ts)与 lh gen asr <audioFile>(generate/asr.ts)分别对应文本转语音与语音识别。
lh gen download <generationId> <asyncTaskId>(generate/index.ts):
| 选项 | 说明 | 默认值 |
|---|---|---|
-o, --output <path> |
输出文件路径(自动推断扩展名) | <generationId>.<ext> |
--interval <sec> |
轮询间隔(秒) | 5 |
--timeout <sec> |
超时(秒,0 表示不限时) | 300 |
行为:按间隔轮询 generation.getGenerationStatus,实时显示 ⋯ Status: processing... (42s);成功后把资产 URL 下载到本地;ID 用错时给出指向正确 ID 格式的清晰报错;超时会提示改用 lh gen status 稍后查看。
lh gen status <generationId> <asyncTaskId> [--json] —— 彩色状态展示(success 绿 / error 红 / processing 黄 / pending 青)、错误信息与成功后的资产/缩略图 URL。`lh gen list [--json [fields]] —— 列出所有生成 topic(ID、TITLE、TYPE、UPDATED)。
后端架构(摘自参考文档):图片/视频生成采用异步任务模式——1) generationTopic.createTopic 建 topic;2) image.createImage / video.createVideo 在一个 DB 事务中创建 batch + generation + asyncTask 记录并触发后台任务(图片经 createAsyncCaller,视频经 initModelRuntimeFromDB),返回包含 asyncTaskId 的结果;3) generation.getGenerationStatus 轮询,入参必须同时提供 generationId 与 asyncTaskId(后者是 async_tasks 表中的 UUID),查询前会调用 checkTimeoutTasks 把 pending/processing 超过约 5 分钟(ASYNC_TASK_TIMEOUT = 298s)的任务标记为 error。文档同时指出服务端路由位于 apps/server/src/routers/lambda/image/index.ts、apps/server/src/routers/lambda/video/index.ts、apps/server/src/routers/lambda/generation.ts,异步任务模型在 packages/database/src/models/asyncTask.ts;且 image/video 路由不走 keyVaults 中间件,而是通过 initModelRuntimeFromDB 或 createAsyncCaller 从数据库读取 API key。
3.3 知识库、文件与文档(lh kb / lh file / lh doc)
参考 references/knowledge.md,源码分别为 apps/cli/src/commands/kb.ts、file.ts、doc.ts。
知识库(lh kb):支持目录树结构(文件夹、文档、文件上传),面向 RAG 场景。
lh kb list [--json [fields]]:列 ID、NAME、DESCRIPTION、UPDATED。lh kb view <id>:递归拉取完整目录树(file.getKnowledgeItems,文件夹custom/folder用Promise.all并行遍历),缩进展示每项类型(File/Doc)、文件类型与大小。lh kb create -n <name> [-d <desc>] [--avatar <url>]:创建,-n必填;后端直接返回字符串 ID。lh kb edit <id> [-n ... -d ... --avatar ...]:至少提供一个变更选项,否则报错。lh kb delete <id> [--remove-files] [--yes]:删除,可选连同关联文件一起删。lh kb add-files <kbId> --ids <fileId1> <fileId2> .../lh kb remove-files <kbId> --ids ... [--yes]:关联/解除文件。lh kb mkdir <kbId> -n <name> [--parent <folderId>]:建文件夹(内部用document.createDocument+fileType: 'custom/folder')。lh kb create-doc <kbId> -t <title> [-c <content>] [--parent <folderId>]:建文档(fileType: 'custom/document')。lh kb move <id> --type <file|doc> [--parent <folderId>]:移动文件/文档到目标文件夹(省略--parent即移到根目录);doc 走document.updateDocument,file 走file.updateFile。lh kb upload <kbId> <filePath> [--parent <folderId>]:本地文件上传,流程为计算 SHA-256 →upload.createS3PreSignedUrl获取预签名 URL → PUT 到 S3 →file.createFile建文件记录。
文件管理(lh file):lh file list [--kb-id <id>] [-L <n>](默认 30 条,列 ID/NAME/TYPE/SIZE/UPDATED)、lh file view <id>(含分块与 embedding 状态)、lh file delete <ids...> [--yes](支持批量)、lh file recent [-L <n>](默认 10 条)。
文档管理(lh doc):lh doc list [-L <n>] [--file-type <type>] [--source-type <type>](source-type 取值 file/web/api/topic);lh doc view <id>(含完整正文);lh doc create -t <title> [-b <body> | -F <body-file>] [--parent <id>] [--slug <slug>] [--kb <id>] [--file-type <type>](-b 与 -F 互斥);lh doc batch-create <file>(JSON 数组批量创建,每项可含 title、content、fileType、knowledgeBaseId、parentId、slug);lh doc edit <id>;lh doc delete <ids...>;lh doc parse <fileId> [--with-pages](把已上传文件解析为文档);lh doc link-topic <docId> <topicId> 与 lh doc topic-docs <topicId> [--type <type>](文档与 topic 双向关联/查询)。
3.4 会话与消息(lh topic / lh message)
参考 references/conversation.md。
lh topic(topic.ts):list [--agent-id <id>] [-L <n>] [--page <n>](默认 30/页,列 ID/TITLE/FAV/UPDATED)、search <keywords>、create -t <title> [--agent-id <id>] [--favorite]、edit <id> [-t <title>] [--favorite|--no-favorite]、delete <ids...> [--yes]、recent [-L <n>](默认 10 条)。
lh message(message.ts):
lh message list [--topic-id <id>] [--agent-id <id>] [-L <n>] [--page <n>] [--user]:提供 topic/agent 过滤时走message.getMessages,否则走message.listAll;列 ID/ROLE/CONTENT/CREATED。lh message search <keywords>:全量消息全文搜索。lh message delete <ids...> [--yes]。lh message count [--start <date>] [--end <date>] [--json]:指定区间的消息总数(日期为 ISO 格式)。lh message heatmap [--json]:按时间展示消息频率的热力图数据。
3.5 用户记忆(lh memory)
参考 references/memory.md,源码 apps/cli/src/commands/memory.ts。记忆分为五个类别:
| 类别 | 说明 |
|---|---|
identity |
用户名、角色、关系 |
activity |
近期活动与状态 |
context |
进行中的上下文、项目、目标 |
experience |
过往经验与关键学习 |
preference |
用户偏好、指令、建议 |
lh memory list [category] [--json [fields]]:按类别分组展示 type/status 与描述。lh memory create:--type、--role、--relationship、-d、--labels <labels...>。lh memory edit <category> <id>:按类别提供不同选项——identity:--type/--role/--relationship;activity:--narrative/--notes/--status;context:--title/--description/--status;experience:--situation/--action/--key-learning;preference:--directives/--suggestions。lh memory delete <category> <id> [--yes]。lh memory persona [--json [fields]]:展示由全部记忆类别编译出的用户画像摘要。lh memory extract [--from <date>] [--to <date>]:触发从聊天记录中提取记忆的异步后台任务;lh memory extract-status [--task-id <id>]查询任务状态。
3.6 技能与插件(lh skill / lh plugin)
参考 references/skills-plugins.md。
lh skill(skill.ts):list [--source <builtin|market|user>]、view <id>、create -n <name> -d <desc> -c <content> [-i <identifier>]、edit <id>、delete <id> [--yes]、search <query>、resources <id>(列出技能内文件)、read-resource <id> <path>。
lh skill install <source>(别名 lh skill i)会根据输入自动识别来源类型:
# GitHub(URL 或 owner/repo 简写)
lh skill install lobehub/skill-repo
lh skill install https://github.com/lobehub/skill-repo
lh skill install lobehub/skill-repo --branch dev
# ZIP URL
lh skill install https://example.com/skill.zip
# 市场标识符
lh skill install my-cool-skill
识别规则:https://github.com/... 或 owner/repo → GitHub;其他 https://... URL → ZIP;其余 → 市场标识符。--branch 仅对 GitHub 生效。
lh plugin(plugin.ts):list(列 ID/IDENTIFIER/TYPE/TITLE);install -i <identifier> --manifest <json> [--type <plugin|customPlugin>] [--settings <json>](-i 与 --manifest 必填);uninstall <id> [--yes];update <id> [--manifest <json>] [--settings <json>]。
3.7 模型与供应商(lh model / lh provider)
参考 references/models-providers.md。
lh model list <providerId>(model.ts):
lh model list openai
lh model list openai --type image --enabled
lh model list lobehub --type video --json
| 选项 | 说明 | 默认值 |
|---|---|---|
-L, --limit <n> |
最大条目数 | 50 |
--enabled |
仅显示已启用模型 | false |
--type <type> |
类型过滤(chat/embedding/tts/stt/image/video/text2music/realtime) | - |
--json [fields] |
JSON 输出 | - |
后端链路为 aiModel.getAiProviderModelList → AiInfraRepos.getAiProviderModelList,类型过滤下沉到仓储层实现。其余子命令:view <id>、create --id <id> --provider <providerId> [--display-name <name>] [--type <type>](type 默认 chat)、edit <id>、toggle <id> --provider <providerId> --enable|--disable(二选一必填)、batch-toggle <ids...> --provider <providerId> --enable|--disable、delete <id> --provider <providerId> [--yes]、clear --provider <providerId> [--remote] [--yes](--remote 表示只清空远端拉取的模型)。
lh provider(provider.ts):list(列 ID/NAME/ENABLED/SOURCE)、view <id>、create --id <id> -n <name> [-s <source>] [-d <desc>] [--logo <url>] [--sdk-type <sdkType>](source 取 builtin 或 custom,默认 custom)、edit <id>(至少一个变更项)、toggle <id> --enable|--disable、delete <id> [--yes]。
lh provider config <id> 用于配置供应商(API key、base URL 等):
lh provider config openai --api-key sk-xxx
lh provider config openai --base-url https://custom-endpoint.com
lh provider config openai --show
lh provider config openai --show --json
| 选项 | 说明 |
|---|---|
--api-key <key> |
设置 API key |
--base-url <url> |
设置 base URL |
--check-model <model> |
设置连通性检查模型 |
--enable-response-api / --disable-response-api |
启用/禁用 Response API 模式(OpenAI) |
--fetch-on-client / --no-fetch-on-client |
启用/禁用客户端拉取模型 |
--show |
显示当前配置 |
--json [fields] |
JSON 输出(配合 --show) |
注意:lobehub 供应商为平台托管,对其设置 --api-key 或 --base-url 会被拒绝并报错。lh provider test <id> [-m <model>] [--json] 用于测试连通性。
3.8 全局搜索与用户配置(lh search / lh whoami / lh usage)
参考 references/search-config.md。
lh search <query> [-t <type>] [-L <n>](search.ts):跨全部资源类型搜索,每种类型默认 10 条。可搜索类型:
| 类型 | 说明 |
|---|---|
agent |
AI 智能体 |
topic |
会话主题 |
file |
已上传文件 |
folder |
文件文件夹 |
message |
聊天消息 |
page |
文档/页面 |
memory |
用户记忆 |
mcp |
MCP 服务器 |
plugin |
已安装插件 |
communityAgent |
社区市场 Agent |
knowledgeBase |
知识库 |
lh whoami [--json [fields]](config.ts):显示当前用户姓名、用户名、邮箱、用户 ID 与订阅计划。**lh usage [--month <YYYY-MM>] [--daily] [--json [fields]]**:默认当前月,--daily` 按天分组,输出 token 用量、费用与按模型明细。
全局通用选项:
| 选项 | 说明 |
|---|---|
--json [fields] |
JSON 输出,可选按逗号分隔字段过滤 |
--yes |
跳过破坏性操作确认 |
-L, --limit <n> |
列表命令分页大小 |
-v, --verbose |
详细/调试日志 |
--help / --version |
帮助 / 版本 |
字段过滤示例:lh agent list --json 输出全量 JSON,lh agent list --json "id,title,model" 只输出指定字段。
四、如何新增一个命令
SKILL.md 给出了三步式流程:
第 1 步:创建命令文件 apps/cli/src/commands/<name>.ts:
import type { Command } from 'commander';
import { getTrpcClient } from '../api/client';
import { outputJson, printTable, truncate } from '../utils/format';
export function register<Name>Command(program: Command) {
const cmd = program.command('<name>').description('...');
// Subcommands
cmd
.command('list')
.description('List items')
.option('-L, --limit <n>', 'Maximum number of items', '30')
.option('--json [fields]', 'Output JSON, optionally specify fields')
.action(async (options) => {
const client = await getTrpcClient();
const result = await client.<router>.<procedure>.query({ ... });
// Handle output
});
}
第 2 步:在入口注册。在命令程序创建处(apps/cli/src/index.ts 引导、命令注册模块)导入并调用:
import { registerNewCommand } from './commands/new';
// ...
registerNewCommand(program);
第 3 步:添加测试。在命令文件旁创建 apps/cli/src/commands/<name>.test.ts(仓库中 apps/cli/src/ 下已有大量 .test.ts 与 e2e/ 目录作为既有实践参照)。
输出与交互约定
所有 list/view 类命令遵循统一模式:
--json [fields]:JSON 输出 + 可选字段过滤;--yes:破坏性操作跳过确认;-L, --limit <n>:分页上限(默认 30);-v, --verbose:详细日志。
表格输出:
const rows = items.map((item) => [item.id, truncate(item.title, 40), timeAgo(item.updatedAt)]);
printTable(rows, ['ID', 'TITLE', 'UPDATED']);
JSON 输出:
if (options.json !== undefined) {
const fields = typeof options.json === 'string' ? options.json : undefined;
outputJson(items, fields);
return;
}
认证:需要认证的命令统一使用 getTrpcClient(),它会按“flag 优先于本地存储”的顺序自动解析 Token 并附带自动刷新(对应 auth/resolveToken.ts、auth/refresh.ts):
const client = await getTrpcClient();
// client.router.procedure.query/mutate(...)
破坏性操作的确认提示:
import { confirm } from '../utils/format';
if (!options.yes) {
const ok = await confirm('Are you sure?');
if (!ok) return;
}
五、本地存储位置与环境隔离
CLI 的所有本地状态集中在 ~/.lobehub/ 目录下:
| 文件 | 路径 | 用途 |
|---|---|---|
| Credentials | ~/.lobehub/credentials.json |
加密 Token(AES-256-GCM) |
| Settings | ~/.lobehub/settings.json |
自定义 server/gateway URL |
| Daemon PID | ~/.lobehub/daemon.pid |
后台进程 PID |
| Daemon Status | ~/.lobehub/daemon.status |
连接状态 JSON |
| Daemon Log | ~/.lobehub/daemon.log |
daemon 输出日志 |
基础目录可用环境变量 LOBEHUB_CLI_HOME 覆盖。例如 LOBEHUB_CLI_HOME=.lobehub-dev 即把状态隔离到项目内的 .lobehub-dev/ 目录(已加入 gitignore),保证开发环境凭据与全局 ~/.lobehub/ 永不冲突。
六、关键依赖
依据 SKILL.md 与 apps/cli/package.json:
| 依赖 | 作用 |
|---|---|
commander |
CLI 框架 |
@trpc/client + superjson |
类型安全 API 客户端(superjson 处理 Date/Map 等类型序列化) |
@lobechat/device-gateway-client |
WebSocket 网关连接 |
@lobechat/local-file-shell |
本地 Shell/文件工具执行 |
picocolors |
终端着色 |
ws |
WebSocket |
diff |
文本 diff |
fast-glob |
文件模式匹配 |
此外,package.json 中还引用了多个 workspace 内部包(如 @lobechat/agent-gateway-client、@lobechat/device-control、@lobechat/heterogeneous-agents、@lobechat/tool-runtime 等,均以 workspace:* 方式引入),以及 dayjs、debug、tinyexec、tree-kill 等工具库;man 字段声明了 man/man1/lh.1、lobe.1、lobehub.1 三份 man 手册(由 man:generate 脚本生成)。
七、开发模式与本地联调实战
7.1 开发模式运行
dev 脚本的完整定义为(见 apps/cli/package.json):
"dev": "LOBEHUB_CLI_HOME=.lobehub-dev bun src/index.ts"
即在 apps/cli/ 下执行:
# 开发模式运行命令(凭据隔离到 .lobehub-dev/)
cd apps/cli && bun run dev -- <command>
# 等价于:
LOBEHUB_CLI_HOME=.lobehub-dev bun src/index.ts <command>
7.2 连接本地开发服务器
第 1 步:启动本地服务端
# 在 cloud 仓库根目录
bun run dev
# 服务启动于 http://localhost:3011(或配置的端口)
第 2 步:通过 Device Code Flow 登录本地服务器
cd apps/cli && bun run dev -- login --server http://localhost:3011
登录流程会:
- 调用
POST http://localhost:3011/oidc/device/auth获取 device code; - 打印形如
http://localhost:3011/oidc/device?user_code=XXXX-YYYY的 URL; - 在浏览器打开该 URL,登录并授权;
- 凭据写入
apps/cli/.lobehub-dev/credentials.json; - 服务器地址写入
apps/cli/.lobehub-dev/settings.json。
此后所有 bun run dev -- <command> 都会默认指向本地服务器。
第 3 步:对本地服务器执行命令
cd apps/cli && bun run dev -- task list
cd apps/cli && bun run dev -- task create -i "Test task" -n "My Task"
cd apps/cli && bun run dev -- agent list
故障排查:
- 登录返回
invalid_grant:检查本地 OIDC provider 是否配置正确(核对.env中的OIDC_*环境变量); - API 调用返回
UNAUTHORIZED:Token 可能已过期,重新执行bun run dev -- login --server http://localhost:3011; - 开发凭据存放在
apps/cli/.lobehub-dev/(gitignored),不会污染~/.lobehub/。
7.3 本地与生产环境切换
# 开发模式(本地服务器)— 使用 .lobehub-dev/
cd apps/cli && bun run dev -- <command>
# 生产环境(app.lobehub.com)— 使用 ~/.lobehub/
lh <command>
两套环境通过不同的凭据目录完全隔离,可以并行运行互不干扰。
7.4 构建与测试
# 构建 CLI
cd apps/cli && bun run build
# 单元测试
cd apps/cli && bun run test
# E2E 测试(需要已认证的 CLI)
cd apps/cli && bunx vitest run e2e/kb.e2e.test.ts
# 全局链接以便测试(安装 lh/lobe/lobehub 命令)
cd apps/cli && bun run cli:link
其中 build 执行 tsdown,test 使用 vitest(配置见 apps/cli/vitest.config.mts);cli:link 即 bun link,会把三个 bin 名称链接到全局,便于直接以 lh 验证行为。
八、小结
LobeHub CLI 以 Commander 为骨架、tRPC 类型安全客户端为血液,把平台的 Agent、生成、知识库、记忆、技能、模型等能力完整映射到终端;其工程约定(--json [fields]、--yes、-L 分页、~/.lobehub/ 存储、LOBEHUB_CLI_HOME 环境隔离)保证了命令行为的一致性与可脚本化。开发新命令时只需遵循“命令文件 + 入口注册 + 同目录测试”三步,并复用 getTrpcClient() 与 utils/format 中的输出工具,即可快速扩展出符合项目风格的新命令组。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0622
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00