ccem 2.0.0-beta → 2.0.0-beta.2

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 (2) hide show
  1. package/dist/index.js +443 -131
  2. package/package.json +14 -14
package/dist/index.js CHANGED
@@ -7,28 +7,343 @@ import inquirer from "inquirer";
7
7
  import chalk7 from "chalk";
8
8
  import Table3 from "cli-table3";
9
9
  import { spawn as spawn3 } from "child_process";
10
- import * as fs7 from "fs";
11
- import * as path5 from "path";
10
+ import * as fs8 from "fs";
11
+ import * as path6 from "path";
12
12
  import { fileURLToPath } from "url";
13
- import { encrypt as encrypt2, decrypt as decrypt2, ENV_PRESETS, PERMISSION_PRESETS as PERMISSION_PRESETS4, getCcemConfigDir, ensureCcemDir as ensureCcemDir3, getCcemConfigPath, getLegacyConfigPath } from "@ccem/core";
13
+
14
+ // ../../packages/core/dist/chunk-YO7HO5AS.js
15
+ var ENV_PRESETS = {
16
+ "GLM": {
17
+ ANTHROPIC_BASE_URL: "https://open.bigmodel.cn/api/anthropic",
18
+ ANTHROPIC_MODEL: "glm-4.6",
19
+ ANTHROPIC_SMALL_FAST_MODEL: "glm-4.5-air"
20
+ },
21
+ "KIMI": {
22
+ ANTHROPIC_BASE_URL: "https://api.moonshot.cn/anthropic",
23
+ ANTHROPIC_MODEL: "kimi-k2-thinking-turbo",
24
+ ANTHROPIC_SMALL_FAST_MODEL: "kimi-k2-turbo-preview"
25
+ },
26
+ "MiniMax": {
27
+ ANTHROPIC_BASE_URL: "https://api.minimaxi.com/anthropic",
28
+ ANTHROPIC_MODEL: "MiniMax-M2",
29
+ ANTHROPIC_SMALL_FAST_MODEL: "MiniMax-M2"
30
+ },
31
+ "DeepSeek": {
32
+ ANTHROPIC_BASE_URL: "https://api.deepseek.com/anthropic",
33
+ ANTHROPIC_MODEL: "deepseek-chat",
34
+ ANTHROPIC_SMALL_FAST_MODEL: "deepseek-chat"
35
+ }
36
+ };
37
+ var PERMISSION_PRESETS = {
38
+ "yolo": {
39
+ name: "YOLO \u6A21\u5F0F",
40
+ description: "\u5168\u90E8\u653E\u5F00\uFF0C\u65E0\u4EFB\u4F55\u9650\u5236",
41
+ permissionMode: "bypassPermissions",
42
+ permissions: {
43
+ allow: [
44
+ "Bash(*)",
45
+ "Read(*)",
46
+ "Edit(*)",
47
+ "Write(*)",
48
+ "WebFetch(*)",
49
+ "WebSearch(*)",
50
+ "Glob(*)",
51
+ "Grep(*)",
52
+ "LSP(*)",
53
+ "NotebookEdit(*)"
54
+ ],
55
+ deny: []
56
+ }
57
+ },
58
+ "dev": {
59
+ name: "\u5F00\u53D1\u6A21\u5F0F",
60
+ description: "\u65E5\u5E38\u5F00\u53D1\u6743\u9650\uFF0C\u4FDD\u62A4\u654F\u611F\u6587\u4EF6",
61
+ permissionMode: "acceptEdits",
62
+ permissions: {
63
+ allow: [
64
+ "Read(*)",
65
+ "Edit(*)",
66
+ "Write(*)",
67
+ "Glob(*)",
68
+ "Grep(*)",
69
+ "LSP(*)",
70
+ "NotebookEdit(*)",
71
+ "Bash(npm:*)",
72
+ "Bash(pnpm:*)",
73
+ "Bash(yarn:*)",
74
+ "Bash(bun:*)",
75
+ "Bash(node:*)",
76
+ "Bash(npx:*)",
77
+ "Bash(git:*)",
78
+ "Bash(tsc:*)",
79
+ "Bash(tsx:*)",
80
+ "Bash(eslint:*)",
81
+ "Bash(prettier:*)",
82
+ "Bash(jest:*)",
83
+ "Bash(vitest:*)",
84
+ "Bash(cargo:*)",
85
+ "Bash(python:*)",
86
+ "Bash(pip:*)",
87
+ "Bash(go:*)",
88
+ "Bash(make:*)",
89
+ "Bash(cmake:*)",
90
+ "Bash(ls:*)",
91
+ "Bash(cat:*)",
92
+ "Bash(head:*)",
93
+ "Bash(tail:*)",
94
+ "Bash(find:*)",
95
+ "Bash(wc:*)",
96
+ "Bash(mkdir:*)",
97
+ "Bash(cp:*)",
98
+ "Bash(mv:*)",
99
+ "Bash(touch:*)",
100
+ "WebSearch"
101
+ ],
102
+ deny: [
103
+ "Read(.env)",
104
+ "Read(.env.*)",
105
+ "Read(**/secrets/**)",
106
+ "Read(**/*.pem)",
107
+ "Read(**/*.key)",
108
+ "Read(**/*credential*)",
109
+ "Bash(rm -rf:*)",
110
+ "Bash(sudo:*)",
111
+ "Bash(chmod:*)",
112
+ "Bash(chown:*)"
113
+ ]
114
+ }
115
+ },
116
+ "readonly": {
117
+ name: "\u53EA\u8BFB\u6A21\u5F0F",
118
+ description: "\u4EC5\u5141\u8BB8\u8BFB\u53D6\u548C\u641C\u7D22\uFF0C\u7981\u6B62\u4EFB\u4F55\u4FEE\u6539",
119
+ permissionMode: "plan",
120
+ permissions: {
121
+ allow: [
122
+ "Read(*)",
123
+ "Glob(*)",
124
+ "Grep(*)",
125
+ "LSP(*)",
126
+ "Bash(git status:*)",
127
+ "Bash(git log:*)",
128
+ "Bash(git diff:*)",
129
+ "Bash(git branch:*)",
130
+ "Bash(git show:*)",
131
+ "Bash(ls:*)",
132
+ "Bash(cat:*)",
133
+ "Bash(head:*)",
134
+ "Bash(tail:*)",
135
+ "Bash(find:*)",
136
+ "Bash(wc:*)",
137
+ "Bash(file:*)",
138
+ "WebSearch"
139
+ ],
140
+ deny: [
141
+ "Edit(*)",
142
+ "Write(*)",
143
+ "NotebookEdit(*)",
144
+ "Bash(rm:*)",
145
+ "Bash(mv:*)",
146
+ "Bash(cp:*)",
147
+ "Bash(mkdir:*)",
148
+ "Bash(touch:*)",
149
+ "Bash(git add:*)",
150
+ "Bash(git commit:*)",
151
+ "Bash(git push:*)",
152
+ "Bash(git checkout:*)",
153
+ "Bash(git reset:*)",
154
+ "Bash(npm install:*)",
155
+ "Bash(pnpm install:*)",
156
+ "Bash(yarn add:*)"
157
+ ]
158
+ }
159
+ },
160
+ "safe": {
161
+ name: "\u5B89\u5168\u6A21\u5F0F",
162
+ description: "\u4FDD\u5B88\u6743\u9650\uFF0C\u9002\u5408\u4E0D\u719F\u6089\u7684\u4EE3\u7801\u5E93",
163
+ permissionMode: "default",
164
+ permissions: {
165
+ allow: [
166
+ "Read(*)",
167
+ "Glob(*)",
168
+ "Grep(*)",
169
+ "LSP(*)",
170
+ "Bash(git status:*)",
171
+ "Bash(git log:*)",
172
+ "Bash(git diff:*)",
173
+ "Bash(ls:*)",
174
+ "Bash(cat:*)",
175
+ "Bash(head:*)",
176
+ "Bash(tail:*)",
177
+ "Bash(find:*)",
178
+ "Bash(wc:*)"
179
+ ],
180
+ deny: [
181
+ "Read(.env)",
182
+ "Read(.env.*)",
183
+ "Read(**/secrets/**)",
184
+ "Read(**/*.pem)",
185
+ "Read(**/*.key)",
186
+ "Read(**/*credential*)",
187
+ "Read(**/*password*)",
188
+ "Edit(*)",
189
+ "Write(*)",
190
+ "NotebookEdit(*)",
191
+ "Bash(curl:*)",
192
+ "Bash(wget:*)",
193
+ "Bash(ssh:*)",
194
+ "Bash(scp:*)",
195
+ "Bash(rm:*)",
196
+ "Bash(mv:*)",
197
+ "WebFetch(*)"
198
+ ]
199
+ }
200
+ },
201
+ "ci": {
202
+ name: "CI/CD \u6A21\u5F0F",
203
+ description: "\u9002\u5408\u81EA\u52A8\u5316\u6D41\u6C34\u7EBF\u7684\u6743\u9650",
204
+ permissionMode: "default",
205
+ permissions: {
206
+ allow: [
207
+ "Read(*)",
208
+ "Edit(*)",
209
+ "Write(*)",
210
+ "Glob(*)",
211
+ "Grep(*)",
212
+ "LSP(*)",
213
+ "Bash(npm:*)",
214
+ "Bash(pnpm:*)",
215
+ "Bash(yarn:*)",
216
+ "Bash(node:*)",
217
+ "Bash(git:*)",
218
+ "Bash(docker:*)",
219
+ "Bash(make:*)",
220
+ "Bash(cargo:*)",
221
+ "Bash(go:*)",
222
+ "Bash(python:*)",
223
+ "Bash(pip:*)",
224
+ "Bash(pytest:*)",
225
+ "Bash(jest:*)",
226
+ "Bash(vitest:*)"
227
+ ],
228
+ deny: [
229
+ "Read(.env.local)",
230
+ "Read(**/secrets/**)",
231
+ "Bash(sudo:*)",
232
+ "Bash(ssh:*)",
233
+ "Bash(scp:*)",
234
+ "WebFetch(*)",
235
+ "WebSearch"
236
+ ]
237
+ }
238
+ },
239
+ "audit": {
240
+ name: "\u5BA1\u8BA1\u6A21\u5F0F",
241
+ description: "\u4EC5\u8BFB\u53D6\u548C\u641C\u7D22\uFF0C\u7528\u4E8E\u5B89\u5168\u5BA1\u8BA1",
242
+ permissionMode: "plan",
243
+ permissions: {
244
+ allow: [
245
+ "Read(*)",
246
+ "Glob(*)",
247
+ "Grep(*)",
248
+ "LSP(*)",
249
+ "Bash(git log:*)",
250
+ "Bash(git blame:*)",
251
+ "Bash(git show:*)",
252
+ "Bash(git diff:*)",
253
+ "Bash(ls:*)",
254
+ "Bash(find:*)",
255
+ "Bash(wc:*)",
256
+ "Bash(file:*)",
257
+ "Bash(stat:*)"
258
+ ],
259
+ deny: [
260
+ "Edit(*)",
261
+ "Write(*)",
262
+ "NotebookEdit(*)",
263
+ "Bash(rm:*)",
264
+ "Bash(mv:*)",
265
+ "Bash(cp:*)",
266
+ "Bash(curl:*)",
267
+ "Bash(wget:*)",
268
+ "Bash(ssh:*)",
269
+ "WebFetch(*)"
270
+ ]
271
+ }
272
+ }
273
+ };
274
+ var getPermissionModeNames = () => {
275
+ return Object.keys(PERMISSION_PRESETS);
276
+ };
277
+
278
+ // ../../packages/core/dist/index.js
279
+ import crypto from "crypto";
280
+ import fs from "fs";
281
+ import path from "path";
282
+ var ALGORITHM = "aes-256-cbc";
283
+ var SECRET_KEY = crypto.scryptSync("claude-code-env-manager-secret", "salt", 32);
284
+ var encrypt = (text) => {
285
+ if (!text) return text;
286
+ const iv = crypto.randomBytes(16);
287
+ const cipher = crypto.createCipheriv(ALGORITHM, SECRET_KEY, iv);
288
+ let encrypted = cipher.update(text, "utf8", "hex");
289
+ encrypted += cipher.final("hex");
290
+ return `enc:${iv.toString("hex")}:${encrypted}`;
291
+ };
292
+ var decrypt = (text) => {
293
+ if (!text || !text.startsWith("enc:")) return text;
294
+ try {
295
+ const parts = text.split(":");
296
+ if (parts.length !== 3) return text;
297
+ const iv = Buffer.from(parts[1], "hex");
298
+ const encryptedText = parts[2];
299
+ const decipher = crypto.createDecipheriv(ALGORITHM, SECRET_KEY, iv);
300
+ let decrypted = decipher.update(encryptedText, "hex", "utf8");
301
+ decrypted += decipher.final("utf8");
302
+ return decrypted;
303
+ } catch {
304
+ return text;
305
+ }
306
+ };
307
+ var getHomeDir = () => {
308
+ return process.env.HOME || process.env.USERPROFILE || "";
309
+ };
310
+ var getCcemConfigDir = () => {
311
+ return path.join(getHomeDir(), ".ccem");
312
+ };
313
+ var getCcemConfigPath = () => {
314
+ return path.join(getCcemConfigDir(), "config.json");
315
+ };
316
+ var ensureCcemDir = () => {
317
+ const ccemDir = getCcemConfigDir();
318
+ if (!fs.existsSync(ccemDir)) {
319
+ fs.mkdirSync(ccemDir, { recursive: true });
320
+ }
321
+ return ccemDir;
322
+ };
323
+ var getLegacyConfigPath = () => {
324
+ const home = getHomeDir();
325
+ if (process.platform === "darwin") {
326
+ return path.join(home, "Library", "Preferences", "claude-code-env-manager-nodejs", "config.json");
327
+ }
328
+ return path.join(home, ".config", "claude-code-env-manager-nodejs", "config.json");
329
+ };
14
330
 
