capdag 0.184.465 → 0.187.479

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.
package/capdag.js CHANGED
@@ -174,7 +174,8 @@ function normalizeEffectValue(rawValue) {
174
174
 
175
175
  function validateNonStructuralTags(tags) {
176
176
  try {
177
- new TaggedUrn('cap', tags, true);
177
+ const serialized = new TaggedUrn('cap', tags).toString();
178
+ TaggedUrn.fromString(serialized);
178
179
  } catch (error) {
179
180
  const msg = error && error.message ? error.message : String(error);
180
181
  const msgLower = msg.toLowerCase();
@@ -1038,6 +1039,8 @@ class CapUrnBuilder {
1038
1039
  `Reserved structural key '${keyLower}' must be set via inSpec(), outSpec(), or effect()`
1039
1040
  );
1040
1041
  }
1042
+ const nextTags = { ...this._tags, [keyLower]: value };
1043
+ validateNonStructuralTags(nextTags);
1041
1044
  this._tags[keyLower] = value;
1042
1045
  return this;
1043
1046
  }
@@ -1058,6 +1061,8 @@ class CapUrnBuilder {
1058
1061
  `Reserved structural key '${keyLower}' cannot be used as a marker`
1059
1062
  );
1060
1063
  }
1064
+ const nextTags = { ...this._tags, [keyLower]: '*' };
1065
+ validateNonStructuralTags(nextTags);
1061
1066
  this._tags[keyLower] = '*';
1062
1067
  return this;
1063
1068
  }
@@ -1143,21 +1148,21 @@ class CapMatcher {
1143
1148
  }
1144
1149
 
1145
1150
  // ============================================================================
1146
- // MEDIA SPEC PARSING
1151
+ // MEDIA DEFINITION PARSING
1147
1152
  // ============================================================================
1148
1153
 
1149
1154
  /**
1150
- * MediaSpec error types
1155
+ * MediaDef error types
1151
1156
  */
