ccjk 15.1.0 → 15.2.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 CHANGED
@@ -15,11 +15,12 @@ npm install -g ccjk
15
15
  ## 快速上手
16
16
 
17
17
  ```bash
18
- ccjk # 交互菜单
19
- ccjk init # 配置 API(同时存为 profile)
20
- ccjk use # 一键切换已配过的 API
21
- ccjk mcp # MCP 服务
22
- ccjk doctor # 检查 settings.json
18
+ ccjk # 交互菜单
19
+ ccjk init # 配置 API(同时存为 profile)
20
+ ccjk use # 一键切换已配过的 API
21
+ ccjk perms standard # 一键设权限档位(同时作用于 3 个工具)
22
+ ccjk mcp # MCP 服务
23
+ ccjk doctor # 检查 settings.json
23
24
  ```
24
25
 
25
26
  ## 命令一览
@@ -32,6 +33,8 @@ ccjk doctor # 检查 settings.json
32
33
  | `ccjk profile ls` | 列出所有 profile(标记当前) |
33
34
  | `ccjk profile show [name]` | 查看 profile 详情(不带参=当前) |
34
35
  | `ccjk profile rm [name]` | 删除 profile |
36
+ | `ccjk perms [tier]` | **一键设权限档位**(safe/standard/yolo),同时作用于 clavue/claude-code/codex |
37
+ | `ccjk perms-show` | 查看三个工具当前的权限状态 |
35
38
  | `ccjk mcp` | 选装预设 MCP 服务(context7、serena、playwright、…) |
36
39
  | `ccjk doctor` | 检查 settings.json 中的常见配置问题 |
37
40
  | `ccjk detect` | 列出已安装的代码工具 |
@@ -52,10 +55,35 @@ ccjk profile ls # 看当前用的是哪个
52
55
 
53
56
  Profile 存储在 `~/.ccjk/profiles/<name>.json`,当前激活的记录在 `~/.ccjk/state.json`。
54
57
 
58
+ ### Perms:一键档位授权
59
+
60
+ 一条命令把 Clavue / Claude Code / Codex 的权限同步到同一档位,减少每次操作都要点确认的烦躁。
61
+
62
+ | 档位 | 适合 | Claude/Clavue | Codex |
63
+ |---|---|---|---|
64
+ | `safe` | 浏览代码、新手 | 仅放行只读(Read/Grep/...) | `approval_policy=untrusted`, `sandbox_mode=read-only` |
65
+ | `standard`(推荐) | 日常开发 | + git/npm/pnpm/python/ls/cat 等高频命令 | `approval_policy=on-failure`, `sandbox_mode=workspace-write` |
66
+ | `yolo` | 可信项目放飞 | `Bash(*)` + `allowUnsandboxedCommands=true` | `approval_policy=never`, `sandbox_mode=workspace-write` |
67
+
68
+ 不论哪一档,都强制写入 `deny`:`rm -rf /`、`git push --force`、`npm publish`、`sudo` 等不可逆 / 高危命令,避免手抖。
69
+
70
+ ```bash
71
+ ccjk perms # 交互选档位(推荐)
72
+ ccjk perms standard # 直接应用 standard 到全部 3 个工具
73
+ ccjk perms safe --tools clavue,claude-code # 只作用于这两个
74
+ ccjk perms yolo --reset # --reset 会清空原 allow 后再写(默认是 append + dedupe)
75
+ ccjk perms-show # 看三个工具当前各是哪档
76
+ ```
77
+
78
+ 合并策略:
79
+ - `allow`:默认 append + dedupe,保护用户自定义白名单。`--reset` 强制覆盖。
80
+ - `deny`:始终覆盖,确保危险命令一定被拦。
81
+
55
82
  ### 非交互模式
56
83
 
57
84
  ```bash
58
85
  ccjk init -t clavue -p glm --api-key sk-xxx --profile work -y
86
+ ccjk perms standard -y
59
87
  ccjk mcp -s context7 serena -y
60
88
  ccjk git-install --scope user -y
61
89
  ```
package/dist/cli.js CHANGED
@@ -11,6 +11,7 @@ import { detectCommand } from './commands/detect.js';
11
11
  import { gitInstallCommand } from './commands/git-install.js';
12
12
  import { menuCommand } from './commands/menu.js';
13
13
  import { profileListCommand, profileRmCommand, profileShowCommand, profileUseCommand, } from './commands/profile.js';
