@terreno/mcp 57.8.0 → 57.10.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 (115) hide show
  1. package/dist/docs/upgrades/57.10.1.md +54 -0
  2. package/dist/docs/upgrades/57.9.0.md +28 -0
  3. package/dist/docs/versioned/next/README.md +1 -0
  4. package/dist/docs/versioned/next/explanation/README.md +4 -0
  5. package/dist/docs/versioned/next/explanation/admin-plugin-frontend.md +2 -2
  6. package/dist/docs/versioned/next/explanation/agent-ui-asks.md +299 -0
  7. package/dist/docs/versioned/next/explanation/agent-ui-blocks.md +67 -0
  8. package/dist/docs/versioned/next/explanation/ai-observability.md +101 -0
  9. package/dist/docs/versioned/next/explanation/charts.md +12 -0
  10. package/dist/docs/versioned/next/explanation/durable-agent-harness.md +531 -0
  11. package/dist/docs/versioned/next/explanation/example-coverage.md +4 -2
  12. package/dist/docs/versioned/next/explanation/loop-engineering.md +1 -1
  13. package/dist/docs/versioned/next/explanation/roadmap-seed-issues.md +49 -1
  14. package/dist/docs/versioned/next/explanation/typescript-configuration.md +1 -1
  15. package/dist/docs/versioned/next/explanation/versioning-policy.md +1 -1
  16. package/dist/docs/versioned/next/how-to/README.md +7 -1
  17. package/dist/docs/versioned/next/how-to/admin-import-prebuilt.md +1 -1
  18. package/dist/docs/versioned/next/how-to/agent-ui-asks.md +730 -0
  19. package/dist/docs/versioned/next/how-to/agent-ui-blocks.md +104 -0
  20. package/dist/docs/versioned/next/how-to/ai-feature-development.md +156 -0
  21. package/dist/docs/versioned/next/how-to/build-a-durable-workflow.md +232 -0
  22. package/dist/docs/versioned/next/how-to/charts-and-dashboards.md +7 -0
  23. package/dist/docs/versioned/next/how-to/circleci.md +9 -6
  24. package/dist/docs/versioned/next/how-to/compare-chart-rendered-snapshots.md +8 -0
  25. package/dist/docs/versioned/next/how-to/install-agent-skills.md +1 -1
  26. package/dist/docs/versioned/next/how-to/observe-llm-calls.md +197 -0
  27. package/dist/docs/versioned/next/how-to/run-tests-locally.md +2 -1
  28. package/dist/docs/versioned/next/how-to/ship-a-new-task-version.md +76 -0
  29. package/dist/docs/versioned/next/how-to/upgrade-terreno.md +1 -1
  30. package/dist/docs/versioned/next/implementationPlans/agent-ui-asks.md +688 -0
  31. package/dist/docs/versioned/next/implementationPlans/agent-ui-blocks.md +10 -6
  32. package/dist/docs/versioned/next/implementationPlans/ai-observability.md +475 -157
  33. package/dist/docs/versioned/next/implementationPlans/b2b-platform-program.md +1 -1
  34. package/dist/docs/versioned/next/implementationPlans/charts-and-dashboards.md +3 -2
  35. package/dist/docs/versioned/next/implementationPlans/dashboard-chart-parity.md +275 -0
  36. package/dist/docs/versioned/next/implementationPlans/durable-agent-harness.md +340 -0
  37. package/dist/docs/versioned/next/implementationPlans/terreno-langfuse-integration.md +1 -1
  38. package/dist/docs/versioned/next/reference/README.md +3 -0
  39. package/dist/docs/versioned/next/reference/admin-config.md +2 -0
  40. package/dist/docs/versioned/next/reference/admin-frontend.md +216 -0
  41. package/dist/docs/versioned/next/reference/agent-ui-asks.md +1059 -0
  42. package/dist/docs/versioned/next/reference/ai-harness.md +1881 -0
  43. package/dist/docs/versioned/next/reference/ai.md +283 -28
  44. package/dist/docs/versioned/next/reference/api.md +46 -0
  45. package/dist/docs/versioned/next/reference/blocks.md +178 -0
  46. package/dist/docs/versioned/next/reference/environment-variables.md +2 -1
  47. package/dist/docs/versioned/next/reference/feature-flags.md +1 -1
  48. package/dist/docs/versioned/next/reference/mcp-server.md +17 -0
  49. package/dist/docs/versioned/next/reference/test.md +11 -2
  50. package/dist/docs/versioned/next/reference/ui.md +418 -11
  51. package/dist/docs/versioned/next/tasks/agent-ui-asks.md +213 -0
  52. package/dist/docs/versioned/next/tasks/agent-ui-blocks.md +2 -1
  53. package/dist/docs/versioned/next/tasks/ai-observability.md +233 -104
  54. package/dist/docs/versioned/next/tasks/dashboard-chart-parity.md +145 -0
  55. package/dist/docs/versioned/next/tasks/durable-agent-harness.md +183 -0
  56. package/dist/tools.d.ts +4 -0
  57. package/dist/tools.d.ts.map +1 -1
  58. package/dist/tools.js +37 -0
  59. package/dist/tools.js.map +1 -1
  60. package/package.json +3 -2
  61. package/src/docs/upgrades/57.10.1.md +54 -0
  62. package/src/docs/upgrades/57.9.0.md +28 -0
  63. package/src/docs/versioned/next/README.md +1 -0
  64. package/src/docs/versioned/next/explanation/README.md +4 -0
  65. package/src/docs/versioned/next/explanation/admin-plugin-frontend.md +2 -2
  66. package/src/docs/versioned/next/explanation/agent-ui-asks.md +299 -0
  67. package/src/docs/versioned/next/explanation/agent-ui-blocks.md +67 -0
  68. package/src/docs/versioned/next/explanation/ai-observability.md +101 -0
  69. package/src/docs/versioned/next/explanation/charts.md +12 -0
  70. package/src/docs/versioned/next/explanation/durable-agent-harness.md +531 -0
  71. package/src/docs/versioned/next/explanation/example-coverage.md +4 -2
  72. package/src/docs/versioned/next/explanation/loop-engineering.md +1 -1
  73. package/src/docs/versioned/next/explanation/roadmap-seed-issues.md +49 -1
  74. package/src/docs/versioned/next/explanation/typescript-configuration.md +1 -1
  75. package/src/docs/versioned/next/explanation/versioning-policy.md +1 -1
  76. package/src/docs/versioned/next/how-to/README.md +7 -1
  77. package/src/docs/versioned/next/how-to/admin-import-prebuilt.md +1 -1
  78. package/src/docs/versioned/next/how-to/agent-ui-asks.md +730 -0
  79. package/src/docs/versioned/next/how-to/agent-ui-blocks.md +104 -0
  80. package/src/docs/versioned/next/how-to/ai-feature-development.md +156 -0
  81. package/src/docs/versioned/next/how-to/build-a-durable-workflow.md +232 -0
  82. package/src/docs/versioned/next/how-to/charts-and-dashboards.md +7 -0
  83. package/src/docs/versioned/next/how-to/circleci.md +9 -6
  84. package/src/docs/versioned/next/how-to/compare-chart-rendered-snapshots.md +8 -0
  85. package/src/docs/versioned/next/how-to/install-agent-skills.md +1 -1
  86. package/src/docs/versioned/next/how-to/observe-llm-calls.md +197 -0
  87. package/src/docs/versioned/next/how-to/run-tests-locally.md +2 -1
  88. package/src/docs/versioned/next/how-to/ship-a-new-task-version.md +76 -0
  89. package/src/docs/versioned/next/how-to/upgrade-terreno.md +1 -1
  90. package/src/docs/versioned/next/implementationPlans/agent-ui-asks.md +688 -0
  91. package/src/docs/versioned/next/implementationPlans/agent-ui-blocks.md +10 -6
  92. package/src/docs/versioned/next/implementationPlans/ai-observability.md +475 -157
  93. package/src/docs/versioned/next/implementationPlans/b2b-platform-program.md +1 -1
  94. package/src/docs/versioned/next/implementationPlans/charts-and-dashboards.md +3 -2
  95. package/src/docs/versioned/next/implementationPlans/dashboard-chart-parity.md +275 -0
  96. package/src/docs/versioned/next/implementationPlans/durable-agent-harness.md +340 -0
  97. package/src/docs/versioned/next/implementationPlans/terreno-langfuse-integration.md +1 -1
  98. package/src/docs/versioned/next/reference/README.md +3 -0
  99. package/src/docs/versioned/next/reference/admin-config.md +2 -0
  100. package/src/docs/versioned/next/reference/admin-frontend.md +216 -0
  101. package/src/docs/versioned/next/reference/agent-ui-asks.md +1059 -0
  102. package/src/docs/versioned/next/reference/ai-harness.md +1881 -0
  103. package/src/docs/versioned/next/reference/ai.md +283 -28
  104. package/src/docs/versioned/next/reference/api.md +46 -0
  105. package/src/docs/versioned/next/reference/blocks.md +178 -0
  106. package/src/docs/versioned/next/reference/environment-variables.md +2 -1
  107. package/src/docs/versioned/next/reference/feature-flags.md +1 -1
  108. package/src/docs/versioned/next/reference/mcp-server.md +17 -0
  109. package/src/docs/versioned/next/reference/test.md +11 -2
  110. package/src/docs/versioned/next/reference/ui.md +418 -11
  111. package/src/docs/versioned/next/tasks/agent-ui-asks.md +213 -0
  112. package/src/docs/versioned/next/tasks/agent-ui-blocks.md +2 -1
  113. package/src/docs/versioned/next/tasks/ai-observability.md +233 -104
  114. package/src/docs/versioned/next/tasks/dashboard-chart-parity.md +145 -0
  115. package/src/docs/versioned/next/tasks/durable-agent-harness.md +183 -0
