@ganakailabs/cloudeval-cli 0.29.1 → 0.29.3

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.
@@ -38,10 +38,10 @@ import {
38
38
  } from "./chunk-ERGQHMNT.js";
39
39
  import {
40
40
  Banner
41
- } from "./chunk-VRLH2WYY.js";
41
+ } from "./chunk-D2ROSW4U.js";
42
42
  import {
43
43
  CLI_VERSION
44
- } from "./chunk-AO4LJZTG.js";
44
+ } from "./chunk-PN4AUAH6.js";
45
45
  import {
46
46
  raisedButtonStyle,
47
47
  terminalTheme
@@ -3,8 +3,8 @@ import {
3
3
  bannerMetaColor,
4
4
  bannerSegmentColor,
5
5
  splitBannerLineSegments
6
- } from "./chunk-VRLH2WYY.js";
7
- import "./chunk-AO4LJZTG.js";
6
+ } from "./chunk-D2ROSW4U.js";
7
+ import "./chunk-PN4AUAH6.js";
8
8
  import "./chunk-ZDKRIOMB.js";
9
9
  export {
10
10
  Banner,
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  CLI_VERSION
3
- } from "./chunk-AO4LJZTG.js";
3
+ } from "./chunk-PN4AUAH6.js";
4
4
  import {
5
5
  shouldUseColor,
6
6
  terminalTheme
@@ -1,5 +1,5 @@
1
1
  // src/version.ts
2
- var CLI_VERSION = "0.29.1";
2
+ var CLI_VERSION = "0.29.3";
3
3
 
4
4
  export {
5
5
  CLI_VERSION
package/dist/cli.js CHANGED
@@ -39,7 +39,7 @@ import {
39
39
  } from "./chunk-ERGQHMNT.js";
40
40
  import {
41
41
  CLI_VERSION
42
- } from "./chunk-AO4LJZTG.js";
42
+ } from "./chunk-PN4AUAH6.js";
43
43
 
44
44
  // src/runtime/prepareInk.ts
45
45
  import fs from "fs";
@@ -3512,32 +3512,33 @@ var deterministicAiSummary = (data, error) => {
3512
3512
  const failedTests = numberFrom(validation?.unitTests?.failed) ?? numberFrom(validation?.unit_tests?.failed) ?? numberFrom(validation?.failedUnitTests) ?? numberFrom(validation?.failed_tests) ?? 0;
3513
3513
  const policyFailed = numberFrom(validation?.policyChecks?.failed) ?? numberFrom(validation?.policy_checks?.failed) ?? numberFrom(data.gate?.policy?.failed) ?? 0;
3514
3514
  const policyStatus = policyFailed > 0 ? "has failed checks" : "GOOD";
3515
+ const weakestPillar = Array.isArray(data.gate?.wellArchitected?.pillars) ? data.gate.wellArchitected.pillars.filter((pillar) => numberFrom(pillar.score) !== void 0).sort(
3516
+ (left, right) => (numberFrom(left.score) ?? 0) - (numberFrom(right.score) ?? 0)
3517
+ )[0] : void 0;
3518
+ const weakestPillarLabel = weakestPillar?.label ?? weakestPillar?.id ?? "the weakest Well-Architected pillar";
3519
+ const highRisk = numberFrom(data.gate?.wellArchitected?.risks?.high) ?? 0;
3515
3520
  const summary = [
3516
3521
  `CloudEval review completed with **${String(data.gate?.status ?? "UNKNOWN").toUpperCase()}**.`,
3517
3522
  `Well-Architected posture is **${formatScore(score)} (${rating})**, validation has **${displayNumber(failedTests)} failed unit tests**, policy checks are **${policyStatus}**, and monthly cost is **${formatMonthlyMoney(cost?.amount, cost?.currency)}**.`,
3518
- "Prioritize **failed validation checks** and the **weakest Well-Architected pillar** first."
3523
+ `Prioritize **failed validation checks** and **${weakestPillarLabel}** first.`
3519
3524
  ].join(" ");
3525
+ const detailsMarkdown = [
3526
+ `**Main risk**
3527
+ The gate is **${String(data.gate?.status ?? "UNKNOWN").toUpperCase()}** with Well-Architected posture **${formatScore(score)} (${rating})**, **${displayNumber(failedTests)} failed unit tests**, and monthly cost **${formatMonthlyMoney(cost?.amount, cost?.currency)}**.`,
3528
+ `**Why it matters**
3529
+ ${highRisk > 0 ? `There are **${displayNumber(highRisk)} high-risk findings**. ` : ""}Validation failures, weak architecture pillars, and cost over budget are the highest-signal remediation inputs before merge.`,
3530
+ `**Recommended actions**
3531
+ Fix **${displayNumber(failedTests)} failed unit tests**, address **${weakestPillarLabel}**, review cost drivers against the budget, rerun CloudEval review, and compare the updated gate.`,
3532
+ "**Evidence used**\n**Gate status**, **Well-Architected score**, **validation totals**, **policy totals**, **monthly cost**, and **architecture signals**."
3533
+ ].join("\n\n");
3520
3534
  return {
3521
3535
  enabled: true,
3522
3536
  status: "fallback",
3523
3537
  fallbackUsed: true,
3524
3538
  warnings: error ? [`Review summary endpoint failed: ${error}`] : [],
3525
3539
  shortSummary: summary,
3526
- detailsMarkdown: [
3527
- "**Main risk**\nCloudEval could not produce an AI-written review summary, so use the deterministic gate evidence.",
3528
- "**Why it matters**\n**Failed validation** and **weak architecture pillars** are the highest-signal remediation inputs.",
3529
- "**Recommended actions**\nFix **failed validation checks**, address the **weakest pillar**, rerun CloudEval review, and compare the updated gate.",
3530
- "**Evidence used**\n**Gate status**, **Well-Architected score**, **validation totals**, **policy totals**, and **monthly cost**."
3531
- ].join("\n\n"),
3532
- markdown: renderAiSummarySections(
3533
- summary,
3534
- [
3535
- "**Main risk**\nCloudEval could not produce an AI-written review summary, so use the deterministic gate evidence.",
3536
- "**Why it matters**\n**Failed validation** and **weak architecture pillars** are the highest-signal remediation inputs.",
3537
- "**Recommended actions**\nFix **failed validation checks**, address the **weakest pillar**, rerun CloudEval review, and compare the updated gate.",
3538
- "**Evidence used**\n**Gate status**, **Well-Architected score**, **validation totals**, **policy totals**, and **monthly cost**."
3539
- ].join("\n\n")
3540
- )
3540
+ detailsMarkdown,
3541
+ markdown: renderAiSummarySections(summary, detailsMarkdown)
3541
3542
  };
3542
3543
  };
3543
3544
  var generateAiSummary = async (input) => {
@@ -3604,6 +3605,11 @@ var buildMarkdownSummary = (data) => {
3604
3605
  { maxRows: 5, remainderLabel: "Unallocated" }
3605
3606
  );
3606
3607
  const positiveResourceCosts = resourceCostRows.filter((resource) => resource.amount > 0);
3608
+ const namedResourceCosts = positiveResourceCosts.filter(
3609
+ (resource) => resource.name !== "Unallocated"
3610
+ );
3611
+ const costPieRows = namedResourceCosts.length ? positiveResourceCosts : costServices.filter((service) => service.amount > 0);
3612
+ const costPieTitle = namedResourceCosts.length ? "Monthly cost by resource" : "Monthly cost by service";
3607
3613
  const openLinks = openInCloudEvalLines(data.links);
3608
3614
  const architectureLines = architectureSignalLines({
3609
3615
  architecture,
@@ -3666,13 +3672,13 @@ var buildMarkdownSummary = (data) => {
3666
3672
  `- Estimated savings: **${formatMonthlyMoney(data.gate.cost.estimatedSavings.amount, data.gate.cost.estimatedSavings.currency)}**`
3667
3673
  );
3668
3674
  }
3669
- if (positiveResourceCosts.length) {
3675
+ if (costPieRows.length) {
3670
3676
  costLines.push(
3671
3677
  "",
3672
3678
  "```mermaid",
3673
- "pie title Monthly cost by resource",
3674
- ...positiveResourceCosts.map(
3675
- (resource) => ` "${mermaidLabel(resource.name)}" : ${trimNumber(resource.amount, 3)}`
3679
+ `pie title ${costPieTitle}`,
3680
+ ...costPieRows.map(
3681
+ (row) => ` "${mermaidLabel(row.name)}" : ${trimNumber(row.amount, 3)}`
3676
3682
  ),
3677
3683
  "```"
3678
3684
  );
@@ -16568,7 +16574,7 @@ program.command("tui").description("Open the CloudEval Terminal UI").option(
16568
16574
  const { assertSecureBaseUrl } = await import("./dist-QYIPN7MD.js");
16569
16575
  const [{ render }, { App }] = await Promise.all([
16570
16576
  import("ink"),
16571
- import("./App-OLD5LMTA.js")
16577
+ import("./App-7FR4HVBO.js")
16572
16578
  ]);
16573
16579
  const baseUrl = await resolveBaseUrl(options, command);
16574
16580
  assertSecureBaseUrl(baseUrl);
@@ -16626,7 +16632,7 @@ program.command("chat").description("Start an interactive chat session").option(
16626
16632
  const { assertSecureBaseUrl } = await import("./dist-QYIPN7MD.js");
16627
16633
  const [{ render }, { App }] = await Promise.all([
16628
16634
  import("ink"),
16629
- import("./App-OLD5LMTA.js")
16635
+ import("./App-7FR4HVBO.js")
16630
16636
  ]);
16631
16637
  const baseUrl = await resolveBaseUrl(options, command);
16632
16638
  assertSecureBaseUrl(baseUrl);
@@ -17380,7 +17386,7 @@ Error: ${errorMsg}
17380
17386
  program.command("banner").description("Preview the startup banner and terminal capabilities").action(async () => {
17381
17387
  const { render } = await import("ink");
17382
17388
  const BannerPreview = React.lazy(async () => ({
17383
- default: (await import("./Banner-6W7U2C44.js")).Banner
17389
+ default: (await import("./Banner-WWNHRGQD.js")).Banner
17384
17390
  }));
17385
17391
  render(
17386
17392
  /* @__PURE__ */ jsx(React.Suspense, { fallback: null, children: /* @__PURE__ */ jsx(BannerPreview, { disable: false }) })
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ganakailabs/cloudeval-cli",
3
- "version": "0.29.1",
3
+ "version": "0.29.3",
4
4
  "license": "LicenseRef-CloudEval-CLI",
5
5
  "type": "module",
6
6
  "description": "CloudEval CLI for cloud architecture, cost, report, automation, and MCP workflows.",
package/sbom.spdx.json CHANGED
@@ -14,7 +14,7 @@
14
14
  {
15
15
  "SPDXID": "SPDXRef-Package-CloudEval-CLI",
16
16
  "name": "CloudEval CLI",
17
- "versionInfo": "0.29.1",
17
+ "versionInfo": "0.29.3",
18
18
  "downloadLocation": "https://github.com/ganakailabs/cloudeval-cli",
19
19
  "filesAnalyzed": false,
20
20
  "licenseConcluded": "LicenseRef-CloudEval-CLI",