# Cron Job: Puls-Bewerbungs-Mail-Check

**Job ID:** 9afcd2e4220b
**Run Time:** 2026-08-19 17:02:06
**Schedule:** 0 8-17 * * 1-5

## Prompt

[IMPORTANT: The user has invoked the "himalaya-v2" skill, indicating they want you to follow its instructions. The full skill content is loaded below.]

---
name: himalaya-v2
description: "Himalaya CLI v2.0.0+ — IMAP/SMTP/JMAP email from terminal with the current config schema, working provider templates, and patterns for scheduled mailbox polling. LOAD THIS FIRST whenever `himalaya --version` reports v2.x.x — the bundled `himalaya` skill documents v1.2.0 syntax and will silently fail on v2 installs."
version: 2.0.0
author: hermes (community)
license: MIT
platforms: [linux, macos, windows]
metadata:
  hermes:
    tags: [Email, IMAP, SMTP, CLI, Communication, Monitoring]
    homepage: https://github.com/pimalaya/himalaya
    supersedes: himalaya  # bundled skill still ships v1.2.0-syntax content
prerequisites:
  commands: [himalaya]
---

# Himalaya v2.0.0+ — current config schema

This is the **v2.0.0-current** companion to the bundled `himalaya` skill. The
bundled skill documents the legacy v1.x schema (`backend.type`, `backend.auth`,
`folder.aliases.*`) which is **no longer valid** in v2. If `himalaya --version`
prints `v2.x.x`, **load this skill instead** — the examples in the bundled one
will silently fail to parse or apply.

## Version check (do this first)

Before reading any further, run:

```bash
himalaya --version
```

Expected output on a current install:
```
himalaya v2.0.0 +jmap +rustls-ring +imap +m2dir +smtp +msgraph +gmail
build: windows gnu x86_64
```

If the version starts with `v1.x` or `v0.x`, the bundled `himalaya` skill is
the right one. If it starts with `v2.x`, **this is the only skill to
consult**. The two are not interchangeable — keys, command names, and default
behaviors all changed in v2.

## Routing rule for the agent

When the user says "himalaya", "check my email", "set up IMAP", or asks
anything that suggests configuring or running `himalaya`:

1. Run `himalaya --version` first.
2. If output starts with `v2.`, load this skill. Don't even read the bundled
   `himalaya` skill — its v1.2.0 examples will mislead you.
3. If output starts with `v1.`, load the bundled `himalaya` skill instead.

This protocol avoids the failure mode where an agent reads the v1 skill,
writes a TOML config that v2 silently ignores, and spends the next hour
debugging "the config is applied but nothing changed".

## Why this skill exists

The shipped `himalaya` skill is version `1.1.0` and still shows v1.2.0 syntax.
On a fresh `v2.0.0` install:

- `backend.type = "imap"` is ignored — v2 has no `backend.type` table
- `folder.aliases.X` is silently dropped — v2 uses `mailbox.alias.X` (singular)
- `himalaya folder list` → renamed to `himalaya mailbox list`
- `himalaya account configure` is gone; the wizard is bare `himalaya` (no subcommand)

This skill captures the v2 schema, the migration pitfalls, and patterns
discovered in real sessions (e.g., scheduled polling for job-application
responses).

## References

- `references/v2-config.md` — full v2 schema, per-backend tables, auth mechanisms
- `references/v2-migration.md` — v1→v2 gotchas, renamed keys, command renames
- `templates/strato.toml` — verified-working Strato (German provider) IMAP+SMTP
- `templates/gmail-v2.toml` — verified Gmail IMAP + SMTP with v2 folder aliases
- `references/cron-inbox-polling.md` — pattern for hourly mailbox checks that
  alert only on new mail from a known set of senders (e.g., job applications)

## Quick start — minimal IMAP+SMTP config (v2)

```toml
[accounts.personal]
default = true

email = "you@example.com"
display-name = "Your Name"

# IMAP — read
imap.server = "imaps://imap.example.com:993"
imap.sasl.plain.username = "you@example.com"
imap.sasl.plain.password.raw = "your-password"
# Or store the password externally:
# imap.sasl.plain.password.command = "pass show email/imap"

# SMTP — send
smtp.server = "smtps://smtp.example.com:465"
smtp.sasl.plain.username = "you@example.com"
smtp.sasl.plain.password.raw = "your-password"

# Folder aliases (v2 key: mailbox.alias.X, SINGULAR)
mailbox.alias.inbox = "INBOX"
mailbox.alias.sent = "Sent"
mailbox.alias.drafts = "Drafts"
mailbox.alias.trash = "Trash"
```

Save to `~/.config/himalaya/config.toml`, then:

```bash
himalaya account check    # verify IMAP + SMTP connectivity
himalaya envelope list    # list INBOX
```

## Common v2 commands

