@warmhub/cli 0.99.0 → 0.100.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 +912 -513
  2. package/package.json +1 -1
package/dist/wh.js CHANGED
@@ -20466,6 +20466,56 @@ function validateManifestSemantics(manifest) {
20466
20466
  }
20467
20467
  return findings;
20468
20468
  }
20469
+ // ../../packages/rules/src/external-contract.ts
20470
+ var FORBIDDEN_EXTERNAL_FIELDS = new Set([
20471
+ "_id",
20472
+ "_creationTime",
20473
+ "repoId",
20474
+ "orgId",
20475
+ "thingId",
20476
+ "shapeThingId",
20477
+ "aboutThingId",
20478
+ "currentVersionId",
20479
+ "createdInCommitId",
20480
+ "validatedShapeVersionId"
20481
+ ]);
20482
+ function isObject3(value) {
20483
+ return typeof value === "object" && value !== null;
20484
+ }
20485
+ function findForbiddenExternalFields(value) {
20486
+ const leaks = [];
20487
+ const seen = new WeakSet;
20488
+ const visit = (current, path) => {
20489
+ if (!isObject3(current))
20490
+ return;
20491
+ if (seen.has(current))
20492
+ return;
20493
+ seen.add(current);
20494
+ if (Array.isArray(current)) {
20495
+ for (const [index, child] of current.entries()) {
20496
+ visit(child, `${path}[${index}]`);
20497
+ }
20498
+ return;
20499
+ }
20500
+ for (const [key, child] of Object.entries(current)) {
20501
+ const nextPath = path === "$" ? `$.${key}` : `${path}.${key}`;
20502
+ if (FORBIDDEN_EXTERNAL_FIELDS.has(key)) {
20503
+ leaks.push({ key, path: nextPath });
20504
+ }
20505
+ visit(child, nextPath);
20506
+ }
20507
+ };
20508
+ visit(value, "$");
20509
+ return leaks;
20510
+ }
20511
+ function assertNoForbiddenExternalFields(value, context = "external payload") {
20512
+ const leaks = findForbiddenExternalFields(value);
20513
+ if (leaks.length === 0)
20514
+ return;
20515
+ const details = leaks.slice(0, 8).map((leak) => `${leak.path} (${leak.key})`).join(", ");
20516
+ const extra = leaks.length > 8 ? ` (+${leaks.length - 8} more)` : "";
20517
+ throw new Error(`Forbidden external identity field leak in ${context}: ${details}${extra}`);
20518
+ }
20469
20519
  // ../../packages/rules/src/field-name-safety.ts
20470
20520
  var ESCAPE_DISPLAY_MAX_CHARS = 120;
