ccjk 16.0.7 → 16.3.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.
Files changed (69) hide show
  1. package/README.md +72 -316
  2. package/dist/chunks/claude-code-config-manager.mjs +28 -7
  3. package/dist/chunks/claude-code-incremental-manager.mjs +2 -2
  4. package/dist/chunks/codex-config-switch.mjs +3 -3
  5. package/dist/chunks/codex-presets.mjs +98 -0
  6. package/dist/chunks/codex-provider-manager.mjs +4 -4
  7. package/dist/chunks/codex-runtime.mjs +246 -0
  8. package/dist/chunks/codex-uninstaller.mjs +2 -2
  9. package/dist/chunks/commands.mjs +1 -1
  10. package/dist/chunks/features.mjs +12 -12
  11. package/dist/chunks/simple-config.mjs +485 -130
  12. package/dist/cli.mjs +1730 -760
  13. package/dist/i18n/locales/en/clean.json +24 -0
  14. package/dist/i18n/locales/en/codex.json +24 -1
  15. package/dist/i18n/locales/en/configuration.json +20 -12
  16. package/dist/i18n/locales/en/hub.json +30 -0
  17. package/dist/i18n/locales/en/menu.json +30 -0
  18. package/dist/i18n/locales/en/workflow.json +13 -1
  19. package/dist/i18n/locales/zh-CN/clean.json +24 -0
  20. package/dist/i18n/locales/zh-CN/codex.json +24 -1
  21. package/dist/i18n/locales/zh-CN/configuration.json +20 -12
  22. package/dist/i18n/locales/zh-CN/hub.json +30 -0
  23. package/dist/i18n/locales/zh-CN/menu.json +30 -0
  24. package/dist/i18n/locales/zh-CN/workflow.json +13 -1
  25. package/dist/index.d.mts +3 -1
  26. package/dist/index.d.ts +3 -1
  27. package/dist/index.mjs +1 -1
  28. package/dist/shared/{ccjk.BSLlI-JL.mjs → ccjk.TC1_-qhV.mjs} +1 -1
  29. package/package.json +1 -1
  30. package/templates/common/output-styles/en/agents-md-baseline.md +28 -0
  31. package/templates/common/output-styles/en/plan-first.md +30 -0
  32. package/templates/common/output-styles/en/surgical-diff.md +27 -0
  33. package/templates/common/output-styles/en/verify-and-ship.md +31 -0
  34. package/templates/common/output-styles/zh-CN/agents-md-baseline.md +28 -0
  35. package/templates/common/output-styles/zh-CN/plan-first.md +30 -0
  36. package/templates/common/output-styles/zh-CN/surgical-diff.md +27 -0
  37. package/templates/common/output-styles/zh-CN/verify-and-ship.md +31 -0
  38. package/templates/common/workflow/bmad/en/bmad-init.md +275 -0
  39. package/templates/common/workflow/bmad/zh-CN/bmad-init.md +275 -0
  40. package/templates/common/workflow/codeReview/en/code-review.md +34 -0
  41. package/templates/common/workflow/codeReview/zh-CN/code-review.md +34 -0
  42. package/templates/common/workflow/continuousDelivery/en/continuous-delivery.md +628 -0
  43. package/templates/common/workflow/continuousDelivery/zh-CN/continuous-delivery.md +628 -0
  44. package/templates/common/workflow/essential/en/agents/ccjk-config-agent.md +187 -0
  45. package/templates/common/workflow/essential/en/agents/ccjk-mcp-agent.md +191 -0
  46. package/templates/common/workflow/essential/en/agents/ccjk-skill-agent.md +249 -0
  47. package/templates/common/workflow/essential/en/agents/ccjk-workflow-agent.md +277 -0
  48. package/templates/common/workflow/essential/en/agents/get-current-datetime.md +29 -0
  49. package/templates/common/workflow/essential/en/agents/init-architect.md +115 -0
  50. package/templates/common/workflow/essential/en/agents/planner.md +116 -0
  51. package/templates/common/workflow/essential/en/agents/teamagent.md +102 -0
  52. package/templates/common/workflow/essential/en/agents/ui-ux-designer.md +91 -0
  53. package/templates/common/workflow/essential/en/feat.md +92 -0
  54. package/templates/common/workflow/essential/en/init-project.md +53 -0
  55. package/templates/common/workflow/essential/zh-CN/agents/get-current-datetime.md +29 -0
  56. package/templates/common/workflow/essential/zh-CN/agents/init-architect.md +115 -0
  57. package/templates/common/workflow/essential/zh-CN/agents/planner.md +116 -0
  58. package/templates/common/workflow/essential/zh-CN/agents/teamagent.md +102 -0
  59. package/templates/common/workflow/essential/zh-CN/agents/ui-ux-designer.md +91 -0
  60. package/templates/common/workflow/essential/zh-CN/feat.md +315 -0
  61. package/templates/common/workflow/essential/zh-CN/init-project.md +53 -0
  62. package/templates/common/workflow/interview/en/interview.md +67 -0
  63. package/templates/common/workflow/interview/zh-CN/interview.md +67 -0
  64. package/templates/common/workflow/linearMethod/en/linear-method.md +651 -0
  65. package/templates/common/workflow/linearMethod/zh-CN/linear-method.md +750 -0
  66. package/templates/common/workflow/refactoringMaster/en/refactoring-master.md +516 -0
  67. package/templates/common/workflow/refactoringMaster/zh-CN/refactoring-master.md +810 -0
  68. package/templates/common/workflow/specFirstTDD/en/spec-first-tdd.md +364 -0
  69. package/templates/common/workflow/specFirstTDD/zh-CN/spec-first-tdd.md +364 -0
