@aitne-sh/aitne 0.1.7 → 0.1.8

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 (222) hide show
  1. package/README.md +195 -829
  2. package/agent-assets/agent-profiles/_safety.md +49 -17
  3. package/agent-assets/agent-profiles/profile-importer.md +1 -1
  4. package/agent-assets/agent-profiles/routine.md +4 -3
  5. package/agent-assets/docs/concepts/agent-day.md +6 -1
  6. package/agent-assets/docs/concepts/auth-health.md +10 -1
  7. package/agent-assets/docs/concepts/backends-and-tiers.md +74 -40
  8. package/agent-assets/docs/concepts/costs-and-quotas.md +25 -5
  9. package/agent-assets/docs/concepts/delegated-mode.md +147 -68
  10. package/agent-assets/docs/concepts/memory-model.md +9 -4
  11. package/agent-assets/docs/concepts/observations.md +13 -1
  12. package/agent-assets/docs/concepts/process-keys.md +20 -5
  13. package/agent-assets/docs/concepts/routines.md +38 -20
  14. package/agent-assets/docs/concepts/safety-model.md +30 -13
  15. package/agent-assets/docs/concepts/skills.md +12 -7
  16. package/agent-assets/docs/features/integrations/calendar.md +1 -1
  17. package/agent-assets/docs/features/integrations/git.md +2 -2
  18. package/agent-assets/docs/features/integrations/github.md +9 -2
  19. package/agent-assets/docs/features/integrations/mail.md +1 -1
  20. package/agent-assets/docs/features/integrations/notion.md +34 -6
  21. package/agent-assets/docs/features/integrations/obsidian.md +7 -2
  22. package/agent-assets/docs/features/lifestyle/git.md +4 -7
  23. package/agent-assets/docs/features/lifestyle/receipts.md +17 -2
  24. package/agent-assets/docs/features/lifestyle/travel-bookings.md +15 -0
  25. package/agent-assets/docs/features/lifestyle/travel-time.md +7 -1
  26. package/agent-assets/docs/features/memory-files/agent-journal.md +2 -2
  27. package/agent-assets/docs/features/memory-files/projects.md +6 -0
  28. package/agent-assets/docs/features/memory-files/roadmap.md +5 -0
  29. package/agent-assets/docs/features/memory-files/today.md +1 -0
  30. package/agent-assets/docs/features/memory-files/user-profile.md +6 -0
  31. package/agent-assets/docs/features/messaging/bang-commands.md +20 -10
  32. package/agent-assets/docs/features/messaging/discord.md +12 -1
  33. package/agent-assets/docs/features/messaging/overview.md +10 -7
  34. package/agent-assets/docs/features/messaging/slack.md +13 -1
  35. package/agent-assets/docs/features/messaging/telegram.md +7 -1
  36. package/agent-assets/docs/features/messaging/whatsapp.md +12 -1
  37. package/agent-assets/docs/features/operations/activity-and-conversations.md +2 -2
  38. package/agent-assets/docs/features/operations/approvals.md +6 -0
  39. package/agent-assets/docs/features/operations/backend-routing.md +7 -0
  40. package/agent-assets/docs/features/operations/cost-tracking.md +6 -0
  41. package/agent-assets/docs/features/operations/notifications.md +6 -0
  42. package/agent-assets/docs/features/operations/schedule-approaching.md +22 -9
  43. package/agent-assets/docs/features/routines/custom-routines.md +10 -4
  44. package/agent-assets/docs/features/routines/evening-review.md +1 -1
  45. package/agent-assets/docs/features/routines/hourly-check.md +1 -1
  46. package/agent-assets/docs/features/routines/morning-routine.md +24 -15
  47. package/agent-assets/docs/features/routines/weekly-review.md +38 -12
  48. package/agent-assets/docs/features/wiki/commands.md +11 -0
  49. package/agent-assets/docs/features/wiki/overview.md +13 -3
  50. package/agent-assets/docs/getting-started/01-what-is-this.md +32 -11
  51. package/agent-assets/docs/getting-started/02-first-steps.md +17 -4
  52. package/agent-assets/docs/getting-started/03-what-can-this-do.md +21 -11
  53. package/agent-assets/docs/getting-started/04-first-day.md +14 -0
  54. package/agent-assets/docs/glossary.md +65 -12
  55. package/agent-assets/docs/guides/add-a-custom-routine.md +12 -0
  56. package/agent-assets/docs/guides/backup-and-restore.md +16 -2
  57. package/agent-assets/docs/guides/budget-and-cost-for-wiki.md +6 -0
  58. package/agent-assets/docs/guides/build-your-wiki.md +14 -0
  59. package/agent-assets/docs/guides/change-which-model-handles-x.md +7 -0
  60. package/agent-assets/docs/guides/connect-a-new-mail-account.md +16 -0
  61. package/agent-assets/docs/guides/explore-with-trace-and-connect.md +6 -0
  62. package/agent-assets/docs/guides/import-knowledge-file.md +11 -0
  63. package/agent-assets/docs/guides/install-and-run.md +20 -4
  64. package/agent-assets/docs/guides/maintain-wiki-health.md +6 -0
  65. package/agent-assets/docs/guides/migrate-machines.md +13 -1
  66. package/agent-assets/docs/guides/multiple-wikis-for-multiple-domains.md +9 -0
  67. package/agent-assets/docs/guides/pause-the-agent.md +12 -4
  68. package/agent-assets/docs/guides/reinstall-cleanly.md +19 -4
  69. package/agent-assets/docs/guides/setup-wizard.md +20 -9
  70. package/agent-assets/docs/guides/switch-default-backend.md +10 -1
  71. package/agent-assets/docs/guides/use-an-existing-obsidian-vault.md +5 -0
  72. package/agent-assets/docs/reference/api.md +29 -1
  73. package/agent-assets/docs/reference/cli-commands.md +22 -3
  74. package/agent-assets/docs/reference/config.md +37 -5
  75. package/agent-assets/docs/reference/disallowed-tools.md +13 -0
  76. package/agent-assets/docs/reference/keyboard-shortcuts.md +13 -0
  77. package/agent-assets/docs/reference/process-keys.md +70 -20
  78. package/agent-assets/docs/reference/skills.md +27 -9
  79. package/agent-assets/docs/troubleshooting/auth-failed.md +7 -2
  80. package/agent-assets/docs/troubleshooting/dashboard-shows-degraded.md +13 -1
  81. package/agent-assets/docs/troubleshooting/fallback-keeps-firing.md +10 -0
  82. package/agent-assets/docs/troubleshooting/messaging-not-pairing.md +11 -0
  83. package/agent-assets/docs/troubleshooting/morning-routine-didnt-run.md +9 -4
  84. package/agent-assets/docs/troubleshooting/observation-not-detected.md +12 -0
  85. package/agent-assets/docs/troubleshooting/quota-exhausted.md +7 -1
  86. package/agent-assets/docs/troubleshooting/wiki-ingest-full-blocked.md +5 -0
  87. package/agent-assets/docs/troubleshooting/wiki-write-failed.md +5 -0
  88. package/agent-assets/optimizer-skills/drift-analysis/SKILL.md +1 -1
  89. package/agent-assets/optimizer-skills/skill-curation/SKILL.md +2 -2
  90. package/agent-assets/skills/agent-actions/SKILL.md +122 -0
  91. package/agent-assets/skills/attach/SKILL.md +1 -2
  92. package/agent-assets/skills/context/SKILL.md +36 -454
  93. package/agent-assets/skills/context/references/api.md +220 -0
  94. package/agent-assets/skills/context/references/required-frontmatter.md +73 -0
  95. package/agent-assets/skills/context/references/snapshot-files.md +103 -0
  96. package/agent-assets/skills/context/seeds/file-responsibilities.seed.json +1 -1
  97. package/agent-assets/skills/docs-search/SKILL.md +13 -13
  98. package/agent-assets/skills/external-services/SKILL.delegated.claude.md +5 -7
  99. package/agent-assets/skills/external-services/SKILL.delegated.codex.md +5 -7
  100. package/agent-assets/skills/external-services/SKILL.delegated.gemini.md +5 -7
  101. package/agent-assets/skills/external-services/SKILL.md +6 -259
  102. package/agent-assets/skills/external-services/SKILL.native.claude.md +1 -2
  103. package/agent-assets/skills/external-services/SKILL.native.codex.md +1 -2
  104. package/agent-assets/skills/external-services/SKILL.native.gemini.md +1 -2
  105. package/agent-assets/skills/external-services/references/calendar-apple.md +97 -0
  106. package/agent-assets/skills/external-services/references/calendar-google.md +72 -0
  107. package/agent-assets/skills/external-services/references/calendar-outlook.md +36 -0
  108. package/agent-assets/skills/external-services/references/github.md +17 -0
  109. package/agent-assets/skills/external-services/references/obsidian.md +49 -0
  110. package/agent-assets/skills/external-services/references/skills-crud.md +27 -0
  111. package/agent-assets/skills/gmail-lifestyle/SKILL.md +224 -0
  112. package/agent-assets/skills/gmail-lifestyle/references/receipts-api.md +93 -0
  113. package/agent-assets/skills/gmail-lifestyle/references/travel-bookings-api.md +75 -0
  114. package/agent-assets/skills/gmail-lifestyle/references/travel-time-api.md +59 -0
  115. package/agent-assets/skills/mail/SKILL.delegated.claude.md +1 -1
  116. package/agent-assets/skills/mail/SKILL.delegated.codex.md +1 -1
  117. package/agent-assets/skills/mail/SKILL.delegated.gemini.md +1 -1
  118. package/agent-assets/skills/mail/SKILL.md +9 -114
  119. package/agent-assets/skills/mail/SKILL.native.claude.md +1 -1
  120. package/agent-assets/skills/mail/SKILL.native.codex.md +1 -1
  121. package/agent-assets/skills/mail/SKILL.native.gemini.md +1 -1
  122. package/agent-assets/skills/mail/references/api.md +108 -0
  123. package/agent-assets/skills/mail/references/examples.md +70 -0
  124. package/agent-assets/skills/mail/references/providers.md +8 -8
  125. package/agent-assets/skills/managed-tasks/SKILL.md +472 -0
  126. package/agent-assets/skills/managed-tasks/references/errors.md +70 -0
  127. package/agent-assets/skills/managed-tasks/references/output-path.md +75 -0
  128. package/agent-assets/skills/managed-tasks/references/recurrence-rule.md +86 -0
  129. package/agent-assets/skills/management-policy/SKILL.md +33 -105
  130. package/agent-assets/skills/management-policy/references/policy-workflow.md +101 -0
  131. package/agent-assets/skills/notify/SKILL.md +6 -78
  132. package/agent-assets/skills/notify/references/priority.md +60 -0
  133. package/agent-assets/skills/notion/SKILL.delegated.claude.md +1 -1
  134. package/agent-assets/skills/notion/SKILL.delegated.codex.md +1 -1
  135. package/agent-assets/skills/notion/SKILL.delegated.gemini.md +1 -1
  136. package/agent-assets/skills/notion/SKILL.md +6 -10
  137. package/agent-assets/skills/notion/SKILL.native.claude.md +1 -2
  138. package/agent-assets/skills/notion/SKILL.native.codex.md +1 -2
  139. package/agent-assets/skills/notion/SKILL.native.gemini.md +1 -2
  140. package/agent-assets/skills/observations/SKILL.md +1 -6
  141. package/agent-assets/skills/project-doc/SKILL.md +1 -5
  142. package/agent-assets/skills/reading/SKILL.md +2 -2
  143. package/agent-assets/skills/roadmap/SKILL.md +37 -135
  144. package/agent-assets/skills/roadmap/references/api.md +100 -0
  145. package/agent-assets/skills/roadmap/references/cross-check.md +73 -0
  146. package/agent-assets/skills/roadmap/references/migration.md +56 -0
  147. package/agent-assets/skills/roadmap/references/preparation-timeline.md +2 -2
  148. package/agent-assets/skills/schedule/SKILL.md +52 -88
  149. package/agent-assets/skills/schedule/references/batch.md +93 -0
  150. package/agent-assets/skills/schedule/references/errors.md +214 -0
  151. package/agent-assets/skills/schedule/references/model-selection.md +96 -0
  152. package/agent-assets/skills/schedule/references/recurrence-rule.md +86 -0
  153. package/agent-assets/skills/schedule/references/recurring.md +185 -0
  154. package/agent-assets/skills/scheduled-managed-task/SKILL.md +13 -15
  155. package/agent-assets/skills/today/SKILL.md +27 -57
  156. package/agent-assets/skills/today/references/agent-plan-lifecycle.md +113 -0
  157. package/agent-assets/skills/user-interview/SKILL.md +12 -59
  158. package/agent-assets/skills/user-interview/references/op-briefing.md +51 -0
  159. package/agent-assets/skills/user-interview/references/op-morning.md +59 -0
  160. package/agent-assets/skills/user-interview/references/sweep-and-fallback.md +1 -1
  161. package/agent-assets/skills/user-profile/SKILL.md +43 -63
  162. package/agent-assets/skills/user-profile/references/character-preferences.md +83 -0
  163. package/agent-assets/skills/user-profile/seeds/topic-files.seed.json +28 -0
  164. package/agent-assets/skills/wiki/wiki-ask/SKILL.md +0 -1
  165. package/agent-assets/skills/wiki/wiki-compile/SKILL.md +0 -1
  166. package/agent-assets/skills/wiki/wiki-connect/SKILL.md +0 -1
  167. package/agent-assets/skills/wiki/wiki-graduate/SKILL.md +0 -1
  168. package/agent-assets/skills/wiki/wiki-ingest/SKILL.md +0 -1
  169. package/agent-assets/skills/wiki/wiki-lint/SKILL.md +0 -1
  170. package/agent-assets/skills/wiki/wiki-trace/SKILL.md +0 -1
  171. package/agent-assets/skills/wiki/wiki-vault-rules/SKILL.md +0 -1
  172. package/agent-assets/system-prompts/routine-fetch-window.md +68 -0
  173. package/agent-assets/system-prompts/skill-index-instruction.md +26 -0
  174. package/agent-assets/task-flows/_partials/calendar-acquire.google_calendar.md +18 -11
  175. package/agent-assets/task-flows/_partials/calendar-acquire.outlook_calendar.md +16 -9
  176. package/agent-assets/task-flows/_partials/capture-user-info.md +24 -0
  177. package/agent-assets/task-flows/_partials/confirm-subflow.md +68 -0
  178. package/agent-assets/task-flows/_partials/dm-intent.long-horizon.md +35 -0
  179. package/agent-assets/task-flows/_partials/dm-intent.project.md +391 -0
  180. package/agent-assets/task-flows/_partials/mail-acquire.gmail.md +20 -11
  181. package/agent-assets/task-flows/_partials/mail-acquire.outlook_mail.md +17 -9
  182. package/agent-assets/task-flows/_partials/notion-acquire.notion.md +18 -12
  183. package/agent-assets/task-flows/knowledge.import.md +1 -1
  184. package/agent-assets/task-flows/message.received.dm.md +13 -15
  185. package/agent-assets/task-flows/message.received.dm_first.md +10 -14
  186. package/agent-assets/task-flows/routine.custom.md +3 -1
  187. package/agent-assets/task-flows/routine.evening_review.md +39 -163
  188. package/agent-assets/task-flows/routine.fetch_window.md +17 -12
  189. package/agent-assets/task-flows/routine.hourly_check.md +16 -8
  190. package/agent-assets/task-flows/routine.hourly_check.triage.md +1 -1
  191. package/agent-assets/task-flows/routine.monthly_review.md +46 -4
  192. package/agent-assets/task-flows/routine.morning_routine_journal.md +113 -0
  193. package/agent-assets/task-flows/routine.morning_routine_today.md +673 -0
  194. package/agent-assets/task-flows/routine.roadmap_refresh.md +60 -15
  195. package/agent-assets/task-flows/routine.user_profile_sweep.md +9 -10
  196. package/agent-assets/task-flows/routine.weekly_review.md +285 -70
  197. package/agent-assets/task-flows/scheduled.dm.md +8 -8
  198. package/agent-assets/task-flows/scheduled.task.md +5 -5
  199. package/agent-assets/task-flows/setup.initial.md +165 -245
  200. package/agent-assets/task-flows/wiki.ingest_url.md +1 -1
  201. package/agent-assets/templates/_manifest.json +7 -7
  202. package/agent-assets/templates/dossiers/_index.md +1 -1
  203. package/agent-assets/templates/rules/journal-format.md +145 -38
  204. package/agent-assets/templates/user/expertise.md +4 -2
  205. package/agent-assets/templates/user/goals.md +4 -2
  206. package/agent-assets/templates/user/people.md +8 -2
  207. package/agent-assets/templates/user/personal.md +4 -2
  208. package/agent-assets/templates/user/work.md +4 -2
  209. package/bin/aitne.mjs +8 -1
  210. package/package.json +4 -4
  211. package/scripts/commands/doctor.mjs +52 -0
  212. package/scripts/commands/run-now.mjs +202 -0
  213. package/scripts/commands/verify.mjs +264 -0
  214. package/agent-assets/docs/features/routines/monthly-review.md +0 -65
  215. package/agent-assets/skills/management-task-modify/SKILL.md +0 -203
  216. package/agent-assets/skills/management-task-register/SKILL.md +0 -330
  217. package/agent-assets/skills/management-task-stop/SKILL.md +0 -166
  218. package/agent-assets/skills/receipts/SKILL.md +0 -134
  219. package/agent-assets/skills/travel/SKILL.md +0 -132
  220. package/agent-assets/skills/travel-time/SKILL.md +0 -158
  221. package/agent-assets/task-flows/routine.morning_routine.md +0 -322
  222. package/agent-assets/task-flows/routine.morning_routine_initial.md +0 -204
