ccjk 2.1.0 → 2.2.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.
package/README.md CHANGED
@@ -67,17 +67,31 @@
67
67
 
68
68
  <br/>
69
69
 
70
- <!-- One-Click Launch -->
70
+ <!-- One-Click Installation -->
71
+ ### ⚡ Quick Install
72
+
73
+ **🌍 Global Users**
71
74
  ```bash
72
- npx ccjk
75
+ curl -fsSL https://raw.githubusercontent.com/miounet11/ccjk/main/install.sh | bash
73
76
  ```
74
77
 
75
- <sup>⚡ Zero Config · Instant Deploy · 30 Seconds to Production</sup>
78
+ **🇨🇳 中国用户**
79
+ ```bash
80
+ curl -fsSL https://ghproxy.com/https://raw.githubusercontent.com/miounet11/ccjk/main/install.sh | bash
81
+ ```
82
+
83
+ **📦 Already have Node.js?**
84
+ ```bash
85
+ npx ccjk # Run directly
86
+ npm i -g ccjk # Or install globally
87
+ ```
88
+
89
+ <sub>✨ Auto-installs Node.js, npm, git if needed · Supports Ubuntu/Debian/CentOS/Fedora/Arch/Alpine/macOS</sub>
76
90
 
77
91
  <br/>
78
92
  <br/>
79
93
 
