@light-merlin-dark/skill-sync 0.1.1 → 0.1.3
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/CHANGELOG.md +8 -0
- package/SKILL.md +4 -1
- package/dist/index.js +51 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.1.3
|
|
4
|
+
- Makefile release: robust GitHub release notes generation via `--notes-file` and correct escaping of `awk $0`.
|
|
5
|
+
|
|
6
|
+
## 0.1.2
|
|
7
|
+
- Report installed “orphan” skills during `skill-sync check` (helps explain why a harness skill UI didn’t update)
|
|
8
|
+
- Add `make release` target (pre-publish → npm publish → git tag + push → GitHub release create/update)
|
|
9
|
+
- Minor: manager skill naming support (codex-style capitalized display)
|
|
10
|
+
|
|
3
11
|
## 0.1.1
|
|
4
12
|
- Add source-topology diagnostics for duplicate skill slugs in configured project roots
|
|
5
13
|
- Surface resolved duplicates as warnings and unresolved duplicates as blocking errors in `check` and `sources`
|
package/SKILL.md
CHANGED
|
@@ -73,6 +73,9 @@ skill-sync harnesses --json
|
|
|
73
73
|
## Safety Rules
|
|
74
74
|
|
|
75
75
|
- Prefer `check` before `sync`.
|
|
76
|
-
-
|
|
76
|
+
- If `check` reports a `conflict` due to an existing *unmanaged* install (common case: a skill folder already exists in a harness root like `~/.hermes/skills/<skill>`), resolve by either:
|
|
77
|
+
- removing the unmanaged directory/file and re-running `sync`, or
|
|
78
|
+
- restoring via `skill-sync backup restore <backup-id>`.
|
|
79
|
+
Do not leave mixed symlink + real directories behind.
|
|
77
80
|
- Use `--home` for isolated testing against a fake home directory.
|
|
78
81
|
- Use `--projects-root` when you need to constrain discovery to a specific source tree.
|
package/dist/index.js
CHANGED
|
@@ -1288,12 +1288,52 @@ function buildSyncPlan(skills, harnesses, config, state, sourceDiagnostics) {
|
|
|
1288
1288
|
}
|
|
1289
1289
|
harnessPlan.entries.sort((a, b) => a.destinationPath.localeCompare(b.destinationPath));
|
|
1290
1290
|
}
|
|
1291
|
+
const orphanSkills = [];
|
|
1292
|
+
for (const harnessPlan of harnessPlans) {
|
|
1293
|
+
const desiredSet = desiredByHarness.get(harnessPlan.harness.id) || new Set;
|
|
1294
|
+
let children = [];
|
|
1295
|
+
try {
|
|
1296
|
+
children = readdirSync3(harnessPlan.harness.rootPath);
|
|
1297
|
+
} catch {
|
|
1298
|
+
continue;
|
|
1299
|
+
}
|
|
1300
|
+
for (const child of children) {
|
|
1301
|
+
const destinationPath = join5(harnessPlan.harness.rootPath, child);
|
|
1302
|
+
if (desiredSet.has(destinationPath)) {
|
|
1303
|
+
continue;
|
|
1304
|
+
}
|
|
1305
|
+
if (state.managedEntries[destinationPath]) {
|
|
1306
|
+
continue;
|
|
1307
|
+
}
|
|
1308
|
+
const inspection = inspectEntry(destinationPath);
|
|
1309
|
+
if (!inspection.exists) {
|
|
1310
|
+
continue;
|
|
1311
|
+
}
|
|
1312
|
+
let hasSkillMd = false;
|
|
1313
|
+
if (inspection.type === "directory") {
|
|
1314
|
+
hasSkillMd = existsSync6(join5(destinationPath, "SKILL.md"));
|
|
1315
|
+
} else if (inspection.type === "symlink" && inspection.resolvedTarget) {
|
|
1316
|
+
hasSkillMd = existsSync6(join5(inspection.resolvedTarget, "SKILL.md"));
|
|
1317
|
+
}
|
|
1318
|
+
if (!hasSkillMd) {
|
|
1319
|
+
continue;
|
|
1320
|
+
}
|
|
1321
|
+
orphanSkills.push({
|
|
1322
|
+
harnessId: harnessPlan.harness.id,
|
|
1323
|
+
harnessRoot: harnessPlan.harness.rootPath,
|
|
1324
|
+
installName: child,
|
|
1325
|
+
destinationPath,
|
|
1326
|
+
inspection
|
|
1327
|
+
});
|
|
1328
|
+
}
|
|
1329
|
+
}
|
|
1291
1330
|
return {
|
|
1292
1331
|
harnesses: harnessPlans,
|
|
1293
1332
|
changes,
|
|
1294
1333
|
conflicts,
|
|
1295
1334
|
ok,
|
|
1296
|
-
sourceDiagnostics: sourceDiagnostics || { warnings: [], errors: [] }
|
|
1335
|
+
sourceDiagnostics: sourceDiagnostics || { warnings: [], errors: [] },
|
|
1336
|
+
orphanSkills: orphanSkills.length ? orphanSkills : undefined
|
|
1297
1337
|
};
|
|
1298
1338
|
}
|
|
1299
1339
|
function buildPlannedEntry(skill, harness, installName, destinationPath, state, config) {
|
|
@@ -1450,6 +1490,16 @@ function print(value, json) {
|
|
|
1450
1490
|
function renderPlan(plan) {
|
|
1451
1491
|
const lines = [];
|
|
1452
1492
|
appendSourceDiagnostics(lines, plan.sourceDiagnostics);
|
|
1493
|
+
if (plan.orphanSkills && plan.orphanSkills.length > 0) {
|
|
1494
|
+
if (lines.length > 0) {
|
|
1495
|
+
lines.push("");
|
|
1496
|
+
}
|
|
1497
|
+
lines.push("Orphan installed skills:");
|
|
1498
|
+
for (const orphan of plan.orphanSkills) {
|
|
1499
|
+
const resolved = orphan.inspection.type === "symlink" ? orphan.inspection.resolvedTarget || orphan.inspection.linkTarget : undefined;
|
|
1500
|
+
lines.push(`- ${orphan.harnessId}/${orphan.installName} ${orphan.destinationPath}${resolved ? ` -> ${resolved}` : ""}`);
|
|
1501
|
+
}
|
|
1502
|
+
}
|
|
1453
1503
|
const counts = countPlanActions(plan);
|
|
1454
1504
|
if (lines.length > 0) {
|
|
1455
1505
|
lines.push("");
|
package/package.json
CHANGED