Skip to content

Commit 1d9f754

Browse files
KenM76claude
authored andcommitted
v0.7.0: Outlook search v2 + new outlook get command
Implements FR_outlook_search_v2_multiterm_sender_match_and_get.md in full on both Windows and macOS. All 6 items shipped. Per Ken's "we're the only users" note, backward compatibility was NOT preserved — defaults changed where the old defaults were wrong: --match defaults to 'word' (was implicit substring) — fixes the base64 false-positive flood the FR documented (4,412 hits → 14) --fields defaults to 'subject,body,from' (was 'subject,body') — if you can search the sender for free you almost always want to EntryID and StoreID columns always emitted (was flag-gated) — connects search → get without a flag Multi-term: --query is repeatable AND accepts comma-separated terms. Both forms compose. Per-hit re-scan against (term × field) regex pairs attributes which term(s) matched each row into a new 'matched' column. Word matching: --match word|substring. Word mode uses DASL ci_phrasematch on content-indexed stores; per-folder try/catch falls back to LIKE + \bterm\b regex when ci_phrasematch throws (the non-indexed-store signal). The C#-side regex post-filter also drops word-mode false positives that DASL LIKE let through. New 'outlook get' command resolves an item by either: --id <EntryID> --store <substr> (direct, via GetItemFromID) --subject <substr> --max N (subject substring walk) Output: labeled headers + [BODY] + optional [HTMLBODY] + attachments list with --headers. Mac parity: OlMacSearchCommand rewritten with same flag surface and column shape. AppleScript whose is substring-only (no ci_phrasematch), so word-mode always uses the C#-side regex post-filter. EntryID column is the integer AppleScript exposes; StoreID column reuses account name since Mac Outlook has no StoreID concept. OlMacGetCommand (new) accepts --id <int> and walks accounts looking for `messages whose id is N`. v0.4.1's OlMacApp.Search() helper + SearchHit record removed (no external users; new commands inline their own AppleScript). Live-verified end-to-end against the FR's Gasspring driving task: combridge outlook search --query "ace control,acecontrols,313.89, gasspring,forklift,spring" --match word --since 2026-02-01 --until 2026-03-31 --snippet /tmp/gasspring.tsv → 14 hits (vs 4,412 substring flood); WS14080CA order email is row #1 with matched=313.89,gasspring,spring combridge outlook get --id <EntryID> --store toprops --headers → full order: headers + MountingDrawing_WS14080CA_8-19-160_8880.pdf attachment + line items + Total: US$313.89 Mirrored to D:\Dev\ScripTree\lib\combridge\ and R:\ScripTree\lib\combridge\ per the CLAUDE.md deployment mandate. FR moved to Complete/ folder. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent ef064ad commit 1d9f754

9 files changed

Lines changed: 1550 additions & 633 deletions

File tree

