codecane 1.0.403 → 1.0.405
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 +1 -1
- package/scripts/codebuff-wrapper.js +87 -23
package/package.json
CHANGED
|
@@ -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
|
|
116
|
-
if (
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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)
|
|
@@ -232,7 +276,7 @@ async function ensureBinaryExists() {
|
|
|
232
276
|
}
|
|
233
277
|
}
|
|
234
278
|
|
|
235
|
-
async function checkForUpdates(runningProcess) {
|
|
279
|
+
async function checkForUpdates(runningProcess, exitListener) {
|
|
236
280
|
try {
|
|
237
281
|
const currentVersion = getCurrentVersion()
|
|
238
282
|
if (!currentVersion) return
|
|
@@ -241,25 +285,43 @@ async function checkForUpdates(runningProcess) {
|
|
|
241
285
|
if (!latestVersion) return
|
|
242
286
|
|
|
243
287
|
if (compareVersions(currentVersion, latestVersion) < 0) {
|
|
244
|
-
|
|
288
|
+
term.clearLine()
|
|
289
|
+
console.log(`\nUpdate available: ${currentVersion} → ${latestVersion}`)
|
|
290
|
+
|
|
291
|
+
// Remove the specific exit listener to prevent it from interfering with the update
|
|
292
|
+
runningProcess.removeListener('exit', exitListener)
|
|
245
293
|
|
|
246
294
|
// Kill the running process
|
|
247
295
|
runningProcess.kill('SIGTERM')
|
|
248
296
|
|
|
249
|
-
// Wait for
|
|
250
|
-
await new Promise((resolve) =>
|
|
297
|
+
// Wait for the process to actually exit
|
|
298
|
+
await new Promise((resolve) => {
|
|
299
|
+
runningProcess.on('exit', resolve)
|
|
300
|
+
// Fallback timeout in case the process doesn't exit gracefully
|
|
301
|
+
setTimeout(() => {
|
|
302
|
+
if (!runningProcess.killed) {
|
|
303
|
+
runningProcess.kill('SIGKILL')
|
|
304
|
+
}
|
|
305
|
+
resolve()
|
|
306
|
+
}, 5000)
|
|
307
|
+
})
|
|
251
308
|
|
|
252
309
|
await downloadBinary(latestVersion)
|
|
253
310
|
|
|
254
|
-
// Restart with new binary
|
|
311
|
+
// Restart with new binary - this replaces the current process
|
|
255
312
|
const newChild = spawn(CONFIG.binaryPath, process.argv.slice(2), {
|
|
256
313
|
stdio: 'inherit',
|
|
257
314
|
cwd: process.cwd(),
|
|
315
|
+
detached: false,
|
|
258
316
|
})
|
|
259
317
|
|
|
318
|
+
// Set up exit handler for the new process
|
|
260
319
|
newChild.on('exit', (code) => {
|
|
261
320
|
process.exit(code || 0)
|
|
262
321
|
})
|
|
322
|
+
|
|
323
|
+
// Don't return - keep this function running to maintain the wrapper
|
|
324
|
+
return new Promise(() => {}) // Never resolves, keeps wrapper alive
|
|
263
325
|
}
|
|
264
326
|
} catch (error) {
|
|
265
327
|
// Silently ignore update check errors
|
|
@@ -267,7 +329,6 @@ async function checkForUpdates(runningProcess) {
|
|
|
267
329
|
}
|
|
268
330
|
|
|
269
331
|
async function main() {
|
|
270
|
-
// Ensure binary exists
|
|
271
332
|
await ensureBinaryExists()
|
|
272
333
|
|
|
273
334
|
// Start codebuff
|
|
@@ -276,14 +337,17 @@ async function main() {
|
|
|
276
337
|
cwd: process.cwd(),
|
|
277
338
|
})
|
|
278
339
|
|
|
340
|
+
// Store reference to the exit listener so we can remove it during updates
|
|
341
|
+
const exitListener = (code) => {
|
|
342
|
+
process.exit(code || 0)
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
child.on('exit', exitListener)
|
|
346
|
+
|
|
279
347
|
// Check for updates in background
|
|
280
348
|
setTimeout(() => {
|
|
281
|
-
checkForUpdates(child)
|
|
349
|
+
checkForUpdates(child, exitListener)
|
|
282
350
|
}, 100)
|
|
283
|
-
|
|
284
|
-
child.on('exit', (code) => {
|
|
285
|
-
process.exit(code || 0)
|
|
286
|
-
})
|
|
287
351
|
}
|
|
288
352
|
|
|
289
353
|
// Run the main function
|