@warmhub/cli 0.79.0 → 0.80.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/wh.js +688 -640
  2. package/package.json +1 -1
package/dist/wh.js CHANGED
@@ -19146,6 +19146,31 @@ var import_usingCtx = __toESM(require_usingCtx(), 1);
19146
19146
  var import_awaitAsyncGenerator = __toESM(require_awaitAsyncGenerator(), 1);
19147
19147
  var import_wrapAsyncGenerator = __toESM(require_wrapAsyncGenerator(), 1);
19148
19148
  var import_objectSpread29 = __toESM(require_objectSpread2(), 1);
19149
+ // ../../packages/rules/src/authority-coverage.ts
19150
+ var EMPTY_COVERAGE = Object.freeze({
19151
+ include: Object.freeze([])
19152
+ });
19153
+ var FULL_REPO_COVERAGE = Object.freeze({
19154
+ include: Object.freeze(["**"])
19155
+ });
19156
+ var EMPTY_COVERAGE_SET = Object.freeze([]);
19157
+ var FULL_REPO_COVERAGE_SET = Object.freeze([
19158
+ Object.freeze([FULL_REPO_COVERAGE])
19159
+ ]);
19160
+ // ../../packages/rules/src/stable-json.ts
19161
+ function stableJson(value) {
19162
+ if (!value || typeof value !== "object") {
19163
+ return JSON.stringify(value);
19164
+ }
19165
+ if (Array.isArray(value)) {
19166
+ return `[${value.map((entry) => stableJson(entry)).join(",")}]`;
19167
+ }
19168
+ const record = value;
19169
+ return `{${Object.keys(record).sort().map((key) => `${JSON.stringify(key)}:${stableJson(record[key])}`).join(",")}}`;
19170
+ }
19171
+ function stableJsonEquals(left, right) {
19172
+ return stableJson(left) === stableJson(right);
19173
+ }
19149
19174
  // ../../packages/rules/src/builtin-shapes.ts
19150
19175
  var BUILTIN_SHAPE_NAMES = [
19151
19176
  "Arc",
@@ -19174,8 +19199,13 @@ var SYNTHESIZED_CONTENT_NAMES = ["LlmsTxt"];
19174
19199
  var isContentShape = (s) => s === "Content";
19175
19200
  var isStoredContentName = (n) => STORED_CONTENT_NAMES.includes(n);
19176
19201
  var isSynthesizedContentName = (n) => SYNTHESIZED_CONTENT_NAMES.includes(n);
19202
+ var BUILTIN_VIEW_SHAPE_NAMES = ["View"];
19203
+ var isViewShape = (name) => BUILTIN_VIEW_SHAPE_NAMES.includes(name);
19204
+ function isRenameableSquattedShape(name) {
19205
+ return isReservedCollectionShape(name) || isViewShape(name);
19206
+ }
19177
19207
  function isBuiltinShape(name) {
19178
- return BUILTIN_SHAPE_NAMES.includes(name) || BUILTIN_CONTENT_SHAPE_NAMES.includes(name);
19208
+ return BUILTIN_SHAPE_NAMES.includes(name) || BUILTIN_CONTENT_SHAPE_NAMES.includes(name) || BUILTIN_VIEW_SHAPE_NAMES.includes(name);
19179
19209
  }
19180
19210
  var BUILTIN_SHAPE_DEFS = {
19181
19211
  Arc: {
@@ -19228,9 +19258,23 @@ var BUILTIN_CONTENT_SHAPE_DEFS = {
19228
19258
  description: "Built-in content shape (Readme / Agents / LlmsTxt well-known names)"
19229
19259
  }
19230
19260
  };
19261
+ var VIEW_QUERY_DIALECT = "warmquery/v1";
19262
+ var BUILTIN_VIEW_SHAPE_DEFS = {
19263
+ View: {
19264
+ fields: {
19265
+ dialect: {
19266
+ type: "string",
19267
+ description: `Query dialect stamp (${VIEW_QUERY_DIALECT})`
19268
+ },
19269
+ query: {}
19270
+ },
19271
+ description: "A named, shareable WarmQuery definition bound to durable IDs"
19272
+ }
19273
+ };
19231
19274
  var ALL_BUILTIN_SHAPE_DEFS = {
19232
19275
  ...BUILTIN_SHAPE_DEFS,
19233
- ...BUILTIN_CONTENT_SHAPE_DEFS
19276
+ ...BUILTIN_CONTENT_SHAPE_DEFS,
19277
+ ...BUILTIN_VIEW_SHAPE_DEFS
19234
19278
  };
19235
19279
  // ../../packages/rules/src/client-header.ts
19236
19280
  var CLIENT_HEADER = "X-WarmHub-Client";
@@ -19297,21 +19341,6 @@ function resolveComponentTemplate(value, ctx) {
19297
19341
  });
19298
19342
  }
19299
19343
 
19300
- // ../../packages/rules/src/stable-json.ts
19301
- function stableJson(value) {
19302
- if (!value || typeof value !== "object") {
19303
- return JSON.stringify(value);
19304
- }
19305
- if (Array.isArray(value)) {
19306
- return `[${value.map((entry) => stableJson(entry)).join(",")}]`;
19307
- }
19308
- const record = value;
19309
- return `{${Object.keys(record).sort().map((key) => `${JSON.stringify(key)}:${stableJson(record[key])}`).join(",")}}`;
19310
- }
19311
- function stableJsonEquals(left, right) {
19312
- return stableJson(left) === stableJson(right);
19313
- }
19314
-
19315
19344
  // ../../packages/rules/src/org-activity-events.ts
19316
19345
  var ORG_MEMBER_ADDED_EVENT_TYPE = "org.member_added";
19317
19346
  var ORG_REPO_CREATED_EVENT_TYPE = "org.repo_created";
@@ -20225,19 +20254,6 @@ function validateManifestSemantics(manifest) {
20225
20254
  }
20226
20255
  return findings;
20227
20256
  }
20228
- // ../../packages/rules/src/external-contract.ts
20229
- var FORBIDDEN_EXTERNAL_FIELDS = new Set([
20230
- "_id",
20231
- "_creationTime",
20232
- "repoId",
20233
- "orgId",
20234
- "thingId",
20235
- "shapeThingId",
20236
- "aboutThingId",
20237
- "currentVersionId",
20238
- "createdInCommitId",
20239
- "validatedShapeVersionId"
20240
- ]);
20241
20257
  // ../../packages/rules/src/field-name-safety.ts
20242
20258
  var ESCAPE_DISPLAY_MAX_CHARS = 120;
