@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 +23 -18
- package/dist/cli.mjs.map +1 -1
- package/dist/plugin/capabilities.d.mts +10 -0
- package/package.json +3 -3
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")
|
|
2439
|
-
|
|
2440
|
-
|
|
2441
|
-
|
|
2442
|
-
|
|
2443
|
-
|
|
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
|
|
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", `
|
|
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",
|
|
2538
|
-
case "deployment": return mk(key, provider, "ok",
|
|
2539
|
-
case "environments": return mk(key, provider, "ok",
|
|
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",
|
|
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",
|
|
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) {
|