@warmhub/sdk-ts 0.77.1 → 0.79.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.
@@ -30,8 +30,18 @@ var SYNTHESIZED_CONTENT_NAMES = ["LlmsTxt"];
30
30
  var isContentShape = (s) => s === "Content";
31
31
  var isStoredContentName = (n) => STORED_CONTENT_NAMES.includes(n);
32
32
  var isSynthesizedContentName = (n) => SYNTHESIZED_CONTENT_NAMES.includes(n);
33
+ var BUILTIN_VIEW_SHAPE_NAMES = ["View"];
34
+ var isViewShape = (name) => BUILTIN_VIEW_SHAPE_NAMES.includes(name);
35
+ var BUILTIN_LICENSE_SHAPE_NAMES = [
36
+ "LicenseSubject",
37
+ "LicenseDeclaration"
38
+ ];
39
+ var isLicenseShape = (name) => BUILTIN_LICENSE_SHAPE_NAMES.includes(name);
40
+ function isRenameableSquattedShape(name) {
41
+ return isReservedCollectionShape(name) || isViewShape(name) || isLicenseShape(name);
42
+ }
33
43
  function isBuiltinShape(name) {
34
- return BUILTIN_SHAPE_NAMES.includes(name) || BUILTIN_CONTENT_SHAPE_NAMES.includes(name);
44
+ return BUILTIN_SHAPE_NAMES.includes(name) || BUILTIN_CONTENT_SHAPE_NAMES.includes(name) || BUILTIN_VIEW_SHAPE_NAMES.includes(name) || BUILTIN_LICENSE_SHAPE_NAMES.includes(name);
35
45
  }
36
46
 
37
47
  // ../rules/src/client-header.ts