@@ -3,7 +3,6 @@ name: external-services
3
3
  description: Load for calendar work (Google Calendar, Outlook Calendar, OR Apple Calendar / iCloud), the user's external Obsidian vault, GitHub, or user-authored Skills management. Mail lives in `mail`; Notion in `notion`; one-shot and recurring scheduling in `schedule`.
4
4
  allowed-tools:
5
5
  - Bash(curl *)
6
- - Bash(jq *)
7
6
  - Read
8
7
  ---
9
8
 
@@ -81,261 +80,23 @@ direct route when not.
81
80
 
82
81
  ---
83
82
 
84
- <!-- service:calendar -->
85
- ## Calendar
86
-
87
- Google Calendar proxy. Operates on the user's primary calendar (configurable via `calendarId` param).
88
-
89
- **Timezone rule**: Always include a TZ offset in `start`/`end` dateTime values (e.g. `-04:00`). All-day events use `YYYY-MM-DD` (no TZ needed).
90
-
91
- **Event status**: GET returns deleted events with `status: "cancelled"` (200, not 404). Always check `status` before acting. The list endpoint automatically excludes cancelled events.
92
-
93
- ### List events
94
- ```bash
95
- curl -s "http://localhost:8321/api/calendar/events?date=today&days=3"
96
- ```
97
-
98
- ### Get event detail
99
- ```bash
100
- curl -s "http://localhost:8321/api/calendar/events/abc123eventid"
101
- ```
102
- **Always GET before PATCH** to see current state and attendees.
103
-
104
- ### Create event (write — Autonomous)
105
- ```bash
106
- curl -s -X POST "http://localhost:8321/api/calendar/events" \
107
- -H 'Content-Type: application/json' \
108
- -d '{"summary": "Team meeting", "start": "2026-04-02T14:00:00-04:00", "end": "2026-04-02T15:00:00-04:00"}'
109
- ```
110
- Optional: `description`, `location`, `reminders`, `recurrence`, `attendees`, `visibility`. All-day: `YYYY-MM-DD`. Attendees: add `?sendUpdates=all` to notify. RRULE: `RRULE:FREQ=WEEKLY;BYDAY=MO,WE,FR`.
111
-
112
- ### Update event (write — Autonomous; commonly on the starter denylist)
113
- ```bash
114
- curl -s -X PATCH "http://localhost:8321/api/calendar/events/abc123" \
115
- -H 'Content-Type: application/json' \
116
- -d '{"start": "2026-04-02T15:00:00-04:00", "end": "2026-04-02T16:00:00-04:00"}'
117
- ```
118
- For recurring events, use the instance ID to update a single occurrence — never PATCH the master.
119
-
120
- **ATTENDEES WARNING**: PATCH with `attendees` **replaces the entire list** — it does NOT append. To add one attendee: (1) GET, (2) copy existing, (3) add new, (4) PATCH full list.
121
-
122
- ### Delete event (write — Autonomous; default starter denylist denies it)
123
- ```bash
124
- curl -s -X DELETE "http://localhost:8321/api/calendar/events/abc123"
125
- ```
126
- Add `?sendUpdates=all` to notify attendees. Do NOT PATCH a cancelled event.
127
-
128
- ### List calendars
129
- ```bash
130
- curl -s http://localhost:8321/api/calendar/calendars
131
- ```
132
-
133
- ### Free/busy query
134
- ```bash
135
- curl -s -X POST http://localhost:8321/api/calendar/freebusy \
136
- -H 'Content-Type: application/json' \
137
- -d '{"timeMin": "2026-04-11T09:00:00-04:00", "timeMax": "2026-04-11T18:00:00-04:00"}'
138
- ```
139
-
140
- ### Calendar error envelope (direct mode)
141
-
142
- | HTTP | `error` | What it means / what to do |
143
- |---|---|---|
144
- | 400 | `validation_error` | Bad request shape (e.g. missing `start`/`end`, malformed RRULE). Fix and retry. |
145
- | 404 | `not_found` | Event id unknown or already deleted. Re-list before retrying. |
146
- | 410 | `integration_delegated` | Calendar flipped to delegated mode mid-session. This skill body is direct-only — re-read `integrations.md` and use `POST /api/integrations/google_calendar/exec` (cross-backend task mode) or your session backend's native Calendar MCP (the same-backend variant) instead. |
147
- | 502 | `calendar_error` | Upstream Google API error — `message` carries the API's text. Surface verbatim; do not retry unless clearly transient. |
148
- | 503 | `calendar_not_configured` | Direct OAuth credentials are missing or the user has disabled Calendar in settings. Tell the user and stop. |
149
- <!-- /service:calendar -->
83
+ {{> ref:calendar-google }}
150
84
 