--snippet

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
WARN: unknown flag 'C:/Users/Ken/AppData/Local/Temp/gasspring.tsv' ignored.
2+
# search: query=ace control,acecontrols,313.89,gasspring,forklift,spring fields=subject,body,from match=word since=2026-02-01 until=2026-03-31
3+
# columns: date store folder sender subject matched entryid storeid
4+
2026-02-27 11:51 ken@toprops.com \\ken@toprops.com\Inbox info=gasspring.ca@mg.gasspring.ca Your Gasspring.ca order WS14080CA has been received! 313.89,gasspring,spring 00000000616E7F889C138B4D8D62615DD1E21AF404AB8500 0000000038A1BB1005E5101AA1BB08002B2A56C200006D737073742E646C6C00000000004E495441F9BFB80100AA0037D96E0000000043003A005C00550073006500720073005C004B0065006E005C0044006F00630075006D0065006E00740073005C004F00750074006C006F006F006B002000460069006C00650073005C006B0065006E00400074006F00700072006F00700073002E0063006F006D002E007000730074000000
5+
2026-02-27 11:51 ken@toprops.com \\ken@toprops.com\Inbox info=gasspring.ca@mg.gasspring.ca Your Gasspring.ca order WS14080CA has been received! 313.89,gasspring,spring 00000000616E7F889C138B4D8D62615DD1E21AF424AB8500 0000000038A1BB1005E5101AA1BB08002B2A56C200006D737073742E646C6C00000000004E495441F9BFB80100AA0037D96E0000000043003A005C00550073006500720073005C004B0065006E005C0044006F00630075006D0065006E00740073005C004F00750074006C006F006F006B002000460069006C00650073005C006B0065006E00400074006F00700072006F00700073002E0063006F006D002E007000730074000000
6+
2026-03-12 02:36 ken@toprops.com \\ken@toprops.com\Inbox Gasspring.ca Please leave a review for Gasspring.ca gasspring 00000000616E7F889C138B4D8D62615DD1E21AF4A4228600 0000000038A1BB1005E5101AA1BB08002B2A56C200006D737073742E646C6C00000000004E495441F9BFB80100AA0037D96E0000000043003A005C00550073006500720073005C004B0065006E005C0044006F00630075006D0065006E00740073005C004F00750074006C006F006F006B002000460069006C00650073005C006B0065006E00400074006F00700072006F00700073002E0063006F006D002E007000730074000000
7+
2026-03-12 02:36 ken@toprops.com \\ken@toprops.com\Inbox Gasspring.ca Please leave a review for Gasspring.ca gasspring 00000000616E7F889C138B4D8D62615DD1E21AF4C4228600 0000000038A1BB1005E5101AA1BB08002B2A56C200006D737073742E646C6C00000000004E495441F9BFB80100AA0037D96E0000000043003A005C00550073006500720073005C004B0065006E005C0044006F00630075006D0065006E00740073005C004F00750074006C006F006F006B002000460069006C00650073005C006B0065006E00400074006F00700072006F00700073002E0063006F006D002E007000730074000000
8+
2026-03-16 03:12 ken@toprops.com \\ken@toprops.com\Inbox Gasspring.ca Please leave a review for Gasspring.ca gasspring 00000000616E7F889C138B4D8D62615DD1E21AF4E4268600 0000000038A1BB1005E5101AA1BB08002B2A56C200006D737073742E646C6C00000000004E495441F9BFB80100AA0037D96E0000000043003A005C00550073006500720073005C004B0065006E005C0044006F00630075006D0065006E00740073005C004F00750074006C006F006F006B002000460069006C00650073005C006B0065006E00400074006F00700072006F00700073002E0063006F006D002E007000730074000000
9+
2026-03-16 03:12 ken@toprops.com \\ken@toprops.com\Inbox Gasspring.ca Please leave a review for Gasspring.ca gasspring 00000000616E7F889C138B4D8D62615DD1E21AF4E4278600 0000000038A1BB1005E5101AA1BB08002B2A56C200006D737073742E646C6C00000000004E495441F9BFB80100AA0037D96E0000000043003A005C00550073006500720073005C004B0065006E005C0044006F00630075006D0065006E00740073005C004F00750074006C006F006F006B002000460069006C00650073005C006B0065006E00400074006F00700072006F00700073002E0063006F006D002E007000730074000000
10+
2026-02-20 11:38 ken@toprops.com \\ken@toprops.com\Drafts ? www.gasspring.ca/gas-spring-calculator/ gasspring,spring 00000000616E7F889C138B4D8D62615DD1E21AF4E4948500 0000000038A1BB1005E5101AA1BB08002B2A56C200006D737073742E646C6C00000000004E495441F9BFB80100AA0037D96E0000000043003A005C00550073006500720073005C004B0065006E005C0044006F00630075006D0065006E00740073005C004F00750074006C006F006F006B002000460069006C00650073005C006B0065006E00400074006F00700072006F00700073002E0063006F006D002E007000730074000000
11+
2026-02-22 15:34 kenem17@gmail.com \\kenem17@gmail.com\Inbox Rakuten Hot Deals Hot Deal for you at Skechers: Spring Preview: Get 20% off regular priced items. spring 00000000EEABA6B3E34C71459883AE73005B00410700C3B68E10F77511CEB4CD00AA00BBB6E600000000000C0000D9539C2261A6BB45B9DAB62C7081B3C101004C3D00000000 0000000038A1BB1005E5101AA1BB08002B2A56C200007073747072782E646C6C0000000000000000E92FEB759650448683B87DE522AA4948000043003A005C00550073006500720073005C004B0065006E005C0041007000700044006100740061005C004C006F00630061006C005C004D006900630072006F0073006F00660074005C004F00750074006C006F006F006B005C006B0065006E0065006D0031003700400067006D00610069006C002E0063006F006D0020002D0020004B0065006E002E006F00730074000000
12+
2026-03-26 12:34 kenem17@gmail.com \\kenem17@gmail.com\Inbox TD Insurance Meloche Monnex 🏠See how you could keep your home safe and dry this spring spring 00000000EEABA6B3E34C71459883AE73005B00410700C3B68E10F77511CEB4CD00AA00BBB6E600000000000C0000D9539C2261A6BB45B9DAB62C7081B3C10100253F00000000 0000000038A1BB1005E5101AA1BB08002B2A56C200007073747072782E646C6C0000000000000000E92FEB759650448683B87DE522AA4948000043003A005C00550073006500720073005C004B0065006E005C0041007000700044006100740061005C004C006F00630061006C005C004D006900630072006F0073006F00660074005C004F00750074006C006F006F006B005C006B0065006E0065006D0031003700400067006D00610069006C002E0063006F006D0020002D0020004B0065006E002E006F00730074000000
13+
2026-03-27 12:15 kenem17@gmail.com \\kenem17@gmail.com\Inbox Old Stone Inn Boutique Hotel Spring is the perfect time for a getaway, and we’re making it even more tempting. spring 00000000EEABA6B3E34C71459883AE73005B00410700C3B68E10F77511CEB4CD00AA00BBB6E600000000000C0000D9539C2261A6BB45B9DAB62C7081B3C101002B3F00000000 0000000038A1BB1005E5101AA1BB08002B2A56C200007073747072782E646C6C0000000000000000E92FEB759650448683B87DE522AA4948000043003A005C00550073006500720073005C004B0065006E005C0041007000700044006100740061005C004C006F00630061006C005C004D006900630072006F0073006F00660074005C004F00750074006C006F006F006B005C006B0065006E0065006D0031003700400067006D00610069006C002E0063006F006D0020002D0020004B0065006E002E006F00730074000000
14+
2026-03-27 13:00 kenem17@gmail.com \\kenem17@gmail.com\Inbox Enbridge Gas Inc. Contact Ontario One Call before you dig this spring spring 00000000EEABA6B3E34C71459883AE73005B00410700C3B68E10F77511CEB4CD00AA00BBB6E600000000000C0000D9539C2261A6BB45B9DAB62C7081B3C101002C3F00000000 0000000038A1BB1005E5101AA1BB08002B2A56C200007073747072782E646C6C0000000000000000E92FEB759650448683B87DE522AA4948000043003A005C00550073006500720073005C004B0065006E005C0041007000700044006100740061005C004C006F00630061006C005C004D006900630072006F0073006F00660074005C004F00750074006C006F006F006B005C006B0065006E0065006D0031003700400067006D00610069006C002E0063006F006D0020002D0020004B0065006E002E006F00730074000000
15+
2026-03-31 00:01 kenem17@gmail.com \\kenem17@gmail.com\Inbox Aeroplan Amazon Big Spring Sale is on! Earn up to 7X the points on eligible purchases spring 00000000EEABA6B3E34C71459883AE73005B00410700C3B68E10F77511CEB4CD00AA00BBB6E600000000000C0000D9539C2261A6BB45B9DAB62C7081B3C10100443F00000000 0000000038A1BB1005E5101AA1BB08002B2A56C200007073747072782E646C6C0000000000000000E92FEB759650448683B87DE522AA4948000043003A005C00550073006500720073005C004B0065006E005C0041007000700044006100740061005C004C006F00630061006C005C004D006900630072006F0073006F00660074005C004F00750074006C006F006F006B005C006B0065006E0065006D0031003700400067006D00610069006C002E0063006F006D0020002D0020004B0065006E002E006F00730074000000
16+
2026-03-12 11:02 KenMantle@hotmail.com \\KenMantle@hotmail.com\Inbox Lisa Kamenar, Ontario Nature Signs of Spring in Your March Nature News spring 000000004B8238F02EE3AE4ABB700739F198CB3607003ECBA3B30BA4314AAA733889B9F6159E00000000010C0000C501071EC6A690439853A4B379D9BC000008763714940000 0000000038A1BB1005E5101AA1BB08002B2A56C20000454D534D44422E444C4C00000000000000001B55FA20AA6611CD9BC800AA002FC45A0C0000004B656E4D616E746C6540686F746D61696C2E636F6D002F6F3D4669727374204F7267616E697A6174696F6E2F6F753D45786368616E67652041646D696E6973747261746976652047726F75702846594449424F484632335350444C54292F636E3D526563697069656E74732F636E3D3030303637464645394438333043343800E94632F43E00000002000000100000004B0065006E004D0061006E0074006C006500400068006F0074006D00610069006C002E0063006F006D0000000000
17+
2026-03-11 02:25 KenMantle@hotmail.com \\KenMantle@hotmail.com\ofbiz.apache.org@dev Divesh Dutta Re: OFBiz re-architecture thoughts spring 000000004B8238F02EE3AE4ABB700739F198CB360700C501071EC6A690439853A4B379D9BC000006263AD1710000C501071EC6A690439853A4B379D9BC0000082B9CFC900000 0000000038A1BB1005E5101AA1BB08002B2A56C20000454D534D44422E444C4C00000000000000001B55FA20AA6611CD9BC800AA002FC45A0C0000004B656E4D616E746C6540686F746D61696C2E636F6D002F6F3D4669727374204F7267616E697A6174696F6E2F6F753D45786368616E67652041646D696E6973747261746976652047726F75702846594449424F484632335350444C54292F636E3D526563697069656E74732F636E3D3030303637464645394438333043343800E94632F43E00000002000000100000004B0065006E004D0061006E0074006C006500400068006F0074006D00610069006C002E0063006F006D0000000000
18+
19+
# stores walked: 4
20+
# folders walked: 257
21+
# folders fallback: 0 (ci_phrasematch unsupported, LIKE+\bterm\b regex used)
22+
# items scanned: 14
23+
# hits emitted: 14

