# Wrapper Script Design

Technical documentation for syntaxis wrapper scripts.

## Overview

Wrapper scripts are NuShell scripts created during installation that provide intelligent configuration discovery and environment setup for workspace binaries.

### Goals

1. **Automatic config discovery** - Find configuration files without user intervention
2. **Environment setup** - Set required environment variables before execution
3. **Transparency** - User sees no difference between wrapper and binary
4. **Flexibility** - Support multiple config file locations
5. **Debugging** - Easy to inspect what's happening

## Architecture

### Binary Layout After Installation

```
~/.cargo/bin/
├── workspace              # Wrapper script (NuShell)
├── workspace.real         # Actual binary (compiled executable)
├── syntaxis-tui          # Wrapper script (NuShell)
├── syntaxis-tui.real     # Actual binary (compiled executable)
└── syntaxis-dashboard    # Actual binary (no wrapper, runs standalone)
```

### Wrapper Script Flow

```
User executes: workspace --help
       ↓
NuShell wrapper script (workspace)
       ↓
1. Search for config file in priority order
       ↓
2. If found: Set WORKSPACE_CONFIG_PATH
       ↓
3. Set other environment variables:
   - WORKSPACE_CONFIG_DIR
   - WORKSPACE_DATA_DIR
       ↓
4. Create data directory if needed
       ↓
5. Execute actual binary (workspace.real)
       ↓
Binary executes with environment setup
```

## Configuration Discovery

### Search Order

Wrapper scripts search for configuration files in this priority order:

```
1. ~/.config/core/workspace.toml
   └─ User configuration

2. ~/.config/core/syntaxis-api.toml
   └─ Fallback to main API config

3. .project/workspace.toml
   └─ Project-specific configuration

4. .vapora/workspace.toml
   └─ VAPORA-specific configuration
```

Returns first matching file, or `null` if none found.

### Configuration Discovery Logic

```nushell
let config_paths = [
    $"($env.HOME)/.config/core/workspace.toml"
    $"($env.HOME)/.config/core/syntaxis-api.toml"
    ".project/workspace.toml"
    ".vapora/workspace.toml"
]

let config_file = (
    $config_paths
    | where { |p| $p | path exists }
    | first
)
```

This ensures:
- User configs are tried first
- Fallback to shared config if specific config not found
- Project configs override user configs
- VAPORA configs are respected
- If no config found, `config_file` is `null`

## Environment Variables

### Set by Wrapper

Wrapper scripts set these environment variables before execution:

| Variable | Purpose | Example |
|----------|---------|---------|
| `WORKSPACE_CONFIG_PATH` | Absolute path to found config file | `~/.config/core/workspace.toml` |
| `WORKSPACE_CONFIG_DIR` | Configuration directory | `~/.config/syntaxis` |
| `WORKSPACE_DATA_DIR` | Runtime data directory | `~/.local/share/syntaxis` |

### Read by Application

The workspace binary reads these variables:

```rust
// In Rust code
let config_path = std::env::var("WORKSPACE_CONFIG_PATH").ok();
let config_dir = std::env::var("WORKSPACE_CONFIG_DIR").ok();
let data_dir = std::env::var("WORKSPACE_DATA_DIR").ok();
```

The binary will:
1. Use `WORKSPACE_CONFIG_PATH` if set (from wrapper)
2. Search in `WORKSPACE_CONFIG_DIR` if set
3. Fall back to default locations if neither set
4. Create `WORKSPACE_DATA_DIR` if it doesn't exist

## Wrapper Script Implementation

### workspace wrapper script location

`~/.cargo/bin/workspace` (or wherever cargo/bin is)

### Full Wrapper Script Example

