@hasna/skills 0.1.47 → 0.1.49
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/bin/index.js +74 -53
- package/bin/mcp.js +52 -31
- package/dist/index.js +54 -33
- package/dist/lib/config.d.ts +1 -1
- package/dist/storage.js +28 -7
- package/package.json +1 -1
- package/skills/hook/bunfig.toml +5 -0
- package/skills/implementation/bunfig.toml +5 -0
package/bin/index.js
CHANGED
|
@@ -9553,7 +9553,7 @@ Learn more about this warning here: https://reactjs.org/link/legacy-context`, so
|
|
|
9553
9553
|
|
|
9554
9554
|
` + ("" + errorBoundaryMessage);
|
|
9555
9555
|
console["error"](combinedMessage);
|
|
9556
|
-
}
|
|
9556
|
+
}
|
|
9557
9557
|
} catch (e) {
|
|
9558
9558
|
setTimeout(function() {
|
|
9559
9559
|
throw e;
|
|
@@ -18037,7 +18037,7 @@ var require_backend = __commonJS((exports, module) => {
|
|
|
18037
18037
|
987: (module2, __unused_webpack_exports, __webpack_require__2) => {
|
|
18038
18038
|
if (true) {
|
|
18039
18039
|
module2.exports = __webpack_require__2(786);
|
|
18040
|
-
}
|
|
18040
|
+
}
|
|
18041
18041
|
},
|
|
18042
18042
|
126: (__unused_webpack_module, exports2, __webpack_require__2) => {
|
|
18043
18043
|
var process3 = __webpack_require__2(169);
|
|
@@ -18487,7 +18487,7 @@ var require_backend = __commonJS((exports, module) => {
|
|
|
18487
18487
|
189: (module2, __unused_webpack_exports, __webpack_require__2) => {
|
|
18488
18488
|
if (true) {
|
|
18489
18489
|
module2.exports = __webpack_require__2(126);
|
|
18490
|
-
}
|
|
18490
|
+
}
|
|
18491
18491
|
},
|
|
18492
18492
|
206: function(module2, exports2, __webpack_require__2) {
|
|
18493
18493
|
var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;
|
|
@@ -18502,7 +18502,7 @@ var require_backend = __commonJS((exports, module) => {
|
|
|
18502
18502
|
(function(root, factory) {
|
|
18503
18503
|
if (true) {
|
|
18504
18504
|
__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__2(430)], __WEBPACK_AMD_DEFINE_FACTORY__ = factory, __WEBPACK_AMD_DEFINE_RESULT__ = typeof __WEBPACK_AMD_DEFINE_FACTORY__ === "function" ? __WEBPACK_AMD_DEFINE_FACTORY__.apply(exports2, __WEBPACK_AMD_DEFINE_ARRAY__) : __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module2.exports = __WEBPACK_AMD_DEFINE_RESULT__);
|
|
18505
|
-
}
|
|
18505
|
+
}
|
|
18506
18506
|
})(this, function ErrorStackParser(StackFrame) {
|
|
18507
18507
|
var FIREFOX_SAFARI_STACK_REGEXP = /(^|@)\S+:\d+/;
|
|
18508
18508
|
var CHROME_IE_STACK_REGEXP = /^\s*at .*(\S+:\d+|\(native\))/m;
|
|
@@ -19198,7 +19198,7 @@ var require_backend = __commonJS((exports, module) => {
|
|
|
19198
19198
|
(function(root, factory) {
|
|
19199
19199
|
if (true) {
|
|
19200
19200
|
__WEBPACK_AMD_DEFINE_ARRAY__ = [], __WEBPACK_AMD_DEFINE_FACTORY__ = factory, __WEBPACK_AMD_DEFINE_RESULT__ = typeof __WEBPACK_AMD_DEFINE_FACTORY__ === "function" ? __WEBPACK_AMD_DEFINE_FACTORY__.apply(exports2, __WEBPACK_AMD_DEFINE_ARRAY__) : __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module2.exports = __WEBPACK_AMD_DEFINE_RESULT__);
|
|
19201
|
-
}
|
|
19201
|
+
}
|
|
19202
19202
|
})(this, function() {
|
|
19203
19203
|
function _isNumber(n) {
|
|
19204
19204
|
return !isNaN(parseFloat(n)) && isFinite(n);
|
|
@@ -24572,7 +24572,7 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
24572
24572
|
var suffix = "";
|
|
24573
24573
|
if (true) {
|
|
24574
24574
|
suffix = " (<anonymous>)";
|
|
24575
|
-
}
|
|
24575
|
+
}
|
|
24576
24576
|
return `
|
|
24577
24577
|
` + prefix + name + suffix;
|
|
24578
24578
|
}
|
|
@@ -27301,7 +27301,7 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
27301
27301
|
hasChanges = true;
|
|
27302
27302
|
updateMostRecentlyInspectedElementIfNecessary(devtoolsInstance.id);
|
|
27303
27303
|
}
|
|
27304
|
-
}
|
|
27304
|
+
}
|
|
27305
27305
|
}
|
|
27306
27306
|
} catch (err) {
|
|
27307
27307
|
_iterator2.e(err);
|
|
@@ -29080,7 +29080,7 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
29080
29080
|
if (contentFiber === null) {
|
|
29081
29081
|
throw new Error("There should always be an Offscreen Fiber child in a hydrated Suspense boundary.");
|
|
29082
29082
|
}
|
|
29083
|
-
}
|
|
29083
|
+
}
|
|
29084
29084
|
var _isTimedOut = fiber.memoizedState !== null;
|
|
29085
29085
|
if (!_isTimedOut) {
|
|
29086
29086
|
newSuspenseNode.rects = measureInstance(newInstance);
|
|
@@ -29114,7 +29114,7 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
29114
29114
|
if (_contentFiber === null) {
|
|
29115
29115
|
throw new Error("There should always be an Offscreen Fiber child in a hydrated Suspense boundary.");
|
|
29116
29116
|
}
|
|
29117
|
-
}
|
|
29117
|
+
}
|
|
29118
29118
|
var suspenseState = fiber.memoizedState;
|
|
29119
29119
|
var _isTimedOut3 = suspenseState !== null;
|
|
29120
29120
|
if (!_isTimedOut3) {
|
|
@@ -29214,7 +29214,7 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
29214
29214
|
trackThrownPromisesFromRetryCache(newSuspenseNode, fiber.stateNode);
|
|
29215
29215
|
mountSuspenseChildrenRecursively(_contentFiber2, traceNearestHostComponentUpdate, stashedSuspenseParent, stashedSuspensePrevious, stashedSuspenseRemaining);
|
|
29216
29216
|
shouldPopSuspenseNode = false;
|
|
29217
|
-
}
|
|
29217
|
+
}
|
|
29218
29218
|
} else {
|
|
29219
29219
|
if (fiber.child !== null) {
|
|
29220
29220
|
mountChildrenRecursively(fiber.child, traceNearestHostComponentUpdate);
|
|
@@ -29800,7 +29800,7 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
29800
29800
|
shouldPopSuspenseNode = false;
|
|
29801
29801
|
} else if (previousHydrated && !nextHydrated) {
|
|
29802
29802
|
throw new Error("Encountered a dehydrated Suspense boundary that was previously hydrated.");
|
|
29803
|
-
}
|
|
29803
|
+
}
|
|
29804
29804
|
} else {
|
|
29805
29805
|
if (nextFiber.child !== prevFiber.child) {
|
|
29806
29806
|
updateFlags |= updateChildrenRecursively(nextFiber.child, prevFiber.child, traceNearestHostComponentUpdate);
|
|
@@ -29846,8 +29846,8 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
29846
29846
|
recordResetChildren(fiberInstance);
|
|
29847
29847
|
}
|
|
29848
29848
|
updateFlags &= ~ShouldResetChildren;
|
|
29849
|
-
}
|
|
29850
|
-
}
|
|
29849
|
+
}
|
|
29850
|
+
}
|
|
29851
29851
|
if ((updateFlags & ShouldResetSuspenseChildren) !== NoUpdate) {
|
|
29852
29852
|
if (fiberInstance !== null && fiberInstance.kind === FIBER_INSTANCE) {
|
|
29853
29853
|
var _suspenseNode3 = fiberInstance.suspenseNode;
|
|
@@ -29855,7 +29855,7 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
29855
29855
|
recordResetSuspenseChildren(_suspenseNode3);
|
|
29856
29856
|
updateFlags &= ~ShouldResetSuspenseChildren;
|
|
29857
29857
|
}
|
|
29858
|
-
}
|
|
29858
|
+
}
|
|
29859
29859
|
}
|
|
29860
29860
|
if ((updateFlags & ShouldResetParentSuspenseChildren) !== NoUpdate) {
|
|
29861
29861
|
if (fiberInstance !== null && fiberInstance.kind === FIBER_INSTANCE) {
|
|
@@ -29864,7 +29864,7 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
29864
29864
|
updateFlags &= ~ShouldResetParentSuspenseChildren;
|
|
29865
29865
|
updateFlags |= ShouldResetSuspenseChildren;
|
|
29866
29866
|
}
|
|
29867
|
-
}
|
|
29867
|
+
}
|
|
29868
29868
|
}
|
|
29869
29869
|
return updateFlags;
|
|
29870
29870
|
} finally {
|
|
@@ -32928,7 +32928,7 @@ The error thrown in the component is:
|
|
|
32928
32928
|
rendererInterface = renderer_attach(hook, id, renderer, global2, shouldStartProfilingNow, profilingSettings);
|
|
32929
32929
|
} else if (renderer.ComponentTree) {
|
|
32930
32930
|
rendererInterface = legacy_renderer_attach(hook, id, renderer, global2);
|
|
32931
|
-
}
|
|
32931
|
+
}
|
|
32932
32932
|
}
|
|
32933
32933
|
return rendererInterface;
|
|
32934
32934
|
}
|
|
@@ -35811,7 +35811,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
35811
35811
|
this._exitCallback = (err) => {
|
|
35812
35812
|
if (err.code !== "commander.executeSubCommandAsync") {
|
|
35813
35813
|
throw err;
|
|
35814
|
-
}
|
|
35814
|
+
}
|
|
35815
35815
|
};
|
|
35816
35816
|
}
|
|
35817
35817
|
return this;
|
|
@@ -36860,7 +36860,7 @@ var package_default;
|
|
|
36860
36860
|
var init_package = __esm(() => {
|
|
36861
36861
|
package_default = {
|
|
36862
36862
|
name: "@hasna/skills",
|
|
36863
|
-
version: "0.1.
|
|
36863
|
+
version: "0.1.49",
|
|
36864
36864
|
description: "Skills library for AI coding agents",
|
|
36865
36865
|
type: "module",
|
|
36866
36866
|
bin: {
|
|
@@ -37848,7 +37848,7 @@ var require_jsx_dev_runtime = __commonJS((exports, module) => {
|
|
|
37848
37848
|
});
|
|
37849
37849
|
|
|
37850
37850
|
// src/lib/config.ts
|
|
37851
|
-
import { existsSync as existsSync3, readFileSync as readFileSync2, writeFileSync, mkdirSync, copyFileSync } from "fs";
|
|
37851
|
+
import { existsSync as existsSync3, readFileSync as readFileSync2, writeFileSync, mkdirSync, copyFileSync, readdirSync, statSync } from "fs";
|
|
37852
37852
|
import { join as join3, dirname } from "path";
|
|
37853
37853
|
import { homedir as homedir2 } from "os";
|
|
37854
37854
|
function validKeys() {
|
|
@@ -37859,6 +37859,24 @@ function allowedValues(key) {
|
|
|
37859
37859
|
return MODE_VALUES;
|
|
37860
37860
|
return ENUM_KEYS[key];
|
|
37861
37861
|
}
|
|
37862
|
+
function mergeDirectoryContents(sourceDir, targetDir) {
|
|
37863
|
+
if (!existsSync3(sourceDir))
|
|
37864
|
+
return;
|
|
37865
|
+
mkdirSync(targetDir, { recursive: true });
|
|
37866
|
+
for (const entry of readdirSync(sourceDir)) {
|
|
37867
|
+
const sourcePath = join3(sourceDir, entry);
|
|
37868
|
+
const targetPath = join3(targetDir, entry);
|
|
37869
|
+
try {
|
|
37870
|
+
const sourceStat = statSync(sourcePath);
|
|
37871
|
+
if (sourceStat.isDirectory()) {
|
|
37872
|
+
mergeDirectoryContents(sourcePath, targetPath);
|
|
37873
|
+
continue;
|
|
37874
|
+
}
|
|
37875
|
+
if (!existsSync3(targetPath))
|
|
37876
|
+
copyFileSync(sourcePath, targetPath);
|
|
37877
|
+
} catch {}
|
|
37878
|
+
}
|
|
37879
|
+
}
|
|
37862
37880
|
function normalizeConfigValue(key, value) {
|
|
37863
37881
|
if (typeof value !== "string")
|
|
37864
37882
|
return;
|
|
@@ -37882,14 +37900,17 @@ function normalizeConfigValue(key, value) {
|
|
|
37882
37900
|
function getDataDir() {
|
|
37883
37901
|
const home = process.env["HOME"] || process.env["USERPROFILE"] || homedir2();
|
|
37884
37902
|
const newDir = join3(home, ".hasna", "skills");
|
|
37903
|
+
const oldDir = join3(home, ".skills");
|
|
37885
37904
|
const oldConfigFile = join3(home, ".skillsrc");
|
|
37905
|
+
mkdirSync(newDir, { recursive: true });
|
|
37906
|
+
try {
|
|
37907
|
+
mergeDirectoryContents(oldDir, newDir);
|
|
37908
|
+
} catch {}
|
|
37886
37909
|
if (existsSync3(oldConfigFile) && !existsSync3(join3(newDir, "config.json"))) {
|
|
37887
|
-
mkdirSync(newDir, { recursive: true });
|
|
37888
37910
|
try {
|
|
37889
37911
|
copyFileSync(oldConfigFile, join3(newDir, "config.json"));
|
|
37890
37912
|
} catch {}
|
|
37891
37913
|
}
|
|
37892
|
-
mkdirSync(newDir, { recursive: true });
|
|
37893
37914
|
return newDir;
|
|
37894
37915
|
}
|
|
37895
37916
|
function getConfigPath(scope) {
|
|
@@ -38478,7 +38499,7 @@ var init_pricing = __esm(() => {
|
|
|
38478
38499
|
});
|
|
38479
38500
|
|
|
38480
38501
|
// src/lib/skill-validation.ts
|
|
38481
|
-
import { existsSync as existsSync4, lstatSync, readFileSync as readFileSync3, readdirSync, statSync } from "fs";
|
|
38502
|
+
import { existsSync as existsSync4, lstatSync, readFileSync as readFileSync3, readdirSync as readdirSync2, statSync as statSync2 } from "fs";
|
|
38482
38503
|
import { isAbsolute, join as join4, normalize } from "path";
|
|
38483
38504
|
function add2(target, code, message) {
|
|
38484
38505
|
target.push({ code, message });
|
|
@@ -38586,7 +38607,7 @@ function validateSkillDirectory(name, skillPath, registryMeta) {
|
|
|
38586
38607
|
if (!VALID_BIN_COMMAND.test(bareName)) {
|
|
38587
38608
|
add2(issues, "skill.name_invalid", `Skill name '${bareName}' must use lowercase letters, numbers, dots, underscores, or hyphens`);
|
|
38588
38609
|
}
|
|
38589
|
-
for (const entry of
|
|
38610
|
+
for (const entry of readdirSync2(skillPath).sort()) {
|
|
38590
38611
|
const entryPath = join4(skillPath, entry);
|
|
38591
38612
|
if (RESERVED_SKILL_ENTRIES.has(entry)) {
|
|
38592
38613
|
add2(issues, "skill.reserved_file", `Reserved file '${entry}' is not allowed in skill packages`);
|
|
@@ -38701,7 +38722,7 @@ function validateSkillDirectory(name, skillPath, registryMeta) {
|
|
|
38701
38722
|
const targetPath = join4(skillPath, target);
|
|
38702
38723
|
if (!existsSync4(targetPath)) {
|
|
38703
38724
|
add2(warnings, "package.bin_target_missing", `package.json bin '${command}' target '${target}' is not present before build`);
|
|
38704
|
-
} else if (
|
|
38725
|
+
} else if (statSync2(targetPath).isDirectory()) {
|
|
38705
38726
|
add2(issues, "package.bin_target_directory", `package.json bin '${command}' target '${target}' must point to a file, not a directory`);
|
|
38706
38727
|
}
|
|
38707
38728
|
}
|
|
@@ -38724,7 +38745,7 @@ function validateSkillDirectory(name, skillPath, registryMeta) {
|
|
|
38724
38745
|
add2(issues, "skill.src_index_missing", "Missing src/index.ts or src/index.js");
|
|
38725
38746
|
} else {
|
|
38726
38747
|
const indexPath = existsSync4(join4(srcDir, "index.ts")) ? join4(srcDir, "index.ts") : join4(srcDir, "index.js");
|
|
38727
|
-
const size2 =
|
|
38748
|
+
const size2 = statSync2(indexPath).size;
|
|
38728
38749
|
if (size2 < 50)
|
|
38729
38750
|
add2(warnings, "skill.src_index_minimal", `Source entry point is very small (${size2}B)`);
|
|
38730
38751
|
}
|
|
@@ -38797,9 +38818,9 @@ import {
|
|
|
38797
38818
|
lstatSync as lstatSync2,
|
|
38798
38819
|
mkdirSync as mkdirSync2,
|
|
38799
38820
|
readFileSync as readFileSync4,
|
|
38800
|
-
readdirSync as
|
|
38821
|
+
readdirSync as readdirSync3,
|
|
38801
38822
|
rmSync,
|
|
38802
|
-
statSync as
|
|
38823
|
+
statSync as statSync3,
|
|
38803
38824
|
writeFileSync as writeFileSync2
|
|
38804
38825
|
} from "fs";
|
|
38805
38826
|
import { basename, dirname as dirname2, isAbsolute as isAbsolute2, join as join5, normalize as normalize2, relative } from "path";
|
|
@@ -38830,7 +38851,7 @@ function findPortableSkill(name, options = {}) {
|
|
|
38830
38851
|
return null;
|
|
38831
38852
|
}
|
|
38832
38853
|
const path = getPortableSkillPath(normalized, options);
|
|
38833
|
-
if (!existsSync5(path) || !
|
|
38854
|
+
if (!existsSync5(path) || !statSync3(path).isDirectory())
|
|
38834
38855
|
return null;
|
|
38835
38856
|
try {
|
|
38836
38857
|
return summarizePortableSkill(path, normalized);
|
|
@@ -38843,7 +38864,7 @@ function listPortableSkills(options = {}) {
|
|
|
38843
38864
|
if (!existsSync5(root))
|
|
38844
38865
|
return [];
|
|
38845
38866
|
const skills = [];
|
|
38846
|
-
for (const entry of
|
|
38867
|
+
for (const entry of readdirSync3(root).sort()) {
|
|
38847
38868
|
if (entry.startsWith(".") || DATA_DIR_NON_SKILL_ENTRIES.has(entry))
|
|
38848
38869
|
continue;
|
|
38849
38870
|
const path = join5(root, entry);
|
|
@@ -38919,7 +38940,7 @@ function scaffoldPortableSkill(name, options = {}) {
|
|
|
38919
38940
|
}
|
|
38920
38941
|
function portPortableSkill(sourcePath, options = {}) {
|
|
38921
38942
|
const absoluteSource = normalize2(sourcePath);
|
|
38922
|
-
if (!existsSync5(absoluteSource) || !
|
|
38943
|
+
if (!existsSync5(absoluteSource) || !statSync3(absoluteSource).isDirectory()) {
|
|
38923
38944
|
throw new Error(`Skill source directory not found: ${sourcePath}`);
|
|
38924
38945
|
}
|
|
38925
38946
|
const inferred = readPortableSkillManifest(absoluteSource, basename(absoluteSource));
|
|
@@ -38988,7 +39009,7 @@ function validatePortableSkillDirectory(name, skillPath) {
|
|
|
38988
39009
|
const entryPath = join5(skillPath, command.entry);
|
|
38989
39010
|
if (!existsSync5(entryPath))
|
|
38990
39011
|
add3(issues, "portable.command_entry_missing", `Command '${command.name}' entry '${command.entry}' is missing`);
|
|
38991
|
-
else if (
|
|
39012
|
+
else if (statSync3(entryPath).isDirectory())
|
|
38992
39013
|
add3(issues, "portable.command_entry_directory", `Command '${command.name}' entry '${command.entry}' must be a file`);
|
|
38993
39014
|
}
|
|
38994
39015
|
}
|
|
@@ -39356,7 +39377,7 @@ function displayName(name) {
|
|
|
39356
39377
|
}
|
|
39357
39378
|
function safeIsDirectory(path) {
|
|
39358
39379
|
try {
|
|
39359
|
-
return
|
|
39380
|
+
return statSync3(path).isDirectory();
|
|
39360
39381
|
} catch {
|
|
39361
39382
|
return false;
|
|
39362
39383
|
}
|
|
@@ -41438,7 +41459,7 @@ __export(exports_registry, {
|
|
|
41438
41459
|
CATEGORIES: () => CATEGORIES,
|
|
41439
41460
|
BASIC_SKILL_NAMES: () => BASIC_SKILL_NAMES
|
|
41440
41461
|
});
|
|
41441
|
-
import { existsSync as existsSync6, readFileSync as readFileSync5, readdirSync as
|
|
41462
|
+
import { existsSync as existsSync6, readFileSync as readFileSync5, readdirSync as readdirSync4 } from "fs";
|
|
41442
41463
|
import { join as join6 } from "path";
|
|
41443
41464
|
function isBasicSkillName(name) {
|
|
41444
41465
|
return BASIC_SKILL_NAMES.includes(name);
|
|
@@ -41476,7 +41497,7 @@ function discoverSkillsInDir(dir) {
|
|
|
41476
41497
|
return [];
|
|
41477
41498
|
const result2 = [];
|
|
41478
41499
|
try {
|
|
41479
|
-
const entries =
|
|
41500
|
+
const entries = readdirSync4(dir, { withFileTypes: true });
|
|
41480
41501
|
for (const entry of entries) {
|
|
41481
41502
|
if (!entry.isDirectory())
|
|
41482
41503
|
continue;
|
|
@@ -54492,7 +54513,7 @@ function finalize(ctx, schema) {
|
|
|
54492
54513
|
result2.$schema = "http://json-schema.org/draft-07/schema#";
|
|
54493
54514
|
} else if (ctx.target === "draft-04") {
|
|
54494
54515
|
result2.$schema = "http://json-schema.org/draft-04/schema#";
|
|
54495
|
-
} else if (ctx.target === "openapi-3.0") {}
|
|
54516
|
+
} else if (ctx.target === "openapi-3.0") {}
|
|
54496
54517
|
if (ctx.external?.uri) {
|
|
54497
54518
|
const id = ctx.external.registry.get(schema)?.id;
|
|
54498
54519
|
if (!id)
|
|
@@ -54757,7 +54778,7 @@ var formatMap, stringProcessor = (schema, ctx, _json, _params) => {
|
|
|
54757
54778
|
if (val === undefined) {
|
|
54758
54779
|
if (ctx.unrepresentable === "throw") {
|
|
54759
54780
|
throw new Error("Literal `undefined` cannot be represented in JSON Schema");
|
|
54760
|
-
}
|
|
54781
|
+
}
|
|
54761
54782
|
} else if (typeof val === "bigint") {
|
|
54762
54783
|
if (ctx.unrepresentable === "throw") {
|
|
54763
54784
|
throw new Error("BigInt literals cannot be represented in JSON Schema");
|
|
@@ -59450,7 +59471,7 @@ var exports_diagnostic = {};
|
|
|
59450
59471
|
__export(exports_diagnostic, {
|
|
59451
59472
|
registerDiagnostic: () => registerDiagnostic
|
|
59452
59473
|
});
|
|
59453
|
-
import { existsSync as existsSync13, readFileSync as readFileSync12, readdirSync as
|
|
59474
|
+
import { existsSync as existsSync13, readFileSync as readFileSync12, readdirSync as readdirSync5, statSync as statSync4, writeFileSync as writeFileSync6 } from "fs";
|
|
59454
59475
|
import { join as join13 } from "path";
|
|
59455
59476
|
import { execSync as execSync2 } from "child_process";
|
|
59456
59477
|
function registerDiagnostic(parent) {
|
|
@@ -59656,7 +59677,7 @@ function handleWhoami(options) {
|
|
|
59656
59677
|
let skillCount = 0;
|
|
59657
59678
|
if (exists)
|
|
59658
59679
|
try {
|
|
59659
|
-
skillCount =
|
|
59680
|
+
skillCount = readdirSync5(agentSkillsPath).filter((f) => !f.startsWith(".") && statSync4(join13(agentSkillsPath, f)).isDirectory()).length;
|
|
59660
59681
|
} catch {}
|
|
59661
59682
|
agentConfigs.push({ agent, label: AGENT_LABELS[agent], path: agentSkillsPath, exists, skillCount });
|
|
59662
59683
|
}
|
|
@@ -59789,7 +59810,7 @@ var REMOTE_SKILL_RUN_CONTRACT_VERSION = 1;
|
|
|
59789
59810
|
|
|
59790
59811
|
// src/lib/run-state.ts
|
|
59791
59812
|
import { createHash, randomBytes } from "crypto";
|
|
59792
|
-
import { existsSync as existsSync14, mkdirSync as mkdirSync5, readFileSync as readFileSync13, readdirSync as
|
|
59813
|
+
import { existsSync as existsSync14, mkdirSync as mkdirSync5, readFileSync as readFileSync13, readdirSync as readdirSync6, statSync as statSync5, writeFileSync as writeFileSync7 } from "fs";
|
|
59793
59814
|
import { extname, join as join14, relative as relative2 } from "path";
|
|
59794
59815
|
function createSkillRun(params, targetDir = process.cwd()) {
|
|
59795
59816
|
const now3 = new Date;
|
|
@@ -59864,11 +59885,11 @@ function listSkillRuns(targetDir = process.cwd(), limit = 50) {
|
|
|
59864
59885
|
if (!existsSync14(runsRoot))
|
|
59865
59886
|
return [];
|
|
59866
59887
|
const records = [];
|
|
59867
|
-
for (const day of
|
|
59888
|
+
for (const day of readdirSync6(runsRoot).sort().reverse()) {
|
|
59868
59889
|
const dayDir = join14(runsRoot, day);
|
|
59869
|
-
if (!
|
|
59890
|
+
if (!statSync5(dayDir).isDirectory())
|
|
59870
59891
|
continue;
|
|
59871
|
-
for (const runId of
|
|
59892
|
+
for (const runId of readdirSync6(dayDir).sort().reverse()) {
|
|
59872
59893
|
const record2 = readRunRecord(join14(dayDir, runId));
|
|
59873
59894
|
if (record2)
|
|
59874
59895
|
records.push(record2);
|
|
@@ -59882,7 +59903,7 @@ function findSkillRun(runId, targetDir = process.cwd()) {
|
|
|
59882
59903
|
const runsRoot = join14(getProjectStateDir(targetDir), "runs");
|
|
59883
59904
|
if (!existsSync14(runsRoot))
|
|
59884
59905
|
return null;
|
|
59885
|
-
for (const day of
|
|
59906
|
+
for (const day of readdirSync6(runsRoot)) {
|
|
59886
59907
|
const record2 = readRunRecord(join14(runsRoot, day, runId));
|
|
59887
59908
|
if (record2)
|
|
59888
59909
|
return record2;
|
|
@@ -59905,7 +59926,7 @@ function collectRunArtifacts(context) {
|
|
|
59905
59926
|
return [];
|
|
59906
59927
|
const artifacts = [];
|
|
59907
59928
|
for (const path of walkFiles(context.exportDir)) {
|
|
59908
|
-
const stat =
|
|
59929
|
+
const stat = statSync5(path);
|
|
59909
59930
|
const bytes = readFileSync13(path);
|
|
59910
59931
|
artifacts.push({
|
|
59911
59932
|
path: toProjectRelative(context.targetDir, path),
|
|
@@ -59928,9 +59949,9 @@ function readRunRecord(runDir) {
|
|
|
59928
59949
|
}
|
|
59929
59950
|
function walkFiles(dir) {
|
|
59930
59951
|
const files = [];
|
|
59931
|
-
for (const entry of
|
|
59952
|
+
for (const entry of readdirSync6(dir)) {
|
|
59932
59953
|
const full = join14(dir, entry);
|
|
59933
|
-
if (
|
|
59954
|
+
if (statSync5(full).isDirectory())
|
|
59934
59955
|
files.push(...walkFiles(full));
|
|
59935
59956
|
else
|
|
59936
59957
|
files.push(full);
|
|
@@ -76147,7 +76168,7 @@ var init_remote_client = __esm(() => {
|
|
|
76147
76168
|
});
|
|
76148
76169
|
|
|
76149
76170
|
// src/mcp/operation-tools.ts
|
|
76150
|
-
import { existsSync as existsSync15, readdirSync as
|
|
76171
|
+
import { existsSync as existsSync15, readdirSync as readdirSync7, statSync as statSync6 } from "fs";
|
|
76151
76172
|
import { join as join15 } from "path";
|
|
76152
76173
|
function registerOperationTools(server) {
|
|
76153
76174
|
server.registerTool("scaffold_skill", {
|
|
@@ -76596,9 +76617,9 @@ function registerOperationTools(server) {
|
|
|
76596
76617
|
let skillCount = 0;
|
|
76597
76618
|
if (exists) {
|
|
76598
76619
|
try {
|
|
76599
|
-
skillCount =
|
|
76620
|
+
skillCount = readdirSync7(agentSkillsPath).filter((f) => {
|
|
76600
76621
|
const full = join15(agentSkillsPath, f);
|
|
76601
|
-
return !f.startsWith(".") &&
|
|
76622
|
+
return !f.startsWith(".") && statSync6(full).isDirectory();
|
|
76602
76623
|
}).length;
|
|
76603
76624
|
} catch {}
|
|
76604
76625
|
}
|
|
@@ -77145,8 +77166,8 @@ import {
|
|
|
77145
77166
|
existsSync as existsSync18,
|
|
77146
77167
|
mkdirSync as mkdirSync8,
|
|
77147
77168
|
readFileSync as readFileSync15,
|
|
77148
|
-
readdirSync as
|
|
77149
|
-
statSync as
|
|
77169
|
+
readdirSync as readdirSync8,
|
|
77170
|
+
statSync as statSync7,
|
|
77150
77171
|
writeFileSync as writeFileSync9
|
|
77151
77172
|
} from "fs";
|
|
77152
77173
|
import { dirname as dirname5, join as join18, normalize as normalize3, relative as relative3, sep } from "path";
|
|
@@ -77281,9 +77302,9 @@ function parsePositiveInteger(value) {
|
|
|
77281
77302
|
}
|
|
77282
77303
|
function walkFiles2(dir) {
|
|
77283
77304
|
const files = [];
|
|
77284
|
-
for (const entry of
|
|
77305
|
+
for (const entry of readdirSync8(dir)) {
|
|
77285
77306
|
const full = join18(dir, entry);
|
|
77286
|
-
const stats =
|
|
77307
|
+
const stats = statSync7(full);
|
|
77287
77308
|
if (stats.isDirectory())
|
|
77288
77309
|
files.push(...walkFiles2(full));
|
|
77289
77310
|
else
|
package/bin/mcp.js
CHANGED
|
@@ -6510,7 +6510,7 @@ var require_dist = __commonJS((exports, module) => {
|
|
|
6510
6510
|
});
|
|
6511
6511
|
|
|
6512
6512
|
// src/lib/config.ts
|
|
6513
|
-
import { existsSync, readFileSync, writeFileSync, mkdirSync, copyFileSync } from "fs";
|
|
6513
|
+
import { existsSync, readFileSync, writeFileSync, mkdirSync, copyFileSync, readdirSync, statSync } from "fs";
|
|
6514
6514
|
import { join, dirname } from "path";
|
|
6515
6515
|
import { homedir } from "os";
|
|
6516
6516
|
function validKeys() {
|
|
@@ -6521,6 +6521,24 @@ function allowedValues(key) {
|
|
|
6521
6521
|
return MODE_VALUES;
|
|
6522
6522
|
return ENUM_KEYS[key];
|
|
6523
6523
|
}
|
|
6524
|
+
function mergeDirectoryContents(sourceDir, targetDir) {
|
|
6525
|
+
if (!existsSync(sourceDir))
|
|
6526
|
+
return;
|
|
6527
|
+
mkdirSync(targetDir, { recursive: true });
|
|
6528
|
+
for (const entry of readdirSync(sourceDir)) {
|
|
6529
|
+
const sourcePath = join(sourceDir, entry);
|
|
6530
|
+
const targetPath = join(targetDir, entry);
|
|
6531
|
+
try {
|
|
6532
|
+
const sourceStat = statSync(sourcePath);
|
|
6533
|
+
if (sourceStat.isDirectory()) {
|
|
6534
|
+
mergeDirectoryContents(sourcePath, targetPath);
|
|
6535
|
+
continue;
|
|
6536
|
+
}
|
|
6537
|
+
if (!existsSync(targetPath))
|
|
6538
|
+
copyFileSync(sourcePath, targetPath);
|
|
6539
|
+
} catch {}
|
|
6540
|
+
}
|
|
6541
|
+
}
|
|
6524
6542
|
function normalizeConfigValue(key, value) {
|
|
6525
6543
|
if (typeof value !== "string")
|
|
6526
6544
|
return;
|
|
@@ -6544,14 +6562,17 @@ function normalizeConfigValue(key, value) {
|
|
|
6544
6562
|
function getDataDir() {
|
|
6545
6563
|
const home = process.env["HOME"] || process.env["USERPROFILE"] || homedir();
|
|
6546
6564
|
const newDir = join(home, ".hasna", "skills");
|
|
6565
|
+
const oldDir = join(home, ".skills");
|
|
6547
6566
|
const oldConfigFile = join(home, ".skillsrc");
|
|
6567
|
+
mkdirSync(newDir, { recursive: true });
|
|
6568
|
+
try {
|
|
6569
|
+
mergeDirectoryContents(oldDir, newDir);
|
|
6570
|
+
} catch {}
|
|
6548
6571
|
if (existsSync(oldConfigFile) && !existsSync(join(newDir, "config.json"))) {
|
|
6549
|
-
mkdirSync(newDir, { recursive: true });
|
|
6550
6572
|
try {
|
|
6551
6573
|
copyFileSync(oldConfigFile, join(newDir, "config.json"));
|
|
6552
6574
|
} catch {}
|
|
6553
6575
|
}
|
|
6554
|
-
mkdirSync(newDir, { recursive: true });
|
|
6555
6576
|
return newDir;
|
|
6556
6577
|
}
|
|
6557
6578
|
function getConfigPath(scope) {
|
|
@@ -18270,7 +18291,7 @@ function finalize(ctx, schema) {
|
|
|
18270
18291
|
result.$schema = "http://json-schema.org/draft-07/schema#";
|
|
18271
18292
|
} else if (ctx.target === "draft-04") {
|
|
18272
18293
|
result.$schema = "http://json-schema.org/draft-04/schema#";
|
|
18273
|
-
} else if (ctx.target === "openapi-3.0") {}
|
|
18294
|
+
} else if (ctx.target === "openapi-3.0") {}
|
|
18274
18295
|
if (ctx.external?.uri) {
|
|
18275
18296
|
const id = ctx.external.registry.get(schema)?.id;
|
|
18276
18297
|
if (!id)
|
|
@@ -18518,7 +18539,7 @@ var literalProcessor = (schema, ctx, json, _params) => {
|
|
|
18518
18539
|
if (val === undefined) {
|
|
18519
18540
|
if (ctx.unrepresentable === "throw") {
|
|
18520
18541
|
throw new Error("Literal `undefined` cannot be represented in JSON Schema");
|
|
18521
|
-
}
|
|
18542
|
+
}
|
|
18522
18543
|
} else if (typeof val === "bigint") {
|
|
18523
18544
|
if (ctx.unrepresentable === "throw") {
|
|
18524
18545
|
throw new Error("BigInt literals cannot be represented in JSON Schema");
|
|
@@ -21798,7 +21819,7 @@ class StdioServerTransport {
|
|
|
21798
21819
|
// package.json
|
|
21799
21820
|
var package_default = {
|
|
21800
21821
|
name: "@hasna/skills",
|
|
21801
|
-
version: "0.1.
|
|
21822
|
+
version: "0.1.49",
|
|
21802
21823
|
description: "Skills library for AI coding agents",
|
|
21803
21824
|
type: "module",
|
|
21804
21825
|
bin: {
|
|
@@ -29481,7 +29502,7 @@ var EMPTY_COMPLETION_RESULT = {
|
|
|
29481
29502
|
|
|
29482
29503
|
// src/lib/registry.ts
|
|
29483
29504
|
init_config();
|
|
29484
|
-
import { existsSync as existsSync4, readFileSync as readFileSync4, readdirSync as
|
|
29505
|
+
import { existsSync as existsSync4, readFileSync as readFileSync4, readdirSync as readdirSync4 } from "fs";
|
|
29485
29506
|
import { join as join4 } from "path";
|
|
29486
29507
|
|
|
29487
29508
|
// src/lib/portable-skills.ts
|
|
@@ -29492,16 +29513,16 @@ import {
|
|
|
29492
29513
|
lstatSync as lstatSync2,
|
|
29493
29514
|
mkdirSync as mkdirSync2,
|
|
29494
29515
|
readFileSync as readFileSync3,
|
|
29495
|
-
readdirSync as
|
|
29516
|
+
readdirSync as readdirSync3,
|
|
29496
29517
|
rmSync,
|
|
29497
|
-
statSync as
|
|
29518
|
+
statSync as statSync3,
|
|
29498
29519
|
writeFileSync as writeFileSync2
|
|
29499
29520
|
} from "fs";
|
|
29500
29521
|
import { basename, dirname as dirname2, isAbsolute as isAbsolute2, join as join3, normalize as normalize2, relative } from "path";
|
|
29501
29522
|
|
|
29502
29523
|
// src/lib/skill-validation.ts
|
|
29503
29524
|
init_pricing();
|
|
29504
|
-
import { existsSync as existsSync2, lstatSync, readFileSync as readFileSync2, readdirSync, statSync } from "fs";
|
|
29525
|
+
import { existsSync as existsSync2, lstatSync, readFileSync as readFileSync2, readdirSync as readdirSync2, statSync as statSync2 } from "fs";
|
|
29505
29526
|
import { isAbsolute, join as join2, normalize } from "path";
|
|
29506
29527
|
var DOC_FILES = ["SKILL.md", "README.md", "CLAUDE.md"];
|
|
29507
29528
|
var RESERVED_SKILL_ENTRIES = new Set([
|
|
@@ -29657,7 +29678,7 @@ function validateSkillDirectory(name, skillPath, registryMeta) {
|
|
|
29657
29678
|
if (!VALID_BIN_COMMAND.test(bareName)) {
|
|
29658
29679
|
add(issues, "skill.name_invalid", `Skill name '${bareName}' must use lowercase letters, numbers, dots, underscores, or hyphens`);
|
|
29659
29680
|
}
|
|
29660
|
-
for (const entry of
|
|
29681
|
+
for (const entry of readdirSync2(skillPath).sort()) {
|
|
29661
29682
|
const entryPath = join2(skillPath, entry);
|
|
29662
29683
|
if (RESERVED_SKILL_ENTRIES.has(entry)) {
|
|
29663
29684
|
add(issues, "skill.reserved_file", `Reserved file '${entry}' is not allowed in skill packages`);
|
|
@@ -29772,7 +29793,7 @@ function validateSkillDirectory(name, skillPath, registryMeta) {
|
|
|
29772
29793
|
const targetPath = join2(skillPath, target);
|
|
29773
29794
|
if (!existsSync2(targetPath)) {
|
|
29774
29795
|
add(warnings, "package.bin_target_missing", `package.json bin '${command}' target '${target}' is not present before build`);
|
|
29775
|
-
} else if (
|
|
29796
|
+
} else if (statSync2(targetPath).isDirectory()) {
|
|
29776
29797
|
add(issues, "package.bin_target_directory", `package.json bin '${command}' target '${target}' must point to a file, not a directory`);
|
|
29777
29798
|
}
|
|
29778
29799
|
}
|
|
@@ -29795,7 +29816,7 @@ function validateSkillDirectory(name, skillPath, registryMeta) {
|
|
|
29795
29816
|
add(issues, "skill.src_index_missing", "Missing src/index.ts or src/index.js");
|
|
29796
29817
|
} else {
|
|
29797
29818
|
const indexPath = existsSync2(join2(srcDir, "index.ts")) ? join2(srcDir, "index.ts") : join2(srcDir, "index.js");
|
|
29798
|
-
const size =
|
|
29819
|
+
const size = statSync2(indexPath).size;
|
|
29799
29820
|
if (size < 50)
|
|
29800
29821
|
add(warnings, "skill.src_index_minimal", `Source entry point is very small (${size}B)`);
|
|
29801
29822
|
}
|
|
@@ -29862,7 +29883,7 @@ function findPortableSkill(name, options = {}) {
|
|
|
29862
29883
|
return null;
|
|
29863
29884
|
}
|
|
29864
29885
|
const path = getPortableSkillPath(normalized, options);
|
|
29865
|
-
if (!existsSync3(path) || !
|
|
29886
|
+
if (!existsSync3(path) || !statSync3(path).isDirectory())
|
|
29866
29887
|
return null;
|
|
29867
29888
|
try {
|
|
29868
29889
|
return summarizePortableSkill(path, normalized);
|
|
@@ -29875,7 +29896,7 @@ function listPortableSkills(options = {}) {
|
|
|
29875
29896
|
if (!existsSync3(root))
|
|
29876
29897
|
return [];
|
|
29877
29898
|
const skills = [];
|
|
29878
|
-
for (const entry of
|
|
29899
|
+
for (const entry of readdirSync3(root).sort()) {
|
|
29879
29900
|
if (entry.startsWith(".") || DATA_DIR_NON_SKILL_ENTRIES.has(entry))
|
|
29880
29901
|
continue;
|
|
29881
29902
|
const path = join3(root, entry);
|
|
@@ -29951,7 +29972,7 @@ function scaffoldPortableSkill(name, options = {}) {
|
|
|
29951
29972
|
}
|
|
29952
29973
|
function portPortableSkill(sourcePath, options = {}) {
|
|
29953
29974
|
const absoluteSource = normalize2(sourcePath);
|
|
29954
|
-
if (!existsSync3(absoluteSource) || !
|
|
29975
|
+
if (!existsSync3(absoluteSource) || !statSync3(absoluteSource).isDirectory()) {
|
|
29955
29976
|
throw new Error(`Skill source directory not found: ${sourcePath}`);
|
|
29956
29977
|
}
|
|
29957
29978
|
const inferred = readPortableSkillManifest(absoluteSource, basename(absoluteSource));
|
|
@@ -30020,7 +30041,7 @@ function validatePortableSkillDirectory(name, skillPath) {
|
|
|
30020
30041
|
const entryPath = join3(skillPath, command.entry);
|
|
30021
30042
|
if (!existsSync3(entryPath))
|
|
30022
30043
|
add2(issues, "portable.command_entry_missing", `Command '${command.name}' entry '${command.entry}' is missing`);
|
|
30023
|
-
else if (
|
|
30044
|
+
else if (statSync3(entryPath).isDirectory())
|
|
30024
30045
|
add2(issues, "portable.command_entry_directory", `Command '${command.name}' entry '${command.entry}' must be a file`);
|
|
30025
30046
|
}
|
|
30026
30047
|
}
|
|
@@ -30388,7 +30409,7 @@ function displayName(name) {
|
|
|
30388
30409
|
}
|
|
30389
30410
|
function safeIsDirectory(path) {
|
|
30390
30411
|
try {
|
|
30391
|
-
return
|
|
30412
|
+
return statSync3(path).isDirectory();
|
|
30392
30413
|
} catch {
|
|
30393
30414
|
return false;
|
|
30394
30415
|
}
|
|
@@ -32384,7 +32405,7 @@ function discoverSkillsInDir(dir) {
|
|
|
32384
32405
|
return [];
|
|
32385
32406
|
const result = [];
|
|
32386
32407
|
try {
|
|
32387
|
-
const entries =
|
|
32408
|
+
const entries = readdirSync4(dir, { withFileTypes: true });
|
|
32388
32409
|
for (const entry of entries) {
|
|
32389
32410
|
if (!entry.isDirectory())
|
|
32390
32411
|
continue;
|
|
@@ -34100,12 +34121,12 @@ function registerDiscoveryTools(server) {
|
|
|
34100
34121
|
}
|
|
34101
34122
|
|
|
34102
34123
|
// src/mcp/operation-tools.ts
|
|
34103
|
-
import { existsSync as existsSync10, readdirSync as
|
|
34124
|
+
import { existsSync as existsSync10, readdirSync as readdirSync6, statSync as statSync5 } from "fs";
|
|
34104
34125
|
import { join as join10 } from "path";
|
|
34105
34126
|
|
|
34106
34127
|
// src/lib/run-state.ts
|
|
34107
34128
|
import { createHash, randomBytes } from "crypto";
|
|
34108
|
-
import { existsSync as existsSync8, mkdirSync as mkdirSync4, readFileSync as readFileSync8, readdirSync as
|
|
34129
|
+
import { existsSync as existsSync8, mkdirSync as mkdirSync4, readFileSync as readFileSync8, readdirSync as readdirSync5, statSync as statSync4, writeFileSync as writeFileSync4 } from "fs";
|
|
34109
34130
|
import { extname, join as join8, relative as relative2 } from "path";
|
|
34110
34131
|
function createSkillRun(params, targetDir = process.cwd()) {
|
|
34111
34132
|
const now = new Date;
|
|
@@ -34179,7 +34200,7 @@ function findSkillRun(runId, targetDir = process.cwd()) {
|
|
|
34179
34200
|
const runsRoot = join8(getProjectStateDir(targetDir), "runs");
|
|
34180
34201
|
if (!existsSync8(runsRoot))
|
|
34181
34202
|
return null;
|
|
34182
|
-
for (const day of
|
|
34203
|
+
for (const day of readdirSync5(runsRoot)) {
|
|
34183
34204
|
const record3 = readRunRecord(join8(runsRoot, day, runId));
|
|
34184
34205
|
if (record3)
|
|
34185
34206
|
return record3;
|
|
@@ -34199,7 +34220,7 @@ function collectRunArtifacts(context) {
|
|
|
34199
34220
|
return [];
|
|
34200
34221
|
const artifacts = [];
|
|
34201
34222
|
for (const path of walkFiles(context.exportDir)) {
|
|
34202
|
-
const stat =
|
|
34223
|
+
const stat = statSync4(path);
|
|
34203
34224
|
const bytes = readFileSync8(path);
|
|
34204
34225
|
artifacts.push({
|
|
34205
34226
|
path: toProjectRelative(context.targetDir, path),
|
|
@@ -34222,9 +34243,9 @@ function readRunRecord(runDir) {
|
|
|
34222
34243
|
}
|
|
34223
34244
|
function walkFiles(dir) {
|
|
34224
34245
|
const files = [];
|
|
34225
|
-
for (const entry of
|
|
34246
|
+
for (const entry of readdirSync5(dir)) {
|
|
34226
34247
|
const full = join8(dir, entry);
|
|
34227
|
-
if (
|
|
34248
|
+
if (statSync4(full).isDirectory())
|
|
34228
34249
|
files.push(...walkFiles(full));
|
|
34229
34250
|
else
|
|
34230
34251
|
files.push(full);
|
|
@@ -34717,9 +34738,9 @@ function registerOperationTools(server) {
|
|
|
34717
34738
|
let skillCount = 0;
|
|
34718
34739
|
if (exists) {
|
|
34719
34740
|
try {
|
|
34720
|
-
skillCount =
|
|
34741
|
+
skillCount = readdirSync6(agentSkillsPath).filter((f) => {
|
|
34721
34742
|
const full = join10(agentSkillsPath, f);
|
|
34722
|
-
return !f.startsWith(".") &&
|
|
34743
|
+
return !f.startsWith(".") && statSync5(full).isDirectory();
|
|
34723
34744
|
}).length;
|
|
34724
34745
|
} catch {}
|
|
34725
34746
|
}
|
|
@@ -35207,8 +35228,8 @@ import {
|
|
|
35207
35228
|
existsSync as existsSync13,
|
|
35208
35229
|
mkdirSync as mkdirSync8,
|
|
35209
35230
|
readFileSync as readFileSync11,
|
|
35210
|
-
readdirSync as
|
|
35211
|
-
statSync as
|
|
35231
|
+
readdirSync as readdirSync7,
|
|
35232
|
+
statSync as statSync6,
|
|
35212
35233
|
writeFileSync as writeFileSync7
|
|
35213
35234
|
} from "fs";
|
|
35214
35235
|
import { dirname as dirname5, join as join13, normalize as normalize3, relative as relative3, sep } from "path";
|
|
@@ -35402,9 +35423,9 @@ function parsePositiveInteger(value) {
|
|
|
35402
35423
|
}
|
|
35403
35424
|
function walkFiles2(dir) {
|
|
35404
35425
|
const files = [];
|
|
35405
|
-
for (const entry of
|
|
35426
|
+
for (const entry of readdirSync7(dir)) {
|
|
35406
35427
|
const full = join13(dir, entry);
|
|
35407
|
-
const stats =
|
|
35428
|
+
const stats = statSync6(full);
|
|
35408
35429
|
if (stats.isDirectory())
|
|
35409
35430
|
files.push(...walkFiles2(full));
|
|
35410
35431
|
else
|
package/dist/index.js
CHANGED
|
@@ -15,11 +15,11 @@ var __export = (target, all) => {
|
|
|
15
15
|
};
|
|
16
16
|
|
|
17
17
|
// src/lib/registry.ts
|
|
18
|
-
import { existsSync as existsSync4, readFileSync as readFileSync4, readdirSync as
|
|
18
|
+
import { existsSync as existsSync4, readFileSync as readFileSync4, readdirSync as readdirSync4 } from "fs";
|
|
19
19
|
import { join as join4 } from "path";
|
|
20
20
|
|
|
21
21
|
// src/lib/config.ts
|
|
22
|
-
import { existsSync, readFileSync, writeFileSync, mkdirSync, copyFileSync } from "fs";
|
|
22
|
+
import { existsSync, readFileSync, writeFileSync, mkdirSync, copyFileSync, readdirSync, statSync } from "fs";
|
|
23
23
|
import { join, dirname } from "path";
|
|
24
24
|
import { homedir } from "os";
|
|
25
25
|
var ENUM_KEYS = {
|
|
@@ -45,6 +45,24 @@ function allowedValues(key) {
|
|
|
45
45
|
return MODE_VALUES;
|
|
46
46
|
return ENUM_KEYS[key];
|
|
47
47
|
}
|
|
48
|
+
function mergeDirectoryContents(sourceDir, targetDir) {
|
|
49
|
+
if (!existsSync(sourceDir))
|
|
50
|
+
return;
|
|
51
|
+
mkdirSync(targetDir, { recursive: true });
|
|
52
|
+
for (const entry of readdirSync(sourceDir)) {
|
|
53
|
+
const sourcePath = join(sourceDir, entry);
|
|
54
|
+
const targetPath = join(targetDir, entry);
|
|
55
|
+
try {
|
|
56
|
+
const sourceStat = statSync(sourcePath);
|
|
57
|
+
if (sourceStat.isDirectory()) {
|
|
58
|
+
mergeDirectoryContents(sourcePath, targetPath);
|
|
59
|
+
continue;
|
|
60
|
+
}
|
|
61
|
+
if (!existsSync(targetPath))
|
|
62
|
+
copyFileSync(sourcePath, targetPath);
|
|
63
|
+
} catch {}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
48
66
|
function normalizeConfigValue(key, value) {
|
|
49
67
|
if (typeof value !== "string")
|
|
50
68
|
return;
|
|
@@ -68,14 +86,17 @@ function normalizeConfigValue(key, value) {
|
|
|
68
86
|
function getDataDir() {
|
|
69
87
|
const home = process.env["HOME"] || process.env["USERPROFILE"] || homedir();
|
|
70
88
|
const newDir = join(home, ".hasna", "skills");
|
|
89
|
+
const oldDir = join(home, ".skills");
|
|
71
90
|
const oldConfigFile = join(home, ".skillsrc");
|
|
91
|
+
mkdirSync(newDir, { recursive: true });
|
|
92
|
+
try {
|
|
93
|
+
mergeDirectoryContents(oldDir, newDir);
|
|
94
|
+
} catch {}
|
|
72
95
|
if (existsSync(oldConfigFile) && !existsSync(join(newDir, "config.json"))) {
|
|
73
|
-
mkdirSync(newDir, { recursive: true });
|
|
74
96
|
try {
|
|
75
97
|
copyFileSync(oldConfigFile, join(newDir, "config.json"));
|
|
76
98
|
} catch {}
|
|
77
99
|
}
|
|
78
|
-
mkdirSync(newDir, { recursive: true });
|
|
79
100
|
return newDir;
|
|
80
101
|
}
|
|
81
102
|
function getConfigPath(scope) {
|
|
@@ -146,15 +167,15 @@ import {
|
|
|
146
167
|
lstatSync as lstatSync2,
|
|
147
168
|
mkdirSync as mkdirSync2,
|
|
148
169
|
readFileSync as readFileSync3,
|
|
149
|
-
readdirSync as
|
|
170
|
+
readdirSync as readdirSync3,
|
|
150
171
|
rmSync,
|
|
151
|
-
statSync as
|
|
172
|
+
statSync as statSync3,
|
|
152
173
|
writeFileSync as writeFileSync2
|
|
153
174
|
} from "fs";
|
|
154
175
|
import { basename, dirname as dirname2, isAbsolute as isAbsolute2, join as join3, normalize as normalize2, relative } from "path";
|
|
155
176
|
|
|
156
177
|
// src/lib/skill-validation.ts
|
|
157
|
-
import { existsSync as existsSync2, lstatSync, readFileSync as readFileSync2, readdirSync, statSync } from "fs";
|
|
178
|
+
import { existsSync as existsSync2, lstatSync, readFileSync as readFileSync2, readdirSync as readdirSync2, statSync as statSync2 } from "fs";
|
|
158
179
|
import { isAbsolute, join as join2, normalize } from "path";
|
|
159
180
|
|
|
160
181
|
// src/lib/skill-aliases.ts
|
|
@@ -788,7 +809,7 @@ function validateSkillDirectory(name, skillPath, registryMeta) {
|
|
|
788
809
|
if (!VALID_BIN_COMMAND.test(bareName)) {
|
|
789
810
|
add(issues, "skill.name_invalid", `Skill name '${bareName}' must use lowercase letters, numbers, dots, underscores, or hyphens`);
|
|
790
811
|
}
|
|
791
|
-
for (const entry of
|
|
812
|
+
for (const entry of readdirSync2(skillPath).sort()) {
|
|
792
813
|
const entryPath = join2(skillPath, entry);
|
|
793
814
|
if (RESERVED_SKILL_ENTRIES.has(entry)) {
|
|
794
815
|
add(issues, "skill.reserved_file", `Reserved file '${entry}' is not allowed in skill packages`);
|
|
@@ -903,7 +924,7 @@ function validateSkillDirectory(name, skillPath, registryMeta) {
|
|
|
903
924
|
const targetPath = join2(skillPath, target);
|
|
904
925
|
if (!existsSync2(targetPath)) {
|
|
905
926
|
add(warnings, "package.bin_target_missing", `package.json bin '${command}' target '${target}' is not present before build`);
|
|
906
|
-
} else if (
|
|
927
|
+
} else if (statSync2(targetPath).isDirectory()) {
|
|
907
928
|
add(issues, "package.bin_target_directory", `package.json bin '${command}' target '${target}' must point to a file, not a directory`);
|
|
908
929
|
}
|
|
909
930
|
}
|
|
@@ -926,7 +947,7 @@ function validateSkillDirectory(name, skillPath, registryMeta) {
|
|
|
926
947
|
add(issues, "skill.src_index_missing", "Missing src/index.ts or src/index.js");
|
|
927
948
|
} else {
|
|
928
949
|
const indexPath = existsSync2(join2(srcDir, "index.ts")) ? join2(srcDir, "index.ts") : join2(srcDir, "index.js");
|
|
929
|
-
const size =
|
|
950
|
+
const size = statSync2(indexPath).size;
|
|
930
951
|
if (size < 50)
|
|
931
952
|
add(warnings, "skill.src_index_minimal", `Source entry point is very small (${size}B)`);
|
|
932
953
|
}
|
|
@@ -948,9 +969,9 @@ function validateRegistryConsistency(registry, skillsDir) {
|
|
|
948
969
|
seen.add(name);
|
|
949
970
|
return false;
|
|
950
971
|
})));
|
|
951
|
-
const skillDirs = existsSync2(skillsDir) ?
|
|
972
|
+
const skillDirs = existsSync2(skillsDir) ? readdirSync2(skillsDir).filter((entry) => {
|
|
952
973
|
const fullPath = join2(skillsDir, entry);
|
|
953
|
-
return !entry.startsWith(".") && entry !== "_common" &&
|
|
974
|
+
return !entry.startsWith(".") && entry !== "_common" && statSync2(fullPath).isDirectory();
|
|
954
975
|
}) : [];
|
|
955
976
|
const directoryNames = new Set(skillDirs);
|
|
956
977
|
const registryNameSet = new Set(registryNames);
|
|
@@ -1017,7 +1038,7 @@ function findPortableSkill(name, options = {}) {
|
|
|
1017
1038
|
return null;
|
|
1018
1039
|
}
|
|
1019
1040
|
const path = getPortableSkillPath(normalized, options);
|
|
1020
|
-
if (!existsSync3(path) || !
|
|
1041
|
+
if (!existsSync3(path) || !statSync3(path).isDirectory())
|
|
1021
1042
|
return null;
|
|
1022
1043
|
try {
|
|
1023
1044
|
return summarizePortableSkill(path, normalized);
|
|
@@ -1030,7 +1051,7 @@ function listPortableSkills(options = {}) {
|
|
|
1030
1051
|
if (!existsSync3(root))
|
|
1031
1052
|
return [];
|
|
1032
1053
|
const skills = [];
|
|
1033
|
-
for (const entry of
|
|
1054
|
+
for (const entry of readdirSync3(root).sort()) {
|
|
1034
1055
|
if (entry.startsWith(".") || DATA_DIR_NON_SKILL_ENTRIES.has(entry))
|
|
1035
1056
|
continue;
|
|
1036
1057
|
const path = join3(root, entry);
|
|
@@ -1106,7 +1127,7 @@ function scaffoldPortableSkill(name, options = {}) {
|
|
|
1106
1127
|
}
|
|
1107
1128
|
function portPortableSkill(sourcePath, options = {}) {
|
|
1108
1129
|
const absoluteSource = normalize2(sourcePath);
|
|
1109
|
-
if (!existsSync3(absoluteSource) || !
|
|
1130
|
+
if (!existsSync3(absoluteSource) || !statSync3(absoluteSource).isDirectory()) {
|
|
1110
1131
|
throw new Error(`Skill source directory not found: ${sourcePath}`);
|
|
1111
1132
|
}
|
|
1112
1133
|
const inferred = readPortableSkillManifest(absoluteSource, basename(absoluteSource));
|
|
@@ -1175,7 +1196,7 @@ function validatePortableSkillDirectory(name, skillPath) {
|
|
|
1175
1196
|
const entryPath = join3(skillPath, command.entry);
|
|
1176
1197
|
if (!existsSync3(entryPath))
|
|
1177
1198
|
add2(issues, "portable.command_entry_missing", `Command '${command.name}' entry '${command.entry}' is missing`);
|
|
1178
|
-
else if (
|
|
1199
|
+
else if (statSync3(entryPath).isDirectory())
|
|
1179
1200
|
add2(issues, "portable.command_entry_directory", `Command '${command.name}' entry '${command.entry}' must be a file`);
|
|
1180
1201
|
}
|
|
1181
1202
|
}
|
|
@@ -1596,7 +1617,7 @@ function displayName(name) {
|
|
|
1596
1617
|
}
|
|
1597
1618
|
function safeIsDirectory(path) {
|
|
1598
1619
|
try {
|
|
1599
|
-
return
|
|
1620
|
+
return statSync3(path).isDirectory();
|
|
1600
1621
|
} catch {
|
|
1601
1622
|
return false;
|
|
1602
1623
|
}
|
|
@@ -3592,7 +3613,7 @@ function discoverSkillsInDir(dir) {
|
|
|
3592
3613
|
return [];
|
|
3593
3614
|
const result = [];
|
|
3594
3615
|
try {
|
|
3595
|
-
const entries =
|
|
3616
|
+
const entries = readdirSync4(dir, { withFileTypes: true });
|
|
3596
3617
|
for (const entry of entries) {
|
|
3597
3618
|
if (!entry.isDirectory())
|
|
3598
3619
|
continue;
|
|
@@ -4063,7 +4084,7 @@ function loadProjectConfigCompat(targetDir) {
|
|
|
4063
4084
|
}
|
|
4064
4085
|
// src/lib/run-state.ts
|
|
4065
4086
|
import { createHash, randomBytes } from "crypto";
|
|
4066
|
-
import { existsSync as existsSync7, mkdirSync as mkdirSync4, readFileSync as readFileSync7, readdirSync as
|
|
4087
|
+
import { existsSync as existsSync7, mkdirSync as mkdirSync4, readFileSync as readFileSync7, readdirSync as readdirSync5, statSync as statSync4, writeFileSync as writeFileSync4 } from "fs";
|
|
4067
4088
|
import { extname, join as join7, relative as relative2 } from "path";
|
|
4068
4089
|
function createSkillRun(params, targetDir = process.cwd()) {
|
|
4069
4090
|
const now = new Date;
|
|
@@ -4138,11 +4159,11 @@ function listSkillRuns(targetDir = process.cwd(), limit = 50) {
|
|
|
4138
4159
|
if (!existsSync7(runsRoot))
|
|
4139
4160
|
return [];
|
|
4140
4161
|
const records = [];
|
|
4141
|
-
for (const day of
|
|
4162
|
+
for (const day of readdirSync5(runsRoot).sort().reverse()) {
|
|
4142
4163
|
const dayDir = join7(runsRoot, day);
|
|
4143
|
-
if (!
|
|
4164
|
+
if (!statSync4(dayDir).isDirectory())
|
|
4144
4165
|
continue;
|
|
4145
|
-
for (const runId of
|
|
4166
|
+
for (const runId of readdirSync5(dayDir).sort().reverse()) {
|
|
4146
4167
|
const record = readRunRecord(join7(dayDir, runId));
|
|
4147
4168
|
if (record)
|
|
4148
4169
|
records.push(record);
|
|
@@ -4156,7 +4177,7 @@ function findSkillRun(runId, targetDir = process.cwd()) {
|
|
|
4156
4177
|
const runsRoot = join7(getProjectStateDir(targetDir), "runs");
|
|
4157
4178
|
if (!existsSync7(runsRoot))
|
|
4158
4179
|
return null;
|
|
4159
|
-
for (const day of
|
|
4180
|
+
for (const day of readdirSync5(runsRoot)) {
|
|
4160
4181
|
const record = readRunRecord(join7(runsRoot, day, runId));
|
|
4161
4182
|
if (record)
|
|
4162
4183
|
return record;
|
|
@@ -4179,7 +4200,7 @@ function collectRunArtifacts(context) {
|
|
|
4179
4200
|
return [];
|
|
4180
4201
|
const artifacts = [];
|
|
4181
4202
|
for (const path of walkFiles(context.exportDir)) {
|
|
4182
|
-
const stat =
|
|
4203
|
+
const stat = statSync4(path);
|
|
4183
4204
|
const bytes = readFileSync7(path);
|
|
4184
4205
|
artifacts.push({
|
|
4185
4206
|
path: toProjectRelative(context.targetDir, path),
|
|
@@ -4202,9 +4223,9 @@ function readRunRecord(runDir) {
|
|
|
4202
4223
|
}
|
|
4203
4224
|
function walkFiles(dir) {
|
|
4204
4225
|
const files = [];
|
|
4205
|
-
for (const entry of
|
|
4226
|
+
for (const entry of readdirSync5(dir)) {
|
|
4206
4227
|
const full = join7(dir, entry);
|
|
4207
|
-
if (
|
|
4228
|
+
if (statSync4(full).isDirectory())
|
|
4208
4229
|
files.push(...walkFiles(full));
|
|
4209
4230
|
else
|
|
4210
4231
|
files.push(full);
|
|
@@ -15483,7 +15504,7 @@ function finalize(ctx, schema) {
|
|
|
15483
15504
|
result.$schema = "http://json-schema.org/draft-07/schema#";
|
|
15484
15505
|
} else if (ctx.target === "draft-04") {
|
|
15485
15506
|
result.$schema = "http://json-schema.org/draft-04/schema#";
|
|
15486
|
-
} else if (ctx.target === "openapi-3.0") {}
|
|
15507
|
+
} else if (ctx.target === "openapi-3.0") {}
|
|
15487
15508
|
if (ctx.external?.uri) {
|
|
15488
15509
|
const id = ctx.external.registry.get(schema)?.id;
|
|
15489
15510
|
if (!id)
|
|
@@ -15731,7 +15752,7 @@ var literalProcessor = (schema, ctx, json, _params) => {
|
|
|
15731
15752
|
if (val === undefined) {
|
|
15732
15753
|
if (ctx.unrepresentable === "throw") {
|
|
15733
15754
|
throw new Error("Literal `undefined` cannot be represented in JSON Schema");
|
|
15734
|
-
}
|
|
15755
|
+
}
|
|
15735
15756
|
} else if (typeof val === "bigint") {
|
|
15736
15757
|
if (ctx.unrepresentable === "throw") {
|
|
15737
15758
|
throw new Error("BigInt literals cannot be represented in JSON Schema");
|
|
@@ -18812,7 +18833,7 @@ import { dirname as dirname4, relative as relative3 } from "path";
|
|
|
18812
18833
|
// package.json
|
|
18813
18834
|
var package_default = {
|
|
18814
18835
|
name: "@hasna/skills",
|
|
18815
|
-
version: "0.1.
|
|
18836
|
+
version: "0.1.49",
|
|
18816
18837
|
description: "Skills library for AI coding agents",
|
|
18817
18838
|
type: "module",
|
|
18818
18839
|
bin: {
|
|
@@ -19795,8 +19816,8 @@ import {
|
|
|
19795
19816
|
existsSync as existsSync12,
|
|
19796
19817
|
mkdirSync as mkdirSync9,
|
|
19797
19818
|
readFileSync as readFileSync11,
|
|
19798
|
-
readdirSync as
|
|
19799
|
-
statSync as
|
|
19819
|
+
readdirSync as readdirSync6,
|
|
19820
|
+
statSync as statSync5,
|
|
19800
19821
|
writeFileSync as writeFileSync8
|
|
19801
19822
|
} from "fs";
|
|
19802
19823
|
import { dirname as dirname6, join as join12, normalize as normalize3, relative as relative4, sep } from "path";
|
|
@@ -20258,9 +20279,9 @@ function parsePositiveInteger(value) {
|
|
|
20258
20279
|
}
|
|
20259
20280
|
function walkFiles2(dir) {
|
|
20260
20281
|
const files = [];
|
|
20261
|
-
for (const entry of
|
|
20282
|
+
for (const entry of readdirSync6(dir)) {
|
|
20262
20283
|
const full = join12(dir, entry);
|
|
20263
|
-
const stats =
|
|
20284
|
+
const stats = statSync5(full);
|
|
20264
20285
|
if (stats.isDirectory())
|
|
20265
20286
|
files.push(...walkFiles2(full));
|
|
20266
20287
|
else
|
package/dist/lib/config.d.ts
CHANGED
|
@@ -19,7 +19,7 @@ export type ConfigScope = "global" | "project";
|
|
|
19
19
|
/**
|
|
20
20
|
* Get the data directory for skills global config/data.
|
|
21
21
|
* New default: ~/.hasna/skills/
|
|
22
|
-
* Auto-migrates from ~/.
|
|
22
|
+
* Auto-migrates from ~/.skills/ and ~/.skillsrc without deleting legacy data.
|
|
23
23
|
*/
|
|
24
24
|
export declare function getDataDir(): string;
|
|
25
25
|
/**
|
package/dist/storage.js
CHANGED
|
@@ -20,14 +20,14 @@ import {
|
|
|
20
20
|
existsSync as existsSync3,
|
|
21
21
|
mkdirSync as mkdirSync3,
|
|
22
22
|
readFileSync as readFileSync3,
|
|
23
|
-
readdirSync,
|
|
24
|
-
statSync,
|
|
23
|
+
readdirSync as readdirSync2,
|
|
24
|
+
statSync as statSync2,
|
|
25
25
|
writeFileSync as writeFileSync3
|
|
26
26
|
} from "fs";
|
|
27
27
|
import { dirname as dirname2, join as join3, normalize, relative, sep } from "path";
|
|
28
28
|
|
|
29
29
|
// src/lib/config.ts
|
|
30
|
-
import { existsSync, readFileSync, writeFileSync, mkdirSync, copyFileSync } from "fs";
|
|
30
|
+
import { existsSync, readFileSync, writeFileSync, mkdirSync, copyFileSync, readdirSync, statSync } from "fs";
|
|
31
31
|
import { join, dirname } from "path";
|
|
32
32
|
import { homedir } from "os";
|
|
33
33
|
var ENUM_KEYS = {
|
|
@@ -53,6 +53,24 @@ function allowedValues(key) {
|
|
|
53
53
|
return MODE_VALUES;
|
|
54
54
|
return ENUM_KEYS[key];
|
|
55
55
|
}
|
|
56
|
+
function mergeDirectoryContents(sourceDir, targetDir) {
|
|
57
|
+
if (!existsSync(sourceDir))
|
|
58
|
+
return;
|
|
59
|
+
mkdirSync(targetDir, { recursive: true });
|
|
60
|
+
for (const entry of readdirSync(sourceDir)) {
|
|
61
|
+
const sourcePath = join(sourceDir, entry);
|
|
62
|
+
const targetPath = join(targetDir, entry);
|
|
63
|
+
try {
|
|
64
|
+
const sourceStat = statSync(sourcePath);
|
|
65
|
+
if (sourceStat.isDirectory()) {
|
|
66
|
+
mergeDirectoryContents(sourcePath, targetPath);
|
|
67
|
+
continue;
|
|
68
|
+
}
|
|
69
|
+
if (!existsSync(targetPath))
|
|
70
|
+
copyFileSync(sourcePath, targetPath);
|
|
71
|
+
} catch {}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
56
74
|
function normalizeConfigValue(key, value) {
|
|
57
75
|
if (typeof value !== "string")
|
|
58
76
|
return;
|
|
@@ -76,14 +94,17 @@ function normalizeConfigValue(key, value) {
|
|
|
76
94
|
function getDataDir() {
|
|
77
95
|
const home = process.env["HOME"] || process.env["USERPROFILE"] || homedir();
|
|
78
96
|
const newDir = join(home, ".hasna", "skills");
|
|
97
|
+
const oldDir = join(home, ".skills");
|
|
79
98
|
const oldConfigFile = join(home, ".skillsrc");
|
|
99
|
+
mkdirSync(newDir, { recursive: true });
|
|
100
|
+
try {
|
|
101
|
+
mergeDirectoryContents(oldDir, newDir);
|
|
102
|
+
} catch {}
|
|
80
103
|
if (existsSync(oldConfigFile) && !existsSync(join(newDir, "config.json"))) {
|
|
81
|
-
mkdirSync(newDir, { recursive: true });
|
|
82
104
|
try {
|
|
83
105
|
copyFileSync(oldConfigFile, join(newDir, "config.json"));
|
|
84
106
|
} catch {}
|
|
85
107
|
}
|
|
86
|
-
mkdirSync(newDir, { recursive: true });
|
|
87
108
|
return newDir;
|
|
88
109
|
}
|
|
89
110
|
function getConfigPath(scope) {
|
|
@@ -743,9 +764,9 @@ function parsePositiveInteger(value) {
|
|
|
743
764
|
}
|
|
744
765
|
function walkFiles(dir) {
|
|
745
766
|
const files = [];
|
|
746
|
-
for (const entry of
|
|
767
|
+
for (const entry of readdirSync2(dir)) {
|
|
747
768
|
const full = join3(dir, entry);
|
|
748
|
-
const stats =
|
|
769
|
+
const stats = statSync2(full);
|
|
749
770
|
if (stats.isDirectory())
|
|
750
771
|
files.push(...walkFiles(full));
|
|
751
772
|
else
|
package/package.json
CHANGED