aamp-sdk 0.1.5

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.
@@ -0,0 +1,65 @@
1
+ /**
2
+ * AAMP Header Parser
3
+ *
4
+ * Parses AAMP protocol headers from email messages.
5
+ * Works with both raw header objects and JMAP Email objects.
6
+ *
7
+ * Headers are case-insensitive; we normalize to lowercase for lookup.
8
+ */
9
+ import { type AampMessage, type TaskResult } from './types.js';
10
+ type RawHeaders = Record<string, string | string[]>;
11
+ /**
12
+ * Normalize a header map to lowercase keys with string values
13
+ */
14
+ export declare function normalizeHeaders(headers: RawHeaders): Record<string, string>;
15
+ export interface EmailMetadata {
16
+ from: string;
17
+ to: string;
18
+ messageId: string;
19
+ subject: string;
20
+ headers: RawHeaders;
21
+ }
22
+ /**
23
+ * Parse AAMP headers from an email's header map.
24
+ * Returns null if this email is not an AAMP message.
25
+ *
26
+ * @param meta - Email metadata (from, to, messageId, subject, headers)
27
+ */
28
+ export declare function parseAampHeaders(meta: EmailMetadata): AampMessage | null;
29
+ /**
30
+ * Build AAMP headers for a task.dispatch email
31
+ */
32
+ export declare function buildDispatchHeaders(params: {
33
+ taskId: string;
34
+ /** Omit or pass undefined/null to send without a deadline */
35
+ timeoutSecs?: number | null;
36
+ contextLinks: string[];
37
+ parentTaskId?: string;
38
+ }): Record<string, string>;
39
+ /**
40
+ * Build AAMP headers for a task.ack email
41
+ */
42
+ export declare function buildAckHeaders(opts: {
43
+ taskId: string;
44
+ }): Record<string, string>;
45
+ /**
46
+ * Build AAMP headers for a task.result email
47
+ */
48
+ export declare function buildResultHeaders(params: {
49
+ taskId: string;
50
+ status: 'completed' | 'rejected';
51
+ output: string;
52
+ errorMsg?: string;
53
+ structuredResult?: TaskResult['structuredResult'];
54
+ }): Record<string, string>;
55
+ /**
56
+ * Build AAMP headers for a task.help email
57
+ */
58
+ export declare function buildHelpHeaders(params: {
59
+ taskId: string;
60
+ question: string;
61
+ blockedReason: string;
62
+ suggestedOptions: string[];
63
+ }): Record<string, string>;
64
+ export {};
65
+ //# sourceMappingURL=parser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../src/parser.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAe,KAAK,WAAW,EAAqB,KAAK,UAAU,EAA+B,MAAM,YAAY,CAAA;AAE3H,KAAK,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC,CAAA;AAEnD;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAO5E;AAkCD,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAA;IACZ,EAAE,EAAE,MAAM,CAAA;IACV,SAAS,EAAE,MAAM,CAAA;IACjB,OAAO,EAAE,MAAM,CAAA;IACf,OAAO,EAAE,UAAU,CAAA;CACpB;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,aAAa,GAAG,WAAW,GAAG,IAAI,CAwFxE;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE;IAC3C,MAAM,EAAE,MAAM,CAAA;IACd,6DAA6D;IAC7D,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC3B,YAAY,EAAE,MAAM,EAAE,CAAA;IACtB,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAezB;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE;IAAE,MAAM,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAKhF;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE;IACzC,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,WAAW,GAAG,UAAU,CAAA;IAChC,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,gBAAgB,CAAC,EAAE,UAAU,CAAC,kBAAkB,CAAC,CAAA;CAClD,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAezB;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE;IACvC,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,EAAE,MAAM,CAAA;IAChB,aAAa,EAAE,MAAM,CAAA;IACrB,gBAAgB,EAAE,MAAM,EAAE,CAAA;CAC3B,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAQzB"}
package/dist/parser.js ADDED
@@ -0,0 +1,187 @@
1
+ /**
2
+ * AAMP Header Parser
3
+ *
4
+ * Parses AAMP protocol headers from email messages.
5
+ * Works with both raw header objects and JMAP Email objects.
6
+ *
7
+ * Headers are case-insensitive; we normalize to lowercase for lookup.
8
+ */
9
+ import { AAMP_HEADER } from './types.js';
10
+ /**
11
+ * Normalize a header map to lowercase keys with string values
12
+ */
13
+ export function normalizeHeaders(headers) {
14
+ return Object.fromEntries(Object.entries(headers).map(([k, v]) => [
15
+ k.toLowerCase(),
16
+ Array.isArray(v) ? v[0] : v,
17
+ ]));
18
+ }
19
+ /**
20
+ * Get a header value by its X-AAMP-* name (case-insensitive)
21
+ */
22
+ function getAampHeader(headers, headerName) {
23
+ return headers[headerName.toLowerCase()];
24
+ }
25
+ function decodeStructuredResult(value) {
26
+ if (!value)
27
+ return undefined;
28
+ try {
29
+ const normalized = value.replace(/-/g, '+').replace(/_/g, '/');
30
+ const padding = normalized.length % 4 === 0 ? '' : '='.repeat(4 - (normalized.length % 4));
31
+ const decoded = Buffer.from(normalized + padding, 'base64').toString('utf-8');
32
+ return JSON.parse(decoded);
33
+ }
34
+ catch {
35
+ return undefined;
36
+ }
37
+ }
38
+ function encodeStructuredResult(value) {
39
+ if (!value)
40
+ return undefined;
41
+ const json = JSON.stringify(value);
42
+ return Buffer.from(json, 'utf-8')
43
+ .toString('base64')
44
+ .replace(/\+/g, '-')
45
+ .replace(/\//g, '_')
46
+ .replace(/=+$/g, '');
47
+ }
48
+ /**
49
+ * Parse AAMP headers from an email's header map.
50
+ * Returns null if this email is not an AAMP message.
51
+ *
52
+ * @param meta - Email metadata (from, to, messageId, subject, headers)
53
+ */
54
+ export function parseAampHeaders(meta) {
55
+ const headers = normalizeHeaders(meta.headers);
56
+ const intent = getAampHeader(headers, AAMP_HEADER.INTENT);
57
+ const taskId = getAampHeader(headers, AAMP_HEADER.TASK_ID);
58
+ if (!intent || !taskId)
59
+ return null;
60
+ const from = meta.from.replace(/^<|>$/g, '');
61
+ const to = meta.to.replace(/^<|>$/g, '');
62
+ if (intent === 'task.dispatch') {
63
+ const timeoutStr = getAampHeader(headers, AAMP_HEADER.TIMEOUT) ?? '300';
64
+ const contextLinksStr = getAampHeader(headers, AAMP_HEADER.CONTEXT_LINKS) ?? '';
65
+ const parentTaskId = getAampHeader(headers, AAMP_HEADER.PARENT_TASK_ID);
66
+ const dispatch = {
67
+ intent: 'task.dispatch',
68
+ taskId,
69
+ title: meta.subject.replace(/^\[AAMP Task\]\s*/, '').trim() || 'Untitled Task',
70
+ timeoutSecs: parseInt(timeoutStr, 10) || 300,
71
+ contextLinks: contextLinksStr
72
+ ? contextLinksStr.split(',').map((s) => s.trim()).filter(Boolean)
73
+ : [],
74
+ ...(parentTaskId ? { parentTaskId } : {}),
75
+ from,
76
+ to,
77
+ messageId: meta.messageId,
78
+ subject: meta.subject,
79
+ bodyText: '', // filled in by jmap-push.ts after parsing
80
+ };
81
+ return dispatch;
82
+ }
83
+ if (intent === 'task.result') {
84
+ const status = (getAampHeader(headers, AAMP_HEADER.STATUS) ?? 'completed');
85
+ const output = getAampHeader(headers, AAMP_HEADER.OUTPUT) ?? '';
86
+ const errorMsg = getAampHeader(headers, AAMP_HEADER.ERROR_MSG);
87
+ const structuredResult = decodeStructuredResult(getAampHeader(headers, AAMP_HEADER.STRUCTURED_RESULT));
88
+ const result = {
89
+ intent: 'task.result',
90
+ taskId,
91
+ status,
92
+ output,
93
+ errorMsg,
94
+ structuredResult,
95
+ from,
96
+ to,
97
+ };
98
+ return result;
99
+ }
100
+ if (intent === 'task.help') {
101
+ const question = getAampHeader(headers, AAMP_HEADER.QUESTION) ?? '';
102
+ const blockedReason = getAampHeader(headers, AAMP_HEADER.BLOCKED_REASON) ?? '';
103
+ const suggestedOptionsStr = getAampHeader(headers, AAMP_HEADER.SUGGESTED_OPTIONS) ?? '';
104
+ const help = {
105
+ intent: 'task.help',
106
+ taskId,
107
+ question,
108
+ blockedReason,
109
+ suggestedOptions: suggestedOptionsStr
110
+ ? suggestedOptionsStr.split('|').map((s) => s.trim()).filter(Boolean)
111
+ : [],
112
+ from,
113
+ to,
114
+ };
115
+ return help;
116
+ }
117
+ if (intent === 'task.ack') {
118
+ const ack = {
119
+ intent: 'task.ack',
120
+ taskId,
121
+ from,
122
+ to,
123
+ };
124
+ return ack;
125
+ }
126
+ return null;
127
+ }
128
+ /**
129
+ * Build AAMP headers for a task.dispatch email
130
+ */
131
+ export function buildDispatchHeaders(params) {
132
+ const headers = {
133
+ [AAMP_HEADER.INTENT]: 'task.dispatch',
134
+ [AAMP_HEADER.TASK_ID]: params.taskId,
135
+ };
136
+ if (params.timeoutSecs != null) {
137
+ headers[AAMP_HEADER.TIMEOUT] = String(params.timeoutSecs);
138
+ }
139
+ if (params.contextLinks.length > 0) {
140
+ headers[AAMP_HEADER.CONTEXT_LINKS] = params.contextLinks.join(',');
141
+ }
142
+ if (params.parentTaskId) {
143
+ headers[AAMP_HEADER.PARENT_TASK_ID] = params.parentTaskId;
144
+ }
145
+ return headers;
146
+ }
147
+ /**
148
+ * Build AAMP headers for a task.ack email
149
+ */
150
+ export function buildAckHeaders(opts) {
151
+ return {
152
+ [AAMP_HEADER.INTENT]: 'task.ack',
153
+ [AAMP_HEADER.TASK_ID]: opts.taskId,
154
+ };
155
+ }
156
+ /**
157
+ * Build AAMP headers for a task.result email
158
+ */
159
+ export function buildResultHeaders(params) {
160
+ const headers = {
161
+ [AAMP_HEADER.INTENT]: 'task.result',
162
+ [AAMP_HEADER.TASK_ID]: params.taskId,
163
+ [AAMP_HEADER.STATUS]: params.status,
164
+ [AAMP_HEADER.OUTPUT]: params.output,
165
+ };
166
+ if (params.errorMsg) {
167
+ headers[AAMP_HEADER.ERROR_MSG] = params.errorMsg;
168
+ }
169
+ const structuredResult = encodeStructuredResult(params.structuredResult);
170
+ if (structuredResult) {
171
+ headers[AAMP_HEADER.STRUCTURED_RESULT] = structuredResult;
172
+ }
173
+ return headers;
174
+ }
175
+ /**
176
+ * Build AAMP headers for a task.help email
177
+ */
178
+ export function buildHelpHeaders(params) {
179
+ return {
180
+ [AAMP_HEADER.INTENT]: 'task.help',
181
+ [AAMP_HEADER.TASK_ID]: params.taskId,
182
+ [AAMP_HEADER.QUESTION]: params.question,
183
+ [AAMP_HEADER.BLOCKED_REASON]: params.blockedReason,
184
+ [AAMP_HEADER.SUGGESTED_OPTIONS]: params.suggestedOptions.join('|'),
185
+ };
186
+ }
187
+ //# sourceMappingURL=parser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parser.js","sourceRoot":"","sources":["../src/parser.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,WAAW,EAAqF,MAAM,YAAY,CAAA;AAI3H;;GAEG;AACH,MAAM,UAAU,gBAAgB,CAAC,OAAmB;IAClD,OAAO,MAAM,CAAC,WAAW,CACvB,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC;QACtC,CAAC,CAAC,WAAW,EAAE;QACf,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;KAC5B,CAAC,CACH,CAAA;AACH,CAAC;AAED;;GAEG;AACH,SAAS,aAAa,CACpB,OAA+B,EAC/B,UAAkB;IAElB,OAAO,OAAO,CAAC,UAAU,CAAC,WAAW,EAAE,CAAC,CAAA;AAC1C,CAAC;AAED,SAAS,sBAAsB,CAAC,KAAc;IAC5C,IAAI,CAAC,KAAK;QAAE,OAAO,SAAS,CAAA;IAC5B,IAAI,CAAC;QACH,MAAM,UAAU,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAA;QAC9D,MAAM,OAAO,GAAG,UAAU,CAAC,MAAM,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAA;QAC1F,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,UAAU,GAAG,OAAO,EAAE,QAAQ,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAA;QAC7E,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAmC,CAAA;IAC9D,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAA;IAClB,CAAC;AACH,CAAC;AAED,SAAS,sBAAsB,CAAC,KAAsC;IACpE,IAAI,CAAC,KAAK;QAAE,OAAO,SAAS,CAAA;IAC5B,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAA;IAClC,OAAO,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC;SAC9B,QAAQ,CAAC,QAAQ,CAAC;SAClB,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC;SACnB,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC;SACnB,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAA;AACxB,CAAC;AAUD;;;;;GAKG;AACH,MAAM,UAAU,gBAAgB,CAAC,IAAmB;IAClD,MAAM,OAAO,GAAG,gBAAgB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;IAE9C,MAAM,MAAM,GAAG,aAAa,CAAC,OAAO,EAAE,WAAW,CAAC,MAAM,CAAC,CAAA;IACzD,MAAM,MAAM,GAAG,aAAa,CAAC,OAAO,EAAE,WAAW,CAAC,OAAO,CAAC,CAAA;IAE1D,IAAI,CAAC,MAAM,IAAI,CAAC,MAAM;QAAE,OAAO,IAAI,CAAA;IAEnC,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAA;IAC5C,MAAM,EAAE,GAAG,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAA;IAExC,IAAI,MAAM,KAAK,eAAe,EAAE,CAAC;QAC/B,MAAM,UAAU,GAAG,aAAa,CAAC,OAAO,EAAE,WAAW,CAAC,OAAO,CAAC,IAAI,KAAK,CAAA;QACvE,MAAM,eAAe,GAAG,aAAa,CAAC,OAAO,EAAE,WAAW,CAAC,aAAa,CAAC,IAAI,EAAE,CAAA;QAE/E,MAAM,YAAY,GAAG,aAAa,CAAC,OAAO,EAAE,WAAW,CAAC,cAAc,CAAC,CAAA;QAEvE,MAAM,QAAQ,GAAiB;YAC7B,MAAM,EAAE,eAAe;YACvB,MAAM;YACN,KAAK,EAAE,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,mBAAmB,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,IAAI,eAAe;YAC9E,WAAW,EAAE,QAAQ,CAAC,UAAU,EAAE,EAAE,CAAC,IAAI,GAAG;YAC5C,YAAY,EAAE,eAAe;gBAC3B,CAAC,CAAC,eAAe,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC;gBACjE,CAAC,CAAC,EAAE;YACN,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACzC,IAAI;YACJ,EAAE;YACF,SAAS,EAAE,IAAI,CAAC,SAAS;YACzB,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,QAAQ,EAAE,EAAE,EAAE,0CAA0C;SACzD,CAAA;QACD,OAAO,QAAQ,CAAA;IACjB,CAAC;IAED,IAAI,MAAM,KAAK,aAAa,EAAE,CAAC;QAC7B,MAAM,MAAM,GAAG,CAAC,aAAa,CAAC,OAAO,EAAE,WAAW,CAAC,MAAM,CAAC,IAAI,WAAW,CAE3D,CAAA;QACd,MAAM,MAAM,GAAG,aAAa,CAAC,OAAO,EAAE,WAAW,CAAC,MAAM,CAAC,IAAI,EAAE,CAAA;QAC/D,MAAM,QAAQ,GAAG,aAAa,CAAC,OAAO,EAAE,WAAW,CAAC,SAAS,CAAC,CAAA;QAC9D,MAAM,gBAAgB,GAAG,sBAAsB,CAC7C,aAAa,CAAC,OAAO,EAAE,WAAW,CAAC,iBAAiB,CAAC,CACtD,CAAA;QAED,MAAM,MAAM,GAAe;YACzB,MAAM,EAAE,aAAa;YACrB,MAAM;YACN,MAAM;YACN,MAAM;YACN,QAAQ;YACR,gBAAgB;YAChB,IAAI;YACJ,EAAE;SACH,CAAA;QACD,OAAO,MAAM,CAAA;IACf,CAAC;IAED,IAAI,MAAM,KAAK,WAAW,EAAE,CAAC;QAC3B,MAAM,QAAQ,GAAG,aAAa,CAAC,OAAO,EAAE,WAAW,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAA;QACnE,MAAM,aAAa,GAAG,aAAa,CAAC,OAAO,EAAE,WAAW,CAAC,cAAc,CAAC,IAAI,EAAE,CAAA;QAC9E,MAAM,mBAAmB,GAAG,aAAa,CAAC,OAAO,EAAE,WAAW,CAAC,iBAAiB,CAAC,IAAI,EAAE,CAAA;QAEvF,MAAM,IAAI,GAAa;YACrB,MAAM,EAAE,WAAW;YACnB,MAAM;YACN,QAAQ;YACR,aAAa;YACb,gBAAgB,EAAE,mBAAmB;gBACnC,CAAC,CAAC,mBAAmB,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC;gBACrE,CAAC,CAAC,EAAE;YACN,IAAI;YACJ,EAAE;SACH,CAAA;QACD,OAAO,IAAI,CAAA;IACb,CAAC;IAED,IAAI,MAAM,KAAK,UAAU,EAAE,CAAC;QAC1B,MAAM,GAAG,GAAY;YACnB,MAAM,EAAE,UAAU;YAClB,MAAM;YACN,IAAI;YACJ,EAAE;SACH,CAAA;QACD,OAAO,GAAG,CAAA;IACZ,CAAC;IAED,OAAO,IAAI,CAAA;AACb,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,oBAAoB,CAAC,MAMpC;IACC,MAAM,OAAO,GAA2B;QACtC,CAAC,WAAW,CAAC,MAAM,CAAC,EAAE,eAAe;QACrC,CAAC,WAAW,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM;KACrC,CAAA;IACD,IAAI,MAAM,CAAC,WAAW,IAAI,IAAI,EAAE,CAAC;QAC/B,OAAO,CAAC,WAAW,CAAC,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,CAAA;IAC3D,CAAC;IACD,IAAI,MAAM,CAAC,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACnC,OAAO,CAAC,WAAW,CAAC,aAAa,CAAC,GAAG,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;IACpE,CAAC;IACD,IAAI,MAAM,CAAC,YAAY,EAAE,CAAC;QACxB,OAAO,CAAC,WAAW,CAAC,cAAc,CAAC,GAAG,MAAM,CAAC,YAAY,CAAA;IAC3D,CAAC;IACD,OAAO,OAAO,CAAA;AAChB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,eAAe,CAAC,IAAwB;IACtD,OAAO;QACL,CAAC,WAAW,CAAC,MAAM,CAAC,EAAE,UAAU;QAChC,CAAC,WAAW,CAAC,OAAO,CAAC,EAAE,IAAI,CAAC,MAAM;KACnC,CAAA;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,kBAAkB,CAAC,MAMlC;IACC,MAAM,OAAO,GAA2B;QACtC,CAAC,WAAW,CAAC,MAAM,CAAC,EAAE,aAAa;QACnC,CAAC,WAAW,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM;QACpC,CAAC,WAAW,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM;QACnC,CAAC,WAAW,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM;KACpC,CAAA;IACD,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC;QACpB,OAAO,CAAC,WAAW,CAAC,SAAS,CAAC,GAAG,MAAM,CAAC,QAAQ,CAAA;IAClD,CAAC;IACD,MAAM,gBAAgB,GAAG,sBAAsB,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAA;IACxE,IAAI,gBAAgB,EAAE,CAAC;QACrB,OAAO,CAAC,WAAW,CAAC,iBAAiB,CAAC,GAAG,gBAAgB,CAAA;IAC3D,CAAC;IACD,OAAO,OAAO,CAAA;AAChB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,gBAAgB,CAAC,MAKhC;IACC,OAAO;QACL,CAAC,WAAW,CAAC,MAAM,CAAC,EAAE,WAAW;QACjC,CAAC,WAAW,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM;QACpC,CAAC,WAAW,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC,QAAQ;QACvC,CAAC,WAAW,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC,aAAa;QAClD,CAAC,WAAW,CAAC,iBAAiB,CAAC,EAAE,MAAM,CAAC,gBAAgB,CAAC,IAAI,CAAC,GAAG,CAAC;KACnE,CAAA;AACH,CAAC"}
@@ -0,0 +1,57 @@
1
+ /**
2
+ * SMTP Sender
3
+ *
4
+ * Sends AAMP protocol emails via SMTP (Stalwart submission port 587).
5
+ */
6
+ import type { SendTaskOptions, SendResultOptions, SendHelpOptions } from './types.js';
7
+ export interface SmtpConfig {
8
+ host: string;
9
+ port: number;
10
+ user: string;
11
+ password: string;
12
+ httpBaseUrl?: string;
13
+ authToken?: string;
14
+ secure?: boolean;
15
+ /** Whether to reject unauthorized TLS certificates (default: true) */
16
+ rejectUnauthorized?: boolean;
17
+ }
18
+ export declare class SmtpSender {
19
+ private readonly config;
20
+ private transport;
21
+ constructor(config: SmtpConfig);
22
+ private senderDomain;
23
+ private recipientDomain;
24
+ private shouldUseHttpFallback;
25
+ private sendViaHttp;
26
+ /**
27
+ * Send a task.dispatch email.
28
+ * Returns both the generated taskId and the SMTP Message-ID so callers can
29
+ * store a reverse-index (messageId → taskId) for In-Reply-To thread routing.
30
+ */
31
+ sendTask(opts: SendTaskOptions): Promise<{
32
+ taskId: string;
33
+ messageId: string;
34
+ }>;
35
+ /**
36
+ * Send a task.result email back to the dispatcher
37
+ */
38
+ sendResult(opts: SendResultOptions): Promise<void>;
39
+ /**
40
+ * Send a task.help email when the agent is blocked
41
+ */
42
+ sendHelp(opts: SendHelpOptions): Promise<void>;
43
+ /**
44
+ * Send a task.ack email to confirm receipt of a dispatch
45
+ */
46
+ sendAck(opts: {
47
+ to: string;
48
+ taskId: string;
49
+ inReplyTo?: string;
50
+ }): Promise<void>;
51
+ /**
52
+ * Verify SMTP connection
53
+ */
54
+ verify(): Promise<boolean>;
55
+ close(): void;
56
+ }
57
+ //# sourceMappingURL=smtp-sender.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"smtp-sender.d.ts","sourceRoot":"","sources":["../src/smtp-sender.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAQH,OAAO,KAAK,EACV,eAAe,EACf,iBAAiB,EACjB,eAAe,EAChB,MAAM,YAAY,CAAA;AAEnB,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,MAAM,CAAA;IAChB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,sEAAsE;IACtE,kBAAkB,CAAC,EAAE,OAAO,CAAA;CAC7B;AAED,qBAAa,UAAU;IAGT,OAAO,CAAC,QAAQ,CAAC,MAAM;IAFnC,OAAO,CAAC,SAAS,CAAa;gBAED,MAAM,EAAE,UAAU;IAe/C,OAAO,CAAC,YAAY;IAIpB,OAAO,CAAC,eAAe;IAIvB,OAAO,CAAC,qBAAqB;YASf,WAAW;IAsCzB;;;;OAIG;IACG,QAAQ,CAAC,IAAI,EAAE,eAAe,GAAG,OAAO,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC;IAwDrF;;OAEG;IACG,UAAU,CAAC,IAAI,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC;IAwDxD;;OAEG;IACG,QAAQ,CAAC,IAAI,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC;IA0DpD;;OAEG;IACG,OAAO,CAAC,IAAI,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IA0BtF;;OAEG;IACG,MAAM,IAAI,OAAO,CAAC,OAAO,CAAC;IAShC,KAAK,IAAI,IAAI;CAGd"}
@@ -0,0 +1,282 @@
1
+ /**
2
+ * SMTP Sender
3
+ *
4
+ * Sends AAMP protocol emails via SMTP (Stalwart submission port 587).
5
+ */
6
+ import { createTransport } from 'nodemailer';
7
+ import { randomUUID } from 'crypto';
8
+ /** Strip CR/LF to prevent email header injection */
9
+ const sanitize = (s) => s.replace(/[\r\n]/g, ' ').trim();
10
+ import { buildDispatchHeaders, buildResultHeaders, buildHelpHeaders, buildAckHeaders } from './parser.js';
11
+ export class SmtpSender {
12
+ config;
13
+ transport;
14
+ constructor(config) {
15
+ this.config = config;
16
+ this.transport = createTransport({
17
+ host: config.host,
18
+ port: config.port,
19
+ secure: config.secure ?? false,
20
+ auth: {
21
+ user: config.user,
22
+ pass: config.password,
23
+ },
24
+ tls: {
25
+ rejectUnauthorized: config.rejectUnauthorized ?? true,
26
+ },
27
+ });
28
+ }
29
+ senderDomain() {
30
+ return this.config.user.split('@')[1]?.toLowerCase() ?? '';
31
+ }
32
+ recipientDomain(email) {
33
+ return email.split('@')[1]?.toLowerCase() ?? '';
34
+ }
35
+ shouldUseHttpFallback(to) {
36
+ return Boolean(this.config.httpBaseUrl
37
+ && this.config.authToken
38
+ && this.senderDomain()
39
+ && this.senderDomain() === this.recipientDomain(to));
40
+ }
41
+ async sendViaHttp(opts) {
42
+ const base = this.config.httpBaseUrl?.replace(/\/$/, '');
43
+ if (!base || !this.config.authToken) {
44
+ throw new Error('HTTP send fallback is not configured');
45
+ }
46
+ const res = await fetch(`${base}/api/send`, {
47
+ method: 'POST',
48
+ headers: {
49
+ Authorization: `Basic ${this.config.authToken}`,
50
+ 'Content-Type': 'application/json',
51
+ },
52
+ body: JSON.stringify({
53
+ to: opts.to,
54
+ subject: opts.subject,
55
+ text: opts.text,
56
+ aampHeaders: opts.aampHeaders,
57
+ attachments: opts.attachments?.map((a) => ({
58
+ filename: a.filename,
59
+ contentType: a.contentType,
60
+ content: typeof a.content === 'string' ? a.content : a.content.toString('base64'),
61
+ })),
62
+ }),
63
+ });
64
+ const data = await res.json().catch(() => ({}));
65
+ if (!res.ok) {
66
+ throw new Error(data.details || `HTTP send failed: ${res.status}`);
67
+ }
68
+ return { messageId: data.messageId };
69
+ }
70
+ /**
71
+ * Send a task.dispatch email.
72
+ * Returns both the generated taskId and the SMTP Message-ID so callers can
73
+ * store a reverse-index (messageId → taskId) for In-Reply-To thread routing.
74
+ */
75
+ async sendTask(opts) {
76
+ const taskId = randomUUID();
77
+ const aampHeaders = buildDispatchHeaders({
78
+ taskId,
79
+ timeoutSecs: opts.timeoutSecs,
80
+ contextLinks: opts.contextLinks ?? [],
81
+ parentTaskId: opts.parentTaskId,
82
+ });
83
+ const sendMailOpts = {
84
+ from: this.config.user,
85
+ to: opts.to,
86
+ subject: `[AAMP Task] ${sanitize(opts.title)}`,
87
+ text: [
88
+ `Task: ${opts.title}`,
89
+ `Task ID: ${taskId}`,
90
+ opts.timeoutSecs ? `Deadline: ${opts.timeoutSecs}s` : `Deadline: none`,
91
+ opts.contextLinks?.length
92
+ ? `Context:\n${opts.contextLinks.map((l) => ` ${l}`).join('\n')}`
93
+ : '',
94
+ ``,
95
+ `--- This email was sent by AAMP. Reply directly to submit your result. ---`,
96
+ ]
97
+ .filter(Boolean)
98
+ .join('\n'),
99
+ headers: aampHeaders,
100
+ };
101
+ if (opts.attachments?.length) {
102
+ sendMailOpts.attachments = opts.attachments.map(a => ({
103
+ filename: a.filename,
104
+ content: typeof a.content === 'string' ? Buffer.from(a.content, 'base64') : a.content,
105
+ contentType: a.contentType,
106
+ }));
107
+ }
108
+ if (this.shouldUseHttpFallback(opts.to)) {
109
+ const info = await this.sendViaHttp({
110
+ to: opts.to,
111
+ subject: sendMailOpts.subject,
112
+ text: sendMailOpts.text,
113
+ aampHeaders,
114
+ attachments: opts.attachments?.map(a => ({
115
+ filename: a.filename,
116
+ contentType: a.contentType,
117
+ content: typeof a.content === 'string' ? Buffer.from(a.content, 'base64') : a.content,
118
+ })),
119
+ });
120
+ return { taskId, messageId: info.messageId ?? '' };
121
+ }
122
+ const info = await this.transport.sendMail(sendMailOpts);
123
+ return { taskId, messageId: info.messageId ?? '' };
124
+ }
125
+ /**
126
+ * Send a task.result email back to the dispatcher
127
+ */
128
+ async sendResult(opts) {
129
+ const aampHeaders = buildResultHeaders({
130
+ taskId: opts.taskId,
131
+ status: opts.status,
132
+ output: opts.output,
133
+ errorMsg: opts.errorMsg,
134
+ structuredResult: opts.structuredResult,
135
+ });
136
+ const mailOpts = {
137
+ from: this.config.user,
138
+ to: opts.to,
139
+ subject: `[AAMP Result] Task ${opts.taskId} — ${opts.status}`,
140
+ text: [
141
+ `AAMP Task Result`,
142
+ ``,
143
+ `Task ID: ${opts.taskId}`,
144
+ `Status: ${opts.status}`,
145
+ ``,
146
+ `Output:`,
147
+ opts.output,
148
+ opts.errorMsg ? `\nError: ${opts.errorMsg}` : '',
149
+ ]
150
+ .filter((s) => s !== '')
151
+ .join('\n'),
152
+ headers: aampHeaders,
153
+ };
154
+ if (opts.inReplyTo) {
155
+ mailOpts.inReplyTo = opts.inReplyTo;
156
+ mailOpts.references = opts.inReplyTo;
157
+ }
158
+ if (opts.attachments?.length) {
159
+ mailOpts.attachments = opts.attachments.map(a => ({
160
+ filename: a.filename,
161
+ content: typeof a.content === 'string' ? Buffer.from(a.content, 'base64') : a.content,
162
+ contentType: a.contentType,
163
+ }));
164
+ }
165
+ if (this.shouldUseHttpFallback(opts.to)) {
166
+ await this.sendViaHttp({
167
+ to: opts.to,
168
+ subject: mailOpts.subject,
169
+ text: mailOpts.text,
170
+ aampHeaders,
171
+ attachments: opts.attachments?.map(a => ({
172
+ filename: a.filename,
173
+ contentType: a.contentType,
174
+ content: typeof a.content === 'string' ? Buffer.from(a.content, 'base64') : a.content,
175
+ })),
176
+ });
177
+ return;
178
+ }
179
+ await this.transport.sendMail(mailOpts);
180
+ }
181
+ /**
182
+ * Send a task.help email when the agent is blocked
183
+ */
184
+ async sendHelp(opts) {
185
+ const aampHeaders = buildHelpHeaders({
186
+ taskId: opts.taskId,
187
+ question: opts.question,
188
+ blockedReason: opts.blockedReason,
189
+ suggestedOptions: opts.suggestedOptions,
190
+ });
191
+ const helpMailOpts = {
192
+ from: this.config.user,
193
+ to: opts.to,
194
+ subject: `[AAMP Help] Task ${opts.taskId} needs assistance`,
195
+ text: [
196
+ `AAMP Task Help Request`,
197
+ ``,
198
+ `Task ID: ${opts.taskId}`,
199
+ ``,
200
+ `Question: ${opts.question}`,
201
+ ``,
202
+ `Blocked reason: ${opts.blockedReason}`,
203
+ ``,
204
+ opts.suggestedOptions.length
205
+ ? `Suggested options:\n${opts.suggestedOptions.map((o, i) => ` ${i + 1}. ${o}`).join('\n')}`
206
+ : '',
207
+ ]
208
+ .filter(Boolean)
209
+ .join('\n'),
210
+ headers: aampHeaders,
211
+ };
212
+ if (opts.inReplyTo) {
213
+ helpMailOpts.inReplyTo = opts.inReplyTo;
214
+ helpMailOpts.references = opts.inReplyTo;
215
+ }
216
+ if (opts.attachments?.length) {
217
+ helpMailOpts.attachments = opts.attachments.map(a => ({
218
+ filename: a.filename,
219
+ content: typeof a.content === 'string' ? Buffer.from(a.content, 'base64') : a.content,
220
+ contentType: a.contentType,
221
+ }));
222
+ }
223
+ if (this.shouldUseHttpFallback(opts.to)) {
224
+ await this.sendViaHttp({
225
+ to: opts.to,
226
+ subject: helpMailOpts.subject,
227
+ text: helpMailOpts.text,
228
+ aampHeaders,
229
+ attachments: opts.attachments?.map(a => ({
230
+ filename: a.filename,
231
+ contentType: a.contentType,
232
+ content: typeof a.content === 'string' ? Buffer.from(a.content, 'base64') : a.content,
233
+ })),
234
+ });
235
+ return;
236
+ }
237
+ await this.transport.sendMail(helpMailOpts);
238
+ }
239
+ /**
240
+ * Send a task.ack email to confirm receipt of a dispatch
241
+ */
242
+ async sendAck(opts) {
243
+ const aampHeaders = buildAckHeaders({ taskId: opts.taskId });
244
+ const mailOpts = {
245
+ from: this.config.user,
246
+ to: opts.to,
247
+ subject: `[AAMP ACK] Task ${opts.taskId}`,
248
+ text: '',
249
+ headers: aampHeaders,
250
+ };
251
+ if (opts.inReplyTo) {
252
+ mailOpts.inReplyTo = opts.inReplyTo;
253
+ mailOpts.references = opts.inReplyTo;
254
+ }
255
+ if (this.shouldUseHttpFallback(opts.to)) {
256
+ await this.sendViaHttp({
257
+ to: opts.to,
258
+ subject: mailOpts.subject,
259
+ text: mailOpts.text,
260
+ aampHeaders,
261
+ });
262
+ return;
263
+ }
264
+ await this.transport.sendMail(mailOpts);
265
+ }
266
+ /**
267
+ * Verify SMTP connection
268
+ */
269
+ async verify() {
270
+ try {
271
+ await this.transport.verify();
272
+ return true;
273
+ }
274
+ catch {
275
+ return false;
276
+ }
277
+ }
278
+ close() {
279
+ this.transport.close();
280
+ }
281
+ }
282
+ //# sourceMappingURL=smtp-sender.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"smtp-sender.js","sourceRoot":"","sources":["../src/smtp-sender.ts"],"names":[],"mappings":"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"}