@warmhub/cli 0.134.0 → 0.135.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 +314 -226
  2. package/package.json +1 -1
package/dist/wh.js CHANGED
@@ -18010,6 +18010,154 @@ var DEFAULT_MAX_OPS_PER_STREAM = 1e6;
18010
18010
  var DEFAULT_STREAM_APPEND_CHUNK_SIZE = 1000;
18011
18011
  var MAX_STREAM_APPEND_OPERATION_COUNT = 1e4;
18012
18012
  var MAX_STREAMING_SUBMISSION_LINE_BYTES = 1024 * 1024;
18013
+ // ../../packages/rules/src/crockford-base32.ts
18014
+ var ALPHABET = "0123456789ABCDEFGHJKMNPQRSTVWXYZ";
18015
+ var DECODE_TABLE = new Uint8Array(256).fill(255);
18016
+ for (let i = 0;i < ALPHABET.length; i++) {
18017
+ const ch = ALPHABET.charCodeAt(i);
18018
+ DECODE_TABLE[ch] = i;
18019
+ if (ch >= 65)
18020
+ DECODE_TABLE[ch + 32] = i;
18021
+ }
18022
+ function encodeBytes(data) {
18023
+ const bitLen = data.length * 8;
18024
+ const charCount = Math.ceil(bitLen / 5);
18025
+ let out = "";
18026
+ for (let i = 0;i < charCount; i++) {
18027
+ const bitPos = i * 5;
18028
+ const byteIdx = bitPos >> 3;
18029
+ const bitOff = bitPos & 7;
18030
+ const b1 = data[byteIdx] ?? 0;
18031
+ let val;
18032
+ if (bitOff <= 3) {
18033
+ val = b1 >> 3 - bitOff & 31;
18034
+ } else {
18035
+ const b2 = data[byteIdx + 1] ?? 0;
18036
+ val = (b1 << bitOff - 3 | b2 >> 11 - bitOff) & 31;
18037
+ }
18038
+ out += ALPHABET[val];
18039
+ }
18040
+ return out;
18041
+ }
18042
+ function decodeBytes(encoded) {
18043
+ const byteLen = Math.floor(encoded.length * 5 / 8);
18044
+ const bytes = new Uint8Array(byteLen);
18045
+ let bitBuf = 0;
18046
+ let bitsInBuf = 0;
18047
+ let bytePos = 0;
18048
+ for (let i = 0;i < encoded.length; i++) {
18049
+ const ch = encoded.charCodeAt(i);
18050
+ const val = DECODE_TABLE[ch];
18051
+ if (val === undefined || val === 255)
18052
+ return null;
18053
+ bitBuf = bitBuf << 5 | val;
18054
+ bitsInBuf += 5;
18055
+ if (bitsInBuf >= 8) {
18056
+ bitsInBuf -= 8;
18057
+ if (bytePos < byteLen) {
18058
+ bytes[bytePos++] = bitBuf >> bitsInBuf & 255;
18059
+ }
18060
+ }
18061
+ }
18062
+ return bytes;
18063
+ }
18064
+
18065
+ // ../../packages/rules/src/durable-id.ts
18066
+ var THING_SCHEME = 1;
18067
+ var REPO_SCHEME = 2;
18068
+ var UUID_BYTES = 16;
18069
+ var CRC_BYTES = 4;
18070
+ function encodedLengthFor(payloadLen) {
18071
+ return Math.ceil((1 + payloadLen + CRC_BYTES) * 8 / 5);
18072
+ }
18073
+ var CRC32C_TABLE = (() => {
18074
+ const POLY = 2197175160;
18075
+ const table = new Uint32Array(256);
18076
+ for (let i = 0;i < 256; i++) {
18077
+ let crc = i;
18078
+ for (let j = 0;j < 8; j++) {
18079
+ crc = crc & 1 ? crc >>> 1 ^ POLY : crc >>> 1;
18080
+ }
18081
+ table[i] = crc >>> 0;
18082
+ }
18083
+ return table;
18084
+ })();
18085
+ function crc32c(data) {
18086
+ let crc = 4294967295;
18087
+ for (const byte of data) {
18088
+ crc = (crc >>> 8 ^ (CRC32C_TABLE[(crc ^ byte) & 255] ?? 0)) >>> 0;
18089
+ }
18090
+ return (crc ^ 4294967295) >>> 0;
18091
+ }
18092
+ function bytesToUuid(bytes, offset = 0) {
18093
+ const hex = Array.from(bytes.slice(offset, offset + 16)).map((b) => b.toString(16).padStart(2, "0")).join("");
18094
+ return [
18095
+ hex.slice(0, 8),
18096
+ hex.slice(8, 12),
18097
+ hex.slice(12, 16),
18098
+ hex.slice(16, 20),
18099
+ hex.slice(20, 32)
18100
+ ].join("-");
18101
+ }
18102
+ function unpackToken(scheme, token, payloadLen) {
18103
+ const stripped = token.startsWith("wh:") ? token.slice(3) : token;
18104
+ if (stripped.length !== encodedLengthFor(payloadLen))
18105
+ return null;
18106
+ const raw = decodeBytes(stripped);
18107
+ if (!raw || raw.length !== 1 + payloadLen + CRC_BYTES)
18108
+ return null;
18109
+ if (raw[0] !== scheme)
18110
+ return null;
18111
+ const crcOffset = 1 + payloadLen;
18112
+ const storedCrc = (raw[crcOffset] ?? 0) << 24 | (raw[crcOffset + 1] ?? 0) << 16 | (raw[crcOffset + 2] ?? 0) << 8 | (raw[crcOffset + 3] ?? 0);
18113
+ const computedCrc = crc32c(raw.slice(0, crcOffset));
18114
+ if (storedCrc >>> 0 !== computedCrc >>> 0)
18115
+ return null;
18116
+ if (encodeBytes(raw) !== stripped.toUpperCase())
18117
+ return null;
18118
+ return raw.slice(1, 1 + payloadLen);
18119
+ }
18120
+ function decodeDurableId(token) {
18121
+ const payload = unpackToken(THING_SCHEME, token, UUID_BYTES * 2);
18122
+ if (!payload)
18123
+ return null;
18124
+ return {
18125
+ repoId: bytesToUuid(payload, 0),
18126
+ thingId: bytesToUuid(payload, UUID_BYTES)
18127
+ };
18128
+ }
18129
+ var VERSION_SELECTOR_RE = /^(?:v0*[1-9]\d*|[Hh][Ee][Aa][Dd]|[Aa][Ll][Ll])$/;
18130
+ function parseDurableReferenceToken(raw) {
18131
+ const at = raw.lastIndexOf("@");
18132
+ const selector = at >= 0 && VERSION_SELECTOR_RE.test(raw.slice(at + 1)) ? raw.slice(at + 1) : null;
18133
+ const core = selector === null ? raw : raw.slice(0, at);
18134
+ if (decodeDurableId(core) === null)
18135
+ return null;
18136
+ const stripped = core.startsWith("wh:") ? core.slice(3) : core;
18137
+ return { durableId: stripped.toUpperCase(), selector };
18138
+ }
18139
+ function decodeRepoDurableId(token) {
18140
+ const payload = unpackToken(REPO_SCHEME, token, UUID_BYTES);
18141
+ if (!payload)
18142
+ return null;
18143
+ return { repoId: bytesToUuid(payload, 0) };
18144
+ }
18145
+
18146
+ // ../../packages/rules/src/wref.ts
18147
+ function splitLocalPath(value) {
18148
+ const slashIndex = value.indexOf("/");
18149
+ if (slashIndex <= 0 || slashIndex === value.length - 1) {
18150
+ return null;
18151
+ }
18152
+ return {
18153
+ shapeName: value.slice(0, slashIndex),
18154
+ bareName: value.slice(slashIndex + 1)
18155
+ };
18156
+ }
18157
+ function withVersion(wref, version) {
18158
+ return `${wref}@v${version}`;
18159
+ }
18160
+
18013
18161
  // ../../packages/rules/src/commit-types.ts