151
85
  ---
152
86
 
153
- <!-- service:outlook-calendar -->
154
- ## Outlook Calendar (Microsoft Graph)
155
-
156
- Use this section **only when `rules/management.md` Schedule = Outlook Calendar**. The provider-routing table at the top of this skill is non-negotiable.
157
-
158
- v1 is **read-only and on-demand** — there is no Outlook calendar poller, so `schedule.approaching` events do not fire for Outlook calendars (the user's own Outlook clients fill that gap). Write surfaces (create / update / delete) are deferred. If the user asks the agent to schedule or change an Outlook event, tell them you can read the calendar but must defer the write to them.
159
-
160
- OAuth is **shared with Outlook Mail** via the same MSAL cache row (`mail:outlook:<accountId>`) — if Outlook Mail is configured `direct` and authenticated, calendar reads succeed with no second consent.
161
-
162
- ### List events
163
- ```bash
164
- curl -s "http://localhost:8321/api/calendar/outlook/events?date=today&days=3"
165
- ```
166
- Same query params as Google (`date`: `YYYY-MM-DD` or `today`; `days`: 1–90; optional `calendarId`). Returns `{ events: [...], accountId }`.
167
-
168
- ### List calendars
169
- ```bash
170
- curl -s http://localhost:8321/api/calendar/outlook/calendars
171
- ```
172
- Returns `{ calendars: [...], accountId }`. The user's primary calendar is marked `primary: true`.
173
-
174
- ### Outlook Calendar error envelope
175
-
176
- | HTTP | `error` | What it means / what to do |
177
- |---|---|---|
178
- | 400 | bad query | Malformed `date` or `days` value. |
179
- | 502 | `calendar_error` | Upstream Microsoft Graph error — `message` carries wire text. |
180
- | 503 | `outlook_not_configured` | No authenticated Outlook account. Direct OAuth credentials missing. |
181
- | 503 | `outlook_calendar_disabled` | The user toggled Outlook Calendar off in Settings → Calendar. Tell the user and stop. |
182
- <!-- /service:outlook-calendar -->
87
+ {{> ref:calendar-outlook }}
183
88
 
184
89
  ---
185
90
 
186
- <!-- service:apple-calendar -->
187
- ## Apple Calendar (iCloud CalDAV)
188
-
189
- Use this section **only when `rules/management.md` Schedule = Apple Calendar**. The provider-routing table at the top of this skill is non-negotiable.
190
-
191
- The route shape mirrors `/api/calendar/*` so prose patterns transfer: list → get → patch / create / delete. Differences are flagged below.
192
-
193
- ### Probe configuration before first use
194
- ```bash
195
- curl -s http://localhost:8321/api/apple-calendar/status
196
- # → { "configured": bool, "available": bool }
197
- ```
198
- - `configured: false` → user has not entered Apple ID + app-specific password yet. Tell the user to open the dashboard's Apple Calendar card (Connections page) and paste a password from `appleid.apple.com` → Sign-In and Security → App-Specific Passwords. **Do not try to read or write events** until `available: true`.
199
- - `configured: true, available: false` → credentials are stored but iCloud rejected the last connection. Surface verbatim; common cause is the user revoked the app-specific password.
200
-
201
- ### List events
202
- ```bash
203
- curl -s "http://localhost:8321/api/apple-calendar/events?date=today&days=3"
204
- ```
205
- Same query params as Google: `date` (`YYYY-MM-DD` or `today`), `days` (max 90). Returns `{ events: [...] }` with the same JSON shape used by the Google route — `id`, `summary`, `start`, `end`, `location`, `description`, `allDay`, `status`, plus two Apple-specific fields:
206
- - `recurring` (bool) — true for any event in a recurring series.
207
- - `recurrenceId` (string|null) — populated for an expanded instance of a series.
208
-
209
- For a recurring instance the `id` is `<UID>__<RECURRENCE-ID>` so you can address a specific occurrence.
210
-
211
- **Timezones**: dateTime values are emitted in UTC (`Z` suffix). Convert to the user's local timezone before showing them.
212
-
213
- ### Get event detail
214
- ```bash
215
- curl -s "http://localhost:8321/api/apple-calendar/events/<id>"
216
- ```
217
- Always GET before PATCH so you see the current summary/start/end.
218
-
219
- ### Create event (write — Autonomous)
220
- ```bash
221
- curl -s -X POST http://localhost:8321/api/apple-calendar/events \
222
- -H 'Content-Type: application/json' \
223
- -d '{"summary": "Team meeting", "start": "2026-04-26T14:00:00+09:00", "end": "2026-04-26T15:00:00+09:00"}'
224
- ```
225
- Optional: `description`, `location`. **[Apple only]** `attendees`, `reminders`, `recurrence`, `visibility` from the Google shape are accepted by the Zod schema but are silently dropped — iCloud invitations and reminder defaults belong to the user's Apple ID and the agent should not author them. If a user asks for those, tell them and stop.
226
-
227
- ### Update event (write — Autonomous)
228
- ```bash
229
- curl -s -X PATCH http://localhost:8321/api/apple-calendar/events/<id> \
230
- -H 'Content-Type: application/json' \
231
- -d '{"start": "2026-04-26T15:00:00+09:00", "end": "2026-04-26T16:00:00+09:00"}'
232
- ```
233
-
234
- **[Apple only] Recurring-event editing semantics — read before writing**
235
- - A composite id (one whose suffix matches `__YYYY-MM-DD…`) addresses **one occurrence** of a series. PATCH/DELETE on it returns `501 recurring_instance_unsupported`. To move a single occurrence the user must edit it from Calendar.app.
236
- - A bare id whose GET returned `recurring: true` is the **series master**. PATCH on the master shifts the **entire series** (every future occurrence moves), and DELETE removes the entire series. Confirm with the user that they intend a series-level edit before issuing the call — agents have historically read "PATCH this event's start" as a single-instance reschedule, which is wrong here.
237
- - A bare id with `recurring: false` is a normal one-off event — PATCH/DELETE behave as usual.
238
- - `summary`, `start`, and `end` may be updated independently. Toggling all-day-ness (`YYYY-MM-DD` ↔ `…T…Z`) requires providing **both** `start` and `end` in the same PATCH; the codec rejects partial all-day toggles with `400 validation_error`.
239
- - Time strings must include a TZ offset (`Z` or `±HH:MM`); naked ISO without offset returns `400 validation_error` — do not interpret a user-stated time as local without an explicit offset.
240
-
241
- ### Delete event (write — Autonomous)
242
- ```bash
243
- curl -s -X DELETE http://localhost:8321/api/apple-calendar/events/<id>
244
- ```
245
- Same recurring semantics as PATCH (see the rules block above).
246
-
247
- ### List calendars
248
- ```bash
249
- curl -s http://localhost:8321/api/apple-calendar/calendars
250
- # → { "calendars": [{ id, summary, description, primary }, ...] }
251
- ```
252
- The `id` is an opaque CalDAV URL. The user's primary calendar is marked `primary: true`. To change which calendar create/list reads, see the dashboard Apple Calendar card.
253
-
254
- ### Free/busy query
255
- ```bash
256
- curl -s -X POST http://localhost:8321/api/apple-calendar/freebusy \
257
- -H 'Content-Type: application/json' \
258
- -d '{"timeMin": "2026-04-26T09:00:00Z", "timeMax": "2026-04-26T18:00:00Z"}'
259
- ```
260
- **[Apple only]** Free-busy is derived from `listEvents` — events with `status: "cancelled"` are excluded. `calendarIds` is ignored (the primary calendar is the only target).
261
-
262
- ### Apple Calendar error envelope
263
-
264
- | HTTP | `error` | What it means / what to do |
265
- |---|---|---|
266
- | 400 | `validation_error` | Bad request shape. Fix and retry. |
267
- | 401 | `auth_failed` | iCloud rejected the credentials. Tell the user to refresh the app-specific password in the dashboard. |
268
- | 404 | `not_found` | Event id unknown or already deleted. Re-list before retrying. |
269
- | 501 | `recurring_instance_unsupported` | The id targets a single occurrence of a recurring series — see the PATCH/DELETE notes above. |
270
- | 502 | `apple_calendar_error` | Upstream iCloud / CalDAV error. `message` carries the wire text. |
271
- | 503 | `apple_calendar_not_configured` | Credentials missing or last connection failed. Run the status probe above. |
272
-
273
- ### Known gap: no proactive notifications
274
-
275
- The hourly polling pivot (`schedule.approaching` events, observation deltas) only fires for Google Calendar today. With Apple Calendar selected, on-demand DM queries work but the agent will not proactively warn about an imminent event — the user's own iOS / macOS Calendar.app notifications fill that gap.
276
- <!-- /service:apple-calendar -->
91
+ {{> ref:calendar-apple }}
277
92
 
278
93
  ---
279
94
 
280
- <!-- service:obsidian -->
281
- ## Obsidian (external vault)
282
-
283
- **Scope**: this skill targets a **separate** Obsidian vault the user maintains
284
- alongside this app — e.g. a personal knowledge base. It is **not** the agent's
285
- own primary management store. The agent's primary files (`today.md`,
286
- `roadmap.md`, `projects/`, `rules/`, `routines/`, `user/`, `agent/`, …) live
287
- in the primary vault and are reached via `/api/context/*` (see the `context`
288
- skill). **Never** use this skill to read or write the primary vault.
289
-
290
- Use this skill when the user asks the agent to look up, append to, or create
291
- notes inside their external knowledge vault — never for the agent's own
292
- working state.
293
-
294
- Output language: follow `<output_language_policy>` (Policy C — body
295
- and any new headings the agent creates are in `<settings primary_language>`).
296
- Preserve verbatim any path / file-name patterns the user has established.
297
-
298
- Full CRUD over the external vault. Requires the Obsidian app running (the
299
- CLI proxies through it). Omit `.md` extension from paths. All writes are
300
- Autonomous; the daemon does not DM the owner before/after the call. Call
301
- `POST /api/notify` yourself when the user would want to know.
302
-
303
- ```bash
304
- curl -s http://localhost:8321/api/obsidian/status # external vault availability
305
- curl -s "http://localhost:8321/api/obsidian/search?q=meeting+notes&limit=10" # search external vault
306
- curl -s http://localhost:8321/api/obsidian/notes/Daily%20Notes/2026-04-06 # read external note
307
- curl -s -X POST http://localhost:8321/api/obsidian/notes \
308
- -H 'Content-Type: application/json' \
309
- -d '{"name": "Meeting Notes 2026-04-02", "content": "# Meeting\n..."}' # create external note (fails if exists)
310
- curl -s -X PUT http://localhost:8321/api/obsidian/notes/Projects/ProjectA \
311
- -H 'Content-Type: application/json' -d '{"content": "# Full body"}' # create-or-overwrite external note
312
- curl -s -X PATCH http://localhost:8321/api/obsidian/notes \
313
- -H 'Content-Type: application/json' \
314
- -d '{"file": "Meeting Notes 2026-04-02", "content": "\n- Action item"}' # append to external note
315
- curl -s -X PATCH http://localhost:8321/api/obsidian/daily \
316
- -H 'Content-Type: application/json' -d '{"content": "- [ ] Follow up"}' # append to external daily note
317
- curl -s -X DELETE http://localhost:8321/api/obsidian/notes/Projects/Old # delete from external vault (moves to trash)
318
- ```
319
- **Endpoint choice**: Read → GET, Create-only → POST, Edit → PUT, Append → PATCH.
320
-
321
- If the user's request is really about the agent's own state (today, roadmap,
322
- projects, journal, rules, routines, user profile), switch to the `context`
323
- skill and the `/api/context/*` endpoints instead.
324
- <!-- /service:obsidian -->
95
+ {{> ref:obsidian }}
325
96
 
