@instruments/materialgraph 0.26.0 → 0.27.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 (113) hide show
  1. package/association-types.d.ts +18 -7
  2. package/attribution-types.d.ts +2 -2
  3. package/brand-types.d.ts +8 -0
  4. package/brands-client.d.ts +5 -36
  5. package/brands-client.js +7 -33
  6. package/by-colour-types.d.ts +40 -13
  7. package/by-spec-types.d.ts +0 -67
  8. package/by-spec-types.js +7 -5
  9. package/catalog-discovery-types.d.ts +1 -16
  10. package/catalogue-client.d.ts +12 -31
  11. package/catalogue-client.js +10 -46
  12. package/catalogue-types.d.ts +40 -0
  13. package/categories-client.d.ts +63 -0
  14. package/categories-client.js +48 -0
  15. package/category-types.d.ts +114 -0
  16. package/client-config.d.ts +2 -4
  17. package/client-config.js +2 -4
  18. package/client-vocabulary.d.ts +2 -4
  19. package/client-vocabulary.js +11 -9
  20. package/client.d.ts +103 -203
  21. package/client.js +126 -251
  22. package/codes-types.d.ts +21 -0
  23. package/colours-client.d.ts +4 -9
  24. package/colours-client.js +0 -8
  25. package/errors.d.ts +1 -1
  26. package/errors.js +1 -0
  27. package/identify-types.d.ts +49 -39
  28. package/identify-types.js +5 -3
  29. package/index.d.ts +11 -21
  30. package/index.js +4 -4
  31. package/list-variant-facets-types.d.ts +60 -0
  32. package/list-variants-types.d.ts +142 -0
  33. package/list-variants-types.js +12 -0
  34. package/match-stream-types.d.ts +13 -0
  35. package/match-stream-types.js +2 -0
  36. package/match-stream.js +12 -8
  37. package/match-types.d.ts +24 -0
  38. package/material-asset-types.d.ts +69 -49
  39. package/material-block-types.d.ts +2 -0
  40. package/material-composition-client.d.ts +21 -0
  41. package/material-composition-client.js +13 -0
  42. package/material-composition-types.d.ts +403 -0
  43. package/material-query-plan-types.d.ts +57 -141
  44. package/material-resources-client.d.ts +9 -7
  45. package/material-resources-client.js +19 -4
  46. package/material-types.d.ts +6 -14
  47. package/operations.d.ts +1 -1
  48. package/operations.js +20 -117
  49. package/package.json +5 -1
  50. package/palette-search-types.d.ts +59 -24
  51. package/query-understanding-types.d.ts +27 -5
  52. package/resolve-client.d.ts +6 -10
  53. package/resolve-client.js +5 -7
  54. package/response-schemas.d.ts +20 -0
  55. package/response-schemas.generated.d.ts +5 -0
  56. package/response-schemas.generated.js +160 -0
  57. package/response-schemas.js +113 -0
  58. package/run-types.d.ts +12 -93
  59. package/runs.d.ts +1 -37
  60. package/runs.js +2 -79
  61. package/schema-resource-types.d.ts +14 -1
  62. package/search-card-types.d.ts +22 -0
  63. package/search-index-plan-types.d.ts +70 -0
  64. package/search-refinement-types.d.ts +8 -38
  65. package/search-refinement-types.js +1 -0
  66. package/search-request-types.d.ts +117 -200
  67. package/search-response-receipt-types.d.ts +12 -268
  68. package/search-result-validation.d.ts +0 -16
  69. package/search-result-validation.js +22 -180
  70. package/spec-facet-types.d.ts +3 -8
  71. package/spec-types.d.ts +17 -10
  72. package/spec-types.js +8 -7
  73. package/specifications.d.ts +13 -55
  74. package/specifications.js +29 -73
  75. package/suggest-types.d.ts +4 -10
  76. package/suggest-types.js +1 -1
  77. package/types.d.ts +135 -338
  78. package/webmcp.d.ts +1 -1
  79. package/webmcp.generated.js +10 -94
  80. package/brand-most-sampled-types.d.ts +0 -33
  81. package/browse-types.d.ts +0 -236
  82. package/client-browse.d.ts +0 -78
  83. package/client-browse.js +0 -71
  84. package/client-exploration.d.ts +0 -9
  85. package/client-exploration.js +0 -5
  86. package/compare-types.d.ts +0 -89
  87. package/composition-client.d.ts +0 -33
  88. package/composition-client.js +0 -28
  89. package/composition-types.d.ts +0 -455
  90. package/composition-types.js +0 -10
  91. package/correction-types.d.ts +0 -88
  92. package/exploration-types.d.ts +0 -118
  93. package/exploration-types.js +0 -1
  94. package/fan-deck-types.d.ts +0 -42
  95. package/fan-deck-types.js +0 -9
  96. package/match-rejection-types.d.ts +0 -43
  97. package/match-rejection-types.js +0 -7
  98. package/palette-completion-types.d.ts +0 -115
  99. package/palette-completion-types.js +0 -1
  100. package/render-assets-types.d.ts +0 -65
  101. package/render-assets-types.js +0 -1
  102. package/search-collapse-types.d.ts +0 -69
  103. package/search-collapse-types.js +0 -1
  104. package/search-mood-types.d.ts +0 -6
  105. package/search-mood-types.js +0 -1
  106. package/search-window-types.d.ts +0 -25
  107. package/search-window-types.js +0 -1
  108. package/slot-pool-types.d.ts +0 -372
  109. package/slot-pool-types.js +0 -1
  110. /package/{brand-most-sampled-types.js → category-types.js} +0 -0
  111. /package/{browse-types.js → list-variant-facets-types.js} +0 -0
  112. /package/{compare-types.js → material-composition-types.js} +0 -0
  113. /package/{correction-types.js → search-index-plan-types.js} +0 -0
