skiller 0.7.19 → 0.7.21

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.
@@ -96,7 +96,8 @@ class AiderAgent {
96
96
  };
97
97
  }
98
98
  getMcpServerKey() {
99
- return this.agentsMdAgent.getMcpServerKey();
99
+ // Aider uses the standard `.mcp.json` schema key.
100
+ return 'mcpServers';
100
101
  }
101
102
  supportsMcpStdio() {
102
103
  return true;
@@ -126,36 +126,11 @@ function parsePluginId(pluginId) {
126
126
  marketplaceId: pluginId.slice(at + 1),
127
127
  };
128
128
  }
129
- async function readKnownMarketplaceInstallLocations(claudeDir) {
130
- const knownPath = path.join(claudeDir, 'plugins', 'known_marketplaces.json');
131
- let raw;
132
- try {
133
- raw = JSON.parse(await fs.readFile(knownPath, 'utf8'));
134
- }
135
- catch {
136
- return {};
137
- }
138
- if (!raw || typeof raw !== 'object')
139
- return {};
140
- const obj = raw;
141
- const out = {};
142
- for (const [marketplaceId, marketplace] of Object.entries(obj)) {
143
- if (!marketplace || typeof marketplace !== 'object')
144
- continue;
145
- const installLocation = marketplace
146
- .installLocation;
147
- if (typeof installLocation !== 'string' || installLocation.trim() === '')
148
- continue;
149
- out[marketplaceId] = installLocation;
150
- }
151
- return out;
152
- }
153
- async function resolvePluginMarketplaceRoot(pluginId, claudeDir, knownMarketplaceInstallLocations) {
129
+ async function resolvePluginMarketplaceRoot(pluginId, claudeDir) {
154
130
  const parsed = parsePluginId(pluginId);
155
131
  if (!parsed)
156
132
  return null;
157
- const marketplaceRoot = knownMarketplaceInstallLocations[parsed.marketplaceId] ??
158
- path.join(claudeDir, 'plugins', 'marketplaces', parsed.marketplaceId);
133
+ const marketplaceRoot = path.join(claudeDir, 'plugins', 'marketplaces', parsed.marketplaceId);
159
134
  const candidates = [
160
135
  path.join(marketplaceRoot, 'plugins', parsed.pluginName),
161
136
  path.join(marketplaceRoot, 'external_plugins', parsed.pluginName),
@@ -266,19 +241,31 @@ async function discoverPluginCommandFiles(installPath) {
266
241
  const commandsRoot = path.join(installPath, 'commands');
267
242
  if (!(await fileExists(commandsRoot)))
268
243
  return [];
269
- let entries;
270
- try {
271
- entries = await fs.readdir(commandsRoot, { withFileTypes: true });
272
- }
273
- catch {
274
- return [];
244
+ const results = [];
245
+ async function walk(current, depth) {
246
+ if (depth >= constants_1.MAX_RECURSION_DEPTH)
247
+ return;
248
+ let entries;
249
+ try {
250
+ entries = await fs.readdir(current, { withFileTypes: true });
251
+ }
252
+ catch {
253
+ return;
254
+ }
255
+ for (const entry of entries) {
256
+ const full = path.join(current, entry.name);
257
+ if (entry.isDirectory()) {
258
+ await walk(full, depth + 1);
259
+ continue;
260
+ }
261
+ if (!entry.isFile() || !entry.name.endsWith('.md'))
262
+ continue;
263
+ const rel = path.relative(commandsRoot, full).replace(/\\/g, '/');
264
+ results.push({ rel, file: full });
265
+ }
275
266
  }
276
- return entries
277
- .filter((e) => e.isFile() && e.name.endsWith('.md'))
278
- .map((e) => ({
279
- name: path.basename(e.name, '.md'),
280
- file: path.join(commandsRoot, e.name),
281
- }));
267
+ await walk(commandsRoot, 0);
268
+ return results;
282
269
  }
283
270
  async function discoverPluginAgentFiles(installPath) {
284
271
  const agentsRoot = path.join(installPath, 'agents');
@@ -328,8 +315,13 @@ function generateBaseNameFromRelId(relId) {
328
315
  const segments = normalized.split('/').filter(Boolean);
329
316
  return segments.map(sanitizeId).join('-');
330
317
  }
331
- function generateBaseNameFromCommand(commandName) {
332
- return sanitizeId(commandName);
318
+ function generateBaseNameFromCommandRelPath(commandRelPath) {
319
+ const normalized = commandRelPath.replace(/\\/g, '/');
320
+ const withoutExt = normalized.endsWith('.md')
321
+ ? normalized.slice(0, -'.md'.length)
322
+ : normalized;
323
+ const segments = withoutExt.split('/').filter(Boolean);
324
+ return segments.map(sanitizeId).join('-');
333
325
  }
334
326
  function pluginBaseNamespacePrefix(pluginId) {
335
327
  const parsed = parsePluginId(pluginId);
@@ -338,19 +330,25 @@ function pluginBaseNamespacePrefix(pluginId) {
338
330
  return sanitizeId(pluginId);
339
331
  }
340
332
  function computePluginNamespacePrefixes(pluginIds) {
341
- const basePrefixByPluginId = new Map();
342
- const counts = new Map();
343
- for (const pluginId of pluginIds) {
344
- const base = pluginBaseNamespacePrefix(pluginId);
345
- basePrefixByPluginId.set(pluginId, base);
346
- counts.set(base, (counts.get(base) ?? 0) + 1);
347
- }
348
333
  const out = new Map();
334
+ const pluginIdsByBase = new Map();
349
335
  for (const pluginId of pluginIds) {
350
- const base = basePrefixByPluginId.get(pluginId) ?? sanitizeId(pluginId);
351
- // If multiple enabled plugins share the same pluginName, fall back to the
352
- // full pluginId for uniqueness (includes marketplace).
353
- out.set(pluginId, (counts.get(base) ?? 0) > 1 ? sanitizeId(pluginId) : base);
336
+ const base = pluginBaseNamespacePrefix(pluginId);
337
+ const bucket = pluginIdsByBase.get(base) ?? [];
338
+ bucket.push(pluginId);
339
+ pluginIdsByBase.set(base, bucket);
340
+ }
341
+ for (const [base, ids] of pluginIdsByBase.entries()) {
342
+ ids.sort((a, b) => a.localeCompare(b));
343
+ if (ids.length === 1) {
344
+ out.set(ids[0], base);
345
+ continue;
346
+ }
347
+ // If multiple enabled plugins share the same plugin name, disambiguate
348
+ // without including the marketplace in the folder name.
349
+ ids.forEach((id, idx) => {
350
+ out.set(id, idx === 0 ? base : `${base}-${idx + 1}`);
351
+ });
354
352
  }
355
353
  return out;
356
354
  }
@@ -395,8 +393,8 @@ async function removeLegacyMarkerFile(dir, dryRun) {
395
393
  // ignore
396
394
  }
397
395
  }
398
- async function loadManagedEntries(targetSkillsDir, dryRun) {
399
- const allEntries = await (0, SkillsManifest_1.loadSkillsManifestEntries)(targetSkillsDir);
396
+ async function loadManagedEntries(projectRoot, targetSkillsDir, dryRun) {
397
+ const allEntries = await (0, SkillsManifest_1.loadSkillsManifestEntries)(projectRoot, targetSkillsDir);
400
398
  const pluginEntries = [];
401
399
  const otherEntries = [];
402
400
  for (const entry of allEntries) {
@@ -501,7 +499,12 @@ async function discoverLocalCommandNames(projectRoot) {
501
499
  }
502
500
  if (!entry.isFile() || !entry.name.endsWith('.md'))
503
501
  continue;
504
- names.add(sanitizeId(path.basename(entry.name, '.md')));
502
+ const rel = path.relative(localCommandsDir, full).replace(/\\/g, '/');
503
+ const withoutExt = rel.endsWith('.md')
504
+ ? rel.slice(0, -'.md'.length)
505
+ : rel;
506
+ const segments = withoutExt.split('/').filter(Boolean);
507
+ names.add(segments.map(sanitizeId).join('-'));
505
508
  }
506
509
  }
507
510
  await walk(localCommandsDir, 0);
@@ -608,7 +611,6 @@ async function syncClaudePluginsToSkillsDirs(args) {
608
611
  }
609
612
  const claudeDir = path.join(getUserHomeDir(), '.claude');
610
613
  const index = await readInstalledPluginsIndex(claudeDir);
611
- const knownMarketplaceInstallLocations = await readKnownMarketplaceInstallLocations(claudeDir);
612
614
  const localSkillNames = await discoverLocalSkillNames(projectRoot);
613
615
  const localCommandNames = await discoverLocalCommandNames(projectRoot);
614
616
  const localAgentNames = await discoverLocalAgentNames(projectRoot);
@@ -620,10 +622,16 @@ async function syncClaudePluginsToSkillsDirs(args) {
620
622
  const resolvedSources = [];
621
623
  const unresolvedEnabled = new Set();
622
624
  for (const pluginId of enabledPlugins) {
623
- const pluginRoot = await resolvePluginMarketplaceRoot(pluginId, claudeDir, knownMarketplaceInstallLocations);
625
+ const pluginRoot = await resolvePluginMarketplaceRoot(pluginId, claudeDir);
624
626
  if (!pluginRoot) {
625
627
  unresolvedEnabled.add(pluginId);
626
- (0, constants_1.logWarn)(`[plugins] Enabled plugin not installed: ${pluginId}`, dryRun);
628
+ const hasIndexEntry = Boolean(index?.plugins?.[pluginId]?.length);
629
+ if (hasIndexEntry) {
630
+ (0, constants_1.logVerboseInfo)(`[plugins] Enabled plugin has no marketplace content, skipping: ${pluginId}`, verbose, dryRun);
631
+ }
632
+ else {
633
+ (0, constants_1.logWarn)(`[plugins] Enabled plugin not installed: ${pluginId}`, dryRun);
634
+ }
627
635
  continue;
628
636
  }
629
637
  const resolved = index
@@ -653,8 +661,8 @@ async function syncClaudePluginsToSkillsDirs(args) {
653
661
  }
654
662
  const commandFiles = await discoverPluginCommandFiles(plugin.pluginRoot);
655
663
  for (const c of commandFiles) {
656
- const baseName = generateBaseNameFromCommand(c.name);
657
- const sourceRelPath = `commands/${path.basename(c.file)}`;
664
+ const baseName = generateBaseNameFromCommandRelPath(c.rel);
665
+ const sourceRelPath = `commands/${c.rel}`;
658
666
  expectedItems.push({
659
667
  itemKey: makeItemKey(plugin.pluginId, 'command', sourceRelPath),
660
668
  pluginId: plugin.pluginId,
@@ -696,7 +704,7 @@ async function syncClaudePluginsToSkillsDirs(args) {
696
704
  let managedEntries = [];
697
705
  let otherEntries = [];
698
706
  if (targetExists) {
699
- const loaded = await loadManagedEntries(targetSkillsDir, dryRun);
707
+ const loaded = await loadManagedEntries(projectRoot, targetSkillsDir, dryRun);
700
708
  managedEntries = loaded.pluginEntries;
701
709
  otherEntries = loaded.otherEntries;
702
710
  }
@@ -859,6 +867,6 @@ async function syncClaudePluginsToSkillsDirs(args) {
859
867
  destRelPath: item.destRelPath,
860
868
  });
861
869
  }
862
- await (0, SkillsManifest_1.writeSkillsManifestEntries)(targetSkillsDir, [...otherEntries, ...nextEntries], dryRun);
870
+ await (0, SkillsManifest_1.writeSkillsManifestEntries)(projectRoot, targetSkillsDir, [...otherEntries, ...nextEntries], dryRun);
863
871
  }
864
872
  }
@@ -85,7 +85,14 @@ async function discoverCommandFiles(projectRoot) {
85
85
  }
86
86
  if (!entry.isFile() || !entry.name.endsWith('.md'))
87
87
  continue;
88
- const name = sanitizeId(path.basename(entry.name, '.md'));
88
+ const relFromCommands = path
89
+ .relative(commandsRoot, full)
90
+ .replace(/\\/g, '/');
91
+ const withoutExt = relFromCommands.endsWith('.md')
92
+ ? relFromCommands.slice(0, -'.md'.length)
93
+ : relFromCommands;
94
+ const segments = withoutExt.split('/').filter(Boolean);
95
+ const name = segments.map(sanitizeId).join('-');
89
96
  const rel = path.relative(projectRoot, full).replace(/\\/g, '/');
90
97
  results.push({ name, file: full, rel });
91
98
  }
@@ -164,9 +171,9 @@ async function writeMarkdownAsSkill(srcPath, destDir, generatedName, kindLabel,
164
171
  return;
165
172
  await fs.writeFile(path.join(destDir, 'SKILL.md'), next, 'utf8');
166
173
  }
167
- async function readPluginManagedDestNames(targetSkillsDir) {
174
+ async function readPluginManagedDestNames(projectRoot, targetSkillsDir) {
168
175
  const names = new Set();
169
- for (const entry of await (0, SkillsManifest_1.loadSkillsManifestEntries)(targetSkillsDir)) {
176
+ for (const entry of await (0, SkillsManifest_1.loadSkillsManifestEntries)(projectRoot, targetSkillsDir)) {
170
177
  if ((0, SkillsManifest_1.isPluginManifestEntry)(entry)) {
171
178
  names.add(entry.destRelPath);
172
179
  }
@@ -262,7 +269,7 @@ async function syncClaudeProjectCommandsAndAgentsToSkillsDirs(args) {
262
269
  const managedEntries = [];
263
270
  const otherEntries = [];
264
271
  if (targetExists) {
265
- const allEntries = await (0, SkillsManifest_1.loadSkillsManifestEntries)(targetSkillsDir);
272
+ const allEntries = await (0, SkillsManifest_1.loadSkillsManifestEntries)(projectRoot, targetSkillsDir);
266
273
  for (const entry of allEntries) {
267
274
  if ((0, SkillsManifest_1.isClaudeManifestEntry)(entry)) {
268
275
  managedEntries.push(entry);
@@ -278,7 +285,7 @@ async function syncClaudeProjectCommandsAndAgentsToSkillsDirs(args) {
278
285
  }
279
286
  const managedDest = new Set(managedEntries.map((e) => e.destRelPath));
280
287
  const pluginManagedDest = targetExists
281
- ? await readPluginManagedDestNames(targetSkillsDir)
288
+ ? await readPluginManagedDestNames(projectRoot, targetSkillsDir)
282
289
  : new Set();
283
290
  const reserved = new Set(localSkillNames);
284
291
  if (targetExists) {
@@ -395,6 +402,6 @@ async function syncClaudeProjectCommandsAndAgentsToSkillsDirs(args) {
395
402
  destRelPath: item.destRelPath,
396
403
  });
397
404
  }
398
- await (0, SkillsManifest_1.writeSkillsManifestEntries)(targetSkillsDir, [...otherEntries, ...nextEntries], dryRun);
405
+ await (0, SkillsManifest_1.writeSkillsManifestEntries)(projectRoot, targetSkillsDir, [...otherEntries, ...nextEntries], dryRun);
399
406
  }
400
407
  }
@@ -41,6 +41,8 @@ exports.writeSkillsManifestEntries = writeSkillsManifestEntries;
41
41
  exports.listSkillDirectories = listSkillDirectories;
42
42
  const fs = __importStar(require("fs/promises"));
43
43
  const path = __importStar(require("path"));
44
+ // Project-level manifest (stored in `.claude/.skiller.json`) that tracks what
45
+ // Skiller installed into each target agent skills directory for this project.
44
46
  exports.SKILLS_MANIFEST_FILENAME = '.skiller.json';
45
47
  exports.LEGACY_UNIFIED_SKILLS_MANIFEST_FILENAME = '.skiller-skills.json';
46
48
  exports.LEGACY_PLUGIN_MANIFEST_FILENAME = '.skiller-plugins.json';
@@ -137,6 +139,37 @@ function parseUnifiedEntries(raw) {
137
139
  }
138
140
  return entries;
139
141
  }
142
+ function normalizePathForKey(p) {
143
+ return path.resolve(p).replace(/\\/g, '/');
144
+ }
145
+ function computeTargetKey(projectRoot, targetSkillsDir) {
146
+ const resolvedProjectRoot = path.resolve(projectRoot);
147
+ const resolvedTarget = path.resolve(targetSkillsDir);
148
+ if (resolvedTarget === resolvedProjectRoot)
149
+ return '.';
150
+ if (resolvedTarget.startsWith(resolvedProjectRoot + path.sep)) {
151
+ return path
152
+ .relative(resolvedProjectRoot, resolvedTarget)
153
+ .replace(/\\/g, '/');
154
+ }
155
+ return normalizePathForKey(resolvedTarget);
156
+ }
157
+ function parseProjectTargets(raw) {
158
+ if (!raw || typeof raw !== 'object')
159
+ return {};
160
+ const obj = raw;
161
+ if (!obj.targets || typeof obj.targets !== 'object')
162
+ return {};
163
+ const targetsObj = obj.targets;
164
+ const out = {};
165
+ for (const [targetKey, rawEntries] of Object.entries(targetsObj)) {
166
+ // Stored as an array of entries per target.
167
+ if (!Array.isArray(rawEntries))
168
+ continue;
169
+ out[targetKey] = normalizeEntries(parseUnifiedEntries({ entries: rawEntries }));
170
+ }
171
+ return out;
172
+ }
140
173
  function parseLegacyPluginEntries(raw) {
141
174
  if (!raw || typeof raw !== 'object')
142
175
  return [];
@@ -197,11 +230,11 @@ function parseLegacyClaudeEntries(raw) {
197
230
  }
198
231
  return entries;
199
232
  }
200
- async function loadSkillsManifestEntries(targetSkillsDir) {
201
- const manifestPath = path.join(targetSkillsDir, exports.SKILLS_MANIFEST_FILENAME);
202
- if (await fileExists(manifestPath)) {
233
+ async function loadLegacyTargetSkillsManifestEntries(targetSkillsDir) {
234
+ const legacyManifestPath = path.join(targetSkillsDir, exports.SKILLS_MANIFEST_FILENAME);
235
+ if (await fileExists(legacyManifestPath)) {
203
236
  try {
204
- const raw = JSON.parse(await fs.readFile(manifestPath, 'utf8'));
237
+ const raw = JSON.parse(await fs.readFile(legacyManifestPath, 'utf8'));
205
238
  return normalizeEntries(parseUnifiedEntries(raw));
206
239
  }
207
240
  catch {
@@ -243,32 +276,78 @@ async function loadSkillsManifestEntries(targetSkillsDir) {
243
276
  }
244
277
  return normalizeEntries(merged);
245
278
  }
246
- async function writeSkillsManifestEntries(targetSkillsDir, entries, dryRun) {
247
- const manifestPath = path.join(targetSkillsDir, exports.SKILLS_MANIFEST_FILENAME);
248
- const legacyUnifiedPath = path.join(targetSkillsDir, exports.LEGACY_UNIFIED_SKILLS_MANIFEST_FILENAME);
249
- const legacyPluginPath = path.join(targetSkillsDir, exports.LEGACY_PLUGIN_MANIFEST_FILENAME);
250
- const legacyClaudePath = path.join(targetSkillsDir, exports.LEGACY_CLAUDE_MANIFEST_FILENAME);
279
+ async function loadSkillsManifestEntries(projectRoot, targetSkillsDir) {
280
+ const projectClaudeDir = path.join(projectRoot, '.claude');
281
+ const projectManifestPath = path.join(projectClaudeDir, exports.SKILLS_MANIFEST_FILENAME);
282
+ const preferredTargetKey = computeTargetKey(projectRoot, targetSkillsDir);
283
+ const absoluteTargetKey = normalizePathForKey(targetSkillsDir);
284
+ if (await fileExists(projectManifestPath)) {
285
+ try {
286
+ const raw = JSON.parse(await fs.readFile(projectManifestPath, 'utf8'));
287
+ const targets = parseProjectTargets(raw);
288
+ const entries = targets[preferredTargetKey] ?? targets[absoluteTargetKey] ?? [];
289
+ return normalizeEntries(entries);
290
+ }
291
+ catch {
292
+ return [];
293
+ }
294
+ }
295
+ // Legacy migration: prior versions stored manifests in the target skills dir.
296
+ return await loadLegacyTargetSkillsManifestEntries(targetSkillsDir);
297
+ }
298
+ async function writeSkillsManifestEntries(projectRoot, targetSkillsDir, entries, dryRun) {
251
299
  const normalized = normalizeEntries(entries);
300
+ const projectClaudeDir = path.join(projectRoot, '.claude');
301
+ const projectManifestPath = path.join(projectClaudeDir, exports.SKILLS_MANIFEST_FILENAME);
302
+ const preferredTargetKey = computeTargetKey(projectRoot, targetSkillsDir);
303
+ const absoluteTargetKey = normalizePathForKey(targetSkillsDir);
304
+ let existingTargets = {};
305
+ if (await fileExists(projectManifestPath)) {
306
+ try {
307
+ const raw = JSON.parse(await fs.readFile(projectManifestPath, 'utf8'));
308
+ existingTargets = parseProjectTargets(raw);
309
+ }
310
+ catch {
311
+ existingTargets = {};
312
+ }
313
+ }
252
314
  if (normalized.length === 0) {
253
- if (dryRun)
254
- return;
255
- await Promise.allSettled([
256
- fs.unlink(manifestPath),
257
- fs.unlink(legacyUnifiedPath),
258
- fs.unlink(legacyPluginPath),
259
- fs.unlink(legacyClaudePath),
260
- ]);
261
- return;
315
+ delete existingTargets[preferredTargetKey];
316
+ if (preferredTargetKey !== absoluteTargetKey) {
317
+ delete existingTargets[absoluteTargetKey];
318
+ }
319
+ }
320
+ else {
321
+ existingTargets[preferredTargetKey] = normalized;
322
+ if (preferredTargetKey !== absoluteTargetKey) {
323
+ delete existingTargets[absoluteTargetKey];
324
+ }
262
325
  }
263
- const manifest = {
264
- version: exports.SKILLS_MANIFEST_VERSION,
265
- entries: normalized,
266
- };
267
326
  if (dryRun)
268
327
  return;
269
- await fs.writeFile(manifestPath, JSON.stringify(manifest, null, 2) + '\n');
270
- // Clean up legacy manifests once unified is written.
328
+ // Ensure `.claude` exists since the manifest lives there.
329
+ await fs.mkdir(projectClaudeDir, { recursive: true });
330
+ const targetKeys = Object.keys(existingTargets).sort((a, b) => a.localeCompare(b));
331
+ if (targetKeys.length === 0) {
332
+ await Promise.allSettled([fs.unlink(projectManifestPath)]);
333
+ }
334
+ else {
335
+ const nextTargets = {};
336
+ for (const key of targetKeys)
337
+ nextTargets[key] = existingTargets[key];
338
+ const manifest = {
339
+ version: exports.SKILLS_MANIFEST_VERSION,
340
+ targets: nextTargets,
341
+ };
342
+ await fs.writeFile(projectManifestPath, JSON.stringify(manifest, null, 2) + '\n');
343
+ }
344
+ // Remove legacy per-target manifests so users see a single `.claude/.skiller.json`.
345
+ const legacyManifestPath = path.join(targetSkillsDir, exports.SKILLS_MANIFEST_FILENAME);
346
+ const legacyUnifiedPath = path.join(targetSkillsDir, exports.LEGACY_UNIFIED_SKILLS_MANIFEST_FILENAME);
347
+ const legacyPluginPath = path.join(targetSkillsDir, exports.LEGACY_PLUGIN_MANIFEST_FILENAME);
348
+ const legacyClaudePath = path.join(targetSkillsDir, exports.LEGACY_CLAUDE_MANIFEST_FILENAME);
271
349
  await Promise.allSettled([
350
+ fs.unlink(legacyManifestPath),
272
351
  fs.unlink(legacyUnifiedPath),
273
352
  fs.unlink(legacyPluginPath),
274
353
  fs.unlink(legacyClaudePath),
@@ -512,9 +512,13 @@ async function applyStandardMcpConfiguration(agent, filteredMcpJson, dest, agent
512
512
  (0, constants_1.logVerbose)(`DRY RUN: Would apply MCP config to: ${dest}`, verbose);
513
513
  }
514
514
  else {
515
- // Transform MCP config for agent-specific compatibility
515
+ // Transform MCP config for compatibility.
516
+ //
517
+ // `.mcp.json` is shared (Claude Code + others). Keep it Claude-compatible
518
+ // so later agents don't overwrite `http|sse` back to legacy `remote`.
516
519
  let mcpToMerge = filteredMcpJson;
517
- if (agent.getIdentifier() === 'claude') {
520
+ if (agent.getIdentifier() === 'claude' ||
521
+ path.basename(dest) === '.mcp.json') {
518
522
  mcpToMerge = transformMcpForClaude(filteredMcpJson);
519
523
  }
520
524
  else if (agent.getIdentifier() === 'kilocode') {
package/package.json CHANGED
@@ -1,79 +1,78 @@
1
1
  {
2
- "name": "skiller",
3
- "version": "0.7.19",
4
- "description": "Skiller — apply the same rules to all coding agents",
5
- "main": "dist/lib.js",
6
- "publishConfig": {
7
- "access": "public"
8
- },
9
- "scripts": {
10
- "postinstall": "[ -n \"$CI\" ] || npx skiller@latest apply",
11
- "lint": "eslint \"src/**/*.{ts,tsx}\"",
12
- "lint:fix": "eslint \"src/**/*.{ts,tsx}\" --fix",
13
- "format": "prettier --write \"src/**/*.{ts,tsx,json,md}\"",
14
- "test": "jest",
15
- "test:watch": "jest --watch",
16
- "test:coverage": "jest --coverage",
17
- "test:integration": "jest tests/e2e/skiller.integration.test.ts --verbose",
18
- "build": "tsc",
19
- "release": "pnpm build && pnpm changeset publish"
20
- },
21
- "repository": {
22
- "type": "git",
23
- "url": "git+https://github.com/udecode/skiller.git"
24
- },
25
- "keywords": [
26
- "ai",
27
- "developer-tools",
28
- "copilot",
29
- "codex",
30
- "claude",
31
- "cursor",
32
- "aider",
33
- "config",
34
- "rules",
35
- "automation"
36
- ],
37
- "author": "Eleanor Berger",
38
- "license": "MIT",
39
- "bugs": {
40
- "url": "https://github.com/udecode/skiller/issues"
41
- },
42
- "engines": {
43
- "node": ">=18"
44
- },
45
- "files": [
46
- "dist",
47
- "README.md",
48
- "LICENSE"
49
- ],
50
- "bin": {
51
- "skiller": "dist/cli/index.js"
52
- },
53
- "devDependencies": {
54
- "@changesets/changelog-github": "^0.5.2",
55
- "@changesets/cli": "2.29.8",
56
- "@eslint/js": "^9.39.1",
57
- "@types/iarna__toml": "^2.0.5",
58
- "@types/jest": "^29.5.14",
59
- "@types/js-yaml": "^4.0.9",
60
- "@types/node": "^24.9.2",
61
- "@types/yargs": "^17.0.34",
62
- "@typescript-eslint/eslint-plugin": "^8.46.2",
63
- "@typescript-eslint/parser": "^8.46.2",
64
- "eslint": "^9.38.0",
65
- "eslint-config-prettier": "^10.1.8",
66
- "eslint-plugin-prettier": "^5.5.4",
67
- "jest": "^29.7.0",
68
- "prettier": "^3.6.2",
69
- "ts-jest": "^29.4.5",
70
- "typescript": "^5.9.3",
71
- "typescript-eslint": "^8.46.2"
72
- },
73
- "dependencies": {
74
- "@iarna/toml": "^2.2.5",
75
- "js-yaml": "^4.1.0",
76
- "yargs": "^18.0.0",
77
- "zod": "^4.1.12"
78
- }
2
+ "name": "skiller",
3
+ "version": "0.7.21",
4
+ "description": "Skiller — apply the same rules to all coding agents",
5
+ "main": "dist/lib.js",
6
+ "publishConfig": {
7
+ "access": "public"
8
+ },
9
+ "scripts": {
10
+ "lint": "eslint \"src/**/*.{ts,tsx}\"",
11
+ "lint:fix": "eslint \"src/**/*.{ts,tsx}\" --fix",
12
+ "format": "prettier --write \"src/**/*.{ts,tsx,json,md}\"",
13
+ "test": "jest",
14
+ "test:watch": "jest --watch",
15
+ "test:coverage": "jest --coverage",
16
+ "test:integration": "jest tests/e2e/skiller.integration.test.ts --verbose",
17
+ "build": "tsc",
18
+ "release": "pnpm build && pnpm changeset publish"
19
+ },
20
+ "repository": {
21
+ "type": "git",
22
+ "url": "git+https://github.com/udecode/skiller.git"
23
+ },
24
+ "keywords": [
25
+ "ai",
26
+ "developer-tools",
27
+ "copilot",
28
+ "codex",
29
+ "claude",
30
+ "cursor",
31
+ "aider",
32
+ "config",
33
+ "rules",
34
+ "automation"
35
+ ],
36
+ "author": "Eleanor Berger",
37
+ "license": "MIT",
38
+ "bugs": {
39
+ "url": "https://github.com/udecode/skiller/issues"
40
+ },
41
+ "engines": {
42
+ "node": ">=18"
43
+ },
44
+ "files": [
45
+ "dist",
46
+ "README.md",
47
+ "LICENSE"
48
+ ],
49
+ "bin": {
50
+ "skiller": "dist/cli/index.js"
51
+ },
52
+ "devDependencies": {
53
+ "@changesets/changelog-github": "^0.5.2",
54
+ "@changesets/cli": "2.29.8",
55
+ "@eslint/js": "^9.39.1",
56
+ "@types/iarna__toml": "^2.0.5",
57
+ "@types/jest": "^29.5.14",
58
+ "@types/js-yaml": "^4.0.9",
59
+ "@types/node": "^24.9.2",
60
+ "@types/yargs": "^17.0.34",
61
+ "@typescript-eslint/eslint-plugin": "^8.46.2",
62
+ "@typescript-eslint/parser": "^8.46.2",
63
+ "eslint": "^9.38.0",
64
+ "eslint-config-prettier": "^10.1.8",
65
+ "eslint-plugin-prettier": "^5.5.4",
66
+ "jest": "^29.7.0",
67
+ "prettier": "^3.6.2",
68
+ "ts-jest": "^29.4.5",
69
+ "typescript": "^5.9.3",
70
+ "typescript-eslint": "^8.46.2"
71
+ },
72
+ "dependencies": {
73
+ "@iarna/toml": "^2.2.5",
74
+ "js-yaml": "^4.1.0",
75
+ "yargs": "^18.0.0",
76
+ "zod": "^4.1.12"
77
+ }
79
78
  }