ally-a11y 1.0.0

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 (84) hide show
  1. package/ACCESSIBILITY.md +205 -0
  2. package/LICENSE +21 -0
  3. package/README.md +940 -0
  4. package/dist/cli.d.ts +7 -0
  5. package/dist/cli.js +528 -0
  6. package/dist/commands/audit-palette.d.ts +18 -0
  7. package/dist/commands/audit-palette.js +613 -0
  8. package/dist/commands/auto-pr.d.ts +19 -0
  9. package/dist/commands/auto-pr.js +434 -0
  10. package/dist/commands/badge.d.ts +11 -0
  11. package/dist/commands/badge.js +143 -0
  12. package/dist/commands/completion.d.ts +4 -0
  13. package/dist/commands/completion.js +185 -0
  14. package/dist/commands/crawl.d.ts +12 -0
  15. package/dist/commands/crawl.js +249 -0
  16. package/dist/commands/doctor.d.ts +5 -0
  17. package/dist/commands/doctor.js +233 -0
  18. package/dist/commands/explain.d.ts +12 -0
  19. package/dist/commands/explain.js +233 -0
  20. package/dist/commands/fix.d.ts +13 -0
  21. package/dist/commands/fix.js +668 -0
  22. package/dist/commands/health.d.ts +11 -0
  23. package/dist/commands/health.js +367 -0
  24. package/dist/commands/history.d.ts +10 -0
  25. package/dist/commands/history.js +191 -0
  26. package/dist/commands/init.d.ts +9 -0
  27. package/dist/commands/init.js +164 -0
  28. package/dist/commands/learn.d.ts +8 -0
  29. package/dist/commands/learn.js +592 -0
  30. package/dist/commands/pr-check.d.ts +12 -0
  31. package/dist/commands/pr-check.js +270 -0
  32. package/dist/commands/report.d.ts +11 -0
  33. package/dist/commands/report.js +375 -0
  34. package/dist/commands/scan-storybook.d.ts +18 -0
  35. package/dist/commands/scan-storybook.js +402 -0
  36. package/dist/commands/scan.d.ts +25 -0
  37. package/dist/commands/scan.js +673 -0
  38. package/dist/commands/stats.d.ts +5 -0
  39. package/dist/commands/stats.js +137 -0
  40. package/dist/commands/tree.d.ts +12 -0
  41. package/dist/commands/tree.js +635 -0
  42. package/dist/commands/triage.d.ts +13 -0
  43. package/dist/commands/triage.js +327 -0
  44. package/dist/commands/watch.d.ts +17 -0
  45. package/dist/commands/watch.js +302 -0
  46. package/dist/types/index.d.ts +60 -0
  47. package/dist/types/index.js +4 -0
  48. package/dist/utils/baseline.d.ts +62 -0
  49. package/dist/utils/baseline.js +169 -0
  50. package/dist/utils/browser.d.ts +78 -0
  51. package/dist/utils/browser.js +239 -0
  52. package/dist/utils/cache.d.ts +76 -0
  53. package/dist/utils/cache.js +178 -0
  54. package/dist/utils/config.d.ts +102 -0
  55. package/dist/utils/config.js +237 -0
  56. package/dist/utils/converters.d.ts +77 -0
  57. package/dist/utils/converters.js +200 -0
  58. package/dist/utils/copilot.d.ts +36 -0
  59. package/dist/utils/copilot.js +139 -0
  60. package/dist/utils/detect.d.ts +22 -0
  61. package/dist/utils/detect.js +197 -0
  62. package/dist/utils/enhanced-errors.d.ts +46 -0
  63. package/dist/utils/enhanced-errors.js +295 -0
  64. package/dist/utils/errors.d.ts +31 -0
  65. package/dist/utils/errors.js +149 -0
  66. package/dist/utils/fix-patterns.d.ts +56 -0
  67. package/dist/utils/fix-patterns.js +529 -0
  68. package/dist/utils/history-tracking.d.ts +94 -0
  69. package/dist/utils/history-tracking.js +230 -0
  70. package/dist/utils/history.d.ts +42 -0
  71. package/dist/utils/history.js +255 -0
  72. package/dist/utils/impact-scores.d.ts +44 -0
  73. package/dist/utils/impact-scores.js +257 -0
  74. package/dist/utils/retry.d.ts +24 -0
  75. package/dist/utils/retry.js +76 -0
  76. package/dist/utils/scanner.d.ts +74 -0
  77. package/dist/utils/scanner.js +606 -0
  78. package/dist/utils/scanner.test.d.ts +4 -0
  79. package/dist/utils/scanner.test.js +162 -0
  80. package/dist/utils/ui.d.ts +44 -0
  81. package/dist/utils/ui.js +276 -0
  82. package/mcp-server/dist/index.d.ts +8 -0
  83. package/mcp-server/dist/index.js +1923 -0
  84. package/package.json +88 -0
