ccem 1.8.1 → 2.0.0-beta
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/dist/index.js +2849 -24
- package/package.json +22 -15
- package/scripts/convert-ansi-to-ts.js +55 -0
- package/scripts/generate-logo.sh +63 -0
- package/scripts/migrate.js +44 -0
- package/README.md +0 -536
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ccem",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0-beta",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Claude Code Environment Manager",
|
|
6
6
|
"author": {
|
|
@@ -10,27 +10,24 @@
|
|
|
10
10
|
},
|
|
11
11
|
"files": [
|
|
12
12
|
"dist",
|
|
13
|
-
"model-prices.json"
|
|
13
|
+
"model-prices.json",
|
|
14
|
+
"scripts"
|
|
14
15
|
],
|
|
15
16
|
"bin": {
|
|
16
17
|
"ccem": "./dist/index.js"
|
|
17
18
|
},
|
|
18
19
|
"scripts": {
|
|
20
|
+
"generate-logo": "bash scripts/generate-logo.sh",
|
|
19
21
|
"build": "tsup",
|
|
20
22
|
"dev": "tsup --watch",
|
|
21
|
-
"start": "node dist/index.js"
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
"
|
|
25
|
-
"
|
|
26
|
-
"@types/react": "^19.2.9",
|
|
27
|
-
"asciify-image": "^0.1.10",
|
|
28
|
-
"sharp": "^0.34.5",
|
|
29
|
-
"terminal-image": "^4.2.0",
|
|
30
|
-
"tsup": "^8.0.2",
|
|
31
|
-
"typescript": "^5.3.3"
|
|
23
|
+
"start": "node dist/index.js",
|
|
24
|
+
"postinstall": "node ./scripts/migrate.js",
|
|
25
|
+
"test": "vitest",
|
|
26
|
+
"test:run": "vitest run",
|
|
27
|
+
"test:coverage": "vitest run --coverage"
|
|
32
28
|
},
|
|
33
29
|
"dependencies": {
|
|
30
|
+
"@ccem/core": "workspace:*",
|
|
34
31
|
"chalk": "^4.1.2",
|
|
35
32
|
"cli-table3": "^0.6.3",
|
|
36
33
|
"commander": "^12.0.0",
|
|
@@ -38,7 +35,17 @@
|
|
|
38
35
|
"ink": "^6.6.0",
|
|
39
36
|
"ink-select-input": "^6.2.0",
|
|
40
37
|
"inquirer": "^8.2.6",
|
|
41
|
-
"react": "^19.2.3"
|
|
38
|
+
"react": "^19.2.3",
|
|
39
|
+
"terminal-image": "^4.2.0"
|
|
42
40
|
},
|
|
43
|
-
"
|
|
41
|
+
"devDependencies": {
|
|
42
|
+
"@types/inquirer": "^9.0.7",
|
|
43
|
+
"@types/node": "^20.11.24",
|
|
44
|
+
"@types/react": "^19.2.9",
|
|
45
|
+
"@vitest/coverage-v8": "^4.0.18",
|
|
46
|
+
"asciify-image": "^0.1.10",
|
|
47
|
+
"tsup": "^8.0.2",
|
|
48
|
+
"typescript": "^5.3.3",
|
|
49
|
+
"vitest": "^4.0.18"
|
|
50
|
+
}
|
|
44
51
|
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import fs from 'fs';
|
|
3
|
+
import path from 'path';
|
|
4
|
+
import { fileURLToPath } from 'url';
|
|
5
|
+
|
|
6
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
7
|
+
|
|
8
|
+
const variants = [
|
|
9
|
+
{ name: 'LOGO_MINIMAL', file: '.tmp/logo-minimal.txt', width: 8 },
|
|
10
|
+
{ name: 'LOGO_COMPACT', file: '.tmp/logo-compact.txt', width: 12 },
|
|
11
|
+
{ name: 'LOGO_FULL', file: '.tmp/logo-full.txt', width: 19 },
|
|
12
|
+
];
|
|
13
|
+
|
|
14
|
+
let output = `// Auto-generated by scripts/generate-logo.sh
|
|
15
|
+
// DO NOT EDIT MANUALLY - Regenerate with: pnpm run generate-logo
|
|
16
|
+
|
|
17
|
+
export interface LogoVariant {
|
|
18
|
+
width: number;
|
|
19
|
+
height: number;
|
|
20
|
+
ansi: string;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
`;
|
|
24
|
+
|
|
25
|
+
for (const variant of variants) {
|
|
26
|
+
const filePath = path.join(__dirname, '..', variant.file);
|
|
27
|
+
|
|
28
|
+
if (!fs.existsSync(filePath)) {
|
|
29
|
+
console.error(`❌ Error: ${variant.file} not found`);
|
|
30
|
+
process.exit(1);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const ansi = fs.readFileSync(filePath, 'utf-8');
|
|
34
|
+
const lines = ansi.split('\n').filter(l => l.trim());
|
|
35
|
+
const height = lines.length;
|
|
36
|
+
|
|
37
|
+
// Escape backslashes, backticks, and dollar signs for template literal
|
|
38
|
+
const escaped = ansi
|
|
39
|
+
.replace(/\\/g, '\\\\')
|
|
40
|
+
.replace(/`/g, '\\`')
|
|
41
|
+
.replace(/\$/g, '\\$');
|
|
42
|
+
|
|
43
|
+
output += `export const ${variant.name}: LogoVariant = {
|
|
44
|
+
width: ${variant.width},
|
|
45
|
+
height: ${height},
|
|
46
|
+
ansi: \`${escaped}\`
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
`;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const outputPath = path.join(__dirname, '..', 'src', 'logo-generated.ts');
|
|
53
|
+
fs.writeFileSync(outputPath, output);
|
|
54
|
+
|
|
55
|
+
console.log('✓ Generated logo variants');
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -e
|
|
3
|
+
|
|
4
|
+
# Generate logo variants from logo.png using chafa
|
|
5
|
+
# This script is run during prebuild to generate logo-generated.ts
|
|
6
|
+
|
|
7
|
+
echo "🎨 Generating logo variants..."
|
|
8
|
+
|
|
9
|
+
# Check dependencies
|
|
10
|
+
if ! command -v sips &> /dev/null; then
|
|
11
|
+
echo "❌ Error: sips not found (macOS only)"
|
|
12
|
+
exit 1
|
|
13
|
+
fi
|
|
14
|
+
|
|
15
|
+
if ! command -v chafa &> /dev/null; then
|
|
16
|
+
echo "❌ Error: chafa not found. Install with: brew install chafa"
|
|
17
|
+
exit 1
|
|
18
|
+
fi
|
|
19
|
+
|
|
20
|
+
# Navigate to CLI directory
|
|
21
|
+
cd "$(dirname "$0")/.."
|
|
22
|
+
|
|
23
|
+
# Check if logo.png exists in project root
|
|
24
|
+
if [ ! -f "../../logo.png" ]; then
|
|
25
|
+
echo "❌ Error: logo.png not found in project root"
|
|
26
|
+
exit 1
|
|
27
|
+
fi
|
|
28
|
+
|
|
29
|
+
# Create temp directory
|
|
30
|
+
mkdir -p .tmp
|
|
31
|
+
|
|
32
|
+
# Step 1: Scale logo to different sizes using sips
|
|
33
|
+
echo " 📐 Scaling images..."
|
|
34
|
+
sips -z 64 64 ../../logo.png --out .tmp/logo-64.png > /dev/null 2>&1
|
|
35
|
+
sips -z 128 128 ../../logo.png --out .tmp/logo-128.png > /dev/null 2>&1
|
|
36
|
+
sips -z 192 192 ../../logo.png --out .tmp/logo-192.png > /dev/null 2>&1
|
|
37
|
+
|
|
38
|
+
# Step 2: Generate ANSI strings using chafa
|
|
39
|
+
echo " 🎨 Converting to ANSI..."
|
|
40
|
+
|
|
41
|
+
# 使用更大的尺寸生成,然后以 C 字母为中心截取
|
|
42
|
+
|
|
43
|
+
# MINIMAL (8 chars wide) - 生成 20 行,以中心截取 5 行
|
|
44
|
+
chafa --size=20x --format=symbols --symbols=block .tmp/logo-64.png > .tmp/logo-minimal-full.txt
|
|
45
|
+
tail -n +7 .tmp/logo-minimal-full.txt | head -n 5 > .tmp/logo-minimal.txt
|
|
46
|
+
|
|
47
|
+
# COMPACT (12 chars wide) - 生成 24 行,以中心截取 7 行
|
|
48
|
+
chafa --size=24x --format=symbols --symbols=block .tmp/logo-128.png > .tmp/logo-compact-full.txt
|
|
49
|
+
tail -n +8 .tmp/logo-compact-full.txt | head -n 7 > .tmp/logo-compact.txt
|
|
50
|
+
|
|
51
|
+
# FULL (19 chars wide) - 生成 30 行,以 C 字母为中心截取第 4-12 行 (9 行,减少底部 2 行)
|
|
52
|
+
chafa --size=30x --format=symbols --symbols=block .tmp/logo-192.png > .tmp/logo-full-full.txt
|
|
53
|
+
tail -n +4 .tmp/logo-full-full.txt | head -n 9 > .tmp/logo-full.txt
|
|
54
|
+
|
|
55
|
+
# Step 3: Convert ANSI to TypeScript
|
|
56
|
+
echo " 📝 Generating TypeScript..."
|
|
57
|
+
node scripts/convert-ansi-to-ts.js
|
|
58
|
+
|
|
59
|
+
# Step 4: Cleanup
|
|
60
|
+
echo " 🧹 Cleaning up..."
|
|
61
|
+
rm -rf .tmp
|
|
62
|
+
|
|
63
|
+
echo "✅ Logo variants generated successfully"
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import fs from 'fs';
|
|
4
|
+
import path from 'path';
|
|
5
|
+
import os from 'os';
|
|
6
|
+
|
|
7
|
+
const home = os.homedir();
|
|
8
|
+
|
|
9
|
+
// 新配置路径
|
|
10
|
+
const newConfigDir = path.join(home, '.ccem');
|
|
11
|
+
const newConfigPath = path.join(newConfigDir, 'config.json');
|
|
12
|
+
|
|
13
|
+
// 旧配置路径
|
|
14
|
+
const legacyConfigPath = process.platform === 'darwin'
|
|
15
|
+
? path.join(home, 'Library', 'Preferences', 'claude-code-env-manager-nodejs', 'config.json')
|
|
16
|
+
: path.join(home, '.config', 'claude-code-env-manager-nodejs', 'config.json');
|
|
17
|
+
|
|
18
|
+
function migrate() {
|
|
19
|
+
// 如果新配置已存在,跳过迁移
|
|
20
|
+
if (fs.existsSync(newConfigPath)) {
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// 如果旧配置不存在,跳过迁移
|
|
25
|
+
if (!fs.existsSync(legacyConfigPath)) {
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
try {
|
|
30
|
+
// 确保新目录存在
|
|
31
|
+
if (!fs.existsSync(newConfigDir)) {
|
|
32
|
+
fs.mkdirSync(newConfigDir, { recursive: true });
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// 复制配置文件
|
|
36
|
+
fs.copyFileSync(legacyConfigPath, newConfigPath);
|
|
37
|
+
console.log('CCEM: 配置已迁移到 ~/.ccem/');
|
|
38
|
+
} catch (err) {
|
|
39
|
+
// 静默失败,不阻塞安装
|
|
40
|
+
console.warn('CCEM: 配置迁移失败,请手动运行 ccem setup migrate');
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
migrate();
|