package/client.d.ts CHANGED
@@ -2,31 +2,29 @@ import type { ApplicabilityOptions, AssociatedOptions } from "./association-type
2
2
  import type { BrandsOptions } from "./brand-types.js";
3
3
  import type { ByColourParams, ByColourResponse } from "./by-colour-types.js";
4
4
  import { CatalogueClient } from "./catalogue-client.js";
5
+ import { CategoriesClient } from "./categories-client.js";
5
6
  import type { ResolvedVerdictCitation } from "./citation-types.js";
6
- import type { BrowseNamespace } from "./client-browse.js";
7
7
  import type { MaterialGraphClientOptions } from "./client-config.js";
8
- import type { ExplorationNamespace } from "./client-exploration.js";
9
8
  import type { SourceMaterialCommentsNamespace } from "./client-source-material-comments.js";
10
9
  import { CodesClient } from "./codes-client.js";
11
10
  import type { CodeAdvisoryInput, CodeAdvisoryResponse } from "./codes-types.js";
12
11
  import { ColoursClient } from "./colours-client.js";
13
- import type { VarySchemesRequest, VarySchemesResponse } from "./composition-types.js";
14
12
  import type { RateLimit } from "./errors.js";
15
13
  import type { BatchId, RunId, VariantId } from "./identifiers.js";
14
+ import type { ListVariantFacetsInput, ListVariantFacetsOutput } from "./list-variant-facets-types.js";
15
+ import type { ListVariantsInput, ListVariantsOutput } from "./list-variants-types.js";
16
16
  import type { MatchStreamEvent } from "./match-stream-types.js";
17
- import type { MatchInput, MatchResponse } from "./match-types.js";
18
- import type { MaterialDocumentPageOptions } from "./material-asset-types.js";
17
+ import type { MatchAnswer, MatchInput } from "./match-types.js";
18
+ import type { ListVariantAssetsOptions, MaterialDocumentPageOptions, VariantAssetPage } from "./material-asset-types.js";
19
+ import type { CompositionCorpusSummary } from "./material-composition-types.js";
19
20
  import type { MaterialQueryPlan } from "./material-query-plan-types.js";
20
21
  import { resolvePhrasesRequest as resolvePhrases } from "./resolve-client.js";
21
- import type { CapabilityManifestResponse, CreatePublicRunRequest, CreatePublicRunResponse, DrainRunEventsOptions, ListRunsOptions, PublicRunListResponse, PublicRunResponse, ResumeRunOptions, RunEvent, SourceMaterialBatchDetail, SourceMaterialBatchReceipt, StreamRunEventsOptions, UploadSourceMaterialInput } from "./run-types.js";
22
+ import type { CreatePublicRunRequest, CreatePublicRunResponse, DrainRunEventsOptions, PublicRunResponse, RunEvent, SourceMaterialBatchDetail, SourceMaterialBatchReceipt, StreamRunEventsOptions, UploadSourceMaterialInput } from "./run-types.js";
22
23
  import type { SchemaResource, SchemaResourceResponse } from "./schema-resource-types.js";
23
- import type { SlotPoolsRequest, SlotPoolsResponse } from "./slot-pool-types.js";
24
- import type { FindSubstitutesOptions, FindSubstitutesResponse } from "./substitute-types.js";
24
+ import type { CardProjectionRequest, SearchCardResponse } from "./search-card-types.js";
25
25
  import type { ProductTypeCoverageOptions, ProductTypeStatusCoverage } from "./taxonomy-coverage-types.js";
26
- import type { ApplicableSpecsResponse, BrandOptions, BySpecOptions, BySpecResponse, ColourFacetsResponse, CoordinateInput, CoordinateResponse, DemandBatchInput, DemandBatchResponse, DemandParams, DemandResponse, ExtractPaletteInput, ExtractPaletteResponse, GlossaryTermResponse, MaterialResponse, MaterialsBatchDetailResponse, MaterialsBatchGetOptions, MaterialsBatchOptions, MaterialsBatchTileResponse, PairingsOptions, PairingsResponse, ResolveAttributeOptions, ResolveAttributeResponse, ResolveAttributeValueOptions, ResolveAttributeValueResponse, ResolveColourOptions, ResolveColourResponse, SearchGetParams, SearchInput, SearchResponse, SiblingsResponse, SpecFacetsDistributionResponse, SpecFacetsListResponse, SuggestColourResponse, SuggestOptions, SuggestResponse, TaxonomyResponse, VocabularySearchOptions, WhoamiResponse } from "./types.js";
26
+ import type { CoordinateInput, CoordinateResponse, DemandBatchInput, DemandBatchResponse, DemandParams, DemandResponse, ExtractPaletteInput, ExtractPaletteResponse, ListAttributesOptions, ListAttributesResult, MaterialResponse, PairingsOptions, PairingsResponse, ResolveColourOptions, ResolveColourResponse, SearchGetParams, SearchInput, SearchResponse, SpecFacetsListResponse, SuggestColourResponse, SuggestOptions, SuggestResponse, VocabularySearchOptions, WhoamiResponse } from "./types.js";
27
27
  export * from "./client-config.js";
28
- export type { BrowseNamespace } from "./client-browse.js";
29
- export type { ExplorationNamespace } from "./client-exploration.js";
30
28
  export type { SourceMaterialCommentsNamespace } from "./client-source-material-comments.js";