@@ -0,0 +1,178 @@
1
+ # UI blocks
2
+
3
+ `@terreno/blocks` checks the YAML (or JSON) document an agent uses when a chat reply is
4
+ components instead of prose. Ask schemas are in [Agent UI Asks](agent-ui-asks.md). Validate a
5
+ file locally with [the blocks how-to](../how-to/agent-ui-blocks.md).
6
+
7
+ ## Document
8
+
9
+ A reply is one mapping. Keys, when present, are in this order: `v`, `datasets`, `blocks`.
10
+
11
+ ```yaml
12
+ v: 1
13
+ blocks:
14
+ - type: text
15
+ markdown: I could not find any signups for that range.
16
+ ```
17
+
18
+ `parseBlocks` strips one surrounding ` ```yaml ` fence, parses YAML 1.2 core schema or JSON,
19
+ and rejects anchors, aliases, and explicit tags (`YAML_FEATURE_DISALLOWED`). A value that is
20
+ not a mapping with `v` is `NOT_A_DOCUMENT`. Callers display that reply with
21
+ `wrapAsTextDocument`, which builds `{v: 1, blocks: [{type: text, markdown}]}`.
22
+
23
+ ## Datasets
24
+
25
+ A dataset name matches `^[a-z][a-z0-9_]{0,63}$`. A document has at most 8 datasets.
26
+
27
+ | Source | Fields | Rule |
28
+ | --- | --- | --- |
29
+ | inline | `columns`: `{name, type}` where `type` is `string`, `number`, or `date`; `rows`: arrays | At most 500 rows and 12 columns. Each row has one value per column. `source: inline` is optional. |
30
+ | ref | `source: ref`, `id`, optional `grain` (`hour`, `day`, `week`, `month`), optional `limit` | `limit` above 1,000 is `TOO_MANY_POINTS`. Set `grain` to a coarser bucket. Column checks run when `knownDatasets` is passed. |
31
+
32
+ ## Charts and tables
33
+
34
+ | Block | Required | Optional |
35
+ | --- | --- | --- |
36
+ | `chart` | `kind`: `line`, `bar`, `area`, `donut`, and either `data` + `x` + `y` or `points` (`{label, value}`) | `id`, `title`, `legend`, `emptyText`, `height`: `sm`, `md`, `lg` |
37
+ | `table` | `data` (dataset name) | `id`, `columns` (names), `title` |
38
+
39
+ `x` is a string or date column. `y` is a number column. A table lists at most 12 columns.
40
+
41
+ ## HTML
42
+
43
+ | Block | Required | Optional |
44
+ | --- | --- | --- |
45
+ | `html` | `html` (at most 100,000 bytes) | `id`, `title`, `height`: `sm`, `md`, `lg` |
46
+
47
+ `validateBlocks` returns `HTML_DISABLED` unless `options.allowHtml` is true. A host turns that on with `uiBlocks.html`. The server sanitizes the HTML before it is stored. The client renders it only when `allowHtml` is set.
48
+
49
+ ## Callout, image, and details
50
+
51
+ | Block | Required | Optional |
52
+ | --- | --- | --- |
53
+ | `callout` | `text` | `id`, `status`: `info`, `warning`, `alert` |
54
+ | `image` | `alt`, `src` | `id` |
55
+ | `details` | `title`, `text` | `id` |
56
+
57
+ `src` is a `data:image` URL, a `file:` ref (`file:` plus an id), or an `https` URL. `https` is allowed only when the hostname is in `validateBlocks` `imageHosts` (the server option is `uiBlocks.imageHosts`). Anything else is `IMAGE_HOST_NOT_ALLOWED`. An empty list rejects every `https` image. A ref dataset `id` uses 1–80 letters, digits, underscores, or hyphens. A block or action-element `id` stays lowercase and starts with a letter. `limit` of `0` is `INVALID_TYPE` (an integer of at least 1), not `TOO_SHORT`.
58
+
59
+ Warnings do not block rendering:
60
+
61
+ | Code | When |
62
+ | --- | --- |
63
+ | `BAR_TOO_MANY_CATEGORIES` | A bar chart would draw more than 60 categories. |
64
+ | `DONUT_TOO_MANY_SLICES` | A donut chart would draw more than 8 slices. |
65
+ | `LINE_SINGLE_POINT` | A line chart has one point. |
66
+
67
+ ## Blocks
68
+
69
+ | Block | Required | Optional | Renders as |
70
+ | --- | --- | --- | --- |
71
+ | `heading` | `text` (1–200) | `size`: `sm`, `md`, `lg`, `xl`, `2xl`; `id` | `Heading` |
72
+ | `text` | `markdown` (1–4,000) | `id` | `MarkdownView` |
73
+ | `metric` | `label` (1–80), `value` (1–80) | `delta` (1–40), `trend`: `up`, `down`, `flat`, `helper` (1–120), `id` | `Card` |
74
+ | `badge` | `text` (1–80) | `status`: `info`, `error`, `warning`, `success`, `neutral`, `active`; `id` | `Badge` |
75
+ | `divider` | — | `id` | `SectionDivider` |
76
+ | `context` | `text` (1–280) | `id` | `Text` |
77
+ | `columns` | `children`: 2–4 blocks | `id` | `Box` row |
78
+ | `card` | `children`: at least 1 block | `title` (1–120), `id` | `Card` |
79
+
80
+ `columns` and `card` sit at the top level. Their children are leaf blocks. A layout block
81
+ inside another layout block is `DEPTH_EXCEEDED`. Every block counts toward the 50-block
82
+ cap, including the `card` or `columns` block itself, so a card cannot hold 50 children.
83
+
84
+ `id` matches `^[a-z][a-z0-9_]{0,63}$`.
85
+
86
+ ## Actions
87
+
88
+ An `actions` block requires `id` and `elements` (1–25). An element is a `button` or a
89
+ `segmented` control.
90
+
91
+ | Element | Required | Optional |
92
+ | --- | --- | --- |
93
+ | `button` | `id`, `text` (1–80), `action` | `variant`: `primary`, `secondary`, `outline`, `ghost`, `destructive`; `iconName` |
94
+ | `segmented` | `id`, `target` (a chart or table `id`), `options` (2–8 of `{label, data}`) | — |
95
+
96
+ `action.kind` is `reply` (`text`), `open` (`url` or `route`, exactly one), `select`
97
+ (`target` plus `data`), or `callback` (`name` plus optional `payload`). A `select` target
98
+ that is not a chart or table `id` is `SELECT_TARGET_INVALID`. When `validateBlocks` is
99
+ called with `hostActions`, a callback `name` outside that list is `UNKNOWN_HOST_ACTION`.
100
+ Omitting `hostActions` skips that check.
101
+
102
+ ## Partial parsing
103
+
104
+ `parseBlocksPartial(text)` never throws. A document that `validateBlocks` accepts returns
105
+ `{datasets, blocks, pending: false}`. A cut reply returns only the top-level blocks whose
106
+ next `- ` already arrived, drops the unfinished tail, and sets `pending: true`. `datasets`
107
+ is present only after the `blocks:` key has started and the prefix parses.
108
+
109
+ ## CLI
110
+
111
+ `terreno-blocks validate <file | ->` prints each problem as `path CODE message — fix` and
112
+ exits 1. A valid document exits 0. Warnings are printed and still exit 0.
113
+
114
+ Unknown fields fail with `UNKNOWN_KEY`. `v` must be `1` (`UNSUPPORTED_VERSION`).
115
+
116
+ ## Limits
117
+
118
+ | Limit | Value |
119
+ | --- | --- |
120
+ | Blocks in one document, including nested blocks | 50 |
121
+ | Nesting | 2 (`blocks` → `columns` or `card` → leaf) |
122
+ | `columns` children | 2–4 |
123
+ | Elements in one `actions` block | 25 |
124
+ | Text in one `text` block | 4,000 characters |
125
+ | Document version | 1 |
126
+
127
+ ## Errors
128
+
129
+ `validateBlocks` returns `{ok: true, doc, warnings}` or `{ok: false, errors, warnings}`.
130
+ Each error is `{path, code, message, fix}`, sorted by path. `warnings` lists chart
131
+ heuristics and does not fail `ok`.
132
+
133
+ | Code | Meaning |
134
+ | --- | --- |
135
+ | `COLUMN_NOT_FOUND` | A chart or table names a column the dataset does not have. |
136
+ | `COLUMN_TYPE_MISMATCH` | A column value, or a chart axis, does not match the column type. |
137
+ | `DATASET_NOT_FOUND` | A chart or table names a dataset the document does not define. |
138
+ | `DATASET_TOO_LARGE` | A dataset has more than 500 rows or 12 columns. |
139
+ | `DEPTH_EXCEEDED` | A `columns` or `card` block is nested inside another layout block. |
140
+ | `DUPLICATE_ID` | A block id, an action-element id, or a column name is used more than once. |
141
+ | `HTML_DISABLED` | An html block is present and this host has not turned HTML on. |
142
+ | `HTML_TOO_LARGE` | An html block is larger than 100,000 bytes. |
143
+ | `IMAGE_HOST_NOT_ALLOWED` | An image URL is not a `data:image` URL, a `file:` ref, or an `https` URL on an allowed host. |
144
+ | `INVALID_ENUM` | A value is not one of the allowed values. |
145
+ | `INVALID_FORMAT` | A string does not match its required format. |
146
+ | `INVALID_TYPE` | A value has the wrong type, including a numeric field below its minimum. |
147
+ | `KEY_ORDER` | Top-level keys are not in the order `v`, `datasets`, `blocks`. |
148
+ | `MISSING_REQUIRED` | A required field is missing. |
149
+ | `NOT_A_DOCUMENT` | The reply is not one YAML or JSON mapping with a `v` field. |
150
+ | `SELECT_TARGET_INVALID` | A select action names a block that is not a chart or table. |
151
+ | `ROW_ARITY_MISMATCH` | A dataset row does not have one value per column. |
152
+ | `TABLE_TOO_WIDE` | A table lists more than 12 columns. |
153
+ | `TOO_FEW` | A list has fewer items than allowed. |
154
+ | `TOO_LONG` | A string is longer than allowed. |
155
+ | `TOO_MANY` | A list has more items than allowed. |
156
+ | `TOO_MANY_BLOCKS` | The document has more than 50 blocks. |
157
+ | `TOO_MANY_POINTS` | A ref dataset `limit` is above 1,000. |
158
+ | `TOO_SHORT` | A string is empty or only whitespace. |
159
+ | `UNKNOWN_HOST_ACTION` | A callback names a host action that is not registered. |
160
+ | `UNKNOWN_KEY` | An object has a field that its schema does not define. |
161
+ | `UNSUPPORTED_VERSION` | `v` is not 1. |
162
+ | `YAML_FEATURE_DISALLOWED` | The document uses a YAML anchor, alias, or explicit tag. |
163
+
164
+ ## Exports
165
+
166
+ | Export | Role |
167
+ | --- | --- |
168
+ | `parseBlocks(text)` | Fence strip, YAML or JSON parse |
169
+ | `parseBlocksPartial(text)` | Completed top-level blocks while a reply is still streaming |
170
+ | `validateBlocks(doc, options?)` | Structure, then dataset, chart, table, action, and html lint. `options.knownDatasets` checks `ref` columns. `options.hostActions` checks callback names. `options.allowHtml` allows `html` blocks. |
171
+ | `wrapAsTextDocument(text)` | Display fallback for a non-document |
172
+ | `blocksSchema` | Zod schema |
173
+ | `blocksJsonSchema` | JSON Schema for the same structure |
174
+ | `blocksPromptSection({hostActions, allowHtml})` | System-prompt section. Limits come from `BLOCK_LIMITS`. `allowHtml` adds the `html` block. |
175
+ | `BLOCK_LIMITS` | The numbers in the table above |
176
+ | `BLOCK_ERROR_CODES` | The codes in the table above |
177
+ | `BLOCK_WARNING_CODES` | `BAR_TOO_MANY_CATEGORIES`, `DONUT_TOO_MANY_SLICES`, `LINE_SINGLE_POINT` |
178
+ | `HTML_HEIGHTS`, `CALLOUT_STATUSES` | Allowed `html` heights and `callout` statuses. `HtmlBlock`, `CalloutBlock`, `ImageBlock`, and `DetailsBlock` are type exports. |
@@ -23,6 +23,7 @@ Comprehensive guide to environment variables used across Terreno packages and ex
23
23
  | `TERRENO_TEST_MONGODB_URI` | `@terreno/test` | ❌ | auto | Yes | tooling |
24
24
  | `TERRENO_TEST_USE_MEMORY_MONGO` | `@terreno/test` | ❌ | — | No | tooling |
25
25
  | `TERRENO_TEST_USE_REPLSET` | `@terreno/test` | ❌ | — | No | tooling |
26
+ | `TERRENO_TEST_MONGO_LAUNCH_TIMEOUT_MS` | `@terreno/test` | ❌ | `60000` | No | tooling |
26
27
  | `TERRENO_TEST_USE_FIXTURE_CACHE` | `@terreno/test` | ❌ | — | No | tooling |
27
28
  | `TERRENO_TEST_CACHE_DIR` | `@terreno/test` | ❌ | — | No | tooling |
28
29
  | `BUN_TEST_DISABLE_DB` | test harness | ❌ | — | No | tooling |
@@ -120,7 +121,7 @@ Resolution order for API base URL (`rtk/src/constants.ts`):
120
121
  | `GEMINI_API_KEY` | `@terreno/ai` | ❌ | — | Yes | server |
121
122
  | `OPENAI_API_KEY` | `@terreno/ai` | ❌ | — | Yes | server |
122
123
  | `GOOGLE_VERTEX_PROJECT` | `@terreno/ai` | ❌ | — | No | server |
123
- | `GOOGLE_VERTEX_LOCATION` | `@terreno/ai` | ❌ | — | No | server |
124
+ | `GOOGLE_VERTEX_LOCATION` | `@terreno/ai` | ❌ | `global` | No | server |
124
125
  | `GOOGLE_VERTEX_ALLOWED_MODELS` | `@terreno/ai` | ❌ | all | No | server |
125
126
  | `CLAUDE_KEY` | tooling | ❌ | — | Yes | tooling |
126
127
  | `LANGFUSE_SECRET_KEY` | `@terreno/ai` | ❌ | — | Yes | server |
@@ -63,7 +63,7 @@ New code can also use OpenFeature React hooks (`useBooleanFlagValue`, `useString
63
63
 
