@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.
Files changed (249) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +464 -0
  3. package/agent-assets/agent-profiles/_safety.md +26 -0
  4. package/agent-assets/agent-profiles/conversational.md +33 -0
  5. package/agent-assets/agent-profiles/docs-qa.md +24 -0
  6. package/agent-assets/agent-profiles/observer.md +28 -0
  7. package/agent-assets/agent-profiles/profile-importer.md +63 -0
  8. package/agent-assets/agent-profiles/proxy.md +28 -0
  9. package/agent-assets/agent-profiles/routine.md +16 -0
  10. package/agent-assets/agent-profiles/task.md +18 -0
  11. package/agent-assets/docs/concepts/agent-day.md +88 -0
  12. package/agent-assets/docs/concepts/auth-health.md +75 -0
  13. package/agent-assets/docs/concepts/backends-and-tiers.md +126 -0
  14. package/agent-assets/docs/concepts/costs-and-quotas.md +103 -0
  15. package/agent-assets/docs/concepts/delegated-mode.md +223 -0
  16. package/agent-assets/docs/concepts/memory-model.md +118 -0
  17. package/agent-assets/docs/concepts/observations.md +80 -0
  18. package/agent-assets/docs/concepts/process-keys.md +89 -0
  19. package/agent-assets/docs/concepts/routines.md +108 -0
  20. package/agent-assets/docs/concepts/safety-and-execution.md +109 -0
  21. package/agent-assets/docs/concepts/safety-model.md +279 -0
  22. package/agent-assets/docs/concepts/skills.md +100 -0
  23. package/agent-assets/docs/features/integrations/calendar.md +92 -0
  24. package/agent-assets/docs/features/integrations/git.md +95 -0
  25. package/agent-assets/docs/features/integrations/github.md +170 -0
  26. package/agent-assets/docs/features/integrations/mail.md +106 -0
  27. package/agent-assets/docs/features/integrations/notion.md +69 -0
  28. package/agent-assets/docs/features/integrations/obsidian.md +71 -0
  29. package/agent-assets/docs/features/lifestyle/git.md +178 -0
  30. package/agent-assets/docs/features/lifestyle/reading.md +93 -0
  31. package/agent-assets/docs/features/lifestyle/receipts.md +71 -0
  32. package/agent-assets/docs/features/lifestyle/travel-bookings.md +44 -0
  33. package/agent-assets/docs/features/lifestyle/travel-time.md +52 -0
  34. package/agent-assets/docs/features/memory-files/agent-journal.md +105 -0
  35. package/agent-assets/docs/features/memory-files/projects.md +56 -0
  36. package/agent-assets/docs/features/memory-files/roadmap.md +61 -0
  37. package/agent-assets/docs/features/memory-files/schedule.md +112 -0
  38. package/agent-assets/docs/features/memory-files/today.md +73 -0
  39. package/agent-assets/docs/features/memory-files/user-profile.md +81 -0
  40. package/agent-assets/docs/features/messaging/dashboard-chat.md +93 -0
  41. package/agent-assets/docs/features/messaging/discord.md +50 -0
  42. package/agent-assets/docs/features/messaging/overview.md +111 -0
  43. package/agent-assets/docs/features/messaging/pairing-and-magic-phrase.md +69 -0
  44. package/agent-assets/docs/features/messaging/slack.md +51 -0
  45. package/agent-assets/docs/features/messaging/telegram.md +63 -0
  46. package/agent-assets/docs/features/messaging/whatsapp.md +48 -0
  47. package/agent-assets/docs/features/operations/activity-and-conversations.md +105 -0
  48. package/agent-assets/docs/features/operations/approvals.md +58 -0
  49. package/agent-assets/docs/features/operations/backend-routing.md +62 -0
  50. package/agent-assets/docs/features/operations/cost-tracking.md +59 -0
  51. package/agent-assets/docs/features/operations/notifications.md +69 -0
  52. package/agent-assets/docs/features/operations/quiet-hours.md +106 -0
  53. package/agent-assets/docs/features/operations/schedule-approaching.md +60 -0
  54. package/agent-assets/docs/features/routines/custom-routines.md +101 -0
  55. package/agent-assets/docs/features/routines/evening-review.md +81 -0
  56. package/agent-assets/docs/features/routines/hourly-check.md +85 -0
  57. package/agent-assets/docs/features/routines/monthly-review.md +65 -0
  58. package/agent-assets/docs/features/routines/morning-routine.md +123 -0
  59. package/agent-assets/docs/features/routines/weekly-review.md +70 -0
  60. package/agent-assets/docs/getting-started/01-what-is-this.md +192 -0
  61. package/agent-assets/docs/getting-started/02-first-steps.md +80 -0
  62. package/agent-assets/docs/getting-started/03-what-can-this-do.md +110 -0
  63. package/agent-assets/docs/getting-started/04-first-day.md +287 -0
  64. package/agent-assets/docs/glossary.md +116 -0
  65. package/agent-assets/docs/guides/add-a-custom-routine.md +71 -0
  66. package/agent-assets/docs/guides/backup-and-restore.md +54 -0
  67. package/agent-assets/docs/guides/change-which-model-handles-x.md +47 -0
  68. package/agent-assets/docs/guides/connect-a-new-mail-account.md +59 -0
  69. package/agent-assets/docs/guides/import-knowledge-file.md +275 -0
  70. package/agent-assets/docs/guides/install-and-run.md +72 -0
  71. package/agent-assets/docs/guides/migrate-machines.md +52 -0
  72. package/agent-assets/docs/guides/pause-the-agent.md +65 -0
  73. package/agent-assets/docs/guides/reinstall-cleanly.md +52 -0
  74. package/agent-assets/docs/guides/setup-wizard.md +107 -0
  75. package/agent-assets/docs/guides/switch-default-backend.md +60 -0
  76. package/agent-assets/docs/reference/api.md +51 -0
  77. package/agent-assets/docs/reference/cli-commands.md +121 -0
  78. package/agent-assets/docs/reference/config.md +74 -0
  79. package/agent-assets/docs/reference/disallowed-tools.md +76 -0
  80. package/agent-assets/docs/reference/keyboard-shortcuts.md +39 -0
  81. package/agent-assets/docs/reference/process-keys.md +59 -0
  82. package/agent-assets/docs/reference/skills.md +50 -0
  83. package/agent-assets/docs/troubleshooting/auth-failed.md +57 -0
  84. package/agent-assets/docs/troubleshooting/dashboard-shows-degraded.md +55 -0
  85. package/agent-assets/docs/troubleshooting/fallback-keeps-firing.md +54 -0
  86. package/agent-assets/docs/troubleshooting/messaging-not-pairing.md +53 -0
  87. package/agent-assets/docs/troubleshooting/morning-routine-didnt-run.md +75 -0
  88. package/agent-assets/docs/troubleshooting/observation-not-detected.md +57 -0
  89. package/agent-assets/docs/troubleshooting/quota-exhausted.md +57 -0
  90. package/agent-assets/optimizer-skills/drift-analysis/SKILL.md +75 -0
  91. package/agent-assets/optimizer-skills/knowledge-map/SKILL.md +71 -0
  92. package/agent-assets/optimizer-skills/skill-curation/SKILL.md +108 -0
  93. package/agent-assets/project-doc-templates/git-repo.md +21 -0
  94. package/agent-assets/project-doc-templates/project.md +38 -0
  95. package/agent-assets/skills/attach/SKILL.md +104 -0
  96. package/agent-assets/skills/context/SKILL.md +257 -0
  97. package/agent-assets/skills/context/curation.json +37 -0
  98. package/agent-assets/skills/context/seeds/file-responsibilities.seed.json +13 -0
  99. package/agent-assets/skills/context/seeds/frontmatter-requirements.seed.json +40 -0
  100. package/agent-assets/skills/docs-search/SKILL.md +176 -0
  101. package/agent-assets/skills/external-services/SKILL.delegated.claude.md +369 -0
  102. package/agent-assets/skills/external-services/SKILL.delegated.codex.md +349 -0
  103. package/agent-assets/skills/external-services/SKILL.delegated.gemini.md +347 -0
  104. package/agent-assets/skills/external-services/SKILL.md +371 -0
  105. package/agent-assets/skills/mail/SKILL.delegated.claude.md +284 -0
  106. package/agent-assets/skills/mail/SKILL.delegated.codex.md +261 -0
  107. package/agent-assets/skills/mail/SKILL.delegated.gemini.md +255 -0
  108. package/agent-assets/skills/mail/SKILL.md +313 -0
  109. package/agent-assets/skills/mail/references/errors.md +17 -0
  110. package/agent-assets/skills/mail/references/providers.md +40 -0
  111. package/agent-assets/skills/mail/references/query-grammar.md +24 -0
  112. package/agent-assets/skills/management-policy/SKILL.md +307 -0
  113. package/agent-assets/skills/management-policy/curation.json +13 -0
  114. package/agent-assets/skills/management-policy/seeds/policy-file-shape.seed.json +16 -0
  115. package/agent-assets/skills/management-task-modify/SKILL.md +202 -0
  116. package/agent-assets/skills/management-task-register/SKILL.md +330 -0
  117. package/agent-assets/skills/management-task-stop/SKILL.md +166 -0
  118. package/agent-assets/skills/notify/SKILL.md +196 -0
  119. package/agent-assets/skills/notion/SKILL.delegated.claude.md +254 -0
  120. package/agent-assets/skills/notion/SKILL.delegated.codex.md +195 -0
  121. package/agent-assets/skills/notion/SKILL.delegated.gemini.md +194 -0
  122. package/agent-assets/skills/notion/SKILL.md +86 -0
  123. package/agent-assets/skills/observations/SKILL.md +234 -0
  124. package/agent-assets/skills/observations/curation.json +13 -0
  125. package/agent-assets/skills/observations/seeds/source-namespacing.seed.json +20 -0
  126. package/agent-assets/skills/project-doc/SKILL.md +86 -0
  127. package/agent-assets/skills/project-doc/curation.json +21 -0
  128. package/agent-assets/skills/project-doc/seeds/project-shape.seed.json +25 -0
  129. package/agent-assets/skills/project-doc/seeds/slug-grammar.seed.json +20 -0
  130. package/agent-assets/skills/reading/SKILL.md +198 -0
  131. package/agent-assets/skills/reading/references/reading-taste.md +197 -0
  132. package/agent-assets/skills/receipts/SKILL.md +134 -0
  133. package/agent-assets/skills/roadmap/SKILL.md +276 -0
  134. package/agent-assets/skills/roadmap/curation.json +13 -0
  135. package/agent-assets/skills/roadmap/references/horizon-tags.md +40 -0
  136. package/agent-assets/skills/roadmap/references/preparation-timeline.md +47 -0
  137. package/agent-assets/skills/roadmap/seeds/entry-types.seed.json +16 -0
  138. package/agent-assets/skills/schedule/SKILL.md +228 -0
  139. package/agent-assets/skills/scheduled-managed-task/SKILL.md +392 -0
  140. package/agent-assets/skills/today/SKILL.md +198 -0
  141. package/agent-assets/skills/today/curation.json +21 -0
  142. package/agent-assets/skills/today/seeds/agent-notes-flavors.seed.json +17 -0
  143. package/agent-assets/skills/today/seeds/section-shape.seed.json +17 -0
  144. package/agent-assets/skills/travel/SKILL.md +132 -0
  145. package/agent-assets/skills/travel-time/SKILL.md +149 -0
  146. package/agent-assets/skills/user-interview/SKILL.md +323 -0
  147. package/agent-assets/skills/user-interview/references/sweep-and-fallback.md +94 -0
  148. package/agent-assets/skills/user-profile/SKILL.md +210 -0
  149. package/agent-assets/skills/user-profile/curation.json +29 -0
  150. package/agent-assets/skills/user-profile/seeds/learned-context-format.seed.json +14 -0
  151. package/agent-assets/skills/user-profile/seeds/routing-table.seed.json +53 -0
  152. package/agent-assets/skills/user-profile/seeds/topic-files.seed.json +27 -0
  153. package/agent-assets/task-flows/dashboard.docs_qa.md +43 -0
  154. package/agent-assets/task-flows/default.md +11 -0
  155. package/agent-assets/task-flows/git.branch.created.md +25 -0
  156. package/agent-assets/task-flows/git.lifecycle.poll.md +52 -0
  157. package/agent-assets/task-flows/git.local_ahead.stale.md +34 -0
  158. package/agent-assets/task-flows/git.merge_to_default.md +30 -0
  159. package/agent-assets/task-flows/git.project.refresh_architecture.md +100 -0
  160. package/agent-assets/task-flows/git.project.retemplate.md +73 -0
  161. package/agent-assets/task-flows/git.push.detected.md +32 -0
  162. package/agent-assets/task-flows/git.push.force_pushed.md +36 -0
  163. package/agent-assets/task-flows/git.tag.created.md +24 -0
  164. package/agent-assets/task-flows/github.assigned.md +43 -0
  165. package/agent-assets/task-flows/github.pull_request.review_requested.md +57 -0
  166. package/agent-assets/task-flows/github.security_alert.md +45 -0
  167. package/agent-assets/task-flows/github.workflow_run.failed.md +57 -0
  168. package/agent-assets/task-flows/knowledge.import.md +161 -0
  169. package/agent-assets/task-flows/message.received.dm.md +142 -0
  170. package/agent-assets/task-flows/message.received.dm_first.md +117 -0
  171. package/agent-assets/task-flows/message.received.md +14 -0
  172. package/agent-assets/task-flows/routine.custom.md +38 -0
  173. package/agent-assets/task-flows/routine.evening_review.md +323 -0
  174. package/agent-assets/task-flows/routine.hourly_check.delegated.claude.md +405 -0
  175. package/agent-assets/task-flows/routine.hourly_check.delegated.codex.md +400 -0
  176. package/agent-assets/task-flows/routine.hourly_check.delegated.gemini.md +404 -0
  177. package/agent-assets/task-flows/routine.hourly_check.md +184 -0
  178. package/agent-assets/task-flows/routine.hourly_check.triage.md +93 -0
  179. package/agent-assets/task-flows/routine.monthly_review.md +250 -0
  180. package/agent-assets/task-flows/routine.morning_routine.md +300 -0
  181. package/agent-assets/task-flows/routine.morning_routine_initial.md +184 -0
  182. package/agent-assets/task-flows/routine.roadmap_refresh.md +275 -0
  183. package/agent-assets/task-flows/routine.today_refresh.md +172 -0
  184. package/agent-assets/task-flows/routine.user_profile_sweep.md +242 -0
  185. package/agent-assets/task-flows/routine.weekly_review.md +247 -0
  186. package/agent-assets/task-flows/schedule.approaching.md +124 -0
  187. package/agent-assets/task-flows/scheduled.dm.md +391 -0
  188. package/agent-assets/task-flows/scheduled.task.md +141 -0
  189. package/agent-assets/task-flows/setup.initial.md +277 -0
  190. package/agent-assets/task-flows/setup.update.md +53 -0
  191. package/agent-assets/templates/README.md +85 -0
  192. package/agent-assets/templates/_index.md +39 -0
  193. package/agent-assets/templates/_manifest.json +103 -0
  194. package/agent-assets/templates/agent/journal.md +10 -0
  195. package/agent-assets/templates/agent/profile-questions.md +74 -0
  196. package/agent-assets/templates/context-index.md +42 -0
  197. package/agent-assets/templates/dossiers/_index.md +22 -0
  198. package/agent-assets/templates/dossiers/evening.md +23 -0
  199. package/agent-assets/templates/dossiers/hourly.md +23 -0
  200. package/agent-assets/templates/dossiers/monthly.md +23 -0
  201. package/agent-assets/templates/dossiers/morning.md +23 -0
  202. package/agent-assets/templates/dossiers/roadmap.md +23 -0
  203. package/agent-assets/templates/dossiers/weekly.md +23 -0
  204. package/agent-assets/templates/projects/_active.base +14 -0
  205. package/agent-assets/templates/projects/_index.md +29 -0
  206. package/agent-assets/templates/roadmap.md +15 -0
  207. package/agent-assets/templates/routines/_index.md +20 -0
  208. package/agent-assets/templates/routines/evening.md +22 -0
  209. package/agent-assets/templates/routines/hourly.md +30 -0
  210. package/agent-assets/templates/routines/monthly.md +25 -0
  211. package/agent-assets/templates/routines/morning.md +26 -0
  212. package/agent-assets/templates/routines/weekly.md +23 -0
  213. package/agent-assets/templates/rules/_index.md +19 -0
  214. package/agent-assets/templates/rules/journal-export.md +41 -0
  215. package/agent-assets/templates/rules/journal-format.md +61 -0
  216. package/agent-assets/templates/rules/management.md +48 -0
  217. package/agent-assets/templates/rules/mcp.md +40 -0
  218. package/agent-assets/templates/rules/policies/_index.md +22 -0
  219. package/agent-assets/templates/rules/redaction.md +30 -0
  220. package/agent-assets/templates/today.md +13 -0
  221. package/agent-assets/templates/user/_index.md +16 -0
  222. package/agent-assets/templates/user/expertise.md +7 -0
  223. package/agent-assets/templates/user/goals.md +7 -0
  224. package/agent-assets/templates/user/people.md +7 -0
  225. package/agent-assets/templates/user/personal.md +7 -0
  226. package/agent-assets/templates/user/profile.md +28 -0
  227. package/agent-assets/templates/user/work.md +7 -0
  228. package/bin/aitne.mjs +1096 -0
  229. package/package.json +78 -0
  230. package/personal-agent.mjs +39 -0
  231. package/scripts/browser.mjs +99 -0
  232. package/scripts/check-redaction-coverage.mjs +109 -0
  233. package/scripts/commands/audit.mjs +309 -0
  234. package/scripts/commands/doctor.mjs +437 -0
  235. package/scripts/commands/open.mjs +40 -0
  236. package/scripts/commands/setup.mjs +21 -0
  237. package/scripts/commands/uninstall.mjs +114 -0
  238. package/scripts/commands/update.mjs +96 -0
  239. package/scripts/commands/version.mjs +62 -0
  240. package/scripts/commands.md +0 -0
  241. package/scripts/lib/sqlite-loader.mjs +49 -0
  242. package/scripts/message-discipline-digest.mjs +535 -0
  243. package/scripts/poc/google-connector-inheritance/REPORT.md +197 -0
  244. package/scripts/poc/google-connector-inheritance/claude-sdk-probe.mjs +79 -0
  245. package/scripts/remint-roadmap-ids.mjs +257 -0
  246. package/scripts/rm-paths.mjs +22 -0
  247. package/scripts/run-node.mjs +223 -0
  248. package/scripts/smoke-obsidian-api.mjs +166 -0
  249. 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.