@warmhub/cli 0.137.0 → 0.139.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 +276 -99
  2. package/package.json +1 -1
package/dist/wh.js CHANGED
@@ -18164,7 +18164,8 @@ var COMMIT_OPERATIONS = [
18164
18164
  "revise",
18165
18165
  "retract",
18166
18166
  "reaffirm",
18167
- "rename"
18167
+ "rename",
18168
+ "remove"
18168
18169
  ];
18169
18170
  var COMMIT_OPERATION_KINDS = [
18170
18171
  "shape",
@@ -43665,7 +43666,11 @@ function normalizeCommitValidationOperations(operations, skipExisting) {
43665
43666
  return operations.map((operation, index) => {
43666
43667
  let normalized;
43667
43668
  try {
43668
- normalized = toBackendStreamOperation(operation);
43669
+ normalized = operation.operation === "remove" ? {
43670
+ operation: "remove",
43671
+ name: operation.name,
43672
+ expectedVersion: operation.expectedVersion
43673
+ } : toBackendStreamOperation(operation);
43669
43674
  } catch (error51) {
43670
43675
  const message = error51 instanceof Error ? error51.message : String(error51);
43671
43676
  throw new CommitValidationInputError(`Invalid operation at index ${index}: ${message}`);
@@ -44526,7 +44531,7 @@ class PartialStreamSubmissionError extends Error {
44526
44531
  }
44527
44532
 
44528
44533
  class AllStreamOperationsFailedError extends Error {
44529
- code = "STREAM_ALL_OPERATIONS_FAILED";
44534
+ code;
44530
44535
  receipts;
44531
44536
  result;
44532
44537
  operations;
@@ -44536,6 +44541,7 @@ class AllStreamOperationsFailedError extends Error {
44536
44541
  const primaryFailure = result.operations.find((operation) => operation.status === "error")?.errors[0];
44537
44542
  super(primaryFailure ? `All ${result.operationCount} stream operations failed: ${primaryFailure.message}` : `All ${result.operationCount} stream operations failed.`);
44538
44543
  this.name = "WarmHubError";
44544
+ this.code = primaryFailure && result.operations.every((operation) => operation.status === "error" && operation.errors.length > 0 && operation.errors.every((error51) => error51.code === primaryFailure.code)) ? primaryFailure.code : "STREAM_ALL_OPERATIONS_FAILED";
44539
44545
  this.cause = primaryFailure;
44540
44546
  this.result = result;
44541
44547
  this.receipts = result.receipts;
@@ -44594,6 +44600,7 @@ var DEFINITE_CLIENT_REJECT_CODES = new Set([
44594
44600
  "KIND_MISMATCH",
44595
44601
  "CONFLICT",
44596
44602
  "NAME_TAKEN",
44603
+ "TARGET_REMOVED",
44597
44604
  "ALREADY_RETRACTED",
44598
44605
  "ARCHIVED",
44599
44606
  "RATE_LIMITED",
@@ -44999,6 +45006,11 @@ var currentErrorDetailsSchema = exports_external.discriminatedUnion("reason", [
44999
45006
  name: exports_external.string().min(1),
45000
45007
  takenBy: exports_external.object({ shape: exports_external.string().min(1), durableId: exports_external.string().min(1) }).loose().optional(),
45001
45008
  suggestedName: exports_external.string().min(1).optional()
45009
+ }).loose(),
45010
+ exports_external.object({
45011
+ reason: exports_external.literal("target_removed"),
45012
+ targetDurableId: exports_external.string().min(1),
45013
+ fieldPath: exports_external.string().optional()
45002
45014
  }).loose()
45003
45015
  ]);
45004
45016
  var currentBaseShape = {
@@ -45489,7 +45501,7 @@ function createStreamingSubmissionHandle(input, deps) {
45489
45501
  // ../../packages/sdk-ts/package.json
45490
45502
  var package_default = {
45491
45503
  name: "@warmhub/sdk-ts",
45492
- version: "0.135.0",
45504
+ version: "0.137.0",
45493
45505
  private: false,
45494
45506
  type: "module",
45495
45507
  description: "The TypeScript SDK for WarmHub — create repos, commit and query data, and compound knowledge with your AI agents.",
@@ -45989,7 +46001,11 @@ function toWarmHubError(error51) {
45989
46001
  if (error51 instanceof Error) {
45990
46002
  const warmhubLike = error51;
45991
46003
  if (error51.name === "WarmHubError" && typeof warmhubLike.code === "string") {
45992
- return new WarmHubError(warmhubLike.code, sanitizeErrorMessage(error51.message), typeof warmhubLike.status === "number" ? warmhubLike.status : undefined, typeof warmhubLike.hint === "string" ? warmhubLike.hint : undefined, typeof warmhubLike.retryAfter === "number" ? warmhubLike.retryAfter : undefined, typeof warmhubLike.errorCode === "string" ? warmhubLike.errorCode : typeof warmhubLike.backendCode === "string" ? warmhubLike.backendCode : undefined, warmhubLike.details);
46004
+ const mapped = new WarmHubError(warmhubLike.code, sanitizeErrorMessage(error51.message), typeof warmhubLike.status === "number" ? warmhubLike.status : undefined, typeof warmhubLike.hint === "string" ? warmhubLike.hint : undefined, typeof warmhubLike.retryAfter === "number" ? warmhubLike.retryAfter : undefined, typeof warmhubLike.errorCode === "string" ? warmhubLike.errorCode : typeof warmhubLike.backendCode === "string" ? warmhubLike.backendCode : undefined, warmhubLike.details);
46005
+ if (isAllFailedStreamError(error51)) {
46006
+ Object.defineProperty(mapped, ALL_OPERATIONS_FAILED, { value: true });
46007
+ }
46008
+ return mapped;
45993
46009
  }
45994
46010
  if (error51.name === "AbortError") {
45995
46011
  return new WarmHubError("CANCELLED", error51.message);
@@ -46001,6 +46017,15 @@ function toWarmHubError(error51) {
46001
46017
  }
46002
46018
  return new WarmHubError("BACKEND", "Unknown SDK error");
46003
46019
  }
46020
+ var ALL_OPERATIONS_FAILED = Symbol.for("@warmhub/sdk-ts:allStreamOperationsFailed");
46021
+ function isAllFailedStreamError(error51) {
46022
+ if (error51 instanceof AllStreamOperationsFailedError)
46023
+ return true;
46024
+ if (!(error51 instanceof Error))
46025
+ return false;
46026
+ const shape = error51;
46027
+ return shape[ALL_OPERATIONS_FAILED] === true || shape.name === "WarmHubError" && Array.isArray(shape.receipts) && Array.isArray(shape.operations);
46028
+ }
46004
46029
  function isWarmHubError(error51) {
46005
46030
  return error51 instanceof WarmHubError;
46006
46031
  }
@@ -46953,7 +46978,8 @@ class WarmHubClient {
46953
46978
  orgName,
46954
46979
  repoName,
46955
46980
  shapeName,
46956
- includeRetracted: opts?.includeRetracted
46981
+ includeRetracted: opts?.includeRetracted,
46982
+ includeComposition: opts?.includeComposition
46957
46983
  });
46958
46984
  } catch (error51) {
46959
46985
  throw toWarmHubError(error51);
@@ -47672,6 +47698,19 @@ class WarmHubClient {
47672
47698
  throw toWarmHubError(error51);
47673
47699
  }
47674
47700
  },
47701
+ remove: async (orgName, repoName, wref, opts) => {
47702
+ try {
47703
+ return await this.trpc.thing.remove.mutate({
47704
+ orgName,
47705
+ repoName,
47706
+ wref,
47707
+ expectedVersion: opts.expectedVersion,
47708
+ eventRequestId: opts.eventRequestId
47709
+ });
47710
+ } catch (error51) {
47711
+ throw toWarmHubError(error51);
47712
+ }
47713
+ },
47675
47714
  resolve: async (orgName, repoName, wref) => {
47676
47715
  try {
47677
47716
  return await this.trpc.thing.resolve.query({
@@ -48410,6 +48449,8 @@ function classifyConflict(message, code) {
48410
48449
  return "incremental-read-unavailable";
48411
48450
  case "NAME_TAKEN":
48412
48451
  return "name-taken";
48452
+ case "TARGET_REMOVED":
48453
+ return "target-removed";
48413
48454
  case undefined:
48414
48455
  default:
48415
48456
  break;
@@ -48450,6 +48491,8 @@ function conflictHint(message, code) {
48450
48491
  const suggested = /for example "([^"]+)"/.exec(message)?.[1];
48451
48492
  return suggested ? `Another Thing in this repository holds this name. Use "${suggested}" or another free name; retrying the same name cannot succeed.` : "Another Thing in this repository holds this name. Choose another name; retrying the same name cannot succeed.";
48452
48493
  }
48494
+ case "target-removed":
48495
+ return "The referenced Thing was removed and cannot be referenced again. Point the reference at another Thing or drop it; retrying cannot succeed.";
48453
48496
  case "other":
48454
48497
  default:
48455
48498
  return "Resolve the conflicting existing state and try again.";
@@ -48474,6 +48517,7 @@ var TOP_LEVEL_USER_INPUT_CODES = new Set([
48474
48517
  var CONFLICT_SHAPED_CODES = new Set([
48475
48518
  "CONFLICT",
48476
48519
  "NAME_TAKEN",
48520
+ "TARGET_REMOVED",
48477
48521
  "ALREADY_EXISTS",
48478
48522
  "BUILTIN_SHAPE_CONFLICT",
48479
48523
  "ARCHIVED",
@@ -48691,6 +48735,11 @@ function generateSuggestions(code, message, context, errorCode) {
48691
48735
  action: "Choose a name no other Thing in the repository holds (use details.suggestedName when the error carries one)"
48692
48736
  });
48693
48737
  break;
48738
+ case "target-removed":
48739
+ suggestions.push({
48740
+ action: "The referenced Thing was removed (details.targetDurableId names it). Reference another Thing or drop the reference"
48741
+ });
48742
+ break;
48694
48743
  case "lease-held":
48695
48744
  suggestions.push({
48696
48745
  action: "Another holder leased this thing. Back off until the lease expires (leaseExpiresAt / retryAfter), then retry"
@@ -52584,7 +52633,7 @@ function emitPartialPageHint(ctx, count, _nextCursor, _limit) {
52584
52633
  }
52585
52634
 
52586
52635
  // ../../packages/warmhub-cli/src/domains/commit-output-contract-id.ts
52587
- var COMMIT_SUBMIT_OUTPUT_SCHEMA_ID = "wh.commit.submit.result/v0.5";
52636
+ var COMMIT_SUBMIT_OUTPUT_SCHEMA_ID = "wh.commit.submit.result/v0.6";
52588
52637
  function identifyCommitSubmitOutput(value) {
52589
52638
  if ("schema" in value) {
52590
52639
  if (value.schema === COMMIT_SUBMIT_OUTPUT_SCHEMA_ID) {
@@ -54439,6 +54488,119 @@ var handleReleaseLease = async (ctx, { flags, args }) => {
54439
54488
  });
54440
54489
  };
54441
54490
 
54491
+ // ../../packages/warmhub-cli/src/domains/commit-validation-render.ts
54492
+ function renderCommitValidation(ctx, result) {
54493
+ if (ctx.format === "json") {
54494
+ ctx.out(JSON.stringify(result));
54495
+ } else if (ctx.format === "jsonl") {
54496
+ for (const operation of result.operations) {
54497
+ ctx.out(JSON.stringify({ type: "operation", ...operation }));
54498
+ }
54499
+ const { operations: _operations, ...summary } = result;
54500
+ ctx.out(JSON.stringify({ type: "summary", ...summary }));
54501
+ } else {
54502
+ renderPrettyValidation(ctx, result);
54503
+ }
54504
+ const error51 = containedDiagnosticError(validationDiagnostics(result));
54505
+ if (error51)
54506
+ ctx.requestedExitCode = error51.code;
54507
+ }
54508
+ function renderPrettyValidation(ctx, result) {
54509
+ const c = ctx.colors;
54510
+ const baseline = result.baseline.kind === "repo_seq" ? `repo sequence ${result.baseline.repoSeq}` : "withheld";
54511
+ ctx.out(`${c.dim}validation baseline${c.reset} ${baseline}`);
54512
+ for (const caveat of result.caveats) {
54513
+ ctx.out(` ${ctx.chars.warn} ${c.dim}${caveat.code}${c.reset} ${caveat.message}`);
54514
+ }
54515
+ for (const operation of result.operations) {
54516
+ const marker = markerFor(operation.status, ctx);
54517
+ ctx.out(`${marker} [${operation.opIndex}] ${operation.operation} ${displayName(c, operation.name)} ${operation.status}`);
54518
+ renderDiagnostics(ctx, operation.status === "error" ? operation.errors : undefined);
54519
+ for (const effect of operation.effects ?? []) {
54520
+ renderEffect(ctx, effect);
54521
+ }
54522
+ }
54523
+ ctx.out(`${c.bold}${result.canCommit ? "can commit" : "cannot commit"}${c.reset} — ${result.counts.wouldApply} would apply, ${result.counts.noop} noop, ${result.counts.error} error`);
54524
+ }
54525
+ function renderEffect(ctx, effect) {
54526
+ ctx.out(` ${markerFor(effect.status, ctx)} effect ${effect.effectIndex}: ${effect.operation} ${displayName(ctx.colors, effect.name)} ${effect.status}`);
54527
+ renderDiagnostics(ctx, "errors" in effect ? effect.errors : undefined, 6);
54528
+ }
54529
+ function renderDiagnostics(ctx, diagnostics, indent = 4) {
54530
+ for (const diagnostic of diagnostics ?? []) {
54531
+ ctx.out(`${" ".repeat(indent)}${diagnostic.code}: ${diagnostic.message}`);
54532
+ }
54533
+ }
54534
+ function markerFor(status, ctx) {
54535
+ if (status === "error" || status === "discarded")
54536
+ return ctx.chars.cross;
54537
+ if (status === "noop")
54538
+ return ctx.chars.warn;
54539
+ return ctx.chars.check;
54540
+ }
54541
+ function validationDiagnostics(result) {
54542
+ const diagnostics = [];
54543
+ for (const operation of result.operations) {
54544
+ if (operation.status === "error")
54545
+ diagnostics.push(...operation.errors);
54546
+ for (const effect of operation.effects ?? []) {
54547
+ if ("errors" in effect)
54548
+ diagnostics.push(...effect.errors);
54549
+ }
54550
+ }
54551
+ return diagnostics;
54552
+ }
54553
+
54554
+ // ../../packages/warmhub-cli/src/domains/thing/remove.ts
54555
+ var USAGE = "Usage: wh thing remove <wref|durableId> [--expected-version <n>] [--yes]";
54556
+ var EXAMPLE = "wh thing remove Location/cave --yes";
54557
+ var removeFlags = {
54558
+ "expected-version": flag.number({
54559
+ description: "only remove if the Thing is still at this version (default: the version read before removing)"
54560
+ }),
54561
+ yes: flag.boolean({ short: "y", description: "Skip confirmation prompt" }),
54562
+ "event-request-id": operationEventRequestIdFlag
54563
+ };
54564
+ var handleThingRemove = async (ctx, { flags, args }) => {
54565
+ const target = args[0];
54566
+ if (!target)
54567
+ usageError(USAGE, EXAMPLE);
54568
+ const { org, repo } = parseOrgRepo(getRepoRef(ctx), ctx.config);
54569
+ const c = ctx.colors;
54570
+ let expectedVersion = parsePositiveIntFlag(flags["expected-version"], "--expected-version", "wh thing remove Location/cave --expected-version 3");
54571
+ let label = target;
54572
+ if (expectedVersion === undefined || !flags.yes && !ctx.dryRun) {
54573
+ const thing = await ctx.client.thing.get(org, repo, target, undefined, {
54574
+ includeRetracted: true
54575
+ });
54576
+ expectedVersion ??= thing.version;
54577
+ label = `${thing.wref} (${thing.metadata?.durableId ?? target})`;
54578
+ }
54579
+ if (ctx.dryRun) {
54580
+ const validation = await ctx.client.commit.validate(org, repo, [
54581
+ { operation: "remove", name: target, expectedVersion }
54582
+ ]);
54583
+ renderCommitValidation(ctx, validation);
54584
+ return;
54585
+ }
54586
+ if (!flags.yes) {
54587
+ const confirmed = await ctx.confirm?.(`Permanently remove ${label} at v${expectedVersion}? This deletes the Thing and all its versions.`);
54588
+ if (!confirmed) {
54589
+ ctx.status("Cancelled");
54590
+ return;
54591
+ }
54592
+ }
54593
+ const eventRequestId = flags["event-request-id"] ?? createOperationEventRequestId();
54594
+ ctx.status(`Operation event request: ${eventRequestId}`);
54595
+ const receipt = await ctx.client.thing.remove(org, repo, target, {
54596
+ eventRequestId,
54597
+ expectedVersion
54598
+ });
54599
+ writeOutput(ctx, receipt, () => {
54600
+ ctx.out(`${c.green}Removed${c.reset} ${displayName(c, label)}`);
54601
+ });
54602
+ };
54603
+
54442
54604
  // ../../packages/warmhub-cli/src/domains/thing/rename.ts
54443
54605
  var renameFlags = {
54444
54606
  "event-request-id": operationEventRequestIdFlag
@@ -55115,6 +55277,19 @@ var THING_DOMAIN = defineDomain({
55115
55277
  ],
55116
55278
  handler: handleThingRetract
55117
55279
  },
55280
+ remove: {
55281
+ prime: false,
55282
+ summary: "Permanently delete a thing and all its versions (needs things:delete)",
55283
+ args: "<wref|durableId>",
55284
+ flags: removeFlags,
55285
+ dryRunBehavior: "execute",
55286
+ examples: [
55287
+ "wh thing remove Location/cave --dry-run",
55288
+ "wh thing remove Location/cave --yes",
55289
+ "wh thing remove 040T1QCTF2Y79... --expected-version 3 --yes"
55290
+ ],
55291
+ handler: handleThingRemove
55292
+ },
55118
55293
  query: {
55119
55294
  prime: true,
55120
55295
  summary: "Query things by filters",
@@ -57645,7 +57820,7 @@ var createFlags3 = {
57645
57820
  };
57646
57821
 
57647
57822
  // ../../packages/warmhub-cli/src/domains/commit-stream-output-contract-id.ts
57648
- var COMMIT_SUBMIT_STREAM_ROW_SCHEMA_ID = "wh.commit.submit.stream.row/v0.4";
57823
+ var COMMIT_SUBMIT_STREAM_ROW_SCHEMA_ID = "wh.commit.submit.stream.row/v0.5";
57649
57824
  function identify(row) {
57650
57825
  if ("schema" in row) {
57651
57826
  throw new Error("Streaming submission row already defines a schema field");
@@ -57661,12 +57836,68 @@ function identifyCommitSubmitStreamRow(row) {
57661
57836
 
57662
57837
  // ../../packages/warmhub-cli/src/domains/commit-submit-template.ts
57663
57838
  import { writeFile } from "node:fs/promises";
57839
+
57840
+ // ../../packages/warmhub-cli/src/domains/shape/composition.ts
57841
+ function capturedShapeMembers(shape) {
57842
+ const data = shape.version?.data;
57843
+ if (Array.isArray(data?.composes) && data.composes.length > 0 && !shape.composition) {
57844
+ throw new CliError(4 /* Backend */, "BACKEND", "The server did not return this Shape’s captured composition. Update the server before scaffolding or displaying inherited fields.");
57845
+ }
57846
+ return shape.composition ?? [];
57847
+ }
57848
+ function effectiveShapeFields(shape) {
57849
+ const data = shape.version?.data;
57850
+ const own = isPlainObject(data?.fields) ? data.fields : {};
57851
+ const fields = structuredClone(own);
57852
+ for (const member of capturedShapeMembers(shape)) {
57853
+ mergeFields(fields, member.fields);
57854
+ }
57855
+ return fields;
57856
+ }
57857
+ function mergeFields(target, source) {
57858
+ for (const [name, spec] of Object.entries(source)) {
57859
+ const bare = name.endsWith("?") ? name.slice(0, -1) : name;
57860
+ if (name.endsWith("?") && Object.hasOwn(target, bare)) {
57861
+ const required2 = target[bare];
57862
+ if (isPlainObject(required2) && !isTypeSpecObject(required2) && isPlainObject(spec) && !isTypeSpecObject(spec)) {
57863
+ mergeFields(required2, spec);
57864
+ }
57865
+ continue;
57866
+ }
57867
+ const optionalName = `${name}?`;
57868
+ if (!name.endsWith("?") && Object.hasOwn(target, optionalName)) {
57869
+ const optional2 = target[optionalName];
57870
+ delete target[optionalName];
57871
+ Object.defineProperty(target, name, {
57872
+ configurable: true,
57873
+ enumerable: true,
57874
+ writable: true,
57875
+ value: isPlainObject(optional2) && !isTypeSpecObject(optional2) && isPlainObject(spec) && !isTypeSpecObject(spec) ? optional2 : spec
57876
+ });
57877
+ }
57878
+ const current = Object.hasOwn(target, name) ? target[name] : undefined;
57879
+ if (isPlainObject(current) && !isTypeSpecObject(current) && isPlainObject(spec) && !isTypeSpecObject(spec)) {
57880
+ mergeFields(current, spec);
57881
+ } else if (current === undefined) {
57882
+ Object.defineProperty(target, name, {
57883
+ configurable: true,
57884
+ enumerable: true,
57885
+ writable: true,
57886
+ value: spec
57887
+ });
57888
+ }
57889
+ }
57890
+ }
57891
+
57892
+ // ../../packages/warmhub-cli/src/domains/commit-submit-template.ts
57664
57893
  var WRITE_TEMPLATE_KINDS = ["thing", "assertion"];
57665
- function composesLocalAssertion(shapeData, org, repo) {
57894
+ function composesLocalAssertion(shapeData, org, repo, captured = []) {
57666
57895
  const composes = shapeData?.composes;
57667
- if (!Array.isArray(composes))
57668
- return false;
57669
- return composes.some((entry) => {
57896
+ const candidates = [
57897
+ ...Array.isArray(composes) ? composes : [],
57898
+ ...captured.map((entry) => entry.wref)
57899
+ ];
57900
+ return candidates.some((entry) => {
57670
57901
  if (typeof entry !== "string")
57671
57902
  return false;
57672
57903
  const unversioned = entry.replace(/@(HEAD|v\d+)$/i, "");
@@ -57675,7 +57906,9 @@ function composesLocalAssertion(shapeData, org, repo) {
57675
57906
  }
57676
57907
  async function readTemplateShape(ctx, org, repo, shapeName) {
57677
57908
  try {
57678
- const shape = await ctx.client.shape.get(org, repo, shapeName);
57909
+ const shape = await ctx.client.shape.get(org, repo, shapeName, {
57910
+ includeComposition: true
57911
+ });
57679
57912
  if ((shapeName === "Set" || shapeName === "List") && shape.componentRef !== "warmhub/system") {
57680
57913
  return;
57681
57914
  }
@@ -57722,21 +57955,15 @@ function zeroValueForField(fieldSpec) {
57722
57955
  }
57723
57956
  }
57724
57957
  if (isPlainObject(fieldSpec)) {
57725
- const result = {};
57726
- for (const [key, value] of Object.entries(fieldSpec)) {
57727
- result[key] = zeroValueForField(value);
57728
- }
57729
- return result;
57958
+ return buildTemplateData(fieldSpec);
57730
57959
  }
57731
57960
  return null;
57732
57961
  }
57733
57962
  function buildTemplateData(fields) {
57734
- const data = {};
57735
- for (const [fieldName, fieldSpec] of Object.entries(fields)) {
57736
- const key = fieldName.endsWith("?") ? fieldName.slice(0, -1) : fieldName;
57737
- data[key] = zeroValueForField(fieldSpec);
57738
- }
57739
- return data;
57963
+ return Object.fromEntries(Object.entries(fields).map(([fieldName, fieldSpec]) => [
57964
+ fieldName.endsWith("?") ? fieldName.slice(0, -1) : fieldName,
57965
+ zeroValueForField(fieldSpec)
57966
+ ]));
57740
57967
  }
57741
57968
  var templateFlags = {
57742
57969
  operation: flag.string({
@@ -57817,12 +58044,12 @@ var handleTemplate = async (ctx, { flags, args }) => {
57817
58044
  }
57818
58045
  const shapeVersion = shape.version;
57819
58046
  const shapeData = shapeVersion?.data;
57820
- const fields = shapeData?.fields ?? {};
58047
+ const fields = effectiveShapeFields(shape);
57821
58048
  let aboutPlaceholder;
57822
58049
  if (templateKind === "assertion") {
57823
58050
  aboutPlaceholder = flags.about ? parseCollectionAboutFlag(flags.about) : "Shape/FILL_IN";
57824
58051
  }
57825
- const composesAssertion = composesLocalAssertion(shapeData, org, repo);
58052
+ const composesAssertion = composesLocalAssertion(shapeData, org, repo, shape.composition);
57826
58053
  const emittedKind = templateKind === "assertion" && composesAssertion ? "thing" : templateKind;
57827
58054
  const data = buildTemplateData(fields);
57828
58055
  const emittedData = aboutPlaceholder && emittedKind === "thing" ? { ...data, about: aboutPlaceholder } : data;
@@ -57963,7 +58190,8 @@ function rejectLegacyLifecycleOperations(operations) {
57963
58190
  if (!legacy)
57964
58191
  return;
57965
58192
  const target = legacy.name ? ` ${legacy.name}` : "";
57966
- throw new CliError(2 /* UserInput */, "USER_INPUT", `Commit operation "${legacy.operation}" is not supported.`, undefined, `Use {"operation":"retract","name":"${legacy.name ?? "<wref>"}"} or \`wh commit submit --retract${target}\`.`);
58193
+ const retract = `Use {"operation":"retract","name":"${legacy.name ?? "<wref>"}"} or \`wh commit submit --retract${target}\``;
58194
+ throw new CliError(2 /* UserInput */, "USER_INPUT", `Commit operation "${legacy.operation}" is not supported.`, undefined, legacy.operation === "remove" ? `To delete the Thing permanently, use \`wh thing remove${target || " <wref>"}\`. To withdraw it, ${retract.charAt(0).toLowerCase()}${retract.slice(1)}.` : `${retract}.`);
57967
58195
  }
57968
58196
  function synthesizeCommitMessage(operations) {
57969
58197
  if (operations.length === 0)
@@ -58666,69 +58894,6 @@ function createBoundedCommitValidateInput(org, repo, operations, options) {
58666
58894
  return input;
58667
58895
  }
58668
58896
 
58669
- // ../../packages/warmhub-cli/src/domains/commit-validation-render.ts
58670
- function renderCommitValidation(ctx, result) {
58671
- if (ctx.format === "json") {
58672
- ctx.out(JSON.stringify(result));
58673
- } else if (ctx.format === "jsonl") {
58674
- for (const operation of result.operations) {
58675
- ctx.out(JSON.stringify({ type: "operation", ...operation }));
58676
- }
58677
- const { operations: _operations, ...summary } = result;
58678
- ctx.out(JSON.stringify({ type: "summary", ...summary }));
58679
- } else {
58680
- renderPrettyValidation(ctx, result);
58681
- }
58682
- const error51 = containedDiagnosticError(validationDiagnostics(result));
58683
- if (error51)
58684
- ctx.requestedExitCode = error51.code;
58685
- }
58686
- function renderPrettyValidation(ctx, result) {
58687
- const c = ctx.colors;
58688
- const baseline = result.baseline.kind === "repo_seq" ? `repo sequence ${result.baseline.repoSeq}` : "withheld";
58689
- ctx.out(`${c.dim}validation baseline${c.reset} ${baseline}`);
58690
- for (const caveat of result.caveats) {
58691
- ctx.out(` ${ctx.chars.warn} ${c.dim}${caveat.code}${c.reset} ${caveat.message}`);
58692
- }
58693
- for (const operation of result.operations) {
58694
- const marker = markerFor(operation.status, ctx);
58695
- ctx.out(`${marker} [${operation.opIndex}] ${operation.operation} ${displayName(c, operation.name)} ${operation.status}`);
58696
- renderDiagnostics(ctx, operation.status === "error" ? operation.errors : undefined);
58697
- for (const effect of operation.effects ?? []) {
58698
- renderEffect(ctx, effect);
58699
- }
58700
- }
58701
- ctx.out(`${c.bold}${result.canCommit ? "can commit" : "cannot commit"}${c.reset} — ${result.counts.wouldApply} would apply, ${result.counts.noop} noop, ${result.counts.error} error`);
58702
- }
58703
- function renderEffect(ctx, effect) {
58704
- ctx.out(` ${markerFor(effect.status, ctx)} effect ${effect.effectIndex}: ${effect.operation} ${displayName(ctx.colors, effect.name)} ${effect.status}`);
58705
- renderDiagnostics(ctx, "errors" in effect ? effect.errors : undefined, 6);
58706
- }
58707
- function renderDiagnostics(ctx, diagnostics, indent = 4) {
58708
- for (const diagnostic of diagnostics ?? []) {
58709
- ctx.out(`${" ".repeat(indent)}${diagnostic.code}: ${diagnostic.message}`);
58710
- }
58711
- }
58712
- function markerFor(status, ctx) {
58713
- if (status === "error" || status === "discarded")
58714
- return ctx.chars.cross;
58715
- if (status === "noop")
58716
- return ctx.chars.warn;
58717
- return ctx.chars.check;
58718
- }
58719
- function validationDiagnostics(result) {
58720
- const diagnostics = [];
58721
- for (const operation of result.operations) {
58722
- if (operation.status === "error")
58723
- diagnostics.push(...operation.errors);
58724
- for (const effect of operation.effects ?? []) {
58725
- if ("errors" in effect)
58726
- diagnostics.push(...effect.errors);
58727
- }
58728
- }
58729
- return diagnostics;
58730
- }
58731
-
58732
58897
  // ../../packages/warmhub-cli/src/domains/commit-validation-execute.ts
58733
58898
  async function executeCommitValidation(ctx, args) {
58734
58899
  const options = {
@@ -59695,7 +59860,7 @@ function bindComponentMethodArgs(invocation, method) {
59695
59860
  }
59696
59861
 
59697
59862
  // ../../packages/warmhub-cli/src/component-exec.ts
59698
- var USAGE = "wh component exec <component> <method> [args] --repo org/repo";
59863
+ var USAGE2 = "wh component exec <component> <method> [args] --repo org/repo";
59699
59864
  function methodHelpHint(componentName, methodName, installRepo) {
59700
59865
  return `wh component exec ${componentName} ${methodName} --help --repo ${installRepo}`;
59701
59866
  }
@@ -59749,7 +59914,7 @@ var handleComponentExec = async (ctx, _domain) => {
59749
59914
  const helpRequested = invocation.help;
59750
59915
  const dryRun = invocation.flags["dry-run"] === true;
59751
59916
  if (!invocation.component)
59752
- usageError("Component name is required", USAGE);
59917
+ usageError("Component name is required", USAGE2);
59753
59918
  const componentName = invocation.component;
59754
59919
  const methodName = invocation.method;
59755
59920
  const { org, repo } = parseOrgRepo(getRepoRef(ctx), ctx.config);
@@ -66264,7 +66429,8 @@ var handleView7 = async (ctx, { flags, args }) => {
66264
66429
  const { org, repo: repo2 } = parseOrgRepo(getRepoRef(ctx), ctx.config);
66265
66430
  const c = ctx.colors;
66266
66431
  const result = await ctx.client.shape.get(org, repo2, shapeName, {
66267
- includeRetracted: flags["include-retracted"]
66432
+ includeRetracted: flags["include-retracted"],
66433
+ includeComposition: ctx.format === "pretty"
66268
66434
  });
66269
66435
  writeOutput(ctx, result, () => {
66270
66436
  const shapeVersion = result.version;
@@ -66281,15 +66447,26 @@ var handleView7 = async (ctx, { flags, args }) => {
66281
66447
  ctx.out(` ${c.dim}owner:${c.reset} ${c.yellow}${componentRef}${c.reset}`);
66282
66448
  }
66283
66449
  const fields = shapeData?.fields;
66284
- if (fields) {
66285
- ctx.out(` ${c.dim}fields:${c.reset}`);
66286
- for (const [fieldName, fieldType] of Object.entries(fields)) {
66450
+ const composes = shapeData?.composes;
66451
+ if (Array.isArray(composes) && composes.length > 0) {
66452
+ ctx.out(` ${c.dim}composes:${c.reset} ${composes.map((name) => escapeTerminalTextForDisplay(String(name))).join(", ")}`);
66453
+ }
66454
+ const printFields = (entries) => {
66455
+ for (const [fieldName, fieldType] of Object.entries(entries)) {
66287
66456
  const typeStr = displayFieldType(fieldType);
66288
66457
  const fieldDesc = fieldDescriptionFromSpec(fieldType);
66289
66458
  const descSuffix = fieldDesc ? ` ${c.dim}${escapeTerminalTextForDisplay(fieldDesc)}${c.reset}` : "";
66290
66459
  const safeFieldName = escapeFieldNameForDisplay(fieldName);
66291
66460
  ctx.out(` ${c.cyan}${safeFieldName}${c.reset}: ${c.dim}${typeStr}${c.reset}${descSuffix}`);
66292
66461
  }
66462
+ };
66463
+ if (fields && Object.keys(fields).length > 0) {
66464
+ ctx.out(` ${c.dim}fields:${c.reset}`);
66465
+ printFields(fields);
66466
+ }
66467
+ for (const member of capturedShapeMembers(result)) {
66468
+ ctx.out(` ${c.dim}inherited from ${escapeTerminalTextForDisplay(member.wref)}:${c.reset}`);
66469
+ printFields(member.fields);
66293
66470
  }
66294
66471
  ctx.out("");
66295
66472
  ctx.out(` ${c.dim}Scaffold a write ops file for this shape:${c.reset} ${c.cyan}wh shape template ${result.name ?? shapeName}${c.reset}`);
@@ -70075,7 +70252,7 @@ function resolveLogLevel(flagLevel, env) {
70075
70252
  // package.json
70076
70253
  var package_default3 = {
70077
70254
  name: "@warmhub/cli",
70078
- version: "0.137.0",
70255
+ version: "0.139.0",
70079
70256
  private: false,
70080
70257
  type: "module",
70081
70258
  description: "The wh CLI for WarmHub — create repos, commit and query data, and compound knowledge with your AI agents.",
@@ -70700,5 +70877,5 @@ process.exitCode = interceptedExitCode === undefined ? await runPreparedCli(laun
70700
70877
  version: package_default3.version
70701
70878
  }) : interceptedExitCode;
70702
70879
 
70703
- //# debugId=9B1B476B36DD254E64756E2164756E21
70704
- //# warmhub-cli-build-info {"cliVersion":"0.137.0","sdkVersion":"0.135.0"}
70880
+ //# debugId=07DF6F73C022E9A064756E2164756E21
70881
+ //# warmhub-cli-build-info {"cliVersion":"0.139.0","sdkVersion":"0.137.0"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@warmhub/cli",
3
- "version": "0.137.0",
3
+ "version": "0.139.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.",