@aiready/cli 0.14.14 → 0.14.16

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.
Files changed (98) hide show
  1. package/CONTRIBUTING.md +86 -1
  2. package/LICENSE +21 -0
  3. package/README.md +152 -52
  4. package/dist/cli.js +73 -12
  5. package/dist/cli.mjs +73 -12
  6. package/package.json +44 -14
  7. package/.aiready/aiready-report-20260227-133806.json +0 -7805
  8. package/.aiready/aiready-report-20260227-133938.json +0 -7951
  9. package/.aiready/aiready-report-20260228-003433.json +0 -7939
  10. package/.aiready/aiready-report-20260228-003613.json +0 -771
  11. package/.aiready/aiready-report-20260314-164626.json +0 -59
  12. package/.aiready/aiready-report-20260314-164741.json +0 -59
  13. package/.aiready/aiready-report-20260319-201106.json +0 -5566
  14. package/.aiready/aiready-report-20260319-201511.json +0 -5566
  15. package/.aiready/aiready-report-20260319-202017.json +0 -5708
  16. package/.github/FUNDING.yml +0 -5
  17. package/.turbo/turbo-build.log +0 -29
  18. package/.turbo/turbo-lint.log +0 -0
  19. package/.turbo/turbo-test.log +0 -76
  20. package/aiready-report.json +0 -30703
  21. package/coverage/base.css +0 -224
  22. package/coverage/block-navigation.js +0 -87
  23. package/coverage/clover.xml +0 -865
  24. package/coverage/coverage-final.json +0 -15
  25. package/coverage/favicon.png +0 -0
  26. package/coverage/index.html +0 -146
  27. package/coverage/prettify.css +0 -1
  28. package/coverage/prettify.js +0 -2
  29. package/coverage/sort-arrow-sprite.png +0 -0
  30. package/coverage/sorter.js +0 -210
  31. package/coverage/src/commands/agent-grounding.ts.html +0 -271
  32. package/coverage/src/commands/ai-signal-clarity.ts.html +0 -253
  33. package/coverage/src/commands/change-amplification.ts.html +0 -94
  34. package/coverage/src/commands/consistency.ts.html +0 -781
  35. package/coverage/src/commands/context.ts.html +0 -871
  36. package/coverage/src/commands/deps-health.ts.html +0 -280
  37. package/coverage/src/commands/doc-drift.ts.html +0 -271
  38. package/coverage/src/commands/index.html +0 -281
  39. package/coverage/src/commands/patterns.ts.html +0 -745
  40. package/coverage/src/commands/scan.ts.html +0 -1393
  41. package/coverage/src/commands/testability.ts.html +0 -304
  42. package/coverage/src/commands/upload.ts.html +0 -466
  43. package/coverage/src/commands/visualize.ts.html +0 -1027
  44. package/coverage/src/index.html +0 -116
  45. package/coverage/src/index.ts.html +0 -1372
  46. package/coverage/src/utils/helpers.ts.html +0 -559
  47. package/coverage/src/utils/index.html +0 -116
  48. package/docs/SPOKE_GUIDE.md +0 -184
  49. package/packages/core/src/.aiready/aiready-report-20260314-161145.json +0 -224
  50. package/packages/core/src/.aiready/aiready-report-20260314-161152.json +0 -235
  51. package/packages/pattern-detect/src/.aiready/aiready-report-20260314-161139.json +0 -224
  52. package/src/.aiready/aiready-report-20260312-103623.json +0 -32574
  53. package/src/.aiready/aiready-report-20260312-110843.json +0 -28740
  54. package/src/.aiready/aiready-report-20260312-110955.json +0 -28740
  55. package/src/.aiready/aiready-report-20260314-203209.json +0 -30713
  56. package/src/.aiready/aiready-report-20260314-203736.json +0 -30713
  57. package/src/.aiready/aiready-report-20260314-203857.json +0 -30713
  58. package/src/.aiready/aiready-report-20260314-204047.json +0 -30713
  59. package/src/.aiready/aiready-report-20260318-002110.json +0 -28782
  60. package/src/__tests__/cli.test.ts +0 -85
  61. package/src/__tests__/config-shape.test.ts +0 -105
  62. package/src/__tests__/unified.test.ts +0 -95
  63. package/src/cli.ts +0 -333
  64. package/src/commands/__tests__/agent-grounding.test.ts +0 -24
  65. package/src/commands/__tests__/ai-signal-clarity.test.ts +0 -32
  66. package/src/commands/__tests__/consistency.test.ts +0 -100
  67. package/src/commands/__tests__/deps-health.test.ts +0 -26
  68. package/src/commands/__tests__/doc-drift.test.ts +0 -26
  69. package/src/commands/__tests__/extra-commands.test.ts +0 -168
  70. package/src/commands/__tests__/init.test.ts +0 -51
  71. package/src/commands/__tests__/scan.test.ts +0 -153
  72. package/src/commands/__tests__/testability.test.ts +0 -36
  73. package/src/commands/__tests__/upload.test.ts +0 -50
  74. package/src/commands/__tests__/visualize.test.ts +0 -78
  75. package/src/commands/agent-grounding.ts +0 -62
  76. package/src/commands/ai-signal-clarity.ts +0 -1
  77. package/src/commands/bug.ts +0 -99
  78. package/src/commands/change-amplification.ts +0 -3
  79. package/src/commands/consistency.ts +0 -232
  80. package/src/commands/context.ts +0 -262
  81. package/src/commands/deps-health.ts +0 -1
  82. package/src/commands/doc-drift.ts +0 -1
  83. package/src/commands/index.ts +0 -20
  84. package/src/commands/init.ts +0 -199
  85. package/src/commands/patterns.ts +0 -222
  86. package/src/commands/report-formatter.ts +0 -267
  87. package/src/commands/scan.ts +0 -432
  88. package/src/commands/shared/configured-tool-action.ts +0 -35
  89. package/src/commands/shared/standard-tool-actions.ts +0 -126
  90. package/src/commands/testability.ts +0 -73
  91. package/src/commands/upload.ts +0 -129
  92. package/src/commands/visualize.ts +0 -321
  93. package/src/index.ts +0 -465
  94. package/src/utils/__tests__/helpers.test.ts +0 -35
  95. package/src/utils/helpers.ts +0 -234
  96. package/tsconfig.json +0 -11
  97. package/tsconfig.tsbuildinfo +0 -1
  98. package/vitest.config.ts +0 -13
