con un clic
cli
LobeHub CLI (@lobehub/cli) development guide — commands, subcommands, architecture.
Menú
LobeHub CLI (@lobehub/cli) development guide — commands, subcommands, architecture.
LobeHub Drizzle ORM schema and query style. Use for pgTable schemas, indexes, joins, inferred types, db.select/db.query, schema fields, foreign keys, junction tables, or postgres query patterns.
LobeHub code review checklist. Use when reviewing a PR, diff, or branch for console leftovers, return await, secrets, i18n, desktop router drift, UI imports, migrations, or cloud impact.
Vitest testing guide. Use when writing or updating tests, fixing failing tests, improving coverage, debugging test issues, or setting up mocks.
Add server-side environment variables that control default values for user settings.
Agent runtime lifecycle hooks. Use for before/after tool or step hooks, tool mocks, human intervention, sub-agent calls, context compression, evals, tracing, callAgent, or lifecycle events.
Build or extend LobeHub Agent Signal pipelines. Use for signal sources, signal/action types, policies, middleware, workflow handoff, dedupe, scope behavior, or observability.
| name | cli |
| description | LobeHub CLI (@lobehub/cli) development guide — commands, subcommands, architecture. |
| disable-model-invocation | true |
LobeHub CLI (@lobehub/cli) is a command-line tool for managing and interacting with LobeHub services. Built with Commander.js + TypeScript.
apps/cli/apps/cli/src/index.tslh, lobe, lobehub (all aliases for the same CLI)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
| Command | Alias | Description |
|---|---|---|
lh login | - | Authenticate via OIDC Device Code Flow |
lh logout | - | Clear stored credentials |
lh connect | - | Device gateway connection & daemon management |
lh status | - | Quick gateway connectivity check |
lh agent | - | Agent CRUD, run, status |
lh generate | gen | Content generation (text, image, video, tts, asr, download) |
lh doc | - | Document CRUD, batch-create, parse, topic linking |
lh file | - | File list, view, delete, recent |
lh kb | - | Knowledge base CRUD, folders, docs, upload, tree view |
lh memory | - | User memory CRUD + extraction |
lh message | - | Message list, search, delete, count, heatmap |
lh topic | - | Topic CRUD + search + recent |
lh skill | - | Skill CRUD + import (GitHub/URL/market) |
lh model | - | Model CRUD, toggle, batch-toggle, clear |
lh provider | - | Provider CRUD, config, test, toggle |
lh plugin | - | Plugin install, uninstall, update |
lh search | - | Global search across all types |
lh whoami | - | Current user info |
lh usage | - | Monthly/daily usage statistics |
Create 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
});
}
In apps/cli/src/index.ts:
import { registerNewCommand } from './commands/new';
// ...
registerNewCommand(program);
Create apps/cli/src/commands/<name>.test.ts alongside the command file.
All list/view commands follow consistent patterns:
--json [fields] - JSON output with optional field filtering--yes - Skip confirmation for destructive ops-L, --limit <n> - Pagination limit (default: 30)-v, --verbose - Verbose loggingconst rows = items.map((item) => [item.id, truncate(item.title, 40), timeAgo(item.updatedAt)]);
printTable(rows, ['ID', 'TITLE', 'UPDATED']);
if (options.json !== undefined) {
const fields = typeof options.json === 'string' ? options.json : undefined;
outputJson(items, fields);
return;
}
Commands that need auth use getTrpcClient() which auto-resolves tokens:
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;
}
| File | Path | Purpose |
|---|---|---|
| Credentials | ~/.lobehub/credentials.json | Encrypted tokens (AES-256-GCM) |
| Settings | ~/.lobehub/settings.json | Custom server/gateway URLs |
| Daemon PID | ~/.lobehub/daemon.pid | Background process PID |
| Daemon Status | ~/.lobehub/daemon.status | Connection status JSON |
| Daemon Log | ~/.lobehub/daemon.log | Daemon output log |
The base directory (~/.lobehub/) can be overridden with the LOBEHUB_CLI_HOME env var (e.g. LOBEHUB_CLI_HOME=.lobehub-dev for dev mode isolation).
commander - CLI framework@trpc/client + superjson - Type-safe API client@lobechat/device-gateway-client - WebSocket gateway connection@lobechat/local-file-shell - Local shell/file tool executionpicocolors - Terminal colorsws - WebSocketdiff - Text diffingfast-glob - File pattern matchingDev mode uses LOBEHUB_CLI_HOME=.lobehub-dev to isolate credentials from the global ~/.lobehub/ directory, so dev and production configs never conflict.
# Run a command in dev mode (from apps/cli/)
cd apps/cli && bun run dev -- <command>
# This is equivalent to:
LOBEHUB_CLI_HOME=.lobehub-dev bun src/index.ts <command>
To test CLI against a local dev server (e.g. localhost:3011):
Step 1: Start the local server
# From cloud repo root
bun run dev
# Server starts on http://localhost:3011 (or configured port)
Step 2: Login to local server via Device Code Flow
cd apps/cli && bun run dev -- login --server http://localhost:3011
This will:
POST http://localhost:3011/oidc/device/auth to get a device codehttp://localhost:3011/oidc/device?user_code=XXXX-YYYYapps/cli/.lobehub-dev/credentials.jsonapps/cli/.lobehub-dev/settings.jsonAfter login, all subsequent bun run dev -- <command> calls will use the local server.
Step 3: Run commands against local server
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
Troubleshooting:
invalid_grant, make sure the local OIDC provider is properly configured (check OIDC_* env vars in .env)UNAUTHORIZED on API calls, your token may have expired — run bun run dev -- login --server http://localhost:3011 againapps/cli/.lobehub-dev/ (gitignored), not in ~/.lobehub/# Dev mode (local server) — uses .lobehub-dev/
cd apps/cli && bun run dev -- <command>
# Production (app.lobehub.com) — uses ~/.lobehub/
lh <command>
The two environments are completely isolated by different credential directories.
# Build CLI
cd apps/cli && bun run build
# Unit tests
cd apps/cli && bun run test
# E2E tests (requires authenticated CLI)
cd apps/cli && bunx vitest run e2e/kb.e2e.test.ts
# Link globally for testing (installs lh/lobe/lobehub commands)
cd apps/cli && bun run cli:link
See references/ for each command group:
references/agent.md (CRUD, run, status)references/generate.md (text, image, video, tts, asr, download)references/knowledge.md (kb, file, doc)references/conversation.md (topic, message)references/memory.md (memory management, extraction)references/skills-plugins.md (skill, plugin)references/models-providers.md (model, provider)references/search-config.md (search, whoami, usage)