@kandiforge/kandi-cli 9.2.0 → 9.2.1
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 +10 -51
- package/bin/kandi +5 -12
- package/package.json +5 -4
- package/scripts/install.js +17 -58
- package/LICENSE +0 -20
package/README.md
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-

|
|
2
|
-
|
|
3
1
|
# Kandi CLI
|
|
4
2
|
|
|
5
3
|
AI-assisted software development CLI with interactive chat and 26 built-in tools.
|
|
@@ -7,64 +5,25 @@ AI-assisted software development CLI with interactive chat and 26 built-in tools
|
|
|
7
5
|
## Installation
|
|
8
6
|
|
|
9
7
|
```bash
|
|
10
|
-
npm install -g kandi-cli
|
|
11
|
-
```
|
|
12
|
-
|
|
13
|
-
Or use with npx:
|
|
14
|
-
|
|
15
|
-
```bash
|
|
16
|
-
npx kandi-cli --help
|
|
17
|
-
```
|
|
18
|
-
|
|
19
|
-
## Requirements
|
|
20
|
-
|
|
21
|
-
- macOS (Intel or Apple Silicon)
|
|
22
|
-
- Node.js 14.0.0 or higher
|
|
23
|
-
|
|
24
|
-
## Getting Started
|
|
25
|
-
|
|
26
|
-
### 1. Configure API Keys
|
|
27
|
-
|
|
28
|
-
```bash
|
|
29
|
-
kandi config set anthropic.api_key "your-api-key"
|
|
30
|
-
kandi config set openai.api_key "your-api-key"
|
|
31
|
-
kandi config set github.token "your-token"
|
|
32
|
-
```
|
|
33
|
-
|
|
34
|
-
### 2. Start Interactive Chat
|
|
35
|
-
|
|
36
|
-
```bash
|
|
37
|
-
kandi chat --allow-all
|
|
8
|
+
npm install -g @kandiforge/kandi-cli
|
|
38
9
|
```
|
|
39
10
|
|
|
40
|
-
|
|
11
|
+
## Usage
|
|
41
12
|
|
|
42
13
|
```bash
|
|
43
|
-
kandi
|
|
14
|
+
kandi --help
|
|
44
15
|
```
|
|
45
16
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
```bash
|
|
49
|
-
kandi exec-spec /path/to/spec.md
|
|
50
|
-
```
|
|
51
|
-
|
|
52
|
-
## Features
|
|
53
|
-
|
|
54
|
-
- **Interactive Chat Mode**: Engage with AI assistants in a conversational interface
|
|
55
|
-
- **26 Built-in Tools**: Comprehensive toolset for software development tasks
|
|
56
|
-
- **Multiple AI Providers**: Support for Anthropic, OpenAI, and other providers
|
|
57
|
-
- **GitHub Integration**: Seamless integration with GitHub repositories
|
|
58
|
-
- **Spec File Execution**: Run detailed specifications for complex tasks
|
|
59
|
-
|
|
60
|
-
## Documentation
|
|
17
|
+
## Platform Support
|
|
61
18
|
|
|
62
|
-
|
|
19
|
+
- macOS (Universal: x86_64 + arm64)
|
|
20
|
+
- Linux (x86_64)
|
|
21
|
+
- Windows (x86_64)
|
|
63
22
|
|
|
64
|
-
##
|
|
23
|
+
## Issues
|
|
65
24
|
|
|
66
|
-
Report issues at: https://github.com/KandiForge/
|
|
25
|
+
Report issues at: https://github.com/KandiForge/apps/issues
|
|
67
26
|
|
|
68
27
|
## License
|
|
69
28
|
|
|
70
|
-
|
|
29
|
+
Proprietary - © Abstract Class Consulting Inc.
|
package/bin/kandi
CHANGED
|
@@ -2,17 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
const { spawn } = require('child_process');
|
|
4
4
|
const path = require('path');
|
|
5
|
-
const fs = require('fs');
|
|
6
5
|
|
|
7
|
-
//
|
|
8
|
-
const
|
|
9
|
-
|
|
10
|
-
// Check if binary exists
|
|
11
|
-
if (!fs.existsSync(binaryPath)) {
|
|
12
|
-
console.error('Error: Kandi CLI binary not found.');
|
|
13
|
-
console.error('Please reinstall the package: npm install -g @kandiforge/kandi-cli');
|
|
14
|
-
process.exit(1);
|
|
15
|
-
}
|
|
6
|
+
// Determine binary name based on platform
|
|
7
|
+
const binaryName = process.platform === 'win32' ? 'kandi-bin.exe' : 'kandi-bin';
|
|
8
|
+
const binaryPath = path.join(__dirname, binaryName);
|
|
16
9
|
|
|
17
10
|
// Spawn the binary with all arguments
|
|
18
11
|
const child = spawn(binaryPath, process.argv.slice(2), {
|
|
@@ -20,13 +13,13 @@ const child = spawn(binaryPath, process.argv.slice(2), {
|
|
|
20
13
|
env: process.env
|
|
21
14
|
});
|
|
22
15
|
|
|
23
|
-
//
|
|
16
|
+
// Forward exit code
|
|
24
17
|
child.on('exit', (code) => {
|
|
25
18
|
process.exit(code || 0);
|
|
26
19
|
});
|
|
27
20
|
|
|
28
21
|
// Handle errors
|
|
29
22
|
child.on('error', (err) => {
|
|
30
|
-
console.error('Failed to start
|
|
23
|
+
console.error('Failed to start kandi binary:', err.message);
|
|
31
24
|
process.exit(1);
|
|
32
25
|
});
|
package/package.json
CHANGED
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kandiforge/kandi-cli",
|
|
3
|
-
"version": "9.2.
|
|
3
|
+
"version": "9.2.1",
|
|
4
4
|
"description": "AI-assisted software development CLI with interactive chat and 26 built-in tools",
|
|
5
5
|
"author": "KandiForge",
|
|
6
6
|
"license": "Proprietary",
|
|
7
|
-
"homepage": "https://github.com/KandiForge/
|
|
7
|
+
"homepage": "https://github.com/KandiForge/apps",
|
|
8
8
|
"repository": {
|
|
9
9
|
"type": "git",
|
|
10
|
-
"url": "https://github.com/KandiForge/
|
|
10
|
+
"url": "https://github.com/KandiForge/apps.git",
|
|
11
|
+
"directory": "CLI"
|
|
11
12
|
},
|
|
12
13
|
"bugs": {
|
|
13
|
-
"url": "https://github.com/KandiForge/
|
|
14
|
+
"url": "https://github.com/KandiForge/apps/issues"
|
|
14
15
|
},
|
|
15
16
|
"keywords": [
|
|
16
17
|
"ai",
|
package/scripts/install.js
CHANGED
|
@@ -4,23 +4,15 @@ const fs = require('fs');
|
|
|
4
4
|
const path = require('path');
|
|
5
5
|
const https = require('https');
|
|
6
6
|
const { execSync } = require('child_process');
|
|
7
|
-
const crypto = require('crypto');
|
|
8
7
|
|
|
9
|
-
|
|
10
|
-
const
|
|
11
|
-
const
|
|
12
|
-
|
|
13
|
-
function getArch() {
|
|
14
|
-
const arch = process.arch;
|
|
15
|
-
if (arch === 'x64') return 'x86_64';
|
|
16
|
-
if (arch === 'arm64') return 'arm64';
|
|
17
|
-
throw new Error(`Unsupported architecture: ${arch}`);
|
|
18
|
-
}
|
|
8
|
+
// This version MUST match package.json
|
|
9
|
+
const RELEASE_VERSION = '9.2.1';
|
|
10
|
+
const GITHUB_REPO = 'KandiForge/apps';
|
|
19
11
|
|
|
20
12
|
function downloadFile(url, destPath) {
|
|
21
13
|
return new Promise((resolve, reject) => {
|
|
22
14
|
console.log(`Downloading from: ${url}`);
|
|
23
|
-
|
|
15
|
+
|
|
24
16
|
https.get(url, (response) => {
|
|
25
17
|
if (response.statusCode === 302 || response.statusCode === 301) {
|
|
26
18
|
// Follow redirect
|
|
@@ -28,20 +20,20 @@ function downloadFile(url, destPath) {
|
|
|
28
20
|
.then(resolve)
|
|
29
21
|
.catch(reject);
|
|
30
22
|
}
|
|
31
|
-
|
|
23
|
+
|
|
32
24
|
if (response.statusCode !== 200) {
|
|
33
|
-
reject(new Error(`Failed to download: ${response.statusCode}`));
|
|
25
|
+
reject(new Error(`Failed to download: ${response.statusCode} ${response.statusMessage}`));
|
|
34
26
|
return;
|
|
35
27
|
}
|
|
36
|
-
|
|
28
|
+
|
|
37
29
|
const file = fs.createWriteStream(destPath);
|
|
38
30
|
response.pipe(file);
|
|
39
|
-
|
|
31
|
+
|
|
40
32
|
file.on('finish', () => {
|
|
41
33
|
file.close();
|
|
42
34
|
resolve();
|
|
43
35
|
});
|
|
44
|
-
|
|
36
|
+
|
|
45
37
|
file.on('error', (err) => {
|
|
46
38
|
fs.unlink(destPath, () => {});
|
|
47
39
|
reject(err);
|
|
@@ -50,28 +42,10 @@ function downloadFile(url, destPath) {
|
|
|
50
42
|
});
|
|
51
43
|
}
|
|
52
44
|
|
|
53
|
-
async function verifyChecksum(filePath, expectedHash) {
|
|
54
|
-
return new Promise((resolve, reject) => {
|
|
55
|
-
const hash = crypto.createHash('sha256');
|
|
56
|
-
const stream = fs.createReadStream(filePath);
|
|
57
|
-
|
|
58
|
-
stream.on('data', (data) => hash.update(data));
|
|
59
|
-
stream.on('end', () => {
|
|
60
|
-
const fileHash = hash.digest('hex');
|
|
61
|
-
if (fileHash === expectedHash) {
|
|
62
|
-
resolve(true);
|
|
63
|
-
} else {
|
|
64
|
-
reject(new Error(`Checksum mismatch. Expected: ${expectedHash}, Got: ${fileHash}`));
|
|
65
|
-
}
|
|
66
|
-
});
|
|
67
|
-
stream.on('error', reject);
|
|
68
|
-
});
|
|
69
|
-
}
|
|
70
|
-
|
|
71
45
|
async function install() {
|
|
72
46
|
try {
|
|
73
|
-
const arch = getArch();
|
|
74
47
|
const platform = process.platform;
|
|
48
|
+
const arch = process.arch;
|
|
75
49
|
|
|
76
50
|
// Determine file name based on platform
|
|
77
51
|
let fileName, extractCmd, binaryName;
|
|
@@ -91,8 +65,8 @@ async function install() {
|
|
|
91
65
|
throw new Error(`Platform ${platform} is not supported. Supported: macOS, Linux, Windows`);
|
|
92
66
|
}
|
|
93
67
|
|
|
94
|
-
// Download URL
|
|
95
|
-
const downloadUrl = `https://
|
|
68
|
+
// Download URL from GitHub release assets (public even for private repos)
|
|
69
|
+
const downloadUrl = `https://github.com/${GITHUB_REPO}/releases/download/kandi-cli-v${RELEASE_VERSION}/${fileName}`;
|
|
96
70
|
|
|
97
71
|
const binDir = path.join(__dirname, '..', 'bin');
|
|
98
72
|
const tempFile = path.join(binDir, fileName);
|
|
@@ -133,32 +107,17 @@ async function install() {
|
|
|
133
107
|
if (platform !== 'win32') {
|
|
134
108
|
fs.chmodSync(binaryPath, 0o755);
|
|
135
109
|
}
|
|
136
|
-
|
|
110
|
+
|
|
137
111
|
console.log('✅ Kandi CLI installed successfully!');
|
|
138
112
|
console.log(`Binary location: ${binaryPath}`);
|
|
139
113
|
console.log('\nTo get started, run: kandi --help');
|
|
140
|
-
|
|
114
|
+
|
|
141
115
|
} catch (error) {
|
|
142
116
|
console.error('❌ Installation failed:', error.message);
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
const localBinary = '/Users/admin/kandi-forge/kandi-cli/target/release/kandi';
|
|
146
|
-
const binDir = path.join(__dirname, '..', 'bin');
|
|
147
|
-
const targetBinary = path.join(binDir, 'kandi-bin');
|
|
148
|
-
|
|
149
|
-
if (fs.existsSync(localBinary)) {
|
|
150
|
-
console.log('Using local development binary as fallback...');
|
|
151
|
-
if (!fs.existsSync(binDir)) {
|
|
152
|
-
fs.mkdirSync(binDir, { recursive: true });
|
|
153
|
-
}
|
|
154
|
-
fs.copyFileSync(localBinary, targetBinary);
|
|
155
|
-
fs.chmodSync(targetBinary, 0o755);
|
|
156
|
-
console.log('✅ Installed local development binary');
|
|
157
|
-
} else {
|
|
158
|
-
process.exit(1);
|
|
159
|
-
}
|
|
117
|
+
console.error('\nPlease report this issue at: https://github.com/KandiForge/apps/issues');
|
|
118
|
+
process.exit(1);
|
|
160
119
|
}
|
|
161
120
|
}
|
|
162
121
|
|
|
163
122
|
// Run installation
|
|
164
|
-
install();
|
|
123
|
+
install();
|
package/LICENSE
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
PROPRIETARY SOFTWARE LICENSE
|
|
2
|
-
|
|
3
|
-
Copyright (c) 2025 KandiForge. All rights reserved.
|
|
4
|
-
|
|
5
|
-
This software and associated documentation files (the "Software") are proprietary
|
|
6
|
-
and confidential. The Software is licensed, not sold.
|
|
7
|
-
|
|
8
|
-
RESTRICTIONS:
|
|
9
|
-
- You may not distribute, sublicense, or resell the Software
|
|
10
|
-
- You may not reverse engineer, decompile, or disassemble the Software
|
|
11
|
-
- You may not remove or alter any proprietary notices or labels
|
|
12
|
-
|
|
13
|
-
USE:
|
|
14
|
-
The Software is provided for use according to the terms of your license agreement
|
|
15
|
-
with KandiForge.
|
|
16
|
-
|
|
17
|
-
NO WARRANTY:
|
|
18
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED.
|
|
19
|
-
|
|
20
|
-
For licensing inquiries, contact: support@kandiforge.com
|