@terreno/mcp 57.0.0 → 57.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 (220) hide show
  1. package/dist/bootstrap.d.ts +1 -1
  2. package/dist/bootstrap.d.ts.map +1 -1
  3. package/dist/bootstrap.js +381 -191
  4. package/dist/bootstrap.js.map +1 -1
  5. package/dist/docs/guidelines/api/skills/mongoose-schema-safety/SKILL.md +8 -0
  6. package/dist/docs/resources/overview.md +6 -1
  7. package/dist/docs/resources/rtk.md +3 -1
  8. package/dist/docs/resources/syncdb.md +43 -0
  9. package/dist/docs/upgrades/56.0.0-beta.2.md +34 -0
  10. package/dist/docs/upgrades/57.1.0.md +126 -0
  11. package/dist/docs/versioned/next/README.md +15 -3
  12. package/dist/docs/versioned/next/explanation/README.md +3 -0
  13. package/dist/docs/versioned/next/explanation/admin-consent-migration.md +15 -0
  14. package/dist/docs/versioned/next/explanation/admin-plugin-frontend.md +12 -0
  15. package/dist/docs/versioned/next/explanation/announcements/rtk-deprecation.md +29 -0
  16. package/dist/docs/versioned/next/explanation/authentication.md +51 -58
  17. package/dist/docs/versioned/next/explanation/local-first-data.md +52 -0
  18. package/dist/docs/versioned/next/explanation/loop-engineering.md +117 -0
  19. package/dist/docs/versioned/next/explanation/repository-settings.md +8 -0
  20. package/dist/docs/versioned/next/explanation/roadmap-process.md +22 -9
  21. package/dist/docs/versioned/next/explanation/roadmap-seed-issues.md +39 -0
  22. package/dist/docs/versioned/next/how-to/README.md +3 -0
  23. package/dist/docs/versioned/next/how-to/admin-add-model.md +41 -0
  24. package/dist/docs/versioned/next/how-to/admin-custom-home.md +31 -0
  25. package/dist/docs/versioned/next/how-to/admin-custom-widget.md +42 -0
  26. package/dist/docs/versioned/next/how-to/admin-import-prebuilt.md +25 -0
  27. package/dist/docs/versioned/next/how-to/circleci.md +173 -0
  28. package/dist/docs/versioned/next/how-to/configure-better-auth.md +13 -10
  29. package/dist/docs/versioned/next/how-to/expose-mcp-tools.md +194 -0
  30. package/dist/docs/versioned/next/how-to/install-agent-skills.md +46 -0
  31. package/dist/docs/versioned/next/how-to/migrate-rtk-to-syncdb.md +26 -1
  32. package/dist/docs/versioned/next/how-to/websocket-integration.md +2 -1
  33. package/dist/docs/versioned/next/implementationPlans/ModularAPI.md +1 -0
  34. package/dist/docs/versioned/next/implementationPlans/README.md +31 -17
  35. package/dist/docs/versioned/next/implementationPlans/admin-improvements-research.md +136 -0
  36. package/dist/docs/versioned/next/implementationPlans/admin-improvements.md +157 -527
  37. package/dist/docs/versioned/next/implementationPlans/admin-only-research.md +4 -0
  38. package/dist/docs/versioned/next/implementationPlans/admin-only.md +3 -1
  39. package/dist/docs/versioned/next/implementationPlans/admin-script-runner.md +1 -0
  40. package/dist/docs/versioned/next/implementationPlans/admin-ui-v2-django-parity.md +1 -0
  41. package/dist/docs/versioned/next/implementationPlans/agentic-sdlc-plugin.md +160 -130
  42. package/dist/docs/versioned/next/implementationPlans/apierror-standard-error-redesign.md +1 -0
  43. package/dist/docs/versioned/next/implementationPlans/b2b-platform-program.md +5 -4
  44. package/dist/docs/versioned/next/implementationPlans/comms-abstraction-research.md +48 -0
  45. package/dist/docs/versioned/next/implementationPlans/comms-abstraction.md +152 -62
  46. package/dist/docs/versioned/next/implementationPlans/comms-adapter-sendgrid.md +9 -9
  47. package/dist/docs/versioned/next/implementationPlans/comms-admin-dashboard.md +1 -1
  48. package/dist/docs/versioned/next/implementationPlans/consent-forms.md +4 -0
  49. package/dist/docs/versioned/next/implementationPlans/design-blend-skill.md +1 -0
  50. package/dist/docs/versioned/next/implementationPlans/docs-site-and-versioning.md +1 -0
  51. package/dist/docs/versioned/next/implementationPlans/feature-flags-openfeature.md +1 -0
  52. package/dist/docs/versioned/next/implementationPlans/feature-flags.md +4 -0
  53. package/dist/docs/versioned/next/implementationPlans/infra-mcp-research.md +1 -0
  54. package/dist/docs/versioned/next/implementationPlans/infra-mcp.md +3 -3
  55. package/dist/docs/versioned/next/implementationPlans/mcp-boost-parity.md +1 -0
  56. package/dist/docs/versioned/next/implementationPlans/migrate-cicd-to-circleci-research.md +1 -0
  57. package/dist/docs/versioned/next/implementationPlans/migrate-cicd-to-circleci.md +2 -2
  58. package/dist/docs/versioned/next/implementationPlans/model-router-actions.md +4 -0
  59. package/dist/docs/versioned/next/implementationPlans/model-router-mcp.md +5 -4
  60. package/dist/docs/versioned/next/implementationPlans/offline-mode.md +3 -1
  61. package/dist/docs/versioned/next/implementationPlans/oss-launch-program.md +11 -2
  62. package/dist/docs/versioned/next/implementationPlans/pluggable-database-sqlite-research.md +150 -0
  63. package/dist/docs/versioned/next/implementationPlans/pluggable-database-sqlite.md +247 -0
  64. package/dist/docs/versioned/next/implementationPlans/positioning-django-rails-universal.md +1 -1
  65. package/dist/docs/versioned/next/implementationPlans/public-roadmap-github.md +2 -2
  66. package/dist/docs/versioned/next/implementationPlans/rbac-permissions.md +52 -15
  67. package/dist/docs/versioned/next/implementationPlans/rtk-to-syncdb-migration-docs.md +13 -12
  68. package/dist/docs/versioned/next/implementationPlans/syncdb-codegen-research.md +137 -0
  69. package/dist/docs/versioned/next/implementationPlans/syncdb-codegen.md +63 -59
  70. package/dist/docs/versioned/next/implementationPlans/syncdb-local-first.md +1 -0
  71. package/dist/docs/versioned/next/implementationPlans/syncdb-phase-c-design.md +1 -0
  72. package/dist/docs/versioned/next/implementationPlans/terreno-langfuse-integration.md +1 -0
  73. package/dist/docs/versioned/next/implementationPlans/terreno-syncdb-2.md +1 -0
  74. package/dist/docs/versioned/next/implementationPlans/upgrade-banner.md +4 -0
  75. package/dist/docs/versioned/next/reference/README.md +6 -1
  76. package/dist/docs/versioned/next/reference/admin-config.md +51 -0
  77. package/dist/docs/versioned/next/reference/ai.md +15 -1
  78. package/dist/docs/versioned/next/reference/api.md +18 -0
  79. package/dist/docs/versioned/next/reference/comms.md +88 -7
  80. package/dist/docs/versioned/next/reference/environment-variables.md +9 -1
  81. package/dist/docs/versioned/next/reference/{rtk.md → legacy/rtk.md} +11 -7
  82. package/dist/docs/versioned/next/reference/lifecycle-plugin.md +54 -0
  83. package/dist/docs/versioned/next/reference/mcp-server.md +7 -0
  84. package/dist/docs/versioned/next/reference/syncdb.md +30 -3
  85. package/dist/docs/versioned/next/tasks/README.md +21 -10
  86. package/dist/docs/versioned/next/tasks/admin-improvements.md +189 -353
  87. package/dist/docs/versioned/next/tasks/admin-only.md +2 -0
  88. package/dist/docs/versioned/next/tasks/agentic-sdlc-plugin.md +54 -160
  89. package/dist/docs/versioned/next/tasks/comms-abstraction.md +30 -24
  90. package/dist/docs/versioned/next/tasks/comms-adapter-sendgrid.md +4 -4
  91. package/dist/docs/versioned/next/tasks/consent-forms.md +2 -0
  92. package/dist/docs/versioned/next/tasks/feature-flags.md +2 -0
  93. package/dist/docs/versioned/next/tasks/migrate-cicd-to-circleci.md +14 -10
  94. package/dist/docs/versioned/next/tasks/model-router-actions.md +2 -0
  95. package/dist/docs/versioned/next/tasks/model-router-mcp.md +27 -27
  96. package/dist/docs/versioned/next/tasks/offline-mode.md +2 -0
  97. package/dist/docs/versioned/next/tasks/pluggable-database-sqlite.md +44 -0
  98. package/dist/docs/versioned/next/tasks/public-roadmap-github.md +1 -1
  99. package/dist/docs/versioned/next/tasks/rtk-to-syncdb-migration-docs.md +15 -15
  100. package/dist/docs/versioned/next/tasks/syncdb-codegen.md +37 -31
  101. package/dist/docs/versioned/next/tasks/upgrade-banner.md +2 -0
  102. package/dist/index.js +24 -55
  103. package/dist/index.js.map +1 -1
  104. package/dist/local/localServer.d.ts.map +1 -1
  105. package/dist/local/localServer.js +9 -8
  106. package/dist/local/localServer.js.map +1 -1
  107. package/dist/local/localTools.d.ts +1 -1
  108. package/dist/local/localTools.d.ts.map +1 -1
  109. package/dist/prompts.d.ts.map +1 -1
  110. package/dist/prompts.js +44 -45
  111. package/dist/prompts.js.map +1 -1
  112. package/dist/resources.d.ts.map +1 -1
  113. package/dist/resources.js +9 -2
  114. package/dist/resources.js.map +1 -1
  115. package/dist/tools.d.ts +1 -1
  116. package/dist/tools.d.ts.map +1 -1
  117. package/dist/tools.js +4 -2
  118. package/dist/tools.js.map +1 -1
  119. package/package.json +7 -3
  120. package/src/docs/guidelines/api/skills/mongoose-schema-safety/SKILL.md +8 -0
  121. package/src/docs/resources/overview.md +6 -1
  122. package/src/docs/resources/rtk.md +3 -1
  123. package/src/docs/resources/syncdb.md +43 -0
  124. package/src/docs/upgrades/56.0.0-beta.2.md +34 -0
  125. package/src/docs/upgrades/57.1.0.md +126 -0
  126. package/src/docs/versioned/next/README.md +15 -3
  127. package/src/docs/versioned/next/explanation/README.md +3 -0
  128. package/src/docs/versioned/next/explanation/admin-consent-migration.md +15 -0
  129. package/src/docs/versioned/next/explanation/admin-plugin-frontend.md +12 -0
  130. package/src/docs/versioned/next/explanation/announcements/rtk-deprecation.md +29 -0
  131. package/src/docs/versioned/next/explanation/authentication.md +51 -58
  132. package/src/docs/versioned/next/explanation/local-first-data.md +52 -0
  133. package/src/docs/versioned/next/explanation/loop-engineering.md +117 -0
  134. package/src/docs/versioned/next/explanation/repository-settings.md +8 -0
  135. package/src/docs/versioned/next/explanation/roadmap-process.md +22 -9
  136. package/src/docs/versioned/next/explanation/roadmap-seed-issues.md +39 -0
  137. package/src/docs/versioned/next/how-to/README.md +3 -0
  138. package/src/docs/versioned/next/how-to/admin-add-model.md +41 -0
  139. package/src/docs/versioned/next/how-to/admin-custom-home.md +31 -0
  140. package/src/docs/versioned/next/how-to/admin-custom-widget.md +42 -0
  141. package/src/docs/versioned/next/how-to/admin-import-prebuilt.md +25 -0
  142. package/src/docs/versioned/next/how-to/circleci.md +173 -0
  143. package/src/docs/versioned/next/how-to/configure-better-auth.md +13 -10
  144. package/src/docs/versioned/next/how-to/expose-mcp-tools.md +194 -0
  145. package/src/docs/versioned/next/how-to/install-agent-skills.md +46 -0
  146. package/src/docs/versioned/next/how-to/migrate-rtk-to-syncdb.md +26 -1
  147. package/src/docs/versioned/next/how-to/websocket-integration.md +2 -1
  148. package/src/docs/versioned/next/implementationPlans/ModularAPI.md +1 -0
  149. package/src/docs/versioned/next/implementationPlans/README.md +31 -17
  150. package/src/docs/versioned/next/implementationPlans/admin-improvements-research.md +136 -0
  151. package/src/docs/versioned/next/implementationPlans/admin-improvements.md +157 -527
  152. package/src/docs/versioned/next/implementationPlans/admin-only-research.md +4 -0
  153. package/src/docs/versioned/next/implementationPlans/admin-only.md +3 -1
  154. package/src/docs/versioned/next/implementationPlans/admin-script-runner.md +1 -0
  155. package/src/docs/versioned/next/implementationPlans/admin-ui-v2-django-parity.md +1 -0
  156. package/src/docs/versioned/next/implementationPlans/agentic-sdlc-plugin.md +160 -130
  157. package/src/docs/versioned/next/implementationPlans/apierror-standard-error-redesign.md +1 -0
  158. package/src/docs/versioned/next/implementationPlans/b2b-platform-program.md +5 -4
  159. package/src/docs/versioned/next/implementationPlans/comms-abstraction-research.md +48 -0
  160. package/src/docs/versioned/next/implementationPlans/comms-abstraction.md +152 -62
  161. package/src/docs/versioned/next/implementationPlans/comms-adapter-sendgrid.md +9 -9
  162. package/src/docs/versioned/next/implementationPlans/comms-admin-dashboard.md +1 -1
  163. package/src/docs/versioned/next/implementationPlans/consent-forms.md +4 -0
  164. package/src/docs/versioned/next/implementationPlans/design-blend-skill.md +1 -0
  165. package/src/docs/versioned/next/implementationPlans/docs-site-and-versioning.md +1 -0
  166. package/src/docs/versioned/next/implementationPlans/feature-flags-openfeature.md +1 -0
  167. package/src/docs/versioned/next/implementationPlans/feature-flags.md +4 -0
  168. package/src/docs/versioned/next/implementationPlans/infra-mcp-research.md +1 -0
  169. package/src/docs/versioned/next/implementationPlans/infra-mcp.md +3 -3
  170. package/src/docs/versioned/next/implementationPlans/mcp-boost-parity.md +1 -0
  171. package/src/docs/versioned/next/implementationPlans/migrate-cicd-to-circleci-research.md +1 -0
  172. package/src/docs/versioned/next/implementationPlans/migrate-cicd-to-circleci.md +2 -2
  173. package/src/docs/versioned/next/implementationPlans/model-router-actions.md +4 -0
  174. package/src/docs/versioned/next/implementationPlans/model-router-mcp.md +5 -4
  175. package/src/docs/versioned/next/implementationPlans/offline-mode.md +3 -1
  176. package/src/docs/versioned/next/implementationPlans/oss-launch-program.md +11 -2
  177. package/src/docs/versioned/next/implementationPlans/pluggable-database-sqlite-research.md +150 -0
  178. package/src/docs/versioned/next/implementationPlans/pluggable-database-sqlite.md +247 -0
  179. package/src/docs/versioned/next/implementationPlans/positioning-django-rails-universal.md +1 -1
  180. package/src/docs/versioned/next/implementationPlans/public-roadmap-github.md +2 -2
  181. package/src/docs/versioned/next/implementationPlans/rbac-permissions.md +52 -15
  182. package/src/docs/versioned/next/implementationPlans/rtk-to-syncdb-migration-docs.md +13 -12
  183. package/src/docs/versioned/next/implementationPlans/syncdb-codegen-research.md +137 -0
  184. package/src/docs/versioned/next/implementationPlans/syncdb-codegen.md +63 -59
  185. package/src/docs/versioned/next/implementationPlans/syncdb-local-first.md +1 -0
  186. package/src/docs/versioned/next/implementationPlans/syncdb-phase-c-design.md +1 -0
  187. package/src/docs/versioned/next/implementationPlans/terreno-langfuse-integration.md +1 -0
  188. package/src/docs/versioned/next/implementationPlans/terreno-syncdb-2.md +1 -0
  189. package/src/docs/versioned/next/implementationPlans/upgrade-banner.md +4 -0
  190. package/src/docs/versioned/next/reference/README.md +6 -1
  191. package/src/docs/versioned/next/reference/admin-config.md +51 -0
  192. package/src/docs/versioned/next/reference/ai.md +15 -1
  193. package/src/docs/versioned/next/reference/api.md +18 -0
  194. package/src/docs/versioned/next/reference/comms.md +88 -7
  195. package/src/docs/versioned/next/reference/environment-variables.md +9 -1
  196. package/src/docs/versioned/next/reference/{rtk.md → legacy/rtk.md} +11 -7
  197. package/src/docs/versioned/next/reference/lifecycle-plugin.md +54 -0
  198. package/src/docs/versioned/next/reference/mcp-server.md +7 -0
  199. package/src/docs/versioned/next/reference/syncdb.md +30 -3
  200. package/src/docs/versioned/next/tasks/README.md +21 -10
  201. package/src/docs/versioned/next/tasks/admin-improvements.md +189 -353
  202. package/src/docs/versioned/next/tasks/admin-only.md +2 -0
  203. package/src/docs/versioned/next/tasks/agentic-sdlc-plugin.md +54 -160
  204. package/src/docs/versioned/next/tasks/comms-abstraction.md +30 -24
  205. package/src/docs/versioned/next/tasks/comms-adapter-sendgrid.md +4 -4
  206. package/src/docs/versioned/next/tasks/consent-forms.md +2 -0
  207. package/src/docs/versioned/next/tasks/feature-flags.md +2 -0
  208. package/src/docs/versioned/next/tasks/migrate-cicd-to-circleci.md +14 -10
  209. package/src/docs/versioned/next/tasks/model-router-actions.md +2 -0
  210. package/src/docs/versioned/next/tasks/model-router-mcp.md +27 -27
  211. package/src/docs/versioned/next/tasks/offline-mode.md +2 -0
  212. package/src/docs/versioned/next/tasks/pluggable-database-sqlite.md +44 -0
  213. package/src/docs/versioned/next/tasks/public-roadmap-github.md +1 -1
  214. package/src/docs/versioned/next/tasks/rtk-to-syncdb-migration-docs.md +15 -15
  215. package/src/docs/versioned/next/tasks/syncdb-codegen.md +37 -31
  216. package/src/docs/versioned/next/tasks/upgrade-banner.md +2 -0
  217. package/dist/docs/versioned/next/implementationPlans/PLAN_INDEX.md +0 -73
  218. package/dist/docs/versioned/next/implementationPlans/syncdb-api-inventory.md +0 -303
  219. package/src/docs/versioned/next/implementationPlans/PLAN_INDEX.md +0 -73
  220. package/src/docs/versioned/next/implementationPlans/syncdb-api-inventory.md +0 -303
