codebuff-cli 1.0.14 → 1.0.15
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/NOTICE +4 -0
- package/cli/scripts/download-binary.cjs +53 -88
- package/package.json +5 -3
- package/cli/bin/codebuff.cjs +0 -165
package/NOTICE
ADDED
|
@@ -3,57 +3,33 @@ const fs = require('fs');
|
|
|
3
3
|
const path = require('path');
|
|
4
4
|
const https = require('https');
|
|
5
5
|
const http = require('http');
|
|
6
|
+
const os = require('os');
|
|
6
7
|
|
|
7
8
|
const REPO = 'Marcus-Mok-GH/codebuff-cli';
|
|
8
9
|
const BINARY_NAME = 'codebuff';
|
|
9
|
-
const MAX_RETRIES = 3;
|
|
10
|
-
const REQUEST_TIMEOUT_MS = 120000;
|
|
11
|
-
const MAX_REDIRECTS = 10;
|
|
12
10
|
|
|
13
11
|
function getVersion() {
|
|
14
|
-
const
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
const mappings = {
|
|
26
|
-
darwin: 'darwin',
|
|
27
|
-
linux: 'linux',
|
|
28
|
-
win32: 'win32',
|
|
29
|
-
};
|
|
30
|
-
const osName = mappings[platform] || platform;
|
|
31
|
-
return osName + '-' + arch;
|
|
12
|
+
const candidates = [
|
|
13
|
+
path.join(__dirname, '..', '..', 'package.json'),
|
|
14
|
+
path.join(__dirname, '..', 'package.json'),
|
|
15
|
+
];
|
|
16
|
+
for (const p of candidates) {
|
|
17
|
+
try {
|
|
18
|
+
const pkg = JSON.parse(fs.readFileSync(p, 'utf8'));
|
|
19
|
+
if (pkg.version) return pkg.version;
|
|
20
|
+
} catch {}
|
|
21
|
+
}
|
|
22
|
+
return '1.0.9';
|
|
32
23
|
}
|
|
33
24
|
|
|
34
25
|
function getBinaryPath() {
|
|
35
|
-
const binDir = path.join(
|
|
36
|
-
const name = process.platform === 'win32' ? BINARY_NAME
|
|
26
|
+
const binDir = path.join(os.homedir(), '.codebuff');
|
|
27
|
+
const name = process.platform === 'win32' ? `${BINARY_NAME}.exe` : BINARY_NAME;
|
|
37
28
|
return path.join(binDir, name);
|
|
38
29
|
}
|
|
39
30
|
|
|
40
|
-
function
|
|
41
|
-
try {
|
|
42
|
-
if (fs.existsSync(dest)) {
|
|
43
|
-
fs.unlinkSync(dest);
|
|
44
|
-
}
|
|
45
|
-
} catch {
|
|
46
|
-
// ignore cleanup errors
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
function download(url, dest, redirectCount = 0) {
|
|
31
|
+
function download(url, dest) {
|
|
51
32
|
return new Promise((resolve, reject) => {
|
|
52
|
-
if (redirectCount > MAX_REDIRECTS) {
|
|
53
|
-
reject(new Error('Too many redirects (max ' + MAX_REDIRECTS + ') while downloading from ' + url));
|
|
54
|
-
return;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
33
|
const client = url.startsWith('https:') ? https : http;
|
|
58
34
|
const file = fs.createWriteStream(dest);
|
|
59
35
|
|
|
@@ -61,10 +37,10 @@ function download(url, dest, redirectCount = 0) {
|
|
|
61
37
|
url,
|
|
62
38
|
{ headers: { 'User-Agent': 'codebuff-cli-installer' } },
|
|
63
39
|
(res) => {
|
|
64
|
-
if (res.statusCode === 301 || res.statusCode === 302
|
|
40
|
+
if (res.statusCode === 301 || res.statusCode === 302) {
|
|
65
41
|
file.close();
|
|
66
|
-
|
|
67
|
-
download(new URL(res.headers.location, url).href, dest
|
|
42
|
+
if (fs.existsSync(dest)) fs.unlinkSync(dest);
|
|
43
|
+
download(new URL(res.headers.location, url).href, dest)
|
|
68
44
|
.then(resolve)
|
|
69
45
|
.catch(reject);
|
|
70
46
|
return;
|
|
@@ -72,8 +48,8 @@ function download(url, dest, redirectCount = 0) {
|
|
|
72
48
|
|
|
73
49
|
if (res.statusCode !== 200) {
|
|
74
50
|
file.close();
|
|
75
|
-
|
|
76
|
-
reject(new Error(
|
|
51
|
+
if (fs.existsSync(dest)) fs.unlinkSync(dest);
|
|
52
|
+
reject(new Error(`HTTP ${res.statusCode}`));
|
|
77
53
|
return;
|
|
78
54
|
}
|
|
79
55
|
|
|
@@ -87,78 +63,67 @@ function download(url, dest, redirectCount = 0) {
|
|
|
87
63
|
|
|
88
64
|
req.on('error', (err) => {
|
|
89
65
|
file.close();
|
|
90
|
-
|
|
91
|
-
reject(
|
|
66
|
+
if (fs.existsSync(dest)) fs.unlinkSync(dest);
|
|
67
|
+
reject(err);
|
|
92
68
|
});
|
|
93
69
|
|
|
94
|
-
req.setTimeout(
|
|
70
|
+
req.setTimeout(30000, () => {
|
|
95
71
|
req.destroy();
|
|
96
72
|
file.close();
|
|
97
|
-
|
|
98
|
-
reject(new Error('
|
|
73
|
+
if (fs.existsSync(dest)) fs.unlinkSync(dest);
|
|
74
|
+
reject(new Error('Request timeout'));
|
|
99
75
|
});
|
|
100
76
|
});
|
|
101
77
|
}
|
|
102
78
|
|
|
103
|
-
async function
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
return true;
|
|
110
|
-
} catch (err) {
|
|
111
|
-
lastError = err;
|
|
112
|
-
console.error('Attempt ' + attempt + ' failed: ' + err.message);
|
|
113
|
-
if (attempt < MAX_RETRIES) {
|
|
114
|
-
const delay = Math.pow(2, attempt) * 1000;
|
|
115
|
-
console.log('Retrying in ' + delay + 'ms...');
|
|
116
|
-
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
117
|
-
}
|
|
118
|
-
}
|
|
79
|
+
async function tryDownload(url, dest) {
|
|
80
|
+
try {
|
|
81
|
+
await download(url, dest);
|
|
82
|
+
return true;
|
|
83
|
+
} catch {
|
|
84
|
+
return false;
|
|
119
85
|
}
|
|
120
|
-
console.error('Failed to download binary after ' + MAX_RETRIES + ' attempts.');
|
|
121
|
-
console.error('Last error: ' + lastError.message);
|
|
122
|
-
return false;
|
|
123
86
|
}
|
|
124
87
|
|
|
125
88
|
async function main() {
|
|
126
|
-
const version = getVersion();
|
|
127
|
-
const platform = getPlatform();
|
|
128
89
|
const binaryPath = getBinaryPath();
|
|
129
90
|
|
|
130
|
-
|
|
91
|
+
if (fs.existsSync(binaryPath)) {
|
|
92
|
+
console.log('Binary already exists at', binaryPath);
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
const version = getVersion();
|
|
97
|
+
const baseUrl = `https://github.com/${REPO}/releases/download/v${version}`;
|
|
131
98
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
99
|
+
// Try platform-specific binary first
|
|
100
|
+
const platformName = `${BINARY_NAME}-${process.platform}-${process.arch}${
|
|
101
|
+
process.platform === 'win32' ? '.exe' : ''
|
|
102
|
+
}`;
|
|
103
|
+
const platformUrl = `${baseUrl}/${platformName}`;
|
|
104
|
+
const genericUrl = `${baseUrl}/${BINARY_NAME}`;
|
|
136
105
|
|
|
137
106
|
fs.mkdirSync(path.dirname(binaryPath), { recursive: true });
|
|
138
107
|
|
|
139
|
-
if (
|
|
140
|
-
console.log(
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
if (await downloadWithRetry(url, binaryPath)) {
|
|
145
|
-
console.log('Download complete.');
|
|
108
|
+
if (await tryDownload(platformUrl, binaryPath)) {
|
|
109
|
+
console.log(`Downloaded platform-specific binary: ${platformName}`);
|
|
110
|
+
} else if (await tryDownload(genericUrl, binaryPath)) {
|
|
111
|
+
console.log(`Downloaded generic binary: ${BINARY_NAME}`);
|
|
146
112
|
} else {
|
|
147
|
-
console.error(
|
|
148
|
-
|
|
149
|
-
|
|
113
|
+
console.error(
|
|
114
|
+
`Failed to download binary from:\n ${platformUrl}\n ${genericUrl}`
|
|
115
|
+
);
|
|
150
116
|
process.exit(1);
|
|
151
117
|
}
|
|
152
118
|
|
|
153
119
|
if (process.platform !== 'win32') {
|
|
154
120
|
fs.chmodSync(binaryPath, 0o755);
|
|
155
|
-
console.log('Made binary executable.');
|
|
156
121
|
}
|
|
157
122
|
|
|
158
|
-
console.log(
|
|
123
|
+
console.log(`Binary installed at: ${binaryPath}`);
|
|
159
124
|
}
|
|
160
125
|
|
|
161
126
|
main().catch((err) => {
|
|
162
|
-
console.error('
|
|
127
|
+
console.error('Error:', err.message);
|
|
163
128
|
process.exit(1);
|
|
164
129
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "codebuff-cli",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.15",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"bin": {
|
|
6
6
|
"codebuff": "cli/bin/codebuff.cjs",
|
|
@@ -10,7 +10,8 @@
|
|
|
10
10
|
"cli/bin/codebuff.cjs",
|
|
11
11
|
"cli/scripts/download-binary.cjs",
|
|
12
12
|
"README.md",
|
|
13
|
-
"LICENSE"
|
|
13
|
+
"LICENSE",
|
|
14
|
+
"NOTICE"
|
|
14
15
|
],
|
|
15
16
|
"publishConfig": {
|
|
16
17
|
"access": "public"
|
|
@@ -42,7 +43,8 @@
|
|
|
42
43
|
"test": "bun --filter='{@codebuff/common,@codebuff/agents,@codebuff/agent-runtime,@codebuff/sdk,@codebuff/cli,@codebuff/evals,@codebuff/scripts}' run test",
|
|
43
44
|
"init-worktree": "bun scripts/init-worktree.ts",
|
|
44
45
|
"cleanup-worktree": "bun scripts/cleanup-worktree.ts",
|
|
45
|
-
"generate-tool-definitions": "bun scripts/generate-tool-definitions.ts"
|
|
46
|
+
"generate-tool-definitions": "bun scripts/generate-tool-definitions.ts",
|
|
47
|
+
"postinstall": "node cli/scripts/download-binary.cjs"
|
|
46
48
|
},
|
|
47
49
|
"dependencies": {
|
|
48
50
|
"@t3-oss/env-nextjs": "^0.7.3",
|
package/cli/bin/codebuff.cjs
DELETED
|
@@ -1,165 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
const { spawn } = require('child_process');
|
|
3
|
-
const fs = require('fs');
|
|
4
|
-
const path = require('path');
|
|
5
|
-
const os = require('os');
|
|
6
|
-
const https = require('https');
|
|
7
|
-
const http = require('http');
|
|
8
|
-
|
|
9
|
-
const BINARY_NAME = 'codebuff';
|
|
10
|
-
const REPO = 'Marcus-Mok-GH/codebuff-cli';
|
|
11
|
-
|
|
12
|
-
const moduleBinary = path.join(__dirname, process.platform === 'win32' ? `${BINARY_NAME}.exe` : BINARY_NAME);
|
|
13
|
-
const localDir = path.join(os.homedir(), '.codebuff', 'bin');
|
|
14
|
-
const localBinary = path.join(localDir, process.platform === 'win32' ? `${BINARY_NAME}.exe` : BINARY_NAME);
|
|
15
|
-
|
|
16
|
-
function resolveBinaryPath() {
|
|
17
|
-
if (fs.existsSync(localBinary)) return localBinary;
|
|
18
|
-
if (fs.existsSync(moduleBinary)) return moduleBinary;
|
|
19
|
-
return null;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
function getVersion() {
|
|
23
|
-
const candidates = [
|
|
24
|
-
path.join(__dirname, '..', '..', 'package.json'),
|
|
25
|
-
path.join(__dirname, '..', 'package.json'),
|
|
26
|
-
];
|
|
27
|
-
for (const p of candidates) {
|
|
28
|
-
try {
|
|
29
|
-
const pkg = JSON.parse(fs.readFileSync(p, 'utf8'));
|
|
30
|
-
if (pkg.version) return pkg.version;
|
|
31
|
-
} catch {}
|
|
32
|
-
}
|
|
33
|
-
return null;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
function download(url, dest) {
|
|
37
|
-
return new Promise((resolve, reject) => {
|
|
38
|
-
const client = url.startsWith('https:') ? https : http;
|
|
39
|
-
const file = fs.createWriteStream(dest);
|
|
40
|
-
|
|
41
|
-
const req = client.get(
|
|
42
|
-
url,
|
|
43
|
-
{ headers: { 'User-Agent': 'codebuff-cli-installer' } },
|
|
44
|
-
(res) => {
|
|
45
|
-
if (res.statusCode === 301 || res.statusCode === 302) {
|
|
46
|
-
file.close();
|
|
47
|
-
if (fs.existsSync(dest)) fs.unlinkSync(dest);
|
|
48
|
-
download(new URL(res.headers.location, url).href, dest)
|
|
49
|
-
.then(resolve)
|
|
50
|
-
.catch(reject);
|
|
51
|
-
return;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
if (res.statusCode !== 200) {
|
|
55
|
-
file.close();
|
|
56
|
-
if (fs.existsSync(dest)) fs.unlinkSync(dest);
|
|
57
|
-
reject(new Error(`HTTP ${res.statusCode}`));
|
|
58
|
-
return;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
res.pipe(file);
|
|
62
|
-
file.on('finish', () => {
|
|
63
|
-
file.close();
|
|
64
|
-
resolve();
|
|
65
|
-
});
|
|
66
|
-
}
|
|
67
|
-
);
|
|
68
|
-
|
|
69
|
-
req.on('error', (err) => {
|
|
70
|
-
file.close();
|
|
71
|
-
if (fs.existsSync(dest)) fs.unlinkSync(dest);
|
|
72
|
-
reject(err);
|
|
73
|
-
});
|
|
74
|
-
|
|
75
|
-
req.setTimeout(30000, () => {
|
|
76
|
-
req.destroy();
|
|
77
|
-
file.close();
|
|
78
|
-
if (fs.existsSync(dest)) fs.unlinkSync(dest);
|
|
79
|
-
reject(new Error('Request timeout'));
|
|
80
|
-
});
|
|
81
|
-
});
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
async function tryDownload(url, dest) {
|
|
85
|
-
try {
|
|
86
|
-
await download(url, dest);
|
|
87
|
-
return true;
|
|
88
|
-
} catch {
|
|
89
|
-
return false;
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
async function downloadBinary(destPath) {
|
|
94
|
-
const version = getVersion();
|
|
95
|
-
if (!version) {
|
|
96
|
-
throw new Error('Could not determine version from package.json');
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
const baseUrl = `https://github.com/${REPO}/releases/download/v${version}`;
|
|
100
|
-
const platformName = `${BINARY_NAME}-${process.platform}-${process.arch}${process.platform === 'win32' ? '.exe' : ''}`;
|
|
101
|
-
const platformUrl = `${baseUrl}/${platformName}`;
|
|
102
|
-
const genericUrl = `${baseUrl}/${BINARY_NAME}`;
|
|
103
|
-
|
|
104
|
-
fs.mkdirSync(path.dirname(destPath), { recursive: true });
|
|
105
|
-
|
|
106
|
-
if (await tryDownload(platformUrl, destPath)) {
|
|
107
|
-
console.log(`Downloaded platform-specific binary: ${platformName}`);
|
|
108
|
-
} else if (await tryDownload(genericUrl, destPath)) {
|
|
109
|
-
console.log(`Downloaded generic binary: ${BINARY_NAME}`);
|
|
110
|
-
} else {
|
|
111
|
-
throw new Error(
|
|
112
|
-
`Failed to download binary from:\n ${platformUrl}\n ${genericUrl}`
|
|
113
|
-
);
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
if (process.platform !== 'win32') {
|
|
117
|
-
fs.chmodSync(destPath, 0o755);
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
function runBinary(binaryPath) {
|
|
122
|
-
const child = spawn(binaryPath, process.argv.slice(2), {
|
|
123
|
-
stdio: 'inherit',
|
|
124
|
-
});
|
|
125
|
-
|
|
126
|
-
child.on('exit', (code, signal) => {
|
|
127
|
-
process.exit(signal ? 1 : code || 0);
|
|
128
|
-
});
|
|
129
|
-
|
|
130
|
-
child.on('error', (err) => {
|
|
131
|
-
console.error('Failed to start codebuff:', err.message);
|
|
132
|
-
process.exit(1);
|
|
133
|
-
});
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
async function main() {
|
|
137
|
-
let binaryPath = resolveBinaryPath();
|
|
138
|
-
|
|
139
|
-
if (binaryPath) {
|
|
140
|
-
runBinary(binaryPath);
|
|
141
|
-
return;
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
console.log('Codebuff binary not found. Downloading...');
|
|
145
|
-
|
|
146
|
-
try {
|
|
147
|
-
await downloadBinary(localBinary);
|
|
148
|
-
binaryPath = localBinary;
|
|
149
|
-
} catch (err) {
|
|
150
|
-
console.error('Failed to download codebuff:', err.message);
|
|
151
|
-
process.exit(1);
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
if (!fs.existsSync(binaryPath)) {
|
|
155
|
-
console.error('Binary still not found after download.');
|
|
156
|
-
process.exit(1);
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
runBinary(binaryPath);
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
main().catch((err) => {
|
|
163
|
-
console.error('Error:', err.message);
|
|
164
|
-
process.exit(1);
|
|
165
|
-
});
|