@atomicmail/agent-skill-openclaw 0.3.24

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.
Files changed (154) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +182 -0
  3. package/SKILL.md +206 -0
  4. package/esm/_dnt.polyfills.d.ts +101 -0
  5. package/esm/_dnt.polyfills.d.ts.map +1 -0
  6. package/esm/_dnt.polyfills.js +127 -0
  7. package/esm/lib/agent/auth/agent-auth-http.d.ts +26 -0
  8. package/esm/lib/agent/auth/agent-auth-http.d.ts.map +1 -0
  9. package/esm/lib/agent/auth/agent-auth-http.js +85 -0
  10. package/esm/lib/agent/auth/agent-jwt.d.ts +12 -0
  11. package/esm/lib/agent/auth/agent-jwt.d.ts.map +1 -0
  12. package/esm/lib/agent/auth/agent-jwt.js +27 -0
  13. package/esm/lib/agent/auth/agent-pow.d.ts +5 -0
  14. package/esm/lib/agent/auth/agent-pow.d.ts.map +1 -0
  15. package/esm/lib/agent/auth/agent-pow.js +49 -0
  16. package/esm/lib/agent/jmap/agent-help-content.d.ts +2 -0
  17. package/esm/lib/agent/jmap/agent-help-content.d.ts.map +1 -0
  18. package/esm/lib/agent/jmap/agent-help-content.js +2 -0
  19. package/esm/lib/agent/jmap/agent-jmap-blob-limits.d.ts +27 -0
  20. package/esm/lib/agent/jmap/agent-jmap-blob-limits.d.ts.map +1 -0
  21. package/esm/lib/agent/jmap/agent-jmap-blob-limits.js +166 -0
  22. package/esm/lib/agent/jmap/agent-jmap-blob-upload.d.ts +24 -0
  23. package/esm/lib/agent/jmap/agent-jmap-blob-upload.d.ts.map +1 -0
  24. package/esm/lib/agent/jmap/agent-jmap-blob-upload.js +104 -0
  25. package/esm/lib/agent/jmap/agent-jmap-email-charset.d.ts +8 -0
  26. package/esm/lib/agent/jmap/agent-jmap-email-charset.d.ts.map +1 -0
  27. package/esm/lib/agent/jmap/agent-jmap-email-charset.js +61 -0
  28. package/esm/lib/agent/jmap/agent-jmap-run.d.ts +52 -0
  29. package/esm/lib/agent/jmap/agent-jmap-run.d.ts.map +1 -0
  30. package/esm/lib/agent/jmap/agent-jmap-run.js +260 -0
  31. package/esm/lib/agent/jmap/agent-jmap-verify.d.ts +9 -0
  32. package/esm/lib/agent/jmap/agent-jmap-verify.d.ts.map +1 -0
  33. package/esm/lib/agent/jmap/agent-jmap-verify.js +50 -0
  34. package/esm/lib/agent/jmap/agent-jmap.d.ts +89 -0
  35. package/esm/lib/agent/jmap/agent-jmap.d.ts.map +1 -0
  36. package/esm/lib/agent/jmap/agent-jmap.js +373 -0
  37. package/esm/lib/agent/jmap/agent-vars.d.ts +30 -0
  38. package/esm/lib/agent/jmap/agent-vars.d.ts.map +1 -0
  39. package/esm/lib/agent/jmap/agent-vars.js +96 -0
  40. package/esm/lib/agent/jmap/help-content/auth.d.ts +2 -0
  41. package/esm/lib/agent/jmap/help-content/auth.d.ts.map +1 -0
  42. package/esm/lib/agent/jmap/help-content/auth.js +33 -0
  43. package/esm/lib/agent/jmap/help-content/cron.d.ts +6 -0
  44. package/esm/lib/agent/jmap/help-content/cron.d.ts.map +1 -0
  45. package/esm/lib/agent/jmap/help-content/cron.js +159 -0
  46. package/esm/lib/agent/jmap/help-content/index.d.ts +6 -0
  47. package/esm/lib/agent/jmap/help-content/index.d.ts.map +1 -0
  48. package/esm/lib/agent/jmap/help-content/index.js +61 -0
  49. package/esm/lib/agent/jmap/help-content/installation.d.ts +2 -0
  50. package/esm/lib/agent/jmap/help-content/installation.d.ts.map +1 -0
  51. package/esm/lib/agent/jmap/help-content/installation.js +47 -0
  52. package/esm/lib/agent/jmap/help-content/jmap-cheatsheet.d.ts +2 -0
  53. package/esm/lib/agent/jmap/help-content/jmap-cheatsheet.d.ts.map +1 -0
  54. package/esm/lib/agent/jmap/help-content/jmap-cheatsheet.js +230 -0
  55. package/esm/lib/agent/jmap/help-content/multi-account.d.ts +2 -0
  56. package/esm/lib/agent/jmap/help-content/multi-account.d.ts.map +1 -0
  57. package/esm/lib/agent/jmap/help-content/multi-account.js +49 -0
  58. package/esm/lib/agent/jmap/help-content/overview.d.ts +2 -0
  59. package/esm/lib/agent/jmap/help-content/overview.d.ts.map +1 -0
  60. package/esm/lib/agent/jmap/help-content/overview.js +49 -0
  61. package/esm/lib/agent/jmap/help-content/presets.d.ts +2 -0
  62. package/esm/lib/agent/jmap/help-content/presets.d.ts.map +1 -0
  63. package/esm/lib/agent/jmap/help-content/presets.js +51 -0
  64. package/esm/lib/agent/jmap/help-content/tools.d.ts +2 -0
  65. package/esm/lib/agent/jmap/help-content/tools.d.ts.map +1 -0
  66. package/esm/lib/agent/jmap/help-content/tools.js +49 -0
  67. package/esm/lib/agent/jmap/help-content/troubleshooting.d.ts +2 -0
  68. package/esm/lib/agent/jmap/help-content/troubleshooting.d.ts.map +1 -0
  69. package/esm/lib/agent/jmap/help-content/troubleshooting.js +65 -0
  70. package/esm/lib/agent/session/agent-credentials-store.d.ts +45 -0
  71. package/esm/lib/agent/session/agent-credentials-store.d.ts.map +1 -0
  72. package/esm/lib/agent/session/agent-credentials-store.js +121 -0
  73. package/esm/lib/agent/session/agent-resolve-config.d.ts +29 -0
  74. package/esm/lib/agent/session/agent-resolve-config.d.ts.map +1 -0
  75. package/esm/lib/agent/session/agent-resolve-config.js +71 -0
  76. package/esm/lib/agent/session/agent-session-for-dir.d.ts +8 -0
  77. package/esm/lib/agent/session/agent-session-for-dir.d.ts.map +1 -0
  78. package/esm/lib/agent/session/agent-session-for-dir.js +33 -0
  79. package/esm/lib/agent/session/agent-session.d.ts +89 -0
  80. package/esm/lib/agent/session/agent-session.d.ts.map +1 -0
  81. package/esm/lib/agent/session/agent-session.js +320 -0
  82. package/esm/lib/agent/session/inbox-id-to-mailbox-email.d.ts +6 -0
  83. package/esm/lib/agent/session/inbox-id-to-mailbox-email.d.ts.map +1 -0
  84. package/esm/lib/agent/session/inbox-id-to-mailbox-email.js +21 -0
  85. package/esm/lib/core/consts.d.ts +17 -0
  86. package/esm/lib/core/consts.d.ts.map +1 -0
  87. package/esm/lib/core/consts.js +28 -0
  88. package/esm/lib/core/jmap-hints.d.ts +3 -0
  89. package/esm/lib/core/jmap-hints.d.ts.map +1 -0
  90. package/esm/lib/core/jmap-hints.js +6 -0
  91. package/esm/lib/core/messages.d.ts +6 -0
  92. package/esm/lib/core/messages.d.ts.map +1 -0
  93. package/esm/lib/core/messages.js +19 -0
  94. package/esm/lib/core/read-npm-package-readme.d.ts +6 -0
  95. package/esm/lib/core/read-npm-package-readme.d.ts.map +1 -0
  96. package/esm/lib/core/read-npm-package-readme.js +81 -0
  97. package/esm/lib/core/shared-assets.d.ts +6 -0
  98. package/esm/lib/core/shared-assets.d.ts.map +1 -0
  99. package/esm/lib/core/shared-assets.js +46 -0
  100. package/esm/lib/core/types.d.ts +2 -0
  101. package/esm/lib/core/types.d.ts.map +1 -0
  102. package/esm/lib/core/types.js +2 -0
  103. package/esm/lib/core/utils.d.ts +12 -0
  104. package/esm/lib/core/utils.d.ts.map +1 -0
  105. package/esm/lib/core/utils.js +29 -0
  106. package/esm/lib/integrations/create-agent-session.d.ts +25 -0
  107. package/esm/lib/integrations/create-agent-session.d.ts.map +1 -0
  108. package/esm/lib/integrations/create-agent-session.js +36 -0
  109. package/esm/lib/integrations/key-value-credential-store.d.ts +21 -0
  110. package/esm/lib/integrations/key-value-credential-store.d.ts.map +1 -0
  111. package/esm/lib/integrations/key-value-credential-store.js +71 -0
  112. package/esm/lib/integrations/n8n-credential-store.d.ts +18 -0
  113. package/esm/lib/integrations/n8n-credential-store.d.ts.map +1 -0
  114. package/esm/lib/integrations/n8n-credential-store.js +62 -0
  115. package/esm/lib/mod.d.ts +23 -0
  116. package/esm/lib/mod.d.ts.map +1 -0
  117. package/esm/lib/mod.js +22 -0
  118. package/esm/lib/network/auth-client.d.ts +57 -0
  119. package/esm/lib/network/auth-client.d.ts.map +1 -0
  120. package/esm/lib/network/auth-client.js +210 -0
  121. package/esm/package.json +3 -0
  122. package/esm/skill/cli.d.ts +3 -0
  123. package/esm/skill/cli.d.ts.map +1 -0
  124. package/esm/skill/cli.js +321 -0
  125. package/package.json +45 -0
  126. package/presets/list_inbox.json +46 -0
  127. package/presets/reply.json +97 -0
  128. package/presets/send_mail.json +70 -0
  129. package/presets/send_mail_attachment.json +92 -0
  130. package/presets/send_mail_blob_attachment.json +74 -0
  131. package/shared/consts.json +11 -0
  132. package/shared/fixtures/pow_vectors.json +32 -0
  133. package/shared/help/fragments/inbox_cron_agent_prompt.md +1 -0
  134. package/shared/help/fragments/post_register_cron_reminder.md +5 -0
  135. package/shared/help/readme_stub.md +3 -0
  136. package/shared/help/topics/auth.md +8 -0
  137. package/shared/help/topics/cron.md +217 -0
  138. package/shared/help/topics/installation.md +35 -0
  139. package/shared/help/topics/jmap_cheatsheet.md +19 -0
  140. package/shared/help/topics/multi_account.md +9 -0
  141. package/shared/help/topics/overview.md +27 -0
  142. package/shared/help/topics/presets.md +12 -0
  143. package/shared/help/topics/tools.md +16 -0
  144. package/shared/help/topics/troubleshooting.md +6 -0
  145. package/shared/manifest.json +31 -0
  146. package/shared/messages/errors.json +68 -0
  147. package/shared/messages/hints.json +8 -0
  148. package/shared/presets/list_inbox.json +46 -0
  149. package/shared/presets/reply.json +97 -0
  150. package/shared/presets/send_mail.json +70 -0
  151. package/shared/presets/send_mail_attachment.json +92 -0
  152. package/shared/presets/send_mail_blob_attachment.json +74 -0
  153. package/shared/skill/SKILL.template.md +202 -0
  154. package/shared/skill/manifest.json +89 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-jmap-run.d.ts","sourceRoot":"","sources":["../../../../src/lib/agent/jmap/agent-jmap-run.ts"],"names":[],"mappings":"AAIA,OAAO,EAEL,KAAK,oBAAoB,EAC1B,MAAM,6BAA6B,CAAC;AAIrC,YAAY,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AAExE,eAAO,MAAM,kBAAkB,qEAGrB,CAAC;AAEX,eAAO,MAAM,wBAAwB,6HAM3B,CAAC;AAEX,eAAO,MAAM,aAAa,EAAG,2BAAoC,CAAC;AAClE,eAAO,MAAM,aAAa,EAAG,2BAAoC,CAAC;AAElE,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,WAAW,EAAE,OAAO,EAAE,CAAC;CACxB;AAED,wBAAgB,iBAAiB,CAC/B,GAAG,EAAE,MAAM,EACX,YAAY,EAAE,MAAM,EAAE,EACtB,MAAM,EAAE,MAAM,GACb,YAAY,CAyBd;AAED,wBAAgB,2BAA2B,CACzC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC/B,MAAM,CAcR;AAED,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC/B,iBAAiB,CAUnB;AAED,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAM1E;AAUD,wBAAgB,uBAAuB,CACrC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAChC,SAAS,EAAE,MAAM,GAChB,oBAAoB,GAAG,IAAI,CA0B7B;AAED,wBAAsB,kBAAkB,CACtC,MAAM,EAAE,MAAM,EACd,aAAa,EAAE,MAAM,GACpB,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAclC;AAED,oEAAoE;AACpE,MAAM,WAAW,0BAA0B;IACzC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,cAAc,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;IAClC,uBAAuB,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;IAC3C,kBAAkB,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;IACtC,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IACnC,QAAQ,CAAC,kBAAkB,CAAC,EAAE,MAAM,CAAC;IACrC,6BAA6B,CAC3B,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAAC,CAAC;CACzC;AAED,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,0BAA0B,CAAC;IACpC,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC/B;AAED,wBAAsB,cAAc,CAClC,KAAK,EAAE,mBAAmB,GACzB,OAAO,CAAC;IAAE,EAAE,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC,CAgE5D;AAED,wBAAsB,mBAAmB,CACvC,IAAI,EAAE,0BAA0B,GAC/B,OAAO,CAAC,MAAM,CAAC,CAuCjB;AAmCD,wBAAsB,QAAQ,CAC5B,WAAW,EAAE,MAAM,EACnB,aAAa,EAAE,MAAM,EACrB,QAAQ,EAAE,YAAY,GACrB,OAAO,CAAC;IAAE,EAAE,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC,CAW5D;AAED,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAU5D"}
