@atomicmail/langchain 0.3.14

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 (138) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +77 -0
  3. package/esm/_dnt.polyfills.d.ts +101 -0
  4. package/esm/_dnt.polyfills.d.ts.map +1 -0
  5. package/esm/_dnt.polyfills.js +127 -0
  6. package/esm/langchain/mod.d.ts +23 -0
  7. package/esm/langchain/mod.d.ts.map +1 -0
  8. package/esm/langchain/mod.js +157 -0
  9. package/esm/lib/agent/auth/agent-auth-http.d.ts +26 -0
  10. package/esm/lib/agent/auth/agent-auth-http.d.ts.map +1 -0
  11. package/esm/lib/agent/auth/agent-auth-http.js +85 -0
  12. package/esm/lib/agent/auth/agent-jwt.d.ts +12 -0
  13. package/esm/lib/agent/auth/agent-jwt.d.ts.map +1 -0
  14. package/esm/lib/agent/auth/agent-jwt.js +27 -0
  15. package/esm/lib/agent/auth/agent-pow.d.ts +5 -0
  16. package/esm/lib/agent/auth/agent-pow.d.ts.map +1 -0
  17. package/esm/lib/agent/auth/agent-pow.js +49 -0
  18. package/esm/lib/agent/jmap/agent-help-content.d.ts +2 -0
  19. package/esm/lib/agent/jmap/agent-help-content.d.ts.map +1 -0
  20. package/esm/lib/agent/jmap/agent-help-content.js +2 -0
  21. package/esm/lib/agent/jmap/agent-jmap-blob-limits.d.ts +27 -0
  22. package/esm/lib/agent/jmap/agent-jmap-blob-limits.d.ts.map +1 -0
  23. package/esm/lib/agent/jmap/agent-jmap-blob-limits.js +166 -0
  24. package/esm/lib/agent/jmap/agent-jmap-blob-upload.d.ts +24 -0
  25. package/esm/lib/agent/jmap/agent-jmap-blob-upload.d.ts.map +1 -0
  26. package/esm/lib/agent/jmap/agent-jmap-blob-upload.js +104 -0
  27. package/esm/lib/agent/jmap/agent-jmap-email-charset.d.ts +8 -0
  28. package/esm/lib/agent/jmap/agent-jmap-email-charset.d.ts.map +1 -0
  29. package/esm/lib/agent/jmap/agent-jmap-email-charset.js +61 -0
  30. package/esm/lib/agent/jmap/agent-jmap-verify.d.ts +9 -0
  31. package/esm/lib/agent/jmap/agent-jmap-verify.d.ts.map +1 -0
  32. package/esm/lib/agent/jmap/agent-jmap-verify.js +50 -0
  33. package/esm/lib/agent/jmap/agent-jmap.d.ts +89 -0
  34. package/esm/lib/agent/jmap/agent-jmap.d.ts.map +1 -0
  35. package/esm/lib/agent/jmap/agent-jmap.js +373 -0
  36. package/esm/lib/agent/jmap/agent-vars.d.ts +30 -0
  37. package/esm/lib/agent/jmap/agent-vars.d.ts.map +1 -0
  38. package/esm/lib/agent/jmap/agent-vars.js +96 -0
  39. package/esm/lib/agent/jmap/help-content/auth.d.ts +2 -0
  40. package/esm/lib/agent/jmap/help-content/auth.d.ts.map +1 -0
  41. package/esm/lib/agent/jmap/help-content/auth.js +33 -0
  42. package/esm/lib/agent/jmap/help-content/cron.d.ts +6 -0
  43. package/esm/lib/agent/jmap/help-content/cron.d.ts.map +1 -0
  44. package/esm/lib/agent/jmap/help-content/cron.js +159 -0
  45. package/esm/lib/agent/jmap/help-content/index.d.ts +6 -0
  46. package/esm/lib/agent/jmap/help-content/index.d.ts.map +1 -0
  47. package/esm/lib/agent/jmap/help-content/index.js +61 -0
  48. package/esm/lib/agent/jmap/help-content/installation.d.ts +2 -0
  49. package/esm/lib/agent/jmap/help-content/installation.d.ts.map +1 -0
  50. package/esm/lib/agent/jmap/help-content/installation.js +47 -0
  51. package/esm/lib/agent/jmap/help-content/jmap-cheatsheet.d.ts +2 -0
  52. package/esm/lib/agent/jmap/help-content/jmap-cheatsheet.d.ts.map +1 -0
  53. package/esm/lib/agent/jmap/help-content/jmap-cheatsheet.js +230 -0
  54. package/esm/lib/agent/jmap/help-content/multi-account.d.ts +2 -0
  55. package/esm/lib/agent/jmap/help-content/multi-account.d.ts.map +1 -0
  56. package/esm/lib/agent/jmap/help-content/multi-account.js +49 -0
  57. package/esm/lib/agent/jmap/help-content/overview.d.ts +2 -0
  58. package/esm/lib/agent/jmap/help-content/overview.d.ts.map +1 -0
  59. package/esm/lib/agent/jmap/help-content/overview.js +49 -0
  60. package/esm/lib/agent/jmap/help-content/presets.d.ts +2 -0
  61. package/esm/lib/agent/jmap/help-content/presets.d.ts.map +1 -0
  62. package/esm/lib/agent/jmap/help-content/presets.js +51 -0
  63. package/esm/lib/agent/jmap/help-content/tools.d.ts +2 -0
  64. package/esm/lib/agent/jmap/help-content/tools.d.ts.map +1 -0
  65. package/esm/lib/agent/jmap/help-content/tools.js +49 -0
  66. package/esm/lib/agent/jmap/help-content/troubleshooting.d.ts +2 -0
  67. package/esm/lib/agent/jmap/help-content/troubleshooting.d.ts.map +1 -0
  68. package/esm/lib/agent/jmap/help-content/troubleshooting.js +65 -0
  69. package/esm/lib/agent/session/agent-credentials-store.d.ts +45 -0
  70. package/esm/lib/agent/session/agent-credentials-store.d.ts.map +1 -0
  71. package/esm/lib/agent/session/agent-credentials-store.js +121 -0
  72. package/esm/lib/agent/session/agent-resolve-config.d.ts +29 -0
  73. package/esm/lib/agent/session/agent-resolve-config.d.ts.map +1 -0
  74. package/esm/lib/agent/session/agent-resolve-config.js +71 -0
  75. package/esm/lib/agent/session/agent-session-for-dir.d.ts +8 -0
  76. package/esm/lib/agent/session/agent-session-for-dir.d.ts.map +1 -0
  77. package/esm/lib/agent/session/agent-session-for-dir.js +33 -0
  78. package/esm/lib/agent/session/agent-session.d.ts +89 -0
  79. package/esm/lib/agent/session/agent-session.d.ts.map +1 -0
  80. package/esm/lib/agent/session/agent-session.js +320 -0
  81. package/esm/lib/agent/session/inbox-id-to-mailbox-email.d.ts +6 -0
  82. package/esm/lib/agent/session/inbox-id-to-mailbox-email.d.ts.map +1 -0
  83. package/esm/lib/agent/session/inbox-id-to-mailbox-email.js +24 -0
  84. package/esm/lib/core/consts.d.ts +17 -0
  85. package/esm/lib/core/consts.d.ts.map +1 -0
  86. package/esm/lib/core/consts.js +28 -0
  87. package/esm/lib/core/messages.d.ts +6 -0
  88. package/esm/lib/core/messages.d.ts.map +1 -0
  89. package/esm/lib/core/messages.js +19 -0
  90. package/esm/lib/core/read-npm-package-readme.d.ts +6 -0
  91. package/esm/lib/core/read-npm-package-readme.d.ts.map +1 -0
  92. package/esm/lib/core/read-npm-package-readme.js +81 -0
  93. package/esm/lib/core/shared-assets.d.ts +6 -0
  94. package/esm/lib/core/shared-assets.d.ts.map +1 -0
  95. package/esm/lib/core/shared-assets.js +46 -0
  96. package/esm/lib/core/types.d.ts +2 -0
  97. package/esm/lib/core/types.d.ts.map +1 -0
  98. package/esm/lib/core/types.js +2 -0
  99. package/esm/lib/core/utils.d.ts +12 -0
  100. package/esm/lib/core/utils.d.ts.map +1 -0
  101. package/esm/lib/core/utils.js +29 -0
  102. package/esm/lib/mod.d.ts +20 -0
  103. package/esm/lib/mod.d.ts.map +1 -0
  104. package/esm/lib/mod.js +19 -0
  105. package/esm/lib/network/auth-client.d.ts +57 -0
  106. package/esm/lib/network/auth-client.d.ts.map +1 -0
  107. package/esm/lib/network/auth-client.js +210 -0
  108. package/esm/package.json +3 -0
  109. package/package.json +51 -0
  110. package/presets/list_inbox.json +46 -0
  111. package/presets/reply.json +97 -0
  112. package/presets/send_mail.json +70 -0
  113. package/presets/send_mail_attachment.json +92 -0
  114. package/presets/send_mail_blob_attachment.json +74 -0
  115. package/shared/consts.json +11 -0
  116. package/shared/fixtures/pow_vectors.json +32 -0
  117. package/shared/help/fragments/inbox_cron_agent_prompt.md +1 -0
  118. package/shared/help/fragments/post_register_cron_reminder.md +5 -0
  119. package/shared/help/readme_stub.md +3 -0
  120. package/shared/help/topics/auth.md +8 -0
  121. package/shared/help/topics/cron.md +217 -0
  122. package/shared/help/topics/installation.md +35 -0
  123. package/shared/help/topics/jmap_cheatsheet.md +19 -0
  124. package/shared/help/topics/multi_account.md +9 -0
  125. package/shared/help/topics/overview.md +27 -0
  126. package/shared/help/topics/presets.md +12 -0
  127. package/shared/help/topics/tools.md +16 -0
  128. package/shared/help/topics/troubleshooting.md +6 -0
  129. package/shared/manifest.json +31 -0
  130. package/shared/messages/errors.json +68 -0
  131. package/shared/messages/hints.json +8 -0
  132. package/shared/presets/list_inbox.json +46 -0
  133. package/shared/presets/reply.json +97 -0
  134. package/shared/presets/send_mail.json +70 -0
  135. package/shared/presets/send_mail_attachment.json +92 -0
  136. package/shared/presets/send_mail_blob_attachment.json +74 -0
  137. package/shared/skill/SKILL.template.md +202 -0
  138. package/shared/skill/manifest.json +89 -0
