@instruments/materialgraph 0.33.0 → 0.36.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 (92) hide show
  1. package/association-types.d.ts +11 -11
  2. package/associations-client.d.ts +7 -7
  3. package/associations-client.js +5 -5
  4. package/brand-types.d.ts +37 -41
  5. package/brand-types.js +3 -5
  6. package/brands-client.d.ts +22 -9
  7. package/brands-client.js +20 -6
  8. package/by-spec-types.d.ts +1 -1
  9. package/catalog-discovery-types.d.ts +3 -3
  10. package/catalogue-client.d.ts +2 -50
  11. package/catalogue-client.js +2 -10
  12. package/catalogue-types.d.ts +1 -1
  13. package/categories-client.d.ts +3 -5
  14. package/categories-client.js +1 -1
  15. package/category-types.d.ts +17 -30
  16. package/citation-types.d.ts +2 -2
  17. package/client-vocabulary.d.ts +2 -2
  18. package/client-vocabulary.js +4 -1
  19. package/client.d.ts +62 -105
  20. package/client.js +68 -106
  21. package/color-profiles-types.d.ts +70 -0
  22. package/colors-client.d.ts +76 -0
  23. package/colors-client.js +52 -0
  24. package/find-sampled-together-types.d.ts +70 -0
  25. package/{find-companions-types.js → find-sampled-together-types.js} +4 -4
  26. package/{find-variants-by-colour-types.d.ts → find-variants-by-color-types.d.ts} +70 -64
  27. package/find-variants-by-vector-types.d.ts +4 -1
  28. package/get-variant-types.d.ts +14 -2
  29. package/http-transport.d.ts +1 -1
  30. package/http-transport.js +1 -2
  31. package/identifiers.d.ts +2 -2
  32. package/identifiers.js +1 -1
  33. package/index.d.ts +5 -14
  34. package/index.js +1 -3
  35. package/list-variant-facets-types.d.ts +4 -4
  36. package/list-variants-types.d.ts +71 -21
  37. package/material-asset-types.d.ts +3 -3
  38. package/material-block-types.d.ts +9 -9
  39. package/material-types.d.ts +10 -8
  40. package/operations.d.ts +2 -2
  41. package/operations.js +19 -25
  42. package/package.json +2 -2
  43. package/{resolve-colour-types.d.ts → resolve-color-types.d.ts} +18 -18
  44. package/response-schemas.generated.d.ts +2 -2
  45. package/response-schemas.generated.js +41 -71
  46. package/response-schemas.js +1 -1
  47. package/samplize-catalogue-types.d.ts +4 -4
  48. package/samplize-colorvec.js +6 -6
  49. package/{corpus-scope-types.d.ts → search-catalogue-subset-types.d.ts} +3 -3
  50. package/search-variants-types.d.ts +33 -2
  51. package/types.d.ts +32 -284
  52. package/webmcp.generated.js +4 -9
  53. package/attribution-types.d.ts +0 -51
  54. package/attribution-types.js +0 -13
  55. package/by-colour-types.d.ts +0 -320
  56. package/colour-region-types.d.ts +0 -18
  57. package/colours-client.d.ts +0 -70
  58. package/colours-client.js +0 -38
  59. package/find-companions-types.d.ts +0 -70
  60. package/material-query-plan-types.d.ts +0 -70
  61. package/material-query-plan-types.js +0 -1
  62. package/ndjson.d.ts +0 -46
  63. package/ndjson.js +0 -111
  64. package/palette-search-types.d.ts +0 -171
  65. package/palette-search-types.js +0 -1
  66. package/query-understanding-types.d.ts +0 -254
  67. package/query-understanding-types.js +0 -1
  68. package/resolve-colour-types.js +0 -1
  69. package/search-card-types.d.ts +0 -86
  70. package/search-card-types.js +0 -1
  71. package/search-index-plan-types.d.ts +0 -74
  72. package/search-index-plan-types.js +0 -1
  73. package/search-refinement-types.d.ts +0 -103
  74. package/search-refinement-types.js +0 -2
  75. package/search-request-types.d.ts +0 -170
  76. package/search-request-types.js +0 -1
  77. package/search-response-receipt-types.d.ts +0 -24
  78. package/search-response-receipt-types.js +0 -1
  79. package/search-response-types.d.ts +0 -11
  80. package/search-response-types.js +0 -1
  81. package/search-result-validation.d.ts +0 -9
  82. package/search-result-validation.js +0 -83
  83. package/spec-types.d.ts +0 -109
  84. package/spec-types.js +0 -54
  85. package/specifications.d.ts +0 -34
  86. package/specifications.js +0 -56
  87. package/validation.d.ts +0 -43
  88. package/validation.js +0 -117
  89. /package/{by-colour-types.js → color-profiles-types.js} +0 -0
  90. /package/{colour-region-types.js → find-variants-by-color-types.js} +0 -0
  91. /package/{corpus-scope-types.js → resolve-color-types.js} +0 -0
  92. /package/{find-variants-by-colour-types.js → search-catalogue-subset-types.js} +0 -0
