@warmhub/cli 0.68.0 → 0.70.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 +189 -650
  2. package/package.json +1 -1
package/dist/wh.js CHANGED
@@ -18618,6 +18618,26 @@ function stableJsonEquals(left, right) {
18618
18618
  return stableJson(left) === stableJson(right);
18619
18619
  }
18620
18620
 
18621
+ // ../../packages/rules/src/subscribable-events.ts
18622
+ var COMMIT_EVENT_TYPE = "commit";
18623
+ var REPO_RENAMED_EVENT_TYPE = "repo.renamed";
18624
+ var ORG_RENAMED_EVENT_TYPE = "org.renamed";
18625
+ var THING_RENAMED_EVENT_TYPE = "thing.renamed";
18626
+ var SHAPE_RENAMED_EVENT_TYPE = "shape.renamed";
18627
+ var SUBSCRIBABLE_EVENT_TYPES = [
18628
+ COMMIT_EVENT_TYPE,
18629
+ REPO_RENAMED_EVENT_TYPE,
18630
+ ORG_RENAMED_EVENT_TYPE,
18631
+ THING_RENAMED_EVENT_TYPE,
18632
+ SHAPE_RENAMED_EVENT_TYPE
18633
+ ];
18634
+ var REPO_SCOPED_EVENT_TYPES = [
18635
+ COMMIT_EVENT_TYPE,
18636
+ REPO_RENAMED_EVENT_TYPE,
18637
+ THING_RENAMED_EVENT_TYPE,
18638
+ SHAPE_RENAMED_EVENT_TYPE
18639
+ ];
18640
+
18621
18641
  // ../../packages/rules/src/component-install.ts
18622
18642
  function manifestShapeData(shape) {
18623
18643
  const data = { fields: shape.fields };
@@ -19168,6 +19188,24 @@ function validateCredential(cred, i, errors) {
19168
19188
  }
19169
19189
  validateProvisioning(cred, path, errors);
19170
19190
  }
