codecane 1.0.404 → 1.0.406

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codecane",
3
- "version": "1.0.404",
3
+ "version": "1.0.406",
4
4
  "description": "AI coding agent",
5
5
  "license": "MIT",
6
6
  "bin": {
@@ -30,6 +30,23 @@ const PLATFORM_TARGETS = {
30
30
  'win32-x64': 'codebuff-win32-x64.zip',
31
31
  }
32
32
 
33
+ // Terminal utilities
34
+ const term = {
35
+ clearLine: () => {
36
+ if (process.stderr.isTTY) {
37
+ process.stderr.write('\r\x1b[K')
38
+ }
39
+ },
40
+ write: (text) => {
41
+ term.clearLine()
42
+ process.stderr.write(text)
43
+ },
44
+ writeLine: (text) => {
45
+ term.clearLine()
46
+ process.stderr.write(text + '\n')
47
+ },
48
+ }
49
+
33
50
  // Utility functions
34
51
  function httpGet(url, options = {}) {
35
52
  return new Promise((resolve, reject) => {
@@ -112,14 +129,22 @@ function compareVersions(v1, v2) {
112
129
  return 0
113
130
  }
114
131
 
115
- function showProgress(downloaded, total) {
116
- if (total > 0) {
117
- const percentage = Math.round((downloaded / total) * 100)
118
- process.stderr.write(`\r${percentage}%`)
119
- } else {
120
- const downloadedMB = (downloaded / 1024 / 1024).toFixed(1)
121
- process.stderr.write(`\r${downloadedMB} MB`)
122
- }
132
+ function formatBytes(bytes) {
133
+ if (bytes === 0) return '0 B'
134
+ const k = 1024
135
+ const sizes = ['B', 'KB', 'MB', 'GB']
136
+ const i = Math.floor(Math.log(bytes) / Math.log(k))
137
+ return parseFloat((bytes / Math.pow(k, i)).toFixed(1)) + ' ' + sizes[i]
138
+ }
139
+
140
+ function formatSpeed(bytesPerSecond) {
141
+ return formatBytes(bytesPerSecond) + '/s'
142
+ }
143
+
144
+ function createProgressBar(percentage, width = 30) {
145
+ const filled = Math.round((width * percentage) / 100)
146
+ const empty = width - filled
147
+ return '[' + '█'.repeat(filled) + '░'.repeat(empty) + ']'
123
148
  }
124
149
 
125
150
  async function downloadBinary(version) {
@@ -135,7 +160,7 @@ async function downloadBinary(version) {
135
160
  // Ensure config directory exists
136
161
  fs.mkdirSync(CONFIG.configDir, { recursive: true })
137
162
 
138
- console.log(`Downloading codebuff v${version}...`)
163
+ term.write(`Downloading codebuff v${version}...`)
139
164
 
140
165
  const res = await httpGet(downloadUrl)
141
166
 
@@ -146,6 +171,7 @@ async function downloadBinary(version) {
146
171
  const totalSize = parseInt(res.headers['content-length'] || '0', 10)
147
172
  let downloadedSize = 0
148
173
  let lastProgressTime = Date.now()
174
+ let lastDownloadedSize = 0
149
175
 
150
176
  const chunks = []
151
177
 
@@ -155,13 +181,27 @@ async function downloadBinary(version) {
155
181
 
156
182
  const now = Date.now()
157
183
  if (now - lastProgressTime >= 100 || downloadedSize === totalSize) {
184
+ const elapsedSeconds = (now - lastProgressTime) / 1000
185
+ const bytesThisInterval = downloadedSize - lastDownloadedSize
186
+ const speed = bytesThisInterval / elapsedSeconds
187
+
158
188
  lastProgressTime = now
159
- showProgress(downloadedSize, totalSize)
189
+ lastDownloadedSize = downloadedSize
190
+
191
+ if (totalSize > 0) {
192
+ const percentage = Math.round((downloadedSize / totalSize) * 100)
193
+ const progressBar = createProgressBar(percentage)
194
+ // const sizeInfo = `${formatBytes(downloadedSize)}/${formatBytes(totalSize)}`
195
+ const speedInfo = speed > 0 ? formatSpeed(speed) : ''
196
+
197
+ term.write(`Downloading... ${progressBar} ${percentage}% ${speedInfo}`)
198
+ } else {
199
+ term.write(`Downloading... ${formatBytes(downloadedSize)}`)
200
+ }
160
201
  }
161
202
  }
162
203
 
163
- process.stderr.write('\n')
164
- console.log('Extracting...')
204
+ term.write('Extracting...')
165
205
 
166
206
  const buffer = Buffer.concat(chunks)
167
207
 
@@ -200,6 +240,9 @@ async function downloadBinary(version) {
200
240
  } else {
201
241
  throw new Error(`Binary not found after extraction`)
202
242
  }
243
+
244
+ // Clear the line after successful download
245
+ term.clearLine()
203
246
  }
204
247
 
205
248
  async function ensureBinaryExists() {
@@ -214,6 +257,7 @@ async function ensureBinaryExists() {
214
257
  try {
215
258
  await downloadBinary(version)
216
259
  } catch (error) {
260
+ term.clearLine()
217
261
  console.error('❌ Failed to download codebuff:', error.message)
218
262
  console.error('Please try again later.')
219
263
  process.exit(1)
@@ -240,11 +284,9 @@ async function checkForUpdates(runningProcess, exitListener) {
240
284
  const latestVersion = await getLatestVersion()
241
285
  if (!latestVersion) return
242
286
 
243
- console.log(`Current version: ${currentVersion}`)
244
- console.log(`Latest version: ${latestVersion}`)
245
-
246
287
  if (compareVersions(currentVersion, latestVersion) < 0) {
247
- process.stdout.write(`Updating...`)
288
+ term.clearLine()
289
+ console.log(`\nUpdate available: ${currentVersion} → ${latestVersion}`)
248
290
 
249
291
  // Remove the specific exit listener to prevent it from interfering with the update
250
292
  runningProcess.removeListener('exit', exitListener)
@@ -266,15 +308,20 @@ async function checkForUpdates(runningProcess, exitListener) {
266
308
 
267
309
  await downloadBinary(latestVersion)
268
310
 
269
- // Restart with new binary
311
+ // Restart with new binary - this replaces the current process
270
312
  const newChild = spawn(CONFIG.binaryPath, process.argv.slice(2), {
271
313
  stdio: 'inherit',
272
314
  cwd: process.cwd(),
315
+ detached: false,
273
316
  })
274
317
 
318
+ // Set up exit handler for the new process
275
319
  newChild.on('exit', (code) => {
276
320
  process.exit(code || 0)
277
321
  })
322
+
323
+ // Don't return - keep this function running to maintain the wrapper
324
+ return new Promise(() => {}) // Never resolves, keeps wrapper alive
278
325
  }
279
326
  } catch (error) {
280
327
  // Silently ignore update check errors
@@ -282,7 +329,6 @@ async function checkForUpdates(runningProcess, exitListener) {
282
329
  }
283
330
 
284
331
  async function main() {
285
- // Ensure binary exists
286
332
  await ensureBinaryExists()
287
333
 
288
334
  // Start codebuff