首页
/ LobeHub CLI 开发指南:命令体系、架构剖析与本地开发实战(@lobehub/cli)

LobeHub CLI 开发指南:命令体系、架构剖析与本地开发实战(@lobehub/cli)

2026-09-04 18:01:37作者:宗隆裙

本文基于 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.jsonSKILL.md):

项目 说明
包路径 apps/cli/
包名 @lobehub/cli(当前版本 0.0.52
入口 apps/cli/src/index.ts
可执行命令 lhlobelobehub(三者是同一 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 与 gatewaydaemon/manager.ts 管理后台守护进程;tools/shell.tstools/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):statusdownload 需要的是 asyncTaskId(UUID 格式),而不是生成 ID(gen_xxx)。asyncTaskIdimage / 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 轮询,入参必须同时提供 generationIdasyncTaskId(后者是 async_tasks 表中的 UUID),查询前会调用 checkTimeoutTasks 把 pending/processing 超过约 5 分钟(ASYNC_TASK_TIMEOUT = 298s)的任务标记为 error。文档同时指出服务端路由位于 apps/server/src/routers/lambda/image/index.tsapps/server/src/routers/lambda/video/index.tsapps/server/src/routers/lambda/generation.ts,异步任务模型在 packages/database/src/models/asyncTask.ts;且 image/video 路由不走 keyVaults 中间件,而是通过 initModelRuntimeFromDBcreateAsyncCaller 从数据库读取 API key。

3.3 知识库、文件与文档(lh kb / lh file / lh doc

参考 references/knowledge.md,源码分别为 apps/cli/src/commands/kb.tsfile.tsdoc.ts

知识库(lh kb:支持目录树结构(文件夹、文档、文件上传),面向 RAG 场景。

  • lh kb list [--json [fields]]:列 ID、NAME、DESCRIPTION、UPDATED。
  • lh kb view <id>:递归拉取完整目录树(file.getKnowledgeItems,文件夹 custom/folderPromise.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 filelh 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 doclh 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 数组批量创建,每项可含 titlecontentfileTypeknowledgeBaseIdparentIdslug);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 topictopic.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 messagemessage.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 skillskill.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 pluginplugin.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.getAiProviderModelListAiInfraRepos.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|--disabledelete <id> --provider <providerId> [--yes]clear --provider <providerId> [--remote] [--yes]--remote 表示只清空远端拉取的模型)。

lh providerprovider.ts):list(列 ID/NAME/ENABLED/SOURCE)、view <id>create --id <id> -n <name> [-s <source>] [-d <desc>] [--logo <url>] [--sdk-type <sdkType>](source 取 builtincustom,默认 custom)、edit <id>(至少一个变更项)、toggle <id> --enable|--disabledelete <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.tse2e/ 目录作为既有实践参照)。

输出与交互约定

所有 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.tsauth/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.mdapps/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:* 方式引入),以及 dayjsdebugtinyexectree-kill 等工具库;man 字段声明了 man/man1/lh.1lobe.1lobehub.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

登录流程会:

  1. 调用 POST http://localhost:3011/oidc/device/auth 获取 device code;
  2. 打印形如 http://localhost:3011/oidc/device?user_code=XXXX-YYYY 的 URL;
  3. 在浏览器打开该 URL,登录并授权;
  4. 凭据写入 apps/cli/.lobehub-dev/credentials.json
  5. 服务器地址写入 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 执行 tsdowntest 使用 vitest(配置见 apps/cli/vitest.config.mts);cli:linkbun link,会把三个 bin 名称链接到全局,便于直接以 lh 验证行为。

八、小结

LobeHub CLI 以 Commander 为骨架、tRPC 类型安全客户端为血液,把平台的 Agent、生成、知识库、记忆、技能、模型等能力完整映射到终端;其工程约定(--json [fields]--yes-L 分页、~/.lobehub/ 存储、LOBEHUB_CLI_HOME 环境隔离)保证了命令行为的一致性与可脚本化。开发新命令时只需遵循“命令文件 + 入口注册 + 同目录测试”三步,并复用 getTrpcClient()utils/format 中的输出工具,即可快速扩展出符合项目风格的新命令组。

登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.12 K
2.72 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
527
590
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
904
1.82 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
854
1.34 K
docsdocs
暂无描述
Markdown
889
5.78 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.52 K
1.01 K
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.33 K
1.45 K
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
982
502
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
540
384