```nushell
#!/usr/bin/env nu
# Generated wrapper for workspace
# Automatically finds configuration and sets up environment

# Find configuration file in standard locations
let config_paths = [
    $"($env.HOME)/.config/core/workspace.toml"
    $"($env.HOME)/.config/core/syntaxis-api.toml"
    ".project/workspace.toml"
    ".vapora/workspace.toml"
]

let config_file = (
    $config_paths
    | where { |p| $p | path exists }
    | first
)

# Setup environment variables
if ($config_file != null) {
    $env.WORKSPACE_CONFIG_PATH = $config_file
}

$env.WORKSPACE_CONFIG_DIR = $"($env.HOME)/.config/syntaxis"
$env.WORKSPACE_DATA_DIR = $"($env.HOME)/.local/share/syntaxis"

# Create data directory if needed
^mkdir -p $env.WORKSPACE_DATA_DIR

# Call actual binary with all arguments
^~/.cargo/bin/workspace.real
```

### Key Design Decisions

1. **NuShell as wrapper language**
   - Reason: Already used in project build system
   - Advantage: Native path handling, string interpolation
   - Consistency: All scripts use same language

2. **Search before setting variables**
   - Reason: Only set `WORKSPACE_CONFIG_PATH` if config actually exists
   - Advantage: Clear separation of concerns
   - Benefit: Application can detect which config was used

3. **Always set `WORKSPACE_CONFIG_DIR` and `WORKSPACE_DATA_DIR`**
   - Reason: Application needs these for fallback behavior
   - Advantage: Consistent environment across all invocations
   - Benefit: Predictable runtime behavior

4. **Create data directory automatically**
   - Reason: Application might not have write permission to create
   - Advantage: Fails fast if permission issues
   - Benefit: Cleaner error messages

5. **Pass all arguments through**
   - Reason: Transparent to user
   - Advantage: No argument parsing needed in wrapper
   - Method: Shell directly executes real binary (arguments auto-passed)

## Binary Renaming Strategy

### Why Rename?

Renaming actual binaries to `.real` suffix:
1. **Clarity** - Easy to see which files are wrappers vs. actual binaries
2. **Safety** - Prevents accidental execution of wrong file
3. **Maintenance** - Can easily identify wrapped binaries
4. **Reversibility** - Can restore by removing wrappers

### Renaming Process

```nushell
def create_wrappers [] {
    let cargo_bin = ($env.HOME + "/.cargo/bin")
    let binaries = ["workspace" "syntaxis-tui"]

    for binary in $binaries {
        let binary_path = ($cargo_bin + "/" + $binary)
        let real_binary_path = ($cargo_bin + "/" + $binary + ".real")

        if ($binary_path | path exists) {
            ^mv $binary_path $real_binary_path
            # Now create wrapper script at original location
        }
    }
}
```

Results:
```
Before:  ~/.cargo/bin/workspace (executable binary)
After:   ~/.cargo/bin/workspace.real (actual binary)
         ~/.cargo/bin/workspace (wrapper script)
```

## Installation Integration

### Creation During Installation

The `install_binary()` function:
1. Compiles binary with `cargo install`
2. Creates wrapper script via `create_wrapper_script()`
3. Renames binary to `.real` via `create_wrappers()`
4. Registers in manifest via `register_installations()`

### Manifest Tracking

Wrapper creation is tracked in `.syntaxis/manifest.toml`:

```toml
[binaries.workspace]
installed = true
wrapper = true                          # ← Indicates wrapper created
path = "~/.cargo/bin/workspace"         # ← Wrapper location
real_binary = "~/.cargo/bin/workspace.real"  # ← Real binary location
```

## Debugging Wrappers

### Inspect Wrapper Script

```bash
cat ~/.cargo/bin/workspace
```

Shows exact config discovery logic and environment setup.

### Trace Execution

Add debug output to see what's happening:

```nushell
# Modify wrapper to add debugging
let config_file = (
    $config_paths
    | where { |p| $p | path exists }
    | first
)

print -e $"Found config: ($config_file)"  # ← Add this line
print -e $"Config dir: ($env.WORKSPACE_CONFIG_DIR)"
print -e $"Data dir: ($env.WORKSPACE_DATA_DIR)"

^~/.cargo/bin/workspace.real
```