31
29
  /**
32
30
  * The MaterialGraph client — every lens on the graph, on one object.
@@ -38,13 +36,13 @@ export type { SourceMaterialCommentsNamespace } from "./client-source-material-c
38
36
  * | --- | --- |
39
37
  * | "find me something like this / matching these words" | {@link MaterialGraphClient.search} |
40
38
  * | "what's IN this photo?" | {@link MaterialGraphClient.match} / {@link MaterialGraphClient.matchStream} |
41
- * | "which materials, from anyone, meet this hard spec?" | {@link MaterialGraphClient.bySpec} |
39
+ * | "which materials, from anyone, meet this hard spec?" | {@link MaterialGraphClient.listVariants} |
42
40
  * | "what's near this colour / this palette / this gradient?" | {@link MaterialGraphClient.byColour}, `colours.palette()`, `colours.gradient()` |
43
- * | "what goes with THIS material?" | {@link MaterialGraphClient.pairings}, {@link MaterialGraphClient.siblings}, {@link MaterialGraphClient.coordinate} |
41
+ * | "what goes with THIS material?" | {@link MaterialGraphClient.pairings}, {@link MaterialGraphClient.listVariants} (same product, other colourways), {@link MaterialGraphClient.coordinate} |
44
42
  * | "what does the manufacturer say is AVAILABLE on this?" | {@link MaterialGraphClient.associatedFinishes}, {@link MaterialGraphClient.associatedProducts} |
45
43
  * | "how much is this specified?" | {@link MaterialGraphClient.demand}, {@link MaterialGraphClient.demandBatch} |
46
44
  * | "is this allowed in an A-2 corridor?" | `codes.*` |
47
- * | "what can I even ask for?" | {@link MaterialGraphClient.specificationFacets}, {@link MaterialGraphClient.attributeValues}, {@link MaterialGraphClient.taxonomy}, {@link MaterialGraphClient.colourFacets}, {@link MaterialGraphClient.glossary} |
45
+ * | "what can I even ask for?" | {@link MaterialGraphClient.specificationFacets}, `categories.list()` |
48
46
  * | "I have words — what do they mean in YOUR vocabulary?" | {@link MaterialGraphClient.resolve} |
49
47
  * | "do the whole job for me, async" | {@link MaterialGraphClient.createRun} + `mg:compose` |
50
48
  *
@@ -67,30 +65,26 @@ export declare class MaterialGraphClient extends CatalogueClient {
67
65
  #private;
68
66
  readonly baseUrl: string;
69
67
  /**
70
- * THE QUESTION: "show me everything in this category / this brand, in a plain
71
- * order." No query, no relevance, no ranking. `browse(params)` is one page;
72
- * `browse.pages(params)` walks them all.
68
+ * THE QUESTION: "what kinds of thing exist, and what are their keys?"
69
+ * `categories.list()` pages the tree (roots, one node's children, or a
70
+ * name/meaning search), and `categories.get(id)` reads one node in full:
71
+ * its place, the names that find it, and the canonical taxonomy concepts it
72
+ * relates to. The source of every category id the other lenses accept
73
+ * (`search({ category })`, `listVariants({ filters })`, `colours.profiles()`).
73
74
  *
74
- * `sort` is optional (`name` A→Z by default, `recent` for newest first, plus
75
- * the five colour ramps), `types`/`brands`/`corpusScope` narrow it, and
76
- * `count: true` returns the total so a listing can say how many things it is
77
- * listing without walking every page. `results.length` remains a PAGE.
78
- *
79
- * Instead use {@link MaterialGraphClient.byColour} for materials NEAR a colour,
80
- * {@link MaterialGraphClient.search} when there is anything to rank against,
81
- * and `colours.profiles()` for a category's palette rather than its members.
82
- *
83
- * @example A category listing that can state its own size
84
- * const page = await client.browse({ types: "tile_surfaces", count: true });
75
+ * A category id is a TREE KEY, never a canonical `product_category` value:
76
+ * the two look alike and are not interchangeable. Discover ids here, never
77
+ * hand-write them. Replaces the retired `taxonomy()` (MG-2226), with no
78
+ * shim.
85
79
  */
86
- readonly browse: BrowseNamespace;
80
+ readonly categories: CategoriesClient;
87
81
  /**
88
82
  * THE QUESTION: "is this material allowed HERE?" — a jurisdiction + occupancy +
89
83
  * finish location, not a property of the material alone. `codes.context()`
90
84
  * discovers the vocabulary, `codes.requirements()` states a space,
91
85
  * `codes.advisory()` badges candidates.
92
86
  *
93
- * Instead use {@link MaterialGraphClient.bySpec} to find materials by a
87
+ * Instead use {@link MaterialGraphClient.listVariants} to find materials by a
94
88
  * classification you already know you need; codes is what tells you WHICH one
95
89
  * the space demands. ADVISORY ONLY: model code as adopted, never a
96
90
  * determination for an authority having jurisdiction.
@@ -100,15 +94,14 @@ export declare class MaterialGraphClient extends CatalogueClient {
100
94
  * THE QUESTION: "what colours exist here?" (`profiles`, `stats`) and "what
101
95
  * matches this whole SET of colours?" (`palette`, `gradient`).
102
96
  *
103
- * Instead use {@link MaterialGraphClient.byColour} for ONE colour,
104
- * {@link MaterialGraphClient.browse} to walk by a colour scalar, and
105
- * {@link MaterialGraphClient.colourFacets} for the colour VOCABULARY rather
106
- * than values. Colour throughout is derived from product imagery — visual
107
- * likeness, never a declared colour specification.
97
+ * Instead use {@link MaterialGraphClient.byColour} for ONE colour and
98
+ * {@link MaterialGraphClient.listVariants} to page through a colour's family.
99
+ * Colour is usually derived from product imagery, which is visual likeness,
100
+ * not a colour specification. A maker's declared colour, such as a paint's
101
+ * published hex, wins where MaterialGraph holds one, and each value's
102
+ * source basis says which.
108
103
  */
