@warmhub/cli 0.112.0 → 0.113.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 +234 -145
  2. package/package.json +1 -1
package/dist/wh.js CHANGED
@@ -35958,8 +35958,7 @@ function isTypeSpecObject(value) {
35958
35958
  if ("pattern" in value && typeof value.pattern !== "string")
35959
35959
  return false;
35960
35960
  if ("pattern" in value && typeof value.pattern === "string" && VALID_PRIMITIVE_TYPES.has(value.pattern)) {
35961
- const baseType2 = typeof value.type === "string" && value.type.endsWith("?") ? value.type.slice(0, -1) : value.type;
35962
- if (baseType2 !== "string")
35961
+ if (baseType !== "string")
35963
35962
  return false;
35964
35963
  }
35965
35964
  if ("enum" in value && !Array.isArray(value.enum))
@@ -35973,8 +35972,7 @@ function isTypeSpecObject(value) {
35973
35972
  if ("shape" in value && typeof value.shape !== "string")
35974
35973
  return false;
35975
35974
  if ("shape" in value && typeof value.shape === "string" && VALID_PRIMITIVE_TYPES.has(value.shape)) {
35976
- const baseType2 = typeof value.type === "string" && value.type.endsWith("?") ? value.type.slice(0, -1) : value.type;
35977
- if (baseType2 !== "wref")
35975
+ if (baseType !== "wref")
35978
35976
  return false;
35979
35977
  }
35980
35978
  if ("items" in value && typeof value.items === "number")
@@ -36079,7 +36077,7 @@ function formatTypeSpecDisplay(spec) {
36079
36077
  } else if (key === "pattern" && typeof val === "string") {
36080
36078
  parts.push(`${key}: "${val}"`);
36081
36079
  } else {
36082
- parts.push(`${key}: ${val}`);
36080
+ parts.push(`${key}: ${String(val)}`);
36083
36081
  }
36084
36082
  }
36085
36083
  return `${baseType} (${parts.join(", ")})`;
@@ -44723,7 +44721,7 @@ var legacyErrorDetailsSchema = exports_external.discriminatedUnion("reason", [
44723
44721
  }),
44724
44722
  exports_external.object({
44725
44723
  reason: exports_external.literal("lease_held"),
44726
- leaseExpiresAt: exports_external.string().datetime()
44724
+ leaseExpiresAt: exports_external.iso.datetime()
44727
44725
  }),
44728
44726
  exports_external.object({
44729
44727
  reason: exports_external.literal("validation_failed"),
@@ -44732,7 +44730,7 @@ var legacyErrorDetailsSchema = exports_external.discriminatedUnion("reason", [
44732
44730
  exports_external.object({
44733
44731
  reason: exports_external.literal("rate_limit_reset"),
44734
44732
  retryAfterSeconds: exports_external.number().int().positive(),
44735
- resetAt: exports_external.string().datetime()
44733
+ resetAt: exports_external.iso.datetime()
44736
44734
  }),
44737
44735
  exports_external.object({
44738
44736
  reason: exports_external.literal("cursor_fence_unavailable"),
@@ -44748,7 +44746,7 @@ var currentErrorDetailsSchema = exports_external.discriminatedUnion("reason", [
44748
44746
  }).strict(),
44749
44747
  exports_external.object({
44750
44748
  reason: exports_external.literal("lease_held"),
44751
- leaseExpiresAt: exports_external.string().datetime()
44749
+ leaseExpiresAt: exports_external.iso.datetime()
44752
44750
  }).strict(),
44753
44751
  exports_external.object({
44754
44752
  reason: exports_external.literal("validation_failed"),
@@ -44757,7 +44755,7 @@ var currentErrorDetailsSchema = exports_external.discriminatedUnion("reason", [
44757
44755
  exports_external.object({
44758
44756
  reason: exports_external.literal("rate_limit_reset"),
44759
44757
  retryAfterSeconds: exports_external.number().nonnegative(),
44760
- resetAt: exports_external.string().datetime()
44758
+ resetAt: exports_external.iso.datetime()
44761
44759
  }).strict(),
44762
44760
  exports_external.object({
44763
44761
  reason: exports_external.literal("cursor_fence_unavailable"),
@@ -44778,7 +44776,7 @@ var currentBaseShape = {
44778
44776
  affirmations: affirmationSchema.optional()
44779
44777
  };
44780
44778
  var resultSchema = exports_external.union([
44781
- exports_external.object({
44779
+ exports_external.looseObject({
44782
44780
  ...positionShape,
44783
44781
  operation: legacyOperationSchema.optional(),
44784
44782
  version: exports_external.number().optional(),
@@ -44793,14 +44791,14 @@ var resultSchema = exports_external.union([
44793
44791
  retryable: exports_external.boolean().optional(),
44794
44792
  warnings: warningSchema,
44795
44793
  affirmations: affirmationSchema.optional()
44796
- }).passthrough(),
44797
- exports_external.object({
44794
+ }),
44795
+ exports_external.looseObject({
44798
44796
  ...currentBaseShape,
44799
44797
  status: exports_external.enum(["applied", "noop"]),
44800
44798
  version: exports_external.number().int().positive().optional(),
44801
44799
  dataHash: exports_external.string().min(1).optional()
44802
- }).passthrough(),
44803
- exports_external.object({
44800
+ }),
44801
+ exports_external.looseObject({
44804
44802
  ...currentBaseShape,
44805
44803
  status: exports_external.literal("error"),
44806
44804
  errors: exports_external.array(exports_external.object({
@@ -44810,26 +44808,26 @@ var resultSchema = exports_external.union([
44810
44808
  details: currentErrorDetailsSchema.optional(),
44811
44809
  retryable: exports_external.boolean().optional()
44812
44810
  }).strict()).min(1)
44813
- }).passthrough()
44811
+ })
44814
44812
  ]);
44815
44813
  var operationCountsSchema = exports_external.object({
44816
44814
  applied: exports_external.number().int().nonnegative(),
44817
44815
  noop: exports_external.number().int().nonnegative(),
44818
44816
  failed: exports_external.number().int().nonnegative()
44819
44817
  });
44820
- var groupSchema = exports_external.object({
44818
+ var groupSchema = exports_external.looseObject({
44821
44819
  type: exports_external.literal("group"),
44822
44820
  chunkOrdinal: exports_external.number().int().nonnegative(),
44823
- eventRequestId: exports_external.string().uuid(),
44821
+ eventRequestId: exports_external.uuid(),
44824
44822
  requestDigest: digestSchema,
44825
44823
  outcome: exports_external.enum(["event", "no_event"]),
44826
44824
  repoSeq: exports_external.number().int().nonnegative().optional(),
44827
44825
  operations: operationCountsSchema,
44828
44826
  manifestDigest: digestSchema
44829
- }).passthrough();
44830
- var summarySchema = exports_external.object({
44827
+ });
44828
+ var summarySchema = exports_external.looseObject({
44831
44829
  type: exports_external.literal("summary"),
44832
- submissionId: exports_external.string().uuid(),
44830
+ submissionId: exports_external.uuid(),
44833
44831
  streamId: exports_external.string().min(1),
44834
44832
  groupSize: exports_external.number().int().positive(),
44835
44833
  groups: exports_external.number().int().nonnegative(),
@@ -44850,12 +44848,12 @@ var summarySchema = exports_external.object({
44850
44848
  groups: exports_external.number().int().nonnegative(),
44851
44849
  digest: digestSchema
44852
44850
  })
44853
- }).passthrough();
44854
- var errorSchema = exports_external.object({
44851
+ });
44852
+ var errorSchema = exports_external.looseObject({
44855
44853
  type: exports_external.literal("error"),
44856
44854
  code: exports_external.string().min(1),
44857
44855
  message: exports_external.string().optional()
44858
- }).passthrough();
44856
+ });
44859
44857
  var rowSchema = exports_external.union([
44860
44858
  resultSchema,
44861
44859
  groupSchema,
@@ -44942,6 +44940,7 @@ class SequenceValidator {
44942
44940
  return this.acceptSummary(row, fail);
44943
44941
  }
44944
44942
  this.index += 1;
44943
+ return;
44945
44944
  }
44946
44945
  async acceptGroup(row, fail) {
44947
44946
  this.manifestDigest = this.manifestDigest.then((previous) => advanceManifest(previous, row.chunkOrdinal, row.requestDigest));
@@ -45054,10 +45053,11 @@ async function* readStreamingSubmissionRows(response, expectedIdentity) {
45054
45053
  if (terminalRow)
45055
45054
  yield terminalRow;
45056
45055
  } finally {
45057
- if (!finished)
45058
- await reader.cancel().catch(() => {
45059
- return;
45060
- });
45056
+ if (!finished) {
45057
+ try {
45058
+ await reader.cancel();
45059
+ } catch {}
45060
+ }
45061
45061
  reader.releaseLock();
45062
45062
  }
45063
45063
  }
@@ -45105,15 +45105,20 @@ function submissionPath(identity2) {
45105
45105
  function createRequestBody(source) {
45106
45106
  const iterator = createNormalizedOperationIterator(source, false);
45107
45107
  let closed = false;
45108
+ const observeSourceReturn = async (returned) => {
45109
+ try {
45110
+ await returned;
45111
+ } catch {}
45112
+ };
45108
45113
  const returnSourceOnce = () => {
45109
45114
  if (closed)
45110
45115
  return;
45111
45116
  closed = true;
45112
- const returned = iterator.returnSourceOnce();
45113
- if (returned)
45114
- Promise.resolve(returned).catch(() => {
45115
- return;
45116
- });
45117
+ try {
45118
+ const returned = iterator.returnSourceOnce();
45119
+ if (returned)
45120
+ observeSourceReturn(returned);
45121
+ } catch {}
45117
45122
  };
45118
45123
  const stream = new ReadableStream({
45119
45124
  async pull(controller) {
@@ -45246,7 +45251,7 @@ function createStreamingSubmissionHandle(input, deps) {
45246
45251
  // ../../packages/sdk-ts/package.json
45247
45252
  var package_default = {
45248
45253
  name: "@warmhub/sdk-ts",
45249
- version: "0.110.0",
45254
+ version: "0.111.0",
45250
45255
  private: false,
45251
45256
  type: "module",
45252
45257
  description: "The TypeScript SDK for WarmHub — create repos, commit and query data, and compound knowledge with your AI agents.",
@@ -48931,8 +48936,11 @@ function writeCrash(err, kind, crashDir, ring, dispatch, whVersion) {
48931
48936
  try {
48932
48937
  writeFileSync(filePath, JSON.stringify(record2, null, 2), { mode: 384 });
48933
48938
  result = { persisted: true, filePath };
48934
- } catch (err2) {
48935
- result = { persisted: false, errorCode: persistenceErrorCode(err2) };
48939
+ } catch (persistenceError) {
48940
+ result = {
48941
+ persisted: false,
48942
+ errorCode: persistenceErrorCode(persistenceError)
48943
+ };
48936
48944
  }
48937
48945
  const breadcrumb = {
48938
48946
  v: 1,
@@ -49517,6 +49525,8 @@ function accessTokenExpiry(accessToken) {
49517
49525
  }
49518
49526
 
49519
49527
  // ../../packages/warmhub-cli/src/auth-refresh.ts
49528
+ var WORKOS_REFRESH_TIMEOUT_MS = 30000;
49529
+
49520
49530
  class WorkOsAuthError extends Error {
49521
49531
  error;
49522
49532
  errorDescription;
@@ -49529,7 +49539,7 @@ class WorkOsAuthError extends Error {
49529
49539
  this.status = status;
49530
49540
  }
49531
49541
  }
49532
- async function refreshAccessToken(tokens) {
49542
+ async function refreshAccessToken(tokens, signal) {
49533
49543
  const log = getLog();
49534
49544
  const { clientId } = tokens;
49535
49545
  const workosUrl = "https://api.workos.com";
@@ -49542,6 +49552,7 @@ async function refreshAccessToken(tokens) {
49542
49552
  request_id: requestId
49543
49553
  });
49544
49554
  const startedAt = Date.now();
49555
+ const requestSignal = signal ?? AbortSignal.timeout(WORKOS_REFRESH_TIMEOUT_MS);
49545
49556
  let res;
49546
49557
  try {
49547
49558
  res = await fetch(`${workosUrl}${path}`, {
@@ -49551,7 +49562,8 @@ async function refreshAccessToken(tokens) {
49551
49562
  grant_type: "refresh_token",
49552
49563
  client_id: clientId,
49553
49564
  refresh_token: tokens.refreshToken
49554
- })
49565
+ }),
49566
+ signal: requestSignal
49555
49567
  });
49556
49568
  } catch (err) {
49557
49569
  log.info("http.error", {
@@ -50118,8 +50130,23 @@ function corruptedAuthError(path, cause) {
50118
50130
  function isAuthLockError(error51, authPath) {
50119
50131
  return error51 instanceof Error && error51.code === "ELOCKED" && (error51.file === undefined || error51.file === authPath);
50120
50132
  }
50121
- function delay2(ms) {
50122
- return new Promise((resolve) => setTimeout(resolve, ms));
50133
+ function abortError(signal) {
50134
+ return signal?.reason instanceof Error ? signal.reason : new DOMException("The operation was aborted", "AbortError");
50135
+ }
50136
+ function delay2(ms, signal) {
50137
+ if (signal?.aborted)
50138
+ return Promise.reject(abortError(signal));
50139
+ return new Promise((resolve, reject) => {
50140
+ const onAbort = () => {
50141
+ clearTimeout(timer);
50142
+ reject(abortError(signal));
50143
+ };
50144
+ const timer = setTimeout(() => {
50145
+ signal?.removeEventListener("abort", onAbort);
50146
+ resolve();
50147
+ }, ms);
50148
+ signal?.addEventListener("abort", onAbort, { once: true });
50149
+ });
50123
50150
  }
50124
50151
  function getTokenInfo(profile) {
50125
50152
  const envToken = process.env.WH_TOKEN;
@@ -50149,7 +50176,7 @@ function getTokenInfo(profile) {
50149
50176
  canRefresh: source === "device" && !!tokens.refreshToken
50150
50177
  };
50151
50178
  }
50152
- async function getValidToken(profile) {
50179
+ async function getValidToken(profile, signal) {
50153
50180
  const log = getLog();
50154
50181
  const envToken = process.env.WH_TOKEN;
50155
50182
  if (envToken) {
@@ -50213,7 +50240,7 @@ async function getValidToken(profile) {
50213
50240
  client_id: lockedTokens.clientId
50214
50241
  });
50215
50242
  try {
50216
- const refreshed = await refreshAccessToken(lockedTokens);
50243
+ const refreshed = await refreshAccessToken(lockedTokens, signal);
50217
50244
  saveProfileWhileLocked(profileName, { ...lockedProf, tokens: refreshed }, authPath);
50218
50245
  log.info("auth.refresh.ok", {
50219
50246
  profile: profileName,
@@ -50222,6 +50249,8 @@ async function getValidToken(profile) {
50222
50249
  });
50223
50250
  return refreshed.accessToken;
50224
50251
  } catch (err) {
50252
+ if (signal?.aborted)
50253
+ throw err;
50225
50254
  const isTransientHttp = err instanceof WorkOsAuthError && (err.status >= 500 || err.status === 429 || err.status === 408);
50226
50255
  if (err instanceof WorkOsAuthError && !isTransientHttp) {
50227
50256
  const classification = err.error === "invalid_grant" ? "invalid_grant" : "terminal";
@@ -50240,14 +50269,14 @@ async function getValidToken(profile) {
50240
50269
  duration_ms: Date.now() - refreshStarted,
50241
50270
  error_name: err instanceof Error ? err.name : "Unknown"
50242
50271
  });
50243
- await delay2(1000);
50272
+ await delay2(1000, signal);
50244
50273
  log.info("auth.refresh.retry", { profile: profileName, attempt: 2 });
50245
50274
  let retryStarted = Date.now();
50246
50275
  try {
50247
50276
  const retryProf = getProfile(profileName, authPath);
50248
50277
  const retryTokens = retryProf?.tokens ?? lockedTokens;
50249
50278
  retryStarted = Date.now();
50250
- const refreshed = await refreshAccessToken(retryTokens);
50279
+ const refreshed = await refreshAccessToken(retryTokens, signal);
50251
50280
  saveProfileWhileLocked(profileName, { ...retryProf ?? lockedProf, tokens: refreshed }, authPath);
50252
50281
  log.info("auth.refresh.ok", {
50253
50282
  profile: profileName,
@@ -50257,6 +50286,8 @@ async function getValidToken(profile) {
50257
50286
  });
50258
50287
  return refreshed.accessToken;
50259
50288
  } catch (retryErr) {
50289
+ if (signal?.aborted)
50290
+ throw retryErr;
50260
50291
  const isTerminal = retryErr instanceof WorkOsAuthError && !(retryErr.status >= 500 || retryErr.status === 429 || retryErr.status === 408);
50261
50292
  const classification = isTerminal ? "terminal" : "transient";
50262
50293
  const fields = {
@@ -50444,7 +50475,7 @@ function createClient(config2, opts = {}) {
50444
50475
  return new WarmHubClient({
50445
50476
  apiUrl: config2.apiUrl,
50446
50477
  auth: {
50447
- getToken: async () => await getValidToken(profile) ?? undefined
50478
+ getToken: async () => await getValidToken(profile, opts.signal) ?? undefined
50448
50479
  },
50449
50480
  fetch: createBenchmarkAwareFetch(benchmarkId, opts.signal),
50450
50481
  functionLogs: opts.functionLogs,
@@ -50479,16 +50510,16 @@ function pollUntilAbort(poll, signal) {
50479
50510
  resolve(result);
50480
50511
  }, (error51) => {
50481
50512
  signal.removeEventListener("abort", onAbort);
50482
- reject(error51);
50513
+ reject(error51 instanceof Error ? error51 : new Error("live poll failed", { cause: error51 }));
50483
50514
  });
50484
50515
  });
50485
50516
  }
50486
50517
  async function runLive(opts) {
50518
+ const controller = new AbortController;
50487
50519
  const auth = opts.auth ?? {
50488
- getToken: async () => await getValidToken(opts.profile) ?? undefined
50520
+ getToken: async () => await getValidToken(opts.profile, controller.signal) ?? undefined
50489
50521
  };
50490
50522
  const benchmarkId = process.env.WH_BENCHMARK_ID?.trim();
50491
- const controller = new AbortController;
50492
50523
  const client = new WarmHubClient({
50493
50524
  apiUrl: opts.apiUrl,
50494
50525
  auth,
@@ -50498,11 +50529,12 @@ async function runLive(opts) {
50498
50529
  clientFlags: opts.clientFlags,
50499
50530
  decorateResponses: opts.decorateResponses
50500
50531
  });
50532
+ const forwardAbort = () => controller.abort();
50501
50533
  if (opts.signal) {
50502
50534
  if (opts.signal.aborted)
50503
50535
  controller.abort();
50504
50536
  else
50505
- opts.signal.addEventListener("abort", () => controller.abort(), {
50537
+ opts.signal.addEventListener("abort", forwardAbort, {
50506
50538
  once: true
50507
50539
  });
50508
50540
  }
@@ -50524,7 +50556,7 @@ async function runLive(opts) {
50524
50556
  const poll = opts.poll(client, controller.signal);
50525
50557
  const result = await pollUntilAbort(poll, controller.signal);
50526
50558
  if (result === LIVE_ABORTED) {
50527
- poll.catch(() => {});
50559
+ observePollAfterAbort(poll);
50528
50560
  break;
50529
50561
  }
50530
50562
  updates += 1;
@@ -50549,12 +50581,18 @@ ${opts.colors.dim}[live • update #${updates} • Ctrl-C to stop]${opts.colors.
50549
50581
  }
50550
50582
  return { updates };
50551
50583
  } finally {
50584
+ opts.signal?.removeEventListener("abort", forwardAbort);
50552
50585
  if (startTimer)
50553
50586
  clearTimeout(startTimer);
50554
50587
  if (inactivityTimer)
50555
50588
  clearTimeout(inactivityTimer);
50556
50589
  }
50557
50590
  }
50591
+ async function observePollAfterAbort(poll) {
50592
+ try {
50593
+ await poll;
50594
+ } catch {}
50595
+ }
50558
50596
  function toCliError2(e) {
50559
50597
  return toCliError(e);
50560
50598
  }
@@ -51854,7 +51892,7 @@ function notYetImplemented(command) {
51854
51892
  }
51855
51893
  function levenshtein(a, b) {
51856
51894
  const m = a.length, n = b.length;
51857
- const dp = Array.from({ length: m + 1 }, (_, i) => Array.from({ length: n + 1 }, (_2, j) => i === 0 ? j : j === 0 ? i : 0));
51895
+ const dp = Array.from({ length: m + 1 }, (_row, i) => Array.from({ length: n + 1 }, (_cell, j) => i === 0 ? j : j === 0 ? i : 0));
51858
51896
  for (let i = 1;i <= m; i++) {
51859
51897
  const row = dp[i];
51860
51898
  const previousRow = dp[i - 1];
@@ -53978,9 +54016,9 @@ var handleResolve = async (ctx, { args }) => {
53978
54016
  const c = ctx.colors;
53979
54017
  const result = await ctx.client.thing.resolve(org, repo, wref);
53980
54018
  writeOutput(ctx, result, () => {
53981
- const wref2 = result.wref ?? result.name ?? "(unknown)";
53982
- ctx.out(`${pinnedWref(c, wref2, result.version)} ${kindLabel(c, result.kind ?? "thing")}`);
53983
- ctx.out(` ${c.dim}wref:${c.reset} ${escapeTerminalTextForDisplay(wref2)}`);
54019
+ const resolvedWref = result.wref ?? result.name ?? "(unknown)";
54020
+ ctx.out(`${pinnedWref(c, resolvedWref, result.version)} ${kindLabel(c, result.kind ?? "thing")}`);
54021
+ ctx.out(` ${c.dim}wref:${c.reset} ${escapeTerminalTextForDisplay(resolvedWref)}`);
53984
54022
  ctx.out(` ${c.dim}version:${c.reset} ${result.version ?? "-"}`);
53985
54023
  ctx.out(` ${c.dim}active:${c.reset} ${String(result.active)}`);
53986
54024
  });
@@ -55299,7 +55337,7 @@ async function pollForDeviceToken(params) {
55299
55337
  reject(new CliError(4 /* Backend */, "BACKEND", connectionErrorMessage(workosUrl), err2));
55300
55338
  return;
55301
55339
  }
55302
- reject(err2);
55340
+ reject(err2 instanceof Error ? err2 : new Error("Device authorization failed.", { cause: err2 }));
55303
55341
  return;
55304
55342
  }
55305
55343
  if (res.ok) {
@@ -55378,7 +55416,9 @@ async function fetchIdentityWref(ctx) {
55378
55416
  function openBrowser(url2) {
55379
55417
  if (process.env.WH_NO_BROWSER)
55380
55418
  return;
55381
- Promise.resolve().then(() => (init_open(), exports_open)).then(({ default: open2 }) => open2(url2)).catch(() => {});
55419
+ Promise.resolve().then(() => (init_open(), exports_open)).then(({ default: open2 }) => open2(url2)).catch(() => {
55420
+ getLog().warn("auth.browser_open_failed");
55421
+ });
55382
55422
  }
55383
55423
 
55384
55424
  // ../../packages/warmhub-cli/src/domains/auth-handlers.ts
@@ -55436,11 +55476,14 @@ var handleLogin = async (ctx, { flags }) => {
55436
55476
  let clientId;
55437
55477
  try {
55438
55478
  clientId = await ctx.client.auth.getClientId();
55439
- } catch {
55479
+ } catch (error51) {
55480
+ if (ctx.signal?.aborted)
55481
+ throw error51;
55440
55482
  clientId = await createUnauthenticatedClient(ctx.config, {
55441
55483
  functionLogs: ctx.functionLogMode,
55442
55484
  clientFlags: ctx.clientFlags,
55443
- decorateResponses: ctx.decorate
55485
+ decorateResponses: ctx.decorate,
55486
+ signal: ctx.signal
55444
55487
  }).auth.getClientId();
55445
55488
  }
55446
55489
  if (!clientId) {
@@ -55452,7 +55495,8 @@ var handleLogin = async (ctx, { flags }) => {
55452
55495
  deviceRes = await fetch(`${workosUrl}/user_management/authorize/device`, {
55453
55496
  method: "POST",
55454
55497
  headers: { "Content-Type": "application/json" },
55455
- body: JSON.stringify({ client_id: clientId })
55498
+ body: JSON.stringify({ client_id: clientId }),
55499
+ signal: ctx.signal
55456
55500
  });
55457
55501
  } catch (err) {
55458
55502
  if (isConnectionError(err)) {
@@ -55927,6 +55971,7 @@ function createChannelServer(opts) {
55927
55971
 
55928
55972
  // ../../packages/warmhub-cli/src/domains/channel.ts
55929
55973
  var RECONNECT_DELAY_MS = 2000;
55974
+ var MAX_CHANNEL_REPOS = 16;
55930
55975
  function formatChannelEvent(org, repo, event) {
55931
55976
  const things = event.affectedThings.join(", ");
55932
55977
  const shapes = event.affectedShapes.join(",");
@@ -55973,7 +56018,7 @@ async function subscribeLoop(client, org, repo, signal, server) {
55973
56018
  break;
55974
56019
  const msg = err instanceof Error ? err.message : String(err);
55975
56020
  if (msg.includes("401") || msg.includes("403") || msg.includes("404") || msg.includes("AUTH") || msg.includes("not found") || msg.includes("Session expired")) {
55976
- throw new Error(`${org}/${repo}: ${msg}`);
56021
+ throw new Error(`${org}/${repo}: ${msg}`, { cause: err });
55977
56022
  }
55978
56023
  await pauseBeforeReconnect();
55979
56024
  }
@@ -55982,7 +56027,13 @@ async function subscribeLoop(client, org, repo, signal, server) {
55982
56027
  var channelFlags = {};
55983
56028
  var handleChannel = async (ctx, { flags }) => {
55984
56029
  const repoRefs = Array.isArray(flags.repo) ? flags.repo : flags.repo ? [flags.repo] : undefined;
55985
- const repos = repoRefs ? repoRefs.map((ref) => parseOrgRepo(ref, ctx.config)) : [parseOrgRepo(undefined, ctx.config)];
56030
+ const parsedRepos = repoRefs ? repoRefs.map((ref) => parseOrgRepo(ref, ctx.config)) : [parseOrgRepo(undefined, ctx.config)];
56031
+ const repos = [
56032
+ ...new Map(parsedRepos.map(({ org, repo }) => [`${org}/${repo}`, { org, repo }])).values()
56033
+ ];
56034
+ if (repos.length > MAX_CHANNEL_REPOS) {
56035
+ throw new CliError(2 /* UserInput */, "USER_INPUT", `Channel can watch at most ${MAX_CHANNEL_REPOS} unique repositories`);
56036
+ }
55986
56037
  const server = createChannelServer({
55987
56038
  name: "warmhub",
55988
56039
  version: "0.1.0",
@@ -56025,6 +56076,7 @@ var handleChannel = async (ctx, { flags }) => {
56025
56076
  else
56026
56077
  signal.addEventListener("abort", () => controller.abort(), { once: true });
56027
56078
  let fatal;
56079
+ let fatalMessage;
56028
56080
  try {
56029
56081
  const subscriptions = Promise.all(repos.map(({ org, repo }) => subscribeLoop(ctx.client, org, repo, controller.signal, server)));
56030
56082
  const closed = server.onClosed.then(() => {
@@ -56034,14 +56086,13 @@ var handleChannel = async (ctx, { flags }) => {
56034
56086
  } catch (err) {
56035
56087
  controller.abort();
56036
56088
  fatal = err;
56037
- const msg = err instanceof Error ? err.message : String(err);
56038
- process.stderr.write(`[warmhub-channel] Fatal: ${msg}
56089
+ fatalMessage = err instanceof Error ? err.message : String(err);
56090
+ process.stderr.write(`[warmhub-channel] Fatal: ${fatalMessage}
56039
56091
  `);
56040
56092
  }
56041
56093
  server.close();
56042
- if (fatal !== undefined) {
56043
- const msg = fatal instanceof Error ? fatal.message : String(fatal);
56044
- throw new CliError(4 /* Backend */, "BACKEND", `channel subscription failed: ${msg}`);
56094
+ if (fatalMessage !== undefined) {
56095
+ throw new CliError(4 /* Backend */, "BACKEND", `channel subscription failed: ${fatalMessage}`, fatal);
56045
56096
  }
56046
56097
  };
56047
56098
  var CHANNEL_DOMAIN = defineDomain({
@@ -58720,7 +58771,7 @@ function constantAliasValueHint(alias, spec) {
58720
58771
  return alias === "json" && spec.long === "format" ? "Use --json alone, or --format json." : `Use --${alias} alone, or --${spec.long} <value>.`;
58721
58772
  }
58722
58773
  function malformedShortCopy(source, knownShorts, spec) {
58723
- const characters = [...source.slice(1)];
58774
+ const characters = Array.from(source.slice(1));
58724
58775
  const clustered = characters.length > 1 && characters.every((name) => knownShorts.has(name));
58725
58776
  if (clustered) {
58726
58777
  return {
@@ -58735,15 +58786,17 @@ function malformedShortCopy(source, knownShorts, spec) {
58735
58786
  };
58736
58787
  }
58737
58788
  function editDistance(left, right) {
58738
- let previous = Array.from({ length: right.length + 1 }, (_, index) => index);
58739
- for (const [leftIndex, leftCharacter] of [...left].entries()) {
58789
+ const leftCharacters = Array.from(left);
58790
+ const rightCharacters = Array.from(right);
58791
+ let previous = Array.from({ length: rightCharacters.length + 1 }, (_, index) => index);
58792
+ for (const [leftIndex, leftCharacter] of leftCharacters.entries()) {
58740
58793
  const current = [leftIndex + 1];
58741
- for (const [rightIndex, rightCharacter] of [...right].entries()) {
58794
+ for (const [rightIndex, rightCharacter] of rightCharacters.entries()) {
58742
58795
  current.push(Math.min((current[rightIndex] ?? 0) + 1, (previous[rightIndex + 1] ?? 0) + 1, (previous[rightIndex] ?? 0) + (leftCharacter === rightCharacter ? 0 : 1)));
58743
58796
  }
58744
58797
  previous = current;
58745
58798
  }
58746
- return previous[right.length] ?? left.length;
58799
+ return previous[rightCharacters.length] ?? leftCharacters.length;
58747
58800
  }
58748
58801
  function closestLongName(input, specs) {
58749
58802
  const candidates = specs.flatMap((spec) => [
@@ -60347,21 +60400,21 @@ var COMPONENT_DOMAIN = defineDomain({
60347
60400
  function resolveCredentialContext(args) {
60348
60401
  const repoRef = getRepoRef(args.ctx);
60349
60402
  if (repoRef) {
60350
- const { org: org2, repo } = parseOrgRepo(repoRef, args.ctx.config);
60351
- if (args.orgFlag && args.orgFlag !== org2) {
60352
- throw new CliError(2 /* UserInput */, "USER_INPUT", `Conflicting org: --repo resolves to '${org2}' but --org was '${args.orgFlag}'`);
60403
+ const { org, repo } = parseOrgRepo(repoRef, args.ctx.config);
60404
+ if (args.orgFlag && args.orgFlag !== org) {
60405
+ throw new CliError(2 /* UserInput */, "USER_INPUT", `Conflicting org: --repo resolves to '${org}' but --org was '${args.orgFlag}'`);
60353
60406
  }
60354
- return { org: org2, repo };
60407
+ return { org, repo };
60355
60408
  }
60356
- const org = args.orgFlag ?? args.ctx.config.defaultOrg;
60357
- if (!org) {
60409
+ const resolvedOrg = args.orgFlag ?? args.ctx.config.defaultOrg;
60410
+ if (!resolvedOrg) {
60358
60411
  if (args.ctx.config.defaultRepo) {
60359
- const { org: org2, repo } = parseOrgRepo(undefined, args.ctx.config);
60360
- return { org: org2, repo };
60412
+ const { org, repo } = parseOrgRepo(undefined, args.ctx.config);
60413
+ return { org, repo };
60361
60414
  }
60362
60415
  throw new CliError(3 /* Config */, "CONFIG", "No org specified. Use --org <org>, --repo org/repo, or set WARMHUB_ORG.");
60363
60416
  }
60364
- return { org };
60417
+ return { org: resolvedOrg };
60365
60418
  }
60366
60419
  function formatCredentialContextTarget(context) {
60367
60420
  return context.repo ? `${context.org}/${context.repo}` : context.org;
@@ -60840,13 +60893,14 @@ async function prepareTextFile(path2, content, mode) {
60840
60893
  temporaryClosed = true;
60841
60894
  return temporaryPath;
60842
60895
  } catch (error51) {
60843
- if (!temporaryClosed)
60844
- await temporary.close().catch(() => {
60845
- return;
60846
- });
60847
- await unlink(temporaryPath).catch(() => {
60848
- return;
60849
- });
60896
+ if (!temporaryClosed) {
60897
+ try {
60898
+ await temporary.close();
60899
+ } catch {}
60900
+ }
60901
+ try {
60902
+ await unlink(temporaryPath);
60903
+ } catch {}
60850
60904
  throw error51;
60851
60905
  }
60852
60906
  }
@@ -61256,9 +61310,9 @@ async function collectChecks(ctx) {
61256
61310
  status: repo !== undefined ? repoParts ? "ok" : "fail" : "warn",
61257
61311
  message: repo !== undefined ? repoParts ? `${hasRepoFlag ? "Target" : "Default"} repo: ${repoForDisplay}${repoProvenance}` : `Invalid repo format "${repoForDisplay}". Expected "org/repo".` : "No default repo set (use --repo flag, WARMHUB_REPO, or wh use org/repo)"
61258
61312
  });
61259
- const profileFlag = ctx.invocation.flags.profile;
61260
- const profile = (typeof profileFlag === "string" ? profileFlag : undefined) ?? ctx.config.profile ?? ctx.profile ?? "default";
61261
- const profileSource = typeof profileFlag === "string" ? "flag" : ctx.config.configSource?.profile;
61313
+ const requestedProfile = ctx.invocation.flags.profile;
61314
+ const profile = (typeof requestedProfile === "string" ? requestedProfile : undefined) ?? ctx.config.profile ?? ctx.profile ?? "default";
61315
+ const profileSource = typeof requestedProfile === "string" ? "flag" : ctx.config.configSource?.profile;
61262
61316
  const profileProvenance = profileSource === "env" ? " (from WH_PROFILE)" : profileSource === "wh-file" ? " (from .wh file)" : profileSource === "flag" ? " (from --profile flag)" : "";
61263
61317
  checks3.push({
61264
61318
  key: "profile",
@@ -61341,8 +61395,8 @@ async function collectChecks(ctx) {
61341
61395
  message: `Token validation failed: ${whoami.error}`
61342
61396
  });
61343
61397
  } else {
61344
- const profileFlag2 = ctx.invocation.flags.profile;
61345
- const activeProfile = (typeof profileFlag2 === "string" ? profileFlag2 : undefined) ?? ctx.config.profile;
61398
+ const profileFlag = ctx.invocation.flags.profile;
61399
+ const activeProfile = (typeof profileFlag === "string" ? profileFlag : undefined) ?? ctx.config.profile;
61346
61400
  const loginCmd = activeProfile && activeProfile !== "default" ? `wh auth login --profile ${activeProfile}` : "wh auth login";
61347
61401
  const detail = process.env.WH_TOKEN ? `WH_TOKEN is set; verify it was issued for ${ctx.config.apiUrl} and that the backend has auth verification enabled, or unset WH_TOKEN and run \`${loginCmd}\`.` : `Run \`${loginCmd}\`, or verify ${ctx.config.apiUrl} is what you expect and has auth verification enabled.`;
61348
61402
  checks3.push({
@@ -62733,6 +62787,7 @@ import { join as join11 } from "node:path";
62733
62787
  import { createHash as createHash2 } from "node:crypto";
62734
62788
  import { Writable } from "node:stream";
62735
62789
  import { pipeline } from "node:stream/promises";
62790
+ import { callbackify } from "node:util";
62736
62791
  import { crc32, createInflateRaw } from "node:zlib";
62737
62792
  var LOCAL_SIGNATURE = 67324752;
62738
62793
  var CENTRAL_SIGNATURE = 33639248;
@@ -62802,32 +62857,31 @@ async function inflateEntry(reader, sink) {
62802
62857
  let compressedSize = 0n;
62803
62858
  let uncompressedSize = 0n;
62804
62859
  let crc = 0;
62860
+ const writeChunk = callbackify(async (bytes) => {
62861
+ try {
62862
+ await sink.write(bytes);
62863
+ } catch (error51) {
62864
+ throw error51 instanceof Error ? error51 : new Error("checkpoint sink failed");
62865
+ }
62866
+ crc = crc32(bytes, crc);
62867
+ uncompressedSize += BigInt(bytes.byteLength);
62868
+ });
62805
62869
  const output = new Writable({
62806
62870
  highWaterMark: INFLATE_INPUT_BYTES,
62807
62871
  write(bytes, _encoding, done) {
62808
- sink.write(bytes).then(() => {
62809
- crc = crc32(bytes, crc);
62810
- uncompressedSize += BigInt(bytes.byteLength);
62811
- done();
62812
- }).catch((error51) => {
62813
- done(error51 instanceof Error ? error51 : new Error("checkpoint sink failed"));
62814
- });
62872
+ writeChunk(bytes, done);
62815
62873
  }
62816
62874
  });
62817
62875
  const completed = pipeline(inflater, output);
62818
- const failed = completed.then(() => new Promise(() => {
62819
- return;
62820
- }), (error51) => Promise.reject(error51));
62821
- failed.catch(() => {
62822
- return;
62823
- });
62876
+ const pipelineFailure = new PipelineFailureSignal;
62877
+ const failureObservation = observePipelineFailure(completed, pipelineFailure);
62824
62878
  try {
62825
62879
  while (!inflater.readableEnded) {
62826
62880
  const input = await reader.readSome(INFLATE_INPUT_BYTES);
62827
62881
  if (!input)
62828
62882
  throw new Error("archive entry is truncated");
62829
62883
  const before = inflater.bytesWritten;
62830
- await writeInflateInput(inflater, input, failed);
62884
+ await writeInflateInput(inflater, input, pipelineFailure);
62831
62885
  const consumed = inflater.bytesWritten - before;
62832
62886
  if (!Number.isSafeInteger(consumed) || consumed < 0 || consumed > input.byteLength) {
62833
62887
  throw new Error("archive inflater consumed invalid input");
@@ -62846,12 +62900,44 @@ async function inflateEntry(reader, sink) {
62846
62900
  } finally {
62847
62901
  if (!inflater.destroyed)
62848
62902
  inflater.destroy();
62849
- await completed.catch(() => {
62850
- return;
62903
+ await failureObservation;
62904
+ }
62905
+ }
62906
+
62907
+ class PipelineFailureSignal {
62908
+ #failure;
62909
+ #rejectCurrent;
62910
+ fail(error51) {
62911
+ const failure = error51 instanceof Error ? error51 : new Error("archive inflater failed");
62912
+ this.#failure = failure;
62913
+ this.#rejectCurrent?.(failure);
62914
+ this.#rejectCurrent = undefined;
62915
+ }
62916
+ async race(work) {
62917
+ if (this.#failure)
62918
+ throw this.#failure;
62919
+ let rejectCurrent;
62920
+ const currentFailure = new Promise((_resolve, reject) => {
62921
+ rejectCurrent = (error51) => reject(error51);
62922
+ this.#rejectCurrent = rejectCurrent;
62851
62923
  });
62924
+ try {
62925
+ return await Promise.race([work, currentFailure]);
62926
+ } finally {
62927
+ if (rejectCurrent && this.#rejectCurrent === rejectCurrent) {
62928
+ this.#rejectCurrent = undefined;
62929
+ }
62930
+ }
62931
+ }
62932
+ }
62933
+ async function observePipelineFailure(completed, signal) {
62934
+ try {
62935
+ await completed;
62936
+ } catch (error51) {
62937
+ signal.fail(error51);
62852
62938
  }
62853
62939
  }
62854
- async function writeInflateInput(inflater, input, failed) {
62940
+ async function writeInflateInput(inflater, input, pipelineFailure) {
62855
62941
  const written = new Promise((resolve4, reject) => {
62856
62942
  inflater.write(input, (error51) => {
62857
62943
  if (error51)
@@ -62860,7 +62946,7 @@ async function writeInflateInput(inflater, input, failed) {
62860
62946
  resolve4();
62861
62947
  });
62862
62948
  });
62863
- await Promise.race([written, failed]);
62949
+ await pipelineFailure.race(written);
62864
62950
  }
62865
62951
  async function readCentralDirectory(reader, entries) {
62866
62952
  const centralOffset = BigInt(reader.position);
@@ -63054,10 +63140,11 @@ function toAsyncIterable2(source) {
63054
63140
  yield value;
63055
63141
  }
63056
63142
  } finally {
63057
- if (!completed)
63058
- await reader.cancel().catch(() => {
63059
- return;
63060
- });
63143
+ if (!completed) {
63144
+ try {
63145
+ await reader.cancel();
63146
+ } catch {}
63147
+ }
63061
63148
  reader.releaseLock();
63062
63149
  }
63063
63150
  }
@@ -63095,7 +63182,7 @@ class CheckpointIdentitySorter {
63095
63182
  this.#scratchPath = scratchPath;
63096
63183
  const sortBudgetBytes = options.sortBudgetBytes ?? CHECKPOINT_IDENTITY_SORT_BUDGET_BYTES;
63097
63184
  this.#mergeFanIn = options.mergeFanIn ?? CHECKPOINT_IDENTITY_MERGE_FAN_IN;
63098
- if (!Number.isSafeInteger(sortBudgetBytes) || sortBudgetBytes < MINIMUM_RESIDENT_BYTES || !Number.isSafeInteger(this.#mergeFanIn) || this.#mergeFanIn < 2) {
63185
+ if (!Number.isSafeInteger(sortBudgetBytes) || sortBudgetBytes < MINIMUM_RESIDENT_BYTES || !Number.isSafeInteger(this.#mergeFanIn) || this.#mergeFanIn < 2 || this.#mergeFanIn > CHECKPOINT_IDENTITY_MERGE_FAN_IN) {
63099
63186
  throw new Error("checkpoint identity sort limits are invalid");
63100
63187
  }
63101
63188
  this.#resident = new ResidentDurableIds(sortBudgetBytes);
@@ -63191,7 +63278,12 @@ class ResidentDurableIds {
63191
63278
  const offsets = this.#offsets.subarray(0, this.#count);
63192
63279
  offsets.sort((left, right) => this.#compareAt(left, right));
63193
63280
  for (let index = 1;index < offsets.length; index += 1) {
63194
- if (this.#compareAt(offsets[index - 1], offsets[index]) === 0) {
63281
+ const previousOffset = offsets[index - 1];
63282
+ const offset = offsets[index];
63283
+ if (previousOffset === undefined || offset === undefined) {
63284
+ throw new Error("checkpoint identity offset is missing");
63285
+ }
63286
+ if (this.#compareAt(previousOffset, offset) === 0) {
63195
63287
  throw new DuplicateCheckpointDurableIdError;
63196
63288
  }
63197
63289
  }
@@ -63415,7 +63507,12 @@ async function writeChunk(output, chunk) {
63415
63507
  function compareUtf8Bytes(left, right) {
63416
63508
  const sharedLength = Math.min(left.length, right.length);
63417
63509
  for (let index = 0;index < sharedLength; index += 1) {
63418
- const difference = left[index] - right[index];
63510
+ const leftByte = left[index];
63511
+ const rightByte = right[index];
63512
+ if (leftByte === undefined || rightByte === undefined) {
63513
+ throw new Error("checkpoint identity byte is missing");
63514
+ }
63515
+ const difference = leftByte - rightByte;
63419
63516
  if (difference !== 0)
63420
63517
  return difference;
63421
63518
  }
@@ -63656,31 +63753,31 @@ function mapVerificationError(error51) {
63656
63753
  import { createHash as createHash4, randomUUID as randomUUID3 } from "node:crypto";
63657
63754
  import { link, lstat as lstat2, open as open4, unlink as unlink2 } from "node:fs/promises";
63658
63755
  import { basename as basename5, dirname as dirname7, join as join12 } from "node:path";
63756
+ async function bestEffortCleanup(cleanup) {
63757
+ try {
63758
+ await cleanup();
63759
+ } catch {}
63760
+ }
63659
63761
  async function writeDownloadedCheckpointArtifact(ctx, response, descriptor, output, ports = {}) {
63660
- if (!response.ok || !response.body) {
63661
- await response.body?.cancel().catch(() => {
63662
- return;
63663
- });
63762
+ const body = response.body;
63763
+ if (!response.ok || !body) {
63764
+ await bestEffortCleanup(() => body?.cancel());
63664
63765
  throw new CliError(4 /* Backend */, "BACKEND", `Checkpoint artifact download failed with HTTP ${response.status}`);
63665
63766
  }
63666
63767
  if (output !== "-") {
63667
63768
  try {
63668
63769
  await refuseExistingDestination(output);
63669
63770
  } catch (error51) {
63670
- await response.body.cancel().catch(() => {
63671
- return;
63672
- });
63771
+ await bestEffortCleanup(() => body.cancel());
63673
63772
  throw error51;
63674
63773
  }
63675
63774
  }
63676
63775
  const digest2 = createHash4("sha256");
63677
63776
  let byteLength = 0;
63678
- const stream = responseChunks(response.body);
63777
+ const stream = responseChunks(body);
63679
63778
  if (output === "-") {
63680
63779
  if (!ctx.writeBinary) {
63681
- await response.body.cancel().catch(() => {
63682
- return;
63683
- });
63780
+ await bestEffortCleanup(() => body.cancel());
63684
63781
  throw new CliError(1 /* Runtime */, "UNKNOWN", "Binary stdout is unavailable for this command context.");
63685
63782
  }
63686
63783
  for await (const bytes of stream) {
@@ -63710,15 +63807,9 @@ async function writeDownloadedCheckpointArtifact(ctx, response, descriptor, outp
63710
63807
  await link(temporary, output);
63711
63808
  await unlink2(temporary);
63712
63809
  } catch (error51) {
63713
- await handle?.close().catch(() => {
63714
- return;
63715
- });
63716
- await unlink2(temporary).catch(() => {
63717
- return;
63718
- });
63719
- await response.body.cancel().catch(() => {
63720
- return;
63721
- });
63810
+ await bestEffortCleanup(() => handle?.close());
63811
+ await bestEffortCleanup(() => unlink2(temporary));
63812
+ await bestEffortCleanup(() => body.cancel());
63722
63813
  if (error51.code === "EEXIST") {
63723
63814
  throw new CliError(2 /* UserInput */, "USER_INPUT", `Refusing to overwrite existing output path '${output}'.`);
63724
63815
  }
@@ -63760,9 +63851,7 @@ async function* responseChunks(body) {
63760
63851
  yield value;
63761
63852
  }
63762
63853
  } finally {
63763
- await reader.cancel().catch(() => {
63764
- return;
63765
- });
63854
+ await bestEffortCleanup(() => reader.cancel());
63766
63855
  reader.releaseLock();
63767
63856
  }
63768
63857
  }
@@ -67875,7 +67964,7 @@ function buildLookup(specs) {
67875
67964
  });
67876
67965
  }
67877
67966
  if (spec.short !== undefined) {
67878
- if ([...spec.short].length !== 1) {
67967
+ if (Array.from(spec.short).length !== 1) {
67879
67968
  throw new Error(`Short flag -${spec.short} must be one character`);
67880
67969
  }
67881
67970
  addUnique(shorts, spec.short, { spec, spelling: "short" });
@@ -68085,7 +68174,7 @@ function bindOccurrences(records, specs, options = {}) {
68085
68174
  continue;
68086
68175
  if (record2.kind === "malformed-short") {
68087
68176
  if ((options.unknownFlags ?? "error") === "error") {
68088
- const firstShort = [...record2.source.slice(1)][0];
68177
+ const firstShort = Array.from(record2.source.slice(1))[0];
68089
68178
  const spec = firstShort ? lookup.shorts.get(firstShort)?.spec : undefined;
68090
68179
  const copy = malformedShortCopy(record2.source, lookup.shorts, spec);
68091
68180
  errors3.push({
@@ -68277,7 +68366,7 @@ function scanArgv(argv) {
68277
68366
  };
68278
68367
  }
68279
68368
  if (source.startsWith("-") && source !== "-") {
68280
- const shortCharacters = [...source.slice(1)];
68369
+ const shortCharacters = Array.from(source.slice(1));
68281
68370
  if (shortCharacters.length === 1) {
68282
68371
  return {
68283
68372
  kind: "option",
@@ -69235,7 +69324,7 @@ function resolveLogLevel(flagLevel, env) {
69235
69324
  // package.json
69236
69325
  var package_default3 = {
69237
69326
  name: "@warmhub/cli",
69238
- version: "0.112.0",
69327
+ version: "0.113.0",
69239
69328
  private: false,
69240
69329
  type: "module",
69241
69330
  description: "The wh CLI for WarmHub — create repos, commit and query data, and compound knowledge with your AI agents.",
@@ -69860,5 +69949,5 @@ process.exitCode = interceptedExitCode === undefined ? await runPreparedCli(laun
69860
69949
  version: package_default3.version
69861
69950
  }) : interceptedExitCode;
69862
69951
 
69863
- //# debugId=A0E5CC4BED9D3F1464756E2164756E21
69864
- //# warmhub-cli-build-info {"cliVersion":"0.112.0","sdkVersion":"0.110.0"}
69952
+ //# debugId=4FF14B239E0A264364756E2164756E21
69953
+ //# warmhub-cli-build-info {"cliVersion":"0.113.0","sdkVersion":"0.111.0"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@warmhub/cli",
3
- "version": "0.112.0",
3
+ "version": "0.113.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.",