sidekick-chat 0.2.2 → 0.2.4
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 +131 -128
- package/package.json +39 -38
- package/src/main.mjs +609 -578
- package/src/quota.mjs +98 -107
- package/src/tui.mjs +90 -92
package/README.md
CHANGED
|
@@ -1,128 +1,131 @@
|
|
|
1
|
-
# Sidekick 终端客户端
|
|
2
|
-
|
|
3
|
-
在终端里和秘书说话。它只是 `chat` World 的又一个客户端,和手机 App、网页版共用同一批会话、未读和回复,
|
|
4
|
-
不新增任何后端接口——所以手机上收到的、终端里发的,是同一份对话。
|
|
5
|
-
|
|
6
|
-
```
|
|
7
|
-
$ npx sidekick-chat
|
|
8
|
-
Sidekick · 秘书 https://hkv4.cznorth.cn/chat
|
|
9
|
-
会话:秘书 · /help 看命令,/conv 列会话,Ctrl-C 退出
|
|
10
|
-
────────────────────────────
|
|
11
|
-
[11-03 13:39] 秘书 codex/gpt-5.5
|
|
12
|
-
已经把 frp 备用入口补给执行器了。
|
|
13
|
-
你 › 明天几点提醒我看牙
|
|
14
|
-
[13:44] 我
|
|
15
|
-
明天几点提醒我看牙
|
|
16
|
-
[13:44] 秘书 codex/gpt-5.5
|
|
17
|
-
记成明天 9:30,提前 10 分钟提醒。
|
|
18
|
-
```
|
|
19
|
-
|
|
20
|
-
## 安装
|
|
21
|
-
|
|
22
|
-
```bash
|
|
23
|
-
npx sidekick-chat # 不装直接用
|
|
24
|
-
npm i -g sidekick-chat # 或者装到全局,命令就是 sidekick
|
|
25
|
-
```
|
|
26
|
-
|
|
27
|
-
仓库里直接用(还没发包时):
|
|
28
|
-
|
|
29
|
-
```bash
|
|
30
|
-
node cli/bin/sidekick.mjs
|
|
31
|
-
```
|
|
32
|
-
|
|
33
|
-
0.2.
|
|
34
|
-
|
|
35
|
-
0.2.1 起,交互界面实时显示服务器的流式回复草稿,支持生成中的 Markdown;正式消息到达后替换草稿,不重复显示。切换会话、断线、清屏或服务端撤回会清除临时草稿。草稿不落盘,重连只补正式消息。`--plain`、管道、一次性 `ask` 和 `--json` 只输出正式消息。
|
|
36
|
-
|
|
37
|
-
需要 Node 22.19 以上。交互界面使用与 Pi agent 相同的 `@earendil-works/pi-tui`,支持 Markdown、中文换行、多行粘贴、输入历史和窗口缩放。
|
|
38
|
-
|
|
39
|
-
Enter 发送,Shift+Enter 换行(终端需支持;也可用 Ctrl+J),↑/↓ 翻输入历史。回复和忙碌状态更新时保留输入草稿与光标。
|
|
40
|
-
|
|
41
|
-
老终端可用 `sidekick --plain`:不上色、不重画输入行。管道和 `TERM=dumb` 自动使用纯文本;`--no-color` / `NO_COLOR` 只关闭颜色。一次性 `ask` 和 `--json` 保持文本/JSON 输出。
|
|
42
|
-
|
|
43
|
-
## 登录
|
|
44
|
-
|
|
45
|
-
凭据存在 `~/.sidekick/config.json`(权限 600),两种方式任选:
|
|
46
|
-
|
|
47
|
-
```bash
|
|
48
|
-
sidekick login # 问地址和网页密码,换一个登录 Cookie
|
|
49
|
-
sidekick login --url http://47.96.64.66:18792 --token <设备令牌> # 直连 chat World
|
|
50
|
-
```
|
|
51
|
-
|
|
52
|
-
- **网页密码**:就是网页版那个 `CORTICO_WEB_PASSWORD`。客户端拿它调站点的 `/api/auth/login`,
|
|
53
|
-
拿到 `cortico_session` Cookie 存起来,400 天不用重登。服务器地址默认 `https://hkv4.cznorth.cn/chat`。
|
|
54
|
-
- **设备令牌**:部署 `.env` 里的 `SIDEKICK_DEVICE_TOKEN`,和手机 App 用的是同一个。
|
|
55
|
-
适合备用线路(杭州 `47.96.64.66:18792`)这种没有网页登录接口的直连地址。
|
|
56
|
-
|
|
57
|
-
`sidekick logout` 清掉本机登录态。Cookie 失效时会提示重新 `sidekick login`。
|
|
58
|
-
|
|
59
|
-
## 用法
|
|
60
|
-
|
|
61
|
-
```bash
|
|
62
|
-
sidekick # 进交互,一行一句
|
|
63
|
-
sidekick "今天有什么安排" # 问一句,回复打印完就退出(适合脚本/管道)
|
|
64
|
-
sidekick ask --wait 20 "…" # 同上,收到第一条后最多再等 20 秒后续消息
|
|
65
|
-
sidekick --conv 收发室 # 指定会话:名字、id 或 /conv 里的序号
|
|
66
|
-
sidekick --json "…" # 每条消息输出一行 JSON
|
|
67
|
-
sidekick --device 家里的电脑 "…" # 换一个署名(默认「终端」)
|
|
68
|
-
```
|
|
69
|
-
|
|
70
|
-
交互里的命令:
|
|
71
|
-
|
|
72
|
-
| 命令 | 作用 |
|
|
73
|
-
|---|---|
|
|
74
|
-
| `/conv` | 列出会话(带未读和最后一条摘要) |
|
|
75
|
-
| `/to <序号\|名字>` | 切换会话 |
|
|
76
|
-
| `/history [n]` | 重印最近 n 条,默认 20 |
|
|
77
|
-
| `/who` | 名册:谁在线、谁在忙 |
|
|
78
|
-
| `/
|
|
79
|
-
| `/clear` | 清屏 |
|
|
80
|
-
| `/quit` | 退出(也可以 Ctrl-C) |
|
|
81
|
-
|
|
82
|
-
其它会话来消息时只在终端里提一句,`/to` 切过去看。其它设备上聊的、手机上聊的,这里都能看到历史的最近 30 条。
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
|
92
|
-
|
|
93
|
-
| `
|
|
94
|
-
| `
|
|
95
|
-
| `
|
|
96
|
-
| `
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
|
106
|
-
|
|
107
|
-
| `
|
|
108
|
-
| `GET /v1/team/
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
src/
|
|
116
|
-
src/
|
|
117
|
-
src/
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
1
|
+
# Sidekick 终端客户端
|
|
2
|
+
|
|
3
|
+
在终端里和秘书说话。它只是 `chat` World 的又一个客户端,和手机 App、网页版共用同一批会话、未读和回复,
|
|
4
|
+
不新增任何后端接口——所以手机上收到的、终端里发的,是同一份对话。
|
|
5
|
+
|
|
6
|
+
```
|
|
7
|
+
$ npx sidekick-chat
|
|
8
|
+
Sidekick · 秘书 https://hkv4.cznorth.cn/chat
|
|
9
|
+
会话:秘书 · /help 看命令,/conv 列会话,Ctrl-C 退出
|
|
10
|
+
────────────────────────────
|
|
11
|
+
[11-03 13:39] 秘书 codex/gpt-5.5
|
|
12
|
+
已经把 frp 备用入口补给执行器了。
|
|
13
|
+
你 › 明天几点提醒我看牙
|
|
14
|
+
[13:44] 我
|
|
15
|
+
明天几点提醒我看牙
|
|
16
|
+
[13:44] 秘书 codex/gpt-5.5
|
|
17
|
+
记成明天 9:30,提前 10 分钟提醒。
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## 安装
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
npx sidekick-chat # 不装直接用
|
|
24
|
+
npm i -g sidekick-chat # 或者装到全局,命令就是 sidekick
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
仓库里直接用(还没发包时):
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
node cli/bin/sidekick.mjs
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
0.2.3 起,输入 `/usage` 时才查询并显示 OpenCode、Codex、Claude WSL 和 Claude Docker 的剩余额度、采样及重置时间。没有常驻 HUD,也不在后台自动刷新。`/quota` 是兼容别名,纯文本交互也支持。刷新失败保留上次查询值并标注,无数据时显示未知。额度沿用 App 的接口,不需要在 CLI 配置模型 API key。
|
|
34
|
+
|
|
35
|
+
0.2.1 起,交互界面实时显示服务器的流式回复草稿,支持生成中的 Markdown;正式消息到达后替换草稿,不重复显示。切换会话、断线、清屏或服务端撤回会清除临时草稿。草稿不落盘,重连只补正式消息。`--plain`、管道、一次性 `ask` 和 `--json` 只输出正式消息。
|
|
36
|
+
|
|
37
|
+
需要 Node 22.19 以上。交互界面使用与 Pi agent 相同的 `@earendil-works/pi-tui`,支持 Markdown、中文换行、多行粘贴、输入历史和窗口缩放。
|
|
38
|
+
|
|
39
|
+
Enter 发送,Shift+Enter 换行(终端需支持;也可用 Ctrl+J),↑/↓ 翻输入历史。回复和忙碌状态更新时保留输入草稿与光标。
|
|
40
|
+
|
|
41
|
+
老终端可用 `sidekick --plain`:不上色、不重画输入行。管道和 `TERM=dumb` 自动使用纯文本;`--no-color` / `NO_COLOR` 只关闭颜色。一次性 `ask` 和 `--json` 保持文本/JSON 输出。
|
|
42
|
+
|
|
43
|
+
## 登录
|
|
44
|
+
|
|
45
|
+
凭据存在 `~/.sidekick/config.json`(权限 600),两种方式任选:
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
sidekick login # 问地址和网页密码,换一个登录 Cookie
|
|
49
|
+
sidekick login --url http://47.96.64.66:18792 --token <设备令牌> # 直连 chat World
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
- **网页密码**:就是网页版那个 `CORTICO_WEB_PASSWORD`。客户端拿它调站点的 `/api/auth/login`,
|
|
53
|
+
拿到 `cortico_session` Cookie 存起来,400 天不用重登。服务器地址默认 `https://hkv4.cznorth.cn/chat`。
|
|
54
|
+
- **设备令牌**:部署 `.env` 里的 `SIDEKICK_DEVICE_TOKEN`,和手机 App 用的是同一个。
|
|
55
|
+
适合备用线路(杭州 `47.96.64.66:18792`)这种没有网页登录接口的直连地址。
|
|
56
|
+
|
|
57
|
+
`sidekick logout` 清掉本机登录态。Cookie 失效时会提示重新 `sidekick login`。
|
|
58
|
+
|
|
59
|
+
## 用法
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
sidekick # 进交互,一行一句
|
|
63
|
+
sidekick "今天有什么安排" # 问一句,回复打印完就退出(适合脚本/管道)
|
|
64
|
+
sidekick ask --wait 20 "…" # 同上,收到第一条后最多再等 20 秒后续消息
|
|
65
|
+
sidekick --conv 收发室 # 指定会话:名字、id 或 /conv 里的序号
|
|
66
|
+
sidekick --json "…" # 每条消息输出一行 JSON
|
|
67
|
+
sidekick --device 家里的电脑 "…" # 换一个署名(默认「终端」)
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
交互里的命令:
|
|
71
|
+
|
|
72
|
+
| 命令 | 作用 |
|
|
73
|
+
|---|---|
|
|
74
|
+
| `/conv` | 列出会话(带未读和最后一条摘要) |
|
|
75
|
+
| `/to <序号\|名字>` | 切换会话 |
|
|
76
|
+
| `/history [n]` | 重印最近 n 条,默认 20 |
|
|
77
|
+
| `/who` | 名册:谁在线、谁在忙 |
|
|
78
|
+
| `/usage` | 查询额度,查看剩余比例、采样和重置时间(`/quota` 为兼容别名) |
|
|
79
|
+
| `/clear` | 清屏 |
|
|
80
|
+
| `/quit` | 退出(也可以 Ctrl-C) |
|
|
81
|
+
|
|
82
|
+
其它会话来消息时只在终端里提一句,`/to` 切过去看。其它设备上聊的、手机上聊的,这里都能看到历史的最近 30 条。
|
|
83
|
+
|
|
84
|
+
**已读只在“人在终端前面”的时候推进**:没过按键的终端收到新消息只把进度攒着,等你下次敲键、发消息或切会话才一起报成已读。
|
|
85
|
+
这样调下来的碎片(或被遗忘的)终端窗口不会把手机上刚弹出的通知瞬间顶掉——已读是多端同步的,任一客户端一推,其他设备就撤通知。
|
|
86
|
+
|
|
87
|
+
## 环境变量
|
|
88
|
+
|
|
89
|
+
参数优先于环境变量,环境变量优先于配置文件:
|
|
90
|
+
|
|
91
|
+
| 变量 | 作用 |
|
|
92
|
+
|---|---|
|
|
93
|
+
| `SIDEKICK_URL` | 服务器地址,如 `https://hkv4.cznorth.cn/chat` |
|
|
94
|
+
| `SIDEKICK_TOKEN` | 设备令牌(Bearer) |
|
|
95
|
+
| `SIDEKICK_PASSWORD` | 网页登录密码(只在 `sidekick login` 时用,不落盘) |
|
|
96
|
+
| `SIDEKICK_COOKIE` | 直接给 `cortico_session` 的值 |
|
|
97
|
+
| `SIDEKICK_DEVICE` | 这台机器的署名 |
|
|
98
|
+
| `SIDEKICK_CONFIG` | 配置文件路径,默认 `~/.sidekick/config.json` |
|
|
99
|
+
| `NO_COLOR` | 设了就不上色 |
|
|
100
|
+
|
|
101
|
+
## 怎么实现的
|
|
102
|
+
|
|
103
|
+
只用了 `chat` World 已经开给手机 App 和网页的那几个接口(`packages/world-chat/src/world.ts` 的 `startHub`):
|
|
104
|
+
|
|
105
|
+
| 接口 | 用途 |
|
|
106
|
+
|---|---|
|
|
107
|
+
| `GET /v1/team/state` | 主 Bot、名册、会话列表 |
|
|
108
|
+
| `GET /v1/team/history?conv=&limit=` | 一个会话的历史 |
|
|
109
|
+
| `POST /v1/team/send` | 发一句 |
|
|
110
|
+
| `POST /v1/team/read` | 标记已读 |
|
|
111
|
+
| `GET /v1/team/stream?after=` | SSE 推流:消息、正在输入、连接状态 |
|
|
112
|
+
|
|
113
|
+
```
|
|
114
|
+
bin/sidekick.mjs 入口,把参数交给 src/main.mjs
|
|
115
|
+
src/main.mjs login / logout / ask / 交互三种流程
|
|
116
|
+
src/api.mjs 接口调用与 SSE 解析,断线按 1s→30s 退避重连,重连时带 seq 补收
|
|
117
|
+
src/config.mjs ~/.sidekick/config.json 读写,参数 > 环境变量 > 配置文件的优先级
|
|
118
|
+
src/format.mjs 纯文本消息排版(纯函数)
|
|
119
|
+
src/tui.mjs Pi TUI:Markdown、编辑器、忙碌状态和差分渲染
|
|
120
|
+
src/prompt.mjs 提问与遮掉回显的密码输入
|
|
121
|
+
test/ node:test,`npm test`;有一个假 World 顶替服务器,不需要联网
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
## 测试
|
|
125
|
+
|
|
126
|
+
```bash
|
|
127
|
+
cd cli && node --test
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
`test/fake-world.mjs` 起了个假的 chat World(实现上面五个接口),所以鉴权失败、发送、推流补收、
|
|
131
|
+
`sidekick ask` 端到端这些都能脱网验证。
|
package/package.json
CHANGED
|
@@ -1,38 +1,39 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "sidekick-chat",
|
|
3
|
-
"version": "0.2.
|
|
4
|
-
"description": "Sidekick 终端客户端:在终端里和秘书对话",
|
|
5
|
-
"type": "module",
|
|
6
|
-
"license": "PolyForm-Noncommercial-1.0.0",
|
|
7
|
-
"engines": {
|
|
8
|
-
"node": ">=22.19.0"
|
|
9
|
-
},
|
|
10
|
-
"bin": {
|
|
11
|
-
"sidekick": "bin/sidekick.mjs"
|
|
12
|
-
},
|
|
13
|
-
"files": [
|
|
14
|
-
"bin",
|
|
15
|
-
"src",
|
|
16
|
-
"README.md",
|
|
17
|
-
"LICENSE"
|
|
18
|
-
],
|
|
19
|
-
"scripts": {
|
|
20
|
-
"test": "node --test"
|
|
21
|
-
},
|
|
22
|
-
"keywords": [
|
|
23
|
-
"sidekick",
|
|
24
|
-
"cli",
|
|
25
|
-
"chat",
|
|
26
|
-
"assistant"
|
|
27
|
-
],
|
|
28
|
-
"repository": {
|
|
29
|
-
"type": "git",
|
|
30
|
-
"url": "git+https://github.com/Cznorth/sidekick
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "sidekick-chat",
|
|
3
|
+
"version": "0.2.4",
|
|
4
|
+
"description": "Sidekick 终端客户端:在终端里和秘书对话",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"license": "PolyForm-Noncommercial-1.0.0",
|
|
7
|
+
"engines": {
|
|
8
|
+
"node": ">=22.19.0"
|
|
9
|
+
},
|
|
10
|
+
"bin": {
|
|
11
|
+
"sidekick": "bin/sidekick.mjs"
|
|
12
|
+
},
|
|
13
|
+
"files": [
|
|
14
|
+
"bin",
|
|
15
|
+
"src",
|
|
16
|
+
"README.md",
|
|
17
|
+
"LICENSE"
|
|
18
|
+
],
|
|
19
|
+
"scripts": {
|
|
20
|
+
"test": "node --test"
|
|
21
|
+
},
|
|
22
|
+
"keywords": [
|
|
23
|
+
"sidekick",
|
|
24
|
+
"cli",
|
|
25
|
+
"chat",
|
|
26
|
+
"assistant"
|
|
27
|
+
],
|
|
28
|
+
"repository": {
|
|
29
|
+
"type": "git",
|
|
30
|
+
"url": "git+https://github.com/Cznorth/sidekick.git",
|
|
31
|
+
"directory": "cli"
|
|
32
|
+
},
|
|
33
|
+
"dependencies": {
|
|
34
|
+
"@earendil-works/pi-tui": "1.0.0"
|
|
35
|
+
},
|
|
36
|
+
"devDependencies": {
|
|
37
|
+
"@xterm/headless": "5.5.0"
|
|
38
|
+
}
|
|
39
|
+
}
|