@aiready/cli 0.7.18 → 0.7.20

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,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
- analyzeUnified,
4
- generateUnifiedSummary
5
- } from "./chunk-P3XAXCTK.mjs";
3
+ analyzeUnified
4
+ } from "./chunk-3SG2GLFJ.mjs";
6
5
 
7
6
  // src/cli.ts
8
7
  import { Command } from "commander";
@@ -16,7 +15,9 @@ import {
16
15
  getElapsedTime,
17
16
  resolveOutputPath,
18
17
  calculateOverallScore,
18
+ formatScore,
19
19
  formatToolScore,
20
+ getRating,
20
21
  getRatingDisplay,
21
22
  parseWeightString
22
23
  } from "@aiready/core";
@@ -46,103 +47,210 @@ program.command("scan").description("Run unified analysis on a codebase").argume
46
47
  if (baseOptions.tools.includes("patterns")) {
47
48
  const { getSmartDefaults } = await import("@aiready/pattern-detect");
48
49
  const patternSmartDefaults = await getSmartDefaults(directory, baseOptions);
49
- finalOptions = { ...patternSmartDefaults, ...finalOptions };
50
+ finalOptions = { ...patternSmartDefaults, ...finalOptions, ...baseOptions };
50
51
  }
51
- const results = await analyzeUnified(finalOptions);
52
+ console.log(chalk.cyan("\n=== AIReady Run Preview ==="));
53
+ console.log(chalk.white("Tools to run:"), (finalOptions.tools || ["patterns", "context", "consistency"]).join(", "));
54
+ console.log(chalk.white("Will use settings from config and defaults."));
55
+ const truncate = (arr, cap = 8) => {
56
+ if (!Array.isArray(arr)) return "";
57
+ const shown = arr.slice(0, cap).map((v) => String(v));
58
+ const more = arr.length - shown.length;
59
+ return shown.join(", ") + (more > 0 ? `, ... (+${more} more)` : "");
60
+ };
61
+ console.log(chalk.white("\nGeneral settings:"));
62
+ if (finalOptions.rootDir) console.log(` rootDir: ${chalk.bold(String(finalOptions.rootDir))}`);
63
+ if (finalOptions.include) console.log(` include: ${chalk.bold(truncate(finalOptions.include, 6))}`);
64
+ if (finalOptions.exclude) console.log(` exclude: ${chalk.bold(truncate(finalOptions.exclude, 6))}`);
65
+ if (finalOptions["pattern-detect"] || finalOptions.minSimilarity) {
66
+ const pd = finalOptions["pattern-detect"] || {
67
+ minSimilarity: finalOptions.minSimilarity,
68
+ minLines: finalOptions.minLines,
69
+ approx: finalOptions.approx,
70
+ minSharedTokens: finalOptions.minSharedTokens,
71
+ maxCandidatesPerBlock: finalOptions.maxCandidatesPerBlock,
72
+ batchSize: finalOptions.batchSize,
73
+ streamResults: finalOptions.streamResults,
74
+ severity: finalOptions.severity,
75
+ includeTests: finalOptions.includeTests
76
+ };
77
+ console.log(chalk.white("\nPattern-detect settings:"));
78
+ console.log(` minSimilarity: ${chalk.bold(pd.minSimilarity ?? "default")}`);
79
+ console.log(` minLines: ${chalk.bold(pd.minLines ?? "default")}`);
80
+ if (pd.approx !== void 0) console.log(` approx: ${chalk.bold(String(pd.approx))}`);
81
+ if (pd.minSharedTokens !== void 0) console.log(` minSharedTokens: ${chalk.bold(String(pd.minSharedTokens))}`);
82
+ if (pd.maxCandidatesPerBlock !== void 0) console.log(` maxCandidatesPerBlock: ${chalk.bold(String(pd.maxCandidatesPerBlock))}`);
83
+ if (pd.batchSize !== void 0) console.log(` batchSize: ${chalk.bold(String(pd.batchSize))}`);
84
+ if (pd.streamResults !== void 0) console.log(` streamResults: ${chalk.bold(String(pd.streamResults))}`);
85
+ if (pd.severity !== void 0) console.log(` severity: ${chalk.bold(String(pd.severity))}`);
86
+ if (pd.includeTests !== void 0) console.log(` includeTests: ${chalk.bold(String(pd.includeTests))}`);
87
+ }
88
+ if (finalOptions["context-analyzer"] || finalOptions.maxDepth) {
89
+ const ca = finalOptions["context-analyzer"] || {
90
+ maxDepth: finalOptions.maxDepth,
91
+ maxContextBudget: finalOptions.maxContextBudget,
92
+ minCohesion: finalOptions.minCohesion,
93
+ maxFragmentation: finalOptions.maxFragmentation,
94
+ includeNodeModules: finalOptions.includeNodeModules
95
+ };
96
+ console.log(chalk.white("\nContext-analyzer settings:"));
97
+ console.log(` maxDepth: ${chalk.bold(ca.maxDepth ?? "default")}`);
98
+ console.log(` maxContextBudget: ${chalk.bold(ca.maxContextBudget ?? "default")}`);
99
+ if (ca.minCohesion !== void 0) console.log(` minCohesion: ${chalk.bold(String(ca.minCohesion))}`);
100
+ if (ca.maxFragmentation !== void 0) console.log(` maxFragmentation: ${chalk.bold(String(ca.maxFragmentation))}`);
101
+ if (ca.includeNodeModules !== void 0) console.log(` includeNodeModules: ${chalk.bold(String(ca.includeNodeModules))}`);
102
+ }
103
+ if (finalOptions.consistency) {
104
+ const c = finalOptions.consistency;
105
+ console.log(chalk.white("\nConsistency settings:"));
106
+ console.log(` checkNaming: ${chalk.bold(String(c.checkNaming ?? true))}`);
107
+ console.log(` checkPatterns: ${chalk.bold(String(c.checkPatterns ?? true))}`);
108
+ console.log(` checkArchitecture: ${chalk.bold(String(c.checkArchitecture ?? false))}`);
109
+ if (c.minSeverity) console.log(` minSeverity: ${chalk.bold(c.minSeverity)}`);
110
+ if (c.acceptedAbbreviations) console.log(` acceptedAbbreviations: ${chalk.bold(truncate(c.acceptedAbbreviations, 8))}`);
111
+ if (c.shortWords) console.log(` shortWords: ${chalk.bold(truncate(c.shortWords, 8))}`);
112
+ }
113
+ console.log(chalk.white("\nStarting analysis..."));
114
+ const progressCallback = (event) => {
115
+ console.log(chalk.cyan(`
116
+ --- ${event.tool.toUpperCase()} RESULTS ---`));
117
+ try {
118
+ if (event.tool === "patterns") {
119
+ const pr = event.data;
120
+ console.log(` Duplicate patterns: ${chalk.bold(String(pr.duplicates?.length || 0))}`);
121
+ console.log(` Files with pattern issues: ${chalk.bold(String(pr.results?.length || 0))}`);
122
+ if (pr.duplicates && pr.duplicates.length > 0) {
123
+ pr.duplicates.slice(0, 5).forEach((d, i) => {
124
+ console.log(` ${i + 1}. ${d.file1.split("/").pop()} \u2194 ${d.file2.split("/").pop()} (sim=${(d.similarity * 100).toFixed(1)}%)`);
125
+ });
126
+ }
127
+ if (pr.results && pr.results.length > 0) {
128
+ console.log(` Top files with pattern issues:`);
129
+ const sortedByIssues = [...pr.results].sort((a, b) => (b.issues?.length || 0) - (a.issues?.length || 0));
130
+ sortedByIssues.slice(0, 5).forEach((r, i) => {
131
+ console.log(` ${i + 1}. ${r.fileName.split("/").pop()} - ${r.issues.length} issue(s)`);
132
+ });
133
+ }
134
+ if (pr.groups && pr.groups.length >= 0) {
135
+ console.log(` \u2705 Grouped ${chalk.bold(String(pr.duplicates?.length || 0))} duplicates into ${chalk.bold(String(pr.groups.length))} file pairs`);
136
+ }
137
+ if (pr.clusters && pr.clusters.length >= 0) {
138
+ console.log(` \u2705 Created ${chalk.bold(String(pr.clusters.length))} refactor clusters`);
139
+ pr.clusters.slice(0, 3).forEach((cl, idx) => {
140
+ const files = (cl.files || []).map((f) => f.path.split("/").pop()).join(", ");
141
+ console.log(` ${idx + 1}. ${files} (${cl.tokenCost || "n/a"} tokens)`);
142
+ });
143
+ }
144
+ } else if (event.tool === "context") {
145
+ const cr = event.data;
146
+ console.log(` Context issues found: ${chalk.bold(String(cr.length || 0))}`);
147
+ cr.slice(0, 5).forEach((c, i) => {
148
+ const msg = c.message ? ` - ${c.message}` : "";
149
+ console.log(` ${i + 1}. ${c.file} (${c.severity || "n/a"})${msg}`);
150
+ });
151
+ } else if (event.tool === "consistency") {
152
+ const rep = event.data;
153
+ console.log(` Consistency totalIssues: ${chalk.bold(String(rep.summary?.totalIssues || 0))}`);
154
+ if (rep.results && rep.results.length > 0) {
155
+ const fileMap = /* @__PURE__ */ new Map();
156
+ rep.results.forEach((r) => {
157
+ (r.issues || []).forEach((issue) => {
158
+ const file = issue.location?.file || r.file || "unknown";
159
+ if (!fileMap.has(file)) fileMap.set(file, []);
160
+ fileMap.get(file).push(issue);
161
+ });
162
+ });
163
+ const files = Array.from(fileMap.entries()).sort((a, b) => b[1].length - a[1].length);
164
+ const topFiles = files.slice(0, 10);
165
+ topFiles.forEach(([file, issues], idx) => {
166
+ const counts = issues.reduce((acc, it) => {
167
+ const s = (it.severity || "info").toLowerCase();
168
+ acc[s] = (acc[s] || 0) + 1;
169
+ return acc;
170
+ }, {});
171
+ const sample = issues.find((it) => it.severity === "critical" || it.severity === "major") || issues[0];
172
+ const sampleMsg = sample ? ` \u2014 ${sample.message}` : "";
173
+ console.log(` ${idx + 1}. ${file} \u2014 ${issues.length} issue(s) (critical:${counts.critical || 0} major:${counts.major || 0} minor:${counts.minor || 0} info:${counts.info || 0})${sampleMsg}`);
174
+ });
175
+ const remaining = files.length - topFiles.length;
176
+ if (remaining > 0) {
177
+ console.log(chalk.dim(` ... and ${remaining} more files with issues (use --output json for full details)`));
178
+ }
179
+ }
180
+ }
181
+ } catch (err) {
182
+ }
183
+ };
184
+ const results = await analyzeUnified({ ...finalOptions, progressCallback, suppressToolConfig: true });
185
+ console.log(chalk.cyan("\n=== AIReady Run Summary ==="));
186
+ console.log(chalk.white("Tools run:"), (finalOptions.tools || ["patterns", "context", "consistency"]).join(", "));
187
+ console.log(chalk.cyan("\nResults summary:"));
188
+ console.log(` Total issues (all tools): ${chalk.bold(String(results.summary.totalIssues || 0))}`);
189
+ if (results.duplicates) console.log(` Duplicate patterns found: ${chalk.bold(String(results.duplicates.length || 0))}`);
190
+ if (results.patterns) console.log(` Pattern files with issues: ${chalk.bold(String(results.patterns.length || 0))}`);
191
+ if (results.context) console.log(` Context issues: ${chalk.bold(String(results.context.length || 0))}`);
192
+ if (results.consistency) console.log(` Consistency issues: ${chalk.bold(String(results.consistency.summary.totalIssues || 0))}`);
193
+ console.log(chalk.cyan("===========================\n"));
52
194
  const elapsedTime = getElapsedTime(startTime);