109
104
  readonly colours: ColoursClient;
110
- /** Discover honest graph questions, then traverse one explicit operator. */
111
- readonly exploration: ExplorationNamespace;
112
105
  /**
113
106
  * THE QUESTION: "what did people say about this uploaded file, and record what
114
107
  * they said." Names on these remarks are REPORTED, never verified — see
@@ -118,29 +111,36 @@ export declare class MaterialGraphClient extends CatalogueClient {
118
111
  constructor(options: MaterialGraphClientOptions);
119
112
  get lastRateLimit(): RateLimit | null;
120
113
  /**
121
- * THE QUESTION: "find me materials like this" — a RANKED answer over words, a
122
- * seed image, colours and a mood, optionally gated by hard specs.
114
+ * THE QUESTION: "find me materials like this": one search over the words, or
115
+ * a seed or query image, optionally gated by a category, hard attribute
116
+ * filters and a corpus scope (ADR 0031).
123
117
  *
124
- * Instead use {@link MaterialGraphClient.bySpec} when the spec IS the question
118
+ * Instead use {@link MaterialGraphClient.listVariants} when the spec IS the question
125
119
  * (ranking would be noise), {@link MaterialGraphClient.byColour} /
126
120
  * `colours.palette()` for visual colour intent (`text` matches WORDS — "sage
127
121
  * green" finds materials that SAY sage, not ones that look it),
128
122
  * {@link MaterialGraphClient.match} for a photo, {@link MaterialGraphClient.pairings}
129
123
  * for what goes WITH something, {@link MaterialGraphClient.suggest} for typeahead.
130
124
  *
131
- * The full POST search primitive. `input.filters` layers typed hard
132
- * specification gates onto ranked colour/visual/lexical/seed search. Build
133
- * them with `certificationProgramme`, `specTerm`, or `hasSpec`.
125
+ * The full POST search primitive. `input.filters` are hard token sets on
126
+ * the search index, run in the same query; they change no ordering. Build
127
+ * them with `certificationProgramme`, `specTerm`, or `hasSpec`. Weights,
128
+ * mood, colours, sort and preferences are gone, and the server refuses them
129
+ * by name.
134
130
  */
131
+ search(input: SearchInput & CardProjectionRequest, signal?: AbortSignal): Promise<SearchCardResponse>;
135
132
  search(input: SearchInput, signal?: AbortSignal): Promise<SearchResponse>;
136
133
  /** Whole materials ask → inspectable meanings and complete safe search requests. */
137
134
  planQuery(query: string, signal?: AbortSignal): Promise<MaterialQueryPlan>;
138
135
  /**
139
136
  * The same question as {@link MaterialGraphClient.search}; the difference is
140
- * transport — a cacheable, link-shareable GET for queries that must survive in
141
- * a URL. `filters`, `preferences`, `verdicts`, image bytes and `weights` have
142
- * no query-string form, so anything using those must go through `search`.
137
+ * transport: a cacheable, link-shareable GET for queries that must survive in
138
+ * a URL. `category`, `filters` and image bytes have no query-string form, so
139
+ * anything using those must go through `search`.
143
140
  */
141
+ searchGet(params: SearchGetParams & {
142
+ view: "card";
143
+ }, signal?: AbortSignal): Promise<SearchCardResponse>;
144
144
  searchGet(params: SearchGetParams, signal?: AbortSignal): Promise<SearchResponse>;
145
145
  /**
146
146
  * THE QUESTION: "what materials are in this PHOTO?" — Material Match classifies
@@ -155,7 +155,7 @@ export declare class MaterialGraphClient extends CatalogueClient {
155
155
  * `droppedBelowFloor` before reporting an empty result: "nothing was good
156
156
  * enough" and "nothing was found" are different answers.
157
157
  */
158
- match(input: MatchInput, signal?: AbortSignal): Promise<MatchResponse>;
158
+ match(input: MatchInput, signal?: AbortSignal): Promise<MatchAnswer>;
159
159
  /**
160
160
  * Material Match as a PROGRESSIVE stream — the same POST
161
161
  * `/api/v1/search/match` endpoint negotiated with `Accept:
@@ -187,7 +187,7 @@ export declare class MaterialGraphClient extends CatalogueClient {
187
187
  * Instead use `colours.palette()` for N colours at stated proportions (a
188
188
  * different ranking, not a wrapper), `colours.gradient()` for a transition,
189
189
  * {@link MaterialGraphClient.resolveColour} first if you hold a NAME,
190
- * {@link MaterialGraphClient.browse} to walk by lightness/vividness, and
190
+ * {@link MaterialGraphClient.listVariants} to page through a category or a brand, and
191
191
  * {@link MaterialGraphClient.search} when colour is one signal among many.
192
192
  * Report matches as visual likeness, never a stated colour specification.
193
193
  * `family` gates to ONE colorscope family (a gated page can be short); `brand` gates to named brands — one brand's nearest colour to another's.
@@ -198,35 +198,33 @@ export declare class MaterialGraphClient extends CatalogueClient {
198
198
  * `/api/v1/materials/{variantId}`).
199
199
  *
200
200
  * The hinge of the API: every relationship lens
201
- * ({@link MaterialGraphClient.siblings}, {@link MaterialGraphClient.pairings},
201
+ * ({@link MaterialGraphClient.listVariants}, {@link MaterialGraphClient.pairings},
202
202
  * {@link MaterialGraphClient.demand}, `codes.advisory()`) hangs off a
203
- * `variantId`. Instead use {@link MaterialGraphClient.materials} for many ids,
204
- * {@link MaterialGraphClient.materialBlocks} to tell "no value" from "not
205
- * checked", {@link MaterialGraphClient.search} when you have no id yet.
203
+ * `variantId`. Instead use {@link MaterialGraphClient.listVariants} for many
204
+ * ids, or for the other colourways of the same product (MG-2222 retired
205
+ * this route's `?include=siblings`; ask `listVariants` with a `product in`
206
+ * filter instead), {@link MaterialGraphClient.materialBlocks} to tell "no
207
+ * value" from "not checked", {@link MaterialGraphClient.search} when you
208
+ * have no id yet.
206
209
  *
207
210
  * @param variantId Opaque — pass back exactly what you were given.
208
211
  */
