@warmhub/cli 0.53.0 → 0.54.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 +319 -90
  2. package/package.json +1 -1
package/dist/wh.js CHANGED
@@ -21294,7 +21294,7 @@ function findSystemComponent(componentId) {
21294
21294
  // ../../packages/sdk-ts/package.json
21295
21295
  var package_default = {
21296
21296
  name: "@warmhub/sdk-ts",
21297
- version: "0.52.1",
21297
+ version: "0.53.0",
21298
21298
  private: false,
21299
21299
  type: "module",
21300
21300
  description: "The TypeScript SDK for WarmHub — create repos, commit and query data, and compound knowledge with your AI agents.",
@@ -22184,6 +22184,17 @@ class WarmHubClient {
22184
22184
  throw toWarmHubError(error);
22185
22185
  }
22186
22186
  },
22187
+ search: async (query, opts) => {
22188
+ try {
22189
+ return await this.trpc.component.search.query({
22190
+ query,
22191
+ limit: opts?.limit,
22192
+ cursor: opts?.cursor
22193
+ });
22194
+ } catch (error) {
22195
+ throw toWarmHubError(error);
22196
+ }
22197
+ },
22187
22198
  get: async (orgName, repoName, componentRef) => {
22188
22199
  try {
22189
22200
  return await this.trpc.component.get.query({
@@ -22519,6 +22530,17 @@ class WarmHubClient {
22519
22530
  throw toWarmHubError(error);
22520
22531
  }
22521
22532
  },
22533
+ search: async (query, opts) => {
22534
+ try {
22535
+ return await this.trpc.repo.search.query({
22536
+ query,
22537
+ limit: opts?.limit,
22538
+ cursor: opts?.cursor
22539
+ });
22540
+ } catch (error) {
22541
+ throw toWarmHubError(error);
22542
+ }
22543
+ },
22522
22544
  create: async (orgName, repoName, description, visibility, displayName) => {
22523
22545
  try {
22524
22546
  return await this.trpc.repo.create.mutate({
@@ -24705,37 +24727,65 @@ function makeStderrSink(minLevel) {
24705
24727
  function enforceLineCap(record) {
24706
24728
  const initial = `${JSON.stringify(record)}
24707
24729
  `;
24708
- if (initial.length <= LINE_CAP + 1)
24730
+ if (lineByteLength(initial) <= LINE_CAP + 1)
24709
24731
  return initial;
24710
24732
  const trimmed = { ...record };
24711
24733
  for (let pass = 0;pass < 8; pass++) {
24712
24734
  const candidate = `${JSON.stringify(trimmed)}
24713
24735
  `;
24714
- if (candidate.length <= LINE_CAP + 1)
24736
+ if (lineByteLength(candidate) <= LINE_CAP + 1)
24715
24737
  return candidate;
24716
24738
  let largestKey = null;
24717
24739
  let largestLen = 0;
24718
24740
  for (const [key, val] of Object.entries(trimmed)) {
24719
- if (typeof val === "string" && val.length > largestLen) {
24741
+ if (typeof val === "string") {
24742
+ const byteLen = lineByteLength(val);
24743
+ if (byteLen <= largestLen)
24744
+ continue;
24720
24745
  largestKey = key;
24721
- largestLen = val.length;
24746
+ largestLen = byteLen;
24722
24747
  }
24723
24748
  }
24724
24749
  if (largestKey === null)
24725
24750
  break;
24726
- const overage = candidate.length - LINE_CAP - 1;
24751
+ const overage = lineByteLength(candidate) - LINE_CAP - 1;
24727
24752
  const current = trimmed[largestKey];
24728
- const allowed = Math.max(0, current.length - overage - TRUNCATED_MARKER.length);
24729
- trimmed[largestKey] = `${current.slice(0, allowed)}${TRUNCATED_MARKER}`;
24753
+ const allowedBytes = Math.max(0, lineByteLength(current) - overage - lineByteLength(TRUNCATED_MARKER));
24754
+ trimmed[largestKey] = `${sliceUtf8Bytes(current, allowedBytes)}${TRUNCATED_MARKER}`;
24730
24755
  }
24731
- return `${JSON.stringify({
24756
+ const fallback = {
24732
24757
  v: trimmed.v,
24733
24758
  ts: trimmed.ts,
24734
24759
  level: trimmed.level,
24735
24760
  msg: trimmed.msg,
24736
24761
  truncated: TRUNCATED_MARKER
24737
- })}
24762
+ };
24763
+ let line = `${JSON.stringify(fallback)}
24764
+ `;
24765
+ if (lineByteLength(line) <= LINE_CAP + 1)
24766
+ return line;
24767
+ const emptyMsgLine = `${JSON.stringify({ ...fallback, msg: "" })}
24738
24768
  `;
24769
+ const msgBudget = Math.max(0, LINE_CAP + 1 - lineByteLength(emptyMsgLine));
24770
+ fallback.msg = sliceUtf8Bytes(fallback.msg, msgBudget);
24771
+ line = `${JSON.stringify(fallback)}
24772
+ `;
24773
+ return line;
24774
+ }
24775
+ function lineByteLength(value) {
24776
+ return Buffer.byteLength(value, "utf8");
24777
+ }
24778
+ function sliceUtf8Bytes(value, maxBytes) {
24779
+ let bytes = 0;
24780
+ let result = "";
24781
+ for (const char of value) {
24782
+ const charBytes = lineByteLength(char);
24783
+ if (bytes + charBytes > maxBytes)
24784
+ break;
24785
+ result += char;
24786
+ bytes += charBytes;
24787
+ }
24788
+ return result;
24739
24789
  }
24740
24790
  function rotateIfNeeded(path, dir) {
24741
24791
  if (!existsSync(path))
@@ -25410,10 +25460,11 @@ async function getValidToken(profile) {
25410
25460
  });
25411
25461
  await delay(1000);
25412
25462
  log.info("auth.refresh.retry", { profile: profileName, attempt: 2 });
25463
+ let retryStarted = Date.now();
25413
25464
  try {
25414
25465
  const retryProf = getProfile(profileName, authPath);
25415
25466
  const retryTokens = retryProf?.tokens ?? lockedTokens;
25416
- const retryStarted = Date.now();
25467
+ retryStarted = Date.now();
25417
25468
  const refreshed = await refreshAccessToken(retryTokens);
25418
25469
  saveProfileWhileLocked(profileName, { ...retryProf ?? lockedProf, tokens: refreshed }, authPath);
25419
25470
  log.info("auth.refresh.ok", {
@@ -25428,7 +25479,7 @@ async function getValidToken(profile) {
25428
25479
  const fields = {
25429
25480
  profile: profileName,
25430
25481
  classification,
25431
- duration_ms: Date.now() - refreshStarted,
25482
+ duration_ms: Date.now() - retryStarted,
25432
25483
  error_name: retryErr instanceof Error ? retryErr.name : "Unknown",
25433
25484
  on_retry: true
25434
25485
  };
@@ -26172,9 +26223,34 @@ function writeOutput(ctx, data, prettyFn) {
26172
26223
  }
26173
26224
  prettyFn();
26174
26225
  }
26175
- function emitPartialPageHint(ctx, count, nextCursor, limit) {
26226
+ function pageEnvelope(items, opts) {
26227
+ const nextCursor = opts.nextCursor ?? null;
26228
+ return {
26229
+ items,
26230
+ page: {
26231
+ limit: opts.limit,
26232
+ count: items.length,
26233
+ hasMore: nextCursor !== null,
26234
+ nextCursor
26235
+ }
26236
+ };
26237
+ }
26238
+ function writePageOutput(ctx, items, opts, prettyFn) {
26239
+ if (ctx.format === "json") {
26240
+ printJson(ctx.out, pageEnvelope(items, opts));
26241
+ return;
26242
+ }
26243
+ if (ctx.format === "jsonl") {
26244
+ printJsonl(ctx.out, items);
26245
+ return;
26246
+ }
26247
+ prettyFn();
26248
+ }
26249
+ function emitPartialPageHint(ctx, count, _nextCursor, _limit) {
26250
+ if (ctx.format === "json" || ctx.format === "jsonl")
26251
+ return;
26176
26252
  const c = ctx.colors;
26177
- ctx.status(`${c.yellow}${count} shown, more available${c.reset} use ${c.cyan}--all${c.reset} to fetch every page, ` + `or re-run the same command plus ${c.cyan}--limit=${limit} --cursor=${nextCursor}${c.reset} to resume from here.`);
26253
+ ctx.status(`${c.yellow}${count} shown; more available${c.reset}. Use ${c.cyan}--all${c.reset} to fetch every page.`);
26178
26254
  }
26179
26255
 
26180
26256
  // ../../packages/warmhub-cli/src/domains/thing/shared.ts
@@ -26250,7 +26326,7 @@ var handleAbout = async (ctx, { flags, args }) => {
26250
26326
  apiUrl: ctx.config.apiUrl,
26251
26327
  poll: (c) => c.thing.about(org, repo, wref, aboutOpts),
26252
26328
  render: (r) => {
26253
- renderAboutResult(ctx.out, ctx.colors, r, wref, boundedLimit);
26329
+ renderAboutResult(ctx.out, ctx.colors, r, wref);
26254
26330
  },
26255
26331
  out: ctx.out,
26256
26332
  err: ctx.err,
@@ -26278,22 +26354,21 @@ var handleAbout = async (ctx, { flags, args }) => {
26278
26354
  cur = page.nextCursor;
26279
26355
  }
26280
26356
  const result2 = { target, assertions, nextCursor: undefined };
26281
- writeOutput(ctx, result2, () => renderAboutResult(ctx.out, ctx.colors, result2, wref, boundedLimit));
26357
+ writePageOutput(ctx, assertions, { limit: pageLimit, nextCursor: null }, () => renderAboutResult(ctx.out, ctx.colors, result2, wref));
26282
26358
  return;
26283
26359
  }
26284
26360
  const result = await fetchPage(cursor);
26285
26361
  if (result.nextCursor) {
26286
26362
  emitPartialPageHint(ctx, result.assertions.length, result.nextCursor, boundedLimit);
26287
26363
  }
26288
- writeOutput(ctx, result, () => renderAboutResult(ctx.out, ctx.colors, result, wref, boundedLimit));
26364
+ writePageOutput(ctx, result.assertions, { limit: boundedLimit, nextCursor: result.nextCursor ?? null }, () => renderAboutResult(ctx.out, ctx.colors, result, wref));
26289
26365
  };
26290
- function renderAboutResult(out, c, result, wref, limit) {
26291
- const resumeHint = `${c.dim}Next: --limit=${limit} --cursor=${result.nextCursor}${c.reset}`;
26366
+ function renderAboutResult(out, c, result, wref) {
26292
26367
  out(`${c.bold}Assertions about${c.reset} ${pinnedWref(c, wref)} (${result.assertions.length}${result.nextCursor ? "+" : ""})`);
26293
26368
  if (result.assertions.length === 0) {
26294
26369
  out(` ${c.dim}(no assertions found)${c.reset}`);
26295
26370
  if (result.nextCursor) {
26296
- out(resumeHint);
26371
+ out(`${c.dim}More available. Use --all to fetch every page.${c.reset}`);
26297
26372
  }
26298
26373
  return;
26299
26374
  }
@@ -26301,7 +26376,7 @@ function renderAboutResult(out, c, result, wref, limit) {
26301
26376
  renderAboutAssertion(out, c, a, " ");
26302
26377
  }
26303
26378
  if (result.nextCursor) {
26304
- out(resumeHint);
26379
+ out(`${c.dim}More available. Use --all to fetch every page.${c.reset}`);
26305
26380
  }
26306
26381
  }
26307
26382
  function renderAboutAssertion(out, c, assertion, indent) {
@@ -26714,7 +26789,10 @@ var handleHistory = async (ctx, { flags, args }) => {
26714
26789
  if (!all && result.nextCursor) {
26715
26790
  emitPartialPageHint(ctx, (result.versions ?? []).length, result.nextCursor, boundedLimit);
26716
26791
  }
26717
- writeOutput(ctx, result, () => renderHistory(ctx.out, ctx.colors, result));
26792
+ writePageOutput(ctx, result.versions ?? [], {
26793
+ limit: all ? pageLimit : boundedLimit,
26794
+ nextCursor: result.nextCursor ?? null
26795
+ }, () => renderHistory(ctx.out, ctx.colors, result));
26718
26796
  };
26719
26797
  async function fetchAllHistoryPages(ctx, org, repo, opts) {
26720
26798
  const versions = [];
@@ -26989,7 +27067,10 @@ var handleHead = async (ctx, { flags, args }) => {
26989
27067
  if (!all && result.nextCursor) {
26990
27068
  emitPartialPageHint(ctx, (result.items ?? []).length, result.nextCursor, boundedLimit);
26991
27069
  }
26992
- writeOutput(ctx, result, () => renderHead(ctx.out, ctx.colors, ctx.chars, result, org, repo, shape, kind));
27070
+ writePageOutput(ctx, result.items ?? [], {
27071
+ limit: all ? pageLimit : boundedLimit,
27072
+ nextCursor: result.nextCursor ?? null
27073
+ }, () => renderHead(ctx.out, ctx.colors, ctx.chars, result, org, repo, shape, kind));
26993
27074
  };
26994
27075
  async function fetchAllHeadPages(ctx, org, repo, opts) {
26995
27076
  const items = [];
@@ -27154,7 +27235,10 @@ var handleQuery = async (ctx, { flags }) => {
27154
27235
  if (!all && result.nextCursor) {
27155
27236
  emitPartialPageHint(ctx, (result.items ?? []).length, result.nextCursor, boundedLimit);
27156
27237
  }
27157
- writeOutput(ctx, result, () => renderQueryResults(ctx.out, c, result));
27238
+ writePageOutput(ctx, result.items ?? [], {
27239
+ limit: all ? pageLimit : boundedLimit,
27240
+ nextCursor: result.nextCursor ?? null
27241
+ }, () => renderQueryResults(ctx.out, c, result));
27158
27242
  };
27159
27243
  async function fetchAllQueryPages(ctx, org, repo, opts) {
27160
27244
  const items = [];
@@ -27260,7 +27344,7 @@ var handleRefs = async (ctx, { flags, args }) => {
27260
27344
  cur = page.nextCursor;
27261
27345
  }
27262
27346
  const result2 = { items, nextCursor: undefined };
27263
- writeOutput(ctx, result2, () => renderRefs(ctx.out, ctx.colors, result2, wref, direction));
27347
+ writePageOutput(ctx, items, { limit: pageLimit, nextCursor: null }, () => renderRefs(ctx.out, ctx.colors, result2, wref, direction));
27264
27348
  maybeEmitAboutHint(ctx, direction, items.length, refsQueryIsNarrowed);
27265
27349
  return;
27266
27350
  }
@@ -27268,7 +27352,7 @@ var handleRefs = async (ctx, { flags, args }) => {
27268
27352
  if (result.nextCursor) {
27269
27353
  emitPartialPageHint(ctx, (result.items ?? []).length, result.nextCursor, boundedLimit);
27270
27354
  }
27271
- writeOutput(ctx, result, () => renderRefs(ctx.out, ctx.colors, result, wref, direction));
27355
+ writePageOutput(ctx, result.items ?? [], { limit: boundedLimit, nextCursor: result.nextCursor ?? null }, () => renderRefs(ctx.out, ctx.colors, result, wref, direction));
27272
27356
  maybeEmitAboutHint(ctx, direction, result.items?.length ?? 0, refsQueryIsNarrowed);
27273
27357
  };
27274
27358
  function maybeEmitAboutHint(ctx, direction, itemCount, refsQueryIsNarrowed) {
@@ -27521,7 +27605,10 @@ var handleSearch = async (ctx, { flags, args }) => {
27521
27605
  if (!all && result.nextCursor) {
27522
27606
  emitPartialPageHint(ctx, result.items.length, result.nextCursor, boundedTextLimit);
27523
27607
  }
27524
- writeOutput(ctx, result, () => renderQueryResults(ctx.out, c, result));
27608
+ writePageOutput(ctx, result.items, {
27609
+ limit: all ? pageLimit : boundedTextLimit,
27610
+ nextCursor: result.nextCursor ?? null
27611
+ }, () => renderQueryResults(ctx.out, c, result));
27525
27612
  };
27526
27613
  async function fetchAllSearchPages(ctx, org, repo, queryText, opts) {
27527
27614
  const items = [];
@@ -28206,7 +28293,10 @@ var handleHistory2 = async (ctx, { flags, args }) => {
28206
28293
  versions,
28207
28294
  nextCursor: flags.all ? undefined : nextCursor
28208
28295
  };
28209
- writeOutput(ctx, result, () => renderHistory(ctx.out, ctx.colors, result));
28296
+ if (!flags.all && result.nextCursor) {
28297
+ emitPartialPageHint(ctx, result.versions.length, result.nextCursor, limit);
28298
+ }
28299
+ writePageOutput(ctx, result.versions, { limit, nextCursor: result.nextCursor ?? null }, () => renderHistory(ctx.out, ctx.colors, result));
28210
28300
  };
28211
28301
  var handleCreate2 = async (ctx, { flags, args }) => {
28212
28302
  const { org, repo } = parseOrgRepo(getRepoRef(ctx) ?? args[0], ctx.config);
@@ -28336,7 +28426,10 @@ var handleList = async (ctx, { flags, args }) => {
28336
28426
  if (!all && result2.nextCursor) {
28337
28427
  emitPartialPageHint(ctx, (result2.items ?? []).length, result2.nextCursor, boundedLimit);
28338
28428
  }
28339
- writeOutput(ctx, result2, () => renderHead(ctx.out, ctx.colors, ctx.chars, result2, org, repo, shape, "assertion"));
28429
+ writePageOutput(ctx, result2.items ?? [], {
28430
+ limit: all ? pageLimit : boundedLimit,
28431
+ nextCursor: result2.nextCursor ?? null
28432
+ }, () => renderHead(ctx.out, ctx.colors, ctx.chars, result2, org, repo, shape, "assertion"));
28340
28433
  return;
28341
28434
  }
28342
28435
  const aboutOpts = {
@@ -28388,7 +28481,10 @@ var handleList = async (ctx, { flags, args }) => {
28388
28481
  if (!all && result.nextCursor) {
28389
28482
  emitPartialPageHint(ctx, (result.assertions ?? []).length, result.nextCursor, boundedLimit);
28390
28483
  }
28391
- writeOutput(ctx, result, () => renderAbout(ctx.out, ctx.colors, result));
28484
+ writePageOutput(ctx, result.assertions ?? [], {
28485
+ limit: all ? pageLimit : boundedLimit,
28486
+ nextCursor: result.nextCursor ?? null
28487
+ }, () => renderAbout(ctx.out, ctx.colors, result));
28392
28488
  };
28393
28489
  async function fetchAllAssertionAboutPages(ctx, org, repo, wref, opts) {
28394
28490
  const assertions = [];
@@ -31481,6 +31577,40 @@ function formatReservedNameWarning(name) {
31481
31577
  return `warning: component name "${name}" shadows the builtin \`wh ${name}\` domain. Operators will need to invoke methods via \`wh component exec ${name} <method>\` — the shorthand \`wh ${name} <method>\` will route to the builtin instead.`;
31482
31578
  }
31483
31579
 
31580
+ // ../../packages/warmhub-cli/src/global-search-command.ts
31581
+ var DEFAULT_LIMIT = 25;
31582
+ async function runGlobalSearchCommand(ctx, args) {
31583
+ const c = ctx.colors;
31584
+ const first = await args.fetch({ limit: args.limit, cursor: args.cursor });
31585
+ const items = [...first.items];
31586
+ let nextCursor = first.nextCursor;
31587
+ if (args.all) {
31588
+ while (nextCursor) {
31589
+ const page = await args.fetch({ limit: args.limit, cursor: nextCursor });
31590
+ items.push(...page.items);
31591
+ nextCursor = page.nextCursor;
31592
+ }
31593
+ }
31594
+ if (!args.all && nextCursor) {
31595
+ emitPartialPageHint(ctx, items.length, nextCursor, args.limit ?? DEFAULT_LIMIT);
31596
+ }
31597
+ writePageOutput(ctx, items, {
31598
+ limit: args.limit ?? DEFAULT_LIMIT,
31599
+ nextCursor: args.all ? null : nextCursor ?? null
31600
+ }, () => {
31601
+ if (items.length === 0) {
31602
+ ctx.status(`${c.dim}No ${args.emptyLabel} matching "${args.query}"${c.reset}`);
31603
+ return;
31604
+ }
31605
+ ctx.out(`${c.bold}${args.title}${c.reset} ${c.dim}"${args.query}"${c.reset}`);
31606
+ ctx.out("");
31607
+ for (const item of items) {
31608
+ const desc = item.description ? ` ${c.dim}${item.description}${c.reset}` : "";
31609
+ ctx.out(` ${c.cyan}${item.orgName}/${item.name}${c.reset}${desc}`);
31610
+ }
31611
+ });
31612
+ }
31613
+
31484
31614
  // ../../packages/warmhub-cli/src/manifest/name-resolution.ts
31485
31615
  function resolveManifestCredentialName(name, ctx) {
31486
31616
  return resolveComponentTemplate(name, {
@@ -32025,6 +32155,12 @@ function resolveMintedTokensFlag(args) {
32025
32155
  return false;
32026
32156
  return;
32027
32157
  }
32158
+ var showSecretsFlag = flag.boolean({
32159
+ description: "Reveal raw lifecycle URLs in command output"
32160
+ });
32161
+ var showSecretsStructuredOutputFlag = flag.boolean({
32162
+ description: "Reveal raw lifecycle URLs in JSON/JSONL output"
32163
+ });
32028
32164
  var installFlags = {};
32029
32165
  var updateFlags = {};
32030
32166
  var validateFlags = {};
@@ -32037,13 +32173,15 @@ var listFlags2 = {
32037
32173
  description: "Fetch all pages (auto-paginate until exhausted)"
32038
32174
  })
32039
32175
  };
32176
+ var DEFAULT_COMPONENT_LIST_LIMIT = 50;
32177
+ var MAX_COMPONENT_LIST_LIMIT = 500;
32040
32178
  var viewFlags3 = {};
32041
32179
  var teardownFlags = {};
32042
32180
  var doctorFlags = {};
32043
32181
  var initFlags = {};
32044
32182
  var searchFlags2 = {
32045
32183
  limit: flag.number({
32046
- description: "Maximum components per page (default: 50, max: 500)"
32184
+ description: "Maximum results per page"
32047
32185
  }),
32048
32186
  cursor: flag.string({ description: "Opaque pagination cursor" }),
32049
32187
  all: flag.boolean({
@@ -32089,7 +32227,8 @@ var registerFlags = {
32089
32227
  }),
32090
32228
  "no-minted-tokens": flag.boolean({
32091
32229
  description: "Disable minted tokens (default)"
32092
- })
32230
+ }),
32231
+ "show-secrets": showSecretsFlag
32093
32232
  };
32094
32233
  function readManifestArg(path2) {
32095
32234
  let raw;
@@ -32113,9 +32252,12 @@ var unregisterFlags = {};
32113
32252
  var registryListFlags = {
32114
32253
  org: flag.string({
32115
32254
  description: "Owner org to list registrations for"
32116
- })
32255
+ }),
32256
+ "show-secrets": showSecretsStructuredOutputFlag
32257
+ };
32258
+ var registryViewFlags = {
32259
+ "show-secrets": showSecretsFlag
32117
32260
  };
32118
- var registryViewFlags = {};
32119
32261
  var registryUpdateFlags = {
32120
32262
  manifest: flag.string({
32121
32263
  description: "Path to a manifest.json to publish as a new version (optional; must have a strictly-greater semver)"
@@ -32154,7 +32296,8 @@ var registryUpdateFlags = {
32154
32296
  }),
32155
32297
  "no-minted-tokens": flag.boolean({
32156
32298
  description: "Disable minted tokens"
32157
- })
32299
+ }),
32300
+ "show-secrets": showSecretsFlag
32158
32301
  };
32159
32302
  function asRecord(value) {
32160
32303
  if (!value || typeof value !== "object" || Array.isArray(value)) {
@@ -32248,7 +32391,8 @@ var handleRegister = async (ctx, { flags, args }) => {
32248
32391
  if (reservedWarning) {
32249
32392
  ctx.err(reservedWarning);
32250
32393
  }
32251
- writeOutput(ctx, result, () => renderRegistryEntry(ctx, result));
32394
+ const output = redactRegistryEntryLifecycleUrls(result, flags["show-secrets"]);
32395
+ writeOutput(ctx, output, () => renderRegistryEntry(ctx, output));
32252
32396
  };
32253
32397
  var handleUnregister = async (ctx, { args }) => {
32254
32398
  const { orgName, componentName } = resolveRegisteredComponentRef(args[0], "Usage: wh component unregister <org/name>", "wh component unregister warmhub/veritas");
@@ -32263,12 +32407,14 @@ var handleRegistryList = async (ctx, { flags, args }) => {
32263
32407
  usageError("Usage: wh component registry list --org <org>", "wh component registry list --org warmhub");
32264
32408
  }
32265
32409
  const result = await ctx.client.component.registry.list(orgName);
32266
- writeOutput(ctx, result.items, () => renderRegistryList(ctx, orgName, result));
32410
+ const items = redactRegistryEntryListLifecycleUrls(result.items, flags["show-secrets"]);
32411
+ writePageOutput(ctx, items, { limit: items.length, nextCursor: null }, () => renderRegistryList(ctx, orgName, { ...result, items }));
32267
32412
  };
32268
- var handleRegistryView = async (ctx, { args }) => {
32413
+ var handleRegistryView = async (ctx, { flags, args }) => {
32269
32414
  const { orgName, componentName } = resolveRegisteredComponentRef(args[0], "Usage: wh component registry view <org/name>", "wh component registry view warmhub/veritas");
32270
32415
  const result = await ctx.client.component.registry.view(orgName, componentName);
32271
- writeOutput(ctx, result, () => renderRegistryEntry(ctx, result));
32416
+ const output = redactRegistryEntryLifecycleUrls(result, flags["show-secrets"]);
32417
+ writeOutput(ctx, output, () => renderRegistryEntry(ctx, output));
32272
32418
  };
32273
32419
  var handleRegistryUpdate = async (ctx, { flags, args }) => {
32274
32420
  const { orgName, componentName } = resolveRegisteredComponentRef(args[0], "Usage: wh component registry update <org/name> [flags]", "wh component registry update warmhub/veritas --public");
@@ -32296,9 +32442,10 @@ var handleRegistryUpdate = async (ctx, { flags, args }) => {
32296
32442
  description: flags.description,
32297
32443
  mintedTokens
32298
32444
  });
32299
- writeOutput(ctx, result, () => renderRegistryEntry(ctx, result));
32445
+ const output = redactRegistryEntryLifecycleUrls(result, flags["show-secrets"]);
32446
+ writeOutput(ctx, output, () => renderRegistryEntry(ctx, output));
32300
32447
  };
32301
- var handleInstall = async (ctx, { args }) => {
32448
+ var handleInstall = async (_ctx, { args }) => {
32302
32449
  const source = args[0];
32303
32450
  const usage = "Usage: wh component install <org/name> --repo org/repo";
32304
32451
  const example = "wh component install warmhub/veritas --repo myorg/myrepo";
@@ -32331,9 +32478,12 @@ var handleList2 = async (ctx, { flags }) => {
32331
32478
  const c = ctx.colors;
32332
32479
  const { items, nextCursor } = await fetchComponentPages(ctx.client, org, repo, { all: flags.all, limit: flags.limit, cursor: flags.cursor });
32333
32480
  if (!flags.all && nextCursor) {
32334
- ctx.status(`${c.yellow}${items.length} shown, more available${c.reset} — use ${c.cyan}--all${c.reset} to fetch every page, ` + `or re-run the same command plus ${c.cyan}--cursor=${nextCursor}${c.reset} to resume from here.`);
32481
+ emitPartialPageHint(ctx, items.length, nextCursor, Math.min(flags.limit ?? DEFAULT_COMPONENT_LIST_LIMIT, MAX_COMPONENT_LIST_LIMIT));
32335
32482
  }
32336
- writeOutput(ctx, items, () => {
32483
+ writePageOutput(ctx, items, {
32484
+ limit: Math.min(flags.limit ?? DEFAULT_COMPONENT_LIST_LIMIT, MAX_COMPONENT_LIST_LIMIT),
32485
+ nextCursor: flags.all ? null : nextCursor ?? null
32486
+ }, () => {
32337
32487
  if (!items.length) {
32338
32488
  ctx.status(`${c.dim}No components installed${c.reset}`);
32339
32489
  return;
@@ -32352,30 +32502,20 @@ var handleList2 = async (ctx, { flags }) => {
32352
32502
  var handleSearch2 = async (ctx, { flags, args }) => {
32353
32503
  const query = args[0]?.trim();
32354
32504
  if (!query) {
32355
- usageError("Usage: wh component search <query> --repo org/repo", "wh component search research --repo myorg/myrepo");
32505
+ usageError("Usage: wh component search <query>", 'wh component search "subjective logic"');
32356
32506
  }
32357
- const { org, repo } = parseOrgRepo(getRepoRef(ctx), ctx.config);
32358
- const c = ctx.colors;
32359
- const { items: allItems, nextCursor } = await fetchComponentPages(ctx.client, org, repo, { all: flags.all, limit: flags.limit, cursor: flags.cursor });
32360
- const needle = query.toLowerCase();
32361
- const items = allItems.filter((item) => [item.ref, item.componentName, item.source].filter((value) => typeof value === "string").some((value) => value.toLowerCase().includes(needle)));
32362
- if (!flags.all && nextCursor) {
32363
- ctx.status(`${c.yellow}${allItems.length} component(s) searched, more pages available${c.reset} — matches beyond this page were not searched. ` + `Use ${c.cyan}--all${c.reset} to search every page, ` + `or re-run the same command plus ${c.cyan}--cursor=${nextCursor}${c.reset} to continue from here.`);
32507
+ if (getRepoRef(ctx)) {
32508
+ const c = ctx.colors;
32509
+ ctx.status(`${c.dim}--repo is ignored: \`wh component search\` searches the cross-org registry. ` + `Use \`wh component list --repo <org/repo>\` to see installed components.${c.reset}`);
32364
32510
  }
32365
- writeOutput(ctx, items, () => {
32366
- if (!items.length) {
32367
- ctx.status(`${c.dim}No components matching "${query}" in ${org}/${repo}${c.reset}`);
32368
- return;
32369
- }
32370
- ctx.out(`${c.bold}Matching Components${c.reset} ${c.cyan}${org}/${repo}${c.reset}`);
32371
- ctx.out("");
32372
- for (const item of items) {
32373
- const version = item.version ?? "unknown";
32374
- const state = item.state ?? "unknown";
32375
- const source = item.source ?? "-";
32376
- const stateColor = stateToColor(c, state);
32377
- ctx.out(` ${c.cyan}${item.ref ?? item.componentName}${c.reset} ${stateColor}${state}${c.reset} ${c.dim}v${version}${c.reset} ${source}`);
32378
- }
32511
+ await runGlobalSearchCommand(ctx, {
32512
+ query,
32513
+ all: flags.all,
32514
+ limit: flags.limit,
32515
+ cursor: flags.cursor,
32516
+ fetch: (opts) => ctx.client.component.search(query, opts),
32517
+ title: "Component search",
32518
+ emptyLabel: "public components"
32379
32519
  });
32380
32520
  };
32381
32521
  var handleView3 = async (ctx, { args }) => {
@@ -32550,10 +32690,10 @@ function renderRegistryEntry(ctx, entry) {
32550
32690
  ctx.out(` Source: ${c.dim}(not installable — no source URL)${c.reset}`);
32551
32691
  }
32552
32692
  if (entry.setupUrl) {
32553
- ctx.out(` Setup: ${entry.setupUrl}`);
32693
+ ctx.out(` Setup: ${formatLifecycleUrl(entry.setupUrl, c)}`);
32554
32694
  }
32555
32695
  if (entry.uninstallUrl) {
32556
- ctx.out(` Uninstall: ${entry.uninstallUrl}`);
32696
+ ctx.out(` Uninstall: ${formatLifecycleUrl(entry.uninstallUrl, c)}`);
32557
32697
  }
32558
32698
  if (entry.credentialSetName || entry.credentialSetId) {
32559
32699
  ctx.out(` Credential set: ${entry.credentialSetName ?? entry.credentialSetId}`);
@@ -32563,6 +32703,43 @@ function renderRegistryEntry(ctx, entry) {
32563
32703
  }
32564
32704
  ctx.out(` ${c.dim}Updated: ${new Date(entry.updatedAt).toISOString().slice(0, 16)}${c.reset}`);
32565
32705
  }
32706
+ function redactRegistryEntryLifecycleUrls(entry, showSecrets) {
32707
+ if (showSecrets)
32708
+ return entry;
32709
+ return {
32710
+ ...entry,
32711
+ ...entry.setupUrl ? { setupUrl: redactSecretBearingUrl(entry.setupUrl) } : {},
32712
+ ...entry.uninstallUrl ? { uninstallUrl: redactSecretBearingUrl(entry.uninstallUrl) } : {}
32713
+ };
32714
+ }
32715
+ function redactRegistryEntryListLifecycleUrls(entries, showSecrets) {
32716
+ if (showSecrets)
32717
+ return entries;
32718
+ return entries.map((entry) => redactRegistryEntryLifecycleUrls(entry, showSecrets));
32719
+ }
32720
+ var REDACTED_LIFECYCLE_URL = "[redacted-url]";
32721
+ var REDACTED_LIFECYCLE_PATH_SUFFIX = "/***";
32722
+ function redactSecretBearingUrl(rawUrl) {
32723
+ try {
32724
+ const origin = new URL(rawUrl).origin;
32725
+ if (origin === "null") {
32726
+ return REDACTED_LIFECYCLE_URL;
32727
+ }
32728
+ return `${origin}${REDACTED_LIFECYCLE_PATH_SUFFIX}`;
32729
+ } catch {
32730
+ return REDACTED_LIFECYCLE_URL;
32731
+ }
32732
+ }
32733
+ function formatLifecycleUrl(url, colors) {
32734
+ if (url === REDACTED_LIFECYCLE_URL) {
32735
+ return `${colors.dim}${url}${colors.reset}`;
32736
+ }
32737
+ if (url.endsWith(REDACTED_LIFECYCLE_PATH_SUFFIX)) {
32738
+ const visiblePrefix = url.slice(0, -REDACTED_LIFECYCLE_PATH_SUFFIX.length);
32739
+ return `${visiblePrefix}${colors.dim}${REDACTED_LIFECYCLE_PATH_SUFFIX}${colors.reset}`;
32740
+ }
32741
+ return url;
32742
+ }
32566
32743
  function renderRegistryList(ctx, orgName, result) {
32567
32744
  const c = ctx.colors;
32568
32745
  if (!result.items.length) {
@@ -32686,10 +32863,13 @@ var COMPONENT_DOMAIN = defineDomain({
32686
32863
  handler: handleComponentExec
32687
32864
  },
32688
32865
  search: {
32689
- summary: "Search for components on GitHub",
32866
+ summary: "Search public components across all orgs (the registry). To list components installed in a repo, use `wh component list --repo`.",
32690
32867
  args: "<query>",
32691
32868
  flags: searchFlags2,
32692
- examples: ["wh component search research"],
32869
+ examples: [
32870
+ 'wh component search "subjective logic"',
32871
+ "wh component search reputation"
32872
+ ],
32693
32873
  handler: handleSearch2
32694
32874
  }
32695
32875
  },
@@ -32812,7 +32992,7 @@ var handleCreate3 = async (ctx, { flags, args }) => {
32812
32992
  var handleList3 = async (ctx, { flags }) => {
32813
32993
  const context = resolveCredentialContext({ ctx, orgFlag: flags.org });
32814
32994
  const items = await ctx.client.credential.listSets(context.org, context.repo);
32815
- writeOutput(ctx, items, () => {
32995
+ writePageOutput(ctx, items, { limit: items.length, nextCursor: null }, () => {
32816
32996
  const c = ctx.colors;
32817
32997
  if (!items.length) {
32818
32998
  ctx.status(`${c.dim}No credential sets in ${formatCredentialContextTarget(context)}${c.reset}`);
@@ -32963,7 +33143,7 @@ var handleAudit = async (ctx, { flags, args }) => {
32963
33143
  limit: flags.limit
32964
33144
  })
32965
33145
  });
32966
- writeOutput(ctx, entries, () => {
33146
+ writePageOutput(ctx, entries, { limit: flags.limit ?? entries.length, nextCursor: null }, () => {
32967
33147
  const c = ctx.colors;
32968
33148
  if (!entries.length) {
32969
33149
  ctx.status(`${c.dim}No audit entries for ${setName}${c.reset}`);
@@ -33372,7 +33552,7 @@ function comparePrereleaseIdentifiers2(a, b) {
33372
33552
  return -1;
33373
33553
  if (!aNum && bNum)
33374
33554
  return 1;
33375
- return a.localeCompare(b);
33555
+ return a < b ? -1 : a > b ? 1 : 0;
33376
33556
  }
33377
33557
  function compareVersions(candidate, current) {
33378
33558
  if (candidate.major !== current.major)
@@ -34035,7 +34215,7 @@ var handleNotifications = async (ctx, { flags }) => {
34035
34215
  since: parseSince(flags.since, usage, example),
34036
34216
  limit: flags.limit
34037
34217
  });
34038
- writeOutput(ctx, result, () => renderActionNotifications(ctx.out, ctx.status, ctx.colors, result));
34218
+ writePageOutput(ctx, result, { limit: flags.limit ?? result.length, nextCursor: null }, () => renderActionNotifications(ctx.out, ctx.status, ctx.colors, result));
34039
34219
  };
34040
34220
  var NOTIFICATIONS_DOMAIN = defineDomain({
34041
34221
  kind: "flat",
@@ -34108,7 +34288,7 @@ var handleList4 = async (ctx, { flags }) => {
34108
34288
  const result = await ctx.client.org.list({
34109
34289
  includeArchived: flags["include-archived"]
34110
34290
  });
34111
- writeOutput(ctx, result.items, () => {
34291
+ writePageOutput(ctx, result.items, { limit: result.items.length, nextCursor: null }, () => {
34112
34292
  if (!result.items.length) {
34113
34293
  ctx.status(`${c.dim}No organizations${c.reset}`);
34114
34294
  return;
@@ -34870,6 +35050,8 @@ var repoListFlags = {
34870
35050
  description: "Fetch all pages (auto-paginate until exhausted)"
34871
35051
  })
34872
35052
  };
35053
+ var DEFAULT_REPO_LIST_LIMIT = 50;
35054
+ var MAX_REPO_LIST_LIMIT = 200;
34873
35055
  var handleList5 = async (ctx, { flags, args }) => {
34874
35056
  const orgName = args[0] ?? ctx.config.defaultOrg;
34875
35057
  if (!orgName) {
@@ -34897,9 +35079,12 @@ var handleList5 = async (ctx, { flags, args }) => {
34897
35079
  }
34898
35080
  }
34899
35081
  if (!all && nextCursor) {
34900
- ctx.status(`${c.yellow}${items.length} shown, more available${c.reset} — use ${c.cyan}--all${c.reset} to fetch every page, ` + `or re-run the same command plus ${c.cyan}--cursor=${nextCursor}${c.reset} to resume from here.`);
35082
+ emitPartialPageHint(ctx, items.length, nextCursor, Math.min(flags.limit ?? DEFAULT_REPO_LIST_LIMIT, MAX_REPO_LIST_LIMIT));
34901
35083
  }
34902
- writeOutput(ctx, items, () => {
35084
+ writePageOutput(ctx, items, {
35085
+ limit: Math.min(flags.limit ?? DEFAULT_REPO_LIST_LIMIT, MAX_REPO_LIST_LIMIT),
35086
+ nextCursor: all ? null : nextCursor ?? null
35087
+ }, () => {
34903
35088
  if (!items.length) {
34904
35089
  ctx.status(`${c.dim}No repos in ${orgName}${c.reset}`);
34905
35090
  return;
@@ -35420,6 +35605,30 @@ var CONTENT_SUBDOMAIN = defineDomain({
35420
35605
  }
35421
35606
  }
35422
35607
  });
35608
+ var repoSearchFlags = {
35609
+ limit: flag.number({
35610
+ description: "Maximum results per page (default: 25, max: 100)"
35611
+ }),
35612
+ cursor: flag.string({ description: "Opaque pagination cursor" }),
35613
+ all: flag.boolean({
35614
+ description: "Fetch all pages (auto-paginate until exhausted)"
35615
+ })
35616
+ };
35617
+ var handleRepoSearch = async (ctx, { flags, args }) => {
35618
+ const query = args[0]?.trim();
35619
+ if (!query) {
35620
+ usageError("Usage: wh repo search <query>", 'wh repo search "payment processing"');
35621
+ }
35622
+ await runGlobalSearchCommand(ctx, {
35623
+ query,
35624
+ all: flags.all,
35625
+ limit: flags.limit,
35626
+ cursor: flags.cursor,
35627
+ fetch: (opts) => ctx.client.repo.search(query, opts),
35628
+ title: "Repo search",
35629
+ emptyLabel: "public repos"
35630
+ });
35631
+ };
35423
35632
  var REPO_DOMAIN = defineDomain({
35424
35633
  name: "repo",
35425
35634
  summary: "Repository management",
@@ -35450,6 +35659,14 @@ var REPO_DOMAIN = defineDomain({
35450
35659
  ],
35451
35660
  handler: handleList5
35452
35661
  },
35662
+ search: {
35663
+ prime: true,
35664
+ summary: "Search public repos across all orgs",
35665
+ args: "<query>",
35666
+ flags: repoSearchFlags,
35667
+ examples: ["wh repo search users", "wh repo search users --limit 10"],
35668
+ handler: handleRepoSearch
35669
+ },
35453
35670
  view: {
35454
35671
  prime: true,
35455
35672
  summary: "Show repo details",
@@ -35576,7 +35793,7 @@ var handleList6 = async (ctx, { flags }) => {
35576
35793
  includeRetracted
35577
35794
  });
35578
35795
  const items = result.items;
35579
- writeOutput(ctx, items, () => {
35796
+ writePageOutput(ctx, items, { limit: items.length, nextCursor: null }, () => {
35580
35797
  if (!items.length) {
35581
35798
  ctx.status(`${c.dim}No shapes registered${c.reset}`);
35582
35799
  return;
@@ -35813,7 +36030,7 @@ var handleHistory3 = async (ctx, { flags, args }) => {
35813
36030
  if (!all && result.nextCursor) {
35814
36031
  emitPartialPageHint(ctx, (result.versions ?? []).length, result.nextCursor, pageLimit);
35815
36032
  }
35816
- writeOutput(ctx, result, () => renderHistory(ctx.out, ctx.colors, result));
36033
+ writePageOutput(ctx, result.versions ?? [], { limit: pageLimit, nextCursor: result.nextCursor ?? null }, () => renderHistory(ctx.out, ctx.colors, result));
35817
36034
  };
35818
36035
  var handleShapeRename = async (ctx, { args }) => {
35819
36036
  const oldName = args[0];
@@ -36255,7 +36472,7 @@ var handleList7 = async (ctx, { flags }) => {
36255
36472
  const { org, repo } = resolveRepoContext(ctx);
36256
36473
  const all = await ctx.client.subscription.list(org, repo);
36257
36474
  const items = all.slice(0, flags.limit ?? all.length);
36258
- writeOutput(ctx, items, () => {
36475
+ writePageOutput(ctx, items, { limit: flags.limit ?? all.length, nextCursor: null }, () => {
36259
36476
  const c = ctx.colors;
36260
36477
  if (!items.length) {
36261
36478
  ctx.status(`${c.dim}No subscriptions in ${org}/${repo}${c.reset}`);
@@ -36722,7 +36939,7 @@ var handleCreate8 = async (ctx, { flags }) => {
36722
36939
  var handleList8 = async (ctx, { flags }) => {
36723
36940
  const c = ctx.colors;
36724
36941
  const items = await ctx.client.token.list({ includeInactive: flags.all });
36725
- writeOutput(ctx, items, () => {
36942
+ writePageOutput(ctx, items, { limit: items.length, nextCursor: null }, () => {
36726
36943
  if (!items.length) {
36727
36944
  ctx.status(`${c.dim}No tokens${c.reset}`);
36728
36945
  return;
@@ -38960,14 +39177,16 @@ async function runCli(argv, opts) {
38960
39177
  teeStderr: debugMode,
38961
39178
  whVersion: version
38962
39179
  });
38963
- process.once("uncaughtException", (e) => {
39180
+ const handleUncaughtException = (e) => {
38964
39181
  logger.crash(e, "uncaughtException");
38965
39182
  process.exit(1);
38966
- });
38967
- process.once("unhandledRejection", (reason) => {
39183
+ };
39184
+ const handleUnhandledRejection = (reason) => {
38968
39185
  logger.crash(reason, "unhandledRejection");
38969
39186
  process.exit(1);
38970
- });
39187
+ };
39188
+ process.once("uncaughtException", handleUncaughtException);
39189
+ process.once("unhandledRejection", handleUnhandledRejection);
38971
39190
  logger.info("cli.start", {
38972
39191
  argv: redactArgv(argv),
38973
39192
  version,
@@ -38977,6 +39196,7 @@ async function runCli(argv, opts) {
38977
39196
  profile: getStringFlag(invocation.flags, "profile", "P") ?? undefined
38978
39197
  });
38979
39198
  let exitCode = 0 /* Ok */;
39199
+ let removeSignalListeners;
38980
39200
  try {
38981
39201
  canonicalizeGlobalFlags({ invocation });
38982
39202
  const retirementHint = lookupInvocationRenameHint(invocation);
@@ -39029,17 +39249,23 @@ async function runCli(argv, opts) {
39029
39249
  const chars = makeChars();
39030
39250
  const ac = new AbortController;
39031
39251
  const liveMode = getBoolFlag(invocation.flags, "live");
39032
- process.on("SIGINT", () => {
39252
+ const handleSigint = () => {
39033
39253
  ac.abort();
39034
39254
  logger.info("cli.cancelled", { signal: "SIGINT" });
39035
39255
  if (!liveMode)
39036
39256
  process.exitCode = 130 /* Cancelled */;
39037
- });
39038
- process.on("SIGTERM", () => {
39257
+ };
39258
+ const handleSigterm = () => {
39039
39259
  ac.abort();
39040
39260
  logger.info("cli.cancelled", { signal: "SIGTERM" });
39041
39261
  process.exitCode = 143;
39042
- });
39262
+ };
39263
+ process.on("SIGINT", handleSigint);
39264
+ process.on("SIGTERM", handleSigterm);
39265
+ removeSignalListeners = () => {
39266
+ process.removeListener("SIGINT", handleSigint);
39267
+ process.removeListener("SIGTERM", handleSigterm);
39268
+ };
39043
39269
  await dispatch({
39044
39270
  client,
39045
39271
  config,
@@ -39098,6 +39324,9 @@ async function runCli(argv, opts) {
39098
39324
  });
39099
39325
  return exitCode;
39100
39326
  } finally {
39327
+ process.removeListener("uncaughtException", handleUncaughtException);
39328
+ process.removeListener("unhandledRejection", handleUnhandledRejection);
39329
+ removeSignalListeners?.();
39101
39330
  logger.info("cli.end", {
39102
39331
  exit_code: exitCode,
39103
39332
  duration_ms: Date.now() - startedAt
@@ -39153,7 +39382,7 @@ function resolveLogLevel(flags, env) {
39153
39382
  // package.json
39154
39383
  var package_default3 = {
39155
39384
  name: "@warmhub/cli",
39156
- version: "0.53.0",
39385
+ version: "0.54.0",
39157
39386
  private: false,
39158
39387
  type: "module",
39159
39388
  description: "The wh CLI for WarmHub — create repos, commit and query data, and compound knowledge with your AI agents.",
@@ -39944,4 +40173,4 @@ if (!updateCheckSuppressedByArgv && shouldRunUpdateCheck(updateEligibility)) {
39944
40173
  var interceptedExitCode = await maybeHandleComponentShellBoundary(dispatchArgv);
39945
40174
  process.exitCode = interceptedExitCode === undefined ? await runCli(dispatchArgv, { version: package_default3.version }) : interceptedExitCode;
39946
40175
 
39947
- //# debugId=E69740B781D6D4C864756E2164756E21
40176
+ //# debugId=194B08F51AA9569F64756E2164756E21
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@warmhub/cli",
3
- "version": "0.53.0",
3
+ "version": "0.54.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.",