codeforge-cli 0.1.0
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/LICENSE +23 -0
- package/README.md +71 -0
- package/bin/forge +40 -0
- package/package.json +49 -0
- package/scripts/postinstall.js +190 -0
- package/scripts/preuninstall.js +28 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
Forge CLI - Commercial Software License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024-2026 Forge Team. All rights reserved.
|
|
4
|
+
|
|
5
|
+
This software and associated documentation files (the "Software") are
|
|
6
|
+
proprietary and confidential. Unauthorized copying, modification,
|
|
7
|
+
distribution, or use of this Software, via any medium, is strictly
|
|
8
|
+
prohibited.
|
|
9
|
+
|
|
10
|
+
The Software is provided under a commercial license. You may use the
|
|
11
|
+
Software only in accordance with the terms of your license agreement
|
|
12
|
+
with Forge Team.
|
|
13
|
+
|
|
14
|
+
For licensing inquiries: hello@forge.dev
|
|
15
|
+
Website: https://forge.dev
|
|
16
|
+
|
|
17
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
18
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
19
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
20
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
21
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
22
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
23
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
# Forge CLI
|
|
2
|
+
|
|
3
|
+
Terminal-first AI coding agent that works with any IDE. Think Cursor, but for your terminal.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install -g forge-cli
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Or use the install script:
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
# macOS / Linux
|
|
15
|
+
curl -fsSL https://forge.dev/install.sh | bash
|
|
16
|
+
|
|
17
|
+
# Windows (PowerShell)
|
|
18
|
+
irm https://forge.dev/install.ps1 | iex
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Quick Start
|
|
22
|
+
|
|
23
|
+
1. **Get your API key** at [forge.dev/account](https://forge.dev/account)
|
|
24
|
+
|
|
25
|
+
2. **Authenticate:**
|
|
26
|
+
```bash
|
|
27
|
+
forge auth login
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
3. **Start coding:**
|
|
31
|
+
```bash
|
|
32
|
+
cd your-project
|
|
33
|
+
forge
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Features
|
|
37
|
+
|
|
38
|
+
- 🤖 **Multi-provider support** - Works with Claude, GPT-4, Gemini, and more
|
|
39
|
+
- 🔧 **IDE-agnostic** - Use with VS Code, Neovim, Emacs, or no IDE at all
|
|
40
|
+
- 📁 **File operations** - Create, edit, and delete files with natural language
|
|
41
|
+
- 💻 **Shell commands** - Run terminal commands with AI assistance
|
|
42
|
+
- 🔍 **Semantic search** - Find relevant code using embeddings
|
|
43
|
+
- 🛡️ **Checkpointing** - Undo any AI changes with automatic snapshots
|
|
44
|
+
- 🧠 **Sub-agents** - Delegate to specialized agents for specific tasks
|
|
45
|
+
- 📝 **Memory** - Remember facts across sessions
|
|
46
|
+
- 🔒 **Enterprise-ready** - SOC 2 compliant, SSO support
|
|
47
|
+
|
|
48
|
+
## Plans
|
|
49
|
+
|
|
50
|
+
| Feature | Free | Pro | Team |
|
|
51
|
+
|---------|------|-----|------|
|
|
52
|
+
| Requests/day | 50 | Unlimited | Unlimited |
|
|
53
|
+
| Models | GPT-4o | All models | All models |
|
|
54
|
+
| Checkpointing | ❌ | ✅ | ✅ |
|
|
55
|
+
| Sub-agents | ❌ | ✅ | ✅ |
|
|
56
|
+
| Priority support | ❌ | ✅ | ✅ |
|
|
57
|
+
| SSO/SAML | ❌ | ❌ | ✅ |
|
|
58
|
+
|
|
59
|
+
## Documentation
|
|
60
|
+
|
|
61
|
+
Visit [forge.dev/docs](https://forge.dev/docs) for full documentation.
|
|
62
|
+
|
|
63
|
+
## Support
|
|
64
|
+
|
|
65
|
+
- 📧 Email: support@forge.dev
|
|
66
|
+
- 💬 Discord: [forge.dev/discord](https://forge.dev/discord)
|
|
67
|
+
- 📖 Docs: [forge.dev/docs](https://forge.dev/docs)
|
|
68
|
+
|
|
69
|
+
---
|
|
70
|
+
|
|
71
|
+
© 2024-2026 Forge Team. All rights reserved.
|
package/bin/forge
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Forge CLI - npm binary wrapper
|
|
5
|
+
* This script launches the installed Forge binary
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
const path = require('path');
|
|
9
|
+
const { spawn } = require('child_process');
|
|
10
|
+
const os = require('os');
|
|
11
|
+
|
|
12
|
+
const libDir = path.join(__dirname, '..', 'lib');
|
|
13
|
+
const ext = os.platform() === 'win32' ? '.exe' : '';
|
|
14
|
+
const forgeBinary = path.join(libDir, `forge${ext}`);
|
|
15
|
+
|
|
16
|
+
// Check if binary exists
|
|
17
|
+
const fs = require('fs');
|
|
18
|
+
if (!fs.existsSync(forgeBinary)) {
|
|
19
|
+
console.error('\x1b[31m[forge]\x1b[0m Binary not found. Try reinstalling:');
|
|
20
|
+
console.error(' npm uninstall -g forge-cli && npm install -g forge-cli');
|
|
21
|
+
process.exit(1);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// Spawn the binary with inherited stdio
|
|
25
|
+
const child = spawn(forgeBinary, process.argv.slice(2), {
|
|
26
|
+
stdio: 'inherit',
|
|
27
|
+
env: {
|
|
28
|
+
...process.env,
|
|
29
|
+
FORGE_LIB_DIR: libDir
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
child.on('error', (err) => {
|
|
34
|
+
console.error(`\x1b[31m[forge]\x1b[0m Failed to start: ${err.message}`);
|
|
35
|
+
process.exit(1);
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
child.on('exit', (code) => {
|
|
39
|
+
process.exit(code || 0);
|
|
40
|
+
});
|
package/package.json
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "codeforge-cli",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Terminal-first AI coding agent that works with any IDE. Think Cursor, but for your terminal.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"ai",
|
|
7
|
+
"coding",
|
|
8
|
+
"agent",
|
|
9
|
+
"terminal",
|
|
10
|
+
"cli",
|
|
11
|
+
"cursor",
|
|
12
|
+
"claude",
|
|
13
|
+
"gpt",
|
|
14
|
+
"llm",
|
|
15
|
+
"autonomous",
|
|
16
|
+
"code-assistant"
|
|
17
|
+
],
|
|
18
|
+
"homepage": "https://forge.dev",
|
|
19
|
+
"bugs": {
|
|
20
|
+
"url": "https://forge.dev/support"
|
|
21
|
+
},
|
|
22
|
+
"license": "SEE LICENSE IN LICENSE",
|
|
23
|
+
"author": "Forge Team <hello@forge.dev>",
|
|
24
|
+
"bin": {
|
|
25
|
+
"forge": "./bin/forge"
|
|
26
|
+
},
|
|
27
|
+
"files": [
|
|
28
|
+
"bin/",
|
|
29
|
+
"scripts/",
|
|
30
|
+
"README.md",
|
|
31
|
+
"LICENSE"
|
|
32
|
+
],
|
|
33
|
+
"scripts": {
|
|
34
|
+
"postinstall": "node scripts/postinstall.js",
|
|
35
|
+
"preuninstall": "node scripts/preuninstall.js"
|
|
36
|
+
},
|
|
37
|
+
"os": [
|
|
38
|
+
"darwin",
|
|
39
|
+
"linux",
|
|
40
|
+
"win32"
|
|
41
|
+
],
|
|
42
|
+
"cpu": [
|
|
43
|
+
"x64",
|
|
44
|
+
"arm64"
|
|
45
|
+
],
|
|
46
|
+
"engines": {
|
|
47
|
+
"node": ">=18.0.0"
|
|
48
|
+
}
|
|
49
|
+
}
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Forge CLI - Postinstall Script
|
|
5
|
+
* Downloads the correct platform-specific binaries after npm install
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
const os = require('os');
|
|
9
|
+
const fs = require('fs');
|
|
10
|
+
const path = require('path');
|
|
11
|
+
const https = require('https');
|
|
12
|
+
const { execSync } = require('child_process');
|
|
13
|
+
|
|
14
|
+
// Configuration - Use GitHub Releases as CDN
|
|
15
|
+
const GITHUB_REPO = process.env.FORGE_GITHUB_REPO || 'tharunmarella/forge-cli';
|
|
16
|
+
const DOWNLOAD_BASE = process.env.FORGE_DOWNLOAD_URL || `https://github.com/${GITHUB_REPO}/releases/download`;
|
|
17
|
+
const VERSION = require('../package.json').version;
|
|
18
|
+
const BIN_DIR = path.join(__dirname, '..', 'bin');
|
|
19
|
+
const LIB_DIR = path.join(__dirname, '..', 'lib');
|
|
20
|
+
|
|
21
|
+
// Platform detection
|
|
22
|
+
const PLATFORM = os.platform();
|
|
23
|
+
const ARCH = os.arch() === 'x64' ? 'amd64' : os.arch();
|
|
24
|
+
|
|
25
|
+
// Mapping for platform names
|
|
26
|
+
const platformMap = {
|
|
27
|
+
darwin: 'darwin',
|
|
28
|
+
linux: 'linux',
|
|
29
|
+
win32: 'windows'
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
const archMap = {
|
|
33
|
+
amd64: 'amd64',
|
|
34
|
+
x64: 'amd64',
|
|
35
|
+
arm64: 'arm64',
|
|
36
|
+
aarch64: 'arm64'
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
function log(message) {
|
|
40
|
+
console.log(`\x1b[36m[forge]\x1b[0m ${message}`);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function error(message) {
|
|
44
|
+
console.error(`\x1b[31m[forge]\x1b[0m ${message}`);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function success(message) {
|
|
48
|
+
console.log(`\x1b[32m[forge]\x1b[0m ${message}`);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
async function downloadFile(url, dest) {
|
|
52
|
+
return new Promise((resolve, reject) => {
|
|
53
|
+
const file = fs.createWriteStream(dest);
|
|
54
|
+
|
|
55
|
+
const request = (url) => {
|
|
56
|
+
https.get(url, {
|
|
57
|
+
headers: {
|
|
58
|
+
'User-Agent': 'forge-cli-installer'
|
|
59
|
+
}
|
|
60
|
+
}, (res) => {
|
|
61
|
+
// Handle redirects
|
|
62
|
+
if (res.statusCode === 302 || res.statusCode === 301) {
|
|
63
|
+
request(res.headers.location);
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
if (res.statusCode === 404) {
|
|
68
|
+
reject(new Error('Binary not found. Please check https://forge.dev/docs/install'));
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
if (res.statusCode !== 200) {
|
|
73
|
+
reject(new Error(`Download failed: HTTP ${res.statusCode}`));
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
const totalSize = parseInt(res.headers['content-length'], 10);
|
|
78
|
+
let downloadedSize = 0;
|
|
79
|
+
let lastProgress = 0;
|
|
80
|
+
|
|
81
|
+
res.on('data', (chunk) => {
|
|
82
|
+
downloadedSize += chunk.length;
|
|
83
|
+
const progress = Math.floor((downloadedSize / totalSize) * 100);
|
|
84
|
+
if (progress >= lastProgress + 10) {
|
|
85
|
+
process.stdout.write(`\r\x1b[36m[forge]\x1b[0m Downloading... ${progress}%`);
|
|
86
|
+
lastProgress = progress;
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
res.pipe(file);
|
|
91
|
+
file.on('finish', () => {
|
|
92
|
+
process.stdout.write('\r\x1b[36m[forge]\x1b[0m Downloading... 100%\n');
|
|
93
|
+
file.close();
|
|
94
|
+
resolve();
|
|
95
|
+
});
|
|
96
|
+
}).on('error', (err) => {
|
|
97
|
+
fs.unlink(dest, () => {});
|
|
98
|
+
reject(err);
|
|
99
|
+
});
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
request(url);
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
async function extractArchive(file, dest) {
|
|
107
|
+
if (file.endsWith('.zip')) {
|
|
108
|
+
if (PLATFORM === 'win32') {
|
|
109
|
+
execSync(`powershell -Command "Expand-Archive -Path '${file}' -DestinationPath '${dest}' -Force"`, { stdio: 'pipe' });
|
|
110
|
+
} else {
|
|
111
|
+
execSync(`unzip -o "${file}" -d "${dest}"`, { stdio: 'pipe' });
|
|
112
|
+
}
|
|
113
|
+
} else {
|
|
114
|
+
execSync(`tar -xzf "${file}" -C "${dest}"`, { stdio: 'pipe' });
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
async function main() {
|
|
119
|
+
const platform = platformMap[PLATFORM];
|
|
120
|
+
const arch = archMap[ARCH] || ARCH;
|
|
121
|
+
|
|
122
|
+
if (!platform) {
|
|
123
|
+
error(`Unsupported platform: ${PLATFORM}`);
|
|
124
|
+
error('Supported: macOS, Linux, Windows');
|
|
125
|
+
process.exit(1);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
log(`Installing Forge CLI v${VERSION} for ${platform}-${arch}...`);
|
|
129
|
+
|
|
130
|
+
// Ensure directories exist
|
|
131
|
+
fs.mkdirSync(BIN_DIR, { recursive: true });
|
|
132
|
+
fs.mkdirSync(LIB_DIR, { recursive: true });
|
|
133
|
+
|
|
134
|
+
try {
|
|
135
|
+
// Construct download URL
|
|
136
|
+
const ext = platform === 'windows' ? 'zip' : 'tar.gz';
|
|
137
|
+
const archiveName = `forge-${platform}-${arch}.${ext}`;
|
|
138
|
+
const downloadUrl = `${DOWNLOAD_BASE}/v${VERSION}/${archiveName}`;
|
|
139
|
+
const archivePath = path.join(LIB_DIR, archiveName);
|
|
140
|
+
|
|
141
|
+
// Download
|
|
142
|
+
await downloadFile(downloadUrl, archivePath);
|
|
143
|
+
|
|
144
|
+
// Extract
|
|
145
|
+
log('Extracting...');
|
|
146
|
+
await extractArchive(archivePath, LIB_DIR);
|
|
147
|
+
|
|
148
|
+
// Set up binaries
|
|
149
|
+
const binExt = PLATFORM === 'win32' ? '.exe' : '';
|
|
150
|
+
const forgeBinary = path.join(LIB_DIR, `forge${binExt}`);
|
|
151
|
+
const forgeHostBinary = path.join(LIB_DIR, `forge-host${binExt}`);
|
|
152
|
+
|
|
153
|
+
// Make executable on Unix
|
|
154
|
+
if (PLATFORM !== 'win32') {
|
|
155
|
+
fs.chmodSync(forgeBinary, 0o755);
|
|
156
|
+
fs.chmodSync(forgeHostBinary, 0o755);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
// Update the bin wrapper to point to the correct binary
|
|
160
|
+
const wrapperPath = path.join(BIN_DIR, PLATFORM === 'win32' ? 'forge.cmd' : 'forge');
|
|
161
|
+
|
|
162
|
+
if (PLATFORM === 'win32') {
|
|
163
|
+
fs.writeFileSync(wrapperPath, `@echo off\n"${forgeBinary}" %*`);
|
|
164
|
+
} else {
|
|
165
|
+
// The wrapper is already in bin/forge, just make sure it's executable
|
|
166
|
+
fs.chmodSync(wrapperPath, 0o755);
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
// Cleanup
|
|
170
|
+
fs.unlinkSync(archivePath);
|
|
171
|
+
|
|
172
|
+
success('');
|
|
173
|
+
success('Forge CLI installed successfully!');
|
|
174
|
+
log('');
|
|
175
|
+
log('Get started:');
|
|
176
|
+
log(' forge auth login');
|
|
177
|
+
log(' forge');
|
|
178
|
+
log('');
|
|
179
|
+
log('Documentation: https://forge.dev/docs');
|
|
180
|
+
|
|
181
|
+
} catch (err) {
|
|
182
|
+
error(`Installation failed: ${err.message}`);
|
|
183
|
+
error('');
|
|
184
|
+
error('Try the manual installation:');
|
|
185
|
+
error(' https://forge.dev/docs/install');
|
|
186
|
+
process.exit(1);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
main();
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Forge CLI - Preuninstall Script
|
|
5
|
+
* Cleanup before uninstalling
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
const fs = require('fs');
|
|
9
|
+
const path = require('path');
|
|
10
|
+
|
|
11
|
+
const libDir = path.join(__dirname, '..', 'lib');
|
|
12
|
+
const binDir = path.join(__dirname, '..', 'bin');
|
|
13
|
+
|
|
14
|
+
// Remove downloaded binaries
|
|
15
|
+
function removeDir(dir) {
|
|
16
|
+
if (fs.existsSync(dir)) {
|
|
17
|
+
fs.rmSync(dir, { recursive: true, force: true });
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
console.log('\x1b[36m[forge]\x1b[0m Cleaning up...');
|
|
22
|
+
|
|
23
|
+
removeDir(libDir);
|
|
24
|
+
|
|
25
|
+
console.log('\x1b[32m[forge]\x1b[0m Forge CLI uninstalled.');
|
|
26
|
+
console.log('');
|
|
27
|
+
console.log('Thank you for using Forge! We\'d love your feedback:');
|
|
28
|
+
console.log(' https://github.com/forge-cli/forge/issues');
|