14
+ import { permsCommand, permsShowCommand } from './commands/perms.js';
14
15
  const pkgPath = join(dirname(fileURLToPath(import.meta.url)), '..', 'package.json');
15
16
  const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8'));
16
17
  const program = new Command();
@@ -63,6 +64,17 @@ program
63
64
  .option('-s, --services <ids...>', '直接指定服务 id')
64
65
  .option('-y, --yes', '跳过确认')
65
66
  .action((opts) => mcpCommand(opts));
67
+ program
68
+ .command('perms [tier]')
69
+ .description('一键设置权限档位(safe | standard | yolo),同时作用于 clavue/claude-code/codex')
70
+ .option('--tools <list>', '逗号分隔指定工具,如 clavue,claude-code(默认全部)')
71
+ .option('--reset', '完全替换 allow 列表(不做合并;deny 总是替换)')
72
+ .option('-y, --yes', '跳过确认')
73
+ .action((tier, opts) => permsCommand(tier, opts));
74
+ program
75
+ .command('perms-show')
76
+ .description('查看三个工具当前的权限状态')
77
+ .action(permsShowCommand);
66
78
  program
67
79
  .command('doctor')
68
80
  .description('检查 settings.json 中的常见配置问题')
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAC9D,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EACL,kBAAkB,EAClB,gBAAgB,EAChB,kBAAkB,EAClB,iBAAiB,GAClB,MAAM,uBAAuB,CAAC;AAE/B,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,cAAc,CAAC,CAAC;AACpF,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,CAAwB,CAAC;AAE9E,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,MAAM,CAAC;KACZ,WAAW,CAAC,6BAA6B,CAAC;KAC1C,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;AAExB,OAAO;KACJ,OAAO,CAAC,MAAM,CAAC;KACf,WAAW,CAAC,sCAAsC,CAAC;KACnD,MAAM,CAAC,mBAAmB,EAAE,mCAAmC,CAAC;KAChE,MAAM,CAAC,qBAAqB,EAAE,uDAAuD,CAAC;KACtF,MAAM,CAAC,kBAAkB,EAAE,cAAc,CAAC;KAC1C,MAAM,CAAC,iBAAiB,EAAE,sBAAsB,CAAC;KACjD,MAAM,CAAC,kBAAkB,EAAE,sBAAsB,CAAC;KAClD,MAAM,CAAC,WAAW,EAAE,MAAM,CAAC;KAC3B,MAAM,CAAC,WAAW,CAAC,CAAC;AAEvB,OAAO;KACJ,OAAO,CAAC,YAAY,CAAC;KACrB,WAAW,CAAC,yBAAyB,CAAC;KACtC,MAAM,CAAC,mBAAmB,EAAE,MAAM,EAAE,QAAQ,CAAC;KAC7C,MAAM,CAAC,WAAW,EAAE,MAAM,CAAC;KAC3B,MAAM,CAAC,CAAC,IAAwB,EAAE,IAAkE,EAAE,EAAE,CACvG,iBAAiB,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC;AAEnC,MAAM,OAAO,GAAG,OAAO;KACpB,OAAO,CAAC,SAAS,CAAC;KAClB,WAAW,CAAC,oBAAoB,CAAC,CAAC;AACrC,OAAO;KACJ,OAAO,CAAC,IAAI,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;KAClC,WAAW,CAAC,oBAAoB,CAAC;KACjC,MAAM,CAAC,kBAAkB,CAAC,CAAC;AAC9B,OAAO;KACJ,OAAO,CAAC,YAAY,CAAC;KACrB,WAAW,CAAC,eAAe,CAAC;KAC5B,MAAM,CAAC,mBAAmB,EAAE,MAAM,EAAE,QAAQ,CAAC;KAC7C,MAAM,CAAC,WAAW,EAAE,MAAM,CAAC;KAC3B,MAAM,CAAC,CAAC,IAAwB,EAAE,IAAkE,EAAE,EAAE,CACvG,iBAAiB,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC;AACnC,OAAO;KACJ,OAAO,CAAC,WAAW,CAAC;KACpB,WAAW,CAAC,YAAY,CAAC;KACzB,MAAM,CAAC,WAAW,EAAE,MAAM,CAAC;KAC3B,MAAM,CAAC,CAAC,IAAwB,EAAE,IAAuB,EAAE,EAAE,CAAC,gBAAgB,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC;AAC/F,OAAO;KACJ,OAAO,CAAC,aAAa,CAAC;KACtB,WAAW,CAAC,uBAAuB,CAAC;KACpC,MAAM,CAAC,CAAC,IAAwB,EAAE,EAAE,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC,CAAC;AAElE,OAAO;KACJ,OAAO,CAAC,KAAK,CAAC;KACd,WAAW,CAAC,WAAW,CAAC;KACxB,MAAM,CAAC,mBAAmB,EAAE,MAAM,EAAE,QAAQ,CAAC;KAC7C,MAAM,CAAC,yBAAyB,EAAE,WAAW,CAAC;KAC9C,MAAM,CAAC,WAAW,EAAE,MAAM,CAAC;KAC3B,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC;AAEtC,OAAO;KACJ,OAAO,CAAC,QAAQ,CAAC;KACjB,WAAW,CAAC,2BAA2B,CAAC;KACxC,MAAM,CAAC,aAAa,CAAC,CAAC;AAEzB,OAAO;KACJ,OAAO,CAAC,QAAQ,CAAC;KACjB,WAAW,CAAC,YAAY,CAAC;KACzB,MAAM,CAAC,aAAa,CAAC,CAAC;AAEzB,OAAO;KACJ,OAAO,CAAC,aAAa,CAAC;KACtB,WAAW,CAAC,uCAAuC,CAAC;KACpD,MAAM,CAAC,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,CAAC;KACnD,MAAM,CAAC,gBAAgB,EAAE,SAAS,CAAC;KACnC,MAAM,CAAC,WAAW,EAAE,MAAM,CAAC;KAC3B,MAAM,CAAC,iBAAiB,CAAC,CAAC;AAE7B,OAAO;KACJ,OAAO,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;KACpC,WAAW,CAAC,YAAY,CAAC;KACzB,MAAM,CAAC,WAAW,CAAC,CAAC;AAEvB,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,GAAU,EAAE,EAAE;IACpD,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,GAAG,CAAC,OAAO,IAAI,CAAC,CAAC,CAAC;IACjD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -6,14 +6,16 @@ import { mcpCommand } from './mcp.js';
6
6
  import { doctorCommand } from './doctor.js';