### Check Environment

```bash
# See what environment wrapper sets
strace -e execve ~/.cargo/bin/workspace --help 2>&1 | grep execve

# Or use nu debugging
nu -c 'source ~/.cargo/bin/workspace; print $env'
```

### Test Config Discovery

```bash
# Create test wrapper
cat > /tmp/test_wrapper.nu << 'EOF'
#!/usr/bin/env nu

let config_paths = [
    $"($env.HOME)/.config/core/workspace.toml"
    $"($env.HOME)/.config/core/syntaxis-api.toml"
    ".project/workspace.toml"
    ".vapora/workspace.toml"
]

let config_file = (
    $config_paths
    | where { |p| $p | path exists }
    | first
)

print $"Found config: ($config_file)"
EOF

# Run test
nu /tmp/test_wrapper.nu
```

## Performance Considerations

### Startup Overhead

Wrapper adds minimal overhead:
1. NuShell startup: ~10-50ms
2. Config search: ~0-5ms (depends on number of existing config files)
3. Directory creation: ~1-2ms
4. Total: ~15-60ms (negligible for CLI tools)

### Optimization Opportunities

If performance becomes critical:

1. **Cache config file location**
   ```nushell
   # Store found path in environment for child processes
   $env.WORKSPACE_CONFIG_FOUND = $config_file
   ```

2. **Short-circuit search**
   ```nushell
   # Stop searching after first find
   if ($"($env.HOME)/.config/core/workspace.toml" | path exists) {
       # Use this, don't check others
   }
   ```

3. **Skip directory creation**
   ```nushell
   # Only create if needed (check first)
   if not ($env.WORKSPACE_DATA_DIR | path exists) {
       ^mkdir -p $env.WORKSPACE_DATA_DIR
   }
   ```

## Troubleshooting Guide

### Wrapper Not Found

**Problem**: `command not found: workspace`

**Solutions**:
1. Check PATH: `echo $PATH | grep .cargo/bin`
2. Verify installation: `ls -la ~/.cargo/bin/workspace*`
3. Check permissions: `ls -l ~/.cargo/bin/workspace`
4. Re-install: `just scripts-install workspace`

### Config Not Loading

**Problem**: Binary doesn't see configuration

**Solutions**:
1. Verify config exists: `ls ~/.config/core/workspace.toml`
2. Check wrapper sees it: `cat ~/.cargo/bin/workspace | grep config_paths`
3. Add debugging to wrapper (see Debugging section)
4. Check environment: `env | grep WORKSPACE`

### Permission Denied

**Problem**: `permission denied: ~/.cargo/bin/workspace`

**Solutions**:
1. Check permissions: `ls -l ~/.cargo/bin/workspace`
2. Make executable: `chmod +x ~/.cargo/bin/workspace`
3. Re-install: `just scripts-install workspace`

### Wrong Binary Executed

**Problem**: `.real` binary being called instead of wrapper

**Solutions**:
1. Check file order: `ls -la ~/.cargo/bin/workspace*`
2. Verify PATH order: `which workspace`
3. Clear PATH cache: `hash -r` (bash) or `rehash` (zsh)
4. Use full path: `~/.cargo/bin/workspace --help`

## Future Improvements

### Version 1.1

1. **Config file caching** - Cache found path to reduce startup time
2. **Wrapper updates** - Auto-update wrappers when configs change
3. **Enhanced debugging** - Built-in debug mode via `--debug` flag
4. **Config merging** - Merge multiple config files for inheritance

### Version 2.0

1. **Binary shims** - Replace NuShell wrappers with compiled shims (faster)
2. **Config templating** - Jinja2-style variable substitution in configs
3. **Hot reload** - Reload configs without restarting application
4. **Remote configs** - Load configs from remote servers

## Related Documentation

- **docs/installation-guide.md** - How to install wrappers
- **docs/configuration.md** - Configuration file options
- **scripts/install-cli.nu** - Wrapper creation implementation
