lack / mail-automation
Stateful mailbox automation, contact resolution and rule processing on top of phore/mail-client.
Requires
- php: >=8.5
- ext-json: *
- ext-pdo: *
- ext-pdo_sqlite: *
- phore/ai-harness: dev-main
- phore/cli2: dev-main
- phore/filesystem: *
- phore/log: dev-master
- phore/mail-client: dev-main
Requires (Dev)
- phpunit/phpunit: ^13.2
Suggests
None
Provides
None
Conflicts
None
Replaces
None
This package is auto-updated.
Last update: 2026-10-09 15:04:42 UTC
README
AI-native mailbox automation on top of phore/mail-client and
phore/ai-harness.
The normal application surface is one MailAutomation object. Connection,
storage, locking, Sent/Inbox synchronization, automation flags, analysis and
action discovery belong to the library rather than to application run.php
files.
Bootstrap
<?php use Lack\MailAutomation\MailAutomation; use Lack\MailAutomation\MailAutomationConfig; return MailAutomation::fromConfig( new MailAutomationConfig( mailbox: dirname(__DIR__) . '/mailclient.yaml', actionsDirectory: __DIR__ . '/actions', ), );
Mailbox folders and the processed, error and actionRequired flags are
configured in the existing phore/mail-client mailbox YAML/JSON.
CLI
The package installs vendor/bin/lack-mail-automation:
vendor/bin/lack-mail-automation run
vendor/bin/lack-mail-automation run --dry-run
vendor/bin/lack-mail-automation run --mail-id '<mail-client-id>'
The default bootstrap is automail/bootstrap.php; use --bootstrap only
when the application keeps it elsewhere.
A normal run observes Sent before Inbox, then any additional folders required
by registered actions. The process lock, cursor handling and status flags are
internal. --mail-id explicitly retries one message without advancing a
folder cursor.
Actions
Actions are discovered recursively from actionsDirectory:
#[OnMailAction(
condition: 'This is the first applicant reply and required CV data is missing.',
priority: 100,
)]
final class RequestCvDetailsAction
{
public function __invoke(AiMail $mail): MailAction
{
return $mail->ai_reply(
new PromptFile(__DIR__ . '/request-details.md'),
)->send();
}
}
Higher numeric priority only resolves overlap between otherwise matching
conditions.
Generated outbound content is AiMailDraft extends AiMail. Drafts provide
setRecipient(), setSubject(), setText(), attach(), draft()
and send(); Reply recipients/subjects remain derived from their source mail
to preserve threading.