@warmhub/cli 0.116.0 → 0.117.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 +317 -68
  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.115.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.",
@@ -46707,7 +46758,8 @@ class WarmHubClient {
46707
46758
  create: async (orgName, repoName, shapeName, fields, opts) => {
46708
46759
  const preflight = shapeDefinitionPreflightError(shapeName, {
46709
46760
  fields,
46710
- ...opts.description !== undefined ? { description: opts.description } : {}
46761
+ ...opts.description !== undefined ? { description: opts.description } : {},
46762
+ ...opts.composes !== undefined ? { composes: opts.composes } : {}
46711
46763
  }, "add");
46712
46764
  if (preflight)
46713
46765
  throw new WarmHubError("VALIDATION_ERROR", preflight);
@@ -46718,7 +46770,8 @@ class WarmHubClient {
46718
46770
  shapeName,
46719
46771
  fields,
46720
46772
  eventRequestId: opts.eventRequestId,
46721
- description: opts.description
46773
+ description: opts.description,
46774
+ composes: opts.composes
46722
46775
  });
46723
46776
  } catch (error51) {
46724
46777
  throw toWarmHubError(error51);
@@ -46727,7 +46780,8 @@ class WarmHubClient {
46727
46780
  revise: async (orgName, repoName, shapeName, newFields, opts) => {
46728
46781
  const preflight = shapeDefinitionPreflightError(shapeName, {
46729
46782
  fields: newFields,
46730
- ...opts.description !== undefined ? { description: opts.description } : {}
46783
+ ...opts.description !== undefined ? { description: opts.description } : {},
46784
+ ...opts.composes !== undefined ? { composes: opts.composes } : {}
46731
46785
  }, "revise");
46732
46786
  if (preflight)
46733
46787
  throw new WarmHubError("VALIDATION_ERROR", preflight);
@@ -46738,7 +46792,8 @@ class WarmHubClient {
46738
46792
  shapeName,
46739
46793
  newFields,
46740
46794
  eventRequestId: opts.eventRequestId,
46741
- description: opts.description
46795
+ description: opts.description,
46796
+ composes: opts.composes
46742
46797
  });
46743
46798
  } catch (error51) {
46744
46799
  throw toWarmHubError(error51);
@@ -47208,6 +47263,8 @@ class WarmHubClient {
47208
47263
  orgName,
47209
47264
  repoName,
47210
47265
  shape: opts?.shape,
47266
+ declaredShape: opts?.declaredShape,
47267
+ includeValidatedShapes: opts?.includeValidatedShapes,
47211
47268
  kind: narrowKind(opts?.kind),
47212
47269
  match: opts?.match,
47213
47270
  dataMode: opts?.dataMode,
@@ -47371,6 +47428,7 @@ class WarmHubClient {
47371
47428
  repoName,
47372
47429
  wref: opts.wref,
47373
47430
  shape: opts.shape,
47431
+ declaredShape: opts.declaredShape,
47374
47432
  about: opts.about,
47375
47433
  includeRetracted: opts.includeRetracted,
47376
47434
  resolveCollections: opts.resolveCollections,
@@ -47447,6 +47505,8 @@ class WarmHubClient {
47447
47505
  orgName,
47448
47506
  repoName,
47449
47507
  shape: opts?.shape,
47508
+ declaredShape: opts?.declaredShape,
47509
+ includeValidatedShapes: opts?.includeValidatedShapes,
47450
47510
  about: opts?.about,
47451
47511
  affirmedAbout: opts?.affirmedAbout,
47452
47512
  kind: narrowKind(opts?.kind),
@@ -47522,6 +47582,7 @@ class WarmHubClient {
47522
47582
  orgName,
47523
47583
  repoName,
47524
47584
  shape: opts?.shape,
47585
+ declaredShape: opts?.declaredShape,
47525
47586
  about: opts?.about,
47526
47587
  affirmedAbout: opts?.affirmedAbout,
47527
47588
  kind: narrowKind(opts?.kind),
@@ -47546,6 +47607,7 @@ class WarmHubClient {
47546
47607
  wref,
47547
47608
  direction: opts?.direction,
47548
47609
  fieldPath: opts?.fieldPath,
47610
+ binding: opts?.binding,
47549
47611
  limit: opts?.limit,
47550
47612
  cursor: opts?.cursor
47551
47613
  });
@@ -47565,6 +47627,8 @@ class WarmHubClient {
47565
47627
  thingHead: async (orgName, repoName, opts, onUpdate) => {
47566
47628
  return this.watchRepoQuery(orgName, repoName, opts?.signal, () => this.thing.head(orgName, repoName, {
47567
47629
  shape: opts?.shape,
47630
+ declaredShape: opts?.declaredShape,
47631
+ includeValidatedShapes: opts?.includeValidatedShapes,
47568
47632
  kind: opts?.kind,
47569
47633
  match: opts?.match,
47570
47634
  dataMode: opts?.dataMode,
@@ -47577,6 +47641,11 @@ class WarmHubClient {
47577
47641
  thingHistory: async (orgName, repoName, opts, onUpdate) => {
47578
47642
  return this.watchRepoQuery(orgName, repoName, opts.signal, () => this.thing.history(orgName, repoName, {
47579
47643
  wref: opts.wref,
47644
+ shape: opts.shape,
47645
+ declaredShape: opts.declaredShape,
47646
+ about: opts.about,
47647
+ resolveCollections: opts.resolveCollections,
47648
+ match: opts.match,
47580
47649
  limit: opts.limit,
47581
47650
  cursor: opts.cursor,
47582
47651
  includeRetracted: opts.includeRetracted
@@ -50679,6 +50748,8 @@ async function checkCompatibility(ctx, domainPath, canonicalVerb, args) {
50679
50748
  if (clientFlags.length > 0)
50680
50749
  capabilities = await probeCapabilities(ctx);
50681
50750
  }
50751
+ if (capabilities)
50752
+ ctx.capabilities = capabilities;
50682
50753
  if (clientFlags.length === 0 || !capabilities)
50683
50754
  return;
50684
50755
  const echoed = capabilities.honoredClientFlags;
@@ -52116,6 +52187,9 @@ function renderWarningLine(out, c, chars, op) {
52116
52187
  return;
52117
52188
  renderUndeclaredFieldsWarning(out, c, chars, op.name, warnings);
52118
52189
  renderCoalescedWrefsWarning(out, c, chars, warnings);
52190
+ for (const entry of warnings.ignoredVersionPins ?? []) {
52191
+ 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)`);
52192
+ }
52119
52193
  for (const warning of warnings.deprecations ?? []) {
52120
52194
  out(` ${c.yellow}${chars.warn}${c.reset} ${escapeInlineTerminalText(warning.shape)} deprecated (de-emphasis milestone ${escapeInlineTerminalText(warning.removalMilestone)}): ${escapeInlineTerminalText(warning.message)}`);
52121
52195
  }
@@ -52236,7 +52310,7 @@ function emitPartialPageHint(ctx, count, _nextCursor, _limit) {
52236
52310
  }
52237
52311
 
52238
52312
  // ../../packages/warmhub-cli/src/domains/commit-output-contract-id.ts
52239
- var COMMIT_SUBMIT_OUTPUT_SCHEMA_ID = "wh.commit.submit.result/v0.3";
52313
+ var COMMIT_SUBMIT_OUTPUT_SCHEMA_ID = "wh.commit.submit.result/v0.4";
52240
52314
  function identifyCommitSubmitOutput(value) {
52241
52315
  if ("schema" in value) {
52242
52316
  if (value.schema === COMMIT_SUBMIT_OUTPUT_SCHEMA_ID) {
@@ -52953,6 +53027,9 @@ var handleCreate2 = async (ctx, { flags, args }) => {
52953
53027
  };
52954
53028
 
52955
53029
  // ../../packages/warmhub-cli/src/domains/thing/render.ts
53030
+ function singularShapeName(result) {
53031
+ return result.shapeName ?? result.shape;
53032
+ }
52956
53033
  function renderHead(out, c, chars, result, org, repo, shape, kind) {
52957
53034
  const items = result.items ?? [];
52958
53035
  const decorations = getResponseDecorations(result);
@@ -52968,6 +53045,12 @@ function renderHead(out, c, chars, result, org, repo, shape, kind) {
52968
53045
  const kl = kindLabel(c, effectiveKind(item.kind ?? "thing", shapeName));
52969
53046
  const retractedTag = item.active === false ? ` ${c.red}[RETRACTED]${c.reset}` : "";
52970
53047
  out(` ${wref} ${kl}${retractedTag}`);
53048
+ if (item.declaredShapes?.length) {
53049
+ out(` ${c.dim}declares:${c.reset} ${refList(c, item.declaredShapes, decorations)}`);
53050
+ }
53051
+ if (item.validatedShapes?.length) {
53052
+ out(` ${c.dim}validates:${c.reset} ${refList(c, item.validatedShapes, decorations)}`);
53053
+ }
52971
53054
  if (item.kind === "assertion" && item.aboutWref) {
52972
53055
  out(` ${c.dim}about:${c.reset} ${refDisplay(c, item.aboutWref, decorations)}`);
52973
53056
  }
@@ -52991,19 +53074,26 @@ function renderHead(out, c, chars, result, org, repo, shape, kind) {
52991
53074
  function renderThing(out, c, result) {
52992
53075
  const decorations = getResponseDecorations(result);
52993
53076
  const wref = result.wref ?? result.name ?? "(unknown)";
52994
- const shapeName = result.shapeName ?? result.shape;
53077
+ const shapeName = singularShapeName(result);
52995
53078
  const displayKind = effectiveKind(result.kind ?? "thing", shapeName);
52996
53079
  const retractedTag = result.active === false ? ` ${c.red}[RETRACTED]${c.reset}` : "";
52997
53080
  out(`${pinnedWref(c, wref, result.version)} ${kindLabel(c, displayKind)}${retractedTag}`);
52998
53081
  out(` ${c.dim}wref:${c.reset} ${escapeTerminalTextForDisplay(wref)}`);
52999
53082
  out(` ${c.dim}version:${c.reset} ${result.version ?? "-"}`);
53000
53083
  out(` ${c.dim}active:${c.reset} ${String(result.active)}`);
53084
+ if (result.declaredShapes?.length) {
53085
+ out(` ${c.dim}declares:${c.reset} ${refList(c, result.declaredShapes, decorations)}`);
53086
+ }
53087
+ if (result.validatedShapes?.length) {
53088
+ out(` ${c.dim}validates:${c.reset} ${refList(c, result.validatedShapes, decorations)}`);
53089
+ }
53001
53090
  if (result.committerWref) {
53002
53091
  out(` ${c.dim}by:${c.reset} ${refDisplay(c, result.committerWref, decorations)}`);
53003
53092
  }
53004
53093
  const aboutWref = result.aboutWref ?? result.about;
53005
- if (aboutWref) {
53006
- out(` ${c.dim}about:${c.reset} ${decoratedRef(c, String(aboutWref), decorations) ?? escapeTerminalTextForDisplay(String(aboutWref))}`);
53094
+ const aboutText = typeof aboutWref === "string" ? aboutWref : JSON.stringify(aboutWref);
53095
+ if (aboutText) {
53096
+ out(` ${c.dim}about:${c.reset} ${decoratedRef(c, aboutText, decorations) ?? escapeTerminalTextForDisplay(aboutText)}`);
53007
53097
  }
53008
53098
  if (result.affirmedWrefs?.length) {
53009
53099
  out(` ${c.dim}affirms:${c.reset} ${refList(c, result.affirmedWrefs, decorations)}`);
@@ -53074,9 +53164,9 @@ function renderGraphValue(out, c, value, indent, decorations) {
53074
53164
  }
53075
53165
  renderGraphNode(out, c, value, indent, decorations);
53076
53166
  }
53077
- function renderGraphNode(out, c, result, indent = "", decorations = undefined) {
53167
+ function renderGraphNode(out, c, result, indent = "", decorations) {
53078
53168
  const wref = result.wref ?? result.name ?? "(unknown)";
53079
- const shapeName = result.shapeName ?? result.shape;
53169
+ const shapeName = singularShapeName(result);
53080
53170
  const displayKind = effectiveKind(result.kind ?? "thing", shapeName);
53081
53171
  out(`${indent}${pinnedWref(c, wref, result.version)} ${kindLabel(c, displayKind)}`);
53082
53172
  if (result.about) {
@@ -53144,6 +53234,12 @@ function renderHistory(out, c, result) {
53144
53234
  const createdOn = ver.metadata?.createdOn;
53145
53235
  const thingCreatedStr = createdOn ? ` ${c.dim}born:${formatTime(createdOn, now)}${c.reset}` : "";
53146
53236
  out(` ${wrefStr} ${op} ${c.dim}${time3}${c.reset}${by}${thingCreatedStr}`);
53237
+ if (ver.declaredShapes?.length) {
53238
+ out(` ${c.dim}declares:${c.reset} ${refList(c, ver.declaredShapes, decorations)}`);
53239
+ }
53240
+ if (ver.validatedShapes?.length) {
53241
+ out(` ${c.dim}validates:${c.reset} ${refList(c, ver.validatedShapes, decorations)}`);
53242
+ }
53147
53243
  const affirmed = ver.affirmedWrefs;
53148
53244
  if (Array.isArray(affirmed) && affirmed.length > 0) {
53149
53245
  out(` ${c.dim}affirms:${c.reset} ${refList(c, affirmed.map(String), decorations)}`);
@@ -53164,7 +53260,8 @@ function renderRefs(out, c, result, wref, direction) {
53164
53260
  const refWref = refDisplay(c, item.wref, decorations, item.version);
53165
53261
  const kl = kindLabel(c, effectiveKind(item.kind ?? "thing", item.shapeName));
53166
53262
  const field = `${c.dim}via ${c.reset}${escapeTerminalTextForDisplay(item.fieldPath ?? "(unknown)")}`;
53167
- out(` ${refWref} ${kl} ${field}`);
53263
+ const binding = item.binding ? ` ${c.dim}${item.binding}${c.reset}` : "";
53264
+ out(` ${refWref} ${kl} ${field}${binding}`);
53168
53265
  }
53169
53266
  out(`${c.dim}${items.length} ref(s)${c.reset}`);
53170
53267
  }
@@ -53240,6 +53337,9 @@ var handleThingGraph = async (ctx, { flags, args }) => {
53240
53337
  // ../../packages/warmhub-cli/src/domains/thing/history.ts
53241
53338
  var historyFlags = {
53242
53339
  shape: flag.string({ description: "Filter by shape" }),
53340
+ "declared-shape": flag.string({
53341
+ description: "Filter by directly declared shape"
53342
+ }),
53243
53343
  limit: flag.number({
53244
53344
  description: "Maximum versions per page (default: 50, max: 500)"
53245
53345
  }),
@@ -53257,6 +53357,7 @@ var handleHistory = async (ctx, { flags, args }) => {
53257
53357
  const wref = args[0];
53258
53358
  const { org, repo } = wref !== undefined && looksLikeDurableId(wref) ? parseOrgRepoOptional(getRepoRef(ctx), ctx.config) : parseOrgRepo(getRepoRef(ctx), ctx.config);
53259
53359
  const shape = flags.shape;
53360
+ const declaredShape = flags["declared-shape"];
53260
53361
  const about = flags.about;
53261
53362
  const limit = flags.limit;
53262
53363
  const cursor = flags.cursor;
@@ -53274,6 +53375,7 @@ var handleHistory = async (ctx, { flags, args }) => {
53274
53375
  const historyOpts = {
53275
53376
  wref,
53276
53377
  shape,
53378
+ declaredShape,
53277
53379
  about,
53278
53380
  includeRetracted,
53279
53381
  resolveCollections,
@@ -53300,23 +53402,28 @@ var handleHistory = async (ctx, { flags, args }) => {
53300
53402
  });
53301
53403
  return;
53302
53404
  }
53303
- const result = all ? await fetchAllHistoryPages(ctx, org, repo, {
53405
+ const fetched = all ? await fetchAllHistoryPages(ctx, org, repo, {
53304
53406
  wref,
53305
53407
  shape,
53408
+ declaredShape,
53306
53409
  about,
53307
53410
  includeRetracted,
53308
53411
  resolveCollections,
53309
53412
  limit: pageLimit,
53310
53413
  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
- });
53414
+ }) : {
53415
+ result: await ctx.client.thing.history(org, repo, {
53416
+ wref,
53417
+ shape,
53418
+ declaredShape,
53419
+ about,
53420
+ includeRetracted,
53421
+ resolveCollections,
53422
+ limit: boundedLimit,
53423
+ cursor
53424
+ })
53425
+ };
53426
+ const { result, refusal } = fetched;
53320
53427
  if (!all && result.nextCursor) {
53321
53428
  emitPartialPageHint(ctx, (result.versions ?? []).length, result.nextCursor, boundedLimit);
53322
53429
  }
@@ -53325,34 +53432,48 @@ var handleHistory = async (ctx, { flags, args }) => {
53325
53432
  nextCursor: result.nextCursor ?? null,
53326
53433
  decorations: getResponseDecorations(result)
53327
53434
  }, () => renderHistory(ctx.out, ctx.colors, result));
53435
+ if (refusal) {
53436
+ ctx.err(`history stopped after ${(result.versions ?? []).length} version(s): the backend refused further refill (${refusal.code}). Narrow the filter to continue.`);
53437
+ throw refusal;
53438
+ }
53328
53439
  };
53329
53440
  async function fetchAllHistoryPages(ctx, org, repo, opts) {
53330
53441
  const versions2 = [];
53331
53442
  let decorations;
53332
53443
  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));
53444
+ let refusal;
53445
+ try {
53446
+ for await (const page of paginatePages2({
53447
+ initialCursor: opts.cursor,
53448
+ fetchPage: (cursor) => ctx.client.thing.history(org, repo, {
53449
+ wref: opts.wref,
53450
+ shape: opts.shape,
53451
+ declaredShape: opts.declaredShape,
53452
+ about: opts.about,
53453
+ includeRetracted: opts.includeRetracted,
53454
+ resolveCollections: opts.resolveCollections,
53455
+ limit: opts.limit,
53456
+ cursor
53457
+ }),
53458
+ title: "Thing history"
53459
+ })) {
53460
+ if (!thing && page.thing)
53461
+ thing = page.thing;
53462
+ versions2.push(...page.versions ?? []);
53463
+ decorations = mergeDecorations(decorations, getResponseDecorations(page));
53464
+ }
53465
+ } catch (error51) {
53466
+ if (!(isWarmHubError(error51) && error51.code === "QUERY_TOO_EXPENSIVE")) {
53467
+ throw error51;
53468
+ }
53469
+ refusal = error51;
53350
53470
  }
53351
- return withDecorations({
53471
+ const result = withDecorations({
53352
53472
  ...thing === undefined ? {} : { thing },
53353
53473
  versions: versions2,
53354
53474
  nextCursor: undefined
53355
53475
  }, decorations);
53476
+ return refusal ? { result, refusal } : { result };
53356
53477
  }
53357
53478
 
53358
53479
  // ../../packages/warmhub-cli/src/domains/thing/lease.ts
@@ -53496,6 +53617,12 @@ function coerceValue(s) {
53496
53617
  // ../../packages/warmhub-cli/src/domains/thing/list.ts
53497
53618
  var headFlags = {
53498
53619
  shape: flag.string({ description: "Filter by shape" }),
53620
+ "declared-shape": flag.string({
53621
+ description: "Filter by directly declared shape"
53622
+ }),
53623
+ "include-validated-shapes": flag.boolean({
53624
+ description: "Include the full certified shape closure"
53625
+ }),
53499
53626
  kind: flag.string({ description: "Filter by kind" }),
53500
53627
  limit: flag.number({
53501
53628
  description: "Max items per page (default: 50, max: 500)"
@@ -53524,6 +53651,8 @@ var headFlags = {
53524
53651
  var handleHead = async (ctx, { flags, args }) => {
53525
53652
  const { org, repo } = parseOrgRepo(getRepoRef(ctx) ?? args[0], ctx.config);
53526
53653
  const shape = flags.shape;
53654
+ const declaredShape = flags["declared-shape"];
53655
+ const includeValidatedShapes = flags["include-validated-shapes"];
53527
53656
  const kind = validateKind(flags.kind);
53528
53657
  const limit = flags.limit;
53529
53658
  const cursor = flags.cursor;
@@ -53538,6 +53667,9 @@ var handleHead = async (ctx, { flags, args }) => {
53538
53667
  usageError("--since-repo-seq cannot be used with --live.", "wh thing list --since-repo-seq 42 --all --format json");
53539
53668
  }
53540
53669
  if (count) {
53670
+ if (includeValidatedShapes) {
53671
+ usageError("--include-validated-shapes cannot be used with --count.", "wh thing list --declared-shape Player --count");
53672
+ }
53541
53673
  if (cursor || all || limit || ctx.liveMode) {
53542
53674
  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
53675
  }
@@ -53546,12 +53678,13 @@ var handleHead = async (ctx, { flags, args }) => {
53546
53678
  validateComponentFilters(componentRef2, strictExclude2, "wh thing list --component acme/veritas");
53547
53679
  return handleCount(ctx, org, repo, {
53548
53680
  shape,
53681
+ declaredShape,
53549
53682
  kind,
53550
53683
  match,
53551
53684
  includeRetracted,
53552
53685
  componentRef: componentRef2,
53553
53686
  excludeComponents: strictExclude2,
53554
- excludeInfraShapes: !strictExclude2 && !shape,
53687
+ excludeInfraShapes: !strictExclude2 && !shape && !declaredShape,
53555
53688
  where: where.length > 0 ? where : undefined,
53556
53689
  ...sinceRepoSeq === undefined ? {} : { sinceRepoSeq }
53557
53690
  });
@@ -53565,13 +53698,15 @@ var handleHead = async (ctx, { flags, args }) => {
53565
53698
  const boundedLimit = Math.min(limit ?? DEFAULT_PAGE_LIMIT, MAX_PAGE_LIMIT);
53566
53699
  const pageLimit = all ? Math.min(limit ?? AUTO_PAGE_LIMIT, MAX_PAGE_LIMIT) : boundedLimit;
53567
53700
  const componentRef = flags.component;
53568
- const hasShape = !!shape;
53701
+ const hasShape = !!shape || !!declaredShape;
53569
53702
  const strictExclude = !!flags["exclude-components"];
53570
53703
  validateComponentFilters(componentRef, strictExclude, "wh thing list --component acme/veritas");
53571
53704
  const excludeComponents = strictExclude;
53572
53705
  const excludeInfraShapes = !strictExclude && !hasShape;
53573
53706
  const headOpts = {
53574
53707
  shape,
53708
+ declaredShape,
53709
+ includeValidatedShapes,
53575
53710
  kind,
53576
53711
  match,
53577
53712
  includeRetracted,
@@ -53608,6 +53743,8 @@ var handleHead = async (ctx, { flags, args }) => {
53608
53743
  const streamJsonl = all && ctx.format === "jsonl";
53609
53744
  const result = all ? await fetchAllHeadPages(ctx, org, repo, {
53610
53745
  shape,
53746
+ declaredShape,
53747
+ includeValidatedShapes,
53611
53748
  kind,
53612
53749
  match,
53613
53750
  includeRetracted,
@@ -53623,6 +53760,8 @@ var handleHead = async (ctx, { flags, args }) => {
53623
53760
  return await ctx.flushOut?.() ?? true;
53624
53761
  } : undefined) : await ctx.client.thing.head(org, repo, {
53625
53762
  shape,
53763
+ declaredShape,
53764
+ includeValidatedShapes,
53626
53765
  kind,
53627
53766
  match,
53628
53767
  includeRetracted,
@@ -53652,6 +53791,8 @@ async function fetchAllHeadPages(ctx, org, repo, opts, onPage) {
53652
53791
  initialCursor: opts.cursor,
53653
53792
  fetchPage: (cursor) => ctx.client.thing.head(org, repo, {
53654
53793
  shape: opts.shape,
53794
+ declaredShape: opts.declaredShape,
53795
+ includeValidatedShapes: opts.includeValidatedShapes,
53655
53796
  kind: opts.kind,
53656
53797
  match: opts.match,
53657
53798
  includeRetracted: opts.includeRetracted,
@@ -53672,6 +53813,12 @@ async function fetchAllHeadPages(ctx, org, repo, opts, onPage) {
53672
53813
  // ../../packages/warmhub-cli/src/domains/thing/query.ts
53673
53814
  var queryFlags = {
53674
53815
  shape: flag.string({ description: "Filter by shape" }),
53816
+ "declared-shape": flag.string({
53817
+ description: "Filter by directly declared shape"
53818
+ }),
53819
+ "include-validated-shapes": flag.boolean({
53820
+ description: "Include the full certified shape closure"
53821
+ }),
53675
53822
  kind: flag.string({ description: "Filter by kind" }),
53676
53823
  about: flag.string({ description: "Filter by about wref" }),
53677
53824
  "affirmed-about": flag.string({
@@ -53710,6 +53857,8 @@ var queryFlags = {
53710
53857
  var handleQuery = async (ctx, { flags }) => {
53711
53858
  const { org, repo } = parseOrgRepo(getRepoRef(ctx), ctx.config);
53712
53859
  const shape = flags.shape;
53860
+ const declaredShape = flags["declared-shape"];
53861
+ const includeValidatedShapes = flags["include-validated-shapes"];
53713
53862
  const about = flags.about;
53714
53863
  const affirmedAbout = flags["affirmed-about"];
53715
53864
  const kind = validateKind(flags.kind);
@@ -53723,7 +53872,7 @@ var handleQuery = async (ctx, { flags }) => {
53723
53872
  const resolveCollections = flags["resolve-collections"];
53724
53873
  const role = parseCollectionRoleFlag(flags.role, "wh thing query --about Player/alice --resolve-collections --role from");
53725
53874
  const componentRef = flags.component;
53726
- const hasShape = !!shape;
53875
+ const hasShape = !!shape || !!declaredShape;
53727
53876
  const strictExclude = !!flags["exclude-components"];
53728
53877
  validateComponentFilters(componentRef, strictExclude, "wh thing query --component acme/veritas");
53729
53878
  const excludeComponents = strictExclude;
@@ -53735,11 +53884,15 @@ var handleQuery = async (ctx, { flags }) => {
53735
53884
  usageError("--since-repo-seq cannot be used with --live.", "wh thing query --since-repo-seq 42 --all --format json");
53736
53885
  }
53737
53886
  if (count) {
53887
+ if (includeValidatedShapes) {
53888
+ usageError("--include-validated-shapes cannot be used with --count.", "wh thing query --declared-shape Player --count");
53889
+ }
53738
53890
  if (cursor || all || limit || ctx.liveMode || role) {
53739
53891
  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
53892
  }
53741
53893
  return handleCount(ctx, org, repo, {
53742
53894
  shape,
53895
+ declaredShape,
53743
53896
  kind,
53744
53897
  match,
53745
53898
  about,
@@ -53766,6 +53919,8 @@ var handleQuery = async (ctx, { flags }) => {
53766
53919
  const pageLimit = all ? Math.min(limit ?? AUTO_PAGE_LIMIT, MAX_PAGE_LIMIT) : boundedLimit;
53767
53920
  const queryOpts = {
53768
53921
  shape,
53922
+ declaredShape,
53923
+ includeValidatedShapes,
53769
53924
  about,
53770
53925
  affirmedAbout,
53771
53926
  kind,
@@ -53806,6 +53961,8 @@ var handleQuery = async (ctx, { flags }) => {
53806
53961
  const streamJsonl = all && ctx.format === "jsonl";
53807
53962
  const result = all ? await fetchAllQueryPages(ctx, org, repo, {
53808
53963
  shape,
53964
+ declaredShape,
53965
+ includeValidatedShapes,
53809
53966
  about,
53810
53967
  affirmedAbout,
53811
53968
  kind,
@@ -53825,6 +53982,8 @@ var handleQuery = async (ctx, { flags }) => {
53825
53982
  return await ctx.flushOut?.() ?? true;
53826
53983
  } : undefined) : await ctx.client.thing.query(org, repo, {
53827
53984
  shape,
53985
+ declaredShape,
53986
+ includeValidatedShapes,
53828
53987
  about,
53829
53988
  affirmedAbout,
53830
53989
  kind,
@@ -53858,6 +54017,8 @@ async function fetchAllQueryPages(ctx, org, repo, opts, onPage) {
53858
54017
  initialCursor: opts.cursor,
53859
54018
  fetchPage: (cursor) => ctx.client.thing.query(org, repo, {
53860
54019
  shape: opts.shape,
54020
+ declaredShape: opts.declaredShape,
54021
+ includeValidatedShapes: opts.includeValidatedShapes,
53861
54022
  about: opts.about,
53862
54023
  affirmedAbout: opts.affirmedAbout,
53863
54024
  kind: opts.kind,
@@ -53891,6 +54052,12 @@ function renderQueryResults(out, c, result) {
53891
54052
  const kl = kindLabel(c, effectiveKind(item.kind ?? "thing", shapeName));
53892
54053
  const retractedTag = item.active === false ? ` ${c.red}[RETRACTED]${c.reset}` : "";
53893
54054
  out(` ${wref} ${kl}${retractedTag}`);
54055
+ if (item.declaredShapes?.length) {
54056
+ out(` ${c.dim}declares:${c.reset} ${refList(c, item.declaredShapes, decorations)}`);
54057
+ }
54058
+ if (item.validatedShapes?.length) {
54059
+ out(` ${c.dim}validates:${c.reset} ${refList(c, item.validatedShapes, decorations)}`);
54060
+ }
53894
54061
  if (item.roles?.length) {
53895
54062
  out(` ${c.dim}roles:${c.reset} ${item.roles.join(", ")}`);
53896
54063
  }
@@ -53914,16 +54081,22 @@ var refsFlags = {
53914
54081
  description: "Show outbound refs (what this target references)"
53915
54082
  }),
53916
54083
  field: flag.string({ description: "Filter by field path (inbound only)" }),
54084
+ binding: flag.string({
54085
+ description: "Keep only edges with this binding: identity (follows the Thing) or versioned (pinned to one version)"
54086
+ }),
53917
54087
  limit: flag.number({
53918
54088
  description: "Max items per page (default: 50, max: 500)"
53919
54089
  }),
53920
54090
  cursor: flag.string({ description: "Opaque pagination cursor" }),
53921
54091
  all: flag.boolean({ description: "Fetch all pages" })
53922
54092
  };
54093
+ function isRefsBinding(value) {
54094
+ return value === "identity" || value === "versioned";
54095
+ }
53923
54096
  var handleRefs = async (ctx, { flags, args }) => {
53924
54097
  const wref = args[0];
53925
54098
  if (!wref) {
53926
- usageError("Usage: wh thing refs <wref> [--inbound|--outbound] [--field FIELD] [--limit N]", "wh thing refs Loc/player");
54099
+ usageError("Usage: wh thing refs <wref> [--inbound|--outbound] [--field FIELD] [--binding identity|versioned] [--limit N]", "wh thing refs Loc/player");
53927
54100
  }
53928
54101
  const { org, repo } = looksLikeDurableId(wref) ? parseOrgRepoOptional(getRepoRef(ctx), ctx.config) : parseOrgRepo(getRepoRef(ctx), ctx.config);
53929
54102
  if (flags.inbound && flags.outbound) {
@@ -53933,10 +54106,14 @@ var handleRefs = async (ctx, { flags, args }) => {
53933
54106
  if (direction === "outbound" && flags.field) {
53934
54107
  usageError("--field is only supported for inbound refs", "wh thing refs Loc/player --field target");
53935
54108
  }
54109
+ const binding = flags.binding;
54110
+ if (binding !== undefined && !isRefsBinding(binding)) {
54111
+ usageError("--binding must be identity or versioned", "wh thing refs Loc/player --binding identity");
54112
+ }
53936
54113
  const limit = flags.limit;
53937
54114
  const cursor = flags.cursor;
53938
54115
  const all = flags.all;
53939
- const refsQueryIsNarrowed = Boolean(flags.field || cursor);
54116
+ const refsQueryIsNarrowed = Boolean(flags.field || binding || cursor);
53940
54117
  if (cursor && !limit) {
53941
54118
  usageError("Usage: wh thing refs <wref> [--limit N] [--cursor TOKEN]", "wh thing refs Loc/player --limit 50 --cursor <token>");
53942
54119
  }
@@ -53945,6 +54122,7 @@ var handleRefs = async (ctx, { flags, args }) => {
53945
54122
  const fetchPage = async (c) => ctx.client.thing.refs(org, repo, wref, {
53946
54123
  direction,
53947
54124
  fieldPath: flags.field,
54125
+ binding,
53948
54126
  limit: pageLimit,
53949
54127
  cursor: c
53950
54128
  });
@@ -57056,7 +57234,7 @@ var createFlags3 = {
57056
57234
  };
57057
57235
 
57058
57236
  // ../../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";
57237
+ var COMMIT_SUBMIT_STREAM_ROW_SCHEMA_ID = "wh.commit.submit.stream.row/v0.3";
57060
57238
  function identify(row) {
57061
57239
  if ("schema" in row) {
57062
57240
  throw new Error("Streaming submission row already defines a schema field");
@@ -61720,7 +61898,7 @@ var DOCTOR_DOMAIN = defineDomain({
61720
61898
  var createFlags5 = {
61721
61899
  key: flag.string({ description: "issuer-scoped idempotency key" }),
61722
61900
  coverage: flag.string({
61723
- description: "inline coverage JSON ({include, exclude?})"
61901
+ description: "inline coverage JSON ({paths, shapes?, shapeless?}; the field axis exists in the grammar but is not servable yet)"
61724
61902
  }),
61725
61903
  view: flag.string({
61726
61904
  description: "View backing coverage instead (View/NAME or View/NAME@vN)"
@@ -61741,7 +61919,7 @@ function repo(ctx) {
61741
61919
  return parseOrgRepo(getRepoRef(ctx), ctx.config);
61742
61920
  }
61743
61921
  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/**"]}'`;
61922
+ var CREATE_EXAMPLE = `wh grant create component acme/indexer --key provision --op things:read --coverage '{"paths":{"include":["**"]},"shapes":["THING_DURABLE_ID"]}'`;
61745
61923
  function parseRecipient(kind, name) {
61746
61924
  switch (kind) {
61747
61925
  case "member":
@@ -61755,6 +61933,7 @@ function parseRecipient(kind, name) {
61755
61933
  };
61756
61934
  default:
61757
61935
  usageError("Grant recipient kind must be member, pat, or component.", CREATE_EXAMPLE);
61936
+ throw new Error("usageError must throw");
61758
61937
  }
61759
61938
  }
61760
61939
  function isPatternList(value) {
@@ -61762,12 +61941,24 @@ function isPatternList(value) {
61762
61941
  }
61763
61942
  function parseCoverage(raw) {
61764
61943
  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);
61944
+ const paths = candidate.paths !== null && typeof candidate.paths === "object" && !Array.isArray(candidate.paths) ? candidate.paths : candidate;
61945
+ if (!isPatternList(paths.include) || paths.include.length === 0) {
61946
+ 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
61947
  }
61768
- if (candidate.exclude !== undefined && !isPatternList(candidate.exclude)) {
61948
+ if (paths.exclude !== undefined && !isPatternList(paths.exclude)) {
61769
61949
  usageError("--coverage exclude must be an array of patterns when present.", CREATE_EXAMPLE);
61770
61950
  }
61951
+ if ("paths" in candidate) {
61952
+ if (candidate.shapes !== undefined && !isPatternList(candidate.shapes)) {
61953
+ usageError("--coverage shapes must be an array of durable Shape ids.", CREATE_EXAMPLE);
61954
+ }
61955
+ if (candidate.fields !== undefined && !isPatternList(candidate.fields)) {
61956
+ usageError("--coverage fields must be an array of field keys.", CREATE_EXAMPLE);
61957
+ }
61958
+ if (candidate.shapeless !== undefined && typeof candidate.shapeless !== "boolean") {
61959
+ usageError("--coverage shapeless must be a boolean.", CREATE_EXAMPLE);
61960
+ }
61961
+ }
61771
61962
  return candidate;
61772
61963
  }
61773
61964
  var handleCreate4 = async (ctx, { args, flags }) => {
@@ -62715,7 +62906,7 @@ var ORG_DOMAIN = defineDomain({
62715
62906
  });
62716
62907
 
62717
62908
  // ../../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";
62909
+ 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
62910
 
62720
62911
  // ../../packages/warmhub-cli/src/domains/prime.ts
62721
62912
  function buildMarkdown(config2) {
@@ -63101,6 +63292,8 @@ class StreamingByteReader {
63101
63292
  return;
63102
63293
  }
63103
63294
  const head = this.#queue[0];
63295
+ if (!head)
63296
+ return;
63104
63297
  const available = head.byteLength - this.#queueOffset;
63105
63298
  const length = Math.min(limit, available);
63106
63299
  const result = head.subarray(this.#queueOffset, this.#queueOffset + length);
@@ -63116,7 +63309,10 @@ class StreamingByteReader {
63116
63309
  if (bytes.byteLength === 0)
63117
63310
  return;
63118
63311
  if (this.#queueOffset > 0) {
63119
- const current = this.#queue[0].subarray(this.#queueOffset);
63312
+ const head = this.#queue[0];
63313
+ if (!head)
63314
+ throw new Error("archive reader queue is inconsistent");
63315
+ const current = head.subarray(this.#queueOffset);
63120
63316
  this.#queue[0] = current;
63121
63317
  this.#queueOffset = 0;
63122
63318
  }
@@ -65386,13 +65582,13 @@ var FIELD_CONSTRAINTS_NOTES = [
65386
65582
  "Per-type constraint keys (enforced at commit time):",
65387
65583
  ` string: ${keyList(STRING_CONSTRAINT_KEYS)}`,
65388
65584
  ` number: ${keyList(NUMBER_CONSTRAINT_KEYS)}`,
65389
- ` wref: ${keyList(WREF_CONSTRAINT_KEYS)} (target shape name; e.g. "shape": "Player")`,
65585
+ ` wref: ${keyList(WREF_CONSTRAINT_KEYS)} (shape target; binding: ${WREF_BINDING_MODES.join("|")})`,
65390
65586
  ` array: ${keyList(ARRAY_CONSTRAINT_KEYS)} (items is the element type spec)`,
65391
65587
  " boolean: (none)",
65392
65588
  "",
65393
65589
  "See docs.warmhub.ai/data-modeling/shapes#field-constraints for full semantics."
65394
65590
  ];
65395
- var FIELDS_FLAG_DESCRIPTION = "Fields JSON; see Notes for per-type constraint keys (enum, pattern, bounds, shape, items)";
65591
+ var FIELDS_FLAG_DESCRIPTION = "Fields JSON; see Notes for per-type constraint keys (enum, pattern, bounds, shape, binding, items)";
65396
65592
 
65397
65593
  // ../../packages/warmhub-cli/src/domains/shape/history.ts
65398
65594
  var historyFlags3 = {
@@ -65597,11 +65793,43 @@ var handleView7 = async (ctx, { flags, args }) => {
65597
65793
  });
65598
65794
  };
65599
65795
 
65796
+ // ../../packages/warmhub-cli/src/composite-shapes.ts
65797
+ var pendingByContext = new WeakMap;
65798
+ async function capabilitiesFor(ctx) {
65799
+ if (ctx.capabilities)
65800
+ return ctx.capabilities;
65801
+ let pending = pendingByContext.get(ctx);
65802
+ if (!pending) {
65803
+ pending = (async () => {
65804
+ try {
65805
+ return await ctx.client.diagnostics.capabilities();
65806
+ } catch {
65807
+ return;
65808
+ }
65809
+ })();
65810
+ pendingByContext.set(ctx, pending);
65811
+ }
65812
+ const capabilities = await pending;
65813
+ if (capabilities)
65814
+ ctx.capabilities = capabilities;
65815
+ return capabilities;
65816
+ }
65817
+ async function assertCompositeShapesEnabled(ctx, option) {
65818
+ const capabilities = await capabilitiesFor(ctx);
65819
+ if (capabilities?.features?.compositeShapes !== false)
65820
+ return;
65821
+ 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.");
65822
+ }
65823
+
65600
65824
  // ../../packages/warmhub-cli/src/domains/shape/write.ts
65601
65825
  var fieldsFileFlag = flag.string({
65602
65826
  description: "read fields from a JSON object file (portable alternative to inline --fields)"
65603
65827
  });
65604
65828
  var createFlags8 = {
65829
+ compose: flag.string({
65830
+ description: "Shape HEAD to include (repeat for multiple members)",
65831
+ multiple: true
65832
+ }),
65605
65833
  "event-request-id": operationEventRequestIdFlag,
65606
65834
  fields: flag.string({ description: FIELDS_FLAG_DESCRIPTION }),
65607
65835
  file: fieldsFileFlag,
@@ -65610,6 +65838,13 @@ var createFlags8 = {
65610
65838
  })
65611
65839
  };
65612
65840
  var reviseFlags3 = {
65841
+ "clear-composition": flag.boolean({
65842
+ description: "remove every composed Shape"
65843
+ }),
65844
+ compose: flag.string({
65845
+ description: "replace composed Shape HEADs (repeat for multiple members)",
65846
+ multiple: true
65847
+ }),
65613
65848
  "event-request-id": operationEventRequestIdFlag,
65614
65849
  fields: flag.string({ description: FIELDS_FLAG_DESCRIPTION }),
65615
65850
  file: fieldsFileFlag,
@@ -65702,6 +65937,10 @@ var handleCreate7 = async (ctx, { flags, args }) => {
65702
65937
  const opts = { eventRequestId };
65703
65938
  if (flags.description !== undefined)
65704
65939
  opts.description = flags.description;
65940
+ if (flags.compose !== undefined) {
65941
+ await assertCompositeShapesEnabled(ctx, "--compose");
65942
+ opts.composes = flags.compose;
65943
+ }
65705
65944
  const response = await ctx.client.shape.create(org, repo2, shapeName, fields, opts);
65706
65945
  const result = shapeChangeFromReceipt(response.receipt);
65707
65946
  writeOutput(ctx, response, () => {
@@ -65724,6 +65963,9 @@ var handleRevise3 = async (ctx, { flags, args }) => {
65724
65963
  missingMessage: "Usage: wh shape revise <name> (--fields '<json>' | --file <path>)",
65725
65964
  example: "wh shape revise Location --file fields.json"
65726
65965
  });
65966
+ if (flags.compose !== undefined && flags["clear-composition"]) {
65967
+ usageError("--compose and --clear-composition cannot be used together", "wh shape revise Location --fields '{}' --clear-composition");
65968
+ }
65727
65969
  const { org, repo: repo2 } = parseOrgRepo(getRepoRef(ctx), ctx.config);
65728
65970
  const c = ctx.colors;
65729
65971
  const previousShape = flags["show-diff"] ? await ctx.client.shape.get(org, repo2, shapeName) : undefined;
@@ -65734,6 +65976,12 @@ var handleRevise3 = async (ctx, { flags, args }) => {
65734
65976
  const opts = { eventRequestId };
65735
65977
  if (flags.description !== undefined)
65736
65978
  opts.description = flags.description;
65979
+ if (flags["clear-composition"]) {
65980
+ opts.composes = [];
65981
+ } else if (flags.compose !== undefined) {
65982
+ await assertCompositeShapesEnabled(ctx, "--compose");
65983
+ opts.composes = flags.compose;
65984
+ }
65737
65985
  const response = await ctx.client.shape.revise(org, repo2, shapeName, newFields, opts);
65738
65986
  const result = shapeChangeFromReceipt(response.receipt);
65739
65987
  let diff;
@@ -65841,6 +66089,7 @@ var SHAPE_DOMAIN = defineDomain({
65841
66089
  examples: [
65842
66090
  `wh shape create GameConfig --repo org/repo --fields '{"x":"number"}'`,
65843
66091
  "wh shape create GameConfig --repo org/repo --file fields.json",
66092
+ "wh shape create AnimalSummary --fields '{}' --compose Animal --compose Summary",
65844
66093
  `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
66094
  ],
65846
66095
  notes: [...FIELD_CONSTRAINTS_NOTES],
@@ -67965,7 +68214,7 @@ async function dispatch(ctx) {
67965
68214
  await dispatchDomain(ctx, invocation);
67966
68215
  }
67967
68216
  // ../../packages/warmhub-cli/src/manifest/shared-infra.ts
67968
- var SHARED_INFRA_SHAPES = findSystemComponent(SYSTEM_COMPONENT_ID)?.shapes ?? [];
68217
+ var SHARED_INFRA_SHAPES = findSystemComponent(SYSTEM_COMPONENT_ID)?.shapes.filter((shape) => shape.installInfra === true) ?? [];
67969
68218
  // ../../packages/warmhub-cli/src/parser/binder.ts
67970
68219
  function effectiveSpecs(specs, options) {
67971
68220
  return specs.map((spec) => {
@@ -69363,7 +69612,7 @@ function resolveLogLevel(flagLevel, env) {
69363
69612
  // package.json
69364
69613
  var package_default3 = {
69365
69614
  name: "@warmhub/cli",
69366
- version: "0.116.0",
69615
+ version: "0.117.0",
69367
69616
  private: false,
69368
69617
  type: "module",
69369
69618
  description: "The wh CLI for WarmHub — create repos, commit and query data, and compound knowledge with your AI agents.",
@@ -69988,5 +70237,5 @@ process.exitCode = interceptedExitCode === undefined ? await runPreparedCli(laun
69988
70237
  version: package_default3.version
69989
70238
  }) : interceptedExitCode;
69990
70239
 
69991
- //# debugId=49B7F9EF6B29BE1264756E2164756E21
69992
- //# warmhub-cli-build-info {"cliVersion":"0.116.0","sdkVersion":"0.114.0"}
70240
+ //# debugId=A07541AC8954FD7B64756E2164756E21
70241
+ //# warmhub-cli-build-info {"cliVersion":"0.117.0","sdkVersion":"0.115.0"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@warmhub/cli",
3
- "version": "0.116.0",
3
+ "version": "0.117.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.",