codebuff-cli 1.0.12 → 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.
@@ -7,9 +7,6 @@ const os = require('os');
7
7
 
8
8
  const REPO = 'Marcus-Mok-GH/codebuff-cli';
9
9
  const BINARY_NAME = 'codebuff';
10
- const MAX_RETRIES = 3;
11
- const REQUEST_TIMEOUT_MS = 120000;
12
- const MAX_REDIRECTS = 10;
13
10
 
14
11
  function getVersion() {
15
12
  const candidates = [
@@ -26,28 +23,13 @@ function getVersion() {
26
23
  }
27
24
 
28
25
  function getBinaryPath() {
29
- const binDir = path.join(os.homedir(), '.codebuff', 'bin');
26
+ const binDir = path.join(os.homedir(), '.codebuff');
30
27
  const name = process.platform === 'win32' ? `${BINARY_NAME}.exe` : BINARY_NAME;
31
28
  return path.join(binDir, name);
32
29
  }
33
30
 
34
- function cleanup(dest) {
35
- try {
36
- if (fs.existsSync(dest)) {
37
- fs.unlinkSync(dest);
38
- }
39
- } catch {
40
- // ignore cleanup errors
41
- }
42
- }
43
-
44
- function download(url, dest, redirectCount = 0) {
31
+ function download(url, dest) {
45
32
  return new Promise((resolve, reject) => {
46
- if (redirectCount > MAX_REDIRECTS) {
47
- reject(new Error(`Too many redirects (max ${MAX_REDIRECTS}) while downloading from ${url}`));
48
- return;
49
- }
50
-
51
33
  const client = url.startsWith('https:') ? https : http;
52
34
  const file = fs.createWriteStream(dest);
53
35
 
@@ -55,10 +37,10 @@ function download(url, dest, redirectCount = 0) {
55
37
  url,
56
38
  { headers: { 'User-Agent': 'codebuff-cli-installer' } },
57
39
  (res) => {
58
- if (res.statusCode === 301 || res.statusCode === 302 || res.statusCode === 307 || res.statusCode === 308) {
40
+ if (res.statusCode === 301 || res.statusCode === 302) {
59
41
  file.close();
60
- cleanup(dest);
61
- 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)
62
44
  .then(resolve)
63
45
  .catch(reject);
64
46
  return;
@@ -66,8 +48,8 @@ function download(url, dest, redirectCount = 0) {
66
48
 
67
49
  if (res.statusCode !== 200) {
68
50
  file.close();
69
- cleanup(dest);
70
- reject(new Error(`Failed to download from ${url}: HTTP ${res.statusCode}`));
51
+ if (fs.existsSync(dest)) fs.unlinkSync(dest);
52
+ reject(new Error(`HTTP ${res.statusCode}`));
71
53
  return;
72
54
  }
73
55
 
@@ -81,36 +63,26 @@ function download(url, dest, redirectCount = 0) {
81
63
 
82
64
  req.on('error', (err) => {
83
65
  file.close();
84
- cleanup(dest);
85
- reject(new Error(`Request failed for ${url}: ${err.message}`));
66
+ if (fs.existsSync(dest)) fs.unlinkSync(dest);
67
+ reject(err);
86
68
  });
87
69
 
88
- req.setTimeout(REQUEST_TIMEOUT_MS, () => {
70
+ req.setTimeout(30000, () => {
89
71
  req.destroy();
90
72
  file.close();
91
- cleanup(dest);
92
- reject(new Error(`Request timeout after ${REQUEST_TIMEOUT_MS}ms for ${url}`));
73
+ if (fs.existsSync(dest)) fs.unlinkSync(dest);
74
+ reject(new Error('Request timeout'));
93
75
  });
94
76
  });
95
77
  }
96
78
 
97
- async function downloadWithRetry(url, dest, retries = MAX_RETRIES) {
98
- let lastError;
99
- for (let attempt = 0; attempt <= retries; attempt++) {
100
- try {
101
- await download(url, dest);
102
- return true;
103
- } catch (err) {
104
- lastError = err;
105
- if (attempt < retries) {
106
- const delay = Math.pow(2, attempt) * 1000;
107
- console.warn(`Download attempt ${attempt + 1} failed for ${url}, retrying in ${delay}ms...`);
108
- await new Promise((resolve) => setTimeout(resolve, delay));
109
- }
110
- }
79
+ async function tryDownload(url, dest) {
80
+ try {
81
+ await download(url, dest);
82
+ return true;
83
+ } catch {
84
+ return false;
111
85
  }
112
- console.error(`Download failed after ${retries + 1} attempts for ${url}: ${lastError.message}`);
113
- return false;
114
86
  }
115
87
 
116
88
  async function main() {
@@ -133,9 +105,9 @@ async function main() {
133
105
 
134
106
  fs.mkdirSync(path.dirname(binaryPath), { recursive: true });
135
107
 
136
- if (await downloadWithRetry(platformUrl, binaryPath)) {
108
+ if (await tryDownload(platformUrl, binaryPath)) {
137
109
  console.log(`Downloaded platform-specific binary: ${platformName}`);
138
- } else if (await downloadWithRetry(genericUrl, binaryPath)) {
110
+ } else if (await tryDownload(genericUrl, binaryPath)) {
139
111
  console.log(`Downloaded generic binary: ${BINARY_NAME}`);
140
112
  } else {
141
113
  console.error(
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codebuff-cli",
3
- "version": "1.0.12",
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
- });