@hasna/skills 0.10.77 → 0.10.78
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 +39 -1
- package/bin/index.js +547 -283
- package/bin/mcp.js +93 -17
- package/bin/migrate.js +1 -1
- package/bin/server.js +1 -1
- package/bin/worker.js +1 -1
- package/dist/cli/commands/runtime-mcp.d.ts +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +56 -8
- package/dist/lib/mcp-registration-environment.d.ts +2 -0
- package/dist/lib/private-publication-customer.d.ts +6 -2
- package/dist/lib/registry-types.d.ts +2 -0
- package/dist/lib/remote-private-publications.d.ts +22 -0
- package/dist/runtime-prerequisites.js +3 -2
- package/dist/sdk/index.d.ts +1 -1
- package/dist/sdk/index.js +53 -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.78",
|
|
27
27
|
description: "Skills library for AI coding agents",
|
|
28
28
|
type: "module",
|
|
29
29
|
bin: {
|
|
@@ -22805,7 +22805,8 @@ var init_codex_native_compatibility = __esm(() => {
|
|
|
22805
22805
|
"codex-cli 0.160.1": ["hooks", "qualified-skill-catalog", "installed-plugin-review"],
|
|
22806
22806
|
"codex-cli 0.161.0": ["hooks", "qualified-skill-catalog", "installed-plugin-review"],
|
|
22807
22807
|
"codex-cli 0.162.0": ["hooks", "qualified-skill-catalog", "installed-plugin-review"],
|
|
22808
|
-
"codex-cli 0.162.1": ["hooks", "qualified-skill-catalog", "installed-plugin-review"]
|
|
22808
|
+
"codex-cli 0.162.1": ["hooks", "qualified-skill-catalog", "installed-plugin-review"],
|
|
22809
|
+
"codex-cli 0.163.0": ["hooks", "qualified-skill-catalog", "installed-plugin-review"]
|
|
22809
22810
|
};
|
|
22810
22811
|
SUPPORTED_CODEX_HOOK_VERSIONS = Object.freeze(Object.keys(MEASURED_CODEX_CAPABILITIES).filter((version2) => supportsCodexNativeCapability(version2, "hooks")));
|
|
22811
22812
|
});
|
|
@@ -39120,6 +39121,7 @@ function normalizeRemoteSkill(skill) {
|
|
|
39120
39121
|
if (!name)
|
|
39121
39122
|
throw new Error("Remote skill requires name or slug");
|
|
39122
39123
|
return {
|
|
39124
|
+
...skill.id !== undefined ? { id: skill.id } : {},
|
|
39123
39125
|
name,
|
|
39124
39126
|
displayName: skill.displayName || titleize(name),
|
|
39125
39127
|
description: skill.description || "",
|
|
@@ -39224,11 +39226,12 @@ var init_remote_registry = __esm(() => {
|
|
|
39224
39226
|
details: exports_external.array(exports_external.string()).optional()
|
|
39225
39227
|
}).passthrough();
|
|
39226
39228
|
remoteSkillSchema = exports_external.object({
|
|
39229
|
+
id: exports_external.string().regex(/^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/).optional(),
|
|
39227
39230
|
name: exports_external.string().min(1).optional(),
|
|
39228
39231
|
slug: exports_external.string().min(1).optional(),
|
|
39229
39232
|
displayName: exports_external.string().optional(),
|
|
39230
39233
|
description: exports_external.string().optional(),
|
|
39231
|
-
category: exports_external.string().optional(),
|
|
39234
|
+
category: exports_external.string().nullable().optional(),
|
|
39232
39235
|
tags: exports_external.array(exports_external.string()).optional(),
|
|
39233
39236
|
dependencies: exports_external.array(exports_external.string()).optional(),
|
|
39234
39237
|
version: exports_external.string().optional(),
|
|
@@ -41617,6 +41620,24 @@ var init_remote_invitation_recovery = __esm(() => {
|
|
|
41617
41620
|
|
|
41618
41621
|
// src/lib/remote-private-publications.ts
|
|
41619
41622
|
import { createHash as createHash26 } from "crypto";
|
|
41623
|
+
function checkedPrivateSkillCreate(value) {
|
|
41624
|
+
const refuse5 = (field3, accepted) => {
|
|
41625
|
+
throw new PrivatePublicationError("INVALID_SKILL_CREATE_INPUT", `Invalid ${field3}. ${accepted}`);
|
|
41626
|
+
};
|
|
41627
|
+
if (!record10(value) || !Object.keys(value).every((key2) => ["slug", "displayName", "description", "visibility", "confirm"].includes(key2)))
|
|
41628
|
+
return refuse5("create input", "Provide only slug, displayName, description, visibility and confirm.");
|
|
41629
|
+
if (value.confirm !== true)
|
|
41630
|
+
throw new PrivatePublicationError("SKILL_CREATE_CONFIRM_REQUIRED", "Explicit confirmation is required to create this skill.");
|
|
41631
|
+
if (typeof value.slug !== "string" || value.slug.length > 128 || !/^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(value.slug))
|
|
41632
|
+
return refuse5("slug", "Use lowercase kebab-case, at most 128 characters.");
|
|
41633
|
+
if (typeof value.displayName !== "string" || !value.displayName.trim() || value.displayName.length > 256 || /[\p{Cc}\p{Cs}\u2028\u2029]/u.test(value.displayName))
|
|
41634
|
+
return refuse5("displayName", "Use nonempty text, at most 256 characters, without control characters.");
|
|
41635
|
+
if (value.description !== undefined && (typeof value.description !== "string" || Buffer.byteLength(value.description) > 8192 || /[\p{Cc}\p{Cs}]/u.test(value.description.replace(/[\r\n\t]/g, ""))))
|
|
41636
|
+
return refuse5("description", "Use text of at most 8192 UTF-8 bytes, without control characters other than tabs and newlines.");
|
|
41637
|
+
if (value.visibility !== undefined && value.visibility !== "private" && value.visibility !== "team")
|
|
41638
|
+
return refuse5("visibility", "Use private or team.");
|
|
41639
|
+
return Object.freeze({ slug: value.slug, displayName: value.displayName.trim(), description: value.description ?? "", visibility: value.visibility ?? "private" });
|
|
41640
|
+
}
|
|
41620
41641
|
function checkedPublicationDeclaration(value) {
|
|
41621
41642
|
if (!exact(value, ["idempotencyKey", "version", "expectedCurrentVersionId", "manifestText", "archiveSha256", "archiveByteSize"]) || !publicationUuid(value.idempotencyKey) || !(value.expectedCurrentVersionId === null || publicationUuid(value.expectedCurrentVersionId)) || typeof value.version !== "string" || !value.version || value.version.length > 128 || /[\p{Cc}\p{Cs}]/u.test(value.version) || typeof value.manifestText !== "string" || Buffer.byteLength(value.manifestText) > 16384 || !hash4(value.archiveSha256) || !Number.isSafeInteger(value.archiveByteSize) || Number(value.archiveByteSize) < 1 || Number(value.archiveByteSize) > PRIVATE_PUBLICATION_MAX_BYTES)
|
|
41622
41643
|
return bad();
|
|
@@ -41636,11 +41657,11 @@ function checkedPublicationView(value, skillId, intentId, declaration) {
|
|
|
41636
41657
|
return invalid4();
|
|
41637
41658
|
return Object.freeze({ ...value });
|
|
41638
41659
|
}
|
|
41639
|
-
async function boundedJson(url2, init, token, mutation, budget3 = 15000, signal) {
|
|
41660
|
+
async function boundedJson(url2, init, token, mutation, budget3 = 15000, signal, create = false) {
|
|
41640
41661
|
const controller = new AbortController;
|
|
41641
41662
|
let reader;
|
|
41642
41663
|
let response;
|
|
41643
|
-
const timeout2 = new PrivatePublicationError("PUBLICATION_UNCONFIRMED", "No confirmed publication result. Inspect the saved intent before retrying.", mutation);
|
|
41664
|
+
const timeout2 = new PrivatePublicationError(create ? "SKILL_CREATE_UNCONFIRMED" : "PUBLICATION_UNCONFIRMED", create ? "Skill creation could not be confirmed. Inspect the workspace for this slug before another create; do not retry automatically." : "No confirmed publication result. Inspect the saved intent before retrying.", mutation);
|
|
41644
41665
|
let timer;
|
|
41645
41666
|
let abort;
|
|
41646
41667
|
try {
|
|
@@ -41680,11 +41701,19 @@ async function boundedJson(url2, init, token, mutation, budget3 = 15000, signal)
|
|
|
41680
41701
|
return invalid4();
|
|
41681
41702
|
}
|
|
41682
41703
|
if (!response.ok) {
|
|
41683
|
-
const
|
|
41684
|
-
|
|
41685
|
-
|
|
41704
|
+
const known = create ? skillCreateFailures : failures2;
|
|
41705
|
+
const code = record10(body) && typeof body.code === "string" && Object.hasOwn(known, body.code) ? body.code : null;
|
|
41706
|
+
if (code && known[code][0] === response.status)
|
|
41707
|
+
throw new PrivatePublicationError(code, known[code][1], mutation && code === "PUBLICATION_UNCERTAIN", response.status);
|
|
41708
|
+
if (create) {
|
|
41709
|
+
if (response.status >= 500)
|
|
41710
|
+
throw timeout2;
|
|
41711
|
+
throw new PrivatePublicationError("SKILL_CREATE_REQUEST_FAILED", "The server refused skill creation.", false, response.status);
|
|
41712
|
+
}
|
|
41686
41713
|
throw new PrivatePublicationError("PUBLICATION_REQUEST_FAILED", "The publication request was refused. Inspect its status before retrying.", mutation && response.status >= 500, response.status);
|
|
41687
41714
|
}
|
|
41715
|
+
if (create && response.status !== 201)
|
|
41716
|
+
return invalid4();
|
|
41688
41717
|
return body;
|
|
41689
41718
|
})(), new Promise((_, reject) => {
|
|
41690
41719
|
abort = () => {
|
|
@@ -41731,6 +41760,15 @@ class RemotePrivatePublicationsClient {
|
|
|
41731
41760
|
this.membershipId = checked.user.membershipId;
|
|
41732
41761
|
Object.freeze(this);
|
|
41733
41762
|
}
|
|
41763
|
+
async createSkill(input2, options = {}) {
|
|
41764
|
+
const body = checkedPrivateSkillCreate(input2);
|
|
41765
|
+
if (options.timeoutMs !== undefined && (!Number.isSafeInteger(options.timeoutMs) || options.timeoutMs < 1 || options.timeoutMs > 15000))
|
|
41766
|
+
throw new PrivatePublicationError("INVALID_SKILL_CREATE_INPUT", "Invalid timeoutMs. Use an integer from 1 to 15000.");
|
|
41767
|
+
const value = await boundedJson(skillsApiRequestUrl(this.apiOrigin, "/api/v1/skills"), { method: "POST", body: JSON.stringify(body) }, this.#token, true, options.timeoutMs, options.signal, true);
|
|
41768
|
+
if (!record10(value) || !publicationUuid(value.id) || value.slug !== body.slug || value.displayName !== body.displayName || value.description !== body.description || value.visibility !== body.visibility || value.sourceType !== "private_hosted" || !record10(value.metadata) || value.metadata.ownerOrganizationId !== this.organizationId)
|
|
41769
|
+
throw new PrivatePublicationError("SKILL_CREATE_UNCONFIRMED", "Skill creation returned an unbound result. Inspect the workspace for this slug before another create; do not retry automatically.", true);
|
|
41770
|
+
return Object.freeze({ id: value.id, slug: body.slug, visibility: body.visibility, sourceType: "private_hosted", ownerOrganizationId: this.organizationId });
|
|
41771
|
+
}
|
|
41734
41772
|
async getCapability(options = {}) {
|
|
41735
41773
|
if (options.timeoutMs !== undefined && (!Number.isSafeInteger(options.timeoutMs) || options.timeoutMs < 1 || options.timeoutMs > 15000))
|
|
41736
41774
|
return bad();
|
|
@@ -41873,7 +41911,7 @@ class RemotePrivatePublicationsClient {
|
|
|
41873
41911
|
}
|
|
41874
41912
|
}
|
|
41875
41913
|
}
|
|
41876
|
-
var PRIVATE_PUBLICATION_MAX_BYTES, failures2, PrivatePublicationError, bad = () => {
|
|
41914
|
+
var PRIVATE_PUBLICATION_MAX_BYTES, skillCreateFailures, failures2, PrivatePublicationError, bad = () => {
|
|
41877
41915
|
throw new PrivatePublicationError("INVALID_PUBLICATION_INPUT", "Invalid publication input or recovery data.");
|
|
41878
41916
|
}, invalid4 = () => {
|
|
41879
41917
|
throw new PrivatePublicationError("INVALID_PUBLICATION_RESPONSE", "The server returned an invalid publication result.");
|
|
@@ -41883,6 +41921,16 @@ var init_remote_private_publications = __esm(() => {
|
|
|
41883
41921
|
init_remote_workspace_selection();
|
|
41884
41922
|
init_skill_contract();
|
|
41885
41923
|
PRIVATE_PUBLICATION_MAX_BYTES = 16 * 1024 * 1024;
|
|
41924
|
+
skillCreateFailures = {
|
|
41925
|
+
INVALID_SLUG: [400, "Provide a lowercase kebab-case skill slug."],
|
|
41926
|
+
INVALID_DISPLAY_NAME: [400, "Provide a nonempty skill display name."],
|
|
41927
|
+
INVALID_VISIBILITY: [400, "Use private or team visibility for source publication."],
|
|
41928
|
+
SESSION_EXPIRED: [401, "Sign in again before creating a private skill."],
|
|
41929
|
+
INTERACTIVE_SESSION_REQUIRED: [403, "An interactive account session is required to create a private skill."],
|
|
41930
|
+
ACCOUNT_UNAVAILABLE: [403, "The current account membership cannot create a private skill."],
|
|
41931
|
+
PLAN_REQUIRED: [403, "Private and team skills require the Pro plan."],
|
|
41932
|
+
SLUG_CONFLICT: [409, "This skill slug already exists. Inspect the existing skill before publishing."]
|
|
41933
|
+
};
|
|
41886
41934
|
failures2 = {
|
|
41887
41935
|
INVALID_REQUEST: [400, "The publication request is invalid."],
|
|
41888
41936
|
SESSION_EXPIRED: [401, "Sign in again to manage this publication."],
|
|
@@ -48312,15 +48360,42 @@ var init_remote_invitation_tools = __esm(() => {
|
|
|
48312
48360
|
});
|
|
48313
48361
|
|
|
48314
48362
|
// src/lib/private-publication-customer.ts
|
|
48363
|
+
function preparePrivatePublicationSession(requested) {
|
|
48364
|
+
const selectors = [
|
|
48365
|
+
"HASNA_PROFILE",
|
|
48366
|
+
"HASNA_HOME",
|
|
48367
|
+
"HASNA_CONFIG_HOME",
|
|
48368
|
+
"HASNA_STATION",
|
|
48369
|
+
"HASNA_SKILLS_API_URL",
|
|
48370
|
+
"SKILLS_API_URL",
|
|
48371
|
+
"HASNA_SKILLS_API_KEY_OVERRIDE",
|
|
48372
|
+
"HASNA_SKILLS_API_KEY_REF",
|
|
48373
|
+
"HASNA_SKILLS_API_KEY",
|
|
48374
|
+
"SKILLS_API_KEY"
|
|
48375
|
+
];
|
|
48376
|
+
const before = new Map(selectors.map((key2) => [key2, process.env[key2]]));
|
|
48377
|
+
const profile = selectedSkillsProfile(process.env), pending = prepareProfileWorkspace("Manage private publications");
|
|
48378
|
+
const captured = requested ? { ...requested } : undefined;
|
|
48379
|
+
const unchanged3 = () => {
|
|
48380
|
+
if (selectors.some((key2) => process.env[key2] !== before.get(key2)) || selectedSkillsProfile(process.env) !== profile)
|
|
48381
|
+
throw new PrivatePublicationError("PUBLICATION_TARGET_CHANGED", "The selected profile or server changed during verification. Start again with a stable target; no skill action was sent.");
|
|
48382
|
+
};
|
|
48383
|
+
return { origin: pending.origin, async verify(email5, code2) {
|
|
48384
|
+
unchanged3();
|
|
48385
|
+
const target = await pending.resolve();
|
|
48386
|
+
const context2 = captured ?? target.context;
|
|
48387
|
+
if (!context2 || !publicationUuid(context2.userId) || !publicationUuid(context2.membershipId) || target.context && (context2.userId !== target.context.userId || context2.membershipId !== target.context.membershipId))
|
|
48388
|
+
throw new PrivatePublicationError("PUBLICATION_CONTEXT_REQUIRED", "Provide the observed user and membership IDs, or select an enrolled workspace profile.");
|
|
48389
|
+
unchanged3();
|
|
48390
|
+
target.unchanged();
|
|
48391
|
+
const client = await new RemoteSkillsAuthClient(target.origin).openPrivatePublications(email5, code2, context2);
|
|
48392
|
+
unchanged3();
|
|
48393
|
+
target.unchanged();
|
|
48394
|
+
return client;
|
|
48395
|
+
} };
|
|
48396
|
+
}
|
|
48315
48397
|
async function privatePublicationSession(email5, code2, requested) {
|
|
48316
|
-
|
|
48317
|
-
const context2 = requested ?? target.context;
|
|
48318
|
-
if (!context2 || !publicationUuid(context2.userId) || !publicationUuid(context2.membershipId) || target.context && (context2.userId !== target.context.userId || context2.membershipId !== target.context.membershipId))
|
|
48319
|
-
throw new PrivatePublicationError("PUBLICATION_CONTEXT_REQUIRED", "Provide the observed user and membership IDs, or select an enrolled workspace profile.");
|
|
48320
|
-
target.unchanged();
|
|
48321
|
-
const client = await new RemoteSkillsAuthClient(target.origin).openPrivatePublications(email5, code2, context2);
|
|
48322
|
-
target.unchanged();
|
|
48323
|
-
return client;
|
|
48398
|
+
return preparePrivatePublicationSession(requested).verify(email5, code2);
|
|
48324
48399
|
}
|
|
48325
48400
|
function privatePublicationCustomerError(error61) {
|
|
48326
48401
|
return error61 instanceof PrivatePublicationError ? { error: error61.message, code: error61.code, uncertain: error61.uncertain } : { error: "The publication action could not be confirmed. Preserve the recovery directory and inspect the same intent; credentials were not changed.", code: "PUBLICATION_ACTION_UNCONFIRMED", uncertain: true };
|
|
@@ -48329,6 +48404,7 @@ var init_private_publication_customer = __esm(() => {
|
|
|
48329
48404
|
init_remote_auth();
|
|
48330
48405
|
init_remote_private_publications();
|
|
48331
48406
|
init_workspace_profile();
|
|
48407
|
+
init_instance_credentials();
|
|
48332
48408
|
});
|
|
48333
48409
|
|
|
48334
48410
|
// src/lib/private-publication-recovery.ts
|
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.78",
|
|
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.78",
|
|
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 PrivatePublicationDeclaration, type PrivatePublicationView, type PrivatePublicationState, type PrivatePublishingCapability } from "./lib/remote-private-publications.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";
|
|
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
|
@@ -9405,7 +9405,8 @@ var MEASURED_CODEX_CAPABILITIES = {
|
|
|
9405
9405
|
"codex-cli 0.160.1": ["hooks", "qualified-skill-catalog", "installed-plugin-review"],
|
|
9406
9406
|
"codex-cli 0.161.0": ["hooks", "qualified-skill-catalog", "installed-plugin-review"],
|
|
9407
9407
|
"codex-cli 0.162.0": ["hooks", "qualified-skill-catalog", "installed-plugin-review"],
|
|
9408
|
-
"codex-cli 0.162.1": ["hooks", "qualified-skill-catalog", "installed-plugin-review"]
|
|
9408
|
+
"codex-cli 0.162.1": ["hooks", "qualified-skill-catalog", "installed-plugin-review"],
|
|
9409
|
+
"codex-cli 0.163.0": ["hooks", "qualified-skill-catalog", "installed-plugin-review"]
|
|
9409
9410
|
};
|
|
9410
9411
|
function supportsCodexNativeCapability(version, capability) {
|
|
9411
9412
|
return typeof version === "string" && Object.hasOwn(MEASURED_CODEX_CAPABILITIES, version) && MEASURED_CODEX_CAPABILITIES[version].includes(capability);
|
|
@@ -15446,7 +15447,7 @@ import { basename as basename13, dirname as dirname24, isAbsolute as isAbsolute2
|
|
|
15446
15447
|
import { homedir as homedir5 } from "os";
|
|
15447
15448
|
import { isAbsolute as isAbsolute25, join as join36, resolve as resolve24 } from "path";
|
|
15448
15449
|
// package.json
|
|
15449
|
-
var version = "0.10.
|
|
15450
|
+
var version = "0.10.78";
|
|
15450
15451
|
var package_default = {
|
|
15451
15452
|
name: "@hasna/skills",
|
|
15452
15453
|
version,
|
|
@@ -44843,11 +44844,12 @@ var remoteAvailabilitySchema = exports_external.object({
|
|
|
44843
44844
|
details: exports_external.array(exports_external.string()).optional()
|
|
44844
44845
|
}).passthrough();
|
|
44845
44846
|
var remoteSkillSchema = exports_external.object({
|
|
44847
|
+
id: exports_external.string().regex(/^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/).optional(),
|
|
44846
44848
|
name: exports_external.string().min(1).optional(),
|
|
44847
44849
|
slug: exports_external.string().min(1).optional(),
|
|
44848
44850
|
displayName: exports_external.string().optional(),
|
|
44849
44851
|
description: exports_external.string().optional(),
|
|
44850
|
-
category: exports_external.string().optional(),
|
|
44852
|
+
category: exports_external.string().nullable().optional(),
|
|
44851
44853
|
tags: exports_external.array(exports_external.string()).optional(),
|
|
44852
44854
|
dependencies: exports_external.array(exports_external.string()).optional(),
|
|
44853
44855
|
version: exports_external.string().optional(),
|
|
@@ -44908,6 +44910,7 @@ function normalizeRemoteSkill(skill) {
|
|
|
44908
44910
|
if (!name)
|
|
44909
44911
|
throw new Error("Remote skill requires name or slug");
|
|
44910
44912
|
return {
|
|
44913
|
+
...skill.id !== undefined ? { id: skill.id } : {},
|
|
44911
44914
|
name,
|
|
44912
44915
|
displayName: skill.displayName || titleize(name),
|
|
44913
44916
|
description: skill.description || "",
|
|
@@ -48385,6 +48388,16 @@ async function requestInvitationEmail(origin, action, input2) {
|
|
|
48385
48388
|
// src/lib/remote-private-publications.ts
|
|
48386
48389
|
import { createHash as createHash34 } from "crypto";
|
|
48387
48390
|
var PRIVATE_PUBLICATION_MAX_BYTES = 16 * 1024 * 1024;
|
|
48391
|
+
var skillCreateFailures = {
|
|
48392
|
+
INVALID_SLUG: [400, "Provide a lowercase kebab-case skill slug."],
|
|
48393
|
+
INVALID_DISPLAY_NAME: [400, "Provide a nonempty skill display name."],
|
|
48394
|
+
INVALID_VISIBILITY: [400, "Use private or team visibility for source publication."],
|
|
48395
|
+
SESSION_EXPIRED: [401, "Sign in again before creating a private skill."],
|
|
48396
|
+
INTERACTIVE_SESSION_REQUIRED: [403, "An interactive account session is required to create a private skill."],
|
|
48397
|
+
ACCOUNT_UNAVAILABLE: [403, "The current account membership cannot create a private skill."],
|
|
48398
|
+
PLAN_REQUIRED: [403, "Private and team skills require the Pro plan."],
|
|
48399
|
+
SLUG_CONFLICT: [409, "This skill slug already exists. Inspect the existing skill before publishing."]
|
|
48400
|
+
};
|
|
48388
48401
|
var failures2 = {
|
|
48389
48402
|
INVALID_REQUEST: [400, "The publication request is invalid."],
|
|
48390
48403
|
SESSION_EXPIRED: [401, "Sign in again to manage this publication."],
|
|
@@ -48431,6 +48444,24 @@ var record11 = (v) => !!v && typeof v === "object" && !Array.isArray(v);
|
|
|
48431
48444
|
var exact = (v, keys2) => record11(v) && Object.keys(v).sort().join(",") === keys2.sort().join(",");
|
|
48432
48445
|
var 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));
|
|
48433
48446
|
var publicationSha256 = (bytes) => createHash34("sha256").update(bytes).digest("hex");
|
|
48447
|
+
function checkedPrivateSkillCreate(value) {
|
|
48448
|
+
const refuse6 = (field3, accepted) => {
|
|
48449
|
+
throw new PrivatePublicationError("INVALID_SKILL_CREATE_INPUT", `Invalid ${field3}. ${accepted}`);
|
|
48450
|
+
};
|
|
48451
|
+
if (!record11(value) || !Object.keys(value).every((key2) => ["slug", "displayName", "description", "visibility", "confirm"].includes(key2)))
|
|
48452
|
+
return refuse6("create input", "Provide only slug, displayName, description, visibility and confirm.");
|
|
48453
|
+
if (value.confirm !== true)
|
|
48454
|
+
throw new PrivatePublicationError("SKILL_CREATE_CONFIRM_REQUIRED", "Explicit confirmation is required to create this skill.");
|
|
48455
|
+
if (typeof value.slug !== "string" || value.slug.length > 128 || !/^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(value.slug))
|
|
48456
|
+
return refuse6("slug", "Use lowercase kebab-case, at most 128 characters.");
|
|
48457
|
+
if (typeof value.displayName !== "string" || !value.displayName.trim() || value.displayName.length > 256 || /[\p{Cc}\p{Cs}\u2028\u2029]/u.test(value.displayName))
|
|
48458
|
+
return refuse6("displayName", "Use nonempty text, at most 256 characters, without control characters.");
|
|
48459
|
+
if (value.description !== undefined && (typeof value.description !== "string" || Buffer.byteLength(value.description) > 8192 || /[\p{Cc}\p{Cs}]/u.test(value.description.replace(/[\r\n\t]/g, ""))))
|
|
48460
|
+
return refuse6("description", "Use text of at most 8192 UTF-8 bytes, without control characters other than tabs and newlines.");
|
|
48461
|
+
if (value.visibility !== undefined && value.visibility !== "private" && value.visibility !== "team")
|
|
48462
|
+
return refuse6("visibility", "Use private or team.");
|
|
48463
|
+
return Object.freeze({ slug: value.slug, displayName: value.displayName.trim(), description: value.description ?? "", visibility: value.visibility ?? "private" });
|
|
48464
|
+
}
|
|
48434
48465
|
function checkedPublicationDeclaration(value) {
|
|
48435
48466
|
if (!exact(value, ["idempotencyKey", "version", "expectedCurrentVersionId", "manifestText", "archiveSha256", "archiveByteSize"]) || !publicationUuid(value.idempotencyKey) || !(value.expectedCurrentVersionId === null || publicationUuid(value.expectedCurrentVersionId)) || typeof value.version !== "string" || !value.version || value.version.length > 128 || /[\p{Cc}\p{Cs}]/u.test(value.version) || typeof value.manifestText !== "string" || Buffer.byteLength(value.manifestText) > 16384 || !hash4(value.archiveSha256) || !Number.isSafeInteger(value.archiveByteSize) || Number(value.archiveByteSize) < 1 || Number(value.archiveByteSize) > PRIVATE_PUBLICATION_MAX_BYTES)
|
|
48436
48467
|
return bad();
|
|
@@ -48450,11 +48481,11 @@ function checkedPublicationView(value, skillId, intentId, declaration) {
|
|
|
48450
48481
|
return invalid4();
|
|
48451
48482
|
return Object.freeze({ ...value });
|
|
48452
48483
|
}
|
|
48453
|
-
async function boundedJson(url2, init, token, mutation, budget3 = 15000, signal) {
|
|
48484
|
+
async function boundedJson(url2, init, token, mutation, budget3 = 15000, signal, create = false) {
|
|
48454
48485
|
const controller = new AbortController;
|
|
48455
48486
|
let reader;
|
|
48456
48487
|
let response;
|
|
48457
|
-
const timeout2 = new PrivatePublicationError("PUBLICATION_UNCONFIRMED", "No confirmed publication result. Inspect the saved intent before retrying.", mutation);
|
|
48488
|
+
const timeout2 = new PrivatePublicationError(create ? "SKILL_CREATE_UNCONFIRMED" : "PUBLICATION_UNCONFIRMED", create ? "Skill creation could not be confirmed. Inspect the workspace for this slug before another create; do not retry automatically." : "No confirmed publication result. Inspect the saved intent before retrying.", mutation);
|
|
48458
48489
|
let timer;
|
|
48459
48490
|
let abort;
|
|
48460
48491
|
try {
|
|
@@ -48494,11 +48525,19 @@ async function boundedJson(url2, init, token, mutation, budget3 = 15000, signal)
|
|
|
48494
48525
|
return invalid4();
|
|
48495
48526
|
}
|
|
48496
48527
|
if (!response.ok) {
|
|
48497
|
-
const
|
|
48498
|
-
|
|
48499
|
-
|
|
48528
|
+
const known = create ? skillCreateFailures : failures2;
|
|
48529
|
+
const code = record11(body) && typeof body.code === "string" && Object.hasOwn(known, body.code) ? body.code : null;
|
|
48530
|
+
if (code && known[code][0] === response.status)
|
|
48531
|
+
throw new PrivatePublicationError(code, known[code][1], mutation && code === "PUBLICATION_UNCERTAIN", response.status);
|
|
48532
|
+
if (create) {
|
|
48533
|
+
if (response.status >= 500)
|
|
48534
|
+
throw timeout2;
|
|
48535
|
+
throw new PrivatePublicationError("SKILL_CREATE_REQUEST_FAILED", "The server refused skill creation.", false, response.status);
|
|
48536
|
+
}
|
|
48500
48537
|
throw new PrivatePublicationError("PUBLICATION_REQUEST_FAILED", "The publication request was refused. Inspect its status before retrying.", mutation && response.status >= 500, response.status);
|
|
48501
48538
|
}
|
|
48539
|
+
if (create && response.status !== 201)
|
|
48540
|
+
return invalid4();
|
|
48502
48541
|
return body;
|
|
48503
48542
|
})(), new Promise((_, reject) => {
|
|
48504
48543
|
abort = () => {
|
|
@@ -48545,6 +48584,15 @@ class RemotePrivatePublicationsClient {
|
|
|
48545
48584
|
this.membershipId = checked.user.membershipId;
|
|
48546
48585
|
Object.freeze(this);
|
|
48547
48586
|
}
|
|
48587
|
+
async createSkill(input2, options = {}) {
|
|
48588
|
+
const body = checkedPrivateSkillCreate(input2);
|
|
48589
|
+
if (options.timeoutMs !== undefined && (!Number.isSafeInteger(options.timeoutMs) || options.timeoutMs < 1 || options.timeoutMs > 15000))
|
|
48590
|
+
throw new PrivatePublicationError("INVALID_SKILL_CREATE_INPUT", "Invalid timeoutMs. Use an integer from 1 to 15000.");
|
|
48591
|
+
const value = await boundedJson(skillsApiRequestUrl(this.apiOrigin, "/api/v1/skills"), { method: "POST", body: JSON.stringify(body) }, this.#token, true, options.timeoutMs, options.signal, true);
|
|
48592
|
+
if (!record11(value) || !publicationUuid(value.id) || value.slug !== body.slug || value.displayName !== body.displayName || value.description !== body.description || value.visibility !== body.visibility || value.sourceType !== "private_hosted" || !record11(value.metadata) || value.metadata.ownerOrganizationId !== this.organizationId)
|
|
48593
|
+
throw new PrivatePublicationError("SKILL_CREATE_UNCONFIRMED", "Skill creation returned an unbound result. Inspect the workspace for this slug before another create; do not retry automatically.", true);
|
|
48594
|
+
return Object.freeze({ id: value.id, slug: body.slug, visibility: body.visibility, sourceType: "private_hosted", ownerOrganizationId: this.organizationId });
|
|
48595
|
+
}
|
|
48548
48596
|
async getCapability(options = {}) {
|
|
48549
48597
|
if (options.timeoutMs !== undefined && (!Number.isSafeInteger(options.timeoutMs) || options.timeoutMs < 1 || options.timeoutMs > 15000))
|
|
48550
48598
|
return bad();
|
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
import { RemotePrivatePublicationsClient } from "./remote-private-publications.js";
|
|
2
2
|
import type { RemoteWorkspaceContext } from "./remote-workspace-selection.js";
|
|
3
|
-
/** Capture
|
|
4
|
-
|
|
3
|
+
/** Capture before code input, so a later profile/origin change cannot retarget consent. */
|
|
4
|
+
export declare function preparePrivatePublicationSession(requested?: RemoteWorkspaceContext): {
|
|
5
|
+
origin: string;
|
|
6
|
+
verify(email: string, code: string): Promise<RemotePrivatePublicationsClient>;
|
|
7
|
+
};
|
|
8
|
+
/** Neither the session nor a signed upload capability is saved to host credentials. */
|
|
5
9
|
export declare function privatePublicationSession(email: string, code: string, requested?: RemoteWorkspaceContext): Promise<RemotePrivatePublicationsClient>;
|
|
6
10
|
export declare function privatePublicationCustomerError(error: unknown): {
|
|
7
11
|
error: string;
|
|
@@ -5,6 +5,8 @@ export type SkillKind = "executable" | "instruction";
|
|
|
5
5
|
*/
|
|
6
6
|
export type SkillSource = "official" | "custom" | "remote" | "private" | "private-hosted" | "upstream" | "extension";
|
|
7
7
|
export interface SkillMeta {
|
|
8
|
+
/** Immutable server UUID, when supplied and validated by a remote metadata read. */
|
|
9
|
+
id?: string;
|
|
8
10
|
name: string;
|
|
9
11
|
displayName: string;
|
|
10
12
|
description: string;
|
|
@@ -1,5 +1,20 @@
|
|
|
1
1
|
import { type RemoteWorkspaceSession } from "./remote-workspace-selection.js";
|
|
2
2
|
export declare const PRIVATE_PUBLICATION_MAX_BYTES: number;
|
|
3
|
+
export interface CreatePrivateSkillInput {
|
|
4
|
+
slug: string;
|
|
5
|
+
displayName: string;
|
|
6
|
+
description?: string;
|
|
7
|
+
visibility?: "private" | "team";
|
|
8
|
+
confirm: true;
|
|
9
|
+
}
|
|
10
|
+
/** Only validated identifiers and enums are returned; server free text stays private. */
|
|
11
|
+
export interface CreatedPrivateSkill {
|
|
12
|
+
id: string;
|
|
13
|
+
slug: string;
|
|
14
|
+
visibility: "private" | "team";
|
|
15
|
+
sourceType: "private_hosted";
|
|
16
|
+
ownerOrganizationId: string;
|
|
17
|
+
}
|
|
3
18
|
export type PrivatePublicationState = "awaiting_upload" | "queued" | "verifying" | "needs_attention" | "committed" | "rejected" | "cancelled" | "expired";
|
|
4
19
|
export interface PrivatePublicationDeclaration {
|
|
5
20
|
idempotencyKey: string;
|
|
@@ -45,6 +60,8 @@ export declare class PrivatePublicationError extends Error {
|
|
|
45
60
|
}
|
|
46
61
|
export declare const publicationUuid: (v: unknown) => v is string;
|
|
47
62
|
export declare const publicationSha256: (bytes: Uint8Array | string) => string;
|
|
63
|
+
/** Validate and capture before verification or any await. Confirmation is local only. */
|
|
64
|
+
export declare function checkedPrivateSkillCreate(value: unknown): Omit<Required<CreatePrivateSkillInput>, "confirm">;
|
|
48
65
|
export declare function checkedPublicationDeclaration(value: unknown): PrivatePublicationDeclaration;
|
|
49
66
|
export declare function checkedPublicationView(value: unknown, skillId: string, intentId?: string, declaration?: PrivatePublicationDeclaration): PrivatePublicationView;
|
|
50
67
|
/** Explicit hosted contract, unrelated to registry publishSkill and its content revisions.
|
|
@@ -56,6 +73,11 @@ export declare class RemotePrivatePublicationsClient {
|
|
|
56
73
|
readonly userId: string;
|
|
57
74
|
readonly membershipId: string;
|
|
58
75
|
constructor(apiUrl: string, session: RemoteWorkspaceSession);
|
|
76
|
+
/** One session-only POST. An uncertain result must be inspected, never replayed. */
|
|
77
|
+
createSkill(input: CreatePrivateSkillInput, options?: {
|
|
78
|
+
timeoutMs?: number;
|
|
79
|
+
signal?: AbortSignal;
|
|
80
|
+
}): Promise<CreatedPrivateSkill>;
|
|
59
81
|
getCapability(options?: {
|
|
60
82
|
timeoutMs?: number;
|
|
61
83
|
signal?: AbortSignal;
|
|
@@ -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.78";
|
|
53
53
|
var package_default = {
|
|
54
54
|
name: "@hasna/skills",
|
|
55
55
|
version,
|
|
@@ -1955,7 +1955,8 @@ var MEASURED_CODEX_CAPABILITIES = {
|
|
|
1955
1955
|
"codex-cli 0.160.1": ["hooks", "qualified-skill-catalog", "installed-plugin-review"],
|
|
1956
1956
|
"codex-cli 0.161.0": ["hooks", "qualified-skill-catalog", "installed-plugin-review"],
|
|
1957
1957
|
"codex-cli 0.162.0": ["hooks", "qualified-skill-catalog", "installed-plugin-review"],
|
|
1958
|
-
"codex-cli 0.162.1": ["hooks", "qualified-skill-catalog", "installed-plugin-review"]
|
|
1958
|
+
"codex-cli 0.162.1": ["hooks", "qualified-skill-catalog", "installed-plugin-review"],
|
|
1959
|
+
"codex-cli 0.163.0": ["hooks", "qualified-skill-catalog", "installed-plugin-review"]
|
|
1959
1960
|
};
|
|
1960
1961
|
function supportsCodexNativeCapability(version2, capability) {
|
|
1961
1962
|
return typeof version2 === "string" && Object.hasOwn(MEASURED_CODEX_CAPABILITIES, version2) && MEASURED_CODEX_CAPABILITIES[version2].includes(capability);
|
package/dist/sdk/index.d.ts
CHANGED
|
@@ -60,7 +60,7 @@ export { WorkspaceLeaveInputError, RemoteWorkspaceLeaveError, RemoteWorkspaceLea
|
|
|
60
60
|
export type { RemoteWorkspaceInvitation, RemoteWorkspaceInvitationsPage, RemoteWorkspaceInvitationResult, RemoteWorkspaceInvitationAcceptance, ListRemoteWorkspaceInvitations, IssueRemoteWorkspaceInvitation, ResendRemoteWorkspaceInvitation, RevokeRemoteWorkspaceInvitation, AcceptRemoteWorkspaceInvitation, RemoteWorkspaceInvitationErrorCode } from "../lib/remote-invitations.js";
|
|
61
61
|
export { WorkspaceInvitationInputError, RemoteWorkspaceInvitationError, RemoteWorkspaceInvitationUnconfirmedError, RemoteWorkspaceInvitationReadError } from "../lib/remote-invitations.js";
|
|
62
62
|
export { InvitationEmailInputError, RemoteInvitationEmailError, RemoteInvitationEmailUnconfirmedError, type RequestInvitationEmailChallenge, type AcceptInvitationEmailChallenge, type RemoteInvitationEmailChallenge, type RemoteInvitationEmailAcceptance, type RemoteInvitationEmailErrorCode } from "../lib/remote-invitation-recovery.js";
|
|
63
|
-
export { RemotePrivatePublicationsClient, PrivatePublicationError, PRIVATE_PUBLICATION_MAX_BYTES, type PrivatePublicationDeclaration, type PrivatePublicationView, type PrivatePublicationState, type PrivatePublishingCapability } from "../lib/remote-private-publications.js";
|
|
63
|
+
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
64
|
export { preparePrivatePublication, readPrivatePublicationRecovery, continuePrivatePublication, inspectPrivatePublication, type PrivatePublicationRecovery, type PrivatePublicationResult } from "../lib/private-publication-recovery.js";
|
|
65
65
|
export { createSkillOperationClient, SkillOperationClientError, SKILL_OPERATION_LIMITS, type SkillOperationClient, type SkillOperationTransport, type SkillOperationRequest, type SkillOperationResult, type SkillOperationJson, type SkillOperationRefusal, type SkillOperationClientErrorCode } from "./operations.js";
|
|
66
66
|
export type { RemoteCreditCheckoutOptions, RemoteCreditCheckout, RemoteCreditCheckoutErrorCode } from "../lib/remote-credit-checkout.js";
|
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.78";
|
|
32375
32375
|
var package_default = {
|
|
32376
32376
|
name: "@hasna/skills",
|
|
32377
32377
|
version,
|
|
@@ -39103,7 +39103,8 @@ var MEASURED_CODEX_CAPABILITIES = {
|
|
|
39103
39103
|
"codex-cli 0.160.1": ["hooks", "qualified-skill-catalog", "installed-plugin-review"],
|
|
39104
39104
|
"codex-cli 0.161.0": ["hooks", "qualified-skill-catalog", "installed-plugin-review"],
|
|
39105
39105
|
"codex-cli 0.162.0": ["hooks", "qualified-skill-catalog", "installed-plugin-review"],
|
|
39106
|
-
"codex-cli 0.162.1": ["hooks", "qualified-skill-catalog", "installed-plugin-review"]
|
|
39106
|
+
"codex-cli 0.162.1": ["hooks", "qualified-skill-catalog", "installed-plugin-review"],
|
|
39107
|
+
"codex-cli 0.163.0": ["hooks", "qualified-skill-catalog", "installed-plugin-review"]
|
|
39107
39108
|
};
|
|
39108
39109
|
function supportsCodexNativeCapability(version2, capability) {
|
|
39109
39110
|
return typeof version2 === "string" && Object.hasOwn(MEASURED_CODEX_CAPABILITIES, version2) && MEASURED_CODEX_CAPABILITIES[version2].includes(capability);
|
|
@@ -98372,6 +98373,16 @@ async function requestInvitationEmail(origin, action, input2) {
|
|
|
98372
98373
|
// src/lib/remote-private-publications.ts
|
|
98373
98374
|
import { createHash as createHash45 } from "crypto";
|
|
98374
98375
|
var PRIVATE_PUBLICATION_MAX_BYTES = 16 * 1024 * 1024;
|
|
98376
|
+
var skillCreateFailures = {
|
|
98377
|
+
INVALID_SLUG: [400, "Provide a lowercase kebab-case skill slug."],
|
|
98378
|
+
INVALID_DISPLAY_NAME: [400, "Provide a nonempty skill display name."],
|
|
98379
|
+
INVALID_VISIBILITY: [400, "Use private or team visibility for source publication."],
|
|
98380
|
+
SESSION_EXPIRED: [401, "Sign in again before creating a private skill."],
|
|
98381
|
+
INTERACTIVE_SESSION_REQUIRED: [403, "An interactive account session is required to create a private skill."],
|
|
98382
|
+
ACCOUNT_UNAVAILABLE: [403, "The current account membership cannot create a private skill."],
|
|
98383
|
+
PLAN_REQUIRED: [403, "Private and team skills require the Pro plan."],
|
|
98384
|
+
SLUG_CONFLICT: [409, "This skill slug already exists. Inspect the existing skill before publishing."]
|
|
98385
|
+
};
|
|
98375
98386
|
var failures2 = {
|
|
98376
98387
|
INVALID_REQUEST: [400, "The publication request is invalid."],
|
|
98377
98388
|
SESSION_EXPIRED: [401, "Sign in again to manage this publication."],
|
|
@@ -98418,6 +98429,24 @@ var record12 = (v2) => !!v2 && typeof v2 === "object" && !Array.isArray(v2);
|
|
|
98418
98429
|
var exact = (v2, keys4) => record12(v2) && Object.keys(v2).sort().join(",") === keys4.sort().join(",");
|
|
98419
98430
|
var date5 = (v2) => typeof v2 === "string" && /^\d{4}-\d\d-\d\dT[0-9:.]+(?:Z|[+-](?:[01]\d|2[0-3]):[0-5]\d)$/.test(v2) && Number.isFinite(Date.parse(v2));
|
|
98420
98431
|
var publicationSha256 = (bytes) => createHash45("sha256").update(bytes).digest("hex");
|
|
98432
|
+
function checkedPrivateSkillCreate(value) {
|
|
98433
|
+
const refuse8 = (field3, accepted) => {
|
|
98434
|
+
throw new PrivatePublicationError("INVALID_SKILL_CREATE_INPUT", `Invalid ${field3}. ${accepted}`);
|
|
98435
|
+
};
|
|
98436
|
+
if (!record12(value) || !Object.keys(value).every((key2) => ["slug", "displayName", "description", "visibility", "confirm"].includes(key2)))
|
|
98437
|
+
return refuse8("create input", "Provide only slug, displayName, description, visibility and confirm.");
|
|
98438
|
+
if (value.confirm !== true)
|
|
98439
|
+
throw new PrivatePublicationError("SKILL_CREATE_CONFIRM_REQUIRED", "Explicit confirmation is required to create this skill.");
|
|
98440
|
+
if (typeof value.slug !== "string" || value.slug.length > 128 || !/^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(value.slug))
|
|
98441
|
+
return refuse8("slug", "Use lowercase kebab-case, at most 128 characters.");
|
|
98442
|
+
if (typeof value.displayName !== "string" || !value.displayName.trim() || value.displayName.length > 256 || /[\p{Cc}\p{Cs}\u2028\u2029]/u.test(value.displayName))
|
|
98443
|
+
return refuse8("displayName", "Use nonempty text, at most 256 characters, without control characters.");
|
|
98444
|
+
if (value.description !== undefined && (typeof value.description !== "string" || Buffer.byteLength(value.description) > 8192 || /[\p{Cc}\p{Cs}]/u.test(value.description.replace(/[\r\n\t]/g, ""))))
|
|
98445
|
+
return refuse8("description", "Use text of at most 8192 UTF-8 bytes, without control characters other than tabs and newlines.");
|
|
98446
|
+
if (value.visibility !== undefined && value.visibility !== "private" && value.visibility !== "team")
|
|
98447
|
+
return refuse8("visibility", "Use private or team.");
|
|
98448
|
+
return Object.freeze({ slug: value.slug, displayName: value.displayName.trim(), description: value.description ?? "", visibility: value.visibility ?? "private" });
|
|
98449
|
+
}
|
|
98421
98450
|
function checkedPublicationDeclaration(value) {
|
|
98422
98451
|
if (!exact(value, ["idempotencyKey", "version", "expectedCurrentVersionId", "manifestText", "archiveSha256", "archiveByteSize"]) || !publicationUuid(value.idempotencyKey) || !(value.expectedCurrentVersionId === null || publicationUuid(value.expectedCurrentVersionId)) || typeof value.version !== "string" || !value.version || value.version.length > 128 || /[\p{Cc}\p{Cs}]/u.test(value.version) || typeof value.manifestText !== "string" || Buffer.byteLength(value.manifestText) > 16384 || !hash5(value.archiveSha256) || !Number.isSafeInteger(value.archiveByteSize) || Number(value.archiveByteSize) < 1 || Number(value.archiveByteSize) > PRIVATE_PUBLICATION_MAX_BYTES)
|
|
98423
98452
|
return bad();
|
|
@@ -98437,11 +98466,11 @@ function checkedPublicationView(value, skillId, intentId, declaration) {
|
|
|
98437
98466
|
return invalid7();
|
|
98438
98467
|
return Object.freeze({ ...value });
|
|
98439
98468
|
}
|
|
98440
|
-
async function boundedJson(url2, init, token, mutation, budget3 = 15000, signal) {
|
|
98469
|
+
async function boundedJson(url2, init, token, mutation, budget3 = 15000, signal, create = false) {
|
|
98441
98470
|
const controller = new AbortController;
|
|
98442
98471
|
let reader;
|
|
98443
98472
|
let response;
|
|
98444
|
-
const timeout2 = new PrivatePublicationError("PUBLICATION_UNCONFIRMED", "No confirmed publication result. Inspect the saved intent before retrying.", mutation);
|
|
98473
|
+
const timeout2 = new PrivatePublicationError(create ? "SKILL_CREATE_UNCONFIRMED" : "PUBLICATION_UNCONFIRMED", create ? "Skill creation could not be confirmed. Inspect the workspace for this slug before another create; do not retry automatically." : "No confirmed publication result. Inspect the saved intent before retrying.", mutation);
|
|
98445
98474
|
let timer;
|
|
98446
98475
|
let abort;
|
|
98447
98476
|
try {
|
|
@@ -98481,11 +98510,19 @@ async function boundedJson(url2, init, token, mutation, budget3 = 15000, signal)
|
|
|
98481
98510
|
return invalid7();
|
|
98482
98511
|
}
|
|
98483
98512
|
if (!response.ok) {
|
|
98484
|
-
const
|
|
98485
|
-
|
|
98486
|
-
|
|
98513
|
+
const known = create ? skillCreateFailures : failures2;
|
|
98514
|
+
const code = record12(body4) && typeof body4.code === "string" && Object.hasOwn(known, body4.code) ? body4.code : null;
|
|
98515
|
+
if (code && known[code][0] === response.status)
|
|
98516
|
+
throw new PrivatePublicationError(code, known[code][1], mutation && code === "PUBLICATION_UNCERTAIN", response.status);
|
|
98517
|
+
if (create) {
|
|
98518
|
+
if (response.status >= 500)
|
|
98519
|
+
throw timeout2;
|
|
98520
|
+
throw new PrivatePublicationError("SKILL_CREATE_REQUEST_FAILED", "The server refused skill creation.", false, response.status);
|
|
98521
|
+
}
|
|
98487
98522
|
throw new PrivatePublicationError("PUBLICATION_REQUEST_FAILED", "The publication request was refused. Inspect its status before retrying.", mutation && response.status >= 500, response.status);
|
|
98488
98523
|
}
|
|
98524
|
+
if (create && response.status !== 201)
|
|
98525
|
+
return invalid7();
|
|
98489
98526
|
return body4;
|
|
98490
98527
|
})(), new Promise((_, reject) => {
|
|
98491
98528
|
abort = () => {
|
|
@@ -98532,6 +98569,15 @@ class RemotePrivatePublicationsClient {
|
|
|
98532
98569
|
this.membershipId = checked.user.membershipId;
|
|
98533
98570
|
Object.freeze(this);
|
|
98534
98571
|
}
|
|
98572
|
+
async createSkill(input2, options = {}) {
|
|
98573
|
+
const body4 = checkedPrivateSkillCreate(input2);
|
|
98574
|
+
if (options.timeoutMs !== undefined && (!Number.isSafeInteger(options.timeoutMs) || options.timeoutMs < 1 || options.timeoutMs > 15000))
|
|
98575
|
+
throw new PrivatePublicationError("INVALID_SKILL_CREATE_INPUT", "Invalid timeoutMs. Use an integer from 1 to 15000.");
|
|
98576
|
+
const value = await boundedJson(skillsApiRequestUrl(this.apiOrigin, "/api/v1/skills"), { method: "POST", body: JSON.stringify(body4) }, this.#token, true, options.timeoutMs, options.signal, true);
|
|
98577
|
+
if (!record12(value) || !publicationUuid(value.id) || value.slug !== body4.slug || value.displayName !== body4.displayName || value.description !== body4.description || value.visibility !== body4.visibility || value.sourceType !== "private_hosted" || !record12(value.metadata) || value.metadata.ownerOrganizationId !== this.organizationId)
|
|
98578
|
+
throw new PrivatePublicationError("SKILL_CREATE_UNCONFIRMED", "Skill creation returned an unbound result. Inspect the workspace for this slug before another create; do not retry automatically.", true);
|
|
98579
|
+
return Object.freeze({ id: value.id, slug: body4.slug, visibility: body4.visibility, sourceType: "private_hosted", ownerOrganizationId: this.organizationId });
|
|
98580
|
+
}
|
|
98535
98581
|
async getCapability(options = {}) {
|
|
98536
98582
|
if (options.timeoutMs !== undefined && (!Number.isSafeInteger(options.timeoutMs) || options.timeoutMs < 1 || options.timeoutMs > 15000))
|
|
98537
98583
|
return bad();
|