20243
20259
  var DANGEROUS_FORMAT_CODEPOINTS = new Set([
@@ -20336,468 +20352,130 @@ function joinFieldIdentityPath(...segments) {
20336
20352
  function joinFieldPathWithEscaper(escapeSegment, segments) {
20337
20353
  return segments.map((segment) => typeof segment === "number" ? `[${segment}]` : escapeSegment(segment)).join(".").replace(/\.\[/g, "[");
20338
20354
  }
20339
- // ../../packages/rules/src/permission-scopes.ts
20340
- var PUBLIC_ORG_PERMISSIONS = new Set([
20341
- "org:read",
20342
- "components:read"
20343
- ]);
20344
- // ../../packages/rules/src/tokens.ts
20345
- 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.";
20346
- var ANY_TOKEN_RE = /[$#]\d+/;
20347
- function hasAnyTokens(s) {
20348
- return ANY_TOKEN_RE.test(s);
20349
- }
20350
20355
 
20351
- // ../../packages/rules/src/preflight-commit.ts
20352
- function preflightCommitDiagnostics(operations, options) {
20353
- const errors = [];
20354
- rejectCommitTokenSyntax(operations, errors);
20355
- illegalOpSequences(operations, errors, options?.checkAddAdd ?? true);
20356
- return errors;
20357
- }
20358
- function getOpName(op) {
20359
- return op.name;
20356
+ // ../../packages/rules/src/shape-types.ts
20357
+ var BASE_PRIMITIVE_TYPES = [
20358
+ "number",
20359
+ "string",
20360
+ "boolean",
20361
+ "wref",
20362
+ "array"
20363
+ ];
20364
+ var BASE_PRIMITIVE_TYPE_SET = new Set(BASE_PRIMITIVE_TYPES);
20365
+ var VALID_PRIMITIVE_TYPES = new Set([
20366
+ "number",
20367
+ "string",
20368
+ "boolean",
20369
+ "wref",
20370
+ "array",
20371
+ "number?",
20372
+ "string?",
20373
+ "boolean?",
20374
+ "wref?",
20375
+ "array?"
20376
+ ]);
20377
+ function isPlainObject(value) {
20378
+ return typeof value === "object" && value !== null && !Array.isArray(value);
20360
20379
  }
20361
- function tokenStringFields(op) {
20362
- const fields = [getOpName(op), op.newName];
20363
- if (typeof op.about === "string") {
20364
- fields.push(op.about);
20380
+ var STRING_CONSTRAINT_KEYS = new Set([
20381
+ "minLength",
20382
+ "maxLength",
20383
+ "pattern",
20384
+ "enum"
20385
+ ]);
20386
+ var NUMBER_CONSTRAINT_KEYS = new Set(["minimum", "maximum", "integer"]);
20387
+ var WREF_CONSTRAINT_KEYS = new Set(["shape"]);
20388
+ var ARRAY_CONSTRAINT_KEYS = new Set(["items", "minItems", "maxItems"]);
20389
+ var COMMON_TYPESPEC_KEYS = new Set(["type", "description"]);
20390
+ var VALID_TYPESPEC_KEYS = new Set([
20391
+ ...COMMON_TYPESPEC_KEYS,
20392
+ ...STRING_CONSTRAINT_KEYS,
20393
+ ...NUMBER_CONSTRAINT_KEYS,
20394
+ ...WREF_CONSTRAINT_KEYS,
20395
+ ...ARRAY_CONSTRAINT_KEYS
20396
+ ]);
20397
+ var CONSTRAINT_KEYS_BY_TYPE = {
20398
+ string: STRING_CONSTRAINT_KEYS,
20399
+ number: NUMBER_CONSTRAINT_KEYS,
20400
+ wref: WREF_CONSTRAINT_KEYS,
20401
+ array: ARRAY_CONSTRAINT_KEYS,
20402
+ boolean: new Set
20403
+ };
20404
+ function isTypeSpecObject(value) {
20405
+ if (!isPlainObject(value) || !("type" in value))
20406
+ return false;
20407
+ if (typeof value.type !== "string" || !VALID_PRIMITIVE_TYPES.has(value.type))
20408
+ return false;
20409
+ const baseType = value.type.endsWith("?") ? value.type.slice(0, -1) : value.type;
20410
+ const allowedConstraints = CONSTRAINT_KEYS_BY_TYPE[baseType] ?? new Set;
20411
+ if (!Object.keys(value).every((k) => COMMON_TYPESPEC_KEYS.has(k) || allowedConstraints.has(k)))
20412
+ return false;
20413
+ if ("minLength" in value && typeof value.minLength !== "number")
20414
+ return false;
20415
+ if ("maxLength" in value && typeof value.maxLength !== "number")
20416
+ return false;
20417
+ if ("pattern" in value && typeof value.pattern !== "string")
20418
+ return false;
20419
+ if ("pattern" in value && typeof value.pattern === "string" && VALID_PRIMITIVE_TYPES.has(value.pattern)) {
20420
+ const baseType2 = typeof value.type === "string" && value.type.endsWith("?") ? value.type.slice(0, -1) : value.type;
20421
+ if (baseType2 !== "string")
20422
+ return false;
20365
20423
  }
20366
- if (op.members) {
20367
- fields.push(...op.members);
20424
+ if ("enum" in value && !Array.isArray(value.enum))
20425
+ return false;
20426
+ if ("minimum" in value && typeof value.minimum !== "number")
20427
+ return false;
20428
+ if ("maximum" in value && typeof value.maximum !== "number")
20429
+ return false;
20430
+ if ("integer" in value && typeof value.integer !== "boolean")
20431
+ return false;
20432
+ if ("shape" in value && typeof value.shape !== "string")
20433
+ return false;
20434
+ if ("shape" in value && typeof value.shape === "string" && VALID_PRIMITIVE_TYPES.has(value.shape)) {
20435
+ const baseType2 = typeof value.type === "string" && value.type.endsWith("?") ? value.type.slice(0, -1) : value.type;
20436
+ if (baseType2 !== "wref")
20437
+ return false;
20368
20438
  }
20369
- return fields;
20439
+ if ("items" in value && typeof value.items === "number")
20440
+ return false;
20441
+ if ("items" in value && typeof value.items === "boolean")
20442
+ return false;
20443
+ if ("minItems" in value && typeof value.minItems !== "number")
20444
+ return false;
20445
+ if ("maxItems" in value && typeof value.maxItems !== "number")
20446
+ return false;
20447
+ return true;
20370
20448
  }
20371
- function rejectCommitTokenSyntax(operations, errors) {
20372
- for (let i = 0;i < operations.length; i++) {
20373
- const op = operations[i];
20374
- if (!op)
20375
- continue;
20376
- for (const field of tokenStringFields(op)) {
20377
- if (field && hasAnyTokens(field)) {
20378
- errors.push({
20379
- code: "COMMIT_TOKEN_SYNTAX_REMOVED",
20380
- operationIndex: i,
20381
- message: COMMIT_TOKEN_SYNTAX_REMOVED_MESSAGE
20382
- });
20383
- break;
20384
- }
20385
- }
20449
+ function primitiveTypeSpecFromFieldSpec(fieldType) {
20450
+ if (typeof fieldType === "string" && VALID_PRIMITIVE_TYPES.has(fieldType)) {
20451
+ return fieldType;
20452
+ }
20453
+ if (isTypeSpecObject(fieldType)) {
20454
+ return fieldType.type;
20386
20455
  }
20456
+ return null;
20387
20457
  }
20388
- function illegalOpSequences(operations, errors, checkAddAdd) {
20389
- const opHistory = new Map;
20390
- for (let i = 0;i < operations.length; i++) {
20391
- const op = operations[i];
20392
- if (!op)
20393
- continue;
20394
- const name = getOpName(op);
20395
- if (!name)
20396
- continue;
20397
- if (hasAnyTokens(name))
20398
- continue;
20399
- const kind = inferOperationKind({ ...op, name });
20400
- const qualName = kind === "shape" ? `shape:${name}` : `thing:${name}`;
20401
- const history = opHistory.get(qualName) ?? [];
20402
- history.push({ operation: op.operation, index: i });
20403
- opHistory.set(qualName, history);
20458
+ function basePrimitiveTypeFromSpec(fieldType) {
20459
+ const typeSpec = primitiveTypeSpecFromFieldSpec(fieldType);
20460
+ if (!typeSpec)
20461
+ return null;
20462
+ const base = typeSpec.endsWith("?") ? typeSpec.slice(0, -1) : typeSpec;
20463
+ return BASE_PRIMITIVE_TYPE_SET.has(base) ? base : null;
20464
+ }
20465
+ function fieldDescriptionFromSpec(fieldType) {
20466
+ let unwrapped = fieldType;
20467
+ if (Array.isArray(fieldType) && fieldType.length === 1) {
20468
+ unwrapped = fieldType[0];
20404
20469
  }
20405
- for (const [qualName, history] of opHistory) {
20406
- if (history.length < 2)
20407
- continue;
20408
- for (let i = 1;i < history.length; i++) {
20409
- const prev = history[i - 1];
20410
- const curr = history[i];
20411
- if (!prev || !curr)
20412
- continue;
20413
- const pair = `${prev.operation}+${curr.operation}`;
20414
- if (checkAddAdd && pair === "add+add") {
20415
- errors.push({
20416
- code: "ILLEGAL_OP_SEQUENCE",
20417
- operationIndex: curr.index,
20418
- message: `Cannot add "${qualName}" twice in the same commit`
20419
- });
20420
- }
20421
- if (pair === "revise+add") {
20422
- errors.push({
20423
- code: "ILLEGAL_OP_SEQUENCE",
20424
- operationIndex: curr.index,
20425
- message: `Cannot revise then add "${qualName}" in the same commit`
20426
- });
20427
- }
20470
+ if (isTypeSpecObject(unwrapped)) {
20471
+ if (typeof unwrapped.description === "string")
20472
+ return unwrapped.description;
20473
+ if ((unwrapped.type === "array" || unwrapped.type === "array?") && "items" in unwrapped) {
20474
+ return fieldDescriptionFromSpec(unwrapped.items);
20428
20475
  }
20476
+ return;
20429
20477
  }
20430
- }
20431
-
20432
- // ../../packages/rules/src/preflight-operation.ts
20433
- var collectionTypes = ["arc", "bond", "set", "list", "pair"];
20434
- var canonicalCollectionTypes = ["arc", "bond", "set", "list"];
20435
- var collectionOps = ["add", "revise"];
20436
- var COLLECTION_CREATE_REQUIRES_NAME_MESSAGE = "Collection create requires a name. Collections are ordinary named things (ADR 0004).";
20437
- 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.';
20438
- function preflightOpDiagnostics(op, operationIndex) {
20439
- const errors = [];
20440
- errors.push(...builtinShapeGuard(op, operationIndex));
20441
- errors.push(...contentNameGuard(op, operationIndex));
20442
- errors.push(...plusSignGuard(op, operationIndex));
20443
- errors.push(...validateCollectionAbouts(op, operationIndex));
20444
- errors.push(...validateCollectionOps(op, operationIndex));
20445
- return errors;
20446
- }
20447
- function builtinShapeGuard(op, operationIndex) {
20448
- const errors = [];
20449
- const name = op.name;
20450
- const isShapeRename = op.operation === "rename" && (op.kind === "shape" || op.name !== undefined && !splitLocalPath(op.name));
20451
- const reservedSourcePassThrough = isShapeRename && name !== undefined && isReservedCollectionShape(name) && op.newName !== undefined && !isReservedCollectionShape(op.newName) && !isBuiltinShape(op.newName);
20452
- if (name && isRetiredCollectionShape(name) && !reservedSourcePassThrough) {
20453
- errors.push({
20454
- code: "RESERVED_NAME",
20455
- operationIndex,
20456
- message: `Shape "${name}" is a retired collection shape and cannot be written manually`
20457
- });
20458
- }
20459
- if (op.operation === "rename" && (op.kind === "shape" || op.name !== undefined && !splitLocalPath(op.name)) && op.newName && isRetiredCollectionShape(op.newName)) {
20460
- errors.push({
20461
- code: "RESERVED_NAME",
20462
- operationIndex,
20463
- message: `Shape "${op.newName}" is a retired collection shape and cannot be written manually`
20464
- });
20465
- } else {
20466
- const builtinShapeName = name && isBuiltinShape(name) && !reservedSourcePassThrough ? name : isShapeRename && op.newName && isBuiltinShape(op.newName) ? op.newName : undefined;
20467
- if (builtinShapeName && (isShapeRename || op.operation !== "retract" && op.kind === "shape")) {
20468
- const action = op.operation === "add" ? "created" : op.operation === "rename" ? "renamed" : "revised";
20469
- errors.push({
20470
- code: "RESERVED_NAME",
20471
- operationIndex,
20472
- message: `Shape "${builtinShapeName}" is a built-in shape and cannot be ${action} manually`
20473
- });
20474
- }
20475
- }
20476
- if (name) {
20477
- const local = splitLocalPath(name);
20478
- if (local && isRetiredCollectionShape(local.shapePrefix)) {
20479
- errors.push({
20480
- code: "VALIDATION_ERROR",
20481
- operationIndex,
20482
- message: `Cannot ${op.operation} under retired collection shape "${local.shapePrefix}". Triple is read-only and retired for new collection writes.`
20483
- });
20484
- } else if (op.kind === "thing" && local && isBuiltinCollectionShape(local.shapePrefix)) {
20485
- 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.`;
20486
- errors.push({
20487
- code: "VALIDATION_ERROR",
20488
- operationIndex,
20489
- message
20490
- });
20491
- }
20492
- }
20493
- return errors;
20494
- }
20495
- function contentNameGuard(op, operationIndex) {
20496
- if (op.kind !== "thing" || !op.name)
20497
- return [];
20498
- const local = splitLocalPath(op.name);
20499
- if (!local || !isContentShape(local.shapePrefix))
20500
- return [];
20501
- const bareName = local.bareName;
20502
- if (isSynthesizedContentName(bareName)) {
20503
- return [
20504
- {
20505
- code: "READ_ONLY_BUILTIN_CONTENT",
20506
- operationIndex,
20507
- message: `${local.shapePrefix}/${bareName} is synthesized; writes are not allowed`
20508
- }
20509
- ];
20510
- }
20511
- if (!isStoredContentName(bareName)) {
20512
- return [
20513
- {
20514
- code: "UNKNOWN_CONTENT_NAME",
20515
- operationIndex,
20516
- message: `${local.shapePrefix}/${bareName} is not a recognized well-known content name`
20517
- }
20518
- ];
20519
- }
20520
- return [];
20521
- }
20522
- function plusSignGuard(op, operationIndex) {
20523
- const errors = [];
20524
- const name = op.name;
20525
- if (op.newName?.includes("+")) {
20526
- errors.push({
20527
- code: "VALIDATION_ERROR",
20528
- operationIndex,
20529
- 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.`
20530
- });
20531
- return errors;
20532
- }
20533
- if (name?.includes("+")) {
20534
- if (op.kind === "collection" && op.operation === "add") {
20535
- errors.push({
20536
- code: "VALIDATION_ERROR",
20537
- operationIndex,
20538
- 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.`
20539
- });
20540
- return errors;
20541
- }
20542
- if (op.kind === "collection")
20543
- return errors;
20544
- const local = splitLocalPath(name);
20545
- if (local && isReservedCollectionShape(local.shapePrefix))
20546
- return errors;
20547
- errors.push({
20548
- code: "VALIDATION_ERROR",
20549
- operationIndex,
20550
- 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.`
20551
- });
20552
- }
20553
- return errors;
20554
- }
20555
- function validateCollectionAbouts(op, operationIndex) {
20556
- const errors = [];
20557
- if (!op.about || typeof op.about === "string")
20558
- return errors;
20559
- errors.push({
20560
- code: "VALIDATION_ERROR",
20561
- operationIndex,
20562
- message: COLLECTION_ABOUT_REMOVED_MESSAGE
20563
- });
20564
- return errors;
20565
- }
20566
- function validateCollectionOps(op, operationIndex) {
20567
- const errors = [];
20568
- if (op.kind !== "collection")
20569
- return errors;
20570
- if (!collectionOps.includes(op.operation)) {
20571
- return errors;
20572
- }
20573
- if (op.operation === "add" && !op.name) {
20574
- errors.push({
20575
- code: "VALIDATION_ERROR",
20576
- operationIndex,
20577
- message: COLLECTION_CREATE_REQUIRES_NAME_MESSAGE
20578
- });
20579
- }
20580
- if (!op.type || !collectionTypes.includes(op.type)) {
20581
- errors.push({
20582
- code: "VALIDATION_ERROR",
20583
- operationIndex,
20584
- message: `Collection "type" is invalid. Use one of: ${canonicalCollectionTypes.join(", ")}. Got: "${op.type ?? ""}"`
20585
- });
20586
- }
20587
- if (!op.members || !Array.isArray(op.members)) {
20588
- errors.push({
20589
- code: "VALIDATION_ERROR",
20590
- operationIndex,
20591
- message: 'Collection requires a "members" array'
20592
- });
20593
- } else {
20594
- for (let i = 0;i < op.members.length; i++) {
20595
- if (typeof op.members[i] !== "string") {
20596
- errors.push({
20597
- code: "VALIDATION_ERROR",
20598
- operationIndex,
20599
- message: `Collection member at index ${i} must be a string`
20600
- });
20601
- }
20602
- }
20603
- }
20604
- if (op.type && op.members) {
20605
- const arityError = collectionArityError(op.type, op.members);
20606
- if (arityError) {
20607
- errors.push({
20608
- code: "VALIDATION_ERROR",
20609
- operationIndex,
20610
- message: arityError
20611
- });
20612
- }
20613
- }
20614
- return errors;
20615
- }
20616
- function collectionArityError(tag, members) {
20617
- switch (tag) {
20618
- case "arc":
20619
- return members.length !== 2 ? `Arc requires exactly 2 members, got ${members.length}` : null;
20620
- case "bond":
20621
- return members.length !== 2 ? `Bond requires exactly 2 members, got ${members.length}` : null;
20622
- case "pair":
20623
- return members.length !== 2 ? `Pair requires exactly 2 members, got ${members.length}` : null;
20624
- case "set":
20625
- case "list":
20626
- return members.length < 1 ? `${tag === "set" ? "Set" : "List"} requires at least 1 member, got 0` : null;
20627
- }
20628
- }
20629
- // ../../packages/rules/src/preflight.ts
20630
- function preflightOpDiagnostics2(op, operationIndex) {
20631
- return preflightOpDiagnostics(op, operationIndex);
20632
- }
20633
- function preflightCommitDiagnostics2(operations, options) {
20634
- return preflightCommitDiagnostics(operations, options);
20635
- }
20636
- // ../../packages/rules/src/read-limits.ts
20637
- var MAX_GET_MANY_WREFS = 500;
20638
- // ../../packages/rules/src/reserved-orgs.ts
20639
- var RESERVED_RAW_CONTENT_TOP_LEVEL_NAMES = [
20640
- "_app",
20641
- "_static",
20642
- "api",
20643
- "health",
20644
- "healthz",
20645
- "mcp",
20646
- "readyz",
20647
- "robots.txt",
20648
- "sse",
20649
- "trpc",
20650
- "version"
20651
- ];
20652
- var RESERVED_ORG_NAMES = [
20653
- ...RESERVED_RAW_CONTENT_TOP_LEVEL_NAMES,
20654
- "admin",
20655
- "billing",
20656
- "blog",
20657
- "docs",
20658
- "help",
20659
- "login",
20660
- "public",
20661
- "settings",
20662
- "signup",
20663
- "status",
20664
- "support",
20665
- "system",
20666
- "warmhub",
20667
- "www"
20668
- ];
20669
- var RESERVED_ORG_NAME_SET = new Set(RESERVED_ORG_NAMES);
20670
- // ../../packages/rules/src/shape-field-key.ts
20671
- function foldFieldName(name) {
20672
- const stripped = name.endsWith("?") ? name.slice(0, -1) : name;
20673
- return stripped.toLowerCase();
20674
- }
20675
- function foldFieldPath(path) {
20676
- return path.split(".").map((segment) => foldFieldName(segment)).join(".");
20677
- }
20678
- // ../../packages/rules/src/shape-types.ts
20679
- var BASE_PRIMITIVE_TYPES = [
20680
- "number",
20681
- "string",
20682
- "boolean",
20683
- "wref",
20684
- "array"
20685
- ];
20686
- var BASE_PRIMITIVE_TYPE_SET = new Set(BASE_PRIMITIVE_TYPES);
20687
- var VALID_PRIMITIVE_TYPES = new Set([
20688
- "number",
20689
- "string",
20690
- "boolean",
20691
- "wref",
20692
- "array",
20693
- "number?",
20694
- "string?",
20695
- "boolean?",
20696
- "wref?",
20697
- "array?"
20698
- ]);
20699
- function isPlainObject(value) {
20700
- return typeof value === "object" && value !== null && !Array.isArray(value);
20701
- }
20702
- var STRING_CONSTRAINT_KEYS = new Set([
20703
- "minLength",
20704
- "maxLength",
20705
- "pattern",
20706
- "enum"
20707
- ]);
20708
- var NUMBER_CONSTRAINT_KEYS = new Set(["minimum", "maximum", "integer"]);
20709
- var WREF_CONSTRAINT_KEYS = new Set(["shape"]);
20710
- var ARRAY_CONSTRAINT_KEYS = new Set(["items", "minItems", "maxItems"]);
20711
- var COMMON_TYPESPEC_KEYS = new Set(["type", "description"]);
20712
- var VALID_TYPESPEC_KEYS = new Set([
20713
- ...COMMON_TYPESPEC_KEYS,
20714
- ...STRING_CONSTRAINT_KEYS,
20715
- ...NUMBER_CONSTRAINT_KEYS,
20716
- ...WREF_CONSTRAINT_KEYS,
20717
- ...ARRAY_CONSTRAINT_KEYS
20718
- ]);
20719
- var CONSTRAINT_KEYS_BY_TYPE = {
20720
- string: STRING_CONSTRAINT_KEYS,
20721
- number: NUMBER_CONSTRAINT_KEYS,
20722
- wref: WREF_CONSTRAINT_KEYS,
20723
- array: ARRAY_CONSTRAINT_KEYS,
20724
- boolean: new Set
20725
- };
20726
- function isTypeSpecObject(value) {
20727
- if (!isPlainObject(value) || !("type" in value))
20728
- return false;
20729
- if (typeof value.type !== "string" || !VALID_PRIMITIVE_TYPES.has(value.type))
20730
- return false;
20731
- const baseType = value.type.endsWith("?") ? value.type.slice(0, -1) : value.type;
20732
- const allowedConstraints = CONSTRAINT_KEYS_BY_TYPE[baseType] ?? new Set;
20733
- if (!Object.keys(value).every((k) => COMMON_TYPESPEC_KEYS.has(k) || allowedConstraints.has(k)))
20734
- return false;
20735
- if ("minLength" in value && typeof value.minLength !== "number")
20736
- return false;
20737
- if ("maxLength" in value && typeof value.maxLength !== "number")
20738
- return false;
20739
- if ("pattern" in value && typeof value.pattern !== "string")
20740
- return false;
20741
- if ("pattern" in value && typeof value.pattern === "string" && VALID_PRIMITIVE_TYPES.has(value.pattern)) {
20742
- const baseType2 = typeof value.type === "string" && value.type.endsWith("?") ? value.type.slice(0, -1) : value.type;
20743
- if (baseType2 !== "string")
20744
- return false;
20745
- }
20746
- if ("enum" in value && !Array.isArray(value.enum))
20747
- return false;
20748
- if ("minimum" in value && typeof value.minimum !== "number")
20749
- return false;
20750
- if ("maximum" in value && typeof value.maximum !== "number")
20751
- return false;
20752
- if ("integer" in value && typeof value.integer !== "boolean")
20753
- return false;
20754
- if ("shape" in value && typeof value.shape !== "string")
20755
- return false;
20756
- if ("shape" in value && typeof value.shape === "string" && VALID_PRIMITIVE_TYPES.has(value.shape)) {
20757
- const baseType2 = typeof value.type === "string" && value.type.endsWith("?") ? value.type.slice(0, -1) : value.type;
20758
- if (baseType2 !== "wref")
20759
- return false;
20760
- }
20761
- if ("items" in value && typeof value.items === "number")
20762
- return false;
20763
- if ("items" in value && typeof value.items === "boolean")
20764
- return false;
20765
- if ("minItems" in value && typeof value.minItems !== "number")
20766
- return false;
20767
- if ("maxItems" in value && typeof value.maxItems !== "number")
20768
- return false;
20769
- return true;
20770
- }
20771
- function primitiveTypeSpecFromFieldSpec(fieldType) {
20772
- if (typeof fieldType === "string" && VALID_PRIMITIVE_TYPES.has(fieldType)) {
20773
- return fieldType;
20774
- }
20775
- if (isTypeSpecObject(fieldType)) {
20776
- return fieldType.type;
20777
- }
20778
- return null;
20779
- }
20780
- function basePrimitiveTypeFromSpec(fieldType) {
20781
- const typeSpec = primitiveTypeSpecFromFieldSpec(fieldType);
20782
- if (!typeSpec)
20783
- return null;
20784
- const base = typeSpec.endsWith("?") ? typeSpec.slice(0, -1) : typeSpec;
20785
- return BASE_PRIMITIVE_TYPE_SET.has(base) ? base : null;
20786
- }
20787
- function fieldDescriptionFromSpec(fieldType) {
20788
- let unwrapped = fieldType;
20789
- if (Array.isArray(fieldType) && fieldType.length === 1) {
20790
- unwrapped = fieldType[0];
20791
- }
20792
- if (isTypeSpecObject(unwrapped)) {
20793
- if (typeof unwrapped.description === "string")
20794
- return unwrapped.description;
20795
- if ((unwrapped.type === "array" || unwrapped.type === "array?") && "items" in unwrapped) {
20796
- return fieldDescriptionFromSpec(unwrapped.items);
20797
- }
20798
- return;
20799
- }
20800
- return;
20478
+ return;
20801
20479
  }
20802
20480
  function displayFieldType(fieldType) {
20803
20481
  if (typeof fieldType === "string")
@@ -20872,6 +20550,7 @@ function displayFieldEntry(fieldType) {
20872
20550
  return { type, description };
20873
20551
  return type;
20874
20552
  }
20553
+
20875
20554
  // ../../node_modules/.bun/re2js@2.8.3/node_modules/re2js/build/index.js
20876
20555
  /*!
20877
20556
  * re2js
@@ -27184,188 +26863,547 @@ var RE2JS = class RE2JS2 {
27184
26863
  pattern() {
27185
26864
  return this.patternInput;
27186
26865
  }
27187
- re2() {
27188
- return this.re2Input;
26866
+ re2() {
26867
+ return this.re2Input;
26868
+ }
26869
+ matches(input) {
26870
+ return this.testExact(input);
26871
+ }
26872
+ matcher(input) {
26873
+ if (Utils.isByteArray(input))
26874
+ input = MatcherInput.utf8(input);
26875
+ return new Matcher(this, input);
26876
+ }
26877
+ test(input) {
26878
+ if (Utils.isByteArray(input))
26879
+ return this.re2Input.matchUTF8(input);
26880
+ return this.re2Input.match(input);
26881
+ }
26882
+ testExact(input) {
26883
+ const machineInput = Utils.isByteArray(input) ? MachineInput.fromUTF8(input) : MachineInput.fromUTF16(input);
26884
+ return this.re2Input.executeEngine(machineInput, 0, RE2Flags.ANCHOR_BOTH, 0) !== null;
26885
+ }
26886
+ split(input, limit = 0) {
26887
+ const m = this.matcher(input);
26888
+ const result = [];
26889
+ let emptiesSkipped = 0;
26890
+ let last = 0;
26891
+ while (m.find()) {
26892
+ if (last === 0 && m.end() === 0) {
26893
+ last = m.end();
26894
+ continue;
26895
+ }
26896
+ if (limit > 0 && result.length === limit - 1)
26897
+ break;
26898
+ if (last === m.start()) {
26899
+ if (limit === 0) {
26900
+ emptiesSkipped += 1;
26901
+ last = m.end();
26902
+ continue;
26903
+ }
26904
+ } else
26905
+ while (emptiesSkipped > 0) {
26906
+ result.push("");
26907
+ emptiesSkipped -= 1;
26908
+ }
26909
+ result.push(m.substring(last, m.start()));
26910
+ last = m.end();
26911
+ }
26912
+ if (limit === 0 && last !== m.inputLength()) {
26913
+ while (emptiesSkipped > 0) {
26914
+ result.push("");
26915
+ emptiesSkipped -= 1;
26916
+ }
26917
+ result.push(m.substring(last, m.inputLength()));
26918
+ }
26919
+ if (limit !== 0 || result.length === 0)
26920
+ result.push(m.substring(last, m.inputLength()));
26921
+ return result;
26922
+ }
26923
+ *matchAll(input) {
26924
+ const m = this.matcher(input);
26925
+ while (m.find()) {
26926
+ const result = [m.group(0)];
26927
+ for (let i = 1;i <= m.groupCount(); i++) {
26928
+ const groupVal = m.group(i);
26929
+ result.push(groupVal === null ? undefined : groupVal);
26930
+ }
26931
+ result.index = m.start(0);
26932
+ result.input = input;
26933
+ const namedGroups = this.namedGroups();
26934
+ if (Object.keys(namedGroups).length > 0) {
26935
+ const parsedGroups = m.getNamedGroups();
26936
+ for (const key in parsedGroups)
26937
+ if (parsedGroups[key] === null)
26938
+ parsedGroups[key] = undefined;
26939
+ result.groups = parsedGroups;
26940
+ } else
26941
+ result.groups = undefined;
26942
+ yield result;
26943
+ }
26944
+ }
26945
+ toString() {
26946
+ return this.patternInput;
26947
+ }
26948
+ programSize() {
26949
+ return this.re2Input.numberOfInstructions();
26950
+ }
26951
+ groupCount() {
26952
+ return this.re2Input.numberOfCapturingGroups();
26953
+ }
26954
+ namedGroups() {
26955
+ return this.re2Input.namedGroups;
26956
+ }
26957
+ equals(other) {
26958
+ if (this === other)
26959
+ return true;
26960
+ if (other === null || this.constructor !== other.constructor)
26961
+ return false;
26962
+ return this.flagsInput === other.flagsInput && this.patternInput === other.patternInput;
26963
+ }
26964
+ };
26965
+
26966
+ // ../../packages/rules/src/shape-validation-types.ts
26967
+ var MAX_CONTENT_FIELD_BYTES = 64 * 1024;
26968
+ var MAX_INDEXABLE_SCALAR_FIELDS_PER_SHAPE = 256;
26969
+ var MAX_INDEXABLE_FIELD_PATH_BYTES = 256;
26970
+ var UNSUPPORTED_REGEX_SYNTAX_REASON = "uses unsupported regex syntax";
26971
+ 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.";
26972
+ var textEncoder = new TextEncoder;
26973
+ function utf8ByteLength(value) {
26974
+ return textEncoder.encode(value).byteLength;
26975
+ }
26976
+ function contentFieldLimitError(path, value) {
26977
+ if (value.length * 3 <= MAX_CONTENT_FIELD_BYTES)
26978
+ return null;
26979
+ const byteLength = utf8ByteLength(value);
26980
+ if (byteLength <= MAX_CONTENT_FIELD_BYTES)
26981
+ return null;
26982
+ return `Field "${path}" is ${byteLength} bytes; ${CONTENT_FIELD_LIMIT_ERROR}`;
26983
+ }
26984
+ function assertContentFieldWithinLimit(path, value, errors) {
26985
+ const message = contentFieldLimitError(path, value);
26986
+ if (message)
26987
+ errors.push(message);
26988
+ }
26989
+ function nativeRegexSyntaxError(pattern) {
26990
+ try {
26991
+ new RegExp(pattern);
26992
+ return false;
26993
+ } catch {
26994
+ return true;
26995
+ }
26996
+ }
26997
+ function normalizePatternForPortableEngine(pattern) {
26998
+ let normalized = "";
26999
+ let inCharacterClass = false;
27000
+ for (let i = 0;i < pattern.length; i++) {
27001
+ const char = pattern[i];
27002
+ if (char === "\\") {
27003
+ const next = pattern[i + 1];
27004
+ if (inCharacterClass && next === "b") {
27005
+ normalized += "\\x08";
27006
+ i++;
27007
+ continue;
27008
+ }
27009
+ normalized += char;
27010
+ if (next !== undefined) {
27011
+ normalized += next;
27012
+ i++;
27013
+ }
27014
+ continue;
27015
+ }
27016
+ if (char === "[") {
27017
+ inCharacterClass = true;
27018
+ } else if (char === "]") {
27019
+ inCharacterClass = false;
27020
+ }
27021
+ normalized += char;
27022
+ }
27023
+ return normalized;
27024
+ }
27025
+ function compilePortablePattern(pattern) {
27026
+ try {
27027
+ return RE2JS.compile(normalizePatternForPortableEngine(pattern));
27028
+ } catch {
27029
+ return;
27189
27030
  }
27190
- matches(input) {
27191
- return this.testExact(input);
27031
+ }
27032
+ function unsupportedPortablePatternReason(pattern) {
27033
+ return compilePortablePattern(pattern) ? undefined : UNSUPPORTED_REGEX_SYNTAX_REASON;
27034
+ }
27035
+ function normalizeOptionalTypeSpec(spec) {
27036
+ if (typeof spec === "string" && spec.endsWith("?")) {
27037
+ return { spec: spec.slice(0, -1), optionalByType: true };
27192
27038
  }
27193
- matcher(input) {
27194
- if (Utils.isByteArray(input))
27195
- input = MatcherInput.utf8(input);
27196
- return new Matcher(this, input);
27039
+ if (isTypeSpecObject(spec) && typeof spec.type === "string" && spec.type.endsWith("?")) {
27040
+ return {
27041
+ spec: { ...spec, type: spec.type.slice(0, -1) },
27042
+ optionalByType: true
27043
+ };
27197
27044
  }
27198
- test(input) {
27199
- if (Utils.isByteArray(input))
27200
- return this.re2Input.matchUTF8(input);
27201
- return this.re2Input.match(input);
27045
+ return { spec, optionalByType: false };
27046
+ }
27047
+ // ../../packages/rules/src/external-contract.ts
27048
+ var FORBIDDEN_EXTERNAL_FIELDS = new Set([
27049
+ "_id",
27050
+ "_creationTime",
27051
+ "repoId",
27052
+ "orgId",
27053
+ "thingId",
27054
+ "shapeThingId",
27055
+ "aboutThingId",
27056
+ "currentVersionId",
27057
+ "createdInCommitId",
27058
+ "validatedShapeVersionId"
27059
+ ]);
27060
+ // ../../packages/rules/src/name-charset.ts
27061
+ var RESERVED_NAME_SEGMENT_CHARS = ["?", "#", "@", ":", "$"];
27062
+ function escapeForCharClass(char) {
27063
+ return char.replace(/[\\\]^-]/g, "\\$&");
27064
+ }
27065
+ var RESERVED_CLASS_BODY = RESERVED_NAME_SEGMENT_CHARS.map(escapeForCharClass).join("");
27066
+ var NAME_SEGMENT_FORBIDDEN_RE = new RegExp(`[${RESERVED_CLASS_BODY}\\s]`);
27067
+ var PATH_SEGMENT_FORBIDDEN_RE = new RegExp(`[/${RESERVED_CLASS_BODY}\\s]`);
27068
+ // ../../packages/rules/src/permission-scopes.ts
27069
+ var PUBLIC_ORG_PERMISSIONS = new Set([
27070
+ "org:read",
27071
+ "components:read"
27072
+ ]);
27073
+ // ../../packages/rules/src/tokens.ts
27074
+ 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.";
27075
+ var ANY_TOKEN_RE = /[$#]\d+/;
27076
+ function hasAnyTokens(s) {
27077
+ return ANY_TOKEN_RE.test(s);
27078
+ }
27079
+
27080
+ // ../../packages/rules/src/preflight-commit.ts
27081
+ function preflightCommitDiagnostics(operations, options) {
27082
+ const errors = [];
27083
+ rejectCommitTokenSyntax(operations, errors);
27084
+ illegalOpSequences(operations, errors, options?.checkAddAdd ?? true);
27085
+ return errors;
27086
+ }
27087
+ function getOpName(op) {
27088
+ return op.name;
27089
+ }
27090
+ function tokenStringFields(op) {
27091
+ const fields = [getOpName(op), op.newName];
27092
+ if (typeof op.about === "string") {
27093
+ fields.push(op.about);
27202
27094
  }
27203
- testExact(input) {
27204
- const machineInput = Utils.isByteArray(input) ? MachineInput.fromUTF8(input) : MachineInput.fromUTF16(input);
27205
- return this.re2Input.executeEngine(machineInput, 0, RE2Flags.ANCHOR_BOTH, 0) !== null;
27095
+ if (op.members) {
27096
+ fields.push(...op.members);
27206
27097
  }
27207
- split(input, limit = 0) {
27208
- const m = this.matcher(input);
27209
- const result = [];
27210
- let emptiesSkipped = 0;
27211
- let last = 0;
27212
- while (m.find()) {
27213
- if (last === 0 && m.end() === 0) {
27214
- last = m.end();
27215
- continue;
27216
- }
27217
- if (limit > 0 && result.length === limit - 1)
27098
+ return fields;
27099
+ }
27100
+ function rejectCommitTokenSyntax(operations, errors) {
27101
+ for (let i = 0;i < operations.length; i++) {
27102
+ const op = operations[i];
27103
+ if (!op)
27104
+ continue;
27105
+ for (const field of tokenStringFields(op)) {
27106
+ if (field && hasAnyTokens(field)) {
27107
+ errors.push({
27108
+ code: "COMMIT_TOKEN_SYNTAX_REMOVED",
27109
+ operationIndex: i,
27110
+ message: COMMIT_TOKEN_SYNTAX_REMOVED_MESSAGE
27111
+ });
27218
27112
  break;
27219
- if (last === m.start()) {
27220
- if (limit === 0) {
27221
- emptiesSkipped += 1;
27222
- last = m.end();
27223
- continue;
27224
- }
27225
- } else
27226
- while (emptiesSkipped > 0) {
27227
- result.push("");
27228
- emptiesSkipped -= 1;
27229
- }
27230
- result.push(m.substring(last, m.start()));
27231
- last = m.end();
27232
- }
27233
- if (limit === 0 && last !== m.inputLength()) {
27234
- while (emptiesSkipped > 0) {
27235
- result.push("");
27236
- emptiesSkipped -= 1;
27237
27113
  }
27238
- result.push(m.substring(last, m.inputLength()));
27239
27114
  }
27240
- if (limit !== 0 || result.length === 0)
27241
- result.push(m.substring(last, m.inputLength()));
27242
- return result;
27243
27115
  }
27244
- *matchAll(input) {
27245
- const m = this.matcher(input);
27246
- while (m.find()) {
27247
- const result = [m.group(0)];
27248
- for (let i = 1;i <= m.groupCount(); i++) {
27249
- const groupVal = m.group(i);
27250
- result.push(groupVal === null ? undefined : groupVal);
27116
+ }
27117
+ function illegalOpSequences(operations, errors, checkAddAdd) {
27118
+ const opHistory = new Map;
27119
+ for (let i = 0;i < operations.length; i++) {
27120
+ const op = operations[i];
27121
+ if (!op)
27122
+ continue;
27123
+ const name = getOpName(op);
27124
+ if (!name)
27125
+ continue;
27126
+ if (hasAnyTokens(name))
27127
+ continue;
27128
+ const kind = inferOperationKind({ ...op, name });
27129
+ const qualName = kind === "shape" ? `shape:${name}` : `thing:${name}`;
27130
+ const history = opHistory.get(qualName) ?? [];
27131
+ history.push({ operation: op.operation, index: i });
27132
+ opHistory.set(qualName, history);
27133
+ }
27134
+ for (const [qualName, history] of opHistory) {
27135
+ if (history.length < 2)
27136
+ continue;
27137
+ for (let i = 1;i < history.length; i++) {
27138
+ const prev = history[i - 1];
27139
+ const curr = history[i];
27140
+ if (!prev || !curr)
27141
+ continue;
27142
+ const pair = `${prev.operation}+${curr.operation}`;
27143
+ if (checkAddAdd && pair === "add+add") {
27144
+ errors.push({
27145
+ code: "ILLEGAL_OP_SEQUENCE",
27146
+ operationIndex: curr.index,
27147
+ message: `Cannot add "${qualName}" twice in the same commit`
27148
+ });
27149
+ }
27150
+ if (pair === "revise+add") {
27151
+ errors.push({
27152
+ code: "ILLEGAL_OP_SEQUENCE",
27153
+ operationIndex: curr.index,
27154
+ message: `Cannot revise then add "${qualName}" in the same commit`
27155
+ });
27251
27156
  }
27252
- result.index = m.start(0);
27253
- result.input = input;
27254
- const namedGroups = this.namedGroups();
27255
- if (Object.keys(namedGroups).length > 0) {
27256
- const parsedGroups = m.getNamedGroups();
27257
- for (const key in parsedGroups)
27258
- if (parsedGroups[key] === null)
27259
- parsedGroups[key] = undefined;
27260
- result.groups = parsedGroups;
27261
- } else
27262
- result.groups = undefined;
27263
- yield result;
27264
27157
  }
27265
27158
  }
27266
- toString() {
27267
- return this.patternInput;
27159
+ }
27160
+
27161
+ // ../../packages/rules/src/preflight-operation.ts
27162
+ var collectionTypes = ["arc", "bond", "set", "list", "pair"];
27163
+ var canonicalCollectionTypes = ["arc", "bond", "set", "list"];
27164
+ var collectionOps = ["add", "revise"];
27165
+ var COLLECTION_CREATE_REQUIRES_NAME_MESSAGE = "Collection create requires a name. Collections are ordinary named things (ADR 0004).";
27166
+ 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.';
27167
+ function preflightOpDiagnostics(op, operationIndex) {
27168
+ const errors = [];
27169
+ errors.push(...builtinShapeGuard(op, operationIndex));
27170
+ errors.push(...contentNameGuard(op, operationIndex));
27171
+ errors.push(...plusSignGuard(op, operationIndex));
27172
+ errors.push(...validateCollectionAbouts(op, operationIndex));
27173
+ errors.push(...validateCollectionOps(op, operationIndex));
27174
+ return errors;
27175
+ }
27176
+ function builtinShapeGuard(op, operationIndex) {
27177
+ const errors = [];
27178
+ const name = op.name;
27179
+ const isShapeRename = op.operation === "rename" && (op.kind === "shape" || op.name !== undefined && !splitLocalPath(op.name));
27180
+ const reservedSourcePassThrough = isShapeRename && name !== undefined && isRenameableSquattedShape(name) && op.newName !== undefined && !isReservedCollectionShape(op.newName) && !isBuiltinShape(op.newName);
27181
+ if (name && isRetiredCollectionShape(name) && !reservedSourcePassThrough) {
27182
+ errors.push({
27183
+ code: "RESERVED_NAME",
27184
+ operationIndex,
27185
+ message: `Shape "${name}" is a retired collection shape and cannot be written manually`
27186
+ });
27268
27187
  }
27269
- programSize() {
27270
- return this.re2Input.numberOfInstructions();
27188
+ if (op.operation === "rename" && (op.kind === "shape" || op.name !== undefined && !splitLocalPath(op.name)) && op.newName && isRetiredCollectionShape(op.newName)) {
27189
+ errors.push({
27190
+ code: "RESERVED_NAME",
27191
+ operationIndex,
27192
+ message: `Shape "${op.newName}" is a retired collection shape and cannot be written manually`
27193
+ });
27194
+ } else {
27195
+ const builtinShapeName = name && isBuiltinShape(name) && !reservedSourcePassThrough ? name : isShapeRename && op.newName && isBuiltinShape(op.newName) ? op.newName : undefined;
27196
+ if (builtinShapeName && (isShapeRename || op.operation !== "retract" && op.kind === "shape")) {
27197
+ const action = op.operation === "add" ? "created" : op.operation === "rename" ? "renamed" : "revised";
27198
+ errors.push({
27199
+ code: "RESERVED_NAME",
27200
+ operationIndex,
27201
+ message: `Shape "${builtinShapeName}" is a built-in shape and cannot be ${action} manually`
27202
+ });
27203
+ }
27271
27204
  }
27272
- groupCount() {
27273
- return this.re2Input.numberOfCapturingGroups();
27205
+ if (name) {
27206
+ const local = splitLocalPath(name);
27207
+ if (local && isRetiredCollectionShape(local.shapePrefix)) {
27208
+ errors.push({
27209
+ code: "VALIDATION_ERROR",
27210
+ operationIndex,
27211
+ message: `Cannot ${op.operation} under retired collection shape "${local.shapePrefix}". Triple is read-only and retired for new collection writes.`
27212
+ });
27213
+ } else if (op.kind === "thing" && local && isBuiltinCollectionShape(local.shapePrefix)) {
27214
+ 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.`;
27215
+ errors.push({
27216
+ code: "VALIDATION_ERROR",
27217
+ operationIndex,
27218
+ message
27219
+ });
27220
+ }
27274
27221
  }
27275
- namedGroups() {
27276
- return this.re2Input.namedGroups;
27222
+ return errors;
27223
+ }
27224
+ function contentNameGuard(op, operationIndex) {
27225
+ if (op.kind !== "thing" || !op.name)
27226
+ return [];
27227
+ const local = splitLocalPath(op.name);
27228
+ if (!local || !isContentShape(local.shapePrefix))
27229
+ return [];
27230
+ const bareName = local.bareName;
27231
+ if (isSynthesizedContentName(bareName)) {
27232
+ return [
27233
+ {
27234
+ code: "READ_ONLY_BUILTIN_CONTENT",
27235
+ operationIndex,
27236
+ message: `${local.shapePrefix}/${bareName} is synthesized; writes are not allowed`
27237
+ }
27238
+ ];
27277
27239
  }
27278
- equals(other) {
27279
- if (this === other)
27280
- return true;
27281
- if (other === null || this.constructor !== other.constructor)
27282
- return false;
27283
- return this.flagsInput === other.flagsInput && this.patternInput === other.patternInput;
27240
+ if (!isStoredContentName(bareName)) {
27241
+ return [
27242
+ {
27243
+ code: "UNKNOWN_CONTENT_NAME",
27244
+ operationIndex,
27245
+ message: `${local.shapePrefix}/${bareName} is not a recognized well-known content name`
27246
+ }
27247
+ ];
27284
27248
  }
27285
- };
27286
-
27287
- // ../../packages/rules/src/shape-validation-types.ts
27288
- var MAX_CONTENT_FIELD_BYTES = 64 * 1024;
27289
- var MAX_INDEXABLE_SCALAR_FIELDS_PER_SHAPE = 256;
27290
- var MAX_INDEXABLE_FIELD_PATH_BYTES = 256;
27291
- var UNSUPPORTED_REGEX_SYNTAX_REASON = "uses unsupported regex syntax";
27292
- 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.";
27293
- var textEncoder = new TextEncoder;
27294
- function utf8ByteLength(value) {
27295
- return textEncoder.encode(value).byteLength;
27249
+ return [];
27296
27250
  }
27297
- function contentFieldLimitError(path, value) {
27298
- if (value.length * 3 <= MAX_CONTENT_FIELD_BYTES)
27299
- return null;
27300
- const byteLength = utf8ByteLength(value);
27301
- if (byteLength <= MAX_CONTENT_FIELD_BYTES)
27302
- return null;
27303
- return `Field "${path}" is ${byteLength} bytes; ${CONTENT_FIELD_LIMIT_ERROR}`;
27251
+ function plusSignGuard(op, operationIndex) {
27252
+ const errors = [];
27253
+ const name = op.name;
27254
+ if (op.newName?.includes("+")) {
27255
+ errors.push({
27256
+ code: "VALIDATION_ERROR",
27257
+ operationIndex,
27258
+ 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.`
27259
+ });
27260
+ return errors;
27261
+ }
27262
+ if (name?.includes("+")) {
27263
+ if (op.kind === "collection" && op.operation === "add") {
27264
+ errors.push({
27265
+ code: "VALIDATION_ERROR",
27266
+ operationIndex,
27267
+ 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.`
27268
+ });
27269
+ return errors;
27270
+ }
27271
+ if (op.kind === "collection")
27272
+ return errors;
27273
+ const local = splitLocalPath(name);
27274
+ if (local && isReservedCollectionShape(local.shapePrefix))
27275
+ return errors;
27276
+ errors.push({
27277
+ code: "VALIDATION_ERROR",
27278
+ operationIndex,
27279
+ 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.`
27280
+ });
27281
+ }
27282
+ return errors;
27304
27283
  }
27305
- function assertContentFieldWithinLimit(path, value, errors) {
27306
- const message = contentFieldLimitError(path, value);
27307
- if (message)
27308
- errors.push(message);
27284
+ function validateCollectionAbouts(op, operationIndex) {
27285
+ const errors = [];
27286
+ if (!op.about || typeof op.about === "string")
27287
+ return errors;
27288
+ errors.push({
27289
+ code: "VALIDATION_ERROR",
27290
+ operationIndex,
27291
+ message: COLLECTION_ABOUT_REMOVED_MESSAGE
27292
+ });
27293
+ return errors;
27309
27294
  }
27310
- function nativeRegexSyntaxError(pattern) {
27311
- try {
27312
- new RegExp(pattern);
27313
- return false;
27314
- } catch {
27315
- return true;
27295
+ function validateCollectionOps(op, operationIndex) {
27296
+ const errors = [];
27297
+ if (op.kind !== "collection")
27298
+ return errors;
27299
+ if (!collectionOps.includes(op.operation)) {
27300
+ return errors;
27316
27301
  }
27317
- }
27318
- function normalizePatternForPortableEngine(pattern) {
27319
- let normalized = "";
27320
- let inCharacterClass = false;
27321
- for (let i = 0;i < pattern.length; i++) {
27322
- const char = pattern[i];
27323
- if (char === "\\") {
27324
- const next = pattern[i + 1];
27325
- if (inCharacterClass && next === "b") {
27326
- normalized += "\\x08";
27327
- i++;
27328
- continue;
27329
- }
27330
- normalized += char;
27331
- if (next !== undefined) {
27332
- normalized += next;
27333
- i++;
27302
+ if (op.operation === "add" && !op.name) {
27303
+ errors.push({
27304
+ code: "VALIDATION_ERROR",
27305
+ operationIndex,
27306
+ message: COLLECTION_CREATE_REQUIRES_NAME_MESSAGE
27307
+ });
27308
+ }
27309
+ if (!op.type || !collectionTypes.includes(op.type)) {
27310
+ errors.push({
27311
+ code: "VALIDATION_ERROR",
27312
+ operationIndex,
27313
+ message: `Collection "type" is invalid. Use one of: ${canonicalCollectionTypes.join(", ")}. Got: "${op.type ?? ""}"`
27314
+ });
27315
+ }
27316
+ if (!op.members || !Array.isArray(op.members)) {
27317
+ errors.push({
27318
+ code: "VALIDATION_ERROR",
27319
+ operationIndex,
27320
+ message: 'Collection requires a "members" array'
27321
+ });
27322
+ } else {
27323
+ for (let i = 0;i < op.members.length; i++) {
27324
+ if (typeof op.members[i] !== "string") {
27325
+ errors.push({
27326
+ code: "VALIDATION_ERROR",
27327
+ operationIndex,
27328
+ message: `Collection member at index ${i} must be a string`
27329
+ });
27334
27330
  }
27335
- continue;
27336
27331
  }
27337
- if (char === "[") {
27338
- inCharacterClass = true;
27339
- } else if (char === "]") {
27340
- inCharacterClass = false;
27332
+ }
27333
+ if (op.type && op.members) {
27334
+ const arityError = collectionArityError(op.type, op.members);
27335
+ if (arityError) {
27336
+ errors.push({
27337
+ code: "VALIDATION_ERROR",
27338
+ operationIndex,
27339
+ message: arityError
27340
+ });
27341
27341
  }
27342
- normalized += char;
27343
27342
  }
27344
- return normalized;
27343
+ return errors;
27345
27344
  }
27346
- function compilePortablePattern(pattern) {
27347
- try {
27348
- return RE2JS.compile(normalizePatternForPortableEngine(pattern));
27349
- } catch {
27350
- return;
27345
+ function collectionArityError(tag, members) {
27346
+ switch (tag) {
27347
+ case "arc":
27348
+ return members.length !== 2 ? `Arc requires exactly 2 members, got ${members.length}` : null;
27349
+ case "bond":
27350
+ return members.length !== 2 ? `Bond requires exactly 2 members, got ${members.length}` : null;
27351
+ case "pair":
27352
+ return members.length !== 2 ? `Pair requires exactly 2 members, got ${members.length}` : null;
27353
+ case "set":
27354
+ case "list":
27355
+ return members.length < 1 ? `${tag === "set" ? "Set" : "List"} requires at least 1 member, got 0` : null;
27351
27356
  }
27352
27357
  }
27353
- function unsupportedPortablePatternReason(pattern) {
27354
- return compilePortablePattern(pattern) ? undefined : UNSUPPORTED_REGEX_SYNTAX_REASON;
27358
+ // ../../packages/rules/src/preflight.ts
27359
+ function preflightOpDiagnostics2(op, operationIndex) {
27360
+ return preflightOpDiagnostics(op, operationIndex);
27355
27361
  }
27356
- function normalizeOptionalTypeSpec(spec) {
27357
- if (typeof spec === "string" && spec.endsWith("?")) {
27358
- return { spec: spec.slice(0, -1), optionalByType: true };
27359
- }
27360
- if (isTypeSpecObject(spec) && typeof spec.type === "string" && spec.type.endsWith("?")) {
27361
- return {
27362
- spec: { ...spec, type: spec.type.slice(0, -1) },
27363
- optionalByType: true
27364
- };
27365
- }
27366
- return { spec, optionalByType: false };
27362
+ function preflightCommitDiagnostics2(operations, options) {
27363
+ return preflightCommitDiagnostics(operations, options);
27364
+ }
27365
+ // ../../packages/rules/src/read-limits.ts
27366
+ var MAX_GET_MANY_WREFS = 500;
27367
+ // ../../packages/rules/src/reserved-orgs.ts
27368
+ var RESERVED_RAW_CONTENT_TOP_LEVEL_NAMES = [
27369
+ "_app",
27370
+ "_static",
27371
+ "api",
27372
+ "health",
27373
+ "healthz",
27374
+ "mcp",
27375
+ "readyz",
27376
+ "robots.txt",
27377
+ "sse",
27378
+ "trpc",
27379
+ "version"
27380
+ ];
27381
+ var RESERVED_ORG_NAMES = [
27382
+ ...RESERVED_RAW_CONTENT_TOP_LEVEL_NAMES,
27383
+ "admin",
27384
+ "billing",
27385
+ "blog",
27386
+ "docs",
27387
+ "help",
27388
+ "login",
27389
+ "public",
27390
+ "settings",
27391
+ "signup",
27392
+ "status",
27393
+ "support",
27394
+ "system",
27395
+ "warmhub",
27396
+ "www"
27397
+ ];
27398
+ var RESERVED_ORG_NAME_SET = new Set(RESERVED_ORG_NAMES);
27399
+ // ../../packages/rules/src/shape-field-key.ts
27400
+ function foldFieldName(name) {
27401
+ const stripped = name.endsWith("?") ? name.slice(0, -1) : name;
27402
+ return stripped.toLowerCase();
27403
+ }
27404
+ function foldFieldPath(path) {
27405
+ return path.split(".").map((segment) => foldFieldName(segment)).join(".");
27367
27406
  }
27368
-
27369
27407
  // ../../packages/rules/src/shape-validation-runtime.ts
27370
27408
  function validatePersistedStringFieldLimits(value, typeDef, errors, path) {
27371
27409
  const normalized = normalizeOptionalTypeSpec(typeDef).spec;
@@ -27379,8 +27417,9 @@ function validatePersistedStringFieldLimits(value, typeDef, errors, path) {
27379
27417
  }
27380
27418
  if (Array.isArray(value)) {
27381
27419
  const elementType = arrayElementType(normalized);
27382
- if (elementType === undefined && !isDeclaredArrayType(normalized))
27420
+ if (normalized !== undefined && elementType === undefined && !isDeclaredArrayType(normalized)) {
27383
27421
  return;
27422
+ }
27384
27423
  for (let i = 0;i < value.length; i++) {
27385
27424
  validatePersistedStringFieldLimits(value[i], elementType, errors, `${path ?? "<value>"}[${i}]`);
27386
27425
  }
@@ -27392,7 +27431,9 @@ function validatePersistedStringFieldLimits(value, typeDef, errors, path) {
27392
27431
  if (normalized !== undefined && fields === undefined)
27393
27432
  return;
27394
27433
  for (const [key, nestedValue] of Object.entries(value)) {
27395
- validatePersistedStringFieldLimits(nestedValue, fields?.get(key), errors, path ? joinFieldPath(path, key) : escapeFieldNameForDisplay(key));
27434
+ const keyPath = path ? joinFieldPath(path, key) : escapeFieldNameForDisplay(key);
27435
+ assertContentFieldWithinLimit(keyPath, key, errors);
27436
+ validatePersistedStringFieldLimits(nestedValue, fields?.get(key), errors, keyPath);
27396
27437
  }
27397
27438
  }
27398
27439
  function isDeclaredStringType(typeDef) {
@@ -28436,7 +28477,7 @@ function dedupeDeprecationsByShape(results) {
28436
28477
  // ../../packages/sdk-ts/package.json
28437
28478
  var package_default = {
28438
28479
  name: "@warmhub/sdk-ts",
28439
- version: "0.77.0",
28480
+ version: "0.78.0",
28440
28481
  private: false,
28441
28482
  type: "module",
28442
28483
  description: "The TypeScript SDK for WarmHub — create repos, commit and query data, and compound knowledge with your AI agents.",
@@ -29904,6 +29945,13 @@ class WarmHubClient {
29904
29945
  throw toWarmHubError(error);
29905
29946
  }
29906
29947
  },
29948
+ latestRuns: async (orgName, repoName) => {
29949
+ try {
29950
+ return await this.trpc.action.latestRuns.query({ orgName, repoName });
29951
+ } catch (error) {
29952
+ throw toWarmHubError(error);
29953
+ }
29954
+ },
29907
29955
  runStats: async (orgName, repoName, opts) => {
29908
29956
  try {
29909
29957
  return await this.trpc.action.runStats.query({
@@ -48924,7 +48972,7 @@ function resolveLogLevel(flagLevel, env) {
48924
48972
  // package.json
48925
48973
  var package_default3 = {
48926
48974
  name: "@warmhub/cli",
48927
- version: "0.79.0",
48975
+ version: "0.80.0",
48928
48976
  private: false,
48929
48977
  type: "module",
48930
48978
  description: "The wh CLI for WarmHub — create repos, commit and query data, and compound knowledge with your AI agents.",
@@ -49541,5 +49589,5 @@ process.exitCode = interceptedExitCode === undefined ? await runPreparedCli(laun
49541
49589
  version: package_default3.version
49542
49590
  }) : interceptedExitCode;
49543
49591
 
49544
- //# debugId=1F88E14E37EC2F1964756E2164756E21
49545
- //# warmhub-cli-build-info {"cliVersion":"0.79.0","sdkVersion":"0.77.0"}
49592
+ //# debugId=3EAE1910B1B57D6664756E2164756E21
49593
+ //# warmhub-cli-build-info {"cliVersion":"0.80.0","sdkVersion":"0.78.0"}