@terreno/mcp 57.21.0 → 58.0.0-beta.1

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 (244) hide show
  1. package/CHANGELOG.md +43 -0
  2. package/README.md +57 -3
  3. package/dist/bootstrap.d.ts.map +1 -1
  4. package/dist/bootstrap.js +17 -16
  5. package/dist/bootstrap.js.map +1 -1
  6. package/dist/docs/guidelines/admin-frontend/guidelines/core.md +6 -5
  7. package/dist/docs/guidelines/ui/guidelines/core.md +1 -1
  8. package/dist/docs/prompts/debug.md +6 -4
  9. package/dist/docs/prompts/screen.md +11 -17
  10. package/dist/docs/resources/overview.md +5 -3
  11. package/dist/docs/resources/patterns.md +157 -238
  12. package/dist/docs/resources/syncdb.md +44 -16
  13. package/dist/docs/templates/bootstrap/CLAUDE.template.md +2 -2
  14. package/dist/docs/templates/bootstrap/cursorrules.template.md +7 -5
  15. package/dist/docs/templates/bootstrap/frontend/app/(tabs)/profile.template.tsx +8 -12
  16. package/dist/docs/templates/bootstrap/frontend/app/_layout.template.tsx +75 -52
  17. package/dist/docs/templates/bootstrap/frontend/app/login.template.tsx +46 -108
  18. package/dist/docs/templates/bootstrap/frontend/app/signup.template.tsx +53 -0
  19. package/dist/docs/templates/bootstrap/frontend/lib/betterAuth.template.md +18 -0
  20. package/dist/docs/templates/bootstrap/frontend/store/apiClient.template.md +33 -0
  21. package/dist/docs/templates/bootstrap/frontend/store/apiSdk.template.md +76 -0
  22. package/dist/docs/templates/bootstrap/frontend/store/syncdb.template.md +56 -0
  23. package/dist/docs/templates/bootstrap/frontend/utils/index.template.md +0 -4
  24. package/dist/docs/upgrades/58.0.0-beta.1.md +504 -0
  25. package/dist/docs/upgrades/58.0.0.md +495 -4
  26. package/dist/docs/versioned/next/README.md +2 -2
  27. package/dist/docs/versioned/next/approval-rubric.md +2 -2
  28. package/dist/docs/versioned/next/explanation/admin-interface.md +6 -5
  29. package/dist/docs/versioned/next/explanation/admin-plugin-frontend.md +1 -1
  30. package/dist/docs/versioned/next/explanation/ai-workflows.md +5 -3
  31. package/dist/docs/versioned/next/explanation/announcements/rtk-deprecation.md +16 -11
  32. package/dist/docs/versioned/next/explanation/authentication.md +62 -43
  33. package/dist/docs/versioned/next/explanation/dependency-management.md +1 -1
  34. package/dist/docs/versioned/next/explanation/deployment-baseline.md +1 -1
  35. package/dist/docs/versioned/next/explanation/example-coverage.md +2 -2
  36. package/dist/docs/versioned/next/explanation/explicit-any-policy.md +5 -6
  37. package/dist/docs/versioned/next/explanation/gcp-hosting-architecture.md +1 -1
  38. package/dist/docs/versioned/next/explanation/local-first-data.md +11 -9
  39. package/dist/docs/versioned/next/explanation/model-router-actions.md +1 -1
  40. package/dist/docs/versioned/next/explanation/modular-api-design.md +2 -2
  41. package/dist/docs/versioned/next/explanation/no-barrel-imports.md +5 -5
  42. package/dist/docs/versioned/next/explanation/roadmap-seed-issues.md +4 -3
  43. package/dist/docs/versioned/next/explanation/source-rules.md +2 -2
  44. package/dist/docs/versioned/next/explanation/typescript-configuration.md +2 -4
  45. package/dist/docs/versioned/next/explanation/versioning-policy.md +3 -3
  46. package/dist/docs/versioned/next/how-to/README.md +3 -2
  47. package/dist/docs/versioned/next/how-to/add-feature-flags.md +50 -25
  48. package/dist/docs/versioned/next/how-to/add-organizations.md +2 -1
  49. package/dist/docs/versioned/next/how-to/admin-custom-home.md +8 -2
  50. package/dist/docs/versioned/next/how-to/admin-custom-widget.md +0 -1
  51. package/dist/docs/versioned/next/how-to/agent-ui-asks.md +6 -6
  52. package/dist/docs/versioned/next/how-to/build-admin-screens.md +10 -8
  53. package/dist/docs/versioned/next/how-to/build-for-web.md +1 -1
  54. package/dist/docs/versioned/next/how-to/call-external-apis.md +2 -2
  55. package/dist/docs/versioned/next/how-to/circleci.md +12 -6
  56. package/dist/docs/versioned/next/how-to/configure-better-auth.md +114 -60
  57. package/dist/docs/versioned/next/how-to/connect-mcp-service-token.md +10 -4
  58. package/dist/docs/versioned/next/how-to/create-a-terreno-app.md +14 -2
  59. package/dist/docs/versioned/next/how-to/debug-with-mcp.md +8 -13
  60. package/dist/docs/versioned/next/how-to/expose-mcp-tools.md +15 -4
  61. package/dist/docs/versioned/next/how-to/generate-the-client-sdk.md +33 -0
  62. package/dist/docs/versioned/next/how-to/github-actions-ci.md +2 -2
  63. package/dist/docs/versioned/next/how-to/in-app-notifications.md +1 -1
  64. package/dist/docs/versioned/next/how-to/migrate-rtk-to-syncdb.md +318 -447
  65. package/dist/docs/versioned/next/how-to/password-reset.md +1 -1
  66. package/dist/docs/versioned/next/how-to/product-announcements.md +6 -3
  67. package/dist/docs/versioned/next/how-to/rate-limiting.md +38 -16
  68. package/dist/docs/versioned/next/how-to/run-mongodb-migrations.md +19 -0
  69. package/dist/docs/versioned/next/how-to/run-tests-locally.md +2 -3
  70. package/dist/docs/versioned/next/how-to/set-up-social-login.md +1 -1
  71. package/dist/docs/versioned/next/how-to/set-up-terreno-mcp.md +2 -2
  72. package/dist/docs/versioned/next/how-to/track-upstream-expo.md +1 -1
  73. package/dist/docs/versioned/next/how-to/upgrade-banner.md +5 -3
  74. package/dist/docs/versioned/next/how-to/upgrade-terreno.md +5 -5
  75. package/dist/docs/versioned/next/how-to/use-syncdb-correctly.md +1 -1
  76. package/dist/docs/versioned/next/how-to/websocket-integration.md +113 -402
  77. package/dist/docs/versioned/next/implementationPlans/b2b-platform-program.md +1 -1
  78. package/dist/docs/versioned/next/implementationPlans/migrate-admin-to-syncdb.md +5 -0
  79. package/dist/docs/versioned/next/implementationPlans/native-module-baseline.md +29 -5
  80. package/dist/docs/versioned/next/implementationPlans/remove-legacy-realtime.md +1 -1
  81. package/dist/docs/versioned/next/implementationPlans/remove-rtk.md +185 -0
  82. package/dist/docs/versioned/next/reference/README.md +1 -1
  83. package/dist/docs/versioned/next/reference/admin-frontend.md +85 -70
  84. package/dist/docs/versioned/next/reference/admin-spa.md +10 -4
  85. package/dist/docs/versioned/next/reference/ai.md +36 -4
  86. package/dist/docs/versioned/next/reference/announcements.md +3 -3
  87. package/dist/docs/versioned/next/reference/api.md +39 -24
  88. package/dist/docs/versioned/next/reference/cli.md +3 -4
  89. package/dist/docs/versioned/next/reference/environment-variables.md +16 -16
  90. package/dist/docs/versioned/next/reference/feature-flags.md +48 -7
  91. package/dist/docs/versioned/next/reference/jobs.md +2 -2
  92. package/dist/docs/versioned/next/reference/legacy/rtk.md +25 -600
  93. package/dist/docs/versioned/next/reference/mcp-server.md +441 -1158
  94. package/dist/docs/versioned/next/reference/syncdb.md +426 -16
  95. package/dist/docs/versioned/next/reference/test.md +28 -3
  96. package/dist/docs/versioned/next/reference/ui.md +132 -19
  97. package/dist/docs/versioned/next/tasks/native-module-baseline.md +8 -4
  98. package/dist/docs/versioned/next/tasks/rate-limiting.md +9 -2
  99. package/dist/docs/versioned/next/tasks/remove-legacy-realtime.md +5 -5
  100. package/dist/docs/versioned/next/tasks/remove-rtk.md +155 -0
  101. package/dist/local/localTools.d.ts.map +1 -1
  102. package/dist/local/localTools.js +3 -54
  103. package/dist/local/localTools.js.map +1 -1
  104. package/dist/local/tools/runtime.d.ts +0 -21
  105. package/dist/local/tools/runtime.d.ts.map +1 -1
  106. package/dist/local/tools/runtime.js +0 -176
  107. package/dist/local/tools/runtime.js.map +1 -1
  108. package/dist/local/tools/syncDb.d.ts +0 -11
  109. package/dist/local/tools/syncDb.d.ts.map +1 -1
  110. package/dist/local/tools/syncDb.js +1 -5
  111. package/dist/local/tools/syncDb.js.map +1 -1
  112. package/dist/packageGuidelines.d.ts +3 -2
  113. package/dist/packageGuidelines.d.ts.map +1 -1
  114. package/dist/packageGuidelines.js +4 -11
  115. package/dist/packageGuidelines.js.map +1 -1
  116. package/dist/prompts.d.ts.map +1 -1
  117. package/dist/prompts.js +17 -18
  118. package/dist/prompts.js.map +1 -1
  119. package/dist/resources.d.ts.map +1 -1
  120. package/dist/resources.js +1 -8
  121. package/dist/resources.js.map +1 -1
  122. package/dist/search/chunker.d.ts +1 -1
  123. package/dist/search/chunker.d.ts.map +1 -1
  124. package/dist/search/inferPackages.d.ts +1 -1
  125. package/dist/search/inferPackages.js +5 -5
  126. package/dist/search/inferPackages.js.map +1 -1
  127. package/dist/tools.d.ts +6 -0
  128. package/dist/tools.d.ts.map +1 -1
  129. package/dist/tools.js +126 -119
  130. package/dist/tools.js.map +1 -1
  131. package/package.json +6 -6
  132. package/src/docs/guidelines/admin-frontend/guidelines/core.md +6 -5
  133. package/src/docs/guidelines/ui/guidelines/core.md +1 -1
  134. package/src/docs/prompts/debug.md +6 -4
  135. package/src/docs/prompts/screen.md +11 -17
  136. package/src/docs/resources/overview.md +5 -3
  137. package/src/docs/resources/patterns.md +157 -238
  138. package/src/docs/resources/syncdb.md +44 -16
  139. package/src/docs/templates/bootstrap/CLAUDE.template.md +2 -2
  140. package/src/docs/templates/bootstrap/cursorrules.template.md +7 -5
  141. package/src/docs/templates/bootstrap/frontend/app/(tabs)/profile.template.tsx +8 -12
  142. package/src/docs/templates/bootstrap/frontend/app/_layout.template.tsx +75 -52
  143. package/src/docs/templates/bootstrap/frontend/app/login.template.tsx +46 -108
  144. package/src/docs/templates/bootstrap/frontend/app/signup.template.tsx +53 -0
  145. package/src/docs/templates/bootstrap/frontend/lib/betterAuth.template.md +18 -0
  146. package/src/docs/templates/bootstrap/frontend/store/apiClient.template.md +33 -0
  147. package/src/docs/templates/bootstrap/frontend/store/apiSdk.template.md +76 -0
  148. package/src/docs/templates/bootstrap/frontend/store/syncdb.template.md +56 -0
  149. package/src/docs/templates/bootstrap/frontend/utils/index.template.md +0 -4
  150. package/src/docs/upgrades/58.0.0-beta.1.md +504 -0
  151. package/src/docs/upgrades/58.0.0.md +495 -4
  152. package/src/docs/versioned/next/README.md +2 -2
  153. package/src/docs/versioned/next/approval-rubric.md +2 -2
  154. package/src/docs/versioned/next/explanation/admin-interface.md +6 -5
  155. package/src/docs/versioned/next/explanation/admin-plugin-frontend.md +1 -1
  156. package/src/docs/versioned/next/explanation/ai-workflows.md +5 -3
  157. package/src/docs/versioned/next/explanation/announcements/rtk-deprecation.md +16 -11
  158. package/src/docs/versioned/next/explanation/authentication.md +62 -43
  159. package/src/docs/versioned/next/explanation/dependency-management.md +1 -1
  160. package/src/docs/versioned/next/explanation/deployment-baseline.md +1 -1
  161. package/src/docs/versioned/next/explanation/example-coverage.md +2 -2
  162. package/src/docs/versioned/next/explanation/explicit-any-policy.md +5 -6
  163. package/src/docs/versioned/next/explanation/gcp-hosting-architecture.md +1 -1
  164. package/src/docs/versioned/next/explanation/local-first-data.md +11 -9
  165. package/src/docs/versioned/next/explanation/model-router-actions.md +1 -1
  166. package/src/docs/versioned/next/explanation/modular-api-design.md +2 -2
  167. package/src/docs/versioned/next/explanation/no-barrel-imports.md +5 -5
  168. package/src/docs/versioned/next/explanation/roadmap-seed-issues.md +4 -3
  169. package/src/docs/versioned/next/explanation/source-rules.md +2 -2
  170. package/src/docs/versioned/next/explanation/typescript-configuration.md +2 -4
  171. package/src/docs/versioned/next/explanation/versioning-policy.md +3 -3
  172. package/src/docs/versioned/next/how-to/README.md +3 -2
  173. package/src/docs/versioned/next/how-to/add-feature-flags.md +50 -25
  174. package/src/docs/versioned/next/how-to/add-organizations.md +2 -1
  175. package/src/docs/versioned/next/how-to/admin-custom-home.md +8 -2
  176. package/src/docs/versioned/next/how-to/admin-custom-widget.md +0 -1
  177. package/src/docs/versioned/next/how-to/agent-ui-asks.md +6 -6
  178. package/src/docs/versioned/next/how-to/build-admin-screens.md +10 -8
  179. package/src/docs/versioned/next/how-to/build-for-web.md +1 -1
  180. package/src/docs/versioned/next/how-to/call-external-apis.md +2 -2
  181. package/src/docs/versioned/next/how-to/circleci.md +12 -6
  182. package/src/docs/versioned/next/how-to/configure-better-auth.md +114 -60
  183. package/src/docs/versioned/next/how-to/connect-mcp-service-token.md +10 -4
  184. package/src/docs/versioned/next/how-to/create-a-terreno-app.md +14 -2
  185. package/src/docs/versioned/next/how-to/debug-with-mcp.md +8 -13
  186. package/src/docs/versioned/next/how-to/expose-mcp-tools.md +15 -4
  187. package/src/docs/versioned/next/how-to/generate-the-client-sdk.md +33 -0
  188. package/src/docs/versioned/next/how-to/github-actions-ci.md +2 -2
  189. package/src/docs/versioned/next/how-to/in-app-notifications.md +1 -1
  190. package/src/docs/versioned/next/how-to/migrate-rtk-to-syncdb.md +318 -447
  191. package/src/docs/versioned/next/how-to/password-reset.md +1 -1
  192. package/src/docs/versioned/next/how-to/product-announcements.md +6 -3
  193. package/src/docs/versioned/next/how-to/rate-limiting.md +38 -16
  194. package/src/docs/versioned/next/how-to/run-mongodb-migrations.md +19 -0
  195. package/src/docs/versioned/next/how-to/run-tests-locally.md +2 -3
  196. package/src/docs/versioned/next/how-to/set-up-social-login.md +1 -1
  197. package/src/docs/versioned/next/how-to/set-up-terreno-mcp.md +2 -2
  198. package/src/docs/versioned/next/how-to/track-upstream-expo.md +1 -1
  199. package/src/docs/versioned/next/how-to/upgrade-banner.md +5 -3
  200. package/src/docs/versioned/next/how-to/upgrade-terreno.md +5 -5
  201. package/src/docs/versioned/next/how-to/use-syncdb-correctly.md +1 -1
  202. package/src/docs/versioned/next/how-to/websocket-integration.md +113 -402
  203. package/src/docs/versioned/next/implementationPlans/b2b-platform-program.md +1 -1
  204. package/src/docs/versioned/next/implementationPlans/migrate-admin-to-syncdb.md +5 -0
  205. package/src/docs/versioned/next/implementationPlans/native-module-baseline.md +29 -5
  206. package/src/docs/versioned/next/implementationPlans/remove-legacy-realtime.md +1 -1
  207. package/src/docs/versioned/next/implementationPlans/remove-rtk.md +185 -0
  208. package/src/docs/versioned/next/reference/README.md +1 -1
  209. package/src/docs/versioned/next/reference/admin-frontend.md +85 -70
  210. package/src/docs/versioned/next/reference/admin-spa.md +10 -4
  211. package/src/docs/versioned/next/reference/ai.md +36 -4
  212. package/src/docs/versioned/next/reference/announcements.md +3 -3
  213. package/src/docs/versioned/next/reference/api.md +39 -24
  214. package/src/docs/versioned/next/reference/cli.md +3 -4
  215. package/src/docs/versioned/next/reference/environment-variables.md +16 -16
  216. package/src/docs/versioned/next/reference/feature-flags.md +48 -7
  217. package/src/docs/versioned/next/reference/jobs.md +2 -2
  218. package/src/docs/versioned/next/reference/legacy/rtk.md +25 -600
  219. package/src/docs/versioned/next/reference/mcp-server.md +441 -1158
  220. package/src/docs/versioned/next/reference/syncdb.md +426 -16
  221. package/src/docs/versioned/next/reference/test.md +28 -3
  222. package/src/docs/versioned/next/reference/ui.md +132 -19
  223. package/src/docs/versioned/next/tasks/native-module-baseline.md +8 -4
  224. package/src/docs/versioned/next/tasks/rate-limiting.md +9 -2
  225. package/src/docs/versioned/next/tasks/remove-legacy-realtime.md +5 -5
  226. package/src/docs/versioned/next/tasks/remove-rtk.md +155 -0
  227. package/dist/docs/guidelines/rtk/guidelines/core.md +0 -26
  228. package/dist/docs/resources/rtk.md +0 -181
  229. package/dist/docs/templates/bootstrap/frontend/openapi-config.template.md +0 -16
  230. package/dist/docs/templates/bootstrap/frontend/scripts/generate-sdk.template.md +0 -49
  231. package/dist/docs/templates/bootstrap/frontend/store/appState.template.md +0 -45
  232. package/dist/docs/templates/bootstrap/frontend/store/errors.template.md +0 -51
  233. package/dist/docs/templates/bootstrap/frontend/store/index.template.md +0 -86
  234. package/dist/docs/templates/bootstrap/frontend/store/openApiSdk.template.md +0 -49
  235. package/dist/docs/templates/bootstrap/frontend/store/sdk.template.md +0 -80
  236. package/src/docs/guidelines/rtk/guidelines/core.md +0 -26
  237. package/src/docs/resources/rtk.md +0 -181
  238. package/src/docs/templates/bootstrap/frontend/openapi-config.template.md +0 -16
  239. package/src/docs/templates/bootstrap/frontend/scripts/generate-sdk.template.md +0 -49
  240. package/src/docs/templates/bootstrap/frontend/store/appState.template.md +0 -45
  241. package/src/docs/templates/bootstrap/frontend/store/errors.template.md +0 -51
  242. package/src/docs/templates/bootstrap/frontend/store/index.template.md +0 -86
  243. package/src/docs/templates/bootstrap/frontend/store/openApiSdk.template.md +0 -49
  244. package/src/docs/templates/bootstrap/frontend/store/sdk.template.md +0 -80
