@42ailab/42cc 0.2.1 → 0.3.9
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 +40 -63
- package/bin/42cc.js +166 -105
- package/package.json +24 -23
- package/assets/.gitkeep +0 -0
- package/assets/42cc.dmg +0 -0
- package/assets/42cc.exe +0 -0
- package/index.js +0 -5
- package/scripts/install.js +0 -252
package/README.md
CHANGED
|
@@ -1,92 +1,69 @@
|
|
|
1
1
|
# 42cc
|
|
2
2
|
|
|
3
|
-
Claude Code
|
|
3
|
+
Claude Code model configuration tool - A simple tray application for managing LLM model settings.
|
|
4
4
|
|
|
5
|
-
##
|
|
6
|
-
|
|
7
|
-
### npm
|
|
8
|
-
|
|
9
|
-
```bash
|
|
10
|
-
npm install -g @42ailab/42cc
|
|
11
|
-
```
|
|
12
|
-
|
|
13
|
-
### bun
|
|
5
|
+
## Installation
|
|
14
6
|
|
|
15
7
|
```bash
|
|
16
|
-
|
|
17
|
-
|
|
8
|
+
# Using bun (recommended)
|
|
9
|
+
bun add -g @42ailab/42cc
|
|
18
10
|
|
|
19
|
-
|
|
11
|
+
# Using npm
|
|
12
|
+
npm install -g @42ailab/42cc
|
|
20
13
|
|
|
21
|
-
|
|
22
|
-
# yarn
|
|
14
|
+
# Using yarn
|
|
23
15
|
yarn global add @42ailab/42cc
|
|
24
16
|
|
|
25
|
-
# pnpm
|
|
17
|
+
# Using pnpm
|
|
26
18
|
pnpm add -g @42ailab/42cc
|
|
27
19
|
```
|
|
28
20
|
|
|
29
|
-
##
|
|
30
|
-
|
|
31
|
-
安装完成后,应用会自动安装并启动。安装包已内置在 npm 包中,无需额外下载。
|
|
21
|
+
## Usage
|
|
32
22
|
|
|
33
|
-
|
|
23
|
+
```bash
|
|
24
|
+
# Start the tray application
|
|
25
|
+
42cc
|
|
34
26
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
- 下次可从 Launchpad 或访达搜索 "42cc" 启动
|
|
27
|
+
# Show version
|
|
28
|
+
42cc --version
|
|
38
29
|
|
|
39
|
-
|
|
30
|
+
# Show help
|
|
31
|
+
42cc --help
|
|
32
|
+
```
|
|
40
33
|
|
|
41
|
-
|
|
42
|
-
- 自动创建开始菜单快捷方式
|
|
43
|
-
- 自动启动应用
|
|
44
|
-
- 下次可从开始菜单搜索 "42cc" 启动
|
|
34
|
+
## Supported Platforms
|
|
45
35
|
|
|
46
|
-
|
|
36
|
+
| Platform | Architecture | Status |
|
|
37
|
+
|----------|--------------|--------|
|
|
38
|
+
| macOS | ARM64 (Apple Silicon) | Supported |
|
|
39
|
+
| macOS | x64 (Intel) | Supported |
|
|
40
|
+
| Windows | x64 | Supported |
|
|
47
41
|
|
|
48
|
-
|
|
49
|
-
- **Windows**: Windows 10 或更高
|
|
50
|
-
- **Node.js**: 14.0.0 或更高
|
|
42
|
+
## How It Works
|
|
51
43
|
|
|
52
|
-
|
|
44
|
+
This package uses platform-specific optional dependencies to deliver the correct binary for your system:
|
|
53
45
|
|
|
54
|
-
-
|
|
55
|
-
-
|
|
56
|
-
- 安装过程中可能需要管理员权限
|
|
46
|
+
- `@42ailab/42cc-darwin-universal` - macOS Universal Binary (ARM64 + x64)
|
|
47
|
+
- `@42ailab/42cc-win32-x64` - Windows x64
|
|
57
48
|
|
|
58
|
-
|
|
49
|
+
When you install `@42ailab/42cc`, your package manager automatically downloads only the binary for your platform.
|
|
59
50
|
|
|
60
|
-
|
|
51
|
+
## Uninstall
|
|
61
52
|
|
|
62
53
|
```bash
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
```
|
|
66
|
-
|
|
67
|
-
### 直接下载
|
|
68
|
-
|
|
69
|
-
访问 [https://get.42plugin.com/42cc/](https://get.42plugin.com/42cc/) 下载安装包。
|
|
54
|
+
# Using bun
|
|
55
|
+
bun remove -g @42ailab/42cc
|
|
70
56
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
- 选择模型供应商
|
|
76
|
-
- 输入 API 密钥
|
|
77
|
-
- 一键完成配置
|
|
78
|
-
|
|
79
|
-
支持的模型供应商:
|
|
80
|
-
- GLM (智谱)
|
|
81
|
-
- MiniMax
|
|
82
|
-
- Anthropic 官方
|
|
83
|
-
- 自定义供应商
|
|
57
|
+
# Using npm
|
|
58
|
+
npm uninstall -g @42ailab/42cc
|
|
59
|
+
```
|
|
84
60
|
|
|
85
|
-
##
|
|
61
|
+
## Links
|
|
86
62
|
|
|
87
|
-
-
|
|
88
|
-
-
|
|
63
|
+
- Homepage: https://42cc.42ailab.com
|
|
64
|
+
- Issues: https://cnb.cool/42ailab/42plugin/meta/-/issues
|
|
65
|
+
- Repository: https://cnb.cool/42ailab/42plugin/42cc
|
|
89
66
|
|
|
90
|
-
##
|
|
67
|
+
## License
|
|
91
68
|
|
|
92
|
-
Proprietary
|
|
69
|
+
Proprietary - 42ailab
|
package/bin/42cc.js
CHANGED
|
@@ -1,134 +1,195 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
3
|
+
/**
|
|
4
|
+
* 42cc CLI Launcher
|
|
5
|
+
*
|
|
6
|
+
* Claude Code model configuration tool - CLI launcher for the 42cc tray application.
|
|
7
|
+
* Uses platform-specific packages via optionalDependencies for optimal installation.
|
|
8
|
+
*
|
|
9
|
+
* Usage:
|
|
10
|
+
* 42cc - Start the tray application
|
|
11
|
+
* 42cc --version - Show version
|
|
12
|
+
* 42cc --help - Show help
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
const { spawn } = require("child_process");
|
|
16
|
+
const path = require("path");
|
|
17
|
+
const fs = require("fs");
|
|
18
|
+
|
|
19
|
+
// =============================================================================
|
|
20
|
+
// Constants
|
|
21
|
+
// =============================================================================
|
|
22
|
+
|
|
23
|
+
const VERSION = require("../package.json").version;
|
|
24
|
+
|
|
25
|
+
// Platform to package mapping
|
|
26
|
+
const PLATFORM_PACKAGES = {
|
|
27
|
+
"darwin-arm64": "@42ailab/42cc-darwin-universal",
|
|
28
|
+
"darwin-x64": "@42ailab/42cc-darwin-universal",
|
|
29
|
+
"win32-x64": "@42ailab/42cc-win32-x64",
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
// =============================================================================
|
|
33
|
+
// Console Output
|
|
34
|
+
// =============================================================================
|
|
35
|
+
|
|
36
|
+
const colors = {
|
|
37
|
+
reset: "\x1b[0m",
|
|
38
|
+
green: "\x1b[32m",
|
|
39
|
+
yellow: "\x1b[33m",
|
|
40
|
+
red: "\x1b[31m",
|
|
41
|
+
dim: "\x1b[2m",
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
function log(msg, color = "reset") {
|
|
45
|
+
console.log(`${colors[color]}${msg}${colors.reset}`);
|
|
46
|
+
}
|
|
14
47
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
42cc --version 显示版本信息
|
|
19
|
-
42cc --update 检查并更新到最新版本
|
|
48
|
+
function logError(msg) {
|
|
49
|
+
console.error(`${colors.red}${msg}${colors.reset}`);
|
|
50
|
+
}
|
|
20
51
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
52
|
+
// =============================================================================
|
|
53
|
+
// Platform Detection
|
|
54
|
+
// =============================================================================
|
|
24
55
|
|
|
25
|
-
|
|
26
|
-
|
|
56
|
+
function getPlatformKey() {
|
|
57
|
+
return `${process.platform}-${process.arch}`;
|
|
27
58
|
}
|
|
28
59
|
|
|
29
|
-
function
|
|
30
|
-
|
|
31
|
-
|
|
60
|
+
function getPackageDir(pkgName) {
|
|
61
|
+
try {
|
|
62
|
+
const pkgPath = require.resolve(`${pkgName}/package.json`);
|
|
63
|
+
return path.dirname(pkgPath);
|
|
64
|
+
} catch {
|
|
65
|
+
return null;
|
|
66
|
+
}
|
|
32
67
|
}
|
|
33
68
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
69
|
+
// =============================================================================
|
|
70
|
+
// Launch Application
|
|
71
|
+
// =============================================================================
|
|
72
|
+
|
|
73
|
+
function launchApp() {
|
|
74
|
+
const platformKey = getPlatformKey();
|
|
75
|
+
const pkgName = PLATFORM_PACKAGES[platformKey];
|
|
76
|
+
|
|
77
|
+
if (!pkgName) {
|
|
78
|
+
logError(`Unsupported platform: ${platformKey}`);
|
|
79
|
+
logError("");
|
|
80
|
+
logError("42cc supports:");
|
|
81
|
+
logError(" - macOS (ARM64 / x64)");
|
|
82
|
+
logError(" - Windows (x64)");
|
|
48
83
|
process.exit(1);
|
|
49
84
|
}
|
|
50
|
-
}
|
|
51
85
|
|
|
52
|
-
|
|
53
|
-
function getLocalVersion() {
|
|
54
|
-
const homeDir = process.env.HOME || process.env.USERPROFILE;
|
|
86
|
+
const pkgDir = getPackageDir(pkgName);
|
|
55
87
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
88
|
+
if (!pkgDir) {
|
|
89
|
+
logError(`Platform package not found: ${pkgName}`);
|
|
90
|
+
logError("");
|
|
91
|
+
logError("This may be a packaging issue. Try reinstalling:");
|
|
92
|
+
logError(" bun remove -g @42ailab/42cc && bun add -g @42ailab/42cc");
|
|
93
|
+
logError(" # or");
|
|
94
|
+
logError(" npm uninstall -g @42ailab/42cc && npm install -g @42ailab/42cc");
|
|
95
|
+
process.exit(1);
|
|
61
96
|
}
|
|
62
97
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
98
|
+
if (process.platform === "darwin") {
|
|
99
|
+
// macOS: Use 'open' to launch .app bundle
|
|
100
|
+
// This ensures Info.plist settings (LSUIElement, etc.) are respected
|
|
101
|
+
const appPath = path.join(pkgDir, "42cc.app");
|
|
102
|
+
|
|
103
|
+
if (!fs.existsSync(appPath)) {
|
|
104
|
+
logError(`Application not found: ${appPath}`);
|
|
105
|
+
process.exit(1);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
const child = spawn("open", ["-a", appPath], {
|
|
109
|
+
detached: true,
|
|
110
|
+
stdio: "ignore",
|
|
111
|
+
});
|
|
112
|
+
child.unref();
|
|
113
|
+
|
|
114
|
+
log("42cc started", "green");
|
|
115
|
+
} else if (process.platform === "win32") {
|
|
116
|
+
// Windows: Launch exe with hidden console
|
|
117
|
+
const exePath = path.join(pkgDir, "bin", "42cc.exe");
|
|
118
|
+
|
|
119
|
+
if (!fs.existsSync(exePath)) {
|
|
120
|
+
logError(`Executable not found: ${exePath}`);
|
|
121
|
+
process.exit(1);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
const child = spawn(exePath, [], {
|
|
125
|
+
detached: true,
|
|
126
|
+
stdio: "ignore",
|
|
127
|
+
windowsHide: true, // Hide console window flash
|
|
128
|
+
});
|
|
129
|
+
child.unref();
|
|
130
|
+
|
|
131
|
+
log("42cc started", "green");
|
|
67
132
|
}
|
|
133
|
+
|
|
134
|
+
process.exit(0);
|
|
68
135
|
}
|
|
69
136
|
|
|
70
|
-
//
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
reject(new Error(`HTTP 请求失败: ${res.statusCode}`));
|
|
77
|
-
return;
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
let data = '';
|
|
81
|
-
res.on('data', (chunk) => data += chunk);
|
|
82
|
-
res.on('end', () => {
|
|
83
|
-
try {
|
|
84
|
-
const json = JSON.parse(data);
|
|
85
|
-
resolve(json.version);
|
|
86
|
-
} catch (e) {
|
|
87
|
-
reject(new Error('解析版本信息失败'));
|
|
88
|
-
}
|
|
89
|
-
});
|
|
90
|
-
}).on('error', (err) => {
|
|
91
|
-
reject(new Error(`网络请求失败: ${err.message}`));
|
|
92
|
-
});
|
|
93
|
-
});
|
|
137
|
+
// =============================================================================
|
|
138
|
+
// Commands
|
|
139
|
+
// =============================================================================
|
|
140
|
+
|
|
141
|
+
function showVersion() {
|
|
142
|
+
console.log(VERSION);
|
|
94
143
|
}
|
|
95
144
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
145
|
+
function showHelp() {
|
|
146
|
+
console.log(`
|
|
147
|
+
42cc - Claude Code Model Configuration Tool
|
|
99
148
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
149
|
+
Usage:
|
|
150
|
+
42cc Start the tray application
|
|
151
|
+
42cc --version Show version information
|
|
152
|
+
42cc --help Show this help message
|
|
103
153
|
|
|
104
|
-
|
|
105
|
-
|
|
154
|
+
Installation:
|
|
155
|
+
bun add -g @42ailab/42cc
|
|
156
|
+
# or
|
|
157
|
+
npm install -g @42ailab/42cc
|
|
106
158
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
159
|
+
Uninstall:
|
|
160
|
+
bun remove -g @42ailab/42cc
|
|
161
|
+
# or
|
|
162
|
+
npm uninstall -g @42ailab/42cc
|
|
111
163
|
|
|
112
|
-
|
|
164
|
+
Supported Platforms:
|
|
165
|
+
- macOS (ARM64 / x64) - Universal Binary
|
|
166
|
+
- Windows (x64)
|
|
113
167
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
168
|
+
More info: https://42cc.42ailab.com
|
|
169
|
+
`);
|
|
170
|
+
}
|
|
117
171
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
172
|
+
// =============================================================================
|
|
173
|
+
// Main
|
|
174
|
+
// =============================================================================
|
|
175
|
+
|
|
176
|
+
function main() {
|
|
177
|
+
const args = process.argv.slice(2);
|
|
178
|
+
const cmd = args[0];
|
|
179
|
+
|
|
180
|
+
switch (cmd) {
|
|
181
|
+
case "--version":
|
|
182
|
+
case "-v":
|
|
183
|
+
showVersion();
|
|
184
|
+
break;
|
|
185
|
+
case "--help":
|
|
186
|
+
case "-h":
|
|
187
|
+
showHelp();
|
|
188
|
+
break;
|
|
189
|
+
default:
|
|
190
|
+
launchApp();
|
|
191
|
+
break;
|
|
121
192
|
}
|
|
122
193
|
}
|
|
123
194
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
if (arg === '--help' || arg === '-h') {
|
|
127
|
-
showHelp();
|
|
128
|
-
} else if (arg === '--version' || arg === '-v') {
|
|
129
|
-
getVersion();
|
|
130
|
-
} else if (arg === '--update' || arg === '-u') {
|
|
131
|
-
checkAndUpdate();
|
|
132
|
-
} else {
|
|
133
|
-
launch();
|
|
134
|
-
}
|
|
195
|
+
main();
|
package/package.json
CHANGED
|
@@ -1,45 +1,46 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@42ailab/42cc",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "Claude Code model configuration tool -
|
|
5
|
-
"main": "index.js",
|
|
3
|
+
"version": "0.3.9",
|
|
4
|
+
"description": "Claude Code model configuration tool - CLI launcher for the 42cc tray application",
|
|
6
5
|
"bin": {
|
|
7
6
|
"42cc": "./bin/42cc.js"
|
|
8
7
|
},
|
|
9
|
-
"
|
|
10
|
-
"
|
|
11
|
-
"
|
|
8
|
+
"files": [
|
|
9
|
+
"bin/",
|
|
10
|
+
"README.md"
|
|
11
|
+
],
|
|
12
|
+
"optionalDependencies": {
|
|
13
|
+
"@42ailab/42cc-darwin-universal": "0.3.9",
|
|
14
|
+
"@42ailab/42cc-win32-x64": "0.3.9"
|
|
15
|
+
},
|
|
16
|
+
"os": [
|
|
17
|
+
"darwin",
|
|
18
|
+
"win32"
|
|
19
|
+
],
|
|
20
|
+
"engines": {
|
|
21
|
+
"node": ">=14.0.0"
|
|
12
22
|
},
|
|
13
23
|
"keywords": [
|
|
14
24
|
"claude-code",
|
|
25
|
+
"claude",
|
|
15
26
|
"ai",
|
|
16
27
|
"model-configuration",
|
|
17
28
|
"42plugin",
|
|
18
|
-
"42ailab"
|
|
29
|
+
"42ailab",
|
|
30
|
+
"tray-app",
|
|
31
|
+
"cli"
|
|
19
32
|
],
|
|
20
33
|
"author": "42ailab <email@huoshuiai.com>",
|
|
21
34
|
"license": "Proprietary",
|
|
22
35
|
"homepage": "https://42cc.42ailab.com",
|
|
23
36
|
"repository": {
|
|
24
37
|
"type": "git",
|
|
25
|
-
"url": "https://
|
|
26
|
-
"directory": "npm-package"
|
|
38
|
+
"url": "https://cnb.cool/42ailab/42plugin/42cc"
|
|
27
39
|
},
|
|
28
40
|
"bugs": {
|
|
29
41
|
"url": "https://cnb.cool/42ailab/42plugin/meta/-/issues"
|
|
30
42
|
},
|
|
31
|
-
"
|
|
32
|
-
"
|
|
33
|
-
}
|
|
34
|
-
"os": [
|
|
35
|
-
"darwin",
|
|
36
|
-
"win32"
|
|
37
|
-
],
|
|
38
|
-
"files": [
|
|
39
|
-
"bin/",
|
|
40
|
-
"scripts/install.js",
|
|
41
|
-
"assets/",
|
|
42
|
-
"index.js",
|
|
43
|
-
"README.md"
|
|
44
|
-
]
|
|
43
|
+
"publishConfig": {
|
|
44
|
+
"access": "public"
|
|
45
|
+
}
|
|
45
46
|
}
|
package/assets/.gitkeep
DELETED
|
File without changes
|
package/assets/42cc.dmg
DELETED
|
Binary file
|
package/assets/42cc.exe
DELETED
|
Binary file
|
package/index.js
DELETED
package/scripts/install.js
DELETED
|
@@ -1,252 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
const fs = require('fs');
|
|
4
|
-
const path = require('path');
|
|
5
|
-
const { execSync } = require('child_process');
|
|
6
|
-
|
|
7
|
-
const ASSETS_DIR = path.join(__dirname, '..', 'assets');
|
|
8
|
-
const APP_VERSION = require('../package.json').version;
|
|
9
|
-
|
|
10
|
-
// 颜色输出
|
|
11
|
-
const colors = {
|
|
12
|
-
reset: '\x1b[0m',
|
|
13
|
-
green: '\x1b[32m',
|
|
14
|
-
yellow: '\x1b[33m',
|
|
15
|
-
blue: '\x1b[34m',
|
|
16
|
-
red: '\x1b[31m'
|
|
17
|
-
};
|
|
18
|
-
|
|
19
|
-
function log(msg, color = 'reset') {
|
|
20
|
-
console.log(`${colors[color]}${msg}${colors.reset}`);
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
function getPlatform() {
|
|
24
|
-
const platform = process.platform;
|
|
25
|
-
if (platform === 'darwin') return 'macos';
|
|
26
|
-
if (platform === 'win32') return 'windows';
|
|
27
|
-
throw new Error(`不支持的平台: ${platform}`);
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
// 保存已安装的版本号到本地文件
|
|
31
|
-
function saveInstalledVersion(version) {
|
|
32
|
-
const homeDir = process.env.HOME || process.env.USERPROFILE;
|
|
33
|
-
const platform = process.platform;
|
|
34
|
-
|
|
35
|
-
let versionDir;
|
|
36
|
-
if (platform === 'darwin') {
|
|
37
|
-
versionDir = path.join(homeDir, '.42cc');
|
|
38
|
-
} else {
|
|
39
|
-
versionDir = path.join(process.env.APPDATA || homeDir, '42cc');
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
const versionFile = path.join(versionDir, 'version');
|
|
43
|
-
|
|
44
|
-
try {
|
|
45
|
-
if (!fs.existsSync(versionDir)) {
|
|
46
|
-
fs.mkdirSync(versionDir, { recursive: true });
|
|
47
|
-
}
|
|
48
|
-
fs.writeFileSync(versionFile, version, 'utf8');
|
|
49
|
-
} catch (e) {
|
|
50
|
-
// 写入版本文件失败不影响安装流程
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
// macOS 自动安装
|
|
55
|
-
async function autoInstallMacOS() {
|
|
56
|
-
const dmgPath = path.join(ASSETS_DIR, '42cc.dmg');
|
|
57
|
-
|
|
58
|
-
if (!fs.existsSync(dmgPath)) {
|
|
59
|
-
throw new Error('未找到安装文件: ' + dmgPath);
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
log('\n开始安装...', 'yellow');
|
|
63
|
-
|
|
64
|
-
try {
|
|
65
|
-
// 1. 挂载 DMG
|
|
66
|
-
log('1. 挂载 DMG...', 'blue');
|
|
67
|
-
execSync(`hdiutil attach "${dmgPath}" -nobrowse -quiet`);
|
|
68
|
-
|
|
69
|
-
// 2. 找到挂载点
|
|
70
|
-
const volumes = fs.readdirSync('/Volumes');
|
|
71
|
-
const mountPoint = volumes.find(v => v.includes('42cc'));
|
|
72
|
-
if (!mountPoint) {
|
|
73
|
-
throw new Error('未找到挂载点');
|
|
74
|
-
}
|
|
75
|
-
const mountPath = `/Volumes/${mountPoint}`;
|
|
76
|
-
|
|
77
|
-
// 3. 复制到 Applications
|
|
78
|
-
log('2. 安装到 Applications...', 'blue');
|
|
79
|
-
const appPath = `${mountPath}/42cc.app`;
|
|
80
|
-
const targetPath = '/Applications/42cc.app';
|
|
81
|
-
|
|
82
|
-
// 检查是否已存在
|
|
83
|
-
if (fs.existsSync(targetPath)) {
|
|
84
|
-
log('检测到已安装的版本,将替换...', 'yellow');
|
|
85
|
-
try {
|
|
86
|
-
execSync(`rm -rf "${targetPath}"`);
|
|
87
|
-
} catch (e) {
|
|
88
|
-
log('需要管理员权限删除旧版本,请输入密码:', 'yellow');
|
|
89
|
-
try {
|
|
90
|
-
execSync(`sudo rm -rf "${targetPath}"`);
|
|
91
|
-
} catch (sudoErr) {
|
|
92
|
-
throw new Error('删除旧版本失败,请手动删除 /Applications/42cc.app 后重试');
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
// 复制应用
|
|
98
|
-
try {
|
|
99
|
-
execSync(`cp -R "${appPath}" /Applications/`);
|
|
100
|
-
log('+ 安装成功', 'green');
|
|
101
|
-
} catch (e) {
|
|
102
|
-
log('需要管理员权限,请输入密码:', 'yellow');
|
|
103
|
-
try {
|
|
104
|
-
execSync(`sudo cp -R "${appPath}" /Applications/`);
|
|
105
|
-
log('+ 安装成功', 'green');
|
|
106
|
-
} catch (sudoErr) {
|
|
107
|
-
throw new Error('安装失败,请检查 /Applications 目录权限');
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
// 4. 卸载 DMG
|
|
112
|
-
log('3. 清理...', 'blue');
|
|
113
|
-
execSync(`hdiutil detach "${mountPath}" -quiet`);
|
|
114
|
-
|
|
115
|
-
// 5. 启动应用
|
|
116
|
-
log('4. 启动应用...', 'blue');
|
|
117
|
-
log('\nGatekeeper 安全提示:', 'yellow');
|
|
118
|
-
log('即将弹出安全确认窗口,请点击"打开"', 'yellow');
|
|
119
|
-
log('(此提示仅首次运行时出现)\n', 'blue');
|
|
120
|
-
|
|
121
|
-
execSync('open -a 42cc');
|
|
122
|
-
|
|
123
|
-
log('\n+ 安装完成', 'green');
|
|
124
|
-
log('=====================================', 'blue');
|
|
125
|
-
log('');
|
|
126
|
-
log('+ 安装位置: /Applications/42cc.app', 'green');
|
|
127
|
-
log('+ 应用已启动并显示在菜单栏', 'green');
|
|
128
|
-
log('+ 下次可从 Launchpad 搜索 "42cc" 启动', 'green');
|
|
129
|
-
log('');
|
|
130
|
-
log('=====================================\n', 'blue');
|
|
131
|
-
|
|
132
|
-
return true;
|
|
133
|
-
} catch (error) {
|
|
134
|
-
log(`\n安装失败: ${error.message}`, 'red');
|
|
135
|
-
return false;
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
// Windows 自动安装
|
|
140
|
-
async function autoInstallWindows() {
|
|
141
|
-
const exePath = path.join(ASSETS_DIR, '42cc.exe');
|
|
142
|
-
|
|
143
|
-
if (!fs.existsSync(exePath)) {
|
|
144
|
-
throw new Error('未找到安装文件: ' + exePath);
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
log('\n开始安装...', 'yellow');
|
|
148
|
-
|
|
149
|
-
try {
|
|
150
|
-
const userProfile = process.env.USERPROFILE || process.env.HOME;
|
|
151
|
-
const installDir = path.join(userProfile, 'AppData', 'Local', '42cc');
|
|
152
|
-
const targetPath = path.join(installDir, '42cc.exe');
|
|
153
|
-
|
|
154
|
-
log('1. 安装到用户目录...', 'blue');
|
|
155
|
-
|
|
156
|
-
// 创建目录
|
|
157
|
-
if (!fs.existsSync(installDir)) {
|
|
158
|
-
fs.mkdirSync(installDir, { recursive: true });
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
// 复制可执行文件
|
|
162
|
-
fs.copyFileSync(exePath, targetPath);
|
|
163
|
-
log(`+ 已安装到: ${installDir}`, 'green');
|
|
164
|
-
|
|
165
|
-
// 创建开始菜单快捷方式
|
|
166
|
-
log('\n2. 创建开始菜单快捷方式...', 'blue');
|
|
167
|
-
try {
|
|
168
|
-
const startMenuDir = path.join(userProfile, 'AppData', 'Roaming', 'Microsoft', 'Windows', 'Start Menu', 'Programs');
|
|
169
|
-
const shortcutPath = path.join(startMenuDir, '42cc.lnk');
|
|
170
|
-
|
|
171
|
-
// 使用 PowerShell 创建快捷方式
|
|
172
|
-
const psScript = `
|
|
173
|
-
$WshShell = New-Object -ComObject WScript.Shell
|
|
174
|
-
$Shortcut = $WshShell.CreateShortcut("${shortcutPath.replace(/\\/g, '\\\\')}")
|
|
175
|
-
$Shortcut.TargetPath = "${targetPath.replace(/\\/g, '\\\\')}"
|
|
176
|
-
$Shortcut.WorkingDirectory = "${installDir.replace(/\\/g, '\\\\')}"
|
|
177
|
-
$Shortcut.Description = "42cc - Claude Code 模型配置工具"
|
|
178
|
-
$Shortcut.Save()
|
|
179
|
-
`;
|
|
180
|
-
|
|
181
|
-
execSync(`powershell -Command "${psScript}"`, { stdio: 'ignore' });
|
|
182
|
-
log('+ 已添加到开始菜单', 'green');
|
|
183
|
-
} catch (e) {
|
|
184
|
-
log('x 创建开始菜单快捷方式失败,可手动创建', 'yellow');
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
// 直接运行应用
|
|
188
|
-
log('\n3. 启动应用...', 'blue');
|
|
189
|
-
try {
|
|
190
|
-
execSync(`start "" "${targetPath}"`, { stdio: 'ignore' });
|
|
191
|
-
|
|
192
|
-
log('\n+ 安装完成', 'green');
|
|
193
|
-
log('=====================================', 'blue');
|
|
194
|
-
log('');
|
|
195
|
-
log('+ 安装位置: ' + installDir, 'green');
|
|
196
|
-
log('+ 应用已启动并显示在系统托盘', 'green');
|
|
197
|
-
log('+ 下次可从开始菜单搜索 "42cc" 启动', 'green');
|
|
198
|
-
log('');
|
|
199
|
-
log('=====================================\n', 'blue');
|
|
200
|
-
} catch (e) {
|
|
201
|
-
log('\n+ 安装完成', 'green');
|
|
202
|
-
log('=====================================', 'blue');
|
|
203
|
-
log('');
|
|
204
|
-
log('+ 安装位置: ' + installDir, 'green');
|
|
205
|
-
log('+ 可从开始菜单搜索 "42cc" 启动', 'green');
|
|
206
|
-
log('x 自动启动失败,请手动打开', 'yellow');
|
|
207
|
-
log('');
|
|
208
|
-
log('=====================================\n', 'blue');
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
return true;
|
|
212
|
-
} catch (error) {
|
|
213
|
-
log(`\n安装失败: ${error.message}`, 'red');
|
|
214
|
-
return false;
|
|
215
|
-
}
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
async function install() {
|
|
219
|
-
try {
|
|
220
|
-
log('\n42cc 安装程序', 'blue');
|
|
221
|
-
log('================\n', 'blue');
|
|
222
|
-
|
|
223
|
-
const platform = getPlatform();
|
|
224
|
-
log(`平台: ${platform}`, 'green');
|
|
225
|
-
log(`版本: ${APP_VERSION}`, 'green');
|
|
226
|
-
|
|
227
|
-
let success = false;
|
|
228
|
-
if (platform === 'macos') {
|
|
229
|
-
success = await autoInstallMacOS();
|
|
230
|
-
} else {
|
|
231
|
-
success = await autoInstallWindows();
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
if (success) {
|
|
235
|
-
saveInstalledVersion(APP_VERSION);
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
log('\n更多信息: https://42ailab.com\n', 'blue');
|
|
239
|
-
|
|
240
|
-
} catch (error) {
|
|
241
|
-
log(`\n错误: ${error.message}`, 'red');
|
|
242
|
-
log('\n如需帮助,请访问: https://cnb.cool/42ailab/42plugin/meta/-/issues\n', 'yellow');
|
|
243
|
-
process.exit(1);
|
|
244
|
-
}
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
// 仅在 postinstall 时运行
|
|
248
|
-
if (require.main === module) {
|
|
249
|
-
install();
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
module.exports = { install };
|