18014
18162
  var COMMIT_OPERATIONS = [
18015
18163
  "add",
@@ -18032,11 +18180,9 @@ var READ_KIND_FILTERS = [
18032
18180
  LEGACY_COLLECTION_READ_KIND,
18033
18181
  LEGACY_ASSERTION_READ_KIND
18034
18182
  ];
18035
- function splitLocalPath(name) {
18036
- const idx = name.indexOf("/");
18037
- if (idx === -1)
18038
- return null;
18039
- return { shapePrefix: name.slice(0, idx), bareName: name.slice(idx + 1) };
18183
+ function splitLocalPath2(name) {
18184
+ const local = splitLocalPath(name);
18185
+ return local ? { shapePrefix: local.shapeName, bareName: local.bareName } : null;
18040
18186
  }
18041
18187
  function inferOperationKind(op) {
18042
18188
  if (op.kind === "shape" || op.kind === "thing" || op.kind === "assertion" || op.kind === "collection") {
@@ -25802,6 +25948,8 @@ function validateManifestSemantics(manifest) {
25802
25948
  }
25803
25949
  return findings;
25804
25950
  }
25951
+ // ../../packages/rules/src/edge-authz.ts
25952
+ var MAX_ALLOWED_SHAPES_PER_LIST = 64;
25805
25953
  // ../../packages/rules/src/external-contract.ts
25806
25954
  var FORBIDDEN_EXTERNAL_FIELDS = new Set([
25807
25955
  "_id",
@@ -26153,7 +26301,7 @@ function preflightOpDiagnostics(op, operationIndex) {
26153
26301
  function builtinShapeGuard(op, operationIndex) {
26154
26302
  const errors = [];
26155
26303
  const name = op.name;
26156
- const isShapeRename = op.operation === "rename" && (op.kind === "shape" || op.name !== undefined && !splitLocalPath(op.name));
26304
+ const isShapeRename = op.operation === "rename" && (op.kind === "shape" || op.name !== undefined && !splitLocalPath2(op.name));
26157
26305
  const reservedSourcePassThrough = isShapeRename && name !== undefined && isRenameableSquattedShape(name) && op.newName !== undefined && !isReservedCollectionShape(op.newName) && !isBuiltinShape(op.newName);
26158
26306
  if (name && isRetiredCollectionShape(name) && !reservedSourcePassThrough) {
26159
26307
  errors.push({
@@ -26162,7 +26310,7 @@ function builtinShapeGuard(op, operationIndex) {
26162
26310
  message: `Shape "${name}" is a retired collection shape and cannot be written manually`
26163
26311
  });
26164
26312
  }
26165
- if (op.operation === "rename" && (op.kind === "shape" || op.name !== undefined && !splitLocalPath(op.name)) && op.newName && isRetiredCollectionShape(op.newName)) {
26313
+ if (op.operation === "rename" && (op.kind === "shape" || op.name !== undefined && !splitLocalPath2(op.name)) && op.newName && isRetiredCollectionShape(op.newName)) {
26166
26314
  errors.push({
26167
26315
  code: "RESERVED_NAME",
26168
26316
  operationIndex,
@@ -26180,7 +26328,7 @@ function builtinShapeGuard(op, operationIndex) {
26180
26328
  }
26181
26329
  }
26182
26330
  if (name && op.operation !== "retract") {
26183
- const local = splitLocalPath(name);
26331
+ const local = splitLocalPath2(name);
26184
26332
  if (local && isRetiredCollectionShape(local.shapePrefix)) {
26185
26333
  errors.push({
26186
26334
  code: "VALIDATION_ERROR",
@@ -26209,13 +26357,13 @@ function reservedRootGuard(op, operationIndex) {
26209
26357
  if (op.kind === "shape")
26210
26358
  return [];
26211
26359
  if (op.operation === "add" && op.name) {
26212
- const stored = op.kind === "collection" ? op.name : splitLocalPath(op.name)?.bareName;
26360
+ const stored = op.kind === "collection" ? op.name : splitLocalPath2(op.name)?.bareName;
26213
26361
  if (stored !== undefined && isReservedThingRoot(stored)) {
26214
26362
  return [reservedRootRefusal(stored, operationIndex)];
26215
26363
  }
26216
26364
  return [];
26217
26365
  }
26218
- const isShapeRename = op.name !== undefined && splitLocalPath(op.name) === null;
26366
+ const isShapeRename = op.name !== undefined && splitLocalPath2(op.name) === null;
26219
26367
  if (op.operation === "rename" && !isShapeRename && op.newName !== undefined && isReservedThingRoot(op.newName)) {
26220
26368
  return [reservedRootRefusal(op.newName, operationIndex)];
26221
26369
  }
@@ -26224,7 +26372,7 @@ function reservedRootGuard(op, operationIndex) {
26224
26372
  function contentNameGuard(op, operationIndex) {
26225
26373
  if (op.kind !== "thing" || !op.name)
26226
26374
  return [];
26227
- const local = splitLocalPath(op.name);
26375
+ const local = splitLocalPath2(op.name);
26228
26376
  if (!local || !isContentShape(local.shapePrefix))
26229
26377
  return [];
26230
26378
  const bareName = local.bareName;
@@ -26270,7 +26418,7 @@ function plusSignGuard(op, operationIndex) {
26270
26418
  }
26271
26419
  if (op.kind === "collection")
26272
26420
  return errors;
26273
- const local = splitLocalPath(name);
26421
+ const local = splitLocalPath2(name);
26274
26422
  if (local && isReservedCollectionShape(local.shapePrefix))
26275
26423
  return errors;
26276
26424
  errors.push({
@@ -43539,139 +43687,6 @@ function commitValidateRequestBodyBytes(input) {
43539
43687
  return new TextEncoder().encode(encodeCommitValidateRequestBody(input)).byteLength;
43540
43688
  }
43541
43689
 
43542
- // ../../packages/rules/src/crockford-base32.ts
43543
- var ALPHABET = "0123456789ABCDEFGHJKMNPQRSTVWXYZ";
43544
- var DECODE_TABLE = new Uint8Array(256).fill(255);
43545
- for (let i = 0;i < ALPHABET.length; i++) {
43546
- const ch = ALPHABET.charCodeAt(i);
43547
- DECODE_TABLE[ch] = i;
43548
- if (ch >= 65)
43549
- DECODE_TABLE[ch + 32] = i;
43550
- }
43551
- function encodeBytes(data) {
43552
- const bitLen = data.length * 8;
43553
- const charCount = Math.ceil(bitLen / 5);
43554
- let out = "";
43555
- for (let i = 0;i < charCount; i++) {
43556
- const bitPos = i * 5;
43557
- const byteIdx = bitPos >> 3;
43558
- const bitOff = bitPos & 7;
43559
- const b1 = data[byteIdx] ?? 0;
43560
- let val;
43561
- if (bitOff <= 3) {
43562
- val = b1 >> 3 - bitOff & 31;
43563
- } else {
43564
- const b2 = data[byteIdx + 1] ?? 0;
43565
- val = (b1 << bitOff - 3 | b2 >> 11 - bitOff) & 31;
43566
- }
43567
- out += ALPHABET[val];
43568
- }
43569
- return out;
43570
- }
43571
- function decodeBytes(encoded) {
43572
- const byteLen = Math.floor(encoded.length * 5 / 8);
43573
- const bytes = new Uint8Array(byteLen);
43574
- let bitBuf = 0;
43575
- let bitsInBuf = 0;
43576
- let bytePos = 0;
43577
- for (let i = 0;i < encoded.length; i++) {
43578
- const ch = encoded.charCodeAt(i);
43579
- const val = DECODE_TABLE[ch];
43580
- if (val === undefined || val === 255)
43581
- return null;
43582
- bitBuf = bitBuf << 5 | val;
43583
- bitsInBuf += 5;
43584
- if (bitsInBuf >= 8) {
43585
- bitsInBuf -= 8;
43586
- if (bytePos < byteLen) {
43587
- bytes[bytePos++] = bitBuf >> bitsInBuf & 255;
43588
- }
43589
- }
43590
- }
43591
- return bytes;
43592
- }
43593
-
43594
- // ../../packages/rules/src/durable-id.ts
43595
- var THING_SCHEME = 1;
43596
- var REPO_SCHEME = 2;
43597
- var UUID_BYTES = 16;
43598
- var CRC_BYTES = 4;
43599
- function encodedLengthFor(payloadLen) {
43600
- return Math.ceil((1 + payloadLen + CRC_BYTES) * 8 / 5);
43601
- }
43602
- var CRC32C_TABLE = (() => {
43603
- const POLY = 2197175160;
43604
- const table = new Uint32Array(256);
43605
- for (let i = 0;i < 256; i++) {
43606
- let crc = i;
43607
- for (let j = 0;j < 8; j++) {
43608
- crc = crc & 1 ? crc >>> 1 ^ POLY : crc >>> 1;
43609
- }
43610
- table[i] = crc >>> 0;
43611
- }
43612
- return table;
43613
- })();
43614
- function crc32c(data) {
43615
- let crc = 4294967295;
43616
- for (const byte of data) {
43617
- crc = (crc >>> 8 ^ (CRC32C_TABLE[(crc ^ byte) & 255] ?? 0)) >>> 0;
43618
- }
43619
- return (crc ^ 4294967295) >>> 0;
43620
- }
43621
- function bytesToUuid(bytes, offset = 0) {
43622
- const hex3 = Array.from(bytes.slice(offset, offset + 16)).map((b) => b.toString(16).padStart(2, "0")).join("");
43623
- return [
43624
- hex3.slice(0, 8),
43625
- hex3.slice(8, 12),
43626
- hex3.slice(12, 16),
43627
- hex3.slice(16, 20),
43628
- hex3.slice(20, 32)
43629
- ].join("-");
43630
- }
43631
- function unpackToken(scheme, token, payloadLen) {
43632
- const stripped = token.startsWith("wh:") ? token.slice(3) : token;
43633
- if (stripped.length !== encodedLengthFor(payloadLen))
43634
- return null;
43635
- const raw = decodeBytes(stripped);
43636
- if (!raw || raw.length !== 1 + payloadLen + CRC_BYTES)
43637
- return null;
43638
- if (raw[0] !== scheme)
43639
- return null;
43640
- const crcOffset = 1 + payloadLen;
43641
- const storedCrc = (raw[crcOffset] ?? 0) << 24 | (raw[crcOffset + 1] ?? 0) << 16 | (raw[crcOffset + 2] ?? 0) << 8 | (raw[crcOffset + 3] ?? 0);
43642
- const computedCrc = crc32c(raw.slice(0, crcOffset));
43643
- if (storedCrc >>> 0 !== computedCrc >>> 0)
43644
- return null;
43645
- if (encodeBytes(raw) !== stripped.toUpperCase())
43646
- return null;
43647
- return raw.slice(1, 1 + payloadLen);
43648
- }
43649
- function decodeDurableId(token) {
43650
- const payload = unpackToken(THING_SCHEME, token, UUID_BYTES * 2);
43651
- if (!payload)
43652
- return null;
43653
- return {
43654
- repoId: bytesToUuid(payload, 0),
43655
- thingId: bytesToUuid(payload, UUID_BYTES)
43656
- };
43657
- }
43658
- var VERSION_SELECTOR_RE = /^(?:v0*[1-9]\d*|[Hh][Ee][Aa][Dd]|[Aa][Ll][Ll])$/;
43659
- function parseDurableReferenceToken(raw) {
43660
- const at = raw.lastIndexOf("@");
43661
- const selector = at >= 0 && VERSION_SELECTOR_RE.test(raw.slice(at + 1)) ? raw.slice(at + 1) : null;
43662
- const core2 = selector === null ? raw : raw.slice(0, at);
43663
- if (decodeDurableId(core2) === null)
43664
- return null;
43665
- const stripped = core2.startsWith("wh:") ? core2.slice(3) : core2;
43666
- return { durableId: stripped.toUpperCase(), selector };
43667
- }
43668
- function decodeRepoDurableId(token) {
43669
- const payload = unpackToken(REPO_SCHEME, token, UUID_BYTES);
43670
- if (!payload)
43671
- return null;
43672
- return { repoId: bytesToUuid(payload, 0) };
43673
- }
43674
-
43675
43690
  // ../../packages/rules/src/json-string-walk.ts
43676
43691
  function walkJsonStringLeaves(value, spec) {
43677
43692
  const { childContext, onStringValue, onObjectKey } = spec;
@@ -45463,7 +45478,7 @@ function createStreamingSubmissionHandle(input, deps) {
45463
45478
  // ../../packages/sdk-ts/package.json
45464
45479
  var package_default = {
45465
45480
  name: "@warmhub/sdk-ts",
45466
- version: "0.132.0",
45481
+ version: "0.133.0",
45467
45482
  private: false,
45468
45483
  type: "module",
45469
45484
  description: "The TypeScript SDK for WarmHub — create repos, commit and query data, and compound knowledge with your AI agents.",
@@ -52326,7 +52341,7 @@ function pinnedWref(c, wref, version2) {
52326
52341
  return `${c.cyan}${escapeTerminalTextForDisplay(wref)}${c.reset}`;
52327
52342
  }
52328
52343
  const base = wref.replace(/@v\d+$/, "");
52329
- return `${c.cyan}${escapeTerminalTextForDisplay(base)}@v${version2}${c.reset}`;
52344
+ return `${c.cyan}${withVersion(escapeTerminalTextForDisplay(base), version2)}${c.reset}`;
52330
52345
  }
52331
52346
  function kindLabel(c, kind) {
52332
52347
  return `${c.dim}${kind}${c.reset}`;
@@ -52337,16 +52352,21 @@ function asCollectionSummaries(value) {
52337
52352
  const entries = value.filter((entry) => typeof entry === "object" && entry !== null && typeof entry.shape === "string");
52338
52353
  return entries.length > 0 ? entries : undefined;
52339
52354
  }
52340
- function bareShapeName(token) {
52355
+ function bareShapeName2(token) {
52341
52356
  const withoutVersion = token.split("@", 1)[0] ?? "";
52342
52357
  return withoutVersion.slice(withoutVersion.lastIndexOf("/") + 1);
52343
52358
  }
52344
- function effectiveKind(kind, shapeName, collections) {
52359
+ function effectiveKind(kind, collections) {
52345
52360
  if (kind !== "thing" && kind)
52346
52361
  return kind;
52347
52362
  const summaryShape = collections?.[0]?.shape;
52348
52363
  if (summaryShape)
52349
- return bareShapeName(summaryShape).toLowerCase();
52364
+ return bareShapeName2(summaryShape).toLowerCase();
52365
+ return kind;
52366
+ }
52367
+ function kindWithoutCertificate(kind, shapeName) {
52368
+ if (kind !== "thing" && kind)
52369
+ return kind;
52350
52370
  if (shapeName && isBuiltinCollectionShape(shapeName)) {
52351
52371
  return shapeName.toLowerCase();
52352
52372
  }
@@ -53258,9 +53278,6 @@ var handleCreate2 = async (ctx, { flags, args }) => {
53258
53278
  };
53259
53279
 
53260
53280
  // ../../packages/warmhub-cli/src/domains/thing/render.ts
53261
- function singularShapeName(result) {
53262
- return result.shapeName ?? result.shape;
53263
- }
53264
53281
  function renderHead(out, c, chars, result, org, repo, shape, kind) {
53265
53282
  const items = result.items ?? [];
53266
53283
  const decorations = getResponseDecorations(result);
@@ -53272,8 +53289,7 @@ function renderHead(out, c, chars, result, org, repo, shape, kind) {
53272
53289
  out(`${c.dim}${chars.hLine.repeat(60)}${c.reset}`);
53273
53290
  for (const item of items) {
53274
53291
  const wref = pinnedWref(c, item.wref ?? item.name ?? "(unknown)", item.version);
53275
- const shapeName = item.shapeName;
53276
- const kl = kindLabel(c, effectiveKind(item.kind ?? "thing", shapeName, asCollectionSummaries(item.collections)));
53292
+ const kl = kindLabel(c, effectiveKind(item.kind ?? "thing", asCollectionSummaries(item.collections)));
53277
53293
  const retractedTag = item.active === false ? ` ${c.red}[RETRACTED]${c.reset}` : "";
53278
53294
  out(` ${wref} ${kl}${retractedTag}`);
53279
53295
  if (item.declaredShapes?.length) {
@@ -53301,8 +53317,7 @@ function renderHead(out, c, chars, result, org, repo, shape, kind) {
53301
53317
  function renderThing(out, c, result) {
53302
53318
  const decorations = getResponseDecorations(result);
53303
53319
  const wref = result.wref ?? result.name ?? "(unknown)";
53304
- const shapeName = singularShapeName(result);
53305
- const displayKind = effectiveKind(result.kind ?? "thing", shapeName, result.collections);
53320
+ const displayKind = effectiveKind(result.kind ?? "thing", result.collections);
53306
53321
  const retractedTag = result.active === false ? ` ${c.red}[RETRACTED]${c.reset}` : "";
53307
53322
  out(`${pinnedWref(c, wref, result.version)} ${kindLabel(c, displayKind)}${retractedTag}`);
53308
53323
  out(` ${c.dim}wref:${c.reset} ${escapeTerminalTextForDisplay(wref)}`);
@@ -53382,8 +53397,7 @@ function renderGraphValue(out, c, value, indent, decorations) {
53382
53397
  }
53383
53398
  function renderGraphNode(out, c, result, indent = "", decorations) {
53384
53399
  const wref = result.wref ?? result.name ?? "(unknown)";
53385
- const shapeName = singularShapeName(result);
53386
- const displayKind = effectiveKind(result.kind ?? "thing", shapeName, result.collections);
53400
+ const displayKind = effectiveKind(result.kind ?? "thing", result.collections);
53387
53401
  out(`${indent}${pinnedWref(c, wref, result.version)} ${kindLabel(c, displayKind)}`);
53388
53402
  if (result.about) {
53389
53403
  out(`${indent} ${c.dim}about:${c.reset}`);
@@ -53423,7 +53437,9 @@ function renderHistory(out, c, result) {
53423
53437
  const decorations = getResponseDecorations(result);
53424
53438
  if (result.thing && typeof result.thing === "object") {
53425
53439
  const wref = result.thing.wref ?? result.thing.name ?? "(unknown)";
53426
- out(`${c.bold}History: ${pinnedWref(c, wref)}${c.reset} ${kindLabel(c, effectiveKind(result.thing.kind ?? "thing", result.thing.shapeName))}`);
53440
+ const newest = (result.versions ?? []).reduce((best, v) => !best || v.version > best.version ? v : best, undefined);
53441
+ const kind = effectiveKind(result.thing.kind ?? "thing", asCollectionSummaries(newest?.collections));
53442
+ out(`${c.bold}History: ${pinnedWref(c, wref)}${c.reset} ${kindLabel(c, kind)}`);
53427
53443
  }
53428
53444
  const firstMeta = result.versions?.[0]?.metadata;
53429
53445
  if (firstMeta?.durableId) {
@@ -53474,7 +53490,7 @@ function renderRefs(out, c, result, wref, direction) {
53474
53490
  out(`${c.dim}${"─".repeat(60)}${c.reset}`);
53475
53491
  for (const item of items) {
53476
53492
  const refWref = refDisplay(c, item.wref, decorations, item.version);
53477
- const kl = kindLabel(c, effectiveKind(item.kind ?? "thing", item.shapeName));
53493
+ const kl = kindLabel(c, kindWithoutCertificate(item.kind ?? "thing", item.shapeName));
53478
53494
  const field = `${c.dim}via ${c.reset}${escapeTerminalTextForDisplay(item.fieldPath ?? "(unknown)")}`;
53479
53495
  const binding = item.binding ? ` ${c.dim}${item.binding}${c.reset}` : "";
53480
53496
  out(` ${refWref} ${kl} ${field}${binding}`);
@@ -53486,7 +53502,7 @@ function* walkBatchResult(wrefs, result, flagsVersion) {
53486
53502
  let missIdx = 0;
53487
53503
  for (const requested of wrefs) {
53488
53504
  const nextMiss = result.missing[missIdx];
53489
- const qualified = flagsVersion !== undefined && !/@v\d+$/.test(requested) ? `${requested}@v${flagsVersion}` : requested;
53505
+ const qualified = flagsVersion !== undefined && !/@v\d+$/.test(requested) ? withVersion(requested, flagsVersion) : requested;
53490
53506
  if (nextMiss !== undefined && (nextMiss === requested || nextMiss === qualified)) {
53491
53507
  yield { kind: "miss", requested, missWref: nextMiss };
53492
53508
  missIdx++;
@@ -53513,9 +53529,9 @@ function renderBatchView(out, c, result, wrefs, flagsVersion) {
53513
53529
  const requestedBase = requested.replace(/@.+$/, "");
53514
53530
  const fallback = item.wref ?? `${item.shapeName ?? "?"}/${item.name ?? "(unknown)"}`;
53515
53531
  const base = requestedBase.length > 0 ? requestedBase : fallback.replace(/@v\d+$/, "");
53516
- const kl = kindLabel(c, effectiveKind(item.kind ?? "thing", item.shapeName, asCollectionSummaries(item.collections)));
53532
+ const kl = kindLabel(c, effectiveKind(item.kind ?? "thing", asCollectionSummaries(item.collections)));
53517
53533
  const retractedTag = item.active === false ? ` ${c.red}[RETRACTED]${c.reset}` : "";
53518
- const display = labeledRef(c, `${base}@v${item.version}`, fallback) ?? `${escapeTerminalTextForDisplay(base)}@v${item.version}`;
53534
+ const display = labeledRef(c, withVersion(base, item.version), fallback) ?? withVersion(escapeTerminalTextForDisplay(base), item.version);
53519
53535
  out(` ${display} ${kl}${retractedTag}`);
53520
53536
  }
53521
53537
  if (result.missing.length > 0) {
@@ -54264,8 +54280,7 @@ function renderQueryResults(out, c, result) {
54264
54280
  }
54265
54281
  for (const item of items) {
54266
54282
  const wref = pinnedWref(c, item.wref ?? item.name ?? "(unknown)", item.version);
54267
- const shapeName = item.shapeName;
54268
- const kl = kindLabel(c, effectiveKind(item.kind ?? "thing", shapeName, asCollectionSummaries(item.collections)));
54283
+ const kl = kindLabel(c, effectiveKind(item.kind ?? "thing", asCollectionSummaries(item.collections)));
54269
54284
  const retractedTag = item.active === false ? ` ${c.red}[RETRACTED]${c.reset}` : "";
54270
54285
  out(` ${wref} ${kl}${retractedTag}`);
54271
54286
  if (item.declaredShapes?.length) {
@@ -55649,6 +55664,129 @@ Run \`wh auth login --profile ${explicitProfile}\` to create it.`);
55649
55664
  };
55650
55665
  }
55651
55666
 
55667
+ // ../../packages/warmhub-cli/src/scope-parse.ts
55668
+ var ENTRY_KEYS = new Set([
55669
+ "resource",
55670
+ "permissions",
55671
+ "allowedMatches",
55672
+ "allowedShapes"
55673
+ ]);
55674
+ var SHAPE_LIST_KEYS = ["shapes", "shapesAll", "shapesNot"];
55675
+ var SHAPE_CLAUSE_KEYS = new Set([...SHAPE_LIST_KEYS, "shapeless"]);
55676
+ function shapeClauseExample(allowResource) {
55677
+ const resource = allowResource ? '"resource":"myorg/myrepo",' : "";
55678
+ return `[{${resource}"permissions":["repo:read"],"allowedMatches":["**"],"allowedShapes":{"shapes":["Player"],"shapesNot":["Secret"]}}]`;
55679
+ }
55680
+ function parseScopeEntriesJson(json2, opts) {
55681
+ const { flagLabel, allowResource } = opts;
55682
+ let parsed;
55683
+ try {
55684
+ parsed = JSON.parse(json2);
55685
+ } catch {
55686
+ throw new CliError(2 /* UserInput */, "USER_INPUT", `${flagLabel} must be valid JSON`);
55687
+ }
55688
+ if (!Array.isArray(parsed) || parsed.length === 0) {
55689
+ throw new CliError(2 /* UserInput */, "USER_INPUT", `${flagLabel} must be a non-empty JSON array`);
55690
+ }
55691
+ return parsed.map((entry, i) => {
55692
+ if (typeof entry !== "object" || entry === null || Array.isArray(entry)) {
55693
+ throw new CliError(2 /* UserInput */, "USER_INPUT", `${flagLabel} entry ${i + 1}: must be an object`);
55694
+ }
55695
+ const obj = entry;
55696
+ const unknownKey = Object.keys(obj).find((key) => !ENTRY_KEYS.has(key));
55697
+ if (unknownKey !== undefined) {
55698
+ throw new CliError(2 /* UserInput */, "USER_INPUT", `${flagLabel} entry ${i + 1}: unknown key "${unknownKey}"`, undefined, `Entry keys are resource, permissions, allowedMatches, allowedShapes. Example: ${flagLabel} '${shapeClauseExample(allowResource)}'`);
55699
+ }
55700
+ if (!Array.isArray(obj.permissions) || obj.permissions.length === 0 || obj.permissions.some((p) => typeof p !== "string" || p.trim().length === 0)) {
55701
+ throw new CliError(2 /* UserInput */, "USER_INPUT", `${flagLabel} entry ${i + 1}: "permissions" must be a non-empty array of non-empty strings`);
55702
+ }
55703
+ if (obj.resource !== undefined) {
55704
+ if (!allowResource) {
55705
+ throw new CliError(2 /* UserInput */, "USER_INPUT", `${flagLabel} entry ${i + 1}: "resource" is not supported (resource is set automatically)`);
55706
+ }
55707
+ if (typeof obj.resource !== "string") {
55708
+ throw new CliError(2 /* UserInput */, "USER_INPUT", `${flagLabel} entry ${i + 1}: "resource" must be a string`);
55709
+ }
55710
+ }
55711
+ if (obj.allowedMatches !== undefined) {
55712
+ if (!Array.isArray(obj.allowedMatches) || obj.allowedMatches.some((m) => typeof m !== "string" || m.trim().length === 0)) {
55713
+ throw new CliError(2 /* UserInput */, "USER_INPUT", `${flagLabel} entry ${i + 1}: "allowedMatches" must be an array of non-empty strings`);
55714
+ }
55715
+ }
55716
+ const allowedShapes = obj.allowedShapes === undefined ? undefined : parseAllowedShapes(obj.allowedShapes, flagLabel, i + 1, allowResource);
55717
+ if (allowResource && (obj.allowedMatches !== undefined || allowedShapes !== undefined) && (typeof obj.resource !== "string" || !obj.resource.includes("/"))) {
55718
+ const fields = [
55719
+ obj.allowedMatches !== undefined && '"allowedMatches"',
55720
+ allowedShapes !== undefined && '"allowedShapes"'
55721
+ ].filter(Boolean).join(" and ");
55722
+ throw new CliError(2 /* UserInput */, "USER_INPUT", `${flagLabel} entry ${i + 1}: ${fields} would restrict nothing on ${typeof obj.resource === "string" ? `the org entry "${obj.resource}"` : "an entry without a resource"}; name and Shape restrictions apply only to a repository entry`, undefined, `Name the repository. Example: ${flagLabel} '${shapeClauseExample(allowResource)}'`);
55723
+ }
55724
+ const result = {
55725
+ permissions: obj.permissions.map((p) => p.trim())
55726
+ };
55727
+ if (obj.resource !== undefined)
55728
+ result.resource = obj.resource;
55729
+ if (obj.allowedMatches !== undefined)
55730
+ result.allowedMatches = obj.allowedMatches.map((m) => m.trim());
55731
+ if (allowedShapes !== undefined)
55732
+ result.allowedShapes = allowedShapes;
55733
+ return result;
55734
+ });
55735
+ }
55736
+ function parseAllowedShapes(value, flagLabel, entry, allowResource) {
55737
+ const refuse = (message) => {
55738
+ throw new CliError(2 /* UserInput */, "USER_INPUT", `${flagLabel} entry ${entry}: "allowedShapes" ${message}`, undefined, `Keys are shapes, shapesAll, shapesNot (1-${MAX_ALLOWED_SHAPES_PER_LIST} Shape names each) and shapeless (boolean). Example: ${flagLabel} '${shapeClauseExample(allowResource)}'`);
55739
+ };
55740
+ if (typeof value !== "object" || value === null || Array.isArray(value)) {
55741
+ refuse("must be an object");
55742
+ }
55743
+ const obj = value;
55744
+ const unknownKey = Object.keys(obj).find((key) => !SHAPE_CLAUSE_KEYS.has(key));
55745
+ if (unknownKey !== undefined)
55746
+ refuse(`has unknown key "${unknownKey}"`);
55747
+ const clause = {};
55748
+ for (const key of SHAPE_LIST_KEYS) {
55749
+ const list = obj[key];
55750
+ if (list === undefined)
55751
+ continue;
55752
+ if (!Array.isArray(list) || list.length === 0 || list.some((n) => typeof n !== "string" || n.trim().length === 0)) {
55753
+ refuse(`"${key}" must be a non-empty array of non-empty Shape names`);
55754
+ }
55755
+ const names = list;
55756
+ if (names.length > MAX_ALLOWED_SHAPES_PER_LIST) {
55757
+ refuse(`"${key}" names ${names.length} Shapes; the limit is ${MAX_ALLOWED_SHAPES_PER_LIST}`);
55758
+ }
55759
+ clause[key] = names.map((n) => n.trim());
55760
+ }
55761
+ if (obj.shapeless !== undefined) {
55762
+ if (typeof obj.shapeless !== "boolean")
55763
+ refuse('"shapeless" must be a boolean');
55764
+ clause.shapeless = obj.shapeless;
55765
+ }
55766
+ return clause;
55767
+ }
55768
+ function formatAllowedShapes(allowedShapes) {
55769
+ if (allowedShapes === undefined)
55770
+ return "";
55771
+ const parts = [];
55772
+ for (const key of SHAPE_LIST_KEYS) {
55773
+ const list = allowedShapes[key];
55774
+ if (list !== undefined) {
55775
+ parts.push(`${key}: ${list.length > 0 ? list.join(", ") : "[none]"}`);
55776
+ }
55777
+ }
55778
+ if (allowedShapes.shapeless !== undefined)
55779
+ parts.push(allowedShapes.shapeless ? "shapeless" : "no shapeless");
55780
+ return parts.map((part) => ` ${part}`).join("");
55781
+ }
55782
+ function formatAllowedMatches(allowedMatches) {
55783
+ if (allowedMatches === undefined)
55784
+ return "";
55785
+ if (allowedMatches.length === 0)
55786
+ return " match: [deny-all]";
55787
+ return ` match: ${allowedMatches.join(", ")}`;
55788
+ }
55789
+
55652
55790
  // ../../packages/warmhub-cli/src/domains/auth-shared.ts
55653
55791
  function clientForStoredFlags(ctx, profile) {
55654
55792
  const { flags } = resolveClientFlags(getProfile(profile)?.flags);
@@ -61817,10 +61955,11 @@ async function collectChecks(ctx) {
61817
61955
  if (whoami.scopes && whoami.scopes.length > 0) {
61818
61956
  const scopeParts = whoami.scopes.map((s) => {
61819
61957
  const perms = s.permissions.join(", ");
61958
+ const shapes = formatAllowedShapes(s.allowedShapes);
61820
61959
  if (s.redactedResource) {
61821
- return `${perms} on redacted/inaccessible repo`;
61960
+ return `${perms} on redacted/inaccessible repo${shapes}`;
61822
61961
  }
61823
- return s.resource ? `${perms} on ${s.resource}` : perms;
61962
+ return `${s.resource ? `${perms} on ${s.resource}` : perms}${shapes}`;
61824
61963
  });
61825
61964
  detailLines.push(`Scopes: ${scopeParts.join(", ")}`);
61826
61965
  }
@@ -67273,57 +67412,6 @@ var SUB_DOMAIN = defineDomain({
67273
67412
  }
67274
67413
  }
67275
67414
  });
67276
- // ../../packages/warmhub-cli/src/scope-parse.ts
67277
- function parseScopeEntriesJson(json2, opts) {
67278
- const { flagLabel, allowResource } = opts;
67279
- let parsed;
67280
- try {
67281
- parsed = JSON.parse(json2);
67282
- } catch {
67283
- throw new CliError(2 /* UserInput */, "USER_INPUT", `${flagLabel} must be valid JSON`);
67284
- }
67285
- if (!Array.isArray(parsed) || parsed.length === 0) {
67286
- throw new CliError(2 /* UserInput */, "USER_INPUT", `${flagLabel} must be a non-empty JSON array`);
67287
- }
67288
- return parsed.map((entry, i) => {
67289
- if (typeof entry !== "object" || entry === null || Array.isArray(entry)) {
67290
- throw new CliError(2 /* UserInput */, "USER_INPUT", `${flagLabel} entry ${i + 1}: must be an object`);
67291
- }
67292
- const obj = entry;
67293
- if (!Array.isArray(obj.permissions) || obj.permissions.length === 0 || obj.permissions.some((p) => typeof p !== "string" || p.trim().length === 0)) {
67294
- throw new CliError(2 /* UserInput */, "USER_INPUT", `${flagLabel} entry ${i + 1}: "permissions" must be a non-empty array of non-empty strings`);
67295
- }
67296
- if (obj.resource !== undefined) {
67297
- if (!allowResource) {
67298
- throw new CliError(2 /* UserInput */, "USER_INPUT", `${flagLabel} entry ${i + 1}: "resource" is not supported (resource is set automatically)`);
67299
- }
67300
- if (typeof obj.resource !== "string") {
67301
- throw new CliError(2 /* UserInput */, "USER_INPUT", `${flagLabel} entry ${i + 1}: "resource" must be a string`);
67302
- }
67303
- }
67304
- if (obj.allowedMatches !== undefined) {
67305
- if (!Array.isArray(obj.allowedMatches) || obj.allowedMatches.some((m) => typeof m !== "string" || m.trim().length === 0)) {
67306
- throw new CliError(2 /* UserInput */, "USER_INPUT", `${flagLabel} entry ${i + 1}: "allowedMatches" must be an array of non-empty strings`);
67307
- }
67308
- }
67309
- const result = {
67310
- permissions: obj.permissions.map((p) => p.trim())
67311
- };
67312
- if (obj.resource !== undefined)
67313
- result.resource = obj.resource;
67314
- if (obj.allowedMatches !== undefined)
67315
- result.allowedMatches = obj.allowedMatches.map((m) => m.trim());
67316
- return result;
67317
- });
67318
- }
67319
- function formatAllowedMatches(allowedMatches) {
67320
- if (allowedMatches === undefined)
67321
- return "";
67322
- if (allowedMatches.length === 0)
67323
- return " match: [deny-all]";
67324
- return ` match: ${allowedMatches.join(", ")}`;
67325
- }
67326
-
67327
67415
  // ../../packages/warmhub-cli/src/domains/token.ts
67328
67416
  var DURATION_MULTIPLIERS = {
67329
67417
  h: 3600000,
@@ -67356,7 +67444,7 @@ var createFlags10 = {
67356
67444
  multiple: true
67357
67445
  }),
67358
67446
  "scopes-json": flag.string({
67359
- description: "Structured scope entries as JSON array (advanced; use for allowedMatches or repeated resource entries; mutually exclusive with --scope)"
67447
+ description: "Structured scope entries as JSON array (advanced; use for allowedMatches, allowedShapes, or repeated resource entries; mutually exclusive with --scope)"
67360
67448
  }),
67361
67449
  description: flag.string({ short: "d", description: "Token description" }),
67362
67450
  expires: flag.string({
@@ -67401,10 +67489,10 @@ function formatScopes(scopes) {
67401
67489
  return "full access";
67402
67490
  return scopes.map((e) => {
67403
67491
  if (e.redactedResource) {
67404
- return `redacted/inaccessible repo=${e.permissions.join(",")}${formatAllowedMatches(e.allowedMatches)}`;
67492
+ return `redacted/inaccessible repo=${e.permissions.join(",")}${formatAllowedMatches(e.allowedMatches)}${formatAllowedShapes(e.allowedShapes)}`;
67405
67493
  }
67406
67494
  const base = e.resource ? `${e.resource}=${e.permissions.join(",")}` : e.permissions.join(",");
67407
- return `${base}${formatAllowedMatches(e.allowedMatches)}`;
67495
+ return `${base}${formatAllowedMatches(e.allowedMatches)}${formatAllowedShapes(e.allowedShapes)}`;
67408
67496
  }).join(" ");
67409
67497
  }
67410
67498
  var handleCreate9 = async (ctx, { flags }) => {
@@ -68271,7 +68359,7 @@ var handleEvaluate = async (ctx, { args, flags }) => {
68271
68359
  nextCursor: result.nextCursor ?? null,
68272
68360
  decorations: getResponseDecorations(result)
68273
68361
  }, () => {
68274
- const selected = `${result.view.wref}@v${result.view.version}`;
68362
+ const selected = withVersion(result.view.wref, result.view.version);
68275
68363
  ctx.out(`${ctx.colors.bold}View ${escapeTerminalTextForDisplay(selected)}${ctx.colors.reset}`);
68276
68364
  renderQueryResults(ctx.out, ctx.colors, result);
68277
68365
  });
@@ -69964,7 +70052,7 @@ function resolveLogLevel(flagLevel, env) {
69964
70052
  // package.json
69965
70053
  var package_default3 = {
69966
70054
  name: "@warmhub/cli",
69967
- version: "0.134.0",
70055
+ version: "0.135.0",
69968
70056
  private: false,
69969
70057
  type: "module",
69970
70058
  description: "The wh CLI for WarmHub — create repos, commit and query data, and compound knowledge with your AI agents.",
@@ -70589,5 +70677,5 @@ process.exitCode = interceptedExitCode === undefined ? await runPreparedCli(laun
70589
70677
  version: package_default3.version
70590
70678
  }) : interceptedExitCode;
70591
70679
 
70592
- //# debugId=59E58BA2C90F5E3C64756E2164756E21
70593
- //# warmhub-cli-build-info {"cliVersion":"0.134.0","sdkVersion":"0.132.0"}
70680
+ //# debugId=BE49CDDCED2454CC64756E2164756E21
70681
+ //# warmhub-cli-build-info {"cliVersion":"0.135.0","sdkVersion":"0.133.0"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@warmhub/cli",
3
- "version": "0.134.0",
3
+ "version": "0.135.0",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "description": "The wh CLI for WarmHub — create repos, commit and query data, and compound knowledge with your AI agents.",