# Reference: Himalaya Setup on ZimaOS / CasaOS

Session: 2026-05-07 — Hermes Agent onboarding on ZimaOS Linux.

## Environment Context

- Hermes runs in a CasaOS-managed container on ZimaOS (Linux x86_64).
- `$HOME` resolves to `/DATA` (not `/home/$USER`), so standard `~/.local/bin` and `~/.config/` paths may fail with permission errors.
- The Hermes agent home is at `/DATA/AppData/hermes/` — this is the reliable base for configs and binaries.
- `mkdir`/`chmod` shell commands may fail inside sandboxed execution; prefer Python `os.makedirs()` and `os.chmod()`.

## Binary Installation

The Himalaya install script expects `PREFIX=~/.local` and uses `mkdir`, which fails on ZimaOS because `~` is `/DATA` and owned by root. Use direct GitHub release download instead.

### Finding the correct release URL

```python
# Query GitHub API for release assets
import urllib.request, json
req = urllib.request.Request("https://api.github.com/repos/pimalaya/himalaya/releases/latest")
with urllib.request.urlopen(req, timeout=10) as resp:
    data = json.loads(resp.read().decode())
    for asset in data.get("assets",[]):
        print(asset["browser_download_url"])
```

For x86_64 Linux the file is named: `himalaya.x86_64-linux.tgz` (NOT `.tar.gz`).

### Installation steps

```bash
cd /tmp
curl -sL -o himalaya.tgz 'https://github.com/pimalaya/himalaya/releases/download/v1.2.0/himalaya.x86_64-linux.tgz'
tar -xzf himalaya.tgz
cp himalaya /DATA/AppData/hermes/bin/
chmod +x /DATA/AppData/hermes/bin/himalaya
```

## Configuration

### Config location

Do NOT use `~/.config/himalaya/` — permission denied. Instead:
- Config: `/DATA/AppData/hermes/himalaya.toml`
- Set env var: `HIMALAYA_CONFIG=/DATA/AppData/hermes/himalaya.toml`

### Password security pattern

Store credentials in a `.env` file with `chmod 600`, then reference it via `auth.cmd` using `grep | cut` so the password is never in the TOML file:

```toml
backend.auth.type = "password"
backend.auth.cmd = "cat /DATA/AppData/.secrets/gmx_email.env | grep GMX_PASSWORD | cut -d= -f2 | tr -d '\\n'"
```

The same pattern applies to SMTP send auth.

### Full working config example (GMX)

```toml
[accounts.gmx]
email = "amadeus.bot@gmx.at"
display-name = "Kiwi"
default = true

backend.type = "imap"
backend.host = "imap.gmx.net"
backend.port = 993
backend.encryption.type = "tls"
backend.login = "amadeus.bot@gmx.at"
backend.auth.type = "password"
backend.auth.cmd = "cat /DATA/AppData/.secrets/gmx_email.env | grep GMX_PASSWORD | cut -d= -f2 | tr -d '\\n'"

message.send.backend.type = "smtp"
message.send.backend.host = "mail.gmx.net"
message.send.backend.port = 587
message.send.backend.encryption.type = "start-tls"
message.send.backend.login = "amadeus.bot@gmx.at"
message.send.backend.auth.type = "password"
message.send.backend.auth.cmd = "cat /DATA/AppData/.secrets/gmx_email.env | grep GMX_PASSWORD | cut -d= -f2 | tr -d '\\n'"

folder.aliases.inbox = "INBOX"
folder.aliases.sent = "Sent"
folder.aliases.drafts = "Drafts"
folder.aliases.trash = "Trash"
```

## Running Himalaya via Python subprocess

Since shell commands may have restricted PATH or missing basic utilities, spawn Himalaya via Python:

```python
import subprocess, os

himalaya_path = "/DATA/AppData/hermes/bin/himalaya"
env = os.environ.copy()
env["HIMALAYA_CONFIG"] = "/DATA/AppData/hermes/himalaya.toml"

result = subprocess.run(
    [himalaya_path, "envelope", "list", "--output", "plain"],
    capture_output=True, text=True, timeout=15, env=env
)
print(result.stdout)
```

## Pitfalls

1. **Wrong filename extension:** Releases use `.tgz` not `.tar.gz`.
2. **Permission denied on `~/.config`:** ZimaOS `/DATA` is root-owned. Always fall back to `/DATA/AppData/hermes/` for configs.
3. **Missing `$EDITOR` for interactive compose:** Non-interactive piped input (`himalaya template send`) is the reliable approach in headless/agent environments.
4. **GMX specifics:** IMAP host is `imap.gmx.net:993`, SMTP is `mail.gmx.net:587` (start-tls). GMX sometimes flags automated connections; monitor for auth failures.
5. **Shell `mkdir`/`chmod` may fail inside sandbox:** Use Python `os.makedirs(..., exist_ok=True)` and `os.chmod(..., 0o600)` instead.
