@bobfrankston/msger 0.1.116 โ†’ 0.1.117

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.
Binary file
Binary file
Binary file
@@ -1,5 +1,7 @@
1
1
  #!/usr/bin/env node
2
- import { execSync } from 'child_process';
2
+ import { spawn } from 'child_process';
3
+ import { styleText } from 'node:util';
4
+ import dns from 'dns/promises';
3
5
  import fs from 'fs';
4
6
  import path from 'path';
5
7
  import packageJson from '../package.json' with { type: 'json' };
@@ -8,21 +10,90 @@ import packageJson from '../package.json' with { type: 'json' };
8
10
  const PI_HOST = 'pi4c'; // or 'pi@raspberrypi.local' or 'pi@192.168.1.xxx'
9
11
  const PI_BUILD_DIR = '/tmp/msger-native-build';
10
12
 
13
+ /**
14
+ * Run SSH command using spawn to avoid quoting issues
15
+ * @param args - Command arguments (e.g., ['pi4c', 'echo Connected'])
16
+ * @param options - Spawn options
17
+ * @returns Promise that resolves on success
18
+ */
19
+ function ssh(...args: string[]): Promise<void> {
20
+ return new Promise((resolve, reject) => {
21
+ const proc = spawn('ssh', args, { stdio: 'inherit' });
22
+ proc.on('close', (code) => {
23
+ if (code === 0) {
24
+ resolve();
25
+ } else {
26
+ reject(new Error(`SSH command failed with code ${code}`));
27
+ }
28
+ });
29
+ proc.on('error', reject);
30
+ });
31
+ }
32
+
33
+ /**
34
+ * Run SCP command using spawn to avoid quoting issues
35
+ * @param args - Command arguments (e.g., ['file.txt', 'pi4c:/tmp/'])
36
+ * @param options - Spawn options
37
+ * @returns Promise that resolves on success
38
+ */
39
+ function scp(...args: string[]): Promise<void> {
40
+ return new Promise((resolve, reject) => {
41
+ const proc = spawn('scp', args, { stdio: 'inherit' });
42
+ proc.on('close', (code) => {
43
+ if (code === 0) {
44
+ resolve();
45
+ } else {
46
+ reject(new Error(`SCP command failed with code ${code}`));
47
+ }
48
+ });
49
+ proc.on('error', reject);
50
+ });
51
+ }
52
+
53
+ /**
54
+ * Run SSH command and capture output
55
+ * @param args - Command arguments
56
+ * @returns Promise that resolves with stdout
57
+ */
58
+ function sshCapture(...args: string[]): Promise<string> {
59
+ return new Promise((resolve, reject) => {
60
+ let stdout = '';
61
+ const proc = spawn('ssh', args, { stdio: ['ignore', 'pipe', 'pipe'] });
62
+ proc.stdout.on('data', (data) => stdout += data.toString());
63
+ proc.on('close', (code) => {
64
+ if (code === 0) {
65
+ resolve(stdout);
66
+ } else {
67
+ reject(new Error(`SSH command failed with code ${code}`));
68
+ }
69
+ });
70
+ proc.on('error', reject);
71
+ });
72
+ }
73
+
11
74
  console.log('๐Ÿฆพ Building ARM64 binary via SSH to Raspberry Pi...');
12
75
  console.log(`๐Ÿ“ Target: ${PI_HOST}`);
13
76
 
