Skip to content

Commit 64eb28f

Browse files
authored
docs: correct READMEs for packages (#436)
1 parent dcfd713 commit 64eb28f

File tree

5 files changed

+147
-0
lines changed

5 files changed

+147
-0
lines changed

backend/README.md

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
# backend
2+
3+
The `backend` package defines a unified `Provider` interface for multi-protocol email support and provides three protocol implementations: IMAP, JMAP, and POP3.
4+
5+
## Architecture
6+
7+
This package acts as an abstraction layer, allowing the rest of the application to interact with mail servers through a consistent interface regardless of the underlying protocol. Implementations self-register at init time via `RegisterBackend`, and the factory function `New()` creates the right provider based on the account's `Protocol` field (defaults to `"imap"`).
8+
9+
### Provider interface
10+
11+
The `Provider` interface composes five sub-interfaces:
12+
13+
| Interface | Methods | Purpose |
14+
|-----------|---------|---------|
15+
| `EmailReader` | `FetchEmails`, `FetchEmailBody`, `FetchAttachment` | Retrieve email lists, bodies, and raw attachments |
16+
| `EmailWriter` | `MarkAsRead`, `DeleteEmail`, `ArchiveEmail`, `MoveEmail` | Modify email state and location |
17+
| `EmailSender` | `SendEmail` | Send outgoing mail |
18+
| `FolderManager` | `FetchFolders` | List available mailboxes |
19+
| `Notifier` | `Watch` | Real-time push notifications for mailbox changes |
20+
21+
Backends that don't support an operation return `ErrNotSupported`.
22+
23+
## Protocols
24+
25+
### IMAP (`backend/imap`)
26+
27+
Wraps the existing `fetcher` and `sender` packages behind the `Provider` interface. IMAP IDLE is handled externally in `main.go`, so `Watch()` returns `ErrNotSupported`.
28+
29+
### JMAP (`backend/jmap`)
30+
31+
Native JMAP implementation (RFC 8620 / RFC 8621) using `go-jmap`. Supports OAuth2 and Basic Auth, real-time push via JMAP EventSource, and full mailbox operations including send (via `EmailSubmission`). JMAP string IDs are hashed to `uint32` UIDs for interface compatibility.
32+
33+
### POP3 (`backend/pop3`)
34+
35+
POP3 + SMTP implementation. Inherently limited to a single INBOX folder, no read flags, no move/archive, and no push notifications. Uses the `sender` package for outgoing mail.
36+
37+
## Files
38+
39+
| File | Description |
40+
|------|-------------|
41+
| `backend.go` | Core interfaces and data types (`Provider`, `Email`, `Attachment`, `Folder`, `OutgoingEmail`, `NotifyEvent`, `Capabilities`) |
42+
| `factory.go` | Protocol registry and `New()` factory function |
43+
| `imap/imap.go` | IMAP provider — adapter over `fetcher` and `sender` packages |
44+
| `jmap/jmap.go` | JMAP provider — native implementation with session management and mailbox caching |
45+
| `pop3/pop3.go` | POP3 provider — per-connection model with UIDL-based UID hashing |

clib/README.md

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,32 @@ Image decoding and PNG re-encoding using [stb_image](https://github.com/nothings
2323

2424
Files: `imgconv.c`, `imgconv.h`, `imgconv.go`, `stb_image.h`, `stb_image_write.h`
2525

26+
### htmlconv
27+
28+
Single-pass HTML-to-structured-elements parser. Takes raw HTML and returns a slice of `HTMLElement` values representing headings, links, images, blockquotes, tables, and text. Used by the email view to render HTML emails in the terminal without a full DOM.
29+
30+
- `HTMLToElements()` — parses HTML into structured elements with type, text, and up to two attributes (e.g., `href`/`src`, `alt`/`cite`).
31+
32+
Files: `htmlconv.c`, `htmlconv.h`, `htmlconv.go`
33+
34+
### markdown
35+
36+
Markdown-to-HTML conversion using [md4c](https://github.com/mity/md4c) (vendored). Supports GitHub-flavored features: tables, strikethrough, task lists, and permissive autolinks.
37+
38+
- `MarkdownToHTML()` — converts Markdown bytes to HTML bytes.
39+
40+
Files: `md4c.c`, `md4c.h`, `md4c-html.c`, `md4c-html.h`, `markdown.go`
41+
42+
## Pure Go fallbacks
43+
44+
Every function has a `_nocgo.go` counterpart (build tag `!cgo`) that provides the same API using pure Go libraries:
45+
46+
| C implementation | Go fallback |
47+
|-----------------|-------------|
48+
| `base64wrap.go` | Manual string builder |
49+
| `imgconv.go` (stb_image) | `image/png`, `image/jpeg`, `image/gif` |
50+
| `htmlconv.go` | `goquery` DOM parsing |
51+
| `markdown.go` (md4c) | `goldmark` |
2652

2753
## Adding new C code
2854

config/README.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,20 @@ All cache files use JSON serialization with restrictive file permissions (`0600`
2121
| `cache.go` | Email, contacts, and drafts caching. Provides CRUD operations for `EmailCache`, `ContactsCache` (with search and frequency-based ranking), and `DraftsCache` (with save/delete/get operations). |
2222
| `folder_cache.go` | Caches IMAP folder listings per account and per-folder email metadata. Stores folder names to avoid repeated IMAP `LIST` commands, and caches email headers per folder for fast navigation. |
2323
| `signature.go` | Loads and saves the user's email signature from `~/.config/matcha/signature.txt`. |
24+
| `oauth.go` | OAuth2 integration — token retrieval, authorization flow launcher, and embedded Python helper extraction. |
25+
| `oauth_script.py` | Embedded Gmail OAuth2 helper script (browser-based auth, token refresh, secure storage). |
2426
| `config_test.go` | Unit tests for configuration logic. |
27+
28+
## OAuth2 / XOAUTH2
29+
30+
Accounts with `auth_method: "oauth2"` use Gmail's XOAUTH2 mechanism instead of passwords. The flow works across three layers:
31+
32+
1. **`config/oauth.go`** — Go-side orchestration. Extracts the embedded Python helper to `~/.config/matcha/oauth/`, invokes it to run the browser-based authorization flow (`RunOAuth2Flow`) or to retrieve a fresh access token (`GetOAuth2Token`). The `IsOAuth2()` method on `Account` checks the auth method.
33+
34+
2. **`config/oauth_script.py`** — Embedded Python script that handles the full OAuth2 lifecycle:
35+
- `auth` — Opens a browser for Google authorization, captures the callback on `localhost:8189`, exchanges the code for tokens, and saves them to `~/.config/matcha/oauth_tokens/`.
36+
- `token` — Returns a fresh access token, automatically refreshing if expired (with a 5-minute buffer).
37+
- `revoke` — Revokes tokens with Google and deletes local storage.
38+
- Client credentials are stored in `~/.config/matcha/oauth_client.json`.
39+
40+
3. **`fetcher/xoauth2.go`** — Implements the XOAUTH2 SASL mechanism (`sasl.Client` interface) for IMAP/SMTP authentication. Formats the initial response as `user=<email>\x01auth=Bearer <token>\x01\x01` per Google's XOAUTH2 protocol spec.

fetcher/README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,8 @@ This package is the IMAP client layer for Matcha. It:
1313
- Supports S/MIME decryption (opaque and enveloped) and detached signature verification
1414
- Provides mailbox operations: delete (expunge), archive (move), and folder-to-folder moves
1515
- Exposes both mailbox-specific and convenience functions (e.g., `FetchEmails` defaults to INBOX)
16+
- Supports XOAUTH2 SASL authentication for Gmail OAuth2 accounts (see `xoauth2.go`)
17+
18+
## XOAUTH2
19+
20+
The `xoauth2.go` file implements the XOAUTH2 SASL mechanism as a `sasl.Client`. When an account uses `auth_method: "oauth2"`, the fetcher calls `config.GetOAuth2Token()` to get a fresh access token, then authenticates the IMAP connection using this SASL client instead of a password. The initial response follows Google's XOAUTH2 protocol: `user=<email>\x01auth=Bearer <token>\x01\x01`.

plugin/README.md

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
# plugin
2+
3+
Lua-based plugin system for extending Matcha. Plugins are loaded from `~/.config/matcha/plugins/` and run inside a sandboxed Lua VM (no `os`, `io`, or `debug` libraries).
4+
5+
## How it works
6+
7+
The `Manager` creates a Lua VM at startup, registers the `matcha` module, and loads all plugins from the user's plugins directory. Plugins can be either a single `.lua` file or a directory with an `init.lua` entry point.
8+
9+
Plugins interact with Matcha by registering callbacks on hooks:
10+
11+
```lua
12+
local matcha = require("matcha")
13+
14+
matcha.on("email_received", function(email)
15+
matcha.log("New email from: " .. email.from)
16+
matcha.notify("New mail!", 3)
17+
end)
18+
```
19+
20+
## Lua API (`matcha` module)
21+
22+
| Function | Description |
23+
|----------|-------------|
24+
| `matcha.on(event, callback)` | Register a callback for a hook event |
25+
| `matcha.log(msg)` | Log a message to stderr |
26+
| `matcha.notify(msg [, seconds])` | Show a temporary notification in the TUI (default 2s) |
27+
| `matcha.set_status(area, text)` | Set a persistent status string for a view area (`"inbox"`, `"composer"`, `"email_view"`) |
28+
29+
## Hook events
30+
31+
| Event | Callback argument | Description |
32+
|-------|-------------------|-------------|
33+
| `startup` || Matcha has started |
34+
| `shutdown` || Matcha is exiting |
35+
| `email_received` | Lua table with `uid`, `from`, `to`, `subject`, `date`, `is_read`, `account_id`, `folder` | New email arrived |
36+
| `email_viewed` | Same as `email_received` | User opened an email |
37+
| `email_send_before` | Table with `to`, `cc`, `subject`, `account_id` | About to send an email |
38+
| `email_send_after` | Same as `email_send_before` | Email sent successfully |
39+
| `folder_changed` | Folder name (string) | User switched folders |
40+
| `composer_updated` | Table with `body`, `body_len`, `subject`, `to` | Composer content changed |
41+
42+
## Available plugins
43+
44+
The following example plugins ship in `~/.config/matcha/plugins/`:
45+
46+
- `email_age.lua`
47+
- `recipient_counter.lua`
48+
49+
## Files
50+
51+
| File | Description |
52+
|------|-------------|
53+
| `plugin.go` | Plugin manager — Lua VM setup, plugin discovery and loading, notification/status state |
54+
| `hooks.go` | Hook definitions, callback registration, and hook invocation helpers |
55+
| `api.go` | `matcha` Lua module registration (`on`, `log`, `notify`, `set_status`) |

0 commit comments

Comments
 (0)