@aiready/core 0.9.33 → 0.9.35
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/client.d.mts +2 -0
- package/dist/client.d.ts +2 -0
- package/dist/index.d.mts +19 -1
- package/dist/index.d.ts +19 -1
- package/dist/index.js +139 -6
- package/dist/index.mjs +143 -14
- package/package.json +1 -1
package/dist/client.d.mts
CHANGED
package/dist/client.d.ts
CHANGED
package/dist/index.d.mts
CHANGED
|
@@ -2,6 +2,7 @@ import { ScanOptions, AIReadyConfig, CostConfig, ModelContextTier, Comprehension
|
|
|
2
2
|
export { AnalysisResult, BusinessReport, CONTEXT_TIER_THRESHOLDS, CommonASTNode, DEFAULT_TOOL_WEIGHTS, ExportInfo, GraphData, GraphEdge, GraphIssueSeverity, GraphMetadata, GraphNode, ImportInfo, Issue, IssueType, LANGUAGE_EXTENSIONS, LanguageConfig, Location, Metrics, ParseError, ParseStatistics, Report, SIZE_ADJUSTED_THRESHOLDS, ScoringConfig, ScoringResult, SourceLocation, SourceRange, TOOL_NAME_MAP, calculateOverallScore, formatScore, formatToolScore, generateHTML, getProjectSizeTier, getRating, getRatingDisplay, getRatingWithContext, getRecommendedThreshold, getToolWeight, normalizeToolName, parseWeightString } from './client.mjs';
|
|
3
3
|
|
|
4
4
|
declare const DEFAULT_EXCLUDE: string[];
|
|
5
|
+
declare const VAGUE_FILE_NAMES: Set<string>;
|
|
5
6
|
/**
|
|
6
7
|
* Scan files in a directory using glob patterns
|
|
7
8
|
*
|
|
@@ -12,6 +13,14 @@ declare const DEFAULT_EXCLUDE: string[];
|
|
|
12
13
|
* @returns Array of absolute file paths matching the patterns
|
|
13
14
|
*/
|
|
14
15
|
declare function scanFiles(options: ScanOptions): Promise<string[]>;
|
|
16
|
+
/**
|
|
17
|
+
* Scan for both files and directories, respecting ignore rules.
|
|
18
|
+
* Useful for tools that need to analyze directory structure.
|
|
19
|
+
*/
|
|
20
|
+
declare function scanEntries(options: ScanOptions): Promise<{
|
|
21
|
+
files: string[];
|
|
22
|
+
dirs: string[];
|
|
23
|
+
}>;
|
|
15
24
|
declare function readFileContent(filePath: string): Promise<string>;
|
|
16
25
|
declare function getFileExtension(filePath: string): string;
|
|
17
26
|
declare function isSourceFile(filePath: string): boolean;
|
|
@@ -826,4 +835,13 @@ declare function exportHistory(rootDir: string, format?: 'json' | 'csv'): string
|
|
|
826
835
|
*/
|
|
827
836
|
declare function clearHistory(rootDir: string): void;
|
|
828
837
|
|
|
829
|
-
|
|
838
|
+
/**
|
|
839
|
+
* Get git commit timestamps for each line in a file
|
|
840
|
+
*/
|
|
841
|
+
declare function getFileCommitTimestamps(file: string): Record<number, number>;
|
|
842
|
+
/**
|
|
843
|
+
* Get the latest commit timestamp for a line range
|
|
844
|
+
*/
|
|
845
|
+
declare function getLineRangeLastModifiedCached(lineStamps: Record<number, number>, startLine: number, endLine: number): number;
|
|
846
|
+
|
|
847
|
+
export { AIReadyConfig, type ASTNode, AcceptancePrediction, type AgentGroundingScore, type AiSignalClarity, type AiSignalClaritySignal, type CLIOptions, type ChangeAmplificationScore, type CognitiveLoad, ComprehensionDifficulty, type ConceptCohesion, CostConfig, DEFAULT_COST_CONFIG, DEFAULT_EXCLUDE, type DebtBreakdown, type DependencyHealthScore, type DocDriftRisk, type ExportWithImports, type FileImport, type FileWithDomain, type KnowledgeConcentrationRisk, Language, LanguageParser, type LoadFactor, MODEL_PRICING_PRESETS, ModelContextTier, type ModelPricingPreset, NamingConvention, ParseResult, ParserFactory, type PatternEntropy, ProductivityImpact, PythonParser, type RemediationVelocity, ScanOptions, type ScoreHistoryEntry, type ScoreTrend, type SemanticDistance, type TechnicalDebtInterest, type TestabilityIndex, ToolScoringOutput, TypeScriptParser, VAGUE_FILE_NAMES, calculateAgentGrounding, calculateAiSignalClarity, calculateChangeAmplification, calculateCognitiveLoad, calculateComprehensionDifficulty, calculateConceptCohesion, calculateDependencyHealth, calculateDocDrift, calculateExtendedFutureProofScore, calculateFutureProofScore, calculateImportSimilarity, calculateKnowledgeConcentration, calculateMonthlyCost, calculatePatternEntropy, calculateProductivityImpact, calculateRemediationVelocity, calculateScoreTrend, calculateSemanticDistance, calculateTechnicalDebtInterest, calculateTestabilityIndex, clearHistory, estimateTokens, exportHistory, extractFunctions, extractImports, formatAcceptanceRate, formatCost, formatHours, getDebtBreakdown, getElapsedTime, getFileCommitTimestamps, getFileExtension, getHistorySummary, getLineRangeLastModifiedCached, getModelPreset, getParser, getSupportedLanguages, handleCLIError, handleJSONOutput, isFileSupported, isSourceFile, loadConfig, loadMergedConfig, loadScoreHistory, mergeConfigWithDefaults, parseCode, parseFileExports, predictAcceptanceRate, readFileContent, resolveOutputPath, saveScoreEntry, scanEntries, scanFiles };
|
package/dist/index.d.ts
CHANGED
|
@@ -2,6 +2,7 @@ import { ScanOptions, AIReadyConfig, CostConfig, ModelContextTier, Comprehension
|
|
|
2
2
|
export { AnalysisResult, BusinessReport, CONTEXT_TIER_THRESHOLDS, CommonASTNode, DEFAULT_TOOL_WEIGHTS, ExportInfo, GraphData, GraphEdge, GraphIssueSeverity, GraphMetadata, GraphNode, ImportInfo, Issue, IssueType, LANGUAGE_EXTENSIONS, LanguageConfig, Location, Metrics, ParseError, ParseStatistics, Report, SIZE_ADJUSTED_THRESHOLDS, ScoringConfig, ScoringResult, SourceLocation, SourceRange, TOOL_NAME_MAP, calculateOverallScore, formatScore, formatToolScore, generateHTML, getProjectSizeTier, getRating, getRatingDisplay, getRatingWithContext, getRecommendedThreshold, getToolWeight, normalizeToolName, parseWeightString } from './client.js';
|
|
3
3
|
|
|
4
4
|
declare const DEFAULT_EXCLUDE: string[];
|
|
5
|
+
declare const VAGUE_FILE_NAMES: Set<string>;
|
|
5
6
|
/**
|
|
6
7
|
* Scan files in a directory using glob patterns
|
|
7
8
|
*
|
|
@@ -12,6 +13,14 @@ declare const DEFAULT_EXCLUDE: string[];
|
|
|
12
13
|
* @returns Array of absolute file paths matching the patterns
|
|
13
14
|
*/
|
|
14
15
|
declare function scanFiles(options: ScanOptions): Promise<string[]>;
|
|
16
|
+
/**
|
|
17
|
+
* Scan for both files and directories, respecting ignore rules.
|
|
18
|
+
* Useful for tools that need to analyze directory structure.
|
|
19
|
+
*/
|
|
20
|
+
declare function scanEntries(options: ScanOptions): Promise<{
|
|
21
|
+
files: string[];
|
|
22
|
+
dirs: string[];
|
|
23
|
+
}>;
|
|
15
24
|
declare function readFileContent(filePath: string): Promise<string>;
|
|
16
25
|
declare function getFileExtension(filePath: string): string;
|
|
17
26
|
declare function isSourceFile(filePath: string): boolean;
|
|
@@ -826,4 +835,13 @@ declare function exportHistory(rootDir: string, format?: 'json' | 'csv'): string
|
|
|
826
835
|
*/
|
|
827
836
|
declare function clearHistory(rootDir: string): void;
|
|
828
837
|
|
|
829
|
-
|
|
838
|
+
/**
|
|
839
|
+
* Get git commit timestamps for each line in a file
|
|
840
|
+
*/
|
|
841
|
+
declare function getFileCommitTimestamps(file: string): Record<number, number>;
|
|
842
|
+
/**
|
|
843
|
+
* Get the latest commit timestamp for a line range
|
|
844
|
+
*/
|
|
845
|
+
declare function getLineRangeLastModifiedCached(lineStamps: Record<number, number>, startLine: number, endLine: number): number;
|
|
846
|
+
|
|
847
|
+
export { AIReadyConfig, type ASTNode, AcceptancePrediction, type AgentGroundingScore, type AiSignalClarity, type AiSignalClaritySignal, type CLIOptions, type ChangeAmplificationScore, type CognitiveLoad, ComprehensionDifficulty, type ConceptCohesion, CostConfig, DEFAULT_COST_CONFIG, DEFAULT_EXCLUDE, type DebtBreakdown, type DependencyHealthScore, type DocDriftRisk, type ExportWithImports, type FileImport, type FileWithDomain, type KnowledgeConcentrationRisk, Language, LanguageParser, type LoadFactor, MODEL_PRICING_PRESETS, ModelContextTier, type ModelPricingPreset, NamingConvention, ParseResult, ParserFactory, type PatternEntropy, ProductivityImpact, PythonParser, type RemediationVelocity, ScanOptions, type ScoreHistoryEntry, type ScoreTrend, type SemanticDistance, type TechnicalDebtInterest, type TestabilityIndex, ToolScoringOutput, TypeScriptParser, VAGUE_FILE_NAMES, calculateAgentGrounding, calculateAiSignalClarity, calculateChangeAmplification, calculateCognitiveLoad, calculateComprehensionDifficulty, calculateConceptCohesion, calculateDependencyHealth, calculateDocDrift, calculateExtendedFutureProofScore, calculateFutureProofScore, calculateImportSimilarity, calculateKnowledgeConcentration, calculateMonthlyCost, calculatePatternEntropy, calculateProductivityImpact, calculateRemediationVelocity, calculateScoreTrend, calculateSemanticDistance, calculateTechnicalDebtInterest, calculateTestabilityIndex, clearHistory, estimateTokens, exportHistory, extractFunctions, extractImports, formatAcceptanceRate, formatCost, formatHours, getDebtBreakdown, getElapsedTime, getFileCommitTimestamps, getFileExtension, getHistorySummary, getLineRangeLastModifiedCached, getModelPreset, getParser, getSupportedLanguages, handleCLIError, handleJSONOutput, isFileSupported, isSourceFile, loadConfig, loadMergedConfig, loadScoreHistory, mergeConfigWithDefaults, parseCode, parseFileExports, predictAcceptanceRate, readFileContent, resolveOutputPath, saveScoreEntry, scanEntries, scanFiles };
|
package/dist/index.js
CHANGED
|
@@ -43,6 +43,7 @@ __export(index_exports, {
|
|
|
43
43
|
SIZE_ADJUSTED_THRESHOLDS: () => SIZE_ADJUSTED_THRESHOLDS,
|
|
44
44
|
TOOL_NAME_MAP: () => TOOL_NAME_MAP,
|
|
45
45
|
TypeScriptParser: () => TypeScriptParser,
|
|
46
|
+
VAGUE_FILE_NAMES: () => VAGUE_FILE_NAMES,
|
|
46
47
|
calculateAgentGrounding: () => calculateAgentGrounding,
|
|
47
48
|
calculateAiSignalClarity: () => calculateAiSignalClarity,
|
|
48
49
|
calculateChangeAmplification: () => calculateChangeAmplification,
|
|
@@ -77,8 +78,10 @@ __export(index_exports, {
|
|
|
77
78
|
generateHTML: () => generateHTML,
|
|
78
79
|
getDebtBreakdown: () => getDebtBreakdown,
|
|
79
80
|
getElapsedTime: () => getElapsedTime,
|
|
81
|
+
getFileCommitTimestamps: () => getFileCommitTimestamps,
|
|
80
82
|
getFileExtension: () => getFileExtension,
|
|
81
83
|
getHistorySummary: () => getHistorySummary,
|
|
84
|
+
getLineRangeLastModifiedCached: () => getLineRangeLastModifiedCached,
|
|
82
85
|
getModelPreset: () => getModelPreset,
|
|
83
86
|
getParser: () => getParser,
|
|
84
87
|
getProjectSizeTier: () => getProjectSizeTier,
|
|
@@ -104,6 +107,7 @@ __export(index_exports, {
|
|
|
104
107
|
readFileContent: () => readFileContent,
|
|
105
108
|
resolveOutputPath: () => resolveOutputPath,
|
|
106
109
|
saveScoreEntry: () => saveScoreEntry,
|
|
110
|
+
scanEntries: () => scanEntries,
|
|
107
111
|
scanFiles: () => scanFiles
|
|
108
112
|
});
|
|
109
113
|
module.exports = __toCommonJS(index_exports);
|
|
@@ -159,6 +163,8 @@ var DEFAULT_EXCLUDE = [
|
|
|
159
163
|
"**/cdk.out/**",
|
|
160
164
|
// Framework-specific build dirs
|
|
161
165
|
"**/.next/**",
|
|
166
|
+
"**/.sst/**",
|
|
167
|
+
"**/.open-next/**",
|
|
162
168
|
"**/.nuxt/**",
|
|
163
169
|
"**/.vuepress/**",
|
|
164
170
|
"**/.cache/**",
|
|
@@ -190,6 +196,28 @@ var DEFAULT_EXCLUDE = [
|
|
|
190
196
|
"**/*.log",
|
|
191
197
|
"**/.DS_Store"
|
|
192
198
|
];
|
|
199
|
+
var VAGUE_FILE_NAMES = /* @__PURE__ */ new Set([
|
|
200
|
+
"utils",
|
|
201
|
+
"helpers",
|
|
202
|
+
"helper",
|
|
203
|
+
"misc",
|
|
204
|
+
"common",
|
|
205
|
+
"shared",
|
|
206
|
+
"tools",
|
|
207
|
+
"util",
|
|
208
|
+
"lib",
|
|
209
|
+
"libs",
|
|
210
|
+
"stuff",
|
|
211
|
+
"functions",
|
|
212
|
+
"methods",
|
|
213
|
+
"handlers",
|
|
214
|
+
"data",
|
|
215
|
+
"temp",
|
|
216
|
+
"tmp",
|
|
217
|
+
"test-utils",
|
|
218
|
+
"test-helpers",
|
|
219
|
+
"mocks"
|
|
220
|
+
]);
|
|
193
221
|
async function scanFiles(options) {
|
|
194
222
|
const {
|
|
195
223
|
rootDir,
|
|
@@ -207,20 +235,35 @@ async function scanFiles(options) {
|
|
|
207
235
|
ignoreFromFile = [];
|
|
208
236
|
}
|
|
209
237
|
}
|
|
238
|
+
const TEST_PATTERNS = ["**/*.test.*", "**/*.spec.*", "**/__tests__/**", "**/test/**", "**/tests/**"];
|
|
239
|
+
const baseExclude = options.includeTests ? DEFAULT_EXCLUDE.filter((p) => !TEST_PATTERNS.includes(p)) : DEFAULT_EXCLUDE;
|
|
210
240
|
const finalExclude = [
|
|
211
|
-
.../* @__PURE__ */ new Set([...exclude || [], ...ignoreFromFile, ...
|
|
241
|
+
.../* @__PURE__ */ new Set([...exclude || [], ...ignoreFromFile, ...baseExclude])
|
|
212
242
|
];
|
|
213
243
|
const files = await (0, import_glob.glob)(include, {
|
|
214
244
|
cwd: rootDir,
|
|
215
245
|
ignore: finalExclude,
|
|
216
246
|
absolute: true
|
|
217
247
|
});
|
|
218
|
-
const
|
|
219
|
-
|
|
248
|
+
const gitignoreFiles = await (0, import_glob.glob)("**/.gitignore", {
|
|
249
|
+
cwd: rootDir,
|
|
250
|
+
ignore: finalExclude,
|
|
251
|
+
absolute: true
|
|
252
|
+
});
|
|
253
|
+
if (gitignoreFiles.length > 0) {
|
|
220
254
|
try {
|
|
221
|
-
const gitTxt = await (0, import_promises.readFile)(gitignorePath, "utf-8");
|
|
222
255
|
const ig = (0, import_ignore.default)();
|
|
223
|
-
|
|
256
|
+
for (const gitignorePath of gitignoreFiles) {
|
|
257
|
+
const gitTxt = await (0, import_promises.readFile)(gitignorePath, "utf-8");
|
|
258
|
+
const gitignoreDir = (0, import_path.dirname)(gitignorePath);
|
|
259
|
+
const relativePrefix = (0, import_path.relative)(rootDir || ".", gitignoreDir).replace(/\\/g, "/");
|
|
260
|
+
const patterns = gitTxt.split(/\r?\n/).map((s) => s.trim()).filter(Boolean).filter((l) => !l.startsWith("#"));
|
|
261
|
+
if (relativePrefix === "." || relativePrefix === "") {
|
|
262
|
+
ig.add(patterns);
|
|
263
|
+
} else {
|
|
264
|
+
ig.add(patterns.map((p) => p.startsWith("/") ? `${relativePrefix}${p}` : `${relativePrefix}/**/${p}`));
|
|
265
|
+
}
|
|
266
|
+
}
|
|
224
267
|
const filtered = files.filter((f) => {
|
|
225
268
|
let rel = (0, import_path.relative)(rootDir || ".", f).replace(/\\/g, "/");
|
|
226
269
|
if (rel === "") rel = f;
|
|
@@ -233,6 +276,54 @@ async function scanFiles(options) {
|
|
|
233
276
|
}
|
|
234
277
|
return files;
|
|
235
278
|
}
|
|
279
|
+
async function scanEntries(options) {
|
|
280
|
+
const files = await scanFiles(options);
|
|
281
|
+
const { rootDir, include = ["**/*"], exclude, includeTests } = options;
|
|
282
|
+
const ignoreFilePath = (0, import_path.join)(rootDir || ".", ".aireadyignore");
|
|
283
|
+
let ignoreFromFile = [];
|
|
284
|
+
if ((0, import_fs.existsSync)(ignoreFilePath)) {
|
|
285
|
+
try {
|
|
286
|
+
const txt = await (0, import_promises.readFile)(ignoreFilePath, "utf-8");
|
|
287
|
+
ignoreFromFile = txt.split(/\r?\n/).map((s) => s.trim()).filter(Boolean).filter((l) => !l.startsWith("#")).filter((l) => !l.startsWith("!"));
|
|
288
|
+
} catch (e) {
|
|
289
|
+
ignoreFromFile = [];
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
const TEST_PATTERNS = ["**/*.test.*", "**/*.spec.*", "**/__tests__/**", "**/test/**", "**/tests/**"];
|
|
293
|
+
const baseExclude = includeTests ? DEFAULT_EXCLUDE.filter((p) => !TEST_PATTERNS.includes(p)) : DEFAULT_EXCLUDE;
|
|
294
|
+
const finalExclude = [.../* @__PURE__ */ new Set([...exclude || [], ...ignoreFromFile, ...baseExclude])];
|
|
295
|
+
const dirs = await (0, import_glob.glob)("**/", {
|
|
296
|
+
cwd: rootDir,
|
|
297
|
+
ignore: finalExclude,
|
|
298
|
+
absolute: true
|
|
299
|
+
});
|
|
300
|
+
const gitignoreFiles = await (0, import_glob.glob)("**/.gitignore", {
|
|
301
|
+
cwd: rootDir,
|
|
302
|
+
ignore: finalExclude,
|
|
303
|
+
absolute: true
|
|
304
|
+
});
|
|
305
|
+
if (gitignoreFiles.length > 0) {
|
|
306
|
+
const ig = (0, import_ignore.default)();
|
|
307
|
+
for (const gitignorePath of gitignoreFiles) {
|
|
308
|
+
const gitTxt = await (0, import_promises.readFile)(gitignorePath, "utf-8");
|
|
309
|
+
const gitignoreDir = (0, import_path.dirname)(gitignorePath);
|
|
310
|
+
const relativePrefix = (0, import_path.relative)(rootDir || ".", gitignoreDir).replace(/\\/g, "/");
|
|
311
|
+
const patterns = gitTxt.split(/\r?\n/).map((s) => s.trim()).filter(Boolean).filter((l) => !l.startsWith("#"));
|
|
312
|
+
if (relativePrefix === "." || relativePrefix === "") {
|
|
313
|
+
ig.add(patterns);
|
|
314
|
+
} else {
|
|
315
|
+
ig.add(patterns.map((p) => p.startsWith("/") ? `${relativePrefix}${p}` : `${relativePrefix}/**/${p}`));
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
const filteredDirs = dirs.filter((d) => {
|
|
319
|
+
let rel = (0, import_path.relative)(rootDir || ".", d).replace(/\\/g, "/").replace(/\/$/, "");
|
|
320
|
+
if (rel === "") return true;
|
|
321
|
+
return !ig.ignores(rel);
|
|
322
|
+
});
|
|
323
|
+
return { files, dirs: filteredDirs };
|
|
324
|
+
}
|
|
325
|
+
return { files, dirs };
|
|
326
|
+
}
|
|
236
327
|
async function readFileContent(filePath) {
|
|
237
328
|
return (0, import_promises.readFile)(filePath, "utf-8");
|
|
238
329
|
}
|
|
@@ -457,9 +548,14 @@ async function loadConfig(rootDir) {
|
|
|
457
548
|
return config;
|
|
458
549
|
} catch (error) {
|
|
459
550
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
460
|
-
|
|
551
|
+
const e = new Error(
|
|
461
552
|
`Failed to load config from ${configPath}: ${errorMessage}`
|
|
462
553
|
);
|
|
554
|
+
try {
|
|
555
|
+
e.cause = error instanceof Error ? error : void 0;
|
|
556
|
+
} catch {
|
|
557
|
+
}
|
|
558
|
+
throw e;
|
|
463
559
|
}
|
|
464
560
|
}
|
|
465
561
|
}
|
|
@@ -2806,6 +2902,39 @@ function clearHistory(rootDir) {
|
|
|
2806
2902
|
(0, import_fs4.writeFileSync)(historyPath, JSON.stringify([]));
|
|
2807
2903
|
}
|
|
2808
2904
|
}
|
|
2905
|
+
|
|
2906
|
+
// src/utils/history-git.ts
|
|
2907
|
+
var import_child_process = require("child_process");
|
|
2908
|
+
function getFileCommitTimestamps(file) {
|
|
2909
|
+
const lineStamps = {};
|
|
2910
|
+
try {
|
|
2911
|
+
const output = (0, import_child_process.execSync)(`git blame -t "${file}"`, {
|
|
2912
|
+
encoding: "utf-8",
|
|
2913
|
+
stdio: ["ignore", "pipe", "ignore"]
|
|
2914
|
+
});
|
|
2915
|
+
const lines = output.split("\n");
|
|
2916
|
+
for (const line of lines) {
|
|
2917
|
+
if (!line) continue;
|
|
2918
|
+
const match = line.match(/^\S+\s+\(.*?(\d{10,})\s+[-+]\d+\s+(\d+)\)/);
|
|
2919
|
+
if (match) {
|
|
2920
|
+
const ts = parseInt(match[1], 10);
|
|
2921
|
+
const ln = parseInt(match[2], 10);
|
|
2922
|
+
lineStamps[ln] = ts;
|
|
2923
|
+
}
|
|
2924
|
+
}
|
|
2925
|
+
} catch {
|
|
2926
|
+
}
|
|
2927
|
+
return lineStamps;
|
|
2928
|
+
}
|
|
2929
|
+
function getLineRangeLastModifiedCached(lineStamps, startLine, endLine) {
|
|
2930
|
+
let latest = 0;
|
|
2931
|
+
for (let i = startLine; i <= endLine; i++) {
|
|
2932
|
+
if (lineStamps[i] && lineStamps[i] > latest) {
|
|
2933
|
+
latest = lineStamps[i];
|
|
2934
|
+
}
|
|
2935
|
+
}
|
|
2936
|
+
return latest;
|
|
2937
|
+
}
|
|
2809
2938
|
// Annotate the CommonJS export names for ESM import in node:
|
|
2810
2939
|
0 && (module.exports = {
|
|
2811
2940
|
CONTEXT_TIER_THRESHOLDS,
|
|
@@ -2821,6 +2950,7 @@ function clearHistory(rootDir) {
|
|
|
2821
2950
|
SIZE_ADJUSTED_THRESHOLDS,
|
|
2822
2951
|
TOOL_NAME_MAP,
|
|
2823
2952
|
TypeScriptParser,
|
|
2953
|
+
VAGUE_FILE_NAMES,
|
|
2824
2954
|
calculateAgentGrounding,
|
|
2825
2955
|
calculateAiSignalClarity,
|
|
2826
2956
|
calculateChangeAmplification,
|
|
@@ -2855,8 +2985,10 @@ function clearHistory(rootDir) {
|
|
|
2855
2985
|
generateHTML,
|
|
2856
2986
|
getDebtBreakdown,
|
|
2857
2987
|
getElapsedTime,
|
|
2988
|
+
getFileCommitTimestamps,
|
|
2858
2989
|
getFileExtension,
|
|
2859
2990
|
getHistorySummary,
|
|
2991
|
+
getLineRangeLastModifiedCached,
|
|
2860
2992
|
getModelPreset,
|
|
2861
2993
|
getParser,
|
|
2862
2994
|
getProjectSizeTier,
|
|
@@ -2882,5 +3014,6 @@ function clearHistory(rootDir) {
|
|
|
2882
3014
|
readFileContent,
|
|
2883
3015
|
resolveOutputPath,
|
|
2884
3016
|
saveScoreEntry,
|
|
3017
|
+
scanEntries,
|
|
2885
3018
|
scanFiles
|
|
2886
3019
|
});
|
package/dist/index.mjs
CHANGED
|
@@ -24,7 +24,7 @@ import {
|
|
|
24
24
|
import { glob } from "glob";
|
|
25
25
|
import { readFile } from "fs/promises";
|
|
26
26
|
import { existsSync } from "fs";
|
|
27
|
-
import { join, relative } from "path";
|
|
27
|
+
import { join, relative, dirname } from "path";
|
|
28
28
|
import ignorePkg from "ignore";
|
|
29
29
|
var DEFAULT_EXCLUDE = [
|
|
30
30
|
// Dependencies
|
|
@@ -40,6 +40,8 @@ var DEFAULT_EXCLUDE = [
|
|
|
40
40
|
"**/cdk.out/**",
|
|
41
41
|
// Framework-specific build dirs
|
|
42
42
|
"**/.next/**",
|
|
43
|
+
"**/.sst/**",
|
|
44
|
+
"**/.open-next/**",
|
|
43
45
|
"**/.nuxt/**",
|
|
44
46
|
"**/.vuepress/**",
|
|
45
47
|
"**/.cache/**",
|
|
@@ -71,6 +73,28 @@ var DEFAULT_EXCLUDE = [
|
|
|
71
73
|
"**/*.log",
|
|
72
74
|
"**/.DS_Store"
|
|
73
75
|
];
|
|
76
|
+
var VAGUE_FILE_NAMES = /* @__PURE__ */ new Set([
|
|
77
|
+
"utils",
|
|
78
|
+
"helpers",
|
|
79
|
+
"helper",
|
|
80
|
+
"misc",
|
|
81
|
+
"common",
|
|
82
|
+
"shared",
|
|
83
|
+
"tools",
|
|
84
|
+
"util",
|
|
85
|
+
"lib",
|
|
86
|
+
"libs",
|
|
87
|
+
"stuff",
|
|
88
|
+
"functions",
|
|
89
|
+
"methods",
|
|
90
|
+
"handlers",
|
|
91
|
+
"data",
|
|
92
|
+
"temp",
|
|
93
|
+
"tmp",
|
|
94
|
+
"test-utils",
|
|
95
|
+
"test-helpers",
|
|
96
|
+
"mocks"
|
|
97
|
+
]);
|
|
74
98
|
async function scanFiles(options) {
|
|
75
99
|
const {
|
|
76
100
|
rootDir,
|
|
@@ -88,20 +112,35 @@ async function scanFiles(options) {
|
|
|
88
112
|
ignoreFromFile = [];
|
|
89
113
|
}
|
|
90
114
|
}
|
|
115
|
+
const TEST_PATTERNS = ["**/*.test.*", "**/*.spec.*", "**/__tests__/**", "**/test/**", "**/tests/**"];
|
|
116
|
+
const baseExclude = options.includeTests ? DEFAULT_EXCLUDE.filter((p) => !TEST_PATTERNS.includes(p)) : DEFAULT_EXCLUDE;
|
|
91
117
|
const finalExclude = [
|
|
92
|
-
.../* @__PURE__ */ new Set([...exclude || [], ...ignoreFromFile, ...
|
|
118
|
+
.../* @__PURE__ */ new Set([...exclude || [], ...ignoreFromFile, ...baseExclude])
|
|
93
119
|
];
|
|
94
120
|
const files = await glob(include, {
|
|
95
121
|
cwd: rootDir,
|
|
96
122
|
ignore: finalExclude,
|
|
97
123
|
absolute: true
|
|
98
124
|
});
|
|
99
|
-
const
|
|
100
|
-
|
|
125
|
+
const gitignoreFiles = await glob("**/.gitignore", {
|
|
126
|
+
cwd: rootDir,
|
|
127
|
+
ignore: finalExclude,
|
|
128
|
+
absolute: true
|
|
129
|
+
});
|
|
130
|
+
if (gitignoreFiles.length > 0) {
|
|
101
131
|
try {
|
|
102
|
-
const gitTxt = await readFile(gitignorePath, "utf-8");
|
|
103
132
|
const ig = ignorePkg();
|
|
104
|
-
|
|
133
|
+
for (const gitignorePath of gitignoreFiles) {
|
|
134
|
+
const gitTxt = await readFile(gitignorePath, "utf-8");
|
|
135
|
+
const gitignoreDir = dirname(gitignorePath);
|
|
136
|
+
const relativePrefix = relative(rootDir || ".", gitignoreDir).replace(/\\/g, "/");
|
|
137
|
+
const patterns = gitTxt.split(/\r?\n/).map((s) => s.trim()).filter(Boolean).filter((l) => !l.startsWith("#"));
|
|
138
|
+
if (relativePrefix === "." || relativePrefix === "") {
|
|
139
|
+
ig.add(patterns);
|
|
140
|
+
} else {
|
|
141
|
+
ig.add(patterns.map((p) => p.startsWith("/") ? `${relativePrefix}${p}` : `${relativePrefix}/**/${p}`));
|
|
142
|
+
}
|
|
143
|
+
}
|
|
105
144
|
const filtered = files.filter((f) => {
|
|
106
145
|
let rel = relative(rootDir || ".", f).replace(/\\/g, "/");
|
|
107
146
|
if (rel === "") rel = f;
|
|
@@ -114,6 +153,54 @@ async function scanFiles(options) {
|
|
|
114
153
|
}
|
|
115
154
|
return files;
|
|
116
155
|
}
|
|
156
|
+
async function scanEntries(options) {
|
|
157
|
+
const files = await scanFiles(options);
|
|
158
|
+
const { rootDir, include = ["**/*"], exclude, includeTests } = options;
|
|
159
|
+
const ignoreFilePath = join(rootDir || ".", ".aireadyignore");
|
|
160
|
+
let ignoreFromFile = [];
|
|
161
|
+
if (existsSync(ignoreFilePath)) {
|
|
162
|
+
try {
|
|
163
|
+
const txt = await readFile(ignoreFilePath, "utf-8");
|
|
164
|
+
ignoreFromFile = txt.split(/\r?\n/).map((s) => s.trim()).filter(Boolean).filter((l) => !l.startsWith("#")).filter((l) => !l.startsWith("!"));
|
|
165
|
+
} catch (e) {
|
|
166
|
+
ignoreFromFile = [];
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
const TEST_PATTERNS = ["**/*.test.*", "**/*.spec.*", "**/__tests__/**", "**/test/**", "**/tests/**"];
|
|
170
|
+
const baseExclude = includeTests ? DEFAULT_EXCLUDE.filter((p) => !TEST_PATTERNS.includes(p)) : DEFAULT_EXCLUDE;
|
|
171
|
+
const finalExclude = [.../* @__PURE__ */ new Set([...exclude || [], ...ignoreFromFile, ...baseExclude])];
|
|
172
|
+
const dirs = await glob("**/", {
|
|
173
|
+
cwd: rootDir,
|
|
174
|
+
ignore: finalExclude,
|
|
175
|
+
absolute: true
|
|
176
|
+
});
|
|
177
|
+
const gitignoreFiles = await glob("**/.gitignore", {
|
|
178
|
+
cwd: rootDir,
|
|
179
|
+
ignore: finalExclude,
|
|
180
|
+
absolute: true
|
|
181
|
+
});
|
|
182
|
+
if (gitignoreFiles.length > 0) {
|
|
183
|
+
const ig = ignorePkg();
|
|
184
|
+
for (const gitignorePath of gitignoreFiles) {
|
|
185
|
+
const gitTxt = await readFile(gitignorePath, "utf-8");
|
|
186
|
+
const gitignoreDir = dirname(gitignorePath);
|
|
187
|
+
const relativePrefix = relative(rootDir || ".", gitignoreDir).replace(/\\/g, "/");
|
|
188
|
+
const patterns = gitTxt.split(/\r?\n/).map((s) => s.trim()).filter(Boolean).filter((l) => !l.startsWith("#"));
|
|
189
|
+
if (relativePrefix === "." || relativePrefix === "") {
|
|
190
|
+
ig.add(patterns);
|
|
191
|
+
} else {
|
|
192
|
+
ig.add(patterns.map((p) => p.startsWith("/") ? `${relativePrefix}${p}` : `${relativePrefix}/**/${p}`));
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
const filteredDirs = dirs.filter((d) => {
|
|
196
|
+
let rel = relative(rootDir || ".", d).replace(/\\/g, "/").replace(/\/$/, "");
|
|
197
|
+
if (rel === "") return true;
|
|
198
|
+
return !ig.ignores(rel);
|
|
199
|
+
});
|
|
200
|
+
return { files, dirs: filteredDirs };
|
|
201
|
+
}
|
|
202
|
+
return { files, dirs };
|
|
203
|
+
}
|
|
117
204
|
async function readFileContent(filePath) {
|
|
118
205
|
return readFile(filePath, "utf-8");
|
|
119
206
|
}
|
|
@@ -306,7 +393,7 @@ function estimateTokens(text) {
|
|
|
306
393
|
|
|
307
394
|
// src/utils/config.ts
|
|
308
395
|
import { readFileSync, existsSync as existsSync2 } from "fs";
|
|
309
|
-
import { join as join2, resolve, dirname } from "path";
|
|
396
|
+
import { join as join2, resolve, dirname as dirname2 } from "path";
|
|
310
397
|
import { pathToFileURL } from "url";
|
|
311
398
|
var CONFIG_FILES = [
|
|
312
399
|
"aiready.json",
|
|
@@ -338,13 +425,18 @@ async function loadConfig(rootDir) {
|
|
|
338
425
|
return config;
|
|
339
426
|
} catch (error) {
|
|
340
427
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
341
|
-
|
|
428
|
+
const e = new Error(
|
|
342
429
|
`Failed to load config from ${configPath}: ${errorMessage}`
|
|
343
430
|
);
|
|
431
|
+
try {
|
|
432
|
+
e.cause = error instanceof Error ? error : void 0;
|
|
433
|
+
} catch {
|
|
434
|
+
}
|
|
435
|
+
throw e;
|
|
344
436
|
}
|
|
345
437
|
}
|
|
346
438
|
}
|
|
347
|
-
const parent =
|
|
439
|
+
const parent = dirname2(currentDir);
|
|
348
440
|
if (parent === currentDir) {
|
|
349
441
|
break;
|
|
350
442
|
}
|
|
@@ -377,7 +469,7 @@ function mergeConfigWithDefaults(userConfig, defaults) {
|
|
|
377
469
|
|
|
378
470
|
// src/utils/cli-helpers.ts
|
|
379
471
|
import { writeFileSync, mkdirSync, existsSync as existsSync3 } from "fs";
|
|
380
|
-
import { join as join3, dirname as
|
|
472
|
+
import { join as join3, dirname as dirname3 } from "path";
|
|
381
473
|
function resolveOutputPath(userPath, defaultFilename, workingDir = process.cwd()) {
|
|
382
474
|
let outputPath;
|
|
383
475
|
if (userPath) {
|
|
@@ -386,7 +478,7 @@ function resolveOutputPath(userPath, defaultFilename, workingDir = process.cwd()
|
|
|
386
478
|
const aireadyDir = join3(workingDir, ".aiready");
|
|
387
479
|
outputPath = join3(aireadyDir, defaultFilename);
|
|
388
480
|
}
|
|
389
|
-
const parentDir =
|
|
481
|
+
const parentDir = dirname3(outputPath);
|
|
390
482
|
if (!existsSync3(parentDir)) {
|
|
391
483
|
mkdirSync(parentDir, { recursive: true });
|
|
392
484
|
}
|
|
@@ -404,7 +496,7 @@ async function loadMergedConfig(directory, defaults, cliOptions) {
|
|
|
404
496
|
}
|
|
405
497
|
function handleJSONOutput(data, outputFile, successMessage) {
|
|
406
498
|
if (outputFile) {
|
|
407
|
-
const dir =
|
|
499
|
+
const dir = dirname3(outputFile);
|
|
408
500
|
if (!existsSync3(dir)) {
|
|
409
501
|
mkdirSync(dir, { recursive: true });
|
|
410
502
|
}
|
|
@@ -2258,7 +2350,7 @@ function calculateExtendedFutureProofScore(params) {
|
|
|
2258
2350
|
|
|
2259
2351
|
// src/utils/history.ts
|
|
2260
2352
|
import { readFileSync as readFileSync2, writeFileSync as writeFileSync2, existsSync as existsSync4, mkdirSync as mkdirSync2 } from "fs";
|
|
2261
|
-
import { join as join4, dirname as
|
|
2353
|
+
import { join as join4, dirname as dirname4 } from "path";
|
|
2262
2354
|
function getHistoryPath(rootDir) {
|
|
2263
2355
|
return join4(rootDir, ".aiready", "history.json");
|
|
2264
2356
|
}
|
|
@@ -2277,7 +2369,7 @@ function loadScoreHistory(rootDir) {
|
|
|
2277
2369
|
}
|
|
2278
2370
|
function saveScoreEntry(rootDir, entry) {
|
|
2279
2371
|
const historyPath = getHistoryPath(rootDir);
|
|
2280
|
-
const historyDir =
|
|
2372
|
+
const historyDir = dirname4(historyPath);
|
|
2281
2373
|
if (!existsSync4(historyDir)) {
|
|
2282
2374
|
mkdirSync2(historyDir, { recursive: true });
|
|
2283
2375
|
}
|
|
@@ -2329,6 +2421,39 @@ function clearHistory(rootDir) {
|
|
|
2329
2421
|
writeFileSync2(historyPath, JSON.stringify([]));
|
|
2330
2422
|
}
|
|
2331
2423
|
}
|
|
2424
|
+
|
|
2425
|
+
// src/utils/history-git.ts
|
|
2426
|
+
import { execSync } from "child_process";
|
|
2427
|
+
function getFileCommitTimestamps(file) {
|
|
2428
|
+
const lineStamps = {};
|
|
2429
|
+
try {
|
|
2430
|
+
const output = execSync(`git blame -t "${file}"`, {
|
|
2431
|
+
encoding: "utf-8",
|
|
2432
|
+
stdio: ["ignore", "pipe", "ignore"]
|
|
2433
|
+
});
|
|
2434
|
+
const lines = output.split("\n");
|
|
2435
|
+
for (const line of lines) {
|
|
2436
|
+
if (!line) continue;
|
|
2437
|
+
const match = line.match(/^\S+\s+\(.*?(\d{10,})\s+[-+]\d+\s+(\d+)\)/);
|
|
2438
|
+
if (match) {
|
|
2439
|
+
const ts = parseInt(match[1], 10);
|
|
2440
|
+
const ln = parseInt(match[2], 10);
|
|
2441
|
+
lineStamps[ln] = ts;
|
|
2442
|
+
}
|
|
2443
|
+
}
|
|
2444
|
+
} catch {
|
|
2445
|
+
}
|
|
2446
|
+
return lineStamps;
|
|
2447
|
+
}
|
|
2448
|
+
function getLineRangeLastModifiedCached(lineStamps, startLine, endLine) {
|
|
2449
|
+
let latest = 0;
|
|
2450
|
+
for (let i = startLine; i <= endLine; i++) {
|
|
2451
|
+
if (lineStamps[i] && lineStamps[i] > latest) {
|
|
2452
|
+
latest = lineStamps[i];
|
|
2453
|
+
}
|
|
2454
|
+
}
|
|
2455
|
+
return latest;
|
|
2456
|
+
}
|
|
2332
2457
|
export {
|
|
2333
2458
|
CONTEXT_TIER_THRESHOLDS,
|
|
2334
2459
|
DEFAULT_COST_CONFIG,
|
|
@@ -2343,6 +2468,7 @@ export {
|
|
|
2343
2468
|
SIZE_ADJUSTED_THRESHOLDS,
|
|
2344
2469
|
TOOL_NAME_MAP,
|
|
2345
2470
|
TypeScriptParser,
|
|
2471
|
+
VAGUE_FILE_NAMES,
|
|
2346
2472
|
calculateAgentGrounding,
|
|
2347
2473
|
calculateAiSignalClarity,
|
|
2348
2474
|
calculateChangeAmplification,
|
|
@@ -2377,8 +2503,10 @@ export {
|
|
|
2377
2503
|
generateHTML,
|
|
2378
2504
|
getDebtBreakdown,
|
|
2379
2505
|
getElapsedTime,
|
|
2506
|
+
getFileCommitTimestamps,
|
|
2380
2507
|
getFileExtension,
|
|
2381
2508
|
getHistorySummary,
|
|
2509
|
+
getLineRangeLastModifiedCached,
|
|
2382
2510
|
getModelPreset,
|
|
2383
2511
|
getParser,
|
|
2384
2512
|
getProjectSizeTier,
|
|
@@ -2404,5 +2532,6 @@ export {
|
|
|
2404
2532
|
readFileContent,
|
|
2405
2533
|
resolveOutputPath,
|
|
2406
2534
|
saveScoreEntry,
|
|
2535
|
+
scanEntries,
|
|
2407
2536
|
scanFiles
|
|
2408
2537
|
};
|