ccjk 10.1.0 → 10.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (115) hide show
  1. package/README.md +28 -0
  2. package/dist/chunks/agent-teams.mjs +1 -1
  3. package/dist/chunks/agent.mjs +1 -1
  4. package/dist/chunks/api-providers.mjs +1 -1
  5. package/dist/chunks/api.mjs +3 -3
  6. package/dist/chunks/auto-bootstrap.mjs +1 -1
  7. package/dist/chunks/auto-updater.mjs +1 -1
  8. package/dist/{shared/ccjk.Br91zBIG.mjs → chunks/banner.mjs} +52 -3
  9. package/dist/chunks/boost.mjs +2 -2
  10. package/dist/chunks/ccjk-agents.mjs +1 -1
  11. package/dist/chunks/ccjk-all.mjs +1 -1
  12. package/dist/chunks/ccjk-config.mjs +1 -1
  13. package/dist/chunks/ccjk-hooks.mjs +1 -1
  14. package/dist/chunks/ccjk-mcp.mjs +2 -2
  15. package/dist/chunks/ccjk-setup.mjs +1 -1
  16. package/dist/chunks/ccjk-skills.mjs +1 -1
  17. package/dist/chunks/ccr.mjs +11 -10
  18. package/dist/chunks/ccu.mjs +1 -1
  19. package/dist/chunks/check-updates.mjs +4 -3
  20. package/dist/chunks/claude-code-config-manager.mjs +8 -7
  21. package/dist/chunks/claude-code-incremental-manager.mjs +3 -2
  22. package/dist/chunks/claude-config.mjs +3 -3
  23. package/dist/chunks/claude-wrapper.mjs +2 -2
  24. package/dist/chunks/codex-config-switch.mjs +3 -2
  25. package/dist/chunks/codex-provider-manager.mjs +3 -2
  26. package/dist/chunks/codex-uninstaller.mjs +2 -2
  27. package/dist/chunks/codex.mjs +5 -5
  28. package/dist/chunks/commands.mjs +88 -391
  29. package/dist/chunks/commands2.mjs +391 -88
  30. package/dist/chunks/completion.mjs +1 -1
  31. package/dist/chunks/config-consolidator.mjs +2 -2
  32. package/dist/chunks/config-switch.mjs +4 -3
  33. package/dist/chunks/config.mjs +6 -98
  34. package/dist/chunks/config2.mjs +411 -400
  35. package/dist/chunks/config3.mjs +401 -410
  36. package/dist/chunks/constants.mjs +1 -1
  37. package/dist/chunks/context.mjs +283 -1
  38. package/dist/chunks/dashboard.mjs +365 -0
  39. package/dist/chunks/doctor.mjs +4 -4
  40. package/dist/chunks/features.mjs +12 -11
  41. package/dist/chunks/fs-operations.mjs +1 -1
  42. package/dist/chunks/health-alerts.mjs +304 -0
  43. package/dist/chunks/health-check.mjs +532 -0
  44. package/dist/chunks/index.mjs +10 -177
  45. package/dist/chunks/index2.mjs +168 -1162
  46. package/dist/chunks/index3.mjs +1076 -910
  47. package/dist/chunks/index4.mjs +947 -137
  48. package/dist/chunks/index5.mjs +167 -635
  49. package/dist/chunks/index6.mjs +663 -0
  50. package/dist/chunks/init.mjs +19 -19
  51. package/dist/chunks/installer.mjs +649 -147
  52. package/dist/chunks/installer2.mjs +147 -649
  53. package/dist/chunks/interview.mjs +2 -2
  54. package/dist/chunks/marketplace.mjs +1 -1
  55. package/dist/chunks/mcp.mjs +5 -4
  56. package/dist/chunks/menu.mjs +22 -9
  57. package/dist/chunks/metrics-display.mjs +152 -0
  58. package/dist/chunks/migrator.mjs +1 -1
  59. package/dist/chunks/monitor.mjs +2 -2
  60. package/dist/chunks/notification.mjs +1 -1
  61. package/dist/chunks/onboarding.mjs +2 -2
  62. package/dist/chunks/package.mjs +1 -1
  63. package/dist/chunks/permission-manager.mjs +2 -2
  64. package/dist/chunks/permissions.mjs +1 -1
  65. package/dist/chunks/persistence-manager.mjs +781 -0
  66. package/dist/chunks/persistence.mjs +667 -0
  67. package/dist/chunks/platform.mjs +1 -1
  68. package/dist/chunks/plugin.mjs +1 -1
  69. package/dist/chunks/prompts.mjs +1 -1
  70. package/dist/chunks/providers.mjs +1 -1
  71. package/dist/chunks/quick-actions.mjs +321 -0
  72. package/dist/chunks/quick-provider.mjs +2 -0
  73. package/dist/chunks/quick-setup.mjs +9 -8
  74. package/dist/chunks/silent-updater.mjs +1 -1
  75. package/dist/chunks/simple-config.mjs +3 -8
  76. package/dist/chunks/skill.mjs +1 -1
  77. package/dist/chunks/skills-sync.mjs +1 -1
  78. package/dist/chunks/skills.mjs +1 -1
  79. package/dist/chunks/slash-commands.mjs +208 -0
  80. package/dist/chunks/smart-defaults.mjs +1 -1
  81. package/dist/chunks/startup.mjs +1 -1
  82. package/dist/chunks/stats.mjs +1 -1
  83. package/dist/chunks/status.mjs +31 -2
  84. package/dist/chunks/team.mjs +1 -1
  85. package/dist/chunks/thinking.mjs +2 -2
  86. package/dist/chunks/uninstall.mjs +5 -5
  87. package/dist/chunks/update.mjs +8 -7
  88. package/dist/chunks/upgrade-manager.mjs +2 -2
  89. package/dist/chunks/version-checker.mjs +3 -3
  90. package/dist/chunks/vim.mjs +1 -1
  91. package/dist/chunks/zero-config.mjs +359 -0
  92. package/dist/cli.mjs +212 -21
  93. package/dist/i18n/locales/en/cli.json +14 -1
  94. package/dist/i18n/locales/en/common.json +27 -0
  95. package/dist/i18n/locales/en/configuration.json +33 -0
  96. package/dist/i18n/locales/en/context.json +54 -1
  97. package/dist/i18n/locales/en/dashboard.json +78 -0
  98. package/dist/i18n/locales/en/persistence.json +127 -0
  99. package/dist/i18n/locales/en/quick-actions.json +78 -0
  100. package/dist/i18n/locales/zh-CN/cli.json +14 -1
  101. package/dist/i18n/locales/zh-CN/common.json +27 -0
  102. package/dist/i18n/locales/zh-CN/configuration.json +33 -0
  103. package/dist/i18n/locales/zh-CN/context.json +54 -1
  104. package/dist/i18n/locales/zh-CN/dashboard.json +78 -0
  105. package/dist/i18n/locales/zh-CN/persistence.json +127 -0
  106. package/dist/i18n/locales/zh-CN/quick-actions.json +78 -0
  107. package/dist/index.mjs +3 -2
  108. package/dist/shared/{ccjk.DE91nClQ.mjs → ccjk.BKoi8-Hy.mjs} +1 -1
  109. package/dist/shared/ccjk.BiCrMV5O.mjs +94 -0
  110. package/dist/shared/{ccjk.Dpw86UX0.mjs → ccjk.CxtuJxaS.mjs} +1 -1
  111. package/dist/shared/{ccjk.ClzTOz9n.mjs → ccjk.DB2UYcq0.mjs} +5 -5
  112. package/dist/shared/{ccjk.CmsW23FN.mjs → ccjk.DVBW2wxp.mjs} +4 -3
  113. package/dist/shared/{ccjk.Bndhan7G.mjs → ccjk.DfwJOEok.mjs} +1 -1
  114. package/dist/shared/{ccjk.DvIrK0wz.mjs → ccjk.DrMygfCF.mjs} +1 -1
  115. package/package.json +19 -19
