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 ADDED
@@ -0,0 +1,4 @@
1
+ Codebuff
2
+ Copyright 2025 Codebuff
3
+
4
+ This product includes software developed for the Codebuff project.
@@ -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 pkgPath = path.join(__dirname, '..', 'package.json');
15
- try {
16
- const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8'));
17
- if (pkg.version) return pkg.version;
18
- } catch {}
19
- throw new Error('Could not determine version from ' + pkgPath);
20
- }
21
-
22
- function getPlatform() {
23
- const platform = process.platform;
24
- const arch = process.arch;
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(__dirname, '..', 'bin');
36
- const name = process.platform === 'win32' ? BINARY_NAME + '.exe' : 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 cleanup(dest) {
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 || res.statusCode === 307 || res.statusCode === 308) {
40
+ if (res.statusCode === 301 || res.statusCode === 302) {
65
41
  file.close();
66
- cleanup(dest);
67
- download(new URL(res.headers.location, url).href, dest, redirectCount + 1)
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
- cleanup(dest);
76
- reject(new Error('Download failed: HTTP ' + res.statusCode + ' from ' + url));
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
- cleanup(dest);
91
- reject(new Error('Network error downloading from ' + url + ': ' + err.message));
66
+ if (fs.existsSync(dest)) fs.unlinkSync(dest);
67
+ reject(err);
92
68
  });
93
69
 
94
- req.setTimeout(REQUEST_TIMEOUT_MS, () => {
70
+ req.setTimeout(30000, () => {
95
71
  req.destroy();
96
72
  file.close();
97
- cleanup(dest);
98
- reject(new Error('Download timeout (' + REQUEST_TIMEOUT_MS + 'ms) for ' + url));
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 downloadWithRetry(url, dest) {
104
- let lastError;
105
- for (let attempt = 1; attempt <= MAX_RETRIES; attempt++) {
106
- try {
107
- console.log('Downloading binary (attempt ' + attempt + '/' + MAX_RETRIES + ')...');
108
- await download(url, dest);
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
- const url = 'https://github.com/' + REPO + '/releases/download/v' + version + '/codebuff-' + platform;
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
- console.log('Platform: ' + platform);
133
- console.log('Version: ' + version);
134
- console.log('Binary path: ' + binaryPath);
135
- console.log('Download URL: ' + url);
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 (fs.existsSync(binaryPath)) {
140
- console.log('Binary already exists. Skipping download.');
141
- process.exit(0);
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('\nUnable to download the codebuff binary.');
148
- console.error('You can try installing manually from:');
149
- console.error(' ' + url);
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('Binary installed at: ' + binaryPath);
123
+ console.log(`Binary installed at: ${binaryPath}`);
159
124
  }
160
125
 
161
126
  main().catch((err) => {
162
- console.error('Fatal error:', err.message);
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.14",
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",
@@ -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
- });