ai-agent-config 2.7.2 → 2.8.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.
- package/README.md +10 -8
- package/package.json +3 -2
- package/scripts/external-sync.js +0 -26
- package/scripts/mcp-installer.js +180 -78
- package/scripts/platforms.js +17 -2
- package/scripts/postinstall.js +7 -8
package/README.md
CHANGED
|
@@ -61,14 +61,16 @@ ai-agent update
|
|
|
61
61
|
|
|
62
62
|
## Supported Platforms
|
|
63
63
|
|
|
64
|
-
| Platform | Skills Path | MCP Support |
|
|
65
|
-
|
|
66
|
-
| Claude Code | `~/.claude/skills/` | `claude_desktop_config.json` |
|
|
67
|
-
| Antigravity IDE | `~/.gemini/antigravity/skills/` | `mcp_config.json` |
|
|
68
|
-
| Cursor | `~/.cursor/skills/` |
|
|
69
|
-
| Windsurf | `~/.windsurf/skills/` |
|
|
70
|
-
| Codex CLI | `~/.codex/skills/` |
|
|
71
|
-
| GitHub Copilot | `~/.github/copilot-instructions.md` | - |
|
|
64
|
+
| Platform | Skills Path | MCP Support | Format |
|
|
65
|
+
|----------|-------------|-------------|--------|
|
|
66
|
+
| Claude Code | `~/.claude/skills/` | ✅ `claude_desktop_config.json` | JSON |
|
|
67
|
+
| Antigravity IDE | `~/.gemini/antigravity/skills/` | ✅ `mcp_config.json` | JSON |
|
|
68
|
+
| **Cursor** | `~/.cursor/skills/` | ✅ **`~/.cursor/mcp.json`** | JSON |
|
|
69
|
+
| **Windsurf** | `~/.windsurf/skills/` | ✅ **`~/.codeium/windsurf/mcp_config.json`** | JSON |
|
|
70
|
+
| **Codex CLI** | `~/.codex/skills/` | ✅ **`~/.codex/config.toml`** | **TOML** |
|
|
71
|
+
| GitHub Copilot | `~/.github/copilot-instructions.md` | ❌ | - |
|
|
72
|
+
|
|
73
|
+
**New in v2.8.0:** MCP server support for Cursor, Windsurf, and Codex CLI!
|
|
72
74
|
|
|
73
75
|
## Secret Management
|
|
74
76
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ai-agent-config",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.8.0",
|
|
4
4
|
"description": "Universal skill & workflow manager for AI coding assistants with bi-directional GitHub sync",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"bin": {
|
|
@@ -40,6 +40,7 @@
|
|
|
40
40
|
"node": ">=18.0.0"
|
|
41
41
|
},
|
|
42
42
|
"dependencies": {
|
|
43
|
+
"@iarna/toml": "^2.2.5",
|
|
43
44
|
"inquirer": "^9.2.12"
|
|
44
45
|
},
|
|
45
46
|
"files": [
|
|
@@ -50,4 +51,4 @@
|
|
|
50
51
|
"index.js",
|
|
51
52
|
"README.md"
|
|
52
53
|
]
|
|
53
|
-
}
|
|
54
|
+
}
|
package/scripts/external-sync.js
CHANGED
|
@@ -119,30 +119,6 @@ function copyDirRecursive(src, dest, excludePaths = []) {
|
|
|
119
119
|
}
|
|
120
120
|
}
|
|
121
121
|
|
|
122
|
-
/**
|
|
123
|
-
* Add attribution to SKILL.md file
|
|
124
|
-
*/
|
|
125
|
-
function addAttribution(skillPath, attribution) {
|
|
126
|
-
const skillFile = path.join(skillPath, "SKILL.md");
|
|
127
|
-
|
|
128
|
-
if (!fs.existsSync(skillFile)) {
|
|
129
|
-
return;
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
let content = fs.readFileSync(skillFile, "utf-8");
|
|
133
|
-
|
|
134
|
-
// Check if attribution already exists
|
|
135
|
-
if (content.includes(attribution)) {
|
|
136
|
-
return;
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
// Add attribution at the top
|
|
140
|
-
const attributionBlock = `---\nsource: external\nattribution: ${attribution}\n---\n\n`;
|
|
141
|
-
content = attributionBlock + content;
|
|
142
|
-
|
|
143
|
-
fs.writeFileSync(skillFile, content, "utf-8");
|
|
144
|
-
}
|
|
145
|
-
|
|
146
122
|
/**
|
|
147
123
|
* Sync all external skills
|
|
148
124
|
*/
|
|
@@ -203,8 +179,6 @@ function syncAll(options = {}) {
|
|
|
203
179
|
const result = copySkill(sourcePath, targetPath, true, excludePaths);
|
|
204
180
|
|
|
205
181
|
if (result.copied) {
|
|
206
|
-
// Skip attribution to save tokens - attribution is already in external-skills.json
|
|
207
|
-
// addAttribution(targetPath, src.attribution);
|
|
208
182
|
console.log(` ✓ ${skillDef.name}`);
|
|
209
183
|
results.copied++;
|
|
210
184
|
} else {
|
package/scripts/mcp-installer.js
CHANGED
|
@@ -5,11 +5,18 @@
|
|
|
5
5
|
|
|
6
6
|
const fs = require("fs");
|
|
7
7
|
const path = require("path");
|
|
8
|
+
const toml = require("@iarna/toml");
|
|
8
9
|
const platforms = require("./platforms");
|
|
9
10
|
const configManager = require("./config-manager");
|
|
10
11
|
|
|
11
12
|
const SKIP_FOLDERS = ["bitwarden"];
|
|
12
13
|
|
|
14
|
+
// Config format constants
|
|
15
|
+
const FORMAT_JSON = "json";
|
|
16
|
+
const FORMAT_TOML = "toml";
|
|
17
|
+
const TOML_MCP_KEY = "mcp_servers"; // Underscore! Not dot
|
|
18
|
+
const JSON_MCP_KEY = "mcpServers"; // CamelCase
|
|
19
|
+
|
|
13
20
|
/**
|
|
14
21
|
* Get the MCP servers directory from the user's sync repo
|
|
15
22
|
* @returns {string|null} Path to .agent/mcp-servers/ or null
|
|
@@ -85,6 +92,143 @@ function getAvailableMcpServers() {
|
|
|
85
92
|
return servers;
|
|
86
93
|
}
|
|
87
94
|
|
|
95
|
+
/**
|
|
96
|
+
* Get config format for a platform
|
|
97
|
+
* @param {string} platformName - Platform name
|
|
98
|
+
* @returns {string} "json" or "toml"
|
|
99
|
+
*/
|
|
100
|
+
function getConfigFormat(platformName) {
|
|
101
|
+
const platform = platforms.getByName(platformName);
|
|
102
|
+
return platform?.mcpConfigFormat || FORMAT_JSON;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Read platform config file (supports JSON and TOML)
|
|
107
|
+
* @param {string} configPath - Path to config file
|
|
108
|
+
* @param {string} format - "json" or "toml"
|
|
109
|
+
* @returns {Object} Parsed config or empty object
|
|
110
|
+
*/
|
|
111
|
+
function readPlatformConfig(configPath, format) {
|
|
112
|
+
if (!fs.existsSync(configPath)) {
|
|
113
|
+
return {};
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
try {
|
|
117
|
+
const content = fs.readFileSync(configPath, "utf-8");
|
|
118
|
+
|
|
119
|
+
if (format === FORMAT_TOML) {
|
|
120
|
+
return toml.parse(content);
|
|
121
|
+
} else {
|
|
122
|
+
return JSON.parse(content);
|
|
123
|
+
}
|
|
124
|
+
} catch (error) {
|
|
125
|
+
console.warn(`⚠️ Failed to parse config at ${configPath}: ${error.message}`);
|
|
126
|
+
return {};
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* Write platform config file (supports JSON and TOML)
|
|
132
|
+
* @param {string} configPath - Path to config file
|
|
133
|
+
* @param {Object} config - Config object to write
|
|
134
|
+
* @param {string} format - "json" or "toml"
|
|
135
|
+
*/
|
|
136
|
+
function writePlatformConfig(configPath, config, format) {
|
|
137
|
+
let content;
|
|
138
|
+
|
|
139
|
+
if (format === FORMAT_TOML) {
|
|
140
|
+
content = toml.stringify(config);
|
|
141
|
+
} else {
|
|
142
|
+
content = JSON.stringify(config, null, 2) + "\n";
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
// Create directory if needed
|
|
146
|
+
const configDir = path.dirname(configPath);
|
|
147
|
+
if (!fs.existsSync(configDir)) {
|
|
148
|
+
fs.mkdirSync(configDir, { recursive: true });
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
fs.writeFileSync(configPath, content, "utf-8");
|
|
152
|
+
|
|
153
|
+
// Set restrictive permissions (owner read/write only) to protect secrets
|
|
154
|
+
// Only on Unix-like systems (macOS, Linux) - Windows uses ACL instead
|
|
155
|
+
if (process.platform !== "win32") {
|
|
156
|
+
try {
|
|
157
|
+
fs.chmodSync(configPath, 0o600);
|
|
158
|
+
} catch (e) {
|
|
159
|
+
console.warn(`⚠️ Warning: Could not set file permissions on ${configPath}: ${e.message}`);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* Build server config object with platform-specific fields
|
|
166
|
+
* @param {Object} server - Server config from repo
|
|
167
|
+
* @param {string} platformName - Platform name
|
|
168
|
+
* @param {Object} existing - Existing server config (for preservation)
|
|
169
|
+
* @returns {Object} Platform-specific server config
|
|
170
|
+
*/
|
|
171
|
+
function buildServerConfig(server, platformName, existing = {}) {
|
|
172
|
+
const config = {
|
|
173
|
+
command: server.command,
|
|
174
|
+
args: server.args,
|
|
175
|
+
};
|
|
176
|
+
|
|
177
|
+
// Preserve existing env vars
|
|
178
|
+
if (existing.env) {
|
|
179
|
+
config.env = existing.env;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
// Platform-specific field handling
|
|
183
|
+
switch (platformName) {
|
|
184
|
+
case "antigravity":
|
|
185
|
+
// Antigravity supports disabledTools
|
|
186
|
+
// Preserve existing disabledTools, or use server's if present
|
|
187
|
+
if (existing.disabledTools) {
|
|
188
|
+
config.disabledTools = existing.disabledTools;
|
|
189
|
+
} else if (server.disabledTools && server.disabledTools.length > 0) {
|
|
190
|
+
config.disabledTools = server.disabledTools;
|
|
191
|
+
}
|
|
192
|
+
break;
|
|
193
|
+
|
|
194
|
+
case "windsurf":
|
|
195
|
+
// Windsurf uses "disabled" boolean field
|
|
196
|
+
// Preserve user's manual setting, otherwise use repo default
|
|
197
|
+
if (existing.disabled !== undefined) {
|
|
198
|
+
config.disabled = existing.disabled;
|
|
199
|
+
} else if (server.enabled !== undefined) {
|
|
200
|
+
config.disabled = !server.enabled;
|
|
201
|
+
}
|
|
202
|
+
break;
|
|
203
|
+
|
|
204
|
+
case "codex":
|
|
205
|
+
// Codex supports enabled, enabled_tools, disabled_tools
|
|
206
|
+
// Preserve user's manual settings, otherwise use repo defaults
|
|
207
|
+
if (existing.enabled !== undefined) {
|
|
208
|
+
config.enabled = existing.enabled;
|
|
209
|
+
} else if (server.enabled !== undefined) {
|
|
210
|
+
config.enabled = server.enabled;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
if (existing.disabled_tools) {
|
|
214
|
+
config.disabled_tools = existing.disabled_tools;
|
|
215
|
+
} else if (server.disabledTools && server.disabledTools.length > 0) {
|
|
216
|
+
config.disabled_tools = server.disabledTools; // Note: snake_case
|
|
217
|
+
}
|
|
218
|
+
break;
|
|
219
|
+
|
|
220
|
+
case "claude":
|
|
221
|
+
// Claude doesn't support disabledTools - skip
|
|
222
|
+
break;
|
|
223
|
+
|
|
224
|
+
case "cursor":
|
|
225
|
+
// Cursor doesn't support disabledTools - skip
|
|
226
|
+
break;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
return config;
|
|
230
|
+
}
|
|
231
|
+
|
|
88
232
|
/**
|
|
89
233
|
* Collect all bitwardenEnv entries from MCP server configs
|
|
90
234
|
* @returns {Array<{ serverName: string, envVar: string, bitwardenItem: string }>}
|
|
@@ -119,63 +263,39 @@ function collectBitwardenEnvs() {
|
|
|
119
263
|
function writeMcpToPlatformConfig(configPath, servers, options = {}) {
|
|
120
264
|
const { force = false, platformName = "" } = options;
|
|
121
265
|
|
|
122
|
-
//
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
266
|
+
// Determine config format
|
|
267
|
+
const format = getConfigFormat(platformName);
|
|
268
|
+
|
|
269
|
+
// Read existing config — preserve ALL existing keys
|
|
270
|
+
let config = readPlatformConfig(configPath, format);
|
|
271
|
+
|
|
272
|
+
// Initialize MCP servers section if not exists
|
|
273
|
+
const mcpKey = format === FORMAT_TOML ? TOML_MCP_KEY : JSON_MCP_KEY;
|
|
274
|
+
if (!config[mcpKey]) {
|
|
275
|
+
config[mcpKey] = {};
|
|
131
276
|
}
|
|
132
277
|
|
|
133
278
|
let added = 0;
|
|
134
279
|
let skipped = 0;
|
|
135
280
|
|
|
136
281
|
for (const server of servers) {
|
|
137
|
-
const existing = config
|
|
282
|
+
const existing = config[mcpKey][server.name];
|
|
138
283
|
|
|
139
284
|
if (existing && !force) {
|
|
140
285
|
skipped++;
|
|
141
286
|
continue;
|
|
142
287
|
}
|
|
143
288
|
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
args: server.args,
|
|
147
|
-
};
|
|
148
|
-
|
|
149
|
-
// Preserve existing env
|
|
150
|
-
if (existing && existing.env) {
|
|
151
|
-
entry.env = existing.env;
|
|
152
|
-
}
|
|
289
|
+
// Build platform-specific config
|
|
290
|
+
const entry = buildServerConfig(server, platformName, existing);
|
|
153
291
|
|
|
154
|
-
|
|
155
|
-
if (platformName !== "claude" && server.disabledTools && server.disabledTools.length > 0) {
|
|
156
|
-
entry.disabledTools = server.disabledTools;
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
config.mcpServers[server.name] = entry;
|
|
292
|
+
config[mcpKey][server.name] = entry;
|
|
160
293
|
added++;
|
|
161
294
|
}
|
|
162
295
|
|
|
163
|
-
// Write back
|
|
296
|
+
// Write back only if changes were made
|
|
164
297
|
if (added > 0) {
|
|
165
|
-
|
|
166
|
-
if (!fs.existsSync(configDir)) {
|
|
167
|
-
fs.mkdirSync(configDir, { recursive: true });
|
|
168
|
-
}
|
|
169
|
-
fs.writeFileSync(configPath, JSON.stringify(config, null, 2) + "\n", "utf-8");
|
|
170
|
-
// Set restrictive permissions (owner read/write only) to protect secrets
|
|
171
|
-
// Only on Unix-like systems (macOS, Linux) - Windows uses ACL instead
|
|
172
|
-
if (process.platform !== "win32") {
|
|
173
|
-
try {
|
|
174
|
-
fs.chmodSync(configPath, 0o600);
|
|
175
|
-
} catch (e) {
|
|
176
|
-
console.warn(`⚠️ Warning: Could not set file permissions on ${configPath}: ${e.message}`);
|
|
177
|
-
}
|
|
178
|
-
}
|
|
298
|
+
writePlatformConfig(configPath, config, format);
|
|
179
299
|
}
|
|
180
300
|
|
|
181
301
|
return { added, skipped };
|
|
@@ -233,31 +353,30 @@ function installMcpServers(options = {}) {
|
|
|
233
353
|
* @param {string} configPath - Path to platform's MCP config file
|
|
234
354
|
* @param {Array} servers - MCP server configs
|
|
235
355
|
* @param {Object} resolvedSecrets - Map of bitwardenItem → resolvedValue
|
|
236
|
-
* @param {string} platformName - Platform name for
|
|
356
|
+
* @param {string} platformName - Platform name for format and field handling
|
|
237
357
|
* @returns {{ installed: number, servers: Array<{ name: string, secretsCount: number }> }}
|
|
238
358
|
*/
|
|
239
359
|
function writeMcpWithSecretsToPlatformConfig(configPath, servers, resolvedSecrets, platformName) {
|
|
360
|
+
// Determine config format
|
|
361
|
+
const format = getConfigFormat(platformName);
|
|
362
|
+
|
|
240
363
|
// Read existing config — preserve ALL existing keys
|
|
241
|
-
let config =
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
config = { mcpServers: {} };
|
|
248
|
-
}
|
|
364
|
+
let config = readPlatformConfig(configPath, format);
|
|
365
|
+
|
|
366
|
+
// Initialize MCP servers section if not exists
|
|
367
|
+
const mcpKey = format === FORMAT_TOML ? TOML_MCP_KEY : JSON_MCP_KEY;
|
|
368
|
+
if (!config[mcpKey]) {
|
|
369
|
+
config[mcpKey] = {};
|
|
249
370
|
}
|
|
250
371
|
|
|
251
372
|
let installed = 0;
|
|
252
373
|
const serverResults = [];
|
|
253
374
|
|
|
254
375
|
for (const server of servers) {
|
|
255
|
-
const existing = config
|
|
376
|
+
const existing = config[mcpKey][server.name] || {};
|
|
256
377
|
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
args: server.args,
|
|
260
|
-
};
|
|
378
|
+
// Build platform-specific config
|
|
379
|
+
const entry = buildServerConfig(server, platformName, existing);
|
|
261
380
|
|
|
262
381
|
// Build env from resolved secrets
|
|
263
382
|
if (server.bitwardenEnv) {
|
|
@@ -280,35 +399,13 @@ function writeMcpWithSecretsToPlatformConfig(configPath, servers, resolvedSecret
|
|
|
280
399
|
serverResults.push({ name: server.name, secretsCount: 0 });
|
|
281
400
|
}
|
|
282
401
|
|
|
283
|
-
|
|
284
|
-
if (platformName !== "claude") {
|
|
285
|
-
if (existing.disabledTools) {
|
|
286
|
-
entry.disabledTools = existing.disabledTools;
|
|
287
|
-
} else if (server.disabledTools && server.disabledTools.length > 0) {
|
|
288
|
-
entry.disabledTools = server.disabledTools;
|
|
289
|
-
}
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
config.mcpServers[server.name] = entry;
|
|
402
|
+
config[mcpKey][server.name] = entry;
|
|
293
403
|
installed++;
|
|
294
404
|
}
|
|
295
405
|
|
|
296
406
|
// Write back
|
|
297
407
|
if (installed > 0) {
|
|
298
|
-
|
|
299
|
-
if (!fs.existsSync(configDir)) {
|
|
300
|
-
fs.mkdirSync(configDir, { recursive: true });
|
|
301
|
-
}
|
|
302
|
-
fs.writeFileSync(configPath, JSON.stringify(config, null, 2) + "\n", "utf-8");
|
|
303
|
-
// Set restrictive permissions (owner read/write only) to protect secrets
|
|
304
|
-
// Only on Unix-like systems (macOS, Linux) - Windows uses ACL instead
|
|
305
|
-
if (process.platform !== "win32") {
|
|
306
|
-
try {
|
|
307
|
-
fs.chmodSync(configPath, 0o600);
|
|
308
|
-
} catch (e) {
|
|
309
|
-
console.warn(`⚠️ Warning: Could not set file permissions on ${configPath}: ${e.message}`);
|
|
310
|
-
}
|
|
311
|
-
}
|
|
408
|
+
writePlatformConfig(configPath, config, format);
|
|
312
409
|
}
|
|
313
410
|
|
|
314
411
|
return { installed, servers: serverResults };
|
|
@@ -362,5 +459,10 @@ module.exports = {
|
|
|
362
459
|
installMcpServers,
|
|
363
460
|
installMcpServersWithSecrets,
|
|
364
461
|
writeMcpToPlatformConfig,
|
|
462
|
+
// New helper functions (for testing)
|
|
463
|
+
getConfigFormat,
|
|
464
|
+
readPlatformConfig,
|
|
465
|
+
writePlatformConfig,
|
|
466
|
+
buildServerConfig,
|
|
365
467
|
SKIP_FOLDERS,
|
|
366
468
|
};
|
package/scripts/platforms.js
CHANGED
|
@@ -79,6 +79,7 @@ const SUPPORTED = [
|
|
|
79
79
|
configDir: ".cursor",
|
|
80
80
|
skillsDir: "skills",
|
|
81
81
|
rulesDir: "rules",
|
|
82
|
+
mcpConfigFile: "mcp.json",
|
|
82
83
|
get configPath() {
|
|
83
84
|
return path.join(HOME, this.configDir);
|
|
84
85
|
},
|
|
@@ -88,6 +89,9 @@ const SUPPORTED = [
|
|
|
88
89
|
get rulesPath() {
|
|
89
90
|
return path.join(HOME, this.configDir, this.rulesDir);
|
|
90
91
|
},
|
|
92
|
+
get mcpConfigPath() {
|
|
93
|
+
return path.join(HOME, this.configDir, this.mcpConfigFile);
|
|
94
|
+
},
|
|
91
95
|
detect() {
|
|
92
96
|
return (
|
|
93
97
|
fs.existsSync(this.configPath) ||
|
|
@@ -101,12 +105,17 @@ const SUPPORTED = [
|
|
|
101
105
|
displayName: "Windsurf",
|
|
102
106
|
configDir: ".windsurf",
|
|
103
107
|
skillsDir: "skills",
|
|
108
|
+
mcpConfigFile: "mcp_config.json",
|
|
104
109
|
get configPath() {
|
|
105
110
|
return path.join(HOME, this.configDir);
|
|
106
111
|
},
|
|
107
112
|
get skillsPath() {
|
|
108
113
|
return path.join(HOME, this.configDir, this.skillsDir);
|
|
109
114
|
},
|
|
115
|
+
get mcpConfigPath() {
|
|
116
|
+
// Windsurf stores config in ~/.codeium/windsurf/
|
|
117
|
+
return path.join(HOME, ".codeium", "windsurf", this.mcpConfigFile);
|
|
118
|
+
},
|
|
110
119
|
detect() {
|
|
111
120
|
return (
|
|
112
121
|
fs.existsSync(this.configPath) ||
|
|
@@ -119,12 +128,17 @@ const SUPPORTED = [
|
|
|
119
128
|
displayName: "Codex CLI",
|
|
120
129
|
configDir: ".codex",
|
|
121
130
|
skillsDir: "skills",
|
|
131
|
+
mcpConfigFile: "config.toml",
|
|
132
|
+
mcpConfigFormat: "toml", // TOML format instead of JSON
|
|
122
133
|
get configPath() {
|
|
123
134
|
return path.join(HOME, this.configDir);
|
|
124
135
|
},
|
|
125
136
|
get skillsPath() {
|
|
126
137
|
return path.join(HOME, this.configDir, this.skillsDir);
|
|
127
138
|
},
|
|
139
|
+
get mcpConfigPath() {
|
|
140
|
+
return path.join(HOME, this.configDir, this.mcpConfigFile);
|
|
141
|
+
},
|
|
128
142
|
detect() {
|
|
129
143
|
return fs.existsSync(this.configPath);
|
|
130
144
|
},
|
|
@@ -141,8 +155,9 @@ const SUPPORTED = [
|
|
|
141
155
|
return path.join(HOME, this.configDir, this.instructionsFile);
|
|
142
156
|
},
|
|
143
157
|
detect() {
|
|
144
|
-
// Copilot
|
|
145
|
-
|
|
158
|
+
// Check for actual Copilot instructions file, not just ~/.github directory
|
|
159
|
+
// (which is created by gh CLI for auth tokens, causing false positives)
|
|
160
|
+
return fs.existsSync(this.instructionsPath);
|
|
146
161
|
},
|
|
147
162
|
},
|
|
148
163
|
];
|
package/scripts/postinstall.js
CHANGED
|
@@ -67,14 +67,13 @@ function main() {
|
|
|
67
67
|
|
|
68
68
|
const fs = require("fs");
|
|
69
69
|
const path = require("path");
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
const
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
);
|
|
70
|
+
|
|
71
|
+
// Use platforms.js to get Antigravity MCP config path (avoid hardcoding)
|
|
72
|
+
const antigravityPlatform = platforms.getByName("antigravity");
|
|
73
|
+
if (!antigravityPlatform) {
|
|
74
|
+
return; // Antigravity platform not available
|
|
75
|
+
}
|
|
76
|
+
const antigravityMcpPath = antigravityPlatform.mcpConfigPath;
|
|
78
77
|
|
|
79
78
|
if (fs.existsSync(path.dirname(antigravityMcpPath))) {
|
|
80
79
|
try {
|