@@ -1,23 +1,23 @@
1
+ import type { Cursor, VariantId } from "./identifiers.js";
2
+ import type { ProductTypeReceipt } from "./material-types.js";
1
3
  /**
2
4
  * Wire types for the DECLARED FF&E association reads
3
5
  * (`GET /api/v1/associated/finishes`, `GET /api/v1/associated/products`).
4
6
  *
5
- * THE AUTHORITY ON "THE MANUFACTURER SAID SO". Every other relationship lens in
7
+ * THE AUTHORITY ON "THE BRAND SAID SO". Every other relationship lens in
6
8
  * this SDK is inference: `pairings` reads order and board activity, `search
7
9
  * ({ similarTo })` reads appearance. These two reads are the only ones carrying
8
- * a compatibility the manufacturer themselves enumerated — this fabric is
10
+ * a compatibility the brand itself enumerated - this fabric is
9
11
  * genuinely available on this chair — and the shapes deliberately share no field
10
12
  * with {@link PairingItem}, so the two can never be concatenated into one list.
11
13
  * Present them as separate sections, and never describe a pairing as available.
12
14
  */
13
- import type { CorpusScope } from "./corpus-scope-types.js";
14
- import type { Cursor, VariantId } from "./identifiers.js";
15
- import type { ProductTypeReceipt } from "./material-types.js";
15
+ import type { SearchCatalogueSubset } from "./search-catalogue-subset-types.js";
16
16
  /**
17
17
  * Why an association is believed.
18
18
  *
19
19
  * Every field is ALWAYS present. `confidence` is a FIXED convention value (0.9)
20
- * that the ingest writes on every manufacturer-declared edge — it is not a
20
+ * that the ingest writes on every brand-declared edge - it is not a
21
21
  * measurement, it does not vary between edges, and it must never be shown as a
22
22
  * score or used to rank. Declared associations carry no ranking at all: that is
23
23
  * the point of them.
@@ -25,9 +25,9 @@ import type { ProductTypeReceipt } from "./material-types.js";
25
25
  export type DeclaredProvenance = {
26
26
  /** The stored convention value (0.9 today). Never a per-edge measurement. */
27
27
  confidence: number;
28
- /** The manufacturer enumerated this association in their own catalog data. */
28
+ /** The brand enumerated this association in its own catalog data. */
29
29
  basis: "manufacturer_declared";
30
- /** The provenance recorded on the edge — the manufacturer catalog feed. */
30
+ /** The provenance recorded on the edge - the brand catalog feed. */
31
31
  source: "warehouse";
32
32
  };
33
33
  /** The material the question was asked about, resolved to its identity. */