64
64
  ## OpenFeature integration
65
65
 
66
- `FeatureFlagsApp` registers an OpenFeature **server** provider (`MongoFeatureFlagProvider`) on a dedicated domain (default `"feature-flags"`) so the global default provider is unchanged. The authenticated bulk endpoint **`GET {basePath}/flagConfiguration`** returns a `FlagConfiguration`-compatible map (suitable for `TypedInMemoryProvider` on the client). The legacy **`GET {basePath}/evaluate`** response shape is unchanged but is **deprecated**: responses include `Deprecation: true` and a `Sunset` HTTP-date header (~90 days). Prefer `useTerrenoFeatureFlags` / `useFeatureFlags` from `@terreno/rtk`, or migrate direct HTTP callers to `/flagConfiguration`.
66
+ `FeatureFlagsApp` registers an OpenFeature **server** provider (`MongoFeatureFlagProvider`) on a dedicated domain (default `"feature-flags"`) so the global default provider is unchanged. The authenticated bulk endpoint **`GET {basePath}/flagConfiguration`** returns a `FlagConfiguration`-compatible map (suitable for `TypedInMemoryProvider` on the client). Disabled **boolean** flags are included and resolve to `off`, so a client can tell a turned-off flag from one that was never created. Disabled variant flags and archived flags are omitted. The legacy **`GET {basePath}/evaluate`** response shape is unchanged but is **deprecated**: responses include `Deprecation: true` and a `Sunset` HTTP-date header (~90 days). Prefer `useTerrenoFeatureFlags` / `useFeatureFlags` from `@terreno/rtk`, or migrate direct HTTP callers to `/flagConfiguration`.
67
67
 
