@blynkai/cli 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +295 -0
- package/package.json +23 -0
- package/src/cli/auth-login.mjs +44 -0
- package/src/cli/help.mjs +53 -0
- package/src/cli/index.mjs +554 -0
- package/src/cli/search-options.mjs +283 -0
- package/src/core/config.mjs +65 -0
- package/src/core/errors.mjs +25 -0
- package/src/core/response.mjs +30 -0
- package/src/core/runtime-paths.mjs +6 -0
- package/src/core/session-store.mjs +144 -0
- package/src/data/commands.mjs +37 -0
- package/src/search/normalize-payload.mjs +201 -0
- package/src/server/index.mjs +308 -0
package/README.md
ADDED
|
@@ -0,0 +1,295 @@
|
|
|
1
|
+
# 灵睿本地助手雏形
|
|
2
|
+
|
|
3
|
+
这是灵睿本地助手的第一版雏形,用于验证:
|
|
4
|
+
|
|
5
|
+
- 本地 `127.0.0.1` 服务是否可用
|
|
6
|
+
- 浏览器授权后,CLI/API 是否可用
|
|
7
|
+
- CLI 退出登录后,CLI/API 是否立即失效
|
|
8
|
+
|
|
9
|
+
## 启动本地服务
|
|
10
|
+
|
|
11
|
+
开发环境需要手动启动本地服务:
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
node local-agent/src/server/index.mjs
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
或在完成 CLI 链接后启动:
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
blynkai agent start
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
后台启动日志默认写入:
|
|
24
|
+
|
|
25
|
+
```text
|
|
26
|
+
~/.lingrui-local-agent/agent.log
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
进程号默认写入:
|
|
30
|
+
|
|
31
|
+
```text
|
|
32
|
+
~/.lingrui-local-agent/agent.pid
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
服务默认监听:
|
|
36
|
+
|
|
37
|
+
```text
|
|
38
|
+
http://127.0.0.1:38100
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## 后端地址配置
|
|
42
|
+
|
|
43
|
+
本地助手转发业务接口时读取环境变量,不在业务代码里写死后端地址:
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
LINGRUI_UPSTREAM_BASE_URL=https://api.blynkai.com
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
优先级:
|
|
50
|
+
|
|
51
|
+
1. `LINGRUI_UPSTREAM_BASE_URL`
|
|
52
|
+
2. `VITE_API_BASE_URL`
|
|
53
|
+
3. 项目根目录 `.env.local` / `.env.production.local` / `.env.production` / `.env.test` 中的 `VITE_API_BASE_URL`
|
|
54
|
+
|
|
55
|
+
本地开发可以直接复用 Vite proxy 当前使用的正式环境地址,也就是 `.env.production` 里的:
|
|
56
|
+
|
|
57
|
+
```text
|
|
58
|
+
VITE_API_BASE_URL=https://api.blynkai.com
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
如果要临时切换测试环境,可这样启动:
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
LINGRUI_UPSTREAM_BASE_URL=https://app.test.blynkai.com node local-agent/src/server/index.mjs
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## CLI 授权地址配置
|
|
68
|
+
|
|
69
|
+
`blynkai login` 不再内置固定域名,必须通过环境变量指定授权页地址:
|
|
70
|
+
|
|
71
|
+
1. `LINGRUI_CLI_AUTHORIZE_URL`(完整授权地址,优先级最高)
|
|
72
|
+
2. `LINGRUI_WEB_BASE_URL`(自动拼接 `${LINGRUI_WEB_BASE_URL}/cli/authorize`)
|
|
73
|
+
|
|
74
|
+
示例:
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
LINGRUI_WEB_BASE_URL=https://fushan.blynkai.com blynkai login
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## TLS / 企业证书配置
|
|
81
|
+
|
|
82
|
+
如果用户网络有企业 HTTPS 代理,Node 可能报:
|
|
83
|
+
|
|
84
|
+
- `UNABLE_TO_GET_ISSUER_CERT_LOCALLY`
|
|
85
|
+
- `unable to get local issuer certificate`
|
|
86
|
+
|
|
87
|
+
建议通过 `NODE_EXTRA_CA_CERTS` 注入企业根证书(PEM 文件):
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
NODE_EXTRA_CA_CERTS=/path/to/corp-root.pem \
|
|
91
|
+
LINGRUI_UPSTREAM_BASE_URL=https://api.blynkai.com \
|
|
92
|
+
node local-agent/src/cli/index.mjs agent start
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
诊断命令:
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
blynkai doctor
|
|
99
|
+
# 或
|
|
100
|
+
node local-agent/src/cli/index.mjs doctor
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
## CLI 使用
|
|
104
|
+
|
|
105
|
+
开发环境先把本地 CLI 链接成 `blynkai` 命令:
|
|
106
|
+
|
|
107
|
+
```bash
|
|
108
|
+
cd local-agent
|
|
109
|
+
npm link
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
然后即可执行:
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
blynkai agent start
|
|
116
|
+
blynkai agent status
|
|
117
|
+
blynkai health
|
|
118
|
+
blynkai doctor
|
|
119
|
+
blynkai whoami
|
|
120
|
+
blynkai list
|
|
121
|
+
blynkai search q=ai time_s=2026-05-19T00:00:00 time_e=2026-05-20T00:00:00 risk=high,very_high field=title,content dry_run=true
|
|
122
|
+
blynkai search center=warning q=public_opinion time_s=2026-05-19T00:00:00 time_e=2026-05-20T00:00:00 read=unread dry_run=true
|
|
123
|
+
blynkai search center=data stats=website q=ai site=weibo,xinhua dry_run=true
|
|
124
|
+
blynkai auth logout
|
|
125
|
+
blynkai ask "我现在登录了吗"
|
|
126
|
+
blynkai ask "调用技能"
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
如果暂时不 link,也可以直接使用 Node 执行:
|
|
130
|
+
|
|
131
|
+
```bash
|
|
132
|
+
node local-agent/src/cli/index.mjs health
|
|
133
|
+
node local-agent/src/cli/index.mjs agent start
|
|
134
|
+
node local-agent/src/cli/index.mjs agent status
|
|
135
|
+
node local-agent/src/cli/index.mjs doctor
|
|
136
|
+
node local-agent/src/cli/index.mjs whoami
|
|
137
|
+
node local-agent/src/cli/index.mjs list
|
|
138
|
+
node local-agent/src/cli/index.mjs search q=ai time_s=2026-05-19T00:00:00 time_e=2026-05-20T00:00:00 dry_run=true
|
|
139
|
+
node local-agent/src/cli/index.mjs auth logout
|
|
140
|
+
node local-agent/src/cli/index.mjs ask "我现在登录了吗"
|
|
141
|
+
node local-agent/src/cli/index.mjs ask "调用技能"
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
退出登录后,再执行:
|
|
145
|
+
|
|
146
|
+
```bash
|
|
147
|
+
blynkai whoami
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
会返回 `session_revoked`。
|
|
151
|
+
|
|
152
|
+
## 开发态演示链路
|
|
153
|
+
|
|
154
|
+
1. 启动本地服务:`node local-agent/src/server/index.mjs` 或 `blynkai agent start`
|
|
155
|
+
2. 启动前端:`pnpm run dev`
|
|
156
|
+
3. 打开灵睿页面并登录
|
|
157
|
+
4. 本地服务收到前端同步的登录态
|
|
158
|
+
5. 执行:`blynkai ask "我现在登录了吗"`
|
|
159
|
+
6. 执行:`blynkai list`
|
|
160
|
+
7. 执行:`blynkai ask "调用技能"`
|
|
161
|
+
8. 网页退出登录后,再执行 CLI 会返回 `session_revoked`
|
|
162
|
+
|
|
163
|
+
## 正式客户态链路
|
|
164
|
+
|
|
165
|
+
正式版本不依赖 `npm link`,需要安装包完成:
|
|
166
|
+
|
|
167
|
+
- 启动本地 `127.0.0.1` 服务
|
|
168
|
+
- 注册 `blynkai` 到系统 PATH
|
|
169
|
+
- 设置登录后或开机自启动
|
|
170
|
+
- 由前端在登录成功后自动同步登录态,退出登录时自动撤销本地会话
|
|
171
|
+
- 安装包内置 Node 运行时与生产依赖,不要求客户机器安装 Node/npm
|
|
172
|
+
|
|
173
|
+
浏览器不能静默安装或启动本地程序,因此客户首次使用时需要安装一次“灵睿本地助手”。
|
|
174
|
+
|
|
175
|
+
## 生成 macOS 应用包
|
|
176
|
+
|
|
177
|
+
开发机需要有 macOS 自带的 `hdiutil`。
|
|
178
|
+
|
|
179
|
+
```bash
|
|
180
|
+
pnpm --dir local-agent run package:mac
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
生成产物:
|
|
184
|
+
|
|
185
|
+
```text
|
|
186
|
+
dist-local-agent/macos-build/Lingrui Assistant.app
|
|
187
|
+
dist-local-agent/macos/lingrui-assistant-macos.zip
|
|
188
|
+
public/downloads/lingrui-local-agent/latest/macos.zip
|
|
189
|
+
public/downloads/lingrui-cli/latest/lingrui-assistant-macos.zip (兼容旧链接)
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
本地验证:
|
|
193
|
+
|
|
194
|
+
```bash
|
|
195
|
+
open "dist-local-agent/macos-build/Lingrui Assistant.app"
|
|
196
|
+
blynkai help
|
|
197
|
+
blynkai status
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
当前 macOS 包会下载一个应用,双击后直接拉起 Terminal,在终端内完成本地 CLI 安装。
|
|
201
|
+
|
|
202
|
+
## 当前接口
|
|
203
|
+
|
|
204
|
+
- `GET /health`
|
|
205
|
+
- `POST /auth/sync`
|
|
206
|
+
- `GET /auth/whoami`
|
|
207
|
+
- `POST /auth/logout`
|
|
208
|
+
- `POST /auth/reconnect`
|
|
209
|
+
- `GET /commands/list`
|
|
210
|
+
- `POST /api/search`
|
|
211
|
+
- `POST /skills/check`
|
|
212
|
+
|
|
213
|
+
## 统一搜索 CLI
|
|
214
|
+
|
|
215
|
+
统一入口:
|
|
216
|
+
|
|
217
|
+
```bash
|
|
218
|
+
blynkai search [query]
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
本地 API:
|
|
222
|
+
|
|
223
|
+
```text
|
|
224
|
+
POST /api/search
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
场景映射:
|
|
228
|
+
|
|
229
|
+
- `center=data` -> `/v1/article/search`
|
|
230
|
+
- `center=warning` -> `/v1/index`
|
|
231
|
+
- `stats=website` -> `/v1/article/website`
|
|
232
|
+
|
|
233
|
+
推荐使用英文短参数 `key=value`:
|
|
234
|
+
|
|
235
|
+
```text
|
|
236
|
+
q=ai
|
|
237
|
+
center=data
|
|
238
|
+
stats=website
|
|
239
|
+
time_s=2026-05-19T00:00:00
|
|
240
|
+
time_e=2026-05-20T00:00:00
|
|
241
|
+
risk=high,very_high
|
|
242
|
+
sentiment=negative
|
|
243
|
+
field=title,content
|
|
244
|
+
type=original,repost,comment
|
|
245
|
+
site=weibo,xinhua
|
|
246
|
+
category=tech,finance
|
|
247
|
+
source=renmin,isite
|
|
248
|
+
read=unread
|
|
249
|
+
valid=yes
|
|
250
|
+
page=1
|
|
251
|
+
size=10
|
|
252
|
+
sort=publish_time
|
|
253
|
+
order=desc
|
|
254
|
+
dry_run=true
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
说明:
|
|
258
|
+
|
|
259
|
+
- 不传时间时,本地助手默认补近 24 小时。
|
|
260
|
+
- `center=data` 默认使用发布时间,默认 `is_valid=Valid`。
|
|
261
|
+
- `center=warning` 默认使用预警推送时间,默认 `review_status=pushed`。
|
|
262
|
+
- 关键词搜索时默认 `sort_field=_score`;无关键词时数据中心默认 `publish_time`,预警中心默认 `push_time`。
|
|
263
|
+
- `site=...` 是检索筛选参数,对应 `website_names`;`stats=website` 才表示返回媒体渠道统计。
|
|
264
|
+
- 旧写法 `search data`、`search warning`、`search website` 暂时兼容,但产品口径统一推荐 `blynkai search center=... stats=...`。
|
|
265
|
+
- 仍兼容 `--publish-start`、`--risk-levels` 等完整选项,便于开发和自动化脚本使用。
|
|
266
|
+
- 未配置上游地址时,`/api/search` 会返回映射后的 `upstream_path` 和 `payload`,方便联调参数。
|
|
267
|
+
- 配置 `LINGRUI_UPSTREAM_BASE_URL` 或 `VITE_API_BASE_URL` 且 CLI token 有效时,本地助手会真实转发到线上接口。
|
|
268
|
+
|
|
269
|
+
## 响应协议
|
|
270
|
+
|
|
271
|
+
成功:
|
|
272
|
+
|
|
273
|
+
```json
|
|
274
|
+
{
|
|
275
|
+
"code": 0,
|
|
276
|
+
"msg": "ok",
|
|
277
|
+
"data": {
|
|
278
|
+
"status": "online"
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
失败:
|
|
284
|
+
|
|
285
|
+
```json
|
|
286
|
+
{
|
|
287
|
+
"code": 40010,
|
|
288
|
+
"msg": "auth_required",
|
|
289
|
+
"hint": "Please sign in to Lingrui in your browser first."
|
|
290
|
+
}
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
## 说明
|
|
294
|
+
|
|
295
|
+
当前版本只做本地助手基础链路,不包含安装包、业务接口和真实技能执行。
|
package/package.json
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@blynkai/cli",
|
|
3
|
+
"version": "0.1.1",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"files": [
|
|
6
|
+
"README.md",
|
|
7
|
+
"src"
|
|
8
|
+
],
|
|
9
|
+
"bin": {
|
|
10
|
+
"blynkai": "./src/cli/index.mjs"
|
|
11
|
+
},
|
|
12
|
+
"scripts": {
|
|
13
|
+
"server": "node src/server/index.mjs",
|
|
14
|
+
"cli": "node src/cli/index.mjs",
|
|
15
|
+
"health": "node src/cli/index.mjs health",
|
|
16
|
+
"whoami": "node src/cli/index.mjs whoami",
|
|
17
|
+
"package:mac": "node scripts/build-macos-pkg.mjs",
|
|
18
|
+
"bundle:web": "node scripts/build-web-bundle.mjs"
|
|
19
|
+
},
|
|
20
|
+
"engines": {
|
|
21
|
+
"node": ">=18"
|
|
22
|
+
}
|
|
23
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { spawn } from 'node:child_process'
|
|
2
|
+
import { platform } from 'node:os'
|
|
3
|
+
|
|
4
|
+
function resolveAuthorizeUrl() {
|
|
5
|
+
const explicitAuthorizeUrl = process.env.LINGRUI_CLI_AUTHORIZE_URL?.trim()
|
|
6
|
+
if (explicitAuthorizeUrl) return explicitAuthorizeUrl
|
|
7
|
+
|
|
8
|
+
const webBaseUrl = process.env.LINGRUI_WEB_BASE_URL?.trim()
|
|
9
|
+
if (webBaseUrl) return `${webBaseUrl.replace(/\/+$/, '')}/cli/authorize`
|
|
10
|
+
|
|
11
|
+
return ''
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function openBrowser(url) {
|
|
15
|
+
const currentPlatform = platform()
|
|
16
|
+
if (currentPlatform === 'darwin') return spawn('open', [url], { detached: true, stdio: 'ignore' })
|
|
17
|
+
if (currentPlatform === 'win32') {
|
|
18
|
+
return spawn('cmd', ['/c', 'start', '', url], { detached: true, stdio: 'ignore' })
|
|
19
|
+
}
|
|
20
|
+
return spawn('xdg-open', [url], { detached: true, stdio: 'ignore' })
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export async function runBrowserLogin() {
|
|
24
|
+
const authorizeUrl = resolveAuthorizeUrl()
|
|
25
|
+
if (!authorizeUrl) {
|
|
26
|
+
console.log('\n❌ 未配置授权地址。')
|
|
27
|
+
console.log('请先设置 LINGRUI_WEB_BASE_URL 或 LINGRUI_CLI_AUTHORIZE_URL。')
|
|
28
|
+
console.log('示例:LINGRUI_WEB_BASE_URL=https://fushan.blynkai.com blynkai login\n')
|
|
29
|
+
return
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const url = new URL(authorizeUrl)
|
|
33
|
+
|
|
34
|
+
console.log('\n请在浏览器完成灵睿 CLI 授权。')
|
|
35
|
+
console.log(`授权地址:${url.toString()}`)
|
|
36
|
+
console.log('如果浏览器已经登录灵睿系统,授权页会把当前登录态同步给本地助手。\n')
|
|
37
|
+
|
|
38
|
+
try {
|
|
39
|
+
const child = openBrowser(url.toString())
|
|
40
|
+
child.unref()
|
|
41
|
+
} catch {
|
|
42
|
+
// 用户仍可手动复制授权地址。
|
|
43
|
+
}
|
|
44
|
+
}
|
package/src/cli/help.mjs
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
export function printHelp() {
|
|
2
|
+
console.log(`
|
|
3
|
+
==========================================
|
|
4
|
+
灵睿助手 CLI (命令行工具)
|
|
5
|
+
==========================================
|
|
6
|
+
|
|
7
|
+
用法:
|
|
8
|
+
blynkai help # 查看帮助信息
|
|
9
|
+
blynkai login # 在浏览器中完成 CLI 授权
|
|
10
|
+
blynkai status # 查看本地助手的运行状态
|
|
11
|
+
blynkai doctor # 一键诊断本地服务、登录态、上游连通性与 TLS
|
|
12
|
+
blynkai whoami # 查看当前登录的用户信息
|
|
13
|
+
blynkai logout # 退出当前登录
|
|
14
|
+
blynkai search # 统一检索,默认查数据中心近 24 小时
|
|
15
|
+
|
|
16
|
+
常用示例:
|
|
17
|
+
blynkai login
|
|
18
|
+
blynkai whoami
|
|
19
|
+
blynkai doctor
|
|
20
|
+
blynkai search q=ai
|
|
21
|
+
blynkai search center=data q=ai time_s=2026-05-19T00:00:00 time_e=2026-05-20T00:00:00
|
|
22
|
+
blynkai search center=warning q=public_opinion time_s=2026-05-19T00:00:00 time_e=2026-05-20T00:00:00 read=unread
|
|
23
|
+
blynkai search center=data stats=website q=ai risk=high,very_high site=weibo,xinhua dry_run=true
|
|
24
|
+
|
|
25
|
+
常用查询参数:
|
|
26
|
+
center=data 检索中心:data 或 warning;默认 data
|
|
27
|
+
stats=website 返回媒体渠道统计;不传则返回文章/预警列表
|
|
28
|
+
q=ai 关键词,对应 keywords
|
|
29
|
+
time_s=2026-05-19T00:00:00 时间开始;data 映射发布时间,warning 映射预警时间
|
|
30
|
+
time_e=2026-05-20T00:00:00 时间结束;data 映射发布时间,warning 映射预警时间
|
|
31
|
+
risk=high,very_high 风险等级:normal,low,medium,high,very_high
|
|
32
|
+
sentiment=negative 情感:positive,neutral,negative
|
|
33
|
+
field=title,content 命中位置:title,content,author,ocr,asr
|
|
34
|
+
type=original,repost,comment 内容类型
|
|
35
|
+
site=weibo,xinhua 具体媒体渠道
|
|
36
|
+
category=tech,finance 文章分类
|
|
37
|
+
source=renmin,isite 数据来源
|
|
38
|
+
read=unread 阅读状态:read,unread,all
|
|
39
|
+
valid=yes 是否相关:yes,no,uncertain,all
|
|
40
|
+
page=1 size=10 分页
|
|
41
|
+
sort=publish_time order=desc 排序
|
|
42
|
+
dry_run=true 只查看将要请求的参数,不真正查询线上接口
|
|
43
|
+
|
|
44
|
+
高级参数:
|
|
45
|
+
仍兼容 --publish-start、--push-start、--risk-levels、--search-fields 等完整选项。
|
|
46
|
+
|
|
47
|
+
提示:
|
|
48
|
+
1. 您无需在终端输入账号密码;请运行 blynkai login,并在浏览器中完成 CLI 授权。
|
|
49
|
+
2. search 只有一个入口,数据中心、预警中心、媒体渠道统计复用同一套筛选参数。
|
|
50
|
+
3. 推荐使用 key=value 形式;没有 key= 的普通文本会自动作为关键词。
|
|
51
|
+
==========================================
|
|
52
|
+
`)
|
|
53
|
+
}
|