@@ -4,10 +4,13 @@ import process__default from 'node:process';
4
4
  import ansis from 'ansis';
5
5
  import { join } from 'pathe';
6
6
  import { s as scanProject } from '../shared/ccjk.DKojSRzw.mjs';
7
- import { r as runHealthCheck } from '../shared/ccjk.Bndhan7G.mjs';
7
+ import { getContextPersistence } from './persistence.mjs';
8
+ import { MetricsDisplay } from './metrics-display.mjs';
9
+ import { r as runHealthCheck } from '../shared/ccjk.DfwJOEok.mjs';
8
10
  import 'node:child_process';
11
+ import 'better-sqlite3';
9
12
  import './constants.mjs';
10
- import './index.mjs';
13
+ import './index2.mjs';
11
14
  import 'node:url';
12
15
  import 'i18next';
13
16
  import 'i18next-fs-backend';
@@ -185,6 +188,28 @@ function renderClaudeCodeSection(defaults) {
185
188
  }
186
189
  return lines;
187
190
  }
191
+ function renderCompressionMetricsSection(projectHash) {
192
+ const lines = [];
193
+ lines.push(heading("Compression Metrics"));
194
+ try {
195
+ const persistence = getContextPersistence();
196
+ const stats = persistence.getCompressionMetricsStats(projectHash);
197
+ if (stats.totalCompressions === 0) {
198
+ lines.push(` ${ansis.gray("No compression data available")}`);
199
+ return lines;
200
+ }
201
+ lines.push(` ${label("Total Saved:".padEnd(14))} ${ansis.green(MetricsDisplay.formatTokenCount(stats.totalTokensSaved))} tokens`);
202
+ lines.push(` ${label("Avg Reduction:".padEnd(14))} ${ansis.yellow(MetricsDisplay.formatRatio(stats.averageCompressionRatio))}`);
203
+ lines.push(` ${label("Cost Savings:".padEnd(14))} ${ansis.green.bold(MetricsDisplay.formatCost(stats.estimatedCostSavings))}`);
204
+ if (stats.sessionStats && stats.sessionStats.compressions > 0) {
205
+ lines.push(` ${label("Session (24h):".padEnd(14))} ${ansis.white(stats.sessionStats.compressions)} compressions, ${ansis.green(MetricsDisplay.formatCost(stats.sessionStats.costSavings))} saved`);
206
+ }
207
+ return lines;
208
+ } catch {
209
+ lines.push(` ${ansis.gray("Metrics unavailable")}`);
210
+ return lines;
211
+ }
212
+ }
188
213
  function renderHealthSection(report, compact) {
189
214
  const lines = [];
190
215
  lines.push(heading("Brain Dashboard"));
@@ -242,6 +267,10 @@ async function statusCommand(options = {}) {
242
267
  sections.push(renderClaudeCodeSection(null));
243
268
  }
244
269
  sections.push(renderHealthSection(health, options.compact || false));
270
+ try {
271
+ sections.push(renderCompressionMetricsSection());
272
+ } catch {
273
+ }
245
274
  console.log();
246
275
  for (let i = 0; i < sections.length; i++) {
247
276
  console.log(sections[i].join("\n"));
@@ -2,7 +2,7 @@ import { existsSync, mkdirSync, readFileSync } from 'node:fs';
2
2
  import ansis from 'ansis';
3
3
  import inquirer from 'inquirer';
4
4
  import { join } from 'pathe';
5
- import { i18n } from './index.mjs';
5
+ import { i18n } from './index2.mjs';
6
6
  import { writeFileAtomic } from './fs-operations.mjs';
7
7
  import 'node:process';
8
8
  import 'node:url';
@@ -1,9 +1,9 @@
1
1
  import ansis from 'ansis';
2
2
  import inquirer from 'inquirer';
3
3
  import { SETTINGS_FILE } from './constants.mjs';
4
- import { i18n } from './index.mjs';
4
+ import { i18n } from './index2.mjs';
5
5
  import { readJsonConfig, writeJsonConfig } from './json-config.mjs';
6
- import { h as handleExitPromptError, a as handleGeneralError } from '../shared/ccjk.DvIrK0wz.mjs';
6
+ import { h as handleExitPromptError, a as handleGeneralError } from '../shared/ccjk.DrMygfCF.mjs';
7
7
  import 'node:os';
8
8
  import 'pathe';
9
9
  import 'node:fs';
@@ -1,10 +1,10 @@
1
1
  import ansis from 'ansis';
2
2
  import inquirer from 'inquirer';
3
3
  import { ZCF_CONFIG_FILE, DEFAULT_CODE_TOOL_TYPE, isCodeToolType } from './constants.mjs';
4
- import { i18n, ensureI18nInitialized } from './index.mjs';
4
+ import { i18n, ensureI18nInitialized } from './index2.mjs';
5
5
  import { readZcfConfig } from './ccjk-config.mjs';
6
- import { r as resolveCodeType } from '../shared/ccjk.Dpw86UX0.mjs';
7
- import { h as handleExitPromptError, a as handleGeneralError } from '../shared/ccjk.DvIrK0wz.mjs';
6
+ import { r as resolveCodeType } from '../shared/ccjk.CxtuJxaS.mjs';
7
+ import { h as handleExitPromptError, a as handleGeneralError } from '../shared/ccjk.DrMygfCF.mjs';
8
8
  import { a as addNumbersToChoices } from '../shared/ccjk.BFQ7yr5S.mjs';
9
9
  import { p as promptBoolean } from '../shared/ccjk.DHbrGcgg.mjs';
10
10
  import { promises } from 'node:fs';
@@ -21,12 +21,12 @@ import 'smol-toml';
21
21
  import './fs-operations.mjs';
22
22
  import 'node:crypto';
23
23
  import 'node:fs/promises';
24
+ import 'dayjs';
24
25
  import './smart-defaults.mjs';
25
26
  import 'node:child_process';
26
27
  import './platform.mjs';
27
28
  import '../shared/ccjk.DKojSRzw.mjs';
28
29
  import 'inquirer-toggle';
29
- import 'dayjs';
30
30
  import 'trash';
31
31
 
32
32
  async function pathExists(p) {
@@ -324,7 +324,7 @@ class ZcfUninstaller {
324
324
  result.removed.push(".claude.json (includes MCP configuration)");
325
325
  }
326
326
  try {
327
- const { uninstallCodeTool } = await import('./installer2.mjs');
327
+ const { uninstallCodeTool } = await import('./installer.mjs');
328
328
  const success = await uninstallCodeTool("claude-code");
329
329
  if (success) {
330
330
  result.removed.push("@anthropic-ai/claude-code");
@@ -3,15 +3,15 @@ import ansis from 'ansis';
3
3
  import inquirer from 'inquirer';
4
4
  import { version } from './package.mjs';
5
5
  import { SETTINGS_FILE, DEFAULT_CODE_TOOL_TYPE, resolveCodeToolType as resolveCodeToolType$1, isCodeToolType } from './constants.mjs';
6
- import { a as runCodexUpdate, M as MCP_SERVICE_CONFIGS, g as getMcpServices } from './codex.mjs';
7
- import { i18n } from './index.mjs';
8
- import { a as displayBanner } from '../shared/ccjk.Br91zBIG.mjs';
6
+ import { r as runCodexUpdate, M as MCP_SERVICE_CONFIGS, g as getMcpServices } from './codex.mjs';
7
+ import { i18n } from './index2.mjs';
8
+ import { displayBanner } from './banner.mjs';
9
9
  import { readZcfConfig, updateZcfConfig } from './ccjk-config.mjs';
10
10
  import { r as readMcpConfig } from './claude-config.mjs';
11
- import { a as copyConfigFiles } from './config.mjs';
12
- import { n as needsMigration, a as migrateSettingsForTokenRetrieval, d as displayMigrationResult, p as promptMigration, u as updatePromptOnly, s as selectAndInstallWorkflows } from '../shared/ccjk.CmsW23FN.mjs';
13
- import { h as handleExitPromptError, a as handleGeneralError } from '../shared/ccjk.DvIrK0wz.mjs';
14
- import { b as installMcpServices } from '../shared/ccjk.ClzTOz9n.mjs';
11
+ import { c as copyConfigFiles } from './config.mjs';
12
+ import { n as needsMigration, m as migrateSettingsForTokenRetrieval, d as displayMigrationResult, p as promptMigration, u as updatePromptOnly, s as selectAndInstallWorkflows } from '../shared/ccjk.DVBW2wxp.mjs';
13
+ import { h as handleExitPromptError, a as handleGeneralError } from '../shared/ccjk.DrMygfCF.mjs';
14
+ import { i as installMcpServices } from '../shared/ccjk.DB2UYcq0.mjs';
15
15
  import { resolveAiOutputLanguage } from './prompts.mjs';
16
16
  import { checkClaudeCodeVersionAndPrompt } from './version-checker.mjs';
17
17
  import 'node:os';
@@ -34,6 +34,7 @@ import 'inquirer-toggle';
34
34
  import 'node:child_process';
35
35
  import 'i18next';
36
36
  import 'i18next-fs-backend';
37
+ import '../shared/ccjk.BiCrMV5O.mjs';
37
38
  import 'node:path';
38
39
  import 'node:util';
39
40
 
@@ -4,8 +4,8 @@ import ora from 'ora';
4
4
  import * as semver from 'semver';
5
5
  import { exec } from 'tinyexec';
6
6
  import { version } from './package.mjs';
7
- import { S as STATUS } from '../shared/ccjk.Br91zBIG.mjs';
8
- import './index.mjs';
7
+ import { STATUS } from './banner.mjs';
8
+ import './index2.mjs';
9
9
  import 'node:fs';
10
10
  import 'node:url';
11
11
  import 'i18next';
@@ -4,7 +4,7 @@ import * as path from 'node:path';
4
4
  import process__default from 'node:process';
5
5
  import { promisify } from 'node:util';
6
6
  import * as semver from 'semver';
7
- import { d as getPlatform, f as findCommandPath, e as getHomebrewCommandPaths } from './platform.mjs';
7
+ import { g as getPlatform, f as findCommandPath, a as getHomebrewCommandPaths } from './platform.mjs';
8
8
  import 'node:os';
9
9
  import 'pathe';
10
10
  import 'tinyexec';
@@ -650,7 +650,7 @@ async function performNpmRemovalAndActivateHomebrew(_npmInstallation, homebrewIn
650
650
  if (homebrewInstallation && !homebrewInstallation.isActive) {
651
651
  console.log("");
652
652
  console.log(ansis.green(`\u{1F517} ${i18n.t("installation:activatingHomebrew")}`));
653
- const { createHomebrewSymlink } = await import('./installer2.mjs');
653
+ const { createHomebrewSymlink } = await import('./installer.mjs');
654
654
  const symlinkResult = await createHomebrewSymlink("claude", homebrewInstallation.path);
655
655
  if (symlinkResult.success) {
656
656
  console.log(ansis.green(`\u2714 ${i18n.t("installation:symlinkCreated", { path: symlinkResult.symlinkPath || "/usr/local/bin/claude" })}`));
@@ -674,7 +674,7 @@ async function performNpmRemovalAndActivateHomebrew(_npmInstallation, homebrewIn
674
674
  }
675
675
  }
676
676
  async function handleDuplicateInstallations(skipPrompt = false) {
677
- const { ensureI18nInitialized, format, i18n } = await import('./index.mjs');
677
+ const { ensureI18nInitialized, format, i18n } = await import('./index2.mjs');
678
678
  const ansis = (await import('ansis')).default;
679
679
  ensureI18nInitialized();
680
680
  const duplicateInfo = await checkDuplicateInstallations();
@@ -1,6 +1,6 @@
1
1
  import ansis from 'ansis';
2
2
  import inquirer from 'inquirer';
3
- import { ensureI18nInitialized, i18n } from './index.mjs';
3
+ import { ensureI18nInitialized, i18n } from './index2.mjs';
4
4
  import { existsSync, readFileSync } from 'node:fs';
5
5
  import { readFile, writeFile, mkdir } from 'node:fs/promises';
6
6
  import { homedir } from 'node:os';
@@ -0,0 +1,359 @@
1
+ import { existsSync, readFileSync } from 'node:fs';
2
+ import ansis from 'ansis';
3
+ import inquirer from 'inquirer';
4
+ import { SETTINGS_FILE, CLAUDE_DIR } from './constants.mjs';
5
+ import { i18n } from './index2.mjs';
6
+ import { ensureDir, writeFileAtomic } from './fs-operations.mjs';
7
+ import { m as mergeAndCleanPermissions } from '../shared/ccjk.BiCrMV5O.mjs';
8
+ import { a as addNumbersToChoices } from '../shared/ccjk.BFQ7yr5S.mjs';
9
+ import 'node:os';
10
+ import 'pathe';
11
+ import 'node:process';
12
+ import 'node:url';
13
+ import 'i18next';
14
+ import 'i18next-fs-backend';
15
+ import 'node:crypto';
16
+ import 'node:fs/promises';
17
+
18
+ const MAX_PRESET = {
19
+ id: "max",
20
+ name: "Maximum Permissions",
21
+ description: "All common commands, file operations, and MCP servers",
22
+ permissions: [
23
+ // Package managers
24
+ "Bash(pnpm *)",
25
+ "Bash(npm *)",
26
+ "Bash(npx *)",
27
+ "Bash(NODE_ENV=* pnpm *)",
28
+ "Bash(yarn *)",
29
+ "Bash(bun *)",
30
+ "Bash(deno *)",
31
+ // Version control
32
+ "Bash(git *)",
33
+ // Build tools
34
+ "Bash(make *)",
35
+ "Bash(cmake *)",
36
+ "Bash(cargo *)",
37
+ "Bash(go *)",
38
+ "Bash(rustc *)",
39
+ // Container tools
40
+ "Bash(docker *)",
41
+ "Bash(docker-compose *)",
42
+ "Bash(podman *)",
43
+ // Programming languages
44
+ "Bash(python *)",
45
+ "Bash(python3 *)",
46
+ "Bash(node *)",
47
+ "Bash(ruby *)",
48
+ "Bash(php *)",
49
+ "Bash(java *)",
50
+ "Bash(javac *)",
51
+ // Shell utilities
52
+ "Bash(which *)",
53
+ "Bash(cat *)",
54
+ "Bash(ls *)",
55
+ "Bash(echo *)",
56
+ "Bash(grep *)",
57
+ "Bash(find *)",
58
+ "Bash(head *)",
59
+ "Bash(tail *)",
60
+ "Bash(wc *)",
61
+ "Bash(sort *)",
62
+ "Bash(uniq *)",
63
+ "Bash(cut *)",
64
+ "Bash(sed *)",
65
+ "Bash(awk *)",
66
+ "Bash(tr *)",
67
+ "Bash(xargs *)",
68
+ // File operations
69
+ "Bash(mkdir *)",
70
+ "Bash(touch *)",
71
+ "Bash(cp *)",
72
+ "Bash(mv *)",
73
+ "Bash(chmod *)",
74
+ "Bash(chown *)",
75
+ "Bash(ln *)",
76
+ // Network tools
77
+ "Bash(curl *)",
78
+ "Bash(wget *)",
79
+ "Bash(ping *)",
80
+ "Bash(netstat *)",
81
+ "Bash(ss *)",
82
+ // System info
83
+ "Bash(ps *)",
84
+ "Bash(top *)",
85
+ "Bash(htop *)",
86
+ "Bash(df *)",
87
+ "Bash(du *)",
88
+ "Bash(free *)",
89
+ "Bash(uname *)",
90
+ // Text editors
91
+ "Bash(vim *)",
92
+ "Bash(nano *)",
93
+ "Bash(emacs *)",
94
+ "Bash(code *)",
95
+ // Compression
96
+ "Bash(tar *)",
97
+ "Bash(gzip *)",
98
+ "Bash(gunzip *)",
99
+ "Bash(zip *)",
100
+ "Bash(unzip *)",
101
+ // Package managers (system)
102
+ "Bash(brew *)",
103
+ "Bash(apt *)",
104
+ "Bash(apt-get *)",
105
+ "Bash(yum *)",
106
+ "Bash(dnf *)",
107
+ "Bash(pacman *)",
108
+ // File operations (Claude Code tools)
109
+ "Read(*)",
110
+ "Edit(*)",
111
+ "Write(*)",
112
+ "NotebookEdit(*)",
113
+ // Web access
114
+ "WebFetch(*)",
115
+ // MCP servers (wildcard for all)
116
+ "MCP(*)"
117
+ ],
118
+ env: {
119
+ ANTHROPIC_MODEL: "",
120
+ ANTHROPIC_DEFAULT_HAIKU_MODEL: "",
121
+ ANTHROPIC_DEFAULT_SONNET_MODEL: "",
122
+ ANTHROPIC_DEFAULT_OPUS_MODEL: ""
123
+ }
124
+ };
125
+ const DEV_PRESET = {
126
+ id: "dev",
127
+ name: "Developer Preset",
128
+ description: "Build tools, git, package managers, and file operations",
129
+ permissions: [
130
+ // Package managers
131
+ "Bash(pnpm *)",
132
+ "Bash(npm *)",
133
+ "Bash(npx *)",
134
+ "Bash(NODE_ENV=* pnpm *)",
135
+ "Bash(yarn *)",
136
+ "Bash(bun *)",
137
+ // Version control
138
+ "Bash(git *)",
139
+ // Build tools
140
+ "Bash(make *)",
141
+ "Bash(cargo *)",
142
+ "Bash(go *)",
143
+ // Programming languages
144
+ "Bash(python *)",
145
+ "Bash(python3 *)",
146
+ "Bash(node *)",
147
+ // Shell utilities
148
+ "Bash(which *)",
149
+ "Bash(cat *)",
150
+ "Bash(ls *)",
151
+ "Bash(echo *)",
152
+ "Bash(grep *)",
153
+ "Bash(find *)",
154
+ "Bash(head *)",
155
+ "Bash(tail *)",
156
+ "Bash(wc *)",
157
+ "Bash(sort *)",
158
+ // File operations
159
+ "Bash(mkdir *)",
160
+ "Bash(touch *)",
161
+ "Bash(cp *)",
162
+ "Bash(mv *)",
163
+ "Bash(chmod *)",
164
+ // File operations (Claude Code tools)
165
+ "Read(*)",
166
+ "Edit(*)",
167
+ "Write(*)",
168
+ "NotebookEdit(*)",
169
+ // Web access for docs
170
+ "WebFetch(*)"
171
+ ],
172
+ env: {
173
+ ANTHROPIC_MODEL: ""
174
+ }
175
+ };
176
+ const SAFE_PRESET = {
177
+ id: "safe",
178
+ name: "Safe Preset",
179
+ description: "Read-only commands, no file modifications",
180
+ permissions: [
181
+ // Read-only shell utilities
182
+ "Bash(which *)",
183
+ "Bash(cat *)",
184
+ "Bash(ls *)",
185
+ "Bash(echo *)",
186
+ "Bash(grep *)",
187
+ "Bash(find *)",
188
+ "Bash(head *)",
189
+ "Bash(tail *)",
190
+ "Bash(wc *)",
191
+ "Bash(sort *)",
192
+ "Bash(uniq *)",
193
+ "Bash(cut *)",
194
+ // System info (read-only)
195
+ "Bash(ps *)",
196
+ "Bash(df *)",
197
+ "Bash(du *)",
198
+ "Bash(uname *)",
199
+ // Git read operations
200
+ "Bash(git status *)",
201
+ "Bash(git log *)",
202
+ "Bash(git diff *)",
203
+ "Bash(git show *)",
204
+ "Bash(git branch *)",
205
+ // File operations (read-only)
206
+ "Read(*)",
207
+ // Web access
208
+ "WebFetch(*)"
209
+ ]
210
+ };
211
+ const PRESETS = [MAX_PRESET, DEV_PRESET, SAFE_PRESET];
212
+ function loadCurrentSettings() {
213
+ if (!existsSync(SETTINGS_FILE)) {
214
+ return {};
215
+ }
216
+ try {
217
+ const content = readFileSync(SETTINGS_FILE, "utf-8");
218
+ return JSON.parse(content);
219
+ } catch {
220
+ return {};
221
+ }
222
+ }
223
+ function saveSettings(settings) {
224
+ ensureDir(CLAUDE_DIR);
225
+ writeFileAtomic(SETTINGS_FILE, JSON.stringify(settings, null, 2));
226
+ }
227
+ function backupSettings() {
228
+ if (!existsSync(SETTINGS_FILE)) {
229
+ return null;
230
+ }
231
+ const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-").slice(0, -5);
232
+ const backupDir = `${CLAUDE_DIR}/backup`;
233
+ ensureDir(backupDir);
234
+ const backupPath = `${backupDir}/settings-${timestamp}.json`;
235
+ const content = readFileSync(SETTINGS_FILE, "utf-8");
236
+ writeFileAtomic(backupPath, content);
237
+ return backupPath;
238
+ }
239
+ function applyPreset(preset, currentSettings) {
240
+ const newSettings = { ...currentSettings };
241
+ if (!newSettings.permissions) {
242
+ newSettings.permissions = { allow: [] };
243
+ }
244
+ newSettings.permissions.allow = mergeAndCleanPermissions(
245
+ preset.permissions,
246
+ newSettings.permissions.allow || []
247
+ );
248
+ if (preset.env) {
249
+ newSettings.env = {
250
+ ...newSettings.env,
251
+ ...preset.env
252
+ };
253
+ }
254
+ return newSettings;
255
+ }
256
+ function showPresetDiff(preset, currentSettings) {
257
+ const isZh = i18n.language === "zh-CN";
258
+ const currentPermissions = new Set(currentSettings.permissions?.allow || []);
259
+ const newPermissions = preset.permissions.filter((p) => !currentPermissions.has(p));
260
+ console.log("");
261
+ console.log(ansis.bold.cyan(isZh ? "\u{1F4CB} \u9884\u8BBE\u8BE6\u60C5" : "\u{1F4CB} Preset Details"));
262
+ console.log(ansis.dim("\u2500".repeat(60)));
263
+ console.log(`${ansis.green("Name:")} ${preset.name}`);
264
+ console.log(`${ansis.green("Description:")} ${preset.description}`);
265
+ console.log("");
266
+ if (newPermissions.length > 0) {
267
+ console.log(ansis.bold.yellow(isZh ? "\u2728 \u5C06\u6DFB\u52A0\u7684\u6743\u9650:" : "\u2728 Permissions to be added:"));
268
+ console.log(ansis.dim(` ${isZh ? "\u603B\u8BA1" : "Total"}: ${newPermissions.length} ${isZh ? "\u9879" : "items"}`));
269
+ const bashPerms = newPermissions.filter((p) => p.startsWith("Bash("));
270
+ const filePerms = newPermissions.filter((p) => ["Read", "Edit", "Write", "NotebookEdit"].some((t) => p.startsWith(t)));
271
+ const otherPerms = newPermissions.filter((p) => !bashPerms.includes(p) && !filePerms.includes(p));
272
+ if (bashPerms.length > 0) {
273
+ console.log(` ${ansis.cyan("Bash:")} ${bashPerms.length} ${isZh ? "\u4E2A\u547D\u4EE4" : "commands"}`);
274
+ }
275
+ if (filePerms.length > 0) {
276
+ console.log(` ${ansis.cyan("File:")} ${filePerms.length} ${isZh ? "\u4E2A\u64CD\u4F5C" : "operations"}`);
277
+ }
278
+ if (otherPerms.length > 0) {
279
+ console.log(` ${ansis.cyan("Other:")} ${otherPerms.length} ${isZh ? "\u9879" : "items"}`);
280
+ }
281
+ } else {
282
+ console.log(ansis.yellow(isZh ? "\u2713 \u6240\u6709\u6743\u9650\u5DF2\u5B58\u5728" : "\u2713 All permissions already exist"));
283
+ }
284
+ console.log(ansis.dim("\u2500".repeat(60)));
285
+ console.log("");
286
+ }
287
+ async function zeroConfig(options = {}) {
288
+ const isZh = i18n.language === "zh-CN";
289
+ if (options.list) {
290
+ console.log("");
291
+ console.log(ansis.bold.cyan(isZh ? "\u{1F4E6} \u53EF\u7528\u7684\u6743\u9650\u9884\u8BBE" : "\u{1F4E6} Available Permission Presets"));
292
+ console.log(ansis.dim("\u2500".repeat(60)));
293
+ for (const preset of PRESETS) {
294
+ console.log(` ${ansis.green(preset.id.padEnd(8))} - ${preset.name}`);
295
+ console.log(` ${ansis.dim(" ".repeat(10))}${preset.description}`);
296
+ console.log(` ${ansis.dim(" ".repeat(10))}${preset.permissions.length} ${isZh ? "\u9879\u6743\u9650" : "permissions"}`);
297
+ console.log("");
298
+ }
299
+ console.log(ansis.dim("\u2500".repeat(60)));
300
+ console.log(ansis.gray(isZh ? "\u4F7F\u7528: npx ccjk zc --preset=<id>" : "Usage: npx ccjk zc --preset=<id>"));
301
+ console.log("");
302
+ return;
303
+ }
304
+ let selectedPreset;
305
+ if (options.preset) {
306
+ selectedPreset = PRESETS.find((p) => p.id === options.preset);
307
+ if (!selectedPreset) {
308
+ console.error(ansis.red(isZh ? `\u9519\u8BEF: \u672A\u627E\u5230\u9884\u8BBE "${options.preset}"` : `Error: Preset "${options.preset}" not found`));
309
+ console.log(ansis.gray(isZh ? "\u4F7F\u7528 --list \u67E5\u770B\u53EF\u7528\u9884\u8BBE" : "Use --list to see available presets"));
310
+ return;
311
+ }
312
+ } else {
313
+ const { presetId } = await inquirer.prompt({
314
+ type: "list",
315
+ name: "presetId",
316
+ message: isZh ? "\u9009\u62E9\u6743\u9650\u9884\u8BBE:" : "Select permission preset:",
317
+ choices: addNumbersToChoices(
318
+ PRESETS.map((p) => ({
319
+ name: `${p.name} - ${ansis.gray(p.description)}`,
320
+ value: p.id,
321
+ short: p.name
322
+ }))
323
+ )
324
+ });
325
+ selectedPreset = PRESETS.find((p) => p.id === presetId);
326
+ if (!selectedPreset) {
327
+ console.log(ansis.yellow(i18n.t("common:cancelled")));
328
+ return;
329
+ }
330
+ }
331
+ const currentSettings = loadCurrentSettings();
332
+ showPresetDiff(selectedPreset, currentSettings);
333
+ if (!options.preset) {
334
+ const { confirm } = await inquirer.prompt({
335
+ type: "confirm",
336
+ name: "confirm",
337
+ message: isZh ? "\u786E\u8BA4\u5E94\u7528\u6B64\u9884\u8BBE?" : "Confirm applying this preset?",
338
+ default: true
339
+ });
340
+ if (!confirm) {
341
+ console.log(ansis.yellow(i18n.t("common:cancelled")));
342
+ return;
343
+ }
344
+ }
345
+ if (!options.skipBackup) {
346
+ const backupPath = backupSettings();
347
+ if (backupPath) {
348
+ console.log(ansis.gray(`\u2714 ${isZh ? "\u5DF2\u5907\u4EFD\u5230" : "Backed up to"}: ${backupPath}`));
349
+ }
350
+ }
351
+ const newSettings = applyPreset(selectedPreset, currentSettings);
352
+ saveSettings(newSettings);
353
+ console.log("");
354
+ console.log(ansis.green(`\u2705 ${isZh ? "\u6743\u9650\u9884\u8BBE\u5DF2\u5E94\u7528" : "Permission preset applied"}: ${selectedPreset.name}`));
355
+ console.log(ansis.gray(` ${isZh ? "\u914D\u7F6E\u6587\u4EF6" : "Config file"}: ${SETTINGS_FILE}`));
356
+ console.log("");
357
+ }
358
+
359
+ export { zeroConfig };