@aiready/context-analyzer 0.21.6 → 0.21.8

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.js CHANGED
@@ -542,7 +542,7 @@ function extractExportsWithAST(content, filePath, domainOptions, fileImports) {
542
542
  dependencies: exp.dependencies,
543
543
  typeReferences: exp.typeReferences
544
544
  }));
545
- } catch (error) {
545
+ } catch {
546
546
  return extractExports(content, filePath, domainOptions, fileImports);
547
547
  }
548
548
  }
@@ -879,6 +879,21 @@ function detectModuleClusters(graph, options) {
879
879
  domainMap.get(primaryDomain).push(file);
880
880
  }
881
881
  const clusters = [];
882
+ const generateSuggestedStructure = (files, tokens, fragmentation) => {
883
+ const targetFiles = Math.max(1, Math.ceil(tokens / 1e4));
884
+ const plan = [];
885
+ if (fragmentation > 0.5) {
886
+ plan.push(
887
+ `Consolidate ${files.length} files scattered across multiple directories into ${targetFiles} core module(s)`
888
+ );
889
+ }
890
+ if (tokens > 2e4) {
891
+ plan.push(
892
+ `Domain logic is very large (${Math.round(tokens / 1e3)}k tokens). Ensure clear sub-domain boundaries.`
893
+ );
894
+ }
895
+ return { targetFiles, consolidationPlan: plan };
896
+ };
882
897
  for (const [domain, files] of domainMap.entries()) {
883
898
  if (files.length < 2 || domain === "unknown") continue;
884
899
  const totalTokens = files.reduce((sum, file) => {
@@ -924,87 +939,15 @@ function detectModuleClusters(graph, options) {
924
939
  }
925
940
  return clusters;
926
941
  }
927
- function generateSuggestedStructure(files, tokens, fragmentation) {
928
- const targetFiles = Math.max(1, Math.ceil(tokens / 1e4));
929
- const plan = [];
930
- if (fragmentation > 0.5) {
931
- plan.push(
932
- `Consolidate ${files.length} files scattered across multiple directories into ${targetFiles} core module(s)`
933
- );
934
- }
935
- if (tokens > 2e4) {
936
- plan.push(
937
- `Domain logic is very large (${Math.round(tokens / 1e3)}k tokens). Ensure clear sub-domain boundaries.`
938
- );
939
- }
940
- return { targetFiles, consolidationPlan: plan };
941
- }
942
942
 
943
- // src/classifier.ts
944
- var Classification = {
945
- BARREL: "barrel-export",
946
- TYPE_DEFINITION: "type-definition",
947
- NEXTJS_PAGE: "nextjs-page",
948
- LAMBDA_HANDLER: "lambda-handler",
949
- SERVICE: "service-file",
950
- EMAIL_TEMPLATE: "email-template",
951
- PARSER: "parser-file",
952
- COHESIVE_MODULE: "cohesive-module",
953
- UTILITY_MODULE: "utility-module",
954
- MIXED_CONCERNS: "mixed-concerns",
955
- UNKNOWN: "unknown"
956
- };
957
- function classifyFile(node, cohesionScore = 1, domains = []) {
958
- if (isBarrelExport(node)) {
959
- return Classification.BARREL;
960
- }
961
- if (isTypeDefinition(node)) {
962
- return Classification.TYPE_DEFINITION;
963
- }
964
- if (isNextJsPage(node)) {
965
- return Classification.NEXTJS_PAGE;
966
- }
967
- if (isLambdaHandler(node)) {
968
- return Classification.LAMBDA_HANDLER;
969
- }
970
- if (isServiceFile(node)) {
971
- return Classification.SERVICE;
972
- }
973
- if (isEmailTemplate(node)) {
974
- return Classification.EMAIL_TEMPLATE;
975
- }
976
- if (isParserFile(node)) {
977
- return Classification.PARSER;
978
- }
979
- if (isSessionFile(node)) {
980
- if (cohesionScore >= 0.25 && domains.length <= 1)
981
- return Classification.COHESIVE_MODULE;
982
- return Classification.UTILITY_MODULE;
983
- }
984
- if (isUtilityModule(node)) {
985
- return Classification.UTILITY_MODULE;
986
- }
987
- if (isConfigFile(node)) {
988
- return Classification.COHESIVE_MODULE;
989
- }
990
- if (domains.length <= 1 && domains[0] !== "unknown") {
991
- return Classification.COHESIVE_MODULE;
992
- }
993
- if (domains.length > 1 && cohesionScore < 0.4) {
994
- return Classification.MIXED_CONCERNS;
995
- }
996
- if (cohesionScore >= 0.7) {
997
- return Classification.COHESIVE_MODULE;
998
- }
999
- return Classification.UNKNOWN;
1000
- }
943
+ // src/heuristics.ts
1001
944
  function isBarrelExport(node) {
1002
945
  const { file, exports: exports2 } = node;
1003
946
  const fileName = file.split("/").pop()?.toLowerCase();
1004
947
  const isIndexFile = fileName === "index.ts" || fileName === "index.js";
1005
948
  const isSmallAndManyExports = node.tokenCost < 1e3 && (exports2 || []).length > 5;
1006
949
  const isReexportPattern = (exports2 || []).length >= 5 && (exports2 || []).every(
1007
- (e) => e.type === "const" || e.type === "function" || e.type === "type" || e.type === "interface"
950
+ (e) => ["const", "function", "type", "interface"].includes(e.type)
1008
951
  );
1009
952
  return !!isIndexFile || !!isSmallAndManyExports || !!isReexportPattern;
1010
953
  }
@@ -1014,20 +957,19 @@ function isTypeDefinition(node) {
1014
957
  const nodeExports = node.exports || [];
1015
958
  const hasExports = nodeExports.length > 0;
1016
959
  const areAllTypes = hasExports && nodeExports.every((e) => e.type === "type" || e.type === "interface");
1017
- const allTypes = !!areAllTypes;
1018
- const isTypePath = file.toLowerCase().includes("/types/") || file.toLowerCase().includes("/interfaces/") || file.toLowerCase().includes("/models/");
1019
- return allTypes || isTypePath && hasExports;
960
+ const isTypePath = /\/(types|interfaces|models)\//i.test(file);
961
+ return !!areAllTypes || isTypePath && hasExports;
1020
962
  }
1021
963
  function isUtilityModule(node) {
1022
964
  const { file } = node;
1023
- const isUtilPath = file.toLowerCase().includes("/utils/") || file.toLowerCase().includes("/helpers/") || file.toLowerCase().includes("/util/") || file.toLowerCase().includes("/helper/");
1024
- const fileName = file.split("/").pop()?.toLowerCase();
1025
- const isUtilName = fileName?.includes("utils.") || fileName?.includes("helpers.") || fileName?.includes("util.") || fileName?.includes("helper.");
1026
- return !!isUtilPath || !!isUtilName;
965
+ const isUtilPath = /\/(utils|helpers|util|helper)\//i.test(file);
966
+ const fileName = file.split("/").pop()?.toLowerCase() || "";
967
+ const isUtilName = /(utils\.|helpers\.|util\.|helper\.)/i.test(fileName);
968
+ return isUtilPath || isUtilName;
1027
969
  }
1028
970
  function isLambdaHandler(node) {
1029
971
  const { file, exports: exports2 } = node;
1030
- const fileName = file.split("/").pop()?.toLowerCase();
972
+ const fileName = file.split("/").pop()?.toLowerCase() || "";
1031
973
  const handlerPatterns = [
1032
974
  "handler",
1033
975
  ".handler.",
@@ -1036,33 +978,29 @@ function isLambdaHandler(node) {
1036
978
  ".lambda.",
1037
979
  "-lambda."
1038
980
  ];
1039
- const isHandlerName = handlerPatterns.some(
1040
- (pattern) => fileName?.includes(pattern)
1041
- );
1042
- const isHandlerPath = file.toLowerCase().includes("/handlers/") || file.toLowerCase().includes("/lambdas/") || file.toLowerCase().includes("/lambda/") || file.toLowerCase().includes("/functions/");
981
+ const isHandlerName = handlerPatterns.some((p) => fileName.includes(p));
982
+ const isHandlerPath = /\/(handlers|lambdas|lambda|functions)\//i.test(file);
1043
983
  const hasHandlerExport = (exports2 || []).some(
1044
- (e) => e.name.toLowerCase() === "handler" || e.name.toLowerCase() === "main" || e.name.toLowerCase() === "lambdahandler" || e.name.toLowerCase().endsWith("handler")
984
+ (e) => ["handler", "main", "lambdahandler"].includes(e.name.toLowerCase()) || e.name.toLowerCase().endsWith("handler")
1045
985
  );
1046
- return !!isHandlerName || !!isHandlerPath || !!hasHandlerExport;
986
+ return isHandlerName || isHandlerPath || hasHandlerExport;
1047
987
  }
1048
988
  function isServiceFile(node) {
1049
989
  const { file, exports: exports2 } = node;
1050
- const fileName = file.split("/").pop()?.toLowerCase();
990
+ const fileName = file.split("/").pop()?.toLowerCase() || "";
1051
991
  const servicePatterns = ["service", ".service.", "-service.", "_service."];
1052
- const isServiceName = servicePatterns.some(
1053
- (pattern) => fileName?.includes(pattern)
1054
- );
992
+ const isServiceName = servicePatterns.some((p) => fileName.includes(p));
1055
993
  const isServicePath = file.toLowerCase().includes("/services/");
1056
994
  const hasServiceNamedExport = (exports2 || []).some(
1057
- (e) => e.name.toLowerCase().includes("service") || e.name.toLowerCase().endsWith("service")
995
+ (e) => e.name.toLowerCase().includes("service")
1058
996
  );
1059
997
  const hasClassExport = (exports2 || []).some((e) => e.type === "class");
1060
- return !!isServiceName || !!isServicePath || !!hasServiceNamedExport && !!hasClassExport;
998
+ return isServiceName || isServicePath || hasServiceNamedExport && hasClassExport;
1061
999
  }
1062
1000
  function isEmailTemplate(node) {
1063
1001
  const { file, exports: exports2 } = node;
1064
- const fileName = file.split("/").pop()?.toLowerCase();
1065
- const emailTemplatePatterns = [
1002
+ const fileName = file.split("/").pop()?.toLowerCase() || "";
1003
+ const emailPatterns = [
1066
1004
  "-email-",
1067
1005
  ".email.",
1068
1006
  "_email_",
@@ -1072,78 +1010,51 @@ function isEmailTemplate(node) {
1072
1010
  "-mail.",
1073
1011
  ".mail."
1074
1012
  ];
1075
- const isEmailTemplateName = emailTemplatePatterns.some(
1076
- (pattern) => fileName?.includes(pattern)
1077
- );
1078
- const isEmailPath = file.toLowerCase().includes("/emails/") || file.toLowerCase().includes("/mail/") || file.toLowerCase().includes("/notifications/");
1013
+ const isEmailName = emailPatterns.some((p) => fileName.includes(p));
1014
+ const isEmailPath = /\/(emails|mail|notifications)\//i.test(file);
1079
1015
  const hasTemplateFunction = (exports2 || []).some(
1080
- (e) => e.type === "function" && (e.name.toLowerCase().startsWith("render") || e.name.toLowerCase().startsWith("generate") || e.name.toLowerCase().includes("template") && e.name.toLowerCase().includes("email"))
1016
+ (e) => e.type === "function" && (e.name.toLowerCase().startsWith("render") || e.name.toLowerCase().startsWith("generate"))
1081
1017
  );
1082
- return !!isEmailPath || !!isEmailTemplateName || !!hasTemplateFunction;
1018
+ return isEmailPath || isEmailName || hasTemplateFunction;
1083
1019
  }
1084
1020
  function isParserFile(node) {
1085
1021
  const { file, exports: exports2 } = node;
1086
- const fileName = file.split("/").pop()?.toLowerCase();
1022
+ const fileName = file.split("/").pop()?.toLowerCase() || "";
1087
1023
  const parserPatterns = [
1088
1024
  "parser",
1089
1025
  ".parser.",
1090
1026
  "-parser.",
1091
1027
  "_parser.",
1092
1028
  "transform",
1093
- ".transform.",
1094
1029
  "converter",
1095
1030
  "mapper",
1096
1031
  "serializer"
1097
1032
  ];
1098
- const isParserName = parserPatterns.some(
1099
- (pattern) => fileName?.includes(pattern)
1100
- );
1101
- const isParserPath = file.toLowerCase().includes("/parsers/") || file.toLowerCase().includes("/transformers/");
1033
+ const isParserName = parserPatterns.some((p) => fileName.includes(p));
1034
+ const isParserPath = /\/(parsers|transformers)\//i.test(file);
1102
1035
  const hasParseFunction = (exports2 || []).some(
1103
- (e) => e.type === "function" && (e.name.toLowerCase().startsWith("parse") || e.name.toLowerCase().startsWith("transform") || e.name.toLowerCase().startsWith("extract"))
1036
+ (e) => e.type === "function" && (e.name.toLowerCase().startsWith("parse") || e.name.toLowerCase().startsWith("transform"))
1104
1037
  );
1105
- return !!isParserName || !!isParserPath || !!hasParseFunction;
1038
+ return isParserName || isParserPath || hasParseFunction;
1106
1039
  }
1107
1040
  function isSessionFile(node) {
1108
1041
  const { file, exports: exports2 } = node;
1109
- const fileName = file.split("/").pop()?.toLowerCase();
1042
+ const fileName = file.split("/").pop()?.toLowerCase() || "";
1110
1043
  const sessionPatterns = ["session", "state", "context", "store"];
1111
- const isSessionName = sessionPatterns.some(
1112
- (pattern) => fileName?.includes(pattern)
1113
- );
1114
- const isSessionPath = file.toLowerCase().includes("/sessions/") || file.toLowerCase().includes("/state/");
1044
+ const isSessionName = sessionPatterns.some((p) => fileName.includes(p));
1045
+ const isSessionPath = /\/(sessions|state)\//i.test(file);
1115
1046
  const hasSessionExport = (exports2 || []).some(
1116
- (e) => e.name.toLowerCase().includes("session") || e.name.toLowerCase().includes("state") || e.name.toLowerCase().includes("store")
1117
- );
1118
- return !!isSessionName || !!isSessionPath || !!hasSessionExport;
1119
- }
1120
- function isConfigFile(node) {
1121
- const { file, exports: exports2 } = node;
1122
- const lowerPath = file.toLowerCase();
1123
- const fileName = file.split("/").pop()?.toLowerCase();
1124
- const configPatterns = [
1125
- ".config.",
1126
- "tsconfig",
1127
- "jest.config",
1128
- "package.json",
1129
- "aiready.json",
1130
- "next.config",
1131
- "sst.config"
1132
- ];
1133
- const isConfigName = configPatterns.some((p) => fileName?.includes(p));
1134
- const isConfigPath = lowerPath.includes("/config/") || lowerPath.includes("/settings/") || lowerPath.includes("/schemas/");
1135
- const hasSchemaExports = (exports2 || []).some(
1136
- (e) => e.name.toLowerCase().includes("schema") || e.name.toLowerCase().includes("config") || e.name.toLowerCase().includes("setting")
1047
+ (e) => ["session", "state", "store"].some((p) => e.name.toLowerCase().includes(p))
1137
1048
  );
1138
- return !!isConfigName || !!isConfigPath || !!hasSchemaExports;
1049
+ return isSessionName || isSessionPath || hasSessionExport;
1139
1050
  }
1140
1051
  function isNextJsPage(node) {
1141
1052
  const { file, exports: exports2 } = node;
1142
1053
  const lowerPath = file.toLowerCase();
1143
- const fileName = file.split("/").pop()?.toLowerCase();
1054
+ const fileName = file.split("/").pop()?.toLowerCase() || "";
1144
1055
  const isInAppDir = lowerPath.includes("/app/") || lowerPath.startsWith("app/");
1145
- const isPageFile = fileName === "page.tsx" || fileName === "page.ts";
1146
- if (!isInAppDir || !isPageFile) return false;
1056
+ if (!isInAppDir || fileName !== "page.tsx" && fileName !== "page.ts")
1057
+ return false;
1147
1058
  const hasDefaultExport = (exports2 || []).some((e) => e.type === "default");
1148
1059
  const nextJsExports = [
1149
1060
  "metadata",
@@ -1152,10 +1063,91 @@ function isNextJsPage(node) {
1152
1063
  "jsonld",
1153
1064
  "icon"
1154
1065
  ];
1155
- const hasNextJsExports = (exports2 || []).some(
1066
+ const hasNextJsExport = (exports2 || []).some(
1156
1067
  (e) => nextJsExports.includes(e.name.toLowerCase())
1157
1068
  );
1158
- return !!hasDefaultExport || !!hasNextJsExports;
1069
+ return hasDefaultExport || hasNextJsExport;
1070
+ }
1071
+ function isConfigFile(node) {
1072
+ const { file, exports: exports2 } = node;
1073
+ const lowerPath = file.toLowerCase();
1074
+ const fileName = file.split("/").pop()?.toLowerCase() || "";
1075
+ const configPatterns = [
1076
+ ".config.",
1077
+ "tsconfig",
1078
+ "jest.config",
1079
+ "package.json",
1080
+ "aiready.json",
1081
+ "next.config",
1082
+ "sst.config"
1083
+ ];
1084
+ const isConfigName = configPatterns.some((p) => fileName.includes(p));
1085
+ const isConfigPath = /\/(config|settings|schemas)\//i.test(lowerPath);
1086
+ const hasSchemaExport = (exports2 || []).some(
1087
+ (e) => ["schema", "config", "setting"].some(
1088
+ (p) => e.name.toLowerCase().includes(p)
1089
+ )
1090
+ );
1091
+ return isConfigName || isConfigPath || hasSchemaExport;
1092
+ }
1093
+
1094
+ // src/classifier.ts
1095
+ var Classification = {
1096
+ BARREL: "barrel-export",
1097
+ TYPE_DEFINITION: "type-definition",
1098
+ NEXTJS_PAGE: "nextjs-page",
1099
+ LAMBDA_HANDLER: "lambda-handler",
1100
+ SERVICE: "service-file",
1101
+ EMAIL_TEMPLATE: "email-template",
1102
+ PARSER: "parser-file",
1103
+ COHESIVE_MODULE: "cohesive-module",
1104
+ UTILITY_MODULE: "utility-module",
1105
+ MIXED_CONCERNS: "mixed-concerns",
1106
+ UNKNOWN: "unknown"
1107
+ };
1108
+ function classifyFile(node, cohesionScore = 1, domains = []) {
1109
+ if (isBarrelExport(node)) {
1110
+ return Classification.BARREL;
1111
+ }
1112
+ if (isTypeDefinition(node)) {
1113
+ return Classification.TYPE_DEFINITION;
1114
+ }
1115
+ if (isNextJsPage(node)) {
1116
+ return Classification.NEXTJS_PAGE;
1117
+ }
1118
+ if (isLambdaHandler(node)) {
1119
+ return Classification.LAMBDA_HANDLER;
1120
+ }
1121
+ if (isServiceFile(node)) {
1122
+ return Classification.SERVICE;
1123
+ }
1124
+ if (isEmailTemplate(node)) {
1125
+ return Classification.EMAIL_TEMPLATE;
1126
+ }
1127
+ if (isParserFile(node)) {
1128
+ return Classification.PARSER;
1129
+ }
1130
+ if (isSessionFile(node)) {
1131
+ if (cohesionScore >= 0.25 && domains.length <= 1)
1132
+ return Classification.COHESIVE_MODULE;
1133
+ return Classification.UTILITY_MODULE;
1134
+ }
1135
+ if (isUtilityModule(node)) {
1136
+ return Classification.UTILITY_MODULE;
1137
+ }
1138
+ if (isConfigFile(node)) {
1139
+ return Classification.COHESIVE_MODULE;
1140
+ }
1141
+ if (domains.length <= 1 && domains[0] !== "unknown") {
1142
+ return Classification.COHESIVE_MODULE;
1143
+ }
1144
+ if (domains.length > 1 && cohesionScore < 0.4) {
1145
+ return Classification.MIXED_CONCERNS;
1146
+ }
1147
+ if (cohesionScore >= 0.7) {
1148
+ return Classification.COHESIVE_MODULE;
1149
+ }
1150
+ return Classification.UNKNOWN;
1159
1151
  }
1160
1152
  function adjustCohesionForClassification(baseCohesion, classification, node) {
1161
1153
  switch (classification) {
@@ -1315,7 +1307,7 @@ function getClassificationRecommendations(classification, file, issues) {
1315
1307
  async function analyzeContext(options) {
1316
1308
  const {
1317
1309
  maxDepth = 5,
1318
- maxContextBudget = 1e4,
1310
+ maxContextBudget = 25e3,
1319
1311
  minCohesion = 0.6,
1320
1312
  maxFragmentation = 0.5,
1321
1313
  includeNodeModules = false,
package/dist/cli.mjs CHANGED
@@ -5,7 +5,7 @@ import {
5
5
  generateHTMLReport,
6
6
  generateSummary,
7
7
  runInteractiveSetup
8
- } from "./chunk-XIXAWCMS.mjs";
8
+ } from "./chunk-D25B5LZR.mjs";
9
9
  import "./chunk-64U3PNO3.mjs";
10
10
 
11
11
  // src/cli.ts
package/dist/index.d.mts CHANGED
@@ -1,36 +1,68 @@
1
- import { ToolProvider, Severity, ScanOptions, CostConfig, ToolScoringOutput } from '@aiready/core';
1
+ import { ToolProvider, Severity, ScanOptions, FileContent, CostConfig, ToolScoringOutput } from '@aiready/core';
2
2
 
3
3
  /**
4
4
  * Context Analyzer Tool Provider
5
5
  */
6
6
  declare const ContextAnalyzerProvider: ToolProvider;
7
7
 
8
+ /**
9
+ * Options for the Context Analyzer tool.
10
+ * Controls thresholds for import depth, context budget, and cohesion.
11
+ */
8
12
  interface ContextAnalyzerOptions extends ScanOptions {
13
+ /** Maximum acceptable import depth (default: 5) */
9
14
  maxDepth?: number;
15
+ /** Maximum acceptable token budget for a single context (default: 25000) */
10
16
  maxContextBudget?: number;
17
+ /** Minimum acceptable cohesion score between 0 and 1 (default: 0.6) */
11
18
  minCohesion?: number;
19
+ /** Maximum acceptable fragmentation score between 0 and 1 (default: 0.5) */
12
20
  maxFragmentation?: number;
21
+ /** Analysis focus area: fragmentation, cohesion, depth, or all (default: 'all') */
13
22
  focus?: 'fragmentation' | 'cohesion' | 'depth' | 'all';
23
+ /** Whether to include node_modules in the analysis (default: false) */
14
24
  includeNodeModules?: boolean;
15
25
  }
26
+ /**
27
+ * The result of a context analysis for a single file or module.
28
+ * Includes metrics for tokens, dependencies, cohesion, and AI impact.
29
+ */
16
30
  interface ContextAnalysisResult {
31
+ /** The file path being analyzed */
17
32
  file: string;
33
+ /** Total number of tokens in this file */
18
34
  tokenCost: number;
35
+ /** Total lines of code in the file */
19
36
  linesOfCode: number;
37
+ /** Maximum depth of the import tree for this file */
20
38
  importDepth: number;
39
+ /** Total number of transitive dependencies */
21
40
  dependencyCount: number;
41
+ /** List of all files in the dependency tree */
22
42
  dependencyList: string[];
43
+ /** Detected circular dependency chains */
23
44
  circularDeps: string[][];
45
+ /** Cohesion score from 0 to 1 (1 is perfect cohesion) */
24
46
  cohesionScore: number;
47
+ /** Detected domain categories for the module */
25
48
  domains: string[];
49
+ /** Number of exported symbols */
26
50
  exportCount: number;
51
+ /** Total tokens required to understand this file and all its dependencies */
27
52
  contextBudget: number;
53
+ /** Fragmentation score from 0 to 1 (0 is well-grouped) */
28
54
  fragmentationScore: number;
55
+ /** List of files that should be loaded together for full context */
29
56
  relatedFiles: string[];
57
+ /** The semantic classification of the file (e.g. 'barrel-export', 'service-file') */
30
58
  fileClassification: FileClassification;
59
+ /** Overall severity of identified issues */
31
60
  severity: Severity | 'critical' | 'major' | 'minor' | 'info';
61
+ /** List of specific structural problems found */
32
62
  issues: string[];
63
+ /** Actionable suggestions for improving context readiness */
33
64
  recommendations: string[];
65
+ /** Estimated tokens that could be saved by following recommendations */
34
66
  potentialSavings: number;
35
67
  }
36
68
  /**
@@ -129,19 +161,28 @@ interface TypeDependency {
129
161
  }
130
162
 
131
163
  /**
132
- * Calculate cohesion score (how related are exports in a file)
133
- * Legacy wrapper for backward compatibility with exact test expectations
164
+ * Calculate cohesion score (how related are exports in a file).
165
+ * Legacy wrapper for backward compatibility with exact test expectations.
166
+ *
167
+ * @param exports - List of exported symbols
168
+ * @param filePath - Path to the file being analyzed
169
+ * @param options - Additional options for cohesion calculation
170
+ * @returns Cohesion score between 0 and 1
134
171
  */
135
172
  declare function calculateCohesion(exports: ExportInfo[], filePath?: string, options?: any): number;
136
173
  /**
137
174
  * Analyze AI context window cost for a codebase
138
175
  */
176
+ /**
177
+ * Performs deep context analysis of a project.
178
+ * Scans files, builds a dependency graph, calculates context budgets,
179
+ * and identifies structural issues like high fragmentation or depth.
180
+ *
181
+ * @param options - Analysis parameters including root directory and focus areas
182
+ * @returns Comprehensive analysis results with metrics and identified issues
183
+ */
139
184
  declare function analyzeContext(options: ContextAnalyzerOptions): Promise<ContextAnalysisResult[]>;
140
185
 
141
- interface FileContent {
142
- file: string;
143
- content: string;
144
- }
145
186
  /**
146
187
  * Auto-detect domain keywords from workspace folder structure
147
188
  */
@@ -172,6 +213,15 @@ declare function detectCircularDependencies(graph: DependencyGraph): string[][];
172
213
  /**
173
214
  * Calculate cohesion score (how related are exports in a file)
174
215
  */
216
+ /**
217
+ * Calculates a cohesion score (0-1) for a module based on its exports,
218
+ * shared imports, and internal structure. High cohesion indicates
219
+ * a well-focused module that is easy for AI models to reason about.
220
+ *
221
+ * @param exports - Exported symbols and their metadata
222
+ * @param imports - Imported symbols and their sources
223
+ * @returns Cohesion score between 0 and 1
224
+ */
175
225
  declare function calculateEnhancedCohesion(exports: ExportInfo[], filePath?: string, options?: {
176
226
  coUsageMatrix?: Map<string, Map<string, number>>;
177
227
  weights?: {
@@ -227,76 +277,6 @@ declare const Classification: {
227
277
  * @returns The determined file classification
228
278
  */
229
279
  declare function classifyFile(node: DependencyNode, cohesionScore?: number, domains?: string[]): FileClassification;
230
- /**
231
- * Detect if a file is a barrel export (index.ts)
232
- *
233
- * @param node The dependency node to check
234
- * @returns True if the file appears to be a barrel export
235
- */
236
- declare function isBarrelExport(node: DependencyNode): boolean;
237
- /**
238
- * Detect if a file is primarily type definitions
239
- *
240
- * @param node The dependency node to check
241
- * @returns True if the file appears to be primarily types
242
- */
243
- declare function isTypeDefinition(node: DependencyNode): boolean;
244
- /**
245
- * Detect if a file is a utility module
246
- *
247
- * @param node The dependency node to check
248
- * @returns True if the file appears to be a utility module
249
- */
250
- declare function isUtilityModule(node: DependencyNode): boolean;
251
- /**
252
- * Detect if a file is a Lambda/API handler
253
- *
254
- * @param node The dependency node to check
255
- * @returns True if the file appears to be a Lambda handler
256
- */
257
- declare function isLambdaHandler(node: DependencyNode): boolean;
258
- /**
259
- * Detect if a file is a service file
260
- *
261
- * @param node The dependency node to check
262
- * @returns True if the file appears to be a service file
263
- */
264
- declare function isServiceFile(node: DependencyNode): boolean;
265
- /**
266
- * Detect if a file is an email template/layout
267
- *
268
- * @param node The dependency node to check
269
- * @returns True if the file appears to be an email template
270
- */
271
- declare function isEmailTemplate(node: DependencyNode): boolean;
272
- /**
273
- * Detect if a file is a parser/transformer
274
- *
275
- * @param node The dependency node to check
276
- * @returns True if the file appears to be a parser
277
- */
278
- declare function isParserFile(node: DependencyNode): boolean;
279
- /**
280
- * Detect if a file is a session/state management file
281
- *
282
- * @param node The dependency node to check
283
- * @returns True if the file appears to be a session/state file
284
- */
285
- declare function isSessionFile(node: DependencyNode): boolean;
286
- /**
287
- * Detect if a file is a configuration or schema file
288
- *
289
- * @param node The dependency node to check
290
- * @returns True if the file appears to be a config file
291
- */
292
- declare function isConfigFile(node: DependencyNode): boolean;
293
- /**
294
- * Detect if a file is a Next.js App Router page
295
- *
296
- * @param node The dependency node to check
297
- * @returns True if the file appears to be a Next.js page
298
- */
299
- declare function isNextJsPage(node: DependencyNode): boolean;
300
280
  /**
301
281
  * Adjust cohesion score based on file classification
302
282
  *
@@ -317,6 +297,10 @@ declare function adjustFragmentationForClassification(baseFragmentation: number,
317
297
 
318
298
  /**
319
299
  * Group files by domain to detect module clusters
300
+ * @param graph - The dependency graph to analyze
301
+ * @param options - Optional configuration options
302
+ * @param options.useLogScale - Whether to use logarithmic scaling for calculations
303
+ * @returns Array of module clusters
320
304
  */
321
305
  declare function detectModuleClusters(graph: DependencyGraph, options?: {
322
306
  useLogScale?: boolean;
@@ -355,6 +339,9 @@ declare function mapScoreToRating(score: number): string;
355
339
  /**
356
340
  * Generate smart defaults for context analysis based on repository size
357
341
  * Automatically tunes thresholds to target ~10 most serious issues
342
+ * @param directory - The root directory to analyze
343
+ * @param userOptions - Partial user-provided options to merge with defaults
344
+ * @returns Complete ContextAnalyzerOptions with smart defaults
358
345
  */
359
346
  declare function getSmartDefaults(directory: string, userOptions: Partial<ContextAnalyzerOptions>): Promise<ContextAnalyzerOptions>;
360
347
 
@@ -365,14 +352,21 @@ declare function generateSummary(results: ContextAnalysisResult[], options?: any
365
352
 
366
353
  /**
367
354
  * Build co-usage matrix: track which files are imported together
355
+ * @param graph - The dependency graph to analyze
356
+ * @returns Map of file to co-usage counts
368
357
  */
369
358
  declare function buildCoUsageMatrix(graph: DependencyGraph): Map<string, Map<string, number>>;
370
359
  /**
371
360
  * Extract type dependencies from AST exports
361
+ * @param graph - The dependency graph to analyze
362
+ * @returns Map of type references to files that use them
372
363
  */
373
364
  declare function buildTypeGraph(graph: DependencyGraph): Map<string, Set<string>>;
374
365
  /**
375
366
  * Find semantic clusters using co-usage patterns
367
+ * @param coUsageMatrix - The co-usage matrix from buildCoUsageMatrix
368
+ * @param minCoUsage - Minimum co-usage count to consider (default: 3)
369
+ * @returns Map of cluster representative files to their cluster members
376
370
  */
377
371
  declare function findSemanticClusters(coUsageMatrix: Map<string, Map<string, number>>, minCoUsage?: number): Map<string, string[]>;
378
372
  /**
@@ -408,4 +402,4 @@ declare function generateHTMLReport(summary: ReturnType<typeof generateSummary>,
408
402
  */
409
403
  declare function runInteractiveSetup(directory: string, current: any): Promise<any>;
410
404
 
411
- export { Classification, type CoUsageData, type ContextAnalysisResult, type ContextAnalyzerOptions, ContextAnalyzerProvider, type ContextSummary, type DependencyGraph, type DependencyNode, type DomainAssignment, type DomainSignals, type ExportInfo, type FileClassification, type ModuleCluster, type TypeDependency, adjustCohesionForClassification, adjustFragmentationForClassification, analyzeContext, buildCoUsageMatrix, buildDependencyGraph, buildTypeGraph, calculateCohesion, calculateContextBudget, calculateContextScore, calculateDirectoryDistance, calculateDomainConfidence, calculateEnhancedCohesion, calculateFragmentation, calculateImportDepth, calculatePathEntropy, calculateStructuralCohesionFromCoUsage, classifyFile, detectCircularDependencies, detectModuleClusters, displayConsoleReport, extractDomainKeywordsFromPaths, extractExports, findConsolidationCandidates, findSemanticClusters, generateHTMLReport, generateSummary, getClassificationRecommendations, getCoUsageData, getGeneralRecommendations, getSmartDefaults, getTransitiveDependencies, inferDomain, inferDomainFromSemantics, isBarrelExport, isConfigFile, isEmailTemplate, isLambdaHandler, isNextJsPage, isParserFile, isServiceFile, isSessionFile, isTypeDefinition, isUtilityModule, mapScoreToRating, runInteractiveSetup };
405
+ export { Classification, type CoUsageData, type ContextAnalysisResult, type ContextAnalyzerOptions, ContextAnalyzerProvider, type ContextSummary, type DependencyGraph, type DependencyNode, type DomainAssignment, type DomainSignals, type ExportInfo, type FileClassification, type ModuleCluster, type TypeDependency, adjustCohesionForClassification, adjustFragmentationForClassification, analyzeContext, buildCoUsageMatrix, buildDependencyGraph, buildTypeGraph, calculateCohesion, calculateContextBudget, calculateContextScore, calculateDirectoryDistance, calculateDomainConfidence, calculateEnhancedCohesion, calculateFragmentation, calculateImportDepth, calculatePathEntropy, calculateStructuralCohesionFromCoUsage, classifyFile, detectCircularDependencies, detectModuleClusters, displayConsoleReport, extractDomainKeywordsFromPaths, extractExports, findConsolidationCandidates, findSemanticClusters, generateHTMLReport, generateSummary, getClassificationRecommendations, getCoUsageData, getGeneralRecommendations, getSmartDefaults, getTransitiveDependencies, inferDomain, inferDomainFromSemantics, mapScoreToRating, runInteractiveSetup };