53
195
  let scoringResult;
54
196
  if (options.score || finalOptions.scoring?.showBreakdown) {
55
197
  const toolScores = /* @__PURE__ */ new Map();
56
- if (results.patterns && baseOptions.tools.includes("patterns")) {
198
+ if (results.duplicates) {
57
199
  const { calculatePatternScore } = await import("@aiready/pattern-detect");
58
- const duplicates = results.duplicates || [];
59
- const score = calculatePatternScore(duplicates, results.patterns.length);
60
- toolScores.set("pattern-detect", score);
200
+ try {
201
+ const patternScore = calculatePatternScore(results.duplicates, results.patterns?.length || 0);
202
+ toolScores.set("pattern-detect", patternScore);
203
+ } catch (err) {
204
+ }
61
205
  }
62
- if (results.context && baseOptions.tools.includes("context")) {
63
- const { calculateContextScore } = await import("@aiready/context-analyzer");
64
- const summary = {
65
- avgContextBudget: results.context.reduce((sum, r) => sum + r.contextBudget, 0) / results.context.length,
66
- maxContextBudget: Math.max(...results.context.map((r) => r.contextBudget)),
67
- avgImportDepth: results.context.reduce((sum, r) => sum + r.importDepth, 0) / results.context.length,
68
- maxImportDepth: Math.max(...results.context.map((r) => r.importDepth)),
69
- avgFragmentation: results.context.reduce((sum, r) => sum + r.fragmentationScore, 0) / results.context.length,
70
- criticalIssues: results.context.filter((r) => r.severity === "critical").length,
71
- majorIssues: results.context.filter((r) => r.severity === "major").length
72
- };
73
- const score = calculateContextScore(summary);
74
- toolScores.set("context-analyzer", score);
206
+ if (results.context) {
207
+ const { generateSummary: genContextSummary, calculateContextScore } = await import("@aiready/context-analyzer");
208
+ try {
209
+ const ctxSummary = genContextSummary(results.context);
210
+ const contextScore = calculateContextScore(ctxSummary);
211
+ toolScores.set("context-analyzer", contextScore);
212
+ } catch (err) {
213
+ }
75
214
  }
76
- if (results.consistency && baseOptions.tools.includes("consistency")) {
215
+ if (results.consistency) {
77
216
  const { calculateConsistencyScore } = await import("@aiready/consistency");
78
- const issues = results.consistency.results?.flatMap((r) => r.issues) || [];
79
- const score = calculateConsistencyScore(issues, results.consistency.summary.filesAnalyzed);
80
- toolScores.set("consistency", score);
81
- }
82
- const cliWeights = options.weights ? parseWeightString(options.weights) : void 0;
83
- scoringResult = calculateOverallScore(toolScores, finalOptions, cliWeights);
84
- if (options.threshold) {
85
- const threshold = parseFloat(options.threshold);
86
- if (scoringResult.overall < threshold) {
87
- console.error(chalk.red(`
88
- \u274C Score ${scoringResult.overall} is below threshold ${threshold}
89
- `));
90
- process.exit(1);
217
+ try {
218
+ const issues = results.consistency.results?.flatMap((r) => r.issues) || [];
219
+ const totalFiles = results.consistency.summary?.filesAnalyzed || 0;
220
+ const consistencyScore = calculateConsistencyScore(issues, totalFiles);
221
+ toolScores.set("consistency", consistencyScore);
222
+ } catch (err) {
91
223
  }
92
224
  }
93
- }
94
- const outputFormat = options.output || finalOptions.output?.format || "console";
95
- const userOutputFile = options.outputFile || finalOptions.output?.file;
96
- if (outputFormat === "json") {
97
- const outputData = {
98
- ...results,
99
- summary: {
100
- ...results.summary,
101
- executionTime: parseFloat(elapsedTime)
102
- },
103
- ...scoringResult && { scoring: scoringResult }
104
- };
105
- const outputPath = resolveOutputPath(
106
- userOutputFile,
107
- `aiready-scan-${(/* @__PURE__ */ new Date()).toISOString().split("T")[0]}.json`,
108
- directory
109
- );
110
- handleJSONOutput(outputData, outputPath, `\u2705 Results saved to ${outputPath}`);
111
- } else {
112
- console.log(generateUnifiedSummary(results));
113
- if (scoringResult) {
114
- const terminalWidth = process.stdout.columns || 80;
115
- const dividerWidth = Math.min(60, terminalWidth - 2);
116
- const divider = "\u2501".repeat(dividerWidth);
117
- console.log(chalk.cyan("\n" + divider));
118
- console.log(chalk.bold.white(" AI READINESS SCORE"));
119
- console.log(chalk.cyan(divider) + "\n");
120
- const { emoji, color } = getRatingDisplay(scoringResult.rating);
121
- const scoreColor = color === "green" ? chalk.green : color === "blue" ? chalk.blue : color === "yellow" ? chalk.yellow : chalk.red;
122
- console.log(` ${emoji} Overall Score: ${scoreColor.bold(scoringResult.overall + "/100")} (${chalk.bold(scoringResult.rating)})`);
123
- console.log(` ${chalk.dim("Timestamp:")} ${new Date(scoringResult.timestamp).toLocaleString()}
124
- `);
125
- if (scoringResult.breakdown.length > 0) {
126
- console.log(chalk.bold(" Component Scores:\n"));
225
+ const cliWeights = parseWeightString(options.weights);
226
+ if (toolScores.size > 0) {
227
+ scoringResult = calculateOverallScore(toolScores, finalOptions, cliWeights.size ? cliWeights : void 0);
228
+ console.log(chalk.bold("\n\u{1F4CA} AI Readiness Overall Score"));
229
+ console.log(` ${formatScore(scoringResult)}`);
230
+ if (scoringResult.breakdown && scoringResult.breakdown.length > 0) {
231
+ console.log(chalk.bold("\nTool breakdown:"));
127
232
  scoringResult.breakdown.forEach((tool) => {
128
- const toolEmoji = tool.toolName === "pattern-detect" ? "\u{1F50D}" : tool.toolName === "context-analyzer" ? "\u{1F9E0}" : "\u{1F3F7}\uFE0F";
129
- const weight = scoringResult.calculation.weights[tool.toolName];
130
- console.log(` ${toolEmoji} ${chalk.white(tool.toolName.padEnd(20))} ${scoreColor(tool.score + "/100")} ${chalk.dim(`(weight: ${weight})`)}`);
233
+ const rating = getRating(tool.score);
234
+ const rd = getRatingDisplay(rating);
235
+ console.log(` - ${tool.toolName}: ${tool.score}/100 (${rating}) ${rd.emoji}`);
131
236
  });
132
237
  console.log();
238
+ if (finalOptions.scoring?.showBreakdown) {
239
+ console.log(chalk.bold("Detailed tool breakdown:"));
240
+ scoringResult.breakdown.forEach((tool) => {
241
+ console.log(formatToolScore(tool));
242
+ });
243
+ console.log();
244
+ }
133
245
  }
134
- console.log(chalk.dim(` Weighted Formula: ${scoringResult.calculation.formula}`));
135
- console.log(chalk.dim(` Normalized Score: ${scoringResult.calculation.normalized}
136
- `));
137
- const allRecommendations = scoringResult.breakdown.flatMap((tool) => tool.recommendations || []).sort((a, b) => b.estimatedImpact - a.estimatedImpact).slice(0, 5);
138
- if (allRecommendations.length > 0) {
139
- console.log(chalk.bold(" Top Recommendations:\n"));
140
- allRecommendations.forEach((rec, i) => {
141
- const priorityIcon = rec.priority === "high" ? "\u{1F534}" : rec.priority === "medium" ? "\u{1F7E1}" : "\u{1F535}";
142
- console.log(` ${i + 1}. ${priorityIcon} ${rec.action}`);
143
- console.log(` ${chalk.dim(`Impact: +${rec.estimatedImpact} points`)}
144
- `);
145
- });
246
+ const outputFormat = options.output || finalOptions.output?.format || "console";
247
+ const userOutputFile = options.outputFile || finalOptions.output?.file;
248
+ if (outputFormat === "json") {
249
+ const dateStr = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
250
+ const defaultFilename = `aiready-scan-${dateStr}.json`;
251
+ const outputPath = resolveOutputPath(userOutputFile, defaultFilename, directory);
252
+ const outputData = { ...results, scoring: scoringResult };
253
+ handleJSONOutput(outputData, outputPath, `\u2705 Summary saved to ${outputPath}`);
146
254
  }
147
255
  }
148
256
  }
package/dist/index.d.mts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { ScanOptions, AnalysisResult } from '@aiready/core';
2
2
  import { ContextAnalysisResult } from '@aiready/context-analyzer';
3
3
  import { DuplicatePattern } from '@aiready/pattern-detect';
4
- import { ConsistencyReport } from '@aiready/consistency';
4
+ import { ConsistencyOptions, ConsistencyReport } from '@aiready/consistency';
5
5
 
6
6
  interface UnifiedAnalysisOptions extends ScanOptions {
7
7
  tools?: ('patterns' | 'context' | 'consistency')[];
@@ -10,6 +10,11 @@ interface UnifiedAnalysisOptions extends ScanOptions {
10
10
  maxCandidatesPerBlock?: number;
11
11
  minSharedTokens?: number;
12
12
  useSmartDefaults?: boolean;
13
+ consistency?: Partial<ConsistencyOptions>;
14
+ progressCallback?: (event: {
15
+ tool: string;
16
+ data: any;
17
+ }) => void;
13
18
  }
14
19
  interface UnifiedAnalysisResult {
15
20
  patterns?: AnalysisResult[];
package/dist/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { ScanOptions, AnalysisResult } from '@aiready/core';
2
2
  import { ContextAnalysisResult } from '@aiready/context-analyzer';
3
3
  import { DuplicatePattern } from '@aiready/pattern-detect';
4
- import { ConsistencyReport } from '@aiready/consistency';
4
+ import { ConsistencyOptions, ConsistencyReport } from '@aiready/consistency';
5
5
 
6
6
  interface UnifiedAnalysisOptions extends ScanOptions {
7
7
  tools?: ('patterns' | 'context' | 'consistency')[];
@@ -10,6 +10,11 @@ interface UnifiedAnalysisOptions extends ScanOptions {
10
10
  maxCandidatesPerBlock?: number;
11
11
  minSharedTokens?: number;
12
12
  useSmartDefaults?: boolean;
13
+ consistency?: Partial<ConsistencyOptions>;
14
+ progressCallback?: (event: {
15
+ tool: string;
16
+ data: any;
17
+ }) => void;
13
18
  }
14
19
  interface UnifiedAnalysisResult {
15
20
  patterns?: AnalysisResult[];
package/dist/index.js CHANGED
@@ -65,6 +65,9 @@ async function analyzeUnified(options) {
65
65
  };
66
66
  if (tools.includes("patterns")) {
67
67
  const patternResult = await (0, import_pattern_detect.analyzePatterns)(options);
68
+ if (options.progressCallback) {
69
+ options.progressCallback({ tool: "patterns", data: patternResult });
70
+ }
68
71
  result.patterns = sortBySeverity(patternResult.results);
69
72
  result.duplicates = patternResult.duplicates;
70
73
  result.summary.totalIssues += patternResult.results.reduce(
@@ -74,6 +77,9 @@ async function analyzeUnified(options) {
74
77
  }
75
78
  if (tools.includes("context")) {
76
79
  const contextResults = await (0, import_context_analyzer.analyzeContext)(options);
80
+ if (options.progressCallback) {
81
+ options.progressCallback({ tool: "context", data: contextResults });
82
+ }
77
83
  result.context = contextResults.sort((a, b) => {
78
84
  const severityDiff = (severityOrder[b.severity] || 0) - (severityOrder[a.severity] || 0);
79
85
  if (severityDiff !== 0) return severityDiff;
@@ -83,14 +89,16 @@ async function analyzeUnified(options) {
83
89
  result.summary.totalIssues += result.context?.length || 0;
84
90
  }
85
91
  if (tools.includes("consistency")) {
86
- const report = await (0, import_consistency.analyzeConsistency)({
92
+ const consistencyOptions = {
87
93
  rootDir: options.rootDir,
88
94
  include: options.include,
89
95
  exclude: options.exclude,
90
- checkNaming: true,
91
- checkPatterns: true,
92
- minSeverity: "info"
93
- });
96
+ ...options.consistency || {}
97
+ };
98
+ const report = await (0, import_consistency.analyzeConsistency)(consistencyOptions);
99
+ if (options.progressCallback) {
100
+ options.progressCallback({ tool: "consistency", data: report });
101
+ }
94
102
  if (report.results) {
95
103
  report.results = sortBySeverity(report.results);
96
104
  }
@@ -114,11 +122,11 @@ function generateUnifiedSummary(result) {
114
122
  output += ` Execution time: ${(summary.executionTime / 1e3).toFixed(2)}s
115
123
 
116
124
  `;
117
- if (result.patterns?.length) {
125
+ if (result.patterns) {
118
126
  output += `\u{1F50D} Pattern Analysis: ${result.patterns.length} issues
119
127
  `;
120
128
  }
121
- if (result.context?.length) {
129
+ if (result.context) {
122
130
  output += `\u{1F9E0} Context Analysis: ${result.context.length} issues
123
131
  `;
124
132
  }
package/dist/index.mjs CHANGED
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  analyzeUnified,
3
3
  generateUnifiedSummary
4
- } from "./chunk-P3XAXCTK.mjs";
4
+ } from "./chunk-3SG2GLFJ.mjs";
5
5
  export {
6
6
  analyzeUnified,
7
7
  generateUnifiedSummary
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aiready/cli",
3
- "version": "0.7.18",
3
+ "version": "0.7.20",
4
4
  "description": "Unified CLI for AIReady analysis tools",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",
@@ -11,10 +11,10 @@
11
11
  "dependencies": {
12
12
  "commander": "^14.0.0",
13
13
  "chalk": "^5.3.0",
14
- "@aiready/context-analyzer": "0.7.16",
15
- "@aiready/consistency": "0.6.14",
16
- "@aiready/core": "0.7.11",
17
- "@aiready/pattern-detect": "0.9.20"
14
+ "@aiready/pattern-detect": "0.9.22",
15
+ "@aiready/consistency": "0.6.16",
16
+ "@aiready/core": "0.7.13",
17
+ "@aiready/context-analyzer": "0.7.18"
18
18
  },
19
19
  "devDependencies": {
20
20
  "tsup": "^8.3.5",