ccjk 2.2.1 → 2.2.4
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 +74 -13
- package/README.zh-CN.md +82 -21
- package/dist/chunks/auto-updater.mjs +23 -3
- package/dist/chunks/ccr.mjs +1 -1
- package/dist/chunks/check-updates.mjs +1 -1
- package/dist/chunks/features2.mjs +1 -1
- package/dist/chunks/init.mjs +40 -2
- package/dist/chunks/menu.mjs +33 -9
- package/dist/chunks/package.mjs +1 -1
- package/dist/chunks/update.mjs +1 -1
- package/dist/{shared/ccjk.Cy-RH2qV.mjs → chunks/version-checker.mjs} +289 -27
- package/dist/i18n/locales/en/installation.json +4 -1
- package/dist/i18n/locales/en/menu.json +9 -0
- package/dist/i18n/locales/en/updater.json +2 -1
- package/dist/i18n/locales/zh-CN/installation.json +4 -1
- package/dist/i18n/locales/zh-CN/menu.json +9 -0
- package/dist/i18n/locales/zh-CN/updater.json +2 -1
- package/dist/index.mjs +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -67,17 +67,31 @@
|
|
|
67
67
|
|
|
68
68
|
<br/>
|
|
69
69
|
|
|
70
|
-
<!-- One-Click
|
|
70
|
+
<!-- One-Click Installation -->
|
|
71
|
+
### ⚡ Quick Install
|
|
72
|
+
|
|
73
|
+
**🌍 Global Users**
|
|
71
74
|
```bash
|
|
72
|
-
|
|
75
|
+
curl -fsSL https://raw.githubusercontent.com/miounet11/ccjk/main/install.sh | bash
|
|
73
76
|
```
|
|
74
77
|
|
|
75
|
-
|
|
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
|
-
[
|
|
94
|
+
[🧠 Architecture](#-core-architecture) · [📊 Benchmarks](#-performance-benchmarks) · [🌟 Acknowledgments](#-ecosystem-acknowledgments)
|
|
81
95
|
|
|
82
96
|
</div>
|
|
83
97
|
|
|
@@ -318,15 +332,53 @@ Doc Generation █████████████████████
|
|
|
318
332
|
|
|
319
333
|
## 🚀 Quick Start
|
|
320
334
|
|
|
321
|
-
###
|
|
335
|
+
### ⚡ One-Click Installation (Recommended)
|
|
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+ | Latest |
|
|
337
|
+
**Auto-installs Node.js, npm, git and CCJK — works on fresh systems!**
|
|
328
338
|
|
|
329
|
-
|
|
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
|
-
#
|
|
358
|
-
npm install -g
|
|
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
|
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
|
-
|
|
75
|
+
curl -fsSL https://ghproxy.com/https://raw.githubusercontent.com/miounet11/ccjk/main/install.sh | bash
|
|
73
76
|
```
|
|
74
77
|
|
|
75
|
-
|
|
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
|
-
|
|
346
|
+
curl -fsSL https://ghproxy.com/https://raw.githubusercontent.com/miounet11/ccjk/main/install.sh | bash
|
|
347
|
+
```
|
|
340
348
|
|
|
341
|
-
|
|
342
|
-
|
|
349
|
+
</td>
|
|
350
|
+
<td width="50%">
|
|
343
351
|
|
|
344
|
-
|
|
345
|
-
|
|
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
|
|
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
|
|
@@ -4,7 +4,7 @@ import { exec } from 'tinyexec';
|
|
|
4
4
|
import { ensureI18nInitialized, i18n, format } from './index2.mjs';
|
|
5
5
|
import { shouldUseSudoForGlobalInstall } from './platform.mjs';
|
|
6
6
|
import { p as promptBoolean } from '../shared/ccjk.DhBeLRzf.mjs';
|
|
7
|
-
import {
|
|
7
|
+
import { checkClaudeCodeVersion, checkCcrVersion, handleDuplicateInstallations, checkCometixLineVersion } from './version-checker.mjs';
|
|
8
8
|
import 'node:fs';
|
|
9
9
|
import 'node:process';
|
|
10
10
|
import 'node:url';
|
|
@@ -128,8 +128,28 @@ async function updateClaudeCode(force = false, skipPrompt = false) {
|
|
|
128
128
|
throw new Error(result.stderr || `Command failed with exit code ${result.exitCode}`);
|
|
129
129
|
}
|
|
130
130
|
} else {
|
|
131
|
-
if (isBroken
|
|
132
|
-
|
|
131
|
+
if (isBroken) {
|
|
132
|
+
if (installationSource === "npm") {
|
|
133
|
+
await execWithSudoIfNeeded("npm", ["install", "-g", "@anthropic-ai/claude-code"]);
|
|
134
|
+
} else if (installationSource === "curl") {
|
|
135
|
+
const { detectAllClaudeCodeInstallations } = await import('./version-checker.mjs');
|
|
136
|
+
const installations = await detectAllClaudeCodeInstallations();
|
|
137
|
+
const curlInstall = installations.find((i) => i.source === "curl" && i.version);
|
|
138
|
+
if (curlInstall?.path) {
|
|
139
|
+
await execWithSudoIfNeeded(curlInstall.path, ["update"]);
|
|
140
|
+
} else {
|
|
141
|
+
throw new Error(i18n.t("updater:curlReinstallRequired"));
|
|
142
|
+
}
|
|
143
|
+
} else {
|
|
144
|
+
const { detectAllClaudeCodeInstallations } = await import('./version-checker.mjs');
|
|
145
|
+
const installations = await detectAllClaudeCodeInstallations();
|
|
146
|
+
const activeInstall = installations.find((i) => i.version);
|
|
147
|
+
if (activeInstall?.path) {
|
|
148
|
+
await execWithSudoIfNeeded(activeInstall.path, ["update"]);
|
|
149
|
+
} else {
|
|
150
|
+
throw new Error(i18n.t("updater:curlReinstallRequired"));
|
|
151
|
+
}
|
|
152
|
+
}
|
|
133
153
|
} else {
|
|
134
154
|
await execWithSudoIfNeeded("claude", ["update"]);
|
|
135
155
|
}
|
package/dist/chunks/ccr.mjs
CHANGED
|
@@ -37,7 +37,7 @@ import './init.mjs';
|
|
|
37
37
|
import '../shared/ccjk.qYAnUMuy.mjs';
|
|
38
38
|
import 'node:util';
|
|
39
39
|
import './auto-updater.mjs';
|
|
40
|
-
import '
|
|
40
|
+
import './version-checker.mjs';
|
|
41
41
|
import 'node:path';
|
|
42
42
|
import '../shared/ccjk.DJM5aVQJ.mjs';
|
|
43
43
|
import '../shared/ccjk.Bi-m3LKY.mjs';
|
|
@@ -23,7 +23,7 @@ import 'tinyexec';
|
|
|
23
23
|
import './platform.mjs';
|
|
24
24
|
import '../shared/ccjk.DhBeLRzf.mjs';
|
|
25
25
|
import 'inquirer-toggle';
|
|
26
|
-
import '
|
|
26
|
+
import './version-checker.mjs';
|
|
27
27
|
import 'node:child_process';
|
|
28
28
|
import 'node:path';
|
|
29
29
|
import 'node:util';
|
package/dist/chunks/init.mjs
CHANGED
|
@@ -28,7 +28,7 @@ import ora from 'ora';
|
|
|
28
28
|
import { exec as exec$1 } from 'tinyexec';
|
|
29
29
|
import { resolveAiOutputLanguage } from './prompts.mjs';
|
|
30
30
|
import { readFile } from 'node:fs/promises';
|
|
31
|
-
import {
|
|
31
|
+
import { checkClaudeCodeVersionAndPrompt } from './version-checker.mjs';
|
|
32
32
|
|
|
33
33
|
const PROVIDER_PRESETS_URL = "https://pub-0dc3e1677e894f07bbea11b17a29e032.r2.dev/providers.json";
|
|
34
34
|
async function fetchProviderPresets() {
|
|
@@ -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) {
|
package/dist/chunks/menu.mjs
CHANGED
|
@@ -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
|
|
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
|
|
3497
|
-
console.log(ansis.bold
|
|
3498
|
-
console.log(
|
|
3499
|
-
console.log(ansis.bold
|
|
3500
|
-
console.log(ansis.bold
|
|
3501
|
-
console.log(ansis.bold.
|
|
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
|
}
|
package/dist/chunks/package.mjs
CHANGED
package/dist/chunks/update.mjs
CHANGED
|
@@ -8,7 +8,7 @@ import { E as runCodexUpdate } from './codex.mjs';
|
|
|
8
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
|
-
import {
|
|
11
|
+
import { checkClaudeCodeVersionAndPrompt } from './version-checker.mjs';
|
|
12
12
|
import 'node:os';
|
|
13
13
|
import 'pathe';
|
|
14
14
|
import 'node:fs';
|
|
@@ -4,7 +4,225 @@ import * as path from 'node:path';
|
|
|
4
4
|
import process from 'node:process';
|
|
5
5
|
import { promisify } from 'node:util';
|
|
6
6
|
import semver from 'semver';
|
|
7
|
-
import {
|
|
7
|
+
import { findCommandPath, getPlatform, getHomebrewCommandPaths } from './platform.mjs';
|
|
8
|
+
import 'node:os';
|
|
9
|
+
import 'pathe';
|
|
10
|
+
import 'tinyexec';
|
|
11
|
+
|
|
12
|
+
function getHome() {
|
|
13
|
+
return process.env.HOME || process.env.USERPROFILE || "";
|
|
14
|
+
}
|
|
15
|
+
const INSTALLATION_SOURCES = [
|
|
16
|
+
// ==================== macOS Sources ====================
|
|
17
|
+
{
|
|
18
|
+
type: "homebrew-cask",
|
|
19
|
+
name: "Homebrew Cask",
|
|
20
|
+
priority: 100,
|
|
21
|
+
// Highest priority on macOS
|
|
22
|
+
platforms: ["macos"],
|
|
23
|
+
pathPatterns: [
|
|
24
|
+
/\/Caskroom\/claude-code\//,
|
|
25
|
+
/\/opt\/homebrew\/Caskroom\//,
|
|
26
|
+
/\/usr\/local\/Caskroom\//
|
|
27
|
+
],
|
|
28
|
+
commonPaths: [
|
|
29
|
+
"/opt/homebrew/Caskroom/claude-code",
|
|
30
|
+
"/usr/local/Caskroom/claude-code"
|
|
31
|
+
],
|
|
32
|
+
getUpdateCommand: () => ({ command: "brew", args: ["upgrade", "--cask", "claude-code"] }),
|
|
33
|
+
isRecommended: true,
|
|
34
|
+
description: "Official recommended installation method for macOS"
|
|
35
|
+
},
|
|
36
|
+
// ==================== Cross-platform Sources ====================
|
|
37
|
+
{
|
|
38
|
+
type: "curl",
|
|
39
|
+
name: "Official Installer (curl)",
|
|
40
|
+
priority: 90,
|
|
41
|
+
// High priority - official method
|
|
42
|
+
platforms: ["macos", "linux"],
|
|
43
|
+
pathPatterns: [
|
|
44
|
+
// ~/.local/bin/claude (Linux/macOS curl default)
|
|
45
|
+
new RegExp(`${getHome().replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}/\\.local/bin/claude`),
|
|
46
|
+
// ~/.claude/bin/claude (alternative location)
|
|
47
|
+
new RegExp(`${getHome().replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}/\\.claude/`),
|
|
48
|
+
// Generic patterns
|
|
49
|
+
/\.local\/bin\/claude$/,
|
|
50
|
+
/\.claude\/bin\/claude$/,
|
|
51
|
+
/\.claude\/local\/bin\/claude$/
|
|
52
|
+
],
|
|
53
|
+
commonPaths: [
|
|
54
|
+
`${getHome()}/.local/bin/claude`,
|
|
55
|
+
`${getHome()}/.claude/bin/claude`,
|
|
56
|
+
`${getHome()}/.claude/local/bin/claude`
|
|
57
|
+
],
|
|
58
|
+
getUpdateCommand: () => ({
|
|
59
|
+
command: "sh",
|
|
60
|
+
args: ["-c", "curl -fsSL https://claude.ai/install.sh | sh"]
|
|
61
|
+
}),
|
|
62
|
+
isRecommended: true,
|
|
63
|
+
description: "Official curl installer from claude.ai"
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
type: "npm",
|
|
67
|
+
name: "npm Global",
|
|
68
|
+
priority: 50,
|
|
69
|
+
// Medium priority
|
|
70
|
+
platforms: ["macos", "linux", "windows"],
|
|
71
|
+
pathPatterns: [
|
|
72
|
+
/\/node_modules\/@anthropic-ai\/claude-code/,
|
|
73
|
+
/\/npm\//,
|
|
74
|
+
/\/fnm_multishells\//,
|
|
75
|
+
/\/\.nvm\//,
|
|
76
|
+
/\/\.volta\//,
|
|
77
|
+
/\/\.asdf\/installs\/nodejs\//,
|
|
78
|
+
/\/\.nodenv\//,
|
|
79
|
+
/\/\.n\/bin\//
|
|
80
|
+
],
|
|
81
|
+
commonPaths: [
|
|
82
|
+
"/usr/local/bin/claude",
|
|
83
|
+
"/usr/bin/claude",
|
|
84
|
+
`${getHome()}/.npm-global/bin/claude`,
|
|
85
|
+
// Node version manager paths
|
|
86
|
+
`${getHome()}/.nvm/versions/node`,
|
|
87
|
+
`${getHome()}/.fnm/node-versions`,
|
|
88
|
+
`${getHome()}/.volta/bin/claude`,
|
|
89
|
+
`${getHome()}/.asdf/shims/claude`
|
|
90
|
+
],
|
|
91
|
+
getUpdateCommand: () => ({ command: "npm", args: ["update", "-g", "@anthropic-ai/claude-code"] }),
|
|
92
|
+
isRecommended: false,
|
|
93
|
+
description: "npm global installation"
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
type: "npm-homebrew-node",
|
|
97
|
+
name: "npm via Homebrew Node",
|
|
98
|
+
priority: 45,
|
|
99
|
+
// Slightly lower than regular npm
|
|
100
|
+
platforms: ["macos"],
|
|
101
|
+
pathPatterns: [
|
|
102
|
+
/\/Cellar\/node\//,
|
|
103
|
+
/\/opt\/homebrew\/lib\/node_modules\//,
|
|
104
|
+
/\/usr\/local\/lib\/node_modules\//
|
|
105
|
+
],
|
|
106
|
+
commonPaths: [
|
|
107
|
+
"/opt/homebrew/Cellar/node",
|
|
108
|
+
"/usr/local/Cellar/node",
|
|
109
|
+
"/opt/homebrew/lib/node_modules/@anthropic-ai/claude-code",
|
|
110
|
+
"/usr/local/lib/node_modules/@anthropic-ai/claude-code"
|
|
111
|
+
],
|
|
112
|
+
getUpdateCommand: () => ({ command: "npm", args: ["update", "-g", "@anthropic-ai/claude-code"] }),
|
|
113
|
+
isRecommended: false,
|
|
114
|
+
description: "npm installation via Homebrew-managed Node.js"
|
|
115
|
+
},
|
|
116
|
+
// ==================== Future Linux Sources ====================
|
|
117
|
+
{
|
|
118
|
+
type: "snap",
|
|
119
|
+
name: "Snap Package",
|
|
120
|
+
priority: 80,
|
|
121
|
+
platforms: ["linux"],
|
|
122
|
+
pathPatterns: [
|
|
123
|
+
/\/snap\/claude-code\//,
|
|
124
|
+
/\/snap\/bin\/claude/
|
|
125
|
+
],
|
|
126
|
+
commonPaths: [
|
|
127
|
+
"/snap/bin/claude",
|
|
128
|
+
"/snap/claude-code/current/bin/claude"
|
|
129
|
+
],
|
|
130
|
+
getUpdateCommand: () => ({ command: "snap", args: ["refresh", "claude-code"] }),
|
|
131
|
+
isRecommended: false,
|
|
132
|
+
description: "Snap package (future support)"
|
|
133
|
+
},
|
|
134
|
+
{
|
|
135
|
+
type: "flatpak",
|
|
136
|
+
name: "Flatpak",
|
|
137
|
+
priority: 75,
|
|
138
|
+
platforms: ["linux"],
|
|
139
|
+
pathPatterns: [
|
|
140
|
+
/\/flatpak\//,
|
|
141
|
+
/com\.anthropic\.claude/
|
|
142
|
+
],
|
|
143
|
+
commonPaths: [
|
|
144
|
+
`${getHome()}/.local/share/flatpak/exports/bin/com.anthropic.claude`,
|
|
145
|
+
"/var/lib/flatpak/exports/bin/com.anthropic.claude"
|
|
146
|
+
],
|
|
147
|
+
getUpdateCommand: () => ({ command: "flatpak", args: ["update", "com.anthropic.claude"] }),
|
|
148
|
+
isRecommended: false,
|
|
149
|
+
description: "Flatpak package (future support)"
|
|
150
|
+
},
|
|
151
|
+
{
|
|
152
|
+
type: "apt",
|
|
153
|
+
name: "APT Package",
|
|
154
|
+
priority: 85,
|
|
155
|
+
platforms: ["linux"],
|
|
156
|
+
pathPatterns: [
|
|
157
|
+
/\/usr\/bin\/claude$/,
|
|
158
|
+
/\/usr\/local\/bin\/claude$/
|
|
159
|
+
],
|
|
160
|
+
commonPaths: [
|
|
161
|
+
"/usr/bin/claude",
|
|
162
|
+
"/usr/local/bin/claude"
|
|
163
|
+
],
|
|
164
|
+
getUpdateCommand: () => ({ command: "apt", args: ["upgrade", "claude-code"] }),
|
|
165
|
+
isRecommended: false,
|
|
166
|
+
description: "APT package (future support)"
|
|
167
|
+
}
|
|
168
|
+
];
|
|
169
|
+
function detectSourceFromPath(path, platform) {
|
|
170
|
+
const sortedSources = [...INSTALLATION_SOURCES].filter((s) => s.platforms.includes(platform)).sort((a, b) => b.priority - a.priority);
|
|
171
|
+
for (const source of sortedSources) {
|
|
172
|
+
for (const pattern of source.pathPatterns) {
|
|
173
|
+
if (pattern.test(path)) {
|
|
174
|
+
return source;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
return null;
|
|
179
|
+
}
|
|
180
|
+
function getCommonPathsForPlatform(platform) {
|
|
181
|
+
const paths = [];
|
|
182
|
+
for (const source of INSTALLATION_SOURCES) {
|
|
183
|
+
if (source.platforms.includes(platform)) {
|
|
184
|
+
paths.push(...source.commonPaths);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
return [...new Set(paths)];
|
|
188
|
+
}
|
|
189
|
+
function findInstallationByCommonPaths(platform) {
|
|
190
|
+
const sortedSources = [...INSTALLATION_SOURCES].filter((s) => s.platforms.includes(platform)).sort((a, b) => b.priority - a.priority);
|
|
191
|
+
for (const source of sortedSources) {
|
|
192
|
+
for (const commonPath of source.commonPaths) {
|
|
193
|
+
if (nodeFs.existsSync(commonPath)) {
|
|
194
|
+
const stats = nodeFs.statSync(commonPath);
|
|
195
|
+
if (stats.isDirectory()) {
|
|
196
|
+
const possibleBinaries = findClaudeBinaryInDirectory(commonPath);
|
|
197
|
+
if (possibleBinaries.length > 0) {
|
|
198
|
+
return { path: possibleBinaries[0], source };
|
|
199
|
+
}
|
|
200
|
+
} else if (stats.isFile()) {
|
|
201
|
+
return { path: commonPath, source };
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
return null;
|
|
207
|
+
}
|
|
208
|
+
function findClaudeBinaryInDirectory(dir, depth = 0) {
|
|
209
|
+
if (depth > 3)
|
|
210
|
+
return [];
|
|
211
|
+
const results = [];
|
|
212
|
+
try {
|
|
213
|
+
const entries = nodeFs.readdirSync(dir, { withFileTypes: true });
|
|
214
|
+
for (const entry of entries) {
|
|
215
|
+
const fullPath = path.join(dir, entry.name);
|
|
216
|
+
if (entry.isFile() && entry.name === "claude") {
|
|
217
|
+
results.push(fullPath);
|
|
218
|
+
} else if (entry.isDirectory() && !entry.name.startsWith(".")) {
|
|
219
|
+
results.push(...findClaudeBinaryInDirectory(fullPath, depth + 1));
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
} catch {
|
|
223
|
+
}
|
|
224
|
+
return results;
|
|
225
|
+
}
|
|
8
226
|
|
|
9
227
|
const execAsync = promisify(exec);
|
|
10
228
|
async function getInstalledVersion(command, maxRetries = 3) {
|
|
@@ -44,35 +262,64 @@ async function getLatestVersion(packageName, maxRetries = 3) {
|
|
|
44
262
|
return null;
|
|
45
263
|
}
|
|
46
264
|
async function getClaudeCodeInstallationSource() {
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
265
|
+
const platform = getPlatform();
|
|
266
|
+
let commandPath = await findCommandPath("claude");
|
|
267
|
+
if (!commandPath) {
|
|
268
|
+
const commonPaths = getCommonPathsForPlatform(platform);
|
|
269
|
+
for (const path of commonPaths) {
|
|
270
|
+
if (nodeFs.existsSync(path)) {
|
|
271
|
+
try {
|
|
272
|
+
const stats = nodeFs.statSync(path);
|
|
273
|
+
if (stats.isFile()) {
|
|
274
|
+
commandPath = path;
|
|
275
|
+
break;
|
|
276
|
+
}
|
|
277
|
+
} catch {
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
if (!commandPath) {
|
|
282
|
+
const found = findInstallationByCommonPaths(platform);
|
|
283
|
+
if (found) {
|
|
284
|
+
commandPath = found.path;
|
|
285
|
+
}
|
|
286
|
+
}
|
|
54
287
|
}
|
|
55
|
-
const commandPath = await findCommandPath("claude");
|
|
56
288
|
if (!commandPath) {
|
|
57
289
|
return { isHomebrew: false, commandPath: null, source: "not-found" };
|
|
58
290
|
}
|
|
59
|
-
|
|
60
|
-
if (isFromCaskroom) {
|
|
61
|
-
return { isHomebrew: true, commandPath, source: "homebrew-cask" };
|
|
62
|
-
}
|
|
291
|
+
let resolvedPath = commandPath;
|
|
63
292
|
try {
|
|
64
|
-
const { stdout
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
}
|
|
293
|
+
const { stdout } = await execAsync(
|
|
294
|
+
`readlink -f "${commandPath}" 2>/dev/null || realpath "${commandPath}" 2>/dev/null || echo "${commandPath}"`
|
|
295
|
+
);
|
|
296
|
+
resolvedPath = stdout.trim();
|
|
69
297
|
} catch {
|
|
70
298
|
}
|
|
71
|
-
|
|
72
|
-
|
|
299
|
+
const detectedSource = detectSourceFromPath(resolvedPath, platform) || detectSourceFromPath(commandPath, platform);
|
|
300
|
+
if (detectedSource) {
|
|
301
|
+
const sourceType = mapSourceType(detectedSource.type);
|
|
302
|
+
return {
|
|
303
|
+
isHomebrew: detectedSource.type === "homebrew-cask",
|
|
304
|
+
commandPath,
|
|
305
|
+
source: sourceType
|
|
306
|
+
};
|
|
73
307
|
}
|
|
74
308
|
return { isHomebrew: false, commandPath, source: "other" };
|
|
75
309
|
}
|
|
310
|
+
function mapSourceType(type) {
|
|
311
|
+
switch (type) {
|
|
312
|
+
case "homebrew-cask":
|
|
313
|
+
return "homebrew-cask";
|
|
314
|
+
case "npm":
|
|
315
|
+
case "npm-homebrew-node":
|
|
316
|
+
return "npm";
|
|
317
|
+
case "curl":
|
|
318
|
+
return "curl";
|
|
319
|
+
default:
|
|
320
|
+
return "other";
|
|
321
|
+
}
|
|
322
|
+
}
|
|
76
323
|
async function detectAllClaudeCodeInstallations() {
|
|
77
324
|
const installations = [];
|
|
78
325
|
const checkedPaths = /* @__PURE__ */ new Set();
|
|
@@ -286,7 +533,7 @@ async function performNpmRemovalAndActivateHomebrew(_npmInstallation, homebrewIn
|
|
|
286
533
|
const ora = (await import('ora')).default;
|
|
287
534
|
const spinner = ora(i18n.t("installation:removingDuplicateInstallation")).start();
|
|
288
535
|
try {
|
|
289
|
-
const { wrapCommandWithSudo } = await import('
|
|
536
|
+
const { wrapCommandWithSudo } = await import('./platform.mjs');
|
|
290
537
|
const { command, args, usedSudo } = wrapCommandWithSudo("npm", ["uninstall", "-g", "@anthropic-ai/claude-code"]);
|
|
291
538
|
if (usedSudo) {
|
|
292
539
|
spinner.info(i18n.t("installation:usingSudo"));
|
|
@@ -297,7 +544,7 @@ async function performNpmRemovalAndActivateHomebrew(_npmInstallation, homebrewIn
|
|
|
297
544
|
if (homebrewInstallation && !homebrewInstallation.isActive) {
|
|
298
545
|
console.log("");
|
|
299
546
|
console.log(ansis.cyan(`\u{1F517} ${i18n.t("installation:activatingHomebrew")}`));
|
|
300
|
-
const { createHomebrewSymlink } = await import('
|
|
547
|
+
const { createHomebrewSymlink } = await import('./init.mjs').then(function (n) { return n.G; });
|
|
301
548
|
const symlinkResult = await createHomebrewSymlink("claude", homebrewInstallation.path);
|
|
302
549
|
if (symlinkResult.success) {
|
|
303
550
|
console.log(ansis.green(`\u2714 ${i18n.t("installation:symlinkCreated", { path: symlinkResult.symlinkPath || "/usr/local/bin/claude" })}`));
|
|
@@ -321,7 +568,7 @@ async function performNpmRemovalAndActivateHomebrew(_npmInstallation, homebrewIn
|
|
|
321
568
|
}
|
|
322
569
|
}
|
|
323
570
|
async function handleDuplicateInstallations(skipPrompt = false) {
|
|
324
|
-
const { ensureI18nInitialized, format, i18n } = await import('
|
|
571
|
+
const { ensureI18nInitialized, format, i18n } = await import('./index2.mjs');
|
|
325
572
|
const ansis = (await import('ansis')).default;
|
|
326
573
|
ensureI18nInitialized();
|
|
327
574
|
const duplicateInfo = await checkDuplicateInstallations();
|
|
@@ -450,13 +697,28 @@ async function checkClaudeCodeVersion() {
|
|
|
450
697
|
let installationInfo = await getClaudeCodeInstallationSource();
|
|
451
698
|
if (!currentVersion) {
|
|
452
699
|
const installations = await detectAllClaudeCodeInstallations();
|
|
453
|
-
const bestInstall = installations.find((i) => i.source === "homebrew-cask") || installations.find((i) => i.source === "npm") || installations[0];
|
|
700
|
+
const bestInstall = installations.find((i) => i.source === "homebrew-cask") || installations.find((i) => i.source === "npm") || installations.find((i) => i.source === "curl") || installations[0];
|
|
454
701
|
if (bestInstall && bestInstall.version) {
|
|
455
702
|
currentVersion = bestInstall.version;
|
|
703
|
+
let mappedSource;
|
|
704
|
+
switch (bestInstall.source) {
|
|
705
|
+
case "homebrew-cask":
|
|
706
|
+
mappedSource = "homebrew-cask";
|
|
707
|
+
break;
|
|
708
|
+
case "npm":
|
|
709
|
+
case "npm-homebrew-node":
|
|
710
|
+
mappedSource = "npm";
|
|
711
|
+
break;
|
|
712
|
+
case "curl":
|
|
713
|
+
mappedSource = "curl";
|
|
714
|
+
break;
|
|
715
|
+
default:
|
|
716
|
+
mappedSource = "other";
|
|
717
|
+
}
|
|
456
718
|
installationInfo = {
|
|
457
719
|
isHomebrew: bestInstall.source === "homebrew-cask",
|
|
458
720
|
commandPath: bestInstall.path,
|
|
459
|
-
source:
|
|
721
|
+
source: mappedSource
|
|
460
722
|
};
|
|
461
723
|
}
|
|
462
724
|
}
|
|
@@ -495,7 +757,7 @@ async function checkClaudeCodeVersionAndPrompt(skipPrompt = false) {
|
|
|
495
757
|
if (!versionInfo.needsUpdate) {
|
|
496
758
|
return;
|
|
497
759
|
}
|
|
498
|
-
const { updateClaudeCode } = await import('
|
|
760
|
+
const { updateClaudeCode } = await import('./auto-updater.mjs');
|
|
499
761
|
await updateClaudeCode(false, skipPrompt);
|
|
500
762
|
} catch (error) {
|
|
501
763
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
@@ -503,4 +765,4 @@ async function checkClaudeCodeVersionAndPrompt(skipPrompt = false) {
|
|
|
503
765
|
}
|
|
504
766
|
}
|
|
505
767
|
|
|
506
|
-
export { checkClaudeCodeVersion
|
|
768
|
+
export { checkCcrVersion, checkClaudeCodeVersion, checkClaudeCodeVersionAndPrompt, checkCometixLineVersion, checkDuplicateInstallations, compareVersions, detectAllClaudeCodeInstallations, getClaudeCodeInstallationSource, getHomebrewClaudeCodeVersion, getInstalledVersion, getLatestVersion, getSourceDisplayName, handleDuplicateInstallations, shouldUpdate };
|
|
@@ -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",
|
|
@@ -22,5 +22,6 @@
|
|
|
22
22
|
"updateSkipped": "Update skipped",
|
|
23
23
|
"updateSuccess": "{tool} updated successfully!",
|
|
24
24
|
"updateSummary": "Update Summary",
|
|
25
|
-
"updating": "Updating {tool}..."
|
|
25
|
+
"updating": "Updating {tool}...",
|
|
26
|
+
"curlReinstallRequired": "Cannot auto-update curl-installed Claude Code. Please run manually: curl -fsSL https://claude.ai/install.sh | sh"
|
|
26
27
|
}
|
|
@@ -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 代理",
|
|
@@ -22,5 +22,6 @@
|
|
|
22
22
|
"updateSkipped": "跳过更新",
|
|
23
23
|
"updateSuccess": "{tool} 更新成功!",
|
|
24
24
|
"updateSummary": "更新摘要",
|
|
25
|
-
"updating": "正在更新 {tool}..."
|
|
25
|
+
"updating": "正在更新 {tool}...",
|
|
26
|
+
"curlReinstallRequired": "无法自动更新 curl 安装的 Claude Code。请手动运行: curl -fsSL https://claude.ai/install.sh | sh"
|
|
26
27
|
}
|
package/dist/index.mjs
CHANGED
|
@@ -39,7 +39,7 @@ import 'node:util';
|
|
|
39
39
|
import './chunks/auto-updater.mjs';
|
|
40
40
|
import 'ora';
|
|
41
41
|
import 'tinyexec';
|
|
42
|
-
import './
|
|
42
|
+
import './chunks/version-checker.mjs';
|
|
43
43
|
import 'node:path';
|
|
44
44
|
import 'semver';
|
|
45
45
|
import './shared/ccjk.CUdzQluX.mjs';
|
package/package.json
CHANGED