imap-agent-cli 0.2.1__tar.gz → 0.3.0__tar.gz

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 (43) hide show
  1. {imap_agent_cli-0.2.1 → imap_agent_cli-0.3.0}/AGENTS.md +1 -1
  2. {imap_agent_cli-0.2.1 → imap_agent_cli-0.3.0}/PKG-INFO +78 -51
  3. {imap_agent_cli-0.2.1 → imap_agent_cli-0.3.0}/README.md +73 -49
  4. imap_agent_cli-0.3.0/docs/setup.md +127 -0
  5. {imap_agent_cli-0.2.1 → imap_agent_cli-0.3.0}/imap_agent_cli.py +4 -1
  6. {imap_agent_cli-0.2.1 → imap_agent_cli-0.3.0}/pyproject.toml +5 -2
  7. {imap_agent_cli-0.2.1 → imap_agent_cli-0.3.0}/spec.md +19 -14
  8. {imap_agent_cli-0.2.1 → imap_agent_cli-0.3.0}/src/imap_agent_cli/__init__.py +1 -1
  9. {imap_agent_cli-0.2.1 → imap_agent_cli-0.3.0}/src/imap_agent_cli/cli.py +75 -59
  10. imap_agent_cli-0.3.0/src/imap_agent_cli/config.py +297 -0
  11. imap_agent_cli-0.3.0/src/imap_agent_cli/credentials.py +79 -0
  12. {imap_agent_cli-0.2.1 → imap_agent_cli-0.3.0}/src/imap_agent_cli/imap_client.py +62 -60
  13. {imap_agent_cli-0.2.1 → imap_agent_cli-0.3.0}/src/imap_agent_cli/models.py +6 -1
  14. imap_agent_cli-0.3.0/src/imap_agent_cli/onboarding.py +200 -0
  15. imap_agent_cli-0.3.0/src/imap_agent_cli/providers.py +67 -0
  16. {imap_agent_cli-0.2.1 → imap_agent_cli-0.3.0}/src/imap_agent_cli/skill.py +15 -12
  17. imap_agent_cli-0.3.0/src/imap_agent_cli/storage.py +72 -0
  18. imap_agent_cli-0.3.0/src/imap_agent_cli/verification.py +94 -0
  19. {imap_agent_cli-0.2.1 → imap_agent_cli-0.3.0}/tests/test_cli.py +16 -3
  20. imap_agent_cli-0.3.0/tests/test_onboarding.py +414 -0
  21. {imap_agent_cli-0.2.1 → imap_agent_cli-0.3.0}/tests/test_pymap_integration.py +36 -9
  22. {imap_agent_cli-0.2.1 → imap_agent_cli-0.3.0}/tests/test_skill.py +9 -0
  23. {imap_agent_cli-0.2.1 → imap_agent_cli-0.3.0}/tests/test_skill_sync.py +6 -5
  24. {imap_agent_cli-0.2.1 → imap_agent_cli-0.3.0}/tests/test_wheel_smoke.py +30 -5
  25. imap_agent_cli-0.2.1/src/imap_agent_cli/config.py +0 -313
  26. {imap_agent_cli-0.2.1 → imap_agent_cli-0.3.0}/.github/workflows/publish.yml +0 -0
  27. {imap_agent_cli-0.2.1 → imap_agent_cli-0.3.0}/.gitignore +0 -0
  28. {imap_agent_cli-0.2.1 → imap_agent_cli-0.3.0}/CHANGELOG.md +0 -0
  29. {imap_agent_cli-0.2.1 → imap_agent_cli-0.3.0}/LICENSE +0 -0
  30. {imap_agent_cli-0.2.1 → imap_agent_cli-0.3.0}/src/imap_agent_cli/errors.py +0 -0
  31. {imap_agent_cli-0.2.1 → imap_agent_cli-0.3.0}/src/imap_agent_cli/mime.py +0 -0
  32. {imap_agent_cli-0.2.1 → imap_agent_cli-0.3.0}/src/imap_agent_cli/render.py +0 -0
  33. {imap_agent_cli-0.2.1 → imap_agent_cli-0.3.0}/src/imap_agent_cli/runtime.py +0 -0
  34. {imap_agent_cli-0.2.1 → imap_agent_cli-0.3.0}/src/imap_agent_cli/search.py +0 -0
  35. {imap_agent_cli-0.2.1 → imap_agent_cli-0.3.0}/tests/__init__.py +0 -0
  36. {imap_agent_cli-0.2.1 → imap_agent_cli-0.3.0}/tests/_bootstrap.py +0 -0
  37. {imap_agent_cli-0.2.1 → imap_agent_cli-0.3.0}/tests/pymap_server_runner.py +0 -0
  38. {imap_agent_cli-0.2.1 → imap_agent_cli-0.3.0}/tests/test_config.py +0 -0
  39. {imap_agent_cli-0.2.1 → imap_agent_cli-0.3.0}/tests/test_imap_client.py +0 -0
  40. {imap_agent_cli-0.2.1 → imap_agent_cli-0.3.0}/tests/test_live_no_seen.py +0 -0
  41. {imap_agent_cli-0.2.1 → imap_agent_cli-0.3.0}/tests/test_mime.py +0 -0
  42. {imap_agent_cli-0.2.1 → imap_agent_cli-0.3.0}/tests/test_runtime.py +0 -0
  43. {imap_agent_cli-0.2.1 → imap_agent_cli-0.3.0}/tests/test_search.py +0 -0
@@ -25,7 +25,7 @@ The core safety boundary is strict: never add support for sending email, deletin
25
25
  - Keep the root wrapper thin; application logic belongs under `src/imap_agent_cli/`.
26
26
  - Preserve stable JSON payloads on stdout. Diagnostics, warnings, progress, and errors must go to stderr.