@@ -0,0 +1,49 @@
1
+ // Help topic: overview (MCP help / AgentSkill help).
2
+ import { postRegisterCronReminder } from "./cron.js";
3
+ export const helpTopicOverview = `\
4
+ # Atomic Mail — Overview
5
+
6
+ Atomic Mail is an email service provider (ESP) designed for AI agents. You
7
+ manage mail over JMAP (RFC 8620 + RFC 8621).
8
+
9
+ ## Public surface (identical for MCP and AgentSkill)
10
+
11
+ Three operations only:
12
+
13
+ 1. **register** — Proof-of-work signup (or idempotent replay when the same
14
+ username matches the inbox already on disk). Usernames are 5–21 characters
15
+ (local-part of \`@atomicmail.ai\`). When a different username is
16
+ requested and credentials already exist, register fails unless you use a
17
+ separate \`credentials_dir\` / \`--credentials-dir\` or pass \`forced: true\`
18
+ / \`--forced\` to replace the current directory. Persists
19
+ credentials and returns \`{ inbox, accountId }\` (and \`apiKey\` on first
20
+ signup).
21
+ 2. **jmap_request** — Send a JMAP method-call batch; auth and JWT rotation are
22
+ automatic. Pass inline \`ops\` JSON or an \`ops_file\` preset (same
23
+ substitution for both). Session-backed tokens (\`$ACCOUNT_ID\`, \`$INBOX\`,
24
+ \`$INBOX_MAILBOX_ID\`, \`$UPLOAD_URL\`, \`$DOWNLOAD_URL\`) resolve from
25
+ credentials and JMAP session (\`$INBOX\` is always a full mailbox address;
26
+ \`$INBOX_MAILBOX_ID\` is the inbox **mailbox id** for filters and
27
+ \`mailboxIds\` — see **presets** topic). Pass any other \`$NAME\` via MCP
28
+ \`vars\` or \`--vars\`. Optional **attachments** (MCP \`attachments\`, skill
29
+ \`--attachment\`): each file is uploaded to \`uploadUrl\` (RFC 8620), then
30
+ \`$ATTACHMENT_0_BLOB_ID\`, … are substituted into your JMAP JSON.
31
+ 3. **help** — This documentation (optional \`topic\` / \`--topic\`), or the
32
+ published package README (\`topic\` / \`--topic\` \`readme\`).
33
+
34
+ ## Typical workflow
35
+
36
+ 1. \`register\` with a username (5–21 characters).
37
+ 2. After register, arrange hourly inbox polling per your runtime (see **cron**
38
+ topic — native scheduler if available; otherwise ask your operator or remind
39
+ manual fetch). Do not cron \`atomicmail jmap_request\` alone.
40
+ 3. \`jmap_request\` with JMAP method calls (presets may use \`$VAR_NAME\`; pass
41
+ custom values in \`vars\` / \`--vars\`).
42
+ 4. Call \`help\` early and often — before guessing JMAP or preset details, not
43
+ only when stuck. Prefer \`help\` over general JMAP knowledge; topics match
44
+ this package version.
45
+
46
+ ${postRegisterCronReminder}
47
+
48
+ Available topics: overview, installation, auth, jmap_cheatsheet, tools,
49
+ presets, cron, multi_account, troubleshooting. Use \`readme\` for the npm package \`README.md\`.`;
@@ -0,0 +1,2 @@
1
+ export declare const helpTopicPresets = "# JMAP presets\n\nSave a method-call array or a full `{ \"using\", \"methodCalls\" }` envelope\nas JSON, then pass `ops_file` (MCP) or `--ops-file` (skill).\n\nRelative paths first resolve against the credential directory (MCP) or current\n`--credentials-dir` (skill). If not found, the runtime falls back to bundled\npresets that ship in both npm packages.\n\n## Bundled presets\n\n- `send_mail.json` \u2014 sends one email using `$TO`, `$SUBJECT`, `$BODY`.\n- `list_inbox.json` \u2014 latest 50 inbox messages (uses `$INBOX_MAILBOX_ID`).\n **Use this preset for hourly inbox polling** (see **cron** topic).\n- `reply.json` \u2014 replies in-thread using `$MAIL_ID` and `$BODY`.\n- `send_mail_attachment.json` \u2014 `Blob/upload` + send; `vars`: `TO`,\n `SUBJECT`, `BODY`, `ATTACHMENT_BASE64`, `ATTACHMENT_TYPE`,\n `ATTACHMENT_NAME`. Fine for modest sizes; large files should use RFC 8620\n upload instead (see `send_mail_blob_attachment.json`).\n- `send_mail_blob_attachment.json` \u2014 one attachment whose `blobId` comes from\n `$ATTACHMENT_0_BLOB_ID` (etc.). Use with MCP `attachments` or skill\n `--attachment PATH` so the client uploads files to `uploadUrl` before the\n batch; `vars`: `TO`, `SUBJECT`, `BODY`. For `text/*` parts referenced\n by `blobId`, the client adds `charset` (default `utf-8`) when omitted (RFC\n 8621). For several files in one `Email/set`, write normal JMAP JSON\n referencing `$ATTACHMENT_1_BLOB_ID`, \u2026\n\n## Placeholders\n\nSyntax: `$VAR_NAME` where `VAR_NAME` matches `/^[A-Z][A-Z0-9_]*$/` (so JMAP\nkeywords like `$draft` stay untouched).\n\n- `$ACCOUNT_ID` \u2014 primary mail account id (from `GET /.well-known/jmap` when\n referenced).\n- `$INBOX` \u2014 inbox email address from credentials.\n- `$INBOX_MAILBOX_ID` \u2014 JMAP mailbox id for the inbox (extra `Mailbox/query`;\n use for `Email/query` / `Email/set` where the API wants a mailbox id).\n- `$UPLOAD_URL` \u2014 RFC 8620 upload URL template from JMAP session.\n- `$DOWNLOAD_URL` \u2014 RFC 8620 download URL template from JMAP session.\n- Any other `$FOO` \u2014 must appear in MCP `vars` or skill `--vars` as\n `\"FOO\": \"...\"` (string values only; JSON escaping in the preset body is your\n responsibility).\n- `$ATTACHMENT_N_BLOB_ID`, `$ATTACHMENT_N_NAME`, `$ATTACHMENT_N_TYPE`,\n `$ATTACHMENT_N_SIZE` (N = 0, 1, \u2026) and `$ATTACHMENT_COUNT` \u2014 injected when\n you pass MCP `attachments` or skill `--attachment`; you can still override\n them in `vars` / `--vars` if needed.\n\nYou may override `ACCOUNT_ID` / `INBOX` / `INBOX_MAILBOX_ID` /\n`UPLOAD_URL` / `DOWNLOAD_URL` via `vars` / `--vars` if needed.";
2
+ //# sourceMappingURL=presets.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"presets.d.ts","sourceRoot":"","sources":["../../../../../src/lib/agent/jmap/help-content/presets.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,gBAAgB,slFAiD0C,CAAC"}
@@ -0,0 +1,51 @@
1
+ // Help topic: presets (MCP help / AgentSkill help).
2
+ export const helpTopicPresets = `\
3
+ # JMAP presets
4
+
5
+ Save a method-call array or a full \`{ "using", "methodCalls" }\` envelope
6
+ as JSON, then pass \`ops_file\` (MCP) or \`--ops-file\` (skill).
7
+
8
+ Relative paths first resolve against the credential directory (MCP) or current
9
+ \`--credentials-dir\` (skill). If not found, the runtime falls back to bundled
10
+ presets that ship in both npm packages.
11
+
12
+ ## Bundled presets
13
+
14
+ - \`send_mail.json\` — sends one email using \`$TO\`, \`$SUBJECT\`, \`$BODY\`.
15
+ - \`list_inbox.json\` — latest 50 inbox messages (uses \`$INBOX_MAILBOX_ID\`).
16
+ **Use this preset for hourly inbox polling** (see **cron** topic).
17
+ - \`reply.json\` — replies in-thread using \`$MAIL_ID\` and \`$BODY\`.
18
+ - \`send_mail_attachment.json\` — \`Blob/upload\` + send; \`vars\`: \`TO\`,
19
+ \`SUBJECT\`, \`BODY\`, \`ATTACHMENT_BASE64\`, \`ATTACHMENT_TYPE\`,
20
+ \`ATTACHMENT_NAME\`. Fine for modest sizes; large files should use RFC 8620
21
+ upload instead (see \`send_mail_blob_attachment.json\`).
22
+ - \`send_mail_blob_attachment.json\` — one attachment whose \`blobId\` comes from
23
+ \`$ATTACHMENT_0_BLOB_ID\` (etc.). Use with MCP \`attachments\` or skill
24
+ \`--attachment PATH\` so the client uploads files to \`uploadUrl\` before the
25
+ batch; \`vars\`: \`TO\`, \`SUBJECT\`, \`BODY\`. For \`text/*\` parts referenced
26
+ by \`blobId\`, the client adds \`charset\` (default \`utf-8\`) when omitted (RFC
27
+ 8621). For several files in one \`Email/set\`, write normal JMAP JSON
28
+ referencing \`$ATTACHMENT_1_BLOB_ID\`, …
29
+
30
+ ## Placeholders
31
+
32
+ Syntax: \`$VAR_NAME\` where \`VAR_NAME\` matches \`/^[A-Z][A-Z0-9_]*$/\` (so JMAP
33
+ keywords like \`$draft\` stay untouched).
34
+
35
+ - \`$ACCOUNT_ID\` — primary mail account id (from \`GET /.well-known/jmap\` when
36
+ referenced).
37
+ - \`$INBOX\` — inbox email address from credentials.
38
+ - \`$INBOX_MAILBOX_ID\` — JMAP mailbox id for the inbox (extra \`Mailbox/query\`;
39
+ use for \`Email/query\` / \`Email/set\` where the API wants a mailbox id).
40
+ - \`$UPLOAD_URL\` — RFC 8620 upload URL template from JMAP session.
41
+ - \`$DOWNLOAD_URL\` — RFC 8620 download URL template from JMAP session.
42
+ - Any other \`$FOO\` — must appear in MCP \`vars\` or skill \`--vars\` as
43
+ \`"FOO": "..."\` (string values only; JSON escaping in the preset body is your
44
+ responsibility).
45
+ - \`$ATTACHMENT_N_BLOB_ID\`, \`$ATTACHMENT_N_NAME\`, \`$ATTACHMENT_N_TYPE\`,
46
+ \`$ATTACHMENT_N_SIZE\` (N = 0, 1, …) and \`$ATTACHMENT_COUNT\` — injected when
47
+ you pass MCP \`attachments\` or skill \`--attachment\`; you can still override
48
+ them in \`vars\` / \`--vars\` if needed.
49
+
50
+ You may override \`ACCOUNT_ID\` / \`INBOX\` / \`INBOX_MAILBOX_ID\` /
51
+ \`UPLOAD_URL\` / \`DOWNLOAD_URL\` via \`vars\` / \`--vars\` if needed.`;
@@ -0,0 +1,2 @@
1
+ export declare const helpTopicTools = "# Tool / CLI reference\n\n## register\n\n**MCP input:** `{ \"username\": string, \"credentials_dir\"?: string, \"forced\"?: boolean }` \n**Skill:** `register --username NAME [--credentials-dir DIR] [--forced]` (or `--api-key KEY`).\n\nUsernames must be 5\u201321 characters (local-part of your `@atomicmail.ai`\naddress).\n\nCreates an inbox or returns the same `{ inbox, accountId }` when the\nusername matches the stored inbox local-part. A **different** username\nfails by default to protect existing credentials. To add another account without\nreplacing the current one, pass a **separate** `credentials_dir` (MCP) or\n`--credentials-dir` (skill) \u2014 see **multi_account** topic. To replace\ncredentials in the **same** directory, pass **`forced: true`** (MCP) or\n**`--forced`** (skill) explicitly after backing up.\n\n**After a successful register,** arrange hourly inbox polling per your runtime\n(see **cron** topic \u2014 native cron hosts schedule an agent turn with\n`list_inbox.json`; no-native-cron hosts ask the operator or remind manual\nfetch).\n\n## jmap_request\n\n**MCP input:** `{ \"credentials_dir\"?: string, \"using\"?: string[], \"ops\"?: string, \"ops_file\"?: string,\n\"vars\"?: Record<string, string>, \"attachments\"?: { path, filename?, content_type? }[] }` \u2014\nkeys in `vars` are names without `$` (e.g. `TO` for `$TO`). Exactly one of\n`ops` or `ops_file`. When `attachments` is non-empty, each path is read on\nthe MCP host, `POST`ed to JMAP `uploadUrl` (RFC 8620), then\n`$ATTACHMENT_N_BLOB_ID` / `$ATTACHMENT_N_NAME` / `$ATTACHMENT_N_TYPE` /\n`$ATTACHMENT_N_SIZE` and `$ATTACHMENT_COUNT` are available in `ops` (same\nsemantics as if you had pasted those strings in `vars`).\n\n**Skill:** `jmap_request --ops '...'` or `--ops-file path` plus\n`--credentials-dir` (optional), plus optional `--vars '<json>'`,\n`--attachment PATH` (repeatable), `--attachment-path-base DIR`, `--using`,\n`--dry-run` (not with `--attachment`).\n\n## help\n\n**MCP:** `{ \"topic\"?: string }` \n**Skill:** `help [--topic TOPIC]`\n\nTopics: overview, installation, auth, jmap_cheatsheet, tools, presets, cron,\nmulti_account, troubleshooting. Topic `readme` prints the published package `README.md`\n(same layout as npm; requires install from npm).";
2
+ //# sourceMappingURL=tools.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../../../../../src/lib/agent/jmap/help-content/tools.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,cAAc,ouEA+CsB,CAAC"}
@@ -0,0 +1,49 @@
1
+ // Help topic: tools (MCP help / AgentSkill help).
2
+ export const helpTopicTools = `\
3
+ # Tool / CLI reference
4
+
5
+ ## register
6
+
7
+ **MCP input:** \`{ "username": string, "credentials_dir"?: string, "forced"?: boolean }\`
8
+ **Skill:** \`register --username NAME [--credentials-dir DIR] [--forced]\` (or \`--api-key KEY\`).
9
+
10
+ Usernames must be 5–21 characters (local-part of your \`@atomicmail.ai\`
11
+ address).
12
+
13
+ Creates an inbox or returns the same \`{ inbox, accountId }\` when the
14
+ username matches the stored inbox local-part. A **different** username
15
+ fails by default to protect existing credentials. To add another account without
16
+ replacing the current one, pass a **separate** \`credentials_dir\` (MCP) or
17
+ \`--credentials-dir\` (skill) — see **multi_account** topic. To replace
18
+ credentials in the **same** directory, pass **\`forced: true\`** (MCP) or
19
+ **\`--forced\`** (skill) explicitly after backing up.
20
+
21
+ **After a successful register,** arrange hourly inbox polling per your runtime
22
+ (see **cron** topic — native cron hosts schedule an agent turn with
23
+ \`list_inbox.json\`; no-native-cron hosts ask the operator or remind manual
24
+ fetch).
25
+
26
+ ## jmap_request
27
+
28
+ **MCP input:** \`{ "credentials_dir"?: string, "using"?: string[], "ops"?: string, "ops_file"?: string,
29
+ "vars"?: Record<string, string>, "attachments"?: { path, filename?, content_type? }[] }\` —
30
+ keys in \`vars\` are names without \`$\` (e.g. \`TO\` for \`$TO\`). Exactly one of
31
+ \`ops\` or \`ops_file\`. When \`attachments\` is non-empty, each path is read on
32
+ the MCP host, \`POST\`ed to JMAP \`uploadUrl\` (RFC 8620), then
33
+ \`$ATTACHMENT_N_BLOB_ID\` / \`$ATTACHMENT_N_NAME\` / \`$ATTACHMENT_N_TYPE\` /
34
+ \`$ATTACHMENT_N_SIZE\` and \`$ATTACHMENT_COUNT\` are available in \`ops\` (same
35
+ semantics as if you had pasted those strings in \`vars\`).
36
+
37
+ **Skill:** \`jmap_request --ops '...'\` or \`--ops-file path\` plus
38
+ \`--credentials-dir\` (optional), plus optional \`--vars '<json>'\`,
39
+ \`--attachment PATH\` (repeatable), \`--attachment-path-base DIR\`, \`--using\`,
40
+ \`--dry-run\` (not with \`--attachment\`).
41
+
42
+ ## help
43
+
44
+ **MCP:** \`{ "topic"?: string }\`
45
+ **Skill:** \`help [--topic TOPIC]\`
46
+
47
+ Topics: overview, installation, auth, jmap_cheatsheet, tools, presets, cron,
48
+ multi_account, troubleshooting. Topic \`readme\` prints the published package \`README.md\`
49
+ (same layout as npm; requires install from npm).`;
@@ -0,0 +1,2 @@
1
+ export declare const helpTopicTroubleshooting = "# Troubleshooting\n\n## Custom endpoint configuration issues\n\nDefaults are production endpoints. Set env vars only for custom deployments.\n\n## No API key / register first\n\nRun `register`, or set `ATOMIC_MAIL_API_KEY`, or copy an existing\n`credentials.json` into the credential directory.\n\n## auth-service /api/v1/session returned 401\n\nInvalid `apiKey` or wrong `ATOMIC_MAIL_SCRYPT_SALT` for this deployment.\n\n## Capability JWT missing inboxId\n\nServer/version mismatch \u2014 verify `ATOMIC_MAIL_AUTH_URL`.\n\n## Could not read ops file\n\nCheck the path; use an absolute path if unsure.\n\n## Missing values for variables (`$TO`, etc.)\n\nPass every custom placeholder in MCP `vars` or `--vars` as a JSON object of\nstrings. Ensure `register` completed so `$ACCOUNT_ID` / `$INBOX` can resolve.\n\n## `invalidArguments` on `Email/query` / `filter/inMailbox`\n\n`inMailbox` must be a **mailbox id**, not your inbox email. Use the built-in\n`$INBOX_MAILBOX_ID` placeholder (or run `Mailbox/get` / `Mailbox/query` and\npaste the id into `vars`).\n\n## `invalidProperties` / `notCreated` on `Blob/upload`\n\nRFC 9404 requires `data` as an **array** of objects, each with **exactly one**\nof `data:asText`, `data:asBase64`, or a `blobId` slice. Typical mistakes:\n`data` as a raw string; `data:asBase64` on the upload object instead of\ninside an array element; mixing two forms in one object. See topic\n`jmap_cheatsheet` (`Blob/upload` shape) and preset `send_mail_attachment.json`.\n\n## RFC 8620 binary `POST` to `uploadUrl` returns 404\n\nThe session lists an `uploadUrl` template, but your deployment must expose\nthat HTTP resource. If `POST` returns 404, out-of-band upload is not wired\non the server \u2014 use `Blob/upload` in JMAP instead, or fix the API gateway.\n\n## `Blob/upload` succeeds but `size` is 0 (or `Email/set` rejects the blob)\n\nThe server accepted the method but did not persist octets (broken or\nincomplete `Blob/upload`). Verify with a tiny `data: [{ \"data:asBase64\": \"QQ==\" }]`\npayload; if `size`\nstays 0, fix the JMAP/blob implementation on the host before sending\nattachments.\n\n## Installed package vs other documentation\n\nThe version you get from `npx -y @atomicmail/mcp` or\n`npx --package=@atomicmail/agent-skill \u2026` may lag behind other published docs.\nIf something disagrees, trust **your installed package**: run `help` and use\nthe bundled presets that ship with that version. In MCP runtimes, `help` with\ntopic `readme` returns package README.md.";
2
+ //# sourceMappingURL=troubleshooting.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"troubleshooting.d.ts","sourceRoot":"","sources":["../../../../../src/lib/agent/jmap/help-content/troubleshooting.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,wBAAwB,y9EA+DO,CAAC"}
@@ -0,0 +1,65 @@
1
+ // Help topic: troubleshooting (MCP help / AgentSkill help).
2
+ export const helpTopicTroubleshooting = `\
3
+ # Troubleshooting
4
+
5
+ ## Custom endpoint configuration issues
6
+
7
+ Defaults are production endpoints. Set env vars only for custom deployments.
8
+
9
+ ## No API key / register first
10
+
11
+ Run \`register\`, or set \`ATOMIC_MAIL_API_KEY\`, or copy an existing
12
+ \`credentials.json\` into the credential directory.
13
+
14
+ ## auth-service /api/v1/session returned 401
15
+
16
+ Invalid \`apiKey\` or wrong \`ATOMIC_MAIL_SCRYPT_SALT\` for this deployment.
17
+
18
+ ## Capability JWT missing inboxId
19
+
20
+ Server/version mismatch — verify \`ATOMIC_MAIL_AUTH_URL\`.
21
+
22
+ ## Could not read ops file
23
+
24
+ Check the path; use an absolute path if unsure.
25
+
26
+ ## Missing values for variables (\`$TO\`, etc.)
27
+
28
+ Pass every custom placeholder in MCP \`vars\` or \`--vars\` as a JSON object of
29
+ strings. Ensure \`register\` completed so \`$ACCOUNT_ID\` / \`$INBOX\` can resolve.
30
+
31
+ ## \`invalidArguments\` on \`Email/query\` / \`filter/inMailbox\`
32
+
33
+ \`inMailbox\` must be a **mailbox id**, not your inbox email. Use the built-in
34
+ \`$INBOX_MAILBOX_ID\` placeholder (or run \`Mailbox/get\` / \`Mailbox/query\` and
35
+ paste the id into \`vars\`).
36
+
37
+ ## \`invalidProperties\` / \`notCreated\` on \`Blob/upload\`
38
+
39
+ RFC 9404 requires \`data\` as an **array** of objects, each with **exactly one**
40
+ of \`data:asText\`, \`data:asBase64\`, or a \`blobId\` slice. Typical mistakes:
41
+ \`data\` as a raw string; \`data:asBase64\` on the upload object instead of
42
+ inside an array element; mixing two forms in one object. See topic
43
+ \`jmap_cheatsheet\` (\`Blob/upload\` shape) and preset \`send_mail_attachment.json\`.
44
+
45
+ ## RFC 8620 binary \`POST\` to \`uploadUrl\` returns 404
46
+
47
+ The session lists an \`uploadUrl\` template, but your deployment must expose
48
+ that HTTP resource. If \`POST\` returns 404, out-of-band upload is not wired
49
+ on the server — use \`Blob/upload\` in JMAP instead, or fix the API gateway.
50
+
51
+ ## \`Blob/upload\` succeeds but \`size\` is 0 (or \`Email/set\` rejects the blob)
52
+
53
+ The server accepted the method but did not persist octets (broken or
54
+ incomplete \`Blob/upload\`). Verify with a tiny \`data: [{ "data:asBase64": "QQ==" }]\`
55
+ payload; if \`size\`
56
+ stays 0, fix the JMAP/blob implementation on the host before sending
57
+ attachments.
58
+
59
+ ## Installed package vs other documentation
60
+
61
+ The version you get from \`npx -y @atomicmail/mcp\` or
62
+ \`npx --package=@atomicmail/agent-skill …\` may lag behind other published docs.
63
+ If something disagrees, trust **your installed package**: run \`help\` and use
64
+ the bundled presets that ship with that version. In MCP runtimes, \`help\` with
65
+ topic \`readme\` returns package README.md.`;
@@ -0,0 +1,45 @@
1
+ export interface Credentials {
2
+ apiKey: string;
3
+ inboxId: string;
4
+ authUrl: string;
5
+ apiUrl: string;
6
+ scryptSalt: string;
7
+ uploadUrl: string;
8
+ downloadUrl: string;
9
+ }
10
+ export interface SkillFiles {
11
+ credentialsFile: string;
12
+ sessionFile: string;
13
+ capabilityFile: string;
14
+ }
15
+ export interface CredentialArtifacts {
16
+ credentials?: Credentials;
17
+ sessionJwt?: string;
18
+ capabilityJwt?: string;
19
+ }
20
+ export interface CredentialStore {
21
+ load(): Promise<CredentialArtifacts>;
22
+ /**
23
+ * Persist provided artifacts. Missing fields are left unchanged.
24
+ */
25
+ save(artifacts: CredentialArtifacts): Promise<void>;
26
+ clear(): Promise<void>;
27
+ }
28
+ export declare function defaultFilesFromOutDir(outDir: string): SkillFiles;
29
+ export declare function parseCredentialsJson(raw: string, pathForErrors?: string): Credentials;
30
+ export declare function serializeCredentials(creds: Credentials): string;
31
+ export declare function writeCredentials(path: string, creds: Credentials): Promise<void>;
32
+ export declare function readCredentials(path: string): Promise<Credentials>;
33
+ export declare function tryReadCredentials(path: string): Promise<Credentials | undefined>;
34
+ export declare function writeJwtFile(path: string, jwt: string): Promise<void>;
35
+ export declare function tryReadJwtFile(path: string): Promise<string | undefined>;
36
+ export declare class FilesystemCredentialStore implements CredentialStore {
37
+ readonly files: SkillFiles;
38
+ constructor(files: SkillFiles);
39
+ load(): Promise<CredentialArtifacts>;
40
+ save(artifacts: CredentialArtifacts): Promise<void>;
41
+ clear(): Promise<void>;
42
+ }
43
+ /** Best-effort removal of credential artifacts (ignore missing files). */
44
+ export declare function unlinkCredentialArtifacts(files: SkillFiles): Promise<void>;
45
+ //# sourceMappingURL=agent-credentials-store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-credentials-store.d.ts","sourceRoot":"","sources":["../../../../src/lib/agent/session/agent-credentials-store.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,UAAU;IACzB,eAAe,EAAE,MAAM,CAAC;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,mBAAmB;IAClC,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,IAAI,OAAO,CAAC,mBAAmB,CAAC,CAAC;IACrC;;OAEG;IACH,IAAI,CAAC,SAAS,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACpD,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAED,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,MAAM,GAAG,UAAU,CAOjE;AAMD,wBAAgB,oBAAoB,CAClC,GAAG,EAAE,MAAM,EACX,aAAa,SAAqB,GACjC,WAAW,CA4Bb;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,WAAW,GAAG,MAAM,CAE/D;AAED,wBAAsB,gBAAgB,CACpC,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,WAAW,GACjB,OAAO,CAAC,IAAI,CAAC,CAGf;AAED,wBAAsB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAWxE;AAED,wBAAsB,kBAAkB,CACtC,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,WAAW,GAAG,SAAS,CAAC,CAOlC;AAED,wBAAsB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAG3E;AAED,wBAAsB,cAAc,CAClC,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAO7B;AAED,qBAAa,yBAA0B,YAAW,eAAe;IAC/D,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAC;gBAEf,KAAK,EAAE,UAAU;IAIvB,IAAI,IAAI,OAAO,CAAC,mBAAmB,CAAC;IAQpC,IAAI,CAAC,SAAS,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC;IAYnD,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAG7B;AAED,0EAA0E;AAC1E,wBAAsB,yBAAyB,CAC7C,KAAK,EAAE,UAAU,GAChB,OAAO,CAAC,IAAI,CAAC,CAcf"}
@@ -0,0 +1,121 @@
1
+ // Credential file I/O shared by MCP and AgentSkill.
2
+ // Three files: credentials.json, session.jwt, capability.jwt (mode 0600).
3
+ import { mkdir, readFile, unlink, writeFile } from "node:fs/promises";
4
+ import { dirname, join, resolve } from "node:path";
5
+ export function defaultFilesFromOutDir(outDir) {
6
+ const base = resolve(outDir);
7
+ return {
8
+ credentialsFile: join(base, "credentials.json"),
9
+ sessionFile: join(base, "session.jwt"),
10
+ capabilityFile: join(base, "capability.jwt"),
11
+ };
12
+ }
13
+ async function ensureParent(path) {
14
+ await mkdir(dirname(path), { recursive: true });
15
+ }
16
+ export function parseCredentialsJson(raw, pathForErrors = "credentials.json") {
17
+ let obj;
18
+ try {
19
+ obj = JSON.parse(raw);
20
+ }
21
+ catch (err) {
22
+ throw new Error(`Credentials file '${pathForErrors}' is not valid JSON: ${err.message}`);
23
+ }
24
+ const required = [
25
+ "apiKey",
26
+ "inboxId",
27
+ "authUrl",
28
+ "apiUrl",
29
+ "scryptSalt",
30
+ "uploadUrl",
31
+ "downloadUrl",
32
+ ];
33
+ for (const k of required) {
34
+ if (typeof obj[k] !== "string" || obj[k].length === 0) {
35
+ throw new Error(`Credentials file '${pathForErrors}' missing required field: ${k}`);
36
+ }
37
+ }
38
+ return obj;
39
+ }
40
+ export function serializeCredentials(creds) {
41
+ return JSON.stringify(creds, null, 2) + "\n";
42
+ }
43
+ export async function writeCredentials(path, creds) {
44
+ await ensureParent(path);
45
+ await writeFile(path, serializeCredentials(creds), { mode: 0o600 });
46
+ }
47
+ export async function readCredentials(path) {
48
+ let raw;
49
+ try {
50
+ raw = await readFile(path, "utf-8");
51
+ }
52
+ catch (err) {
53
+ throw new Error(`Could not read credentials file '${path}': ${err.message}. ` +
54
+ "Did you run register first?");
55
+ }
56
+ return parseCredentialsJson(raw, path);
57
+ }
58
+ export async function tryReadCredentials(path) {
59
+ try {
60
+ const raw = await readFile(path, "utf-8");
61
+ return parseCredentialsJson(raw, path);
62
+ }
63
+ catch {
64
+ return undefined;
65
+ }
66
+ }
67
+ export async function writeJwtFile(path, jwt) {
68
+ await ensureParent(path);
69
+ await writeFile(path, jwt, { mode: 0o600 });
70
+ }
71
+ export async function tryReadJwtFile(path) {
72
+ try {
73
+ const raw = await readFile(path, "utf-8");
74
+ return raw.trim();
75
+ }
76
+ catch {
77
+ return undefined;
78
+ }
79
+ }
80
+ export class FilesystemCredentialStore {
81
+ files;
82
+ constructor(files) {
83
+ this.files = files;
84
+ }
85
+ async load() {
86
+ return {
87
+ credentials: await tryReadCredentials(this.files.credentialsFile),
88
+ sessionJwt: await tryReadJwtFile(this.files.sessionFile),
89
+ capabilityJwt: await tryReadJwtFile(this.files.capabilityFile),
90
+ };
91
+ }
92
+ async save(artifacts) {
93
+ if (artifacts.credentials !== undefined) {
94
+ await writeCredentials(this.files.credentialsFile, artifacts.credentials);
95
+ }
96
+ if (artifacts.sessionJwt !== undefined) {
97
+ await writeJwtFile(this.files.sessionFile, artifacts.sessionJwt);
98
+ }
99
+ if (artifacts.capabilityJwt !== undefined) {
100
+ await writeJwtFile(this.files.capabilityFile, artifacts.capabilityJwt);
101
+ }
102
+ }
103
+ async clear() {
104
+ await unlinkCredentialArtifacts(this.files);
105
+ }
106
+ }
107
+ /** Best-effort removal of credential artifacts (ignore missing files). */
108
+ export async function unlinkCredentialArtifacts(files) {
109
+ for (const p of [
110
+ files.credentialsFile,
111
+ files.sessionFile,
112
+ files.capabilityFile,
113
+ ]) {
114
+ try {
115
+ await unlink(p);
116
+ }
117
+ catch {
118
+ // ignore
119
+ }
120
+ }
121
+ }
@@ -0,0 +1,29 @@
1
+ import { type SkillFiles } from "./agent-credentials-store.js";
2
+ export type ConfigSource = "credentials-file" | "env" | "mixed" | "defaults";
3
+ export interface ResolvedAgentConfig {
4
+ authUrl: string;
5
+ apiUrl: string;
6
+ scryptSalt: string;
7
+ apiKey?: string;
8
+ inboxId?: string;
9
+ credentialDir: string;
10
+ files: SkillFiles;
11
+ source: ConfigSource;
12
+ }
13
+ /**
14
+ * Default credential directory:
15
+ * 1. ATOMIC_MAIL_CREDENTIALS_DIR
16
+ * 2. ~/.atomicmail/ or %USERPROFILE%/.atomicmail
17
+ */
18
+ export declare function resolveCredentialDir(): string;
19
+ /**
20
+ * AgentSkill / CLI: resolve credential directory from `--credentials-dir` or
21
+ * `ATOMIC_MAIL_CREDENTIALS_DIR`, with `~` expansion (MCP uses `resolveCredentialDir` instead).
22
+ */
23
+ export declare function expandCredentialDirInput(dir?: string): string;
24
+ /**
25
+ * Merge credentials.json with ATOMIC_MAIL_* env (env wins per field).
26
+ * authUrl and apiUrl fall back to production defaults when unset.
27
+ */
28
+ export declare function resolveAgentConfigFromEnv(): Promise<ResolvedAgentConfig>;
29
+ //# sourceMappingURL=agent-resolve-config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-resolve-config.d.ts","sourceRoot":"","sources":["../../../../src/lib/agent/session/agent-resolve-config.ts"],"names":[],"mappings":"AAWA,OAAO,EAEL,KAAK,UAAU,EAEhB,MAAM,8BAA8B,CAAC;AAEtC,MAAM,MAAM,YAAY,GACpB,kBAAkB,GAClB,KAAK,GACL,OAAO,GACP,UAAU,CAAC;AAEf,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,UAAU,CAAC;IAClB,MAAM,EAAE,YAAY,CAAC;CACtB;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,IAAI,MAAM,CAW7C;AAED;;;GAGG;AACH,wBAAgB,wBAAwB,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,CAI7D;AAED;;;GAGG;AACH,wBAAsB,yBAAyB,IAAI,OAAO,CACxD,mBAAmB,CACpB,CAuCA"}
@@ -0,0 +1,71 @@
1
+ // Resolve MCP / process credential dir + URLs from env + credentials.json.
2
+ import { homedir } from "node:os";
3
+ import process from "node:process";
4
+ import { resolve } from "node:path";
5
+ import { DEFAULT_API_URL, DEFAULT_AUTH_URL, DEFAULT_POW_SCRYPT_SALT_HEX, } from "../../core/consts.js";
6
+ import { defaultFilesFromOutDir, tryReadCredentials, } from "./agent-credentials-store.js";
7
+ /**
8
+ * Default credential directory:
9
+ * 1. ATOMIC_MAIL_CREDENTIALS_DIR
10
+ * 2. ~/.atomicmail/ or %USERPROFILE%/.atomicmail
11
+ */
12
+ export function resolveCredentialDir() {
13
+ const fromEnv = process.env.ATOMIC_MAIL_CREDENTIALS_DIR;
14
+ if (fromEnv && fromEnv.length > 0)
15
+ return fromEnv;
16
+ const home = process.env.HOME || process.env.USERPROFILE;
17
+ if (!home) {
18
+ throw new Error("Cannot determine default credential directory: HOME and USERPROFILE " +
19
+ "are both unset. Set ATOMIC_MAIL_CREDENTIALS_DIR explicitly.");
20
+ }
21
+ return `${home.replace(/[\\/]+$/, "")}/.atomicmail`;
22
+ }
23
+ /**
24
+ * AgentSkill / CLI: resolve credential directory from `--credentials-dir` or
25
+ * `ATOMIC_MAIL_CREDENTIALS_DIR`, with `~` expansion (MCP uses `resolveCredentialDir` instead).
26
+ */
27
+ export function expandCredentialDirInput(dir) {
28
+ const raw = dir ?? process.env.ATOMIC_MAIL_CREDENTIALS_DIR ?? "~/.atomicmail";
29
+ if (raw === "~")
30
+ return homedir();
31
+ return resolve(raw.replace(/^~\//, `${homedir()}/`));
32
+ }
33
+ /**
34
+ * Merge credentials.json with ATOMIC_MAIL_* env (env wins per field).
35
+ * authUrl and apiUrl fall back to production defaults when unset.
36
+ */
37
+ export async function resolveAgentConfigFromEnv() {
38
+ const credentialDir = resolveCredentialDir();
39
+ const files = defaultFilesFromOutDir(credentialDir);
40
+ const fileCreds = await tryReadCredentials(files.credentialsFile);
41
+ const env = process.env;
42
+ const envAuthUrl = env.ATOMIC_MAIL_AUTH_URL;
43
+ const envApiUrl = env.ATOMIC_MAIL_API_URL;
44
+ const envSalt = env.ATOMIC_MAIL_SCRYPT_SALT;
45
+ const envApiKey = env.ATOMIC_MAIL_API_KEY;
46
+ const authUrl = envAuthUrl ?? fileCreds?.authUrl ?? DEFAULT_AUTH_URL;
47
+ const apiUrl = envApiUrl ?? fileCreds?.apiUrl ?? DEFAULT_API_URL;
48
+ const scryptSalt = envSalt ?? fileCreds?.scryptSalt ??
49
+ DEFAULT_POW_SCRYPT_SALT_HEX;
50
+ const apiKey = envApiKey ?? fileCreds?.apiKey;
51
+ const inboxId = fileCreds?.inboxId;
52
+ const usingFile = fileCreds !== undefined;
53
+ const usingEnv = !!(envAuthUrl || envApiUrl || envSalt || envApiKey);
54
+ const source = usingFile && usingEnv
55
+ ? "mixed"
56
+ : usingFile
57
+ ? "credentials-file"
58
+ : usingEnv
59
+ ? "env"
60
+ : "defaults";
61
+ return {
62
+ authUrl: authUrl.replace(/\/+$/, ""),
63
+ apiUrl: apiUrl.replace(/\/+$/, ""),
64
+ scryptSalt: scryptSalt,
65
+ apiKey,
66
+ inboxId,
67
+ credentialDir,
68
+ files,
69
+ source,
70
+ };
71
+ }
@@ -0,0 +1,8 @@
1
+ import { AgentSession } from "./agent-session.js";
2
+ import { type ResolvedAgentConfig } from "./agent-resolve-config.js";
3
+ export interface CreateAgentSessionForCredentialDirOptions {
4
+ /** When true, credentials.json must exist (jmap_request path). */
5
+ requireCredentials?: boolean;
6
+ }
7
+ export declare function createAgentSessionForCredentialDir(credentialDir: string, envDefaults: Pick<ResolvedAgentConfig, "authUrl" | "apiUrl" | "scryptSalt">, options?: CreateAgentSessionForCredentialDirOptions): Promise<AgentSession>;
8
+ //# sourceMappingURL=agent-session-for-dir.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-session-for-dir.d.ts","sourceRoot":"","sources":["../../../../src/lib/agent/session/agent-session-for-dir.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAMlD,OAAO,EAEL,KAAK,mBAAmB,EACzB,MAAM,2BAA2B,CAAC;AAEnC,MAAM,WAAW,yCAAyC;IACxD,kEAAkE;IAClE,kBAAkB,CAAC,EAAE,OAAO,CAAC;CAC9B;AAED,wBAAsB,kCAAkC,CACtD,aAAa,EAAE,MAAM,EACrB,WAAW,EAAE,IAAI,CAAC,mBAAmB,EAAE,SAAS,GAAG,QAAQ,GAAG,YAAY,CAAC,EAC3E,OAAO,GAAE,yCAA8C,GACtD,OAAO,CAAC,YAAY,CAAC,CAgCvB"}
@@ -0,0 +1,33 @@
1
+ // Create AgentSession for a specific credential directory (MCP per-request / CLI parity).
2
+ import { AgentSession } from "./agent-session.js";
3
+ import { defaultFilesFromOutDir, FilesystemCredentialStore, tryReadCredentials, } from "./agent-credentials-store.js";
4
+ import { expandCredentialDirInput, } from "./agent-resolve-config.js";
5
+ export async function createAgentSessionForCredentialDir(credentialDir, envDefaults, options = {}) {
6
+ const expandedDir = expandCredentialDirInput(credentialDir);
7
+ const files = defaultFilesFromOutDir(expandedDir);
8
+ const store = new FilesystemCredentialStore(files);
9
+ const fileCreds = await tryReadCredentials(files.credentialsFile);
10
+ if (!fileCreds) {
11
+ if (options.requireCredentials) {
12
+ throw new Error(`No credentials in '${expandedDir}'. Run register with ` +
13
+ `credentials_dir pointing at that directory first.`);
14
+ }
15
+ return AgentSession.create({
16
+ authUrl: envDefaults.authUrl,
17
+ apiUrl: envDefaults.apiUrl,
18
+ scryptSalt: envDefaults.scryptSalt,
19
+ credentialDir: expandedDir,
20
+ store,
21
+ });
22
+ }
23
+ const creds = fileCreds;
24
+ return AgentSession.create({
25
+ authUrl: creds.authUrl,
26
+ apiUrl: creds.apiUrl,
27
+ scryptSalt: creds.scryptSalt,
28
+ apiKey: creds.apiKey,
29
+ inboxId: creds.inboxId,
30
+ credentialDir: expandedDir,
31
+ store,
32
+ });
33
+ }