@@ -58,12 +58,25 @@ await getCommsService().sendSms({
58
58
  });
59
59
  ```
60
60
 
61
- `sendPushToUser()` resolves active device tokens and deactivates tokens only when a provider marks
62
- a failure as permanent. `startVerification()` and `checkVerification()` delegate to the configured
63
- verification provider. `startVerification()` accepts `channel: "sms"` or `channel: "email"`;
64
- `checkVerification()` verifies the code against the same phone number or email destination and may
65
- return an `error` reason when `valid` is false. Start attempts store the verification channel in
66
- delivery-log metadata while recipient values remain redacted.
61
+ `sendPushToUser()` resolves active device tokens and deactivates tokens when
62
+ `errorClass` is `"permanent"` or `isPermanentFailure` is `true`. Provider throws become
63
+ `errorClass: "transient"` with `errorCode: "provider-throw"` and never reject the
64
+ `CommsService` promise. Transient failures retry once (`onRetry` with
65
+ `context.attempt === 2`); push retries only the failed tokens. `checkVerification()` does
66
+ not retry.
67
+
68
+ `beforeSend` may mutate the message or cancel (`status: "cancelled"`, no provider call).
69
+ A throwing `beforeSend` is logged and treated as no-op (send continues). Adapters later
70
+ call `recordDeliveryEvent()` / `recordOptOut()` to update the log and fire
71
+ `onDeliveryEvent` / `onOptOut`.
72
+
73
+ Each send stores one `CommsMessage` row with `attempts[]`. Rendered payloads are retained
74
+ for `retainPayloadDays` (default 30, `0` disables) after `redactPayload`. Mail payloads
75
+ keep `to`, `from`, `subject`, `text`, `html`, `replyTo`, `templateId`, and
76
+ `dynamicTemplateData`. SMS payloads keep `to` and `body`. Push payloads omit tokens.
77
+ Verification start stores `{channel}` only; verification checks store no payload.
78
+ `recordDeliveryEvent` writes `status`, `errorCode`, and `errorClass` onto the matching
79
+ row (`opened` does not change status). Expired payloads are unset, not deleted.
67
80
 
68
81
  ## Provider contracts
69
82
 
@@ -77,17 +90,67 @@ delivery-log metadata while recipient values remain redacted.
77
90
  Concrete SendGrid, Twilio, and Expo providers are separate adapter packages/subpath exports. Core
78
91
  `@terreno/comms` has no concrete provider SDK dependencies.
79
92
 
93
+ ### SendGrid mail adapter
94
+
95
+ ```bash
96
+ bun add @sendgrid/mail
97
+ ```
98
+
99
+ ```typescript
100
+ import {CommsApp} from "@terreno/comms";
101
+ import {SendGridMailProvider} from "@terreno/comms/adapters/sendgrid";
102
+
103
+ new TerrenoApp({userModel: User})
104
+ .register(
105
+ new CommsApp({
106
+ defaultFrom: "notifications@example.com",
107
+ mail: new SendGridMailProvider({
108
+ // apiKey defaults to process.env.SENDGRID_API_KEY (required)
109
+ fromEmail: "notifications@example.com",
110
+ fromName: "Terreno",
111
+ // sandboxMode defaults to true when NODE_ENV === "test"
112
+ }),
113
+ onError: async (_context, result) => {
114
+ console.error("mail failed", result.errorCode, result.errorClass);
115
+ },
116
+ })
117
+ )
118
+ .start();
119
+ ```
120
+
121
+ `SendGridMailProvider` fails fast at construction when `SENDGRID_API_KEY` (or `apiKey`) is
122
+ missing. Send-time failures never throw through `sendMail`; they return
123
+ `accepted: false` with `errorCode` / `errorClass` (`permanent` | `transient` | `config`).
124
+ Transient failures are retried once by `CommsService`. Accepted sends store the SendGrid
125
+ `x-message-id` and a `metadata.consoleUrl` Email Activity deep link on the `CommsMessage`
126
+ row.
127
+
128
+ **Sender verification checklist (SendGrid):**
129
+
130
+ 1. Create an API key with Mail Send permission.
131
+ 2. Verify the from domain (or single sender) in SendGrid.
132
+ 3. Confirm the from address matches a verified identity.
133
+ 4. Use sandbox mode in CI/tests so no real mail is delivered.
134
+
80
135
  ## Configuration
81
136
 
82
137
  ```typescript