209
- material(variantId: VariantId, options?: {
210
- includeSiblings?: boolean;
211
- }, signal?: AbortSignal): Promise<MaterialResponse>;
212
+ material(variantId: VariantId, signal?: AbortSignal): Promise<MaterialResponse>;
213
+ materialBlocks(variantId: VariantId, signal?: AbortSignal): Promise<import("./material-block-types.js").MaterialBlockProjection>;
212
214
  /**
213
- * THE QUESTION: "what other colourways and finishes does this product come in?"
214
- * — the SAME product, different variants.
215
+ * THE QUESTION: "which product types can composition be answered for yet?"
215
216
  *
216
- * Instead use {@link MaterialGraphClient.pairings} for a DIFFERENT product that
217
- * goes with this one, and `search({ similarTo })` for one that LOOKS like it.
217
+ * Coverage per product type, in Live SKUs as well as tuples. Read the SKU
218
+ * figure: one tuple can carry a hundred thousand SKUs or one.
218
219
  */
219
- siblings(variantId: VariantId, signal?: AbortSignal): Promise<SiblingsResponse>;
220
- materialBlocks(variantId: VariantId, signal?: AbortSignal): Promise<import("./material-block-types.js").MaterialBlockProjection>;
221
- materialAssets(variantId: VariantId, signal?: AbortSignal): Promise<import("./material-asset-types.js").MaterialAssetProjection>;
222
- materialRenderAssets(variantId: VariantId, signal?: AbortSignal): Promise<import("./render-assets-types.js").MaterialRenderAssets>;
220
+ compositionReport(signal?: AbortSignal): Promise<CompositionCorpusSummary>;
221
+ listVariantAssets(variantId: VariantId, options?: ListVariantAssetsOptions, signal?: AbortSignal): Promise<VariantAssetPage>;
223
222
  materialDocuments(variantId: VariantId, options?: MaterialDocumentPageOptions, signal?: AbortSignal): Promise<import("./material-asset-types.js").MaterialDocumentPage>;
224
223
  /**
225
224
  * THE QUESTION: "what does the schema DEFINE?" — the governed static registry.
226
225
  *
227
226
  * Definitions, not data: use {@link MaterialGraphClient.specificationFacets} for
228
- * what the corpus actually holds and {@link MaterialGraphClient.glossary} to
229
- * explain one term.
227
+ * what the corpus actually holds.
230
228
  */
231
229
  schema<K extends SchemaResource>(resource: K, signal?: AbortSignal): Promise<SchemaResourceResponse<K>>;
232
230
  /**
@@ -234,9 +232,9 @@ export declare class MaterialGraphClient extends CatalogueClient {
234
232
  * off one resolved material (GET `/api/v1/materials/{variantId}/pairings`).
235
233
  *
236
234
  * Instead use {@link MaterialGraphClient.coordinate} for a whole palette of
237
- * picks, {@link MaterialGraphClient.siblings} for the same product in another
238
- * colour, and `search({ similarTo })` for a LIKE-THIS substitute — similar and
239
- * complementary are opposite questions.
235
+ * picks, {@link MaterialGraphClient.listVariants} for the same product in
236
+ * another colour, and `search({ similarTo })` for a LIKE-THIS substitute —
237
+ * similar and complementary are opposite questions.
240
238
  *
241
239
  * READ `item.source` BEFORE PHRASING: the rail mixes three tiers of evidence —
242
240
  * `cospec` (real orders), `considered` (board activity), `colour` (palette
@@ -244,45 +242,37 @@ export declare class MaterialGraphClient extends CatalogueClient {
244
242
  * you how much of the rail is real order evidence.
245
243
  */
246
244
  pairings(variantId: VariantId, options?: PairingsOptions, signal?: AbortSignal): Promise<PairingsResponse>;
247
- /** Find bounded, exact-spec substitutes for one opaque variant id. */
248
- findSubstitutes(variantId: VariantId, options?: FindSubstitutesOptions, signal?: AbortSignal): Promise<FindSubstitutesResponse>;
249
245
  /** "What finishes does the manufacturer declare for THIS product?" — {@link declaredFinishes}. */
250
246
  associatedFinishes(variantId: VariantId, options?: AssociatedOptions, signal?: AbortSignal): Promise<import("./association-types.js").DeclaredAssociationsResponse>;
251
247
  /** "What products does the manufacturer declare THIS finish for?" — {@link declaredProducts}. */
252
248
  associatedProducts(variantId: VariantId, options?: AssociatedOptions, signal?: AbortSignal): Promise<import("./association-types.js").DeclaredAssociationsResponse>;
253
249
  applicability(options: ApplicabilityOptions, signal?: AbortSignal): Promise<import("./association-types.js").ApplicabilityResponse>;
