agentic-skill-mill 1.0.9 → 1.0.11
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 +8 -12
- package/compiled/claude/agentic-skill-mill/SKILL.md +31 -26
- package/compiled/codex/agentic-skill-mill/SKILL.md +31 -26
- package/compiled/cursor/skills/agentic-skill-mill/SKILL.md +31 -26
- package/compiled/opencode/agentic-skill-mill.md +31 -26
- package/compiled/windsurf/skills/agentic-skill-mill/SKILL.md +31 -26
- package/dist/core/scaffold.js +0 -1
- package/dist/core/scaffold.js.map +1 -1
- package/install.js +555 -0
- package/package.json +10 -13
- package/skill/build/manifest.json +0 -2
- package/skill/fragments/meta/architecture-overview.md +6 -4
- package/skill/fragments/meta/distribution-and-ci.md +21 -17
- package/skill/fragments/meta/rename-workflow.md +2 -2
- package/skill/skills/agentic-skill-mill/agentic-skill-mill.md +2 -3
- package/compiled/cursor/rules/agentic-skill-mill.mdc +0 -547
- package/compiled/windsurf/rules/agentic-skill-mill.md +0 -547
- package/install-local.ps1 +0 -385
- package/install-local.sh +0 -265
- package/install.ps1 +0 -48
- package/install.sh +0 -44
package/install.js
ADDED
|
@@ -0,0 +1,555 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Unified install script for agentic-skill-mill.
|
|
4
|
+
*
|
|
5
|
+
* Cross-platform Node.js implementation that replaces:
|
|
6
|
+
* - install.sh / install.ps1
|
|
7
|
+
* - install-local.sh / install-local.ps1
|
|
8
|
+
*
|
|
9
|
+
* Usage:
|
|
10
|
+
* node install.js [options]
|
|
11
|
+
*
|
|
12
|
+
* Options:
|
|
13
|
+
* --claude Install skills for Claude Code
|
|
14
|
+
* --cursor Install skills for Cursor
|
|
15
|
+
* --windsurf Install skills for Windsurf
|
|
16
|
+
* --opencode Install skills for OpenCode
|
|
17
|
+
* --codex Install skills for Codex
|
|
18
|
+
* --all Install for all five tools
|
|
19
|
+
* --skills-only Skip npm install/build/link (just copy skills)
|
|
20
|
+
* --uninstall Remove installed skills from target tools
|
|
21
|
+
* --compile-only Generate compiled/ output directory (no install)
|
|
22
|
+
* -h, --help Show this help
|
|
23
|
+
*
|
|
24
|
+
* If no flags are provided, the script auto-detects installed tools.
|
|
25
|
+
*/
|
|
26
|
+
|
|
27
|
+
import fs from 'node:fs';
|
|
28
|
+
import path from 'node:path';
|
|
29
|
+
import os from 'node:os';
|
|
30
|
+
import { spawnSync } from 'node:child_process';
|
|
31
|
+
import { fileURLToPath } from 'node:url';
|
|
32
|
+
|
|
33
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
34
|
+
const repoDir = path.dirname(path.resolve(__filename));
|
|
35
|
+
|
|
36
|
+
// --- Constants -------------------------------------------------------------
|
|
37
|
+
|
|
38
|
+
const MANAGED_MARKER = 'managed_by: agentic-skill-mill';
|
|
39
|
+
const PROJECT_NAME = 'agentic-skill-mill';
|
|
40
|
+
const CLI_BIN_NAME = 'skillmill';
|
|
41
|
+
const SKILL_NAME = 'agentic-skill-mill';
|
|
42
|
+
|
|
43
|
+
const HOME = os.homedir();
|
|
44
|
+
const APPDATA = process.env.APPDATA;
|
|
45
|
+
|
|
46
|
+
// --- Source dirs (compiled output) -------------------------------------
|
|
47
|
+
|
|
48
|
+
const COMPILED_DIR = path.join(repoDir, 'compiled');
|
|
49
|
+
|
|
50
|
+
const SRC = {
|
|
51
|
+
claude: path.join(COMPILED_DIR, 'claude', SKILL_NAME),
|
|
52
|
+
cursorSkills: path.join(COMPILED_DIR, 'cursor', 'skills'),
|
|
53
|
+
windsurfSkills: path.join(COMPILED_DIR, 'windsurf', 'skills'),
|
|
54
|
+
opencode: path.join(COMPILED_DIR, 'opencode'),
|
|
55
|
+
codex: path.join(COMPILED_DIR, 'codex', SKILL_NAME),
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
// --- Target directories -----------------------------------------------------
|
|
59
|
+
|
|
60
|
+
const DEST = {
|
|
61
|
+
claude: path.join(HOME, '.claude', 'skills', SKILL_NAME),
|
|
62
|
+
cursorSkills: path.join(HOME, '.cursor', 'skills', SKILL_NAME),
|
|
63
|
+
windsurfSkills: path.join(HOME, '.codeium', 'windsurf', 'skills', SKILL_NAME),
|
|
64
|
+
opencode: path.join(APPDATA || path.join(HOME, '.config', 'opencode'), 'agents'),
|
|
65
|
+
codex: path.join(process.env.CODEX_HOME || path.join(HOME, '.codex'), 'skills', SKILL_NAME),
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
// --- Filesystem helpers ----------------------------------------------------
|
|
69
|
+
|
|
70
|
+
function ensureDir(dir) {
|
|
71
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function listFiles(dir, ext) {
|
|
75
|
+
if (!fs.existsSync(dir)) return [];
|
|
76
|
+
return fs.readdirSync(dir)
|
|
77
|
+
.filter((name) => name.endsWith(ext))
|
|
78
|
+
.map((name) => path.join(dir, name));
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
function readText(file) {
|
|
82
|
+
return fs.readFileSync(file, 'utf8');
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function writeText(file, content) {
|
|
86
|
+
ensureDir(path.dirname(file));
|
|
87
|
+
fs.writeFileSync(file, content);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
function fileExists(file) {
|
|
91
|
+
try {
|
|
92
|
+
return fs.statSync(file).isFile();
|
|
93
|
+
} catch {
|
|
94
|
+
return false;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
function dirExists(dir) {
|
|
99
|
+
try {
|
|
100
|
+
return fs.statSync(dir).isDirectory();
|
|
101
|
+
} catch {
|
|
102
|
+
return false;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
function fileContains(file, marker) {
|
|
107
|
+
if (!fileExists(file)) return false;
|
|
108
|
+
return readText(file).includes(marker);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
function cleanupManagedFiles(destDir) {
|
|
112
|
+
if (!dirExists(destDir)) return;
|
|
113
|
+
const walk = (d) => {
|
|
114
|
+
for (const entry of fs.readdirSync(d, { withFileTypes: true })) {
|
|
115
|
+
const full = path.join(d, entry.name);
|
|
116
|
+
if (entry.isDirectory()) {
|
|
117
|
+
walk(full);
|
|
118
|
+
} else if (entry.isFile() && fileContains(full, MANAGED_MARKER)) {
|
|
119
|
+
fs.unlinkSync(full);
|
|
120
|
+
console.log(` Removed stale: ${full}`);
|
|
121
|
+
// Try to remove empty parent dirs
|
|
122
|
+
const parent = path.dirname(full);
|
|
123
|
+
try {
|
|
124
|
+
if (dirExists(parent) && fs.readdirSync(parent).length === 0) {
|
|
125
|
+
fs.rmdirSync(parent);
|
|
126
|
+
}
|
|
127
|
+
} catch {
|
|
128
|
+
// Ignore errors
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
};
|
|
133
|
+
walk(destDir);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
function copyFile(src, dest) {
|
|
137
|
+
ensureDir(path.dirname(dest));
|
|
138
|
+
fs.copyFileSync(src, dest);
|
|
139
|
+
console.log(` ${dest}`);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// --- Shell helpers --------------------------------------------------------
|
|
143
|
+
|
|
144
|
+
function runNode(args, options = {}) {
|
|
145
|
+
const result = spawnSync('node', args, {
|
|
146
|
+
stdio: 'inherit',
|
|
147
|
+
cwd: repoDir,
|
|
148
|
+
...options,
|
|
149
|
+
});
|
|
150
|
+
if (result.status !== 0) {
|
|
151
|
+
process.exit(result.status ?? 1);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
function runNpm(args, options = {}) {
|
|
156
|
+
const result = spawnSync('npm', args, {
|
|
157
|
+
stdio: 'inherit',
|
|
158
|
+
cwd: repoDir,
|
|
159
|
+
...options,
|
|
160
|
+
});
|
|
161
|
+
if (result.status !== 0) {
|
|
162
|
+
process.exit(result.status ?? 1);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
// --- Install functions ------------------------------------------------------
|
|
167
|
+
|
|
168
|
+
function installClaude() {
|
|
169
|
+
const src = SRC.claude;
|
|
170
|
+
const dest = DEST.claude;
|
|
171
|
+
if (!dirExists(src)) {
|
|
172
|
+
console.log(` Warning: source missing ${src}`);
|
|
173
|
+
return;
|
|
174
|
+
}
|
|
175
|
+
ensureDir(dest);
|
|
176
|
+
const srcFile = path.join(src, 'SKILL.md');
|
|
177
|
+
if (fileExists(srcFile)) {
|
|
178
|
+
copyFile(srcFile, path.join(dest, 'SKILL.md'));
|
|
179
|
+
}
|
|
180
|
+
console.log(` Claude: ${dest}`);
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
function installCursor() {
|
|
184
|
+
// Skills directory only (not rules)
|
|
185
|
+
const srcSkills = SRC.cursorSkills;
|
|
186
|
+
const destSkills = DEST.cursorSkills;
|
|
187
|
+
if (dirExists(srcSkills)) {
|
|
188
|
+
ensureDir(destSkills);
|
|
189
|
+
const srcFile = path.join(srcSkills, 'SKILL.md');
|
|
190
|
+
if (fileExists(srcFile)) {
|
|
191
|
+
copyFile(srcFile, path.join(destSkills, 'SKILL.md'));
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
console.log(` Cursor: skills -> ${destSkills}`);
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
function installWindsurf() {
|
|
198
|
+
// Skills directory only (not rules)
|
|
199
|
+
const srcSkills = SRC.windsurfSkills;
|
|
200
|
+
const destSkills = DEST.windsurfSkills;
|
|
201
|
+
if (dirExists(srcSkills)) {
|
|
202
|
+
ensureDir(destSkills);
|
|
203
|
+
const srcFile = path.join(srcSkills, 'SKILL.md');
|
|
204
|
+
if (fileExists(srcFile)) {
|
|
205
|
+
copyFile(srcFile, path.join(destSkills, 'SKILL.md'));
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
console.log(` Windsurf: skills -> ${destSkills}`);
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
function installOpenCode() {
|
|
212
|
+
const src = SRC.opencode;
|
|
213
|
+
const dest = DEST.opencode;
|
|
214
|
+
if (!dirExists(src)) {
|
|
215
|
+
console.log(` Warning: source missing ${src}`);
|
|
216
|
+
return;
|
|
217
|
+
}
|
|
218
|
+
ensureDir(dest);
|
|
219
|
+
// opencode uses .md files directly in agents directory
|
|
220
|
+
for (const srcFile of listFiles(src, '.md')) {
|
|
221
|
+
const destFile = path.join(dest, path.basename(srcFile));
|
|
222
|
+
copyFile(srcFile, destFile);
|
|
223
|
+
}
|
|
224
|
+
console.log(` OpenCode: ${dest}`);
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
function installCodex() {
|
|
228
|
+
const src = SRC.codex;
|
|
229
|
+
const dest = DEST.codex;
|
|
230
|
+
if (!dirExists(src)) {
|
|
231
|
+
console.log(` Warning: source missing ${src}`);
|
|
232
|
+
return;
|
|
233
|
+
}
|
|
234
|
+
ensureDir(dest);
|
|
235
|
+
const srcFile = path.join(src, 'SKILL.md');
|
|
236
|
+
if (fileExists(srcFile)) {
|
|
237
|
+
copyFile(srcFile, path.join(dest, 'SKILL.md'));
|
|
238
|
+
}
|
|
239
|
+
console.log(` Codex: ${dest}`);
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
// --- Uninstall functions ---------------------------------------------------
|
|
243
|
+
|
|
244
|
+
function uninstallClaude() {
|
|
245
|
+
const dest = DEST.claude;
|
|
246
|
+
if (dirExists(dest)) {
|
|
247
|
+
fs.rmSync(dest, { recursive: true, force: true });
|
|
248
|
+
}
|
|
249
|
+
console.log(` Claude: removed`);
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
function uninstallCursor() {
|
|
253
|
+
const destSkills = DEST.cursorSkills;
|
|
254
|
+
if (dirExists(destSkills)) {
|
|
255
|
+
fs.rmSync(destSkills, { recursive: true, force: true });
|
|
256
|
+
}
|
|
257
|
+
console.log(` Cursor: removed`);
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
function uninstallWindsurf() {
|
|
261
|
+
const destSkills = DEST.windsurfSkills;
|
|
262
|
+
if (dirExists(destSkills)) {
|
|
263
|
+
fs.rmSync(destSkills, { recursive: true, force: true });
|
|
264
|
+
}
|
|
265
|
+
console.log(` Windsurf: removed`);
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
function uninstallOpenCode() {
|
|
269
|
+
const dest = DEST.opencode;
|
|
270
|
+
if (dirExists(dest)) {
|
|
271
|
+
for (const f of listFiles(dest, '.md')) {
|
|
272
|
+
if (fileContains(f, MANAGED_MARKER)) {
|
|
273
|
+
fs.unlinkSync(f);
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
console.log(` OpenCode: removed`);
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
function uninstallCodex() {
|
|
281
|
+
const dest = DEST.codex;
|
|
282
|
+
if (dirExists(dest)) {
|
|
283
|
+
fs.rmSync(dest, { recursive: true, force: true });
|
|
284
|
+
}
|
|
285
|
+
console.log(` Codex: removed`);
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
// --- Auto-detection -------------------------------------------------------
|
|
289
|
+
|
|
290
|
+
function detectEditors() {
|
|
291
|
+
const detected = [];
|
|
292
|
+
if (dirExists(path.join(HOME, '.claude'))) detected.push('claude');
|
|
293
|
+
if (dirExists(path.join(HOME, '.cursor'))) detected.push('cursor');
|
|
294
|
+
if (
|
|
295
|
+
dirExists(path.join(HOME, '.windsurf')) ||
|
|
296
|
+
dirExists(path.join(HOME, '.codeium', 'windsurf'))
|
|
297
|
+
) {
|
|
298
|
+
detected.push('windsurf');
|
|
299
|
+
}
|
|
300
|
+
if (
|
|
301
|
+
dirExists(path.join(APPDATA || path.join(HOME, '.config', 'opencode'))) ||
|
|
302
|
+
dirExists(path.join(HOME, '.config', 'opencode'))
|
|
303
|
+
) {
|
|
304
|
+
detected.push('opencode');
|
|
305
|
+
}
|
|
306
|
+
if (
|
|
307
|
+
process.env.CODEX_HOME ||
|
|
308
|
+
dirExists(path.join(HOME, '.codex'))
|
|
309
|
+
) {
|
|
310
|
+
detected.push('codex');
|
|
311
|
+
}
|
|
312
|
+
return detected;
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
// --- CLI parsing ---------------------------------------------------------
|
|
316
|
+
|
|
317
|
+
function printHelp() {
|
|
318
|
+
process.stdout.write(`Usage: node install.js [options]
|
|
319
|
+
|
|
320
|
+
Options:
|
|
321
|
+
--claude Install skills for Claude Code
|
|
322
|
+
--cursor Install skills for Cursor
|
|
323
|
+
--windsurf Install skills for Windsurf
|
|
324
|
+
--opencode Install skills for OpenCode
|
|
325
|
+
--codex Install skills for Codex
|
|
326
|
+
--all Install for all five tools
|
|
327
|
+
--skills-only Skip npm install/build/link (just copy skills)
|
|
328
|
+
--uninstall Remove installed skills from target tools
|
|
329
|
+
--compile-only Generate compiled/ output directory (no install)
|
|
330
|
+
-h, --help Show this help
|
|
331
|
+
|
|
332
|
+
No flags = auto-detect installed tools.
|
|
333
|
+
|
|
334
|
+
Environment overrides:
|
|
335
|
+
CODEX_HOME Codex home directory (default: ~/.codex)
|
|
336
|
+
`);
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
function parseArgs(argv) {
|
|
340
|
+
const targets = [];
|
|
341
|
+
const flags = {
|
|
342
|
+
help: false,
|
|
343
|
+
skillsOnly: false,
|
|
344
|
+
uninstall: false,
|
|
345
|
+
compileOnly: false,
|
|
346
|
+
all: false,
|
|
347
|
+
};
|
|
348
|
+
|
|
349
|
+
for (const arg of argv) {
|
|
350
|
+
switch (arg) {
|
|
351
|
+
case '--claude':
|
|
352
|
+
targets.push('claude');
|
|
353
|
+
break;
|
|
354
|
+
case '--cursor':
|
|
355
|
+
targets.push('cursor');
|
|
356
|
+
break;
|
|
357
|
+
case '--windsurf':
|
|
358
|
+
targets.push('windsurf');
|
|
359
|
+
break;
|
|
360
|
+
case '--opencode':
|
|
361
|
+
targets.push('opencode');
|
|
362
|
+
break;
|
|
363
|
+
case '--codex':
|
|
364
|
+
targets.push('codex');
|
|
365
|
+
break;
|
|
366
|
+
case '--all':
|
|
367
|
+
flags.all = true;
|
|
368
|
+
break;
|
|
369
|
+
case '--skills-only':
|
|
370
|
+
flags.skillsOnly = true;
|
|
371
|
+
break;
|
|
372
|
+
case '--uninstall':
|
|
373
|
+
flags.uninstall = true;
|
|
374
|
+
break;
|
|
375
|
+
case '--compile-only':
|
|
376
|
+
flags.compileOnly = true;
|
|
377
|
+
break;
|
|
378
|
+
case '-h':
|
|
379
|
+
case '--help':
|
|
380
|
+
flags.help = true;
|
|
381
|
+
break;
|
|
382
|
+
default:
|
|
383
|
+
console.error(`Unknown option: ${arg}`);
|
|
384
|
+
console.error('Run: node install.js --help');
|
|
385
|
+
process.exit(1);
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
if (flags.all) {
|
|
390
|
+
targets.length = 0;
|
|
391
|
+
targets.push('claude', 'cursor', 'windsurf', 'opencode', 'codex');
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
return { targets, flags };
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
// --- Build orchestration -------------------------------------------------
|
|
398
|
+
|
|
399
|
+
function buildProject() {
|
|
400
|
+
console.log('--> Installing dependencies...');
|
|
401
|
+
runNpm(['install']);
|
|
402
|
+
|
|
403
|
+
console.log('--> Cleaning previous build...');
|
|
404
|
+
const distDir = path.join(repoDir, 'dist');
|
|
405
|
+
if (dirExists(distDir)) {
|
|
406
|
+
fs.rmSync(distDir, { recursive: true });
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
console.log('--> Building TypeScript...');
|
|
410
|
+
runNpm(['run', 'build']);
|
|
411
|
+
|
|
412
|
+
const distCli = path.join(distDir, 'cli', 'index.js');
|
|
413
|
+
if (fileExists(distCli)) {
|
|
414
|
+
fs.chmodSync(distCli, 0o755);
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
console.log('--> Compiling skills...');
|
|
418
|
+
runNpm(['run', 'compile']);
|
|
419
|
+
|
|
420
|
+
console.log('--> Linking CLI globally...');
|
|
421
|
+
runNpm(['link']);
|
|
422
|
+
|
|
423
|
+
// Verify CLI is available
|
|
424
|
+
const npmPrefix = spawnSync('npm', ['prefix', '-g'], { encoding: 'utf8' }).stdout.trim();
|
|
425
|
+
const cliPath = path.join(npmPrefix, 'bin', CLI_BIN_NAME);
|
|
426
|
+
const cliPathAlt = path.join(npmPrefix, 'bin', `${CLI_BIN_NAME}.cmd`);
|
|
427
|
+
|
|
428
|
+
if (fileExists(cliPath) || fileExists(cliPathAlt)) {
|
|
429
|
+
console.log(` ${CLI_BIN_NAME}: ${cliPath}`);
|
|
430
|
+
} else {
|
|
431
|
+
console.log(` Warning: ${CLI_BIN_NAME} not found after npm link. Try: npm link`);
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
// --- Main -----------------------------------------------------------------
|
|
436
|
+
|
|
437
|
+
function main(argv) {
|
|
438
|
+
const { targets, flags } = parseArgs(argv);
|
|
439
|
+
|
|
440
|
+
if (flags.help) {
|
|
441
|
+
printHelp();
|
|
442
|
+
return;
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
// Compile-only path
|
|
446
|
+
if (flags.compileOnly) {
|
|
447
|
+
console.log('==> Compiling skills...');
|
|
448
|
+
runNode([path.join(repoDir, 'skill', 'build', 'compile.mjs')]);
|
|
449
|
+
console.log('==> Done.');
|
|
450
|
+
return;
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
// Resolve targets
|
|
454
|
+
let resolvedTargets = targets.length > 0 ? targets : detectEditors();
|
|
455
|
+
|
|
456
|
+
if (resolvedTargets.length === 0) {
|
|
457
|
+
console.error(
|
|
458
|
+
'ERROR: No supported tools detected. Use --claude, --cursor, --windsurf, --opencode, or --codex.'
|
|
459
|
+
);
|
|
460
|
+
process.exit(1);
|
|
461
|
+
}
|
|
462
|
+
// Dedupe
|
|
463
|
+
resolvedTargets = [...new Set(resolvedTargets)];
|
|
464
|
+
|
|
465
|
+
console.log(`==> ${PROJECT_NAME} setup`);
|
|
466
|
+
console.log(` Project: ${repoDir}`);
|
|
467
|
+
console.log(` Targets: ${resolvedTargets.join(' ')}`);
|
|
468
|
+
console.log('');
|
|
469
|
+
|
|
470
|
+
// Uninstall path
|
|
471
|
+
if (flags.uninstall) {
|
|
472
|
+
console.log('==> Uninstalling...');
|
|
473
|
+
for (const t of resolvedTargets) {
|
|
474
|
+
switch (t) {
|
|
475
|
+
case 'claude':
|
|
476
|
+
uninstallClaude();
|
|
477
|
+
break;
|
|
478
|
+
case 'cursor':
|
|
479
|
+
uninstallCursor();
|
|
480
|
+
break;
|
|
481
|
+
case 'windsurf':
|
|
482
|
+
uninstallWindsurf();
|
|
483
|
+
break;
|
|
484
|
+
case 'opencode':
|
|
485
|
+
uninstallOpenCode();
|
|
486
|
+
break;
|
|
487
|
+
case 'codex':
|
|
488
|
+
uninstallCodex();
|
|
489
|
+
break;
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
console.log('--> Removing CLI link...');
|
|
494
|
+
runNpm(['unlink', PROJECT_NAME]);
|
|
495
|
+
|
|
496
|
+
console.log('');
|
|
497
|
+
console.log('==> Done. Skills and CLI removed.');
|
|
498
|
+
return;
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
// Install path
|
|
502
|
+
if (!flags.skillsOnly) {
|
|
503
|
+
buildProject();
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
console.log('--> Cleaning stale files...');
|
|
507
|
+
for (const t of resolvedTargets) {
|
|
508
|
+
switch (t) {
|
|
509
|
+
case 'claude':
|
|
510
|
+
cleanupManagedFiles(DEST.claude);
|
|
511
|
+
break;
|
|
512
|
+
case 'cursor':
|
|
513
|
+
cleanupManagedFiles(DEST.cursorSkills);
|
|
514
|
+
break;
|
|
515
|
+
case 'windsurf':
|
|
516
|
+
cleanupManagedFiles(DEST.windsurfSkills);
|
|
517
|
+
break;
|
|
518
|
+
case 'opencode':
|
|
519
|
+
cleanupManagedFiles(DEST.opencode);
|
|
520
|
+
break;
|
|
521
|
+
case 'codex':
|
|
522
|
+
cleanupManagedFiles(DEST.codex);
|
|
523
|
+
break;
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
console.log('--> Installing skills...');
|
|
528
|
+
for (const t of resolvedTargets) {
|
|
529
|
+
switch (t) {
|
|
530
|
+
case 'claude':
|
|
531
|
+
installClaude();
|
|
532
|
+
break;
|
|
533
|
+
case 'cursor':
|
|
534
|
+
installCursor();
|
|
535
|
+
break;
|
|
536
|
+
case 'windsurf':
|
|
537
|
+
installWindsurf();
|
|
538
|
+
break;
|
|
539
|
+
case 'opencode':
|
|
540
|
+
installOpenCode();
|
|
541
|
+
break;
|
|
542
|
+
case 'codex':
|
|
543
|
+
installCodex();
|
|
544
|
+
break;
|
|
545
|
+
}
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
console.log('');
|
|
549
|
+
console.log('==> Done.');
|
|
550
|
+
console.log('');
|
|
551
|
+
console.log(`Skills installed for: ${resolvedTargets.join(' ')}`);
|
|
552
|
+
console.log(`CLI available as: ${CLI_BIN_NAME}`);
|
|
553
|
+
}
|
|
554
|
+
|
|
555
|
+
main(process.argv.slice(2));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agentic-skill-mill",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.11",
|
|
4
4
|
"description": "Forge and refine agent skill projects -- fragment-composed skills compiled to 7 IDE targets with a companion CLI",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -19,10 +19,7 @@
|
|
|
19
19
|
"compiled",
|
|
20
20
|
"skill",
|
|
21
21
|
"README.md",
|
|
22
|
-
"install.
|
|
23
|
-
"install-local.sh",
|
|
24
|
-
"install.ps1",
|
|
25
|
-
"install-local.ps1"
|
|
22
|
+
"install.js"
|
|
26
23
|
],
|
|
27
24
|
"scripts": {
|
|
28
25
|
"build": "tsc -p tsconfig.build.json",
|
|
@@ -31,14 +28,14 @@
|
|
|
31
28
|
"test:coverage": "vitest run --coverage",
|
|
32
29
|
"lint": "eslint src",
|
|
33
30
|
"typecheck": "tsc --noEmit",
|
|
34
|
-
"setup": "
|
|
35
|
-
"setup:all": "
|
|
36
|
-
"setup:windows": "
|
|
37
|
-
"setup:windows:all": "
|
|
38
|
-
"install-skills": "
|
|
39
|
-
"install-skills:windows": "
|
|
40
|
-
"uninstall-skills": "
|
|
41
|
-
"uninstall-skills:windows": "
|
|
31
|
+
"setup": "node install.js",
|
|
32
|
+
"setup:all": "node install.js --all",
|
|
33
|
+
"setup:windows": "node install.js",
|
|
34
|
+
"setup:windows:all": "node install.js --all",
|
|
35
|
+
"install-skills": "node install.js --skills-only",
|
|
36
|
+
"install-skills:windows": "node install.js --skills-only",
|
|
37
|
+
"uninstall-skills": "node install.js --uninstall",
|
|
38
|
+
"uninstall-skills:windows": "node install.js --uninstall",
|
|
42
39
|
"compile": "node skill/build/compile.mjs",
|
|
43
40
|
"compile:validate": "node skill/build/compile.mjs --validate",
|
|
44
41
|
"compile:watch": "node skill/build/compile.mjs --watch"
|
|
@@ -6,7 +6,7 @@ Skills (what to do) CLI Companion (tools to do it with)
|
|
|
6
6
|
skill/fragments/*.md src/core/*.ts
|
|
7
7
|
| |
|
|
8
8
|
v v
|
|
9
|
-
compiled/ (
|
|
9
|
+
compiled/ (5 IDE formats) dist/ (npm -> npx or global CLI)
|
|
10
10
|
| |
|
|
11
11
|
+---------> Agent <----------+
|
|
12
12
|
^
|
|
@@ -31,7 +31,9 @@ Skills (what to do) CLI Companion (tools to do it with)
|
|
|
31
31
|
- `src/errors/types.ts` — Typed error hierarchy (AppError, NotFoundError, etc.)
|
|
32
32
|
- `src/cache/cache-manager.ts` — Two-tier cache (memory + disk) with TTL
|
|
33
33
|
|
|
34
|
-
**
|
|
34
|
+
**Local installers:** Every project ships a single cross-platform `install.js` (Node.js).
|
|
35
|
+
|
|
36
|
+
**The installer** (`install.js`) builds the CLI, compiles skills, and copies compiled outputs to IDE-specific directories (~/.claude/skills, ~/.cursor/rules, etc.) with marker-based stale file cleanup. The bootstrap installer is hosted at `https://agenticskillmill.com/install.sh` and bundled in the npm package. It installs the npm utility first, then delegates to `node install.js --skills-only`.
|
|
35
37
|
|
|
36
38
|
### Key files to modify when augmenting a project
|
|
37
39
|
|
|
@@ -39,8 +41,8 @@ Skills (what to do) CLI Companion (tools to do it with)
|
|
|
39
41
|
|------|---------|
|
|
40
42
|
| Add a CLI command | `src/core/<name>.ts`, `src/cli/commands/<name>.ts`, `src/cli/index.ts`, `src/index.ts` |
|
|
41
43
|
| Add a fragment | `skill/fragments/<category>/<name>.md`, `skill/build/manifest.json`, skill source |
|
|
42
|
-
| Add a skill | `skill/skills/<name>/<name>.md`, `skill/build/manifest.json
|
|
43
|
-
| Change installer behavior | `install.
|
|
44
|
+
| Add a skill | `skill/skills/<name>/<name>.md`, `skill/build/manifest.json` |
|
|
45
|
+
| Change installer behavior | `install.js`, then copy to `site/install.sh` and `site/install.ps1` |
|
|
44
46
|
| Update the landing page | `site/index.html`, `site/style.css` |
|
|
45
47
|
| Change CI secrets or workflow | `.github/workflows/release.yml` or `deploy-pages.yml`, repo settings |
|
|
46
48
|
| Rename the project | See the rename workflow |
|