@theholocron/cli 5.0.0-alpha.182 → 5.0.0-alpha.184

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
@@ -2410,6 +2410,7 @@ async function runDeployFromFiles(input) {
2410
2410
  * errors → `whoami()` (org reachability) or `describe()`
2411
2411
  * logs → `whoami()` (dataset reachability) or `describe()`
2412
2412
  * wiki → `whoami()` (token presence only — not a live check, see holocron#1079)
2413
+ * notifications → `whoami()` when the provider provisions (bot token + server access); otherwise just "loaded"
2413
2414
  * others → just "loaded" (no smoke endpoint defined yet)
2414
2415
  *
2415
2416
  * Output is plain text via a passed-in `print` function so tests can
@@ -2435,15 +2436,13 @@ async function runDoctor(input) {
2435
2436
  const cardinality = CARDINALITY[key];
2436
2437
  const entry = config.providers[key];
2437
2438
  const providers = entry?.cardinality === "many" ? entry.tuples.map((t) => t.provider) : entry?.cardinality === "single" ? [entry.tuple.provider] : [];
2438
- if (cardinality === "many") loader.get(key).forEach((_impl, idx) => {
2439
- rows.push({
2440
- capability: key,
2441
- provider: providers[idx] ?? "?",
2442
- status: "skip",
2443
- message: "loaded (no smoke check defined for this capability)"
2444
- });
2445
- });
2446
- else {
2439
+ if (cardinality === "many") {
2440
+ const impls = loader.get(key);
2441
+ for (const [idx, impl] of impls.entries()) {
2442
+ const name = impl.providerName ?? providers[idx];
2443
+ rows.push(await smokeCheck(key, name, impl));
2444
+ }
2445
+ } else {
2447
2446
  const impl = loader.get(key);
2448
2447
  const row = await smokeCheck(key, providers[0] ?? "?", impl);
2449
2448
  rows.push(row);
@@ -2499,11 +2498,11 @@ async function smokeCheck(key, provider, impl) {
2499
2498
  }
2500
2499
  /** Vendor response bodies land in the terminal — cap their length so one
2501
2500
  * oversized error can't flood the report, and strip control characters
2502
- * (newlines included) so a crafted body can't forge extra report lines
2503
- * or inject terminal escape sequences. */
2501
+ * (newlines and the C1 range, whose 0x9b is an 8-bit CSI) so a crafted body
2502
+ * can't forge extra report lines or inject terminal escape sequences. */
2504
2503
  const MAX_DETAIL_LENGTH = 200;
2505
2504
  function sanitizeDetail(text) {
2506
- const stripped = text.replace(/[\x00-\x1f\x7f]/g, " ").replace(/\s+/g, " ").trim();
2505
+ const stripped = text.replace(/[\x00-\x1f\x7f-\x9f]/g, " ").replace(/\s+/g, " ").trim();
2507
2506
  return stripped.length > MAX_DETAIL_LENGTH ? `${stripped.slice(0, MAX_DETAIL_LENGTH)}…` : stripped;
2508
2507
  }
2509
2508
  /**
@@ -2529,19 +2528,19 @@ async function runSmokeCheck(key, provider, impl) {
2529
2528
  const report = await impl.doctor();
2530
2529
  return mk(key, provider, "ok", `${report.authedAs} / ${report.projectLabel} (${countResolvedLifecycle(report)})`);
2531
2530
  }
2532
- case "secrets": return mk(key, provider, "ok", `repo secrets: ${(await impl.listSecrets({ kind: "repo" })).length} configured`);
2531
+ case "secrets": return mk(key, provider, "ok", `secrets: ${(await impl.listSecrets({ kind: "repo" })).length} configured`);
2533
2532
  case "ci": {
2534
2533
  const runs = await impl.listRuns({ limit: 1 });
2535
2534
  return mk(key, provider, "ok", runs.length === 0 ? "no recent runs" : `most recent: ${runs[0].workflowName} (${runs[0].status})`);
2536
2535
  }
2537
- case "vault": return mk(key, provider, "ok", `${(await impl.list()).length} keys available`);
2538
- case "deployment": return mk(key, provider, "ok", `${(await impl.listProjects()).length} project(s) visible`);
2539
- case "environments": return mk(key, provider, "ok", `${(await impl.listEnvironments()).length} environment(s) configured`);
2536
+ case "vault": return mk(key, provider, "ok", `keys: ${(await impl.list()).length} visible`);
2537
+ case "deployment": return mk(key, provider, "ok", `projects: ${(await impl.listProjects()).length} visible`);
2538
+ case "environments": return mk(key, provider, "ok", `environments: ${(await impl.listEnvironments()).length} configured`);
2540
2539
  case "dns": {
2541
2540
  const dns = impl;
2542
2541
  if (dns.whoami) {
2543
2542
  const who = await dns.whoami();
2544
- return mk(key, provider, who.ok ? "ok" : "fail", `${who.zones} zone(s) visible`);
2543
+ return mk(key, provider, who.ok ? "ok" : "fail", `zones: ${who.zones} visible`);
2545
2544
  }
2546
2545
  return mk(key, provider, "skip", "loaded (no smoke check defined for this capability)");
2547
2546
  }
@@ -2549,7 +2548,7 @@ async function runSmokeCheck(key, provider, impl) {
2549
2548
  const workers = impl;
2550
2549
  if (workers.whoami) {
2551
2550
  const who = await workers.whoami();
2552
- return mk(key, provider, who.ok ? "ok" : "fail", `${who.scripts} script(s) visible`);
2551
+ return mk(key, provider, who.ok ? "ok" : "fail", `scripts: ${who.scripts} visible`);
2553
2552
  }
2554
2553
  return mk(key, provider, "skip", "loaded (no smoke check defined for this capability)");
2555
2554
  }
@@ -2582,6 +2581,12 @@ async function runSmokeCheck(key, provider, impl) {
2582
2581
  }
2583
2582
  return mk(key, provider, "skip", "loaded (no smoke check defined for this capability)");
2584
2583
  }
2584
+ case "notifications": {
2585
+ const notifications = impl;
2586
+ const who = notifications.whoami ? await notifications.whoami() : null;
2587
+ if (who) return mk(key, provider, "ok", `server: ${sanitizeDetail(who.target)}`);
2588
+ return mk(key, provider, "skip", "loaded (no smoke check defined for this capability)");
2589
+ }
2585
2590
  case "wiki": {
2586
2591
  const wiki = impl;
2587
2592
  if (wiki.whoami) {