@@ -54,49 +54,66 @@ After adding the backend routes, regenerate the SDK so the frontend can call the
54
54
  cd your-frontend && bun run sdk
55
55
  ```
56
56
 
57
- Regeneration may emit a hook for `/feature-flags/flagConfiguration`; prefer **`useTerrenoFeatureFlags`** / **`useFeatureFlags`** from `@terreno/rtk` so OpenFeature domain, cache keying, and optional socket refetch stay consistent.
57
+ Regeneration may emit a hook for `/feature-flags/flagConfiguration`; prefer **`useTerrenoFeatureFlags`** / **`useFeatureFlags`** from `@terreno/syncdb/flags` so the OpenFeature domain, per-user refetch, and socket refresh stay consistent.
58
58
 
59
59
  ### 4. Use feature flags in the frontend
60
60
 
61
- **Recommended (OpenFeature):** add `@openfeature/react-sdk` to the app, wrap the tree (or the subtree that reads flags) in `<OpenFeatureProvider domain="feature-flags">`, and call `useTerrenoFeatureFlags(terrenoApi, {userId, socket})` once after auth so the OpenFeature client receives `GET /feature-flags/flagConfiguration`. Then use standard hooks such as `useBooleanFlagValue` / `useStringFlagValue` / `FeatureFlag`.
61
+ Add `@openfeature/web-sdk` and `@openfeature/react-sdk` to the app (`catalog:` versions). Both
62
+ hooks come from `@terreno/syncdb/flags`, fetch through the request client from
63
+ `ApiClientProvider`, and refetch when the server pushes `featureFlagsChanged` on the syncdb
64
+ socket.
62
65
 
63
- **Back-compat:** `useFeatureFlags(terrenoApi)` from `@terreno/rtk` still returns `{flags, getFlag, getVariant, isLoading, …}` with the same semantics as before; it uses `/flagConfiguration` under the hood. You do not need to call a generated RTK hook for `/flagConfiguration` directly.
66
+ **Recommended (OpenFeature):** wrap the tree that reads flags in
67
+ `<OpenFeatureProvider domain="feature-flags">` and call `useTerrenoFeatureFlags` once after
68
+ auth. Pass your `syncDb` as `socket` when this component sits above `SyncDbProvider`. Then read
69
+ values with `useBooleanFlagValue` / `useStringFlagValue` / `FeatureFlag`.
70
+
71
+ ```typescript
72
+ import {OpenFeatureProvider} from "@openfeature/react-sdk";
73
+ import {useTerrenoFeatureFlags} from "@terreno/syncdb/flags";
74
+ import {syncDb} from "@/store/syncdb";
75
+
76
+ const FlagsBridge: React.FC<{children: React.ReactNode; userId?: string}> = ({
77
+ children,
78
+ userId,
79
+ }) => {
80
+ useTerrenoFeatureFlags({skip: !userId, socket: syncDb, userId});
81
+ return <OpenFeatureProvider domain="feature-flags">{children}</OpenFeatureProvider>;
82
+ };
83
+ ```
64
84
 
65
85
  ```typescript