@@ -0,0 +1,260 @@
1
+ // JMAP execution for integration hosts (n8n bundle) — fetch-only, no node:fs.
2
+ import { JMAP_NEXT_HINTS } from "../../core/jmap-hints.js";
3
+ import { inboxIdToMailboxEmail } from "../session/inbox-id-to-mailbox-email.js";
4
+ import { assertBlobUploadEnvelopeWithinLimits, } from "./agent-jmap-blob-limits.js";
5
+ import { ensureTextCharsetOnEmailSetBlobParts } from "./agent-jmap-email-charset.js";
6
+ import { substituteVars } from "./agent-vars.js";
7
+ export const DEFAULT_JMAP_USING = [
8
+ "urn:ietf:params:jmap:core",
9
+ "urn:ietf:params:jmap:mail",
10
+ ];
11
+ export const BUNDLED_OPS_PRESET_NAMES = [
12
+ "list_inbox.json",
13
+ "reply.json",
14
+ "send_mail.json",
15
+ "send_mail_attachment.json",
16
+ "send_mail_blob_attachment.json",
17
+ ];
18
+ export const JMAP_MAIL_URN = "urn:ietf:params:jmap:mail";
19
+ export const JMAP_BLOB_URN = "urn:ietf:params:jmap:blob";
20
+ export function parseJmapEnvelope(raw, defaultUsing, source) {
21
+ let value;
22
+ try {
23
+ value = JSON.parse(raw);
24
+ }
25
+ catch (err) {
26
+ throw new Error(`${source} is not valid JSON: ${err.message}`);
27
+ }
28
+ if (Array.isArray(value)) {
29
+ return { using: [...defaultUsing], methodCalls: value };
30
+ }
31
+ if (value !== null &&
32
+ typeof value === "object" &&
33
+ Array.isArray(value.methodCalls)) {
34
+ const obj = value;
35
+ const using = Array.isArray(obj.using)
36
+ ? obj.using.filter((u) => typeof u === "string")
37
+ : [...defaultUsing];
38
+ return { using, methodCalls: obj.methodCalls };
39
+ }
40
+ throw new Error(`${source} must be a methodCalls array, e.g. ` +
41
+ '[["Mailbox/get",{...},"m0"]], or an object with a methodCalls array.');
42
+ }
43
+ export function extractPrimaryMailAccountId(session) {
44
+ const primary = session["primaryAccounts"];
45
+ if (!primary || typeof primary !== "object") {
46
+ throw new Error("JMAP session missing primaryAccounts.");
47
+ }
48
+ const id = primary[JMAP_MAIL_URN];
49
+ if (typeof id !== "string" || id.length === 0) {
50
+ throw new Error(`JMAP session missing primaryAccounts['${JMAP_MAIL_URN}'].`);
51
+ }
52
+ return id;
53
+ }
54
+ export function extractBlobEndpoints(session) {
55
+ const uploadUrl = session["uploadUrl"];
56
+ const downloadUrl = session["downloadUrl"];
57
+ if (typeof uploadUrl !== "string" || uploadUrl.length === 0) {
58
+ throw new Error("JMAP session missing uploadUrl.");
59
+ }
60
+ if (typeof downloadUrl !== "string" || downloadUrl.length === 0) {
61
+ throw new Error("JMAP session missing downloadUrl.");
62
+ }
63
+ return { uploadUrl, downloadUrl };
64
+ }
65
+ export function extractJmapApiUrl(session) {
66
+ const u = session["apiUrl"];
67
+ if (typeof u !== "string" || u.length === 0) {
68
+ throw new Error("JMAP session missing apiUrl.");
69
+ }
70
+ return u;
71
+ }
72
+ function asNonNegativeInt(v) {
73
+ if (typeof v !== "number" || !Number.isFinite(v))
74
+ return undefined;
75
+ if (!Number.isInteger(v) || v < 0 || v > Number.MAX_SAFE_INTEGER) {
76
+ return undefined;
77
+ }
78
+ return v;
79
+ }
80
+ export function extractBlobUploadLimits(session, accountId) {
81
+ const accounts = session["accounts"];
82
+ if (!accounts || typeof accounts !== "object")
83
+ return null;
84
+ const acc = accounts[accountId];
85
+ if (!acc || typeof acc !== "object")
86
+ return null;
87
+ const caps = acc["accountCapabilities"];
88
+ if (!caps || typeof caps !== "object")
89
+ return null;
90
+ const blob = caps[JMAP_BLOB_URN];
91
+ if (!blob || typeof blob !== "object")
92
+ return null;
93
+ const b = blob;
94
+ let maxSizeBlobSet = null;
95
+ const rawMax = b["maxSizeBlobSet"];
96
+ if (rawMax === null) {
97
+ maxSizeBlobSet = null;
98
+ }
99
+ else {
100
+ const n = asNonNegativeInt(rawMax);
101
+ maxSizeBlobSet = n === undefined ? null : n;
102
+ }
103
+ const maxDs = asNonNegativeInt(b["maxDataSources"]);
104
+ const out = { maxSizeBlobSet };
105
+ if (maxDs !== undefined) {
106
+ out.maxDataSources = maxDs;
107
+ }
108
+ return out;
109
+ }
110
+ export async function fetchJmapWellKnown(apiUrl, capabilityJwt) {
111
+ const base = apiUrl.replace(/\/+$/, "");
112
+ const res = await fetch(`${base}/.well-known/jmap`, {
113
+ headers: { Authorization: `Bearer ${capabilityJwt}` },
114
+ });
115
+ const text = await res.text();
116
+ if (!res.ok) {
117
+ throw new Error(`JMAP session fetch failed (HTTP ${res.status}): ${text}`);
118
+ }
119
+ try {
120
+ return JSON.parse(text);
121
+ }
122
+ catch {
123
+ throw new Error("JMAP session response is not valid JSON.");
124
+ }
125
+ }
126
+ export async function runJmapRequest(input) {
127
+ const mergedVars = input.vars ?? {};
128
+ const { text: raw } = await substituteVars({
129
+ raw: input.opsJson,
130
+ vars: mergedVars,
131
+ autoResolvers: {
132
+ ACCOUNT_ID: () => input.session.getPrimaryMailAccountId(),
133
+ INBOX: async () => {
134
+ const rawInbox = input.session.currentInboxId;
135
+ if (!rawInbox) {
136
+ throw new Error("No inbox in session; run register first.");
137
+ }
138
+ return inboxIdToMailboxEmail(rawInbox);
139
+ },
140
+ INBOX_MAILBOX_ID: () => fetchInboxMailboxId(input.session),
141
+ UPLOAD_URL: async () => {
142
+ if (input.session.currentUploadUrl) {
143
+ return input.session.currentUploadUrl;
144
+ }
145
+ throw new Error("JMAP session missing uploadUrl.");
146
+ },
147
+ DOWNLOAD_URL: async () => {
148
+ if (input.session.currentDownloadUrl) {
149
+ return input.session.currentDownloadUrl;
150
+ }
151
+ throw new Error("JMAP session missing downloadUrl.");
152
+ },
153
+ },
154
+ });
155
+ const envelope = parseJmapEnvelope(raw, input.defaultUsing, input.sourceLabel);
156
+ ensureTextCharsetOnEmailSetBlobParts(envelope);
157
+ await enforceJmapBlobUploadLimitsIfApplicable(input.session, envelope);
158
+ const jmapPostUrl = await input.session.getJmapPostUrl();
159
+ if (input.dryRun) {
160
+ return {
161
+ ok: true,
162
+ status: 200,
163
+ bodyText: JSON.stringify({ dryRun: true, url: jmapPostUrl, envelope }, null, 2),
164
+ };
165
+ }
166
+ const capabilityJwt = await input.session.getCapabilityToken();
167
+ const { ok, status, bodyText } = await postJmap(jmapPostUrl, capabilityJwt, envelope);
168
+ if (!ok) {
169
+ return { ok, status, bodyText };
170
+ }
171
+ return { ok, status, bodyText: attachJmapNextHints(bodyText) };
172
+ }
173
+ export async function fetchInboxMailboxId(port) {
174
+ const accountId = await port.getPrimaryMailAccountId();
175
+ const capabilityJwt = await port.getCapabilityToken();
176
+ const envelope = {
177
+ using: ["urn:ietf:params:jmap:core", "urn:ietf:params:jmap:mail"],
178
+ methodCalls: [
179
+ ["Mailbox/query", { accountId, filter: { role: "inbox" } }, "mq0"],
180
+ ],
181
+ };
182
+ const jmapPostUrl = await port.getJmapPostUrl();
183
+ const { ok, status, bodyText } = await postJmap(jmapPostUrl, capabilityJwt, envelope);
184
+ if (!ok) {
185
+ throw new Error(`Mailbox/query failed (HTTP ${status}): ${bodyText}`);
186
+ }
187
+ let parsed;
188
+ try {
189
+ parsed = JSON.parse(bodyText);
190
+ }
191
+ catch {
192
+ throw new Error("Mailbox/query response is not valid JSON.");
193
+ }
194
+ const responses = parsed
195
+ .methodResponses;
196
+ const first = responses?.[0];
197
+ if (!Array.isArray(first) || first[0] === "error") {
198
+ throw new Error(`Mailbox/query failed: ${bodyText}`);
199
+ }
200
+ if (first[0] !== "Mailbox/query") {
201
+ throw new Error(`Mailbox/query failed: ${bodyText}`);
202
+ }
203
+ const payload = first[1];
204
+ const id = payload.ids?.[0];
205
+ if (typeof id !== "string" || id.length === 0) {
206
+ throw new Error("Mailbox/query returned no inbox mailbox id.");
207
+ }
208
+ return id;
209
+ }
210
+ function collectBlobUploadAccountIds(envelope) {
211
+ const ids = new Set();
212
+ for (const call of envelope.methodCalls) {
213
+ if (!Array.isArray(call) || call[0] !== "Blob/upload")
214
+ continue;
215
+ const arg = call[1];
216
+ if (!arg || typeof arg !== "object")
217
+ continue;
218
+ const aid = arg["accountId"];
219
+ if (typeof aid === "string" && aid.length > 0)
220
+ ids.add(aid);
221
+ }
222
+ return [...ids];
223
+ }
224
+ async function enforceJmapBlobUploadLimitsIfApplicable(session, envelope) {
225
+ if (!envelope.using.includes(JMAP_BLOB_URN))
226
+ return;
227
+ const hasUpload = envelope.methodCalls.some((c) => Array.isArray(c) && c[0] === "Blob/upload");
228
+ if (!hasUpload)
229
+ return;
230
+ const accountIds = collectBlobUploadAccountIds(envelope);
231
+ const limitsByAccount = new Map();
232
+ for (const id of accountIds) {
233
+ limitsByAccount.set(id, await session.getBlobUploadLimitsForAccount(id));
234
+ }
235
+ assertBlobUploadEnvelopeWithinLimits(envelope, limitsByAccount);
236
+ }
237
+ export async function postJmap(jmapPostUrl, capabilityJwt, envelope) {
238
+ const res = await fetch(jmapPostUrl, {
239
+ method: "POST",
240
+ headers: {
241
+ "Content-Type": "application/json",
242
+ Authorization: `Bearer ${capabilityJwt}`,
243
+ },
244
+ body: JSON.stringify(envelope),
245
+ });
246
+ const bodyText = await res.text();
247
+ return { ok: res.ok, status: res.status, bodyText };
248
+ }
249
+ export function attachJmapNextHints(bodyText) {
250
+ try {
251
+ const obj = JSON.parse(bodyText);
252
+ if (obj && typeof obj === "object" && !Array.isArray(obj)) {
253
+ return JSON.stringify({ ...obj, _next: [...JMAP_NEXT_HINTS] }, null, 2);
254
+ }
255
+ }
256
+ catch {
257
+ // not JSON
258
+ }
259
+ return bodyText;
260
+ }
@@ -0,0 +1,9 @@
1
+ /** Parse JMAP responses for integration tests and dev CLIs. */
2
+ /** Throws if `EmailSubmission/set` did not create a submission. */
3
+ export declare function assertJmapSubmissionCreated(bodyText: string): void;
4
+ /**
5
+ * Throws if the first `Blob/upload` response reports `size: 0` for a non-empty
6
+ * payload (common server misconfiguration).
7
+ */
8
+ export declare function assertBlobUploadSizesNonZero(bodyText: string, expectBytes: number): void;
9
+ //# sourceMappingURL=agent-jmap-verify.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-jmap-verify.d.ts","sourceRoot":"","sources":["../../../../src/lib/agent/jmap/agent-jmap-verify.ts"],"names":[],"mappings":"AAAA,+DAA+D;AAE/D,mEAAmE;AACnE,wBAAgB,2BAA2B,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAoBlE;AAED;;;GAGG;AACH,wBAAgB,4BAA4B,CAC1C,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM,GAClB,IAAI,CAwBN"}
@@ -0,0 +1,50 @@
1
+ /** Parse JMAP responses for integration tests and dev CLIs. */
2
+ /** Throws if `EmailSubmission/set` did not create a submission. */
3
+ export function assertJmapSubmissionCreated(bodyText) {
4
+ let parsed;
5
+ try {
6
+ parsed = JSON.parse(bodyText);
7
+ }
8
+ catch {
9
+ throw new Error("JMAP response was not JSON; cannot verify submission.");
10
+ }
11
+ const responses = parsed.methodResponses ?? [];
12
+ for (const r of responses) {
13
+ if (!Array.isArray(r) || r[0] !== "EmailSubmission/set")
14
+ continue;
15
+ const payload = r[1];
16
+ if (payload?.created && Object.keys(payload.created).length > 0) {
17
+ return;
18
+ }
19
+ }
20
+ throw new Error("EmailSubmission/set did not create a submission. Response:\n" + bodyText);
21
+ }
22
+ /**
23
+ * Throws if the first `Blob/upload` response reports `size: 0` for a non-empty
24
+ * payload (common server misconfiguration).
25
+ */
26
+ export function assertBlobUploadSizesNonZero(bodyText, expectBytes) {
27
+ if (expectBytes <= 0)
28
+ return;
29
+ let parsed;
30
+ try {
31
+ parsed = JSON.parse(bodyText);
32
+ }
33
+ catch {
34
+ return;
35
+ }
36
+ const first = parsed.methodResponses?.[0];
37
+ if (!Array.isArray(first) || first[0] !== "Blob/upload")
38
+ return;
39
+ const payload = first[1];
40
+ const created = payload?.created;
41
+ if (!created || typeof created !== "object")
42
+ return;
43
+ for (const v of Object.values(created)) {
44
+ const s = v?.size;
45
+ if (typeof s === "number" && s === 0) {
46
+ throw new Error("Blob/upload returned size 0 — this host is not persisting blob bytes. " +
47
+ "Fix the server, or use RFC 8620 binary upload when POST to uploadUrl works.");
48
+ }
49
+ }
50
+ }
@@ -0,0 +1,89 @@
1
+ import { type JmapBlobUploadLimits } from "./agent-jmap-blob-limits.js";
2
+ import { type JmapAttachmentInput } from "./agent-jmap-blob-upload.js";
3
+ export type { JmapAttachmentInput } from "./agent-jmap-blob-upload.js";
4
+ export type { JmapBlobUploadLimits } from "./agent-jmap-blob-limits.js";
5
+ export declare const DEFAULT_JMAP_USING: readonly ["urn:ietf:params:jmap:core", "urn:ietf:params:jmap:mail"];
6
+ export declare const BUNDLED_OPS_PRESET_NAMES: readonly ["list_inbox.json", "reply.json", "send_mail.json", "send_mail_attachment.json", "send_mail_blob_attachment.json"];
7
+ export declare const JMAP_MAIL_URN: "urn:ietf:params:jmap:mail";
8
+ /** RFC 9404 blob extension URN (Blob/upload, Blob/get, Blob/lookup). */
9
+ export declare const JMAP_BLOB_URN: "urn:ietf:params:jmap:blob";
10
+ export interface JmapEnvelope {
11
+ using: string[];
12
+ methodCalls: unknown[];
13
+ }
14
+ export declare function parseJmapEnvelope(raw: string, defaultUsing: string[], source: string): JmapEnvelope;
15
+ export declare function resolveOpsFilePath(credentialDir: string, opsFile: string): string;
16
+ export declare function readOpsFile(credentialDir: string, opsFile: string): Promise<string>;
17
+ export declare function extractPrimaryMailAccountId(session: Record<string, unknown>): string;
18
+ export interface JmapBlobEndpoints {
19
+ uploadUrl: string;
20
+ downloadUrl: string;
21
+ }
22
+ export declare function extractBlobEndpoints(session: Record<string, unknown>): JmapBlobEndpoints;
23
+ /** RFC 8620 §2 / §3.1: POST target for JMAP API calls from the Session object. */
24
+ export declare function extractJmapApiUrl(session: Record<string, unknown>): string;
25
+ /**
26
+ * RFC 9404 §3.1 blob limits for one account from GET /.well-known/jmap JSON.
27
+ * Returns null when the account does not advertise `urn:ietf:params:jmap:blob`.
28
+ */
29
+ export declare function extractBlobUploadLimits(session: Record<string, unknown>, accountId: string): JmapBlobUploadLimits | null;
30
+ export declare function fetchJmapWellKnown(apiUrl: string, capabilityJwt: string): Promise<Record<string, unknown>>;
31
+ /** Minimal surface for JMAP execution (implemented by AgentSession). */
32
+ export interface JmapSessionPort {
33
+ /** Base used for `GET /.well-known/jmap` (configured `ATOMIC_MAIL_API_URL` / credentials). */
34
+ readonly apiUrl: string;
35
+ readonly files?: {
36
+ credentialsFile: string;
37
+ };
38
+ /** RFC 8620 Session `apiUrl` — full URL for `POST` JMAP batches. */
39
+ getJmapPostUrl(): Promise<string>;
40
+ getPrimaryMailAccountId(): Promise<string>;
41
+ getCapabilityToken(): Promise<string>;
42
+ readonly currentInboxId?: string;
43
+ readonly currentUploadUrl?: string;
44
+ readonly currentDownloadUrl?: string;
45
+ /** RFC 9404 §3.1 limits from cached session; null if blob capability not advertised for the account. */
46
+ getBlobUploadLimitsForAccount(accountId: string): Promise<JmapBlobUploadLimits | null>;
47
+ }
48
+ export interface RunJmapRequestInput {
49
+ session: JmapSessionPort;
50
+ /** Raw JSON: methodCalls array or full envelope */
51
+ opsJson: string;
52
+ /** Default `using` when the envelope omits it */
53
+ defaultUsing: string[];
54
+ /** Label for parse errors */
55
+ sourceLabel: string;
56
+ dryRun?: boolean;
57
+ /**
58
+ * Local files uploaded via RFC 8620 (`POST` to session `uploadUrl`) before
59
+ * `$VAR` substitution. Injects `ATTACHMENT_0_BLOB_ID`, `ATTACHMENT_0_NAME`,
60
+ * `ATTACHMENT_0_TYPE`, `ATTACHMENT_0_SIZE`, … and `ATTACHMENT_COUNT`.
61
+ */
62
+ attachments?: JmapAttachmentInput[];
63
+ /** Base path for relative `attachments[].path` (default: process cwd). */
64
+ attachmentPathBase?: string;
65
+ /** Values for `$VAR` tokens (keys without `$`). Overrides injected attachment vars. */
66
+ vars?: Record<string, string>;
67
+ }
68
+ /**
69
+ * Parse ops JSON, substitute `$VAR_NAME` tokens (session + caller vars), POST to JMAP.
70
+ */
71
+ export declare function runJmapRequest(input: RunJmapRequestInput): Promise<{
72
+ ok: boolean;
73
+ status: number;
74
+ bodyText: string;
75
+ }>;
76
+ /**
77
+ * Resolves the JMAP `Mailbox` id for the account inbox (`role: "inbox"`).
78
+ * Used for `$INBOX_MAILBOX_ID` substitution (distinct from `$INBOX`, which is
79
+ * the mailbox *email address* — see `inboxIdToMailboxEmail` for normalization).
80
+ */
81
+ export declare function fetchInboxMailboxId(port: JmapSessionPort): Promise<string>;
82
+ export declare function postJmap(jmapPostUrl: string, capabilityJwt: string, envelope: JmapEnvelope): Promise<{
83
+ ok: boolean;
84
+ status: number;
85
+ bodyText: string;
86
+ }>;
87
+ /** Attach _next hints to a successful JMAP JSON object when parseable. */
88
+ export declare function attachJmapNextHints(bodyText: string): string;
89
+ //# sourceMappingURL=agent-jmap.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-jmap.d.ts","sourceRoot":"","sources":["../../../../src/lib/agent/jmap/agent-jmap.ts"],"names":[],"mappings":"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"}