@aiready/cli 0.3.3 → 0.3.5
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/.turbo/turbo-build.log +7 -7
- package/dist/cli.js +42 -63
- package/dist/cli.mjs +41 -62
- package/package.json +4 -4
- package/src/cli.ts +46 -75
package/.turbo/turbo-build.log
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
|
|
2
2
|
|
|
3
|
-
> @aiready/cli@0.3.
|
|
3
|
+
> @aiready/cli@0.3.5 build /Users/pengcao/projects/aiready/packages/cli
|
|
4
4
|
> tsup src/index.ts src/cli.ts --format cjs,esm --dts
|
|
5
5
|
|
|
6
6
|
[34mCLI[39m Building entry: src/cli.ts, src/index.ts
|
|
@@ -9,15 +9,15 @@
|
|
|
9
9
|
[34mCLI[39m Target: es2020
|
|
10
10
|
[34mCJS[39m Build start
|
|
11
11
|
[34mESM[39m Build start
|
|
12
|
+
[32mCJS[39m [1mdist/cli.js [22m[32m10.43 KB[39m
|
|
12
13
|
[32mCJS[39m [1mdist/index.js [22m[32m2.57 KB[39m
|
|
13
|
-
[32mCJS[39m
|
|
14
|
-
[32mCJS[39m ⚡️ Build success in 56ms
|
|
15
|
-
[32mESM[39m [1mdist/chunk-KZKXZKES.mjs [22m[32m1.45 KB[39m
|
|
16
|
-
[32mESM[39m [1mdist/cli.mjs [22m[32m8.12 KB[39m
|
|
14
|
+
[32mCJS[39m ⚡️ Build success in 60ms
|
|
17
15
|
[32mESM[39m [1mdist/index.mjs [22m[32m138.00 B[39m
|
|
18
|
-
[32mESM[39m
|
|
16
|
+
[32mESM[39m [1mdist/chunk-KZKXZKES.mjs [22m[32m1.45 KB[39m
|
|
17
|
+
[32mESM[39m [1mdist/cli.mjs [22m[32m7.58 KB[39m
|
|
18
|
+
[32mESM[39m ⚡️ Build success in 60ms
|
|
19
19
|
DTS Build start
|
|
20
|
-
DTS ⚡️ Build success in
|
|
20
|
+
DTS ⚡️ Build success in 523ms
|
|
21
21
|
DTS dist/cli.d.ts 20.00 B
|
|
22
22
|
DTS dist/index.d.ts 731.00 B
|
|
23
23
|
DTS dist/cli.d.mts 20.00 B
|
package/dist/cli.js
CHANGED
|
@@ -78,18 +78,16 @@ function generateUnifiedSummary(result) {
|
|
|
78
78
|
|
|
79
79
|
// src/cli.ts
|
|
80
80
|
var import_chalk = __toESM(require("chalk"));
|
|
81
|
-
var import_fs = require("fs");
|
|
82
81
|
var import_path = require("path");
|
|
83
82
|
var import_core = require("@aiready/core");
|
|
84
|
-
var
|
|
85
|
-
var packageJson = JSON.parse((0,
|
|
83
|
+
var import_fs = require("fs");
|
|
84
|
+
var packageJson = JSON.parse((0, import_fs.readFileSync)((0, import_path.join)(__dirname, "../package.json"), "utf8"));
|
|
86
85
|
var program = new import_commander.Command();
|
|
87
86
|
program.name("aiready").description("AIReady - Unified AI-readiness analysis tools").version(packageJson.version).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");
|
|
88
87
|
program.command("scan").description("Run unified analysis on a codebase").argument("<directory>", "Directory to analyze").option("-t, --tools <tools>", "Tools to run (comma-separated: patterns,context)", "patterns,context").option("--include <patterns>", "File patterns to include (comma-separated)").option("--exclude <patterns>", "File patterns to exclude (comma-separated)").option("-o, --output <format>", "Output format: console, json", "console").option("--output-file <path>", "Output file path (for json)").action(async (directory, options) => {
|
|
89
88
|
console.log(import_chalk.default.blue("\u{1F680} Starting AIReady unified analysis...\n"));
|
|
90
89
|
const startTime = Date.now();
|
|
91
90
|
try {
|
|
92
|
-
const config = (0, import_core.loadConfig)(directory);
|
|
93
91
|
const defaults = {
|
|
94
92
|
tools: ["patterns", "context"],
|
|
95
93
|
include: void 0,
|
|
@@ -99,17 +97,15 @@ program.command("scan").description("Run unified analysis on a codebase").argume
|
|
|
99
97
|
file: void 0
|
|
100
98
|
}
|
|
101
99
|
};
|
|
102
|
-
const
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
exclude: options.exclude?.split(",") || mergedConfig.exclude
|
|
108
|
-
};
|
|
100
|
+
const finalOptions = (0, import_core.loadMergedConfig)(directory, defaults, {
|
|
101
|
+
tools: options.tools ? options.tools.split(",").map((t) => t.trim()) : void 0,
|
|
102
|
+
include: options.include?.split(","),
|
|
103
|
+
exclude: options.exclude?.split(",")
|
|
104
|
+
});
|
|
109
105
|
const results = await analyzeUnified(finalOptions);
|
|
110
|
-
const elapsedTime = (
|
|
111
|
-
const outputFormat = options.output ||
|
|
112
|
-
const outputFile = options.outputFile ||
|
|
106
|
+
const elapsedTime = (0, import_core.getElapsedTime)(startTime);
|
|
107
|
+
const outputFormat = options.output || finalOptions.output?.format || "console";
|
|
108
|
+
const outputFile = options.outputFile || finalOptions.output?.file;
|
|
113
109
|
if (outputFormat === "json") {
|
|
114
110
|
const outputData = {
|
|
115
111
|
...results,
|
|
@@ -118,28 +114,24 @@ program.command("scan").description("Run unified analysis on a codebase").argume
|
|
|
118
114
|
executionTime: parseFloat(elapsedTime)
|
|
119
115
|
}
|
|
120
116
|
};
|
|
121
|
-
|
|
122
|
-
(0, import_fs.writeFileSync)(outputFile, JSON.stringify(outputData, null, 2));
|
|
123
|
-
console.log(import_chalk.default.green(`\u2705 Results saved to ${outputFile}`));
|
|
124
|
-
} else {
|
|
125
|
-
console.log(JSON.stringify(outputData, null, 2));
|
|
126
|
-
}
|
|
117
|
+
(0, import_core.handleJSONOutput)(outputData, outputFile, `\u2705 Results saved to ${outputFile}`);
|
|
127
118
|
} else {
|
|
128
119
|
console.log(generateUnifiedSummary(results));
|
|
129
120
|
}
|
|
130
121
|
} catch (error) {
|
|
131
|
-
|
|
132
|
-
process.exit(1);
|
|
122
|
+
(0, import_core.handleCLIError)(error, "Analysis");
|
|
133
123
|
}
|
|
134
124
|
});
|
|
135
|
-
program.command("patterns").description("Run pattern detection analysis").argument("<directory>", "Directory to analyze").option("-s, --similarity <number>", "Minimum similarity score (0-1)", "0.40").option("-l, --min-lines <number>", "Minimum lines to consider", "5").option("--include <patterns>", "File patterns to include (comma-separated)").option("--exclude <patterns>", "File patterns to exclude (comma-separated)").option("-o, --output <format>", "Output format: console, json", "console").option("--output-file <path>", "Output file path (for json)").action(async (directory, options) => {
|
|
125
|
+
program.command("patterns").description("Run pattern detection analysis").argument("<directory>", "Directory to analyze").option("-s, --similarity <number>", "Minimum similarity score (0-1)", "0.40").option("-l, --min-lines <number>", "Minimum lines to consider", "5").option("--max-candidates <number>", "Maximum candidates per block (performance tuning)").option("--min-shared-tokens <number>", "Minimum shared tokens for candidates (performance tuning)").option("--full-scan", "Disable smart defaults for comprehensive analysis (slower)").option("--include <patterns>", "File patterns to include (comma-separated)").option("--exclude <patterns>", "File patterns to exclude (comma-separated)").option("-o, --output <format>", "Output format: console, json", "console").option("--output-file <path>", "Output file path (for json)").action(async (directory, options) => {
|
|
136
126
|
console.log(import_chalk.default.blue("\u{1F50D} Analyzing patterns...\n"));
|
|
137
127
|
const startTime = Date.now();
|
|
138
128
|
try {
|
|
139
|
-
const config = (0, import_core.loadConfig)(directory);
|
|
140
129
|
const defaults = {
|
|
141
130
|
minSimilarity: 0.4,
|
|
142
131
|
minLines: 5,
|
|
132
|
+
maxCandidatesPerBlock: 100,
|
|
133
|
+
minSharedTokens: 8,
|
|
134
|
+
useSmartDefaults: true,
|
|
143
135
|
include: void 0,
|
|
144
136
|
exclude: void 0,
|
|
145
137
|
output: {
|
|
@@ -147,46 +139,41 @@ program.command("patterns").description("Run pattern detection analysis").argume
|
|
|
147
139
|
file: void 0
|
|
148
140
|
}
|
|
149
141
|
};
|
|
150
|
-
const
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
142
|
+
const finalOptions = (0, import_core.loadMergedConfig)(directory, defaults, {
|
|
143
|
+
minSimilarity: options.similarity ? parseFloat(options.similarity) : void 0,
|
|
144
|
+
minLines: options.minLines ? parseInt(options.minLines) : void 0,
|
|
145
|
+
maxCandidatesPerBlock: options.maxCandidates ? parseInt(options.maxCandidates) : void 0,
|
|
146
|
+
minSharedTokens: options.minSharedTokens ? parseInt(options.minSharedTokens) : void 0,
|
|
147
|
+
// If --full-scan is specified, don't use smart defaults
|
|
148
|
+
useSmartDefaults: !options.fullScan,
|
|
149
|
+
include: options.include?.split(","),
|
|
150
|
+
exclude: options.exclude?.split(",")
|
|
151
|
+
});
|
|
158
152
|
const { analyzePatterns: analyzePatterns2, generateSummary } = await import("@aiready/pattern-detect");
|
|
159
153
|
const { results } = await analyzePatterns2(finalOptions);
|
|
160
|
-
const elapsedTime = (
|
|
154
|
+
const elapsedTime = (0, import_core.getElapsedTime)(startTime);
|
|
161
155
|
const summary = generateSummary(results);
|
|
162
|
-
const outputFormat = options.output ||
|
|
163
|
-
const outputFile = options.outputFile ||
|
|
156
|
+
const outputFormat = options.output || finalOptions.output?.format || "console";
|
|
157
|
+
const outputFile = options.outputFile || finalOptions.output?.file;
|
|
164
158
|
if (outputFormat === "json") {
|
|
165
159
|
const outputData = {
|
|
166
160
|
results,
|
|
167
161
|
summary: { ...summary, executionTime: parseFloat(elapsedTime) }
|
|
168
162
|
};
|
|
169
|
-
|
|
170
|
-
(0, import_fs.writeFileSync)(outputFile, JSON.stringify(outputData, null, 2));
|
|
171
|
-
console.log(import_chalk.default.green(`\u2705 Results saved to ${outputFile}`));
|
|
172
|
-
} else {
|
|
173
|
-
console.log(JSON.stringify(outputData, null, 2));
|
|
174
|
-
}
|
|
163
|
+
(0, import_core.handleJSONOutput)(outputData, outputFile, `\u2705 Results saved to ${outputFile}`);
|
|
175
164
|
} else {
|
|
176
165
|
console.log(`Pattern Analysis Complete (${elapsedTime}s)`);
|
|
177
166
|
console.log(`Found ${summary.totalPatterns} duplicate patterns`);
|
|
178
167
|
console.log(`Total token cost: ${summary.totalTokenCost} tokens`);
|
|
179
168
|
}
|
|
180
169
|
} catch (error) {
|
|
181
|
-
|
|
182
|
-
process.exit(1);
|
|
170
|
+
(0, import_core.handleCLIError)(error, "Pattern analysis");
|
|
183
171
|
}
|
|
184
172
|
});
|
|
185
173
|
program.command("context").description("Run context window cost analysis").argument("<directory>", "Directory to analyze").option("--max-depth <number>", "Maximum acceptable import depth", "5").option("--max-context <number>", "Maximum acceptable context budget (tokens)", "10000").option("--include <patterns>", "File patterns to include (comma-separated)").option("--exclude <patterns>", "File patterns to exclude (comma-separated)").option("-o, --output <format>", "Output format: console, json", "console").option("--output-file <path>", "Output file path (for json)").action(async (directory, options) => {
|
|
186
174
|
console.log(import_chalk.default.blue("\u{1F9E0} Analyzing context costs...\n"));
|
|
187
175
|
const startTime = Date.now();
|
|
188
176
|
try {
|
|
189
|
-
const config = (0, import_core.loadConfig)(directory);
|
|
190
177
|
const defaults = {
|
|
191
178
|
maxDepth: 5,
|
|
192
179
|
maxContextBudget: 1e4,
|
|
@@ -197,31 +184,24 @@ program.command("context").description("Run context window cost analysis").argum
|
|
|
197
184
|
file: void 0
|
|
198
185
|
}
|
|
199
186
|
};
|
|
200
|
-
const
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
exclude: options.exclude?.split(",") || mergedConfig.exclude
|
|
207
|
-
};
|
|
187
|
+
const finalOptions = (0, import_core.loadMergedConfig)(directory, defaults, {
|
|
188
|
+
maxDepth: options.maxDepth ? parseInt(options.maxDepth) : void 0,
|
|
189
|
+
maxContextBudget: options.maxContext ? parseInt(options.maxContext) : void 0,
|
|
190
|
+
include: options.include?.split(","),
|
|
191
|
+
exclude: options.exclude?.split(",")
|
|
192
|
+
});
|
|
208
193
|
const { analyzeContext: analyzeContext2, generateSummary } = await import("@aiready/context-analyzer");
|
|
209
194
|
const results = await analyzeContext2(finalOptions);
|
|
210
|
-
const elapsedTime = (
|
|
195
|
+
const elapsedTime = (0, import_core.getElapsedTime)(startTime);
|
|
211
196
|
const summary = generateSummary(results);
|
|
212
|
-
const outputFormat = options.output ||
|
|
213
|
-
const outputFile = options.outputFile ||
|
|
197
|
+
const outputFormat = options.output || finalOptions.output?.format || "console";
|
|
198
|
+
const outputFile = options.outputFile || finalOptions.output?.file;
|
|
214
199
|
if (outputFormat === "json") {
|
|
215
200
|
const outputData = {
|
|
216
201
|
results,
|
|
217
202
|
summary: { ...summary, executionTime: parseFloat(elapsedTime) }
|
|
218
203
|
};
|
|
219
|
-
|
|
220
|
-
(0, import_fs.writeFileSync)(outputFile, JSON.stringify(outputData, null, 2));
|
|
221
|
-
console.log(import_chalk.default.green(`\u2705 Results saved to ${outputFile}`));
|
|
222
|
-
} else {
|
|
223
|
-
console.log(JSON.stringify(outputData, null, 2));
|
|
224
|
-
}
|
|
204
|
+
(0, import_core.handleJSONOutput)(outputData, outputFile, `\u2705 Results saved to ${outputFile}`);
|
|
225
205
|
} else {
|
|
226
206
|
console.log(`Context Analysis Complete (${elapsedTime}s)`);
|
|
227
207
|
console.log(`Files analyzed: ${summary.totalFiles}`);
|
|
@@ -230,8 +210,7 @@ program.command("context").description("Run context window cost analysis").argum
|
|
|
230
210
|
console.log(`Average fragmentation: ${(summary.avgFragmentation * 100).toFixed(1)}%`);
|
|
231
211
|
}
|
|
232
212
|
} catch (error) {
|
|
233
|
-
|
|
234
|
-
process.exit(1);
|
|
213
|
+
(0, import_core.handleCLIError)(error, "Context analysis");
|
|
235
214
|
}
|
|
236
215
|
});
|
|
237
216
|
program.parse();
|
package/dist/cli.mjs
CHANGED
|
@@ -7,9 +7,8 @@ import {
|
|
|
7
7
|
// src/cli.ts
|
|
8
8
|
import { Command } from "commander";
|
|
9
9
|
import chalk from "chalk";
|
|
10
|
-
import { writeFileSync } from "fs";
|
|
11
10
|
import { join } from "path";
|
|
12
|
-
import {
|
|
11
|
+
import { loadMergedConfig, handleJSONOutput, handleCLIError, getElapsedTime } from "@aiready/core";
|
|
13
12
|
import { readFileSync } from "fs";
|
|
14
13
|
var packageJson = JSON.parse(readFileSync(join(__dirname, "../package.json"), "utf8"));
|
|
15
14
|
var program = new Command();
|
|
@@ -18,7 +17,6 @@ program.command("scan").description("Run unified analysis on a codebase").argume
|
|
|
18
17
|
console.log(chalk.blue("\u{1F680} Starting AIReady unified analysis...\n"));
|
|
19
18
|
const startTime = Date.now();
|
|
20
19
|
try {
|
|
21
|
-
const config = loadConfig(directory);
|
|
22
20
|
const defaults = {
|
|
23
21
|
tools: ["patterns", "context"],
|
|
24
22
|
include: void 0,
|
|
@@ -28,17 +26,15 @@ program.command("scan").description("Run unified analysis on a codebase").argume
|
|
|
28
26
|
file: void 0
|
|
29
27
|
}
|
|
30
28
|
};
|
|
31
|
-
const
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
exclude: options.exclude?.split(",") || mergedConfig.exclude
|
|
37
|
-
};
|
|
29
|
+
const finalOptions = loadMergedConfig(directory, defaults, {
|
|
30
|
+
tools: options.tools ? options.tools.split(",").map((t) => t.trim()) : void 0,
|
|
31
|
+
include: options.include?.split(","),
|
|
32
|
+
exclude: options.exclude?.split(",")
|
|
33
|
+
});
|
|
38
34
|
const results = await analyzeUnified(finalOptions);
|
|
39
|
-
const elapsedTime = (
|
|
40
|
-
const outputFormat = options.output ||
|
|
41
|
-
const outputFile = options.outputFile ||
|
|
35
|
+
const elapsedTime = getElapsedTime(startTime);
|
|
36
|
+
const outputFormat = options.output || finalOptions.output?.format || "console";
|
|
37
|
+
const outputFile = options.outputFile || finalOptions.output?.file;
|
|
42
38
|
if (outputFormat === "json") {
|
|
43
39
|
const outputData = {
|
|
44
40
|
...results,
|
|
@@ -47,28 +43,24 @@ program.command("scan").description("Run unified analysis on a codebase").argume
|
|
|
47
43
|
executionTime: parseFloat(elapsedTime)
|
|
48
44
|
}
|
|
49
45
|
};
|
|
50
|
-
|
|
51
|
-
writeFileSync(outputFile, JSON.stringify(outputData, null, 2));
|
|
52
|
-
console.log(chalk.green(`\u2705 Results saved to ${outputFile}`));
|
|
53
|
-
} else {
|
|
54
|
-
console.log(JSON.stringify(outputData, null, 2));
|
|
55
|
-
}
|
|
46
|
+
handleJSONOutput(outputData, outputFile, `\u2705 Results saved to ${outputFile}`);
|
|
56
47
|
} else {
|
|
57
48
|
console.log(generateUnifiedSummary(results));
|
|
58
49
|
}
|
|
59
50
|
} catch (error) {
|
|
60
|
-
|
|
61
|
-
process.exit(1);
|
|
51
|
+
handleCLIError(error, "Analysis");
|
|
62
52
|
}
|
|
63
53
|
});
|
|
64
|
-
program.command("patterns").description("Run pattern detection analysis").argument("<directory>", "Directory to analyze").option("-s, --similarity <number>", "Minimum similarity score (0-1)", "0.40").option("-l, --min-lines <number>", "Minimum lines to consider", "5").option("--include <patterns>", "File patterns to include (comma-separated)").option("--exclude <patterns>", "File patterns to exclude (comma-separated)").option("-o, --output <format>", "Output format: console, json", "console").option("--output-file <path>", "Output file path (for json)").action(async (directory, options) => {
|
|
54
|
+
program.command("patterns").description("Run pattern detection analysis").argument("<directory>", "Directory to analyze").option("-s, --similarity <number>", "Minimum similarity score (0-1)", "0.40").option("-l, --min-lines <number>", "Minimum lines to consider", "5").option("--max-candidates <number>", "Maximum candidates per block (performance tuning)").option("--min-shared-tokens <number>", "Minimum shared tokens for candidates (performance tuning)").option("--full-scan", "Disable smart defaults for comprehensive analysis (slower)").option("--include <patterns>", "File patterns to include (comma-separated)").option("--exclude <patterns>", "File patterns to exclude (comma-separated)").option("-o, --output <format>", "Output format: console, json", "console").option("--output-file <path>", "Output file path (for json)").action(async (directory, options) => {
|
|
65
55
|
console.log(chalk.blue("\u{1F50D} Analyzing patterns...\n"));
|
|
66
56
|
const startTime = Date.now();
|
|
67
57
|
try {
|
|
68
|
-
const config = loadConfig(directory);
|
|
69
58
|
const defaults = {
|
|
70
59
|
minSimilarity: 0.4,
|
|
71
60
|
minLines: 5,
|
|
61
|
+
maxCandidatesPerBlock: 100,
|
|
62
|
+
minSharedTokens: 8,
|
|
63
|
+
useSmartDefaults: true,
|
|
72
64
|
include: void 0,
|
|
73
65
|
exclude: void 0,
|
|
74
66
|
output: {
|
|
@@ -76,46 +68,41 @@ program.command("patterns").description("Run pattern detection analysis").argume
|
|
|
76
68
|
file: void 0
|
|
77
69
|
}
|
|
78
70
|
};
|
|
79
|
-
const
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
71
|
+
const finalOptions = loadMergedConfig(directory, defaults, {
|
|
72
|
+
minSimilarity: options.similarity ? parseFloat(options.similarity) : void 0,
|
|
73
|
+
minLines: options.minLines ? parseInt(options.minLines) : void 0,
|
|
74
|
+
maxCandidatesPerBlock: options.maxCandidates ? parseInt(options.maxCandidates) : void 0,
|
|
75
|
+
minSharedTokens: options.minSharedTokens ? parseInt(options.minSharedTokens) : void 0,
|
|
76
|
+
// If --full-scan is specified, don't use smart defaults
|
|
77
|
+
useSmartDefaults: !options.fullScan,
|
|
78
|
+
include: options.include?.split(","),
|
|
79
|
+
exclude: options.exclude?.split(",")
|
|
80
|
+
});
|
|
87
81
|
const { analyzePatterns, generateSummary } = await import("@aiready/pattern-detect");
|
|
88
82
|
const { results } = await analyzePatterns(finalOptions);
|
|
89
|
-
const elapsedTime = (
|
|
83
|
+
const elapsedTime = getElapsedTime(startTime);
|
|
90
84
|
const summary = generateSummary(results);
|
|
91
|
-
const outputFormat = options.output ||
|
|
92
|
-
const outputFile = options.outputFile ||
|
|
85
|
+
const outputFormat = options.output || finalOptions.output?.format || "console";
|
|
86
|
+
const outputFile = options.outputFile || finalOptions.output?.file;
|
|
93
87
|
if (outputFormat === "json") {
|
|
94
88
|
const outputData = {
|
|
95
89
|
results,
|
|
96
90
|
summary: { ...summary, executionTime: parseFloat(elapsedTime) }
|
|
97
91
|
};
|
|
98
|
-
|
|
99
|
-
writeFileSync(outputFile, JSON.stringify(outputData, null, 2));
|
|
100
|
-
console.log(chalk.green(`\u2705 Results saved to ${outputFile}`));
|
|
101
|
-
} else {
|
|
102
|
-
console.log(JSON.stringify(outputData, null, 2));
|
|
103
|
-
}
|
|
92
|
+
handleJSONOutput(outputData, outputFile, `\u2705 Results saved to ${outputFile}`);
|
|
104
93
|
} else {
|
|
105
94
|
console.log(`Pattern Analysis Complete (${elapsedTime}s)`);
|
|
106
95
|
console.log(`Found ${summary.totalPatterns} duplicate patterns`);
|
|
107
96
|
console.log(`Total token cost: ${summary.totalTokenCost} tokens`);
|
|
108
97
|
}
|
|
109
98
|
} catch (error) {
|
|
110
|
-
|
|
111
|
-
process.exit(1);
|
|
99
|
+
handleCLIError(error, "Pattern analysis");
|
|
112
100
|
}
|
|
113
101
|
});
|
|
114
102
|
program.command("context").description("Run context window cost analysis").argument("<directory>", "Directory to analyze").option("--max-depth <number>", "Maximum acceptable import depth", "5").option("--max-context <number>", "Maximum acceptable context budget (tokens)", "10000").option("--include <patterns>", "File patterns to include (comma-separated)").option("--exclude <patterns>", "File patterns to exclude (comma-separated)").option("-o, --output <format>", "Output format: console, json", "console").option("--output-file <path>", "Output file path (for json)").action(async (directory, options) => {
|
|
115
103
|
console.log(chalk.blue("\u{1F9E0} Analyzing context costs...\n"));
|
|
116
104
|
const startTime = Date.now();
|
|
117
105
|
try {
|
|
118
|
-
const config = loadConfig(directory);
|
|
119
106
|
const defaults = {
|
|
120
107
|
maxDepth: 5,
|
|
121
108
|
maxContextBudget: 1e4,
|
|
@@ -126,31 +113,24 @@ program.command("context").description("Run context window cost analysis").argum
|
|
|
126
113
|
file: void 0
|
|
127
114
|
}
|
|
128
115
|
};
|
|
129
|
-
const
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
exclude: options.exclude?.split(",") || mergedConfig.exclude
|
|
136
|
-
};
|
|
116
|
+
const finalOptions = loadMergedConfig(directory, defaults, {
|
|
117
|
+
maxDepth: options.maxDepth ? parseInt(options.maxDepth) : void 0,
|
|
118
|
+
maxContextBudget: options.maxContext ? parseInt(options.maxContext) : void 0,
|
|
119
|
+
include: options.include?.split(","),
|
|
120
|
+
exclude: options.exclude?.split(",")
|
|
121
|
+
});
|
|
137
122
|
const { analyzeContext, generateSummary } = await import("@aiready/context-analyzer");
|
|
138
123
|
const results = await analyzeContext(finalOptions);
|
|
139
|
-
const elapsedTime = (
|
|
124
|
+
const elapsedTime = getElapsedTime(startTime);
|
|
140
125
|
const summary = generateSummary(results);
|
|
141
|
-
const outputFormat = options.output ||
|
|
142
|
-
const outputFile = options.outputFile ||
|
|
126
|
+
const outputFormat = options.output || finalOptions.output?.format || "console";
|
|
127
|
+
const outputFile = options.outputFile || finalOptions.output?.file;
|
|
143
128
|
if (outputFormat === "json") {
|
|
144
129
|
const outputData = {
|
|
145
130
|
results,
|
|
146
131
|
summary: { ...summary, executionTime: parseFloat(elapsedTime) }
|
|
147
132
|
};
|
|
148
|
-
|
|
149
|
-
writeFileSync(outputFile, JSON.stringify(outputData, null, 2));
|
|
150
|
-
console.log(chalk.green(`\u2705 Results saved to ${outputFile}`));
|
|
151
|
-
} else {
|
|
152
|
-
console.log(JSON.stringify(outputData, null, 2));
|
|
153
|
-
}
|
|
133
|
+
handleJSONOutput(outputData, outputFile, `\u2705 Results saved to ${outputFile}`);
|
|
154
134
|
} else {
|
|
155
135
|
console.log(`Context Analysis Complete (${elapsedTime}s)`);
|
|
156
136
|
console.log(`Files analyzed: ${summary.totalFiles}`);
|
|
@@ -159,8 +139,7 @@ program.command("context").description("Run context window cost analysis").argum
|
|
|
159
139
|
console.log(`Average fragmentation: ${(summary.avgFragmentation * 100).toFixed(1)}%`);
|
|
160
140
|
}
|
|
161
141
|
} catch (error) {
|
|
162
|
-
|
|
163
|
-
process.exit(1);
|
|
142
|
+
handleCLIError(error, "Context analysis");
|
|
164
143
|
}
|
|
165
144
|
});
|
|
166
145
|
program.parse();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aiready/cli",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.5",
|
|
4
4
|
"description": "Unified CLI for AIReady analysis tools",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"module": "./dist/index.mjs",
|
|
@@ -11,9 +11,9 @@
|
|
|
11
11
|
"dependencies": {
|
|
12
12
|
"commander": "^12.1.0",
|
|
13
13
|
"chalk": "^5.3.0",
|
|
14
|
-
"@aiready/
|
|
15
|
-
"@aiready/
|
|
16
|
-
"@aiready/
|
|
14
|
+
"@aiready/core": "0.3.3",
|
|
15
|
+
"@aiready/context-analyzer": "0.3.5",
|
|
16
|
+
"@aiready/pattern-detect": "0.7.7"
|
|
17
17
|
},
|
|
18
18
|
"devDependencies": {
|
|
19
19
|
"tsup": "^8.3.5",
|
package/src/cli.ts
CHANGED
|
@@ -5,7 +5,7 @@ import { analyzeUnified, generateUnifiedSummary } from './index';
|
|
|
5
5
|
import chalk from 'chalk';
|
|
6
6
|
import { writeFileSync } from 'fs';
|
|
7
7
|
import { join } from 'path';
|
|
8
|
-
import {
|
|
8
|
+
import { loadMergedConfig, handleJSONOutput, handleCLIError, getElapsedTime } from '@aiready/core';
|
|
9
9
|
import { readFileSync } from 'fs';
|
|
10
10
|
|
|
11
11
|
const packageJson = JSON.parse(readFileSync(join(__dirname, '../package.json'), 'utf8'));
|
|
@@ -33,9 +33,6 @@ program
|
|
|
33
33
|
const startTime = Date.now();
|
|
34
34
|
|
|
35
35
|
try {
|
|
36
|
-
// Load config file if it exists
|
|
37
|
-
const config = loadConfig(directory);
|
|
38
|
-
|
|
39
36
|
// Define defaults
|
|
40
37
|
const defaults = {
|
|
41
38
|
tools: ['patterns', 'context'],
|
|
@@ -47,23 +44,19 @@ program
|
|
|
47
44
|
},
|
|
48
45
|
};
|
|
49
46
|
|
|
50
|
-
//
|
|
51
|
-
const
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
tools: options.tools ? options.tools.split(',').map((t: string) => t.trim()) as ('patterns' | 'context')[] : mergedConfig.tools,
|
|
57
|
-
include: options.include?.split(',') || mergedConfig.include,
|
|
58
|
-
exclude: options.exclude?.split(',') || mergedConfig.exclude,
|
|
59
|
-
};
|
|
47
|
+
// Load and merge config with CLI options
|
|
48
|
+
const finalOptions = loadMergedConfig(directory, defaults, {
|
|
49
|
+
tools: options.tools ? options.tools.split(',').map((t: string) => t.trim()) as ('patterns' | 'context')[] : undefined,
|
|
50
|
+
include: options.include?.split(','),
|
|
51
|
+
exclude: options.exclude?.split(','),
|
|
52
|
+
}) as any;
|
|
60
53
|
|
|
61
54
|
const results = await analyzeUnified(finalOptions);
|
|
62
55
|
|
|
63
|
-
const elapsedTime = (
|
|
56
|
+
const elapsedTime = getElapsedTime(startTime);
|
|
64
57
|
|
|
65
|
-
const outputFormat = options.output ||
|
|
66
|
-
const outputFile = options.outputFile ||
|
|
58
|
+
const outputFormat = options.output || finalOptions.output?.format || 'console';
|
|
59
|
+
const outputFile = options.outputFile || finalOptions.output?.file;
|
|
67
60
|
|
|
68
61
|
if (outputFormat === 'json') {
|
|
69
62
|
const outputData = {
|
|
@@ -74,19 +67,13 @@ program
|
|
|
74
67
|
},
|
|
75
68
|
};
|
|
76
69
|
|
|
77
|
-
|
|
78
|
-
writeFileSync(outputFile, JSON.stringify(outputData, null, 2));
|
|
79
|
-
console.log(chalk.green(`✅ Results saved to ${outputFile}`));
|
|
80
|
-
} else {
|
|
81
|
-
console.log(JSON.stringify(outputData, null, 2));
|
|
82
|
-
}
|
|
70
|
+
handleJSONOutput(outputData, outputFile, `✅ Results saved to ${outputFile}`);
|
|
83
71
|
} else {
|
|
84
72
|
// Console output
|
|
85
73
|
console.log(generateUnifiedSummary(results));
|
|
86
74
|
}
|
|
87
75
|
} catch (error) {
|
|
88
|
-
|
|
89
|
-
process.exit(1);
|
|
76
|
+
handleCLIError(error, 'Analysis');
|
|
90
77
|
}
|
|
91
78
|
});
|
|
92
79
|
|
|
@@ -97,6 +84,9 @@ program
|
|
|
97
84
|
.argument('<directory>', 'Directory to analyze')
|
|
98
85
|
.option('-s, --similarity <number>', 'Minimum similarity score (0-1)', '0.40')
|
|
99
86
|
.option('-l, --min-lines <number>', 'Minimum lines to consider', '5')
|
|
87
|
+
.option('--max-candidates <number>', 'Maximum candidates per block (performance tuning)')
|
|
88
|
+
.option('--min-shared-tokens <number>', 'Minimum shared tokens for candidates (performance tuning)')
|
|
89
|
+
.option('--full-scan', 'Disable smart defaults for comprehensive analysis (slower)')
|
|
100
90
|
.option('--include <patterns>', 'File patterns to include (comma-separated)')
|
|
101
91
|
.option('--exclude <patterns>', 'File patterns to exclude (comma-separated)')
|
|
102
92
|
.option('-o, --output <format>', 'Output format: console, json', 'console')
|
|
@@ -107,13 +97,13 @@ program
|
|
|
107
97
|
const startTime = Date.now();
|
|
108
98
|
|
|
109
99
|
try {
|
|
110
|
-
// Load config file if it exists
|
|
111
|
-
const config = loadConfig(directory);
|
|
112
|
-
|
|
113
100
|
// Define defaults
|
|
114
101
|
const defaults = {
|
|
115
102
|
minSimilarity: 0.4,
|
|
116
103
|
minLines: 5,
|
|
104
|
+
maxCandidatesPerBlock: 100,
|
|
105
|
+
minSharedTokens: 8,
|
|
106
|
+
useSmartDefaults: true,
|
|
117
107
|
include: undefined,
|
|
118
108
|
exclude: undefined,
|
|
119
109
|
output: {
|
|
@@ -122,27 +112,27 @@ program
|
|
|
122
112
|
},
|
|
123
113
|
};
|
|
124
114
|
|
|
125
|
-
//
|
|
126
|
-
const
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
include: options.include?.split(',')
|
|
134
|
-
exclude: options.exclude?.split(',')
|
|
135
|
-
};
|
|
115
|
+
// Load and merge config with CLI options
|
|
116
|
+
const finalOptions = loadMergedConfig(directory, defaults, {
|
|
117
|
+
minSimilarity: options.similarity ? parseFloat(options.similarity) : undefined,
|
|
118
|
+
minLines: options.minLines ? parseInt(options.minLines) : undefined,
|
|
119
|
+
maxCandidatesPerBlock: options.maxCandidates ? parseInt(options.maxCandidates) : undefined,
|
|
120
|
+
minSharedTokens: options.minSharedTokens ? parseInt(options.minSharedTokens) : undefined,
|
|
121
|
+
// If --full-scan is specified, don't use smart defaults
|
|
122
|
+
useSmartDefaults: !options.fullScan,
|
|
123
|
+
include: options.include?.split(','),
|
|
124
|
+
exclude: options.exclude?.split(','),
|
|
125
|
+
});
|
|
136
126
|
|
|
137
127
|
const { analyzePatterns, generateSummary } = await import('@aiready/pattern-detect');
|
|
138
128
|
|
|
139
129
|
const { results } = await analyzePatterns(finalOptions);
|
|
140
130
|
|
|
141
|
-
const elapsedTime = (
|
|
131
|
+
const elapsedTime = getElapsedTime(startTime);
|
|
142
132
|
const summary = generateSummary(results);
|
|
143
133
|
|
|
144
|
-
const outputFormat = options.output ||
|
|
145
|
-
const outputFile = options.outputFile ||
|
|
134
|
+
const outputFormat = options.output || finalOptions.output?.format || 'console';
|
|
135
|
+
const outputFile = options.outputFile || finalOptions.output?.file;
|
|
146
136
|
|
|
147
137
|
if (outputFormat === 'json') {
|
|
148
138
|
const outputData = {
|
|
@@ -150,20 +140,14 @@ program
|
|
|
150
140
|
summary: { ...summary, executionTime: parseFloat(elapsedTime) },
|
|
151
141
|
};
|
|
152
142
|
|
|
153
|
-
|
|
154
|
-
writeFileSync(outputFile, JSON.stringify(outputData, null, 2));
|
|
155
|
-
console.log(chalk.green(`✅ Results saved to ${outputFile}`));
|
|
156
|
-
} else {
|
|
157
|
-
console.log(JSON.stringify(outputData, null, 2));
|
|
158
|
-
}
|
|
143
|
+
handleJSONOutput(outputData, outputFile, `✅ Results saved to ${outputFile}`);
|
|
159
144
|
} else {
|
|
160
145
|
console.log(`Pattern Analysis Complete (${elapsedTime}s)`);
|
|
161
146
|
console.log(`Found ${summary.totalPatterns} duplicate patterns`);
|
|
162
147
|
console.log(`Total token cost: ${summary.totalTokenCost} tokens`);
|
|
163
148
|
}
|
|
164
149
|
} catch (error) {
|
|
165
|
-
|
|
166
|
-
process.exit(1);
|
|
150
|
+
handleCLIError(error, 'Pattern analysis');
|
|
167
151
|
}
|
|
168
152
|
});
|
|
169
153
|
|
|
@@ -183,9 +167,6 @@ program
|
|
|
183
167
|
const startTime = Date.now();
|
|
184
168
|
|
|
185
169
|
try {
|
|
186
|
-
// Load config file if it exists
|
|
187
|
-
const config = loadConfig(directory);
|
|
188
|
-
|
|
189
170
|
// Define defaults
|
|
190
171
|
const defaults = {
|
|
191
172
|
maxDepth: 5,
|
|
@@ -198,27 +179,23 @@ program
|
|
|
198
179
|
},
|
|
199
180
|
};
|
|
200
181
|
|
|
201
|
-
//
|
|
202
|
-
const
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
maxContextBudget: options.maxContext ? parseInt(options.maxContext) : mergedConfig.maxContextBudget,
|
|
209
|
-
include: options.include?.split(',') || mergedConfig.include,
|
|
210
|
-
exclude: options.exclude?.split(',') || mergedConfig.exclude,
|
|
211
|
-
};
|
|
182
|
+
// Load and merge config with CLI options
|
|
183
|
+
const finalOptions = loadMergedConfig(directory, defaults, {
|
|
184
|
+
maxDepth: options.maxDepth ? parseInt(options.maxDepth) : undefined,
|
|
185
|
+
maxContextBudget: options.maxContext ? parseInt(options.maxContext) : undefined,
|
|
186
|
+
include: options.include?.split(','),
|
|
187
|
+
exclude: options.exclude?.split(','),
|
|
188
|
+
});
|
|
212
189
|
|
|
213
190
|
const { analyzeContext, generateSummary } = await import('@aiready/context-analyzer');
|
|
214
191
|
|
|
215
192
|
const results = await analyzeContext(finalOptions);
|
|
216
193
|
|
|
217
|
-
const elapsedTime = (
|
|
194
|
+
const elapsedTime = getElapsedTime(startTime);
|
|
218
195
|
const summary = generateSummary(results);
|
|
219
196
|
|
|
220
|
-
const outputFormat = options.output ||
|
|
221
|
-
const outputFile = options.outputFile ||
|
|
197
|
+
const outputFormat = options.output || finalOptions.output?.format || 'console';
|
|
198
|
+
const outputFile = options.outputFile || finalOptions.output?.file;
|
|
222
199
|
|
|
223
200
|
if (outputFormat === 'json') {
|
|
224
201
|
const outputData = {
|
|
@@ -226,12 +203,7 @@ program
|
|
|
226
203
|
summary: { ...summary, executionTime: parseFloat(elapsedTime) },
|
|
227
204
|
};
|
|
228
205
|
|
|
229
|
-
|
|
230
|
-
writeFileSync(outputFile, JSON.stringify(outputData, null, 2));
|
|
231
|
-
console.log(chalk.green(`✅ Results saved to ${outputFile}`));
|
|
232
|
-
} else {
|
|
233
|
-
console.log(JSON.stringify(outputData, null, 2));
|
|
234
|
-
}
|
|
206
|
+
handleJSONOutput(outputData, outputFile, `✅ Results saved to ${outputFile}`);
|
|
235
207
|
} else {
|
|
236
208
|
console.log(`Context Analysis Complete (${elapsedTime}s)`);
|
|
237
209
|
console.log(`Files analyzed: ${summary.totalFiles}`);
|
|
@@ -240,8 +212,7 @@ program
|
|
|
240
212
|
console.log(`Average fragmentation: ${(summary.avgFragmentation * 100).toFixed(1)}%`);
|
|
241
213
|
}
|
|
242
214
|
} catch (error) {
|
|
243
|
-
|
|
244
|
-
process.exit(1);
|
|
215
|
+
handleCLIError(error, 'Context analysis');
|
|
245
216
|
}
|
|
246
217
|
});
|
|
247
218
|
|