capdag 0.140.310 → 0.145.321

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.
@@ -313,11 +313,10 @@ function buildStylesheet() {
313
313
  'text-background-opacity': 1,
314
314
  'text-background-padding': '4px',
315
315
  'text-background-shape': 'roundrectangle',
316
- // Keep labels horizontal autorotate clips along
317
- // fan-out edges and rotates labels into unreadable
318
- // angles when multiple edges share a source.
319
- 'text-rotation': 0,
320
- 'text-margin-y': 0,
316
+ // Align labels along their edges so perpendicular/misaligned
317
+ // text no longer reads as floating metadata.
318
+ 'text-rotation': 'autorotate',
319
+ 'text-margin-y': -6,
321
320
  'curve-style': 'bezier',
322
321
  'control-point-step-size': 40,
323
322
  'width': 1.5,
package/capdag.js CHANGED
@@ -3140,448 +3140,6 @@ class CapArgumentValue {
3140
3140
  }
3141
3141
  }
3142
3142
 
3143
- // ============================================================================
3144
- // CAP MATRIX - Registry for Capability Hosts
3145
- // ============================================================================
3146
-
3147
- /**
3148
- * Error types for capability host registry operations
3149
- */
3150
- class CapMatrixError extends Error {
3151
- constructor(type, message) {
3152
- super(message);
3153
- this.name = 'CapMatrixError';
3154
- this.type = type;
3155
- }
3156
-
3157
- static noSetsFound(capability) {
3158
- return new CapMatrixError('NoSetsFound', `No cap sets found for capability: ${capability}`);
3159
- }
3160
-
3161
- static invalidUrn(urn, reason) {
3162
- return new CapMatrixError('InvalidUrn', `Invalid capability URN: ${urn}: ${reason}`);
3163
- }
3164
-
3165
- static registryError(message) {
3166
- return new CapMatrixError('RegistryError', message);
3167
- }
3168
- }
3169
-
3170
- /**
3171
- * Internal entry for a registered capability host
3172
- */
3173
- class CapSetEntry {
3174
- constructor(name, host, capabilities) {
3175
- this.name = name;
3176
- this.host = host; // Object implementing executeCap(capUrn, arguments) -> Promise
3177
- this.capabilities = capabilities; // Array<Cap>
3178
- }
3179
- }
3180
-
3181
- /**
3182
- * Unified registry for cap sets (providers and cartridges)
3183
- * Provides capability host discovery using subset matching.
3184
- */
3185
- class CapMatrix {
3186
- constructor() {
3187
- this.sets = new Map(); // Map<string, CapSetEntry>
3188
- }
3189
-
3190
- /**
3191
- * Register a capability host with its supported capabilities
3192
- * @param {string} name - Unique name for the capability host
3193
- * @param {object} host - Object with executeCap method
3194
- * @param {Cap[]} capabilities - Array of capabilities this host supports
3195
- */
3196
- registerCapSet(name, host, capabilities) {
3197
- const entry = new CapSetEntry(name, host, capabilities);
3198
- this.sets.set(name, entry);
3199
- }
3200
-
3201
- /**
3202
- * Find cap sets that can handle the requested capability
3203
- * Uses subset matching: host capabilities must be a subset of or match the request
3204
- * @param {string} requestUrn - The capability URN to find sets for
3205
- * @returns {object[]} Array of hosts that can handle the request
3206
- * @throws {CapMatrixError} If URN is invalid or no sets found
3207
- */
3208
- findCapSets(requestUrn) {
3209
- let request;
3210
- try {
3211
- request = CapUrn.fromString(requestUrn);
3212
- } catch (e) {
3213
- throw CapMatrixError.invalidUrn(requestUrn, e.message);
3214
- }
3215
-
3216
- const matchingHosts = [];
3217
-
3218
- for (const entry of this.sets.values()) {
3219
- for (const cap of entry.capabilities) {
3220
- if (cap.urn.accepts(request)) {
3221
- matchingHosts.push(entry.host);
3222
- break; // Found a matching capability for this host
3223
- }
3224
- }
3225
- }
3226
-
3227
- if (matchingHosts.length === 0) {
3228
- throw CapMatrixError.noSetsFound(requestUrn);
3229
- }
3230
-
3231
- return matchingHosts;
3232
- }
3233
-
3234
- /**
3235
- * Find the best capability host for the request using specificity ranking
3236
- * @param {string} requestUrn - The capability URN to find the best host for
3237
- * @returns {{host: object, cap: Cap}} The best host and matching cap definition
3238
- * @throws {CapMatrixError} If URN is invalid or no sets found
3239
- */
3240
- findBestCapSet(requestUrn) {
3241
- let request;
3242
- try {
3243
- request = CapUrn.fromString(requestUrn);
3244
- } catch (e) {
3245
- throw CapMatrixError.invalidUrn(requestUrn, e.message);
3246
- }
3247
-
3248
- let bestHost = null;
3249
- let bestCap = null;
3250
- let bestSpecificity = -1;
3251
-
3252
- for (const entry of this.sets.values()) {
3253
- for (const cap of entry.capabilities) {
3254
- if (cap.urn.accepts(request)) {
3255
- const specificity = cap.urn.specificity();
3256
- if (bestSpecificity === -1 || specificity > bestSpecificity) {
3257
- bestHost = entry.host;
3258
- bestCap = cap;
3259
- bestSpecificity = specificity;
3260
- }
3261
- break; // Found match for this entry, check next
3262
- }
3263
- }
3264
- }
3265
-
3266
- if (bestHost === null) {
3267
- throw CapMatrixError.noSetsFound(requestUrn);
3268
- }
3269
-
3270
- return { host: bestHost, cap: bestCap };
3271
- }
3272
-
3273
- /**
3274
- * Get all registered capability host names
3275
- * @returns {string[]} Array of host names
3276
- */
3277
- getHostNames() {
3278
- return Array.from(this.sets.keys());
3279
- }
3280
-
3281
- /**
3282
- * Get all capabilities from all registered sets
3283
- * @returns {Cap[]} Array of all capabilities
3284
- */
3285
- getAllCapabilities() {
3286
- const capabilities = [];
3287
- for (const entry of this.sets.values()) {
3288
- capabilities.push(...entry.capabilities);
3289
- }
3290
- return capabilities;
3291
- }
3292
-
3293
- /**
3294
- * Check if any host accepts the specified capability request
3295
- * @param {string} requestUrn - The capability URN to check
3296
- * @returns {boolean} Whether the capability request is accepted
3297
- */
3298
- acceptsRequest(requestUrn) {
3299
- try {
3300
- this.findCapSets(requestUrn);
3301
- return true;
3302
- } catch (e) {
3303
- if (e instanceof CapMatrixError) {
3304
- return false;
3305
- }
3306
- throw e;
3307
- }
3308
- }
3309
-
3310
- /**
3311
- * Unregister a capability host
3312
- * @param {string} name - The name of the host to unregister
3313
- * @returns {boolean} Whether the host was found and removed
3314
- */
3315
- unregisterCapSet(name) {
3316
- return this.sets.delete(name);
3317
- }
3318
-
3319
- /**
3320
- * Clear all registered sets
3321
- */
3322
- clear() {
3323
- this.sets.clear();
3324
- }
3325
- }
3326
-
3327
- // ============================================================================
3328
- // CAP BLOCK - Composite Registry
3329
- // ============================================================================
3330
-
3331
- /**
3332
- * Result of finding the best match across registries
3333
- */
3334
- class BestCapSetMatch {
3335
- /**
3336
- * @param {Cap} cap - The Cap definition that matched
3337
- * @param {number} specificity - The specificity score of the match
3338
- * @param {string} registryName - The name of the registry that provided this match
3339
- */
3340
- constructor(cap, specificity, registryName) {
3341
- this.cap = cap;
3342
- this.specificity = specificity;
3343
- this.registryName = registryName;
3344
- }
3345
- }
3346
-
3347
- /**
3348
- * Composite CapSet that wraps multiple registries
3349
- * and delegates execution to the best matching one.
3350
- */
3351
- class CompositeCapSet {
3352
- /**
3353
- * @param {Array<{name: string, registry: CapMatrix}>} registries
3354
- */
3355
- constructor(registries) {
3356
- this.registries = registries;
3357
- }
3358
-
3359
- /**
3360
- * Execute a capability by finding the best match and delegating
3361
- * @param {string} capUrn - The capability URN to execute
3362
- * @param {CapArgumentValue[]} args - Arguments identified by media_urn
3363
- * @returns {Promise<CapResult>}
3364
- */
3365
- async executeCap(capUrn, args) {
3366
- let request;
3367
- try {
3368
- request = CapUrn.fromString(capUrn);
3369
- } catch (e) {
3370
- throw new Error(`Invalid cap URN '${capUrn}': ${e.message}`);
3371
- }
3372
-
3373
- // Find the best matching host across all registries
3374
- let bestHost = null;
3375
- let bestSpecificity = -1;
3376
-
3377
- for (const { registry } of this.registries) {
3378
- for (const entry of registry.sets.values()) {
3379
- for (const cap of entry.capabilities) {
3380
- if (cap.urn.accepts(request)) {
3381
- const specificity = cap.urn.specificity();
3382
- if (bestSpecificity === -1 || specificity > bestSpecificity) {
3383
- bestHost = entry.host;
3384
- bestSpecificity = specificity;
3385
- }
3386
- break; // Found match for this entry
3387
- }
3388
- }
3389
- }
3390
- }
3391
-
3392
- if (bestHost === null) {
3393
- throw new Error(`No capability host found for '${capUrn}'`);
3394
- }
3395
-
3396
- // Delegate execution to the best matching host
3397
- return bestHost.executeCap(capUrn, args);
3398
- }
3399
-
3400
- /**
3401
- * Build a directed graph from all capabilities in the registries.
3402
- * @returns {CapGraph}
3403
- */
3404
- graph() {
3405
- return CapGraph.buildFromRegistries(this.registries);
3406
- }
3407
- }
3408
-
3409
- /**
3410
- * Composite registry that wraps multiple CapMatrix instances
3411
- * and finds the best match across all of them by specificity.
3412
- *
3413
- * When multiple registries can handle a request, this registry compares
3414
- * specificity scores and returns the most specific match.
3415
- * On tie, defaults to the first registry that was added (priority order).
3416
- */
3417
- class CapBlock {
3418
- constructor() {
3419
- this.registries = []; // Array of {name: string, registry: CapMatrix}
3420
- }
3421
-
3422
- /**
3423
- * Add a child registry with a name.
3424
- * Registries are checked in order of addition for tie-breaking.
3425
- * @param {string} name - Unique name for this registry
3426
- * @param {CapMatrix} registry - The CapMatrix to add
3427
- */
3428
- addRegistry(name, registry) {
3429
- this.registries.push({ name, registry });
3430
- }
3431
-
3432
- /**
3433
- * Remove a child registry by name
3434
- * @param {string} name - The name of the registry to remove
3435
- * @returns {CapMatrix|null} The removed registry, or null if not found
3436
- */
3437
- removeRegistry(name) {
3438
- const index = this.registries.findIndex(entry => entry.name === name);
3439
- if (index !== -1) {
3440
- const removed = this.registries[index].registry;
3441
- this.registries.splice(index, 1);
3442
- return removed;
3443
- }
3444
- return null;
3445
- }
3446
-
3447
- /**
3448
- * Get a child registry by name
3449
- * @param {string} name - The name of the registry
3450
- * @returns {CapMatrix|null} The registry, or null if not found
3451
- */
3452
- getRegistry(name) {
3453
- const entry = this.registries.find(e => e.name === name);
3454
- return entry ? entry.registry : null;
3455
- }
3456
-
3457
- /**
3458
- * Get names of all child registries
3459
- * @returns {string[]} Array of registry names in priority order
3460
- */
3461
- getRegistryNames() {
3462
- return this.registries.map(entry => entry.name);
3463
- }
3464
-
3465
- /**
3466
- * Check if a capability is available and return execution info.
3467
- * This is the main entry point for capability lookup.
3468
- * @param {string} capUrn - The capability URN to look up
3469
- * @returns {{cap: Cap, compositeHost: CompositeCapSet}} The cap and composite host for execution
3470
- * @throws {CapMatrixError} If URN is invalid or no match found
3471
- */
3472
- can(capUrn) {
3473
- // Find the best match to get the cap definition
3474
- const bestMatch = this.findBestCapSet(capUrn);
3475
-
3476
- // Create a CompositeCapSet that will delegate execution
3477
- const compositeHost = new CompositeCapSet([...this.registries]);
3478
-
3479
- return {
3480
- cap: bestMatch.cap,
3481
- compositeHost: compositeHost
3482
- };
3483
- }
3484
-
3485
- /**
3486
- * Find the best capability host across ALL child registries.
3487
- * Polls all registries and compares their best matches by specificity.
3488
- * On specificity tie, returns the match from the first registry.
3489
- * @param {string} requestUrn - The capability URN to find the best host for
3490
- * @returns {BestCapSetMatch} The best match
3491
- * @throws {CapMatrixError} If URN is invalid or no match found
3492
- */
3493
- findBestCapSet(requestUrn) {
3494
- let request;
3495
- try {
3496
- request = CapUrn.fromString(requestUrn);
3497
- } catch (e) {
3498
- throw CapMatrixError.invalidUrn(requestUrn, e.message);
3499
- }
3500
-
3501
- let bestOverall = null;
3502
-
3503
- for (const { name, registry } of this.registries) {
3504
- // Find the best match within this registry
3505
- const result = this._findBestInRegistry(registry, request);
3506
- if (result) {
3507
- const { cap, specificity } = result;
3508
- const candidate = new BestCapSetMatch(cap, specificity, name);
3509
-
3510
- if (bestOverall === null) {
3511
- bestOverall = candidate;
3512
- } else if (specificity > bestOverall.specificity) {
3513
- // Only replace if strictly more specific
3514
- // On tie, keep the first one (priority order)
3515
- bestOverall = candidate;
3516
- }
3517
- }
3518
- }
3519
-
3520
- if (bestOverall === null) {
3521
- throw CapMatrixError.noSetsFound(requestUrn);
3522
- }
3523
-
3524
- return bestOverall;
3525
- }
3526
-
3527
- /**
3528
- * Check if any registry accepts the specified capability request
3529
- * @param {string} requestUrn - The capability URN to check
3530
- * @returns {boolean} Whether the capability request is accepted
3531
- */
3532
- acceptsRequest(requestUrn) {
3533
- try {
3534
- this.findBestCapSet(requestUrn);
3535
- return true;
3536
- } catch (e) {
3537
- if (e instanceof CapMatrixError) {
3538
- return false;
3539
- }
3540
- throw e;
3541
- }
3542
- }
3543
-
3544
- /**
3545
- * Find the best match within a single registry
3546
- * @private
3547
- * @param {CapMatrix} registry - The registry to search
3548
- * @param {CapUrn} request - The parsed request URN
3549
- * @returns {{cap: Cap, specificity: number}|null} The best match or null
3550
- */
3551
- _findBestInRegistry(registry, request) {
3552
- let bestCap = null;
3553
- let bestSpecificity = -1;
3554
-
3555
- for (const entry of registry.sets.values()) {
3556
- for (const cap of entry.capabilities) {
3557
- if (cap.urn.accepts(request)) {
3558
- const specificity = cap.urn.specificity();
3559
- if (bestSpecificity === -1 || specificity > bestSpecificity) {
3560
- bestCap = cap;
3561
- bestSpecificity = specificity;
3562
- }
3563
- break; // Found match for this entry
3564
- }
3565
- }
3566
- }
3567
-
3568
- if (bestCap === null) {
3569
- return null;
3570
- }
3571
- return { cap: bestCap, specificity: bestSpecificity };
3572
- }
3573
-
3574
- /**
3575
- * Build a directed graph from all capabilities across all registries.
3576
- * The graph represents all possible conversions where:
3577
- * - Nodes are media URNs (e.g., "media:string", "media:binary")
3578
- * - Edges are capabilities that convert from one media URN to another
3579
- * @returns {CapGraph} The capability graph
3580
- */
3581
- graph() {
3582
- return CapGraph.buildFromRegistries(this.registries);
3583
- }
3584
- }
3585
3143
 
