@shi_zhen/code-helper 0.1.2 → 0.1.3

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.
@@ -33,7 +33,7 @@ var require_package = __commonJS({
33
33
  "package.json"(exports, module) {
34
34
  module.exports = {
35
35
  name: "@shi_zhen/code-helper",
36
- version: "0.1.2",
36
+ version: "0.1.3",
37
37
  description: "Code Helper - A unified tool to manage your Claude Code",
38
38
  repository: {
39
39
  type: "git",
@@ -193,10 +193,10 @@ async function getRemoteVersion() {
193
193
  }
194
194
  function readCache() {
195
195
  try {
196
- if (!fs9.existsSync(CACHE_FILE)) {
196
+ if (!fs10.existsSync(CACHE_FILE)) {
197
197
  return null;
198
198
  }
199
- const content = fs9.readFileSync(CACHE_FILE, "utf-8");
199
+ const content = fs10.readFileSync(CACHE_FILE, "utf-8");
200
200
  return JSON.parse(content);
201
201
  } catch {
202
202
  return null;
@@ -204,10 +204,10 @@ function readCache() {
204
204
  }
205
205
  function writeCache(data) {
206
206
  try {
207
- if (!fs9.existsSync(CACHE_DIR)) {
208
- fs9.mkdirSync(CACHE_DIR, { recursive: true });
207
+ if (!fs10.existsSync(CACHE_DIR)) {
208
+ fs10.mkdirSync(CACHE_DIR, { recursive: true });
209
209
  }
210
- fs9.writeFileSync(CACHE_FILE, JSON.stringify(data, null, 2));
210
+ fs10.writeFileSync(CACHE_FILE, JSON.stringify(data, null, 2));
211
211
  } catch (error) {
212
212
  }
213
213
  }
@@ -307,16 +307,16 @@ async function testUpdate() {
307
307
  chalk3.cyan("\n\u{1F4A1} \u63D0\u793A: \u53D1\u5E03\u65B0\u7248\u672C\u540E\uFF0C\u7528\u6237\u9996\u6B21\u542F\u52A8\u65F6\u4F1A\u81EA\u52A8\u66F4\u65B0\n")
308
308
  );
309
309
  }
310
- var os10, path10, fs9, CACHE_DIR, CACHE_FILE, CHECK_INTERVAL;
310
+ var os11, path11, fs10, CACHE_DIR, CACHE_FILE, CHECK_INTERVAL;
311
311
  var init_version = __esm({
312
312
  "src/cli/utils/version.ts"() {
313
313
  "use strict";
314
314
  init_exec();
315
- os10 = __require("os");
316
- path10 = __require("path");
317
- fs9 = __require("fs");
318
- CACHE_DIR = path10.join(os10.homedir(), ".code-helper");
319
- CACHE_FILE = path10.join(CACHE_DIR, "version-check.json");
315
+ os11 = __require("os");
316
+ path11 = __require("path");
317
+ fs10 = __require("fs");
318
+ CACHE_DIR = path11.join(os11.homedir(), ".code-helper");
319
+ CACHE_FILE = path11.join(CACHE_DIR, "version-check.json");
320
320
  CHECK_INTERVAL = 24 * 60 * 60 * 1e3;
321
321
  }
322
322
  });
@@ -1338,7 +1338,7 @@ var COMMON_PROXY_PORTS = [
1338
1338
  var INSTALL_METHODS = [
1339
1339
  {
1340
1340
  name: "\u5B98\u65B9\u811A\u672C\u5B89\u88C5",
1341
- command: "curl -fsSL https://claude.ai/install.sh | bash",
1341
+ command: 'temp=$(mktemp) && trap "rm -f $temp" EXIT && curl -fsSL https://claude.ai/install.sh -o "$temp" && bash "$temp"',
1342
1342
  description: "\u9700\u8981\u4EE3\u7406\u6216\u5916\u7F51\u8BBF\u95EE",
1343
1343
  platforms: ["darwin", "linux"],
1344
1344
  recommended: true
@@ -1582,7 +1582,7 @@ async function showInstallMenu() {
1582
1582
  let envVars = {};
1583
1583
  if (proxyUrl) {
1584
1584
  if (finalCommand.includes("curl")) {
1585
- finalCommand = finalCommand.replace("curl ", `curl --proxy ${proxyUrl} `);
1585
+ finalCommand = finalCommand.replace(/curl\s+/g, `curl --proxy ${proxyUrl} `);
1586
1586
  } else {
1587
1587
  envVars = {
1588
1588
  http_proxy: proxyUrl,
@@ -3252,11 +3252,248 @@ async function handleInstallAll(marketplacePlugins) {
3252
3252
  }
3253
3253
 
3254
3254
  // src/cli/menus/settings.ts
3255
- import fs8 from "fs";
3255
+ import fs9 from "fs";
3256
3256
  import inquirer7 from "inquirer";
3257
+ import os10 from "os";
3258
+ import path10 from "path";
3259
+
3260
+ // src/cli/utils/permissions.ts
3261
+ import fs8 from "fs";
3257
3262
  import os9 from "os";
3258
3263
  import path9 from "path";
3259
3264
  var SETTINGS_FILE2 = path9.join(os9.homedir(), ".claude", "settings.json");
3265
+ var PERMISSION_RULES = {
3266
+ // 中等权限配置
3267
+ moderate: {
3268
+ allow: [
3269
+ // 文件操作
3270
+ "ReadFile(*)",
3271
+ "WriteFile(*)",
3272
+ "EditFile(*)",
3273
+ "Glob(*)",
3274
+ "Grep(*)",
3275
+ // Git 常规操作
3276
+ "Bash(git:status*)",
3277
+ "Bash(git:add*)",
3278
+ "Bash(git:commit*)",
3279
+ "Bash(git:pull*)",
3280
+ "Bash(git:branch*)",
3281
+ "Bash(git:checkout*)",
3282
+ "Bash(git:diff*)",
3283
+ "Bash(git:log*)",
3284
+ "Bash(git:clone*)",
3285
+ "Bash(git:stash*)",
3286
+ "Bash(git:show*)",
3287
+ "Bash(git:fetch*)",
3288
+ // Node/NPM
3289
+ "Bash(node:*)",
3290
+ "Bash(npm:run*)",
3291
+ "Bash(npm:test*)",
3292
+ "Bash(npm:install*)",
3293
+ "Bash(npx:*)",
3294
+ // Python
3295
+ "Bash(python:*)",
3296
+ "Bash(python3:*)",
3297
+ "Bash(pip:install*)",
3298
+ "Bash(pip3:install*)",
3299
+ // 常用工具
3300
+ "Bash(cat:*)",
3301
+ "Bash(ls:*)",
3302
+ "Bash(grep:*)",
3303
+ "Bash(find:*)",
3304
+ "Bash(curl:*)",
3305
+ "Bash(wget:*)",
3306
+ "Bash(echo:*)",
3307
+ "Bash(mkdir:*)",
3308
+ "Bash(cp:*)",
3309
+ "Bash(mv:*)",
3310
+ "Bash(touch:*)",
3311
+ "Bash(pwd:*)",
3312
+ "Bash(cd:*)"
3313
+ ],
3314
+ deny: [
3315
+ // 高危操作
3316
+ "Bash(rm:-rf*)",
3317
+ "Bash(rm:*-rf*)",
3318
+ "Bash(rm:*-r*-f*)",
3319
+ "Bash(sudo:*)",
3320
+ "Bash(git:push*--force*)",
3321
+ "Bash(git:push*-f*)",
3322
+ "Bash(chmod:*)",
3323
+ "Bash(chown:*)",
3324
+ // 反黑客操作
3325
+ "Bash(nc:*-e*)",
3326
+ // 反向 shell
3327
+ "Bash(bash:*-i*)",
3328
+ // 交互式 bash
3329
+ "Bash(*>&*)",
3330
+ // 重定向到网络
3331
+ "Bash(*base64*-d*)",
3332
+ // 可疑的 base64 解码
3333
+ "Bash(wget:*&&*)",
3334
+ // 下载并执行
3335
+ "Bash(curl:*|*sh*)",
3336
+ // 管道执行
3337
+ "Bash(curl:*|*bash*)"
3338
+ ]
3339
+ },
3340
+ // 最大权限配置
3341
+ maximum: {
3342
+ allow: [
3343
+ // 继承中等权限的所有规则
3344
+ "ReadFile(*)",
3345
+ "WriteFile(*)",
3346
+ "EditFile(*)",
3347
+ "Glob(*)",
3348
+ "Grep(*)",
3349
+ // Git 所有操作(除了强制推送)
3350
+ "Bash(git:*)",
3351
+ // Node/NPM
3352
+ "Bash(node:*)",
3353
+ "Bash(npm:*)",
3354
+ "Bash(npx:*)",
3355
+ // Python
3356
+ "Bash(python:*)",
3357
+ "Bash(python3:*)",
3358
+ "Bash(pip:*)",
3359
+ "Bash(pip3:*)",
3360
+ // 常用工具
3361
+ "Bash(cat:*)",
3362
+ "Bash(ls:*)",
3363
+ "Bash(grep:*)",
3364
+ "Bash(find:*)",
3365
+ "Bash(curl:*)",
3366
+ "Bash(wget:*)",
3367
+ "Bash(echo:*)",
3368
+ "Bash(mkdir:*)",
3369
+ "Bash(cp:*)",
3370
+ "Bash(mv:*)",
3371
+ "Bash(touch:*)",
3372
+ "Bash(pwd:*)",
3373
+ "Bash(cd:*)",
3374
+ // 额外允许的操作
3375
+ "Bash(rm:*)"
3376
+ // 允许删除,但不包括 rm -rf
3377
+ ],
3378
+ deny: [
3379
+ // 高危操作(需要确认)
3380
+ "Bash(rm:-rf*)",
3381
+ "Bash(rm:*-rf*)",
3382
+ "Bash(rm:*-r*-f*)",
3383
+ "Bash(sudo:*)",
3384
+ "Bash(git:push*--force*)",
3385
+ "Bash(git:push*-f*)",
3386
+ "Bash(dd:*)",
3387
+ "Bash(mkfs:*)",
3388
+ // 反黑客操作
3389
+ "Bash(nc:*-e*)",
3390
+ // 反向 shell
3391
+ "Bash(bash:*-i*)",
3392
+ // 交互式 bash
3393
+ "Bash(*>&*)",
3394
+ // 重定向到网络
3395
+ "Bash(*base64*-d*)",
3396
+ // 可疑的 base64 解码
3397
+ "Bash(wget:*&&*)",
3398
+ // 下载并执行
3399
+ "Bash(curl:*|*sh*)",
3400
+ // 管道执行
3401
+ "Bash(curl:*|*bash*)"
3402
+ ]
3403
+ }
3404
+ };
3405
+ var PERMISSION_DESCRIPTIONS = {
3406
+ ["default" /* DEFAULT */]: {
3407
+ name: "\u9ED8\u8BA4",
3408
+ description: "\u6BCF\u6B21\u5371\u9669\u64CD\u4F5C\u90FD\u9700\u8981\u786E\u8BA4\uFF08Claude Code \u539F\u59CB\u884C\u4E3A\uFF09",
3409
+ autoAllow: [],
3410
+ needConfirm: ["\u6240\u6709\u53EF\u80FD\u5371\u9669\u7684\u64CD\u4F5C"]
3411
+ },
3412
+ ["moderate" /* MODERATE */]: {
3413
+ name: "\u4E2D\u7B49\u6743\u9650",
3414
+ description: "\u81EA\u52A8\u5141\u8BB8\u5E38\u89C4\u64CD\u4F5C\uFF0C\u53EA\u786E\u8BA4\u5220\u9664\u548C\u5371\u9669\u547D\u4EE4",
3415
+ autoAllow: [
3416
+ "\u6587\u4EF6\u64CD\u4F5C\uFF08\u8BFB/\u5199/\u7F16\u8F91\uFF09",
3417
+ "Git \u5E38\u89C4\u64CD\u4F5C\uFF08status/add/commit/pull\u7B49\uFF09",
3418
+ "Node/NPM \u64CD\u4F5C",
3419
+ "Python/pip \u64CD\u4F5C",
3420
+ "\u5E38\u7528\u5DE5\u5177\uFF08cat/ls/grep/curl\u7B49\uFF09"
3421
+ ],
3422
+ needConfirm: [
3423
+ "rm -rf\uFF08\u5F3A\u5236\u9012\u5F52\u5220\u9664\uFF09",
3424
+ "sudo\uFF08\u7CFB\u7EDF\u6743\u9650\uFF09",
3425
+ "git push --force\uFF08\u5F3A\u5236\u63A8\u9001\uFF09",
3426
+ "chmod/chown\uFF08\u6743\u9650\u4FEE\u6539\uFF09"
3427
+ ]
3428
+ },
3429
+ ["maximum" /* MAXIMUM */]: {
3430
+ name: "\u6700\u5927\u6743\u9650",
3431
+ description: "\u81EA\u52A8\u5141\u8BB8\u51E0\u4E4E\u6240\u6709\u64CD\u4F5C\uFF0C\u53EA\u786E\u8BA4\u6781\u5EA6\u5371\u9669\u7684\u547D\u4EE4",
3432
+ autoAllow: [
3433
+ "\u6240\u6709\u4E2D\u7B49\u6743\u9650\u7684\u64CD\u4F5C",
3434
+ "git push\uFF08\u666E\u901A\u63A8\u9001\uFF09",
3435
+ "git rebase/merge",
3436
+ "\u6587\u4EF6\u5220\u9664\uFF08rm\uFF0C\u975E\u9012\u5F52\u5F3A\u5236\uFF09"
3437
+ ],
3438
+ needConfirm: [
3439
+ "rm -rf\uFF08\u5F3A\u5236\u9012\u5F52\u5220\u9664\uFF09",
3440
+ "sudo\uFF08\u7CFB\u7EDF\u6743\u9650\uFF09",
3441
+ "git push --force\uFF08\u5F3A\u5236\u63A8\u9001\uFF09",
3442
+ "dd/mkfs\uFF08\u78C1\u76D8\u64CD\u4F5C\uFF09",
3443
+ "curl | bash\uFF08\u7BA1\u9053\u6267\u884C\uFF09"
3444
+ ]
3445
+ }
3446
+ };
3447
+ function getCurrentPermissionLevel() {
3448
+ try {
3449
+ if (!fs8.existsSync(SETTINGS_FILE2)) {
3450
+ return "default" /* DEFAULT */;
3451
+ }
3452
+ const content = fs8.readFileSync(SETTINGS_FILE2, "utf-8");
3453
+ const settings = JSON.parse(content);
3454
+ if (!settings.permissions || !settings.permissionLevel) {
3455
+ return "default" /* DEFAULT */;
3456
+ }
3457
+ return settings.permissionLevel;
3458
+ } catch {
3459
+ return "default" /* DEFAULT */;
3460
+ }
3461
+ }
3462
+ function applyPermissionLevel(level) {
3463
+ let settings = {};
3464
+ try {
3465
+ if (fs8.existsSync(SETTINGS_FILE2)) {
3466
+ const content = fs8.readFileSync(SETTINGS_FILE2, "utf-8");
3467
+ settings = JSON.parse(content);
3468
+ }
3469
+ } catch {
3470
+ }
3471
+ if (level === "default" /* DEFAULT */) {
3472
+ delete settings.permissions;
3473
+ delete settings.permissionLevel;
3474
+ } else {
3475
+ const rules = PERMISSION_RULES[level];
3476
+ settings.permissions = {
3477
+ allow: rules.allow,
3478
+ deny: rules.deny
3479
+ };
3480
+ settings.permissionLevel = level;
3481
+ }
3482
+ const settingsDir = path9.dirname(SETTINGS_FILE2);
3483
+ if (!fs8.existsSync(settingsDir)) {
3484
+ fs8.mkdirSync(settingsDir, { recursive: true });
3485
+ }
3486
+ fs8.writeFileSync(SETTINGS_FILE2, JSON.stringify(settings, null, 2), "utf-8");
3487
+ }
3488
+ function getPermissionLevelName(level) {
3489
+ return PERMISSION_DESCRIPTIONS[level].name;
3490
+ }
3491
+ function getPermissionLevelDescription(level) {
3492
+ return PERMISSION_DESCRIPTIONS[level];
3493
+ }
3494
+
3495
+ // src/cli/menus/settings.ts
3496
+ var SETTINGS_FILE3 = path10.join(os10.homedir(), ".claude", "settings.json");
3260
3497
  var LANGUAGE_OPTIONS = [
3261
3498
  { name: "\u4E2D\u6587 (chinese)", value: "chinese" },
3262
3499
  { name: "English", value: "english" },
@@ -3282,6 +3519,10 @@ async function showSettingsMenu() {
3282
3519
  name: `\u57FA\u7840\u8BBE\u7F6E`,
3283
3520
  value: "basic" /* BASIC */
3284
3521
  },
3522
+ {
3523
+ name: `\u6743\u9650\u914D\u7F6E`,
3524
+ value: "permissions" /* PERMISSIONS */
3525
+ },
3285
3526
  {
3286
3527
  name: `\u67E5\u770B\u914D\u7F6E\u6587\u4EF6`,
3287
3528
  value: "view_config" /* VIEW_CONFIG */
@@ -3302,6 +3543,9 @@ async function showSettingsMenu() {
3302
3543
  case "basic" /* BASIC */:
3303
3544
  await showBasicSettings();
3304
3545
  break;
3546
+ case "permissions" /* PERMISSIONS */:
3547
+ await showPermissionsSettings();
3548
+ break;
3305
3549
  case "view_config" /* VIEW_CONFIG */:
3306
3550
  await handleViewConfig();
3307
3551
  break;
@@ -3500,11 +3744,11 @@ async function handleBooleanSetting(key, label) {
3500
3744
  }
3501
3745
  async function handleViewConfig() {
3502
3746
  console.log();
3503
- console.log(theme.primary(`\u914D\u7F6E\u6587\u4EF6\u8DEF\u5F84: ${SETTINGS_FILE2}`));
3747
+ console.log(theme.primary(`\u914D\u7F6E\u6587\u4EF6\u8DEF\u5F84: ${SETTINGS_FILE3}`));
3504
3748
  console.log();
3505
3749
  try {
3506
- if (fs8.existsSync(SETTINGS_FILE2)) {
3507
- const content = fs8.readFileSync(SETTINGS_FILE2, "utf-8");
3750
+ if (fs9.existsSync(SETTINGS_FILE3)) {
3751
+ const content = fs9.readFileSync(SETTINGS_FILE3, "utf-8");
3508
3752
  console.log(theme.dim("\u2500".repeat(50)));
3509
3753
  console.log(content);
3510
3754
  console.log(theme.dim("\u2500".repeat(50)));
@@ -3519,6 +3763,106 @@ async function handleViewConfig() {
3519
3763
  { type: "input", name: "continue", message: "\u6309\u56DE\u8F66\u952E\u7EE7\u7EED..." }
3520
3764
  ]);
3521
3765
  }
3766
+ async function showPermissionsSettings() {
3767
+ while (true) {
3768
+ showHeader();
3769
+ const currentLevel = getCurrentPermissionLevel();
3770
+ const currentLevelName = getPermissionLevelName(currentLevel);
3771
+ console.log(createBoxTitle(`\u6743\u9650\u914D\u7F6E [\u5F53\u524D: ${currentLevelName}]`));
3772
+ console.log();
3773
+ const { choice } = await inquirer7.prompt([
3774
+ {
3775
+ type: "list",
3776
+ name: "choice",
3777
+ message: "\u8BF7\u9009\u62E9\u6743\u9650\u7EA7\u522B\uFF1A",
3778
+ choices: [
3779
+ {
3780
+ name: `\u9ED8\u8BA4\uFF08\u6BCF\u6B21\u90FD\u786E\u8BA4\uFF09${currentLevel === "default" /* DEFAULT */ ? theme.success(" \u2713") : ""}`,
3781
+ value: "default" /* DEFAULT */
3782
+ },
3783
+ {
3784
+ name: `\u4E2D\u7B49\u6743\u9650\uFF08\u53EA\u786E\u8BA4\u5220\u9664\u548C\u5371\u9669\u547D\u4EE4\uFF09${currentLevel === "moderate" /* MODERATE */ ? theme.success(" \u2713") : ""}`,
3785
+ value: "moderate" /* MODERATE */
3786
+ },
3787
+ {
3788
+ name: `\u6700\u5927\u6743\u9650\uFF08\u53EA\u786E\u8BA4\u9AD8\u5371\u64CD\u4F5C\uFF09${currentLevel === "maximum" /* MAXIMUM */ ? theme.success(" \u2713") : ""}`,
3789
+ value: "maximum" /* MAXIMUM */
3790
+ },
3791
+ new inquirer7.Separator(),
3792
+ {
3793
+ name: `${theme.dim("<-")} \u8FD4\u56DE`,
3794
+ value: "__back__"
3795
+ },
3796
+ {
3797
+ name: `${theme.dim("X")} \u9000\u51FA`,
3798
+ value: "__exit__"
3799
+ }
3800
+ ]
3801
+ }
3802
+ ]);
3803
+ if (choice === "__back__") {
3804
+ return;
3805
+ }
3806
+ if (choice === "__exit__") {
3807
+ process.exit(0);
3808
+ }
3809
+ await handlePermissionLevelChange(choice);
3810
+ }
3811
+ }
3812
+ async function handlePermissionLevelChange(level) {
3813
+ const currentLevel = getCurrentPermissionLevel();
3814
+ if (level === currentLevel) {
3815
+ showInfo("\u5DF2\u7ECF\u662F\u5F53\u524D\u6743\u9650\u7EA7\u522B");
3816
+ console.log();
3817
+ await inquirer7.prompt([
3818
+ { type: "input", name: "continue", message: "\u6309\u56DE\u8F66\u952E\u7EE7\u7EED..." }
3819
+ ]);
3820
+ return;
3821
+ }
3822
+ if (level !== "default" /* DEFAULT */) {
3823
+ const confirmed = await showPermissionConfirmation(level);
3824
+ if (!confirmed) {
3825
+ return;
3826
+ }
3827
+ }
3828
+ try {
3829
+ applyPermissionLevel(level);
3830
+ const levelName = getPermissionLevelName(level);
3831
+ showSuccess(`\u6743\u9650\u914D\u7F6E\u5DF2\u66F4\u65B0\u4E3A\uFF1A${levelName}`);
3832
+ showInfo(`\u914D\u7F6E\u6587\u4EF6\uFF1A${SETTINGS_FILE3}`);
3833
+ } catch (error) {
3834
+ showError(`\u4FDD\u5B58\u5931\u8D25: ${error.message}`);
3835
+ }
3836
+ console.log();
3837
+ await inquirer7.prompt([
3838
+ { type: "input", name: "continue", message: "\u6309\u56DE\u8F66\u952E\u7EE7\u7EED..." }
3839
+ ]);
3840
+ }
3841
+ async function showPermissionConfirmation(level) {
3842
+ console.log();
3843
+ const desc = getPermissionLevelDescription(level);
3844
+ console.log(theme.warning(`\u4F60\u5373\u5C06\u5207\u6362\u5230\u300C${desc.name}\u300D\u6A21\u5F0F`));
3845
+ console.log();
3846
+ console.log(theme.success("\u5C06\u81EA\u52A8\u5141\u8BB8\u7684\u64CD\u4F5C\uFF1A"));
3847
+ desc.autoAllow.forEach((item) => {
3848
+ console.log(theme.success(` \u2713 ${item}`));
3849
+ });
3850
+ console.log();
3851
+ console.log(theme.warning("\u4ECD\u9700\u786E\u8BA4\u7684\u64CD\u4F5C\uFF1A"));
3852
+ desc.needConfirm.forEach((item) => {
3853
+ console.log(theme.warning(` \u26A0 ${item}`));
3854
+ });
3855
+ console.log();
3856
+ const { confirm } = await inquirer7.prompt([
3857
+ {
3858
+ type: "confirm",
3859
+ name: "confirm",
3860
+ message: "\u786E\u5B9A\u5207\u6362\u5417\uFF1F",
3861
+ default: false
3862
+ }
3863
+ ]);
3864
+ return confirm;
3865
+ }
3522
3866
 
3523
3867
  // src/cli/menus/main.ts
3524
3868
  async function showMainMenu() {