@hasna/skills 0.6.1 → 0.6.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/index.js +73 -44
- package/bin/mcp.js +1 -1
- package/bin/migrate.js +1 -1
- package/bin/server.js +1 -1
- package/bin/worker.js +1 -1
- package/dist/index.js +56 -27
- package/dist/sdk/index.js +56 -27
- package/package.json +1 -1
package/bin/index.js
CHANGED
|
@@ -36868,7 +36868,7 @@ var package_default;
|
|
|
36868
36868
|
var init_package = __esm(() => {
|
|
36869
36869
|
package_default = {
|
|
36870
36870
|
name: "@hasna/skills",
|
|
36871
|
-
version: "0.6.
|
|
36871
|
+
version: "0.6.2",
|
|
36872
36872
|
description: "Skills library for AI coding agents",
|
|
36873
36873
|
type: "module",
|
|
36874
36874
|
bin: {
|
|
@@ -43006,7 +43006,7 @@ var require_cli_spinners = __commonJS((exports, module) => {
|
|
|
43006
43006
|
|
|
43007
43007
|
// src/lib/agent-integration.ts
|
|
43008
43008
|
import { createHash as createHash2, randomUUID as randomUUID3 } from "crypto";
|
|
43009
|
-
import { existsSync as existsSync13, lstatSync as lstatSync3, mkdirSync as mkdirSync4, readFileSync as readFileSync8, readdirSync as readdirSync7, readlinkSync, realpathSync as realpathSync3, renameSync as renameSync2, writeFileSync as writeFileSync4, unlinkSync, chmodSync } from "fs";
|
|
43009
|
+
import { existsSync as existsSync13, lstatSync as lstatSync3, statSync as statSync7, mkdirSync as mkdirSync4, readFileSync as readFileSync8, readdirSync as readdirSync7, readlinkSync, realpathSync as realpathSync3, renameSync as renameSync2, writeFileSync as writeFileSync4, unlinkSync, chmodSync } from "fs";
|
|
43010
43010
|
import { dirname as dirname4, join as join13, resolve as resolve4, relative as relative3, isAbsolute as isAbsolute3, sep as sep3 } from "path";
|
|
43011
43011
|
import { homedir as homedir3 } from "os";
|
|
43012
43012
|
function assertSafePath(path) {
|
|
@@ -43094,15 +43094,27 @@ function inventoryNativeSkills(home = homedir3(), options = {}) {
|
|
|
43094
43094
|
for (const [agent, path] of ROOTS)
|
|
43095
43095
|
roots.push([agent, join13(resolve4(options.projectDir), path)]);
|
|
43096
43096
|
const entries = [], seen = new Set;
|
|
43097
|
-
|
|
43097
|
+
const cacheScans = new Map, maxAliasProofEntries = 1e4;
|
|
43098
|
+
function emptySiblingCacheAlias(path, parent) {
|
|
43099
|
+
const link2 = readlinkSync(path), target = resolve4(parent, link2);
|
|
43100
|
+
if (dirname4(target) !== parent || (isAbsolute3(link2) ? link2 !== target : dirname4(link2) !== "."))
|
|
43101
|
+
return false;
|
|
43102
|
+
if (!lstatSync3(target, { throwIfNoEntry: false })?.isDirectory())
|
|
43103
|
+
return false;
|
|
43104
|
+
const scan = cacheScans.get(target);
|
|
43105
|
+
return Boolean(scan?.complete && !scan.hasSkills && scan.entries <= maxAliasProofEntries);
|
|
43106
|
+
}
|
|
43107
|
+
function visit(agent, path, vendor = false, depth = 0, pluginCache = false) {
|
|
43108
|
+
const scan = { complete: true, hasSkills: false, entries: 1 };
|
|
43098
43109
|
assertSafePath(path);
|
|
43099
43110
|
if (!existsSync13(path))
|
|
43100
|
-
return;
|
|
43111
|
+
return scan;
|
|
43101
43112
|
if (!lstatSync3(path).isDirectory())
|
|
43102
|
-
return;
|
|
43113
|
+
return scan;
|
|
43103
43114
|
if (existsSync13(join13(path, "SKILL.md"))) {
|
|
43115
|
+
scan.hasSkills = true;
|
|
43104
43116
|
if (seen.has(path))
|
|
43105
|
-
return;
|
|
43117
|
+
return scan;
|
|
43106
43118
|
seen.add(path);
|
|
43107
43119
|
let managed = false;
|
|
43108
43120
|
const marker = join13(path, ".hasna-skills.json");
|
|
@@ -43113,11 +43125,14 @@ function inventoryNativeSkills(home = homedir3(), options = {}) {
|
|
|
43113
43125
|
}
|
|
43114
43126
|
const rootAlias = aliases.find((item) => path === item.target || path.startsWith(item.target + sep3));
|
|
43115
43127
|
entries.push({ agent, path, hash: treeHash(path), managed, vendor, ...rootAlias ? { rootAlias } : {} });
|
|
43116
|
-
return;
|
|
43128
|
+
return scan;
|
|
43117
43129
|
}
|
|
43118
43130
|
if (depth > (vendor ? 8 : 3))
|
|
43119
|
-
return;
|
|
43120
|
-
|
|
43131
|
+
return { ...scan, complete: false };
|
|
43132
|
+
const children = readdirSync7(path, { withFileTypes: true }).sort((a, b) => a.name < b.name ? -1 : a.name > b.name ? 1 : 0);
|
|
43133
|
+
if (pluginCache)
|
|
43134
|
+
children.sort((a, b) => Number(a.isSymbolicLink()) - Number(b.isSymbolicLink()));
|
|
43135
|
+
for (const { name } of children) {
|
|
43121
43136
|
if (name === "node_modules")
|
|
43122
43137
|
continue;
|
|
43123
43138
|
if (name.startsWith(".") && name !== ".system")
|
|
@@ -43125,14 +43140,28 @@ function inventoryNativeSkills(home = homedir3(), options = {}) {
|
|
|
43125
43140
|
const isVendor = vendor || name === ".system";
|
|
43126
43141
|
if (isVendor && !options.includeVendor)
|
|
43127
43142
|
continue;
|
|
43128
|
-
|
|
43143
|
+
const child = join13(path, name);
|
|
43144
|
+
if (isVendor && lstatSync3(child, { throwIfNoEntry: false })?.isSymbolicLink()) {
|
|
43145
|
+
const target = statSync7(child, { throwIfNoEntry: false });
|
|
43146
|
+
if (target?.isFile() || pluginCache && target?.isDirectory() && emptySiblingCacheAlias(child, path)) {
|
|
43147
|
+
scan.entries++;
|
|
43148
|
+
continue;
|
|
43149
|
+
}
|
|
43150
|
+
}
|
|
43151
|
+
const childScan = visit(agent, child, isVendor, depth + 1, pluginCache);
|
|
43152
|
+
scan.complete &&= childScan.complete;
|
|
43153
|
+
scan.hasSkills ||= childScan.hasSkills;
|
|
43154
|
+
scan.entries += childScan.entries;
|
|
43129
43155
|
}
|
|
43156
|
+
if (pluginCache)
|
|
43157
|
+
cacheScans.set(path, scan);
|
|
43158
|
+
return scan;
|
|
43130
43159
|
}
|
|
43131
43160
|
for (const [agent, path] of roots)
|
|
43132
43161
|
visit(agent, path);
|
|
43133
43162
|
if (options.includeVendor) {
|
|
43134
43163
|
for (const agent of ["codex", "claude"])
|
|
43135
|
-
visit(agent, canonicalAgentPath(join13(home, `.${agent}`, "plugins", "cache"), aliases), true);
|
|
43164
|
+
visit(agent, canonicalAgentPath(join13(home, `.${agent}`, "plugins", "cache"), aliases), true, 0, true);
|
|
43136
43165
|
}
|
|
43137
43166
|
recheckRootAliases(aliases);
|
|
43138
43167
|
return entries;
|
|
@@ -43363,7 +43392,7 @@ var init_agent_integration = __esm(() => {
|
|
|
43363
43392
|
});
|
|
43364
43393
|
|
|
43365
43394
|
// src/lib/home-migration.ts
|
|
43366
|
-
import { existsSync as existsSync14, mkdirSync as mkdirSync5, readdirSync as readdirSync8, renameSync as renameSync3, rmSync as rmSync2, statSync as
|
|
43395
|
+
import { existsSync as existsSync14, mkdirSync as mkdirSync5, readdirSync as readdirSync8, renameSync as renameSync3, rmSync as rmSync2, statSync as statSync8, writeFileSync as writeFileSync5 } from "fs";
|
|
43367
43396
|
import { join as join14 } from "path";
|
|
43368
43397
|
function layoutMigrationRecordPath(appDir) {
|
|
43369
43398
|
return join14(appDir, SKILLS_CACHE_DIRNAME, LAYOUT_MIGRATION_RECORD);
|
|
@@ -43376,7 +43405,7 @@ function migrationAppDir(homeDir) {
|
|
|
43376
43405
|
}
|
|
43377
43406
|
function looksLikeSkillDirectory2(path) {
|
|
43378
43407
|
try {
|
|
43379
|
-
if (!
|
|
43408
|
+
if (!statSync8(path).isDirectory())
|
|
43380
43409
|
return false;
|
|
43381
43410
|
} catch {
|
|
43382
43411
|
return false;
|
|
@@ -43508,7 +43537,7 @@ import {
|
|
|
43508
43537
|
readdirSync as readdirSync9,
|
|
43509
43538
|
renameSync as renameSync4,
|
|
43510
43539
|
rmSync as rmSync3,
|
|
43511
|
-
statSync as
|
|
43540
|
+
statSync as statSync9,
|
|
43512
43541
|
writeFileSync as writeFileSync6
|
|
43513
43542
|
} from "fs";
|
|
43514
43543
|
import { homedir as homedir4 } from "os";
|
|
@@ -43625,7 +43654,7 @@ function containsSkillDirectories(path) {
|
|
|
43625
43654
|
}
|
|
43626
43655
|
function isDirectory(path) {
|
|
43627
43656
|
try {
|
|
43628
|
-
return
|
|
43657
|
+
return statSync9(path).isDirectory();
|
|
43629
43658
|
} catch {
|
|
43630
43659
|
return false;
|
|
43631
43660
|
}
|
|
@@ -50123,7 +50152,7 @@ var init_remote_workspace_leave = __esm(() => {
|
|
|
50123
50152
|
});
|
|
50124
50153
|
|
|
50125
50154
|
// src/lib/auth-store.ts
|
|
50126
|
-
import { chmodSync as chmodSync2, existsSync as existsSync18, mkdirSync as mkdirSync8, readFileSync as readFileSync13, renameSync as renameSync5, statSync as
|
|
50155
|
+
import { chmodSync as chmodSync2, existsSync as existsSync18, mkdirSync as mkdirSync8, readFileSync as readFileSync13, renameSync as renameSync5, statSync as statSync10, unlinkSync as unlinkSync2, writeFileSync as writeFileSync8 } from "fs";
|
|
50127
50156
|
import { basename as basename4, dirname as dirname7, join as join19 } from "path";
|
|
50128
50157
|
function getAuthFilePath(env3 = process.env) {
|
|
50129
50158
|
return skillsCredentialFilePath(env3);
|
|
@@ -50281,7 +50310,7 @@ function getApiUrl(action, env3 = process.env, options = {}) {
|
|
|
50281
50310
|
}
|
|
50282
50311
|
function credentialFileMode(env3 = process.env) {
|
|
50283
50312
|
try {
|
|
50284
|
-
return
|
|
50313
|
+
return statSync10(skillsCredentialFilePath(env3)).mode & 511;
|
|
50285
50314
|
} catch {
|
|
50286
50315
|
return null;
|
|
50287
50316
|
}
|
|
@@ -51430,7 +51459,7 @@ var init_revision = __esm(() => {
|
|
|
51430
51459
|
|
|
51431
51460
|
// src/lib/skill-bundle.ts
|
|
51432
51461
|
import { createHash as createHash5 } from "crypto";
|
|
51433
|
-
import { readFileSync as readFileSync14, readdirSync as readdirSync10, statSync as
|
|
51462
|
+
import { readFileSync as readFileSync14, readdirSync as readdirSync10, statSync as statSync11 } from "fs";
|
|
51434
51463
|
import { join as join20, relative as relative4 } from "path";
|
|
51435
51464
|
import { createGunzip } from "zlib";
|
|
51436
51465
|
function isDotenvFile(lower) {
|
|
@@ -51491,7 +51520,7 @@ function walk(root, current, out) {
|
|
|
51491
51520
|
continue;
|
|
51492
51521
|
if (isCredentialFile(entry.name))
|
|
51493
51522
|
continue;
|
|
51494
|
-
const stats =
|
|
51523
|
+
const stats = statSync11(absolute);
|
|
51495
51524
|
out.push({
|
|
51496
51525
|
path: rel,
|
|
51497
51526
|
bytes: ownBytes(readFileSync14(absolute)),
|
|
@@ -55435,7 +55464,7 @@ var init_init = __esm(() => {
|
|
|
55435
55464
|
});
|
|
55436
55465
|
|
|
55437
55466
|
// src/lib/home-adoption.ts
|
|
55438
|
-
import { constants as constants4, closeSync as closeSync4, fstatSync as fstatSync4, lstatSync as lstatSync8, openSync as openSync4, readSync as readSync3, existsSync as existsSync24, mkdirSync as mkdirSync11, readdirSync as readdirSync11, readFileSync as readFileSync21, rmSync as rmSync6, statSync as
|
|
55467
|
+
import { constants as constants4, closeSync as closeSync4, fstatSync as fstatSync4, lstatSync as lstatSync8, openSync as openSync4, readSync as readSync3, existsSync as existsSync24, mkdirSync as mkdirSync11, readdirSync as readdirSync11, readFileSync as readFileSync21, rmSync as rmSync6, statSync as statSync12, writeFileSync as writeFileSync12 } from "fs";
|
|
55439
55468
|
import { homedir as homedir6 } from "os";
|
|
55440
55469
|
import { join as join27 } from "path";
|
|
55441
55470
|
function indexCanonicalCorpus(corpusRoot) {
|
|
@@ -55471,7 +55500,7 @@ function selectedHomeNames(options, index, homeDir2, agents) {
|
|
|
55471
55500
|
continue;
|
|
55472
55501
|
const present = agents.some((agent) => {
|
|
55473
55502
|
try {
|
|
55474
|
-
return
|
|
55503
|
+
return statSync12(join27(agentGlobalSkillsDir(agent, homeDir2), name)).isDirectory();
|
|
55475
55504
|
} catch {
|
|
55476
55505
|
return false;
|
|
55477
55506
|
}
|
|
@@ -55505,7 +55534,7 @@ function scanUnmarkedHomes(options = {}) {
|
|
|
55505
55534
|
continue;
|
|
55506
55535
|
const dir = join27(home, skill);
|
|
55507
55536
|
try {
|
|
55508
|
-
if (!
|
|
55537
|
+
if (!statSync12(dir).isDirectory())
|
|
55509
55538
|
continue;
|
|
55510
55539
|
} catch {
|
|
55511
55540
|
continue;
|
|
@@ -55518,7 +55547,7 @@ function scanUnmarkedHomes(options = {}) {
|
|
|
55518
55547
|
if (!existsSync24(skillMdPath))
|
|
55519
55548
|
continue;
|
|
55520
55549
|
const hash2 = hashSkillMarkdownFile(skillMdPath);
|
|
55521
|
-
const mtime =
|
|
55550
|
+
const mtime = statSync12(skillMdPath).mtime.toISOString();
|
|
55522
55551
|
const entry = { agent, skill, home, path: dir, hash: hash2, mtime };
|
|
55523
55552
|
const canonicalHash = index.get(skill);
|
|
55524
55553
|
if (canonicalHash === undefined) {
|
|
@@ -55647,7 +55676,7 @@ function pruneStrayHomes(options = {}) {
|
|
|
55647
55676
|
continue;
|
|
55648
55677
|
const dir = join27(home, skill);
|
|
55649
55678
|
try {
|
|
55650
|
-
if (!
|
|
55679
|
+
if (!statSync12(dir).isDirectory())
|
|
55651
55680
|
continue;
|
|
55652
55681
|
} catch {
|
|
55653
55682
|
continue;
|
|
@@ -55688,7 +55717,7 @@ var init_home_adoption = __esm(() => {
|
|
|
55688
55717
|
});
|
|
55689
55718
|
|
|
55690
55719
|
// src/lib/home-census.ts
|
|
55691
|
-
import { existsSync as existsSync25, readFileSync as readFileSync22, readdirSync as readdirSync12, statSync as
|
|
55720
|
+
import { existsSync as existsSync25, readFileSync as readFileSync22, readdirSync as readdirSync12, statSync as statSync13 } from "fs";
|
|
55692
55721
|
import { homedir as homedir7 } from "os";
|
|
55693
55722
|
import { join as join28 } from "path";
|
|
55694
55723
|
function sortEntries(entries) {
|
|
@@ -55733,7 +55762,7 @@ function censusHomeDrift(options = {}) {
|
|
|
55733
55762
|
continue;
|
|
55734
55763
|
const dir = join28(home, skill);
|
|
55735
55764
|
try {
|
|
55736
|
-
if (!
|
|
55765
|
+
if (!statSync13(dir).isDirectory())
|
|
55737
55766
|
continue;
|
|
55738
55767
|
} catch {
|
|
55739
55768
|
continue;
|
|
@@ -55986,7 +56015,7 @@ var exports_diagnostic = {};
|
|
|
55986
56015
|
__export(exports_diagnostic, {
|
|
55987
56016
|
registerDiagnostic: () => registerDiagnostic
|
|
55988
56017
|
});
|
|
55989
|
-
import { existsSync as existsSync26, readFileSync as readFileSync24, readdirSync as readdirSync13, statSync as
|
|
56018
|
+
import { existsSync as existsSync26, readFileSync as readFileSync24, readdirSync as readdirSync13, statSync as statSync14 } from "fs";
|
|
55990
56019
|
import { join as join29 } from "path";
|
|
55991
56020
|
import { execSync as execSync2 } from "child_process";
|
|
55992
56021
|
function registerDiagnostic(parent) {
|
|
@@ -56179,7 +56208,7 @@ function handleWhoami(options) {
|
|
|
56179
56208
|
let skillCount = 0;
|
|
56180
56209
|
if (exists)
|
|
56181
56210
|
try {
|
|
56182
|
-
skillCount = readdirSync13(agentSkillsPath).filter((f) => !f.startsWith(".") &&
|
|
56211
|
+
skillCount = readdirSync13(agentSkillsPath).filter((f) => !f.startsWith(".") && statSync14(join29(agentSkillsPath, f)).isDirectory()).length;
|
|
56183
56212
|
} catch {}
|
|
56184
56213
|
agentConfigs.push({ agent, label: AGENT_LABELS[agent], path: agentSkillsPath, exists, skillCount });
|
|
56185
56214
|
}
|
|
@@ -56766,7 +56795,7 @@ var init_runs = __esm(() => {
|
|
|
56766
56795
|
|
|
56767
56796
|
// src/lib/run-state.ts
|
|
56768
56797
|
import { createHash as createHash9, randomBytes } from "crypto";
|
|
56769
|
-
import { existsSync as existsSync27, mkdirSync as mkdirSync13, readFileSync as readFileSync25, readdirSync as readdirSync14, statSync as
|
|
56798
|
+
import { existsSync as existsSync27, mkdirSync as mkdirSync13, readFileSync as readFileSync25, readdirSync as readdirSync14, statSync as statSync15, writeFileSync as writeFileSync14 } from "fs";
|
|
56770
56799
|
import { extname, join as join31, relative as relative5 } from "path";
|
|
56771
56800
|
function createSkillRun(params, targetDir = process.cwd()) {
|
|
56772
56801
|
const now3 = new Date;
|
|
@@ -56848,7 +56877,7 @@ function listSkillRuns(targetDir = process.cwd(), limit = 50) {
|
|
|
56848
56877
|
const records = [];
|
|
56849
56878
|
for (const day of readdirSync14(runsRoot).sort().reverse()) {
|
|
56850
56879
|
const dayDir = join31(runsRoot, day);
|
|
56851
|
-
if (!
|
|
56880
|
+
if (!statSync15(dayDir).isDirectory())
|
|
56852
56881
|
continue;
|
|
56853
56882
|
for (const runId2 of readdirSync14(dayDir).sort().reverse()) {
|
|
56854
56883
|
const record4 = readRunRecord(join31(dayDir, runId2));
|
|
@@ -56897,7 +56926,7 @@ function collectRunArtifacts(context) {
|
|
|
56897
56926
|
return [];
|
|
56898
56927
|
const artifacts = [];
|
|
56899
56928
|
for (const path of walkFiles(context.exportDir)) {
|
|
56900
|
-
const stat =
|
|
56929
|
+
const stat = statSync15(path);
|
|
56901
56930
|
const bytes = readFileSync25(path);
|
|
56902
56931
|
artifacts.push({
|
|
56903
56932
|
path: toProjectRelative(context.targetDir, path),
|
|
@@ -56922,7 +56951,7 @@ function walkFiles(dir) {
|
|
|
56922
56951
|
const files = [];
|
|
56923
56952
|
for (const entry of readdirSync14(dir)) {
|
|
56924
56953
|
const full = join31(dir, entry);
|
|
56925
|
-
if (
|
|
56954
|
+
if (statSync15(full).isDirectory())
|
|
56926
56955
|
files.push(...walkFiles(full));
|
|
56927
56956
|
else
|
|
56928
56957
|
files.push(full);
|
|
@@ -74831,7 +74860,7 @@ var init_run_routing = __esm(() => {
|
|
|
74831
74860
|
});
|
|
74832
74861
|
|
|
74833
74862
|
// src/mcp/operation-tools.ts
|
|
74834
|
-
import { existsSync as existsSync28, readdirSync as readdirSync15, statSync as
|
|
74863
|
+
import { existsSync as existsSync28, readdirSync as readdirSync15, statSync as statSync16 } from "fs";
|
|
74835
74864
|
import { join as join32 } from "path";
|
|
74836
74865
|
function registerOperationTools(server) {
|
|
74837
74866
|
server.registerTool("scaffold_skill", {
|
|
@@ -75290,7 +75319,7 @@ function registerOperationTools(server) {
|
|
|
75290
75319
|
try {
|
|
75291
75320
|
skillCount = readdirSync15(agentSkillsPath).filter((f) => {
|
|
75292
75321
|
const full = join32(agentSkillsPath, f);
|
|
75293
|
-
return !f.startsWith(".") &&
|
|
75322
|
+
return !f.startsWith(".") && statSync16(full).isDirectory();
|
|
75294
75323
|
}).length;
|
|
75295
75324
|
} catch {}
|
|
75296
75325
|
}
|
|
@@ -75877,7 +75906,7 @@ import {
|
|
|
75877
75906
|
mkdirSync as mkdirSync16,
|
|
75878
75907
|
readFileSync as readFileSync27,
|
|
75879
75908
|
readdirSync as readdirSync16,
|
|
75880
|
-
statSync as
|
|
75909
|
+
statSync as statSync17,
|
|
75881
75910
|
writeFileSync as writeFileSync16
|
|
75882
75911
|
} from "fs";
|
|
75883
75912
|
import { dirname as dirname12, join as join35, normalize as normalize3, relative as relative6, sep as sep4 } from "path";
|
|
@@ -76003,7 +76032,7 @@ function walkFiles2(dir) {
|
|
|
76003
76032
|
const files = [];
|
|
76004
76033
|
for (const entry of readdirSync16(dir)) {
|
|
76005
76034
|
const full = join35(dir, entry);
|
|
76006
|
-
const stats =
|
|
76035
|
+
const stats = statSync17(full);
|
|
76007
76036
|
if (stats.isDirectory())
|
|
76008
76037
|
files.push(...walkFiles2(full));
|
|
76009
76038
|
else
|
|
@@ -79118,7 +79147,7 @@ var init_completion = __esm(() => {
|
|
|
79118
79147
|
});
|
|
79119
79148
|
|
|
79120
79149
|
// src/lib/portable-snapshot-filter.ts
|
|
79121
|
-
import { readdirSync as readdirSync17, statSync as
|
|
79150
|
+
import { readdirSync as readdirSync17, statSync as statSync18 } from "fs";
|
|
79122
79151
|
import { homedir as homedir9 } from "os";
|
|
79123
79152
|
import { join as join40, sep as sep5 } from "path";
|
|
79124
79153
|
function isExcludedSkillFileName(fileName) {
|
|
@@ -79186,7 +79215,7 @@ function walkEntries(absoluteRoot) {
|
|
|
79186
79215
|
}
|
|
79187
79216
|
function isRegularFile(filePath) {
|
|
79188
79217
|
try {
|
|
79189
|
-
return
|
|
79218
|
+
return statSync18(filePath).isFile();
|
|
79190
79219
|
} catch {
|
|
79191
79220
|
return false;
|
|
79192
79221
|
}
|
|
@@ -79272,7 +79301,7 @@ import {
|
|
|
79272
79301
|
copyFileSync as copyFileSync2,
|
|
79273
79302
|
mkdirSync as mkdirSync21,
|
|
79274
79303
|
readFileSync as readFileSync31,
|
|
79275
|
-
statSync as
|
|
79304
|
+
statSync as statSync19,
|
|
79276
79305
|
writeFileSync as writeFileSync21
|
|
79277
79306
|
} from "fs";
|
|
79278
79307
|
import { dirname as dirname17, isAbsolute as isAbsolute8, relative as relative7, resolve as resolve9, sep as sep6 } from "path";
|
|
@@ -79312,7 +79341,7 @@ function scanHome(definition, homesRoot) {
|
|
|
79312
79341
|
skipped.push({ relativePath: entry.relativePath, reason: "not-regular-file" });
|
|
79313
79342
|
continue;
|
|
79314
79343
|
}
|
|
79315
|
-
const info =
|
|
79344
|
+
const info = statSync19(entry.fullPath);
|
|
79316
79345
|
portable.push({
|
|
79317
79346
|
relativePath: entry.relativePath,
|
|
79318
79347
|
fullPath: entry.fullPath,
|
|
@@ -80055,7 +80084,7 @@ import {
|
|
|
80055
80084
|
mkdirSync as mkdirSync22,
|
|
80056
80085
|
readdirSync as readdirSync18,
|
|
80057
80086
|
readFileSync as readFileSync34,
|
|
80058
|
-
statSync as
|
|
80087
|
+
statSync as statSync20,
|
|
80059
80088
|
writeFileSync as writeFileSync23
|
|
80060
80089
|
} from "fs";
|
|
80061
80090
|
import { dirname as dirname18, join as join42, resolve as resolve10, sep as sep7 } from "path";
|
|
@@ -80152,7 +80181,7 @@ function planStationHydration(stationId, repoRoot) {
|
|
|
80152
80181
|
});
|
|
80153
80182
|
continue;
|
|
80154
80183
|
}
|
|
80155
|
-
const info =
|
|
80184
|
+
const info = statSync20(entry.fullPath);
|
|
80156
80185
|
const manifestHash = manifestHashes.get(`${agent}${MANIFEST_HASH_KEY_SEP}${homeRelative}`) ?? null;
|
|
80157
80186
|
let verified = false;
|
|
80158
80187
|
if (manifestHash !== null) {
|
|
@@ -82715,11 +82744,11 @@ var init_storage = __esm(() => {
|
|
|
82715
82744
|
});
|
|
82716
82745
|
|
|
82717
82746
|
// src/lib/registry-reconcile.ts
|
|
82718
|
-
import { existsSync as existsSync35, readFileSync as readFileSync36, statSync as
|
|
82747
|
+
import { existsSync as existsSync35, readFileSync as readFileSync36, statSync as statSync21, writeFileSync as writeFileSync25 } from "fs";
|
|
82719
82748
|
import { join as join44 } from "path";
|
|
82720
82749
|
function isDirectory2(path) {
|
|
82721
82750
|
try {
|
|
82722
|
-
return
|
|
82751
|
+
return statSync21(path).isDirectory();
|
|
82723
82752
|
} catch {
|
|
82724
82753
|
return false;
|
|
82725
82754
|
}
|
package/bin/mcp.js
CHANGED
|
@@ -5586,7 +5586,7 @@ var package_default;
|
|
|
5586
5586
|
var init_package = __esm(() => {
|
|
5587
5587
|
package_default = {
|
|
5588
5588
|
name: "@hasna/skills",
|
|
5589
|
-
version: "0.6.
|
|
5589
|
+
version: "0.6.2",
|
|
5590
5590
|
description: "Skills library for AI coding agents",
|
|
5591
5591
|
type: "module",
|
|
5592
5592
|
bin: {
|
package/bin/migrate.js
CHANGED
package/bin/server.js
CHANGED
|
@@ -23100,7 +23100,7 @@ var init_dist_es9 = __esm(() => {
|
|
|
23100
23100
|
// package.json
|
|
23101
23101
|
var package_default = {
|
|
23102
23102
|
name: "@hasna/skills",
|
|
23103
|
-
version: "0.6.
|
|
23103
|
+
version: "0.6.2",
|
|
23104
23104
|
description: "Skills library for AI coding agents",
|
|
23105
23105
|
type: "module",
|
|
23106
23106
|
bin: {
|
package/bin/worker.js
CHANGED
|
@@ -23103,7 +23103,7 @@ import { randomUUID as randomUUID5 } from "crypto";
|
|
|
23103
23103
|
// package.json
|
|
23104
23104
|
var package_default = {
|
|
23105
23105
|
name: "@hasna/skills",
|
|
23106
|
-
version: "0.6.
|
|
23106
|
+
version: "0.6.2",
|
|
23107
23107
|
description: "Skills library for AI coding agents",
|
|
23108
23108
|
type: "module",
|
|
23109
23109
|
bin: {
|
package/dist/index.js
CHANGED
|
@@ -3493,7 +3493,7 @@ import {
|
|
|
3493
3493
|
readdirSync as readdirSync8,
|
|
3494
3494
|
renameSync as renameSync3,
|
|
3495
3495
|
rmSync as rmSync2,
|
|
3496
|
-
statSync as
|
|
3496
|
+
statSync as statSync8,
|
|
3497
3497
|
writeFileSync as writeFileSync5
|
|
3498
3498
|
} from "fs";
|
|
3499
3499
|
import { homedir as homedir3 } from "os";
|
|
@@ -3501,7 +3501,7 @@ import { basename as basename3, dirname as dirname5, join as join10 } from "path
|
|
|
3501
3501
|
|
|
3502
3502
|
// src/lib/agent-integration.ts
|
|
3503
3503
|
import { createHash as createHash2, randomUUID } from "crypto";
|
|
3504
|
-
import { existsSync as existsSync9, lstatSync as lstatSync3, mkdirSync as mkdirSync4, readFileSync as readFileSync7, readdirSync as readdirSync7, readlinkSync, realpathSync as realpathSync3, renameSync as renameSync2, writeFileSync as writeFileSync4, unlinkSync, chmodSync } from "fs";
|
|
3504
|
+
import { existsSync as existsSync9, lstatSync as lstatSync3, statSync as statSync7, mkdirSync as mkdirSync4, readFileSync as readFileSync7, readdirSync as readdirSync7, readlinkSync, realpathSync as realpathSync3, renameSync as renameSync2, writeFileSync as writeFileSync4, unlinkSync, chmodSync } from "fs";
|
|
3505
3505
|
import { dirname as dirname4, join as join9, resolve as resolve3, relative as relative3, isAbsolute as isAbsolute3, sep as sep3 } from "path";
|
|
3506
3506
|
import { homedir as homedir2 } from "os";
|
|
3507
3507
|
var sha = (data) => createHash2("sha256").update(data).digest("hex");
|
|
@@ -3600,15 +3600,27 @@ function inventoryNativeSkills(home = homedir2(), options = {}) {
|
|
|
3600
3600
|
for (const [agent, path] of ROOTS)
|
|
3601
3601
|
roots.push([agent, join9(resolve3(options.projectDir), path)]);
|
|
3602
3602
|
const entries = [], seen = new Set;
|
|
3603
|
-
|
|
3603
|
+
const cacheScans = new Map, maxAliasProofEntries = 1e4;
|
|
3604
|
+
function emptySiblingCacheAlias(path, parent) {
|
|
3605
|
+
const link = readlinkSync(path), target = resolve3(parent, link);
|
|
3606
|
+
if (dirname4(target) !== parent || (isAbsolute3(link) ? link !== target : dirname4(link) !== "."))
|
|
3607
|
+
return false;
|
|
3608
|
+
if (!lstatSync3(target, { throwIfNoEntry: false })?.isDirectory())
|
|
3609
|
+
return false;
|
|
3610
|
+
const scan = cacheScans.get(target);
|
|
3611
|
+
return Boolean(scan?.complete && !scan.hasSkills && scan.entries <= maxAliasProofEntries);
|
|
3612
|
+
}
|
|
3613
|
+
function visit(agent, path, vendor = false, depth = 0, pluginCache = false) {
|
|
3614
|
+
const scan = { complete: true, hasSkills: false, entries: 1 };
|
|
3604
3615
|
assertSafePath(path);
|
|
3605
3616
|
if (!existsSync9(path))
|
|
3606
|
-
return;
|
|
3617
|
+
return scan;
|
|
3607
3618
|
if (!lstatSync3(path).isDirectory())
|
|
3608
|
-
return;
|
|
3619
|
+
return scan;
|
|
3609
3620
|
if (existsSync9(join9(path, "SKILL.md"))) {
|
|
3621
|
+
scan.hasSkills = true;
|
|
3610
3622
|
if (seen.has(path))
|
|
3611
|
-
return;
|
|
3623
|
+
return scan;
|
|
3612
3624
|
seen.add(path);
|
|
3613
3625
|
let managed = false;
|
|
3614
3626
|
const marker = join9(path, ".hasna-skills.json");
|
|
@@ -3619,11 +3631,14 @@ function inventoryNativeSkills(home = homedir2(), options = {}) {
|
|
|
3619
3631
|
}
|
|
3620
3632
|
const rootAlias = aliases.find((item) => path === item.target || path.startsWith(item.target + sep3));
|
|
3621
3633
|
entries.push({ agent, path, hash: treeHash(path), managed, vendor, ...rootAlias ? { rootAlias } : {} });
|
|
3622
|
-
return;
|
|
3634
|
+
return scan;
|
|
3623
3635
|
}
|
|
3624
3636
|
if (depth > (vendor ? 8 : 3))
|
|
3625
|
-
return;
|
|
3626
|
-
|
|
3637
|
+
return { ...scan, complete: false };
|
|
3638
|
+
const children = readdirSync7(path, { withFileTypes: true }).sort((a, b) => a.name < b.name ? -1 : a.name > b.name ? 1 : 0);
|
|
3639
|
+
if (pluginCache)
|
|
3640
|
+
children.sort((a, b) => Number(a.isSymbolicLink()) - Number(b.isSymbolicLink()));
|
|
3641
|
+
for (const { name } of children) {
|
|
3627
3642
|
if (name === "node_modules")
|
|
3628
3643
|
continue;
|
|
3629
3644
|
if (name.startsWith(".") && name !== ".system")
|
|
@@ -3631,14 +3646,28 @@ function inventoryNativeSkills(home = homedir2(), options = {}) {
|
|
|
3631
3646
|
const isVendor = vendor || name === ".system";
|
|
3632
3647
|
if (isVendor && !options.includeVendor)
|
|
3633
3648
|
continue;
|
|
3634
|
-
|
|
3649
|
+
const child = join9(path, name);
|
|
3650
|
+
if (isVendor && lstatSync3(child, { throwIfNoEntry: false })?.isSymbolicLink()) {
|
|
3651
|
+
const target = statSync7(child, { throwIfNoEntry: false });
|
|
3652
|
+
if (target?.isFile() || pluginCache && target?.isDirectory() && emptySiblingCacheAlias(child, path)) {
|
|
3653
|
+
scan.entries++;
|
|
3654
|
+
continue;
|
|
3655
|
+
}
|
|
3656
|
+
}
|
|
3657
|
+
const childScan = visit(agent, child, isVendor, depth + 1, pluginCache);
|
|
3658
|
+
scan.complete &&= childScan.complete;
|
|
3659
|
+
scan.hasSkills ||= childScan.hasSkills;
|
|
3660
|
+
scan.entries += childScan.entries;
|
|
3635
3661
|
}
|
|
3662
|
+
if (pluginCache)
|
|
3663
|
+
cacheScans.set(path, scan);
|
|
3664
|
+
return scan;
|
|
3636
3665
|
}
|
|
3637
3666
|
for (const [agent, path] of roots)
|
|
3638
3667
|
visit(agent, path);
|
|
3639
3668
|
if (options.includeVendor) {
|
|
3640
3669
|
for (const agent of ["codex", "claude"])
|
|
3641
|
-
visit(agent, canonicalAgentPath(join9(home, `.${agent}`, "plugins", "cache"), aliases), true);
|
|
3670
|
+
visit(agent, canonicalAgentPath(join9(home, `.${agent}`, "plugins", "cache"), aliases), true, 0, true);
|
|
3642
3671
|
}
|
|
3643
3672
|
recheckRootAliases(aliases);
|
|
3644
3673
|
return entries;
|
|
@@ -3963,7 +3992,7 @@ function containsSkillDirectories(path) {
|
|
|
3963
3992
|
}
|
|
3964
3993
|
function isDirectory(path) {
|
|
3965
3994
|
try {
|
|
3966
|
-
return
|
|
3995
|
+
return statSync8(path).isDirectory();
|
|
3967
3996
|
} catch {
|
|
3968
3997
|
return false;
|
|
3969
3998
|
}
|
|
@@ -4594,7 +4623,7 @@ function loadProjectConfigCompat(targetDir) {
|
|
|
4594
4623
|
}
|
|
4595
4624
|
// src/lib/run-state.ts
|
|
4596
4625
|
import { createHash as createHash3, randomBytes } from "crypto";
|
|
4597
|
-
import { existsSync as existsSync13, mkdirSync as mkdirSync7, readFileSync as readFileSync11, readdirSync as readdirSync9, statSync as
|
|
4626
|
+
import { existsSync as existsSync13, mkdirSync as mkdirSync7, readFileSync as readFileSync11, readdirSync as readdirSync9, statSync as statSync9, writeFileSync as writeFileSync7 } from "fs";
|
|
4598
4627
|
import { extname, join as join13, relative as relative4 } from "path";
|
|
4599
4628
|
function createSkillRun(params, targetDir = process.cwd()) {
|
|
4600
4629
|
const now = new Date;
|
|
@@ -4676,7 +4705,7 @@ function listSkillRuns(targetDir = process.cwd(), limit = 50) {
|
|
|
4676
4705
|
const records = [];
|
|
4677
4706
|
for (const day of readdirSync9(runsRoot).sort().reverse()) {
|
|
4678
4707
|
const dayDir = join13(runsRoot, day);
|
|
4679
|
-
if (!
|
|
4708
|
+
if (!statSync9(dayDir).isDirectory())
|
|
4680
4709
|
continue;
|
|
4681
4710
|
for (const runId of readdirSync9(dayDir).sort().reverse()) {
|
|
4682
4711
|
const record = readRunRecord(join13(dayDir, runId));
|
|
@@ -4715,7 +4744,7 @@ function collectRunArtifacts(context) {
|
|
|
4715
4744
|
return [];
|
|
4716
4745
|
const artifacts = [];
|
|
4717
4746
|
for (const path of walkFiles(context.exportDir)) {
|
|
4718
|
-
const stat =
|
|
4747
|
+
const stat = statSync9(path);
|
|
4719
4748
|
const bytes = readFileSync11(path);
|
|
4720
4749
|
artifacts.push({
|
|
4721
4750
|
path: toProjectRelative(context.targetDir, path),
|
|
@@ -4740,7 +4769,7 @@ function walkFiles(dir) {
|
|
|
4740
4769
|
const files = [];
|
|
4741
4770
|
for (const entry of readdirSync9(dir)) {
|
|
4742
4771
|
const full = join13(dir, entry);
|
|
4743
|
-
if (
|
|
4772
|
+
if (statSync9(full).isDirectory())
|
|
4744
4773
|
files.push(...walkFiles(full));
|
|
4745
4774
|
else
|
|
4746
4775
|
files.push(full);
|
|
@@ -12614,7 +12643,7 @@ import { dirname as dirname7, join as join18 } from "path";
|
|
|
12614
12643
|
|
|
12615
12644
|
// src/lib/skill-bundle.ts
|
|
12616
12645
|
import { createHash as createHash6 } from "crypto";
|
|
12617
|
-
import { readFileSync as readFileSync15, readdirSync as readdirSync10, statSync as
|
|
12646
|
+
import { readFileSync as readFileSync15, readdirSync as readdirSync10, statSync as statSync10 } from "fs";
|
|
12618
12647
|
import { join as join17, relative as relative5 } from "path";
|
|
12619
12648
|
import { createGunzip } from "zlib";
|
|
12620
12649
|
var BLOCK = 512;
|
|
@@ -12798,7 +12827,7 @@ function walk(root, current, out) {
|
|
|
12798
12827
|
continue;
|
|
12799
12828
|
if (isCredentialFile(entry.name))
|
|
12800
12829
|
continue;
|
|
12801
|
-
const stats =
|
|
12830
|
+
const stats = statSync10(absolute);
|
|
12802
12831
|
out.push({
|
|
12803
12832
|
path: rel,
|
|
12804
12833
|
bytes: ownBytes(readFileSync15(absolute)),
|
|
@@ -13710,7 +13739,7 @@ import { dirname as dirname8, relative as relative6 } from "path";
|
|
|
13710
13739
|
// package.json
|
|
13711
13740
|
var package_default = {
|
|
13712
13741
|
name: "@hasna/skills",
|
|
13713
|
-
version: "0.6.
|
|
13742
|
+
version: "0.6.2",
|
|
13714
13743
|
description: "Skills library for AI coding agents",
|
|
13715
13744
|
type: "module",
|
|
13716
13745
|
bin: {
|
|
@@ -15031,7 +15060,7 @@ import {
|
|
|
15031
15060
|
mkdirSync as mkdirSync12,
|
|
15032
15061
|
readFileSync as readFileSync17,
|
|
15033
15062
|
readdirSync as readdirSync11,
|
|
15034
|
-
statSync as
|
|
15063
|
+
statSync as statSync11,
|
|
15035
15064
|
writeFileSync as writeFileSync11
|
|
15036
15065
|
} from "fs";
|
|
15037
15066
|
import { dirname as dirname10, join as join20, normalize as normalize3, relative as relative7, sep as sep4 } from "path";
|
|
@@ -15529,7 +15558,7 @@ function walkFiles2(dir) {
|
|
|
15529
15558
|
const files = [];
|
|
15530
15559
|
for (const entry of readdirSync11(dir)) {
|
|
15531
15560
|
const full = join20(dir, entry);
|
|
15532
|
-
const stats =
|
|
15561
|
+
const stats = statSync11(full);
|
|
15533
15562
|
if (stats.isDirectory())
|
|
15534
15563
|
files.push(...walkFiles2(full));
|
|
15535
15564
|
else
|
|
@@ -15615,13 +15644,13 @@ import {
|
|
|
15615
15644
|
copyFileSync as copyFileSync2,
|
|
15616
15645
|
mkdirSync as mkdirSync13,
|
|
15617
15646
|
readFileSync as readFileSync18,
|
|
15618
|
-
statSync as
|
|
15647
|
+
statSync as statSync13,
|
|
15619
15648
|
writeFileSync as writeFileSync12
|
|
15620
15649
|
} from "fs";
|
|
15621
15650
|
import { dirname as dirname11, isAbsolute as isAbsolute5, relative as relative8, resolve as resolve4, sep as sep6 } from "path";
|
|
15622
15651
|
|
|
15623
15652
|
// src/lib/portable-snapshot-filter.ts
|
|
15624
|
-
import { readdirSync as readdirSync12, statSync as
|
|
15653
|
+
import { readdirSync as readdirSync12, statSync as statSync12 } from "fs";
|
|
15625
15654
|
import { homedir as homedir5 } from "os";
|
|
15626
15655
|
import { join as join21, sep as sep5 } from "path";
|
|
15627
15656
|
var SYNC_HOMES = [
|
|
@@ -15759,7 +15788,7 @@ function walkEntries(absoluteRoot) {
|
|
|
15759
15788
|
}
|
|
15760
15789
|
function isRegularFile(filePath) {
|
|
15761
15790
|
try {
|
|
15762
|
-
return
|
|
15791
|
+
return statSync12(filePath).isFile();
|
|
15763
15792
|
} catch {
|
|
15764
15793
|
return false;
|
|
15765
15794
|
}
|
|
@@ -15815,7 +15844,7 @@ function scanHome(definition, homesRoot) {
|
|
|
15815
15844
|
skipped.push({ relativePath: entry.relativePath, reason: "not-regular-file" });
|
|
15816
15845
|
continue;
|
|
15817
15846
|
}
|
|
15818
|
-
const info =
|
|
15847
|
+
const info = statSync13(entry.fullPath);
|
|
15819
15848
|
portable.push({
|
|
15820
15849
|
relativePath: entry.relativePath,
|
|
15821
15850
|
fullPath: entry.fullPath,
|
|
@@ -15942,7 +15971,7 @@ import {
|
|
|
15942
15971
|
mkdirSync as mkdirSync14,
|
|
15943
15972
|
readdirSync as readdirSync13,
|
|
15944
15973
|
readFileSync as readFileSync19,
|
|
15945
|
-
statSync as
|
|
15974
|
+
statSync as statSync14,
|
|
15946
15975
|
writeFileSync as writeFileSync13
|
|
15947
15976
|
} from "fs";
|
|
15948
15977
|
import { dirname as dirname12, join as join22, resolve as resolve5, sep as sep7 } from "path";
|
|
@@ -16042,7 +16071,7 @@ function planStationHydration(stationId, repoRoot) {
|
|
|
16042
16071
|
});
|
|
16043
16072
|
continue;
|
|
16044
16073
|
}
|
|
16045
|
-
const info =
|
|
16074
|
+
const info = statSync14(entry.fullPath);
|
|
16046
16075
|
const manifestHash = manifestHashes.get(`${agent}${MANIFEST_HASH_KEY_SEP}${homeRelative}`) ?? null;
|
|
16047
16076
|
let verified = false;
|
|
16048
16077
|
if (manifestHash !== null) {
|
package/dist/sdk/index.js
CHANGED
|
@@ -24427,7 +24427,7 @@ var init_event_sink = __esm(() => {
|
|
|
24427
24427
|
// package.json
|
|
24428
24428
|
var package_default = {
|
|
24429
24429
|
name: "@hasna/skills",
|
|
24430
|
-
version: "0.6.
|
|
24430
|
+
version: "0.6.2",
|
|
24431
24431
|
description: "Skills library for AI coding agents",
|
|
24432
24432
|
type: "module",
|
|
24433
24433
|
bin: {
|
|
@@ -38174,7 +38174,7 @@ import {
|
|
|
38174
38174
|
readdirSync as readdirSync9,
|
|
38175
38175
|
renameSync as renameSync3,
|
|
38176
38176
|
rmSync as rmSync2,
|
|
38177
|
-
statSync as
|
|
38177
|
+
statSync as statSync9,
|
|
38178
38178
|
writeFileSync as writeFileSync5
|
|
38179
38179
|
} from "fs";
|
|
38180
38180
|
import { homedir as homedir4 } from "os";
|
|
@@ -38182,7 +38182,7 @@ import { basename as basename3, dirname as dirname9, join as join15 } from "path
|
|
|
38182
38182
|
|
|
38183
38183
|
// src/lib/agent-integration.ts
|
|
38184
38184
|
import { createHash as createHash7, randomUUID as randomUUID5 } from "crypto";
|
|
38185
|
-
import { existsSync as existsSync4, lstatSync as lstatSync2, mkdirSync as mkdirSync4, readFileSync as readFileSync6, readdirSync as readdirSync4, readlinkSync, realpathSync, renameSync, writeFileSync as writeFileSync2, unlinkSync, chmodSync } from "fs";
|
|
38185
|
+
import { existsSync as existsSync4, lstatSync as lstatSync2, statSync as statSync3, mkdirSync as mkdirSync4, readFileSync as readFileSync6, readdirSync as readdirSync4, readlinkSync, realpathSync, renameSync, writeFileSync as writeFileSync2, unlinkSync, chmodSync } from "fs";
|
|
38186
38186
|
import { dirname as dirname6, join as join9, resolve as resolve2, relative as relative2, isAbsolute as isAbsolute3, sep } from "path";
|
|
38187
38187
|
import { homedir as homedir3 } from "os";
|
|
38188
38188
|
var sha = (data) => createHash7("sha256").update(data).digest("hex");
|
|
@@ -38281,15 +38281,27 @@ function inventoryNativeSkills(home = homedir3(), options = {}) {
|
|
|
38281
38281
|
for (const [agent, path] of ROOTS)
|
|
38282
38282
|
roots.push([agent, join9(resolve2(options.projectDir), path)]);
|
|
38283
38283
|
const entries = [], seen = new Set;
|
|
38284
|
-
|
|
38284
|
+
const cacheScans = new Map, maxAliasProofEntries = 1e4;
|
|
38285
|
+
function emptySiblingCacheAlias(path, parent) {
|
|
38286
|
+
const link = readlinkSync(path), target = resolve2(parent, link);
|
|
38287
|
+
if (dirname6(target) !== parent || (isAbsolute3(link) ? link !== target : dirname6(link) !== "."))
|
|
38288
|
+
return false;
|
|
38289
|
+
if (!lstatSync2(target, { throwIfNoEntry: false })?.isDirectory())
|
|
38290
|
+
return false;
|
|
38291
|
+
const scan = cacheScans.get(target);
|
|
38292
|
+
return Boolean(scan?.complete && !scan.hasSkills && scan.entries <= maxAliasProofEntries);
|
|
38293
|
+
}
|
|
38294
|
+
function visit(agent, path, vendor = false, depth = 0, pluginCache = false) {
|
|
38295
|
+
const scan = { complete: true, hasSkills: false, entries: 1 };
|
|
38285
38296
|
assertSafePath(path);
|
|
38286
38297
|
if (!existsSync4(path))
|
|
38287
|
-
return;
|
|
38298
|
+
return scan;
|
|
38288
38299
|
if (!lstatSync2(path).isDirectory())
|
|
38289
|
-
return;
|
|
38300
|
+
return scan;
|
|
38290
38301
|
if (existsSync4(join9(path, "SKILL.md"))) {
|
|
38302
|
+
scan.hasSkills = true;
|
|
38291
38303
|
if (seen.has(path))
|
|
38292
|
-
return;
|
|
38304
|
+
return scan;
|
|
38293
38305
|
seen.add(path);
|
|
38294
38306
|
let managed = false;
|
|
38295
38307
|
const marker = join9(path, ".hasna-skills.json");
|
|
@@ -38300,11 +38312,14 @@ function inventoryNativeSkills(home = homedir3(), options = {}) {
|
|
|
38300
38312
|
}
|
|
38301
38313
|
const rootAlias = aliases.find((item) => path === item.target || path.startsWith(item.target + sep));
|
|
38302
38314
|
entries.push({ agent, path, hash: treeHash(path), managed, vendor, ...rootAlias ? { rootAlias } : {} });
|
|
38303
|
-
return;
|
|
38315
|
+
return scan;
|
|
38304
38316
|
}
|
|
38305
38317
|
if (depth > (vendor ? 8 : 3))
|
|
38306
|
-
return;
|
|
38307
|
-
|
|
38318
|
+
return { ...scan, complete: false };
|
|
38319
|
+
const children = readdirSync4(path, { withFileTypes: true }).sort((a3, b3) => a3.name < b3.name ? -1 : a3.name > b3.name ? 1 : 0);
|
|
38320
|
+
if (pluginCache)
|
|
38321
|
+
children.sort((a3, b3) => Number(a3.isSymbolicLink()) - Number(b3.isSymbolicLink()));
|
|
38322
|
+
for (const { name } of children) {
|
|
38308
38323
|
if (name === "node_modules")
|
|
38309
38324
|
continue;
|
|
38310
38325
|
if (name.startsWith(".") && name !== ".system")
|
|
@@ -38312,14 +38327,28 @@ function inventoryNativeSkills(home = homedir3(), options = {}) {
|
|
|
38312
38327
|
const isVendor = vendor || name === ".system";
|
|
38313
38328
|
if (isVendor && !options.includeVendor)
|
|
38314
38329
|
continue;
|
|
38315
|
-
|
|
38330
|
+
const child = join9(path, name);
|
|
38331
|
+
if (isVendor && lstatSync2(child, { throwIfNoEntry: false })?.isSymbolicLink()) {
|
|
38332
|
+
const target = statSync3(child, { throwIfNoEntry: false });
|
|
38333
|
+
if (target?.isFile() || pluginCache && target?.isDirectory() && emptySiblingCacheAlias(child, path)) {
|
|
38334
|
+
scan.entries++;
|
|
38335
|
+
continue;
|
|
38336
|
+
}
|
|
38337
|
+
}
|
|
38338
|
+
const childScan = visit(agent, child, isVendor, depth + 1, pluginCache);
|
|
38339
|
+
scan.complete &&= childScan.complete;
|
|
38340
|
+
scan.hasSkills ||= childScan.hasSkills;
|
|
38341
|
+
scan.entries += childScan.entries;
|
|
38316
38342
|
}
|
|
38343
|
+
if (pluginCache)
|
|
38344
|
+
cacheScans.set(path, scan);
|
|
38345
|
+
return scan;
|
|
38317
38346
|
}
|
|
38318
38347
|
for (const [agent, path] of roots)
|
|
38319
38348
|
visit(agent, path);
|
|
38320
38349
|
if (options.includeVendor) {
|
|
38321
38350
|
for (const agent of ["codex", "claude"])
|
|
38322
|
-
visit(agent, canonicalAgentPath(join9(home, `.${agent}`, "plugins", "cache"), aliases), true);
|
|
38351
|
+
visit(agent, canonicalAgentPath(join9(home, `.${agent}`, "plugins", "cache"), aliases), true, 0, true);
|
|
38323
38352
|
}
|
|
38324
38353
|
recheckRootAliases(aliases);
|
|
38325
38354
|
return entries;
|
|
@@ -38532,7 +38561,7 @@ import {
|
|
|
38532
38561
|
realpathSync as realpathSync3,
|
|
38533
38562
|
renameSync as renameSync2,
|
|
38534
38563
|
rmSync,
|
|
38535
|
-
statSync as
|
|
38564
|
+
statSync as statSync8,
|
|
38536
38565
|
writeFileSync as writeFileSync4
|
|
38537
38566
|
} from "fs";
|
|
38538
38567
|
import { basename as basename2, dirname as dirname8, isAbsolute as isAbsolute5, join as join14, normalize as normalize2, relative as relative4, resolve as resolve3, sep as sep3 } from "path";
|
|
@@ -39247,7 +39276,7 @@ var SKILLS = [
|
|
|
39247
39276
|
];
|
|
39248
39277
|
|
|
39249
39278
|
// src/lib/hosted-skill-set.ts
|
|
39250
|
-
import { existsSync as existsSync5, readFileSync as readFileSync7, readdirSync as readdirSync5, statSync as
|
|
39279
|
+
import { existsSync as existsSync5, readFileSync as readFileSync7, readdirSync as readdirSync5, statSync as statSync4 } from "fs";
|
|
39251
39280
|
import { join as join10 } from "path";
|
|
39252
39281
|
var HOSTED_RUNTIMES = new Set(["hosted"]);
|
|
39253
39282
|
var HOSTED_SOURCES = new Set(["remote", "private-hosted"]);
|
|
@@ -39286,7 +39315,7 @@ var BRACE_SOURCE_EXCLUSION = new RegExp(`^!skills/\\{(${SLUG}(?:,${SLUG})+)\\}/s
|
|
|
39286
39315
|
var SINGLE_SOURCE_EXCLUSION = new RegExp(`^!skills/(${SLUG})/src$`);
|
|
39287
39316
|
|
|
39288
39317
|
// src/lib/skill-validation.ts
|
|
39289
|
-
import { existsSync as existsSync6, lstatSync as lstatSync3, readFileSync as readFileSync8, readdirSync as readdirSync6, statSync as
|
|
39318
|
+
import { existsSync as existsSync6, lstatSync as lstatSync3, readFileSync as readFileSync8, readdirSync as readdirSync6, statSync as statSync5 } from "fs";
|
|
39290
39319
|
import { isAbsolute as isAbsolute4, join as join11, normalize } from "path";
|
|
39291
39320
|
var VALID_SKILL_KINDS = ["executable", "instruction"];
|
|
39292
39321
|
var DOC_FILES = ["SKILL.md", "README.md", "CLAUDE.md"];
|
|
@@ -39574,7 +39603,7 @@ function validateSkillDirectory(name, skillPath, registryMeta) {
|
|
|
39574
39603
|
const targetPath = join11(skillPath, target);
|
|
39575
39604
|
if (!existsSync6(targetPath)) {
|
|
39576
39605
|
add(warnings, "package.bin_target_missing", `package.json bin '${command3}' target '${target}' is not present before build`);
|
|
39577
|
-
} else if (
|
|
39606
|
+
} else if (statSync5(targetPath).isDirectory()) {
|
|
39578
39607
|
add(issues, "package.bin_target_directory", `package.json bin '${command3}' target '${target}' must point to a file, not a directory`);
|
|
39579
39608
|
}
|
|
39580
39609
|
}
|
|
@@ -39600,7 +39629,7 @@ function validateSkillDirectory(name, skillPath, registryMeta) {
|
|
|
39600
39629
|
add(issues, "skill.src_index_missing", "Missing src/index.ts or src/index.js");
|
|
39601
39630
|
} else {
|
|
39602
39631
|
const indexPath = existsSync6(join11(srcDir, "index.ts")) ? join11(srcDir, "index.ts") : join11(srcDir, "index.js");
|
|
39603
|
-
const size =
|
|
39632
|
+
const size = statSync5(indexPath).size;
|
|
39604
39633
|
if (size < 50)
|
|
39605
39634
|
add(warnings, "skill.src_index_minimal", `Source entry point is very small (${size}B)`);
|
|
39606
39635
|
}
|
|
@@ -39625,7 +39654,7 @@ function validateRegistryConsistency(registry, skillsDir) {
|
|
|
39625
39654
|
})));
|
|
39626
39655
|
const skillDirs = existsSync6(skillsDir) ? readdirSync6(skillsDir).filter((entry) => {
|
|
39627
39656
|
const fullPath = join11(skillsDir, entry);
|
|
39628
|
-
return !entry.startsWith(".") && entry !== "_common" &&
|
|
39657
|
+
return !entry.startsWith(".") && entry !== "_common" && statSync5(fullPath).isDirectory();
|
|
39629
39658
|
}) : [];
|
|
39630
39659
|
const directoryNames = new Set(skillDirs);
|
|
39631
39660
|
const registryNameSet = new Set(registryNames);
|
|
@@ -39641,7 +39670,7 @@ function validateRegistryConsistency(registry, skillsDir) {
|
|
|
39641
39670
|
|
|
39642
39671
|
// src/lib/skill-hash.ts
|
|
39643
39672
|
import { createHash as createHash8 } from "crypto";
|
|
39644
|
-
import { existsSync as existsSync7, readdirSync as readdirSync7, readFileSync as readFileSync9, statSync as
|
|
39673
|
+
import { existsSync as existsSync7, readdirSync as readdirSync7, readFileSync as readFileSync9, statSync as statSync6 } from "fs";
|
|
39645
39674
|
import { join as join12, sep as sep2 } from "path";
|
|
39646
39675
|
var CONTENT_HASH_ALGORITHM = "sha256";
|
|
39647
39676
|
var HASH_EXCLUDE_DIRS = new Set([".git", "node_modules", "dist", "build", ".turbo"]);
|
|
@@ -39707,7 +39736,7 @@ function collectBundleFiles(skillPath) {
|
|
|
39707
39736
|
const absolute = join12(skillPath, entry);
|
|
39708
39737
|
if (!existsSync7(absolute))
|
|
39709
39738
|
continue;
|
|
39710
|
-
if (
|
|
39739
|
+
if (statSync6(absolute).isDirectory())
|
|
39711
39740
|
collectDirectory(files, absolute, entry);
|
|
39712
39741
|
else
|
|
39713
39742
|
collectFile(files, absolute, entry);
|
|
@@ -39722,7 +39751,7 @@ function collectDirectory(files, dir, rel) {
|
|
|
39722
39751
|
const childRel = `${rel}/${entry}`;
|
|
39723
39752
|
let stats;
|
|
39724
39753
|
try {
|
|
39725
|
-
stats =
|
|
39754
|
+
stats = statSync6(absolute);
|
|
39726
39755
|
} catch {
|
|
39727
39756
|
continue;
|
|
39728
39757
|
}
|
|
@@ -40871,7 +40900,7 @@ function findPortableSkill(name, options = {}) {
|
|
|
40871
40900
|
return null;
|
|
40872
40901
|
}
|
|
40873
40902
|
const path = getPortableSkillPath(normalized, options);
|
|
40874
|
-
if (!existsSync9(path) || !
|
|
40903
|
+
if (!existsSync9(path) || !statSync8(path).isDirectory())
|
|
40875
40904
|
return null;
|
|
40876
40905
|
try {
|
|
40877
40906
|
return summarizePortableSkill(path, normalized);
|
|
@@ -40940,7 +40969,7 @@ function scaffoldPortableSkill(name, options = {}) {
|
|
|
40940
40969
|
}
|
|
40941
40970
|
function portPortableSkillDirectory(sourceDir, options = {}) {
|
|
40942
40971
|
const absoluteSource = normalize2(sourceDir);
|
|
40943
|
-
if (!existsSync9(absoluteSource) || !
|
|
40972
|
+
if (!existsSync9(absoluteSource) || !statSync8(absoluteSource).isDirectory()) {
|
|
40944
40973
|
throw new Error(`Import directory not found: ${sourceDir}`);
|
|
40945
40974
|
}
|
|
40946
40975
|
const continueOnError = options.continueOnError ?? true;
|
|
@@ -41006,7 +41035,7 @@ function assertDisjointImportPaths(source, destination) {
|
|
|
41006
41035
|
}
|
|
41007
41036
|
function portPortableSkill(sourcePath, options = {}) {
|
|
41008
41037
|
const absoluteSource = normalize2(sourcePath);
|
|
41009
|
-
if (!existsSync9(absoluteSource) || !
|
|
41038
|
+
if (!existsSync9(absoluteSource) || !statSync8(absoluteSource).isDirectory()) {
|
|
41010
41039
|
throw new Error(`Skill source directory not found: ${sourcePath}`);
|
|
41011
41040
|
}
|
|
41012
41041
|
const inferred = readPortableSkillManifestForImport(absoluteSource);
|
|
@@ -41170,7 +41199,7 @@ function validatePortableSkillDirectory(name, skillPath) {
|
|
|
41170
41199
|
const entryPath = join14(skillPath, command3.entry);
|
|
41171
41200
|
if (!existsSync9(entryPath))
|
|
41172
41201
|
add3(issues, "portable.command_entry_missing", `Command '${command3.name}' entry '${command3.entry}' is missing`);
|
|
41173
|
-
else if (
|
|
41202
|
+
else if (statSync8(entryPath).isDirectory())
|
|
41174
41203
|
add3(issues, "portable.command_entry_directory", `Command '${command3.name}' entry '${command3.entry}' must be a file`);
|
|
41175
41204
|
}
|
|
41176
41205
|
}
|
|
@@ -41260,7 +41289,7 @@ function summarizePortableSkill(skillPath, fallbackName) {
|
|
|
41260
41289
|
}
|
|
41261
41290
|
function safeIsDirectory(path) {
|
|
41262
41291
|
try {
|
|
41263
|
-
return
|
|
41292
|
+
return statSync8(path).isDirectory();
|
|
41264
41293
|
} catch {
|
|
41265
41294
|
return false;
|
|
41266
41295
|
}
|
|
@@ -41400,7 +41429,7 @@ function containsSkillDirectories(path) {
|
|
|
41400
41429
|
}
|
|
41401
41430
|
function isDirectory(path) {
|
|
41402
41431
|
try {
|
|
41403
|
-
return
|
|
41432
|
+
return statSync9(path).isDirectory();
|
|
41404
41433
|
} catch {
|
|
41405
41434
|
return false;
|
|
41406
41435
|
}
|