@kandiforge/kandi-cli 0.45.7 → 0.45.14
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/package.json +1 -1
- package/scripts/install.js +136 -18
- package/scripts/CLAUDE.md +0 -7
package/package.json
CHANGED
package/scripts/install.js
CHANGED
|
@@ -6,13 +6,58 @@ const https = require('https');
|
|
|
6
6
|
const { execSync } = require('child_process');
|
|
7
7
|
|
|
8
8
|
// This version MUST match package.json
|
|
9
|
-
const RELEASE_VERSION = '0.45.
|
|
9
|
+
const RELEASE_VERSION = '0.45.14';
|
|
10
10
|
const GITHUB_REPO = 'KandiForge/distribution';
|
|
11
|
+
const PACKAGE_NAME = '@kandiforge/kandi-cli';
|
|
12
|
+
|
|
13
|
+
// ANSI color codes
|
|
14
|
+
const colors = {
|
|
15
|
+
reset: '\x1b[0m',
|
|
16
|
+
bold: '\x1b[1m',
|
|
17
|
+
dim: '\x1b[2m',
|
|
18
|
+
cyan: '\x1b[36m',
|
|
19
|
+
green: '\x1b[32m',
|
|
20
|
+
yellow: '\x1b[33m',
|
|
21
|
+
blue: '\x1b[34m',
|
|
22
|
+
magenta: '\x1b[35m',
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
function log(message) {
|
|
26
|
+
console.log(message);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function logStep(step, message) {
|
|
30
|
+
log(`${colors.cyan}[${step}]${colors.reset} ${message}`);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function logSuccess(message) {
|
|
34
|
+
log(`${colors.green}OK${colors.reset} ${message}`);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function logInfo(message) {
|
|
38
|
+
log(`${colors.dim} ${message}${colors.reset}`);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function getPlatformName(platform) {
|
|
42
|
+
const names = {
|
|
43
|
+
darwin: 'macOS',
|
|
44
|
+
linux: 'Linux',
|
|
45
|
+
win32: 'Windows',
|
|
46
|
+
};
|
|
47
|
+
return names[platform] || platform;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function getArchName(arch) {
|
|
51
|
+
const names = {
|
|
52
|
+
arm64: 'Apple Silicon',
|
|
53
|
+
x64: 'x64',
|
|
54
|
+
ia32: 'x86',
|
|
55
|
+
};
|
|
56
|
+
return names[arch] || arch;
|
|
57
|
+
}
|
|
11
58
|
|
|
12
59
|
function downloadFile(url, destPath) {
|
|
13
60
|
return new Promise((resolve, reject) => {
|
|
14
|
-
console.log(`Downloading from: ${url}`);
|
|
15
|
-
|
|
16
61
|
https.get(url, (response) => {
|
|
17
62
|
if (response.statusCode === 302 || response.statusCode === 301) {
|
|
18
63
|
// Follow redirect
|
|
@@ -57,6 +102,15 @@ function extractZip(zipPath, destDir) {
|
|
|
57
102
|
async function install() {
|
|
58
103
|
try {
|
|
59
104
|
const platform = process.platform;
|
|
105
|
+
const arch = process.arch;
|
|
106
|
+
|
|
107
|
+
// Print installation header
|
|
108
|
+
log('');
|
|
109
|
+
log(`${colors.bold}${colors.cyan}Kandi CLI${colors.reset} ${colors.dim}v${RELEASE_VERSION}${colors.reset}`);
|
|
110
|
+
log(`${colors.dim}AI-powered code generation and development tool${colors.reset}`);
|
|
111
|
+
log('');
|
|
112
|
+
|
|
113
|
+
logStep('1/4', `Detecting platform: ${colors.bold}${getPlatformName(platform)}${colors.reset} (${getArchName(arch)})`);
|
|
60
114
|
|
|
61
115
|
// Determine archive name and binary extension based on platform
|
|
62
116
|
let fileName, isZip, ext;
|
|
@@ -92,7 +146,6 @@ async function install() {
|
|
|
92
146
|
}
|
|
93
147
|
|
|
94
148
|
// Clean bin directory - remove any existing binaries to avoid mixing platforms
|
|
95
|
-
console.log('Cleaning bin directory...');
|
|
96
149
|
const existingFiles = fs.readdirSync(binDir);
|
|
97
150
|
for (const file of existingFiles) {
|
|
98
151
|
// Skip .gitkeep or other dotfiles
|
|
@@ -101,20 +154,19 @@ async function install() {
|
|
|
101
154
|
try {
|
|
102
155
|
fs.unlinkSync(filePath);
|
|
103
156
|
} catch (e) {
|
|
104
|
-
|
|
157
|
+
// Ignore cleanup errors
|
|
105
158
|
}
|
|
106
159
|
}
|
|
107
160
|
|
|
108
|
-
|
|
109
|
-
|
|
161
|
+
logStep('2/4', 'Downloading binaries from GitHub releases...');
|
|
162
|
+
logInfo(downloadUrl);
|
|
110
163
|
await downloadFile(downloadUrl, tempFile);
|
|
111
164
|
|
|
112
|
-
|
|
113
|
-
console.log('Extracting binaries...');
|
|
165
|
+
logStep('3/4', 'Extracting binaries...');
|
|
114
166
|
if (isZip) {
|
|
115
167
|
extractZip(tempFile, binDir);
|
|
116
168
|
} else {
|
|
117
|
-
execSync(`tar -xzf "${tempFile}" -C "${binDir}"`, { stdio: '
|
|
169
|
+
execSync(`tar -xzf "${tempFile}" -C "${binDir}"`, { stdio: 'pipe' });
|
|
118
170
|
}
|
|
119
171
|
|
|
120
172
|
// Clean up archive
|
|
@@ -138,9 +190,7 @@ async function install() {
|
|
|
138
190
|
fs.chmodSync(destPath, 0o755);
|
|
139
191
|
}
|
|
140
192
|
|
|
141
|
-
installedBinaries.push(
|
|
142
|
-
} else {
|
|
143
|
-
console.warn(`Warning: ${binaryName} not found in archive`);
|
|
193
|
+
installedBinaries.push({ name: baseName, path: destPath });
|
|
144
194
|
}
|
|
145
195
|
}
|
|
146
196
|
|
|
@@ -153,15 +203,83 @@ async function install() {
|
|
|
153
203
|
throw new Error('No binaries were found in the archive');
|
|
154
204
|
}
|
|
155
205
|
|
|
156
|
-
|
|
157
|
-
|
|
206
|
+
logStep('4/4', 'Setting up CLI commands...');
|
|
207
|
+
|
|
208
|
+
// Create symlinks in npm global bin directory
|
|
209
|
+
// npm doesn't create symlinks for binaries that don't exist at install time,
|
|
210
|
+
// so we need to create them manually after downloading
|
|
211
|
+
let symlinkSuccess = false;
|
|
212
|
+
try {
|
|
213
|
+
// Get npm prefix and construct bin path (npm bin -g is deprecated)
|
|
214
|
+
const npmPrefix = execSync('npm config get prefix', { encoding: 'utf8' }).trim();
|
|
215
|
+
const npmGlobalBin = path.join(npmPrefix, 'bin');
|
|
216
|
+
|
|
217
|
+
for (const binary of installedBinaries) {
|
|
218
|
+
const binaryName = `${binary.name}${ext}`;
|
|
219
|
+
const sourcePath = binary.path;
|
|
220
|
+
const linkPath = path.join(npmGlobalBin, binaryName);
|
|
221
|
+
|
|
222
|
+
if (fs.existsSync(sourcePath)) {
|
|
223
|
+
// Remove existing symlink if it exists
|
|
224
|
+
try {
|
|
225
|
+
if (fs.existsSync(linkPath) || fs.lstatSync(linkPath).isSymbolicLink()) {
|
|
226
|
+
fs.unlinkSync(linkPath);
|
|
227
|
+
}
|
|
228
|
+
} catch (e) {
|
|
229
|
+
// Ignore if file doesn't exist
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
// Create symlink
|
|
233
|
+
if (platform === 'win32') {
|
|
234
|
+
// On Windows, copy the file instead of symlinking (requires admin for symlinks)
|
|
235
|
+
fs.copyFileSync(sourcePath, linkPath);
|
|
236
|
+
} else {
|
|
237
|
+
fs.symlinkSync(sourcePath, linkPath);
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
symlinkSuccess = true;
|
|
242
|
+
} catch (symlinkError) {
|
|
243
|
+
// Symlink creation failed - will show path instructions below
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
// Print success message
|
|
247
|
+
log('');
|
|
248
|
+
log(`${colors.green}Installation complete!${colors.reset}`);
|
|
249
|
+
log('');
|
|
250
|
+
log(`${colors.bold}Installed ${installedBinaries.length} binaries:${colors.reset}`);
|
|
158
251
|
for (const binary of installedBinaries) {
|
|
159
|
-
|
|
252
|
+
log(` ${colors.cyan}${binary.name}${colors.reset}`);
|
|
160
253
|
}
|
|
161
254
|
|
|
255
|
+
// Print next steps
|
|
256
|
+
log('');
|
|
257
|
+
log(`${colors.bold}Next steps:${colors.reset}`);
|
|
258
|
+
log(` ${colors.dim}1.${colors.reset} Start an AI-powered coding session:`);
|
|
259
|
+
log(` ${colors.cyan}kandi-forge${colors.reset}`);
|
|
260
|
+
log('');
|
|
261
|
+
log(` ${colors.dim}2.${colors.reset} Optimize context for AI requests:`);
|
|
262
|
+
log(` ${colors.cyan}kandi-supersmall --help${colors.reset}`);
|
|
263
|
+
log('');
|
|
264
|
+
|
|
265
|
+
if (!symlinkSuccess) {
|
|
266
|
+
log(`${colors.yellow}Note:${colors.reset} Commands may not be in your PATH.`);
|
|
267
|
+
log(`Add this to your shell profile:`);
|
|
268
|
+
log(` ${colors.dim}export PATH="${binDir}:$PATH"${colors.reset}`);
|
|
269
|
+
log('');
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
log(`${colors.dim}Documentation: https://docs.kandiforge.com${colors.reset}`);
|
|
273
|
+
log('');
|
|
274
|
+
|
|
162
275
|
} catch (error) {
|
|
163
|
-
|
|
164
|
-
|
|
276
|
+
log('');
|
|
277
|
+
log(`${colors.bold}Installation failed${colors.reset}`);
|
|
278
|
+
log(`${colors.dim}${error.message}${colors.reset}`);
|
|
279
|
+
log('');
|
|
280
|
+
log(`Please report this issue at:`);
|
|
281
|
+
log(`${colors.cyan}https://github.com/KandiForge/apps/issues${colors.reset}`);
|
|
282
|
+
log('');
|
|
165
283
|
process.exit(1);
|
|
166
284
|
}
|
|
167
285
|
}
|