@naarang/ccc 2.0.0-alpha.5 → 2.0.0-alpha.6
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/bin/ccc.cjs +83 -83
- package/dist/index.js +39 -39
- package/dist/scripts/build-binaries.ts +270 -14
- package/dist/scripts/postinstall.cjs +84 -84
- package/package.json +79 -79
- package/scripts/build-binaries.ts +270 -14
- package/scripts/postinstall.cjs +84 -84
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Build script for creating cross-platform binaries with embedded version
|
|
3
|
+
* and native library support (bun-pty)
|
|
3
4
|
*/
|
|
4
5
|
|
|
5
6
|
import { $ } from 'bun';
|
|
6
|
-
import { readFileSync, mkdirSync, existsSync } from 'fs';
|
|
7
|
+
import { readFileSync, writeFileSync, mkdirSync, existsSync, unlinkSync } from 'fs';
|
|
7
8
|
import { join } from 'path';
|
|
8
9
|
|
|
9
10
|
// Read version from package.json
|
|
@@ -18,41 +19,296 @@ if (!existsSync(binariesDir)) {
|
|
|
18
19
|
mkdirSync(binariesDir, { recursive: true });
|
|
19
20
|
}
|
|
20
21
|
|
|
21
|
-
// Define targets
|
|
22
|
+
// Define targets with their native library paths
|
|
22
23
|
const targets = [
|
|
23
|
-
{
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
24
|
+
{
|
|
25
|
+
name: 'linux-x64',
|
|
26
|
+
target: 'bun-linux-x64',
|
|
27
|
+
outfile: 'ccc-linux-x64',
|
|
28
|
+
ptyLib: 'librust_pty.so',
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
name: 'linux-arm64',
|
|
32
|
+
target: 'bun-linux-arm64',
|
|
33
|
+
outfile: 'ccc-linux-arm64',
|
|
34
|
+
ptyLib: 'librust_pty_arm64.so',
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
name: 'darwin-x64',
|
|
38
|
+
target: 'bun-darwin-x64',
|
|
39
|
+
outfile: 'ccc-darwin-x64',
|
|
40
|
+
ptyLib: 'librust_pty.dylib',
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
name: 'darwin-arm64',
|
|
44
|
+
target: 'bun-darwin-arm64',
|
|
45
|
+
outfile: 'ccc-darwin-arm64',
|
|
46
|
+
ptyLib: 'librust_pty_arm64.dylib',
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
name: 'windows-x64',
|
|
50
|
+
target: 'bun-windows-x64',
|
|
51
|
+
outfile: 'ccc-windows-x64.exe',
|
|
52
|
+
ptyLib: 'rust_pty.dll',
|
|
53
|
+
},
|
|
28
54
|
];
|
|
29
55
|
|
|
30
56
|
// Parse command line arguments
|
|
31
57
|
const args = process.argv.slice(2);
|
|
32
|
-
const targetArg = args.find(arg => !arg.startsWith('-'));
|
|
33
|
-
const selectedTargets = targetArg
|
|
34
|
-
? targets.filter(t => t.name === targetArg)
|
|
35
|
-
: targets;
|
|
58
|
+
const targetArg = args.find((arg) => !arg.startsWith('-'));
|
|
59
|
+
const selectedTargets = targetArg ? targets.filter((t) => t.name === targetArg) : targets;
|
|
36
60
|
|
|
37
61
|
if (targetArg && selectedTargets.length === 0) {
|
|
38
62
|
console.error(`Unknown target: ${targetArg}`);
|
|
39
|
-
console.error(`Available targets: ${targets.map(t => t.name).join(', ')}`);
|
|
63
|
+
console.error(`Available targets: ${targets.map((t) => t.name).join(', ')}`);
|
|
40
64
|
process.exit(1);
|
|
41
65
|
}
|
|
42
66
|
|
|
67
|
+
// Path to the generated loader file
|
|
68
|
+
const loaderDir = join(import.meta.dir, '..', 'src', 'lib');
|
|
69
|
+
const loaderPath = join(loaderDir, 'bun-pty-loader.generated.ts');
|
|
70
|
+
|
|
71
|
+
// Ensure the lib directory exists
|
|
72
|
+
if (!existsSync(loaderDir)) {
|
|
73
|
+
mkdirSync(loaderDir, { recursive: true });
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Generate a platform-specific bun-pty loader that embeds the native library
|
|
78
|
+
* This inlines the bun-pty implementation to ensure the library is extracted
|
|
79
|
+
* before dlopen is called (bun-pty calls dlopen at module load time)
|
|
80
|
+
*/
|
|
81
|
+
function generatePtyLoader(ptyLib: string): void {
|
|
82
|
+
const loaderContent = `/**
|
|
83
|
+
* Auto-generated bun-pty implementation with embedded native library
|
|
84
|
+
* DO NOT EDIT - This file is generated by build-binaries.ts
|
|
85
|
+
*
|
|
86
|
+
* This is a copy of bun-pty's implementation that uses an embedded native library.
|
|
87
|
+
* We can't just set BUN_PTY_LIB and import bun-pty because bun-pty calls dlopen
|
|
88
|
+
* at module load time, before our env var setup code runs.
|
|
89
|
+
*/
|
|
90
|
+
|
|
91
|
+
import { dlopen, FFIType, ptr } from 'bun:ffi';
|
|
92
|
+
import { Buffer } from 'buffer';
|
|
93
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'fs';
|
|
94
|
+
import { join } from 'path';
|
|
95
|
+
import { tmpdir } from 'os';
|
|
96
|
+
|
|
97
|
+
// Embed the native library file - Bun will include this in the binary
|
|
98
|
+
// @ts-ignore - Bun's file embedding syntax
|
|
99
|
+
import embeddedLibPath from '../../node_modules/bun-pty/rust-pty/target/release/${ptyLib}' with { type: 'file' };
|
|
100
|
+
|
|
101
|
+
// Extract embedded library to temp directory
|
|
102
|
+
const libName = '${ptyLib}';
|
|
103
|
+
const tempDir = join(tmpdir(), 'ccc-pty-lib');
|
|
104
|
+
const extractedLibPath = join(tempDir, libName);
|
|
105
|
+
|
|
106
|
+
if (!existsSync(extractedLibPath)) {
|
|
107
|
+
if (!existsSync(tempDir)) {
|
|
108
|
+
mkdirSync(tempDir, { recursive: true });
|
|
109
|
+
}
|
|
110
|
+
const libData = readFileSync(embeddedLibPath);
|
|
111
|
+
writeFileSync(extractedLibPath, libData);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// Load the native library
|
|
115
|
+
const lib = dlopen(extractedLibPath, {
|
|
116
|
+
bun_pty_spawn: {
|
|
117
|
+
args: [FFIType.cstring, FFIType.cstring, FFIType.cstring, FFIType.i32, FFIType.i32],
|
|
118
|
+
returns: FFIType.i32,
|
|
119
|
+
},
|
|
120
|
+
bun_pty_write: {
|
|
121
|
+
args: [FFIType.i32, FFIType.pointer, FFIType.i32],
|
|
122
|
+
returns: FFIType.i32,
|
|
123
|
+
},
|
|
124
|
+
bun_pty_read: {
|
|
125
|
+
args: [FFIType.i32, FFIType.pointer, FFIType.i32],
|
|
126
|
+
returns: FFIType.i32,
|
|
127
|
+
},
|
|
128
|
+
bun_pty_resize: {
|
|
129
|
+
args: [FFIType.i32, FFIType.i32, FFIType.i32],
|
|
130
|
+
returns: FFIType.i32,
|
|
131
|
+
},
|
|
132
|
+
bun_pty_kill: { args: [FFIType.i32], returns: FFIType.i32 },
|
|
133
|
+
bun_pty_get_pid: { args: [FFIType.i32], returns: FFIType.i32 },
|
|
134
|
+
bun_pty_get_exit_code: { args: [FFIType.i32], returns: FFIType.i32 },
|
|
135
|
+
bun_pty_close: { args: [FFIType.i32], returns: FFIType.void },
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
// EventEmitter for PTY events
|
|
139
|
+
class EventEmitter<T> {
|
|
140
|
+
private listeners: ((data: T) => void)[] = [];
|
|
141
|
+
|
|
142
|
+
event = (listener: (data: T) => void) => {
|
|
143
|
+
this.listeners.push(listener);
|
|
144
|
+
return {
|
|
145
|
+
dispose: () => {
|
|
146
|
+
const i = this.listeners.indexOf(listener);
|
|
147
|
+
if (i !== -1) this.listeners.splice(i, 1);
|
|
148
|
+
},
|
|
149
|
+
};
|
|
150
|
+
};
|
|
151
|
+
|
|
152
|
+
fire(data: T) {
|
|
153
|
+
for (const listener of this.listeners) {
|
|
154
|
+
listener(data);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
// Shell quote helper
|
|
160
|
+
function shQuote(s: string): string {
|
|
161
|
+
if (s.length === 0) return "''";
|
|
162
|
+
return \`'\${s.replace(/'/g, \`'\\\\''\\'\`)}'\`;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
const DEFAULT_COLS = 80;
|
|
166
|
+
const DEFAULT_ROWS = 24;
|
|
167
|
+
const DEFAULT_FILE = process.platform === 'win32' ? 'powershell.exe' : 'sh';
|
|
168
|
+
|
|
169
|
+
export interface IPtyOptions {
|
|
170
|
+
name?: string;
|
|
171
|
+
cols?: number;
|
|
172
|
+
rows?: number;
|
|
173
|
+
cwd?: string;
|
|
174
|
+
env?: Record<string, string>;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
export interface IPty {
|
|
178
|
+
pid: number;
|
|
179
|
+
cols: number;
|
|
180
|
+
rows: number;
|
|
181
|
+
process: string;
|
|
182
|
+
onData: (listener: (data: string) => void) => { dispose: () => void };
|
|
183
|
+
onExit: (listener: (data: { exitCode: number; signal?: string }) => void) => { dispose: () => void };
|
|
184
|
+
write(data: string): void;
|
|
185
|
+
resize(cols: number, rows: number): void;
|
|
186
|
+
kill(signal?: string): void;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
export class Terminal implements IPty {
|
|
190
|
+
private handle = -1;
|
|
191
|
+
private _pid = -1;
|
|
192
|
+
private _cols = DEFAULT_COLS;
|
|
193
|
+
private _rows = DEFAULT_ROWS;
|
|
194
|
+
private _readLoop = false;
|
|
195
|
+
private _closing = false;
|
|
196
|
+
private _onData = new EventEmitter<string>();
|
|
197
|
+
private _onExit = new EventEmitter<{ exitCode: number; signal?: string }>();
|
|
198
|
+
|
|
199
|
+
constructor(file = DEFAULT_FILE, args: string[] = [], opts: IPtyOptions = {}) {
|
|
200
|
+
this._cols = opts.cols ?? DEFAULT_COLS;
|
|
201
|
+
this._rows = opts.rows ?? DEFAULT_ROWS;
|
|
202
|
+
const cwd = opts.cwd ?? process.cwd();
|
|
203
|
+
const cmdline = [file, ...args.map(shQuote)].join(' ');
|
|
204
|
+
let envStr = '';
|
|
205
|
+
if (opts.env) {
|
|
206
|
+
const envPairs = Object.entries(opts.env).map(([k, v]) => \`\${k}=\${v}\`);
|
|
207
|
+
envStr = envPairs.join('\\x00') + '\\x00';
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
this.handle = lib.symbols.bun_pty_spawn(
|
|
211
|
+
Buffer.from(\`\${cmdline}\\x00\`, 'utf8'),
|
|
212
|
+
Buffer.from(\`\${cwd}\\x00\`, 'utf8'),
|
|
213
|
+
Buffer.from(\`\${envStr}\\x00\`, 'utf8'),
|
|
214
|
+
this._cols,
|
|
215
|
+
this._rows
|
|
216
|
+
);
|
|
217
|
+
|
|
218
|
+
if (this.handle < 0) throw new Error('PTY spawn failed');
|
|
219
|
+
this._pid = lib.symbols.bun_pty_get_pid(this.handle);
|
|
220
|
+
this._startReadLoop();
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
get pid() { return this._pid; }
|
|
224
|
+
get cols() { return this._cols; }
|
|
225
|
+
get rows() { return this._rows; }
|
|
226
|
+
get process() { return 'shell'; }
|
|
227
|
+
get onData() { return this._onData.event; }
|
|
228
|
+
get onExit() { return this._onExit.event; }
|
|
229
|
+
|
|
230
|
+
write(data: string) {
|
|
231
|
+
if (this._closing) return;
|
|
232
|
+
const buf = Buffer.from(data, 'utf8');
|
|
233
|
+
lib.symbols.bun_pty_write(this.handle, ptr(buf), buf.length);
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
resize(cols: number, rows: number) {
|
|
237
|
+
if (this._closing) return;
|
|
238
|
+
this._cols = cols;
|
|
239
|
+
this._rows = rows;
|
|
240
|
+
lib.symbols.bun_pty_resize(this.handle, cols, rows);
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
kill(signal = 'SIGTERM') {
|
|
244
|
+
if (this._closing) return;
|
|
245
|
+
this._closing = true;
|
|
246
|
+
lib.symbols.bun_pty_kill(this.handle);
|
|
247
|
+
lib.symbols.bun_pty_close(this.handle);
|
|
248
|
+
this._onExit.fire({ exitCode: 0, signal });
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
private async _startReadLoop() {
|
|
252
|
+
if (this._readLoop) return;
|
|
253
|
+
this._readLoop = true;
|
|
254
|
+
const buf = Buffer.allocUnsafe(4096);
|
|
255
|
+
|
|
256
|
+
while (this._readLoop && !this._closing) {
|
|
257
|
+
const n = lib.symbols.bun_pty_read(this.handle, ptr(buf), buf.length);
|
|
258
|
+
if (n > 0) {
|
|
259
|
+
this._onData.fire(buf.subarray(0, n).toString('utf8'));
|
|
260
|
+
} else if (n === -2) {
|
|
261
|
+
const exitCode = lib.symbols.bun_pty_get_exit_code(this.handle);
|
|
262
|
+
this._onExit.fire({ exitCode });
|
|
263
|
+
break;
|
|
264
|
+
} else if (n < 0) {
|
|
265
|
+
break;
|
|
266
|
+
} else {
|
|
267
|
+
await new Promise((r) => setTimeout(r, 8));
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
export function spawn(file: string, args: string[], options: IPtyOptions): IPty {
|
|
274
|
+
return new Terminal(file, args, options);
|
|
275
|
+
}
|
|
276
|
+
`;
|
|
277
|
+
|
|
278
|
+
writeFileSync(loaderPath, loaderContent);
|
|
279
|
+
console.log(` Generated bun-pty loader for ${ptyLib}`);
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
/**
|
|
283
|
+
* Clean up the generated loader file
|
|
284
|
+
*/
|
|
285
|
+
function cleanupLoader(): void {
|
|
286
|
+
if (existsSync(loaderPath)) {
|
|
287
|
+
unlinkSync(loaderPath);
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
|
|
43
291
|
// Build each target
|
|
44
|
-
for (const { name, target, outfile } of selectedTargets) {
|
|
292
|
+
for (const { name, target, outfile, ptyLib } of selectedTargets) {
|
|
45
293
|
console.log(`\nBuilding ${name}...`);
|
|
46
294
|
|
|
47
295
|
const outfilePath = join(binariesDir, outfile);
|
|
48
296
|
|
|
49
297
|
try {
|
|
50
|
-
|
|
298
|
+
// Generate platform-specific bun-pty loader
|
|
299
|
+
generatePtyLoader(ptyLib);
|
|
300
|
+
|
|
301
|
+
// Build the binary (bun-pty is now bundled via the generated loader)
|
|
302
|
+
await $`bun build --compile --minify --bytecode --target=${target} --external @ngrok/ngrok --external expo-server-sdk --define BUILD_VERSION='"${VERSION}"' src/index.ts --outfile ${outfilePath}`;
|
|
51
303
|
console.log(` ✓ Built ${outfile}`);
|
|
52
304
|
} catch (error) {
|
|
53
305
|
console.error(` ✗ Failed to build ${name}:`, error);
|
|
306
|
+
cleanupLoader();
|
|
54
307
|
process.exit(1);
|
|
55
308
|
}
|
|
56
309
|
}
|
|
57
310
|
|
|
311
|
+
// Clean up generated files
|
|
312
|
+
cleanupLoader();
|
|
313
|
+
|
|
58
314
|
console.log('\nBuild complete!');
|
package/scripts/postinstall.cjs
CHANGED
|
@@ -1,84 +1,84 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
/**
|
|
3
|
-
* Postinstall script (CommonJS version for npm compatibility)
|
|
4
|
-
*
|
|
5
|
-
* This script checks if bun-pty is working correctly.
|
|
6
|
-
* bun-pty is a Bun-native PTY implementation that doesn't require node-gyp.
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
const { existsSync } = require('fs');
|
|
10
|
-
const { join } = require('path');
|
|
11
|
-
const { spawn } = require('child_process');
|
|
12
|
-
|
|
13
|
-
const ROOT_PATH = join(__dirname, '..');
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* Check if Bun is available
|
|
17
|
-
*/
|
|
18
|
-
function checkBun() {
|
|
19
|
-
return new Promise((resolve) => {
|
|
20
|
-
const result = spawn('bun', ['--version'], { stdio: 'pipe', shell: true });
|
|
21
|
-
result.on('close', (code) => resolve(code === 0));
|
|
22
|
-
result.on('error', () => resolve(false));
|
|
23
|
-
});
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* Check if bun-pty works (requires Bun runtime)
|
|
28
|
-
*/
|
|
29
|
-
async function checkBunPty() {
|
|
30
|
-
const hasBun = await checkBun();
|
|
31
|
-
if (!hasBun) {
|
|
32
|
-
console.log('[postinstall] Bun not found, skipping bun-pty check');
|
|
33
|
-
console.log('[postinstall] Install Bun for full functionality: https://bun.sh');
|
|
34
|
-
return false;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
return new Promise((resolve) => {
|
|
38
|
-
// Run a simple Bun script to test bun-pty
|
|
39
|
-
const testScript = `
|
|
40
|
-
try {
|
|
41
|
-
const { spawn } = require('bun-pty');
|
|
42
|
-
const shell = process.platform === 'win32' ? 'cmd.exe' : 'sh';
|
|
43
|
-
const pty = spawn(shell, [], { cols: 80, rows: 24 });
|
|
44
|
-
pty.kill();
|
|
45
|
-
console.log('bun-pty is working correctly');
|
|
46
|
-
process.exit(0);
|
|
47
|
-
} catch (e) {
|
|
48
|
-
console.error('bun-pty check failed:', e.message);
|
|
49
|
-
process.exit(1);
|
|
50
|
-
}
|
|
51
|
-
`;
|
|
52
|
-
|
|
53
|
-
const testProcess = spawn('bun', ['-e', testScript], {
|
|
54
|
-
cwd: ROOT_PATH,
|
|
55
|
-
stdio: 'inherit',
|
|
56
|
-
shell: true,
|
|
57
|
-
});
|
|
58
|
-
|
|
59
|
-
testProcess.on('close', (code) => resolve(code === 0));
|
|
60
|
-
testProcess.on('error', () => resolve(false));
|
|
61
|
-
});
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
async function main() {
|
|
65
|
-
console.log('[postinstall] Code Chat Connect v2 - Post-installation check\n');
|
|
66
|
-
|
|
67
|
-
// Check bun-pty
|
|
68
|
-
const ptyWorks = await checkBunPty();
|
|
69
|
-
|
|
70
|
-
if (ptyWorks) {
|
|
71
|
-
console.log('\n[postinstall] All checks passed!');
|
|
72
|
-
} else {
|
|
73
|
-
console.log('\n[postinstall] Terminal functionality may be limited.');
|
|
74
|
-
console.log('[postinstall] Ensure Bun is installed: https://bun.sh');
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
console.log('\n[postinstall] Run "ccc" to start the server.\n');
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
main().catch((err) => {
|
|
81
|
-
console.error('[postinstall] Error:', err.message);
|
|
82
|
-
// Don't fail the install on postinstall errors
|
|
83
|
-
process.exit(0);
|
|
84
|
-
});
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Postinstall script (CommonJS version for npm compatibility)
|
|
4
|
+
*
|
|
5
|
+
* This script checks if bun-pty is working correctly.
|
|
6
|
+
* bun-pty is a Bun-native PTY implementation that doesn't require node-gyp.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
const { existsSync } = require('fs');
|
|
10
|
+
const { join } = require('path');
|
|
11
|
+
const { spawn } = require('child_process');
|
|
12
|
+
|
|
13
|
+
const ROOT_PATH = join(__dirname, '..');
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Check if Bun is available
|
|
17
|
+
*/
|
|
18
|
+
function checkBun() {
|
|
19
|
+
return new Promise((resolve) => {
|
|
20
|
+
const result = spawn('bun', ['--version'], { stdio: 'pipe', shell: true });
|
|
21
|
+
result.on('close', (code) => resolve(code === 0));
|
|
22
|
+
result.on('error', () => resolve(false));
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Check if bun-pty works (requires Bun runtime)
|
|
28
|
+
*/
|
|
29
|
+
async function checkBunPty() {
|
|
30
|
+
const hasBun = await checkBun();
|
|
31
|
+
if (!hasBun) {
|
|
32
|
+
console.log('[postinstall] Bun not found, skipping bun-pty check');
|
|
33
|
+
console.log('[postinstall] Install Bun for full functionality: https://bun.sh');
|
|
34
|
+
return false;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
return new Promise((resolve) => {
|
|
38
|
+
// Run a simple Bun script to test bun-pty
|
|
39
|
+
const testScript = `
|
|
40
|
+
try {
|
|
41
|
+
const { spawn } = require('bun-pty');
|
|
42
|
+
const shell = process.platform === 'win32' ? 'cmd.exe' : 'sh';
|
|
43
|
+
const pty = spawn(shell, [], { cols: 80, rows: 24 });
|
|
44
|
+
pty.kill();
|
|
45
|
+
console.log('bun-pty is working correctly');
|
|
46
|
+
process.exit(0);
|
|
47
|
+
} catch (e) {
|
|
48
|
+
console.error('bun-pty check failed:', e.message);
|
|
49
|
+
process.exit(1);
|
|
50
|
+
}
|
|
51
|
+
`;
|
|
52
|
+
|
|
53
|
+
const testProcess = spawn('bun', ['-e', testScript], {
|
|
54
|
+
cwd: ROOT_PATH,
|
|
55
|
+
stdio: 'inherit',
|
|
56
|
+
shell: true,
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
testProcess.on('close', (code) => resolve(code === 0));
|
|
60
|
+
testProcess.on('error', () => resolve(false));
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
async function main() {
|
|
65
|
+
console.log('[postinstall] Code Chat Connect v2 - Post-installation check\n');
|
|
66
|
+
|
|
67
|
+
// Check bun-pty
|
|
68
|
+
const ptyWorks = await checkBunPty();
|
|
69
|
+
|
|
70
|
+
if (ptyWorks) {
|
|
71
|
+
console.log('\n[postinstall] All checks passed!');
|
|
72
|
+
} else {
|
|
73
|
+
console.log('\n[postinstall] Terminal functionality may be limited.');
|
|
74
|
+
console.log('[postinstall] Ensure Bun is installed: https://bun.sh');
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
console.log('\n[postinstall] Run "ccc" to start the server.\n');
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
main().catch((err) => {
|
|
81
|
+
console.error('[postinstall] Error:', err.message);
|
|
82
|
+
// Don't fail the install on postinstall errors
|
|
83
|
+
process.exit(0);
|
|
84
|
+
});
|