gogcli-mcp-gmail 2.22.0 → 2.23.0
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/README.md +91 -6
- package/SKILL.md +32 -4
- package/dist/index.js +986 -30
- package/manifest.json +8 -4
- package/package.json +1 -1
- package/src/tools/gmail-extra.ts +2102 -21
- package/tests/tools/draft-fork-signature.test.ts +67 -0
- package/tests/tools/draft-fork.test.ts +995 -0
- package/tests/tools/draft-write-vs-refetch.test.ts +81 -0
- package/tests/tools/gmail-extra.test.ts +1295 -0
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import { authoredBodyLines, measureBodyAgreement } from '../../src/tools/gmail-extra.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* HAZARD A — the lineage judgement must not fire on two unrelated drafts.
|
|
6
|
+
*
|
|
7
|
+
* `boilerplateLineFlags` stripped the RFC 3676 `-- ` block, the client's own
|
|
8
|
+
* `Sent from my iPhone`, and the NAME under a sign-off — but the run stopped at
|
|
9
|
+
* the first line that was not name-shaped, so a USER-CONFIGURED signature
|
|
10
|
+
* survived as authored prose:
|
|
11
|
+
*
|
|
12
|
+
* Thanks, -> stripped
|
|
13
|
+
* Chris Hall -> stripped
|
|
14
|
+
* (704) 555-0142 -> run stopped; survived
|
|
15
|
+
* chris.c.hall@gmail.com -> survived
|
|
16
|
+
* https://example.com/chris -> survived
|
|
17
|
+
*
|
|
18
|
+
* Those lines are identical on every message the account composes. Measured
|
|
19
|
+
* before the fix: two unrelated drafts shared 3 authored lines / 61 chars and
|
|
20
|
+
* scored similarity 0.60 against a 0.60 threshold — meetsThreshold TRUE on a
|
|
21
|
+
* plumber note and a soccer note. In a mailbox whose drafts go to a parenting
|
|
22
|
+
* coordinator, a wrong pairing is the expensive direction.
|
|
23
|
+
*/
|
|
24
|
+
const SIGNATURE = ['Thanks,', 'Chris Hall', '(704) 555-0142', 'chris.c.hall@gmail.com', 'https://example.com/chris'];
|
|
25
|
+
const withSig = (body: string[]) => ['Hi Sam,', '', ...body, '', ...SIGNATURE].join('\n');
|
|
26
|
+
|
|
27
|
+
describe('a shared signature is never lineage evidence', () => {
|
|
28
|
+
it('does not pair two unrelated drafts that share one signature', () => {
|
|
29
|
+
const m = measureBodyAgreement(withSig(['The plumber comes Tuesday at 9am.']), withSig(['Soccer registration closes Friday.']));
|
|
30
|
+
expect(m.sharedAuthoredLines).toBe(0);
|
|
31
|
+
expect(m.meetsThreshold).toBe(false);
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
it('strips the whole signature block, not just the name', () => {
|
|
35
|
+
expect(authoredBodyLines(withSig(['The plumber comes Tuesday at 9am.']))).toEqual(['The plumber comes Tuesday at 9am.']);
|
|
36
|
+
});
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
describe('and it still stops at authored content', () => {
|
|
40
|
+
it('keeps a postscript under the signature', () => {
|
|
41
|
+
expect(authoredBodyLines([...SIGNATURE, '', 'P.S. The invoice is attached.'].join('\n')))
|
|
42
|
+
.toEqual(['P.S. The invoice is attached.']);
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
it('keeps prose under the sign-off', () => {
|
|
46
|
+
expect(authoredBodyLines(['Thanks,', 'Chris', '', 'Actually the plumber moved to Wednesday.'].join('\n')))
|
|
47
|
+
.toEqual(['Actually the plumber moved to Wednesday.']);
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
it('keeps contact-shaped lines that are NOT under a sign-off', () => {
|
|
51
|
+
// The rule is positional. A bare phone number in the body is content.
|
|
52
|
+
expect(authoredBodyLines(['(704) 555-0142', 'chris@example.com'].join('\n')))
|
|
53
|
+
.toEqual(['(704) 555-0142', 'chris@example.com']);
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
it('keeps a phone number inside a sentence', () => {
|
|
57
|
+
expect(authoredBodyLines(['Call me at (704) 555-0142 about the roof.', '', 'Thanks,', 'Chris'].join('\n')))
|
|
58
|
+
.toEqual(['Call me at (704) 555-0142 about the roof.']);
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
it('still pairs two drafts that genuinely share authored prose', () => {
|
|
62
|
+
const shared = ['The plumber comes Tuesday at 9am.', 'He will need access to the crawlspace.', 'I left a key under the mat for him.'];
|
|
63
|
+
const m = measureBodyAgreement(withSig(shared), withSig([...shared, 'One more thing: the gate code is 4417.']));
|
|
64
|
+
expect(m.sharedAuthoredLines).toBeGreaterThanOrEqual(3);
|
|
65
|
+
expect(m.meetsThreshold).toBe(true);
|
|
66
|
+
});
|
|
67
|
+
});
|