@aiready/context-analyzer 0.9.34 → 0.9.36

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
@@ -2,17 +2,26 @@
2
2
  import {
3
3
  analyzeContext,
4
4
  generateSummary
5
- } from "./chunk-EVX2W2BK.mjs";
5
+ } from "./chunk-7LUSCLGR.mjs";
6
6
 
7
7
  // src/cli.ts
8
8
  import { Command } from "commander";
9
9
  import chalk from "chalk";
10
10
  import { writeFileSync, existsSync, readFileSync, mkdirSync } from "fs";
11
11
  import { join, dirname } from "path";
12
- import { loadMergedConfig, handleJSONOutput, handleCLIError, getElapsedTime, resolveOutputPath } from "@aiready/core";
12
+ import {
13
+ loadMergedConfig,
14
+ handleJSONOutput,
15
+ handleCLIError,
16
+ getElapsedTime,
17
+ resolveOutputPath
18
+ } from "@aiready/core";
13
19
  import prompts from "prompts";
14
20
  var program = new Command();
15
- program.name("aiready-context").description("Analyze AI context window cost and code structure").version("0.1.0").addHelpText("after", "\nCONFIGURATION:\n Supports config files: aiready.json, aiready.config.json, .aiready.json, .aireadyrc.json, aiready.config.js, .aireadyrc.js\n CLI options override config file settings").argument("<directory>", "Directory to analyze").option("--max-depth <number>", "Maximum acceptable import depth").option(
21
+ program.name("aiready-context").description("Analyze AI context window cost and code structure").version("0.1.0").addHelpText(
22
+ "after",
23
+ "\nCONFIGURATION:\n Supports config files: aiready.json, aiready.config.json, .aiready.json, .aireadyrc.json, aiready.config.js, .aireadyrc.js\n CLI options override config file settings"
24
+ ).argument("<directory>", "Directory to analyze").option("--max-depth <number>", "Maximum acceptable import depth").option(
16
25
  "--max-context <number>",
17
26
  "Maximum acceptable context budget (tokens)"
18
27
  ).option("--min-cohesion <number>", "Minimum acceptable cohesion score (0-1)").option(
@@ -21,11 +30,17 @@ program.name("aiready-context").description("Analyze AI context window cost and
21
30
  ).option(
22
31
  "--focus <type>",
23
32
  "Analysis focus: fragmentation, cohesion, depth, all"
24
- ).option("--include-node-modules", "Include node_modules in analysis").option("--include <patterns>", "File patterns to include (comma-separated)").option("--exclude <patterns>", "File patterns to exclude (comma-separated)").option("--max-results <number>", "Maximum number of results to show in console output").option(
33
+ ).option("--include-node-modules", "Include node_modules in analysis").option("--include <patterns>", "File patterns to include (comma-separated)").option("--exclude <patterns>", "File patterns to exclude (comma-separated)").option(
34
+ "--max-results <number>",
35
+ "Maximum number of results to show in console output"
36
+ ).option(
25
37
  "-o, --output <format>",
26
38
  "Output format: console, json, html",
27
39
  "console"
28
- ).option("--output-file <path>", "Output file path (for json/html)").option("--interactive", "Run interactive setup to suggest excludes and focus areas").action(async (directory, options) => {
40
+ ).option("--output-file <path>", "Output file path (for json/html)").option(
41
+ "--interactive",
42
+ "Run interactive setup to suggest excludes and focus areas"
43
+ ).action(async (directory, options) => {
29
44
  console.log(chalk.blue("\u{1F50D} Analyzing context window costs...\n"));
30
45
  const startTime = Date.now();
31
46
  try {
@@ -69,8 +84,12 @@ program.name("aiready-context").description("Analyze AI context window cost and
69
84
  `context-report-${(/* @__PURE__ */ new Date()).toISOString().split("T")[0]}.json`,
70
85
  directory
71
86
  );
72
- handleJSONOutput(jsonOutput, outputPath, `
73
- \u2713 JSON report saved to ${outputPath}`);
87
+ handleJSONOutput(
88
+ jsonOutput,
89
+ outputPath,
90
+ `
91
+ \u2713 JSON report saved to ${outputPath}`
92
+ );
74
93
  return;
75
94
  }
76
95
  if (options.output === "html") {
@@ -89,7 +108,12 @@ program.name("aiready-context").description("Analyze AI context window cost and
89
108
  \u2713 HTML report saved to ${outputPath}`));
90
109
  return;
91
110
  }
92
- displayConsoleReport(summary, results, elapsedTime, finalOptions.maxResults);
111
+ displayConsoleReport(
112
+ summary,
113
+ results,
114
+ elapsedTime,
115
+ finalOptions.maxResults
116
+ );
93
117
  displayTuningGuidance(results, finalOptions);
94
118
  } catch (error) {
95
119
  handleCLIError(error, "Analysis");
@@ -99,28 +123,80 @@ program.parse();
99
123
  function displayTuningGuidance(results, options) {
100
124
  const issueCount = results.filter((r) => r.severity !== "info").length;
101
125
  if (issueCount === 0) {
102
- console.log(chalk.green("\n\u2728 No optimization opportunities found! Your code is well-structured for AI context usage.\n"));
126
+ console.log(
127
+ chalk.green(
128
+ "\n\u2728 No optimization opportunities found! Your code is well-structured for AI context usage.\n"
129
+ )
130
+ );
103
131
  return;
104
132
  }
105
133
  console.log(chalk.cyan("\n\u2501".repeat(60)));
106
134
  console.log(chalk.bold.white(" TUNING GUIDANCE"));
107
135
  console.log(chalk.cyan("\u2501".repeat(60) + "\n"));
108
136
  if (issueCount < 5) {
109
- console.log(chalk.yellow("\u{1F4CA} Showing few optimization opportunities. To find more areas to improve:\n"));
110
- console.log(chalk.dim(" \u2022 Lower --max-depth (currently: " + options.maxDepth + ") to catch shallower import chains"));
111
- console.log(chalk.dim(" \u2022 Lower --max-context (currently: " + options.maxContextBudget.toLocaleString() + ") to catch smaller files"));
112
- console.log(chalk.dim(" \u2022 Raise --min-cohesion (currently: " + (options.minCohesion * 100).toFixed(0) + "%) to be stricter about mixed concerns"));
113
- console.log(chalk.dim(" \u2022 Lower --max-fragmentation (currently: " + (options.maxFragmentation * 100).toFixed(0) + "%) to catch scattered code\n"));
137
+ console.log(
138
+ chalk.yellow(
139
+ "\u{1F4CA} Showing few optimization opportunities. To find more areas to improve:\n"
140
+ )
141
+ );
142
+ console.log(
143
+ chalk.dim(
144
+ " \u2022 Lower --max-depth (currently: " + options.maxDepth + ") to catch shallower import chains"
145
+ )
146
+ );
147
+ console.log(
148
+ chalk.dim(
149
+ " \u2022 Lower --max-context (currently: " + options.maxContextBudget.toLocaleString() + ") to catch smaller files"
150
+ )
151
+ );
152
+ console.log(
153
+ chalk.dim(
154
+ " \u2022 Raise --min-cohesion (currently: " + (options.minCohesion * 100).toFixed(0) + "%) to be stricter about mixed concerns"
155
+ )
156
+ );
157
+ console.log(
158
+ chalk.dim(
159
+ " \u2022 Lower --max-fragmentation (currently: " + (options.maxFragmentation * 100).toFixed(0) + "%) to catch scattered code\n"
160
+ )
161
+ );
114
162
  } else if (issueCount > 20) {
115
- console.log(chalk.yellow("\u{1F4CA} Showing many opportunities. To focus on highest-impact areas:\n"));
116
- console.log(chalk.dim(" \u2022 Raise --max-depth (currently: " + options.maxDepth + ") to only catch very deep chains"));
117
- console.log(chalk.dim(" \u2022 Raise --max-context (currently: " + options.maxContextBudget.toLocaleString() + ") to focus on largest files"));
118
- console.log(chalk.dim(" \u2022 Lower --min-cohesion (currently: " + (options.minCohesion * 100).toFixed(0) + "%) to only flag severe mixed concerns"));
119
- console.log(chalk.dim(" \u2022 Raise --max-fragmentation (currently: " + (options.maxFragmentation * 100).toFixed(0) + "%) to only flag highly scattered code\n"));
163
+ console.log(
164
+ chalk.yellow(
165
+ "\u{1F4CA} Showing many opportunities. To focus on highest-impact areas:\n"
166
+ )
167
+ );
168
+ console.log(
169
+ chalk.dim(
170
+ " \u2022 Raise --max-depth (currently: " + options.maxDepth + ") to only catch very deep chains"
171
+ )
172
+ );
173
+ console.log(
174
+ chalk.dim(
175
+ " \u2022 Raise --max-context (currently: " + options.maxContextBudget.toLocaleString() + ") to focus on largest files"
176
+ )
177
+ );
178
+ console.log(
179
+ chalk.dim(
180
+ " \u2022 Lower --min-cohesion (currently: " + (options.minCohesion * 100).toFixed(0) + "%) to only flag severe mixed concerns"
181
+ )
182
+ );
183
+ console.log(
184
+ chalk.dim(
185
+ " \u2022 Raise --max-fragmentation (currently: " + (options.maxFragmentation * 100).toFixed(0) + "%) to only flag highly scattered code\n"
186
+ )
187
+ );
120
188
  } else {
121
- console.log(chalk.green("\u{1F4CA} Good balance of optimization opportunities (showing " + issueCount + " areas)\n"));
189
+ console.log(
190
+ chalk.green(
191
+ "\u{1F4CA} Good balance of optimization opportunities (showing " + issueCount + " areas)\n"
192
+ )
193
+ );
122
194
  console.log(chalk.dim(" \u{1F4A1} Tip: Adjust thresholds if needed:"));
123
- console.log(chalk.dim(" aiready-context . --max-depth N --max-context N --min-cohesion 0.X\n"));
195
+ console.log(
196
+ chalk.dim(
197
+ " aiready-context . --max-depth N --max-context N --min-cohesion 0.X\n"
198
+ )
199
+ );
124
200
  }
125
201
  console.log(chalk.dim(" \u{1F4D6} See README for detailed tuning guide\n"));
126
202
  }
@@ -131,9 +207,13 @@ function displayConsoleReport(summary, results, elapsedTime, maxResults = 10) {
131
207
  console.log(chalk.cyan(divider));
132
208
  console.log(chalk.bold.white(" CONTEXT ANALYSIS SUMMARY"));
133
209
  console.log(chalk.cyan(divider) + "\n");
134
- console.log(chalk.white(`\u{1F4C1} Files analyzed: ${chalk.bold(summary.totalFiles)}`));
135
210
  console.log(
136
- chalk.white(`\u{1F4CA} Total tokens: ${chalk.bold(summary.totalTokens.toLocaleString())}`)
211
+ chalk.white(`\u{1F4C1} Files analyzed: ${chalk.bold(summary.totalFiles)}`)
212
+ );
213
+ console.log(
214
+ chalk.white(
215
+ `\u{1F4CA} Total tokens: ${chalk.bold(summary.totalTokens.toLocaleString())}`
216
+ )
137
217
  );
138
218
  console.log(
139
219
  chalk.yellow(
@@ -158,7 +238,9 @@ function displayConsoleReport(summary, results, elapsedTime, maxResults = 10) {
158
238
  );
159
239
  }
160
240
  if (summary.minorIssues > 0) {
161
- console.log(chalk.blue(` \u{1F535} Minor: ${chalk.bold(summary.minorIssues)}`));
241
+ console.log(
242
+ chalk.blue(` \u{1F535} Minor: ${chalk.bold(summary.minorIssues)}`)
243
+ );
162
244
  }
163
245
  console.log(
164
246
  chalk.green(
@@ -253,11 +335,14 @@ function displayConsoleReport(summary, results, elapsedTime, maxResults = 10) {
253
335
  )
254
336
  );
255
337
  console.log(
256
- chalk.dim("\u{1F41B} Found a bug? Report it: https://github.com/caopengau/aiready-context-analyzer/issues\n")
338
+ chalk.dim(
339
+ "\u{1F41B} Found a bug? Report it: https://github.com/caopengau/aiready-context-analyzer/issues\n"
340
+ )
257
341
  );
258
342
  }
259
343
  function generateHTMLReport(summary, results) {
260
344
  const totalIssues = summary.criticalIssues + summary.majorIssues + summary.minorIssues;
345
+ void results;
261
346
  return `<!DOCTYPE html>
262
347
  <html lang="en">
263
348
  <head>
@@ -385,14 +470,16 @@ function generateHTMLReport(summary, results) {
385
470
  </tr>
386
471
  </thead>
387
472
  <tbody>
388
- ${summary.fragmentedModules.map((m) => `
473
+ ${summary.fragmentedModules.map(
474
+ (m) => `
389
475
  <tr>
390
476
  <td>${m.domain}</td>
391
477
  <td>${m.files.length}</td>
392
478
  <td>${(m.fragmentationScore * 100).toFixed(0)}%</td>
393
479
  <td>${m.totalTokens.toLocaleString()}</td>
394
480
  </tr>
395
- `).join("")}
481
+ `
482
+ ).join("")}
396
483
  </tbody>
397
484
  </table>
398
485
  </div>
@@ -410,13 +497,15 @@ function generateHTMLReport(summary, results) {
410
497
  </tr>
411
498
  </thead>
412
499
  <tbody>
413
- ${summary.topExpensiveFiles.map((f) => `
500
+ ${summary.topExpensiveFiles.map(
501
+ (f) => `
414
502
  <tr>
415
503
  <td>${f.file}</td>
416
504
  <td>${f.contextBudget.toLocaleString()} tokens</td>
417
505
  <td class="issue-${f.severity}">${f.severity.toUpperCase()}</td>
418
506
  </tr>
419
- `).join("")}
507
+ `
508
+ ).join("")}
420
509
  </tbody>
421
510
  </table>
422
511
  </div>
@@ -438,7 +527,8 @@ async function runInteractiveSetup(directory, current) {
438
527
  try {
439
528
  const pkg = JSON.parse(readFileSync(pkgPath, "utf-8"));
440
529
  deps = { ...pkg.dependencies || {}, ...pkg.devDependencies || {} };
441
- } catch {
530
+ } catch (e) {
531
+ void e;
442
532
  }
443
533
  }
444
534
  const hasNextJs = existsSync(join(directory, ".next")) || !!deps["next"];
@@ -458,7 +548,7 @@ async function runInteractiveSetup(directory, current) {
458
548
  active: "yes",
459
549
  inactive: "no"
460
550
  });
461
- let nextOptions = { ...current };
551
+ const nextOptions = { ...current };
462
552
  if (applyExcludes) {
463
553
  nextOptions.exclude = Array.from(recommendedExcludes);
464
554
  }
@@ -475,9 +565,23 @@ async function runInteractiveSetup(directory, current) {
475
565
  });
476
566
  if (focusArea === "frontend") {
477
567
  nextOptions.include = ["**/*.{ts,tsx,js,jsx}"];
478
- nextOptions.exclude = Array.from(/* @__PURE__ */ new Set([...nextOptions.exclude || [], "**/cdk.out/**", "**/infra/**", "**/server/**", "**/backend/**"]));
568
+ nextOptions.exclude = Array.from(
569
+ /* @__PURE__ */ new Set([
570
+ ...nextOptions.exclude || [],
571
+ "**/cdk.out/**",
572
+ "**/infra/**",
573
+ "**/server/**",
574
+ "**/backend/**"
575
+ ])
576
+ );
479
577
  } else if (focusArea === "backend") {
480
- nextOptions.include = ["**/api/**", "**/server/**", "**/backend/**", "**/infra/**", "**/*.{ts,js,py,java}"];
578
+ nextOptions.include = [
579
+ "**/api/**",
580
+ "**/server/**",
581
+ "**/backend/**",
582
+ "**/infra/**",
583
+ "**/*.{ts,js,py,java}"
584
+ ];
481
585
  }
482
586
  console.log(chalk.green("\u2713 Interactive configuration applied."));
483
587
  return nextOptions;