27
27
  - Do not print secrets, credentials, full message bodies, or attachment contents in logs.
28
- - Keep credentials in environment variables or config references to environment variables. Do not add config examples that store passwords directly.
28
+ - Keep secrets separate from ordinary configuration. Credentials may come from environment variables, explicit stdin, or the separate credentials file written by setup. Never include real credentials in examples. Use normal inherited filesystem permissions. Do not require an OS keyring or persist shell environment variables.
29
29
  - Keep README and skill language platform-neutral and agent-tool-neutral. Avoid shell-specific syntax unless explicitly documenting a shell-specific example.
30
30
  - If changing installed-skill behavior or wording, update `src/imap_agent_cli/skill.py` and `tests/test_skill.py` together.
31
31
  - If changing MIME parsing, body rendering, draft creation, or search behavior, add focused tests for the contract being changed.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: imap-agent-cli
3
- Version: 0.2.1
3
+ Version: 0.3.0
4
4
  Summary: Agent-first IMAP CLI for safe email search, read, attachment download, and draft creation
5
5
  Project-URL: Homepage, https://github.com/pseudosavant/imap-agent-cli
6
6
  Project-URL: Repository, https://github.com/pseudosavant/imap-agent-cli
@@ -21,13 +21,16 @@ Classifier: Programming Language :: Python :: 3.13
21
21
  Classifier: Topic :: Communications :: Email
22
22
  Classifier: Topic :: Communications :: Email :: Post-Office :: IMAP
23
23
  Classifier: Topic :: Utilities
24
- Requires-Python: >=3.11
24
+ Requires-Python: <3.14,>=3.11
25
25
  Requires-Dist: beautifulsoup4>=4.12.0
26
26
  Requires-Dist: bleach>=6.2.0
27
+ Requires-Dist: filelock>=3.16.0
27
28
  Requires-Dist: imapclient>=3.0.0
28
29
  Requires-Dist: markdownify>=0.14.0
29
30
  Requires-Dist: packaging>=23.2
31
+ Requires-Dist: prompt-toolkit>=3.0.43
30
32
  Requires-Dist: pyyaml>=6.0
33
+ Requires-Dist: tomlkit>=0.13.0
31
34
  Provides-Extra: test
32
35
  Requires-Dist: pymap>=0.36.0; extra == 'test'
33
36
  Requires-Dist: pytest>=8.0.0; extra == 'test'
@@ -39,40 +42,51 @@ Description-Content-Type: text/markdown
39
42
 
40
43
  It never sends email and cannot change existing messages or folders.
41
44
 
42
- ## Prerequisite
45
+ ## Quick start with an agent
43
46
 
