codecane 1.0.420-beta.2 → 1.0.420-beta.200
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/README.md +1 -3
- package/index.js +41 -99
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -39,7 +39,7 @@ Once running, simply chat with Codecane to say what coding task you want done.
|
|
|
39
39
|
- Can run your tests or type checker or linter; can install packages
|
|
40
40
|
- It's powerful: ask Codecane to keep working until it reaches a condition and it will.
|
|
41
41
|
|
|
42
|
-
Our users regularly use Codecane to implement new features, write unit tests, refactor code,write scripts, or give advice.
|
|
42
|
+
Our users regularly use Codecane to implement new features, write unit tests, refactor code, write scripts, or give advice.
|
|
43
43
|
|
|
44
44
|
## Knowledge Files
|
|
45
45
|
|
|
@@ -69,5 +69,3 @@ If you still have errors, it's a good idea to [reinstall Node](https://nodejs.or
|
|
|
69
69
|
## Feedback
|
|
70
70
|
|
|
71
71
|
We value your input! Please email your feedback to `founders@codebuff.com`. Thank you for using Codecane!
|
|
72
|
-
|
|
73
|
-
<!-- Test comment for staging workflow -->
|
package/index.js
CHANGED
|
@@ -1,36 +1,34 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
const fs = require('fs')
|
|
4
|
-
const path = require('path')
|
|
5
|
-
const os = require('os')
|
|
6
3
|
const { spawn } = require('child_process')
|
|
4
|
+
const fs = require('fs')
|
|
7
5
|
const https = require('https')
|
|
6
|
+
const os = require('os')
|
|
7
|
+
const path = require('path')
|
|
8
8
|
const zlib = require('zlib')
|
|
9
|
+
|
|
9
10
|
const tar = require('tar')
|
|
10
11
|
|
|
11
|
-
// Hardcoded package name for codecane
|
|
12
12
|
const packageName = 'codecane'
|
|
13
13
|
|
|
14
14
|
function createConfig(packageName) {
|
|
15
15
|
const homeDir = os.homedir()
|
|
16
16
|
const configDir = path.join(homeDir, '.config', 'manicode')
|
|
17
|
-
const binaryName =
|
|
18
|
-
|
|
17
|
+
const binaryName =
|
|
18
|
+
process.platform === 'win32' ? `${packageName}.exe` : packageName
|
|
19
|
+
|
|
19
20
|
return {
|
|
20
21
|
homeDir,
|
|
21
22
|
configDir,
|
|
22
23
|
binaryName,
|
|
23
24
|
binaryPath: path.join(configDir, binaryName),
|
|
24
|
-
githubRepo: 'CodebuffAI/codebuff-community',
|
|
25
25
|
userAgent: `${packageName}-cli`,
|
|
26
26
|
requestTimeout: 20000,
|
|
27
|
-
isPrerelease: true, // codecane always looks for prereleases
|
|
28
27
|
}
|
|
29
28
|
}
|
|
30
29
|
|
|
31
30
|
const CONFIG = createConfig(packageName)
|
|
32
31
|
|
|
33
|
-
// Platform target mapping
|
|
34
32
|
const PLATFORM_TARGETS = {
|
|
35
33
|
'linux-x64': `${packageName}-linux-x64.tar.gz`,
|
|
36
34
|
'linux-arm64': `${packageName}-linux-arm64.tar.gz`,
|
|
@@ -39,7 +37,6 @@ const PLATFORM_TARGETS = {
|
|
|
39
37
|
'win32-x64': `${packageName}-win32-x64.tar.gz`,
|
|
40
38
|
}
|
|
41
39
|
|
|
42
|
-
// Terminal utilities
|
|
43
40
|
const term = {
|
|
44
41
|
clearLine: () => {
|
|
45
42
|
if (process.stderr.isTTY) {
|
|
@@ -56,7 +53,6 @@ const term = {
|
|
|
56
53
|
},
|
|
57
54
|
}
|
|
58
55
|
|
|
59
|
-
// Utility functions
|
|
60
56
|
function httpGet(url, options = {}) {
|
|
61
57
|
return new Promise((resolve, reject) => {
|
|
62
58
|
const parsedUrl = new URL(url)
|
|
@@ -69,13 +65,6 @@ function httpGet(url, options = {}) {
|
|
|
69
65
|
},
|
|
70
66
|
}
|
|
71
67
|
|
|
72
|
-
// Add GitHub token if available
|
|
73
|
-
const token = process.env.GITHUB_TOKEN
|
|
74
|
-
if (token) {
|
|
75
|
-
console.log('Using your GITHUB_TOKEN to download the latest version.')
|
|
76
|
-
reqOptions.headers.Authorization = `Bearer ${token}`
|
|
77
|
-
}
|
|
78
|
-
|
|
79
68
|
const req = https.get(reqOptions, (res) => {
|
|
80
69
|
if (res.statusCode === 302 || res.statusCode === 301) {
|
|
81
70
|
return httpGet(new URL(res.headers.location, url).href, options)
|
|
@@ -98,43 +87,15 @@ function httpGet(url, options = {}) {
|
|
|
98
87
|
async function getLatestVersion() {
|
|
99
88
|
try {
|
|
100
89
|
const res = await httpGet(
|
|
101
|
-
`https://
|
|
90
|
+
`https://registry.npmjs.org/${packageName}/latest`,
|
|
102
91
|
)
|
|
103
92
|
|
|
104
93
|
if (res.statusCode !== 200) return null
|
|
105
94
|
|
|
106
95
|
const body = await streamToString(res)
|
|
96
|
+
const packageData = JSON.parse(body)
|
|
107
97
|
|
|
108
|
-
|
|
109
|
-
const tagMatches = body.match(
|
|
110
|
-
/<id>tag:github\.com,2008:Repository\/\d+\/([^<]+)<\/id>/g
|
|
111
|
-
)
|
|
112
|
-
|
|
113
|
-
if (!tagMatches) return null
|
|
114
|
-
|
|
115
|
-
// Extract all version tags
|
|
116
|
-
const versions = tagMatches
|
|
117
|
-
.map((match) => {
|
|
118
|
-
const tagMatch = match.match(
|
|
119
|
-
/<id>tag:github\.com,2008:Repository\/\d+\/([^<]+)<\/id>/
|
|
120
|
-
)
|
|
121
|
-
return tagMatch ? tagMatch[1].replace(/^v/, '') : null
|
|
122
|
-
})
|
|
123
|
-
.filter(Boolean)
|
|
124
|
-
|
|
125
|
-
if (versions.length === 0) return null
|
|
126
|
-
|
|
127
|
-
// Filter versions based on whether we want prereleases or stable releases
|
|
128
|
-
const filteredVersions = versions.filter((version) => {
|
|
129
|
-
const isPrerelease = version.includes('-')
|
|
130
|
-
return CONFIG.isPrerelease === isPrerelease
|
|
131
|
-
})
|
|
132
|
-
|
|
133
|
-
if (filteredVersions.length === 0) return null
|
|
134
|
-
|
|
135
|
-
// Sort and return the latest version
|
|
136
|
-
filteredVersions.sort(compareVersions)
|
|
137
|
-
return filteredVersions[filteredVersions.length - 1]
|
|
98
|
+
return packageData.version || null
|
|
138
99
|
} catch (error) {
|
|
139
100
|
return null
|
|
140
101
|
}
|
|
@@ -212,7 +173,6 @@ function compareVersions(v1, v2) {
|
|
|
212
173
|
const p1 = parseVersion(v1)
|
|
213
174
|
const p2 = parseVersion(v2)
|
|
214
175
|
|
|
215
|
-
// Compare main version parts
|
|
216
176
|
for (let i = 0; i < Math.max(p1.main.length, p2.main.length); i++) {
|
|
217
177
|
const n1 = p1.main[i] || 0
|
|
218
178
|
const n2 = p2.main[i] || 0
|
|
@@ -221,15 +181,13 @@ function compareVersions(v1, v2) {
|
|
|
221
181
|
if (n1 > n2) return 1
|
|
222
182
|
}
|
|
223
183
|
|
|
224
|
-
// If main versions are equal, compare prerelease parts
|
|
225
184
|
if (p1.prerelease.length === 0 && p2.prerelease.length === 0) {
|
|
226
|
-
return 0
|
|
185
|
+
return 0
|
|
227
186
|
} else if (p1.prerelease.length === 0) {
|
|
228
|
-
return 1
|
|
187
|
+
return 1
|
|
229
188
|
} else if (p2.prerelease.length === 0) {
|
|
230
|
-
return -1
|
|
189
|
+
return -1
|
|
231
190
|
} else {
|
|
232
|
-
// Both have prerelease parts, compare them
|
|
233
191
|
for (
|
|
234
192
|
let i = 0;
|
|
235
193
|
i < Math.max(p1.prerelease.length, p2.prerelease.length);
|
|
@@ -238,7 +196,6 @@ function compareVersions(v1, v2) {
|
|
|
238
196
|
const pr1 = p1.prerelease[i] || ''
|
|
239
197
|
const pr2 = p2.prerelease[i] || ''
|
|
240
198
|
|
|
241
|
-
// Handle numeric vs. string parts
|
|
242
199
|
const isNum1 = !isNaN(parseInt(pr1))
|
|
243
200
|
const isNum2 = !isNaN(parseInt(pr2))
|
|
244
201
|
|
|
@@ -248,16 +205,16 @@ function compareVersions(v1, v2) {
|
|
|
248
205
|
if (num1 < num2) return -1
|
|
249
206
|
if (num1 > num2) return 1
|
|
250
207
|
} else if (isNum1 && !isNum2) {
|
|
251
|
-
return 1
|
|
208
|
+
return 1
|
|
252
209
|
} else if (!isNum1 && isNum2) {
|
|
253
210
|
return -1
|
|
254
|
-
} else {
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
211
|
+
} else if (pr1 < pr2) {
|
|
212
|
+
return -1
|
|
213
|
+
} else if (pr1 > pr2) {
|
|
214
|
+
return 1
|
|
258
215
|
}
|
|
259
216
|
}
|
|
260
|
-
return 0
|
|
217
|
+
return 0
|
|
261
218
|
}
|
|
262
219
|
}
|
|
263
220
|
|
|
@@ -283,9 +240,8 @@ async function downloadBinary(version) {
|
|
|
283
240
|
throw new Error(`Unsupported platform: ${process.platform} ${process.arch}`)
|
|
284
241
|
}
|
|
285
242
|
|
|
286
|
-
const downloadUrl =
|
|
243
|
+
const downloadUrl = `${process.env.NEXT_PUBLIC_CODEBUFF_APP_URL || 'https://codebuff.com'}/api/releases/download/${version}/${fileName}`
|
|
287
244
|
|
|
288
|
-
// Ensure config directory exists
|
|
289
245
|
fs.mkdirSync(CONFIG.configDir, { recursive: true })
|
|
290
246
|
|
|
291
247
|
if (fs.existsSync(CONFIG.binaryPath)) {
|
|
@@ -313,8 +269,8 @@ async function downloadBinary(version) {
|
|
|
313
269
|
const pct = Math.round((downloadedSize / totalSize) * 100)
|
|
314
270
|
term.write(
|
|
315
271
|
`Downloading... ${createProgressBar(pct)} ${pct}% of ${formatBytes(
|
|
316
|
-
totalSize
|
|
317
|
-
)}
|
|
272
|
+
totalSize,
|
|
273
|
+
)}`,
|
|
318
274
|
)
|
|
319
275
|
} else {
|
|
320
276
|
term.write(`Downloading... ${formatBytes(downloadedSize)}`)
|
|
@@ -331,7 +287,6 @@ async function downloadBinary(version) {
|
|
|
331
287
|
})
|
|
332
288
|
|
|
333
289
|
try {
|
|
334
|
-
// Find the extracted binary - it should be named "codebuff" or "codebuff.exe"
|
|
335
290
|
const files = fs.readdirSync(CONFIG.configDir)
|
|
336
291
|
const extractedPath = path.join(CONFIG.configDir, CONFIG.binaryName)
|
|
337
292
|
|
|
@@ -341,7 +296,7 @@ async function downloadBinary(version) {
|
|
|
341
296
|
}
|
|
342
297
|
} else {
|
|
343
298
|
throw new Error(
|
|
344
|
-
`Binary not found after extraction. Expected: ${extractedPath}, Available files: ${files.join(', ')}
|
|
299
|
+
`Binary not found after extraction. Expected: ${extractedPath}, Available files: ${files.join(', ')}`,
|
|
345
300
|
)
|
|
346
301
|
}
|
|
347
302
|
} catch (error) {
|
|
@@ -367,7 +322,7 @@ async function ensureBinaryExists() {
|
|
|
367
322
|
await downloadBinary(version)
|
|
368
323
|
} catch (error) {
|
|
369
324
|
term.clearLine()
|
|
370
|
-
console.error('❌ Failed to download
|
|
325
|
+
console.error('❌ Failed to download codecane:', error.message)
|
|
371
326
|
console.error('Please check your internet connection and try again')
|
|
372
327
|
process.exit(1)
|
|
373
328
|
}
|
|
@@ -383,22 +338,16 @@ async function checkForUpdates(runningProcess, exitListener) {
|
|
|
383
338
|
if (!latestVersion) return
|
|
384
339
|
|
|
385
340
|
if (
|
|
386
|
-
// Download new version if current binary errors.
|
|
387
341
|
currentVersion === 'error' ||
|
|
388
342
|
compareVersions(currentVersion, latestVersion) < 0
|
|
389
343
|
) {
|
|
390
344
|
term.clearLine()
|
|
391
345
|
|
|
392
|
-
// Remove the specific exit listener to prevent it from interfering with the update
|
|
393
346
|
runningProcess.removeListener('exit', exitListener)
|
|
394
|
-
|
|
395
|
-
// Kill the running process
|
|
396
347
|
runningProcess.kill('SIGTERM')
|
|
397
348
|
|
|
398
|
-
// Wait for the process to actually exit
|
|
399
349
|
await new Promise((resolve) => {
|
|
400
350
|
runningProcess.on('exit', resolve)
|
|
401
|
-
// Fallback timeout in case the process doesn't exit gracefully
|
|
402
351
|
setTimeout(() => {
|
|
403
352
|
if (!runningProcess.killed) {
|
|
404
353
|
runningProcess.kill('SIGKILL')
|
|
@@ -411,55 +360,48 @@ async function checkForUpdates(runningProcess, exitListener) {
|
|
|
411
360
|
|
|
412
361
|
await downloadBinary(latestVersion)
|
|
413
362
|
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
{
|
|
419
|
-
stdio: 'inherit',
|
|
420
|
-
detached: false,
|
|
421
|
-
}
|
|
422
|
-
)
|
|
363
|
+
const newChild = spawn(CONFIG.binaryPath, process.argv.slice(2), {
|
|
364
|
+
stdio: 'inherit',
|
|
365
|
+
detached: false,
|
|
366
|
+
})
|
|
423
367
|
|
|
424
|
-
// Set up exit handler for the new process
|
|
425
368
|
newChild.on('exit', (code) => {
|
|
426
369
|
process.exit(code || 0)
|
|
427
370
|
})
|
|
428
371
|
|
|
429
|
-
|
|
430
|
-
return new Promise(() => {}) // Never resolves, keeps wrapper alive
|
|
372
|
+
return new Promise(() => {})
|
|
431
373
|
}
|
|
432
374
|
} catch (error) {
|
|
433
|
-
//
|
|
375
|
+
// Ignore update failures
|
|
434
376
|
}
|
|
435
377
|
}
|
|
436
378
|
|
|
437
379
|
async function main() {
|
|
380
|
+
console.log('\x1b[1m\x1b[91m' + '='.repeat(60) + '\x1b[0m')
|
|
381
|
+
console.log('\x1b[1m\x1b[93m❄️ CODECANE STAGING ENVIRONMENT ❄️\x1b[0m')
|
|
382
|
+
console.log(
|
|
383
|
+
'\x1b[1m\x1b[91mFOR TESTING PURPOSES ONLY - NOT FOR PRODUCTION USE\x1b[0m',
|
|
384
|
+
)
|
|
385
|
+
console.log('\x1b[1m\x1b[91m' + '='.repeat(60) + '\x1b[0m')
|
|
386
|
+
console.log('')
|
|
387
|
+
|
|
438
388
|
await ensureBinaryExists()
|
|
439
389
|
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
[packageName, ...process.argv.slice(2)],
|
|
444
|
-
{
|
|
445
|
-
stdio: 'inherit',
|
|
446
|
-
}
|
|
447
|
-
)
|
|
390
|
+
const child = spawn(CONFIG.binaryPath, process.argv.slice(2), {
|
|
391
|
+
stdio: 'inherit',
|
|
392
|
+
})
|
|
448
393
|
|
|
449
|
-
// Store reference to the exit listener so we can remove it during updates
|
|
450
394
|
const exitListener = (code) => {
|
|
451
395
|
process.exit(code || 0)
|
|
452
396
|
}
|
|
453
397
|
|
|
454
398
|
child.on('exit', exitListener)
|
|
455
399
|
|
|
456
|
-
// Check for updates in background
|
|
457
400
|
setTimeout(() => {
|
|
458
401
|
checkForUpdates(child, exitListener)
|
|
459
402
|
}, 100)
|
|
460
403
|
}
|
|
461
404
|
|
|
462
|
-
// Run the main function
|
|
463
405
|
main().catch((error) => {
|
|
464
406
|
console.error('❌ Unexpected error:', error.message)
|
|
465
407
|
process.exit(1)
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "codecane",
|
|
3
|
-
"version": "1.0.420-beta.
|
|
4
|
-
"description": "AI coding agent (staging)",
|
|
3
|
+
"version": "1.0.420-beta.200",
|
|
4
|
+
"description": "AI coding agent CLI (staging)",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"bin": {
|
|
7
7
|
"codecane": "index.js"
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
},
|
|
31
31
|
"repository": {
|
|
32
32
|
"type": "git",
|
|
33
|
-
"url": "https://github.com/CodebuffAI/codebuff
|
|
33
|
+
"url": "https://github.com/CodebuffAI/codebuff.git"
|
|
34
34
|
},
|
|
35
35
|
"homepage": "https://codebuff.com",
|
|
36
36
|
"publishConfig": {
|