254
250
  /**
255
- * THE QUESTION: "hydrate these ids I already hold" (POST
256
- * `/api/v1/materials/batch`, ≤ 100 ids) — never a discovery call. Throws
257
- * client-side above {@link MAX_BATCH_IDS}. The response is NOT positional:
258
- * match on `variantId` and read `missingIds` rather than comparing lengths.
259
- * {@link MaterialGraphClient.materialsCached} is the CDN-friendly GET form.
251
+ * THE QUESTION: "eligible variants matching these hard filters, ranked and
252
+ * cursor-paged" (GET `/api/v1/variants`, MG-2222) — the one read behind
253
+ * `list_variants`, hydrating ids you already hold (`{terms: [{field:
254
+ * "variant", op: "in", values: [...]}]}`, up to 100), the other colourways
255
+ * of a product (`{terms: [{field: "product", op: "in", values:
256
+ * [productId]}, {field: "variant", op: "not_in", values: [variantId]}]}` —
257
+ * `filters` is kind-grouped, `{terms, numbers, presence}`, every condition
258
+ * across all three ANDed), or a category/maker listing. An explicit
259
+ * `variant in` id that does not resolve to an eligible variant is
260
+ * reported in `unresolvedVariantIds`, never silently dropped from the
261
+ * page.
260
262
  *
261
- * @param ids Opaque tokens, passed back verbatim.
263
+ * `filters`/`optionalFilters`/`orderBy` are sent as URL-encoded JSON;
264
+ * `attributes`/`include` as comma-separated lists — the server validates,
265
+ * this method does not duplicate that check.
262
266
  */
263
- materials(ids: VariantId[], options: {
264
- view: "detail";
265
- idKind?: MaterialsBatchOptions["idKind"];
266
- }, signal?: AbortSignal): Promise<MaterialsBatchDetailResponse>;
267
- materials(ids: VariantId[], options?: {
268
- view?: "tile";
269
- idKind?: MaterialsBatchOptions["idKind"];
270
- }, signal?: AbortSignal): Promise<MaterialsBatchTileResponse>;
267
+ listVariants(input: ListVariantsInput, signal?: AbortSignal): Promise<ListVariantsOutput>;
271
268
  /**
272
- * Cacheable GET form of the batch read (GET `/api/v1/materials/batch`,
273
- * `Cache-Control: public, max-age=300`). Same response as {@link materials};
274
- * prefer this for repeatable, cache-friendly id sets. Also ≤ 100 ids.
269
+ * THE QUESTION: "which values do the variants matching these filters carry,
270
+ * and how many of each" (POST `/api/v1/variants/facets`, MG-2294) — the
271
+ * options and counts a filter UI shows beside a {@link
272
+ * MaterialGraphClient.listVariants} page. `filters` is the same tree
273
+ * `listVariants()` takes; the server validates both.
275
274
  */
276
- materialsCached(ids: VariantId[], options: {
277
- view: "detail";
278
- idKind?: MaterialsBatchGetOptions["idKind"];
279
- }, signal?: AbortSignal): Promise<MaterialsBatchDetailResponse>;
280
- materialsCached(ids: VariantId[], options?: {
281
- view?: "tile";
282
- idKind?: MaterialsBatchGetOptions["idKind"];
283
- }, signal?: AbortSignal): Promise<MaterialsBatchTileResponse>;
284
- /** Vocabulary families and counts; use `colours.profiles()` for a material palette. */
285
- colourFacets(signal?: AbortSignal): Promise<ColourFacetsResponse>;
275
+ listVariantFacets(input: ListVariantFacetsInput, signal?: AbortSignal): Promise<ListVariantFacetsOutput>;
286
276
  /** Resolve a colour name to its hex, and the named paint's catalogue variant. */
287
277
  resolveColour(name: string, signal?: AbortSignal, options?: ResolveColourOptions): Promise<ResolveColourResponse>;
288
278
  /** Ranked colour-name typeahead (GET `/api/v1/search/colours/suggest`). */
@@ -291,44 +281,20 @@ export declare class MaterialGraphClient extends CatalogueClient {
291
281
  }, signal?: AbortSignal): Promise<SuggestColourResponse>;
292
282
  /** Entity typeahead. Navigate using the selected `refId`; use `search()` for materials. */
293
283
  suggest(q: string, options?: SuggestOptions, signal?: AbortSignal): Promise<SuggestResponse>;
294
- /** Resolve free text to a canonical attribute id. */
295
- resolveAttribute(q: string, options?: ResolveAttributeOptions, signal?: AbortSignal): Promise<ResolveAttributeResponse>;
296
- /** Resolve a value under a canonical attribute id; inspect `recommendedAction` for ambiguity. */
297
- resolveAttributeValue(attributeId: string, query: string, options?: ResolveAttributeValueOptions, signal?: AbortSignal): Promise<ResolveAttributeValueResponse>;
284
+ /**
285
+ * THE QUESTION: "which attribute means this phrase?" or "what could a
286
+ * <category> be specified by?" (GET `/api/v1/catalog/attributes`). One page of
287
+ * attribute definitions, browsed or found by id, name, misspelling or
288
+ * meaning, scoped by `categoryIds`, `blockIds` and `filterableOnly`. Pass an
289
+ * item's `id` with one of its `filterOps` to
290
+ * {@link MaterialGraphClient.listVariants}; follow `pageInfo.endCursor` for
291
+ * the next page.
292
+ */
293
+ listAttributes(options?: ListAttributesOptions, signal?: AbortSignal): Promise<ListAttributesResult>;
298
294
  /** "Is this phrase an attribute or a value?" — see {@link searchVocabularyRequest}. */