20471
20521
  var DANGEROUS_FORMAT_CODEPOINTS = new Set([
@@ -21486,7 +21536,7 @@ __export(exports_util, {
21486
21536
  joinValues: () => joinValues,
21487
21537
  issue: () => issue,
21488
21538
  isPlainObject: () => isPlainObject,
21489
- isObject: () => isObject3,
21539
+ isObject: () => isObject4,
21490
21540
  hexToUint8Array: () => hexToUint8Array,
21491
21541
  getSizableOrigin: () => getSizableOrigin,
21492
21542
  getParsedType: () => getParsedType,
@@ -21649,7 +21699,7 @@ function slugify(input) {
21649
21699
  return input.toLowerCase().trim().replace(/[^\w\s-]/g, "").replace(/[\s_-]+/g, "-").replace(/^-+|-+$/g, "");
21650
21700
  }
21651
21701
  var captureStackTrace = "captureStackTrace" in Error ? Error.captureStackTrace : (..._args) => {};
21652
- function isObject3(data) {
21702
+ function isObject4(data) {
21653
21703
  return typeof data === "object" && data !== null && !Array.isArray(data);
21654
21704
  }
21655
21705
  var allowsEval = /* @__PURE__ */ cached(() => {
@@ -21668,7 +21718,7 @@ var allowsEval = /* @__PURE__ */ cached(() => {
21668
21718
  }
21669
21719
  });
21670
21720
  function isPlainObject(o) {
21671
- if (isObject3(o) === false)
21721
+ if (isObject4(o) === false)
21672
21722
  return false;
21673
21723
  const ctor = o.constructor;
21674
21724
  if (ctor === undefined)
@@ -21676,7 +21726,7 @@ function isPlainObject(o) {
21676
21726
  if (typeof ctor !== "function")
21677
21727
  return true;
21678
21728
  const prot = ctor.prototype;
21679
- if (isObject3(prot) === false)
21729
+ if (isObject4(prot) === false)
21680
21730
  return false;
21681
21731
  if (Object.prototype.hasOwnProperty.call(prot, "isPrototypeOf") === false) {
21682
21732
  return false;
@@ -23885,13 +23935,13 @@ var $ZodObject = /* @__PURE__ */ $constructor("$ZodObject", (inst, def) => {
23885
23935
  }
23886
23936
  return propValues;
23887
23937
  });
23888
- const isObject4 = isObject3;
23938
+ const isObject5 = isObject4;
23889
23939
  const catchall = def.catchall;
23890
23940
  let value;
23891
23941
  inst._zod.parse = (payload, ctx) => {
23892
23942
  value ?? (value = _normalized.value);
23893
23943
  const input = payload.value;
23894
- if (!isObject4(input)) {
23944
+ if (!isObject5(input)) {
23895
23945
  payload.issues.push({
23896
23946
  expected: "object",
23897
23947
  code: "invalid_type",
@@ -24018,7 +24068,7 @@ var $ZodObjectJIT = /* @__PURE__ */ $constructor("$ZodObjectJIT", (inst, def) =>
24018
24068
  return (payload, ctx) => fn(shape, payload, ctx);
24019
24069
  };
24020
24070
  let fastpass;
24021
- const isObject4 = isObject3;
24071
+ const isObject5 = isObject4;
24022
24072
  const jit = !globalConfig.jitless;
24023
24073
  const allowsEval2 = allowsEval;
24024
24074
  const fastEnabled = jit && allowsEval2.value;
@@ -24027,7 +24077,7 @@ var $ZodObjectJIT = /* @__PURE__ */ $constructor("$ZodObjectJIT", (inst, def) =>
24027
24077
  inst._zod.parse = (payload, ctx) => {
24028
24078
  value ?? (value = _normalized.value);
24029
24079
  const input = payload.value;
24030
- if (!isObject4(input)) {
24080
+ if (!isObject5(input)) {
24031
24081
  payload.issues.push({
24032
24082
  expected: "object",
24033
24083
  code: "invalid_type",
@@ -24203,7 +24253,7 @@ var $ZodDiscriminatedUnion = /* @__PURE__ */ $constructor("$ZodDiscriminatedUnio
24203
24253
  });
24204
24254
  inst._zod.parse = (payload, ctx) => {
24205
24255
  const input = payload.value;
24206
- if (!isObject3(input)) {
24256
+ if (!isObject4(input)) {
24207
24257
  payload.issues.push({
24208
24258
  code: "invalid_type",
24209
24259
  expected: "object",
@@ -42856,6 +42906,273 @@ function commitValidateRequestBodyBytes(input) {
42856
42906
  return new TextEncoder().encode(encodeCommitValidateRequestBody(input)).byteLength;
42857
42907
  }
42858
42908
 
42909
+ // ../../packages/rules/src/crockford-base32.ts
42910
+ var ALPHABET = "0123456789ABCDEFGHJKMNPQRSTVWXYZ";
42911
+ var DECODE_TABLE = new Uint8Array(256).fill(255);
42912
+ for (let i = 0;i < ALPHABET.length; i++) {
42913
+ const ch = ALPHABET.charCodeAt(i);
42914
+ DECODE_TABLE[ch] = i;
42915
+ if (ch >= 65)
42916
+ DECODE_TABLE[ch + 32] = i;
42917
+ }
42918
+ function encodeBytes(data) {
42919
+ const bitLen = data.length * 8;
42920
+ const charCount = Math.ceil(bitLen / 5);
42921
+ let out = "";
42922
+ for (let i = 0;i < charCount; i++) {
42923
+ const bitPos = i * 5;
42924
+ const byteIdx = bitPos >> 3;
42925
+ const bitOff = bitPos & 7;
42926
+ const b1 = data[byteIdx] ?? 0;
42927
+ let val;
42928
+ if (bitOff <= 3) {
42929
+ val = b1 >> 3 - bitOff & 31;
42930
+ } else {
42931
+ const b2 = data[byteIdx + 1] ?? 0;
42932
+ val = (b1 << bitOff - 3 | b2 >> 11 - bitOff) & 31;
42933
+ }
42934
+ out += ALPHABET[val];
42935
+ }
42936
+ return out;
42937
+ }
42938
+ function decodeBytes(encoded) {
42939
+ const byteLen = Math.floor(encoded.length * 5 / 8);
42940
+ const bytes = new Uint8Array(byteLen);
42941
+ let bitBuf = 0;
42942
+ let bitsInBuf = 0;
42943
+ let bytePos = 0;
42944
+ for (let i = 0;i < encoded.length; i++) {
42945
+ const ch = encoded.charCodeAt(i);
42946
+ const val = DECODE_TABLE[ch];
42947
+ if (val === undefined || val === 255)
42948
+ return null;
42949
+ bitBuf = bitBuf << 5 | val;
42950
+ bitsInBuf += 5;
42951
+ if (bitsInBuf >= 8) {
42952
+ bitsInBuf -= 8;
42953
+ if (bytePos < byteLen) {
42954
+ bytes[bytePos++] = bitBuf >> bitsInBuf & 255;
42955
+ }
42956
+ }
42957
+ }
42958
+ return bytes;
42959
+ }
42960
+
42961
+ // ../../packages/rules/src/durable-id.ts
42962
+ var THING_SCHEME = 1;
42963
+ var REPO_SCHEME = 2;
42964
+ var UUID_BYTES = 16;
42965
+ var CRC_BYTES = 4;
42966
+ function encodedLengthFor(payloadLen) {
42967
+ return Math.ceil((1 + payloadLen + CRC_BYTES) * 8 / 5);
42968
+ }
42969
+ var CRC32C_TABLE = (() => {
42970
+ const POLY = 2197175160;
42971
+ const table = new Uint32Array(256);
42972
+ for (let i = 0;i < 256; i++) {
42973
+ let crc = i;
42974
+ for (let j = 0;j < 8; j++) {
42975
+ crc = crc & 1 ? crc >>> 1 ^ POLY : crc >>> 1;
42976
+ }
42977
+ table[i] = crc >>> 0;
42978
+ }
42979
+ return table;
42980
+ })();
42981
+ function crc32c(data) {
42982
+ let crc = 4294967295;
42983
+ for (const byte of data) {
42984
+ crc = (crc >>> 8 ^ (CRC32C_TABLE[(crc ^ byte) & 255] ?? 0)) >>> 0;
42985
+ }
42986
+ return (crc ^ 4294967295) >>> 0;
42987
+ }
42988
+ function bytesToUuid(bytes, offset = 0) {
42989
+ const hex3 = Array.from(bytes.slice(offset, offset + 16)).map((b) => b.toString(16).padStart(2, "0")).join("");
42990
+ return [
42991
+ hex3.slice(0, 8),
42992
+ hex3.slice(8, 12),
42993
+ hex3.slice(12, 16),
42994
+ hex3.slice(16, 20),
42995
+ hex3.slice(20, 32)
42996
+ ].join("-");
42997
+ }
42998
+ function unpackToken(scheme, token, payloadLen) {
42999
+ const stripped = token.startsWith("wh:") ? token.slice(3) : token;
43000
+ if (stripped.length !== encodedLengthFor(payloadLen))
43001
+ return null;
43002
+ const raw = decodeBytes(stripped);
43003
+ if (!raw || raw.length !== 1 + payloadLen + CRC_BYTES)
43004
+ return null;
43005
+ if (raw[0] !== scheme)
43006
+ return null;
43007
+ const crcOffset = 1 + payloadLen;
43008
+ const storedCrc = (raw[crcOffset] ?? 0) << 24 | (raw[crcOffset + 1] ?? 0) << 16 | (raw[crcOffset + 2] ?? 0) << 8 | (raw[crcOffset + 3] ?? 0);
43009
+ const computedCrc = crc32c(raw.slice(0, crcOffset));
43010
+ if (storedCrc >>> 0 !== computedCrc >>> 0)
43011
+ return null;
43012
+ if (encodeBytes(raw) !== stripped.toUpperCase())
43013
+ return null;
43014
+ return raw.slice(1, 1 + payloadLen);
43015
+ }
43016
+ function decodeDurableId(token) {
43017
+ const payload = unpackToken(THING_SCHEME, token, UUID_BYTES * 2);
43018
+ if (!payload)
43019
+ return null;
43020
+ return {
43021
+ repoId: bytesToUuid(payload, 0),
43022
+ thingId: bytesToUuid(payload, UUID_BYTES)
43023
+ };
43024
+ }
43025
+ var VERSION_SELECTOR_RE = /^(?:v0*[1-9]\d*|[Hh][Ee][Aa][Dd]|[Aa][Ll][Ll])$/;
43026
+ function parseDurableReferenceToken(raw) {
43027
+ const at = raw.lastIndexOf("@");
43028
+ const selector = at >= 0 && VERSION_SELECTOR_RE.test(raw.slice(at + 1)) ? raw.slice(at + 1) : null;
43029
+ const core2 = selector === null ? raw : raw.slice(0, at);
43030
+ if (decodeDurableId(core2) === null)
43031
+ return null;
43032
+ const stripped = core2.startsWith("wh:") ? core2.slice(3) : core2;
43033
+ return { durableId: stripped.toUpperCase(), selector };
43034
+ }
43035
+ function decodeRepoDurableId(token) {
43036
+ const payload = unpackToken(REPO_SCHEME, token, UUID_BYTES);
43037
+ if (!payload)
43038
+ return null;
43039
+ return { repoId: bytesToUuid(payload, 0) };
43040
+ }
43041
+
43042
+ // ../../packages/rules/src/json-string-walk.ts
43043
+ function walkJsonStringLeaves(value, spec) {
43044
+ const { childContext, onStringValue, onObjectKey } = spec;
43045
+ const stack = [{ value, context: spec.rootContext }];
43046
+ while (stack.length > 0) {
43047
+ const { value: current, context } = stack.pop();
43048
+ if (typeof current === "string") {
43049
+ onStringValue(current, context);
43050
+ continue;
43051
+ }
43052
+ if (Array.isArray(current)) {
43053
+ for (let i = current.length - 1;i >= 0; i--) {
43054
+ stack.push({ value: current[i], context: childContext(context, i) });
43055
+ }
43056
+ continue;
43057
+ }
43058
+ if (!isPlainObject2(current))
43059
+ continue;
43060
+ const entries = Object.entries(current).map(([key, nested]) => [key, childContext(context, key), nested]);
43061
+ if (onObjectKey) {
43062
+ for (const [key, keyContext] of entries) {
43063
+ onObjectKey(key, keyContext);
43064
+ }
43065
+ }
43066
+ for (let i = entries.length - 1;i >= 0; i--) {
43067
+ const entry = entries[i];
43068
+ if (entry)
43069
+ stack.push({ value: entry[2], context: entry[1] });
43070
+ }
43071
+ }
43072
+ }
43073
+
43074
+ // ../../packages/rules/src/durable-token-collection.ts
43075
+ function collectDurableTokens(value) {
43076
+ const tokens = new Set;
43077
+ walkJsonStringLeaves(value, {
43078
+ rootContext: { key: null, parentKey: null, insideData: false },
43079
+ childContext: (parent, key) => ({
43080
+ key,
43081
+ parentKey: parent.key,
43082
+ insideData: parent.insideData || key === "data"
43083
+ }),
43084
+ onStringValue: (leaf, context) => {
43085
+ if (context.key === "durableId" && context.parentKey === "metadata" && !context.insideData) {
43086
+ return;
43087
+ }
43088
+ const parsed = parseDurableReferenceToken(leaf);
43089
+ if (parsed)
43090
+ tokens.add(parsed.durableId);
43091
+ }
43092
+ });
43093
+ return tokens;
43094
+ }
43095
+
43096
+ // ../../packages/sdk-ts/src/decoration.ts
43097
+ function buildDecorations(items) {
43098
+ const decorations = {};
43099
+ for (const item of items) {
43100
+ decorations[item.durableId] = item.canonicalWref;
43101
+ }
43102
+ return decorations;
43103
+ }
43104
+ function isObjectPayload(data) {
43105
+ return typeof data === "object" && data !== null && !Array.isArray(data);
43106
+ }
43107
+ function getResponseDecorations(result) {
43108
+ if (!isObjectPayload(result))
43109
+ return;
43110
+ const decorations = result.decorations;
43111
+ return isObjectPayload(decorations) ? decorations : undefined;
43112
+ }
43113
+ function markDecorationFailure(error51) {
43114
+ const marked = error51 instanceof Error ? error51 : new Error(String(error51));
43115
+ return Object.assign(marked, { decorationFailure: true });
43116
+ }
43117
+ function createDecorationLink(deps) {
43118
+ return () => ({ op, next }) => {
43119
+ if (!deps.enabled || op.type !== "query" || op.path === "thing.headVersions") {
43120
+ return next(op);
43121
+ }
43122
+ return observable((observer) => {
43123
+ let cancelled = false;
43124
+ let upstreamDone = false;
43125
+ let lookupInFlight = false;
43126
+ const maybeComplete = () => {
43127
+ if (!cancelled && upstreamDone && !lookupInFlight) {
43128
+ observer.complete();
43129
+ }
43130
+ };
43131
+ const subscription = next(op).subscribe({
43132
+ next: (envelope) => {
43133
+ const data = envelope.result?.data;
43134
+ if (!isObjectPayload(data)) {
43135
+ observer.next(envelope);
43136
+ return;
43137
+ }
43138
+ const tokens = collectDurableTokens(data);
43139
+ if (tokens.size === 0) {
43140
+ observer.next(envelope);
43141
+ return;
43142
+ }
43143
+ lookupInFlight = true;
43144
+ deps.getClient().thing.headVersions(undefined, undefined, [...tokens]).then(({ items }) => {
43145
+ if (cancelled)
43146
+ return;
43147
+ observer.next({
43148
+ ...envelope,
43149
+ result: {
43150
+ ...envelope.result,
43151
+ data: { ...data, decorations: buildDecorations(items) }
43152
+ }
43153
+ });
43154
+ }).catch((error51) => {
43155
+ if (cancelled)
43156
+ return;
43157
+ observer.error(TRPCClientError.from(markDecorationFailure(error51)));
43158
+ }).finally(() => {
43159
+ lookupInFlight = false;
43160
+ maybeComplete();
43161
+ });
43162
+ },
43163
+ error: (error51) => observer.error(error51),
43164
+ complete: () => {
43165
+ upstreamDone = true;
43166
+ maybeComplete();
43167
+ }
43168
+ });
43169
+ return () => {
43170
+ cancelled = true;
43171
+ subscription.unsubscribe();
43172
+ };
43173
+ });
43174
+ };
43175
+ }
42859
43176
  // ../../packages/sdk-ts/src/grant-client.ts
42860
43177
  function createGrantClient(getTrpc, mapError) {
42861
43178
  return {
@@ -44164,7 +44481,7 @@ function createStreamingSubmissionHandle(input, deps) {
44164
44481
  // ../../packages/sdk-ts/package.json
44165
44482
  var package_default = {
44166
44483
  name: "@warmhub/sdk-ts",
44167
- version: "0.97.0",
44484
+ version: "0.98.0",
44168
44485
  private: false,
44169
44486
  type: "module",
44170
44487
  description: "The TypeScript SDK for WarmHub — create repos, commit and query data, and compound knowledge with your AI agents.",
@@ -44342,15 +44659,17 @@ function isProductionApiUrl(apiUrl, productionApiUrl) {
44342
44659
  }
44343
44660
  }
44344
44661
  // ../../packages/sdk-ts/src/index.ts
44345
- var WARMHUB_CLIENT_OPTION_NAMES = [
44346
- "apiUrl",
44347
- "fetch",
44348
- "accessToken",
44349
- "auth",
44350
- "functionLogs",
44351
- "client",
44352
- "clientFlags"
44353
- ];
44662
+ var WARMHUB_CLIENT_OPTIONS = {
44663
+ apiUrl: true,
44664
+ fetch: true,
44665
+ accessToken: true,
44666
+ auth: true,
44667
+ functionLogs: true,
44668
+ client: true,
44669
+ clientFlags: true,
44670
+ decorateResponses: true
44671
+ };
44672
+ var WARMHUB_CLIENT_OPTION_NAMES = Object.keys(WARMHUB_CLIENT_OPTIONS);
44354
44673
  var WARMHUB_CLIENT_OPTION_NAME_SET = new Set(WARMHUB_CLIENT_OPTION_NAMES);
44355
44674
  var ACCESS_TOKEN_OPTION_ALIASES = new Set(["token", "apiKey", "bearer"]);
44356
44675
  function validateWarmHubClientOptions(options) {
@@ -44718,6 +45037,7 @@ class WarmHubClient {
44718
45037
  accessToken;
44719
45038
  clientIdentity;
44720
45039
  clientFlags;
45040
+ decorateResponses;
44721
45041
  functionLogMode;
44722
45042
  getToken;
44723
45043
  compatibilityCheck;
@@ -46673,6 +46993,7 @@ class WarmHubClient {
46673
46993
  version: options?.client?.version ?? SDK_VERSION
46674
46994
  };
46675
46995
  this.clientFlags = normalizeClientFlags(options?.clientFlags);
46996
+ this.decorateResponses = options?.decorateResponses ?? false;
46676
46997
  if (typeof this.accessToken === "function") {
46677
46998
  const provider = this.accessToken;
46678
46999
  this.getToken = async () => await provider();
@@ -46686,6 +47007,10 @@ class WarmHubClient {
46686
47007
  value: createTRPCClient({
46687
47008
  links: [
46688
47009
  this.createCompatibilityLink(),
47010
+ createDecorationLink({
47011
+ enabled: this.decorateResponses,
47012
+ getClient: () => this
47013
+ }),
46689
47014
  splitLink({
46690
47015
  condition: (op) => UNBATCHED_TRPC_PATHS.has(op.path),
46691
47016
  true: httpLink({ url: url2, fetch: fetch2, methodOverride: "POST" }),
@@ -46704,7 +47029,8 @@ class WarmHubClient {
46704
47029
  fetch: this.fetchImpl,
46705
47030
  accessToken,
46706
47031
  client: this.clientIdentity,
46707
- clientFlags: this.clientFlags
47032
+ clientFlags: this.clientFlags,
47033
+ decorateResponses: this.decorateResponses
46708
47034
  });
46709
47035
  }
46710
47036
  actions = this.action;
@@ -47403,7 +47729,15 @@ function printCliError(err, errWriter, opts = {}) {
47403
47729
 
47404
47730
  // ../../packages/warmhub-cli/src/errors.ts
47405
47731
  function fromWh(exit, kind, err, hint = err.hint) {
47406
- return new CliError(exit, kind, err.message, err, hint, undefined, err.errorCode);
47732
+ return appendDecorationHint(err, new CliError(exit, kind, err.message, err, hint, undefined, err.errorCode));
47733
+ }
47734
+ var DECORATION_FAILURE_HINT = "This failure came from the --decorate label lookup; the read itself may be fine. Retry with --no-decorate to skip decoration.";
47735
+ function appendDecorationHint(err, cliError) {
47736
+ if (err.decorationFailure !== true)
47737
+ return cliError;
47738
+ const hint = cliError.hint ? `${cliError.hint}
47739
+ ${DECORATION_FAILURE_HINT}` : DECORATION_FAILURE_HINT;
47740
+ return new CliError(cliError.code, cliError.kind, cliError.message, cliError.cause, hint, cliError.context, cliError.backendCode, cliError.recovery);
47407
47741
  }
47408
47742
  function classifyAuthError(input) {
47409
47743
  if (input.code !== "UNAUTHENTICATED" && input.code !== "FORBIDDEN") {
@@ -47463,7 +47797,7 @@ function toCliError(err) {
47463
47797
  backendCode: err.errorCode
47464
47798
  });
47465
47799
  if (authError)
47466
- return authError;
47800
+ return appendDecorationHint(err, authError);
47467
47801
  if (isFieldIndexErrorCode(err.code)) {
47468
47802
  const exit = err.code === "FIELD_NOT_INDEXABLE" ? 2 /* UserInput */ : 4 /* Backend */;
47469
47803
  return fromWh(exit, err.code, err);
@@ -48940,11 +49274,18 @@ async function modifyStore(mutator, path) {
48940
49274
  return result;
48941
49275
  });
48942
49276
  }
48943
- async function saveProfileWithFlagsLocked(name, profile, flags, path) {
49277
+ async function saveProfileWithFlagsLocked(name, profile, flags, decorate, path) {
48944
49278
  await modifyStore((store) => {
48945
- const stored = hasProfile(store, name) ? store.profiles[name]?.flags : undefined;
48946
- const resolved = flags ?? (Array.isArray(stored) ? stored : undefined);
48947
- setProfile(store, name, resolved?.length ? { ...profile, flags: [...resolved] } : profile);
49279
+ const stored = hasProfile(store, name) ? store.profiles[name] : undefined;
49280
+ const resolvedFlags = flags ?? (Array.isArray(stored?.flags) ? stored.flags : undefined);
49281
+ const resolvedDecorate = decorate ?? stored?.settings?.decorate;
49282
+ const next = { ...profile };
49283
+ if (resolvedFlags?.length)
49284
+ next.flags = [...resolvedFlags];
49285
+ if (resolvedDecorate !== undefined) {
49286
+ next.settings = { decorate: resolvedDecorate };
49287
+ }
49288
+ setProfile(store, name, next);
48948
49289
  }, path);
48949
49290
  }
48950
49291
  async function deleteProfileLocked(name, path) {
@@ -49325,7 +49666,8 @@ function createClient(config2, opts = {}) {
49325
49666
  fetch: createBenchmarkAwareFetch(benchmarkId, opts.signal),
49326
49667
  functionLogs: opts.functionLogs,
49327
49668
  client: cliClientIdentity(),
49328
- clientFlags: opts.clientFlags
49669
+ clientFlags: opts.clientFlags,
49670
+ decorateResponses: opts.decorateResponses
49329
49671
  });
49330
49672
  }
49331
49673
  function createUnauthenticatedClient(config2, opts = {}) {
@@ -49335,7 +49677,8 @@ function createUnauthenticatedClient(config2, opts = {}) {
49335
49677
  fetch: createBenchmarkAwareFetch(benchmarkId, opts.signal),
49336
49678
  functionLogs: opts.functionLogs,
49337
49679
  client: cliClientIdentity(),
49338
- clientFlags: opts.clientFlags
49680
+ clientFlags: opts.clientFlags,
49681
+ decorateResponses: opts.decorateResponses
49339
49682
  });
49340
49683
  }
49341
49684
  function wantsStructuredLiveOutput(format) {
@@ -49369,7 +49712,8 @@ async function runLive(opts) {
49369
49712
  fetch: createBenchmarkAwareFetch(benchmarkId, controller.signal),
49370
49713
  functionLogs: opts.functionLogs,
49371
49714
  client: cliClientIdentity(),
49372
- clientFlags: opts.clientFlags
49715
+ clientFlags: opts.clientFlags,
49716
+ decorateResponses: opts.decorateResponses
49373
49717
  });
49374
49718
  if (opts.signal) {
49375
49719
  if (opts.signal.aborted)
@@ -49724,6 +50068,24 @@ var FLAG_CATALOG = [
49724
50068
  description: "Emit a dispatch plan; commit submit instead runs server validation"
49725
50069
  }
49726
50070
  },
50071
+ {
50072
+ scope: "global",
50073
+ spec: {
50074
+ long: "decorate",
50075
+ type: "boolean",
50076
+ description: "Resolve durable-id references to labels (default: on; adds label lookups when references are present)",
50077
+ conflictsWith: ["no-decorate"]
50078
+ }
50079
+ },
50080
+ {
50081
+ scope: "global",
50082
+ spec: {
50083
+ long: "no-decorate",
50084
+ type: "boolean",
50085
+ description: "Render durable-id references as raw tokens (no lookup)",
50086
+ conflictsWith: ["decorate"]
50087
+ }
50088
+ },
49727
50089
  {
49728
50090
  scope: "root",
49729
50091
  spec: {
@@ -49733,6 +50095,11 @@ var FLAG_CATALOG = [
49733
50095
  }
49734
50096
  }
49735
50097
  ];
50098
+ function explicitDecorateFlag(flags) {
50099
+ if (flags["no-decorate"] === true)
50100
+ return false;
50101
+ return typeof flags.decorate === "boolean" ? flags.decorate : undefined;
50102
+ }
49736
50103
  var GLOBAL_FLAG_SPECS = FLAG_CATALOG.filter((entry) => entry.scope === "global").map((entry) => entry.spec);
49737
50104
  var CONTEXTUAL_CONTROL_SPECS = FLAG_CATALOG.filter((entry) => entry.scope === "contextual").map((entry) => entry.spec);
49738
50105
  var ROOT_CONTROL_SPECS = FLAG_CATALOG.filter((entry) => entry.scope === "root").map((entry) => entry.spec);
@@ -50251,6 +50618,23 @@ function isInstallSnapshotCacheShape(value) {
50251
50618
  return true;
50252
50619
  }
50253
50620
 
50621
+ // ../../packages/warmhub-cli/src/pagination.ts
50622
+ async function* paginatePages2(args) {
50623
+ let cursor = args.initialCursor;
50624
+ const seenCursors = new Set(cursor ? [cursor] : []);
50625
+ while (true) {
50626
+ const page = await args.fetchPage(cursor);
50627
+ yield page;
50628
+ if (!page.nextCursor)
50629
+ return;
50630
+ if (seenCursors.has(page.nextCursor)) {
50631
+ throw new CliError(4 /* Backend */, "BACKEND", `${args.title} pagination cursor repeated; aborting pagination to avoid an infinite loop.`, undefined, "Retry the operation. If cursors continue to repeat, report this as a backend pagination issue.");
50632
+ }
50633
+ seenCursors.add(page.nextCursor);
50634
+ cursor = page.nextCursor;
50635
+ }
50636
+ }
50637
+
50254
50638
  // ../../packages/warmhub-cli/src/install-snapshot-cache.ts
50255
50639
  var INSTALL_SNAPSHOT_TTL_MS = 5 * 60 * 1000;
50256
50640
  function loadInstallSnapshotCache(repoSlug) {
@@ -50387,15 +50771,15 @@ async function refreshFromSummaries(repoSlug, parsed, activeItems, client, now,
50387
50771
  }
50388
50772
  async function fetchAllSummaries(client, org, repo) {
50389
50773
  const items = [];
50390
- let cursor;
50391
- do {
50392
- const page = await client.component.list(org, repo, {
50774
+ for await (const page of paginatePages2({
50775
+ fetchPage: (cursor) => client.component.list(org, repo, {
50393
50776
  limit: 500,
50394
50777
  cursor
50395
- });
50778
+ }),
50779
+ title: "Component install snapshot"
50780
+ })) {
50396
50781
  items.push(...page.items);
50397
- cursor = page.nextCursor;
50398
- } while (cursor);
50782
+ }
50399
50783
  return items;
50400
50784
  }
50401
50785
  function filterActiveItems(items) {
@@ -50698,55 +51082,27 @@ function findClosest(input, candidates, maxDistance = 2) {
50698
51082
  return best;
50699
51083
  }
50700
51084
 
50701
- // ../../packages/warmhub-cli/src/sanitize.ts
50702
- var FORBIDDEN_EXTERNAL_FIELDS2 = new Set([
50703
- "_id",
50704
- "_creationTime",
50705
- "repoId",
50706
- "orgId",
50707
- "thingId",
50708
- "shapeThingId",
50709
- "aboutThingId",
50710
- "currentVersionId",
50711
- "createdInCommitId",
50712
- "validatedShapeVersionId"
50713
- ]);
50714
- function isObject4(value) {
50715
- return typeof value === "object" && value !== null;
51085
+ // ../../packages/warmhub-cli/src/decorations.ts
51086
+ function rowDecorationsSubset(row, decorations) {
51087
+ if (decorations === undefined)
51088
+ return;
51089
+ let subset;
51090
+ for (const id of collectDurableTokens(row)) {
51091
+ const label = decorations[id];
51092
+ if (label === undefined)
51093
+ continue;
51094
+ subset ??= {};
51095
+ subset[id] = label;
51096
+ }
51097
+ return subset;
50716
51098
  }
50717
- function findForbiddenKeys(value) {
50718
- const leaks = [];
50719
- const seen = new WeakSet;
50720
- const visit = (current, path) => {
50721
- if (!isObject4(current))
50722
- return;
50723
- if (seen.has(current))
50724
- return;
50725
- seen.add(current);
50726
- if (Array.isArray(current)) {
50727
- for (const [index, child] of current.entries()) {
50728
- visit(child, `${path}[${index}]`);
50729
- }
50730
- return;
50731
- }
50732
- for (const [key, child] of Object.entries(current)) {
50733
- const nextPath = path === "$" ? `$.${key}` : `${path}.${key}`;
50734
- if (FORBIDDEN_EXTERNAL_FIELDS2.has(key)) {
50735
- leaks.push({ key, path: nextPath });
50736
- }
50737
- visit(child, nextPath);
50738
- }
50739
- };
50740
- visit(value, "$");
50741
- return leaks;
51099
+ function mergeDecorations(into, page) {
51100
+ if (page === undefined)
51101
+ return into;
51102
+ return { ...into, ...page };
50742
51103
  }
50743
- function assertNoForbiddenKeys(value, context = "external payload") {
50744
- const leaks = findForbiddenKeys(value);
50745
- if (leaks.length === 0)
50746
- return;
50747
- const details = leaks.slice(0, 8).map((leak) => `${leak.path} (${leak.key})`).join(", ");
50748
- const extra = leaks.length > 8 ? ` (+${leaks.length - 8} more)` : "";
50749
- throw new Error(`Forbidden external identity field leak in ${context}: ${details}${extra}`);
51104
+ function withDecorations(result, decorations) {
51105
+ return decorations === undefined ? result : Object.assign(result, { decorations });
50750
51106
  }
50751
51107
 
50752
51108
  // ../../packages/warmhub-cli/src/format.ts
@@ -50791,9 +51147,6 @@ function pinnedWref(c, wref, version2) {
50791
51147
  const base = wref.replace(/@v\d+$/, "");
50792
51148
  return `${c.cyan}${escapeTerminalTextForDisplay(base)}@v${version2}${c.reset}`;
50793
51149
  }
50794
- function formatAffirmedWrefs(c, wrefs) {
50795
- return wrefs.map((wref) => pinnedWref(c, wref)).join(`${c.dim},${c.reset} `);
50796
- }
50797
51150
  function kindLabel(c, kind) {
50798
51151
  return `${c.dim}${kind}${c.reset}`;
50799
51152
  }
@@ -50934,11 +51287,11 @@ function renderSingleOpSuccess(out, c, chars, op, opts) {
50934
51287
  renderWarningLine(out, c, chars, op);
50935
51288
  }
50936
51289
  function printJson(out, data) {
50937
- assertNoForbiddenKeys(data, "CLI JSON output");
51290
+ assertNoForbiddenExternalFields(data, "CLI JSON output");
50938
51291
  out(JSON.stringify(data, null, 2));
50939
51292
  }
50940
51293
  function printJsonLine(out, data) {
50941
- assertNoForbiddenKeys(data, "CLI JSON output");
51294
+ assertNoForbiddenExternalFields(data, "CLI JSON output");
50942
51295
  out(JSON.stringify(data) ?? "null");
50943
51296
  }
50944
51297
  function printJsonl(out, data) {
@@ -50972,6 +51325,7 @@ function pageEnvelope(items, opts) {
50972
51325
  return {
50973
51326
  items,
50974
51327
  ...opts.repoSeq === undefined ? {} : { repoSeq: opts.repoSeq },
51328
+ ...opts.decorations === undefined ? {} : { decorations: opts.decorations },
50975
51329
  page: {
50976
51330
  limit: opts.limit,
50977
51331
  count: items.length,
@@ -50986,11 +51340,22 @@ function writePageOutput(ctx, items, opts, prettyFn) {
50986
51340
  return;
50987
51341
  }
50988
51342
  if (ctx.format === "jsonl") {
50989
- printJsonl(ctx.out, items);
51343
+ printJsonl(ctx.out, decorateJsonlRows(items, opts.decorations));
50990
51344
  return;
50991
51345
  }
50992
51346
  prettyFn();
50993
51347
  }
51348
+ function decorateJsonlRows(items, decorations) {
51349
+ if (decorations === undefined)
51350
+ return items;
51351
+ return items.map((item) => {
51352
+ if (typeof item !== "object" || item === null || Array.isArray(item)) {
51353
+ return item;
51354
+ }
51355
+ const subset = rowDecorationsSubset(item, decorations);
51356
+ return subset === undefined ? item : { ...item, decorations: subset };
51357
+ });
51358
+ }
50994
51359
  function emitPartialPageHint(ctx, count, _nextCursor, _limit) {
50995
51360
  if (ctx.format === "json" || ctx.format === "jsonl")
50996
51361
  return;
@@ -51010,6 +51375,110 @@ function identifyCommitSubmitOutput(value) {
51010
51375
  return { schema: COMMIT_SUBMIT_OUTPUT_SCHEMA_ID, ...value };
51011
51376
  }
51012
51377
 
51378
+ // ../../packages/warmhub-cli/src/durable-id-style.ts
51379
+ var REPO_TOKEN_LEN = 34;
51380
+ var HUE_REPO = "8A7C6A";
51381
+ var HUE_TIMESTAMP = "7E9BAC";
51382
+ var HUE_ENTROPY = "E8C378";
51383
+ var HUE_CRC = "74846B";
51384
+ var THING_BANDS = [
51385
+ { start: 0, end: 28, weight: "faint", hex: HUE_REPO },
51386
+ { start: 28, end: 37, weight: "normal", hex: HUE_TIMESTAMP },
51387
+ { start: 37, end: 53, weight: "bold", hex: HUE_ENTROPY },
51388
+ { start: 53, end: 60, weight: "faint", hex: HUE_CRC }
51389
+ ];
51390
+ var REPO_BANDS = [
51391
+ { start: 0, end: 28, weight: "faint", hex: HUE_REPO },
51392
+ { start: 28, end: 34, weight: "faint", hex: HUE_CRC }
51393
+ ];
51394
+ function fg(hex3) {
51395
+ const r = Number.parseInt(hex3.slice(0, 2), 16);
51396
+ const g = Number.parseInt(hex3.slice(2, 4), 16);
51397
+ const b = Number.parseInt(hex3.slice(4, 6), 16);
51398
+ return `\x1B[38;2;${r};${g};${b}m`;
51399
+ }
51400
+ function styleBand(text, band, c) {
51401
+ const weight = band.weight === "bold" ? c.bold : band.weight === "faint" ? c.dim : "";
51402
+ const hue = c.truecolor ? fg(band.hex) : "";
51403
+ const prefix = `${weight}${hue}`;
51404
+ return prefix === "" ? text : `${prefix}${text}${c.reset}`;
51405
+ }
51406
+ function styleDurableId(token, c) {
51407
+ if (c.reset === "")
51408
+ return token;
51409
+ const parsed = parseDurableReferenceToken(token);
51410
+ if (parsed) {
51411
+ const prefix = token.startsWith("wh:") ? "wh:" : "";
51412
+ const selector = parsed.selector === null ? "" : token.slice(token.lastIndexOf("@"));
51413
+ const core2 = token.slice(prefix.length, token.length - selector.length);
51414
+ return `${dimPart(prefix, c)}${styleBands(core2, THING_BANDS, c)}${dimPart(selector, c)}`;
51415
+ }
51416
+ if (token.length === REPO_TOKEN_LEN && decodeRepoDurableId(token)) {
51417
+ return styleBands(token, REPO_BANDS, c);
51418
+ }
51419
+ return token;
51420
+ }
51421
+ function dimPart(text, c) {
51422
+ return text === "" ? "" : `${c.dim}${text}${c.reset}`;
51423
+ }
51424
+ function styleBands(token, bands, c) {
51425
+ let out = "";
51426
+ for (const band of bands) {
51427
+ out += styleBand(token.slice(band.start, band.end), band, c);
51428
+ }
51429
+ return out;
51430
+ }
51431
+
51432
+ // ../../packages/warmhub-cli/src/reference-display.ts
51433
+ function decoratedRef(c, value, decorations) {
51434
+ const parsed = parseDurableReferenceToken(value);
51435
+ if (!parsed)
51436
+ return null;
51437
+ const label = decorations?.[parsed.durableId];
51438
+ if (label === undefined)
51439
+ return styleDurableId(value, c);
51440
+ return labeledRef(c, value, label);
51441
+ }
51442
+ function labeledRef(c, value, label) {
51443
+ const parsed = parseDurableReferenceToken(value);
51444
+ if (!parsed)
51445
+ return null;
51446
+ const styled = styleDurableId(value, c);
51447
+ const pin = parsed.selector !== null && /^v/i.test(parsed.selector) ? Number.parseInt(parsed.selector.slice(1), 10) : undefined;
51448
+ return `${pinnedWref(c, label, pin)} ${c.dim}(${c.reset}${styled}${c.dim})${c.reset}`;
51449
+ }
51450
+ function refDisplay(c, value, decorations, version2) {
51451
+ return decoratedRef(c, value, decorations) ?? pinnedWref(c, value, version2);
51452
+ }
51453
+ function refList(c, wrefs, decorations) {
51454
+ return wrefs.map((wref) => refDisplay(c, wref, decorations)).join(`${c.dim},${c.reset} `);
51455
+ }
51456
+ var JSON_LINE_STRING_VALUE_RE = /"([^"\\]+)",?$/;
51457
+ function jsonLineLabelSuffix(c, rawLine, decorations) {
51458
+ if (decorations === undefined)
51459
+ return "";
51460
+ const match = JSON_LINE_STRING_VALUE_RE.exec(rawLine);
51461
+ if (!match || match[1] === undefined)
51462
+ return "";
51463
+ const parsed = parseDurableReferenceToken(match[1]);
51464
+ const label = parsed ? decorations[parsed.durableId] : undefined;
51465
+ if (label === undefined)
51466
+ return "";
51467
+ return ` ${c.dim}← ${escapeTerminalTextForDisplay(label)}${c.reset}`;
51468
+ }
51469
+ function renderJsonDataBlock(out, c, data, indent, decorations) {
51470
+ const lines = JSON.stringify(data, null, 2).split(`
51471
+ `);
51472
+ for (const line of lines) {
51473
+ out(`${indent}${escapeTerminalTextForDisplay(line)}${jsonLineLabelSuffix(c, line, decorations)}`);
51474
+ }
51475
+ }
51476
+ function dataPreview(c, data) {
51477
+ const preview = JSON.stringify(data);
51478
+ const truncated = preview.length > 80 ? `${preview.slice(0, 77)}...` : preview;
51479
+ return `${c.dim}${escapeTerminalTextForDisplay(truncated)}${c.reset}`;
51480
+ }
51481
+
51013
51482
  // ../../packages/warmhub-cli/src/domains/assertion/shared.ts
51014
51483
  var COLLECTION_TAGS = ["arc", "bond", "pair", "set", "list"];
51015
51484
  function parseAbout(raw) {
@@ -51025,6 +51494,7 @@ function parseAbout(raw) {
51025
51494
  }
51026
51495
  function renderAbout(out, c, result) {
51027
51496
  const target = result.target;
51497
+ const decorations = getResponseDecorations(result);
51028
51498
  const targetKind = target?.kind ?? "thing";
51029
51499
  const targetWref = target?.wref ?? target?.name ?? "(unknown)";
51030
51500
  out(`${c.bold}About:${c.reset} ${pinnedWref(c, targetWref, target?.version)} ${kindLabel(c, targetKind)}`);
@@ -51040,15 +51510,11 @@ function renderAbout(out, c, result) {
51040
51510
  const wref = a.wref ?? a.name;
51041
51511
  out(` ${pinnedWref(c, wref, a.version)} ${kindLabel(c, a.kind ?? "assertion")}`);
51042
51512
  if (Array.isArray(a.affirmedWrefs) && a.affirmedWrefs.length > 0) {
51043
- out(` ${c.dim}affirms:${c.reset} ${formatAffirmedWrefs(c, a.affirmedWrefs.map(String))}`);
51513
+ out(` ${c.dim}affirms:${c.reset} ${refList(c, a.affirmedWrefs.map(String), decorations)}`);
51044
51514
  }
51045
51515
  if (a.data && typeof a.data === "object") {
51046
51516
  out(` ${c.dim}data:${c.reset}`);
51047
- const lines = JSON.stringify(a.data, null, 2).split(`
51048
- `);
51049
- for (const line of lines) {
51050
- out(` ${line}`);
51051
- }
51517
+ renderJsonDataBlock(out, c, a.data, " ", decorations);
51052
51518
  }
51053
51519
  const children = a.children;
51054
51520
  if (children?.length) {
@@ -51061,11 +51527,7 @@ function renderAbout(out, c, result) {
51061
51527
  out(` ${c.dim}+--${c.reset} ${pinnedWref(c, childWref)} ${childKl}`);
51062
51528
  if (child.data) {
51063
51529
  out(` ${c.dim}data:${c.reset}`);
51064
- const lines = JSON.stringify(child.data, null, 2).split(`
51065
- `);
51066
- for (const line of lines) {
51067
- out(` ${line}`);
51068
- }
51530
+ renderJsonDataBlock(out, c, child.data, " ", decorations);
51069
51531
  }
51070
51532
  }
51071
51533
  }
@@ -51073,9 +51535,10 @@ function renderAbout(out, c, result) {
51073
51535
  }
51074
51536
  async function fetchAllAssertionHeadPages(ctx, org, repo, opts) {
51075
51537
  const items = [];
51076
- let cursor = opts.cursor;
51077
- while (true) {
51078
- const page = await ctx.client.thing.head(org, repo, {
51538
+ let decorations;
51539
+ for await (const page of paginatePages2({
51540
+ initialCursor: opts.cursor,
51541
+ fetchPage: (cursor) => ctx.client.thing.head(org, repo, {
51079
51542
  shape: opts.shape,
51080
51543
  kind: opts.kind,
51081
51544
  match: opts.match,
@@ -51083,20 +51546,21 @@ async function fetchAllAssertionHeadPages(ctx, org, repo, opts) {
51083
51546
  limit: opts.limit,
51084
51547
  cursor,
51085
51548
  ...opts.where ? { where: opts.where } : {}
51086
- });
51549
+ }),
51550
+ title: "Assertion list"
51551
+ })) {
51087
51552
  items.push(...page.items ?? []);
51088
- if (!page.nextCursor)
51089
- break;
51090
- cursor = page.nextCursor;
51553
+ decorations = mergeDecorations(decorations, getResponseDecorations(page));
51091
51554
  }
51092
- return { items, nextCursor: undefined };
51555
+ return withDecorations({ items, nextCursor: undefined }, decorations);
51093
51556
  }
51094
51557
  async function fetchAllAssertionAboutPages(ctx, org, repo, wref, opts) {
51095
51558
  const assertions = [];
51096
- let cursor = opts.cursor;
51559
+ let decorations;
51097
51560
  let target;
51098
- while (true) {
51099
- const page = await ctx.client.thing.about(org, repo, wref, {
51561
+ for await (const page of paginatePages2({
51562
+ initialCursor: opts.cursor,
51563
+ fetchPage: (cursor) => ctx.client.thing.about(org, repo, wref, {
51100
51564
  shape: opts.shape,
51101
51565
  match: opts.match,
51102
51566
  depth: opts.depth,
@@ -51105,18 +51569,18 @@ async function fetchAllAssertionAboutPages(ctx, org, repo, wref, opts) {
51105
51569
  limit: opts.limit,
51106
51570
  cursor,
51107
51571
  ...opts.where ? { where: opts.where } : {}
51108
- });
51572
+ }),
51573
+ title: "Assertion about"
51574
+ })) {
51109
51575
  target = page.target;
51110
51576
  assertions.push(...page.assertions ?? []);
51111
- if (!page.nextCursor)
51112
- break;
51113
- cursor = page.nextCursor;
51577
+ decorations = mergeDecorations(decorations, getResponseDecorations(page));
51114
51578
  }
51115
- return {
51579
+ return withDecorations({
51116
51580
  target,
51117
51581
  assertions,
51118
51582
  nextCursor: undefined
51119
- };
51583
+ }, decorations);
51120
51584
  }
51121
51585
 
51122
51586
  // ../../packages/warmhub-cli/src/domains/assertion/mutators.ts
@@ -51302,7 +51766,7 @@ var handleCreate = async (ctx, { flags, args }) => {
51302
51766
  // ../../packages/warmhub-cli/src/domains/thing/shared.ts
51303
51767
  var CROCKFORD_CHARACTER_PATTERN = "0-9A-HJKMNP-TV-Za-hjkmnp-tv-z";
51304
51768
  var VERSION_SUFFIX_PATTERN = String.raw`(?:v0*[1-9]\d*|[Hh][Ee][Aa][Dd]|[Aa][Ll][Ll])`;
51305
- var DURABLE_ID_PATTERN_RE = new RegExp(`^[${CROCKFORD_CHARACTER_PATTERN}]{60}(?:@${VERSION_SUFFIX_PATTERN})?$`);
51769
+ var DURABLE_ID_PATTERN_RE = new RegExp(`^(?:wh:)?[${CROCKFORD_CHARACTER_PATTERN}]{60}(?:@${VERSION_SUFFIX_PATTERN})?$`);
51306
51770
  var WREF_SEGMENT = String.raw`[^/?#@:\s$]+`;
51307
51771
  var CANONICAL_WREF_PATTERN_RE = new RegExp(`^wh:${WREF_SEGMENT}/${WREF_SEGMENT}/${WREF_SEGMENT}(?:/${WREF_SEGMENT})*(?:@${VERSION_SUFFIX_PATTERN})?$`);
51308
51772
  function looksLikeDurableId(wref) {
@@ -51343,32 +51807,33 @@ function requireIncrementalCheckpoint(repoSeq, required2) {
51343
51807
  }
51344
51808
  async function collectThingPages(args) {
51345
51809
  const items = [];
51346
- let cursor = args.initialCursor;
51347
- const seenCursors = new Set(cursor ? [cursor] : []);
51348
- while (true) {
51349
- const page = await args.fetchPage(cursor);
51810
+ let decorations;
51811
+ for await (const page of paginatePages2({
51812
+ initialCursor: args.initialCursor,
51813
+ fetchPage: args.fetchPage,
51814
+ title: args.title
51815
+ })) {
51350
51816
  const pageItems = page.items ?? [];
51817
+ const pageDecorations = getResponseDecorations(page);
51351
51818
  if (args.onPage) {
51352
- if (!await args.onPage(pageItems)) {
51819
+ if (!await args.onPage(pageItems, pageDecorations)) {
51353
51820
  return { items, nextCursor: undefined };
51354
51821
  }
51355
51822
  } else {
51356
51823
  items.push(...pageItems);
51824
+ decorations = mergeDecorations(decorations, pageDecorations);
51357
51825
  }
51358
51826
  if (!page.nextCursor) {
51359
51827
  requireIncrementalCheckpoint(page.repoSeq, args.requireRepoSeq);
51360
51828
  return {
51361
51829
  items,
51362
51830
  nextCursor: undefined,
51363
- ...page.repoSeq === undefined ? {} : { repoSeq: page.repoSeq }
51831
+ ...page.repoSeq === undefined ? {} : { repoSeq: page.repoSeq },
51832
+ ...decorations === undefined ? {} : { decorations }
51364
51833
  };
51365
51834
  }
51366
- if (seenCursors.has(page.nextCursor)) {
51367
- throw new CliError(4 /* Backend */, "BACKEND", `${args.title} pagination cursor repeated; aborting --all to avoid an infinite loop.`, undefined, "Retry without --all to fetch one page and inspect page.nextCursor. If cursors repeat, report this as a backend pagination issue.");
51368
- }
51369
- seenCursors.add(page.nextCursor);
51370
- cursor = page.nextCursor;
51371
51835
  }
51836
+ throw new Error("paginatePages completed without yielding a terminal page");
51372
51837
  }
51373
51838
  async function handleCount(ctx, org, repo, opts) {
51374
51839
  const result = await ctx.client.thing.count(org, repo, opts);
@@ -51454,33 +51919,40 @@ var handleAbout = async (ctx, { flags, args }) => {
51454
51919
  functionLogs: ctx.functionLogMode,
51455
51920
  profile: ctx.profile,
51456
51921
  clientFlags: ctx.clientFlags,
51922
+ decorateResponses: ctx.decorate,
51457
51923
  signal: ctx.signal
51458
51924
  });
51459
51925
  return;
51460
51926
  }
51461
51927
  if (all) {
51462
51928
  const assertions = [];
51463
- let cur = cursor;
51929
+ let decorations;
51464
51930
  let target;
51465
- while (true) {
51466
- const page = await fetchPage(cur);
51931
+ for await (const page of paginatePages2({
51932
+ initialCursor: cursor,
51933
+ fetchPage,
51934
+ title: "Thing about"
51935
+ })) {
51467
51936
  target = target ?? page.target;
51468
51937
  assertions.push(...page.assertions ?? []);
51469
- if (!page.nextCursor)
51470
- break;
51471
- cur = page.nextCursor;
51938
+ decorations = mergeDecorations(decorations, getResponseDecorations(page));
51472
51939
  }
51473
- const result2 = { target, assertions, nextCursor: undefined };
51474
- writePageOutput(ctx, assertions, { limit: pageLimit, nextCursor: null }, () => renderAboutResult(ctx.out, ctx.colors, result2, wref));
51940
+ const result2 = withDecorations({ target, assertions, nextCursor: undefined }, decorations);
51941
+ writePageOutput(ctx, assertions, { limit: pageLimit, nextCursor: null, decorations }, () => renderAboutResult(ctx.out, ctx.colors, result2, wref));
51475
51942
  return;
51476
51943
  }
51477
51944
  const result = await fetchPage(cursor);
51478
51945
  if (result.nextCursor) {
51479
51946
  emitPartialPageHint(ctx, result.assertions.length, result.nextCursor, boundedLimit);
51480
51947
  }
51481
- writePageOutput(ctx, result.assertions, { limit: boundedLimit, nextCursor: result.nextCursor ?? null }, () => renderAboutResult(ctx.out, ctx.colors, result, wref));
51948
+ writePageOutput(ctx, result.assertions, {
51949
+ limit: boundedLimit,
51950
+ nextCursor: result.nextCursor ?? null,
51951
+ decorations: getResponseDecorations(result)
51952
+ }, () => renderAboutResult(ctx.out, ctx.colors, result, wref));
51482
51953
  };
51483
51954
  function renderAboutResult(out, c, result, wref) {
51955
+ const decorations = getResponseDecorations(result);
51484
51956
  out(`${c.bold}Assertions about${c.reset} ${pinnedWref(c, wref)} (${result.assertions.length}${result.nextCursor ? "+" : ""})`);
51485
51957
  if (result.assertions.length === 0) {
51486
51958
  out(` ${c.dim}(no assertions found)${c.reset}`);
@@ -51490,32 +51962,31 @@ function renderAboutResult(out, c, result, wref) {
51490
51962
  return;
51491
51963
  }
51492
51964
  for (const a of result.assertions) {
51493
- renderAboutAssertion(out, c, a, " ");
51965
+ renderAboutAssertion(out, c, a, " ", decorations);
51494
51966
  }
51495
51967
  if (result.nextCursor) {
51496
51968
  out(`${c.dim}More available. Use --all to fetch every page.${c.reset}`);
51497
51969
  }
51498
51970
  }
51499
- function renderAboutAssertion(out, c, assertion, indent) {
51971
+ function renderAboutAssertion(out, c, assertion, indent, decorations) {
51500
51972
  const sname = assertion.shapeName ?? assertion.shape ?? "?";
51501
51973
  const aWref = assertion.wref ?? (assertion.name ? `${sname}/${assertion.name}` : "(unknown)");
51502
51974
  const retractedTag = assertion.active === false ? ` ${c.red}[RETRACTED]${c.reset}` : "";
51503
51975
  out(`${indent}${pinnedWref(c, aWref, assertion.version)}${retractedTag}`);
51504
51976
  if (assertion.aboutWref) {
51505
- out(`${indent} ${c.dim}about:${c.reset} ${pinnedWref(c, assertion.aboutWref)}`);
51977
+ out(`${indent} ${c.dim}about:${c.reset} ${refDisplay(c, assertion.aboutWref, decorations)}`);
51506
51978
  }
51507
51979
  if (assertion.roles?.length) {
51508
51980
  out(`${indent} ${c.dim}roles:${c.reset} ${assertion.roles.join(", ")}`);
51509
51981
  }
51510
51982
  if (assertion.data && typeof assertion.data === "object") {
51511
- const preview = JSON.stringify(assertion.data);
51512
- out(`${indent} ${c.dim}${preview.length > 80 ? `${preview.slice(0, 77)}...` : preview}${c.reset}`);
51983
+ out(`${indent} ${dataPreview(c, assertion.data)}`);
51513
51984
  }
51514
51985
  const children = assertion.children;
51515
51986
  if (Array.isArray(children)) {
51516
51987
  for (const child of children) {
51517
51988
  if (child && typeof child === "object") {
51518
- renderAboutAssertion(out, c, child, `${indent} `);
51989
+ renderAboutAssertion(out, c, child, `${indent} `, decorations);
51519
51990
  }
51520
51991
  }
51521
51992
  }
@@ -51609,183 +52080,10 @@ var handleCreate2 = async (ctx, { flags, args }) => {
51609
52080
  }));
51610
52081
  };
51611
52082
 
51612
- // ../../packages/rules/src/crockford-base32.ts
51613
- var ALPHABET = "0123456789ABCDEFGHJKMNPQRSTVWXYZ";
51614
- var DECODE_TABLE = new Uint8Array(256).fill(255);
51615
- for (let i = 0;i < ALPHABET.length; i++) {
51616
- const ch = ALPHABET.charCodeAt(i);
51617
- DECODE_TABLE[ch] = i;
51618
- if (ch >= 65)
51619
- DECODE_TABLE[ch + 32] = i;
51620
- }
51621
- function encodeBytes(data) {
51622
- const bitLen = data.length * 8;
51623
- const charCount = Math.ceil(bitLen / 5);
51624
- let out = "";
51625
- for (let i = 0;i < charCount; i++) {
51626
- const bitPos = i * 5;
51627
- const byteIdx = bitPos >> 3;
51628
- const bitOff = bitPos & 7;
51629
- const b1 = data[byteIdx] ?? 0;
51630
- let val;
51631
- if (bitOff <= 3) {
51632
- val = b1 >> 3 - bitOff & 31;
51633
- } else {
51634
- const b2 = data[byteIdx + 1] ?? 0;
51635
- val = (b1 << bitOff - 3 | b2 >> 11 - bitOff) & 31;
51636
- }
51637
- out += ALPHABET[val];
51638
- }
51639
- return out;
51640
- }
51641
- function decodeBytes(encoded) {
51642
- const byteLen = Math.floor(encoded.length * 5 / 8);
51643
- const bytes = new Uint8Array(byteLen);
51644
- let bitBuf = 0;
51645
- let bitsInBuf = 0;
51646
- let bytePos = 0;
51647
- for (let i = 0;i < encoded.length; i++) {
51648
- const ch = encoded.charCodeAt(i);
51649
- const val = DECODE_TABLE[ch];
51650
- if (val === undefined || val === 255)
51651
- return null;
51652
- bitBuf = bitBuf << 5 | val;
51653
- bitsInBuf += 5;
51654
- if (bitsInBuf >= 8) {
51655
- bitsInBuf -= 8;
51656
- if (bytePos < byteLen) {
51657
- bytes[bytePos++] = bitBuf >> bitsInBuf & 255;
51658
- }
51659
- }
51660
- }
51661
- return bytes;
51662
- }
51663
-
51664
- // ../../packages/rules/src/durable-id.ts
51665
- var THING_SCHEME = 1;
51666
- var REPO_SCHEME = 2;
51667
- var UUID_BYTES = 16;
51668
- var CRC_BYTES = 4;
51669
- function encodedLengthFor(payloadLen) {
51670
- return Math.ceil((1 + payloadLen + CRC_BYTES) * 8 / 5);
51671
- }
51672
- var CRC32C_TABLE = (() => {
51673
- const POLY = 2197175160;
51674
- const table = new Uint32Array(256);
51675
- for (let i = 0;i < 256; i++) {
51676
- let crc = i;
51677
- for (let j = 0;j < 8; j++) {
51678
- crc = crc & 1 ? crc >>> 1 ^ POLY : crc >>> 1;
51679
- }
51680
- table[i] = crc >>> 0;
51681
- }
51682
- return table;
51683
- })();
51684
- function crc32c(data) {
51685
- let crc = 4294967295;
51686
- for (const byte of data) {
51687
- crc = (crc >>> 8 ^ (CRC32C_TABLE[(crc ^ byte) & 255] ?? 0)) >>> 0;
51688
- }
51689
- return (crc ^ 4294967295) >>> 0;
51690
- }
51691
- function bytesToUuid(bytes, offset = 0) {
51692
- const hex3 = Array.from(bytes.slice(offset, offset + 16)).map((b) => b.toString(16).padStart(2, "0")).join("");
51693
- return [
51694
- hex3.slice(0, 8),
51695
- hex3.slice(8, 12),
51696
- hex3.slice(12, 16),
51697
- hex3.slice(16, 20),
51698
- hex3.slice(20, 32)
51699
- ].join("-");
51700
- }
51701
- function unpackToken(scheme, token, payloadLen) {
51702
- const stripped = token.startsWith("wh:") ? token.slice(3) : token;
51703
- if (stripped.length !== encodedLengthFor(payloadLen))
51704
- return null;
51705
- const raw = decodeBytes(stripped);
51706
- if (!raw || raw.length !== 1 + payloadLen + CRC_BYTES)
51707
- return null;
51708
- if (raw[0] !== scheme)
51709
- return null;
51710
- const crcOffset = 1 + payloadLen;
51711
- const storedCrc = (raw[crcOffset] ?? 0) << 24 | (raw[crcOffset + 1] ?? 0) << 16 | (raw[crcOffset + 2] ?? 0) << 8 | (raw[crcOffset + 3] ?? 0);
51712
- const computedCrc = crc32c(raw.slice(0, crcOffset));
51713
- if (storedCrc >>> 0 !== computedCrc >>> 0)
51714
- return null;
51715
- if (encodeBytes(raw) !== stripped.toUpperCase())
51716
- return null;
51717
- return raw.slice(1, 1 + payloadLen);
51718
- }
51719
- function decodeDurableId(token) {
51720
- const payload = unpackToken(THING_SCHEME, token, UUID_BYTES * 2);
51721
- if (!payload)
51722
- return null;
51723
- return {
51724
- repoId: bytesToUuid(payload, 0),
51725
- thingId: bytesToUuid(payload, UUID_BYTES)
51726
- };
51727
- }
51728
- function decodeRepoDurableId(token) {
51729
- const payload = unpackToken(REPO_SCHEME, token, UUID_BYTES);
51730
- if (!payload)
51731
- return null;
51732
- return { repoId: bytesToUuid(payload, 0) };
51733
- }
51734
-
51735
- // ../../packages/warmhub-cli/src/durable-id-style.ts
51736
- var THING_TOKEN_LEN = 60;
51737
- var REPO_TOKEN_LEN = 34;
51738
- var HUE_REPO = "8A7C6A";
51739
- var HUE_TIMESTAMP = "7E9BAC";
51740
- var HUE_ENTROPY = "E8C378";
51741
- var HUE_CRC = "74846B";
51742
- var THING_BANDS = [
51743
- { start: 0, end: 28, weight: "faint", hex: HUE_REPO },
51744
- { start: 28, end: 37, weight: "normal", hex: HUE_TIMESTAMP },
51745
- { start: 37, end: 53, weight: "bold", hex: HUE_ENTROPY },
51746
- { start: 53, end: 60, weight: "faint", hex: HUE_CRC }
51747
- ];
51748
- var REPO_BANDS = [
51749
- { start: 0, end: 28, weight: "faint", hex: HUE_REPO },
51750
- { start: 28, end: 34, weight: "faint", hex: HUE_CRC }
51751
- ];
51752
- function fg(hex3) {
51753
- const r = Number.parseInt(hex3.slice(0, 2), 16);
51754
- const g = Number.parseInt(hex3.slice(2, 4), 16);
51755
- const b = Number.parseInt(hex3.slice(4, 6), 16);
51756
- return `\x1B[38;2;${r};${g};${b}m`;
51757
- }
51758
- function bandsFor(token) {
51759
- if (token.length === THING_TOKEN_LEN && decodeDurableId(token)) {
51760
- return THING_BANDS;
51761
- }
51762
- if (token.length === REPO_TOKEN_LEN && decodeRepoDurableId(token)) {
51763
- return REPO_BANDS;
51764
- }
51765
- return null;
51766
- }
51767
- function styleBand(text, band, c) {
51768
- const weight = band.weight === "bold" ? c.bold : band.weight === "faint" ? c.dim : "";
51769
- const hue = c.truecolor ? fg(band.hex) : "";
51770
- const prefix = `${weight}${hue}`;
51771
- return prefix === "" ? text : `${prefix}${text}${c.reset}`;
51772
- }
51773
- function styleDurableId(token, c) {
51774
- if (c.reset === "")
51775
- return token;
51776
- const bands = bandsFor(token);
51777
- if (!bands)
51778
- return token;
51779
- let out = "";
51780
- for (const band of bands) {
51781
- out += styleBand(token.slice(band.start, band.end), band, c);
51782
- }
51783
- return out;
51784
- }
51785
-
51786
52083
  // ../../packages/warmhub-cli/src/domains/thing/render.ts
51787
52084
  function renderHead(out, c, chars, result, org, repo, shape, kind) {
51788
52085
  const items = result.items ?? [];
52086
+ const decorations = getResponseDecorations(result);
51789
52087
  if (!items.length) {
51790
52088
  out(`${c.dim}No items in HEAD${c.reset}`);
51791
52089
  return;
@@ -51799,19 +52097,17 @@ function renderHead(out, c, chars, result, org, repo, shape, kind) {
51799
52097
  const retractedTag = item.active === false ? ` ${c.red}[RETRACTED]${c.reset}` : "";
51800
52098
  out(` ${wref} ${kl}${retractedTag}`);
51801
52099
  if (item.kind === "assertion" && item.aboutWref) {
51802
- out(` ${c.dim}about:${c.reset} ${pinnedWref(c, item.aboutWref)}`);
52100
+ out(` ${c.dim}about:${c.reset} ${refDisplay(c, item.aboutWref, decorations)}`);
51803
52101
  }
51804
52102
  if (item.affirmedWrefs?.length) {
51805
- out(` ${c.dim}affirms:${c.reset} ${formatAffirmedWrefs(c, item.affirmedWrefs)}`);
52103
+ out(` ${c.dim}affirms:${c.reset} ${refList(c, item.affirmedWrefs, decorations)}`);
51806
52104
  }
51807
52105
  const fields = shapeName && (item.kind === "thing" || item.kind === "collection") && item.data ? collectionFields(shapeName, item.data) : null;
51808
52106
  if (fields) {
51809
52107
  const allWrefs = fields.flatMap((f) => f.wrefs);
51810
- out(` ${allWrefs.map((w) => pinnedWref(c, w)).join(`${c.dim},${c.reset} `)}`);
52108
+ out(` ${refList(c, allWrefs, decorations)}`);
51811
52109
  } else if (item.data && typeof item.data === "object") {
51812
- const preview = JSON.stringify(item.data);
51813
- const truncated = preview.length > 80 ? `${preview.slice(0, 77)}...` : preview;
51814
- out(` ${c.dim}${escapeTerminalTextForDisplay(truncated)}${c.reset}`);
52110
+ out(` ${dataPreview(c, item.data)}`);
51815
52111
  }
51816
52112
  const itemMeta = item.metadata;
51817
52113
  if (itemMeta?.durableId) {
@@ -51821,6 +52117,7 @@ function renderHead(out, c, chars, result, org, repo, shape, kind) {
51821
52117
  out(`${c.dim}${items.length} item(s)${c.reset}`);
51822
52118
  }
51823
52119
  function renderThing(out, c, result) {
52120
+ const decorations = getResponseDecorations(result);
51824
52121
  const wref = result.wref ?? result.name ?? "(unknown)";
51825
52122
  const shapeName = result.shapeName ?? result.shape;
51826
52123
  const displayKind = effectiveKind(result.kind ?? "thing", shapeName);
@@ -51830,14 +52127,14 @@ function renderThing(out, c, result) {
51830
52127
  out(` ${c.dim}version:${c.reset} ${result.version ?? "-"}`);
51831
52128
  out(` ${c.dim}active:${c.reset} ${String(result.active)}`);
51832
52129
  if (result.committerWref) {
51833
- out(` ${c.dim}by:${c.reset} ${pinnedWref(c, result.committerWref)}`);
52130
+ out(` ${c.dim}by:${c.reset} ${refDisplay(c, result.committerWref, decorations)}`);
51834
52131
  }
51835
52132
  const aboutWref = result.aboutWref ?? result.about;
51836
52133
  if (aboutWref) {
51837
- out(` ${c.dim}about:${c.reset} ${escapeTerminalTextForDisplay(String(aboutWref))}`);
52134
+ out(` ${c.dim}about:${c.reset} ${decoratedRef(c, String(aboutWref), decorations) ?? escapeTerminalTextForDisplay(String(aboutWref))}`);
51838
52135
  }
51839
52136
  if (result.affirmedWrefs?.length) {
51840
- out(` ${c.dim}affirms:${c.reset} ${formatAffirmedWrefs(c, result.affirmedWrefs)}`);
52137
+ out(` ${c.dim}affirms:${c.reset} ${refList(c, result.affirmedWrefs, decorations)}`);
51841
52138
  }
51842
52139
  const meta3 = result.metadata;
51843
52140
  if (meta3?.durableId || meta3?.createdOn || meta3?.revisedOn) {
@@ -51853,31 +52150,27 @@ function renderThing(out, c, result) {
51853
52150
  }
51854
52151
  }
51855
52152
  if (result.collection) {
51856
- renderCollectionSummary(out, c, result.collection);
52153
+ renderCollectionSummary(out, c, result.collection, decorations);
51857
52154
  }
51858
52155
  const fields = shapeName && result.data ? collectionFields(shapeName, result.data) : null;
51859
52156
  if (fields) {
51860
52157
  for (const field of fields) {
51861
52158
  if (field.wrefs.length === 1) {
51862
52159
  const pad = " ".repeat(Math.max(1, 9 - field.name.length));
51863
- out(` ${c.dim}${escapeTerminalTextForDisplay(field.name)}:${c.reset}${pad}${pinnedWref(c, field.wrefs[0])}`);
52160
+ out(` ${c.dim}${escapeTerminalTextForDisplay(field.name)}:${c.reset}${pad}${refDisplay(c, field.wrefs[0] ?? "", decorations)}`);
51864
52161
  } else {
51865
52162
  out(` ${c.dim}${escapeTerminalTextForDisplay(field.name)}:${c.reset}`);
51866
52163
  for (const w of field.wrefs) {
51867
- out(` ${pinnedWref(c, w)}`);
52164
+ out(` ${refDisplay(c, w, decorations)}`);
51868
52165
  }
51869
52166
  }
51870
52167
  }
51871
52168
  } else if (result.data) {
51872
52169
  out(` ${c.dim}data:${c.reset}`);
51873
- const lines = JSON.stringify(result.data, null, 2).split(`
51874
- `);
51875
- for (const line of lines) {
51876
- out(` ${escapeTerminalTextForDisplay(line)}`);
51877
- }
52170
+ renderJsonDataBlock(out, c, result.data, " ", decorations);
51878
52171
  }
51879
52172
  }
51880
- function renderCollectionSummary(out, c, collection) {
52173
+ function renderCollectionSummary(out, c, collection, decorations) {
51881
52174
  out(` ${c.dim}collection:${c.reset} ${collection.type}`);
51882
52175
  out(` ${c.dim}members:${c.reset} ${collection.memberCount}`);
51883
52176
  if (collection.fullData)
@@ -51889,19 +52182,12 @@ function renderCollectionSummary(out, c, collection) {
51889
52182
  return;
51890
52183
  out(` ${c.dim}preview:${c.reset}`);
51891
52184
  for (const wref of preview) {
51892
- out(` ${pinnedWref(c, wref)}`);
52185
+ out(` ${refDisplay(c, wref, decorations)}`);
51893
52186
  }
51894
52187
  }
51895
- function renderDataBlock(out, data, indent) {
51896
- const lines = JSON.stringify(data, null, 2).split(`
51897
- `);
51898
- for (const line of lines) {
51899
- out(`${indent}${escapeTerminalTextForDisplay(line)}`);
51900
- }
51901
- }
51902
- function renderGraphValue(out, c, value, indent) {
52188
+ function renderGraphValue(out, c, value, indent, decorations) {
51903
52189
  if (typeof value === "string") {
51904
- out(`${indent}${pinnedWref(c, value)}`);
52190
+ out(`${indent}${refDisplay(c, value, decorations)}`);
51905
52191
  return;
51906
52192
  }
51907
52193
  if (value === null || typeof value === "number" || typeof value === "boolean") {
@@ -51910,26 +52196,26 @@ function renderGraphValue(out, c, value, indent) {
51910
52196
  }
51911
52197
  if (Array.isArray(value)) {
51912
52198
  for (const item of value) {
51913
- renderGraphValue(out, c, item, indent);
52199
+ renderGraphValue(out, c, item, indent, decorations);
51914
52200
  }
51915
52201
  return;
51916
52202
  }
51917
- renderGraphNode(out, c, value, indent);
52203
+ renderGraphNode(out, c, value, indent, decorations);
51918
52204
  }
51919
- function renderGraphNode(out, c, result, indent = "") {
52205
+ function renderGraphNode(out, c, result, indent = "", decorations = undefined) {
51920
52206
  const wref = result.wref ?? result.name ?? "(unknown)";
51921
52207
  const shapeName = result.shapeName ?? result.shape;
51922
52208
  const displayKind = effectiveKind(result.kind ?? "thing", shapeName);
51923
52209
  out(`${indent}${pinnedWref(c, wref, result.version)} ${kindLabel(c, displayKind)}`);
51924
52210
  if (result.about) {
51925
52211
  out(`${indent} ${c.dim}about:${c.reset}`);
51926
- renderGraphValue(out, c, result.about, `${indent} `);
52212
+ renderGraphValue(out, c, result.about, `${indent} `, decorations);
51927
52213
  } else if (result.aboutWref) {
51928
- out(`${indent} ${c.dim}about:${c.reset} ${pinnedWref(c, result.aboutWref)}`);
52214
+ out(`${indent} ${c.dim}about:${c.reset} ${refDisplay(c, result.aboutWref, decorations)}`);
51929
52215
  }
51930
52216
  if (result.data) {
51931
52217
  out(`${indent} ${c.dim}data:${c.reset}`);
51932
- renderDataBlock(out, result.data, `${indent} `);
52218
+ renderJsonDataBlock(out, c, result.data, `${indent} `, decorations);
51933
52219
  }
51934
52220
  const resolved = result.resolved ?? {};
51935
52221
  const resolvedEntries = Object.entries(resolved);
@@ -51937,25 +52223,26 @@ function renderGraphNode(out, c, result, indent = "") {
51937
52223
  out(`${indent} ${c.dim}resolved:${c.reset}`);
51938
52224
  for (const [fieldPath, value] of resolvedEntries) {
51939
52225
  out(`${indent} ${c.dim}${escapeTerminalTextForDisplay(fieldPath)}:${c.reset}`);
51940
- renderGraphValue(out, c, value, `${indent} `);
52226
+ renderGraphValue(out, c, value, `${indent} `, decorations);
51941
52227
  }
51942
52228
  }
51943
52229
  const assertions = result.assertions ?? [];
51944
52230
  if (assertions.length > 0) {
51945
52231
  out(`${indent} ${c.dim}assertions:${c.reset}`);
51946
52232
  for (const assertion of assertions) {
51947
- renderGraphNode(out, c, assertion, `${indent} `);
52233
+ renderGraphNode(out, c, assertion, `${indent} `, decorations);
51948
52234
  }
51949
52235
  }
51950
52236
  }
51951
52237
  function renderThingGraph(out, c, result) {
51952
- renderGraphNode(out, c, result);
52238
+ renderGraphNode(out, c, result, "", getResponseDecorations(result));
51953
52239
  if (result.graph) {
51954
52240
  const truncated = result.graph.truncated ? " truncated" : "";
51955
52241
  out(` ${c.dim}graph:${c.reset} depth=${result.graph.depth} limit=${result.graph.limit}${truncated}`);
51956
52242
  }
51957
52243
  }
51958
52244
  function renderHistory(out, c, result) {
52245
+ const decorations = getResponseDecorations(result);
51959
52246
  if (result.thing && typeof result.thing === "object") {
51960
52247
  const wref = result.thing.wref ?? result.thing.name ?? "(unknown)";
51961
52248
  out(`${c.bold}History: ${pinnedWref(c, wref)}${c.reset} ${kindLabel(c, effectiveKind(result.thing.kind ?? "thing", result.thing.shapeName))}`);
@@ -51981,13 +52268,13 @@ function renderHistory(out, c, result) {
51981
52268
  const time3 = ver.createdAt ? formatTime(ver.createdAt, now) : "";
51982
52269
  const wref = ver.wref ?? ver.thingName;
51983
52270
  const wrefStr = wref ? pinnedWref(c, wref, ver.version) : "";
51984
- const by = ver.committerWref ? ` ${c.dim}by${c.reset} ${pinnedWref(c, ver.committerWref)}` : "";
52271
+ const by = ver.committerWref ? ` ${c.dim}by${c.reset} ${refDisplay(c, ver.committerWref, decorations)}` : "";
51985
52272
  const createdOn = ver.metadata?.createdOn;
51986
52273
  const thingCreatedStr = createdOn ? ` ${c.dim}born:${formatTime(createdOn, now)}${c.reset}` : "";
51987
52274
  out(` ${wrefStr} ${op} ${c.dim}${time3}${c.reset}${by}${thingCreatedStr}`);
51988
52275
  const affirmed = ver.affirmedWrefs;
51989
52276
  if (Array.isArray(affirmed) && affirmed.length > 0) {
51990
- out(` ${c.dim}affirms:${c.reset} ${formatAffirmedWrefs(c, affirmed.map(String))}`);
52277
+ out(` ${c.dim}affirms:${c.reset} ${refList(c, affirmed.map(String), decorations)}`);
51991
52278
  }
51992
52279
  }
51993
52280
  }
@@ -51997,11 +52284,12 @@ function renderRefs(out, c, result, wref, direction) {
51997
52284
  out(`${c.dim}No ${direction} refs${c.reset}`);
51998
52285
  return;
51999
52286
  }
52287
+ const decorations = getResponseDecorations(result);
52000
52288
  const label = direction === "inbound" ? "References to" : "Referenced by";
52001
52289
  out(`${c.bold}${label}${c.reset} ${c.cyan}${escapeTerminalTextForDisplay(wref)}${c.reset}`);
52002
52290
  out(`${c.dim}${"─".repeat(60)}${c.reset}`);
52003
52291
  for (const item of items) {
52004
- const refWref = pinnedWref(c, item.wref, item.version);
52292
+ const refWref = refDisplay(c, item.wref, decorations, item.version);
52005
52293
  const kl = kindLabel(c, effectiveKind(item.kind ?? "thing", item.shapeName));
52006
52294
  const field = `${c.dim}via ${c.reset}${escapeTerminalTextForDisplay(item.fieldPath ?? "(unknown)")}`;
52007
52295
  out(` ${refWref} ${kl} ${field}`);
@@ -52042,7 +52330,8 @@ function renderBatchView(out, c, result, wrefs, flagsVersion) {
52042
52330
  const base = requestedBase.length > 0 ? requestedBase : fallback.replace(/@v\d+$/, "");
52043
52331
  const kl = kindLabel(c, effectiveKind(item.kind ?? "thing", item.shapeName));
52044
52332
  const retractedTag = item.active === false ? ` ${c.red}[RETRACTED]${c.reset}` : "";
52045
- out(` ${escapeTerminalTextForDisplay(base)}@v${item.version} ${kl}${retractedTag}`);
52333
+ const display = labeledRef(c, `${base}@v${item.version}`, fallback) ?? `${escapeTerminalTextForDisplay(base)}@v${item.version}`;
52334
+ out(` ${display} ${kl}${retractedTag}`);
52046
52335
  }
52047
52336
  if (result.missing.length > 0) {
52048
52337
  out("Missing:");
@@ -52134,6 +52423,7 @@ var handleHistory = async (ctx, { flags, args }) => {
52134
52423
  functionLogs: ctx.functionLogMode,
52135
52424
  profile: ctx.profile,
52136
52425
  clientFlags: ctx.clientFlags,
52426
+ decorateResponses: ctx.decorate,
52137
52427
  signal: ctx.signal
52138
52428
  });
52139
52429
  return;
@@ -52160,15 +52450,17 @@ var handleHistory = async (ctx, { flags, args }) => {
52160
52450
  }
52161
52451
  writePageOutput(ctx, result.versions ?? [], {
52162
52452
  limit: all ? pageLimit : boundedLimit,
52163
- nextCursor: result.nextCursor ?? null
52453
+ nextCursor: result.nextCursor ?? null,
52454
+ decorations: getResponseDecorations(result)
52164
52455
  }, () => renderHistory(ctx.out, ctx.colors, result));
52165
52456
  };
52166
52457
  async function fetchAllHistoryPages(ctx, org, repo, opts) {
52167
52458
  const versions2 = [];
52168
- let cursor = opts.cursor;
52459
+ let decorations;
52169
52460
  let thing;
52170
- while (true) {
52171
- const page = await ctx.client.thing.history(org, repo, {
52461
+ for await (const page of paginatePages2({
52462
+ initialCursor: opts.cursor,
52463
+ fetchPage: (cursor) => ctx.client.thing.history(org, repo, {
52172
52464
  wref: opts.wref,
52173
52465
  shape: opts.shape,
52174
52466
  about: opts.about,
@@ -52176,25 +52468,19 @@ async function fetchAllHistoryPages(ctx, org, repo, opts) {
52176
52468
  resolveCollections: opts.resolveCollections,
52177
52469
  limit: opts.limit,
52178
52470
  cursor
52179
- });
52471
+ }),
52472
+ title: "Thing history"
52473
+ })) {
52180
52474
  if (!thing && page.thing)
52181
52475
  thing = page.thing;
52182
52476
  versions2.push(...page.versions ?? []);
52183
- if (!page.nextCursor)
52184
- break;
52185
- cursor = page.nextCursor;
52186
- }
52187
- if (thing) {
52188
- return {
52189
- thing,
52190
- versions: versions2,
52191
- nextCursor: undefined
52192
- };
52477
+ decorations = mergeDecorations(decorations, getResponseDecorations(page));
52193
52478
  }
52194
- return {
52479
+ return withDecorations({
52480
+ ...thing === undefined ? {} : { thing },
52195
52481
  versions: versions2,
52196
52482
  nextCursor: undefined
52197
- };
52483
+ }, decorations);
52198
52484
  }
52199
52485
 
52200
52486
  // ../../packages/warmhub-cli/src/domains/thing/lease.ts
@@ -52442,6 +52728,7 @@ var handleHead = async (ctx, { flags, args }) => {
52442
52728
  functionLogs: ctx.functionLogMode,
52443
52729
  profile: ctx.profile,
52444
52730
  clientFlags: ctx.clientFlags,
52731
+ decorateResponses: ctx.decorate,
52445
52732
  signal: ctx.signal
52446
52733
  });
52447
52734
  return;
@@ -52459,8 +52746,8 @@ var handleHead = async (ctx, { flags, args }) => {
52459
52746
  excludeInfraShapes,
52460
52747
  where: where.length > 0 ? where : undefined,
52461
52748
  ...sinceRepoSeq === undefined ? {} : { sinceRepoSeq }
52462
- }, streamJsonl ? async (items) => {
52463
- writePageOutput(ctx, items, { limit: pageLimit }, () => {});
52749
+ }, streamJsonl ? async (items, pageDecorations) => {
52750
+ writePageOutput(ctx, items, { limit: pageLimit, decorations: pageDecorations }, () => {});
52464
52751
  return await ctx.flushOut?.() ?? true;
52465
52752
  } : undefined) : await ctx.client.thing.head(org, repo, {
52466
52753
  shape,
@@ -52484,7 +52771,8 @@ var handleHead = async (ctx, { flags, args }) => {
52484
52771
  writePageOutput(ctx, result.items ?? [], {
52485
52772
  limit: all ? pageLimit : boundedLimit,
52486
52773
  nextCursor: result.nextCursor ?? null,
52487
- ...result.repoSeq === undefined ? {} : { repoSeq: result.repoSeq }
52774
+ ...result.repoSeq === undefined ? {} : { repoSeq: result.repoSeq },
52775
+ decorations: getResponseDecorations(result)
52488
52776
  }, () => renderHead(ctx.out, ctx.colors, ctx.chars, result, org, repo, shape, kind));
52489
52777
  };
52490
52778
  async function fetchAllHeadPages(ctx, org, repo, opts, onPage) {
@@ -52638,6 +52926,7 @@ var handleQuery = async (ctx, { flags }) => {
52638
52926
  functionLogs: ctx.functionLogMode,
52639
52927
  profile: ctx.profile,
52640
52928
  clientFlags: ctx.clientFlags,
52929
+ decorateResponses: ctx.decorate,
52641
52930
  signal: ctx.signal
52642
52931
  });
52643
52932
  return;
@@ -52659,8 +52948,8 @@ var handleQuery = async (ctx, { flags }) => {
52659
52948
  excludeInfraShapes,
52660
52949
  where: where.length > 0 ? where : undefined,
52661
52950
  ...sinceRepoSeq === undefined ? {} : { sinceRepoSeq }
52662
- }, streamJsonl ? async (items) => {
52663
- writePageOutput(ctx, items, { limit: pageLimit }, () => {});
52951
+ }, streamJsonl ? async (items, pageDecorations) => {
52952
+ writePageOutput(ctx, items, { limit: pageLimit, decorations: pageDecorations }, () => {});
52664
52953
  return await ctx.flushOut?.() ?? true;
52665
52954
  } : undefined) : await ctx.client.thing.query(org, repo, {
52666
52955
  shape,
@@ -52688,7 +52977,8 @@ var handleQuery = async (ctx, { flags }) => {
52688
52977
  writePageOutput(ctx, result.items ?? [], {
52689
52978
  limit: all ? pageLimit : boundedLimit,
52690
52979
  nextCursor: result.nextCursor ?? null,
52691
- ...result.repoSeq === undefined ? {} : { repoSeq: result.repoSeq }
52980
+ ...result.repoSeq === undefined ? {} : { repoSeq: result.repoSeq },
52981
+ decorations: getResponseDecorations(result)
52692
52982
  }, () => renderQueryResults(ctx.out, c, result));
52693
52983
  };
52694
52984
  async function fetchAllQueryPages(ctx, org, repo, opts, onPage) {
@@ -52718,6 +53008,7 @@ async function fetchAllQueryPages(ctx, org, repo, opts, onPage) {
52718
53008
  }
52719
53009
  function renderQueryResults(out, c, result) {
52720
53010
  const items = result.items ?? [];
53011
+ const decorations = getResponseDecorations(result);
52721
53012
  if (!items.length) {
52722
53013
  out(`${c.dim}No results${c.reset}`);
52723
53014
  return;
@@ -52734,11 +53025,9 @@ function renderQueryResults(out, c, result) {
52734
53025
  const fields = shapeName && (item.kind === "thing" || item.kind === "collection" || !item.kind) && item.data ? collectionFields(shapeName, item.data) : null;
52735
53026
  if (fields) {
52736
53027
  const allWrefs = fields.flatMap((f) => f.wrefs);
52737
- out(` ${allWrefs.map((w) => pinnedWref(c, escapeTerminalTextForDisplay(w))).join(`${c.dim},${c.reset} `)}`);
53028
+ out(` ${refList(c, allWrefs, decorations)}`);
52738
53029
  } else if (item.data && typeof item.data === "object") {
52739
- const preview = JSON.stringify(item.data);
52740
- const truncated = preview.length > 80 ? `${preview.slice(0, 77)}...` : preview;
52741
- out(` ${c.dim}${truncated}${c.reset}`);
53030
+ out(` ${dataPreview(c, item.data)}`);
52742
53031
  }
52743
53032
  }
52744
53033
  out(`${c.dim}${items.length} result(s)${c.reset}`);
@@ -52789,16 +53078,17 @@ var handleRefs = async (ctx, { flags, args }) => {
52789
53078
  });
52790
53079
  if (all) {
52791
53080
  const items = [];
52792
- let cur = cursor;
52793
- while (true) {
52794
- const page = await fetchPage(cur);
53081
+ let decorations;
53082
+ for await (const page of paginatePages2({
53083
+ initialCursor: cursor,
53084
+ fetchPage,
53085
+ title: "Thing refs"
53086
+ })) {
52795
53087
  items.push(...page.items ?? []);
52796
- if (!page.nextCursor)
52797
- break;
52798
- cur = page.nextCursor;
53088
+ decorations = mergeDecorations(decorations, getResponseDecorations(page));
52799
53089
  }
52800
- const result2 = { items, nextCursor: undefined };
52801
- writePageOutput(ctx, items, { limit: pageLimit, nextCursor: null }, () => renderRefs(ctx.out, ctx.colors, result2, wref, direction));
53090
+ const result2 = withDecorations({ items, nextCursor: undefined }, decorations);
53091
+ writePageOutput(ctx, items, { limit: pageLimit, nextCursor: null, decorations }, () => renderRefs(ctx.out, ctx.colors, result2, wref, direction));
52802
53092
  maybeEmitAboutHint(ctx, direction, items.length, refsQueryIsNarrowed);
52803
53093
  return;
52804
53094
  }
@@ -52806,7 +53096,11 @@ var handleRefs = async (ctx, { flags, args }) => {
52806
53096
  if (result.nextCursor) {
52807
53097
  emitPartialPageHint(ctx, (result.items ?? []).length, result.nextCursor, boundedLimit);
52808
53098
  }
52809
- writePageOutput(ctx, result.items ?? [], { limit: boundedLimit, nextCursor: result.nextCursor ?? null }, () => renderRefs(ctx.out, ctx.colors, result, wref, direction));
53099
+ writePageOutput(ctx, result.items ?? [], {
53100
+ limit: boundedLimit,
53101
+ nextCursor: result.nextCursor ?? null,
53102
+ decorations: getResponseDecorations(result)
53103
+ }, () => renderRefs(ctx.out, ctx.colors, result, wref, direction));
52810
53104
  maybeEmitAboutHint(ctx, direction, result.items?.length ?? 0, refsQueryIsNarrowed);
52811
53105
  };
52812
53106
  function maybeEmitAboutHint(ctx, direction, itemCount, refsQueryIsNarrowed) {
@@ -53072,23 +53366,25 @@ var handleSearch = async (ctx, { flags, args }) => {
53072
53366
  excludeComponents,
53073
53367
  excludeInfraShapes
53074
53368
  });
53075
- const result = {
53369
+ const result = withDecorations({
53076
53370
  items: rawResult.items ?? [],
53077
53371
  nextCursor: "nextCursor" in rawResult ? rawResult.nextCursor : undefined
53078
- };
53372
+ }, getResponseDecorations(rawResult));
53079
53373
  if (!all && result.nextCursor) {
53080
53374
  emitPartialPageHint(ctx, result.items.length, result.nextCursor, boundedTextLimit);
53081
53375
  }
53082
53376
  writePageOutput(ctx, result.items, {
53083
53377
  limit: all ? pageLimit : boundedTextLimit,
53084
- nextCursor: result.nextCursor ?? null
53378
+ nextCursor: result.nextCursor ?? null,
53379
+ decorations: getResponseDecorations(result)
53085
53380
  }, () => renderQueryResults(ctx.out, c, result));
53086
53381
  };
53087
53382
  async function fetchAllSearchPages(ctx, org, repo, queryText, opts) {
53088
53383
  const items = [];
53089
- let cursor = opts.cursor;
53090
- while (true) {
53091
- const page = await ctx.client.thing.search(org, repo, queryText, {
53384
+ let decorations;
53385
+ for await (const page of paginatePages2({
53386
+ initialCursor: opts.cursor,
53387
+ fetchPage: (cursor) => ctx.client.thing.search(org, repo, queryText, {
53092
53388
  shape: opts.shape,
53093
53389
  kind: opts.kind,
53094
53390
  about: opts.about,
@@ -53101,13 +53397,13 @@ async function fetchAllSearchPages(ctx, org, repo, queryText, opts) {
53101
53397
  componentRef: opts.componentRef,
53102
53398
  excludeComponents: opts.excludeComponents,
53103
53399
  excludeInfraShapes: opts.excludeInfraShapes
53104
- });
53400
+ }),
53401
+ title: "Thing search"
53402
+ })) {
53105
53403
  items.push(...page.items ?? []);
53106
- if (!page.nextCursor)
53107
- break;
53108
- cursor = page.nextCursor;
53404
+ decorations = mergeDecorations(decorations, getResponseDecorations(page));
53109
53405
  }
53110
- return { items, nextCursor: undefined };
53406
+ return withDecorations({ items, nextCursor: undefined }, decorations);
53111
53407
  }
53112
53408
 
53113
53409
  // ../../packages/warmhub-cli/src/domains/thing/view.ts
@@ -53348,6 +53644,7 @@ async function runSingleView(ctx, wref, flags) {
53348
53644
  functionLogs: ctx.functionLogMode,
53349
53645
  profile: ctx.profile,
53350
53646
  clientFlags: ctx.clientFlags,
53647
+ decorateResponses: ctx.decorate,
53351
53648
  signal: ctx.signal
53352
53649
  });
53353
53650
  return;
@@ -53373,6 +53670,7 @@ async function runBatchView(ctx, wrefs, flags) {
53373
53670
  const dataMode = validateDataMode(flags["data-mode"]);
53374
53671
  const result = await ctx.client.thing.getMany(org, repo, wrefs, flags.version, { includeRetracted, dataMode });
53375
53672
  if (ctx.format === "jsonl") {
53673
+ const responseDecorations = getResponseDecorations(result);
53376
53674
  for (const event of walkBatchResult(wrefs, result, flags.version)) {
53377
53675
  if (event.kind === "miss") {
53378
53676
  ctx.out(JSON.stringify({
@@ -53384,11 +53682,13 @@ async function runBatchView(ctx, wrefs, flags) {
53384
53682
  ctx.out(JSON.stringify({ requested: event.requested, found: false }));
53385
53683
  } else {
53386
53684
  const { wref: itemWref, ...rest } = event.item;
53685
+ const decorations = rowDecorationsSubset(event.item, responseDecorations);
53387
53686
  ctx.out(JSON.stringify({
53388
53687
  requested: event.requested,
53389
53688
  found: true,
53390
53689
  wref: itemWref,
53391
- ...rest
53690
+ ...rest,
53691
+ ...decorations === undefined ? {} : { decorations }
53392
53692
  }));
53393
53693
  }
53394
53694
  }
@@ -53633,6 +53933,7 @@ var handleView2 = async (ctx, { flags, args }) => {
53633
53933
  functionLogs: ctx.functionLogMode,
53634
53934
  profile: ctx.profile,
53635
53935
  clientFlags: ctx.clientFlags,
53936
+ decorateResponses: ctx.decorate,
53636
53937
  signal: ctx.signal
53637
53938
  });
53638
53939
  return;
@@ -53690,35 +53991,48 @@ var handleHistory2 = async (ctx, { flags, args }) => {
53690
53991
  functionLogs: ctx.functionLogMode,
53691
53992
  profile: ctx.profile,
53692
53993
  clientFlags: ctx.clientFlags,
53994
+ decorateResponses: ctx.decorate,
53693
53995
  signal: ctx.signal
53694
53996
  });
53695
53997
  return;
53696
53998
  }
53697
53999
  const versions2 = [];
53698
- let cursor = flags.cursor;
53699
54000
  let thing;
53700
54001
  let nextCursor;
53701
- do {
53702
- const page = await ctx.client.thing.history(org, repo, {
53703
- wref,
53704
- includeRetracted: flags["include-retracted"],
53705
- limit,
53706
- cursor
53707
- });
53708
- thing = thing ?? page.thing;
54002
+ let decorations;
54003
+ const fetchPage = (cursor) => ctx.client.thing.history(org, repo, {
54004
+ wref,
54005
+ includeRetracted: flags["include-retracted"],
54006
+ limit,
54007
+ cursor
54008
+ });
54009
+ if (flags.all) {
54010
+ for await (const page of paginatePages2({
54011
+ initialCursor: flags.cursor,
54012
+ fetchPage,
54013
+ title: "Assertion history"
54014
+ })) {
54015
+ thing = thing ?? page.thing;
54016
+ versions2.push(...page.versions ?? []);
54017
+ decorations = mergeDecorations(decorations, getResponseDecorations(page));
54018
+ nextCursor = page.nextCursor;
54019
+ }
54020
+ } else {
54021
+ const page = await fetchPage(flags.cursor);
54022
+ thing = page.thing;
53709
54023
  versions2.push(...page.versions ?? []);
54024
+ decorations = getResponseDecorations(page);
53710
54025
  nextCursor = page.nextCursor;
53711
- cursor = flags.all ? nextCursor : undefined;
53712
- } while (cursor);
53713
- const result = {
54026
+ }
54027
+ const result = withDecorations({
53714
54028
  thing,
53715
54029
  versions: versions2,
53716
54030
  nextCursor: flags.all ? undefined : nextCursor
53717
- };
54031
+ }, decorations);
53718
54032
  if (!flags.all && result.nextCursor) {
53719
54033
  emitPartialPageHint(ctx, result.versions.length, result.nextCursor, limit);
53720
54034
  }
53721
- writePageOutput(ctx, result.versions, { limit, nextCursor: result.nextCursor ?? null }, () => renderHistory(ctx.out, ctx.colors, result));
54035
+ writePageOutput(ctx, result.versions, { limit, nextCursor: result.nextCursor ?? null, decorations }, () => renderHistory(ctx.out, ctx.colors, result));
53722
54036
  };
53723
54037
  var listFlags = {
53724
54038
  about: flag.string({
@@ -53815,6 +54129,7 @@ var handleList = async (ctx, { flags, args }) => {
53815
54129
  functionLogs: ctx.functionLogMode,
53816
54130
  profile: ctx.profile,
53817
54131
  clientFlags: ctx.clientFlags,
54132
+ decorateResponses: ctx.decorate,
53818
54133
  signal: ctx.signal
53819
54134
  });
53820
54135
  return;
@@ -53828,7 +54143,8 @@ var handleList = async (ctx, { flags, args }) => {
53828
54143
  }
53829
54144
  writePageOutput(ctx, result2.items ?? [], {
53830
54145
  limit: all ? pageLimit : boundedLimit,
53831
- nextCursor: result2.nextCursor ?? null
54146
+ nextCursor: result2.nextCursor ?? null,
54147
+ decorations: getResponseDecorations(result2)
53832
54148
  }, () => renderHead(ctx.out, ctx.colors, ctx.chars, result2, org, repo, shape, "assertion"));
53833
54149
  return;
53834
54150
  }
@@ -53859,6 +54175,7 @@ var handleList = async (ctx, { flags, args }) => {
53859
54175
  functionLogs: ctx.functionLogMode,
53860
54176
  profile: ctx.profile,
53861
54177
  clientFlags: ctx.clientFlags,
54178
+ decorateResponses: ctx.decorate,
53862
54179
  signal: ctx.signal
53863
54180
  });
53864
54181
  return;
@@ -53887,7 +54204,8 @@ var handleList = async (ctx, { flags, args }) => {
53887
54204
  }
53888
54205
  writePageOutput(ctx, result.assertions ?? [], {
53889
54206
  limit: all ? pageLimit : boundedLimit,
53890
- nextCursor: result.nextCursor ?? null
54207
+ nextCursor: result.nextCursor ?? null,
54208
+ decorations: getResponseDecorations(result)
53891
54209
  }, () => renderAbout(ctx.out, ctx.colors, result));
53892
54210
  };
53893
54211
 
@@ -54043,13 +54361,15 @@ Run \`wh auth login --profile ${explicitProfile}\` to create it.`);
54043
54361
  process.stderr.write(`warning: ignoring malformed client flag "${token}"
54044
54362
  `);
54045
54363
  }
54364
+ const decorate = explicitDecorateFlag(invocation.flags) ?? profileData?.settings?.decorate ?? true;
54046
54365
  const client = args.client ?? createClient(config2, {
54047
54366
  functionLogs: args.functionLogs,
54048
54367
  profile: effectiveProfile,
54049
54368
  signal: args.signal,
54050
- clientFlags
54369
+ clientFlags,
54370
+ decorateResponses: decorate
54051
54371
  });
54052
- return { config: config2, profile: effectiveProfile, client, clientFlags };
54372
+ return { config: config2, profile: effectiveProfile, client, clientFlags, decorate };
54053
54373
  }
54054
54374
 
54055
54375
  // ../../packages/warmhub-cli/src/domains/auth-shared.ts
@@ -54063,10 +54383,11 @@ function clientForStoredFlags(ctx, profile) {
54063
54383
  functionLogs: ctx.functionLogMode,
54064
54384
  profile,
54065
54385
  signal: ctx.signal,
54066
- clientFlags: flags
54386
+ clientFlags: flags,
54387
+ decorateResponses: ctx.decorate
54067
54388
  });
54068
54389
  }
54069
- async function loginWithToken(ctx, profile, explicitFlags) {
54390
+ async function loginWithToken(ctx, profile, explicitFlags, explicitDecorate) {
54070
54391
  const c = ctx.colors;
54071
54392
  if (process.stdin.isTTY) {
54072
54393
  throw new CliError(2 /* UserInput */, "USER_INPUT", "No token provided on stdin.", undefined, 'Pipe a JWT token via stdin: echo "$TOKEN" | wh auth login --with-token');
@@ -54103,7 +54424,7 @@ async function loginWithToken(ctx, profile, explicitFlags) {
54103
54424
  source: "token"
54104
54425
  },
54105
54426
  apiUrl: ctx.config.apiUrl
54106
- }, explicitFlags);
54427
+ }, explicitFlags, explicitDecorate);
54107
54428
  try {
54108
54429
  await clientForStoredFlags(ctx, profile).auth.sync();
54109
54430
  } catch (err) {
@@ -54192,7 +54513,7 @@ async function pollForDeviceToken(params) {
54192
54513
  poll().catch(reject);
54193
54514
  });
54194
54515
  }
54195
- function renderTokenInfo(ctx, info, profileName, apiUrl, identityWref, flags) {
54516
+ function renderTokenInfo(ctx, info, profileName, apiUrl, identityWref, flags, decorate) {
54196
54517
  const c = ctx.colors;
54197
54518
  const prefix = profileName ? `${c.bold}${profileName}${c.reset}: ` : "";
54198
54519
  const sourceLabel = {
@@ -54230,6 +54551,9 @@ function renderTokenInfo(ctx, info, profileName, apiUrl, identityWref, flags) {
54230
54551
  if (flags?.length) {
54231
54552
  ctx.status(` ${c.dim}Client flags:${c.reset} ${flags.join(", ")}`);
54232
54553
  }
54554
+ if (decorate !== undefined && decorate !== null) {
54555
+ ctx.status(` ${c.dim}Decorate:${c.reset} ${decorate ? "on" : "off"}`);
54556
+ }
54233
54557
  }
54234
54558
  async function fetchIdentityWref(ctx) {
54235
54559
  if (process.env.WH_TOKEN)
@@ -54268,6 +54592,7 @@ function authStatusEntry(info, options) {
54268
54592
  email: info.email ?? null,
54269
54593
  expiresAt: info.expiresAt ?? null,
54270
54594
  flags: options.flags ?? [],
54595
+ decorate: options.decorate ?? null,
54271
54596
  identityWref: options.identityWref ?? null,
54272
54597
  profile: options.profile ?? null,
54273
54598
  source: info.source
@@ -54295,8 +54620,9 @@ var handleLogin = async (ctx, { flags }) => {
54295
54620
  }
54296
54621
  }
54297
54622
  const explicitFlags = requestedFlags.length > 0 ? [...new Set(requestedFlags)].sort() : undefined;
54623
+ const explicitDecorate = explicitDecorateFlag(flags);
54298
54624
  if (flags["with-token"]) {
54299
- return loginWithToken(ctx, profile, explicitFlags);
54625
+ return loginWithToken(ctx, profile, explicitFlags, explicitDecorate);
54300
54626
  }
54301
54627
  const c = ctx.colors;
54302
54628
  let clientId;
@@ -54305,7 +54631,8 @@ var handleLogin = async (ctx, { flags }) => {
54305
54631
  } catch {
54306
54632
  clientId = await createUnauthenticatedClient(ctx.config, {
54307
54633
  functionLogs: ctx.functionLogMode,
54308
- clientFlags: ctx.clientFlags
54634
+ clientFlags: ctx.clientFlags,
54635
+ decorateResponses: ctx.decorate
54309
54636
  }).auth.getClientId();
54310
54637
  }
54311
54638
  if (!clientId) {
@@ -54380,7 +54707,7 @@ var handleLogin = async (ctx, { flags }) => {
54380
54707
  source: "device"
54381
54708
  },
54382
54709
  apiUrl: ctx.config.apiUrl
54383
- }, explicitFlags);
54710
+ }, explicitFlags, explicitDecorate);
54384
54711
  try {
54385
54712
  await clientForStoredFlags(ctx, profile).auth.sync();
54386
54713
  } catch (err) {
@@ -54423,10 +54750,11 @@ var handleStatus = async (ctx, { flags }) => {
54423
54750
  active: true,
54424
54751
  apiUrl: prof.apiUrl,
54425
54752
  flags: Array.isArray(prof.flags) ? prof.flags : [],
54753
+ decorate: prof.settings?.decorate,
54426
54754
  identityWref,
54427
54755
  profile: selectedProfile
54428
54756
  });
54429
- writeOutput(ctx, authStatusOutput(selectedProfile, [entry]), () => renderTokenInfo(ctx, info, selectedProfile, prof.apiUrl, identityWref, entry.flags));
54757
+ writeOutput(ctx, authStatusOutput(selectedProfile, [entry]), () => renderTokenInfo(ctx, info, selectedProfile, prof.apiUrl, identityWref, entry.flags, entry.decorate));
54430
54758
  return;
54431
54759
  }
54432
54760
  const envToken = process.env.WH_TOKEN;
@@ -54460,10 +54788,11 @@ var handleStatus = async (ctx, { flags }) => {
54460
54788
  active: !envToken && name === activeProfile,
54461
54789
  apiUrl: prof.apiUrl,
54462
54790
  flags: profileFlags,
54791
+ decorate: prof.settings?.decorate,
54463
54792
  identityWref,
54464
54793
  profile: name
54465
54794
  }));
54466
- prettyEntries.push(() => renderTokenInfo(ctx, info, name, prof.apiUrl, identityWref, profileFlags));
54795
+ prettyEntries.push(() => renderTokenInfo(ctx, info, name, prof.apiUrl, identityWref, profileFlags, prof.settings?.decorate));
54467
54796
  }
54468
54797
  }
54469
54798
  writeOutput(ctx, authStatusOutput(envToken ? null : activeProfile, entries), () => {
@@ -54985,30 +55314,33 @@ function renderMembers(ctx, result) {
54985
55314
  ctx.out(`${c.dim}No members${c.reset}`);
54986
55315
  return;
54987
55316
  }
55317
+ const decorations = getResponseDecorations(result);
54988
55318
  for (const item of result.items) {
54989
55319
  const position = item.position ?? 0;
54990
- ctx.out(`${String(position).padStart(4, " ")} ${pinnedWref(c, item.wref)}`);
55320
+ ctx.out(`${String(position).padStart(4, " ")} ${refDisplay(c, item.wref, decorations)}`);
54991
55321
  }
54992
55322
  }
54993
55323
  function renderContains(ctx, result) {
54994
55324
  const c = ctx.colors;
55325
+ const decorations = getResponseDecorations(result);
54995
55326
  for (const item of result.results) {
54996
55327
  const marker = item.contains ? ctx.chars.check : ctx.chars.cross;
54997
55328
  const color = item.contains ? c.green : c.red;
54998
55329
  const at = item.positions === undefined || item.positions.length === 0 ? "" : ` ${c.dim}@${item.positions.join(",")}${c.reset}`;
54999
- ctx.out(`${color}${marker}${c.reset} ${pinnedWref(c, item.member)}${at}`);
55330
+ ctx.out(`${color}${marker}${c.reset} ${refDisplay(c, item.member, decorations)}${at}`);
55000
55331
  }
55001
55332
  }
55002
55333
  function renderDiff(ctx, result) {
55003
55334
  const c = ctx.colors;
55335
+ const decorations = getResponseDecorations(result);
55004
55336
  if (result.mode === "ordered") {
55005
55337
  if (result.changed.length === 0) {
55006
55338
  ctx.out(`${c.dim}No ordered differences${c.reset}`);
55007
55339
  return;
55008
55340
  }
55009
55341
  for (const item of result.changed) {
55010
- const left = item.left?.wref ?? `${c.dim}(none)${c.reset}`;
55011
- const right = item.right?.wref ?? `${c.dim}(none)${c.reset}`;
55342
+ const left = item.left?.wref ? refDisplay(c, item.left.wref, decorations) : `${c.dim}(none)${c.reset}`;
55343
+ const right = item.right?.wref ? refDisplay(c, item.right.wref, decorations) : `${c.dim}(none)${c.reset}`;
55012
55344
  ctx.out(`${String(item.position).padStart(4, " ")} ${left} -> ${right}`);
55013
55345
  }
55014
55346
  return;
@@ -55018,10 +55350,10 @@ function renderDiff(ctx, result) {
55018
55350
  return;
55019
55351
  }
55020
55352
  for (const member of result.added) {
55021
- ctx.out(`${c.green}+${c.reset} ${member.wref}`);
55353
+ ctx.out(`${c.green}+${c.reset} ${refDisplay(c, member.wref, decorations)}`);
55022
55354
  }
55023
55355
  for (const member of result.removed) {
55024
- ctx.out(`${c.red}-${c.reset} ${member.wref}`);
55356
+ ctx.out(`${c.red}-${c.reset} ${refDisplay(c, member.wref, decorations)}`);
55025
55357
  }
55026
55358
  }
55027
55359
  function renderStats(ctx, result) {
@@ -55412,33 +55744,34 @@ var handleCollectionMembers = async (ctx, { flags, args }) => {
55412
55744
  const pageLimit = flags.all ? Math.min(flags.limit ?? AUTO_PAGE_LIMIT, MAX_PAGE_LIMIT) : boundedLimit;
55413
55745
  if (flags.all) {
55414
55746
  const items = [];
55415
- let cursor = flags.cursor;
55747
+ let decorations;
55416
55748
  let snapshotVersion = flags.version;
55417
55749
  let firstPage;
55418
- while (true) {
55419
- const page = await ctx.client.collection.members(org, repo, wref, {
55750
+ for await (const page of paginatePages2({
55751
+ initialCursor: flags.cursor,
55752
+ fetchPage: (cursor) => ctx.client.collection.members(org, repo, wref, {
55420
55753
  version: snapshotVersion,
55421
55754
  limit: pageLimit,
55422
55755
  cursor
55423
- });
55756
+ }),
55757
+ title: "Collection members"
55758
+ })) {
55424
55759
  firstPage ??= {
55425
55760
  type: page.type,
55426
55761
  wref: page.wref,
55427
55762
  version: page.version
55428
55763
  };
55429
55764
  items.push(...page.items);
55765
+ decorations = mergeDecorations(decorations, getResponseDecorations(page));
55430
55766
  snapshotVersion ??= page.version;
55431
- if (!page.nextCursor)
55432
- break;
55433
- cursor = page.nextCursor;
55434
55767
  }
55435
- writeCollectionMembersOutput(ctx, {
55768
+ writeCollectionMembersOutput(ctx, withDecorations({
55436
55769
  type: firstPage?.type ?? "set",
55437
55770
  wref: firstPage?.wref ?? wref,
55438
55771
  version: snapshotVersion ?? firstPage?.version ?? flags.version ?? 1,
55439
55772
  items,
55440
55773
  nextCursor: undefined
55441
- }, { limit: pageLimit, nextCursor: null });
55774
+ }, decorations), { limit: pageLimit, nextCursor: null, decorations });
55442
55775
  return;
55443
55776
  }
55444
55777
  const result = await ctx.client.collection.members(org, repo, wref, {
@@ -55451,7 +55784,8 @@ var handleCollectionMembers = async (ctx, { flags, args }) => {
55451
55784
  }
55452
55785
  writeCollectionMembersOutput(ctx, result, {
55453
55786
  limit: boundedLimit,
55454
- nextCursor: result.nextCursor ?? null
55787
+ nextCursor: result.nextCursor ?? null,
55788
+ decorations: getResponseDecorations(result)
55455
55789
  });
55456
55790
  };
55457
55791
  function writeCollectionMembersOutput(ctx, result, page) {
@@ -55462,12 +55796,13 @@ function writeCollectionMembersOutput(ctx, result, page) {
55462
55796
  wref: result.wref,
55463
55797
  version: result.version,
55464
55798
  items: result.items,
55799
+ ...page.decorations === undefined ? {} : { decorations: page.decorations },
55465
55800
  page: envelope.page
55466
55801
  });
55467
55802
  return;
55468
55803
  }
55469
55804
  if (ctx.format === "jsonl") {
55470
- printJsonl(ctx.out, result.items);
55805
+ printJsonl(ctx.out, decorateJsonlRows(result.items, page.decorations));
55471
55806
  return;
55472
55807
  }
55473
55808
  renderMembers(ctx, result);
@@ -55856,6 +56191,24 @@ function identifyCommitSubmitStreamRow(row) {
55856
56191
  // ../../packages/warmhub-cli/src/domains/commit-submit-template.ts
55857
56192
  import { writeFile } from "node:fs/promises";
55858
56193
  var WRITE_TEMPLATE_KINDS = ["thing", "assertion"];
56194
+ var COLLECTION_TEMPLATE_SPECS = {
56195
+ Arc: {
56196
+ type: "arc",
56197
+ members: ["Shape/FILL_IN_FROM", "Shape/FILL_IN_TO"]
56198
+ },
56199
+ Bond: {
56200
+ type: "bond",
56201
+ members: ["Shape/FILL_IN_1", "Shape/FILL_IN_2"]
56202
+ },
56203
+ Set: { type: "set", members: ["Shape/FILL_IN"] },
56204
+ List: { type: "list", members: ["Shape/FILL_IN"] }
56205
+ };
56206
+ function collectionTemplateSpec(shapeName) {
56207
+ if (!isBuiltinCollectionShape(shapeName) || shapeName === "Pair") {
56208
+ return;
56209
+ }
56210
+ return COLLECTION_TEMPLATE_SPECS[shapeName];
56211
+ }
55859
56212
  function zeroValueForField(fieldSpec) {
55860
56213
  if (Array.isArray(fieldSpec))
55861
56214
  return [];
@@ -55953,12 +56306,27 @@ var handleTemplate = async (ctx, { flags, args }) => {
55953
56306
  const count = Math.max(1, flags.count ?? 1);
55954
56307
  const operations = [];
55955
56308
  for (const shapeName of shapeNames) {
56309
+ const collectionTemplate = templateKind === "thing" ? collectionTemplateSpec(shapeName) : undefined;
56310
+ const operationKind = collectionTemplate ? "collection" : templateKind;
55956
56311
  if (operationType === "retract") {
55957
56312
  for (let i = 0;i < count; i++) {
55958
56313
  operations.push({
55959
56314
  operation: "retract",
55960
- kind: templateKind,
55961
- name: templateKind === "shape" ? shapeName : `${shapeName}/FILL_IN`
56315
+ kind: operationKind,
56316
+ name: operationKind === "shape" ? shapeName : `${shapeName}/FILL_IN`
56317
+ });
56318
+ }
56319
+ continue;
56320
+ }
56321
+ const nameSuffix = count > 1 ? (i) => `my-${shapeName.toLowerCase()}-${i + 1}` : () => `my-${shapeName.toLowerCase()}`;
56322
+ if (collectionTemplate) {
56323
+ for (let i = 0;i < count; i++) {
56324
+ operations.push({
56325
+ operation: operationType,
56326
+ kind: "collection",
56327
+ type: collectionTemplate.type,
56328
+ name: operationType === "add" ? nameSuffix(i) : `${shapeName}/FILL_IN`,
56329
+ members: [...collectionTemplate.members]
55962
56330
  });
55963
56331
  }
55964
56332
  continue;
@@ -55972,7 +56340,6 @@ var handleTemplate = async (ctx, { flags, args }) => {
55972
56340
  aboutPlaceholder = flags.about ? parseCollectionAboutFlag(flags.about) : "Shape/FILL_IN";
55973
56341
  }
55974
56342
  const data = buildTemplateData(fields);
55975
- const nameSuffix = count > 1 ? (i) => `my-${shapeName.toLowerCase()}-${i + 1}` : () => `my-${shapeName.toLowerCase()}`;
55976
56343
  const affirmedTargetsPlaceholder = templateKind === "assertion" ? { affirmedTargets: [] } : {};
55977
56344
  for (let i = 0;i < count; i++) {
55978
56345
  const op = operationType === "add" ? {
@@ -58891,20 +59258,24 @@ var handleTeardown = async (ctx, { args, flags }) => {
58891
59258
  var DEFAULT_LIMIT = 25;
58892
59259
  async function runGlobalSearchCommand(ctx, args) {
58893
59260
  const c = ctx.colors;
58894
- const first = await args.fetch({ limit: args.limit, cursor: args.cursor });
58895
- const items = [...first.items];
58896
- let nextCursor = first.nextCursor;
59261
+ const items = [];
59262
+ let nextCursor;
58897
59263
  if (args.all) {
58898
- const seenCursors = new Set(args.cursor ? [args.cursor] : []);
58899
- while (nextCursor) {
58900
- if (seenCursors.has(nextCursor)) {
58901
- throw new CliError(4 /* Backend */, "BACKEND", `${args.title} pagination cursor repeated; aborting --all to avoid an infinite loop.`, undefined, "Retry without --all to fetch one page and inspect page.nextCursor. If cursors repeat, report this as a backend pagination issue.");
58902
- }
58903
- seenCursors.add(nextCursor);
58904
- const page = await args.fetch({ limit: args.limit, cursor: nextCursor });
59264
+ for await (const page of paginatePages2({
59265
+ initialCursor: args.cursor,
59266
+ fetchPage: (cursor) => args.fetch({ limit: args.limit, cursor }),
59267
+ title: args.title
59268
+ })) {
58905
59269
  items.push(...page.items);
58906
59270
  nextCursor = page.nextCursor;
58907
59271
  }
59272
+ } else {
59273
+ const page = await args.fetch({
59274
+ limit: args.limit,
59275
+ cursor: args.cursor
59276
+ });
59277
+ items.push(...page.items);
59278
+ nextCursor = page.nextCursor;
58908
59279
  }
58909
59280
  if (!args.all && nextCursor) {
58910
59281
  emitPartialPageHint(ctx, items.length, nextCursor, args.limit ?? DEFAULT_LIMIT);
@@ -58928,26 +59299,22 @@ async function runGlobalSearchCommand(ctx, args) {
58928
59299
 
58929
59300
  // ../../packages/warmhub-cli/src/domains/component-list-handlers.ts
58930
59301
  async function fetchComponentPages(client, org, repo, opts) {
58931
- const firstPage = await client.component.list(org, repo, {
58932
- limit: opts.limit,
58933
- cursor: opts.cursor
58934
- });
58935
- const items = [...firstPage.items ?? []];
58936
- let nextCursor = firstPage.nextCursor;
59302
+ const items = [];
59303
+ let nextCursor;
59304
+ const fetchPage = (cursor) => client.component.list(org, repo, { limit: opts.limit, cursor });
58937
59305
  if (opts.all) {
58938
- const seenCursors = new Set(opts.cursor ? [opts.cursor] : []);
58939
- while (nextCursor) {
58940
- if (seenCursors.has(nextCursor)) {
58941
- throw new CliError(4 /* Backend */, "BACKEND", "Component list pagination cursor repeated; aborting --all to avoid an infinite loop.", undefined, "Retry without --all to fetch one page and inspect page.nextCursor. If cursors repeat, report this as a backend pagination issue.");
58942
- }
58943
- seenCursors.add(nextCursor);
58944
- const page = await client.component.list(org, repo, {
58945
- limit: opts.limit,
58946
- cursor: nextCursor
58947
- });
59306
+ for await (const page of paginatePages2({
59307
+ initialCursor: opts.cursor,
59308
+ fetchPage,
59309
+ title: "Component list"
59310
+ })) {
58948
59311
  items.push(...page.items ?? []);
58949
59312
  nextCursor = page.nextCursor;
58950
59313
  }
59314
+ } else {
59315
+ const page = await fetchPage(opts.cursor);
59316
+ items.push(...page.items ?? []);
59317
+ nextCursor = page.nextCursor;
58951
59318
  }
58952
59319
  return { items, nextCursor };
58953
59320
  }
@@ -63340,23 +63707,26 @@ var handleList6 = async (ctx, { flags, args }) => {
63340
63707
  const c = ctx.colors;
63341
63708
  const all = flags.all;
63342
63709
  const includeArchived = flags["include-archived"];
63343
- const firstPage = await ctx.client.repo.list(orgName, {
63710
+ const items = [];
63711
+ let nextCursor;
63712
+ const fetchPage = (cursor) => ctx.client.repo.list(orgName, {
63344
63713
  includeArchived,
63345
63714
  limit: flags.limit,
63346
- cursor: flags.cursor
63715
+ cursor
63347
63716
  });
63348
- const items = [...firstPage.items];
63349
- let nextCursor = firstPage.nextCursor;
63350
63717
  if (all) {
63351
- while (nextCursor) {
63352
- const page = await ctx.client.repo.list(orgName, {
63353
- includeArchived,
63354
- limit: flags.limit,
63355
- cursor: nextCursor
63356
- });
63718
+ for await (const page of paginatePages2({
63719
+ initialCursor: flags.cursor,
63720
+ fetchPage,
63721
+ title: "Repository list"
63722
+ })) {
63357
63723
  items.push(...page.items);
63358
63724
  nextCursor = page.nextCursor;
63359
63725
  }
63726
+ } else {
63727
+ const page = await fetchPage(flags.cursor);
63728
+ items.push(...page.items);
63729
+ nextCursor = page.nextCursor;
63360
63730
  }
63361
63731
  if (!all && nextCursor) {
63362
63732
  emitPartialPageHint(ctx, items.length, nextCursor, Math.min(flags.limit ?? DEFAULT_REPO_LIST_LIMIT, MAX_REPO_LIST_LIMIT));
@@ -63869,34 +64239,47 @@ var handleHistory3 = async (ctx, { flags, args }) => {
63869
64239
  functionLogs: ctx.functionLogMode,
63870
64240
  profile: ctx.profile,
63871
64241
  clientFlags: ctx.clientFlags,
64242
+ decorateResponses: ctx.decorate,
63872
64243
  signal: ctx.signal
63873
64244
  });
63874
64245
  return;
63875
64246
  }
63876
64247
  const versions2 = [];
63877
- let next = cursor;
63878
64248
  let thing;
63879
64249
  let nextCursor;
63880
- do {
63881
- const page = await ctx.client.shape.history(org, repo2, bareName, {
63882
- includeRetracted,
63883
- limit: pageLimit,
63884
- cursor: next
63885
- });
63886
- thing = thing ?? page.thing;
64250
+ let decorations;
64251
+ const fetchPage = (pageCursor) => ctx.client.shape.history(org, repo2, bareName, {
64252
+ includeRetracted,
64253
+ limit: pageLimit,
64254
+ cursor: pageCursor
64255
+ });
64256
+ if (all) {
64257
+ for await (const page of paginatePages2({
64258
+ initialCursor: cursor,
64259
+ fetchPage,
64260
+ title: "Shape history"
64261
+ })) {
64262
+ thing = thing ?? page.thing;
64263
+ versions2.push(...page.versions ?? []);
64264
+ decorations = mergeDecorations(decorations, getResponseDecorations(page));
64265
+ nextCursor = page.nextCursor;
64266
+ }
64267
+ } else {
64268
+ const page = await fetchPage(cursor);
64269
+ thing = page.thing;
63887
64270
  versions2.push(...page.versions ?? []);
64271
+ decorations = getResponseDecorations(page);
63888
64272
  nextCursor = page.nextCursor;
63889
- next = all ? nextCursor : undefined;
63890
- } while (next);
63891
- const result = {
64273
+ }
64274
+ const result = withDecorations({
63892
64275
  thing,
63893
64276
  versions: versions2,
63894
64277
  nextCursor: all ? undefined : nextCursor
63895
- };
64278
+ }, decorations);
63896
64279
  if (!all && result.nextCursor) {
63897
64280
  emitPartialPageHint(ctx, (result.versions ?? []).length, result.nextCursor, pageLimit);
63898
64281
  }
63899
- writePageOutput(ctx, result.versions ?? [], { limit: pageLimit, nextCursor: result.nextCursor ?? null }, () => renderHistory(ctx.out, ctx.colors, result));
64282
+ writePageOutput(ctx, result.versions ?? [], { limit: pageLimit, nextCursor: result.nextCursor ?? null, decorations }, () => renderHistory(ctx.out, ctx.colors, result));
63900
64283
  };
63901
64284
 
63902
64285
  // ../../packages/warmhub-cli/src/domains/shape/list.ts
@@ -64874,6 +65257,7 @@ var handleLog = async (ctx, { flags, args }) => {
64874
65257
  functionLogs: ctx.functionLogMode,
64875
65258
  profile: ctx.profile,
64876
65259
  clientFlags: ctx.clientFlags,
65260
+ decorateResponses: ctx.decorate,
64877
65261
  signal: ctx.signal
64878
65262
  });
64879
65263
  return;
@@ -66062,13 +66446,22 @@ var handleEvaluate = async (ctx, { args, flags }) => {
66062
66446
  const boundedLimit = Math.min(flags.limit ?? DEFAULT_PAGE_LIMIT, MAX_PAGE_LIMIT);
66063
66447
  const pageLimit = flags.all ? Math.min(flags.limit ?? AUTO_PAGE_LIMIT, MAX_PAGE_LIMIT) : boundedLimit;
66064
66448
  if (flags.all) {
66065
- const items = await ctx.client.view.evaluateAll(org, repo2, wref, {
66066
- limit: pageLimit,
66067
- cursor: flags.cursor
66449
+ const collected = await collectThingPages({
66450
+ initialCursor: flags.cursor,
66451
+ fetchPage: (cursor) => ctx.client.view.evaluate(org, repo2, wref, {
66452
+ limit: pageLimit,
66453
+ cursor
66454
+ }),
66455
+ requireRepoSeq: false,
66456
+ title: "View evaluate"
66068
66457
  });
66069
- writePageOutput(ctx, items, { limit: pageLimit, nextCursor: null }, () => {
66458
+ writePageOutput(ctx, collected.items, {
66459
+ limit: pageLimit,
66460
+ nextCursor: null,
66461
+ decorations: getResponseDecorations(collected)
66462
+ }, () => {
66070
66463
  ctx.out(`${ctx.colors.bold}View ${escapeTerminalTextForDisplay(wref)}${ctx.colors.reset}`);
66071
- renderQueryResults(ctx.out, ctx.colors, { items });
66464
+ renderQueryResults(ctx.out, ctx.colors, collected);
66072
66465
  });
66073
66466
  return;
66074
66467
  }
@@ -66079,7 +66472,11 @@ var handleEvaluate = async (ctx, { args, flags }) => {
66079
66472
  if (result.nextCursor) {
66080
66473
  emitPartialPageHint(ctx, result.items.length, result.nextCursor, boundedLimit);
66081
66474
  }
66082
- writePageOutput(ctx, result.items, { limit: boundedLimit, nextCursor: result.nextCursor ?? null }, () => {
66475
+ writePageOutput(ctx, result.items, {
66476
+ limit: boundedLimit,
66477
+ nextCursor: result.nextCursor ?? null,
66478
+ decorations: getResponseDecorations(result)
66479
+ }, () => {
66083
66480
  const selected = `${result.view.wref}@v${result.view.version}`;
66084
66481
  ctx.out(`${ctx.colors.bold}View ${escapeTerminalTextForDisplay(selected)}${ctx.colors.reset}`);
66085
66482
  renderQueryResults(ctx.out, ctx.colors, result);
@@ -67613,11 +68010,12 @@ async function runPreparedCli(rawArgv, prepared, opts) {
67613
68010
  requestedMode: requestedFunctionLogs
67614
68011
  });
67615
68012
  const localOnlyCommand = isLocalOnlyInvocation(invocation);
67616
- const { config: config2, client, profile, clientFlags } = localOnlyCommand ? {
68013
+ const { config: config2, client, profile, clientFlags, decorate } = localOnlyCommand ? {
67617
68014
  config: loadConfig(),
67618
68015
  client: createLocalOnlyClient(),
67619
68016
  profile: "default",
67620
- clientFlags: []
68017
+ clientFlags: [],
68018
+ decorate: true
67621
68019
  } : resolveCliContext({
67622
68020
  invocation,
67623
68021
  format,
@@ -67638,6 +68036,7 @@ async function runPreparedCli(rawArgv, prepared, opts) {
67638
68036
  invocation,
67639
68037
  profile,
67640
68038
  clientFlags,
68039
+ decorate,
67641
68040
  colors,
67642
68041
  chars,
67643
68042
  format,
@@ -67756,7 +68155,7 @@ function resolveLogLevel(flagLevel, env) {
67756
68155
  // package.json
67757
68156
  var package_default3 = {
67758
68157
  name: "@warmhub/cli",
67759
- version: "0.99.0",
68158
+ version: "0.100.0",
67760
68159
  private: false,
67761
68160
  type: "module",
67762
68161
  description: "The wh CLI for WarmHub — create repos, commit and query data, and compound knowledge with your AI agents.",
@@ -68381,5 +68780,5 @@ process.exitCode = interceptedExitCode === undefined ? await runPreparedCli(laun
68381
68780
  version: package_default3.version
68382
68781
  }) : interceptedExitCode;
68383
68782
 
68384
- //# debugId=CA32D47F32E428AA64756E2164756E21
68385
- //# warmhub-cli-build-info {"cliVersion":"0.99.0","sdkVersion":"0.97.0"}
68783
+ //# debugId=EFD7221F8FE4C7C064756E2164756E21
68784
+ //# warmhub-cli-build-info {"cliVersion":"0.100.0","sdkVersion":"0.98.0"}