@aiready/cli 0.9.43 → 0.9.46

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.
@@ -1,6 +1,6 @@
1
1
 
2
2
  
3
- > @aiready/cli@0.9.43 build /Users/pengcao/projects/aiready/packages/cli
3
+ > @aiready/cli@0.9.46 build /Users/pengcao/projects/aiready/packages/cli
4
4
  > tsup src/index.ts src/cli.ts --format cjs,esm
5
5
 
6
6
  CLI Building entry: src/cli.ts, src/index.ts
@@ -10,20 +10,20 @@
10
10
  CJS Build start
11
11
  ESM Build start
12
12
 
13
- [12:55:45 AM]  WARN  ▲ [WARNING] "import.meta" is not available with the "cjs" output format and will be empty [empty-import-meta]
13
+  WARN  ▲ [WARNING] "import.meta" is not available with the "cjs" output format and will be empty [empty-import-meta] 12:53:18 PM
14
14
 
15
- src/cli.ts:23:31:
16
-  23 │ return dirname(fileURLToPath(import.meta.url));
15
+ src/cli.ts:25:31:
16
+  25 │ return dirname(fileURLToPath(import.meta.url));
17
17
  ╵ ~~~~~~~~~~~
18
18
 
19
19
  You need to set the output format to "esm" for "import.meta" to work correctly.
20
20
 
21
21
 
22
22
 
23
- CJS dist/index.js 9.42 KB
24
- CJS dist/cli.js 80.79 KB
25
- CJS ⚡️ Build success in 100ms
26
- ESM dist/cli.mjs 70.25 KB
27
- ESM dist/chunk-LLJMKNBI.mjs 8.07 KB
28
- ESM dist/index.mjs 138.00 B
29
- ESM ⚡️ Build success in 104ms
23
+ CJS dist/cli.js 89.07 KB
24
+ CJS dist/index.js 13.89 KB
25
+ CJS ⚡️ Build success in 32ms
26
+ ESM dist/index.mjs 170.00 B
27
+ ESM dist/chunk-6FOVC2OE.mjs 12.49 KB
28
+ ESM dist/cli.mjs 73.70 KB
29
+ ESM ⚡️ Build success in 32ms
@@ -1,17 +1,17 @@
1
1
 
2
2
  
3
- > @aiready/cli@0.9.43 test /Users/pengcao/projects/aiready/packages/cli
3
+ > @aiready/cli@0.9.46 test /Users/pengcao/projects/aiready/packages/cli
4
4
  > vitest run
5
5
 
