skiller 0.5.0 → 0.5.1

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.
@@ -68,7 +68,7 @@ async function discoverSkills(projectRoot, skillerDir) {
68
68
  * Gets the paths that skills will generate, for gitignore purposes.
69
69
  * Returns empty array if skills directory doesn't exist.
70
70
  */
71
- async function getSkillsGitignorePaths(projectRoot) {
71
+ async function getSkillsGitignorePaths(projectRoot, options = {}) {
72
72
  const claudeSkillsDir = path.join(projectRoot, constants_1.CLAUDE_SKILLS_PATH);
73
73
  // Check if skills directory exists
74
74
  let skillsExist = false;
@@ -83,16 +83,24 @@ async function getSkillsGitignorePaths(projectRoot) {
83
83
  return [];
84
84
  }
85
85
  const paths = [];
86
- // When using .claude/skills, check if it's generated from .claude/rules
87
- // If .claude/rules exists, then .claude/skills is generated and should be gitignored
88
- const claudeRulesDir = path.join(projectRoot, '.claude', 'rules');
89
- try {
90
- await fs.access(claudeRulesDir);
91
- // .claude/rules exists, so .claude/skills is generated
86
+ // Gitignore .claude/skills if:
87
+ // 1. generate_from_rules is explicitly true in config, OR
88
+ // 2. .claude/rules directory exists (skills are generated from rules)
89
+ if (options.generateFromRules) {
90
+ // Config says skills are generated from rules
92
91
  paths.push(path.join(projectRoot, constants_1.CLAUDE_SKILLS_PATH));
93
92
  }
94
- catch {
95
- // .claude/rules doesn't exist, so .claude/skills is versioned (don't gitignore)
93
+ else {
94
+ // Check if .claude/rules exists (fallback for when config not passed)
95
+ const claudeRulesDir = path.join(projectRoot, '.claude', 'rules');
96
+ try {
97
+ await fs.access(claudeRulesDir);
98
+ // .claude/rules exists, so .claude/skills is generated
99
+ paths.push(path.join(projectRoot, constants_1.CLAUDE_SKILLS_PATH));
100
+ }
101
+ catch {
102
+ // .claude/rules doesn't exist, so .claude/skills is versioned (don't gitignore)
103
+ }
96
104
  }
97
105
  // Always gitignore .skillz (for MCP agents)
98
106
  paths.push(path.join(projectRoot, constants_1.SKILLZ_DIR));
@@ -408,10 +408,16 @@ async function handleMcpConfiguration(agent, agentConfig, config, skillerMcpJson
408
408
  typeof filteredMcpJson.mcpServers === 'object') {
409
409
  const mcpServers = { ...filteredMcpJson.mcpServers };
410
410
  delete mcpServers[SKILLZ_MCP_SERVER_NAME];
411
- filteredMcpJson = {
412
- ...filteredMcpJson,
413
- mcpServers,
414
- };
411
+ // If no servers remain after removal, set to null to skip file generation
412
+ if (Object.keys(mcpServers).length === 0) {
413
+ filteredMcpJson = null;
414
+ }
415
+ else {
416
+ filteredMcpJson = {
417
+ ...filteredMcpJson,
418
+ mcpServers,
419
+ };
420
+ }
415
421
  (0, constants_1.logVerboseInfo)(`Removed Skillz MCP server for ${agent.getName()} (has native skills support)`, verbose, dryRun);
416
422
  }
417
423
  }
@@ -448,12 +454,19 @@ async function handleMcpConfiguration(agent, agentConfig, config, skillerMcpJson
448
454
  // No .skillz directory, skip adding Skillz server
449
455
  }
450
456
  }
451
- if (!filteredMcpJson) {
457
+ // Skip if no MCP config or if mcpServers is empty
458
+ const hasServers = filteredMcpJson &&
459
+ filteredMcpJson.mcpServers &&
460
+ typeof filteredMcpJson.mcpServers === 'object' &&
461
+ Object.keys(filteredMcpJson.mcpServers).length >
462
+ 0;
463
+ if (!hasServers) {
452
464
  (0, constants_1.logVerbose)(`No compatible MCP servers found for ${agent.getName()} - skipping MCP configuration`, verbose);
453
465
  return;
454
466
  }
455
467
  await updateGitignoreForMcpFile(dest, projectRoot, generatedPaths, backup);
456
- await applyMcpConfiguration(agent, filteredMcpJson, dest, agentConfig, config, projectRoot, cliMcpStrategy, dryRun, verbose, backup);
468
+ await applyMcpConfiguration(agent, filteredMcpJson, // Safe: hasServers check above ensures this is non-null
469
+ dest, agentConfig, config, projectRoot, cliMcpStrategy, dryRun, verbose, backup);
457
470
  }
458
471
  async function updateGitignoreForMcpFile(dest, projectRoot, generatedPaths, backup = true) {
459
472
  if (dest.startsWith(projectRoot)) {
package/dist/lib.js CHANGED
@@ -156,7 +156,10 @@ async function applyAllAgentConfigs(projectRoot, includedAgents, configPath, cli
156
156
  if (skillsEnabledForGitignore) {
157
157
  // Skills enabled by default or explicitly
158
158
  const { getSkillsGitignorePaths } = await Promise.resolve().then(() => __importStar(require('./core/SkillsProcessor')));
159
- const skillsPaths = await getSkillsGitignorePaths(projectRoot);
159
+ const generateFromRules = loadedConfig.skills?.generate_from_rules ?? false;
160
+ const skillsPaths = await getSkillsGitignorePaths(projectRoot, {
161
+ generateFromRules,
162
+ });
160
163
  allGeneratedPaths = [...generatedPaths, ...skillsPaths];
161
164
  }
162
165
  await (0, apply_engine_1.updateGitignore)(projectRoot, allGeneratedPaths, loadedConfig, cliGitignoreEnabled, dryRun);
package/package.json CHANGED
@@ -1,12 +1,13 @@
1
1
  {
2
2
  "name": "skiller",
3
- "version": "0.5.0",
3
+ "version": "0.5.1",
4
4
  "description": "Skiller — apply the same rules to all coding agents",
5
5
  "main": "dist/lib.js",
6
6
  "publishConfig": {
7
7
  "access": "public"
8
8
  },
9
9
  "scripts": {
10
+ "postinstall": "npx skiller@latest apply",
10
11
  "lint": "eslint \"src/**/*.{ts,tsx}\"",
11
12
  "lint:fix": "eslint \"src/**/*.{ts,tsx}\" --fix",
12
13
  "format": "prettier --write \"src/**/*.{ts,tsx,json,md}\"",