7
7
  import { gitInstallCommand } from './git-install.js';
8
8
  import { profileUseCommand } from './profile.js';
9
+ import { permsCommand } from './perms.js';
9
10
  import { listProfiles, readState } from '../core/profiles.js';
10
11
  const ITEMS = [
11
12
  { key: '1', label: '配置 API(init)', run: () => initCommand() },
12
13
  { key: '2', label: '切换 Profile(快速切换 API)', run: () => profileUseCommand(undefined) },
13
- { key: '3', label: '配置 MCP 服务', run: () => mcpCommand() },
14
- { key: '4', label: '体检(doctor)', run: () => doctorCommand() },
15
- { key: '5', label: '安装 Git 命令模板', run: () => gitInstallCommand() },
16
- { key: '6', label: '检测已安装的工具', run: async () => detectCommand() },
14
+ { key: '3', label: '一键设权限档位(safe/standard/yolo)', run: () => permsCommand(undefined) },
15
+ { key: '4', label: '配置 MCP 服务', run: () => mcpCommand() },
16
+ { key: '5', label: '体检(doctor)', run: () => doctorCommand() },
17
+ { key: '6', label: '安装 Git 命令模板', run: () => gitInstallCommand() },
18
+ { key: '7', label: '检测已安装的工具', run: async () => detectCommand() },
17
19
  ];
18
20
  export async function menuCommand() {
19
21
  console.log(ansis.bold('\nccjk - Clavue/Claude Code 配置助手\n'));
@@ -31,7 +33,7 @@ export async function menuCommand() {
31
33
  type: 'input',
32
34
  name: 'choice',
33
35
  message: '\n选择',
34
- validate: (v) => /^[1-6q]$/.test(v.trim()) || '输入 1-6 或 q',
36
+ validate: (v) => /^[1-7q]$/.test(v.trim()) || '输入 1-7 或 q',
35
37
  }]);
36
38
  if (choice.trim() === 'q')
37
39
  return;
