@aiready/cli 0.9.45 → 0.9.46

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
@@ -1,8 +1,9 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  __require,
4
- analyzeUnified
5
- } from "./chunk-LLJMKNBI.mjs";
4
+ analyzeUnified,
5
+ scoreUnified
6
+ } from "./chunk-6FOVC2OE.mjs";
6
7
 
7
8
  // src/cli.ts
8
9
  import { Command } from "commander";
@@ -20,7 +21,6 @@ import {
20
21
  handleCLIError as handleCLIError2,
21
22
  getElapsedTime,
22
23
  resolveOutputPath,
23
- calculateOverallScore,
24
24
  formatScore,
25
25
  formatToolScore,
26
26
  calculateTokenBudget,
@@ -28,7 +28,6 @@ import {
28
28
  getModelPreset,
29
29
  getRating,
30
30
  getRatingDisplay,
31
- parseWeightString,
32
31
  getRepoMetadata
33
32
  } from "@aiready/core";
34
33
 
@@ -160,9 +159,7 @@ function truncateArray(arr, cap = 8) {
160
159
  import fs from "fs";
161
160
  import { resolve as resolvePath2 } from "path";
162
161
  import chalk2 from "chalk";
163
- import {
164
- handleCLIError
165
- } from "@aiready/core";
162
+ import { handleCLIError } from "@aiready/core";
166
163
  async function uploadAction(file, options) {
167
164
  const startTime = Date.now();
168
165
  const filePath = resolvePath2(process.cwd(), file);
@@ -170,8 +167,14 @@ async function uploadAction(file, options) {
170
167
  const apiKey = options.apiKey || process.env.AIREADY_API_KEY;
171
168
  if (!apiKey) {
172
169
  console.error(chalk2.red("\u274C API Key is required for upload."));
173
- console.log(chalk2.dim(" Set AIREADY_API_KEY environment variable or use --api-key flag."));
174
- console.log(chalk2.dim(" Get an API key from https://getaiready.dev/dashboard"));
170
+ console.log(
171
+ chalk2.dim(
172
+ " Set AIREADY_API_KEY environment variable or use --api-key flag."
173
+ )
174
+ );
175
+ console.log(
176
+ chalk2.dim(" Get an API key from https://getaiready.dev/dashboard")
177
+ );
175
178
  process.exit(1);
176
179
  }
177
180
  if (!fs.existsSync(filePath)) {
@@ -180,13 +183,16 @@ async function uploadAction(file, options) {
180
183
  }
181
184
  try {
182
185
  console.log(chalk2.blue(`\u{1F680} Uploading report to ${serverUrl}...`));
183
- const reportData = JSON.parse(fs.readFileSync(filePath, "utf-8"));
186
+ console.log(chalk2.dim(` Reading report from ${filePath}...`));
187
+ const reportContent = fs.readFileSync(filePath, "utf-8");
188
+ const reportData = JSON.parse(reportContent);
189
+ console.log(chalk2.dim(` Successfully parsed report JSON.`));
184
190
  const repoId = options.repoId || reportData.repository?.repoId;
185
191
  const res = await fetch(`${serverUrl}/api/analysis/upload`, {
186
192
  method: "POST",
187
193
  headers: {
188
194
  "Content-Type": "application/json",
189
- "Authorization": `Bearer ${apiKey}`
195
+ Authorization: `Bearer ${apiKey}`
190
196
  },
191
197
  body: JSON.stringify({
192
198
  data: reportData,
@@ -194,11 +200,36 @@ async function uploadAction(file, options) {
194
200
  // Might be null, server will handle mapping
195
201
  })
196
202
  });
197
- const result = await res.json();
203
+ const contentType = res.headers.get("content-type");
204
+ let result = {};
205
+ if (contentType?.includes("application/json")) {
206
+ result = await res.json();
207
+ } else {
208
+ const text = await res.text();
209
+ result = { error: text || res.statusText };
210
+ }
198
211
  if (!res.ok) {
199
- console.error(chalk2.red(`\u274C Upload failed: ${result.error || res.statusText}`));
212
+ console.error(
213
+ chalk2.red(`\u274C Upload failed: ${result.error || res.statusText}`)
214
+ );
215
+ if (contentType?.includes("text/html")) {
216
+ console.log(
217
+ chalk2.yellow(
218
+ " Note: Received an HTML response. This often indicates a redirect (e.g., to a login page) or a server error."
219
+ )
220
+ );
221
+ if (result.error?.includes("Redirecting")) {
222
+ console.log(
223
+ chalk2.dim(
224
+ " Detected redirect. Check if the API endpoint requires authentication or has changed."
225
+ )
226
+ );
227
+ }
228
+ }
200
229
  if (res.status === 401) {
201
- console.log(chalk2.dim(" Hint: Your API key may be invalid or expired."));
230
+ console.log(
231
+ chalk2.dim(" Hint: Your API key may be invalid or expired.")
232
+ );
202
233
  }
203
234
  process.exit(1);
204
235
  }
@@ -606,246 +637,136 @@ async function scanAction(directory, options) {
606
637
  void elapsedTime;
607
638
  let scoringResult;
608
639
  if (options.score || finalOptions.scoring?.showBreakdown) {
609
- const toolScores = /* @__PURE__ */ new Map();
610
- if (results.duplicates) {
611
- const { calculatePatternScore } = await import("@aiready/pattern-detect");
640
+ scoringResult = await scoreUnified(results, finalOptions);
641
+ console.log(chalk3.bold("\n\u{1F4CA} AI Readiness Overall Score"));
642
+ console.log(` ${formatScore(scoringResult)}`);
643
+ if (options.compareTo) {
612
644
  try {
613
- const patternScore = calculatePatternScore(
614
- results.duplicates,
615
- results.patterns?.length || 0
645
+ const prevReportStr = readFileSync2(
646
+ resolvePath3(process.cwd(), options.compareTo),
647
+ "utf8"
616
648
  );
617
- const wastedTokens = results.duplicates.reduce((sum, d) => sum + (d.tokenCost || 0), 0);
618
- patternScore.tokenBudget = calculateTokenBudget({
619
- totalContextTokens: wastedTokens * 2,
620
- // Estimated context
621
- wastedTokens: {
622
- duplication: wastedTokens,
623
- fragmentation: 0,
624
- chattiness: 0
625
- }
626
- });
627
- toolScores.set("pattern-detect", patternScore);
628
- } catch (err) {
629
- void err;
630
- }
631
- }
632
- if (results.context) {
633
- const { generateSummary: genContextSummary, calculateContextScore } = await import("@aiready/context-analyzer");
634
- try {
635
- const ctxSummary = genContextSummary(results.context);
636
- const contextScore = calculateContextScore(ctxSummary);
637
- contextScore.tokenBudget = calculateTokenBudget({
638
- totalContextTokens: ctxSummary.totalTokens,
639
- wastedTokens: {
640
- duplication: 0,
641
- fragmentation: ctxSummary.totalPotentialSavings || 0,
642
- chattiness: 0
643
- }
644
- });
645
- toolScores.set("context-analyzer", contextScore);
646
- } catch (err) {
647
- void err;
648
- }
649
- }
650
- if (results.consistency) {
651
- const { calculateConsistencyScore } = await import("@aiready/consistency");
652
- try {
653
- const issues = results.consistency.results?.flatMap((r) => r.issues) || [];
654
- const totalFiles = results.consistency.summary?.filesAnalyzed || 0;
655
- const consistencyScore = calculateConsistencyScore(
656
- issues,
657
- totalFiles
658
- );
659
- toolScores.set("consistency", consistencyScore);
660
- } catch (err) {
661
- void err;
662
- }
663
- }
664
- if (results.aiSignalClarity) {
665
- const { calculateAiSignalClarityScore } = await import("@aiready/ai-signal-clarity");
666
- try {
667
- const hrScore = calculateAiSignalClarityScore(
668
- results.aiSignalClarity
669
- );
670
- toolScores.set("ai-signal-clarity", hrScore);
671
- } catch (err) {
672
- void err;
673
- }
674
- }
675
- if (results.grounding) {
676
- const { calculateGroundingScore } = await import("@aiready/agent-grounding");
677
- try {
678
- const agScore = calculateGroundingScore(results.grounding);
679
- toolScores.set("agent-grounding", agScore);
680
- } catch (err) {
681
- void err;
682
- }
683
- }
684
- if (results.testability) {
685
- const { calculateTestabilityScore } = await import("@aiready/testability");
686
- try {
687
- const tbScore = calculateTestabilityScore(results.testability);
688
- toolScores.set("testability", tbScore);
689
- } catch (err) {
690
- void err;
691
- }
692
- }
693
- if (results.docDrift) {
694
- toolScores.set("doc-drift", {
695
- toolName: "doc-drift",
696
- score: results.docDrift.summary.score,
697
- rawMetrics: results.docDrift.rawData,
698
- factors: [],
699
- recommendations: (results.docDrift.recommendations || []).map(
700
- (action) => ({
701
- action,
702
- estimatedImpact: 5,
703
- priority: "medium"
704
- })
705
- )
706
- });
707
- }
708
- if (results.deps) {
709
- toolScores.set("dependency-health", {
710
- toolName: "dependency-health",
711
- score: results.deps.summary.score,
712
- rawMetrics: results.deps.rawData,
713
- factors: [],
714
- recommendations: (results.deps.recommendations || []).map(
715
- (action) => ({
716
- action,
717
- estimatedImpact: 5,
718
- priority: "medium"
719
- })
720
- )
721
- });
722
- }
723
- if (results.changeAmplification) {
724
- toolScores.set("change-amplification", {
725
- toolName: "change-amplification",
726
- score: results.changeAmplification.summary.score,
727
- rawMetrics: results.changeAmplification.rawData,
728
- factors: [],
729
- recommendations: (results.changeAmplification.recommendations || []).map((action) => ({
730
- action,
731
- estimatedImpact: 5,
732
- priority: "medium"
733
- }))
734
- });
735
- }
736
- const cliWeights = parseWeightString(options.weights);
737
- if (toolScores.size > 0) {
738
- scoringResult = calculateOverallScore(
739
- toolScores,
740
- finalOptions,
741
- cliWeights.size ? cliWeights : void 0
742
- );
743
- console.log(chalk3.bold("\n\u{1F4CA} AI Readiness Overall Score"));
744
- console.log(` ${formatScore(scoringResult)}`);
745
- if (options.compareTo) {
746
- try {
747
- const prevReportStr = readFileSync2(
748
- resolvePath3(process.cwd(), options.compareTo),
749
- "utf8"
750
- );
751
- const prevReport = JSON.parse(prevReportStr);
752
- const prevScore = prevReport.scoring?.score || prevReport.scoring?.overallScore;
753
- if (typeof prevScore === "number") {
754
- const diff = scoringResult.overall - prevScore;
755
- const diffStr = diff > 0 ? `+${diff}` : String(diff);
756
- console.log();
757
- if (diff > 0) {
758
- console.log(
759
- chalk3.green(
760
- ` \u{1F4C8} Trend: ${diffStr} compared to ${options.compareTo} (${prevScore} \u2192 ${scoringResult.overall})`
761
- )
762
- );
763
- } else if (diff < 0) {
764
- console.log(
765
- chalk3.red(
766
- ` \u{1F4C9} Trend: ${diffStr} compared to ${options.compareTo} (${prevScore} \u2192 ${scoringResult.overall})`
767
- )
768
- );
769
- } else {
770
- console.log(
771
- chalk3.blue(
772
- ` \u2796 Trend: No change compared to ${options.compareTo} (${prevScore} \u2192 ${scoringResult.overall})`
773
- )
774
- );
775
- }
776
- scoringResult.trend = {
777
- previousScore: prevScore,
778
- difference: diff
779
- };
649
+ const prevReport = JSON.parse(prevReportStr);
650
+ const prevScore = prevReport.scoring?.score || prevReport.scoring?.overallScore;
651
+ if (typeof prevScore === "number") {
652
+ const diff = scoringResult.overall - prevScore;
653
+ const diffStr = diff > 0 ? `+${diff}` : String(diff);
654
+ console.log();
655
+ if (diff > 0) {
656
+ console.log(
657
+ chalk3.green(
658
+ ` \u{1F4C8} Trend: ${diffStr} compared to ${options.compareTo} (${prevScore} \u2192 ${scoringResult.overall})`
659
+ )
660
+ );
661
+ } else if (diff < 0) {
662
+ console.log(
663
+ chalk3.red(
664
+ ` \u{1F4C9} Trend: ${diffStr} compared to ${options.compareTo} (${prevScore} \u2192 ${scoringResult.overall})`
665
+ )
666
+ );
780
667
  } else {
781
668
  console.log(
782
- chalk3.yellow(
783
- `
784
- \u26A0\uFE0F Previous report at ${options.compareTo} does not contain an overall score.`
669
+ chalk3.blue(
670
+ ` \u2796 Trend: No change compared to ${options.compareTo} (${prevScore} \u2192 ${scoringResult.overall})`
785
671
  )
786
672
  );
787
673
  }
788
- } catch (e) {
789
- void e;
674
+ scoringResult.trend = {
675
+ previousScore: prevScore,
676
+ difference: diff
677
+ };
678
+ } else {
790
679
  console.log(
791
680
  chalk3.yellow(
792
681
  `
793
- \u26A0\uFE0F Could not read or parse previous report at ${options.compareTo}.`
682
+ \u26A0\uFE0F Previous report at ${options.compareTo} does not contain an overall score.`
794
683
  )
795
684
  );
796
685
  }
686
+ } catch (e) {
687
+ void e;
688
+ console.log(
689
+ chalk3.yellow(
690
+ `
691
+ \u26A0\uFE0F Could not read or parse previous report at ${options.compareTo}.`
692
+ )
693
+ );
797
694
  }
798
- const totalWastedDuplication = Array.from(toolScores.values()).reduce((sum, s) => sum + (s.tokenBudget?.wastedTokens.bySource.duplication || 0), 0);
799
- const totalWastedFragmentation = Array.from(toolScores.values()).reduce((sum, s) => sum + (s.tokenBudget?.wastedTokens.bySource.fragmentation || 0), 0);
800
- const totalContext = Math.max(...Array.from(toolScores.values()).map((s) => s.tokenBudget?.totalContextTokens || 0));
801
- if (totalContext > 0) {
802
- const unifiedBudget = calculateTokenBudget({
803
- totalContextTokens: totalContext,
804
- wastedTokens: {
805
- duplication: totalWastedDuplication,
806
- fragmentation: totalWastedFragmentation,
807
- chattiness: 0
808
- }
809
- });
810
- const targetModel = options.model || "claude-4.6";
811
- const modelPreset = getModelPreset(targetModel);
812
- const costEstimate = estimateCostFromBudget(unifiedBudget, modelPreset);
813
- const barWidth = 20;
814
- const filled = Math.round(unifiedBudget.efficiencyRatio * barWidth);
815
- const bar = chalk3.green("\u2588".repeat(filled)) + chalk3.dim("\u2591".repeat(barWidth - filled));
816
- console.log(chalk3.bold("\n\u{1F4CA} AI Token Budget Analysis (v0.13)"));
817
- console.log(` Efficiency: [${bar}] ${(unifiedBudget.efficiencyRatio * 100).toFixed(0)}%`);
818
- console.log(` Total Context: ${chalk3.bold(unifiedBudget.totalContextTokens.toLocaleString())} tokens`);
819
- console.log(` Wasted Tokens: ${chalk3.red(unifiedBudget.wastedTokens.total.toLocaleString())} (${(unifiedBudget.wastedTokens.total / unifiedBudget.totalContextTokens * 100).toFixed(1)}%)`);
820
- console.log(` Waste Breakdown:`);
821
- console.log(` \u2022 Duplication: ${unifiedBudget.wastedTokens.bySource.duplication.toLocaleString()} tokens`);
822
- console.log(` \u2022 Fragmentation: ${unifiedBudget.wastedTokens.bySource.fragmentation.toLocaleString()} tokens`);
823
- console.log(` Potential Savings: ${chalk3.green(unifiedBudget.potentialRetrievableTokens.toLocaleString())} tokens retrievable`);
824
- console.log(`
825
- Est. Monthly Cost (${modelPreset.name}): ${chalk3.bold("$" + costEstimate.total)} [range: $${costEstimate.range[0]}-$${costEstimate.range[1]}]`);
826
- scoringResult.tokenBudget = unifiedBudget;
827
- scoringResult.costEstimate = {
828
- model: modelPreset.name,
829
- ...costEstimate
830
- };
831
- }
832
- if (scoringResult.breakdown && scoringResult.breakdown.length > 0) {
833
- console.log(chalk3.bold("\nTool breakdown:"));
695
+ }
696
+ const totalWastedDuplication = (scoringResult.breakdown || []).reduce(
697
+ (sum, s) => sum + (s.tokenBudget?.wastedTokens.bySource.duplication || 0),
698
+ 0
699
+ );
700
+ const totalWastedFragmentation = (scoringResult.breakdown || []).reduce(
701
+ (sum, s) => sum + (s.tokenBudget?.wastedTokens.bySource.fragmentation || 0),
702
+ 0
703
+ );
704
+ const totalContext = Math.max(
705
+ ...(scoringResult.breakdown || []).map(
706
+ (s) => s.tokenBudget?.totalContextTokens || 0
707
+ )
708
+ );
709
+ if (totalContext > 0) {
710
+ const unifiedBudget = calculateTokenBudget({
711
+ totalContextTokens: totalContext,
712
+ wastedTokens: {
713
+ duplication: totalWastedDuplication,
714
+ fragmentation: totalWastedFragmentation,
715
+ chattiness: 0
716
+ }
717
+ });
718
+ const targetModel = options.model || "claude-4.6";
719
+ const modelPreset = getModelPreset(targetModel);
720
+ const costEstimate = estimateCostFromBudget(unifiedBudget, modelPreset);
721
+ const barWidth = 20;
722
+ const filled = Math.round(unifiedBudget.efficiencyRatio * barWidth);
723
+ const bar = chalk3.green("\u2588".repeat(filled)) + chalk3.dim("\u2591".repeat(barWidth - filled));
724
+ console.log(chalk3.bold("\n\u{1F4CA} AI Token Budget Analysis (v0.13)"));
725
+ console.log(
726
+ ` Efficiency: [${bar}] ${(unifiedBudget.efficiencyRatio * 100).toFixed(0)}%`
727
+ );
728
+ console.log(
729
+ ` Total Context: ${chalk3.bold(unifiedBudget.totalContextTokens.toLocaleString())} tokens`
730
+ );
731
+ console.log(
732
+ ` Wasted Tokens: ${chalk3.red(unifiedBudget.wastedTokens.total.toLocaleString())} (${(unifiedBudget.wastedTokens.total / unifiedBudget.totalContextTokens * 100).toFixed(1)}%)`
733
+ );
734
+ console.log(` Waste Breakdown:`);
735
+ console.log(
736
+ ` \u2022 Duplication: ${unifiedBudget.wastedTokens.bySource.duplication.toLocaleString()} tokens`
737
+ );
738
+ console.log(
739
+ ` \u2022 Fragmentation: ${unifiedBudget.wastedTokens.bySource.fragmentation.toLocaleString()} tokens`
740
+ );
741
+ console.log(
742
+ ` Potential Savings: ${chalk3.green(unifiedBudget.potentialRetrievableTokens.toLocaleString())} tokens retrievable`
743
+ );
744
+ console.log(
745
+ `
746
+ Est. Monthly Cost (${modelPreset.name}): ${chalk3.bold("$" + costEstimate.total)} [range: $${costEstimate.range[0]}-$${costEstimate.range[1]}]`
747
+ );
748
+ scoringResult.tokenBudget = unifiedBudget;
749
+ scoringResult.costEstimate = {
750
+ model: modelPreset.name,
751
+ ...costEstimate
752
+ };
753
+ }
754
+ if (scoringResult.breakdown && scoringResult.breakdown.length > 0) {
755
+ console.log(chalk3.bold("\nTool breakdown:"));
756
+ scoringResult.breakdown.forEach((tool) => {
757
+ const rating = getRating(tool.score);
758
+ const rd = getRatingDisplay(rating);
759
+ console.log(
760
+ ` - ${tool.toolName}: ${tool.score}/100 (${rating}) ${rd.emoji}`
761
+ );
762
+ });
763
+ console.log();
764
+ if (finalOptions.scoring?.showBreakdown) {
765
+ console.log(chalk3.bold("Detailed tool breakdown:"));
834
766
  scoringResult.breakdown.forEach((tool) => {
835
- const rating = getRating(tool.score);
836
- const rd = getRatingDisplay(rating);
837
- console.log(
838
- ` - ${tool.toolName}: ${tool.score}/100 (${rating}) ${rd.emoji}`
839
- );
767
+ console.log(formatToolScore(tool));
840
768
  });
841
769
  console.log();
842
- if (finalOptions.scoring?.showBreakdown) {
843
- console.log(chalk3.bold("Detailed tool breakdown:"));
844
- scoringResult.breakdown.forEach((tool) => {
845
- console.log(formatToolScore(tool));
846
- });
847
- console.log();
848
- }
849
770
  }
850
771
  }
851
772
  }
package/dist/index.js CHANGED
@@ -31,12 +31,14 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
31
31
  var index_exports = {};
32
32
  __export(index_exports, {
33
33
  analyzeUnified: () => analyzeUnified,
34
- generateUnifiedSummary: () => generateUnifiedSummary
34
+ generateUnifiedSummary: () => generateUnifiedSummary,
35
+ scoreUnified: () => scoreUnified
35
36
  });
36
37
  module.exports = __toCommonJS(index_exports);
37
38
  var import_pattern_detect = require("@aiready/pattern-detect");
38
39
  var import_context_analyzer = require("@aiready/context-analyzer");
39
40
  var import_consistency = require("@aiready/consistency");
41
+ var import_core = require("@aiready/core");
40
42
  var severityOrder = {
41
43
  critical: 4,
42
44
  major: 3,
@@ -211,6 +213,150 @@ async function analyzeUnified(options) {
211
213
  result.summary.executionTime = Date.now() - startTime;
212
214
  return result;
213
215
  }
216
+ async function scoreUnified(results, options) {
217
+ const toolScores = /* @__PURE__ */ new Map();
218
+ if (results.duplicates) {
219
+ const { calculatePatternScore } = await import("@aiready/pattern-detect");
220
+ try {
221
+ const patternScore = calculatePatternScore(
222
+ results.duplicates,
223
+ results.patterns?.length || 0
224
+ );
225
+ const wastedTokens = results.duplicates.reduce(
226
+ (sum, d) => sum + (d.tokenCost || 0),
227
+ 0
228
+ );
229
+ patternScore.tokenBudget = (0, import_core.calculateTokenBudget)({
230
+ totalContextTokens: wastedTokens * 2,
231
+ // Estimated context
232
+ wastedTokens: {
233
+ duplication: wastedTokens,
234
+ fragmentation: 0,
235
+ chattiness: 0
236
+ }
237
+ });
238
+ toolScores.set("pattern-detect", patternScore);
239
+ } catch (err) {
240
+ void err;
241
+ }
242
+ }
243
+ if (results.context) {
244
+ const { generateSummary: genContextSummary, calculateContextScore } = await import("@aiready/context-analyzer");
245
+ try {
246
+ const ctxSummary = genContextSummary(results.context);
247
+ const contextScore = calculateContextScore(ctxSummary);
248
+ contextScore.tokenBudget = (0, import_core.calculateTokenBudget)({
249
+ totalContextTokens: ctxSummary.totalTokens,
250
+ wastedTokens: {
251
+ duplication: 0,
252
+ fragmentation: ctxSummary.totalPotentialSavings || 0,
253
+ chattiness: 0
254
+ }
255
+ });
256
+ toolScores.set("context-analyzer", contextScore);
257
+ } catch (err) {
258
+ void err;
259
+ }
260
+ }
261
+ if (results.consistency) {
262
+ const { calculateConsistencyScore } = await import("@aiready/consistency");
263
+ try {
264
+ const issues = results.consistency.results?.flatMap((r) => r.issues) || [];
265
+ const totalFiles = results.consistency.summary?.filesAnalyzed || 0;
266
+ const consistencyScore = calculateConsistencyScore(issues, totalFiles);
267
+ toolScores.set("consistency", consistencyScore);
268
+ } catch (err) {
269
+ void err;
270
+ }
271
+ }
272
+ if (results.aiSignalClarity) {
273
+ const { calculateAiSignalClarityScore } = await import("@aiready/ai-signal-clarity");
274
+ try {
275
+ const hrScore = calculateAiSignalClarityScore(results.aiSignalClarity);
276
+ toolScores.set("ai-signal-clarity", hrScore);
277
+ } catch (err) {
278
+ void err;
279
+ }
280
+ }
281
+ if (results.grounding) {
282
+ const { calculateGroundingScore } = await import("@aiready/agent-grounding");
283
+ try {
284
+ const agScore = calculateGroundingScore(results.grounding);
285
+ toolScores.set("agent-grounding", agScore);
286
+ } catch (err) {
287
+ void err;
288
+ }
289
+ }
290
+ if (results.testability) {
291
+ const { calculateTestabilityScore } = await import("@aiready/testability");
292
+ try {
293
+ const tbScore = calculateTestabilityScore(results.testability);
294
+ toolScores.set("testability", tbScore);
295
+ } catch (err) {
296
+ void err;
297
+ }
298
+ }
299
+ if (results.docDrift) {
300
+ toolScores.set("doc-drift", {
301
+ toolName: "doc-drift",
302
+ score: results.docDrift.summary.score,
303
+ rawMetrics: results.docDrift.rawData,
304
+ factors: [],
305
+ recommendations: (results.docDrift.recommendations || []).map(
306
+ (action) => ({
307
+ action,
308
+ estimatedImpact: 5,
309
+ priority: "medium"
310
+ })
311
+ )
312
+ });
313
+ }
314
+ if (results.deps) {
315
+ toolScores.set("dependency-health", {
316
+ toolName: "dependency-health",
317
+ score: results.deps.summary.score,
318
+ rawMetrics: results.deps.rawData,
319
+ factors: [],
320
+ recommendations: (results.deps.recommendations || []).map(
321
+ (action) => ({
322
+ action,
323
+ estimatedImpact: 5,
324
+ priority: "medium"
325
+ })
326
+ )
327
+ });
328
+ }
329
+ if (results.changeAmplification) {
330
+ toolScores.set("change-amplification", {
331
+ toolName: "change-amplification",
332
+ score: results.changeAmplification.summary.score,
333
+ rawMetrics: results.changeAmplification.rawData,
334
+ factors: [],
335
+ recommendations: (results.changeAmplification.recommendations || []).map(
336
+ (action) => ({
337
+ action,
338
+ estimatedImpact: 5,
339
+ priority: "medium"
340
+ })
341
+ )
342
+ });
343
+ }
344
+ if (toolScores.size === 0) {
345
+ return {
346
+ overall: 0,
347
+ rating: "Critical",
348
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
349
+ toolsUsed: [],
350
+ breakdown: [],
351
+ calculation: {
352
+ formula: "0 / 0 = 0",
353
+ weights: {},
354
+ normalized: "0 / 0 = 0"
355
+ }
356
+ };
357
+ }
358
+ return (0, import_core.calculateOverallScore)(toolScores, options, void 0);
359
+ }
214
360
  function generateUnifiedSummary(result) {
215
361
  const { summary } = result;
216
362
  let output = `\u{1F680} AIReady Analysis Complete
@@ -266,5 +412,6 @@ function generateUnifiedSummary(result) {
266
412
  // Annotate the CommonJS export names for ESM import in node:
267
413
  0 && (module.exports = {
268
414
  analyzeUnified,
269
- generateUnifiedSummary
415
+ generateUnifiedSummary,
416
+ scoreUnified
270
417
  });
package/dist/index.mjs CHANGED
@@ -1,8 +1,10 @@
1
1
  import {
2
2
  analyzeUnified,
3
- generateUnifiedSummary
4
- } from "./chunk-LLJMKNBI.mjs";
3
+ generateUnifiedSummary,
4
+ scoreUnified
5
+ } from "./chunk-6FOVC2OE.mjs";
5
6
  export {
6
7
  analyzeUnified,
7
- generateUnifiedSummary
8
+ generateUnifiedSummary,
9
+ scoreUnified
8
10
  };