@chiendt/ack-cli 1.3.0-dev.2 → 1.3.0-dev.4
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/cli-manifest.json +2 -2
- package/dist/index.js +140 -99
- package/package.json +1 -1
package/cli-manifest.json
CHANGED
package/dist/index.js
CHANGED
|
@@ -51018,8 +51018,16 @@ import { existsSync as existsSync18 } from "node:fs";
|
|
|
51018
51018
|
import { readFile as readFile14, readdir as readdir10, stat as stat6 } from "node:fs/promises";
|
|
51019
51019
|
import { homedir as homedir18 } from "node:os";
|
|
51020
51020
|
import { join as join33 } from "node:path";
|
|
51021
|
-
|
|
51022
|
-
|
|
51021
|
+
function resolveSkillsDir(projectPath) {
|
|
51022
|
+
return projectPath ? join33(projectPath, ".claude", "skills") : globalSkillsDir;
|
|
51023
|
+
}
|
|
51024
|
+
function resolveMetadataPath(scope, projectPath) {
|
|
51025
|
+
if (scope === "global")
|
|
51026
|
+
return join33(homedir18(), ".claude", "metadata.json");
|
|
51027
|
+
return join33(projectPath ?? process.cwd(), ".claude", "metadata.json");
|
|
51028
|
+
}
|
|
51029
|
+
async function getCkSkillMetadata(scope, projectPath) {
|
|
51030
|
+
const metaPath = resolveMetadataPath(scope, projectPath);
|
|
51023
51031
|
if (!existsSync18(metaPath))
|
|
51024
51032
|
return null;
|
|
51025
51033
|
const result = new Map;
|
|
@@ -51087,15 +51095,13 @@ function inferCategory(name, metadata) {
|
|
|
51087
51095
|
return "ai-ml";
|
|
51088
51096
|
return "other";
|
|
51089
51097
|
}
|
|
51090
|
-
async function scanSkills() {
|
|
51098
|
+
async function scanSkills(projectPath) {
|
|
51099
|
+
const skillsDir = resolveSkillsDir(projectPath);
|
|
51091
51100
|
if (!existsSync18(skillsDir))
|
|
51092
51101
|
return [];
|
|
51093
51102
|
try {
|
|
51094
51103
|
const entries = await readdir10(skillsDir);
|
|
51095
|
-
const [globalMeta, projectMeta] = await Promise.all([
|
|
51096
|
-
getCkSkillMetadata("global"),
|
|
51097
|
-
getCkSkillMetadata("project")
|
|
51098
|
-
]);
|
|
51104
|
+
const [globalMeta, projectMeta] = projectPath ? [null, await getCkSkillMetadata("project", projectPath)] : await Promise.all([getCkSkillMetadata("global"), getCkSkillMetadata("project")]);
|
|
51099
51105
|
const ckMeta = globalMeta ?? projectMeta;
|
|
51100
51106
|
const skills = [];
|
|
51101
51107
|
for (const entry of entries) {
|
|
@@ -51146,10 +51152,10 @@ async function scanSkills() {
|
|
|
51146
51152
|
return [];
|
|
51147
51153
|
}
|
|
51148
51154
|
}
|
|
51149
|
-
var import_gray_matter4,
|
|
51155
|
+
var import_gray_matter4, globalSkillsDir, SKIP_DIRS2;
|
|
51150
51156
|
var init_skill_scanner = __esm(() => {
|
|
51151
51157
|
import_gray_matter4 = __toESM(require_gray_matter(), 1);
|
|
51152
|
-
|
|
51158
|
+
globalSkillsDir = join33(homedir18(), ".claude", "skills");
|
|
51153
51159
|
SKIP_DIRS2 = [".venv", "scripts", "__pycache__", "node_modules", ".git", "common"];
|
|
51154
51160
|
});
|
|
51155
51161
|
|
|
@@ -51158,11 +51164,13 @@ import { existsSync as existsSync19 } from "node:fs";
|
|
|
51158
51164
|
import { copyFile as copyFile2, mkdir as mkdir9, readFile as readFile15, rename as rename5, rm as rm4, writeFile as writeFile9 } from "node:fs/promises";
|
|
51159
51165
|
import { homedir as homedir19 } from "node:os";
|
|
51160
51166
|
import { join as join34 } from "node:path";
|
|
51161
|
-
function getSettingsPath() {
|
|
51167
|
+
function getSettingsPath(projectPath) {
|
|
51168
|
+
if (projectPath)
|
|
51169
|
+
return join34(projectPath, ".claude", settingsFilename);
|
|
51162
51170
|
return join34(claudeDir, settingsFilename);
|
|
51163
51171
|
}
|
|
51164
|
-
async function readSettings() {
|
|
51165
|
-
const settingsPath = getSettingsPath();
|
|
51172
|
+
async function readSettings(projectPath) {
|
|
51173
|
+
const settingsPath = getSettingsPath(projectPath);
|
|
51166
51174
|
try {
|
|
51167
51175
|
if (!existsSync19(settingsPath))
|
|
51168
51176
|
return null;
|
|
@@ -51634,14 +51642,14 @@ async function countMdFilesRecursive(dir, depth = 0) {
|
|
|
51634
51642
|
}
|
|
51635
51643
|
}
|
|
51636
51644
|
async function countSkills2() {
|
|
51637
|
-
const
|
|
51638
|
-
if (!existsSync20(
|
|
51645
|
+
const skillsDir = join38(claudeDir2, "skills");
|
|
51646
|
+
if (!existsSync20(skillsDir))
|
|
51639
51647
|
return 0;
|
|
51640
51648
|
try {
|
|
51641
|
-
const entries = await readdir11(
|
|
51649
|
+
const entries = await readdir11(skillsDir);
|
|
51642
51650
|
let count = 0;
|
|
51643
51651
|
for (const entry of entries) {
|
|
51644
|
-
if (existsSync20(join38(
|
|
51652
|
+
if (existsSync20(join38(skillsDir, entry, "SKILL.md")))
|
|
51645
51653
|
count++;
|
|
51646
51654
|
}
|
|
51647
51655
|
return count;
|
|
@@ -61065,6 +61073,32 @@ import { existsSync as existsSync37 } from "node:fs";
|
|
|
61065
61073
|
import { readFile as readFile27 } from "node:fs/promises";
|
|
61066
61074
|
import { homedir as homedir32 } from "node:os";
|
|
61067
61075
|
import { basename as basename21, join as join55, resolve as resolve28 } from "node:path";
|
|
61076
|
+
async function countProjectMcpJsonServers(projectPath) {
|
|
61077
|
+
const filePath = join55(projectPath, ".mcp.json");
|
|
61078
|
+
if (!existsSync37(filePath))
|
|
61079
|
+
return 0;
|
|
61080
|
+
try {
|
|
61081
|
+
const content = await readFile27(filePath, "utf-8");
|
|
61082
|
+
const parsed = JSON.parse(content);
|
|
61083
|
+
const servers = parsed.mcpServers && typeof parsed.mcpServers === "object" && !Array.isArray(parsed.mcpServers) ? parsed.mcpServers : parsed;
|
|
61084
|
+
return Object.keys(servers).filter((k2) => k2 !== "mcpServers").length;
|
|
61085
|
+
} catch {
|
|
61086
|
+
return 0;
|
|
61087
|
+
}
|
|
61088
|
+
}
|
|
61089
|
+
function resolveKitInfo(metadata) {
|
|
61090
|
+
const kitsMap = metadata.kits ?? null;
|
|
61091
|
+
if (kitsMap && typeof kitsMap === "object") {
|
|
61092
|
+
const kits2 = Object.entries(kitsMap).map(([kit, info]) => ({ kit, version: (info?.version ?? "").toString() })).filter(({ version }) => version.trim() !== "");
|
|
61093
|
+
if (kits2.length > 0) {
|
|
61094
|
+
return { primaryKit: kits2[0].kit, primaryVersion: kits2[0].version, kits: kits2 };
|
|
61095
|
+
}
|
|
61096
|
+
}
|
|
61097
|
+
const legacyKit = typeof metadata.kit === "string" ? metadata.kit : null;
|
|
61098
|
+
const legacyVersion = typeof metadata.version === "string" ? metadata.version : null;
|
|
61099
|
+
const kits = legacyKit && legacyVersion ? [{ kit: legacyKit, version: legacyVersion }] : [];
|
|
61100
|
+
return { primaryKit: legacyKit, primaryVersion: legacyVersion, kits };
|
|
61101
|
+
}
|
|
61068
61102
|
function registerProjectRoutes(app) {
|
|
61069
61103
|
app.get("/api/projects", async (req, res) => {
|
|
61070
61104
|
try {
|
|
@@ -61312,23 +61346,26 @@ async function buildProjectInfoFromRegistry(registered, cachedSettings, cachedSk
|
|
|
61312
61346
|
}
|
|
61313
61347
|
} catch {}
|
|
61314
61348
|
const hasLocalConfig = hasClaudeDir && CkConfigManager.projectConfigExists(registered.path, false);
|
|
61315
|
-
const settings =
|
|
61316
|
-
const skills =
|
|
61349
|
+
const settings = hasClaudeDir ? await readSettings(registered.path) : null;
|
|
61350
|
+
const skills = hasClaudeDir ? await scanSkills(registered.path) : [];
|
|
61317
61351
|
const settingsPath = join55(homedir32(), ".claude", "settings.json");
|
|
61318
61352
|
const health = existsSync37(settingsPath) ? "healthy" : "warning";
|
|
61319
61353
|
const model = getCurrentModel() || settings?.model || "claude-sonnet-4";
|
|
61320
61354
|
const planData = includePlanData ? await buildProjectPlanData(registered.path, "project") : null;
|
|
61355
|
+
const kitInfo = resolveKitInfo(metadata);
|
|
61356
|
+
const projectMcpJsonCount = await countProjectMcpJsonServers(registered.path);
|
|
61321
61357
|
return {
|
|
61322
61358
|
id: registered.id,
|
|
61323
61359
|
name: registered.alias,
|
|
61324
61360
|
path: registered.path,
|
|
61325
61361
|
hasLocalConfig,
|
|
61326
|
-
kitType:
|
|
61327
|
-
version:
|
|
61362
|
+
kitType: kitInfo.primaryKit,
|
|
61363
|
+
version: kitInfo.primaryVersion,
|
|
61364
|
+
kits: kitInfo.kits,
|
|
61328
61365
|
health,
|
|
61329
61366
|
model,
|
|
61330
61367
|
activeHooks: settings ? countHooks(settings) : 0,
|
|
61331
|
-
mcpServers: settings ? countMcpServers(settings) : 0,
|
|
61368
|
+
mcpServers: (settings ? countMcpServers(settings) : 0) + projectMcpJsonCount,
|
|
61332
61369
|
skills: skills.map((s) => s.id),
|
|
61333
61370
|
pinned: registered.pinned,
|
|
61334
61371
|
tags: registered.tags,
|
|
@@ -61354,24 +61391,28 @@ async function detectAndBuildProjectInfo(path5, id, cachedSettings, cachedSkills
|
|
|
61354
61391
|
}
|
|
61355
61392
|
} catch {}
|
|
61356
61393
|
const hasLocalConfig = CkConfigManager.projectConfigExists(path5, id === "global");
|
|
61357
|
-
const
|
|
61358
|
-
const
|
|
61394
|
+
const isGlobal = id === "global";
|
|
61395
|
+
const settings = isGlobal ? await readSettings() : await readSettings(path5);
|
|
61396
|
+
const skills = isGlobal ? await scanSkills() : await scanSkills(path5);
|
|
61359
61397
|
const settingsPath = join55(homedir32(), ".claude", "settings.json");
|
|
61360
61398
|
const health = existsSync37(settingsPath) ? "healthy" : "warning";
|
|
61361
61399
|
const model = getCurrentModel() || settings?.model || "claude-sonnet-4";
|
|
61362
61400
|
const scope = id === "global" ? "global" : "project";
|
|
61401
|
+
const projectMcpJsonCount = isGlobal ? 0 : await countProjectMcpJsonServers(path5);
|
|
61363
61402
|
const planData = includePlanData ? await buildProjectPlanData(id === "global" ? null : path5, scope) : null;
|
|
61403
|
+
const kitInfo = resolveKitInfo(metadata);
|
|
61364
61404
|
return {
|
|
61365
61405
|
id,
|
|
61366
61406
|
name: basename21(path5) || (id === "global" ? "Global" : "Current"),
|
|
61367
61407
|
path: path5,
|
|
61368
61408
|
hasLocalConfig,
|
|
61369
|
-
kitType:
|
|
61370
|
-
version:
|
|
61409
|
+
kitType: kitInfo.primaryKit,
|
|
61410
|
+
version: kitInfo.primaryVersion,
|
|
61411
|
+
kits: kitInfo.kits,
|
|
61371
61412
|
health,
|
|
61372
61413
|
model,
|
|
61373
61414
|
activeHooks: settings ? countHooks(settings) : 0,
|
|
61374
|
-
mcpServers: settings ? countMcpServers(settings) : 0,
|
|
61415
|
+
mcpServers: (settings ? countMcpServers(settings) : 0) + projectMcpJsonCount,
|
|
61375
61416
|
skills: skills.map((s) => s.id),
|
|
61376
61417
|
planSettings: planData?.planSettings,
|
|
61377
61418
|
activePlans: planData?.activePlans
|
|
@@ -62195,16 +62236,16 @@ async function detectSource(skillDir) {
|
|
|
62195
62236
|
return "local";
|
|
62196
62237
|
}
|
|
62197
62238
|
async function listSkills() {
|
|
62198
|
-
const
|
|
62239
|
+
const skillsDir = getSkillsDir();
|
|
62199
62240
|
let entries;
|
|
62200
62241
|
try {
|
|
62201
|
-
const dirEntries = await fs6.readdir(
|
|
62242
|
+
const dirEntries = await fs6.readdir(skillsDir, { withFileTypes: true });
|
|
62202
62243
|
entries = dirEntries.filter((e2) => e2.isDirectory()).map((e2) => e2.name);
|
|
62203
62244
|
} catch {
|
|
62204
62245
|
return [];
|
|
62205
62246
|
}
|
|
62206
62247
|
const skills = await Promise.all(entries.map(async (name) => {
|
|
62207
|
-
const skillDir = path5.join(
|
|
62248
|
+
const skillDir = path5.join(skillsDir, name);
|
|
62208
62249
|
const skillMdPath = path5.join(skillDir, "SKILL.md");
|
|
62209
62250
|
try {
|
|
62210
62251
|
await fs6.access(skillMdPath);
|
|
@@ -62253,8 +62294,8 @@ function registerSkillBrowserRoutes(app) {
|
|
|
62253
62294
|
const query = rawQuery.slice(0, 500);
|
|
62254
62295
|
const limit = Math.min(100, Math.max(1, Number.parseInt(rawLimit, 10) || 10));
|
|
62255
62296
|
try {
|
|
62256
|
-
const
|
|
62257
|
-
const catalog = await skillCatalogGenerator.readOrRegenerate(
|
|
62297
|
+
const skillsDir = getSkillsDir();
|
|
62298
|
+
const catalog = await skillCatalogGenerator.readOrRegenerate(skillsDir);
|
|
62258
62299
|
const results = searchSkills(catalog.skills, query, limit, catalog.generated);
|
|
62259
62300
|
res.json({ results });
|
|
62260
62301
|
} catch {
|
|
@@ -62275,11 +62316,11 @@ function registerSkillBrowserRoutes(app) {
|
|
|
62275
62316
|
res.status(400).json({ error: "Invalid skill name" });
|
|
62276
62317
|
return;
|
|
62277
62318
|
}
|
|
62278
|
-
const
|
|
62279
|
-
const skillDir = path5.join(
|
|
62319
|
+
const skillsDir = getSkillsDir();
|
|
62320
|
+
const skillDir = path5.join(skillsDir, name);
|
|
62280
62321
|
const skillMdPath = path5.join(skillDir, "SKILL.md");
|
|
62281
62322
|
const resolvedPath = path5.resolve(skillMdPath);
|
|
62282
|
-
const resolvedSkillsDir = path5.resolve(
|
|
62323
|
+
const resolvedSkillsDir = path5.resolve(skillsDir);
|
|
62283
62324
|
if (!resolvedPath.startsWith(resolvedSkillsDir + path5.sep)) {
|
|
62284
62325
|
res.status(403).json({ error: "Access denied" });
|
|
62285
62326
|
return;
|
|
@@ -63710,7 +63751,7 @@ var package_default;
|
|
|
63710
63751
|
var init_package = __esm(() => {
|
|
63711
63752
|
package_default = {
|
|
63712
63753
|
name: "@chiendt/ack-cli",
|
|
63713
|
-
version: "1.3.0-dev.
|
|
63754
|
+
version: "1.3.0-dev.4",
|
|
63714
63755
|
description: "ACK CLI - tool for bootstrapping and updating ACK kits (Claude Code agent kits)",
|
|
63715
63756
|
type: "module",
|
|
63716
63757
|
repository: {
|
|
@@ -73594,8 +73635,8 @@ function validatePackageName(packageName) {
|
|
|
73594
73635
|
throw new Error("Invalid package name");
|
|
73595
73636
|
}
|
|
73596
73637
|
}
|
|
73597
|
-
function validateScriptPath(
|
|
73598
|
-
const skillsDirResolved = resolve37(
|
|
73638
|
+
function validateScriptPath(skillsDir, scriptPath) {
|
|
73639
|
+
const skillsDirResolved = resolve37(skillsDir);
|
|
73599
73640
|
const scriptPathResolved = resolve37(scriptPath);
|
|
73600
73641
|
const skillsDirNormalized = isWindows() ? skillsDirResolved.toLowerCase() : skillsDirResolved;
|
|
73601
73642
|
const scriptPathNormalized = isWindows() ? scriptPathResolved.toLowerCase() : scriptPathResolved;
|
|
@@ -73920,8 +73961,8 @@ function getSystemPackageCommands(summary, systemFailures) {
|
|
|
73920
73961
|
}
|
|
73921
73962
|
return summary.remediation.sudo_packages ? [summary.remediation.sudo_packages] : [];
|
|
73922
73963
|
}
|
|
73923
|
-
function displayInstallErrors(
|
|
73924
|
-
const summaryPath = join99(
|
|
73964
|
+
function displayInstallErrors(skillsDir) {
|
|
73965
|
+
const summaryPath = join99(skillsDir, ".install-error-summary.json");
|
|
73925
73966
|
if (!existsSync66(summaryPath)) {
|
|
73926
73967
|
logger.error("Skills installation failed. Run with --verbose for details.");
|
|
73927
73968
|
return;
|
|
@@ -74019,8 +74060,8 @@ async function checkNeedsSudoPackages() {
|
|
|
74019
74060
|
return true;
|
|
74020
74061
|
}
|
|
74021
74062
|
}
|
|
74022
|
-
function hasInstallState(
|
|
74023
|
-
const stateFilePath = join99(
|
|
74063
|
+
function hasInstallState(skillsDir) {
|
|
74064
|
+
const stateFilePath = join99(skillsDir, ".install-state.json");
|
|
74024
74065
|
return existsSync66(stateFilePath);
|
|
74025
74066
|
}
|
|
74026
74067
|
var WHICH_COMMAND_TIMEOUT_MS = 5000, WINDOWS_SYSTEM_PACKAGES, SYSTEM_TOOL_KEYS, WINDOWS_RSVG_COMMANDS;
|
|
@@ -74039,7 +74080,7 @@ var init_install_error_handler = __esm(() => {
|
|
|
74039
74080
|
|
|
74040
74081
|
// src/services/package-installer/skills-installer.ts
|
|
74041
74082
|
import { join as join100 } from "node:path";
|
|
74042
|
-
async function installSkillsDependencies(
|
|
74083
|
+
async function installSkillsDependencies(skillsDir, options2 = {}) {
|
|
74043
74084
|
const { skipConfirm = false, withSudo = false } = options2;
|
|
74044
74085
|
const displayName = "Skills Dependencies";
|
|
74045
74086
|
if (isCIEnvironment()) {
|
|
@@ -74064,9 +74105,9 @@ async function installSkillsDependencies(skillsDir2, options2 = {}) {
|
|
|
74064
74105
|
const clack = await Promise.resolve().then(() => (init_dist2(), exports_dist));
|
|
74065
74106
|
const platform9 = process.platform;
|
|
74066
74107
|
const scriptName = platform9 === "win32" ? "install.ps1" : "install.sh";
|
|
74067
|
-
const scriptPath = join100(
|
|
74108
|
+
const scriptPath = join100(skillsDir, scriptName);
|
|
74068
74109
|
try {
|
|
74069
|
-
validateScriptPath(
|
|
74110
|
+
validateScriptPath(skillsDir, scriptPath);
|
|
74070
74111
|
} catch (error) {
|
|
74071
74112
|
const errorMessage = error instanceof Error ? error.message : "Unknown error";
|
|
74072
74113
|
logger.error(`Invalid script path: ${errorMessage}`);
|
|
@@ -74080,7 +74121,7 @@ async function installSkillsDependencies(skillsDir2, options2 = {}) {
|
|
|
74080
74121
|
logger.warning(`Skills installation script not found: ${scriptPath}`);
|
|
74081
74122
|
logger.info("");
|
|
74082
74123
|
logger.info("\uD83D\uDCD6 Manual Installation Instructions:");
|
|
74083
|
-
logger.info(` See: ${join100(
|
|
74124
|
+
logger.info(` See: ${join100(skillsDir, "INSTALLATION.md")}`);
|
|
74084
74125
|
logger.info("");
|
|
74085
74126
|
logger.info("Quick start:");
|
|
74086
74127
|
logger.info(" cd .claude/skills/ai-multimodal/scripts");
|
|
@@ -74127,7 +74168,7 @@ async function installSkillsDependencies(skillsDir2, options2 = {}) {
|
|
|
74127
74168
|
logger.info(` ${platform9 === "win32" ? `powershell -File "${scriptPath}"` : `bash ${scriptPath}`}`);
|
|
74128
74169
|
logger.info("");
|
|
74129
74170
|
logger.info("Or see complete guide:");
|
|
74130
|
-
logger.info(` ${join100(
|
|
74171
|
+
logger.info(` ${join100(skillsDir, "INSTALLATION.md")}`);
|
|
74131
74172
|
return {
|
|
74132
74173
|
success: false,
|
|
74133
74174
|
package: displayName,
|
|
@@ -74137,7 +74178,7 @@ async function installSkillsDependencies(skillsDir2, options2 = {}) {
|
|
|
74137
74178
|
logger.info(`Installing ${displayName}...`);
|
|
74138
74179
|
logger.info(`Running: ${scriptPath}`);
|
|
74139
74180
|
const scriptArgs = ["--yes"];
|
|
74140
|
-
if (hasInstallState(
|
|
74181
|
+
if (hasInstallState(skillsDir)) {
|
|
74141
74182
|
if (skipConfirm || isNonInteractive()) {
|
|
74142
74183
|
logger.info("Resuming previous installation...");
|
|
74143
74184
|
scriptArgs.push("--resume");
|
|
@@ -74204,13 +74245,13 @@ async function installSkillsDependencies(skillsDir2, options2 = {}) {
|
|
|
74204
74245
|
if (platform9 === "win32") {
|
|
74205
74246
|
await executeInteractiveScript("powershell.exe", ["-NoLogo", "-ExecutionPolicy", "Bypass", "-File", scriptPath, "-Y"], {
|
|
74206
74247
|
timeout: 600000,
|
|
74207
|
-
cwd:
|
|
74248
|
+
cwd: skillsDir,
|
|
74208
74249
|
env: scriptEnv
|
|
74209
74250
|
});
|
|
74210
74251
|
} else {
|
|
74211
74252
|
await executeInteractiveScript("bash", [scriptPath, ...scriptArgs], {
|
|
74212
74253
|
timeout: 600000,
|
|
74213
|
-
cwd:
|
|
74254
|
+
cwd: skillsDir,
|
|
74214
74255
|
env: scriptEnv
|
|
74215
74256
|
});
|
|
74216
74257
|
}
|
|
@@ -74224,7 +74265,7 @@ async function installSkillsDependencies(skillsDir2, options2 = {}) {
|
|
|
74224
74265
|
const exitCodeMatch = errorMessage.match(/exited with code (\d+)/);
|
|
74225
74266
|
const exitCode = exitCodeMatch ? Number.parseInt(exitCodeMatch[1], 10) : 1;
|
|
74226
74267
|
if (exitCode === EXIT_CODE_PARTIAL_SUCCESS) {
|
|
74227
|
-
displayInstallErrors(
|
|
74268
|
+
displayInstallErrors(skillsDir);
|
|
74228
74269
|
logger.info("");
|
|
74229
74270
|
logger.success("Core functionality is available despite some package failures.");
|
|
74230
74271
|
return {
|
|
@@ -74234,7 +74275,7 @@ async function installSkillsDependencies(skillsDir2, options2 = {}) {
|
|
|
74234
74275
|
};
|
|
74235
74276
|
}
|
|
74236
74277
|
if (exitCode === EXIT_CODE_CRITICAL_FAILURE) {
|
|
74237
|
-
displayInstallErrors(
|
|
74278
|
+
displayInstallErrors(skillsDir);
|
|
74238
74279
|
logger.error("");
|
|
74239
74280
|
logger.error("Skills installation failed. See above for details.");
|
|
74240
74281
|
return {
|
|
@@ -74248,7 +74289,7 @@ async function installSkillsDependencies(skillsDir2, options2 = {}) {
|
|
|
74248
74289
|
logger.info("\uD83D\uDCD6 Manual Installation Instructions:");
|
|
74249
74290
|
logger.info("");
|
|
74250
74291
|
logger.info("See complete guide:");
|
|
74251
|
-
logger.info(` cat ${join100(
|
|
74292
|
+
logger.info(` cat ${join100(skillsDir, "INSTALLATION.md")}`);
|
|
74252
74293
|
logger.info("");
|
|
74253
74294
|
logger.info("Quick start:");
|
|
74254
74295
|
logger.info(" cd .claude/skills/ai-multimodal/scripts");
|
|
@@ -74265,9 +74306,9 @@ async function installSkillsDependencies(skillsDir2, options2 = {}) {
|
|
|
74265
74306
|
};
|
|
74266
74307
|
}
|
|
74267
74308
|
}
|
|
74268
|
-
async function handleSkillsInstallation(
|
|
74309
|
+
async function handleSkillsInstallation(skillsDir, options2 = {}) {
|
|
74269
74310
|
try {
|
|
74270
|
-
const skillsResult = await installSkillsDependencies(
|
|
74311
|
+
const skillsResult = await installSkillsDependencies(skillsDir, options2);
|
|
74271
74312
|
if (skillsResult.success) {
|
|
74272
74313
|
if (skillsResult.version === PARTIAL_INSTALL_VERSION) {
|
|
74273
74314
|
logger.success("Skills core dependencies installed (some optional packages skipped)");
|
|
@@ -87826,10 +87867,10 @@ import { existsSync as existsSync53 } from "node:fs";
|
|
|
87826
87867
|
import { readFile as readFile40, readdir as readdir19 } from "node:fs/promises";
|
|
87827
87868
|
import { basename as basename24, join as join76, relative as relative16 } from "node:path";
|
|
87828
87869
|
var SKIP_DIRS5 = new Set([".git", ".venv", "__pycache__", "node_modules", "scripts", "common"]);
|
|
87829
|
-
async function scanSkills2(
|
|
87830
|
-
if (!existsSync53(
|
|
87870
|
+
async function scanSkills2(skillsDir) {
|
|
87871
|
+
if (!existsSync53(skillsDir))
|
|
87831
87872
|
return [];
|
|
87832
|
-
const skillDirs = await findSkillDirs(
|
|
87873
|
+
const skillDirs = await findSkillDirs(skillsDir);
|
|
87833
87874
|
const skills = [];
|
|
87834
87875
|
for (const dir of skillDirs) {
|
|
87835
87876
|
const file = join76(dir, "SKILL.md");
|
|
@@ -87837,7 +87878,7 @@ async function scanSkills2(skillsDir2) {
|
|
|
87837
87878
|
const content = await readFile40(file, "utf8");
|
|
87838
87879
|
const { data } = import_gray_matter11.default(content, { engines: { javascript: { parse: () => ({}) } } });
|
|
87839
87880
|
const rawName = typeof data.name === "string" ? data.name : "";
|
|
87840
|
-
const fallbackId = relative16(
|
|
87881
|
+
const fallbackId = relative16(skillsDir, dir).replace(/\\/g, "/") || basename24(dir);
|
|
87841
87882
|
skills.push({
|
|
87842
87883
|
id: normalizeSkillId(rawName, fallbackId),
|
|
87843
87884
|
description: typeof data.description === "string" ? data.description : "",
|
|
@@ -103473,13 +103514,13 @@ import { join as join129, relative as relative27 } from "node:path";
|
|
|
103473
103514
|
class SkillsManifestManager {
|
|
103474
103515
|
static MANIFEST_FILENAME = ".skills-manifest.json";
|
|
103475
103516
|
static MANIFEST_VERSION = "1.0.0";
|
|
103476
|
-
static async generateManifest(
|
|
103477
|
-
logger.debug(`Generating manifest for: ${
|
|
103478
|
-
if (!await import_fs_extra24.pathExists(
|
|
103479
|
-
throw new SkillsMigrationError(`Skills directory does not exist: ${
|
|
103517
|
+
static async generateManifest(skillsDir) {
|
|
103518
|
+
logger.debug(`Generating manifest for: ${skillsDir}`);
|
|
103519
|
+
if (!await import_fs_extra24.pathExists(skillsDir)) {
|
|
103520
|
+
throw new SkillsMigrationError(`Skills directory does not exist: ${skillsDir}`);
|
|
103480
103521
|
}
|
|
103481
|
-
const structure = await SkillsManifestManager.detectStructure(
|
|
103482
|
-
const skills = await SkillsManifestManager.scanSkills(
|
|
103522
|
+
const structure = await SkillsManifestManager.detectStructure(skillsDir);
|
|
103523
|
+
const skills = await SkillsManifestManager.scanSkills(skillsDir, structure);
|
|
103483
103524
|
const manifest = {
|
|
103484
103525
|
version: SkillsManifestManager.MANIFEST_VERSION,
|
|
103485
103526
|
structure,
|
|
@@ -103489,13 +103530,13 @@ class SkillsManifestManager {
|
|
|
103489
103530
|
logger.debug(`Generated manifest with ${skills.length} skills (${structure} structure)`);
|
|
103490
103531
|
return manifest;
|
|
103491
103532
|
}
|
|
103492
|
-
static async writeManifest(
|
|
103493
|
-
const manifestPath = join129(
|
|
103533
|
+
static async writeManifest(skillsDir, manifest) {
|
|
103534
|
+
const manifestPath = join129(skillsDir, SkillsManifestManager.MANIFEST_FILENAME);
|
|
103494
103535
|
await writeFile32(manifestPath, JSON.stringify(manifest, null, 2), "utf-8");
|
|
103495
103536
|
logger.debug(`Wrote manifest to: ${manifestPath}`);
|
|
103496
103537
|
}
|
|
103497
|
-
static async readManifest(
|
|
103498
|
-
const manifestPath = join129(
|
|
103538
|
+
static async readManifest(skillsDir) {
|
|
103539
|
+
const manifestPath = join129(skillsDir, SkillsManifestManager.MANIFEST_FILENAME);
|
|
103499
103540
|
if (!await import_fs_extra24.pathExists(manifestPath)) {
|
|
103500
103541
|
logger.debug(`No manifest found at: ${manifestPath}`);
|
|
103501
103542
|
return null;
|
|
@@ -103511,14 +103552,14 @@ class SkillsManifestManager {
|
|
|
103511
103552
|
return null;
|
|
103512
103553
|
}
|
|
103513
103554
|
}
|
|
103514
|
-
static async detectStructure(
|
|
103515
|
-
const entries = await readdir34(
|
|
103555
|
+
static async detectStructure(skillsDir) {
|
|
103556
|
+
const entries = await readdir34(skillsDir, { withFileTypes: true });
|
|
103516
103557
|
const dirs = entries.filter((entry) => entry.isDirectory() && !BUILD_ARTIFACT_DIRS.includes(entry.name) && !entry.name.startsWith("."));
|
|
103517
103558
|
if (dirs.length === 0) {
|
|
103518
103559
|
return "flat";
|
|
103519
103560
|
}
|
|
103520
103561
|
for (const dir of dirs.slice(0, 3)) {
|
|
103521
|
-
const dirPath = join129(
|
|
103562
|
+
const dirPath = join129(skillsDir, dir.name);
|
|
103522
103563
|
const subEntries = await readdir34(dirPath, { withFileTypes: true });
|
|
103523
103564
|
const hasSubdirs = subEntries.some((entry) => entry.isDirectory());
|
|
103524
103565
|
if (hasSubdirs) {
|
|
@@ -103531,13 +103572,13 @@ class SkillsManifestManager {
|
|
|
103531
103572
|
}
|
|
103532
103573
|
return "flat";
|
|
103533
103574
|
}
|
|
103534
|
-
static async scanSkills(
|
|
103575
|
+
static async scanSkills(skillsDir, structure) {
|
|
103535
103576
|
const skills = [];
|
|
103536
103577
|
if (structure === "flat") {
|
|
103537
|
-
const entries = await readdir34(
|
|
103578
|
+
const entries = await readdir34(skillsDir, { withFileTypes: true });
|
|
103538
103579
|
for (const entry of entries) {
|
|
103539
103580
|
if (entry.isDirectory() && !BUILD_ARTIFACT_DIRS.includes(entry.name) && !entry.name.startsWith(".")) {
|
|
103540
|
-
const skillPath = join129(
|
|
103581
|
+
const skillPath = join129(skillsDir, entry.name);
|
|
103541
103582
|
const hash = await SkillsManifestManager.hashDirectory(skillPath);
|
|
103542
103583
|
skills.push({
|
|
103543
103584
|
name: entry.name,
|
|
@@ -103546,10 +103587,10 @@ class SkillsManifestManager {
|
|
|
103546
103587
|
}
|
|
103547
103588
|
}
|
|
103548
103589
|
} else {
|
|
103549
|
-
const categories = await readdir34(
|
|
103590
|
+
const categories = await readdir34(skillsDir, { withFileTypes: true });
|
|
103550
103591
|
for (const category of categories) {
|
|
103551
103592
|
if (category.isDirectory() && !BUILD_ARTIFACT_DIRS.includes(category.name) && !category.name.startsWith(".")) {
|
|
103552
|
-
const categoryPath = join129(
|
|
103593
|
+
const categoryPath = join129(skillsDir, category.name);
|
|
103553
103594
|
const skillEntries = await readdir34(categoryPath, { withFileTypes: true });
|
|
103554
103595
|
for (const skillEntry of skillEntries) {
|
|
103555
103596
|
if (skillEntry.isDirectory() && !skillEntry.name.startsWith(".")) {
|
|
@@ -103706,11 +103747,11 @@ function getPathMapping(skillName, oldBasePath, newBasePath) {
|
|
|
103706
103747
|
var import_fs_extra25 = __toESM(require_lib(), 1);
|
|
103707
103748
|
import { readdir as readdir35 } from "node:fs/promises";
|
|
103708
103749
|
import { join as join130 } from "node:path";
|
|
103709
|
-
async function scanDirectory(
|
|
103710
|
-
if (!await import_fs_extra25.pathExists(
|
|
103750
|
+
async function scanDirectory(skillsDir) {
|
|
103751
|
+
if (!await import_fs_extra25.pathExists(skillsDir)) {
|
|
103711
103752
|
return ["flat", []];
|
|
103712
103753
|
}
|
|
103713
|
-
const entries = await readdir35(
|
|
103754
|
+
const entries = await readdir35(skillsDir, { withFileTypes: true });
|
|
103714
103755
|
const dirs = entries.filter((entry) => entry.isDirectory() && entry.name !== "node_modules" && !entry.name.startsWith("."));
|
|
103715
103756
|
if (dirs.length === 0) {
|
|
103716
103757
|
return ["flat", []];
|
|
@@ -103718,7 +103759,7 @@ async function scanDirectory(skillsDir2) {
|
|
|
103718
103759
|
let totalSkillLikeCount = 0;
|
|
103719
103760
|
const allSkills = [];
|
|
103720
103761
|
for (const dir of dirs) {
|
|
103721
|
-
const dirPath = join130(
|
|
103762
|
+
const dirPath = join130(skillsDir, dir.name);
|
|
103722
103763
|
const subEntries = await readdir35(dirPath, { withFileTypes: true });
|
|
103723
103764
|
const subdirs = subEntries.filter((entry) => entry.isDirectory() && !entry.name.startsWith("."));
|
|
103724
103765
|
if (subdirs.length > 0) {
|
|
@@ -104171,22 +104212,22 @@ function validatePath2(path10, paramName) {
|
|
|
104171
104212
|
|
|
104172
104213
|
class SkillsBackupManager {
|
|
104173
104214
|
static BACKUP_PREFIX = ".skills-backup-";
|
|
104174
|
-
static async createBackup(
|
|
104175
|
-
validatePath2(
|
|
104215
|
+
static async createBackup(skillsDir, parentDir) {
|
|
104216
|
+
validatePath2(skillsDir, "skillsDir");
|
|
104176
104217
|
if (parentDir) {
|
|
104177
104218
|
validatePath2(parentDir, "parentDir");
|
|
104178
104219
|
}
|
|
104179
|
-
if (!await import_fs_extra28.pathExists(
|
|
104180
|
-
throw new SkillsMigrationError(`Cannot create backup: Skills directory does not exist: ${
|
|
104220
|
+
if (!await import_fs_extra28.pathExists(skillsDir)) {
|
|
104221
|
+
throw new SkillsMigrationError(`Cannot create backup: Skills directory does not exist: ${skillsDir}`);
|
|
104181
104222
|
}
|
|
104182
104223
|
const timestamp = Date.now();
|
|
104183
104224
|
const randomSuffix = Math.random().toString(36).substring(2, 8);
|
|
104184
104225
|
const backupDirName = `${SkillsBackupManager.BACKUP_PREFIX}${timestamp}-${randomSuffix}`;
|
|
104185
|
-
const backupDir = parentDir ? join132(parentDir, backupDirName) : join132(
|
|
104226
|
+
const backupDir = parentDir ? join132(parentDir, backupDirName) : join132(skillsDir, "..", backupDirName);
|
|
104186
104227
|
logger.info(`Creating backup at: ${backupDir}`);
|
|
104187
104228
|
try {
|
|
104188
104229
|
await mkdir34(backupDir, { recursive: true });
|
|
104189
|
-
await SkillsBackupManager.copyDirectory(
|
|
104230
|
+
await SkillsBackupManager.copyDirectory(skillsDir, backupDir);
|
|
104190
104231
|
logger.success("Backup created successfully");
|
|
104191
104232
|
return backupDir;
|
|
104192
104233
|
} catch (error) {
|
|
@@ -104458,16 +104499,16 @@ function validatePath3(path10, paramName) {
|
|
|
104458
104499
|
}
|
|
104459
104500
|
}
|
|
104460
104501
|
}
|
|
104461
|
-
async function scanSkillsDirectory(
|
|
104462
|
-
if (!await import_fs_extra30.pathExists(
|
|
104502
|
+
async function scanSkillsDirectory(skillsDir) {
|
|
104503
|
+
if (!await import_fs_extra30.pathExists(skillsDir)) {
|
|
104463
104504
|
return ["flat", []];
|
|
104464
104505
|
}
|
|
104465
|
-
const entries = await readdir39(
|
|
104506
|
+
const entries = await readdir39(skillsDir, { withFileTypes: true });
|
|
104466
104507
|
const dirs = entries.filter((entry) => entry.isDirectory() && entry.name !== "node_modules" && !entry.name.startsWith("."));
|
|
104467
104508
|
if (dirs.length === 0) {
|
|
104468
104509
|
return ["flat", []];
|
|
104469
104510
|
}
|
|
104470
|
-
const firstDirPath = join134(
|
|
104511
|
+
const firstDirPath = join134(skillsDir, dirs[0].name);
|
|
104471
104512
|
const subEntries = await readdir39(firstDirPath, { withFileTypes: true });
|
|
104472
104513
|
const subdirs = subEntries.filter((entry) => entry.isDirectory() && !entry.name.startsWith("."));
|
|
104473
104514
|
if (subdirs.length > 0) {
|
|
@@ -104483,7 +104524,7 @@ async function scanSkillsDirectory(skillsDir2) {
|
|
|
104483
104524
|
if (skillLikeCount > 0) {
|
|
104484
104525
|
const skills = [];
|
|
104485
104526
|
for (const dir of dirs) {
|
|
104486
|
-
const categoryPath = join134(
|
|
104527
|
+
const categoryPath = join134(skillsDir, dir.name);
|
|
104487
104528
|
const skillDirs = await readdir39(categoryPath, { withFileTypes: true });
|
|
104488
104529
|
skills.push(...skillDirs.filter((entry) => entry.isDirectory() && !entry.name.startsWith(".")).map((entry) => entry.name));
|
|
104489
104530
|
}
|
|
@@ -104492,17 +104533,17 @@ async function scanSkillsDirectory(skillsDir2) {
|
|
|
104492
104533
|
}
|
|
104493
104534
|
return ["flat", dirs.map((dir) => dir.name)];
|
|
104494
104535
|
}
|
|
104495
|
-
async function findSkillPath(
|
|
104496
|
-
const flatPath = join134(
|
|
104536
|
+
async function findSkillPath(skillsDir, skillName) {
|
|
104537
|
+
const flatPath = join134(skillsDir, skillName);
|
|
104497
104538
|
if (await import_fs_extra30.pathExists(flatPath)) {
|
|
104498
104539
|
return { path: flatPath, category: undefined };
|
|
104499
104540
|
}
|
|
104500
|
-
const entries = await readdir39(
|
|
104541
|
+
const entries = await readdir39(skillsDir, { withFileTypes: true });
|
|
104501
104542
|
for (const entry of entries) {
|
|
104502
104543
|
if (!entry.isDirectory() || entry.name.startsWith(".") || entry.name === "node_modules") {
|
|
104503
104544
|
continue;
|
|
104504
104545
|
}
|
|
104505
|
-
const categoryPath = join134(
|
|
104546
|
+
const categoryPath = join134(skillsDir, entry.name);
|
|
104506
104547
|
const skillPath = join134(categoryPath, skillName);
|
|
104507
104548
|
if (await import_fs_extra30.pathExists(skillPath)) {
|
|
104508
104549
|
return { path: skillPath, category: entry.name };
|
|
@@ -104931,8 +104972,8 @@ async function handlePostInstall(ctx) {
|
|
|
104931
104972
|
}
|
|
104932
104973
|
if (installSkills) {
|
|
104933
104974
|
const { handleSkillsInstallation: handleSkillsInstallation2 } = await Promise.resolve().then(() => (init_package_installer(), exports_package_installer));
|
|
104934
|
-
const
|
|
104935
|
-
await handleSkillsInstallation2(
|
|
104975
|
+
const skillsDir = PathResolver.buildSkillsPath(ctx.resolvedDir, ctx.options.global);
|
|
104976
|
+
await handleSkillsInstallation2(skillsDir, {
|
|
104936
104977
|
skipConfirm: ctx.isNonInteractive,
|
|
104937
104978
|
withSudo: ctx.options.withSudo
|
|
104938
104979
|
});
|
|
@@ -109774,8 +109815,8 @@ async function postSetup(resolvedDir, validOptions, isNonInteractive2, prompts)
|
|
|
109774
109815
|
}
|
|
109775
109816
|
if (installSkills) {
|
|
109776
109817
|
const { handleSkillsInstallation: handleSkillsInstallation2 } = await Promise.resolve().then(() => (init_package_installer(), exports_package_installer));
|
|
109777
|
-
const
|
|
109778
|
-
await handleSkillsInstallation2(
|
|
109818
|
+
const skillsDir = PathResolver.buildSkillsPath(resolvedDir, false);
|
|
109819
|
+
await handleSkillsInstallation2(skillsDir, {
|
|
109779
109820
|
skipConfirm: isNonInteractive2,
|
|
109780
109821
|
withSudo: validOptions.withSudo
|
|
109781
109822
|
});
|