19191
+ function validateEventTrigger(trigger, path, errors) {
19192
+ const event = trigger.event;
19193
+ if (event !== undefined) {
19194
+ if (typeof event !== "string" || !REPO_SCOPED_EVENT_TYPES.includes(event)) {
19195
+ errors.push(`${path}.event must be one of: ${REPO_SCOPED_EVENT_TYPES.join(", ")}`);
19196
+ return;
19197
+ }
19198
+ }
19199
+ if (event === undefined || event === COMMIT_EVENT_TYPE) {
19200
+ requireString(trigger, "shape", path, errors);
19201
+ return;
19202
+ }
19203
+ for (const field of ["shape", "filter"]) {
19204
+ if (trigger[field] !== undefined) {
19205
+ errors.push(`${path}.${field} is not valid for a "${event}" trigger — metadata events have no shape or filter`);
19206
+ }
19207
+ }
19208
+ }
19171
19209
  function validateSubscription(sub, i, errors) {
19172
19210
  const path = `manifest.subscriptions[${i}]`;
19173
19211
  if (!isObject2(sub)) {
@@ -19188,7 +19226,7 @@ function validateSubscription(sub, i, errors) {
19188
19226
  errors.push(`${path}.trigger must be an object`);
19189
19227
  } else {
19190
19228
  if (sub.trigger.kind === "event") {
19191
- requireString(sub.trigger, "shape", `${path}.trigger`, errors);
19229
+ validateEventTrigger(sub.trigger, `${path}.trigger`, errors);
19192
19230
  } else if (sub.trigger.kind === "cron") {
19193
19231
  errors.push(`${path}.trigger.kind "cron" is no longer supported; cron subscriptions were removed from the public surface — use an "event" trigger`);
19194
19232
  } else {
@@ -19407,7 +19445,7 @@ function validateManifestSemantics(manifest) {
19407
19445
  ]);
19408
19446
  const knownSeedShapes = new Set([...shapeNames, "ComponentConfig"]);
19409
19447
  for (const sub of manifest.subscriptions) {
19410
- if (sub.trigger.kind === "event" && !knownSubscriptionTriggerShapes.has(sub.trigger.shape)) {
19448
+ if (sub.trigger.kind === "event" && sub.trigger.shape !== undefined && !knownSubscriptionTriggerShapes.has(sub.trigger.shape)) {
19411
19449
  findings.push({
19412
19450
  level: "error",
19413
19451
  code: "MISSING_SUBSCRIPTION_TRIGGER_SHAPE_REF",
@@ -19592,336 +19630,6 @@ var PUBLIC_ORG_PERMISSIONS = new Set([
19592
19630
  "org:read",
19593
19631
  "components:read"
19594
19632
  ]);
19595
- // ../../packages/rules/src/platform-status-constants.ts
19596
- var PLATFORM_STATUS_CATALOG_SHAPE = "PlatformStatusCatalog";
19597
- var PLATFORM_STATUS_CATALOG_NAME = "main";
19598
- var PLATFORM_STATUS_CATALOG_WREF = `${PLATFORM_STATUS_CATALOG_SHAPE}/${PLATFORM_STATUS_CATALOG_NAME}`;
19599
- var PLATFORM_STATUS_STATUSES = [
19600
- {
19601
- key: "available",
19602
- label: "Available",
19603
- description: "Works as expected."
19604
- },
19605
- {
19606
- key: "degraded",
19607
- label: "Degraded",
19608
- description: "Works with known caveats or partial reliability."
19609
- },
19610
- {
19611
- key: "unavailable",
19612
- label: "Unavailable",
19613
- description: "Exists in code but is broken or blocked."
19614
- },
19615
- {
19616
- key: "not_yet_built",
19617
- label: "Not Yet Built",
19618
- description: "This feature-surface combination does not exist yet."
19619
- },
19620
- {
19621
- key: "unknown",
19622
- label: "Unknown",
19623
- description: "Has not been assessed yet."
19624
- }
19625
- ];
19626
- var PLATFORM_STATUS_OBSERVATION_SOURCES = [
19627
- "probe",
19628
- "code_inventory",
19629
- "issue_mining",
19630
- "manual"
19631
- ];
19632
- var PLATFORM_STATUS_OBSERVATION_KINDS = [
19633
- "surface_present",
19634
- "surface_missing",
19635
- "probe_pass",
19636
- "probe_fail",
19637
- "issue_linked",
19638
- "manual_assessment"
19639
- ];
19640
- var PLATFORM_STATUS_PROBE_ARTIFACT_KINDS = [
19641
- "evidence",
19642
- "note",
19643
- "step",
19644
- "workflow_run",
19645
- "issue"
19646
- ];
19647
- // ../../packages/rules/src/platform-status-field-specs.ts
19648
- var issueFields = {
19649
- number: {
19650
- type: "number",
19651
- integer: true,
19652
- description: "GitHub issue number."
19653
- },
19654
- title: {
19655
- type: "string",
19656
- description: "GitHub issue title."
19657
- },
19658
- oneLineSummary: {
19659
- type: "string",
19660
- description: "One-line summary of the issue impact."
19661
- }
19662
- };
19663
- var dimensionFields = {
19664
- slug: {
19665
- type: "string",
19666
- description: "Stable slug used in thing names and programmatic queries."
19667
- },
19668
- label: {
19669
- type: "string",
19670
- description: "Human-readable label."
19671
- },
19672
- description: {
19673
- type: "string",
19674
- description: "Human-readable description."
19675
- },
19676
- "url?": {
19677
- type: "string",
19678
- description: "Optional canonical URL for this environment."
19679
- }
19680
- };
19681
- var PLATFORM_STATUS_CATALOG_FIELDS = {
19682
- schemaVersion: {
19683
- type: "number",
19684
- integer: true,
19685
- description: "Schema version for the platform status catalog."
19686
- },
19687
- title: {
19688
- type: "string",
19689
- description: "Display title for the status board."
19690
- },
19691
- orgName: {
19692
- type: "string",
19693
- description: "Owning organization for the status repo."
19694
- },
19695
- repoName: {
19696
- type: "string",
19697
- description: "Repository name for the status repo."
19698
- },
19699
- sourceIssueNumber: {
19700
- type: "number",
19701
- integer: true,
19702
- description: "Source GitHub issue number for this board."
19703
- },
19704
- sourceIssueUrl: {
19705
- type: "string",
19706
- description: "Source GitHub issue URL for this board."
19707
- },
19708
- features: [dimensionFields],
19709
- surfaces: [dimensionFields],
19710
- environments: [dimensionFields],
19711
- statuses: [
19712
- {
19713
- key: {
19714
- type: "string",
19715
- enum: PLATFORM_STATUS_STATUSES.map((status) => status.key),
19716
- description: "Stable status key."
19717
- },
19718
- label: {
19719
- type: "string",
19720
- description: "Human-readable label for the status."
19721
- },
19722
- description: {
19723
- type: "string",
19724
- description: "Human-readable definition of the status."
19725
- }
19726
- }
19727
- ],
19728
- updatedAt: {
19729
- type: "number",
19730
- integer: true,
19731
- description: "Timestamp when the catalog was last updated."
19732
- },
19733
- "notes?": {
19734
- type: "string",
19735
- description: "Optional operator notes for the board as a whole."
19736
- }
19737
- };
19738
- var PLATFORM_STATUS_CELL_FIELDS = {
19739
- feature: {
19740
- type: "string",
19741
- description: "Feature slug from the catalog."
19742
- },
19743
- surface: {
19744
- type: "string",
19745
- description: "Surface slug from the catalog."
19746
- },
19747
- environment: {
19748
- type: "string",
19749
- description: "Environment slug from the catalog."
19750
- },
19751
- status: {
19752
- type: "string",
19753
- enum: PLATFORM_STATUS_STATUSES.map((status) => status.key),
19754
- description: "Current readiness state for this matrix cell."
19755
- },
19756
- since: {
19757
- type: "number",
19758
- integer: true,
19759
- description: "Timestamp when this status last changed."
19760
- },
19761
- lastVerified: {
19762
- type: "number",
19763
- integer: true,
19764
- description: "Timestamp when this cell was last verified."
19765
- },
19766
- verifiedBy: {
19767
- type: "string",
19768
- enum: ["probe", "code_inventory", "issue_mining", "manual"],
19769
- description: "Verification source for the latest assessment."
19770
- },
19771
- knownIssues: [issueFields],
19772
- caveats: [
19773
- {
19774
- type: "string",
19775
- description: "Human caveat describing a limitation or workaround."
19776
- }
19777
- ],
19778
- "notes?": {
19779
- type: "string",
19780
- description: "Optional free-form notes for this cell."
19781
- },
19782
- "issueMiningBaseline?": {
19783
- status: {
19784
- type: "string",
19785
- enum: PLATFORM_STATUS_STATUSES.map((status) => status.key),
19786
- description: "Cell status before issue mining temporarily degraded it."
19787
- },
19788
- since: {
19789
- type: "number",
19790
- integer: true,
19791
- description: "Original status-change timestamp before issue mining."
19792
- },
19793
- lastVerified: {
19794
- type: "number",
19795
- integer: true,
19796
- description: "Original verification timestamp before issue mining."
19797
- },
19798
- verifiedBy: {
19799
- type: "string",
19800
- enum: ["probe", "code_inventory", "issue_mining", "manual"],
19801
- description: "Original verifier before issue mining."
19802
- },
19803
- knownIssues: [issueFields],
19804
- caveats: [
19805
- {
19806
- type: "string",
19807
- description: "Original caveats before issue mining."
19808
- }
19809
- ],
19810
- "notes?": {
19811
- type: "string",
19812
- description: "Original notes before issue mining."
19813
- }
19814
- }
19815
- };
19816
- var PLATFORM_STATUS_OBSERVATION_FIELDS = {
19817
- cell: {
19818
- type: "wref",
19819
- description: "Target PlatformStatusCell/<feature>/<surface>/<environment> wref."
19820
- },
19821
- feature: {
19822
- type: "string",
19823
- description: "Feature slug from the catalog."
19824
- },
19825
- surface: {
19826
- type: "string",
19827
- description: "Surface slug from the catalog."
19828
- },
19829
- environment: {
19830
- type: "string",
19831
- description: "Environment slug from the catalog."
19832
- },
19833
- source: {
19834
- type: "string",
19835
- enum: [...PLATFORM_STATUS_OBSERVATION_SOURCES],
19836
- description: "Producer of this observation."
19837
- },
19838
- kind: {
19839
- type: "string",
19840
- enum: [...PLATFORM_STATUS_OBSERVATION_KINDS],
19841
- description: "Observation kind within the status pipeline."
19842
- },
19843
- observedAt: {
19844
- type: "number",
19845
- integer: true,
19846
- description: "Timestamp when this observation was recorded."
19847
- },
19848
- summary: {
19849
- type: "string",
19850
- description: "One-line summary of the observation."
19851
- },
19852
- evidence: [
19853
- {
19854
- type: "string",
19855
- description: "Supporting evidence path, command, or URL."
19856
- }
19857
- ],
19858
- "statusHint?": {
19859
- type: "string",
19860
- enum: PLATFORM_STATUS_STATUSES.map((status) => status.key),
19861
- description: "Optional status implication suggested by this observation alone."
19862
- },
19863
- "notes?": {
19864
- type: "string",
19865
- description: "Optional free-form notes for this observation."
19866
- }
19867
- };
19868
- var PLATFORM_STATUS_PROBE_ARTIFACT_FIELDS = {
19869
- run: {
19870
- type: "wref",
19871
- description: "Target PlatformStatusProbeRun wref."
19872
- },
19873
- cell: {
19874
- type: "wref",
19875
- description: "Target PlatformStatusCell/<feature>/<surface>/<environment> wref."
19876
- },
19877
- runId: {
19878
- type: "string",
19879
- description: "Shared batch run identifier for this probe execution."
19880
- },
19881
- probeId: {
19882
- type: "string",
19883
- description: "Stable probe definition identifier."
19884
- },
19885
- feature: {
19886
- type: "string",
19887
- description: "Feature slug from the catalog."
19888
- },
19889
- surface: {
19890
- type: "string",
19891
- description: "Surface slug from the catalog."
19892
- },
19893
- environment: {
19894
- type: "string",
19895
- description: "Environment slug from the catalog."
19896
- },
19897
- observedAt: {
19898
- type: "number",
19899
- integer: true,
19900
- description: "Timestamp when this artifact was captured."
19901
- },
19902
- index: {
19903
- type: "number",
19904
- integer: true,
19905
- description: "Stable ordering index within the probe run."
19906
- },
19907
- kind: {
19908
- type: "string",
19909
- enum: [...PLATFORM_STATUS_PROBE_ARTIFACT_KINDS],
19910
- description: "Artifact category captured during the run."
19911
- },
19912
- label: {
19913
- type: "string",
19914
- description: "Human-readable artifact label."
19915
- },
19916
- value: {
19917
- type: "string",
19918
- description: "Artifact payload or summary text."
19919
- },
19920
- "url?": {
19921
- type: "string",
19922
- description: "Optional URL associated with this artifact."
19923
- }
19924
- };
19925
19633
  // ../../packages/rules/src/tokens.ts
19926
19634
  var COMMIT_TOKEN_SYNTAX_REMOVED_MESSAGE = "$N/#N commit-token syntax is no longer supported. Use explicit names and explicit wrefs. For assertions about newly created things, create the thing with a deterministic name and set about to that wref in the same commit.";
19927
19635
  var ANY_TOKEN_RE = /[$#]\d+/;
@@ -20040,12 +19748,17 @@ function builtinShapeGuard(op, operationIndex) {
20040
19748
  operationIndex,
20041
19749
  message: `Shape "${op.newName}" is a retired collection shape and cannot be written manually`
20042
19750
  });
20043
- } else if (op.operation !== "retract" && op.kind === "shape" && name && isBuiltinShape(name)) {
20044
- errors.push({
20045
- code: "RESERVED_NAME",
20046
- operationIndex,
20047
- message: `Shape "${name}" is a built-in shape and cannot be ${op.operation === "add" ? "created" : "revised"} manually`
20048
- });
19751
+ } else {
19752
+ const isShapeRename = op.operation === "rename" && (op.kind === "shape" || op.name !== undefined && !splitLocalPath(op.name));
19753
+ const builtinShapeName = name && isBuiltinShape(name) ? name : isShapeRename && op.newName && isBuiltinShape(op.newName) ? op.newName : undefined;
19754
+ if (builtinShapeName && (isShapeRename || op.operation !== "retract" && op.kind === "shape")) {
19755
+ const action = op.operation === "add" ? "created" : op.operation === "rename" ? "renamed" : "revised";
19756
+ errors.push({
19757
+ code: "RESERVED_NAME",
19758
+ operationIndex,
19759
+ message: `Shape "${builtinShapeName}" is a built-in shape and cannot be ${action} manually`
19760
+ });
19761
+ }
20049
19762
  }
20050
19763
  if (name) {
20051
19764
  const local = splitLocalPath(name);
@@ -26946,7 +26659,7 @@ function validatePersistedStringFieldLimits(value, typeDef, errors, path) {
26946
26659
  }
26947
26660
  if (Array.isArray(value)) {
26948
26661
  const elementType = arrayElementType(normalized);
26949
- if (normalized !== undefined && elementType === undefined)
26662
+ if (elementType === undefined && !isDeclaredArrayType(normalized))
26950
26663
  return;
26951
26664
  for (let i = 0;i < value.length; i++) {
26952
26665
  validatePersistedStringFieldLimits(value[i], elementType, errors, `${path ?? "<value>"}[${i}]`);
@@ -26979,6 +26692,11 @@ function arrayElementType(typeDef) {
26979
26692
  return typeDef.items;
26980
26693
  return;
26981
26694
  }
26695
+ function isDeclaredArrayType(typeDef) {
26696
+ if (typeDef === "array" || Array.isArray(typeDef))
26697
+ return true;
26698
+ return isTypeSpecObject(typeDef) && typeDef.type === "array";
26699
+ }
26982
26700
  function nestedObjectFields(typeDef) {
26983
26701
  if (!isPlainObject(typeDef) || isTypeSpecObject(typeDef))
26984
26702
  return;
@@ -27356,15 +27074,6 @@ function validateShapeDefinition(data, options = {}) {
27356
27074
  }
27357
27075
  return { valid: true };
27358
27076
  }
27359
- // ../../packages/rules/src/subscribable-events.ts
27360
- var COMMIT_EVENT_TYPE = "commit";
27361
- var REPO_RENAMED_EVENT_TYPE = "repo.renamed";
27362
- var ORG_RENAMED_EVENT_TYPE = "org.renamed";
27363
- var SUBSCRIBABLE_EVENT_TYPES = [
27364
- COMMIT_EVENT_TYPE,
27365
- REPO_RENAMED_EVENT_TYPE,
27366
- ORG_RENAMED_EVENT_TYPE
27367
- ];
27368
27077
  // ../../packages/rules/src/system-components/system.ts
27369
27078
  var SYSTEM_COMPONENT_ID = "com.warmhub.system";
27370
27079
  var COMPONENT_INSTALL_FIELDS = {
@@ -27427,7 +27136,7 @@ function findSystemComponent(componentId) {
27427
27136
  // ../../packages/sdk-ts/package.json
27428
27137
  var package_default = {
27429
27138
  name: "@warmhub/sdk-ts",
27430
- version: "0.67.0",
27139
+ version: "0.69.0",
27431
27140
  private: false,
27432
27141
  type: "module",
27433
27142
  description: "The TypeScript SDK for WarmHub — create repos, commit and query data, and compound knowledge with your AI agents.",
@@ -32968,7 +32677,7 @@ function collectionFields(shapeName, data) {
32968
32677
  return result;
32969
32678
  }
32970
32679
  function effectiveKind(kind, shapeName) {
32971
- if ((kind === "thing" || !kind) && shapeName && isBuiltinCollectionShape(shapeName)) {
32680
+ if ((kind === "thing" || kind === "collection" || !kind) && shapeName && isBuiltinCollectionShape(shapeName)) {
32972
32681
  return shapeName.toLowerCase();
32973
32682
  }
32974
32683
  return kind;
@@ -33211,7 +32920,8 @@ async function fetchAllAssertionHeadPages(ctx, org, repo, opts) {
33211
32920
  match: opts.match,
33212
32921
  includeRetracted: opts.includeRetracted,
33213
32922
  limit: opts.limit,
33214
- cursor
32923
+ cursor,
32924
+ ...opts.where ? { where: opts.where } : {}
33215
32925
  });
33216
32926
  items.push(...page.items ?? []);
33217
32927
  if (!page.nextCursor)
@@ -33232,7 +32942,8 @@ async function fetchAllAssertionAboutPages(ctx, org, repo, wref, opts) {
33232
32942
  includeRetracted: opts.includeRetracted,
33233
32943
  resolveCollections: opts.resolveCollections,
33234
32944
  limit: opts.limit,
33235
- cursor
32945
+ cursor,
32946
+ ...opts.where ? { where: opts.where } : {}
33236
32947
  });
33237
32948
  target = page.target;
33238
32949
  assertions.push(...page.assertions ?? []);
@@ -33249,27 +32960,27 @@ async function fetchAllAssertionAboutPages(ctx, org, repo, wref, opts) {
33249
32960
 
33250
32961
  // ../../packages/warmhub-cli/src/domains/assertion/mutators.ts
33251
32962
  var createFlags = {
33252
- name: flag.string({ description: "Assertion name" }),
32963
+ name: flag.string({ description: "assertion name (required)" }),
33253
32964
  shape: flag.string({ description: "Shape for assertion (required)" }),
33254
32965
  data: flag.string({ description: "Data payload (JSON)" }),
33255
32966
  about: flag.string({ description: "Target wref" }),
33256
32967
  message: flag.string({ short: "m", description: "Commit message" }),
33257
32968
  committer: flag.string({
33258
- description: "Committer thing wref (e.g. Agent/bot-1)"
32969
+ description: "Committer wref (shape or shaped thing; e.g. Agent/bot-1)"
33259
32970
  })
33260
32971
  };
33261
32972
  var reviseFlags = {
33262
32973
  data: flag.string({ description: "Data payload (JSON)" }),
33263
32974
  message: flag.string({ short: "m", description: "Commit message" }),
33264
32975
  committer: flag.string({
33265
- description: "Committer thing wref (e.g. Agent/bot-1)"
32976
+ description: "Committer wref (shape or shaped thing; e.g. Agent/bot-1)"
33266
32977
  })
33267
32978
  };
33268
32979
  var retractFlags = {
33269
32980
  reason: flag.string({ description: "Reason for retraction (<=500 chars)" }),
33270
32981
  message: flag.string({ short: "m", description: "Commit message" }),
33271
32982
  committer: flag.string({
33272
- description: "Committer thing wref (e.g. Agent/bot-1)"
32983
+ description: "Committer wref (shape or shaped thing; e.g. Agent/bot-1)"
33273
32984
  })
33274
32985
  };
33275
32986
  var handleRevise = async (ctx, { flags, args }) => {
@@ -33330,11 +33041,11 @@ var handleCreate = async (ctx, { flags, args }) => {
33330
33041
  const message = flags.message;
33331
33042
  const data = flags.data !== undefined ? parseJsonObject(flags.data, "--data") : undefined;
33332
33043
  const c = ctx.colors;
33333
- if (!shape || !aboutRaw) {
33334
- usageError("Usage: wh assertion create --shape <shape> --about <wref|type:members> [--name <name>] --data <json>", `wh assertion create --shape belief --about player --data '{"confidence":0.8}'`);
33044
+ if (!shape || !aboutRaw || !name) {
33045
+ usageError("Usage: wh assertion create --shape <shape> --name <name> --about <wref> [--data <json>]", `wh assertion create --shape belief --name player-belief --about player --data '{"confidence":0.8}'`);
33335
33046
  }
33336
33047
  const about = parseAbout(aboutRaw);
33337
- const localName = name ? `${shape}/${name}` : `${shape}/${shape}-$1`;
33048
+ const localName = `${shape}/${name}`;
33338
33049
  const operations = [
33339
33050
  {
33340
33051
  operation: "add",
@@ -33356,9 +33067,14 @@ var handleCreate = async (ctx, { flags, args }) => {
33356
33067
 
33357
33068
  // ../../packages/warmhub-cli/src/domains/thing/shared.ts
33358
33069
  var DURABLE_ID_PATTERN_RE = /^[0-9a-zA-HJ-NP-Tv-z]{60}(@(v\d+|HEAD|ALL))?$/i;
33070
+ var WREF_SEGMENT = String.raw`[^/?#@:\s$]+`;
33071
+ var CANONICAL_WREF_PATTERN_RE = new RegExp(String.raw`^wh:${WREF_SEGMENT}/${WREF_SEGMENT}/${WREF_SEGMENT}(?:/${WREF_SEGMENT})*(?:@(?:v[1-9]\d*|HEAD|ALL))?$`, "i");
33359
33072
  function looksLikeDurableId(wref) {
33360
33073
  return DURABLE_ID_PATTERN_RE.test(wref);
33361
33074
  }
33075
+ function looksLikeCanonicalWref(wref) {
33076
+ return CANONICAL_WREF_PATTERN_RE.test(wref);
33077
+ }
33362
33078
  var DEFAULT_PAGE_LIMIT = 50;
33363
33079
  var DEFAULT_SEARCH_LIMIT = 25;
33364
33080
  var MAX_PAGE_LIMIT = 500;
@@ -33510,7 +33226,7 @@ var createFlags2 = {
33510
33226
  }),
33511
33227
  message: flag.string({ short: "m", description: "Commit message" }),
33512
33228
  committer: flag.string({
33513
- description: "Committer thing wref (e.g. Agent/bot-1)"
33229
+ description: "Committer wref (shape or shaped thing; e.g. Agent/bot-1)"
33514
33230
  })
33515
33231
  };
33516
33232
  var handleCreate2 = async (ctx, { flags, args }) => {
@@ -33566,10 +33282,10 @@ function renderHead(out, c, chars, result, org, repo, shape, kind) {
33566
33282
  if (item.kind === "assertion" && item.aboutWref) {
33567
33283
  out(` ${c.dim}about:${c.reset} ${pinnedWref(c, item.aboutWref)}`);
33568
33284
  }
33569
- const fields = shapeName && item.kind === "thing" && item.data ? collectionFields(shapeName, item.data) : null;
33285
+ const fields = shapeName && (item.kind === "thing" || item.kind === "collection") && item.data ? collectionFields(shapeName, item.data) : null;
33570
33286
  if (fields) {
33571
33287
  const allWrefs = fields.flatMap((f) => f.wrefs);
33572
- out(` ${allWrefs.map((w) => pinnedWref(c, w)).join(`${c.dim},${c.reset} `)}`);
33288
+ out(` ${allWrefs.map((w) => pinnedWref(c, escapeTerminalTextForDisplay(w))).join(`${c.dim},${c.reset} `)}`);
33573
33289
  } else if (item.data && typeof item.data === "object") {
33574
33290
  const preview = JSON.stringify(item.data);
33575
33291
  const truncated = preview.length > 80 ? `${preview.slice(0, 77)}...` : preview;
@@ -33619,11 +33335,11 @@ function renderThing(out, c, result) {
33619
33335
  for (const field of fields) {
33620
33336
  if (field.wrefs.length === 1) {
33621
33337
  const pad = " ".repeat(Math.max(1, 9 - field.name.length));
33622
- out(` ${c.dim}${field.name}:${c.reset}${pad}${pinnedWref(c, field.wrefs[0])}`);
33338
+ out(` ${c.dim}${field.name}:${c.reset}${pad}${pinnedWref(c, escapeTerminalTextForDisplay(field.wrefs[0]))}`);
33623
33339
  } else {
33624
33340
  out(` ${c.dim}${field.name}:${c.reset}`);
33625
33341
  for (const w of field.wrefs) {
33626
- out(` ${pinnedWref(c, w)}`);
33342
+ out(` ${pinnedWref(c, escapeTerminalTextForDisplay(w))}`);
33627
33343
  }
33628
33344
  }
33629
33345
  }
@@ -33648,7 +33364,7 @@ function renderCollectionSummary(out, c, collection) {
33648
33364
  return;
33649
33365
  out(` ${c.dim}preview:${c.reset}`);
33650
33366
  for (const wref of preview) {
33651
- out(` ${pinnedWref(c, wref)}`);
33367
+ out(` ${pinnedWref(c, escapeTerminalTextForDisplay(wref))}`);
33652
33368
  }
33653
33369
  }
33654
33370
  function renderDataBlock(out, data, indent) {
@@ -33717,7 +33433,7 @@ function renderThingGraph(out, c, result) {
33717
33433
  function renderHistory(out, c, result) {
33718
33434
  if (result.thing && typeof result.thing === "object") {
33719
33435
  const wref = result.thing.wref ?? result.thing.name ?? "(unknown)";
33720
- out(`${c.bold}History: ${pinnedWref(c, wref)}${c.reset} ${kindLabel(c, result.thing.kind ?? "thing")}`);
33436
+ out(`${c.bold}History: ${pinnedWref(c, wref)}${c.reset} ${kindLabel(c, effectiveKind(result.thing.kind ?? "thing", result.thing.shapeName))}`);
33721
33437
  }
33722
33438
  const firstMeta = result.versions?.[0]?.metadata;
33723
33439
  if (firstMeta?.durableId) {
@@ -33821,7 +33537,7 @@ var handleThingGraph = async (ctx, { flags, args }) => {
33821
33537
  if (depth !== undefined && (depth < 1 || depth > 5)) {
33822
33538
  usageError("Usage: wh thing graph <wref> --depth <1-5>", "wh thing graph Game/base --depth 2");
33823
33539
  }
33824
- const { org, repo } = parseOrgRepo(getRepoRef(ctx), ctx.config);
33540
+ const { org, repo } = looksLikeDurableId(wref) ? parseOrgRepoOptional(getRepoRef(ctx), ctx.config) : parseOrgRepo(getRepoRef(ctx), ctx.config);
33825
33541
  const result = await ctx.client.thing.graph(org, repo, wref, {
33826
33542
  depth,
33827
33543
  version: flags.version
@@ -34008,6 +33724,7 @@ function validateComponentFilters(componentRef, excludeComponents, ...examples)
34008
33724
  // ../../packages/warmhub-cli/src/domains/thing/where.ts
34009
33725
  var MAX_WHERE_IN_VALUES = 1000;
34010
33726
  var WHERE_USAGE_HINT = 'Example: --where state=NC --where "employees>=100" --where "state?"';
33727
+ var FIELD_USAGE_HINT = "Example: --field data.round=1";
34011
33728
  function requireWhereFieldPath(raw, fieldPath) {
34012
33729
  const normalized = fieldPath.trim();
34013
33730
  if (!normalized) {
@@ -34050,6 +33767,27 @@ function parseWhereFlag(raw) {
34050
33767
  }
34051
33768
  throw new CliError(2 /* UserInput */, "USER_INPUT", `Malformed --where predicate: "${raw}". Supported operators: =, !=, >, >=, <, <=, ~, in:[...], ?`, undefined, WHERE_USAGE_HINT);
34052
33769
  }
33770
+ function parseFieldFlag(raw) {
33771
+ if (!raw.trim()) {
33772
+ throw new CliError(2 /* UserInput */, "USER_INPUT", `Malformed --field predicate: "${raw}". --field requires data.path=value.`, undefined, FIELD_USAGE_HINT);
33773
+ }
33774
+ const parsed = parseWhereFlag(raw);
33775
+ if (parsed.op !== "eq") {
33776
+ throw new CliError(2 /* UserInput */, "USER_INPUT", `Malformed --field predicate: "${raw}". --field supports exact equality only.`, undefined, FIELD_USAGE_HINT);
33777
+ }
33778
+ if (!parsed.fieldPath.startsWith("data.")) {
33779
+ throw new CliError(2 /* UserInput */, "USER_INPUT", `Malformed --field predicate: "${raw}". Field paths must start with "data.".`, undefined, FIELD_USAGE_HINT);
33780
+ }
33781
+ const fieldPath = parsed.fieldPath.slice("data.".length);
33782
+ if (!fieldPath) {
33783
+ throw new CliError(2 /* UserInput */, "USER_INPUT", `Malformed --field predicate: "${raw}". Field path cannot be empty after "data.".`, undefined, FIELD_USAGE_HINT);
33784
+ }
33785
+ return {
33786
+ fieldPath,
33787
+ op: "eq",
33788
+ rhs: parsed.rhs
33789
+ };
33790
+ }
34053
33791
  function coerceValue(s) {
34054
33792
  if (s.startsWith('"') && s.endsWith('"') || s.startsWith("'") && s.endsWith("'")) {
34055
33793
  return s.slice(1, -1);
@@ -34398,10 +34136,10 @@ function renderQueryResults(out, c, result) {
34398
34136
  const kl = kindLabel(c, effectiveKind(item.kind ?? "thing", shapeName));
34399
34137
  const retractedTag = item.active === false ? ` ${c.red}[RETRACTED]${c.reset}` : "";
34400
34138
  out(` ${wref} ${kl}${retractedTag}`);
34401
- const fields = shapeName && (item.kind === "thing" || !item.kind) && item.data ? collectionFields(shapeName, item.data) : null;
34139
+ const fields = shapeName && (item.kind === "thing" || item.kind === "collection" || !item.kind) && item.data ? collectionFields(shapeName, item.data) : null;
34402
34140
  if (fields) {
34403
34141
  const allWrefs = fields.flatMap((f) => f.wrefs);
34404
- out(` ${allWrefs.map((w) => pinnedWref(c, w)).join(`${c.dim},${c.reset} `)}`);
34142
+ out(` ${allWrefs.map((w) => pinnedWref(c, escapeTerminalTextForDisplay(w))).join(`${c.dim},${c.reset} `)}`);
34405
34143
  } else if (item.data && typeof item.data === "object") {
34406
34144
  const preview = JSON.stringify(item.data);
34407
34145
  const truncated = preview.length > 80 ? `${preview.slice(0, 77)}...` : preview;
@@ -34414,10 +34152,10 @@ function renderQueryResults(out, c, result) {
34414
34152
  // ../../packages/warmhub-cli/src/domains/thing/refs.ts
34415
34153
  var refsFlags = {
34416
34154
  inbound: flag.boolean({
34417
- description: "Show inbound refs (what references this thing) [default]"
34155
+ description: "Show inbound refs (what references this target) [default]"
34418
34156
  }),
34419
34157
  outbound: flag.boolean({
34420
- description: "Show outbound refs (what this thing references)"
34158
+ description: "Show outbound refs (what this target references)"
34421
34159
  }),
34422
34160
  field: flag.string({ description: "Filter by field path (inbound only)" }),
34423
34161
  limit: flag.number({
@@ -34532,7 +34270,7 @@ var handleResolve = async (ctx, { args }) => {
34532
34270
  if (!wref) {
34533
34271
  usageError("Usage: wh thing resolve <wref>", "wh thing resolve player");
34534
34272
  }
34535
- const { org, repo } = looksLikeDurableId(wref) ? parseOrgRepoOptional(getRepoRef(ctx), ctx.config) : parseOrgRepo(getRepoRef(ctx), ctx.config);
34273
+ const { org, repo } = looksLikeDurableId(wref) || looksLikeCanonicalWref(wref) ? parseOrgRepoOptional(getRepoRef(ctx), ctx.config) : parseOrgRepo(getRepoRef(ctx), ctx.config);
34536
34274
  const c = ctx.colors;
34537
34275
  const result = await ctx.client.thing.resolve(org, repo, wref);
34538
34276
  writeOutput(ctx, result, () => {
@@ -34552,7 +34290,7 @@ var retractFlags2 = {
34552
34290
  reason: flag.string({ description: "Reason for retraction (<=500 chars)" }),
34553
34291
  message: flag.string({ short: "m", description: "Commit message" }),
34554
34292
  committer: flag.string({
34555
- description: "Committer thing wref (e.g. Agent/bot-1)"
34293
+ description: "Committer wref (shape or shaped thing; e.g. Agent/bot-1)"
34556
34294
  }),
34557
34295
  "lease-id": flag.string({
34558
34296
  description: "Read-lease token from `wh thing lease` (auto-released on success)"
@@ -34592,7 +34330,7 @@ var reviseFlags2 = {
34592
34330
  data: flag.string({ description: "Data payload (JSON)" }),
34593
34331
  message: flag.string({ short: "m", description: "Commit message" }),
34594
34332
  committer: flag.string({
34595
- description: "Committer thing wref (e.g. Agent/bot-1)"
34333
+ description: "Committer wref (shape or shaped thing; e.g. Agent/bot-1)"
34596
34334
  }),
34597
34335
  "expected-version": flag.number({
34598
34336
  description: "Only apply if the target is still at this version (optimistic concurrency)"
@@ -34805,7 +34543,7 @@ var viewFlags = {
34805
34543
  description: "Resolve embedded graph to this depth (1-5)"
34806
34544
  }),
34807
34545
  "include-retracted": flag.boolean({
34808
- description: "View a retracted thing"
34546
+ description: "View a retracted shape or shaped thing"
34809
34547
  }),
34810
34548
  file: flag.string({
34811
34549
  description: "Read additional wrefs from <path>, one per line. Use `--file=-` for stdin (the `=` form is required) or pass bare `-` as a positional. Lines starting with '#' and blank lines are ignored; lines are not split on any other character."
@@ -34869,7 +34607,7 @@ async function collectWrefs(opts) {
34869
34607
  async function runSingleView(ctx, wref, flags) {
34870
34608
  const version = flags.version;
34871
34609
  const depth = flags.depth;
34872
- const { org, repo } = looksLikeDurableId(wref) && depth === undefined ? parseOrgRepoOptional(getRepoRef(ctx), ctx.config) : parseOrgRepo(getRepoRef(ctx), ctx.config);
34610
+ const { org, repo } = looksLikeDurableId(wref) ? parseOrgRepoOptional(getRepoRef(ctx), ctx.config) : parseOrgRepo(getRepoRef(ctx), ctx.config);
34873
34611
  const includeRetracted = flags["include-retracted"] || version !== undefined;
34874
34612
  const dataMode = validateDataMode(flags["data-mode"]);
34875
34613
  if (depth !== undefined && (depth < 1 || depth > 5)) {
@@ -35032,7 +34770,7 @@ var THING_DOMAIN = defineDomain({
35032
34770
  },
35033
34771
  resolve: {
35034
34772
  prime: true,
35035
- summary: "Resolve wref to thing",
34773
+ summary: "Resolve a wref to its canonical thing identity",
35036
34774
  args: "<wref>",
35037
34775
  handler: handleResolve
35038
34776
  },
@@ -35056,7 +34794,7 @@ var THING_DOMAIN = defineDomain({
35056
34794
  },
35057
34795
  retract: {
35058
34796
  prime: true,
35059
- summary: "Withdraw a thing, assertion, shape, or collection. Irreversible for the given identity.",
34797
+ summary: "Withdraw a thing. Irreversible for the given identity.",
35060
34798
  args: "<wref>",
35061
34799
  flags: retractFlags2,
35062
34800
  examples: [
@@ -35094,7 +34832,7 @@ var THING_DOMAIN = defineDomain({
35094
34832
  },
35095
34833
  refs: {
35096
34834
  prime: true,
35097
- summary: "Show refs (backlinks or cross-references) for a thing",
34835
+ summary: "Show refs (backlinks or cross-references) for a target",
35098
34836
  args: "<wref>",
35099
34837
  flags: refsFlags,
35100
34838
  examples: [
@@ -35126,7 +34864,7 @@ var THING_DOMAIN = defineDomain({
35126
34864
  "wh thing graph Game/base --depth 2"
35127
34865
  ],
35128
34866
  notes: [
35129
- "`graph` does not traverse inbound wref-field references; use `wh thing refs <wref> --inbound` to find things whose fields point at this thing."
34867
+ "`graph` does not traverse inbound wref-field references; use `wh thing refs <wref> --inbound` to find things whose fields point at this target."
35130
34868
  ],
35131
34869
  handler: handleThingGraph
35132
34870
  }
@@ -35151,9 +34889,9 @@ var handleView2 = async (ctx, { flags, args }) => {
35151
34889
  if (!wref) {
35152
34890
  usageError("Usage: wh assertion view <wref> [--version <n>] [--depth <n>]", "wh assertion view Belief/cave-safe --depth 2");
35153
34891
  }
35154
- const { org, repo } = parseOrgRepo(getRepoRef(ctx), ctx.config);
35155
34892
  const version = flags.version;
35156
34893
  const depth = flags.depth;
34894
+ const { org, repo } = looksLikeDurableId(wref) ? parseOrgRepoOptional(getRepoRef(ctx), ctx.config) : parseOrgRepo(getRepoRef(ctx), ctx.config);
35157
34895
  const includeRetracted = flags["include-retracted"] || version !== undefined;
35158
34896
  if (depth !== undefined && (depth < 1 || depth > 5)) {
35159
34897
  usageError("Usage: wh assertion view <wref> --depth <1-5>", "wh assertion view Belief/cave-safe --depth 2");
@@ -35215,7 +34953,7 @@ var handleHistory2 = async (ctx, { flags, args }) => {
35215
34953
  if (ctx.liveMode && flags.all) {
35216
34954
  usageError("Usage: wh assertion history <wref> [--limit N] [--cursor TOKEN] [--live]", "wh assertion history Belief/cave-safe --limit 50 --live");
35217
34955
  }
35218
- const { org, repo } = parseOrgRepo(getRepoRef(ctx), ctx.config);
34956
+ const { org, repo } = looksLikeDurableId(wref) ? parseOrgRepoOptional(getRepoRef(ctx), ctx.config) : parseOrgRepo(getRepoRef(ctx), ctx.config);
35219
34957
  const limit = Math.min(flags.limit ?? DEFAULT_PAGE_LIMIT2, MAX_PAGE_LIMIT2);
35220
34958
  if (ctx.liveMode) {
35221
34959
  await runLive({
@@ -35278,6 +35016,9 @@ var listFlags = {
35278
35016
  cursor: flag.string({ description: "Opaque pagination cursor" }),
35279
35017
  all: flag.boolean({ description: "Fetch all pages" }),
35280
35018
  count: flag.boolean({ description: "Return count of matching assertions" }),
35019
+ field: flag.string({
35020
+ description: "exact data-field filter (data.path=value); served by the typed field index"
35021
+ }),
35281
35022
  match: flag.string({ description: "Filter by wref glob pattern" }),
35282
35023
  "resolve-collections": flag.boolean({
35283
35024
  description: "Include assertions about collections (Pair/Set/List) containing the target."
@@ -35295,9 +35036,11 @@ var handleList = async (ctx, { flags, args }) => {
35295
35036
  const cursor = flags.cursor;
35296
35037
  const all = flags.all;
35297
35038
  const count = flags.count;
35039
+ const field = flags.field;
35298
35040
  const match = flags.match;
35299
35041
  const resolveCollections = flags["resolve-collections"];
35300
35042
  const includeRetracted = flags["include-retracted"];
35043
+ const where = field === undefined ? undefined : [parseFieldFlag(field)];
35301
35044
  if (count) {
35302
35045
  if (cursor || all || limit || ctx.liveMode) {
35303
35046
  usageError("Usage: wh assertion list --count [--shape SHAPE] [--about WREF] [--match PATTERN]", "wh assertion list --shape Belief --count");
@@ -35311,7 +35054,8 @@ var handleList = async (ctx, { flags, args }) => {
35311
35054
  match,
35312
35055
  about: wref,
35313
35056
  includeRetracted,
35314
- resolveCollections
35057
+ resolveCollections,
35058
+ ...where ? { where } : {}
35315
35059
  });
35316
35060
  }
35317
35061
  if (cursor && !limit) {
@@ -35332,7 +35076,8 @@ var handleList = async (ctx, { flags, args }) => {
35332
35076
  match,
35333
35077
  includeRetracted,
35334
35078
  limit: pageLimit,
35335
- cursor
35079
+ cursor,
35080
+ ...where ? { where } : {}
35336
35081
  };
35337
35082
  if (ctx.liveMode) {
35338
35083
  await runLive({
@@ -35377,7 +35122,8 @@ var handleList = async (ctx, { flags, args }) => {
35377
35122
  includeRetracted,
35378
35123
  resolveCollections,
35379
35124
  limit: pageLimit,
35380
- cursor
35125
+ cursor,
35126
+ ...where ? { where } : {}
35381
35127
  };
35382
35128
  if (ctx.liveMode) {
35383
35129
  await runLive({
@@ -35406,7 +35152,8 @@ var handleList = async (ctx, { flags, args }) => {
35406
35152
  includeRetracted,
35407
35153
  resolveCollections,
35408
35154
  limit: pageLimit,
35409
- cursor
35155
+ cursor,
35156
+ ...where ? { where } : {}
35410
35157
  }) : await ctx.client.thing.about(org, repo, wref, {
35411
35158
  shape,
35412
35159
  match,
@@ -35414,7 +35161,8 @@ var handleList = async (ctx, { flags, args }) => {
35414
35161
  includeRetracted,
35415
35162
  resolveCollections,
35416
35163
  limit: boundedLimit,
35417
- cursor
35164
+ cursor,
35165
+ ...where ? { where } : {}
35418
35166
  });
35419
35167
  if (!all && result.nextCursor) {
35420
35168
  emitPartialPageHint(ctx, (result.assertions ?? []).length, result.nextCursor, boundedLimit);
@@ -35439,6 +35187,7 @@ var ASSERTION_DOMAIN = defineDomain({
35439
35187
  examples: [
35440
35188
  "wh assertion list",
35441
35189
  "wh assertion list Location/cave --shape Belief",
35190
+ "wh assertion list Session/run-001 --shape HypothesisCandidate --field data.round=1",
35442
35191
  "wh assertion view Belief/cave-safe",
35443
35192
  "wh assertion list --about Location/cave --shape Belief"
35444
35193
  ],
@@ -35462,8 +35211,8 @@ var ASSERTION_DOMAIN = defineDomain({
35462
35211
  args: "",
35463
35212
  flags: createFlags,
35464
35213
  examples: [
35465
- `wh assertion create --shape belief --about player --data '{"confidence":0.8}'`,
35466
- `wh assertion create --shape Distance --about Pair/location-distance --data '{"value":5}'`
35214
+ `wh assertion create --shape belief --name player-belief --about player --data '{"confidence":0.8}'`,
35215
+ `wh assertion create --shape Distance --name location-distance-value --about Pair/location-distance --data '{"value":5}'`
35467
35216
  ],
35468
35217
  handler: handleCreate
35469
35218
  },
@@ -37009,7 +36758,7 @@ var COLLECTION_TYPES = ["pair", "set", "list"];
37009
36758
  var commonWriteFlags = {
37010
36759
  message: flag.string({ short: "m", description: "Commit message" }),
37011
36760
  committer: flag.string({
37012
- description: "Committer thing wref (e.g. Agent/bot-1)"
36761
+ description: "Committer wref (shape or shaped thing; e.g. Agent/bot-1)"
37013
36762
  })
37014
36763
  };
37015
36764
  var collectionInputFlags = {
@@ -37573,7 +37322,7 @@ var createFlags3 = {
37573
37322
  }),
37574
37323
  message: flag.string({ short: "m", description: "Commit message" }),
37575
37324
  committer: flag.string({
37576
- description: "Committer thing wref (e.g. Agent/bot-1)"
37325
+ description: "Committer wref (shape or shaped thing; e.g. Agent/bot-1)"
37577
37326
  }),
37578
37327
  add: flag.string({
37579
37328
  description: "Add a new thing (bare name — use --shape to set the shape). Repeatable; pair each --add with its own --data. For >20 ops, use --file <path>.",
@@ -37597,7 +37346,7 @@ var createFlags3 = {
37597
37346
  multiple: true
37598
37347
  }),
37599
37348
  about: flag.string({
37600
- description: "Target thing for assertions. Repeatable; one per --add, or a single value broadcast to all.",
37349
+ description: "Target shape or shaped thing for assertions. Repeatable; one per --add, or a single value broadcast to all.",
37601
37350
  multiple: true
37602
37351
  }),
37603
37352
  reason: flag.string({
@@ -40932,7 +40681,7 @@ var CREDENTIAL_DOMAIN = defineDomain({
40932
40681
  revoke: {
40933
40682
  status: "live",
40934
40683
  prime: true,
40935
- summary: "Revoke a credential set (blocks new binds and strips auth from existing webhook deliveries)",
40684
+ summary: "Revoke a credential set (blocks new binds and stops bound webhook deliveries)",
40936
40685
  args: "<setName>",
40937
40686
  flags: revokeFlags,
40938
40687
  examples: [
@@ -42080,6 +41829,13 @@ var ONBOARD_DOMAIN = defineDomain({
42080
41829
  handler: handleOnboard
42081
41830
  });
42082
41831
 
41832
+ // ../../packages/warmhub-cli/src/display-name.ts
41833
+ function ensureNonEmptyDisplayName(value, exampleCommand) {
41834
+ if (value !== undefined && value.trim() === "") {
41835
+ usageError("--display-name requires a non-empty value", exampleCommand);
41836
+ }
41837
+ }
41838
+
42083
41839
  // ../../packages/warmhub-cli/src/domains/org-member.ts
42084
41840
  var addMemberFlags = {
42085
41841
  role: flag.string({
@@ -42233,6 +41989,7 @@ var handleCreate4 = async (ctx, { flags, args }) => {
42233
41989
  if (!name) {
42234
41990
  usageError('Usage: wh org create <name> [--display-name "..."] [--description "..."]', 'wh org create caryden --display-name "Carl Ryden" -d "A great org"');
42235
41991
  }
41992
+ ensureNonEmptyDisplayName(flags["display-name"], 'wh org create acme --display-name "Acme Co"');
42236
41993
  const c = ctx.colors;
42237
41994
  const result = await ctx.client.org.create(name, flags["display-name"], flags.description);
42238
41995
  writeOutput(ctx, result, () => {
@@ -42317,6 +42074,7 @@ var handleOrgRename = async (ctx, { args, flags }) => {
42317
42074
  if (newSlug !== undefined && newSlug.length === 0 || rawSlugFromInvocation === "" || flagSlug === "") {
42318
42075
  usageError("New slug must be a non-empty string", "wh org rename acme acme-co");
42319
42076
  }
42077
+ ensureNonEmptyDisplayName(displayName2, 'wh org rename acme --display-name "Acme Co"');
42320
42078
  const c = ctx.colors;
42321
42079
  const slugChange = newSlug && newSlug !== oldName ? newSlug : undefined;
42322
42080
  if (displayName2 !== undefined && slugChange) {
@@ -42440,242 +42198,7 @@ var ORG_DOMAIN = defineDomain({
42440
42198
  });
42441
42199
 
42442
42200
  // ../../packages/warmhub-cli/src/domains/prime-content.md
42443
- var prime_content_default = `# WarmHub CLI Context
42444
- > **Context Recovery**: Run \`wh prime\` after compaction or new session
42445
-
42446
- ## Environment
42447
- {{REPO_LINE}}
42448
-
42449
- ## Core Concepts
42450
- - **Thing**: A named entity versioned by write operations. **Assertion**: A claim about a thing with shape-validated data.
42451
- - **Shape**: Schema defining data structure. **Write**: One or more add/revise/retract operations with per-operation results.
42452
- - **wref**: Reference as \`Shape/name\` (e.g., \`Player/alice\`). Cross-repo: \`wh:org/repo/Shape/name\`.
42453
-
42454
- ## Versioned Things
42455
- - \`Shape/name\` identifies the logical thing. \`Shape/name@vN\` pins an exact version.
42456
- - Read surfaces may show pinned wrefs (\`@vN\`) in data. Treat them as version metadata, not a different thing.
42457
-
42458
- ## Key Workflows
42459
-
42460
- **Write data** (discover shapes → scaffold ops → submit):
42461
- \`\`\`bash
42462
- wh shape list --repo org/repo # list available shapes
42463
- wh shape view ShapeName --repo org/repo # inspect fields
42464
- wh shape template ShapeName -o ops.json --repo org/repo # scaffold write ops (supports --kind assertion)
42465
- # edit ops.json — fill FILL_IN placeholders — then:
42466
- wh commit submit --file ops.json -m "msg" --repo org/repo # submit operations (bare \`wh commit\` also works)
42467
- # or single assertion (no file needed):
42468
- wh assertion create --shape ShapeName --about Target/name --name my-assertion --data '{"field":1}' --repo org/repo
42469
- # Relay failed operation details when present. Never hand-guess ops JSON — use \`wh shape template <Shape>\`.
42470
- \`\`\`
42471
-
42472
- **Read data:**
42473
- \`\`\`bash
42474
- wh thing list --repo org/repo # all things at HEAD
42475
- wh thing view Shape/name --repo org/repo # inspect a thing
42476
- wh thing query --shape MyShape --repo org/repo # find things by shape
42477
- wh thing about Shape/name --repo org/repo # assertions about thing/shape
42478
- wh assertion list --repo org/repo # all assertions at HEAD
42479
- wh thing history Shape/name --repo org/repo # version history
42480
-
42481
- # Batch read — wh thing view is variadic (max 500 wrefs/call):
42482
- wh thing view Player/alice Player/bob # variadic positionals
42483
- wh thing view --file wrefs.txt --json # one wref per line
42484
- cat wrefs.txt | wh thing view --format jsonl # one JSON line per *deduped* requested wref
42485
- \`\`\`
42486
-
42487
- ## Wref Quick Reference
42488
-
42489
- Write operations use explicit names and explicit wrefs. To connect operations
42490
- inside one commit, create the first thing with a deterministic name and point
42491
- later operations at that wref.
42492
-
42493
- ## Command Reference
42494
-
42495
- **Global flags**: \`--repo\`, \`--format\`, \`--json\`, \`--live\`
42496
- ### thing — Thing operations
42497
- - \`wh thing list [--shape] [--kind] [--match] [--include-retracted]\` — Current HEAD state
42498
- - \`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.
42499
- - \`wh thing history [wref] [--shape] [--about] [--include-retracted]\` — Version history
42500
- - \`wh thing resolve <wref>\` — Resolve wref
42501
- - \`wh thing create <name|Shape/name> --data <json-object> [--shape] [--message] [--committer]\` — Create
42502
- - \`wh thing revise <name> [--data] [--message] [--committer] [--expected-version]\` — Revise (CONFLICT if HEAD≠n)
42503
- - \`wh thing retract <wref> -m <message> [--reason] [--kind]\` — Retract
42504
- - \`wh thing query [--shape] [--kind] [--about] [--match]\` — Query by filters
42505
- - \`wh thing search <query> [--shape] [--kind] [--about] [--mode]\` — Search text
42506
- - \`wh thing rename <Shape/oldName> <newName>\` — Rename
42507
- - \`wh thing refs <wref> [--inbound] [--outbound] [--field]\` — Show field references; use \`wh thing about\` for assertions about things/shapes
42508
- - \`wh thing about <wref> [--shape] [--match] [--depth] [--resolve-collections] [--limit] [--include-retracted]\` — Show assertions about the target identity; \`--resolve-collections\` expands collection members for bare/@HEAD/@ALL inputs, not pinned @vN
42509
-
42510
- ### commit — Write operations
42511
- - \`wh commit submit [--ops|--file|--add|--revise|--retract] [--kind] [--data] [--reason] [--expected-version] [--chunk-size] [--skip-existing] [--progress] [--stream-id]\` — Submit operations (bare \`wh commit\` is equivalent). Use \`--file ops.jsonl --stream-id <id> --chunk-size 5000 --skip-existing\` for bulk ingest.
42512
- - \`wh shape template <shape> [shape2 ...] [--kind] [--operation add|revise|retract] [-o file]\` — Generate sample ops
42513
-
42514
- ### assertion — Assertion operations
42515
- - \`wh assertion list [--about wref] [--shape] [--match] [--include-retracted]\` — Browse assertions
42516
- - \`wh assertion view <wref> [--version] [--include-retracted]\` — Assertion details
42517
- - \`wh assertion create [--name] [--shape] [--data] [--about] [--message] [--committer]\` — Create assertion
42518
- - \`wh assertion revise <wref> --data <json> [--message] [--committer]\` — Revise assertion
42519
- - \`wh assertion retract <wref> -m <message> [--reason] [--committer]\` — Retract assertion
42520
- - \`wh assertion history <wref> [--include-retracted]\` — Assertion history
42521
-
42522
- ### shape — Shape management
42523
- - \`wh shape list [--match] [--include-retracted]\` — List all shapes
42524
- - \`wh shape view <name> [--include-retracted]\` — Shape details
42525
- - \`wh shape revise <name> [--fields]\` — Revise shape
42526
- - \`wh shape create <name> [--fields]\` — Create shape
42527
- - \`wh shape retract <name> -m <message> [--reason]\` — Retract shape
42528
- - \`wh shape history <name> [--include-retracted]\` — Shape history
42529
- - \`wh shape rename <oldName> <newName>\` — Rename shape
42530
-
42531
- ### repo — Repository management
42532
- - \`wh repo create <org/name> [--display-name] [--description] [--visibility]\` — Create repo
42533
- - \`wh repo list [org]\` — List repos
42534
- - \`wh repo view [org/repo]\` — Repo details
42535
-
42536
- ### org — Organization management
42537
- - \`wh org create <name> [--display-name]\` — Create a new organization
42538
- - \`wh org view <name>\` — View organization details (alias: info)
42539
- - \`wh org list\` — List all organizations
42540
-
42541
- ### sub — Subscription management
42542
- - \`wh sub create <name> [flags]\` — Create a subscription
42543
- - \`wh sub view <name>\` — View subscription details
42544
- - \`wh sub list\` — List all subscriptions
42545
- - \`wh sub log <name>\` — Tail subscription delivery feed
42546
- - \`wh sub attempts <runId>\` — Show attempt history for a run
42547
- - \`wh sub pause <name>\` — Pause a subscription
42548
- - \`wh sub resume <name>\` — Resume a paused subscription
42549
- - \`wh sub bind <name> [--credentials]\` — Bind a credential set to a subscription for webhook auth
42550
- - \`wh sub unbind <name>\` — Remove credential binding from a subscription
42551
- - \`wh sub delete <name>\` — Delete a subscription
42552
-
42553
- ### notifications — Action notification listing
42554
- - \`wh notifications [--limit] [--since]\` — List repo-scoped action notifications
42555
-
42556
- ### credential — Credential set management
42557
- - \`wh credential create <name> [--repo org/repo | --org org] [--scope] [--description]\` — Create an empty credential set
42558
- - \`wh credential list [--repo org/repo | --org org]\` — List credential sets accessible from a repo or org
42559
- - \`wh credential view <name> [--repo org/repo | --org org]\` — View a credential set (key names only, no values)
42560
- - \`wh credential delete <name> [--repo org/repo | --org org]\` — Delete a credential set and its Vault object
42561
- - \`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"}\`)
42562
- - \`wh credential unset <setName> <keyName> [--repo org/repo | --org org]\` — Remove a key from a credential set
42563
- - \`wh credential audit <setName> [--repo org/repo | --org org]\` — View audit log for a credential set
42564
- - \`wh credential revoke <setName> [--repo org/repo | --org org] [--reason]\` — Revoke a credential set (blocks new binds and strips auth from existing webhook deliveries)
42565
-
42566
- ### component — Component management
42567
- - \`wh component validate <path>\` — Validate package
42568
- - \`wh component install <org/name>\` — Install a registered component
42569
- - \`wh component register <name> --org <org> --manifest <path> [flags]\` — Register component identity
42570
- - \`wh component unregister <org/name>\` — Remove a registered component identity
42571
- - \`wh component registry list --org <org>\` — List registered components
42572
- - \`wh component registry view <org/name>\` — View a registered component
42573
- - \`wh component registry update <org/name> [flags]\` — Update a registered component
42574
- - \`wh component list\` — List installed components
42575
- - \`wh component update <org/name>\` — Update installed component
42576
- - \`wh component view <org/name>\` — Show component details (alias: show)
42577
- - \`wh component doctor <org/name>\` — Run component health checks
42578
- - \`wh component teardown <org/name>\` — Pause component subscriptions
42579
-
42580
- ### Getting More Info
42581
- - \`wh help\` — full help overview
42582
- - \`wh <domain>\` — list verbs for a domain
42583
- - \`wh <domain> <verb> --help\` — verb details with flags and examples
42584
- - \`wh help --format json\` — full CLI spec as JSON (best for agents)
42585
-
42586
- ## Common Workflows
42587
-
42588
- **Explore a repo:**
42589
- \`\`\`bash
42590
- wh thing list --repo org/repo # see all things in HEAD
42591
- wh thing view Shape/name --repo org/repo # inspect a specific thing
42592
- wh thing history Shape/name --repo org/repo # inspect version history
42593
- wh thing about Shape/name # assertions about thing/shape
42594
- \`\`\`
42595
-
42596
- **Create an assertion** (most common write):
42597
- \`\`\`bash
42598
- # --about takes a target wref: Shape/name thing, or Shape itself.
42599
- wh assertion create --shape MyShape --about TargetShape/target-name \\
42600
- --name my-assertion --data '{"field_a":1,"field_b":"value"}' --repo org/repo
42601
- # Output includes per-operation status; relay failures when present.
42602
- \`\`\`
42603
-
42604
- **Create via write entrypoint** (alternative, supports batches and streams):
42605
- \`\`\`bash
42606
- wh commit submit --add my-item --shape MyShape --kind assertion \\
42607
- --about TargetShape/target-name --data '{"field_a":1}' --repo org/repo
42608
- \`\`\`
42609
-
42610
- **Batch write via file** (generate template → edit → submit):
42611
- \`\`\`bash
42612
- wh shape template Hypothesis Evidence -o ops.json # add --kind assertion --about TargetShape/name for assertions
42613
- # edit ops.json — fill FILL_IN placeholders
42614
- wh commit submit --file ops.json -m "batch update" # submit all operations (bare \`wh commit\` is equivalent)
42615
- # --file format: docs.warmhub.ai/cli-reference/commit-operations
42616
- \`\`\`
42617
-
42618
- **Bulk write (JSONL stream, >1k ops)** — one chunked stream beats per-record commits (~60× faster):
42619
- \`\`\`bash
42620
- wh shape template MyShape -o ops.jsonl # one op per line (.jsonl)
42621
- ID="bulk-$(date +%s)" # choose your own; set it up front so reruns are safe
42622
- wh commit submit --file ops.jsonl --stream-id "$ID" --chunk-size 5000 \\
42623
- --skip-existing --progress -m "bulk ingest" --repo org/repo
42624
- # --chunk-size: ops per append chunk (default 1000, max 10000); chunk≈1 is ~60× slower
42625
- # --skip-existing: skips already-written add ops (drops per-row read-before-write)
42626
- # Add-stream restart: rerun the WHOLE file with the SAME --stream-id.
42627
- # Fixed-name adds are idempotent via --skip-existing. Mid-stream resume is not
42628
- # a CLI mode. Mixed revise/retract JSONL streams are not full-rerun safe after
42629
- # an ambiguous append; inspect repo state and reconcile explicitly.
42630
- \`\`\`
42631
-
42632
- **Create collections:**
42633
- \`\`\`bash
42634
- wh commit submit --type pair --name location-distance --members Location/a,Location/b --repo org/repo
42635
- wh assertion create --shape Distance --about Pair/location-distance --data '{"value":5}' --repo org/repo
42636
- \`\`\`
42637
-
42638
- **Modify data:**
42639
- \`\`\`bash
42640
- wh thing revise Shape/name --data '{"x":5,"y":3}' -m "update" --repo org/repo
42641
- wh thing retract Shape/old-item -m "withdrawn" --reason "data feed contaminated" --repo org/repo
42642
- \`\`\`
42643
-
42644
- **Query and filter:**
42645
- \`\`\`bash
42646
- wh thing query --shape MyShape # by shape
42647
- wh thing query --kind assertion --about Shape/name # by kind + target
42648
- wh thing history Shape/name --limit 10 # version history
42649
- \`\`\`
42650
-
42651
- ## Built-in Content shape
42652
-
42653
- WarmHub repos expose three well-known content wrefs:
42654
- - \`Content/Readme\` — stored markdown for humans
42655
- - \`Content/Agents\` — stored markdown guidance for AI agents
42656
- - \`Content/LlmsTxt\` — synthesized per-request sitemap (read-only)
42657
-
42658
- Fetch via \`wh repo content get --kind readme|agents|llms-txt\`,
42659
- \`client.repo.getReadme/getAgents/getLlmsTxt\`, MCP \`warmhub_repo_content_get\`,
42660
- or raw HTTP \`GET /{org}/{repo}/readme.md|agents.md|llms.txt\`.
42661
- See \`wh repo describe\` → \`additionalInformation\` for the discovery field.
42662
-
42663
- ## Query Discipline
42664
- - Plan the repo, shapes, and wrefs you need before the first query.
42665
- - Gather the needed facts from one repo before switching to another.
42666
- - Do the queries first, then write one complete answer.
42667
-
42668
- ## Agent Tips
42669
- - **Always run commands for live data** — this context describes the CLI, not repo contents
42670
- - **Before writing, discover wrefs** — run \`wh thing list\` or \`wh shape list\`
42671
- - **Shape field types**: \`string\`, \`number\`, \`boolean\`, \`wref\`, arrays, optionals, nested objects
42672
- - **Write commands return per-operation results** — relay failures and affected wrefs to the user
42673
- - **Pass data inline** with \`--data '{...}'\` — do NOT create temp files
42674
- - Add \`--json\` to any command for machine-readable JSON output
42675
- - **Aliases teach canonical commands** — executing aliases emit a status hint; misleading lifecycle aliases reject and point to \`retract\`
42676
- - 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.
42677
- - Use \`wh doctor\` to check environment health
42678
- `;
42201
+ 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 -m \"msg\" --repo org/repo # submit operations (bare `wh commit` also works)\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 — Thing operations\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 <json-object> [--shape] [--message] [--committer]` — 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]` — 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] [--limit] [--include-retracted]` — Show assertions about the target identity; `--resolve-collections` expands collection members for bare/@HEAD/@ALL inputs, not pinned @vN\n\n### commit — Write operations\n- `wh commit submit [--ops|--file|--add|--revise|--retract] [--kind] [--data] [--reason] [--expected-version] [--chunk-size] [--skip-existing] [--progress] [--stream-id]` — Submit operations (bare `wh commit` is equivalent). Use `--file ops.jsonl --stream-id <id> --chunk-size 5000 --skip-existing` for bulk ingest.\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]` — 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]` — Revise shape\n- `wh shape create <name> [--fields]` — Create shape\n- `wh shape retract <name> -m <message> [--reason]` — 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>` — Delete a subscription\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` — full help overview\n- `wh <domain>` — list verbs for a domain\n- `wh <domain> <verb> --help` — verb details with flags and examples\n- `wh help --format json` — full CLI spec as JSON (best for agents)\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)\" # choose your own; set it up front so reruns are safe\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# Add-stream restart: rerun the WHOLE file with the SAME --stream-id.\n# Fixed-name adds are idempotent via --skip-existing. Mid-stream resume is not\n# a CLI mode. Mixed revise/retract JSONL streams are not full-rerun safe after\n# an ambiguous append; inspect repo state and reconcile explicitly.\n```\n\n**Create collections:**\n```bash\nwh commit submit --type pair --name location-distance --members Location,Location/a --repo org/repo\nwh assertion create --shape Distance --name location-distance-value --about Pair/location-distance --data '{\"value\":5}' --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";
42679
42202
 
42680
42203
  // ../../packages/warmhub-cli/src/domains/prime.ts
42681
42204
  function buildMarkdown(config) {
@@ -42721,7 +42244,7 @@ var wrefSyntax = {
42721
42244
  "Player/alice",
42722
42245
  "GameState/round-1/state"
42723
42246
  ],
42724
- canonicalFormat: "wh:org/repo/Shape/name",
42247
+ canonicalFormat: "wh:org/repo/Shape or wh:org/repo/Shape/name",
42725
42248
  versionModifiers: ["@HEAD", "@vN", "@ALL"]
42726
42249
  };
42727
42250
  var handlePrime = async (ctx) => {
@@ -42826,11 +42349,6 @@ function parseExplicitOrgRepoArg(ref, usage, example) {
42826
42349
  const [orgName, repoName] = parts;
42827
42350
  return { orgName, repoName };
42828
42351
  }
42829
- function ensureNonEmptyDisplayName(value, exampleCommand) {
42830
- if (value !== undefined && value.trim() === "") {
42831
- usageError("--display-name requires a non-empty value", exampleCommand);
42832
- }
42833
- }
42834
42352
  function resolveOrgRepoArg(ref, orgFlag) {
42835
42353
  if (ref?.includes("/")) {
42836
42354
  const parts = ref.split("/");
@@ -43830,7 +43348,7 @@ var retractFlags3 = {
43830
43348
  reason: flag.string({ description: "Reason for retraction (<=500 chars)" }),
43831
43349
  message: flag.string({ short: "m", description: "Commit message" }),
43832
43350
  committer: flag.string({
43833
- description: "Committer thing wref (e.g. Agent/bot-1)"
43351
+ description: "Committer wref (shape or shaped thing; e.g. Agent/bot-1)"
43834
43352
  })
43835
43353
  };
43836
43354
  var handleCreate6 = async (ctx, { flags, args }) => {
@@ -44006,7 +43524,7 @@ var createFlags8 = {
44006
43524
  description: "Shape to subscribe to"
44007
43525
  }),
44008
43526
  event: flag.string({
44009
- description: "Event to watch: commit (default), repo.renamed, or org.renamed"
43527
+ description: "Event to watch: commit (default), repo.renamed, org.renamed, thing.renamed, or shape.renamed"
44010
43528
  }),
44011
43529
  org: flag.string({
44012
43530
  description: "Org slug for an org-scoped subscription (org.renamed)"
@@ -44203,7 +43721,7 @@ function scopeLabel(scope) {
44203
43721
  // ../../packages/warmhub-cli/src/domains/sub/handlers-create.ts
44204
43722
  var handleCreate7 = async (ctx, { flags, args }) => {
44205
43723
  const name = args[0] ?? flags.name;
44206
- const usage = "Usage: wh sub create <name> (--repo org/repo | --org org) [--event commit|repo.renamed|org.renamed] [options]";
43724
+ const usage = "Usage: wh sub create <name> (--repo org/repo | --org org) [--event commit|repo.renamed|org.renamed|thing.renamed|shape.renamed] [options]";
44207
43725
  const example = `wh sub create signal-hook --repo myorg/myrepo --on Signal --filter '{"shape":"Signal"}' --webhook-url https://example.com/hook`;
44208
43726
  if (!name) {
44209
43727
  usageError(usage, example);
@@ -44242,7 +43760,7 @@ var handleCreate7 = async (ctx, { flags, args }) => {
44242
43760
  return;
44243
43761
  }
44244
43762
  const { org, repo } = resolveRepoContext(ctx);
44245
- if (eventType === "repo.renamed") {
43763
+ if (eventType !== "commit") {
44246
43764
  rejectCommitFlags(flags, eventType);
44247
43765
  const result2 = await ctx.client.subscription.create({
44248
43766
  orgName: org,
@@ -44255,7 +43773,7 @@ var handleCreate7 = async (ctx, { flags, args }) => {
44255
43773
  });
44256
43774
  writeOutput(ctx, result2, () => {
44257
43775
  const c = ctx.colors;
44258
- ctx.status(`${c.green}Created subscription${c.reset} ${c.cyan}${name}${c.reset} on ${c.cyan}${org}/${repo}${c.reset} (repo.renamed)`);
43776
+ ctx.status(`${c.green}Created subscription${c.reset} ${c.cyan}${name}${c.reset} on ${c.cyan}${org}/${repo}${c.reset} (${eventType})`);
44259
43777
  });
44260
43778
  return;
44261
43779
  }
@@ -45048,10 +44566,11 @@ var TOKEN_DOMAIN = defineDomain({
45048
44566
  // ../../packages/warmhub-cli/src/update-check-cache.ts
45049
44567
  import { mkdirSync as mkdirSync7, readFileSync as readFileSync10, writeFileSync as writeFileSync7 } from "node:fs";
45050
44568
  import { homedir as homedir5 } from "node:os";
45051
- import { dirname as dirname7, resolve as resolve3 } from "node:path";
44569
+ import { dirname as dirname8, resolve as resolve3 } from "node:path";
45052
44570
 
45053
44571
  // ../../packages/warmhub-cli/src/update-check-fetch.ts
45054
44572
  import * as childProcess4 from "node:child_process";
44573
+ import { dirname as dirname7 } from "node:path";
45055
44574
  var WH_CLI_PACKAGE_NAME = "@warmhub/cli";
45056
44575
  var UPDATE_DIST_TAG = "latest";
45057
44576
  var DEFAULT_UPDATE_REGISTRY = "https://registry.npmjs.org";
@@ -45092,8 +44611,24 @@ var getUpdateRegistryConfigFingerprint = (env, _cwd, _homePath, _options = {}) =
45092
44611
  return `env:${override}`;
45093
44612
  return `default:${DEFAULT_UPDATE_REGISTRY}`;
45094
44613
  };
44614
+ function withNpmRegistryEnv(env, registry2) {
44615
+ const childEnv = { ...env };
44616
+ for (const key of Object.keys(childEnv)) {
44617
+ if (key.toLowerCase() === "npm_config_registry")
44618
+ delete childEnv[key];
44619
+ }
44620
+ return { ...childEnv, npm_config_registry: registry2 };
44621
+ }
45095
44622
  var fetchLatestCliVersion = (env, registry2) => {
45096
- const proc = childProcess4.spawnSync("npm", [
44623
+ const isWindows = process.platform === "win32";
44624
+ const proc = isWindows ? childProcess4.spawnSync(`npm view ${WH_CLI_PACKAGE_NAME}@${UPDATE_DIST_TAG} version --json`, {
44625
+ encoding: "utf8",
44626
+ cwd: dirname7(process.execPath),
44627
+ env: withNpmRegistryEnv(env, registry2),
44628
+ shell: true,
44629
+ stdio: "pipe",
44630
+ timeout: 8000
44631
+ }) : childProcess4.spawnSync("npm", [
45097
44632
  "view",
45098
44633
  `${WH_CLI_PACKAGE_NAME}@${UPDATE_DIST_TAG}`,
45099
44634
  "version",
@@ -45122,7 +44657,7 @@ var readCache = (homePath) => {
45122
44657
  };
45123
44658
  var writeCache = (homePath, cache) => {
45124
44659
  const path2 = cachePath(homePath);
45125
- mkdirSync7(dirname7(path2), { recursive: true });
44660
+ mkdirSync7(dirname8(path2), { recursive: true });
45126
44661
  writeFileSync7(path2, `${JSON.stringify(cache, null, 2)}
45127
44662
  `, "utf8");
45128
44663
  };
@@ -45141,7 +44676,7 @@ var markUpdateNoticeShown = ({
45141
44676
  import { spawnSync as spawnSync2 } from "node:child_process";
45142
44677
  import { existsSync as existsSync9, readFileSync as readFileSync11, realpathSync } from "node:fs";
45143
44678
  import { homedir as homedir6 } from "node:os";
45144
- import { dirname as dirname8, resolve as resolve4 } from "node:path";
44679
+ import { dirname as dirname9, resolve as resolve4 } from "node:path";
45145
44680
  var DEV_INSTALL_PACKAGE_SEARCH_DEPTH = 8;
45146
44681
  var DEV_INSTALL_GIT_SEARCH_DEPTH = 4;
45147
44682
  var normalizePath = (path2) => path2 ? path2.replaceAll("\\", "/") : "";
@@ -45285,7 +44820,7 @@ var formatUnknownInstallHint = (activePath, realPath, latestVersion, registry2)
45285
44820
  var isDevInstall = (scriptPath) => {
45286
44821
  if (!scriptPath)
45287
44822
  return false;
45288
- let dir = dirname8(scriptPath);
44823
+ let dir = dirname9(scriptPath);
45289
44824
  for (let i = 0;i < DEV_INSTALL_PACKAGE_SEARCH_DEPTH; i += 1) {
45290
44825
  const pkgPath = resolve4(dir, "package.json");
45291
44826
  try {
@@ -45297,7 +44832,7 @@ var isDevInstall = (scriptPath) => {
45297
44832
  for (let j = 0;j < DEV_INSTALL_GIT_SEARCH_DEPTH; j += 1) {
45298
44833
  if (existsSync9(resolve4(probe, ".git")))
45299
44834
  return true;
45300
- const parent2 = dirname8(probe);
44835
+ const parent2 = dirname9(probe);
45301
44836
  if (parent2 === probe)
45302
44837
  break;
45303
44838
  probe = parent2;
@@ -45305,7 +44840,7 @@ var isDevInstall = (scriptPath) => {
45305
44840
  return false;
45306
44841
  }
45307
44842
  } catch {}
45308
- const parent = dirname8(dir);
44843
+ const parent = dirname9(dir);
45309
44844
  if (parent === dir)
45310
44845
  break;
45311
44846
  dir = parent;
@@ -46520,6 +46055,7 @@ async function runCli(argv, opts) {
46520
46055
  ...traceFields
46521
46056
  });
46522
46057
  let exitCode = 0 /* Ok */;
46058
+ let cancelledExitCode;
46523
46059
  let removeSignalListeners;
46524
46060
  try {
46525
46061
  canonicalizeGlobalFlags({ invocation });
@@ -46573,7 +46109,6 @@ async function runCli(argv, opts) {
46573
46109
  const chars = makeChars();
46574
46110
  const ac = new AbortController;
46575
46111
  const liveMode = getBoolFlag(invocation.flags, "live");
46576
- let cancelledExitCode;
46577
46112
  const handleSigint = () => {
46578
46113
  ac.abort();
46579
46114
  logger.info("cli.cancelled", { signal: "SIGINT", ...traceFields });
@@ -46620,6 +46155,10 @@ async function runCli(argv, opts) {
46620
46155
  exitCode = cancelledExitCode ?? 0 /* Ok */;
46621
46156
  return exitCode;
46622
46157
  } catch (error) {
46158
+ if (cancelledExitCode !== undefined) {
46159
+ exitCode = cancelledExitCode;
46160
+ return exitCode;
46161
+ }
46623
46162
  const cliError = toCliError2(error);
46624
46163
  const fields = {
46625
46164
  kind: cliError.kind,
@@ -46698,7 +46237,7 @@ function resolveLogLevel(flags, env) {
46698
46237
  // package.json
46699
46238
  var package_default3 = {
46700
46239
  name: "@warmhub/cli",
46701
- version: "0.68.0",
46240
+ version: "0.70.0",
46702
46241
  private: false,
46703
46242
  type: "module",
46704
46243
  description: "The wh CLI for WarmHub — create repos, commit and query data, and compound knowledge with your AI agents.",
@@ -47353,4 +46892,4 @@ if (!updateCheckSuppressedByArgv && shouldRunUpdateCheck(updateEligibility)) {
47353
46892
  var interceptedExitCode = await maybeHandleComponentShellBoundary(dispatchArgv);
47354
46893
  process.exitCode = interceptedExitCode === undefined ? await runCli(dispatchArgv, { version: package_default3.version }) : interceptedExitCode;
47355
46894
 
47356
- //# debugId=201635543D774B8564756E2164756E21
46895
+ //# debugId=14D7F2CE92253D6D64756E2164756E21