@hasna/skills 0.10.81 → 0.10.82
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 +278 -57
- package/bin/mcp.js +120 -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 +116 -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 +2 -2
- package/dist/sdk/index.d.ts +1 -1
- package/dist/sdk/index.js +116 -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.82";
|
|
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
|
}
|
|
@@ -99515,7 +99527,7 @@ function checkedPublicationView(value, skillId, intentId, declaration) {
|
|
|
99515
99527
|
return invalid7();
|
|
99516
99528
|
return Object.freeze({ ...value });
|
|
99517
99529
|
}
|
|
99518
|
-
async function boundedJson(url2, init, token, mutation, budget3 = 15000, signal, create = false) {
|
|
99530
|
+
async function boundedJson(url2, init, token, mutation, budget3 = 15000, signal, create = false, readBinding) {
|
|
99519
99531
|
const controller = new AbortController;
|
|
99520
99532
|
let reader;
|
|
99521
99533
|
let response;
|
|
@@ -99531,8 +99543,18 @@ async function boundedJson(url2, init, token, mutation, budget3 = 15000, signal,
|
|
|
99531
99543
|
redirect: "error",
|
|
99532
99544
|
credentials: "omit",
|
|
99533
99545
|
signal: controller.signal,
|
|
99534
|
-
headers: {
|
|
99546
|
+
headers: {
|
|
99547
|
+
"Content-Type": "application/json",
|
|
99548
|
+
Authorization: `Bearer ${token}`,
|
|
99549
|
+
...readBinding ? {
|
|
99550
|
+
"x-skills-user-id": readBinding.userId,
|
|
99551
|
+
"x-skills-workspace-id": readBinding.organizationId,
|
|
99552
|
+
"x-skills-membership-id": readBinding.membershipId
|
|
99553
|
+
} : {}
|
|
99554
|
+
}
|
|
99535
99555
|
});
|
|
99556
|
+
if (readBinding && response.ok && response.status !== 200)
|
|
99557
|
+
return invalid7();
|
|
99536
99558
|
const length = response.headers.get("content-length");
|
|
99537
99559
|
if (length !== null && (!/^\d+$/.test(length) || Number(length) > 65536))
|
|
99538
99560
|
return invalid7();
|
|
@@ -99600,6 +99622,88 @@ async function boundedJson(url2, init, token, mutation, budget3 = 15000, signal,
|
|
|
99600
99622
|
response?.body?.cancel().catch(() => {});
|
|
99601
99623
|
}
|
|
99602
99624
|
}
|
|
99625
|
+
var historyInput = () => {
|
|
99626
|
+
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.");
|
|
99627
|
+
};
|
|
99628
|
+
var historyResponse = () => {
|
|
99629
|
+
throw new PrivatePublicationError("INVALID_PRIVATE_HISTORY_RESPONSE", "The server returned invalid private version history.");
|
|
99630
|
+
};
|
|
99631
|
+
var historyText = (value) => typeof value === "string" && value.length > 0 && value.length <= 128 && !/[\p{Cc}\p{Cs}\u2028\u2029]/u.test(value);
|
|
99632
|
+
function historyDate(value) {
|
|
99633
|
+
if (typeof value !== "string")
|
|
99634
|
+
return false;
|
|
99635
|
+
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);
|
|
99636
|
+
if (!parts)
|
|
99637
|
+
return false;
|
|
99638
|
+
const [, y2, m2, d4, separator, h4, minute, second, fraction, zone, offsetHour, offsetMinute] = parts;
|
|
99639
|
+
if (separator === " " ? zone === "Z" || (fraction?.length ?? 0) > 6 : zone !== "Z" && offsetMinute === undefined)
|
|
99640
|
+
return false;
|
|
99641
|
+
const year = Number(y2), month = Number(m2), day = Number(d4);
|
|
99642
|
+
const leap = year % 4 === 0 && (year % 100 !== 0 || year % 400 === 0);
|
|
99643
|
+
const days = [31, leap ? 29 : 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
|
|
99644
|
+
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);
|
|
99645
|
+
}
|
|
99646
|
+
function privateHistory(value, organizationId, skillId, limit, cursor2) {
|
|
99647
|
+
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)
|
|
99648
|
+
return historyResponse();
|
|
99649
|
+
const seen = new Set;
|
|
99650
|
+
let previous = cursor2;
|
|
99651
|
+
const versions2 = value.versions.map((row) => {
|
|
99652
|
+
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))
|
|
99653
|
+
return historyResponse();
|
|
99654
|
+
seen.add(row.id);
|
|
99655
|
+
previous = row.id;
|
|
99656
|
+
return Object.freeze({ id: row.id, version: row.version, releasedAt: row.releasedAt, createdAt: row.createdAt });
|
|
99657
|
+
});
|
|
99658
|
+
if (value.nextCursor !== null && (!versions2.length || value.nextCursor !== versions2.at(-1).id))
|
|
99659
|
+
return historyResponse();
|
|
99660
|
+
return Object.freeze({
|
|
99661
|
+
organizationId,
|
|
99662
|
+
skillId,
|
|
99663
|
+
slug: value.slug,
|
|
99664
|
+
currentVersion: value.currentVersion,
|
|
99665
|
+
currentVersionId: value.currentVersionId,
|
|
99666
|
+
versions: Object.freeze(versions2),
|
|
99667
|
+
nextCursor: value.nextCursor
|
|
99668
|
+
});
|
|
99669
|
+
}
|
|
99670
|
+
|
|
99671
|
+
class RemotePrivateSkillHistoryClient {
|
|
99672
|
+
apiOrigin;
|
|
99673
|
+
organizationId;
|
|
99674
|
+
userId;
|
|
99675
|
+
membershipId;
|
|
99676
|
+
#token;
|
|
99677
|
+
constructor(apiUrl, session) {
|
|
99678
|
+
const checked = parseWorkspaceSession(session, { userId: session?.user?.id, membershipId: session?.user?.membershipId });
|
|
99679
|
+
this.apiOrigin = normalizeSkillsApiOrigin(apiUrl);
|
|
99680
|
+
this.#token = checked.token;
|
|
99681
|
+
this.organizationId = checked.organization.id;
|
|
99682
|
+
this.userId = checked.user.id;
|
|
99683
|
+
this.membershipId = checked.user.membershipId;
|
|
99684
|
+
Object.freeze(this);
|
|
99685
|
+
}
|
|
99686
|
+
async listVersions(skillId, options = {}) {
|
|
99687
|
+
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))
|
|
99688
|
+
return historyInput();
|
|
99689
|
+
const limit = options.limit ?? 20, cursor2 = options.cursor;
|
|
99690
|
+
const query = new URLSearchParams;
|
|
99691
|
+
if (options.limit !== undefined)
|
|
99692
|
+
query.set("limit", String(limit));
|
|
99693
|
+
if (cursor2 !== undefined)
|
|
99694
|
+
query.set("cursor", cursor2);
|
|
99695
|
+
const path2 = `/api/v1/skills/${skillId}/versions${query.size ? `?${query}` : ""}`;
|
|
99696
|
+
let value;
|
|
99697
|
+
try {
|
|
99698
|
+
value = await boundedJson(skillsApiRequestUrl(this.apiOrigin, path2), { method: "GET" }, this.#token, false, options.timeoutMs, options.signal, false, this);
|
|
99699
|
+
} catch (error61) {
|
|
99700
|
+
if (error61 instanceof PrivatePublicationError && error61.code === "INVALID_PUBLICATION_RESPONSE")
|
|
99701
|
+
return historyResponse();
|
|
99702
|
+
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);
|
|
99703
|
+
}
|
|
99704
|
+
return privateHistory(value, this.organizationId, skillId, limit, cursor2);
|
|
99705
|
+
}
|
|
99706
|
+
}
|
|
99603
99707
|
|
|
99604
99708
|
class RemotePrivatePublicationsClient {
|
|
99605
99709
|
apiOrigin;
|
|
@@ -99852,6 +99956,10 @@ class RemoteSkillsAuthClient {
|
|
|
99852
99956
|
const origin = this.apiOrigin, captured = workspaceContext(context);
|
|
99853
99957
|
return new RemotePrivatePublicationsClient(origin, await this.switchWorkspace(email4, code, captured));
|
|
99854
99958
|
}
|
|
99959
|
+
async openPrivateSkillHistory(email4, code, context) {
|
|
99960
|
+
const origin = this.apiOrigin, captured = workspaceContext(context);
|
|
99961
|
+
return new RemotePrivateSkillHistoryClient(origin, await this.switchWorkspace(email4, code, captured));
|
|
99962
|
+
}
|
|
99855
99963
|
requestInvitationEmailChallenge(input2) {
|
|
99856
99964
|
return requestInvitationEmail(this.apiOrigin, "challenge", input2);
|
|
99857
99965
|
}
|
|
@@ -100562,6 +100670,7 @@ export {
|
|
|
100562
100670
|
RemoteRecurringReadError,
|
|
100563
100671
|
RemoteRecurringError,
|
|
100564
100672
|
RemoteQuoteUnavailableError,
|
|
100673
|
+
RemotePrivateSkillHistoryClient,
|
|
100565
100674
|
RemotePrivatePublicationsClient,
|
|
100566
100675
|
RemoteInvitationEmailUnconfirmedError,
|
|
100567
100676
|
RemoteInvitationEmailError,
|