83
138
  interface CommsAppOptions {
84
139
  basePath?: string; // default: "/comms"
140
+ beforeSend?: (context: CommsHookContext) =>
141
+ Promise<{cancel?: boolean; message?: CommsHookMessage} | undefined>;
85
142
  defaultFrom?: string;
86
143
  logMessages?: boolean; // default: true
87
144
  mail?: MailProvider;
88
145
  onDeliveryEvent?: (event: DeliveryEvent) => Promise<void>;
146
+ onError?: (context: CommsHookContext, result: SendResult) => Promise<void>;
147
+ onOptOut?: (event: OptOutEvent) => Promise<void>;
148
+ onRetry?: (context: CommsHookContext, result: SendResult) => Promise<void>;
149
+ onSend?: (context: CommsHookContext, result: SendResult) => Promise<void>;
89
150
  push?: PushProvider;
151
+ redactPayload?: (context: CommsHookContext, payload: unknown) => unknown;
90
152
  redactRecipients?: boolean; // default: true
153
+ retainPayloadDays?: number; // default: 30; 0 stores no payload
91
154
  sms?: SmsProvider;
92
155
  verification?: VerificationProvider;
93
156
  }
@@ -99,7 +162,25 @@ When a channel is unconfigured:
99
162
  - production throws a `501` `APIError` titled `Comms channel not configured`.
