@delorenj/skillex 0.4.0 → 0.4.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/dist/cli.js +67 -28
- package/dist/index.js +67 -28
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -8620,7 +8620,7 @@ async function buildScope(scope, options, forbiddenRoots, verifySet = verifySele
|
|
|
8620
8620
|
if (!owned4)
|
|
8621
8621
|
refuse3(root, "Whole-root switching requires explicit ownership of the existing root.");
|
|
8622
8622
|
if (owned4.kind === "link") return { identity: owned4 };
|
|
8623
|
-
const
|
|
8623
|
+
const children2 = {};
|
|
8624
8624
|
for (const name of awaitableNames) {
|
|
8625
8625
|
const child = links[join25(root, name)];
|
|
8626
8626
|
if (!child)
|
|
@@ -8628,9 +8628,9 @@ async function buildScope(scope, options, forbiddenRoots, verifySet = verifySele
|
|
|
8628
8628
|
join25(root, name),
|
|
8629
8629
|
"Foreign content prevents a whole-root switch; it will not be removed."
|
|
8630
8630
|
);
|
|
8631
|
-
|
|
8631
|
+
children2[name] = child;
|
|
8632
8632
|
}
|
|
8633
|
-
return { identity: owned4, children };
|
|
8633
|
+
return { identity: owned4, children: children2 };
|
|
8634
8634
|
};
|
|
8635
8635
|
const awaitableNames = rootEntry?.info.isDirectory() ? await readdir16(physicalPath(root, recovery)) : [];
|
|
8636
8636
|
if (!rootEntry) {
|
|
@@ -8969,7 +8969,7 @@ async function publishPrepared(work, staged, destination, node, directories) {
|
|
|
8969
8969
|
async function stageNode(work, operation2, path) {
|
|
8970
8970
|
if (operation2.children !== void 0) {
|
|
8971
8971
|
await mkdir7(path, { mode: 493 });
|
|
8972
|
-
const
|
|
8972
|
+
const children2 = {};
|
|
8973
8973
|
for (const [name, target2] of operation2.children) {
|
|
8974
8974
|
const destination = join25(operation2.path, name);
|
|
8975
8975
|
if (!await canonicalTarget(work, name, target2))
|
|
@@ -8978,11 +8978,11 @@ async function stageNode(work, operation2, path) {
|
|
|
8978
8978
|
await symlink4(relative9(dirname13(destination), target2), child);
|
|
8979
8979
|
const found2 = await entry2(child);
|
|
8980
8980
|
if (!found2) refuse3(child, "Prepared activation link disappeared.");
|
|
8981
|
-
|
|
8981
|
+
children2[name] = identity(found2);
|
|
8982
8982
|
}
|
|
8983
8983
|
const found = await entry2(path);
|
|
8984
8984
|
if (!found) refuse3(path, "Prepared activation directory disappeared.");
|
|
8985
|
-
return { identity: identity(found), children };
|
|
8985
|
+
return { identity: identity(found), children: children2 };
|
|
8986
8986
|
}
|
|
8987
8987
|
if (operation2.target !== void 0) {
|
|
8988
8988
|
if (dirname13(operation2.path) === work.plan.activationRoot && !await canonicalTarget(work, basename5(operation2.path), operation2.target))
|
|
@@ -11417,7 +11417,7 @@ async function captureMigrationNode(path) {
|
|
|
11417
11417
|
mode: Number(before.mode & 0o7777n),
|
|
11418
11418
|
...before.isSymbolicLink() ? { raw: await readlink6(path) } : {}
|
|
11419
11419
|
};
|
|
11420
|
-
const
|
|
11420
|
+
const children2 = {};
|
|
11421
11421
|
let hash5 = null;
|
|
11422
11422
|
if (before.isDirectory()) {
|
|
11423
11423
|
const names2 = await readdir22(path, { encoding: "buffer" });
|
|
@@ -11434,7 +11434,7 @@ async function captureMigrationNode(path) {
|
|
|
11434
11434
|
const child = await captureMigrationNode(join31(path, name));
|
|
11435
11435
|
if (!child)
|
|
11436
11436
|
migrationRefusal(join31(path, name), "Content disappeared during migration inventory.");
|
|
11437
|
-
Object.defineProperty(
|
|
11437
|
+
Object.defineProperty(children2, name, { value: child, enumerable: true });
|
|
11438
11438
|
}
|
|
11439
11439
|
} else if (before.isFile()) {
|
|
11440
11440
|
const handle = await open10(
|
|
@@ -11473,7 +11473,7 @@ async function captureMigrationNode(path) {
|
|
|
11473
11473
|
const after = await lstat20(path, { bigint: true });
|
|
11474
11474
|
if (after.dev !== before.dev || after.ino !== before.ino || after.mode !== before.mode || after.size !== before.size || after.mtimeNs !== before.mtimeNs || after.ctimeNs !== before.ctimeNs)
|
|
11475
11475
|
migrationRefusal(path, "Content changed while its migration inventory was being captured.");
|
|
11476
|
-
return { identity: identity5, hash: hash5, children };
|
|
11476
|
+
return { identity: identity5, hash: hash5, children: children2 };
|
|
11477
11477
|
}
|
|
11478
11478
|
function migrationDigest(node) {
|
|
11479
11479
|
const project = (item2) => ({
|
|
@@ -12574,16 +12574,16 @@ async function prepare2(target2) {
|
|
|
12574
12574
|
shared,
|
|
12575
12575
|
"The old alias points at one skill definition rather than a collection root."
|
|
12576
12576
|
);
|
|
12577
|
-
const
|
|
12577
|
+
const children2 = {};
|
|
12578
12578
|
const claimNames = [];
|
|
12579
12579
|
const proofs = [{ path: shared, node: contents }];
|
|
12580
12580
|
for (const name of Object.keys(contents.children)) {
|
|
12581
12581
|
const path = join34(target2.root, name);
|
|
12582
12582
|
const mapped2 = await canonicalMapping(target2, path);
|
|
12583
12583
|
const output2 = mapped2?.name ?? name;
|
|
12584
|
-
if (Object.hasOwn(
|
|
12584
|
+
if (Object.hasOwn(children2, output2))
|
|
12585
12585
|
migrationRefusal(path, "Two original children map to the same resulting name.");
|
|
12586
|
-
Object.defineProperty(
|
|
12586
|
+
Object.defineProperty(children2, output2, {
|
|
12587
12587
|
value: mapped2?.target ?? join34(shared, name),
|
|
12588
12588
|
enumerable: true
|
|
12589
12589
|
});
|
|
@@ -12598,7 +12598,7 @@ async function prepare2(target2) {
|
|
|
12598
12598
|
[
|
|
12599
12599
|
mapped2 ? "The mapped canonical content is verified." : "The original child remains reachable through a foreign forwarding link; its shared target is untouched."
|
|
12600
12600
|
],
|
|
12601
|
-
|
|
12601
|
+
children2[output2]
|
|
12602
12602
|
)
|
|
12603
12603
|
);
|
|
12604
12604
|
}
|
|
@@ -12607,7 +12607,7 @@ async function prepare2(target2) {
|
|
|
12607
12607
|
"Replace only the old root symlink with a real directory; preserve every inventoried child and leave the shared target untouched."
|
|
12608
12608
|
]),
|
|
12609
12609
|
previous: root,
|
|
12610
|
-
children,
|
|
12610
|
+
children: children2,
|
|
12611
12611
|
claimRoot: true,
|
|
12612
12612
|
claimNames,
|
|
12613
12613
|
proofs
|
|
@@ -18229,13 +18229,13 @@ async function normalizeScope(options = {}) {
|
|
|
18229
18229
|
// src/core/profile-sync.ts
|
|
18230
18230
|
import { randomUUID as randomUUID11 } from "node:crypto";
|
|
18231
18231
|
import { constants as constants13 } from "node:fs";
|
|
18232
|
-
import { mkdir as mkdir12, open as open17, readdir as
|
|
18232
|
+
import { mkdir as mkdir12, open as open17, readdir as readdir30, realpath as realpath32, rename as rename11, symlink as symlink7, unlink as unlink12 } from "node:fs/promises";
|
|
18233
18233
|
import { dirname as dirname27, join as join44, resolve as resolve25 } from "node:path";
|
|
18234
18234
|
import { isDeepStrictEqual as isDeepStrictEqual10 } from "node:util";
|
|
18235
18235
|
|
|
18236
18236
|
// src/core/profile-policy.ts
|
|
18237
18237
|
import { constants as constants12 } from "node:fs";
|
|
18238
|
-
import { open as open16, readFile as readFile18, stat as stat8 } from "node:fs/promises";
|
|
18238
|
+
import { open as open16, readdir as readdir29, readFile as readFile18, stat as stat8 } from "node:fs/promises";
|
|
18239
18239
|
import { join as join43 } from "node:path";
|
|
18240
18240
|
import { parseDocument as parseDocument4 } from "yaml";
|
|
18241
18241
|
var metadataFiles = /* @__PURE__ */ new Set([
|
|
@@ -18248,9 +18248,48 @@ var metadataFiles = /* @__PURE__ */ new Set([
|
|
|
18248
18248
|
".curator_ledger.jsonl"
|
|
18249
18249
|
]);
|
|
18250
18250
|
var metadataDirectories = /* @__PURE__ */ new Set([".curator_backups", ".locks"]);
|
|
18251
|
-
|
|
18251
|
+
var hubFiles = /* @__PURE__ */ new Set(["audit.log", "taps.json", "lock.json"]);
|
|
18252
|
+
async function children(path) {
|
|
18253
|
+
try {
|
|
18254
|
+
return await readdir29(path, { withFileTypes: true });
|
|
18255
|
+
} catch {
|
|
18256
|
+
return null;
|
|
18257
|
+
}
|
|
18258
|
+
}
|
|
18259
|
+
async function categoryStub(item2) {
|
|
18260
|
+
if (item2.kind !== "directory" || item2.shadows) return false;
|
|
18261
|
+
const entries = await children(item2.path);
|
|
18262
|
+
return entries?.length === 1 && entries[0]?.name === "DESCRIPTION.md" && entries[0].isFile();
|
|
18263
|
+
}
|
|
18264
|
+
async function idleHub(item2) {
|
|
18265
|
+
if (item2.kind !== "directory" || item2.name !== ".hub") return false;
|
|
18266
|
+
const entries = await children(item2.path);
|
|
18267
|
+
if (!entries) return false;
|
|
18268
|
+
for (const child of entries) {
|
|
18269
|
+
const path = join43(item2.path, child.name);
|
|
18270
|
+
if (child.isFile() && hubFiles.has(child.name)) {
|
|
18271
|
+
if (child.name !== "lock.json") continue;
|
|
18272
|
+
try {
|
|
18273
|
+
const lock = JSON.parse(await readFile18(path, "utf8"));
|
|
18274
|
+
const installed = lock?.installed;
|
|
18275
|
+
if (!installed || typeof installed !== "object" || Object.keys(installed).length)
|
|
18276
|
+
return false;
|
|
18277
|
+
} catch {
|
|
18278
|
+
return false;
|
|
18279
|
+
}
|
|
18280
|
+
} else if (child.isDirectory() && child.name === "quarantine") {
|
|
18281
|
+
if ((await children(path))?.length !== 0) return false;
|
|
18282
|
+
} else if (child.isDirectory() && child.name === "index-cache") {
|
|
18283
|
+
const cached2 = await children(path);
|
|
18284
|
+
if (!cached2 || cached2.some((entry3) => !entry3.isFile())) return false;
|
|
18285
|
+
} else return false;
|
|
18286
|
+
}
|
|
18287
|
+
return true;
|
|
18288
|
+
}
|
|
18289
|
+
async function hermesMetadata(item2) {
|
|
18252
18290
|
if (item2.kind === "file") return metadataFiles.has(item2.name);
|
|
18253
|
-
if (item2.kind === "directory")
|
|
18291
|
+
if (item2.kind === "directory")
|
|
18292
|
+
return metadataDirectories.has(item2.name) || await idleHub(item2) || await categoryStub(item2);
|
|
18254
18293
|
return false;
|
|
18255
18294
|
}
|
|
18256
18295
|
function refuse5(path, message) {
|
|
@@ -18288,7 +18327,7 @@ async function profileInheritsGlobal(profile) {
|
|
|
18288
18327
|
async function assertStrictProfile(profile, options, local) {
|
|
18289
18328
|
if (!await strictProfile(profile, options)) return false;
|
|
18290
18329
|
for (const item2 of local)
|
|
18291
|
-
if (!hermesMetadata(item2))
|
|
18330
|
+
if (!await hermesMetadata(item2))
|
|
18292
18331
|
refuse5(item2.path, `Skillex-only profile contains unowned entry ${item2.name}.`);
|
|
18293
18332
|
const path = join43(profile.root, "config.yaml");
|
|
18294
18333
|
const config = await entry2(path);
|
|
@@ -18461,7 +18500,7 @@ async function observations(profile, state) {
|
|
|
18461
18500
|
"Use the explicit migrate workflow to replace this whole-root alias or conflicting file while preserving profile content."
|
|
18462
18501
|
);
|
|
18463
18502
|
if (root)
|
|
18464
|
-
for (const name of (await
|
|
18503
|
+
for (const name of (await readdir30(profile.skillsRoot)).sort()) {
|
|
18465
18504
|
const path = join44(profile.skillsRoot, name);
|
|
18466
18505
|
const actual = await entry2(path);
|
|
18467
18506
|
if (!actual) continue;
|
|
@@ -20669,7 +20708,7 @@ async function adoptRoot(options = {}) {
|
|
|
20669
20708
|
}
|
|
20670
20709
|
|
|
20671
20710
|
// src/core/sets.ts
|
|
20672
|
-
import { readdir as
|
|
20711
|
+
import { readdir as readdir31 } from "node:fs/promises";
|
|
20673
20712
|
import { join as join47 } from "node:path";
|
|
20674
20713
|
function validateName(name) {
|
|
20675
20714
|
parseManifest({ sets: [{ name }] }, "set name");
|
|
@@ -20692,7 +20731,7 @@ async function listSets(options = {}) {
|
|
|
20692
20731
|
const failures = [];
|
|
20693
20732
|
if (await inspectPath(path)) {
|
|
20694
20733
|
await requireDirectory(path, "E_SET_MISSING");
|
|
20695
|
-
for (const entry3 of (await
|
|
20734
|
+
for (const entry3 of (await readdir31(path, { withFileTypes: true })).sort(
|
|
20696
20735
|
(a, b) => a.name < b.name ? -1 : a.name > b.name ? 1 : 0
|
|
20697
20736
|
)) {
|
|
20698
20737
|
if (entry3.name.startsWith(".") || entry3.name.startsWith("_") || !entry3.isDirectory() && !entry3.isSymbolicLink())
|
|
@@ -20834,7 +20873,7 @@ async function removeSetSkills(name, names2, options = {}) {
|
|
|
20834
20873
|
}
|
|
20835
20874
|
|
|
20836
20875
|
// src/core/vendor-inspect.ts
|
|
20837
|
-
import { readdir as
|
|
20876
|
+
import { readdir as readdir32 } from "node:fs/promises";
|
|
20838
20877
|
import { join as join48 } from "node:path";
|
|
20839
20878
|
|
|
20840
20879
|
// src/core/vendor-git.ts
|
|
@@ -21126,8 +21165,8 @@ async function readVendorGitSource(source, checkoutRoot, options = {}) {
|
|
|
21126
21165
|
checkout
|
|
21127
21166
|
).trim();
|
|
21128
21167
|
const base = await treeAt(checkout, rootTree, source.subdir, options);
|
|
21129
|
-
const
|
|
21130
|
-
const declarations = source.membership === "explicit" ? source.skills :
|
|
21168
|
+
const children2 = await treeEntries(checkout, base, options);
|
|
21169
|
+
const declarations = source.membership === "explicit" ? source.skills : children2.filter(
|
|
21131
21170
|
(entry3) => !entry3.name.startsWith(".") && !entry3.name.startsWith("_") && (entry3.type === "tree" || entry3.mode === "120000" || entry3.mode === "160000")
|
|
21132
21171
|
).map((entry3) => ({ name: entry3.name, dir: entry3.name }));
|
|
21133
21172
|
const selected = declarations.filter(
|
|
@@ -21199,7 +21238,7 @@ async function recordedInventory(manifest, observation, options) {
|
|
|
21199
21238
|
const recorded = /* @__PURE__ */ new Map();
|
|
21200
21239
|
const failed2 = /* @__PURE__ */ new Set();
|
|
21201
21240
|
const catalog = join48(manifest.registry.root, "all-skills");
|
|
21202
|
-
for (const entry3 of (await
|
|
21241
|
+
for (const entry3 of (await readdir32(catalog, { withFileTypes: true })).sort(
|
|
21203
21242
|
(a, b) => a.name.localeCompare(b.name)
|
|
21204
21243
|
)) {
|
|
21205
21244
|
checkVendorSignal(options);
|
|
@@ -21672,7 +21711,7 @@ async function inspectVendorStatus(options = {}) {
|
|
|
21672
21711
|
|
|
21673
21712
|
// src/core/vendor-sync.ts
|
|
21674
21713
|
import { randomUUID as randomUUID14 } from "node:crypto";
|
|
21675
|
-
import { chmod as chmod4, lstat as lstat27, mkdir as mkdir14, open as open20, readdir as
|
|
21714
|
+
import { chmod as chmod4, lstat as lstat27, mkdir as mkdir14, open as open20, readdir as readdir33, rename as rename14 } from "node:fs/promises";
|
|
21676
21715
|
import { dirname as dirname30, join as join49 } from "node:path";
|
|
21677
21716
|
function refuse8(code, message, path, fix) {
|
|
21678
21717
|
fail(code, message, { path, fix }, ExitCode.REFUSED);
|
|
@@ -21899,7 +21938,7 @@ async function prepare6(options, extractedAt) {
|
|
|
21899
21938
|
}
|
|
21900
21939
|
}
|
|
21901
21940
|
if (options.prune) {
|
|
21902
|
-
for (const name of (await
|
|
21941
|
+
for (const name of (await readdir33(catalog)).filter(isSkillName).sort()) {
|
|
21903
21942
|
if (names2.has(name)) continue;
|
|
21904
21943
|
const path = join49(catalog, name);
|
|
21905
21944
|
if (!(await vendorLstat(path))?.isDirectory()) continue;
|
package/dist/index.js
CHANGED
|
@@ -8618,7 +8618,7 @@ async function buildScope(scope, options, forbiddenRoots, verifySet = verifySele
|
|
|
8618
8618
|
if (!owned4)
|
|
8619
8619
|
refuse3(root, "Whole-root switching requires explicit ownership of the existing root.");
|
|
8620
8620
|
if (owned4.kind === "link") return { identity: owned4 };
|
|
8621
|
-
const
|
|
8621
|
+
const children2 = {};
|
|
8622
8622
|
for (const name of awaitableNames) {
|
|
8623
8623
|
const child = links[join25(root, name)];
|
|
8624
8624
|
if (!child)
|
|
@@ -8626,9 +8626,9 @@ async function buildScope(scope, options, forbiddenRoots, verifySet = verifySele
|
|
|
8626
8626
|
join25(root, name),
|
|
8627
8627
|
"Foreign content prevents a whole-root switch; it will not be removed."
|
|
8628
8628
|
);
|
|
8629
|
-
|
|
8629
|
+
children2[name] = child;
|
|
8630
8630
|
}
|
|
8631
|
-
return { identity: owned4, children };
|
|
8631
|
+
return { identity: owned4, children: children2 };
|
|
8632
8632
|
};
|
|
8633
8633
|
const awaitableNames = rootEntry?.info.isDirectory() ? await readdir16(physicalPath(root, recovery)) : [];
|
|
8634
8634
|
if (!rootEntry) {
|
|
@@ -8967,7 +8967,7 @@ async function publishPrepared(work, staged, destination, node, directories) {
|
|
|
8967
8967
|
async function stageNode(work, operation2, path) {
|
|
8968
8968
|
if (operation2.children !== void 0) {
|
|
8969
8969
|
await mkdir7(path, { mode: 493 });
|
|
8970
|
-
const
|
|
8970
|
+
const children2 = {};
|
|
8971
8971
|
for (const [name, target2] of operation2.children) {
|
|
8972
8972
|
const destination = join25(operation2.path, name);
|
|
8973
8973
|
if (!await canonicalTarget(work, name, target2))
|
|
@@ -8976,11 +8976,11 @@ async function stageNode(work, operation2, path) {
|
|
|
8976
8976
|
await symlink4(relative9(dirname13(destination), target2), child);
|
|
8977
8977
|
const found2 = await entry2(child);
|
|
8978
8978
|
if (!found2) refuse3(child, "Prepared activation link disappeared.");
|
|
8979
|
-
|
|
8979
|
+
children2[name] = identity(found2);
|
|
8980
8980
|
}
|
|
8981
8981
|
const found = await entry2(path);
|
|
8982
8982
|
if (!found) refuse3(path, "Prepared activation directory disappeared.");
|
|
8983
|
-
return { identity: identity(found), children };
|
|
8983
|
+
return { identity: identity(found), children: children2 };
|
|
8984
8984
|
}
|
|
8985
8985
|
if (operation2.target !== void 0) {
|
|
8986
8986
|
if (dirname13(operation2.path) === work.plan.activationRoot && !await canonicalTarget(work, basename5(operation2.path), operation2.target))
|
|
@@ -11415,7 +11415,7 @@ async function captureMigrationNode(path) {
|
|
|
11415
11415
|
mode: Number(before.mode & 0o7777n),
|
|
11416
11416
|
...before.isSymbolicLink() ? { raw: await readlink6(path) } : {}
|
|
11417
11417
|
};
|
|
11418
|
-
const
|
|
11418
|
+
const children2 = {};
|
|
11419
11419
|
let hash5 = null;
|
|
11420
11420
|
if (before.isDirectory()) {
|
|
11421
11421
|
const names2 = await readdir22(path, { encoding: "buffer" });
|
|
@@ -11432,7 +11432,7 @@ async function captureMigrationNode(path) {
|
|
|
11432
11432
|
const child = await captureMigrationNode(join31(path, name));
|
|
11433
11433
|
if (!child)
|
|
11434
11434
|
migrationRefusal(join31(path, name), "Content disappeared during migration inventory.");
|
|
11435
|
-
Object.defineProperty(
|
|
11435
|
+
Object.defineProperty(children2, name, { value: child, enumerable: true });
|
|
11436
11436
|
}
|
|
11437
11437
|
} else if (before.isFile()) {
|
|
11438
11438
|
const handle = await open10(
|
|
@@ -11471,7 +11471,7 @@ async function captureMigrationNode(path) {
|
|
|
11471
11471
|
const after = await lstat20(path, { bigint: true });
|
|
11472
11472
|
if (after.dev !== before.dev || after.ino !== before.ino || after.mode !== before.mode || after.size !== before.size || after.mtimeNs !== before.mtimeNs || after.ctimeNs !== before.ctimeNs)
|
|
11473
11473
|
migrationRefusal(path, "Content changed while its migration inventory was being captured.");
|
|
11474
|
-
return { identity: identity4, hash: hash5, children };
|
|
11474
|
+
return { identity: identity4, hash: hash5, children: children2 };
|
|
11475
11475
|
}
|
|
11476
11476
|
function migrationDigest(node) {
|
|
11477
11477
|
const project = (item2) => ({
|
|
@@ -12572,16 +12572,16 @@ async function prepare2(target2) {
|
|
|
12572
12572
|
shared,
|
|
12573
12573
|
"The old alias points at one skill definition rather than a collection root."
|
|
12574
12574
|
);
|
|
12575
|
-
const
|
|
12575
|
+
const children2 = {};
|
|
12576
12576
|
const claimNames = [];
|
|
12577
12577
|
const proofs = [{ path: shared, node: contents }];
|
|
12578
12578
|
for (const name of Object.keys(contents.children)) {
|
|
12579
12579
|
const path = join34(target2.root, name);
|
|
12580
12580
|
const mapped2 = await canonicalMapping(target2, path);
|
|
12581
12581
|
const output = mapped2?.name ?? name;
|
|
12582
|
-
if (Object.hasOwn(
|
|
12582
|
+
if (Object.hasOwn(children2, output))
|
|
12583
12583
|
migrationRefusal(path, "Two original children map to the same resulting name.");
|
|
12584
|
-
Object.defineProperty(
|
|
12584
|
+
Object.defineProperty(children2, output, {
|
|
12585
12585
|
value: mapped2?.target ?? join34(shared, name),
|
|
12586
12586
|
enumerable: true
|
|
12587
12587
|
});
|
|
@@ -12596,7 +12596,7 @@ async function prepare2(target2) {
|
|
|
12596
12596
|
[
|
|
12597
12597
|
mapped2 ? "The mapped canonical content is verified." : "The original child remains reachable through a foreign forwarding link; its shared target is untouched."
|
|
12598
12598
|
],
|
|
12599
|
-
|
|
12599
|
+
children2[output]
|
|
12600
12600
|
)
|
|
12601
12601
|
);
|
|
12602
12602
|
}
|
|
@@ -12605,7 +12605,7 @@ async function prepare2(target2) {
|
|
|
12605
12605
|
"Replace only the old root symlink with a real directory; preserve every inventoried child and leave the shared target untouched."
|
|
12606
12606
|
]),
|
|
12607
12607
|
previous: root,
|
|
12608
|
-
children,
|
|
12608
|
+
children: children2,
|
|
12609
12609
|
claimRoot: true,
|
|
12610
12610
|
claimNames,
|
|
12611
12611
|
proofs
|
|
@@ -18227,13 +18227,13 @@ async function normalizeScope(options = {}) {
|
|
|
18227
18227
|
// src/core/profile-sync.ts
|
|
18228
18228
|
import { randomUUID as randomUUID11 } from "node:crypto";
|
|
18229
18229
|
import { constants as constants13 } from "node:fs";
|
|
18230
|
-
import { mkdir as mkdir12, open as open17, readdir as
|
|
18230
|
+
import { mkdir as mkdir12, open as open17, readdir as readdir30, realpath as realpath32, rename as rename11, symlink as symlink7, unlink as unlink12 } from "node:fs/promises";
|
|
18231
18231
|
import { dirname as dirname27, join as join44, resolve as resolve25 } from "node:path";
|
|
18232
18232
|
import { isDeepStrictEqual as isDeepStrictEqual10 } from "node:util";
|
|
18233
18233
|
|
|
18234
18234
|
// src/core/profile-policy.ts
|
|
18235
18235
|
import { constants as constants12 } from "node:fs";
|
|
18236
|
-
import { open as open16, readFile as readFile18, stat as stat8 } from "node:fs/promises";
|
|
18236
|
+
import { open as open16, readdir as readdir29, readFile as readFile18, stat as stat8 } from "node:fs/promises";
|
|
18237
18237
|
import { join as join43 } from "node:path";
|
|
18238
18238
|
import { parseDocument as parseDocument4 } from "yaml";
|
|
18239
18239
|
var metadataFiles = /* @__PURE__ */ new Set([
|
|
@@ -18246,9 +18246,48 @@ var metadataFiles = /* @__PURE__ */ new Set([
|
|
|
18246
18246
|
".curator_ledger.jsonl"
|
|
18247
18247
|
]);
|
|
18248
18248
|
var metadataDirectories = /* @__PURE__ */ new Set([".curator_backups", ".locks"]);
|
|
18249
|
-
|
|
18249
|
+
var hubFiles = /* @__PURE__ */ new Set(["audit.log", "taps.json", "lock.json"]);
|
|
18250
|
+
async function children(path) {
|
|
18251
|
+
try {
|
|
18252
|
+
return await readdir29(path, { withFileTypes: true });
|
|
18253
|
+
} catch {
|
|
18254
|
+
return null;
|
|
18255
|
+
}
|
|
18256
|
+
}
|
|
18257
|
+
async function categoryStub(item2) {
|
|
18258
|
+
if (item2.kind !== "directory" || item2.shadows) return false;
|
|
18259
|
+
const entries = await children(item2.path);
|
|
18260
|
+
return entries?.length === 1 && entries[0]?.name === "DESCRIPTION.md" && entries[0].isFile();
|
|
18261
|
+
}
|
|
18262
|
+
async function idleHub(item2) {
|
|
18263
|
+
if (item2.kind !== "directory" || item2.name !== ".hub") return false;
|
|
18264
|
+
const entries = await children(item2.path);
|
|
18265
|
+
if (!entries) return false;
|
|
18266
|
+
for (const child of entries) {
|
|
18267
|
+
const path = join43(item2.path, child.name);
|
|
18268
|
+
if (child.isFile() && hubFiles.has(child.name)) {
|
|
18269
|
+
if (child.name !== "lock.json") continue;
|
|
18270
|
+
try {
|
|
18271
|
+
const lock = JSON.parse(await readFile18(path, "utf8"));
|
|
18272
|
+
const installed = lock?.installed;
|
|
18273
|
+
if (!installed || typeof installed !== "object" || Object.keys(installed).length)
|
|
18274
|
+
return false;
|
|
18275
|
+
} catch {
|
|
18276
|
+
return false;
|
|
18277
|
+
}
|
|
18278
|
+
} else if (child.isDirectory() && child.name === "quarantine") {
|
|
18279
|
+
if ((await children(path))?.length !== 0) return false;
|
|
18280
|
+
} else if (child.isDirectory() && child.name === "index-cache") {
|
|
18281
|
+
const cached2 = await children(path);
|
|
18282
|
+
if (!cached2 || cached2.some((entry3) => !entry3.isFile())) return false;
|
|
18283
|
+
} else return false;
|
|
18284
|
+
}
|
|
18285
|
+
return true;
|
|
18286
|
+
}
|
|
18287
|
+
async function hermesMetadata(item2) {
|
|
18250
18288
|
if (item2.kind === "file") return metadataFiles.has(item2.name);
|
|
18251
|
-
if (item2.kind === "directory")
|
|
18289
|
+
if (item2.kind === "directory")
|
|
18290
|
+
return metadataDirectories.has(item2.name) || await idleHub(item2) || await categoryStub(item2);
|
|
18252
18291
|
return false;
|
|
18253
18292
|
}
|
|
18254
18293
|
function refuse5(path, message) {
|
|
@@ -18286,7 +18325,7 @@ async function profileInheritsGlobal(profile) {
|
|
|
18286
18325
|
async function assertStrictProfile(profile, options, local) {
|
|
18287
18326
|
if (!await strictProfile(profile, options)) return false;
|
|
18288
18327
|
for (const item2 of local)
|
|
18289
|
-
if (!hermesMetadata(item2))
|
|
18328
|
+
if (!await hermesMetadata(item2))
|
|
18290
18329
|
refuse5(item2.path, `Skillex-only profile contains unowned entry ${item2.name}.`);
|
|
18291
18330
|
const path = join43(profile.root, "config.yaml");
|
|
18292
18331
|
const config = await entry2(path);
|
|
@@ -18459,7 +18498,7 @@ async function observations(profile, state) {
|
|
|
18459
18498
|
"Use the explicit migrate workflow to replace this whole-root alias or conflicting file while preserving profile content."
|
|
18460
18499
|
);
|
|
18461
18500
|
if (root)
|
|
18462
|
-
for (const name of (await
|
|
18501
|
+
for (const name of (await readdir30(profile.skillsRoot)).sort()) {
|
|
18463
18502
|
const path = join44(profile.skillsRoot, name);
|
|
18464
18503
|
const actual = await entry2(path);
|
|
18465
18504
|
if (!actual) continue;
|
|
@@ -20667,7 +20706,7 @@ async function adoptRoot(options = {}) {
|
|
|
20667
20706
|
}
|
|
20668
20707
|
|
|
20669
20708
|
// src/core/sets.ts
|
|
20670
|
-
import { readdir as
|
|
20709
|
+
import { readdir as readdir31 } from "node:fs/promises";
|
|
20671
20710
|
import { join as join47 } from "node:path";
|
|
20672
20711
|
function validateName(name) {
|
|
20673
20712
|
parseManifest({ sets: [{ name }] }, "set name");
|
|
@@ -20690,7 +20729,7 @@ async function listSets(options = {}) {
|
|
|
20690
20729
|
const failures = [];
|
|
20691
20730
|
if (await inspectPath(path)) {
|
|
20692
20731
|
await requireDirectory(path, "E_SET_MISSING");
|
|
20693
|
-
for (const entry3 of (await
|
|
20732
|
+
for (const entry3 of (await readdir31(path, { withFileTypes: true })).sort(
|
|
20694
20733
|
(a, b) => a.name < b.name ? -1 : a.name > b.name ? 1 : 0
|
|
20695
20734
|
)) {
|
|
20696
20735
|
if (entry3.name.startsWith(".") || entry3.name.startsWith("_") || !entry3.isDirectory() && !entry3.isSymbolicLink())
|
|
@@ -20832,7 +20871,7 @@ async function removeSetSkills(name, names2, options = {}) {
|
|
|
20832
20871
|
}
|
|
20833
20872
|
|
|
20834
20873
|
// src/core/vendor-inspect.ts
|
|
20835
|
-
import { readdir as
|
|
20874
|
+
import { readdir as readdir32 } from "node:fs/promises";
|
|
20836
20875
|
import { join as join48 } from "node:path";
|
|
20837
20876
|
|
|
20838
20877
|
// src/core/vendor-git.ts
|
|
@@ -21124,8 +21163,8 @@ async function readVendorGitSource(source, checkoutRoot, options = {}) {
|
|
|
21124
21163
|
checkout
|
|
21125
21164
|
).trim();
|
|
21126
21165
|
const base = await treeAt(checkout, rootTree, source.subdir, options);
|
|
21127
|
-
const
|
|
21128
|
-
const declarations = source.membership === "explicit" ? source.skills :
|
|
21166
|
+
const children2 = await treeEntries(checkout, base, options);
|
|
21167
|
+
const declarations = source.membership === "explicit" ? source.skills : children2.filter(
|
|
21129
21168
|
(entry3) => !entry3.name.startsWith(".") && !entry3.name.startsWith("_") && (entry3.type === "tree" || entry3.mode === "120000" || entry3.mode === "160000")
|
|
21130
21169
|
).map((entry3) => ({ name: entry3.name, dir: entry3.name }));
|
|
21131
21170
|
const selected = declarations.filter(
|
|
@@ -21197,7 +21236,7 @@ async function recordedInventory(manifest, observation, options) {
|
|
|
21197
21236
|
const recorded = /* @__PURE__ */ new Map();
|
|
21198
21237
|
const failed2 = /* @__PURE__ */ new Set();
|
|
21199
21238
|
const catalog = join48(manifest.registry.root, "all-skills");
|
|
21200
|
-
for (const entry3 of (await
|
|
21239
|
+
for (const entry3 of (await readdir32(catalog, { withFileTypes: true })).sort(
|
|
21201
21240
|
(a, b) => a.name.localeCompare(b.name)
|
|
21202
21241
|
)) {
|
|
21203
21242
|
checkVendorSignal(options);
|
|
@@ -21670,7 +21709,7 @@ async function inspectVendorStatus(options = {}) {
|
|
|
21670
21709
|
|
|
21671
21710
|
// src/core/vendor-sync.ts
|
|
21672
21711
|
import { randomUUID as randomUUID14 } from "node:crypto";
|
|
21673
|
-
import { chmod as chmod4, lstat as lstat27, mkdir as mkdir14, open as open20, readdir as
|
|
21712
|
+
import { chmod as chmod4, lstat as lstat27, mkdir as mkdir14, open as open20, readdir as readdir33, rename as rename14 } from "node:fs/promises";
|
|
21674
21713
|
import { dirname as dirname30, join as join49 } from "node:path";
|
|
21675
21714
|
function refuse8(code, message, path, fix) {
|
|
21676
21715
|
fail(code, message, { path, fix }, ExitCode.REFUSED);
|
|
@@ -21897,7 +21936,7 @@ async function prepare6(options, extractedAt) {
|
|
|
21897
21936
|
}
|
|
21898
21937
|
}
|
|
21899
21938
|
if (options.prune) {
|
|
21900
|
-
for (const name of (await
|
|
21939
|
+
for (const name of (await readdir33(catalog)).filter(isSkillName).sort()) {
|
|
21901
21940
|
if (names2.has(name)) continue;
|
|
21902
21941
|
const path = join49(catalog, name);
|
|
21903
21942
|
if (!(await vendorLstat(path))?.isDirectory()) continue;
|