freebuff 0.0.26 → 0.0.29
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/index.js +110 -8
- package/package.json +1 -1
package/index.js
CHANGED
|
@@ -13,6 +13,40 @@ const tar = require('tar')
|
|
|
13
13
|
|
|
14
14
|
const packageName = 'freebuff'
|
|
15
15
|
|
|
16
|
+
/**
|
|
17
|
+
* Terminal escape sequences to reset terminal state after the child process exits.
|
|
18
|
+
* When the binary is SIGKILL'd, it can't clean up its own terminal state.
|
|
19
|
+
* The wrapper (this process) survives and must reset these modes.
|
|
20
|
+
*
|
|
21
|
+
* Keep in sync with TERMINAL_RESET_SEQUENCES in cli/src/utils/renderer-cleanup.ts
|
|
22
|
+
*/
|
|
23
|
+
const TERMINAL_RESET_SEQUENCES =
|
|
24
|
+
'\x1b[?1049l' + // Exit alternate screen buffer
|
|
25
|
+
'\x1b[?1000l' + // Disable X10 mouse mode
|
|
26
|
+
'\x1b[?1002l' + // Disable button event mouse mode
|
|
27
|
+
'\x1b[?1003l' + // Disable any-event mouse mode (all motion)
|
|
28
|
+
'\x1b[?1006l' + // Disable SGR extended mouse mode
|
|
29
|
+
'\x1b[?1004l' + // Disable focus reporting
|
|
30
|
+
'\x1b[?2004l' + // Disable bracketed paste mode
|
|
31
|
+
'\x1b[?25h' // Show cursor
|
|
32
|
+
|
|
33
|
+
function resetTerminal() {
|
|
34
|
+
try {
|
|
35
|
+
if (process.stdin.isTTY && process.stdin.setRawMode) {
|
|
36
|
+
process.stdin.setRawMode(false)
|
|
37
|
+
}
|
|
38
|
+
} catch {
|
|
39
|
+
// stdin may be closed
|
|
40
|
+
}
|
|
41
|
+
try {
|
|
42
|
+
if (process.stdout.isTTY) {
|
|
43
|
+
process.stdout.write(TERMINAL_RESET_SEQUENCES)
|
|
44
|
+
}
|
|
45
|
+
} catch {
|
|
46
|
+
// stdout may be closed
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
16
50
|
function createConfig(packageName) {
|
|
17
51
|
const homeDir = os.homedir()
|
|
18
52
|
const configDir = path.join(homeDir, '.config', 'manicode')
|
|
@@ -513,18 +547,24 @@ async function checkForUpdates(runningProcess, exitListener) {
|
|
|
513
547
|
term.clearLine()
|
|
514
548
|
|
|
515
549
|
runningProcess.removeListener('exit', exitListener)
|
|
516
|
-
runningProcess.kill('SIGTERM')
|
|
517
550
|
|
|
518
551
|
await new Promise((resolve) => {
|
|
519
|
-
|
|
552
|
+
let exited = false
|
|
553
|
+
runningProcess.once('exit', () => {
|
|
554
|
+
exited = true
|
|
555
|
+
resolve()
|
|
556
|
+
})
|
|
557
|
+
runningProcess.kill('SIGTERM')
|
|
520
558
|
setTimeout(() => {
|
|
521
|
-
if (!
|
|
559
|
+
if (!exited) {
|
|
522
560
|
runningProcess.kill('SIGKILL')
|
|
561
|
+
// Safety: resolve after giving SIGKILL time to take effect
|
|
562
|
+
setTimeout(() => resolve(), 1000)
|
|
523
563
|
}
|
|
524
|
-
resolve()
|
|
525
564
|
}, 5000)
|
|
526
565
|
})
|
|
527
566
|
|
|
567
|
+
resetTerminal()
|
|
528
568
|
console.log(`Update available: ${currentVersion} → ${latestVersion}`)
|
|
529
569
|
|
|
530
570
|
await downloadBinary(latestVersion)
|
|
@@ -534,8 +574,15 @@ async function checkForUpdates(runningProcess, exitListener) {
|
|
|
534
574
|
detached: false,
|
|
535
575
|
})
|
|
536
576
|
|
|
537
|
-
newChild.on('exit', (code) => {
|
|
538
|
-
|
|
577
|
+
newChild.on('exit', (code, signal) => {
|
|
578
|
+
resetTerminal()
|
|
579
|
+
printCrashDiagnostics(code, signal)
|
|
580
|
+
process.exit(signal ? 1 : (code || 0))
|
|
581
|
+
})
|
|
582
|
+
|
|
583
|
+
newChild.on('error', (err) => {
|
|
584
|
+
console.error('Failed to start freebuff:', err.message)
|
|
585
|
+
process.exit(1)
|
|
539
586
|
})
|
|
540
587
|
|
|
541
588
|
return new Promise(() => {})
|
|
@@ -545,6 +592,54 @@ async function checkForUpdates(runningProcess, exitListener) {
|
|
|
545
592
|
}
|
|
546
593
|
}
|
|
547
594
|
|
|
595
|
+
function printCrashDiagnostics(code, signal) {
|
|
596
|
+
// Windows NTSTATUS codes (unsigned DWORD)
|
|
597
|
+
const unsignedCode = code != null && code < 0 ? (code >>> 0) : code
|
|
598
|
+
const isIllegalInstruction =
|
|
599
|
+
signal === 'SIGILL' ||
|
|
600
|
+
(process.platform === 'win32' && unsignedCode === 0xC000001D)
|
|
601
|
+
const isAccessViolation =
|
|
602
|
+
signal === 'SIGSEGV' ||
|
|
603
|
+
(process.platform === 'win32' && unsignedCode === 0xC0000005)
|
|
604
|
+
const isBusError = signal === 'SIGBUS'
|
|
605
|
+
const isAbort =
|
|
606
|
+
signal === 'SIGABRT' ||
|
|
607
|
+
(process.platform === 'win32' && unsignedCode === 0xC0000409)
|
|
608
|
+
|
|
609
|
+
if (!isIllegalInstruction && !isAccessViolation && !isBusError && !isAbort) return
|
|
610
|
+
|
|
611
|
+
const exitInfo = signal ? `signal ${signal}` : `code ${code}`
|
|
612
|
+
console.error('')
|
|
613
|
+
console.error(`❌ ${packageName} exited immediately (${exitInfo})`)
|
|
614
|
+
console.error('')
|
|
615
|
+
|
|
616
|
+
if (isIllegalInstruction) {
|
|
617
|
+
console.error('Your CPU may not support the required instruction set (AVX2).')
|
|
618
|
+
console.error('This typically affects CPUs from before 2013.')
|
|
619
|
+
console.error('Unfortunately, this binary is not compatible with your system.')
|
|
620
|
+
console.error('')
|
|
621
|
+
} else if (isAccessViolation) {
|
|
622
|
+
console.error('The binary crashed with an access violation.')
|
|
623
|
+
console.error('')
|
|
624
|
+
} else if (isBusError) {
|
|
625
|
+
console.error('The binary crashed with a bus error.')
|
|
626
|
+
console.error('This may indicate a platform compatibility issue.')
|
|
627
|
+
console.error('')
|
|
628
|
+
} else if (isAbort) {
|
|
629
|
+
console.error('The binary crashed with an abort signal.')
|
|
630
|
+
console.error('')
|
|
631
|
+
}
|
|
632
|
+
|
|
633
|
+
console.error('System info:')
|
|
634
|
+
console.error(` Platform: ${process.platform} ${process.arch}`)
|
|
635
|
+
console.error(` Node: ${process.version}`)
|
|
636
|
+
console.error(` Binary: ${CONFIG.binaryPath}`)
|
|
637
|
+
console.error('')
|
|
638
|
+
console.error('Please report this issue at:')
|
|
639
|
+
console.error(' https://github.com/CodebuffAI/codebuff/issues')
|
|
640
|
+
console.error('')
|
|
641
|
+
}
|
|
642
|
+
|
|
548
643
|
async function main() {
|
|
549
644
|
await ensureBinaryExists()
|
|
550
645
|
|
|
@@ -552,12 +647,19 @@ async function main() {
|
|
|
552
647
|
stdio: 'inherit',
|
|
553
648
|
})
|
|
554
649
|
|
|
555
|
-
const exitListener = (code) => {
|
|
556
|
-
|
|
650
|
+
const exitListener = (code, signal) => {
|
|
651
|
+
resetTerminal()
|
|
652
|
+
printCrashDiagnostics(code, signal)
|
|
653
|
+
process.exit(signal ? 1 : (code || 0))
|
|
557
654
|
}
|
|
558
655
|
|
|
559
656
|
child.on('exit', exitListener)
|
|
560
657
|
|
|
658
|
+
child.on('error', (err) => {
|
|
659
|
+
console.error('Failed to start freebuff:', err.message)
|
|
660
|
+
process.exit(1)
|
|
661
|
+
})
|
|
662
|
+
|
|
561
663
|
setTimeout(() => {
|
|
562
664
|
checkForUpdates(child, exitListener)
|
|
563
665
|
}, 100)
|