@@ -1 +1 @@
1
- {"version":3,"file":"menu.js","sourceRoot":"","sources":["../../src/commands/menu.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"menu.js","sourceRoot":"","sources":["../../src/commands/menu.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,110 @@
1
+ import inquirer from 'inquirer';
2
+ import ansis from 'ansis';
3
+ import { TOOLS } from '../core/tools.js';
4
+ import { readSettings, writeSettings } from '../core/settings.js';
5
+ import { readTomlFile, writeTomlFile } from '../core/toml.js';
6
+ import { TIERS, applyTierToClaudeSettings, applyTierToCodexConfig, detectClaudeTier, detectCodexTier, getTier, } from '../core/perms.js';
7
+ export async function permsCommand(tier, opts = {}) {
8
+ const tierId = tier ?? await pickTier();
9
+ const def = getTier(tierId);
10
+ const tools = parseTools(opts.tools);
11
+ console.log(ansis.bold(`\n档位: ${def.name} (${def.id})`));
12
+ console.log(ansis.dim(` ${def.description}\n`));
13
+ console.log(ansis.dim(` 目标工具: ${tools.join(', ')}`));
14
+ if (opts.reset)
15
+ console.log(ansis.yellow(' --reset: 将完全替换 allow 列表(用户已有自定义会丢)'));
16
+ console.log();
17
+ if (!opts.yes) {
18
+ const { ok } = await inquirer.prompt([{
19
+ type: 'confirm',
20
+ name: 'ok',
21
+ message: '确认应用?',
22
+ default: true,
23
+ }]);
24
+ if (!ok) {
25
+ console.log(ansis.gray('已取消。'));
26
+ return;
27
+ }
28
+ }
29
+ const reset = opts.reset ?? false;
30
+ const results = [];
31
+ for (const t of tools) {
32
+ if (t === 'codex') {
33
+ const r = await applyToCodex(def);
34
+ results.push(r);
35
+ }
36
+ else {
37
+ const r = await applyToClaudeLike(t, def, reset);
38
+ results.push(r);
39
+ }
40
+ }
41
+ console.log(ansis.green('\n✔ 权限设置已应用'));
42
+ for (const r of results)
43
+ console.log(` ${r}`);
44
+ console.log();
45
+ }
46
+ async function applyToClaudeLike(tool, def, reset) {
47
+ const meta = TOOLS[tool];
48
+ const settings = await readSettings(meta.settingsFile);
49
+ const { addedAllow } = applyTierToClaudeSettings(settings, def, { reset });
50
+ const backup = await writeSettings(meta.settingsFile, settings);
51
+ const allowMsg = reset ? `allow=${def.claude.allow.length}(已替换)` : `allow +${addedAllow}`;
52
+ const tail = backup ? ansis.dim(` · 备份 ${backup.split('/').pop()}`) : '';
53
+ return `${meta.displayName}: ${allowMsg}, deny=${def.claude.deny.length}, allowUnsandboxed=${def.claude.allowUnsandboxedCommands}${tail}`;
54
+ }
55
+ async function applyToCodex(def) {
56
+ const meta = TOOLS.codex;
57
+ const doc = await readTomlFile(meta.settingsFile);
58
+ applyTierToCodexConfig(doc, def);
59
+ const backup = await writeTomlFile(meta.settingsFile, doc);
60
+ const tail = backup ? ansis.dim(` · 备份 ${backup.split('/').pop()}`) : '';
61
+ return `${meta.displayName}: approval_policy=${def.codex.approvalPolicy}, sandbox_mode=${def.codex.sandboxMode}${tail}`;
62
+ }
63
+ export async function permsShowCommand() {
64
+ console.log(ansis.bold('\n当前权限状态:\n'));
65
+ for (const tool of ['clavue', 'claude-code']) {
66
+ const meta = TOOLS[tool];
67
+ const settings = await readSettings(meta.settingsFile);
68
+ const tier = detectClaudeTier(settings);
69
+ const allow = settings.permissions?.allow ?? [];
70
+ const deny = settings.permissions?.deny ?? [];
71
+ const unsandboxed = settings.allowUnsandboxedCommands === true;
72
+ const tierLabel = tier ? ansis.green(tier) : ansis.gray('自定义/未配置');
73
+ console.log(` ${ansis.bold(meta.displayName.padEnd(14))} ${tierLabel}`);
74
+ console.log(ansis.dim(` allow: ${allow.length}, deny: ${deny.length}, allowUnsandboxed: ${unsandboxed}`));
75
+ }
76
+ const codexMeta = TOOLS.codex;
77
+ const doc = await readTomlFile(codexMeta.settingsFile);
78
+ const codexTier = detectCodexTier(doc);
79
+ const ap = doc.values.get('approval_policy') ?? '(未设)';
80
+ const sm = doc.values.get('sandbox_mode') ?? '(未设)';
81
+ const tierLabel = codexTier ? ansis.green(codexTier) : ansis.gray('自定义/未配置');
82
+ console.log(` ${ansis.bold(codexMeta.displayName.padEnd(14))} ${tierLabel}`);
83
+ console.log(ansis.dim(` approval_policy: ${ap}, sandbox_mode: ${sm}`));
84
+ console.log();
85
+ }
86
+ async function pickTier() {
87
+ const { tier } = await inquirer.prompt([{
88
+ type: 'list',
89
+ name: 'tier',
90
+ message: '选择权限档位',
91
+ default: 'standard',
92
+ choices: Object.values(TIERS).map(t => ({
93
+ name: `${t.name.padEnd(10)} ${ansis.dim(t.description)}`,
94
+ value: t.id,
95
+ })),
96
+ }]);
97
+ return tier;
98
+ }
99
+ function parseTools(raw) {
100
+ if (!raw)
101
+ return ['clavue', 'claude-code', 'codex'];
102
+ const valid = ['clavue', 'claude-code', 'codex'];
103
+ const items = raw.split(',').map(s => s.trim()).filter(Boolean);
104
+ for (const t of items) {
105
+ if (!valid.includes(t))
106
+ throw new Error(`未知工具 "${t}",可选: ${valid.join(', ')}`);
107
+ }
108
+ return items;
109
+ }
110
+ //# sourceMappingURL=perms.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"perms.js","sourceRoot":"","sources":["../../src/commands/perms.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,167 @@
1
+ import { setTomlValue } from './toml.js';
2
+ /**
3
+ * 三个档位定义。
4
+ *
5
+ * 设计原则:
6
+ * - safe:日常浏览/阅读代码,几乎不会触发授权弹窗。所有写操作仍需确认。
7
+ * - standard:日常开发,git/包管理常见命令免弹窗,但破坏性命令仍要确认。
8
+ * - yolo:大胆放飞,但保留 deny 兜底(rm -rf /、git push --force 等绝对禁止)。
9
+ *
10
+ * 不要乱加规则:每条 allow/deny 都应能用一句话解释为什么放进或挡住。
11
+ */
12
+ export const TIERS = {
13
+ safe: {
14
+ id: 'safe',
15
+ name: '安全模式',
16
+ description: '只读操作免确认;写操作、命令执行都要授权(适合新手 / 浏览代码)',
17
+ claude: {
18
+ allow: [
19
+ 'Read(*)',
20
+ 'Grep(*)',
21
+ 'Glob(*)',
22
+ 'LS(*)',
23
+ 'WebFetch(*)',
24
+ 'WebSearch(*)',
25
+ ],
26
+ deny: COMMON_DENY(),
27
+ allowUnsandboxedCommands: false,
28
+ },
29
+ codex: {
30
+ approvalPolicy: 'untrusted',
31
+ sandboxMode: 'read-only',
32
+ },
33
+ },
34
+ standard: {
35
+ id: 'standard',
36
+ name: '日常开发',
37
+ description: '只读 + git/npm/pnpm/常见 shell 免确认;危险命令仍拦截(推荐)',
38
+ claude: {
39
+ allow: [
40
+ 'Read(*)', 'Grep(*)', 'Glob(*)', 'LS(*)', 'WebFetch(*)', 'WebSearch(*)',
41
+ 'Edit(*)', 'Write(*)', 'NotebookEdit(*)',
42
+ 'Bash(git status)', 'Bash(git diff:*)', 'Bash(git log:*)', 'Bash(git show:*)',
43
+ 'Bash(git branch:*)', 'Bash(git stash:*)', 'Bash(git add:*)', 'Bash(git commit:*)',
44
+ 'Bash(git pull:*)', 'Bash(git fetch:*)', 'Bash(git rebase:*)', 'Bash(git merge:*)',
45
+ 'Bash(git checkout:*)', 'Bash(git switch:*)', 'Bash(git restore:*)',
46
+ 'Bash(npm:*)', 'Bash(pnpm:*)', 'Bash(yarn:*)', 'Bash(bun:*)', 'Bash(npx:*)', 'Bash(pnpx:*)',
47
+ 'Bash(node:*)', 'Bash(tsx:*)', 'Bash(deno:*)',
48
+ 'Bash(python:*)', 'Bash(python3:*)', 'Bash(pip:*)', 'Bash(pip3:*)', 'Bash(uv:*)', 'Bash(poetry:*)',
49
+ 'Bash(cargo:*)', 'Bash(rustc:*)',
50
+ 'Bash(go:*)',
51
+ 'Bash(make:*)',
52
+ 'Bash(ls:*)', 'Bash(cat:*)', 'Bash(head:*)', 'Bash(tail:*)', 'Bash(wc:*)',
53
+ 'Bash(rg:*)', 'Bash(grep:*)', 'Bash(find:*)', 'Bash(fd:*)',
54
+ 'Bash(echo:*)', 'Bash(pwd)', 'Bash(which:*)', 'Bash(env)',
55
+ 'Bash(mkdir:*)', 'Bash(touch:*)', 'Bash(cp:*)', 'Bash(mv:*)',
56
+ 'Bash(curl:*)', 'Bash(wget:*)',
57
+ ],
58
+ deny: COMMON_DENY(),
59
+ allowUnsandboxedCommands: false,
60
+ },
61
+ codex: {
62
+ approvalPolicy: 'on-failure',
63
+ sandboxMode: 'workspace-write',
64
+ },
65
+ },
66
+ yolo: {
67
+ id: 'yolo',
68
+ name: '放开授权',
69
+ description: '默认放行所有操作;仅保留极少数高危命令拦截(仅在可信项目里用)',
70
+ claude: {
71
+ allow: [
72
+ 'Read(*)', 'Grep(*)', 'Glob(*)', 'LS(*)', 'WebFetch(*)', 'WebSearch(*)',
73
+ 'Edit(*)', 'Write(*)', 'NotebookEdit(*)',
74
+ 'Bash(*)',
75
+ ],
76
+ deny: COMMON_DENY(),
77
+ allowUnsandboxedCommands: true,
78
+ },
79
+ codex: {
80
+ approvalPolicy: 'never',
81
+ sandboxMode: 'workspace-write',
82
+ },
83
+ },
84
+ };
85
+ /**
86
+ * 必须始终拦截的命令——任何档位都加。
87
+ * 注意是模式不是精确字符串,使用 Claude Code 的 `Bash(<command>:*)` 语法。
88
+ */
89
+ function COMMON_DENY() {
90
+ return [
91
+ 'Bash(rm -rf /:*)',
92
+ 'Bash(rm -rf ~:*)',
93
+ 'Bash(rm -rf $HOME:*)',
94
+ 'Bash(:(){ :|:& };:*)',
95
+ 'Bash(mkfs:*)',
96
+ 'Bash(dd if=:*)',
97
+ 'Bash(git push --force:*)',
98
+ 'Bash(git push -f:*)',
99
+ 'Bash(git push --force-with-lease:*)',
100
+ 'Bash(npm publish:*)',
101
+ 'Bash(pnpm publish:*)',
102
+ 'Bash(yarn publish:*)',
103
+ 'Bash(sudo:*)',
104
+ ];
105
+ }
106
+ export function getTier(id) {
107
+ if (!(id in TIERS)) {
108
+ throw new Error(`未知档位 "${id}",可选: ${Object.keys(TIERS).join(', ')}`);
109
+ }
110
+ return TIERS[id];
111
+ }
112
+ /**
113
+ * 应用到 Claude/Clavue settings.json(in-place)。
114
+ * 合并策略:deny 总是覆盖(确保危险拦截生效),allow 默认 append + dedupe。
115
+ */
116
+ export function applyTierToClaudeSettings(settings, tier, opts = {}) {
117
+ settings.permissions = settings.permissions ?? {};
118
+ const before = settings.permissions.allow ?? [];
119
+ const allow = opts.reset
120
+ ? [...tier.claude.allow]
121
+ : dedupe([...before, ...tier.claude.allow]);
122
+ settings.permissions.allow = allow;
123
+ settings.permissions.deny = [...tier.claude.deny];
124
+ settings.allowUnsandboxedCommands = tier.claude.allowUnsandboxedCommands;
125
+ return {
126
+ addedAllow: allow.length - before.length,
127
+ replacedDeny: true,
128
+ };
129
+ }
130
+ /**
131
+ * 应用到 Codex config.toml(修改 TomlDoc.raw 原地)。
132
+ * Codex 没有 allow/deny 列表语义,只有 policy + sandbox,所以"合并"在这里没意义,直接覆盖这两个字段。
133
+ */
134
+ export function applyTierToCodexConfig(doc, tier) {
135
+ setTomlValue(doc, 'approval_policy', tier.codex.approvalPolicy);
136
+ setTomlValue(doc, 'sandbox_mode', tier.codex.sandboxMode);
137
+ }
138
+ function dedupe(arr) {
139
+ return Array.from(new Set(arr));
140
+ }
141
+ /**
142
+ * 读出当前 settings 看起来最像哪个档位(仅做提示,不精确)。
143
+ * 判断依据:是否启用 allowUnsandboxedCommands、Bash(*) 是否在 allow 里。
144
+ */
145
+ export function detectClaudeTier(settings) {
146
+ const allow = settings.permissions?.allow ?? [];
147
+ const allowUnsandboxed = settings.allowUnsandboxedCommands === true;
148
+ if (allowUnsandboxed && allow.includes('Bash(*)'))
149
+ return 'yolo';
150
+ if (allow.some(a => a.startsWith('Bash(git') || a.startsWith('Bash(npm')))
151
+ return 'standard';
152
+ if (allow.length > 0 && allow.every(a => /^(Read|Grep|Glob|LS|WebFetch|WebSearch)\(/.test(a)))
153
+ return 'safe';
154
+ return null;
155
+ }
156
+ export function detectCodexTier(doc) {
157
+ const ap = doc.values.get('approval_policy');
158
+ const sm = doc.values.get('sandbox_mode');
159
+ if (ap === 'never' && sm === 'workspace-write')
160
+ return 'yolo';
161
+ if (ap === 'on-failure' && sm === 'workspace-write')
162
+ return 'standard';
163
+ if (ap === 'untrusted' && sm === 'read-only')
164
+ return 'safe';
165
+ return null;
166
+ }
167
+ //# sourceMappingURL=perms.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"perms.js","sourceRoot":"","sources":["../../src/core/perms.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,160 @@
1
+ /**
2
+ * 极简 TOML 读写器,仅支持本工具需要的字段:
3
+ * - 顶层标量(string/number/bool)
4
+ * - 顶层数组 of string
5
+ * - [section] / [section.subsection] 表
6
+ *
7
+ * 设计取舍:
8
+ * - 不引入第三方 TOML 库(codex 配置很简单,自己写够用)
9
+ * - 写出时**最大限度保留原文件**:未识别的行原样保留,已知字段就地替换
10
+ * - 仅在末尾追加新字段
11
+ *
12
+ * 不支持的特性(codex 当前配置不会用到):
13
+ * - 多行字符串、复杂内联表、数字数组、日期等
14
+ * 如果碰到无法解析的内容,readCodexConfig 会原样保留它,set/get 只操作能识别的部分。
15
+ */
16
+ import { existsSync } from 'node:fs';
17
+ import { copyFile, mkdir, readFile, writeFile } from 'node:fs/promises';
18
+ import { dirname } from 'node:path';
19
+ import { expandHome } from './paths.js';
20
+ export async function readTomlFile(path) {
21
+ const real = expandHome(path);
22
+ if (!existsSync(real))
23
+ return { raw: '', values: new Map() };
24
+ const raw = await readFile(real, 'utf-8');
25
+ return parseToml(raw);
26
+ }
27
+ export async function writeTomlFile(path, doc) {
28
+ const real = expandHome(path);
29
+ await mkdir(dirname(real), { recursive: true });
30
+ let backup = '';
31
+ if (existsSync(real)) {
32
+ const ts = new Date().toISOString().replace(/[:.]/g, '-');
33
+ backup = `${real}.bak-${ts}`;
34
+ await copyFile(real, backup);
35
+ }
36
+ await writeFile(real, doc.raw, 'utf-8');
37
+ return backup;
38
+ }
39
+ export function parseToml(raw) {
40
+ const values = new Map();
41
+ let section = '';
42
+ for (const line of raw.split('\n')) {
43
+ const t = line.trim();
44
+ if (!t || t.startsWith('#'))
45
+ continue;
46
+ const sec = /^\[([^\]]+)\]$/.exec(t);
47
+ if (sec) {
48
+ section = sec[1].trim();
49
+ continue;
50
+ }
51
+ const kv = /^([A-Za-z0-9_.-]+)\s*=\s*(.+?)\s*(?:#.*)?$/.exec(t);
52
+ if (!kv)
53
+ continue;
54
+ const key = section ? `${section}.${kv[1]}` : kv[1];
55
+ const v = parseScalar(kv[2]);
56
+ if (v !== undefined)
57
+ values.set(key, v);
58
+ }
59
+ return { raw, values };
60
+ }
61
+ function parseScalar(s) {
62
+ s = s.trim();
63
+ if (s === 'true')
64
+ return true;
65
+ if (s === 'false')
66
+ return false;
67
+ if (/^-?\d+$/.test(s))
68
+ return Number.parseInt(s, 10);
69
+ if (/^-?\d+\.\d+$/.test(s))
70
+ return Number.parseFloat(s);
71
+ const dq = /^"((?:[^"\\]|\\.)*)"$/.exec(s);
72
+ if (dq)
73
+ return dq[1].replace(/\\"/g, '"').replace(/\\\\/g, '\\');
74
+ const sq = /^'([^']*)'$/.exec(s);
75
+ if (sq)
76
+ return sq[1];
77
+ return undefined;
78
+ }
79
+ function formatScalar(v) {
80
+ if (typeof v === 'boolean')
81
+ return v ? 'true' : 'false';
82
+ if (typeof v === 'number')
83
+ return String(v);
84
+ return `"${v.replace(/\\/g, '\\\\').replace(/"/g, '\\"')}"`;
85
+ }
86
+ /**
87
+ * 设置一个 key('foo.bar' 表示 [foo] section 下的 bar)。
88
+ * - 若已存在:原地替换
89
+ * - 若不存在:追加(保持原 section,没有则建一个)
90
+ */
91
+ export function setTomlValue(doc, key, value) {
92
+ doc.values.set(key, value);
93
+ doc.raw = rewriteToml(doc.raw, key, value);
94
+ }
95
+ function rewriteToml(raw, key, value) {
96
+ const dot = key.lastIndexOf('.');
97
+ const section = dot >= 0 ? key.slice(0, dot) : '';
98
+ const localKey = dot >= 0 ? key.slice(dot + 1) : key;
99
+ const formatted = `${localKey} = ${formatScalar(value)}`;
100
+ const lines = raw.split('\n');
101
+ let curSection = '';
102
+ let replaced = false;
103
+ let sectionLineIdx = -1;
104
+ let sectionLastIdx = -1;
105
+ let firstSectionIdx = -1;
106
+ for (let i = 0; i < lines.length; i++) {
107
+ const t = lines[i].trim();
108
+ const sec = /^\[([^\]]+)\]$/.exec(t);
109
+ if (sec) {
110
+ curSection = sec[1].trim();
111
+ if (firstSectionIdx < 0)
112
+ firstSectionIdx = i;
113
+ if (curSection === section)
114
+ sectionLineIdx = i;
115
+ continue;
116
+ }
117
+ if (curSection === section)
118
+ sectionLastIdx = i;
119
+ const kv = /^([A-Za-z0-9_.-]+)\s*=/.exec(t);
120
+ if (!kv)
121
+ continue;
122
+ if (curSection === section && kv[1] === localKey) {
123
+ lines[i] = formatted;
124
+ replaced = true;
125
+ break;
126
+ }
127
+ }
128
+ if (replaced)
129
+ return lines.join('\n');
130
+ if (!section) {
131
+ // 顶层 key:必须插在第一个 section 之前,否则会落进那个 section
132
+ if (firstSectionIdx >= 0) {
133
+ // 找到第一个 section 前最后一个非空行的位置
134
+ let insertAt = firstSectionIdx;
135
+ while (insertAt > 0 && lines[insertAt - 1].trim() === '')
136
+ insertAt--;
137
+ lines.splice(insertAt, 0, formatted);
138
+ return ensureTrailingNewline(lines.join('\n'));
139
+ }
140
+ const out = lines.slice();
141
+ if (out.length > 0 && out[out.length - 1].trim() !== '')
142
+ out.push('');
143
+ out.push(formatted);
144
+ return ensureTrailingNewline(out.join('\n'));
145
+ }
146
+ if (sectionLineIdx >= 0) {
147
+ const insertAt = sectionLastIdx >= 0 ? sectionLastIdx + 1 : sectionLineIdx + 1;
148
+ lines.splice(insertAt, 0, formatted);
149
+ return lines.join('\n');
150
+ }
151
+ const out = lines.slice();
152
+ if (out.length > 0 && out[out.length - 1].trim() !== '')
153
+ out.push('');
154
+ out.push(`[${section}]`, formatted);
155
+ return ensureTrailingNewline(out.join('\n'));
156
+ }
157
+ function ensureTrailingNewline(s) {
158
+ return s.endsWith('\n') ? s : `${s}\n`;
159
+ }
160
+ //# sourceMappingURL=toml.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"toml.js","sourceRoot":"","sources":["../../src/core/toml.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ccjk",
3
- "version": "15.1.0",
3
+ "version": "15.2.0",
4
4
  "description": "Clavue / Claude Code 配置 CLI — init、API、MCP、doctor、git 模板。一条命令搞定。",
5
5
  "type": "module",
6
6
  "bin": {