100
163
 
101
164
  Delivery attempts are stored in `CommsMessage`. Recipient values are stored as `[redacted]` unless
102
- `redactRecipients` is explicitly `false`.
165
+ `redactRecipients` is explicitly `false`. Rendered payloads are retained for `retainPayloadDays`
166
+ (default 30) after `redactPayload`; expired payloads are unset without deleting the log row.
167
+ Mail payloads keep `to`, `from`, `subject`, `text`, `html`, `replyTo`, `templateId`, and
168
+ `dynamicTemplateData`. SMS payloads keep `to` and `body`. Verification start keeps `{channel}`
169
+ only; verification checks store no payload. `recordDeliveryEvent` writes `status`, `errorCode`,
170
+ and `errorClass` onto the matching row (`opened` does not change status).
171
+
172
+ `beforeSend` may replace the message or cancel the send (`status: "cancelled"`). `onSend` and
173
+ `onError` fire after every channel outcome. `onRetry` fires once before the inline retry when
174
+ `errorClass` is `"transient"` (`context.attempt === 2`; shipped signature is `(context, result)`).
175
+ Throwing hooks are logged and never change the send outcome. Exception text stays in logs;
176
+ `metadata.hookErrors` records only `hook-threw` per hook name. Adapters should call
177
+ `recordDeliveryEvent()` and `recordOptOut()` rather than invoking those hooks directly.
178
+
179
+ Provider throws become `{accepted: false, errorClass: "transient", errorCode: "provider-throw"}`.
180
+ Permanent and config failures are not retried. Push retries re-send only the tokens whose first
181
+ result was transient; tokens are deactivated when `errorClass` is `"permanent"` or
182
+ `isPermanentFailure` is true. Each push token gets its own hook context (`attempt`, `isRetry`,
183
+ `messageId`).
103
184
 