68
68
  ### `defaultVariant` on `FeatureFlag`
69
69
 
@@ -391,6 +391,23 @@ Validate a Mongoose schema against Terreno conventions.
391
391
  - Recommendations for fixes
392
392
  - Severity levels (error, warning, info)
393
393
 
394
+ ### terreno_validate_ui_blocks
395
+
396
+ Check one whole-reply YAML or JSON document. The text is the same report `terreno-blocks validate` prints: each problem is `path CODE message — fix`. A valid document with no warnings returns an empty string.
397
+
398
+ **Parameters:**
399
+
400
+ ``````typescript
401
+ {
402
+ document: string; // Required — the YAML or JSON document
403
+ }
404
+ ``````
405
+
406
+ **Returns:**
407
+
408
+ - The CLI report, including a trailing newline when there is at least one line
409
+ - An empty string when the document is valid and has no warnings
410
+
394
411
  ### terreno_bootstrap_ai_rules
395
412
 
396
413
  Scaffold AI coding assistant rules (AGENTS.md, Cursor/Windsurf rules, Copilot instructions, rulesync config).
@@ -79,10 +79,14 @@ Defaults: `TOKEN_SECRET`, `TOKEN_ISSUER`, `REFRESH_TOKEN_SECRET`, `SESSION_SECRE
79
79
  |----------|--------|
80
80
  | `TERRENO_TEST_USE_MEMORY_MONGO` | When `"true"`, `registerSimpleMongoPreload` starts `mongodb-memory-server` if `TERRENO_TEST_MONGODB_URI` is unset. |
81
81
  | `TERRENO_TEST_MONGODB_URI` | External MongoDB URI. Takes priority over in-memory server in `startMongoServer` and `registerSimpleMongoPreload`. |
82
+ | `TERRENO_TEST_MONGO_LAUNCH_TIMEOUT_MS` | Per-mongod start timeout for in-memory servers started by `startMongoServer`. Default `60000` (mongodb-memory-server's own default is 10s). Startup is tried twice. |
82
83
  | `BUN_TEST_DISABLE_DB` | When `"true"`, `registerBackendPreload` skips all Mongo `beforeAll`/`afterAll` hooks (no DB startup). |
83
84
 
84
85
  `startMongoServer` also publishes the resolved URI to `TERRENO_TEST_MONGO_URI` and honors `TERRENO_TEST_USE_REPLSET=true` for replica-set memory servers.
85
86
 
87
+ If `registerBackendPreload` cannot start Mongo, every later test fails at once with
88
+ `MongoDB test server failed to start` instead of waiting on mongoose command buffering.
89
+
86
90
  ## Exported helpers
87
91
 
88
92
  | Export | Description |
@@ -92,6 +96,7 @@ Defaults: `TOKEN_SECRET`, `TOKEN_ISSUER`, `REFRESH_TOKEN_SECRET`, `SESSION_SECRE
92
96
  | `setTerrenoTestEnv` | Apply and validate auth test env vars. |
