a11y-devkit-deploy 0.6.1 → 0.6.3

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "a11y-devkit-deploy",
3
- "version": "0.6.1",
3
+ "version": "0.6.3",
4
4
  "description": "CLI to deploy a11y skills and MCP servers across IDEs",
5
5
  "license": "MIT",
6
6
  "type": "module",
package/src/cli.js CHANGED
@@ -17,6 +17,30 @@ async function loadConfig() {
17
17
  return JSON.parse(raw);
18
18
  }
19
19
 
20
+ async function loadPackageJson() {
21
+ const pkgPath = path.join(__dirname, "..", "package.json");
22
+ const raw = await fs.readFile(pkgPath, "utf8");
23
+ return JSON.parse(raw);
24
+ }
25
+
26
+ const skillDescriptions = {
27
+ "a11y-base-web-skill": "Core accessibility testing utilities",
28
+ "a11y-issue-writer-skill": "Document accessibility issues",
29
+ "a11y-tester-skill": "Run accessibility tests",
30
+ "a11y-remediator-skill": "Fix accessibility issues",
31
+ "a11y-validator-skill": "Validate accessibility compliance",
32
+ "web-standards-skill": "Web standards reference",
33
+ "a11y-audit-fix-agent-orchestrator-skill": "Orchestrate accessibility audits"
34
+ };
35
+
36
+ const mcpDescriptions = {
37
+ "wcag": "WCAG guidelines reference",
38
+ "aria": "ARIA specification reference",
39
+ "magentaa11y": "MagentaA11y accessibility acceptance criteria tool",
40
+ "a11y-personas": "Accessibility personas and user scenarios",
41
+ "arc-issues": "Pre-formatted a11y issue templates"
42
+ };
43
+
20
44
  function parseArgs(argv) {
21
45
  const args = new Set(argv.slice(2));
22
46
  return {
@@ -36,12 +60,26 @@ async function run() {
36
60
  const projectRoot = process.cwd();
37
61
  const platformInfo = getPlatform();
38
62
  const config = await loadConfig();
63
+ const pkg = await loadPackageJson();
39
64
  const idePaths = getIdePaths(projectRoot, platformInfo, config.ideSkillsPaths);
40
65
  const args = parseArgs(process.argv);
41
66
 
42
- header("A11y Devkit Deploy", "Install skills + MCP servers across IDEs");
67
+ header(`A11y Devkit Deploy v${pkg.version}`, "Install skills + MCP servers across IDEs");
43
68
  info(`Detected OS: ${formatOs(platformInfo)}`);
44
69
 
70
+ console.log("\nSkills to install:");
71
+ config.skills.forEach((skill) => {
72
+ const description = skillDescriptions[skill] || "No description";
73
+ console.log(`${skill} - ${description}`);
74
+ });
75
+
76
+ console.log("\nMCP Servers to install:");
77
+ config.mcpServers.forEach((server) => {
78
+ const description = mcpDescriptions[server.name] || "No description";
79
+ console.log(`${server.name} - ${description}`);
80
+ });
81
+ console.log("");
82
+
45
83
  const ideChoices = [
46
84
  { title: "Claude Code", value: "claude" },
47
85
  { title: "Cursor", value: "cursor" },
@@ -50,6 +88,7 @@ async function run() {
50
88
  ];
51
89
 
52
90
  let scope = args.scope;
91
+ let mcpScope = null;
53
92
  let ideSelection = ["claude", "cursor", "codex", "vscode"];
54
93
  let installSkills = true;
55
94
 
@@ -61,11 +100,29 @@ async function run() {
61
100
  name: "scope",
62
101
  message: "Install skills + repo locally or globally?",
63
102
  choices: [
64
- { title: "Local to this project", value: "local" },
103
+ { title: `Local to this project (${formatPath(projectRoot)})`, value: "local" },
65
104
  { title: "Global for this user", value: "global" }
66
105
  ],
67
106
  initial: 0
68
107
  },
108
+ {
109
+ type: "select",
110
+ name: "mcpScope",
111
+ message: "Install MCP configs locally or globally?",
112
+ choices: [
113
+ {
114
+ title: `Local to this project (${formatPath(projectRoot)})`,
115
+ value: "local",
116
+ description: "Write to .claude/mcp.json, .cursor/mcp.json, etc. (version-controllable)"
117
+ },
118
+ {
119
+ title: "Global for this user",
120
+ value: "global",
121
+ description: "Write to ~/Library/Application Support/{IDE}/mcp.json"
122
+ }
123
+ ],
124
+ initial: 0
125
+ },
69
126
  {
70
127
  type: "multiselect",
71
128
  name: "ides",
@@ -91,6 +148,7 @@ async function run() {
91
148
  );
92
149
 
93
150
  scope = scope || response.scope;
151
+ mcpScope = response.mcpScope || "local";
94
152
  ideSelection = response.ides || ideSelection;
95
153
  installSkills = response.installSkills;
96
154
  }
@@ -98,13 +156,17 @@ async function run() {
98
156
  if (!scope) {
99
157
  scope = "local";
100
158
  }
159
+ if (!mcpScope) {
160
+ mcpScope = "local";
161
+ }
101
162
 
102
163
  if (!ideSelection.length) {
103
164
  warn("No IDEs selected. MCP installation requires at least one IDE.");
104
165
  process.exit(1);
105
166
  }
106
167
 
107
- info(`Install scope: ${scope === "local" ? "Local" : "Global"}`);
168
+ info(`Skills scope: ${scope === "local" ? "Local" : "Global"}`);
169
+ info(`MCP scope: ${mcpScope === "local" ? "Local" : "Global"}`);
108
170
 
109
171
  // Create temp directory for npm install
110
172
  const tempDir = path.join(getTempDir(), `.a11y-devkit-${Date.now()}`);
@@ -128,10 +190,19 @@ async function run() {
128
190
 
129
191
  // Configure MCP servers using npx (no local installation needed!)
130
192
  const mcpSpinner = startSpinner("Updating MCP configurations...");
131
- for (const ide of ideSelection) {
132
- await installMcpConfig(idePaths[ide].mcpConfig, config.mcpServers, idePaths[ide].mcpServerKey);
193
+ const mcpConfigPaths = mcpScope === "local"
194
+ ? ideSelection.map((ide) => idePaths[ide].localMcpConfig)
195
+ : ideSelection.map((ide) => idePaths[ide].mcpConfig);
196
+
197
+ for (let i = 0; i < ideSelection.length; i++) {
198
+ const ide = ideSelection[i];
199
+ await installMcpConfig(
200
+ mcpConfigPaths[i],
201
+ config.mcpServers,
202
+ idePaths[ide].mcpServerKey
203
+ );
133
204
  }
134
- mcpSpinner.succeed(`MCP configs updated for ${ideSelection.length} IDE(s).`);
205
+ mcpSpinner.succeed(`MCP configs updated for ${ideSelection.length} IDE(s) (${mcpScope} scope).`);
135
206
 
136
207
  // Clean up temporary directory
137
208
  const cleanupSpinner = startSpinner("Cleaning up temporary files...");
package/src/paths.js CHANGED
@@ -47,6 +47,7 @@ function getIdePaths(projectRoot, platformInfo = getPlatform(), ideSkillsPaths =
47
47
  claude: {
48
48
  name: "Claude Code",
49
49
  mcpConfig: path.join(appSupport, "Claude", "mcp.json"),
50
+ localMcpConfig: path.join(projectRoot, ".claude", "mcp.json"),
50
51
  mcpServerKey: "servers",
51
52
  skillsDir: path.join(home, skillsPaths.claude),
52
53
  localSkillsDir: path.join(projectRoot, skillsPaths.claude)
@@ -54,6 +55,7 @@ function getIdePaths(projectRoot, platformInfo = getPlatform(), ideSkillsPaths =
54
55
  cursor: {
55
56
  name: "Cursor",
56
57
  mcpConfig: path.join(appSupport, "Cursor", "mcp.json"),
58
+ localMcpConfig: path.join(projectRoot, ".cursor", "mcp.json"),
57
59
  mcpServerKey: "mcpServers",
58
60
  skillsDir: path.join(home, skillsPaths.cursor),
59
61
  localSkillsDir: path.join(projectRoot, skillsPaths.cursor)
@@ -61,6 +63,7 @@ function getIdePaths(projectRoot, platformInfo = getPlatform(), ideSkillsPaths =
61
63
  codex: {
62
64
  name: "Codex",
63
65
  mcpConfig: path.join(home, ".codex", "mcp.json"),
66
+ localMcpConfig: path.join(projectRoot, ".codex", "mcp.json"),
64
67
  mcpServerKey: "servers",
65
68
  skillsDir: path.join(home, skillsPaths.codex),
66
69
  localSkillsDir: path.join(projectRoot, skillsPaths.codex)
@@ -68,6 +71,7 @@ function getIdePaths(projectRoot, platformInfo = getPlatform(), ideSkillsPaths =
68
71
  vscode: {
69
72
  name: "VSCode",
70
73
  mcpConfig: path.join(appSupport, "Code", "User", "mcp.json"),
74
+ localMcpConfig: path.join(projectRoot, ".vscode", "mcp.json"),
71
75
  mcpServerKey: "servers",
72
76
  skillsDir: path.join(home, skillsPaths.vscode),
73
77
  localSkillsDir: path.join(projectRoot, skillsPaths.vscode)