@bobfrankston/msger 0.1.80 → 0.1.82

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/DEVELOPERS.md ADDED
@@ -0,0 +1,265 @@
1
+ # msger - Developer Guide
2
+
3
+ This document contains technical information for developers working on msger.
4
+
5
+ ## Architecture
6
+
7
+ ```
8
+ @bobfrankston/msger (TypeScript wrapper)
9
+ ↓ spawns native binary with JSON via stdin OR file + CLI args
10
+ @bobfrankston/msger-native (Rust binary - platform-specific)
11
+ ↓ creates native window with webview
12
+ ↓ displays HTML/URL content with buttons
13
+ ↓ outputs JSON result to stdout
14
+ TypeScript wrapper returns Promise<MessageBoxResult>
15
+ ```
16
+
17
+ **Platform-specific binaries:**
18
+ - `msgernative.exe` - Windows x64 (WebView2)
19
+ - `msgernative` - Linux x86_64 (WebKitGTK)
20
+ - `msgernative-arm64` - Linux ARM64/Raspberry Pi (WebKitGTK)
21
+
22
+ The correct binary is automatically selected based on `process.platform` and `process.arch`.
23
+
24
+ ## Building from Source
25
+
26
+ ### Prerequisites
27
+
28
+ - **Rust** (install from https://rustup.rs/)
29
+ - **Node.js** (v16 or later)
30
+ - **Windows**: Visual Studio Build Tools with C++ development tools
31
+ - **macOS**: Xcode Command Line Tools
32
+ - **Linux**: WebKitGTK development packages
33
+
34
+ ### Build Commands
35
+
36
+ ```bash
37
+ # Build everything (TypeScript + all native binaries)
38
+ npm run build
39
+
40
+ # Build only TypeScript wrapper
41
+ npm run build:ts
42
+
43
+ # Build Windows binary
44
+ npm run build:native
45
+
46
+ # Build Linux x64 binary (via WSL)
47
+ npm run build:native:wsl
48
+
49
+ # Build ARM64 binary (via SSH to Raspberry Pi)
50
+ npm run build:native:pi
51
+
52
+ # Build all native binaries
53
+ npm run build:native:all
54
+
55
+ # Watch mode for TypeScript development
56
+ npm run watch
57
+ ```
58
+
59
+ ### Building ARM64 Binary
60
+
61
+ To build the ARM64 binary for Raspberry Pi:
62
+
63
+ 1. Update `PI_HOST` in `msger-native/build-pi.ts` with your Pi's hostname/IP
64
+ 2. Ensure SSH keys are set up: `ssh-copy-id pi@your-pi`
65
+ 3. Run: `npm run build:native:pi`
66
+
67
+ The script will automatically:
68
+ - Copy source files to the Pi via SSH
69
+ - Install Rust and build dependencies if needed
70
+ - Build the binary on the Pi
71
+ - Copy the binary back to your development machine
72
+
73
+ ### Manual Rust Build
74
+
75
+ If you prefer to build the Rust binary manually:
76
+
77
+ ```bash
78
+ cd msger-native
79
+
80
+ # Debug build (faster compile, larger binary)
81
+ cargo build
82
+
83
+ # Release build (optimized, smaller binary)
84
+ cargo build --release
85
+ ```
86
+
87
+ **Note**: If you encounter linker errors on Windows, make sure Visual Studio Build Tools with C++ workload is installed.
88
+
89
+ ### Cross-Platform Builds
90
+
91
+ ```bash
92
+ # Windows
93
+ cargo build --release --target x86_64-pc-windows-msvc
94
+
95
+ # Linux (from Linux or WSL)
96
+ cargo build --release --target x86_64-unknown-linux-gnu
97
+
98
+ # macOS (requires macOS or CI)
99
+ cargo build --release --target x86_64-apple-darwin
100
+ cargo build --release --target aarch64-apple-darwin # Apple Silicon
101
+ ```
102
+
103
+ ## Project Structure
104
+
105
+ The project consists of two parts:
106
+
107
+ 1. **`msger-native/`** - Rust binary (subdirectory with its own Cargo.toml)
108
+ - `src/main.rs` - Main application logic
109
+ - `src/msger-api.js` - JavaScript API injected into webviews
110
+ - `src/template.html` - HTML template for message boxes
111
+ - `bin/` - Compiled binaries for distribution
112
+ - `README.md` - Rust-specific documentation
113
+
114
+ 2. **Root directory** - TypeScript wrapper and npm package
115
+ - TypeScript wrapper for Node.js API
116
+ - CLI interface
117
+ - Build scripts
118
+
119
+ When you run `npm run build`, it:
120
+ 1. Builds platform-specific Rust binaries
121
+ 2. Copies binaries to `msger-native/bin/`
122
+ 3. Compiles TypeScript to JavaScript
123
+
124
+ All binaries are bundled with the npm package, and the correct one is selected at runtime.
125
+
126
+ ## Dependencies
127
+
128
+ ### Rust (msger-native)
129
+
130
+ - **wry** (0.47) - Cross-platform webview library
131
+ - **tao** (0.30) - Cross-platform windowing
132
+ - **serde** / **serde_json** (1.0) - JSON serialization
133
+ - **clap** (4.5) - Command-line argument parsing
134
+ - **windows** (0.58) - Windows API bindings (Windows only)
135
+ - **image** (0.24) - Icon loading
136
+
137
+ ### TypeScript/Node.js
138
+
139
+ - Standard Node.js APIs for process spawning
140
+ - No runtime dependencies
141
+
142
+ ## Design Trade-offs
143
+
144
+ ### Why Rust + WebView instead of Electron?
145
+
146
+ **Size:**
147
+ - Electron: ~100MB bundled app
148
+ - msger: ~2-5MB per platform binary
149
+ - **50-100x smaller**
150
+
151
+ **Startup Time:**
152
+ - Electron: ~2-3 seconds
153
+ - msger: ~50-200ms
154
+ - **10-20x faster**
155
+
156
+ **Memory:**
157
+ - Electron: ~100-200MB
158
+ - msger: ~20-50MB
159
+ - **3-5x less**
160
+
161
+ **Trade-off:** Platform-specific binaries vs single JavaScript bundle. We chose better performance.
162
+
163
+ ### Why Multiple Binaries?
164
+
165
+ We ship separate binaries for each platform instead of one universal binary:
166
+
167
+ **Pros:**
168
+ - Smaller download per platform
169
+ - Native performance
170
+ - No cross-compilation complexity
171
+
172
+ **Cons:**
173
+ - Larger npm package overall
174
+ - Need to build on each platform
175
+
176
+ **Decision:** Better user experience (smaller, faster) outweighs developer complexity.
177
+
178
+ ### Why stdin/stdout JSON instead of native Node.js addon?
179
+
180
+ **Pros:**
181
+ - Platform independence (no native compilation at install time)
182
+ - Easy debugging (can test with echo/pipes)
183
+ - Clear separation of concerns
184
+ - No version compatibility issues
185
+
186
+ **Cons:**
187
+ - Slightly higher overhead (process spawn)
188
+ - No shared memory
189
+
190
+ **Decision:** The 50-200ms startup is fast enough, and JSON is simpler than N-API.
191
+
192
+ ## Testing the Native Binary
193
+
194
+ ### Standalone Tests
195
+
196
+ ```bash
197
+ # Simple message
198
+ echo '{"message":"Hello from Rust!","buttons":["Cancel","OK"]}' | ./msger-native/bin/msgernative
199
+
200
+ # With input field
201
+ echo '{"message":"Enter your name:","allowInput":true,"defaultValue":"John","buttons":["Cancel","Submit"]}' | ./msger-native/bin/msgernative
202
+
203
+ # With HTML content
204
+ echo '{"title":"Rich Content","html":"<h2>Welcome</h2><p>This is <strong>HTML</strong> content</p>","buttons":["Close"]}' | ./msger-native/bin/msgernative
205
+
206
+ # JSON file + CLI overrides
207
+ ./msger-native/bin/msgernative config.json --title "Override Title" --width 800
208
+
209
+ # Pure CLI
210
+ ./msger-native/bin/msgernative --message "Hello" --buttons "OK,Cancel" --width 600
211
+ ```
212
+
213
+ ## Contributing
214
+
215
+ ### Code Style
216
+
217
+ - **Rust**: Follow standard `rustfmt` style
218
+ - **TypeScript**: 4-space indentation, semicolons
219
+ - **Comments**: Explain why, not what
220
+
221
+ ### Pull Requests
222
+
223
+ 1. Create a feature branch
224
+ 2. Make your changes
225
+ 3. Test on your platform
226
+ 4. Submit PR with description
227
+
228
+ ### Testing Checklist
229
+
230
+ Before submitting:
231
+ - [ ] Test on Windows (if available)
232
+ - [ ] Test on Linux (if available)
233
+ - [ ] Test stdin mode
234
+ - [ ] Test JSON file mode
235
+ - [ ] Test CLI argument mode
236
+ - [ ] Test button clicks
237
+ - [ ] Test input fields
238
+ - [ ] Test HTML content
239
+ - [ ] Test URL loading
240
+ - [ ] Update documentation
241
+
242
+ ## Performance Comparison
243
+
244
+ | | **Electron (msgview)** | **Rust (msger)** | **Improvement** |
245
+ |---|---|---|---|
246
+ | **Binary Size** | ~100MB | ~1-2MB per platform | **50-100x smaller** |
247
+ | **Startup Time** | ~2-3 seconds | ~50-200ms | **10-20x faster** |
248
+ | **Memory Usage** | ~100-200MB | ~20-50MB | **3-5x less** |
249
+ | **Cross-Platform** | ✅ Win/Mac/Linux | ✅ Win/Linux x64/ARM64 | Similar |
250
+ | **Full HTML/CSS** | ✅ Chromium | ✅ WebView2/WebKit | Same |
251
+ | **URL Loading** | ✅ | ✅ | Same |
252
+
253
+ ## Technical Documentation
254
+
255
+ For detailed technical status, known issues, and roadmap, see:
256
+ - [TODO.md](TODO.md) - Development roadmap and known issues
257
+ - [SESSION-NOTES.md](SESSION-NOTES.md) - Implementation notes and decisions (if available)
258
+
259
+ ## License
260
+
261
+ ISC
262
+
263
+ ## Author
264
+
265
+ Bob Frankston
package/README.md CHANGED
@@ -1,12 +1,16 @@
1
1
  # @bobfrankston/msger
2
2
 
3
- Fast, lightweight, cross-platform message box - Rust-powered alternative to `@bobfrankston/msgview`.
3
+ Fast, lightweight message boxes for Node.js applications.
4
4
 
5
- This package provides a TypeScript/JavaScript API that wraps the native Rust implementation for:
6
- - **10-20x faster startup** (~50-200ms vs ~2-3s)
7
- - **50x smaller binary** (~2-5MB vs ~100MB)
8
- - **5x less memory** (~20-50MB vs ~100-200MB)
9
- - **Cross-platform**: Windows (WebView2), Linux x86_64 (WebKitGTK), Linux ARM64/Raspberry Pi (WebKitGTK)
5
+ Display native message boxes, dialogs, and HTML content with a simple JavaScript API. Works on Windows, Linux (x64), and Linux (ARM64/Raspberry Pi).
6
+
7
+ ## Quick Links
8
+
9
+ - **[Installation](#installation)** - Get started
10
+ - **[Command Line Usage](#command-line-usage)** - Use from shell scripts
11
+ - **[Node.js API](#nodejs-api-reference)** - Use from JavaScript/TypeScript
12
+ - **[For Developers](DEVELOPERS.md)** - Building & architecture
13
+ - **[Roadmap](TODO.md)** - Technical status & planned features
10
14
 
11
15
  ## Installation
12
16
 
@@ -19,34 +23,18 @@ For global CLI usage:
19
23
  npm install -g @bobfrankston/msger
20
24
  ```
21
25
 
22
- **Platform Support:**
23
- - Windows (x64) - Uses WebView2
24
- - Linux x86_64 - Uses WebKitGTK 4.0
25
- - Linux ARM64/Raspberry Pi - Uses WebKitGTK 4.0
26
+ **Supported Platforms:**
27
+ - Windows (x64)
28
+ - Linux (x64)
29
+ - Linux (ARM64 / Raspberry Pi)
26
30
 
27
- The correct binary is automatically selected based on your platform and architecture.
31
+ ---
28
32
 
29
- ## Usage
33
+ # Command Line Usage
30
34
 
31
- ### As a Library (Recommended)
35
+ The `msger` command-line tool provides a quick way to display message boxes from shell scripts, batch files, or terminal.
32
36
 
33
- ```typescript
34
- import { showMessageBox } from '@bobfrankston/msger';
35
-
36
- const result = await showMessageBox({
37
- title: 'Confirm Action',
38
- message: 'Are you sure you want to proceed?',
39
- buttons: ['Cancel', 'OK']
40
- });
41
-
42
- console.log('User clicked:', result.button);
43
-
44
- if (result.value) {
45
- console.log('User entered:', result.value);
46
- }
47
- ```
48
-
49
- ### As a CLI Tool
37
+ ## Basic Examples
50
38
 
51
39
  ```bash
52
40
  # Simple message
@@ -91,7 +79,194 @@ msger -message "Closing in 5 seconds..." -timeout 5
91
79
  msger --help
92
80
  ```
93
81
 
94
- ## API
82
+ ## JSON Configuration Files
83
+
84
+ You can store message box configuration in a JSON file for reuse:
85
+
86
+ ```bash
87
+ # Load configuration from file
88
+ msger config.json
89
+
90
+ # Override specific values
91
+ msger config.json --title "New Title" --width 800
92
+ ```
93
+
94
+ ### Complete JSON Structure
95
+
96
+ ```json
97
+ {
98
+ "title": "Window Title",
99
+ "message": "Plain text message (supports ANSI color codes)",
100
+ "html": "<h1>HTML content</h1><p>Rich formatting</p>",
101
+ "url": "https://example.com",
102
+ "size": {
103
+ "width": 600,
104
+ "height": 400
105
+ },
106
+ "pos": {
107
+ "x": 100,
108
+ "y": 100,
109
+ "screen": 0
110
+ },
111
+ "buttons": ["Cancel", "OK"],
112
+ "defaultValue": "default input text",
113
+ "inputPlaceholder": "Enter text here...",
114
+ "allowInput": false,
115
+ "timeout": 30,
116
+ "autoSize": false,
117
+ "alwaysOnTop": false,
118
+ "fullscreen": false,
119
+ "zoomPercent": 100,
120
+ "debug": false,
121
+ "icon": "path/to/icon.png",
122
+ "dev": false
123
+ }
124
+ ```
125
+
126
+ ### Field Reference
127
+
128
+ | Field | Type | Default | Description |
129
+ |-------|------|---------|-------------|
130
+ | `title` | string | "Message" | Window title |
131
+ | `message` | string | null | Plain text message (supports ANSI color codes) |
132
+ | `html` | string | null | HTML content to display |
133
+ | `url` | string | null | URL to load (web or file://) |
134
+ | `size` | object | `{"width": 600, "height": 400}` | Window size |
135
+ | `size.width` | number | 600 (or 1024 for URLs) | Window width in pixels |
136
+ | `size.height` | number | 400 (or 768 for URLs) | Window height in pixels |
137
+ | `pos` | object | null | Window position |
138
+ | `pos.x` | number | - | X coordinate in pixels |
139
+ | `pos.y` | number | - | Y coordinate in pixels |
140
+ | `pos.screen` | number | null | [Windows only] Screen index (0=primary, 1=second, etc.) |
141
+ | `buttons` | string[] | ["OK"] | Button labels |
142
+ | `defaultValue` | string | null | Default input value |
143
+ | `inputPlaceholder` | string | null | Placeholder text for input field |
144
+ | `allowInput` | boolean | false | Show input field |
145
+ | `timeout` | number | null | Auto-close after N seconds |
146
+ | `autoSize` | boolean | true when no size | Auto-resize window to fit content |
147
+ | `alwaysOnTop` | boolean | false | Keep window on top |
148
+ | `fullscreen` | boolean | false | Start in fullscreen mode |
149
+ | `zoomPercent` | number | 100 | Initial zoom level (100=100%, 150=150%) |
150
+ | `debug` | boolean | false | Return debug info in result |
151
+ | `icon` | string | null | Path to window icon (.png, .ico) |
152
+ | `dev` | boolean | false | Enable developer mode |
153
+
154
+ **Content Priority:** Only one content type will be displayed (in order):
155
+ 1. `url` - If provided, loads URL (ignores message/html)
156
+ 2. `html` - If provided, displays HTML (ignores message)
157
+ 3. `message` - Plain text with ANSI color support
158
+
159
+ **Backward Compatibility:** The old `width` and `height` fields (at the top level) are still supported for backward compatibility, but the `size` object is preferred. If both are provided, `size` takes precedence.
160
+
161
+ ### JSON Examples
162
+
163
+ **Simple dialog:**
164
+ ```json
165
+ {
166
+ "title": "Confirm",
167
+ "message": "Are you sure?",
168
+ "buttons": ["Cancel", "OK"]
169
+ }
170
+ ```
171
+
172
+ **Input dialog:**
173
+ ```json
174
+ {
175
+ "title": "Enter Name",
176
+ "message": "Please enter your name:",
177
+ "allowInput": true,
178
+ "inputPlaceholder": "Your name here",
179
+ "defaultValue": "John Doe",
180
+ "buttons": ["Cancel", "Submit"]
181
+ }
182
+ ```
183
+
184
+ **HTML content:**
185
+ ```json
186
+ {
187
+ "title": "Welcome",
188
+ "html": "<h1>Welcome!</h1><p>Getting started...</p>",
189
+ "size": {
190
+ "width": 700,
191
+ "height": 500
192
+ }
193
+ }
194
+ ```
195
+
196
+ **Positioned window on second monitor:**
197
+ ```json
198
+ {
199
+ "message": "Second screen",
200
+ "pos": {
201
+ "x": 0,
202
+ "y": 100,
203
+ "screen": 1
204
+ }
205
+ }
206
+ ```
207
+
208
+ ## CLI Options Reference
209
+
210
+ ```
211
+ Usage: msger [options] [message words...]
212
+
213
+ Options:
214
+ -message, --message <text> Plain text message
215
+ -title, --title <text> Window title
216
+ -html, --html <html> HTML content
217
+ -url, --url <url> URL to load (web or file://)
218
+ -buttons, --buttons <labels> Button labels (e.g., -buttons Yes No Cancel)
219
+ -ok, --ok Add OK button
220
+ -cancel, --cancel Add Cancel button
221
+ -input, --input [placeholder] Include input field with optional placeholder text
222
+ -default, --default <text> Default value for input field
223
+ -size, --size <width,height> Window size (e.g., -size 800,600)
224
+ -pos, --pos <x,y> Window position (e.g., -pos 100,200)
225
+ -screen, --screen <number> [Windows only] Screen index (0=primary, 1=second, etc.)
226
+ -zoom, --zoom <percent> Zoom level as percentage (e.g., -zoom 150 for 150%)
227
+ -timeout, --timeout <seconds> Auto-close after specified seconds
228
+ -ontop, --ontop Keep window always on top
229
+ -detach, --detach Launch window independently (parent returns immediately)
230
+ -fullscreen, --fullscreen Start window in fullscreen mode (F11 to toggle, Escape to exit)
231
+ -debug, --debug Return debug info (HTML, size, autoSize) in result
232
+ -v, -version, --version Show version number
233
+ -help, -?, --help Show help message
234
+
235
+ Notes:
236
+ - If no options provided, all non-option arguments are concatenated as message
237
+ - Press ESC to dismiss (returns button: "dismissed")
238
+ - Press Enter to click last (default) button
239
+ - OK button is green by default
240
+ - URLs default to 1024x768 window size
241
+ - Windows auto-size to fit content when size not specified
242
+ - Runtime zoom: Ctrl+Wheel, Ctrl+Plus, Ctrl+Minus
243
+ ```
244
+
245
+ ---
246
+
247
+ # Node.js API Reference
248
+
249
+ Use msger in your Node.js or TypeScript applications with a simple Promise-based API.
250
+
251
+ ## Quick Start
252
+
253
+ ```typescript
254
+ import { showMessageBox } from '@bobfrankston/msger';
255
+
256
+ const result = await showMessageBox({
257
+ title: 'Confirm Action',
258
+ message: 'Are you sure you want to proceed?',
259
+ buttons: ['Cancel', 'OK']
260
+ });
261
+
262
+ console.log('User clicked:', result.button);
263
+
264
+ if (result.value) {
265
+ console.log('User entered:', result.value);
266
+ }
267
+ ```
268
+
269
+ ## API Functions
95
270
 
96
271
  ### `showMessageBox(options: MessageBoxOptions): Promise<MessageBoxResult>`
97
272
 
@@ -147,7 +322,7 @@ interface MessageBoxResult {
147
322
  }
148
323
  ```
149
324
 
150
- ## Examples
325
+ ## API Examples
151
326
 
152
327
  ### Simple Confirmation Dialog
153
328
 
@@ -254,17 +429,12 @@ const result = await showMessageBox({
254
429
  });
255
430
 
256
431
  if (result.timeout) {
257
- console.log('Dialog timed out');
432
+ console.log('Notification auto-closed');
258
433
  }
259
434
  ```
260
435
 
261
436
  The countdown timer displays as a subtle yellow badge in the top-right corner, showing the remaining seconds (e.g., "10s", "9s", "8s"...).
262
437
 
263
- if (result.timeout) {
264
- console.log('Notification auto-closed');
265
- }
266
- ```
267
-
268
438
  ### HTML Forms
269
439
 
270
440
  ```typescript
@@ -356,161 +526,35 @@ await showMessageBox({
356
526
  });
357
527
  ```
358
528
 
359
- ## Architecture
360
-
361
- ```
362
- @bobfrankston/msger (TypeScript wrapper)
363
- ↓ spawns native binary with JSON via stdin
364
- @bobfrankston/msger-native (Rust binary - platform-specific)
365
- ↓ creates native window with webview
366
- ↓ displays HTML/URL content with buttons
367
- ↓ outputs JSON result to stdout
368
- TypeScript wrapper returns Promise<MessageBoxResult>
369
- ```
370
-
371
- **Platform-specific binaries:**
372
- - `msgernative.exe` - Windows x64 (WebView2)
373
- - `msgernative` - Linux x86_64 (WebKitGTK)
374
- - `msgernative-arm64` - Linux ARM64/Raspberry Pi (WebKitGTK)
375
-
376
- The correct binary is automatically selected based on `process.platform` and `process.arch`.
377
-
378
- ## Building from Source
379
-
380
- ```bash
381
- # Build everything (TypeScript + all native binaries)
382
- npm run build
383
-
384
- # Build only TypeScript wrapper
385
- npm run build:ts
386
-
387
- # Build Windows binary
388
- npm run build:native
389
-
390
- # Build Linux x64 binary (via WSL)
391
- npm run build:native:wsl
392
-
393
- # Build ARM64 binary (via SSH to Raspberry Pi)
394
- npm run build:native:pi
395
-
396
- # Build all native binaries
397
- npm run build:native:all
398
-
399
- # Watch mode for TypeScript development
400
- npm run watch
401
- ```
402
-
403
- ### Building ARM64 Binary
404
-
405
- To build the ARM64 binary for Raspberry Pi:
406
-
407
- 1. Update `PI_HOST` in `msger-native/build-pi.ts` with your Pi's hostname/IP
408
- 2. Ensure SSH keys are set up: `ssh-copy-id pi@your-pi`
409
- 3. Run: `npm run build:native:pi`
410
-
411
- The script will automatically:
412
- - Copy source files to the Pi via SSH
413
- - Install Rust and build dependencies if needed
414
- - Build the binary on the Pi
415
- - Copy the binary back to your development machine
416
-
417
- ## Development
418
-
419
- The project consists of two parts:
420
-
421
- 1. **`msger-native/`** - Rust binary (subdirectory with its own Cargo.toml)
422
- 2. **Root directory** - TypeScript wrapper and npm package
423
-
424
- When you run `npm run build`, it:
425
- 1. Builds platform-specific Rust binaries
426
- 2. Copies binaries to `msger-native/bin/`
427
- 3. Compiles TypeScript to JavaScript
428
-
429
- All binaries are bundled with the npm package, and the correct one is selected at runtime.
430
-
431
529
  ## Features
432
530
 
433
- - ✅ Cross-platform native webview (Windows, Linux x64, Linux ARM64)
434
- - ✅ Full HTML/CSS support with inline styles
435
- - ✅ ANSI color escape sequences (automatic conversion to HTML colors)
436
- - ✅ Load external URLs or local files
437
- - ✅ Customizable buttons (OK button is green by default)
438
- - ✅ Input field support with placeholder text
439
- - ✅ HTML forms with automatic data collection
531
+ - ✅ Display plain text, HTML content, or load URLs
532
+ - ✅ Full HTML/CSS support
533
+ - ✅ ANSI color codes (colored terminal output)
534
+ - ✅ Customizable buttons
535
+ - ✅ Input fields and forms
440
536
  - ✅ Auto-close with timeout
441
- - ✅ Window positioning (x, y coordinates)
442
- - ✅ Multi-monitor support (Windows only - screen index)
537
+ - ✅ Window positioning and sizing
538
+ - ✅ Multi-monitor support (Windows)
443
539
  - ✅ Always on top mode
444
- - ✅ Zoom control (initial percent + runtime Ctrl+Wheel/+/-)
445
- - ✅ Auto-sizing windows (fit content when size not specified)
446
- - ✅ Keyboard shortcuts (Enter, Escape, F11)
447
- - ✅ Window close detection
448
- - ✅ Detached process mode (independent window)
449
- - ✅ Fullscreen mode with F11 toggle
540
+ - ✅ Zoom control
541
+ - ✅ Fullscreen mode
450
542
  - ✅ TypeScript type definitions
451
- - ✅ Small binary size (~2-5MB per platform)
452
- - ✅ Fast startup (~50-200ms)
453
- - ✅ Low memory usage (~20-50MB)
543
+ - ✅ Keyboard shortcuts (Enter, Escape, F11)
454
544
 
455
- ## Performance Comparison
545
+ ## Why msger?
456
546
 
457
- | | **Electron (msgview)** | **Rust (msger)** | **Improvement** |
458
- |---|---|---|---|
459
- | **Binary Size** | ~100MB | ~1-2MB per platform | **50-100x smaller** |
460
- | **Startup Time** | ~2-3 seconds | ~50-200ms | **10-20x faster** |
461
- | **Memory Usage** | ~100-200MB | ~20-50MB | **3-5x less** |
462
- | **Cross-Platform** | ✅ Win/Mac/Linux | ✅ Win/Linux x64/ARM64 | Similar |
463
- | **Full HTML/CSS** | ✅ Chromium | ✅ WebView2/WebKit | Same |
464
- | **URL Loading** | ✅ | ✅ | Same |
547
+ - **Fast** - Opens in under 200ms
548
+ - **Small** - Only a few MB installed
549
+ - **Simple** - Easy Promise-based API
550
+ - **Flexible** - Plain text, HTML, or load URLs
551
+ - **Cross-platform** - Works on Windows and Linux
465
552
 
466
- ## CLI Options
553
+ For technical details and performance metrics, see [DEVELOPERS.md](DEVELOPERS.md).
467
554
 
468
- ```
469
- Usage: msger [options] [message words...]
555
+ ---
470
556
 
471
- Options:
472
- -message, --message <text> Plain text message
473
- -title, --title <text> Window title
474
- -html, --html <html> HTML content
475
- -url, --url <url> URL to load (web or file://)
476
- -buttons, --buttons <labels> Button labels (e.g., -buttons Yes No Cancel)
477
- -ok, --ok Add OK button
478
- -cancel, --cancel Add Cancel button
479
- -input, --input [placeholder] Include input field with optional placeholder text
480
- -default, --default <text> Default value for input field
481
- -size, --size <width,height> Window size (e.g., -size 800,600)
482
- -pos, --pos <x,y> Window position (e.g., -pos 100,200)
483
- -screen, --screen <number> [Windows only] Screen index (0=primary, 1=second, etc.)
484
- -zoom, --zoom <percent> Zoom level as percentage (e.g., -zoom 150 for 150%)
485
- -timeout, --timeout <seconds> Auto-close after specified seconds
486
- -ontop, --ontop Keep window always on top
487
- -detach, --detach Launch window independently (parent returns immediately)
488
- -fullscreen, --fullscreen Start window in fullscreen mode (F11 to toggle, Escape to exit)
489
- -debug, --debug Return debug info (HTML, size, autoSize) in result
490
- -v, -version, --version Show version number
491
- -help, -?, --help Show help message
492
-
493
- Examples:
494
- msger Hello World
495
- msger -message "Save changes?" -buttons Yes No Cancel
496
- msger -message "Enter your name:" -input "Your name" -default "John Doe"
497
- msger -html "<h1>Title</h1><p>Formatted <b>content</b></p>"
498
- msger -html "<span style='color:red;background-color:yellow'>Colored text</span>"
499
- msger -url "https://example.com"
500
- msger -url "https://example.com" -detach
501
- msger -title "Alert" -message "Operation complete"
502
- msger -message "Positioned" -pos 100,100 -screen 1
503
- msger -message "Large text" -zoom 150 -ontop
504
-
505
- Notes:
506
- - If no options provided, all non-option arguments are concatenated as message
507
- - Press ESC to dismiss (returns button: "dismissed")
508
- - Press Enter to click last (default) button
509
- - OK button is green by default
510
- - URLs default to 1024x768 window size
511
- - Windows auto-size to fit content when size not specified
512
- - Runtime zoom: Ctrl+Wheel, Ctrl+Plus, Ctrl+Minus
513
- ```
557
+ # Additional Information
514
558
 
515
559
  ## Important Notes
516
560
 
@@ -518,10 +562,6 @@ Notes:
518
562
 
519
563
  ⚠️ **msger is designed for displaying trusted, friendly content** (local apps, your HTML files). It is NOT a secure sandbox for untrusted/hostile web content. Use `-htmlfrom` and `-url` with trusted sources only.
520
564
 
521
- ### Technical Details & Known Issues
522
-
523
- For detailed technical information, known limitations, current status, and planned features, see [TODO.md](TODO.md).
524
-
525
565
  ### msger JavaScript API
526
566
 
527
567
  **Minimal API** - Most functionality uses native browser APIs:
@@ -530,6 +570,12 @@ For detailed technical information, known limitations, current status, and plann
530
570
 
531
571
  **Recommendation:** Use native browser APIs (`localStorage`, `window.close()`) for compatibility. Code will work in any browser context, not just msger.
532
572
 
573
+ ## For Developers
574
+
575
+ - **Building & Architecture**: See [DEVELOPERS.md](DEVELOPERS.md)
576
+ - **Technical Status & Roadmap**: See [TODO.md](TODO.md)
577
+ - **Native Binary Documentation**: See [msger-native/README.md](msger-native/README.md)
578
+
533
579
  ## License
534
580
 
535
581
  ISC
Binary file
@@ -1,8 +1,10 @@
1
1
  {
2
2
  "title": "Example Message Box",
3
3
  "message": "This is a sample message box configuration.\n\nYou can override any of these settings via command-line arguments.",
4
- "width": 600,
5
- "height": 400,
4
+ "size": {
5
+ "width": 600,
6
+ "height": 400
7
+ },
6
8
  "pos": {
7
9
  "x": 100,
8
10
  "y": 100,
@@ -166,6 +166,13 @@ struct Position {
166
166
  screen: Option<i32>,
167
167
  }
168
168
 
169
+ #[derive(Deserialize, Debug)]
170
+ #[serde(rename_all = "camelCase")]
171
+ struct Size {
172
+ width: i32,
173
+ height: i32,
174
+ }
175
+
169
176
  #[derive(Deserialize, Debug)]
170
177
  #[serde(rename_all = "camelCase")]
171
178
  struct MessageBoxOptions {
@@ -177,8 +184,13 @@ struct MessageBoxOptions {
177
184
  html: Option<String>,
178
185
  #[serde(default)]
179
186
  url: Option<String>,
187
+ // New size object (preferred)
188
+ #[serde(default)]
189
+ size: Option<Size>,
190
+ // Deprecated: use size.width instead
180
191
  #[serde(default = "default_width")]
181
192
  width: i32,
193
+ // Deprecated: use size.height instead
182
194
  #[serde(default = "default_height")]
183
195
  height: i32,
184
196
  #[serde(default)]
@@ -358,11 +370,21 @@ fn merge_cli_with_options(cli: &Cli, mut options: MessageBoxOptions) -> MessageB
358
370
  if let Some(ref url) = cli.url {
359
371
  options.url = Some(url.clone());
360
372
  }
361
- if let Some(width) = cli.width {
362
- options.width = width;
363
- }
364
- if let Some(height) = cli.height {
365
- options.height = height;
373
+
374
+ // Handle size - if CLI provides width or height, update both old fields and size object
375
+ if cli.width.is_some() || cli.height.is_some() {
376
+ let existing_size = options.size.take().unwrap_or(Size {
377
+ width: options.width,
378
+ height: options.height,
379
+ });
380
+ let new_size = Size {
381
+ width: cli.width.unwrap_or(existing_size.width),
382
+ height: cli.height.unwrap_or(existing_size.height),
383
+ };
384
+ // Update both for backward compatibility
385
+ options.width = new_size.width;
386
+ options.height = new_size.height;
387
+ options.size = Some(new_size);
366
388
  }
367
389
 
368
390
  // Handle position
@@ -504,6 +526,13 @@ fn main() {
504
526
  None
505
527
  };
506
528
 
529
+ // Determine final width and height (size object takes precedence over individual width/height)
530
+ let (final_width, final_height) = if let Some(ref size) = options.size {
531
+ (size.width, size.height)
532
+ } else {
533
+ (options.width, options.height)
534
+ };
535
+
507
536
  // Load window icon (default or custom)
508
537
  let icon = if let Some(ref icon_path) = options.icon {
509
538
  load_icon(icon_path)
@@ -515,8 +544,8 @@ fn main() {
515
544
  let mut window_builder = WindowBuilder::new()
516
545
  .with_title(&options.title)
517
546
  .with_inner_size(tao::dpi::LogicalSize::new(
518
- options.width as f64,
519
- options.height as f64,
547
+ final_width as f64,
548
+ final_height as f64,
520
549
  ))
521
550
  .with_resizable(true)
522
551
  .with_always_on_top(options.always_on_top);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bobfrankston/msger",
3
- "version": "0.1.80",
3
+ "version": "0.1.82",
4
4
  "description": "Fast, lightweight, cross-platform message box - Rust-powered alternative to msgview",
5
5
  "type": "module",
6
6
  "main": "./index.js",