ccem 1.6.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 ADDED
@@ -0,0 +1,365 @@
1
+ # Claude Code Env Manager
2
+
3
+ 优雅的使用 Claude Code 🍷
4
+
5
+ 切换 API 服务商、配置权限模式、查看用量统计、安装 Skills。
6
+
7
+ ![Demo](./index.png)
8
+
9
+ ## 这工具干嘛的
10
+
11
+ 用 Claude Code 的人可能会遇到几个烦心事:
12
+
13
+ - 想用国产模型(GLM、KIMI、DeepSeek)但每次都要手动设置环境变量
14
+ - 每次执行命令都要点"允许",烦死了,但又不想用 `--dangerously-skip-permissions`
15
+ - 想知道这个月花了多少钱,但 Claude 没有用量统计界面
16
+
17
+ ccem 就是解决这些问题的。
18
+
19
+ ## 安装
20
+
21
+ ```bash
22
+ npm install -g ccem
23
+ # 或
24
+ pnpm add -g ccem
25
+ # 或直接跑
26
+ npx ccem
27
+ ```
28
+
29
+ ## 快速上手
30
+
31
+ ```bash
32
+ ccem # 进入交互菜单
33
+ ccem add kimi # 添加 KIMI 环境,自动填好 URL 和模型
34
+ ccem use kimi # 切换到 KIMI
35
+ ccem dev # 用开发模式启动 Claude Code
36
+ ```
37
+
38
+ ![Demo](./demo.png)
39
+
40
+ ---
41
+
42
+ ## 环境管理
43
+
44
+ ### 交互菜单
45
+
46
+ 运行 `ccem` 会看到一个菜单:
47
+
48
+ | 选项 | 干嘛用 |
49
+ |------|--------|
50
+ | Start Claude Code | 启动,如果设了默认权限模式会自动带上 |
51
+ | Switch Environment | 切换 API 环境 |
52
+ | Permission Mode | 选个权限模式再启动 |
53
+ | View Usage | 看用量和花费 |
54
+ | Set Default Mode | 设置默认权限模式 |
55
+
56
+ ### 命令
57
+
58
+ ```bash
59
+ ccem ls # 列出所有环境
60
+ ccem use <name> # 切换环境
61
+ ccem add <name> # 添加环境
62
+ ccem del <name> # 删除环境(official 删不掉)
63
+ ccem current # 当前用的哪个环境
64
+ ccem env # 输出 export 命令,配合 eval 用
65
+ ccem env --json # 输出 JSON
66
+ ccem run <command> # 带着环境变量跑命令
67
+ ```
68
+
69
+ ### 内置预设
70
+
71
+ 添加环境时可以选预设,省得自己填 URL:
72
+
73
+ | 预设 | Base URL | 模型 |
74
+ |------|----------|------|
75
+ | GLM(智谱) | `https://open.bigmodel.cn/api/anthropic` | glm-4.6 |
76
+ | KIMI(月之暗面) | `https://api.moonshot.cn/anthropic` | kimi-k2-thinking-turbo |
77
+ | MiniMax | `https://api.minimaxi.com/anthropic` | MiniMax-M2 |
78
+ | DeepSeek | `https://api.deepseek.com/anthropic` | deepseek-chat |
79
+
80
+ ### Shell 集成
81
+
82
+ `ccem use` 切换环境后,当前终端的环境变量不会自动更新。加这段到 `~/.zshrc` 或 `~/.bashrc`:
83
+
84
+ ```bash
85
+ ccem() {
86
+ command ccem "$@"
87
+ local exit_code=$?
88
+ if [[ $exit_code -eq 0 ]]; then
89
+ if [[ "$1" == "use" || -z "$1" ]]; then
90
+ eval "$(command ccem env)"
91
+ fi
92
+ fi
93
+ return $exit_code
94
+ }
95
+ ```
96
+
97
+ 加完跑一下 `source ~/.zshrc`。
98
+
99
+ ---
100
+
101
+ ## 权限模式
102
+
103
+ Claude Code 默认每个操作都要确认。用 `--dangerously-skip-permissions` 又太放飞。ccem 提供 6 种预设,在"什么都要确认"和"什么都不管"之间找个平衡。
104
+
105
+ ### 6 种模式
106
+
107
+ | 模式 | 图标 | 说明 | 什么时候用 |
108
+ |------|------|------|------------|
109
+ | yolo | 🔓 | 全部放开 | 自己的项目,完全信任 |
110
+ | dev | 💻 | 开发常用权限,屏蔽敏感文件 | 日常开发 |
111
+ | readonly | 👀 | 只能读不能改 | 看代码、学习 |
112
+ | safe | 🛡️ | 限制网络和修改 | 不熟悉的代码库 |
113
+ | ci | 🔧 | CI/CD 用 | 自动化流程 |
114
+ | audit | 🔍 | 只读 + 搜索 | 安全审计 |
115
+
116
+ ### 临时模式
117
+
118
+ 退出就还原,不改配置文件:
119
+
120
+ ```bash
121
+ ccem yolo # 放飞
122
+ ccem dev # 开发
123
+ ccem readonly # 只读
124
+ ccem safe # 安全
125
+ ccem ci # CI
126
+ ccem audit # 审计
127
+ ```
128
+
129
+ 实现方式是通过 `--allowedTools` 和 `--disallowedTools` 参数传给 Claude Code。
130
+
131
+ ### 永久模式
132
+
133
+ 写到 `.claude/settings.json`,下次启动还生效:
134
+
135
+ ```bash
136
+ ccem setup perms --yolo
137
+ ccem setup perms --dev
138
+ ccem setup perms --readonly
139
+ ccem setup perms --safe
140
+ ccem setup perms --ci
141
+ ccem setup perms --audit
142
+ ccem setup perms --reset # 恢复默认
143
+ ```
144
+
145
+ ### 默认模式
146
+
147
+ 设了默认模式后,交互菜单里点 "Start Claude Code" 会自动用这个模式:
148
+
149
+ ```bash
150
+ ccem setup default-mode --dev # 默认用开发模式
151
+ ccem setup default-mode --reset # 清掉默认设置
152
+ ccem setup default-mode # 看当前默认是啥
153
+ ```
154
+
155
+ ### 查看当前权限
156
+
157
+ ```bash
158
+ ccem --mode # 当前用的什么模式
159
+ ccem --list-modes # 列出所有模式
160
+ ```
161
+
162
+ ### 权限细节
163
+
164
+ <details>
165
+ <summary><b>dev 模式具体允许/禁止什么</b></summary>
166
+
167
+ **允许:**
168
+ - 文件:Read、Edit、Write、Glob、Grep、LSP、NotebookEdit
169
+ - 开发工具:npm、pnpm、yarn、bun、node、npx、git、tsc、tsx
170
+ - 质量工具:eslint、prettier、jest、vitest
171
+ - 其他:cargo、python、pip、go、make、cmake
172
+ - 常用命令:ls、cat、head、tail、find、wc、mkdir、cp、mv、touch
173
+ - WebSearch
174
+
175
+ **禁止:**
176
+ - 敏感文件:.env、.env.*、secrets/、*.pem、*.key、*credential*
177
+ - 危险命令:rm -rf、sudo、chmod、chown
178
+
179
+ </details>
180
+
181
+ <details>
182
+ <summary><b>safe 模式具体允许/禁止什么</b></summary>
183
+
184
+ **允许:**
185
+ - 只读:Read、Glob、Grep、LSP
186
+ - Git 查看:git status、git log、git diff
187
+ - 文件查看:ls、cat、head、tail、find、wc
188
+
189
+ **禁止:**
190
+ - 敏感文件:.env、secrets/、*.pem、*.key、*credential*、*password*
191
+ - 修改:Edit、Write、NotebookEdit
192
+ - 网络:curl、wget、ssh、scp、WebFetch
193
+ - 文件操作:rm、mv
194
+
195
+ </details>
196
+
197
+ ---
198
+
199
+ ## 用量统计
200
+
201
+ ccem 会读 Claude Code 的日志(在 `~/.claude/projects/` 下面的 JSONL 文件),统计 token 用量和费用。
202
+
203
+ 价格数据从 LiteLLM 的 GitHub 仓库拉取,会缓存到本地。
204
+
205
+ 交互菜单里选 "View Usage" 可以看详细统计:
206
+
207
+ ```
208
+ Token Usage Statistics
209
+ ────────────────────────────────────────────────────────
210
+ Oct Nov Dec Jan
211
+ Mon · ░ ▒ ▓ █ ░ · ▒ ...
212
+ Tue ░ ▒ · █ ▓ ░ ▒ · ...
213
+ ...
214
+
215
+ Less · ░ ▒ ▓ █ More
216
+
217
+ Period Input Output Cache Read Cost
218
+ Today 12.5K 8.2K 45.3K $0.15
219
+ This Week 89.2K 52.1K 312.4K $1.23
220
+ All Time 1.2M 823.5K 4.5M $15.67
221
+
222
+ By Model
223
+ claude-sonnet-4-5 823.5K $12.34
224
+ claude-haiku-4-5 412.3K $3.33
225
+ ```
226
+
227
+ 日志解析结果会缓存到 `~/.ccem/usage-cache.json`,下次打开会先显示缓存数据,后台更新。
228
+
229
+ ---
230
+
231
+ ## Skill 管理
232
+
233
+ 可以从 GitHub 装 Claude Code 的 Skills。装完会放到当前目录的 `.claude/skills/` 下面。
234
+
235
+ ```bash
236
+ ccem skill add # 交互选择
237
+ ccem skill add <name> # 装预设的
238
+ ccem skill add <github-url> # 从 GitHub 装
239
+ ccem skill ls # 列出已装的
240
+ ccem skill rm <name> # 删掉
241
+ ```
242
+
243
+ ### 预设列表
244
+
245
+ | Skill | 干嘛用 |
246
+ |-------|--------|
247
+ | frontend-design | 前端界面设计 |
248
+ | skill-creator | 创建新 skill |
249
+ | web-artifacts-builder | 做可交互的 Web 组件 |
250
+ | canvas-design | Canvas 绘图 |
251
+ | algorithmic-art | 算法艺术 |
252
+ | theme-factory | 做 UI 主题 |
253
+ | mcp-builder | 做 MCP 服务器 |
254
+ | webapp-testing | Web 应用测试 |
255
+ | pdf | 处理 PDF |
256
+ | docx | 处理 Word |
257
+ | pptx | 处理 PPT |
258
+ | xlsx | 处理 Excel |
259
+ | brand-guidelines | 品牌指南 |
260
+ | doc-coauthoring | 文档协作 |
261
+ | internal-comms | 内部通信文档 |
262
+ | slack-gif-creator | 做 Slack GIF |
263
+
264
+ ### 从 GitHub 装
265
+
266
+ ```bash
267
+ ccem skill add https://github.com/owner/repo
268
+ ccem skill add https://github.com/owner/repo/tree/main/path/to/skill
269
+ ccem skill add owner/repo
270
+ ```
271
+
272
+ ---
273
+
274
+ ## 初始化
275
+
276
+ 新装 Claude Code 后可以跑一下:
277
+
278
+ ```bash
279
+ ccem setup init
280
+ ```
281
+
282
+ 会做三件事:
283
+
284
+ 1. 设置 `hasCompletedOnboarding: true`,跳过新手引导
285
+ 2. 禁用遥测(设置 `DISABLE_TELEMETRY=1` 等环境变量)
286
+ 3. 装 `chrome-devtools` MCP 工具
287
+
288
+ 配置写到:
289
+ - `~/.claude.json`
290
+ - `~/.claude/settings.json`
291
+
292
+ ---
293
+
294
+ ## 命令速查
295
+
296
+ ### 环境
297
+
298
+ | 命令 | 说明 |
299
+ |------|------|
300
+ | `ccem` | 交互菜单 |
301
+ | `ccem ls` | 列出环境 |
302
+ | `ccem use <name>` | 切换 |
303
+ | `ccem add <name>` | 添加 |
304
+ | `ccem del <name>` | 删除 |
305
+ | `ccem current` | 当前环境 |
306
+ | `ccem env` | 输出环境变量 |
307
+ | `ccem env --json` | JSON 格式 |
308
+ | `ccem run <cmd>` | 带环境变量跑命令 |
309
+
310
+ ### 权限(临时)
311
+
312
+ | 命令 | 说明 |
313
+ |------|------|
314
+ | `ccem yolo` | YOLO 模式 |
315
+ | `ccem dev` | 开发模式 |
316
+ | `ccem readonly` | 只读模式 |
317
+ | `ccem safe` | 安全模式 |
318
+ | `ccem ci` | CI 模式 |
319
+ | `ccem audit` | 审计模式 |
320
+ | `ccem --mode` | 看当前模式 |
321
+ | `ccem --list-modes` | 列出所有模式 |
322
+
323
+ ### 权限(永久)
324
+
325
+ | 命令 | 说明 |
326
+ |------|------|
327
+ | `ccem setup perms --<mode>` | 永久应用 |
328
+ | `ccem setup perms --reset` | 重置 |
329
+ | `ccem setup default-mode --<mode>` | 设默认模式 |
330
+ | `ccem setup default-mode --reset` | 清默认模式 |
331
+ | `ccem setup default-mode` | 看默认模式 |
332
+
333
+ ### Skill
334
+
335
+ | 命令 | 说明 |
336
+ |------|------|
337
+ | `ccem skill add` | 交互添加 |
338
+ | `ccem skill add <name>` | 添加预设 |
339
+ | `ccem skill add <url>` | 从 GitHub 添加 |
340
+ | `ccem skill ls` | 列出已装 |
341
+ | `ccem skill rm <name>` | 删除 |
342
+
343
+ ### 初始化
344
+
345
+ | 命令 | 说明 |
346
+ |------|------|
347
+ | `ccem setup init` | 初始化配置 |
348
+
349
+ ---
350
+
351
+ ## 数据存哪了
352
+
353
+ | 路径 | 内容 |
354
+ |------|------|
355
+ | `~/.config/claude-code-env-manager/` | 环境配置 |
356
+ | `~/.ccem/usage-cache.json` | 用量缓存 |
357
+ | `~/.ccem/model-prices.json` | 价格缓存 |
358
+ | `.claude/settings.json` | 项目权限配置 |
359
+ | `.claude/skills/` | 已装的 skills |
360
+
361
+ ---
362
+
363
+ ## License
364
+
365
+ MIT
package/dist/index.js ADDED
@@ -0,0 +1,21 @@
1
+ #!/usr/bin/env node
2
+ import{Command as io}from"commander";import ao from"conf";import U from"inquirer";import d from"chalk";import kt from"cli-table3";import{spawn as Et}from"child_process";import*as he from"readline";import*as Rt from"fs";import*as fe from"path";import{fileURLToPath as co}from"url";import ae from"crypto";import X from"fs";import B from"path";var De="aes-256-cbc",He=ae.scryptSync("claude-code-env-manager-secret","salt",32),$e=e=>{if(!e)return e;let t=ae.randomBytes(16),o=ae.createCipheriv(De,He,t),n=o.update(e,"utf8","hex");return n+=o.final("hex"),`enc:${t.toString("hex")}:${n}`},j=e=>{if(!e||!e.startsWith("enc:"))return e;try{let t=e.split(":");if(t.length!==3)return e;let o=Buffer.from(t[1],"hex"),n=t[2],s=ae.createDecipheriv(De,He,o),i=s.update(n,"hex","utf8");return i+=s.final("utf8"),i}catch{return e}},Ue=()=>{let e=process.cwd(),t=B.parse(e).root;for(;e!==t;){if(X.existsSync(B.join(e,".git"))||X.existsSync(B.join(e,"package.json")))return e;e=B.dirname(e)}return process.cwd()},ce=(e=!0)=>{let t=Ue(),o=B.join(t,".claude"),n=e?"settings.local.json":"settings.json";return B.join(o,n)},Fe=()=>{let e=Ue(),t=B.join(e,".claude");return X.existsSync(t)||X.mkdirSync(t,{recursive:!0}),t},_e=()=>process.env.HOME||process.env.USERPROFILE||"",Se=()=>B.join(_e(),".claude.json"),Pe=()=>B.join(_e(),".claude","settings.json"),je=()=>{let e=B.join(_e(),".claude");return X.existsSync(e)||X.mkdirSync(e,{recursive:!0}),e};var Ae={GLM:{ANTHROPIC_BASE_URL:"https://open.bigmodel.cn/api/anthropic",ANTHROPIC_MODEL:"glm-4.6",ANTHROPIC_SMALL_FAST_MODEL:"glm-4.5-air"},KIMI:{ANTHROPIC_BASE_URL:"https://api.moonshot.cn/anthropic",ANTHROPIC_MODEL:"kimi-k2-thinking-turbo",ANTHROPIC_SMALL_FAST_MODEL:"kimi-k2-turbo-preview"},MiniMax:{ANTHROPIC_BASE_URL:"https://api.minimaxi.com/anthropic",ANTHROPIC_MODEL:"MiniMax-M2",ANTHROPIC_SMALL_FAST_MODEL:"MiniMax-M2"},DeepSeek:{ANTHROPIC_BASE_URL:"https://api.deepseek.com/anthropic",ANTHROPIC_MODEL:"deepseek-chat",ANTHROPIC_SMALL_FAST_MODEL:"deepseek-chat"}},O={yolo:{name:"YOLO \u6A21\u5F0F",description:"\u5168\u90E8\u653E\u5F00\uFF0C\u65E0\u4EFB\u4F55\u9650\u5236",permissionMode:"bypassPermissions",permissions:{allow:["Bash(*)","Read(*)","Edit(*)","Write(*)","WebFetch(*)","WebSearch(*)","Glob(*)","Grep(*)","LSP(*)","NotebookEdit(*)"],deny:[]}},dev:{name:"\u5F00\u53D1\u6A21\u5F0F",description:"\u65E5\u5E38\u5F00\u53D1\u6743\u9650\uFF0C\u4FDD\u62A4\u654F\u611F\u6587\u4EF6",permissionMode:"acceptEdits",permissions:{allow:["Read(*)","Edit(*)","Write(*)","Glob(*)","Grep(*)","LSP(*)","NotebookEdit(*)","Bash(npm:*)","Bash(pnpm:*)","Bash(yarn:*)","Bash(bun:*)","Bash(node:*)","Bash(npx:*)","Bash(git:*)","Bash(tsc:*)","Bash(tsx:*)","Bash(eslint:*)","Bash(prettier:*)","Bash(jest:*)","Bash(vitest:*)","Bash(cargo:*)","Bash(python:*)","Bash(pip:*)","Bash(go:*)","Bash(make:*)","Bash(cmake:*)","Bash(ls:*)","Bash(cat:*)","Bash(head:*)","Bash(tail:*)","Bash(find:*)","Bash(wc:*)","Bash(mkdir:*)","Bash(cp:*)","Bash(mv:*)","Bash(touch:*)","WebSearch"],deny:["Read(.env)","Read(.env.*)","Read(**/secrets/**)","Read(**/*.pem)","Read(**/*.key)","Read(**/*credential*)","Bash(rm -rf:*)","Bash(sudo:*)","Bash(chmod:*)","Bash(chown:*)"]}},readonly:{name:"\u53EA\u8BFB\u6A21\u5F0F",description:"\u4EC5\u5141\u8BB8\u8BFB\u53D6\u548C\u641C\u7D22\uFF0C\u7981\u6B62\u4EFB\u4F55\u4FEE\u6539",permissionMode:"plan",permissions:{allow:["Read(*)","Glob(*)","Grep(*)","LSP(*)","Bash(git status:*)","Bash(git log:*)","Bash(git diff:*)","Bash(git branch:*)","Bash(git show:*)","Bash(ls:*)","Bash(cat:*)","Bash(head:*)","Bash(tail:*)","Bash(find:*)","Bash(wc:*)","Bash(file:*)","WebSearch"],deny:["Edit(*)","Write(*)","NotebookEdit(*)","Bash(rm:*)","Bash(mv:*)","Bash(cp:*)","Bash(mkdir:*)","Bash(touch:*)","Bash(git add:*)","Bash(git commit:*)","Bash(git push:*)","Bash(git checkout:*)","Bash(git reset:*)","Bash(npm install:*)","Bash(pnpm install:*)","Bash(yarn add:*)"]}},safe:{name:"\u5B89\u5168\u6A21\u5F0F",description:"\u4FDD\u5B88\u6743\u9650\uFF0C\u9002\u5408\u4E0D\u719F\u6089\u7684\u4EE3\u7801\u5E93",permissionMode:"default",permissions:{allow:["Read(*)","Glob(*)","Grep(*)","LSP(*)","Bash(git status:*)","Bash(git log:*)","Bash(git diff:*)","Bash(ls:*)","Bash(cat:*)","Bash(head:*)","Bash(tail:*)","Bash(find:*)","Bash(wc:*)"],deny:["Read(.env)","Read(.env.*)","Read(**/secrets/**)","Read(**/*.pem)","Read(**/*.key)","Read(**/*credential*)","Read(**/*password*)","Edit(*)","Write(*)","NotebookEdit(*)","Bash(curl:*)","Bash(wget:*)","Bash(ssh:*)","Bash(scp:*)","Bash(rm:*)","Bash(mv:*)","WebFetch(*)"]}},ci:{name:"CI/CD \u6A21\u5F0F",description:"\u9002\u5408\u81EA\u52A8\u5316\u6D41\u6C34\u7EBF\u7684\u6743\u9650",permissionMode:"default",permissions:{allow:["Read(*)","Edit(*)","Write(*)","Glob(*)","Grep(*)","LSP(*)","Bash(npm:*)","Bash(pnpm:*)","Bash(yarn:*)","Bash(node:*)","Bash(git:*)","Bash(docker:*)","Bash(make:*)","Bash(cargo:*)","Bash(go:*)","Bash(python:*)","Bash(pip:*)","Bash(pytest:*)","Bash(jest:*)","Bash(vitest:*)"],deny:["Read(.env.local)","Read(**/secrets/**)","Bash(sudo:*)","Bash(ssh:*)","Bash(scp:*)","WebFetch(*)","WebSearch"]}},audit:{name:"\u5BA1\u8BA1\u6A21\u5F0F",description:"\u4EC5\u8BFB\u53D6\u548C\u641C\u7D22\uFF0C\u7528\u4E8E\u5B89\u5168\u5BA1\u8BA1",permissionMode:"plan",permissions:{allow:["Read(*)","Glob(*)","Grep(*)","LSP(*)","Bash(git log:*)","Bash(git blame:*)","Bash(git show:*)","Bash(git diff:*)","Bash(ls:*)","Bash(find:*)","Bash(wc:*)","Bash(file:*)","Bash(stat:*)"],deny:["Edit(*)","Write(*)","NotebookEdit(*)","Bash(rm:*)","Bash(mv:*)","Bash(cp:*)","Bash(curl:*)","Bash(wget:*)","Bash(ssh:*)","WebFetch(*)"]}}},Ce=()=>Object.keys(O);import N from"chalk";import Je from"cli-table3";import*as Y from"fs";import*as I from"fs/promises";import*as G from"path";import*as ke from"os";import*as Ge from"readline";var Te=G.join(ke.homedir(),".claude","projects"),le=G.join(ke.homedir(),".ccem"),Ee=1,Re=()=>G.join(le,"usage-cache.json"),xt=()=>G.join(le,"model-prices.json");async function Ke(){try{await I.access(le)}catch{await I.mkdir(le,{recursive:!0})}}var Lt="https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",bt=()=>G.join(__dirname,"..","model-prices.json"),Z={"claude-opus-4-5":{input_cost_per_token:5e-6,output_cost_per_token:25e-6,cache_read_input_token_cost:5e-7,cache_creation_input_token_cost:625e-8},"claude-sonnet-4-5":{input_cost_per_token:3e-6,output_cost_per_token:15e-6,cache_read_input_token_cost:3e-7,cache_creation_input_token_cost:375e-8},"claude-haiku-4-5":{input_cost_per_token:1e-6,output_cost_per_token:5e-6,cache_read_input_token_cost:1e-7,cache_creation_input_token_cost:125e-8}};function de(e){return e.replace(/-20\d{6}.*$/,"").replace(/-v\d+:\d+$/,"").replace(/^anthropic\./,"").replace(/^vertex_ai\//,"").replace(/@.*$/,"")}var Q=null;async function Nt(){if(Q)return Q;await Ke();let e=xt();try{let t=await fetch(Lt,{signal:AbortSignal.timeout(1e3)});if(t.ok){let o=await t.json(),n={};for(let[s,i]of Object.entries(o))i.input_cost_per_token&&i.output_cost_per_token&&(n[s]={input_cost_per_token:i.input_cost_per_token,output_cost_per_token:i.output_cost_per_token,cache_read_input_token_cost:i.cache_read_input_token_cost,cache_creation_input_token_cost:i.cache_creation_input_token_cost});return await I.writeFile(e,JSON.stringify(n,null,2)),Q=n,n}}catch{}try{let t=await I.readFile(e,"utf-8"),o=JSON.parse(t);return Q=o,o}catch{}try{let t=bt(),o=await I.readFile(t,"utf-8"),n=JSON.parse(o);return Q=n,n}catch{}return Q=Z,Z}function Bt(e,t){if(t[e])return t[e];let o=de(e);if(t[o])return t[o];for(let[n,s]of Object.entries(t))if(n.includes(o)||o.includes(de(n)))return s;return e.includes("opus")?Z["claude-opus-4-5"]:e.includes("sonnet")?Z["claude-sonnet-4-5"]:e.includes("haiku")?Z["claude-haiku-4-5"]:Z["claude-sonnet-4-5"]}function vt(e,t){return e.inputTokens*t.input_cost_per_token+e.outputTokens*t.output_cost_per_token+e.cacheReadTokens*(t.cache_read_input_token_cost||0)+e.cacheCreationTokens*(t.cache_creation_input_token_cost||0)}function v(){return{inputTokens:0,outputTokens:0,cacheReadTokens:0,cacheCreationTokens:0,cost:0}}function D(e,t){return{inputTokens:e.inputTokens+t.inputTokens,outputTokens:e.outputTokens+t.outputTokens,cacheReadTokens:e.cacheReadTokens+t.cacheReadTokens,cacheCreationTokens:e.cacheCreationTokens+t.cacheCreationTokens,cost:e.cost+t.cost}}async function Dt(e){try{let t=await I.stat(e);return{mtime:t.mtimeMs,size:t.size}}catch{return null}}function Ht(){try{let e=Re();if(!Y.existsSync(e))return null;let t=JSON.parse(Y.readFileSync(e,"utf-8"));return t.version!==Ee?null:t}catch{return null}}async function $t(){try{let e=Re(),t=await I.readFile(e,"utf-8"),o=JSON.parse(t);return o.version!==Ee?null:o}catch{return null}}function We(){let e=Ht();if(!e)return null;let t=new Date,o=new Date(t.getFullYear(),t.getMonth(),t.getDate()),n=new Date(o);n.setDate(n.getDate()-n.getDay());let s={today:v(),week:v(),total:v(),dailyHistory:{},byModel:{},lastUpdated:t.toISOString()};for(let i of Object.values(e.files))for(let a of i.stats.entries){let c=new Date(a.timestamp),l=a.timestamp.split("T")[0];s.total=D(s.total,a.usage),s.dailyHistory[l]||(s.dailyHistory[l]=v()),s.dailyHistory[l]=D(s.dailyHistory[l],a.usage);let m=de(a.model);s.byModel[m]||(s.byModel[m]=v()),s.byModel[m]=D(s.byModel[m],a.usage),c>=o&&(s.today=D(s.today,a.usage)),c>=n&&(s.week=D(s.week,a.usage))}return s}async function Ut(e){try{await Ke(),await I.writeFile(Re(),JSON.stringify(e,null,2))}catch{}}async function Ft(e,t,o){let n=[];try{let s=Y.createReadStream(e,{encoding:"utf-8"}),i=Ge.createInterface({input:s,crlfDelay:1/0}),a=0;for await(let c of i){if(a++,a%100===0){if(o?.aborted)throw i.close(),s.destroy(),new Error("Aborted");a%1e3===0&&await new Promise(l=>setTimeout(l,0))}if(c.trim())try{let l=JSON.parse(c);if(l.type!=="assistant"||!l.message?.usage)continue;let m=l.message.model||"unknown",f=l.message.usage,y={inputTokens:f.input_tokens||0,outputTokens:f.output_tokens||0,cacheReadTokens:f.cache_read_input_tokens||0,cacheCreationTokens:f.cache_creation_input_tokens||0},p=Bt(m,t),_=vt(y,p);n.push({timestamp:l.timestamp||new Date().toISOString(),model:m,usage:{...y,cost:_}})}catch{}}}catch(s){if(s.message==="Aborted")throw s}return{entries:n}}async function jt(){let e=[];try{if(!await I.access(Te).then(()=>!0).catch(()=>!1))return e;let o=await I.readdir(Te);for(let n of o){let s=G.join(Te,n);try{if((await I.stat(s)).isDirectory()){let a=await I.readdir(s);for(let c of a)c.endsWith(".jsonl")&&e.push(G.join(s,c))}}catch{}}}catch{}return e}async function Ye(e){if(e?.aborted)throw new Error("Aborted");let t=await Nt();if(e?.aborted)throw new Error("Aborted");let o=await jt();if(e?.aborted)throw new Error("Aborted");let n=await $t(),s={version:Ee,files:{},lastUpdated:new Date().toISOString()},i=[],a=5,c=[];for(let p=0;p<o.length;p+=a)c.push(o.slice(p,p+a));for(let p of c){if(e?.aborted)throw new Error("Aborted");let _=p.map(async g=>{let S=await Dt(g);if(!S)return null;let R=n?.files[g],k=R&&R.meta.mtime===S.mtime&&R.meta.size===S.size,E;return k?E=R.stats:(E=await Ft(g,t,e),await new Promise(C=>setTimeout(C,0))),{file:g,meta:S,stats:E}}),u=await Promise.all(_);for(let g of u)g&&(s.files[g.file]={meta:g.meta,stats:g.stats},i.push(...g.stats.entries))}e?.aborted||Ut(s).catch(()=>{});let l=new Date,m=new Date(l.getFullYear(),l.getMonth(),l.getDate()),f=new Date(m);f.setDate(f.getDate()-f.getDay());let y={today:v(),week:v(),total:v(),dailyHistory:{},byModel:{},lastUpdated:l.toISOString()};for(let p of i){let _=new Date(p.timestamp),u=p.timestamp.split("T")[0];y.total=D(y.total,p.usage),y.dailyHistory[u]||(y.dailyHistory[u]=v()),y.dailyHistory[u]=D(y.dailyHistory[u],p.usage);let g=de(p.model);y.byModel[g]||(y.byModel[g]=v()),y.byModel[g]=D(y.byModel[g],p.usage),_>=m&&(y.today=D(y.today,p.usage)),_>=f&&(y.week=D(y.week,p.usage))}return y}function b(e){return e>=1e6?(e/1e6).toFixed(1)+"M":e>=1e3?(e/1e3).toFixed(1)+"K":e.toString()}function ee(e){return e>=1||e>=.01?"$"+e.toFixed(2):"$"+e.toFixed(4)}function J(e){return e.inputTokens+e.outputTokens+e.cacheReadTokens+e.cacheCreationTokens}var r={primary:N.hex("#89B4FA"),accent:N.hex("#CBA6F7"),success:N.hex("#A6E3A1"),warning:N.hex("#F9E2AF"),danger:N.hex("#F38BA8"),text:N.white,muted:N.hex("#6C7086"),dim:N.hex("#45475A")},ze=["\u280B","\u2819","\u2839","\u2838","\u283C","\u2834","\u2826","\u2827","\u2807","\u280F"],we=0,se=null,Gt=()=>r.primary(ze[we]),Ve=e=>{se||(se=setInterval(()=>{we=(we+1)%ze.length,e()},80))},pe=()=>{se&&(clearInterval(se),se=null)};var qe=()=>process.stdout.columns||80,Xe=(e,t,o)=>{let n=N.hex("#89B4FA"),s=N.hex("#45475A"),i=N.hex("#6C7086"),a=qe(),c=a<60,l=a<45,m=r.primary("CCEM")+" "+r.muted("Claude Code Env Manager"),f=r.primary("CCEM"),y=r.muted("Env: ")+r.primary(e),p=t.ANTHROPIC_BASE_URL||"-",_=t.ANTHROPIC_MODEL||"-",u=t.ANTHROPIC_SMALL_FAST_MODEL||"-",g=t.ANTHROPIC_API_KEY?t.ANTHROPIC_API_KEY.slice(0,2)+"\u2022\u2022\u2022\u2022"+t.ANTHROPIC_API_KEY.slice(-4):"-",S=(w,F)=>w.length>F?w.slice(0,F-3)+"...":w,R=(w,F)=>{if(w.length<=F)return w;try{let $=new URL(w),wt=$.protocol+"//",ve=$.host,ye=$.pathname+$.search,Ot=ve.slice(0,8),Mt=ve.slice(-4),It=ye.length>10?ye.slice(0,7)+"...":ye;return`${wt}${Ot}...${Mt}${It}`}catch{return S(w,F)}},k=7,E;c?E=[y,r.muted("Model:".padEnd(k))+r.dim(S(_,25)),r.muted("Key:".padEnd(k))+r.dim(g)]:E=[y+(o&&O[o]?" "+r.accent(`[${O[o].name}]`):""),r.muted("URL:".padEnd(k))+r.dim(R(p,40)),r.muted("Model:".padEnd(k))+r.dim(S(_,15))+" "+r.muted("Fast:".padEnd(k))+r.dim(S(u,15)),r.muted("Key:".padEnd(k))+r.dim(g)];let C=[];if(l)C.push(` ${i("*")} ${s("\u2584\u2588\u2584")} ${i("*")}`),C.push(` ${i("*")} ${n("\u2590\u259B\u2588\u2588\u2588\u2588\u2588\u259C\u258C")} ${i("*")}`),C.push(` ${i("*")} ${n("\u259D\u259C\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u259B\u2598")} ${i("*")}`),C.push(` ${i("*")} ${n("\u2598\u2598 \u259D\u259D")} ${i("*")}`),C.push(""),C.push(f),C.push(""),E.forEach(w=>C.push(w));else{let w=c?" ":" ";C.push(""),C.push(` ${s("\u2584\u2588\u2588\u2584")} ${w}${c?f:m}`),C.push(` ${i("*")} ${n("\u2590\u259B\u2588\u2588\u2588\u2588\u2588\u259C\u258C")} ${i("*")} ${w}${E[0]||""}`),C.push(` ${i("*")} ${n("\u259D\u259C\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u259B\u2598")} ${i("*")} ${w}${E[1]||""}`),C.push(` ${i("*")} ${n("\u2598\u2598 \u259D\u259D")} ${i("*")} ${w}${E[2]||""}`),E[3]&&C.push(` ${w}${E[3]}`)}return C.join(`
3
+ `)},Qe=(e,t)=>{if(t)return r.muted(" Usage: ")+Gt()+r.dim(" Loading...");if(!e)return r.muted(" Usage: ")+r.dim("No data");let n=qe()<70,s=J(e.today),i=J(e.week),a=J(e.total);return n?r.muted(" Usage: ")+r.text("Today ")+r.primary(b(s))+r.dim(" | ")+r.text("Week ")+r.primary(b(i))+r.dim(" | ")+r.text("Total ")+r.primary(b(a)):r.muted(" Usage: ")+r.text("Today ")+r.primary(b(s).padStart(6))+r.dim(` (${ee(e.today.cost)})`)+r.dim(" | ")+r.text("Week ")+r.primary(b(i).padStart(6))+r.dim(` (${ee(e.week.cost)})`)+r.dim(" | ")+r.text("Total ")+r.primary(b(a).padStart(6))+r.dim(` (${ee(e.total.cost)})`)},Ze=()=>{let e=process.stdout.columns||80;return r.dim("\u2500".repeat(e))};var Oe=e=>{let t="Start Claude Code";return e&&O[e]&&(t=`Start Claude Code ${r.muted(`(${O[e].name})`)}`),[{name:r.success(t),value:"start",short:"Start"},{name:r.primary("Switch Environment"),value:"switch",short:"Switch"},{name:r.primary("Permission Mode"),value:"perm",short:"Permission"},{name:r.accent("View Usage"),value:"usage",short:"Usage"},{name:r.text("Set Default Mode"),value:"setDefault",short:"Default"},{name:r.muted("Exit"),value:"exit",short:"Exit"}]},Kt={yolo:r.danger,dev:r.success,readonly:r.primary,safe:r.warning,ci:r.accent,audit:r.primary},Me=(e,t=!1)=>{let n=["yolo","dev","readonly","safe","ci","audit"].map(s=>{let i=O[s],a=Kt[s],l=t&&s===e?r.success(" *"):"";return{name:a(i.name.padEnd(12))+r.muted(i.description)+l,value:s,short:i.name}});return t&&n.push({name:r.muted("Clear default"),value:"clear",short:"Clear"}),n.push({name:r.muted("Back"),value:"back",short:"Back"}),n},et=(e,t)=>Object.keys(e).map(o=>{let n=o===t,s=n?r.success(" *"):"";return{name:(n?r.primary(o):r.text(o))+s,value:o,short:o}}),ne={success:e=>console.log(r.success("\u2713 ")+r.text(e)),error:e=>console.log(r.danger("\u2717 ")+r.text(e)),warning:e=>console.log(r.warning("! ")+r.text(e)),info:e=>console.log(r.primary("\u203A ")+r.text(e))},tt=()=>r.muted("Starting Claude Code...");var Wt=(e,t=6)=>{let o=[],n=new Date,s=new Date(n);s.setMonth(s.getMonth()-t);let i=s.getDay(),a=s.getDate()-i+(i===0?-6:1);s.setDate(a),s.setHours(0,0,0,0);let c=[],l=new Date(s);for(;(l<=n||l.getDay()!==1)&&(c.push(l.toISOString().split("T")[0]),l.setDate(l.getDate()+1),!(l>n&&l.getDay()===1)););let m=0;for(let S of c){let R=e.dailyHistory[S];if(R){let k=J(R);k>m&&(m=k)}}let f=" ",y=-1,p=Math.ceil(c.length/7);for(let S=0;S<p;S++){let R=S*7;if(R<c.length){let k=new Date(c[R]),E=k.getMonth();if(E!==y&&S<p-1){let C=k.toLocaleString("default",{month:"short"});f+=r.muted(C),y=E}}}f=" ";let _=-1;for(let S=0;S<p;S++){let R=S*7;if(R>=c.length)break;let k=new Date(c[R]),E=k.getMonth();if(E!==_){let C=k.toLocaleString("default",{month:"short"});f+=r.muted(C.padEnd(4)),S++,_=E}else f+=" "}o.push(f);let u=["Mon","","Wed","","Fri","","Sun"],g=[" ","\u2591","\u2592","\u2593","\u2588"];for(let S=0;S<7;S++){let R=r.muted((u[S]||"").padEnd(4)+" ");for(let k=0;k<p;k++){let E=k*7+S;if(E<c.length){let C=c[E];if(new Date(C)>n)R+=" ";else{let w=e.dailyHistory[C],F=w?J(w):0,$=0;F>0&&(m===0?$=0:$=Math.ceil(F/m*4)),R+=($===0?r.dim("\xB7"):r.primary(g[$]))+" "}}}o.push(R)}return o.push(""),o.push(" "+r.dim("Less ")+r.dim("\xB7")+" "+r.primary(g[1])+" "+r.primary(g[2])+" "+r.primary(g[3])+" "+r.primary(g[4])+" "+r.dim(" More")),o.join(`
4
+ `)},ot=e=>{let t=[];t.push(""),t.push(r.primary(" Token Usage Statistics")),t.push(r.dim("\u2500".repeat(60))),t.push(""),t.push(Wt(e)),t.push(""),t.push(r.dim("\u2500".repeat(60)));let o=new Je({head:[r.muted("Period"),r.muted("Input"),r.muted("Output"),r.muted("Cache Read"),r.muted("Cost")],style:{head:[],border:[]},chars:{top:"","top-mid":"","top-left":"","top-right":"",bottom:"","bottom-mid":"","bottom-left":"","bottom-right":"",left:" ","left-mid":"",mid:"","mid-mid":"",right:"","right-mid":"",middle:" "}}),n=(i,a)=>[r.text(i),r.primary(b(a.inputTokens)),r.primary(b(a.outputTokens)),r.primary(b(a.cacheReadTokens)),r.success(ee(a.cost))];o.push(n("Today",e.today)),o.push(n("This Week",e.week)),o.push(n("All Time",e.total)),t.push(o.toString());let s=Object.entries(e.byModel).sort((i,a)=>a[1].cost-i[1].cost);if(s.length>0){t.push(""),t.push(r.dim("\u2500".repeat(60))),t.push(r.muted(" By Model")),t.push("");let i=new Je({head:[r.muted("Model"),r.muted("Tokens"),r.muted("Cost")],style:{head:[],border:[]},chars:{top:"","top-mid":"","top-left":"","top-right":"",bottom:"","bottom-mid":"","bottom-left":"","bottom-right":"",left:" ","left-mid":"",mid:"","mid-mid":"",right:"","right-mid":"",middle:" "}});for(let[a,c]of s){let l=J(c);i.push([r.text(a),r.primary(b(l)),r.success(ee(c.cost))])}t.push(i.toString())}return t.push(""),t.push(r.dim("\u2500".repeat(60))),t.push(r.muted(` Last updated: ${new Date(e.lastUpdated).toLocaleString()}`)),t.join(`
5
+ `)};import z from"fs";import A from"chalk";import st from"cli-table3";import{spawn as Yt}from"child_process";var Ie=e=>{if(z.existsSync(e))try{let t=z.readFileSync(e,"utf-8");return JSON.parse(t)}catch{console.warn(A.yellow(`\u8B66\u544A: \u65E0\u6CD5\u89E3\u6790 ${e}\uFF0C\u5C06\u521B\u5EFA\u5907\u4EFD`));let t=e+".error."+Date.now();return z.copyFileSync(e,t),console.log(A.gray(`\u5907\u4EFD\u5DF2\u4FDD\u5B58\u5230: ${t}`)),{}}return{}},nt=(e,t)=>{Fe(),z.writeFileSync(e,JSON.stringify(t,null,2)+`
6
+ `)},Jt=(e,t)=>{let o=e.permissions?.allow||[],n=e.permissions?.deny||[],s=[...new Set([...t.allow,...o])],i=[...new Set([...t.deny,...n])];return{...e,permissions:{allow:s,deny:i}}},rt=e=>{let t=O[e];t||(console.error(A.red(`\u672A\u77E5\u7684\u6743\u9650\u6A21\u5F0F: ${e}`)),console.log(A.yellow("\u53EF\u7528\u6A21\u5F0F: "+Ce().join(", "))),process.exit(1));let o=ce(!0),n=Ie(o),s=Jt(n,t.permissions);nt(o,s),console.log(A.green(`\u5DF2\u5E94\u7528 ${t.name}`)),console.log(A.gray(`\u914D\u7F6E\u5DF2\u5199\u5165: ${o}`)),console.log(A.gray(`\u8BF4\u660E: ${t.description}`))},it=()=>{let e=ce(!0);if(!z.existsSync(e)){console.log(A.yellow("\u6CA1\u6709\u81EA\u5B9A\u4E49\u6743\u9650\u914D\u7F6E\u9700\u8981\u91CD\u7F6E"));return}let t=Ie(e);delete t.permissions,Object.keys(t).length===0?(z.unlinkSync(e),console.log(A.green("\u5DF2\u5220\u9664\u914D\u7F6E\u6587\u4EF6\uFF08\u6587\u4EF6\u4E3A\u7A7A\uFF09"))):(nt(e,t),console.log(A.green("\u6743\u9650\u914D\u7F6E\u5DF2\u91CD\u7F6E"))),console.log(A.gray(`\u6587\u4EF6: ${e}`))},at=()=>{let e=ce(!0);if(!z.existsSync(e)){console.log(A.yellow("\u672A\u914D\u7F6E\u81EA\u5B9A\u4E49\u6743\u9650")),console.log(A.gray(`\u6587\u4EF6\u4E0D\u5B58\u5728: ${e}`));return}let t=Ie(e);if(!t.permissions){console.log(A.yellow("\u672A\u914D\u7F6E\u81EA\u5B9A\u4E49\u6743\u9650"));return}let o=Object.entries(O).find(([a,c])=>{let l=new Set(t.permissions?.allow||[]),m=new Set(t.permissions?.deny||[]),f=new Set(c.permissions.allow),y=new Set(c.permissions.deny),p=c.permissions.allow.every(u=>l.has(u)),_=c.permissions.deny.every(u=>m.has(u));return p&&_});console.log(o?A.green(`\u5F53\u524D\u6A21\u5F0F: ${o[0]} (${o[1].name})`):A.yellow("\u5F53\u524D\u6A21\u5F0F: \u81EA\u5B9A\u4E49")),console.log(A.gray(`\u914D\u7F6E\u6587\u4EF6: ${e}`));let n=new st({head:["\u7C7B\u578B","\u89C4\u5219"],style:{head:["cyan"]},colWidths:[10,70]}),s=t.permissions.allow||[],i=t.permissions.deny||[];n.push(["Allow",s.length>0?s.join(`
7
+ `):"(\u65E0)"]),n.push(["Deny",i.length>0?i.join(`
8
+ `):"(\u65E0)"]),console.log(n.toString())},ct=()=>{let e=new st({head:["\u6A21\u5F0F","\u6807\u5FD7","\u8BF4\u660E"],style:{head:["cyan"]},colWidths:[15,15,50]});Object.entries(O).forEach(([t,o])=>{e.push([o.name,`--${t}`,o.description])}),console.log(A.bold(`\u53EF\u7528\u6743\u9650\u6A21\u5F0F:
9
+ `)),console.log(e.toString()),console.log(A.gray(`
10
+ \u4E34\u65F6\u6A21\u5F0F: ccem <mode>`)),console.log(A.gray("\u6C38\u4E45\u6A21\u5F0F: ccem setup perms --<mode>"))},ue=async(e,t)=>{let o=O[e];o||(console.error(A.red(`\u672A\u77E5\u7684\u6743\u9650\u6A21\u5F0F: ${e}`)),console.log(A.yellow("\u53EF\u7528\u6A21\u5F0F: "+Ce().join(", "))),process.exit(1));let n=[];if(n.push("--permission-mode",o.permissionMode),o.permissions.allow.length>0){let i=o.permissions.allow.map(a=>`"${a}"`).join(" ");n.push("--allowedTools",i)}if(o.permissions.deny.length>0){let i=o.permissions.deny.map(a=>`"${a}"`).join(" ");n.push("--disallowedTools",i)}console.log(A.green(`\u5DF2\u5E94\u7528 ${o.name}\uFF08\u4E34\u65F6\uFF09`)),console.log(A.gray(`\u8BF4\u660E: ${o.description}`)),console.log("");let s={...process.env};return t&&(t.ANTHROPIC_BASE_URL&&(s.ANTHROPIC_BASE_URL=t.ANTHROPIC_BASE_URL),t.ANTHROPIC_API_KEY&&(s.ANTHROPIC_API_KEY=j(t.ANTHROPIC_API_KEY)),t.ANTHROPIC_MODEL&&(s.ANTHROPIC_MODEL=t.ANTHROPIC_MODEL),t.ANTHROPIC_SMALL_FAST_MODEL&&(s.ANTHROPIC_SMALL_FAST_MODEL=t.ANTHROPIC_SMALL_FAST_MODEL)),new Promise(i=>{let a=Yt("claude",n,{stdio:"inherit",shell:!0,env:s});a.on("exit",c=>{process.exit(c??0)}),a.on("error",c=>{console.error(A.red(`\u542F\u52A8 Claude Code \u5931\u8D25: ${c.message}`)),process.exit(1)})})};import xe from"fs";import P from"chalk";import{spawn as zt}from"child_process";var lt=e=>{if(xe.existsSync(e))try{let t=xe.readFileSync(e,"utf-8");return JSON.parse(t)}catch{return console.warn(P.yellow(`\u8B66\u544A: \u65E0\u6CD5\u89E3\u6790 ${e}`)),{}}return{}},dt=(e,t)=>{xe.writeFileSync(e,JSON.stringify(t,null,2)+`
11
+ `)},Vt=()=>{let e=Se();try{let t=lt(e);return t.hasCompletedOnboarding===!0?(console.log(P.gray(" \u2713 hasCompletedOnboarding \u5DF2\u8BBE\u7F6E")),!0):(t.hasCompletedOnboarding=!0,dt(e,t),console.log(P.green(" \u2713 \u5DF2\u8BBE\u7F6E hasCompletedOnboarding: true")),!0)}catch(t){return console.error(P.red(` \u2717 \u8BBE\u7F6E hasCompletedOnboarding \u5931\u8D25: ${t}`)),!1}},qt=()=>{let e=Pe();try{je();let t=lt(e);(!t.env||typeof t.env!="object")&&(t.env={});let o=t.env,n={DISABLE_BUG_COMMAND:"1",DISABLE_ERROR_REPORTING:"1",DISABLE_TELEMETRY:"1"},s=!1;for(let[i,a]of Object.entries(n))o[i]!==a&&(o[i]=a,s=!0);return s?(dt(e,t),console.log(P.green(" \u2713 \u5DF2\u914D\u7F6E\u73AF\u5883\u53D8\u91CF:")),console.log(P.gray(" DISABLE_BUG_COMMAND=1")),console.log(P.gray(" DISABLE_ERROR_REPORTING=1")),console.log(P.gray(" DISABLE_TELEMETRY=1")),!0):(console.log(P.gray(" \u2713 \u73AF\u5883\u53D8\u91CF\u5DF2\u914D\u7F6E")),!0)}catch(t){return console.error(P.red(` \u2717 \u8BBE\u7F6E\u73AF\u5883\u53D8\u91CF\u5931\u8D25: ${t}`)),!1}},Xt=()=>new Promise(e=>{console.log(P.cyan(" \u2192 \u6B63\u5728\u6DFB\u52A0 chrome-devtools MCP \u5DE5\u5177..."));let t=zt("claude",["mcp","add","chrome-devtools","npx","chrome-devtools-mcp@latest","--scope","user"],{stdio:"pipe",shell:!0}),o="",n="";t.stdout?.on("data",s=>{o+=s.toString()}),t.stderr?.on("data",s=>{n+=s.toString()}),t.on("exit",s=>{s===0?(console.log(P.green(" \u2713 \u5DF2\u6DFB\u52A0 chrome-devtools MCP \u5DE5\u5177")),e(!0)):n.includes("already exists")||o.includes("already exists")?(console.log(P.gray(" \u2713 chrome-devtools MCP \u5DE5\u5177\u5DF2\u5B58\u5728")),e(!0)):(console.error(P.red(` \u2717 \u6DFB\u52A0 MCP \u5DE5\u5177\u5931\u8D25 (code: ${s})`)),n&&console.error(P.gray(` ${n.trim()}`)),e(!1))}),t.on("error",s=>{console.error(P.red(` \u2717 \u6267\u884C claude \u547D\u4EE4\u5931\u8D25: ${s.message}`)),console.log(P.yellow(" \u8BF7\u786E\u4FDD\u5DF2\u5B89\u88C5 Claude Code CLI")),e(!1)})}),pt=async()=>{console.log(P.bold(`
12
+ \u{1F527} Claude Code \u521D\u59CB\u5316\u8BBE\u7F6E
13
+ `)),console.log(P.cyan("1. \u8BBE\u7F6E onboarding \u72B6\u6001"));let e=Vt();console.log(P.cyan(`
14
+ 2. \u914D\u7F6E\u9690\u79C1\u8BBE\u7F6E`));let t=qt();console.log(P.cyan(`
15
+ 3. \u5B89\u88C5 MCP \u5DE5\u5177`));let o=await Xt();console.log(""),console.log(e&&t&&o?P.green.bold("\u2705 \u521D\u59CB\u5316\u5B8C\u6210\uFF01"):P.yellow.bold("\u26A0\uFE0F \u90E8\u5206\u6B65\u9AA4\u672A\u5B8C\u6210\uFF0C\u8BF7\u68C0\u67E5\u4E0A\u8FF0\u9519\u8BEF")),console.log(P.gray(`
16
+ \u914D\u7F6E\u6587\u4EF6\u4F4D\u7F6E:`)),console.log(P.gray(` - ${Se()}`)),console.log(P.gray(` - ${Pe()}`)),console.log("")};import{execSync as te}from"child_process";import*as T from"fs";import*as x from"path";import M from"chalk";var mt={official:{label:"\u5B98\u65B9",icon:"\u{1F3E2}"},featured:{label:"\u7CBE\u9009",icon:"\u2B50"},others:{label:"\u5176\u4ED6",icon:"\u{1F4E6}"}},gt=[{name:"frontend-design",description:"\u521B\u5EFA\u9AD8\u8D28\u91CF\u524D\u7AEF\u754C\u9762\u8BBE\u8BA1",group:"official",install:{type:"preset",name:"frontend-design"}},{name:"skill-creator",description:"\u521B\u5EFA\u65B0\u7684 Claude Code skills",group:"official",install:{type:"preset",name:"skill-creator"}},{name:"web-artifacts-builder",description:"\u6784\u5EFA\u53EF\u4EA4\u4E92\u7684 Web \u7EC4\u4EF6",group:"official",install:{type:"preset",name:"web-artifacts-builder"}},{name:"canvas-design",description:"Canvas \u7ED8\u56FE\u8BBE\u8BA1",group:"official",install:{type:"preset",name:"canvas-design"}},{name:"algorithmic-art",description:"\u7B97\u6CD5\u827A\u672F\u751F\u6210",group:"official",install:{type:"preset",name:"algorithmic-art"}},{name:"theme-factory",description:"\u4E3B\u9898\u5DE5\u5382 - \u521B\u5EFA UI \u4E3B\u9898",group:"official",install:{type:"preset",name:"theme-factory"}},{name:"mcp-builder",description:"\u6784\u5EFA MCP \u670D\u52A1\u5668",group:"official",install:{type:"preset",name:"mcp-builder"}},{name:"webapp-testing",description:"Web \u5E94\u7528\u6D4B\u8BD5",group:"official",install:{type:"preset",name:"webapp-testing"}},{name:"pdf",description:"PDF \u6587\u6863\u5904\u7406",group:"official",install:{type:"preset",name:"pdf"}},{name:"docx",description:"Word \u6587\u6863\u5904\u7406",group:"official",install:{type:"preset",name:"docx"}},{name:"pptx",description:"PowerPoint \u6F14\u793A\u6587\u7A3F\u5904\u7406",group:"official",install:{type:"preset",name:"pptx"}},{name:"xlsx",description:"Excel \u8868\u683C\u5904\u7406",group:"official",install:{type:"preset",name:"xlsx"}},{name:"brand-guidelines",description:"\u54C1\u724C\u6307\u5357\u751F\u6210",group:"official",install:{type:"preset",name:"brand-guidelines"}},{name:"doc-coauthoring",description:"\u6587\u6863\u534F\u4F5C\u7F16\u5199",group:"official",install:{type:"preset",name:"doc-coauthoring"}},{name:"internal-comms",description:"\u5185\u90E8\u901A\u4FE1\u6587\u6863",group:"official",install:{type:"preset",name:"internal-comms"}},{name:"slack-gif-creator",description:"Slack GIF \u521B\u5EFA\u5668",group:"official",install:{type:"preset",name:"slack-gif-creator"}},{name:"superpowers",description:"Claude Code Plan\u6A21\u5F0F\u5347\u7EA7\u7248\uFF0C\u8FDE\u7EED\u8FFD\u95EE\u8BA8\u8BBA\u786E\u5B9A\u5F00\u53D1\u65B9\u6848",group:"featured",install:{type:"plugin",marketplace:"obra/superpowers-marketplace",package:"superpowers@superpowers-marketplace"}},{name:"ui-ux-pro-max",description:"\u4E13\u4E1A UI/UX \u8BBE\u8BA1",group:"featured",install:{type:"github",url:"https://github.com/nextlevelbuilder/ui-ux-pro-max-skill/tree/main/.claude/skills/ui-ux-pro-max"}},{name:"Humanizer-zh",description:"\u53BB\u9664\u6587\u672C\u4E2D AI \u751F\u6210\u75D5\u8FF9\uFF0C\u6539\u5199\u5F97\u66F4\u81EA\u7136\u3001\u66F4\u50CF\u4EBA\u7C7B\u4E66\u5199",group:"featured",install:{type:"github",url:"https://github.com/op7418/Humanizer-zh"}},{name:"skill-writer",description:"\u6307\u5BFC\u7528\u6237\u4E3A Claude Code \u521B\u5EFA\u4EE3\u7406\u6280\u80FD",group:"others",install:{type:"github",url:"https://github.com/pytorch/pytorch/tree/main/.claude/skills/skill-writer"}}];function ht(e){return gt.filter(t=>t.group===e)}function ft(){return["official","featured","others"]}function ut(e){if(/^[\w-]+\/[\w-]+$/.test(e)){let[a,c]=e.split("/");return{owner:a,repo:c,branch:"main",path:""}}let t=e.match(/github\.com\/([^/]+)\/([^/]+)(?:\/tree\/([^/]+)(?:\/(.*))?)?/);if(!t)return null;let[,o,n,s="main",i=""]=t;return{owner:o,repo:n.replace(/\.git$/,""),branch:s,path:i}}function Le(){return x.join(process.cwd(),".claude","skills")}function Qt(){let e=Le();return T.existsSync(e)?Zt(e):T.mkdirSync(e,{recursive:!0}),e}function Zt(e){try{let t=T.readdirSync(e,{withFileTypes:!0});for(let o of t)if(o.isDirectory()&&o.name.startsWith(".tmp-")){let n=x.join(e,o.name);T.rmSync(n,{recursive:!0})}}catch{}}function me(e,t,o,n,s){let i=Qt(),a=x.join(i,s);T.existsSync(a)&&(console.log(M.yellow(`Skill "${s}" already exists. Updating...`)),T.rmSync(a,{recursive:!0}));let c=`https://github.com/${e}/${t}.git`,l=x.join(i,`.tmp-${Date.now()}`);try{T.mkdirSync(l,{recursive:!0}),te("git init",{cwd:l,stdio:"pipe"}),te(`git remote add origin ${c}`,{cwd:l,stdio:"pipe"}),te("git config core.sparseCheckout true",{cwd:l,stdio:"pipe"});let m=x.join(l,".git","info","sparse-checkout");T.writeFileSync(m,n?`${n}/
17
+ `:`*
18
+ `),te(`git pull --depth=1 origin ${o}`,{cwd:l,stdio:"pipe"});let f=n?x.join(l,n):l;if(!T.existsSync(f))throw new Error(`Path "${n}" not found in repository`);return yt(f,a),console.log(M.green(`Successfully installed skill "${s}"`)),!0}catch(m){let f=m instanceof Error?m.message:String(m);return console.error(M.red(`Failed to download skill: ${f}`)),!1}finally{T.existsSync(l)&&T.rmSync(l,{recursive:!0})}}function yt(e,t){T.mkdirSync(t,{recursive:!0});let o=T.readdirSync(e,{withFileTypes:!0});for(let n of o){if(n.name===".git")continue;let s=x.join(e,n.name),i=x.join(t,n.name);n.isDirectory()?yt(s,i):T.copyFileSync(s,i)}}function ge(e){let t=gt.find(s=>s.name===e);if(t){if(t.install.type==="preset")return me("anthropics","skills","main",`skills/${t.install.name}`,t.name);if(t.install.type==="github"){let s=ut(t.install.url);return s?me(s.owner,s.repo,s.branch,s.path,t.name):(console.error(M.red(`Invalid GitHub URL in preset: ${t.install.url}`)),!1)}else if(t.install.type==="plugin")return console.error(M.yellow(`Plugin installation not yet supported for "${t.name}"`)),console.log(M.gray(`Marketplace: ${t.install.marketplace}`)),console.log(M.gray(`Package: ${t.install.package}`)),!1}let o=ut(e);if(!o)return console.error(M.red("Invalid GitHub URL or preset name")),console.log(M.gray("Examples:")),console.log(M.gray(" ccem skill add frontend-design")),console.log(M.gray(" ccem skill add https://github.com/owner/repo")),console.log(M.gray(" ccem skill add https://github.com/owner/repo/tree/main/path")),!1;let n;return o.path?n=x.basename(o.path):n=o.repo,me(o.owner,o.repo,o.branch,o.path,n)}function _t(){let e=Le();return T.existsSync(e)?T.readdirSync(e,{withFileTypes:!0}).filter(o=>o.isDirectory()&&!o.name.startsWith(".")).map(o=>({name:o.name,path:x.join(e,o.name)})):[]}function St(e){let t=Le(),o=x.join(t,e);return T.existsSync(o)?(T.rmSync(o,{recursive:!0}),console.log(M.green(`Removed skill "${e}"`)),!0):(console.error(M.red(`Skill "${e}" not found`)),!1)}function eo(e,t){try{return console.log(M.cyan(`Adding marketplace: ${e}...`)),te(`claude plugin marketplace add ${e}`,{stdio:"inherit"}),console.log(M.cyan(`Installing package: ${t}...`)),te(`claude plugin install ${t}`,{stdio:"inherit"}),console.log(M.green(`Successfully installed ${t}`)),!0}catch(o){let n=o instanceof Error?o.message:String(o);return console.error(M.red(`Failed to install from marketplace: ${n}`)),!1}}function Pt(e){switch(console.log(M.cyan(`Installing ${e.name}...`)),e.install.type){case"preset":let t={repo:"anthropics/skills",path:`skills/${e.install.name}`,branch:"main"},[o,n]=t.repo.split("/");return me(o,n,t.branch,t.path,e.name);case"github":return ge(e.install.url);case"plugin":return eo(e.install.marketplace,e.install.package)}}import{render as no}from"ink";import{useState as At,useEffect as to}from"react";import{Box as K,Text as V,useInput as oo,useApp as so}from"ink";import{jsx as H,jsxs as re}from"react/jsx-runtime";function Ct({onSelect:e,onCancel:t}){let{exit:o}=so(),n=ft(),[s,i]=At(0),[a,c]=At(0),l=n[s],f=[...ht(l),null],y=f.length-1;return to(()=>{c(0)},[s]),oo((p,_)=>{if(_.tab&&!_.shift){i(u=>(u+1)%n.length);return}if(_.tab&&_.shift){i(u=>(u-1+n.length)%n.length);return}if(_.upArrow){c(u=>Math.max(0,u-1));return}if(_.downArrow){c(u=>Math.min(y,u+1));return}if(_.return){let u=f[a];e(u===null?"custom":u);return}if(_.escape||p==="q"){t(),o();return}}),re(K,{flexDirection:"column",children:[H(K,{marginBottom:1,children:n.map((p,_)=>{let u=mt[p],g=_===s;return H(K,{marginRight:2,children:re(V,{bold:g,color:g?"cyan":"gray",inverse:g,children:[" ",u.icon," ",u.label," "]})},p)})}),H(K,{marginBottom:1,children:H(V,{color:"gray",children:"\u2500".repeat(50)})}),H(K,{flexDirection:"column",children:f.map((p,_)=>{let u=_===a,g=u?"\u276F ":" ";return p===null?H(K,{children:re(V,{color:u?"yellow":"gray",children:[g,"\u8F93\u5165\u81EA\u5B9A\u4E49 GitHub URL"]})},"custom"):H(K,{children:re(V,{color:u?"cyan":void 0,children:[g,H(V,{bold:u,children:p.name}),re(V,{color:"gray",children:[" - ",p.description]})]})},p.name)})}),H(K,{marginTop:1,children:H(V,{color:"gray",children:"Tab \u5207\u6362\u5206\u7EC4 | \u2191\u2193 \u9009\u62E9 | Enter \u786E\u8BA4 | Esc \u53D6\u6D88"})})]})}import{jsx as ro}from"react/jsx-runtime";async function Tt(){return new Promise(e=>{let t=!1,{unmount:o,waitUntilExit:n}=no(ro(Ct,{onSelect:s=>{t||(t=!0,o(),e(s==="custom"?{type:"custom"}:{type:"skill",skill:s}))},onCancel:()=>{t||(t=!0,o(),e({type:"cancelled"}))}}));n().then(()=>{t||e({type:"cancelled"})})})}var lo=co(import.meta.url),po=fe.dirname(lo),uo=fe.resolve(po,"..","package.json"),mo=JSON.parse(Rt.readFileSync(uo,"utf-8")),L=new io,h=new ao({projectName:"claude-code-env-manager",defaults:{registries:{official:{ANTHROPIC_BASE_URL:"https://api.anthropic.com",ANTHROPIC_MODEL:"claude-sonnet-4-5-20250929",ANTHROPIC_SMALL_FAST_MODEL:"claude-haiku-4-5-20251001"}},current:"official",defaultMode:null}}),ie=["yolo","dev","readonly","safe","ci","audit"],W=null,oe=!0;var q=null,go=e=>{let t=We();t?(W=t,oe=!1):e&&Ve(e),q&&q.abort(),q=new AbortController;let o=q.signal;Ye(o).then(n=>{if(o.aborted)return;let s=oe||W&&n&&W.lastUpdated!==n.lastUpdated;W=n,oe=!1,pe(),s&&e&&e()}).catch(n=>{n.message!=="Aborted"&&(oe=!1,pe())})};L.name("ccem").description("Claude Code Environment Manager - \u7BA1\u7406 Claude Code \u73AF\u5883\u53D8\u91CF\u548C\u6743\u9650").version(mo.version).option("--mode","\u67E5\u770B\u5F53\u524D\u6743\u9650\u6A21\u5F0F").option("--list-modes","\u5217\u51FA\u6240\u6709\u53EF\u7528\u6743\u9650\u6A21\u5F0F");ie.forEach(e=>{let t=O[e];L.command(e).description(`\u4E34\u65F6\u5E94\u7528 ${t.name}\uFF0C\u9000\u51FA\u540E\u8FD8\u539F`).action(async()=>{let o=h.get("registries"),n=h.get("current"),s=o[n];await ue(e,s)})});var be=(e,t)=>{if(!process.stdout.isTTY)return;let o=h.get("current"),s=h.get("registries")[o],i=h.get("defaultMode");s&&(console.log(Xe(o,{ANTHROPIC_BASE_URL:s.ANTHROPIC_BASE_URL,ANTHROPIC_API_KEY:s.ANTHROPIC_API_KEY?j(s.ANTHROPIC_API_KEY):void 0,ANTHROPIC_MODEL:s.ANTHROPIC_MODEL,ANTHROPIC_SMALL_FAST_MODEL:s.ANTHROPIC_SMALL_FAST_MODEL},i)),console.log(""),console.log(Qe(e,t)),console.log(Ze()),console.log(""))},ho=async e=>{let t=h.get("registries");if(!t[e]){console.error(d.red(`Environment '${e}' not found.`));return}h.set("current",e),process.stdout.isTTY?console.log(d.green(`Switched to environment '${e}'`)):console.error(d.green(`Switched to environment '${e}'`)),be(null,!1);let o=t[e],n=[];o.ANTHROPIC_BASE_URL&&n.push(`export ANTHROPIC_BASE_URL="${o.ANTHROPIC_BASE_URL}"`),o.ANTHROPIC_API_KEY&&n.push(`export ANTHROPIC_API_KEY="${j(o.ANTHROPIC_API_KEY)}"`),o.ANTHROPIC_MODEL&&n.push(`export ANTHROPIC_MODEL="${o.ANTHROPIC_MODEL}"`),o.ANTHROPIC_SMALL_FAST_MODEL&&n.push(`export ANTHROPIC_SMALL_FAST_MODEL="${o.ANTHROPIC_SMALL_FAST_MODEL}"`),process.stdout.isTTY?(console.log(d.yellow(`
19
+ To apply to current shell immediately, run:`)),console.log(d.cyan("eval $(ccem env)")),console.log(d.yellow(`
20
+ Or manually export:`)),n.forEach(s=>console.log(s))):n.forEach(s=>console.log(s))};L.command("ls").description("List all configured environments").action(()=>{let e=h.get("registries"),t=h.get("current"),o=new kt({head:["Name","Base URL","Model"],style:{head:["cyan"]}});Object.keys(e).forEach(n=>{let s=e[n],i=n===t?d.green("* "):" ";o.push([i+n,s.ANTHROPIC_BASE_URL||"-",s.ANTHROPIC_MODEL||"-"])}),console.log(o.toString())});L.command("use <name>").description("Switch to a specific environment").action(async e=>{await ho(e)});L.command("add <name>").description("Add a new environment configuration").action(async e=>{let t=h.get("registries");if(t[e]){console.log(d.red(`Environment '${e}' already exists.`));return}let{usePreset:o}=await U.prompt([{type:"confirm",name:"usePreset",message:"Do you want to use a preset configuration?",default:!0}]),n={};if(o){let{presetName:i}=await U.prompt([{type:"list",name:"presetName",message:"Select a preset:",choices:Object.keys(Ae)}]);n=Ae[i]}let s=await U.prompt([{type:"input",name:"ANTHROPIC_BASE_URL",message:"Enter ANTHROPIC_BASE_URL:",default:n.ANTHROPIC_BASE_URL||"https://api.anthropic.com"},{type:"password",name:"ANTHROPIC_API_KEY",message:"Enter ANTHROPIC_API_KEY:"},{type:"input",name:"ANTHROPIC_MODEL",message:"Enter ANTHROPIC_MODEL:",default:n.ANTHROPIC_MODEL||"claude-sonnet-4-5-20250929"},{type:"input",name:"ANTHROPIC_SMALL_FAST_MODEL",message:"Enter ANTHROPIC_SMALL_FAST_MODEL:",default:n.ANTHROPIC_SMALL_FAST_MODEL||"claude-haiku-4-5-20251001"}]);s.ANTHROPIC_API_KEY&&(s.ANTHROPIC_API_KEY=$e(s.ANTHROPIC_API_KEY)),t[e]=s,h.set("registries",t),console.log(d.green(`Environment '${e}' added successfully.`))});L.command("del <name>").description("Delete an environment configuration").action(e=>{let t=h.get("registries");if(!t[e]){console.log(d.red(`Environment '${e}' not found.`));return}if(e==="official"){console.log(d.red("Cannot delete default 'official' environment."));return}delete t[e],h.set("registries",t),h.get("current")===e&&(h.set("current","official"),console.log(d.yellow("Deleted current environment. Switched back to 'official'."))),console.log(d.green(`Environment '${e}' deleted.`))});L.command("current").description("Show current environment name").action(()=>{let e=h.get("current");console.log(d.green(e))});L.command("env").description("Output environment variables for shell eval").option("--json","Output as JSON").action(e=>{let t=h.get("registries"),o=h.get("current"),n=t[o];if(!n)return;let s={...n};s.ANTHROPIC_API_KEY&&(s.ANTHROPIC_API_KEY=j(s.ANTHROPIC_API_KEY)),e.json?console.log(JSON.stringify(s,null,2)):(s.ANTHROPIC_BASE_URL&&console.log(`export ANTHROPIC_BASE_URL="${s.ANTHROPIC_BASE_URL}"`),s.ANTHROPIC_API_KEY&&console.log(`export ANTHROPIC_API_KEY="${s.ANTHROPIC_API_KEY}"`),s.ANTHROPIC_MODEL&&console.log(`export ANTHROPIC_MODEL="${s.ANTHROPIC_MODEL}"`),s.ANTHROPIC_SMALL_FAST_MODEL&&console.log(`export ANTHROPIC_SMALL_FAST_MODEL="${s.ANTHROPIC_SMALL_FAST_MODEL}"`))});L.command("run <command...>").description("Run a command with the current environment variables").action(e=>{let t=h.get("registries"),o=h.get("current"),n=t[o];n||(console.error(d.red("No environment configuration found.")),process.exit(1));let s={...process.env};n.ANTHROPIC_BASE_URL&&(s.ANTHROPIC_BASE_URL=n.ANTHROPIC_BASE_URL),n.ANTHROPIC_API_KEY&&(s.ANTHROPIC_API_KEY=j(n.ANTHROPIC_API_KEY||"")),n.ANTHROPIC_MODEL&&(s.ANTHROPIC_MODEL=n.ANTHROPIC_MODEL),n.ANTHROPIC_SMALL_FAST_MODEL&&(s.ANTHROPIC_SMALL_FAST_MODEL=n.ANTHROPIC_SMALL_FAST_MODEL);let[i,...a]=e;Et(i,a,{env:s,stdio:"inherit",shell:!0}).on("exit",l=>{process.exit(l??0)})});var Ne=L.command("setup").description("Setup commands for permanent configurations");Ne.command("perms").description("\u6C38\u4E45\u914D\u7F6E\u6743\u9650\u6A21\u5F0F").option("--yolo","\u5E94\u7528 YOLO \u6A21\u5F0F\uFF08\u5168\u90E8\u653E\u5F00\uFF09").option("--dev","\u5E94\u7528\u5F00\u53D1\u6A21\u5F0F").option("--readonly","\u5E94\u7528\u53EA\u8BFB\u6A21\u5F0F").option("--safe","\u5E94\u7528\u5B89\u5168\u6A21\u5F0F").option("--ci","\u5E94\u7528 CI/CD \u6A21\u5F0F").option("--audit","\u5E94\u7528\u5BA1\u8BA1\u6A21\u5F0F").option("--reset","\u91CD\u7F6E\u6743\u9650\u914D\u7F6E").action(function(){let e=this.opts();if(e.reset){it();return}for(let t of ie)if(e[t]){rt(t);return}console.log(d.yellow("\u8BF7\u6307\u5B9A\u4E00\u4E2A\u6743\u9650\u6A21\u5F0F\uFF0C\u4F8B\u5982: ccem setup perms --dev")),console.log(d.gray("\u53EF\u7528\u6A21\u5F0F: "+ie.join(", "))),console.log(d.gray("\u91CD\u7F6E\u6743\u9650: ccem setup perms --reset"))});Ne.command("default-mode").description("\u8BBE\u7F6E\u9ED8\u8BA4\u6743\u9650\u6A21\u5F0F").option("--yolo","YOLO \u6A21\u5F0F").option("--dev","\u5F00\u53D1\u6A21\u5F0F").option("--readonly","\u53EA\u8BFB\u6A21\u5F0F").option("--safe","\u5B89\u5168\u6A21\u5F0F").option("--ci","CI/CD \u6A21\u5F0F").option("--audit","\u5BA1\u8BA1\u6A21\u5F0F").option("--reset","\u6E05\u9664\u9ED8\u8BA4\u6A21\u5F0F").action(function(){let e=this.opts();if(e.reset){h.set("defaultMode",null),console.log(d.green("\u5DF2\u6E05\u9664\u9ED8\u8BA4\u6743\u9650\u6A21\u5F0F"));return}for(let o of ie)if(e[o]){h.set("defaultMode",o),console.log(d.green(`\u5DF2\u8BBE\u7F6E\u9ED8\u8BA4\u6743\u9650\u6A21\u5F0F: ${O[o].name}`)),console.log(d.gray("\u4E0B\u6B21\u542F\u52A8 ccem \u65F6\u5C06\u9ED8\u8BA4\u4F7F\u7528\u6B64\u6A21\u5F0F"));return}let t=h.get("defaultMode");t&&O[t]?console.log(d.green(`\u5F53\u524D\u9ED8\u8BA4\u6A21\u5F0F: ${O[t].name}`)):console.log(d.yellow("\u672A\u8BBE\u7F6E\u9ED8\u8BA4\u6743\u9650\u6A21\u5F0F")),console.log(d.gray(`
21
+ \u8BBE\u7F6E\u9ED8\u8BA4\u6A21\u5F0F: ccem setup default-mode --dev`)),console.log(d.gray("\u6E05\u9664\u9ED8\u8BA4\u6A21\u5F0F: ccem setup default-mode --reset")),console.log(d.gray("\u53EF\u7528\u6A21\u5F0F: "+ie.join(", ")))});Ne.command("init").description("\u521D\u59CB\u5316 Claude Code \u5168\u5C40\u914D\u7F6E\uFF08\u8DF3\u8FC7 onboarding\u3001\u7981\u7528\u9065\u6D4B\u3001\u5B89\u88C5 MCP \u5DE5\u5177\uFF09").action(async()=>{await pt()});var Be=L.command("skill").description("\u7BA1\u7406 Claude Code skills");Be.command("add [url]").description("\u6DFB\u52A0 skill\uFF08\u4ECE\u5B98\u65B9\u9884\u8BBE\u6216 GitHub URL\uFF09").action(async e=>{if(e)ge(e);else{let t=await Tt();if(t.type==="cancelled"){console.log(d.yellow("\u5DF2\u53D6\u6D88"));return}if(t.type==="custom"){let{customUrl:o}=await U.prompt([{type:"input",name:"customUrl",message:"\u8F93\u5165 GitHub URL:",validate:n=>n.trim()?!n.includes("github.com")&&!/^[\w-]+\/[\w-]+$/.test(n)?"\u8BF7\u8F93\u5165\u6709\u6548\u7684 GitHub URL \u6216 owner/repo \u683C\u5F0F":!0:"\u8BF7\u8F93\u5165\u6709\u6548\u7684 URL"}]);ge(o)}else t.skill&&Pt(t.skill)}});Be.command("ls").description("\u5217\u51FA\u5DF2\u5B89\u88C5\u7684 skills").action(()=>{let e=_t();if(e.length===0){console.log(d.yellow("\u5F53\u524D\u76EE\u5F55\u6CA1\u6709\u5B89\u88C5\u4EFB\u4F55 skill")),console.log(d.gray("\u4F7F\u7528 ccem skill add \u6DFB\u52A0 skills"));return}let t=new kt({head:["Name","Path"],style:{head:["cyan"]}});e.forEach(o=>{t.push([d.green(o.name),d.gray(o.path)])}),console.log(t.toString())});Be.command("rm <name>").description("\u5220\u9664\u5DF2\u5B89\u88C5\u7684 skill").action(e=>{St(e)});L.action(async e=>{if(e.mode){at();return}if(e.listModes){ct();return}for(go(()=>{he.cursorTo(process.stdout,0,0),he.clearScreenDown(process.stdout),be(W,oe),console.log("");let o=h.get("defaultMode");console.log(d.gray("?")+" "+d.gray("Select action")+" "+d.cyan("(Use arrow keys)")),Oe(o).forEach((s,i)=>{let a=i===0?d.cyan("\u276F"):" ";console.log(a+" "+s.name)})});;){console.clear(),be(W,oe),console.log("");let o=h.get("defaultMode"),n=h.get("registries"),s=h.get("current"),i=n[s],{action:a}=await U.prompt([{type:"list",name:"action",message:d.gray("Select action"),choices:Oe(o),prefix:d.gray("?")}]);if(a==="start"){if(q&&(q.abort(),q=null),pe(),i||(ne.error("No environment configuration found."),process.exit(1)),o&&O[o])await ue(o,i);else{let c={...process.env};i.ANTHROPIC_BASE_URL&&(c.ANTHROPIC_BASE_URL=i.ANTHROPIC_BASE_URL),i.ANTHROPIC_API_KEY&&(c.ANTHROPIC_API_KEY=j(i.ANTHROPIC_API_KEY||"")),i.ANTHROPIC_MODEL&&(c.ANTHROPIC_MODEL=i.ANTHROPIC_MODEL),i.ANTHROPIC_SMALL_FAST_MODEL&&(c.ANTHROPIC_SMALL_FAST_MODEL=i.ANTHROPIC_SMALL_FAST_MODEL),console.log(tt()),Et("claude",[],{env:c,stdio:"inherit",shell:!0}).on("exit",m=>{process.exit(m??0)})}return}else if(a==="usage")console.clear(),W?console.log(ot(W)):ne.warning("No usage data available"),await U.prompt([{type:"input",name:"continue",message:d.gray("Press Enter to continue..."),prefix:""}]);else if(a==="switch"){let{selected:c}=await U.prompt([{type:"list",name:"selected",message:d.gray("Select environment"),choices:et(n,s),prefix:d.gray("?"),default:s}]);h.set("current",c)}else if(a==="perm"){let{permMode:c}=await U.prompt([{type:"list",name:"permMode",message:d.gray("Select permission mode"),choices:Me(null,!1),prefix:d.gray("?")}]);if(c!=="back"){await ue(c,i);return}}else if(a==="setDefault"){let c=h.get("defaultMode"),{selectedMode:l}=await U.prompt([{type:"list",name:"selectedMode",message:d.gray("Set default permission mode"),choices:Me(c,!0),prefix:d.gray("?")}]);l==="clear"?(h.set("defaultMode",null),ne.success("Default mode cleared"),await new Promise(m=>setTimeout(m,800))):l!=="back"&&(h.set("defaultMode",l),ne.success(`Default mode set: ${O[l].name}`),await new Promise(m=>setTimeout(m,800)))}else process.exit(0)}});L.parse(process.argv);