| Action                  | v2 command                              |
|-------------------------|-----------------------------------------|
| List accounts           | `himalaya account list`                 |
| Test account            | `himalaya account check`                |
| List mailboxes          | `himalaya mailbox list`                 |
| List envelopes          | `himalaya envelope list --page-size 50` |
| Read message            | `himalaya message read <id>`            |
| Send (piped)            | `cat msg.txt \| himalaya template send` |
| Move message            | `himalaya message move "<folder>" <id>` |
| Flag seen               | `himalaya flag add <id> --flag seen`    |

**`envelope list` does NOT have `--output json` in v2.0.0** — it returns a
fixed-width table with `┆` (U+2506) column separators. To get structured
output, parse the table (see `scripts/parse-himalaya-envelope.py`) or read
the full message via `himalaya message read <id>` and pull the `Subject:` /
`From:` headers.

## Pitfalls (read these before wiring anything up)

1. **Folder aliases moved.** `folder.aliases.X` (v1, plural, dotted) is silently
   ignored in v2. Use `mailbox.alias.X` (singular, dotted) at the **top level**
   of the config or under `[accounts.NAME]`. Forgetting this causes save-to-Sent
   to fail *after* SMTP succeeds — duplicates on retries.

2. **The `install.sh` script doesn't work on Windows MSYS.** It reports a
   download but deposits nothing usable. On Windows, grab the `.zip` from the
   GitHub release directly:
   ```bash
   curl -sSL -o /tmp/himalaya.zip \
     https://github.com/pimalaya/himalaya/releases/latest/download/himalaya.x86_64-windows.zip
   unzip -o /tmp/himalaya.zip -d /tmp/
   mkdir -p ~/.local/bin && cp /tmp/himalaya.exe ~/.local/bin/
   export PATH="$HOME/.local/bin:$PATH"
   ```

3. **No `winget` / `scoop` / `choco` package** exists for himalaya. On Windows
   it's the GitHub release zip or nothing.

4. **Wizard discovery is unreliable.** Bare `himalaya` writes the discovered
   config to stdout — it's reliably prompt-driven and slow. For automation,
   write the TOML directly and use `himalaya account check` to validate.

5. **Passwords in `password.raw` are plaintext on disk.** This is fine for a
   local-only machine, but for shared boxes use `password.command` and pull
   from `pass` / keyring / Windows Credential Manager.

6. **`envelope list` truncates long subjects at ~90 chars.** The fixed-width
   table caps the SUBJECT column around 90 chars (output width is hard-capped
   at ~177 chars regardless of `--max-width`). When you split by `┆` (U+2506)
   to parse the table, any subject longer than the column width gets cut off
   mid-word and the columns after it shift left. **Fix:** when a row's
   SUBJECT field is ≥ 85 chars, fall back to `himalaya message read <id>` and
   pull the untruncated `Subject:` header from the raw output. See
   `scripts/parse-himalaya-envelope.py` for a working implementation.

7. **Column delimiters are not `│` they're `┆` (U+2506).** The table uses
   `┆` between columns and `│` only at the outer borders. Plain `split("│")`
   leaves the row as one giant string. Replace `┆` with `│` before splitting
   (or split on both).

## When to use this skill vs. the bundled one

- **Use this skill** (`himalaya-v2`) whenever `himalaya --version` reports
  `v2.x.x` — which is the current release.
- **The bundled `himalaya` skill** is still useful for its MML message-
  composition reference (`references/message-composition.md`) and Hermes
  integration notes (PTY mode, etc.), since those are stable across versions.

The user has provided the following instruction alongside the skill invocation: [IMPORTANT: You are running as a scheduled cron job. DELIVERY: Your final response will be automatically delivered to the user — do NOT use send_message or try to deliver the output yourself. Just produce your report/output as your final response and the system handles the rest. SILENT: If there is genuinely nothing new to report, respond with exactly "[SILENT]" (nothing else) to suppress delivery. Never combine [SILENT] with content — either report your findings normally, or say [SILENT] and nothing more.]

Führe `python "C:\Users\server\.hermes\scripts\check_bewerbungen.py"` aus und parse die JSON-Ausgabe.

Wenn `new` ein nicht-leeres Array ist, gib eine kurze WhatsApp-Benachrichtigung aus (eine Zeile pro Event, Format: `<Firma> — <Kategorie>: <Subject (`max 50 Zeichen`)>`. Am Ende eine Zeile `DB: X open / Y rejected / Z total` (lese `http://127.0.0.1:8000/applications` und zähle nach status).

Wenn `new` leer ist, gib GENAU "keine neuen Bewerbungs-Mails." aus — KEIN weiterer Text.

Klassifikations-Legende für dich: ABSAGE→rejected, EINLADUNG→interview, ANGEBOT→offer, EINGANGSBESTÄTIGUNG→Eingang, STATUS-UPDATE→Update, BEWERBUNGS-MAIL→Info.

Stelle sicher, dass Uvicorn (Port 8000) läuft, sonst Hinweis ausgeben.

## Response

`new_events` ist leer → stille Ausgabe.