15
331
  // src/ui.ts
16
332
  import chalk from "chalk";
17
333
  import Table from "cli-table3";
18
- import { PERMISSION_PRESETS } from "@ccem/core";
19
334
 
20
335
  // src/usage.ts
21
- import * as fs from "fs";
336
+ import * as fs2 from "fs";
22
337
  import * as fsPromises from "fs/promises";
23
- import * as path from "path";
338
+ import * as path2 from "path";
24
339
  import * as os from "os";
25
340
  import * as readline from "readline";
26
- var CLAUDE_PROJECTS_DIR = path.join(os.homedir(), ".claude", "projects");
27
- var CCEM_DIR = path.join(os.homedir(), ".ccem");
341
+ var CLAUDE_PROJECTS_DIR = path2.join(os.homedir(), ".claude", "projects");
342
+ var CCEM_DIR = path2.join(os.homedir(), ".ccem");
28
343
  var CACHE_VERSION = 1;
29
- var getCachePath = () => path.join(CCEM_DIR, "usage-cache.json");
30
- var getPricesPath = () => path.join(CCEM_DIR, "model-prices.json");
31
- async function ensureCcemDir() {
344
+ var getCachePath = () => path2.join(CCEM_DIR, "usage-cache.json");
345
+ var getPricesPath = () => path2.join(CCEM_DIR, "model-prices.json");
346
+ async function ensureCcemDir2() {
32
347
  try {
33
348
  await fsPromises.access(CCEM_DIR);
34
349
  } catch {
@@ -37,7 +352,7 @@ async function ensureCcemDir() {
37
352
  }
38
353
  var LITELLM_PRICES_URL = "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json";
39
354
  var getBundledPricesPath = () => {
40
- return path.join(__dirname, "..", "model-prices.json");
355
+ return path2.join(__dirname, "..", "model-prices.json");
41
356
  };
42
357
  var DEFAULT_PRICES = {
43
358
  "claude-opus-4-5": {
@@ -66,7 +381,7 @@ function normalizeModelName(model) {
66
381
  var pricesCache = null;
67
382
  async function loadPrices() {
68
383
  if (pricesCache) return pricesCache;
69
- await ensureCcemDir();
384
+ await ensureCcemDir2();
70
385
  const pricesPath = getPricesPath();
71
386
  try {
72
387
  const response = await fetch(LITELLM_PRICES_URL, { signal: AbortSignal.timeout(1e3) });
@@ -156,8 +471,8 @@ async function getFileMetaAsync(filePath) {
156
471
  function loadCacheSync() {
157
472
  try {
158
473
  const cachePath = getCachePath();
159
- if (!fs.existsSync(cachePath)) return null;
160
- const data = JSON.parse(fs.readFileSync(cachePath, "utf-8"));
474
+ if (!fs2.existsSync(cachePath)) return null;
475
+ const data = JSON.parse(fs2.readFileSync(cachePath, "utf-8"));
161
476
  if (data.version !== CACHE_VERSION) return null;
162
477
  return data;
163
478
  } catch {
@@ -216,7 +531,7 @@ function getUsageStatsFromCache() {
216
531
  }
217
532
  async function saveCacheAsync(cache) {
218
533
  try {
219
- await ensureCcemDir();
534
+ await ensureCcemDir2();
220
535
  await fsPromises.writeFile(getCachePath(), JSON.stringify(cache, null, 2));
221
536
  } catch {
222
537
  }
@@ -224,7 +539,7 @@ async function saveCacheAsync(cache) {
224
539
  async function parseJSONLFileAsync(filePath, prices, signal) {
225
540
  const entries = [];
226
541
  try {
227
- const fileStream = fs.createReadStream(filePath, { encoding: "utf-8" });
542
+ const fileStream = fs2.createReadStream(filePath, { encoding: "utf-8" });
228
543
  const rl = readline.createInterface({
229
544
  input: fileStream,
230
545
  crlfDelay: Infinity
@@ -278,14 +593,14 @@ async function getAllJSONLFilesAsync() {
278
593
  if (!projectsDirExists) return files;
279
594
  const projects = await fsPromises.readdir(CLAUDE_PROJECTS_DIR);
280
595
  for (const project of projects) {
281
- const projectPath = path.join(CLAUDE_PROJECTS_DIR, project);
596
+ const projectPath = path2.join(CLAUDE_PROJECTS_DIR, project);
282
597
  try {
283
598
  const stat2 = await fsPromises.stat(projectPath);
284
599
  if (stat2.isDirectory()) {
285
600
  const projectFiles = await fsPromises.readdir(projectPath);
286
601
  for (const file of projectFiles) {
287
602
  if (file.endsWith(".jsonl")) {
288
- files.push(path.join(projectPath, file));
603
+ files.push(path2.join(projectPath, file));
289
604
  }
290
605
  }
291
606
  }
@@ -506,10 +821,10 @@ var renderLogoWithEnvPanel = (envName, env, defaultMode) => {
506
821
  const parsed = new URL(url);
507
822
  const protocol = parsed.protocol + "//";
508
823
  const host = parsed.host;
509
- const path6 = parsed.pathname + parsed.search;
824
+ const path7 = parsed.pathname + parsed.search;
510
825
  const hostStart = host.slice(0, 8);
511
826
  const hostEnd = host.slice(-4);
512
- const pathPart = path6.length > 10 ? path6.slice(0, 7) + "..." : path6;
827
+ const pathPart = path7.length > 10 ? path7.slice(0, 7) + "..." : path7;
513
828
  return `${protocol}${hostStart}...${hostEnd}${pathPart}`;
514
829
  } catch {
515
830
  return truncate(url, max);
@@ -947,64 +1262,62 @@ var selectEnvWithKeys = (registries, current) => {
947
1262
  };
948
1263
 
949
1264
  // src/permissions.ts
950
- import fs4 from "fs";
1265
+ import fs5 from "fs";
951
1266
  import chalk3 from "chalk";
952
1267
  import Table2 from "cli-table3";
953
- import { PERMISSION_PRESETS as PERMISSION_PRESETS3, getPermissionModeNames } from "@ccem/core";
954
1268
 
955
1269
  // src/utils.ts
956
- import crypto from "crypto";
957
- import fs2 from "fs";
958
- import path2 from "path";
959
- var SECRET_KEY = crypto.scryptSync("claude-code-env-manager-secret", "salt", 32);
1270
+ import crypto2 from "crypto";
1271
+ import fs3 from "fs";
1272
+ import path3 from "path";
1273
+ var SECRET_KEY2 = crypto2.scryptSync("claude-code-env-manager-secret", "salt", 32);
960
1274
  var findProjectRoot = () => {
961
1275
  let currentDir = process.cwd();
962
- const root = path2.parse(currentDir).root;
1276
+ const root = path3.parse(currentDir).root;
963
1277
  while (currentDir !== root) {
964
- if (fs2.existsSync(path2.join(currentDir, ".git")) || fs2.existsSync(path2.join(currentDir, "package.json"))) {
1278
+ if (fs3.existsSync(path3.join(currentDir, ".git")) || fs3.existsSync(path3.join(currentDir, "package.json"))) {
965
1279
  return currentDir;
966
1280
  }
967
- currentDir = path2.dirname(currentDir);
1281
+ currentDir = path3.dirname(currentDir);
968
1282
  }
969
1283
  return process.cwd();
970
1284
  };
971
1285
  var getSettingsPath = (useLocal = true) => {
972
1286
  const projectRoot = findProjectRoot();
973
- const claudeDir = path2.join(projectRoot, ".claude");
1287
+ const claudeDir = path3.join(projectRoot, ".claude");
974
1288
  const filename = useLocal ? "settings.local.json" : "settings.json";
975
- return path2.join(claudeDir, filename);
1289
+ return path3.join(claudeDir, filename);
976
1290
  };
977
1291
  var ensureClaudeDir = () => {
978
1292
  const projectRoot = findProjectRoot();
979
- const claudeDir = path2.join(projectRoot, ".claude");
980
- if (!fs2.existsSync(claudeDir)) {
981
- fs2.mkdirSync(claudeDir, { recursive: true });
1293
+ const claudeDir = path3.join(projectRoot, ".claude");
1294
+ if (!fs3.existsSync(claudeDir)) {
1295
+ fs3.mkdirSync(claudeDir, { recursive: true });
982
1296
  }
983
1297
  return claudeDir;
984
1298
  };
985
- var getHomeDir = () => {
1299
+ var getHomeDir2 = () => {
986
1300
  return process.env.HOME || process.env.USERPROFILE || "";
987
1301
  };
988
1302
  var getGlobalClaudeConfigPath = () => {
989
- return path2.join(getHomeDir(), ".claude.json");
1303
+ return path3.join(getHomeDir2(), ".claude.json");
990
1304
  };
991
1305
  var getGlobalClaudeSettingsPath = () => {
992
- return path2.join(getHomeDir(), ".claude", "settings.json");
1306
+ return path3.join(getHomeDir2(), ".claude", "settings.json");
993
1307
  };
994
1308
  var ensureGlobalClaudeDir = () => {
995
- const claudeDir = path2.join(getHomeDir(), ".claude");
996
- if (!fs2.existsSync(claudeDir)) {
997
- fs2.mkdirSync(claudeDir, { recursive: true });
1309
+ const claudeDir = path3.join(getHomeDir2(), ".claude");
1310
+ if (!fs3.existsSync(claudeDir)) {
1311
+ fs3.mkdirSync(claudeDir, { recursive: true });
998
1312
  }
999
1313
  return claudeDir;
1000
1314
  };
1001
1315
 
1002
1316
  // src/launcher.ts
1003
1317
  import { spawn } from "child_process";
1004
- import * as fs3 from "fs";
1005
- import * as path3 from "path";
1318
+ import * as fs4 from "fs";
1319
+ import * as path4 from "path";
1006
1320
  import chalk2 from "chalk";
1007
- import { decrypt, PERMISSION_PRESETS as PERMISSION_PRESETS2, ensureCcemDir as ensureCcemDir2 } from "@ccem/core";
1008
1321
  function buildEnvVars(envConfig) {
1009
1322
  const vars = {};
1010
1323
  if (envConfig.ANTHROPIC_BASE_URL) vars.ANTHROPIC_BASE_URL = envConfig.ANTHROPIC_BASE_URL;
@@ -1014,7 +1327,7 @@ function buildEnvVars(envConfig) {
1014
1327
  return vars;
1015
1328
  }
1016
1329
  function buildPermArgs(modeName) {
1017
- const preset = PERMISSION_PRESETS2[modeName];
1330
+ const preset = PERMISSION_PRESETS[modeName];
1018
1331
  if (!preset) return [];
1019
1332
  const args = ["--permission-mode", preset.permissionMode];
1020
1333
  if (preset.permissions.allow.length > 0) {
@@ -1028,9 +1341,9 @@ function buildPermArgs(modeName) {
1028
1341
  return args;
1029
1342
  }
1030
1343
  function ensureSessionsDir() {
1031
- const dir = path3.join(ensureCcemDir2(), "sessions");
1032
- if (!fs3.existsSync(dir)) {
1033
- fs3.mkdirSync(dir, { recursive: true });
1344
+ const dir = path4.join(ensureCcemDir(), "sessions");
1345
+ if (!fs4.existsSync(dir)) {
1346
+ fs4.mkdirSync(dir, { recursive: true });
1034
1347
  }
1035
1348
  return dir;
1036
1349
  }
@@ -1043,7 +1356,7 @@ async function launchClaude(options) {
1043
1356
  delete env.CLAUDECODE;
1044
1357
  const args = [];
1045
1358
  if (permMode) {
1046
- const preset = PERMISSION_PRESETS2[permMode];
1359
+ const preset = PERMISSION_PRESETS[permMode];
1047
1360
  if (preset) {
1048
1361
  if (!silent) {
1049
1362
  console.log(chalk2.green(`\u5DF2\u5E94\u7528 ${preset.name}\uFF08\u4E34\u65F6\uFF09`));
@@ -1072,8 +1385,8 @@ async function launchClaude(options) {
1072
1385
  child.on("exit", (code) => {
1073
1386
  if (sessionId) {
1074
1387
  try {
1075
- fs3.writeFileSync(
1076
- path3.join(sessionsDir, `${sessionId}.exit`),
1388
+ fs4.writeFileSync(
1389
+ path4.join(sessionsDir, `${sessionId}.exit`),
1077
1390
  String(code ?? 0)
1078
1391
  );
1079
1392
  } catch {
@@ -1090,14 +1403,14 @@ async function launchClaude(options) {
1090
1403
 
1091
1404
  // src/permissions.ts
1092
1405
  var readSettings = (settingsPath) => {
1093
- if (fs4.existsSync(settingsPath)) {
1406
+ if (fs5.existsSync(settingsPath)) {
1094
1407
  try {
1095
- const content = fs4.readFileSync(settingsPath, "utf-8");
1408
+ const content = fs5.readFileSync(settingsPath, "utf-8");
1096
1409
  return JSON.parse(content);
1097
1410
  } catch {
1098
1411
  console.warn(chalk3.yellow(`\u8B66\u544A: \u65E0\u6CD5\u89E3\u6790 ${settingsPath}\uFF0C\u5C06\u521B\u5EFA\u5907\u4EFD`));
1099
1412
  const backupPath = settingsPath + ".error." + Date.now();
1100
- fs4.copyFileSync(settingsPath, backupPath);
1413
+ fs5.copyFileSync(settingsPath, backupPath);
1101
1414
  console.log(chalk3.gray(`\u5907\u4EFD\u5DF2\u4FDD\u5B58\u5230: ${backupPath}`));
1102
1415
  return {};
1103
1416
  }
@@ -1106,7 +1419,7 @@ var readSettings = (settingsPath) => {
1106
1419
  };
1107
1420
  var writeSettings = (settingsPath, config3) => {
1108
1421
  ensureClaudeDir();
1109
- fs4.writeFileSync(settingsPath, JSON.stringify(config3, null, 2) + "\n");
1422
+ fs5.writeFileSync(settingsPath, JSON.stringify(config3, null, 2) + "\n");
1110
1423
  };
1111
1424
  var mergePermissions = (existing, preset) => {
1112
1425
  const existingAllow = existing.permissions?.allow || [];
@@ -1122,7 +1435,7 @@ var mergePermissions = (existing, preset) => {
1122
1435
  };
1123
1436
  };
1124
1437
  var applyPermissionMode = (modeName) => {
1125
- const preset = PERMISSION_PRESETS3[modeName];
1438
+ const preset = PERMISSION_PRESETS[modeName];
1126
1439
  if (!preset) {
1127
1440
  console.error(chalk3.red(`\u672A\u77E5\u7684\u6743\u9650\u6A21\u5F0F: ${modeName}`));
1128
1441
  console.log(chalk3.yellow("\u53EF\u7528\u6A21\u5F0F: " + getPermissionModeNames().join(", ")));
@@ -1138,14 +1451,14 @@ var applyPermissionMode = (modeName) => {
1138
1451
  };
1139
1452
  var resetPermissions = () => {
1140
1453
  const settingsPath = getSettingsPath(true);
1141
- if (!fs4.existsSync(settingsPath)) {
1454
+ if (!fs5.existsSync(settingsPath)) {
1142
1455
  console.log(chalk3.yellow("\u6CA1\u6709\u81EA\u5B9A\u4E49\u6743\u9650\u914D\u7F6E\u9700\u8981\u91CD\u7F6E"));
1143
1456
  return;
1144
1457
  }
1145
1458
  const config3 = readSettings(settingsPath);
1146
1459
  delete config3.permissions;
1147
1460
  if (Object.keys(config3).length === 0) {
1148
- fs4.unlinkSync(settingsPath);
1461
+ fs5.unlinkSync(settingsPath);
1149
1462
  console.log(chalk3.green("\u5DF2\u5220\u9664\u914D\u7F6E\u6587\u4EF6\uFF08\u6587\u4EF6\u4E3A\u7A7A\uFF09"));
1150
1463
  } else {
1151
1464
  writeSettings(settingsPath, config3);
@@ -1155,7 +1468,7 @@ var resetPermissions = () => {
1155
1468
  };
1156
1469
  var showCurrentMode = () => {
1157
1470
  const settingsPath = getSettingsPath(true);
1158
- if (!fs4.existsSync(settingsPath)) {
1471
+ if (!fs5.existsSync(settingsPath)) {
1159
1472
  console.log(chalk3.yellow("\u672A\u914D\u7F6E\u81EA\u5B9A\u4E49\u6743\u9650"));
1160
1473
  console.log(chalk3.gray(`\u6587\u4EF6\u4E0D\u5B58\u5728: ${settingsPath}`));
1161
1474
  return;
@@ -1165,7 +1478,7 @@ var showCurrentMode = () => {
1165
1478
  console.log(chalk3.yellow("\u672A\u914D\u7F6E\u81EA\u5B9A\u4E49\u6743\u9650"));
1166
1479
  return;
1167
1480
  }
1168
- const matchedPreset = Object.entries(PERMISSION_PRESETS3).find(([_, preset]) => {
1481
+ const matchedPreset = Object.entries(PERMISSION_PRESETS).find(([_, preset]) => {
1169
1482
  const configAllow = new Set(config3.permissions?.allow || []);
1170
1483
  const configDeny = new Set(config3.permissions?.deny || []);
1171
1484
  const presetAllow = new Set(preset.permissions.allow);
@@ -1197,7 +1510,7 @@ var listAvailableModes = () => {
1197
1510
  style: { head: ["cyan"] },
1198
1511
  colWidths: [15, 15, 50]
1199
1512
  });
1200
- Object.entries(PERMISSION_PRESETS3).forEach(([key, preset]) => {
1513
+ Object.entries(PERMISSION_PRESETS).forEach(([key, preset]) => {
1201
1514
  table.push([preset.name, `--${key}`, preset.description]);
1202
1515
  });
1203
1516
  console.log(chalk3.bold("\u53EF\u7528\u6743\u9650\u6A21\u5F0F:\n"));
@@ -1206,7 +1519,7 @@ var listAvailableModes = () => {
1206
1519
  console.log(chalk3.gray("\u6C38\u4E45\u6A21\u5F0F: ccem setup perms --<mode>"));
1207
1520
  };
1208
1521
  var runWithTempPermissions = async (modeName, envConfig) => {
1209
- const preset = PERMISSION_PRESETS3[modeName];
1522
+ const preset = PERMISSION_PRESETS[modeName];
1210
1523
  if (!preset) {
1211
1524
  console.error(chalk3.red(`\u672A\u77E5\u7684\u6743\u9650\u6A21\u5F0F: ${modeName}`));
1212
1525
  console.log(chalk3.yellow("\u53EF\u7528\u6A21\u5F0F: " + getPermissionModeNames().join(", ")));
@@ -1216,13 +1529,13 @@ var runWithTempPermissions = async (modeName, envConfig) => {
1216
1529
  };
1217
1530
 
1218
1531
  // src/setup.ts
1219
- import fs5 from "fs";
1532
+ import fs6 from "fs";
1220
1533
  import chalk4 from "chalk";
1221
1534
  import { spawn as spawn2 } from "child_process";
1222
1535
  var readJsonFile = (filePath) => {
1223
- if (fs5.existsSync(filePath)) {
1536
+ if (fs6.existsSync(filePath)) {
1224
1537
  try {
1225
- const content = fs5.readFileSync(filePath, "utf-8");
1538
+ const content = fs6.readFileSync(filePath, "utf-8");
1226
1539
  return JSON.parse(content);
1227
1540
  } catch {
1228
1541
  console.warn(chalk4.yellow(`\u8B66\u544A: \u65E0\u6CD5\u89E3\u6790 ${filePath}`));
@@ -1232,7 +1545,7 @@ var readJsonFile = (filePath) => {
1232
1545
  return {};
1233
1546
  };
1234
1547
  var writeJsonFile = (filePath, data) => {
1235
- fs5.writeFileSync(filePath, JSON.stringify(data, null, 2) + "\n");
1548
+ fs6.writeFileSync(filePath, JSON.stringify(data, null, 2) + "\n");
1236
1549
  };
1237
1550
  var setupOnboarding = () => {
1238
1551
  const configPath = getGlobalClaudeConfigPath();
@@ -1354,8 +1667,8 @@ var runSetupInit = async () => {
1354
1667
 
1355
1668
  // src/skills.ts
1356
1669
  import { execSync } from "child_process";
1357
- import * as fs6 from "fs";
1358
- import * as path4 from "path";
1670
+ import * as fs7 from "fs";
1671
+ import * as path5 from "path";
1359
1672
  import chalk5 from "chalk";
1360
1673
  var SKILL_GROUPS = {
1361
1674
  official: { label: "\u5B98\u65B9", icon: "\u{1F3E2}" },
@@ -1524,12 +1837,12 @@ function parseGitHubUrl(url) {
1524
1837
  };
1525
1838
  }
1526
1839
  function getSkillsDir() {
1527
- return path4.join(process.cwd(), ".claude", "skills");
1840
+ return path5.join(process.cwd(), ".claude", "skills");
1528
1841
  }
1529
1842
  function ensureSkillsDir() {
1530
1843
  const skillsDir = getSkillsDir();
1531
- if (!fs6.existsSync(skillsDir)) {
1532
- fs6.mkdirSync(skillsDir, { recursive: true });
1844
+ if (!fs7.existsSync(skillsDir)) {
1845
+ fs7.mkdirSync(skillsDir, { recursive: true });
1533
1846
  } else {
1534
1847
  cleanupTempDirs(skillsDir);
1535
1848
  }
@@ -1537,11 +1850,11 @@ function ensureSkillsDir() {
1537
1850
  }
1538
1851
  function cleanupTempDirs(skillsDir) {
1539
1852
  try {
1540
- const entries = fs6.readdirSync(skillsDir, { withFileTypes: true });
1853
+ const entries = fs7.readdirSync(skillsDir, { withFileTypes: true });
1541
1854
  for (const entry of entries) {
1542
1855
  if (entry.isDirectory() && entry.name.startsWith(".tmp-")) {
1543
- const tmpPath = path4.join(skillsDir, entry.name);
1544
- fs6.rmSync(tmpPath, { recursive: true });
1856
+ const tmpPath = path5.join(skillsDir, entry.name);
1857
+ fs7.rmSync(tmpPath, { recursive: true });
1545
1858
  }
1546
1859
  }
1547
1860
  } catch {
@@ -1549,24 +1862,24 @@ function cleanupTempDirs(skillsDir) {
1549
1862
  }
1550
1863
  function downloadSkillWithGit(owner, repo, branch, repoPath, targetName) {
1551
1864
  const skillsDir = ensureSkillsDir();
1552
- const targetDir = path4.join(skillsDir, targetName);
1553
- if (fs6.existsSync(targetDir)) {
1865
+ const targetDir = path5.join(skillsDir, targetName);
1866
+ if (fs7.existsSync(targetDir)) {
1554
1867
  console.log(chalk5.yellow(`Skill "${targetName}" already exists. Updating...`));
1555
- fs6.rmSync(targetDir, { recursive: true });
1868
+ fs7.rmSync(targetDir, { recursive: true });
1556
1869
  }
1557
1870
  const repoUrl = `https://github.com/${owner}/${repo}.git`;
1558
- const tempDir = path4.join(skillsDir, `.tmp-${Date.now()}`);
1871
+ const tempDir = path5.join(skillsDir, `.tmp-${Date.now()}`);
1559
1872
  try {
1560
- fs6.mkdirSync(tempDir, { recursive: true });
1873
+ fs7.mkdirSync(tempDir, { recursive: true });
1561
1874
  execSync(`git init`, { cwd: tempDir, stdio: "pipe" });
1562
1875
  execSync(`git remote add origin ${repoUrl}`, { cwd: tempDir, stdio: "pipe" });
1563
1876
  execSync(`git config core.sparseCheckout true`, { cwd: tempDir, stdio: "pipe" });
1564
- const sparseFile = path4.join(tempDir, ".git", "info", "sparse-checkout");
1565
- fs6.writeFileSync(sparseFile, repoPath ? `${repoPath}/
1877
+ const sparseFile = path5.join(tempDir, ".git", "info", "sparse-checkout");
1878
+ fs7.writeFileSync(sparseFile, repoPath ? `${repoPath}/
1566
1879
  ` : "*\n");
1567
1880
  execSync(`git pull --depth=1 origin ${branch}`, { cwd: tempDir, stdio: "pipe" });
1568
- const sourceDir = repoPath ? path4.join(tempDir, repoPath) : tempDir;
1569
- if (!fs6.existsSync(sourceDir)) {
1881
+ const sourceDir = repoPath ? path5.join(tempDir, repoPath) : tempDir;
1882
+ if (!fs7.existsSync(sourceDir)) {
1570
1883
  throw new Error(`Path "${repoPath}" not found in repository`);
1571
1884
  }
1572
1885
  copyDir(sourceDir, targetDir);
@@ -1577,22 +1890,22 @@ function downloadSkillWithGit(owner, repo, branch, repoPath, targetName) {
1577
1890
  console.error(chalk5.red(`Failed to download skill: ${errMsg}`));
1578
1891
  return false;
1579
1892
  } finally {
1580
- if (fs6.existsSync(tempDir)) {
1581
- fs6.rmSync(tempDir, { recursive: true });
1893
+ if (fs7.existsSync(tempDir)) {
1894
+ fs7.rmSync(tempDir, { recursive: true });
1582
1895
  }
1583
1896
  }
1584
1897
  }
1585
1898
  function copyDir(src, dest) {
1586
- fs6.mkdirSync(dest, { recursive: true });
1587
- const entries = fs6.readdirSync(src, { withFileTypes: true });
1899
+ fs7.mkdirSync(dest, { recursive: true });
1900
+ const entries = fs7.readdirSync(src, { withFileTypes: true });
1588
1901
  for (const entry of entries) {
1589
1902
  if (entry.name === ".git") continue;
1590
- const srcPath = path4.join(src, entry.name);
1591
- const destPath = path4.join(dest, entry.name);
1903
+ const srcPath = path5.join(src, entry.name);
1904
+ const destPath = path5.join(dest, entry.name);
1592
1905
  if (entry.isDirectory()) {
1593
1906
  copyDir(srcPath, destPath);
1594
1907
  } else {
1595
- fs6.copyFileSync(srcPath, destPath);
1908
+ fs7.copyFileSync(srcPath, destPath);
1596
1909
  }
1597
1910
  }
1598
1911
  }
@@ -1638,7 +1951,7 @@ function addSkillFromGitHub(urlOrPreset) {
1638
1951
  }
1639
1952
  let skillName;
1640
1953
  if (parsed.path) {
1641
- skillName = path4.basename(parsed.path);
1954
+ skillName = path5.basename(parsed.path);
1642
1955
  } else {
1643
1956
  skillName = parsed.repo;
1644
1957
  }
@@ -1652,23 +1965,23 @@ function addSkillFromGitHub(urlOrPreset) {
1652
1965
  }
1653
1966
  function listInstalledSkills() {
1654
1967
  const skillsDir = getSkillsDir();
1655
- if (!fs6.existsSync(skillsDir)) {
1968
+ if (!fs7.existsSync(skillsDir)) {
1656
1969
  return [];
1657
1970
  }
1658
- const entries = fs6.readdirSync(skillsDir, { withFileTypes: true });
1971
+ const entries = fs7.readdirSync(skillsDir, { withFileTypes: true });
1659
1972
  return entries.filter((entry) => entry.isDirectory() && !entry.name.startsWith(".")).map((entry) => ({
1660
1973
  name: entry.name,
1661
- path: path4.join(skillsDir, entry.name)
1974
+ path: path5.join(skillsDir, entry.name)
1662
1975
  }));
1663
1976
  }
1664
1977
  function removeSkill(name) {
1665
1978
  const skillsDir = getSkillsDir();
1666
- const targetDir = path4.join(skillsDir, name);
1667
- if (!fs6.existsSync(targetDir)) {
1979
+ const targetDir = path5.join(skillsDir, name);
1980
+ if (!fs7.existsSync(targetDir)) {
1668
1981
  console.error(chalk5.red(`Skill "${name}" not found`));
1669
1982
  return false;
1670
1983
  }
1671
- fs6.rmSync(targetDir, { recursive: true });
1984
+ fs7.rmSync(targetDir, { recursive: true });
1672
1985
  console.log(chalk5.green(`Removed skill "${name}"`));
1673
1986
  return true;
1674
1987
  }
@@ -1826,19 +2139,18 @@ async function runSkillSelector() {
1826
2139
  }
1827
2140
 
1828
2141
  // src/remote.ts
1829
- import crypto2 from "crypto";
2142
+ import crypto3 from "crypto";
1830
2143
  import chalk6 from "chalk";
1831
2144
  import Conf from "conf";
1832
- import { encrypt } from "@ccem/core";
1833
2145
  var config = new Conf({
1834
2146
  projectName: "claude-code-env-manager"
1835
2147
  });
1836
2148
  var decryptWithSecret = (encryptedBase64, secret) => {
1837
- const key = crypto2.scryptSync(secret, "ccem-salt", 32);
2149
+ const key = crypto3.scryptSync(secret, "ccem-salt", 32);
1838
2150
  const combined = Buffer.from(encryptedBase64, "base64");
1839
2151
  const iv = combined.subarray(0, 16);
1840
2152
  const encryptedHex = combined.subarray(16).toString("hex");
1841
- const decipher = crypto2.createDecipheriv("aes-256-cbc", key, iv);
2153
+ const decipher = crypto3.createDecipheriv("aes-256-cbc", key, iv);
1842
2154
  let decrypted = decipher.update(encryptedHex, "hex", "utf8");
1843
2155
  decrypted += decipher.final("utf8");
1844
2156
  return decrypted;
@@ -2075,11 +2387,11 @@ Replace \\\`TARGET_ID\\\` or \\\`TARGET_NAME\\\` with the user's selection.
2075
2387
 
2076
2388
  // src/index.ts
2077
2389
  var __filename = fileURLToPath(import.meta.url);
2078
- var __dirname2 = path5.dirname(__filename);
2079
- var pkgPath = path5.resolve(__dirname2, "..", "package.json");
2080
- var pkg = JSON.parse(fs7.readFileSync(pkgPath, "utf-8"));
2390
+ var __dirname2 = path6.dirname(__filename);
2391
+ var pkgPath = path6.resolve(__dirname2, "..", "package.json");
2392
+ var pkg = JSON.parse(fs8.readFileSync(pkgPath, "utf-8"));
2081
2393
  var program = new Command();
2082
- ensureCcemDir3();
2394
+ ensureCcemDir();
2083
2395
  var config2 = new Conf2({
2084
2396
  projectName: "claude-code-env-manager",
2085
2397
  cwd: getCcemConfigDir(),
@@ -2132,7 +2444,7 @@ var initUsageStats = (onUpdate) => {
2132
2444
  };
2133
2445
  program.name("ccem").description("Claude Code Environment Manager - \u7BA1\u7406 Claude Code \u73AF\u5883\u53D8\u91CF\u548C\u6743\u9650").version(pkg.version).option("--mode", "\u67E5\u770B\u5F53\u524D\u6743\u9650\u6A21\u5F0F").option("--list-modes", "\u5217\u51FA\u6240\u6709\u53EF\u7528\u6743\u9650\u6A21\u5F0F");
2134
2446
  PERMISSION_MODES.forEach((mode) => {
2135
- const preset = PERMISSION_PRESETS4[mode];
2447
+ const preset = PERMISSION_PRESETS[mode];
2136
2448
  program.command(mode).description(`\u4E34\u65F6\u5E94\u7528 ${preset.name}\uFF0C\u9000\u51FA\u540E\u8FD8\u539F`).action(async () => {
2137
2449
  const registries = config2.get("registries");
2138
2450
  const current = config2.get("current");
@@ -2149,7 +2461,7 @@ var showCurrentEnv = (usageStats2, usageLoading2) => {
2149
2461
  if (!env) return;
2150
2462
  console.log(renderLogoWithEnvPanel(current, {
2151
2463
  ANTHROPIC_BASE_URL: env.ANTHROPIC_BASE_URL,
2152
- ANTHROPIC_API_KEY: env.ANTHROPIC_API_KEY ? decrypt2(env.ANTHROPIC_API_KEY) : void 0,
2464
+ ANTHROPIC_API_KEY: env.ANTHROPIC_API_KEY ? decrypt(env.ANTHROPIC_API_KEY) : void 0,
2153
2465
  ANTHROPIC_MODEL: env.ANTHROPIC_MODEL,
2154
2466
  ANTHROPIC_SMALL_FAST_MODEL: env.ANTHROPIC_SMALL_FAST_MODEL
2155
2467
  }, defaultMode));
@@ -2174,7 +2486,7 @@ var switchEnvironment = async (name) => {
2174
2486
  const env = registries[name];
2175
2487
  const exportCmds = [];
2176
2488
  if (env.ANTHROPIC_BASE_URL) exportCmds.push(`export ANTHROPIC_BASE_URL="${env.ANTHROPIC_BASE_URL}"`);
2177
- if (env.ANTHROPIC_API_KEY) exportCmds.push(`export ANTHROPIC_API_KEY="${decrypt2(env.ANTHROPIC_API_KEY)}"`);
2489
+ if (env.ANTHROPIC_API_KEY) exportCmds.push(`export ANTHROPIC_API_KEY="${decrypt(env.ANTHROPIC_API_KEY)}"`);
2178
2490
  if (env.ANTHROPIC_MODEL) exportCmds.push(`export ANTHROPIC_MODEL="${env.ANTHROPIC_MODEL}"`);
2179
2491
  if (env.ANTHROPIC_SMALL_FAST_MODEL) exportCmds.push(`export ANTHROPIC_SMALL_FAST_MODEL="${env.ANTHROPIC_SMALL_FAST_MODEL}"`);
2180
2492
  if (process.stdout.isTTY) {
@@ -2259,7 +2571,7 @@ program.command("add <name>").description("Add a new environment configuration")
2259
2571
  }
2260
2572
  ]);
2261
2573
  if (answers.ANTHROPIC_API_KEY) {
2262
- answers.ANTHROPIC_API_KEY = encrypt2(answers.ANTHROPIC_API_KEY);
2574
+ answers.ANTHROPIC_API_KEY = encrypt(answers.ANTHROPIC_API_KEY);
2263
2575
  }
2264
2576
  registries[name] = answers;
2265
2577
  config2.set("registries", registries);
@@ -2356,7 +2668,7 @@ program.command("cp <source> <target>").description("Copy an environment configu
2356
2668
  }
2357
2669
  ]);
2358
2670
  if (answers.ANTHROPIC_BASE_URL) current.ANTHROPIC_BASE_URL = answers.ANTHROPIC_BASE_URL;
2359
- if (answers.ANTHROPIC_API_KEY) current.ANTHROPIC_API_KEY = encrypt2(answers.ANTHROPIC_API_KEY);
2671
+ if (answers.ANTHROPIC_API_KEY) current.ANTHROPIC_API_KEY = encrypt(answers.ANTHROPIC_API_KEY);
2360
2672
  if (answers.ANTHROPIC_MODEL) current.ANTHROPIC_MODEL = answers.ANTHROPIC_MODEL;
2361
2673
  if (answers.ANTHROPIC_SMALL_FAST_MODEL) current.ANTHROPIC_SMALL_FAST_MODEL = answers.ANTHROPIC_SMALL_FAST_MODEL;
2362
2674
  registries[target] = current;
@@ -2375,7 +2687,7 @@ program.command("env").description("Output environment variables for shell eval"
2375
2687
  if (!env) return;
2376
2688
  const outputEnv = { ...env };
2377
2689
  if (outputEnv.ANTHROPIC_API_KEY) {
2378
- outputEnv.ANTHROPIC_API_KEY = decrypt2(outputEnv.ANTHROPIC_API_KEY);
2690
+ outputEnv.ANTHROPIC_API_KEY = decrypt(outputEnv.ANTHROPIC_API_KEY);
2379
2691
  }
2380
2692
  if (options.json) {
2381
2693
  console.log(JSON.stringify(outputEnv, null, 2));
@@ -2396,7 +2708,7 @@ program.command("run <command...>").description("Run a command with the current
2396
2708
  }
2397
2709
  const env = { ...process.env };
2398
2710
  if (envConfig.ANTHROPIC_BASE_URL) env.ANTHROPIC_BASE_URL = envConfig.ANTHROPIC_BASE_URL;
2399
- if (envConfig.ANTHROPIC_API_KEY) env.ANTHROPIC_API_KEY = decrypt2(envConfig.ANTHROPIC_API_KEY || "");
2711
+ if (envConfig.ANTHROPIC_API_KEY) env.ANTHROPIC_API_KEY = decrypt(envConfig.ANTHROPIC_API_KEY || "");
2400
2712
  if (envConfig.ANTHROPIC_MODEL) env.ANTHROPIC_MODEL = envConfig.ANTHROPIC_MODEL;
2401
2713
  if (envConfig.ANTHROPIC_SMALL_FAST_MODEL) env.ANTHROPIC_SMALL_FAST_MODEL = envConfig.ANTHROPIC_SMALL_FAST_MODEL;
2402
2714
  const [cmd, ...args] = command;
@@ -2436,14 +2748,14 @@ setupCmd.command("default-mode").description("\u8BBE\u7F6E\u9ED8\u8BA4\u6743\u96
2436
2748
  for (const mode of PERMISSION_MODES) {
2437
2749
  if (options[mode]) {
2438
2750
  config2.set("defaultMode", mode);
2439
- console.log(chalk7.green(`\u5DF2\u8BBE\u7F6E\u9ED8\u8BA4\u6743\u9650\u6A21\u5F0F: ${PERMISSION_PRESETS4[mode].name}`));
2751
+ console.log(chalk7.green(`\u5DF2\u8BBE\u7F6E\u9ED8\u8BA4\u6743\u9650\u6A21\u5F0F: ${PERMISSION_PRESETS[mode].name}`));
2440
2752
  console.log(chalk7.gray(`\u4E0B\u6B21\u542F\u52A8 ccem \u65F6\u5C06\u9ED8\u8BA4\u4F7F\u7528\u6B64\u6A21\u5F0F`));
2441
2753
  return;
2442
2754
  }
2443
2755
  }
2444
2756
  const currentDefault = config2.get("defaultMode");
2445
- if (currentDefault && PERMISSION_PRESETS4[currentDefault]) {
2446
- console.log(chalk7.green(`\u5F53\u524D\u9ED8\u8BA4\u6A21\u5F0F: ${PERMISSION_PRESETS4[currentDefault].name}`));
2757
+ if (currentDefault && PERMISSION_PRESETS[currentDefault]) {
2758
+ console.log(chalk7.green(`\u5F53\u524D\u9ED8\u8BA4\u6A21\u5F0F: ${PERMISSION_PRESETS[currentDefault].name}`));
2447
2759
  } else {
2448
2760
  console.log(chalk7.yellow("\u672A\u8BBE\u7F6E\u9ED8\u8BA4\u6743\u9650\u6A21\u5F0F"));
2449
2761
  }
@@ -2459,28 +2771,28 @@ setupCmd.command("migrate").description("\u8FC1\u79FB\u65E7\u7248\u914D\u7F6E\u5
2459
2771
  const newConfigPath = getCcemConfigPath();
2460
2772
  const legacyConfigPath = getLegacyConfigPath();
2461
2773
  console.log(chalk7.cyan("\n\u{1F504} \u914D\u7F6E\u8FC1\u79FB\n"));
2462
- if (!fs7.existsSync(legacyConfigPath)) {
2774
+ if (!fs8.existsSync(legacyConfigPath)) {
2463
2775
  console.log(chalk7.yellow("\u672A\u627E\u5230\u65E7\u7248\u914D\u7F6E\u6587\u4EF6"));
2464
2776
  console.log(chalk7.gray(` \u65E7\u8DEF\u5F84: ${legacyConfigPath}`));
2465
2777
  return;
2466
2778
  }
2467
- if (fs7.existsSync(newConfigPath) && !options.force) {
2779
+ if (fs8.existsSync(newConfigPath) && !options.force) {
2468
2780
  console.log(chalk7.green("\u2713 \u914D\u7F6E\u5DF2\u5728\u65B0\u8DEF\u5F84"));
2469
2781
  console.log(chalk7.gray(` \u8DEF\u5F84: ${newConfigPath}`));
2470
2782
  console.log(chalk7.gray("\n\u4F7F\u7528 --force \u5F3A\u5236\u91CD\u65B0\u8FC1\u79FB"));
2471
2783
  return;
2472
2784
  }
2473
2785
  try {
2474
- ensureCcemDir3();
2475
- fs7.copyFileSync(legacyConfigPath, newConfigPath);
2786
+ ensureCcemDir();
2787
+ fs8.copyFileSync(legacyConfigPath, newConfigPath);
2476
2788
  console.log(chalk7.green("\u2713 \u914D\u7F6E\u5DF2\u8FC1\u79FB"));
2477
2789
  console.log(chalk7.gray(` \u4ECE: ${legacyConfigPath}`));
2478
2790
  console.log(chalk7.gray(` \u5230: ${newConfigPath}`));
2479
2791
  if (options.clean) {
2480
- fs7.unlinkSync(legacyConfigPath);
2481
- const legacyDir = path5.dirname(legacyConfigPath);
2792
+ fs8.unlinkSync(legacyConfigPath);
2793
+ const legacyDir = path6.dirname(legacyConfigPath);
2482
2794
  try {
2483
- fs7.rmdirSync(legacyDir);
2795
+ fs8.rmdirSync(legacyDir);
2484
2796
  } catch {
2485
2797
  }
2486
2798
  console.log(chalk7.green("\u2713 \u5DF2\u5220\u9664\u65E7\u914D\u7F6E\u6587\u4EF6"));
@@ -2491,13 +2803,13 @@ setupCmd.command("migrate").description("\u8FC1\u79FB\u65E7\u7248\u914D\u7F6E\u5
2491
2803
  });
2492
2804
  setupCmd.command("cron").description("\u5B89\u88C5 ccem-cron skill \u5230 Claude Code\uFF08~/.claude/skills/\uFF09").option("--force", "\u5F3A\u5236\u8986\u76D6\u5DF2\u6709\u6587\u4EF6").action(async function() {
2493
2805
  const options = this.opts();
2494
- const skillDir = path5.join(process.env.HOME || "~", ".claude", "skills");
2495
- const targetPath = path5.join(skillDir, "ccem-cron.md");
2496
- if (!fs7.existsSync(skillDir)) {
2497
- fs7.mkdirSync(skillDir, { recursive: true });
2806
+ const skillDir = path6.join(process.env.HOME || "~", ".claude", "skills");
2807
+ const targetPath = path6.join(skillDir, "ccem-cron.md");
2808
+ if (!fs8.existsSync(skillDir)) {
2809
+ fs8.mkdirSync(skillDir, { recursive: true });
2498
2810
  console.log(chalk7.gray(`\u521B\u5EFA\u76EE\u5F55: ${skillDir}`));
2499
2811
  }
2500
- if (fs7.existsSync(targetPath) && !options.force) {
2812
+ if (fs8.existsSync(targetPath) && !options.force) {
2501
2813
  const { overwrite } = await inquirer.prompt([
2502
2814
  {
2503
2815
  type: "confirm",
@@ -2511,7 +2823,7 @@ setupCmd.command("cron").description("\u5B89\u88C5 ccem-cron skill \u5230 Claude
2511
2823
  return;
2512
2824
  }
2513
2825
  }
2514
- fs7.writeFileSync(targetPath, CCEM_CRON_SKILL_CONTENT, "utf-8");
2826
+ fs8.writeFileSync(targetPath, CCEM_CRON_SKILL_CONTENT, "utf-8");
2515
2827
  console.log(chalk7.green(`\u2713 \u5DF2\u5B89\u88C5 ccem-cron skill`));
2516
2828
  console.log(chalk7.gray(` \u8DEF\u5F84: ${targetPath}`));
2517
2829
  console.log(chalk7.cyan(`
@@ -2689,7 +3001,7 @@ Editing environment '${result.name}'`));
2689
3001
  }
2690
3002
  ]);
2691
3003
  if (answers.ANTHROPIC_BASE_URL) envToEdit.ANTHROPIC_BASE_URL = answers.ANTHROPIC_BASE_URL;
2692
- if (answers.ANTHROPIC_API_KEY) envToEdit.ANTHROPIC_API_KEY = encrypt2(answers.ANTHROPIC_API_KEY);
3004
+ if (answers.ANTHROPIC_API_KEY) envToEdit.ANTHROPIC_API_KEY = encrypt(answers.ANTHROPIC_API_KEY);
2693
3005
  if (answers.ANTHROPIC_MODEL) envToEdit.ANTHROPIC_MODEL = answers.ANTHROPIC_MODEL;
2694
3006
  if (answers.ANTHROPIC_SMALL_FAST_MODEL) envToEdit.ANTHROPIC_SMALL_FAST_MODEL = answers.ANTHROPIC_SMALL_FAST_MODEL;
2695
3007
  registries[result.name] = envToEdit;
@@ -2774,7 +3086,7 @@ Editing environment '${result.name}'`));
2774
3086
  }
2775
3087
  ]);
2776
3088
  if (editAnswers.ANTHROPIC_BASE_URL) envToEdit.ANTHROPIC_BASE_URL = editAnswers.ANTHROPIC_BASE_URL;
2777
- if (editAnswers.ANTHROPIC_API_KEY) envToEdit.ANTHROPIC_API_KEY = encrypt2(editAnswers.ANTHROPIC_API_KEY);
3089
+ if (editAnswers.ANTHROPIC_API_KEY) envToEdit.ANTHROPIC_API_KEY = encrypt(editAnswers.ANTHROPIC_API_KEY);
2778
3090
  if (editAnswers.ANTHROPIC_MODEL) envToEdit.ANTHROPIC_MODEL = editAnswers.ANTHROPIC_MODEL;
2779
3091
  if (editAnswers.ANTHROPIC_SMALL_FAST_MODEL) envToEdit.ANTHROPIC_SMALL_FAST_MODEL = editAnswers.ANTHROPIC_SMALL_FAST_MODEL;
2780
3092
  registries[targetName] = envToEdit;
@@ -2839,7 +3151,7 @@ Editing environment '${result.name}'`));
2839
3151
  await new Promise((resolve2) => setTimeout(resolve2, 800));
2840
3152
  } else if (selectedMode !== "back") {
2841
3153
  config2.set("defaultMode", selectedMode);
2842
- msg.success(`Default mode set: ${PERMISSION_PRESETS4[selectedMode].name}`);
3154
+ msg.success(`Default mode set: ${PERMISSION_PRESETS[selectedMode].name}`);
2843
3155
  await new Promise((resolve2) => setTimeout(resolve2, 800));
2844
3156
  }
2845
3157
  } else {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ccem",
3
- "version": "2.0.0-beta",
3
+ "version": "2.0.0-beta.2",
4
4
  "type": "module",
5
5
  "description": "Claude Code Environment Manager",
6
6
  "author": {
@@ -16,18 +16,7 @@
16
16
  "bin": {
17
17
  "ccem": "./dist/index.js"
18
18
  },
19
- "scripts": {
20
- "generate-logo": "bash scripts/generate-logo.sh",
21
- "build": "tsup",
22
- "dev": "tsup --watch",
23
- "start": "node dist/index.js",
24
- "postinstall": "node ./scripts/migrate.js",
25
- "test": "vitest",
26
- "test:run": "vitest run",
27
- "test:coverage": "vitest run --coverage"
28
- },
29
19
  "dependencies": {
30
- "@ccem/core": "workspace:*",
31
20
  "chalk": "^4.1.2",
32
21
  "cli-table3": "^0.6.3",
33
22
  "commander": "^12.0.0",
@@ -46,6 +35,17 @@
46
35
  "asciify-image": "^0.1.10",
47
36
  "tsup": "^8.0.2",
48
37
  "typescript": "^5.3.3",
49
- "vitest": "^4.0.18"
38
+ "vitest": "^4.0.18",
39
+ "@ccem/core": "2.0.0-beta.2"
40
+ },
41
+ "scripts": {
42
+ "generate-logo": "bash scripts/generate-logo.sh",
43
+ "build": "tsup",
44
+ "dev": "tsup --watch",
45
+ "start": "node dist/index.js",
46
+ "postinstall": "node ./scripts/migrate.js",
47
+ "test": "vitest",
48
+ "test:run": "vitest run",
49
+ "test:coverage": "vitest run --coverage"
50
50
  }
51
- }
51
+ }