77
+ // Debug: Test DNS resolution first
78
+ console.log('๐Ÿ” Testing DNS resolution...');
79
+ try {
80
+ const result = await dns.lookup(PI_HOST);
81
+ console.log(`โœ… DNS lookup successful: ${PI_HOST} -> ${result.address} (family: IPv${result.family})`);
82
+ } catch (error: any) {
83
+ console.log(`โš ๏ธ DNS lookup failed for ${PI_HOST}: ${error.message}`);
84
+ console.log(' Continuing anyway - SSH may have its own resolution...');
85
+ }
86
+
14
87
  try {
15
88
  // Test SSH connection
16
89
  console.log('๐Ÿ” Testing SSH connection...');
17
- execSync(`ssh ${PI_HOST} "echo Connected"`, { stdio: 'pipe', timeout: 5000 });
90
+ await sshCapture(PI_HOST, 'echo Connected');
18
91
  console.log('โœ… SSH connection successful');
19
92
  } catch (error) {
20
93
  // Yellow/orange banner for warning (not an error)
21
- console.log('\x1b[93m\x1b[40m'); // Bright yellow on black
22
- console.log('โ•”โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•—');
23
- console.log('โ•‘ โ„น๏ธ RASPBERRY PI NOT AVAILABLE - SKIPPING ARM64 BUILD โ•‘');
24
- console.log('โ•šโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•');
25
- console.log('\x1b[0m'); // Reset colors
94
+ console.log(styleText(['yellow', 'bold'], 'โ•”โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•—'));
95
+ console.log(styleText(['yellow', 'bold'], 'โ•‘ โ„น๏ธ RASPBERRY PI NOT AVAILABLE - SKIPPING ARM64 BUILD โ•‘'));
96
+ console.log(styleText(['yellow', 'bold'], 'โ•šโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•'));
26
97
  console.log('');
27
98
  console.log(`Cannot connect to Pi: ${PI_HOST}`);
28
99
  console.log('To enable Pi builds:');
@@ -36,7 +107,7 @@ try {
36
107
 
37
108
  // Create build directory on Pi
38
109
  console.log('๐Ÿ“ Creating build directory on Pi...');
39
- execSync(`ssh ${PI_HOST} "mkdir -p ${PI_BUILD_DIR}/src"`, { stdio: 'inherit' });
110
+ await ssh(PI_HOST, `mkdir -p ${PI_BUILD_DIR}/src`);
40
111
 
41
112
  // Check if build is needed (compare source file mtimes with existing binary)
42
113
  console.log('๐Ÿ” Checking if build is needed...');
@@ -76,60 +147,52 @@ if (fs.existsSync(destPath)) {
76
147
 
77
148
  // Copy source files to Pi
78
149
  console.log('๐Ÿ“ค Copying source files to Pi...');
79
- execSync(`scp Cargo.toml ${PI_HOST}:${PI_BUILD_DIR}/`, { stdio: 'inherit', cwd: import.meta.dirname });
80
- execSync(`scp -r src/* ${PI_HOST}:${PI_BUILD_DIR}/src/`, { stdio: 'inherit', cwd: import.meta.dirname });
150
+ const origDir = process.cwd();
151
+ process.chdir(import.meta.dirname);
152
+ await scp('Cargo.toml', `${PI_HOST}:${PI_BUILD_DIR}/`);
153
+ await scp('-r', 'src/*', `${PI_HOST}:${PI_BUILD_DIR}/src/`);
154
+ process.chdir(origDir);
81
155
 
82
156
  // Check for C compiler (gcc/cc) on Pi
83
157
  console.log('๐Ÿ” Checking for C compiler on Pi...');
84
158
  try {
85
- execSync(`ssh ${PI_HOST} "command -v gcc"`, { stdio: 'pipe' });
159
+ await sshCapture(PI_HOST, 'command -v gcc');
86
160
  console.log('โœ… C compiler found');
87
161
  } catch {
88
- console.log('๐Ÿ“ฆ Installing build-essential (C compiler, make, etc.) on Pi...');
89
- execSync(`ssh ${PI_HOST} "sudo apt-get update && sudo apt-get install -y build-essential"`, { stdio: 'inherit' });
90
- console.log('โœ… build-essential installed');
162
+ console.log('โš ๏ธ C compiler not found - build will likely fail');
163
+ console.log(' To fix: ssh pi4c "sudo apt-get install -y build-essential"');
91
164
  }
92
165
 
93
166
  // Check for Rust on Pi
94
167
  console.log('๐Ÿ” Checking for Rust/Cargo on Pi...');
95
168
  try {
96
- execSync(`ssh ${PI_HOST} "command -v cargo"`, { stdio: 'pipe' });
169
+ await sshCapture(PI_HOST, 'source ~/.cargo/env 2>/dev/null; command -v cargo');
97
170
  console.log('โœ… Rust/Cargo found');
98
171
  } catch {
99
- console.log('๐Ÿ“ฆ Installing Rust on Pi...');
100
- execSync(`ssh ${PI_HOST} "curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y"`, { stdio: 'inherit' });
101
- console.log('โœ… Rust installed successfully');
172
+ console.log('โš ๏ธ Rust not found - build will fail');
173
+ console.log(' To fix: ssh pi4c "curl --proto \'=https\' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y"');
174
+ process.exit(0);
102
175
  }
103
176
 
104
177
  // Ensure pkg-config is installed first (required to check for other dependencies)
105
178
  console.log('๐Ÿ”ง Ensuring pkg-config is installed on Pi...');
106
179
  try {
107
- execSync(`ssh ${PI_HOST} "command -v pkg-config"`, { stdio: 'pipe' });
180
+ await sshCapture(PI_HOST, 'command -v pkg-config');
108
181
  console.log('โœ… pkg-config found');
109
182
  } catch {
110
- console.log('๐Ÿ“ฆ Installing pkg-config on Pi...');
111
- execSync(`ssh ${PI_HOST} "sudo apt-get update && sudo apt-get install -y pkg-config"`, { stdio: 'inherit' });
112
- console.log('โœ… pkg-config installed');
183
+ console.log('โš ๏ธ pkg-config not found - build will likely fail');
184
+ console.log(' To fix: ssh pi4c "sudo apt-get install -y pkg-config"');
113
185
  }
114
186
 
115
187
  // Check for build dependencies on Pi
116
188
  console.log('๐Ÿ” Checking for build dependencies on Pi...');
117
189
  try {
118
190
  // Check for all required libraries: glib, gobject, gio, gtk, webkit
119
- execSync(`ssh ${PI_HOST} "pkg-config --exists glib-2.0 gobject-2.0 gio-2.0 gtk+-3.0 && (pkg-config --exists webkit2gtk-4.1 || pkg-config --exists webkit2gtk-4.0)"`, { stdio: 'pipe' });
191
+ await sshCapture(PI_HOST, 'pkg-config --exists glib-2.0 gobject-2.0 gio-2.0 gtk+-3.0 && (pkg-config --exists webkit2gtk-4.1 || pkg-config --exists webkit2gtk-4.0)');
120
192
  console.log('โœ… Build dependencies found');
121
193
  } catch {
122
- console.log('๐Ÿ“ฆ Installing build dependencies on Pi...');
123
- // Install all required development packages
124
- // Try webkit2gtk-4.1 first (newer), fallback to 4.0 if not available
125
- try {
126
- execSync(`ssh ${PI_HOST} "sudo apt-get install -y libglib2.0-dev libgtk-3-dev libwebkit2gtk-4.1-dev"`, { stdio: 'inherit' });
127
- console.log('โœ… Build dependencies installed (webkit2gtk-4.1)');
128
- } catch {
129
- console.log('โ„น๏ธ webkit2gtk-4.1 not available, trying 4.0...');
130
- execSync(`ssh ${PI_HOST} "sudo apt-get install -y libglib2.0-dev libgtk-3-dev libwebkit2gtk-4.0-dev libsoup2.4-dev"`, { stdio: 'inherit' });
131
- console.log('โœ… Build dependencies installed (webkit2gtk-4.0)');
132
- }
194
+ console.log('โš ๏ธ Build dependencies not found - build will likely fail');
195
+ console.log(' To fix: ssh pi4c "sudo apt-get install -y libglib2.0-dev libgtk-3-dev libwebkit2gtk-4.1-dev"');
133
196
  }
134
197
 
135
198
  // Get NPM version from imported package.json
@@ -138,20 +201,19 @@ console.log(`๐Ÿ“‹ Package version: ${npmVersion}`);
138
201
 
139
202
  // Copy package.json to Pi (needed for version)
140
203
  console.log('๐Ÿ“ค Copying package.json to Pi...');
141
- execSync(`scp package.json ${PI_HOST}:${PI_BUILD_DIR}/`, { stdio: 'inherit', cwd: import.meta.dirname });
204
+ process.chdir(import.meta.dirname);
205
+ await scp('package.json', `${PI_HOST}:${PI_BUILD_DIR}/`);
206
+ process.chdir(origDir);
142
207
 
143
208
  // Build on Pi
144
209
  console.log('\n๐Ÿ“ฆ Building ARM64 binary on Pi...');
145
210
  try {
146
211
  // Source cargo env and build (ensures cargo can find all its dependencies including cc)
147
212
  // Export NPM_VERSION for Rust build
148
- execSync(`ssh ${PI_HOST} "cd ${PI_BUILD_DIR} && source ~/.cargo/env && export PKG_CONFIG_PATH=/usr/lib/aarch64-linux-gnu/pkgconfig:/usr/share/pkgconfig && export NPM_VERSION=${npmVersion} && cargo build --release"`, { stdio: 'inherit' });
213
+ await ssh(PI_HOST, `cd ${PI_BUILD_DIR} && source ~/.cargo/env && export PKG_CONFIG_PATH=/usr/lib/aarch64-linux-gnu/pkgconfig:/usr/share/pkgconfig && export NPM_VERSION=${npmVersion} && cargo build --release`);
149
214
  console.log('โœ… ARM64 build completed');
150
215
  } catch (error: any) {
151
216
  console.error('โŒ Pi build failed:');
152
- console.error(error.stdout?.toString());
153
- console.error(error.stderr?.toString());
154
- console.error('');
155
217
  console.error('โš ๏ธ Continuing without Pi binary...');
156
218
  process.exit(0); // Exit gracefully to not break overall build
157
219
  }
@@ -163,7 +225,7 @@ if (!fs.existsSync(destDir)) {
163
225
  fs.mkdirSync(destDir, { recursive: true });
164
226
  }
165
227
 
166
- execSync(`scp ${PI_HOST}:${PI_BUILD_DIR}/target/release/msgernative ${destPath}`, { stdio: 'inherit' });
228
+ await scp(`${PI_HOST}:${PI_BUILD_DIR}/target/release/msgernative`, destPath);
167
229
 
168
230
  // Set execute permissions
169
231
  fs.chmodSync(destPath, 0o755);
@@ -175,6 +237,6 @@ console.log(`๐Ÿ“Š Binary size: ${sizeMB} MB`);
175
237
 
176
238
  // Cleanup on Pi
177
239
  console.log('๐Ÿงน Cleaning up on Pi...');
178
- execSync(`ssh ${PI_HOST} "rm -rf ${PI_BUILD_DIR}"`, { stdio: 'inherit' });
240
+ await ssh(PI_HOST, `rm -rf ${PI_BUILD_DIR}`);
179
241
 
180
242
  console.log('\n๐ŸŽ‰ ARM64 build process completed!');
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bobfrankston/msger",
3
- "version": "0.1.116",
3
+ "version": "0.1.117",
4
4
  "description": "Fast, lightweight, cross-platform message box - Rust-powered alternative to msgview",
5
5
  "type": "module",
6
6
  "main": "./index.js",