@aitne-sh/aitne 0.1.0
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.
- package/LICENSE +21 -0
- package/README.md +464 -0
- package/agent-assets/agent-profiles/_safety.md +26 -0
- package/agent-assets/agent-profiles/conversational.md +33 -0
- package/agent-assets/agent-profiles/docs-qa.md +24 -0
- package/agent-assets/agent-profiles/observer.md +28 -0
- package/agent-assets/agent-profiles/profile-importer.md +63 -0
- package/agent-assets/agent-profiles/proxy.md +28 -0
- package/agent-assets/agent-profiles/routine.md +16 -0
- package/agent-assets/agent-profiles/task.md +18 -0
- package/agent-assets/docs/concepts/agent-day.md +88 -0
- package/agent-assets/docs/concepts/auth-health.md +75 -0
- package/agent-assets/docs/concepts/backends-and-tiers.md +126 -0
- package/agent-assets/docs/concepts/costs-and-quotas.md +103 -0
- package/agent-assets/docs/concepts/delegated-mode.md +223 -0
- package/agent-assets/docs/concepts/memory-model.md +118 -0
- package/agent-assets/docs/concepts/observations.md +80 -0
- package/agent-assets/docs/concepts/process-keys.md +89 -0
- package/agent-assets/docs/concepts/routines.md +108 -0
- package/agent-assets/docs/concepts/safety-and-execution.md +109 -0
- package/agent-assets/docs/concepts/safety-model.md +279 -0
- package/agent-assets/docs/concepts/skills.md +100 -0
- package/agent-assets/docs/features/integrations/calendar.md +92 -0
- package/agent-assets/docs/features/integrations/git.md +95 -0
- package/agent-assets/docs/features/integrations/github.md +170 -0
- package/agent-assets/docs/features/integrations/mail.md +106 -0
- package/agent-assets/docs/features/integrations/notion.md +69 -0
- package/agent-assets/docs/features/integrations/obsidian.md +71 -0
- package/agent-assets/docs/features/lifestyle/git.md +178 -0
- package/agent-assets/docs/features/lifestyle/reading.md +93 -0
- package/agent-assets/docs/features/lifestyle/receipts.md +71 -0
- package/agent-assets/docs/features/lifestyle/travel-bookings.md +44 -0
- package/agent-assets/docs/features/lifestyle/travel-time.md +52 -0
- package/agent-assets/docs/features/memory-files/agent-journal.md +105 -0
- package/agent-assets/docs/features/memory-files/projects.md +56 -0
- package/agent-assets/docs/features/memory-files/roadmap.md +61 -0
- package/agent-assets/docs/features/memory-files/schedule.md +112 -0
- package/agent-assets/docs/features/memory-files/today.md +73 -0
- package/agent-assets/docs/features/memory-files/user-profile.md +81 -0
- package/agent-assets/docs/features/messaging/dashboard-chat.md +93 -0
- package/agent-assets/docs/features/messaging/discord.md +50 -0
- package/agent-assets/docs/features/messaging/overview.md +111 -0
- package/agent-assets/docs/features/messaging/pairing-and-magic-phrase.md +69 -0
- package/agent-assets/docs/features/messaging/slack.md +51 -0
- package/agent-assets/docs/features/messaging/telegram.md +63 -0
- package/agent-assets/docs/features/messaging/whatsapp.md +48 -0
- package/agent-assets/docs/features/operations/activity-and-conversations.md +105 -0
- package/agent-assets/docs/features/operations/approvals.md +58 -0
- package/agent-assets/docs/features/operations/backend-routing.md +62 -0
- package/agent-assets/docs/features/operations/cost-tracking.md +59 -0
- package/agent-assets/docs/features/operations/notifications.md +69 -0
- package/agent-assets/docs/features/operations/quiet-hours.md +106 -0
- package/agent-assets/docs/features/operations/schedule-approaching.md +60 -0
- package/agent-assets/docs/features/routines/custom-routines.md +101 -0
- package/agent-assets/docs/features/routines/evening-review.md +81 -0
- package/agent-assets/docs/features/routines/hourly-check.md +85 -0
- package/agent-assets/docs/features/routines/monthly-review.md +65 -0
- package/agent-assets/docs/features/routines/morning-routine.md +123 -0
- package/agent-assets/docs/features/routines/weekly-review.md +70 -0
- package/agent-assets/docs/getting-started/01-what-is-this.md +192 -0
- package/agent-assets/docs/getting-started/02-first-steps.md +80 -0
- package/agent-assets/docs/getting-started/03-what-can-this-do.md +110 -0
- package/agent-assets/docs/getting-started/04-first-day.md +287 -0
- package/agent-assets/docs/glossary.md +116 -0
- package/agent-assets/docs/guides/add-a-custom-routine.md +71 -0
- package/agent-assets/docs/guides/backup-and-restore.md +54 -0
- package/agent-assets/docs/guides/change-which-model-handles-x.md +47 -0
- package/agent-assets/docs/guides/connect-a-new-mail-account.md +59 -0
- package/agent-assets/docs/guides/import-knowledge-file.md +275 -0
- package/agent-assets/docs/guides/install-and-run.md +72 -0
- package/agent-assets/docs/guides/migrate-machines.md +52 -0
- package/agent-assets/docs/guides/pause-the-agent.md +65 -0
- package/agent-assets/docs/guides/reinstall-cleanly.md +52 -0
- package/agent-assets/docs/guides/setup-wizard.md +107 -0
- package/agent-assets/docs/guides/switch-default-backend.md +60 -0
- package/agent-assets/docs/reference/api.md +51 -0
- package/agent-assets/docs/reference/cli-commands.md +121 -0
- package/agent-assets/docs/reference/config.md +74 -0
- package/agent-assets/docs/reference/disallowed-tools.md +76 -0
- package/agent-assets/docs/reference/keyboard-shortcuts.md +39 -0
- package/agent-assets/docs/reference/process-keys.md +59 -0
- package/agent-assets/docs/reference/skills.md +50 -0
- package/agent-assets/docs/troubleshooting/auth-failed.md +57 -0
- package/agent-assets/docs/troubleshooting/dashboard-shows-degraded.md +55 -0
- package/agent-assets/docs/troubleshooting/fallback-keeps-firing.md +54 -0
- package/agent-assets/docs/troubleshooting/messaging-not-pairing.md +53 -0
- package/agent-assets/docs/troubleshooting/morning-routine-didnt-run.md +75 -0
- package/agent-assets/docs/troubleshooting/observation-not-detected.md +57 -0
- package/agent-assets/docs/troubleshooting/quota-exhausted.md +57 -0
- package/agent-assets/optimizer-skills/drift-analysis/SKILL.md +75 -0
- package/agent-assets/optimizer-skills/knowledge-map/SKILL.md +71 -0
- package/agent-assets/optimizer-skills/skill-curation/SKILL.md +108 -0
- package/agent-assets/project-doc-templates/git-repo.md +21 -0
- package/agent-assets/project-doc-templates/project.md +38 -0
- package/agent-assets/skills/attach/SKILL.md +104 -0
- package/agent-assets/skills/context/SKILL.md +257 -0
- package/agent-assets/skills/context/curation.json +37 -0
- package/agent-assets/skills/context/seeds/file-responsibilities.seed.json +13 -0
- package/agent-assets/skills/context/seeds/frontmatter-requirements.seed.json +40 -0
- package/agent-assets/skills/docs-search/SKILL.md +176 -0
- package/agent-assets/skills/external-services/SKILL.delegated.claude.md +369 -0
- package/agent-assets/skills/external-services/SKILL.delegated.codex.md +349 -0
- package/agent-assets/skills/external-services/SKILL.delegated.gemini.md +347 -0
- package/agent-assets/skills/external-services/SKILL.md +371 -0
- package/agent-assets/skills/mail/SKILL.delegated.claude.md +284 -0
- package/agent-assets/skills/mail/SKILL.delegated.codex.md +261 -0
- package/agent-assets/skills/mail/SKILL.delegated.gemini.md +255 -0
- package/agent-assets/skills/mail/SKILL.md +313 -0
- package/agent-assets/skills/mail/references/errors.md +17 -0
- package/agent-assets/skills/mail/references/providers.md +40 -0
- package/agent-assets/skills/mail/references/query-grammar.md +24 -0
- package/agent-assets/skills/management-policy/SKILL.md +307 -0
- package/agent-assets/skills/management-policy/curation.json +13 -0
- package/agent-assets/skills/management-policy/seeds/policy-file-shape.seed.json +16 -0
- package/agent-assets/skills/management-task-modify/SKILL.md +202 -0
- package/agent-assets/skills/management-task-register/SKILL.md +330 -0
- package/agent-assets/skills/management-task-stop/SKILL.md +166 -0
- package/agent-assets/skills/notify/SKILL.md +196 -0
- package/agent-assets/skills/notion/SKILL.delegated.claude.md +254 -0
- package/agent-assets/skills/notion/SKILL.delegated.codex.md +195 -0
- package/agent-assets/skills/notion/SKILL.delegated.gemini.md +194 -0
- package/agent-assets/skills/notion/SKILL.md +86 -0
- package/agent-assets/skills/observations/SKILL.md +234 -0
- package/agent-assets/skills/observations/curation.json +13 -0
- package/agent-assets/skills/observations/seeds/source-namespacing.seed.json +20 -0
- package/agent-assets/skills/project-doc/SKILL.md +86 -0
- package/agent-assets/skills/project-doc/curation.json +21 -0
- package/agent-assets/skills/project-doc/seeds/project-shape.seed.json +25 -0
- package/agent-assets/skills/project-doc/seeds/slug-grammar.seed.json +20 -0
- package/agent-assets/skills/reading/SKILL.md +198 -0
- package/agent-assets/skills/reading/references/reading-taste.md +197 -0
- package/agent-assets/skills/receipts/SKILL.md +134 -0
- package/agent-assets/skills/roadmap/SKILL.md +276 -0
- package/agent-assets/skills/roadmap/curation.json +13 -0
- package/agent-assets/skills/roadmap/references/horizon-tags.md +40 -0
- package/agent-assets/skills/roadmap/references/preparation-timeline.md +47 -0
- package/agent-assets/skills/roadmap/seeds/entry-types.seed.json +16 -0
- package/agent-assets/skills/schedule/SKILL.md +228 -0
- package/agent-assets/skills/scheduled-managed-task/SKILL.md +392 -0
- package/agent-assets/skills/today/SKILL.md +198 -0
- package/agent-assets/skills/today/curation.json +21 -0
- package/agent-assets/skills/today/seeds/agent-notes-flavors.seed.json +17 -0
- package/agent-assets/skills/today/seeds/section-shape.seed.json +17 -0
- package/agent-assets/skills/travel/SKILL.md +132 -0
- package/agent-assets/skills/travel-time/SKILL.md +149 -0
- package/agent-assets/skills/user-interview/SKILL.md +323 -0
- package/agent-assets/skills/user-interview/references/sweep-and-fallback.md +94 -0
- package/agent-assets/skills/user-profile/SKILL.md +210 -0
- package/agent-assets/skills/user-profile/curation.json +29 -0
- package/agent-assets/skills/user-profile/seeds/learned-context-format.seed.json +14 -0
- package/agent-assets/skills/user-profile/seeds/routing-table.seed.json +53 -0
- package/agent-assets/skills/user-profile/seeds/topic-files.seed.json +27 -0
- package/agent-assets/task-flows/dashboard.docs_qa.md +43 -0
- package/agent-assets/task-flows/default.md +11 -0
- package/agent-assets/task-flows/git.branch.created.md +25 -0
- package/agent-assets/task-flows/git.lifecycle.poll.md +52 -0
- package/agent-assets/task-flows/git.local_ahead.stale.md +34 -0
- package/agent-assets/task-flows/git.merge_to_default.md +30 -0
- package/agent-assets/task-flows/git.project.refresh_architecture.md +100 -0
- package/agent-assets/task-flows/git.project.retemplate.md +73 -0
- package/agent-assets/task-flows/git.push.detected.md +32 -0
- package/agent-assets/task-flows/git.push.force_pushed.md +36 -0
- package/agent-assets/task-flows/git.tag.created.md +24 -0
- package/agent-assets/task-flows/github.assigned.md +43 -0
- package/agent-assets/task-flows/github.pull_request.review_requested.md +57 -0
- package/agent-assets/task-flows/github.security_alert.md +45 -0
- package/agent-assets/task-flows/github.workflow_run.failed.md +57 -0
- package/agent-assets/task-flows/knowledge.import.md +161 -0
- package/agent-assets/task-flows/message.received.dm.md +142 -0
- package/agent-assets/task-flows/message.received.dm_first.md +117 -0
- package/agent-assets/task-flows/message.received.md +14 -0
- package/agent-assets/task-flows/routine.custom.md +38 -0
- package/agent-assets/task-flows/routine.evening_review.md +323 -0
- package/agent-assets/task-flows/routine.hourly_check.delegated.claude.md +405 -0
- package/agent-assets/task-flows/routine.hourly_check.delegated.codex.md +400 -0
- package/agent-assets/task-flows/routine.hourly_check.delegated.gemini.md +404 -0
- package/agent-assets/task-flows/routine.hourly_check.md +184 -0
- package/agent-assets/task-flows/routine.hourly_check.triage.md +93 -0
- package/agent-assets/task-flows/routine.monthly_review.md +250 -0
- package/agent-assets/task-flows/routine.morning_routine.md +300 -0
- package/agent-assets/task-flows/routine.morning_routine_initial.md +184 -0
- package/agent-assets/task-flows/routine.roadmap_refresh.md +275 -0
- package/agent-assets/task-flows/routine.today_refresh.md +172 -0
- package/agent-assets/task-flows/routine.user_profile_sweep.md +242 -0
- package/agent-assets/task-flows/routine.weekly_review.md +247 -0
- package/agent-assets/task-flows/schedule.approaching.md +124 -0
- package/agent-assets/task-flows/scheduled.dm.md +391 -0
- package/agent-assets/task-flows/scheduled.task.md +141 -0
- package/agent-assets/task-flows/setup.initial.md +277 -0
- package/agent-assets/task-flows/setup.update.md +53 -0
- package/agent-assets/templates/README.md +85 -0
- package/agent-assets/templates/_index.md +39 -0
- package/agent-assets/templates/_manifest.json +103 -0
- package/agent-assets/templates/agent/journal.md +10 -0
- package/agent-assets/templates/agent/profile-questions.md +74 -0
- package/agent-assets/templates/context-index.md +42 -0
- package/agent-assets/templates/dossiers/_index.md +22 -0
- package/agent-assets/templates/dossiers/evening.md +23 -0
- package/agent-assets/templates/dossiers/hourly.md +23 -0
- package/agent-assets/templates/dossiers/monthly.md +23 -0
- package/agent-assets/templates/dossiers/morning.md +23 -0
- package/agent-assets/templates/dossiers/roadmap.md +23 -0
- package/agent-assets/templates/dossiers/weekly.md +23 -0
- package/agent-assets/templates/projects/_active.base +14 -0
- package/agent-assets/templates/projects/_index.md +29 -0
- package/agent-assets/templates/roadmap.md +15 -0
- package/agent-assets/templates/routines/_index.md +20 -0
- package/agent-assets/templates/routines/evening.md +22 -0
- package/agent-assets/templates/routines/hourly.md +30 -0
- package/agent-assets/templates/routines/monthly.md +25 -0
- package/agent-assets/templates/routines/morning.md +26 -0
- package/agent-assets/templates/routines/weekly.md +23 -0
- package/agent-assets/templates/rules/_index.md +19 -0
- package/agent-assets/templates/rules/journal-export.md +41 -0
- package/agent-assets/templates/rules/journal-format.md +61 -0
- package/agent-assets/templates/rules/management.md +48 -0
- package/agent-assets/templates/rules/mcp.md +40 -0
- package/agent-assets/templates/rules/policies/_index.md +22 -0
- package/agent-assets/templates/rules/redaction.md +30 -0
- package/agent-assets/templates/today.md +13 -0
- package/agent-assets/templates/user/_index.md +16 -0
- package/agent-assets/templates/user/expertise.md +7 -0
- package/agent-assets/templates/user/goals.md +7 -0
- package/agent-assets/templates/user/people.md +7 -0
- package/agent-assets/templates/user/personal.md +7 -0
- package/agent-assets/templates/user/profile.md +28 -0
- package/agent-assets/templates/user/work.md +7 -0
- package/bin/aitne.mjs +1096 -0
- package/package.json +78 -0
- package/personal-agent.mjs +39 -0
- package/scripts/browser.mjs +99 -0
- package/scripts/check-redaction-coverage.mjs +109 -0
- package/scripts/commands/audit.mjs +309 -0
- package/scripts/commands/doctor.mjs +437 -0
- package/scripts/commands/open.mjs +40 -0
- package/scripts/commands/setup.mjs +21 -0
- package/scripts/commands/uninstall.mjs +114 -0
- package/scripts/commands/update.mjs +96 -0
- package/scripts/commands/version.mjs +62 -0
- package/scripts/commands.md +0 -0
- package/scripts/lib/sqlite-loader.mjs +49 -0
- package/scripts/message-discipline-digest.mjs +535 -0
- package/scripts/poc/google-connector-inheritance/REPORT.md +197 -0
- package/scripts/poc/google-connector-inheritance/claude-sdk-probe.mjs +79 -0
- package/scripts/remint-roadmap-ids.mjs +257 -0
- package/scripts/rm-paths.mjs +22 -0
- package/scripts/run-node.mjs +223 -0
- package/scripts/smoke-obsidian-api.mjs +166 -0
- package/scripts/start.mjs +160 -0
|
@@ -0,0 +1,313 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: mail
|
|
3
|
+
description: Load when reading, searching, sending, drafting, replying, tagging, or filing email — Gmail, Outlook, Yahoo, and iCloud accounts share one route surface, with provider-native translation at the daemon.
|
|
4
|
+
allowed-tools:
|
|
5
|
+
- Bash(curl *)
|
|
6
|
+
- Read
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Mail Operations Guide (multi-provider)
|
|
10
|
+
|
|
11
|
+
All mail work goes through `/api/mail/*`. Gmail, Outlook, Yahoo, iCloud —
|
|
12
|
+
same route surface, per-account routing, provider-native translation at the
|
|
13
|
+
daemon.
|
|
14
|
+
|
|
15
|
+
## 0. Delegation-aware routing (read before §1)
|
|
16
|
+
|
|
17
|
+
This body is materialized only in direct mode and same-backend Gmail
|
|
18
|
+
delegation. (Cross-backend Gmail delegation pulls
|
|
19
|
+
`SKILL.delegated.<backend>.md` instead — that variant has its own
|
|
20
|
+
routing prose.) Read the `<integration_modes>` block injected above:
|
|
21
|
+
|
|
22
|
+
- **Non-Gmail accounts (iCloud, Outlook, Yahoo, IMAP):** unaffected —
|
|
23
|
+
use the `/api/mail/:acct/*` endpoints documented below regardless of
|
|
24
|
+
Gmail's mode.
|
|
25
|
+
- **Gmail accounts AND `gmail="delegated"` (same-backend):** the
|
|
26
|
+
per-account gate inside the mail handler returns
|
|
27
|
+
`410 {"error": "integration_delegated"}`. Do NOT retry through
|
|
28
|
+
`/api/mail/*`. Use the connector tools your session already holds
|
|
29
|
+
natively — `mcp__claude_ai_Gmail__*` (Claude session),
|
|
30
|
+
`mcp__codex_apps__gmail._*` (Codex session), or
|
|
31
|
+
`mcp_google-workspace_gmail.*` (Gemini session, via the
|
|
32
|
+
`google-workspace` extension).
|
|
33
|
+
|
|
34
|
+
Account-resolution (§1) is unchanged: `accounts.md` lists every active
|
|
35
|
+
account regardless of mode. The branch above only affects the wire call
|
|
36
|
+
once an account is selected.
|
|
37
|
+
|
|
38
|
+
## 1. Account resolution (do this first)
|
|
39
|
+
|
|
40
|
+
`accounts.md` (next to this file) lists the active accounts available this
|
|
41
|
+
session — scope-gated to `enabled provider ∧ account.active ∧ healthy`. If
|
|
42
|
+
the file is absent or empty, there are no active mail accounts: tell the
|
|
43
|
+
user and stop. Account setup is outside this skill's scope — do NOT
|
|
44
|
+
speculate about how to add one.
|
|
45
|
+
|
|
46
|
+
There is **no global "primary" account**. Pick one from conversation
|
|
47
|
+
context, in this order:
|
|
48
|
+
|
|
49
|
+
1. **User named it.** `"email from my work gmail"` / `"reply from my
|
|
50
|
+
icloud"` → match against the `email` / `label` columns in `accounts.md`.
|
|
51
|
+
2. **Replying to a thread.** The reply MUST go from the account that
|
|
52
|
+
received the original. Find it by the `accountId` attached to the
|
|
53
|
+
message/thread you fetched.
|
|
54
|
+
3. **Exactly one active account.** No ambiguity — use it.
|
|
55
|
+
4. **Multiple active, no context clue.** Ask the user which account to
|
|
56
|
+
use. Do NOT pick arbitrarily.
|
|
57
|
+
|
|
58
|
+
If an API call returns `404 not_found` on an id you resolved from
|
|
59
|
+
`accounts.md`, the file may be stale. Re-fetch the scope-gated set:
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
curl -s "http://localhost:8321/api/mail/accounts?active=1"
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
This returns the same filtered view `accounts.md` was materialized from.
|
|
66
|
+
Do NOT call `GET /api/mail/accounts` without `?active=1` for recovery — it
|
|
67
|
+
includes dormant and unhealthy rows that every operation will reject.
|
|
68
|
+
|
|
69
|
+
## 2. Decision rules
|
|
70
|
+
|
|
71
|
+
### Send vs draft
|
|
72
|
+
- **Prefer drafts.** Create via `POST /mail/:acct/drafts`. The user sends
|
|
73
|
+
from the provider's web UI.
|
|
74
|
+
- Direct send (`POST /mail/:acct/messages/send`) succeeds autonomously —
|
|
75
|
+
the daemon does not DM the owner before sending. (The user's
|
|
76
|
+
`deniedTools` list applies to **delegated-mode connector tools** —
|
|
77
|
+
e.g. Codex's `send_email` — and is enforced at the
|
|
78
|
+
`/api/integrations/:key/exec` task-mode chokepoint via the per-task
|
|
79
|
+
allowed-tools envelope. In direct mode, the `/api/mail/*` route
|
|
80
|
+
handler has no equivalent deny check today, so a send call is what
|
|
81
|
+
it appears to be: a send.) When you judge the user would want to
|
|
82
|
+
know about a send immediately (e.g. a reply to a stranger), call
|
|
83
|
+
`POST /api/notify` yourself.
|
|
84
|
+
- Never include `bcc` unless the user explicitly asks for it.
|
|
85
|
+
|
|
86
|
+
### Replies — RFC-2822 headers are the source of truth
|
|
87
|
+
Provider thread ids (Gmail `threadId`, Graph `conversationId`) differ;
|
|
88
|
+
RFC-2822 `Message-Id` + `References` is the one chain that works across
|
|
89
|
+
all four kinds.
|
|
90
|
+
|
|
91
|
+
1. Fetch the thread metadata: `GET /api/mail/:acct/threads/:threadId?body=none`
|
|
92
|
+
(returns `messages[]` in chronological order without raw HTML bodies).
|
|
93
|
+
2. From the last message, pull `rfc822MsgId` and `references`.
|
|
94
|
+
3. Build the `reply` block:
|
|
95
|
+
```json
|
|
96
|
+
{
|
|
97
|
+
"inReplyToRfc822Id": "<last.rfc822MsgId>",
|
|
98
|
+
"references": ["<A>", "<B>", "<last.rfc822MsgId>"],
|
|
99
|
+
"providerThreadId": "<last.threadId>",
|
|
100
|
+
"parentProviderMsgId": "<last.providerMsgId>"
|
|
101
|
+
}
|
|
102
|
+
```
|
|
103
|
+
`providerThreadId` is Gmail's `threadId` / Graph's `conversationId`. On
|
|
104
|
+
IMAP (Yahoo / iCloud) threads are client-walked — omit it there.
|
|
105
|
+
4. For reply-all, build `to` from the original `from` + existing `to`, and
|
|
106
|
+
`cc` from the original `cc`, excluding the sender account's own email
|
|
107
|
+
(resolve from `accounts.md`).
|
|
108
|
+
|
|
109
|
+
If the thread endpoint returns `status: "partial"` with `missingAncestors
|
|
110
|
+
> 0`, reply is still safe (the chain you have is headers-valid), but
|
|
111
|
+
acknowledge to the user that older context wasn't indexed locally.
|
|
112
|
+
|
|
113
|
+
### Searching — prefer the local index
|
|
114
|
+
For "find emails about X / from Y / last month" queries, start with the
|
|
115
|
+
daemon's local FTS5 index — zero provider round-trips, cross-account:
|
|
116
|
+
|
|
117
|
+
```bash
|
|
118
|
+
curl -s "http://localhost:8321/api/mail/search?q=invoice+acme&limit=20"
|
|
119
|
+
# Scope to one account: &accountId=<id>
|
|
120
|
+
# Shape: { results: [{ accountId, providerMsgId, subject, snippet,
|
|
121
|
+
# receivedAtUtc, from: { email }, isRead }], count, query }
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
Only fall back to per-account provider search (`/mail/:acct/messages?q=`)
|
|
125
|
+
when you need provider-fresh results or the index doesn't cover the time
|
|
126
|
+
range (fresh installs).
|
|
127
|
+
|
|
128
|
+
### Reading message bodies — use extracted chunks
|
|
129
|
+
Do not dump full raw HTML mail into a file for `Read`. Large airline,
|
|
130
|
+
receipt, and marketing emails often arrive as one-line compressed HTML and
|
|
131
|
+
can exceed the tool's token/line limits.
|
|
132
|
+
|
|
133
|
+
For headers/snippet/attachment metadata only, use:
|
|
134
|
+
|
|
135
|
+
```bash
|
|
136
|
+
curl -s "http://localhost:8321/api/mail/ACCT/messages/MSG?body=none"
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
For body understanding, fetch the extracted body endpoint first:
|
|
140
|
+
|
|
141
|
+
```bash
|
|
142
|
+
curl -s "http://localhost:8321/api/mail/ACCT/messages/MSG/body?format=extracted&maxChars=12000"
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
Shape: `{ content, source, links, images, chunk, hasMore, nextChunk,
|
|
146
|
+
totalChars, rawHtmlAvailable, linkCount, imageCount, nextMetadataOffset }`.
|
|
147
|
+
`content` contains visible body text plus link URLs and image alt/title
|
|
148
|
+
metadata. If `hasMore` is true, request the next content chunk:
|
|
149
|
+
|
|
150
|
+
```bash
|
|
151
|
+
curl -s "http://localhost:8321/api/mail/ACCT/messages/MSG/body?format=extracted&chunk=1&maxChars=12000"
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
The structured `links` / `images` arrays are paginated separately so a
|
|
155
|
+
marketing email with thousands of links cannot blow up a response. If
|
|
156
|
+
`nextMetadataOffset` is non-null and you need structured metadata beyond
|
|
157
|
+
what is already rendered in `content`, pass `metadataOffset=<value>`.
|
|
158
|
+
|
|
159
|
+
Only use `format=raw` when exact markup is required; it is still chunked:
|
|
160
|
+
|
|
161
|
+
```bash
|
|
162
|
+
curl -s "http://localhost:8321/api/mail/ACCT/messages/MSG/body?format=raw&chunk=0&maxChars=12000"
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
### When NOT to act
|
|
166
|
+
- During `routine.hourly_check` this skill is **read-only** — no sending,
|
|
167
|
+
no draft edits, no tag changes, no trash / untrash / archive.
|
|
168
|
+
- No bulk operations without user confirmation.
|
|
169
|
+
- Trash / untrash / archive run autonomously when not on the user's
|
|
170
|
+
deny list. The daemon does not DM the owner before the call. Single
|
|
171
|
+
ops only; if you're about to trash 3+ messages at once, stop and ask
|
|
172
|
+
the user — the agent's own judgment is the gate, not the daemon.
|
|
173
|
+
- **Delegated mode**: this skill body is loaded only when `gmail.mode ===
|
|
174
|
+
"direct"`. When Gmail is delegated, the materializer picks
|
|
175
|
+
`SKILL.delegated.<sessionBackend>.md` (cross-backend) or skips the
|
|
176
|
+
skill entirely (same-backend, native MCP). If you somehow reach
|
|
177
|
+
`/api/mail/*` from this body while Gmail is delegated, the route
|
|
178
|
+
returns `410 integration_delegated` — re-read `integrations.md` and
|
|
179
|
+
use `POST /api/integrations/gmail/exec` (task mode) instead.
|
|
180
|
+
|
|
181
|
+
## 3. Provider capability matrix
|
|
182
|
+
|
|
183
|
+
{{> ref:providers }}
|
|
184
|
+
|
|
185
|
+
## 4. Query grammar
|
|
186
|
+
|
|
187
|
+
{{> ref:query-grammar }}
|
|
188
|
+
|
|
189
|
+
## 5. Error handling
|
|
190
|
+
|
|
191
|
+
{{> ref:errors }}
|
|
192
|
+
|
|
193
|
+
## 6. Worked examples
|
|
194
|
+
|
|
195
|
+
### Reply with context
|
|
196
|
+
```bash
|
|
197
|
+
# 1. Find the thread — start local.
|
|
198
|
+
curl -s "http://localhost:8321/api/mail/search?q=from:alice+proposal&limit=5"
|
|
199
|
+
# → pick the hit, note accountId + providerMsgId.
|
|
200
|
+
|
|
201
|
+
# 2. Fetch the thread.
|
|
202
|
+
curl -s "http://localhost:8321/api/mail/acct-1/threads/THREAD_ID"
|
|
203
|
+
# → last message has rfc822MsgId, references[], providerMsgId.
|
|
204
|
+
|
|
205
|
+
# 3. Create a draft threaded to it. Drafts are Autonomous tier.
|
|
206
|
+
curl -sX POST "http://localhost:8321/api/mail/acct-1/drafts" \
|
|
207
|
+
-H "Content-Type: application/json" \
|
|
208
|
+
-d '{
|
|
209
|
+
"to": ["alice@example.com"],
|
|
210
|
+
"subject": "Re: Proposal",
|
|
211
|
+
"textBody": "Thanks Alice — ...",
|
|
212
|
+
"reply": {
|
|
213
|
+
"inReplyToRfc822Id": "<abc@mail.example.com>",
|
|
214
|
+
"references": ["<root@mail.example.com>", "<abc@mail.example.com>"],
|
|
215
|
+
"providerThreadId": "THREAD_ID",
|
|
216
|
+
"parentProviderMsgId": "PARENT_MSG_ID"
|
|
217
|
+
}
|
|
218
|
+
}'
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
### File a message (read + tag + archive)
|
|
222
|
+
```bash
|
|
223
|
+
curl -sX POST "http://localhost:8321/api/mail/acct-1/messages/MSG/read" \
|
|
224
|
+
-d '{"read": true}'
|
|
225
|
+
curl -sX POST "http://localhost:8321/api/mail/acct-1/messages/MSG/tags" \
|
|
226
|
+
-d '{"add": ["followup"], "remove": []}'
|
|
227
|
+
curl -sX POST "http://localhost:8321/api/mail/acct-1/messages/MSG/archive"
|
|
228
|
+
```
|
|
229
|
+
On IMAP, confirm `followup` is in `GET /mail/:acct/tags` `.userDefined`
|
|
230
|
+
first — unknown keywords get dropped.
|
|
231
|
+
|
|
232
|
+
### Cross-account search → pick account → send
|
|
233
|
+
```bash
|
|
234
|
+
# Find recipient's earlier emails across all accounts.
|
|
235
|
+
curl -s "http://localhost:8321/api/mail/search?q=from:bob@acme.com&limit=10"
|
|
236
|
+
# → hits carry accountId. Use whichever account received the earlier thread
|
|
237
|
+
# so the reply comes from a familiar address.
|
|
238
|
+
|
|
239
|
+
curl -sX POST "http://localhost:8321/api/mail/acct-2/messages/send" \
|
|
240
|
+
-H "Content-Type: application/json" \
|
|
241
|
+
-d '{"to": ["bob@acme.com"], "subject": "...", "textBody": "..."}'
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
## 7. API reference
|
|
245
|
+
|
|
246
|
+
Base URL `http://localhost:8321`. `ACCT` = accountId from `accounts.md`.
|
|
247
|
+
|
|
248
|
+
### Accounts
|
|
249
|
+
```bash
|
|
250
|
+
curl -s "http://localhost:8321/api/mail/accounts?active=1"
|
|
251
|
+
# → { accounts: [{ id, kind, email, label?, authStatus, idleEnabled, active, createdAt }, ...] }
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
### Search (local FTS5, cross-account)
|
|
255
|
+
```bash
|
|
256
|
+
curl -s "http://localhost:8321/api/mail/search?q=...&limit=50&accountId=ACCT"
|
|
257
|
+
# → { results: [{ accountId, providerMsgId, subject, snippet, receivedAtUtc,
|
|
258
|
+
# from: { email } | null, isRead }], count, query }
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
### Read
|
|
262
|
+
```bash
|
|
263
|
+
# List / search via the provider.
|
|
264
|
+
curl -s "http://localhost:8321/api/mail/ACCT/messages?q=is:unread&limit=20"
|
|
265
|
+
# → { messages: [{ providerMsgId, threadId, from, subject, snippet,
|
|
266
|
+
# receivedAtUtc, isRead, flags, hasAttachment }] }
|
|
267
|
+
|
|
268
|
+
curl -s "http://localhost:8321/api/mail/ACCT/messages/MSG_ID"
|
|
269
|
+
# → { message: { ..., body: { text, html }, attachments: [...] } }
|
|
270
|
+
|
|
271
|
+
curl -s "http://localhost:8321/api/mail/ACCT/threads/THREAD_ID"
|
|
272
|
+
# → { thread: { threadId, messages: [...], status: "full"|"partial", missingAncestors? } }
|
|
273
|
+
|
|
274
|
+
curl -s "http://localhost:8321/api/mail/ACCT/folders"
|
|
275
|
+
curl -s "http://localhost:8321/api/mail/ACCT/tags"
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
### Send / draft
|
|
279
|
+
```bash
|
|
280
|
+
# Direct send — Autonomous; rejected with 403 when the user has denied
|
|
281
|
+
# the send tool. Call /api/notify yourself if the user should know.
|
|
282
|
+
curl -sX POST "http://localhost:8321/api/mail/ACCT/messages/send" \
|
|
283
|
+
-H "Content-Type: application/json" \
|
|
284
|
+
-d '{"to": [...], "subject": "...", "textBody": "...", "reply"?: {...}}'
|
|
285
|
+
# → { result: { id, isDraft: false, rfc822MsgId?, warnings? } }
|
|
286
|
+
|
|
287
|
+
# Draft CRUD — Autonomous tier.
|
|
288
|
+
curl -s "http://localhost:8321/api/mail/ACCT/drafts"
|
|
289
|
+
curl -s "http://localhost:8321/api/mail/ACCT/drafts/DRAFT_ID"
|
|
290
|
+
curl -sX POST "http://localhost:8321/api/mail/ACCT/drafts" -d '{...}'
|
|
291
|
+
curl -sX PATCH "http://localhost:8321/api/mail/ACCT/drafts/DRAFT_ID" -d '{...}'
|
|
292
|
+
# PATCH response: { status, id, warnings? }
|
|
293
|
+
# - On Outlook, `warnings: ["reply_threading_immutable_after_create"]` if
|
|
294
|
+
# `reply` was supplied — reply headers are fixed at createDraft time.
|
|
295
|
+
curl -sX DELETE "http://localhost:8321/api/mail/ACCT/drafts/DRAFT_ID"
|
|
296
|
+
curl -sX POST "http://localhost:8321/api/mail/ACCT/drafts/DRAFT_ID/send"
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
### Modify / move
|
|
300
|
+
```bash
|
|
301
|
+
curl -sX POST "http://localhost:8321/api/mail/ACCT/messages/MSG_ID/read" -d '{"read": true}'
|
|
302
|
+
curl -sX POST "http://localhost:8321/api/mail/ACCT/messages/MSG_ID/tags" -d '{"add": ["Starred"], "remove": []}'
|
|
303
|
+
curl -sX POST "http://localhost:8321/api/mail/ACCT/messages/MSG_ID/trash"
|
|
304
|
+
curl -sX POST "http://localhost:8321/api/mail/ACCT/messages/MSG_ID/untrash"
|
|
305
|
+
curl -sX POST "http://localhost:8321/api/mail/ACCT/messages/MSG_ID/archive"
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
### Health
|
|
309
|
+
```bash
|
|
310
|
+
curl -s "http://localhost:8321/api/mail/ACCT/health"
|
|
311
|
+
# → { accountId, lastPollAtUtc, lastError, lastErrorAtUtc,
|
|
312
|
+
# consecutiveErrorCount, idleFallbackUntilUtc }
|
|
313
|
+
```
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
---
|
|
2
|
+
kind: reference
|
|
3
|
+
parent_skill: mail
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
Direct-mode write routes share `{ error: string, message: string, detail?: string }`. Map by the `error` code first, then `detail` for richer disambiguation.
|
|
7
|
+
|
|
8
|
+
| HTTP | `error` | `detail` | What it means / what to do |
|
|
9
|
+
|---|---|---|---|
|
|
10
|
+
| 400 | `provider_not_enabled` | `kind_not_enabled` | The provider is authenticated but the user disabled that provider in settings. Tell the user and stop. |
|
|
11
|
+
| 400 | `provider_not_enabled` | `account_inactive` | This specific account is paused. Tell the user to re-enable it in the dashboard. Stop. |
|
|
12
|
+
| 400 | `provider_not_enabled` | `account_unhealthy` | **Credentials broken** (refresh rejected / app password expired). Tell the user to re-authenticate at `/connections/mail#<accountId>`. Stop. Do NOT treat as "provider disabled." |
|
|
13
|
+
| 404 | `not_found` | — | Account id unknown or message/thread id gone. First retry: re-resolve via `?active=1` (§1). If still 404, surface to user. |
|
|
14
|
+
| 410 | `integration_delegated` | — | Gmail flipped to delegated mode mid-session. This skill body is direct-only — re-read `integrations.md` and use `POST /api/integrations/gmail/exec` (cross-backend task mode) or your session backend's native Gmail MCP (the same-backend variant) instead. |
|
|
15
|
+
| 501 | `not_implemented` | — | Operation unavailable on this provider kind (e.g. IMAP draft writes, Outlook attachment download). Fall back to the provider's native UI and tell the user. |
|
|
16
|
+
| 502 | `provider_auth_error` | — | Upstream rejected the credentials mid-call. Re-consent needed. Do NOT retry; tell the user. |
|
|
17
|
+
| other 5xx | — | — | Transient. Backoff, one retry, then surface the error text. |
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
---
|
|
2
|
+
kind: reference
|
|
3
|
+
parent_skill: mail
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
Each provider supports the unified surface but with differing semantics.
|
|
7
|
+
Routes return **HTTP 501 `not_implemented`** when a method isn't available
|
|
8
|
+
on this kind — do NOT retry; tell the user and fall back.
|
|
9
|
+
|
|
10
|
+
| Operation | Gmail | Outlook | Yahoo / iCloud (IMAP) |
|
|
11
|
+
|---|---|---|---|
|
|
12
|
+
| Read, search, list folders | ✅ | ✅ | ✅ (ASCII; non-ASCII degrades — see §4) |
|
|
13
|
+
| Direct send (`POST /messages/send`) | ✅ | ✅ | ✅ |
|
|
14
|
+
| `markRead` / `tags` / `trash` | ✅ | ✅ | ✅ |
|
|
15
|
+
| `archive` / `untrash` | ✅ | ✅ | ✅ |
|
|
16
|
+
| Thread read (`GET /threads/:id`) | ✅ | ✅ | ⚠️ client-walked; `status: "partial"` possible |
|
|
17
|
+
| Draft read (`GET /drafts`, `GET /drafts/:id`) | ✅ | ✅ | ✅ |
|
|
18
|
+
| Draft write (`POST`/`PATCH`/`DELETE /drafts`, `POST /drafts/:id/send`) | ✅ | ✅ | ❌ **501** — direct `/messages/send` only |
|
|
19
|
+
| Attachment download (via `/receipts/:id/file`) | ✅ | ❌ 501 | ❌ 501 |
|
|
20
|
+
|
|
21
|
+
**IMAP drafts** (Yahoo / iCloud): every draft *write* returns 501. To
|
|
22
|
+
queue outbound mail for a non-Gmail IMAP user, send directly via
|
|
23
|
+
`POST /messages/send` (agent composes body) or ask the user to compose in
|
|
24
|
+
their native client. MIME-constructed drafts ship in a later phase.
|
|
25
|
+
|
|
26
|
+
**Attachments beyond Gmail**: receipts / attachment download currently
|
|
27
|
+
work only for Gmail messages. If the user asks you to save an attachment
|
|
28
|
+
off an Outlook or IMAP message, say so and point them to the provider's
|
|
29
|
+
web UI.
|
|
30
|
+
|
|
31
|
+
### Provider-specific quirks
|
|
32
|
+
|
|
33
|
+
| Concern | Gmail / Outlook | Yahoo / iCloud (IMAP) |
|
|
34
|
+
|---|---|---|
|
|
35
|
+
| Tag semantics | Gmail: label ids. Outlook: category names. Free-form. | System flags only (`\Seen \Flagged \Answered`) + server-advertised `PERMANENTFLAGS` keywords. Unknown tags silently dropped. |
|
|
36
|
+
| Threads | Provider-authoritative | Client-walked from `In-Reply-To` + `References`. `status: "partial"` when local index lacks older ancestors. `404 not_found` if the rfc822 id can't be reached. |
|
|
37
|
+
| `PATCH /drafts/:id` with `reply` | Gmail: threading is editable. Outlook: silently ignores `reply`; response includes `warnings: ["reply_threading_immutable_after_create"]` — create a fresh draft to reshape threading. | N/A (draft writes 501) |
|
|
38
|
+
|
|
39
|
+
Call `GET /api/mail/:acct/tags` before tagging on IMAP — `userDefined` is
|
|
40
|
+
often empty on servers that don't advertise keywords.
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
---
|
|
2
|
+
kind: reference
|
|
3
|
+
parent_skill: mail
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
One grammar, translated per-provider:
|
|
7
|
+
|
|
8
|
+
| Token | Meaning |
|
|
9
|
+
|---|---|
|
|
10
|
+
| `from:<email>` | sender match |
|
|
11
|
+
| `to:<email>` | recipient match |
|
|
12
|
+
| `subject:"..."` | substring of subject |
|
|
13
|
+
| `has:attachment` | ≥ 1 attachment |
|
|
14
|
+
| `is:unread` | unread only |
|
|
15
|
+
| `newer_than:<N>d` | received in last N days |
|
|
16
|
+
| `older_than:<N>d` | received before N days |
|
|
17
|
+
| `<free text>` | subject / body / from |
|
|
18
|
+
|
|
19
|
+
**Non-ASCII and IMAP.** Before running a non-ASCII free-text query
|
|
20
|
+
against an IMAP account, check `accounts.md` `kind` column. For `yahoo`
|
|
21
|
+
/ `icloud`, the route downgrades to client-side filtering over recent
|
|
22
|
+
UIDs — historic ranges will be **incomplete**. Either (a) keep the
|
|
23
|
+
window short with `newer_than:30d`, (b) use the local FTS5 endpoint
|
|
24
|
+
instead, or (c) tell the user results may miss older matches.
|