@@ -0,0 +1,164 @@
1
+ /**
2
+ * ally init command - Sets up ally configuration in a project
3
+ */
4
+ import { mkdir, writeFile } from 'fs/promises';
5
+ import { existsSync } from 'fs';
6
+ import { join } from 'path';
7
+ import chalk from 'chalk';
8
+ import { printBanner, printSuccess, printInfo, printWarning, } from '../utils/ui.js';
9
+ /**
10
+ * Set up pre-commit hooks for accessibility checks
11
+ */
12
+ async function setupPreCommitHooks(cwd, force, createdFiles) {
13
+ const gitDir = join(cwd, '.git');
14
+ const huskyDir = join(cwd, '.husky');
15
+ // Pre-commit hook script content
16
+ const preCommitScript = `#!/bin/sh
17
+ # Accessibility check - block commits with a11y errors
18
+ npx ally-a11y scan src/ --ci --fail-on error
19
+ `;
20
+ // Pre-commit config YAML content
21
+ const preCommitConfigYaml = `repos:
22
+ - repo: local
23
+ hooks:
24
+ - id: ally-scan
25
+ name: Accessibility Check
26
+ entry: npx ally-a11y scan src/ --ci --fail-on error
27
+ language: system
28
+ types: [html]
29
+ pass_filenames: false
30
+ `;
31
+ // Check if husky is installed (look for .husky directory or package.json reference)
32
+ const hasHusky = existsSync(huskyDir);
33
+ const hasGit = existsSync(gitDir);
34
+ if (hasHusky) {
35
+ // Use husky-style hook
36
+ const huskyPreCommit = join(huskyDir, 'pre-commit');
37
+ if (!existsSync(huskyPreCommit) || force) {
38
+ await writeFile(huskyPreCommit, preCommitScript, { mode: 0o755 });
39
+ printSuccess('Created .husky/pre-commit');
40
+ createdFiles.push('.husky/pre-commit');
41
+ }
42
+ else {
43
+ printWarning('.husky/pre-commit already exists (use --force to overwrite)');
44
+ }
45
+ }
46
+ else if (hasGit) {
47
+ // Use git hooks directly
48
+ const hooksDir = join(gitDir, 'hooks');
49
+ if (!existsSync(hooksDir)) {
50
+ await mkdir(hooksDir, { recursive: true });
51
+ }
52
+ const gitPreCommit = join(hooksDir, 'pre-commit');
53
+ if (!existsSync(gitPreCommit) || force) {
54
+ await writeFile(gitPreCommit, preCommitScript, { mode: 0o755 });
55
+ printSuccess('Created .git/hooks/pre-commit');
56
+ createdFiles.push('.git/hooks/pre-commit');
57
+ }
58
+ else {
59
+ printWarning('.git/hooks/pre-commit already exists (use --force to overwrite)');
60
+ }
61
+ }
62
+ else {
63
+ printWarning('No .git directory found - skipping git hook setup');
64
+ }
65
+ // Always create .pre-commit-config.yaml for the pre-commit framework
66
+ const preCommitConfigPath = join(cwd, '.pre-commit-config.yaml');
67
+ if (!existsSync(preCommitConfigPath) || force) {
68
+ await writeFile(preCommitConfigPath, preCommitConfigYaml);
69
+ printSuccess('Created .pre-commit-config.yaml');
70
+ createdFiles.push('.pre-commit-config.yaml');
71
+ }
72
+ else {
73
+ printWarning('.pre-commit-config.yaml already exists (use --force to overwrite)');
74
+ }
75
+ }
76
+ export async function initCommand(options = {}) {
77
+ printBanner();
78
+ const cwd = process.cwd();
79
+ const { force = false, hooks = false } = options;
80
+ const createdFiles = [];
81
+ console.log(chalk.bold.cyan('Setting up ally in your project...\n'));
82
+ // Create .ally directory
83
+ const allyDir = join(cwd, '.ally');
84
+ if (!existsSync(allyDir)) {
85
+ await mkdir(allyDir, { recursive: true });
86
+ printSuccess('Created .ally/ directory');
87
+ }
88
+ else {
89
+ printInfo('.ally/ directory already exists');
90
+ }
91
+ // Create .copilot directory and MCP config
92
+ const copilotDir = join(cwd, '.copilot');
93
+ const mcpConfigPath = join(copilotDir, 'mcp-config.json');
94
+ if (!existsSync(copilotDir)) {
95
+ await mkdir(copilotDir, { recursive: true });
96
+ }
97
+ if (!existsSync(mcpConfigPath) || force) {
98
+ const mcpConfig = {
99
+ mcpServers: {
100
+ 'ally-patterns': {
101
+ type: 'local',
102
+ command: 'node',
103
+ tools: ['*'],
104
+ args: ['./node_modules/ally-a11y/mcp-server/dist/index.js'],
105
+ env: {},
106
+ },
107
+ },
108
+ };
109
+ await writeFile(mcpConfigPath, JSON.stringify(mcpConfig, null, 2));
110
+ printSuccess('Created .copilot/mcp-config.json');
111
+ }
112
+ else {
113
+ printWarning('.copilot/mcp-config.json already exists (use --force to overwrite)');
114
+ }
115
+ // Set up pre-commit hooks if requested
116
+ if (hooks) {
117
+ await setupPreCommitHooks(cwd, force, createdFiles);
118
+ }
119
+ // Add to .gitignore if it exists
120
+ const gitignorePath = join(cwd, '.gitignore');
121
+ if (existsSync(gitignorePath)) {
122
+ const { readFile } = await import('fs/promises');
123
+ const gitignore = await readFile(gitignorePath, 'utf-8');
124
+ const toAdd = [];
125
+ if (!gitignore.includes('.ally/')) {
126
+ toAdd.push('.ally/');
127
+ }
128
+ if (toAdd.length > 0) {
129
+ const appendContent = '\n# Ally accessibility scanner\n' + toAdd.join('\n') + '\n';
130
+ const { appendFile } = await import('fs/promises');
131
+ await appendFile(gitignorePath, appendContent);
132
+ printSuccess('Updated .gitignore');
133
+ }
134
+ }
135
+ // Summary
136
+ console.log();
137
+ console.log(chalk.bold('Setup complete! Next steps:'));
138
+ console.log();
139
+ console.log(chalk.cyan(' 1. Scan your project:'));
140
+ console.log(chalk.dim(' ally scan ./src'));
141
+ console.log();
142
+ console.log(chalk.cyan(' 2. Understand issues:'));
143
+ console.log(chalk.dim(' ally explain'));
144
+ console.log();
145
+ console.log(chalk.cyan(' 3. Fix with AI assistance:'));
146
+ console.log(chalk.dim(' ally fix'));
147
+ console.log();
148
+ console.log(chalk.cyan(' 4. Generate report:'));
149
+ console.log(chalk.dim(' ally report'));
150
+ console.log();
151
+ // Show hook-specific info if hooks were created
152
+ if (createdFiles.length > 0) {
153
+ console.log(chalk.bold('Pre-commit hooks configured:'));
154
+ for (const file of createdFiles) {
155
+ console.log(chalk.dim(` ${file}`));
156
+ }
157
+ console.log();
158
+ printInfo('Commits will now be checked for accessibility violations');
159
+ }
160
+ printInfo('For AI-powered fixes, install GitHub Copilot CLI:');
161
+ console.log(chalk.dim(' npm install -g @github/copilot-cli'));
162
+ console.log(chalk.dim(' copilot auth login'));
163
+ }
164
+ export default initCommand;
@@ -0,0 +1,8 @@
1
+ /**
2
+ * ally learn command - Educational command that explains WCAG criteria in depth
3
+ */
4
+ interface LearnOptions {
5
+ list?: boolean;
6
+ }
7
+ export declare function learnCommand(violationId?: string, options?: LearnOptions): Promise<void>;
8
+ export default learnCommand;