326
97
  ---
327
98
 
328
- <!-- service:github -->
329
- ## GitHub
330
-
331
- ```bash
332
- curl -s http://localhost:8321/api/github/repos # list watched repos
333
- curl -s "http://localhost:8321/api/github/pulls?owner=user&repo=repo&state=open" # list PRs
334
- curl -s -X POST http://localhost:8321/api/github/pulls/comment \
335
- -H 'Content-Type: application/json' \
336
- -d '{"owner": "user", "repo": "repo", "pull_number": 42, "comment": "LGTM"}' # comment — Autonomous
337
- ```
338
- <!-- /service:github -->
99
+ {{> ref:github }}
339
100
 
340
101
  ---
341
102
 
@@ -360,18 +121,4 @@ flows.
360
121
 
361
122
  ---
362
123
 
363
- ## Skills Management
364
-
365
- User-authored skills: `~/.personal-agent/skills/{slug}/SKILL.md`. Built-in skills are read-only (403). Slug: lowercase kebab-case `[a-z0-9][a-z0-9-]*`, 1–64 chars.
366
-
367
- ```bash
368
- curl -s http://localhost:8321/api/skills # list all
369
- curl -s http://localhost:8321/api/skills/todo-digest # read one
370
- curl -s -X POST http://localhost:8321/api/skills \
371
- -H 'Content-Type: application/json' \
372
- -d '{"name": "todo-digest", "description": "Summarize today.md", "content": "# TODO Digest\n...", "allowedTools": ["Bash(curl *)", "Read"]}'
373
- curl -s -X PUT http://localhost:8321/api/skills/todo-digest \
374
- -H 'Content-Type: application/json' -d '{"description": "New description"}' # update
375
- curl -s -X DELETE http://localhost:8321/api/skills/todo-digest # delete
376
- ```
377
- Always `GET /api/skills` before creating (check name collisions). **Omit frontmatter** from `content` — the API injects it.
124
+ {{> ref:skills-crud }}
@@ -1,9 +1,8 @@
1
1
  ---
