@warmhub/cli 0.116.0 → 0.118.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 +509 -122
  2. package/package.json +1 -1
package/dist/wh.js CHANGED
@@ -18071,6 +18071,8 @@ function manifestShapeData(shape) {
18071
18071
  const data = { fields: shape.fields };
18072
18072
  if (shape.description !== undefined)
18073
18073
  data.description = shape.description;
18074
+ if (shape.composes !== undefined)
18075
+ data.composes = shape.composes;
18074
18076
  return data;
18075
18077
  }
18076
18078
  function shapeDataEquals(left, right) {
@@ -18576,8 +18578,9 @@ function optionalStringArray(obj, field, path, errors) {
18576
18578
  return;
18577
18579
  }
18578
18580
  for (let i = 0;i < obj[field].length; i++) {
18579
- if (typeof obj[field][i] !== "string") {
18580
- errors.push(`${path}.${field}[${i}] must be a string`);
18581
+ const entry = obj[field][i];
18582
+ if (typeof entry !== "string" || entry.length === 0) {
18583
+ errors.push(`${path}.${field}[${i}] must be a non-empty string`);
18581
18584
  }
18582
18585
  }
18583
18586
  }
@@ -18602,6 +18605,7 @@ var ALLOWED_SHAPE_KEYS = new Set([
18602
18605
  "name",
18603
18606
  "description",
18604
18607
  "fields",
18608
+ "composes",
18605
18609
  "provisioning"
18606
18610
  ]);
18607
18611
  var VALID_PROVISIONING_VALUES = new Set(["manifest", "setup"]);
@@ -18648,6 +18652,9 @@ function validateShape(shape, i, errors) {
18648
18652
  if (!isObject(shape.fields)) {
18649
18653
  errors.push(`${path}.fields must be an object`);
18650
18654
  }
18655
+ if ("composes" in shape) {
18656
+ optionalStringArray(shape, "composes", path, errors);
18657
+ }
18651
18658
  validateProvisioning(shape, path, errors);
18652
18659
  }
18653
18660
  function validateCredential(cred, i, errors) {
@@ -34441,6 +34448,30 @@ var BASE_PRIMITIVE_TYPES = [
34441
34448
  "wref",
34442
34449
  "array"
34443
34450
  ];
34451
+ var WREF_BINDING_MODES = ["identity", "versioned", "either"];
34452
+ var WREF_BINDING_MODES_DIAGNOSTIC = `${WREF_BINDING_MODES.slice(0, -1).join(", ")}, or ${WREF_BINDING_MODES.at(-1)}`;
34453
+ var WREF_BINDING_MODE_SET = new Set(WREF_BINDING_MODES);
34454
+ function isWrefBindingMode(value) {
34455
+ return typeof value === "string" && WREF_BINDING_MODE_SET.has(value);
34456
+ }
34457
+ function wrefBindingConstraintError(path, spec) {
34458
+ if (!("binding" in spec) || !("type" in spec))
34459
+ return null;
34460
+ if (typeof spec.type !== "string" || !VALID_PRIMITIVE_TYPES.has(spec.type)) {
34461
+ return null;
34462
+ }
34463
+ if (typeof spec.binding === "string" && VALID_PRIMITIVE_TYPES.has(spec.binding)) {
34464
+ return null;
34465
+ }
34466
+ const type = spec.type.endsWith("?") ? spec.type.slice(0, -1) : spec.type;
34467
+ if (type !== "wref") {
34468
+ return `Constraint "binding" at "${path}" is only valid for type "wref"`;
34469
+ }
34470
+ if (!isWrefBindingMode(spec.binding)) {
34471
+ return `"binding" at "${path}" must be ${WREF_BINDING_MODES_DIAGNOSTIC}`;
34472
+ }
34473
+ return null;
34474
+ }
34444
34475
  var BASE_PRIMITIVE_TYPE_SET = new Set(BASE_PRIMITIVE_TYPES);
34445
34476
  var VALID_PRIMITIVE_TYPES = new Set([
34446
34477
  ...BASE_PRIMITIVE_TYPES,
@@ -34456,7 +34487,7 @@ var STRING_CONSTRAINT_KEYS = new Set([
34456
34487
  "enum"
34457
34488
  ]);
34458
34489
  var NUMBER_CONSTRAINT_KEYS = new Set(["minimum", "maximum", "integer"]);
34459
- var WREF_CONSTRAINT_KEYS = new Set(["shape"]);
34490
+ var WREF_CONSTRAINT_KEYS = new Set(["shape", "binding"]);
34460
34491
  var ARRAY_CONSTRAINT_KEYS = new Set(["items", "minItems", "maxItems"]);
34461
34492
  var COMMON_TYPESPEC_KEYS = new Set(["type", "description"]);
34462
34493
  var VALID_TYPESPEC_KEYS = new Set([
@@ -34502,6 +34533,8 @@ function isTypeSpecObject(value) {
34502
34533
  return false;
34503
34534
  if ("shape" in value && typeof value.shape !== "string")
34504
34535
  return false;
34536
+ if ("binding" in value && !isWrefBindingMode(value.binding))
34537
+ return false;
34505
34538
  if ("shape" in value && typeof value.shape === "string" && VALID_PRIMITIVE_TYPES.has(value.shape)) {
34506
34539
  if (baseType !== "wref")
34507
34540
  return false;
@@ -34572,7 +34605,8 @@ function formatTypeSpecDisplay(spec) {
34572
34605
  const typeName = isOptional ? baseType.slice(0, -1) : baseType;
34573
34606
  const suffix = isOptional ? "?" : "";
34574
34607
  if (typeName === "wref" && typeof spec.shape === "string") {
34575
- return `wref${suffix}<${spec.shape}>`;
34608
+ const typed = `wref${suffix}<${spec.shape}>`;
34609
+ return isWrefBindingMode(spec.binding) ? `${typed} (binding: ${spec.binding})` : typed;
34576
34610
  }
34577
34611
  if (typeName === "array" && "items" in spec) {
34578
34612
  const elementDisplay = displayFieldType(spec.items);
@@ -41201,6 +41235,11 @@ function validateTypeSpec(path, identityPath, spec, errors3, context) {
41201
41235
  return;
41202
41236
  }
41203
41237
  if (isPlainObject2(spec)) {
41238
+ const bindingError = wrefBindingConstraintError(path, spec);
41239
+ if (bindingError) {
41240
+ errors3.push(bindingError);
41241
+ return;
41242
+ }
41204
41243
  if (isTypeSpecObject(spec)) {
41205
41244
  validateTypedFieldObject(path, identityPath, spec, errors3, context);
41206
41245
  return;
@@ -41398,7 +41437,7 @@ function validationContext(options = {}) {
41398
41437
  function isAllowedLegacyUnsafeFieldPath2(context, path) {
41399
41438
  return context.allowUnsafeFieldNamePaths.has(path);
41400
41439
  }
41401
- var ALLOWED_SHAPE_KEYS2 = new Set(["fields", "description"]);
41440
+ var ALLOWED_SHAPE_KEYS2 = new Set(["fields", "description", "composes"]);
41402
41441
  function collectIndexableShapeFieldPaths(fields, prefix = "") {
41403
41442
  const paths = [];
41404
41443
  for (const [key, value] of Object.entries(fields)) {
@@ -41546,6 +41585,11 @@ function validateShapeDefinition(data, options = {}) {
41546
41585
  if ("description" in obj && typeof obj.description !== "string") {
41547
41586
  errors3.push('"description" must be a string');
41548
41587
  }
41588
+ if ("composes" in obj) {
41589
+ if (!Array.isArray(obj.composes) || !obj.composes.every((value) => typeof value === "string" && value.length > 0)) {
41590
+ errors3.push('"composes" must be an array of non-empty Shape wrefs');
41591
+ }
41592
+ }
41549
41593
  validatePersistedContentLimits(obj, [], errors3);
41550
41594
  if (errors3.length > 0) {
41551
41595
  return { valid: false, errors: errors3 };
@@ -41596,10 +41640,17 @@ var SYSTEM_COMPONENT = {
41596
41640
  name: SYSTEM_MANIFEST.component.name,
41597
41641
  version: SYSTEM_MANIFEST.component.version,
41598
41642
  manifest: SYSTEM_MANIFEST,
41599
- installInfra: true,
41600
41643
  shapes: [
41601
- { name: "ComponentInstall", fields: COMPONENT_INSTALL_FIELDS },
41602
- { name: "ComponentConfig", fields: COMPONENT_CONFIG_FIELDS }
41644
+ {
41645
+ name: "ComponentInstall",
41646
+ fields: COMPONENT_INSTALL_FIELDS,
41647
+ installInfra: true
41648
+ },
41649
+ {
41650
+ name: "ComponentConfig",
41651
+ fields: COMPONENT_CONFIG_FIELDS,
41652
+ installInfra: true
41653
+ }
41603
41654
  ]
41604
41655
  };
41605
41656
 
@@ -41607,7 +41658,7 @@ var SYSTEM_COMPONENT = {
41607
41658
  var SYSTEM_COMPONENTS = [
41608
41659
  SYSTEM_COMPONENT
41609
41660
  ];
41610
- var SYSTEM_INFRA_SHAPE_NAMES = new Set(SYSTEM_COMPONENTS.filter((entry) => entry.installInfra === true).flatMap((entry) => entry.shapes.map((s) => s.name)));
41661
+ var SYSTEM_INFRA_SHAPE_NAMES = new Set(SYSTEM_COMPONENTS.flatMap((entry) => entry.shapes.filter((shape) => shape.installInfra === true).map((shape) => shape.name)));
41611
41662
  function findSystemComponent(componentId) {
41612
41663
  return SYSTEM_COMPONENTS.find((entry) => entry.componentId === componentId);
41613
41664
  }
@@ -45261,7 +45312,7 @@ function createStreamingSubmissionHandle(input, deps) {
45261
45312
  // ../../packages/sdk-ts/package.json
45262
45313
  var package_default = {
45263
45314
  name: "@warmhub/sdk-ts",
45264
- version: "0.114.0",
45315
+ version: "0.116.0",
45265
45316
  private: false,
45266
45317
  type: "module",
45267
45318
  description: "The TypeScript SDK for WarmHub — create repos, commit and query data, and compound knowledge with your AI agents.",
@@ -46674,6 +46725,30 @@ class WarmHubClient {
46674
46725
  } catch (error51) {
46675
46726
  throw toWarmHubError(error51);
46676
46727
  }
46728
+ },
46729
+ pin: async (orgName, repoName, shape, fieldPath) => {
46730
+ try {
46731
+ return await this.trpc.repo.index.pin.mutate({
46732
+ orgName,
46733
+ repoName,
46734
+ shape,
46735
+ fieldPath
46736
+ });
46737
+ } catch (error51) {
46738
+ throw toWarmHubError(error51);
46739
+ }
46740
+ },
46741
+ unpin: async (orgName, repoName, shape, fieldPath) => {
46742
+ try {
46743
+ return await this.trpc.repo.index.unpin.mutate({
46744
+ orgName,
46745
+ repoName,
46746
+ shape,
46747
+ fieldPath
46748
+ });
46749
+ } catch (error51) {
46750
+ throw toWarmHubError(error51);
46751
+ }
46677
46752
  }
46678
46753
  }
46679
46754
  };
@@ -46707,7 +46782,8 @@ class WarmHubClient {
46707
46782
  create: async (orgName, repoName, shapeName, fields, opts) => {
46708
46783
  const preflight = shapeDefinitionPreflightError(shapeName, {
46709
46784
  fields,
46710
- ...opts.description !== undefined ? { description: opts.description } : {}
46785
+ ...opts.description !== undefined ? { description: opts.description } : {},
46786
+ ...opts.composes !== undefined ? { composes: opts.composes } : {}
46711
46787
  }, "add");
46712
46788
  if (preflight)
46713
46789
  throw new WarmHubError("VALIDATION_ERROR", preflight);
@@ -46718,7 +46794,8 @@ class WarmHubClient {
46718
46794
  shapeName,
46719
46795
  fields,
46720
46796
  eventRequestId: opts.eventRequestId,
46721
- description: opts.description
46797
+ description: opts.description,
46798
+ composes: opts.composes
46722
46799
  });
46723
46800
  } catch (error51) {
46724
46801
  throw toWarmHubError(error51);
@@ -46727,7 +46804,8 @@ class WarmHubClient {
46727
46804
  revise: async (orgName, repoName, shapeName, newFields, opts) => {
46728
46805
  const preflight = shapeDefinitionPreflightError(shapeName, {
46729
46806
  fields: newFields,
46730
- ...opts.description !== undefined ? { description: opts.description } : {}
46807
+ ...opts.description !== undefined ? { description: opts.description } : {},
46808
+ ...opts.composes !== undefined ? { composes: opts.composes } : {}
46731
46809
  }, "revise");
46732
46810
  if (preflight)
46733
46811
  throw new WarmHubError("VALIDATION_ERROR", preflight);
@@ -46738,7 +46816,8 @@ class WarmHubClient {
46738
46816
  shapeName,
46739
46817
  newFields,
46740
46818
  eventRequestId: opts.eventRequestId,
46741
- description: opts.description
46819
+ description: opts.description,
46820
+ composes: opts.composes
46742
46821
  });
46743
46822
  } catch (error51) {
46744
46823
  throw toWarmHubError(error51);
@@ -47208,6 +47287,8 @@ class WarmHubClient {
47208
47287
  orgName,
47209
47288
  repoName,
47210
47289
  shape: opts?.shape,
47290
+ declaredShape: opts?.declaredShape,
47291
+ includeValidatedShapes: opts?.includeValidatedShapes,
47211
47292
  kind: narrowKind(opts?.kind),
47212
47293
  match: opts?.match,
47213
47294
  dataMode: opts?.dataMode,
@@ -47371,6 +47452,7 @@ class WarmHubClient {
47371
47452
  repoName,
47372
47453
  wref: opts.wref,
47373
47454
  shape: opts.shape,
47455
+ declaredShape: opts.declaredShape,
47374
47456
  about: opts.about,
47375
47457
  includeRetracted: opts.includeRetracted,
47376
47458
  resolveCollections: opts.resolveCollections,
@@ -47447,6 +47529,8 @@ class WarmHubClient {
47447
47529
  orgName,
47448
47530
  repoName,
47449
47531
  shape: opts?.shape,
47532
+ declaredShape: opts?.declaredShape,
47533
+ includeValidatedShapes: opts?.includeValidatedShapes,
47450
47534
  about: opts?.about,
47451
47535
  affirmedAbout: opts?.affirmedAbout,
47452
47536
  kind: narrowKind(opts?.kind),
@@ -47522,6 +47606,7 @@ class WarmHubClient {
47522
47606
  orgName,
47523
47607
  repoName,
47524
47608
  shape: opts?.shape,
47609
+ declaredShape: opts?.declaredShape,
47525
47610
  about: opts?.about,
47526
47611
  affirmedAbout: opts?.affirmedAbout,
47527
47612
  kind: narrowKind(opts?.kind),
@@ -47546,6 +47631,7 @@ class WarmHubClient {
47546
47631
  wref,
47547
47632
  direction: opts?.direction,
47548
47633
  fieldPath: opts?.fieldPath,
47634
+ binding: opts?.binding,
47549
47635
  limit: opts?.limit,
47550
47636
  cursor: opts?.cursor
47551
47637
  });
@@ -47565,6 +47651,8 @@ class WarmHubClient {
47565
47651
  thingHead: async (orgName, repoName, opts, onUpdate) => {
47566
47652
  return this.watchRepoQuery(orgName, repoName, opts?.signal, () => this.thing.head(orgName, repoName, {
47567
47653
  shape: opts?.shape,
47654
+ declaredShape: opts?.declaredShape,
47655
+ includeValidatedShapes: opts?.includeValidatedShapes,
47568
47656
  kind: opts?.kind,
47569
47657
  match: opts?.match,
47570
47658
  dataMode: opts?.dataMode,
@@ -47577,6 +47665,11 @@ class WarmHubClient {
47577
47665
  thingHistory: async (orgName, repoName, opts, onUpdate) => {
47578
47666
  return this.watchRepoQuery(orgName, repoName, opts.signal, () => this.thing.history(orgName, repoName, {
47579
47667
  wref: opts.wref,
47668
+ shape: opts.shape,
47669
+ declaredShape: opts.declaredShape,
47670
+ about: opts.about,
47671
+ resolveCollections: opts.resolveCollections,
47672
+ match: opts.match,
47580
47673
  limit: opts.limit,
47581
47674
  cursor: opts.cursor,
47582
47675
  includeRetracted: opts.includeRetracted
@@ -48440,6 +48533,12 @@ function generateSuggestions(code, message, context, errorCode) {
48440
48533
  }
48441
48534
  }
48442
48535
  if (code === "FIELD_NOT_INDEXABLE") {
48536
+ if (message.includes("field-not-declared")) {
48537
+ suggestions.push({
48538
+ action: "Declare the field path for indexing, then retry",
48539
+ command: "wh repo index pin <Shape> <field.path>"
48540
+ });
48541
+ }
48443
48542
  suggestions.push({
48444
48543
  action: "Inspect indexed field state for the repo",
48445
48544
  command: "wh repo describe --indexed-fields"
@@ -50679,6 +50778,8 @@ async function checkCompatibility(ctx, domainPath, canonicalVerb, args) {
50679
50778
  if (clientFlags.length > 0)
50680
50779
  capabilities = await probeCapabilities(ctx);
50681
50780
  }
50781
+ if (capabilities)
50782
+ ctx.capabilities = capabilities;
50682
50783
  if (clientFlags.length === 0 || !capabilities)
50683
50784
  return;
50684
50785
  const echoed = capabilities.honoredClientFlags;
@@ -52116,6 +52217,9 @@ function renderWarningLine(out, c, chars, op) {
52116
52217
  return;
52117
52218
  renderUndeclaredFieldsWarning(out, c, chars, op.name, warnings);
52118
52219
  renderCoalescedWrefsWarning(out, c, chars, warnings);
52220
+ for (const entry of warnings.ignoredVersionPins ?? []) {
52221
+ out(` ${c.yellow}${chars.warn}${c.reset} ignored version pin ${escapeInlineTerminalText(entry.fieldPath)}: ${c.dim}${escapeInlineTerminalText(entry.wref)}${c.reset} (field binding is ${escapeInlineTerminalText(entry.binding)}; the reference follows the Thing)`);
52222
+ }
52119
52223
  for (const warning of warnings.deprecations ?? []) {
52120
52224
  out(` ${c.yellow}${chars.warn}${c.reset} ${escapeInlineTerminalText(warning.shape)} deprecated (de-emphasis milestone ${escapeInlineTerminalText(warning.removalMilestone)}): ${escapeInlineTerminalText(warning.message)}`);
52121
52225
  }
@@ -52236,7 +52340,7 @@ function emitPartialPageHint(ctx, count, _nextCursor, _limit) {
52236
52340
  }
52237
52341
 
52238
52342
  // ../../packages/warmhub-cli/src/domains/commit-output-contract-id.ts
52239
- var COMMIT_SUBMIT_OUTPUT_SCHEMA_ID = "wh.commit.submit.result/v0.3";
52343
+ var COMMIT_SUBMIT_OUTPUT_SCHEMA_ID = "wh.commit.submit.result/v0.4";
52240
52344
  function identifyCommitSubmitOutput(value) {
52241
52345
  if ("schema" in value) {
52242
52346
  if (value.schema === COMMIT_SUBMIT_OUTPUT_SCHEMA_ID) {
@@ -52953,6 +53057,9 @@ var handleCreate2 = async (ctx, { flags, args }) => {
52953
53057
  };
52954
53058
 
52955
53059
  // ../../packages/warmhub-cli/src/domains/thing/render.ts
53060
+ function singularShapeName(result) {
53061
+ return result.shapeName ?? result.shape;
53062
+ }
52956
53063
  function renderHead(out, c, chars, result, org, repo, shape, kind) {
52957
53064
  const items = result.items ?? [];
52958
53065
  const decorations = getResponseDecorations(result);
@@ -52968,6 +53075,12 @@ function renderHead(out, c, chars, result, org, repo, shape, kind) {
52968
53075
  const kl = kindLabel(c, effectiveKind(item.kind ?? "thing", shapeName));
52969
53076
  const retractedTag = item.active === false ? ` ${c.red}[RETRACTED]${c.reset}` : "";
52970
53077
  out(` ${wref} ${kl}${retractedTag}`);
53078
+ if (item.declaredShapes?.length) {
53079
+ out(` ${c.dim}declares:${c.reset} ${refList(c, item.declaredShapes, decorations)}`);
53080
+ }
53081
+ if (item.validatedShapes?.length) {
53082
+ out(` ${c.dim}validates:${c.reset} ${refList(c, item.validatedShapes, decorations)}`);
53083
+ }
52971
53084
  if (item.kind === "assertion" && item.aboutWref) {
52972
53085
  out(` ${c.dim}about:${c.reset} ${refDisplay(c, item.aboutWref, decorations)}`);
52973
53086
  }
@@ -52991,19 +53104,26 @@ function renderHead(out, c, chars, result, org, repo, shape, kind) {
52991
53104
  function renderThing(out, c, result) {
52992
53105
  const decorations = getResponseDecorations(result);
52993
53106
  const wref = result.wref ?? result.name ?? "(unknown)";
52994
- const shapeName = result.shapeName ?? result.shape;
53107
+ const shapeName = singularShapeName(result);
52995
53108
  const displayKind = effectiveKind(result.kind ?? "thing", shapeName);
52996
53109
  const retractedTag = result.active === false ? ` ${c.red}[RETRACTED]${c.reset}` : "";
52997
53110
  out(`${pinnedWref(c, wref, result.version)} ${kindLabel(c, displayKind)}${retractedTag}`);
52998
53111
  out(` ${c.dim}wref:${c.reset} ${escapeTerminalTextForDisplay(wref)}`);
52999
53112
  out(` ${c.dim}version:${c.reset} ${result.version ?? "-"}`);
53000
53113
  out(` ${c.dim}active:${c.reset} ${String(result.active)}`);
53114
+ if (result.declaredShapes?.length) {
53115
+ out(` ${c.dim}declares:${c.reset} ${refList(c, result.declaredShapes, decorations)}`);
53116
+ }
53117
+ if (result.validatedShapes?.length) {
53118
+ out(` ${c.dim}validates:${c.reset} ${refList(c, result.validatedShapes, decorations)}`);
53119
+ }
53001
53120
  if (result.committerWref) {
53002
53121
  out(` ${c.dim}by:${c.reset} ${refDisplay(c, result.committerWref, decorations)}`);
53003
53122
  }
53004
53123
  const aboutWref = result.aboutWref ?? result.about;
53005
- if (aboutWref) {
53006
- out(` ${c.dim}about:${c.reset} ${decoratedRef(c, String(aboutWref), decorations) ?? escapeTerminalTextForDisplay(String(aboutWref))}`);
53124
+ const aboutText = typeof aboutWref === "string" ? aboutWref : JSON.stringify(aboutWref);
53125
+ if (aboutText) {
53126
+ out(` ${c.dim}about:${c.reset} ${decoratedRef(c, aboutText, decorations) ?? escapeTerminalTextForDisplay(aboutText)}`);
53007
53127
  }
53008
53128
  if (result.affirmedWrefs?.length) {
53009
53129
  out(` ${c.dim}affirms:${c.reset} ${refList(c, result.affirmedWrefs, decorations)}`);
@@ -53074,9 +53194,9 @@ function renderGraphValue(out, c, value, indent, decorations) {
53074
53194
  }
53075
53195
  renderGraphNode(out, c, value, indent, decorations);
53076
53196
  }
53077
- function renderGraphNode(out, c, result, indent = "", decorations = undefined) {
53197
+ function renderGraphNode(out, c, result, indent = "", decorations) {
53078
53198
  const wref = result.wref ?? result.name ?? "(unknown)";
53079
- const shapeName = result.shapeName ?? result.shape;
53199
+ const shapeName = singularShapeName(result);
53080
53200
  const displayKind = effectiveKind(result.kind ?? "thing", shapeName);
53081
53201
  out(`${indent}${pinnedWref(c, wref, result.version)} ${kindLabel(c, displayKind)}`);
53082
53202
  if (result.about) {
@@ -53144,6 +53264,12 @@ function renderHistory(out, c, result) {
53144
53264
  const createdOn = ver.metadata?.createdOn;
53145
53265
  const thingCreatedStr = createdOn ? ` ${c.dim}born:${formatTime(createdOn, now)}${c.reset}` : "";
53146
53266
  out(` ${wrefStr} ${op} ${c.dim}${time3}${c.reset}${by}${thingCreatedStr}`);
53267
+ if (ver.declaredShapes?.length) {
53268
+ out(` ${c.dim}declares:${c.reset} ${refList(c, ver.declaredShapes, decorations)}`);
53269
+ }
53270
+ if (ver.validatedShapes?.length) {
53271
+ out(` ${c.dim}validates:${c.reset} ${refList(c, ver.validatedShapes, decorations)}`);
53272
+ }
53147
53273
  const affirmed = ver.affirmedWrefs;
53148
53274
  if (Array.isArray(affirmed) && affirmed.length > 0) {
53149
53275
  out(` ${c.dim}affirms:${c.reset} ${refList(c, affirmed.map(String), decorations)}`);
@@ -53164,7 +53290,8 @@ function renderRefs(out, c, result, wref, direction) {
53164
53290
  const refWref = refDisplay(c, item.wref, decorations, item.version);
53165
53291
  const kl = kindLabel(c, effectiveKind(item.kind ?? "thing", item.shapeName));
53166
53292
  const field = `${c.dim}via ${c.reset}${escapeTerminalTextForDisplay(item.fieldPath ?? "(unknown)")}`;
53167
- out(` ${refWref} ${kl} ${field}`);
53293
+ const binding = item.binding ? ` ${c.dim}${item.binding}${c.reset}` : "";
53294
+ out(` ${refWref} ${kl} ${field}${binding}`);
53168
53295
  }
53169
53296
  out(`${c.dim}${items.length} ref(s)${c.reset}`);
53170
53297
  }
@@ -53240,6 +53367,9 @@ var handleThingGraph = async (ctx, { flags, args }) => {
53240
53367
  // ../../packages/warmhub-cli/src/domains/thing/history.ts
53241
53368
  var historyFlags = {
53242
53369
  shape: flag.string({ description: "Filter by shape" }),
53370
+ "declared-shape": flag.string({
53371
+ description: "Filter by directly declared shape"
53372
+ }),
53243
53373
  limit: flag.number({
53244
53374
  description: "Maximum versions per page (default: 50, max: 500)"
53245
53375
  }),
@@ -53257,6 +53387,7 @@ var handleHistory = async (ctx, { flags, args }) => {
53257
53387
  const wref = args[0];
53258
53388
  const { org, repo } = wref !== undefined && looksLikeDurableId(wref) ? parseOrgRepoOptional(getRepoRef(ctx), ctx.config) : parseOrgRepo(getRepoRef(ctx), ctx.config);
53259
53389
  const shape = flags.shape;
53390
+ const declaredShape = flags["declared-shape"];
53260
53391
  const about = flags.about;
53261
53392
  const limit = flags.limit;
53262
53393
  const cursor = flags.cursor;
@@ -53274,6 +53405,7 @@ var handleHistory = async (ctx, { flags, args }) => {
53274
53405
  const historyOpts = {
53275
53406
  wref,
53276
53407
  shape,
53408
+ declaredShape,
53277
53409
  about,
53278
53410
  includeRetracted,
53279
53411
  resolveCollections,
@@ -53300,23 +53432,28 @@ var handleHistory = async (ctx, { flags, args }) => {
53300
53432
  });
53301
53433
  return;
53302
53434
  }
53303
- const result = all ? await fetchAllHistoryPages(ctx, org, repo, {
53435
+ const fetched = all ? await fetchAllHistoryPages(ctx, org, repo, {
53304
53436
  wref,
53305
53437
  shape,
53438
+ declaredShape,
53306
53439
  about,
53307
53440
  includeRetracted,
53308
53441
  resolveCollections,
53309
53442
  limit: pageLimit,
53310
53443
  cursor
53311
- }) : await ctx.client.thing.history(org, repo, {
53312
- wref,
53313
- shape,
53314
- about,
53315
- includeRetracted,
53316
- resolveCollections,
53317
- limit: boundedLimit,
53318
- cursor
53319
- });
53444
+ }) : {
53445
+ result: await ctx.client.thing.history(org, repo, {
53446
+ wref,
53447
+ shape,
53448
+ declaredShape,
53449
+ about,
53450
+ includeRetracted,
53451
+ resolveCollections,
53452
+ limit: boundedLimit,
53453
+ cursor
53454
+ })
53455
+ };
53456
+ const { result, refusal } = fetched;
53320
53457
  if (!all && result.nextCursor) {
53321
53458
  emitPartialPageHint(ctx, (result.versions ?? []).length, result.nextCursor, boundedLimit);
53322
53459
  }
@@ -53325,34 +53462,48 @@ var handleHistory = async (ctx, { flags, args }) => {
53325
53462
  nextCursor: result.nextCursor ?? null,
53326
53463
  decorations: getResponseDecorations(result)
53327
53464
  }, () => renderHistory(ctx.out, ctx.colors, result));
53465
+ if (refusal) {
53466
+ ctx.err(`history stopped after ${(result.versions ?? []).length} version(s): the backend refused further refill (${refusal.code}). Narrow the filter to continue.`);
53467
+ throw refusal;
53468
+ }
53328
53469
  };
53329
53470
  async function fetchAllHistoryPages(ctx, org, repo, opts) {
53330
53471
  const versions2 = [];
53331
53472
  let decorations;
53332
53473
  let thing;
53333
- for await (const page of paginatePages2({
53334
- initialCursor: opts.cursor,
53335
- fetchPage: (cursor) => ctx.client.thing.history(org, repo, {
53336
- wref: opts.wref,
53337
- shape: opts.shape,
53338
- about: opts.about,
53339
- includeRetracted: opts.includeRetracted,
53340
- resolveCollections: opts.resolveCollections,
53341
- limit: opts.limit,
53342
- cursor
53343
- }),
53344
- title: "Thing history"
53345
- })) {
53346
- if (!thing && page.thing)
53347
- thing = page.thing;
53348
- versions2.push(...page.versions ?? []);
53349
- decorations = mergeDecorations(decorations, getResponseDecorations(page));
53474
+ let refusal;
53475
+ try {
53476
+ for await (const page of paginatePages2({
53477
+ initialCursor: opts.cursor,
53478
+ fetchPage: (cursor) => ctx.client.thing.history(org, repo, {
53479
+ wref: opts.wref,
53480
+ shape: opts.shape,
53481
+ declaredShape: opts.declaredShape,
53482
+ about: opts.about,
53483
+ includeRetracted: opts.includeRetracted,
53484
+ resolveCollections: opts.resolveCollections,
53485
+ limit: opts.limit,
53486
+ cursor
53487
+ }),
53488
+ title: "Thing history"
53489
+ })) {
53490
+ if (!thing && page.thing)
53491
+ thing = page.thing;
53492
+ versions2.push(...page.versions ?? []);
53493
+ decorations = mergeDecorations(decorations, getResponseDecorations(page));
53494
+ }
53495
+ } catch (error51) {
53496
+ if (!(isWarmHubError(error51) && error51.code === "QUERY_TOO_EXPENSIVE")) {
53497
+ throw error51;
53498
+ }
53499
+ refusal = error51;
53350
53500
  }
53351
- return withDecorations({
53501
+ const result = withDecorations({
53352
53502
  ...thing === undefined ? {} : { thing },
53353
53503
  versions: versions2,
53354
53504
  nextCursor: undefined
53355
53505
  }, decorations);
53506
+ return refusal ? { result, refusal } : { result };
53356
53507
  }
53357
53508
 
53358
53509
  // ../../packages/warmhub-cli/src/domains/thing/lease.ts
@@ -53496,6 +53647,12 @@ function coerceValue(s) {
53496
53647
  // ../../packages/warmhub-cli/src/domains/thing/list.ts
53497
53648
  var headFlags = {
53498
53649
  shape: flag.string({ description: "Filter by shape" }),
53650
+ "declared-shape": flag.string({
53651
+ description: "Filter by directly declared shape"
53652
+ }),
53653
+ "include-validated-shapes": flag.boolean({
53654
+ description: "Include the full certified shape closure"
53655
+ }),
53499
53656
  kind: flag.string({ description: "Filter by kind" }),
53500
53657
  limit: flag.number({
53501
53658
  description: "Max items per page (default: 50, max: 500)"
@@ -53524,6 +53681,8 @@ var headFlags = {
53524
53681
  var handleHead = async (ctx, { flags, args }) => {
53525
53682
  const { org, repo } = parseOrgRepo(getRepoRef(ctx) ?? args[0], ctx.config);
53526
53683
  const shape = flags.shape;
53684
+ const declaredShape = flags["declared-shape"];
53685
+ const includeValidatedShapes = flags["include-validated-shapes"];
53527
53686
  const kind = validateKind(flags.kind);
53528
53687
  const limit = flags.limit;
53529
53688
  const cursor = flags.cursor;
@@ -53538,6 +53697,9 @@ var handleHead = async (ctx, { flags, args }) => {
53538
53697
  usageError("--since-repo-seq cannot be used with --live.", "wh thing list --since-repo-seq 42 --all --format json");
53539
53698
  }
53540
53699
  if (count) {
53700
+ if (includeValidatedShapes) {
53701
+ usageError("--include-validated-shapes cannot be used with --count.", "wh thing list --declared-shape Player --count");
53702
+ }
53541
53703
  if (cursor || all || limit || ctx.liveMode) {
53542
53704
  usageError("Usage: wh thing list --count [--shape SHAPE] [--kind KIND] [--match PATTERN] [--since-repo-seq N]", "wh thing list --shape Player --count --since-repo-seq 42");
53543
53705
  }
@@ -53546,12 +53708,13 @@ var handleHead = async (ctx, { flags, args }) => {
53546
53708
  validateComponentFilters(componentRef2, strictExclude2, "wh thing list --component acme/veritas");
53547
53709
  return handleCount(ctx, org, repo, {
53548
53710
  shape,
53711
+ declaredShape,
53549
53712
  kind,
53550
53713
  match,
53551
53714
  includeRetracted,
53552
53715
  componentRef: componentRef2,
53553
53716
  excludeComponents: strictExclude2,
53554
- excludeInfraShapes: !strictExclude2 && !shape,
53717
+ excludeInfraShapes: !strictExclude2 && !shape && !declaredShape,
53555
53718
  where: where.length > 0 ? where : undefined,
53556
53719
  ...sinceRepoSeq === undefined ? {} : { sinceRepoSeq }
53557
53720
  });
@@ -53565,13 +53728,15 @@ var handleHead = async (ctx, { flags, args }) => {
53565
53728
  const boundedLimit = Math.min(limit ?? DEFAULT_PAGE_LIMIT, MAX_PAGE_LIMIT);
53566
53729
  const pageLimit = all ? Math.min(limit ?? AUTO_PAGE_LIMIT, MAX_PAGE_LIMIT) : boundedLimit;
53567
53730
  const componentRef = flags.component;
53568
- const hasShape = !!shape;
53731
+ const hasShape = !!shape || !!declaredShape;
53569
53732
  const strictExclude = !!flags["exclude-components"];
53570
53733
  validateComponentFilters(componentRef, strictExclude, "wh thing list --component acme/veritas");
53571
53734
  const excludeComponents = strictExclude;
53572
53735
  const excludeInfraShapes = !strictExclude && !hasShape;
53573
53736
  const headOpts = {
53574
53737
  shape,
53738
+ declaredShape,
53739
+ includeValidatedShapes,
53575
53740
  kind,
53576
53741
  match,
53577
53742
  includeRetracted,
@@ -53608,6 +53773,8 @@ var handleHead = async (ctx, { flags, args }) => {
53608
53773
  const streamJsonl = all && ctx.format === "jsonl";
53609
53774
  const result = all ? await fetchAllHeadPages(ctx, org, repo, {
53610
53775
  shape,
53776
+ declaredShape,
53777
+ includeValidatedShapes,
53611
53778
  kind,
53612
53779
  match,
53613
53780
  includeRetracted,
@@ -53623,6 +53790,8 @@ var handleHead = async (ctx, { flags, args }) => {
53623
53790
  return await ctx.flushOut?.() ?? true;
53624
53791
  } : undefined) : await ctx.client.thing.head(org, repo, {
53625
53792
  shape,
53793
+ declaredShape,
53794
+ includeValidatedShapes,
53626
53795
  kind,
53627
53796
  match,
53628
53797
  includeRetracted,
@@ -53652,6 +53821,8 @@ async function fetchAllHeadPages(ctx, org, repo, opts, onPage) {
53652
53821
  initialCursor: opts.cursor,
53653
53822
  fetchPage: (cursor) => ctx.client.thing.head(org, repo, {
53654
53823
  shape: opts.shape,
53824
+ declaredShape: opts.declaredShape,
53825
+ includeValidatedShapes: opts.includeValidatedShapes,
53655
53826
  kind: opts.kind,
53656
53827
  match: opts.match,
53657
53828
  includeRetracted: opts.includeRetracted,
@@ -53672,6 +53843,12 @@ async function fetchAllHeadPages(ctx, org, repo, opts, onPage) {
53672
53843
  // ../../packages/warmhub-cli/src/domains/thing/query.ts
53673
53844
  var queryFlags = {
53674
53845
  shape: flag.string({ description: "Filter by shape" }),
53846
+ "declared-shape": flag.string({
53847
+ description: "Filter by directly declared shape"
53848
+ }),
53849
+ "include-validated-shapes": flag.boolean({
53850
+ description: "Include the full certified shape closure"
53851
+ }),
53675
53852
  kind: flag.string({ description: "Filter by kind" }),
53676
53853
  about: flag.string({ description: "Filter by about wref" }),
53677
53854
  "affirmed-about": flag.string({
@@ -53710,6 +53887,8 @@ var queryFlags = {
53710
53887
  var handleQuery = async (ctx, { flags }) => {
53711
53888
  const { org, repo } = parseOrgRepo(getRepoRef(ctx), ctx.config);
53712
53889
  const shape = flags.shape;
53890
+ const declaredShape = flags["declared-shape"];
53891
+ const includeValidatedShapes = flags["include-validated-shapes"];
53713
53892
  const about = flags.about;
53714
53893
  const affirmedAbout = flags["affirmed-about"];
53715
53894
  const kind = validateKind(flags.kind);
@@ -53723,7 +53902,7 @@ var handleQuery = async (ctx, { flags }) => {
53723
53902
  const resolveCollections = flags["resolve-collections"];
53724
53903
  const role = parseCollectionRoleFlag(flags.role, "wh thing query --about Player/alice --resolve-collections --role from");
53725
53904
  const componentRef = flags.component;
53726
- const hasShape = !!shape;
53905
+ const hasShape = !!shape || !!declaredShape;
53727
53906
  const strictExclude = !!flags["exclude-components"];
53728
53907
  validateComponentFilters(componentRef, strictExclude, "wh thing query --component acme/veritas");
53729
53908
  const excludeComponents = strictExclude;
@@ -53735,11 +53914,15 @@ var handleQuery = async (ctx, { flags }) => {
53735
53914
  usageError("--since-repo-seq cannot be used with --live.", "wh thing query --since-repo-seq 42 --all --format json");
53736
53915
  }
53737
53916
  if (count) {
53917
+ if (includeValidatedShapes) {
53918
+ usageError("--include-validated-shapes cannot be used with --count.", "wh thing query --declared-shape Player --count");
53919
+ }
53738
53920
  if (cursor || all || limit || ctx.liveMode || role) {
53739
53921
  usageError("Usage: wh thing query --count [--shape SHAPE] [--about WREF] [--kind KIND] [--match PATTERN] [--since-repo-seq N]", "wh thing query --kind assertion --about Player/alice --count --since-repo-seq 42");
53740
53922
  }
53741
53923
  return handleCount(ctx, org, repo, {
53742
53924
  shape,
53925
+ declaredShape,
53743
53926
  kind,
53744
53927
  match,
53745
53928
  about,
@@ -53766,6 +53949,8 @@ var handleQuery = async (ctx, { flags }) => {
53766
53949
  const pageLimit = all ? Math.min(limit ?? AUTO_PAGE_LIMIT, MAX_PAGE_LIMIT) : boundedLimit;
53767
53950
  const queryOpts = {
53768
53951
  shape,
53952
+ declaredShape,
53953
+ includeValidatedShapes,
53769
53954
  about,
53770
53955
  affirmedAbout,
53771
53956
  kind,
@@ -53806,6 +53991,8 @@ var handleQuery = async (ctx, { flags }) => {
53806
53991
  const streamJsonl = all && ctx.format === "jsonl";
53807
53992
  const result = all ? await fetchAllQueryPages(ctx, org, repo, {
53808
53993
  shape,
53994
+ declaredShape,
53995
+ includeValidatedShapes,
53809
53996
  about,
53810
53997
  affirmedAbout,
53811
53998
  kind,
@@ -53825,6 +54012,8 @@ var handleQuery = async (ctx, { flags }) => {
53825
54012
  return await ctx.flushOut?.() ?? true;
53826
54013
  } : undefined) : await ctx.client.thing.query(org, repo, {
53827
54014
  shape,
54015
+ declaredShape,
54016
+ includeValidatedShapes,
53828
54017
  about,
53829
54018
  affirmedAbout,
53830
54019
  kind,
@@ -53858,6 +54047,8 @@ async function fetchAllQueryPages(ctx, org, repo, opts, onPage) {
53858
54047
  initialCursor: opts.cursor,
53859
54048
  fetchPage: (cursor) => ctx.client.thing.query(org, repo, {
53860
54049
  shape: opts.shape,
54050
+ declaredShape: opts.declaredShape,
54051
+ includeValidatedShapes: opts.includeValidatedShapes,
53861
54052
  about: opts.about,
53862
54053
  affirmedAbout: opts.affirmedAbout,
53863
54054
  kind: opts.kind,
@@ -53891,6 +54082,12 @@ function renderQueryResults(out, c, result) {
53891
54082
  const kl = kindLabel(c, effectiveKind(item.kind ?? "thing", shapeName));
53892
54083
  const retractedTag = item.active === false ? ` ${c.red}[RETRACTED]${c.reset}` : "";
53893
54084
  out(` ${wref} ${kl}${retractedTag}`);
54085
+ if (item.declaredShapes?.length) {
54086
+ out(` ${c.dim}declares:${c.reset} ${refList(c, item.declaredShapes, decorations)}`);
54087
+ }
54088
+ if (item.validatedShapes?.length) {
54089
+ out(` ${c.dim}validates:${c.reset} ${refList(c, item.validatedShapes, decorations)}`);
54090
+ }
53894
54091
  if (item.roles?.length) {
53895
54092
  out(` ${c.dim}roles:${c.reset} ${item.roles.join(", ")}`);
53896
54093
  }
@@ -53914,16 +54111,22 @@ var refsFlags = {
53914
54111
  description: "Show outbound refs (what this target references)"
53915
54112
  }),
53916
54113
  field: flag.string({ description: "Filter by field path (inbound only)" }),
54114
+ binding: flag.string({
54115
+ description: "Keep only edges with this binding: identity (follows the Thing) or versioned (pinned to one version)"
54116
+ }),
53917
54117
  limit: flag.number({
53918
54118
  description: "Max items per page (default: 50, max: 500)"
53919
54119
  }),
53920
54120
  cursor: flag.string({ description: "Opaque pagination cursor" }),
53921
54121
  all: flag.boolean({ description: "Fetch all pages" })
53922
54122
  };
54123
+ function isRefsBinding(value) {
54124
+ return value === "identity" || value === "versioned";
54125
+ }
53923
54126
  var handleRefs = async (ctx, { flags, args }) => {
53924
54127
  const wref = args[0];
53925
54128
  if (!wref) {
53926
- usageError("Usage: wh thing refs <wref> [--inbound|--outbound] [--field FIELD] [--limit N]", "wh thing refs Loc/player");
54129
+ usageError("Usage: wh thing refs <wref> [--inbound|--outbound] [--field FIELD] [--binding identity|versioned] [--limit N]", "wh thing refs Loc/player");
53927
54130
  }
53928
54131
  const { org, repo } = looksLikeDurableId(wref) ? parseOrgRepoOptional(getRepoRef(ctx), ctx.config) : parseOrgRepo(getRepoRef(ctx), ctx.config);
53929
54132
  if (flags.inbound && flags.outbound) {
@@ -53933,10 +54136,14 @@ var handleRefs = async (ctx, { flags, args }) => {
53933
54136
  if (direction === "outbound" && flags.field) {
53934
54137
  usageError("--field is only supported for inbound refs", "wh thing refs Loc/player --field target");
53935
54138
  }
54139
+ const binding = flags.binding;
54140
+ if (binding !== undefined && !isRefsBinding(binding)) {
54141
+ usageError("--binding must be identity or versioned", "wh thing refs Loc/player --binding identity");
54142
+ }
53936
54143
  const limit = flags.limit;
53937
54144
  const cursor = flags.cursor;
53938
54145
  const all = flags.all;
53939
- const refsQueryIsNarrowed = Boolean(flags.field || cursor);
54146
+ const refsQueryIsNarrowed = Boolean(flags.field || binding || cursor);
53940
54147
  if (cursor && !limit) {
53941
54148
  usageError("Usage: wh thing refs <wref> [--limit N] [--cursor TOKEN]", "wh thing refs Loc/player --limit 50 --cursor <token>");
53942
54149
  }
@@ -53945,6 +54152,7 @@ var handleRefs = async (ctx, { flags, args }) => {
53945
54152
  const fetchPage = async (c) => ctx.client.thing.refs(org, repo, wref, {
53946
54153
  direction,
53947
54154
  fieldPath: flags.field,
54155
+ binding,
53948
54156
  limit: pageLimit,
53949
54157
  cursor: c
53950
54158
  });
@@ -57056,7 +57264,7 @@ var createFlags3 = {
57056
57264
  };
57057
57265
 
57058
57266
  // ../../packages/warmhub-cli/src/domains/commit-stream-output-contract-id.ts
57059
- var COMMIT_SUBMIT_STREAM_ROW_SCHEMA_ID = "wh.commit.submit.stream.row/v0.2";
57267
+ var COMMIT_SUBMIT_STREAM_ROW_SCHEMA_ID = "wh.commit.submit.stream.row/v0.3";
57060
57268
  function identify(row) {
57061
57269
  if ("schema" in row) {
57062
57270
  throw new Error("Streaming submission row already defines a schema field");
@@ -61720,7 +61928,7 @@ var DOCTOR_DOMAIN = defineDomain({
61720
61928
  var createFlags5 = {
61721
61929
  key: flag.string({ description: "issuer-scoped idempotency key" }),
61722
61930
  coverage: flag.string({
61723
- description: "inline coverage JSON ({include, exclude?})"
61931
+ description: "inline coverage JSON ({paths, shapes?, shapeless?}; the field axis exists in the grammar but is not servable yet)"
61724
61932
  }),
61725
61933
  view: flag.string({
61726
61934
  description: "View backing coverage instead (View/NAME or View/NAME@vN)"
@@ -61741,7 +61949,7 @@ function repo(ctx) {
61741
61949
  return parseOrgRepo(getRepoRef(ctx), ctx.config);
61742
61950
  }
61743
61951
  var CREATE_USAGE = "Usage: wh grant create <member EMAIL | pat NAME | component ORG/NAME> --key KEY --op OP [--op OP] (--coverage JSON | --view View/NAME[@vN])";
61744
- var CREATE_EXAMPLE = `wh grant create component acme/indexer --key provision --op things:read --coverage '{"include":["Lesson/**"]}'`;
61952
+ var CREATE_EXAMPLE = `wh grant create component acme/indexer --key provision --op things:read --coverage '{"paths":{"include":["**"]},"shapes":["THING_DURABLE_ID"]}'`;
61745
61953
  function parseRecipient(kind, name) {
61746
61954
  switch (kind) {
61747
61955
  case "member":
@@ -61755,6 +61963,7 @@ function parseRecipient(kind, name) {
61755
61963
  };
61756
61964
  default:
61757
61965
  usageError("Grant recipient kind must be member, pat, or component.", CREATE_EXAMPLE);
61966
+ throw new Error("usageError must throw");
61758
61967
  }
61759
61968
  }
61760
61969
  function isPatternList(value) {
@@ -61762,12 +61971,24 @@ function isPatternList(value) {
61762
61971
  }
61763
61972
  function parseCoverage(raw) {
61764
61973
  const candidate = parseJsonObject(raw, "--coverage");
61765
- if (!isPatternList(candidate.include) || candidate.include.length === 0) {
61766
- usageError("--coverage must be an object with a non-empty include array of patterns ({include, exclude?}).", CREATE_EXAMPLE);
61974
+ const paths = candidate.paths !== null && typeof candidate.paths === "object" && !Array.isArray(candidate.paths) ? candidate.paths : candidate;
61975
+ if (!isPatternList(paths.include) || paths.include.length === 0) {
61976
+ usageError("--coverage must contain a non-empty paths.include array (terminal {paths, shapes?, shapeless?, fields?}); legacy {include, exclude?} is accepted for compatibility.", CREATE_EXAMPLE);
61767
61977
  }
61768
- if (candidate.exclude !== undefined && !isPatternList(candidate.exclude)) {
61978
+ if (paths.exclude !== undefined && !isPatternList(paths.exclude)) {
61769
61979
  usageError("--coverage exclude must be an array of patterns when present.", CREATE_EXAMPLE);
61770
61980
  }
61981
+ if ("paths" in candidate) {
61982
+ if (candidate.shapes !== undefined && !isPatternList(candidate.shapes)) {
61983
+ usageError("--coverage shapes must be an array of durable Shape ids.", CREATE_EXAMPLE);
61984
+ }
61985
+ if (candidate.fields !== undefined && !isPatternList(candidate.fields)) {
61986
+ usageError("--coverage fields must be an array of field keys.", CREATE_EXAMPLE);
61987
+ }
61988
+ if (candidate.shapeless !== undefined && typeof candidate.shapeless !== "boolean") {
61989
+ usageError("--coverage shapeless must be a boolean.", CREATE_EXAMPLE);
61990
+ }
61991
+ }
61771
61992
  return candidate;
61772
61993
  }
61773
61994
  var handleCreate4 = async (ctx, { args, flags }) => {
@@ -62715,7 +62936,7 @@ var ORG_DOMAIN = defineDomain({
62715
62936
  });
62716
62937
 
62717
62938
  // ../../packages/warmhub-cli/src/domains/prime-content.md
62718
- var prime_content_default = "# WarmHub CLI Context\n> **Context Recovery**: Run `wh prime` after compaction or new session\n\n## Environment\n{{REPO_LINE}}\n\n## Core Concepts\n- **Thing**: A named entity versioned by writes. **Assertion**: A thing that makes a shape-validated claim about another thing.\n- **Shape**: A thing defining data structure; every other thing has one. **Write**: One or more add/revise/retract operations with per-operation results.\n- **wref**: A reference to a thing. Local: `Player` (the shape) or `Player/alice` (a thing with that shape). Cross-repo: `wh:org/repo/Shape` or `wh:org/repo/Shape/name`.\n\n## Versioned Wrefs\n- `Shape` addresses the shape itself; `Shape/name` addresses a thing with that shape. `@vN` pins either.\n- Floating write refs to retracted targets fail; existing pinned versions remain valid.\n- Rename invalidates old spellings, including `@vN`; the new name resolves history.\n- Untyped wrefs accept any thing. `wref<T>` requires the target's shape to be `T`; a shape has no shape, so never satisfies it. `wref?` coalesces only `thing_absent`, never a missing shape.\n\n## Key Workflows\n\n**Write data** (discover shapes → scaffold ops → submit):\n```bash\nwh shape list --repo org/repo # list available shapes\nwh shape view ShapeName --repo org/repo # inspect fields\nwh shape template ShapeName -o ops.json --repo org/repo # scaffold write ops (supports --kind assertion)\n# edit ops.json — fill FILL_IN placeholders — then:\nwh commit submit --file ops.json --dry-run --repo org/repo # preview; remove --dry-run to submit\n# or single assertion (no file needed):\nwh assertion create --shape ShapeName --about Target/name --name my-assertion --data '{\"field\":1}' --repo org/repo\n# Relay failed operation details when present. Never hand-guess ops JSON — use `wh shape template <Shape>`.\n```\n\n**Read data:**\n```bash\nwh thing list --repo org/repo # all things at HEAD\nwh thing view Shape/name --repo org/repo # inspect a thing\nwh thing query --shape MyShape --repo org/repo # find things by shape\nwh thing about Shape --repo org/repo # assertions about a shape\nwh assertion list --repo org/repo # all assertions at HEAD\nwh thing history Shape/name --repo org/repo # version history\n\n# Batch read — wh thing view is variadic (max 500 wrefs/call):\nwh thing view Player/alice Player/bob # variadic positionals\nwh thing view --file wrefs.txt --json # one wref per line\ncat wrefs.txt | wh thing view --format jsonl # one JSON line per *deduped* requested wref\n```\n\n## Wref Quick Reference\n\nWrites use explicit names and wrefs. Untyped fields, collection members,\nassertion `about`, and committers accept any thing. Create a deterministic\ntarget before referencing it in the same commit.\n\n## Command Reference\n\n**Global flags**: `--repo`, `--format`, `--json`, `--live`\n### thing — Things\n- `wh thing list [--shape] [--kind] [--match] [--include-retracted]` — Current HEAD state\n- `wh thing view [<wref>...] [--file <path>] [--version] [--depth] [--include-retracted] [--data-mode auto|full]` — Thing details. Variadic (max 500). `--version` implies `--include-retracted`. Batch JSON returns `{ requested, items, missing }`; jsonl emits one row per deduped requested wref. Large Set/List bodies summarize by default; use `--data-mode full` for canonical collection JSON.\n- `wh thing history [wref] [--shape] [--about] [--include-retracted]` — Version history\n- `wh thing resolve <wref>` — Resolve a wref to its canonical thing identity\n- `wh thing create <name|Shape/name> (--data|--file) [--shape]` — Create\n- `wh thing revise <name> [--data] [--message] [--committer] [--expected-version]` — Revise (CONFLICT if HEAD≠n)\n- `wh thing retract <wref> -m <message> [--reason] [--kind] [--expected-version]` — Retract\n- `wh thing query [--shape] [--kind] [--about] [--match]` — Query by filters\n- `wh thing search <query> [--shape] [--kind] [--about] [--mode]` — Search text\n- `wh thing rename <Shape/oldName> <newName>` — Rename\n- `wh thing refs <wref> [--inbound] [--outbound] [--field]` — Show field references; use `wh thing about` for assertions about the target thing\n- `wh thing about <wref> [--shape] [--match] [--depth] [--resolve-collections] [--role from|to|ends] [--limit] [--include-retracted]` — Show assertions about the target identity; `--resolve-collections` expands bare/@HEAD/@ALL members, `--role` filters direction; not pinned @vN\n\n- `wh view evaluate VIEW [--limit N] [--cursor TOK] [--all]`\n### commit — Write operations\n- `wh commit submit [--ops|--file|--add|--revise|--retract] [--dry-run] [--skip-existing]` — Submit operations, or evaluate the complete bounded input without durable changes under `--dry-run`. JSONL preview emits one operation row per input plus one summary.\n- `wh shape template <shape> [shape2 ...] [--kind] [--operation add|revise|retract] [-o file]` — Generate sample ops\n\n### assertion — Assertion operations\n- `wh assertion list [--about wref] [--shape] [--match] [--include-retracted]` — Browse assertions\n- `wh assertion view <wref> [--version] [--include-retracted]` — Assertion details\n- `wh assertion create --shape <s> --name <n> --about <wref> [--data] [-m] [--committer]` — Create assertion\n- `wh assertion revise <wref> --data <json> [--message] [--committer]` — Revise assertion\n- `wh assertion retract <wref> -m <message> [--reason] [--committer] [--expected-version]` — Retract assertion\n- `wh assertion history <wref> [--include-retracted]` — Assertion history\n\n### shape — Shape management\n- `wh shape list [--match] [--include-retracted]` — List all shapes\n- `wh shape view <name> [--include-retracted]` — Shape details\n- `wh shape revise <name> (--fields|--file)`\n- `wh shape create <name> (--fields|--file)`\n- `wh shape retract <name> -m <message> [--reason] [--expected-version]` — Retract shape\n- `wh shape history <name> [--include-retracted]` — Shape history\n- `wh shape rename <oldName> <newName>` — Rename shape\n\n### repo — Repository management\n- `wh repo create <org/name> [--display-name] [--description] [--visibility]` — Create repo\n- `wh repo list [org]` — List repos\n- `wh repo view [org/repo]` — Repo details\n\n### org — Organization management\n- `wh org create <name> [--display-name]` — Create a new organization\n- `wh org view <name>` — View organization details (alias: info)\n- `wh org list` — List all organizations\n\n### sub — Subscription management\n- `wh sub create <name> [flags]` — Create a subscription\n- `wh sub view <name>` — View subscription details\n- `wh sub list` — List all subscriptions\n- `wh sub log <name>` — Tail subscription delivery feed\n- `wh sub attempts <runId>` — Show attempt history for a run\n- `wh sub pause <name>` — Pause a subscription\n- `wh sub resume <name>` — Resume a paused subscription\n- `wh sub bind <name> [--credentials]` — Bind a credential set to a subscription for webhook auth\n- `wh sub unbind <name>` — Remove credential binding from a subscription\n- `wh sub delete <name>` — Retire; name reserved\n\n### notifications — Action notification listing\n- `wh notifications [--limit] [--since]` — List repo-scoped action notifications\n\n### credential — Credential set management\n- `wh credential create <name> [--repo org/repo | --org org] [--scope] [--description]` — Create an empty credential set\n- `wh credential list [--repo org/repo | --org org]` — List credential sets accessible from a repo or org\n- `wh credential view <name> [--repo org/repo | --org org]` — View a credential set (key names only, no values)\n- `wh credential delete <name> [--repo org/repo | --org org]` — Delete a credential set and its Vault object\n- `wh credential set <setName> [<keyName>] [--repo org/repo | --org org] [--value]` — Set credential key(s). With `<keyName>`: single-key form (reads value from `--value` or stdin). Without `<keyName>`: batch form (reads JSON object from stdin, e.g. `{\"KEY\":\"val\"}`)\n- `wh credential unset <setName> <keyName> [--repo org/repo | --org org]` — Remove a key from a credential set\n- `wh credential audit <setName> [--repo org/repo | --org org]` — View audit log for a credential set\n- `wh credential revoke <setName> [--repo org/repo | --org org] [--reason]` — Revoke a credential set (blocks new binds and stops bound webhook deliveries)\n\n### component — Component management\n- `wh component validate <path>` — Validate package\n- `wh component install <org/name>` — Install a registered component\n- `wh component register <name> --org <org> --manifest <path> [flags]` — Register component identity\n- `wh component unregister <org/name>` — Remove a registered component identity\n- `wh component registry list --org <org>` — List registered components\n- `wh component registry view <org/name>` — View a registered component\n- `wh component registry update <org/name> [flags]` — Update a registered component\n- `wh component list` — List installed components\n- `wh component update <org/name>` — Update installed component\n- `wh component view <org/name>` — Show component details (alias: show)\n- `wh component doctor <org/name>` — Run component health checks\n- `wh component teardown <org/name>` — Pause component subscriptions\n\n### Getting More Info\n- `wh help` — help overview\n- `wh <domain>` — domain verbs\n- `wh <domain> <verb> --help` — verb flags and examples\n- `wh help --format json` — `CliSpecV2` (`schemaVersion: 2`): global/contextual/root tables and command overrides\n\n## Common Workflows\n\n**Explore a repo:**\n```bash\nwh thing list --repo org/repo # see all things in HEAD\nwh thing view Shape/name --repo org/repo # inspect a specific thing\nwh thing history Shape/name --repo org/repo # inspect version history\nwh thing about Shape/name # assertions about thing/shape\n```\n\n**Create an assertion** (most common write):\n```bash\n# --about takes an untyped target wref: Shape or Shape/name.\nwh assertion create --shape MyShape --about TargetShape/target-name \\\n --name my-assertion --data '{\"field_a\":1,\"field_b\":\"value\"}' --repo org/repo\n# Output includes per-operation status; relay failures when present.\n```\n\n**Create via write entrypoint** (alternative, supports batches and streams):\n```bash\nwh commit submit --add my-item --shape MyShape --kind assertion \\\n --about TargetShape/target-name --data '{\"field_a\":1}' --repo org/repo\n```\n\n**Batch write via file** (generate template → edit → submit):\n```bash\nwh shape template Hypothesis Evidence -o ops.json # add --kind assertion --about TargetShape/name for assertions\n# edit ops.json — fill FILL_IN placeholders\nwh commit submit --file ops.json -m \"batch update\" # submit all operations (bare `wh commit` is equivalent)\n# --file format: docs.warmhub.ai/cli-reference/commit-operations\n```\n\n**Bulk write (JSONL stream, >1k ops)** — one chunked stream beats per-record commits (~60× faster):\n```bash\nwh shape template MyShape -o ops.jsonl # one op per line (.jsonl)\nID=\"bulk-$(date +%s)\" # caller id for chunk correlation\nwh commit submit --file ops.jsonl --stream-id \"$ID\" --chunk-size 5000 \\\n --skip-existing --progress -m \"bulk ingest\" --repo org/repo\n# --chunk-size: ops per append chunk (default 1000, max 10000); chunk≈1 is ~60× slower\n# --skip-existing: skips already-written add ops (drops per-row read-before-write)\n# --stream-id identifies the submission but provides no receipt or resume.\n# After an outcome-unknown append, stop writes and reconcile attempted + unsent\n# work from a later verified checkpoint; never blindly replay revise/retract.\n```\n\n**Create collections:**\n```bash\nwh commit submit --type arc --name route --members Location/a,Location/b --repo org/repo\nwh assertion create --shape Supports --name route-support --about Arc/route --data '{\"confidence\":0.8}' --repo org/repo\n```\n\n**Modify data:**\n```bash\nwh thing revise Shape/name --data '{\"x\":5,\"y\":3}' -m \"update\" --repo org/repo\nwh thing retract Shape/old-item -m \"withdrawn\" --reason \"data feed contaminated\" --repo org/repo\n```\n\n**Query and filter:**\n```bash\nwh thing query --shape MyShape # by shape\nwh thing query --kind assertion --about Shape/name # by kind + target\nwh thing history Shape/name --limit 10 # version history\n```\n\n## Built-in Content shape\n\nWarmHub repos expose three well-known content wrefs:\n- `Content/Readme` — stored markdown for humans\n- `Content/Agents` — stored markdown guidance for AI agents\n- `Content/LlmsTxt` — synthesized per-request sitemap (read-only)\n\nFetch via `wh repo content get --kind readme|agents|llms-txt`,\n`client.repo.getReadme/getAgents/getLlmsTxt`, MCP `warmhub_repo_content_get`,\nor raw HTTP `GET /{org}/{repo}/readme.md|agents.md|llms.txt`.\nSee `wh repo describe` → `additionalInformation` for the discovery field.\n\n## Query Discipline\n- Plan the repo, shapes, and wrefs you need before the first query.\n- Gather the needed facts from one repo before switching to another.\n- Do the queries first, then write one complete answer.\n\n## Agent Tips\n- **Always run commands for live data** — this context describes the CLI, not repo contents\n- **Before writing, discover wrefs** — run `wh thing list` or `wh shape list`\n- **Shape field types**: `string`, `number`, `boolean`, `wref`, arrays, optionals, nested objects\n- **Write commands return per-operation results** — relay failures and affected wrefs to the user\n- **Pass data inline** with `--data '{...}'` — do NOT create temp files\n- Add `--json` to any command for machine-readable JSON output\n- **Aliases teach canonical commands** — executing aliases emit a status hint; misleading lifecycle aliases reject and point to `retract`\n- Writes go through `wh commit submit` (or bare `wh commit`) or wrappers (`create`, `revise`, `retract`, `assertion create`). `retract` irreversibly withdraws an identity and creates a history entry.\n- Use `wh doctor` to check environment health\n";
62939
+ var prime_content_default = "# WarmHub CLI Context\n> **Context Recovery**: Run `wh prime` after compaction or new session\n\n## Environment\n{{REPO_LINE}}\n\n## Core Concepts\n- **Thing**: A named entity versioned by writes. **Assertion**: A thing that makes a shape-validated claim about another thing.\n- **Shape**: A thing defining data structure; every other thing has one. **Write**: One or more add/revise/retract operations with per-operation results.\n- **wref**: A reference to a thing. Local: `Player` (the shape) or `Player/alice` (a thing with that shape). Cross-repo: `wh:org/repo/Shape` or `wh:org/repo/Shape/name`.\n\n## Versioned Wrefs\n- `Shape` addresses the shape itself; `Shape/name` addresses a thing with that shape. `@vN` pins either.\n- Floating write refs to retracted targets fail; existing pinned versions remain valid.\n- Rename invalidates old spellings, including `@vN`; the new name resolves history.\n- Untyped wrefs accept any thing. `wref<T>` requires the target's shape to be `T`; a shape has no shape, so never satisfies it. `wref?` coalesces only `thing_absent`, never a missing shape.\n- Wref `binding`: `identity` follows the Thing, `versioned` pins.\n\n## Key Workflows\n\n**Write data** (discover shapes → scaffold ops → submit):\n```bash\nwh shape list --repo org/repo # list available shapes\nwh shape view ShapeName --repo org/repo # inspect fields\nwh shape template ShapeName -o ops.json --repo org/repo # scaffold write ops (supports --kind assertion)\n# edit ops.json — fill FILL_IN placeholders — then:\nwh commit submit --file ops.json --dry-run --repo org/repo # preview; remove --dry-run to submit\n# or single assertion (no file needed):\nwh assertion create --shape ShapeName --about Target/name --name my-assertion --data '{\"field\":1}' --repo org/repo\n# Relay failed operation details when present. Never hand-guess ops JSON — use `wh shape template <Shape>`.\n```\n\n**Read data:**\n```bash\nwh thing list --repo org/repo # all things at HEAD\nwh thing view Shape/name --repo org/repo # inspect a thing\nwh thing query --shape MyShape --repo org/repo # find things by shape\nwh thing about Shape --repo org/repo # assertions about a shape\nwh assertion list --repo org/repo # all assertions at HEAD\nwh thing history Shape/name --repo org/repo # version history\n\n# Batch read — wh thing view is variadic (max 500 wrefs/call):\nwh thing view Player/alice Player/bob # variadic positionals\nwh thing view --file wrefs.txt --json # one wref per line\ncat wrefs.txt | wh thing view --format jsonl # one JSON line per *deduped* requested wref\n```\n\n## Wref Quick Reference\n\nWrites use explicit names and wrefs. Untyped fields, collection members,\nassertion `about`, and committers accept any thing. Create a deterministic\ntarget before referencing it in the same commit.\n\n## Command Reference\n\n**Global flags**: `--repo`, `--format`, `--json`, `--live`\n### thing — Things\n- `wh thing list [--shape] [--kind] [--match] [--include-retracted]` — Current HEAD state\n- `wh thing view [<wref>...] [--file <path>] [--version] [--depth] [--include-retracted] [--data-mode auto|full]` — Thing details. Variadic (max 500). `--version` implies `--include-retracted`. Batch JSON returns `{ requested, items, missing }`; jsonl emits one row per deduped requested wref. Large Set/List bodies summarize by default; use `--data-mode full` for canonical collection JSON.\n- `wh thing history [wref] [--shape] [--about] [--include-retracted]` — Version history\n- `wh thing resolve <wref>` — Resolve a wref to its canonical thing identity\n- `wh thing create <name|Shape/name> (--data|--file) [--shape]` — Create\n- `wh thing revise <name> [--data] [--message] [--committer] [--expected-version]` — Revise (CONFLICT if HEAD≠n)\n- `wh thing retract <wref> -m <message> [--reason] [--kind] [--expected-version]` — Retract\n- `wh thing query [--shape] [--kind] [--about] [--match]` — Query by filters\n- `wh thing search <query> [--shape] [--kind] [--about] [--mode]` — Search text\n- `wh thing rename <Shape/oldName> <newName>` — Rename\n- `wh thing refs <wref> [--inbound] [--outbound] [--field]` — Show field references; use `wh thing about` for assertions about the target thing\n- `wh thing about <wref> [--shape] [--match] [--depth] [--resolve-collections] [--role from|to|ends] [--limit] [--include-retracted]` — Show assertions about the target identity; `--resolve-collections` expands bare/@HEAD/@ALL members, `--role` filters direction; not pinned @vN\n\n- `wh view evaluate VIEW [--limit N] [--cursor TOK] [--all]`\n### commit — Write operations\n- `wh commit submit [--ops|--file|--add|--revise|--retract] [--dry-run] [--skip-existing]` — Submit operations, or evaluate the complete bounded input without durable changes under `--dry-run`. JSONL preview emits one operation row per input plus one summary.\n- `wh shape template <shape> [shape2 ...] [--kind] [--operation add|revise|retract] [-o file]` — Generate sample ops\n\n### assertion — Assertion operations\n- `wh assertion list [--about wref] [--shape] [--match] [--include-retracted]` — Browse assertions\n- `wh assertion view <wref> [--version] [--include-retracted]` — Assertion details\n- `wh assertion create --shape <s> --name <n> --about <wref> [--data] [-m] [--committer]` — Create assertion\n- `wh assertion revise <wref> --data <json> [--message] [--committer]` — Revise assertion\n- `wh assertion retract <wref> -m <message> [--reason] [--committer] [--expected-version]` — Retract assertion\n- `wh assertion history <wref> [--include-retracted]` — Assertion history\n\n### shape — Shape management\n- `wh shape list [--match] [--include-retracted]` — List all shapes\n- `wh shape view <name> [--include-retracted]` — Shape details\n- `wh shape revise <name> (--fields|--file)`\n- `wh shape create <name> (--fields|--file)`\n- `wh shape retract <name> -m <message> [--reason] [--expected-version]` — Retract shape\n- `wh shape history <name> [--include-retracted]` — Shape history\n- `wh shape rename <oldName> <newName>` — Rename shape\n\n### repo — Repository management\n- `wh repo create <org/name> [--display-name] [--description] [--visibility]` — Create repo\n- `wh repo list [org]` — List repos\n- `wh repo view [org/repo]` — Repo details\n\n### org — Organization management\n- `wh org create <name> [--display-name]` — Create a new organization\n- `wh org view <name>` — View organization details (alias: info)\n- `wh org list` — List all organizations\n\n### sub — Subscription management\n- `wh sub create <name> [flags]` — Create a subscription\n- `wh sub view <name>` — View subscription details\n- `wh sub list` — List all subscriptions\n- `wh sub log <name>` — Tail subscription delivery feed\n- `wh sub attempts <runId>` — Show attempt history for a run\n- `wh sub pause <name>` — Pause a subscription\n- `wh sub resume <name>` — Resume a paused subscription\n- `wh sub bind <name> [--credentials]` — Bind a credential set to a subscription for webhook auth\n- `wh sub unbind <name>` — Remove credential binding from a subscription\n- `wh sub delete <name>` — Retire; name reserved\n\n### notifications — Action notification listing\n- `wh notifications [--limit] [--since]` — List repo-scoped action notifications\n\n### credential — Credential set management\n- `wh credential create <name> [--repo org/repo | --org org] [--scope] [--description]` — Create an empty credential set\n- `wh credential list [--repo org/repo | --org org]` — List credential sets accessible from a repo or org\n- `wh credential view <name> [--repo org/repo | --org org]` — View a credential set (key names only, no values)\n- `wh credential delete <name> [--repo org/repo | --org org]` — Delete a credential set and its Vault object\n- `wh credential set <setName> [<keyName>] [--repo org/repo | --org org] [--value]` — Set credential key(s). With `<keyName>`: single-key form (reads value from `--value` or stdin). Without `<keyName>`: batch form (reads JSON object from stdin, e.g. `{\"KEY\":\"val\"}`)\n- `wh credential unset <setName> <keyName> [--repo org/repo | --org org]` — Remove a key from a credential set\n- `wh credential audit <setName> [--repo org/repo | --org org]` — View audit log for a credential set\n- `wh credential revoke <setName> [--repo org/repo | --org org] [--reason]` — Revoke a credential set (blocks new binds and stops bound webhook deliveries)\n\n### component — Component management\n- `wh component validate <path>` — Validate package\n- `wh component install <org/name>` — Install a registered component\n- `wh component register <name> --org <org> --manifest <path> [flags]` — Register component identity\n- `wh component unregister <org/name>` — Remove a registered component identity\n- `wh component registry list --org <org>` — List registered components\n- `wh component registry view <org/name>` — View a registered component\n- `wh component registry update <org/name> [flags]` — Update a registered component\n- `wh component list` — List installed components\n- `wh component update <org/name>` — Update installed component\n- `wh component view <org/name>` — Show component details (alias: show)\n- `wh component doctor <org/name>` — Run component health checks\n- `wh component teardown <org/name>` — Pause component subscriptions\n\n### Getting More Info\n- `wh help` — help overview\n- `wh <domain>` — domain verbs\n- `wh <domain> <verb> --help` — verb flags and examples\n- `wh help --format json` — `CliSpecV2` (`schemaVersion: 2`): global/contextual/root tables and command overrides\n\n## Common Workflows\n\n**Explore a repo:**\n```bash\nwh thing list --repo org/repo # see all things in HEAD\nwh thing view Shape/name --repo org/repo # inspect a specific thing\nwh thing history Shape/name --repo org/repo # inspect version history\nwh thing about Shape/name # assertions about thing/shape\n```\n\n**Create an assertion** (most common write):\n```bash\n# --about takes an untyped target wref: Shape or Shape/name.\nwh assertion create --shape MyShape --about TargetShape/target-name \\\n --name my-assertion --data '{\"field_a\":1,\"field_b\":\"value\"}' --repo org/repo\n# Output includes per-operation status; relay failures when present.\n```\n\n**Create via write entrypoint** (alternative, supports batches and streams):\n```bash\nwh commit submit --add my-item --shape MyShape --kind assertion \\\n --about TargetShape/target-name --data '{\"field_a\":1}' --repo org/repo\n```\n\n**Batch write via file** (generate template → edit → submit):\n```bash\nwh shape template Hypothesis Evidence -o ops.json # add --kind assertion --about TargetShape/name for assertions\n# edit ops.json — fill FILL_IN placeholders\nwh commit submit --file ops.json -m \"batch update\" # submit all operations (bare `wh commit` is equivalent)\n# --file format: docs.warmhub.ai/cli-reference/commit-operations\n```\n\n**Bulk write (JSONL stream, >1k ops)** — one chunked stream beats per-record commits (~60× faster):\n```bash\nwh shape template MyShape -o ops.jsonl # one op per line (.jsonl)\nID=\"bulk-$(date +%s)\" # caller id for chunk correlation\nwh commit submit --file ops.jsonl --stream-id \"$ID\" --chunk-size 5000 \\\n --skip-existing --progress -m \"bulk ingest\" --repo org/repo\n# --chunk-size: ops per append chunk (default 1000, max 10000); chunk≈1 is ~60× slower\n# --skip-existing: skips already-written add ops (drops per-row read-before-write)\n# --stream-id identifies the submission but provides no receipt or resume.\n# After an outcome-unknown append, stop writes and reconcile attempted + unsent\n# work from a later verified checkpoint; never blindly replay revise/retract.\n```\n\n**Create collections:**\n```bash\nwh commit submit --type arc --name route --members Location/a,Location/b --repo org/repo\nwh assertion create --shape Supports --name route-support --about Arc/route --data '{\"confidence\":0.8}' --repo org/repo\n```\n\n**Modify data:**\n```bash\nwh thing revise Shape/name --data '{\"x\":5,\"y\":3}' -m \"update\" --repo org/repo\nwh thing retract Shape/old-item -m \"withdrawn\" --reason \"data feed contaminated\" --repo org/repo\n```\n\n**Query and filter:**\n```bash\nwh thing query --shape MyShape # by shape\nwh thing query --kind assertion --about Shape/name # by kind + target\nwh thing history Shape/name --limit 10 # version history\n```\n\n## Built-in Content shape\n\nWarmHub repos expose three well-known content wrefs:\n- `Content/Readme` — stored markdown for humans\n- `Content/Agents` — stored markdown guidance for AI agents\n- `Content/LlmsTxt` — synthesized per-request sitemap (read-only)\n\nFetch via `wh repo content get --kind readme|agents|llms-txt`,\n`client.repo.getReadme/getAgents/getLlmsTxt`, MCP `warmhub_repo_content_get`,\nor raw HTTP `GET /{org}/{repo}/readme.md|agents.md|llms.txt`.\nSee `wh repo describe` → `additionalInformation` for the discovery field.\n\n## Query Discipline\n- Plan the repo, shapes, and wrefs you need before the first query.\n- Gather the needed facts from one repo before switching to another.\n- Do the queries first, then write one complete answer.\n\n## Agent Tips\n- **Always run commands for live data** — this context describes the CLI, not repo contents\n- **Before writing, discover wrefs** — run `wh thing list` or `wh shape list`\n- **Shape field types**: `string`, `number`, `boolean`, `wref`, arrays, optionals, nested objects\n- **Write commands return per-operation results** — relay failures and affected wrefs to the user\n- **Pass data inline** with `--data '{...}'` — do NOT create temp files\n- Add `--json` to any command for machine-readable JSON output\n- **Aliases teach canonical commands** — executing aliases emit a status hint; misleading lifecycle aliases reject and point to `retract`\n- Writes go through `wh commit submit` (or bare `wh commit`) or wrappers (`create`, `revise`, `retract`, `assertion create`). `retract` irreversibly withdraws an identity and creates a history entry.\n- Use `wh doctor` to check environment health\n";
62719
62940
 
62720
62941
  // ../../packages/warmhub-cli/src/domains/prime.ts
62721
62942
  function buildMarkdown(config2) {
@@ -63101,6 +63322,8 @@ class StreamingByteReader {
63101
63322
  return;
63102
63323
  }
63103
63324
  const head = this.#queue[0];
63325
+ if (!head)
63326
+ return;
63104
63327
  const available = head.byteLength - this.#queueOffset;
63105
63328
  const length = Math.min(limit, available);
63106
63329
  const result = head.subarray(this.#queueOffset, this.#queueOffset + length);
@@ -63116,7 +63339,10 @@ class StreamingByteReader {
63116
63339
  if (bytes.byteLength === 0)
63117
63340
  return;
63118
63341
  if (this.#queueOffset > 0) {
63119
- const current = this.#queue[0].subarray(this.#queueOffset);
63342
+ const head = this.#queue[0];
63343
+ if (!head)
63344
+ throw new Error("archive reader queue is inconsistent");
63345
+ const current = head.subarray(this.#queueOffset);
63120
63346
  this.#queue[0] = current;
63121
63347
  this.#queueOffset = 0;
63122
63348
  }
@@ -64833,6 +65059,70 @@ var VERIFY_VERB = {
64833
65059
  handler: handleVerify2
64834
65060
  };
64835
65061
 
65062
+ // ../../packages/warmhub-cli/src/domains/repo/index-pin.ts
65063
+ var PIN_USAGE = "Usage: wh repo index pin <Shape> <field.path> [org/repo]";
65064
+ var PIN_EXAMPLE = "wh repo index pin Person address.city acme/world";
65065
+ var UNPIN_USAGE = "Usage: wh repo index unpin <Shape> <field.path> [org/repo]";
65066
+ var UNPIN_EXAMPLE = "wh repo index unpin Person address.city acme/world";
65067
+ function parseIndexArgs(args, usage, example) {
65068
+ const [shape, fieldPath, repoRef] = args;
65069
+ if (!shape || !fieldPath) {
65070
+ usageError(usage, example);
65071
+ }
65072
+ return { shape, fieldPath, repoRef };
65073
+ }
65074
+ function renderPinResult(ctx, verb, result) {
65075
+ const c = ctx.colors;
65076
+ ctx.out(`${c.green}${verb}${c.reset} ${c.cyan}${escapeTerminalTextForDisplay(result.fieldPath)}${c.reset} via ${escapeTerminalTextForDisplay(result.declaredByShape)}`);
65077
+ if (result.carryingShapes.length === 0) {
65078
+ ctx.out(` ${c.dim}no shape in this repo carries the path${c.reset}`);
65079
+ return;
65080
+ }
65081
+ const maxShape = result.carryingShapes.reduce((m, s) => Math.max(m, s.shape.length), 0);
65082
+ for (const carrying of result.carryingShapes) {
65083
+ ctx.out(` ${c.cyan}${escapeTerminalTextForDisplay(carrying.shape.padEnd(maxShape))}${c.reset} ${escapeTerminalTextForDisplay(carrying.markerState)}`);
65084
+ }
65085
+ }
65086
+ var handlePin = async (ctx, { args }) => {
65087
+ const { shape, fieldPath, repoRef } = parseIndexArgs(args, PIN_USAGE, PIN_EXAMPLE);
65088
+ const { org, repo: repo2 } = parseOrgRepo(getRepoRef(ctx) ?? repoRef, ctx.config);
65089
+ const result = await ctx.client.repo.index.pin(org, repo2, shape, fieldPath);
65090
+ writeOutput(ctx, result, () => renderPinResult(ctx, "Declared", result));
65091
+ };
65092
+ var handleUnpin = async (ctx, { args }) => {
65093
+ const { shape, fieldPath, repoRef } = parseIndexArgs(args, UNPIN_USAGE, UNPIN_EXAMPLE);
65094
+ const { org, repo: repo2 } = parseOrgRepo(getRepoRef(ctx) ?? repoRef, ctx.config);
65095
+ const result = await ctx.client.repo.index.unpin(org, repo2, shape, fieldPath);
65096
+ writeOutput(ctx, result, () => renderPinResult(ctx, "Withdrew", result));
65097
+ };
65098
+ var INDEX_SUBDOMAIN = defineDomain({
65099
+ name: "index",
65100
+ summary: "Declare which field paths the typed field index carries",
65101
+ verbs: {
65102
+ pin: {
65103
+ summary: "Declare a field path for indexing",
65104
+ args: "<Shape> <field.path> [org/repo]",
65105
+ notes: [
65106
+ "The declaration is repository-wide: every shape carrying the path is backfilled, not just the one named here.",
65107
+ "The path is resolved through the shape’s effective contract, so a composite may name a property one of its composed shapes owns.",
65108
+ "Read `wh repo describe --indexed-fields` for readiness."
65109
+ ],
65110
+ examples: [PIN_EXAMPLE, "wh repo index pin Person address.city"],
65111
+ handler: handlePin
65112
+ },
65113
+ unpin: {
65114
+ summary: "Withdraw a field path from indexing",
65115
+ args: "<Shape> <field.path> [org/repo]",
65116
+ notes: [
65117
+ "Refuses while a stored View definition references the path, naming the Views.",
65118
+ "Rows are evicted asynchronously; predicates on the path fail immediately."
65119
+ ],
65120
+ examples: [UNPIN_EXAMPLE, "wh repo index unpin Person address.city"],
65121
+ handler: handleUnpin
65122
+ }
65123
+ }
65124
+ });
65125
+
64836
65126
  // ../../packages/warmhub-cli/src/domains/repo/lifecycle.ts
64837
65127
  var confirmFlags2 = {
64838
65128
  yes: flag.boolean({ short: "y", description: "Skip confirmation prompt" })
@@ -64950,6 +65240,100 @@ var handleList6 = async (ctx, { flags, args }) => {
64950
65240
  });
64951
65241
  };
64952
65242
 
65243
+ // ../../packages/warmhub-cli/src/domains/repo/indexed-fields-view.ts
65244
+ function stripShapeThingId(bucket) {
65245
+ return bucket.map(({ shapeThingId: _omit, ...rest }) => rest);
65246
+ }
65247
+ function toPublicIndexedFields(report) {
65248
+ return {
65249
+ building: stripShapeThingId(report.building),
65250
+ ready: stripShapeThingId(report.ready),
65251
+ failed: stripShapeThingId(report.failed),
65252
+ other: stripShapeThingId(report.other),
65253
+ declarations: report.declarations,
65254
+ consistency: report.consistency
65255
+ };
65256
+ }
65257
+ function stateColor(c, state) {
65258
+ switch (state) {
65259
+ case "ready":
65260
+ return c.green;
65261
+ case "building":
65262
+ return c.yellow;
65263
+ case "failed":
65264
+ return c.red;
65265
+ default:
65266
+ return c.dim;
65267
+ }
65268
+ }
65269
+ function renderDeclarations(out, c, view) {
65270
+ const { declarations, consistency } = view;
65271
+ if (declarations.length === 0) {
65272
+ out(`${c.bold}Declared Fields${c.reset} ${c.dim}none${c.reset}`);
65273
+ out(` ${c.dim}Declare one with \`wh repo index pin <Shape> <path>\`${c.reset}`);
65274
+ } else {
65275
+ out(`${c.bold}Declared Fields${c.reset} (${declarations.length})`);
65276
+ out("");
65277
+ const maxPath = declarations.reduce((m, d) => Math.max(m, d.fieldPath.length), 0);
65278
+ for (const declaration of declarations) {
65279
+ const pathLabel = escapeTerminalTextForDisplay(declaration.fieldPath.padEnd(maxPath));
65280
+ const readiness = declaration.ready ? "ready" : "not ready";
65281
+ const rc = declaration.ready ? c.green : c.yellow;
65282
+ const carriedBy = declaration.carrying.length > 0 ? declaration.carrying.map((m) => `${m.shapeName} (${m.state})`).join(", ") : "no carrying shape";
65283
+ out(` ${c.cyan}${pathLabel}${c.reset} ${rc}${readiness}${c.reset} ${c.dim}${escapeTerminalTextForDisplay(carriedBy)}${c.reset}`);
65284
+ if (declaration.declaredByShape) {
65285
+ out(` ${c.dim}pinned via ${escapeTerminalTextForDisplay(declaration.declaredByShape)}${c.reset}`);
65286
+ }
65287
+ }
65288
+ }
65289
+ out("");
65290
+ if (!consistency.consistent) {
65291
+ out(`${c.bold}${c.red}Index consistency${c.reset}`);
65292
+ for (const marker of consistency.undeclaredMarkers) {
65293
+ out(` ${c.red}undeclared${c.reset} ${c.cyan}${escapeTerminalTextForDisplay(marker.shapeName)}${c.reset} ${escapeTerminalTextForDisplay(marker.fieldPath)}`);
65294
+ }
65295
+ out("");
65296
+ }
65297
+ }
65298
+ function renderMarkers(out, c, view) {
65299
+ const allEntries = [
65300
+ ...view.building,
65301
+ ...view.ready,
65302
+ ...view.failed,
65303
+ ...view.other
65304
+ ];
65305
+ if (allEntries.length === 0) {
65306
+ out(`${c.bold}Indexed Fields${c.reset} ${c.dim}none${c.reset}`);
65307
+ return;
65308
+ }
65309
+ out(`${c.bold}Indexed Fields${c.reset} (${allEntries.length})`);
65310
+ out("");
65311
+ const maxShape = allEntries.reduce((m, e) => Math.max(m, e.shapeName.length), 0);
65312
+ const maxField = allEntries.reduce((m, e) => Math.max(m, e.fieldPath.length), 0);
65313
+ const maxState = allEntries.reduce((m, e) => Math.max(m, e.state.length), 0);
65314
+ for (const entry of allEntries) {
65315
+ const shapeLabel = escapeTerminalTextForDisplay(entry.shapeName.padEnd(maxShape));
65316
+ const fieldLabel = escapeTerminalTextForDisplay(entry.fieldPath.padEnd(maxField));
65317
+ const stateLabel = escapeTerminalTextForDisplay(entry.state.padEnd(maxState));
65318
+ const sc = stateColor(c, entry.state);
65319
+ let line = ` ${c.cyan}${shapeLabel}${c.reset} ${c.dim}${fieldLabel}${c.reset} ${sc}${stateLabel}${c.reset}`;
65320
+ if (entry.state === "building" && entry.backfillTotal != null && entry.backfillTotal > 0) {
65321
+ const pct = Math.round(entry.backfillDone / entry.backfillTotal * 100);
65322
+ line += ` ${c.dim}${entry.backfillDone}/${entry.backfillTotal} (${pct}%)${c.reset}`;
65323
+ } else if (entry.state === "building") {
65324
+ line += ` ${c.dim}${entry.backfillDone} rows${c.reset}`;
65325
+ } else if (entry.state === "failed" && entry.failureReason) {
65326
+ line += ` ${c.dim}${escapeTerminalTextForDisplay(entry.failureReason)}${c.reset}`;
65327
+ }
65328
+ out(line);
65329
+ }
65330
+ out("");
65331
+ }
65332
+ function renderIndexedFields(out, c, view) {
65333
+ renderDeclarations(out, c, view);
65334
+ renderMarkers(out, c, view);
65335
+ }
65336
+
64953
65337
  // ../../packages/warmhub-cli/src/domains/repo/manage.ts
64954
65338
  var repoRenameFlags = {
64955
65339
  "display-name": flag.string({
@@ -65044,15 +65428,7 @@ var handleDescribe = async (ctx, { args, flags }) => {
65044
65428
  ...nameStrings(shapes).map((name) => [name, 0]),
65045
65429
  ...Object.entries(stats.byShape)
65046
65430
  ]);
65047
- function stripShapeThingId(bucket) {
65048
- return bucket.map(({ shapeThingId: _omit, ...rest }) => rest);
65049
- }
65050
- const indexedFieldsPublic = indexedFields ? {
65051
- building: stripShapeThingId(indexedFields.building),
65052
- ready: stripShapeThingId(indexedFields.ready),
65053
- failed: stripShapeThingId(indexedFields.failed),
65054
- other: stripShapeThingId(indexedFields.other)
65055
- } : null;
65431
+ const indexedFieldsPublic = indexedFields ? toPublicIndexedFields(indexedFields) : null;
65056
65432
  const payload = {
65057
65433
  org,
65058
65434
  repo: repo2,
@@ -65128,50 +65504,7 @@ var handleDescribe = async (ctx, { args, flags }) => {
65128
65504
  ctx.out("");
65129
65505
  }
65130
65506
  if (indexedFieldsPublic) {
65131
- const allEntries = [
65132
- ...indexedFieldsPublic.building,
65133
- ...indexedFieldsPublic.ready,
65134
- ...indexedFieldsPublic.failed,
65135
- ...indexedFieldsPublic.other
65136
- ];
65137
- if (allEntries.length === 0) {
65138
- ctx.out(`${c.bold}Indexed Fields${c.reset} ${c.dim}none${c.reset}`);
65139
- } else {
65140
- ctx.out(`${c.bold}Indexed Fields${c.reset} (${allEntries.length})`);
65141
- ctx.out("");
65142
- const stateColor = (state) => {
65143
- switch (state) {
65144
- case "ready":
65145
- return c.green;
65146
- case "building":
65147
- return c.yellow;
65148
- case "failed":
65149
- return c.red;
65150
- default:
65151
- return c.dim;
65152
- }
65153
- };
65154
- const maxShape = allEntries.reduce((m, e) => Math.max(m, e.shapeName.length), 0);
65155
- const maxField = allEntries.reduce((m, e) => Math.max(m, e.fieldPath.length), 0);
65156
- const maxState = allEntries.reduce((m, e) => Math.max(m, e.state.length), 0);
65157
- for (const entry of allEntries) {
65158
- const shapeLabel = escapeTerminalTextForDisplay(entry.shapeName.padEnd(maxShape));
65159
- const fieldLabel = escapeTerminalTextForDisplay(entry.fieldPath.padEnd(maxField));
65160
- const stateLabel = escapeTerminalTextForDisplay(entry.state.padEnd(maxState));
65161
- const sc = stateColor(entry.state);
65162
- let line = ` ${c.cyan}${shapeLabel}${c.reset} ${c.dim}${fieldLabel}${c.reset} ${sc}${stateLabel}${c.reset}`;
65163
- if (entry.state === "building" && entry.backfillTotal != null && entry.backfillTotal > 0) {
65164
- const pct = Math.round(entry.backfillDone / entry.backfillTotal * 100);
65165
- line += ` ${c.dim}${entry.backfillDone}/${entry.backfillTotal} (${pct}%)${c.reset}`;
65166
- } else if (entry.state === "building") {
65167
- line += ` ${c.dim}${entry.backfillDone} rows${c.reset}`;
65168
- } else if (entry.state === "failed" && entry.failureReason) {
65169
- line += ` ${c.dim}${escapeTerminalTextForDisplay(entry.failureReason)}${c.reset}`;
65170
- }
65171
- ctx.out(line);
65172
- }
65173
- ctx.out("");
65174
- }
65507
+ renderIndexedFields(ctx.out, c, indexedFieldsPublic);
65175
65508
  }
65176
65509
  });
65177
65510
  };
@@ -65369,7 +65702,8 @@ var REPO_DOMAIN = defineDomain({
65369
65702
  },
65370
65703
  subdomains: {
65371
65704
  checkpoint: CHECKPOINT_SUBDOMAIN,
65372
- content: CONTENT_SUBDOMAIN
65705
+ content: CONTENT_SUBDOMAIN,
65706
+ index: INDEX_SUBDOMAIN
65373
65707
  }
65374
65708
  });
65375
65709
 
@@ -65386,13 +65720,13 @@ var FIELD_CONSTRAINTS_NOTES = [
65386
65720
  "Per-type constraint keys (enforced at commit time):",
65387
65721
  ` string: ${keyList(STRING_CONSTRAINT_KEYS)}`,
65388
65722
  ` number: ${keyList(NUMBER_CONSTRAINT_KEYS)}`,
65389
- ` wref: ${keyList(WREF_CONSTRAINT_KEYS)} (target shape name; e.g. "shape": "Player")`,
65723
+ ` wref: ${keyList(WREF_CONSTRAINT_KEYS)} (shape target; binding: ${WREF_BINDING_MODES.join("|")})`,
65390
65724
  ` array: ${keyList(ARRAY_CONSTRAINT_KEYS)} (items is the element type spec)`,
65391
65725
  " boolean: (none)",
65392
65726
  "",
65393
65727
  "See docs.warmhub.ai/data-modeling/shapes#field-constraints for full semantics."
65394
65728
  ];
65395
- var FIELDS_FLAG_DESCRIPTION = "Fields JSON; see Notes for per-type constraint keys (enum, pattern, bounds, shape, items)";
65729
+ var FIELDS_FLAG_DESCRIPTION = "Fields JSON; see Notes for per-type constraint keys (enum, pattern, bounds, shape, binding, items)";
65396
65730
 
65397
65731
  // ../../packages/warmhub-cli/src/domains/shape/history.ts
65398
65732
  var historyFlags3 = {
@@ -65597,11 +65931,43 @@ var handleView7 = async (ctx, { flags, args }) => {
65597
65931
  });
65598
65932
  };
65599
65933
 
65934
+ // ../../packages/warmhub-cli/src/composite-shapes.ts
65935
+ var pendingByContext = new WeakMap;
65936
+ async function capabilitiesFor(ctx) {
65937
+ if (ctx.capabilities)
65938
+ return ctx.capabilities;
65939
+ let pending = pendingByContext.get(ctx);
65940
+ if (!pending) {
65941
+ pending = (async () => {
65942
+ try {
65943
+ return await ctx.client.diagnostics.capabilities();
65944
+ } catch {
65945
+ return;
65946
+ }
65947
+ })();
65948
+ pendingByContext.set(ctx, pending);
65949
+ }
65950
+ const capabilities = await pending;
65951
+ if (capabilities)
65952
+ ctx.capabilities = capabilities;
65953
+ return capabilities;
65954
+ }
65955
+ async function assertCompositeShapesEnabled(ctx, option) {
65956
+ const capabilities = await capabilitiesFor(ctx);
65957
+ if (capabilities?.features?.compositeShapes !== false)
65958
+ return;
65959
+ throw new CliError(2 /* UserInput */, "USER_INPUT", `composite Shapes are not enabled on this backend; ${option} is unavailable`, undefined, "Create the Shape without --compose, or ask an operator to enable WARMHUB_COMPOSITE_SHAPES_WRITE. Removing an existing composition with --clear-composition still works.");
65960
+ }
65961
+
65600
65962
  // ../../packages/warmhub-cli/src/domains/shape/write.ts
65601
65963
  var fieldsFileFlag = flag.string({
65602
65964
  description: "read fields from a JSON object file (portable alternative to inline --fields)"
65603
65965
  });
65604
65966
  var createFlags8 = {
65967
+ compose: flag.string({
65968
+ description: "Shape HEAD to include (repeat for multiple members)",
65969
+ multiple: true
65970
+ }),
65605
65971
  "event-request-id": operationEventRequestIdFlag,
65606
65972
  fields: flag.string({ description: FIELDS_FLAG_DESCRIPTION }),
65607
65973
  file: fieldsFileFlag,
@@ -65610,6 +65976,13 @@ var createFlags8 = {
65610
65976
  })
65611
65977
  };
65612
65978
  var reviseFlags3 = {
65979
+ "clear-composition": flag.boolean({
65980
+ description: "remove every composed Shape"
65981
+ }),
65982
+ compose: flag.string({
65983
+ description: "replace composed Shape HEADs (repeat for multiple members)",
65984
+ multiple: true
65985
+ }),
65613
65986
  "event-request-id": operationEventRequestIdFlag,
65614
65987
  fields: flag.string({ description: FIELDS_FLAG_DESCRIPTION }),
65615
65988
  file: fieldsFileFlag,
@@ -65702,6 +66075,10 @@ var handleCreate7 = async (ctx, { flags, args }) => {
65702
66075
  const opts = { eventRequestId };
65703
66076
  if (flags.description !== undefined)
65704
66077
  opts.description = flags.description;
66078
+ if (flags.compose !== undefined) {
66079
+ await assertCompositeShapesEnabled(ctx, "--compose");
66080
+ opts.composes = flags.compose;
66081
+ }
65705
66082
  const response = await ctx.client.shape.create(org, repo2, shapeName, fields, opts);
65706
66083
  const result = shapeChangeFromReceipt(response.receipt);
65707
66084
  writeOutput(ctx, response, () => {
@@ -65724,6 +66101,9 @@ var handleRevise3 = async (ctx, { flags, args }) => {
65724
66101
  missingMessage: "Usage: wh shape revise <name> (--fields '<json>' | --file <path>)",
65725
66102
  example: "wh shape revise Location --file fields.json"
65726
66103
  });
66104
+ if (flags.compose !== undefined && flags["clear-composition"]) {
66105
+ usageError("--compose and --clear-composition cannot be used together", "wh shape revise Location --fields '{}' --clear-composition");
66106
+ }
65727
66107
  const { org, repo: repo2 } = parseOrgRepo(getRepoRef(ctx), ctx.config);
65728
66108
  const c = ctx.colors;
65729
66109
  const previousShape = flags["show-diff"] ? await ctx.client.shape.get(org, repo2, shapeName) : undefined;
@@ -65734,6 +66114,12 @@ var handleRevise3 = async (ctx, { flags, args }) => {
65734
66114
  const opts = { eventRequestId };
65735
66115
  if (flags.description !== undefined)
65736
66116
  opts.description = flags.description;
66117
+ if (flags["clear-composition"]) {
66118
+ opts.composes = [];
66119
+ } else if (flags.compose !== undefined) {
66120
+ await assertCompositeShapesEnabled(ctx, "--compose");
66121
+ opts.composes = flags.compose;
66122
+ }
65737
66123
  const response = await ctx.client.shape.revise(org, repo2, shapeName, newFields, opts);
65738
66124
  const result = shapeChangeFromReceipt(response.receipt);
65739
66125
  let diff;
@@ -65841,6 +66227,7 @@ var SHAPE_DOMAIN = defineDomain({
65841
66227
  examples: [
65842
66228
  `wh shape create GameConfig --repo org/repo --fields '{"x":"number"}'`,
65843
66229
  "wh shape create GameConfig --repo org/repo --file fields.json",
66230
+ "wh shape create AnimalSummary --fields '{}' --compose Animal --compose Summary",
65844
66231
  `wh shape create Player --fields '{"name":{"type":"string","minLength":1,"maxLength":40},"role":{"type":"string","enum":["dm","player"]},"level":{"type":"number","minimum":1,"integer":true},"home":{"type":"wref","shape":"Location"},"tags":{"type":"array","items":"string","minItems":1}}'`
65845
66232
  ],
65846
66233
  notes: [...FIELD_CONSTRAINTS_NOTES],
@@ -67965,7 +68352,7 @@ async function dispatch(ctx) {
67965
68352
  await dispatchDomain(ctx, invocation);
67966
68353
  }
67967
68354
  // ../../packages/warmhub-cli/src/manifest/shared-infra.ts
67968
- var SHARED_INFRA_SHAPES = findSystemComponent(SYSTEM_COMPONENT_ID)?.shapes ?? [];
68355
+ var SHARED_INFRA_SHAPES = findSystemComponent(SYSTEM_COMPONENT_ID)?.shapes.filter((shape) => shape.installInfra === true) ?? [];
67969
68356
  // ../../packages/warmhub-cli/src/parser/binder.ts
67970
68357
  function effectiveSpecs(specs, options) {
67971
68358
  return specs.map((spec) => {
@@ -69363,7 +69750,7 @@ function resolveLogLevel(flagLevel, env) {
69363
69750
  // package.json
69364
69751
  var package_default3 = {
69365
69752
  name: "@warmhub/cli",
69366
- version: "0.116.0",
69753
+ version: "0.118.0",
69367
69754
  private: false,
69368
69755
  type: "module",
69369
69756
  description: "The wh CLI for WarmHub — create repos, commit and query data, and compound knowledge with your AI agents.",
@@ -69988,5 +70375,5 @@ process.exitCode = interceptedExitCode === undefined ? await runPreparedCli(laun
69988
70375
  version: package_default3.version
69989
70376
  }) : interceptedExitCode;
69990
70377
 
69991
- //# debugId=49B7F9EF6B29BE1264756E2164756E21
69992
- //# warmhub-cli-build-info {"cliVersion":"0.116.0","sdkVersion":"0.114.0"}
70378
+ //# debugId=E526A210005F6CCA64756E2164756E21
70379
+ //# warmhub-cli-build-info {"cliVersion":"0.118.0","sdkVersion":"0.116.0"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@warmhub/cli",
3
- "version": "0.116.0",
3
+ "version": "0.118.0",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "description": "The wh CLI for WarmHub — create repos, commit and query data, and compound knowledge with your AI agents.",