ccjk 15.6.0 → 15.7.0
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 +158 -110
- package/dist/commands/menu.js +90 -31
- package/dist/commands/menu.js.map +1 -1
- package/dist/core/banner.js +122 -0
- package/dist/core/banner.js.map +1 -0
- package/package.json +6 -3
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# ccjk
|
|
2
2
|
|
|
3
|
-
> Clavue / Claude Code
|
|
3
|
+
> Clavue / Claude Code / Codex 的本地配置 CLI。一条命令搞定 API、Profile、权限、MCP、状态栏、版本管理。
|
|
4
4
|
|
|
5
5
|
[](https://www.npmjs.com/package/ccjk)
|
|
6
6
|
[](./LICENSE)
|
|
@@ -12,47 +12,90 @@
|
|
|
12
12
|
npm install -g ccjk
|
|
13
13
|
```
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
升级:`npm install -g ccjk@latest`
|
|
16
16
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
ccjk
|
|
23
|
-
ccjk
|
|
24
|
-
ccjk
|
|
25
|
-
ccjk
|
|
26
|
-
|
|
17
|
+
## ccjk 能干什么
|
|
18
|
+
|
|
19
|
+
| 场景 | 命令 |
|
|
20
|
+
|---|---|
|
|
21
|
+
| 第一次配 API key | `ccjk init` |
|
|
22
|
+
| 多个 API key 之间切换(GLM/Kimi/Anthropic/...) | `ccjk use` |
|
|
23
|
+
| 不想每次都点确认权限 | `ccjk perms standard` |
|
|
24
|
+
| 看不到当前模型/用量 | `ccjk statusline-install` |
|
|
25
|
+
| settings.json 出问题 | `ccjk doctor --fix` |
|
|
26
|
+
| 装 MCP 服务(context7、serena、playwright...) | `ccjk mcp` |
|
|
27
|
+
| 看哪个工具该升级了 | `ccjk tools --check-updates` |
|
|
28
|
+
| 写入出错想还原 | `ccjk rollback` |
|
|
29
|
+
| 跨机器迁移配置 | `ccjk profile export` / `import` |
|
|
30
|
+
| 不想记命令 | `ccjk`(交互菜单) |
|
|
27
31
|
|
|
28
32
|
## 命令一览
|
|
29
33
|
|
|
34
|
+
### 配置 API(init / use / profile)
|
|
35
|
+
|
|
30
36
|
| 命令 | 用途 |
|
|
31
37
|
|---|---|
|
|
32
|
-
| `ccjk` |
|
|
33
|
-
| `ccjk
|
|
34
|
-
| `ccjk
|
|
35
|
-
| `ccjk profile
|
|
36
|
-
| `ccjk profile
|
|
37
|
-
|
|
38
|
-
|
|
38
|
+
| `ccjk init` | 配 API:写 `~/.claude/settings.json` 的 env,并自动保存为 profile |
|
|
39
|
+
| `ccjk use [name]` | 一键切换 profile(不带参=交互选) |
|
|
40
|
+
| `ccjk profile ls` / `show` / `rm` | profile 列表 / 详情 / 删除 |
|
|
41
|
+
| `ccjk profile export` | 导出 profile 为 JSON 包(迁移 / 团队共享) |
|
|
42
|
+
| `ccjk profile import <file>` | 从 JSON 包导入 profile |
|
|
43
|
+
|
|
44
|
+
### 权限档位(perms)
|
|
45
|
+
|
|
46
|
+
| 命令 | 用途 |
|
|
47
|
+
|---|---|
|
|
48
|
+
| `ccjk perms [tier]` | 一键设权限档位(`safe` / `standard` / `yolo`),同步 3 个工具 |
|
|
39
49
|
| `ccjk perms-show` | 查看三个工具当前的权限状态 |
|
|
40
|
-
|
|
41
|
-
|
|
50
|
+
|
|
51
|
+
### MCP 服务
|
|
52
|
+
|
|
53
|
+
| 命令 | 用途 |
|
|
54
|
+
|---|---|
|
|
42
55
|
| `ccjk mcp` | 选装预设 MCP 服务(交互勾选) |
|
|
43
56
|
| `ccjk mcp-ls` | 列出已安装的 MCP |
|
|
44
|
-
| `ccjk mcp-add
|
|
57
|
+
| `ccjk mcp-add <name>` | 添加自定义 MCP 服务 |
|
|
45
58
|
| `ccjk mcp-rm [name]` | 卸载 MCP 服务 |
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
|
50
|
-
|
|
51
|
-
| `ccjk
|
|
59
|
+
|
|
60
|
+
### 状态栏(statusline)
|
|
61
|
+
|
|
62
|
+
| 命令 | 用途 |
|
|
63
|
+
|---|---|
|
|
64
|
+
| `ccjk statusline-install` | 安装状态栏,显示模型 / 目录 / context 用量 / 今日调用 / 速率 |
|
|
65
|
+
| `ccjk statusline-uninstall` | 卸载状态栏 |
|
|
66
|
+
|
|
67
|
+
### 体检 / 还原
|
|
68
|
+
|
|
69
|
+
| 命令 | 用途 |
|
|
70
|
+
|---|---|
|
|
71
|
+
| `ccjk doctor` | 检查 settings.json 的常见配置问题 |
|
|
72
|
+
| `ccjk doctor --fix` | 自动修可修的问题(修改前备份) |
|
|
73
|
+
| `ccjk rollback` | 从备份还原 settings.json / config.toml |
|
|
74
|
+
|
|
75
|
+
### 工具版本管理
|
|
76
|
+
|
|
77
|
+
| 命令 | 用途 |
|
|
78
|
+
|---|---|
|
|
79
|
+
| `ccjk tools` | 查看 Clavue / Claude Code / Codex 本地版本 |
|
|
80
|
+
| `ccjk tools --check-updates` | 加查 npm latest,标记 outdated |
|
|
81
|
+
| `ccjk install [tool]` | 安装代码工具(`--all` 装全部缺失的) |
|
|
82
|
+
| `ccjk update [tool]` | 升级代码工具到最新版(`--all` 全部 outdated) |
|
|
83
|
+
|
|
84
|
+
### 其他
|
|
85
|
+
|
|
86
|
+
| 命令 | 用途 |
|
|
87
|
+
|---|---|
|
|
88
|
+
| `ccjk` | 交互菜单(默认) |
|
|
52
89
|
| `ccjk detect` | 列出已安装的代码工具 |
|
|
53
90
|
| `ccjk git-install` | 安装 `/ccjk:git-commit` 等 slash 命令模板 |
|
|
54
91
|
|
|
55
|
-
|
|
92
|
+
---
|
|
93
|
+
|
|
94
|
+
## 详解
|
|
95
|
+
|
|
96
|
+
### Profile:多 API 切换
|
|
97
|
+
|
|
98
|
+
`ccjk init` 配完 API 默认会问"保存为 profile?"。之后 `ccjk use` 可以在多个 profile 之间一键切换:
|
|
56
99
|
|
|
57
100
|
```bash
|
|
58
101
|
ccjk init -t clavue -p glm --api-key sk-xxx --profile work -y
|
|
@@ -70,12 +113,12 @@ Profile 存储在 `~/.ccjk/profiles/<name>.json`,当前激活的记录在 `~/.
|
|
|
70
113
|
#### 导出 / 导入:跨机器迁移
|
|
71
114
|
|
|
72
115
|
```bash
|
|
73
|
-
ccjk profile export
|
|
74
|
-
ccjk profile export -n work free -o team.json -y
|
|
75
|
-
ccjk profile export --redact -o template.json -y
|
|
116
|
+
ccjk profile export # 交互勾选
|
|
117
|
+
ccjk profile export -n work free -o team.json -y # 直接导出 work + free
|
|
118
|
+
ccjk profile export --redact -o template.json -y # 抹去 API key("模板")
|
|
76
119
|
|
|
77
120
|
# 在另一台机器
|
|
78
|
-
ccjk profile import team.json
|
|
121
|
+
ccjk profile import team.json # 同名时交互问跳过/覆盖/重命名
|
|
79
122
|
ccjk profile import team.json --conflict skip -y # 全部 skip 已有的
|
|
80
123
|
```
|
|
81
124
|
|
|
@@ -85,37 +128,50 @@ ccjk profile import team.json --conflict skip -y # 全部 skip 已有的
|
|
|
85
128
|
|
|
86
129
|
一条命令把 Clavue / Claude Code / Codex 的权限同步到同一档位,减少每次操作都要点确认的烦躁。
|
|
87
130
|
|
|
88
|
-
| 档位 | 适合 | Claude/Clavue | Codex |
|
|
131
|
+
| 档位 | 适合 | Claude / Clavue | Codex |
|
|
89
132
|
|---|---|---|---|
|
|
90
133
|
| `safe` | 浏览代码、新手 | 仅放行只读(Read/Grep/...) | `approval_policy=untrusted`, `sandbox_mode=read-only` |
|
|
91
134
|
| `standard`(推荐) | 日常开发 | + git/npm/pnpm/python/ls/cat 等高频命令 | `approval_policy=on-failure`, `sandbox_mode=workspace-write` |
|
|
92
135
|
| `yolo` | 可信项目放飞 | `Bash(*)` + `allowUnsandboxedCommands=true` | `approval_policy=never`, `sandbox_mode=workspace-write` |
|
|
93
136
|
|
|
94
|
-
不论哪一档,都强制写入 `deny`:`rm -rf /`、`git push --force`、`npm publish`、`sudo` 等不可逆 /
|
|
137
|
+
不论哪一档,都强制写入 `deny`:`rm -rf /`、`git push --force`、`npm publish`、`sudo` 等不可逆 / 高危命令。
|
|
95
138
|
|
|
96
139
|
```bash
|
|
97
|
-
ccjk perms
|
|
98
|
-
ccjk perms standard
|
|
99
|
-
ccjk perms safe --tools clavue,claude-code
|
|
100
|
-
ccjk perms yolo --reset
|
|
101
|
-
ccjk perms-show
|
|
140
|
+
ccjk perms # 交互选档位(推荐)
|
|
141
|
+
ccjk perms standard # 直接应用 standard 到全部 3 个工具
|
|
142
|
+
ccjk perms safe --tools clavue,claude-code # 只作用于这两个
|
|
143
|
+
ccjk perms yolo --reset # --reset 会清空原 allow 后再写
|
|
144
|
+
ccjk perms-show # 看三个工具当前各是哪档
|
|
102
145
|
```
|
|
103
146
|
|
|
104
147
|
合并策略:
|
|
105
148
|
- `allow`:默认 append + dedupe,保护用户自定义白名单。`--reset` 强制覆盖。
|
|
106
149
|
- `deny`:始终覆盖,确保危险命令一定被拦。
|
|
107
150
|
|
|
108
|
-
###
|
|
151
|
+
### Statusline:底部状态栏
|
|
152
|
+
|
|
153
|
+
显示模型、当前目录、context 用量、今日 API 调用次数、tokens 速率。
|
|
109
154
|
|
|
110
155
|
```bash
|
|
111
|
-
ccjk
|
|
112
|
-
ccjk
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
156
|
+
ccjk statusline-install # 写入 settings.statusLine(重启 Claude Code 生效)
|
|
157
|
+
ccjk statusline-uninstall # 卸载
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
效果(一行):
|
|
161
|
+
|
|
162
|
+
```
|
|
163
|
+
Sonnet 4.5 1M │ 📁 ccjk │ ⚡ 4.5% 45.0k │ 12 calls · 1.5k tok/m
|
|
117
164
|
```
|
|
118
165
|
|
|
166
|
+
字段含义:
|
|
167
|
+
- `Sonnet 4.5 1M` — 模型名 + context window 大小(1M / 200k)
|
|
168
|
+
- `📁 ccjk` — 当前工作目录的 basename(home 显示为 `~`)
|
|
169
|
+
- `⚡ 4.5% 45.0k` — context 已用百分比 + 当前 token 数
|
|
170
|
+
- `12 calls` — 今日总 API 调用数(聚合所有 transcripts)
|
|
171
|
+
- `1.5k tok/m` 或 `80 tok/s` — 今日产出速率(output tokens / 活跃秒数)
|
|
172
|
+
|
|
173
|
+
实现:扫 `~/.claude/projects/*/*.jsonl` 当天 mtime 文件,读 `message.usage` 聚合。错误一律 swallow,不会让 Claude Code UI 报红。
|
|
174
|
+
|
|
119
175
|
### Doctor:体检 + 自动修复
|
|
120
176
|
|
|
121
177
|
```bash
|
|
@@ -124,12 +180,17 @@ ccjk doctor --fix # 自动修可修的(修改前备份)
|
|
|
124
180
|
ccjk doctor --fix -y # 跳过确认
|
|
125
181
|
```
|
|
126
182
|
|
|
127
|
-
|
|
128
|
-
|
|
183
|
+
| 规则 | 严重度 | 自动修 | 说明 |
|
|
184
|
+
|---|---|---|---|
|
|
185
|
+
| `model-overrides-env` | error | ✓ | 顶层 `settings.model` 会覆盖 `env.ANTHROPIC_MODEL` |
|
|
186
|
+
| `duplicate-auth` | warn | ✓ | 同时存在 `API_KEY` 和 `AUTH_TOKEN`(保留 AUTH_TOKEN,删 API_KEY) |
|
|
187
|
+
| `missing-credentials` | error | ✗ | 设了 `BASE_URL` 但缺凭证 → 跑 `ccjk init` |
|
|
188
|
+
| `invalid-base-url` | error | ✗ | URL 格式不合法 → 跑 `ccjk init` |
|
|
189
|
+
| `hook-bloat` | warn | ✗ | 单个 hook 注册超过 5 个处理器(人工审查) |
|
|
129
190
|
|
|
130
191
|
### Rollback:从备份还原
|
|
131
192
|
|
|
132
|
-
每次 `init` / `mcp` / `perms` / `doctor --fix` 写入前都会自动备份到
|
|
193
|
+
每次 `init` / `mcp` / `perms` / `doctor --fix` / `mcp-add/rm` / `statusline-install` 写入前都会自动备份到 `<file>.bak-<ISO时间戳>`。
|
|
133
194
|
|
|
134
195
|
```bash
|
|
135
196
|
ccjk rollback # 列所有备份,按时间倒序
|
|
@@ -138,101 +199,88 @@ ccjk rollback -t clavue # 只看一个工具的备份
|
|
|
138
199
|
|
|
139
200
|
还原前会再备份一份当前状态,所以**还原本身也可还原**。
|
|
140
201
|
|
|
141
|
-
###
|
|
202
|
+
### Tools / Install / Update:版本管理
|
|
142
203
|
|
|
143
|
-
|
|
204
|
+
三个开发工具的本地版本、npm 最新版、安装、升级——都在 ccjk 里。
|
|
144
205
|
|
|
145
206
|
```bash
|
|
146
|
-
ccjk
|
|
147
|
-
ccjk
|
|
148
|
-
```
|
|
149
|
-
|
|
150
|
-
效果(一行):
|
|
151
|
-
|
|
152
|
-
```
|
|
153
|
-
Sonnet 4.5 1M │ 📁 ccjk │ ⚡ 4.5% 45.0k │ 12 calls · 1.5k tok/m
|
|
154
|
-
```
|
|
207
|
+
ccjk tools # 看本地版本
|
|
208
|
+
ccjk tools --check-updates # 加查 npm latest
|
|
155
209
|
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
- `📁 ccjk` — 当前工作目录的 basename(home 显示为 `~`)
|
|
159
|
-
- `⚡ 4.5% 45.0k` — context 已用百分比 + 当前 token 数
|
|
160
|
-
- `12 calls` — 今日总 API 调用数(聚合所有 transcripts)
|
|
161
|
-
- `1.5k tok/m` 或 `80 tok/s` — 今日产出速率(output tokens / 跨度秒数)
|
|
162
|
-
|
|
163
|
-
实现细节:扫 `~/.claude/projects/*/*.jsonl` 当天 mtime 文件,读 `message.usage` 字段聚合。错误一律 swallow,不会让 Claude Code UI 报红。
|
|
164
|
-
|
|
165
|
-
### Tools:工具版本管理
|
|
166
|
-
|
|
167
|
-
三个开发工具(Clavue / Claude Code / Codex)的本地版本、npm 最新版、安装、升级——一条命令搞定。
|
|
168
|
-
|
|
169
|
-
```bash
|
|
170
|
-
ccjk tools # 看本地三个工具的版本
|
|
171
|
-
ccjk tools --check-updates # 额外查 npm latest,标记 outdated
|
|
172
|
-
|
|
173
|
-
ccjk install # 交互选择要安装的工具
|
|
174
|
-
ccjk install codex # 安装 Codex
|
|
210
|
+
ccjk install # 交互选要装的工具
|
|
211
|
+
ccjk install codex # 直接装 Codex
|
|
175
212
|
ccjk install --all # 装全部缺失的
|
|
176
213
|
|
|
177
|
-
ccjk update #
|
|
178
|
-
ccjk update claude-code #
|
|
179
|
-
ccjk update --all #
|
|
214
|
+
ccjk update # 交互选 outdated 的工具
|
|
215
|
+
ccjk update claude-code # 直接升级 Claude Code
|
|
216
|
+
ccjk update --all # 升级所有 outdated
|
|
217
|
+
ccjk update --dry-run # 只显示命令不执行
|
|
180
218
|
```
|
|
181
219
|
|
|
182
220
|
输出示例:
|
|
183
221
|
|
|
184
222
|
```
|
|
185
|
-
Clavue 8.9.2
|
|
223
|
+
Clavue 8.9.2 (latest)
|
|
186
224
|
Claude Code 2.1.138 (latest)
|
|
187
225
|
Codex 0.128.0 → 0.130.0 可升级
|
|
188
226
|
```
|
|
189
227
|
|
|
190
|
-
|
|
228
|
+
实现是 `npm install -g <pkg>` / `npm install -g <pkg>@<latest>`,命令完整列出后等用户确认。npm 因权限失败时会输出建议的 `sudo` 命令让用户自己跑,不假装成功。
|
|
191
229
|
|
|
192
|
-
|
|
230
|
+
### 非交互模式
|
|
193
231
|
|
|
194
|
-
|
|
195
|
-
|---|---|---|
|
|
196
|
-
| Clavue | `~/.claude/settings.json` | 主推 |
|
|
197
|
-
| Claude Code | `~/.claude/settings.json` | 完整支持 |
|
|
198
|
-
| Codex | `~/.codex/config.toml` | 仅检测 |
|
|
232
|
+
适合脚本 / CI / 装机:
|
|
199
233
|
|
|
200
|
-
|
|
234
|
+
```bash
|
|
235
|
+
ccjk init -t clavue -p glm --api-key sk-xxx --profile work -y
|
|
236
|
+
ccjk perms standard -y
|
|
237
|
+
ccjk mcp -s context7 serena -y
|
|
238
|
+
ccjk mcp-add my-server --command npx --args "-y @scope/pkg" -y
|
|
239
|
+
ccjk doctor --fix -y
|
|
240
|
+
ccjk statusline-install -y
|
|
241
|
+
ccjk update --all -y
|
|
242
|
+
ccjk git-install --scope user -y
|
|
243
|
+
```
|
|
201
244
|
|
|
202
|
-
|
|
245
|
+
---
|
|
203
246
|
|
|
204
|
-
##
|
|
247
|
+
## 支持的工具
|
|
205
248
|
|
|
206
|
-
|
|
|
249
|
+
| 工具 | 配置目标 | 范围 |
|
|
207
250
|
|---|---|---|
|
|
208
|
-
|
|
|
209
|
-
|
|
|
210
|
-
|
|
|
211
|
-
|
|
212
|
-
|
|
251
|
+
| Clavue | `~/.claude/settings.json` | API / Profile / Perms / MCP / Statusline / Doctor / Rollback |
|
|
252
|
+
| Claude Code | `~/.claude/settings.json` | API / Profile / Perms / MCP / Statusline / Doctor / Rollback |
|
|
253
|
+
| Codex | `~/.codex/config.toml` | Perms / Detect / Install / Update(API 配置请直接编辑 config.toml) |
|
|
254
|
+
|
|
255
|
+
### 内置 API Provider
|
|
256
|
+
|
|
257
|
+
`glm` / `kimi` / `minimax` / `anthropic` / `custom`
|
|
213
258
|
|
|
214
259
|
## 设计原则
|
|
215
260
|
|
|
216
|
-
-
|
|
217
|
-
-
|
|
218
|
-
-
|
|
261
|
+
- **配置工具就是配置工具**。不做 brain、orchestrator、sandbox、dashboard 这类东西。
|
|
262
|
+
- **不主动写代码**。不写 `~/.claude/CLAUDE.md`,不装 hooks,不开后台进程。
|
|
263
|
+
- **可还原**。所有写入前都备份;`ccjk rollback` 能找回任何旧版本。
|
|
264
|
+
- **可重复**。所有交互式命令都有非交互参数(`-y`、`--profile`、`--tools`、`--services`...),适合脚本。
|
|
265
|
+
- **不偷跑命令**。`install` / `update` 会显示完整命令并等用户确认。
|
|
219
266
|
|
|
220
267
|
## 从 v14 升级
|
|
221
268
|
|
|
222
|
-
v15
|
|
269
|
+
v15 是从零重写的精简版本,命令集和行为都和 v14.x 不兼容:
|
|
223
270
|
|
|
224
|
-
- v14 的子命令(brain/sandbox/teleport/cloud-sync 等)在 v15
|
|
225
|
-
- v14 在 `~/.claude/CLAUDE.md`
|
|
226
|
-
- 如果你只用 v14 的 init/mcp/doctor/git
|
|
271
|
+
- v14 的子命令(brain/sandbox/teleport/cloud-sync 等)在 v15 **不存在**。
|
|
272
|
+
- v14 在 `~/.claude/CLAUDE.md` 注入的 "Smart Assistant Mode" 在 v15 **不会再写入**。如需手动清理旧版残留,删除该文件中相关段落即可。
|
|
273
|
+
- 如果你只用 v14 的 init/mcp/doctor/git 等核心功能,直接 `npm install -g ccjk@latest` 升级即可。
|
|
227
274
|
- 需要 v14 的扩展能力,请固定旧版本:`npm install -g ccjk@14`。
|
|
228
275
|
|
|
229
276
|
## 开发
|
|
230
277
|
|
|
231
278
|
```bash
|
|
232
279
|
pnpm install
|
|
233
|
-
pnpm typecheck
|
|
234
|
-
pnpm test
|
|
235
|
-
pnpm
|
|
280
|
+
pnpm typecheck # TypeScript 检查
|
|
281
|
+
pnpm test # 跑全部测试(>100 测试)
|
|
282
|
+
pnpm lint # ESLint
|
|
283
|
+
pnpm build # tsc 出 dist/
|
|
236
284
|
```
|
|
237
285
|
|
|
238
286
|
## 许可
|
package/dist/commands/menu.js
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import { readFileSync } from 'node:fs';
|
|
2
|
+
import { dirname, join } from 'node:path';
|
|
3
|
+
import { fileURLToPath } from 'node:url';
|
|
1
4
|
import inquirer from 'inquirer';
|
|
2
5
|
import ansis from 'ansis';
|
|
3
6
|
import { detectCommand } from './detect.js';
|
|
@@ -10,43 +13,99 @@ import { permsCommand } from './perms.js';
|
|
|
10
13
|
import { rollbackCommand } from './rollback.js';
|
|
11
14
|
import { statusLineInstallCommand } from './statusline.js';
|
|
12
15
|
import { installCommand, updateCommand, versionCommand } from './version.js';
|
|
13
|
-
import {
|
|
14
|
-
const
|
|
15
|
-
{
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
{
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
16
|
+
import { collectStatus, renderBanner, renderStatusBar } from '../core/banner.js';
|
|
17
|
+
const GROUPS = [
|
|
18
|
+
{
|
|
19
|
+
title: '配置 API',
|
|
20
|
+
items: [
|
|
21
|
+
{ label: '配置 API(init)', hint: '写 settings.json,存为 profile', run: () => initCommand() },
|
|
22
|
+
{ label: '切换 Profile', hint: '在已配过的 API 之间切换', run: () => profileUseCommand(undefined) },
|
|
23
|
+
{ label: '权限档位', hint: 'safe / standard / yolo(同步 3 工具)', run: () => permsCommand(undefined) },
|
|
24
|
+
],
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
title: '增强体验',
|
|
28
|
+
items: [
|
|
29
|
+
{ label: '安装状态栏', hint: '显示模型 / 用量 / 速率', run: () => statusLineInstallCommand() },
|
|
30
|
+
{ label: '配置 MCP 服务', hint: 'context7 / serena / playwright ...', run: () => mcpCommand() },
|
|
31
|
+
{ label: '安装 Git 命令模板', hint: '/ccjk:git-commit 等 slash 命令', run: () => gitInstallCommand() },
|
|
32
|
+
],
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
title: '维护与诊断',
|
|
36
|
+
items: [
|
|
37
|
+
{ label: '体检(doctor)', hint: '检查 settings.json 配置问题', run: () => doctorCommand() },
|
|
38
|
+
{ label: '从备份还原', hint: '回滚 settings.json / config.toml', run: () => rollbackCommand() },
|
|
39
|
+
{ label: '查看版本 / 检查更新', hint: '本地 + npm latest', run: () => versionCommand({ checkUpdates: true }) },
|
|
40
|
+
{ label: '安装代码工具', hint: 'Clavue / Claude Code / Codex', run: () => installCommand(undefined) },
|
|
41
|
+
{ label: '更新代码工具', hint: '升级到最新版', run: () => updateCommand(undefined) },
|
|
42
|
+
{ label: '检测已安装的工具', hint: '看哪些已装哪些没装', run: async () => detectCommand() },
|
|
43
|
+
],
|
|
44
|
+
},
|
|
27
45
|
];
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
46
|
+
/**
|
|
47
|
+
* 中文字符在 monospace 终端通常占 2 列。padEnd 按字符数算不对齐,
|
|
48
|
+
* 这里手动补空格让 hint 对齐到第 22 列。
|
|
49
|
+
*/
|
|
50
|
+
function padToVisibleWidth(s, width) {
|
|
51
|
+
let w = 0;
|
|
52
|
+
for (const ch of s) {
|
|
53
|
+
const code = ch.codePointAt(0) ?? 0;
|
|
54
|
+
if (code >= 0x4e00 && code <= 0x9fff)
|
|
55
|
+
w += 2;
|
|
56
|
+
else if (code >= 0x3000 && code <= 0x303f)
|
|
57
|
+
w += 2;
|
|
58
|
+
else if (code >= 0xff00 && code <= 0xffef)
|
|
59
|
+
w += 2;
|
|
60
|
+
else
|
|
61
|
+
w += 1;
|
|
62
|
+
}
|
|
63
|
+
return s + ' '.repeat(Math.max(0, width - w));
|
|
64
|
+
}
|
|
65
|
+
function getVersion() {
|
|
66
|
+
try {
|
|
67
|
+
const pkgPath = join(dirname(fileURLToPath(import.meta.url)), '..', '..', 'package.json');
|
|
68
|
+
const raw = readFileSync(pkgPath, 'utf-8');
|
|
69
|
+
return JSON.parse(raw).version;
|
|
35
70
|
}
|
|
36
|
-
|
|
37
|
-
|
|
71
|
+
catch {
|
|
72
|
+
return '?.?.?';
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
export async function menuCommand() {
|
|
76
|
+
console.log();
|
|
77
|
+
console.log(renderBanner(getVersion()));
|
|
78
|
+
console.log();
|
|
79
|
+
const status = await collectStatus();
|
|
80
|
+
const statusLines = renderStatusBar(status);
|
|
81
|
+
for (const l of statusLines)
|
|
82
|
+
console.log(l);
|
|
83
|
+
console.log();
|
|
84
|
+
const choices = [];
|
|
85
|
+
let idx = 0;
|
|
86
|
+
const flat = [];
|
|
87
|
+
for (const g of GROUPS) {
|
|
88
|
+
choices.push(new inquirer.Separator(ansis.dim(`── ${g.title} ───────────────────────────`)));
|
|
89
|
+
for (const item of g.items) {
|
|
90
|
+
const hint = item.hint ? ` ${ansis.dim(item.hint)}` : '';
|
|
91
|
+
const padded = padToVisibleWidth(item.label, 20);
|
|
92
|
+
choices.push({ name: `${padded}${hint}`, value: idx, short: item.label });
|
|
93
|
+
flat.push(item);
|
|
94
|
+
idx++;
|
|
95
|
+
}
|
|
38
96
|
}
|
|
39
|
-
|
|
97
|
+
choices.push(new inquirer.Separator(ansis.dim('──────────────────────────────────────────')));
|
|
98
|
+
choices.push({ name: ansis.gray('退出'), value: -1, short: '退出' });
|
|
40
99
|
const { choice } = await inquirer.prompt([{
|
|
41
|
-
type: '
|
|
100
|
+
type: 'list',
|
|
42
101
|
name: 'choice',
|
|
43
|
-
message: '
|
|
44
|
-
|
|
102
|
+
message: ansis.bold('选择操作'),
|
|
103
|
+
choices,
|
|
104
|
+
pageSize: 20,
|
|
105
|
+
loop: false,
|
|
45
106
|
}]);
|
|
46
|
-
if (choice
|
|
107
|
+
if (choice < 0)
|
|
47
108
|
return;
|
|
48
|
-
|
|
49
|
-
if (item)
|
|
50
|
-
await item.run();
|
|
109
|
+
await flat[choice].run();
|
|
51
110
|
}
|
|
52
111
|
//# sourceMappingURL=menu.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"menu.js","sourceRoot":"","sources":["../../src/commands/menu.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,MAAM,UAAU,CAAC;AAChC,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACxC,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AACtC,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACjD,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,wBAAwB,EAAE,MAAM,iBAAiB,CAAC;AAC3D,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC7E,OAAO,EAAE,YAAY,EAAE,
|
|
1
|
+
{"version":3,"file":"menu.js","sourceRoot":"","sources":["../../src/commands/menu.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import ansis from 'ansis';
|
|
2
|
+
import { homedir } from 'node:os';
|
|
3
|
+
import { existsSync } from 'node:fs';
|
|
4
|
+
import { TOOLS } from './tools.js';
|
|
5
|
+
import { getInstalledVersion } from './versions.js';
|
|
6
|
+
import { listProfiles, readState } from './profiles.js';
|
|
7
|
+
import { readSettings } from './settings.js';
|
|
8
|
+
import { detectClaudeTier } from './perms.js';
|
|
9
|
+
import { expandHome } from './paths.js';
|
|
10
|
+
/**
|
|
11
|
+
* 渲染启动横幅。简洁优先:
|
|
12
|
+
* - 不闪烁、不动画
|
|
13
|
+
* - ASCII art 用单字节字符,避免双宽字体导致对齐歪
|
|
14
|
+
* - 终端不支持颜色时降级(ansis 自动处理)
|
|
15
|
+
*/
|
|
16
|
+
export function renderBanner(version) {
|
|
17
|
+
const lines = [];
|
|
18
|
+
const dim = ansis.dim;
|
|
19
|
+
const bold = ansis.bold;
|
|
20
|
+
// ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
|
|
21
|
+
// ▄▄ ▄▄ ▄ ▄ ▄ ▄
|
|
22
|
+
// 走字母 art:每行严格 6 字符 × n,全部 ASCII:
|
|
23
|
+
//
|
|
24
|
+
// ██████╗ ██████╗ ██╗██╗ ██╗
|
|
25
|
+
// ██╔════╝ ██╔════╝ ██║██║ ██╔╝
|
|
26
|
+
// ██║ ██║ ██║█████╔╝
|
|
27
|
+
// ██║ ██║ ██ ██║██╔═██╗
|
|
28
|
+
// ╚██████╗ ╚██████╗ ╚█████╔╝██║ ██╗
|
|
29
|
+
// ╚═════╝ ╚═════╝ ╚════╝ ╚═╝ ╚═╝
|
|
30
|
+
//
|
|
31
|
+
// 这些字符(█ ╗ ╔ ║ ═ ╚)大多数 monospace 字体里都是单宽,对齐稳。
|
|
32
|
+
const art = [
|
|
33
|
+
' ██████╗ ██████╗ ██╗██╗ ██╗',
|
|
34
|
+
' ██╔════╝ ██╔════╝ ██║██║ ██╔╝',
|
|
35
|
+
' ██║ ██║ ██║█████╔╝ ',
|
|
36
|
+
' ██║ ██║ ██ ██║██╔═██╗ ',
|
|
37
|
+
' ╚██████╗ ╚██████╗ ╚█████╔╝██║ ██╗',
|
|
38
|
+
' ╚═════╝ ╚═════╝ ╚════╝ ╚═╝ ╚═╝',
|
|
39
|
+
];
|
|
40
|
+
for (const a of art)
|
|
41
|
+
lines.push(bold.cyan(a));
|
|
42
|
+
lines.push('');
|
|
43
|
+
lines.push(` ${bold('Clavue 官方配置工具')} ${dim('· Claude Code / Codex 通用')}`);
|
|
44
|
+
lines.push(` ${dim(`v${version} · npm i -g ccjk · github.com/miounet11/ccjk`)}`);
|
|
45
|
+
return lines.join('\n');
|
|
46
|
+
}
|
|
47
|
+
export async function collectStatus() {
|
|
48
|
+
const profiles = await listProfiles().catch(() => []);
|
|
49
|
+
const state = await readState().catch(() => ({}));
|
|
50
|
+
// 读 Claude/Clavue settings 决定 perms 档位 + statusline 是否装了
|
|
51
|
+
let permsTier;
|
|
52
|
+
let statuslineInstalled = false;
|
|
53
|
+
try {
|
|
54
|
+
const path = expandHome(TOOLS.clavue.settingsFile);
|
|
55
|
+
if (existsSync(path)) {
|
|
56
|
+
const s = await readSettings(TOOLS.clavue.settingsFile);
|
|
57
|
+
const detected = detectClaudeTier(s);
|
|
58
|
+
if (detected)
|
|
59
|
+
permsTier = detected;
|
|
60
|
+
const sl = s.statusLine;
|
|
61
|
+
if (sl?.command)
|
|
62
|
+
statuslineInstalled = true;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
catch { /* swallow */ }
|
|
66
|
+
const toolsInstalled = Object.keys(TOOLS).map((t) => {
|
|
67
|
+
const v = getInstalledVersion(t);
|
|
68
|
+
return {
|
|
69
|
+
tool: t,
|
|
70
|
+
...(v.version ? { version: v.version } : {}),
|
|
71
|
+
installed: v.installed,
|
|
72
|
+
};
|
|
73
|
+
});
|
|
74
|
+
return {
|
|
75
|
+
...(state.current ? { profileName: state.current } : {}),
|
|
76
|
+
profileCount: profiles.length,
|
|
77
|
+
...(permsTier ? { permsTier } : {}),
|
|
78
|
+
statuslineInstalled,
|
|
79
|
+
toolsInstalled,
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
/** 渲染状态行(横幅下方一行) */
|
|
83
|
+
export function renderStatusBar(s) {
|
|
84
|
+
const out = [];
|
|
85
|
+
// 左边:profile + 档位 + 状态栏
|
|
86
|
+
const pieces = [];
|
|
87
|
+
if (s.profileName) {
|
|
88
|
+
pieces.push(`${ansis.dim('profile')} ${ansis.cyan(s.profileName)}`);
|
|
89
|
+
}
|
|
90
|
+
else {
|
|
91
|
+
pieces.push(ansis.dim('profile (未设置)'));
|
|
92
|
+
}
|
|
93
|
+
if (s.permsTier) {
|
|
94
|
+
const c = s.permsTier === 'safe' ? ansis.green : s.permsTier === 'standard' ? ansis.cyan : ansis.yellow;
|
|
95
|
+
pieces.push(`${ansis.dim('perms')} ${c(s.permsTier)}`);
|
|
96
|
+
}
|
|
97
|
+
pieces.push(`${ansis.dim('statusline')} ${s.statuslineInstalled ? ansis.green('●') : ansis.gray('○')}`);
|
|
98
|
+
out.push(` ${pieces.join(' · ')}`);
|
|
99
|
+
// 右边:工具版本一行
|
|
100
|
+
const toolPieces = s.toolsInstalled.map((t) => {
|
|
101
|
+
const meta = TOOLS[t.tool];
|
|
102
|
+
if (!t.installed)
|
|
103
|
+
return ansis.gray(`${meta.displayName}: 未装`);
|
|
104
|
+
const ver = t.version ? ansis.green(`v${t.version}`) : ansis.yellow('?');
|
|
105
|
+
return `${ansis.dim(meta.displayName)} ${ver}`;
|
|
106
|
+
});
|
|
107
|
+
out.push(` ${toolPieces.join(' · ')}`);
|
|
108
|
+
return out;
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* 把绝对路径压短:home 目录显示为 ~。
|
|
112
|
+
* 留作未来用——目前 banner/menu 没用到,但放这里集中。
|
|
113
|
+
*/
|
|
114
|
+
export function shortenPath(p) {
|
|
115
|
+
const h = homedir();
|
|
116
|
+
if (p === h)
|
|
117
|
+
return '~';
|
|
118
|
+
if (p.startsWith(`${h}/`))
|
|
119
|
+
return `~/${p.slice(h.length + 1)}`;
|
|
120
|
+
return p;
|
|
121
|
+
}
|
|
122
|
+
//# sourceMappingURL=banner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"banner.js","sourceRoot":"","sources":["../../src/core/banner.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ccjk",
|
|
3
|
-
"version": "15.
|
|
4
|
-
"description": "Clavue / Claude Code
|
|
3
|
+
"version": "15.7.0",
|
|
4
|
+
"description": "Clavue / Claude Code / Codex 的本地配置 CLI — profile 切换、权限档位、状态栏、MCP、版本管理,一条命令搞定。",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
7
7
|
"ccjk": "./dist/cli.js"
|
|
@@ -31,7 +31,10 @@
|
|
|
31
31
|
"anthropic",
|
|
32
32
|
"ai-coding",
|
|
33
33
|
"developer-tools",
|
|
34
|
-
"config"
|
|
34
|
+
"config",
|
|
35
|
+
"profile",
|
|
36
|
+
"statusline",
|
|
37
|
+
"permissions"
|
|
35
38
|
],
|
|
36
39
|
"author": {
|
|
37
40
|
"name": "CCJK Team",
|