package/README.md CHANGED
@@ -1,8 +1,6 @@
1
1
  # ccjk
2
2
 
3
- > Clavue / Claude Code / Codex / Grok CLI 的统一专业配置工具。所有工具采用完全一致的配置体验(API Key + Base URL + 模型选择),profile 管理、权限策略一站式搞定。ccjk 统一交互设计,让配置简单高效、无例外。
4
-
5
- **核心亮点**:Grok CLI 配置已与 Codex、Clavue、Claude Code 完全统一,无任何例外。一次配置,多工具通用。
3
+ > **Clavue / Claude Code / Codex / Grok CLI 的医生 + 快捷操作员** —— 扫描本地配置健康度,经确认后一键写入 API、MCP、模型与工作流。不替代原生工具写代码,不碰 agent runtime。
6
4
 
7
5
  [![npm](https://img.shields.io/npm/v/ccjk.svg)](https://www.npmjs.com/package/ccjk)
8
6
  [![license](https://img.shields.io/npm/l/ccjk.svg)](./LICENSE)
@@ -16,356 +14,114 @@ npm install -g ccjk
16
14
 
17
15
  升级:`npm install -g ccjk@latest`
18
16
 
19
- 5 分钟上手 → [QUICKSTART.md](./docs/QUICKSTART.md)
20
-
21
- ## ccjk 能干什么
22
-
23
- | 场景 | 命令 |
24
- |---|---|
25
- | 第一次装 ccjk 配置零基础 | `ccjk onboard`(无 profile 时自动跑) |
26
- | 第一次配 API key | `ccjk init` |
27
- | 装机后想一键配置好 | `ccjk workflow run starter` |
28
- | 写代码 / 闲聊切换思考强度 | `ccjk mode use code` / `ccjk mode use chat` |
29
- | 多个 API key 之间切换(GLM/Kimi/Anthropic/...) | `ccjk use` |
30
- | 想知道 API 通不通 / 多快 | `ccjk probe` / `ccjk bench` |
31
- | 不想每次都点确认权限 | `ccjk perms standard` |
32
- | 看不到当前模型/用量 | `ccjk statusline-install` |
33
- | settings.json 出问题 | `ccjk doctor --fix` |
34
- | CI 集成 / 脚本检测配置 drift | `ccjk doctor --json` |
35
- | 装 MCP 服务(context7、serena、playwright...) | `ccjk mcp` |
36
- | 看哪个工具该升级了 | `ccjk tools --check-updates` |
37
- | 写入出错想还原 | `ccjk rollback` |
38
- | 跨机器迁移配置 | `ccjk profile export` / `import` |
39
- | 已经手配过 settings.json 想纳入管理 | `ccjk migrate` |
40
- | 两个 profile 字段对比 | `ccjk profile-diff <a> <b>` |
41
- | 不想记命令 | `ccjk`(交互菜单) |
42
- | 想一眼看全配置状态 | `ccjk status` |
43
-
44
- ## 命令一览
45
-
46
- ### 快速开始
47
-
48
- | 命令 | 用途 |
49
- |---|---|
50
- | `ccjk workflow ls` | 列出可用工作流(starter / team-import / reset-soft / dev-ready) |
51
- | `ccjk workflow run [id]` | **跑工作流**:按顺序执行多个 ccjk 命令(每步单独确认) |
52
- | `ccjk mode ls` | 列出可用对话模式(code / chat / fast / deep) |
53
- | `ccjk mode use [name]` | **切换对话模式**:thinking / effort 一键档位(同步 Claude+Codex) |
54
- | `ccjk mode show [name]` | 查看模式详情(不带参=当前) |
55
- | `ccjk mode add [name]` | 新建自定义模式(基于内置模式复制+改) |
56
-
57
- ### 配置 API(init / use / profile)
58
-
59
- | 命令 | 用途 |
60
- |---|---|
61
- | `ccjk init` | 配 API:写 `~/.claude/settings.json` 的 env,并自动保存为 profile |
62
- | `ccjk use [name]` | 一键切换 profile(不带参=交互选) |
63
- | `ccjk migrate` | 反向导入:把已配好的 settings.json 抽成 profile(不动 settings 本身) |
64
- | `ccjk profile ls` / `show` / `rm` | profile 列表 / 详情 / 删除 |
65
- | `ccjk profile copy <from> <to>` | 基于现有 profile 复制(可选改 apiKey/baseUrl/model) |
66
- | `ccjk profile rename <old> <new>` | 重命名 profile |
67
- | `ccjk profile-diff <a> <b>` | 两个 profile 字段差异对比(`--json` CI 用) |
68
- | `ccjk profile export` | 导出 profile 为 JSON 包(迁移 / 团队共享) |
69
- | `ccjk profile import <file>` | 从 JSON 包导入 profile |
70
- | `ccjk probe [profile]` | 真实 HTTP 探活,看 baseUrl 通不通(`--json` CI 用) |
71
- | `ccjk bench [profile]` | 性能基准(TTFT / 吞吐),默认 3 run 取平均(`--json` CI 用) |
72
-
73
- ### 权限档位(perms)
74
-
75
- | 命令 | 用途 |
76
- |---|---|
77
- | `ccjk perms [tier]` | 一键设权限档位(`safe` / `standard` / `yolo`),同步 3 个工具 |
78
- | `ccjk perms-show` | 查看当前各工具的权限档位状态 |
79
-
80
- ### MCP 服务
81
-
82
- | 命令 | 用途 |
83
- |---|---|
84
- | `ccjk mcp` | 选装预设 MCP 服务(交互勾选) |
85
- | `ccjk mcp-ls` | 列出已安装的 MCP |
86
- | `ccjk mcp-add <name>` | 添加自定义 MCP 服务 |
87
- | `ccjk mcp-rm [name]` | 卸载 MCP 服务 |
17
+ ## 30 秒看懂
88
18
 
89
- ### 状态栏(statusline)
19
+ | 角色 | 做什么 | 怎么用 |
20
+ |---|---|---|
21
+ | **医生** | 只读扫描脏 MCP、坏 Skill、冗余 prompt、配置风险 | `ccjk clean`、菜单 **H** 医生中心 |
22
+ | **操作员** | 备份后写入 API / MCP / 模型 / 工作流 | `ccjk init`、菜单 **W** 快捷向导 |
90
23
 
91
- | 命令 | 用途 |
92
- |---|---|
93
- | `ccjk statusline-install` | 安装状态栏,显示模型 / 目录 / context 用量 / 今日调用 / 速率 |
94
- | `ccjk statusline-uninstall` | 卸载状态栏 |
24
+ 启动交互菜单(推荐入口):
95
25
 
96
- ### 体检 / 还原
26
+ ```bash
27
+ ccjk
28
+ ```
97
29
 
98
- | 命令 | 用途 |
99
- |---|---|
100
- | `ccjk doctor` | 检查 settings.json 的常见配置问题 |
101
- | `ccjk doctor --fix` | 自动修可修的问题(修改前备份) |
102
- | `ccjk rollback` | 从备份还原 settings.json / config.toml |
30
+ 主菜单按 **操作员 / 医生 / 跨工具 / CCJK** 分区;按 **W** 进快捷向导,按 **H** 进医生中心。
103
31
 
104
- ### 工具版本管理
32
+ ## 常见场景
105
33
 
106
- | 命令 | 用途 |
34
+ | 场景 | 命令 / 操作 |
107
35
  |---|---|
108
- | `ccjk tools` | 查看 Clavue / Claude Code / Codex / Grok 本地版本 |
109
- | `ccjk tools --check-updates` | 加查 npm latest,标记 outdated |
110
- | `ccjk install [tool]` | 安装代码工具(`--all` 装全部缺失的) |
111
- | `ccjk update [tool]` | 升级代码工具到最新版(`--all` 全部 outdated) |
36
+ | 第一次配置某个工具 | `ccjk init -T codex`(或 `clavue` / `claude-code` / `grok`) |
37
+ | Codex 干净起步 / 日常优化 | 菜单 **W** 完整初始化(预设:干净 / 优化 / 自定义) |
38
+ | 环境脏了想清理 | `ccjk clean` 或菜单 **H** 智能清理 |
39
+ | 彻底重置 Codex 再初始化 | 菜单 **W** 重置后初始化 |
40
+ | API 通不通 | `ccjk probe` |
41
+ | 切换 Codex API 提供商 | `ccjk config-switch` |
42
+ | Grok / Reasonix 状态与启动 | `ccjk grok` / `ccjk reasonix` |
43
+ | 检查工具版本更新 | `ccjk check-updates` |
112
44
 
113
- ### 其他
45
+ ## CLI 命令
114
46
 
115
47
  | 命令 | 用途 |
116
48
  |---|---|
117
49
  | `ccjk` | 交互菜单(默认) |
118
- | `ccjk status` | **一眼看全**:profile / perms / mode / 工具版本 / MCP / 工作流 |
119
- | `ccjk completion <shell>` | 生成 bash/zsh/fish 补全脚本 |
120
- | `ccjk detect` | 列出已安装的代码工具 |
121
- | `ccjk git-install` | 安装 `/ccjk:git-commit` 等 slash 命令模板 |
122
-
123
- ---
124
-
125
- ## 详解
50
+ | `ccjk init` | 完整初始化(API、MCP、模型、工作流、记忆) |
51
+ | `ccjk clean` | 环境清理:脏 MCP、坏 Skills、冗余 prompts |
52
+ | `ccjk clean --purge-all` | 全部清理(删前备份 Codex 配置) |
53
+ | `ccjk clean -s` | 非交互,仅清理高置信度项 |
54
+ | `ccjk probe` | HTTP 探活当前 API |
55
+ | `ccjk bench` | 轻量延迟基准 |
56
+ | `ccjk config-switch` | 切换 Codex provider / Claude 配置 |
57
+ | `ccjk update` | 仅更新工作流与记忆文档 |
58
+ | `ccjk check-updates` | 检查并更新 Claude Code / Codex / CCR |
59
+ | `ccjk grok [profile]` | Grok CLI 状态与 profile 启动 |
60
+ | `ccjk reasonix [profile]` | Reasonix 伴侣:状态与启动 |
61
+ | `ccjk uninstall` | 卸载 CCJK 管理的配置 |
62
+ | `ccjk ccr` | Claude Code Router 配置 |
63
+ | `ccjk ccu` | Claude Code 用量分析 |
64
+
65
+ 工具别名:`-T cv`(Clavue)、`-T cc`(Claude Code)、`-T cx`(Codex)、`-T gk`(Grok)。
126
66
 
127
- ### Workflow:快速工作流
128
-
129
- 把多个 ccjk 命令串起来一键跑,省去你按顺序敲。每步都会单独问你"执行 / 跳过 / 中止",不会偷偷做事。
130
-
131
- | 工作流 | 步骤 |
132
- |---|---|
133
- | `starter` | 配 API → perms standard → statusline-install → 装常用 MCP(可选) |
134
- | `team-import` | 导入 profile 包 → 切到该 profile → perms standard → doctor --fix |
135
- | `reset-soft` | 卸 statusline → 切到 perms safe |
136
- | `dev-ready` | 切 code 对话模式 → perms standard → 装 git slash 命令 → doctor --fix |
137
-
138
- ```bash
139
- ccjk workflow # 列出全部
140
- ccjk workflow run starter # 直接跑 starter
141
- ccjk workflow run # 交互选
142
- ```
143
-
144
- 工作流定义存在代码里,未来会支持 `~/.ccjk/workflows/<id>.json` 加载用户自定义(数据结构已就位)。
145
-
146
- ### Mode:对话模式
147
-
148
- 把 Claude/Clavue 的 `thinking` 设置和 Codex 的 `model_reasoning_effort` 抽象成一个统一档位,一键同步两个工具。
149
-
150
- | 模式 | Claude thinking | Codex effort | 适用 |
151
- |---|---|---|---|
152
- | `code` | on, budget 16k | high | 写代码、调 bug、重构 |
153
- | `chat` | off | medium | 答疑、解释概念、随便聊 |
154
- | `fast` | off | low | 简单查询、小修改、想立刻拿到结果 |
155
- | `deep` | on, budget 32k | high | 架构设计、复杂 debug、多角度推理 |
156
-
157
- ```bash
158
- ccjk mode ls # 列出全部模式(标记当前)
159
- ccjk mode use code # 切到 code 模式(同步 Claude + Codex)
160
- ccjk mode show # 看当前模式详情
161
- ccjk mode add fast2 --base fast --thinking off --effort low # 自定义模式
162
- ```
163
-
164
- 写到工具的**原生字段**(`thinking`、`model_reasoning_effort`),卸载 ccjk 后配置依然有效。需要重启 Claude Code / Codex 才能生效。
165
-
166
- 自定义模式存在 `~/.ccjk/modes/<id>.json`,可手动编辑。同名时覆盖内置。
167
-
168
- ### Profile:多 API 切换
169
-
170
- `ccjk init` 配完 API 默认会问"保存为 profile?"。之后 `ccjk use` 可以在多个 profile 之间一键切换:
171
-
172
- ```bash
173
- ccjk init -t clavue -p glm --api-key sk-xxx --profile work -y
174
- ccjk init -t clavue -p kimi --api-key sk-yyy --profile free -y
175
-
176
- ccjk use # 交互选 work / free
177
- ccjk use free # 直接切到 free
178
- ccjk profile ls # 看当前用的是哪个
179
- ```
180
-
181
- 切换后需重启 Claude Code 才能生效(settings.json 是启动时读的)。
182
-
183
- Profile 存储在 `~/.ccjk/profiles/<name>.json`,当前激活的记录在 `~/.ccjk/state.json`。
184
-
185
- #### 导出 / 导入:跨机器迁移
186
-
187
- ```bash
188
- ccjk profile export # 交互勾选
189
- ccjk profile export -n work free -o team.json -y # 直接导出 work + free
190
- ccjk profile export --redact -o template.json -y # 抹去 API key("模板")
191
-
192
- # 在另一台机器
193
- ccjk profile import team.json # 同名时交互问跳过/覆盖/重命名
194
- ccjk profile import team.json --conflict skip -y # 全部 skip 已有的
195
- ```
196
-
197
- 包是简单 JSON(schema=1),可以手动编辑。带 key 的包**等同于凭证文件**,请妥善保管或用 `--redact` 导出无 key 模板再单独传 key。
198
-
199
- ### Perms:一键档位授权
200
-
201
- 一条命令把 Clavue / Claude Code / Codex 的权限同步到同一档位,减少每次操作都要点确认的烦躁。(Grok CLI 走 OAuth 自管,不参与 perms 同步。)
67
+ ## 支持的工具
202
68
 
203
- | 档位 | 适合 | Claude / Clavue | Codex |
204
- |---|---|---|---|
205
- | `safe` | 浏览代码、新手 | 仅放行只读(Read/Grep/...) | `approval_policy=untrusted`, `sandbox_mode=read-only` |
206
- | `standard`(推荐) | 日常开发 | + git/npm/pnpm/python/ls/cat 等高频命令 | `approval_policy=on-failure`, `sandbox_mode=workspace-write` |
207
- | `yolo` | 可信项目放飞 | `Bash(*)` + `allowUnsandboxedCommands=true` | `approval_policy=never`, `sandbox_mode=workspace-write` |
69
+ | 工具 | 配置根目录 | ccjk 能力 |
70
+ |---|---|---|
71
+ | **Clavue** | `~/.clavue/` | 医生 + 操作员:init / MCP / 模型 / 工作流 / 权限 / 清理 |
72
+ | **Claude Code** | `~/.claude/` | 同上 |
73
+ | **Codex** | `~/.codex/`(`CODEX_HOME`) | 同上 + 三端共用配置(见下) |
74
+ | **Grok CLI** | `~/.grok/` + `~/.ccjk/` profile | 医生(清理 skills)+ 轻量操作员(profile 启动) |
208
75
 
209
- 不论哪一档,都强制写入 `deny`:`rm -rf /`、`git push --force`、`npm publish`、`sudo` 等不可逆 / 高危命令。
76
+ ccjk 自身配置只在 `~/.ccjk/`,**绝不混入**各工具目录。
210
77
 
211
- ```bash
212
- ccjk perms # 交互选档位(推荐)
213
- ccjk perms standard # 直接应用 standard 到全部 3 个工具
214
- ccjk perms safe --tools clavue,claude-code # 只作用于这两个
215
- ccjk perms yolo --reset # --reset 会清空原 allow 后再写
216
- ccjk perms-show # 看三个工具当前各是哪档
217
- ```
78
+ ### Codex:CLI + 桌面 App + IDE 扩展
218
79
 
219
- 合并策略:
220
- - `allow`:默认 append + dedupe,保护用户自定义白名单。`--reset` 强制覆盖。
221
- - `deny`:始终覆盖,确保危险命令一定被拦。
80
+ OpenAI 官方设计下,三端**共用同一份** `config.toml`:
222
81
 
223
- ### Statusline:底部状态栏
82
+ - 默认路径:`~/.codex/config.toml`
83
+ - 可用环境变量 `CODEX_HOME` 覆盖配置根
84
+ - `~/Library/Application Support/Codex`(macOS)等是 Electron 运行时缓存,**不是**配置目录
224
85
 
225
- 显示模型、当前目录、context 用量、今日 API 调用次数、tokens 速率。
86
+ ccjk 写入配置后:
226
87
 
227
- ```bash
228
- ccjk statusline-install # 写入 settings.statusLine(重启 Claude Code 生效)
229
- ccjk statusline-uninstall # 卸载
230
- ```
88
+ - **CLI / IDE 扩展**:通常即时生效
89
+ - **桌面 App**:若正在运行,需**完全退出后重新打开**
231
90
 
232
- 效果(一行):
91
+ 医生中心会显示三端检测状态,并对第三方 provider + `features.goals` / `multi_agent` 给出配置风险提示。
233
92
 
234
- ```
235
- Sonnet 4.5 1M │ 📁 ccjk │ ⚡ 4.5% 45.0k │ 12 calls · 1.5k tok/m
236
- ```
93
+ ### Codex 初始化预设
237
94
 
238
- 字段含义:
239
- - `Sonnet 4.5 1M` — 模型名 + context window 大小(1M / 200k)
240
- - `📁 ccjk` — 当前工作目录的 basename(home 显示为 `~`)
241
- - `⚡ 4.5% 45.0k` — context 已用百分比 + 当前 token 数
242
- - `12 calls` — 今日总 API 调用数(聚合所有 transcripts)
243
- - `1.5k tok/m` 或 `80 tok/s` — 今日产出速率(output tokens / 活跃秒数)
244
-
245
- 实现:扫 `~/.claude/projects/*/*.jsonl` 当天 mtime 文件,读 `message.usage` 聚合。错误一律 swallow,不会让 Claude Code UI 报红。
246
-
247
- ### Doctor:体检 + 自动修复
248
-
249
- ```bash
250
- ccjk doctor # 列出问题,标记哪些可自动修
251
- ccjk doctor --fix # 自动修可修的(修改前备份)
252
- ccjk doctor --fix -y # 跳过确认
253
- ```
254
-
255
- | 规则 | 严重度 | 自动修 | 说明 |
95
+ | 预设 | AGENTS | 工作流 | MCP |
256
96
  |---|---|---|---|
257
- | `model-overrides-env` | error | | 顶层 `settings.model` 会覆盖 `env.ANTHROPIC_MODEL` |
258
- | `duplicate-auth` | warn | | 同时存在 `API_KEY` 和 `AUTH_TOKEN`(保留 AUTH_TOKEN,删 API_KEY) |
259
- | `missing-credentials` | error | | 设了 `BASE_URL` 但缺凭证 → 跑 `ccjk init` |
260
- | `invalid-base-url` | error | ✗ | URL 格式不合法 → 跑 `ccjk init` |
261
- | `hook-bloat` | warn | ✗ | 单个 hook 注册超过 5 个处理器(人工审查) |
262
-
263
- ### Rollback:从备份还原
264
-
265
- 每次 `init` / `mcp` / `perms` / `doctor --fix` / `mcp-add/rm` / `statusline-install` 写入前都会自动备份到 `<file>.bak-<ISO时间戳>`。
266
-
267
- ```bash
268
- ccjk rollback # 列所有备份,按时间倒序
269
- ccjk rollback -t clavue # 只看一个工具的备份
270
- ```
271
-
272
- 还原前会再备份一份当前状态,所以**还原本身也可还原**。
273
-
274
- ### Tools / Install / Update:版本管理
275
-
276
- 三个开发工具的本地版本、npm 最新版、安装、升级——都在 ccjk 里。
277
-
278
- ```bash
279
- ccjk tools # 看本地版本
280
- ccjk tools --check-updates # 加查 npm latest
281
-
282
- ccjk install # 交互选要装的工具
283
- ccjk install codex # 直接装 Codex
284
- ccjk install --all # 装全部缺失的
285
-
286
- ccjk update # 交互选 outdated 的工具
287
- ccjk update claude-code # 直接升级 Claude Code
288
- ccjk update --all # 升级所有 outdated
289
- ccjk update --dry-run # 只显示命令不执行
290
- ```
291
-
292
- 输出示例:
293
-
294
- ```
295
- Clavue 8.9.2 (latest)
296
- Claude Code 2.1.138 (latest)
297
- Codex 0.128.0 → 0.130.0 可升级
298
- ```
299
-
300
- 实现是 `npm install -g <pkg>` / `npm install -g <pkg>@<latest>`,命令完整列出后等用户确认。npm 因权限失败时会输出建议的 `sudo` 命令让用户自己跑,不假装成功。
301
-
302
- ### 非交互模式
303
-
304
- 适合脚本 / CI / 装机:
305
-
306
- ```bash
307
- ccjk init -t clavue -p glm --api-key sk-xxx --profile work -y
308
- ccjk perms standard -y
309
- ccjk mcp -s context7 serena -y
310
- ccjk mcp-add my-server --command npx --args "-y @scope/pkg" -y
311
- ccjk doctor --fix -y
312
- ccjk statusline-install -y
313
- ccjk update --all -y
314
- ccjk git-install --scope user -y
315
- ```
316
-
317
- ---
318
-
319
- ## 支持的工具
320
-
321
- | 工具 | 配置目标 | 范围 |
322
- |---|---|---|
323
- | Clavue | `~/.claude/settings.json` | API / Profile / Perms / MCP / Statusline / Doctor / Rollback |
324
- | Claude Code | `~/.claude/settings.json` | API / Profile / Perms / MCP / Statusline / Doctor / Rollback |
325
- | Codex | `~/.codex/config.toml` | Perms / Detect / Install / Update(API 配置请直接编辑 config.toml) |
326
- | Grok CLI | OAuth(`~/.grok/auth.json`) | Detect / Status / 使用指引(`ccjk grok`);登录走 `grok login`,不参与 ccjk profile/perms 同步 |
327
-
328
- ### 内置 API Provider
329
-
330
- `glm` / `kimi` / `minimax` / `anthropic` / `custom`
97
+ | **干净** | 不写 | 不装 | 不装 |
98
+ | **优化** | 工程基线 | 默认工程流 | context7 |
99
+ | **自定义** | 用户自选 | 用户自选 | 用户自选 |
331
100
 
332
101
  ## 设计原则
333
102
 
334
- - **配置工具就是配置工具**。不做 brain、orchestrator、sandbox、dashboard 这类东西。
335
- - **不主动写代码**。不写 `~/.claude/CLAUDE.md`,不装 hooks,不开后台进程。
336
- - **可还原**。所有写入前都备份;`ccjk rollback` 能找回任何旧版本。
337
- - **可重复**。所有交互式命令都有非交互参数(`-y`、`--profile`、`--tools`、`--services`...),适合脚本。
338
- - **不偷跑命令**。`install` / `update` 会显示完整命令并等用户确认。
339
-
340
- ## 从 v14 升级
103
+ - **配置工具就是配置工具** —— 不做 brain、orchestrator、后台守护进程
104
+ - **不主动写代码** —— 不在运行时偷偷注入 hook 或命令
105
+ - **备份先行** —— 任何写盘前产生 `.bak-<ts>` 备份
106
+ - **可重复** —— `init -s`、`clean -s`、`clean --purge-all` 等支持脚本化
341
107
 
342
- v15 是从零重写的精简版本,命令集和行为都和 v14.x 不兼容:
343
-
344
- - v14 的子命令(brain/sandbox/teleport/cloud-sync 等)在 v15 **不存在**。
345
- - v14 在 `~/.claude/CLAUDE.md` 注入的 "Smart Assistant Mode" 在 v15 **不会再写入**。如需手动清理旧版残留,删除该文件中相关段落即可。
346
- - 如果你只用 v14 的 init/mcp/doctor/git 等核心功能,直接 `npm install -g ccjk@latest` 升级即可。
347
- - 需要 v14 的扩展能力,请固定旧版本:`npm install -g ccjk@14`。
108
+ 产品细节见 [PRODUCT.md](./PRODUCT.md),架构见 [ARCHITECTURE.md](./ARCHITECTURE.md)。
348
109
 
349
110
  ## 开发
350
111
 
351
112
  ```bash
352
113
  pnpm install
353
- pnpm typecheck # TypeScript 检查
354
- pnpm test # 跑全部测试(>150 测试)
355
- pnpm lint # ESLint
356
- pnpm build # tsc 出 dist/
114
+ pnpm typecheck
115
+ pnpm test # 2500+ tests
116
+ pnpm lint
117
+ pnpm build
357
118
  ```
358
119
 
359
- CI 在每次 PR / push 到 main 时自动跑(Node 20 + 22 矩阵)。
360
-
361
- ### Shell 补全
362
-
363
120
  ```bash
364
- ccjk completion bash > /usr/local/etc/bash_completion.d/ccjk
365
- ccjk completion zsh > "${fpath[1]}/_ccjk" # 然后 compinit
366
- ccjk completion fish > ~/.config/fish/completions/ccjk.fish
121
+ # 冒烟:进入 Codex 菜单
122
+ echo '' | node dist/cli.mjs -T codex
367
123
  ```
368
124
 
369
125
  ## 许可
370
126
 
371
- [MIT](./LICENSE)
127
+ [MIT](./LICENSE)
@@ -1,6 +1,6 @@
1
1
  import dayjs from 'dayjs';
2
2
  import { join } from 'pathe';
3
- import { c as CCJK_CONFIG_FILE, C as CCJK_CONFIG_DIR, ax as ensureDir, ay as readDefaultTomlConfig, az as createDefaultTomlConfig, aA as exists, aB as readJsonConfig, aC as writeTomlConfig, ar as getActiveCodeTool, v as activeSettingsFile, aD as clearModelEnv, aE as normalizeClaudeFamilySettings, aF as copyFile } from './simple-config.mjs';
3
+ import { c as CCJK_CONFIG_FILE, C as CCJK_CONFIG_DIR, aC as ensureDir, aD as readDefaultTomlConfig, aE as createDefaultTomlConfig, az as exists, aF as readJsonConfig, aG as writeTomlConfig, at as getActiveCodeTool, w as activeSettingsFile, aH as clearModelEnv, aI as normalizeClaudeFamilySettings, aJ as copyFile } from './simple-config.mjs';
4
4
  import 'node:fs';
5
5
  import 'node:process';
6
6
  import 'ansis';
@@ -183,17 +183,17 @@ class ClaudeCodeConfigManager {
183
183
  * Apply profile settings to Claude Code runtime
184
184
  */
185
185
  static async applyProfileSettings(profile, codeTool) {
186
- const { ensureI18nInitialized, i18n } = await import('./simple-config.mjs').then(function (n) { return n.bp; });
186
+ const { ensureI18nInitialized, i18n } = await import('./simple-config.mjs').then(function (n) { return n.bF; });
187
187
  ensureI18nInitialized();
188
188
  const targetTool = codeTool ?? getActiveCodeTool();
189
189
  const settingsFile = activeSettingsFile(targetTool === "codex" || targetTool === "grok" ? "claude-code" : targetTool);
190
190
  try {
191
191
  if (!profile) {
192
- const { switchToOfficialLogin } = await import('./simple-config.mjs').then(function (n) { return n.bt; });
192
+ const { switchToOfficialLogin } = await import('./simple-config.mjs').then(function (n) { return n.bK; });
193
193
  switchToOfficialLogin(targetTool === "clavue" ? "clavue" : "claude-code");
194
194
  return;
195
195
  }
196
- const { readJsonConfig: readJsonConfig2, writeJsonConfig } = await import('./simple-config.mjs').then(function (n) { return n.br; });
196
+ const { readJsonConfig: readJsonConfig2, writeJsonConfig } = await import('./simple-config.mjs').then(function (n) { return n.bH; });
197
197
  const settings = readJsonConfig2(settingsFile) || {};
198
198
  if (!settings.env)
199
199
  settings.env = {};
@@ -206,7 +206,7 @@ class ClaudeCodeConfigManager {
206
206
  settings.env.ANTHROPIC_AUTH_TOKEN = profile.apiKey;
207
207
  delete settings.env.ANTHROPIC_API_KEY;
208
208
  } else if (profile.authType === "ccr_proxy") {
209
- const { readCcrConfig } = await import('./simple-config.mjs').then(function (n) { return n.bu; });
209
+ const { readCcrConfig } = await import('./simple-config.mjs').then(function (n) { return n.bL; });
210
210
  const ccrConfig = readCcrConfig();
211
211
  if (!ccrConfig) {
212
212
  throw new Error(i18n.t("ccr:ccrNotConfigured") || "CCR proxy configuration not found");
@@ -243,7 +243,28 @@ class ClaudeCodeConfigManager {
243
243
  const normalizedTool = targetTool === "clavue" ? "clavue" : "claude-code";
244
244
  normalizeClaudeFamilySettings(settings, { codeTool: normalizedTool });
245
245
  writeJsonConfig(settingsFile, settings);
246
- const { setPrimaryApiKey, addCompletedOnboarding } = await import('./simple-config.mjs').then(function (n) { return n.bs; });
246
+ if (normalizedTool === "clavue" && profile.baseUrl && profile.apiKey) {
247
+ try {
248
+ const { saveProviderProfile, generateProfileId, createModelRouting } = await import('./simple-config.mjs').then(function (n) { return n.bJ; });
249
+ const profileId = generateProfileId(profile.name || "ccjk-profile");
250
+ saveProviderProfile({
251
+ id: profileId,
252
+ name: profile.name || "ccjk-profile",
253
+ baseUrl: profile.baseUrl,
254
+ authType: profile.authType === "ccr_proxy" ? "api_key" : profile.authType,
255
+ apiKey: profile.apiKey,
256
+ modelRouting: createModelRouting({
257
+ primaryModel: profile.primaryModel,
258
+ haikuModel: profile.defaultHaikuModel,
259
+ sonnetModel: profile.defaultSonnetModel,
260
+ opusModel: profile.defaultOpusModel
261
+ }),
262
+ setAsActive: true
263
+ });
264
+ } catch {
265
+ }
266
+ }
267
+ const { setPrimaryApiKey, addCompletedOnboarding } = await import('./simple-config.mjs').then(function (n) { return n.bI; });
247
268
  setPrimaryApiKey(normalizedTool);
248
269
  addCompletedOnboarding(normalizedTool);
249
270
  if (shouldRestartCcr) {
@@ -604,7 +625,7 @@ class ClaudeCodeConfigManager {
604
625
  */
605
626
  static async syncCcrProfile() {
606
627
  try {
607
- const { readCcrConfig } = await import('./simple-config.mjs').then(function (n) { return n.bu; });
628
+ const { readCcrConfig } = await import('./simple-config.mjs').then(function (n) { return n.bL; });
608
629
  const ccrConfig = readCcrConfig();
609
630
  if (!ccrConfig) {
610
631
  await this.ensureCcrProfileExists(ccrConfig);
@@ -1,8 +1,8 @@
1
1
  import ansis from 'ansis';
2
2
  import inquirer from 'inquirer';
3
- import { aq as ensureI18nInitialized, ar as getActiveCodeTool, as as i18n, at as addNumbersToChoices, au as validateApiKey, av as promptBoolean } from './simple-config.mjs';
3
+ import { as as ensureI18nInitialized, at as getActiveCodeTool, au as i18n, av as addNumbersToChoices, aw as validateApiKey, ax as promptBoolean } from './simple-config.mjs';
4
4
  import { ClaudeCodeConfigManager } from './claude-code-config-manager.mjs';
5
- import { g as getClaudeFamilyRuntimeLabel } from '../shared/ccjk.BSLlI-JL.mjs';
5
+ import { g as getClaudeFamilyRuntimeLabel } from '../shared/ccjk.TC1_-qhV.mjs';
6
6
  import 'node:fs';
7
7
  import 'node:process';
8
8
  import 'node:child_process';
@@ -1,6 +1,6 @@
1
1
  import ansis from 'ansis';
2
2
  import inquirer from 'inquirer';
3
- import { aq as ensureI18nInitialized, aG as detectConfigManagementMode, as as i18n, at as addNumbersToChoices, av as promptBoolean, aB as readJsonConfig, l as CODEX_AUTH_FILE } from './simple-config.mjs';
3
+ import { as as ensureI18nInitialized, aK as detectConfigManagementMode, au as i18n, av as addNumbersToChoices, ax as promptBoolean, aF as readJsonConfig, m as CODEX_AUTH_FILE } from './simple-config.mjs';
4
4
  import { deleteProviders, addProviderToExisting, editExistingProvider } from './codex-provider-manager.mjs';
5
5
  import 'node:fs';
6
6
  import 'node:process';
@@ -155,7 +155,7 @@ async function handleAddProvider() {
155
155
  defaultValue: true
156
156
  });
157
157
  if (setAsDefault) {
158
- const { switchToProvider } = await import('./simple-config.mjs').then(function (n) { return n.by; });
158
+ const { switchToProvider } = await import('./simple-config.mjs').then(function (n) { return n.bQ; });
159
159
  const switched = await switchToProvider(provider.id);
160
160
  if (switched) {
161
161
  console.log(ansis.green(i18n.t("multi-config:profileSetAsDefault", { name: provider.name })));
@@ -330,7 +330,7 @@ ${i18n.t("codex:copyingProvider", { name: provider.name })}`));
330
330
  defaultValue: false
331
331
  });
332
332
  if (setAsDefault) {
333
- const { switchToProvider } = await import('./simple-config.mjs').then(function (n) { return n.by; });
333
+ const { switchToProvider } = await import('./simple-config.mjs').then(function (n) { return n.bQ; });
334
334
  const switched = await switchToProvider(copiedProvider.id);
335
335
  if (switched) {
336
336
  console.log(ansis.green(i18n.t("multi-config:profileSetAsDefault", { name: copiedProvider.name })));
@@ -0,0 +1,98 @@
1
+ import ansis from 'ansis';
2
+ import inquirer from 'inquirer';
3
+ import { as as ensureI18nInitialized, au as i18n, av as addNumbersToChoices, aO as CODEX_WORKFLOW_CONFIG_BASE } from './simple-config.mjs';
4
+ import 'node:fs';
5
+ import 'node:process';
6
+ import 'node:child_process';
7
+ import 'node:os';
8
+ import 'node:util';
9
+ import 'dayjs';
10
+ import 'pathe';
11
+ import 'node:url';
12
+ import 'inquirer-toggle';
13
+ import 'ora';
14
+ import 'tinyexec';
15
+ import 'semver';
16
+ import 'node:fs/promises';
17
+ import 'i18next';
18
+ import 'i18next-fs-backend';
19
+ import '@rainbowatcher/toml-edit-js';
20
+
21
+ const OPTIMIZED_MCP_SERVICES = ["context7"];
22
+ const CODEX_SETUP_PRESETS = {
23
+ clean: {
24
+ id: "clean",
25
+ systemPromptStyle: "none",
26
+ skipWorkflowInstall: true,
27
+ skipAgentsLanguageDirective: true,
28
+ mcpServices: false
29
+ },
30
+ optimized: {
31
+ id: "optimized",
32
+ systemPromptStyle: "agents-md-baseline",
33
+ skipWorkflowInstall: false,
34
+ skipAgentsLanguageDirective: false,
35
+ mcpServices: [...OPTIMIZED_MCP_SERVICES],
36
+ workflowNames: void 0
37
+ }
38
+ };
39
+ function getDefaultCodexWorkflowNames() {
40
+ ensureI18nInitialized();
41
+ return CODEX_WORKFLOW_CONFIG_BASE.filter((config) => config.defaultSelected).map((config) => i18n.t(`workflow:workflowOption.${config.id}`));
42
+ }
43
+ function applyCodexSetupPreset(presetId, options = {}) {
44
+ if (presetId === "custom")
45
+ return { ...options, setupPreset: "custom" };
46
+ const preset = CODEX_SETUP_PRESETS[presetId];
47
+ const workflowNames = preset.workflowNames ?? getDefaultCodexWorkflowNames();
48
+ return {
49
+ ...options,
50
+ setupPreset: presetId,
51
+ systemPromptStyle: preset.systemPromptStyle,
52
+ skipWorkflowInstall: preset.skipWorkflowInstall,
53
+ skipAgentsLanguageDirective: preset.skipAgentsLanguageDirective,
54
+ mcpServices: preset.mcpServices,
55
+ workflows: preset.skipWorkflowInstall ? [] : workflowNames,
56
+ skipPrompt: options.skipPrompt ?? false
57
+ };
58
+ }
59
+ function getCodexPresetChoices() {
60
+ ensureI18nInitialized();
61
+ return [
62
+ {
63
+ id: "clean",
64
+ name: i18n.t("codex:preset.clean.name"),
65
+ description: i18n.t("codex:preset.clean.description")
66
+ },
67
+ {
68
+ id: "optimized",
69
+ name: i18n.t("codex:preset.optimized.name"),
70
+ description: i18n.t("codex:preset.optimized.description")
71
+ },
72
+ {
73
+ id: "custom",
74
+ name: i18n.t("codex:preset.custom.name"),
75
+ description: i18n.t("codex:preset.custom.description")
76
+ }
77
+ ];
78
+ }
79
+ async function promptCodexSetupPreset() {
80
+ ensureI18nInitialized();
81
+ console.log(ansis.dim(`
82
+ ${i18n.t("codex:preset.intro")}
83
+ `));
84
+ const { preset } = await inquirer.prompt({
85
+ type: "list",
86
+ name: "preset",
87
+ message: i18n.t("codex:preset.selectPrompt"),
88
+ choices: addNumbersToChoices(getCodexPresetChoices().map((choice) => ({
89
+ name: `${choice.name} - ${ansis.gray(choice.description)}`,
90
+ value: choice.id,
91
+ short: choice.name
92
+ }))),
93
+ default: "optimized"
94
+ });
95
+ return preset ?? null;
96
+ }
97
+
98
+ export { CODEX_SETUP_PRESETS, OPTIMIZED_MCP_SERVICES, applyCodexSetupPreset, getCodexPresetChoices, getDefaultCodexWorkflowNames, promptCodexSetupPreset };