80
- [🚀 Quick Start](#-quick-start) · [🧠 Architecture](#-core-architecture) · [📊 Benchmarks](#-performance-benchmarks) · [🌟 Acknowledgments](#-ecosystem-acknowledgments)
94
+ [🧠 Architecture](#-core-architecture) · [📊 Benchmarks](#-performance-benchmarks) · [🌟 Acknowledgments](#-ecosystem-acknowledgments)
81
95
 
82
96
  </div>
83
97
 
@@ -123,7 +137,7 @@ In the realm of AI-assisted development, **Context Engineering** and **Cognitive
123
137
 
124
138
  ```
125
139
  ┌─────────────────────────────────────────────────────────────────┐
126
- │ CCJK Cognitive Enhancement Engine v2.0
140
+ │ CCJK Cognitive Enhancement Engine v2.2
127
141
  ├─────────────────────────────────────────────────────────────────┤
128
142
  │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
129
143
  │ │ 🧠 Skill │ │ 🤖 Agent │ │ 🔌 Integr. │ │
@@ -318,15 +332,53 @@ Doc Generation █████████████████████
318
332
 
319
333
  ## 🚀 Quick Start
320
334
 
321
- ### Requirements
335
+ ### ⚡ One-Click Installation (Recommended)
322
336
 
323
- | Dependency | Minimum | Recommended |
324
- |:-----------|:-------:|:-----------:|
325
- | Node.js | 18.0+ | 20.x LTS |
326
- | npm/pnpm | 8.0+ | pnpm 9.x |
327
- | Claude Code | 1.0+ | Latest |
337
+ **Auto-installs Node.js, npm, git and CCJK — works on fresh systems!**
328
338
 
329
- ### Installation
339
+ <table>
340
+ <tr>
341
+ <td width="50%">
342
+
343
+ **🌍 Global Users**
344
+
345
+ ```bash
346
+ curl -fsSL https://raw.githubusercontent.com/miounet11/ccjk/main/install.sh | bash
347
+ ```
348
+
349
+ </td>
350
+ <td width="50%">
351
+
352
+ **🇨🇳 中国用户 (China Mirror)**
353
+
354
+ ```bash
355
+ curl -fsSL https://ghproxy.com/https://raw.githubusercontent.com/miounet11/ccjk/main/install.sh | bash
356
+ ```
357
+
358
+ </td>
359
+ </tr>
360
+ </table>
361
+
362
+ <details>
363
+ <summary><b>📋 Supported Platforms</b></summary>
364
+
365
+ | Platform | Package Manager | Status |
366
+ |:---------|:----------------|:------:|
367
+ | **Ubuntu/Debian** | apt | ✅ Full Support |
368
+ | **CentOS/RHEL/Fedora** | dnf/yum | ✅ Full Support |
369
+ | **Arch Linux** | pacman | ✅ Full Support |
370
+ | **Alpine Linux** | apk | ✅ Full Support |
371
+ | **openSUSE** | zypper | ✅ Full Support |
372
+ | **macOS** | Homebrew | ✅ Full Support |
373
+ | **Windows** | Manual | ⚠️ See below |
374
+
375
+ **Windows Users:** Please install [Node.js](https://nodejs.org/) first, then run `npm install -g ccjk`
376
+
377
+ </details>
378
+
379
+ <br/>
380
+
381
+ ### 📦 Manual Installation
330
382
 
331
383
  <table>
332
384
  <tr>
@@ -354,14 +406,23 @@ pnpm add -g ccjk
354
406
  # npmmirror (recommended)
355
407
  npm install -g ccjk --registry https://registry.npmmirror.com
356
408
 
357
- # Taobao mirror
358
- npm install -g ccjk --registry https://registry.npm.taobao.org
409
+ # Or use cnpm
410
+ npm install -g cnpm --registry=https://registry.npmmirror.com
411
+ cnpm install -g ccjk
359
412
  ```
360
413
 
361
414
  </td>
362
415
  </tr>
363
416
  </table>
364
417
 
418
+ ### Requirements
419
+
420
+ | Dependency | Minimum | Recommended |
421
+ |:-----------|:-------:|:-----------:|
422
+ | Node.js | 18.0+ | 20.x LTS |
423
+ | npm/pnpm | 8.0+ | pnpm 9.x |
424
+ | Claude Code | 1.0+ | Latest |
425
+
365
426
  ### 30-Second Quick Experience
366
427
 
367
428
  ```bash
@@ -618,7 +679,7 @@ Want to contribute? [View Guidelines](CONTRIBUTING.md)
618
679
 
619
680
  ## 📜 License
620
681
 
621
- **MIT License** © 2025 [CCJK Contributors](https://github.com/miounet11/ccjk/graphs/contributors)
682
+ **MIT License** © 2025-2026 [CCJK Contributors](https://github.com/miounet11/ccjk/graphs/contributors)
622
683
 
623
684
  <br/>
624
685
 
package/README.zh-CN.md CHANGED
@@ -67,17 +67,31 @@
67
67
 
68
68
  <br/>
69
69
 
70
- <!-- 一键启动 -->
70
+ <!-- 一键安装 -->
71
+ ### ⚡ 快速安装
72
+
73
+ **🇨🇳 中国用户(推荐)**
71
74
  ```bash
72
- npx ccjk
75
+ curl -fsSL https://ghproxy.com/https://raw.githubusercontent.com/miounet11/ccjk/main/install.sh | bash
73
76
  ```
74
77
 
75
- <sup>⚡ 零配置 · 即装即用 · 30秒内完成部署</sup>
78
+ **🌍 国际用户**
79
+ ```bash
80
+ curl -fsSL https://raw.githubusercontent.com/miounet11/ccjk/main/install.sh | bash
81
+ ```
82
+
83
+ **📦 已有 Node.js?**
84
+ ```bash
85
+ npx ccjk # 直接运行
86
+ npm i -g ccjk # 或全局安装
87
+ ```
88
+
89
+ <sub>✨ 自动安装 Node.js、npm、git · 支持 Ubuntu/Debian/CentOS/Fedora/Arch/Alpine/macOS</sub>
76
90
 
77
91
  <br/>
78
92
  <br/>
79
93
 
80
- [🚀 快速入门](#-快速入门) · [🧠 核心架构](#-核心架构) · [📊 性能基准](#-性能基准) · [🌟 生态致谢](#-生态致谢)
94
+ [🧠 核心架构](#-核心架构) · [📊 性能基准](#-性能基准) · [🌟 生态致谢](#-生态致谢)
81
95
 
82
96
  </div>
83
97
 
@@ -318,34 +332,56 @@ Bug 定位 █████████████████████
318
332
 
319
333
  ## 🚀 快速入门
320
334
 
321
- ### 环境要求
335
+ ### ⚡ 一键安装(推荐)
322
336
 
323
- | 依赖 | 最低版本 | 推荐版本 |
324
- |:-----|:--------:|:--------:|
325
- | Node.js | 18.0+ | 20.x LTS |
326
- | npm/pnpm | 8.0+ | pnpm 9.x |
327
- | Claude Code | 1.0+ | 最新版 |
328
-
329
- ### 安装方式
337
+ **自动安装 Node.js、npm、git CCJK 支持全新系统!**
330
338
 
331
339
  <table>
332
340
  <tr>
333
341
  <td width="50%">
334
342
 
335
- **🌍 全球用户**
343
+ **🇨🇳 中国用户(推荐)**
336
344
 
337
345
  ```bash
338
- # 交互式安装 (推荐)
339
- npx ccjk
346
+ curl -fsSL https://ghproxy.com/https://raw.githubusercontent.com/miounet11/ccjk/main/install.sh | bash
347
+ ```
340
348
 
341
- # 全局安装
342
- npm install -g ccjk
349
+ </td>
350
+ <td width="50%">
343
351
 
344
- # pnpm 用户
345
- pnpm add -g ccjk
352
+ **🌍 国际用户**
353
+
354
+ ```bash
355
+ curl -fsSL https://raw.githubusercontent.com/miounet11/ccjk/main/install.sh | bash
346
356
  ```
347
357
 
348
358
  </td>
359
+ </tr>
360
+ </table>
361
+
362
+ <details>
363
+ <summary><b>📋 支持的平台</b></summary>
364
+
365
+ | 平台 | 包管理器 | 状态 |
366
+ |:-----|:---------|:----:|
367
+ | **Ubuntu/Debian** | apt | ✅ 完全支持 |
368
+ | **CentOS/RHEL/Fedora** | dnf/yum | ✅ 完全支持 |
369
+ | **Arch Linux** | pacman | ✅ 完全支持 |
370
+ | **Alpine Linux** | apk | ✅ 完全支持 |
371
+ | **openSUSE** | zypper | ✅ 完全支持 |
372
+ | **macOS** | Homebrew | ✅ 完全支持 |
373
+ | **Windows** | 手动安装 | ⚠️ 见下方说明 |
374
+
375
+ **Windows 用户:** 请先安装 [Node.js](https://nodejs.org/),然后运行 `npm install -g ccjk`
376
+
377
+ </details>
378
+
379
+ <br/>
380
+
381
+ ### 📦 手动安装
382
+
383
+ <table>
384
+ <tr>
349
385
  <td width="50%">
350
386
 
351
387
  **🇨🇳 中国用户 (镜像加速)**
@@ -354,14 +390,39 @@ pnpm add -g ccjk
354
390
  # npmmirror 镜像 (推荐)
355
391
  npm install -g ccjk --registry https://registry.npmmirror.com
356
392
 
357
- # 淘宝镜像
358
- npm install -g ccjk --registry https://registry.npm.taobao.org
393
+ # 或使用 cnpm
394
+ npm install -g cnpm --registry=https://registry.npmmirror.com
395
+ cnpm install -g ccjk
396
+ ```
397
+
398
+ </td>
399
+ <td width="50%">
400
+
401
+ **🌍 全球用户**
402
+
403
+ ```bash
404
+ # 交互式安装 (推荐)
405
+ npx ccjk
406
+
407
+ # 全局安装
408
+ npm install -g ccjk
409
+
410
+ # pnpm 用户
411
+ pnpm add -g ccjk
359
412
  ```
360
413
 
361
414
  </td>
362
415
  </tr>
363
416
  </table>
364
417
 
418
+ ### 环境要求
419
+
420
+ | 依赖 | 最低版本 | 推荐版本 |
421
+ |:-----|:--------:|:--------:|
422
+ | Node.js | 18.0+ | 20.x LTS |
423
+ | npm/pnpm | 8.0+ | pnpm 9.x |
424
+ | Claude Code | 1.0+ | 最新版 |
425
+
365
426
  ### 30 秒快速体验
366
427
 
367
428
  ```bash
@@ -29,12 +29,12 @@ import './platform.mjs';
29
29
  import '../shared/ccjk.DhBeLRzf.mjs';
30
30
  import 'inquirer-toggle';
31
31
  import './prompts.mjs';
32
- import '../shared/ccjk.HAxAfl1Z.mjs';
32
+ import '../shared/ccjk.DwDtZ5cK.mjs';
33
+ import 'node:child_process';
33
34
  import '../shared/ccjk.CUdzQluX.mjs';
34
35
  import './features2.mjs';
35
36
  import './init.mjs';
36
- import '../shared/ccjk.TVnFUDQc.mjs';
37
- import 'node:child_process';
37
+ import '../shared/ccjk.qYAnUMuy.mjs';
38
38
  import 'node:util';
39
39
  import './auto-updater.mjs';
40
40
  import '../shared/ccjk.Cy-RH2qV.mjs';
@@ -32,7 +32,7 @@ import 'inquirer';
32
32
  import './claude-config.mjs';
33
33
  import './prompts.mjs';
34
34
  import './package.mjs';
35
- import '../shared/ccjk.HAxAfl1Z.mjs';
35
+ import '../shared/ccjk.DwDtZ5cK.mjs';
36
36
 
37
37
  class ToolUpdateScheduler {
38
38
  /**
@@ -26,7 +26,8 @@ import '../shared/ccjk.DhBeLRzf.mjs';
26
26
  import 'inquirer-toggle';
27
27
  import './prompts.mjs';
28
28
  import './package.mjs';
29
- import '../shared/ccjk.HAxAfl1Z.mjs';
29
+ import '../shared/ccjk.DwDtZ5cK.mjs';
30
+ import 'node:child_process';
30
31
 
31
32
  class ClaudeCodeConfigManager {
32
33
  static CONFIG_FILE = ZCF_CONFIG_FILE;
@@ -3,7 +3,7 @@ import inquirer from 'inquirer';
3
3
  import { ensureI18nInitialized, i18n } from './index2.mjs';
4
4
  import { ClaudeCodeConfigManager } from './claude-code-config-manager.mjs';
5
5
  import { a as addNumbersToChoices, p as promptBoolean } from '../shared/ccjk.DhBeLRzf.mjs';
6
- import { v as validateApiKey } from '../shared/ccjk.TVnFUDQc.mjs';
6
+ import { v as validateApiKey } from '../shared/ccjk.qYAnUMuy.mjs';
7
7
  import 'node:fs';
8
8
  import 'node:process';
9
9
  import 'node:url';
@@ -27,7 +27,8 @@ import './claude-config.mjs';
27
27
  import './platform.mjs';
28
28
  import './prompts.mjs';
29
29
  import './package.mjs';
30
- import '../shared/ccjk.HAxAfl1Z.mjs';
30
+ import '../shared/ccjk.DwDtZ5cK.mjs';
31
+ import 'node:child_process';
31
32
  import 'inquirer-toggle';
32
33
 
33
34
  function getAuthTypeLabel(authType) {
@@ -17,7 +17,7 @@ import { readJsonConfig, writeJsonConfig } from './json-config.mjs';
17
17
  import { isWindows, getMcpCommand, getSystemRoot, wrapCommandWithSudo, normalizeTomlPath } from './platform.mjs';
18
18
  import { p as promptBoolean, a as addNumbersToChoices } from '../shared/ccjk.DhBeLRzf.mjs';
19
19
  import { resolveAiOutputLanguage } from './prompts.mjs';
20
- import { g as getMcpServices, M as MCP_SERVICE_CONFIGS } from '../shared/ccjk.HAxAfl1Z.mjs';
20
+ import { g as getMcpServices, M as MCP_SERVICE_CONFIGS } from '../shared/ccjk.DwDtZ5cK.mjs';
21
21
 
22
22
  const MODEL_ENV_KEYS = [
23
23
  "ANTHROPIC_MODEL",
@@ -28,7 +28,8 @@ import './platform.mjs';
28
28
  import 'inquirer-toggle';
29
29
  import './prompts.mjs';
30
30
  import './package.mjs';
31
- import '../shared/ccjk.HAxAfl1Z.mjs';
31
+ import '../shared/ccjk.DwDtZ5cK.mjs';
32
+ import 'node:child_process';
32
33
 
33
34
  async function configSwitchCommand(options) {
34
35
  try {
@@ -1,20 +1,21 @@
1
1
  import ansis from 'ansis';
2
2
  import inquirer from 'inquirer';
3
- import { g as getMcpServices } from '../shared/ccjk.HAxAfl1Z.mjs';
3
+ import { g as getMcpServices } from '../shared/ccjk.DwDtZ5cK.mjs';
4
4
  import { SUPPORTED_LANGS, LANG_LABELS } from './constants.mjs';
5
5
  import { ensureI18nInitialized, i18n, changeLanguage } from './index2.mjs';
6
6
  import { updateZcfConfig, readZcfConfig } from './ccjk-config.mjs';
7
7
  import { q as isCcrInstalled, t as installCcr, E as setupCcrConfiguration } from './init.mjs';
8
8
  import { r as readMcpConfig, f as fixWindowsMcpConfig, w as writeMcpConfig, b as backupMcpConfig, a as buildMcpServerConfig, m as mergeMcpServers } from './claude-config.mjs';
9
9
  import { Y as applyAiLanguageDirective, W as getExistingModelConfig, T as updateCustomModel, U as updateDefaultModel, $ as selectMcpServices, X as getExistingApiConfig, _ as promptApiConfigurationAction, R as configureApi, Z as switchToOfficialLogin } from './codex.mjs';
10
- import { a as configureOutputStyle, m as modifyApiConfigPartially, v as validateApiKey, f as formatApiKeyDisplay } from '../shared/ccjk.TVnFUDQc.mjs';
10
+ import { a as configureOutputStyle, m as modifyApiConfigPartially, v as validateApiKey, f as formatApiKeyDisplay } from '../shared/ccjk.qYAnUMuy.mjs';
11
11
  import { isWindows } from './platform.mjs';
12
12
  import { a as addNumbersToChoices, p as promptBoolean } from '../shared/ccjk.DhBeLRzf.mjs';
13
13
  import { o as openSettingsJson, a as importRecommendedPermissions, i as importRecommendedEnv } from '../shared/ccjk.DJM5aVQJ.mjs';
14
+ import 'node:child_process';
14
15
  import 'node:os';
16
+ import 'node:process';
15
17
  import 'pathe';
16
18
  import 'node:fs';
17
- import 'node:process';
18
19
  import 'node:url';
19
20
  import 'i18next';
20
21
  import 'i18next-fs-backend';
@@ -26,7 +27,6 @@ import './json-config.mjs';
26
27
  import 'dayjs';
27
28
  import './package.mjs';
28
29
  import '../shared/ccjk.BhKlRJ0h.mjs';
29
- import 'node:child_process';
30
30
  import 'node:util';
31
31
  import './auto-updater.mjs';
32
32
  import 'ora';
@@ -4,8 +4,8 @@ import process from 'node:process';
4
4
  import ansis from 'ansis';
5
5
  import inquirer from 'inquirer';
6
6
  import { version } from './package.mjs';
7
- import { g as getMcpServices, M as MCP_SERVICE_CONFIGS } from '../shared/ccjk.HAxAfl1Z.mjs';
8
- import { m as modifyApiConfigPartially, c as configureApiCompletely, s as selectAndInstallWorkflows, a as configureOutputStyle, f as formatApiKeyDisplay, W as WORKFLOW_CONFIG_BASE } from '../shared/ccjk.TVnFUDQc.mjs';
7
+ import { g as getMcpServices, M as MCP_SERVICE_CONFIGS } from '../shared/ccjk.DwDtZ5cK.mjs';
8
+ import { m as modifyApiConfigPartially, c as configureApiCompletely, s as selectAndInstallWorkflows, a as configureOutputStyle, f as formatApiKeyDisplay, W as WORKFLOW_CONFIG_BASE } from '../shared/ccjk.qYAnUMuy.mjs';
9
9
  import { SETTINGS_FILE, DEFAULT_CODE_TOOL_TYPE, CODE_TOOL_BANNERS, API_DEFAULT_URL } from './constants.mjs';
10
10
  import { ensureI18nInitialized, i18n } from './index2.mjs';
11
11
  import { a as displayBannerWithInfo, p as padToDisplayWidth } from '../shared/ccjk.BhKlRJ0h.mjs';
@@ -1172,6 +1172,33 @@ async function verifyInstallation(codeType) {
1172
1172
  }
1173
1173
  }
1174
1174
  }
1175
+ if (getPlatform() === "linux") {
1176
+ const home = homedir();
1177
+ const linuxPaths = [
1178
+ `${home}/.local/bin/${command}`,
1179
+ // Standard XDG user bin (curl install default)
1180
+ `${home}/.claude/bin/${command}`,
1181
+ // Claude-specific bin directory
1182
+ `/usr/local/bin/${command}`,
1183
+ // System-wide installation
1184
+ `/usr/bin/${command}`
1185
+ // System package manager
1186
+ ];
1187
+ for (const path of linuxPaths) {
1188
+ if (exists(path)) {
1189
+ const version = await detectInstalledVersion(codeType);
1190
+ const needsPathUpdate = path.includes(".local/bin") && !process.env.PATH?.includes(".local/bin");
1191
+ return {
1192
+ success: true,
1193
+ commandPath: path,
1194
+ version,
1195
+ needsSymlink: false,
1196
+ symlinkCreated: false,
1197
+ error: needsPathUpdate ? "PATH_UPDATE_NEEDED" : void 0
1198
+ };
1199
+ }
1200
+ }
1201
+ }
1175
1202
  return {
1176
1203
  success: false,
1177
1204
  commandPath: null,
@@ -1258,16 +1285,27 @@ function displayVerificationResult(result, codeType) {
1258
1285
  if (result.symlinkCreated) {
1259
1286
  console.log(ansis.green(`\u2714 ${codeTypeName} ${i18n.t("installation:verificationSuccess")}`));
1260
1287
  console.log(ansis.gray(` ${i18n.t("installation:symlinkCreated", { path: result.commandPath })}`));
1288
+ } else if (result.commandPath) {
1289
+ console.log(ansis.green(`\u2714 ${codeTypeName} ${i18n.t("installation:verificationSuccess")}`));
1290
+ console.log(ansis.gray(` ${i18n.t("installation:foundAtPath", { path: result.commandPath })}`));
1261
1291
  }
1262
1292
  if (result.version) {
1263
1293
  console.log(ansis.gray(` ${i18n.t("installation:detectedVersion", { version: result.version })}`));
1264
1294
  }
1295
+ if (result.error === "PATH_UPDATE_NEEDED") {
1296
+ console.log(ansis.yellow(`
1297
+ \u26A0 ${i18n.t("installation:pathUpdateNeeded")}`));
1298
+ console.log(ansis.gray(` ${i18n.t("installation:pathUpdateHint")}`));
1299
+ console.log(ansis.cyan(` export PATH="$HOME/.local/bin:$PATH"`));
1300
+ console.log(ansis.gray(` ${i18n.t("installation:pathUpdatePermanent")}`));
1301
+ console.log(ansis.cyan(` echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.bashrc`));
1302
+ }
1265
1303
  } else {
1266
1304
  console.log(ansis.yellow(`\u26A0 ${codeTypeName} ${i18n.t("installation:verificationFailed")}`));
1267
1305
  if (result.commandPath) {
1268
1306
  console.log(ansis.gray(` ${i18n.t("installation:foundAtPath", { path: result.commandPath })}`));
1269
1307
  }
1270
- if (result.error) {
1308
+ if (result.error && result.error !== "PATH_UPDATE_NEEDED") {
1271
1309
  console.log(ansis.gray(` ${result.error}`));
1272
1310
  }
1273
1311
  if (result.needsSymlink && !result.symlinkCreated) {
@@ -1,16 +1,17 @@
1
1
  import ansis from 'ansis';
2
2
  import inquirer from 'inquirer';
3
- import { a as getMcpService, M as MCP_SERVICE_CONFIGS } from '../shared/ccjk.HAxAfl1Z.mjs';
3
+ import { a as getMcpService, M as MCP_SERVICE_CONFIGS } from '../shared/ccjk.DwDtZ5cK.mjs';
4
4
  import { ensureI18nInitialized, i18n } from './index2.mjs';
5
5
  import { ClAUDE_CONFIG_FILE, CODEX_CONFIG_FILE } from './constants.mjs';
6
6
  import { r as readMcpConfig, w as writeMcpConfig, a as buildMcpServerConfig } from './claude-config.mjs';
7
7
  import { r as readCodexConfig, w as writeCodexConfig, N as applyCodexPlatformCommand } from './codex.mjs';
8
8
  import { exists } from './fs-operations.mjs';
9
9
  import { isWindows, getSystemRoot } from './platform.mjs';
10
+ import 'node:child_process';
10
11
  import 'node:os';
12
+ import 'node:process';
11
13
  import 'pathe';
12
14
  import 'node:fs';
13
- import 'node:process';
14
15
  import 'node:url';
15
16
  import 'i18next';
16
17
  import 'i18next-fs-backend';
@@ -1,12 +1,13 @@
1
1
  import ansis from 'ansis';
2
- import { M as MCP_SERVICE_CONFIGS } from '../shared/ccjk.HAxAfl1Z.mjs';
2
+ import { M as MCP_SERVICE_CONFIGS } from '../shared/ccjk.DwDtZ5cK.mjs';
3
3
  import { i18n } from './index2.mjs';
4
4
  import { b as backupMcpConfig, r as readMcpConfig, w as writeMcpConfig } from './claude-config.mjs';
5
5
  import { checkMcpPerformance, formatPerformanceWarning } from './mcp-performance.mjs';
6
+ import 'node:child_process';
6
7
  import 'node:os';
8
+ import 'node:process';
7
9
  import 'pathe';
8
10
  import 'node:fs';
9
- import 'node:process';
10
11
  import 'node:url';
11
12
  import 'i18next';
12
13
  import 'i18next-fs-backend';
@@ -5,7 +5,7 @@ import inquirer from 'inquirer';
5
5
  import { join } from 'pathe';
6
6
  import { CODE_TOOL_BANNERS, CLAUDE_DIR, isCodeToolType, DEFAULT_CODE_TOOL_TYPE } from './constants.mjs';
7
7
  import { ensureI18nInitialized, i18n } from './index2.mjs';
8
- import { a as displayBannerWithInfo, p as padToDisplayWidth } from '../shared/ccjk.BhKlRJ0h.mjs';
8
+ import { a as displayBannerWithInfo } from '../shared/ccjk.BhKlRJ0h.mjs';
9
9
  import { updateZcfConfig, readZcfConfig } from './ccjk-config.mjs';
10
10
  import { E as runCodexUpdate, D as runCodexUninstall, M as configureCodexMcp, j as configureCodexApi, G as runCodexWorkflowImportWithLanguageSelection, B as runCodexFullInit } from './codex.mjs';
11
11
  import { r as resolveCodeType } from '../shared/ccjk.CUdzQluX.mjs';
@@ -3492,13 +3492,35 @@ async function isFirstTimeUser() {
3492
3492
  return false;
3493
3493
  }
3494
3494
  async function showNewUserWelcome() {
3495
+ const { version } = await import('./package.mjs');
3495
3496
  console.log("");
3496
- console.log(ansis.bold.cyan("\u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557"));
3497
- console.log(ansis.bold.cyan("\u2551") + ansis.bold.white(padToDisplayWidth(` ${i18n.t("menu:newUser.welcomeTitle")}`, 62)) + ansis.bold.cyan("\u2551"));
3498
- console.log(`${ansis.bold.cyan("\u2551")} ${ansis.bold.cyan("\u2551")}`);
3499
- console.log(ansis.bold.cyan("\u2551") + padToDisplayWidth(` ${i18n.t("menu:newUser.welcomeDesc1")}`, 62) + ansis.bold.cyan("\u2551"));
3500
- console.log(ansis.bold.cyan("\u2551") + padToDisplayWidth(` ${i18n.t("menu:newUser.welcomeDesc2")}`, 62) + ansis.bold.cyan("\u2551"));
3501
- console.log(ansis.bold.cyan("\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D"));
3497
+ console.log(ansis.cyan.bold("\u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557"));
3498
+ console.log(`${ansis.cyan.bold("\u2551")} ${ansis.cyan.bold("\u2551")}`);
3499
+ console.log(ansis.cyan.bold("\u2551") + ansis.white.bold(" \u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2557\u2588\u2588\u2557 \u2588\u2588\u2557 ") + ansis.cyan.bold("\u2551"));
3500
+ console.log(ansis.cyan.bold("\u2551") + ansis.white.bold(" \u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D \u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D \u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2554\u255D ") + ansis.cyan.bold("\u2551"));
3501
+ console.log(ansis.cyan.bold("\u2551") + ansis.white.bold(" \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2588\u2588\u2588\u2554\u255D ") + ansis.cyan.bold("\u2551"));
3502
+ console.log(ansis.cyan.bold("\u2551") + ansis.white.bold(" \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588 \u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2588\u2588\u2557 ") + ansis.cyan.bold("\u2551"));
3503
+ console.log(ansis.cyan.bold("\u2551") + ansis.white.bold(" \u255A\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u255A\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u255A\u2588\u2588\u2588\u2588\u2588\u2554\u255D\u2588\u2588\u2551 \u2588\u2588\u2557 ") + ansis.cyan.bold("\u2551"));
3504
+ console.log(ansis.cyan.bold("\u2551") + ansis.white.bold(" \u255A\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u255D ") + ansis.cyan.bold("\u2551"));
3505
+ console.log(`${ansis.cyan.bold("\u2551")} ${ansis.cyan.bold("\u2551")}`);
3506
+ console.log(ansis.cyan.bold("\u2551") + ansis.gray(` Claude Code JinKu - v${version}`.padEnd(72)) + ansis.cyan.bold("\u2551"));
3507
+ console.log(`${ansis.cyan.bold("\u2551")} ${ansis.cyan.bold("\u2551")}`);
3508
+ console.log(ansis.cyan.bold("\u2560\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2563"));
3509
+ console.log(`${ansis.cyan.bold("\u2551")} ${ansis.cyan.bold("\u2551")}`);
3510
+ console.log(ansis.cyan.bold("\u2551") + ansis.yellow.bold(` ${i18n.t("menu:newUser.welcomeTitle")}`.padEnd(72)) + ansis.cyan.bold("\u2551"));
3511
+ console.log(`${ansis.cyan.bold("\u2551")} ${ansis.cyan.bold("\u2551")}`);
3512
+ console.log(ansis.cyan.bold("\u2551") + ansis.white(` ${i18n.t("menu:newUser.welcomeDesc1")}`.padEnd(72)) + ansis.cyan.bold("\u2551"));
3513
+ console.log(ansis.cyan.bold("\u2551") + ansis.white(` ${i18n.t("menu:newUser.welcomeDesc2")}`.padEnd(72)) + ansis.cyan.bold("\u2551"));
3514
+ console.log(`${ansis.cyan.bold("\u2551")} ${ansis.cyan.bold("\u2551")}`);
3515
+ console.log(ansis.cyan.bold("\u2560\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2563"));
3516
+ console.log(`${ansis.cyan.bold("\u2551")} ${ansis.cyan.bold("\u2551")}`);
3517
+ console.log(ansis.cyan.bold("\u2551") + ansis.green(` ${i18n.t("menu:newUser.highlights")}`.padEnd(72)) + ansis.cyan.bold("\u2551"));
3518
+ console.log(ansis.cyan.bold("\u2551") + ansis.gray(` \u2022 ${i18n.t("menu:newUser.highlight1")}`.padEnd(72)) + ansis.cyan.bold("\u2551"));
3519
+ console.log(ansis.cyan.bold("\u2551") + ansis.gray(` \u2022 ${i18n.t("menu:newUser.highlight2")}`.padEnd(72)) + ansis.cyan.bold("\u2551"));
3520
+ console.log(ansis.cyan.bold("\u2551") + ansis.gray(` \u2022 ${i18n.t("menu:newUser.highlight3")}`.padEnd(72)) + ansis.cyan.bold("\u2551"));
3521
+ console.log(ansis.cyan.bold("\u2551") + ansis.gray(` \u2022 ${i18n.t("menu:newUser.highlight4")}`.padEnd(72)) + ansis.cyan.bold("\u2551"));
3522
+ console.log(`${ansis.cyan.bold("\u2551")} ${ansis.cyan.bold("\u2551")}`);
3523
+ console.log(ansis.cyan.bold("\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D"));
3502
3524
  console.log("");
3503
3525
  const { mode } = await inquirer.prompt({
3504
3526
  type: "list",
@@ -3506,7 +3528,7 @@ async function showNewUserWelcome() {
3506
3528
  message: i18n.t("menu:newUser.selectPrompt"),
3507
3529
  choices: [
3508
3530
  {
3509
- name: ansis.green(i18n.t("menu:newUser.quickStart")) + ansis.dim(` - ${i18n.t("menu:newUser.quickStartDesc")}`),
3531
+ name: ansis.green.bold(i18n.t("menu:newUser.quickStart")) + ansis.dim(` - ${i18n.t("menu:newUser.quickStartDesc")}`),
3510
3532
  value: "quick"
3511
3533
  },
3512
3534
  {
@@ -3517,7 +3539,9 @@ async function showNewUserWelcome() {
3517
3539
  name: ansis.yellow(i18n.t("menu:newUser.viewHelp")) + ansis.dim(` - ${i18n.t("menu:newUser.viewHelpDesc")}`),
3518
3540
  value: "help"
3519
3541
  }
3520
- ]
3542
+ ],
3543
+ loop: false,
3544
+ pageSize: 10
3521
3545
  });
3522
3546
  return mode;
3523
3547
  }
@@ -1,4 +1,4 @@
1
- const version = "2.1.0";
1
+ const version = "2.2.2";
2
2
  const homepage = "https://github.com/miounet11/ccjk";
3
3
 
4
4
  export { homepage, version };
@@ -1,5 +1,5 @@
1
1
  import { existsSync } from 'node:fs';
2
- import { mkdir, writeFile, readdir, readFile } from 'node:fs/promises';
2
+ import { mkdir, writeFile, readdir, readFile, rm, stat } from 'node:fs/promises';
3
3
  import { homedir } from 'node:os';
4
4
  import { join } from 'node:path';
5
5
  import process from 'node:process';
@@ -7,6 +7,8 @@ import ansis from 'ansis';
7
7
  import inquirer from 'inquirer';
8
8
 
9
9
  const SESSIONS_DIR = join(homedir(), ".ccjk", "sessions");
10
+ const CCJK_DIR = join(homedir(), ".ccjk");
11
+ const CLAUDE_DIR = join(homedir(), ".claude");
10
12
  async function saveSession() {
11
13
  try {
12
14
  const timestamp = (/* @__PURE__ */ new Date()).toISOString();
@@ -164,5 +166,190 @@ Session data would be exported here.
164
166
  console.error(ansis.red("Failed to export session:"), error);
165
167
  }
166
168
  }
169
+ function formatBytes(bytes) {
170
+ if (bytes === 0)
171
+ return "0 B";
172
+ const k = 1024;
173
+ const sizes = ["B", "KB", "MB", "GB"];
174
+ const i = Math.floor(Math.log(bytes) / Math.log(k));
175
+ return `${Number.parseFloat((bytes / k ** i).toFixed(2))} ${sizes[i]}`;
176
+ }
177
+ async function getDirSize(dirPath) {
178
+ if (!existsSync(dirPath))
179
+ return 0;
180
+ let totalSize = 0;
181
+ try {
182
+ const entries = await readdir(dirPath, { withFileTypes: true });
183
+ for (const entry of entries) {
184
+ const fullPath = join(dirPath, entry.name);
185
+ if (entry.isDirectory()) {
186
+ totalSize += await getDirSize(fullPath);
187
+ } else {
188
+ const fileStat = await stat(fullPath);
189
+ totalSize += fileStat.size;
190
+ }
191
+ }
192
+ } catch {
193
+ }
194
+ return totalSize;
195
+ }
196
+ async function countFiles(dirPath) {
197
+ if (!existsSync(dirPath))
198
+ return 0;
199
+ let count = 0;
200
+ try {
201
+ const entries = await readdir(dirPath, { withFileTypes: true });
202
+ for (const entry of entries) {
203
+ const fullPath = join(dirPath, entry.name);
204
+ if (entry.isDirectory()) {
205
+ count += await countFiles(fullPath);
206
+ } else {
207
+ count++;
208
+ }
209
+ }
210
+ } catch {
211
+ }
212
+ return count;
213
+ }
214
+ async function analyzeCleanupTargets() {
215
+ const targets = [];
216
+ const ccjkCacheDirs = [
217
+ { name: "ccjk/cache", path: join(CCJK_DIR, "cache"), desc: "General cache files", safe: true },
218
+ { name: "ccjk/sessions", path: join(CCJK_DIR, "sessions"), desc: "Saved session data", safe: true },
219
+ { name: "ccjk/logs", path: join(CCJK_DIR, "logs"), desc: "Log files", safe: true },
220
+ { name: "ccjk/temp", path: join(CCJK_DIR, "temp"), desc: "Temporary files", safe: true }
221
+ ];
222
+ const claudeDirs = [
223
+ { name: "claude/projects", path: join(CLAUDE_DIR, "projects"), desc: "Claude project caches", safe: true },
224
+ { name: "claude/debug", path: join(CLAUDE_DIR, "debug"), desc: "Debug logs and traces", safe: true },
225
+ { name: "claude/file-history", path: join(CLAUDE_DIR, "file-history"), desc: "File edit history", safe: true },
226
+ { name: "claude/shell-snapshots", path: join(CLAUDE_DIR, "shell-snapshots"), desc: "Shell state snapshots", safe: true },
227
+ { name: "claude/paste-cache", path: join(CLAUDE_DIR, "paste-cache"), desc: "Clipboard paste cache", safe: true },
228
+ { name: "claude/todos", path: join(CLAUDE_DIR, "todos"), desc: "Todo list files", safe: false },
229
+ { name: "claude/plans", path: join(CLAUDE_DIR, "plans"), desc: "Plan files", safe: true },
230
+ { name: "claude/session-env", path: join(CLAUDE_DIR, "session-env"), desc: "Session environment data", safe: true },
231
+ { name: "claude/ide", path: join(CLAUDE_DIR, "ide"), desc: "IDE integration cache", safe: true }
232
+ ];
233
+ for (const dir of [...ccjkCacheDirs, ...claudeDirs]) {
234
+ if (existsSync(dir.path)) {
235
+ const size = await getDirSize(dir.path);
236
+ const fileCount = await countFiles(dir.path);
237
+ if (size > 0) {
238
+ targets.push({
239
+ name: dir.name,
240
+ path: dir.path,
241
+ description: dir.desc,
242
+ size,
243
+ fileCount,
244
+ safe: dir.safe
245
+ });
246
+ }
247
+ }
248
+ }
249
+ return targets.sort((a, b) => b.size - a.size);
250
+ }
251
+ async function cleanupSession(options = {}) {
252
+ try {
253
+ console.log(ansis.cyan.bold("\n\u{1F9F9} Session & Cache Cleanup\n"));
254
+ console.log(ansis.gray("Analyzing cleanup targets..."));
255
+ const targets = await analyzeCleanupTargets();
256
+ if (targets.length === 0) {
257
+ console.log(ansis.green("\u2714 No cleanup needed - everything is clean!"));
258
+ return;
259
+ }
260
+ console.log(ansis.white.bold("\nCleanup Targets:\n"));
261
+ let totalSize = 0;
262
+ let totalFiles = 0;
263
+ for (const target of targets) {
264
+ totalSize += target.size;
265
+ totalFiles += target.fileCount;
266
+ const sizeStr = formatBytes(target.size).padStart(10);
267
+ const filesStr = `${target.fileCount} files`.padStart(12);
268
+ console.log(` ${ansis.yellow(sizeStr)} ${ansis.gray(filesStr)} ${ansis.white(target.name)}`);
269
+ console.log(` ${ansis.gray(` ${target.description}`)}`);
270
+ console.log(` ${ansis.gray(` ${target.path}`)}`);
271
+ console.log("");
272
+ }
273
+ console.log(ansis.white.bold("\u2500".repeat(50)));
274
+ console.log(` ${ansis.cyan(formatBytes(totalSize).padStart(10))} ${ansis.gray(`${totalFiles} files`.padStart(12))} ${ansis.white.bold("Total")}`);
275
+ console.log("");
276
+ if (!options.force) {
277
+ const { confirm } = await inquirer.prompt({
278
+ type: "confirm",
279
+ name: "confirm",
280
+ message: options.all ? `Delete ALL ${targets.length} targets (${formatBytes(totalSize)})?` : "Select targets to clean?",
281
+ default: false
282
+ });
283
+ if (!confirm) {
284
+ console.log(ansis.yellow("Cleanup cancelled"));
285
+ return;
286
+ }
287
+ }
288
+ let selectedTargets = targets;
289
+ if (!options.all && !options.force) {
290
+ const { selected } = await inquirer.prompt({
291
+ type: "checkbox",
292
+ name: "selected",
293
+ message: "Select targets to clean:",
294
+ choices: targets.map((t) => ({
295
+ name: `${t.name} (${formatBytes(t.size)}, ${t.fileCount} files)`,
296
+ value: t.path,
297
+ checked: t.safe
298
+ }))
299
+ });
300
+ selectedTargets = targets.filter((t) => selected.includes(t.path));
301
+ }
302
+ if (selectedTargets.length === 0) {
303
+ console.log(ansis.yellow("No targets selected"));
304
+ return;
305
+ }
306
+ console.log(ansis.gray("\nCleaning up..."));
307
+ let cleanedSize = 0;
308
+ let cleanedFiles = 0;
309
+ for (const target of selectedTargets) {
310
+ try {
311
+ await rm(target.path, { recursive: true, force: true });
312
+ cleanedSize += target.size;
313
+ cleanedFiles += target.fileCount;
314
+ console.log(ansis.green(` \u2714 ${target.name}`));
315
+ } catch (error) {
316
+ console.log(ansis.red(` \u2716 ${target.name}: ${error}`));
317
+ }
318
+ }
319
+ console.log("");
320
+ console.log(ansis.green.bold(`\u2714 Cleanup complete!`));
321
+ console.log(ansis.gray(` Freed ${formatBytes(cleanedSize)} (${cleanedFiles} files)`));
322
+ } catch (error) {
323
+ console.error(ansis.red("Failed to cleanup:"), error);
324
+ }
325
+ }
326
+ async function sessionStatus() {
327
+ try {
328
+ console.log(ansis.cyan.bold("\n\u{1F4CA} Session & Cache Status\n"));
329
+ const targets = await analyzeCleanupTargets();
330
+ if (targets.length === 0) {
331
+ console.log(ansis.green("\u2714 All clean - no cached data found"));
332
+ return;
333
+ }
334
+ let totalSize = 0;
335
+ let totalFiles = 0;
336
+ console.log(ansis.white.bold("Directory Size Files"));
337
+ console.log(ansis.gray("\u2500".repeat(50)));
338
+ for (const target of targets) {
339
+ totalSize += target.size;
340
+ totalFiles += target.fileCount;
341
+ const name = target.name.padEnd(24);
342
+ const size = formatBytes(target.size).padStart(10);
343
+ const files = String(target.fileCount).padStart(8);
344
+ console.log(`${ansis.white(name)} ${ansis.yellow(size)} ${ansis.gray(files)}`);
345
+ }
346
+ console.log(ansis.gray("\u2500".repeat(50)));
347
+ console.log(`${ansis.white.bold("Total".padEnd(24))} ${ansis.cyan.bold(formatBytes(totalSize).padStart(10))} ${ansis.gray(String(totalFiles).padStart(8))}`);
348
+ console.log("");
349
+ console.log(ansis.gray(`Run ${ansis.cyan("ccjk session cleanup")} to free up space`));
350
+ } catch (error) {
351
+ console.error(ansis.red("Failed to get status:"), error);
352
+ }
353
+ }
167
354
 
168
- export { exportSession, listSessions, restoreSession, saveSession };
355
+ export { cleanupSession, exportSession, listSessions, restoreSession, saveSession, sessionStatus };
@@ -5,7 +5,7 @@ import { i18n } from './index2.mjs';
5
5
  import { d as displayBanner } from '../shared/ccjk.BhKlRJ0h.mjs';
6
6
  import { readZcfConfig, updateZcfConfig } from './ccjk-config.mjs';
7
7
  import { E as runCodexUpdate } from './codex.mjs';
8
- import { u as updatePromptOnly, s as selectAndInstallWorkflows } from '../shared/ccjk.TVnFUDQc.mjs';
8
+ import { u as updatePromptOnly, s as selectAndInstallWorkflows } from '../shared/ccjk.qYAnUMuy.mjs';
9
9
  import { h as handleExitPromptError, a as handleGeneralError } from '../shared/ccjk.B7169qud.mjs';
10
10
  import { resolveAiOutputLanguage } from './prompts.mjs';
11
11
  import { c as checkClaudeCodeVersionAndPrompt } from '../shared/ccjk.Cy-RH2qV.mjs';
@@ -30,7 +30,7 @@ import './claude-config.mjs';
30
30
  import './platform.mjs';
31
31
  import '../shared/ccjk.DhBeLRzf.mjs';
32
32
  import 'inquirer-toggle';
33
- import '../shared/ccjk.HAxAfl1Z.mjs';
33
+ import '../shared/ccjk.DwDtZ5cK.mjs';
34
34
  import 'node:child_process';
35
35
  import 'node:path';
36
36
  import 'node:util';
package/dist/cli.mjs CHANGED
@@ -246,11 +246,15 @@ const COMMANDS = [
246
246
  },
247
247
  {
248
248
  name: "session <action> [id]",
249
- description: "Manage sessions",
249
+ description: "Manage sessions (save, list, restore, export, cleanup, status)",
250
250
  tier: "extended",
251
+ options: [
252
+ { flags: "--all, -a", description: "Clean all targets without selection" },
253
+ { flags: "--force, -f", description: "Force cleanup without confirmation" }
254
+ ],
251
255
  loader: async () => {
252
- const { saveSession, listSessions, restoreSession, exportSession } = await import('./chunks/session.mjs');
253
- return async (_options, action, id) => {
256
+ const { saveSession, listSessions, restoreSession, exportSession, cleanupSession, sessionStatus } = await import('./chunks/session.mjs');
257
+ return async (options, action, id) => {
254
258
  const actionStr = action;
255
259
  if (actionStr === "save")
256
260
  await saveSession();
@@ -260,6 +264,12 @@ const COMMANDS = [
260
264
  await restoreSession(id);
261
265
  else if (actionStr === "export")
262
266
  await exportSession(id);
267
+ else if (actionStr === "cleanup" || actionStr === "clean")
268
+ await cleanupSession({ all: options.all, force: options.force });
269
+ else if (actionStr === "status")
270
+ await sessionStatus();
271
+ else
272
+ console.error(`Unknown action: ${actionStr}. Use: save, list, restore, export, cleanup, or status`);
263
273
  };
264
274
  }
265
275
  },
@@ -76,5 +76,8 @@
76
76
  "duplicateWarningContinue": "Acknowledged duplicate installation risk, continue",
77
77
  "versionMismatchWarning": "⚠️ Version mismatch: npm is {npmVersion}, Homebrew is {homebrewVersion}",
78
78
  "activatingHomebrew": "Activating Homebrew installation...",
79
- "autoRemovingNpm": "Silent mode: Auto-removing npm installation and keeping Homebrew..."
79
+ "autoRemovingNpm": "Silent mode: Auto-removing npm installation and keeping Homebrew...",
80
+ "pathUpdateNeeded": "PATH configuration required",
81
+ "pathUpdateHint": "Add ~/.local/bin to your PATH to use claude command directly:",
82
+ "pathUpdatePermanent": "To make this permanent, add to your shell config:"
80
83
  }
@@ -255,6 +255,15 @@
255
255
  "newUser.fullConfigDesc": "Customize all options",
256
256
  "newUser.viewHelp": "📖 View Help",
257
257
  "newUser.viewHelpDesc": "Learn about CCJK features",
258
+ "newUser.selectLang": "🌐 Select Language",
259
+ "newUser.selectLangDesc": "Change display language",
260
+ "newUser.langPrompt": "Select your preferred language:",
261
+ "newUser.langChanged": "Language changed to {{lang}}",
262
+ "newUser.highlights": "✨ Highlights",
263
+ "newUser.highlight1": "One-click API configuration with multiple providers",
264
+ "newUser.highlight2": "Pre-built workflow templates for common tasks",
265
+ "newUser.highlight3": "MCP services for enhanced capabilities",
266
+ "newUser.highlight4": "Smart diagnostics and auto-fix",
258
267
  "newUser.featuresTitle": "📖 CCJK Features Overview",
259
268
  "newUser.coreFeatures": "Core Features:",
260
269
  "newUser.feature.api": "API Configuration - Support Auth Token, API Key, CCR Proxy",
@@ -76,5 +76,8 @@
76
76
  "duplicateWarningContinue": "已知晓多重安装风险,继续使用",
77
77
  "versionMismatchWarning": "⚠️ 版本不一致:npm 版本为 {npmVersion},Homebrew 版本为 {homebrewVersion}",
78
78
  "activatingHomebrew": "正在激活 Homebrew 安装...",
79
- "autoRemovingNpm": "静默模式:自动删除 npm 安装并保留 Homebrew..."
79
+ "autoRemovingNpm": "静默模式:自动删除 npm 安装并保留 Homebrew...",
80
+ "pathUpdateNeeded": "需要配置 PATH 环境变量",
81
+ "pathUpdateHint": "将 ~/.local/bin 添加到 PATH 以直接使用 claude 命令:",
82
+ "pathUpdatePermanent": "要永久生效,请添加到 shell 配置文件:"
80
83
  }
@@ -255,6 +255,15 @@
255
255
  "newUser.fullConfigDesc": "自定义所有选项",
256
256
  "newUser.viewHelp": "📖 查看帮助",
257
257
  "newUser.viewHelpDesc": "了解 CCJK 功能",
258
+ "newUser.selectLang": "🌐 选择语言",
259
+ "newUser.selectLangDesc": "更改显示语言",
260
+ "newUser.langPrompt": "请选择您的首选语言:",
261
+ "newUser.langChanged": "语言已更改为 {{lang}}",
262
+ "newUser.highlights": "✨ 亮点功能",
263
+ "newUser.highlight1": "一键配置 API,支持多种提供商",
264
+ "newUser.highlight2": "预置工作流模板,开箱即用",
265
+ "newUser.highlight3": "MCP 服务增强 AI 能力",
266
+ "newUser.highlight4": "智能诊断,自动修复问题",
258
267
  "newUser.featuresTitle": "📖 CCJK 功能介绍",
259
268
  "newUser.coreFeatures": "核心功能:",
260
269
  "newUser.feature.api": "API 配置 - 支持 Auth Token、API Key、CCR 代理",
package/dist/index.mjs CHANGED
@@ -17,14 +17,15 @@ import 'node:process';
17
17
  import 'ansis';
18
18
  import 'inquirer';
19
19
  import './chunks/package.mjs';
20
- import './shared/ccjk.HAxAfl1Z.mjs';
20
+ import './shared/ccjk.DwDtZ5cK.mjs';
21
+ import 'node:child_process';
21
22
  import 'node:os';
22
23
  import 'pathe';
23
24
  import './chunks/index2.mjs';
24
25
  import 'node:url';
25
26
  import 'i18next';
26
27
  import 'i18next-fs-backend';
27
- import './shared/ccjk.TVnFUDQc.mjs';
28
+ import './shared/ccjk.qYAnUMuy.mjs';
28
29
  import './chunks/ccjk-config.mjs';
29
30
  import 'smol-toml';
30
31
  import './chunks/fs-operations.mjs';
@@ -34,7 +35,6 @@ import './chunks/json-config.mjs';
34
35
  import 'dayjs';
35
36
  import './shared/ccjk.DhBeLRzf.mjs';
36
37
  import 'inquirer-toggle';
37
- import 'node:child_process';
38
38
  import 'node:util';
39
39
  import './chunks/auto-updater.mjs';
40
40
  import 'ora';
@@ -1,4 +1,6 @@
1
+ import 'node:child_process';
1
2
  import { homedir } from 'node:os';
3
+ import 'node:process';
2
4
  import { join } from 'pathe';
3
5
  import { ensureI18nInitialized, i18n } from '../chunks/index2.mjs';
4
6
 
@@ -25,7 +27,7 @@ function createPlaywrightMcpConfig(options = {}) {
25
27
  };
26
28
  }
27
29
  const MCP_SERVICE_CONFIGS = [
28
- // Documentation and Search Services
30
+ // Documentation and Search Services - Universal (no GUI required)
29
31
  {
30
32
  id: "context7",
31
33
  requiresApiKey: false,
@@ -35,6 +37,7 @@ const MCP_SERVICE_CONFIGS = [
35
37
  args: ["-y", "@upstash/context7-mcp@latest"],
36
38
  env: {}
37
39
  }
40
+ // Works on all platforms - no special requirements
38
41
  },
39
42
  {
40
43
  id: "open-websearch",
@@ -49,6 +52,7 @@ const MCP_SERVICE_CONFIGS = [
49
52
  ALLOWED_SEARCH_ENGINES: "duckduckgo,bing,brave"
50
53
  }
51
54
  }
55
+ // Works on all platforms - no special requirements
52
56
  },
53
57
  {
54
58
  id: "mcp-deepwiki",
@@ -59,6 +63,7 @@ const MCP_SERVICE_CONFIGS = [
59
63
  args: ["-y", "mcp-deepwiki@latest"],
60
64
  env: {}
61
65
  }
66
+ // Works on all platforms - no special requirements
62
67
  },
63
68
  // Development Workflow Services
64
69
  {
@@ -70,6 +75,7 @@ const MCP_SERVICE_CONFIGS = [
70
75
  args: ["-y", "@pimzino/spec-workflow-mcp@latest"],
71
76
  env: {}
72
77
  }
78
+ // Works on all platforms - no special requirements
73
79
  },
74
80
  {
75
81
  id: "serena",
@@ -79,14 +85,23 @@ const MCP_SERVICE_CONFIGS = [
79
85
  command: "uvx",
80
86
  args: ["--from", "git+https://github.com/oraios/serena", "serena", "start-mcp-server", "--context", "ide-assistant", "--enable-web-dashboard", "false"],
81
87
  env: {}
88
+ },
89
+ platformRequirements: {
90
+ requiredCommands: ["uvx"]
91
+ // Requires uv/uvx to be installed
82
92
  }
83
93
  },
84
- // Browser and Automation Services
94
+ // Browser and Automation Services - Require GUI environment
85
95
  {
86
96
  id: "Playwright",
87
97
  requiresApiKey: false,
88
- config: createPlaywrightMcpConfig()
98
+ config: createPlaywrightMcpConfig(),
89
99
  // Uses default profile with chromium browser
100
+ platformRequirements: {
101
+ platforms: ["macos", "windows"],
102
+ // GUI required - exclude headless Linux/WSL/Termux
103
+ requiresGui: true
104
+ }
90
105
  },
91
106
  {
92
107
  id: "puppeteer",
@@ -96,9 +111,14 @@ const MCP_SERVICE_CONFIGS = [
96
111
  command: "npx",
97
112
  args: ["-y", "@anthropic-ai/mcp-server-puppeteer@latest"],
98
113
  env: {}
114
+ },
115
+ platformRequirements: {
116
+ platforms: ["macos", "windows"],
117
+ // GUI required - exclude headless Linux/WSL/Termux
118
+ requiresGui: true
99
119
  }
100
120
  },
101
- // Anthropic Official MCP Services
121
+ // Anthropic Official MCP Services - Universal
102
122
  {
103
123
  id: "filesystem",
104
124
  requiresApiKey: false,
@@ -108,6 +128,7 @@ const MCP_SERVICE_CONFIGS = [
108
128
  args: ["-y", "@anthropic-ai/mcp-server-filesystem@latest", "."],
109
129
  env: {}
110
130
  }
131
+ // Works on all platforms - no special requirements
111
132
  },
112
133
  {
113
134
  id: "memory",
@@ -118,6 +139,7 @@ const MCP_SERVICE_CONFIGS = [
118
139
  args: ["-y", "@anthropic-ai/mcp-server-memory@latest"],
119
140
  env: {}
120
141
  }
142
+ // Works on all platforms - no special requirements
121
143
  },
122
144
  {
123
145
  id: "sequential-thinking",
@@ -128,6 +150,7 @@ const MCP_SERVICE_CONFIGS = [
128
150
  args: ["-y", "@anthropic-ai/mcp-server-sequential-thinking@latest"],
129
151
  env: {}
130
152
  }
153
+ // Works on all platforms - no special requirements
131
154
  },
132
155
  {
133
156
  id: "fetch",
@@ -138,6 +161,7 @@ const MCP_SERVICE_CONFIGS = [
138
161
  args: ["-y", "@anthropic-ai/mcp-server-fetch@latest"],
139
162
  env: {}
140
163
  }
164
+ // Works on all platforms - no special requirements
141
165
  },
142
166
  {
143
167
  id: "sqlite",
@@ -148,6 +172,7 @@ const MCP_SERVICE_CONFIGS = [
148
172
  args: ["-y", "@anthropic-ai/mcp-server-sqlite@latest"],
149
173
  env: {}
150
174
  }
175
+ // Works on all platforms - no special requirements
151
176
  }
152
177
  ];
153
178
  async function getMcpServices() {
@@ -280,8 +280,8 @@ async function configureOutputStyle(preselectedStyles, preselectedDefault) {
280
280
  return {
281
281
  name: `${styleInfo?.name || style.id} - ${ansis.gray(styleInfo?.description || "")}`,
282
282
  value: style.id,
283
- checked: true
284
- // Default select all custom styles
283
+ checked: false
284
+ // Let user choose, not pre-selected
285
285
  };
286
286
  })),
287
287
  validate: async (input) => input.length > 0 || i18n.t("configuration:selectAtLeastOne")
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "ccjk",
3
3
  "type": "module",
4
- "version": "2.1.0",
4
+ "version": "2.2.2",
5
5
  "packageManager": "pnpm@10.17.1",
6
6
  "description": "Claude Code JinKu - Advanced AI-powered development assistant with skills, agents, and LLM-driven audit",
7
7
  "author": {