66
86
  import {useBooleanFlagValue} from "@openfeature/react-sdk";
67
- import {useTerrenoFeatureFlags, useSelectCurrentUserId} from "@terreno/rtk";
68
- import {terrenoApi} from "@/store/sdk";
69
87
 
70
88
  const GatedBanner: React.FC = () => {
71
- const userId = useSelectCurrentUserId();
72
- useTerrenoFeatureFlags(terrenoApi, {userId, skip: !userId});
73
89
  const showBanner = useBooleanFlagValue("new-ui", false);
74
90
  return showBanner ? <NewUI /> : null;
75
91
  };
76
92
  ```
77
93
 
94
+ **Flat accessors:** `useFeatureFlags` returns `{flags, getFlag, getVariant, isLoading, error,
95
+ refetch}`. Screens below the bridge can pass `socket: null` — they share the bridge's cached
96
+ query, so its refetch updates them too.
97
+
78
98
  ```typescript
79
- import {useFeatureFlags} from "@terreno/rtk";
80
- import {terrenoApi} from "@/store/sdk";
99
+ import {useFeatureFlags} from "@terreno/syncdb/flags";
81
100
 
82
- const LegacyStyle: React.FC = () => {
83
- const {getFlag, isLoading} = useFeatureFlags(terrenoApi);
101
+ const LegacyStyle: React.FC<{userId?: string}> = ({userId}) => {
102
+ const {getFlag, isLoading} = useFeatureFlags({skip: !userId, socket: null, userId});
84
103
 
85
104
  if (isLoading) {
86
105
  return <Spinner />;
87
106
  }
88
107
 
89
- const showNewUI = getFlag("new-ui");
90
-
91
- return showNewUI ? <NewUI /> : <OldUI />;
108
+ return getFlag("new-ui") ? <NewUI /> : <OldUI />;
92
109
  };
93
110
  ```
94
111
 
95
112
  ### 4b. Live updates (optional)
96
113
 
97
- To push flag changes to open clients without a refresh, pass **`liveUpdates`** when constructing `FeatureFlagsApp` (see `example-backend/src/server.ts`): Mongoose **`FeatureFlag.watch()`** drives a Socket.io broadcast. **MongoDB must run as a replica set** (a single-node replica set is enough); standalone instances cannot use change streams, and the plugin logs a warning if `watch()` fails.
114
+ To push flag changes to open clients without a refresh, pass **`liveUpdates`** when constructing `FeatureFlagsApp` (see `example-backend/src/server.ts`): Mongoose **`FeatureFlag.watch()`** drives a Socket.io broadcast. Point `socketIoServer` at `() => realtimeApp.getIo()` so the push goes out on the socket the syncdb client already holds. **MongoDB must run as a replica set** (a single-node replica set is enough); standalone instances cannot use change streams, and the plugin logs a warning if `watch()` fails.
98
115
 
99
- On the client, pass the same Socket.io **client** into `useTerrenoFeatureFlags` / `useFeatureFlags` as `socket`; the hook listens for `featureFlagsChanged` (or `socketEventName`) and refetches `/flagConfiguration`. The event payload is only `{ key: string }` — the same flag keys are already returned to every authenticated user in `/flagConfiguration`, so this is not considered a new exposure.
116
+ On the client there is nothing extra to wire: `useTerrenoFeatureFlags` listens for `featureFlagsChanged` (or `socketEventName`) through `syncDb.onSocketEvent` and refetches `/flagConfiguration`. The app opens no second socket. The event payload is only `{ key: string }` — the same flag keys are already returned to every authenticated user in `/flagConfiguration`, so this is not considered a new exposure.
100
117
 
101
118
  ### 5. Create flags via the admin panel
102
119
 
@@ -111,23 +128,31 @@ Navigate to the admin panel in your app. The "Feature Flags" card appears automa
111
128
 
112
129
  ## Migrating from `GET …/evaluate` (OpenFeature)
113
130
 
114
- Terreno's feature-flag stack uses **OpenFeature** (`@terreno/feature-flags` on the server, `@terreno/rtk` on the client). Use this checklist if you upgrade from a Terreno release that only documented `GET …/evaluate`.
131
+ Terreno's feature-flag stack uses **OpenFeature** (`@terreno/feature-flags` on the server, `@terreno/syncdb/flags` on the client). Use this checklist if you upgrade from a Terreno release that only documented `GET …/evaluate`.
115
132
 
116
133
  ### Backend (`@terreno/feature-flags`)
117
134
 
118
135
  1. Keep **`FeatureFlagsApp`** registered as before; admin CRUD is unchanged.
119
136
  2. Prefer authenticated clients calling **`GET {basePath}/flagConfiguration`** — the JSON body matches OpenFeature's static configuration shape (for `TypedInMemoryProvider` on the client).
120
- 3. **`GET {basePath}/evaluate`** still returns the legacy `Record<key, boolean | string | null>` map but is **deprecated** (`Deprecation: true`, `Sunset` header). Migrate direct HTTP or hand-written clients to `/flagConfiguration`, or rely on `@terreno/rtk` hooks below.
137
+ 3. **`GET {basePath}/evaluate`** still returns the legacy `Record<key, boolean | string | null>` map but is **deprecated** (`Deprecation: true`, `Sunset` header). Migrate direct HTTP or hand-written clients to `/flagConfiguration`, or rely on the `@terreno/syncdb/flags` hooks below.
121
138
  4. **`FeatureFlag`** documents gain optional **`defaultVariant`** (boolean: `"on"` / `"off"`; variant: a key from `variants`). Omitted values are filled on save. For existing databases, run a one-off backfill or reuse the pattern in `example-backend/src/scripts/seed-feature-flags.ts`.
122
139
  5. **Live updates (optional):** pass `liveUpdates: { socketIoServer: io | () => io }` to `FeatureFlagsApp`. MongoDB must run as a **replica set** (a single-node replica set is enough) so Mongoose change streams work.
123
140
 
124
- ### Frontend (`@terreno/rtk` + OpenFeature)
125
-
126
- 1. **`useFeatureFlags(terrenoApi, …)`** — no code changes required for the common case; it already uses `/flagConfiguration` and keeps `{ flags, getFlag, getVariant, isLoading, refetch }`.
127
- 2. **OpenFeature React hooks** (`useBooleanFlagValue`, `useStringFlagValue`, `<FeatureFlag>`, …): add **`@openfeature/react-sdk`** and **`@openfeature/web-sdk`** to your app (align versions with `@terreno/rtk` **peerDependencies** and the root **`catalog`**).
128
- 3. Wrap the UI that reads flags in **`<OpenFeatureProvider domain="feature-flags">`** (or the same `domain` you pass into the hook).
129
- 4. After auth, call **`useTerrenoFeatureFlags(terrenoApi, { userId, skip, socket, … })`** once under your Redux `Provider` so OpenFeature is populated before hooks read flag values.
130
- 5. **Regenerate the OpenAPI SDK** after the backend exposes the new route: `cd your-frontend && bun run sdk`. Prefer **`useTerrenoFeatureFlags` / `useFeatureFlags`** over calling a generated `flagConfiguration` hook directly, so domain, cache keys, and optional socket refetch stay consistent.
141
+ ### Frontend (`@terreno/syncdb/flags` + OpenFeature)
142
+
143
+ 1. Replace the Terreno 57 `useFeatureFlags(terrenoApi, options)` with
144
+ `useFeatureFlags(options)` from `@terreno/syncdb/flags`. The result shape is unchanged:
145
+ `{flags, getFlag, getVariant, isLoading, error, refetch}`. The legacy string `basePath`
146
+ argument is gone; pass `{basePath}`.
147
+ 2. Replace `useTerrenoFeatureFlags(terrenoApi, {socket, ...})` with
148
+ `useTerrenoFeatureFlags({socket: syncDb, ...})`. `socket` is now your `SyncDb` client, not a
149
+ Socket.io client, and defaults to the `SyncDbProvider` client.
150
+ 3. Drop `useSocketConnection` and `useRealtimeDebug`. Listen for other server events with
151
+ `useSocketEvent` from `@terreno/syncdb/react` (see
152
+ [WebSocket integration](./websocket-integration.md)).
153
+ 4. Keep `@openfeature/web-sdk` and `@openfeature/react-sdk` in the app (`catalog:` versions) and
154
+ wrap the UI that reads flags in `<OpenFeatureProvider domain="feature-flags">`.
155
+ 5. Mount the hooks under `ApiClientProvider`, or pass `client`.
131
156
 
132
157
  ### Further reading
133
158
 
@@ -173,7 +173,8 @@ exactly one administered organization may omit it; Terreno infers that org.
173
173
  Operators and superadmins must select an org.
174
174
 
175
175
  Frontend admin hosts use `OrgContextProvider` + `OrgSwitcher`.
176
- `useAdminApi` adds the selected organization header automatically.
176
+ `useAdminModelApi` and the built-in admin screens add the selected organization
177
+ header automatically.
177
178
 
178
179
  Disabled organizations are excluded from `/orgs/mine` and cannot be selected as
179
180
  tenant context. Operators re-enable them from the organization directory UI or
@@ -25,8 +25,14 @@ Built-in IDs include `modelStats`, `modelsGrid`, `scriptRunner`, `versionConfig`
25
25
  For an app-specific widget, implement `AdminHomeWidgetProps` and register it:
26
26
 
27
27
  ```tsx
28
- <AdminProvider widgets={{home: {operationsSummary: OperationsSummary}}} api={api}>
29
- <AdminHome api={api} />
28
+ <AdminProvider
29
+ apiBase="/admin"
30
+ apiOrigin={baseUrl}
31
+ getAuthHeaders={getAdminAuthHeaders}
32
+ routeBase="/admin"
33
+ widgets={{home: {operationsSummary: OperationsSummary}}}
34
+ >
35
+ <AdminHome />
30
36
  </AdminProvider>
31
37
  ```
32
38
 
@@ -33,7 +33,6 @@ const RichTextWidget: React.FC<AdminFieldWidgetProps> = ({
33
33
 
34
34
  ```tsx
35
35
  <AdminProvider
36
- api={api}
37
36
  apiBase="/admin"
38
37
  routeBase="/admin"
39
38
  widgets={{fields: {"rich-text": RichTextWidget}}}
@@ -248,9 +248,9 @@ use uploads, or lower the per-file cap with `asks: {maxFileSizeBytes: 5_000_000}
248
248
  <GPTChat resolveAskFiles={resolveAskFiles} {...chatProps} />;
249
249
  ```
250
250
 
251
- `postFilesUpload` is an RTK Query mutation in `example-frontend/store/sdk.ts` whose body is a
252
- `FormData` with a `file` part; the base query sends it with the session token. The generated
253
- SDK has no file endpoints, because `/files/*` exists only on a server with a bucket.
251
+ `usePostFilesUploadMutation` is a generated hook in `example-frontend/store/apiSdk.ts` whose
252
+ body is a `FormData` with a `file` part; the request client sends it with the session token.
253
+ `/files/*` exists only on a server with a bucket.
254
254
  `createAskFileUploader` (in `gptAsks.ts`) returns `undefined` on 404, the upload's `id` and
255
255
  `size` on success, and throws with the server's detail otherwise (such as 401 when the session
256
256
  has ended), so the ask stays open. See `example-frontend/app/(tabs)/ai.tsx`.
