skiller 0.8.2 → 0.9.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/dist/cli/commands.js +60 -1
- package/dist/cli/handlers.js +240 -5
- package/dist/cli/skills-cli.js +72 -0
- package/dist/constants.js +2 -1
- package/dist/core/ClaudePluginMigration.js +229 -0
- package/dist/core/ClaudePluginSync.js +1 -34
- package/dist/core/ClaudeProjectSync.js +37 -58
- package/dist/core/ConfigLoader.js +4 -4
- package/dist/core/FileSystemUtils.js +19 -48
- package/dist/core/FrontmatterParser.js +11 -1
- package/dist/core/LegacyClaudePluginState.js +123 -0
- package/dist/core/RulesToSkillsMigration.js +173 -0
- package/dist/core/SkillOwnership.js +397 -0
- package/dist/core/SkillsManifest.js +79 -23
- package/dist/core/SkillsProcessor.js +565 -317
- package/dist/core/SkillsUtils.js +6 -11
- package/dist/core/UnifiedConfigLoader.js +6 -5
- package/dist/core/project-paths.js +8 -0
- package/dist/lib.js +10 -16
- package/package.json +8 -8
|
@@ -37,10 +37,13 @@ exports.SKILLS_MANIFEST_VERSION = exports.LEGACY_CLAUDE_MANIFEST_FILENAME = expo
|
|
|
37
37
|
exports.isPluginManifestEntry = isPluginManifestEntry;
|
|
38
38
|
exports.isClaudeManifestEntry = isClaudeManifestEntry;
|
|
39
39
|
exports.loadSkillsManifestEntries = loadSkillsManifestEntries;
|
|
40
|
+
exports.loadLocalSkillNames = loadLocalSkillNames;
|
|
41
|
+
exports.writeLocalSkillNames = writeLocalSkillNames;
|
|
40
42
|
exports.writeSkillsManifestEntries = writeSkillsManifestEntries;
|
|
41
43
|
exports.listSkillDirectories = listSkillDirectories;
|
|
42
44
|
const fs = __importStar(require("fs/promises"));
|
|
43
45
|
const path = __importStar(require("path"));
|
|
46
|
+
const project_paths_1 = require("./project-paths");
|
|
44
47
|
// Project-level manifest (stored in `.claude/.skiller.json`) that tracks what
|
|
45
48
|
// Skiller installed into each target agent skills directory for this project.
|
|
46
49
|
exports.SKILLS_MANIFEST_FILENAME = '.skiller.json';
|
|
@@ -154,6 +157,24 @@ function computeTargetKey(projectRoot, targetSkillsDir) {
|
|
|
154
157
|
}
|
|
155
158
|
return normalizePathForKey(resolvedTarget);
|
|
156
159
|
}
|
|
160
|
+
function computeCompatibleTargetKeys(projectRoot, targetSkillsDir) {
|
|
161
|
+
const keys = new Set([
|
|
162
|
+
computeTargetKey(projectRoot, targetSkillsDir),
|
|
163
|
+
normalizePathForKey(targetSkillsDir),
|
|
164
|
+
]);
|
|
165
|
+
const resolvedTarget = path.resolve(targetSkillsDir);
|
|
166
|
+
const canonicalSkillsDir = path.resolve(projectRoot, project_paths_1.CANONICAL_SKILLER_DIR, 'skills');
|
|
167
|
+
const legacySkillsDir = path.resolve(projectRoot, project_paths_1.LEGACY_SKILLER_DIR, 'skills');
|
|
168
|
+
if (resolvedTarget === canonicalSkillsDir ||
|
|
169
|
+
resolvedTarget === legacySkillsDir) {
|
|
170
|
+
const aliasTarget = resolvedTarget === canonicalSkillsDir
|
|
171
|
+
? legacySkillsDir
|
|
172
|
+
: canonicalSkillsDir;
|
|
173
|
+
keys.add(computeTargetKey(projectRoot, aliasTarget));
|
|
174
|
+
keys.add(normalizePathForKey(aliasTarget));
|
|
175
|
+
}
|
|
176
|
+
return [...keys];
|
|
177
|
+
}
|
|
157
178
|
function parseProjectTargets(raw) {
|
|
158
179
|
if (!raw || typeof raw !== 'object')
|
|
159
180
|
return {};
|
|
@@ -170,6 +191,31 @@ function parseProjectTargets(raw) {
|
|
|
170
191
|
}
|
|
171
192
|
return out;
|
|
172
193
|
}
|
|
194
|
+
function parseLocalSkills(raw) {
|
|
195
|
+
if (!raw || typeof raw !== 'object')
|
|
196
|
+
return [];
|
|
197
|
+
const obj = raw;
|
|
198
|
+
if (!Array.isArray(obj.localSkills))
|
|
199
|
+
return [];
|
|
200
|
+
return [
|
|
201
|
+
...new Set(obj.localSkills.filter((v) => typeof v === 'string')),
|
|
202
|
+
].sort((a, b) => a.localeCompare(b));
|
|
203
|
+
}
|
|
204
|
+
async function readProjectManifestRaw(projectRoot) {
|
|
205
|
+
const canonicalManifestPath = path.join(projectRoot, project_paths_1.CANONICAL_SKILLER_DIR, exports.SKILLS_MANIFEST_FILENAME);
|
|
206
|
+
const legacyManifestPath = path.join(projectRoot, project_paths_1.LEGACY_SKILLER_DIR, exports.SKILLS_MANIFEST_FILENAME);
|
|
207
|
+
for (const manifestPath of [canonicalManifestPath, legacyManifestPath]) {
|
|
208
|
+
if (!(await fileExists(manifestPath)))
|
|
209
|
+
continue;
|
|
210
|
+
try {
|
|
211
|
+
return JSON.parse(await fs.readFile(manifestPath, 'utf8'));
|
|
212
|
+
}
|
|
213
|
+
catch {
|
|
214
|
+
return null;
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
return null;
|
|
218
|
+
}
|
|
173
219
|
function parseLegacyPluginEntries(raw) {
|
|
174
220
|
if (!raw || typeof raw !== 'object')
|
|
175
221
|
return [];
|
|
@@ -277,40 +323,49 @@ async function loadLegacyTargetSkillsManifestEntries(targetSkillsDir) {
|
|
|
277
323
|
return normalizeEntries(merged);
|
|
278
324
|
}
|
|
279
325
|
async function loadSkillsManifestEntries(projectRoot, targetSkillsDir) {
|
|
280
|
-
const
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
const targets = parseProjectTargets(raw);
|
|
288
|
-
const entries = targets[preferredTargetKey] ?? targets[absoluteTargetKey] ?? [];
|
|
289
|
-
return normalizeEntries(entries);
|
|
290
|
-
}
|
|
291
|
-
catch {
|
|
292
|
-
return [];
|
|
326
|
+
const raw = await readProjectManifestRaw(projectRoot);
|
|
327
|
+
if (raw) {
|
|
328
|
+
const targets = parseProjectTargets(raw);
|
|
329
|
+
for (const key of computeCompatibleTargetKeys(projectRoot, targetSkillsDir)) {
|
|
330
|
+
const entries = targets[key];
|
|
331
|
+
if (entries)
|
|
332
|
+
return normalizeEntries(entries);
|
|
293
333
|
}
|
|
334
|
+
return [];
|
|
294
335
|
}
|
|
295
336
|
// Legacy migration: prior versions stored manifests in the target skills dir.
|
|
296
337
|
return await loadLegacyTargetSkillsManifestEntries(targetSkillsDir);
|
|
297
338
|
}
|
|
339
|
+
async function loadLocalSkillNames(projectRoot) {
|
|
340
|
+
const raw = await readProjectManifestRaw(projectRoot);
|
|
341
|
+
return parseLocalSkills(raw);
|
|
342
|
+
}
|
|
343
|
+
async function writeLocalSkillNames(projectRoot, localSkillNames, dryRun) {
|
|
344
|
+
const projectSkillerDir = path.join(projectRoot, project_paths_1.CANONICAL_SKILLER_DIR);
|
|
345
|
+
const projectManifestPath = path.join(projectSkillerDir, exports.SKILLS_MANIFEST_FILENAME);
|
|
346
|
+
const raw = await readProjectManifestRaw(projectRoot);
|
|
347
|
+
const existingTargets = parseProjectTargets(raw);
|
|
348
|
+
const nextLocalSkills = [...new Set(localSkillNames)].sort((a, b) => a.localeCompare(b));
|
|
349
|
+
if (dryRun)
|
|
350
|
+
return;
|
|
351
|
+
await fs.mkdir(projectSkillerDir, { recursive: true });
|
|
352
|
+
const manifest = {
|
|
353
|
+
version: exports.SKILLS_MANIFEST_VERSION,
|
|
354
|
+
targets: existingTargets,
|
|
355
|
+
localSkills: nextLocalSkills,
|
|
356
|
+
};
|
|
357
|
+
await fs.writeFile(projectManifestPath, JSON.stringify(manifest, null, 2) + '\n');
|
|
358
|
+
}
|
|
298
359
|
async function writeSkillsManifestEntries(projectRoot, targetSkillsDir, entries, dryRun) {
|
|
299
360
|
const normalized = normalizeEntries(entries);
|
|
300
|
-
const projectClaudeDir = path.join(projectRoot,
|
|
361
|
+
const projectClaudeDir = path.join(projectRoot, project_paths_1.CANONICAL_SKILLER_DIR);
|
|
301
362
|
const projectManifestPath = path.join(projectClaudeDir, exports.SKILLS_MANIFEST_FILENAME);
|
|
302
363
|
const preferredTargetKey = computeTargetKey(projectRoot, targetSkillsDir);
|
|
303
364
|
const absoluteTargetKey = normalizePathForKey(targetSkillsDir);
|
|
304
365
|
let existingTargets = {};
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
existingTargets = parseProjectTargets(raw);
|
|
309
|
-
}
|
|
310
|
-
catch {
|
|
311
|
-
existingTargets = {};
|
|
312
|
-
}
|
|
313
|
-
}
|
|
366
|
+
const raw = await readProjectManifestRaw(projectRoot);
|
|
367
|
+
existingTargets = parseProjectTargets(raw);
|
|
368
|
+
const existingLocalSkills = parseLocalSkills(raw);
|
|
314
369
|
if (normalized.length === 0) {
|
|
315
370
|
delete existingTargets[preferredTargetKey];
|
|
316
371
|
if (preferredTargetKey !== absoluteTargetKey) {
|
|
@@ -338,6 +393,7 @@ async function writeSkillsManifestEntries(projectRoot, targetSkillsDir, entries,
|
|
|
338
393
|
const manifest = {
|
|
339
394
|
version: exports.SKILLS_MANIFEST_VERSION,
|
|
340
395
|
targets: nextTargets,
|
|
396
|
+
localSkills: existingLocalSkills,
|
|
341
397
|
};
|
|
342
398
|
await fs.writeFile(projectManifestPath, JSON.stringify(manifest, null, 2) + '\n');
|
|
343
399
|
}
|