@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,261 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: mail
|
|
3
|
+
description: Load when the task touches Gmail and Gmail is in cross-backend delegated mode (DM session is Codex; `delegatedBackend` is non-Codex). Gmail accounts route through `POST /api/integrations/gmail/exec`; non-Gmail accounts (IMAP/Outlook/iCloud/Yahoo) keep the direct-mode `/api/mail/*` surface.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Mail (delegated, cross-backend)
|
|
7
|
+
|
|
8
|
+
Gmail is delegated to a different backend (Claude or Gemini). The
|
|
9
|
+
daemon spawns that backend on demand, lets it pick the right MCP tool,
|
|
10
|
+
and returns a schema-validated JSON result. **You describe intent in
|
|
11
|
+
natural language; the daemon picks the tool.** Tool name divergence
|
|
12
|
+
between Claude (`search_threads`), Gemini (`search`) and any custom
|
|
13
|
+
MCP server the user installs is invisible to you.
|
|
14
|
+
|
|
15
|
+
To confirm Gmail's current delegate, read
|
|
16
|
+
`~/.personal-agent/integrations.md` and consult its `delegatedBackend`
|
|
17
|
+
field. The same prose body below works for every delegate.
|
|
18
|
+
|
|
19
|
+
## Non-Gmail accounts keep the direct-mode surface
|
|
20
|
+
|
|
21
|
+
Per-account gating: the `/api/mail/*` 410 only fires when the resolved
|
|
22
|
+
`accountId` is `kind=gmail`. IMAP / Outlook / iCloud / Yahoo accounts
|
|
23
|
+
remain fully reachable through the direct-mode endpoints documented in
|
|
24
|
+
the base `mail` skill body — `GET /api/mail/:acct/messages`,
|
|
25
|
+
`POST /mail/:acct/drafts`, `GET /api/mail/:acct/threads/:threadId`, etc.
|
|
26
|
+
Use `accounts.md` (still materialized for this session) to resolve the
|
|
27
|
+
account and pick the path:
|
|
28
|
+
|
|
29
|
+
| Selected account `kind` | Path |
|
|
30
|
+
|---|---|
|
|
31
|
+
| `gmail` | task: `POST /api/integrations/gmail/exec {task, outputSchema, …}` (this file) |
|
|
32
|
+
| `outlook` / `icloud` / `yahoo` / `imap` | direct: `/api/mail/:acct/*` (base body) |
|
|
33
|
+
|
|
34
|
+
Only the Gmail branch leaves the direct-mode surface. Account
|
|
35
|
+
resolution (§1 of the base body), draft-vs-send rules, and reply-thread
|
|
36
|
+
chaining are unchanged for non-Gmail accounts.
|
|
37
|
+
|
|
38
|
+
## Call shape
|
|
39
|
+
|
|
40
|
+
The single endpoint is `POST /api/integrations/gmail/exec`. The body
|
|
41
|
+
takes a natural-language `task` plus an `outputSchema` (Draft-07 JSON
|
|
42
|
+
Schema) the daemon validates the result against.
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
curl -sS -X POST http://localhost:8321/api/integrations/gmail/exec \
|
|
46
|
+
-H 'Content-Type: application/json' \
|
|
47
|
+
-d '{
|
|
48
|
+
"task": "Search Gmail for unread messages from alice@example.com in the last 7 days. Return up to 10 with sender, subject, snippet, timestamp.",
|
|
49
|
+
"outputSchema": {
|
|
50
|
+
"type": "object",
|
|
51
|
+
"required": ["messages"],
|
|
52
|
+
"properties": {
|
|
53
|
+
"messages": {
|
|
54
|
+
"type": "array",
|
|
55
|
+
"items": {
|
|
56
|
+
"type": "object",
|
|
57
|
+
"required": ["from", "subject", "snippet", "ts"],
|
|
58
|
+
"properties": {
|
|
59
|
+
"from": {"type": "string"},
|
|
60
|
+
"subject": {"type": "string"},
|
|
61
|
+
"snippet": {"type": "string"},
|
|
62
|
+
"ts": {"type": "string", "format": "date-time"}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
},
|
|
68
|
+
"maxToolCalls": 5,
|
|
69
|
+
"cacheable": true
|
|
70
|
+
}'
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
Response shape on success:
|
|
74
|
+
|
|
75
|
+
```jsonc
|
|
76
|
+
{
|
|
77
|
+
"result": { "messages": [ ... ] }, // schema-validated parse
|
|
78
|
+
"needsConfirmation": false,
|
|
79
|
+
"confirmationPlan": null,
|
|
80
|
+
"trace": [ /* per-tool-call breakdown — informational */ ],
|
|
81
|
+
"cost": { "tokensInput": ..., "costUsd": ..., "durationMs": ... }
|
|
82
|
+
}
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
`outputSchema` is **required** — the subprocess emits exactly one JSON
|
|
86
|
+
object as its final message and the daemon validates it. Schemas
|
|
87
|
+
larger than 4 KB are rejected (`schema_too_large`). Caps default to
|
|
88
|
+
`maxToolCalls=7`, `maxBudgetUsd=0.05`, `timeoutMs=60000` — bump them
|
|
89
|
+
via the request body up to the hard caps (15 / 0.50 / 300000) when a
|
|
90
|
+
task genuinely needs more.
|
|
91
|
+
|
|
92
|
+
## Idempotent reads — `cacheable: true`
|
|
93
|
+
|
|
94
|
+
Pure-read tasks (thread fetches, search summarisations, label lookups)
|
|
95
|
+
should set `cacheable: true` so a repeat invocation within 60s returns
|
|
96
|
+
~5ms from the in-memory LRU. The cache key includes the integration
|
|
97
|
+
state version, so flipping `deniedTools` or `delegatedBackend` purges
|
|
98
|
+
entries automatically. Cache hits still write a `delegated_task.exec`
|
|
99
|
+
audit row with `cost_usd=0` and `detail.cacheHit=true`.
|
|
100
|
+
|
|
101
|
+
Never set `cacheable: true` on:
|
|
102
|
+
- destructive-confirm second calls (`allowDestructive: true`),
|
|
103
|
+
- tasks that depend on minute-level freshness,
|
|
104
|
+
- any write.
|
|
105
|
+
|
|
106
|
+
## Destructive-confirm dance — `allowDestructive`
|
|
107
|
+
|
|
108
|
+
Default is `false`. The subprocess will not call destructive tools
|
|
109
|
+
(send / delete / batch label mutate / etc.) — instead it returns:
|
|
110
|
+
|
|
111
|
+
```jsonc
|
|
112
|
+
{
|
|
113
|
+
"needsConfirmation": true,
|
|
114
|
+
"confirmationPlan": "I will send a reply to alice@example.com with subject \"Re: Proposal\" and body …"
|
|
115
|
+
}
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
Surface `confirmationPlan` to the user verbatim. On their explicit OK,
|
|
119
|
+
re-issue the **same `task` verbatim** with `allowDestructive: true`. Do
|
|
120
|
+
NOT set `cacheable: true` on the second call — the confirmation does
|
|
121
|
+
not extend across cache lifetimes.
|
|
122
|
+
|
|
123
|
+
## Worked examples
|
|
124
|
+
|
|
125
|
+
### Read a whole thread (composition handled by the subprocess)
|
|
126
|
+
|
|
127
|
+
When the active connector lacks a thread-fetch primitive (Gemini), the
|
|
128
|
+
subprocess composes search + per-message get — you don't have to
|
|
129
|
+
think about it.
|
|
130
|
+
|
|
131
|
+
```bash
|
|
132
|
+
curl -sS -X POST http://localhost:8321/api/integrations/gmail/exec \
|
|
133
|
+
-H 'Content-Type: application/json' \
|
|
134
|
+
-d '{
|
|
135
|
+
"task": "Fetch every message in Gmail thread <THREAD_ID>. For each message, return from / subject / body / timestamp. Sort by timestamp ascending.",
|
|
136
|
+
"outputSchema": {
|
|
137
|
+
"type": "object",
|
|
138
|
+
"required": ["messages"],
|
|
139
|
+
"properties": {
|
|
140
|
+
"messages": {
|
|
141
|
+
"type": "array",
|
|
142
|
+
"items": {
|
|
143
|
+
"type": "object",
|
|
144
|
+
"required": ["from", "subject", "body", "ts"],
|
|
145
|
+
"properties": {
|
|
146
|
+
"from": {"type": "string"},
|
|
147
|
+
"subject": {"type": "string"},
|
|
148
|
+
"body": {"type": "string"},
|
|
149
|
+
"ts": {"type": "string", "format": "date-time"}
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
},
|
|
155
|
+
"maxToolCalls": 7,
|
|
156
|
+
"cacheable": true
|
|
157
|
+
}'
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
### Compose a draft (default-safe, no destructive flag needed)
|
|
161
|
+
|
|
162
|
+
```bash
|
|
163
|
+
curl -sS -X POST http://localhost:8321/api/integrations/gmail/exec \
|
|
164
|
+
-H 'Content-Type: application/json' \
|
|
165
|
+
-d '{
|
|
166
|
+
"task": "Compose a Gmail draft replying to message <MESSAGE_ID>. Subject: \"Re: <ORIGINAL_SUBJECT>\". Body: <BODY>. Preserve the RFC-2822 thread (Message-Id + References).",
|
|
167
|
+
"outputSchema": {
|
|
168
|
+
"type": "object",
|
|
169
|
+
"required": ["draftId"],
|
|
170
|
+
"properties": { "draftId": { "type": "string" } }
|
|
171
|
+
},
|
|
172
|
+
"maxToolCalls": 4
|
|
173
|
+
}'
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
### Send a previously-vetted draft (destructive — confirmation required)
|
|
177
|
+
|
|
178
|
+
```bash
|
|
179
|
+
curl -sS -X POST http://localhost:8321/api/integrations/gmail/exec \
|
|
180
|
+
-H 'Content-Type: application/json' \
|
|
181
|
+
-d '{
|
|
182
|
+
"task": "Send Gmail draft <DRAFT_ID> as-is. Do not edit the body.",
|
|
183
|
+
"outputSchema": {
|
|
184
|
+
"type": "object",
|
|
185
|
+
"required": ["messageId"],
|
|
186
|
+
"properties": { "messageId": { "type": "string" } }
|
|
187
|
+
},
|
|
188
|
+
"maxToolCalls": 2,
|
|
189
|
+
"allowDestructive": true
|
|
190
|
+
}'
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
## Default deny floor
|
|
194
|
+
|
|
195
|
+
The setup wizard pre-populates `gmail.deniedTools` with the connector's
|
|
196
|
+
destructive defaults. `/exec` honors the deny list: a task that
|
|
197
|
+
requires a denied tool surfaces as `tool_unavailable` — surface that
|
|
198
|
+
to the user and ask whether to lift the deny before retrying.
|
|
199
|
+
|
|
200
|
+
## Decision rules
|
|
201
|
+
|
|
202
|
+
- **Prefer drafts over send.** Drafts are reversible, send is not.
|
|
203
|
+
- **Replies preserve the RFC-2822 chain.** Pin `Message-Id` /
|
|
204
|
+
`References` headers on the draft.
|
|
205
|
+
- **The reply account is implicit.** The connector picks the account
|
|
206
|
+
based on its own auth.
|
|
207
|
+
- **No `bcc` unless the user explicitly asks for it.**
|
|
208
|
+
- **Bulk operations: ask first.** Summarise count + criteria and
|
|
209
|
+
confirm before invoking.
|
|
210
|
+
|
|
211
|
+
## Error envelope
|
|
212
|
+
|
|
213
|
+
`/exec` extends the direct-mode envelope with delegated-mode fields.
|
|
214
|
+
Discriminator: `body.mode === "delegated"`.
|
|
215
|
+
|
|
216
|
+
| HTTP | `error` | retry? | What to do |
|
|
217
|
+
|---|---|---|---|
|
|
218
|
+
| 400 | `validation_error` / `schema_too_large` | no | Fix the request body. |
|
|
219
|
+
| 409 | `mode_mismatch` | no | Gmail isn't delegated, OR your DM backend matches `delegatedBackend`. Re-read `integrations.md` and stop. |
|
|
220
|
+
| 409 | `precondition` | no | Mode/backend was flipped during queue wait. Re-read `integrations.md` and re-plan. |
|
|
221
|
+
| 429 | `task_quota_exhausted` | no | Daily cap reached; wait or surface. |
|
|
222
|
+
| 502 | `parse_error` / `schema_violation` | no (daemon already retried once) | Consider a simpler schema. |
|
|
223
|
+
| 502 | `tool_unavailable` | no | No connector tool fits. Surface the gap. |
|
|
224
|
+
| 502 | `tool_failed` | maybe | Connector tool returned an error. Surface `body.message` verbatim; retry only if clearly transient. |
|
|
225
|
+
| 502 | `auth_error` | no | Connector signed out. Tell the user to re-authenticate. |
|
|
226
|
+
| 502 | `policy_violation` | no | Subprocess attempted a tool outside the per-task allowlist (anti-injection). |
|
|
227
|
+
| 502 | `loop_aborted` | no | `maxToolCalls` exceeded. Bump the cap or simplify. |
|
|
228
|
+
| 502 | `budget_exhausted` | no | `maxBudgetUsd` exceeded. Caller can raise the cap. |
|
|
229
|
+
| 502 | `post_write_format_failure` | no | Write succeeded; formatting failed. Side effect is real — surface with the partial trace. |
|
|
230
|
+
| 503 | `delegated_proxy_busy` | yes | Queue saturated. Backoff 3-5s and retry once. |
|
|
231
|
+
| 503 | `task_mode_disabled` | no | Operator turned the kill switch off. Stop. |
|
|
232
|
+
| 504 | `timeout` | yes (1×) | Wall-clock fired. Retry once for simple intents. |
|
|
233
|
+
| 500 | `subprocess_crashed` | no | Daemon-side defect. Surface and stop. |
|
|
234
|
+
|
|
235
|
+
## Owner notification (opt-in)
|
|
236
|
+
|
|
237
|
+
The daemon does not auto-DM the owner. When you take an action the
|
|
238
|
+
user would want to know about *immediately* — sending an external
|
|
239
|
+
email, archiving a stack, applying a sensitive label — call:
|
|
240
|
+
|
|
241
|
+
```bash
|
|
242
|
+
curl -sS -X POST http://localhost:8321/api/notify \
|
|
243
|
+
-H 'Content-Type: application/json' \
|
|
244
|
+
-d '{"message": "Sent reply to alice@example.com (Re: Proposal)"}'
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
Do not call `/api/notify` for routine reads / drafts / searches.
|
|
248
|
+
|
|
249
|
+
## Cost / retrospective
|
|
250
|
+
|
|
251
|
+
Every `/exec` writes one row to `agent_actions` with
|
|
252
|
+
`action_type='delegated_task.exec'` (token + USD breakdown). When the
|
|
253
|
+
user asks what you did:
|
|
254
|
+
|
|
255
|
+
```bash
|
|
256
|
+
curl -sS "http://localhost:8321/api/agent/actions?kind=delegated_task.exec&since=2026-04-25T00:00:00Z&limit=50"
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
Summarise from the returned `actions` array — each row carries
|
|
260
|
+
`detail.task` (the natural-language intent), cost, cache hit flag,
|
|
261
|
+
and timestamp.
|
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: mail
|
|
3
|
+
description: Load when the task touches Gmail and Gmail is in cross-backend delegated mode (DM session is Gemini; `delegatedBackend` is non-Gemini). Gmail accounts route through `POST /api/integrations/gmail/exec`; non-Gmail accounts (IMAP/Outlook/iCloud/Yahoo) keep the direct-mode `/api/mail/*` surface.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Mail (delegated, cross-backend)
|
|
7
|
+
|
|
8
|
+
Gmail is delegated to a different backend (Claude or Codex). The
|
|
9
|
+
daemon spawns that backend on demand, lets it pick the right MCP tool,
|
|
10
|
+
and returns a schema-validated JSON result. **You describe intent in
|
|
11
|
+
natural language; the daemon picks the tool.** Tool name divergence
|
|
12
|
+
between Claude (`search_threads`), Codex (`search_emails`) and any
|
|
13
|
+
custom MCP server the user installs is invisible to you.
|
|
14
|
+
|
|
15
|
+
To confirm Gmail's current delegate, read
|
|
16
|
+
`~/.personal-agent/integrations.md` and consult its `delegatedBackend`
|
|
17
|
+
field. The same prose body below works for every delegate.
|
|
18
|
+
|
|
19
|
+
## Non-Gmail accounts keep the direct-mode surface
|
|
20
|
+
|
|
21
|
+
Per-account gating: the `/api/mail/*` 410 only fires when the resolved
|
|
22
|
+
`accountId` is `kind=gmail`. IMAP / Outlook / iCloud / Yahoo accounts
|
|
23
|
+
remain fully reachable through the direct-mode endpoints documented in
|
|
24
|
+
the base `mail` skill body. Use `accounts.md` (still materialized for
|
|
25
|
+
this session) to resolve the account and pick the path:
|
|
26
|
+
|
|
27
|
+
| Selected account `kind` | Path |
|
|
28
|
+
|---|---|
|
|
29
|
+
| `gmail` | task: `POST /api/integrations/gmail/exec {task, outputSchema, …}` (this file) |
|
|
30
|
+
| `outlook` / `icloud` / `yahoo` / `imap` | direct: `/api/mail/:acct/*` (base body) |
|
|
31
|
+
|
|
32
|
+
Only the Gmail branch leaves the direct-mode surface. Account
|
|
33
|
+
resolution, draft-vs-send rules, and reply-thread chaining are
|
|
34
|
+
unchanged for non-Gmail accounts.
|
|
35
|
+
|
|
36
|
+
## Call shape
|
|
37
|
+
|
|
38
|
+
The single endpoint is `POST /api/integrations/gmail/exec`. The body
|
|
39
|
+
takes a natural-language `task` plus an `outputSchema` (Draft-07 JSON
|
|
40
|
+
Schema) the daemon validates the result against.
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
curl -sS -X POST http://localhost:8321/api/integrations/gmail/exec \
|
|
44
|
+
-H 'Content-Type: application/json' \
|
|
45
|
+
-d '{
|
|
46
|
+
"task": "Search Gmail for unread messages from alice@example.com in the last 7 days. Return up to 10 with sender, subject, snippet, timestamp.",
|
|
47
|
+
"outputSchema": {
|
|
48
|
+
"type": "object",
|
|
49
|
+
"required": ["messages"],
|
|
50
|
+
"properties": {
|
|
51
|
+
"messages": {
|
|
52
|
+
"type": "array",
|
|
53
|
+
"items": {
|
|
54
|
+
"type": "object",
|
|
55
|
+
"required": ["from", "subject", "snippet", "ts"],
|
|
56
|
+
"properties": {
|
|
57
|
+
"from": {"type": "string"},
|
|
58
|
+
"subject": {"type": "string"},
|
|
59
|
+
"snippet": {"type": "string"},
|
|
60
|
+
"ts": {"type": "string", "format": "date-time"}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
},
|
|
66
|
+
"maxToolCalls": 5,
|
|
67
|
+
"cacheable": true
|
|
68
|
+
}'
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
Response shape on success:
|
|
72
|
+
|
|
73
|
+
```jsonc
|
|
74
|
+
{
|
|
75
|
+
"result": { "messages": [ ... ] }, // schema-validated parse
|
|
76
|
+
"needsConfirmation": false,
|
|
77
|
+
"confirmationPlan": null,
|
|
78
|
+
"trace": [ /* per-tool-call breakdown — informational */ ],
|
|
79
|
+
"cost": { "tokensInput": ..., "costUsd": ..., "durationMs": ... }
|
|
80
|
+
}
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
`outputSchema` is **required** — the subprocess emits exactly one JSON
|
|
84
|
+
object as its final message and the daemon validates it. Schemas
|
|
85
|
+
larger than 4 KB are rejected (`schema_too_large`). Caps default to
|
|
86
|
+
`maxToolCalls=7`, `maxBudgetUsd=0.05`, `timeoutMs=60000` — bump them
|
|
87
|
+
via the request body up to the hard caps (15 / 0.50 / 300000) when a
|
|
88
|
+
task genuinely needs more.
|
|
89
|
+
|
|
90
|
+
## Idempotent reads — `cacheable: true`
|
|
91
|
+
|
|
92
|
+
Pure-read tasks should set `cacheable: true` so a repeat invocation
|
|
93
|
+
within 60s returns ~5ms from the in-memory LRU. The cache key includes
|
|
94
|
+
the integration state version, so flipping `deniedTools` or
|
|
95
|
+
`delegatedBackend` purges entries automatically. Cache hits still
|
|
96
|
+
write a `delegated_task.exec` audit row with `cost_usd=0` and
|
|
97
|
+
`detail.cacheHit=true`.
|
|
98
|
+
|
|
99
|
+
Never set `cacheable: true` on:
|
|
100
|
+
- destructive-confirm second calls (`allowDestructive: true`),
|
|
101
|
+
- tasks that depend on minute-level freshness,
|
|
102
|
+
- any write.
|
|
103
|
+
|
|
104
|
+
## Destructive-confirm dance — `allowDestructive`
|
|
105
|
+
|
|
106
|
+
Default is `false`. The subprocess will not call destructive tools —
|
|
107
|
+
instead it returns:
|
|
108
|
+
|
|
109
|
+
```jsonc
|
|
110
|
+
{
|
|
111
|
+
"needsConfirmation": true,
|
|
112
|
+
"confirmationPlan": "I will send a reply to alice@example.com with subject \"Re: Proposal\" and body …"
|
|
113
|
+
}
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
Surface `confirmationPlan` to the user verbatim. On their explicit OK,
|
|
117
|
+
re-issue the **same `task` verbatim** with `allowDestructive: true`. Do
|
|
118
|
+
NOT set `cacheable: true` on the second call — the confirmation does
|
|
119
|
+
not extend across cache lifetimes.
|
|
120
|
+
|
|
121
|
+
## Worked examples
|
|
122
|
+
|
|
123
|
+
### Read a whole thread (composition handled by the subprocess)
|
|
124
|
+
|
|
125
|
+
```bash
|
|
126
|
+
curl -sS -X POST http://localhost:8321/api/integrations/gmail/exec \
|
|
127
|
+
-H 'Content-Type: application/json' \
|
|
128
|
+
-d '{
|
|
129
|
+
"task": "Fetch every message in Gmail thread <THREAD_ID>. For each message, return from / subject / body / timestamp. Sort by timestamp ascending.",
|
|
130
|
+
"outputSchema": {
|
|
131
|
+
"type": "object",
|
|
132
|
+
"required": ["messages"],
|
|
133
|
+
"properties": {
|
|
134
|
+
"messages": {
|
|
135
|
+
"type": "array",
|
|
136
|
+
"items": {
|
|
137
|
+
"type": "object",
|
|
138
|
+
"required": ["from", "subject", "body", "ts"],
|
|
139
|
+
"properties": {
|
|
140
|
+
"from": {"type": "string"},
|
|
141
|
+
"subject": {"type": "string"},
|
|
142
|
+
"body": {"type": "string"},
|
|
143
|
+
"ts": {"type": "string", "format": "date-time"}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
},
|
|
149
|
+
"maxToolCalls": 7,
|
|
150
|
+
"cacheable": true
|
|
151
|
+
}'
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
### Compose a draft (default-safe)
|
|
155
|
+
|
|
156
|
+
```bash
|
|
157
|
+
curl -sS -X POST http://localhost:8321/api/integrations/gmail/exec \
|
|
158
|
+
-H 'Content-Type: application/json' \
|
|
159
|
+
-d '{
|
|
160
|
+
"task": "Compose a Gmail draft replying to message <MESSAGE_ID>. Subject: \"Re: <ORIGINAL_SUBJECT>\". Body: <BODY>. Preserve the RFC-2822 thread (Message-Id + References).",
|
|
161
|
+
"outputSchema": {
|
|
162
|
+
"type": "object",
|
|
163
|
+
"required": ["draftId"],
|
|
164
|
+
"properties": { "draftId": { "type": "string" } }
|
|
165
|
+
},
|
|
166
|
+
"maxToolCalls": 4
|
|
167
|
+
}'
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
### Send a previously-vetted draft (destructive)
|
|
171
|
+
|
|
172
|
+
```bash
|
|
173
|
+
curl -sS -X POST http://localhost:8321/api/integrations/gmail/exec \
|
|
174
|
+
-H 'Content-Type: application/json' \
|
|
175
|
+
-d '{
|
|
176
|
+
"task": "Send Gmail draft <DRAFT_ID> as-is. Do not edit the body.",
|
|
177
|
+
"outputSchema": {
|
|
178
|
+
"type": "object",
|
|
179
|
+
"required": ["messageId"],
|
|
180
|
+
"properties": { "messageId": { "type": "string" } }
|
|
181
|
+
},
|
|
182
|
+
"maxToolCalls": 2,
|
|
183
|
+
"allowDestructive": true
|
|
184
|
+
}'
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
## Default deny floor
|
|
188
|
+
|
|
189
|
+
The setup wizard pre-populates `gmail.deniedTools` with the connector's
|
|
190
|
+
destructive defaults. `/exec` honors the deny list: a task that
|
|
191
|
+
requires a denied tool surfaces as `tool_unavailable` — surface that
|
|
192
|
+
to the user and ask whether to lift the deny before retrying.
|
|
193
|
+
|
|
194
|
+
## Decision rules
|
|
195
|
+
|
|
196
|
+
- **Prefer drafts over send.** Drafts are reversible, send is not.
|
|
197
|
+
- **Replies preserve the RFC-2822 chain.** Pin `Message-Id` /
|
|
198
|
+
`References` headers on the draft.
|
|
199
|
+
- **The reply account is implicit.** The connector picks the account
|
|
200
|
+
based on its own auth.
|
|
201
|
+
- **No `bcc` unless the user explicitly asks for it.**
|
|
202
|
+
- **Bulk operations: ask first.** Summarise count + criteria and
|
|
203
|
+
confirm before invoking.
|
|
204
|
+
|
|
205
|
+
## Error envelope
|
|
206
|
+
|
|
207
|
+
`/exec` extends the direct-mode envelope with delegated-mode fields.
|
|
208
|
+
Discriminator: `body.mode === "delegated"`.
|
|
209
|
+
|
|
210
|
+
| HTTP | `error` | retry? | What to do |
|
|
211
|
+
|---|---|---|---|
|
|
212
|
+
| 400 | `validation_error` / `schema_too_large` | no | Fix the request body. |
|
|
213
|
+
| 409 | `mode_mismatch` | no | Gmail isn't delegated, OR your DM backend matches `delegatedBackend`. Re-read `integrations.md` and stop. |
|
|
214
|
+
| 409 | `precondition` | no | Mode/backend was flipped during queue wait. Re-read `integrations.md` and re-plan. |
|
|
215
|
+
| 429 | `task_quota_exhausted` | no | Daily cap reached; wait or surface. |
|
|
216
|
+
| 502 | `parse_error` / `schema_violation` | no (daemon already retried once) | Consider a simpler schema. |
|
|
217
|
+
| 502 | `tool_unavailable` | no | No connector tool fits. Surface the gap. |
|
|
218
|
+
| 502 | `tool_failed` | maybe | Connector tool returned an error. Surface `body.message` verbatim; retry only if clearly transient. |
|
|
219
|
+
| 502 | `auth_error` | no | Connector signed out. Tell the user to re-authenticate. |
|
|
220
|
+
| 502 | `policy_violation` | no | Subprocess attempted a tool outside the per-task allowlist (anti-injection). |
|
|
221
|
+
| 502 | `loop_aborted` | no | `maxToolCalls` exceeded. Bump the cap or simplify. |
|
|
222
|
+
| 502 | `budget_exhausted` | no | `maxBudgetUsd` exceeded. Caller can raise the cap. |
|
|
223
|
+
| 502 | `post_write_format_failure` | no | Write succeeded; formatting failed. Side effect is real — surface with the partial trace. |
|
|
224
|
+
| 503 | `delegated_proxy_busy` | yes | Queue saturated. Backoff 3-5s and retry once. |
|
|
225
|
+
| 503 | `task_mode_disabled` | no | Operator turned the kill switch off. Stop. |
|
|
226
|
+
| 504 | `timeout` | yes (1×) | Wall-clock fired. Retry once for simple intents. |
|
|
227
|
+
| 500 | `subprocess_crashed` | no | Daemon-side defect. Surface and stop. |
|
|
228
|
+
|
|
229
|
+
## Owner notification (opt-in)
|
|
230
|
+
|
|
231
|
+
The daemon does not auto-DM the owner. When you take an action the
|
|
232
|
+
user would want to know about *immediately* — sending an external
|
|
233
|
+
email, archiving a stack, applying a sensitive label — call:
|
|
234
|
+
|
|
235
|
+
```bash
|
|
236
|
+
curl -sS -X POST http://localhost:8321/api/notify \
|
|
237
|
+
-H 'Content-Type: application/json' \
|
|
238
|
+
-d '{"message": "Sent reply to alice@example.com (Re: Proposal)"}'
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
Do not call `/api/notify` for routine reads / drafts / searches.
|
|
242
|
+
|
|
243
|
+
## Cost / retrospective
|
|
244
|
+
|
|
245
|
+
Every `/exec` writes one row to `agent_actions` with
|
|
246
|
+
`action_type='delegated_task.exec'` (token + USD breakdown). When the
|
|
247
|
+
user asks what you did:
|
|
248
|
+
|
|
249
|
+
```bash
|
|
250
|
+
curl -sS "http://localhost:8321/api/agent/actions?kind=delegated_task.exec&since=2026-04-25T00:00:00Z&limit=50"
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
Summarise from the returned `actions` array — each row carries
|
|
254
|
+
`detail.task` (the natural-language intent), cost, cache hit flag,
|
|
255
|
+
and timestamp.
|