codebuff 1.0.633 → 1.0.634

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.
Files changed (3) hide show
  1. package/README.md +38 -0
  2. package/index.js +109 -11
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -56,6 +56,8 @@ Some have said every change should be paired with a unit test. In 2024, every ch
56
56
 
57
57
  ## Troubleshooting
58
58
 
59
+ ### Permission Errors
60
+
59
61
  If you are getting permission errors during installation, try using sudo:
60
62
 
61
63
  ```
@@ -64,6 +66,42 @@ sudo npm install -g codebuff
64
66
 
65
67
  If you still have errors, it's a good idea to [reinstall Node](https://nodejs.org/en/download).
66
68
 
69
+ ### Corporate Proxy / Firewall
70
+
71
+ If you see `Failed to download codebuff: Request timeout` or `Failed to determine latest version`, you may be behind a corporate proxy or firewall.
72
+
73
+ Codebuff respects standard proxy environment variables. Set `HTTPS_PROXY` to route traffic through your proxy:
74
+
75
+ **Linux / macOS (bash/zsh):**
76
+ ```bash
77
+ export HTTPS_PROXY=http://your-proxy-server:port
78
+ codebuff
79
+ ```
80
+
81
+ **Windows (PowerShell):**
82
+ ```powershell
83
+ $env:HTTPS_PROXY = "http://your-proxy-server:port"
84
+ codebuff
85
+ ```
86
+
87
+ **Windows (CMD):**
88
+ ```cmd
89
+ set HTTPS_PROXY=http://your-proxy-server:port
90
+ codebuff
91
+ ```
92
+
93
+ To make it permanent, add the `export` or `set` line to your shell profile (e.g. `~/.bashrc`, `~/.zshrc`, or Windows System Environment Variables).
94
+
95
+ **Supported environment variables:**
96
+
97
+ | Variable | Purpose |
98
+ |---|---|
99
+ | `HTTPS_PROXY` / `https_proxy` | Proxy for HTTPS requests (recommended) |
100
+ | `HTTP_PROXY` / `http_proxy` | Fallback proxy for HTTP requests |
101
+ | `NO_PROXY` / `no_proxy` | Comma-separated list of hostnames to bypass the proxy (port suffixes are ignored) |
102
+
103
+ Both `http://` and `https://` proxy URLs are supported. Proxy authentication is supported via URL credentials (e.g. `http://user:password@proxy:port`).
104
+
67
105
  ## Feedback
68
106
 
69
107
  We value your input! Please email your feedback to `founders@codebuff.com`. Thank you for using Codebuff!
package/index.js CHANGED
@@ -6,6 +6,7 @@ const http = require('http')
6
6
  const https = require('https')
7
7
  const os = require('os')
8
8
  const path = require('path')
9
+ const tls = require('tls')
9
10
  const zlib = require('zlib')
10
11
 
11
12
  const tar = require('tar')
@@ -95,6 +96,76 @@ function trackUpdateFailed(errorMessage, version, context = {}) {
95
96
  }
96
97
  }
97
98
 
