- Scheme 69.3%
- Shell 23.5%
- Makefile 7%
- Common Lisp 0.2%
|
|
||
|---|---|---|
| .forgejo | ||
| .jerboa | ||
| .jpkg/build | ||
| bin | ||
| docs | ||
| protonmail | ||
| scripts | ||
| support | ||
| test | ||
| .gitignore | ||
| .gitsafeignore | ||
| AGENTS.md | ||
| dependencies.lock | ||
| jpkg.sexp | ||
| LICENSE | ||
| main.ss | ||
| Makefile | ||
| plan.md | ||
| README.md | ||
| SECURITY.md | ||
| VERSION | ||
jerboa-protonmail
Read-only Proton Mail access experiments in Jerboa.
The stable first target is a local IMAP client for Proton Mail Bridge. Bridge
handles Proton authentication, key management, and local decryption; this tool
will initially list folders, list messages, fetch raw messages, decode common
email formats, and export .eml files without mutating mailbox state.
The native direct-Proton track is documented in plan.md, but it is not the
first implementation path.
Current Status
Phase 7 is in progress:
- CLI entry point.
- Environment config helper.
- Bridge IMAP connectivity probe.
- Structured IMAP response parser.
- Folder listing.
- Header-only message listing.
- Raw message fetch.
.emlexport.- Full Bridge folder sync into a local SQLite database.
- Decoded
showoutput throughjerboa-mail. - Search by from, subject, and since.
- Config validation and opt-in integration checks.
- Smoke tests.
- Makefile.
- Project plan.
Live Proton Bridge checks are attempted only when Bridge credentials are set.
Development
make run ARGS='--help'
make doctor
make binary
make test
make release-evidence
make integration-test
bin/protonmail-read doctor
By default the Makefile uses a checked-in ./jerbuild, a local
.jerboa/bin/jerbuild, or a jerbuild on PATH. If no toolchain exists,
make test fetches the pinned Jerboa release into .jerboa/bin.
Override with:
make JERBUILD=/path/to/jerbuild test
Pinned dependencies are fetched from git.jerboa.sh into .deps and verified
against dependencies.lock. Override dependency paths with:
make JERBOA_SSL_DIR=/path/to/jerboa-ssl \
JERBOA_MAIL_DIR=/path/to/jerboa-mail \
JERBOA_SQLITE_DIR=/path/to/jerboa-sqlite \
test
Bridge Configuration
Later phases will read Bridge IMAP settings from environment variables:
export PROTON_BRIDGE_HOST=127.0.0.1
export PROTON_BRIDGE_PORT=1143
export PROTON_BRIDGE_USER='bridge-generated-user'
export PROTON_BRIDGE_PASSWORD='bridge-generated-password'
export PROTON_BRIDGE_TLS=loopback-plain
Use Bridge-generated IMAP credentials, not your Proton account password.
The default transport is tls and certificate or handshake failures are fatal.
Because the common Bridge listener on port 1143 is plaintext, it requires the
explicit mode loopback-plain; that mode accepts only literal 127.0.0.1 or
::1. There is no opportunistic plaintext fallback and DNS names are rejected
for plaintext.
Commands
bin/protonmail-read doctor
bin/protonmail-read folders
bin/protonmail-read list --folder INBOX --limit 20
bin/protonmail-read show --folder INBOX --uid 123
bin/protonmail-read raw --folder INBOX --uid 123 > message.eml
bin/protonmail-read export-eml --folder INBOX --uid 123 --output message.eml
bin/protonmail-read sync-db --db protonmail.sqlite
bin/protonmail-read sync-db --db protonmail.sqlite --folder INBOX
bin/protonmail-read search --folder INBOX --from person@example.com
bin/protonmail-read search --folder INBOX --subject invoice
bin/protonmail-read search --folder INBOX --since 2026-01-01
Safety
The implemented IMAP fetches use BODY.PEEK[...] so reads should not mark
messages as read. The tool does not issue STORE, EXPUNGE, COPY, MOVE,
APPEND, CREATE, or DELETE.
Exported .eml files contain plaintext mail after Bridge has decrypted it
locally. export-eml refuses existing destinations, symlinks, and untrusted
group/world-writable parent directories; it creates a verified 0600 file and
publishes complete content atomically. Treat exports as sensitive.
sync-db also stores plaintext mail after Bridge has decrypted it locally. The
SQLite database contains raw RFC 5322 message bytes in the messages.raw BLOB
column plus indexed folder, UID, header, size, and SHA-256 metadata. The command
is resumable: messages already present for the same (folder, uid) are skipped,
and new messages are fetched with BODY.PEEK[].
Normal folder, summary, header, body, greeting, and error output filters ANSI,
OSC, C0/C1, DEL, and bidirectional terminal controls. raw is intentionally
unfiltered for exact RFC 5322 output and refuses a terminal unless the user
passes --unsafe-terminal; piping it is preferred.
IMAP input is bounded before allocation: 16 KiB per line, 32 MiB per message literal, 64 MiB per command response, 4096 response entries, 64 literals, and a 60-second total response deadline in addition to socket idle timeouts.
Credential and plaintext-mail handling are documented in
docs/credential-handling.md. Dependency
provenance is documented in
docs/dependency-provenance.md, and local
release evidence is documented in
docs/release-evidence.md. Production release
requires make release-evidence plus live Bridge credential and plaintext
export review.