mayai-pec-cli 0.1.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.
@@ -0,0 +1,46 @@
1
+ # Python
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+ *.so
6
+ .Python
7
+
8
+ # Distribution / packaging
9
+ build/
10
+ dist/
11
+ *.egg-info/
12
+ *.egg
13
+ pip-wheel-metadata/
14
+
15
+ # Virtual environments
16
+ .venv/
17
+ venv/
18
+ env/
19
+ ENV/
20
+
21
+ # Test / lint caches
22
+ .pytest_cache/
23
+ .ruff_cache/
24
+ .mypy_cache/
25
+ .coverage
26
+ htmlcov/
27
+
28
+ # Editors / OS
29
+ .vscode/
30
+ .idea/
31
+ *.swp
32
+ .DS_Store
33
+
34
+ # Local Claude / agent state
35
+ .claude/
36
+
37
+ # Credentials and local config (never commit PEC passwords or Fernet keys)
38
+ credentials.json
39
+ *.credentials.json
40
+ key.bin
41
+ .env
42
+ .env.*
43
+ config.json
44
+
45
+ # Attachments downloaded by `pec get --save-attachments`
46
+ attachments/
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 MayAI
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,20 @@
1
+ .PHONY: install dev test lint clean
2
+
3
+ PYTHON ?= python3
4
+
5
+ install:
6
+ $(PYTHON) -m pip install -e .
7
+
8
+ dev:
9
+ $(PYTHON) -m pip install -e ".[dev]"
10
+
11
+ test:
12
+ $(PYTHON) -m pytest tests/
13
+
14
+ lint:
15
+ $(PYTHON) -m ruff check pec_cli/
16
+
17
+ clean:
18
+ find . -type d -name __pycache__ -prune -exec rm -rf {} +
19
+ find . -type f -name '*.pyc' -delete
20
+ rm -rf build dist *.egg-info .pytest_cache .ruff_cache
@@ -0,0 +1,261 @@
1
+ Metadata-Version: 2.4
2
+ Name: mayai-pec-cli
3
+ Version: 0.1.0
4
+ Summary: Command-line client for Italian PEC (Posta Elettronica Certificata) — built for AI agents and developers.
5
+ Project-URL: Homepage, https://mayai.it
6
+ Project-URL: Documentation, https://github.com/mayai-it/pec-cli#readme
7
+ Project-URL: Repository, https://github.com/mayai-it/pec-cli
8
+ Project-URL: Issues, https://github.com/mayai-it/pec-cli/issues
9
+ Project-URL: Changelog, https://github.com/mayai-it/pec-cli/releases
10
+ Author-email: MayAI <info@mayai.it>
11
+ Maintainer-email: MayAI <info@mayai.it>
12
+ License: MIT
13
+ License-File: LICENSE
14
+ Keywords: ai-agents,aruba,cli,command-line,email,imap,infocert,italian,italy,legalmail,llm,namirial,pec,posta-elettronica-certificata,poste-italiane,smtp
15
+ Classifier: Development Status :: 3 - Alpha
16
+ Classifier: Environment :: Console
17
+ Classifier: Intended Audience :: Developers
18
+ Classifier: Intended Audience :: Legal Industry
19
+ Classifier: Intended Audience :: System Administrators
20
+ Classifier: License :: OSI Approved :: MIT License
21
+ Classifier: Natural Language :: English
22
+ Classifier: Natural Language :: Italian
23
+ Classifier: Operating System :: MacOS
24
+ Classifier: Operating System :: Microsoft :: Windows
25
+ Classifier: Operating System :: OS Independent
26
+ Classifier: Operating System :: POSIX :: Linux
27
+ Classifier: Programming Language :: Python :: 3
28
+ Classifier: Programming Language :: Python :: 3 :: Only
29
+ Classifier: Programming Language :: Python :: 3.11
30
+ Classifier: Programming Language :: Python :: 3.12
31
+ Classifier: Programming Language :: Python :: 3.13
32
+ Classifier: Topic :: Communications :: Email
33
+ Classifier: Topic :: Communications :: Email :: Post-Office :: IMAP
34
+ Classifier: Topic :: Communications :: Email :: Post-Office :: POP3
35
+ Classifier: Topic :: Office/Business
36
+ Classifier: Topic :: Utilities
37
+ Classifier: Typing :: Typed
38
+ Requires-Python: >=3.11
39
+ Requires-Dist: click>=8.1.0
40
+ Requires-Dist: cryptography>=42.0.0
41
+ Requires-Dist: keyring>=24.0.0
42
+ Provides-Extra: dev
43
+ Requires-Dist: build>=1.2.0; extra == 'dev'
44
+ Requires-Dist: pytest>=8.0.0; extra == 'dev'
45
+ Requires-Dist: ruff>=0.5.0; extra == 'dev'
46
+ Requires-Dist: twine>=5.0.0; extra == 'dev'
47
+ Description-Content-Type: text/markdown
48
+
49
+ # pec-cli
50
+
51
+ Command-line client for **PEC** (Posta Elettronica Certificata — Italian
52
+ certified email), built for both humans and AI agents. Designed to be
53
+ context-efficient: the default output strips empty fields, and `--json`
54
+ produces NDJSON suitable for piping into LLMs or jq.
55
+
56
+ Talks to the standard IMAP/SMTP endpoints exposed by Italian PEC providers
57
+ (Aruba, Legalmail/InfoCert, Namirial, Register.it, Poste Italiane, Pec.it),
58
+ all over SSL/TLS.
59
+
60
+ Part of [MayAI CLI](https://mayai.it).
61
+
62
+ ## Requirements
63
+
64
+ - Python 3.11+
65
+ - A working PEC account from one of the supported providers
66
+
67
+ ## Installation
68
+
69
+ From PyPI (recommended):
70
+
71
+ ```bash
72
+ pip install mayai-pec-cli
73
+ ```
74
+
75
+ The package installs a single `pec` command on your `PATH`.
76
+
77
+ From source:
78
+
79
+ ```bash
80
+ git clone https://github.com/mayai-it/pec-cli.git
81
+ cd pec-cli
82
+ make install
83
+ ```
84
+
85
+ For local development (adds `pytest`, `ruff`):
86
+
87
+ ```bash
88
+ make dev
89
+ ```
90
+
91
+ ## Quick start
92
+
93
+ ```bash
94
+ # 1. Authenticate (password prompted interactively, never passed as a flag)
95
+ pec auth login --address mia@pec.it --provider aruba
96
+
97
+ # 2. Verify
98
+ pec auth status
99
+
100
+ # 3. List the 20 most recent PECs in the inbox as NDJSON
101
+ pec --json list
102
+
103
+ # 4. Filter to unread, since a given date
104
+ pec --json list --unread --from 2025-01-01 --limit 50
105
+
106
+ # 5. Read a single message and save its attachments to ./attachments
107
+ pec get 1234 --save-attachments ./attachments
108
+
109
+ # 6. Inspect the parsed PEC certification (daticert.xml) for a message
110
+ pec get 1234 --cert --json
111
+
112
+ # 7. Trace the full receipt chain for an original message id
113
+ pec trace 'opec123.20260321102500.12345.67.1.1@pec.it'
114
+
115
+ # 8. Send a PEC with an attachment
116
+ pec send --to dest@pec.it --subject "Oggetto" --file body.txt --attach doc.pdf
117
+ ```
118
+
119
+ ## Command reference
120
+
121
+ | Command | Description |
122
+ |---|---|
123
+ | `pec auth login --address ADDR --provider P` | Prompt for password, verify via IMAP, save credentials in the system keyring (Fernet-encrypted file as fallback). |
124
+ | `pec auth status` | Show whether credentials are present. |
125
+ | `pec auth logout` | Delete saved credentials (keyring entry + any local encryption key). |
126
+ | `pec list [--folder F] [--unread] [--from YYYY-MM-DD] [--limit N]` | List PEC messages (default folder `inbox`, default limit 20). |
127
+ | `pec get <id> [--folder F] [--save-attachments DIR] [--cert]` | Fetch a single PEC by IMAP UID; `--cert` includes the parsed `daticert.xml` certification; `--save-attachments` writes attachments to `DIR`. |
128
+ | `pec trace <message-id> [--folder F] [--limit N]` | Find every receipt in the folder whose `daticert.xml` references this message id, ordered chronologically (`accettazione` → `presa-in-carico` → `avvenuta-consegna` / `errore-consegna`). |
129
+ | `pec send --to ADDR --subject S (--body T | --file F) [--attach F] [--cc ADDR] [--dry-run]` | Send a PEC; `--to`, `--cc`, `--attach` are repeatable. |
130
+
131
+ ### Global flags
132
+
133
+ These work in any position (before or after the subcommand):
134
+
135
+ | Flag | Effect |
136
+ |---|---|
137
+ | `--json` | Emit one JSON object per line (NDJSON). |
138
+ | `--verbose` | Log IMAP/SMTP timings and certification metadata to stderr. |
139
+ | `-h`, `--help` | Show help for the current command. |
140
+
141
+ ### Exit codes
142
+
143
+ | Code | Meaning |
144
+ |---|---|
145
+ | `0` | Success |
146
+ | `1` | Application error (network, send failure, bad arguments) |
147
+ | `2` | Not authenticated — run `pec auth login` |
148
+
149
+ ## Supported providers
150
+
151
+ | Provider | `--provider` | IMAP | SMTP |
152
+ |----------------------|--------------|-------------------------------|-------------------------------|
153
+ | Aruba PEC | `aruba` | `imaps.pec.aruba.it:993` | `smtps.pec.aruba.it:465` |
154
+ | Legalmail (InfoCert) | `legalmail` | `imapmail.legalmail.it:993` | `smtpmail.legalmail.it:465` |
155
+ | Namirial | `namirial` | `imap.namirialpec.it:993` | `smtp.namirialpec.it:465` |
156
+ | Register.it | `register` | `imap.pec.register.it:993` | `smtp.pec.register.it:465` |
157
+ | Poste Italiane | `poste` | `imappec.poste.it:993` | `smtppec.poste.it:465` |
158
+ | Pec.it | `pec.it` | `imap.pec.it:993` | `smtp.pec.it:465` |
159
+
160
+ All providers use implicit SSL/TLS (IMAPS:993 / SMTPS:465). Username is the
161
+ full PEC address; the password is the one provided by the PEC provider.
162
+
163
+ ## Authentication
164
+
165
+ PEC is plain IMAP/SMTP with SSL — there's no OAuth. `pec auth login`:
166
+
167
+ 1. Prompts you for the password on stderr (never echoed, never on argv).
168
+ 2. Verifies it by opening an IMAP connection and logging in.
169
+ 3. Stores the password in the **system keyring** — macOS Keychain, Linux
170
+ Secret Service, or Windows Credential Locker (DPAPI) — under the service
171
+ name `mayai-cli-pec` and the PEC address as the username.
172
+ 4. Writes a small metadata file at
173
+ `~/.config/mayai-cli/pec/credentials.json` (mode `0600`) recording the
174
+ address, provider, and where the password lives.
175
+
176
+ On headless boxes or CI where no keyring backend is available, the CLI
177
+ transparently falls back to **Fernet** encryption: a 32-byte key at
178
+ `~/.config/mayai-cli/pec/key.bin` (mode `0600`) encrypts the password inside
179
+ `credentials.json`. Existing installs that still have a `key.bin` are
180
+ migrated to the keyring on the next `pec auth login` (and `key.bin` is then
181
+ removed).
182
+
183
+ `pec auth logout` clears the keyring entry and removes the on-disk files.
184
+ The password is never written to plain disk and never accepted via a
185
+ command-line flag.
186
+
187
+ ## Output format
188
+
189
+ - **Default** — compact human-readable text. Empty / null fields are stripped
190
+ so terminal output stays scannable.
191
+ - **`--json`** — NDJSON. One object per line; lists stream one element per
192
+ line so consumers can process incrementally.
193
+ - **`--verbose`** — adds protocol timing lines on stderr (e.g.
194
+ `imap: connected to imaps.pec.aruba.it:993 as mia@pec.it (284ms)`), and
195
+ surfaces the PEC certification attachments (`daticert.xml`,
196
+ `postacert.eml`, `smime.p7s/p7m`) that are normally hidden.
197
+
198
+ Errors always go to stderr, prefixed with `error:`.
199
+
200
+ ### What `pec list` returns
201
+
202
+ Each row carries the IMAP UID (`id`), a normalized ISO date, the sender, the
203
+ subject, the PEC type (`accettazione`, `consegna`, `errore`, `preavviso`, …)
204
+ when present, and read/attachment flags.
205
+
206
+ ### What `pec get` returns
207
+
208
+ The full message — `from`, `to`, `cc`, `subject`, `date`, plain-text body
209
+ (HTML body too with `--verbose`), and the attachment list with each
210
+ attachment's filename and size in bytes.
211
+
212
+ PEC messages that carry a `daticert.xml` certification (every receipt and
213
+ every sent PEC) get an extra `pec_cert_type` field in the default output,
214
+ e.g. `"avvenuta-consegna"`. Pass `--cert` to also include the fully parsed
215
+ certification (`tipo`, `mittente`, `destinatari`, `data`, `identificativo`,
216
+ `riferimento_message_id`, `oggetto`, optional `errore`):
217
+
218
+ ```bash
219
+ pec get 1234 --cert --json
220
+ ```
221
+
222
+ By default the PEC certification files (`daticert.xml`, `postacert.eml`,
223
+ `smime.p7s`, `smime.p7m`) are filtered out of both the listed attachments
224
+ and the saved files; pass `--verbose` to include them. Use
225
+ `--save-attachments DIR` to write attachments to disk under `DIR`
226
+ (created if it doesn't exist).
227
+
228
+ ### What `pec trace` returns
229
+
230
+ `pec trace <message-id>` scans recent PECs in a folder (default `inbox`,
231
+ `--limit 200`), reads each `daticert.xml`, and returns the chain whose
232
+ `riferimento_message_id` matches the given id, sorted chronologically:
233
+
234
+ ```json
235
+ {
236
+ "message_id": "opec123.20260321102500.12345.67.1.1@pec.it",
237
+ "events": [
238
+ {"id": "204", "tipo": "accettazione", "data": "2026-03-21T10:25:00+01:00", "...": "..."},
239
+ {"id": "205", "tipo": "presa-in-carico", "data": "2026-03-21T10:25:04+01:00", "...": "..."},
240
+ {"id": "206", "tipo": "avvenuta-consegna","data": "2026-03-21T10:25:07+01:00", "...": "..."}
241
+ ],
242
+ "count": 3
243
+ }
244
+ ```
245
+
246
+ The argument is the certified `identificativo` of the original message — the
247
+ same value `pec get --cert` returns under `pec_cert.identificativo`. Surround
248
+ or strip `<...>` brackets as you wish; the CLI normalizes them.
249
+
250
+ ## Development
251
+
252
+ ```bash
253
+ make dev # install with dev extras
254
+ make test # run pytest
255
+ make lint # run ruff
256
+ make clean # remove caches and build artifacts
257
+ ```
258
+
259
+ ## License
260
+
261
+ MIT — see [LICENSE](./LICENSE).
@@ -0,0 +1,213 @@
1
+ # pec-cli
2
+
3
+ Command-line client for **PEC** (Posta Elettronica Certificata — Italian
4
+ certified email), built for both humans and AI agents. Designed to be
5
+ context-efficient: the default output strips empty fields, and `--json`
6
+ produces NDJSON suitable for piping into LLMs or jq.
7
+
8
+ Talks to the standard IMAP/SMTP endpoints exposed by Italian PEC providers
9
+ (Aruba, Legalmail/InfoCert, Namirial, Register.it, Poste Italiane, Pec.it),
10
+ all over SSL/TLS.
11
+
12
+ Part of [MayAI CLI](https://mayai.it).
13
+
14
+ ## Requirements
15
+
16
+ - Python 3.11+
17
+ - A working PEC account from one of the supported providers
18
+
19
+ ## Installation
20
+
21
+ From PyPI (recommended):
22
+
23
+ ```bash
24
+ pip install mayai-pec-cli
25
+ ```
26
+
27
+ The package installs a single `pec` command on your `PATH`.
28
+
29
+ From source:
30
+
31
+ ```bash
32
+ git clone https://github.com/mayai-it/pec-cli.git
33
+ cd pec-cli
34
+ make install
35
+ ```
36
+
37
+ For local development (adds `pytest`, `ruff`):
38
+
39
+ ```bash
40
+ make dev
41
+ ```
42
+
43
+ ## Quick start
44
+
45
+ ```bash
46
+ # 1. Authenticate (password prompted interactively, never passed as a flag)
47
+ pec auth login --address mia@pec.it --provider aruba
48
+
49
+ # 2. Verify
50
+ pec auth status
51
+
52
+ # 3. List the 20 most recent PECs in the inbox as NDJSON
53
+ pec --json list
54
+
55
+ # 4. Filter to unread, since a given date
56
+ pec --json list --unread --from 2025-01-01 --limit 50
57
+
58
+ # 5. Read a single message and save its attachments to ./attachments
59
+ pec get 1234 --save-attachments ./attachments
60
+
61
+ # 6. Inspect the parsed PEC certification (daticert.xml) for a message
62
+ pec get 1234 --cert --json
63
+
64
+ # 7. Trace the full receipt chain for an original message id
65
+ pec trace 'opec123.20260321102500.12345.67.1.1@pec.it'
66
+
67
+ # 8. Send a PEC with an attachment
68
+ pec send --to dest@pec.it --subject "Oggetto" --file body.txt --attach doc.pdf
69
+ ```
70
+
71
+ ## Command reference
72
+
73
+ | Command | Description |
74
+ |---|---|
75
+ | `pec auth login --address ADDR --provider P` | Prompt for password, verify via IMAP, save credentials in the system keyring (Fernet-encrypted file as fallback). |
76
+ | `pec auth status` | Show whether credentials are present. |
77
+ | `pec auth logout` | Delete saved credentials (keyring entry + any local encryption key). |
78
+ | `pec list [--folder F] [--unread] [--from YYYY-MM-DD] [--limit N]` | List PEC messages (default folder `inbox`, default limit 20). |
79
+ | `pec get <id> [--folder F] [--save-attachments DIR] [--cert]` | Fetch a single PEC by IMAP UID; `--cert` includes the parsed `daticert.xml` certification; `--save-attachments` writes attachments to `DIR`. |
80
+ | `pec trace <message-id> [--folder F] [--limit N]` | Find every receipt in the folder whose `daticert.xml` references this message id, ordered chronologically (`accettazione` → `presa-in-carico` → `avvenuta-consegna` / `errore-consegna`). |
81
+ | `pec send --to ADDR --subject S (--body T | --file F) [--attach F] [--cc ADDR] [--dry-run]` | Send a PEC; `--to`, `--cc`, `--attach` are repeatable. |
82
+
83
+ ### Global flags
84
+
85
+ These work in any position (before or after the subcommand):
86
+
87
+ | Flag | Effect |
88
+ |---|---|
89
+ | `--json` | Emit one JSON object per line (NDJSON). |
90
+ | `--verbose` | Log IMAP/SMTP timings and certification metadata to stderr. |
91
+ | `-h`, `--help` | Show help for the current command. |
92
+
93
+ ### Exit codes
94
+
95
+ | Code | Meaning |
96
+ |---|---|
97
+ | `0` | Success |
98
+ | `1` | Application error (network, send failure, bad arguments) |
99
+ | `2` | Not authenticated — run `pec auth login` |
100
+
101
+ ## Supported providers
102
+
103
+ | Provider | `--provider` | IMAP | SMTP |
104
+ |----------------------|--------------|-------------------------------|-------------------------------|
105
+ | Aruba PEC | `aruba` | `imaps.pec.aruba.it:993` | `smtps.pec.aruba.it:465` |
106
+ | Legalmail (InfoCert) | `legalmail` | `imapmail.legalmail.it:993` | `smtpmail.legalmail.it:465` |
107
+ | Namirial | `namirial` | `imap.namirialpec.it:993` | `smtp.namirialpec.it:465` |
108
+ | Register.it | `register` | `imap.pec.register.it:993` | `smtp.pec.register.it:465` |
109
+ | Poste Italiane | `poste` | `imappec.poste.it:993` | `smtppec.poste.it:465` |
110
+ | Pec.it | `pec.it` | `imap.pec.it:993` | `smtp.pec.it:465` |
111
+
112
+ All providers use implicit SSL/TLS (IMAPS:993 / SMTPS:465). Username is the
113
+ full PEC address; the password is the one provided by the PEC provider.
114
+
115
+ ## Authentication
116
+
117
+ PEC is plain IMAP/SMTP with SSL — there's no OAuth. `pec auth login`:
118
+
119
+ 1. Prompts you for the password on stderr (never echoed, never on argv).
120
+ 2. Verifies it by opening an IMAP connection and logging in.
121
+ 3. Stores the password in the **system keyring** — macOS Keychain, Linux
122
+ Secret Service, or Windows Credential Locker (DPAPI) — under the service
123
+ name `mayai-cli-pec` and the PEC address as the username.
124
+ 4. Writes a small metadata file at
125
+ `~/.config/mayai-cli/pec/credentials.json` (mode `0600`) recording the
126
+ address, provider, and where the password lives.
127
+
128
+ On headless boxes or CI where no keyring backend is available, the CLI
129
+ transparently falls back to **Fernet** encryption: a 32-byte key at
130
+ `~/.config/mayai-cli/pec/key.bin` (mode `0600`) encrypts the password inside
131
+ `credentials.json`. Existing installs that still have a `key.bin` are
132
+ migrated to the keyring on the next `pec auth login` (and `key.bin` is then
133
+ removed).
134
+
135
+ `pec auth logout` clears the keyring entry and removes the on-disk files.
136
+ The password is never written to plain disk and never accepted via a
137
+ command-line flag.
138
+
139
+ ## Output format
140
+
141
+ - **Default** — compact human-readable text. Empty / null fields are stripped
142
+ so terminal output stays scannable.
143
+ - **`--json`** — NDJSON. One object per line; lists stream one element per
144
+ line so consumers can process incrementally.
145
+ - **`--verbose`** — adds protocol timing lines on stderr (e.g.
146
+ `imap: connected to imaps.pec.aruba.it:993 as mia@pec.it (284ms)`), and
147
+ surfaces the PEC certification attachments (`daticert.xml`,
148
+ `postacert.eml`, `smime.p7s/p7m`) that are normally hidden.
149
+
150
+ Errors always go to stderr, prefixed with `error:`.
151
+
152
+ ### What `pec list` returns
153
+
154
+ Each row carries the IMAP UID (`id`), a normalized ISO date, the sender, the
155
+ subject, the PEC type (`accettazione`, `consegna`, `errore`, `preavviso`, …)
156
+ when present, and read/attachment flags.
157
+
158
+ ### What `pec get` returns
159
+
160
+ The full message — `from`, `to`, `cc`, `subject`, `date`, plain-text body
161
+ (HTML body too with `--verbose`), and the attachment list with each
162
+ attachment's filename and size in bytes.
163
+
164
+ PEC messages that carry a `daticert.xml` certification (every receipt and
165
+ every sent PEC) get an extra `pec_cert_type` field in the default output,
166
+ e.g. `"avvenuta-consegna"`. Pass `--cert` to also include the fully parsed
167
+ certification (`tipo`, `mittente`, `destinatari`, `data`, `identificativo`,
168
+ `riferimento_message_id`, `oggetto`, optional `errore`):
169
+
170
+ ```bash
171
+ pec get 1234 --cert --json
172
+ ```
173
+
174
+ By default the PEC certification files (`daticert.xml`, `postacert.eml`,
175
+ `smime.p7s`, `smime.p7m`) are filtered out of both the listed attachments
176
+ and the saved files; pass `--verbose` to include them. Use
177
+ `--save-attachments DIR` to write attachments to disk under `DIR`
178
+ (created if it doesn't exist).
179
+
180
+ ### What `pec trace` returns
181
+
182
+ `pec trace <message-id>` scans recent PECs in a folder (default `inbox`,
183
+ `--limit 200`), reads each `daticert.xml`, and returns the chain whose
184
+ `riferimento_message_id` matches the given id, sorted chronologically:
185
+
186
+ ```json
187
+ {
188
+ "message_id": "opec123.20260321102500.12345.67.1.1@pec.it",
189
+ "events": [
190
+ {"id": "204", "tipo": "accettazione", "data": "2026-03-21T10:25:00+01:00", "...": "..."},
191
+ {"id": "205", "tipo": "presa-in-carico", "data": "2026-03-21T10:25:04+01:00", "...": "..."},
192
+ {"id": "206", "tipo": "avvenuta-consegna","data": "2026-03-21T10:25:07+01:00", "...": "..."}
193
+ ],
194
+ "count": 3
195
+ }
196
+ ```
197
+
198
+ The argument is the certified `identificativo` of the original message — the
199
+ same value `pec get --cert` returns under `pec_cert.identificativo`. Surround
200
+ or strip `<...>` brackets as you wish; the CLI normalizes them.
201
+
202
+ ## Development
203
+
204
+ ```bash
205
+ make dev # install with dev extras
206
+ make test # run pytest
207
+ make lint # run ruff
208
+ make clean # remove caches and build artifacts
209
+ ```
210
+
211
+ ## License
212
+
213
+ MIT — see [LICENSE](./LICENSE).
@@ -0,0 +1,3 @@
1
+ """pec-cli — Read and send PEC (Posta Elettronica Certificata) from the terminal."""
2
+
3
+ __version__ = "0.1.0"
@@ -0,0 +1,21 @@
1
+ """Credential storage for PEC accounts."""
2
+
3
+ from pec_cli.auth.credentials import (
4
+ PROVIDERS,
5
+ Credentials,
6
+ ProviderConfig,
7
+ delete_credentials,
8
+ get_provider,
9
+ load_credentials,
10
+ save_credentials,
11
+ )
12
+
13
+ __all__ = [
14
+ "Credentials",
15
+ "PROVIDERS",
16
+ "ProviderConfig",
17
+ "delete_credentials",
18
+ "get_provider",
19
+ "load_credentials",
20
+ "save_credentials",
21
+ ]