claude-skill-lord 1.5.0 → 1.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.
- package/.claude-plugin/marketplace.json +4 -4
- package/.claude-plugin/plugin.json +7 -6
- package/README.md +6 -6
- package/manifests/install-modules.json +6 -24
- package/manifests/install-profiles.json +2 -15
- package/package.json +1 -1
- package/scripts/install.js +22 -45
- package/scripts/lib/profile-utils.js +6 -17
- package/scripts/sl.js +35 -232
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://anthropic.com/claude-code/marketplace.schema.json",
|
|
3
|
-
"name": "
|
|
3
|
+
"name": "claude-skill-lord",
|
|
4
4
|
"owner": {
|
|
5
5
|
"name": "Dong Anh",
|
|
6
6
|
"email": "donganhvu20@gmail.com"
|
|
7
7
|
},
|
|
8
8
|
"plugins": [
|
|
9
9
|
{
|
|
10
|
-
"name": "
|
|
10
|
+
"name": "claude-skill-lord",
|
|
11
11
|
"source": "./",
|
|
12
|
-
"description": "Curated
|
|
13
|
-
"version": "1.
|
|
12
|
+
"description": "Curated Claude Code plugin — 22 agents, 61 skills, 40+ commands with intelligent skill routing and UI/UX design intelligence",
|
|
13
|
+
"version": "1.5.1",
|
|
14
14
|
"category": "workflow",
|
|
15
15
|
"tags": ["agents", "skills", "commands", "hooks", "skill-routing", "quality-gate", "tdd", "code-review"],
|
|
16
16
|
"strict": false
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
{
|
|
2
|
-
"name": "
|
|
3
|
-
"version": "1.
|
|
4
|
-
"description": "Curated
|
|
2
|
+
"name": "claude-skill-lord",
|
|
3
|
+
"version": "1.5.1",
|
|
4
|
+
"description": "Curated Claude Code plugin — 22 agents, 61 skills, 40+ commands with intelligent skill routing and UI/UX design intelligence",
|
|
5
5
|
"author": {
|
|
6
|
-
"name": "
|
|
6
|
+
"name": "Dong Anh",
|
|
7
|
+
"email": "donganhvu20@gmail.com"
|
|
7
8
|
},
|
|
8
|
-
"homepage": "https://github.com/
|
|
9
|
-
"repository": "https://github.com/
|
|
9
|
+
"homepage": "https://github.com/donganhvuphp/Claude-Skills-Lord",
|
|
10
|
+
"repository": "https://github.com/donganhvuphp/Claude-Skills-Lord",
|
|
10
11
|
"license": "MIT",
|
|
11
12
|
"keywords": [
|
|
12
13
|
"claude-code",
|
package/README.md
CHANGED
|
@@ -41,16 +41,17 @@ That's it. `csl init` copies skills, agents, and commands into `.claude/` and ge
|
|
|
41
41
|
|
|
42
42
|
```bash
|
|
43
43
|
csl init # interactive setup (asks profile + target)
|
|
44
|
-
csl init full # install everything (61 skills)
|
|
45
|
-
csl init core # lightweight setup (16 skills)
|
|
44
|
+
csl init full # install everything (61 skills + canvas fonts)
|
|
46
45
|
csl init --dry-run # preview without copying
|
|
47
46
|
csl init --fresh # clean reinstall
|
|
47
|
+
csl upgrade full # upgrade to full profile (additive, no overwrites)
|
|
48
48
|
csl update # update CLI to latest version
|
|
49
49
|
csl migrate # update project files after csl update
|
|
50
50
|
csl migrate --dry-run # preview what would change
|
|
51
|
+
csl diff # compare project files with source package
|
|
51
52
|
csl uninstall # remove from current project
|
|
52
53
|
csl doctor # check health + available updates
|
|
53
|
-
csl list # show all components
|
|
54
|
+
csl list # show all components with install status
|
|
54
55
|
```
|
|
55
56
|
|
|
56
57
|
### Alternative: per-project install
|
|
@@ -74,9 +75,8 @@ node scripts/sl.js init full --target /path/to/your/project
|
|
|
74
75
|
|
|
75
76
|
| Profile | Skills | Agents | Best For |
|
|
76
77
|
|---------|--------|--------|----------|
|
|
77
|
-
| `
|
|
78
|
-
| `
|
|
79
|
-
| `full` | 61 (all tiers) | 22 all | Multi-language, enterprise |
|
|
78
|
+
| `developer` | 44 (Tier 1+2) | 22 all | Recommended for all projects (default) |
|
|
79
|
+
| `full` | 61 (all tiers) | 22 all + canvas fonts | Multi-language, design, enterprise |
|
|
80
80
|
|
|
81
81
|
---
|
|
82
82
|
|
|
@@ -1,42 +1,24 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version":
|
|
2
|
+
"version": 2,
|
|
3
3
|
"modules": [
|
|
4
4
|
{
|
|
5
|
-
"id": "agents
|
|
5
|
+
"id": "agents",
|
|
6
6
|
"kind": "agents",
|
|
7
|
-
"description": "
|
|
8
|
-
"paths": ["agents/
|
|
7
|
+
"description": "All 22 agents — planner, code-reviewer, debugger, architect, security, scout, and more",
|
|
8
|
+
"paths": ["agents/"],
|
|
9
9
|
"defaultInstall": true,
|
|
10
|
-
"cost": "light",
|
|
11
|
-
"stability": "stable"
|
|
12
|
-
},
|
|
13
|
-
{
|
|
14
|
-
"id": "agents-extended",
|
|
15
|
-
"kind": "agents",
|
|
16
|
-
"description": "Extended agents — architect, security, e2e, refactor, loop, router, gate",
|
|
17
|
-
"paths": ["agents/architect.md", "agents/security-reviewer.md", "agents/e2e-runner.md", "agents/refactor-cleaner.md", "agents/loop-operator.md", "agents/skill-router.md", "agents/quality-gate.md", "agents/chief-of-staff.md", "agents/harness-optimizer.md", "agents/build-error-resolver.md", "agents/project-manager.md", "agents/ui-ux-designer.md", "agents/database-admin.md", "agents/brainstormer.md", "agents/copywriter.md"],
|
|
18
|
-
"defaultInstall": false,
|
|
19
10
|
"cost": "medium",
|
|
20
11
|
"stability": "stable"
|
|
21
12
|
},
|
|
22
13
|
{
|
|
23
|
-
"id": "commands
|
|
14
|
+
"id": "commands",
|
|
24
15
|
"kind": "commands",
|
|
25
|
-
"description": "
|
|
16
|
+
"description": "All commands — plan, code, test, fix, cook, design, bootstrap, and more",
|
|
26
17
|
"paths": ["commands/"],
|
|
27
18
|
"defaultInstall": true,
|
|
28
19
|
"cost": "light",
|
|
29
20
|
"stability": "stable"
|
|
30
21
|
},
|
|
31
|
-
{
|
|
32
|
-
"id": "commands-extended",
|
|
33
|
-
"kind": "commands",
|
|
34
|
-
"description": "Extended commands — design, bootstrap, evolve, learn, tdd, e2e",
|
|
35
|
-
"paths": ["commands/"],
|
|
36
|
-
"defaultInstall": false,
|
|
37
|
-
"cost": "light",
|
|
38
|
-
"stability": "stable"
|
|
39
|
-
},
|
|
40
22
|
{
|
|
41
23
|
"id": "skills-tier-1",
|
|
42
24
|
"kind": "skills",
|
|
@@ -1,17 +1,4 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version":
|
|
3
|
-
"
|
|
4
|
-
"core": {
|
|
5
|
-
"description": "Essential development skills — debugging, testing, code review, security",
|
|
6
|
-
"modules": ["agents-core", "commands-core", "skills-tier-1", "hooks-essential", "workflows"]
|
|
7
|
-
},
|
|
8
|
-
"developer": {
|
|
9
|
-
"description": "Full development toolkit — core + frameworks, patterns, CI/CD",
|
|
10
|
-
"modules": ["agents-core", "agents-extended", "commands-core", "commands-extended", "skills-tier-1", "skills-tier-2", "hooks-essential", "workflows"]
|
|
11
|
-
},
|
|
12
|
-
"full": {
|
|
13
|
-
"description": "Complete SkillLord — all skills, all agents, all commands",
|
|
14
|
-
"modules": ["agents-core", "agents-extended", "commands-core", "commands-extended", "skills-tier-1", "skills-tier-2", "skills-tier-3", "canvas-fonts", "hooks-essential", "workflows"]
|
|
15
|
-
}
|
|
16
|
-
}
|
|
2
|
+
"version": 3,
|
|
3
|
+
"modules": ["agents", "commands", "skills-tier-1", "skills-tier-2", "skills-tier-3", "canvas-fonts", "hooks-essential", "workflows"]
|
|
17
4
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "claude-skill-lord",
|
|
3
|
-
"version": "1.5.
|
|
3
|
+
"version": "1.5.1",
|
|
4
4
|
"description": "Curated best-of-both Claude Code plugin — 22 agents, 61 tiered skills, 40+ commands with intelligent skill routing and UI/UX design intelligence",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Dong Anh",
|
package/scripts/install.js
CHANGED
|
@@ -1,17 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
*
|
|
4
|
+
* Claude Skill Lord Installer
|
|
5
5
|
*
|
|
6
|
-
* Usage:
|
|
7
|
-
* skilllord-install [profile] [--target <path>] [--dry-run]
|
|
8
|
-
*
|
|
9
|
-
* Profiles: core, developer, full (default: developer)
|
|
10
|
-
*
|
|
11
|
-
* Examples:
|
|
12
|
-
* skilllord-install core
|
|
13
|
-
* skilllord-install full --target ./my-project
|
|
14
|
-
* skilllord-install developer --dry-run
|
|
6
|
+
* Usage: csl init [--target <path>] [--dry-run] [--no-fonts]
|
|
15
7
|
*/
|
|
16
8
|
|
|
17
9
|
const fs = require('fs');
|
|
@@ -20,34 +12,29 @@ const path = require('path');
|
|
|
20
12
|
// Parse CLI args
|
|
21
13
|
const args = process.argv.slice(2);
|
|
22
14
|
const flags = {};
|
|
23
|
-
let profile = 'developer';
|
|
24
15
|
|
|
25
16
|
for (let i = 0; i < args.length; i++) {
|
|
26
17
|
if (args[i] === '--target' && args[i + 1]) {
|
|
27
18
|
flags.target = args[++i];
|
|
28
19
|
} else if (args[i] === '--dry-run') {
|
|
29
20
|
flags.dryRun = true;
|
|
21
|
+
} else if (args[i] === '--no-fonts') {
|
|
22
|
+
flags.noFonts = true;
|
|
30
23
|
} else if (args[i] === '--help' || args[i] === '-h') {
|
|
31
24
|
flags.help = true;
|
|
32
|
-
} else if (!args[i].startsWith('-')) {
|
|
33
|
-
profile = args[i];
|
|
34
25
|
}
|
|
35
26
|
}
|
|
36
27
|
|
|
37
28
|
if (flags.help) {
|
|
38
29
|
console.log(`
|
|
39
|
-
Claude Skill Lord Installer
|
|
30
|
+
Claude Skill Lord Installer
|
|
40
31
|
|
|
41
|
-
Usage: csl init [
|
|
42
|
-
|
|
43
|
-
Profiles:
|
|
44
|
-
core 16 tier-1 skills, 7 agents (lightweight)
|
|
45
|
-
developer 44 skills (tier-1+2), 22 agents (recommended)
|
|
46
|
-
full 61 skills (all tiers), 22 agents (everything)
|
|
32
|
+
Usage: csl init [options]
|
|
47
33
|
|
|
48
34
|
Options:
|
|
49
35
|
--target <path> Target project directory (default: current directory)
|
|
50
36
|
--dry-run Show what would be installed without copying
|
|
37
|
+
--no-fonts Skip canvas font files (~7MB)
|
|
51
38
|
--help, -h Show this help
|
|
52
39
|
`);
|
|
53
40
|
process.exit(0);
|
|
@@ -58,39 +45,33 @@ const skillLordRoot = path.resolve(__dirname, '..');
|
|
|
58
45
|
const targetDir = path.resolve(flags.target || process.cwd());
|
|
59
46
|
const targetClaudeDir = path.join(targetDir, '.claude');
|
|
60
47
|
|
|
61
|
-
// Load
|
|
62
|
-
const
|
|
48
|
+
// Load manifest
|
|
49
|
+
const { collectModuleFiles, buildPluginJson } = require('./lib/profile-utils');
|
|
50
|
+
const manifestPath = path.join(skillLordRoot, 'manifests', 'install-profiles.json');
|
|
63
51
|
const modulesPath = path.join(skillLordRoot, 'manifests', 'install-modules.json');
|
|
64
52
|
|
|
65
|
-
if (!fs.existsSync(
|
|
53
|
+
if (!fs.existsSync(manifestPath) || !fs.existsSync(modulesPath)) {
|
|
66
54
|
console.error('Error: Manifest files not found. Ensure SkillLord is properly installed.');
|
|
67
55
|
process.exit(1);
|
|
68
56
|
}
|
|
69
57
|
|
|
70
|
-
const
|
|
58
|
+
const manifest = JSON.parse(fs.readFileSync(manifestPath, 'utf8'));
|
|
71
59
|
const modules = JSON.parse(fs.readFileSync(modulesPath, 'utf8'));
|
|
72
60
|
|
|
73
|
-
|
|
74
|
-
if (
|
|
75
|
-
|
|
76
|
-
console.error(`Available profiles: ${Object.keys(profiles.profiles).join(', ')}`);
|
|
77
|
-
process.exit(1);
|
|
61
|
+
let moduleIds = manifest.modules;
|
|
62
|
+
if (flags.noFonts) {
|
|
63
|
+
moduleIds = moduleIds.filter(id => id !== 'canvas-fonts');
|
|
78
64
|
}
|
|
79
65
|
|
|
66
|
+
const selectedModules = modules.modules.filter(m => moduleIds.includes(m.id));
|
|
67
|
+
|
|
80
68
|
const pkg = require(path.join(skillLordRoot, 'package.json'));
|
|
81
|
-
console.log(`\n Claude Skill Lord
|
|
69
|
+
console.log(`\n Claude Skill Lord v${pkg.version}`);
|
|
82
70
|
console.log(` ${'='.repeat(38)}\n`);
|
|
83
|
-
console.log(` Profile: ${profile}`);
|
|
84
|
-
console.log(` Desc: ${selectedProfile.description}`);
|
|
85
71
|
console.log(` Target: ${targetDir}`);
|
|
72
|
+
if (flags.noFonts) console.log(` Fonts: skipped (--no-fonts)`);
|
|
86
73
|
console.log(` Dry run: ${flags.dryRun ? 'yes' : 'no'}\n`);
|
|
87
74
|
|
|
88
|
-
// Resolve modules for selected profile
|
|
89
|
-
const { collectModuleFiles } = require('./lib/profile-utils');
|
|
90
|
-
const selectedModules = modules.modules.filter(
|
|
91
|
-
(m) => selectedProfile.modules.includes(m.id)
|
|
92
|
-
);
|
|
93
|
-
|
|
94
75
|
// Collect all files to copy
|
|
95
76
|
for (const mod of selectedModules) {
|
|
96
77
|
console.log(` [${mod.cost}] ${mod.id}: ${mod.description}`);
|
|
@@ -116,12 +97,10 @@ for (const f of filesToCopy) {
|
|
|
116
97
|
const destPath = path.join(targetClaudeDir, f.rel);
|
|
117
98
|
const destDir = path.dirname(destPath);
|
|
118
99
|
|
|
119
|
-
// Create directory if needed
|
|
120
100
|
if (!fs.existsSync(destDir)) {
|
|
121
101
|
fs.mkdirSync(destDir, { recursive: true });
|
|
122
102
|
}
|
|
123
103
|
|
|
124
|
-
// Copy file (don't overwrite existing)
|
|
125
104
|
if (fs.existsSync(destPath)) {
|
|
126
105
|
skipped++;
|
|
127
106
|
} else {
|
|
@@ -130,15 +109,13 @@ for (const f of filesToCopy) {
|
|
|
130
109
|
}
|
|
131
110
|
}
|
|
132
111
|
|
|
133
|
-
// Generate plugin.json
|
|
134
|
-
const { buildPluginJson } = require('./lib/profile-utils');
|
|
112
|
+
// Generate plugin.json
|
|
135
113
|
const pluginJsonPath = path.join(targetClaudeDir, 'plugin.json');
|
|
136
|
-
const pluginJson = buildPluginJson(
|
|
114
|
+
const pluginJson = buildPluginJson('full', filesToCopy, pkg.version);
|
|
137
115
|
fs.writeFileSync(pluginJsonPath, JSON.stringify(pluginJson, null, 2));
|
|
138
116
|
console.log(`\n Generated: .claude/plugin.json`);
|
|
139
117
|
|
|
140
118
|
console.log(`\n Installation complete!`);
|
|
141
119
|
console.log(` Copied: ${copied} files`);
|
|
142
|
-
console.log(` Skipped: ${skipped} files (already exist)`);
|
|
120
|
+
if (skipped > 0) console.log(` Skipped: ${skipped} files (already exist)`);
|
|
143
121
|
console.log(`\n Run "claude" in your project to start using Claude Skill Lord.\n`);
|
|
144
|
-
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Shared utilities for
|
|
3
|
-
* Used by: install.js, sl.js (migrate,
|
|
2
|
+
* Shared utilities for installation and plugin.json generation.
|
|
3
|
+
* Used by: install.js, sl.js (migrate, doctor, list, diff)
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
const fs = require('fs');
|
|
@@ -9,19 +9,9 @@ const path = require('path');
|
|
|
9
9
|
const rootDir = path.resolve(__dirname, '..', '..');
|
|
10
10
|
|
|
11
11
|
function loadManifests() {
|
|
12
|
-
const
|
|
12
|
+
const manifest = JSON.parse(fs.readFileSync(path.join(rootDir, 'manifests', 'install-profiles.json'), 'utf8'));
|
|
13
13
|
const modules = JSON.parse(fs.readFileSync(path.join(rootDir, 'manifests', 'install-modules.json'), 'utf8'));
|
|
14
|
-
return {
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
function detectInstalledProfile(claudeDir) {
|
|
18
|
-
const skillsDir = path.join(claudeDir, 'skills');
|
|
19
|
-
if (!fs.existsSync(skillsDir)) return null;
|
|
20
|
-
const dirs = fs.readdirSync(skillsDir, { withFileTypes: true })
|
|
21
|
-
.filter(e => e.isDirectory()).map(e => e.name);
|
|
22
|
-
if (dirs.includes('tier-3')) return 'full';
|
|
23
|
-
if (dirs.includes('tier-2')) return 'developer';
|
|
24
|
-
return 'core';
|
|
14
|
+
return { manifest, modules };
|
|
25
15
|
}
|
|
26
16
|
|
|
27
17
|
function buildPluginJson(profile, filesToCopy, version) {
|
|
@@ -40,8 +30,7 @@ function buildPluginJson(profile, filesToCopy, version) {
|
|
|
40
30
|
return {
|
|
41
31
|
name: 'claude-skill-lord',
|
|
42
32
|
version,
|
|
43
|
-
|
|
44
|
-
description: `Claude Skill Lord (${profile} profile)`,
|
|
33
|
+
description: `Claude Skill Lord v${version}`,
|
|
45
34
|
agents: agentFiles,
|
|
46
35
|
commands: ['./commands/'],
|
|
47
36
|
skills: [...skillDirs],
|
|
@@ -94,4 +83,4 @@ function collectModuleFiles(selectedModules) {
|
|
|
94
83
|
return filesToCopy;
|
|
95
84
|
}
|
|
96
85
|
|
|
97
|
-
module.exports = { loadManifests,
|
|
86
|
+
module.exports = { loadManifests, buildPluginJson, readPluginJson, collectFiles, collectModuleFiles };
|
package/scripts/sl.js
CHANGED
|
@@ -45,40 +45,14 @@ const commands = {
|
|
|
45
45
|
console.log(`Claude Skill Lord v${getInstalledVersion()}`);
|
|
46
46
|
},
|
|
47
47
|
|
|
48
|
-
init:
|
|
49
|
-
let profile = subArgs.find(a => !a.startsWith('-')) || null;
|
|
48
|
+
init: () => {
|
|
50
49
|
const hasTarget = subArgs.includes('--target');
|
|
51
50
|
const dryRun = subArgs.includes('--dry-run');
|
|
52
51
|
const fresh = subArgs.includes('--fresh');
|
|
52
|
+
const noFonts = subArgs.includes('--no-fonts');
|
|
53
53
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
console.log(`\n Claude Skill Lord — Project Setup\n`);
|
|
57
|
-
console.log(' Profiles:');
|
|
58
|
-
console.log(' 1) core — 16 skills, 7 agents (lightweight)');
|
|
59
|
-
console.log(' 2) developer — 44 skills, 22 agents (recommended)');
|
|
60
|
-
console.log(' 3) full — 61 skills, 22 agents (everything)\n');
|
|
61
|
-
|
|
62
|
-
const choice = await ask(' Choose profile [1/2/3] (default: 2): ');
|
|
63
|
-
profile = { '1': 'core', '2': 'developer', '3': 'full' }[choice] || 'developer';
|
|
64
|
-
|
|
65
|
-
const confirmTarget = await ask(` Target directory [.]: `);
|
|
66
|
-
const target = confirmTarget || '.';
|
|
67
|
-
|
|
68
|
-
const confirm = await ask(`\n Install "${profile}" profile to "${path.resolve(target)}"? [Y/n]: `);
|
|
69
|
-
if (confirm.toLowerCase() === 'n') {
|
|
70
|
-
console.log(' Cancelled.\n');
|
|
71
|
-
return;
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
process.argv = ['node', 'install.js', profile, '--target', target];
|
|
75
|
-
if (dryRun) process.argv.push('--dry-run');
|
|
76
|
-
if (fresh) process.argv.push('--fresh');
|
|
77
|
-
} else {
|
|
78
|
-
profile = profile || 'developer';
|
|
79
|
-
const initArgs = hasTarget ? subArgs : [...subArgs, '--target', '.'];
|
|
80
|
-
process.argv = ['node', 'install.js', ...initArgs];
|
|
81
|
-
}
|
|
54
|
+
const initArgs = hasTarget ? subArgs : [...subArgs, '--target', '.'];
|
|
55
|
+
process.argv = ['node', 'install.js', ...initArgs];
|
|
82
56
|
|
|
83
57
|
// Handle --fresh: remove existing .claude/ before install
|
|
84
58
|
if (fresh) {
|
|
@@ -91,44 +65,17 @@ const commands = {
|
|
|
91
65
|
}
|
|
92
66
|
}
|
|
93
67
|
|
|
94
|
-
//
|
|
68
|
+
// Check existing installation
|
|
95
69
|
if (!fresh && !dryRun) {
|
|
96
|
-
const {
|
|
70
|
+
const { readPluginJson } = require('./lib/profile-utils');
|
|
97
71
|
const targetIdx = process.argv.indexOf('--target');
|
|
98
72
|
const targetPath = targetIdx >= 0 ? path.resolve(process.argv[targetIdx + 1]) : path.resolve('.');
|
|
99
|
-
const
|
|
100
|
-
const existingPlugin = readPluginJson(existingClaudeDir);
|
|
73
|
+
const existingPlugin = readPluginJson(path.join(targetPath, '.claude'));
|
|
101
74
|
|
|
102
75
|
if (existingPlugin) {
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
// B7: Same profile re-init
|
|
107
|
-
console.log(`\n Already installed: ${profile} profile (v${existingPlugin.version})`);
|
|
108
|
-
console.log(` Use "csl init ${profile} --fresh" to reinstall from scratch.\n`);
|
|
109
|
-
return;
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
const profileOrder = { core: 1, developer: 2, full: 3 };
|
|
113
|
-
const isDowngrade = profileOrder[profile] < profileOrder[existingProfile];
|
|
114
|
-
|
|
115
|
-
if (isDowngrade && !process.env.CI) {
|
|
116
|
-
// B2: Downgrade warning
|
|
117
|
-
const agentCount = existingPlugin.agents ? existingPlugin.agents.length : '?';
|
|
118
|
-
console.log(`\n WARNING: Downgrade detected`);
|
|
119
|
-
console.log(` Current: ${existingProfile} (${agentCount} agents)`);
|
|
120
|
-
console.log(` Target: ${profile}`);
|
|
121
|
-
console.log(` Extra agents/skills will become unreferenced.\n`);
|
|
122
|
-
|
|
123
|
-
const confirm = await ask(` Continue with downgrade? [y/N]: `);
|
|
124
|
-
if (confirm.toLowerCase() !== 'y') {
|
|
125
|
-
console.log(' Cancelled.\n');
|
|
126
|
-
return;
|
|
127
|
-
}
|
|
128
|
-
} else if (!isDowngrade) {
|
|
129
|
-
// Upgrade info
|
|
130
|
-
console.log(`\n Upgrading: ${existingProfile} -> ${profile}`);
|
|
131
|
-
}
|
|
76
|
+
console.log(`\n Already installed (v${existingPlugin.version})`);
|
|
77
|
+
console.log(` Use "csl init --fresh" to reinstall from scratch.\n`);
|
|
78
|
+
return;
|
|
132
79
|
}
|
|
133
80
|
}
|
|
134
81
|
|
|
@@ -193,23 +140,10 @@ const commands = {
|
|
|
193
140
|
console.log(` Installed version: ${currentVersion}`);
|
|
194
141
|
console.log(` New version: ${newVersion}`);
|
|
195
142
|
|
|
196
|
-
// Collect files from source
|
|
197
|
-
const
|
|
198
|
-
const modules =
|
|
199
|
-
|
|
200
|
-
// Detect which profile is installed based on skill directories
|
|
201
|
-
const installedSkillDirs = fs.existsSync(path.join(claudeDir, 'skills'))
|
|
202
|
-
? fs.readdirSync(path.join(claudeDir, 'skills'), { withFileTypes: true })
|
|
203
|
-
.filter(e => e.isDirectory()).map(e => e.name)
|
|
204
|
-
: [];
|
|
205
|
-
const hasTier3 = installedSkillDirs.includes('tier-3');
|
|
206
|
-
const hasTier2 = installedSkillDirs.includes('tier-2');
|
|
207
|
-
const detectedProfile = hasTier3 ? 'full' : hasTier2 ? 'developer' : 'core';
|
|
208
|
-
|
|
209
|
-
console.log(` Detected profile: ${detectedProfile}`);
|
|
210
|
-
|
|
211
|
-
const selectedProfile = profiles.profiles[detectedProfile];
|
|
212
|
-
const selectedModules = modules.modules.filter(m => selectedProfile.modules.includes(m.id));
|
|
143
|
+
// Collect files from source (all modules)
|
|
144
|
+
const { loadManifests } = require('./lib/profile-utils');
|
|
145
|
+
const { manifest, modules } = loadManifests();
|
|
146
|
+
const selectedModules = modules.modules.filter(m => manifest.modules.includes(m.id));
|
|
213
147
|
|
|
214
148
|
// Collect all source files
|
|
215
149
|
const sourceFiles = collectModuleFiles(selectedModules);
|
|
@@ -245,7 +179,7 @@ const commands = {
|
|
|
245
179
|
// Rebuild plugin.json with correct agents/skills for detected profile
|
|
246
180
|
const { buildPluginJson } = require('./lib/profile-utils');
|
|
247
181
|
if (!dryRun) {
|
|
248
|
-
const rebuilt = buildPluginJson(
|
|
182
|
+
const rebuilt = buildPluginJson('full', sourceFiles, newVersion);
|
|
249
183
|
fs.writeFileSync(pluginPath, JSON.stringify(rebuilt, null, 2));
|
|
250
184
|
console.log(` Rebuilt plugin.json (${rebuilt.agents.length} agents, ${rebuilt.skills.length} skill dirs)`);
|
|
251
185
|
}
|
|
@@ -282,73 +216,8 @@ const commands = {
|
|
|
282
216
|
console.log(' Claude Skill Lord has been uninstalled from this project.\n');
|
|
283
217
|
},
|
|
284
218
|
|
|
285
|
-
upgrade: async () => {
|
|
286
|
-
const { detectInstalledProfile, buildPluginJson, loadManifests } = require('./lib/profile-utils');
|
|
287
|
-
const targetProfile = subArgs.find(a => !a.startsWith('-')) || null;
|
|
288
|
-
const targetDir = path.resolve(subArgs.includes('--target')
|
|
289
|
-
? subArgs[subArgs.indexOf('--target') + 1] : '.');
|
|
290
|
-
const claudeDir = path.join(targetDir, '.claude');
|
|
291
|
-
const dryRun = subArgs.includes('--dry-run');
|
|
292
|
-
|
|
293
|
-
if (!fs.existsSync(claudeDir)) {
|
|
294
|
-
console.log(`\n No .claude/ found. Run "csl init" first.\n`);
|
|
295
|
-
process.exit(1);
|
|
296
|
-
}
|
|
297
|
-
|
|
298
|
-
const currentProfile = detectInstalledProfile(claudeDir);
|
|
299
|
-
if (!currentProfile) {
|
|
300
|
-
console.log(`\n Could not detect current profile. Run "csl init" first.\n`);
|
|
301
|
-
return;
|
|
302
|
-
}
|
|
303
|
-
const newProfile = targetProfile || currentProfile;
|
|
304
|
-
const profileOrder = { core: 1, developer: 2, full: 3 };
|
|
305
|
-
|
|
306
|
-
if (!profileOrder[newProfile]) {
|
|
307
|
-
console.log(`\n Unknown profile "${newProfile}". Available: core, developer, full\n`);
|
|
308
|
-
return;
|
|
309
|
-
}
|
|
310
|
-
|
|
311
|
-
if (profileOrder[newProfile] < profileOrder[currentProfile]) {
|
|
312
|
-
console.log(`\n Cannot downgrade with upgrade. Use "csl init ${newProfile} --fresh" instead.\n`);
|
|
313
|
-
return;
|
|
314
|
-
}
|
|
315
|
-
|
|
316
|
-
console.log(`\n Claude Skill Lord — Upgrade\n`);
|
|
317
|
-
console.log(` Current: ${currentProfile}`);
|
|
318
|
-
console.log(` Target: ${newProfile}`);
|
|
319
|
-
|
|
320
|
-
const { profiles, modules } = loadManifests();
|
|
321
|
-
const selectedProfile = profiles.profiles[newProfile];
|
|
322
|
-
const selectedModules = modules.modules.filter(m => selectedProfile.modules.includes(m.id));
|
|
323
|
-
|
|
324
|
-
const filesToCopy = collectModuleFiles(selectedModules);
|
|
325
|
-
|
|
326
|
-
let added = 0;
|
|
327
|
-
for (const f of filesToCopy) {
|
|
328
|
-
const destPath = path.join(claudeDir, f.rel);
|
|
329
|
-
if (!fs.existsSync(destPath)) {
|
|
330
|
-
if (dryRun) { console.log(` + ${f.rel}`); }
|
|
331
|
-
else {
|
|
332
|
-
const destDir = path.dirname(destPath);
|
|
333
|
-
if (!fs.existsSync(destDir)) fs.mkdirSync(destDir, { recursive: true });
|
|
334
|
-
fs.copyFileSync(f.src, destPath);
|
|
335
|
-
}
|
|
336
|
-
added++;
|
|
337
|
-
}
|
|
338
|
-
}
|
|
339
|
-
|
|
340
|
-
if (!dryRun) {
|
|
341
|
-
const pkg = require(path.join(rootDir, 'package.json'));
|
|
342
|
-
const pluginJson = buildPluginJson(newProfile, filesToCopy, pkg.version);
|
|
343
|
-
fs.writeFileSync(path.join(claudeDir, 'plugin.json'), JSON.stringify(pluginJson, null, 2));
|
|
344
|
-
}
|
|
345
|
-
|
|
346
|
-
console.log(`\n ${dryRun ? '[DRY RUN] ' : ''}Added ${added} new files`);
|
|
347
|
-
console.log(` Profile: ${currentProfile} -> ${newProfile}\n`);
|
|
348
|
-
},
|
|
349
|
-
|
|
350
219
|
diff: () => {
|
|
351
|
-
const {
|
|
220
|
+
const { loadManifests } = require('./lib/profile-utils');
|
|
352
221
|
const targetDir = path.resolve(subArgs.includes('--target')
|
|
353
222
|
? subArgs[subArgs.indexOf('--target') + 1] : '.');
|
|
354
223
|
const claudeDir = path.join(targetDir, '.claude');
|
|
@@ -358,12 +227,10 @@ const commands = {
|
|
|
358
227
|
process.exit(1);
|
|
359
228
|
}
|
|
360
229
|
|
|
361
|
-
|
|
362
|
-
console.log(`\n Claude Skill Lord — Diff (${profile} profile)\n`);
|
|
230
|
+
console.log(`\n Claude Skill Lord — Diff\n`);
|
|
363
231
|
|
|
364
|
-
const {
|
|
365
|
-
const
|
|
366
|
-
const selectedModules = modules.modules.filter(m => selectedProfile.modules.includes(m.id));
|
|
232
|
+
const { manifest, modules } = loadManifests();
|
|
233
|
+
const selectedModules = modules.modules.filter(m => manifest.modules.includes(m.id));
|
|
367
234
|
|
|
368
235
|
const sourceFiles = collectModuleFiles(selectedModules);
|
|
369
236
|
|
|
@@ -402,44 +269,20 @@ const commands = {
|
|
|
402
269
|
},
|
|
403
270
|
|
|
404
271
|
list: () => {
|
|
405
|
-
const { readPluginJson, detectInstalledProfile } = require('./lib/profile-utils');
|
|
406
272
|
const manifest = JSON.parse(
|
|
407
273
|
fs.readFileSync(path.join(rootDir, 'skills', 'manifest.json'), 'utf8')
|
|
408
274
|
);
|
|
409
275
|
const agents = fs.readdirSync(path.join(rootDir, 'agents')).filter(f => f.endsWith('.md'));
|
|
410
276
|
|
|
411
|
-
// Detect installed state from project
|
|
412
|
-
const projectClaudeDir = path.join(process.cwd(), '.claude');
|
|
413
|
-
const projectPlugin = readPluginJson(projectClaudeDir);
|
|
414
|
-
const installedAgents = projectPlugin
|
|
415
|
-
? new Set((projectPlugin.agents || []).map(a => a.replace('./', '').replace('.md', '')))
|
|
416
|
-
: null;
|
|
417
|
-
const installedSkillDirs = projectPlugin
|
|
418
|
-
? new Set((projectPlugin.skills || []).map(s => s.replace('./', '').replace(/\/$/, '')))
|
|
419
|
-
: null;
|
|
420
|
-
|
|
421
|
-
const tag = (name, set) => set ? (set.has(name) ? ' [installed]' : ' [available]') : '';
|
|
422
|
-
|
|
423
277
|
console.log(`\n Claude Skill Lord Components\n`);
|
|
424
278
|
|
|
425
|
-
if (projectPlugin) {
|
|
426
|
-
const profile = projectPlugin.profile || detectInstalledProfile(projectClaudeDir) || '?';
|
|
427
|
-
console.log(` Project profile: ${profile} (v${projectPlugin.version || '?'})\n`);
|
|
428
|
-
}
|
|
429
|
-
|
|
430
279
|
console.log(` Agents: ${agents.length}`);
|
|
431
|
-
agents.forEach(a => {
|
|
432
|
-
const name = a.replace('.md', '');
|
|
433
|
-
console.log(` - ${name}${tag(`agents/${name}`, installedAgents)}`);
|
|
434
|
-
});
|
|
280
|
+
agents.forEach(a => console.log(` - ${a.replace('.md', '')}`));
|
|
435
281
|
|
|
436
282
|
console.log(`\n Skills: ${manifest.skills.length}`);
|
|
437
283
|
[1, 2, 3].forEach(tier => {
|
|
438
284
|
const skills = manifest.skills.filter(s => s.tier === tier);
|
|
439
|
-
|
|
440
|
-
const tierInstalled = installedSkillDirs ? installedSkillDirs.has(tierDir) : null;
|
|
441
|
-
const tierTag = tierInstalled === null ? '' : tierInstalled ? ' [installed]' : ' [available]';
|
|
442
|
-
console.log(`\n Tier ${tier}${tierTag} (${skills.length}):`);
|
|
285
|
+
console.log(`\n Tier ${tier} (${skills.length}):`);
|
|
443
286
|
skills.forEach(s => console.log(` - ${s.name}: ${s.description}`));
|
|
444
287
|
});
|
|
445
288
|
|
|
@@ -557,42 +400,15 @@ const commands = {
|
|
|
557
400
|
if (missing.length) throw new Error(`missing: ${missing.join(', ')}`);
|
|
558
401
|
});
|
|
559
402
|
|
|
560
|
-
//
|
|
561
|
-
info('
|
|
403
|
+
// Consistency: check declared skill dirs exist on disk
|
|
404
|
+
info('Skills intact', () => {
|
|
562
405
|
const pPath = path.join(projectClaudeDir, 'plugin.json');
|
|
563
406
|
if (!fs.existsSync(pPath)) throw new Error('no plugin.json');
|
|
564
407
|
const p = JSON.parse(fs.readFileSync(pPath, 'utf8'));
|
|
565
|
-
|
|
566
|
-
const declaredAgents = (p.agents || []).map(a => a.replace('./', ''));
|
|
567
|
-
const agentsDir = path.join(projectClaudeDir, 'agents');
|
|
568
|
-
const diskAgents = fs.existsSync(agentsDir)
|
|
569
|
-
? fs.readdirSync(agentsDir).filter(f => f.endsWith('.md'))
|
|
570
|
-
: [];
|
|
571
|
-
const orphaned = diskAgents.filter(f => !declaredAgents.includes(`agents/${f}`));
|
|
572
|
-
|
|
573
408
|
const declaredSkillDirs = (p.skills || []).map(s => s.replace('./', '').replace(/\/$/, ''));
|
|
574
|
-
const
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
throw new Error(`${missingSkillDirs.length} declared skill dirs missing: ${missingSkillDirs.join(', ')}`);
|
|
578
|
-
}
|
|
579
|
-
|
|
580
|
-
const details = [];
|
|
581
|
-
if (orphaned.length > 0) details.push(`${orphaned.length} orphaned agent files`);
|
|
582
|
-
if (p.profile) details.push(`profile: ${p.profile}`);
|
|
583
|
-
if (details.length) console.log(` (${details.join(', ')})`);
|
|
584
|
-
});
|
|
585
|
-
|
|
586
|
-
info('Profile metadata', () => {
|
|
587
|
-
const pPath = path.join(projectClaudeDir, 'plugin.json');
|
|
588
|
-
const p = JSON.parse(fs.readFileSync(pPath, 'utf8'));
|
|
589
|
-
if (!p.profile) {
|
|
590
|
-
throw new Error('no profile field in plugin.json. Run "csl migrate" to fix.');
|
|
591
|
-
}
|
|
592
|
-
const { detectInstalledProfile } = require('./lib/profile-utils');
|
|
593
|
-
const detected = detectInstalledProfile(projectClaudeDir);
|
|
594
|
-
if (detected && detected !== p.profile) {
|
|
595
|
-
throw new Error(`plugin.json says "${p.profile}" but disk shows "${detected}". Run "csl migrate" to fix.`);
|
|
409
|
+
const missing = declaredSkillDirs.filter(d => !fs.existsSync(path.join(projectClaudeDir, d)));
|
|
410
|
+
if (missing.length > 0) {
|
|
411
|
+
throw new Error(`${missing.length} skill dirs missing: ${missing.join(', ')}`);
|
|
596
412
|
}
|
|
597
413
|
});
|
|
598
414
|
}
|
|
@@ -617,10 +433,9 @@ const commands = {
|
|
|
617
433
|
Usage: csl <command> [options]
|
|
618
434
|
|
|
619
435
|
Commands:
|
|
620
|
-
init
|
|
621
|
-
upgrade [profile] Upgrade to a higher profile (additive, no overwrites)
|
|
436
|
+
init Install in current project (22 agents, 61 skills, all commands)
|
|
622
437
|
update Update CLI to latest version
|
|
623
|
-
migrate Update
|
|
438
|
+
migrate Update project files after csl update
|
|
624
439
|
diff Compare project files with source package
|
|
625
440
|
uninstall Remove Claude Skill Lord from a project
|
|
626
441
|
list List all agents, skills, and commands
|
|
@@ -632,35 +447,23 @@ const commands = {
|
|
|
632
447
|
--target <path> Target directory (default: current directory)
|
|
633
448
|
--dry-run Preview without copying
|
|
634
449
|
--fresh Clean reinstall (remove existing .claude/ first)
|
|
450
|
+
--no-fonts Skip canvas font files (~7MB)
|
|
635
451
|
|
|
636
|
-
|
|
637
|
-
--target <path> Target directory (default: current directory)
|
|
638
|
-
--dry-run Preview what would be added
|
|
639
|
-
|
|
640
|
-
Migrate Options:
|
|
641
|
-
--target <path> Target directory (default: current directory)
|
|
642
|
-
--dry-run Preview changes without applying
|
|
643
|
-
|
|
644
|
-
Diff Options:
|
|
452
|
+
Migrate/Diff Options:
|
|
645
453
|
--target <path> Target directory (default: current directory)
|
|
454
|
+
--dry-run Preview changes without applying (migrate only)
|
|
646
455
|
|
|
647
456
|
Uninstall Options:
|
|
648
457
|
--target <path> Target directory (default: current directory)
|
|
649
458
|
--force, -f Skip confirmation prompt
|
|
650
459
|
|
|
651
|
-
Profiles:
|
|
652
|
-
core 16 skills, 7 agents — lightweight
|
|
653
|
-
developer 44 skills, 22 agents — recommended
|
|
654
|
-
full 61 skills, 22 agents — everything
|
|
655
|
-
|
|
656
460
|
Examples:
|
|
657
|
-
csl init #
|
|
658
|
-
csl init
|
|
659
|
-
csl init
|
|
660
|
-
csl
|
|
461
|
+
csl init # Install everything
|
|
462
|
+
csl init --no-fonts # Skip canvas fonts (~7MB lighter)
|
|
463
|
+
csl init --dry-run # Preview without copying
|
|
464
|
+
csl init --fresh # Clean reinstall
|
|
661
465
|
csl update # Update to latest version
|
|
662
466
|
csl migrate # Update project files after csl update
|
|
663
|
-
csl migrate --dry-run # Preview what would change
|
|
664
467
|
csl diff # Show modified/missing/extra files
|
|
665
468
|
csl uninstall # Remove from current project
|
|
666
469
|
csl doctor # Check health + updates
|