299
295
  searchVocabulary(query: string, options?: VocabularySearchOptions, signal?: AbortSignal): Promise<import("./catalog-discovery-types.js").VocabularySearchResponse>;
300
296
  /** "I have words — what do they mean, and what stands behind them?" — see {@link resolvePhrases}. */
301
297
  resolve(phrases: string[], scope?: Parameters<typeof resolvePhrases>[2]): Promise<import("./resolve-types.js").ResolveResponse>;
302
- /**
303
- * THE QUESTION: "which materials, from ANYONE, are ASTM E84 Class A AND
304
- * GREENGUARD-certified?" — hard specifications, no ranking, every brand at
305
- * once whatever each called the value in source. The value-anchored,
306
- * spec-only primitive (GET `/api/v1/search/specifications`).
307
- *
308
- * Instead use `search({ filters })` when the spec merely GATES a ranked
309
- * question, `codes.advisory()` when the real question is what a space demands,
310
- * and {@link specificationFacets} first if you do not know the canonical
311
- * tokens. Guessing one no longer returns a silently empty answer: an
312
- * unresolvable criterion means the query NEVER RAN and the response says so —
313
- * read {@link BySpecResponse.unresolvedCriteria} before treating an empty
314
- * `matches` as "nothing qualifies". A PAGE, NOT A CORPUS, unusually so:
315
- * `totalMatches` is the returned sample's size under `limit`, not a corpus
316
- * count. Each `spec` is an `attribute:value` criterion built with
317
- * `specCriterion` / `certificationProgrammeCriterion`; a variant must satisfy
318
- * ALL of them, and each match carries per-criterion trust (`confidence` +
319
- * `sourceBasis`). NUMBER-valued specs take BOUNDS, not values — pass
320
- * `options.ranges` built with `specRangeCriterion("light_reflectance_value",
321
- * { min: 60 })`; bounds are inclusive, at least one is required, and a
322
- * non-numeric stored value is excluded rather than read as zero.
323
- */
324
- bySpec(spec: string | string[], options?: BySpecOptions, signal?: AbortSignal): Promise<BySpecResponse>;
325
- /**
326
- * THE QUESTION: "what kinds of thing exist, and what are their canonical keys?"
327
- * The source of every `categoryKey` / product-type id the other lenses accept
328
- * (`search({ category })`, `colours.profiles()`,
329
- * {@link MaterialGraphClient.applicableSpecs}). Discover, never hand-write.
330
- */
331
- taxonomy(signal?: AbortSignal): Promise<TaxonomyResponse>;
332
298
  /**
333
299
  * Exact current primary-type status counts by retained source category path.
334
300
  * `comparisonThreshold` is a reporting cutoff only: it never promotes a
@@ -402,9 +368,8 @@ export declare class MaterialGraphClient extends CatalogueClient {
402
368
  /**
403
369
  * THE QUESTION: "what can I even filter on, and what values does the corpus
404
370
  * actually hold?" The start of every spec-driven workflow. Instead use
405
- * {@link MaterialGraphClient.attributeValues} for ONE attribute's distribution,
406
- * {@link MaterialGraphClient.applicableSpecs} for what a product type COULD
407
- * carry, {@link MaterialGraphClient.schema} for the definition.
371
+ * {@link MaterialGraphClient.listAttributes} with `categoryIds` for what a
372
+ * product type COULD carry, {@link MaterialGraphClient.schema} for the definition.
408
373
  *
409
374
  * Discover the live specification vocabulary (GET
410
375
  * `/api/v1/catalog/specifications/facets`) — the facetable spec attributes that
@@ -413,41 +378,14 @@ export declare class MaterialGraphClient extends CatalogueClient {
413
378
  * exists: LEED, GREENGUARD, ASTM E84 Class A, FloorScore, EPDs all surface here
414
379
  * with counts. Includes the virtual `certification_programme` facet (its values
415
380
  * are programme names). Learn an `attribute:value` here, then reuse it as a
416
- * {@link bySpec} criterion or a {@link search} `filters` entry. NOTE: continuous
381
+ * {@link MaterialGraphClient.listVariants} filter leaf or a {@link search}
382
+ * `filters` entry. NOTE: continuous
417
383
  * numeric specs (e.g. `slip_resistance_dcof`, a 0–1 DCOF range) are NOT
418
384
  * token-facetable and do not appear here — read those per-attribute.
419
385
  */
420
386
  specificationFacets(signal?: AbortSignal): Promise<SpecFacetsListResponse>;
421
- /**
422
- * List the live value distribution for ONE canonical attribute (GET
423
- * `/api/v1/catalog/attributes/{attributeId}/values`), ordered by cross-brand
424
- * reach with variant + brand counts. The drill-in companion to
425
- * {@link specificationFacets} — e.g. every certification programme on record,
426
- * or every fire classification and how many variants carry each.
427
- */
428
- attributeValues(attributeId: string, signal?: AbortSignal): Promise<SpecFacetsDistributionResponse>;
429
- /**
430
- * THE QUESTION: "what specs COULD a material of this type carry?" — the
431
- * template, not the data. Use it to know which absences are meaningful; instead
432
- * use {@link MaterialGraphClient.specificationFacets} for what the corpus holds
433
- * and {@link MaterialGraphClient.materialBlocks} for one material.
434
- *
435
- * @param key A canonical taxonomy key from {@link MaterialGraphClient.taxonomy}.
436
- */
437
- applicableSpecs(key: string, signal?: AbortSignal): Promise<ApplicableSpecsResponse>;
438
- /**
439
- * THE QUESTION: "what does 'DCOF' MEAN?" — one term explained, for a human.
440
- * Explanation, not retrieval: instead use
441
- * {@link MaterialGraphClient.searchVocabulary} to FIND a token and
442
- * {@link MaterialGraphClient.attributeValues} for the values it takes.
443
- */
444
- glossary(term: string, signal?: AbortSignal): Promise<GlossaryTermResponse>;
445
387
  /** "Whose catalogs are in here, and how big is each?" — {@link listBrands}. */
