@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.
Files changed (95) hide show
  1. package/CONTRIBUTING.md +86 -1
  2. package/LICENSE +21 -0
  3. package/package.json +33 -12
  4. package/.aiready/aiready-report-20260227-133806.json +0 -7805
  5. package/.aiready/aiready-report-20260227-133938.json +0 -7951
  6. package/.aiready/aiready-report-20260228-003433.json +0 -7939
  7. package/.aiready/aiready-report-20260228-003613.json +0 -771
  8. package/.aiready/aiready-report-20260314-164626.json +0 -59
  9. package/.aiready/aiready-report-20260314-164741.json +0 -59
  10. package/.aiready/aiready-report-20260319-201106.json +0 -5566
  11. package/.aiready/aiready-report-20260319-201511.json +0 -5566
  12. package/.aiready/aiready-report-20260319-202017.json +0 -5708
  13. package/.github/FUNDING.yml +0 -5
  14. package/.turbo/turbo-build.log +0 -29
  15. package/.turbo/turbo-lint.log +0 -0
  16. package/.turbo/turbo-test.log +0 -76
  17. package/aiready-report.json +0 -30703
  18. package/coverage/base.css +0 -224
  19. package/coverage/block-navigation.js +0 -87
  20. package/coverage/clover.xml +0 -865
  21. package/coverage/coverage-final.json +0 -15
  22. package/coverage/favicon.png +0 -0
  23. package/coverage/index.html +0 -146
  24. package/coverage/prettify.css +0 -1
  25. package/coverage/prettify.js +0 -2
  26. package/coverage/sort-arrow-sprite.png +0 -0
  27. package/coverage/sorter.js +0 -210
  28. package/coverage/src/commands/agent-grounding.ts.html +0 -271
  29. package/coverage/src/commands/ai-signal-clarity.ts.html +0 -253
  30. package/coverage/src/commands/change-amplification.ts.html +0 -94
  31. package/coverage/src/commands/consistency.ts.html +0 -781
  32. package/coverage/src/commands/context.ts.html +0 -871
  33. package/coverage/src/commands/deps-health.ts.html +0 -280
  34. package/coverage/src/commands/doc-drift.ts.html +0 -271
  35. package/coverage/src/commands/index.html +0 -281
  36. package/coverage/src/commands/patterns.ts.html +0 -745
  37. package/coverage/src/commands/scan.ts.html +0 -1393
  38. package/coverage/src/commands/testability.ts.html +0 -304
  39. package/coverage/src/commands/upload.ts.html +0 -466
  40. package/coverage/src/commands/visualize.ts.html +0 -1027
  41. package/coverage/src/index.html +0 -116
  42. package/coverage/src/index.ts.html +0 -1372
  43. package/coverage/src/utils/helpers.ts.html +0 -559
  44. package/coverage/src/utils/index.html +0 -116
  45. package/docs/SPOKE_GUIDE.md +0 -184
  46. package/packages/core/src/.aiready/aiready-report-20260314-161145.json +0 -224
  47. package/packages/core/src/.aiready/aiready-report-20260314-161152.json +0 -235
  48. package/packages/pattern-detect/src/.aiready/aiready-report-20260314-161139.json +0 -224
  49. package/src/.aiready/aiready-report-20260312-103623.json +0 -32574
  50. package/src/.aiready/aiready-report-20260312-110843.json +0 -28740
  51. package/src/.aiready/aiready-report-20260312-110955.json +0 -28740
  52. package/src/.aiready/aiready-report-20260314-203209.json +0 -30713
  53. package/src/.aiready/aiready-report-20260314-203736.json +0 -30713
  54. package/src/.aiready/aiready-report-20260314-203857.json +0 -30713
  55. package/src/.aiready/aiready-report-20260314-204047.json +0 -30713
  56. package/src/.aiready/aiready-report-20260318-002110.json +0 -28782
  57. package/src/__tests__/cli.test.ts +0 -85
  58. package/src/__tests__/config-shape.test.ts +0 -105
  59. package/src/__tests__/unified.test.ts +0 -95
  60. package/src/cli.ts +0 -333
  61. package/src/commands/__tests__/agent-grounding.test.ts +0 -24
  62. package/src/commands/__tests__/ai-signal-clarity.test.ts +0 -32
  63. package/src/commands/__tests__/consistency.test.ts +0 -100
  64. package/src/commands/__tests__/deps-health.test.ts +0 -26
  65. package/src/commands/__tests__/doc-drift.test.ts +0 -26
  66. package/src/commands/__tests__/extra-commands.test.ts +0 -168
  67. package/src/commands/__tests__/init.test.ts +0 -51
  68. package/src/commands/__tests__/scan.test.ts +0 -153
  69. package/src/commands/__tests__/testability.test.ts +0 -36
  70. package/src/commands/__tests__/upload.test.ts +0 -50
  71. package/src/commands/__tests__/visualize.test.ts +0 -78
  72. package/src/commands/agent-grounding.ts +0 -62
  73. package/src/commands/ai-signal-clarity.ts +0 -1
  74. package/src/commands/bug.ts +0 -99
  75. package/src/commands/change-amplification.ts +0 -3
  76. package/src/commands/consistency.ts +0 -232
  77. package/src/commands/context.ts +0 -262
  78. package/src/commands/deps-health.ts +0 -1
  79. package/src/commands/doc-drift.ts +0 -1
  80. package/src/commands/index.ts +0 -20
  81. package/src/commands/init.ts +0 -199
  82. package/src/commands/patterns.ts +0 -222
  83. package/src/commands/report-formatter.ts +0 -267
  84. package/src/commands/scan.ts +0 -432
  85. package/src/commands/shared/configured-tool-action.ts +0 -35
  86. package/src/commands/shared/standard-tool-actions.ts +0 -126
  87. package/src/commands/testability.ts +0 -73
  88. package/src/commands/upload.ts +0 -129
  89. package/src/commands/visualize.ts +0 -321
  90. package/src/index.ts +0 -465
  91. package/src/utils/__tests__/helpers.test.ts +0 -35
  92. package/src/utils/helpers.ts +0 -234
  93. package/tsconfig.json +0 -11
  94. package/tsconfig.tsbuildinfo +0 -1
  95. 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
- });