@recynie/pi-coremail
v0.4.1
Published
Independent IMAP/SMTP and Coremail Web extensions for pi
Maintainers
Readme
pi-coremail
A secure, lightweight pi package for Coremail deployments. It contains two independent extension modules:
- Coremail IMAP/SMTP reads and sends ordinary mail through standard protocols.
- Coremail Web manages contacts, contact groups, Web drafts, attachments, and server-side scheduled mail through Coremail's internal Web API.
Each module has its own extension entry, configuration file, Secret Service credential, Slash Command, and agent tool. Users can enable either module without enabling the other.
Features
IMAP/SMTP module
- Lists, searches, reads, marks, and deletes messages
- Creates, updates, sends, and deletes drafts
- Sends messages and downloads attachments
- Detects common English and Chinese Drafts/Sent folder names
Web module
- Lists, reads, creates, updates, and deletes contacts by server id
- Manages contact groups and group membership
- Lists Web drafts and schedules existing drafts with their attachments
- Creates, lists, and cancels server-side scheduled messages, including newly composed messages with attachments
- Maintains Coremail cookies and
sid, and retries once after a recoverable session expiry - Rejects unsupported verification-code and secondary-authentication login flows clearly
Requirements
- Node.js 20 or later
- pi coding agent
- Linux Secret Service and
secret-tool(libsecret-toolson Debian and Ubuntu) - IMAP/SMTP enabled by the administrator when using the IMAP/SMTP module
- A compatible Coremail XT Web deployment when using the Web module
Install secret-tool on Debian or Ubuntu:
sudo apt install libsecret-toolsInstallation
pi install npm:@recynie/pi-coremailAdd -l for a project-local installation. If pi is already running, use /reload after installation.
Other package operations:
pi update --extension npm:@recynie/pi-coremail
pi remove npm:@recynie/pi-coremailFor development:
git clone https://github.com/recynie/pi-coremail.git
cd pi-coremail
pnpm install
pnpm check
pi install .Enable modules independently
The package manifest exposes these entries separately:
extensions/coremail.ts
extensions/coremail-web.tsRun pi config to enable or disable either extension. Press Tab in pi config to switch between global and project-local settings.
Package filters can also select one entry explicitly. IMAP/SMTP only:
{
"packages": [
{
"source": "npm:@recynie/pi-coremail",
"extensions": ["extensions/coremail.ts"]
}
]
}Web only:
{
"packages": [
{
"source": "npm:@recynie/pi-coremail",
"extensions": ["extensions/coremail-web.ts"]
}
]
}IMAP/SMTP account
Use one parameterized Slash Command:
/coremail login [account]
/coremail status
/coremail logoutThe Slash Command menu shows this syntax and each action's description. After typing /coremail , select or complete login, status, or logout; login can also complete the currently configured account.
/coremail login prompts for the account, IMAP and SMTP hosts, ports and security modes, and a masked password. It verifies both protocols before storing anything.
The non-sensitive configuration is stored with mode 0600 at:
~/.pi/agent/coremail.jsonPI_CODING_AGENT_DIR changes the parent directory. The password is stored in Secret Service with:
service=pi-coremail
account=<email-address>/coremail logout removes only this configuration and credential. It does not affect Coremail Web.
The IMAP/SMTP module also retains its documented ephemeral environment configuration (COREMAIL_ACCOUNT, COREMAIL_PASSWORD, COREMAIL_IMAP_HOST, and COREMAIL_SMTP_HOST, plus optional port/security variables).
coremail agent tool
| Action | Description |
|---|---|
| folders | List mailbox folders |
| list | List messages in a folder |
| list_drafts | Detect and list the Drafts folder |
| search | Search message metadata/content |
| read | Read a message and attachment metadata |
| set_seen | Mark a message read or unread |
| create_draft | Create a draft |
| update_draft | Replace a draft |
| send_draft | Send a draft and remove the original |
| send | Send immediately |
| delete | Delete by folder-scoped IMAP UID |
| download_attachment | Download an attachment without overwriting an existing file |
send and send_draft deliver immediately. IMAP UIDs are valid only inside the folder returned with them.
Coremail Web account
Use the independent Web command:
/coremail-web login [account]
/coremail-web status
/coremail-web logoutThe Slash Command menu shows this syntax and each action's description. After typing /coremail-web , select or complete login, status, or logout; login can also complete the currently configured Web account.
/coremail-web login prompts for:
- Account
- Configurable HTTPS Web Base URL, such as
https://mail.example.edu/ - Masked Web password
It performs a real Web login and a read-only authenticated API check before saving the configuration. Production code does not contain an institution-specific hostname.
The non-sensitive configuration is stored with mode 0600 at:
~/.pi/agent/coremail-web.jsonExample:
{
"account": "[email protected]",
"baseUrl": "https://mail.example.edu/"
}The Web password has a separate Secret Service identity:
service=pi-coremail-web
account=<email-address>/coremail-web logout removes the Web configuration and all credentials in the dedicated pi-coremail-web namespace, including stale entries from an earlier account. Cookies and sid are held in memory and are discarded with the client/session. The IMAP/SMTP module remains configured.
coremail_web agent tool
| Action | Description |
|---|---|
| contacts_list | List or search contacts |
| contacts_get | Read one contact by server id |
| contacts_create | Create a contact |
| contacts_update | Update a contact by server id |
| contacts_delete | Delete a contact by server id |
| groups_list | List groups, reserved state, and membership |
| groups_create | Create a group with optional members |
| groups_update | Rename a group and replace membership |
| groups_delete | Empty and delete a non-reserved group |
| groups_add_members | Add contacts to a group |
| groups_remove_members | Remove contacts from a group |
| groups_move_members | Move contacts between groups |
| drafts_list | List or subject/recipient-filter ordinary Web drafts and their server ids |
| scheduled_list | List messages still waiting for scheduled delivery |
| schedule | Compose and schedule a real message, with optional attachment paths |
| scheduled_from_draft | Schedule an existing Web draft while preserving its attachments |
| scheduled_cancel | Cancel pending delivery and preserve the message as a draft |
Contact models include the server id, name, primary email, additional emails, mobile number, and group ids. Mutation operations use server ids and never rely on list positions. Coremail-reserved groups are read-only.
A newly composed scheduled message accepts to, optional cc/bcc, subject, exactly one of text or html, optional attachments paths relative to pi's working directory, a future ISO 8601 scheduledAt, and an optional IANA timeZone.
To schedule an existing draft, call drafts_list, then pass its Web server id as draftId to scheduled_from_draft with scheduledAt and optional timeZone. An IMAP UID is not a Web draft id. Coremail converts the draft to a scheduled message and retains its existing attachments.
Both scheduling actions are real external sends: Coremail will deliver the message at the requested time without another pi confirmation.
Cancellation results are explicit:
cancelled: pending delivery was cancelled and Coremail converted it to a draft, retaining attachments supported by the server.delivering: cancellation raced with a message that entered delivery.not_found: no pending scheduled item has that id; it may already have been delivered or removed.
Interactive tool display
Both tools provide action-specific interactive rendering. A stable English title identifies the extension and operation, then appends a concise outcome when execution finishes:
Coremail · search “meeting” in INBOX → 3 matches
Coremail Web · schedule “Reminder” for Sep 1, 09:00 → successCollapsed results show a short preview. Expanded results show bounded structured details such as message UIDs, contact and group ids, recipients, attachments, delivery states, and scheduled times. Lists display up to 3 items when collapsed and 50 when expanded; message bodies display up to 3 non-empty lines when collapsed and 100 lines when expanded. Every projected string and body line also has visible-column and code-point bounds. Non-theme terminal escape/control sequences are removed before projection or rendering. Omitted or truncated data is identified explicitly. Dates use an English short format in the runtime's local time zone. An explicitly supplied scheduling timeZone takes precedence, and expanded scheduled results also show the exact ISO time and time-zone name.
The TUI uses pi's default pending, success, and error tool backgrounds with semantic title, parameter, status, metadata, and body styles. Operations whose requested outcome is already explicit use the ordinary muted suffix success instead of repeating the verb (for example, delete … → success); resulting ids retain the normal accent variable style. Ordinary content statuses—including unread, read-only, rejected recipients, and cancellation race states—use the normal output style. The warning color and bold weight are reserved for genuinely warning title suffixes. Expanded failures add bounded safe context such as the action, mailbox UID, server id, and sanitized error code. Protocol response text, commands, and private response bodies are excluded. Successful SMTP delivery followed by failure to remove the source draft is identified in text so users are not encouraged to send the message again. Scheduled cancellation keeps cancelled, delivering, and not_found semantically distinct.
Agent-visible tool content retains the existing JSON serialization and is limited to 50 KB or 2,000 lines. Tool details additionally contain a typed, bounded UI projection. The projection includes only fields needed by the collapsed and expanded display and excludes passwords, login data, cookies, sid, private response bodies, and stack traces. Older session entries without the projection remain visible through a bounded fallback.
Internal Web API compatibility
Coremail Web uses undocumented internal APIs, including pab:* contact operations and mbox:compose. These APIs can differ between Coremail versions and deployments. The client centralizes transport and response parsing so compatibility failures produce a Coremail code without exposing response bodies.
The client supports the ordinary username/password login form used by Coremail XT. It fails clearly when the deployment requires a CAPTCHA, SMS/email verification, secondary authentication, or an unrecognized login flow. It does not bypass those controls.
The HTTPS Web Base URL is configurable. A successful test against one institution does not guarantee compatibility with every Coremail release.
Security
- Passwords are entered through masked TUI fields and stored in Linux Secret Service.
- IMAP/SMTP and Web credentials use separate Secret Service namespaces.
- Passwords, login request bodies, cookies,
sid, and private API response bodies are never included in tool details or errors. - Node.js TLS certificate verification remains enabled.
- Contact and message data enters agent context only when the corresponding tool operation returns it.
- Scheduled sending is an external side effect. Review recipients, attachment paths, and time before requesting
scheduleorscheduled_from_draft. - Attachment downloads use mode
0600and never overwrite existing files. - A pi extension runs with the current user's permissions. Review the source before installation.
- This project is independent and is not affiliated with Coremail or any institution.
Testing
Mocked automated tests do not connect to a mailbox. Sanitized evidence from the authorized live run is recorded in docs/integration-verification.md.
pnpm typecheck
pnpm test
pnpm checkThey cover configuration, login/session handling, cookies, Coremail errors, response parsing, input validation, contacts, groups, membership, attachment upload, Web draft listing, and scheduled-mail state handling.
Real integration testing is intentionally separate from both pnpm check and the published package. During an authorized integration run, a temporary script outside the repository may read the ignored local .env keys:
ACCOUNT=<test account>
PASSWD=<test password>The temporary Web phase should use a unique random prefix, exercise contact/group CRUD and membership, verify scheduled listing/cancellation, and schedule messages to the same test account. Attachment verification should cover both a newly composed message and an existing Web draft. A separate IMAP verification phase may confirm final receipt, compare attachment bytes, and clean the test messages from Inbox, Drafts, and Sent. The script and credentials must not be committed or added to package scripts.
.env is ignored by Git and is never loaded by the production extension.
The sanitized record of the authorized 2026-08-25 Web and separate IMAP run is available at docs/integration-verification.md.
