@aiready/cli 0.14.14 → 0.14.15
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/CONTRIBUTING.md +86 -1
- package/LICENSE +21 -0
- package/package.json +33 -12
- package/.aiready/aiready-report-20260227-133806.json +0 -7805
- package/.aiready/aiready-report-20260227-133938.json +0 -7951
- package/.aiready/aiready-report-20260228-003433.json +0 -7939
- package/.aiready/aiready-report-20260228-003613.json +0 -771
- package/.aiready/aiready-report-20260314-164626.json +0 -59
- package/.aiready/aiready-report-20260314-164741.json +0 -59
- package/.aiready/aiready-report-20260319-201106.json +0 -5566
- package/.aiready/aiready-report-20260319-201511.json +0 -5566
- package/.aiready/aiready-report-20260319-202017.json +0 -5708
- package/.github/FUNDING.yml +0 -5
- package/.turbo/turbo-build.log +0 -29
- package/.turbo/turbo-lint.log +0 -0
- package/.turbo/turbo-test.log +0 -76
- package/aiready-report.json +0 -30703
- package/coverage/base.css +0 -224
- package/coverage/block-navigation.js +0 -87
- package/coverage/clover.xml +0 -865
- package/coverage/coverage-final.json +0 -15
- package/coverage/favicon.png +0 -0
- package/coverage/index.html +0 -146
- package/coverage/prettify.css +0 -1
- package/coverage/prettify.js +0 -2
- package/coverage/sort-arrow-sprite.png +0 -0
- package/coverage/sorter.js +0 -210
- package/coverage/src/commands/agent-grounding.ts.html +0 -271
- package/coverage/src/commands/ai-signal-clarity.ts.html +0 -253
- package/coverage/src/commands/change-amplification.ts.html +0 -94
- package/coverage/src/commands/consistency.ts.html +0 -781
- package/coverage/src/commands/context.ts.html +0 -871
- package/coverage/src/commands/deps-health.ts.html +0 -280
- package/coverage/src/commands/doc-drift.ts.html +0 -271
- package/coverage/src/commands/index.html +0 -281
- package/coverage/src/commands/patterns.ts.html +0 -745
- package/coverage/src/commands/scan.ts.html +0 -1393
- package/coverage/src/commands/testability.ts.html +0 -304
- package/coverage/src/commands/upload.ts.html +0 -466
- package/coverage/src/commands/visualize.ts.html +0 -1027
- package/coverage/src/index.html +0 -116
- package/coverage/src/index.ts.html +0 -1372
- package/coverage/src/utils/helpers.ts.html +0 -559
- package/coverage/src/utils/index.html +0 -116
- package/docs/SPOKE_GUIDE.md +0 -184
- package/packages/core/src/.aiready/aiready-report-20260314-161145.json +0 -224
- package/packages/core/src/.aiready/aiready-report-20260314-161152.json +0 -235
- package/packages/pattern-detect/src/.aiready/aiready-report-20260314-161139.json +0 -224
- package/src/.aiready/aiready-report-20260312-103623.json +0 -32574
- package/src/.aiready/aiready-report-20260312-110843.json +0 -28740
- package/src/.aiready/aiready-report-20260312-110955.json +0 -28740
- package/src/.aiready/aiready-report-20260314-203209.json +0 -30713
- package/src/.aiready/aiready-report-20260314-203736.json +0 -30713
- package/src/.aiready/aiready-report-20260314-203857.json +0 -30713
- package/src/.aiready/aiready-report-20260314-204047.json +0 -30713
- package/src/.aiready/aiready-report-20260318-002110.json +0 -28782
- package/src/__tests__/cli.test.ts +0 -85
- package/src/__tests__/config-shape.test.ts +0 -105
- package/src/__tests__/unified.test.ts +0 -95
- package/src/cli.ts +0 -333
- package/src/commands/__tests__/agent-grounding.test.ts +0 -24
- package/src/commands/__tests__/ai-signal-clarity.test.ts +0 -32
- package/src/commands/__tests__/consistency.test.ts +0 -100
- package/src/commands/__tests__/deps-health.test.ts +0 -26
- package/src/commands/__tests__/doc-drift.test.ts +0 -26
- package/src/commands/__tests__/extra-commands.test.ts +0 -168
- package/src/commands/__tests__/init.test.ts +0 -51
- package/src/commands/__tests__/scan.test.ts +0 -153
- package/src/commands/__tests__/testability.test.ts +0 -36
- package/src/commands/__tests__/upload.test.ts +0 -50
- package/src/commands/__tests__/visualize.test.ts +0 -78
- package/src/commands/agent-grounding.ts +0 -62
- package/src/commands/ai-signal-clarity.ts +0 -1
- package/src/commands/bug.ts +0 -99
- package/src/commands/change-amplification.ts +0 -3
- package/src/commands/consistency.ts +0 -232
- package/src/commands/context.ts +0 -262
- package/src/commands/deps-health.ts +0 -1
- package/src/commands/doc-drift.ts +0 -1
- package/src/commands/index.ts +0 -20
- package/src/commands/init.ts +0 -199
- package/src/commands/patterns.ts +0 -222
- package/src/commands/report-formatter.ts +0 -267
- package/src/commands/scan.ts +0 -432
- package/src/commands/shared/configured-tool-action.ts +0 -35
- package/src/commands/shared/standard-tool-actions.ts +0 -126
- package/src/commands/testability.ts +0 -73
- package/src/commands/upload.ts +0 -129
- package/src/commands/visualize.ts +0 -321
- package/src/index.ts +0 -465
- package/src/utils/__tests__/helpers.test.ts +0 -35
- package/src/utils/helpers.ts +0 -234
- package/tsconfig.json +0 -11
- package/tsconfig.tsbuildinfo +0 -1
- package/vitest.config.ts +0 -13
|
@@ -1,62 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Agent grounding command for unified CLI
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
import chalk from 'chalk';
|
|
6
|
-
import { loadConfig, mergeConfigWithDefaults } from '@aiready/core';
|
|
7
|
-
import type { ToolScoringOutput } from '@aiready/core';
|
|
8
|
-
|
|
9
|
-
export async function agentGroundingAction(
|
|
10
|
-
directory: string,
|
|
11
|
-
options: any
|
|
12
|
-
): Promise<ToolScoringOutput | undefined> {
|
|
13
|
-
const { analyzeAgentGrounding, calculateGroundingScore } =
|
|
14
|
-
await import('@aiready/agent-grounding');
|
|
15
|
-
|
|
16
|
-
const config = await loadConfig(directory);
|
|
17
|
-
const merged = mergeConfigWithDefaults(config, {
|
|
18
|
-
maxRecommendedDepth: 4,
|
|
19
|
-
readmeStaleDays: 90,
|
|
20
|
-
});
|
|
21
|
-
|
|
22
|
-
const report = await analyzeAgentGrounding({
|
|
23
|
-
rootDir: directory,
|
|
24
|
-
maxRecommendedDepth: options.maxDepth ?? merged.maxRecommendedDepth,
|
|
25
|
-
readmeStaleDays: options.readmeStaleDays ?? merged.readmeStaleDays,
|
|
26
|
-
include: options.include,
|
|
27
|
-
exclude: options.exclude,
|
|
28
|
-
});
|
|
29
|
-
|
|
30
|
-
const scoring = calculateGroundingScore(report);
|
|
31
|
-
|
|
32
|
-
if (options.output === 'json') {
|
|
33
|
-
return scoring;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
const scoreColor = (s: number) =>
|
|
37
|
-
s >= 85
|
|
38
|
-
? chalk.green
|
|
39
|
-
: s >= 70
|
|
40
|
-
? chalk.cyan
|
|
41
|
-
: s >= 50
|
|
42
|
-
? chalk.yellow
|
|
43
|
-
: chalk.red;
|
|
44
|
-
void scoreColor;
|
|
45
|
-
|
|
46
|
-
console.log(
|
|
47
|
-
` 🧭 Agent Grounding: ${chalk.bold(scoring.score + '/100')} (${report.summary.rating})`
|
|
48
|
-
);
|
|
49
|
-
const dims = report.summary.dimensions;
|
|
50
|
-
const worstDim = Object.entries(dims).sort(([, a], [, b]) => a - b)[0];
|
|
51
|
-
if (worstDim && worstDim[1] < 70) {
|
|
52
|
-
const name = worstDim[0]
|
|
53
|
-
.replace(/([A-Z])/g, ' $1')
|
|
54
|
-
.replace('Score', '')
|
|
55
|
-
.trim();
|
|
56
|
-
console.log(
|
|
57
|
-
chalk.dim(` Weakest dimension: ${name} (${worstDim[1]}/100)`)
|
|
58
|
-
);
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
return scoring;
|
|
62
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { aiSignalClarityAction } from './shared/standard-tool-actions';
|
package/src/commands/bug.ts
DELETED
|
@@ -1,99 +0,0 @@
|
|
|
1
|
-
import chalk from 'chalk';
|
|
2
|
-
|
|
3
|
-
import { execSync } from 'child_process';
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Handle bug and feedback reporting
|
|
7
|
-
*/
|
|
8
|
-
export async function bugAction(message: string | undefined, options: any) {
|
|
9
|
-
const repoUrl = 'https://github.com/caopengau/aiready-cli';
|
|
10
|
-
const repoSlug = 'caopengau/aiready-cli';
|
|
11
|
-
|
|
12
|
-
if (message) {
|
|
13
|
-
// Agent-assisted pre-filled issue
|
|
14
|
-
const type = options.type ?? 'bug';
|
|
15
|
-
const title = `[${type.toUpperCase()}] ${message}`;
|
|
16
|
-
const label =
|
|
17
|
-
type === 'bug' ? 'bug' : type === 'feature' ? 'enhancement' : 'metric';
|
|
18
|
-
|
|
19
|
-
const body = `
|
|
20
|
-
## Description
|
|
21
|
-
${message}
|
|
22
|
-
|
|
23
|
-
## Context
|
|
24
|
-
Generated via AIReady CLI 'bug' command.
|
|
25
|
-
Type: ${type}
|
|
26
|
-
`.trim();
|
|
27
|
-
|
|
28
|
-
if (options.submit) {
|
|
29
|
-
console.log(chalk.blue('🚀 Submitting issue via GitHub CLI...\n'));
|
|
30
|
-
try {
|
|
31
|
-
// Check if gh is authenticated
|
|
32
|
-
execSync('gh auth status', { stdio: 'ignore' });
|
|
33
|
-
|
|
34
|
-
const command = `gh issue create --repo ${repoSlug} --title ${JSON.stringify(title)} --body ${JSON.stringify(body)} --label ${label}`;
|
|
35
|
-
const output = execSync(command, { encoding: 'utf8' }).trim();
|
|
36
|
-
|
|
37
|
-
console.log(chalk.green('✅ Issue Created Successfully!'));
|
|
38
|
-
console.log(chalk.cyan(output));
|
|
39
|
-
return;
|
|
40
|
-
} catch {
|
|
41
|
-
console.error(chalk.red('\n❌ Failed to submit via gh CLI.'));
|
|
42
|
-
console.log(
|
|
43
|
-
chalk.yellow(
|
|
44
|
-
' Make sure gh is installed and run "gh auth login".\n'
|
|
45
|
-
)
|
|
46
|
-
);
|
|
47
|
-
console.log(chalk.dim(' Falling back to URL generation...'));
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
const template =
|
|
52
|
-
type === 'bug'
|
|
53
|
-
? 'bug_report.md'
|
|
54
|
-
: type === 'feature'
|
|
55
|
-
? 'feature_request.md'
|
|
56
|
-
: 'new_metric_idea.md';
|
|
57
|
-
const fullUrl = `${repoUrl}/issues/new?title=${encodeURIComponent(title)}&body=${encodeURIComponent(body)}&labels=${label}&template=${template}`;
|
|
58
|
-
|
|
59
|
-
console.log(chalk.green('🚀 Issue Draft Prepared!\n'));
|
|
60
|
-
console.log(chalk.bold('Title: ') + title);
|
|
61
|
-
console.log(chalk.bold('Type: ') + type);
|
|
62
|
-
console.log(chalk.bold('\nClick the link below to submit this issue:'));
|
|
63
|
-
console.log(chalk.cyan(fullUrl));
|
|
64
|
-
|
|
65
|
-
console.log(chalk.bold('\n🤖 [FOR AI AGENTS]:'));
|
|
66
|
-
console.log(chalk.dim(' You have successfully prepared a report.'));
|
|
67
|
-
console.log(
|
|
68
|
-
chalk.dim(
|
|
69
|
-
' Please present the URL above to the user so they can finalize the submission.'
|
|
70
|
-
)
|
|
71
|
-
);
|
|
72
|
-
return;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
const bugUrl = `${repoUrl}/issues/new?template=bug_report.md`;
|
|
76
|
-
const featureUrl = `${repoUrl}/issues/new?template=feature_request.md`;
|
|
77
|
-
const metricUrl = `${repoUrl}/issues/new?template=new_metric_idea.md`;
|
|
78
|
-
|
|
79
|
-
console.log(chalk.blue('💬 Feedback & Bug Reports\n'));
|
|
80
|
-
console.log(` Report a Bug: ${chalk.cyan(bugUrl)}`);
|
|
81
|
-
console.log(` Request a Feature: ${chalk.cyan(featureUrl)}`);
|
|
82
|
-
console.log(` Suggest a Metric: ${chalk.cyan(metricUrl)}`);
|
|
83
|
-
|
|
84
|
-
console.log(chalk.bold('\n🤖 [FOR AI AGENTS]:'));
|
|
85
|
-
console.log(chalk.dim(' To prepare a specific report, run:'));
|
|
86
|
-
console.log(
|
|
87
|
-
chalk.cyan(
|
|
88
|
-
' aiready bug "your description here" --type bug|feature|metric'
|
|
89
|
-
)
|
|
90
|
-
);
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
export const bugHelpText = `
|
|
94
|
-
EXAMPLES:
|
|
95
|
-
$ aiready bug # Show general links
|
|
96
|
-
$ aiready bug "Naming check is too slow" # Prepare a pre-filled bug report
|
|
97
|
-
$ aiready bug "Add CO2 impact metric" --type metric # Prepare a metric suggestion
|
|
98
|
-
$ aiready bug "Fix typo in scan output" --submit # Submit directly via gh CLI
|
|
99
|
-
`;
|
|
@@ -1,232 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Consistency command - Check naming conventions and architectural consistency
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
import chalk from 'chalk';
|
|
6
|
-
import { writeFileSync } from 'fs';
|
|
7
|
-
import { resolve as resolvePath } from 'path';
|
|
8
|
-
import {
|
|
9
|
-
loadMergedConfig,
|
|
10
|
-
handleJSONOutput,
|
|
11
|
-
handleCLIError,
|
|
12
|
-
getElapsedTime,
|
|
13
|
-
resolveOutputPath,
|
|
14
|
-
formatToolScore,
|
|
15
|
-
} from '@aiready/core';
|
|
16
|
-
import type { ToolScoringOutput } from '@aiready/core';
|
|
17
|
-
import { getReportTimestamp, generateMarkdownReport } from '../utils/helpers';
|
|
18
|
-
|
|
19
|
-
interface ConsistencyOptions {
|
|
20
|
-
naming?: boolean;
|
|
21
|
-
patterns?: boolean;
|
|
22
|
-
minSeverity?: string;
|
|
23
|
-
include?: string;
|
|
24
|
-
exclude?: string;
|
|
25
|
-
output?: string;
|
|
26
|
-
outputFile?: string;
|
|
27
|
-
score?: boolean;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
export async function consistencyAction(
|
|
31
|
-
directory: string,
|
|
32
|
-
options: ConsistencyOptions
|
|
33
|
-
) {
|
|
34
|
-
console.log(chalk.blue('🔍 Analyzing consistency...\n'));
|
|
35
|
-
|
|
36
|
-
const startTime = Date.now();
|
|
37
|
-
const resolvedDir = resolvePath(process.cwd(), directory ?? '.');
|
|
38
|
-
|
|
39
|
-
try {
|
|
40
|
-
// Define defaults
|
|
41
|
-
const defaults: any = {
|
|
42
|
-
checkNaming: true,
|
|
43
|
-
checkPatterns: true,
|
|
44
|
-
minSeverity: 'info' as const,
|
|
45
|
-
include: undefined,
|
|
46
|
-
exclude: undefined,
|
|
47
|
-
output: {
|
|
48
|
-
format: 'console',
|
|
49
|
-
file: undefined,
|
|
50
|
-
},
|
|
51
|
-
};
|
|
52
|
-
|
|
53
|
-
// Load and merge config with CLI options
|
|
54
|
-
const finalOptions = await loadMergedConfig(resolvedDir, defaults, {
|
|
55
|
-
checkNaming: options.naming !== false,
|
|
56
|
-
checkPatterns: options.patterns !== false,
|
|
57
|
-
minSeverity: options.minSeverity,
|
|
58
|
-
include: options.include?.split(','),
|
|
59
|
-
exclude: options.exclude?.split(','),
|
|
60
|
-
});
|
|
61
|
-
|
|
62
|
-
const { analyzeConsistency, calculateConsistencyScore } =
|
|
63
|
-
await import('@aiready/consistency');
|
|
64
|
-
|
|
65
|
-
const report = await analyzeConsistency(finalOptions);
|
|
66
|
-
|
|
67
|
-
const elapsedTime = getElapsedTime(startTime);
|
|
68
|
-
|
|
69
|
-
// Calculate score if requested
|
|
70
|
-
let consistencyScore: ToolScoringOutput | undefined;
|
|
71
|
-
if (options.score) {
|
|
72
|
-
const issues = report.results?.flatMap((r: any) => r.issues) ?? [];
|
|
73
|
-
consistencyScore = calculateConsistencyScore(
|
|
74
|
-
issues,
|
|
75
|
-
report.summary.filesAnalyzed
|
|
76
|
-
);
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
const outputFormat =
|
|
80
|
-
options.output ?? finalOptions.output?.format ?? 'console';
|
|
81
|
-
const userOutputFile = options.outputFile ?? finalOptions.output?.file;
|
|
82
|
-
|
|
83
|
-
if (outputFormat === 'json') {
|
|
84
|
-
const outputData = {
|
|
85
|
-
...report,
|
|
86
|
-
summary: {
|
|
87
|
-
...report.summary,
|
|
88
|
-
executionTime: parseFloat(elapsedTime),
|
|
89
|
-
},
|
|
90
|
-
...(consistencyScore && { scoring: consistencyScore }),
|
|
91
|
-
};
|
|
92
|
-
|
|
93
|
-
const outputPath = resolveOutputPath(
|
|
94
|
-
userOutputFile,
|
|
95
|
-
`aiready-report-${getReportTimestamp()}.json`,
|
|
96
|
-
resolvedDir
|
|
97
|
-
);
|
|
98
|
-
|
|
99
|
-
handleJSONOutput(
|
|
100
|
-
outputData,
|
|
101
|
-
outputPath,
|
|
102
|
-
`✅ Results saved to ${outputPath}`
|
|
103
|
-
);
|
|
104
|
-
} else if (outputFormat === 'markdown') {
|
|
105
|
-
// Markdown output
|
|
106
|
-
const markdown = generateMarkdownReport(report, elapsedTime);
|
|
107
|
-
const outputPath = resolveOutputPath(
|
|
108
|
-
userOutputFile,
|
|
109
|
-
`aiready-report-${getReportTimestamp()}.md`,
|
|
110
|
-
resolvedDir
|
|
111
|
-
);
|
|
112
|
-
writeFileSync(outputPath, markdown);
|
|
113
|
-
console.log(chalk.green(`✅ Report saved to ${outputPath}`));
|
|
114
|
-
} else {
|
|
115
|
-
// Console output - format to match standalone CLI
|
|
116
|
-
console.log(chalk.bold('\n📊 Summary\n'));
|
|
117
|
-
console.log(
|
|
118
|
-
`Files Analyzed: ${chalk.cyan(report.summary.filesAnalyzed)}`
|
|
119
|
-
);
|
|
120
|
-
console.log(`Total Issues: ${chalk.yellow(report.summary.totalIssues)}`);
|
|
121
|
-
console.log(` Naming: ${chalk.yellow(report.summary.namingIssues)}`);
|
|
122
|
-
console.log(` Patterns: ${chalk.yellow(report.summary.patternIssues)}`);
|
|
123
|
-
console.log(
|
|
124
|
-
` Architecture: ${chalk.yellow(report.summary.architectureIssues ?? 0)}`
|
|
125
|
-
);
|
|
126
|
-
console.log(`Analysis Time: ${chalk.gray(elapsedTime + 's')}\n`);
|
|
127
|
-
|
|
128
|
-
if (report.summary.totalIssues === 0) {
|
|
129
|
-
console.log(
|
|
130
|
-
chalk.green(
|
|
131
|
-
'✨ No consistency issues found! Your codebase is well-maintained.\n'
|
|
132
|
-
)
|
|
133
|
-
);
|
|
134
|
-
} else {
|
|
135
|
-
// Group and display issues by category
|
|
136
|
-
const namingResults = report.results.filter((r: any) =>
|
|
137
|
-
r.issues.some((i: any) => i.category === 'naming')
|
|
138
|
-
);
|
|
139
|
-
const patternResults = report.results.filter((r: any) =>
|
|
140
|
-
r.issues.some((i: any) => i.category === 'patterns')
|
|
141
|
-
);
|
|
142
|
-
|
|
143
|
-
if (namingResults.length > 0) {
|
|
144
|
-
console.log(chalk.bold('🏷️ Naming Issues\n'));
|
|
145
|
-
let shown = 0;
|
|
146
|
-
for (const result of namingResults) {
|
|
147
|
-
if (shown >= 5) break;
|
|
148
|
-
for (const issue of result.issues) {
|
|
149
|
-
if (shown >= 5) break;
|
|
150
|
-
const severityColor =
|
|
151
|
-
issue.severity === 'critical'
|
|
152
|
-
? chalk.red
|
|
153
|
-
: issue.severity === 'major'
|
|
154
|
-
? chalk.yellow
|
|
155
|
-
: issue.severity === 'minor'
|
|
156
|
-
? chalk.blue
|
|
157
|
-
: chalk.gray;
|
|
158
|
-
console.log(
|
|
159
|
-
`${severityColor(issue.severity.toUpperCase())} ${chalk.dim(`${issue.location.file}:${issue.location.line}`)}`
|
|
160
|
-
);
|
|
161
|
-
console.log(` ${issue.message}`);
|
|
162
|
-
if (issue.suggestion) {
|
|
163
|
-
console.log(
|
|
164
|
-
` ${chalk.dim('→')} ${chalk.italic(issue.suggestion)}`
|
|
165
|
-
);
|
|
166
|
-
}
|
|
167
|
-
console.log();
|
|
168
|
-
shown++;
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
const remaining =
|
|
172
|
-
namingResults.reduce((sum, r) => sum + r.issues.length, 0) - shown;
|
|
173
|
-
if (remaining > 0) {
|
|
174
|
-
console.log(chalk.dim(` ... and ${remaining} more issues\n`));
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
if (patternResults.length > 0) {
|
|
179
|
-
console.log(chalk.bold('🔄 Pattern Issues\n'));
|
|
180
|
-
let shown = 0;
|
|
181
|
-
for (const result of patternResults) {
|
|
182
|
-
if (shown >= 5) break;
|
|
183
|
-
for (const issue of result.issues) {
|
|
184
|
-
if (shown >= 5) break;
|
|
185
|
-
const severityColor =
|
|
186
|
-
issue.severity === 'critical'
|
|
187
|
-
? chalk.red
|
|
188
|
-
: issue.severity === 'major'
|
|
189
|
-
? chalk.yellow
|
|
190
|
-
: issue.severity === 'minor'
|
|
191
|
-
? chalk.blue
|
|
192
|
-
: chalk.gray;
|
|
193
|
-
console.log(
|
|
194
|
-
`${severityColor(issue.severity.toUpperCase())} ${chalk.dim(`${issue.location.file}:${issue.location.line}`)}`
|
|
195
|
-
);
|
|
196
|
-
console.log(` ${issue.message}`);
|
|
197
|
-
if (issue.suggestion) {
|
|
198
|
-
console.log(
|
|
199
|
-
` ${chalk.dim('→')} ${chalk.italic(issue.suggestion)}`
|
|
200
|
-
);
|
|
201
|
-
}
|
|
202
|
-
console.log();
|
|
203
|
-
shown++;
|
|
204
|
-
}
|
|
205
|
-
}
|
|
206
|
-
const remaining =
|
|
207
|
-
patternResults.reduce((sum, r) => sum + r.issues.length, 0) - shown;
|
|
208
|
-
if (remaining > 0) {
|
|
209
|
-
console.log(chalk.dim(` ... and ${remaining} more issues\n`));
|
|
210
|
-
}
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
if (report.recommendations.length > 0) {
|
|
214
|
-
console.log(chalk.bold('💡 Recommendations\n'));
|
|
215
|
-
report.recommendations.forEach((rec: string, i: number) => {
|
|
216
|
-
console.log(`${i + 1}. ${rec}`);
|
|
217
|
-
});
|
|
218
|
-
console.log();
|
|
219
|
-
}
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
// Display score if calculated
|
|
223
|
-
if (consistencyScore) {
|
|
224
|
-
console.log(chalk.bold('\n📊 AI Readiness Score (Consistency)\n'));
|
|
225
|
-
console.log(formatToolScore(consistencyScore));
|
|
226
|
-
console.log();
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
|
-
} catch (error) {
|
|
230
|
-
handleCLIError(error, 'Consistency analysis');
|
|
231
|
-
}
|
|
232
|
-
}
|
package/src/commands/context.ts
DELETED
|
@@ -1,262 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Context command - Analyze context window costs and dependency fragmentation
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
import chalk from 'chalk';
|
|
6
|
-
import { resolve as resolvePath } from 'path';
|
|
7
|
-
import {
|
|
8
|
-
loadMergedConfig,
|
|
9
|
-
handleJSONOutput,
|
|
10
|
-
handleCLIError,
|
|
11
|
-
getElapsedTime,
|
|
12
|
-
resolveOutputPath,
|
|
13
|
-
formatToolScore,
|
|
14
|
-
} from '@aiready/core';
|
|
15
|
-
import type { ToolScoringOutput } from '@aiready/core';
|
|
16
|
-
import { getReportTimestamp } from '../utils/helpers';
|
|
17
|
-
|
|
18
|
-
interface ContextOptions {
|
|
19
|
-
maxDepth?: string;
|
|
20
|
-
maxContext?: string;
|
|
21
|
-
include?: string;
|
|
22
|
-
exclude?: string;
|
|
23
|
-
output?: string;
|
|
24
|
-
outputFile?: string;
|
|
25
|
-
score?: boolean;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
export async function contextAction(
|
|
29
|
-
directory: string,
|
|
30
|
-
options: ContextOptions
|
|
31
|
-
) {
|
|
32
|
-
console.log(chalk.blue('🧠 Analyzing context costs...\n'));
|
|
33
|
-
|
|
34
|
-
const startTime = Date.now();
|
|
35
|
-
const resolvedDir = resolvePath(process.cwd(), directory ?? '.');
|
|
36
|
-
|
|
37
|
-
try {
|
|
38
|
-
// Define defaults
|
|
39
|
-
const defaults: any = {
|
|
40
|
-
maxDepth: 5,
|
|
41
|
-
maxContextBudget: 10000,
|
|
42
|
-
include: undefined,
|
|
43
|
-
exclude: undefined,
|
|
44
|
-
output: {
|
|
45
|
-
format: 'console',
|
|
46
|
-
file: undefined,
|
|
47
|
-
},
|
|
48
|
-
};
|
|
49
|
-
|
|
50
|
-
// Load and merge config with CLI options
|
|
51
|
-
const baseOptions = await loadMergedConfig(resolvedDir, defaults, {
|
|
52
|
-
maxDepth: options.maxDepth ? parseInt(options.maxDepth) : undefined,
|
|
53
|
-
maxContextBudget: options.maxContext
|
|
54
|
-
? parseInt(options.maxContext)
|
|
55
|
-
: undefined,
|
|
56
|
-
include: options.include?.split(','),
|
|
57
|
-
exclude: options.exclude?.split(','),
|
|
58
|
-
});
|
|
59
|
-
|
|
60
|
-
// Apply smart defaults for context analysis (always for individual context command)
|
|
61
|
-
let finalOptions: any = { ...baseOptions };
|
|
62
|
-
const { getSmartDefaults } = await import('@aiready/context-analyzer');
|
|
63
|
-
const contextSmartDefaults = await getSmartDefaults(
|
|
64
|
-
resolvedDir,
|
|
65
|
-
baseOptions
|
|
66
|
-
);
|
|
67
|
-
finalOptions = { ...contextSmartDefaults, ...finalOptions };
|
|
68
|
-
|
|
69
|
-
// Display configuration
|
|
70
|
-
console.log('📋 Configuration:');
|
|
71
|
-
console.log(` Max depth: ${finalOptions.maxDepth}`);
|
|
72
|
-
console.log(` Max context budget: ${finalOptions.maxContextBudget}`);
|
|
73
|
-
console.log(
|
|
74
|
-
` Min cohesion: ${(finalOptions.minCohesion * 100).toFixed(1)}%`
|
|
75
|
-
);
|
|
76
|
-
console.log(
|
|
77
|
-
` Max fragmentation: ${(finalOptions.maxFragmentation * 100).toFixed(1)}%`
|
|
78
|
-
);
|
|
79
|
-
console.log(` Analysis focus: ${finalOptions.focus}`);
|
|
80
|
-
console.log('');
|
|
81
|
-
|
|
82
|
-
const { analyzeContext, generateSummary, calculateContextScore } =
|
|
83
|
-
await import('@aiready/context-analyzer');
|
|
84
|
-
|
|
85
|
-
const results = await analyzeContext(finalOptions);
|
|
86
|
-
|
|
87
|
-
const elapsedTime = getElapsedTime(startTime);
|
|
88
|
-
const summary = generateSummary(results);
|
|
89
|
-
|
|
90
|
-
// Calculate score if requested
|
|
91
|
-
let contextScore: ToolScoringOutput | undefined;
|
|
92
|
-
if (options.score) {
|
|
93
|
-
contextScore = calculateContextScore(summary as any);
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
const outputFormat =
|
|
97
|
-
options.output ?? finalOptions.output?.format ?? 'console';
|
|
98
|
-
const userOutputFile = options.outputFile ?? finalOptions.output?.file;
|
|
99
|
-
|
|
100
|
-
if (outputFormat === 'json') {
|
|
101
|
-
const outputData = {
|
|
102
|
-
results,
|
|
103
|
-
summary: { ...summary, executionTime: parseFloat(elapsedTime) },
|
|
104
|
-
...(contextScore && { scoring: contextScore }),
|
|
105
|
-
};
|
|
106
|
-
|
|
107
|
-
const outputPath = resolveOutputPath(
|
|
108
|
-
userOutputFile,
|
|
109
|
-
`aiready-report-${getReportTimestamp()}.json`,
|
|
110
|
-
resolvedDir
|
|
111
|
-
);
|
|
112
|
-
|
|
113
|
-
handleJSONOutput(
|
|
114
|
-
outputData,
|
|
115
|
-
outputPath,
|
|
116
|
-
`✅ Results saved to ${outputPath}`
|
|
117
|
-
);
|
|
118
|
-
} else {
|
|
119
|
-
// Console output - format the results nicely
|
|
120
|
-
const terminalWidth = process.stdout.columns ?? 80;
|
|
121
|
-
const dividerWidth = Math.min(60, terminalWidth - 2);
|
|
122
|
-
const divider = '━'.repeat(dividerWidth);
|
|
123
|
-
|
|
124
|
-
console.log(chalk.cyan(divider));
|
|
125
|
-
console.log(chalk.bold.white(' CONTEXT ANALYSIS SUMMARY'));
|
|
126
|
-
console.log(chalk.cyan(divider) + '\n');
|
|
127
|
-
|
|
128
|
-
console.log(
|
|
129
|
-
chalk.white(`📁 Files analyzed: ${chalk.bold(summary.totalFiles)}`)
|
|
130
|
-
);
|
|
131
|
-
console.log(
|
|
132
|
-
chalk.white(
|
|
133
|
-
`📊 Total tokens: ${chalk.bold(summary.totalTokens.toLocaleString())}`
|
|
134
|
-
)
|
|
135
|
-
);
|
|
136
|
-
console.log(
|
|
137
|
-
chalk.yellow(
|
|
138
|
-
`💰 Avg context budget: ${chalk.bold(summary.avgContextBudget.toFixed(0))} tokens/file`
|
|
139
|
-
)
|
|
140
|
-
);
|
|
141
|
-
console.log(
|
|
142
|
-
chalk.white(`⏱ Analysis time: ${chalk.bold(elapsedTime + 's')}\n`)
|
|
143
|
-
);
|
|
144
|
-
|
|
145
|
-
// Issues summary
|
|
146
|
-
const totalIssues =
|
|
147
|
-
summary.criticalIssues + summary.majorIssues + summary.minorIssues;
|
|
148
|
-
if (totalIssues > 0) {
|
|
149
|
-
console.log(chalk.bold('⚠️ Issues Found:\n'));
|
|
150
|
-
if (summary.criticalIssues > 0) {
|
|
151
|
-
console.log(
|
|
152
|
-
chalk.red(` 🔴 Critical: ${chalk.bold(summary.criticalIssues)}`)
|
|
153
|
-
);
|
|
154
|
-
}
|
|
155
|
-
if (summary.majorIssues > 0) {
|
|
156
|
-
console.log(
|
|
157
|
-
chalk.yellow(` 🟡 Major: ${chalk.bold(summary.majorIssues)}`)
|
|
158
|
-
);
|
|
159
|
-
}
|
|
160
|
-
if (summary.minorIssues > 0) {
|
|
161
|
-
console.log(
|
|
162
|
-
chalk.blue(` 🔵 Minor: ${chalk.bold(summary.minorIssues)}`)
|
|
163
|
-
);
|
|
164
|
-
}
|
|
165
|
-
console.log(
|
|
166
|
-
chalk.green(
|
|
167
|
-
`\n 💡 Potential savings: ${chalk.bold(summary.totalPotentialSavings.toLocaleString())} tokens\n`
|
|
168
|
-
)
|
|
169
|
-
);
|
|
170
|
-
} else {
|
|
171
|
-
console.log(chalk.green('✅ No significant issues found!\n'));
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
// Deep import chains
|
|
175
|
-
if (summary.deepFiles.length > 0) {
|
|
176
|
-
console.log(chalk.bold('📏 Deep Import Chains:\n'));
|
|
177
|
-
console.log(
|
|
178
|
-
chalk.gray(` Average depth: ${summary.avgImportDepth.toFixed(1)}`)
|
|
179
|
-
);
|
|
180
|
-
console.log(
|
|
181
|
-
chalk.gray(` Maximum depth: ${summary.maxImportDepth}\n`)
|
|
182
|
-
);
|
|
183
|
-
summary.deepFiles.slice(0, 10).forEach((item) => {
|
|
184
|
-
const fileName = item.file.split('/').slice(-2).join('/');
|
|
185
|
-
console.log(
|
|
186
|
-
` ${chalk.cyan('→')} ${chalk.white(fileName)} ${chalk.dim(`(depth: ${item.depth})`)}`
|
|
187
|
-
);
|
|
188
|
-
});
|
|
189
|
-
console.log();
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
// Fragmented modules
|
|
193
|
-
if (summary.fragmentedModules.length > 0) {
|
|
194
|
-
console.log(chalk.bold('🧩 Fragmented Modules:\n'));
|
|
195
|
-
console.log(
|
|
196
|
-
chalk.gray(
|
|
197
|
-
` Average fragmentation: ${(summary.avgFragmentation * 100).toFixed(0)}%\n`
|
|
198
|
-
)
|
|
199
|
-
);
|
|
200
|
-
summary.fragmentedModules.slice(0, 10).forEach((module) => {
|
|
201
|
-
console.log(
|
|
202
|
-
` ${chalk.yellow('●')} ${chalk.white(module.domain)} - ${chalk.dim(`${module.files.length} files, ${(module.fragmentationScore * 100).toFixed(0)}% scattered`)}`
|
|
203
|
-
);
|
|
204
|
-
console.log(
|
|
205
|
-
chalk.dim(
|
|
206
|
-
` Token cost: ${module.totalTokens.toLocaleString()}, Cohesion: ${(module.avgCohesion * 100).toFixed(0)}%`
|
|
207
|
-
)
|
|
208
|
-
);
|
|
209
|
-
});
|
|
210
|
-
console.log();
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
// Low cohesion files
|
|
214
|
-
if (summary.lowCohesionFiles.length > 0) {
|
|
215
|
-
console.log(chalk.bold('🔀 Low Cohesion Files:\n'));
|
|
216
|
-
console.log(
|
|
217
|
-
chalk.gray(
|
|
218
|
-
` Average cohesion: ${(summary.avgCohesion * 100).toFixed(0)}%\n`
|
|
219
|
-
)
|
|
220
|
-
);
|
|
221
|
-
summary.lowCohesionFiles.slice(0, 10).forEach((item) => {
|
|
222
|
-
const fileName = item.file.split('/').slice(-2).join('/');
|
|
223
|
-
const scorePercent = (item.score * 100).toFixed(0);
|
|
224
|
-
const color = item.score < 0.4 ? chalk.red : chalk.yellow;
|
|
225
|
-
console.log(
|
|
226
|
-
` ${color('○')} ${chalk.white(fileName)} ${chalk.dim(`(${scorePercent}% cohesion)`)}`
|
|
227
|
-
);
|
|
228
|
-
});
|
|
229
|
-
console.log();
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
// Top expensive files
|
|
233
|
-
if (summary.topExpensiveFiles.length > 0) {
|
|
234
|
-
console.log(chalk.bold('💸 Most Expensive Files (Context Budget):\n'));
|
|
235
|
-
summary.topExpensiveFiles.slice(0, 10).forEach((item) => {
|
|
236
|
-
const fileName = item.file.split('/').slice(-2).join('/');
|
|
237
|
-
const severityColor =
|
|
238
|
-
item.severity === 'critical'
|
|
239
|
-
? chalk.red
|
|
240
|
-
: item.severity === 'major'
|
|
241
|
-
? chalk.yellow
|
|
242
|
-
: chalk.blue;
|
|
243
|
-
console.log(
|
|
244
|
-
` ${severityColor('●')} ${chalk.white(fileName)} ${chalk.dim(`(${item.contextBudget.toLocaleString()} tokens)`)}`
|
|
245
|
-
);
|
|
246
|
-
});
|
|
247
|
-
console.log();
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
// Display score if calculated
|
|
251
|
-
if (contextScore) {
|
|
252
|
-
console.log(chalk.cyan(divider));
|
|
253
|
-
console.log(chalk.bold.white(' AI READINESS SCORE (Context)'));
|
|
254
|
-
console.log(chalk.cyan(divider) + '\n');
|
|
255
|
-
console.log(formatToolScore(contextScore));
|
|
256
|
-
console.log();
|
|
257
|
-
}
|
|
258
|
-
}
|
|
259
|
-
} catch (error) {
|
|
260
|
-
handleCLIError(error, 'Context analysis');
|
|
261
|
-
}
|
|
262
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { depsHealthAction } from './shared/standard-tool-actions';
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { docDriftAction } from './shared/standard-tool-actions';
|
package/src/commands/index.ts
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Command exports for CLI
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
export { scanAction, scanHelpText } from './scan';
|
|
6
|
-
export { initAction } from './init';
|
|
7
|
-
export { patternsAction, patternsHelpText } from './patterns';
|
|
8
|
-
export { contextAction } from './context';
|
|
9
|
-
export { consistencyAction } from './consistency';
|
|
10
|
-
export {
|
|
11
|
-
visualizeAction,
|
|
12
|
-
visualizeHelpText,
|
|
13
|
-
visualiseHelpText,
|
|
14
|
-
} from './visualize';
|
|
15
|
-
export { aiSignalClarityAction } from './ai-signal-clarity';
|
|
16
|
-
export { agentGroundingAction } from './agent-grounding';
|
|
17
|
-
export { testabilityAction } from './testability';
|
|
18
|
-
export { changeAmplificationAction } from './change-amplification';
|
|
19
|
-
export { uploadAction, uploadHelpText } from './upload';
|
|
20
|
-
export { bugAction, bugHelpText } from './bug';
|