6
6
  [?25l
7
7
   RUN  v4.0.18 /Users/pengcao/projects/aiready/packages/cli
8
8
 
9
- ✓ src/__tests__/cli.test.ts (3 tests) 3ms
10
- ✓ dist/__tests__/cli.test.js (3 tests) 9ms
9
+ ✓ dist/__tests__/cli.test.js (3 tests) 2ms
10
+ ✓ src/__tests__/cli.test.ts (3 tests) 23ms
11
11
 
12
12
   Test Files  2 passed (2)
13
13
   Tests  6 passed (6)
14
-  Start at  00:56:33
15
-  Duration  7.83s (transform 2.63s, setup 0ms, import 12.42s, tests 12ms, environment 0ms)
14
+  Start at  12:53:41
15
+  Duration  1.88s (transform 634ms, setup 0ms, import 2.66s, tests 25ms, environment 0ms)
16
16
 
17
17
  [?25h
package/README.md CHANGED
@@ -4,7 +4,14 @@
4
4
 
5
5
  ## 🏛️ Architecture
6
6
 
7
+ ```markdown
8
+ # @aiready/cli
9
+
10
+ > Unified command-line interface for the AIReady framework.
11
+
12
+ ## 🏛️ Architecture
7
13
  ```
14
+
8
15
  🎯 USER
9
16
 
10
17
 
@@ -19,12 +26,13 @@
19
26
  🏢 @aiready/core
20
27
 
21
28
  Legend:
22
- PAT = pattern-detect CTX = context-analyzer
23
- CON = consistency AMP = change-amplification
24
- DEP = deps-health DOC = doc-drift
25
- SIG = ai-signal-clarity AGT = agent-grounding
26
- TST = testability
27
- ```
29
+ PAT = pattern-detect CTX = context-analyzer
30
+ CON = consistency AMP = change-amplification
31
+ DEP = deps-health DOC = doc-drift
32
+ SIG = ai-signal-clarity AGT = agent-grounding
33
+ TST = testability
34
+
35
+ ````
28
36
 
29
37
  ## Overview
30
38
 
@@ -37,9 +45,39 @@ The CLI provides both unified analysis (scan multiple tools at once) and individ
37
45
  aiready scan .
38
46
 
39
47
  # Run a specific tool
40
- aiready pattern-detect .
48
+ aiready patterns . --similarity 0.6
49
+ ````
50
+
51
+ ## 🌐 Platform Integration
52
+
53
+ Connect your local scans to the [AIReady Dashboard](https://getaiready.dev/dashboard).
54
+
55
+ ### Automatic Upload
56
+
57
+ Scan and upload results in one step:
58
+
59
+ ```bash
60
+ aiready scan . --upload --api-key ar_...
61
+ ```
62
+
63
+ ### Manual Upload
64
+
65
+ Upload an existing report JSON:
66
+
67
+ ```bash
68
+ aiready upload .aiready/latest.json --api-key ar_...
41
69
  ```
42
70
 
71
+ ### Options
72
+
73
+ - `--upload`: Automatically upload results after scan
74
+ - `--api-key <key>`: Your platform API key (or set `AIREADY_API_KEY`)
75
+ - `--server <url>`: Custom platform URL (optional)
76
+
43
77
  ## License
44
78
 
45
79
  MIT
80
+
81
+ ```
82
+
83
+ ```
@@ -0,0 +1,392 @@
1
+ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
2
+ get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
3
+ }) : x)(function(x) {
4
+ if (typeof require !== "undefined") return require.apply(this, arguments);
5
+ throw Error('Dynamic require of "' + x + '" is not supported');
6
+ });
7
+
8
+ // src/index.ts
9
+ import { analyzePatterns } from "@aiready/pattern-detect";
10
+ import { analyzeContext } from "@aiready/context-analyzer";
11
+ import { analyzeConsistency } from "@aiready/consistency";
12
+ import {
13
+ calculateOverallScore,
14
+ calculateTokenBudget
15
+ } from "@aiready/core";
16
+ var severityOrder = {
17
+ critical: 4,
18
+ major: 3,
19
+ minor: 2,
20
+ info: 1
21
+ };
22
+ function sortBySeverity(results) {
23
+ return results.map((file) => {
24
+ const sortedIssues = [...file.issues].sort((a, b) => {
25
+ const severityDiff = (severityOrder[b.severity] || 0) - (severityOrder[a.severity] || 0);
26
+ if (severityDiff !== 0) return severityDiff;
27
+ return (a.location?.line || 0) - (b.location?.line || 0);
28
+ });
29
+ return { ...file, issues: sortedIssues };
30
+ }).sort((a, b) => {
31
+ const aMaxSeverity = Math.max(
32
+ ...a.issues.map((i) => severityOrder[i.severity] || 0),
33
+ 0
34
+ );
35
+ const bMaxSeverity = Math.max(
36
+ ...b.issues.map((i) => severityOrder[i.severity] || 0),
37
+ 0
38
+ );
39
+ if (aMaxSeverity !== bMaxSeverity) {
40
+ return bMaxSeverity - aMaxSeverity;
41
+ }
42
+ if (a.issues.length !== b.issues.length) {
43
+ return b.issues.length - a.issues.length;
44
+ }
45
+ return a.fileName.localeCompare(b.fileName);
46
+ });
47
+ }
48
+ async function analyzeUnified(options) {
49
+ const startTime = Date.now();
50
+ const tools = options.tools || ["patterns", "context", "consistency"];
51
+ const result = {
52
+ summary: {
53
+ totalIssues: 0,
54
+ toolsRun: tools,
55
+ executionTime: 0
56
+ }
57
+ };
58
+ if (tools.includes("patterns")) {
59
+ const patternResult = await analyzePatterns(options);
60
+ if (options.progressCallback) {
61
+ options.progressCallback({ tool: "patterns", data: patternResult });
62
+ }
63
+ result.patterns = sortBySeverity(patternResult.results);
64
+ result.duplicates = patternResult.duplicates;
65
+ result.summary.totalIssues += patternResult.results.reduce(
66
+ (sum, file) => sum + file.issues.length,
67
+ 0
68
+ );
69
+ }
70
+ if (tools.includes("context")) {
71
+ const contextResults = await analyzeContext(options);
72
+ if (options.progressCallback) {
73
+ options.progressCallback({ tool: "context", data: contextResults });
74
+ }
75
+ result.context = contextResults.sort((a, b) => {
76
+ const severityDiff = (severityOrder[b.severity] || 0) - (severityOrder[a.severity] || 0);
77
+ if (severityDiff !== 0) return severityDiff;
78
+ if (a.tokenCost !== b.tokenCost) return b.tokenCost - a.tokenCost;
79
+ return b.fragmentationScore - a.fragmentationScore;
80
+ });
81
+ result.summary.totalIssues += result.context?.length || 0;
82
+ }
83
+ if (tools.includes("consistency")) {
84
+ const consistencyOptions = {
85
+ rootDir: options.rootDir,
86
+ include: options.include,
87
+ exclude: options.exclude,
88
+ ...options.consistency || {}
89
+ };
90
+ const report = await analyzeConsistency(consistencyOptions);
91
+ if (options.progressCallback) {
92
+ options.progressCallback({ tool: "consistency", data: report });
93
+ }
94
+ if (report.results) {
95
+ report.results = sortBySeverity(report.results);
96
+ }
97
+ result.consistency = report;
98
+ result.summary.totalIssues += report.summary.totalIssues;
99
+ }
100
+ if (tools.includes("doc-drift")) {
101
+ const { analyzeDocDrift } = await import("@aiready/doc-drift");
102
+ const report = await analyzeDocDrift({
103
+ rootDir: options.rootDir,
104
+ include: options.include,
105
+ exclude: options.exclude,
106
+ onProgress: options.onProgress
107
+ });
108
+ if (options.progressCallback) {
109
+ options.progressCallback({ tool: "doc-drift", data: report });
110
+ }
111
+ result.docDrift = report;
112
+ result.summary.totalIssues += report.issues?.length || 0;
113
+ }
114
+ if (tools.includes("deps-health")) {
115
+ const { analyzeDeps } = await import("@aiready/deps");
116
+ const report = await analyzeDeps({
117
+ rootDir: options.rootDir,
118
+ include: options.include,
119
+ exclude: options.exclude,
120
+ onProgress: options.onProgress
121
+ });
122
+ if (options.progressCallback) {
123
+ options.progressCallback({ tool: "deps-health", data: report });
124
+ }
125
+ result.deps = report;
126
+ result.summary.totalIssues += report.issues?.length || 0;
127
+ }
128
+ if (tools.includes("aiSignalClarity")) {
129
+ const { analyzeAiSignalClarity } = await import("@aiready/ai-signal-clarity");
130
+ const report = await analyzeAiSignalClarity({
131
+ rootDir: options.rootDir,
132
+ include: options.include,
133
+ exclude: options.exclude,
134
+ onProgress: options.onProgress
135
+ });
136
+ if (options.progressCallback) {
137
+ options.progressCallback({ tool: "aiSignalClarity", data: report });
138
+ }
139
+ result.aiSignalClarity = report;
140
+ result.summary.totalIssues += report.results?.reduce(
141
+ (sum, r) => sum + (r.issues?.length || 0),
142
+ 0
143
+ ) || 0;
144
+ }
145
+ if (tools.includes("grounding")) {
146
+ const { analyzeAgentGrounding } = await import("@aiready/agent-grounding");
147
+ const report = await analyzeAgentGrounding({
148
+ rootDir: options.rootDir,
149
+ include: options.include,
150
+ exclude: options.exclude,
151
+ onProgress: options.onProgress
152
+ });
153
+ if (options.progressCallback) {
154
+ options.progressCallback({ tool: "grounding", data: report });
155
+ }
156
+ result.grounding = report;
157
+ result.summary.totalIssues += report.issues?.length || 0;
158
+ }
159
+ if (tools.includes("testability")) {
160
+ const { analyzeTestability } = await import("@aiready/testability");
161
+ const report = await analyzeTestability({
162
+ rootDir: options.rootDir,
163
+ include: options.include,
164
+ exclude: options.exclude,
165
+ onProgress: options.onProgress
166
+ });
167
+ if (options.progressCallback) {
168
+ options.progressCallback({ tool: "testability", data: report });
169
+ }
170
+ result.testability = report;
171
+ result.summary.totalIssues += report.issues?.length || 0;
172
+ }
173
+ if (tools.includes("changeAmplification")) {
174
+ const { analyzeChangeAmplification } = await import("@aiready/change-amplification");
175
+ const report = await analyzeChangeAmplification({
176
+ rootDir: options.rootDir,
177
+ include: options.include,
178
+ exclude: options.exclude,
179
+ onProgress: options.onProgress
180
+ });
181
+ if (options.progressCallback) {
182
+ options.progressCallback({ tool: "changeAmplification", data: report });
183
+ }
184
+ result.changeAmplification = report;
185
+ result.summary.totalIssues += report.summary?.totalIssues || 0;
186
+ }
187
+ result.summary.executionTime = Date.now() - startTime;
188
+ return result;
189
+ }
190
+ async function scoreUnified(results, options) {
191
+ const toolScores = /* @__PURE__ */ new Map();
192
+ if (results.duplicates) {
193
+ const { calculatePatternScore } = await import("@aiready/pattern-detect");
194
+ try {
195
+ const patternScore = calculatePatternScore(
196
+ results.duplicates,
197
+ results.patterns?.length || 0
198
+ );
199
+ const wastedTokens = results.duplicates.reduce(
200
+ (sum, d) => sum + (d.tokenCost || 0),
201
+ 0
202
+ );
203
+ patternScore.tokenBudget = calculateTokenBudget({
204
+ totalContextTokens: wastedTokens * 2,
205
+ // Estimated context
206
+ wastedTokens: {
207
+ duplication: wastedTokens,
208
+ fragmentation: 0,
209
+ chattiness: 0
210
+ }
211
+ });
212
+ toolScores.set("pattern-detect", patternScore);
213
+ } catch (err) {
214
+ void err;
215
+ }
216
+ }
217
+ if (results.context) {
218
+ const { generateSummary: genContextSummary, calculateContextScore } = await import("@aiready/context-analyzer");
219
+ try {
220
+ const ctxSummary = genContextSummary(results.context);
221
+ const contextScore = calculateContextScore(ctxSummary);
222
+ contextScore.tokenBudget = calculateTokenBudget({
223
+ totalContextTokens: ctxSummary.totalTokens,
224
+ wastedTokens: {
225
+ duplication: 0,
226
+ fragmentation: ctxSummary.totalPotentialSavings || 0,
227
+ chattiness: 0
228
+ }
229
+ });
230
+ toolScores.set("context-analyzer", contextScore);
231
+ } catch (err) {
232
+ void err;
233
+ }
234
+ }
235
+ if (results.consistency) {
236
+ const { calculateConsistencyScore } = await import("@aiready/consistency");
237
+ try {
238
+ const issues = results.consistency.results?.flatMap((r) => r.issues) || [];
239
+ const totalFiles = results.consistency.summary?.filesAnalyzed || 0;
240
+ const consistencyScore = calculateConsistencyScore(issues, totalFiles);
241
+ toolScores.set("consistency", consistencyScore);
242
+ } catch (err) {
243
+ void err;
244
+ }
245
+ }
246
+ if (results.aiSignalClarity) {
247
+ const { calculateAiSignalClarityScore } = await import("@aiready/ai-signal-clarity");
248
+ try {
249
+ const hrScore = calculateAiSignalClarityScore(results.aiSignalClarity);
250
+ toolScores.set("ai-signal-clarity", hrScore);
251
+ } catch (err) {
252
+ void err;
253
+ }
254
+ }
255
+ if (results.grounding) {
256
+ const { calculateGroundingScore } = await import("@aiready/agent-grounding");
257
+ try {
258
+ const agScore = calculateGroundingScore(results.grounding);
259
+ toolScores.set("agent-grounding", agScore);
260
+ } catch (err) {
261
+ void err;
262
+ }
263
+ }
264
+ if (results.testability) {
265
+ const { calculateTestabilityScore } = await import("@aiready/testability");
266
+ try {
267
+ const tbScore = calculateTestabilityScore(results.testability);
268
+ toolScores.set("testability", tbScore);
269
+ } catch (err) {
270
+ void err;
271
+ }
272
+ }
273
+ if (results.docDrift) {
274
+ toolScores.set("doc-drift", {
275
+ toolName: "doc-drift",
276
+ score: results.docDrift.summary.score,
277
+ rawMetrics: results.docDrift.rawData,
278
+ factors: [],
279
+ recommendations: (results.docDrift.recommendations || []).map(
280
+ (action) => ({
281
+ action,
282
+ estimatedImpact: 5,
283
+ priority: "medium"
284
+ })
285
+ )
286
+ });
287
+ }
288
+ if (results.deps) {
289
+ toolScores.set("dependency-health", {
290
+ toolName: "dependency-health",
291
+ score: results.deps.summary.score,
292
+ rawMetrics: results.deps.rawData,
293
+ factors: [],
294
+ recommendations: (results.deps.recommendations || []).map(
295
+ (action) => ({
296
+ action,
297
+ estimatedImpact: 5,
298
+ priority: "medium"
299
+ })
300
+ )
301
+ });
302
+ }
303
+ if (results.changeAmplification) {
304
+ toolScores.set("change-amplification", {
305
+ toolName: "change-amplification",
306
+ score: results.changeAmplification.summary.score,
307
+ rawMetrics: results.changeAmplification.rawData,
308
+ factors: [],
309
+ recommendations: (results.changeAmplification.recommendations || []).map(
310
+ (action) => ({
311
+ action,
312
+ estimatedImpact: 5,
313
+ priority: "medium"
314
+ })
315
+ )
316
+ });
317
+ }
318
+ if (toolScores.size === 0) {
319
+ return {
320
+ overall: 0,
321
+ rating: "Critical",
322
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
323
+ toolsUsed: [],
324
+ breakdown: [],
325
+ calculation: {
326
+ formula: "0 / 0 = 0",
327
+ weights: {},
328
+ normalized: "0 / 0 = 0"
329
+ }
330
+ };
331
+ }
332
+ return calculateOverallScore(toolScores, options, void 0);
333
+ }
334
+ function generateUnifiedSummary(result) {
335
+ const { summary } = result;
336
+ let output = `\u{1F680} AIReady Analysis Complete
337
+
338
+ `;
339
+ output += `\u{1F4CA} Summary:
340
+ `;
341
+ output += ` Tools run: ${summary.toolsRun.join(", ")}
342
+ `;
343
+ output += ` Total issues found: ${summary.totalIssues}
344
+ `;
345
+ output += ` Execution time: ${(summary.executionTime / 1e3).toFixed(2)}s
346
+
347
+ `;
348
+ if (result.patterns) {
349
+ output += `\u{1F50D} Pattern Analysis: ${result.patterns.length} issues
350
+ `;
351
+ }
352
+ if (result.context) {
353
+ output += `\u{1F9E0} Context Analysis: ${result.context.length} issues
354
+ `;
355
+ }
356
+ if (result.consistency) {
357
+ output += `\u{1F3F7}\uFE0F Consistency Analysis: ${result.consistency.summary.totalIssues} issues
358
+ `;
359
+ }
360
+ if (result.docDrift) {
361
+ output += `\u{1F4DD} Doc Drift Analysis: ${result.docDrift.issues?.length || 0} issues
362
+ `;
363
+ }
364
+ if (result.deps) {
365
+ output += `\u{1F4E6} Dependency Health: ${result.deps.issues?.length || 0} issues
366
+ `;
367
+ }
368
+ if (result.aiSignalClarity) {
369
+ output += `\u{1F9E0} AI Signal Clarity: ${result.aiSignalClarity.summary?.totalSignals || 0} signals
370
+ `;
371
+ }
372
+ if (result.grounding) {
373
+ output += `\u{1F9ED} Agent Grounding: ${result.grounding.issues?.length || 0} issues
374
+ `;
375
+ }
376
+ if (result.testability) {
377
+ output += `\u{1F9EA} Testability Index: ${result.testability.issues?.length || 0} issues
378
+ `;
379
+ }
380
+ if (result.changeAmplification) {
381
+ output += `\u{1F4A5} Change Amplification: ${result.changeAmplification.summary?.totalIssues || 0} cascading risks
382
+ `;
383
+ }
384
+ return output;
385
+ }
386
+
387
+ export {
388
+ __require,
389
+ analyzeUnified,
390
+ scoreUnified,
391
+ generateUnifiedSummary
392
+ };