@@ -1,85 +0,0 @@
1
- import { describe, it, expect, beforeEach, afterEach } from 'vitest';
2
- import { analyzeUnified } from '../index';
3
- import { ToolRegistry, ToolName, SpokeOutputSchema } from '@aiready/core';
4
-
5
- describe('CLI Unified Analysis', () => {
6
- beforeEach(() => {
7
- ToolRegistry.clear();
8
-
9
- // Register mock providers
10
- ToolRegistry.register({
11
- id: ToolName.PatternDetect,
12
- alias: ['patterns'],
13
- analyze: async () =>
14
- SpokeOutputSchema.parse({
15
- results: [],
16
- summary: {},
17
- metadata: { toolName: ToolName.PatternDetect, version: '1.0.0' },
18
- }),
19
- score: () => ({
20
- toolName: ToolName.PatternDetect,
21
- score: 80,
22
- factors: [],
23
- recommendations: [],
24
- rawMetrics: {},
25
- }),
26
- defaultWeight: 10,
27
- });
28
-
29
- ToolRegistry.register({
30
- id: ToolName.ContextAnalyzer,
31
- alias: ['context'],
32
- analyze: async () =>
33
- SpokeOutputSchema.parse({
34
- results: [],
35
- summary: {},
36
- metadata: { toolName: ToolName.ContextAnalyzer, version: '1.0.0' },
37
- }),
38
- score: () => ({
39
- toolName: ToolName.ContextAnalyzer,
40
- score: 70,
41
- factors: [],
42
- recommendations: [],
43
- rawMetrics: {},
44
- }),
45
- defaultWeight: 10,
46
- });
47
- });
48
-
49
- afterEach(() => {
50
- ToolRegistry.clear();
51
- });
52
-
53
- it('should run unified analysis with both tools', async () => {
54
- const results = await analyzeUnified({
55
- rootDir: '/test',
56
- tools: ['patterns', 'context'],
57
- });
58
-
59
- expect(results).toHaveProperty(ToolName.PatternDetect);
60
- expect(results).toHaveProperty(ToolName.ContextAnalyzer);
61
- expect(results).toHaveProperty('summary');
62
- });
63
-
64
- it('should run analysis with only patterns tool', async () => {
65
- const results = await analyzeUnified({
66
- rootDir: '/test',
67
- tools: ['patterns'],
68
- });
69
-
70
- expect(results).toHaveProperty(ToolName.PatternDetect);
71
- expect(results).not.toHaveProperty(ToolName.ContextAnalyzer);
72
- expect(results).toHaveProperty('summary');
73
- });
74
-
75
- it('should run analysis with only context tool', async () => {
76
- const results = await analyzeUnified({
77
- rootDir: '/test',
78
- tools: ['context'],
79
- });
80
-
81
- expect(results).not.toHaveProperty(ToolName.PatternDetect);
82
- expect(results).toHaveProperty(ToolName.ContextAnalyzer);
83
- expect(results).toHaveProperty('summary');
84
- });
85
- });
@@ -1,105 +0,0 @@
1
- import { describe, it, expect, beforeEach, afterEach } from 'vitest';
2
- import { analyzeUnified } from '../index';
3
- import { ToolRegistry, ToolName, SpokeOutputSchema } from '@aiready/core';
4
-
5
- describe('CLI Configuration Shape', () => {
6
- beforeEach(() => {
7
- ToolRegistry.clear();
8
-
9
- // Register a mock provider that returns its input config in metadata
10
- ToolRegistry.register({
11
- id: ToolName.PatternDetect,
12
- alias: ['patterns'],
13
- analyze: async (options) =>
14
- SpokeOutputSchema.parse({
15
- results: [],
16
- summary: { config: options },
17
- metadata: {
18
- toolName: ToolName.PatternDetect,
19
- version: '1.0.0',
20
- config: options,
21
- },
22
- }),
23
- score: () => ({
24
- toolName: ToolName.PatternDetect,
25
- score: 80,
26
- factors: [],
27
- recommendations: [],
28
- rawMetrics: {},
29
- }),
30
- defaultWeight: 10,
31
- });
32
- });
33
-
34
- afterEach(() => {
35
- ToolRegistry.clear();
36
- });
37
-
38
- it('should generate a strictly portable AIReadyConfig in summary', async () => {
39
- const results = await analyzeUnified({
40
- rootDir: '/tmp/fake-repo',
41
- tools: [ToolName.PatternDetect],
42
- exclude: ['**/node_modules/**'],
43
- // Pass a tool-specific override
44
- toolConfigs: {
45
- [ToolName.PatternDetect]: {
46
- minSimilarity: 0.9,
47
- // This should be stripped
48
- rootDir: '/tmp/fake-repo',
49
- },
50
- },
51
- });
52
-
53
- const config = results.summary.config;
54
-
55
- // 1. Check top-level structure
56
- expect(config).toHaveProperty('scan');
57
- expect(config).toHaveProperty('tools');
58
-
59
- // 2. Ensure rootDir is STRIPPED from top level
60
- expect(config).not.toHaveProperty('rootDir');
61
-
62
- // 3. Ensure internal keys are stripped from scan section
63
- expect(config.scan).toHaveProperty('tools');
64
- expect(config.scan).toHaveProperty('exclude');
65
- expect(config.scan).not.toHaveProperty('rootDir');
66
-
67
- // 4. Ensure recursive stripping in tools section
68
- const patternConfig = config.tools[ToolName.PatternDetect];
69
- expect(patternConfig).toHaveProperty('minSimilarity', 0.9);
70
- expect(patternConfig).not.toHaveProperty('rootDir');
71
- expect(patternConfig).not.toHaveProperty('onProgress');
72
- });
73
-
74
- it('should strip internal keys like useSmartDefaults and batchSize', async () => {
75
- const results = await analyzeUnified({
76
- rootDir: '/test',
77
- tools: [ToolName.PatternDetect],
78
- useSmartDefaults: true,
79
- batchSize: 50,
80
- });
81
-
82
- const config = results.summary.config;
83
-
84
- expect(config).not.toHaveProperty('useSmartDefaults');
85
- expect(config.scan).not.toHaveProperty('useSmartDefaults');
86
-
87
- // Check tool level too
88
- const patternConfig = config.tools[ToolName.PatternDetect];
89
- expect(patternConfig).not.toHaveProperty('useSmartDefaults');
90
- expect(patternConfig).not.toHaveProperty('batchSize');
91
- });
92
-
93
- it('should produce a config that is compatible with tool specific collection', async () => {
94
- // This test ensures that the toolConfigs collected from individual tools
95
- // are also sanitized before being merged into the final report.
96
- const results = await analyzeUnified({
97
- rootDir: '/test',
98
- tools: [ToolName.PatternDetect],
99
- });
100
-
101
- const toolConfigs = results.summary.toolConfigs;
102
- expect(toolConfigs).toBeDefined();
103
- expect(toolConfigs![ToolName.PatternDetect]).not.toHaveProperty('rootDir');
104
- });
105
- });
@@ -1,95 +0,0 @@
1
- import { describe, it, expect, vi, beforeEach } from 'vitest';
2
- import { analyzeUnified, scoreUnified, generateUnifiedSummary } from '../index';
3
- import { ToolRegistry } from '@aiready/core';
4
-
5
- vi.mock('@aiready/core', async () => {
6
- const actual = await vi.importActual('@aiready/core');
7
- return {
8
- ...actual,
9
- initializeParsers: vi.fn().mockResolvedValue(undefined),
10
- calculateOverallScore: vi
11
- .fn()
12
- .mockReturnValue({ overall: 85, breakdown: [] }),
13
- calculateTokenBudget: vi.fn().mockReturnValue({}),
14
- };
15
- });
16
-
17
- describe('Unified CLI logic', () => {
18
- beforeEach(() => {
19
- vi.clearAllMocks();
20
- });
21
-
22
- describe('analyzeUnified', () => {
23
- it('should run multiple tools and aggregate results', async () => {
24
- const mockProvider1 = {
25
- id: 'tool1',
26
- analyze: vi.fn().mockResolvedValue({
27
- results: [{ fileName: 'f1.ts', issues: [{}, {}] }],
28
- summary: { totalFiles: 1 },
29
- }),
30
- score: vi.fn(),
31
- };
32
-
33
- vi.spyOn(ToolRegistry, 'find').mockImplementation((id) => {
34
- if (id === 'tool1') return mockProvider1 as any;
35
- return null;
36
- });
37
-
38
- const options = {
39
- rootDir: '.',
40
- tools: ['tool1'],
41
- };
42
-
43
- const result = await analyzeUnified(options as any);
44
- expect(result.summary.totalIssues).toBe(2);
45
- expect(result.summary.toolsRun).toContain('tool1');
46
- });
47
- });
48
-
49
- describe('scoreUnified', () => {
50
- it('should score results from multiple tools', async () => {
51
- const mockProvider = {
52
- id: 'tool1',
53
- score: vi.fn().mockReturnValue({ score: 80 }),
54
- };
55
- vi.spyOn(ToolRegistry, 'get').mockReturnValue(mockProvider as any);
56
-
57
- const results = {
58
- summary: { toolsRun: ['tool1'] },
59
- tool1: { results: [] },
60
- };
61
-
62
- const score = await scoreUnified(results as any, { rootDir: '.' } as any);
63
- expect(score.overall).toBe(85); // From mocked calculateOverallScore
64
- expect(mockProvider.score).toHaveBeenCalled();
65
- });
66
-
67
- it('should handle empty tools', async () => {
68
- const results = { summary: { toolsRun: [] } };
69
- const score = await scoreUnified(results as any, { rootDir: '.' } as any);
70
- expect(score.overall).toBe(0);
71
- });
72
- });
73
-
74
- describe('generateUnifiedSummary', () => {
75
- it('should generate human-readable summary', () => {
76
- const result = {
77
- summary: {
78
- toolsRun: ['tool1'],
79
- totalIssues: 5,
80
- executionTime: 1200,
81
- },
82
- tool1: { results: [{ issues: [{}, {}] }] },
83
- };
84
-
85
- vi.spyOn(ToolRegistry, 'getAll').mockReturnValue([
86
- { id: 'tool1' },
87
- ] as any);
88
-
89
- const summary = generateUnifiedSummary(result as any);
90
- expect(summary).toContain('AIReady Analysis Complete');
91
- expect(summary).toContain('Total issues found: 5');
92
- expect(summary).toContain('1.20s');
93
- });
94
- });
95
- });
package/src/cli.ts DELETED
@@ -1,333 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- import { Command } from 'commander';
4
- import { readFileSync } from 'fs';
5
- import { join, dirname } from 'path';
6
- import { fileURLToPath } from 'url';
7
-
8
- import {
9
- scanAction,
10
- scanHelpText,
11
- initAction,
12
- patternsAction,
13
- patternsHelpText,
14
- contextAction,
15
- consistencyAction,
16
- visualizeAction,
17
- visualizeHelpText,
18
- visualiseHelpText,
19
- changeAmplificationAction,
20
- testabilityAction,
21
- uploadAction,
22
- uploadHelpText,
23
- bugAction,
24
- bugHelpText,
25
- } from './commands';
26
-
27
- const getDirname = () => {
28
- if (typeof __dirname !== 'undefined') return __dirname;
29
- return dirname(fileURLToPath(import.meta.url));
30
- };
31
-
32
- const packageJson = JSON.parse(
33
- readFileSync(join(getDirname(), '../package.json'), 'utf8')
34
- );
35
-
36
- const program = new Command();
37
-
38
- program
39
- .name('aiready')
40
- .description('AIReady - Assess and improve AI-readiness of codebases')
41
- .version(packageJson.version)
42
- .addHelpText(
43
- 'after',
44
- `
45
- AI READINESS SCORING:
46
- Get a 0-100 score indicating how AI-ready your codebase is.
47
- Use --score flag with any analysis command for detailed breakdown.
48
-
49
- EXAMPLES:
50
- $ aiready scan # Comprehensive analysis with AI Readiness Score
51
- $ aiready scan --no-score # Run scan without score calculation
52
- $ aiready init # Create a default aiready.json configuration
53
- $ aiready init --full # Create configuration with ALL available options
54
- $ npx @aiready/cli scan # Industry standard way to run standard scan
55
- $ aiready scan --output json # Output raw JSON for piping
56
-
57
- GETTING STARTED:
58
- 1. Run 'aiready init' to create a persistent 'aiready.json' config file
59
- 2. Run 'aiready scan' to analyze your codebase and get an AI Readiness Score
60
- 3. Use 'aiready init --full' to see every fine-tuning parameter available
61
- 4. Use '--profile agentic' for agent-focused analysis
62
- 5. Set up CI/CD with '--threshold' for quality gates
63
-
64
- CONFIGURATION:
65
- Config files (searched upward): aiready.json, .aiready.json, aiready.config.*
66
- CLI options override config file settings
67
-
68
- Example aiready.json:
69
- {
70
- "scan": { "exclude": ["**/dist/**", "**/node_modules/**"] },
71
- "tools": {
72
- "pattern-detect": { "minSimilarity": 0.5 },
73
- "context-analyzer": { "maxContextBudget": 15000 }
74
- },
75
- "output": { "format": "json", "directory": ".aiready" }
76
- }
77
-
78
- VERSION: ${packageJson.version}
79
- DOCUMENTATION: https://aiready.dev/docs/cli
80
- GITHUB: https://github.com/caopengau/aiready-cli
81
- LANDING: https://github.com/caopengau/aiready-landing`
82
- );
83
-
84
- // Scan command - Run comprehensive AI-readiness analysis
85
- program
86
- .command('scan')
87
- .description(
88
- 'Run comprehensive AI-readiness analysis (patterns + context + consistency)'
89
- )
90
- .argument('[directory]', 'Directory to analyze', '.')
91
- .option(
92
- '-t, --tools <tools>',
93
- 'Tools to run (comma-separated: patterns,context,consistency,doc-drift,deps-health,aiSignalClarity,grounding,testability,changeAmplification)'
94
- )
95
- .option(
96
- '--profile <type>',
97
- 'Scan profile to use (agentic, cost, logic, ui, security, onboarding)'
98
- )
99
- .option(
100
- '--compare-to <path>',
101
- 'Compare results against a previous AIReady report JSON'
102
- )
103
- .option('--include <patterns>', 'File patterns to include (comma-separated)')
104
- .option('--exclude <patterns>', 'File patterns to exclude (comma-separated)')
105
- .option('-o, --output <format>', 'Output format: console, json', 'console')
106
- .option('--output-file <path>', 'Output file path (for json)')
107
- .option('--score', 'Calculate and display AI Readiness Score (0-100)', true)
108
- .option('--no-score', 'Disable calculating AI Readiness Score')
109
- .option('--weights <weights>', 'Custom scoring weights')
110
- .option('--threshold <score>', 'Fail CI/CD if score below threshold (0-100)')
111
- .option(
112
- '--ci',
113
- 'CI mode: GitHub Actions annotations, no colors, fail on threshold'
114
- )
115
- .option(
116
- '--fail-on <level>',
117
- 'Fail on issues: critical, major, any',
118
- 'critical'
119
- )
120
- .option('--api-key <key>', 'Platform API key for automatic upload')
121
- .option('--upload', 'Automatically upload results to the platform')
122
- .option('--server <url>', 'Custom platform URL')
123
- .addHelpText('after', scanHelpText)
124
- .action(async (directory, options) => {
125
- await scanAction(directory, options);
126
- });
127
-
128
- // Init command - Generate default configuration
129
- program
130
- .command('init')
131
- .description('Generate a default configuration (aiready.json)')
132
- .option('-f, --force', 'Overwrite existing configuration file')
133
- .option(
134
- '--js',
135
- 'Generate configuration as a JavaScript file (aiready.config.js)'
136
- )
137
- .option('--full', 'Generate a full configuration with all available options')
138
- .action(async (options) => {
139
- const format = options.js ? 'js' : 'json';
140
- await initAction({ force: options.force, format, full: options.full });
141
- });
142
-
143
- // Patterns command - Detect duplicate code patterns
144
- program
145
- .command('patterns')
146
- .description('Detect duplicate code patterns that confuse AI models')
147
- .argument('[directory]', 'Directory to analyze', '.')
148
- .option('-s, --similarity <number>', 'Minimum similarity score (0-1)', '0.40')
149
- .option('-l, --min-lines <number>', 'Minimum lines to consider', '5')
150
- .option(
151
- '--max-candidates <number>',
152
- 'Maximum candidates per block (performance tuning)'
153
- )
154
- .option(
155
- '--min-shared-tokens <number>',
156
- 'Minimum shared tokens for candidates (performance tuning)'
157
- )
158
- .option(
159
- '--full-scan',
160
- 'Disable smart defaults for comprehensive analysis (slower)'
161
- )
162
- .option('--include <patterns>', 'File patterns to include (comma-separated)')
163
- .option('--exclude <patterns>', 'File patterns to exclude (comma-separated)')
164
- .option('-o, --output <format>', 'Output format: console, json', 'console')
165
- .option('--output-file <path>', 'Output file path (for json)')
166
- .option('--score', 'Calculate and display AI Readiness Score (0-100)', true)
167
- .option('--no-score', 'Disable calculating AI Readiness Score')
168
- .addHelpText('after', patternsHelpText)
169
- .action(async (directory, options) => {
170
- await patternsAction(directory, options);
171
- });
172
-
173
- // Context command - Analyze context window costs
174
- program
175
- .command('context')
176
- .description('Analyze context window costs and dependency fragmentation')
177
- .argument('[directory]', 'Directory to analyze', '.')
178
- .option('--max-depth <number>', 'Maximum acceptable import depth', '5')
179
- .option(
180
- '--max-context <number>',
181
- 'Maximum acceptable context budget (tokens)',
182
- '10000'
183
- )
184
- .option('--include <patterns>', 'File patterns to include (comma-separated)')
185
- .option('--exclude <patterns>', 'File patterns to exclude (comma-separated)')
186
- .option('-o, --output <format>', 'Output format: console, json', 'console')
187
- .option('--output-file <path>', 'Output file path (for json)')
188
- .option('--score', 'Calculate and display AI Readiness Score (0-100)', true)
189
- .option('--no-score', 'Disable calculating AI Readiness Score')
190
- .action(async (directory, options) => {
191
- await contextAction(directory, options);
192
- });
193
-
194
- // Consistency command - Check naming conventions
195
- program
196
- .command('consistency')
197
- .description('Check naming conventions and architectural consistency')
198
- .argument('[directory]', 'Directory to analyze', '.')
199
- .option('--naming', 'Check naming conventions (default: true)')
200
- .option('--no-naming', 'Skip naming analysis')
201
- .option('--patterns', 'Check code patterns (default: true)')
202
- .option('--no-patterns', 'Skip pattern analysis')
203
- .option(
204
- '--min-severity <level>',
205
- 'Minimum severity: info|minor|major|critical',
206
- 'info'
207
- )
208
- .option('--include <patterns>', 'File patterns to include (comma-separated)')
209
- .option('--exclude <patterns>', 'File patterns to exclude (comma-separated)')
210
- .option(
211
- '-o, --output <format>',
212
- 'Output format: console, json, markdown',
213
- 'console'
214
- )
215
- .option('--output-file <path>', 'Output file path (for json/markdown)')
216
- .option('--score', 'Calculate and display AI Readiness Score (0-100)', true)
217
- .option('--no-score', 'Disable calculating AI Readiness Score')
218
- .action(async (directory, options) => {
219
- await consistencyAction(directory, options);
220
- });
221
-
222
- // Visualise command (British spelling alias)
223
- program
224
- .command('visualise')
225
- .description('Alias for visualize (British spelling)')
226
- .argument('[directory]', 'Directory to analyze', '.')
227
- .option(
228
- '--report <path>',
229
- 'Report path (auto-detects latest .aiready/aiready-report-*.json if not provided)'
230
- )
231
- .option(
232
- '-o, --output <path>',
233
- 'Output HTML path (relative to directory)',
234
- 'packages/visualizer/visualization.html'
235
- )
236
- .option('--open', 'Open generated HTML in default browser')
237
- .option(
238
- '--serve [port]',
239
- 'Start a local static server to serve the visualization (optional port number)',
240
- false
241
- )
242
- .option(
243
- '--dev',
244
- 'Start Vite dev server (live reload) for interactive development',
245
- true
246
- )
247
- .addHelpText('after', visualiseHelpText)
248
- .action(async (directory, options) => {
249
- await visualizeAction(directory, options);
250
- });
251
-
252
- // Visualize command - Generate interactive visualization
253
- program
254
- .command('visualize')
255
- .description('Generate interactive visualization from an AIReady report')
256
- .argument('[directory]', 'Directory to analyze', '.')
257
- .option(
258
- '--report <path>',
259
- 'Report path (auto-detects latest .aiready/aiready-report-*.json if not provided)'
260
- )
261
- .option(
262
- '-o, --output <path>',
263
- 'Output HTML path (relative to directory)',
264
- 'packages/visualizer/visualization.html'
265
- )
266
- .option('--open', 'Open generated HTML in default browser')
267
- .option(
268
- '--serve [port]',
269
- 'Start a local static server to serve the visualization (optional port number)',
270
- false
271
- )
272
- .option(
273
- '--dev',
274
- 'Start Vite dev server (live reload) for interactive development',
275
- false
276
- )
277
- .addHelpText('after', visualizeHelpText)
278
- .action(async (directory, options) => {
279
- await visualizeAction(directory, options);
280
- });
281
-
282
- // Change Amplification command
283
- program
284
- .command('change-amplification')
285
- .description('Analyze graph metrics for change amplification')
286
- .argument('[directory]', 'Directory to analyze', '.')
287
- .option('--include <patterns>', 'File patterns to include (comma-separated)')
288
- .option('--exclude <patterns>', 'File patterns to exclude (comma-separated)')
289
- .option('-o, --output <format>', 'Output format: console, json', 'console')
290
- .option('--output-file <path>', 'Output file path (for json)')
291
- .action(async (directory, options) => {
292
- await changeAmplificationAction(directory, options);
293
- });
294
-
295
- // Testability command
296
- program
297
- .command('testability')
298
- .description('Analyze test coverage and AI readiness')
299
- .argument('[directory]', 'Directory to analyze', '.')
300
- .option('--min-coverage <ratio>', 'Minimum acceptable coverage ratio', '0.3')
301
- .option('--include <patterns>', 'File patterns to include (comma-separated)')
302
- .option('--exclude <patterns>', 'File patterns to exclude (comma-separated)')
303
- .option('-o, --output <format>', 'Output format: console, json', 'console')
304
- .option('--output-file <path>', 'Output file path (for json)')
305
- .action(async (directory, options) => {
306
- await testabilityAction(directory, options);
307
- });
308
-
309
- // Upload command - Upload report JSON to platform
310
- program
311
- .command('upload')
312
- .description('Upload an AIReady report JSON to the platform')
313
- .argument('<file>', 'Report JSON file to upload')
314
- .option('--api-key <key>', 'Platform API key')
315
- .option('--repo-id <id>', 'Platform repository ID (optional)')
316
- .option('--server <url>', 'Custom platform URL')
317
- .addHelpText('after', uploadHelpText)
318
- .action(async (file, options) => {
319
- await uploadAction(file, options);
320
- });
321
-
322
- program
323
- .command('bug')
324
- .description('Report a bug or provide feedback (Agent-friendly)')
325
- .argument('[message]', 'Short description of the issue')
326
- .option('-t, --type <type>', 'Issue type: bug, feature, metric', 'bug')
327
- .option('--submit', 'Submit the issue directly using the GitHub CLI (gh)')
328
- .addHelpText('after', bugHelpText)
329
- .action(async (message, options) => {
330
- await bugAction(message, options);
331
- });
332
-
333
- program.parse();
@@ -1,24 +0,0 @@
1
- import { describe, it, expect, vi } from 'vitest';
2
- import { agentGroundingAction } from '../agent-grounding';
3
-
4
- vi.mock('@aiready/agent-grounding', () => ({
5
- analyzeAgentGrounding: vi.fn().mockResolvedValue({
6
- summary: { score: 75, rating: 'good', dimensions: { apiClarityScore: 60 } },
7
- results: [],
8
- }),
9
- calculateGroundingScore: vi.fn().mockReturnValue({ score: 75 }),
10
- }));
11
-
12
- vi.mock('@aiready/core', () => ({
13
- loadConfig: vi.fn().mockResolvedValue({}),
14
- mergeConfigWithDefaults: vi
15
- .fn()
16
- .mockImplementation((c, d) => ({ ...d, ...c })),
17
- }));
18
-
19
- describe('Agent Grounding CLI Action', () => {
20
- it('should run analysis and return scoring', async () => {
21
- const result = await agentGroundingAction('.', { output: 'json' });
22
- expect(result?.score).toBe(75);
23
- });
24
- });
@@ -1,32 +0,0 @@
1
- import { describe, it, expect, vi } from 'vitest';
2
- import { aiSignalClarityAction } from '../ai-signal-clarity';
3
-
4
- vi.mock('@aiready/ai-signal-clarity', () => ({
5
- analyzeAiSignalClarity: vi.fn().mockResolvedValue({
6
- summary: {
7
- score: 85,
8
- rating: 'low',
9
- topRisk: 'none',
10
- totalSignals: 0,
11
- criticalSignals: 0,
12
- majorSignals: 0,
13
- minorSignals: 0,
14
- },
15
- results: [],
16
- }),
17
- calculateAiSignalClarityScore: vi.fn().mockReturnValue({ score: 85 }),
18
- }));
19
-
20
- vi.mock('@aiready/core', () => ({
21
- loadConfig: vi.fn().mockResolvedValue({}),
22
- mergeConfigWithDefaults: vi
23
- .fn()
24
- .mockImplementation((c, d) => ({ ...d, ...c })),
25
- }));
26
-
27
- describe('AI Signal Clarity CLI Action', () => {
28
- it('should run analysis and return scoring', async () => {
29
- const result = await aiSignalClarityAction('.', { output: 'json' });
30
- expect(result?.score).toBe(85);
31
- });
32
- });