feat(cli): replace serve/web commands with unified start command

- Add `chatlab start` with --headless (API-only) and --no-open flags
- Remove redundant `serve` and `web` commands
- Update fetch adapter comments to reference chatlab start
- Add chatlab start usage examples to quick-start docs (cn/en/tw)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
diguaandClaude Sonnet 4.6 committed 2026-05-30 14:19:42 +08:00
1 parent 8e01121b7a
commit 6cdc040ce8
6 files changed
+51 -69

No files matched your search

+18 -66
View File
@@ -5,7 +5,6 @@
*/
import * as fs from 'fs'
import * as path from 'path'
import { execSync } from 'child_process'
import { Command } from 'commander'
import { DEFAULT_API_PORT, loadConfig, getConfigPath } from '@openchatlab/config'
@@ -280,23 +279,24 @@ program
})
program
.command('serve')
.description('Start the HTTP API server')
.command('start')
.description('Start ChatLab (HTTP API + Web UI)')
.option('--port <port>', 'Server port', String(DEFAULT_API_PORT))
.option('--host <host>', 'Listen address', '127.0.0.1')
.option('--token <token>', 'Custom Bearer Token (reads from config or auto-generates if omitted)')
.option('--web [dir]', 'Serve Web frontend static assets (defaults to dist-web/)')
.option('--headless', 'API-only mode, do not serve the Web UI')
.option('--no-open', 'Do not auto-open the browser')
.action(async (options) => {
const { startHttpServer } = await import('./http')
const port = parseInt(options.port, 10)
let webRoot: string | undefined
if (options.web !== undefined) {
const webDir = typeof options.web === 'string' ? options.web : resolveCliPath('dist-web')
if (!options.headless) {
const webDir = resolveCliPath('dist-web')
if (fs.existsSync(webDir)) {
webRoot = path.resolve(webDir)
webRoot = webDir
} else {
console.warn(`Warning: Web directory not found: ${webDir}, starting in API-only mode`)
console.warn('Warning: dist-web/ not found, starting in API-only mode')
}
}
@@ -311,70 +311,21 @@ program
const { startPeriodicUpdateCheck } = await import('./update-checker')
startPeriodicUpdateCheck()
console.log(`\nChatLab HTTP API started`)
console.log(` Address: http://${info.host}:${info.port}`)
console.log(` Token: ${info.token}`)
if (webRoot) {
console.log(` Web UI: http://${info.host}:${info.port}/`)
}
console.log(`\nExample:`)
console.log(` curl -H "Authorization: Bearer ${info.token}" http://${info.host}:${info.port}/api/v1/status`)
console.log(`\nPress Ctrl+C to stop.\n`)
const shutdown = async () => {
console.log('\nShutting down...')
const { stopHttpServer } = await import('./http')
await stopHttpServer()
process.exit(0)
}
process.on('SIGINT', shutdown)
process.on('SIGTERM', shutdown)
} catch (err: unknown) {
const message = err instanceof Error ? err.message : String(err)
if (message.includes('EADDRINUSE')) {
console.error(`Error: port ${port} is already in use`)
} else {
console.error(`Startup failed: ${message}`)
}
process.exit(1)
}
})
program
.command('web')
.description('Launch Web UI with one click (HTTP API + browser auto-open)')
.option('--port <port>', 'Server port', String(DEFAULT_API_PORT))
.option('--host <host>', 'Listen address', '127.0.0.1')
.option('--no-open', 'Do not auto-open browser')
.action(async (options) => {
const { startHttpServer } = await import('./http')
const port = parseInt(options.port, 10)
const webDir = resolveCliPath('dist-web')
let webRoot: string | undefined
if (fs.existsSync(webDir)) {
webRoot = webDir
} else {
console.warn('Warning: dist-web/ not found, Web UI will not be available (API-only mode)')
}
try {
const info = await startHttpServer({ port, host: options.host, webRoot })
const { startPeriodicUpdateCheck } = await import('./update-checker')
startPeriodicUpdateCheck()
const url = `http://${info.host === '0.0.0.0' ? '127.0.0.1' : info.host}:${info.port}`
const displayHost = info.host === '0.0.0.0' ? '127.0.0.1' : info.host
const url = `http://${displayHost}:${info.port}`
console.log(`\nChatLab v${getVersion()}`)
console.log(` Web UI: ${url}`)
if (webRoot) console.log(` Web UI: ${url}/`)
console.log(` API: ${url}`)
console.log(` Token: ${info.token}`)
console.log(`\nExample:`)
console.log(` curl -H "Authorization: Bearer ${info.token}" ${url}/api/v1/status`)
if (options.open && webRoot) {
if (webRoot && options.open) {
openBrowser(url)
console.log(`\nBrowser opened. Press Ctrl+C to stop.`)
console.log(`\nBrowser opened. Press Ctrl+C to stop.\n`)
} else {
console.log(`\nPress Ctrl+C to stop.`)
console.log(`\nPress Ctrl+C to stop.\n`)
}
const shutdown = async () => {
@@ -383,6 +334,7 @@ program
await stopHttpServer()
process.exit(0)
}
process.on('SIGINT', shutdown)
process.on('SIGTERM', shutdown)
} catch (err: unknown) {
+10
View File
@@ -20,6 +20,16 @@ npm i chatlab-cli -g
需要 Node.js ≥ 20。CLI 适合服务端部署或搭配 AI Agent(如 Claude Desktop)使用。
安装后运行以下命令启动 ChatLab:
```bash
chatlab start # 启动 API + Web UI,并在浏览器中打开
chatlab start --no-open # 启动但不自动打开浏览器(适合服务器环境)
chatlab start --headless # 仅启动 API,不挂载 Web UI(供脚本 / AI Agent 调用)
```
常用选项:`--port <端口>`(默认 3110)、`--host <地址>`、`--token <令牌>`。
## 第二步:导入聊天记录
ChatLab 提供三种导入方式,适用于不同场景:
+10
View File
@@ -20,6 +20,16 @@ npm i chatlab-cli -g
Requires Node.js ≥ 20. The CLI is suited for server-side deployments or pairing with an AI Agent (e.g., Claude Desktop).
After installation, start ChatLab with:
```bash
chatlab start # Start API + Web UI and open in browser
chatlab start --no-open # Start without auto-opening the browser (for server environments)
chatlab start --headless # API-only mode, no Web UI (for scripts / AI Agents)
```
Common options: `--port <port>` (default 3110), `--host <address>`, `--token <token>`.
## Step 2: Import chat records
ChatLab provides three import methods for different scenarios:
+10
View File
@@ -20,6 +20,16 @@ npm i chatlab-cli -g
需要 Node.js ≥ 20。CLI 適合伺服器部署或搭配 AI Agent(如 Claude Desktop)使用。
安裝完成後,執行以下指令啟動 ChatLab:
```bash
chatlab start # 啟動 API + Web UI,並在瀏覽器中開啟
chatlab start --no-open # 啟動但不自動開啟瀏覽器(適合伺服器環境)
chatlab start --headless # 僅啟動 API,不掛載 Web UI(供腳本 / AI Agent 呼叫)
```
常用選項:`--port <連接埠>`(預設 3110)、`--host <位址>`、`--token <令牌>`。
## 第二步:匯入聊天記錄
ChatLab 提供三種匯入方式,適用於不同場景:
+2 -2
View File
@@ -1,7 +1,7 @@
/**
* CLI serve Web 模式下的 AIAdapter 实现
* CLI Web 模式下的 AIAdapter 实现
*
* 通过 HTTP 调用 chatlab serve 后端的 /_web/ai/* 端点。
* 通过 HTTP 调用 chatlab start 后端的 /_web/ai/* 端点。
* 不支持 Web 模式的功能(文件导出等)返回安全的降级响应。
*/
+1 -1
View File
@@ -1,7 +1,7 @@
/**
* FetchDataAdapter — 通过 HTTP 调用 /_web/ 内部 API
*
* 用于 CLI serve Web 场景:前端通过 fetch 访问 chatlab serve 后端。
* 用于 CLI Web 场景:前端通过 fetch 访问 chatlab start 后端。
*/
import type { AnalysisSession, MessageType } from '@/types/base'