@warmhub/sdk-ts 0.65.0 → 0.67.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -3,10 +3,21 @@ import { TRPCClientError, createTRPCProxyClient, splitLink, httpBatchLink, httpL
3
3
  // src/index.ts
4
4
 
5
5
  // ../rules/src/builtin-shapes.ts
6
- var BUILTIN_SHAPE_NAMES = ["Pair", "Triple", "Set", "List"];
6
+ var BUILTIN_SHAPE_NAMES = ["Pair", "Set", "List"];
7
+ var RETIRED_COLLECTION_SHAPE_NAMES = ["Triple"];
8
+ var RESERVED_COLLECTION_SHAPE_NAMES = [
9
+ ...BUILTIN_SHAPE_NAMES,
10
+ ...RETIRED_COLLECTION_SHAPE_NAMES
11
+ ];
7
12
  function isBuiltinCollectionShape(name) {
8
13
  return BUILTIN_SHAPE_NAMES.includes(name);
9
14
  }
15
+ function isRetiredCollectionShape(name) {
16
+ return RETIRED_COLLECTION_SHAPE_NAMES.includes(name);
17
+ }
18
+ function isReservedCollectionShape(name) {
19
+ return RESERVED_COLLECTION_SHAPE_NAMES.includes(name);
20
+ }
10
21
  var BUILTIN_CONTENT_SHAPE_NAMES = ["Content"];
11
22
  var STORED_CONTENT_NAMES = ["Readme", "Agents"];
12
23
  var SYNTHESIZED_CONTENT_NAMES = ["LlmsTxt"];
@@ -29,29 +40,6 @@ var DEFAULT_STREAM_APPEND_CHUNK_SIZE = 1e3;
29
40
  var MAX_STREAM_APPEND_OPERATION_COUNT = 1e4;
30
41
 
31
42
  // ../rules/src/commit-types.ts
32
- function isCollectionAbout(value) {
33
- if (typeof value !== "object" || value === null || Array.isArray(value))
34
- return false;
35
- const record = value;
36
- const keys = Object.keys(record);
37
- if (keys.length !== 1) return false;
38
- const key = keys[0];
39
- if (key !== "pair" && key !== "triple" && key !== "set" && key !== "list")
40
- return false;
41
- return Array.isArray(record[key]);
42
- }
43
- function collectionAboutType(about) {
44
- if ("pair" in about) return "pair";
45
- if ("triple" in about) return "triple";
46
- if ("set" in about) return "set";
47
- return "list";
48
- }
49
- function collectionAboutMembers(about) {
50
- if ("pair" in about) return about.pair;
51
- if ("triple" in about) return about.triple;
52
- if ("set" in about) return about.set;
53
- return about.list;
54
- }
55
43
  function splitLocalPath(name) {
56
44
  const idx = name.indexOf("/");
57
45
  if (idx === -1) return null;
@@ -364,23 +352,8 @@ var PLATFORM_STATUS_STATUSES = [
364
352
  enum: PLATFORM_STATUS_STATUSES.map((status) => status.key)}});
365
353
 
366
354
  // ../rules/src/tokens.ts