@@ -46,7 +46,7 @@ export type DeclaredAssociation = {
46
46
  variantName: string | null;
47
47
  /** The role played by this endpoint of the declared edge. */
48
48
  role: "finish" | "product";
49
- /** The directed relationship asserted by the manufacturer. */
49
+ /** The directed relationship asserted by the brand. */
50
50
  relation: "applicable_finish";
51
51
  /** Accepted sampleability when known; absent means unknown. */
52
52
  sampleable?: boolean;
@@ -63,7 +63,7 @@ export type DeclaredAssociation = {
63
63
  * The eligible variants of this association's product, the set `listVariants`
64
64
  * pages. Absent when the product has no eligible variant.
65
65
  */
66
- colourwayCount?: number;
66
+ colorwayCount?: number;
67
67
  };
68
68
  /**
69
69
  * One page of declared associations.
@@ -101,7 +101,7 @@ export type AssociatedOptions = {
101
101
  * carrying a Material Bank id; absent or `all` is the whole declared set.
102
102
  * Membership does not establish sampleability; use `sampleableOnly` for that.
103
103
  */
104
- corpusScope?: CorpusScope;
104
+ searchCatalogueSubset?: SearchCatalogueSubset;
105
105
  /** Return only associations whose effective sampleability is true. */
106
106
  sampleableOnly?: boolean;
107
107
  /**
@@ -5,9 +5,9 @@
5
5
  * `.associatedProducts` delegate here; the contract lives in this file.
6
6
  *
7
7
  * DECLARED IS NOT INFERRED — the rule this whole lens exists to make
8
- * unmissable. These two reads return compatibility the MANUFACTURER stated
8
+ * unmissable. These two reads return compatibility the BRAND stated
9
9
  * ("this fabric is available on this chair"); `pairings()` returns
10
- * companionship the graph INFERRED from orders, boards and colour. The two
10
+ * companionship the graph INFERRED from orders, boards and color. The two
11
11
  * response shapes share no field, on purpose: render them as separate
12
12
  * sections, never concatenate them, and never describe a pairing as
13
13
  * "available on".
@@ -17,12 +17,12 @@ import type { HttpTransport } from "./http-transport.js";
17
17
  import type { VariantId } from "./identifiers.js";
18
18
  /**
19
19
  * THE QUESTION: "what finishes can I get on THIS chair?" — the fabrics,
20
- * leathers and surfaces the MANUFACTURER declares are available on a product
20
+ * leathers and surfaces the BRAND declares are available on a product
21
21
  * variant (GET `/api/v1/associated/finishes`).
22
22
  *
23
23
  * Instead use `pairings()` for what merely GOES WITH something (inference from
24
- * orders, boards and colour) and `siblings()` for the same product in another
25
- * colourway. These are the only relationships the manufacturer themselves
24
+ * orders, boards and color) and `listVariants()` for the same product in another
25
+ * colorway. These are the only relationships the brand itself
26
26
  * stated: `kind` is always `"declared_association"`, and the shape shares no
27
27
  * field with a pairing — see the module docblock for why that matters.
28
28
  *
@@ -36,7 +36,7 @@ import type { VariantId } from "./identifiers.js";
36
36
  export declare const declaredFinishes: (transport: HttpTransport, variantId: VariantId, options?: AssociatedOptions, signal?: AbortSignal) => Promise<DeclaredAssociationsResponse>;
37
37
  /**
38
38
  * THE QUESTION: "what furniture takes THIS fabric?" — the products the
39
- * MANUFACTURER declares a finish variant is available on (GET
39
+ * BRAND declares a finish variant is available on (GET
40
40
  * `/api/v1/associated/products`).
41
41
  *
42
42
  * The exact reverse of {@link declaredFinishes} over one stored relationship,
@@ -49,5 +49,5 @@ export declare const declaredFinishes: (transport: HttpTransport, variantId: Var
49
49
  * @param variantId The FINISH variant. Opaque — pass back exactly what you were given.
50
50
  */
51
51
  export declare const declaredProducts: (transport: HttpTransport, variantId: VariantId, options?: AssociatedOptions, signal?: AbortSignal) => Promise<DeclaredAssociationsResponse>;
52
- /** Read manufacturer-declared applicability without collapsing Product/Variant grain. */
52
+ /** Read brand-declared applicability without collapsing Product/Variant default attribute level. */
53
53
  export declare const applicability: (transport: HttpTransport, options: ApplicabilityOptions, signal?: AbortSignal) => Promise<ApplicabilityResponse>;
@@ -1,12 +1,12 @@
1
1
  import { resolveOperation } from "./operations.js";
2
2
  /**
3
3
  * THE QUESTION: "what finishes can I get on THIS chair?" — the fabrics,
4
- * leathers and surfaces the MANUFACTURER declares are available on a product
4
+ * leathers and surfaces the BRAND declares are available on a product
5
5
  * variant (GET `/api/v1/associated/finishes`).
6
6
  *
7
7
  * Instead use `pairings()` for what merely GOES WITH something (inference from
8
- * orders, boards and colour) and `siblings()` for the same product in another
9
- * colourway. These are the only relationships the manufacturer themselves
8
+ * orders, boards and color) and `listVariants()` for the same product in another
9
+ * colorway. These are the only relationships the brand itself
10
10
  * stated: `kind` is always `"declared_association"`, and the shape shares no
11
11
  * field with a pairing — see the module docblock for why that matters.
12
12
  *
@@ -20,7 +20,7 @@ import { resolveOperation } from "./operations.js";
20
20
  export const declaredFinishes = async (transport, variantId, options, signal) => await transport.requestJson(resolveOperation("list_associated_finishes"), { query: { variantId, ...options }, signal });
21
21
  /**
22
22
  * THE QUESTION: "what furniture takes THIS fabric?" — the products the
23
- * MANUFACTURER declares a finish variant is available on (GET
23
+ * BRAND declares a finish variant is available on (GET
24
24
  * `/api/v1/associated/products`).
25
25
  *
26
26
  * The exact reverse of {@link declaredFinishes} over one stored relationship,
@@ -33,5 +33,5 @@ export const declaredFinishes = async (transport, variantId, options, signal) =>
33
33
  * @param variantId The FINISH variant. Opaque — pass back exactly what you were given.
34
34
  */
35
35
  export const declaredProducts = async (transport, variantId, options, signal) => await transport.requestJson(resolveOperation("list_associated_products"), { query: { variantId, ...options }, signal });
36
- /** Read manufacturer-declared applicability without collapsing Product/Variant grain. */
36
+ /** Read brand-declared applicability without collapsing Product/Variant default attribute level. */
37
37
  export const applicability = async (transport, options, signal) => await transport.requestJson(resolveOperation("get_applicability"), { query: options, signal });
package/brand-types.d.ts CHANGED
@@ -1,52 +1,48 @@
1
1
  /**
2
- * Query options and wire types for the canonical brands collection
3
- * (`GET /api/v1/brands`).
4
- *
5
- * The SDK's one OFFSET-paginated surface — everything else that pages uses an
6
- * opaque cursor. `meta` is where the page/corpus distinction is settled here.
2
+ * Query options and wire types for the canonical brand list
3
+ * (`GET /api/v1/brands`), the same page and the same input the MCP
4
+ * `list_brands` tool and the `mg brand list` command take.
7
5
  */
8
- import type { CorpusScope, CorpusScopeReceipt } from "./corpus-scope-types.js";
6
+ import type { SearchCatalogueSubset } from "./search-catalogue-subset-types.js";
9
7
  export type BrandsOptions = {
10
8
  /**
11
- * Which corpus to list from. Narrows the brands AND the corpus their counts
12
- * are drawn from, inside the query. Absent or `"all"` is the whole graph.
9
+ * A brand name, alias or misspelling, e.g. `"Kvadrat"`. Omit to browse the
10
+ * list by name. Every brand the text matches comes back, so an ambiguous name
11
+ * is yours to disambiguate.
13
12
  */
14
- corpusScope?: CorpusScope;
15
- /** Fuzzy name filter. Omit for the whole collection. */
16
- q?: string;
17
- /** Page size. Never a bound on the collection. */
13
+ query?: string;
14
+ /**
15
+ * A category id from `categories.list()`. Keeps brands with at least one
16
+ * eligible variant in that category scope.
17
+ */
18
+ categoryId?: string;
19
+ /**
20
+ * Keeps brands with at least one eligible variant in this corpus, by the same
21
+ * per-variant test `listVariants()` applies. Absent or `"all"` is every brand
22
+ * that carries materials.
23
+ */
24
+ searchCatalogueSubset?: SearchCatalogueSubset;
25
+ /** Page size, 1 to 50. Never a bound on the list. */
18
26
  limit?: number;
19
- /** Row offset for the next page. Paired with `meta.hasMore`. */
20
- offset?: number;
27
+ /** The previous page's `pageInfo.endCursor`, with the same `query`, `categoryId` and `searchCatalogueSubset`. */
28
+ cursor?: string;
21
29
  };
22
- export type BrandCatalogListItem = {
23
- id: string;
24
- slug: string;
25
- name: string;
26
- primaryMarketSegment: string;
27
- homepageUrl: string | null;
28
- /** Products INGESTED into MaterialGraph, not the brand's own catalog size. */
29
- productCount: number;
30
- /** Variants ingested into MaterialGraph. A coverage figure, not a claim about the brand. */
31
- variantCount: number;
32
- };
33
- export type BrandCatalogListPage = {
34
- /** Present only when a narrowing scope applied; absence means the whole graph. */
35
- corpusScope?: CorpusScopeReceipt;
36
- /** THIS PAGE. Its length is `meta.count`, never `meta.total`. */
37
- items: BrandCatalogListItem[];
30
+ export type BrandItem = {
38
31
  /**
39
- * A PAGE IS NOT A CORPUS, spelled out:
40
- * - `count` — items on THIS page.
41
- * - `total` — brands matching the query overall. The number to quote.
42
- * - `limit` / `offset` — the window that produced this page.
43
- * - `hasMore` — whether another page exists. Keep walking while true.
32
+ * The brand's slug: the value `listVariants()`' `brand` filter and
33
+ * `resolveVariant()`' `brandId` take. Never a display name.
44
34
  */
45
- meta: {
46
- count: number;
47
- total: number;
48
- limit: number;
49
- offset: number;
50
- hasMore: boolean;
35
+ brandId: string;
36
+ name: string;
37
+ /** The brand's homepage, or null when none is on record. */
38
+ website: string | null;
39
+ };
40
+ export type ListBrandsPage = {
41
+ /** THIS PAGE. Follow `pageInfo.endCursor` for the rest; a page is not a total. */
42
+ items: BrandItem[];
43
+ pageInfo: {
44
+ /** Null on the last page. */
45
+ endCursor: string | null;
46
+ hasNextPage: boolean;
51
47
  };
52
48
  };
package/brand-types.js CHANGED
@@ -1,8 +1,6 @@
1
1
  /**
2
- * Query options and wire types for the canonical brands collection
3
- * (`GET /api/v1/brands`).
4
- *
5
- * The SDK's one OFFSET-paginated surface — everything else that pages uses an
6
- * opaque cursor. `meta` is where the page/corpus distinction is settled here.
2
+ * Query options and wire types for the canonical brand list
3
+ * (`GET /api/v1/brands`), the same page and the same input the MCP
4
+ * `list_brands` tool and the `mg brand list` command take.
7
5
  */
8
6
  export {};
@@ -1,17 +1,30 @@
1
1
  /**
2
- * The BRAND lens: the catalogue collection, as a thin wrapper over the shared
2
+ * The BRAND lens: the brand list, as a thin wrapper over the shared
3
3
  * {@link HttpTransport}. `MaterialGraphClient.brands` delegates here; the
4
4
  * contract lives in this file.
5
5
  *
6
- * A brand is a COMPANY, not a catalogue. Every count this read returns is
7
- * coverage — what MaterialGraph has ingested — and never a claim about how
8
- * many products the brand sells.
6
+ * A brand is a COMPANY, not a catalogue. The list says which brands have
7
+ * eligible materials in the scope asked for, and nothing about how many
8
+ * products a brand sells.
9
9
  */
10
- import type { BrandCatalogListPage, BrandsOptions } from "./brand-types.js";
10
+ import type { BrandsOptions, ListBrandsPage } from "./brand-types.js";
11
11
  import type { HttpTransport } from "./http-transport.js";
12
12
  /**
13
- * THE QUESTION: "whose catalogs are in here, and how big is each?" The SDK's
14
- * one OFFSET-paginated surface: read `meta.total` for the collection size and
15
- * `meta.hasMore` to keep walking.
13
+ * THE QUESTION: "which brands are in here?" Cursor-paged like every other
14
+ * list: follow `pageInfo.endCursor` with the same options until `hasNextPage`
15
+ * is false.
16
+ *
17
+ * To list one brand's materials, pass its `brandId` (its slug, never a display
18
+ * name) as the `brand` filter value:
19
+ *
20
+ * @example
21
+ * const { items } = await mg.brands({ query: "Autex", searchCatalogueSubset: "materialBankNaOrderable" });
22
+ * const brand = items.find((b) => b.brandId === "autex-acoustics");
23
+ * if (!brand) throw new Error("autex-acoustics is not on this page");
24
+ * const page = await mg.listVariants({
25
+ * searchCatalogueSubset: "materialBankNaOrderable",
26
+ * filters: { terms: [{ field: "brand", op: "in", values: [brand.brandId] }] },
27
+ * limit: 3,
28
+ * });
16
29
  */
17
- export declare const listBrands: (transport: HttpTransport, options?: BrandsOptions, signal?: AbortSignal) => Promise<BrandCatalogListPage>;
30
+ export declare const listBrands: (transport: HttpTransport, options?: BrandsOptions, signal?: AbortSignal) => Promise<ListBrandsPage>;
package/brands-client.js CHANGED
@@ -1,15 +1,29 @@
1
1
  import { resolveOperation } from "./operations.js";
2
2
  /**
3
- * THE QUESTION: "whose catalogs are in here, and how big is each?" The SDK's
4
- * one OFFSET-paginated surface: read `meta.total` for the collection size and
5
- * `meta.hasMore` to keep walking.
3
+ * THE QUESTION: "which brands are in here?" Cursor-paged like every other
4
+ * list: follow `pageInfo.endCursor` with the same options until `hasNextPage`
5
+ * is false.
6
+ *
7
+ * To list one brand's materials, pass its `brandId` (its slug, never a display
8
+ * name) as the `brand` filter value:
9
+ *
10
+ * @example
11
+ * const { items } = await mg.brands({ query: "Autex", searchCatalogueSubset: "materialBankNaOrderable" });
12
+ * const brand = items.find((b) => b.brandId === "autex-acoustics");
13
+ * if (!brand) throw new Error("autex-acoustics is not on this page");
14
+ * const page = await mg.listVariants({
15
+ * searchCatalogueSubset: "materialBankNaOrderable",
16
+ * filters: { terms: [{ field: "brand", op: "in", values: [brand.brandId] }] },
17
+ * limit: 3,
18
+ * });
6
19
  */
7
20
  export const listBrands = async (transport, options = {}, signal) => await transport.requestJson(resolveOperation("list_brands"), {
8
21
  query: {
9
- corpusScope: options.corpusScope,
22
+ categoryId: options.categoryId,
23
+ cursor: options.cursor,
10
24
  limit: options.limit,
11
- offset: options.offset,
12
- q: options.q,
25
+ query: options.query,
26
+ searchCatalogueSubset: options.searchCatalogueSubset,
13
27
  },
14
28
  signal,
15
29
  });
@@ -51,7 +51,7 @@ export type BySpecVerdictCell = {
51
51
  /** Trust in `value`, 0–1. Null = unrecorded, which is weaker than a low score. */
52
52
  confidence: number | null;
53
53
  /** Where `value` came from (`tested` > `declared` > `catalog_feed` > `derived`). */
54
- sourceBasis: string | null;
54
+ valueOrigin: string | null;
55
55
  /**
56
56
  * Why an `unverified` cell missed the bar; null otherwise.
57
57
  * - `below_confidence` — the value is real but scored under the floor.
@@ -3,7 +3,7 @@
3
3
  *
4
4
  * THE LENS: turning a HUMAN PHRASE into the canonical vocabulary the spec
5
5
  * surfaces accept. Nothing here returns materials — it returns the tokens you
6
- * then spend on `mg.bySpec()` or `mg.search({ filters })`.
6
+ * then spend on `mg.listVariants({ filters })`.
7
7
  */
8
8
  import type { OpenEnum } from "./types.js";
9
9
  /**
@@ -17,13 +17,13 @@ export type ResolveValueCandidate = {
17
17
  dictionaryId?: string;
18
18
  score: number;
19
19
  tier: OpenEnum<"exact_id" | "exact_alias" | "lexical" | "semantic">;
20
- /** Present only for a colour_family candidate resolved via the colorscope fallback. */
20
+ /** Present only for a color_family candidate resolved via the colorscope fallback. */
21
21
  via?: OpenEnum<"colorscope">;
22
22
  };
23
23
  /**
24
24
  * The resolver's verdict on ONE free-text token — the single shape every
25
25
  * resolving surface speaks, so a caller learns to read it once. Carried per bad
26
- * criterion by `bySpec`'s `unresolvedCriteria`.
26
+ * criterion by `BySpecUnresolvedCriterion`, a shape no current method returns.
27
27
  *
28
28
  * READ `recommendedAction`, NOT JUST `best`. `ambiguous` with a populated
29
29
  * `candidates` list means the phrase genuinely matched several terms — taking
@@ -3,71 +3,23 @@ import type { HttpTransport } from "./http-transport.js";
3
3
  import type { VariantId } from "./identifiers.js";
4
4
  import type { ResolveVariantInput, ResolveVariantOutput } from "./resolve-variant-types.js";
5
5
  import type { SamplizeCatalogueOptions, SamplizeCataloguePage } from "./samplize-catalogue-types.js";
6
- import type { SamplizeColorVecCache } from "./samplize-colorvec.js";
7
6
  /** Catalogue publication operations inherited by the public SDK client. */
8
7
  export declare class CatalogueClient {
9
8
  #private;
10
9
  protected constructor(transport: HttpTransport);
11
10
  /**
12
- * THE QUESTION: "what does this manufacturer page or code resolve to in the
11
+ * THE QUESTION: "what does this brand page or code resolve to in the
13
12
  * graph?" Give `input.url` alone, or `input.code` with `input.brandId` (from
14
13
  * {@link CatalogueClient.brands} - inherited by {@link MaterialGraphClient})
15
14
  * when there is no page to read.
16
15
  *
17
- * Exact and scoreless: a sibling colourway, a similar image or a brand match
16
+ * Exact and scoreless: a sibling colorway, a similar image or a brand match
18
17
  * alone never identifies a variant. Read `outcome` - `identified` names
19
18
  * an exact stored variant, `placed` an exact brand with no variant match,
20
19
  * `ambiguous` carries bounded `candidates`, and `unresolved` states why,
21
20
  * never a guess. The submitted URL is never persisted.
22
21
  */
23
22
  resolveVariant(input: ResolveVariantInput, signal?: AbortSignal): Promise<ResolveVariantOutput>;
24
- /** Complete producer-owned vectors and classifications for portable colour matching. */
25
- samplizeColorVecCache(sourceVersion: string, signal?: AbortSignal): Promise<SamplizeColorVecCache>;
26
- /** MG-owned full-catalogue facets and directional colour refinement before page limiting. */
27
- samplizeCatalogueSearch(input: {
28
- palette?: {
29
- hex: string;
30
- proportion: number;
31
- }[];
32
- query?: string;
33
- reference?: string;
34
- direction?: "similar" | "lighter" | "darker" | "muted";
35
- lightnessMin?: number;
36
- lightnessMax?: number;
37
- temperatureMin?: number;
38
- temperatureMax?: number;
39
- family?: string[];
40
- lightness?: string[];
41
- intensity?: string[];
42
- brand?: string[];
43
- sourceVersion: string;
44
- limit?: number;
45
- }, signal?: AbortSignal): Promise<{
46
- target?: {
47
- ref: string;
48
- hex: string;
49
- name?: string;
50
- source: string;
51
- confidence?: number;
52
- };
53
- embeddingVersion?: string;
54
- rankingVersion?: string;
55
- dictionaryVersion?: string;
56
- eligibleCount?: number;
57
- groups?: {
58
- hex: string;
59
- proportion: number;
60
- quota: number;
61
- ids: string[];
62
- shortfall: number;
63
- }[];
64
- ids: string[];
65
- limited: boolean;
66
- sourceVersion: string;
67
- counts: Record<string, Record<string, number>>;
68
- countBasis: string;
69
- basis: string;
70
- }>;
71
23
  /** Complete version-pinned Samplize paint corpus; stock never limits eligibility. */
72
24
  samplizeCatalogue(options?: SamplizeCatalogueOptions, signal?: AbortSignal): Promise<SamplizeCataloguePage>;
73
25
  /**
@@ -6,12 +6,12 @@ export class CatalogueClient {
6
6
  this.#transport = transport;
7
7
  }
8
8
  /**
9
- * THE QUESTION: "what does this manufacturer page or code resolve to in the
9
+ * THE QUESTION: "what does this brand page or code resolve to in the
10
10
  * graph?" Give `input.url` alone, or `input.code` with `input.brandId` (from
11
11
  * {@link CatalogueClient.brands} - inherited by {@link MaterialGraphClient})
12
12
  * when there is no page to read.
13
13
  *
14
- * Exact and scoreless: a sibling colourway, a similar image or a brand match
14
+ * Exact and scoreless: a sibling colorway, a similar image or a brand match
15
15
  * alone never identifies a variant. Read `outcome` - `identified` names
16
16
  * an exact stored variant, `placed` an exact brand with no variant match,
17
17
  * `ambiguous` carries bounded `candidates`, and `unresolved` states why,
@@ -20,14 +20,6 @@ export class CatalogueClient {
20
20
  async resolveVariant(input, signal) {
21
21
  return await this.#transport.requestJson(resolveOperation("resolve_variant"), { body: input, signal });
22
22
  }
23
- /** Complete producer-owned vectors and classifications for portable colour matching. */
24
- async samplizeColorVecCache(sourceVersion, signal) {
25
- return await this.#transport.requestJson(resolveOperation("samplize_colorvec_cache"), { query: { sourceVersion }, signal });
26
- }
27
- /** MG-owned full-catalogue facets and directional colour refinement before page limiting. */
28
- async samplizeCatalogueSearch(input, signal) {
29
- return await this.#transport.requestJson(resolveOperation("samplize_catalogue_search"), { body: input, signal });
30
- }
31
23
  /** Complete version-pinned Samplize paint corpus; stock never limits eligibility. */
32
24
  async samplizeCatalogue(options = {}, signal) {
33
25
  return await this.#transport.requestJson(resolveOperation("samplize_catalogue_products"), { query: { ...options }, signal });
@@ -240,7 +240,7 @@ export interface CatalogAvailableReceipt {
240
240
  algorithm: "sha256";
241
241
  value: string;
242
242
  };
243
- sourceBasis: "brand_supplied";
243
+ valueOrigin: "brand_supplied";
244
244
  retainedUrl: string;
245
245
  status: "retained";
246
246
  };
@@ -2,8 +2,7 @@
2
2
  * The category-tree surface, namespaced as `mg.categories` (MG-2226). Replaces
3
3
  * `taxonomy()` / `GET /api/v1/taxonomy/categories`, retired with no shim.
4
4
  *
5
- * `list()` pages the tree (roots, one node's children, or a name/meaning
6
- * search), and `get(id)` reads one node in full: its place, the names and
5
+ * `list()` pages the tree (roots, one node's children, or a name search), and `get(id)` reads one node in full: its place, the names and
7
6
  * phrases that find it, and the canonical taxonomy concepts it relates to.
8
7
  *
9
8
  * A category id is a TREE KEY, never a canonical `product_category` value,
@@ -14,8 +13,7 @@
14
13
  *
15
14
  * The namespace holds no transport of its own: the client hands it a bound
16
15
  * `get` callback, so auth, rate-limit accounting and error shaping stay in
17
- * exactly one place. `mg.browse` and `mg.codes` set the precedent for a
18
- * namespace over flat methods.
16
+ * exactly one place.
19
17
  */
20
18
  import type { CategoriesGetResult, CategoriesListInput, CategoriesListResult } from "./category-types.js";
21
19
  import type { QueryParams } from "./http-transport.js";
@@ -31,7 +29,7 @@ export declare class CategoriesClient {
31
29
  * One bounded page of the category tree (GET `/api/v1/categories`). With
32
30
  * nothing set, the top-level categories; `parentId` alone, that category's
33
31
  * direct children; `query`, every category (or only `parentId` and
34
- * everything under it) by name, phrase, near spelling or meaning: the
32
+ * everything under it) by name, phrase or near spelling: the
35
33
  * first method that finds anything wins, and every match it finds is
36
34
  * returned, ranked by method then distance.
37
35
  *
@@ -7,7 +7,7 @@ export class CategoriesClient {
7
7
  * One bounded page of the category tree (GET `/api/v1/categories`). With
8
8
  * nothing set, the top-level categories; `parentId` alone, that category's
9
9
  * direct children; `query`, every category (or only `parentId` and
10
- * everything under it) by name, phrase, near spelling or meaning: the
10
+ * everything under it) by name, phrase or near spelling: the
11
11
  * first method that finds anything wins, and every match it finds is
12
12
  * returned, ranked by method then distance.
13
13
  *
@@ -7,12 +7,8 @@
7
7
  * `getCategoryInputSchema` / `getCategoryResultSchema` Zod contracts the routes
8
8
  * are built from.
9
9
  *
10
- * A category id is a TREE KEY (a product-type group or a product type, e.g.
11
- * `"tile_surfaces"`), never a canonical `product_category` value (a termId such
12
- * as `"wall_panel"`). The two vocabularies look alike and are not
13
- * interchangeable, and a termId passed where an id belongs is refused, naming
14
- * which it is. `get(id).productCategory` is where a category relates to its
15
- * termIds; category filters elsewhere in the SDK take the id, never the termId.
10
+ * Category ids identify original Material Bank nodes. Reviewed equivalent nodes
11
+ * retain their stable ids; every node carries its exact source path.
16
12
  */
17
13
  import type { OpenEnum } from "./types.js";
18
14
  /** A category named by id, as in `ancestors` and `children`. */
@@ -20,32 +16,29 @@ export type CategoryRef = {
20
16
  id: string;
21
17
  name: string;
22
18
  };
23
- export type CategoryKind = OpenEnum<"group" | "product_type">;
24
- /**
25
- * How one item matched a `query`: `exact` (the id or a name), `alias` (a
26
- * phrase that names the category), `fuzzy` (a near spelling) or `vector`
27
- * (similar meaning, from the served vocabulary embeddings). Earlier methods
28
- * are surer; a page holds matches from one method only.
29
- */
19
+ export type CategoryKind = OpenEnum<"category">;
20
+ /** How a query matched source category names or exact paths through the lexical matcher. */
30
21
  export type CategoryMatch = {
31
- /** The name, former name or phrase that matched. Null for `vector`, which compares meaning. */
22
+ /** The name or source path that matched. */
32
23
  matchedText: string | null;
33
- method: OpenEnum<"exact" | "alias" | "fuzzy" | "vector">;
24
+ method: OpenEnum<"exact" | "alias" | "fuzzy">;
34
25
  };
35
26
  /**
36
27
  * One item on a `categories.list` page: what picks the next call. `get(id)`
37
- * has the description, ancestors, children, names and concepts.
28
+ * has the source path, depth, ancestors and children.
38
29
  */
39
30
  export type CategoryItem = {
40
31
  /** Whether `categories.list({ parentId: this.id })` lists anything. */
41
32
  hasChildren: boolean;
42
- /** A tree key, not a canonical `product_category` value. */
33
+ /** A source category identity, also used in product_category memberships. */
43
34
  id: string;
44
35
  /** Present only when the page answers a `query`. */
45
36
  match?: CategoryMatch;
46
37
  name: string;
47
38
  /** The parent category's id, or null for a top-level category. */
48
39
  parentId: string | null;
40
+ path: string;
41
+ depth: number;
49
42
  };
50
43
  export type CategoriesPageInfo = {
51
44
  /** Pass back as `cursor` with the same `query` and `parentId` for the next page. */
@@ -69,13 +62,7 @@ export type CategoriesListResult = {
69
62
  notice?: string;
70
63
  pageInfo: CategoriesPageInfo;
71
64
  };
72
- /**
73
- * One canonical taxonomy concept a category relates to. `termId` is the value
74
- * a record's `product_category` attribute holds, not the category id. `match`
75
- * is present only for product types: `exact` (the same thing), `close`,
76
- * `broad` (the concept contains this type) or `narrow` (the concept is one
77
- * kind within this type).
78
- */
65
+ /** Independent semantic mapping metadata; it does not assert source category membership. */
79
66
  export type CategoryConcept = {
80
67
  label: string;
81
68
  match?: OpenEnum<"exact" | "close" | "broad" | "narrow">;
@@ -84,10 +71,7 @@ export type CategoryConcept = {
84
71
  };
85
72
  export type CategoryProductCategory = {
86
73
  concepts: CategoryConcept[];
87
- /**
88
- * The `product_category` value a record holds when the category alone
89
- * decides it. Null for groups and for `conditional` or `unmapped` types.
90
- */
74
+ /** Legacy semantic mapping value, separate from source product_category enum[] values. */
91
75
  recordValue: string | null;
92
76
  /**
93
77
  * `mapped`: the category fixes its canonical concepts. `conditional`: each
@@ -106,9 +90,12 @@ export type CategoriesGetResult = {
106
90
  description: string | null;
107
91
  /** Names this category carried before a rename; they still find it. */
108
92
  formerNames: string[];
109
- /** A tree key, not a canonical `product_category` value. */
93
+ /** A source category identity, also used in product_category memberships. */
110
94
  id: string;
111
95
  kind: CategoryKind;
112
96
  name: string;
113
- productCategory: CategoryProductCategory;
97
+ /** Complete original Material Bank path; reviewed equivalents may retain a different stable id. */
98
+ path: string;
99
+ /** Zero-based depth in the source hierarchy. */
100
+ depth: number;
114
101
  };
@@ -8,7 +8,7 @@ export type ResolvedVerdictCitation = {
8
8
  citationId: string;
9
9
  sourceType: string;
10
10
  source: {
11
- kind: "source_record" | "source_material" | "source_fact" | "url" | "asset" | "download" | "manual_note" | "agent_output";
11
+ kind: "source_record" | "source_material" | "source_statement" | "url" | "asset" | "download" | "manual_note" | "agent_output";
12
12
  /** Canonical source/fact/asset/download id, a public source URL, or the claim-source handle when no public reference is available. */
13
13
  ref: string;
14
14
  title?: string;
@@ -16,7 +16,7 @@ export type ResolvedVerdictCitation = {
16
16
  /** Same-origin public asset proxy path when retained bytes are available. */
17
17
  publicPath?: string;
18
18
  sourceId?: string;
19
- sourceFactId?: string;
19
+ sourceStatementId?: string;
20
20
  sourceAssetId?: string;
21
21
  sourceDownloadId?: string;
22
22
  locator?: {