@hasna/skills 0.10.81 → 0.10.83
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/README.md +35 -0
- package/bin/index.js +279 -57
- package/bin/mcp.js +121 -11
- package/bin/migrate.js +1 -1
- package/bin/server.js +1 -1
- package/bin/worker.js +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +117 -7
- package/dist/lib/agent-discovery-directories.d.ts +2 -1
- package/dist/lib/private-publication-customer.d.ts +4 -1
- package/dist/lib/remote-auth.d.ts +3 -1
- package/dist/lib/remote-private-publications.d.ts +35 -0
- package/dist/runtime-prerequisites.js +3 -2
- package/dist/sdk/index.d.ts +1 -1
- package/dist/sdk/index.js +117 -7
- package/package.json +1 -1
package/dist/sdk/index.js
CHANGED
|
@@ -32371,7 +32371,7 @@ var init_event_sink = __esm(() => {
|
|
|
32371
32371
|
init_dist();
|
|
32372
32372
|
});
|
|
32373
32373
|
// package.json
|
|
32374
|
-
var version = "0.10.
|
|
32374
|
+
var version = "0.10.83";
|
|
32375
32375
|
var package_default = {
|
|
32376
32376
|
name: "@hasna/skills",
|
|
32377
32377
|
version,
|
|
@@ -41268,7 +41268,7 @@ function hashClaudePluginCacheOrphanMarker(path, budget2, changes) {
|
|
|
41268
41268
|
if (!before)
|
|
41269
41269
|
return null;
|
|
41270
41270
|
const uid = process.getuid?.();
|
|
41271
|
-
if (!before.isFile() || uid === undefined || before.uid !== uid || before.size > 32)
|
|
41271
|
+
if (!before.isFile() || uid === undefined || before.uid !== uid || before.size > 32 || (before.mode & 73) !== 0)
|
|
41272
41272
|
throw new Error("Invalid Claude orphan marker file or owner");
|
|
41273
41273
|
const fd = openSync13(path, constants10.O_RDONLY | constants10.O_NOFOLLOW | constants10.O_NONBLOCK);
|
|
41274
41274
|
try {
|
|
@@ -41630,7 +41630,7 @@ function safe2(path) {
|
|
|
41630
41630
|
function same2(before, after) {
|
|
41631
41631
|
return Boolean(after && after.isDirectory() && before.dev === after.dev && before.ino === after.ino && before.mtimeMs === after.mtimeMs && before.ctimeMs === after.ctimeMs);
|
|
41632
41632
|
}
|
|
41633
|
-
function capture(path, budget2, excludedRoots, omittedRoots = [], rows) {
|
|
41633
|
+
function capture(path, budget2, excludedRoots, omittedRoots = [], rows, claudeMarkers) {
|
|
41634
41634
|
safe2(path);
|
|
41635
41635
|
if (omittedRoots.some((root2) => path === root2 || path.startsWith(root2 + "/")))
|
|
41636
41636
|
return { path, sha256: null };
|
|
@@ -41658,6 +41658,11 @@ function capture(path, budget2, excludedRoots, omittedRoots = [], rows) {
|
|
|
41658
41658
|
need4(child2.length <= AGENT_POLICY_LIMITS.pathCharacters, "Native discovery directory path limit exceeded");
|
|
41659
41659
|
const stat = lstatSync13(child2);
|
|
41660
41660
|
need4(stat.isFile() || stat.isDirectory(), "Refusing symlink or special native discovery directory member");
|
|
41661
|
+
if (claudeMarkers && isClaudePluginCacheOrphanMarker(child2)) {
|
|
41662
|
+
need4(hashClaudePluginCacheOrphanMarker(child2) !== null, "Claude orphan marker changed while reading directory");
|
|
41663
|
+
if (claudeMarkers === "omit")
|
|
41664
|
+
continue;
|
|
41665
|
+
}
|
|
41661
41666
|
const row = JSON.stringify([childRelative, stat.isDirectory() ? "directory" : "file"]) + `
|
|
41662
41667
|
`;
|
|
41663
41668
|
budget2.bytes += Buffer.byteLength(row);
|
|
@@ -41714,20 +41719,27 @@ function verifyDiscoveryDirectoryProjection(directories, omittedRoots, tolerance
|
|
|
41714
41719
|
witnessChanged(new NativeDiscoveryWitnessChange("membership", directories[i].path, "Native discovery directory membership changed outside retired Codex roots"), tolerance, tolerance?.acceptsMembership(directories[i].path) === true);
|
|
41715
41720
|
}
|
|
41716
41721
|
}
|
|
41717
|
-
function
|
|
41722
|
+
function captureOrdinaryDirectories(paths, excludedRoots, claudeMarkers) {
|
|
41718
41723
|
need4(Array.isArray(paths) && paths.length <= AGENT_POLICY_LIMITS.discoveryDirectories && new Set(paths).size === paths.length, "Invalid native discovery directory collection");
|
|
41719
41724
|
const budget2 = { entries: 0, bytes: 0 };
|
|
41720
41725
|
for (const root of excludedRoots)
|
|
41721
41726
|
safe2(root);
|
|
41722
|
-
return paths.map((path) => capture(path, budget2, excludedRoots));
|
|
41727
|
+
return paths.map((path) => capture(path, budget2, excludedRoots, [], undefined, claudeMarkers));
|
|
41728
|
+
}
|
|
41729
|
+
function captureDiscoveryDirectories(paths, excludedRoots = []) {
|
|
41730
|
+
return captureOrdinaryDirectories(paths, excludedRoots, "omit");
|
|
41723
41731
|
}
|
|
41724
41732
|
function verifyDiscoveryDirectories(directories, excludedRoots = [], tolerance) {
|
|
41725
41733
|
need4(Array.isArray(directories) && directories.length <= AGENT_POLICY_LIMITS.discoveryDirectories, "Invalid native discovery directory collection");
|
|
41726
41734
|
for (const directory of directories)
|
|
41727
41735
|
need4(directory && typeof directory === "object" && (directory.sha256 === null || typeof directory.sha256 === "string" && /^[a-f0-9]{64}$/.test(directory.sha256)), "Invalid native discovery directory digest");
|
|
41728
41736
|
const current = captureDiscoveryDirectories(directories.map((directory) => directory.path), excludedRoots);
|
|
41737
|
+
let legacy;
|
|
41729
41738
|
for (let i = 0;i < directories.length; i++)
|
|
41730
41739
|
if (current[i].sha256 !== directories[i].sha256) {
|
|
41740
|
+
legacy ??= captureOrdinaryDirectories(directories.map((directory) => directory.path), excludedRoots, "retain");
|
|
41741
|
+
if (legacy[i].sha256 === directories[i].sha256)
|
|
41742
|
+
continue;
|
|
41731
41743
|
witnessChanged(new NativeDiscoveryWitnessChange("membership", directories[i].path, `Native discovery directory membership changed; run skills hook install with a fresh discovery review: ${directories[i].path}`), tolerance, tolerance?.acceptsMembership(directories[i].path) === true);
|
|
41732
41744
|
}
|
|
41733
41745
|
}
|
|
@@ -46227,6 +46239,7 @@ var OPTIONAL_CONTEXT_FAILURES = new Set([
|
|
|
46227
46239
|
"CACHED_PROFILE_EXPIRED",
|
|
46228
46240
|
"CACHED_PROFILE_MISSING",
|
|
46229
46241
|
"CACHED_BUNDLE_MISSING",
|
|
46242
|
+
"PROFILE_LOCK_MISMATCH",
|
|
46230
46243
|
"SESSION_RECONCILIATION_REQUIRED",
|
|
46231
46244
|
"SESSION_RENEWAL_TIMEOUT",
|
|
46232
46245
|
"SESSION_WRITE_BUSY",
|
|
@@ -99515,7 +99528,7 @@ function checkedPublicationView(value, skillId, intentId, declaration) {
|
|
|
99515
99528
|
return invalid7();
|
|
99516
99529
|
return Object.freeze({ ...value });
|
|
99517
99530
|
}
|
|
99518
|
-
async function boundedJson(url2, init, token, mutation, budget3 = 15000, signal, create = false) {
|
|
99531
|
+
async function boundedJson(url2, init, token, mutation, budget3 = 15000, signal, create = false, readBinding) {
|
|
99519
99532
|
const controller = new AbortController;
|
|
99520
99533
|
let reader;
|
|
99521
99534
|
let response;
|
|
@@ -99531,8 +99544,18 @@ async function boundedJson(url2, init, token, mutation, budget3 = 15000, signal,
|
|
|
99531
99544
|
redirect: "error",
|
|
99532
99545
|
credentials: "omit",
|
|
99533
99546
|
signal: controller.signal,
|
|
99534
|
-
headers: {
|
|
99547
|
+
headers: {
|
|
99548
|
+
"Content-Type": "application/json",
|
|
99549
|
+
Authorization: `Bearer ${token}`,
|
|
99550
|
+
...readBinding ? {
|
|
99551
|
+
"x-skills-user-id": readBinding.userId,
|
|
99552
|
+
"x-skills-workspace-id": readBinding.organizationId,
|
|
99553
|
+
"x-skills-membership-id": readBinding.membershipId
|
|
99554
|
+
} : {}
|
|
99555
|
+
}
|
|
99535
99556
|
});
|
|
99557
|
+
if (readBinding && response.ok && response.status !== 200)
|
|
99558
|
+
return invalid7();
|
|
99536
99559
|
const length = response.headers.get("content-length");
|
|
99537
99560
|
if (length !== null && (!/^\d+$/.test(length) || Number(length) > 65536))
|
|
99538
99561
|
return invalid7();
|
|
@@ -99600,6 +99623,88 @@ async function boundedJson(url2, init, token, mutation, budget3 = 15000, signal,
|
|
|
99600
99623
|
response?.body?.cancel().catch(() => {});
|
|
99601
99624
|
}
|
|
99602
99625
|
}
|
|
99626
|
+
var historyInput = () => {
|
|
99627
|
+
throw new PrivatePublicationError("INVALID_PRIVATE_HISTORY_INPUT", "Provide a private skill UUID, limit from 1 to 50, and an optional UUID cursor; timeoutMs must be from 1 to 15000.");
|
|
99628
|
+
};
|
|
99629
|
+
var historyResponse = () => {
|
|
99630
|
+
throw new PrivatePublicationError("INVALID_PRIVATE_HISTORY_RESPONSE", "The server returned invalid private version history.");
|
|
99631
|
+
};
|
|
99632
|
+
var historyText = (value) => typeof value === "string" && value.length > 0 && value.length <= 128 && !/[\p{Cc}\p{Cs}\u2028\u2029]/u.test(value);
|
|
99633
|
+
function historyDate(value) {
|
|
99634
|
+
if (typeof value !== "string")
|
|
99635
|
+
return false;
|
|
99636
|
+
const parts = /^(\d{4})-(\d{2})-(\d{2})(T| )(\d{2}):(\d{2}):(\d{2})(?:\.(\d{1,9}))?(Z|[+-](\d{2})(?::(\d{2}))?)$/.exec(value);
|
|
99637
|
+
if (!parts)
|
|
99638
|
+
return false;
|
|
99639
|
+
const [, y2, m2, d4, separator, h4, minute, second, fraction, zone, offsetHour, offsetMinute] = parts;
|
|
99640
|
+
if (separator === " " ? zone === "Z" || (fraction?.length ?? 0) > 6 : zone !== "Z" && offsetMinute === undefined)
|
|
99641
|
+
return false;
|
|
99642
|
+
const year = Number(y2), month = Number(m2), day = Number(d4);
|
|
99643
|
+
const leap = year % 4 === 0 && (year % 100 !== 0 || year % 400 === 0);
|
|
99644
|
+
const days = [31, leap ? 29 : 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
|
|
99645
|
+
return year > 0 && month >= 1 && month <= 12 && day >= 1 && day <= days[month - 1] && Number(h4) <= 23 && Number(minute) <= 59 && Number(second) <= 59 && (zone === "Z" || Number(offsetHour) <= 23 && Number(offsetMinute ?? 0) <= 59);
|
|
99646
|
+
}
|
|
99647
|
+
function privateHistory(value, organizationId, skillId, limit, cursor2) {
|
|
99648
|
+
if (!record12(value) || value.organizationId !== organizationId || value.skillId !== skillId || typeof value.slug !== "string" || !/^[a-z0-9-]+$/.test(value.slug) || !(value.currentVersion === null || historyText(value.currentVersion)) || !(value.currentVersionId === null || publicationUuid(value.currentVersionId)) || value.currentVersion === null !== (value.currentVersionId === null) || !(value.nextCursor === null || publicationUuid(value.nextCursor)) || !Array.isArray(value.versions) || value.versions.length > limit)
|
|
99649
|
+
return historyResponse();
|
|
99650
|
+
const seen = new Set;
|
|
99651
|
+
let previous = cursor2;
|
|
99652
|
+
const versions2 = value.versions.map((row) => {
|
|
99653
|
+
if (!record12(row) || !publicationUuid(row.id) || seen.has(row.id) || previous !== undefined && row.id >= previous || !historyText(row.version) || !(row.releasedAt === null || historyDate(row.releasedAt)) || !historyDate(row.createdAt) || row.id === value.currentVersionId !== (row.version === value.currentVersion))
|
|
99654
|
+
return historyResponse();
|
|
99655
|
+
seen.add(row.id);
|
|
99656
|
+
previous = row.id;
|
|
99657
|
+
return Object.freeze({ id: row.id, version: row.version, releasedAt: row.releasedAt, createdAt: row.createdAt });
|
|
99658
|
+
});
|
|
99659
|
+
if (value.nextCursor !== null && (!versions2.length || value.nextCursor !== versions2.at(-1).id))
|
|
99660
|
+
return historyResponse();
|
|
99661
|
+
return Object.freeze({
|
|
99662
|
+
organizationId,
|
|
99663
|
+
skillId,
|
|
99664
|
+
slug: value.slug,
|
|
99665
|
+
currentVersion: value.currentVersion,
|
|
99666
|
+
currentVersionId: value.currentVersionId,
|
|
99667
|
+
versions: Object.freeze(versions2),
|
|
99668
|
+
nextCursor: value.nextCursor
|
|
99669
|
+
});
|
|
99670
|
+
}
|
|
99671
|
+
|
|
99672
|
+
class RemotePrivateSkillHistoryClient {
|
|
99673
|
+
apiOrigin;
|
|
99674
|
+
organizationId;
|
|
99675
|
+
userId;
|
|
99676
|
+
membershipId;
|
|
99677
|
+
#token;
|
|
99678
|
+
constructor(apiUrl, session) {
|
|
99679
|
+
const checked = parseWorkspaceSession(session, { userId: session?.user?.id, membershipId: session?.user?.membershipId });
|
|
99680
|
+
this.apiOrigin = normalizeSkillsApiOrigin(apiUrl);
|
|
99681
|
+
this.#token = checked.token;
|
|
99682
|
+
this.organizationId = checked.organization.id;
|
|
99683
|
+
this.userId = checked.user.id;
|
|
99684
|
+
this.membershipId = checked.user.membershipId;
|
|
99685
|
+
Object.freeze(this);
|
|
99686
|
+
}
|
|
99687
|
+
async listVersions(skillId, options = {}) {
|
|
99688
|
+
if (!publicationUuid(skillId) || options.limit !== undefined && (!Number.isSafeInteger(options.limit) || options.limit < 1 || options.limit > 50) || options.cursor !== undefined && !publicationUuid(options.cursor) || options.timeoutMs !== undefined && (!Number.isSafeInteger(options.timeoutMs) || options.timeoutMs < 1 || options.timeoutMs > 15000))
|
|
99689
|
+
return historyInput();
|
|
99690
|
+
const limit = options.limit ?? 20, cursor2 = options.cursor;
|
|
99691
|
+
const query = new URLSearchParams;
|
|
99692
|
+
if (options.limit !== undefined)
|
|
99693
|
+
query.set("limit", String(limit));
|
|
99694
|
+
if (cursor2 !== undefined)
|
|
99695
|
+
query.set("cursor", cursor2);
|
|
99696
|
+
const path2 = `/api/v1/skills/${skillId}/versions${query.size ? `?${query}` : ""}`;
|
|
99697
|
+
let value;
|
|
99698
|
+
try {
|
|
99699
|
+
value = await boundedJson(skillsApiRequestUrl(this.apiOrigin, path2), { method: "GET" }, this.#token, false, options.timeoutMs, options.signal, false, this);
|
|
99700
|
+
} catch (error61) {
|
|
99701
|
+
if (error61 instanceof PrivatePublicationError && error61.code === "INVALID_PUBLICATION_RESPONSE")
|
|
99702
|
+
return historyResponse();
|
|
99703
|
+
throw new PrivatePublicationError("PRIVATE_HISTORY_UNAVAILABLE", "Unable to read private version history. Check the selected server, current membership and fresh sign-in; no skill or credential was changed.", false, error61 instanceof PrivatePublicationError ? error61.status : undefined);
|
|
99704
|
+
}
|
|
99705
|
+
return privateHistory(value, this.organizationId, skillId, limit, cursor2);
|
|
99706
|
+
}
|
|
99707
|
+
}
|
|
99603
99708
|
|
|
99604
99709
|
class RemotePrivatePublicationsClient {
|
|
99605
99710
|
apiOrigin;
|
|
@@ -99852,6 +99957,10 @@ class RemoteSkillsAuthClient {
|
|
|
99852
99957
|
const origin = this.apiOrigin, captured = workspaceContext(context);
|
|
99853
99958
|
return new RemotePrivatePublicationsClient(origin, await this.switchWorkspace(email4, code, captured));
|
|
99854
99959
|
}
|
|
99960
|
+
async openPrivateSkillHistory(email4, code, context) {
|
|
99961
|
+
const origin = this.apiOrigin, captured = workspaceContext(context);
|
|
99962
|
+
return new RemotePrivateSkillHistoryClient(origin, await this.switchWorkspace(email4, code, captured));
|
|
99963
|
+
}
|
|
99855
99964
|
requestInvitationEmailChallenge(input2) {
|
|
99856
99965
|
return requestInvitationEmail(this.apiOrigin, "challenge", input2);
|
|
99857
99966
|
}
|
|
@@ -100562,6 +100671,7 @@ export {
|
|
|
100562
100671
|
RemoteRecurringReadError,
|
|
100563
100672
|
RemoteRecurringError,
|
|
100564
100673
|
RemoteQuoteUnavailableError,
|
|
100674
|
+
RemotePrivateSkillHistoryClient,
|
|
100565
100675
|
RemotePrivatePublicationsClient,
|
|
100566
100676
|
RemoteInvitationEmailUnconfirmedError,
|
|
100567
100677
|
RemoteInvitationEmailError,
|