@theholocron/cli 5.0.0-alpha.175 → 5.0.0-alpha.177

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.
package/dist/cli.mjs CHANGED
@@ -2257,7 +2257,7 @@ async function runDoctor(input) {
2257
2257
  capability: row.capability,
2258
2258
  provider: row.provider,
2259
2259
  status: row.status,
2260
- detail: row.message
2260
+ detail: row.logMessage ?? row.message
2261
2261
  }, `doctor: ${row.capability}`);
2262
2262
  print(statusRow(row.status, [`${pad(row.capability, 14)} via ${pad(row.provider, 14)}`, row.message]));
2263
2263
  }
@@ -2296,9 +2296,34 @@ async function smokeCheck(key, provider, impl) {
2296
2296
  try {
2297
2297
  return await withTimeout(runSmokeCheck(key, provider, impl), SMOKE_CHECK_TIMEOUT_MS);
2298
2298
  } catch (err) {
2299
- return mk(key, provider, "fail", errorMessage(err));
2299
+ return mk(key, provider, "fail", smokeCheckErrorMessage(err), errorMessage(err));
2300
2300
  }
2301
2301
  }
2302
+ /** Vendor response bodies land in the terminal — cap their length so one
2303
+ * oversized error can't flood the report, and strip control characters
2304
+ * (newlines included) so a crafted body can't forge extra report lines
2305
+ * or inject terminal escape sequences. */
2306
+ const MAX_DETAIL_LENGTH = 200;
2307
+ function sanitizeDetail(text) {
2308
+ const stripped = text.replace(/[\x00-\x1f\x7f]/g, " ").replace(/\s+/g, " ").trim();
2309
+ return stripped.length > MAX_DETAIL_LENGTH ? `${stripped.slice(0, MAX_DETAIL_LENGTH)}…` : stripped;
2310
+ }
2311
+ /**
2312
+ * `errorMessage(err)` alone is just `"<Vendor> <METHOD> <path> → <status>"` —
2313
+ * the actual reason (what the vendor's response body said) lives in
2314
+ * `ProviderApiError.details`, a raw response-body string (not parsed JSON —
2315
+ * see AGENTS.md), and was being silently dropped. Appending it (sanitized
2316
+ * and length-capped — see `sanitizeDetail`) turns e.g. a bare "→ 400" into
2317
+ * something that actually explains itself, without the vendor text being
2318
+ * able to overwhelm or manipulate the terminal report.
2319
+ */
2320
+ function smokeCheckErrorMessage(err) {
2321
+ if (err instanceof ProviderApiError$1 && err.details) {
2322
+ const detail = sanitizeDetail(String(err.details));
2323
+ if (detail) return `${errorMessage(err)}: ${detail}`;
2324
+ }
2325
+ return errorMessage(err);
2326
+ }
2302
2327
  async function runSmokeCheck(key, provider, impl) {
2303
2328
  switch (key) {
2304
2329
  case "source": return mk(key, provider, "ok", `whoami: ${(await impl.whoami()).login}`);
@@ -2365,12 +2390,13 @@ async function runSmokeCheck(key, provider, impl) {
2365
2390
  function countResolvedLifecycle(report) {
2366
2391
  return `${report.lifecycle.filter((l) => l.resolved).length}/${report.lifecycle.length} lifecycle slots ready`;
2367
2392
  }
2368
- function mk(capability, provider, status, message) {
2393
+ function mk(capability, provider, status, message, logMessage) {
2369
2394
  return {
2370
2395
  capability,
2371
2396
  provider,
2372
2397
  status,
2373
- message
2398
+ message,
2399
+ ...logMessage !== void 0 ? { logMessage } : {}
2374
2400
  };
2375
2401
  }
2376
2402
  //#endregion