104
185
  ## Routes
105
186
 
@@ -133,9 +133,17 @@ Resolution order for API base URL (`rtk/src/constants.ts`):
133
133
  | Variable | Read by | Required | Default | Secret | Scope |
134
134
  |----------|---------|----------|---------|--------|-------|
135
135
  | `COMMS_ENABLED` | example-backend | ❌ | `true` | No | server |
136
+ | `COMMS_DEFAULT_FROM` | example-backend / `@terreno/comms` | ❌ | — | No | server |
137
+ | `COMMS_DEFAULT_FROM_NAME` | example-backend | ❌ | — | No | server |
138
+ | `SENDGRID_API_KEY` | `@terreno/comms/adapters/sendgrid` | ❌ | — | Yes | server |
139
+ | `SENDGRID_SANDBOX_MODE` | example-backend | ❌ | — | No | server |
136
140
 
137
141
  Set `COMMS_ENABLED=false` to omit the example backend's communications plugin and routes.
138
- Provider credentials are documented by their separate adapter packages.
142
+ When `SENDGRID_API_KEY` is set, the example backend registers `SendGridMailProvider`
143
+ (optional peer `@sendgrid/mail`). Without a key, non-production environments keep the
144
+ console mail provider; production leaves mail unconfigured until a provider is wired.
145
+ `SENDGRID_SANDBOX_MODE=true` forces SendGrid sandbox mode for non-test runtimes.
146
+ Sender identity must be verified in SendGrid before real delivery works.
139
147
 