3586
3144
  // ============================================================================
3587
3145
  // CAP GRAPH - Directed graph of capability conversions
@@ -3669,25 +3227,6 @@ class CapGraph {
3669
3227
  this.incoming.get(toUrn).push(edgeIndex);
3670
3228
  }
3671
3229
 
3672
- /**
3673
- * Build a graph from multiple registries.
3674
- * @param {Array<{name: string, registry: CapMatrix}>} registries
3675
- * @returns {CapGraph}
3676
- */
3677
- static buildFromRegistries(registries) {
3678
- const graph = new CapGraph();
3679
-
3680
- for (const { name, registry } of registries) {
3681
- for (const entry of registry.sets.values()) {
3682
- for (const cap of entry.capabilities) {
3683
- graph.addCap(cap, name);
3684
- }
3685
- }
3686
- }
3687
-
3688
- return graph;
3689
- }
3690
-
3691
3230
  /**
3692
3231
  * Get all nodes (media URNs) in the graph.
3693
3232
  * @returns {Set<string>}
@@ -5681,11 +5220,6 @@ module.exports = {
5681
5220
  mediaUrnForType,
5682
5221
  modelAvailabilityUrn,
5683
5222
  modelPathUrn,
5684
- CapMatrixError,
5685
- CapMatrix,
5686
- BestCapSetMatch,
5687
- CompositeCapSet,
5688
- CapBlock,
5689
5223
  CapGraphEdge,
5690
5224
  CapGraphStats,
5691
5225
  CapGraph,
package/capdag.test.js CHANGED
@@ -7,7 +7,6 @@ const {
7
7
  MediaUrn, MediaUrnError, MediaUrnErrorCodes,
8
8
  Cap, MediaSpec, MediaSpecError, MediaSpecErrorCodes,
9
9
  resolveMediaUrn, buildExtensionIndex, mediaUrnsForExtension, getExtensionMappings,
10
- CapMatrixError, CapMatrix, BestCapSetMatch, CompositeCapSet, CapBlock,
11
10
  CartridgeInfo, CartridgeCapSummary, CartridgeSuggestion, CartridgeRepoClient, CartridgeRepoServer,
12
11
  CapGraphEdge, CapGraphStats, CapGraph,
13
12
  StdinSource, StdinSourceKind,
@@ -112,20 +111,6 @@ function testUrn(tags) {
112
111
  return `cap:in="${MEDIA_VOID}";${tags};out="${MEDIA_OBJECT}"`;
113
112
  }
114
113
 
115
- // Mock CapSet for testing
116
- class MockCapSet {
117
- constructor(name) {
118
- this.name = name;
119
- }
120
-
121
- async executeCap(capUrn, args) {
122
- return {
123
- binaryOutput: null,
124
- textOutput: `Mock response from ${this.name}`
125
- };
126
- }
127
- }
128
-
129
114
  // Helper to create a Cap for testing
130
115
  function makeCap(urnString, title) {
131
116
  const capUrn = CapUrn.fromString(urnString);
@@ -139,14 +124,6 @@ function makeGraphCap(inUrn, outUrn, title) {
139
124
  return new Cap(capUrn, title, 'convert', title);
140
125
  }
141
126
 
142
- // Helper to create a test URN for matrix tests
143
- function matrixTestUrn(tags) {
144
- if (!tags) {
145
- return 'cap:in="media:void";out="media:object"';
146
- }
147
- return `cap:in="media:void";out="media:object";${tags}`;
148
- }
149
-
150
127
  // ============================================================================
151
128
  // cap_urn.rs: TEST001-TEST050, TEST890-TEST891
152
129
  // ============================================================================
@@ -1167,357 +1144,72 @@ function test110_multipleExtensions() {
1167
1144
  }
1168
1145
 
1169
1146
  // ============================================================================
1170
- // cap_matrix.rs: TEST117-TEST131
1147
+ // cap_graph: browse-mode API used by cap-graph-renderer.js
1148
+ //
1149
+ // The renderer builds its browse graph by:
1150
+ // const capGraph = new CapGraph();
1151
+ // for each cap in /api/capabilities: capGraph.addCap(cap, 'registry');
1152
+ // ... then reads capGraph.edges / getOutgoing(urn) / etc.
1153
+ //
1154
+ // These tests lock in that specific contract. They do NOT cover
1155
+ // buildFromRegistries / CapMatrix / CapBlock — all deleted with the dead
1156
+ // in-process dispatch stack.
1171
1157
  // ============================================================================
1172
1158
 
1173
- // TEST117: Test registering cap set and finding by exact and subset matching
1174
- function test117_capBlockMoreSpecificWins() {
1175
- const providerRegistry = new CapMatrix();
1176
- const cartridgeRegistry = new CapMatrix();
1177
-
1178
- const providerHost = new MockCapSet('provider');
1179
- const providerCap = makeCap(
1180
- 'cap:in="media:binary";op=generate_thumbnail;out="media:binary"',
1181
- 'Provider Thumbnail Generator (generic)'
1182
- );
1183
- providerRegistry.registerCapSet('provider', providerHost, [providerCap]);
1184
-
1185
- const cartridgeHost = new MockCapSet('cartridge');
1186
- const cartridgeCap = makeCap(
1187
- 'cap:ext=pdf;in="media:binary";op=generate_thumbnail;out="media:binary"',
1188
- 'Cartridge PDF Thumbnail Generator (specific)'
1189
- );
1190
- cartridgeRegistry.registerCapSet('cartridge', cartridgeHost, [cartridgeCap]);
1191
-
1192
- const composite = new CapBlock();
1193
- composite.addRegistry('providers', providerRegistry);
1194
- composite.addRegistry('cartridges', cartridgeRegistry);
1195
-
1196
- const request = 'cap:ext=pdf;in="media:binary";op=generate_thumbnail;out="media:binary"';
1197
- const best = composite.findBestCapSet(request);
1198
-
1199
- assertEqual(best.registryName, 'cartridges', 'More specific cartridge should win');
1200
- assertEqual(best.cap.title, 'Cartridge PDF Thumbnail Generator (specific)', 'Should get cartridge cap');
1201
- }
1202
-
1203
- // TEST118: Test selecting best cap set based on specificity ranking With is_dispatchable semantics: - Provider must satisfy ALL request constraints - General request matches specific provider (provider refines request) - Specific request does NOT match general provider (provider lacks constraints)
1204
- function test118_capBlockTieGoesToFirst() {
1205
- const registry1 = new CapMatrix();
1206
- const registry2 = new CapMatrix();
1207
-
1208
- const host1 = new MockCapSet('host1');
1209
- const cap1 = makeCap(matrixTestUrn('ext=pdf;op=generate'), 'Registry 1 Cap');
1210
- registry1.registerCapSet('host1', host1, [cap1]);
1211
-
1212
- const host2 = new MockCapSet('host2');
1213
- const cap2 = makeCap(matrixTestUrn('ext=pdf;op=generate'), 'Registry 2 Cap');
1214
- registry2.registerCapSet('host2', host2, [cap2]);
1215
-
1216
- const composite = new CapBlock();
1217
- composite.addRegistry('first', registry1);
1218
- composite.addRegistry('second', registry2);
1219
-
1220
- const best = composite.findBestCapSet(matrixTestUrn('ext=pdf;op=generate'));
1221
- assertEqual(best.registryName, 'first', 'On tie, first registry should win');
1222
- }
1223
-
1224
- // TEST119: Test invalid URN returns InvalidUrn error
1225
- function test119_capBlockPollsAll() {
1226
- const registry1 = new CapMatrix();
1227
- const registry2 = new CapMatrix();
1228
- const registry3 = new CapMatrix();
1229
-
1230
- const host1 = new MockCapSet('host1');
1231
- const cap1 = makeCap(matrixTestUrn('op=different'), 'Registry 1');
1232
- registry1.registerCapSet('host1', host1, [cap1]);
1233
-
1234
- const host2 = new MockCapSet('host2');
1235
- const cap2 = makeCap(matrixTestUrn('op=generate'), 'Registry 2');
1236
- registry2.registerCapSet('host2', host2, [cap2]);
1237
-
1238
- const host3 = new MockCapSet('host3');
1239
- const cap3 = makeCap(matrixTestUrn('ext=pdf;format=thumbnail;op=generate'), 'Registry 3');
1240
- registry3.registerCapSet('host3', host3, [cap3]);
1241
-
1242
- const composite = new CapBlock();
1243
- composite.addRegistry('r1', registry1);
1244
- composite.addRegistry('r2', registry2);
1245
- composite.addRegistry('r3', registry3);
1246
-
1247
- const best = composite.findBestCapSet(matrixTestUrn('ext=pdf;format=thumbnail;op=generate'));
1248
- assertEqual(best.registryName, 'r3', 'Most specific registry should win');
1249
- }
1250
-
1251
- // TEST120: Test accepts_request checks if registry can handle a capability request
1252
- function test120_capBlockNoMatch() {
1253
- const registry = new CapMatrix();
1254
- const composite = new CapBlock();
1255
- composite.addRegistry('empty', registry);
1256
-
1257
- try {
1258
- composite.findBestCapSet(matrixTestUrn('op=nonexistent'));
1259
- throw new Error('Expected error for non-matching capability');
1260
- } catch (e) {
1261
- assert(e instanceof CapMatrixError, 'Should be CapMatrixError');
1262
- assertEqual(e.type, 'NoSetsFound', 'Should be NoSetsFound error');
1263
- }
1264
- }
1265
-
1266
- // TEST121: Test CapBlock selects more specific cap over less specific regardless of registry order
1267
- function test121_capBlockFallbackScenario() {
1268
- const providerRegistry = new CapMatrix();
1269
- const cartridgeRegistry = new CapMatrix();
1270
-
1271
- const providerHost = new MockCapSet('provider_fallback');
1272
- const providerCap = makeCap(
1273
- 'cap:in="media:binary";op=generate_thumbnail;out="media:binary"',
1274
- 'Generic Thumbnail Provider'
1275
- );
1276
- providerRegistry.registerCapSet('provider_fallback', providerHost, [providerCap]);
1277
-
1278
- const cartridgeHost = new MockCapSet('pdf_cartridge');
1279
- const cartridgeCap = makeCap(
1280
- 'cap:ext=pdf;in="media:binary";op=generate_thumbnail;out="media:binary"',
1281
- 'PDF Thumbnail Cartridge'
1282
- );
1283
- cartridgeRegistry.registerCapSet('pdf_cartridge', cartridgeHost, [cartridgeCap]);
1284
-
1285
- const composite = new CapBlock();
1286
- composite.addRegistry('providers', providerRegistry);
1287
- composite.addRegistry('cartridges', cartridgeRegistry);
1288
-
1289
- // PDF request -> cartridge wins
1290
- const best = composite.findBestCapSet('cap:ext=pdf;in="media:binary";op=generate_thumbnail;out="media:binary"');
1291
- assertEqual(best.registryName, 'cartridges', 'Cartridge should win for PDF');
1292
-
1293
- // WAV request -> provider wins (fallback)
1294
- const bestWav = composite.findBestCapSet('cap:ext=wav;in="media:binary";op=generate_thumbnail;out="media:binary"');
1295
- assertEqual(bestWav.registryName, 'providers', 'Provider should win for wav (fallback)');
1296
- }
1297
-
1298
- // TEST122: Test CapBlock breaks specificity ties by first registered registry
1299
- function test122_capBlockCanMethod() {
1300
- const providerRegistry = new CapMatrix();
1301
- const providerHost = new MockCapSet('test_provider');
1302
- const providerCap = makeCap(matrixTestUrn('ext=pdf;op=generate'), 'Test Provider');
1303
- providerRegistry.registerCapSet('test_provider', providerHost, [providerCap]);
1304
-
1305
- const composite = new CapBlock();
1306
- composite.addRegistry('providers', providerRegistry);
1307
-
1308
- const result = composite.can(matrixTestUrn('ext=pdf;op=generate'));
1309
- assert(result.cap !== null, 'Should return cap');
1310
- assert(result.compositeHost instanceof CompositeCapSet, 'Should return CompositeCapSet');
1311
- assert(composite.acceptsRequest(matrixTestUrn('ext=pdf;op=generate')), 'Should accept matching cap');
1312
- assert(!composite.acceptsRequest(matrixTestUrn('op=nonexistent')), 'Should not accept non-matching cap');
1313
- }
1314
-
1315
- // TEST123: Test CapBlock polls all registries to find most specific match
1316
- function test123_capBlockRegistryManagement() {
1317
- const composite = new CapBlock();
1318
- const registry1 = new CapMatrix();
1319
- const registry2 = new CapMatrix();
1320
-
1321
- composite.addRegistry('r1', registry1);
1322
- composite.addRegistry('r2', registry2);
1323
- assertEqual(composite.getRegistryNames().length, 2, 'Should have 2 registries');
1159
+ // Add a cap and check it becomes an edge with from/to nodes and carries the
1160
+ // registry name we passed. This is exactly the shape the renderer depends on.
1161
+ function testCapGraphAddCapPopulatesEdgesAndNodes() {
1162
+ const graph = new CapGraph();
1163
+ const cap = makeGraphCap('media:pdf', 'media:textable', 'PDF to Text');
1164
+ graph.addCap(cap, 'registry');
1324
1165
 
1325
- assertEqual(composite.getRegistry('r1'), registry1, 'Should get correct registry');
1166
+ const edges = graph.getEdges();
1167
+ assertEqual(edges.length, 1, 'Graph must have one edge after a single addCap');
1168
+ assertEqual(edges[0].fromUrn, 'media:pdf', 'Edge fromUrn must be cap in_spec');
1169
+ assertEqual(edges[0].toUrn, 'media:textable', 'Edge toUrn must be cap out_spec');
1170
+ assertEqual(edges[0].registryName, 'registry', 'Edge must carry the registry name passed to addCap');
1326
1171
 
1327
- const removed = composite.removeRegistry('r1');
1328
- assertEqual(removed, registry1, 'Should return removed registry');
1329
- assertEqual(composite.getRegistryNames().length, 1, 'Should have 1 registry after removal');
1330
-
1331
- assertEqual(composite.getRegistry('nonexistent'), null, 'Should return null for non-existent');
1332
- }
1333
-
1334
- // TEST124: Test CapBlock returns error when no registries match the request
1335
- function test124_capGraphBasicConstruction() {
1336
- const registry = new CapMatrix();
1337
- const mockHost = { executeCap: async () => ({ textOutput: 'mock' }) };
1338
-
1339
- const cap1 = makeGraphCap('media:binary', 'media:string', 'Binary to String');
1340
- const cap2 = makeGraphCap('media:string', 'media:object', 'String to Object');
1341
- registry.registerCapSet('converter', mockHost, [cap1, cap2]);
1342
-
1343
- const cube = new CapBlock();
1344
- cube.addRegistry('converters', registry);
1345
-
1346
- const graph = cube.graph();
1347
- assertEqual(graph.getNodes().size, 3, 'Expected 3 nodes');
1348
- assertEqual(graph.getEdges().length, 2, 'Expected 2 edges');
1349
- assertEqual(graph.stats().nodeCount, 3, 'Expected 3 nodes in stats');
1350
- assertEqual(graph.stats().edgeCount, 2, 'Expected 2 edges in stats');
1351
- }
1352
-
1353
- // TEST125: Test CapBlock prefers specific cartridge over generic provider fallback
1354
- function test125_capGraphOutgoingIncoming() {
1355
- const registry = new CapMatrix();
1356
- const mockHost = { executeCap: async () => ({ textOutput: 'mock' }) };
1357
-
1358
- const cap1 = makeGraphCap('media:binary', 'media:string', 'Binary to String');
1359
- const cap2 = makeGraphCap('media:binary', 'media:object', 'Binary to Object');
1360
- registry.registerCapSet('converter', mockHost, [cap1, cap2]);
1361
-
1362
- const cube = new CapBlock();
1363
- cube.addRegistry('converters', registry);
1364
- const graph = cube.graph();
1365
-
1366
- assertEqual(graph.getOutgoing('media:binary').length, 2, 'binary should have 2 outgoing');
1367
- assertEqual(graph.getIncoming('media:string').length, 1, 'string should have 1 incoming');
1368
- assertEqual(graph.getIncoming('media:object').length, 1, 'object should have 1 incoming');
1369
- }
1370
-
1371
- // TEST126: Test composite can method returns CapCaller for capability execution
1372
- function test126_capGraphCanConvert() {
1373
- const registry = new CapMatrix();
1374
- const mockHost = { executeCap: async () => ({ textOutput: 'mock' }) };
1375
-
1376
- const cap1 = makeGraphCap('media:binary', 'media:string', 'Binary to String');
1377
- const cap2 = makeGraphCap('media:string', 'media:object', 'String to Object');
1378
- registry.registerCapSet('converter', mockHost, [cap1, cap2]);
1379
-
1380
- const cube = new CapBlock();
1381
- cube.addRegistry('converters', registry);
1382
- const graph = cube.graph();
1383
-
1384
- assert(graph.canConvert('media:binary', 'media:string'), 'Direct conversion');
1385
- assert(graph.canConvert('media:string', 'media:object'), 'Direct conversion');
1386
- assert(graph.canConvert('media:binary', 'media:object'), 'Transitive conversion');
1387
- assert(graph.canConvert('media:binary', 'media:binary'), 'Same spec');
1388
- assert(!graph.canConvert('media:object', 'media:binary'), 'Impossible conversion');
1389
- assert(!graph.canConvert('media:nonexistent', 'media:string'), 'Nonexistent node');
1390
- }
1391
-
1392
- // TEST127: Test CapGraph adds nodes and edges from capability definitions
1393
- function test127_capGraphFindPath() {
1394
- const registry = new CapMatrix();
1395
- const mockHost = { executeCap: async () => ({ textOutput: 'mock' }) };
1396
-
1397
- const cap1 = makeGraphCap('media:binary', 'media:string', 'Binary to String');
1398
- const cap2 = makeGraphCap('media:string', 'media:object', 'String to Object');
1399
- registry.registerCapSet('converter', mockHost, [cap1, cap2]);
1400
-
1401
- const cube = new CapBlock();
1402
- cube.addRegistry('converters', registry);
1403
- const graph = cube.graph();
1404
-
1405
- // Direct path
1406
- let path = graph.findPath('media:binary', 'media:string');
1407
- assert(path !== null, 'Should find direct path');
1408
- assertEqual(path.length, 1, 'Direct path length should be 1');
1409
-
1410
- // Transitive path
1411
- path = graph.findPath('media:binary', 'media:object');
1412
- assert(path !== null, 'Should find transitive path');
1413
- assertEqual(path.length, 2, 'Transitive path length should be 2');
1414
-
1415
- // No path
1416
- path = graph.findPath('media:object', 'media:binary');
1417
- assertEqual(path, null, 'Should not find impossible path');
1418
-
1419
- // Same spec
1420
- path = graph.findPath('media:binary', 'media:binary');
1421
- assert(path !== null, 'Same spec should return empty path');
1422
- assertEqual(path.length, 0, 'Same spec path should be empty');
1423
- }
1424
-
1425
- // TEST128: Test CapGraph tracks outgoing and incoming edges for spec conversions
1426
- function test128_capGraphFindAllPaths() {
1427
- const registry = new CapMatrix();
1428
- const mockHost = { executeCap: async () => ({ textOutput: 'mock' }) };
1429
-
1430
- const cap1 = makeGraphCap('media:binary', 'media:string', 'Binary to String');
1431
- const cap2 = makeGraphCap('media:string', 'media:object', 'String to Object');
1432
- const cap3 = makeGraphCap('media:binary', 'media:object', 'Binary to Object (direct)');
1433
- registry.registerCapSet('converter', mockHost, [cap1, cap2, cap3]);
1434
-
1435
- const cube = new CapBlock();
1436
- cube.addRegistry('converters', registry);
1437
- const graph = cube.graph();
1438
-
1439
- const paths = graph.findAllPaths('media:binary', 'media:object', 3);
1440
- assertEqual(paths.length, 2, 'Should find 2 paths');
1441
- assertEqual(paths[0].length, 1, 'Shortest path first (direct)');
1442
- assertEqual(paths[1].length, 2, 'Longer path second (via string)');
1172
+ const nodes = graph.getNodes();
1173
+ assert(nodes.has('media:pdf'), 'from_spec must appear as a node');
1174
+ assert(nodes.has('media:textable'), 'to_spec must appear as a node');
1443
1175
  }
1444
1176
 
1445
- // TEST129: Test CapGraph detects direct and indirect conversion paths between specs
1446
- function test129_capGraphGetDirectEdges() {
1447
- const registry1 = new CapMatrix();
1448
- const registry2 = new CapMatrix();
1449
- const mockHost1 = { executeCap: async () => ({ textOutput: 'mock1' }) };
1450
- const mockHost2 = { executeCap: async () => ({ textOutput: 'mock2' }) };
1177
+ // getOutgoing takes a concrete source URN and returns edges whose from_spec
1178
+ // the source conforms to. It must NOT be a plain string lookup.
1179
+ function testCapGraphGetOutgoingConformsToMatching() {
1180
+ const graph = new CapGraph();
1181
+ graph.addCap(makeGraphCap('media:textable', 'media:embedding-vector', 'Embed text'), 'registry');
1451
1182
 
1452
- const cap1 = makeGraphCap('media:binary', 'media:string', 'Generic Binary to String');
1453
- const capUrn2 = CapUrn.fromString('cap:ext=pdf;in="media:binary";op=convert;out="media:string"');
1454
- const cap2 = new Cap(capUrn2, 'PDF Binary to String', 'convert', 'PDF Binary to String');
1183
+ // 'media:txt;textable' conforms to 'media:textable' renderer relies on
1184
+ // this for the browse-mode fan-out from specific source URNs to caps that
1185
+ // accept a broader media pattern.
1186
+ const outgoingFromSpecific = graph.getOutgoing('media:txt;textable');
1187
+ assertEqual(outgoingFromSpecific.length, 1, 'Specific URN must match broader cap input');
1455
1188
 
1456
- registry1.registerCapSet('converter1', mockHost1, [cap1]);
1457
- registry2.registerCapSet('converter2', mockHost2, [cap2]);
1189
+ // The broad URN still matches its own edge.
1190
+ const outgoingFromBroad = graph.getOutgoing('media:textable');
1191
+ assertEqual(outgoingFromBroad.length, 1, 'Exact URN must match');
1458
1192
 
1459
- const cube = new CapBlock();
1460
- cube.addRegistry('reg1', registry1);
1461
- cube.addRegistry('reg2', registry2);
1462
- const graph = cube.graph();
1463
-
1464
- const edges = graph.getDirectEdges('media:binary', 'media:string');
1465
- assertEqual(edges.length, 2, 'Expected 2 direct edges');
1466
- assertEqual(edges[0].cap.title, 'PDF Binary to String', 'More specific edge first');
1467
- assert(edges[0].specificity > edges[1].specificity, 'First edge should have higher specificity');
1193
+ // A totally unrelated URN must not match.
1194
+ const outgoingFromUnrelated = graph.getOutgoing('media:image;png');
1195
+ assertEqual(outgoingFromUnrelated.length, 0, 'Unrelated URN must not match');
1468
1196
  }
1469
1197
 
1470
- // TEST130: Test CapGraph finds shortest path for spec conversion chain
1471
- function test130_capGraphStats() {
1472
- const registry = new CapMatrix();
1473
- const mockHost = { executeCap: async () => ({ textOutput: 'mock' }) };
1198
+ // Each edge must carry the registry name it was added with. This is how
1199
+ // the renderer colours/groups edges by provenance in browse mode.
1200
+ function testCapGraphDistinctRegistryNames() {
1201
+ const graph = new CapGraph();
1202
+ graph.addCap(makeGraphCap('media:pdf', 'media:textable', 'PDF to Text'), 'providers');
1203
+ graph.addCap(makeGraphCap('media:textable', 'media:embedding-vector', 'Embed'), 'cartridges');
1474
1204
 
1475
- const cap1 = makeGraphCap('media:binary', 'media:string', 'Binary to String');
1476
- const cap2 = makeGraphCap('media:string', 'media:object', 'String to Object');
1477
- const cap3 = makeGraphCap('media:binary', 'media:json', 'Binary to JSON');
1478
- registry.registerCapSet('converter', mockHost, [cap1, cap2, cap3]);
1205
+ const edges = graph.getEdges();
1206
+ assertEqual(edges.length, 2, 'Two caps must produce two edges');
1479
1207
 
1480
- const cube = new CapBlock();
1481
- cube.addRegistry('converters', registry);
1482
- const graph = cube.graph();
1483
- const stats = graph.stats();
1484
-
1485
- assertEqual(stats.nodeCount, 4, '4 unique nodes');
1486
- assertEqual(stats.edgeCount, 3, '3 edges');
1487
- assertEqual(stats.inputUrnCount, 2, '2 input URNs');
1488
- assertEqual(stats.outputUrnCount, 3, '3 output URNs');
1208
+ const names = new Set(edges.map(e => e.registryName));
1209
+ assert(names.has('providers'), 'providers registry name must be preserved');
1210
+ assert(names.has('cartridges'), 'cartridges registry name must be preserved');
1489
1211
  }
1490
1212
 
1491
- // TEST131: Test CapGraph finds all conversion paths sorted by length
1492
- function test131_capGraphWithCapBlock() {
1493
- const providerRegistry = new CapMatrix();
1494
- const cartridgeRegistry = new CapMatrix();
1495
- const providerHost = { executeCap: async () => ({ textOutput: 'provider' }) };
1496
- const cartridgeHost = { executeCap: async () => ({ textOutput: 'cartridge' }) };
1497
-
1498
- const providerCap = makeGraphCap('media:binary', 'media:string', 'Provider Binary to String');
1499
- providerRegistry.registerCapSet('provider', providerHost, [providerCap]);
1500
-
1501
- const cartridgeCap = makeGraphCap('media:string', 'media:object', 'Cartridge String to Object');
1502
- cartridgeRegistry.registerCapSet('cartridge', cartridgeHost, [cartridgeCap]);
1503
-
1504
- const cube = new CapBlock();
1505
- cube.addRegistry('providers', providerRegistry);
1506
- cube.addRegistry('cartridges', cartridgeRegistry);
1507
- const graph = cube.graph();
1508
-
1509
- assert(graph.canConvert('media:binary', 'media:object'), 'Should convert across registries');
1510
- const path = graph.findPath('media:binary', 'media:object');
1511
- assert(path !== null, 'Should find path');
1512
- assertEqual(path.length, 2, 'Path through 2 registries');
1513
- assertEqual(path[0].registryName, 'providers', 'First edge from providers');
1514
- assertEqual(path[1].registryName, 'cartridges', 'Second edge from cartridges');
1515
- }
1516
-
1517
- // TEST132: N/A (already covered by TEST129)
1518
- // TEST133: N/A (already covered by TEST131)
1519
- // TEST134: N/A (already covered by TEST130)
1520
-
1521
1213
  // ============================================================================
1522
1214
  // caller.rs: TEST156-TEST159
1523
1215
  // ============================================================================
@@ -1930,73 +1622,6 @@ function testJS_stdinSourceNullData() {
1930
1622
  assertEqual(source.data, null, 'Data should be null');
1931
1623
  }
1932
1624
 
1933
- function testJS_argsPassedToExecuteCap() {
1934
- let receivedArgs = null;
1935
- const mockHost = {
1936
- executeCap: async (capUrn, args) => {
1937
- receivedArgs = args;
1938
- return { textOutput: 'ok' };
1939
- }
1940
- };
1941
-
1942
- const cap = new Cap(
1943
- CapUrn.fromString('cap:in="media:void";op=test;out="media:string"'),
1944
- 'Test Cap',
1945
- 'test-command'
1946
- );
1947
- const registry = new CapMatrix();
1948
- registry.registerCapSet('test', mockHost, [cap]);
1949
- const cube = new CapBlock();
1950
- cube.addRegistry('test', registry);
1951
-
1952
- const args = [new CapArgumentValue('media:void', new Uint8Array([1, 2, 3]))];
1953
- const { compositeHost } = cube.can('cap:in="media:void";op=test;out="media:string"');
1954
-
1955
- return compositeHost.executeCap(
1956
- 'cap:in="media:void";op=test;out="media:string"',
1957
- args
1958
- ).then(() => {
1959
- assert(receivedArgs !== null, 'Should receive arguments');
1960
- assert(Array.isArray(receivedArgs), 'Should receive array');
1961
- assertEqual(receivedArgs.length, 1, 'Should have one argument');
1962
- assertEqual(receivedArgs[0].mediaUrn, 'media:void', 'Correct mediaUrn');
1963
- assertEqual(receivedArgs[0].value.length, 3, 'Correct data length');
1964
- });
1965
- }
1966
-
1967
- function testJS_binaryArgPassedToExecuteCap() {
1968
- let receivedArgs = null;
1969
- const mockHost = {
1970
- executeCap: async (capUrn, args) => {
1971
- receivedArgs = args;
1972
- return { textOutput: 'ok' };
1973
- }
1974
- };
1975
-
1976
- const cap = new Cap(
1977
- CapUrn.fromString('cap:in="media:void";op=test;out="media:string"'),
1978
- 'Test Cap',
1979
- 'test-command'
1980
- );
1981
- const registry = new CapMatrix();
1982
- registry.registerCapSet('test', mockHost, [cap]);
1983
- const cube = new CapBlock();
1984
- cube.addRegistry('test', registry);
1985
-
1986
- const binaryArg = new CapArgumentValue('media:pdf', new Uint8Array([0x89, 0x50, 0x4E, 0x47]));
1987
- const { compositeHost } = cube.can('cap:in="media:void";op=test;out="media:string"');
1988
-
1989
- return compositeHost.executeCap(
1990
- 'cap:in="media:void";op=test;out="media:string"',
1991
- [binaryArg]
1992
- ).then(() => {
1993
- assert(receivedArgs !== null, 'Should receive arguments');
1994
- assertEqual(receivedArgs[0].mediaUrn, 'media:pdf', 'Correct mediaUrn');
1995
- assertEqual(receivedArgs[0].value[0], 0x89, 'First byte check');
1996
- assertEqual(receivedArgs[0].value.length, 4, 'Correct data length');
1997
- });
1998
- }
1999
-
2000
1625
  function testJS_mediaSpecConstruction() {
2001
1626
  const spec1 = new MediaSpec('text/plain', 'https://capdag.com/schema/str', null, 'String', null, 'media:string');
2002
1627
  assertEqual(spec1.contentType, 'text/plain', 'Should have content type');
@@ -5547,24 +5172,13 @@ async function runTests() {
5547
5172
  runTest('TEST109: extensions_with_metadata_and_validation', test109_extensionsWithMetadataAndValidation);
5548
5173
  runTest('TEST110: multiple_extensions', test110_multipleExtensions);
5549
5174
 
5550
- // cap_matrix.rs: TEST117-TEST131
5551
- console.log('\n--- cap_matrix.rs ---');
5552
- runTest('TEST117: cap_block_more_specific_wins', test117_capBlockMoreSpecificWins);
5553
- runTest('TEST118: cap_block_tie_goes_to_first', test118_capBlockTieGoesToFirst);
5554
- runTest('TEST119: cap_block_polls_all', test119_capBlockPollsAll);
5555
- runTest('TEST120: cap_block_no_match', test120_capBlockNoMatch);
5556
- runTest('TEST121: cap_block_fallback_scenario', test121_capBlockFallbackScenario);
5557
- runTest('TEST122: cap_block_can_method', test122_capBlockCanMethod);
5558
- runTest('TEST123: cap_block_registry_management', test123_capBlockRegistryManagement);
5559
- runTest('TEST124: cap_graph_basic_construction', test124_capGraphBasicConstruction);
5560
- runTest('TEST125: cap_graph_outgoing_incoming', test125_capGraphOutgoingIncoming);
5561
- runTest('TEST126: cap_graph_can_convert', test126_capGraphCanConvert);
5562
- runTest('TEST127: cap_graph_find_path', test127_capGraphFindPath);
5563
- runTest('TEST128: cap_graph_find_all_paths', test128_capGraphFindAllPaths);
5564
- runTest('TEST129: cap_graph_direct_edges_sorted_by_specificity', test129_capGraphGetDirectEdges);
5565
- runTest('TEST130: cap_graph_stats', test130_capGraphStats);
5566
- runTest('TEST131: cap_block_graph_integration', test131_capGraphWithCapBlock);
5567
- console.log(' SKIP TEST132-134: N/A (already covered by TEST129-131)');
5175
+ // cap-graph-renderer.js uses CapGraph in browse mode (static registry from
5176
+ // /api/capabilities). These tests guard the minimal API the renderer relies
5177
+ // on: new CapGraph(), addCap(cap, registryName), getEdges(), getOutgoing().
5178
+ console.log('\n--- cap_graph (browse-mode API used by cap-graph-renderer) ---');
5179
+ runTest('cap_graph: add_cap_populates_edges_and_nodes', testCapGraphAddCapPopulatesEdgesAndNodes);
5180
+ runTest('cap_graph: get_outgoing_conforms_to_matching', testCapGraphGetOutgoingConformsToMatching);
5181
+ runTest('cap_graph: distinct_registry_names_recorded_per_edge', testCapGraphDistinctRegistryNames);
5568
5182
 
5569
5183
  // caller.rs: TEST156-TEST159
5570
5184
  console.log('\n--- caller.rs (StdinSource) ---');
@@ -5608,10 +5222,6 @@ async function runTests() {
5608
5222
  runTest('JS: media_spec_documentation_propagates_through_resolve', testJS_mediaSpecDocumentationPropagatesThroughResolve);
5609
5223
  runTest('JS: stdin_source_kind_constants', testJS_stdinSourceKindConstants);
5610
5224
  runTest('JS: stdin_source_null_data', testJS_stdinSourceNullData);
5611
- const p1 = runTest('JS: args_passed_to_executeCap', testJS_argsPassedToExecuteCap);
5612
- if (p1) await p1;
5613
- const p2 = runTest('JS: binary_arg_passed_to_executeCap', testJS_binaryArgPassedToExecuteCap);
5614
- if (p2) await p2;
5615
5225
  runTest('JS: media_spec_construction', testJS_mediaSpecConstruction);
5616
5226
 
5617
5227
  // cartridge_repo: CartridgeRepoServer and CartridgeRepoClient tests
package/package.json CHANGED
@@ -40,5 +40,5 @@
40
40
  "pretest": "npm run build:parser",
41
41
  "test": "node capdag.test.js"
42
42
  },
43
- "version": "0.140.310"
43
+ "version": "0.145.321"
44
44
  }