1152
- class MediaSpecError extends Error {
1157
+ class MediaDefError extends Error {
1153
1158
  constructor(code, message) {
1154
1159
  super(message);
1155
- this.name = 'MediaSpecError';
1160
+ this.name = 'MediaDefError';
1156
1161
  this.code = code;
1157
1162
  }
1158
1163
  }
1159
1164
 
1160
- const MediaSpecErrorCodes = {
1165
+ const MediaDefErrorCodes = {
1161
1166
  UNRESOLVABLE_MEDIA_URN: 1,
1162
1167
  DUPLICATE_MEDIA_URN: 2
1163
1168
  };
@@ -1168,7 +1173,7 @@ const MediaSpecErrorCodes = {
1168
1173
 
1169
1174
  /**
1170
1175
  * Well-known built-in media URN constants
1171
- * These media URNs are implicitly available and do not need to be declared in mediaSpecs
1176
+ * These media URNs are implicitly available and do not need to be declared in mediaDefs
1172
1177
  *
1173
1178
  * Cardinality and Structure use orthogonal marker tags:
1174
1179
  * - `list` marker: presence = list/array, absence = scalar (default)
@@ -1361,11 +1366,11 @@ const MEDIA_COLLECTION_LIST = 'media:collection;list;record';
1361
1366
  // Media URN for adapter selection output - JSON record
1362
1367
  const MEDIA_ADAPTER_SELECTION = 'media:adapter-selection;json;record';
1363
1368
  // Fabric registry lookup wire types (consumed/produced by cap:lookup-cap;fabric
1364
- // and cap:lookup-media-spec;fabric, both implemented by fetchcartridge).
1369
+ // and cap:lookup-media-def;fabric, both implemented by fetchcartridge).
1365
1370
  const MEDIA_CAP_URN = 'media:cap-urn;textable';
1366
1371
  const MEDIA_MEDIA_URN = 'media:media-urn;textable';
1367
1372
  const MEDIA_CAP_DEFINITION = 'media:cap-definition;json;record;textable';
1368
- const MEDIA_MEDIA_SPEC_DEFINITION = 'media:media-spec-definition;json;record;textable';
1373
+ const MEDIA_MEDIA_DEFINITION = 'media:media-definition;json;record;textable';
1369
1374
 
1370
1375
  // =============================================================================
1371
1376
  // STANDARD CAP URN CONSTANTS
@@ -1381,9 +1386,9 @@ const CAP_ADAPTER_SELECTION = 'cap:in="media:";out="media:adapter-selection;json
1381
1386
 
1382
1387
  // Fabric registry lookup caps. Implemented by fetchcartridge.
1383
1388
  // CAP_LOOKUP_CAP_FABRIC resolves a canonical cap URN to its full flattened
1384
- // cap definition; CAP_LOOKUP_MEDIA_SPEC_FABRIC does the same for media specs.
1389
+ // cap definition; CAP_LOOKUP_MEDIA_DEF_FABRIC does the same for media defs.
1385
1390
  const CAP_LOOKUP_CAP_FABRIC = 'cap:in="media:cap-urn;textable";fabric;lookup-cap;out="media:cap-definition;json;record;textable"';
1386
- const CAP_LOOKUP_MEDIA_SPEC_FABRIC = 'cap:in="media:media-urn;textable";fabric;lookup-media-spec;out="media:media-spec-definition;json;record;textable"';
1391
+ const CAP_LOOKUP_MEDIA_DEF_FABRIC = 'cap:in="media:media-urn;textable";fabric;lookup-media-def;out="media:media-definition;json;record;textable"';
1387
1392
 
1388
1393
  // =============================================================================
1389
1394
  // MEDIA URN CLASS
@@ -1786,21 +1791,21 @@ function getProfileURL(profileName) {
1786
1791
  // MEDIA URN TAG UTILITIES
1787
1792
  // =============================================================================
1788
1793
  // NOTE: The MEDIA_X constants above are convenience values for referencing
1789
- // common media URNs in code. Resolution must go through mediaSpecs tables -
1794
+ // common media URNs in code. Resolution must go through mediaDefs tables -
1790
1795
  // there is NO built-in resolution.
1791
1796
 
1792
1797
  /**
1793
- * Resolved MediaSpec structure
1798
+ * Resolved MediaDef structure
1794
1799
  *
1795
- * A MediaSpec is a resolved media specification containing information about
1796
- * a value type in the CAPDAG system. MediaSpecs are identified by unique media URNs
1800
+ * A MediaDef is a resolved media definition containing information about
1801
+ * a value type in the CAPDAG system. MediaDefs are identified by unique media URNs
1797
1802
  * and contain fields like media_type, profile_uri, schema, etc.
1798
1803
  *
1799
- * MediaSpecs are defined in JSON files in the registry or inline in cap definitions.
1804
+ * MediaDefs are defined in JSON files in the registry or inline in cap definitions.
1800
1805
  */
1801
- class MediaSpec {
1806
+ class MediaDef {
1802
1807
  /**
1803
- * Create a new MediaSpec
1808
+ * Create a new MediaDef
1804
1809
  * @param {string} contentType - The MIME content type
1805
1810
  * @param {string|null} profile - Optional profile URL
1806
1811
  * @param {Object|null} schema - Optional JSON Schema for local validation
@@ -1810,7 +1815,7 @@ class MediaSpec {
1810
1815
  * @param {Object|null} validation - Optional validation rules (min, max, min_length, max_length, pattern, allowed_values)
1811
1816
  * @param {Object|null} metadata - Optional metadata (arbitrary key-value pairs for display/categorization)
1812
1817
  * @param {string[]} extensions - File extensions for storing this media type (e.g., ['pdf'], ['jpg', 'jpeg'])
1813
- * @param {string|null} documentation - Optional long-form markdown documentation. Rendered in media info panels, the cap navigator, capdag-dot-com, and anywhere else a rich-text explanation of the media spec is useful.
1818
+ * @param {string|null} documentation - Optional long-form markdown documentation. Rendered in media info panels, the cap navigator, capdag-dot-com, and anywhere else a rich-text explanation of the media def is useful.
1814
1819
  */
1815
1820
  constructor(contentType, profile = null, schema = null, title = null, description = null, mediaUrn = null, validation = null, metadata = null, extensions = [], documentation = null) {
1816
1821
  this.contentType = contentType;
@@ -1929,7 +1934,7 @@ class MediaSpec {
1929
1934
  /**
1930
1935
  * Get the canonical string representation
1931
1936
  * Format: <media-type>; profile="<url>" (no content-type: prefix)
1932
- * @returns {string} The media_spec as a string
1937
+ * @returns {string} The media_def as a string
1933
1938
  */
1934
1939
  toString() {
1935
1940
  if (this.profile) {
@@ -1939,37 +1944,37 @@ class MediaSpec {
1939
1944
  }
1940
1945
 
1941
1946
  /**
1942
- * Get MediaSpec from a CapUrn using the output media URN
1947
+ * Get MediaDef from a CapUrn using the output media URN
1943
1948
  * NOTE: outSpec is now a required first-class field on CapUrn
1944
1949
  * @param {CapUrn} capUrn - The cap URN
1945
- * @param {Object} mediaSpecs - Optional mediaSpecs lookup table for resolution
1946
- * @returns {MediaSpec} The resolved MediaSpec
1947
- * @throws {MediaSpecError} If media URN cannot be resolved
1950
+ * @param {Object} mediaDefs - Optional mediaDefs lookup table for resolution
1951
+ * @returns {MediaDef} The resolved MediaDef
1952
+ * @throws {MediaDefError} If media URN cannot be resolved
1948
1953
  */
1949
- static fromCapUrn(capUrn, mediaSpecs = []) {
1954
+ static fromCapUrn(capUrn, mediaDefs = []) {
1950
1955
  // outSpec is now a required field, so it's always present
1951
1956
  const mediaUrn = capUrn.getOutSpec();
1952
1957
 
1953
- // Resolve the media URN to a MediaSpec - no fallbacks, fail hard
1954
- return resolveMediaUrn(mediaUrn, mediaSpecs);
1958
+ // Resolve the media URN to a MediaDef - no fallbacks, fail hard
1959
+ return resolveMediaUrn(mediaUrn, mediaDefs);
1955
1960
  }
1956
1961
  }
1957
1962
 
1958
1963
  /**
1959
- * Resolve a media URN to a MediaSpec
1964
+ * Resolve a media URN to a MediaDef
1960
1965
  *
1961
- * Resolution: Look up mediaUrn in mediaSpecs array (by urn field), FAIL HARD if not found.
1962
- * There is no built-in resolution - all media URNs must be in mediaSpecs.
1966
+ * Resolution: Look up mediaUrn in mediaDefs array (by urn field), FAIL HARD if not found.
1967
+ * There is no built-in resolution - all media URNs must be in mediaDefs.
1963
1968
  *
1964
1969
  * @param {string} mediaUrn - The media URN (e.g., "media:textable")
1965
- * @param {Array} mediaSpecs - The mediaSpecs array (each item has urn, media_type, title, etc.)
1966
- * @returns {MediaSpec} The resolved MediaSpec
1967
- * @throws {MediaSpecError} If media URN cannot be resolved
1970
+ * @param {Array} mediaDefs - The mediaDefs array (each item has urn, media_type, title, etc.)
1971
+ * @returns {MediaDef} The resolved MediaDef
1972
+ * @throws {MediaDefError} If media URN cannot be resolved
1968
1973
  */
1969
- function resolveMediaUrn(mediaUrn, mediaSpecs = []) {
1970
- // Look up in mediaSpecs array by urn field
1971
- if (mediaSpecs && Array.isArray(mediaSpecs)) {
1972
- const def = mediaSpecs.find(spec => spec.urn === mediaUrn);
1974
+ function resolveMediaUrn(mediaUrn, mediaDefs = []) {
1975
+ // Look up in mediaDefs array by urn field
1976
+ if (mediaDefs && Array.isArray(mediaDefs)) {
1977
+ const def = mediaDefs.find(spec => spec.urn === mediaUrn);
1973
1978
 
1974
1979
  if (def) {
1975
1980
  // Object form: { urn, media_type, title, profile_uri?, schema?, description?, documentation?, validation?, metadata?, extensions? }
@@ -1990,37 +1995,37 @@ function resolveMediaUrn(mediaUrn, mediaSpecs = []) {
1990
1995
  const extensions = Array.isArray(def.extensions) ? def.extensions : [];
1991
1996
 
1992
1997
  if (!mediaType) {
1993
- throw new MediaSpecError(
1994
- MediaSpecErrorCodes.UNRESOLVABLE_MEDIA_URN,
1998
+ throw new MediaDefError(
1999
+ MediaDefErrorCodes.UNRESOLVABLE_MEDIA_URN,
1995
2000
  `Media URN '${mediaUrn}' has invalid definition: missing media_type`
1996
2001
  );
1997
2002
  }
1998
2003
 
1999
- return new MediaSpec(mediaType, profileUri, schema, title, description, mediaUrn, validation, metadata, extensions, documentation);
2004
+ return new MediaDef(mediaType, profileUri, schema, title, description, mediaUrn, validation, metadata, extensions, documentation);
2000
2005
  }
2001
2006
  }
2002
2007
 
2003
- // FAIL HARD - media URN must be in mediaSpecs array
2004
- throw new MediaSpecError(
2005
- MediaSpecErrorCodes.UNRESOLVABLE_MEDIA_URN,
2006
- `Cannot resolve media URN: '${mediaUrn}'. Not found in mediaSpecs array.`
2008
+ // FAIL HARD - media URN must be in mediaDefs array
2009
+ throw new MediaDefError(
2010
+ MediaDefErrorCodes.UNRESOLVABLE_MEDIA_URN,
2011
+ `Cannot resolve media URN: '${mediaUrn}'. Not found in mediaDefs array.`
2007
2012
  );
2008
2013
  }
2009
2014
 
2010
2015
  /**
2011
- * Build an extension index from a mediaSpecs array.
2016
+ * Build an extension index from a mediaDefs array.
2012
2017
  * Maps lowercase extension strings to arrays of media URNs that use that extension.
2013
2018
  *
2014
- * @param {Array} mediaSpecs - The mediaSpecs array
2019
+ * @param {Array} mediaDefs - The mediaDefs array
2015
2020
  * @returns {Map<string, string[]>} Map from extension to list of URNs
2016
2021
  */
2017
- function buildExtensionIndex(mediaSpecs) {
2022
+ function buildExtensionIndex(mediaDefs) {
2018
2023
  const index = new Map();
2019
- if (!mediaSpecs || !Array.isArray(mediaSpecs)) {
2024
+ if (!mediaDefs || !Array.isArray(mediaDefs)) {
2020
2025
  return index;
2021
2026
  }
2022
2027
 
2023
- for (const spec of mediaSpecs) {
2028
+ for (const spec of mediaDefs) {
2024
2029
  if (!spec.urn || !Array.isArray(spec.extensions)) continue;
2025
2030
  for (const ext of spec.extensions) {
2026
2031
  const extLower = ext.toLowerCase();
@@ -2046,24 +2051,24 @@ function buildExtensionIndex(mediaSpecs) {
2046
2051
  * Lookup is case-insensitive.
2047
2052
  *
2048
2053
  * @param {string} extension - The file extension to look up (without leading dot)
2049
- * @param {Array} mediaSpecs - The mediaSpecs array
2054
+ * @param {Array} mediaDefs - The mediaDefs array
2050
2055
  * @returns {string[]} Array of media URNs for the extension
2051
- * @throws {MediaSpecError} If no media spec is registered for the given extension
2056
+ * @throws {MediaDefError} If no media def is registered for the given extension
2052
2057
  *
2053
2058
  * @example
2054
- * const urns = mediaUrnsForExtension('pdf', mediaSpecs);
2059
+ * const urns = mediaUrnsForExtension('pdf', mediaDefs);
2055
2060
  * // May return ['media:pdf']
2056
2061
  */
2057
- function mediaUrnsForExtension(extension, mediaSpecs) {
2058
- const index = buildExtensionIndex(mediaSpecs);
2062
+ function mediaUrnsForExtension(extension, mediaDefs) {
2063
+ const index = buildExtensionIndex(mediaDefs);
2059
2064
  const extLower = extension.toLowerCase();
2060
2065
  const urns = index.get(extLower);
2061
2066
 
2062
2067
  if (!urns || urns.length === 0) {
2063
- throw new MediaSpecError(
2064
- MediaSpecErrorCodes.UNRESOLVABLE_MEDIA_URN,
2065
- `No media spec registered for extension '${extension}'. ` +
2066
- `Ensure the media spec is defined with an 'extensions' array containing '${extension}'.`
2068
+ throw new MediaDefError(
2069
+ MediaDefErrorCodes.UNRESOLVABLE_MEDIA_URN,
2070
+ `No media def registered for extension '${extension}'. ` +
2071
+ `Ensure the media def is defined with an 'extensions' array containing '${extension}'.`
2067
2072
  );
2068
2073
  }
2069
2074
 
@@ -2075,29 +2080,29 @@ function mediaUrnsForExtension(extension, mediaSpecs) {
2075
2080
  *
2076
2081
  * Returns an array of [extension, urns] pairs for debugging and introspection.
2077
2082
  *
2078
- * @param {Array} mediaSpecs - The mediaSpecs array
2083
+ * @param {Array} mediaDefs - The mediaDefs array
2079
2084
  * @returns {Array<[string, string[]]>} Array of [extension, urns] pairs
2080
2085
  */
2081
- function getExtensionMappings(mediaSpecs) {
2082
- const index = buildExtensionIndex(mediaSpecs);
2086
+ function getExtensionMappings(mediaDefs) {
2087
+ const index = buildExtensionIndex(mediaDefs);
2083
2088
  return Array.from(index.entries());
2084
2089
  }
2085
2090
 
2086
2091
  /**
2087
- * Validate that media_specs array has no duplicate URNs.
2092
+ * Validate that media_defs array has no duplicate URNs.
2088
2093
  *
2089
- * @param {Array} mediaSpecs - The mediaSpecs array to validate
2094
+ * @param {Array} mediaDefs - The mediaDefs array to validate
2090
2095
  * @returns {{valid: boolean, error?: string, duplicates?: string[]}}
2091
2096
  */
2092
- function validateNoMediaSpecDuplicates(mediaSpecs) {
2093
- if (!mediaSpecs || !Array.isArray(mediaSpecs) || mediaSpecs.length === 0) {
2097
+ function validateNoMediaDefDuplicates(mediaDefs) {
2098
+ if (!mediaDefs || !Array.isArray(mediaDefs) || mediaDefs.length === 0) {
2094
2099
  return { valid: true };
2095
2100
  }
2096
2101
 
2097
2102
  const seen = new Set();
2098
2103
  const duplicates = [];
2099
2104
 
2100
- for (const spec of mediaSpecs) {
2105
+ for (const spec of mediaDefs) {
2101
2106
  if (!spec.urn) continue;
2102
2107
  if (seen.has(spec.urn)) {
2103
2108
  duplicates.push(spec.urn);
@@ -2109,7 +2114,7 @@ function validateNoMediaSpecDuplicates(mediaSpecs) {
2109
2114
  if (duplicates.length > 0) {
2110
2115
  return {
2111
2116
  valid: false,
2112
- error: `Duplicate media URNs in media_specs: ${duplicates.join(', ')}`,
2117
+ error: `Duplicate media URNs in media_defs: ${duplicates.join(', ')}`,
2113
2118
  duplicates
2114
2119
  };
2115
2120
  }
@@ -2118,20 +2123,20 @@ function validateNoMediaSpecDuplicates(mediaSpecs) {
2118
2123
  }
2119
2124
 
2120
2125
  /**
2121
- * XV5: Validate that inline media_specs don't redefine existing registry specs.
2126
+ * XV5: Validate that inline media_defs don't redefine existing registry specs.
2122
2127
  *
2123
2128
  * Validation requires a registryLookup function to check if media URNs exist.
2124
2129
  * If no registryLookup is provided, validation passes (graceful degradation).
2125
2130
  *
2126
- * @param {Array} mediaSpecs - The inline media_specs array from a capability
2131
+ * @param {Array} mediaDefs - The inline media_defs array from a capability
2127
2132
  * @param {Object} [options] - Validation options
2128
2133
  * @param {Function} [options.registryLookup] - Function to check if media URN exists in registry
2129
2134
  * Returns true if exists, false otherwise
2130
2135
  * Should handle errors gracefully (return false)
2131
2136
  * @returns {Promise<{valid: boolean, error?: string, redefines?: string[]}>}
2132
2137
  */
2133
- async function validateNoMediaSpecRedefinition(mediaSpecs, options = {}) {
2134
- if (!mediaSpecs || !Array.isArray(mediaSpecs) || mediaSpecs.length === 0) {
2138
+ async function validateNoMediaDefRedefinition(mediaDefs, options = {}) {
2139
+ if (!mediaDefs || !Array.isArray(mediaDefs) || mediaDefs.length === 0) {
2135
2140
  return { valid: true };
2136
2141
  }
2137
2142
 
@@ -2144,7 +2149,7 @@ async function validateNoMediaSpecRedefinition(mediaSpecs, options = {}) {
2144
2149
 
2145
2150
  const redefines = [];
2146
2151
 
2147
- for (const spec of mediaSpecs) {
2152
+ for (const spec of mediaDefs) {
2148
2153
  const mediaUrn = spec.urn;
2149
2154
  if (!mediaUrn) continue;
2150
2155
  try {
@@ -2161,7 +2166,7 @@ async function validateNoMediaSpecRedefinition(mediaSpecs, options = {}) {
2161
2166
  if (redefines.length > 0) {
2162
2167
  return {
2163
2168
  valid: false,
2164
- error: `XV5: Inline media specs redefine existing registry specs: ${redefines.join(', ')}`,
2169
+ error: `XV5: Inline media defs redefine existing registry specs: ${redefines.join(', ')}`,
2165
2170
  redefines
2166
2171
  };
2167
2172
  }
@@ -2173,13 +2178,13 @@ async function validateNoMediaSpecRedefinition(mediaSpecs, options = {}) {
2173
2178
  * XV5: Synchronous version that checks against a provided lookup function.
2174
2179
  * If no registryLookup is provided, validation passes (graceful degradation).
2175
2180
  *
2176
- * @param {Array} mediaSpecs - The inline media_specs array from a capability
2181
+ * @param {Array} mediaDefs - The inline media_defs array from a capability
2177
2182
  * @param {Function} [registryLookup] - Synchronous function to check if media URN exists
2178
2183
  * Returns true if exists, false otherwise
2179
2184
  * @returns {{valid: boolean, error?: string, redefines?: string[]}}
2180
2185
  */
2181
- function validateNoMediaSpecRedefinitionSync(mediaSpecs, registryLookup = null) {
2182
- if (!mediaSpecs || !Array.isArray(mediaSpecs) || mediaSpecs.length === 0) {
2186
+ function validateNoMediaDefRedefinitionSync(mediaDefs, registryLookup = null) {
2187
+ if (!mediaDefs || !Array.isArray(mediaDefs) || mediaDefs.length === 0) {
2183
2188
  return { valid: true };
2184
2189
  }
2185
2190
 
@@ -2190,7 +2195,7 @@ function validateNoMediaSpecRedefinitionSync(mediaSpecs, registryLookup = null)
2190
2195
 
2191
2196
  const redefines = [];
2192
2197
 
2193
- for (const spec of mediaSpecs) {
2198
+ for (const spec of mediaDefs) {
2194
2199
  const mediaUrn = spec.urn;
2195
2200
  if (!mediaUrn) continue;
2196
2201
  if (registryLookup(mediaUrn)) {
@@ -2201,7 +2206,7 @@ function validateNoMediaSpecRedefinitionSync(mediaSpecs, registryLookup = null)
2201
2206
  if (redefines.length > 0) {
2202
2207
  return {
2203
2208
  valid: false,
2204
- error: `XV5: Inline media specs redefine existing registry specs: ${redefines.join(', ')}`,
2209
+ error: `XV5: Inline media defs redefine existing registry specs: ${redefines.join(', ')}`,
2205
2210
  redefines
2206
2211
  };
2207
2212
  }
@@ -2213,13 +2218,13 @@ function validateNoMediaSpecRedefinitionSync(mediaSpecs, registryLookup = null)
2213
2218
  * Check if a CapUrn represents binary output.
2214
2219
  * Throws error if the output spec cannot be resolved - no fallbacks.
2215
2220
  * @param {CapUrn} capUrn - The cap URN
2216
- * @param {Array} mediaSpecs - Optional mediaSpecs array
2221
+ * @param {Array} mediaDefs - Optional mediaDefs array
2217
2222
  * @returns {boolean} True if binary
2218
- * @throws {MediaSpecError} If 'out' tag is missing or spec ID cannot be resolved
2223
+ * @throws {MediaDefError} If 'out' tag is missing or spec ID cannot be resolved
2219
2224
  */
2220
- function isBinaryCapUrn(capUrn, mediaSpecs = []) {
2221
- const mediaSpec = MediaSpec.fromCapUrn(capUrn, mediaSpecs);
2222
- return mediaSpec.isBinary();
2225
+ function isBinaryCapUrn(capUrn, mediaDefs = []) {
2226
+ const mediaDef = MediaDef.fromCapUrn(capUrn, mediaDefs);
2227
+ return mediaDef.isBinary();
2223
2228
  }
2224
2229
 
2225
2230
  /**
@@ -2227,13 +2232,13 @@ function isBinaryCapUrn(capUrn, mediaSpecs = []) {
2227
2232
  * Note: This checks for explicit JSON format marker only.
2228
2233
  * Throws error if the output spec cannot be resolved - no fallbacks.
2229
2234
  * @param {CapUrn} capUrn - The cap URN
2230
- * @param {Array} mediaSpecs - Optional mediaSpecs array
2235
+ * @param {Array} mediaDefs - Optional mediaDefs array
2231
2236
  * @returns {boolean} True if explicit JSON tag present
2232
- * @throws {MediaSpecError} If 'out' tag is missing or spec ID cannot be resolved
2237
+ * @throws {MediaDefError} If 'out' tag is missing or spec ID cannot be resolved
2233
2238
  */
2234
- function isJSONCapUrn(capUrn, mediaSpecs = []) {
2235
- const mediaSpec = MediaSpec.fromCapUrn(capUrn, mediaSpecs);
2236
- return mediaSpec.isJSON();
2239
+ function isJSONCapUrn(capUrn, mediaDefs = []) {
2240
+ const mediaDef = MediaDef.fromCapUrn(capUrn, mediaDefs);
2241
+ return mediaDef.isJSON();
2237
2242
  }
2238
2243
 
2239
2244
  /**
@@ -2241,13 +2246,13 @@ function isJSONCapUrn(capUrn, mediaSpecs = []) {
2241
2246
  * Structured data can be serialized as JSON when transmitted as text.
2242
2247
  * Throws error if the output spec cannot be resolved - no fallbacks.
2243
2248
  * @param {CapUrn} capUrn - The cap URN
2244
- * @param {Array} mediaSpecs - Optional mediaSpecs array
2249
+ * @param {Array} mediaDefs - Optional mediaDefs array
2245
2250
  * @returns {boolean} True if structured (map or list)
2246
- * @throws {MediaSpecError} If 'out' tag is missing or spec ID cannot be resolved
2251
+ * @throws {MediaDefError} If 'out' tag is missing or spec ID cannot be resolved
2247
2252
  */
2248
- function isStructuredCapUrn(capUrn, mediaSpecs = []) {
2249
- const mediaSpec = MediaSpec.fromCapUrn(capUrn, mediaSpecs);
2250
- return mediaSpec.isStructured();
2253
+ function isStructuredCapUrn(capUrn, mediaDefs = []) {
2254
+ const mediaDef = MediaDef.fromCapUrn(capUrn, mediaDefs);
2255
+ return mediaDef.isStructured();
2251
2256
  }
2252
2257
 
2253
2258
  /**
@@ -2309,10 +2314,15 @@ const RESERVED_CLI_FLAGS = ['manifest', '--help', '--version', '-v', '-h'];
2309
2314
  * Argument source - specifies how an argument can be provided
2310
2315
  */
2311
2316
  class ArgSource {
2312
- constructor() {
2317
+ constructor(obj = null) {
2313
2318
  this.stdin = null; // string (media URN) or null
2314
2319
  this.position = null; // number or null
2315
2320
  this.cli_flag = null; // string or null
2321
+ if (obj !== null) {
2322
+ if (obj.stdin !== undefined) this.stdin = obj.stdin;
2323
+ if (obj.position !== undefined) this.position = obj.position;
2324
+ if (obj.cli_flag !== undefined) this.cli_flag = obj.cli_flag;
2325
+ }
2316
2326
  }
2317
2327
 
2318
2328
  /**
@@ -3041,25 +3051,25 @@ class ValidationError extends Error {
3041
3051
  case 'UnknownArgument':
3042
3052
  return `Cap '${capUrn}' does not accept argument '${details.argumentName}' - check capability definition for valid arguments`;
3043
3053
  case 'InvalidArgumentType':
3044
- if (details.expectedMediaSpec) {
3054
+ if (details.expectedMediaDef) {
3045
3055
  const errors = details.schemaErrors ? details.schemaErrors.join(', ') : 'validation failed';
3046
- return `Cap '${capUrn}' argument '${details.argumentName}' expects media_spec '${details.expectedMediaSpec}' but ${errors} for value: ${JSON.stringify(details.actualValue)}`;
3056
+ return `Cap '${capUrn}' argument '${details.argumentName}' expects media_def '${details.expectedMediaDef}' but ${errors} for value: ${JSON.stringify(details.actualValue)}`;
3047
3057
  }
3048
3058
  return `Cap '${capUrn}' argument '${details.argumentName}' expects type '${details.expectedType}' but received '${details.actualType}' with value: ${JSON.stringify(details.actualValue)}`;
3049
3059
  case 'MediaValidationFailed':
3050
3060
  return `Cap '${capUrn}' argument '${details.argumentName}' failed validation rule '${details.validationRule}' with value: ${JSON.stringify(details.actualValue)}`;
3051
- case 'MediaSpecValidationFailed':
3052
- return `Cap '${capUrn}' argument '${details.argumentName}' failed media spec '${details.mediaUrn}' validation rule '${details.validationRule}' with value: ${JSON.stringify(details.actualValue)}`;
3061
+ case 'MediaDefValidationFailed':
3062
+ return `Cap '${capUrn}' argument '${details.argumentName}' failed media def '${details.mediaUrn}' validation rule '${details.validationRule}' with value: ${JSON.stringify(details.actualValue)}`;
3053
3063
  case 'InvalidOutputType':
3054
- if (details.expectedMediaSpec) {
3064
+ if (details.expectedMediaDef) {
3055
3065
  const errors = details.schemaErrors ? details.schemaErrors.join(', ') : 'validation failed';
3056
- return `Cap '${capUrn}' output expects media_spec '${details.expectedMediaSpec}' but ${errors} for value: ${JSON.stringify(details.actualValue)}`;
3066
+ return `Cap '${capUrn}' output expects media_def '${details.expectedMediaDef}' but ${errors} for value: ${JSON.stringify(details.actualValue)}`;
3057
3067
  }
3058
3068
  return `Cap '${capUrn}' output expects type '${details.expectedType}' but received '${details.actualType}' with value: ${JSON.stringify(details.actualValue)}`;
3059
3069
  case 'OutputValidationFailed':
3060
3070
  return `Cap '${capUrn}' output failed validation rule '${details.validationRule}' with value: ${JSON.stringify(details.actualValue)}`;
3061
- case 'OutputMediaSpecValidationFailed':
3062
- return `Cap '${capUrn}' output failed media spec '${details.mediaUrn}' validation rule '${details.validationRule}' with value: ${JSON.stringify(details.actualValue)}`;
3071
+ case 'OutputMediaDefValidationFailed':
3072
+ return `Cap '${capUrn}' output failed media def '${details.mediaUrn}' validation rule '${details.validationRule}' with value: ${JSON.stringify(details.actualValue)}`;
3063
3073
  case 'InvalidCapSchema':
3064
3074
  return `Cap '${capUrn}' has invalid schema: ${details.issue}`;
3065
3075
  case 'TooManyArguments':
@@ -3226,12 +3236,12 @@ class InputValidator {
3226
3236
  *
3227
3237
  * @param {Cap} cap
3228
3238
  * @param {Array} argValues
3229
- * @param {Array} mediaSpecs - Media specs the cap's args reference;
3239
+ * @param {Array} mediaDefs - Media defs the cap's args reference;
3230
3240
  * threaded through to `resolveMediaUrn` for schema resolution.
3231
3241
  * Required for any cap whose args reference media URNs that
3232
3242
  * resolve through the registry.
3233
3243
  */
3234
- static validatePositionalArguments(cap, argValues, mediaSpecs = []) {
3244
+ static validatePositionalArguments(cap, argValues, mediaDefs = []) {
3235
3245
  const capUrn = cap.urnString();
3236
3246
  const args = cap.arguments;
3237
3247
 
@@ -3252,7 +3262,7 @@ class InputValidator {
3252
3262
  });
3253
3263
  }
3254
3264
 
3255
- InputValidator.validateSingleArgument(cap, args.required[i], argValues[i], mediaSpecs);
3265
+ InputValidator.validateSingleArgument(cap, args.required[i], argValues[i], mediaDefs);
3256
3266
  }
3257
3267
 
3258
3268
  // Validate optional arguments if provided
@@ -3260,7 +3270,7 @@ class InputValidator {
3260
3270
  for (let i = 0; i < args.optional.length; i++) {
3261
3271
  const argIndex = requiredCount + i;
3262
3272
  if (argIndex < argValues.length) {
3263
- InputValidator.validateSingleArgument(cap, args.optional[i], argValues[argIndex], mediaSpecs);
3273
+ InputValidator.validateSingleArgument(cap, args.optional[i], argValues[argIndex], mediaDefs);
3264
3274
  }
3265
3275
  }
3266
3276
  }
@@ -3270,10 +3280,10 @@ class InputValidator {
3270
3280
  *
3271
3281
  * @param {Cap} cap
3272
3282
  * @param {Array} namedArgs
3273
- * @param {Array} mediaSpecs - Media specs the cap's args reference;
3283
+ * @param {Array} mediaDefs - Media defs the cap's args reference;
3274
3284
  * threaded through to `resolveMediaUrn` for schema resolution.
3275
3285
  */
3276
- static validateNamedArguments(cap, namedArgs, mediaSpecs = []) {
3286
+ static validateNamedArguments(cap, namedArgs, mediaDefs = []) {
3277
3287
  const capUrn = cap.urnString();
3278
3288
  const args = cap.arguments;
3279
3289
 
@@ -3295,14 +3305,14 @@ class InputValidator {
3295
3305
 
3296
3306
  // Validate the provided argument value
3297
3307
  const providedValue = providedArgs.get(reqArg.name);
3298
- InputValidator.validateSingleArgument(cap, reqArg, providedValue, mediaSpecs);
3308
+ InputValidator.validateSingleArgument(cap, reqArg, providedValue, mediaDefs);
3299
3309
  }
3300
3310
 
3301
3311
  // Validate optional arguments if provided
3302
3312
  for (const optArg of args.optional) {
3303
3313
  if (providedArgs.has(optArg.name)) {
3304
3314
  const providedValue = providedArgs.get(optArg.name);
3305
- InputValidator.validateSingleArgument(cap, optArg, providedValue, mediaSpecs);
3315
+ InputValidator.validateSingleArgument(cap, optArg, providedValue, mediaDefs);
3306
3316
  }
3307
3317
  }
3308
3318
 
@@ -3324,24 +3334,24 @@ class InputValidator {
3324
3334
  /**
3325
3335
  * Validate a single argument against its definition
3326
3336
  * Two-pass validation:
3327
- * 1. Type validation + media spec validation rules (inherent to semantic type)
3337
+ * 1. Type validation + media def validation rules (inherent to semantic type)
3328
3338
  */
3329
- static validateSingleArgument(cap, argDef, value, mediaSpecs = []) {
3330
- // Type validation - returns the resolved MediaSpec
3331
- const mediaSpec = InputValidator.validateArgumentType(cap, argDef, value, mediaSpecs);
3339
+ static validateSingleArgument(cap, argDef, value, mediaDefs = []) {
3340
+ // Type validation - returns the resolved MediaDef
3341
+ const mediaDef = InputValidator.validateArgumentType(cap, argDef, value, mediaDefs);
3332
3342
 
3333
- // Media spec validation rules (inherent to the semantic type)
3334
- if (mediaSpec && mediaSpec.validation) {
3335
- InputValidator.validateMediaSpecRules(cap, argDef, mediaSpec, value);
3343
+ // Media def validation rules (inherent to the semantic type)
3344
+ if (mediaDef && mediaDef.validation) {
3345
+ InputValidator.validateMediaDefRules(cap, argDef, mediaDef, value);
3336
3346
  }
3337
3347
  }
3338
3348
 
3339
3349
  /**
3340
- * Validate argument type using MediaSpec
3341
- * Resolves spec ID to MediaSpec before validation
3342
- * @returns {MediaSpec|null} The resolved MediaSpec
3350
+ * Validate argument type using MediaDef
3351
+ * Resolves spec ID to MediaDef before validation
3352
+ * @returns {MediaDef|null} The resolved MediaDef
3343
3353
  */
3344
- static validateArgumentType(cap, argDef, value, mediaSpecs = []) {
3354
+ static validateArgumentType(cap, argDef, value, mediaDefs = []) {
3345
3355
  const capUrn = cap.urnString();
3346
3356
 
3347
3357
  // Get mediaUrn field (now contains a media URN)
@@ -3351,10 +3361,10 @@ class InputValidator {
3351
3361
  return null;
3352
3362
  }
3353
3363
 
3354
- // Resolve media URN to MediaSpec - FAIL HARD if unresolvable
3355
- let mediaSpec;
3364
+ // Resolve media URN to MediaDef - FAIL HARD if unresolvable
3365
+ let mediaDef;
3356
3366
  try {
3357
- mediaSpec = resolveMediaUrn(mediaUrn, mediaSpecs);
3367
+ mediaDef = resolveMediaUrn(mediaUrn, mediaDefs);
3358
3368
  } catch (e) {
3359
3369
  throw new ValidationError('InvalidCapSchema', capUrn, {
3360
3370
  issue: `Cannot resolve media URN '${mediaUrn}' for argument '${argDef.name}': ${e.message}`
@@ -3362,56 +3372,56 @@ class InputValidator {
3362
3372
  }
3363
3373
 
3364
3374
  // For binary media types, expect base64-encoded string
3365
- if (mediaSpec.isBinary()) {
3375
+ if (mediaDef.isBinary()) {
3366
3376
  if (typeof value !== 'string') {
3367
3377
  throw new ValidationError('InvalidArgumentType', capUrn, {
3368
3378
  argumentName: argDef.name,
3369
- expectedMediaSpec: mediaUrn,
3379
+ expectedMediaDef: mediaUrn,
3370
3380
  actualValue: value,
3371
3381
  schemaErrors: ['Expected base64-encoded string for binary type']
3372
3382
  });
3373
3383
  }
3374
- return mediaSpec;
3384
+ return mediaDef;
3375
3385
  }
3376
3386
 
3377
- // If the resolved media spec has a local schema, validate against it
3378
- if (mediaSpec.schema) {
3387
+ // If the resolved media def has a local schema, validate against it
3388
+ if (mediaDef.schema) {
3379
3389
  // TODO: Full JSON Schema validation would require a JSON Schema library
3380
3390
  // For now, skip local schema validation
3381
3391
  }
3382
3392
 
3383
3393
  // For types with profile, validate against profile
3384
- if (mediaSpec.profile) {
3385
- const valid = InputValidator.validateAgainstProfile(mediaSpec.profile, value);
3394
+ if (mediaDef.profile) {
3395
+ const valid = InputValidator.validateAgainstProfile(mediaDef.profile, value);
3386
3396
  if (!valid) {
3387
3397
  throw new ValidationError('InvalidArgumentType', capUrn, {
3388
3398
  argumentName: argDef.name,
3389
- expectedMediaSpec: mediaUrn,
3399
+ expectedMediaDef: mediaUrn,
3390
3400
  actualValue: value,
3391
3401
  schemaErrors: [`Value does not match profile schema`]
3392
3402
  });
3393
3403
  }
3394
3404
  }
3395
3405
 
3396
- return mediaSpec;
3406
+ return mediaDef;
3397
3407
  }
3398
3408
 
3399
3409
  /**
3400
- * Validate value against media spec's inherent validation rules (first pass)
3410
+ * Validate value against media def's inherent validation rules (first pass)
3401
3411
  * @param {Cap} cap - The capability
3402
3412
  * @param {Object} argDef - The argument definition
3403
- * @param {MediaSpec} mediaSpec - The resolved media spec
3413
+ * @param {MediaDef} mediaDef - The resolved media def
3404
3414
  * @param {*} value - The value to validate
3405
3415
  */
3406
- static validateMediaSpecRules(cap, argDef, mediaSpec, value) {
3416
+ static validateMediaDefRules(cap, argDef, mediaDef, value) {
3407
3417
  const capUrn = cap.urnString();
3408
- const validation = mediaSpec.validation;
3409
- const mediaUrn = mediaSpec.mediaUrn;
3418
+ const validation = mediaDef.validation;
3419
+ const mediaUrn = mediaDef.mediaUrn;
3410
3420
 
3411
3421
  // Min/max validation for numbers
3412
3422
  if (typeof value === 'number') {
3413
3423
  if (validation.min !== undefined && value < validation.min) {
3414
- throw new ValidationError('MediaSpecValidationFailed', capUrn, {
3424
+ throw new ValidationError('MediaDefValidationFailed', capUrn, {
3415
3425
  argumentName: argDef.name,
3416
3426
  mediaUrn: mediaUrn,
3417
3427
  validationRule: `min value ${validation.min}`,
@@ -3419,7 +3429,7 @@ class InputValidator {
3419
3429
  });
3420
3430
  }
3421
3431
  if (validation.max !== undefined && value > validation.max) {
3422
- throw new ValidationError('MediaSpecValidationFailed', capUrn, {
3432
+ throw new ValidationError('MediaDefValidationFailed', capUrn, {
3423
3433
  argumentName: argDef.name,
3424
3434
  mediaUrn: mediaUrn,
3425
3435
  validationRule: `max value ${validation.max}`,
@@ -3432,7 +3442,7 @@ class InputValidator {
3432
3442
  if (typeof value === 'string' || Array.isArray(value)) {
3433
3443
  const length = value.length;
3434
3444
  if (validation.min_length !== undefined && length < validation.min_length) {
3435
- throw new ValidationError('MediaSpecValidationFailed', capUrn, {
3445
+ throw new ValidationError('MediaDefValidationFailed', capUrn, {
3436
3446
  argumentName: argDef.name,
3437
3447
  mediaUrn: mediaUrn,
3438
3448
  validationRule: `min length ${validation.min_length}`,
@@ -3440,7 +3450,7 @@ class InputValidator {
3440
3450
  });
3441
3451
  }
3442
3452
  if (validation.max_length !== undefined && length > validation.max_length) {
3443
- throw new ValidationError('MediaSpecValidationFailed', capUrn, {
3453
+ throw new ValidationError('MediaDefValidationFailed', capUrn, {
3444
3454
  argumentName: argDef.name,
3445
3455
  mediaUrn: mediaUrn,
3446
3456
  validationRule: `max length ${validation.max_length}`,
@@ -3453,7 +3463,7 @@ class InputValidator {
3453
3463
  if (typeof value === 'string' && validation.pattern) {
3454
3464
  const regex = new RegExp(validation.pattern);
3455
3465
  if (!regex.test(value)) {
3456
- throw new ValidationError('MediaSpecValidationFailed', capUrn, {
3466
+ throw new ValidationError('MediaDefValidationFailed', capUrn, {
3457
3467
  argumentName: argDef.name,
3458
3468
  mediaUrn: mediaUrn,
3459
3469
  validationRule: `pattern ${validation.pattern}`,
@@ -3465,7 +3475,7 @@ class InputValidator {
3465
3475
  // Allowed values validation
3466
3476
  if (validation.allowed_values && Array.isArray(validation.allowed_values)) {
3467
3477
  if (!validation.allowed_values.includes(value)) {
3468
- throw new ValidationError('MediaSpecValidationFailed', capUrn, {
3478
+ throw new ValidationError('MediaDefValidationFailed', capUrn, {
3469
3479
  argumentName: argDef.name,
3470
3480
  mediaUrn: mediaUrn,
3471
3481
  validationRule: `allowed values [${validation.allowed_values.join(', ')}]`,
@@ -3536,32 +3546,32 @@ class InputValidator {
3536
3546
  */
3537
3547
  class OutputValidator {
3538
3548
  /**
3539
- * Validate output against cap output schema using MediaSpec.
3549
+ * Validate output against cap output schema using MediaDef.
3540
3550
  *
3541
3551
  * @param {Cap} cap
3542
3552
  * @param {*} output
3543
- * @param {Array} mediaSpecs - Media specs the cap output references;
3553
+ * @param {Array} mediaDefs - Media defs the cap output references;
3544
3554
  * threaded through to `resolveMediaUrn` for schema resolution.
3545
3555
  */
3546
- static validateOutput(cap, output, mediaSpecs = []) {
3556
+ static validateOutput(cap, output, mediaDefs = []) {
3547
3557
  const outputDef = cap.output;
3548
3558
 
3549
3559
  if (!outputDef) return; // No output definition to validate against
3550
3560
 
3551
- // Type validation - returns the resolved MediaSpec
3552
- const mediaSpec = OutputValidator.validateOutputType(cap, outputDef, output, mediaSpecs);
3561
+ // Type validation - returns the resolved MediaDef
3562
+ const mediaDef = OutputValidator.validateOutputType(cap, outputDef, output, mediaDefs);
3553
3563
 
3554
- // Media spec validation rules (inherent to the semantic type)
3555
- if (mediaSpec && mediaSpec.validation) {
3556
- OutputValidator.validateOutputMediaSpecRules(cap, mediaSpec, output);
3564
+ // Media def validation rules (inherent to the semantic type)
3565
+ if (mediaDef && mediaDef.validation) {
3566
+ OutputValidator.validateOutputMediaDefRules(cap, mediaDef, output);
3557
3567
  }
3558
3568
  }
3559
3569
 
3560
3570
  /**
3561
- * Validate output type using MediaSpec
3562
- * @returns {MediaSpec|null} The resolved MediaSpec
3571
+ * Validate output type using MediaDef
3572
+ * @returns {MediaDef|null} The resolved MediaDef
3563
3573
  */
3564
- static validateOutputType(cap, outputDef, value, mediaSpecs = []) {
3574
+ static validateOutputType(cap, outputDef, value, mediaDefs = []) {
3565
3575
  const capUrn = cap.urnString();
3566
3576
 
3567
3577
  // Get mediaUrn field (now contains a media URN)
@@ -3571,10 +3581,10 @@ class OutputValidator {
3571
3581
  return null;
3572
3582
  }
3573
3583
 
3574
- // Resolve media URN to MediaSpec - FAIL HARD if unresolvable
3575
- let mediaSpec;
3584
+ // Resolve media URN to MediaDef - FAIL HARD if unresolvable
3585
+ let mediaDef;
3576
3586
  try {
3577
- mediaSpec = resolveMediaUrn(mediaUrn, mediaSpecs);
3587
+ mediaDef = resolveMediaUrn(mediaUrn, mediaDefs);
3578
3588
  } catch (e) {
3579
3589
  throw new ValidationError('InvalidCapSchema', capUrn, {
3580
3590
  issue: `Cannot resolve media URN '${mediaUrn}' for output: ${e.message}`
@@ -3582,57 +3592,57 @@ class OutputValidator {
3582
3592
  }
3583
3593
 
3584
3594
  // For binary media types, expect base64-encoded string
3585
- if (mediaSpec.isBinary()) {
3595
+ if (mediaDef.isBinary()) {
3586
3596
  if (typeof value !== 'string') {
3587
3597
  throw new ValidationError('InvalidOutputType', capUrn, {
3588
- expectedMediaSpec: mediaUrn,
3598
+ expectedMediaDef: mediaUrn,
3589
3599
  actualValue: value,
3590
3600
  schemaErrors: ['Expected base64-encoded string for binary type']
3591
3601
  });
3592
3602
  }
3593
- return mediaSpec;
3603
+ return mediaDef;
3594
3604
  }
3595
3605
 
3596
- // If the resolved media spec has a local schema, validate against it
3597
- if (mediaSpec.schema) {
3606
+ // If the resolved media def has a local schema, validate against it
3607
+ if (mediaDef.schema) {
3598
3608
  // TODO: Full JSON Schema validation would require a JSON Schema library
3599
3609
  // For now, skip local schema validation
3600
3610
  }
3601
3611
 
3602
3612
  // For types with profile, validate against profile
3603
- if (mediaSpec.profile) {
3604
- const valid = InputValidator.validateAgainstProfile(mediaSpec.profile, value);
3613
+ if (mediaDef.profile) {
3614
+ const valid = InputValidator.validateAgainstProfile(mediaDef.profile, value);
3605
3615
  if (!valid) {
3606
3616
  throw new ValidationError('InvalidOutputType', capUrn, {
3607
- expectedMediaSpec: mediaUrn,
3617
+ expectedMediaDef: mediaUrn,
3608
3618
  actualValue: value,
3609
3619
  schemaErrors: [`Value does not match profile schema`]
3610
3620
  });
3611
3621
  }
3612
3622
  }
3613
3623
 
3614
- return mediaSpec;
3624
+ return mediaDef;
3615
3625
  }
3616
3626
 
3617
3627
  /**
3618
- * Validate output against media spec's inherent validation rules (first pass)
3628
+ * Validate output against media def's inherent validation rules (first pass)
3619
3629
  */
3620
- static validateOutputMediaSpecRules(cap, mediaSpec, value) {
3630
+ static validateOutputMediaDefRules(cap, mediaDef, value) {
3621
3631
  const capUrn = cap.urnString();
3622
- const validation = mediaSpec.validation;
3623
- const mediaUrn = mediaSpec.mediaUrn;
3632
+ const validation = mediaDef.validation;
3633
+ const mediaUrn = mediaDef.mediaUrn;
3624
3634
 
3625
3635
  // Min/max validation for numbers
3626
3636
  if (typeof value === 'number') {
3627
3637
  if (validation.min !== undefined && value < validation.min) {
3628
- throw new ValidationError('OutputMediaSpecValidationFailed', capUrn, {
3638
+ throw new ValidationError('OutputMediaDefValidationFailed', capUrn, {
3629
3639
  mediaUrn: mediaUrn,
3630
3640
  validationRule: `min value ${validation.min}`,
3631
3641
  actualValue: value
3632
3642
  });
3633
3643
  }
3634
3644
  if (validation.max !== undefined && value > validation.max) {
3635
- throw new ValidationError('OutputMediaSpecValidationFailed', capUrn, {
3645
+ throw new ValidationError('OutputMediaDefValidationFailed', capUrn, {
3636
3646
  mediaUrn: mediaUrn,
3637
3647
  validationRule: `max value ${validation.max}`,
3638
3648
  actualValue: value
@@ -3643,14 +3653,14 @@ class OutputValidator {
3643
3653
  // Length validation for strings
3644
3654
  if (typeof value === 'string') {
3645
3655
  if (validation.min_length !== undefined && value.length < validation.min_length) {
3646
- throw new ValidationError('OutputMediaSpecValidationFailed', capUrn, {
3656
+ throw new ValidationError('OutputMediaDefValidationFailed', capUrn, {
3647
3657
  mediaUrn: mediaUrn,
3648
3658
  validationRule: `min length ${validation.min_length}`,
3649
3659
  actualValue: value
3650
3660
  });
3651
3661
  }
3652
3662
  if (validation.max_length !== undefined && value.length > validation.max_length) {
3653
- throw new ValidationError('OutputMediaSpecValidationFailed', capUrn, {
3663
+ throw new ValidationError('OutputMediaDefValidationFailed', capUrn, {
3654
3664
  mediaUrn: mediaUrn,
3655
3665
  validationRule: `max length ${validation.max_length}`,
3656
3666
  actualValue: value
@@ -3662,7 +3672,7 @@ class OutputValidator {
3662
3672
  if (typeof value === 'string' && validation.pattern) {
3663
3673
  const regex = new RegExp(validation.pattern);
3664
3674
  if (!regex.test(value)) {
3665
- throw new ValidationError('OutputMediaSpecValidationFailed', capUrn, {
3675
+ throw new ValidationError('OutputMediaDefValidationFailed', capUrn, {
3666
3676
  mediaUrn: mediaUrn,
3667
3677
  validationRule: `pattern ${validation.pattern}`,
3668
3678
  actualValue: value
@@ -3673,7 +3683,7 @@ class OutputValidator {
3673
3683
  // Allowed values validation
3674
3684
  if (validation.allowed_values && Array.isArray(validation.allowed_values)) {
3675
3685
  if (!validation.allowed_values.includes(value)) {
3676
- throw new ValidationError('OutputMediaSpecValidationFailed', capUrn, {
3686
+ throw new ValidationError('OutputMediaDefValidationFailed', capUrn, {
3677
3687
  mediaUrn: mediaUrn,
3678
3688
  validationRule: `allowed values [${validation.allowed_values.join(', ')}]`,
3679
3689
  actualValue: value
@@ -6140,7 +6150,7 @@ class FabricRegistryEntry {
6140
6150
  }
6141
6151
 
6142
6152
  /**
6143
- * A media spec entry from the registry.
6153
+ * A media def entry from the registry.
6144
6154
  *
6145
6155
  * Wire shape mirrors the per-URN objects published at
6146
6156
  * <base>/media/<sha256(canonical-urn)>
@@ -6182,7 +6192,7 @@ async function sha256Hex(s) {
6182
6192
  }
6183
6193
 
6184
6194
  /**
6185
- * Client for fetching and caching capabilities and media specs.
6195
+ * Client for fetching and caching capabilities and media defs.
6186
6196
  *
6187
6197
  * Reads from `<baseUrl>/api/capabilities` (the flat catalogue) and
6188
6198
  * `<baseUrl>/{caps,media}/<sha256>` (per-URN).
@@ -6274,7 +6284,7 @@ class FabricRegistryClient {
6274
6284
  }
6275
6285
 
6276
6286
  /**
6277
- * Lookup a single media spec by URN.
6287
+ * Lookup a single media def by URN.
6278
6288
  *
6279
6289
  * Canonicalises through MediaUrn and looks up by SHA-256 hash.
6280
6290
  *
@@ -6377,9 +6387,9 @@ module.exports = {
6377
6387
  CapValidator,
6378
6388
  validateCapArgs,
6379
6389
  RESERVED_CLI_FLAGS,
6380
- MediaSpec,
6381
- MediaSpecError,
6382
- MediaSpecErrorCodes,
6390
+ MediaDef,
6391
+ MediaDefError,
6392
+ MediaDefErrorCodes,
6383
6393
  isBinaryCapUrn,
6384
6394
  isJSONCapUrn,
6385
6395
  isStructuredCapUrn,
@@ -6387,9 +6397,9 @@ module.exports = {
6387
6397
  buildExtensionIndex,
6388
6398
  mediaUrnsForExtension,
6389
6399
  getExtensionMappings,
6390
- validateNoMediaSpecRedefinition,
6391
- validateNoMediaSpecRedefinitionSync,
6392
- validateNoMediaSpecDuplicates,
6400
+ validateNoMediaDefRedefinition,
6401
+ validateNoMediaDefRedefinitionSync,
6402
+ validateNoMediaDefDuplicates,
6393
6403
  getSchemaBaseURL,
6394
6404
  getProfileURL,
6395
6405
  MEDIA_STRING,
@@ -6486,12 +6496,12 @@ module.exports = {
6486
6496
  MEDIA_CAP_URN,
6487
6497
  MEDIA_MEDIA_URN,
6488
6498
  MEDIA_CAP_DEFINITION,
6489
- MEDIA_MEDIA_SPEC_DEFINITION,
6499
+ MEDIA_MEDIA_DEFINITION,
6490
6500
  // Standard cap URN constants
6491
6501
  CAP_IDENTITY,
6492
6502
  CAP_ADAPTER_SELECTION,
6493
6503
  CAP_LOOKUP_CAP_FABRIC,
6494
- CAP_LOOKUP_MEDIA_SPEC_FABRIC,
6504
+ CAP_LOOKUP_MEDIA_DEF_FABRIC,
6495
6505
  // Cap execution result
6496
6506
  CapResult,
6497
6507
  // Unified argument type