140
148
  ## Observability
141
149
 
@@ -1,4 +1,8 @@
1
- # @terreno/rtk
1
+ # @terreno/rtk (legacy)
2
+
3
+ > **Deprecated for data synchronization.** `@terreno/rtk` remains published through the **56.x** line (and the stable **0.x** line) with a deprecation notice. It will **not** be published in the next major Terreno release. For collection reads/writes, offline sync, and realtime convergence, use [`@terreno/syncdb`](../syncdb.md) and the [migration guide](../../how-to/migrate-rtk-to-syncdb.md).
4
+ >
5
+ > RTK Query is still the correct tool for **non-synced** endpoints: generated OpenAPI hooks (`/auth/me`, admin RPC, AI routes), Better Auth session Redux wiring, feature flags, and sockets.
2
6
 
3
7
  Redux Toolkit Query utilities for frontends using @terreno/api backends. JWT auth, token storage, SDK code generation from OpenAPI, and real-time WebSocket connections.
4
8
 
@@ -114,7 +118,7 @@ export const store = configureStore({
114
118
  }
115
119
  ``````
116
120
 
117
- **Learn more:** [Configure Better Auth](../how-to/configure-better-auth.md)
121
+ **Learn more:** [Configure Better Auth](../../how-to/configure-better-auth.md)
118
122
 
119
123
  ## WebSocket Integration
120
124
 
@@ -439,8 +443,8 @@ EXPO_PUBLIC_API_URL=http://localhost:4000
439
443
 
440
444
  ## Related Documentation
441
445
 
442
- - [Authentication Architecture](../explanation/authentication.md) — Deep-dive into JWT + Passport system
443
- - [WebSocket Integration How-To](../how-to/websocket-integration.md) — Real-time connection setup
444
- - [Add GitHub OAuth](../how-to/add-github-oauth.md) — Step-by-step OAuth setup guide
445
- - [@terreno/api Reference](./api.md) — Backend API framework
446
- - [@terreno/ui Reference](./ui.md) — React Native components
446
+ - [Authentication Architecture](../../explanation/authentication.md) — Deep-dive into JWT + Passport system
447
+ - [WebSocket Integration How-To](../../how-to/websocket-integration.md) — Real-time connection setup
448
+ - [Add GitHub OAuth](../../how-to/add-github-oauth.md) — Step-by-step OAuth setup guide
449
+ - [@terreno/api Reference](../api.md) — Backend API framework
450
+ - [@terreno/ui Reference](../ui.md) — React Native components
@@ -0,0 +1,54 @@
1
+ # Lifecycle plugin reference
2
+
3
+ Plugin: `terreno-planning` (`2.0.0`)
4
+
5
+ All five skills are explicitly invoked (`disable-model-invocation: true`) and implement
6
+ one bounded transition.
7
+
8
+ | Skill | Preconditions | Primary output | PASS next |
9
+ | --- | --- | --- | --- |
10
+ | `terreno-1-grow` | request/spec + repository | approved IP/tasks + criterion/verification map | Pick |
11
+ | `terreno-2-pick` | approved task + branch/state | implemented slice + tests/internal reviews | Roast |
12
+ | `terreno-3-roast` | Pick result + current diff | independent requirement/evidence verdict | Brew |
13
+ | `terreno-4-brew` | Roast PASS + branch/evidence | pushed head + PR + attached evidence | Taste |
14
+ | `terreno-5-taste` | PR + current state | one current-head reaction result | null or fresh Taste |
15
+
16
+ Every stage includes:
17
+
18
+ - Preconditions
19
+ - Inputs
20
+ - Procedure
21
+ - Supporting skills
22
+ - Evidence produced
23
+ - Success, failure, and blocked conditions
24
+ - Recommended next stage
25
+
26
+ Results use `PASS`, `FAIL`, `BLOCKED`, or `PENDING` and follow
27
+ [`stage-result.schema.json`](https://github.com/FlourishHealth/terreno/blob/master/plugins/terreno-planning/references/stage-result.schema.json).
28
+ Loop state follows
29
+ [`execution-state.schema.json`](https://github.com/FlourishHealth/terreno/blob/master/plugins/terreno-planning/references/execution-state.schema.json).
30
+
31
+ The outer loop owns state persistence, waiting, stage invocation, retries, and escalation.
32
+ Brew exits after PR setup. Taste observes/acts once and exits.
33
+
34
+ GitHub communication follows a fixed attention budget: `Why`, `What changed`, and
35
+ `Verification` are the only visible PR sections; optional detail is expandable; comments
36
+ are reserved for blocked decisions or non-obvious review resolutions.
37
+
38
+ Every stage follows the
39
+ [documentation contract](https://github.com/FlourishHealth/terreno/blob/master/plugins/terreno-planning/references/documentation-contract.md):
40
+ read architecture docs before acting, update them in the same slice, and fail the slice
41
+ when user-visible or architectural behavior ships without matching docs.
42
+
43
+ Install the published skill set (lifecycle stages plus repo and package skills):
44
+
45
+ ```bash
46
+ npx skills add FlourishHealth/terreno
47
+ ```
48
+
49
+ Regenerate the committed `skills/` tree with `bun run skills:sync`. Package skills under
50
+ `<package>/.ai/skills/` overlay the repo copies.
51
+
52
+ Exact commands and domain conventions are supplied by repository-local skills discovered
53
+ at stage start; they are not bundled into the lifecycle plugin.
54
+
@@ -7,6 +7,13 @@ Published npm package for the Terreno Model Context Protocol (MCP) server. The m
7
7
 
8
8
  It provides AI coding assistants with documentation access, code generation tools, and workflow prompts.
9
9
 
10
+ Both HTTP MCP surfaces (`@terreno/mcp` and the `modelRouter` endpoint in
11
+ `@terreno/api`) use the MCP TypeScript SDK v2 and speak the stateless
12
+ `2026-07-28` protocol revision. The HTTP handlers retain the SDK's stateless
13
+ legacy fallback for 2025-era clients. `terreno-mcp-local` uses v2 `serveStdio`,
14
+ which negotiates the connection era and pins one server instance for that
15
+ connection.
16
+
10
17
  ## Table of Contents
11
18
 
12
19
  - [Overview](#overview)
@@ -10,6 +10,7 @@ Local-first data layer for Terreno frontends. A TinyBase `MergeableStore` on dev
10
10
  - [createSyncDb configuration](#createsyncdb-configuration)
11
11
  - [SyncDb client methods](#syncdb-client-methods)
12
12
  - [React hooks](#react-hooks)
13
+ - [Codegen](#codegen)
13
14
  - [Conflict API](#conflict-api)
14
15
  - [Sync status API](#sync-status-api)
15
16
  - [Stream scoping](#stream-scoping)
@@ -24,7 +25,8 @@ Local-first data layer for Terreno frontends. A TinyBase `MergeableStore` on dev
24
25
  - `createSyncDb`, `SyncDb`, `SyncDbConfig`, `MutateArgs`
25
26
  - `betterAuthAdapter`, `AuthProvider`
26
27
  - `listConflicts`, `wipeLocalData`, `generateMutationId`
27
- - React (`@terreno/syncdb/react`): `SyncDbProvider`, `useEntity`, `useQuery`, `useEntityIds`, `useMutate`, `useSyncStatus`, `useConflicts`, `useSyncDebugLog`
28
+ - React (`@terreno/syncdb/react`): `SyncDbProvider`, `useEntity`, `useQuery`, `useEntityIds`, `useMutate`, `useSyncStatus`, `useConflicts`, `useSyncDebugLog`, `createCollectionHooks`
29
+ - CLI: `terreno-syncdb-codegen` (generates `SYNC_COLLECTIONS` + friendly hooks from OpenAPI)
28
30
  - Testing (`@terreno/syncdb/testing`): `createFakeTransport`
29
31
 
30
32
  ## Installation
@@ -181,7 +183,7 @@ export const syncDb = createSyncDb({
181
183
  | `goOffline()` | Simulated outage: disconnect transport, pause replay/reconcile/timer; local mutations keep queueing. |
182
184
  | `goOnline()` | End simulated outage; reconnect triggers reconcile + outbox replay. |
183
185
  | `mutate({collection, operation, id?, data?})` | Optimistic local write + durable outbox enqueue + fire-and-forget replay. Returns `{mutationId, id}`. |
184
- | `reconcile()` | HTTP snapshot catch-up for every known stream; runs tombstone compaction on success. |
186
+ | `reconcile()` | HTTP snapshot catch-up for every known stream; runs tombstone compaction on success. Also runs automatically on (re)connect, on a rate-limited seq-jump hint, and on the periodic timer; each `sync:subscribed` confirmation additionally pages just the streams it names. |
185
187
  | `forceResync()` | Purge every known stream locally and re-bootstrap from cursor 0 (outbox/conflicts untouched). Returns `{ok, reason?, streams, purged, repaired}`. |
186
188
  | `replayOutbox()` | Drain queued mutations for the current user now. |
187
189
  | `resolveConflict({mutationId, strategy})` | Apply `"useServer"` or `"keepMine"` to a recorded conflict. |
@@ -199,6 +201,7 @@ Import from `@terreno/syncdb/react`:
199
201
 
200
202
  ```typescript
201
203
  import {
204
+ createCollectionHooks,
202
205
  SyncDbProvider,
203
206
  useConflicts,
204
207
  useEntity,
@@ -289,6 +292,30 @@ Available when the client was created with `debug: true`. `log?.snapshot()` retu
289
292
 
290
293
  Returns the `SyncDb` instance from context (escape hatch for imperative calls like `forceResync()`).
291
294
 
295
+ ### `createCollectionHooks`
296
+
297
+ Factory used by `terreno-syncdb-codegen` and by hand-written custom collections. Returns five operation hooks (`useListQuery`, `useReadQuery`, `useCreateMutation`, `useUpdateMutation`, `useDeleteMutation`). Generated SDKs rename them to friendly names (`useTodos`, `useTodo`, `useCreateTodo`, …). Mutation hooks return `[trigger]`; triggers apply locally and return `{mutationId, id}` synchronously. Optional `retries` maps to `maxAttempts` (`false` → 1, a number → that many, omitted → engine default).
298
+
299
+ ```typescript
300
+ export const {useListQuery: useNotes, useCreateMutation: useCreateNote} =
301
+ createCollectionHooks<Note, CreateNoteBody, UpdateNoteBody>({
302
+ collection: "notes",
303
+ });
304
+ ```
305
+
306
+ ## Codegen
307
+
308
+ `terreno-syncdb-codegen` is a bin of `@terreno/syncdb`. It reads OpenAPI, discovers list operations with `x-terreno-sync`, and writes typed hooks plus `SYNC_COLLECTIONS`.
309
+
310
+ ```bash
311
+ terreno-syncdb-codegen \
312
+ --schema http://localhost:4000/openapi.json \
313
+ --out ./store/syncDbSdk.ts \
314
+ --config ./syncdb-codegen.json
315
+ ```
316
+
317
+ Do not edit the generated file. `--collections` filters when extensions exist. When they do not, it reads list/create/patch schemas from `GET /{name}` (or `/{name}/`). A missing path, a list response without `data.items`, a spec with no extensions and no `--collections` all exit non-zero.
318
+
292
319
  ## Conflict API
293
320
 
294
321
  A **conflict** occurs when the client's `baseVersion` (last seen `_syncSeq`) does not match the server's current seq. The server responds with a `conflict` nack (HTTP **409** on `POST /sync/mutate`, or `sync:nack` with `code: "conflict"` on the socket) carrying the canonical server document.
@@ -380,7 +407,7 @@ Conflict responses on mutate: **409** with `{nack}` body (`code: "conflict"`).
380
407
  | Event | Direction | Payload |
381
408
  |-------|-----------|---------|
382
409
  | `sync:subscribe` / `sync:unsubscribe` | client → server | `{collections: string[]}` |
383
- | `sync:subscribed` | server → client | `{collection, streams}` |
410
+ | `sync:subscribed` | server → client | `{collection, streams}` — sent after the stream rooms are joined; the client pages each confirmed stream from its cursor so a write landing between the startup snapshot and the join is not missed |
384
411
  | `sync:error` | server → client | `{collection, message}` |
385
412
  | `sync:delta` | server → client | `{collection, id, method, data?, seq, stream, deleted?, frontierSeq?}` |
386
413
  | `sync:mutate` | client → server | `{mutationId, collection, operation, id?, data?, baseVersion?}` |
@@ -1,29 +1,39 @@
1
1
  # Task lists
2
2
 
3
- Bot-consumable execution checklists, one per implementation plan (IP). A task file is
4
- the second half of the pair described in
5
- [`docs/implementationPlans/README.md`](../implementationPlans/README.md):
3
+ Bot-consumable execution checklists. Most files pair with an implementation plan (IP)
4
+ as described in [`docs/implementationPlans/README.md`](../implementationPlans/README.md):
6
5
 
7
6
  - **IP** (`docs/implementationPlans/<slug>.md`) — the design: what and why.
8
7
  - **Task list** (`docs/tasks/<slug>.md`) — the steps: the concrete, ordered work.
9
8
 
10
9
  The filename slug matches the IP it belongs to.
11
10
 
11
+ The loop's small-feature profile may use a task file with `**Feature profile:** true` and
12
+ no full IP when repository policy permits. The destination, scope, decisions, acceptance
13
+ criteria, tracer, and verification seam live in that durable contract so a fresh Pick
14
+ agent can implement one task without conversation history.
15
+
12
16
  ## Task shape
13
17
 
14
- Each task is a checkbox with four fields so it can be picked up and verified independently:
18
+ Each task is a tracer-bullet vertical slice with explicit blocking edges:
15
19
 
16
20
  ```markdown
17
21
  - [ ] **Task 1.1**: Short title
18
- - Description: what to implement
22
+ - Delivers: the narrow end-to-end behavior this makes usable
19
23
  - Files: expected files to create or modify
20
- - Depends on: none | other task IDs
21
- - Acceptance: how to verify it is done
24
+ - Blocked by: none | other task IDs
25
+ - Acceptance: observable proof, including focused Bun tests
22
26
  ```
23
27
 
24
- Group tasks by phase (`### Phase 1: …`). Order them by dependency — models first, then
25
- APIs, then UI. Blend-style runs may append a **Plan vs Actual** log to the same file after
26
- each task.
28
+ Group tasks by phase (`### Phase 1: …`) and order them by dependency. Every normal task
29
+ cuts through the required data, API, UI, documentation, and test layers rather than
30
+ batching one layer across the whole feature. A completed task is demoable or independently
31
+ verifiable and small enough for one fresh agent context. Work the **frontier**: any task
32
+ whose blockers are complete.
33
+
34
+ Wide mechanical refactors that cannot land green as vertical slices use
35
+ **expand → migrate batches → contract**. The contract task is blocked by every migration
36
+ batch. Grow-style runs may append a **Plan vs Actual** log after each task.
27
37
 
28
38
  ## What lives here vs elsewhere
29
39
 
@@ -33,6 +43,7 @@ each task.
33
43
  | Concrete task steps and their status | this directory |
34
44
  | Public status and target | GitHub roadmap issue / Project (roadmap-enabled repos) |
35
45
  | Sprint estimates and assignees | Linear |
46
+ | Current stage/attempt/head/result | loop-owned execution state (default `.terreno/pipeline/<slug>.json`) |
36
47
 
37
48
  Do not copy the full checklist into a GitHub issue or Linear. Create linked GitHub child
38
49
  issues only for tasks that outside contributors should be able to claim independently; the