@skillsmith/cli 0.8.1 → 0.8.2
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 +4 -0
- package/dist/.skillsmith-dist-hash +1 -1
- package/dist/.tsbuildinfo +1 -1
- package/dist/cli.js +499 -462
- package/package.json +3 -3
package/dist/cli.js
CHANGED
|
@@ -933,15 +933,15 @@ var init_wsl_utils = __esm({
|
|
|
933
933
|
const { stdout } = await executePowerShell(command, { powerShellPath: psPath });
|
|
934
934
|
return stdout.trim();
|
|
935
935
|
};
|
|
936
|
-
convertWslPathToWindows = async (
|
|
937
|
-
if (/^[a-z]+:\/\//i.test(
|
|
938
|
-
return
|
|
936
|
+
convertWslPathToWindows = async (path24) => {
|
|
937
|
+
if (/^[a-z]+:\/\//i.test(path24)) {
|
|
938
|
+
return path24;
|
|
939
939
|
}
|
|
940
940
|
try {
|
|
941
|
-
const { stdout } = await execFile2("wslpath", ["-aw",
|
|
941
|
+
const { stdout } = await execFile2("wslpath", ["-aw", path24], { encoding: "utf8" });
|
|
942
942
|
return stdout.trim();
|
|
943
943
|
} catch {
|
|
944
|
-
return
|
|
944
|
+
return path24;
|
|
945
945
|
}
|
|
946
946
|
};
|
|
947
947
|
}
|
|
@@ -1127,7 +1127,7 @@ __export(open_exports, {
|
|
|
1127
1127
|
openApp: () => openApp
|
|
1128
1128
|
});
|
|
1129
1129
|
import process10 from "node:process";
|
|
1130
|
-
import
|
|
1130
|
+
import path14 from "node:path";
|
|
1131
1131
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
1132
1132
|
import childProcess3 from "node:child_process";
|
|
1133
1133
|
import fs16, { constants as fsConstants2 } from "node:fs/promises";
|
|
@@ -1160,8 +1160,8 @@ var init_open = __esm({
|
|
|
1160
1160
|
init_is_inside_container();
|
|
1161
1161
|
init_is_in_ssh();
|
|
1162
1162
|
fallbackAttemptSymbol = /* @__PURE__ */ Symbol("fallbackAttempt");
|
|
1163
|
-
__dirname = import.meta.url ?
|
|
1164
|
-
localXdgOpenPath =
|
|
1163
|
+
__dirname = import.meta.url ? path14.dirname(fileURLToPath2(import.meta.url)) : "";
|
|
1164
|
+
localXdgOpenPath = path14.join(__dirname, "xdg-open");
|
|
1165
1165
|
({ platform, arch } = process10);
|
|
1166
1166
|
tryEachApp = async (apps2, opener) => {
|
|
1167
1167
|
if (apps2.length === 0) {
|
|
@@ -2345,29 +2345,29 @@ function relocateUnderHome(absolutePath, homeDir) {
|
|
|
2345
2345
|
import { chmodSync as chmodSync2, existsSync as existsSync3, mkdirSync as mkdirSync2, readFileSync as readFileSync2, statSync, writeFileSync as writeFileSync2 } from "node:fs";
|
|
2346
2346
|
import { dirname as dirname2, join as join5 } from "node:path";
|
|
2347
2347
|
function writeOwnedArtifactFile(opts) {
|
|
2348
|
-
const { path:
|
|
2349
|
-
if (existsSync3(
|
|
2350
|
-
const existing = readFileSync2(
|
|
2351
|
-
const currentlyExecutable = isExecutable(
|
|
2348
|
+
const { path: path24, content, executable, backupDir } = opts;
|
|
2349
|
+
if (existsSync3(path24)) {
|
|
2350
|
+
const existing = readFileSync2(path24, "utf-8");
|
|
2351
|
+
const currentlyExecutable = isExecutable(path24);
|
|
2352
2352
|
if (existing === content && currentlyExecutable === executable) {
|
|
2353
2353
|
return { changed: false, backupPath: null };
|
|
2354
2354
|
}
|
|
2355
|
-
const backupPath = writeBackup(
|
|
2356
|
-
mkdirSync2(dirname2(
|
|
2357
|
-
writeFileSync2(
|
|
2355
|
+
const backupPath = writeBackup(path24, backupDir);
|
|
2356
|
+
mkdirSync2(dirname2(path24), { recursive: true });
|
|
2357
|
+
writeFileSync2(path24, content, "utf-8");
|
|
2358
2358
|
if (executable)
|
|
2359
|
-
chmodSync2(
|
|
2359
|
+
chmodSync2(path24, 493);
|
|
2360
2360
|
return { changed: true, backupPath };
|
|
2361
2361
|
}
|
|
2362
|
-
mkdirSync2(dirname2(
|
|
2363
|
-
writeFileSync2(
|
|
2362
|
+
mkdirSync2(dirname2(path24), { recursive: true });
|
|
2363
|
+
writeFileSync2(path24, content, "utf-8");
|
|
2364
2364
|
if (executable)
|
|
2365
|
-
chmodSync2(
|
|
2365
|
+
chmodSync2(path24, 493);
|
|
2366
2366
|
return { changed: true, backupPath: null };
|
|
2367
2367
|
}
|
|
2368
|
-
function isExecutable(
|
|
2368
|
+
function isExecutable(path24) {
|
|
2369
2369
|
try {
|
|
2370
|
-
return (statSync(
|
|
2370
|
+
return (statSync(path24).mode & 73) !== 0;
|
|
2371
2371
|
} catch {
|
|
2372
2372
|
return false;
|
|
2373
2373
|
}
|
|
@@ -2397,11 +2397,11 @@ function getAgentInstallBackupsDir() {
|
|
|
2397
2397
|
return join6(getAgentInstallDir(), "backups");
|
|
2398
2398
|
}
|
|
2399
2399
|
function loadAgentManifest() {
|
|
2400
|
-
const
|
|
2401
|
-
if (!existsSync4(
|
|
2400
|
+
const path24 = getAgentManifestPath();
|
|
2401
|
+
if (!existsSync4(path24))
|
|
2402
2402
|
return emptyManifest();
|
|
2403
2403
|
try {
|
|
2404
|
-
const parsed = JSON.parse(readFileSync3(
|
|
2404
|
+
const parsed = JSON.parse(readFileSync3(path24, "utf-8"));
|
|
2405
2405
|
if (!parsed || !Array.isArray(parsed.entries))
|
|
2406
2406
|
return emptyManifest();
|
|
2407
2407
|
return {
|
|
@@ -2550,11 +2550,11 @@ import { existsSync as existsSync5, mkdirSync as mkdirSync4, readFileSync as rea
|
|
|
2550
2550
|
import { dirname as dirname3, join as join8 } from "node:path";
|
|
2551
2551
|
|
|
2552
2552
|
// ../core/dist/src/install/agent-config-merge.types.js
|
|
2553
|
-
function shouldBackup(
|
|
2554
|
-
return !alreadyBackedUpPaths?.has(
|
|
2553
|
+
function shouldBackup(path24, alreadyBackedUpPaths) {
|
|
2554
|
+
return !alreadyBackedUpPaths?.has(path24);
|
|
2555
2555
|
}
|
|
2556
|
-
function markBackedUp(
|
|
2557
|
-
alreadyBackedUpPaths?.add(
|
|
2556
|
+
function markBackedUp(path24, alreadyBackedUpPaths) {
|
|
2557
|
+
alreadyBackedUpPaths?.add(path24);
|
|
2558
2558
|
}
|
|
2559
2559
|
function looksLikeOurMcpEntry(value) {
|
|
2560
2560
|
if (!value || typeof value !== "object")
|
|
@@ -2629,50 +2629,50 @@ function writeBackup2(sourcePath, backupDir) {
|
|
|
2629
2629
|
return backupPath;
|
|
2630
2630
|
}
|
|
2631
2631
|
function mergeJsonMcpEntry(opts) {
|
|
2632
|
-
const { path:
|
|
2632
|
+
const { path: path24, keyPath, entryValue, backupDir, force = false, alreadyBackedUpPaths } = opts;
|
|
2633
2633
|
let doc = {};
|
|
2634
2634
|
let existed = false;
|
|
2635
|
-
if (existsSync5(
|
|
2635
|
+
if (existsSync5(path24)) {
|
|
2636
2636
|
existed = true;
|
|
2637
2637
|
let raw;
|
|
2638
2638
|
try {
|
|
2639
|
-
raw = readFileSync4(
|
|
2639
|
+
raw = readFileSync4(path24, "utf-8");
|
|
2640
2640
|
} catch (e) {
|
|
2641
|
-
return { status: "error", path:
|
|
2641
|
+
return { status: "error", path: path24, backupPath: null, errorMessage: e.message };
|
|
2642
2642
|
}
|
|
2643
2643
|
try {
|
|
2644
2644
|
const parsed = raw.trim().length === 0 ? {} : JSON.parse(raw);
|
|
2645
2645
|
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
2646
|
-
return { status: "error", path:
|
|
2646
|
+
return { status: "error", path: path24, backupPath: null, errorMessage: "not a JSON object" };
|
|
2647
2647
|
}
|
|
2648
2648
|
doc = parsed;
|
|
2649
2649
|
} catch (e) {
|
|
2650
|
-
return { status: "error", path:
|
|
2650
|
+
return { status: "error", path: path24, backupPath: null, errorMessage: e.message };
|
|
2651
2651
|
}
|
|
2652
2652
|
}
|
|
2653
2653
|
const container = getAtPath(doc, keyPath);
|
|
2654
2654
|
const existingEntry = container && typeof container === "object" && !Array.isArray(container) ? container.skillsmith : void 0;
|
|
2655
2655
|
if (existingEntry !== void 0) {
|
|
2656
2656
|
if (deepEqualJson(existingEntry, entryValue)) {
|
|
2657
|
-
return { status: "unchanged", path:
|
|
2657
|
+
return { status: "unchanged", path: path24, backupPath: null };
|
|
2658
2658
|
}
|
|
2659
2659
|
if (!looksLikeOurMcpEntry(existingEntry) && !force) {
|
|
2660
|
-
return { status: "conflict", path:
|
|
2660
|
+
return { status: "conflict", path: path24, backupPath: null };
|
|
2661
2661
|
}
|
|
2662
|
-
const backupPath2 = existed && shouldBackup(
|
|
2663
|
-
markBackedUp(
|
|
2662
|
+
const backupPath2 = existed && shouldBackup(path24, alreadyBackedUpPaths) ? writeBackup2(path24, backupDir) : null;
|
|
2663
|
+
markBackedUp(path24, alreadyBackedUpPaths);
|
|
2664
2664
|
setAtPath(doc, keyPath, { ...container, skillsmith: entryValue });
|
|
2665
|
-
mkdirSync4(dirname3(
|
|
2666
|
-
writeFileSync4(
|
|
2667
|
-
return { status: "updated", path:
|
|
2665
|
+
mkdirSync4(dirname3(path24), { recursive: true, mode: 448 });
|
|
2666
|
+
writeFileSync4(path24, JSON.stringify(doc, null, 2) + "\n", { mode: 384 });
|
|
2667
|
+
return { status: "updated", path: path24, backupPath: backupPath2 };
|
|
2668
2668
|
}
|
|
2669
|
-
const backupPath = existed && shouldBackup(
|
|
2670
|
-
markBackedUp(
|
|
2669
|
+
const backupPath = existed && shouldBackup(path24, alreadyBackedUpPaths) ? writeBackup2(path24, backupDir) : null;
|
|
2670
|
+
markBackedUp(path24, alreadyBackedUpPaths);
|
|
2671
2671
|
const currentContainer = container && typeof container === "object" && !Array.isArray(container) ? container : {};
|
|
2672
2672
|
setAtPath(doc, keyPath, { ...currentContainer, skillsmith: entryValue });
|
|
2673
|
-
mkdirSync4(dirname3(
|
|
2674
|
-
writeFileSync4(
|
|
2675
|
-
return { status: "created", path:
|
|
2673
|
+
mkdirSync4(dirname3(path24), { recursive: true, mode: 448 });
|
|
2674
|
+
writeFileSync4(path24, JSON.stringify(doc, null, 2) + "\n", { mode: 384 });
|
|
2675
|
+
return { status: "created", path: path24, backupPath };
|
|
2676
2676
|
}
|
|
2677
2677
|
|
|
2678
2678
|
// ../core/dist/src/install/agent-config-merge.yaml.js
|
|
@@ -2694,15 +2694,15 @@ function toPlainValue(node) {
|
|
|
2694
2694
|
return node;
|
|
2695
2695
|
}
|
|
2696
2696
|
function mergeYamlMcpEntry(opts) {
|
|
2697
|
-
const { path:
|
|
2697
|
+
const { path: path24, entryValue, backupDir, force = false, mcpServersKey, alreadyBackedUpPaths } = opts;
|
|
2698
2698
|
let doc;
|
|
2699
|
-
const existed = existsSync6(
|
|
2699
|
+
const existed = existsSync6(path24);
|
|
2700
2700
|
if (existed) {
|
|
2701
2701
|
let raw;
|
|
2702
2702
|
try {
|
|
2703
|
-
raw = readFileSync5(
|
|
2703
|
+
raw = readFileSync5(path24, "utf-8");
|
|
2704
2704
|
} catch (e) {
|
|
2705
|
-
return { status: "error", path:
|
|
2705
|
+
return { status: "error", path: path24, backupPath: null, errorMessage: e.message };
|
|
2706
2706
|
}
|
|
2707
2707
|
if (raw.trim().length === 0) {
|
|
2708
2708
|
doc = new Document({});
|
|
@@ -2711,7 +2711,7 @@ function mergeYamlMcpEntry(opts) {
|
|
|
2711
2711
|
if (parsed.errors.length > 0) {
|
|
2712
2712
|
return {
|
|
2713
2713
|
status: "error",
|
|
2714
|
-
path:
|
|
2714
|
+
path: path24,
|
|
2715
2715
|
backupPath: null,
|
|
2716
2716
|
errorMessage: parsed.errors[0]?.message ?? "YAML parse error"
|
|
2717
2717
|
};
|
|
@@ -2719,7 +2719,7 @@ function mergeYamlMcpEntry(opts) {
|
|
|
2719
2719
|
if (parsed.contents !== null && isScalar(parsed.contents) && parsed.contents.value === null) {
|
|
2720
2720
|
doc = new Document({});
|
|
2721
2721
|
} else if (parsed.contents !== null && !isMap(parsed.contents)) {
|
|
2722
|
-
return { status: "error", path:
|
|
2722
|
+
return { status: "error", path: path24, backupPath: null, errorMessage: "not a YAML mapping" };
|
|
2723
2723
|
} else {
|
|
2724
2724
|
doc = parsed;
|
|
2725
2725
|
}
|
|
@@ -2730,24 +2730,24 @@ function mergeYamlMcpEntry(opts) {
|
|
|
2730
2730
|
const existingEntry = toPlainValue(doc.getIn([mcpServersKey, "skillsmith"]));
|
|
2731
2731
|
if (existingEntry !== void 0) {
|
|
2732
2732
|
if (deepEqualJson(existingEntry, entryValue)) {
|
|
2733
|
-
return { status: "unchanged", path:
|
|
2733
|
+
return { status: "unchanged", path: path24, backupPath: null };
|
|
2734
2734
|
}
|
|
2735
2735
|
if (!looksLikeOurMcpEntry(existingEntry) && !force) {
|
|
2736
|
-
return { status: "conflict", path:
|
|
2736
|
+
return { status: "conflict", path: path24, backupPath: null };
|
|
2737
2737
|
}
|
|
2738
|
-
const backupPath2 = existed && shouldBackup(
|
|
2739
|
-
markBackedUp(
|
|
2738
|
+
const backupPath2 = existed && shouldBackup(path24, alreadyBackedUpPaths) ? writeBackup3(path24, backupDir) : null;
|
|
2739
|
+
markBackedUp(path24, alreadyBackedUpPaths);
|
|
2740
2740
|
doc.setIn([mcpServersKey, "skillsmith"], entryValue);
|
|
2741
|
-
mkdirSync5(dirname4(
|
|
2742
|
-
writeFileSync5(
|
|
2743
|
-
return { status: "updated", path:
|
|
2741
|
+
mkdirSync5(dirname4(path24), { recursive: true, mode: 448 });
|
|
2742
|
+
writeFileSync5(path24, doc.toString(), { mode: 384 });
|
|
2743
|
+
return { status: "updated", path: path24, backupPath: backupPath2 };
|
|
2744
2744
|
}
|
|
2745
|
-
const backupPath = existed && shouldBackup(
|
|
2746
|
-
markBackedUp(
|
|
2745
|
+
const backupPath = existed && shouldBackup(path24, alreadyBackedUpPaths) ? writeBackup3(path24, backupDir) : null;
|
|
2746
|
+
markBackedUp(path24, alreadyBackedUpPaths);
|
|
2747
2747
|
doc.setIn([mcpServersKey, "skillsmith"], entryValue);
|
|
2748
|
-
mkdirSync5(dirname4(
|
|
2749
|
-
writeFileSync5(
|
|
2750
|
-
return { status: "created", path:
|
|
2748
|
+
mkdirSync5(dirname4(path24), { recursive: true, mode: 448 });
|
|
2749
|
+
writeFileSync5(path24, doc.toString(), { mode: 384 });
|
|
2750
|
+
return { status: "created", path: path24, backupPath };
|
|
2751
2751
|
}
|
|
2752
2752
|
|
|
2753
2753
|
// ../core/dist/src/install/agent-config-merge.toml-block.js
|
|
@@ -2768,17 +2768,17 @@ function writeBackup4(sourcePath, backupDir) {
|
|
|
2768
2768
|
return backupPath;
|
|
2769
2769
|
}
|
|
2770
2770
|
function mergeTomlBlock(opts) {
|
|
2771
|
-
const { path:
|
|
2771
|
+
const { path: path24, markerId, blockContent, foreignHeaderPattern, backupDir, force = false, alreadyBackedUpPaths } = opts;
|
|
2772
2772
|
const start = markerStart(markerId);
|
|
2773
2773
|
const end = markerEnd(markerId);
|
|
2774
2774
|
const trimmedBlock = blockContent.trim();
|
|
2775
|
-
const existed = existsSync7(
|
|
2775
|
+
const existed = existsSync7(path24);
|
|
2776
2776
|
let raw = "";
|
|
2777
2777
|
if (existed) {
|
|
2778
2778
|
try {
|
|
2779
|
-
raw = readFileSync6(
|
|
2779
|
+
raw = readFileSync6(path24, "utf-8");
|
|
2780
2780
|
} catch (e) {
|
|
2781
|
-
return { status: "error", path:
|
|
2781
|
+
return { status: "error", path: path24, backupPath: null, errorMessage: e.message };
|
|
2782
2782
|
}
|
|
2783
2783
|
}
|
|
2784
2784
|
const blockRegex = new RegExp(`${escapeRegExp(start)}\\n([\\s\\S]*?)\\n${escapeRegExp(end)}`);
|
|
@@ -2786,31 +2786,31 @@ function mergeTomlBlock(opts) {
|
|
|
2786
2786
|
if (match) {
|
|
2787
2787
|
const existingBlock = (match[1] ?? "").trim();
|
|
2788
2788
|
if (existingBlock === trimmedBlock) {
|
|
2789
|
-
return { status: "unchanged", path:
|
|
2789
|
+
return { status: "unchanged", path: path24, backupPath: null };
|
|
2790
2790
|
}
|
|
2791
|
-
const backupPath2 = shouldBackup(
|
|
2792
|
-
markBackedUp(
|
|
2791
|
+
const backupPath2 = shouldBackup(path24, alreadyBackedUpPaths) ? writeBackup4(path24, backupDir) : null;
|
|
2792
|
+
markBackedUp(path24, alreadyBackedUpPaths);
|
|
2793
2793
|
const replacement = `${start}
|
|
2794
2794
|
${trimmedBlock}
|
|
2795
2795
|
${end}`;
|
|
2796
2796
|
const updated = raw.replace(blockRegex, replacement);
|
|
2797
|
-
writeFileSync6(
|
|
2798
|
-
return { status: "updated", path:
|
|
2797
|
+
writeFileSync6(path24, updated, { mode: 384 });
|
|
2798
|
+
return { status: "updated", path: path24, backupPath: backupPath2 };
|
|
2799
2799
|
}
|
|
2800
2800
|
if (foreignHeaderPattern.test(raw)) {
|
|
2801
2801
|
void force;
|
|
2802
|
-
return { status: "conflict", path:
|
|
2802
|
+
return { status: "conflict", path: path24, backupPath: null };
|
|
2803
2803
|
}
|
|
2804
|
-
const backupPath = existed && shouldBackup(
|
|
2805
|
-
markBackedUp(
|
|
2804
|
+
const backupPath = existed && shouldBackup(path24, alreadyBackedUpPaths) ? writeBackup4(path24, backupDir) : null;
|
|
2805
|
+
markBackedUp(path24, alreadyBackedUpPaths);
|
|
2806
2806
|
const separator = raw.length > 0 && !raw.endsWith("\n\n") ? raw.endsWith("\n") ? "\n" : "\n\n" : "";
|
|
2807
2807
|
const appended = `${raw}${separator}${start}
|
|
2808
2808
|
${trimmedBlock}
|
|
2809
2809
|
${end}
|
|
2810
2810
|
`;
|
|
2811
|
-
mkdirSync6(dirname5(
|
|
2812
|
-
writeFileSync6(
|
|
2813
|
-
return { status: "created", path:
|
|
2811
|
+
mkdirSync6(dirname5(path24), { recursive: true, mode: 448 });
|
|
2812
|
+
writeFileSync6(path24, appended, { mode: 384 });
|
|
2813
|
+
return { status: "created", path: path24, backupPath };
|
|
2814
2814
|
}
|
|
2815
2815
|
function escapeRegExp(s) {
|
|
2816
2816
|
return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
@@ -2850,24 +2850,24 @@ function writeBackup5(sourcePath, backupDir) {
|
|
|
2850
2850
|
return backupPath;
|
|
2851
2851
|
}
|
|
2852
2852
|
function mergeJsonArrayEntry(opts) {
|
|
2853
|
-
const { path:
|
|
2853
|
+
const { path: path24, keyPath, entry, isOurEntry, backupDir, alreadyBackedUpPaths } = opts;
|
|
2854
2854
|
let doc = {};
|
|
2855
|
-
const existed = existsSync8(
|
|
2855
|
+
const existed = existsSync8(path24);
|
|
2856
2856
|
if (existed) {
|
|
2857
2857
|
let raw;
|
|
2858
2858
|
try {
|
|
2859
|
-
raw = readFileSync7(
|
|
2859
|
+
raw = readFileSync7(path24, "utf-8");
|
|
2860
2860
|
} catch (e) {
|
|
2861
|
-
return { status: "error", path:
|
|
2861
|
+
return { status: "error", path: path24, backupPath: null, errorMessage: e.message };
|
|
2862
2862
|
}
|
|
2863
2863
|
try {
|
|
2864
2864
|
const parsed = raw.trim().length === 0 ? {} : JSON.parse(raw);
|
|
2865
2865
|
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
2866
|
-
return { status: "error", path:
|
|
2866
|
+
return { status: "error", path: path24, backupPath: null, errorMessage: "not a JSON object" };
|
|
2867
2867
|
}
|
|
2868
2868
|
doc = parsed;
|
|
2869
2869
|
} catch (e) {
|
|
2870
|
-
return { status: "error", path:
|
|
2870
|
+
return { status: "error", path: path24, backupPath: null, errorMessage: e.message };
|
|
2871
2871
|
}
|
|
2872
2872
|
}
|
|
2873
2873
|
const rawArray = getAtPath2(doc, keyPath);
|
|
@@ -2875,23 +2875,23 @@ function mergeJsonArrayEntry(opts) {
|
|
|
2875
2875
|
const existingIndex = array2.findIndex(isOurEntry);
|
|
2876
2876
|
if (existingIndex >= 0) {
|
|
2877
2877
|
if (deepEqualJson(array2[existingIndex], entry)) {
|
|
2878
|
-
return { status: "unchanged", path:
|
|
2878
|
+
return { status: "unchanged", path: path24, backupPath: null };
|
|
2879
2879
|
}
|
|
2880
|
-
const backupPath2 = existed && shouldBackup(
|
|
2881
|
-
markBackedUp(
|
|
2880
|
+
const backupPath2 = existed && shouldBackup(path24, alreadyBackedUpPaths) ? writeBackup5(path24, backupDir) : null;
|
|
2881
|
+
markBackedUp(path24, alreadyBackedUpPaths);
|
|
2882
2882
|
array2[existingIndex] = entry;
|
|
2883
2883
|
setAtPath2(doc, keyPath, array2);
|
|
2884
|
-
mkdirSync7(dirname6(
|
|
2885
|
-
writeFileSync7(
|
|
2886
|
-
return { status: "updated", path:
|
|
2884
|
+
mkdirSync7(dirname6(path24), { recursive: true, mode: 448 });
|
|
2885
|
+
writeFileSync7(path24, JSON.stringify(doc, null, 2) + "\n", { mode: 384 });
|
|
2886
|
+
return { status: "updated", path: path24, backupPath: backupPath2 };
|
|
2887
2887
|
}
|
|
2888
|
-
const backupPath = existed && shouldBackup(
|
|
2889
|
-
markBackedUp(
|
|
2888
|
+
const backupPath = existed && shouldBackup(path24, alreadyBackedUpPaths) ? writeBackup5(path24, backupDir) : null;
|
|
2889
|
+
markBackedUp(path24, alreadyBackedUpPaths);
|
|
2890
2890
|
array2.push(entry);
|
|
2891
2891
|
setAtPath2(doc, keyPath, array2);
|
|
2892
|
-
mkdirSync7(dirname6(
|
|
2893
|
-
writeFileSync7(
|
|
2894
|
-
return { status: "created", path:
|
|
2892
|
+
mkdirSync7(dirname6(path24), { recursive: true, mode: 448 });
|
|
2893
|
+
writeFileSync7(path24, JSON.stringify(doc, null, 2) + "\n", { mode: 384 });
|
|
2894
|
+
return { status: "created", path: path24, backupPath };
|
|
2895
2895
|
}
|
|
2896
2896
|
|
|
2897
2897
|
// ../core/dist/src/install/agent-pack-installer.entry.js
|
|
@@ -2945,16 +2945,16 @@ function installShim(harness, artifact, ctx, report) {
|
|
|
2945
2945
|
const target = AGENT_SHIM_TARGETS[harness];
|
|
2946
2946
|
if (!target || !artifact)
|
|
2947
2947
|
return;
|
|
2948
|
-
const
|
|
2948
|
+
const path24 = relocateUnderHome(target.path, ctx.homeDir);
|
|
2949
2949
|
const result = writeOwnedArtifactFile({
|
|
2950
|
-
path:
|
|
2950
|
+
path: path24,
|
|
2951
2951
|
content: artifact.content,
|
|
2952
2952
|
executable: false,
|
|
2953
2953
|
backupDir: ctx.backupDir
|
|
2954
2954
|
});
|
|
2955
2955
|
report.shimWritten = true;
|
|
2956
2956
|
ctx.entries.push({
|
|
2957
|
-
path:
|
|
2957
|
+
path: path24,
|
|
2958
2958
|
kind: "shim",
|
|
2959
2959
|
harness,
|
|
2960
2960
|
backupPath: result.backupPath,
|
|
@@ -3104,9 +3104,9 @@ function installCodexAgentsShim(artifact, ctx, report) {
|
|
|
3104
3104
|
const target = AGENT_MCP_TARGETS.codex;
|
|
3105
3105
|
if (!artifact)
|
|
3106
3106
|
return;
|
|
3107
|
-
const
|
|
3107
|
+
const path24 = relocateUnderHome(target.path, ctx.homeDir);
|
|
3108
3108
|
const result = mergeTomlBlock({
|
|
3109
|
-
path:
|
|
3109
|
+
path: path24,
|
|
3110
3110
|
markerId: "agents.skillsmith-agent",
|
|
3111
3111
|
blockContent: artifact.content,
|
|
3112
3112
|
foreignHeaderPattern: CODEX_AGENTS_FOREIGN_HEADER,
|
|
@@ -3117,7 +3117,7 @@ function installCodexAgentsShim(artifact, ctx, report) {
|
|
|
3117
3117
|
if (mergeSucceeded(result.status)) {
|
|
3118
3118
|
report.shimWritten = true;
|
|
3119
3119
|
ctx.entries.push({
|
|
3120
|
-
path:
|
|
3120
|
+
path: path24,
|
|
3121
3121
|
kind: "shim",
|
|
3122
3122
|
harness: "codex",
|
|
3123
3123
|
backupPath: result.backupPath,
|
|
@@ -3125,32 +3125,32 @@ function installCodexAgentsShim(artifact, ctx, report) {
|
|
|
3125
3125
|
});
|
|
3126
3126
|
}
|
|
3127
3127
|
if (result.status === "conflict") {
|
|
3128
|
-
report.notes.push(`Codex agent entry at ${
|
|
3128
|
+
report.notes.push(`Codex agent entry at ${path24} already has a hand-written [agents.skillsmith-agent] table \u2014 left untouched.`);
|
|
3129
3129
|
}
|
|
3130
3130
|
if (result.status === "error") {
|
|
3131
|
-
report.notes.push(`Codex agent entry merge failed at ${
|
|
3131
|
+
report.notes.push(`Codex agent entry merge failed at ${path24}: ${result.errorMessage}`);
|
|
3132
3132
|
}
|
|
3133
3133
|
}
|
|
3134
3134
|
function installMcpConfig(harness, ctx, report) {
|
|
3135
3135
|
const target = AGENT_MCP_TARGETS[harness];
|
|
3136
|
-
const
|
|
3136
|
+
const path24 = relocateUnderHome(target.path, ctx.homeDir);
|
|
3137
3137
|
const entryValue = harness === "opencode" ? buildOpenCodeMcpEntryValue() : buildAgentMcpEntryValue();
|
|
3138
3138
|
const result = target.format === "json" ? mergeJsonMcpEntry({
|
|
3139
|
-
path:
|
|
3139
|
+
path: path24,
|
|
3140
3140
|
keyPath: target.keyPath,
|
|
3141
3141
|
entryValue,
|
|
3142
3142
|
backupDir: ctx.backupDir,
|
|
3143
3143
|
force: ctx.force,
|
|
3144
3144
|
alreadyBackedUpPaths: ctx.backedUpPaths
|
|
3145
3145
|
}) : target.format === "yaml" ? mergeYamlMcpEntry({
|
|
3146
|
-
path:
|
|
3146
|
+
path: path24,
|
|
3147
3147
|
mcpServersKey: target.keyPath[0] ?? "mcp_servers",
|
|
3148
3148
|
entryValue,
|
|
3149
3149
|
backupDir: ctx.backupDir,
|
|
3150
3150
|
force: ctx.force,
|
|
3151
3151
|
alreadyBackedUpPaths: ctx.backedUpPaths
|
|
3152
3152
|
}) : mergeTomlBlock({
|
|
3153
|
-
path:
|
|
3153
|
+
path: path24,
|
|
3154
3154
|
markerId: "mcp_servers.skillsmith",
|
|
3155
3155
|
blockContent: buildCodexMcpTomlBlock(),
|
|
3156
3156
|
foreignHeaderPattern: CODEX_MCP_FOREIGN_HEADER,
|
|
@@ -3161,7 +3161,7 @@ function installMcpConfig(harness, ctx, report) {
|
|
|
3161
3161
|
report.mcpConfig = result;
|
|
3162
3162
|
if (mergeSucceeded(result.status)) {
|
|
3163
3163
|
ctx.entries.push({
|
|
3164
|
-
path:
|
|
3164
|
+
path: path24,
|
|
3165
3165
|
kind: "mcp-config",
|
|
3166
3166
|
harness,
|
|
3167
3167
|
backupPath: result.backupPath,
|
|
@@ -3169,10 +3169,10 @@ function installMcpConfig(harness, ctx, report) {
|
|
|
3169
3169
|
});
|
|
3170
3170
|
}
|
|
3171
3171
|
if (result.status === "conflict") {
|
|
3172
|
-
report.notes.push(`MCP config at ${
|
|
3172
|
+
report.notes.push(`MCP config at ${path24} already has a 'skillsmith' entry that doesn't look like ours \u2014 left untouched. Re-run with --force to overwrite, or edit ${path24} manually.`);
|
|
3173
3173
|
}
|
|
3174
3174
|
if (result.status === "error") {
|
|
3175
|
-
report.notes.push(`MCP config merge failed at ${
|
|
3175
|
+
report.notes.push(`MCP config merge failed at ${path24}: ${result.errorMessage}`);
|
|
3176
3176
|
}
|
|
3177
3177
|
}
|
|
3178
3178
|
|
|
@@ -3196,15 +3196,15 @@ function isCodexPresent(homeDir) {
|
|
|
3196
3196
|
return existsSync9(relocateUnderHome(join13(homedir6(), ".codex"), homeDir));
|
|
3197
3197
|
}
|
|
3198
3198
|
function writeSkillPackFor(clientNativePath, content, ctx, harness) {
|
|
3199
|
-
const
|
|
3199
|
+
const path24 = join13(relocateUnderHome(clientNativePath, ctx.homeDir), AGENT_PACK_SKILL_NAME, "SKILL.md");
|
|
3200
3200
|
const result = writeOwnedArtifactFile({
|
|
3201
|
-
path:
|
|
3201
|
+
path: path24,
|
|
3202
3202
|
content,
|
|
3203
3203
|
executable: false,
|
|
3204
3204
|
backupDir: ctx.backupDir
|
|
3205
3205
|
});
|
|
3206
3206
|
ctx.entries.push({
|
|
3207
|
-
path:
|
|
3207
|
+
path: path24,
|
|
3208
3208
|
kind: "skill",
|
|
3209
3209
|
harness,
|
|
3210
3210
|
backupPath: result.backupPath,
|
|
@@ -3358,8 +3358,8 @@ function allowedPathSuffixes() {
|
|
|
3358
3358
|
cachedSuffixes = computeAllowedPathSuffixes();
|
|
3359
3359
|
return cachedSuffixes;
|
|
3360
3360
|
}
|
|
3361
|
-
function isAllowedManifestEntryPath(
|
|
3362
|
-
const normalized = resolve2(
|
|
3361
|
+
function isAllowedManifestEntryPath(path24) {
|
|
3362
|
+
const normalized = resolve2(path24);
|
|
3363
3363
|
for (const suffix of allowedPathSuffixes()) {
|
|
3364
3364
|
if (normalized.endsWith(sep + suffix) || normalized === suffix)
|
|
3365
3365
|
return true;
|
|
@@ -6629,10 +6629,10 @@ function mergeDefs(...defs) {
|
|
|
6629
6629
|
function cloneDef(schema) {
|
|
6630
6630
|
return mergeDefs(schema._zod.def);
|
|
6631
6631
|
}
|
|
6632
|
-
function getElementAtPath(obj,
|
|
6633
|
-
if (!
|
|
6632
|
+
function getElementAtPath(obj, path24) {
|
|
6633
|
+
if (!path24)
|
|
6634
6634
|
return obj;
|
|
6635
|
-
return
|
|
6635
|
+
return path24.reduce((acc, key) => acc?.[key], obj);
|
|
6636
6636
|
}
|
|
6637
6637
|
function promiseAllObject(promisesObj) {
|
|
6638
6638
|
const keys = Object.keys(promisesObj);
|
|
@@ -6998,11 +6998,11 @@ function aborted(x, startIndex = 0) {
|
|
|
6998
6998
|
}
|
|
6999
6999
|
return false;
|
|
7000
7000
|
}
|
|
7001
|
-
function prefixIssues(
|
|
7001
|
+
function prefixIssues(path24, issues) {
|
|
7002
7002
|
return issues.map((iss) => {
|
|
7003
7003
|
var _a2;
|
|
7004
7004
|
(_a2 = iss).path ?? (_a2.path = []);
|
|
7005
|
-
iss.path.unshift(
|
|
7005
|
+
iss.path.unshift(path24);
|
|
7006
7006
|
return iss;
|
|
7007
7007
|
});
|
|
7008
7008
|
}
|
|
@@ -7164,7 +7164,7 @@ function formatError(error46, mapper = (issue2) => issue2.message) {
|
|
|
7164
7164
|
}
|
|
7165
7165
|
function treeifyError(error46, mapper = (issue2) => issue2.message) {
|
|
7166
7166
|
const result = { errors: [] };
|
|
7167
|
-
const processError = (error47,
|
|
7167
|
+
const processError = (error47, path24 = []) => {
|
|
7168
7168
|
var _a2, _b;
|
|
7169
7169
|
for (const issue2 of error47.issues) {
|
|
7170
7170
|
if (issue2.code === "invalid_union" && issue2.errors.length) {
|
|
@@ -7174,7 +7174,7 @@ function treeifyError(error46, mapper = (issue2) => issue2.message) {
|
|
|
7174
7174
|
} else if (issue2.code === "invalid_element") {
|
|
7175
7175
|
processError({ issues: issue2.issues }, issue2.path);
|
|
7176
7176
|
} else {
|
|
7177
|
-
const fullpath = [...
|
|
7177
|
+
const fullpath = [...path24, ...issue2.path];
|
|
7178
7178
|
if (fullpath.length === 0) {
|
|
7179
7179
|
result.errors.push(mapper(issue2));
|
|
7180
7180
|
continue;
|
|
@@ -7206,8 +7206,8 @@ function treeifyError(error46, mapper = (issue2) => issue2.message) {
|
|
|
7206
7206
|
}
|
|
7207
7207
|
function toDotPath(_path) {
|
|
7208
7208
|
const segs = [];
|
|
7209
|
-
const
|
|
7210
|
-
for (const seg of
|
|
7209
|
+
const path24 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
|
|
7210
|
+
for (const seg of path24) {
|
|
7211
7211
|
if (typeof seg === "number")
|
|
7212
7212
|
segs.push(`[${seg}]`);
|
|
7213
7213
|
else if (typeof seg === "symbol")
|
|
@@ -19007,13 +19007,13 @@ function resolveRef(ref, ctx) {
|
|
|
19007
19007
|
if (!ref.startsWith("#")) {
|
|
19008
19008
|
throw new Error("External $ref is not supported, only local refs (#/...) are allowed");
|
|
19009
19009
|
}
|
|
19010
|
-
const
|
|
19011
|
-
if (
|
|
19010
|
+
const path24 = ref.slice(1).split("/").filter(Boolean);
|
|
19011
|
+
if (path24.length === 0) {
|
|
19012
19012
|
return ctx.rootSchema;
|
|
19013
19013
|
}
|
|
19014
19014
|
const defsKey = ctx.version === "draft-2020-12" ? "$defs" : "definitions";
|
|
19015
|
-
if (
|
|
19016
|
-
const key =
|
|
19015
|
+
if (path24[0] === defsKey) {
|
|
19016
|
+
const key = path24[1];
|
|
19017
19017
|
if (!key || !ctx.defs[key]) {
|
|
19018
19018
|
throw new Error(`Reference not found: ${ref}`);
|
|
19019
19019
|
}
|
|
@@ -19617,19 +19617,19 @@ function validateUrl(url2) {
|
|
|
19617
19617
|
|
|
19618
19618
|
// ../core/dist/src/validation/path-validators.js
|
|
19619
19619
|
import { resolve as resolve3 } from "path";
|
|
19620
|
-
function validatePath(
|
|
19621
|
-
if (!
|
|
19620
|
+
function validatePath(path24, rootDir) {
|
|
19621
|
+
if (!path24) {
|
|
19622
19622
|
throw new ValidationError("Path cannot be empty", "EMPTY_PATH");
|
|
19623
19623
|
}
|
|
19624
19624
|
if (!rootDir) {
|
|
19625
19625
|
throw new ValidationError("Root directory cannot be empty", "EMPTY_ROOT_DIR");
|
|
19626
19626
|
}
|
|
19627
|
-
const normalizedPath = resolve3(rootDir,
|
|
19627
|
+
const normalizedPath = resolve3(rootDir, path24);
|
|
19628
19628
|
const normalizedRoot = resolve3(rootDir);
|
|
19629
19629
|
const isWithinRoot = normalizedPath.startsWith(normalizedRoot + "/") || normalizedPath === normalizedRoot;
|
|
19630
19630
|
if (!isWithinRoot) {
|
|
19631
|
-
throw new ValidationError(`Path traversal detected: ${
|
|
19632
|
-
originalPath:
|
|
19631
|
+
throw new ValidationError(`Path traversal detected: ${path24}`, "PATH_TRAVERSAL", {
|
|
19632
|
+
originalPath: path24,
|
|
19633
19633
|
normalizedPath,
|
|
19634
19634
|
rootDir,
|
|
19635
19635
|
normalizedRoot
|
|
@@ -20403,8 +20403,8 @@ function implicitDownloadBasename(line) {
|
|
|
20403
20403
|
const slash = noFrag.indexOf("/");
|
|
20404
20404
|
if (slash < 0)
|
|
20405
20405
|
return "";
|
|
20406
|
-
const
|
|
20407
|
-
return
|
|
20406
|
+
const path24 = noFrag.slice(slash + 1).replace(/\/+$/, "");
|
|
20407
|
+
return path24 === "" ? "" : path24.split("/").pop() ?? "";
|
|
20408
20408
|
};
|
|
20409
20409
|
const wget = line.match(/\bwget\b(?![^\n]{0,200}\s-[oO]\b)[^\n]{0,200}?https?:\/\/(\S{1,400})/i);
|
|
20410
20410
|
if (wget)
|
|
@@ -22356,21 +22356,21 @@ function mapErrnoToCode(err) {
|
|
|
22356
22356
|
return "io";
|
|
22357
22357
|
}
|
|
22358
22358
|
}
|
|
22359
|
-
function describe3(code,
|
|
22359
|
+
function describe3(code, path24) {
|
|
22360
22360
|
switch (code) {
|
|
22361
22361
|
case "permission":
|
|
22362
|
-
return `Cannot read: ${
|
|
22362
|
+
return `Cannot read: ${path24}`;
|
|
22363
22363
|
case "not-found":
|
|
22364
|
-
return `Not found: ${
|
|
22364
|
+
return `Not found: ${path24}`;
|
|
22365
22365
|
case "loop":
|
|
22366
|
-
return `Symlink loop detected: ${
|
|
22366
|
+
return `Symlink loop detected: ${path24}`;
|
|
22367
22367
|
case "symlink-escape":
|
|
22368
|
-
return `Symlink outside root, skipped: ${
|
|
22368
|
+
return `Symlink outside root, skipped: ${path24}`;
|
|
22369
22369
|
case "io":
|
|
22370
|
-
return `Filesystem error: ${
|
|
22370
|
+
return `Filesystem error: ${path24}`;
|
|
22371
22371
|
}
|
|
22372
22372
|
}
|
|
22373
|
-
async function wrap(
|
|
22373
|
+
async function wrap(path24, op) {
|
|
22374
22374
|
try {
|
|
22375
22375
|
return { ok: true, value: await op() };
|
|
22376
22376
|
} catch (error46) {
|
|
@@ -22379,25 +22379,25 @@ async function wrap(path23, op) {
|
|
|
22379
22379
|
ok: false,
|
|
22380
22380
|
error: {
|
|
22381
22381
|
code,
|
|
22382
|
-
path:
|
|
22383
|
-
message: describe3(code,
|
|
22382
|
+
path: path24,
|
|
22383
|
+
message: describe3(code, path24),
|
|
22384
22384
|
cause: error46
|
|
22385
22385
|
}
|
|
22386
22386
|
};
|
|
22387
22387
|
}
|
|
22388
22388
|
}
|
|
22389
22389
|
var safeFs = {
|
|
22390
|
-
readdir(
|
|
22391
|
-
return wrap(
|
|
22390
|
+
readdir(path24) {
|
|
22391
|
+
return wrap(path24, () => fs2.readdir(path24, { withFileTypes: true }));
|
|
22392
22392
|
},
|
|
22393
|
-
stat(
|
|
22394
|
-
return wrap(
|
|
22393
|
+
stat(path24) {
|
|
22394
|
+
return wrap(path24, () => fs2.stat(path24));
|
|
22395
22395
|
},
|
|
22396
|
-
readFile(
|
|
22397
|
-
return wrap(
|
|
22396
|
+
readFile(path24, encoding = "utf-8") {
|
|
22397
|
+
return wrap(path24, () => fs2.readFile(path24, encoding));
|
|
22398
22398
|
},
|
|
22399
|
-
realpath(
|
|
22400
|
-
return wrap(
|
|
22399
|
+
realpath(path24) {
|
|
22400
|
+
return wrap(path24, () => fs2.realpath(path24));
|
|
22401
22401
|
}
|
|
22402
22402
|
};
|
|
22403
22403
|
function isRealpathContained(candidateReal, rootReal) {
|
|
@@ -22803,8 +22803,8 @@ var LocalFilesystemAdapter = class extends BaseSourceAdapter {
|
|
|
22803
22803
|
/**
|
|
22804
22804
|
* Generate a deterministic ID from a path
|
|
22805
22805
|
*/
|
|
22806
|
-
generateId(
|
|
22807
|
-
return createHash2("sha256").update(
|
|
22806
|
+
generateId(path24) {
|
|
22807
|
+
return createHash2("sha256").update(path24).digest("hex").slice(0, 16);
|
|
22808
22808
|
}
|
|
22809
22809
|
/**
|
|
22810
22810
|
* Generate SHA hash for content
|
|
@@ -23311,7 +23311,7 @@ var BetterSqlite3Database = class {
|
|
|
23311
23311
|
return this.db;
|
|
23312
23312
|
}
|
|
23313
23313
|
};
|
|
23314
|
-
function createBetterSqlite3Database(
|
|
23314
|
+
function createBetterSqlite3Database(path24 = ":memory:", options) {
|
|
23315
23315
|
const Database = require2("better-sqlite3");
|
|
23316
23316
|
const dbOptions = {
|
|
23317
23317
|
timeout: options?.timeout ?? 5e3
|
|
@@ -23325,7 +23325,7 @@ function createBetterSqlite3Database(path23 = ":memory:", options) {
|
|
|
23325
23325
|
if (options?.verbose) {
|
|
23326
23326
|
dbOptions.verbose = console.log;
|
|
23327
23327
|
}
|
|
23328
|
-
const db = new Database(
|
|
23328
|
+
const db = new Database(path24, dbOptions);
|
|
23329
23329
|
return new BetterSqlite3Database(db);
|
|
23330
23330
|
}
|
|
23331
23331
|
var betterSqlite3FailureReason;
|
|
@@ -23362,16 +23362,16 @@ function isCorruptionError(err) {
|
|
|
23362
23362
|
const message = (err instanceof Error ? err.message : typeof err === "string" ? err : String(err)).toLowerCase();
|
|
23363
23363
|
return CORRUPTION_MARKERS.some((marker) => message.includes(marker));
|
|
23364
23364
|
}
|
|
23365
|
-
function backupCorruptDbFile(
|
|
23366
|
-
if (
|
|
23365
|
+
function backupCorruptDbFile(path24) {
|
|
23366
|
+
if (path24 === ":memory:") {
|
|
23367
23367
|
throw new Error("[Skillsmith] backupCorruptDbFile: cannot back up an in-memory database");
|
|
23368
23368
|
}
|
|
23369
|
-
if (!existsSync12(
|
|
23370
|
-
throw new Error(`[Skillsmith] backupCorruptDbFile: file does not exist: ${
|
|
23369
|
+
if (!existsSync12(path24)) {
|
|
23370
|
+
throw new Error(`[Skillsmith] backupCorruptDbFile: file does not exist: ${path24}`);
|
|
23371
23371
|
}
|
|
23372
23372
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
23373
|
-
const backupPath = `${
|
|
23374
|
-
renameSync(
|
|
23373
|
+
const backupPath = `${path24}.corrupt-${timestamp}`;
|
|
23374
|
+
renameSync(path24, backupPath);
|
|
23375
23375
|
return backupPath;
|
|
23376
23376
|
}
|
|
23377
23377
|
|
|
@@ -23603,13 +23603,13 @@ var SqlJsDatabaseAdapter = class {
|
|
|
23603
23603
|
return this.db;
|
|
23604
23604
|
}
|
|
23605
23605
|
};
|
|
23606
|
-
async function createSqlJsDatabase(
|
|
23606
|
+
async function createSqlJsDatabase(path24 = ":memory:", options) {
|
|
23607
23607
|
const SQL = await loadSqlJs();
|
|
23608
23608
|
let data;
|
|
23609
|
-
if (
|
|
23610
|
-
data = readFileSync10(
|
|
23611
|
-
} else if (
|
|
23612
|
-
throw new Error(`SQLITE_CANTOPEN: unable to open database file: ${
|
|
23609
|
+
if (path24 !== ":memory:" && existsSync13(path24)) {
|
|
23610
|
+
data = readFileSync10(path24);
|
|
23611
|
+
} else if (path24 !== ":memory:" && options?.fileMustExist) {
|
|
23612
|
+
throw new Error(`SQLITE_CANTOPEN: unable to open database file: ${path24}`);
|
|
23613
23613
|
}
|
|
23614
23614
|
let db;
|
|
23615
23615
|
let partialDb;
|
|
@@ -23627,15 +23627,15 @@ async function createSqlJsDatabase(path23 = ":memory:", options) {
|
|
|
23627
23627
|
} catch {
|
|
23628
23628
|
}
|
|
23629
23629
|
}
|
|
23630
|
-
if (!isCorruptionError(error46) ||
|
|
23630
|
+
if (!isCorruptionError(error46) || path24 === ":memory:" || !existsSync13(path24)) {
|
|
23631
23631
|
throw error46;
|
|
23632
23632
|
}
|
|
23633
|
-
const backupPath = backupCorruptDbFile(
|
|
23634
|
-
console.warn(`[Skillsmith] The local database at ${
|
|
23633
|
+
const backupPath = backupCorruptDbFile(path24);
|
|
23634
|
+
console.warn(`[Skillsmith] The local database at ${path24} was corrupt and could not be opened. It has been backed up to ${backupPath} and will be rebuilt on the next sync.`);
|
|
23635
23635
|
db = new SQL.Database();
|
|
23636
23636
|
db.run("PRAGMA foreign_keys = ON");
|
|
23637
23637
|
}
|
|
23638
|
-
return new SqlJsDatabaseAdapter(db,
|
|
23638
|
+
return new SqlJsDatabaseAdapter(db, path24, options);
|
|
23639
23639
|
}
|
|
23640
23640
|
function isSqlJsAvailable() {
|
|
23641
23641
|
try {
|
|
@@ -23648,21 +23648,21 @@ function isSqlJsAvailable() {
|
|
|
23648
23648
|
|
|
23649
23649
|
// ../core/dist/src/db/createDatabase.js
|
|
23650
23650
|
var wasmFallbackNoticeEmitted = false;
|
|
23651
|
-
function createDatabaseSync(
|
|
23651
|
+
function createDatabaseSync(path24 = ":memory:", options) {
|
|
23652
23652
|
if (!isBetterSqlite3Available()) {
|
|
23653
23653
|
throw new Error("[Skillsmith] Native SQLite module (better-sqlite3) is not available. This may be due to:\n - Binary compiled for a different platform (Linux vs macOS)\n - Node.js version mismatch\n - Missing native build tools\n\nSolutions:\n - Run in Docker: docker compose --profile dev up -d\n - Rebuild native module: npm rebuild better-sqlite3\n - Use createDatabaseAsync() for automatic WASM fallback");
|
|
23654
23654
|
}
|
|
23655
|
-
return createBetterSqlite3Database(
|
|
23655
|
+
return createBetterSqlite3Database(path24, options);
|
|
23656
23656
|
}
|
|
23657
|
-
async function createDatabaseAsync(
|
|
23657
|
+
async function createDatabaseAsync(path24 = ":memory:", options) {
|
|
23658
23658
|
if (process.env.SKILLSMITH_FORCE_WASM === "true") {
|
|
23659
23659
|
if (isSqlJsAvailable()) {
|
|
23660
|
-
return await createSqlJsDatabase(
|
|
23660
|
+
return await createSqlJsDatabase(path24, options);
|
|
23661
23661
|
}
|
|
23662
23662
|
throw new Error("[Skillsmith] SKILLSMITH_FORCE_WASM is set but sql.js (WASM) is not available.\n\nInstall sql.js: npm install sql.js");
|
|
23663
23663
|
}
|
|
23664
23664
|
if (isBetterSqlite3Available()) {
|
|
23665
|
-
return createBetterSqlite3Database(
|
|
23665
|
+
return createBetterSqlite3Database(path24, options);
|
|
23666
23666
|
}
|
|
23667
23667
|
if (isSqlJsAvailable()) {
|
|
23668
23668
|
if (!wasmFallbackNoticeEmitted) {
|
|
@@ -23676,7 +23676,7 @@ async function createDatabaseAsync(path23 = ":memory:", options) {
|
|
|
23676
23676
|
}
|
|
23677
23677
|
console.warn(message);
|
|
23678
23678
|
}
|
|
23679
|
-
return await createSqlJsDatabase(
|
|
23679
|
+
return await createSqlJsDatabase(path24, options);
|
|
23680
23680
|
}
|
|
23681
23681
|
throw new Error("[Skillsmith] No SQLite driver available.\n\nNeither better-sqlite3 (native) nor sql.js (WASM) could be loaded.\n\nSolutions:\n - Run in Docker: docker compose --profile dev up -d\n - Rebuild native module: npm rebuild better-sqlite3\n - Install sql.js: npm install sql.js");
|
|
23682
23682
|
}
|
|
@@ -25687,11 +25687,11 @@ var INVENTORY_LIMITS = {
|
|
|
25687
25687
|
import { readdir as readdir3, readFile as readFile2, realpath, stat as stat2 } from "node:fs/promises";
|
|
25688
25688
|
import { createHash as createHash4 } from "node:crypto";
|
|
25689
25689
|
import { join as join21 } from "node:path";
|
|
25690
|
-
async function safeRealpath(
|
|
25690
|
+
async function safeRealpath(path24) {
|
|
25691
25691
|
try {
|
|
25692
|
-
return await realpath(
|
|
25692
|
+
return await realpath(path24);
|
|
25693
25693
|
} catch {
|
|
25694
|
-
return
|
|
25694
|
+
return path24;
|
|
25695
25695
|
}
|
|
25696
25696
|
}
|
|
25697
25697
|
async function resolvesToDirectory(entryPath, isDirectory, isSymbolicLink) {
|
|
@@ -28204,8 +28204,8 @@ function initializeSchema(db) {
|
|
|
28204
28204
|
db.prepare("INSERT OR IGNORE INTO schema_version (version) VALUES (1)").run();
|
|
28205
28205
|
runMigrations(db);
|
|
28206
28206
|
}
|
|
28207
|
-
function openDatabase(
|
|
28208
|
-
const db = createDatabaseSync(
|
|
28207
|
+
function openDatabase(path24) {
|
|
28208
|
+
const db = createDatabaseSync(path24);
|
|
28209
28209
|
db.pragma("foreign_keys = ON");
|
|
28210
28210
|
const hasSchemaVersion = db.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name='schema_version'").get();
|
|
28211
28211
|
if (!hasSchemaVersion) {
|
|
@@ -32103,17 +32103,17 @@ function getCliLogger() {
|
|
|
32103
32103
|
// src/utils/open-database.ts
|
|
32104
32104
|
import { existsSync as existsSync19 } from "node:fs";
|
|
32105
32105
|
var logger8 = getCliLogger();
|
|
32106
|
-
async function openCliDatabase(
|
|
32106
|
+
async function openCliDatabase(path24, options) {
|
|
32107
32107
|
if (options?.readonly) {
|
|
32108
|
-
return createDatabaseAsync(
|
|
32108
|
+
return createDatabaseAsync(path24, { readonly: true });
|
|
32109
32109
|
}
|
|
32110
32110
|
let db;
|
|
32111
32111
|
try {
|
|
32112
|
-
db = await createDatabaseAsync(
|
|
32112
|
+
db = await createDatabaseAsync(path24);
|
|
32113
32113
|
initializeSchema(db);
|
|
32114
32114
|
return db;
|
|
32115
32115
|
} catch (err) {
|
|
32116
|
-
if (!isCorruptionError(err) ||
|
|
32116
|
+
if (!isCorruptionError(err) || path24 === ":memory:" || !existsSync19(path24)) {
|
|
32117
32117
|
throw err;
|
|
32118
32118
|
}
|
|
32119
32119
|
if (db) {
|
|
@@ -32122,11 +32122,11 @@ async function openCliDatabase(path23, options) {
|
|
|
32122
32122
|
} catch {
|
|
32123
32123
|
}
|
|
32124
32124
|
}
|
|
32125
|
-
const backupPath = backupCorruptDbFile(
|
|
32125
|
+
const backupPath = backupCorruptDbFile(path24);
|
|
32126
32126
|
logger8.warn(
|
|
32127
|
-
`[Skillsmith] The local database at ${
|
|
32127
|
+
`[Skillsmith] The local database at ${path24} was corrupt and could not be opened. It has been backed up to ${backupPath} and will be rebuilt on the next sync.`
|
|
32128
32128
|
);
|
|
32129
|
-
const fresh = await createDatabaseAsync(
|
|
32129
|
+
const fresh = await createDatabaseAsync(path24);
|
|
32130
32130
|
initializeSchema(fresh);
|
|
32131
32131
|
return fresh;
|
|
32132
32132
|
}
|
|
@@ -32135,6 +32135,7 @@ async function openCliDatabase(path23, options) {
|
|
|
32135
32135
|
// src/commands/install.ts
|
|
32136
32136
|
import { Command } from "commander";
|
|
32137
32137
|
import ora from "ora";
|
|
32138
|
+
import * as path13 from "node:path";
|
|
32138
32139
|
|
|
32139
32140
|
// src/utils/sanitize.ts
|
|
32140
32141
|
import { homedir as homedir18 } from "os";
|
|
@@ -32347,10 +32348,11 @@ async function installActionImpl(skillId, opts) {
|
|
|
32347
32348
|
...!result.success && result.errorCode !== void 0 && { errorCode: result.errorCode }
|
|
32348
32349
|
});
|
|
32349
32350
|
if (result.success && alsoLinkClients.length > 0) {
|
|
32351
|
+
const linkSkillName = path13.basename(result.installPath);
|
|
32350
32352
|
for (const target of alsoLinkClients) {
|
|
32351
32353
|
try {
|
|
32352
32354
|
const linked = await addLink({
|
|
32353
|
-
skillId,
|
|
32355
|
+
skillId: linkSkillName,
|
|
32354
32356
|
fromClient: client,
|
|
32355
32357
|
toClient: target,
|
|
32356
32358
|
preferSymlink: opts.symlink ?? false,
|
|
@@ -33534,9 +33536,9 @@ Validation Result for ${filePath}:
|
|
|
33534
33536
|
}
|
|
33535
33537
|
console.log();
|
|
33536
33538
|
}
|
|
33537
|
-
async function fileExists(
|
|
33539
|
+
async function fileExists(path24) {
|
|
33538
33540
|
try {
|
|
33539
|
-
await access3(
|
|
33541
|
+
await access3(path24);
|
|
33540
33542
|
return true;
|
|
33541
33543
|
} catch {
|
|
33542
33544
|
return false;
|
|
@@ -34857,7 +34859,7 @@ function createPublishCommand() {
|
|
|
34857
34859
|
import { Command as Command5 } from "commander";
|
|
34858
34860
|
import ora6 from "ora";
|
|
34859
34861
|
import { readFile as readFile9, writeFile as writeFile6, stat as stat8 } from "fs/promises";
|
|
34860
|
-
import { basename as
|
|
34862
|
+
import { basename as basename5, dirname as dirname18, join as join41, resolve as resolve11 } from "path";
|
|
34861
34863
|
|
|
34862
34864
|
// src/utils/tool-analyzer.ts
|
|
34863
34865
|
var TOOL_PATTERNS3 = {
|
|
@@ -35039,7 +35041,7 @@ async function generateSubagent2(skillPath, options) {
|
|
|
35039
35041
|
return;
|
|
35040
35042
|
}
|
|
35041
35043
|
const agentsDir = await ensureAgentsDirectory(options.output);
|
|
35042
|
-
const subagentPath = join41(agentsDir, `${
|
|
35044
|
+
const subagentPath = join41(agentsDir, `${basename5(metadata.name)}-specialist.md`);
|
|
35043
35045
|
if (await fileExists(subagentPath)) {
|
|
35044
35046
|
if (!options.force) {
|
|
35045
35047
|
spinner.warn(`Subagent already exists: ${subagentPath}`);
|
|
@@ -36613,9 +36615,9 @@ function getAssetsPath() {
|
|
|
36613
36615
|
function getTargetPath() {
|
|
36614
36616
|
return join45(getCanonicalInstallPath(), "skillsmith");
|
|
36615
36617
|
}
|
|
36616
|
-
async function directoryExists(
|
|
36618
|
+
async function directoryExists(path24) {
|
|
36617
36619
|
try {
|
|
36618
|
-
const stats = await stat10(
|
|
36620
|
+
const stats = await stat10(path24);
|
|
36619
36621
|
return stats.isDirectory();
|
|
36620
36622
|
} catch {
|
|
36621
36623
|
return false;
|
|
@@ -37533,7 +37535,7 @@ import { Command as Command21 } from "commander";
|
|
|
37533
37535
|
|
|
37534
37536
|
// src/commands/audit-collisions.ts
|
|
37535
37537
|
import * as crypto11 from "node:crypto";
|
|
37536
|
-
import * as
|
|
37538
|
+
import * as fs33 from "node:fs";
|
|
37537
37539
|
import { homedir as homedir29 } from "node:os";
|
|
37538
37540
|
import { join as join58 } from "node:path";
|
|
37539
37541
|
import { Command as Command18 } from "commander";
|
|
@@ -37543,7 +37545,7 @@ import { input as input4, select as select3 } from "@inquirer/prompts";
|
|
|
37543
37545
|
import * as crypto3 from "node:crypto";
|
|
37544
37546
|
import * as fs17 from "node:fs/promises";
|
|
37545
37547
|
import * as os7 from "node:os";
|
|
37546
|
-
import * as
|
|
37548
|
+
import * as path15 from "node:path";
|
|
37547
37549
|
|
|
37548
37550
|
// ../mcp-server/node_modules/ulid/dist/node/index.js
|
|
37549
37551
|
import crypto2 from "node:crypto";
|
|
@@ -37641,15 +37643,15 @@ function ulid3(seedTime, prng) {
|
|
|
37641
37643
|
}
|
|
37642
37644
|
|
|
37643
37645
|
// ../mcp-server/dist/src/audit/audit-history.js
|
|
37644
|
-
var DEFAULT_AUDITS_DIR =
|
|
37646
|
+
var DEFAULT_AUDITS_DIR = path15.join(os7.homedir(), ".skillsmith", "audits");
|
|
37645
37647
|
function newAuditId() {
|
|
37646
37648
|
return ulid3();
|
|
37647
37649
|
}
|
|
37648
37650
|
async function writeAuditHistory(result, opts = {}) {
|
|
37649
37651
|
const auditsDir = opts.auditsDir ?? DEFAULT_AUDITS_DIR;
|
|
37650
|
-
const auditDir =
|
|
37651
|
-
const resultPath =
|
|
37652
|
-
const reportPath =
|
|
37652
|
+
const auditDir = path15.join(auditsDir, result.auditId);
|
|
37653
|
+
const resultPath = path15.join(auditDir, "result.json");
|
|
37654
|
+
const reportPath = path15.join(auditDir, "report.md");
|
|
37653
37655
|
const tmpPath = `${resultPath}.tmp`;
|
|
37654
37656
|
await fs17.mkdir(auditDir, { recursive: true });
|
|
37655
37657
|
const json2 = JSON.stringify(result, null, 2);
|
|
@@ -38149,8 +38151,8 @@ function getErrorMap2() {
|
|
|
38149
38151
|
|
|
38150
38152
|
// ../mcp-server/node_modules/zod/v3/helpers/parseUtil.js
|
|
38151
38153
|
var makeIssue = (params) => {
|
|
38152
|
-
const { data, path:
|
|
38153
|
-
const fullPath = [...
|
|
38154
|
+
const { data, path: path24, errorMaps, issueData } = params;
|
|
38155
|
+
const fullPath = [...path24, ...issueData.path || []];
|
|
38154
38156
|
const fullIssue = {
|
|
38155
38157
|
...issueData,
|
|
38156
38158
|
path: fullPath
|
|
@@ -38266,11 +38268,11 @@ var errorUtil;
|
|
|
38266
38268
|
|
|
38267
38269
|
// ../mcp-server/node_modules/zod/v3/types.js
|
|
38268
38270
|
var ParseInputLazyPath = class {
|
|
38269
|
-
constructor(parent, value,
|
|
38271
|
+
constructor(parent, value, path24, key) {
|
|
38270
38272
|
this._cachedPath = [];
|
|
38271
38273
|
this.parent = parent;
|
|
38272
38274
|
this.data = value;
|
|
38273
|
-
this._path =
|
|
38275
|
+
this._path = path24;
|
|
38274
38276
|
this._key = key;
|
|
38275
38277
|
}
|
|
38276
38278
|
get path() {
|
|
@@ -42545,7 +42547,7 @@ function nsToMs(ns) {
|
|
|
42545
42547
|
|
|
42546
42548
|
// ../mcp-server/dist/src/audit/audit-report-writer.js
|
|
42547
42549
|
import * as fs19 from "node:fs/promises";
|
|
42548
|
-
import * as
|
|
42550
|
+
import * as path16 from "node:path";
|
|
42549
42551
|
function renderAuditReport(result, opts = {}) {
|
|
42550
42552
|
const generatedAt = opts.generatedAt ?? /* @__PURE__ */ new Date();
|
|
42551
42553
|
const sections = [];
|
|
@@ -42572,7 +42574,7 @@ function renderAuditReport(result, opts = {}) {
|
|
|
42572
42574
|
return sections.join("\n").trimEnd() + "\n";
|
|
42573
42575
|
}
|
|
42574
42576
|
async function writeAuditReport(result, opts) {
|
|
42575
|
-
const reportPath =
|
|
42577
|
+
const reportPath = path16.join(opts.auditDir, "report.md");
|
|
42576
42578
|
const tmpPath = `${reportPath}.tmp`;
|
|
42577
42579
|
await fs19.mkdir(opts.auditDir, { recursive: true });
|
|
42578
42580
|
const body = renderAuditReport(result, {
|
|
@@ -42757,28 +42759,28 @@ import * as os10 from "node:os";
|
|
|
42757
42759
|
// ../mcp-server/dist/src/utils/local-inventory.js
|
|
42758
42760
|
import * as fs20 from "node:fs";
|
|
42759
42761
|
import * as os8 from "node:os";
|
|
42760
|
-
import * as
|
|
42761
|
-
var DEFAULT_HOME_CLAUDE_DIR =
|
|
42762
|
-
var DEFAULT_MANIFEST_PATH3 =
|
|
42762
|
+
import * as path17 from "node:path";
|
|
42763
|
+
var DEFAULT_HOME_CLAUDE_DIR = path17.join(os8.homedir(), ".claude");
|
|
42764
|
+
var DEFAULT_MANIFEST_PATH3 = path17.join(os8.homedir(), ".skillsmith", "manifest.json");
|
|
42763
42765
|
async function scanLocalInventory(opts = {}) {
|
|
42764
42766
|
const startedAt = process.hrtime.bigint();
|
|
42765
42767
|
const homeDir = opts.homeDir ?? os8.homedir();
|
|
42766
|
-
const claudeDir = opts.homeDir ?
|
|
42768
|
+
const claudeDir = opts.homeDir ? path17.join(opts.homeDir, ".claude") : DEFAULT_HOME_CLAUDE_DIR;
|
|
42767
42769
|
const manifestPath = opts.manifestPath ?? DEFAULT_MANIFEST_PATH3;
|
|
42768
42770
|
const warnings = [];
|
|
42769
42771
|
const entries = [];
|
|
42770
42772
|
const manifest = loadManifest3(manifestPath);
|
|
42771
|
-
entries.push(...scanSkills(
|
|
42772
|
-
const agentsSkillsDir = opts.homeDir ?
|
|
42773
|
+
entries.push(...scanSkills(path17.join(claudeDir, "skills"), manifest, warnings));
|
|
42774
|
+
const agentsSkillsDir = opts.homeDir ? path17.join(opts.homeDir, ".agents", "skills") : path17.join(os8.homedir(), ".agents", "skills");
|
|
42773
42775
|
entries.push(...scanSkills(agentsSkillsDir, manifest, warnings));
|
|
42774
|
-
entries.push(...scanCommands(
|
|
42775
|
-
entries.push(...scanAgents(
|
|
42776
|
-
const userClaudeMd =
|
|
42776
|
+
entries.push(...scanCommands(path17.join(claudeDir, "commands"), warnings));
|
|
42777
|
+
entries.push(...scanAgents(path17.join(claudeDir, "agents"), warnings));
|
|
42778
|
+
const userClaudeMd = path17.join(claudeDir, "CLAUDE.md");
|
|
42777
42779
|
if (fs20.existsSync(userClaudeMd)) {
|
|
42778
42780
|
entries.push(...extractClaudeMdTriggers(userClaudeMd, warnings));
|
|
42779
42781
|
}
|
|
42780
42782
|
if (opts.projectDir) {
|
|
42781
|
-
const projectClaudeMd =
|
|
42783
|
+
const projectClaudeMd = path17.join(opts.projectDir, "CLAUDE.md");
|
|
42782
42784
|
if (fs20.existsSync(projectClaudeMd)) {
|
|
42783
42785
|
entries.push(...extractClaudeMdTriggers(projectClaudeMd, warnings));
|
|
42784
42786
|
}
|
|
@@ -42806,8 +42808,8 @@ function scanSkills(skillsDir, manifest, warnings) {
|
|
|
42806
42808
|
for (const dirent of dirEntries) {
|
|
42807
42809
|
if (!dirent.isDirectory() || dirent.name.startsWith("."))
|
|
42808
42810
|
continue;
|
|
42809
|
-
const skillDir =
|
|
42810
|
-
const skillMd =
|
|
42811
|
+
const skillDir = path17.join(skillsDir, dirent.name);
|
|
42812
|
+
const skillMd = path17.join(skillDir, "SKILL.md");
|
|
42811
42813
|
let identifier = dirent.name;
|
|
42812
42814
|
let description;
|
|
42813
42815
|
let mtime;
|
|
@@ -42869,7 +42871,7 @@ function scanMdDir(dir, kind, warnings) {
|
|
|
42869
42871
|
continue;
|
|
42870
42872
|
if (dirent.name.startsWith("."))
|
|
42871
42873
|
continue;
|
|
42872
|
-
const filePath =
|
|
42874
|
+
const filePath = path17.join(dir, dirent.name);
|
|
42873
42875
|
const identifier = dirent.name.slice(0, -3);
|
|
42874
42876
|
const fm = readFrontmatter2(filePath);
|
|
42875
42877
|
const description = coerceDescription2(fm.description);
|
|
@@ -42904,10 +42906,10 @@ function coerceDescription2(value) {
|
|
|
42904
42906
|
// ../mcp-server/dist/src/audit/security-baseline.js
|
|
42905
42907
|
import * as fs21 from "node:fs";
|
|
42906
42908
|
import * as os9 from "node:os";
|
|
42907
|
-
import * as
|
|
42909
|
+
import * as path18 from "node:path";
|
|
42908
42910
|
var SECURITY_BASELINE_VERSION = 1;
|
|
42909
42911
|
function defaultBaselinePath(homeDir = os9.homedir()) {
|
|
42910
|
-
return
|
|
42912
|
+
return path18.join(homeDir, ".skillsmith", "audits", "security-baseline.json");
|
|
42911
42913
|
}
|
|
42912
42914
|
function emptyBaseline() {
|
|
42913
42915
|
return { version: SECURITY_BASELINE_VERSION, skills: {} };
|
|
@@ -42930,7 +42932,7 @@ function loadSecurityBaseline(baselinePath) {
|
|
|
42930
42932
|
}
|
|
42931
42933
|
}
|
|
42932
42934
|
function saveSecurityBaseline(baselinePath, baseline) {
|
|
42933
|
-
const dir =
|
|
42935
|
+
const dir = path18.dirname(baselinePath);
|
|
42934
42936
|
fs21.mkdirSync(dir, { recursive: true, mode: 448 });
|
|
42935
42937
|
const tmp = `${baselinePath}.tmp-${process.pid}-${process.hrtime.bigint()}`;
|
|
42936
42938
|
fs21.writeFileSync(tmp, JSON.stringify(baseline, null, 2), { mode: 384 });
|
|
@@ -43174,14 +43176,14 @@ function hashDigest(payload) {
|
|
|
43174
43176
|
import * as crypto7 from "node:crypto";
|
|
43175
43177
|
import * as fs23 from "node:fs/promises";
|
|
43176
43178
|
import * as os11 from "node:os";
|
|
43177
|
-
import * as
|
|
43179
|
+
import * as path19 from "node:path";
|
|
43178
43180
|
|
|
43179
43181
|
// ../mcp-server/dist/src/audit/namespace-overrides.types.js
|
|
43180
43182
|
var CURRENT_VERSION = 1;
|
|
43181
43183
|
|
|
43182
43184
|
// ../mcp-server/dist/src/audit/namespace-overrides.js
|
|
43183
43185
|
function defaultLedgerPath() {
|
|
43184
|
-
return
|
|
43186
|
+
return path19.join(os11.homedir(), ".skillsmith", "namespace-overrides.json");
|
|
43185
43187
|
}
|
|
43186
43188
|
var ULID_PREFIX = "ovr_";
|
|
43187
43189
|
function emptyLedger() {
|
|
@@ -43261,7 +43263,7 @@ async function writeLedger(ledger, opts = {}) {
|
|
|
43261
43263
|
const ledgerPath2 = opts.ledgerPath ?? defaultLedgerPath();
|
|
43262
43264
|
const tmpSuffix = crypto7.randomBytes(6).toString("hex");
|
|
43263
43265
|
const tmpPath = `${ledgerPath2}.${tmpSuffix}.tmp`;
|
|
43264
|
-
await fs23.mkdir(
|
|
43266
|
+
await fs23.mkdir(path19.dirname(ledgerPath2), { recursive: true });
|
|
43265
43267
|
const normalized = { version: CURRENT_VERSION, overrides: ledger.overrides };
|
|
43266
43268
|
const json2 = JSON.stringify(normalized, null, 2);
|
|
43267
43269
|
try {
|
|
@@ -43301,23 +43303,22 @@ function findOverride(ledger, query) {
|
|
|
43301
43303
|
}
|
|
43302
43304
|
|
|
43303
43305
|
// ../mcp-server/dist/src/audit/rename-engine.js
|
|
43304
|
-
import * as
|
|
43305
|
-
import * as path21 from "node:path";
|
|
43306
|
+
import * as fs27 from "node:fs/promises";
|
|
43306
43307
|
|
|
43307
43308
|
// ../mcp-server/dist/src/tools/install.conflict-helpers.js
|
|
43308
43309
|
import * as fs24 from "fs/promises";
|
|
43309
|
-
import * as
|
|
43310
|
+
import * as path20 from "path";
|
|
43310
43311
|
function getBackupsDir() {
|
|
43311
|
-
return
|
|
43312
|
+
return path20.join(getCanonicalInstallPath(), ".backups");
|
|
43312
43313
|
}
|
|
43313
43314
|
async function createSkillBackup(skillName, installPath, reason) {
|
|
43314
43315
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
43315
|
-
const backupDir =
|
|
43316
|
+
const backupDir = path20.join(getBackupsDir(), skillName, `${timestamp}_${reason}`);
|
|
43316
43317
|
await fs24.mkdir(backupDir, { recursive: true });
|
|
43317
43318
|
const entries = await fs24.readdir(installPath, { withFileTypes: true });
|
|
43318
43319
|
for (const entry of entries) {
|
|
43319
|
-
const srcPath =
|
|
43320
|
-
const destPath =
|
|
43320
|
+
const srcPath = path20.join(installPath, entry.name);
|
|
43321
|
+
const destPath = path20.join(backupDir, entry.name);
|
|
43321
43322
|
if (entry.isSymbolicLink()) {
|
|
43322
43323
|
console.warn(`Skipping symlink in skill backup: ${entry.name}`);
|
|
43323
43324
|
continue;
|
|
@@ -43334,8 +43335,8 @@ async function copyDirectory2(src, dest) {
|
|
|
43334
43335
|
await fs24.mkdir(dest, { recursive: true });
|
|
43335
43336
|
const entries = await fs24.readdir(src, { withFileTypes: true });
|
|
43336
43337
|
for (const entry of entries) {
|
|
43337
|
-
const srcPath =
|
|
43338
|
-
const destPath =
|
|
43338
|
+
const srcPath = path20.join(src, entry.name);
|
|
43339
|
+
const destPath = path20.join(dest, entry.name);
|
|
43339
43340
|
if (entry.isSymbolicLink()) {
|
|
43340
43341
|
console.warn(`Skipping symlink in directory copy: ${entry.name}`);
|
|
43341
43342
|
continue;
|
|
@@ -43351,7 +43352,7 @@ async function copyDirectory2(src, dest) {
|
|
|
43351
43352
|
// ../mcp-server/dist/src/audit/rename-engine.apply-paths.js
|
|
43352
43353
|
import * as fs25 from "node:fs/promises";
|
|
43353
43354
|
import * as os12 from "node:os";
|
|
43354
|
-
import * as
|
|
43355
|
+
import * as path21 from "node:path";
|
|
43355
43356
|
function actionToKind(action) {
|
|
43356
43357
|
switch (action) {
|
|
43357
43358
|
case "rename_command_file":
|
|
@@ -43362,12 +43363,16 @@ function actionToKind(action) {
|
|
|
43362
43363
|
return "skill";
|
|
43363
43364
|
}
|
|
43364
43365
|
}
|
|
43365
|
-
function
|
|
43366
|
+
function resolveRenameTarget(suggestion) {
|
|
43366
43367
|
const src = suggestion.entry.source_path;
|
|
43368
|
+
return suggestion.applyAction === "rename_skill_dir_and_frontmatter" ? path21.dirname(src) : src;
|
|
43369
|
+
}
|
|
43370
|
+
function computeDestPath(suggestion, newName) {
|
|
43371
|
+
const target = resolveRenameTarget(suggestion);
|
|
43367
43372
|
if (suggestion.applyAction === "rename_skill_dir_and_frontmatter") {
|
|
43368
|
-
return
|
|
43373
|
+
return path21.join(path21.dirname(target), newName);
|
|
43369
43374
|
}
|
|
43370
|
-
return
|
|
43375
|
+
return path21.join(path21.dirname(target), `${newName}.md`);
|
|
43371
43376
|
}
|
|
43372
43377
|
function deriveSkillId(suggestion) {
|
|
43373
43378
|
const author = suggestion.entry.meta?.author;
|
|
@@ -43393,17 +43398,19 @@ async function pathExists2(target) {
|
|
|
43393
43398
|
}
|
|
43394
43399
|
}
|
|
43395
43400
|
async function stageSingleFileForBackup(srcFile) {
|
|
43396
|
-
const tmp = await fs25.mkdtemp(
|
|
43397
|
-
await fs25.copyFile(srcFile,
|
|
43401
|
+
const tmp = await fs25.mkdtemp(path21.join(os12.tmpdir(), "skillsmith-rename-stage-"));
|
|
43402
|
+
await fs25.copyFile(srcFile, path21.join(tmp, path21.basename(srcFile)));
|
|
43398
43403
|
return tmp;
|
|
43399
43404
|
}
|
|
43400
43405
|
async function runBackup(suggestion) {
|
|
43401
|
-
const skillName = path20.basename(suggestion.entry.source_path).replace(/\.md$/, "");
|
|
43402
43406
|
const action = suggestion.applyAction;
|
|
43407
|
+
const target = resolveRenameTarget(suggestion);
|
|
43403
43408
|
if (action === "rename_skill_dir_and_frontmatter") {
|
|
43404
|
-
|
|
43409
|
+
const skillName2 = path21.basename(target);
|
|
43410
|
+
return createSkillBackup(skillName2, target, "namespace-rename");
|
|
43405
43411
|
}
|
|
43406
|
-
const
|
|
43412
|
+
const skillName = path21.basename(target).replace(/\.md$/, "");
|
|
43413
|
+
const staged = await stageSingleFileForBackup(target);
|
|
43407
43414
|
try {
|
|
43408
43415
|
return await createSkillBackup(skillName, staged, "namespace-rename");
|
|
43409
43416
|
} finally {
|
|
@@ -43413,11 +43420,11 @@ async function runBackup(suggestion) {
|
|
|
43413
43420
|
}
|
|
43414
43421
|
}
|
|
43415
43422
|
}
|
|
43416
|
-
function buildSummary(oldIdentifier, newIdentifier, auditId, action) {
|
|
43423
|
+
function buildSummary(oldIdentifier, newIdentifier, auditId, collisionId, action) {
|
|
43417
43424
|
if (action === "revert") {
|
|
43418
43425
|
return `Reverted /${oldIdentifier} \u2192 /${newIdentifier}. Audit: ${auditId}`;
|
|
43419
43426
|
}
|
|
43420
|
-
return `Renamed /${oldIdentifier} \u2192 /${newIdentifier}. To undo:
|
|
43427
|
+
return `Renamed /${oldIdentifier} \u2192 /${newIdentifier}. To undo: call apply_namespace_rename with auditId: '${auditId}', collisionId: '${collisionId}', action: 'revert'.`;
|
|
43421
43428
|
}
|
|
43422
43429
|
|
|
43423
43430
|
// ../mcp-server/dist/src/audit/rename-engine.helpers.js
|
|
@@ -43563,6 +43570,150 @@ function escapeForDoubleQuoted(s) {
|
|
|
43563
43570
|
return s.replace(/\\/g, "\\\\").replace(/"/g, '\\"');
|
|
43564
43571
|
}
|
|
43565
43572
|
|
|
43573
|
+
// ../mcp-server/dist/src/audit/rename-engine.revert.js
|
|
43574
|
+
import * as fs26 from "node:fs/promises";
|
|
43575
|
+
import * as path22 from "node:path";
|
|
43576
|
+
async function revertRename(suggestion, auditId, collisionId) {
|
|
43577
|
+
const ledger = await readLedger();
|
|
43578
|
+
const matches = ledger.overrides.filter((o) => o.auditId === auditId);
|
|
43579
|
+
let entry = matches.find((o) => o.collisionId === collisionId);
|
|
43580
|
+
if (!entry) {
|
|
43581
|
+
if (matches.length >= 2) {
|
|
43582
|
+
return {
|
|
43583
|
+
success: false,
|
|
43584
|
+
collisionId: suggestion.collisionId,
|
|
43585
|
+
appliedAction: suggestion.applyAction,
|
|
43586
|
+
appliedRequest: "revert",
|
|
43587
|
+
fromPath: resolveRenameTarget(suggestion),
|
|
43588
|
+
toPath: "",
|
|
43589
|
+
backupPath: "",
|
|
43590
|
+
ledgerEntryId: "",
|
|
43591
|
+
summary: "",
|
|
43592
|
+
error: {
|
|
43593
|
+
kind: "namespace.rename.revert_ambiguous",
|
|
43594
|
+
auditId,
|
|
43595
|
+
collisionId,
|
|
43596
|
+
candidateCount: matches.length,
|
|
43597
|
+
message: `revert is ambiguous: ${matches.length} ledger entries share auditId ${auditId} and none match collisionId ${collisionId}; re-run skill_inventory_audit to obtain current collisionIds`
|
|
43598
|
+
}
|
|
43599
|
+
};
|
|
43600
|
+
}
|
|
43601
|
+
entry = matches[0];
|
|
43602
|
+
}
|
|
43603
|
+
if (!entry) {
|
|
43604
|
+
return {
|
|
43605
|
+
success: true,
|
|
43606
|
+
collisionId: suggestion.collisionId,
|
|
43607
|
+
appliedAction: suggestion.applyAction,
|
|
43608
|
+
appliedRequest: "revert",
|
|
43609
|
+
fromPath: resolveRenameTarget(suggestion),
|
|
43610
|
+
toPath: resolveRenameTarget(suggestion),
|
|
43611
|
+
backupPath: "",
|
|
43612
|
+
ledgerEntryId: "",
|
|
43613
|
+
summary: buildSummary(suggestion.currentName, suggestion.currentName, auditId, collisionId, "revert")
|
|
43614
|
+
};
|
|
43615
|
+
}
|
|
43616
|
+
const action = suggestion.applyAction;
|
|
43617
|
+
const onDisk = entry.renamedPath;
|
|
43618
|
+
const target = entry.originalPath;
|
|
43619
|
+
if (!await pathExists2(onDisk)) {
|
|
43620
|
+
return {
|
|
43621
|
+
success: false,
|
|
43622
|
+
collisionId: suggestion.collisionId,
|
|
43623
|
+
appliedAction: action,
|
|
43624
|
+
appliedRequest: "revert",
|
|
43625
|
+
fromPath: onDisk,
|
|
43626
|
+
toPath: target,
|
|
43627
|
+
backupPath: "",
|
|
43628
|
+
ledgerEntryId: entry.id,
|
|
43629
|
+
summary: "",
|
|
43630
|
+
error: {
|
|
43631
|
+
kind: "namespace.ledger.disk_divergence",
|
|
43632
|
+
ledgerRenamedTo: entry.renamedTo,
|
|
43633
|
+
onDisk,
|
|
43634
|
+
message: `revert source missing on disk: ${onDisk}`,
|
|
43635
|
+
remediationHint: "restore from ~/.claude/skills/.backups or remove the ledger entry manually"
|
|
43636
|
+
}
|
|
43637
|
+
};
|
|
43638
|
+
}
|
|
43639
|
+
if (target !== onDisk && await pathExists2(target)) {
|
|
43640
|
+
return {
|
|
43641
|
+
success: false,
|
|
43642
|
+
collisionId: suggestion.collisionId,
|
|
43643
|
+
appliedAction: action,
|
|
43644
|
+
appliedRequest: "revert",
|
|
43645
|
+
fromPath: onDisk,
|
|
43646
|
+
toPath: target,
|
|
43647
|
+
backupPath: "",
|
|
43648
|
+
ledgerEntryId: entry.id,
|
|
43649
|
+
summary: "",
|
|
43650
|
+
error: {
|
|
43651
|
+
kind: "namespace.rename.target_exists",
|
|
43652
|
+
target,
|
|
43653
|
+
message: `revert target already exists: ${target}`
|
|
43654
|
+
}
|
|
43655
|
+
};
|
|
43656
|
+
}
|
|
43657
|
+
try {
|
|
43658
|
+
if (action === "rename_skill_dir_and_frontmatter") {
|
|
43659
|
+
const skillMdPath = path22.join(onDisk, "SKILL.md");
|
|
43660
|
+
const current = await fs26.readFile(skillMdPath, "utf-8");
|
|
43661
|
+
const restored = rewriteFrontmatterName(current, entry.originalIdentifier);
|
|
43662
|
+
if (!restored.ok) {
|
|
43663
|
+
return {
|
|
43664
|
+
success: false,
|
|
43665
|
+
collisionId: suggestion.collisionId,
|
|
43666
|
+
appliedAction: action,
|
|
43667
|
+
appliedRequest: "revert",
|
|
43668
|
+
fromPath: onDisk,
|
|
43669
|
+
toPath: target,
|
|
43670
|
+
backupPath: "",
|
|
43671
|
+
ledgerEntryId: entry.id,
|
|
43672
|
+
summary: "",
|
|
43673
|
+
error: {
|
|
43674
|
+
kind: "namespace.rename.frontmatter_rewrite_failed",
|
|
43675
|
+
reason: restored.error.message,
|
|
43676
|
+
message: `revert frontmatter rewrite failed: ${restored.error.message}`
|
|
43677
|
+
}
|
|
43678
|
+
};
|
|
43679
|
+
}
|
|
43680
|
+
await fs26.writeFile(skillMdPath, restored.content, "utf-8");
|
|
43681
|
+
await fs26.rename(onDisk, target);
|
|
43682
|
+
} else {
|
|
43683
|
+
await fs26.rename(onDisk, target);
|
|
43684
|
+
}
|
|
43685
|
+
} catch (err) {
|
|
43686
|
+
return {
|
|
43687
|
+
success: false,
|
|
43688
|
+
collisionId: suggestion.collisionId,
|
|
43689
|
+
appliedAction: action,
|
|
43690
|
+
appliedRequest: "revert",
|
|
43691
|
+
fromPath: onDisk,
|
|
43692
|
+
toPath: target,
|
|
43693
|
+
backupPath: "",
|
|
43694
|
+
ledgerEntryId: entry.id,
|
|
43695
|
+
summary: "",
|
|
43696
|
+
error: fsErr(err.message)
|
|
43697
|
+
};
|
|
43698
|
+
}
|
|
43699
|
+
const filtered = {
|
|
43700
|
+
version: ledger.version,
|
|
43701
|
+
overrides: ledger.overrides.filter((o) => o.id !== entry.id)
|
|
43702
|
+
};
|
|
43703
|
+
await writeLedger(filtered);
|
|
43704
|
+
return {
|
|
43705
|
+
success: true,
|
|
43706
|
+
collisionId: suggestion.collisionId,
|
|
43707
|
+
appliedAction: action,
|
|
43708
|
+
appliedRequest: "revert",
|
|
43709
|
+
fromPath: onDisk,
|
|
43710
|
+
toPath: target,
|
|
43711
|
+
backupPath: "",
|
|
43712
|
+
ledgerEntryId: entry.id,
|
|
43713
|
+
summary: buildSummary(entry.renamedTo, entry.originalIdentifier, auditId, collisionId, "revert")
|
|
43714
|
+
};
|
|
43715
|
+
}
|
|
43716
|
+
|
|
43566
43717
|
// ../mcp-server/dist/src/audit/suggestion-chain.js
|
|
43567
43718
|
import * as crypto8 from "node:crypto";
|
|
43568
43719
|
var SANITIZE_MAX_LENGTH = 256;
|
|
@@ -43615,7 +43766,7 @@ async function applyRename(input7) {
|
|
|
43615
43766
|
const { suggestion, request } = input7;
|
|
43616
43767
|
const auditId = request.auditId;
|
|
43617
43768
|
if (request.action === "revert") {
|
|
43618
|
-
return revertRename(suggestion, auditId);
|
|
43769
|
+
return revertRename(suggestion, auditId, request.collisionId);
|
|
43619
43770
|
}
|
|
43620
43771
|
const newName = request.customName ?? suggestion.suggested;
|
|
43621
43772
|
const skillId = deriveSkillId(suggestion);
|
|
@@ -43639,7 +43790,7 @@ async function applyRename(input7) {
|
|
|
43639
43790
|
toPath: existing.renamedPath,
|
|
43640
43791
|
backupPath: "",
|
|
43641
43792
|
ledgerEntryId: existing.id,
|
|
43642
|
-
summary: buildSummary(suggestion.currentName, existing.renamedTo, auditId, "apply")
|
|
43793
|
+
summary: buildSummary(suggestion.currentName, existing.renamedTo, auditId, suggestion.collisionId, "apply")
|
|
43643
43794
|
};
|
|
43644
43795
|
}
|
|
43645
43796
|
return {
|
|
@@ -43647,7 +43798,7 @@ async function applyRename(input7) {
|
|
|
43647
43798
|
collisionId: suggestion.collisionId,
|
|
43648
43799
|
appliedAction: action,
|
|
43649
43800
|
appliedRequest: "apply",
|
|
43650
|
-
fromPath: suggestion
|
|
43801
|
+
fromPath: resolveRenameTarget(suggestion),
|
|
43651
43802
|
toPath: "",
|
|
43652
43803
|
backupPath: "",
|
|
43653
43804
|
ledgerEntryId: "",
|
|
@@ -43655,20 +43806,21 @@ async function applyRename(input7) {
|
|
|
43655
43806
|
error: {
|
|
43656
43807
|
kind: "namespace.ledger.disk_divergence",
|
|
43657
43808
|
ledgerRenamedTo: existing.renamedTo,
|
|
43658
|
-
onDisk: suggestion
|
|
43809
|
+
onDisk: resolveRenameTarget(suggestion),
|
|
43659
43810
|
message: `ledger records rename to ${existing.renamedTo} but no file at ${existing.renamedPath}`,
|
|
43660
43811
|
remediationHint: "re-run skill_inventory_audit and reapply, or call apply_namespace_rename with customName to overwrite the ledger entry"
|
|
43661
43812
|
}
|
|
43662
43813
|
};
|
|
43663
43814
|
}
|
|
43815
|
+
const renameTarget = resolveRenameTarget(suggestion);
|
|
43664
43816
|
const destPath = computeDestPath(suggestion, newName);
|
|
43665
|
-
if (destPath !==
|
|
43817
|
+
if (destPath !== renameTarget && await pathExists2(destPath)) {
|
|
43666
43818
|
return {
|
|
43667
43819
|
success: false,
|
|
43668
43820
|
collisionId: suggestion.collisionId,
|
|
43669
43821
|
appliedAction: action,
|
|
43670
43822
|
appliedRequest: "apply",
|
|
43671
|
-
fromPath:
|
|
43823
|
+
fromPath: renameTarget,
|
|
43672
43824
|
toPath: destPath,
|
|
43673
43825
|
backupPath: "",
|
|
43674
43826
|
ledgerEntryId: "",
|
|
@@ -43689,7 +43841,7 @@ async function applyRename(input7) {
|
|
|
43689
43841
|
collisionId: suggestion.collisionId,
|
|
43690
43842
|
appliedAction: action,
|
|
43691
43843
|
appliedRequest: "apply",
|
|
43692
|
-
fromPath:
|
|
43844
|
+
fromPath: renameTarget,
|
|
43693
43845
|
toPath: destPath,
|
|
43694
43846
|
backupPath: "",
|
|
43695
43847
|
ledgerEntryId: "",
|
|
@@ -43703,17 +43855,17 @@ async function applyRename(input7) {
|
|
|
43703
43855
|
}
|
|
43704
43856
|
try {
|
|
43705
43857
|
if (action === "rename_skill_dir_and_frontmatter") {
|
|
43706
|
-
const skillMdPath =
|
|
43858
|
+
const skillMdPath = suggestion.entry.source_path;
|
|
43707
43859
|
let original;
|
|
43708
43860
|
try {
|
|
43709
|
-
original = await
|
|
43861
|
+
original = await fs27.readFile(skillMdPath, "utf-8");
|
|
43710
43862
|
} catch (err) {
|
|
43711
43863
|
return {
|
|
43712
43864
|
success: false,
|
|
43713
43865
|
collisionId: suggestion.collisionId,
|
|
43714
43866
|
appliedAction: action,
|
|
43715
43867
|
appliedRequest: "apply",
|
|
43716
|
-
fromPath:
|
|
43868
|
+
fromPath: renameTarget,
|
|
43717
43869
|
toPath: destPath,
|
|
43718
43870
|
backupPath,
|
|
43719
43871
|
ledgerEntryId: "",
|
|
@@ -43728,7 +43880,7 @@ async function applyRename(input7) {
|
|
|
43728
43880
|
collisionId: suggestion.collisionId,
|
|
43729
43881
|
appliedAction: action,
|
|
43730
43882
|
appliedRequest: "apply",
|
|
43731
|
-
fromPath:
|
|
43883
|
+
fromPath: renameTarget,
|
|
43732
43884
|
toPath: destPath,
|
|
43733
43885
|
backupPath,
|
|
43734
43886
|
ledgerEntryId: "",
|
|
@@ -43740,10 +43892,10 @@ async function applyRename(input7) {
|
|
|
43740
43892
|
}
|
|
43741
43893
|
};
|
|
43742
43894
|
}
|
|
43743
|
-
await
|
|
43744
|
-
await
|
|
43895
|
+
await fs27.writeFile(skillMdPath, rewriteResult.content, "utf-8");
|
|
43896
|
+
await fs27.rename(renameTarget, destPath);
|
|
43745
43897
|
} else {
|
|
43746
|
-
await
|
|
43898
|
+
await fs27.rename(renameTarget, destPath);
|
|
43747
43899
|
}
|
|
43748
43900
|
} catch (err) {
|
|
43749
43901
|
return {
|
|
@@ -43751,7 +43903,7 @@ async function applyRename(input7) {
|
|
|
43751
43903
|
collisionId: suggestion.collisionId,
|
|
43752
43904
|
appliedAction: action,
|
|
43753
43905
|
appliedRequest: "apply",
|
|
43754
|
-
fromPath:
|
|
43906
|
+
fromPath: renameTarget,
|
|
43755
43907
|
toPath: destPath,
|
|
43756
43908
|
backupPath,
|
|
43757
43909
|
ledgerEntryId: "",
|
|
@@ -43764,9 +43916,10 @@ async function applyRename(input7) {
|
|
|
43764
43916
|
kind,
|
|
43765
43917
|
originalIdentifier: suggestion.currentName,
|
|
43766
43918
|
renamedTo: newName,
|
|
43767
|
-
originalPath:
|
|
43919
|
+
originalPath: renameTarget,
|
|
43768
43920
|
renamedPath: destPath,
|
|
43769
43921
|
auditId,
|
|
43922
|
+
collisionId: suggestion.collisionId,
|
|
43770
43923
|
reason: suggestion.reason
|
|
43771
43924
|
});
|
|
43772
43925
|
if (updated !== ledger) {
|
|
@@ -43782,132 +43935,16 @@ async function applyRename(input7) {
|
|
|
43782
43935
|
collisionId: suggestion.collisionId,
|
|
43783
43936
|
appliedAction: action,
|
|
43784
43937
|
appliedRequest: "apply",
|
|
43785
|
-
fromPath:
|
|
43938
|
+
fromPath: renameTarget,
|
|
43786
43939
|
toPath: destPath,
|
|
43787
43940
|
backupPath,
|
|
43788
43941
|
ledgerEntryId: newEntry?.id ?? "",
|
|
43789
|
-
summary: buildSummary(suggestion.currentName, newName, auditId, "apply")
|
|
43790
|
-
};
|
|
43791
|
-
}
|
|
43792
|
-
async function revertRename(suggestion, auditId) {
|
|
43793
|
-
const ledger = await readLedger();
|
|
43794
|
-
const entry = ledger.overrides.find((o) => o.auditId === auditId);
|
|
43795
|
-
if (!entry) {
|
|
43796
|
-
return {
|
|
43797
|
-
success: true,
|
|
43798
|
-
collisionId: suggestion.collisionId,
|
|
43799
|
-
appliedAction: suggestion.applyAction,
|
|
43800
|
-
appliedRequest: "revert",
|
|
43801
|
-
fromPath: suggestion.entry.source_path,
|
|
43802
|
-
toPath: suggestion.entry.source_path,
|
|
43803
|
-
backupPath: "",
|
|
43804
|
-
ledgerEntryId: "",
|
|
43805
|
-
summary: buildSummary(suggestion.currentName, suggestion.currentName, auditId, "revert")
|
|
43806
|
-
};
|
|
43807
|
-
}
|
|
43808
|
-
const action = suggestion.applyAction;
|
|
43809
|
-
const onDisk = entry.renamedPath;
|
|
43810
|
-
const target = entry.originalPath;
|
|
43811
|
-
if (!await pathExists2(onDisk)) {
|
|
43812
|
-
return {
|
|
43813
|
-
success: false,
|
|
43814
|
-
collisionId: suggestion.collisionId,
|
|
43815
|
-
appliedAction: action,
|
|
43816
|
-
appliedRequest: "revert",
|
|
43817
|
-
fromPath: onDisk,
|
|
43818
|
-
toPath: target,
|
|
43819
|
-
backupPath: "",
|
|
43820
|
-
ledgerEntryId: entry.id,
|
|
43821
|
-
summary: "",
|
|
43822
|
-
error: {
|
|
43823
|
-
kind: "namespace.ledger.disk_divergence",
|
|
43824
|
-
ledgerRenamedTo: entry.renamedTo,
|
|
43825
|
-
onDisk,
|
|
43826
|
-
message: `revert source missing on disk: ${onDisk}`,
|
|
43827
|
-
remediationHint: "restore from ~/.claude/skills/.backups or remove the ledger entry manually"
|
|
43828
|
-
}
|
|
43829
|
-
};
|
|
43830
|
-
}
|
|
43831
|
-
if (target !== onDisk && await pathExists2(target)) {
|
|
43832
|
-
return {
|
|
43833
|
-
success: false,
|
|
43834
|
-
collisionId: suggestion.collisionId,
|
|
43835
|
-
appliedAction: action,
|
|
43836
|
-
appliedRequest: "revert",
|
|
43837
|
-
fromPath: onDisk,
|
|
43838
|
-
toPath: target,
|
|
43839
|
-
backupPath: "",
|
|
43840
|
-
ledgerEntryId: entry.id,
|
|
43841
|
-
summary: "",
|
|
43842
|
-
error: {
|
|
43843
|
-
kind: "namespace.rename.target_exists",
|
|
43844
|
-
target,
|
|
43845
|
-
message: `revert target already exists: ${target}`
|
|
43846
|
-
}
|
|
43847
|
-
};
|
|
43848
|
-
}
|
|
43849
|
-
try {
|
|
43850
|
-
if (action === "rename_skill_dir_and_frontmatter") {
|
|
43851
|
-
const skillMdPath = path21.join(onDisk, "SKILL.md");
|
|
43852
|
-
const current = await fs26.readFile(skillMdPath, "utf-8");
|
|
43853
|
-
const restored = rewriteFrontmatterName(current, entry.originalIdentifier);
|
|
43854
|
-
if (!restored.ok) {
|
|
43855
|
-
return {
|
|
43856
|
-
success: false,
|
|
43857
|
-
collisionId: suggestion.collisionId,
|
|
43858
|
-
appliedAction: action,
|
|
43859
|
-
appliedRequest: "revert",
|
|
43860
|
-
fromPath: onDisk,
|
|
43861
|
-
toPath: target,
|
|
43862
|
-
backupPath: "",
|
|
43863
|
-
ledgerEntryId: entry.id,
|
|
43864
|
-
summary: "",
|
|
43865
|
-
error: {
|
|
43866
|
-
kind: "namespace.rename.frontmatter_rewrite_failed",
|
|
43867
|
-
reason: restored.error.message,
|
|
43868
|
-
message: `revert frontmatter rewrite failed: ${restored.error.message}`
|
|
43869
|
-
}
|
|
43870
|
-
};
|
|
43871
|
-
}
|
|
43872
|
-
await fs26.writeFile(skillMdPath, restored.content, "utf-8");
|
|
43873
|
-
await fs26.rename(onDisk, target);
|
|
43874
|
-
} else {
|
|
43875
|
-
await fs26.rename(onDisk, target);
|
|
43876
|
-
}
|
|
43877
|
-
} catch (err) {
|
|
43878
|
-
return {
|
|
43879
|
-
success: false,
|
|
43880
|
-
collisionId: suggestion.collisionId,
|
|
43881
|
-
appliedAction: action,
|
|
43882
|
-
appliedRequest: "revert",
|
|
43883
|
-
fromPath: onDisk,
|
|
43884
|
-
toPath: target,
|
|
43885
|
-
backupPath: "",
|
|
43886
|
-
ledgerEntryId: entry.id,
|
|
43887
|
-
summary: "",
|
|
43888
|
-
error: fsErr(err.message)
|
|
43889
|
-
};
|
|
43890
|
-
}
|
|
43891
|
-
const filtered = {
|
|
43892
|
-
version: ledger.version,
|
|
43893
|
-
overrides: ledger.overrides.filter((o) => o.id !== entry.id)
|
|
43894
|
-
};
|
|
43895
|
-
await writeLedger(filtered);
|
|
43896
|
-
return {
|
|
43897
|
-
success: true,
|
|
43898
|
-
collisionId: suggestion.collisionId,
|
|
43899
|
-
appliedAction: action,
|
|
43900
|
-
appliedRequest: "revert",
|
|
43901
|
-
fromPath: onDisk,
|
|
43902
|
-
toPath: target,
|
|
43903
|
-
backupPath: "",
|
|
43904
|
-
ledgerEntryId: entry.id,
|
|
43905
|
-
summary: buildSummary(entry.renamedTo, entry.originalIdentifier, auditId, "revert")
|
|
43942
|
+
summary: buildSummary(suggestion.currentName, newName, auditId, suggestion.collisionId, "apply")
|
|
43906
43943
|
};
|
|
43907
43944
|
}
|
|
43908
43945
|
|
|
43909
43946
|
// ../mcp-server/dist/src/audit/edit-suggester.js
|
|
43910
|
-
import * as
|
|
43947
|
+
import * as fs28 from "node:fs/promises";
|
|
43911
43948
|
var ADD_DOMAIN_QUALIFIER = {
|
|
43912
43949
|
category: "description_overlap",
|
|
43913
43950
|
pattern: "add_domain_qualifier",
|
|
@@ -43977,7 +44014,7 @@ async function runEditSuggester(result, opts) {
|
|
|
43977
44014
|
const fileCache = /* @__PURE__ */ new Map();
|
|
43978
44015
|
await Promise.all(Array.from(uniquePaths).map(async (filePath) => {
|
|
43979
44016
|
try {
|
|
43980
|
-
const content = await
|
|
44017
|
+
const content = await fs28.readFile(filePath, "utf-8");
|
|
43981
44018
|
fileCache.set(filePath, content);
|
|
43982
44019
|
} catch (err) {
|
|
43983
44020
|
console.warn(`[edit-suggester] read failed for ${filePath} (${err.message}); skipping flags that target it`);
|
|
@@ -44091,7 +44128,7 @@ var MS_PER_DAY3 = 24 * 60 * 60 * 1e3;
|
|
|
44091
44128
|
import * as os14 from "node:os";
|
|
44092
44129
|
|
|
44093
44130
|
// ../core/dist/src/audit/exclusions.js
|
|
44094
|
-
import { promises as
|
|
44131
|
+
import { promises as fs29 } from "node:fs";
|
|
44095
44132
|
import { join as join56 } from "node:path";
|
|
44096
44133
|
var EXCLUSIONS_FILE = "audit-exclusions.json";
|
|
44097
44134
|
var EMPTY_CONFIG = { version: 1, exclusions: [] };
|
|
@@ -44099,13 +44136,13 @@ function getExclusionsPath(opts) {
|
|
|
44099
44136
|
return join56(opts?.configDir ?? getConfigDir(), EXCLUSIONS_FILE);
|
|
44100
44137
|
}
|
|
44101
44138
|
async function loadExclusions(opts = {}) {
|
|
44102
|
-
const
|
|
44139
|
+
const path24 = opts.configPath ?? getExclusionsPath();
|
|
44103
44140
|
let raw;
|
|
44104
44141
|
try {
|
|
44105
|
-
raw = await
|
|
44142
|
+
raw = await fs29.readFile(path24, "utf-8");
|
|
44106
44143
|
} catch (err) {
|
|
44107
44144
|
if (err.code !== "ENOENT") {
|
|
44108
|
-
console.warn(`[audit-exclusions] read failed for ${
|
|
44145
|
+
console.warn(`[audit-exclusions] read failed for ${path24}: ${err.message}`);
|
|
44109
44146
|
}
|
|
44110
44147
|
return EMPTY_CONFIG;
|
|
44111
44148
|
}
|
|
@@ -44113,11 +44150,11 @@ async function loadExclusions(opts = {}) {
|
|
|
44113
44150
|
try {
|
|
44114
44151
|
parsed = JSON.parse(raw);
|
|
44115
44152
|
} catch {
|
|
44116
|
-
console.warn(`[audit-exclusions] malformed JSON at ${
|
|
44153
|
+
console.warn(`[audit-exclusions] malformed JSON at ${path24} \u2014 ignoring file`);
|
|
44117
44154
|
return EMPTY_CONFIG;
|
|
44118
44155
|
}
|
|
44119
44156
|
if (!isExclusionsConfig(parsed)) {
|
|
44120
|
-
console.warn(`[audit-exclusions] unrecognized schema at ${
|
|
44157
|
+
console.warn(`[audit-exclusions] unrecognized schema at ${path24} (expected version: 1) \u2014 ignoring file`);
|
|
44121
44158
|
return EMPTY_CONFIG;
|
|
44122
44159
|
}
|
|
44123
44160
|
return parsed;
|
|
@@ -44168,30 +44205,30 @@ function tierAllowsAuditMode(tier, mode) {
|
|
|
44168
44205
|
}
|
|
44169
44206
|
|
|
44170
44207
|
// ../mcp-server/dist/src/audit/audit-suggestions.js
|
|
44171
|
-
import * as
|
|
44208
|
+
import * as fs30 from "node:fs/promises";
|
|
44172
44209
|
import * as os13 from "node:os";
|
|
44173
|
-
import * as
|
|
44174
|
-
var DEFAULT_AUDITS_DIR2 =
|
|
44210
|
+
import * as path23 from "node:path";
|
|
44211
|
+
var DEFAULT_AUDITS_DIR2 = path23.join(os13.homedir(), ".skillsmith", "audits");
|
|
44175
44212
|
async function writeAuditSuggestions(auditId, renameSuggestions, recommendedEdits, opts = {}) {
|
|
44176
44213
|
const auditsDir = opts.auditsDir ?? DEFAULT_AUDITS_DIR2;
|
|
44177
|
-
const auditDir =
|
|
44178
|
-
const suggestionsPath =
|
|
44214
|
+
const auditDir = path23.join(auditsDir, auditId);
|
|
44215
|
+
const suggestionsPath = path23.join(auditDir, "suggestions.json");
|
|
44179
44216
|
const tmpPath = `${suggestionsPath}.tmp`;
|
|
44180
|
-
await
|
|
44217
|
+
await fs30.mkdir(auditDir, { recursive: true });
|
|
44181
44218
|
const payload = {
|
|
44182
44219
|
version: 1,
|
|
44183
44220
|
auditId,
|
|
44184
44221
|
renameSuggestions: [...renameSuggestions],
|
|
44185
44222
|
recommendedEdits: [...recommendedEdits]
|
|
44186
44223
|
};
|
|
44187
|
-
await
|
|
44188
|
-
await
|
|
44224
|
+
await fs30.writeFile(tmpPath, JSON.stringify(payload, null, 2), "utf-8");
|
|
44225
|
+
await fs30.rename(tmpPath, suggestionsPath);
|
|
44189
44226
|
return { suggestionsPath };
|
|
44190
44227
|
}
|
|
44191
44228
|
|
|
44192
44229
|
// ../mcp-server/dist/src/audit/rot-detector.js
|
|
44193
44230
|
import * as crypto9 from "node:crypto";
|
|
44194
|
-
import * as
|
|
44231
|
+
import * as fs31 from "node:fs/promises";
|
|
44195
44232
|
var SCANNABLE_KINDS2 = /* @__PURE__ */ new Set(["skill", "command", "agent"]);
|
|
44196
44233
|
var DEAD_LINK_PATTERNS = [
|
|
44197
44234
|
/\]\(\s*<?https?:\/\/(www\.)?example\.(com|org|net)\b[^)]*\)/i,
|
|
@@ -44242,7 +44279,7 @@ async function detectVersionDrift(inventory, opts) {
|
|
|
44242
44279
|
}
|
|
44243
44280
|
async function readEntryContent(sourcePath) {
|
|
44244
44281
|
try {
|
|
44245
|
-
return await
|
|
44282
|
+
return await fs31.readFile(sourcePath, "utf-8");
|
|
44246
44283
|
} catch {
|
|
44247
44284
|
return null;
|
|
44248
44285
|
}
|
|
@@ -44282,7 +44319,7 @@ function deriveRotId(auditId, entry, signal) {
|
|
|
44282
44319
|
|
|
44283
44320
|
// ../mcp-server/dist/src/audit/run-inventory-audit.detectors.js
|
|
44284
44321
|
import * as crypto10 from "node:crypto";
|
|
44285
|
-
import * as
|
|
44322
|
+
import * as fs32 from "node:fs";
|
|
44286
44323
|
function buildRenameSuggestions(result, fullInventory) {
|
|
44287
44324
|
const suggestions = [];
|
|
44288
44325
|
for (const flag of result.exactCollisions) {
|
|
@@ -44366,7 +44403,7 @@ function isAgentPackSelfCollision(flag) {
|
|
|
44366
44403
|
}
|
|
44367
44404
|
function hashFileContent(filePath) {
|
|
44368
44405
|
try {
|
|
44369
|
-
const content =
|
|
44406
|
+
const content = fs32.readFileSync(filePath);
|
|
44370
44407
|
return crypto10.createHash("sha256").update(content).digest("hex");
|
|
44371
44408
|
} catch {
|
|
44372
44409
|
return null;
|
|
@@ -44565,13 +44602,13 @@ function backupsDir() {
|
|
|
44565
44602
|
}
|
|
44566
44603
|
function backupLedgerForReset() {
|
|
44567
44604
|
const src = ledgerPath();
|
|
44568
|
-
if (!
|
|
44605
|
+
if (!fs33.existsSync(src)) return null;
|
|
44569
44606
|
const dir = backupsDir();
|
|
44570
|
-
|
|
44607
|
+
fs33.mkdirSync(dir, { recursive: true, mode: 448 });
|
|
44571
44608
|
const ts2 = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
44572
44609
|
const suffix = crypto11.randomBytes(4).toString("hex");
|
|
44573
44610
|
const backupFile = join58(dir, `ledger-${ts2}-${suffix}.json`);
|
|
44574
|
-
|
|
44611
|
+
fs33.copyFileSync(src, backupFile);
|
|
44575
44612
|
return backupFile;
|
|
44576
44613
|
}
|
|
44577
44614
|
async function runResetLedger() {
|
|
@@ -45318,7 +45355,7 @@ var auditAction = withTelemetry(auditActionImpl, {
|
|
|
45318
45355
|
import { Command as Command22 } from "commander";
|
|
45319
45356
|
import { input as input6, confirm as confirm6, select as select4 } from "@inquirer/prompts";
|
|
45320
45357
|
import ora12 from "ora";
|
|
45321
|
-
import { mkdir as mkdir17, writeFile as
|
|
45358
|
+
import { mkdir as mkdir17, writeFile as writeFile15, stat as stat12 } from "fs/promises";
|
|
45322
45359
|
import { join as join59 } from "path";
|
|
45323
45360
|
var logger29 = getCliLogger();
|
|
45324
45361
|
var VALID_TYPES = ["basic", "intermediate", "advanced"];
|
|
@@ -45533,12 +45570,12 @@ Thumbs.db
|
|
|
45533
45570
|
if (includeScripts) {
|
|
45534
45571
|
await mkdir17(join59(skillDir, "scripts"), { recursive: true });
|
|
45535
45572
|
}
|
|
45536
|
-
await
|
|
45537
|
-
await
|
|
45538
|
-
await
|
|
45539
|
-
await
|
|
45573
|
+
await writeFile15(join59(skillDir, "SKILL.md"), skillMdContent, "utf-8");
|
|
45574
|
+
await writeFile15(join59(skillDir, "README.md"), readmeContent, "utf-8");
|
|
45575
|
+
await writeFile15(join59(skillDir, "CHANGELOG.md"), changelogContent, "utf-8");
|
|
45576
|
+
await writeFile15(join59(skillDir, ".gitignore"), gitignoreContent, "utf-8");
|
|
45540
45577
|
if (includeScripts) {
|
|
45541
|
-
await
|
|
45578
|
+
await writeFile15(join59(skillDir, "scripts", "example.js"), scriptContent, "utf-8");
|
|
45542
45579
|
}
|
|
45543
45580
|
spinner.succeed(`Skill scaffolded at ${skillDir}`);
|
|
45544
45581
|
} catch (error46) {
|
|
@@ -45912,12 +45949,12 @@ function createImportCommand() {
|
|
|
45912
45949
|
// src/commands/import-local.ts
|
|
45913
45950
|
import { Command as Command25 } from "commander";
|
|
45914
45951
|
import { resolve as resolve16 } from "node:path";
|
|
45915
|
-
import { promises as
|
|
45952
|
+
import { promises as fs35 } from "node:fs";
|
|
45916
45953
|
|
|
45917
45954
|
// src/commands/import-local.helpers.ts
|
|
45918
45955
|
import { createHash as createHash17 } from "node:crypto";
|
|
45919
|
-
import { promises as
|
|
45920
|
-
import { join as join60, resolve as resolve15, dirname as dirname25, basename as
|
|
45956
|
+
import { promises as fs34 } from "node:fs";
|
|
45957
|
+
import { join as join60, resolve as resolve15, dirname as dirname25, basename as basename8, sep as sep4, relative as relative6 } from "node:path";
|
|
45921
45958
|
import matter from "gray-matter";
|
|
45922
45959
|
var SKILL_FILENAME = "SKILL.md";
|
|
45923
45960
|
var MAX_DEPTH = 8;
|
|
@@ -45925,7 +45962,7 @@ function localSkillId(canonicalPath) {
|
|
|
45925
45962
|
return createHash17("sha256").update(canonicalPath).digest("hex").slice(0, 32);
|
|
45926
45963
|
}
|
|
45927
45964
|
async function walkSkillFiles(rootDir) {
|
|
45928
|
-
const canonicalRoot = await
|
|
45965
|
+
const canonicalRoot = await fs34.realpath(rootDir).catch(() => resolve15(rootDir));
|
|
45929
45966
|
const files = [];
|
|
45930
45967
|
const skipped = [];
|
|
45931
45968
|
const visited = /* @__PURE__ */ new Set();
|
|
@@ -45933,7 +45970,7 @@ async function walkSkillFiles(rootDir) {
|
|
|
45933
45970
|
if (depth > MAX_DEPTH) return;
|
|
45934
45971
|
let entries;
|
|
45935
45972
|
try {
|
|
45936
|
-
entries = await
|
|
45973
|
+
entries = await fs34.readdir(dir, { withFileTypes: true });
|
|
45937
45974
|
} catch {
|
|
45938
45975
|
return;
|
|
45939
45976
|
}
|
|
@@ -45942,7 +45979,7 @@ async function walkSkillFiles(rootDir) {
|
|
|
45942
45979
|
if (entry.isSymbolicLink()) {
|
|
45943
45980
|
let realPath;
|
|
45944
45981
|
try {
|
|
45945
|
-
realPath = await
|
|
45982
|
+
realPath = await fs34.realpath(entryPath);
|
|
45946
45983
|
} catch {
|
|
45947
45984
|
continue;
|
|
45948
45985
|
}
|
|
@@ -45953,10 +45990,10 @@ async function walkSkillFiles(rootDir) {
|
|
|
45953
45990
|
}
|
|
45954
45991
|
if (visited.has(realPath)) continue;
|
|
45955
45992
|
visited.add(realPath);
|
|
45956
|
-
const stat13 = await
|
|
45993
|
+
const stat13 = await fs34.stat(realPath).catch(() => null);
|
|
45957
45994
|
if (stat13?.isDirectory()) {
|
|
45958
45995
|
await walk(realPath, depth + 1);
|
|
45959
|
-
} else if (stat13?.isFile() &&
|
|
45996
|
+
} else if (stat13?.isFile() && basename8(realPath) === SKILL_FILENAME) {
|
|
45960
45997
|
files.push(realPath);
|
|
45961
45998
|
}
|
|
45962
45999
|
continue;
|
|
@@ -45966,7 +46003,7 @@ async function walkSkillFiles(rootDir) {
|
|
|
45966
46003
|
await walk(entryPath, depth + 1);
|
|
45967
46004
|
} else if (entry.isFile() && entry.name === SKILL_FILENAME) {
|
|
45968
46005
|
try {
|
|
45969
|
-
const real = await
|
|
46006
|
+
const real = await fs34.realpath(entryPath);
|
|
45970
46007
|
files.push(real);
|
|
45971
46008
|
} catch {
|
|
45972
46009
|
files.push(entryPath);
|
|
@@ -45979,10 +46016,10 @@ async function walkSkillFiles(rootDir) {
|
|
|
45979
46016
|
}
|
|
45980
46017
|
async function parseSkillFile(filePath) {
|
|
45981
46018
|
const id = localSkillId(filePath);
|
|
45982
|
-
const fallbackName =
|
|
46019
|
+
const fallbackName = basename8(dirname25(filePath));
|
|
45983
46020
|
let content;
|
|
45984
46021
|
try {
|
|
45985
|
-
content = await
|
|
46022
|
+
content = await fs34.readFile(filePath, "utf8");
|
|
45986
46023
|
} catch (error46) {
|
|
45987
46024
|
return {
|
|
45988
46025
|
id,
|
|
@@ -46058,7 +46095,7 @@ async function runImportLocal(opts) {
|
|
|
46058
46095
|
dryRun: !!opts.dryRun
|
|
46059
46096
|
};
|
|
46060
46097
|
try {
|
|
46061
|
-
const stat13 = await
|
|
46098
|
+
const stat13 = await fs35.stat(rootDir);
|
|
46062
46099
|
if (!stat13.isDirectory()) {
|
|
46063
46100
|
result.errors.push({ path: rootDir, message: "not-a-directory" });
|
|
46064
46101
|
result.durationMs = Date.now() - start;
|
|
@@ -46175,14 +46212,14 @@ async function startWatchMode(opts, jsonOutput) {
|
|
|
46175
46212
|
watcher.on("unlink", (p) => onEvent("unlink", p));
|
|
46176
46213
|
console.log(`[import-local] watching ${rootDir} (Ctrl-C to stop)`);
|
|
46177
46214
|
}
|
|
46178
|
-
async function importLocalActionImpl(
|
|
46215
|
+
async function importLocalActionImpl(path24, cliOptions) {
|
|
46179
46216
|
try {
|
|
46180
46217
|
let resolvedClient;
|
|
46181
46218
|
if (cliOptions.client !== void 0) {
|
|
46182
46219
|
resolvedClient = resolveClientId(cliOptions.client);
|
|
46183
46220
|
}
|
|
46184
46221
|
const opts = {
|
|
46185
|
-
...
|
|
46222
|
+
...path24 !== void 0 && { path: path24 },
|
|
46186
46223
|
...resolvedClient !== void 0 && { client: resolvedClient },
|
|
46187
46224
|
...cliOptions.watch !== void 0 && { watch: cliOptions.watch },
|
|
46188
46225
|
...cliOptions.dryRun !== void 0 && { dryRun: cliOptions.dryRun },
|
|
@@ -46245,7 +46282,7 @@ function printHumanSummary(result) {
|
|
|
46245
46282
|
|
|
46246
46283
|
// src/commands/config.ts
|
|
46247
46284
|
import * as crypto12 from "node:crypto";
|
|
46248
|
-
import * as
|
|
46285
|
+
import * as fs36 from "node:fs";
|
|
46249
46286
|
import { homedir as homedir30 } from "node:os";
|
|
46250
46287
|
import { join as join61, dirname as dirname26 } from "node:path";
|
|
46251
46288
|
import { Command as Command26 } from "commander";
|
|
@@ -46274,10 +46311,10 @@ function configPath() {
|
|
|
46274
46311
|
return join61(homedir30(), CONFIG_DIR3, CONFIG_FILE3);
|
|
46275
46312
|
}
|
|
46276
46313
|
function readConfigFile2() {
|
|
46277
|
-
const
|
|
46278
|
-
if (!
|
|
46314
|
+
const path24 = configPath();
|
|
46315
|
+
if (!fs36.existsSync(path24)) return {};
|
|
46279
46316
|
try {
|
|
46280
|
-
const raw =
|
|
46317
|
+
const raw = fs36.readFileSync(path24, "utf-8");
|
|
46281
46318
|
const parsed = JSON.parse(raw);
|
|
46282
46319
|
if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) return {};
|
|
46283
46320
|
return parsed;
|
|
@@ -46286,16 +46323,16 @@ function readConfigFile2() {
|
|
|
46286
46323
|
}
|
|
46287
46324
|
}
|
|
46288
46325
|
function writeConfigFileAtomic(config2) {
|
|
46289
|
-
const
|
|
46290
|
-
const dir = dirname26(
|
|
46291
|
-
|
|
46326
|
+
const path24 = configPath();
|
|
46327
|
+
const dir = dirname26(path24);
|
|
46328
|
+
fs36.mkdirSync(dir, { recursive: true, mode: 448 });
|
|
46292
46329
|
const tmpSuffix = crypto12.randomBytes(6).toString("hex");
|
|
46293
|
-
const tmpPath = `${
|
|
46330
|
+
const tmpPath = `${path24}.${tmpSuffix}.tmp`;
|
|
46294
46331
|
const json2 = JSON.stringify(config2, null, 2);
|
|
46295
|
-
|
|
46296
|
-
|
|
46332
|
+
fs36.writeFileSync(tmpPath, json2, { encoding: "utf-8", mode: 384 });
|
|
46333
|
+
fs36.renameSync(tmpPath, path24);
|
|
46297
46334
|
try {
|
|
46298
|
-
|
|
46335
|
+
fs36.chmodSync(path24, 384);
|
|
46299
46336
|
} catch {
|
|
46300
46337
|
}
|
|
46301
46338
|
}
|
|
@@ -46395,7 +46432,7 @@ import { readdirSync as readdirSync4, unlinkSync as unlinkSync3, statSync as sta
|
|
|
46395
46432
|
|
|
46396
46433
|
// src/commands/telemetry.helpers.ts
|
|
46397
46434
|
import * as crypto13 from "node:crypto";
|
|
46398
|
-
import * as
|
|
46435
|
+
import * as fs37 from "node:fs";
|
|
46399
46436
|
import { join as join62, dirname as dirname27 } from "node:path";
|
|
46400
46437
|
import { homedir as homedir31 } from "node:os";
|
|
46401
46438
|
var TelemetryHookError = class extends Error {
|
|
@@ -46413,10 +46450,10 @@ function resolveSettingsPath(scope) {
|
|
|
46413
46450
|
return join62(process.cwd(), ".claude", "settings.json");
|
|
46414
46451
|
}
|
|
46415
46452
|
function loadClaudeSettings(scope) {
|
|
46416
|
-
const
|
|
46417
|
-
if (!
|
|
46453
|
+
const path24 = resolveSettingsPath(scope);
|
|
46454
|
+
if (!fs37.existsSync(path24)) return {};
|
|
46418
46455
|
try {
|
|
46419
|
-
const raw =
|
|
46456
|
+
const raw = fs37.readFileSync(path24, "utf-8");
|
|
46420
46457
|
const parsed = JSON.parse(raw);
|
|
46421
46458
|
if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) return {};
|
|
46422
46459
|
return parsed;
|
|
@@ -46482,16 +46519,16 @@ function removeSkillHookEntries(settings, hookPath) {
|
|
|
46482
46519
|
return { ...settings, hooks };
|
|
46483
46520
|
}
|
|
46484
46521
|
function writeClaudeSettings(scope, settings) {
|
|
46485
|
-
const
|
|
46486
|
-
const dir = dirname27(
|
|
46487
|
-
|
|
46522
|
+
const path24 = resolveSettingsPath(scope);
|
|
46523
|
+
const dir = dirname27(path24);
|
|
46524
|
+
fs37.mkdirSync(dir, { recursive: true, mode: 448 });
|
|
46488
46525
|
const tmpSuffix = crypto13.randomBytes(6).toString("hex");
|
|
46489
|
-
const tmpPath = `${
|
|
46526
|
+
const tmpPath = `${path24}.${tmpSuffix}.tmp`;
|
|
46490
46527
|
const json2 = JSON.stringify(settings, null, 2);
|
|
46491
|
-
|
|
46492
|
-
|
|
46528
|
+
fs37.writeFileSync(tmpPath, json2, { encoding: "utf-8", mode: 384 });
|
|
46529
|
+
fs37.renameSync(tmpPath, path24);
|
|
46493
46530
|
try {
|
|
46494
|
-
|
|
46531
|
+
fs37.chmodSync(path24, 384);
|
|
46495
46532
|
} catch {
|
|
46496
46533
|
}
|
|
46497
46534
|
}
|
|
@@ -47082,7 +47119,7 @@ function createAgentCommand() {
|
|
|
47082
47119
|
|
|
47083
47120
|
// src/commands/diagnose.ts
|
|
47084
47121
|
import { mkdirSync as mkdirSync14, readFileSync as readFileSync25, writeFileSync as writeFileSync15 } from "node:fs";
|
|
47085
|
-
import { basename as
|
|
47122
|
+
import { basename as basename9, dirname as dirname29, resolve as resolve17 } from "node:path";
|
|
47086
47123
|
import { Command as Command30 } from "commander";
|
|
47087
47124
|
|
|
47088
47125
|
// src/commands/log-records.helpers.ts
|
|
@@ -47218,7 +47255,7 @@ function buildBundleContent(summary, files) {
|
|
|
47218
47255
|
} else {
|
|
47219
47256
|
for (const file2 of files) {
|
|
47220
47257
|
parts.push("");
|
|
47221
|
-
parts.push(`===== ${
|
|
47258
|
+
parts.push(`===== ${basename9(file2)} (${fileSizeBytes(file2)} bytes) =====`);
|
|
47222
47259
|
try {
|
|
47223
47260
|
parts.push(readFileSync25(file2, "utf8"));
|
|
47224
47261
|
} catch (error46) {
|
|
@@ -47333,18 +47370,18 @@ async function startTail(dir, level, opts = {}) {
|
|
|
47333
47370
|
const paths = todaysFilePaths(dir);
|
|
47334
47371
|
const offsets = /* @__PURE__ */ new Map();
|
|
47335
47372
|
let printedAny = false;
|
|
47336
|
-
for (const
|
|
47337
|
-
if (!existsSync29(
|
|
47338
|
-
offsets.set(
|
|
47373
|
+
for (const path24 of paths) {
|
|
47374
|
+
if (!existsSync29(path24)) {
|
|
47375
|
+
offsets.set(path24, 0);
|
|
47339
47376
|
continue;
|
|
47340
47377
|
}
|
|
47341
|
-
let records = readLogRecords(
|
|
47378
|
+
let records = readLogRecords(path24);
|
|
47342
47379
|
if (level) records = filterByMinLevel(records, level);
|
|
47343
47380
|
if (records.length > 0) {
|
|
47344
47381
|
printRecords(sortByTsAsc(records));
|
|
47345
47382
|
printedAny = true;
|
|
47346
47383
|
}
|
|
47347
|
-
offsets.set(
|
|
47384
|
+
offsets.set(path24, statSync8(path24).size);
|
|
47348
47385
|
}
|
|
47349
47386
|
if (!printedAny) {
|
|
47350
47387
|
console.log(noLogsFoundMessage(dir));
|
|
@@ -47359,25 +47396,25 @@ async function startTail(dir, level, opts = {}) {
|
|
|
47359
47396
|
await new Promise((resolve18) => {
|
|
47360
47397
|
watcher.once("ready", resolve18);
|
|
47361
47398
|
});
|
|
47362
|
-
const handleEvent = (
|
|
47399
|
+
const handleEvent = (path24) => {
|
|
47363
47400
|
let size;
|
|
47364
47401
|
try {
|
|
47365
|
-
size = statSync8(
|
|
47402
|
+
size = statSync8(path24).size;
|
|
47366
47403
|
} catch {
|
|
47367
47404
|
return;
|
|
47368
47405
|
}
|
|
47369
|
-
const previousOffset = offsets.get(
|
|
47406
|
+
const previousOffset = offsets.get(path24) ?? 0;
|
|
47370
47407
|
if (size <= previousOffset) {
|
|
47371
|
-
offsets.set(
|
|
47408
|
+
offsets.set(path24, size);
|
|
47372
47409
|
return;
|
|
47373
47410
|
}
|
|
47374
47411
|
let content;
|
|
47375
47412
|
try {
|
|
47376
|
-
content = readFileSync26(
|
|
47413
|
+
content = readFileSync26(path24).subarray(previousOffset).toString("utf8");
|
|
47377
47414
|
} catch {
|
|
47378
47415
|
return;
|
|
47379
47416
|
}
|
|
47380
|
-
offsets.set(
|
|
47417
|
+
offsets.set(path24, size);
|
|
47381
47418
|
for (const line of content.split("\n")) {
|
|
47382
47419
|
const trimmed = line.trim();
|
|
47383
47420
|
if (!trimmed) continue;
|
|
@@ -47534,8 +47571,8 @@ var program = new Command32();
|
|
|
47534
47571
|
var commandName = process.argv[1]?.endsWith("sklx") ? "sklx" : "skillsmith";
|
|
47535
47572
|
program.name(commandName).description("Agent Skill Discovery and Management CLI (alias: sklx)").version(CLI_VERSION);
|
|
47536
47573
|
program.hook("preAction", async (_thisCommand, actionCommand) => {
|
|
47537
|
-
const
|
|
47538
|
-
if (!shouldShowStartupHeader(
|
|
47574
|
+
const path24 = resolveCommandPath(actionCommand.name(), actionCommand.parent?.name(), commandName);
|
|
47575
|
+
if (!shouldShowStartupHeader(path24, Boolean(process.stdout.isTTY))) return;
|
|
47539
47576
|
await displayStartupHeader(CLI_VERSION);
|
|
47540
47577
|
});
|
|
47541
47578
|
program.addCommand(createImportCommand());
|