@human-avatar/skills-for-humanity 1.0.2 → 1.1.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/bin/install.js +62 -85
- package/package.json +1 -1
package/bin/install.js
CHANGED
|
@@ -28,14 +28,12 @@ const SCOPES = {
|
|
|
28
28
|
user: {
|
|
29
29
|
label: 'User',
|
|
30
30
|
description: 'available in all projects',
|
|
31
|
-
|
|
32
|
-
settingsPath: path.join(os.homedir(), '.claude', 'settings.json'),
|
|
31
|
+
skillsDir: path.join(os.homedir(), '.claude', 'skills'),
|
|
33
32
|
},
|
|
34
33
|
project: {
|
|
35
34
|
label: 'Project',
|
|
36
35
|
description: `this project only ${dim}(${process.cwd()})${reset}`,
|
|
37
|
-
|
|
38
|
-
settingsPath: path.join(process.cwd(), '.claude', 'settings.json'),
|
|
36
|
+
skillsDir: path.join(process.cwd(), '.claude', 'skills'),
|
|
39
37
|
},
|
|
40
38
|
};
|
|
41
39
|
|
|
@@ -49,17 +47,16 @@ const args = process.argv.slice(2);
|
|
|
49
47
|
|
|
50
48
|
if (args.includes('--help') || args.includes('-h')) {
|
|
51
49
|
log(`
|
|
52
|
-
${bold}skills-for-humanity${reset} —
|
|
50
|
+
${bold}skills-for-humanity${reset} — 131 structured thinking tools for Claude Code
|
|
53
51
|
|
|
54
52
|
${bold}Usage:${reset}
|
|
55
53
|
npx @human-avatar/skills-for-humanity [options]
|
|
56
54
|
|
|
57
55
|
${bold}Options:${reset}
|
|
58
56
|
${cyan}--scope user|project${reset} Install scope (prompted if omitted)
|
|
59
|
-
${dim}user: ~/.claude/ — all projects${reset}
|
|
60
|
-
${dim}project: ./.claude/ — this project only${reset}
|
|
61
|
-
${cyan}--
|
|
62
|
-
${cyan}--uninstall${reset} Remove skills and clean up settings.json
|
|
57
|
+
${dim}user: ~/.claude/skills/ — all projects${reset}
|
|
58
|
+
${dim}project: ./.claude/skills/ — this project only${reset}
|
|
59
|
+
${cyan}--uninstall${reset} Remove installed skills
|
|
63
60
|
${cyan}--help${reset} Show this help message
|
|
64
61
|
|
|
65
62
|
${bold}After install:${reset}
|
|
@@ -86,20 +83,10 @@ function removeDir(dir) {
|
|
|
86
83
|
if (fs.existsSync(dir)) fs.rmSync(dir, { recursive: true, force: true });
|
|
87
84
|
}
|
|
88
85
|
|
|
89
|
-
function
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
function writeSettings(settingsPath, settings) {
|
|
96
|
-
fs.mkdirSync(path.dirname(settingsPath), { recursive: true });
|
|
97
|
-
fs.writeFileSync(settingsPath, JSON.stringify(settings, null, 2) + '\n');
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
function countDirs(dir) {
|
|
101
|
-
try { return fs.readdirSync(dir, { withFileTypes: true }).filter((e) => e.isDirectory()).length; }
|
|
102
|
-
catch { return '?'; }
|
|
86
|
+
function ourSkillNames() {
|
|
87
|
+
return fs.readdirSync(SKILLS_SRC, { withFileTypes: true })
|
|
88
|
+
.filter((e) => e.isDirectory())
|
|
89
|
+
.map((e) => e.name);
|
|
103
90
|
}
|
|
104
91
|
|
|
105
92
|
function prompt(question) {
|
|
@@ -112,8 +99,8 @@ function prompt(question) {
|
|
|
112
99
|
async function askScope() {
|
|
113
100
|
log(`${bold}Where should the skills be installed?${reset}`);
|
|
114
101
|
log();
|
|
115
|
-
log(` ${cyan}1) User${reset} — available in all projects ${dim}(~/.claude/)${reset}`);
|
|
116
|
-
log(` ${cyan}2) Project${reset} — this project only ${dim}(./.claude/)${reset}`);
|
|
102
|
+
log(` ${cyan}1) User${reset} — available in all projects ${dim}(~/.claude/skills/)${reset}`);
|
|
103
|
+
log(` ${cyan}2) Project${reset} — this project only ${dim}(./.claude/skills/)${reset}`);
|
|
117
104
|
log();
|
|
118
105
|
|
|
119
106
|
while (true) {
|
|
@@ -129,16 +116,6 @@ async function askScope() {
|
|
|
129
116
|
// ---------------------------------------------------------------------------
|
|
130
117
|
|
|
131
118
|
async function resolveTarget() {
|
|
132
|
-
// --dir takes precedence, skips scope prompt entirely
|
|
133
|
-
const dirFlag = args.indexOf('--dir');
|
|
134
|
-
if (dirFlag !== -1 && args[dirFlag + 1]) {
|
|
135
|
-
const custom = path.resolve(args[dirFlag + 1]);
|
|
136
|
-
// For custom dirs, write settings next to the dir's .claude parent if it exists,
|
|
137
|
-
// otherwise fall back to user settings.
|
|
138
|
-
const customSettings = path.join(path.dirname(custom), 'settings.json');
|
|
139
|
-
return { pluginsDir: custom, settingsPath: customSettings };
|
|
140
|
-
}
|
|
141
|
-
|
|
142
119
|
// --scope flag skips the interactive prompt
|
|
143
120
|
const scopeFlag = args.indexOf('--scope');
|
|
144
121
|
if (scopeFlag !== -1 && args[scopeFlag + 1]) {
|
|
@@ -159,6 +136,26 @@ async function resolveTarget() {
|
|
|
159
136
|
return SCOPES[key];
|
|
160
137
|
}
|
|
161
138
|
|
|
139
|
+
// ---------------------------------------------------------------------------
|
|
140
|
+
// Migrate: remove legacy pluginDirectories entry if present
|
|
141
|
+
// ---------------------------------------------------------------------------
|
|
142
|
+
|
|
143
|
+
function cleanLegacySettings(settingsPath, legacyDir) {
|
|
144
|
+
if (!fs.existsSync(settingsPath)) return;
|
|
145
|
+
try {
|
|
146
|
+
const settings = JSON.parse(fs.readFileSync(settingsPath, 'utf8'));
|
|
147
|
+
if (!Array.isArray(settings.pluginDirectories)) return;
|
|
148
|
+
const before = settings.pluginDirectories.length;
|
|
149
|
+
settings.pluginDirectories = settings.pluginDirectories.filter(
|
|
150
|
+
(d) => !path.resolve(d).includes('skills-for-humanity')
|
|
151
|
+
);
|
|
152
|
+
if (settings.pluginDirectories.length < before) {
|
|
153
|
+
fs.writeFileSync(settingsPath, JSON.stringify(settings, null, 2) + '\n');
|
|
154
|
+
log(`${dim}→ Removed legacy pluginDirectories entry from ${settingsPath}${reset}`);
|
|
155
|
+
}
|
|
156
|
+
} catch { /* ignore */ }
|
|
157
|
+
}
|
|
158
|
+
|
|
162
159
|
// ---------------------------------------------------------------------------
|
|
163
160
|
// Uninstall
|
|
164
161
|
// ---------------------------------------------------------------------------
|
|
@@ -169,28 +166,24 @@ async function uninstall() {
|
|
|
169
166
|
log();
|
|
170
167
|
|
|
171
168
|
const target = await resolveTarget();
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
const
|
|
178
|
-
if (
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
(d) => path.resolve(d) !== path.resolve(target.pluginsDir)
|
|
182
|
-
);
|
|
183
|
-
if (settings.pluginDirectories.length < before) {
|
|
184
|
-
writeSettings(target.settingsPath, settings);
|
|
185
|
-
log(`${green}✓${reset} Removed from ${dim}${target.settingsPath}${reset}`);
|
|
186
|
-
} else {
|
|
187
|
-
log(`${dim}→ Not found in settings — nothing to remove${reset}`);
|
|
188
|
-
}
|
|
169
|
+
const { skillsDir } = target;
|
|
170
|
+
|
|
171
|
+
const names = ourSkillNames();
|
|
172
|
+
let removed = 0;
|
|
173
|
+
for (const name of names) {
|
|
174
|
+
const dest = path.join(skillsDir, name);
|
|
175
|
+
if (fs.existsSync(dest)) {
|
|
176
|
+
removeDir(dest);
|
|
177
|
+
removed++;
|
|
189
178
|
}
|
|
190
|
-
} catch (e) {
|
|
191
|
-
warn(`Could not update settings.json: ${e.message}`);
|
|
192
179
|
}
|
|
193
180
|
|
|
181
|
+
log(`${green}✓${reset} Removed ${removed} skills from ${dim}${skillsDir}${reset}`);
|
|
182
|
+
|
|
183
|
+
// Clean up legacy pluginDirectories entry if present
|
|
184
|
+
const settingsPath = path.join(path.dirname(skillsDir), 'settings.json');
|
|
185
|
+
cleanLegacySettings(settingsPath, skillsDir);
|
|
186
|
+
|
|
194
187
|
log();
|
|
195
188
|
log(`${dim}Uninstall complete.${reset}`);
|
|
196
189
|
log();
|
|
@@ -203,51 +196,35 @@ async function uninstall() {
|
|
|
203
196
|
async function install() {
|
|
204
197
|
log();
|
|
205
198
|
log(`${bold}${cyan}skills-for-humanity${reset}`);
|
|
206
|
-
log(`${dim}
|
|
199
|
+
log(`${dim}131 structured thinking tools for Claude Code${reset}`);
|
|
207
200
|
log();
|
|
208
201
|
|
|
209
202
|
const target = await resolveTarget();
|
|
210
|
-
const {
|
|
203
|
+
const { skillsDir } = target;
|
|
211
204
|
|
|
212
|
-
//
|
|
213
|
-
const
|
|
214
|
-
|
|
205
|
+
// Copy each skill into the skills directory
|
|
206
|
+
const names = ourSkillNames();
|
|
207
|
+
const isUpdate = names.some((n) => fs.existsSync(path.join(skillsDir, n)));
|
|
208
|
+
log(`${isUpdate ? 'Updating' : 'Installing'} ${names.length} skills to ${yellow}${skillsDir}${reset}…`);
|
|
215
209
|
|
|
216
210
|
try {
|
|
217
|
-
|
|
218
|
-
|
|
211
|
+
for (const name of names) {
|
|
212
|
+
copyDir(path.join(SKILLS_SRC, name), path.join(skillsDir, name));
|
|
213
|
+
}
|
|
214
|
+
log(`${green}✓${reset} ${names.length} skills ${isUpdate ? 'updated' : 'installed'}`);
|
|
219
215
|
} catch (e) {
|
|
220
216
|
err(`Could not copy skills: ${e.message}`);
|
|
221
217
|
process.exit(1);
|
|
222
218
|
}
|
|
223
219
|
|
|
224
|
-
//
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
if (!Array.isArray(settings.pluginDirectories)) settings.pluginDirectories = [];
|
|
228
|
-
|
|
229
|
-
const already = settings.pluginDirectories.some(
|
|
230
|
-
(d) => path.resolve(d) === path.resolve(pluginsDir)
|
|
231
|
-
);
|
|
232
|
-
|
|
233
|
-
if (!already) {
|
|
234
|
-
settings.pluginDirectories.push(pluginsDir);
|
|
235
|
-
writeSettings(settingsPath, settings);
|
|
236
|
-
log(`${green}✓${reset} Registered in ${dim}${settingsPath}${reset}`);
|
|
237
|
-
} else {
|
|
238
|
-
log(`${dim}→ Already registered in ${settingsPath}${reset}`);
|
|
239
|
-
}
|
|
240
|
-
} catch (e) {
|
|
241
|
-
warn(`Could not update settings.json: ${e.message}`);
|
|
242
|
-
log();
|
|
243
|
-
log(`Add this to ${yellow}${settingsPath}${reset} manually:`);
|
|
244
|
-
log(` ${dim}{ "pluginDirectories": ["${pluginsDir}"] }${reset}`);
|
|
245
|
-
}
|
|
220
|
+
// Clean up legacy pluginDirectories entry if present
|
|
221
|
+
const settingsPath = path.join(path.dirname(skillsDir), 'settings.json');
|
|
222
|
+
cleanLegacySettings(settingsPath, skillsDir);
|
|
246
223
|
|
|
247
|
-
//
|
|
224
|
+
// Done
|
|
248
225
|
log();
|
|
249
226
|
log(`${bold}Done.${reset} Restart Claude Code, then:`);
|
|
250
|
-
log(` ${cyan}/human${reset} ${dim}— route to the right skill from all
|
|
227
|
+
log(` ${cyan}/human${reset} ${dim}— route to the right skill from all 131${reset}`);
|
|
251
228
|
log(` ${cyan}/ethics${reset} ${dim}— ethical analysis${reset}`);
|
|
252
229
|
log(` ${cyan}/logic${reset} ${dim}— validate and pressure-test reasoning${reset}`);
|
|
253
230
|
log(` ${cyan}/creativity${reset} ${dim}— de Bono suite + brainstorm${reset}`);
|
package/package.json
CHANGED