CHANGELOG.md

Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,150 @@ All notable changes to this project will be documented in this file.
44
Format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/);
55
versions follow [SemVer](https://semver.org/spec/v2.0.0.html).
66

7+
## [0.7.0] — Outlook search v2: multi-term + word matching + sender + EntryID, and new `outlook get`
8+
9+
Addresses `FR_outlook_search_v2_multiterm_sender_match_and_get.md` in full
10+
(all 6 items). Both Windows and macOS Outlook plugins updated for parity.
11+
12+
**Breaking change** in CLI output (justified per the FR's "we're the only
13+
users" note — backward compatibility deliberately not preserved). The
14+
`outlook search` columns now include `matched`, `entryid`, and `storeid`
15+
on every row (no longer flag-gated), and defaults changed where the old
16+
default was wrong. Wrappers built against v0.6.x output need their
17+
column expectations updated.
18+
19+
### Why withdraw the v0.4.0 behavior
20+
21+
The v0.4.0 implementation was single-term, substring-only, subject/body-only,
22+
since-only, and emitted no EntryID. The FR documented a real
23+
"cast a wide net" task (searching for a Gasspring.ca order across two
24+
mailboxes for a US$313.89 charge) where every one of those gaps blocked
25+
progress. Specifically, substring matching of `pdac` against a base64
26+
URL-tracking blob `…ZPDACfM5…` matched a Sudbury meal newsletter — the
27+
kind of systematic false positive modern marketing mail generates by
28+
design.
29+
30+
### Changed defaults (FR § "What I'd ship instead")
31+
32+
| Setting | Old default | New default | Why |
33+
|---|---|---|---|
34+
| `--match` | implicit substring | **`word`** (ci_phrasematch on indexed; LIKE+regex fallback) | substring is just wrong for marketing mail; the fix should be the default |
35+
| `--fields` | `subject,body` | **`subject,body,from`** | if you can search the sender for free, you almost always want to |
36+
| EntryID/StoreID emission | not emitted | **always emitted** | connects `search``get` without a flag |
37+
38+
### Added — `outlook search` v2
39+
40+
- **Multi-term**: `--query` is now repeatable AND accepts comma-separated terms.
41+
Both forms compose. `--query "a,b" --query c` → three terms ORed.
42+
- **Sender field**: `--fields` accepts `from` (alias `sender`), mapping to
43+
both `urn:schemas:httpmail:fromname` (display) and `fromemail` (SMTP
44+
address). Default fields now include `from`.
45+
- **Word matching**: `--match word|substring`. `word` (default) uses DASL
46+
`ci_phrasematch` on content-indexed stores. Per-folder try/catch falls
47+
back to `LIKE` + C#-side `\bterm\b` regex when `ci_phrasematch` throws
48+
"condition is not valid" (the non-indexed-store signal). Either path
49+
produces the same word-boundary semantics.
50+
- **Date window**: `--until yyyy-MM-dd` mirrors `--since`. Together they
51+
form a closed interval. Either alone is open on the other end.
52+
- **`matched` column**: every row lists the term(s) that hit, computed
53+
by a C#-side re-scan of each Restrict candidate against
54+
(term × field) regex pairs. The same re-scan drops word-mode false
55+
positives that DASL LIKE let through but `\bterm\b` rejects.
56+
- **`entryid` + `storeid` columns**: always emitted on every row. EntryIDs
57+
are only unique within a store, so both are needed to call
58+
`GetItemFromID(entryID, storeID)` reliably.
59+
60+
### Added — new `outlook get` command
61+
62+
Resolves an item by either path:
63+
64+
- `--id <EntryID> [--store <substr>]` — direct fetch via
65+
`NameSpace.GetItemFromID(entryID, storeID)`. Fast and precise. The
66+
`--store` substring is resolved to the matching store's `StoreID`
67+
before lookup; without it, GetItemFromID searches the default store
68+
and may miss items in other accounts.
69+
- `--subject <substr> [--store <substr>] [--folder <substr>] [--max N]`
70+
recursive walk for interactive use when you don't have an EntryID
71+
handy. Returns the first `--max` matches (default 1).
72+
73+
Output is a one-block-per-item plain-text dump with labeled headers
74+
(`Subject`, `From`, `To`, `Cc`, `ReceivedTime`, `Size`, `Folder`,
75+
`EntryID`, `StoreID`) followed by `[BODY]` with the plain-text content.
76+
`--html` additionally dumps `[HTMLBODY]`. `--headers` adds the
77+
attachments list (name + size) and `MessageClass`.
78+
79+
### Verified (live test from the FR's driving task)
80+
81+
Ran the exact Gasspring scenario from the FR against the live mailboxes:
82+
83+
```
84+
combridge outlook search --query "ace control,acecontrols,313.89,gasspring,forklift,spring" \
85+
--match word --since 2026-02-01 --until 2026-03-31 --snippet /tmp/gasspring.tsv
86+
```
87+
88+
- **14 hits emitted** (vs the FR's documented 4,412-hit substring flood — a
89+
99.7% noise reduction from the word-boundary filter)
90+
- **First hit** = `Your Gasspring.ca order WS14080CA has been received!` with
91+
`matched=313.89,gasspring,spring` (three signal terms — exactly the FR's
92+
predicted top-row pattern)
93+
- **4 stores walked, 257 folders walked, 0 folders required fallback**
94+
(entire mailbox content-indexed)
95+
- **Per-hit EntryID + StoreID emitted in every row**
96+
97+
Then `outlook get --id <EntryID> --store toprops --headers` fetched the
98+
full order email including:
99+
- Headers (Subject, From, To, ReceivedTime, Size, Folder, EntryID, StoreID, MessageClass)
100+
- Attachment list (`MountingDrawing_WS14080CA_8-19-160_8880.pdf`, 200 KB)
101+
- Full plain-text body with the line items the FR predicted
102+
(4× $153.48 gas springs, 8× $59.36 brackets, **Total: US$313.89**)
103+
104+
Both subject-fallback (`--subject "WS14080CA" --store toprops`) and
105+
direct-ID paths return the same item.
106+
107+
### Mac parity
108+
109+
`OlMacSearchCommand` rewritten to match. Same flag surface, same column
110+
shape, same `matched`/`entryid`/`storeid` always-emitted output. Mac
111+
differences (architectural, not behavioral):
112+
113+
- AppleScript `whose` is substring-only — no `ci_phrasematch`. Word-mode
114+
always uses the C#-side `\bterm\b` regex post-filter. There's no
115+
"fast path" for indexed stores; every search behaves like the Windows
116+
fallback path.
117+
- Per-term separate `whose` queries because Mac Outlook's dictionary
118+
doesn't reliably accept compound `whose ... or ...` predicates against
119+
messages. Costs `terms × fields` AppleScript evaluations per folder
120+
instead of one — measurable on large mailboxes.
121+
- The `entryid` column is the integer AppleScript exposes via
122+
`id of message` (not the opaque hex EntryID Windows uses). Mac has no
123+
StoreID concept; we reuse the account name in the `storeid` column for
124+
cross-OS schema compatibility.
125+
- `OlMacGetCommand` (new) accepts `--id <integer>` and resolves via
126+
AppleScript `messages whose id is N` walked per account/folder.
127+
`--subject` path identical to Windows.
128+
- Still classic Outlook for Mac only — "New Outlook for Mac" (the 2024+
129+
Catalyst UI) restricts the AppleScript dictionary too far.
130+
131+
### Removed
132+
- v0.4.1's `OlMacApp.Search(...)` programmatic helper and `SearchHit`
133+
record. The new search command inlines its own AppleScript; a
134+
programmatic equivalent should either shell out to
135+
`combridge outlook search` or write its own AppleScript via
136+
`Osascript.Run(...)`. Less mechanism, fewer abstractions.
137+
138+
### Files
139+
- `src/plugins/ComBridge.Plugins.Outlook/OlSearchCommand.cs` (rewritten,
140+
new file split from OutlookPlugin.cs)
141+
- `src/plugins/ComBridge.Plugins.Outlook/OlGetCommand.cs` (new)
142+
- `src/plugins/ComBridge.Plugins.Outlook/OutlookPlugin.cs` (old inline
143+
OlSearchCommand removed; Commands list updated)
144+
- `src/plugins/ComBridge.Plugins.Outlook.Mac/OlMacSearchCommand.cs` (rewritten)
145+
- `src/plugins/ComBridge.Plugins.Outlook.Mac/OlMacGetCommand.cs` (new)
146+
- `src/plugins/ComBridge.Plugins.Outlook.Mac/OutlookMacPlugin.cs` (old
147+
inline OlMacSearchCommand removed; Commands list updated)
148+
- `src/plugins/ComBridge.Plugins.Outlook.Mac/OlMacApp.cs` (Search +
149+
SearchHit removed)
150+
7151
## [0.6.0]`list-addins` across every plugin (universal diagnostic command)
8152

9153
Adds a new `list-addins` subcommand to every plugin: Excel, Word,

0 commit comments

Comments
 (0)