@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/bin/mcp.js
CHANGED
|
@@ -23,7 +23,7 @@ var package_default;
|
|
|
23
23
|
var init_package = __esm(() => {
|
|
24
24
|
package_default = {
|
|
25
25
|
name: "@hasna/skills",
|
|
26
|
-
version: "0.10.
|
|
26
|
+
version: "0.10.82",
|
|
27
27
|
description: "Skills library for AI coding agents",
|
|
28
28
|
type: "module",
|
|
29
29
|
bin: {
|
|
@@ -23031,7 +23031,7 @@ function hashClaudePluginCacheOrphanMarker(path, budget2, changes) {
|
|
|
23031
23031
|
if (!before)
|
|
23032
23032
|
return null;
|
|
23033
23033
|
const uid = process.getuid?.();
|
|
23034
|
-
if (!before.isFile() || uid === undefined || before.uid !== uid || before.size > 32)
|
|
23034
|
+
if (!before.isFile() || uid === undefined || before.uid !== uid || before.size > 32 || (before.mode & 73) !== 0)
|
|
23035
23035
|
throw new Error("Invalid Claude orphan marker file or owner");
|
|
23036
23036
|
const fd = openSync7(path, constants4.O_RDONLY | constants4.O_NOFOLLOW | constants4.O_NONBLOCK);
|
|
23037
23037
|
try {
|
|
@@ -30444,7 +30444,7 @@ function safe2(path) {
|
|
|
30444
30444
|
function same2(before, after) {
|
|
30445
30445
|
return Boolean(after && after.isDirectory() && before.dev === after.dev && before.ino === after.ino && before.mtimeMs === after.mtimeMs && before.ctimeMs === after.ctimeMs);
|
|
30446
30446
|
}
|
|
30447
|
-
function capture(path, budget2, excludedRoots, omittedRoots = [], rows) {
|
|
30447
|
+
function capture(path, budget2, excludedRoots, omittedRoots = [], rows, claudeMarkers) {
|
|
30448
30448
|
safe2(path);
|
|
30449
30449
|
if (omittedRoots.some((root2) => path === root2 || path.startsWith(root2 + "/")))
|
|
30450
30450
|
return { path, sha256: null };
|
|
@@ -30472,6 +30472,11 @@ function capture(path, budget2, excludedRoots, omittedRoots = [], rows) {
|
|
|
30472
30472
|
need3(child2.length <= AGENT_POLICY_LIMITS.pathCharacters, "Native discovery directory path limit exceeded");
|
|
30473
30473
|
const stat = lstatSync8(child2);
|
|
30474
30474
|
need3(stat.isFile() || stat.isDirectory(), "Refusing symlink or special native discovery directory member");
|
|
30475
|
+
if (claudeMarkers && isClaudePluginCacheOrphanMarker(child2)) {
|
|
30476
|
+
need3(hashClaudePluginCacheOrphanMarker(child2) !== null, "Claude orphan marker changed while reading directory");
|
|
30477
|
+
if (claudeMarkers === "omit")
|
|
30478
|
+
continue;
|
|
30479
|
+
}
|
|
30475
30480
|
const row = JSON.stringify([childRelative, stat.isDirectory() ? "directory" : "file"]) + `
|
|
30476
30481
|
`;
|
|
30477
30482
|
budget2.bytes += Buffer.byteLength(row);
|
|
@@ -30528,25 +30533,33 @@ function verifyDiscoveryDirectoryProjection(directories, omittedRoots, tolerance
|
|
|
30528
30533
|
witnessChanged(new NativeDiscoveryWitnessChange("membership", directories[i].path, "Native discovery directory membership changed outside retired Codex roots"), tolerance, tolerance?.acceptsMembership(directories[i].path) === true);
|
|
30529
30534
|
}
|
|
30530
30535
|
}
|
|
30531
|
-
function
|
|
30536
|
+
function captureOrdinaryDirectories(paths, excludedRoots, claudeMarkers) {
|
|
30532
30537
|
need3(Array.isArray(paths) && paths.length <= AGENT_POLICY_LIMITS.discoveryDirectories && new Set(paths).size === paths.length, "Invalid native discovery directory collection");
|
|
30533
30538
|
const budget2 = { entries: 0, bytes: 0 };
|
|
30534
30539
|
for (const root of excludedRoots)
|
|
30535
30540
|
safe2(root);
|
|
30536
|
-
return paths.map((path) => capture(path, budget2, excludedRoots));
|
|
30541
|
+
return paths.map((path) => capture(path, budget2, excludedRoots, [], undefined, claudeMarkers));
|
|
30542
|
+
}
|
|
30543
|
+
function captureDiscoveryDirectories(paths, excludedRoots = []) {
|
|
30544
|
+
return captureOrdinaryDirectories(paths, excludedRoots, "omit");
|
|
30537
30545
|
}
|
|
30538
30546
|
function verifyDiscoveryDirectories(directories, excludedRoots = [], tolerance) {
|
|
30539
30547
|
need3(Array.isArray(directories) && directories.length <= AGENT_POLICY_LIMITS.discoveryDirectories, "Invalid native discovery directory collection");
|
|
30540
30548
|
for (const directory of directories)
|
|
30541
30549
|
need3(directory && typeof directory === "object" && (directory.sha256 === null || typeof directory.sha256 === "string" && /^[a-f0-9]{64}$/.test(directory.sha256)), "Invalid native discovery directory digest");
|
|
30542
30550
|
const current = captureDiscoveryDirectories(directories.map((directory) => directory.path), excludedRoots);
|
|
30551
|
+
let legacy;
|
|
30543
30552
|
for (let i = 0;i < directories.length; i++)
|
|
30544
30553
|
if (current[i].sha256 !== directories[i].sha256) {
|
|
30554
|
+
legacy ??= captureOrdinaryDirectories(directories.map((directory) => directory.path), excludedRoots, "retain");
|
|
30555
|
+
if (legacy[i].sha256 === directories[i].sha256)
|
|
30556
|
+
continue;
|
|
30545
30557
|
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);
|
|
30546
30558
|
}
|
|
30547
30559
|
}
|
|
30548
30560
|
var init_agent_discovery_directories = __esm(() => {
|
|
30549
30561
|
init_agent_policy_limits();
|
|
30562
|
+
init_claude_plugin_cache_marker();
|
|
30550
30563
|
init_native_discovery_witness_change();
|
|
30551
30564
|
});
|
|
30552
30565
|
|
|
@@ -41871,7 +41884,7 @@ function checkedPublicationView(value, skillId, intentId, declaration) {
|
|
|
41871
41884
|
return invalid4();
|
|
41872
41885
|
return Object.freeze({ ...value });
|
|
41873
41886
|
}
|
|
41874
|
-
async function boundedJson(url2, init, token, mutation, budget3 = 15000, signal, create = false) {
|
|
41887
|
+
async function boundedJson(url2, init, token, mutation, budget3 = 15000, signal, create = false, readBinding) {
|
|
41875
41888
|
const controller = new AbortController;
|
|
41876
41889
|
let reader;
|
|
41877
41890
|
let response;
|
|
@@ -41887,8 +41900,18 @@ async function boundedJson(url2, init, token, mutation, budget3 = 15000, signal,
|
|
|
41887
41900
|
redirect: "error",
|
|
41888
41901
|
credentials: "omit",
|
|
41889
41902
|
signal: controller.signal,
|
|
41890
|
-
headers: {
|
|
41903
|
+
headers: {
|
|
41904
|
+
"Content-Type": "application/json",
|
|
41905
|
+
Authorization: `Bearer ${token}`,
|
|
41906
|
+
...readBinding ? {
|
|
41907
|
+
"x-skills-user-id": readBinding.userId,
|
|
41908
|
+
"x-skills-workspace-id": readBinding.organizationId,
|
|
41909
|
+
"x-skills-membership-id": readBinding.membershipId
|
|
41910
|
+
} : {}
|
|
41911
|
+
}
|
|
41891
41912
|
});
|
|
41913
|
+
if (readBinding && response.ok && response.status !== 200)
|
|
41914
|
+
return invalid4();
|
|
41892
41915
|
const length = response.headers.get("content-length");
|
|
41893
41916
|
if (length !== null && (!/^\d+$/.test(length) || Number(length) > 65536))
|
|
41894
41917
|
return invalid4();
|
|
@@ -41956,6 +41979,81 @@ async function boundedJson(url2, init, token, mutation, budget3 = 15000, signal,
|
|
|
41956
41979
|
response?.body?.cancel().catch(() => {});
|
|
41957
41980
|
}
|
|
41958
41981
|
}
|
|
41982
|
+
function historyDate(value) {
|
|
41983
|
+
if (typeof value !== "string")
|
|
41984
|
+
return false;
|
|
41985
|
+
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);
|
|
41986
|
+
if (!parts)
|
|
41987
|
+
return false;
|
|
41988
|
+
const [, y, m, d, separator, h, minute, second, fraction, zone, offsetHour, offsetMinute] = parts;
|
|
41989
|
+
if (separator === " " ? zone === "Z" || (fraction?.length ?? 0) > 6 : zone !== "Z" && offsetMinute === undefined)
|
|
41990
|
+
return false;
|
|
41991
|
+
const year = Number(y), month = Number(m), day = Number(d);
|
|
41992
|
+
const leap = year % 4 === 0 && (year % 100 !== 0 || year % 400 === 0);
|
|
41993
|
+
const days = [31, leap ? 29 : 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
|
|
41994
|
+
return year > 0 && month >= 1 && month <= 12 && day >= 1 && day <= days[month - 1] && Number(h) <= 23 && Number(minute) <= 59 && Number(second) <= 59 && (zone === "Z" || Number(offsetHour) <= 23 && Number(offsetMinute ?? 0) <= 59);
|
|
41995
|
+
}
|
|
41996
|
+
function privateHistory(value, organizationId, skillId, limit, cursor2) {
|
|
41997
|
+
if (!record10(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)
|
|
41998
|
+
return historyResponse();
|
|
41999
|
+
const seen = new Set;
|
|
42000
|
+
let previous = cursor2;
|
|
42001
|
+
const versions2 = value.versions.map((row) => {
|
|
42002
|
+
if (!record10(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))
|
|
42003
|
+
return historyResponse();
|
|
42004
|
+
seen.add(row.id);
|
|
42005
|
+
previous = row.id;
|
|
42006
|
+
return Object.freeze({ id: row.id, version: row.version, releasedAt: row.releasedAt, createdAt: row.createdAt });
|
|
42007
|
+
});
|
|
42008
|
+
if (value.nextCursor !== null && (!versions2.length || value.nextCursor !== versions2.at(-1).id))
|
|
42009
|
+
return historyResponse();
|
|
42010
|
+
return Object.freeze({
|
|
42011
|
+
organizationId,
|
|
42012
|
+
skillId,
|
|
42013
|
+
slug: value.slug,
|
|
42014
|
+
currentVersion: value.currentVersion,
|
|
42015
|
+
currentVersionId: value.currentVersionId,
|
|
42016
|
+
versions: Object.freeze(versions2),
|
|
42017
|
+
nextCursor: value.nextCursor
|
|
42018
|
+
});
|
|
42019
|
+
}
|
|
42020
|
+
|
|
42021
|
+
class RemotePrivateSkillHistoryClient {
|
|
42022
|
+
apiOrigin;
|
|
42023
|
+
organizationId;
|
|
42024
|
+
userId;
|
|
42025
|
+
membershipId;
|
|
42026
|
+
#token;
|
|
42027
|
+
constructor(apiUrl, session) {
|
|
42028
|
+
const checked = parseWorkspaceSession(session, { userId: session?.user?.id, membershipId: session?.user?.membershipId });
|
|
42029
|
+
this.apiOrigin = normalizeSkillsApiOrigin(apiUrl);
|
|
42030
|
+
this.#token = checked.token;
|
|
42031
|
+
this.organizationId = checked.organization.id;
|
|
42032
|
+
this.userId = checked.user.id;
|
|
42033
|
+
this.membershipId = checked.user.membershipId;
|
|
42034
|
+
Object.freeze(this);
|
|
42035
|
+
}
|
|
42036
|
+
async listVersions(skillId, options = {}) {
|
|
42037
|
+
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))
|
|
42038
|
+
return historyInput();
|
|
42039
|
+
const limit = options.limit ?? 20, cursor2 = options.cursor;
|
|
42040
|
+
const query = new URLSearchParams;
|
|
42041
|
+
if (options.limit !== undefined)
|
|
42042
|
+
query.set("limit", String(limit));
|
|
42043
|
+
if (cursor2 !== undefined)
|
|
42044
|
+
query.set("cursor", cursor2);
|
|
42045
|
+
const path = `/api/v1/skills/${skillId}/versions${query.size ? `?${query}` : ""}`;
|
|
42046
|
+
let value;
|
|
42047
|
+
try {
|
|
42048
|
+
value = await boundedJson(skillsApiRequestUrl(this.apiOrigin, path), { method: "GET" }, this.#token, false, options.timeoutMs, options.signal, false, this);
|
|
42049
|
+
} catch (error61) {
|
|
42050
|
+
if (error61 instanceof PrivatePublicationError && error61.code === "INVALID_PUBLICATION_RESPONSE")
|
|
42051
|
+
return historyResponse();
|
|
42052
|
+
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);
|
|
42053
|
+
}
|
|
42054
|
+
return privateHistory(value, this.organizationId, skillId, limit, cursor2);
|
|
42055
|
+
}
|
|
42056
|
+
}
|
|
41959
42057
|
|
|
41960
42058
|
class RemotePrivatePublicationsClient {
|
|
41961
42059
|
apiOrigin;
|
|
@@ -42129,7 +42227,11 @@ var PRIVATE_PUBLICATION_MAX_BYTES, skillCreateFailures, failures2, PrivatePublic
|
|
|
42129
42227
|
throw new PrivatePublicationError("INVALID_PUBLICATION_INPUT", "Invalid publication input or recovery data.");
|
|
42130
42228
|
}, invalid4 = () => {
|
|
42131
42229
|
throw new PrivatePublicationError("INVALID_PUBLICATION_RESPONSE", "The server returned an invalid publication result.");
|
|
42132
|
-
}, publicationUuid = (v) => typeof v === "string" && /^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/.test(v), hash4 = (v) => typeof v === "string" && /^[a-f0-9]{64}$/.test(v), record10 = (v) => !!v && typeof v === "object" && !Array.isArray(v), exact = (v, keys2) => record10(v) && Object.keys(v).sort().join(",") === keys2.sort().join(","), date5 = (v) => typeof v === "string" && /^\d{4}-\d\d-\d\dT[0-9:.]+(?:Z|[+-](?:[01]\d|2[0-3]):[0-5]\d)$/.test(v) && Number.isFinite(Date.parse(v)), publicationSha256 = (bytes) => createHash27("sha256").update(bytes).digest("hex")
|
|
42230
|
+
}, publicationUuid = (v) => typeof v === "string" && /^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/.test(v), hash4 = (v) => typeof v === "string" && /^[a-f0-9]{64}$/.test(v), record10 = (v) => !!v && typeof v === "object" && !Array.isArray(v), exact = (v, keys2) => record10(v) && Object.keys(v).sort().join(",") === keys2.sort().join(","), date5 = (v) => typeof v === "string" && /^\d{4}-\d\d-\d\dT[0-9:.]+(?:Z|[+-](?:[01]\d|2[0-3]):[0-5]\d)$/.test(v) && Number.isFinite(Date.parse(v)), publicationSha256 = (bytes) => createHash27("sha256").update(bytes).digest("hex"), historyInput = () => {
|
|
42231
|
+
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.");
|
|
42232
|
+
}, historyResponse = () => {
|
|
42233
|
+
throw new PrivatePublicationError("INVALID_PRIVATE_HISTORY_RESPONSE", "The server returned invalid private version history.");
|
|
42234
|
+
}, historyText = (value) => typeof value === "string" && value.length > 0 && value.length <= 128 && !/[\p{Cc}\p{Cs}\u2028\u2029]/u.test(value);
|
|
42133
42235
|
var init_remote_private_publications = __esm(() => {
|
|
42134
42236
|
init_fleet_credentials();
|
|
42135
42237
|
init_remote_workspace_selection();
|
|
@@ -42244,6 +42346,10 @@ class RemoteSkillsAuthClient {
|
|
|
42244
42346
|
const origin = this.apiOrigin, captured = workspaceContext(context);
|
|
42245
42347
|
return new RemotePrivatePublicationsClient(origin, await this.switchWorkspace(email4, code, captured));
|
|
42246
42348
|
}
|
|
42349
|
+
async openPrivateSkillHistory(email4, code, context) {
|
|
42350
|
+
const origin = this.apiOrigin, captured = workspaceContext(context);
|
|
42351
|
+
return new RemotePrivateSkillHistoryClient(origin, await this.switchWorkspace(email4, code, captured));
|
|
42352
|
+
}
|
|
42247
42353
|
requestInvitationEmailChallenge(input2) {
|
|
42248
42354
|
return requestInvitationEmail(this.apiOrigin, "challenge", input2);
|
|
42249
42355
|
}
|
|
@@ -48574,7 +48680,7 @@ var init_remote_invitation_tools = __esm(() => {
|
|
|
48574
48680
|
});
|
|
48575
48681
|
|
|
48576
48682
|
// src/lib/private-publication-customer.ts
|
|
48577
|
-
function
|
|
48683
|
+
function preparePrivateSession(requested, action, open2) {
|
|
48578
48684
|
const selectors = [
|
|
48579
48685
|
"HASNA_PROFILE",
|
|
48580
48686
|
"HASNA_HOME",
|
|
@@ -48588,7 +48694,7 @@ function preparePrivatePublicationSession(requested) {
|
|
|
48588
48694
|
"SKILLS_API_KEY"
|
|
48589
48695
|
];
|
|
48590
48696
|
const before = new Map(selectors.map((key2) => [key2, process.env[key2]]));
|
|
48591
|
-
const profile = selectedSkillsProfile(process.env), pending = prepareProfileWorkspace(
|
|
48697
|
+
const profile = selectedSkillsProfile(process.env), pending = prepareProfileWorkspace(action);
|
|
48592
48698
|
const captured = requested ? { ...requested } : undefined;
|
|
48593
48699
|
const unchanged3 = () => {
|
|
48594
48700
|
if (selectors.some((key2) => process.env[key2] !== before.get(key2)) || selectedSkillsProfile(process.env) !== profile)
|
|
@@ -48602,12 +48708,15 @@ function preparePrivatePublicationSession(requested) {
|
|
|
48602
48708
|
throw new PrivatePublicationError("PUBLICATION_CONTEXT_REQUIRED", "Provide the observed user and membership IDs, or select an enrolled workspace profile.");
|
|
48603
48709
|
unchanged3();
|
|
48604
48710
|
target.unchanged();
|
|
48605
|
-
const client = await new RemoteSkillsAuthClient(target.origin)
|
|
48711
|
+
const client = await open2(new RemoteSkillsAuthClient(target.origin), email5, code2, context2);
|
|
48606
48712
|
unchanged3();
|
|
48607
48713
|
target.unchanged();
|
|
48608
48714
|
return client;
|
|
48609
48715
|
} };
|
|
48610
48716
|
}
|
|
48717
|
+
function preparePrivatePublicationSession(requested) {
|
|
48718
|
+
return preparePrivateSession(requested, "Manage private publications", (auth, email5, code2, context2) => auth.openPrivatePublications(email5, code2, context2));
|
|
48719
|
+
}
|
|
48611
48720
|
async function privatePublicationSession(email5, code2, requested) {
|
|
48612
48721
|
return preparePrivatePublicationSession(requested).verify(email5, code2);
|
|
48613
48722
|
}
|
package/bin/migrate.js
CHANGED
package/bin/server.js
CHANGED
|
@@ -24140,7 +24140,7 @@ restoreLaunchCwd();
|
|
|
24140
24140
|
// package.json
|
|
24141
24141
|
var package_default = {
|
|
24142
24142
|
name: "@hasna/skills",
|
|
24143
|
-
version: "0.10.
|
|
24143
|
+
version: "0.10.82",
|
|
24144
24144
|
description: "Skills library for AI coding agents",
|
|
24145
24145
|
type: "module",
|
|
24146
24146
|
bin: {
|
package/bin/worker.js
CHANGED
|
@@ -24143,7 +24143,7 @@ import { randomUUID as randomUUID6 } from "crypto";
|
|
|
24143
24143
|
// package.json
|
|
24144
24144
|
var package_default = {
|
|
24145
24145
|
name: "@hasna/skills",
|
|
24146
|
-
version: "0.10.
|
|
24146
|
+
version: "0.10.82",
|
|
24147
24147
|
description: "Skills library for AI coding agents",
|
|
24148
24148
|
type: "module",
|
|
24149
24149
|
bin: {
|
package/dist/index.d.ts
CHANGED
|
@@ -53,7 +53,7 @@ export { WorkspaceLeaveInputError, RemoteWorkspaceLeaveError, RemoteWorkspaceLea
|
|
|
53
53
|
export type { RemoteWorkspaceInvitation, RemoteWorkspaceInvitationsPage, RemoteWorkspaceInvitationResult, RemoteWorkspaceInvitationAcceptance, ListRemoteWorkspaceInvitations, IssueRemoteWorkspaceInvitation, ResendRemoteWorkspaceInvitation, RevokeRemoteWorkspaceInvitation, AcceptRemoteWorkspaceInvitation, RemoteWorkspaceInvitationErrorCode } from "./lib/remote-invitations.js";
|
|
54
54
|
export { WorkspaceInvitationInputError, RemoteWorkspaceInvitationError, RemoteWorkspaceInvitationUnconfirmedError, RemoteWorkspaceInvitationReadError } from "./lib/remote-invitations.js";
|
|
55
55
|
export { InvitationEmailInputError, RemoteInvitationEmailError, RemoteInvitationEmailUnconfirmedError, type RequestInvitationEmailChallenge, type AcceptInvitationEmailChallenge, type RemoteInvitationEmailChallenge, type RemoteInvitationEmailAcceptance, type RemoteInvitationEmailErrorCode } from "./lib/remote-invitation-recovery.js";
|
|
56
|
-
export { RemotePrivatePublicationsClient, PrivatePublicationError, PRIVATE_PUBLICATION_MAX_BYTES, type CreatePrivateSkillInput, type CreatedPrivateSkill, type PrivatePublicationDeclaration, type PrivatePublicationView, type PrivatePublicationState, type PrivatePublishingCapability } from "./lib/remote-private-publications.js";
|
|
56
|
+
export { RemotePrivatePublicationsClient, RemotePrivateSkillHistoryClient, PrivatePublicationError, PRIVATE_PUBLICATION_MAX_BYTES, type PrivateSkillVersion, type PrivateSkillVersionHistory, type PrivateSkillVersionHistoryOptions, type CreatePrivateSkillInput, type CreatedPrivateSkill, type PrivatePublicationDeclaration, type PrivatePublicationView, type PrivatePublicationState, type PrivatePublishingCapability } from "./lib/remote-private-publications.js";
|
|
57
57
|
export { preparePrivatePublication, readPrivatePublicationRecovery, continuePrivatePublication, inspectPrivatePublication, type PrivatePublicationRecovery, type PrivatePublicationResult } from "./lib/private-publication-recovery.js";
|
|
58
58
|
export { HttpProfileClient, createProfileClient, type ProfileClient, type AuthenticatedProfilePrincipal, type AuthenticatedProfileRole } from "./lib/profile-client.js";
|
|
59
59
|
export type { SkillSelection, SkillProfile, ResolvedSkillSelection, ResolvedSkillProfile, StationSkillStateInput, StationSkillState } from "./types/skill-selection.js";
|
package/dist/index.js
CHANGED
|
@@ -9643,7 +9643,7 @@ function hashClaudePluginCacheOrphanMarker(path, budget2, changes) {
|
|
|
9643
9643
|
if (!before)
|
|
9644
9644
|
return null;
|
|
9645
9645
|
const uid = process.getuid?.();
|
|
9646
|
-
if (!before.isFile() || uid === undefined || before.uid !== uid || before.size > 32)
|
|
9646
|
+
if (!before.isFile() || uid === undefined || before.uid !== uid || before.size > 32 || (before.mode & 73) !== 0)
|
|
9647
9647
|
throw new Error("Invalid Claude orphan marker file or owner");
|
|
9648
9648
|
const fd = openSync3(path, constants3.O_RDONLY | constants3.O_NOFOLLOW | constants3.O_NONBLOCK);
|
|
9649
9649
|
try {
|
|
@@ -10269,7 +10269,7 @@ function safe2(path) {
|
|
|
10269
10269
|
function same2(before, after) {
|
|
10270
10270
|
return Boolean(after && after.isDirectory() && before.dev === after.dev && before.ino === after.ino && before.mtimeMs === after.mtimeMs && before.ctimeMs === after.ctimeMs);
|
|
10271
10271
|
}
|
|
10272
|
-
function capture(path, budget2, excludedRoots, omittedRoots = [], rows) {
|
|
10272
|
+
function capture(path, budget2, excludedRoots, omittedRoots = [], rows, claudeMarkers) {
|
|
10273
10273
|
safe2(path);
|
|
10274
10274
|
if (omittedRoots.some((root2) => path === root2 || path.startsWith(root2 + "/")))
|
|
10275
10275
|
return { path, sha256: null };
|
|
@@ -10297,6 +10297,11 @@ function capture(path, budget2, excludedRoots, omittedRoots = [], rows) {
|
|
|
10297
10297
|
need3(child2.length <= AGENT_POLICY_LIMITS.pathCharacters, "Native discovery directory path limit exceeded");
|
|
10298
10298
|
const stat = lstatSync7(child2);
|
|
10299
10299
|
need3(stat.isFile() || stat.isDirectory(), "Refusing symlink or special native discovery directory member");
|
|
10300
|
+
if (claudeMarkers && isClaudePluginCacheOrphanMarker(child2)) {
|
|
10301
|
+
need3(hashClaudePluginCacheOrphanMarker(child2) !== null, "Claude orphan marker changed while reading directory");
|
|
10302
|
+
if (claudeMarkers === "omit")
|
|
10303
|
+
continue;
|
|
10304
|
+
}
|
|
10300
10305
|
const row = JSON.stringify([childRelative, stat.isDirectory() ? "directory" : "file"]) + `
|
|
10301
10306
|
`;
|
|
10302
10307
|
budget2.bytes += Buffer.byteLength(row);
|
|
@@ -10353,20 +10358,27 @@ function verifyDiscoveryDirectoryProjection(directories, omittedRoots, tolerance
|
|
|
10353
10358
|
witnessChanged(new NativeDiscoveryWitnessChange("membership", directories[i].path, "Native discovery directory membership changed outside retired Codex roots"), tolerance, tolerance?.acceptsMembership(directories[i].path) === true);
|
|
10354
10359
|
}
|
|
10355
10360
|
}
|
|
10356
|
-
function
|
|
10361
|
+
function captureOrdinaryDirectories(paths, excludedRoots, claudeMarkers) {
|
|
10357
10362
|
need3(Array.isArray(paths) && paths.length <= AGENT_POLICY_LIMITS.discoveryDirectories && new Set(paths).size === paths.length, "Invalid native discovery directory collection");
|
|
10358
10363
|
const budget2 = { entries: 0, bytes: 0 };
|
|
10359
10364
|
for (const root of excludedRoots)
|
|
10360
10365
|
safe2(root);
|
|
10361
|
-
return paths.map((path) => capture(path, budget2, excludedRoots));
|
|
10366
|
+
return paths.map((path) => capture(path, budget2, excludedRoots, [], undefined, claudeMarkers));
|
|
10367
|
+
}
|
|
10368
|
+
function captureDiscoveryDirectories(paths, excludedRoots = []) {
|
|
10369
|
+
return captureOrdinaryDirectories(paths, excludedRoots, "omit");
|
|
10362
10370
|
}
|
|
10363
10371
|
function verifyDiscoveryDirectories(directories, excludedRoots = [], tolerance) {
|
|
10364
10372
|
need3(Array.isArray(directories) && directories.length <= AGENT_POLICY_LIMITS.discoveryDirectories, "Invalid native discovery directory collection");
|
|
10365
10373
|
for (const directory of directories)
|
|
10366
10374
|
need3(directory && typeof directory === "object" && (directory.sha256 === null || typeof directory.sha256 === "string" && /^[a-f0-9]{64}$/.test(directory.sha256)), "Invalid native discovery directory digest");
|
|
10367
10375
|
const current = captureDiscoveryDirectories(directories.map((directory) => directory.path), excludedRoots);
|
|
10376
|
+
let legacy;
|
|
10368
10377
|
for (let i = 0;i < directories.length; i++)
|
|
10369
10378
|
if (current[i].sha256 !== directories[i].sha256) {
|
|
10379
|
+
legacy ??= captureOrdinaryDirectories(directories.map((directory) => directory.path), excludedRoots, "retain");
|
|
10380
|
+
if (legacy[i].sha256 === directories[i].sha256)
|
|
10381
|
+
continue;
|
|
10370
10382
|
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);
|
|
10371
10383
|
}
|
|
10372
10384
|
}
|
|
@@ -15852,7 +15864,7 @@ import { basename as basename14, dirname as dirname25, isAbsolute as isAbsolute2
|
|
|
15852
15864
|
import { homedir as homedir5 } from "os";
|
|
15853
15865
|
import { isAbsolute as isAbsolute25, join as join37, resolve as resolve24 } from "path";
|
|
15854
15866
|
// package.json
|
|
15855
|
-
var version = "0.10.
|
|
15867
|
+
var version = "0.10.82";
|
|
15856
15868
|
var package_default = {
|
|
15857
15869
|
name: "@hasna/skills",
|
|
15858
15870
|
version,
|
|
@@ -49531,7 +49543,7 @@ function checkedPublicationView(value, skillId, intentId, declaration) {
|
|
|
49531
49543
|
return invalid4();
|
|
49532
49544
|
return Object.freeze({ ...value });
|
|
49533
49545
|
}
|
|
49534
|
-
async function boundedJson(url2, init, token, mutation, budget3 = 15000, signal, create = false) {
|
|
49546
|
+
async function boundedJson(url2, init, token, mutation, budget3 = 15000, signal, create = false, readBinding) {
|
|
49535
49547
|
const controller = new AbortController;
|
|
49536
49548
|
let reader;
|
|
49537
49549
|
let response;
|
|
@@ -49547,8 +49559,18 @@ async function boundedJson(url2, init, token, mutation, budget3 = 15000, signal,
|
|
|
49547
49559
|
redirect: "error",
|
|
49548
49560
|
credentials: "omit",
|
|
49549
49561
|
signal: controller.signal,
|
|
49550
|
-
headers: {
|
|
49562
|
+
headers: {
|
|
49563
|
+
"Content-Type": "application/json",
|
|
49564
|
+
Authorization: `Bearer ${token}`,
|
|
49565
|
+
...readBinding ? {
|
|
49566
|
+
"x-skills-user-id": readBinding.userId,
|
|
49567
|
+
"x-skills-workspace-id": readBinding.organizationId,
|
|
49568
|
+
"x-skills-membership-id": readBinding.membershipId
|
|
49569
|
+
} : {}
|
|
49570
|
+
}
|
|
49551
49571
|
});
|
|
49572
|
+
if (readBinding && response.ok && response.status !== 200)
|
|
49573
|
+
return invalid4();
|
|
49552
49574
|
const length = response.headers.get("content-length");
|
|
49553
49575
|
if (length !== null && (!/^\d+$/.test(length) || Number(length) > 65536))
|
|
49554
49576
|
return invalid4();
|
|
@@ -49616,6 +49638,88 @@ async function boundedJson(url2, init, token, mutation, budget3 = 15000, signal,
|
|
|
49616
49638
|
response?.body?.cancel().catch(() => {});
|
|
49617
49639
|
}
|
|
49618
49640
|
}
|
|
49641
|
+
var historyInput = () => {
|
|
49642
|
+
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.");
|
|
49643
|
+
};
|
|
49644
|
+
var historyResponse = () => {
|
|
49645
|
+
throw new PrivatePublicationError("INVALID_PRIVATE_HISTORY_RESPONSE", "The server returned invalid private version history.");
|
|
49646
|
+
};
|
|
49647
|
+
var historyText = (value) => typeof value === "string" && value.length > 0 && value.length <= 128 && !/[\p{Cc}\p{Cs}\u2028\u2029]/u.test(value);
|
|
49648
|
+
function historyDate(value) {
|
|
49649
|
+
if (typeof value !== "string")
|
|
49650
|
+
return false;
|
|
49651
|
+
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);
|
|
49652
|
+
if (!parts)
|
|
49653
|
+
return false;
|
|
49654
|
+
const [, y, m, d, separator, h, minute, second, fraction, zone, offsetHour, offsetMinute] = parts;
|
|
49655
|
+
if (separator === " " ? zone === "Z" || (fraction?.length ?? 0) > 6 : zone !== "Z" && offsetMinute === undefined)
|
|
49656
|
+
return false;
|
|
49657
|
+
const year = Number(y), month = Number(m), day = Number(d);
|
|
49658
|
+
const leap = year % 4 === 0 && (year % 100 !== 0 || year % 400 === 0);
|
|
49659
|
+
const days = [31, leap ? 29 : 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
|
|
49660
|
+
return year > 0 && month >= 1 && month <= 12 && day >= 1 && day <= days[month - 1] && Number(h) <= 23 && Number(minute) <= 59 && Number(second) <= 59 && (zone === "Z" || Number(offsetHour) <= 23 && Number(offsetMinute ?? 0) <= 59);
|
|
49661
|
+
}
|
|
49662
|
+
function privateHistory(value, organizationId, skillId, limit, cursor2) {
|
|
49663
|
+
if (!record11(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)
|
|
49664
|
+
return historyResponse();
|
|
49665
|
+
const seen = new Set;
|
|
49666
|
+
let previous = cursor2;
|
|
49667
|
+
const versions2 = value.versions.map((row) => {
|
|
49668
|
+
if (!record11(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))
|
|
49669
|
+
return historyResponse();
|
|
49670
|
+
seen.add(row.id);
|
|
49671
|
+
previous = row.id;
|
|
49672
|
+
return Object.freeze({ id: row.id, version: row.version, releasedAt: row.releasedAt, createdAt: row.createdAt });
|
|
49673
|
+
});
|
|
49674
|
+
if (value.nextCursor !== null && (!versions2.length || value.nextCursor !== versions2.at(-1).id))
|
|
49675
|
+
return historyResponse();
|
|
49676
|
+
return Object.freeze({
|
|
49677
|
+
organizationId,
|
|
49678
|
+
skillId,
|
|
49679
|
+
slug: value.slug,
|
|
49680
|
+
currentVersion: value.currentVersion,
|
|
49681
|
+
currentVersionId: value.currentVersionId,
|
|
49682
|
+
versions: Object.freeze(versions2),
|
|
49683
|
+
nextCursor: value.nextCursor
|
|
49684
|
+
});
|
|
49685
|
+
}
|
|
49686
|
+
|
|
49687
|
+
class RemotePrivateSkillHistoryClient {
|
|
49688
|
+
apiOrigin;
|
|
49689
|
+
organizationId;
|
|
49690
|
+
userId;
|
|
49691
|
+
membershipId;
|
|
49692
|
+
#token;
|
|
49693
|
+
constructor(apiUrl, session) {
|
|
49694
|
+
const checked = parseWorkspaceSession(session, { userId: session?.user?.id, membershipId: session?.user?.membershipId });
|
|
49695
|
+
this.apiOrigin = normalizeSkillsApiOrigin(apiUrl);
|
|
49696
|
+
this.#token = checked.token;
|
|
49697
|
+
this.organizationId = checked.organization.id;
|
|
49698
|
+
this.userId = checked.user.id;
|
|
49699
|
+
this.membershipId = checked.user.membershipId;
|
|
49700
|
+
Object.freeze(this);
|
|
49701
|
+
}
|
|
49702
|
+
async listVersions(skillId, options = {}) {
|
|
49703
|
+
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))
|
|
49704
|
+
return historyInput();
|
|
49705
|
+
const limit = options.limit ?? 20, cursor2 = options.cursor;
|
|
49706
|
+
const query = new URLSearchParams;
|
|
49707
|
+
if (options.limit !== undefined)
|
|
49708
|
+
query.set("limit", String(limit));
|
|
49709
|
+
if (cursor2 !== undefined)
|
|
49710
|
+
query.set("cursor", cursor2);
|
|
49711
|
+
const path = `/api/v1/skills/${skillId}/versions${query.size ? `?${query}` : ""}`;
|
|
49712
|
+
let value;
|
|
49713
|
+
try {
|
|
49714
|
+
value = await boundedJson(skillsApiRequestUrl(this.apiOrigin, path), { method: "GET" }, this.#token, false, options.timeoutMs, options.signal, false, this);
|
|
49715
|
+
} catch (error61) {
|
|
49716
|
+
if (error61 instanceof PrivatePublicationError && error61.code === "INVALID_PUBLICATION_RESPONSE")
|
|
49717
|
+
return historyResponse();
|
|
49718
|
+
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);
|
|
49719
|
+
}
|
|
49720
|
+
return privateHistory(value, this.organizationId, skillId, limit, cursor2);
|
|
49721
|
+
}
|
|
49722
|
+
}
|
|
49619
49723
|
|
|
49620
49724
|
class RemotePrivatePublicationsClient {
|
|
49621
49725
|
apiOrigin;
|
|
@@ -49868,6 +49972,10 @@ class RemoteSkillsAuthClient {
|
|
|
49868
49972
|
const origin = this.apiOrigin, captured = workspaceContext(context);
|
|
49869
49973
|
return new RemotePrivatePublicationsClient(origin, await this.switchWorkspace(email4, code, captured));
|
|
49870
49974
|
}
|
|
49975
|
+
async openPrivateSkillHistory(email4, code, context) {
|
|
49976
|
+
const origin = this.apiOrigin, captured = workspaceContext(context);
|
|
49977
|
+
return new RemotePrivateSkillHistoryClient(origin, await this.switchWorkspace(email4, code, captured));
|
|
49978
|
+
}
|
|
49871
49979
|
requestInvitationEmailChallenge(input2) {
|
|
49872
49980
|
return requestInvitationEmail(this.apiOrigin, "challenge", input2);
|
|
49873
49981
|
}
|
|
@@ -53463,6 +53571,7 @@ export {
|
|
|
53463
53571
|
RemoteRouteUnsupportedError,
|
|
53464
53572
|
RemoteRequestError,
|
|
53465
53573
|
RemoteQuoteUnavailableError,
|
|
53574
|
+
RemotePrivateSkillHistoryClient,
|
|
53466
53575
|
RemotePrivatePublicationsClient,
|
|
53467
53576
|
RemoteInvitationEmailUnconfirmedError,
|
|
53468
53577
|
RemoteInvitationEmailError,
|
|
@@ -15,7 +15,8 @@ export declare function captureDiscoveryDirectoryProjection(paths: string[], omi
|
|
|
15
15
|
* membership change is a NativeDiscoveryWitnessChange: thrown, unless the live
|
|
16
16
|
* Codex prompt hook's tolerance accepts it. Invalid inventories always throw. */
|
|
17
17
|
export declare function verifyDiscoveryDirectoryProjection(directories: DiscoveryDirectoryProjection[], omittedRoots: readonly string[], tolerance?: NativeDiscoveryWitnessTolerance): void;
|
|
18
|
-
/** Read-only capture
|
|
18
|
+
/** Read-only membership capture, excluding validated Claude cleanup markers.
|
|
19
|
+
* Callers must still review source bytes; projected inventories remain exact. */
|
|
19
20
|
export declare function captureDiscoveryDirectories(paths: string[], excludedRoots?: readonly string[]): DiscoveryDirectory[];
|
|
20
21
|
/** A membership change is a NativeDiscoveryWitnessChange: thrown, unless the
|
|
21
22
|
* live Codex prompt hook's tolerance accepts it. Invalid collections always throw. */
|
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
import { RemotePrivatePublicationsClient } from "./remote-private-publications.js";
|
|
2
2
|
import type { RemoteWorkspaceContext } from "./remote-workspace-selection.js";
|
|
3
|
-
/** Capture before code input, so a later profile/origin change cannot retarget consent. */
|
|
4
3
|
export declare function preparePrivatePublicationSession(requested?: RemoteWorkspaceContext): {
|
|
5
4
|
origin: string;
|
|
6
5
|
verify(email: string, code: string): Promise<RemotePrivatePublicationsClient>;
|
|
7
6
|
};
|
|
7
|
+
export declare function preparePrivateSkillHistorySession(requested?: RemoteWorkspaceContext): {
|
|
8
|
+
origin: string;
|
|
9
|
+
verify(email: string, code: string): Promise<import("./remote-private-publications.js").RemotePrivateSkillHistoryClient>;
|
|
10
|
+
};
|
|
8
11
|
/** Neither the session nor a signed upload capability is saved to host credentials. */
|
|
9
12
|
export declare function privatePublicationSession(email: string, code: string, requested?: RemoteWorkspaceContext): Promise<RemotePrivatePublicationsClient>;
|
|
10
13
|
export declare function privatePublicationCustomerError(error: unknown): {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type RequestInvitationEmailChallenge, type AcceptInvitationEmailChallenge } from "./remote-invitation-recovery.js";
|
|
2
|
-
import { RemotePrivatePublicationsClient } from "./remote-private-publications.js";
|
|
2
|
+
import { RemotePrivatePublicationsClient, RemotePrivateSkillHistoryClient } from "./remote-private-publications.js";
|
|
3
3
|
import { type ListRemoteWorkspaceInvitations, type IssueRemoteWorkspaceInvitation, type ResendRemoteWorkspaceInvitation, type RevokeRemoteWorkspaceInvitation, type AcceptRemoteWorkspaceInvitation } from "./remote-invitations.js";
|
|
4
4
|
import { type LeaveRemoteWorkspace } from "./remote-workspace-leave.js";
|
|
5
5
|
import { type RemoteWorkspaceContext, type RemoteWorkspaceSession, type RemoteAccountWorkspaceDiscovery } from "./remote-workspace-selection.js";
|
|
@@ -26,6 +26,8 @@ export declare class RemoteSkillsAuthClient {
|
|
|
26
26
|
constructor(apiUrl: string);
|
|
27
27
|
/** One fresh workspace-bound session for an entire publication. No credentials are saved. */
|
|
28
28
|
openPrivatePublications(email: string, code: string, context: RemoteWorkspaceContext): Promise<RemotePrivatePublicationsClient>;
|
|
29
|
+
/** Fresh workspace-bound, read-only private history session; no key is created or saved. */
|
|
30
|
+
openPrivateSkillHistory(email: string, code: string, context: RemoteWorkspaceContext): Promise<RemotePrivateSkillHistoryClient>;
|
|
29
31
|
requestInvitationEmailChallenge(input: RequestInvitationEmailChallenge): Promise<import("./remote-invitation-recovery.js").RemoteInvitationEmailChallenge>;
|
|
30
32
|
acceptInvitationEmailChallenge(input: AcceptInvitationEmailChallenge): Promise<import("./remote-invitation-recovery.js").RemoteInvitationEmailAcceptance>;
|
|
31
33
|
requestCode(email: string): Promise<any>;
|
|
@@ -64,6 +64,41 @@ export declare const publicationSha256: (bytes: Uint8Array | string) => string;
|
|
|
64
64
|
export declare function checkedPrivateSkillCreate(value: unknown): Omit<Required<CreatePrivateSkillInput>, "confirm">;
|
|
65
65
|
export declare function checkedPublicationDeclaration(value: unknown): PrivatePublicationDeclaration;
|
|
66
66
|
export declare function checkedPublicationView(value: unknown, skillId: string, intentId?: string, declaration?: PrivatePublicationDeclaration): PrivatePublicationView;
|
|
67
|
+
/** Metadata-only private history uses the existing interactive UUID route,
|
|
68
|
+
* distinct from the public slug/API-key version contract. */
|
|
69
|
+
export interface PrivateSkillVersion {
|
|
70
|
+
id: string;
|
|
71
|
+
version: string;
|
|
72
|
+
releasedAt: string | null;
|
|
73
|
+
createdAt: string;
|
|
74
|
+
}
|
|
75
|
+
export interface PrivateSkillVersionHistory {
|
|
76
|
+
organizationId: string;
|
|
77
|
+
skillId: string;
|
|
78
|
+
slug: string;
|
|
79
|
+
currentVersion: string | null;
|
|
80
|
+
currentVersionId: string | null;
|
|
81
|
+
versions: readonly PrivateSkillVersion[];
|
|
82
|
+
nextCursor: string | null;
|
|
83
|
+
}
|
|
84
|
+
export interface PrivateSkillVersionHistoryOptions {
|
|
85
|
+
limit?: number;
|
|
86
|
+
cursor?: string;
|
|
87
|
+
timeoutMs?: number;
|
|
88
|
+
signal?: AbortSignal;
|
|
89
|
+
}
|
|
90
|
+
/** Read-only session consumer; permits viewer history without granting any publication action.
|
|
91
|
+
* Tokens stay in a private field and are never persisted or serialized. */
|
|
92
|
+
export declare class RemotePrivateSkillHistoryClient {
|
|
93
|
+
#private;
|
|
94
|
+
readonly apiOrigin: string;
|
|
95
|
+
readonly organizationId: string;
|
|
96
|
+
readonly userId: string;
|
|
97
|
+
readonly membershipId: string;
|
|
98
|
+
constructor(apiUrl: string, session: RemoteWorkspaceSession);
|
|
99
|
+
/** One page and one GET. Follow nextCursor explicitly; an error never prints partial history. */
|
|
100
|
+
listVersions(skillId: string, options?: PrivateSkillVersionHistoryOptions): Promise<PrivateSkillVersionHistory>;
|
|
101
|
+
}
|
|
67
102
|
/** Explicit hosted contract, unrelated to registry publishSkill and its content revisions.
|
|
68
103
|
* Session tokens stay in private fields and are never written to credentials. */
|
|
69
104
|
export declare class RemotePrivatePublicationsClient {
|
|
@@ -49,7 +49,7 @@ var __require = import.meta.require;
|
|
|
49
49
|
// src/runtime-prerequisites.ts
|
|
50
50
|
import { isAbsolute as isAbsolute7 } from "path";
|
|
51
51
|
// package.json
|
|
52
|
-
var version = "0.10.
|
|
52
|
+
var version = "0.10.82";
|
|
53
53
|
var package_default = {
|
|
54
54
|
name: "@hasna/skills",
|
|
55
55
|
version,
|
|
@@ -2554,7 +2554,7 @@ function hashClaudePluginCacheOrphanMarker(path, budget, changes) {
|
|
|
2554
2554
|
if (!before)
|
|
2555
2555
|
return null;
|
|
2556
2556
|
const uid = process.getuid?.();
|
|
2557
|
-
if (!before.isFile() || uid === undefined || before.uid !== uid || before.size > 32)
|
|
2557
|
+
if (!before.isFile() || uid === undefined || before.uid !== uid || before.size > 32 || (before.mode & 73) !== 0)
|
|
2558
2558
|
throw new Error("Invalid Claude orphan marker file or owner");
|
|
2559
2559
|
const fd = openSync4(path, constants4.O_RDONLY | constants4.O_NOFOLLOW | constants4.O_NONBLOCK);
|
|
2560
2560
|
try {
|
package/dist/sdk/index.d.ts
CHANGED
|
@@ -61,7 +61,7 @@ export { WorkspaceLeaveInputError, RemoteWorkspaceLeaveError, RemoteWorkspaceLea
|
|
|
61
61
|
export type { RemoteWorkspaceInvitation, RemoteWorkspaceInvitationsPage, RemoteWorkspaceInvitationResult, RemoteWorkspaceInvitationAcceptance, ListRemoteWorkspaceInvitations, IssueRemoteWorkspaceInvitation, ResendRemoteWorkspaceInvitation, RevokeRemoteWorkspaceInvitation, AcceptRemoteWorkspaceInvitation, RemoteWorkspaceInvitationErrorCode } from "../lib/remote-invitations.js";
|
|
62
62
|
export { WorkspaceInvitationInputError, RemoteWorkspaceInvitationError, RemoteWorkspaceInvitationUnconfirmedError, RemoteWorkspaceInvitationReadError } from "../lib/remote-invitations.js";
|
|
63
63
|
export { InvitationEmailInputError, RemoteInvitationEmailError, RemoteInvitationEmailUnconfirmedError, type RequestInvitationEmailChallenge, type AcceptInvitationEmailChallenge, type RemoteInvitationEmailChallenge, type RemoteInvitationEmailAcceptance, type RemoteInvitationEmailErrorCode } from "../lib/remote-invitation-recovery.js";
|
|
64
|
-
export { RemotePrivatePublicationsClient, PrivatePublicationError, PRIVATE_PUBLICATION_MAX_BYTES, type CreatePrivateSkillInput, type CreatedPrivateSkill, type PrivatePublicationDeclaration, type PrivatePublicationView, type PrivatePublicationState, type PrivatePublishingCapability } from "../lib/remote-private-publications.js";
|
|
64
|
+
export { RemotePrivatePublicationsClient, RemotePrivateSkillHistoryClient, PrivatePublicationError, PRIVATE_PUBLICATION_MAX_BYTES, type PrivateSkillVersion, type PrivateSkillVersionHistory, type PrivateSkillVersionHistoryOptions, type CreatePrivateSkillInput, type CreatedPrivateSkill, type PrivatePublicationDeclaration, type PrivatePublicationView, type PrivatePublicationState, type PrivatePublishingCapability } from "../lib/remote-private-publications.js";
|
|
65
65
|
export { preparePrivatePublication, readPrivatePublicationRecovery, continuePrivatePublication, inspectPrivatePublication, type PrivatePublicationRecovery, type PrivatePublicationResult } from "../lib/private-publication-recovery.js";
|
|
66
66
|
export { createSkillOperationClient, SkillOperationClientError, SKILL_OPERATION_LIMITS, type SkillOperationClient, type SkillOperationTransport, type SkillOperationRequest, type SkillOperationResult, type SkillOperationJson, type SkillOperationRefusal, type SkillOperationClientErrorCode } from "./operations.js";
|
|
67
67
|
export type { RemoteCreditCheckoutOptions, RemoteCreditCheckout, RemoteCreditCheckoutErrorCode } from "../lib/remote-credit-checkout.js";
|