93
97
  | `startMongoServer` / `stopMongoServer` | Start or stop shared in-memory Mongo and connect mongoose. |
94
98
  | `getMongoServerUri` | Resolved URI after `startMongoServer`. |
99
+ | `resolveMongoLaunchTimeoutMs` | In-memory mongod launch timeout from `TERRENO_TEST_MONGO_LAUNCH_TIMEOUT_MS` (integer ≥ 1000), default 60000. |
95
100
  | `getBaseServer` | Build an Express app for supertest from route registrars. |
96
101
  | `authAsUser` | Login helper returning auth headers for supertest. |
97
102
  | `createMongoTestCache` | Fixture-cache controller for fast `@terreno/api` tests. |
@@ -112,8 +117,12 @@ Defaults: `TOKEN_SECRET`, `TOKEN_ISSUER`, `REFRESH_TOKEN_SECRET`, `SESSION_SECRE
112
117
  Package CI uses `scripts/check-coverage.ts` (`bun run test:coverage`, default 95%
113
118
  functions and lines) as the live gate. Bun 1.4.2+ may exit 1 on bunfig
114
119
  `coverageThreshold` before isolated LCOV merges; the script continues when tests
115
- reported `0 fail` and then enforces 95% on the merged report. Dedicated CircleCI
116
- jobs (`api-ci`, `ai-ci`,
120
+ reported `0 fail` and then enforces 95% on the merged report. The blocks
121
+ coverage pass sets `--max-concurrency=1`, because Bun's default 20-way run
122
+ exits 0 on a 2-vCPU worker before it prints the `All files` row. When that
123
+ row is still missing after one retry, the script uses `coverage/lcov.info`
124
+ only if it lists every non-test source file under `src/`. Dedicated CircleCI
125
+ jobs (`api-ci`, `ai-ci`, `blocks-ci`,
117
126
  `rtk-ci`, `ui-ci`, `syncdb-ci`, `comms-ci`, `mcp-server-ci`, `admin-spa-ci`) run
118
127
  that script. Published packages without a dedicated workflow
119
128
  (`admin-backend`, `admin-frontend`, `api-health`, `feature-flags`, `@terreno/test`)