446
388
  brands(options?: BrandsOptions, signal?: AbortSignal): Promise<import("./brand-types.js").BrandCatalogListPage>;
447
- /** "Who is this brand, and what do they claim?" — {@link brandProfile}. */
448
- brand(brandSlug: string, options?: BrandOptions, signal?: AbortSignal): Promise<import("./types.js").BrandProfileResponse>;
449
- /** "This maker's whole range, the way a fan deck reads" — {@link brandColourDeck}. */
450
- brandColourDeck(brandSlug: string, signal?: AbortSignal): Promise<import("./fan-deck-types.js").BrandFanDeck>;
451
389
  /**
452
390
  * Upload one atomic source-material batch (POST `/api/v1/source-material`,
453
391
  * multipart). Pass a heterogeneous pile via `{ files }` (any mix of PDF,
@@ -464,60 +402,22 @@ export declare class MaterialGraphClient extends CatalogueClient {
464
402
  * exist. Requires the `mg:compose` scope.
465
403
  */
466
404
  sourceMaterialBatch(batchId: BatchId, signal?: AbortSignal): Promise<SourceMaterialBatchDetail>;
467
- /**
468
- * THE QUESTION: "what can the hosted agentic surface be asked to DO?" Start
469
- * here before {@link MaterialGraphClient.createRun}: each capability carries its
470
- * live input/output schemas, scopes and side-effect class, so nothing about a
471
- * Run need be hardcoded.
472
- */
473
- capabilities(signal?: AbortSignal): Promise<CapabilityManifestResponse>;
474
405
  /**
475
406
  * THE QUESTION: "do a whole job for me" — the ASYNC lens. Everything else here
476
407
  * answers in one round trip; a Run may suspend for human input and finish
477
408
  * minutes later. Follow with {@link MaterialGraphClient.streamRunEvents} (live)
478
- * or {@link MaterialGraphClient.run} (poll); resume via
479
- * {@link MaterialGraphClient.resumeRun}; pick the capability from
480
- * {@link MaterialGraphClient.capabilities}. Pass `idempotencyKey` so a retry
409
+ * or {@link MaterialGraphClient.run} (poll). Pass `idempotencyKey` so a retry
481
410
  * replays rather than duplicates.
482
411
  */
483
412
  createRun(body: CreatePublicRunRequest, signal?: AbortSignal): Promise<CreatePublicRunResponse>;
484
413
  /**
485
414
  * THE QUESTION: "where has this Run got to?" — the caller-owned, redacted
486
415
  * ledger record. Polling; prefer {@link MaterialGraphClient.streamRunEvents}
487
- * when a human is waiting. `suspended` is not a failure — it means the Run is
488
- * asking you something (see {@link MaterialGraphClient.resumeRun}).
416
+ * when a human is waiting.
489
417
  */
490
418
  run(runId: RunId, signal?: AbortSignal): Promise<PublicRunResponse>;
491
- /**
492
- * THE QUESTION: "which Runs are mine?" — your own Runs, newest first, paged
493
- * (GET `/api/v1/runs`). This is how a client that lost a Run id finds its work
494
- * again: `{ status: "suspended" }` returns the Runs still waiting on an
495
- * answer, whose ids you can then feed to {@link MaterialGraphClient.resumeRun}.
496
- *
497
- * Only your own Runs are ever returned. Page by following `nextCursor` until
498
- * it is ABSENT — a full page is not the signal to stop.
499
- */
500
- listRuns(options?: ListRunsOptions): Promise<PublicRunListResponse>;
501
419
  /** Follow a verdict cell's citation handle to its canonical claim source. */
502
420
  citation(citationId: string, signal?: AbortSignal): Promise<ResolvedVerdictCitation>;
503
- /**
504
- * Resume a suspended Run (POST `/api/v1/runs/{runId}/resume`).
505
- *
506
- * The third argument accepts either an `AbortSignal` (the published form) or
507
- * {@link ResumeRunOptions}, whose `stepId` guards against resuming a step the
508
- * run has already moved past — the API answers 409 on a mismatch (MG-608).
509
- */
510
- resumeRun(runId: RunId, resumeData: unknown, signalOrOptions?: AbortSignal | ResumeRunOptions): Promise<PublicRunResponse>;
511
- /**
512
- * THE QUESTION: "stop this Run." Requests DURABLE cancellation — the Run
513
- * acknowledges and unwinds; the call returning does not mean it has stopped.
514
- * Poll {@link MaterialGraphClient.run} for the terminal state.
515
- */
516
- cancelRun(runId: RunId, signal?: AbortSignal): Promise<PublicRunResponse>;
517
- /** Option B from a composed Run, along one axis. See {@link varySchemeCall}. */
518
- varyScheme(body: VarySchemesRequest, signal?: AbortSignal): Promise<VarySchemesResponse>;
519
- /** Ranked candidate pools for up to 24 slots. See {@link slotPoolsCall}. */
520
- slotPools(body: SlotPoolsRequest, signal?: AbortSignal): Promise<SlotPoolsResponse>;
521
421
  /**
522
422
  * Stream ordered Run events as an async iterator (GET
523
423
  * `/api/v1/runs/{runId}/events`, SSE). Iterates until the stream ends or the