a11y-devkit-deploy 0.7.0 → 0.7.2
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/README.md +165 -25
- package/config/a11y.json +44 -12
- package/package.json +1 -1
- package/src/cli.js +70 -43
- package/src/paths.js +18 -52
package/README.md
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# A11y Devkit Deploy
|
|
2
2
|
|
|
3
|
-
A **fully config-driven**, cross-platform CLI for deploying accessibility skills and MCP servers across Claude Code, Cursor, Codex, and
|
|
3
|
+
A **fully config-driven**, cross-platform CLI for deploying accessibility skills and MCP servers across multiple IDEs: Claude Code, Cursor, Codex, VSCode, Windsurf, and Factory.
|
|
4
4
|
|
|
5
|
-
**Add new skills
|
|
5
|
+
**Add new skills, MCP servers, or entire IDEs without writing code** - just edit the JSON config and re-run.
|
|
6
6
|
|
|
7
7
|
## Install
|
|
8
8
|
|
|
@@ -27,8 +27,8 @@ a11y-devkit-deploy
|
|
|
27
27
|
|
|
28
28
|
Once installation completes, you'll find a comprehensive usage guide in your IDE's skills directory:
|
|
29
29
|
|
|
30
|
-
- **Local install**: `.claude/skills/README.md` (or `.cursor/skills/`, `.codex/skills/` depending on your IDE)
|
|
31
|
-
- **Global install**: `~/.claude/skills/README.md` (or your IDE's global skills directory)
|
|
30
|
+
- **Local install**: `.claude/skills/a11y/a11y-devkit-README.md` (or `.cursor/skills/a11y/`, `.codex/skills/a11y/` depending on your IDE)
|
|
31
|
+
- **Global install**: `~/.claude/skills/a11y/a11y-devkit-README.md` (or your IDE's global skills directory)
|
|
32
32
|
|
|
33
33
|
### What's in the Guide
|
|
34
34
|
|
|
@@ -42,7 +42,7 @@ The bundled README includes:
|
|
|
42
42
|
|
|
43
43
|
### Preview the Guide
|
|
44
44
|
|
|
45
|
-
You can preview the guide here: [templates/
|
|
45
|
+
You can preview the guide here: [templates/deploy-README.md](templates/deploy-README.md)
|
|
46
46
|
|
|
47
47
|
### Next Steps
|
|
48
48
|
|
|
@@ -75,7 +75,31 @@ This CLI automates the setup of accessibility tooling by:
|
|
|
75
75
|
- **a11y-personas** - Accessibility personas for diverse user needs
|
|
76
76
|
- **arc-issues** - Format AxeCore violations into standardized issue templates
|
|
77
77
|
|
|
78
|
-
**Fully customizable** - add/remove skills
|
|
78
|
+
**Fully customizable** - add/remove skills, MCP servers, or entire IDEs by editing the config file.
|
|
79
|
+
|
|
80
|
+
## Why This Tool?
|
|
81
|
+
|
|
82
|
+
**Zero Hardcoded Values** - Every aspect of the tool is driven by `config/a11y.json`:
|
|
83
|
+
- IDE paths and configuration files
|
|
84
|
+
- Skills to install
|
|
85
|
+
- MCP servers to configure
|
|
86
|
+
- Even the IDE list itself
|
|
87
|
+
|
|
88
|
+
**Adding Support for a New IDE** takes just 5 lines of JSON:
|
|
89
|
+
```json
|
|
90
|
+
{
|
|
91
|
+
"id": "new-ide",
|
|
92
|
+
"displayName": "New IDE",
|
|
93
|
+
"mcpServerKey": "servers",
|
|
94
|
+
"skillsFolder": ".new-ide/skills",
|
|
95
|
+
"mcpConfigFile": ".new-ide/mcp.json"
|
|
96
|
+
}
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
**Safe by Default** - Won't overwrite your existing:
|
|
100
|
+
- Custom MCP servers in your IDE configs
|
|
101
|
+
- Other skills in your skills directories
|
|
102
|
+
- Creates backups if it encounters JSON parsing errors
|
|
79
103
|
|
|
80
104
|
### Skills Installed (Default)
|
|
81
105
|
|
|
@@ -118,9 +142,9 @@ The generated MCP config looks like this:
|
|
|
118
142
|
|
|
119
143
|
## Configuration
|
|
120
144
|
|
|
121
|
-
The entire tool is **fully config-driven**. Edit `config/a11y.json` to customize everything without touching code
|
|
145
|
+
The entire tool is **fully config-driven**. Edit `config/a11y.json` to customize everything without touching code.
|
|
122
146
|
|
|
123
|
-
###
|
|
147
|
+
### Adding a New Skill
|
|
124
148
|
|
|
125
149
|
Simply add an object to the `skills` array with a `name` (npm package) and `description`:
|
|
126
150
|
|
|
@@ -139,7 +163,7 @@ Simply add an object to the `skills` array with a `name` (npm package) and `desc
|
|
|
139
163
|
}
|
|
140
164
|
```
|
|
141
165
|
|
|
142
|
-
###
|
|
166
|
+
### Adding a New MCP Server
|
|
143
167
|
|
|
144
168
|
Add an object to the `mcpServers` array with name, description, command, and args:
|
|
145
169
|
|
|
@@ -162,40 +186,96 @@ Add an object to the `mcpServers` array with name, description, command, and arg
|
|
|
162
186
|
}
|
|
163
187
|
```
|
|
164
188
|
|
|
189
|
+
### Adding a New IDE
|
|
190
|
+
|
|
191
|
+
Add an object to the `ides` array with the IDE's configuration:
|
|
192
|
+
|
|
193
|
+
```json
|
|
194
|
+
{
|
|
195
|
+
"ides": [
|
|
196
|
+
{
|
|
197
|
+
"id": "windsurf",
|
|
198
|
+
"displayName": "Windsurf",
|
|
199
|
+
"mcpServerKey": "servers",
|
|
200
|
+
"skillsFolder": ".codeium/windsurf/skills",
|
|
201
|
+
"mcpConfigFile": ".codeium/windsurf/mcp_config.json"
|
|
202
|
+
}
|
|
203
|
+
]
|
|
204
|
+
}
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
**IDE Configuration Properties:**
|
|
208
|
+
- `id` - Unique identifier for the IDE
|
|
209
|
+
- `displayName` - Human-readable name shown in prompts
|
|
210
|
+
- `mcpServerKey` - MCP config key name (`"servers"` or `"mcpServers"`)
|
|
211
|
+
- `skillsFolder` - Path to skills directory (relative to home/project root)
|
|
212
|
+
- `mcpConfigFile` - Path to MCP config file (relative to home/project root)
|
|
213
|
+
|
|
165
214
|
### Config Structure
|
|
166
215
|
|
|
216
|
+
- `skillsFolder` - Subfolder name to bundle skills under (e.g., "a11y")
|
|
217
|
+
- `readmeTemplate` - README template file to copy into skills directories
|
|
167
218
|
- `skills` - Array of skill objects with `name` (npm package) and `description`
|
|
168
|
-
- `
|
|
169
|
-
- `ideMcpPaths` - IDE-specific MCP config file paths
|
|
219
|
+
- `ides` - Array of IDE configuration objects
|
|
170
220
|
- `mcpServers` - MCP server definitions with name, description, command, and args
|
|
171
221
|
|
|
172
222
|
All changes take effect immediately - just re-run the CLI to deploy your updated config.
|
|
173
223
|
|
|
224
|
+
### Safe Merging
|
|
225
|
+
|
|
226
|
+
The CLI **safely merges** with existing configurations:
|
|
227
|
+
- **MCP configs** - Adds/updates only the specified servers, preserves others
|
|
228
|
+
- **Skills** - Installs only the configured skills, preserves other skills in the directory
|
|
229
|
+
- **Backups** - Creates `.bak` files if JSON parsing fails
|
|
230
|
+
|
|
174
231
|
## Directory Structure
|
|
175
232
|
|
|
176
233
|
### Local Install (Project-Specific)
|
|
177
234
|
```
|
|
178
235
|
your-project/
|
|
179
|
-
├── .claude/
|
|
180
|
-
├── .
|
|
181
|
-
|
|
182
|
-
|
|
236
|
+
├── .claude/
|
|
237
|
+
│ ├── mcp.json # Claude Code MCP config
|
|
238
|
+
│ └── skills/ # Claude Code skills
|
|
239
|
+
├── .cursor/
|
|
240
|
+
│ ├── mcp.json # Cursor MCP config
|
|
241
|
+
│ └── skills/ # Cursor skills
|
|
242
|
+
├── .codex/
|
|
243
|
+
│ ├── mcp.json # Codex MCP config
|
|
244
|
+
│ └── skills/ # Codex skills
|
|
245
|
+
├── .github/
|
|
246
|
+
│ ├── mcp.json # VSCode MCP config
|
|
247
|
+
│ └── skills/ # VSCode skills
|
|
248
|
+
├── .codeium/windsurf/
|
|
249
|
+
│ ├── mcp_config.json # Windsurf MCP config
|
|
250
|
+
│ └── skills/ # Windsurf skills
|
|
251
|
+
└── .factory/
|
|
252
|
+
├── mcp.json # Factory MCP config
|
|
253
|
+
└── skills/ # Factory skills
|
|
183
254
|
```
|
|
184
255
|
|
|
185
256
|
### Global Install (User-Wide)
|
|
186
257
|
```
|
|
187
|
-
~/.claude/
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
~/.
|
|
258
|
+
~/.claude/
|
|
259
|
+
├── mcp.json # Claude Code global MCP config
|
|
260
|
+
└── skills/ # Claude Code global skills
|
|
261
|
+
~/.cursor/
|
|
262
|
+
├── mcp.json # Cursor global MCP config
|
|
263
|
+
└── skills/ # Cursor global skills
|
|
264
|
+
~/.codex/
|
|
265
|
+
├── mcp.json # Codex global MCP config
|
|
266
|
+
└── skills/ # Codex global skills
|
|
267
|
+
~/.github/
|
|
268
|
+
├── mcp.json # VSCode global MCP config
|
|
269
|
+
└── skills/ # VSCode global skills
|
|
270
|
+
~/.codeium/windsurf/
|
|
271
|
+
├── mcp_config.json # Windsurf global MCP config
|
|
272
|
+
└── skills/ # Windsurf global skills
|
|
273
|
+
~/.factory/
|
|
274
|
+
├── mcp.json # Factory global MCP config
|
|
275
|
+
└── skills/ # Factory global skills
|
|
191
276
|
```
|
|
192
277
|
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
MCP configurations are written to each IDE's OS-specific config path:
|
|
196
|
-
- **macOS**: `~/Library/Application Support/{IDE}/mcp.json`
|
|
197
|
-
- **Windows**: `%APPDATA%\{IDE}\mcp.json`
|
|
198
|
-
- **Linux**: `~/.config/{IDE}/mcp.json`
|
|
278
|
+
**Note:** Paths are fully customizable per IDE in `config/a11y.json`
|
|
199
279
|
|
|
200
280
|
## MCP Servers Included (Default)
|
|
201
281
|
|
|
@@ -208,3 +288,63 @@ MCP configurations are written to each IDE's OS-specific config path:
|
|
|
208
288
|
| magentaa11y | `magentaa11y-mcp` | Component accessibility acceptance criteria |
|
|
209
289
|
| a11y-personas | `a11y-personas-mcp` | Accessibility personas for diverse users |
|
|
210
290
|
| arc-issues | `arc-issues-mcp` | AxeCore violation formatting |
|
|
291
|
+
|
|
292
|
+
## Complete Config Example
|
|
293
|
+
|
|
294
|
+
Here's what a complete `config/a11y.json` looks like:
|
|
295
|
+
|
|
296
|
+
```json
|
|
297
|
+
{
|
|
298
|
+
"skillsFolder": "a11y",
|
|
299
|
+
"readmeTemplate": "deploy-README.md",
|
|
300
|
+
"skills": [
|
|
301
|
+
{
|
|
302
|
+
"name": "a11y-base-web-skill",
|
|
303
|
+
"description": "Core accessibility testing utilities"
|
|
304
|
+
},
|
|
305
|
+
{
|
|
306
|
+
"name": "a11y-tester-skill",
|
|
307
|
+
"description": "Run accessibility tests"
|
|
308
|
+
}
|
|
309
|
+
],
|
|
310
|
+
"ides": [
|
|
311
|
+
{
|
|
312
|
+
"id": "claude",
|
|
313
|
+
"displayName": "Claude Code",
|
|
314
|
+
"mcpServerKey": "servers",
|
|
315
|
+
"skillsFolder": ".claude/skills",
|
|
316
|
+
"mcpConfigFile": ".claude/mcp.json"
|
|
317
|
+
},
|
|
318
|
+
{
|
|
319
|
+
"id": "cursor",
|
|
320
|
+
"displayName": "Cursor",
|
|
321
|
+
"mcpServerKey": "mcpServers",
|
|
322
|
+
"skillsFolder": ".cursor/skills",
|
|
323
|
+
"mcpConfigFile": ".cursor/mcp.json"
|
|
324
|
+
},
|
|
325
|
+
{
|
|
326
|
+
"id": "windsurf",
|
|
327
|
+
"displayName": "Windsurf",
|
|
328
|
+
"mcpServerKey": "servers",
|
|
329
|
+
"skillsFolder": ".codeium/windsurf/skills",
|
|
330
|
+
"mcpConfigFile": ".codeium/windsurf/mcp_config.json"
|
|
331
|
+
}
|
|
332
|
+
],
|
|
333
|
+
"mcpServers": [
|
|
334
|
+
{
|
|
335
|
+
"name": "wcag",
|
|
336
|
+
"description": "WCAG guidelines reference",
|
|
337
|
+
"command": "npx",
|
|
338
|
+
"args": ["-y", "wcag-mcp"]
|
|
339
|
+
},
|
|
340
|
+
{
|
|
341
|
+
"name": "aria",
|
|
342
|
+
"description": "ARIA specification reference",
|
|
343
|
+
"command": "npx",
|
|
344
|
+
"args": ["-y", "aria-mcp"]
|
|
345
|
+
}
|
|
346
|
+
]
|
|
347
|
+
}
|
|
348
|
+
```
|
|
349
|
+
|
|
350
|
+
Everything is customizable - add, remove, or modify any section to match your needs.
|
package/config/a11y.json
CHANGED
|
@@ -31,18 +31,50 @@
|
|
|
31
31
|
"description": "Orchestrate accessibility audits"
|
|
32
32
|
}
|
|
33
33
|
],
|
|
34
|
-
"
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
34
|
+
"ides": [
|
|
35
|
+
{
|
|
36
|
+
"id": "claude",
|
|
37
|
+
"displayName": "Claude Code",
|
|
38
|
+
"mcpServerKey": "servers",
|
|
39
|
+
"skillsFolder": ".claude/skills",
|
|
40
|
+
"mcpConfigFile": ".claude/mcp.json"
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
"id": "cursor",
|
|
44
|
+
"displayName": "Cursor",
|
|
45
|
+
"mcpServerKey": "mcpServers",
|
|
46
|
+
"skillsFolder": ".cursor/skills",
|
|
47
|
+
"mcpConfigFile": ".cursor/mcp.json"
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
"id": "codex",
|
|
51
|
+
"displayName": "Codex",
|
|
52
|
+
"mcpServerKey": "servers",
|
|
53
|
+
"skillsFolder": ".codex/skills",
|
|
54
|
+
"mcpConfigFile": ".codex/mcp.json"
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
"id": "vscode",
|
|
58
|
+
"displayName": "VSCode",
|
|
59
|
+
"mcpServerKey": "servers",
|
|
60
|
+
"skillsFolder": ".github/skills",
|
|
61
|
+
"mcpConfigFile": ".github/mcp.json"
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
"id": "windsurf",
|
|
65
|
+
"displayName": "Windsurf",
|
|
66
|
+
"mcpServerKey": "servers",
|
|
67
|
+
"skillsFolder": ".codeium/windsurf/skills",
|
|
68
|
+
"mcpConfigFile": ".codeium/windsurf/mcp_config.json"
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
"id": "factory",
|
|
72
|
+
"displayName": "Factory",
|
|
73
|
+
"mcpServerKey": "mcpServers",
|
|
74
|
+
"skillsFolder": ".factory/skills",
|
|
75
|
+
"mcpConfigFile": ".factory/mcp.json"
|
|
76
|
+
}
|
|
77
|
+
],
|
|
46
78
|
"mcpServers": [
|
|
47
79
|
{
|
|
48
80
|
"name": "wcag",
|
package/package.json
CHANGED
package/src/cli.js
CHANGED
|
@@ -27,7 +27,11 @@ function parseArgs(argv) {
|
|
|
27
27
|
const args = new Set(argv.slice(2));
|
|
28
28
|
return {
|
|
29
29
|
autoYes: args.has("--yes") || args.has("-y"),
|
|
30
|
-
scope: args.has("--global")
|
|
30
|
+
scope: args.has("--global")
|
|
31
|
+
? "global"
|
|
32
|
+
: args.has("--local")
|
|
33
|
+
? "local"
|
|
34
|
+
: null,
|
|
31
35
|
};
|
|
32
36
|
}
|
|
33
37
|
|
|
@@ -43,17 +47,23 @@ async function run() {
|
|
|
43
47
|
const platformInfo = getPlatform();
|
|
44
48
|
const config = await loadConfig();
|
|
45
49
|
const pkg = await loadPackageJson();
|
|
46
|
-
const idePaths = getIdePaths(projectRoot, platformInfo, config.
|
|
50
|
+
const idePaths = getIdePaths(projectRoot, platformInfo, config.ides);
|
|
47
51
|
const args = parseArgs(process.argv);
|
|
48
52
|
|
|
49
|
-
header(
|
|
53
|
+
header(
|
|
54
|
+
`A11y Devkit Deploy v${pkg.version}`,
|
|
55
|
+
"Install skills + MCP servers across IDEs",
|
|
56
|
+
);
|
|
50
57
|
info(`Detected OS: ${formatOs(platformInfo)}`);
|
|
51
58
|
|
|
52
59
|
console.log("\nSkills to install:");
|
|
53
60
|
config.skills.forEach((skill) => {
|
|
54
61
|
const name = typeof skill === "string" ? skill : skill.name;
|
|
55
|
-
const description =
|
|
56
|
-
|
|
62
|
+
const description =
|
|
63
|
+
typeof skill === "string"
|
|
64
|
+
? "No description"
|
|
65
|
+
: skill.description || "No description";
|
|
66
|
+
console.log(`- ${name}: ${description}`);
|
|
57
67
|
});
|
|
58
68
|
|
|
59
69
|
console.log("\nMCP Servers to install:");
|
|
@@ -63,16 +73,14 @@ async function run() {
|
|
|
63
73
|
});
|
|
64
74
|
console.log("");
|
|
65
75
|
|
|
66
|
-
const ideChoices =
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
{ title: "VSCode", value: "vscode" }
|
|
71
|
-
];
|
|
76
|
+
const ideChoices = config.ides.map((ide) => ({
|
|
77
|
+
title: ide.displayName,
|
|
78
|
+
value: ide.id,
|
|
79
|
+
}));
|
|
72
80
|
|
|
73
81
|
let scope = args.scope;
|
|
74
82
|
let mcpScope = null;
|
|
75
|
-
let ideSelection =
|
|
83
|
+
let ideSelection = config.ides.map((ide) => ide.id);
|
|
76
84
|
let installSkills = true;
|
|
77
85
|
|
|
78
86
|
if (!args.autoYes) {
|
|
@@ -83,10 +91,13 @@ async function run() {
|
|
|
83
91
|
name: "scope",
|
|
84
92
|
message: "Install skills + repo locally or globally?",
|
|
85
93
|
choices: [
|
|
86
|
-
{
|
|
87
|
-
|
|
94
|
+
{
|
|
95
|
+
title: `Local to this project (${formatPath(projectRoot)})`,
|
|
96
|
+
value: "local",
|
|
97
|
+
},
|
|
98
|
+
{ title: "Global for this user", value: "global" },
|
|
88
99
|
],
|
|
89
|
-
initial: 0
|
|
100
|
+
initial: 0,
|
|
90
101
|
},
|
|
91
102
|
{
|
|
92
103
|
type: "select",
|
|
@@ -96,22 +107,23 @@ async function run() {
|
|
|
96
107
|
{
|
|
97
108
|
title: `Local to this project (${formatPath(projectRoot)})`,
|
|
98
109
|
value: "local",
|
|
99
|
-
description:
|
|
110
|
+
description:
|
|
111
|
+
"Write to project-level IDE config folders (version-controllable)",
|
|
100
112
|
},
|
|
101
113
|
{
|
|
102
114
|
title: "Global for this user",
|
|
103
115
|
value: "global",
|
|
104
|
-
description: "Write to user-level IDE config folders"
|
|
105
|
-
}
|
|
116
|
+
description: "Write to user-level IDE config folders",
|
|
117
|
+
},
|
|
106
118
|
],
|
|
107
|
-
initial: 0
|
|
119
|
+
initial: 0,
|
|
108
120
|
},
|
|
109
121
|
{
|
|
110
122
|
type: "multiselect",
|
|
111
123
|
name: "ides",
|
|
112
124
|
message: "Configure MCP for which IDEs?",
|
|
113
125
|
choices: ideChoices,
|
|
114
|
-
initial: ideChoices.map((_, index) => index)
|
|
126
|
+
initial: ideChoices.map((_, index) => index),
|
|
115
127
|
},
|
|
116
128
|
{
|
|
117
129
|
type: "toggle",
|
|
@@ -119,15 +131,15 @@ async function run() {
|
|
|
119
131
|
message: "Install skills into IDE skills folders?",
|
|
120
132
|
active: "yes",
|
|
121
133
|
inactive: "no",
|
|
122
|
-
initial: true
|
|
123
|
-
}
|
|
134
|
+
initial: true,
|
|
135
|
+
},
|
|
124
136
|
],
|
|
125
137
|
{
|
|
126
138
|
onCancel: () => {
|
|
127
139
|
warn("Setup cancelled.");
|
|
128
140
|
process.exit(0);
|
|
129
|
-
}
|
|
130
|
-
}
|
|
141
|
+
},
|
|
142
|
+
},
|
|
131
143
|
);
|
|
132
144
|
|
|
133
145
|
scope = scope || response.scope;
|
|
@@ -158,13 +170,24 @@ async function run() {
|
|
|
158
170
|
const skillsSpinner = startSpinner("Installing skills from npm...");
|
|
159
171
|
|
|
160
172
|
try {
|
|
161
|
-
const skillTargets =
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
const
|
|
167
|
-
|
|
173
|
+
const skillTargets =
|
|
174
|
+
scope === "local"
|
|
175
|
+
? ideSelection.map((ide) => idePaths[ide].localSkillsDir)
|
|
176
|
+
: ideSelection.map((ide) => idePaths[ide].skillsDir);
|
|
177
|
+
|
|
178
|
+
const skillNames = config.skills.map((skill) =>
|
|
179
|
+
typeof skill === "string" ? skill : skill.name,
|
|
180
|
+
);
|
|
181
|
+
const result = await installSkillsFromNpm(
|
|
182
|
+
skillNames,
|
|
183
|
+
skillTargets,
|
|
184
|
+
tempDir,
|
|
185
|
+
config.skillsFolder,
|
|
186
|
+
config.readmeTemplate,
|
|
187
|
+
);
|
|
188
|
+
skillsSpinner.succeed(
|
|
189
|
+
`${result.installed} skills installed to ${skillTargets.length} IDE location(s).`,
|
|
190
|
+
);
|
|
168
191
|
} catch (error) {
|
|
169
192
|
skillsSpinner.fail(`Failed to install skills: ${error.message}`);
|
|
170
193
|
}
|
|
@@ -174,19 +197,22 @@ async function run() {
|
|
|
174
197
|
|
|
175
198
|
// Configure MCP servers using npx (no local installation needed!)
|
|
176
199
|
const mcpSpinner = startSpinner("Updating MCP configurations...");
|
|
177
|
-
const mcpConfigPaths =
|
|
178
|
-
|
|
179
|
-
|
|
200
|
+
const mcpConfigPaths =
|
|
201
|
+
mcpScope === "local"
|
|
202
|
+
? ideSelection.map((ide) => idePaths[ide].localMcpConfig)
|
|
203
|
+
: ideSelection.map((ide) => idePaths[ide].mcpConfig);
|
|
180
204
|
|
|
181
205
|
for (let i = 0; i < ideSelection.length; i++) {
|
|
182
206
|
const ide = ideSelection[i];
|
|
183
207
|
await installMcpConfig(
|
|
184
208
|
mcpConfigPaths[i],
|
|
185
209
|
config.mcpServers,
|
|
186
|
-
idePaths[ide].mcpServerKey
|
|
210
|
+
idePaths[ide].mcpServerKey,
|
|
187
211
|
);
|
|
188
212
|
}
|
|
189
|
-
mcpSpinner.succeed(
|
|
213
|
+
mcpSpinner.succeed(
|
|
214
|
+
`MCP configs updated for ${ideSelection.length} IDE(s) (${mcpScope} scope).`,
|
|
215
|
+
);
|
|
190
216
|
|
|
191
217
|
// Clean up temporary directory
|
|
192
218
|
const cleanupSpinner = startSpinner("Cleaning up temporary files...");
|
|
@@ -199,17 +225,18 @@ async function run() {
|
|
|
199
225
|
console.log("");
|
|
200
226
|
success("Next Steps:");
|
|
201
227
|
const skillsFolderPath = config.skillsFolder ? `${config.skillsFolder}/` : "";
|
|
202
|
-
const skillsPath =
|
|
203
|
-
|
|
204
|
-
|
|
228
|
+
const skillsPath =
|
|
229
|
+
scope === "local"
|
|
230
|
+
? `.claude/skills/${skillsFolderPath}README.md (or your IDE's equivalent)`
|
|
231
|
+
: `~/.claude/skills/${skillsFolderPath}README.md (or your IDE's global skills directory)`;
|
|
205
232
|
info(`📖 Check ${skillsPath} for comprehensive usage guide`);
|
|
206
233
|
info("✨ Includes 70+ example prompts for all skills and MCP servers");
|
|
207
|
-
info(
|
|
234
|
+
info(
|
|
235
|
+
"🚀 Start with the 'Getting Started' section for your first accessibility check",
|
|
236
|
+
);
|
|
208
237
|
console.log("");
|
|
209
238
|
info("You can re-run this CLI any time to update skills and configs.");
|
|
210
239
|
info("Documentation: https://github.com/joe-watkins/a11y-devkit#readme");
|
|
211
240
|
}
|
|
212
241
|
|
|
213
|
-
export {
|
|
214
|
-
run
|
|
215
|
-
};
|
|
242
|
+
export { run };
|
package/src/paths.js
CHANGED
|
@@ -30,60 +30,26 @@ function getAppSupportDir(platformInfo = getPlatform()) {
|
|
|
30
30
|
return process.env.XDG_CONFIG_HOME || path.join(os.homedir(), ".config");
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
-
function getIdePaths(projectRoot, platformInfo = getPlatform(),
|
|
34
|
-
const appSupport = getAppSupportDir(platformInfo);
|
|
33
|
+
function getIdePaths(projectRoot, platformInfo = getPlatform(), ideConfigs = []) {
|
|
35
34
|
const home = os.homedir();
|
|
35
|
+
const paths = {};
|
|
36
|
+
|
|
37
|
+
for (const ide of ideConfigs) {
|
|
38
|
+
// Use custom paths from config, or fall back to default pattern: ~/.{id}/
|
|
39
|
+
const skillsFolder = ide.skillsFolder || `.${ide.id}/skills`;
|
|
40
|
+
const mcpConfigFile = ide.mcpConfigFile || `.${ide.id}/mcp.json`;
|
|
41
|
+
|
|
42
|
+
paths[ide.id] = {
|
|
43
|
+
name: ide.displayName,
|
|
44
|
+
mcpConfig: path.join(home, mcpConfigFile),
|
|
45
|
+
localMcpConfig: path.join(projectRoot, mcpConfigFile),
|
|
46
|
+
mcpServerKey: ide.mcpServerKey,
|
|
47
|
+
skillsDir: path.join(home, skillsFolder),
|
|
48
|
+
localSkillsDir: path.join(projectRoot, skillsFolder)
|
|
49
|
+
};
|
|
50
|
+
}
|
|
36
51
|
|
|
37
|
-
|
|
38
|
-
const skillsPaths = ideSkillsPaths || {
|
|
39
|
-
claude: ".claude/skills",
|
|
40
|
-
cursor: ".cursor/skills",
|
|
41
|
-
codex: ".codex/skills",
|
|
42
|
-
vscode: ".vscode/skills",
|
|
43
|
-
local: ".github/skills"
|
|
44
|
-
};
|
|
45
|
-
|
|
46
|
-
const mcpPaths = ideMcpPaths || {
|
|
47
|
-
claude: ".claude/mcp.json",
|
|
48
|
-
cursor: ".cursor/mcp.json",
|
|
49
|
-
codex: ".codex/mcp.json",
|
|
50
|
-
vscode: ".vscode/mcp.json"
|
|
51
|
-
};
|
|
52
|
-
|
|
53
|
-
return {
|
|
54
|
-
claude: {
|
|
55
|
-
name: "Claude Code",
|
|
56
|
-
mcpConfig: path.join(appSupport, "Claude", "mcp.json"),
|
|
57
|
-
localMcpConfig: path.join(projectRoot, mcpPaths.claude),
|
|
58
|
-
mcpServerKey: "servers",
|
|
59
|
-
skillsDir: path.join(home, skillsPaths.claude),
|
|
60
|
-
localSkillsDir: path.join(projectRoot, skillsPaths.claude)
|
|
61
|
-
},
|
|
62
|
-
cursor: {
|
|
63
|
-
name: "Cursor",
|
|
64
|
-
mcpConfig: path.join(appSupport, "Cursor", "mcp.json"),
|
|
65
|
-
localMcpConfig: path.join(projectRoot, mcpPaths.cursor),
|
|
66
|
-
mcpServerKey: "mcpServers",
|
|
67
|
-
skillsDir: path.join(home, skillsPaths.cursor),
|
|
68
|
-
localSkillsDir: path.join(projectRoot, skillsPaths.cursor)
|
|
69
|
-
},
|
|
70
|
-
codex: {
|
|
71
|
-
name: "Codex",
|
|
72
|
-
mcpConfig: path.join(home, ".codex", "mcp.json"),
|
|
73
|
-
localMcpConfig: path.join(projectRoot, mcpPaths.codex),
|
|
74
|
-
mcpServerKey: "servers",
|
|
75
|
-
skillsDir: path.join(home, skillsPaths.codex),
|
|
76
|
-
localSkillsDir: path.join(projectRoot, skillsPaths.codex)
|
|
77
|
-
},
|
|
78
|
-
vscode: {
|
|
79
|
-
name: "VSCode",
|
|
80
|
-
mcpConfig: path.join(appSupport, "Code", "User", "mcp.json"),
|
|
81
|
-
localMcpConfig: path.join(projectRoot, mcpPaths.vscode),
|
|
82
|
-
mcpServerKey: "servers",
|
|
83
|
-
skillsDir: path.join(home, skillsPaths.vscode),
|
|
84
|
-
localSkillsDir: path.join(projectRoot, skillsPaths.vscode)
|
|
85
|
-
}
|
|
86
|
-
};
|
|
52
|
+
return paths;
|
|
87
53
|
}
|
|
88
54
|
|
|
89
55
|
export {
|