44
- `imap-agent-cli` is designed to be used with [`uv`](https://docs.astral.sh/uv/getting-started/installation/). Install `uv` before continuing. The documented workflows and managed agent skill use `uvx` to run the tool without requiring a global installation.
47
+ You need an IMAP-enabled email account and a compatible password or app password. Setup explains credential creation for Gmail, Fastmail, and iCloud. Other IMAP servers need their provider's hostname and login details. Microsoft 365 and Outlook.com require OAuth and are not supported. Microsoft app passwords are not a workaround.
45
48
 
46
- ## Quick start with an agent
49
+ Install [`uv`](https://docs.astral.sh/uv/getting-started/installation/) if needed. The managed skill runs the tool with `uvx`. You do not need a global tool installation. uv can obtain a compatible Python automatically. Direct Python installs require Python 3.11 through 3.13. IMAPClient is currently incompatible with Python 3.14.
47
50
 
48
- Install the managed `imap` agent skill:
51
+ PowerShell:
49
52
 
50
- ```text
51
- uvx imap-agent-cli skill install
53
+ ```powershell
54
+ # Skip this command if uv is already installed.
55
+ powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
56
+
57
+ # Open a new PowerShell window after installation.
58
+ uv --version
59
+ uvx imap-agent-cli setup --format plain
52
60
  ```
53
61
 
54
- Configure a default IMAP account through environment variables:
62
+ Bash on Linux or macOS:
55
63
 
56
- ```text
57
- IMAP_AGENT_CLI_HOST=imap.example.com
58
- IMAP_AGENT_CLI_PORT=993
59
- IMAP_AGENT_CLI_USERNAME=me@example.com
60
- IMAP_AGENT_CLI_PASSWORD=your-password-or-app-password
61
- IMAP_AGENT_CLI_TLS=true
62
- IMAP_AGENT_CLI_SSL_MODE=required
64
+ ```bash
65
+ # Skip these two commands if uv is already installed.
66
+ curl -LsSf https://astral.sh/uv/install.sh | sh
67
+ . "$HOME/.local/bin/env"
68
+
69
+ uv --version
70
+ uvx imap-agent-cli setup --format plain
63
71
  ```
64
72
 
65
- Check the connection without reading message bodies:
73
+ Enter your credential only at the masked terminal prompt. Never paste a credential into agent chat. Setup saves account settings and credentials separately, verifies read-only mailbox access, and installs the managed `imap` skill. No separate test command is needed after successful setup.
74
+
75
+ You can provide information you already know:
66
76
 
67
77
  ```text
68
- uvx imap-agent-cli config check
78
+ uvx imap-agent-cli setup "me@gmail.com"
79
+ uvx imap-agent-cli setup "https://app.fastmail.com/"
80
+ uvx imap-agent-cli setup --host imap.example.com --username me@example.com
69
81
  ```
70
82
 
71
- Then use `$imap` in Codex, Claude Code, or another agentic tool that supports skills:
83
+ A webmail URL is only a provider hint. It is not fetched. Custom email domains require a provider hostname. See [setup and credential guidance](docs/setup.md) for provider requirements and recovery commands.
84
+
85
+ Start a new agent session if the skill is not available. Then ask:
72
86
 
73
- > Use $imap to find the five most recent emails about the Acme renewal. Summarize the latest thread and create a reply draft asking for the updated contract. Do not download attachments.
87
+ > Use $imap to list the five newest messages in INBOX. Show senders and subjects only.
74
88
 
75
- The skill teaches the agent to search before reading, keep operations bounded, download attachments only when requested, and create drafts without sending them.
89
+ The agent must have access to `uvx`, the saved files, and the IMAP server. A remote host or container needs its own runtime and credential provision. If terminal use works but agent use fails, ask the agent to run `uvx imap-agent-cli config check`. Do not ask it to open the credentials file.
76
90
 
77
91
  ## What it can do
78
92
 
@@ -130,51 +144,63 @@ The usual workflow is to search first, select a result by folder and UID, read o
130
144
 
131
145
  ## Configure accounts
132
146
 
133
- ### One account with environment variables
134
-
135
- For a single account, environment variables are enough:
147
+ ### Saved accounts
136
148
 
137
149
  ```text
138
- IMAP_AGENT_CLI_HOST=imap.example.com
139
- IMAP_AGENT_CLI_PORT=993
140
- IMAP_AGENT_CLI_USERNAME=me@example.com
141
- IMAP_AGENT_CLI_PASSWORD=your-password-or-app-password
142
- IMAP_AGENT_CLI_TLS=true
143
- IMAP_AGENT_CLI_SSL_MODE=required
144
- IMAP_AGENT_CLI_DRAFTS_FOLDER=Drafts
150
+ uvx imap-agent-cli setup
151
+ uvx imap-agent-cli setup --profile work
152
+ uvx imap-agent-cli setup --profile work --set-default
153
+ uvx imap-agent-cli profiles
154
+ uvx imap-agent-cli config show
145
155
  ```
146
156
 
147
- `IMAP_AGENT_CLI_DRAFTS_FOLDER` is optional. When omitted, the CLI tries the server's IMAP special-use metadata and common Drafts folder names.
157
+ The first account uses the name `default`. Adding an account preserves the existing default. Pass `--profile work` to mailbox commands to select it.
148
158
 
149
- Validate the resolved configuration, login, folders, default folder, and Drafts detection without reading message bodies:
159
+ Non-secret settings live in `~/.imap-agent-cli/config.toml`. Setup saves entered passwords in `~/.imap-agent-cli/credentials.toml` with normal inherited permissions. It does not require a keyring, change ACLs, or persist shell variables. The credential file is plain text. Keep it out of repositories and shared exports.
150
160
 
151
- ```text
152
- uvx imap-agent-cli config check
153
- ```
161
+ Repeated setup reuses existing credentials and preserves unrelated configuration and skill content. Use `setup --replace-password` to verify and save a replacement. Unset password environment overrides first. Existing configuration remains usable if verification or saving fails.
154
162
 
155
- ### Multiple account profiles
163
+ ### Environment overrides
156
164
 
157
- Create a config file when you need named accounts:
165
+ Environment variables remain available. Connection flags take priority over non-empty environment overrides, followed by the selected saved profile and built-in defaults. Password resolution uses explicit stdin, the profile's named password variable, the global password variable, and finally the matching saved credential. Rejected credentials do not trigger fallback to another source.
158
166
 
159
- ```text
160
- uvx imap-agent-cli config init
161
- uvx imap-agent-cli config add-profile work --host imap.example.com --port 993 --username me@example.com --password-env IMAP_AGENT_CLI_WORK_PASSWORD
162
- uvx imap-agent-cli config set-default-profile work
167
+ PowerShell:
168
+
169
+ ```powershell
170
+ $env:IMAP_AGENT_CLI_HOST = "imap.example.com"
171
+ $env:IMAP_AGENT_CLI_USERNAME = "me@example.com"
172
+ $imapCredential = Read-Host "IMAP password or app password" -AsSecureString
173
+ $env:IMAP_AGENT_CLI_PASSWORD = [System.Net.NetworkCredential]::new("", $imapCredential).Password
174
+ Remove-Variable imapCredential
175
+ uvx imap-agent-cli setup --non-interactive
176
+ ```
177
+
178
+ Bash:
179
+
180
+ ```bash
181
+ export IMAP_AGENT_CLI_HOST="imap.example.com"
182
+ export IMAP_AGENT_CLI_USERNAME="me@example.com"
183
+ read -rs -p "IMAP password or app password: " IMAP_AGENT_CLI_PASSWORD
184
+ printf '\n'
185
+ export IMAP_AGENT_CLI_PASSWORD
186
+ uvx imap-agent-cli setup --non-interactive
163
187
  ```
164
188
 
165
- The config file is stored at `~/.imap-agent-cli/config.toml`. Keep passwords in environment variables. Profiles store the name of the password environment variable, not the password itself.
189
+ These variables affect the current shell and its children. An already-running agent does not inherit later changes. Setup uses an environment password without saving its value. Secure defaults supply port `993`, `tls=true`, and `ssl_mode=required`.
166
190
 
167
- The CLI uses standard IMAP username and password authentication. It does not provide OAuth setup. Providers that disable account-password login may require an app password.
191
+ The existing `config init`, `config add-profile`, and `config set-default-profile` commands remain available. `config init` creates a starter file. Prefer `setup` to complete onboarding. Existing `password_env` references continue to work.
168
192
 
169
- Inspect resolved settings without exposing secrets, or list available profiles:
193
+ ### Check configuration
170
194
 
171
195
  ```text
172
- uvx imap-agent-cli config show
173
- uvx imap-agent-cli profiles
174
- uvx imap-agent-cli config check --profile work
196
+ uvx imap-agent-cli config check
197
+ uvx imap-agent-cli config check --profile work --format plain
198
+ uvx imap-agent-cli config check --local
175
199
  ```
176
200
 
177
- Pass `--profile NAME` to any mailbox command to select a non-default profile. Direct commands also accept connection flags and `--password-stdin` for one-off use.
201
+ Checks never write configuration, credentials, or skills. The network check verifies login, opens the default mailbox read-only, and checks bounded metadata access. It never reads bodies or appends a test message. Missing Drafts is a warning for reading. Finding Drafts does not verify append permission or quota. An empty mailbox leaves metadata fetching untested.
202
+
203
+ Use `--config PATH` or `IMAP_AGENT_CLI_CONFIG` for another configuration file. Use `--credentials-file PATH` or `IMAP_AGENT_CLI_CREDENTIALS_FILE` for a separate credential file. Explicit paths work with setup, diagnostics, and mailbox commands. Relative command-line paths resolve from the working directory. Setup saves an explicitly selected credential file path for later use. Custom skill locations use `--skills-dir PATH`.
178
204
 
179
205
  ### Connection security
180
206
 
@@ -296,7 +322,7 @@ uvx imap-agent-cli skill status
296
322
  uvx imap-agent-cli skill status --format plain
297
323
  ```
298
324
 
299
- Normal invocations of an installed CLI update a pristine older managed skill to the running CLI version. Synchronization is local. It does not query PyPI, refresh uv's cache, or update the CLI. Missing skills are never installed automatically. Unmanaged, modified, equal-version, and newer skills are preserved.
325
+ Normal mailbox invocations and top-level help, version, and about commands of an installed CLI update a pristine older managed skill to the running CLI version. Synchronization is local. It does not query PyPI, refresh uv's cache, or update the CLI. Missing skills are never installed automatically. Unmanaged, modified, equal-version, and newer skills are preserved.
300
326
 
301
327
  Restore altered managed content explicitly:
302
328
 
@@ -336,7 +362,7 @@ uvx imap-agent-cli draft create --json draft.json
336
362
  uvx imap-agent-cli draft reply --json reply.json
337
363
  ```
338
364
 
339
- Use `--json -` to read the JSON request from stdin. Failures leave stdout empty and write a compact JSON error to stderr. Logs do not include passwords, message bodies, or attachment content.
365
+ Use `--json -` to read the JSON request from stdin. Operational failures leave stdout empty and write a compact JSON error to stderr. Setup and configuration checks return structured readiness reports when verification or a later step fails. Check the exit status and the `ready` or `ok` field. Human diagnostics go to stderr. Add `--format plain` to setup or config check for a readable report. Logs do not include passwords, message bodies, or attachment content.
340
366
 
341
367
  Default guardrails keep work bounded:
342
368
 
@@ -355,6 +381,7 @@ Commands expose targeted overrides such as `--max-results`, `--max-scan`, `--max
355
381
 
356
382
  | Command | Purpose |
357
383
  | --- | --- |
384
+ | `setup` | Verify and save an account, then install the managed skill |
358
385
  | `config` | Initialize, inspect, validate, and manage profile configuration |
359
386
  | `profiles` | List configured profile names |
360
387
  | `skill` | Install, inspect, or remove the managed agent skill |
@@ -4,40 +4,51 @@
4
4
 
5
5
  It never sends email and cannot change existing messages or folders.
6
6
 
7
- ## Prerequisite
7
+ ## Quick start with an agent
8
8
 
9
- `imap-agent-cli` is designed to be used with [`uv`](https://docs.astral.sh/uv/getting-started/installation/). Install `uv` before continuing. The documented workflows and managed agent skill use `uvx` to run the tool without requiring a global installation.
9
+ You need an IMAP-enabled email account and a compatible password or app password. Setup explains credential creation for Gmail, Fastmail, and iCloud. Other IMAP servers need their provider's hostname and login details. Microsoft 365 and Outlook.com require OAuth and are not supported. Microsoft app passwords are not a workaround.
10
10
 
11
- ## Quick start with an agent
11
+ Install [`uv`](https://docs.astral.sh/uv/getting-started/installation/) if needed. The managed skill runs the tool with `uvx`. You do not need a global tool installation. uv can obtain a compatible Python automatically. Direct Python installs require Python 3.11 through 3.13. IMAPClient is currently incompatible with Python 3.14.
12
12
 
13
- Install the managed `imap` agent skill:
13
+ PowerShell:
14
14
 
15
- ```text
16
- uvx imap-agent-cli skill install
15
+ ```powershell
16
+ # Skip this command if uv is already installed.
17
+ powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
18
+
19
+ # Open a new PowerShell window after installation.
20
+ uv --version
21
+ uvx imap-agent-cli setup --format plain
17
22
  ```
18
23
 
19
- Configure a default IMAP account through environment variables:
24
+ Bash on Linux or macOS:
20
25
 
21
- ```text
22
- IMAP_AGENT_CLI_HOST=imap.example.com
23
- IMAP_AGENT_CLI_PORT=993
24
- IMAP_AGENT_CLI_USERNAME=me@example.com
25
- IMAP_AGENT_CLI_PASSWORD=your-password-or-app-password
26
- IMAP_AGENT_CLI_TLS=true
27
- IMAP_AGENT_CLI_SSL_MODE=required
26
+ ```bash
27
+ # Skip these two commands if uv is already installed.
28
+ curl -LsSf https://astral.sh/uv/install.sh | sh
29
+ . "$HOME/.local/bin/env"
30
+
31
+ uv --version
32
+ uvx imap-agent-cli setup --format plain
28
33
  ```
29
34
 
30
- Check the connection without reading message bodies:
35
+ Enter your credential only at the masked terminal prompt. Never paste a credential into agent chat. Setup saves account settings and credentials separately, verifies read-only mailbox access, and installs the managed `imap` skill. No separate test command is needed after successful setup.
36
+
37
+ You can provide information you already know:
31
38
 
32
39
  ```text
33
- uvx imap-agent-cli config check
40
+ uvx imap-agent-cli setup "me@gmail.com"
41
+ uvx imap-agent-cli setup "https://app.fastmail.com/"
42
+ uvx imap-agent-cli setup --host imap.example.com --username me@example.com
34
43
  ```
35
44
 
36
- Then use `$imap` in Codex, Claude Code, or another agentic tool that supports skills:
45
+ A webmail URL is only a provider hint. It is not fetched. Custom email domains require a provider hostname. See [setup and credential guidance](docs/setup.md) for provider requirements and recovery commands.
46
+
47
+ Start a new agent session if the skill is not available. Then ask:
37
48
 
38
- > Use $imap to find the five most recent emails about the Acme renewal. Summarize the latest thread and create a reply draft asking for the updated contract. Do not download attachments.
49
+ > Use $imap to list the five newest messages in INBOX. Show senders and subjects only.
39
50
 
40
- The skill teaches the agent to search before reading, keep operations bounded, download attachments only when requested, and create drafts without sending them.
51
+ The agent must have access to `uvx`, the saved files, and the IMAP server. A remote host or container needs its own runtime and credential provision. If terminal use works but agent use fails, ask the agent to run `uvx imap-agent-cli config check`. Do not ask it to open the credentials file.
41
52
 
42
53
  ## What it can do
43
54
 
@@ -95,51 +106,63 @@ The usual workflow is to search first, select a result by folder and UID, read o
95
106
 
96
107
  ## Configure accounts
97
108
 
98
- ### One account with environment variables
99
-
100
- For a single account, environment variables are enough:
109
+ ### Saved accounts
101
110
 
102
111
  ```text
103
- IMAP_AGENT_CLI_HOST=imap.example.com
104
- IMAP_AGENT_CLI_PORT=993
105
- IMAP_AGENT_CLI_USERNAME=me@example.com
106
- IMAP_AGENT_CLI_PASSWORD=your-password-or-app-password
107
- IMAP_AGENT_CLI_TLS=true
108
- IMAP_AGENT_CLI_SSL_MODE=required
109
- IMAP_AGENT_CLI_DRAFTS_FOLDER=Drafts
112
+ uvx imap-agent-cli setup
113
+ uvx imap-agent-cli setup --profile work
114
+ uvx imap-agent-cli setup --profile work --set-default
115
+ uvx imap-agent-cli profiles
116
+ uvx imap-agent-cli config show
110
117
  ```
111
118
 
112
- `IMAP_AGENT_CLI_DRAFTS_FOLDER` is optional. When omitted, the CLI tries the server's IMAP special-use metadata and common Drafts folder names.
119
+ The first account uses the name `default`. Adding an account preserves the existing default. Pass `--profile work` to mailbox commands to select it.
113
120
 
114
- Validate the resolved configuration, login, folders, default folder, and Drafts detection without reading message bodies:
121
+ Non-secret settings live in `~/.imap-agent-cli/config.toml`. Setup saves entered passwords in `~/.imap-agent-cli/credentials.toml` with normal inherited permissions. It does not require a keyring, change ACLs, or persist shell variables. The credential file is plain text. Keep it out of repositories and shared exports.
115
122
 
116
- ```text
117
- uvx imap-agent-cli config check
118
- ```
123
+ Repeated setup reuses existing credentials and preserves unrelated configuration and skill content. Use `setup --replace-password` to verify and save a replacement. Unset password environment overrides first. Existing configuration remains usable if verification or saving fails.
119
124
 
120
- ### Multiple account profiles
125
+ ### Environment overrides
121
126
 
122
- Create a config file when you need named accounts:
127
+ Environment variables remain available. Connection flags take priority over non-empty environment overrides, followed by the selected saved profile and built-in defaults. Password resolution uses explicit stdin, the profile's named password variable, the global password variable, and finally the matching saved credential. Rejected credentials do not trigger fallback to another source.
123
128
 
124
- ```text
125
- uvx imap-agent-cli config init
126
- uvx imap-agent-cli config add-profile work --host imap.example.com --port 993 --username me@example.com --password-env IMAP_AGENT_CLI_WORK_PASSWORD
127
- uvx imap-agent-cli config set-default-profile work
129
+ PowerShell:
130
+
131
+ ```powershell
132
+ $env:IMAP_AGENT_CLI_HOST = "imap.example.com"
133
+ $env:IMAP_AGENT_CLI_USERNAME = "me@example.com"
134
+ $imapCredential = Read-Host "IMAP password or app password" -AsSecureString
135
+ $env:IMAP_AGENT_CLI_PASSWORD = [System.Net.NetworkCredential]::new("", $imapCredential).Password
136
+ Remove-Variable imapCredential
137
+ uvx imap-agent-cli setup --non-interactive
138
+ ```
139
+
140
+ Bash:
141
+
142
+ ```bash
143
+ export IMAP_AGENT_CLI_HOST="imap.example.com"
144
+ export IMAP_AGENT_CLI_USERNAME="me@example.com"
145
+ read -rs -p "IMAP password or app password: " IMAP_AGENT_CLI_PASSWORD
146
+ printf '\n'
147
+ export IMAP_AGENT_CLI_PASSWORD
148
+ uvx imap-agent-cli setup --non-interactive
128
149
  ```
129
150
 
130
- The config file is stored at `~/.imap-agent-cli/config.toml`. Keep passwords in environment variables. Profiles store the name of the password environment variable, not the password itself.
151
+ These variables affect the current shell and its children. An already-running agent does not inherit later changes. Setup uses an environment password without saving its value. Secure defaults supply port `993`, `tls=true`, and `ssl_mode=required`.
131
152
 
132
- The CLI uses standard IMAP username and password authentication. It does not provide OAuth setup. Providers that disable account-password login may require an app password.
153
+ The existing `config init`, `config add-profile`, and `config set-default-profile` commands remain available. `config init` creates a starter file. Prefer `setup` to complete onboarding. Existing `password_env` references continue to work.
133
154
 
134
- Inspect resolved settings without exposing secrets, or list available profiles:
155
+ ### Check configuration
135
156
 
136
157
  ```text
137
- uvx imap-agent-cli config show
138
- uvx imap-agent-cli profiles
139
- uvx imap-agent-cli config check --profile work
158
+ uvx imap-agent-cli config check
159
+ uvx imap-agent-cli config check --profile work --format plain
160
+ uvx imap-agent-cli config check --local
140
161
  ```
141
162
 
142
- Pass `--profile NAME` to any mailbox command to select a non-default profile. Direct commands also accept connection flags and `--password-stdin` for one-off use.
163
+ Checks never write configuration, credentials, or skills. The network check verifies login, opens the default mailbox read-only, and checks bounded metadata access. It never reads bodies or appends a test message. Missing Drafts is a warning for reading. Finding Drafts does not verify append permission or quota. An empty mailbox leaves metadata fetching untested.
164
+
165
+ Use `--config PATH` or `IMAP_AGENT_CLI_CONFIG` for another configuration file. Use `--credentials-file PATH` or `IMAP_AGENT_CLI_CREDENTIALS_FILE` for a separate credential file. Explicit paths work with setup, diagnostics, and mailbox commands. Relative command-line paths resolve from the working directory. Setup saves an explicitly selected credential file path for later use. Custom skill locations use `--skills-dir PATH`.
143
166
 
144
167
  ### Connection security
145
168
 
@@ -261,7 +284,7 @@ uvx imap-agent-cli skill status
261
284
  uvx imap-agent-cli skill status --format plain
262
285
  ```
263
286
 
264
- Normal invocations of an installed CLI update a pristine older managed skill to the running CLI version. Synchronization is local. It does not query PyPI, refresh uv's cache, or update the CLI. Missing skills are never installed automatically. Unmanaged, modified, equal-version, and newer skills are preserved.
287
+ Normal mailbox invocations and top-level help, version, and about commands of an installed CLI update a pristine older managed skill to the running CLI version. Synchronization is local. It does not query PyPI, refresh uv's cache, or update the CLI. Missing skills are never installed automatically. Unmanaged, modified, equal-version, and newer skills are preserved.
265
288
 
266
289
  Restore altered managed content explicitly:
267
290
 
@@ -301,7 +324,7 @@ uvx imap-agent-cli draft create --json draft.json
301
324
  uvx imap-agent-cli draft reply --json reply.json
302
325
  ```
303
326
 
304
- Use `--json -` to read the JSON request from stdin. Failures leave stdout empty and write a compact JSON error to stderr. Logs do not include passwords, message bodies, or attachment content.
327
+ Use `--json -` to read the JSON request from stdin. Operational failures leave stdout empty and write a compact JSON error to stderr. Setup and configuration checks return structured readiness reports when verification or a later step fails. Check the exit status and the `ready` or `ok` field. Human diagnostics go to stderr. Add `--format plain` to setup or config check for a readable report. Logs do not include passwords, message bodies, or attachment content.
305
328
 
306
329
  Default guardrails keep work bounded:
307
330
 
@@ -320,6 +343,7 @@ Commands expose targeted overrides such as `--max-results`, `--max-scan`, `--max
320
343
 
321
344
  | Command | Purpose |
322
345
  | --- | --- |
346
+ | `setup` | Verify and save an account, then install the managed skill |
323
347
  | `config` | Initialize, inspect, validate, and manage profile configuration |
324
348
  | `profiles` | List configured profile names |
325
349
  | `skill` | Install, inspect, or remove the managed agent skill |
@@ -0,0 +1,127 @@
1
+ # Setup and credentials
2
+
3
+ Run `uvx imap-agent-cli setup` in your own terminal. The tool prompts only for missing settings and credentials. Password input is masked with asterisks. It never requests a secret in agent chat.
4
+
5
+ ## Provider requirements
6
+
7
+ | Provider | Credential and creation steps | Renewal |
8
+ | --- | --- | --- |
9
+ | Generic IMAP | Ask your provider for its IMAP hostname, login identity, and authentication requirements. Prefer an app password when offered. An administrator may need to enable IMAP. | Follow the provider's expiration and revocation policy. There is no universal IMAP credential lifetime. |
10
+ | Gmail | Enable 2-Step Verification. Open [Google App Passwords](https://myaccount.google.com/apppasswords) and create one named imap-agent-cli. The server is `imap.gmail.com:993`. | Google revokes app passwords when the account password changes. Generate a replacement. There is no refresh-token flow or configurable expiry in this tool. |
11
+ | Google Workspace | App passwords are usable only when account and organization policy permit them. Administrators control IMAP access and allowed clients. Do not enable legacy less-secure-app access. | Administrator policy or account changes may require a new credential or prevent this authentication method entirely. |
12
+ | Fastmail | Open Settings, Privacy & Security, then Connected apps & API tokens. Create an app password with mail-only access. Use `imap.fastmail.com:993` and your Fastmail login address. Your plan must support third-party IMAP clients. | Replace the credential if disabled or removed. The reviewed guidance gives no fixed expiration. Ordinary Fastmail passwords do not work. |
13
+ | iCloud | Enable two-factor authentication. At [Apple Account](https://account.apple.com/), open Sign-In and Security, then App-Specific Passwords. Generate a password named imap-agent-cli. Use `imap.mail.me.com:993`. | Changing or resetting the primary Apple Account password revokes app-specific passwords. Generate a replacement. |
14
+ | Microsoft 365 and Outlook.com | Unsupported. These services require OAuth. The tool does not register a Microsoft application or implement OAuth. Microsoft app passwords are not a workaround. | Not applicable. |
15
+
16
+ Google recommends OAuth when supported. App passwords may be unavailable for Advanced Protection, security-key-only 2-Step Verification, or organization accounts. Personal Gmail always enables IMAP. Workspace administrators control it separately. Apple documents both short and full-address IMAP usernames. Use `--username` to correct a login identity and `--sender` when the draft sender address differs from it.
17
+
18
+ Official requirements:
19
+
20
+ - [Google app passwords](https://support.google.com/accounts/answer/185833?hl=en)
21
+ - [Gmail client access](https://support.google.com/mail/answer/7126229?hl=en)
22
+ - [Google IMAP endpoint](https://developers.google.com/workspace/gmail/imap/imap-smtp)
23
+ - [Workspace app-password exception](https://knowledge.workspace.google.com/admin/sync/transition-from-less-secure-apps-to-oauth)
24
+ - [Workspace administrator controls](https://knowledge.workspace.google.com/admin/sync/turn-pop-and-imap-on-or-off-for-users)
25
+ - [Fastmail app passwords](https://www.fastmail.help/hc/en-us/articles/360058752854-App-passwords)
26
+ - [Fastmail server settings](https://www.fastmail.help/hc/en-us/articles/1500000278342-Server-names-and-ports)
27
+ - [Apple app-specific passwords](https://support.apple.com/en-us/102654)
28
+ - [iCloud server settings](https://support.apple.com/en-us/102525)
29
+ - [Exchange Online authentication requirements](https://learn.microsoft.com/en-us/exchange/clients-and-mobile-in-exchange-online/deprecation-of-basic-authentication-exchange-online)
30
+ - [Outlook.com IMAP requirements](https://support.microsoft.com/en-US/Outlook/pop-imap-and-smtp-settings-for-outlook-com)
31
+
32
+ Provider presets are connection hints, not a claim that a particular account was tested. Custom domains do not identify their IMAP server reliably. Setup never sends credentials to a guessed server or fetches a webmail URL.
33
+
34
+ ## Permissions and verification
35
+
36
+ Reading needs mailbox lookup and read access. On servers implementing standard IMAP ACLs, these are `l` and `r`. Draft append needs `i` on the selected Drafts folder. The current draft command does not request flags during append. The CLI needs no SMTP sending permission, deletion permission, or folder-management permission. See [IMAP ACL rights](https://www.rfc-editor.org/rfc/rfc4314.html#section-2.1).
37
+
38
+ Provider app passwords may grant broader access, including writes and sending through another program. The CLI enforces its own restrictions. The credential itself is not necessarily read-only.
39
+
40
+ Setup and `config check` authenticate, inspect capabilities and folder names, open the default mailbox with `EXAMINE`, and inspect at most one message's metadata. The search covers at most 250 possible UIDs. No message body or attachment is fetched. No draft is appended. An empty mailbox or unavailable UIDNEXT leaves metadata fetching untested. Missing or ambiguous Drafts is advisory for reading.
41
+
42
+ Verification uses configured connection and read timeouts, a 60-second operation budget after sign-in, and a limit of 1000 returned folders. These are socket timeouts, not a hard wall-clock limit on DNS resolution or a server that sends a slow continuous response. The IMAP library materializes the LIST response before the folder count is checked. This is not a streaming response-size limit.
43
+
44
+ `EXAMINE` avoids changing permanent mailbox state, including `\Recent`. Fetches in ordinary read commands use `BODY.PEEK`. There is no read-write selection fallback. See [IMAP read-only selection](https://www.rfc-editor.org/rfc/rfc3501.html#section-6.3.2).
45
+
46
+ Success establishes only the tested operations from the current execution environment. It does not establish draft append permission, quota, message-body rendering, attachment download, access to every folder, or future credential validity. Sign-in can create provider audit records or security notifications.
47
+
48
+ ## Storage and precedence
49
+
50
+ Ordinary settings live in `~/.imap-agent-cli/config.toml`. Entered credentials live in the separate `credentials.toml`. Profile records contain credential references, never passwords. Saved credentials are bound to the hostname, port, username, transport settings, and authentication method. An endpoint override cannot silently reuse a saved credential for another endpoint.
51
+
52
+ Files use normal inherited ACLs and the process umask. The tool does not require a keyring, change permissions, or encrypt these files. Keep them outside repositories and shared exports. A stolen credential may grant more access than the CLI exposes.
53
+
54
+ Connection settings resolve from flags or the supplied setup target, non-empty environment overrides, the selected saved profile, then built-in defaults. This makes environment settings explicit overrides, including when a saved default profile exists. Password resolution is:
55
+
56
+ 1. Explicit `--password-stdin` input.
57
+ 2. The selected profile's `password_env` variable.
58
+ 3. `IMAP_AGENT_CLI_PASSWORD`.
59
+ 4. A matching saved credential.
60
+
61
+ Environment passwords are never automatically saved. A rejected credential does not trigger another source. A valid environment or stdin credential can bypass an unavailable credentials file. Password characters are preserved, including whitespace.
62
+
63
+ Use `--config PATH` or `IMAP_AGENT_CLI_CONFIG` for a different configuration. Use `--credentials-file PATH` or `IMAP_AGENT_CLI_CREDENTIALS_FILE` for credentials. Explicit path flags override path variables. Relative CLI paths are relative to the working directory. A relative credential path saved in a profile is relative to the configuration directory. An explicit setup `--credentials-file` is saved as an absolute profile reference. A path environment override must also be present in later executions.
64
+
65
+ Replacement verifies before saving. The credential record is staged first, then the profile pointer commits atomically. A failed configuration write cannot replace the credential used by the old profile. Superseded records in the same file that are unreferenced by other profiles in the same configuration are removed after commit. Switching credential files preserves the old file. Use a separate credentials file for each independent configuration file. Do not share internal credential identifiers across independent configurations.
66
+
67
+ File locks coordinate simultaneous CLI writers. Concurrent changes detected before replacement abort the write. Lock files may remain alongside the TOML files. They contain no credentials. Configuration updates preserve unrelated tables, comments, and profiles. An external editor does not participate in the CLI's advisory locking.
68
+
69
+ ## Repair setup
70
+
71
+ Inspect without modifying local files:
72
+
73
+ ```text
74
+ uvx imap-agent-cli config check --profile work --format plain
75
+ uvx imap-agent-cli config check --profile work --local
76
+ ```
77
+
78
+ Replace a saved password in your terminal:
79
+
80
+ ```text
81
+ uvx imap-agent-cli setup --profile work --replace-password
82
+ ```
83
+
84
+ If an environment override is active, unset it first. The diagnostic identifies the exact variable. For the global variable:
85
+
86
+ PowerShell:
87
+
88
+ ```powershell
89
+ Remove-Item Env:IMAP_AGENT_CLI_PASSWORD -ErrorAction SilentlyContinue
90
+ uvx imap-agent-cli setup --profile work --replace-password
91
+ ```
92
+
93
+ Bash:
94
+
95
+ ```bash
96
+ unset IMAP_AGENT_CLI_PASSWORD
97
+ uvx imap-agent-cli setup --profile work --replace-password
98
+ ```
99
+
100
+ Correct a connection or folder:
101
+
102
+ ```text
103
+ uvx imap-agent-cli setup --profile work --host imap.example.com
104
+ uvx imap-agent-cli setup --profile work --default-folder INBOX
105
+ uvx imap-agent-cli setup --profile work --drafts-folder "Drafts"
106
+ ```
107
+
108
+ Changing the endpoint with a saved credential requires an explicit replacement credential. TLS certificate errors need a corrected hostname, trust configuration, or network route. Do not disable encryption as a repair.
109
+
110
+ Inspect a protected skill before deciding whether to replace it:
111
+
112
+ ```text
113
+ uvx imap-agent-cli skill status --format plain
114
+ uvx imap-agent-cli skill install
115
+ ```
116
+
117
+ Setup never forces a skill replacement. Modified and unmanaged skills are preserved. Explicit `skill install --force` still refuses unmanaged content and newer versions. Use `--skills-dir PATH` consistently for custom skill roots.
118
+
119
+ ## Agent execution
120
+
121
+ Mailbox commands never prompt. `setup --non-interactive` fails without writing account settings when required input is missing. It uses provisioned environment or file credentials. Explicit `--password-stdin` can accept a credential from a trusted secret source and saves it during setup. Never put a literal credential in a shell command. Do not combine credential stdin with JSON stdin.
122
+
123
+ Setup does not persist shell variables. An already-running desktop agent does not receive environment changes from another terminal. Sandboxes need access to the selected files and IMAP network endpoint. Remote hosts and containers need their own runtime and credentials, preferably a separate app password per host. Do not automatically copy secrets between hosts. The CLI does not infer that terminal permissions apply to an agent.
124
+
125
+ A successful CLI check does not prove that the harness loaded the installed skill. Start a new agent session if needed. The agent should use diagnostics rather than open credential files. A missing skill is reported separately from mailbox readiness.
126
+
127
+ Initial uv package resolution needs access to package and Python downloads. Offline execution requires a provisioned runtime or a usable cache. The managed skill does not automatically update the CLI.
@@ -1,5 +1,5 @@
1
1
  # /// script
2
- # requires-python = ">=3.11"
2
+ # requires-python = ">=3.11,<3.14"
3
3
  # dependencies = [
4
4
  # "IMAPClient>=3.0.0",
5
5
  # "beautifulsoup4>=4.12.0",
@@ -7,6 +7,9 @@
7
7
  # "markdownify>=0.14.0",
8
8
  # "packaging>=23.2",
9
9
  # "PyYAML>=6.0",
10
+ # "prompt-toolkit>=3.0.43",
11
+ # "tomlkit>=0.13.0",
12
+ # "filelock>=3.16.0",
10
13
  # ]
11
14
  # ///
12
15
  """Local development wrapper for imap-agent-cli."""
@@ -4,11 +4,11 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "imap-agent-cli"
7
- version = "0.2.1"
7
+ version = "0.3.0"
8
8
  description = "Agent-first IMAP CLI for safe email search, read, attachment download, and draft creation"
9
9
  readme = "README.md"
10
10
  license = "MIT"
11
- requires-python = ">=3.11"
11
+ requires-python = ">=3.11,<3.14"
12
12
  authors = [
13
13
  { name = "Paul" },
14
14
  ]
@@ -34,6 +34,9 @@ dependencies = [
34
34
  "markdownify>=0.14.0",
35
35
  "packaging>=23.2",
36
36
  "PyYAML>=6.0",
37
+ "prompt-toolkit>=3.0.43",
38
+ "tomlkit>=0.13.0",
39
+ "filelock>=3.16.0",
37
40
  ]
38
41
 
39
42
  [project.optional-dependencies]