codebuff 1.0.512 → 1.0.514
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 +18 -16
- package/index.js +140 -155
- package/package.json +1 -2
package/README.md
CHANGED
|
@@ -1,49 +1,51 @@
|
|
|
1
|
-
# The most powerful coding agent
|
|
1
|
+
# 🚀 Codecane - The most powerful coding agent (STAGING)
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
**⚠️ This is a staging/beta release for testing purposes.**
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Codecane is a CLI tool that writes code for you.
|
|
6
|
+
|
|
7
|
+
1. Run `codecane` from your project directory
|
|
6
8
|
2. Tell it what to do
|
|
7
9
|
3. It will read and write to files and run commands to produce the code you want
|
|
8
10
|
|
|
9
|
-
Note:
|
|
11
|
+
Note: Codecane will run commands in your terminal as it deems necessary to fulfill your request.
|
|
10
12
|
|
|
11
13
|
## Installation
|
|
12
14
|
|
|
13
|
-
To install
|
|
15
|
+
To install Codecane (staging), run:
|
|
14
16
|
|
|
15
17
|
```bash
|
|
16
|
-
npm install -g
|
|
18
|
+
npm install -g codecane@beta
|
|
17
19
|
```
|
|
18
20
|
|
|
19
21
|
(Use `sudo` if you get a permission error.)
|
|
20
22
|
|
|
21
23
|
## Usage
|
|
22
24
|
|
|
23
|
-
After installation, you can start
|
|
25
|
+
After installation, you can start Codecane by running:
|
|
24
26
|
|
|
25
27
|
```bash
|
|
26
|
-
|
|
28
|
+
codecane [project-directory]
|
|
27
29
|
```
|
|
28
30
|
|
|
29
|
-
If no project directory is specified,
|
|
31
|
+
If no project directory is specified, Codecane will use the current directory.
|
|
30
32
|
|
|
31
|
-
Once running, simply chat with
|
|
33
|
+
Once running, simply chat with Codecane to say what coding task you want done.
|
|
32
34
|
|
|
33
35
|
## Features
|
|
34
36
|
|
|
35
37
|
- Understands your whole codebase
|
|
36
38
|
- Creates and edits multiple files based on your request
|
|
37
39
|
- Can run your tests or type checker or linter; can install packages
|
|
38
|
-
- It's powerful: ask
|
|
40
|
+
- It's powerful: ask Codecane to keep working until it reaches a condition and it will.
|
|
39
41
|
|
|
40
|
-
Our users regularly use
|
|
42
|
+
Our users regularly use Codecane to implement new features, write unit tests, refactor code, write scripts, or give advice.
|
|
41
43
|
|
|
42
44
|
## Knowledge Files
|
|
43
45
|
|
|
44
46
|
To unlock the full benefits of modern LLMs, we recommend storing knowledge alongside your code. Add a `knowledge.md` file anywhere in your project to provide helpful context, guidance, and tips for the LLM as it performs tasks for you.
|
|
45
47
|
|
|
46
|
-
|
|
48
|
+
Codecane can fluently read and write files, so it will add knowledge as it goes. You don't need to write knowledge manually!
|
|
47
49
|
|
|
48
50
|
Some have said every change should be paired with a unit test. In 2024, every change should come with a knowledge update!
|
|
49
51
|
|
|
@@ -52,18 +54,18 @@ Some have said every change should be paired with a unit test. In 2024, every ch
|
|
|
52
54
|
1. Type '/help' or just '/' to see available commands.
|
|
53
55
|
2. Create a `knowledge.md` file and collect specific points of advice. The assistant will use this knowledge to improve its responses.
|
|
54
56
|
3. Type `undo` or `redo` to revert or reapply file changes from the conversation.
|
|
55
|
-
4. Press `Esc` or `Ctrl+C` while
|
|
57
|
+
4. Press `Esc` or `Ctrl+C` while Codecane is generating a response to stop it.
|
|
56
58
|
|
|
57
59
|
## Troubleshooting
|
|
58
60
|
|
|
59
61
|
If you are getting permission errors during installation, try using sudo:
|
|
60
62
|
|
|
61
63
|
```
|
|
62
|
-
sudo npm install -g
|
|
64
|
+
sudo npm install -g codecane@beta
|
|
63
65
|
```
|
|
64
66
|
|
|
65
67
|
If you still have errors, it's a good idea to [reinstall Node](https://nodejs.org/en/download).
|
|
66
68
|
|
|
67
69
|
## Feedback
|
|
68
70
|
|
|
69
|
-
We value your input! Please email your feedback to `founders@codebuff.com`. Thank you for using
|
|
71
|
+
We value your input! Please email your feedback to `founders@codebuff.com`. Thank you for using Codecane!
|
package/index.js
CHANGED
|
@@ -7,52 +7,52 @@ const os = require('os')
|
|
|
7
7
|
const path = require('path')
|
|
8
8
|
const zlib = require('zlib')
|
|
9
9
|
|
|
10
|
-
const { Command } = require('commander')
|
|
11
10
|
const tar = require('tar')
|
|
12
11
|
|
|
13
|
-
const
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
12
|
+
const packageName = 'codebuff'
|
|
13
|
+
|
|
14
|
+
function createConfig(packageName) {
|
|
15
|
+
const homeDir = os.homedir()
|
|
16
|
+
const configDir = path.join(homeDir, '.config', 'manicode')
|
|
17
|
+
const binaryName =
|
|
18
|
+
process.platform === 'win32' ? `${packageName}.exe` : packageName
|
|
19
|
+
|
|
20
|
+
return {
|
|
21
|
+
homeDir,
|
|
22
|
+
configDir,
|
|
23
|
+
binaryName,
|
|
24
|
+
binaryPath: path.join(configDir, binaryName),
|
|
25
|
+
userAgent: `${packageName}-cli`,
|
|
26
|
+
requestTimeout: 20000,
|
|
27
|
+
}
|
|
20
28
|
}
|
|
21
29
|
|
|
22
|
-
CONFIG
|
|
30
|
+
const CONFIG = createConfig(packageName)
|
|
23
31
|
|
|
24
|
-
// Platform target mapping
|
|
25
32
|
const PLATFORM_TARGETS = {
|
|
26
|
-
'linux-x64':
|
|
27
|
-
'linux-arm64':
|
|
28
|
-
'darwin-x64':
|
|
29
|
-
'darwin-arm64':
|
|
30
|
-
'win32-x64':
|
|
33
|
+
'linux-x64': `${packageName}-linux-x64.tar.gz`,
|
|
34
|
+
'linux-arm64': `${packageName}-linux-arm64.tar.gz`,
|
|
35
|
+
'darwin-x64': `${packageName}-darwin-x64.tar.gz`,
|
|
36
|
+
'darwin-arm64': `${packageName}-darwin-arm64.tar.gz`,
|
|
37
|
+
'win32-x64': `${packageName}-win32-x64.tar.gz`,
|
|
31
38
|
}
|
|
32
39
|
|
|
33
|
-
// Terminal utilities
|
|
34
|
-
let isPrintMode = false
|
|
35
40
|
const term = {
|
|
36
41
|
clearLine: () => {
|
|
37
|
-
if (
|
|
42
|
+
if (process.stderr.isTTY) {
|
|
38
43
|
process.stderr.write('\r\x1b[K')
|
|
39
44
|
}
|
|
40
45
|
},
|
|
41
46
|
write: (text) => {
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
process.stderr.write(text)
|
|
45
|
-
}
|
|
47
|
+
term.clearLine()
|
|
48
|
+
process.stderr.write(text)
|
|
46
49
|
},
|
|
47
50
|
writeLine: (text) => {
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
process.stderr.write(text + '\n')
|
|
51
|
-
}
|
|
51
|
+
term.clearLine()
|
|
52
|
+
process.stderr.write(text + '\n')
|
|
52
53
|
},
|
|
53
54
|
}
|
|
54
55
|
|
|
55
|
-
// Utility functions
|
|
56
56
|
function httpGet(url, options = {}) {
|
|
57
57
|
return new Promise((resolve, reject) => {
|
|
58
58
|
const parsedUrl = new URL(url)
|
|
@@ -65,12 +65,6 @@ function httpGet(url, options = {}) {
|
|
|
65
65
|
},
|
|
66
66
|
}
|
|
67
67
|
|
|
68
|
-
// Add GitHub token if available
|
|
69
|
-
const token = process.env.GITHUB_TOKEN
|
|
70
|
-
if (token) {
|
|
71
|
-
reqOptions.headers.Authorization = `Bearer ${token}`
|
|
72
|
-
}
|
|
73
|
-
|
|
74
68
|
const req = https.get(reqOptions, (res) => {
|
|
75
69
|
if (res.statusCode === 302 || res.statusCode === 301) {
|
|
76
70
|
return httpGet(new URL(res.headers.location, url).href, options)
|
|
@@ -117,13 +111,10 @@ function streamToString(stream) {
|
|
|
117
111
|
}
|
|
118
112
|
|
|
119
113
|
function getCurrentVersion() {
|
|
120
|
-
|
|
121
|
-
try {
|
|
122
|
-
if (!fs.existsSync(CONFIG.binaryPath)) {
|
|
123
|
-
resolve('error')
|
|
124
|
-
return
|
|
125
|
-
}
|
|
114
|
+
if (!fs.existsSync(CONFIG.binaryPath)) return null
|
|
126
115
|
|
|
116
|
+
try {
|
|
117
|
+
return new Promise((resolve, reject) => {
|
|
127
118
|
const child = spawn(CONFIG.binaryPath, ['--version'], {
|
|
128
119
|
cwd: os.homedir(),
|
|
129
120
|
stdio: 'pipe',
|
|
@@ -146,9 +137,9 @@ function getCurrentVersion() {
|
|
|
146
137
|
if (!child.killed) {
|
|
147
138
|
child.kill('SIGKILL')
|
|
148
139
|
}
|
|
149
|
-
},
|
|
140
|
+
}, 4000)
|
|
150
141
|
resolve('error')
|
|
151
|
-
},
|
|
142
|
+
}, 4000)
|
|
152
143
|
|
|
153
144
|
child.on('exit', (code) => {
|
|
154
145
|
clearTimeout(timeout)
|
|
@@ -163,31 +154,74 @@ function getCurrentVersion() {
|
|
|
163
154
|
clearTimeout(timeout)
|
|
164
155
|
resolve('error')
|
|
165
156
|
})
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
}
|
|
157
|
+
})
|
|
158
|
+
} catch (error) {
|
|
159
|
+
return 'error'
|
|
160
|
+
}
|
|
170
161
|
}
|
|
171
162
|
|
|
172
163
|
function compareVersions(v1, v2) {
|
|
173
164
|
if (!v1 || !v2) return 0
|
|
174
165
|
|
|
166
|
+
// Always update if the current version is not a valid semver
|
|
167
|
+
// e.g. 1.0.420-beta.1
|
|
175
168
|
if (!v1.match(/^\d+(\.\d+)*$/)) {
|
|
176
169
|
return -1
|
|
177
170
|
}
|
|
178
171
|
|
|
179
|
-
const
|
|
180
|
-
|
|
172
|
+
const parseVersion = (version) => {
|
|
173
|
+
const parts = version.split('-')
|
|
174
|
+
const mainParts = parts[0].split('.').map(Number)
|
|
175
|
+
const prereleaseParts = parts[1] ? parts[1].split('.') : []
|
|
176
|
+
return { main: mainParts, prerelease: prereleaseParts }
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
const p1 = parseVersion(v1)
|
|
180
|
+
const p2 = parseVersion(v2)
|
|
181
181
|
|
|
182
|
-
for (let i = 0; i < Math.max(
|
|
183
|
-
const
|
|
184
|
-
const
|
|
182
|
+
for (let i = 0; i < Math.max(p1.main.length, p2.main.length); i++) {
|
|
183
|
+
const n1 = p1.main[i] || 0
|
|
184
|
+
const n2 = p2.main[i] || 0
|
|
185
185
|
|
|
186
|
-
if (
|
|
187
|
-
if (
|
|
186
|
+
if (n1 < n2) return -1
|
|
187
|
+
if (n1 > n2) return 1
|
|
188
188
|
}
|
|
189
189
|
|
|
190
|
-
|
|
190
|
+
if (p1.prerelease.length === 0 && p2.prerelease.length === 0) {
|
|
191
|
+
return 0
|
|
192
|
+
} else if (p1.prerelease.length === 0) {
|
|
193
|
+
return 1
|
|
194
|
+
} else if (p2.prerelease.length === 0) {
|
|
195
|
+
return -1
|
|
196
|
+
} else {
|
|
197
|
+
for (
|
|
198
|
+
let i = 0;
|
|
199
|
+
i < Math.max(p1.prerelease.length, p2.prerelease.length);
|
|
200
|
+
i++
|
|
201
|
+
) {
|
|
202
|
+
const pr1 = p1.prerelease[i] || ''
|
|
203
|
+
const pr2 = p2.prerelease[i] || ''
|
|
204
|
+
|
|
205
|
+
const isNum1 = !isNaN(parseInt(pr1))
|
|
206
|
+
const isNum2 = !isNaN(parseInt(pr2))
|
|
207
|
+
|
|
208
|
+
if (isNum1 && isNum2) {
|
|
209
|
+
const num1 = parseInt(pr1)
|
|
210
|
+
const num2 = parseInt(pr2)
|
|
211
|
+
if (num1 < num2) return -1
|
|
212
|
+
if (num1 > num2) return 1
|
|
213
|
+
} else if (isNum1 && !isNum2) {
|
|
214
|
+
return 1
|
|
215
|
+
} else if (!isNum1 && isNum2) {
|
|
216
|
+
return -1
|
|
217
|
+
} else if (pr1 < pr2) {
|
|
218
|
+
return -1
|
|
219
|
+
} else if (pr1 > pr2) {
|
|
220
|
+
return 1
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
return 0
|
|
224
|
+
}
|
|
191
225
|
}
|
|
192
226
|
|
|
193
227
|
function formatBytes(bytes) {
|
|
@@ -212,16 +246,30 @@ async function downloadBinary(version) {
|
|
|
212
246
|
throw new Error(`Unsupported platform: ${process.platform} ${process.arch}`)
|
|
213
247
|
}
|
|
214
248
|
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
: `https://codebuff.com/api/releases/download/${version}/${fileName}`
|
|
249
|
+
const downloadUrl = `${
|
|
250
|
+
process.env.NEXT_PUBLIC_CODEBUFF_APP_URL || 'https://codebuff.com'
|
|
251
|
+
}/api/releases/download/${version}/${fileName}`
|
|
219
252
|
|
|
220
|
-
// Ensure config directory exists
|
|
221
253
|
fs.mkdirSync(CONFIG.configDir, { recursive: true })
|
|
222
254
|
|
|
223
255
|
if (fs.existsSync(CONFIG.binaryPath)) {
|
|
224
|
-
|
|
256
|
+
try {
|
|
257
|
+
fs.unlinkSync(CONFIG.binaryPath)
|
|
258
|
+
} catch (err) {
|
|
259
|
+
// Fallback: try renaming the locked/undeletable binary
|
|
260
|
+
const backupPath = CONFIG.binaryPath + `.old.${Date.now()}`
|
|
261
|
+
|
|
262
|
+
try {
|
|
263
|
+
fs.renameSync(CONFIG.binaryPath, backupPath)
|
|
264
|
+
} catch (renameErr) {
|
|
265
|
+
// If we can't unlink OR rename, we can't safely proceed
|
|
266
|
+
throw new Error(
|
|
267
|
+
`Failed to replace existing binary. ` +
|
|
268
|
+
`unlink error: ${err.code || err.message}, ` +
|
|
269
|
+
`rename error: ${renameErr.code || renameErr.message}`,
|
|
270
|
+
)
|
|
271
|
+
}
|
|
272
|
+
}
|
|
225
273
|
}
|
|
226
274
|
|
|
227
275
|
term.write('Downloading...')
|
|
@@ -263,7 +311,6 @@ async function downloadBinary(version) {
|
|
|
263
311
|
})
|
|
264
312
|
|
|
265
313
|
try {
|
|
266
|
-
// Find the extracted binary - it should be named "codebuff" or "codebuff.exe"
|
|
267
314
|
const files = fs.readdirSync(CONFIG.configDir)
|
|
268
315
|
const extractedPath = path.join(CONFIG.configDir, CONFIG.binaryName)
|
|
269
316
|
|
|
@@ -278,20 +325,12 @@ async function downloadBinary(version) {
|
|
|
278
325
|
}
|
|
279
326
|
} catch (error) {
|
|
280
327
|
term.clearLine()
|
|
281
|
-
|
|
282
|
-
console.error(`Extraction failed: ${error.message}`)
|
|
283
|
-
}
|
|
328
|
+
console.error(`Extraction failed: ${error.message}`)
|
|
284
329
|
process.exit(1)
|
|
285
330
|
}
|
|
286
331
|
|
|
287
332
|
term.clearLine()
|
|
288
|
-
|
|
289
|
-
console.log(
|
|
290
|
-
JSON.stringify({ type: 'download', version, status: 'complete' }),
|
|
291
|
-
)
|
|
292
|
-
} else {
|
|
293
|
-
console.log('Download complete! Starting Codebuff...')
|
|
294
|
-
}
|
|
333
|
+
console.log('Download complete! Starting Codebuff...')
|
|
295
334
|
}
|
|
296
335
|
|
|
297
336
|
async function ensureBinaryExists() {
|
|
@@ -302,17 +341,8 @@ async function ensureBinaryExists() {
|
|
|
302
341
|
|
|
303
342
|
const version = await getLatestVersion()
|
|
304
343
|
if (!version) {
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
JSON.stringify({
|
|
308
|
-
type: 'error',
|
|
309
|
-
message: 'Failed to determine latest version.',
|
|
310
|
-
}),
|
|
311
|
-
)
|
|
312
|
-
} else {
|
|
313
|
-
console.error('❌ Failed to determine latest version')
|
|
314
|
-
console.error('Please check your internet connection and try again')
|
|
315
|
-
}
|
|
344
|
+
console.error('❌ Failed to determine latest version')
|
|
345
|
+
console.error('Please check your internet connection and try again')
|
|
316
346
|
process.exit(1)
|
|
317
347
|
}
|
|
318
348
|
|
|
@@ -320,45 +350,31 @@ async function ensureBinaryExists() {
|
|
|
320
350
|
await downloadBinary(version)
|
|
321
351
|
} catch (error) {
|
|
322
352
|
term.clearLine()
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
JSON.stringify({
|
|
326
|
-
type: 'error',
|
|
327
|
-
message: `Failed to download codebuff: ${error.message}`,
|
|
328
|
-
}),
|
|
329
|
-
)
|
|
330
|
-
} else {
|
|
331
|
-
console.error('❌ Failed to download codebuff:', error.message)
|
|
332
|
-
console.error('Please check your internet connection and try again')
|
|
333
|
-
}
|
|
353
|
+
console.error('❌ Failed to download codebuff:', error.message)
|
|
354
|
+
console.error('Please check your internet connection and try again')
|
|
334
355
|
process.exit(1)
|
|
335
356
|
}
|
|
336
357
|
}
|
|
337
358
|
|
|
338
|
-
async function checkForUpdates(runningProcess, exitListener
|
|
359
|
+
async function checkForUpdates(runningProcess, exitListener) {
|
|
339
360
|
try {
|
|
340
361
|
const currentVersion = await getCurrentVersion()
|
|
362
|
+
if (!currentVersion) return
|
|
341
363
|
|
|
342
364
|
const latestVersion = await getLatestVersion()
|
|
343
365
|
if (!latestVersion) return
|
|
344
366
|
|
|
345
367
|
if (
|
|
346
|
-
// Download new version if current binary errors.
|
|
347
368
|
currentVersion === 'error' ||
|
|
348
369
|
compareVersions(currentVersion, latestVersion) < 0
|
|
349
370
|
) {
|
|
350
371
|
term.clearLine()
|
|
351
372
|
|
|
352
|
-
// Remove the specific exit listener to prevent it from interfering with the update
|
|
353
373
|
runningProcess.removeListener('exit', exitListener)
|
|
354
|
-
|
|
355
|
-
// Kill the running process
|
|
356
374
|
runningProcess.kill('SIGTERM')
|
|
357
375
|
|
|
358
|
-
// Wait for the process to actually exit
|
|
359
376
|
await new Promise((resolve) => {
|
|
360
377
|
runningProcess.on('exit', resolve)
|
|
361
|
-
// Fallback timeout in case the process doesn't exit gracefully
|
|
362
378
|
setTimeout(() => {
|
|
363
379
|
if (!runningProcess.killed) {
|
|
364
380
|
runningProcess.kill('SIGKILL')
|
|
@@ -367,76 +383,45 @@ async function checkForUpdates(runningProcess, exitListener, retry) {
|
|
|
367
383
|
}, 5000)
|
|
368
384
|
})
|
|
369
385
|
|
|
370
|
-
|
|
371
|
-
console.log(`Update available: ${currentVersion} → ${latestVersion}`)
|
|
372
|
-
}
|
|
386
|
+
console.log(`Update available: ${currentVersion} → ${latestVersion}`)
|
|
373
387
|
|
|
374
388
|
await downloadBinary(latestVersion)
|
|
375
389
|
|
|
376
|
-
|
|
390
|
+
const newChild = spawn(CONFIG.binaryPath, process.argv.slice(2), {
|
|
391
|
+
stdio: 'inherit',
|
|
392
|
+
detached: false,
|
|
393
|
+
})
|
|
394
|
+
|
|
395
|
+
newChild.on('exit', (code) => {
|
|
396
|
+
process.exit(code || 0)
|
|
397
|
+
})
|
|
398
|
+
|
|
399
|
+
return new Promise(() => {})
|
|
377
400
|
}
|
|
378
401
|
} catch (error) {
|
|
379
|
-
//
|
|
402
|
+
// Ignore update failures
|
|
380
403
|
}
|
|
381
404
|
}
|
|
382
405
|
|
|
383
|
-
async function main(
|
|
384
|
-
isPrintMode = printMode
|
|
406
|
+
async function main() {
|
|
385
407
|
await ensureBinaryExists()
|
|
386
408
|
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
const child = spawn(CONFIG.binaryPath, process.argv.slice(2), {
|
|
391
|
-
stdio: 'inherit',
|
|
392
|
-
})
|
|
409
|
+
const child = spawn(CONFIG.binaryPath, process.argv.slice(2), {
|
|
410
|
+
stdio: 'inherit',
|
|
411
|
+
})
|
|
393
412
|
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
}
|
|
413
|
+
const exitListener = (code) => {
|
|
414
|
+
process.exit(code || 0)
|
|
415
|
+
}
|
|
398
416
|
|
|
399
|
-
|
|
417
|
+
child.on('exit', exitListener)
|
|
400
418
|
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
if (!error) {
|
|
405
|
-
checkForUpdates(child, exitListener, () => main(false, isPrintMode))
|
|
406
|
-
}
|
|
407
|
-
}, 100)
|
|
408
|
-
}
|
|
409
|
-
} catch (err) {
|
|
410
|
-
error = err
|
|
411
|
-
if (firstRun) {
|
|
412
|
-
if (!isPrintMode) {
|
|
413
|
-
console.error('❌ Codebuff failed to start:', error.message)
|
|
414
|
-
console.log('Redownloading Codebuff...')
|
|
415
|
-
}
|
|
416
|
-
// Binary could be corrupted (killed before download completed), so delete and retry.
|
|
417
|
-
fs.unlinkSync(CONFIG.binaryPath)
|
|
418
|
-
await main(false, isPrintMode)
|
|
419
|
-
}
|
|
420
|
-
}
|
|
419
|
+
setTimeout(() => {
|
|
420
|
+
checkForUpdates(child, exitListener)
|
|
421
|
+
}, 100)
|
|
421
422
|
}
|
|
422
423
|
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
program
|
|
426
|
-
.name('codebuff')
|
|
427
|
-
.description('AI coding agent')
|
|
428
|
-
.helpOption(false)
|
|
429
|
-
.option('-p, --print', 'print mode - suppress wrapper output')
|
|
430
|
-
.allowUnknownOption()
|
|
431
|
-
.parse()
|
|
432
|
-
|
|
433
|
-
const options = program.opts()
|
|
434
|
-
isPrintMode = options.print
|
|
435
|
-
|
|
436
|
-
// Run the main function
|
|
437
|
-
main(true, isPrintMode).catch((error) => {
|
|
438
|
-
if (!isPrintMode) {
|
|
439
|
-
console.error('❌ Unexpected error:', error.message)
|
|
440
|
-
}
|
|
424
|
+
main().catch((error) => {
|
|
425
|
+
console.error('❌ Unexpected error:', error.message)
|
|
441
426
|
process.exit(1)
|
|
442
427
|
})
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "codebuff",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.514",
|
|
4
4
|
"description": "AI coding agent",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"bin": {
|
|
@@ -27,7 +27,6 @@
|
|
|
27
27
|
"node": ">=16"
|
|
28
28
|
},
|
|
29
29
|
"dependencies": {
|
|
30
|
-
"commander": "^12.0.0",
|
|
31
30
|
"tar": "^6.2.0"
|
|
32
31
|
},
|
|
33
32
|
"repository": {
|