@bobfrankston/mailx-settings 0.1.10 → 0.1.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/docs/contacts.md +6 -1
- package/docs/search.md +99 -0
- package/index.d.ts +8 -0
- package/index.d.ts.map +1 -1
- package/index.js +23 -0
- package/package.json +3 -3
package/docs/contacts.md
CHANGED
|
@@ -18,7 +18,11 @@
|
|
|
18
18
|
],
|
|
19
19
|
"discovered": [
|
|
20
20
|
{ "name": "Bob", "email": "bob@example.com", "useCount": 715, "lastUsed": 1777921829000 }
|
|
21
|
-
]
|
|
21
|
+
],
|
|
22
|
+
"groups": {
|
|
23
|
+
"Joes": ["joe@example.com", "jo@example.com"],
|
|
24
|
+
"Family": ["alice@example.com", "Joes"]
|
|
25
|
+
}
|
|
22
26
|
}
|
|
23
27
|
```
|
|
24
28
|
|
|
@@ -27,6 +31,7 @@
|
|
|
27
31
|
- **preferred** — manually-curated, top-ranked in autocomplete. Add people you actually want to reach quickly.
|
|
28
32
|
- **denylist** — addresses (lowercased) excluded from autocomplete entirely.
|
|
29
33
|
- **discovered** — auto-collected from sent/received mail. `useCount` × recency drives autocomplete ranking. Junk patterns (see below) are dropped at insertion.
|
|
34
|
+
- **groups** — mailing lists. Type the group name in To/Cc/Bcc and compose expands it into the member addresses on send. Each value is an array of either email addresses (`"a@b.com"` or `"Name <a@b.com>"`) or other group names (recursive aliasing — cycles are detected, depth capped at 10). Group lookup is case-insensitive on the key. The two `Joes` example above plus the `Family` example show flat membership and one group nested inside another.
|
|
30
35
|
|
|
31
36
|
## Global junk filter
|
|
32
37
|
|
package/docs/search.md
ADDED
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
# Search
|
|
2
|
+
|
|
3
|
+
> **Owned by rmfmail. Do not edit this file** — it's reference documentation.
|
|
4
|
+
|
|
5
|
+
Search in rmfmail runs in one of three modes depending on what you've selected:
|
|
6
|
+
|
|
7
|
+
- **All folders** (default) — searches your **local cache** using SQLite FTS5
|
|
8
|
+
- **This folder** — instant client-side filter on visible rows; full FTS5 search on Enter
|
|
9
|
+
- **Server** (the "Server" checkbox) — sends the query to the mail server (IMAP SEARCH on bobma-style accounts; **not yet wired to Gmail API for Gmail accounts** — see "Limitations" below)
|
|
10
|
+
|
|
11
|
+
The mode you're in dictates which query operators work. Scope matters.
|
|
12
|
+
|
|
13
|
+
## Common shortcuts (work in every mode)
|
|
14
|
+
|
|
15
|
+
These are parsed by mailx before dispatch, so they apply to all three scopes:
|
|
16
|
+
|
|
17
|
+
| Form | Effect |
|
|
18
|
+
|---|---|
|
|
19
|
+
| `from:bob` | Match sender substring |
|
|
20
|
+
| `to:eleanor` | Match recipient substring |
|
|
21
|
+
| `subject:lunch` | Match subject substring (everything until the next `keyword:` or end) |
|
|
22
|
+
| `/regex/` | Client-side regex over the currently-visible rows. Local only — never sent to the server. |
|
|
23
|
+
|
|
24
|
+
The remaining (unqualified) text becomes the **body** search term in the server query, or a free-text FTS5 phrase in local mode.
|
|
25
|
+
|
|
26
|
+
## Mode 1: Local search (FTS5) — default
|
|
27
|
+
|
|
28
|
+
Uses SQLite's FTS5 full-text index built from envelopes + locally-cached bodies. Fast, indexed, ~1ms per query.
|
|
29
|
+
|
|
30
|
+
Supported FTS5 syntax (when the search box has more than one word and no scope checkbox):
|
|
31
|
+
|
|
32
|
+
| Operator | Example | Meaning |
|
|
33
|
+
|---|---|---|
|
|
34
|
+
| `term1 term2` | `bob lunch` | both must appear (implicit AND) |
|
|
35
|
+
| `term1 OR term2` | `bob OR eleanor` | either |
|
|
36
|
+
| `term1 NOT term2` | `bob NOT spam` | first without the second |
|
|
37
|
+
| `"phrase"` | `"happy birthday"` | exact phrase |
|
|
38
|
+
| `term*` | `lunch*` | prefix |
|
|
39
|
+
| `^col:term` | `^subject:budget` | restrict to one indexed column (subject, body, from, to) |
|
|
40
|
+
| `NEAR(a b, 5)` | `NEAR(bob lunch, 5)` | both within 5 tokens of each other |
|
|
41
|
+
|
|
42
|
+
**Case**: FTS5 is **case-insensitive**. `AND`/`OR`/`NOT` work in any case (`and`, `OR`, `Not` are equivalent).
|
|
43
|
+
|
|
44
|
+
What's actually indexed: subject, from, to, cc, snippet (first ~200 chars of body), and the full body text *if* the body has been downloaded locally (the blue dot in the list). Bodies that haven't been prefetched aren't searchable until they are.
|
|
45
|
+
|
|
46
|
+
## Mode 2: This-folder filter
|
|
47
|
+
|
|
48
|
+
When the scope dropdown is set to "This folder" and you type, mailx **client-side filters the currently rendered rows** instantly — no server hit, no FTS5. Just substring match across each visible row's text.
|
|
49
|
+
|
|
50
|
+
Press **Enter** to escalate to a full FTS5 search of the folder.
|
|
51
|
+
|
|
52
|
+
`/regex/` works here for fast on-screen filtering.
|
|
53
|
+
|
|
54
|
+
## Mode 3: Server search
|
|
55
|
+
|
|
56
|
+
Tick the "Server" checkbox and the query goes to the mail server.
|
|
57
|
+
|
|
58
|
+
### bobma / Dovecot (IMAP SEARCH)
|
|
59
|
+
|
|
60
|
+
Standard IMAP keys, server-side. Combinable with implicit AND. mailx parses your `from:`, `to:`, `subject:` qualifiers and forwards them as IMAP keys; remaining text becomes a `BODY` search.
|
|
61
|
+
|
|
62
|
+
| Key | Example | Meaning |
|
|
63
|
+
|---|---|---|
|
|
64
|
+
| `BODY <text>` | (default for unqualified words) | Substring of body |
|
|
65
|
+
| `TEXT <text>` | (not exposed in the UI yet) | Substring of header + body |
|
|
66
|
+
| `SUBJECT <text>` | `subject:budget` | Substring of subject |
|
|
67
|
+
| `FROM <addr>` | `from:bob` | Substring of From line |
|
|
68
|
+
| `TO <addr>` | `to:eleanor` | Substring of To line |
|
|
69
|
+
| `SINCE <date>` | (not exposed) | RFC 822 date |
|
|
70
|
+
|
|
71
|
+
**Case**: IMAP SEARCH is **case-insensitive** (per RFC 3501 §6.4.4). `bob AND eleanor` and `bob and eleanor` behave the same on Dovecot.
|
|
72
|
+
|
|
73
|
+
**`AND` / `OR`**: IMAP's grammar is implicit-AND between keys. There's no literal `AND` keyword — typing `bob AND eleanor` would be sent as a body search for the literal three-word string. To OR keys you'd use IMAP's `OR <key1> <key2>` prefix syntax, which mailx doesn't expose in the UI today.
|
|
74
|
+
|
|
75
|
+
So if you typed `bob AND eleanor` on bobma and got results, what likely happened is the body literally contained the string "bob and eleanor" (case-insensitive). Apparent "AND" success is coincidence with the literal text.
|
|
76
|
+
|
|
77
|
+
### Gmail (server-search currently unwired)
|
|
78
|
+
|
|
79
|
+
`searchAndFetchOnServer` is IMAP-only and `withConnection` doesn't exist for Gmail-API accounts. Server-scope queries on Gmail today **return nothing new** — they only hit local cache. This is a known gap; the fix is to add a Gmail-API path that uses Google's `q=` query parameter (full Gmail search syntax: `from:`, `subject:`, `has:attachment`, `older_than:1y`, `label:`, etc., with proper boolean `AND`/`OR`).
|
|
80
|
+
|
|
81
|
+
That explains the asymmetry you may have noticed: `bob AND eleanor` "worked" against bobma (literal-text coincidence) but not against Gmail (no IMAP/API call ever fired).
|
|
82
|
+
|
|
83
|
+
## Limitations
|
|
84
|
+
|
|
85
|
+
- **No regex on the server side** (any provider). `/pattern/` only filters the visible local rows.
|
|
86
|
+
- **Server search results are stored locally** (envelope-only) on first hit. So a server search is also a backfill of envelopes for those messages — they appear next to local results without re-fetching.
|
|
87
|
+
- **Body search on bodies you haven't prefetched** only works server-side. The local FTS5 index can't search what isn't downloaded.
|
|
88
|
+
|
|
89
|
+
## Practical patterns
|
|
90
|
+
|
|
91
|
+
| Goal | What to type | Scope |
|
|
92
|
+
|---|---|---|
|
|
93
|
+
| Quick keyword in current folder | `lunch` | This folder (instant) |
|
|
94
|
+
| All-time mail from someone | `from:bob.frankston@example.com` | All folders (FTS5) |
|
|
95
|
+
| Mail mentioning two people | `bob eleanor` | All folders (FTS5; implicit AND) |
|
|
96
|
+
| Either of two terms | `bob OR eleanor` | All folders (FTS5) |
|
|
97
|
+
| Exact phrase | `"open source"` | All folders (FTS5) |
|
|
98
|
+
| Regex over what's on screen | `/^Re: \[mailx\]/` | Any (client-side) |
|
|
99
|
+
| Old mail beyond `historyDays` | type query, then check the **Server** checkbox | Server (Dovecot only today) |
|
package/index.d.ts
CHANGED
|
@@ -126,6 +126,14 @@ export declare function saveKeys(keys: AiKeys): Promise<void>;
|
|
|
126
126
|
* `keys: { anthropic: "", openai: "" }` and `keys: { anthropic: "sk-..." }`
|
|
127
127
|
* becomes `keys: { anthropic: "sk-...", openai: "" }`. Idempotent. */
|
|
128
128
|
export declare function ensureKeysSectionExists(): Promise<void>;
|
|
129
|
+
/** First-run helper: write a `groups` sample into contacts.jsonc so the
|
|
130
|
+
* user sees how to set up a mailing list. Compose's `expandRecipients`
|
|
131
|
+
* loads `cfg.groups` from this file at send time and resolves group
|
|
132
|
+
* names to the member addresses. Idempotent — only writes if `groups`
|
|
133
|
+
* is missing entirely (won't clobber a user-defined map). The sample
|
|
134
|
+
* uses example.com so it's harmless if the user accidentally sends to
|
|
135
|
+
* the unmodified placeholder. */
|
|
136
|
+
export declare function ensureGroupsSampleExists(): Promise<void>;
|
|
129
137
|
/** First-run helper: materialize the `autocomplete` block in
|
|
130
138
|
* preferences.jsonc with explicit defaults. loadPreferences() merges
|
|
131
139
|
* defaults at read time, but the file on disk often has no
|
package/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"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"}
|
package/index.js
CHANGED
|
@@ -924,6 +924,29 @@ export async function ensureKeysSectionExists() {
|
|
|
924
924
|
raw.keys = merged;
|
|
925
925
|
saveFile("accounts.jsonc", raw);
|
|
926
926
|
}
|
|
927
|
+
/** First-run helper: write a `groups` sample into contacts.jsonc so the
|
|
928
|
+
* user sees how to set up a mailing list. Compose's `expandRecipients`
|
|
929
|
+
* loads `cfg.groups` from this file at send time and resolves group
|
|
930
|
+
* names to the member addresses. Idempotent — only writes if `groups`
|
|
931
|
+
* is missing entirely (won't clobber a user-defined map). The sample
|
|
932
|
+
* uses example.com so it's harmless if the user accidentally sends to
|
|
933
|
+
* the unmodified placeholder. */
|
|
934
|
+
export async function ensureGroupsSampleExists() {
|
|
935
|
+
const sharedDir = getSharedDir();
|
|
936
|
+
const sharedPath = path.join(sharedDir, "contacts.jsonc");
|
|
937
|
+
const raw = readJsonc(sharedPath);
|
|
938
|
+
if (!raw)
|
|
939
|
+
return; // contacts.jsonc not bootstrapped yet — service will seed
|
|
940
|
+
if (raw.groups && typeof raw.groups === "object")
|
|
941
|
+
return; // user has groups
|
|
942
|
+
raw.groups = {
|
|
943
|
+
"Joes (sample — rename or remove me)": [
|
|
944
|
+
"joe@example.com",
|
|
945
|
+
"jo@example.com",
|
|
946
|
+
],
|
|
947
|
+
};
|
|
948
|
+
saveFile("contacts.jsonc", raw);
|
|
949
|
+
}
|
|
927
950
|
/** First-run helper: materialize the `autocomplete` block in
|
|
928
951
|
* preferences.jsonc with explicit defaults. loadPreferences() merges
|
|
929
952
|
* defaults at read time, but the file on disk often has no
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bobfrankston/mailx-settings",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.12",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"types": "index.d.ts",
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
},
|
|
18
18
|
"license": "ISC",
|
|
19
19
|
"dependencies": {
|
|
20
|
-
"@bobfrankston/mailx-types": "^0.1.
|
|
20
|
+
"@bobfrankston/mailx-types": "^0.1.10",
|
|
21
21
|
"jsonc-parser": "^3.3.1"
|
|
22
22
|
},
|
|
23
23
|
"repository": {
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
},
|
|
34
34
|
".transformedSnapshot": {
|
|
35
35
|
"dependencies": {
|
|
36
|
-
"@bobfrankston/mailx-types": "^0.1.
|
|
36
|
+
"@bobfrankston/mailx-types": "^0.1.10",
|
|
37
37
|
"jsonc-parser": "^3.3.1"
|
|
38
38
|
}
|
|
39
39
|
}
|