@@ -297,9 +297,9 @@ answer as two rows, and ratings are sent by message index.
297
297
 
298
298
  A turn can stream only `{done}`, for example when the server cancels a second ask because one is
299
299
  already pending. Reload the conversation with `GET /gpt/histories/:id` when a turn streamed nothing
300
- visible, or when `done.pendingAsk` names an ask the stream did not send. The `@terreno/rtk` base
301
- query returns the `data` of single-document responses, so an RTK query for that route resolves to
302
- the history itself, not `{data}` (see [emptyApi](../reference/legacy/rtk.md#emptyapi--emptysplitapi)).
300
+ visible, or when `done.pendingAsk` names an ask the stream did not send. The `@terreno/syncdb/api`
301
+ request client unwraps the `data` of single-document responses, so `apiClient.request` for that
302
+ route resolves to the history itself, not `{data}` (see [API client](../reference/syncdb.md#api-client)).
303
303
 
304
304
  Refetch the history list after a turn that streams ask events or reloads the conversation. The
305
305
  example app reopens a conversation from the list's cached rows, which still hold the pending ask.
@@ -25,7 +25,6 @@ Embedded app (`example-frontend`):
25
25
  const syncConflicts = useConflicts();
26
26
 
27
27
  <AdminProvider
28
- api={api}
29
28
  apiBase="/admin"
30
29
  apiOrigin={baseUrl}
31
30
  getAuthHeaders={getAdminAuthHeaders}
@@ -35,7 +34,6 @@ const syncConflicts = useConflicts();
35
34
  widgets={{screens: {"sync-lab": SyncLabScreen}}}
36
35
  >
37
36
  <AdminShellLayout
38
- api={api}
39
37
  apiBase="/admin"
40
38
  configurationPath="/admin/configuration"
41
39
  rolesPath="/roles"
@@ -53,8 +51,8 @@ store name and `windowCollections` set; do not mix admin rows into the owner/ten
53
51
  product store. Start that client after `canOpenAdminPage` succeeds, block the admin
54
52
  shell until `start()` resolves, and call `stop()` when the admin layout unmounts.
55
53
 
56
- Gate entry with `canOpenAdminPage` from `@terreno/rtk` (`admin:access`). Do not
57
- rely on `user.admin` alone when RBAC is on. Import `baseUrl` from `@terreno/rtk`
54
+ Gate entry with `canOpenAdminPage` from `@terreno/syncdb/app` (`admin:access`). Do not
55
+ rely on `user.admin` alone when RBAC is on. Import `baseUrl` from `@terreno/syncdb/config`
58
56
  and pass it as `apiOrigin` so admin RPC (`GET /admin/config`, `/rbac/roles`, …)
59
57
  hits the API instead of the Expo web origin.
60
58
 
@@ -123,11 +121,15 @@ for those paths. Otherwise `[model]/[id]` treats the id as a generic document.
123
121
 
124
122
  ## 5. Fetch data the admin way
125
123
 
124
+ - Every admin request goes through the `AdminProvider` fetch client. Admin
125
+ components take no `api` prop.
126
126
  - String-`_id` collections configured with `adminBroadcast` use windowed syncdb
127
- when the host passes `syncDb` plus fetch auth.
128
- - ObjectId model CRUD and API-only hosts keep `useAdminApi`.
129
- - Bulk patch remains server-side: native admin fetch for windowed hosts, RTK fallback otherwise.
130
- - Admin RPC uses the host-bound native fetch client. Do not add axios.
127
+ when the host passes `syncDb`.
128
+ - ObjectId and API-only models use fetch CRUD. Custom screens call
129
+ `useAdminModelApi(routePath, modelName)` for list/read/create/update/delete.
130
+ - Bulk patch stays server-side at `{routePath}/bulk-patch` for every model.
131
+ - Custom admin RPC uses `useAdminRpc` + `useAdminRpcQuery` / `useAdminRpcMutation`.
132
+ Do not add axios or a second request client.
131
133
 
132
134
  ## 6. Sidebar and grouping
133
135
 
@@ -26,7 +26,7 @@ bun expo export --platform web
26
26
 
27
27
  ### Alternative: `app.json` `extra.BASE_URL`
28
28
 
29
- `@terreno/rtk` resolves the API base from `expo-constants` `extra.BASE_URL` and `EXPO_PUBLIC_API_URL` (see `rtk/src/constants.ts` `resolveBaseUrls`). Priority in **production** builds:
29
+ `@terreno/syncdb/config` resolves the API base from `expo-constants` `extra.BASE_URL` and `EXPO_PUBLIC_API_URL` (see `syncdb/src/config/resolveBaseUrls.ts`). Priority in **production** builds:
30
30
 
31
31
  1. `EXPO_PUBLIC_API_URL` environment variable (set before export)
32
32
  2. `extra.BASE_URL` in app config (when env var is unset)
@@ -10,7 +10,7 @@ How to talk to third-party HTTP APIs (payment processors, health integrations, m
10
10
  | Calling an external service through its own SDK (Twilio, Google APIs, Stripe) | `withApiErrorHandling` around the SDK calls — the SDK owns transport, you standardize failures |
11
11
  | Logging or classifying a caught error from any external call | `normalizeApiError` |
12
12
  | Surfacing an external failure to your API's consumers from a route handler | `withApiErrorHandling` with `rethrowAs: "apiError"` |
13
- | Making internal requests to your own `@terreno/api` backend | None of these — use `@terreno/rtk` on the frontend or direct function calls on the backend |
13
+ | Making internal requests to your own `@terreno/api` backend | None of these — use the generated `store/apiSdk.ts` hooks (`@terreno/syncdb/api` request client) or syncdb collection hooks on the frontend, or direct function calls on the backend |
14
14
 
15
15
  **Rule of thumb:** any file that would otherwise contain `axios.create(...)` plus a token variable plus a `try/catch → axios.isAxiosError → log → throw` block should use these utilities instead.
16
16
 
@@ -92,7 +92,7 @@ Note the hook's output classification also feeds the client's retry decision —
92
92
 
93
93
  ## When not to use this
94
94
 
95
- - **Your own backend's routes** — use the generated `@terreno/rtk` SDK (frontend) or call the function directly (backend).
95
+ - **Your own backend's routes** — use syncdb collection hooks or the generated `store/apiSdk.ts` hooks (frontend) or call the function directly (backend).
96
96
  - **SDK-managed transport** (Twilio, googleapis) — don't fight the SDK's HTTP layer; adopt only `normalizeApiError`/`withApiErrorHandling` for consistent failure handling.
97
97
  - **Webhook notifiers** — `sendToSlack`/`sendToGoogleChat`/`sendToZoom` post to a fixed webhook. Slack channel creation, invites, and bot posts use `createSlackPrivateChannel`, `inviteSlackUsersToChannel`, and `postSlackMessage` with `SLACK_BOT_TOKEN`. See [Webhooks & Notifications](../reference/api.md#webhooks--notifications).
98
98
 
@@ -47,6 +47,13 @@ list pipelines on the slug above.
47
47
  | `.circleci/config.yml` | Setup workflow + `path-filtering` (this is the live config) |
48
48
  | `.circleci/continue-config.yml` | Real jobs/workflows gated by those params |
49
49
 
50
+ ## Bun version is pinned
51
+
52
+ `install_bun_and_deps` pins Bun with `node/install-bun` `version`. Bun 1.4.4 reports
53
+ lower line coverage than 1.4.2 for the same tests, which fails the 95% package
54
+ coverage gates. Bump the pin together with the local toolchain and re-run
55
+ `bun run test:coverage` in each package first.
56
+
50
57
  ## Bun install is uncached
51
58
 
52
59
  `install_bun_and_deps` runs `bun install --frozen-lockfile` with
@@ -87,8 +94,8 @@ The example-backend Docker job runs only when its image recipe changes
87
94
  (`Dockerfile`, `.dockerignore`, package manifests, or `bun.lock`). API/source
88
95
  changes are covered by preview CD builds and do not start a duplicate image job.
89
96
 
90
- UI, RTK, and admin-frontend changes do **not** start `example-backend-ci`.
91
- Those packages are covered by `ui-ci` / `rtk-ci` / `packages-ci` plus e2e and
97
+ UI, syncdb, and admin-frontend changes do **not** start `example-backend-ci`.
98
+ Those packages are covered by `ui-ci` / `syncdb-ci` / `packages-ci` plus e2e and
92
99
  admin-spa. `new-file-coverage` starts on package `src/` (and example app
93
100
  runtime paths including `example-frontend/components/`), not on every `*.ts`
94
101
  file in the repo (Playwright specs no longer compile the world). Package CI
@@ -169,13 +176,13 @@ non-PR branch builds.
169
176
  | Path (examples) | Parameter | PR job | `master` job |
170
177
  | --- | --- | --- | --- |
171
178
  | `demo/**`, `ui/**` | `run-deploy-demo` | `deploy-demo-preview` | `deploy-demo` |
172
- | `example-frontend/**`, `admin-frontend/**`, `rtk/**`, `ui/**`, `ai/**`, `blocks/**`, `syncdb/**`, `bun.lock` | `run-deploy-frontend` | `deploy-frontend-preview` | `deploy-frontend` |
179
+ | `example-frontend/**`, `admin-frontend/**`, `ui/**`, `ai/**`, `blocks/**`, `syncdb/**`, `bun.lock` | `run-deploy-frontend` | `deploy-frontend-preview` | `deploy-frontend` |
173
180
  | `docs/**`, `website/**` | `run-deploy-docs` | `deploy-docs-preview` | `deploy-docs` |
174
181
  | `example-backend/**`, `api/**`, `comms/**`, `jobs/**`, `admin-spa/**`, `feature-flags/**`, `announcements/**`, plus every frontend path above | `run-cd-backend` | `gcp-cd-preview` | `gcp-cd-prod` |
175
182
  | `terraform/**`, `infra/**` | `run-cd-terraform` | `gcp-cd-preview` | `gcp-cd-prod` |
176
183
  | `mcp-server/**`, `ui/**` | `run-cd-mcp` | _(none)_ | `gcp-cd-prod` (runs `mcp-server` `test:ci` first) |
177
184
 
178
- The backend image bundles the admin SPA (ui, rtk, admin-frontend, syncdb), so
185
+ The backend image bundles the admin SPA (ui, admin-frontend, syncdb), so
179
186
  those paths redeploy the backend too. Every frontend PR preview therefore gets
180
187
  an isolated `pr-N` backend: `deploy-frontend-preview` always points
181
188
  `EXPO_PUBLIC_API_URL` at it (the prod backend rejects preview CORS) and waits
@@ -283,7 +290,7 @@ ambient OIDC token for GCP impersonation.
283
290
  Branch protection must require the CircleCI job names below. Remove disabled
284
291
  GitHub check names or pull requests will wait for checks that can no longer run.
285
292
 
286
- Dedicated package jobs (`api-ci`, `ai-ci`, `blocks-ci`, `rtk-ci`, `ui-ci`, `syncdb-ci`,
293
+ Dedicated package jobs (`api-ci`, `ai-ci`, `blocks-ci`, `ui-ci`, `syncdb-ci`,
287
294
  `comms-ci`, `mcp-server-ci`, `admin-spa-ci`) run `bun run test:coverage`
288
295
  (`scripts/check-coverage.ts`, 95% functions and lines). Isolated `syncdb` tests
289
296
  are included by that script. Published packages without a dedicated workflow
@@ -305,7 +312,6 @@ the same commands through the parameterized `packages-ci` job, gated by
305
312
  | Admin frontend lint, compile, coverage | `packages-ci` (`admin-frontend`) |
306
313
  | Run all tests (AI CI) | `ai-ci` |
307
314
  | Lint, compile, and test blocks | `blocks-ci` |
308
- | RTK Lint and Build | `rtk-ci` |
309
315
  | Syncdb Lint, Build, and Tests | `syncdb-ci` |
310
316
  | UI Lint, Build, Types, and Tests + demo typecheck | `ui-ci` |
311
317
  | Demo Lint and TypeScript Check | `ui-demo-ci` (demo-only PRs) |