2
2
  name: external-services
3
- description: Load when an external-services surface is in scope (Google Calendar / Obsidian / GitHub / Skills CRUD / scheduling) and Google Calendar is in native mode bound to Claude (`nativeBackend === "claude"`). Calendar runs through Claude's hosted Calendar connector directly; the daemon does not proxy Calendar. Other surfaces (Apple/Outlook Calendar, Obsidian, GitHub, scheduling, Skills CRUD) keep their direct routes.
3
+ description: Load when an external-services surface is in scope and Google Calendar is in native mode bound to Claude (`nativeBackend === "claude"`). Calendar runs via Claude's hosted Calendar connector; daemon does not proxy. Obsidian, GitHub, scheduling, Skills CRUD keep direct routes.
4
4
  allowed-tools:
5
5
  - Bash(curl *)
6
- - Bash(jq *)
7
6
  - Read
8
7
  ---
9
8
 
@@ -1,9 +1,8 @@
1
1
  ---
2
2
  name: external-services
3
- description: Load when an external-services surface is in scope (Google Calendar / Obsidian / GitHub / Skills CRUD / scheduling) and Google Calendar is in native mode bound to Codex (`nativeBackend === "codex"`). Calendar runs through the in-session Calendar connector your Codex harness exposes directly; the daemon does not proxy Calendar. Other surfaces (Apple/Outlook Calendar, Obsidian, GitHub, scheduling, Skills CRUD) keep their direct routes.
3
+ description: Load when an external-services surface is in scope and Google Calendar is in native mode bound to Codex (`nativeBackend === "codex"`). Calendar runs via the Codex Calendar connector; daemon does not proxy. Obsidian, GitHub, scheduling, Skills CRUD keep direct routes.
4
4
  allowed-tools:
5
5
  - Bash(curl *)
6
- - Bash(jq *)
7
6
  - Read
8
7
  ---
9
8
 
@@ -1,9 +1,8 @@
1
1
  ---
2
2
  name: external-services
3
- description: Load when an external-services surface is in scope (Google Calendar / Obsidian / GitHub / Skills CRUD / scheduling) and Google Calendar is in native mode bound to Gemini (`nativeBackend === "gemini"`). Calendar runs through the in-session Calendar connector your Gemini harness exposes directly; the daemon does not proxy Calendar. Other surfaces (Apple/Outlook Calendar, Obsidian, GitHub, scheduling, Skills CRUD) keep their direct routes.
3
+ description: Load when an external-services surface is in scope and Google Calendar is in native mode bound to Gemini (`nativeBackend === "gemini"`). Calendar runs via the Gemini Calendar connector; daemon does not proxy. Obsidian, GitHub, scheduling, Skills CRUD keep direct routes.
4
4
  allowed-tools:
5
5
  - Bash(curl *)
6
- - Bash(jq *)
7
6
  - Read
8
7
  ---
9
8
 
@@ -0,0 +1,97 @@
1
+ ---
2
+ kind: reference
3
+ name: calendar-apple
4
+ description: Apple Calendar (iCloud CalDAV) reference — list/get/create/update/delete with recurring-instance gotchas, app-specific-password setup probe, no proactive notifications. Stripped when `apple_calendar` is not configured.
5
+ ---
6
+
7
+ <!-- service:apple-calendar -->
8
+ ## Apple Calendar (iCloud CalDAV)
9
+
10
+ Use this section **only when `rules/management.md` Schedule = Apple Calendar**. The provider-routing table at the top of this skill is non-negotiable.
11
+
12
+ The route shape mirrors `/api/calendar/*` so prose patterns transfer: list → get → patch / create / delete. Differences are flagged below.
13
+
14
+ ### Probe configuration before first use
15
+ ```bash
16
+ curl -s http://localhost:8321/api/apple-calendar/status
17
+ # → { "configured": bool, "available": bool }
18
+ ```
19
+ - `configured: false` → user has not entered Apple ID + app-specific password yet. Tell the user to open the dashboard's Apple Calendar card (Connections page) and paste a password from `appleid.apple.com` → Sign-In and Security → App-Specific Passwords. **Do not try to read or write events** until `available: true`.
20
+ - `configured: true, available: false` → credentials are stored but iCloud rejected the last connection. Surface verbatim; common cause is the user revoked the app-specific password.
21
+
22
+ ### List events
23
+ ```bash
24
+ curl -s "http://localhost:8321/api/apple-calendar/events?date=today&days=3"
25
+ ```
26
+ Same query params as Google: `date` (`YYYY-MM-DD` or `today`), `days` (max 90). Returns `{ events: [...] }` with the same JSON shape used by the Google route — `id`, `summary`, `start`, `end`, `location`, `description`, `allDay`, `status`, plus two Apple-specific fields:
27
+ - `recurring` (bool) — true for any event in a recurring series.
28
+ - `recurrenceId` (string|null) — populated for an expanded instance of a series.
29
+
30
+ For a recurring instance the `id` is `<UID>__<RECURRENCE-ID>` so you can address a specific occurrence.
31
+
32
+ **Timezones**: dateTime values are emitted in UTC (`Z` suffix). Convert to the user's local timezone before showing them.
33
+
34
+ ### Get event detail
35
+ ```bash
36
+ curl -s "http://localhost:8321/api/apple-calendar/events/<id>"
37
+ ```
38
+ Always GET before PATCH so you see the current summary/start/end.
39
+
40
+ ### Create event (write — Autonomous)
41
+ ```bash
42
+ curl -s -X POST http://localhost:8321/api/apple-calendar/events \
43
+ -H 'Content-Type: application/json' \
44
+ -d '{"summary": "Team meeting", "start": "2026-04-26T14:00:00+09:00", "end": "2026-04-26T15:00:00+09:00"}'
45
+ ```
46
+ Optional: `description`, `location`. **[Apple only]** `attendees`, `reminders`, `recurrence`, `visibility` from the Google shape are accepted by the Zod schema but are silently dropped — iCloud invitations and reminder defaults belong to the user's Apple ID and the agent should not author them. If a user asks for those, tell them and stop.
47
+
48
+ ### Update event (write — Autonomous)
49
+ ```bash
50
+ curl -s -X PATCH http://localhost:8321/api/apple-calendar/events/<id> \
51
+ -H 'Content-Type: application/json' \
52
+ -d '{"start": "2026-04-26T15:00:00+09:00", "end": "2026-04-26T16:00:00+09:00"}'
53
+ ```
54
+
55
+ **[Apple only] Recurring-event editing semantics — read before writing**
56
+ - A composite id (one whose suffix matches `__YYYY-MM-DD…`) addresses **one occurrence** of a series. PATCH/DELETE on it returns `501 recurring_instance_unsupported`. To move a single occurrence the user must edit it from Calendar.app.
57
+ - A bare id whose GET returned `recurring: true` is the **series master**. PATCH on the master shifts the **entire series** (every future occurrence moves), and DELETE removes the entire series. Confirm with the user that they intend a series-level edit before issuing the call — agents have historically read "PATCH this event's start" as a single-instance reschedule, which is wrong here.
58
+ - A bare id with `recurring: false` is a normal one-off event — PATCH/DELETE behave as usual.
59
+ - `summary`, `start`, and `end` may be updated independently. Toggling all-day-ness (`YYYY-MM-DD` ↔ `…T…Z`) requires providing **both** `start` and `end` in the same PATCH; the codec rejects partial all-day toggles with `400 validation_error`.
60
+ - Time strings must include a TZ offset (`Z` or `±HH:MM`); naked ISO without offset returns `400 validation_error` — do not interpret a user-stated time as local without an explicit offset.
61
+
62
+ ### Delete event (write — Autonomous)
63
+ ```bash
64
+ curl -s -X DELETE http://localhost:8321/api/apple-calendar/events/<id>
65
+ ```
66
+ Same recurring semantics as PATCH (see the rules block above).
67
+
68
+ ### List calendars
69
+ ```bash
70
+ curl -s http://localhost:8321/api/apple-calendar/calendars
71
+ # → { "calendars": [{ id, summary, description, primary }, ...] }
72
+ ```
73
+ The `id` is an opaque CalDAV URL. The user's primary calendar is marked `primary: true`. To change which calendar create/list reads, see the dashboard Apple Calendar card.
74
+
75
+ ### Free/busy query
76
+ ```bash
77
+ curl -s -X POST http://localhost:8321/api/apple-calendar/freebusy \
78
+ -H 'Content-Type: application/json' \
79
+ -d '{"timeMin": "2026-04-26T09:00:00Z", "timeMax": "2026-04-26T18:00:00Z"}'
80
+ ```
81
+ **[Apple only]** Free-busy is derived from `listEvents` — events with `status: "cancelled"` are excluded. `calendarIds` is ignored (the primary calendar is the only target).
82
+
83
+ ### Apple Calendar error envelope
84
+
85
+ | HTTP | `error` | What it means / what to do |
86
+ |---|---|---|
87
+ | 400 | `validation_error` | Bad request shape. Fix and retry. |
88
+ | 401 | `auth_failed` | iCloud rejected the credentials. Tell the user to refresh the app-specific password in the dashboard. |
89
+ | 404 | `not_found` | Event id unknown or already deleted. Re-list before retrying. |
90
+ | 501 | `recurring_instance_unsupported` | The id targets a single occurrence of a recurring series — see the PATCH/DELETE notes above. |
91
+ | 502 | `apple_calendar_error` | Upstream iCloud / CalDAV error. `message` carries the wire text. |
92
+ | 503 | `apple_calendar_not_configured` | Credentials missing or last connection failed. Run the status probe above. |
93
+
94
+ ### Known gap: no proactive notifications
95
+
96
+ The hourly polling pivot (`schedule.approaching` events, observation deltas) only fires for Google Calendar today. With Apple Calendar selected, on-demand DM queries work but the agent will not proactively warn about an imminent event — the user's own iOS / macOS Calendar.app notifications fill that gap.
97
+ <!-- /service:apple-calendar -->
@@ -0,0 +1,72 @@
1
+ ---
2
+ kind: reference
3
+ name: calendar-google
4
+ description: Google Calendar direct-mode reference — list/get/create/update/delete events, list calendars, free-busy. ATTENDEES PATCH replaces the whole list. Stripped by the integration-mode filter when `google_calendar !== "direct"`.
5
+ ---
6
+
7
+ <!-- service:calendar -->
8
+ ## Calendar
9
+
10
+ Google Calendar proxy. Operates on the user's primary calendar (configurable via `calendarId` param).
11
+
12
+ **Timezone rule**: Always include a TZ offset in `start`/`end` dateTime values (e.g. `-04:00`). All-day events use `YYYY-MM-DD` (no TZ needed).
13
+
14
+ **Event status**: GET returns deleted events with `status: "cancelled"` (200, not 404). Always check `status` before acting. The list endpoint automatically excludes cancelled events.
15
+
16
+ ### List events
17
+ ```bash
18
+ curl -s "http://localhost:8321/api/calendar/events?date=today&days=3"
19
+ ```
20
+
21
+ ### Get event detail
22
+ ```bash
23
+ curl -s "http://localhost:8321/api/calendar/events/abc123eventid"
24
+ ```
25
+ **Always GET before PATCH** to see current state and attendees.
26
+
27
+ ### Create event (write — Autonomous)
28
+ ```bash
29
+ curl -s -X POST "http://localhost:8321/api/calendar/events" \
30
+ -H 'Content-Type: application/json' \
31
+ -d '{"summary": "Team meeting", "start": "2026-04-02T14:00:00-04:00", "end": "2026-04-02T15:00:00-04:00"}'
32
+ ```
33
+ Optional: `description`, `location`, `reminders`, `recurrence`, `attendees`, `visibility`. All-day: `YYYY-MM-DD`. Attendees: add `?sendUpdates=all` to notify. RRULE: `RRULE:FREQ=WEEKLY;BYDAY=MO,WE,FR`.
34
+
35
+ ### Update event (write — Autonomous; commonly on the starter denylist)
36
+ ```bash
37
+ curl -s -X PATCH "http://localhost:8321/api/calendar/events/abc123" \
38
+ -H 'Content-Type: application/json' \
39
+ -d '{"start": "2026-04-02T15:00:00-04:00", "end": "2026-04-02T16:00:00-04:00"}'
40
+ ```
41
+ For recurring events, use the instance ID to update a single occurrence — never PATCH the master.
42
+
43
+ **ATTENDEES WARNING**: PATCH with `attendees` **replaces the entire list** — it does NOT append. To add one attendee: (1) GET, (2) copy existing, (3) add new, (4) PATCH full list.
44
+
45
+ ### Delete event (write — Autonomous; default starter denylist denies it)
46
+ ```bash
47
+ curl -s -X DELETE "http://localhost:8321/api/calendar/events/abc123"
48
+ ```
49
+ Add `?sendUpdates=all` to notify attendees. Do NOT PATCH a cancelled event.
50
+
51
+ ### List calendars
52
+ ```bash
53
+ curl -s http://localhost:8321/api/calendar/calendars
54
+ ```
55
+
56
+ ### Free/busy query
57
+ ```bash
58
+ curl -s -X POST http://localhost:8321/api/calendar/freebusy \
59
+ -H 'Content-Type: application/json' \
60
+ -d '{"timeMin": "2026-04-11T09:00:00-04:00", "timeMax": "2026-04-11T18:00:00-04:00"}'
61
+ ```
62
+
63
+ ### Calendar error envelope (direct mode)
64
+
65
+ | HTTP | `error` | What it means / what to do |
66
+ |---|---|---|
67
+ | 400 | `validation_error` | Bad request shape (e.g. missing `start`/`end`, malformed RRULE). Fix and retry. |
68
+ | 404 | `not_found` | Event id unknown or already deleted. Re-list before retrying. |
69
+ | 410 | `integration_delegated` | Calendar flipped to delegated mode mid-session. This skill body is direct-only — re-read `integrations.md` and use `POST /api/integrations/google_calendar/exec` (cross-backend task mode) or your session backend's native Calendar MCP (the same-backend variant) instead. |
70
+ | 502 | `calendar_error` | Upstream Google API error — `message` carries the API's text. Surface verbatim; do not retry unless clearly transient. |
71
+ | 503 | `calendar_not_configured` | Direct OAuth credentials are missing or the user has disabled Calendar in settings. Tell the user and stop. |
72
+ <!-- /service:calendar -->
@@ -0,0 +1,36 @@
1
+ ---
2
+ kind: reference
3
+ name: calendar-outlook
4
+ description: Outlook Calendar reference (Microsoft Graph) — read-only on-demand. Same query shape as Google. Stripped when `outlook_calendar` is not configured.
5
+ ---
6
+
7
+ <!-- service:outlook-calendar -->
8
+ ## Outlook Calendar (Microsoft Graph)
9
+
10
+ Use this section **only when `rules/management.md` Schedule = Outlook Calendar**. The provider-routing table at the top of this skill is non-negotiable.
11
+
12
+ v1 is **read-only and on-demand** — there is no Outlook calendar poller, so `schedule.approaching` events do not fire for Outlook calendars (the user's own Outlook clients fill that gap). Write surfaces (create / update / delete) are deferred. If the user asks the agent to schedule or change an Outlook event, tell them you can read the calendar but must defer the write to them.
13
+
14
+ OAuth is **shared with Outlook Mail** via the same MSAL cache row (`mail:outlook:<accountId>`) — if Outlook Mail is configured `direct` and authenticated, calendar reads succeed with no second consent.
15
+
16
+ ### List events
17
+ ```bash
18
+ curl -s "http://localhost:8321/api/calendar/outlook/events?date=today&days=3"
19
+ ```
20
+ Same query params as Google (`date`: `YYYY-MM-DD` or `today`; `days`: 1–90; optional `calendarId`). Returns `{ events: [...], accountId }`.
21
+
22
+ ### List calendars
23
+ ```bash
24
+ curl -s http://localhost:8321/api/calendar/outlook/calendars
25
+ ```
26
+ Returns `{ calendars: [...], accountId }`. The user's primary calendar is marked `primary: true`.
27
+
28
+ ### Outlook Calendar error envelope
29
+
30
+ | HTTP | `error` | What it means / what to do |
31
+ |---|---|---|
32
+ | 400 | bad query | Malformed `date` or `days` value. |
33
+ | 502 | `calendar_error` | Upstream Microsoft Graph error — `message` carries wire text. |
34
+ | 503 | `outlook_not_configured` | No authenticated Outlook account. Direct OAuth credentials missing. |
35
+ | 503 | `outlook_calendar_disabled` | The user toggled Outlook Calendar off in Settings → Calendar. Tell the user and stop. |
36
+ <!-- /service:outlook-calendar -->
@@ -0,0 +1,17 @@
1
+ ---
2
+ kind: reference
3
+ name: github
4
+ description: GitHub direct-mode reference — list repos, list PRs, comment on a PR. Autonomous tier. Stripped when `github` is not configured.
5
+ ---
6
+
7
+ <!-- service:github -->
8
+ ## GitHub
9
+
10
+ ```bash
11
+ curl -s http://localhost:8321/api/github/repos # list watched repos
12
+ curl -s "http://localhost:8321/api/github/pulls?owner=user&repo=repo&state=open" # list PRs
13
+ curl -s -X POST http://localhost:8321/api/github/pulls/comment \
14
+ -H 'Content-Type: application/json' \
15
+ -d '{"owner": "user", "repo": "repo", "pull_number": 42, "comment": "LGTM"}' # comment — Autonomous
16
+ ```
17
+ <!-- /service:github -->
@@ -0,0 +1,49 @@
1
+ ---
2
+ kind: reference
3
+ name: obsidian
4
+ description: External Obsidian vault CRUD — separate from the agent's primary management vault. Routed via /api/obsidian/*. Stripped when `obsidian` is not configured.
5
+ ---
6
+
7
+ <!-- service:obsidian -->
8
+ ## Obsidian (external vault)
9
+
10
+ **Scope**: this skill targets a **separate** Obsidian vault the user maintains
11
+ alongside this app — e.g. a personal knowledge base. It is **not** the agent's
12
+ own primary management store. The agent's primary files (`today.md`,
13
+ `roadmap.md`, `projects/`, `rules/`, `routines/`, `user/`, `agent/`, …) live
14
+ in the primary vault and are reached via `/api/context/*` (see the `context`
15
+ skill). **Never** use this skill to read or write the primary vault.
16
+
17
+ Use this skill when the user asks the agent to look up, append to, or create
18
+ notes inside their external knowledge vault — never for the agent's own
19
+ working state.
20
+
21
+ Output language: external-vault writes are Policy C — see `<output_language_policy>`. Preserve verbatim any path / file-name patterns the user has established.
22
+
23
+ Full CRUD over the external vault. Requires the Obsidian app running (the
24
+ CLI proxies through it). Omit `.md` extension from paths. All writes are
25
+ Autonomous; the daemon does not DM the owner before/after the call. Call
26
+ `POST /api/notify` yourself when the user would want to know.
27
+
28
+ ```bash
29
+ curl -s http://localhost:8321/api/obsidian/status # external vault availability
30
+ curl -s "http://localhost:8321/api/obsidian/search?q=meeting+notes&limit=10" # search external vault
31
+ curl -s http://localhost:8321/api/obsidian/notes/Daily%20Notes/2026-04-06 # read external note
32
+ curl -s -X POST http://localhost:8321/api/obsidian/notes \
33
+ -H 'Content-Type: application/json' \
34
+ -d '{"name": "Meeting Notes 2026-04-02", "content": "# Meeting\n..."}' # create external note (fails if exists)
35
+ curl -s -X PUT http://localhost:8321/api/obsidian/notes/Projects/ProjectA \
36
+ -H 'Content-Type: application/json' -d '{"content": "# Full body"}' # create-or-overwrite external note
37
+ curl -s -X PATCH http://localhost:8321/api/obsidian/notes \
38
+ -H 'Content-Type: application/json' \
39
+ -d '{"file": "Meeting Notes 2026-04-02", "content": "\n- Action item"}' # append to external note
40
+ curl -s -X PATCH http://localhost:8321/api/obsidian/daily \
41
+ -H 'Content-Type: application/json' -d '{"content": "- [ ] Follow up"}' # append to external daily note
42
+ curl -s -X DELETE http://localhost:8321/api/obsidian/notes/Projects/Old # delete from external vault (moves to trash)
43
+ ```
44
+ **Endpoint choice**: Read → GET, Create-only → POST, Edit → PUT, Append → PATCH.
45
+
46
+ If the user's request is really about the agent's own state (today, roadmap,
47
+ projects, journal, rules, routines, user profile), switch to the `context`
48
+ skill and the `/api/context/*` endpoints instead.
49
+ <!-- /service:obsidian -->
@@ -0,0 +1,27 @@
1
+ ---
2
+ kind: reference
3
+ name: skills-crud
4
+ description: Dashboard-shaped CRUD for user-authored skills under ~/.personal-agent/skills/. Built-in skills are read-only (403).
5
+ ---
6
+
7
+ ## Skills Management
8
+
9
+ User-authored skills: `~/.personal-agent/skills/{slug}/SKILL.md`. Built-in skills are read-only (403). Slug: lowercase kebab-case `[a-z0-9][a-z0-9-]*`, 1–64 chars.
10
+
11
+ ```bash
12
+ curl -s http://localhost:8321/api/skills # list all
13
+ curl -s http://localhost:8321/api/skills/todo-digest # read one
14
+ curl -s -X POST http://localhost:8321/api/skills \
15
+ -H 'Content-Type: application/json' \
16
+ -d '{"name": "todo-digest", "description": "Summarize today.md", "content": "# TODO Digest\n...", "allowedTools": ["Bash(curl *)", "Read"]}'
17
+ curl -s -X PUT http://localhost:8321/api/skills/todo-digest \
18
+ -H 'Content-Type: application/json' -d '{"description": "New description"}' # update
19
+ curl -s -X DELETE http://localhost:8321/api/skills/todo-digest # delete
20
+ ```
21
+ Always `GET /api/skills` before creating (check name collisions). **Omit frontmatter** from `content` — the API injects it.
22
+
23
+ The description is the **only** routing signal the SDK uses to pick a
24
+ skill — keep it under 280 chars and make the trigger surface
25
+ distinct from every other skill in the manifest. Slug grammar is
26
+ strict: `[a-z0-9][a-z0-9-]*[a-z0-9]` or `[a-z0-9]` (single char),
27
+ 1-64 chars total. PUT rejects collisions with built-in slugs.