367
- var ALLOC_TOKEN_RE = /\$(\d+)/g;
368
- var REF_TOKEN_RE = /#(\d+)/g;
355
+ var COMMIT_TOKEN_SYNTAX_REMOVED_MESSAGE = "$N/#N commit-token syntax is no longer supported. Use explicit names and explicit wrefs. For assertions about newly created things, create the thing with a deterministic name and set about to that wref in the same commit.";
369
356
  var ANY_TOKEN_RE = /[$#]\d+/;
370
- function findAllocTokens(s) {
371
- const tokens = [];
372
- for (const m of s.matchAll(ALLOC_TOKEN_RE)) {
373
- tokens.push(Number.parseInt(m[1], 10));
374
- }
375
- return tokens;
376
- }
377
- function findRefTokens(s) {
378
- const tokens = [];
379
- for (const m of s.matchAll(REF_TOKEN_RE)) {
380
- tokens.push(Number.parseInt(m[1], 10));
381
- }
382
- return tokens;
383
- }
384
357
  function hasAnyTokens(s) {
385
358
  return ANY_TOKEN_RE.test(s);
386
359
  }
@@ -388,146 +361,35 @@ function hasAnyTokens(s) {
388
361
  // ../rules/src/preflight-commit.ts
389
362
  function preflightCommitDiagnostics(operations, options) {
390
363
  const errors = [];
391
- tokenHygiene(operations, errors);
392
- illegalOpSequences(operations, errors);
364
+ rejectCommitTokenSyntax(operations, errors);
365
+ illegalOpSequences(operations, errors, options?.checkAddAdd ?? true);
393
366
  return errors;
394
367
  }
395
368
  function getOpName(op) {
396
369
  return op.name;
397
370
  }
398
- function collectionAboutMembersOrEmpty(about) {
399
- if (about && typeof about !== "string" && isCollectionAbout(about)) {
400
- return collectionAboutMembers(about);
401
- }
402
- return [];
403
- }
404
371
  function tokenStringFields(op) {
405
- const fields = [getOpName(op)];
372
+ const fields = [getOpName(op), op.newName];
406
373
  if (typeof op.about === "string") {
407
374
  fields.push(op.about);
408
- } else {
409
- fields.push(...collectionAboutMembersOrEmpty(op.about));
410
375
  }
411
376
  if (op.members) {
412
377
  fields.push(...op.members);
413
378
  }
414
379
  return fields;
415
380
  }
416
- function collectMisusedAllocFields(op) {
417
- const result = [];
418
- if (op.operation === "add") {
419
- if (typeof op.about === "string") {
420
- result.push({ value: op.about });
421
- }
422
- for (const m of collectionAboutMembersOrEmpty(op.about)) {
423
- result.push({ value: m, context: "collection member" });
424
- }
425
- if (op.members) {
426
- for (const m of op.members) {
427
- result.push({ value: m, context: "collection member" });
428
- }
429
- }
430
- } else {
431
- const name = getOpName(op);
432
- if (name) {
433
- result.push({ value: name });
434
- }
435
- }
436
- return result;
437
- }
438
- function tokenHygiene(operations, errors) {
439
- let anyTokens = false;
440
- for (const op of operations) {
441
- for (const f of tokenStringFields(op)) {
442
- if (f && hasAnyTokens(f)) {
443
- anyTokens = true;
444
- break;
445
- }
446
- }
447
- if (anyTokens) break;
448
- }
449
- if (!anyTokens) return;
450
- const allocations = /* @__PURE__ */ new Map();
451
- for (let i = 0; i < operations.length; i++) {
452
- const op = operations[i];
453
- if (!op || op.operation !== "add" || !op.name) continue;
454
- const local = splitLocalPath(op.name);
455
- if (!local) {
456
- const allocs = findAllocTokens(op.name);
457
- if (allocs.length > 0) {
458
- errors.push({
459
- code: "ALLOC_TOKEN_IN_SHAPE_NAME",
460
- operationIndex: i,
461
- message: `Allocation token $${allocs[0]} not allowed in shape name "${op.name}"`
462
- });
463
- }
464
- continue;
465
- }
466
- const segments = local.bareName.split("/");
467
- const lastSegment = segments[segments.length - 1];
468
- const lastSegAllocs = lastSegment ? findAllocTokens(lastSegment) : [];
469
- for (let s = 0; s < segments.length - 1; s++) {
470
- const seg = segments[s];
471
- if (!seg) continue;
472
- const earlyAllocs = findAllocTokens(seg);
473
- if (earlyAllocs.length > 0) {
474
- errors.push({
475
- code: "ALLOC_TOKEN_WRONG_SEGMENT",
476
- operationIndex: i,
477
- message: `Allocation token $${earlyAllocs[0]} must be in the last segment of ADD name "${op.name}"`
478
- });
479
- }
480
- }
481
- for (const tokenNum of lastSegAllocs) {
482
- if (tokenNum <= 0) {
483
- errors.push({
484
- code: "INVALID_TOKEN_NUMBER",
485
- operationIndex: i,
486
- message: `Token number must be positive: $${tokenNum}`
487
- });
488
- }
489
- if (allocations.has(tokenNum)) {
490
- errors.push({
491
- code: "DUPLICATE_ALLOC_TOKEN",
492
- operationIndex: i,
493
- message: `Token $${tokenNum} allocated more than once`
494
- });
495
- }
496
- allocations.set(tokenNum, { opIndex: i });
497
- }
498
- }
381
+ function rejectCommitTokenSyntax(operations, errors) {
499
382
  for (let i = 0; i < operations.length; i++) {
500
383
  const op = operations[i];
501
384
  if (!op) continue;
502
385
  for (const field of tokenStringFields(op)) {
503
- if (!field) continue;
504
- const refs = findRefTokens(field);
505
- for (const tokenNum of refs) {
506
- if (tokenNum <= 0) {
507
- errors.push({
508
- code: "INVALID_TOKEN_NUMBER",
509
- operationIndex: i,
510
- message: `Token number must be positive: #${tokenNum}`
511
- });
512
- }
513
- if (!allocations.has(tokenNum)) {
514
- errors.push({
515
- code: "UNRESOLVED_REF_TOKEN",
516
- operationIndex: i,
517
- message: `Reference #${tokenNum} has no matching allocation $${tokenNum}`
518
- });
519
- }
520
- }
521
- }
522
- const misusedFields = collectMisusedAllocFields(op);
523
- for (const { value, context } of misusedFields) {
524
- const allocs = findAllocTokens(value);
525
- if (allocs.length > 0) {
386
+ if (field && hasAnyTokens(field)) {
526
387
  errors.push({
527
- code: "MISUSED_ALLOC_TOKEN",
388
+ code: "COMMIT_TOKEN_SYNTAX_REMOVED",
528
389
  operationIndex: i,
529
- message: context ? `Use #${allocs[0]} to reference token ${allocs[0]} in ${context}, not $${allocs[0]}` : `Use #${allocs[0]} to reference token ${allocs[0]}, not $${allocs[0]}`
390
+ message: COMMIT_TOKEN_SYNTAX_REMOVED_MESSAGE
530
391
  });
392
+ break;
531
393
  }
532
394
  }
533
395
  }
@@ -553,6 +415,13 @@ function illegalOpSequences(operations, errors, checkAddAdd) {
553
415
  const curr = history[i];
554
416
  if (!prev || !curr) continue;
555
417
  const pair = `${prev.operation}+${curr.operation}`;
418
+ if (checkAddAdd && pair === "add+add") {
419
+ errors.push({
420
+ code: "ILLEGAL_OP_SEQUENCE",
421
+ operationIndex: curr.index,
422
+ message: `Cannot add "${qualName}" twice in the same commit`
423
+ });
424
+ }
556
425
  if (pair === "revise+add") {
557
426
  errors.push({
558
427
  code: "ILLEGAL_OP_SEQUENCE",
@@ -565,8 +434,10 @@ function illegalOpSequences(operations, errors, checkAddAdd) {
565
434
  }
566
435
 
567
436
  // ../rules/src/preflight-operation.ts
568
- var collectionTypes = ["pair", "triple", "set", "list"];
437
+ var collectionTypes = ["pair", "set", "list"];
569
438
  var collectionOps = ["add", "revise"];
439
+ var COLLECTION_CREATE_REQUIRES_NAME_MESSAGE = "Collection create requires a name. Collections are ordinary named things (ADR 0004).";
440
+ var COLLECTION_ABOUT_REMOVED_MESSAGE = 'about accepts a wref. Create the collection as its own named operation, then point the assertion at it. Prefer deterministic relationship names, for example: [{"operation":"add","kind":"collection","type":"pair","name":"a-b-relationship","members":["A","B"]},{"operation":"add","kind":"assertion","about":"Pair/a-b-relationship","name":"Assertion/example","data":{}}]. For CLI usage, use wh commit submit --file with the two operations.';
570
441
  function preflightOpDiagnostics(op, operationIndex) {
571
442
  const errors = [];
572
443
  errors.push(...builtinShapeGuard(op, operationIndex));
@@ -579,17 +450,36 @@ function preflightOpDiagnostics(op, operationIndex) {
579
450
  function builtinShapeGuard(op, operationIndex) {
580
451
  const errors = [];
581
452
  const name = op.name;
582
- if (op.kind === "shape" && name && isBuiltinShape(name)) {
453
+ if (name && isRetiredCollectionShape(name)) {
454
+ errors.push({
455
+ code: "RESERVED_NAME",
456
+ operationIndex,
457
+ message: `Shape "${name}" is a retired collection shape and cannot be written manually`
458
+ });
459
+ }
460
+ if (op.operation === "rename" && (op.kind === "shape" || op.name !== void 0 && !splitLocalPath(op.name)) && op.newName && isRetiredCollectionShape(op.newName)) {
461
+ errors.push({
462
+ code: "RESERVED_NAME",
463
+ operationIndex,
464
+ message: `Shape "${op.newName}" is a retired collection shape and cannot be written manually`
465
+ });
466
+ } else if (op.operation !== "retract" && op.kind === "shape" && name && isBuiltinShape(name)) {
583
467
  errors.push({
584
468
  code: "RESERVED_NAME",
585
469
  operationIndex,
586
470
  message: `Shape "${name}" is a built-in shape and cannot be ${op.operation === "add" ? "created" : "revised"} manually`
587
471
  });
588
472
  }
589
- if (op.kind === "thing" && name) {
473
+ if (name) {
590
474
  const local = splitLocalPath(name);
591
- if (local && isBuiltinCollectionShape(local.shapePrefix)) {
592
- const message = op.operation === "add" ? `Cannot add kind="thing" under built-in shape "${local.shapePrefix}". Use kind="collection" or the about sugar instead.` : `Cannot revise kind="thing" under built-in shape "${local.shapePrefix}". Collections are immutable.`;
475
+ if (local && isRetiredCollectionShape(local.shapePrefix)) {
476
+ errors.push({
477
+ code: "VALIDATION_ERROR",
478
+ operationIndex,
479
+ message: `Cannot ${op.operation} under retired collection shape "${local.shapePrefix}". Triple is read-only and retired for new collection writes.`
480
+ });
481
+ } else if (op.kind === "thing" && local && isBuiltinCollectionShape(local.shapePrefix)) {
482
+ const message = op.operation === "add" ? `Cannot add kind="thing" under built-in shape "${local.shapePrefix}". Use kind="collection" instead.` : `Cannot revise kind="thing" under built-in shape "${local.shapePrefix}". Use kind="collection" to revise a collection.`;
593
483
  errors.push({
594
484
  code: "VALIDATION_ERROR",
595
485
  operationIndex,
@@ -627,109 +517,100 @@ function contentNameGuard(op, operationIndex) {
627
517
  function plusSignGuard(op, operationIndex) {
628
518
  const errors = [];
629
519
  const name = op.name;
630
- if (op.kind === "collection") return errors;
631
- if (name?.includes("+")) {
632
- const local = splitLocalPath(name);
633
- if (local && isBuiltinCollectionShape(local.shapePrefix)) return errors;
520
+ if (op.newName?.includes("+")) {
634
521
  errors.push({
635
522
  code: "VALIDATION_ERROR",
636
523
  operationIndex,
637
- message: `Name "${name}" contains reserved character "+". The "+" character is reserved for collection names.`
638
- });
639
- }
640
- return errors;
641
- }
642
- function validateCollectionAbouts(op, operationIndex) {
643
- const errors = [];
644
- if (!op.about || typeof op.about === "string") return errors;
645
- if (!isCollectionAbout(op.about)) {
646
- const keys = typeof op.about === "object" && op.about !== null ? Object.keys(op.about) : [];
647
- errors.push({
648
- code: "VALIDATION_ERROR",
649
- operationIndex,
650
- message: `Structured about must have exactly one key: pair, triple, set, or list. Got: ${keys.join(", ") || typeof op.about}`
524
+ message: `Name "${op.newName}" contains reserved character "+". The "+" character is reserved for the historical collection auto-name namespace and is not allowed in user-supplied names.`
651
525
  });
652
526
  return errors;
653
527
  }
654
- const tag = collectionAboutType(op.about);
655
- const members = collectionAboutMembers(op.about);
656
- for (let i = 0; i < members.length; i++) {
657
- if (typeof members[i] !== "string") {
528
+ if (name?.includes("+")) {
529
+ if (op.kind === "collection" && op.operation === "add") {
658
530
  errors.push({
659
531
  code: "VALIDATION_ERROR",
660
532
  operationIndex,
661
- message: `Collection member at index ${i} must be a string, got ${typeof members[i]}`
533
+ message: `Name "${name}" contains reserved character "+". The "+" character is reserved for the historical collection auto-name namespace and is not allowed in user-supplied names.`
662
534
  });
535
+ return errors;
663
536
  }
664
- }
665
- const arityError = collectionArityError(tag, members);
666
- if (arityError) {
537
+ if (op.kind === "collection") return errors;
538
+ const local = splitLocalPath(name);
539
+ if (local && isReservedCollectionShape(local.shapePrefix)) return errors;
667
540
  errors.push({
668
541
  code: "VALIDATION_ERROR",
669
542
  operationIndex,
670
- message: arityError
543
+ message: `Name "${name}" contains reserved character "+". The "+" character is reserved for the historical collection auto-name namespace and is not allowed in user-supplied names.`
671
544
  });
672
545
  }
673
546
  return errors;
674
547
  }
548
+ function validateCollectionAbouts(op, operationIndex) {
549
+ const errors = [];
550
+ if (!op.about || typeof op.about === "string") return errors;
551
+ errors.push({
552
+ code: "VALIDATION_ERROR",
553
+ operationIndex,
554
+ message: COLLECTION_ABOUT_REMOVED_MESSAGE
555
+ });
556
+ return errors;
557
+ }
675
558
  function validateCollectionOps(op, operationIndex) {
676
559
  const errors = [];
677
560
  if (op.kind !== "collection") return errors;
678
561
  if (!collectionOps.includes(op.operation)) {
562
+ return errors;
563
+ }
564
+ if (op.operation === "add" && !op.name) {
679
565
  errors.push({
680
566
  code: "VALIDATION_ERROR",
681
567
  operationIndex,
682
- message: `Collection kind only supports "add" or "revise" operation, got "${op.operation}"`
568
+ message: COLLECTION_CREATE_REQUIRES_NAME_MESSAGE
683
569
  });
684
- return errors;
685
570
  }
686
- if (op.operation === "add") {
687
- if (!op.type || !collectionTypes.includes(op.type)) {
688
- errors.push({
689
- code: "VALIDATION_ERROR",
690
- operationIndex,
691
- message: `Collection "type" must be one of: pair, triple, set, list. Got: "${op.type ?? ""}"`
692
- });
693
- }
694
- if (!op.members || !Array.isArray(op.members)) {
695
- errors.push({
696
- code: "VALIDATION_ERROR",
697
- operationIndex,
698
- message: 'Collection requires a "members" array'
699
- });
700
- } else {
701
- for (let i = 0; i < op.members.length; i++) {
702
- if (typeof op.members[i] !== "string") {
703
- errors.push({
704
- code: "VALIDATION_ERROR",
705
- operationIndex,
706
- message: `Collection member at index ${i} must be a string`
707
- });
708
- }
709
- }
710
- }
711
- if (op.type && op.members) {
712
- const arityError = collectionArityError(
713
- op.type,
714
- op.members
715
- );
716
- if (arityError) {
571
+ if (!op.type || !collectionTypes.includes(op.type)) {
572
+ errors.push({
573
+ code: "VALIDATION_ERROR",
574
+ operationIndex,
575
+ message: `Collection "type" must be one of: pair, set, list. Got: "${op.type ?? ""}"`
576
+ });
577
+ }
578
+ if (!op.members || !Array.isArray(op.members)) {
579
+ errors.push({
580
+ code: "VALIDATION_ERROR",
581
+ operationIndex,
582
+ message: 'Collection requires a "members" array'
583
+ });
584
+ } else {
585
+ for (let i = 0; i < op.members.length; i++) {
586
+ if (typeof op.members[i] !== "string") {
717
587
  errors.push({
718
588
  code: "VALIDATION_ERROR",
719
589
  operationIndex,
720
- message: arityError
590
+ message: `Collection member at index ${i} must be a string`
721
591
  });
722
592
  }
723
593
  }
724
594
  }
595
+ if (op.type && op.members) {
596
+ const arityError = collectionArityError(
597
+ op.type,
598
+ op.members
599
+ );
600
+ if (arityError) {
601
+ errors.push({
602
+ code: "VALIDATION_ERROR",
603
+ operationIndex,
604
+ message: arityError
605
+ });
606
+ }
607
+ }
725
608
  return errors;
726
609
  }
727
610
  function collectionArityError(tag, members) {
728
611
  switch (tag) {
729
612
  case "pair":
730
613
  return members.length !== 2 ? `Pair requires exactly 2 members, got ${members.length}` : null;
731
- case "triple":
732
- return members.length !== 3 ? `Triple requires exactly 3 members, got ${members.length}` : null;
733
614
  case "set":
734
615
  case "list":
735
616
  return members.length < 1 ? `${tag === "set" ? "Set" : "List"} requires at least 1 member, got 0` : null;
@@ -741,7 +622,7 @@ function preflightOpDiagnostics2(op, operationIndex) {
741
622
  return preflightOpDiagnostics(op, operationIndex);
742
623
  }
743
624
  function preflightCommitDiagnostics2(operations, options) {
744
- return preflightCommitDiagnostics(operations);
625
+ return preflightCommitDiagnostics(operations, options);
745
626
  }
746
627
 
747
628
  // ../rules/src/reserved-orgs.ts
@@ -7224,7 +7105,7 @@ function normalizeOptionalTypeSpec(spec) {
7224
7105
  return { spec, optionalByType: false };
7225
7106
  }
7226
7107
  function isFieldOptional(fieldKey, typeSpec) {
7227
- const optionalByKey = fieldKey !== void 0 && fieldKey.endsWith("?");
7108
+ const optionalByKey = fieldKey?.endsWith("?");
7228
7109
  return optionalByKey || normalizeOptionalTypeSpec(typeSpec).optionalByType;
7229
7110
  }
7230
7111
 
@@ -8034,17 +7915,39 @@ function shapeDefinitionPreflightError(name, data, verb) {
8034
7915
  }
8035
7916
 
8036
7917
  // src/collection-operation-normalize.ts
8037
- var collectionTypes2 = /* @__PURE__ */ new Set([
8038
- "pair",
8039
- "triple",
8040
- "set",
8041
- "list"
8042
- ]);
7918
+ var collectionTypes2 = /* @__PURE__ */ new Set(["pair", "set", "list"]);
8043
7919
  function normalizeBackendCollectionAdd(operation, source) {
7920
+ const normalized = normalizeCollectionWrite(operation, source, "add");
7921
+ return {
7922
+ operation: "add",
7923
+ kind: "collection",
7924
+ name: normalized.name,
7925
+ type: normalized.type,
7926
+ members: normalized.members,
7927
+ ...operation.skipExisting === true ? { skipExisting: true } : {}
7928
+ };
7929
+ }
7930
+ function normalizeBackendCollectionRevise(operation, source) {
7931
+ const normalized = normalizeCollectionWrite(operation, source, "revise");
7932
+ if (!normalized.name) {
7933
+ throw new Error(`${source}: collection revise requires a target name`);
7934
+ }
7935
+ return {
7936
+ operation: "revise",
7937
+ kind: "collection",
7938
+ name: normalized.name,
7939
+ type: normalized.type,
7940
+ members: normalized.members,
7941
+ ...typeof operation.expectedVersion === "number" ? { expectedVersion: operation.expectedVersion } : {},
7942
+ ...typeof operation.leaseId === "string" && operation.leaseId.length > 0 ? { leaseId: operation.leaseId } : {}
7943
+ };
7944
+ }
7945
+ function normalizeCollectionWrite(operation, source, writeOperation) {
8044
7946
  const diagnostics = preflightOpDiagnostics2(
8045
7947
  {
8046
- operation: "add",
7948
+ operation: writeOperation,
8047
7949
  kind: "collection",
7950
+ name: typeof operation.name === "string" ? operation.name : void 0,
8048
7951
  type: typeof operation.type === "string" ? operation.type : void 0,
8049
7952
  members: Array.isArray(operation.members) ? operation.members : void 0
8050
7953
  },
@@ -8058,35 +7961,40 @@ function normalizeBackendCollectionAdd(operation, source) {
8058
7961
  const type = normalizeCollectionType(operation.type);
8059
7962
  if (!type) {
8060
7963
  throw new Error(
8061
- `${source}: collection add requires 'type' to be one of: pair, triple, set, list`
7964
+ `${source}: collection ${writeOperation} requires 'type' to be one of: pair, set, list`
8062
7965
  );
8063
7966
  }
8064
7967
  if (!Array.isArray(operation.members)) {
8065
- throw new Error(`${source}: collection add requires a 'members' array`);
7968
+ throw new Error(
7969
+ `${source}: collection ${writeOperation} requires a 'members' array`
7970
+ );
8066
7971
  }
8067
7972
  const name = normalizeOptionalName(operation.name);
8068
- if (operation.name !== void 0 && !name) {
7973
+ if (!name) {
8069
7974
  throw new Error(
8070
- `${source}: collection add name must be a non-empty string when provided`
7975
+ `${source}: collection ${writeOperation} name must be a non-empty string`
8071
7976
  );
8072
7977
  }
8073
- assertNoUnsupportedCollectionAddFields(operation, source);
7978
+ assertNoUnsupportedCollectionFields(operation, source, writeOperation);
8074
7979
  return {
8075
- operation: "add",
8076
- kind: "collection",
8077
- ...name ? { name } : {},
7980
+ name,
8078
7981
  type,
8079
- members: operation.members,
8080
- ...operation.skipExisting === true ? { skipExisting: true } : {}
7982
+ members: operation.members
8081
7983
  };
8082
7984
  }
8083
- function assertNoUnsupportedCollectionAddFields(operation, source) {
8084
- const unsupportedFields = ["about", "aboutWref", "shapeWref", "data"].filter(
7985
+ function assertNoUnsupportedCollectionFields(operation, source, writeOperation) {
7986
+ const unsupportedFields = [
7987
+ "about",
7988
+ "aboutWref",
7989
+ "shapeWref",
7990
+ "data",
7991
+ ...writeOperation === "revise" ? ["skipExisting"] : []
7992
+ ].filter(
8085
7993
  (field) => operation[field] !== void 0
8086
7994
  );
8087
7995
  if (unsupportedFields.length > 0) {
8088
7996
  throw new Error(
8089
- `${source}: collection add does not support ${unsupportedFields.map((field) => `'${field}'`).join(", ")}`
7997
+ `${source}: collection ${writeOperation} does not support ${unsupportedFields.map((field) => `'${field}'`).join(", ")}`
8090
7998
  );
8091
7999
  }
8092
8000
  }
@@ -8137,14 +8045,12 @@ function toBackendStreamOperation(operation) {
8137
8045
  `${kind2} revise operation no longer supports 'active' \u2014 use retract('${name}') instead`
8138
8046
  );
8139
8047
  }
8048
+ if (kind2 === "collection") {
8049
+ return normalizeBackendCollectionRevise(operation, "commit.apply");
8050
+ }
8140
8051
  if (operation.data === void 0) {
8141
8052
  throw new Error(`${kind2} revise operation requires 'data'`);
8142
8053
  }
8143
- if (kind2 === "collection") {
8144
- throw new Error(
8145
- `collection revise is no longer supported \u2014 use retract('${name}') instead`
8146
- );
8147
- }
8148
8054
  if (kind2 === "assertion") {
8149
8055
  return {
8150
8056
  operation: "revise",
@@ -8184,6 +8090,9 @@ function toBackendStreamOperation(operation) {
8184
8090
  if (!("about" in operation) || operation.about === void 0) {
8185
8091
  throw new Error("assertion add operation requires 'about'");
8186
8092
  }
8093
+ if (typeof operation.about !== "string") {
8094
+ throw new Error(COLLECTION_ABOUT_REMOVED_MESSAGE);
8095
+ }
8187
8096
  if (operation.data === void 0) {
8188
8097
  throw new Error("assertion add operation requires 'data'");
8189
8098
  }
@@ -8333,10 +8242,9 @@ var DEFINITE_CLIENT_REJECT_CODES = /* @__PURE__ */ new Set([
8333
8242
  "CONFLICT",
8334
8243
  "ALREADY_RETRACTED",
8335
8244
  "ARCHIVED",
8336
- // Pre-apply rejections from stream/service.ts: applyRateLimit() and the
8337
- // unresolved-token check both throw before any operation lands, so the
8338
- // first-chunk wrapper would discard structured retry/validation detail
8339
- // (retryAfter, the failing token, etc.).
8245
+ // Pre-apply rejections from stream/service.ts throw before any operation
8246
+ // lands, so the first-chunk wrapper would discard structured
8247
+ // retry/validation detail (retryAfter, validation diagnostics, etc.).
8340
8248
  "RATE_LIMITED",
8341
8249
  "TOO_MANY_REQUESTS",
8342
8250
  "UNRESOLVED_TOKEN"
@@ -8390,34 +8298,14 @@ function computeBackoffDelayMs(attempt, policy) {
8390
8298
  function sleep(ms) {
8391
8299
  return new Promise((resolve) => setTimeout(resolve, ms));
8392
8300
  }
8393
- var TOKEN_REF_REGEX = /[$#]\d+/;
8394
- function stringHasTokenRef(value) {
8395
- return typeof value === "string" && TOKEN_REF_REGEX.test(value);
8396
- }
8397
- function structuralValueHasTokenRef(value, seen = /* @__PURE__ */ new WeakSet()) {
8398
- if (stringHasTokenRef(value)) return true;
8399
- if (value !== null && typeof value === "object") {
8400
- if (seen.has(value)) return false;
8401
- seen.add(value);
8402
- if (Array.isArray(value)) {
8403
- return value.some((entry) => structuralValueHasTokenRef(entry, seen));
8404
- }
8405
- return Object.values(value).some(
8406
- (entry) => structuralValueHasTokenRef(entry, seen)
8407
- );
8408
- }
8409
- return false;
8410
- }
8411
- function opUsesTokens(op) {
8412
- return stringHasTokenRef(op.name) || stringHasTokenRef(op.wref) || structuralValueHasTokenRef(op.about) || stringHasTokenRef(op.aboutWref) || structuralValueHasTokenRef(op.members) || structuralValueHasTokenRef(op.data);
8413
- }
8414
8301
 
8415
8302
  // src/stream-submit-submit.ts
8416
8303
  var StreamValidationError = class extends Error {
8417
- code = "VALIDATION_ERROR";
8304
+ code;
8418
8305
  status = 400;
8419
- constructor(message) {
8306
+ constructor(message, code = "VALIDATION_ERROR") {
8420
8307
  super(message);
8308
+ this.code = code;
8421
8309
  this.name = "WarmHubError";
8422
8310
  }
8423
8311
  };
@@ -8442,6 +8330,7 @@ async function submitOperationsViaStream(client, args) {
8442
8330
  }
8443
8331
  return streamOperation;
8444
8332
  });
8333
+ validateNormalizedOperations(operations);
8445
8334
  const chunkSize = normalizeChunkSize(args.chunkSize);
8446
8335
  let streamId = args.streamId ?? createStreamId();
8447
8336
  const policy = args.streamId !== void 0 ? false : resolveRetryPolicy(args.retry);
@@ -8456,7 +8345,6 @@ async function submitOperationsViaStream(client, args) {
8456
8345
  let attempt = 1;
8457
8346
  let priorAttemptAmbiguous = false;
8458
8347
  const chunkIsAtomic = chunk.length === 1;
8459
- const chunkUsesTokens = chunk.some(opUsesTokens);
8460
8348
  while (true) {
8461
8349
  try {
8462
8350
  const appendResult = await client.stream.append({
@@ -8481,7 +8369,7 @@ async function submitOperationsViaStream(client, args) {
8481
8369
  if (chunkResults.length === 0 && !priorAttemptAmbiguous && isDefiniteClientError(cause)) {
8482
8370
  throw cause;
8483
8371
  }
8484
- if (chunkResults.length === 0 && chunkIsAtomic && !chunkUsesTokens && policy !== false && attempt < policy.maxAttempts && isTransientStreamFailure(cause)) {
8372
+ if (chunkResults.length === 0 && chunkIsAtomic && policy !== false && attempt < policy.maxAttempts && isTransientStreamFailure(cause)) {
8485
8373
  await sleep(computeBackoffDelayMs(attempt, policy));
8486
8374
  attempt += 1;
8487
8375
  priorAttemptAmbiguous = true;
@@ -8531,6 +8419,20 @@ async function submitOperationsViaStream(client, args) {
8531
8419
  }
8532
8420
  return result;
8533
8421
  }
8422
+ function validateNormalizedOperations(operations) {
8423
+ const diagnostics = preflightCommitDiagnostics2(operations).filter(
8424
+ (diagnostic) => !isServerAuthoritativeSequenceDiagnostic(diagnostic)
8425
+ );
8426
+ const firstDiagnostic = diagnostics[0];
8427
+ if (!firstDiagnostic) return;
8428
+ throw new StreamValidationError(
8429
+ `Invalid operation at index ${firstDiagnostic.operationIndex}: ${firstDiagnostic.message}`,
8430
+ firstDiagnostic.code
8431
+ );
8432
+ }
8433
+ function isServerAuthoritativeSequenceDiagnostic(diagnostic) {
8434
+ return diagnostic.code === "ILLEGAL_OP_SEQUENCE" && diagnostic.message.includes("Cannot revise then add ");
8435
+ }
8534
8436
  function isAllSubmittedOperationsFailed(result, submittedOperationCount) {
8535
8437
  if (submittedOperationCount <= 0) {
8536
8438
  return false;
@@ -8867,6 +8769,9 @@ function toBackendOp(op) {
8867
8769
  `OperationBuilder: assertion add '${name2}' missing required 'about'`
8868
8770
  );
8869
8771
  }
8772
+ if (typeof about !== "string") {
8773
+ throw new Error(COLLECTION_ABOUT_REMOVED_MESSAGE);
8774
+ }
8870
8775
  return {
8871
8776
  operation: "add",
8872
8777
  kind: kind2,
@@ -8892,9 +8797,7 @@ function toBackendOp(op) {
8892
8797
  }
8893
8798
  const kind = normalizeReviseKind(op, name);
8894
8799
  if (kind === "collection") {
8895
- throw new Error(
8896
- `OperationBuilder: collection revise is no longer supported \u2014 use retract('${name}') instead`
8897
- );
8800
+ return normalizeBackendCollectionRevise({ ...op, name }, "OperationBuilder");
8898
8801
  }
8899
8802
  return {
8900
8803
  operation: "revise",
@@ -8919,7 +8822,9 @@ function toPreflightOp(op, kind) {
8919
8822
  return {
8920
8823
  operation: op.operation,
8921
8824
  kind,
8922
- name: op.name ?? op.wref
8825
+ name: op.name ?? op.wref,
8826
+ type: getCollectionType(op),
8827
+ members: getCollectionMembers(op)
8923
8828
  };
8924
8829
  }
8925
8830
  function throwAggregatedMessages(messages) {
@@ -8951,9 +8856,7 @@ function preflightCheckAdd(op, kind) {
8951
8856
  if (op.name) {
8952
8857
  messages.push(...preflightCheckCommon("ADD", kind, op.name, getAddData(op)));
8953
8858
  }
8954
- if (kind === "assertion" && getAddAbout(op) === void 0 && // Token-bearing names defer to validate() so the more specific token
8955
- // diagnostics surface instead of this eager check.
8956
- !(op.name && hasAnyTokens(op.name))) {
8859
+ if (kind === "assertion" && getAddAbout(op) === void 0) {
8957
8860
  messages.push(
8958
8861
  `ADD assertion '${op.name}' missing required 'about' \u2014 for hierarchical thing names set kind: 'thing' explicitly`
8959
8862
  );
@@ -8975,17 +8878,16 @@ function preflightCheckAdd(op, kind) {
8975
8878
  }
8976
8879
  throwAggregatedMessages(messages);
8977
8880
  }
8978
- function preflightCheckRevise(kind, name, data) {
8881
+ function preflightCheckRevise(kind, name, op) {
8979
8882
  const messages = [];
8980
- if (data === void 0) {
8883
+ if (kind !== "collection" && op.data === void 0) {
8981
8884
  messages.push(`OperationBuilder: ${kind} revise requires 'data'`);
8982
8885
  }
8983
8886
  messages.push(
8984
- ...preflightCheckCommon("REVISE", kind, name, data),
8985
- ...preflightOpDiagnostics2(
8986
- toPreflightOp({ operation: "revise", name, data }, kind),
8987
- 0
8988
- ).map((diagnostic) => diagnostic.message)
8887
+ ...preflightCheckCommon("REVISE", kind, name, op.data),
8888
+ ...preflightOpDiagnostics2(toPreflightOp({ ...op, name }, kind), 0).map(
8889
+ (diagnostic) => diagnostic.message
8890
+ )
8989
8891
  );
8990
8892
  throwAggregatedMessages(messages);
8991
8893
  }
@@ -9086,7 +8988,10 @@ var OperationBuilder = class {
9086
8988
  { ...normalized },
9087
8989
  target
9088
8990
  );
9089
- preflightCheckRevise(reviseKind, target, normalized.data);
8991
+ preflightCheckRevise(reviseKind, target, {
8992
+ operation: "revise",
8993
+ ...normalized
8994
+ });
9090
8995
  }
9091
8996
  const frozen = Object.freeze({
9092
8997
  operation: "revise",
@@ -9230,6 +9135,36 @@ var OperationBuilder = class {
9230
9135
  }
9231
9136
  }
9232
9137
  }
9138
+ const operationDiagnostics = this.ops.flatMap((op, operationIndex) => {
9139
+ if (op.operation === "add") {
9140
+ return preflightOpDiagnostics2(
9141
+ toPreflightOp(op, normalizeAddKind(op)),
9142
+ operationIndex
9143
+ );
9144
+ }
9145
+ if (op.operation === "revise") {
9146
+ const target = op.name ?? op.wref;
9147
+ return preflightOpDiagnostics2(
9148
+ toPreflightOp(op, target ? normalizeReviseKind(op, target) : "thing"),
9149
+ operationIndex
9150
+ );
9151
+ }
9152
+ return preflightOpDiagnostics2(
9153
+ {
9154
+ operation: "retract",
9155
+ kind: op.kind,
9156
+ name: op.name
9157
+ },
9158
+ operationIndex
9159
+ );
9160
+ });
9161
+ for (const diagnostic of operationDiagnostics) {
9162
+ errors.push({
9163
+ code: diagnostic.code,
9164
+ operationIndex: diagnostic.operationIndex,
9165
+ message: diagnostic.message
9166
+ });
9167
+ }
9233
9168
  const preflightOps = this.ops.filter((op) => op.operation !== "retract").map((op) => {
9234
9169
  if (op.operation === "add") {
9235
9170
  return toPreflightOp(op, normalizeAddKind(op));
@@ -9240,7 +9175,9 @@ var OperationBuilder = class {
9240
9175
  target ? normalizeReviseKind(op, target) : "thing"
9241
9176
  );
9242
9177
  });
9243
- const diagnostics = preflightCommitDiagnostics2(preflightOps);
9178
+ const diagnostics = preflightCommitDiagnostics2(preflightOps, {
9179
+ checkAddAdd: false
9180
+ });
9244
9181
  for (const diagnostic of diagnostics) {
9245
9182
  errors.push({
9246
9183
  code: diagnostic.code,
@@ -9341,7 +9278,7 @@ function validateWarmHubClientOptions(options) {
9341
9278
  throw new TypeError(`Unknown WarmHubClient option "${key}"${hint}`);
9342
9279
  }
9343
9280
  }
9344
- var SDK_VERSION = "0.65.0" ;
9281
+ var SDK_VERSION = "0.67.0" ;
9345
9282
  var DEFAULT_API_URL = "https://api.warmhub.ai";
9346
9283
  var UNBATCHED_TRPC_PATHS = /* @__PURE__ */ new Set([
9347
9284
  "repo.shapeInstanceCounts",
@@ -9460,6 +9397,47 @@ function sanitizeSubscriptionUpdateInput(input) {
9460
9397
  } = input;
9461
9398
  return supported;
9462
9399
  }
9400
+ function hasCollectionQuerySource(source) {
9401
+ return !!source && (!!source.shape || !!source.kind || !!source.about || !!source.match || !!source.componentRef || source.excludeComponents === true || (source.where?.length ?? 0) > 0);
9402
+ }
9403
+ function hasCollectionSelectorAnchor(source) {
9404
+ return !!source && (!!source.shape || !!source.about || !!source.match || !!source.componentRef || (source.where?.length ?? 0) > 0);
9405
+ }
9406
+ function hasExplicitCollectionMembers(opts) {
9407
+ const members = opts.members;
9408
+ return Array.isArray(members) && members.length > 0;
9409
+ }
9410
+ function collectionTypeFromWref(wref) {
9411
+ const local = wref.replace(/^wh:[^/]+\/[^/]+\//, "").replace(/@(?:HEAD|ALL|v\d+)$/, "");
9412
+ const shape = local.split("/")[0]?.toLowerCase();
9413
+ return shape === "pair" || shape === "set" || shape === "list" ? shape : void 0;
9414
+ }
9415
+ function assertSelectorBackedCollectionType(type, opts) {
9416
+ if (hasCollectionQuerySource(opts.query) && !hasCollectionSelectorAnchor(opts.query)) {
9417
+ throw new WarmHubError(
9418
+ "VALIDATION_ERROR",
9419
+ "Selector-backed collection sources require shape, about, match, componentRef, or where; kind and excludeComponents only narrow an existing selector."
9420
+ );
9421
+ }
9422
+ if (opts.sourceRepo && !hasCollectionSelectorAnchor(opts.query)) {
9423
+ throw new WarmHubError(
9424
+ "VALIDATION_ERROR",
9425
+ "sourceRepo requires a selector-backed collection query"
9426
+ );
9427
+ }
9428
+ if (opts.sourceRepo && hasExplicitCollectionMembers(opts)) {
9429
+ throw new WarmHubError(
9430
+ "VALIDATION_ERROR",
9431
+ "sourceRepo cannot be combined with explicit members; use canonical wh:org/repo/... member wrefs or omit sourceRepo."
9432
+ );
9433
+ }
9434
+ if (hasCollectionQuerySource(opts.query) && type !== "set") {
9435
+ throw new WarmHubError(
9436
+ "VALIDATION_ERROR",
9437
+ "Selector-backed collection sources are only supported for set collections"
9438
+ );
9439
+ }
9440
+ }
9463
9441
  function resolveFunctionLogMode(mode) {
9464
9442
  return mode ?? "off";
9465
9443
  }
@@ -10712,6 +10690,46 @@ var WarmHubClient = class _WarmHubClient {
10712
10690
  throw toWarmHubError(error);
10713
10691
  }
10714
10692
  },
10693
+ /**
10694
+ * Browse the public "Explore" directory: every `visibility='public'` live
10695
+ * repository across all orgs, with search, org/activity/subscription/thing
10696
+ * filters, and sort. No auth required — anonymous callers see the same
10697
+ * public-only listing.
10698
+ *
10699
+ * Two mutually-exclusive modes. Browse mode paginates a filtered, sorted
10700
+ * listing (`search`/`org`/`activity`/`hasSubscriptions`/`minThings`/`sort`/
10701
+ * `limit`/`cursor`). Slugs mode is an exact-match batch lookup: pass up to
10702
+ * 12 `org/repo` slugs to resolve just those live public repos in input
10703
+ * order, ignoring every browse field. Combining `slugs` with any browse/
10704
+ * search/sort/filter field is a hard input error, not a silently-filtered
10705
+ * list.
10706
+ *
10707
+ * `total` and `orgs` (the org-filter facet) are returned on the first page
10708
+ * only — i.e. when `cursor` is absent.
10709
+ *
10710
+ * Cursor contract: cursors are short-lived resume tokens for the same query
10711
+ * and result scope. If filters, visibility, or backing streams change, the
10712
+ * backend may reject a saved cursor with `VALIDATION_ERROR` / `Invalid
10713
+ * cursor`; restart the query without `cursor` instead of retrying the stale
10714
+ * token.
10715
+ */
10716
+ explore: async (opts) => {
10717
+ try {
10718
+ return await this.trpc.repo.explore.query({
10719
+ search: opts?.search,
10720
+ org: opts?.org,
10721
+ activity: opts?.activity,
10722
+ hasSubscriptions: opts?.hasSubscriptions,
10723
+ minThings: opts?.minThings,
10724
+ sort: opts?.sort,
10725
+ limit: opts?.limit,
10726
+ cursor: opts?.cursor,
10727
+ slugs: opts?.slugs
10728
+ });
10729
+ } catch (error) {
10730
+ throw toWarmHubError(error);
10731
+ }
10732
+ },
10715
10733
  /**
10716
10734
  * Fetch a repository's `Content/Readme` markdown record.
10717
10735
  *
@@ -11324,6 +11342,165 @@ var WarmHubClient = class _WarmHubClient {
11324
11342
  }
11325
11343
  }
11326
11344
  };
11345
+ collection = {
11346
+ create: async (orgName, repoName, opts) => {
11347
+ try {
11348
+ assertSelectorBackedCollectionType(opts.type, opts);
11349
+ return await this.trpc.collection.create.mutate({
11350
+ orgName,
11351
+ repoName,
11352
+ type: opts.type,
11353
+ name: opts.name,
11354
+ members: opts.members,
11355
+ from: opts.from,
11356
+ add: opts.add,
11357
+ remove: opts.remove,
11358
+ replaceMembers: opts.replaceMembers,
11359
+ query: opts.query,
11360
+ sourceOrgName: opts.sourceRepo?.orgName,
11361
+ sourceRepoName: opts.sourceRepo?.repoName,
11362
+ skipExisting: opts.skipExisting,
11363
+ message: opts.message,
11364
+ committer: opts.committer
11365
+ });
11366
+ } catch (error) {
11367
+ throw toWarmHubError(error);
11368
+ }
11369
+ },
11370
+ members: async (orgName, repoName, wref, opts) => {
11371
+ try {
11372
+ return await this.trpc.collection.members.query({
11373
+ orgName,
11374
+ repoName,
11375
+ wref,
11376
+ version: opts?.version,
11377
+ limit: opts?.limit,
11378
+ cursor: opts?.cursor
11379
+ });
11380
+ } catch (error) {
11381
+ throw toWarmHubError(error);
11382
+ }
11383
+ },
11384
+ membersIter: (orgName, repoName, wref, opts) => {
11385
+ let snapshotVersion = opts?.version;
11386
+ return paginate(
11387
+ async (cursor) => {
11388
+ const page = await this.collection.members(orgName, repoName, wref, {
11389
+ ...opts,
11390
+ version: snapshotVersion,
11391
+ cursor
11392
+ });
11393
+ snapshotVersion ??= page.version;
11394
+ return page;
11395
+ },
11396
+ (page) => page.items,
11397
+ opts?.cursor
11398
+ );
11399
+ },
11400
+ membersAll: async (orgName, repoName, wref, opts) => {
11401
+ const { max, ...pageOpts } = opts ?? {};
11402
+ let snapshotVersion = pageOpts.version;
11403
+ return await collectPaginatedPages(
11404
+ async (cursor) => {
11405
+ const page = await this.collection.members(orgName, repoName, wref, {
11406
+ ...pageOpts,
11407
+ version: snapshotVersion,
11408
+ cursor
11409
+ });
11410
+ snapshotVersion ??= page.version;
11411
+ return page;
11412
+ },
11413
+ (page) => page.items,
11414
+ max,
11415
+ pageOpts.cursor
11416
+ );
11417
+ },
11418
+ contains: async (orgName, repoName, wref, members, opts) => {
11419
+ try {
11420
+ return await this.trpc.collection.contains.query({
11421
+ orgName,
11422
+ repoName,
11423
+ wref,
11424
+ version: opts?.version,
11425
+ members,
11426
+ position: opts?.position
11427
+ });
11428
+ } catch (error) {
11429
+ throw toWarmHubError(error);
11430
+ }
11431
+ },
11432
+ diff: async (orgName, repoName, leftWref, rightWref, opts) => {
11433
+ try {
11434
+ return await this.trpc.collection.diff.query({
11435
+ orgName,
11436
+ repoName,
11437
+ leftWref,
11438
+ rightWref,
11439
+ leftVersion: opts?.leftVersion,
11440
+ rightVersion: opts?.rightVersion,
11441
+ mode: opts?.mode
11442
+ });
11443
+ } catch (error) {
11444
+ throw toWarmHubError(error);
11445
+ }
11446
+ },
11447
+ revise: async (orgName, repoName, wref, opts) => {
11448
+ try {
11449
+ const targetType = collectionTypeFromWref(wref);
11450
+ if (hasCollectionQuerySource(opts.query) && !hasCollectionSelectorAnchor(opts.query)) {
11451
+ throw new WarmHubError(
11452
+ "VALIDATION_ERROR",
11453
+ "Selector-backed collection sources require shape, about, match, componentRef, or where; kind and excludeComponents only narrow an existing selector."
11454
+ );
11455
+ }
11456
+ if (opts.sourceRepo && !hasCollectionSelectorAnchor(opts.query)) {
11457
+ throw new WarmHubError(
11458
+ "VALIDATION_ERROR",
11459
+ "sourceRepo requires a selector-backed collection query"
11460
+ );
11461
+ }
11462
+ if (opts.sourceRepo && hasExplicitCollectionMembers(opts)) {
11463
+ throw new WarmHubError(
11464
+ "VALIDATION_ERROR",
11465
+ "sourceRepo cannot be combined with explicit members; use canonical wh:org/repo/... member wrefs or omit sourceRepo."
11466
+ );
11467
+ }
11468
+ if (hasCollectionQuerySource(opts.query) && targetType && targetType !== "set") {
11469
+ throw new WarmHubError(
11470
+ "VALIDATION_ERROR",
11471
+ "Selector-backed revise requires a Set/<name> target wref"
11472
+ );
11473
+ }
11474
+ return await this.trpc.collection.revise.mutate({
11475
+ orgName,
11476
+ repoName,
11477
+ wref,
11478
+ members: opts.members,
11479
+ add: opts.add,
11480
+ remove: opts.remove,
11481
+ query: opts.query,
11482
+ sourceOrgName: opts.sourceRepo?.orgName,
11483
+ sourceRepoName: opts.sourceRepo?.repoName,
11484
+ message: opts.message,
11485
+ committer: opts.committer
11486
+ });
11487
+ } catch (error) {
11488
+ throw toWarmHubError(error);
11489
+ }
11490
+ },
11491
+ stats: async (orgName, repoName, wref, opts) => {
11492
+ try {
11493
+ return await this.trpc.collection.stats.query({
11494
+ orgName,
11495
+ repoName,
11496
+ wref,
11497
+ version: opts?.version
11498
+ });
11499
+ } catch (error) {
11500
+ throw toWarmHubError(error);
11501
+ }
11502
+ }
11503
+ };
11327
11504
  /**
11328
11505
  * Read surface for things, assertions, histories, references, search, and in-place thing renames.
11329
11506
  */
@@ -11406,6 +11583,7 @@ var WarmHubClient = class _WarmHubClient {
11406
11583
  *
11407
11584
  * @param version Optional exact version to pin when the wref is not already version-qualified.
11408
11585
  * @param opts.includeRetracted Include retracted records instead of treating them as missing.
11586
+ * @param opts.dataMode Defaults to `auto`; pass `full` to force full collection bodies.
11409
11587
  */
11410
11588
  get: async (orgName, repoName, wref, version, opts) => {
11411
11589
  try {
@@ -11414,7 +11592,8 @@ var WarmHubClient = class _WarmHubClient {
11414
11592
  repoName,
11415
11593
  wref,
11416
11594
  version,
11417
- includeRetracted: opts?.includeRetracted
11595
+ includeRetracted: opts?.includeRetracted,
11596
+ dataMode: opts?.dataMode
11418
11597
  });
11419
11598
  } catch (error) {
11420
11599
  throw toWarmHubError(error);
@@ -11524,7 +11703,8 @@ var WarmHubClient = class _WarmHubClient {
11524
11703
  repoName,
11525
11704
  wrefs: chunkWrefs,
11526
11705
  version,
11527
- includeRetracted: opts?.includeRetracted
11706
+ includeRetracted: opts?.includeRetracted,
11707
+ dataMode: opts?.dataMode
11528
11708
  });
11529
11709
  };
11530
11710
  if (wrefs.length <= chunkSize) {
@@ -11844,7 +12024,8 @@ var WarmHubClient = class _WarmHubClient {
11844
12024
  componentRef: opts?.componentRef,
11845
12025
  excludeComponents: opts?.excludeComponents,
11846
12026
  excludeInfraShapes: opts?.excludeInfraShapes,
11847
- mode: opts?.mode
12027
+ mode: opts?.mode,
12028
+ nameMatch: opts?.nameMatch
11848
12029
  });
11849
12030
  } catch (error) {
11850
12031
  throw toWarmHubError(error);
@@ -12135,7 +12316,7 @@ var WarmHubClient = class _WarmHubClient {
12135
12316
  /**
12136
12317
  * Append one non-empty chunk of stream operations to a repository.
12137
12318
  *
12138
- * Most callers should prefer `commit.apply` or `OperationBuilder`. Use this low-level surface only when you already have stream operations, a stream ID, and any allocated `$N` / `#N` token state you need to continue.
12319
+ * Most callers should prefer `commit.apply` or `OperationBuilder`. Use this low-level surface only when you already have backend-shaped stream operations and a caller-managed stream ID.
12139
12320
  */
12140
12321
  append: async (input) => {
12141
12322
  try {
@@ -12630,5 +12811,5 @@ re2js/build/index.js:
12630
12811
  */
12631
12812
 
12632
12813
  export { AllStreamOperationsFailedError, CLI_INSTALL_REPO_HEADER, CLI_SIGNATURE_HEADER, CLI_TIMESTAMP_HEADER, CONTENT_FIELD_LIMIT_ERROR, CliCallVerificationError, DEFAULT_API_URL, DEFAULT_STREAM_CHUNK_SIZE, MAX_CONTENT_FIELD_BYTES, MAX_STREAM_APPEND_OPERATION_COUNT2 as MAX_STREAM_APPEND_OPERATION_COUNT, OperationBuilder, PartialStreamSubmissionError, SDK_VERSION, WarmHubClient, WarmHubError, connectionErrorMessage, contentFieldLimitError, countStreamAppendResultStatuses, isConnectionError, isRetryable, isWarmHubError, normalizeWref, resolveFunctionLogMode, sanitizeErrorMessage, sdkVersionIsBelowMinimum, streamAppendResultStatus, submitOperationsViaStream, toWarmHubError, validateAgainstShape, verifyCliCall };
12633
- //# sourceMappingURL=chunk-C2Q4D3JM.js.map
12634
- //# sourceMappingURL=chunk-C2Q4D3JM.js.map
12814
+ //# sourceMappingURL=chunk-2KN2JWJU.js.map
12815
+ //# sourceMappingURL=chunk-2KN2JWJU.js.map