@@ -290,343 +300,16 @@ function isUnsafeFieldName(name) {
290
300
  function stripOptionalMarker(key) {
291
301
  return key.endsWith("?") ? key.slice(0, -1) : key;
292
302
  }
293
- function joinFieldPath(...segments) {
294
- return joinFieldPathWithEscaper(escapeFieldNameForDisplay, segments);
295
- }
296
- function joinFieldIdentityPath(...segments) {
297
- return joinFieldPathWithEscaper(escapeFieldNameForIdentity, segments);
298
- }
299
- function joinFieldPathWithEscaper(escapeSegment, segments) {
300
- return segments.map(
301
- (segment) => typeof segment === "number" ? `[${segment}]` : escapeSegment(segment)
302
- ).join(".").replace(/\.\[/g, "[");
303
- }
304
-
305
- // ../rules/src/tokens.ts
306
- 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.";
307
- var ANY_TOKEN_RE = /[$#]\d+/;
308
- function hasAnyTokens(s) {
309
- return ANY_TOKEN_RE.test(s);
310
- }
311
-
312
- // ../rules/src/preflight-commit.ts
313
- function preflightCommitDiagnostics(operations, options) {
314
- const errors = [];
315
- rejectCommitTokenSyntax(operations, errors);
316
- illegalOpSequences(operations, errors, options?.checkAddAdd ?? true);
317
- return errors;
318
- }
319
- function getOpName(op) {
320
- return op.name;
321
- }
322
- function tokenStringFields(op) {
323
- const fields = [getOpName(op), op.newName];
324
- if (typeof op.about === "string") {
325
- fields.push(op.about);
326
- }
327
- if (op.members) {
328
- fields.push(...op.members);
329
- }
330
- return fields;
331
- }
332
- function rejectCommitTokenSyntax(operations, errors) {
333
- for (let i = 0; i < operations.length; i++) {
334
- const op = operations[i];
335
- if (!op) continue;
336
- for (const field of tokenStringFields(op)) {
337
- if (field && hasAnyTokens(field)) {
338
- errors.push({
339
- code: "COMMIT_TOKEN_SYNTAX_REMOVED",
340
- operationIndex: i,
341
- message: COMMIT_TOKEN_SYNTAX_REMOVED_MESSAGE
342
- });
343
- break;
344
- }
345
- }
346
- }
347
- }
348
- function illegalOpSequences(operations, errors, checkAddAdd) {
349
- const opHistory = /* @__PURE__ */ new Map();
350
- for (let i = 0; i < operations.length; i++) {
351
- const op = operations[i];
352
- if (!op) continue;
353
- const name = getOpName(op);
354
- if (!name) continue;
355
- if (hasAnyTokens(name)) continue;
356
- const kind = inferOperationKind({ ...op, name });
357
- const qualName = kind === "shape" ? `shape:${name}` : `thing:${name}`;
358
- const history = opHistory.get(qualName) ?? [];
359
- history.push({ operation: op.operation, index: i });
360
- opHistory.set(qualName, history);
361
- }
362
- for (const [qualName, history] of opHistory) {
363
- if (history.length < 2) continue;
364
- for (let i = 1; i < history.length; i++) {
365
- const prev = history[i - 1];
366
- const curr = history[i];
367
- if (!prev || !curr) continue;
368
- const pair = `${prev.operation}+${curr.operation}`;
369
- if (checkAddAdd && pair === "add+add") {
370
- errors.push({
371
- code: "ILLEGAL_OP_SEQUENCE",
372
- operationIndex: curr.index,
373
- message: `Cannot add "${qualName}" twice in the same commit`
374
- });
375
- }
376
- if (pair === "revise+add") {
377
- errors.push({
378
- code: "ILLEGAL_OP_SEQUENCE",
379
- operationIndex: curr.index,
380
- message: `Cannot revise then add "${qualName}" in the same commit`
381
- });
382
- }
383
- }
384
- }
385
- }
386
-
387
- // ../rules/src/preflight-operation.ts
388
- var collectionTypes = ["arc", "bond", "set", "list", "pair"];
389
- var canonicalCollectionTypes = ["arc", "bond", "set", "list"];
390
- var collectionOps = ["add", "revise"];
391
- var COLLECTION_CREATE_REQUIRES_NAME_MESSAGE = "Collection create requires a name. Collections are ordinary named things (ADR 0004).";
392
- 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":"arc","name":"a-to-b","members":["A","B"]},{"operation":"add","kind":"assertion","about":"Arc/a-to-b","name":"Assertion/example","data":{}}]. For CLI usage, use wh commit submit --file with the two operations.';
393
- function preflightOpDiagnostics(op, operationIndex) {
394
- const errors = [];
395
- errors.push(...builtinShapeGuard(op, operationIndex));
396
- errors.push(...contentNameGuard(op, operationIndex));
397
- errors.push(...plusSignGuard(op, operationIndex));
398
- errors.push(...validateCollectionAbouts(op, operationIndex));
399
- errors.push(...validateCollectionOps(op, operationIndex));
400
- return errors;
401
- }
402
- function builtinShapeGuard(op, operationIndex) {
403
- const errors = [];
404
- const name = op.name;
405
- const isShapeRename = op.operation === "rename" && (op.kind === "shape" || op.name !== void 0 && !splitLocalPath(op.name));
406
- const reservedSourcePassThrough = isShapeRename && name !== void 0 && isReservedCollectionShape(name) && op.newName !== void 0 && !isReservedCollectionShape(op.newName) && !isBuiltinShape(op.newName);
407
- if (name && isRetiredCollectionShape(name) && !reservedSourcePassThrough) {
408
- errors.push({
409
- code: "RESERVED_NAME",
410
- operationIndex,
411
- message: `Shape "${name}" is a retired collection shape and cannot be written manually`
412
- });
413
- }
414
- if (op.operation === "rename" && (op.kind === "shape" || op.name !== void 0 && !splitLocalPath(op.name)) && op.newName && isRetiredCollectionShape(op.newName)) {
415
- errors.push({
416
- code: "RESERVED_NAME",
417
- operationIndex,
418
- message: `Shape "${op.newName}" is a retired collection shape and cannot be written manually`
419
- });
420
- } else {
421
- const builtinShapeName = name && isBuiltinShape(name) && !reservedSourcePassThrough ? name : isShapeRename && op.newName && isBuiltinShape(op.newName) ? op.newName : void 0;
422
- if (builtinShapeName && (isShapeRename || op.operation !== "retract" && op.kind === "shape")) {
423
- const action = op.operation === "add" ? "created" : op.operation === "rename" ? "renamed" : "revised";
424
- errors.push({
425
- code: "RESERVED_NAME",
426
- operationIndex,
427
- message: `Shape "${builtinShapeName}" is a built-in shape and cannot be ${action} manually`
428
- });
429
- }
430
- }
431
- if (name) {
432
- const local = splitLocalPath(name);
433
- if (local && isRetiredCollectionShape(local.shapePrefix)) {
434
- errors.push({
435
- code: "VALIDATION_ERROR",
436
- operationIndex,
437
- message: `Cannot ${op.operation} under retired collection shape "${local.shapePrefix}". Triple is read-only and retired for new collection writes.`
438
- });
439
- } else if (op.kind === "thing" && local && isBuiltinCollectionShape(local.shapePrefix)) {
440
- 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.`;
441
- errors.push({
442
- code: "VALIDATION_ERROR",
443
- operationIndex,
444
- message
445
- });
446
- }
447
- }
448
- return errors;
449
- }
450
- function contentNameGuard(op, operationIndex) {
451
- if (op.kind !== "thing" || !op.name) return [];
452
- const local = splitLocalPath(op.name);
453
- if (!local || !isContentShape(local.shapePrefix)) return [];
454
- const bareName = local.bareName;
455
- if (isSynthesizedContentName(bareName)) {
456
- return [
457
- {
458
- code: "READ_ONLY_BUILTIN_CONTENT",
459
- operationIndex,
460
- message: `${local.shapePrefix}/${bareName} is synthesized; writes are not allowed`
461
- }
462
- ];
463
- }
464
- if (!isStoredContentName(bareName)) {
465
- return [
466
- {
467
- code: "UNKNOWN_CONTENT_NAME",
468
- operationIndex,
469
- message: `${local.shapePrefix}/${bareName} is not a recognized well-known content name`
470
- }
471
- ];
472
- }
473
- return [];
474
- }
475
- function plusSignGuard(op, operationIndex) {
476
- const errors = [];
477
- const name = op.name;
478
- if (op.newName?.includes("+")) {
479
- errors.push({
480
- code: "VALIDATION_ERROR",
481
- operationIndex,
482
- 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.`
483
- });
484
- return errors;
485
- }
486
- if (name?.includes("+")) {
487
- if (op.kind === "collection" && op.operation === "add") {
488
- errors.push({
489
- code: "VALIDATION_ERROR",
490
- operationIndex,
491
- 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.`
492
- });
493
- return errors;
494
- }
495
- if (op.kind === "collection") return errors;
496
- const local = splitLocalPath(name);
497
- if (local && isReservedCollectionShape(local.shapePrefix)) return errors;
498
- errors.push({
499
- code: "VALIDATION_ERROR",
500
- operationIndex,
501
- 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.`
502
- });
503
- }
504
- return errors;
505
- }
506
- function validateCollectionAbouts(op, operationIndex) {
507
- const errors = [];
508
- if (!op.about || typeof op.about === "string") return errors;
509
- errors.push({
510
- code: "VALIDATION_ERROR",
511
- operationIndex,
512
- message: COLLECTION_ABOUT_REMOVED_MESSAGE
513
- });
514
- return errors;
515
- }
516
- function validateCollectionOps(op, operationIndex) {
517
- const errors = [];
518
- if (op.kind !== "collection") return errors;
519
- if (!collectionOps.includes(op.operation)) {
520
- return errors;
521
- }
522
- if (op.operation === "add" && !op.name) {
523
- errors.push({
524
- code: "VALIDATION_ERROR",
525
- operationIndex,
526
- message: COLLECTION_CREATE_REQUIRES_NAME_MESSAGE
527
- });
528
- }
529
- if (!op.type || !collectionTypes.includes(op.type)) {
530
- errors.push({
531
- code: "VALIDATION_ERROR",
532
- operationIndex,
533
- message: `Collection "type" is invalid. Use one of: ${canonicalCollectionTypes.join(", ")}. Got: "${op.type ?? ""}"`
534
- });
535
- }
536
- if (!op.members || !Array.isArray(op.members)) {
537
- errors.push({
538
- code: "VALIDATION_ERROR",
539
- operationIndex,
540
- message: 'Collection requires a "members" array'
541
- });
542
- } else {
543
- for (let i = 0; i < op.members.length; i++) {
544
- if (typeof op.members[i] !== "string") {
545
- errors.push({
546
- code: "VALIDATION_ERROR",
547
- operationIndex,
548
- message: `Collection member at index ${i} must be a string`
549
- });
550
- }
551
- }
552
- }
553
- if (op.type && op.members) {
554
- const arityError = collectionArityError(
555
- op.type,
556
- op.members
557
- );
558
- if (arityError) {
559
- errors.push({
560
- code: "VALIDATION_ERROR",
561
- operationIndex,
562
- message: arityError
563
- });
564
- }
565
- }
566
- return errors;
567
- }
568
- function collectionArityError(tag, members) {
569
- switch (tag) {
570
- case "arc":
571
- return members.length !== 2 ? `Arc requires exactly 2 members, got ${members.length}` : null;
572
- case "bond":
573
- return members.length !== 2 ? `Bond requires exactly 2 members, got ${members.length}` : null;
574
- case "pair":
575
- return members.length !== 2 ? `Pair requires exactly 2 members, got ${members.length}` : null;
576
- case "set":
577
- case "list":
578
- return members.length < 1 ? `${tag === "set" ? "Set" : "List"} requires at least 1 member, got 0` : null;
579
- }
580
- }
581
-
582
- // ../rules/src/preflight.ts
583
- function preflightOpDiagnostics2(op, operationIndex) {
584
- return preflightOpDiagnostics(op, operationIndex);
585
- }
586
- function preflightCommitDiagnostics2(operations, options) {
587
- return preflightCommitDiagnostics(operations, options);
588
- }
589
-
590
- // ../rules/src/reserved-orgs.ts
591
- var RESERVED_RAW_CONTENT_TOP_LEVEL_NAMES = [
592
- "_app",
593
- "_static",
594
- "api",
595
- "health",
596
- "healthz",
597
- "mcp",
598
- "readyz",
599
- "robots.txt",
600
- "sse",
601
- "trpc",
602
- "version"
603
- ];
604
- var RESERVED_ORG_NAMES = [
605
- ...RESERVED_RAW_CONTENT_TOP_LEVEL_NAMES,
606
- "admin",
607
- "billing",
608
- "blog",
609
- "docs",
610
- "help",
611
- "login",
612
- "public",
613
- "settings",
614
- "signup",
615
- "status",
616
- "support",
617
- "system",
618
- "warmhub",
619
- "www"
620
- ];
621
- new Set(RESERVED_ORG_NAMES);
622
-
623
- // ../rules/src/shape-field-key.ts
624
- function foldFieldName(name) {
625
- const stripped = name.endsWith("?") ? name.slice(0, -1) : name;
626
- return stripped.toLowerCase();
627
- }
628
- function foldFieldPath(path) {
629
- return path.split(".").map((segment) => foldFieldName(segment)).join(".");
303
+ function joinFieldPath(...segments) {
304
+ return joinFieldPathWithEscaper(escapeFieldNameForDisplay, segments);
305
+ }
306
+ function joinFieldIdentityPath(...segments) {
307
+ return joinFieldPathWithEscaper(escapeFieldNameForIdentity, segments);
308
+ }
309
+ function joinFieldPathWithEscaper(escapeSegment, segments) {
310
+ return segments.map(
311
+ (segment) => typeof segment === "number" ? `[${segment}]` : escapeSegment(segment)
312
+ ).join(".").replace(/\.\[/g, "[");
630
313
  }
631
314
 
632
315
  // ../rules/src/shape-types.ts
@@ -6987,89 +6670,423 @@ var RE2JS = class RE2JS2 {
6987
6670
  if (other === null || this.constructor !== other.constructor) return false;
6988
6671
  return this.flagsInput === other.flagsInput && this.patternInput === other.patternInput;
6989
6672
  }
6990
- };
6991
-
6992
- // ../rules/src/shape-validation-types.ts
6993
- var MAX_CONTENT_FIELD_BYTES = 64 * 1024;
6994
- var MAX_INDEXABLE_SCALAR_FIELDS_PER_SHAPE = 256;
6995
- var MAX_INDEXABLE_FIELD_PATH_BYTES = 256;
6996
- var UNSUPPORTED_REGEX_SYNTAX_REASON = "uses unsupported regex syntax";
6997
- var CONTENT_FIELD_LIMIT_ERROR = `WarmHub content fields are limited to ${MAX_CONTENT_FIELD_BYTES} bytes. WarmHub is not a document store; store large documents in S3, Box, Drive, or another document system and reference them from WarmHub instead.`;
6998
- var textEncoder = new TextEncoder();
6999
- function utf8ByteLength(value) {
7000
- return textEncoder.encode(value).byteLength;
6673
+ };
6674
+
6675
+ // ../rules/src/shape-validation-types.ts
6676
+ var MAX_CONTENT_FIELD_BYTES = 64 * 1024;
6677
+ var MAX_INDEXABLE_SCALAR_FIELDS_PER_SHAPE = 256;
6678
+ var MAX_INDEXABLE_FIELD_PATH_BYTES = 256;
6679
+ var UNSUPPORTED_REGEX_SYNTAX_REASON = "uses unsupported regex syntax";
6680
+ var CONTENT_FIELD_LIMIT_ERROR = `WarmHub content fields are limited to ${MAX_CONTENT_FIELD_BYTES} bytes. WarmHub is not a document store; store large documents in S3, Box, Drive, or another document system and reference them from WarmHub instead.`;
6681
+ var textEncoder = new TextEncoder();
6682
+ function utf8ByteLength(value) {
6683
+ return textEncoder.encode(value).byteLength;
6684
+ }
6685
+ function contentFieldLimitError(path, value) {
6686
+ if (value.length * 3 <= MAX_CONTENT_FIELD_BYTES) return null;
6687
+ const byteLength = utf8ByteLength(value);
6688
+ if (byteLength <= MAX_CONTENT_FIELD_BYTES) return null;
6689
+ return `Field "${path}" is ${byteLength} bytes; ${CONTENT_FIELD_LIMIT_ERROR}`;
6690
+ }
6691
+ function assertContentFieldWithinLimit(path, value, errors) {
6692
+ const message = contentFieldLimitError(path, value);
6693
+ if (message) errors.push(message);
6694
+ }
6695
+ function nativeRegexSyntaxError(pattern) {
6696
+ try {
6697
+ new RegExp(pattern);
6698
+ return false;
6699
+ } catch {
6700
+ return true;
6701
+ }
6702
+ }
6703
+ function normalizePatternForPortableEngine(pattern) {
6704
+ let normalized = "";
6705
+ let inCharacterClass = false;
6706
+ for (let i = 0; i < pattern.length; i++) {
6707
+ const char = pattern[i];
6708
+ if (char === "\\") {
6709
+ const next = pattern[i + 1];
6710
+ if (inCharacterClass && next === "b") {
6711
+ normalized += "\\x08";
6712
+ i++;
6713
+ continue;
6714
+ }
6715
+ normalized += char;
6716
+ if (next !== void 0) {
6717
+ normalized += next;
6718
+ i++;
6719
+ }
6720
+ continue;
6721
+ }
6722
+ if (char === "[") {
6723
+ inCharacterClass = true;
6724
+ } else if (char === "]") {
6725
+ inCharacterClass = false;
6726
+ }
6727
+ normalized += char;
6728
+ }
6729
+ return normalized;
6730
+ }
6731
+ function compilePortablePattern(pattern) {
6732
+ try {
6733
+ return RE2JS.compile(normalizePatternForPortableEngine(pattern));
6734
+ } catch {
6735
+ return void 0;
6736
+ }
6737
+ }
6738
+ function unsupportedPortablePatternReason(pattern) {
6739
+ return compilePortablePattern(pattern) ? void 0 : UNSUPPORTED_REGEX_SYNTAX_REASON;
6740
+ }
6741
+ function normalizeOptionalTypeSpec(spec) {
6742
+ if (typeof spec === "string" && spec.endsWith("?")) {
6743
+ return { spec: spec.slice(0, -1), optionalByType: true };
6744
+ }
6745
+ if (isTypeSpecObject(spec) && typeof spec.type === "string" && spec.type.endsWith("?")) {
6746
+ return {
6747
+ spec: { ...spec, type: spec.type.slice(0, -1) },
6748
+ optionalByType: true
6749
+ };
6750
+ }
6751
+ return { spec, optionalByType: false };
6752
+ }
6753
+ function isFieldOptional(fieldKey, typeSpec) {
6754
+ const optionalByKey = fieldKey?.endsWith("?");
6755
+ return optionalByKey || normalizeOptionalTypeSpec(typeSpec).optionalByType;
6756
+ }
6757
+
6758
+ // ../rules/src/name-charset.ts
6759
+ var RESERVED_NAME_SEGMENT_CHARS = ["?", "#", "@", ":", "$"];
6760
+ function escapeForCharClass(char) {
6761
+ return char.replace(/[\\\]^-]/g, "\\$&");
6762
+ }
6763
+ RESERVED_NAME_SEGMENT_CHARS.map(escapeForCharClass).join("");
6764
+
6765
+ // ../rules/src/tokens.ts
6766
+ 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.";
6767
+ var ANY_TOKEN_RE = /[$#]\d+/;
6768
+ function hasAnyTokens(s) {
6769
+ return ANY_TOKEN_RE.test(s);
6770
+ }
6771
+
6772
+ // ../rules/src/preflight-commit.ts
6773
+ function preflightCommitDiagnostics(operations, options) {
6774
+ const errors = [];
6775
+ rejectCommitTokenSyntax(operations, errors);
6776
+ illegalOpSequences(operations, errors, options?.checkAddAdd ?? true);
6777
+ return errors;
6778
+ }
6779
+ function getOpName(op) {
6780
+ return op.name;
6781
+ }
6782
+ function tokenStringFields(op) {
6783
+ const fields = [getOpName(op), op.newName];
6784
+ if (typeof op.about === "string") {
6785
+ fields.push(op.about);
6786
+ }
6787
+ if (op.members) {
6788
+ fields.push(...op.members);
6789
+ }
6790
+ return fields;
6791
+ }
6792
+ function rejectCommitTokenSyntax(operations, errors) {
6793
+ for (let i = 0; i < operations.length; i++) {
6794
+ const op = operations[i];
6795
+ if (!op) continue;
6796
+ for (const field of tokenStringFields(op)) {
6797
+ if (field && hasAnyTokens(field)) {
6798
+ errors.push({
6799
+ code: "COMMIT_TOKEN_SYNTAX_REMOVED",
6800
+ operationIndex: i,
6801
+ message: COMMIT_TOKEN_SYNTAX_REMOVED_MESSAGE
6802
+ });
6803
+ break;
6804
+ }
6805
+ }
6806
+ }
6807
+ }
6808
+ function illegalOpSequences(operations, errors, checkAddAdd) {
6809
+ const opHistory = /* @__PURE__ */ new Map();
6810
+ for (let i = 0; i < operations.length; i++) {
6811
+ const op = operations[i];
6812
+ if (!op) continue;
6813
+ const name = getOpName(op);
6814
+ if (!name) continue;
6815
+ if (hasAnyTokens(name)) continue;
6816
+ const kind = inferOperationKind({ ...op, name });
6817
+ const qualName = kind === "shape" ? `shape:${name}` : `thing:${name}`;
6818
+ const history = opHistory.get(qualName) ?? [];
6819
+ history.push({ operation: op.operation, index: i });
6820
+ opHistory.set(qualName, history);
6821
+ }
6822
+ for (const [qualName, history] of opHistory) {
6823
+ if (history.length < 2) continue;
6824
+ for (let i = 1; i < history.length; i++) {
6825
+ const prev = history[i - 1];
6826
+ const curr = history[i];
6827
+ if (!prev || !curr) continue;
6828
+ const pair = `${prev.operation}+${curr.operation}`;
6829
+ if (checkAddAdd && pair === "add+add") {
6830
+ errors.push({
6831
+ code: "ILLEGAL_OP_SEQUENCE",
6832
+ operationIndex: curr.index,
6833
+ message: `Cannot add "${qualName}" twice in the same commit`
6834
+ });
6835
+ }
6836
+ if (pair === "revise+add") {
6837
+ errors.push({
6838
+ code: "ILLEGAL_OP_SEQUENCE",
6839
+ operationIndex: curr.index,
6840
+ message: `Cannot revise then add "${qualName}" in the same commit`
6841
+ });
6842
+ }
6843
+ }
6844
+ }
6845
+ }
6846
+
6847
+ // ../rules/src/preflight-operation.ts
6848
+ var collectionTypes = ["arc", "bond", "set", "list", "pair"];
6849
+ var canonicalCollectionTypes = ["arc", "bond", "set", "list"];
6850
+ var collectionOps = ["add", "revise"];
6851
+ var COLLECTION_CREATE_REQUIRES_NAME_MESSAGE = "Collection create requires a name. Collections are ordinary named things (ADR 0004).";
6852
+ 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":"arc","name":"a-to-b","members":["A","B"]},{"operation":"add","kind":"assertion","about":"Arc/a-to-b","name":"Assertion/example","data":{}}]. For CLI usage, use wh commit submit --file with the two operations.';
6853
+ function preflightOpDiagnostics(op, operationIndex) {
6854
+ const errors = [];
6855
+ errors.push(...builtinShapeGuard(op, operationIndex));
6856
+ errors.push(...contentNameGuard(op, operationIndex));
6857
+ errors.push(...plusSignGuard(op, operationIndex));
6858
+ errors.push(...validateCollectionAbouts(op, operationIndex));
6859
+ errors.push(...validateCollectionOps(op, operationIndex));
6860
+ return errors;
6861
+ }
6862
+ function builtinShapeGuard(op, operationIndex) {
6863
+ const errors = [];
6864
+ const name = op.name;
6865
+ const isShapeRename = op.operation === "rename" && (op.kind === "shape" || op.name !== void 0 && !splitLocalPath(op.name));
6866
+ const reservedSourcePassThrough = isShapeRename && name !== void 0 && isRenameableSquattedShape(name) && op.newName !== void 0 && !isReservedCollectionShape(op.newName) && !isBuiltinShape(op.newName);
6867
+ if (name && isRetiredCollectionShape(name) && !reservedSourcePassThrough) {
6868
+ errors.push({
6869
+ code: "RESERVED_NAME",
6870
+ operationIndex,
6871
+ message: `Shape "${name}" is a retired collection shape and cannot be written manually`
6872
+ });
6873
+ }
6874
+ if (op.operation === "rename" && (op.kind === "shape" || op.name !== void 0 && !splitLocalPath(op.name)) && op.newName && isRetiredCollectionShape(op.newName)) {
6875
+ errors.push({
6876
+ code: "RESERVED_NAME",
6877
+ operationIndex,
6878
+ message: `Shape "${op.newName}" is a retired collection shape and cannot be written manually`
6879
+ });
6880
+ } else {
6881
+ const builtinShapeName = name && isBuiltinShape(name) && !reservedSourcePassThrough ? name : isShapeRename && op.newName && isBuiltinShape(op.newName) ? op.newName : void 0;
6882
+ if (builtinShapeName && (isShapeRename || op.operation !== "retract" && op.kind === "shape")) {
6883
+ const action = op.operation === "add" ? "created" : op.operation === "rename" ? "renamed" : "revised";
6884
+ errors.push({
6885
+ code: "RESERVED_NAME",
6886
+ operationIndex,
6887
+ message: `Shape "${builtinShapeName}" is a built-in shape and cannot be ${action} manually`
6888
+ });
6889
+ }
6890
+ }
6891
+ if (name) {
6892
+ const local = splitLocalPath(name);
6893
+ if (local && isRetiredCollectionShape(local.shapePrefix)) {
6894
+ errors.push({
6895
+ code: "VALIDATION_ERROR",
6896
+ operationIndex,
6897
+ message: `Cannot ${op.operation} under retired collection shape "${local.shapePrefix}". Triple is read-only and retired for new collection writes.`
6898
+ });
6899
+ } else if (op.kind === "thing" && local && isBuiltinCollectionShape(local.shapePrefix)) {
6900
+ 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.`;
6901
+ errors.push({
6902
+ code: "VALIDATION_ERROR",
6903
+ operationIndex,
6904
+ message
6905
+ });
6906
+ }
6907
+ }
6908
+ return errors;
6909
+ }
6910
+ function contentNameGuard(op, operationIndex) {
6911
+ if (op.kind !== "thing" || !op.name) return [];
6912
+ const local = splitLocalPath(op.name);
6913
+ if (!local || !isContentShape(local.shapePrefix)) return [];
6914
+ const bareName = local.bareName;
6915
+ if (isSynthesizedContentName(bareName)) {
6916
+ return [
6917
+ {
6918
+ code: "READ_ONLY_BUILTIN_CONTENT",
6919
+ operationIndex,
6920
+ message: `${local.shapePrefix}/${bareName} is synthesized; writes are not allowed`
6921
+ }
6922
+ ];
6923
+ }
6924
+ if (!isStoredContentName(bareName)) {
6925
+ return [
6926
+ {
6927
+ code: "UNKNOWN_CONTENT_NAME",
6928
+ operationIndex,
6929
+ message: `${local.shapePrefix}/${bareName} is not a recognized well-known content name`
6930
+ }
6931
+ ];
6932
+ }
6933
+ return [];
7001
6934
  }
7002
- function contentFieldLimitError(path, value) {
7003
- if (value.length * 3 <= MAX_CONTENT_FIELD_BYTES) return null;
7004
- const byteLength = utf8ByteLength(value);
7005
- if (byteLength <= MAX_CONTENT_FIELD_BYTES) return null;
7006
- return `Field "${path}" is ${byteLength} bytes; ${CONTENT_FIELD_LIMIT_ERROR}`;
6935
+ function plusSignGuard(op, operationIndex) {
6936
+ const errors = [];
6937
+ const name = op.name;
6938
+ if (op.newName?.includes("+")) {
6939
+ errors.push({
6940
+ code: "VALIDATION_ERROR",
6941
+ operationIndex,
6942
+ 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.`
6943
+ });
6944
+ return errors;
6945
+ }
6946
+ if (name?.includes("+")) {
6947
+ if (op.kind === "collection" && op.operation === "add") {
6948
+ errors.push({
6949
+ code: "VALIDATION_ERROR",
6950
+ operationIndex,
6951
+ 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.`
6952
+ });
6953
+ return errors;
6954
+ }
6955
+ if (op.kind === "collection") return errors;
6956
+ const local = splitLocalPath(name);
6957
+ if (local && isReservedCollectionShape(local.shapePrefix)) return errors;
6958
+ errors.push({
6959
+ code: "VALIDATION_ERROR",
6960
+ operationIndex,
6961
+ 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.`
6962
+ });
6963
+ }
6964
+ return errors;
7007
6965
  }
7008
- function assertContentFieldWithinLimit(path, value, errors) {
7009
- const message = contentFieldLimitError(path, value);
7010
- if (message) errors.push(message);
6966
+ function validateCollectionAbouts(op, operationIndex) {
6967
+ const errors = [];
6968
+ if (!op.about || typeof op.about === "string") return errors;
6969
+ errors.push({
6970
+ code: "VALIDATION_ERROR",
6971
+ operationIndex,
6972
+ message: COLLECTION_ABOUT_REMOVED_MESSAGE
6973
+ });
6974
+ return errors;
7011
6975
  }
7012
- function nativeRegexSyntaxError(pattern) {
7013
- try {
7014
- new RegExp(pattern);
7015
- return false;
7016
- } catch {
7017
- return true;
6976
+ function validateCollectionOps(op, operationIndex) {
6977
+ const errors = [];
6978
+ if (op.kind !== "collection") return errors;
6979
+ if (!collectionOps.includes(op.operation)) {
6980
+ return errors;
7018
6981
  }
7019
- }
7020
- function normalizePatternForPortableEngine(pattern) {
7021
- let normalized = "";
7022
- let inCharacterClass = false;
7023
- for (let i = 0; i < pattern.length; i++) {
7024
- const char = pattern[i];
7025
- if (char === "\\") {
7026
- const next = pattern[i + 1];
7027
- if (inCharacterClass && next === "b") {
7028
- normalized += "\\x08";
7029
- i++;
7030
- continue;
7031
- }
7032
- normalized += char;
7033
- if (next !== void 0) {
7034
- normalized += next;
7035
- i++;
6982
+ if (op.operation === "add" && !op.name) {
6983
+ errors.push({
6984
+ code: "VALIDATION_ERROR",
6985
+ operationIndex,
6986
+ message: COLLECTION_CREATE_REQUIRES_NAME_MESSAGE
6987
+ });
6988
+ }
6989
+ if (!op.type || !collectionTypes.includes(op.type)) {
6990
+ errors.push({
6991
+ code: "VALIDATION_ERROR",
6992
+ operationIndex,
6993
+ message: `Collection "type" is invalid. Use one of: ${canonicalCollectionTypes.join(", ")}. Got: "${op.type ?? ""}"`
6994
+ });
6995
+ }
6996
+ if (!op.members || !Array.isArray(op.members)) {
6997
+ errors.push({
6998
+ code: "VALIDATION_ERROR",
6999
+ operationIndex,
7000
+ message: 'Collection requires a "members" array'
7001
+ });
7002
+ } else {
7003
+ for (let i = 0; i < op.members.length; i++) {
7004
+ if (typeof op.members[i] !== "string") {
7005
+ errors.push({
7006
+ code: "VALIDATION_ERROR",
7007
+ operationIndex,
7008
+ message: `Collection member at index ${i} must be a string`
7009
+ });
7036
7010
  }
7037
- continue;
7038
7011
  }
7039
- if (char === "[") {
7040
- inCharacterClass = true;
7041
- } else if (char === "]") {
7042
- inCharacterClass = false;
7012
+ }
7013
+ if (op.type && op.members) {
7014
+ const arityError = collectionArityError(
7015
+ op.type,
7016
+ op.members
7017
+ );
7018
+ if (arityError) {
7019
+ errors.push({
7020
+ code: "VALIDATION_ERROR",
7021
+ operationIndex,
7022
+ message: arityError
7023
+ });
7043
7024
  }
7044
- normalized += char;
7045
7025
  }
7046
- return normalized;
7026
+ return errors;
7047
7027
  }
7048
- function compilePortablePattern(pattern) {
7049
- try {
7050
- return RE2JS.compile(normalizePatternForPortableEngine(pattern));
7051
- } catch {
7052
- return void 0;
7028
+ function collectionArityError(tag, members) {
7029
+ switch (tag) {
7030
+ case "arc":
7031
+ return members.length !== 2 ? `Arc requires exactly 2 members, got ${members.length}` : null;
7032
+ case "bond":
7033
+ return members.length !== 2 ? `Bond requires exactly 2 members, got ${members.length}` : null;
7034
+ case "pair":
7035
+ return members.length !== 2 ? `Pair requires exactly 2 members, got ${members.length}` : null;
7036
+ case "set":
7037
+ case "list":
7038
+ return members.length < 1 ? `${tag === "set" ? "Set" : "List"} requires at least 1 member, got 0` : null;
7053
7039
  }
7054
7040
  }
7055
- function unsupportedPortablePatternReason(pattern) {
7056
- return compilePortablePattern(pattern) ? void 0 : UNSUPPORTED_REGEX_SYNTAX_REASON;
7041
+
7042
+ // ../rules/src/preflight.ts
7043
+ function preflightOpDiagnostics2(op, operationIndex) {
7044
+ return preflightOpDiagnostics(op, operationIndex);
7057
7045
  }
7058
- function normalizeOptionalTypeSpec(spec) {
7059
- if (typeof spec === "string" && spec.endsWith("?")) {
7060
- return { spec: spec.slice(0, -1), optionalByType: true };
7061
- }
7062
- if (isTypeSpecObject(spec) && typeof spec.type === "string" && spec.type.endsWith("?")) {
7063
- return {
7064
- spec: { ...spec, type: spec.type.slice(0, -1) },
7065
- optionalByType: true
7066
- };
7067
- }
7068
- return { spec, optionalByType: false };
7046
+ function preflightCommitDiagnostics2(operations, options) {
7047
+ return preflightCommitDiagnostics(operations, options);
7069
7048
  }
7070
- function isFieldOptional(fieldKey, typeSpec) {
7071
- const optionalByKey = fieldKey?.endsWith("?");
7072
- return optionalByKey || normalizeOptionalTypeSpec(typeSpec).optionalByType;
7049
+
7050
+ // ../rules/src/reserved-orgs.ts
7051
+ var RESERVED_RAW_CONTENT_TOP_LEVEL_NAMES = [
7052
+ "_app",
7053
+ "_static",
7054
+ "api",
7055
+ "health",
7056
+ "healthz",
7057
+ "mcp",
7058
+ "readyz",
7059
+ "robots.txt",
7060
+ "sse",
7061
+ "trpc",
7062
+ "version"
7063
+ ];
7064
+ var RESERVED_ORG_NAMES = [
7065
+ ...RESERVED_RAW_CONTENT_TOP_LEVEL_NAMES,
7066
+ "admin",
7067
+ "billing",
7068
+ "blog",
7069
+ "docs",
7070
+ "help",
7071
+ "login",
7072
+ "public",
7073
+ "settings",
7074
+ "signup",
7075
+ "status",
7076
+ "support",
7077
+ "system",
7078
+ "warmhub",
7079
+ "www"
7080
+ ];
7081
+ new Set(RESERVED_ORG_NAMES);
7082
+
7083
+ // ../rules/src/shape-field-key.ts
7084
+ function foldFieldName(name) {
7085
+ const stripped = name.endsWith("?") ? name.slice(0, -1) : name;
7086
+ return stripped.toLowerCase();
7087
+ }
7088
+ function foldFieldPath(path) {
7089
+ return path.split(".").map((segment) => foldFieldName(segment)).join(".");
7073
7090
  }
7074
7091
 
7075
7092
  // ../rules/src/shape-validation-runtime.ts
@@ -7141,7 +7158,9 @@ function validatePersistedStringFieldLimits(value, typeDef, errors, path) {
7141
7158
  }
7142
7159
  if (Array.isArray(value)) {
7143
7160
  const elementType = arrayElementType(normalized);
7144
- if (elementType === void 0 && !isDeclaredArrayType(normalized)) return;
7161
+ if (normalized !== void 0 && elementType === void 0 && !isDeclaredArrayType(normalized)) {
7162
+ return;
7163
+ }
7145
7164
  for (let i = 0; i < value.length; i++) {
7146
7165
  validatePersistedStringFieldLimits(
7147
7166
  value[i],
@@ -7156,11 +7175,13 @@ function validatePersistedStringFieldLimits(value, typeDef, errors, path) {
7156
7175
  const fields = nestedObjectFields(normalized);
7157
7176
  if (normalized !== void 0 && fields === void 0) return;
7158
7177
  for (const [key, nestedValue] of Object.entries(value)) {
7178
+ const keyPath = path ? joinFieldPath(path, key) : escapeFieldNameForDisplay(key);
7179
+ assertContentFieldWithinLimit(keyPath, key, errors);
7159
7180
  validatePersistedStringFieldLimits(
7160
7181
  nestedValue,
7161
7182
  fields?.get(key),
7162
7183
  errors,
7163
- path ? joinFieldPath(path, key) : escapeFieldNameForDisplay(key)
7184
+ keyPath
7164
7185
  );
7165
7186
  }
7166
7187
  }
@@ -8536,7 +8557,7 @@ var SDK_DEVELOPMENT_VERSION = "0.0.0-development";
8536
8557
  function sdkVersionIsDevelopment(version) {
8537
8558
  return version === SDK_DEVELOPMENT_VERSION;
8538
8559
  }
8539
- var SDK_VERSION = "0.77.1" ;
8560
+ var SDK_VERSION = "0.79.0" ;
8540
8561
 
8541
8562
  // src/component-cli.ts
8542
8563
  var SUPPORTED_METHODS = /* @__PURE__ */ new Set([
@@ -10822,6 +10843,37 @@ var WarmHubClient = class _WarmHubClient {
10822
10843
  throw toWarmHubError(error);
10823
10844
  }
10824
10845
  },
10846
+ /**
10847
+ * Fetch the repository's normalized license declaration.
10848
+ *
10849
+ * Returns `null` when no valid active declaration is visible to the caller.
10850
+ */
10851
+ getLicense: async (orgName, repoName) => {
10852
+ try {
10853
+ return await this.trpc.repo.getLicense.query({
10854
+ orgName,
10855
+ repoName
10856
+ });
10857
+ } catch (error) {
10858
+ throw toWarmHubError(error);
10859
+ }
10860
+ },
10861
+ /**
10862
+ * Return the repository's aggregate describe model.
10863
+ *
10864
+ * The aggregate includes subscription metadata and therefore retains the
10865
+ * backend's `subscriptions:read` authorization requirement.
10866
+ */
10867
+ describe: async (orgName, repoName) => {
10868
+ try {
10869
+ return await this.trpc.repo.describe.query({
10870
+ orgName,
10871
+ repoName
10872
+ });
10873
+ } catch (error) {
10874
+ throw toWarmHubError(error);
10875
+ }
10876
+ },
10825
10877
  /**
10826
10878
  * Commit a new `Content/Readme` value.
10827
10879
  *
@@ -11366,6 +11418,20 @@ var WarmHubClient = class _WarmHubClient {
11366
11418
  throw toWarmHubError(error);
11367
11419
  }
11368
11420
  },
11421
+ /**
11422
+ * Return the newest visible action run for each subscription in a repo.
11423
+ *
11424
+ * This grouped read is intended for subscription summaries that need
11425
+ * complete per-subscription recency without walking repo-wide history or
11426
+ * issuing one request per subscription.
11427
+ */
11428
+ latestRuns: async (orgName, repoName) => {
11429
+ try {
11430
+ return await this.trpc.action.latestRuns.query({ orgName, repoName });
11431
+ } catch (error) {
11432
+ throw toWarmHubError(error);
11433
+ }
11434
+ },
11369
11435
  /**
11370
11436
  * Aggregate run counts (total + per-status) for a repo or one subscription.
11371
11437
  *
@@ -12889,5 +12955,5 @@ re2js/build/index.js:
12889
12955
  */
12890
12956
 
12891
12957
  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 };
12892
- //# sourceMappingURL=chunk-FSZF2NVH.js.map
12893
- //# sourceMappingURL=chunk-FSZF2NVH.js.map
12958
+ //# sourceMappingURL=chunk-NREDPYF7.js.map
12959
+ //# sourceMappingURL=chunk-NREDPYF7.js.map