@hasna/skills 0.6.0 → 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 +105 -69
- package/bin/mcp.js +1 -2
- package/bin/migrate.js +1 -1
- package/bin/server.js +1 -1
- package/bin/worker.js +1 -1
- package/dist/cli/commands/runtime.d.ts +0 -3
- package/dist/cli/output.d.ts +2 -0
- package/dist/index.js +56 -27
- package/dist/sdk/index.js +56 -27
- package/package.json +1 -1
package/bin/index.js
CHANGED
|
@@ -47,6 +47,14 @@ var __export = (target, all) => {
|
|
|
47
47
|
var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
|
|
48
48
|
var __require = import.meta.require;
|
|
49
49
|
|
|
50
|
+
// src/cli/output.ts
|
|
51
|
+
async function writeCliOutput(text, newline = true) {
|
|
52
|
+
await new Promise((resolve, reject) => {
|
|
53
|
+
process.stdout.write(newline ? `${text}
|
|
54
|
+
` : text, (error) => error ? reject(error) : resolve());
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
|
|
50
58
|
// ../../node_modules/.bun/react@18.3.1/node_modules/react/cjs/react.development.js
|
|
51
59
|
var require_react_development = __commonJS((exports, module) => {
|
|
52
60
|
if (true) {
|
|
@@ -36860,7 +36868,7 @@ var package_default;
|
|
|
36860
36868
|
var init_package = __esm(() => {
|
|
36861
36869
|
package_default = {
|
|
36862
36870
|
name: "@hasna/skills",
|
|
36863
|
-
version: "0.6.
|
|
36871
|
+
version: "0.6.2",
|
|
36864
36872
|
description: "Skills library for AI coding agents",
|
|
36865
36873
|
type: "module",
|
|
36866
36874
|
bin: {
|
|
@@ -42998,7 +43006,7 @@ var require_cli_spinners = __commonJS((exports, module) => {
|
|
|
42998
43006
|
|
|
42999
43007
|
// src/lib/agent-integration.ts
|
|
43000
43008
|
import { createHash as createHash2, randomUUID as randomUUID3 } from "crypto";
|
|
43001
|
-
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";
|
|
43002
43010
|
import { dirname as dirname4, join as join13, resolve as resolve4, relative as relative3, isAbsolute as isAbsolute3, sep as sep3 } from "path";
|
|
43003
43011
|
import { homedir as homedir3 } from "os";
|
|
43004
43012
|
function assertSafePath(path) {
|
|
@@ -43086,15 +43094,27 @@ function inventoryNativeSkills(home = homedir3(), options = {}) {
|
|
|
43086
43094
|
for (const [agent, path] of ROOTS)
|
|
43087
43095
|
roots.push([agent, join13(resolve4(options.projectDir), path)]);
|
|
43088
43096
|
const entries = [], seen = new Set;
|
|
43089
|
-
|
|
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 };
|
|
43090
43109
|
assertSafePath(path);
|
|
43091
43110
|
if (!existsSync13(path))
|
|
43092
|
-
return;
|
|
43111
|
+
return scan;
|
|
43093
43112
|
if (!lstatSync3(path).isDirectory())
|
|
43094
|
-
return;
|
|
43113
|
+
return scan;
|
|
43095
43114
|
if (existsSync13(join13(path, "SKILL.md"))) {
|
|
43115
|
+
scan.hasSkills = true;
|
|
43096
43116
|
if (seen.has(path))
|
|
43097
|
-
return;
|
|
43117
|
+
return scan;
|
|
43098
43118
|
seen.add(path);
|
|
43099
43119
|
let managed = false;
|
|
43100
43120
|
const marker = join13(path, ".hasna-skills.json");
|
|
@@ -43105,11 +43125,14 @@ function inventoryNativeSkills(home = homedir3(), options = {}) {
|
|
|
43105
43125
|
}
|
|
43106
43126
|
const rootAlias = aliases.find((item) => path === item.target || path.startsWith(item.target + sep3));
|
|
43107
43127
|
entries.push({ agent, path, hash: treeHash(path), managed, vendor, ...rootAlias ? { rootAlias } : {} });
|
|
43108
|
-
return;
|
|
43128
|
+
return scan;
|
|
43109
43129
|
}
|
|
43110
43130
|
if (depth > (vendor ? 8 : 3))
|
|
43111
|
-
return;
|
|
43112
|
-
|
|
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) {
|
|
43113
43136
|
if (name === "node_modules")
|
|
43114
43137
|
continue;
|
|
43115
43138
|
if (name.startsWith(".") && name !== ".system")
|
|
@@ -43117,14 +43140,28 @@ function inventoryNativeSkills(home = homedir3(), options = {}) {
|
|
|
43117
43140
|
const isVendor = vendor || name === ".system";
|
|
43118
43141
|
if (isVendor && !options.includeVendor)
|
|
43119
43142
|
continue;
|
|
43120
|
-
|
|
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;
|
|
43121
43155
|
}
|
|
43156
|
+
if (pluginCache)
|
|
43157
|
+
cacheScans.set(path, scan);
|
|
43158
|
+
return scan;
|
|
43122
43159
|
}
|
|
43123
43160
|
for (const [agent, path] of roots)
|
|
43124
43161
|
visit(agent, path);
|
|
43125
43162
|
if (options.includeVendor) {
|
|
43126
43163
|
for (const agent of ["codex", "claude"])
|
|
43127
|
-
visit(agent, canonicalAgentPath(join13(home, `.${agent}`, "plugins", "cache"), aliases), true);
|
|
43164
|
+
visit(agent, canonicalAgentPath(join13(home, `.${agent}`, "plugins", "cache"), aliases), true, 0, true);
|
|
43128
43165
|
}
|
|
43129
43166
|
recheckRootAliases(aliases);
|
|
43130
43167
|
return entries;
|
|
@@ -43355,7 +43392,7 @@ var init_agent_integration = __esm(() => {
|
|
|
43355
43392
|
});
|
|
43356
43393
|
|
|
43357
43394
|
// src/lib/home-migration.ts
|
|
43358
|
-
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";
|
|
43359
43396
|
import { join as join14 } from "path";
|
|
43360
43397
|
function layoutMigrationRecordPath(appDir) {
|
|
43361
43398
|
return join14(appDir, SKILLS_CACHE_DIRNAME, LAYOUT_MIGRATION_RECORD);
|
|
@@ -43368,7 +43405,7 @@ function migrationAppDir(homeDir) {
|
|
|
43368
43405
|
}
|
|
43369
43406
|
function looksLikeSkillDirectory2(path) {
|
|
43370
43407
|
try {
|
|
43371
|
-
if (!
|
|
43408
|
+
if (!statSync8(path).isDirectory())
|
|
43372
43409
|
return false;
|
|
43373
43410
|
} catch {
|
|
43374
43411
|
return false;
|
|
@@ -43500,7 +43537,7 @@ import {
|
|
|
43500
43537
|
readdirSync as readdirSync9,
|
|
43501
43538
|
renameSync as renameSync4,
|
|
43502
43539
|
rmSync as rmSync3,
|
|
43503
|
-
statSync as
|
|
43540
|
+
statSync as statSync9,
|
|
43504
43541
|
writeFileSync as writeFileSync6
|
|
43505
43542
|
} from "fs";
|
|
43506
43543
|
import { homedir as homedir4 } from "os";
|
|
@@ -43617,7 +43654,7 @@ function containsSkillDirectories(path) {
|
|
|
43617
43654
|
}
|
|
43618
43655
|
function isDirectory(path) {
|
|
43619
43656
|
try {
|
|
43620
|
-
return
|
|
43657
|
+
return statSync9(path).isDirectory();
|
|
43621
43658
|
} catch {
|
|
43622
43659
|
return false;
|
|
43623
43660
|
}
|
|
@@ -50115,7 +50152,7 @@ var init_remote_workspace_leave = __esm(() => {
|
|
|
50115
50152
|
});
|
|
50116
50153
|
|
|
50117
50154
|
// src/lib/auth-store.ts
|
|
50118
|
-
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";
|
|
50119
50156
|
import { basename as basename4, dirname as dirname7, join as join19 } from "path";
|
|
50120
50157
|
function getAuthFilePath(env3 = process.env) {
|
|
50121
50158
|
return skillsCredentialFilePath(env3);
|
|
@@ -50273,7 +50310,7 @@ function getApiUrl(action, env3 = process.env, options = {}) {
|
|
|
50273
50310
|
}
|
|
50274
50311
|
function credentialFileMode(env3 = process.env) {
|
|
50275
50312
|
try {
|
|
50276
|
-
return
|
|
50313
|
+
return statSync10(skillsCredentialFilePath(env3)).mode & 511;
|
|
50277
50314
|
} catch {
|
|
50278
50315
|
return null;
|
|
50279
50316
|
}
|
|
@@ -51422,7 +51459,7 @@ var init_revision = __esm(() => {
|
|
|
51422
51459
|
|
|
51423
51460
|
// src/lib/skill-bundle.ts
|
|
51424
51461
|
import { createHash as createHash5 } from "crypto";
|
|
51425
|
-
import { readFileSync as readFileSync14, readdirSync as readdirSync10, statSync as
|
|
51462
|
+
import { readFileSync as readFileSync14, readdirSync as readdirSync10, statSync as statSync11 } from "fs";
|
|
51426
51463
|
import { join as join20, relative as relative4 } from "path";
|
|
51427
51464
|
import { createGunzip } from "zlib";
|
|
51428
51465
|
function isDotenvFile(lower) {
|
|
@@ -51483,7 +51520,7 @@ function walk(root, current, out) {
|
|
|
51483
51520
|
continue;
|
|
51484
51521
|
if (isCredentialFile(entry.name))
|
|
51485
51522
|
continue;
|
|
51486
|
-
const stats =
|
|
51523
|
+
const stats = statSync11(absolute);
|
|
51487
51524
|
out.push({
|
|
51488
51525
|
path: rel,
|
|
51489
51526
|
bytes: ownBytes(readFileSync14(absolute)),
|
|
@@ -53548,7 +53585,7 @@ function registerContextCommands(parent) {
|
|
|
53548
53585
|
sessionId: options.session,
|
|
53549
53586
|
file: options.file
|
|
53550
53587
|
});
|
|
53551
|
-
|
|
53588
|
+
await writeCliOutput(options.json ? JSON.stringify(result2) : result2.content);
|
|
53552
53589
|
} catch (error) {
|
|
53553
53590
|
reportContextError(error, options.json);
|
|
53554
53591
|
}
|
|
@@ -53565,7 +53602,7 @@ function registerContextCommands(parent) {
|
|
|
53565
53602
|
maxChars: Number(options.maxChars),
|
|
53566
53603
|
maxSkills: Number(options.maxSkills)
|
|
53567
53604
|
});
|
|
53568
|
-
|
|
53605
|
+
await writeCliOutput(options.json ? JSON.stringify(result2) : result2.context);
|
|
53569
53606
|
} catch (error) {
|
|
53570
53607
|
reportContextError(error, options.json);
|
|
53571
53608
|
}
|
|
@@ -53656,9 +53693,9 @@ async function handleProfileSync(options, dependencies = {}) {
|
|
|
53656
53693
|
check: options.check ?? dependencies.check
|
|
53657
53694
|
});
|
|
53658
53695
|
if (options.json)
|
|
53659
|
-
|
|
53696
|
+
await writeCliOutput(JSON.stringify(result2));
|
|
53660
53697
|
else
|
|
53661
|
-
|
|
53698
|
+
await writeCliOutput(options.check ? result2.changed ? "Skills profile or cached bundles need syncing." : "Skills profile and cached bundles are current." : `Synced Skills profile ${result2.profile.profileId} at ${result2.profile.profileRevision}; ${result2.downloaded} bundle(s) downloaded.`);
|
|
53662
53699
|
if (options.check && result2.changed)
|
|
53663
53700
|
process.exitCode = 1;
|
|
53664
53701
|
} catch (error) {
|
|
@@ -55427,7 +55464,7 @@ var init_init = __esm(() => {
|
|
|
55427
55464
|
});
|
|
55428
55465
|
|
|
55429
55466
|
// src/lib/home-adoption.ts
|
|
55430
|
-
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";
|
|
55431
55468
|
import { homedir as homedir6 } from "os";
|
|
55432
55469
|
import { join as join27 } from "path";
|
|
55433
55470
|
function indexCanonicalCorpus(corpusRoot) {
|
|
@@ -55463,7 +55500,7 @@ function selectedHomeNames(options, index, homeDir2, agents) {
|
|
|
55463
55500
|
continue;
|
|
55464
55501
|
const present = agents.some((agent) => {
|
|
55465
55502
|
try {
|
|
55466
|
-
return
|
|
55503
|
+
return statSync12(join27(agentGlobalSkillsDir(agent, homeDir2), name)).isDirectory();
|
|
55467
55504
|
} catch {
|
|
55468
55505
|
return false;
|
|
55469
55506
|
}
|
|
@@ -55497,7 +55534,7 @@ function scanUnmarkedHomes(options = {}) {
|
|
|
55497
55534
|
continue;
|
|
55498
55535
|
const dir = join27(home, skill);
|
|
55499
55536
|
try {
|
|
55500
|
-
if (!
|
|
55537
|
+
if (!statSync12(dir).isDirectory())
|
|
55501
55538
|
continue;
|
|
55502
55539
|
} catch {
|
|
55503
55540
|
continue;
|
|
@@ -55510,7 +55547,7 @@ function scanUnmarkedHomes(options = {}) {
|
|
|
55510
55547
|
if (!existsSync24(skillMdPath))
|
|
55511
55548
|
continue;
|
|
55512
55549
|
const hash2 = hashSkillMarkdownFile(skillMdPath);
|
|
55513
|
-
const mtime =
|
|
55550
|
+
const mtime = statSync12(skillMdPath).mtime.toISOString();
|
|
55514
55551
|
const entry = { agent, skill, home, path: dir, hash: hash2, mtime };
|
|
55515
55552
|
const canonicalHash = index.get(skill);
|
|
55516
55553
|
if (canonicalHash === undefined) {
|
|
@@ -55639,7 +55676,7 @@ function pruneStrayHomes(options = {}) {
|
|
|
55639
55676
|
continue;
|
|
55640
55677
|
const dir = join27(home, skill);
|
|
55641
55678
|
try {
|
|
55642
|
-
if (!
|
|
55679
|
+
if (!statSync12(dir).isDirectory())
|
|
55643
55680
|
continue;
|
|
55644
55681
|
} catch {
|
|
55645
55682
|
continue;
|
|
@@ -55680,7 +55717,7 @@ var init_home_adoption = __esm(() => {
|
|
|
55680
55717
|
});
|
|
55681
55718
|
|
|
55682
55719
|
// src/lib/home-census.ts
|
|
55683
|
-
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";
|
|
55684
55721
|
import { homedir as homedir7 } from "os";
|
|
55685
55722
|
import { join as join28 } from "path";
|
|
55686
55723
|
function sortEntries(entries) {
|
|
@@ -55725,7 +55762,7 @@ function censusHomeDrift(options = {}) {
|
|
|
55725
55762
|
continue;
|
|
55726
55763
|
const dir = join28(home, skill);
|
|
55727
55764
|
try {
|
|
55728
|
-
if (!
|
|
55765
|
+
if (!statSync13(dir).isDirectory())
|
|
55729
55766
|
continue;
|
|
55730
55767
|
} catch {
|
|
55731
55768
|
continue;
|
|
@@ -55978,7 +56015,7 @@ var exports_diagnostic = {};
|
|
|
55978
56015
|
__export(exports_diagnostic, {
|
|
55979
56016
|
registerDiagnostic: () => registerDiagnostic
|
|
55980
56017
|
});
|
|
55981
|
-
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";
|
|
55982
56019
|
import { join as join29 } from "path";
|
|
55983
56020
|
import { execSync as execSync2 } from "child_process";
|
|
55984
56021
|
function registerDiagnostic(parent) {
|
|
@@ -56171,7 +56208,7 @@ function handleWhoami(options) {
|
|
|
56171
56208
|
let skillCount = 0;
|
|
56172
56209
|
if (exists)
|
|
56173
56210
|
try {
|
|
56174
|
-
skillCount = readdirSync13(agentSkillsPath).filter((f) => !f.startsWith(".") &&
|
|
56211
|
+
skillCount = readdirSync13(agentSkillsPath).filter((f) => !f.startsWith(".") && statSync14(join29(agentSkillsPath, f)).isDirectory()).length;
|
|
56175
56212
|
} catch {}
|
|
56176
56213
|
agentConfigs.push({ agent, label: AGENT_LABELS[agent], path: agentSkillsPath, exists, skillCount });
|
|
56177
56214
|
}
|
|
@@ -56758,7 +56795,7 @@ var init_runs = __esm(() => {
|
|
|
56758
56795
|
|
|
56759
56796
|
// src/lib/run-state.ts
|
|
56760
56797
|
import { createHash as createHash9, randomBytes } from "crypto";
|
|
56761
|
-
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";
|
|
56762
56799
|
import { extname, join as join31, relative as relative5 } from "path";
|
|
56763
56800
|
function createSkillRun(params, targetDir = process.cwd()) {
|
|
56764
56801
|
const now3 = new Date;
|
|
@@ -56840,7 +56877,7 @@ function listSkillRuns(targetDir = process.cwd(), limit = 50) {
|
|
|
56840
56877
|
const records = [];
|
|
56841
56878
|
for (const day of readdirSync14(runsRoot).sort().reverse()) {
|
|
56842
56879
|
const dayDir = join31(runsRoot, day);
|
|
56843
|
-
if (!
|
|
56880
|
+
if (!statSync15(dayDir).isDirectory())
|
|
56844
56881
|
continue;
|
|
56845
56882
|
for (const runId2 of readdirSync14(dayDir).sort().reverse()) {
|
|
56846
56883
|
const record4 = readRunRecord(join31(dayDir, runId2));
|
|
@@ -56889,7 +56926,7 @@ function collectRunArtifacts(context) {
|
|
|
56889
56926
|
return [];
|
|
56890
56927
|
const artifacts = [];
|
|
56891
56928
|
for (const path of walkFiles(context.exportDir)) {
|
|
56892
|
-
const stat =
|
|
56929
|
+
const stat = statSync15(path);
|
|
56893
56930
|
const bytes = readFileSync25(path);
|
|
56894
56931
|
artifacts.push({
|
|
56895
56932
|
path: toProjectRelative(context.targetDir, path),
|
|
@@ -56914,7 +56951,7 @@ function walkFiles(dir) {
|
|
|
56914
56951
|
const files = [];
|
|
56915
56952
|
for (const entry of readdirSync14(dir)) {
|
|
56916
56953
|
const full = join31(dir, entry);
|
|
56917
|
-
if (
|
|
56954
|
+
if (statSync15(full).isDirectory())
|
|
56918
56955
|
files.push(...walkFiles(full));
|
|
56919
56956
|
else
|
|
56920
56957
|
files.push(full);
|
|
@@ -74823,7 +74860,7 @@ var init_run_routing = __esm(() => {
|
|
|
74823
74860
|
});
|
|
74824
74861
|
|
|
74825
74862
|
// src/mcp/operation-tools.ts
|
|
74826
|
-
import { existsSync as existsSync28, readdirSync as readdirSync15, statSync as
|
|
74863
|
+
import { existsSync as existsSync28, readdirSync as readdirSync15, statSync as statSync16 } from "fs";
|
|
74827
74864
|
import { join as join32 } from "path";
|
|
74828
74865
|
function registerOperationTools(server) {
|
|
74829
74866
|
server.registerTool("scaffold_skill", {
|
|
@@ -75282,7 +75319,7 @@ function registerOperationTools(server) {
|
|
|
75282
75319
|
try {
|
|
75283
75320
|
skillCount = readdirSync15(agentSkillsPath).filter((f) => {
|
|
75284
75321
|
const full = join32(agentSkillsPath, f);
|
|
75285
|
-
return !f.startsWith(".") &&
|
|
75322
|
+
return !f.startsWith(".") && statSync16(full).isDirectory();
|
|
75286
75323
|
}).length;
|
|
75287
75324
|
} catch {}
|
|
75288
75325
|
}
|
|
@@ -75869,7 +75906,7 @@ import {
|
|
|
75869
75906
|
mkdirSync as mkdirSync16,
|
|
75870
75907
|
readFileSync as readFileSync27,
|
|
75871
75908
|
readdirSync as readdirSync16,
|
|
75872
|
-
statSync as
|
|
75909
|
+
statSync as statSync17,
|
|
75873
75910
|
writeFileSync as writeFileSync16
|
|
75874
75911
|
} from "fs";
|
|
75875
75912
|
import { dirname as dirname12, join as join35, normalize as normalize3, relative as relative6, sep as sep4 } from "path";
|
|
@@ -75995,7 +76032,7 @@ function walkFiles2(dir) {
|
|
|
75995
76032
|
const files = [];
|
|
75996
76033
|
for (const entry of readdirSync16(dir)) {
|
|
75997
76034
|
const full = join35(dir, entry);
|
|
75998
|
-
const stats =
|
|
76035
|
+
const stats = statSync17(full);
|
|
75999
76036
|
if (stats.isDirectory())
|
|
76000
76037
|
files.push(...walkFiles2(full));
|
|
76001
76038
|
else
|
|
@@ -77924,7 +77961,7 @@ function registerRuntime(parent) {
|
|
|
77924
77961
|
try {
|
|
77925
77962
|
const client = await CloudExecutionClient.configured();
|
|
77926
77963
|
const value = operation === "show" ? await client.get(id) : await client[operation](id);
|
|
77927
|
-
|
|
77964
|
+
await writeCliOutput(JSON.stringify(value, null, 2));
|
|
77928
77965
|
} catch (error2) {
|
|
77929
77966
|
console.error(JSON.stringify({ error: error2.message }));
|
|
77930
77967
|
process.exitCode = 1;
|
|
@@ -78260,9 +78297,9 @@ async function handleRun(name, args2, options) {
|
|
|
78260
78297
|
throw new Error("Selected local execution accepts arguments and structured --input only");
|
|
78261
78298
|
const result4 = await executeSelectedLocal(selected, { args: args2, input, cwd: process.cwd() });
|
|
78262
78299
|
if (options.json)
|
|
78263
|
-
|
|
78300
|
+
await writeCliOutput(JSON.stringify(result4, null, 2));
|
|
78264
78301
|
else {
|
|
78265
|
-
|
|
78302
|
+
await writeCliOutput(result4.stdout, false);
|
|
78266
78303
|
process.stderr.write(result4.stderr);
|
|
78267
78304
|
console.error(JSON.stringify({ selection: result4.selection, target: result4.target, exitCode: result4.exitCode, runDirectory: result4.runDirectory }));
|
|
78268
78305
|
}
|
|
@@ -78281,7 +78318,7 @@ async function handleRun(name, args2, options) {
|
|
|
78281
78318
|
if (options.wait)
|
|
78282
78319
|
console.error(JSON.stringify({ executionId: admitted.id, status: admitted.status }));
|
|
78283
78320
|
const result3 = options.wait ? await client2.wait(admitted.id, { timeoutMs, intervalMs }) : admitted;
|
|
78284
|
-
|
|
78321
|
+
await writeCliOutput(JSON.stringify(result3, null, 2));
|
|
78285
78322
|
if (["failed", "cancelled"].includes(result3.status))
|
|
78286
78323
|
process.exitCode = 1;
|
|
78287
78324
|
} catch (error2) {
|
|
@@ -78484,7 +78521,7 @@ async function handleRun(name, args2, options) {
|
|
|
78484
78521
|
console.log(JSON.stringify({ skill: skill.name, args: args2, ...result2, run: completed }, null, 2));
|
|
78485
78522
|
else {
|
|
78486
78523
|
if (result2.stdout)
|
|
78487
|
-
|
|
78524
|
+
await writeCliOutput(result2.stdout, false);
|
|
78488
78525
|
if (result2.stderr)
|
|
78489
78526
|
process.stderr.write(result2.stderr);
|
|
78490
78527
|
if (result2.error)
|
|
@@ -79110,7 +79147,7 @@ var init_completion = __esm(() => {
|
|
|
79110
79147
|
});
|
|
79111
79148
|
|
|
79112
79149
|
// src/lib/portable-snapshot-filter.ts
|
|
79113
|
-
import { readdirSync as readdirSync17, statSync as
|
|
79150
|
+
import { readdirSync as readdirSync17, statSync as statSync18 } from "fs";
|
|
79114
79151
|
import { homedir as homedir9 } from "os";
|
|
79115
79152
|
import { join as join40, sep as sep5 } from "path";
|
|
79116
79153
|
function isExcludedSkillFileName(fileName) {
|
|
@@ -79178,7 +79215,7 @@ function walkEntries(absoluteRoot) {
|
|
|
79178
79215
|
}
|
|
79179
79216
|
function isRegularFile(filePath) {
|
|
79180
79217
|
try {
|
|
79181
|
-
return
|
|
79218
|
+
return statSync18(filePath).isFile();
|
|
79182
79219
|
} catch {
|
|
79183
79220
|
return false;
|
|
79184
79221
|
}
|
|
@@ -79264,7 +79301,7 @@ import {
|
|
|
79264
79301
|
copyFileSync as copyFileSync2,
|
|
79265
79302
|
mkdirSync as mkdirSync21,
|
|
79266
79303
|
readFileSync as readFileSync31,
|
|
79267
|
-
statSync as
|
|
79304
|
+
statSync as statSync19,
|
|
79268
79305
|
writeFileSync as writeFileSync21
|
|
79269
79306
|
} from "fs";
|
|
79270
79307
|
import { dirname as dirname17, isAbsolute as isAbsolute8, relative as relative7, resolve as resolve9, sep as sep6 } from "path";
|
|
@@ -79304,7 +79341,7 @@ function scanHome(definition, homesRoot) {
|
|
|
79304
79341
|
skipped.push({ relativePath: entry.relativePath, reason: "not-regular-file" });
|
|
79305
79342
|
continue;
|
|
79306
79343
|
}
|
|
79307
|
-
const info =
|
|
79344
|
+
const info = statSync19(entry.fullPath);
|
|
79308
79345
|
portable.push({
|
|
79309
79346
|
relativePath: entry.relativePath,
|
|
79310
79347
|
fullPath: entry.fullPath,
|
|
@@ -79856,15 +79893,15 @@ function agents(value) {
|
|
|
79856
79893
|
}
|
|
79857
79894
|
function registerAgentIntegration(parent) {
|
|
79858
79895
|
const hook = parent.command("hook").description("Load selected Skills context through agent lifecycle hooks");
|
|
79859
|
-
hook.command("install").option("--agent <agent>", "Agent to configure: claude, codex, all", "all").option("--command <path>", "Skills executable used by the hook", "skills").option("--selection-profile <id>", "Shared selection profile", "default").option("--include-vendor", "Also disable discovered vendor system skills in Codex", false).option("--allow-root-aliases", "Allow home .claude/.codex aliases to existing directories within this home", false).option("--apply", "Apply the plan, preserving prior configuration in private backups", false).option("--json", "Output a receipt as JSON", false).description("Plan or install prompt hooks and disable native skill invocation").action((options) => {
|
|
79896
|
+
hook.command("install").option("--agent <agent>", "Agent to configure: claude, codex, all", "all").option("--command <path>", "Skills executable used by the hook", "skills").option("--selection-profile <id>", "Shared selection profile", "default").option("--include-vendor", "Also disable discovered vendor system skills in Codex", false).option("--allow-root-aliases", "Allow home .claude/.codex aliases to existing directories within this home", false).option("--apply", "Apply the plan, preserving prior configuration in private backups", false).option("--json", "Output a receipt as JSON", false).description("Plan or install prompt hooks and disable native skill invocation").action(async (options) => {
|
|
79860
79897
|
try {
|
|
79861
79898
|
const plan = planAgentIntegration({ agents: agents(options.agent), command: options.command, profileId: options.selectionProfile, includeVendor: options.includeVendor, allowRootAliases: options.allowRootAliases });
|
|
79862
79899
|
const result2 = options.apply ? applyAgentIntegration(plan) : { changed: [], backups: [] };
|
|
79863
79900
|
const receipt = { applied: options.apply, planned: plan.changes.map((change) => change.path), ...result2, rootAliases: plan.rootAliases ?? [], nativeSkills: plan.nativeSkills.map((entry) => ({ agent: entry.agent, path: entry.path, managed: entry.managed, vendor: entry.vendor })) };
|
|
79864
79901
|
if (options.json)
|
|
79865
|
-
|
|
79902
|
+
await writeCliOutput(JSON.stringify(receipt));
|
|
79866
79903
|
else
|
|
79867
|
-
|
|
79904
|
+
await writeCliOutput(`${options.apply ? "Configured" : "Planned"} ${plan.changes.length} agent configuration change(s).${options.apply ? " Restart the agent and trust the installed hook configuration." : " Use --apply to install."}`);
|
|
79868
79905
|
} catch (error2) {
|
|
79869
79906
|
console.error(error2.message);
|
|
79870
79907
|
process.exitCode = 1;
|
|
@@ -79906,29 +79943,29 @@ function registerAgentIntegration(parent) {
|
|
|
79906
79943
|
const result2 = JSON.parse(stdout);
|
|
79907
79944
|
if (typeof result2.context !== "string")
|
|
79908
79945
|
throw new Error("Invalid Skills context response");
|
|
79909
|
-
|
|
79946
|
+
await writeCliOutput(JSON.stringify(hookContextOutput(event, result2)));
|
|
79910
79947
|
} finally {
|
|
79911
79948
|
clearTimeout(timer);
|
|
79912
79949
|
}
|
|
79913
79950
|
} catch {
|
|
79914
79951
|
const reason = "Skills context is unavailable. Run skills sync --selection-profile <id> and skills context --stdin --json to diagnose the selected profile.";
|
|
79915
79952
|
if (event === "UserPromptSubmit")
|
|
79916
|
-
|
|
79953
|
+
await writeCliOutput(JSON.stringify({ decision: "block", reason }));
|
|
79917
79954
|
else if (event === "SessionStart")
|
|
79918
|
-
|
|
79955
|
+
await writeCliOutput(JSON.stringify({ continue: false, stopReason: reason, systemMessage: reason }));
|
|
79919
79956
|
else
|
|
79920
|
-
|
|
79957
|
+
await writeCliOutput(JSON.stringify({ systemMessage: reason, hookSpecificOutput: { hookEventName: "SubagentStart", additionalContext: "Required Skills context was unavailable. Report this to the parent before performing task actions." } }));
|
|
79921
79958
|
}
|
|
79922
79959
|
});
|
|
79923
79960
|
const migrate = parent.command("migrate").description("Preserve and retire native agent skill copies");
|
|
79924
|
-
migrate.command("native").option("--project <directory>", "Also inventory native skills in a project directory").option("--include-unmanaged", "Archive user-authored skills as well as Skills-managed copies", false).option("--allow-root-aliases", "Allow home .claude/.codex aliases to existing directories within this home", false).option("--apply", "Move selected skills to private archives outside agent discovery roots", false).option("--json", "Output inventory and archive receipt as JSON", false).description("Inventory native skill copies; preserve complete directories before retiring them").action((options) => {
|
|
79961
|
+
migrate.command("native").option("--project <directory>", "Also inventory native skills in a project directory").option("--include-unmanaged", "Archive user-authored skills as well as Skills-managed copies", false).option("--allow-root-aliases", "Allow home .claude/.codex aliases to existing directories within this home", false).option("--apply", "Move selected skills to private archives outside agent discovery roots", false).option("--json", "Output inventory and archive receipt as JSON", false).description("Inventory native skill copies; preserve complete directories before retiring them").action(async (options) => {
|
|
79925
79962
|
try {
|
|
79926
79963
|
const inventory = inventoryNativeSkills(undefined, { projectDir: options.project, allowRootAliases: options.allowRootAliases });
|
|
79927
79964
|
const result2 = options.apply ? archiveNativeSkills(inventory, { includeUnmanaged: options.includeUnmanaged, allowRootAliases: options.allowRootAliases }) : { entries: [] };
|
|
79928
79965
|
if (options.json)
|
|
79929
|
-
|
|
79966
|
+
await writeCliOutput(JSON.stringify({ applied: options.apply, inventory, ...result2 }));
|
|
79930
79967
|
else
|
|
79931
|
-
|
|
79968
|
+
await writeCliOutput(`${inventory.length} native skill(s) found; ${result2.entries.length} archived with recovery receipts.${options.apply ? "" : " Use --apply to archive managed copies."}`);
|
|
79932
79969
|
} catch (error2) {
|
|
79933
79970
|
console.error(error2.message);
|
|
79934
79971
|
process.exitCode = 1;
|
|
@@ -80008,7 +80045,7 @@ function registerProfiles(parent) {
|
|
|
80008
80045
|
if (options.save)
|
|
80009
80046
|
writeFileSync22(options.save, `${text2}
|
|
80010
80047
|
`, { mode: 384, flag: "wx" });
|
|
80011
|
-
|
|
80048
|
+
await writeCliOutput(options.json ? text2 : `${profile.id} at ${profile.revision}: ${profile.selections.map((skill) => `${skill.slug}@${skill.version}`).join(", ")}`);
|
|
80012
80049
|
} catch (error2) {
|
|
80013
80050
|
console.error(error2.message);
|
|
80014
80051
|
process.exitCode = 1;
|
|
@@ -80021,7 +80058,7 @@ function registerProfiles(parent) {
|
|
|
80021
80058
|
throw new Error("Profile input exceeds the size limit");
|
|
80022
80059
|
const input = JSON.parse(text2);
|
|
80023
80060
|
const profile = await saveSkillProfile(id2, input.selections, options.ifMatch);
|
|
80024
|
-
|
|
80061
|
+
await writeCliOutput(options.json ? JSON.stringify(profile) : `Saved ${profile.id} at ${profile.revision}`);
|
|
80025
80062
|
} catch (error2) {
|
|
80026
80063
|
console.error(error2.message);
|
|
80027
80064
|
process.exitCode = 1;
|
|
@@ -80029,7 +80066,7 @@ function registerProfiles(parent) {
|
|
|
80029
80066
|
});
|
|
80030
80067
|
parent.command("station-state <id>").description("Read this actor's last applied skill selection on a station").option("--json", "Output the station receipt as JSON", false).action(async (id2) => {
|
|
80031
80068
|
try {
|
|
80032
|
-
|
|
80069
|
+
await writeCliOutput(JSON.stringify(await readStationSkillState(id2), null, 2));
|
|
80033
80070
|
} catch (error2) {
|
|
80034
80071
|
console.error(error2.message);
|
|
80035
80072
|
process.exitCode = 1;
|
|
@@ -80047,7 +80084,7 @@ import {
|
|
|
80047
80084
|
mkdirSync as mkdirSync22,
|
|
80048
80085
|
readdirSync as readdirSync18,
|
|
80049
80086
|
readFileSync as readFileSync34,
|
|
80050
|
-
statSync as
|
|
80087
|
+
statSync as statSync20,
|
|
80051
80088
|
writeFileSync as writeFileSync23
|
|
80052
80089
|
} from "fs";
|
|
80053
80090
|
import { dirname as dirname18, join as join42, resolve as resolve10, sep as sep7 } from "path";
|
|
@@ -80144,7 +80181,7 @@ function planStationHydration(stationId, repoRoot) {
|
|
|
80144
80181
|
});
|
|
80145
80182
|
continue;
|
|
80146
80183
|
}
|
|
80147
|
-
const info =
|
|
80184
|
+
const info = statSync20(entry.fullPath);
|
|
80148
80185
|
const manifestHash = manifestHashes.get(`${agent}${MANIFEST_HASH_KEY_SEP}${homeRelative}`) ?? null;
|
|
80149
80186
|
let verified = false;
|
|
80150
80187
|
if (manifestHash !== null) {
|
|
@@ -82707,11 +82744,11 @@ var init_storage = __esm(() => {
|
|
|
82707
82744
|
});
|
|
82708
82745
|
|
|
82709
82746
|
// src/lib/registry-reconcile.ts
|
|
82710
|
-
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";
|
|
82711
82748
|
import { join as join44 } from "path";
|
|
82712
82749
|
function isDirectory2(path) {
|
|
82713
82750
|
try {
|
|
82714
|
-
return
|
|
82751
|
+
return statSync21(path).isDirectory();
|
|
82715
82752
|
} catch {
|
|
82716
82753
|
return false;
|
|
82717
82754
|
}
|
|
@@ -83147,7 +83184,6 @@ var init_registry_reconcile2 = __esm(() => {
|
|
|
83147
83184
|
init_selection_cache();
|
|
83148
83185
|
init_registry_reconcile();
|
|
83149
83186
|
});
|
|
83150
|
-
|
|
83151
83187
|
// ../../node_modules/.bun/ink@5.2.1+6e93904c7bfe2418/node_modules/ink/build/render.js
|
|
83152
83188
|
import { Stream } from "stream";
|
|
83153
83189
|
import process12 from "process";
|
|
@@ -90963,8 +90999,8 @@ program2.command("interactive", { isDefault: true }).alias("i").allowExcessArgum
|
|
|
90963
90999
|
process.exit(1);
|
|
90964
91000
|
}
|
|
90965
91001
|
if (!isTTY2) {
|
|
90966
|
-
|
|
90967
|
-
|
|
91002
|
+
await writeCliOutput(JSON.stringify(loadBasicRegistry().map(getCompactSkillDiscovery)));
|
|
91003
|
+
return;
|
|
90968
91004
|
}
|
|
90969
91005
|
render_default(/* @__PURE__ */ jsx_dev_runtime7.jsxDEV(App2, {}, undefined, false, undefined, this));
|
|
90970
91006
|
});
|
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: {
|
|
@@ -26973,7 +26973,6 @@ var init_selection_resolver = __esm(() => {
|
|
|
26973
26973
|
init_selected_document();
|
|
26974
26974
|
init_selection_cache();
|
|
26975
26975
|
});
|
|
26976
|
-
|
|
26977
26976
|
// src/lib/skill-context.ts
|
|
26978
26977
|
var init_skill_context = __esm(() => {
|
|
26979
26978
|
init_selection_resolver();
|
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
|
}
|