# msger - Developer Guide

This document contains technical information for developers working on msger.

## Architecture

```
@bobfrankston/msger (TypeScript wrapper)
    ↓ spawns native binary with JSON via stdin OR file + CLI args
@bobfrankston/msger-native (Rust binary - platform-specific)
    ↓ creates native window with webview
    ↓ displays HTML/URL content with buttons
    ↓ outputs JSON result to stdout
TypeScript wrapper returns Promise<MessageBoxResult>
```

**Platform-specific binaries:**
- `msgernative.exe` - Windows x64 (WebView2)
- `msgernative` - Linux x86_64 (WebKitGTK)
- `msgernative-arm64` - Linux ARM64/Raspberry Pi (WebKitGTK)

The correct binary is automatically selected based on `process.platform` and `process.arch`.

## Building from Source

### Prerequisites

- **Rust** (install from https://rustup.rs/)
- **Node.js** (v16 or later)
- **Windows**: Visual Studio Build Tools with C++ development tools
- **macOS**: Xcode Command Line Tools
- **Linux**: WebKitGTK development packages

### Build Commands

```bash
# Build everything (TypeScript + all native binaries)
npm run build

# Build only TypeScript wrapper
npm run build:ts

# Build Windows binary
npm run build:native

# Build Linux x64 binary (via WSL)
npm run build:native:wsl

# Build ARM64 binary (via SSH to Raspberry Pi)
npm run build:native:pi

# Build all native binaries
npm run build:native:all

# Watch mode for TypeScript development
npm run watch
```

### Building ARM64 Binary

To build the ARM64 binary for Raspberry Pi:

1. Update `PI_HOST` in `msger-native/build-pi.ts` with your Pi's hostname/IP
2. Ensure SSH keys are set up: `ssh-copy-id pi@your-pi`
3. Run: `npm run build:native:pi`

The script will automatically:
- Copy source files to the Pi via SSH
- Install Rust and build dependencies if needed
- Build the binary on the Pi
- Copy the binary back to your development machine

### Manual Rust Build

If you prefer to build the Rust binary manually:

```bash
cd msger-native

# Debug build (faster compile, larger binary)
cargo build

# Release build (optimized, smaller binary)
cargo build --release
```

**Note**: If you encounter linker errors on Windows, make sure Visual Studio Build Tools with C++ workload is installed.

### Cross-Platform Builds

```bash
# Windows
cargo build --release --target x86_64-pc-windows-msvc

# Linux (from Linux or WSL)
cargo build --release --target x86_64-unknown-linux-gnu

# macOS (requires macOS or CI)
cargo build --release --target x86_64-apple-darwin
cargo build --release --target aarch64-apple-darwin  # Apple Silicon
```

## Project Structure

The project consists of two parts:

1. **`msger-native/`** - Rust binary (subdirectory with its own Cargo.toml)
   - `src/main.rs` - Main application logic
   - `src/msger-api.js` - JavaScript API injected into webviews
   - `src/template.html` - HTML template for message boxes
   - `bin/` - Compiled binaries for distribution
   - `README.md` - Rust-specific documentation

2. **Root directory** - TypeScript wrapper and npm package
   - TypeScript wrapper for Node.js API
   - CLI interface
   - Build scripts

When you run `npm run build`, it:
1. Builds platform-specific Rust binaries
2. Copies binaries to `msger-native/bin/`
3. Compiles TypeScript to JavaScript

All binaries are bundled with the npm package, and the correct one is selected at runtime.

## Dependencies

### Rust (msger-native)

- **wry** (0.47) - Cross-platform webview library
- **tao** (0.30) - Cross-platform windowing
- **serde** / **serde_json** (1.0) - JSON serialization
- **clap** (4.5) - Command-line argument parsing
- **windows** (0.58) - Windows API bindings (Windows only)
- **image** (0.24) - Icon loading

### TypeScript/Node.js

- Standard Node.js APIs for process spawning
- No runtime dependencies

## Design Trade-offs

### Why Rust + WebView instead of Electron?

**Size:**
- Electron: ~100MB bundled app
- msger: ~2-5MB per platform binary
- **50-100x smaller**

**Startup Time:**
- Electron: ~2-3 seconds
- msger: ~50-200ms
- **10-20x faster**

**Memory:**
- Electron: ~100-200MB
- msger: ~20-50MB
- **3-5x less**

**Trade-off:** Platform-specific binaries vs single JavaScript bundle. We chose better performance.

### Why Multiple Binaries?

We ship separate binaries for each platform instead of one universal binary:

**Pros:**
- Smaller download per platform
- Native performance
- No cross-compilation complexity

**Cons:**
- Larger npm package overall
- Need to build on each platform

**Decision:** Better user experience (smaller, faster) outweighs developer complexity.

### Why stdin/stdout JSON instead of native Node.js addon?

**Pros:**
- Platform independence (no native compilation at install time)
- Easy debugging (can test with echo/pipes)
- Clear separation of concerns
- No version compatibility issues

**Cons:**
- Slightly higher overhead (process spawn)
- No shared memory

**Decision:** The 50-200ms startup is fast enough, and JSON is simpler than N-API.

## Testing the Native Binary

### Standalone Tests

```bash
# Simple message
echo '{"message":"Hello from Rust!","buttons":["Cancel","OK"]}' | ./msger-native/bin/msgernative

# With input field
echo '{"message":"Enter your name:","allowInput":true,"defaultValue":"John","buttons":["Cancel","Submit"]}' | ./msger-native/bin/msgernative

# With HTML content
echo '{"title":"Rich Content","html":"<h2>Welcome</h2><p>This is <strong>HTML</strong> content</p>","buttons":["Close"]}' | ./msger-native/bin/msgernative

# JSON file + CLI overrides
./msger-native/bin/msgernative config.json --title "Override Title" --width 800

# Pure CLI
./msger-native/bin/msgernative --message "Hello" --buttons "OK,Cancel" --width 600
```

## Contributing

### Code Style

- **Rust**: Follow standard `rustfmt` style
- **TypeScript**: 4-space indentation, semicolons
- **Comments**: Explain why, not what

### Pull Requests

1. Create a feature branch
2. Make your changes
3. Test on your platform
4. Submit PR with description

### Testing Checklist

Before submitting:
- [ ] Test on Windows (if available)
- [ ] Test on Linux (if available)
- [ ] Test stdin mode
- [ ] Test JSON file mode
- [ ] Test CLI argument mode
- [ ] Test button clicks
- [ ] Test input fields
- [ ] Test HTML content
- [ ] Test URL loading
- [ ] Update documentation

## Performance Comparison

|  | **Electron (msgview)** | **Rust (msger)** | **Improvement** |
|---|---|---|---|
| **Binary Size** | ~100MB | ~1-2MB per platform | **50-100x smaller** |
| **Startup Time** | ~2-3 seconds | ~50-200ms | **10-20x faster** |
| **Memory Usage** | ~100-200MB | ~20-50MB | **3-5x less** |
| **Cross-Platform** | ✅ Win/Mac/Linux | ✅ Win/Linux x64/ARM64 | Similar |
| **Full HTML/CSS** | ✅ Chromium | ✅ WebView2/WebKit | Same |
| **URL Loading** | ✅ | ✅ | Same |

## Technical Documentation

For detailed technical status, known issues, and roadmap, see:
- [TODO.md](TODO.md) - Development roadmap and known issues
- [SESSION-NOTES.md](SESSION-NOTES.md) - Implementation notes and decisions (if available)

## License

ISC

## Author

Bob Frankston