99
+ function getProxyUrl() {
100
+ return (
101
+ process.env.HTTPS_PROXY ||
102
+ process.env.https_proxy ||
103
+ process.env.HTTP_PROXY ||
104
+ process.env.http_proxy ||
105
+ null
106
+ )
107
+ }
108
+
109
+ function shouldBypassProxy(hostname) {
110
+ const noProxy = process.env.NO_PROXY || process.env.no_proxy || ''
111
+ if (!noProxy) return false
112
+ const domains = noProxy.split(',').map((d) => d.trim().toLowerCase().replace(/:\d+$/, ''))
113
+ const host = hostname.toLowerCase()
114
+ return domains.some((d) => {
115
+ if (d === '*') return true
116
+ if (d.startsWith('.')) return host.endsWith(d) || host === d.slice(1)
117
+ return host === d || host.endsWith('.' + d)
118
+ })
119
+ }
120
+
121
+ function connectThroughProxy(proxyUrl, targetHost, targetPort) {
122
+ return new Promise((resolve, reject) => {
123
+ const proxy = new URL(proxyUrl)
124
+ const isHttpsProxy = proxy.protocol === 'https:'
125
+ const connectOptions = {
126
+ hostname: proxy.hostname,
127
+ port: proxy.port || (isHttpsProxy ? 443 : 80),
128
+ method: 'CONNECT',
129
+ path: `${targetHost}:${targetPort}`,
130
+ headers: {
131
+ Host: `${targetHost}:${targetPort}`,
132
+ },
133
+ }
134
+
135
+ if (proxy.username || proxy.password) {
136
+ const auth = Buffer.from(
137
+ `${decodeURIComponent(proxy.username || '')}:${decodeURIComponent(proxy.password || '')}`,
138
+ ).toString('base64')
139
+ connectOptions.headers['Proxy-Authorization'] = `Basic ${auth}`
140
+ }
141
+
142
+ const transport = isHttpsProxy ? https : http
143
+ const req = transport.request(connectOptions)
144
+
145
+ req.on('connect', (res, socket) => {
146
+ if (res.statusCode === 200) {
147
+ resolve(socket)
148
+ } else {
149
+ socket.destroy()
150
+ reject(
151
+ new Error(`Proxy CONNECT failed with status ${res.statusCode}`),
152
+ )
153
+ }
154
+ })
155
+
156
+ req.on('error', (err) => {
157
+ reject(new Error(`Proxy connection failed: ${err.message}`))
158
+ })
159
+
160
+ req.setTimeout(CONFIG.requestTimeout, () => {
161
+ req.destroy()
162
+ reject(new Error('Proxy connection timeout.'))
163
+ })
164
+
165
+ req.end()
166
+ })
167
+ }
168
+
98
169
  const PLATFORM_TARGETS = {
99
170
  'linux-x64': `${packageName}-linux-x64.tar.gz`,
100
171
  'linux-arm64': `${packageName}-linux-arm64.tar.gz`,
@@ -119,20 +190,37 @@ const term = {
119
190
  },
120
191
  }
121
192
 
122
- function httpGet(url, options = {}) {
123
- return new Promise((resolve, reject) => {
124
- const parsedUrl = new URL(url)
125
- const reqOptions = {
126
- hostname: parsedUrl.hostname,
127
- path: parsedUrl.pathname + parsedUrl.search,
128
- headers: {
129
- 'User-Agent': CONFIG.userAgent,
130
- ...options.headers,
131
- },
132
- }
193
+ async function httpGet(url, options = {}) {
194
+ const parsedUrl = new URL(url)
195
+ const proxyUrl = getProxyUrl()
196
+
197
+ const reqOptions = {
198
+ hostname: parsedUrl.hostname,
199
+ path: parsedUrl.pathname + parsedUrl.search,
200
+ headers: {
201
+ 'User-Agent': CONFIG.userAgent,
202
+ ...options.headers,
203
+ },
204
+ }
205
+
206
+ if (proxyUrl && !shouldBypassProxy(parsedUrl.hostname)) {
207
+ const tunnelSocket = await connectThroughProxy(
208
+ proxyUrl,
209
+ parsedUrl.hostname,
210
+ parsedUrl.port || 443,
211
+ )
212
+ reqOptions.agent = false
213
+ reqOptions.createConnection = () =>
214
+ tls.connect({
215
+ socket: tunnelSocket,
216
+ servername: parsedUrl.hostname,
217
+ })
218
+ }
133
219
 
220
+ return new Promise((resolve, reject) => {
134
221
  const req = https.get(reqOptions, (res) => {
135
222
  if (res.statusCode === 302 || res.statusCode === 301) {
223
+ res.resume()
136
224
  return httpGet(new URL(res.headers.location, url).href, options)
137
225
  .then(resolve)
138
226
  .catch(reject)
@@ -400,6 +488,11 @@ async function ensureBinaryExists() {
400
488
  if (!version) {
401
489
  console.error('❌ Failed to determine latest version')
402
490
  console.error('Please check your internet connection and try again')
491
+ if (!getProxyUrl()) {
492
+ console.error(
493
+ 'If you are behind a proxy, set the HTTPS_PROXY environment variable',
494
+ )
495
+ }
403
496
  process.exit(1)
404
497
  }
405
498
 
@@ -409,6 +502,11 @@ async function ensureBinaryExists() {
409
502
  term.clearLine()
410
503
  console.error('❌ Failed to download codebuff:', error.message)
411
504
  console.error('Please check your internet connection and try again')
505
+ if (!getProxyUrl()) {
506
+ console.error(
507
+ 'If you are behind a proxy, set the HTTPS_PROXY environment variable',
508
+ )
509
+ }
412
510
  process.exit(1)
413
511
  }
414
512
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codebuff",
3
- "version": "1.0.633",
3
+ "version": "1.0.634",
4
4
  "description": "AI coding agent",
5
5
  "license": "MIT",
6
6
  "bin": {