@hasna/skills 0.10.61 → 0.10.62
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/index.js +78 -5
- package/bin/mcp.js +8 -3
- package/bin/migrate.js +8 -3
- package/bin/server.js +8 -3
- package/bin/worker.js +8 -3
- package/dist/cli/commands/runtime-copyfile.d.ts +1 -0
- package/dist/index.js +66 -60
- package/dist/lib/agent-install-selection.d.ts +1 -0
- package/dist/runtime-prerequisites.d.ts +9 -0
- package/dist/runtime-prerequisites.js +3089 -0
- package/dist/sdk/index.js +211 -205
- package/docs/runtime-activation.md +23 -0
- package/package.json +8 -3
package/dist/sdk/index.js
CHANGED
|
@@ -323,13 +323,13 @@ var require_directives = __commonJS((exports) => {
|
|
|
323
323
|
onError(0, "%YAML directive should contain exactly one part");
|
|
324
324
|
return false;
|
|
325
325
|
}
|
|
326
|
-
const [
|
|
327
|
-
if (
|
|
328
|
-
this.yaml.version =
|
|
326
|
+
const [version2] = parts;
|
|
327
|
+
if (version2 === "1.1" || version2 === "1.2") {
|
|
328
|
+
this.yaml.version = version2;
|
|
329
329
|
return true;
|
|
330
330
|
} else {
|
|
331
|
-
const isValid = /^\d+\.\d+$/.test(
|
|
332
|
-
onError(6, `Unsupported YAML version ${
|
|
331
|
+
const isValid = /^\d+\.\d+$/.test(version2);
|
|
332
|
+
onError(6, `Unsupported YAML version ${version2}`, isValid);
|
|
333
333
|
return false;
|
|
334
334
|
}
|
|
335
335
|
}
|
|
@@ -3248,14 +3248,14 @@ var require_Document = __commonJS((exports) => {
|
|
|
3248
3248
|
version: "1.2"
|
|
3249
3249
|
}, options);
|
|
3250
3250
|
this.options = opt;
|
|
3251
|
-
let { version } = opt;
|
|
3251
|
+
let { version: version2 } = opt;
|
|
3252
3252
|
if (options?._directives) {
|
|
3253
3253
|
this.directives = options._directives.atDocument();
|
|
3254
3254
|
if (this.directives.yaml.explicit)
|
|
3255
|
-
|
|
3255
|
+
version2 = this.directives.yaml.version;
|
|
3256
3256
|
} else
|
|
3257
|
-
this.directives = new directives.Directives({ version });
|
|
3258
|
-
this.setSchema(
|
|
3257
|
+
this.directives = new directives.Directives({ version: version2 });
|
|
3258
|
+
this.setSchema(version2, options);
|
|
3259
3259
|
this.contents = value === undefined ? null : this.createNode(value, _replacer, options);
|
|
3260
3260
|
}
|
|
3261
3261
|
clone() {
|
|
@@ -3371,11 +3371,11 @@ var require_Document = __commonJS((exports) => {
|
|
|
3371
3371
|
this.contents.setIn(path, value);
|
|
3372
3372
|
}
|
|
3373
3373
|
}
|
|
3374
|
-
setSchema(
|
|
3375
|
-
if (typeof
|
|
3376
|
-
|
|
3374
|
+
setSchema(version2, options = {}) {
|
|
3375
|
+
if (typeof version2 === "number")
|
|
3376
|
+
version2 = String(version2);
|
|
3377
3377
|
let opt;
|
|
3378
|
-
switch (
|
|
3378
|
+
switch (version2) {
|
|
3379
3379
|
case "1.1":
|
|
3380
3380
|
if (this.directives)
|
|
3381
3381
|
this.directives.yaml.version = "1.1";
|
|
@@ -3386,9 +3386,9 @@ var require_Document = __commonJS((exports) => {
|
|
|
3386
3386
|
case "1.2":
|
|
3387
3387
|
case "next":
|
|
3388
3388
|
if (this.directives)
|
|
3389
|
-
this.directives.yaml.version =
|
|
3389
|
+
this.directives.yaml.version = version2;
|
|
3390
3390
|
else
|
|
3391
|
-
this.directives = new directives.Directives({ version });
|
|
3391
|
+
this.directives = new directives.Directives({ version: version2 });
|
|
3392
3392
|
opt = { resolveKnownTags: true, schema: "core" };
|
|
3393
3393
|
break;
|
|
3394
3394
|
case null:
|
|
@@ -3397,7 +3397,7 @@ var require_Document = __commonJS((exports) => {
|
|
|
3397
3397
|
opt = null;
|
|
3398
3398
|
break;
|
|
3399
3399
|
default: {
|
|
3400
|
-
const sv = JSON.stringify(
|
|
3400
|
+
const sv = JSON.stringify(version2);
|
|
3401
3401
|
throw new Error(`Expected '1.1', '1.2' or null as first argument, but found: ${sv}`);
|
|
3402
3402
|
}
|
|
3403
3403
|
}
|
|
@@ -8727,8 +8727,8 @@ var require_client = __commonJS((exports) => {
|
|
|
8727
8727
|
}
|
|
8728
8728
|
};
|
|
8729
8729
|
var warningEmitted = false;
|
|
8730
|
-
var emitWarningIfUnsupportedVersion = (
|
|
8731
|
-
if (
|
|
8730
|
+
var emitWarningIfUnsupportedVersion = (version2) => {
|
|
8731
|
+
if (version2 && !warningEmitted && parseInt(version2.substring(1, version2.indexOf("."))) < 16) {
|
|
8732
8732
|
warningEmitted = true;
|
|
8733
8733
|
}
|
|
8734
8734
|
};
|
|
@@ -16782,19 +16782,19 @@ var require_client2 = __commonJS((exports) => {
|
|
|
16782
16782
|
var state = {
|
|
16783
16783
|
warningEmitted: false
|
|
16784
16784
|
};
|
|
16785
|
-
var emitWarningIfUnsupportedVersion = (
|
|
16786
|
-
if (
|
|
16785
|
+
var emitWarningIfUnsupportedVersion = (version2) => {
|
|
16786
|
+
if (version2 && !state.warningEmitted) {
|
|
16787
16787
|
if (process.env.AWS_SDK_JS_NODE_VERSION_SUPPORT_WARNING_DISABLED === "true") {
|
|
16788
16788
|
state.warningEmitted = true;
|
|
16789
16789
|
return;
|
|
16790
16790
|
}
|
|
16791
|
-
const userMajorVersion = parseInt(
|
|
16791
|
+
const userMajorVersion = parseInt(version2.substring(1, version2.indexOf(".")));
|
|
16792
16792
|
const vv = 22;
|
|
16793
16793
|
if (userMajorVersion < vv) {
|
|
16794
16794
|
state.warningEmitted = true;
|
|
16795
16795
|
process.emitWarning(`NodeVersionSupportWarning: The AWS SDK for JavaScript (v3)
|
|
16796
16796
|
versions published after the first week of January 2027
|
|
16797
|
-
will require node >=${vv}. You are running node ${
|
|
16797
|
+
will require node >=${vv}. You are running node ${version2}.
|
|
16798
16798
|
|
|
16799
16799
|
To continue receiving updates to AWS services, bug fixes,
|
|
16800
16800
|
and security updates please upgrade to node >=${vv}.
|
|
@@ -17431,14 +17431,14 @@ More information can be found at: https://a.co/c895JFp`);
|
|
|
17431
17431
|
};
|
|
17432
17432
|
var escapeUserAgent = (userAgentPair) => {
|
|
17433
17433
|
const name = userAgentPair[0].split(UA_NAME_SEPARATOR).map((part) => part.replace(UA_NAME_ESCAPE_REGEX, UA_ESCAPE_CHAR)).join(UA_NAME_SEPARATOR);
|
|
17434
|
-
const
|
|
17434
|
+
const version2 = userAgentPair[1]?.replace(UA_VALUE_ESCAPE_REGEX, UA_ESCAPE_CHAR);
|
|
17435
17435
|
const prefixSeparatorIndex = name.indexOf(UA_NAME_SEPARATOR);
|
|
17436
17436
|
const prefix = name.substring(0, prefixSeparatorIndex);
|
|
17437
17437
|
let uaName = name.substring(prefixSeparatorIndex + 1);
|
|
17438
17438
|
if (prefix === "api") {
|
|
17439
17439
|
uaName = uaName.toLowerCase();
|
|
17440
17440
|
}
|
|
17441
|
-
return [prefix, uaName,
|
|
17441
|
+
return [prefix, uaName, version2].filter((item) => item && item.length > 0).reduce((acc, item, index) => {
|
|
17442
17442
|
switch (index) {
|
|
17443
17443
|
case 0:
|
|
17444
17444
|
return item;
|
|
@@ -26111,9 +26111,9 @@ var require_sso_oidc = __commonJS((exports) => {
|
|
|
26111
26111
|
Region: { type: "builtInParams", name: "region" },
|
|
26112
26112
|
UseDualStack: { type: "builtInParams", name: "useDualstackEndpoint" }
|
|
26113
26113
|
};
|
|
26114
|
-
var
|
|
26114
|
+
var version2 = "3.997.43";
|
|
26115
26115
|
var packageInfo = {
|
|
26116
|
-
version
|
|
26116
|
+
version: version2
|
|
26117
26117
|
};
|
|
26118
26118
|
var k2 = "ref";
|
|
26119
26119
|
var a2 = -1;
|
|
@@ -26986,7 +26986,7 @@ var awsEndpointFunctions2, emitWarningIfUnsupportedVersion$1, createDefaultUserA
|
|
|
26986
26986
|
useFipsEndpoint: options.useFipsEndpoint ?? false,
|
|
26987
26987
|
defaultSigningName: "awsssoportal"
|
|
26988
26988
|
});
|
|
26989
|
-
}, commonParams2,
|
|
26989
|
+
}, commonParams2, version2 = "3.997.43", packageInfo, k2 = "ref", a2 = -1, b2 = true, c2 = "isSet", d2 = "PartitionResult", e3 = "booleanEquals", f2 = "getAttr", g2, h2, i2, j2, _data2, root3 = 2, r3 = 1e8, nodes2, bdd2, cache2, defaultEndpointResolver2 = (endpointParams, context = {}) => {
|
|
26990
26990
|
return cache2.get(endpointParams, () => decideEndpoint2(bdd2, {
|
|
26991
26991
|
endpointParams,
|
|
26992
26992
|
logger: context.logger
|
|
@@ -27118,7 +27118,7 @@ var init_sso = __esm(() => {
|
|
|
27118
27118
|
UseDualStack: { type: "builtInParams", name: "useDualstackEndpoint" }
|
|
27119
27119
|
};
|
|
27120
27120
|
packageInfo = {
|
|
27121
|
-
version
|
|
27121
|
+
version: version2
|
|
27122
27122
|
};
|
|
27123
27123
|
g2 = { [k2]: "Endpoint" };
|
|
27124
27124
|
h2 = { [k2]: d2 };
|
|
@@ -27951,9 +27951,9 @@ var require_sts = __commonJS((exports) => {
|
|
|
27951
27951
|
Region: { type: "builtInParams", name: "region" },
|
|
27952
27952
|
UseDualStack: { type: "builtInParams", name: "useDualstackEndpoint" }
|
|
27953
27953
|
};
|
|
27954
|
-
var
|
|
27954
|
+
var version3 = "3.997.43";
|
|
27955
27955
|
var packageInfo2 = {
|
|
27956
|
-
version:
|
|
27956
|
+
version: version3
|
|
27957
27957
|
};
|
|
27958
27958
|
|
|
27959
27959
|
class STSServiceException extends ServiceException2 {
|
|
@@ -28788,9 +28788,9 @@ var require_signin = __commonJS((exports) => {
|
|
|
28788
28788
|
Region: { type: "builtInParams", name: "region" },
|
|
28789
28789
|
UseDualStack: { type: "builtInParams", name: "useDualstackEndpoint" }
|
|
28790
28790
|
};
|
|
28791
|
-
var
|
|
28791
|
+
var version3 = "3.997.43";
|
|
28792
28792
|
var packageInfo2 = {
|
|
28793
|
-
version:
|
|
28793
|
+
version: version3
|
|
28794
28794
|
};
|
|
28795
28795
|
var s2 = "ref";
|
|
28796
28796
|
var a3 = -1;
|
|
@@ -30227,9 +30227,9 @@ var require_sts2 = __commonJS((exports) => {
|
|
|
30227
30227
|
Region: { type: "builtInParams", name: "region" },
|
|
30228
30228
|
UseDualStack: { type: "builtInParams", name: "useDualstackEndpoint" }
|
|
30229
30229
|
};
|
|
30230
|
-
var
|
|
30230
|
+
var version3 = "3.997.43";
|
|
30231
30231
|
var packageInfo2 = {
|
|
30232
|
-
version:
|
|
30232
|
+
version: version3
|
|
30233
30233
|
};
|
|
30234
30234
|
|
|
30235
30235
|
class STSServiceException extends ServiceException2 {
|
|
@@ -31503,14 +31503,14 @@ function signPayload(secret, timestamp, body4) {
|
|
|
31503
31503
|
}
|
|
31504
31504
|
function isPrivateAddress(address) {
|
|
31505
31505
|
const normalized = stripZoneId(address);
|
|
31506
|
-
const
|
|
31507
|
-
if (
|
|
31506
|
+
const version3 = isIP3(normalized);
|
|
31507
|
+
if (version3 === 4) {
|
|
31508
31508
|
const integer = ipv4ToInt(normalized);
|
|
31509
31509
|
if (integer === undefined)
|
|
31510
31510
|
return true;
|
|
31511
31511
|
return IPV4_PRIVATE_RANGES.some(([low, high]) => integer >= low && integer <= high);
|
|
31512
31512
|
}
|
|
31513
|
-
if (
|
|
31513
|
+
if (version3 === 6) {
|
|
31514
31514
|
const groups = ipv6Groups(normalized);
|
|
31515
31515
|
if (!groups)
|
|
31516
31516
|
return true;
|
|
@@ -31550,8 +31550,8 @@ async function resolveWebhookTarget(url, policy = {}) {
|
|
|
31550
31550
|
const addresses = resolved2.map((entry) => normalizeHostname(entry.address));
|
|
31551
31551
|
return { hostname: hostname2, addresses };
|
|
31552
31552
|
}
|
|
31553
|
-
const
|
|
31554
|
-
if (
|
|
31553
|
+
const version3 = isIP3(hostname2);
|
|
31554
|
+
if (version3 === 4 || version3 === 6) {
|
|
31555
31555
|
if (isPrivateAddress(hostname2)) {
|
|
31556
31556
|
throw new Error(`Webhook target ${hostname2} is a private or special-use address`);
|
|
31557
31557
|
}
|
|
@@ -32371,9 +32371,10 @@ var init_event_sink = __esm(() => {
|
|
|
32371
32371
|
init_dist();
|
|
32372
32372
|
});
|
|
32373
32373
|
// package.json
|
|
32374
|
+
var version = "0.10.62";
|
|
32374
32375
|
var package_default = {
|
|
32375
32376
|
name: "@hasna/skills",
|
|
32376
|
-
version
|
|
32377
|
+
version,
|
|
32377
32378
|
description: "Skills library for AI coding agents",
|
|
32378
32379
|
type: "module",
|
|
32379
32380
|
bin: {
|
|
@@ -32414,6 +32415,7 @@ var package_default = {
|
|
|
32414
32415
|
"migrations/",
|
|
32415
32416
|
"docs/skill-standard.md",
|
|
32416
32417
|
"docs/plugin-admission.md",
|
|
32418
|
+
"docs/runtime-activation.md",
|
|
32417
32419
|
"schemas/",
|
|
32418
32420
|
"LICENSE",
|
|
32419
32421
|
"README.md",
|
|
@@ -32424,8 +32426,8 @@ var package_default = {
|
|
|
32424
32426
|
types: "./dist/index.d.ts",
|
|
32425
32427
|
scripts: {
|
|
32426
32428
|
clean: "rm -rf bin/ dist/",
|
|
32427
|
-
build: "bun run clean && bun build --external @hasna/contracts/kernel-lock ./src/cli/index.tsx --outdir ./bin --target bun && bun build --external @modelcontextprotocol/sdk ./src/mcp/index.ts --outfile ./bin/mcp.js --target bun && bun build --external @hasna/contracts/kernel-lock ./src/server/index.ts --outfile ./bin/server.js --target bun && bun build --external @hasna/contracts/kernel-lock ./src/server/worker.ts --outfile ./bin/worker.js --target bun && bun build --external @hasna/contracts/kernel-lock ./src/server/migrate.ts --outfile ./bin/migrate.js --target bun && bun build --external @hasna/contracts/kernel-lock ./src/server/maintenance.ts --outfile ./bin/maintenance.js --target bun && bun build ./src/index.ts ./src/storage.ts ./src/sdk/index.ts ./src/admin-contract.ts --outdir ./dist --target bun && tsc --emitDeclarationOnly --declaration --outDir dist && bun scripts/stage-kernel-lock-assets.ts",
|
|
32428
|
-
"build:js": "rm -rf dist && bun build ./src/index.ts ./src/storage.ts ./src/sdk/index.ts ./src/admin-contract.ts --outdir ./dist --target bun && tsc --emitDeclarationOnly --declaration --outDir dist && bun scripts/stage-kernel-lock-assets.ts",
|
|
32429
|
+
build: "bun run clean && bun build --external @hasna/contracts/kernel-lock ./src/cli/index.tsx --outdir ./bin --target bun && bun build --external @modelcontextprotocol/sdk ./src/mcp/index.ts --outfile ./bin/mcp.js --target bun && bun build --external @hasna/contracts/kernel-lock ./src/server/index.ts --outfile ./bin/server.js --target bun && bun build --external @hasna/contracts/kernel-lock ./src/server/worker.ts --outfile ./bin/worker.js --target bun && bun build --external @hasna/contracts/kernel-lock ./src/server/migrate.ts --outfile ./bin/migrate.js --target bun && bun build --external @hasna/contracts/kernel-lock ./src/server/maintenance.ts --outfile ./bin/maintenance.js --target bun && bun build ./src/index.ts ./src/storage.ts ./src/sdk/index.ts ./src/admin-contract.ts ./src/runtime-prerequisites.ts --outdir ./dist --target bun && tsc --emitDeclarationOnly --declaration --outDir dist && bun scripts/stage-kernel-lock-assets.ts",
|
|
32430
|
+
"build:js": "rm -rf dist && bun build ./src/index.ts ./src/storage.ts ./src/sdk/index.ts ./src/admin-contract.ts ./src/runtime-prerequisites.ts --outdir ./dist --target bun && tsc --emitDeclarationOnly --declaration --outDir dist && bun scripts/stage-kernel-lock-assets.ts",
|
|
32429
32431
|
test: "bun test --timeout 30000",
|
|
32430
32432
|
dev: "bun run ./src/cli/index.tsx",
|
|
32431
32433
|
"dev:watch": "bun --watch run ./src/cli/index.tsx",
|
|
@@ -32502,6 +32504,10 @@ var package_default = {
|
|
|
32502
32504
|
homepage: "https://github.com/hasna/skills/tree/main/apps/skills",
|
|
32503
32505
|
bugs: {
|
|
32504
32506
|
url: "https://github.com/hasna/skills/issues"
|
|
32507
|
+
},
|
|
32508
|
+
skillsRuntimePrerequisites: {
|
|
32509
|
+
version: 1,
|
|
32510
|
+
entry: "dist/runtime-prerequisites.js"
|
|
32505
32511
|
}
|
|
32506
32512
|
};
|
|
32507
32513
|
|
|
@@ -33870,24 +33876,24 @@ class CloudExecutionClient {
|
|
|
33870
33876
|
}
|
|
33871
33877
|
return response;
|
|
33872
33878
|
}
|
|
33873
|
-
async eligibility(slug,
|
|
33874
|
-
if (!/^[a-z0-9-]+$/.test(slug) || !/^\d+\.\d+\.\d+$/.test(
|
|
33879
|
+
async eligibility(slug, version2, bundleDigest) {
|
|
33880
|
+
if (!/^[a-z0-9-]+$/.test(slug) || !/^\d+\.\d+\.\d+$/.test(version2) || bundleDigest !== undefined && !/^(sha256:)?[a-f0-9]{64}$/.test(bundleDigest))
|
|
33875
33881
|
throw Error("Cloud eligibility requires an exact skill version and valid digest");
|
|
33876
|
-
const query = new URLSearchParams({ version, ...bundleDigest ? { bundleDigest } : {} });
|
|
33882
|
+
const query = new URLSearchParams({ version: version2, ...bundleDigest ? { bundleDigest } : {} });
|
|
33877
33883
|
const v = await jsonBody(await this.request(`${slug}/eligibility?${query}`));
|
|
33878
|
-
if (!v || v.contractVersion !== 1 || typeof v.eligible !== "boolean" || v.skill !== slug || v.version !==
|
|
33884
|
+
if (!v || v.contractVersion !== 1 || typeof v.eligible !== "boolean" || v.skill !== slug || v.version !== version2 || !/^[a-f0-9]{64}$/.test(v.bundleDigest) || bundleDigest && bundleDigest.replace(/^sha256:/, "") !== v.bundleDigest || v.eligible && (!v.executionContract || !["pdf.v1", "regex-test.v1"].includes(v.executionContract.id)))
|
|
33879
33885
|
throw Error("Invalid cloud eligibility receipt");
|
|
33880
33886
|
return v;
|
|
33881
33887
|
}
|
|
33882
|
-
async submit(slug,
|
|
33883
|
-
if (!/^[a-z0-9-]+$/.test(slug) || !/^\d+\.\d+\.\d+$/.test(
|
|
33888
|
+
async submit(slug, version2, input, key, selection) {
|
|
33889
|
+
if (!/^[a-z0-9-]+$/.test(slug) || !/^\d+\.\d+\.\d+$/.test(version2))
|
|
33884
33890
|
throw Error("Cloud execution requires skill@exact-version");
|
|
33885
33891
|
if (!/^[A-Za-z0-9._:-]{1,128}$/.test(key))
|
|
33886
33892
|
throw Error("Invalid idempotency key");
|
|
33887
33893
|
if (selection?.authority && selection.authority !== skillsApiRequestUrl(this.apiOrigin, "/api/v1/").replace(/\/$/, ""))
|
|
33888
33894
|
throw Error("Selected skill belongs to another Skills authority");
|
|
33889
33895
|
const execution = parseExecution(await jsonBody(await this.request(slug, "POST", {
|
|
33890
|
-
version,
|
|
33896
|
+
version: version2,
|
|
33891
33897
|
input,
|
|
33892
33898
|
idempotencyKey: key,
|
|
33893
33899
|
...selection ? {
|
|
@@ -33895,7 +33901,7 @@ class CloudExecutionClient {
|
|
|
33895
33901
|
workspaceId: selection.workspaceId
|
|
33896
33902
|
} : {}
|
|
33897
33903
|
})));
|
|
33898
|
-
if (execution.skill !== slug || execution.version !==
|
|
33904
|
+
if (execution.skill !== slug || execution.version !== version2 || selection && execution.bundleDigest.replace(/^sha256:/, "") !== selection.bundleDigest.replace(/^sha256:/, ""))
|
|
33899
33905
|
throw Error("Cloud execution receipt does not match the selected exact skill");
|
|
33900
33906
|
return execution;
|
|
33901
33907
|
}
|
|
@@ -34912,9 +34918,9 @@ function resolvedProfileSnapshot(profile, authority) {
|
|
|
34912
34918
|
};
|
|
34913
34919
|
}
|
|
34914
34920
|
function profileSelectionSnapshot(selections) {
|
|
34915
|
-
return selections.map(({ slug, version, bundleDigest, aliases, triggers }) => ({
|
|
34921
|
+
return selections.map(({ slug, version: version2, bundleDigest, aliases, triggers }) => ({
|
|
34916
34922
|
slug,
|
|
34917
|
-
version,
|
|
34923
|
+
version: version2,
|
|
34918
34924
|
bundleDigest,
|
|
34919
34925
|
...aliases !== undefined ? { aliases } : {},
|
|
34920
34926
|
...triggers !== undefined ? { triggers } : {}
|
|
@@ -35088,8 +35094,8 @@ async function verifySelectionBundleResponse(selection, response, signal, deadli
|
|
|
35088
35094
|
if (!response?.ok)
|
|
35089
35095
|
throw new SkillSelectionError("BUNDLE_UNAVAILABLE", `The selected skill bundle is unavailable${response ? ` (HTTP ${response.status})` : ""}.`);
|
|
35090
35096
|
const declared = response.headers.get("X-Skill-Bundle-Sha256");
|
|
35091
|
-
const
|
|
35092
|
-
if (declared && `sha256:${declared}` !== selection.bundleDigest ||
|
|
35097
|
+
const version2 = response.headers.get("X-Skill-Version");
|
|
35098
|
+
if (declared && `sha256:${declared}` !== selection.bundleDigest || version2 && version2 !== selection.version) {
|
|
35093
35099
|
await response.body?.cancel();
|
|
35094
35100
|
throw new SkillSelectionError("BUNDLE_IDENTITY_MISMATCH", "The returned bundle does not match the selected version and digest.");
|
|
35095
35101
|
}
|
|
@@ -36982,10 +36988,10 @@ function selectedSecretBindingsTemplate(scope, names, createClient = createSecre
|
|
|
36982
36988
|
} catch {
|
|
36983
36989
|
return refuse("LOCAL_SECRET_UNAVAILABLE", "Configure the Secrets CLI authority and authentication before preparing execution bindings.");
|
|
36984
36990
|
}
|
|
36985
|
-
const { authority, workspaceId, profileRevision, slug, version, bundleDigest } = scope.selection;
|
|
36991
|
+
const { authority, workspaceId, profileRevision, slug, version: version2, bundleDigest } = scope.selection;
|
|
36986
36992
|
return {
|
|
36987
36993
|
schema: "hasna.skills-secret-bindings.v1",
|
|
36988
|
-
selection: { authority, workspaceId, profileId: scope.profileId, profileRevision, slug, version, bundleDigest },
|
|
36994
|
+
selection: { authority, workspaceId, profileId: scope.profileId, profileRevision, slug, version: version2, bundleDigest },
|
|
36989
36995
|
consumer: { stationId: process.env.HASNA_STATION || stationHostname(), workspaceDirectory: realpathSync2(scope.cwd) },
|
|
36990
36996
|
secretsAuthority,
|
|
36991
36997
|
bindings: Object.fromEntries(names.map((name) => [name, ""]))
|
|
@@ -37451,10 +37457,10 @@ class HttpProfileClient {
|
|
|
37451
37457
|
invalid2();
|
|
37452
37458
|
return result;
|
|
37453
37459
|
}
|
|
37454
|
-
async getBundle(slug,
|
|
37455
|
-
if (!identifier2(slug) || !/^[A-Za-z0-9][A-Za-z0-9._+-]{0,127}$/.test(
|
|
37460
|
+
async getBundle(slug, version2) {
|
|
37461
|
+
if (!identifier2(slug) || !/^[A-Za-z0-9][A-Za-z0-9._+-]{0,127}$/.test(version2) || version2.includes(".."))
|
|
37456
37462
|
throw new Error("Invalid immutable skill reference");
|
|
37457
|
-
return this.request(`/skills/${encodeURIComponent(slug)}/versions/${encodeURIComponent(
|
|
37463
|
+
return this.request(`/skills/${encodeURIComponent(slug)}/versions/${encodeURIComponent(version2)}/bundle`);
|
|
37458
37464
|
}
|
|
37459
37465
|
}
|
|
37460
37466
|
async function createProfileClient(signal) {
|
|
@@ -38548,7 +38554,7 @@ function assertClaudeHookEventsReplacement(before, replacement, events) {
|
|
|
38548
38554
|
need(JSON.stringify(withoutOwnedEvents(original)) === JSON.stringify(withoutOwnedEvents(next)), `${label} update changed settings outside hooks.${label}`);
|
|
38549
38555
|
}
|
|
38550
38556
|
var PERSISTED_EFFORT_LEVELS = new Set(["low", "medium", "high", "xhigh"]);
|
|
38551
|
-
function inferencePreference(key, child,
|
|
38557
|
+
function inferencePreference(key, child, version2) {
|
|
38552
38558
|
if (key === "skipDangerousModePermissionPrompt") {
|
|
38553
38559
|
need(child.kind === "literal" && (child.value === "true" || child.value === "false"), "contains an invalid dialog acknowledgment");
|
|
38554
38560
|
return false;
|
|
@@ -38561,7 +38567,7 @@ function inferencePreference(key, child, version) {
|
|
|
38561
38567
|
return false;
|
|
38562
38568
|
need(child.kind === "object", "requires an object of model preferences");
|
|
38563
38569
|
child.entries = child.entries.filter(([model, preferences]) => {
|
|
38564
|
-
if (
|
|
38570
|
+
if (version2 === 2 && !BUILTIN_MODEL_SELECTIONS.has(model) || preferences.kind !== "object" || preferences.entries.length !== 1 || preferences.entries[0][0] !== "effortLevel")
|
|
38565
38571
|
return true;
|
|
38566
38572
|
const effort = preferences.entries[0][1];
|
|
38567
38573
|
need(effort.kind === "string" && PERSISTED_EFFORT_LEVELS.has(effort.value), "contains an invalid persisted model effort level");
|
|
@@ -38569,12 +38575,12 @@ function inferencePreference(key, child, version) {
|
|
|
38569
38575
|
});
|
|
38570
38576
|
return child.entries.length === 0;
|
|
38571
38577
|
}
|
|
38572
|
-
function settingsDigest(text,
|
|
38578
|
+
function settingsDigest(text, version2 = 1) {
|
|
38573
38579
|
const value = parse3(text);
|
|
38574
38580
|
value.entries = value.entries.filter(([key, child]) => {
|
|
38575
|
-
if (
|
|
38581
|
+
if (version2 === 4 && key === "theme" && child.kind === "string" && BUILTIN_THEMES.has(child.value))
|
|
38576
38582
|
return false;
|
|
38577
|
-
if (
|
|
38583
|
+
if (version2 !== 1 && inferencePreference(key, child, version2 === 4 ? 3 : version2))
|
|
38578
38584
|
return false;
|
|
38579
38585
|
if (key === "model") {
|
|
38580
38586
|
need(child.kind === "string", "contains an invalid model selection");
|
|
@@ -38590,7 +38596,7 @@ function settingsDigest(text, version = 1) {
|
|
|
38590
38596
|
}
|
|
38591
38597
|
return true;
|
|
38592
38598
|
});
|
|
38593
|
-
return createHash7("sha256").update(`hasna.skills.claude-settings.v${
|
|
38599
|
+
return createHash7("sha256").update(`hasna.skills.claude-settings.v${version2}\x00`).update(JSON.stringify(canonical(value))).digest("hex");
|
|
38594
38600
|
}
|
|
38595
38601
|
function hashClaudeSettingsReplacement(text, budget) {
|
|
38596
38602
|
need(typeof text === "string", "requires settings text");
|
|
@@ -38803,10 +38809,10 @@ var MEASURED_CODEX_CAPABILITIES = {
|
|
|
38803
38809
|
"codex-cli 0.161.0": ["hooks", "qualified-skill-catalog", "installed-plugin-review"],
|
|
38804
38810
|
"codex-cli 0.162.0": ["hooks", "qualified-skill-catalog", "installed-plugin-review"]
|
|
38805
38811
|
};
|
|
38806
|
-
function supportsCodexNativeCapability(
|
|
38807
|
-
return typeof
|
|
38812
|
+
function supportsCodexNativeCapability(version2, capability) {
|
|
38813
|
+
return typeof version2 === "string" && Object.hasOwn(MEASURED_CODEX_CAPABILITIES, version2) && MEASURED_CODEX_CAPABILITIES[version2].includes(capability);
|
|
38808
38814
|
}
|
|
38809
|
-
var SUPPORTED_CODEX_HOOK_VERSIONS = Object.freeze(Object.keys(MEASURED_CODEX_CAPABILITIES).filter((
|
|
38815
|
+
var SUPPORTED_CODEX_HOOK_VERSIONS = Object.freeze(Object.keys(MEASURED_CODEX_CAPABILITIES).filter((version2) => supportsCodexNativeCapability(version2, "hooks")));
|
|
38810
38816
|
|
|
38811
38817
|
// src/lib/codex-native-skill-catalog.ts
|
|
38812
38818
|
import { realpathSync as realpathSync6 } from "fs";
|
|
@@ -38828,14 +38834,14 @@ async function connectCodexHookRpc(options) {
|
|
|
38828
38834
|
const binary = realpathSync5(found), stat = statSync4(binary);
|
|
38829
38835
|
if (!stat.isFile() || (stat.mode & 18) !== 0)
|
|
38830
38836
|
throw new Error("CODEX_HOOK_TRUST_UNSAFE_EXECUTABLE");
|
|
38831
|
-
let
|
|
38837
|
+
let version2;
|
|
38832
38838
|
try {
|
|
38833
38839
|
const output = await promisify(execFile)(binary, ["--version"], { timeout: Math.min(5000, timeoutMs), maxBuffer: 4096 });
|
|
38834
|
-
|
|
38840
|
+
version2 = output.stdout.trim();
|
|
38835
38841
|
} catch {
|
|
38836
38842
|
throw new Error("CODEX_HOOK_TRUST_NATIVE_UNAVAILABLE");
|
|
38837
38843
|
}
|
|
38838
|
-
if (!supportsCodexNativeCapability(
|
|
38844
|
+
if (!supportsCodexNativeCapability(version2, "hooks"))
|
|
38839
38845
|
throw new Error("CODEX_HOOK_TRUST_NATIVE_UNSUPPORTED_VERSION");
|
|
38840
38846
|
const current = statSync4(binary);
|
|
38841
38847
|
if (realpathSync5(found) !== binary || ["dev", "ino", "size", "mtimeMs", "ctimeMs"].some((k) => stat[k] !== current[k]))
|
|
@@ -38915,7 +38921,7 @@ async function connectCodexHookRpc(options) {
|
|
|
38915
38921
|
}
|
|
38916
38922
|
});
|
|
38917
38923
|
const rpc = {
|
|
38918
|
-
version,
|
|
38924
|
+
version: version2,
|
|
38919
38925
|
processId: child.pid,
|
|
38920
38926
|
request(method, params) {
|
|
38921
38927
|
if (stopped)
|
|
@@ -38954,7 +38960,7 @@ async function connectCodexHookRpc(options) {
|
|
|
38954
38960
|
};
|
|
38955
38961
|
try {
|
|
38956
38962
|
const initialized = await rpc.request("initialize", { clientInfo: { name: "skills-native-hook-enrollment", version: "1" }, capabilities: { experimentalApi: true } });
|
|
38957
|
-
const nativeVersion =
|
|
38963
|
+
const nativeVersion = version2.slice("codex-cli ".length);
|
|
38958
38964
|
if (typeof initialized?.userAgent !== "string" || !(initialized.userAgent === `skills-native-hook-enrollment/${nativeVersion}` || initialized.userAgent.startsWith(`skills-native-hook-enrollment/${nativeVersion} `)))
|
|
38959
38965
|
throw new Error("CODEX_HOOK_TRUST_NATIVE_VERSION_MISMATCH");
|
|
38960
38966
|
child.stdin.write(`{"method":"initialized"}
|
|
@@ -40395,7 +40401,7 @@ function canonical3(value, depth = 0, budget2 = { remaining: 65536 }) {
|
|
|
40395
40401
|
need3(isRecord(value));
|
|
40396
40402
|
return ["object", Object.entries(value).sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0).map(([key, child]) => [key, canonical3(child, depth + 1, budget2)])];
|
|
40397
40403
|
}
|
|
40398
|
-
function normalize2(config,
|
|
40404
|
+
function normalize2(config, version2 = 2) {
|
|
40399
40405
|
if (isRecord(config.hooks)) {
|
|
40400
40406
|
delete config.hooks.state;
|
|
40401
40407
|
if (!Object.keys(config.hooks).length)
|
|
@@ -40413,11 +40419,11 @@ function normalize2(config, version = 2) {
|
|
|
40413
40419
|
if (!Object.keys(skills).length)
|
|
40414
40420
|
delete config.skills;
|
|
40415
40421
|
}
|
|
40416
|
-
inference(config,
|
|
40422
|
+
inference(config, version2);
|
|
40417
40423
|
if (isRecord(config.profiles)) {
|
|
40418
40424
|
for (const profile of Object.values(config.profiles))
|
|
40419
40425
|
if (isRecord(profile))
|
|
40420
|
-
inference(profile,
|
|
40426
|
+
inference(profile, version2);
|
|
40421
40427
|
}
|
|
40422
40428
|
}
|
|
40423
40429
|
function disablesOneSkill(entry) {
|
|
@@ -40429,8 +40435,8 @@ function disablesOneSkill(entry) {
|
|
|
40429
40435
|
const selector = ["path", "name"].filter((key) => Object.hasOwn(entry, key));
|
|
40430
40436
|
return selector.length === 1 && typeof entry[selector[0]] === "string" && entry[selector[0]].length > 0;
|
|
40431
40437
|
}
|
|
40432
|
-
function inference(target,
|
|
40433
|
-
const keys2 =
|
|
40438
|
+
function inference(target, version2) {
|
|
40439
|
+
const keys2 = version2 >= 3 ? [...INFERENCE, "service_tier", "plan_mode_reasoning_effort", "personality"] : INFERENCE;
|
|
40434
40440
|
for (const key of keys2)
|
|
40435
40441
|
if (Object.hasOwn(target, key)) {
|
|
40436
40442
|
const value = target[key];
|
|
@@ -40438,7 +40444,7 @@ function inference(target, version) {
|
|
|
40438
40444
|
need3(typeof value === "string" && MODEL.test(value));
|
|
40439
40445
|
else if (key === "personality")
|
|
40440
40446
|
need3(typeof value === "string" && ["none", "friendly", "pragmatic"].includes(value));
|
|
40441
|
-
else if (
|
|
40447
|
+
else if (version2 >= 3 && key !== "model_verbosity") {
|
|
40442
40448
|
need3(typeof value === "string" && value.length <= 128 && !/[\x00-\x1f\x7f]/.test(value));
|
|
40443
40449
|
if (key !== "service_tier")
|
|
40444
40450
|
need3(value.length > 0);
|
|
@@ -40556,7 +40562,7 @@ function projectModelAvailabilityNux(config, text) {
|
|
|
40556
40562
|
}
|
|
40557
40563
|
return { config, numericSource: text };
|
|
40558
40564
|
}
|
|
40559
|
-
function settingsDigest2(text,
|
|
40565
|
+
function settingsDigest2(text, version2 = 2) {
|
|
40560
40566
|
let config;
|
|
40561
40567
|
try {
|
|
40562
40568
|
config = Bun.TOML.parse(text);
|
|
@@ -40564,10 +40570,10 @@ function settingsDigest2(text, version = 2) {
|
|
|
40564
40570
|
throw new Error("Invalid Codex settings witness");
|
|
40565
40571
|
}
|
|
40566
40572
|
need3(isRecord(config));
|
|
40567
|
-
const mcp =
|
|
40568
|
-
const projected =
|
|
40569
|
-
normalize2(projected.config,
|
|
40570
|
-
return sha2(`hasna.skills.codex-settings.v${
|
|
40573
|
+
const mcp = version2 >= 3 ? projectRegularCodexMcp(config, text) : { config, numericSource: text };
|
|
40574
|
+
const projected = version2 === 4 ? projectModelAvailabilityNux(mcp.config, mcp.numericSource) : mcp;
|
|
40575
|
+
normalize2(projected.config, version2);
|
|
40576
|
+
return sha2(`hasna.skills.codex-settings.v${version2}\x00${JSON.stringify([canonical3(projected.config), numericTokens2(projected.numericSource)])}`);
|
|
40571
40577
|
}
|
|
40572
40578
|
function hashCodexSettingsReplacementV2(text, budget2 = { remaining: 256 * 1024 * 1024 }) {
|
|
40573
40579
|
need3(Buffer.byteLength(text) <= 1024 * 1024 && budget2.remaining >= Buffer.byteLength(text));
|
|
@@ -43143,8 +43149,8 @@ class Deadline {
|
|
|
43143
43149
|
async function bundle(selection2, api, deadline) {
|
|
43144
43150
|
const response = await deadline.wait(api.getBundle(selection2.slug, selection2.version));
|
|
43145
43151
|
pluginNeed(response?.ok, "Selected plugin or migrated payload bundle is unavailable");
|
|
43146
|
-
const declared = response.headers.get("X-Skill-Bundle-Sha256"),
|
|
43147
|
-
if (declared && `sha256:${declared}` !== selection2.bundleDigest ||
|
|
43152
|
+
const declared = response.headers.get("X-Skill-Bundle-Sha256"), version2 = response.headers.get("X-Skill-Version");
|
|
43153
|
+
if (declared && `sha256:${declared}` !== selection2.bundleDigest || version2 && version2 !== selection2.version) {
|
|
43148
43154
|
await response.body?.cancel();
|
|
43149
43155
|
pluginRefusal("Selected plugin bundle identity differs from the API response");
|
|
43150
43156
|
}
|
|
@@ -43315,9 +43321,9 @@ function readRegistry(path) {
|
|
|
43315
43321
|
closeSync15(fd);
|
|
43316
43322
|
}
|
|
43317
43323
|
}
|
|
43318
|
-
function nativeVersionMatches(
|
|
43324
|
+
function nativeVersionMatches(version2, receipt) {
|
|
43319
43325
|
const upstream = receipt.plan.manifest.upstream.version;
|
|
43320
|
-
return upstream === null ? /^[a-f0-9]{12}$/.test(
|
|
43326
|
+
return upstream === null ? /^[a-f0-9]{12}$/.test(version2) : version2.startsWith(`${upstream}-`);
|
|
43321
43327
|
}
|
|
43322
43328
|
function hashManagedPluginRegistry(path, managed) {
|
|
43323
43329
|
validateManagedPluginWitnesses(managed);
|
|
@@ -43385,14 +43391,14 @@ function hashManagedPluginRegistry(path, managed) {
|
|
|
43385
43391
|
} finally {
|
|
43386
43392
|
directory.closeSync();
|
|
43387
43393
|
}
|
|
43388
|
-
for (const
|
|
43389
|
-
const files = pluginFileWitnesses(snapshotPluginTree(join25(cacheRoot,
|
|
43394
|
+
for (const version2 of names.sort()) {
|
|
43395
|
+
const files = pluginFileWitnesses(snapshotPluginTree(join25(cacheRoot, version2), { nativeRuntime: `claude-${target.native.version}` }));
|
|
43390
43396
|
verifiedBytes += files.reduce((total, file) => total + file.size, 0);
|
|
43391
43397
|
pluginNeed(verifiedBytes <= 256 * 1024 * 1024, "Managed plugin verification exceeds its aggregate byte budget");
|
|
43392
43398
|
const serialized = JSON.stringify(files);
|
|
43393
|
-
const expected = currentFiles.get(join25(cacheRoot,
|
|
43399
|
+
const expected = currentFiles.get(join25(cacheRoot, version2));
|
|
43394
43400
|
pluginNeed(expected === undefined || serialized === expected, "Current native cache differs from its exact registered producer receipt");
|
|
43395
|
-
pluginNeed([...approvals.values()].some((receipt) => nativeVersionMatches(
|
|
43401
|
+
pluginNeed([...approvals.values()].some((receipt) => nativeVersionMatches(version2, receipt) && JSON.stringify(receipt.plan.files) === serialized), "A retained native plugin cache version differs from every approved projection");
|
|
43396
43402
|
}
|
|
43397
43403
|
for (const row of rows)
|
|
43398
43404
|
pluginNeed(names.includes(row.version), "Managed native plugin installation is missing");
|
|
@@ -43547,9 +43553,9 @@ function textField(value) {
|
|
|
43547
43553
|
need6(value?.kind === "string" && value.value.length > 0 && !/[\x00-\x1f\x7f]/.test(value.value), "contains an invalid recognized field");
|
|
43548
43554
|
return value.value;
|
|
43549
43555
|
}
|
|
43550
|
-
function normalizeRow(row,
|
|
43556
|
+
function normalizeRow(row, version2 = 1) {
|
|
43551
43557
|
if (!exactKeys2(row, ["source", "installLocation", "lastUpdated"])) {
|
|
43552
|
-
if (
|
|
43558
|
+
if (version2 !== 2 || !exactKeys2(row, ["source", "installLocation", "lastUpdated", "autoUpdate"]))
|
|
43553
43559
|
return;
|
|
43554
43560
|
const autoUpdate = field2(row, "autoUpdate");
|
|
43555
43561
|
need6(autoUpdate?.kind === "literal" && (autoUpdate.value === "true" || autoUpdate.value === "false"), "contains an invalid automatic-update preference");
|
|
@@ -47593,7 +47599,7 @@ function readManifest(skillPath, fallbackName, normalizeName) {
|
|
|
47593
47599
|
const pkg = existsSync9(pkgPath) ? readJsonObject(pkgPath) : undefined;
|
|
47594
47600
|
const name = normalizeName(stringField(jsonManifest, "name") ?? frontmatter?.name ?? stringValue(pkg?.name) ?? fallbackName);
|
|
47595
47601
|
const description = stringField(jsonManifest, "description") ?? frontmatter?.description ?? stringValue(pkg?.description) ?? `${name} skill`;
|
|
47596
|
-
const
|
|
47602
|
+
const version2 = readDeclaredSkillVersion(skillPath) ?? PORTABLE_SKILL_DEFAULT_VERSION;
|
|
47597
47603
|
const kind = parseSkillKind(stringField(jsonManifest, "kind") ?? frontmatter?.kind);
|
|
47598
47604
|
const commands = parseManifestCommands(jsonManifest) ?? (kind === "instruction" ? [] : inferPackageCommands(pkg, name)) ?? [];
|
|
47599
47605
|
const runtime = parseManifestRuntime(jsonManifest) ?? inferRuntimeFromCommands(commands);
|
|
@@ -47602,7 +47608,7 @@ function readManifest(skillPath, fallbackName, normalizeName) {
|
|
|
47602
47608
|
standard: stringField(jsonManifest, "standard") ?? PORTABLE_SKILL_STANDARD,
|
|
47603
47609
|
name,
|
|
47604
47610
|
description,
|
|
47605
|
-
version,
|
|
47611
|
+
version: version2,
|
|
47606
47612
|
displayName: stringField(jsonManifest, "displayName") ?? frontmatter?.displayName ?? displayName(name),
|
|
47607
47613
|
category: stringField(jsonManifest, "category") ?? frontmatter?.category ?? "Development Tools",
|
|
47608
47614
|
tags: stringArrayField(jsonManifest, "tags") ?? frontmatter?.tags ?? ["custom"],
|
|
@@ -49572,8 +49578,8 @@ function installSkill(name, options = {}) {
|
|
|
49572
49578
|
};
|
|
49573
49579
|
}
|
|
49574
49580
|
const meta = getSkill(canonicalName);
|
|
49575
|
-
const
|
|
49576
|
-
pinProjectSkill(skillName, { version, source: meta?.source ?? "official" }, targetDir);
|
|
49581
|
+
const version2 = readBundledSkillVersion(name);
|
|
49582
|
+
pinProjectSkill(skillName, { version: version2, source: meta?.source ?? "official" }, targetDir);
|
|
49577
49583
|
warnMissingDependencies(canonicalName, targetDir);
|
|
49578
49584
|
return { skill: canonicalName, success: true, path: getProjectConfigPath(targetDir), mode: "pin", source: meta?.source ?? "official" };
|
|
49579
49585
|
}
|
|
@@ -50259,9 +50265,9 @@ function exactProfileSelection(spec, profile) {
|
|
|
50259
50265
|
validateResolvedProfile(profile);
|
|
50260
50266
|
const at = spec.lastIndexOf("@");
|
|
50261
50267
|
const slug = at > 0 ? spec.slice(0, at) : spec;
|
|
50262
|
-
const
|
|
50263
|
-
const selection2 = profile.selections.find((entry) => (entry.slug === slug || entry.aliases?.includes(slug)) && (
|
|
50264
|
-
if (!selection2 ||
|
|
50268
|
+
const version2 = at > 0 ? spec.slice(at + 1) : undefined;
|
|
50269
|
+
const selection2 = profile.selections.find((entry) => (entry.slug === slug || entry.aliases?.includes(slug)) && (version2 === undefined || version2 === entry.version));
|
|
50270
|
+
if (!selection2 || version2 === "")
|
|
50265
50271
|
throw new SkillSelectionError("SKILL_NOT_SELECTED", "The requested exact skill version is not selected by this profile or project lock.");
|
|
50266
50272
|
return selection2;
|
|
50267
50273
|
}
|
|
@@ -50361,16 +50367,16 @@ async function executeSelectedLocal(selected, options = {}) {
|
|
|
50361
50367
|
env.SKILLS_WORKSPACE_DIR = resolve24(options.cwd ?? process.cwd());
|
|
50362
50368
|
env.SKILLS_RUN_DIR = runDirectory;
|
|
50363
50369
|
if (runtime.version) {
|
|
50364
|
-
const
|
|
50365
|
-
const actual =
|
|
50366
|
-
if (
|
|
50370
|
+
const version2 = await subprocess([executable2, ...runtimeName === "bun" ? ["--no-env-file"] : [], "--version"], runDirectory, env, "", Math.min(timeoutMs, 5000));
|
|
50371
|
+
const actual = version2.stdout.trim().replace(/^v/, "").replace(/^Python /, "");
|
|
50372
|
+
if (version2.exitCode !== 0 || actual !== runtime.version)
|
|
50367
50373
|
throw new SkillSelectionError("LOCAL_RUNTIME_VERSION_MISMATCH", "The installed runtime version differs from the version selected by the skill.");
|
|
50368
50374
|
}
|
|
50369
50375
|
let executionGrant;
|
|
50370
50376
|
if (shared) {
|
|
50371
|
-
const { authority: authority2, workspaceId, profileRevision, slug, version, bundleDigest } = selection2;
|
|
50377
|
+
const { authority: authority2, workspaceId, profileRevision, slug, version: version2, bundleDigest } = selection2;
|
|
50372
50378
|
const request2 = {
|
|
50373
|
-
selection: { authority: authority2, workspaceId, profileId, profileRevision, slug, version, bundleDigest },
|
|
50379
|
+
selection: { authority: authority2, workspaceId, profileId, profileRevision, slug, version: version2, bundleDigest },
|
|
50374
50380
|
consumer: { stationId: process.env.HASNA_STATION || stationHostname2(), workspaceDirectory: realpathSync16(options.cwd ?? process.cwd()) }
|
|
50375
50381
|
};
|
|
50376
50382
|
const grant = await (options.resolveExecutionGrant ?? resolveExecutionGrant)(request2);
|
|
@@ -60216,26 +60222,26 @@ class ArtifactStorage {
|
|
|
60216
60222
|
keyFor(run, relativePath) {
|
|
60217
60223
|
return this.objectKeyFor(run.orgId, run.id, relativePath);
|
|
60218
60224
|
}
|
|
60219
|
-
async putVersionObjects(orgId, slug,
|
|
60225
|
+
async putVersionObjects(orgId, slug, version3, bytes, manifest, contentType = "application/gzip") {
|
|
60220
60226
|
if (!this.bucket || !this.s3)
|
|
60221
60227
|
return { storageKind: "db" };
|
|
60222
|
-
const key = this.versionKeyFor(orgId, slug,
|
|
60228
|
+
const key = this.versionKeyFor(orgId, slug, version3, "bundle.tar.gz");
|
|
60223
60229
|
await this.s3.send(new PutObjectCommand({ Bucket: this.bucket, Key: key, Body: bytes, ContentType: contentType }));
|
|
60224
60230
|
await this.s3.send(new PutObjectCommand({
|
|
60225
60231
|
Bucket: this.bucket,
|
|
60226
|
-
Key: this.versionKeyFor(orgId, slug,
|
|
60232
|
+
Key: this.versionKeyFor(orgId, slug, version3, "manifest.json"),
|
|
60227
60233
|
Body: new TextEncoder().encode(JSON.stringify(manifest, null, 2)),
|
|
60228
60234
|
ContentType: "application/json"
|
|
60229
60235
|
}));
|
|
60230
60236
|
return { storageKind: "s3", storageKey: key };
|
|
60231
60237
|
}
|
|
60232
|
-
versionPlacement(orgId, slug,
|
|
60238
|
+
versionPlacement(orgId, slug, version3) {
|
|
60233
60239
|
if (!this.bucket || !this.s3)
|
|
60234
60240
|
return { storageKind: "db" };
|
|
60235
|
-
return { storageKind: "s3", storageKey: this.versionKeyFor(orgId, slug,
|
|
60241
|
+
return { storageKind: "s3", storageKey: this.versionKeyFor(orgId, slug, version3, "bundle.tar.gz") };
|
|
60236
60242
|
}
|
|
60237
|
-
versionKeyFor(orgId, slug,
|
|
60238
|
-
return `${this.prefix}/skills/${encodeURIComponent(orgId)}/${encodeURIComponent(slug)}/${encodeURIComponent(
|
|
60243
|
+
versionKeyFor(orgId, slug, version3, file) {
|
|
60244
|
+
return `${this.prefix}/skills/${encodeURIComponent(orgId)}/${encodeURIComponent(slug)}/${encodeURIComponent(version3)}/${file}`;
|
|
60239
60245
|
}
|
|
60240
60246
|
bundleKeyFor(orgId, sha2563) {
|
|
60241
60247
|
return `${this.prefix}/bundles/${encodeURIComponent(orgId)}/${sha2563}.tar.gz`;
|
|
@@ -61055,10 +61061,10 @@ class SkillVersionExistsError extends Error {
|
|
|
61055
61061
|
version;
|
|
61056
61062
|
existingSha256;
|
|
61057
61063
|
attemptedSha256;
|
|
61058
|
-
constructor(slug,
|
|
61059
|
-
super(`version conflict for '${slug}@${
|
|
61064
|
+
constructor(slug, version3, existingSha256, attemptedSha256) {
|
|
61065
|
+
super(`version conflict for '${slug}@${version3}': already published with bundle ${existingSha256}, ` + `refusing to overwrite it with ${attemptedSha256}. Publish a new version instead.`);
|
|
61060
61066
|
this.slug = slug;
|
|
61061
|
-
this.version =
|
|
61067
|
+
this.version = version3;
|
|
61062
61068
|
this.existingSha256 = existingSha256;
|
|
61063
61069
|
this.attemptedSha256 = attemptedSha256;
|
|
61064
61070
|
this.name = "SkillVersionExistsError";
|
|
@@ -61719,8 +61725,8 @@ class SqliteSkillsStore {
|
|
|
61719
61725
|
async listSkillVersions(principal, slug) {
|
|
61720
61726
|
return this.all("SELECT * FROM skills_versions WHERE org_id = ? AND slug = ? ORDER BY created_at DESC, version DESC", [principal.orgId, slug]).map(rowToSkillVersion);
|
|
61721
61727
|
}
|
|
61722
|
-
async getSkillVersion(principal, slug,
|
|
61723
|
-
const row = this.get("SELECT * FROM skills_versions WHERE org_id = ? AND slug = ? AND version = ? LIMIT 1", [principal.orgId, slug,
|
|
61728
|
+
async getSkillVersion(principal, slug, version3) {
|
|
61729
|
+
const row = this.get("SELECT * FROM skills_versions WHERE org_id = ? AND slug = ? AND version = ? LIMIT 1", [principal.orgId, slug, version3]);
|
|
61724
61730
|
return row ? rowToSkillVersion(row) : null;
|
|
61725
61731
|
}
|
|
61726
61732
|
async getPublishedSelectionStates(principal, selections2) {
|
|
@@ -61728,7 +61734,7 @@ class SqliteSkillsStore {
|
|
|
61728
61734
|
throw new RangeError("Published selection lookup exceeds the profile selection limit");
|
|
61729
61735
|
if (!selections2.length)
|
|
61730
61736
|
return [];
|
|
61731
|
-
const requested = JSON.stringify(selections2.map(({ slug, version:
|
|
61737
|
+
const requested = JSON.stringify(selections2.map(({ slug, version: version3 }) => ({ slug, version: version3 })));
|
|
61732
61738
|
return this.all(`SELECT json_extract(q.value, '$.slug') AS slug, json_extract(q.value, '$.version') AS version,
|
|
61733
61739
|
r.slug IS NOT NULL AS skill_exists, r.lifecycle, r.tombstoned_at, r.authorization_epoch,
|
|
61734
61740
|
v.bundle_sha256, b.sha256 IS NOT NULL AS bundle_available
|
|
@@ -61806,18 +61812,18 @@ function applySqliteMigrations(db, migrationsDir = resolveMigrationsDir("sqlite"
|
|
|
61806
61812
|
}
|
|
61807
61813
|
const appliedNow = [];
|
|
61808
61814
|
for (const file of files) {
|
|
61809
|
-
const
|
|
61815
|
+
const version3 = file.replace(/\.sql$/, "");
|
|
61810
61816
|
const text2 = readFileSync27(join42(migrationsDir, file), "utf8");
|
|
61811
61817
|
const apply = db.transaction(() => {
|
|
61812
|
-
const already = db.query("SELECT 1 AS present FROM schema_migrations WHERE version = ? LIMIT 1").get(
|
|
61818
|
+
const already = db.query("SELECT 1 AS present FROM schema_migrations WHERE version = ? LIMIT 1").get(version3);
|
|
61813
61819
|
if (already)
|
|
61814
61820
|
return false;
|
|
61815
61821
|
db.exec(text2);
|
|
61816
|
-
db.run("INSERT INTO schema_migrations (version) VALUES (?)", [
|
|
61822
|
+
db.run("INSERT INTO schema_migrations (version) VALUES (?)", [version3]);
|
|
61817
61823
|
return true;
|
|
61818
61824
|
});
|
|
61819
61825
|
if (apply.immediate())
|
|
61820
|
-
appliedNow.push(
|
|
61826
|
+
appliedNow.push(version3);
|
|
61821
61827
|
}
|
|
61822
61828
|
return appliedNow;
|
|
61823
61829
|
}
|
|
@@ -62589,18 +62595,18 @@ function byteLength(value) {
|
|
|
62589
62595
|
function titleize(name) {
|
|
62590
62596
|
return name.replace(/[-_]+/g, " ").replace(/\b\w/g, (char) => char.toUpperCase());
|
|
62591
62597
|
}
|
|
62592
|
-
function skillVersionPayload(
|
|
62598
|
+
function skillVersionPayload(version3, currentSha) {
|
|
62593
62599
|
return {
|
|
62594
|
-
slug:
|
|
62595
|
-
version:
|
|
62596
|
-
bundleSha256:
|
|
62597
|
-
bundleByteSize:
|
|
62598
|
-
storageKind:
|
|
62599
|
-
...
|
|
62600
|
-
manifest:
|
|
62601
|
-
...
|
|
62602
|
-
createdAt:
|
|
62603
|
-
current: currentSha !== undefined && currentSha ===
|
|
62600
|
+
slug: version3.slug,
|
|
62601
|
+
version: version3.version,
|
|
62602
|
+
bundleSha256: version3.bundleSha256,
|
|
62603
|
+
bundleByteSize: version3.bundleByteSize,
|
|
62604
|
+
storageKind: version3.storageKind,
|
|
62605
|
+
...version3.storageKey ? { storageKey: version3.storageKey } : {},
|
|
62606
|
+
manifest: version3.manifest,
|
|
62607
|
+
...version3.publishedByUserId ? { publishedByUserId: version3.publishedByUserId } : {},
|
|
62608
|
+
createdAt: version3.createdAt,
|
|
62609
|
+
current: currentSha !== undefined && currentSha === version3.bundleSha256
|
|
62604
62610
|
};
|
|
62605
62611
|
}
|
|
62606
62612
|
async function listSkillVersionsPayload(store, principal, slug) {
|
|
@@ -62614,21 +62620,21 @@ async function listSkillVersionsPayload(store, principal, slug) {
|
|
|
62614
62620
|
slug,
|
|
62615
62621
|
...record4?.version ? { currentVersion: record4.version } : {},
|
|
62616
62622
|
...currentSha ? { currentBundleSha256: currentSha } : {},
|
|
62617
|
-
versions: versions.map((
|
|
62623
|
+
versions: versions.map((version3) => skillVersionPayload(version3, currentSha))
|
|
62618
62624
|
};
|
|
62619
62625
|
}
|
|
62620
|
-
async function readSkillVersion(store, principal, slug,
|
|
62626
|
+
async function readSkillVersion(store, principal, slug, version3) {
|
|
62621
62627
|
assertPublishableSlug(slug);
|
|
62622
|
-
if (!isValidSkillVersion(
|
|
62623
|
-
throw new SkillRequestError(400, "INVALID_VERSION", `version '${
|
|
62628
|
+
if (!isValidSkillVersion(version3)) {
|
|
62629
|
+
throw new SkillRequestError(400, "INVALID_VERSION", `version '${version3.slice(0, 40)}' is not a valid skill version (${SKILL_VERSION_RULE})`);
|
|
62624
62630
|
}
|
|
62625
|
-
const found = await store.getSkillVersion(principal, slug,
|
|
62631
|
+
const found = await store.getSkillVersion(principal, slug, version3);
|
|
62626
62632
|
if (!found)
|
|
62627
|
-
throw new SkillRequestError(404, "SKILL_VERSION_NOT_FOUND", `no published version '${
|
|
62633
|
+
throw new SkillRequestError(404, "SKILL_VERSION_NOT_FOUND", `no published version '${version3}' of '${slug}'`);
|
|
62628
62634
|
return found;
|
|
62629
62635
|
}
|
|
62630
|
-
async function readSkillVersionBundle(store, artifactStorage, principal, slug,
|
|
62631
|
-
const found = await readSkillVersion(store, principal, slug,
|
|
62636
|
+
async function readSkillVersionBundle(store, artifactStorage, principal, slug, version3) {
|
|
62637
|
+
const found = await readSkillVersion(store, principal, slug, version3);
|
|
62632
62638
|
const resolved = await resolvePublishedSkill(store, artifactStorage, principal, slug);
|
|
62633
62639
|
if (resolved.kind === "tombstone")
|
|
62634
62640
|
throw new SkillRequestError(410, "SKILL_DELETED", `'${slug}' was deleted; its version bundles are withheld while the slug is deleted`);
|
|
@@ -62642,18 +62648,18 @@ async function readSkillVersionBundle(store, artifactStorage, principal, slug, v
|
|
|
62642
62648
|
throw new SkillRequestError(503, "BUNDLE_BACKEND_UNAVAILABLE", "bundle storage backend unavailable");
|
|
62643
62649
|
const actual = createHash33("sha256").update(bytes).digest("hex");
|
|
62644
62650
|
if (actual !== found.bundleSha256) {
|
|
62645
|
-
throw new SkillRequestError(500, "BUNDLE_DIGEST_DRIFT", `stored bundle for '${slug}@${
|
|
62651
|
+
throw new SkillRequestError(500, "BUNDLE_DIGEST_DRIFT", `stored bundle for '${slug}@${version3}' hashes to ${actual} but was published as ${found.bundleSha256}`);
|
|
62646
62652
|
}
|
|
62647
62653
|
return { version: found, bytes, authorizationEpoch: resolved.record.authorizationEpoch };
|
|
62648
62654
|
}
|
|
62649
62655
|
function publishVersionOf(manifest) {
|
|
62650
|
-
const
|
|
62651
|
-
if (
|
|
62656
|
+
const version3 = optionalString(manifest.version);
|
|
62657
|
+
if (version3 === undefined)
|
|
62652
62658
|
return;
|
|
62653
|
-
if (!isValidSkillVersion(
|
|
62654
|
-
throw new SkillRequestError(400, "INVALID_VERSION", `version '${
|
|
62659
|
+
if (!isValidSkillVersion(version3)) {
|
|
62660
|
+
throw new SkillRequestError(400, "INVALID_VERSION", `version '${version3.slice(0, 40)}' is not a valid skill version (${SKILL_VERSION_RULE})`);
|
|
62655
62661
|
}
|
|
62656
|
-
return
|
|
62662
|
+
return version3;
|
|
62657
62663
|
}
|
|
62658
62664
|
|
|
62659
62665
|
// src/server/execution-grants-api.ts
|
|
@@ -68031,8 +68037,8 @@ function publicJob(job) {
|
|
|
68031
68037
|
artifacts: (job.result?.artifacts ?? []).map(({ base64, ...meta }) => meta)
|
|
68032
68038
|
};
|
|
68033
68039
|
}
|
|
68034
|
-
function findReview(service, tenant, slug,
|
|
68035
|
-
return service.config.reviewedBundles.find((b4) => b4.slug === slug && b4.version ===
|
|
68040
|
+
function findReview(service, tenant, slug, version3, sha2563) {
|
|
68041
|
+
return service.config.reviewedBundles.find((b4) => b4.slug === slug && b4.version === version3 && b4.sha256 === sha2563 && (!b4.executionContract || b4.tenantId === tenant && b4.imageDigest === service.config.imageDigest));
|
|
68036
68042
|
}
|
|
68037
68043
|
function sameContract(admission, contract, image) {
|
|
68038
68044
|
return digestInput(admission.executionContract ?? null) === digestInput(contract ?? null) && (!contract || admission.runtimeImageDigest === image);
|
|
@@ -68078,13 +68084,13 @@ async function handleRuntimeApiRequest(request2, principal, service) {
|
|
|
68078
68084
|
const skill = await service.productStore.getSkill(principal, id2);
|
|
68079
68085
|
if (skill?.lifecycle === "archived")
|
|
68080
68086
|
return refusal2("SKILL_ARCHIVED", 410);
|
|
68081
|
-
const
|
|
68082
|
-
if (!
|
|
68087
|
+
const version3 = skill && !skill.tombstonedAt && await service.productStore.getSkillVersion(principal, id2, versionName);
|
|
68088
|
+
if (!version3)
|
|
68083
68089
|
return refusal2("SKILL_VERSION_NOT_FOUND", 404);
|
|
68084
68090
|
const pinned = query.get("bundleDigest");
|
|
68085
|
-
if (pinned && pinned.replace(/^sha256:/, "") !==
|
|
68091
|
+
if (pinned && pinned.replace(/^sha256:/, "") !== version3.bundleSha256)
|
|
68086
68092
|
return refusal2("SELECTION_DIGEST_MISMATCH", 409);
|
|
68087
|
-
const review = findReview(service, principal.orgId, id2, versionName,
|
|
68093
|
+
const review = findReview(service, principal.orgId, id2, versionName, version3.bundleSha256);
|
|
68088
68094
|
if (!review)
|
|
68089
68095
|
return json3({
|
|
68090
68096
|
contractVersion: 1,
|
|
@@ -68092,10 +68098,10 @@ async function handleRuntimeApiRequest(request2, principal, service) {
|
|
|
68092
68098
|
reason: "BUNDLE_NOT_REVIEWED_FOR_CLOUD",
|
|
68093
68099
|
skill: id2,
|
|
68094
68100
|
version: versionName,
|
|
68095
|
-
bundleDigest:
|
|
68101
|
+
bundleDigest: version3.bundleSha256
|
|
68096
68102
|
});
|
|
68097
68103
|
if (review.executionContract) {
|
|
68098
|
-
const bytes = await reviewedBytes(service, principal,
|
|
68104
|
+
const bytes = await reviewedBytes(service, principal, version3.bundleSha256);
|
|
68099
68105
|
await inspectPureBundle(bytes, review.executionContract);
|
|
68100
68106
|
}
|
|
68101
68107
|
return json3({
|
|
@@ -68103,7 +68109,7 @@ async function handleRuntimeApiRequest(request2, principal, service) {
|
|
|
68103
68109
|
eligible: true,
|
|
68104
68110
|
skill: id2,
|
|
68105
68111
|
version: versionName,
|
|
68106
|
-
bundleDigest:
|
|
68112
|
+
bundleDigest: version3.bundleSha256,
|
|
68107
68113
|
runtimeImageDigest: service.config.imageDigest,
|
|
68108
68114
|
executionContract: review.executionContract ?? { id: "pdf.v1" },
|
|
68109
68115
|
secrets: "none",
|
|
@@ -68133,12 +68139,12 @@ async function handleRuntimeApiRequest(request2, principal, service) {
|
|
|
68133
68139
|
return refusal2("SKILL_NOT_FOUND", 404);
|
|
68134
68140
|
if (skill.lifecycle === "archived")
|
|
68135
68141
|
return refusal2("SKILL_ARCHIVED", 410);
|
|
68136
|
-
const
|
|
68137
|
-
if (!
|
|
68142
|
+
const version3 = await service.productStore.getSkillVersion(principal, id2, raw.version);
|
|
68143
|
+
if (!version3)
|
|
68138
68144
|
return refusal2("SKILL_VERSION_NOT_FOUND", 404);
|
|
68139
|
-
if (raw.bundleDigest !== undefined && (typeof raw.bundleDigest !== "string" || raw.bundleDigest.replace(/^sha256:/, "") !==
|
|
68145
|
+
if (raw.bundleDigest !== undefined && (typeof raw.bundleDigest !== "string" || raw.bundleDigest.replace(/^sha256:/, "") !== version3.bundleSha256))
|
|
68140
68146
|
return refusal2("SELECTION_DIGEST_MISMATCH", 409);
|
|
68141
|
-
const review = findReview(service, principal.orgId, id2, raw.version,
|
|
68147
|
+
const review = findReview(service, principal.orgId, id2, raw.version, version3.bundleSha256);
|
|
68142
68148
|
if (!review)
|
|
68143
68149
|
return refusal2("BUNDLE_NOT_REVIEWED_FOR_CLOUD", 403);
|
|
68144
68150
|
const contract = review.executionContract;
|
|
@@ -68146,9 +68152,9 @@ async function handleRuntimeApiRequest(request2, principal, service) {
|
|
|
68146
68152
|
return refusal2("PURE_SELECTION_REQUIRED", 400);
|
|
68147
68153
|
const input = contract ? pureInput(raw.input) : runtimeInput(raw.input);
|
|
68148
68154
|
const existing = await service.store.getRunByKey(principal.orgId, key);
|
|
68149
|
-
if (existing && (existing.admission.skillId !== id2 || existing.admission.skillVersion !== raw.version || existing.admission.bundleDigest !==
|
|
68155
|
+
if (existing && (existing.admission.skillId !== id2 || existing.admission.skillVersion !== raw.version || existing.admission.bundleDigest !== version3.bundleSha256 || existing.admission.inputDigest !== digestInput(input) || !sameContract(existing.admission, contract, service.config.imageDigest)))
|
|
68150
68156
|
return refusal2("IDEMPOTENCY_CONFLICT", 409);
|
|
68151
|
-
const bytes = await reviewedBytes(service, principal,
|
|
68157
|
+
const bytes = await reviewedBytes(service, principal, version3.bundleSha256);
|
|
68152
68158
|
if (contract)
|
|
68153
68159
|
await inspectPureBundle(bytes, contract);
|
|
68154
68160
|
const admission = createSubmitRunService({
|
|
@@ -68168,7 +68174,7 @@ async function handleRuntimeApiRequest(request2, principal, service) {
|
|
|
68168
68174
|
tenantId: principal.orgId,
|
|
68169
68175
|
skillId: id2,
|
|
68170
68176
|
skillVersion: raw.version,
|
|
68171
|
-
bundleDigest:
|
|
68177
|
+
bundleDigest: version3.bundleSha256,
|
|
68172
68178
|
input,
|
|
68173
68179
|
idempotencyKey: key,
|
|
68174
68180
|
runtime: "bun",
|
|
@@ -68178,7 +68184,7 @@ async function handleRuntimeApiRequest(request2, principal, service) {
|
|
|
68178
68184
|
maxArtifactsBytes: RUNTIME_MAX_ARTIFACT_BYTES
|
|
68179
68185
|
}
|
|
68180
68186
|
});
|
|
68181
|
-
if (run.tenantId !== principal.orgId || run.skillId !== id2 || run.skillVersion !== raw.version || run.bundleDigest !==
|
|
68187
|
+
if (run.tenantId !== principal.orgId || run.skillId !== id2 || run.skillVersion !== raw.version || run.bundleDigest !== version3.bundleSha256 || run.inputDigest !== digestInput(input) || !sameContract(run, contract, service.config.imageDigest))
|
|
68182
68188
|
return refusal2("IDEMPOTENCY_CONFLICT", 409);
|
|
68183
68189
|
await service.store.mutate(run.runId, (j4) => {
|
|
68184
68190
|
if (!j4.input) {
|
|
@@ -68776,20 +68782,20 @@ class MemorySkillsStore {
|
|
|
68776
68782
|
async listSkillVersions(principal, slug) {
|
|
68777
68783
|
return Array.from(this.versions.values()).filter((v2) => v2.orgId === principal.orgId && v2.slug === slug).sort((a4, b4) => b4.createdAt.localeCompare(a4.createdAt) || b4.version.localeCompare(a4.version));
|
|
68778
68784
|
}
|
|
68779
|
-
async getSkillVersion(principal, slug,
|
|
68780
|
-
const found = this.versions.get(versionKey(principal.orgId, slug,
|
|
68785
|
+
async getSkillVersion(principal, slug, version3) {
|
|
68786
|
+
const found = this.versions.get(versionKey(principal.orgId, slug, version3));
|
|
68781
68787
|
return found && found.orgId === principal.orgId ? found : null;
|
|
68782
68788
|
}
|
|
68783
68789
|
async getPublishedSelectionStates(principal, selections2) {
|
|
68784
68790
|
if (selections2.length > MAX_PROFILE_SELECTIONS)
|
|
68785
68791
|
throw new RangeError("Published selection lookup exceeds the profile selection limit");
|
|
68786
|
-
return selections2.map(({ slug, version:
|
|
68792
|
+
return selections2.map(({ slug, version: version3 }) => {
|
|
68787
68793
|
const current = this.skills.get(skillKey(principal.orgId, slug));
|
|
68788
|
-
const selectedVersion = this.versions.get(versionKey(principal.orgId, slug,
|
|
68794
|
+
const selectedVersion = this.versions.get(versionKey(principal.orgId, slug, version3));
|
|
68789
68795
|
const bundle2 = selectedVersion && this.bundles.get(skillKey(principal.orgId, selectedVersion.bundleSha256));
|
|
68790
68796
|
return {
|
|
68791
68797
|
slug,
|
|
68792
|
-
version:
|
|
68798
|
+
version: version3,
|
|
68793
68799
|
current: current?.orgId === principal.orgId ? {
|
|
68794
68800
|
authorizationEpoch: current.authorizationEpoch,
|
|
68795
68801
|
lifecycle: current.lifecycle,
|
|
@@ -68950,8 +68956,8 @@ function skillKey(orgId, slug) {
|
|
|
68950
68956
|
function pinKey(orgId, principal, slug) {
|
|
68951
68957
|
return `${orgId.length}:${orgId}:${principal.length}:${principal}:${slug}`;
|
|
68952
68958
|
}
|
|
68953
|
-
function versionKey(orgId, slug,
|
|
68954
|
-
return `${orgId.length}:${orgId}:${slug.length}:${slug}:${
|
|
68959
|
+
function versionKey(orgId, slug, version3) {
|
|
68960
|
+
return `${orgId.length}:${orgId}:${slug.length}:${slug}:${version3}`;
|
|
68955
68961
|
}
|
|
68956
68962
|
|
|
68957
68963
|
class PostgresSkillsStore {
|
|
@@ -69605,9 +69611,9 @@ class PostgresSkillsStore {
|
|
|
69605
69611
|
`;
|
|
69606
69612
|
return rows.map((row) => rowToSkillVersion(row));
|
|
69607
69613
|
}
|
|
69608
|
-
async getSkillVersion(principal, slug,
|
|
69614
|
+
async getSkillVersion(principal, slug, version3) {
|
|
69609
69615
|
const rows = await this.sql`
|
|
69610
|
-
SELECT * FROM skills_versions WHERE org_id = ${principal.orgId} AND slug = ${slug} AND version = ${
|
|
69616
|
+
SELECT * FROM skills_versions WHERE org_id = ${principal.orgId} AND slug = ${slug} AND version = ${version3} LIMIT 1
|
|
69611
69617
|
`;
|
|
69612
69618
|
return rows[0] ? rowToSkillVersion(rows[0]) : null;
|
|
69613
69619
|
}
|
|
@@ -69616,7 +69622,7 @@ class PostgresSkillsStore {
|
|
|
69616
69622
|
throw new RangeError("Published selection lookup exceeds the profile selection limit");
|
|
69617
69623
|
if (!selections2.length)
|
|
69618
69624
|
return [];
|
|
69619
|
-
const requested = JSON.stringify(selections2.map(({ slug, version:
|
|
69625
|
+
const requested = JSON.stringify(selections2.map(({ slug, version: version3 }) => ({ slug, version: version3 })));
|
|
69620
69626
|
const rows = await this.sql`
|
|
69621
69627
|
SELECT q.value->>'slug' AS slug, q.value->>'version' AS version,
|
|
69622
69628
|
r.slug IS NOT NULL AS skill_exists, r.lifecycle, r.tombstoned_at, r.authorization_epoch,
|
|
@@ -69910,20 +69916,20 @@ async function handleApiV1(store, governanceStore, principal, request2, parts, c
|
|
|
69910
69916
|
return updated ? json4(publishedPayload(updated), { headers: { ETag: revisionEtag(updated.revisionId) } }) : json4({ error: "published skill not found", code: "SKILL_NOT_FOUND" }, { status: 404 });
|
|
69911
69917
|
}
|
|
69912
69918
|
if (request2.method === "GET" && id2 && subresource === "versions" && childId && !parts[4]) {
|
|
69913
|
-
const
|
|
69919
|
+
const version3 = await readSkillVersion(store, principal, id2, childId);
|
|
69914
69920
|
const current = (await store.getSkill(principal, id2))?.bundleSha256;
|
|
69915
|
-
return json4(skillVersionPayload(
|
|
69921
|
+
return json4(skillVersionPayload(version3, current));
|
|
69916
69922
|
}
|
|
69917
69923
|
if (request2.method === "GET" && id2 && subresource === "versions" && childId && parts[4] === "bundle" && !parts[5]) {
|
|
69918
|
-
const { version:
|
|
69924
|
+
const { version: version3, bytes, authorizationEpoch } = await readSkillVersionBundle(store, artifactStorage, principal, id2, childId);
|
|
69919
69925
|
const headers = {
|
|
69920
69926
|
"Content-Type": "application/gzip",
|
|
69921
69927
|
"Content-Length": String(bytes.byteLength),
|
|
69922
|
-
"Content-Disposition": `attachment; filename="${
|
|
69923
|
-
"X-Skill-Bundle-Sha256":
|
|
69924
|
-
"X-Skill-Version":
|
|
69928
|
+
"Content-Disposition": `attachment; filename="${version3.slug}-${version3.version}.tar.gz"`,
|
|
69929
|
+
"X-Skill-Bundle-Sha256": version3.bundleSha256,
|
|
69930
|
+
"X-Skill-Version": version3.version,
|
|
69925
69931
|
...authorizationEpoch ? { "X-Skill-Authorization-Epoch": authorizationEpoch } : {},
|
|
69926
|
-
ETag: `"${
|
|
69932
|
+
ETag: `"${version3.bundleSha256}"`,
|
|
69927
69933
|
"Cache-Control": "no-store"
|
|
69928
69934
|
};
|
|
69929
69935
|
if (config.bundleSigningKey)
|
|
@@ -71173,11 +71179,11 @@ function datetimeRegex(args) {
|
|
|
71173
71179
|
regex = `${regex}(${opts.join("|")})`;
|
|
71174
71180
|
return new RegExp(`^${regex}$`);
|
|
71175
71181
|
}
|
|
71176
|
-
function isValidIP(ip,
|
|
71177
|
-
if ((
|
|
71182
|
+
function isValidIP(ip, version3) {
|
|
71183
|
+
if ((version3 === "v4" || !version3) && ipv4Regex.test(ip)) {
|
|
71178
71184
|
return true;
|
|
71179
71185
|
}
|
|
71180
|
-
if ((
|
|
71186
|
+
if ((version3 === "v6" || !version3) && ipv6Regex.test(ip)) {
|
|
71181
71187
|
return true;
|
|
71182
71188
|
}
|
|
71183
71189
|
return false;
|
|
@@ -71204,11 +71210,11 @@ function isValidJWT(jwt, alg) {
|
|
|
71204
71210
|
return false;
|
|
71205
71211
|
}
|
|
71206
71212
|
}
|
|
71207
|
-
function isValidCidr(ip,
|
|
71208
|
-
if ((
|
|
71213
|
+
function isValidCidr(ip, version3) {
|
|
71214
|
+
if ((version3 === "v4" || !version3) && ipv4CidrRegex.test(ip)) {
|
|
71209
71215
|
return true;
|
|
71210
71216
|
}
|
|
71211
|
-
if ((
|
|
71217
|
+
if ((version3 === "v6" || !version3) && ipv6CidrRegex.test(ip)) {
|
|
71212
71218
|
return true;
|
|
71213
71219
|
}
|
|
71214
71220
|
return false;
|
|
@@ -74445,8 +74451,8 @@ function createRunEventEmitter(options = {}) {
|
|
|
74445
74451
|
const { sink, versionFor, failOpen = false } = options;
|
|
74446
74452
|
return {
|
|
74447
74453
|
async emit(type, run) {
|
|
74448
|
-
const
|
|
74449
|
-
const event = buildRunLifecycleEvent(type, run, { version:
|
|
74454
|
+
const version3 = versionFor ? await versionFor(run) : undefined;
|
|
74455
|
+
const event = buildRunLifecycleEvent(type, run, { version: version3 });
|
|
74450
74456
|
validateRunLifecycleEvent(event);
|
|
74451
74457
|
try {
|
|
74452
74458
|
if (sink) {
|
|
@@ -74790,7 +74796,7 @@ __export(exports_external2, {
|
|
|
74790
74796
|
// node_modules/zod/v4/core/index.js
|
|
74791
74797
|
var exports_core2 = {};
|
|
74792
74798
|
__export(exports_core2, {
|
|
74793
|
-
version: () =>
|
|
74799
|
+
version: () => version3,
|
|
74794
74800
|
validateAsync: () => validateAsync,
|
|
74795
74801
|
validate: () => validate2,
|
|
74796
74802
|
util: () => exports_util,
|
|
@@ -76467,10 +76473,10 @@ function nanoidOfLength(length) {
|
|
|
76467
76473
|
var duration = /^P(?:(\d+W)|(?!.*W)(?=\d|T\d)(\d+Y)?(\d+M)?(\d+D)?(T(?=\d)(\d+H)?(\d+M)?(\d+([.,]\d+)?S)?)?)$/;
|
|
76468
76474
|
var extendedDuration = /^[-+]?P(?!$)(?:(?:[-+]?\d+Y)|(?:[-+]?\d+[.,]\d+Y$))?(?:(?:[-+]?\d+M)|(?:[-+]?\d+[.,]\d+M$))?(?:(?:[-+]?\d+W)|(?:[-+]?\d+[.,]\d+W$))?(?:(?:[-+]?\d+D)|(?:[-+]?\d+[.,]\d+D$))?(?:T(?=[\d+-])(?:(?:[-+]?\d+H)|(?:[-+]?\d+[.,]\d+H$))?(?:(?:[-+]?\d+M)|(?:[-+]?\d+[.,]\d+M$))?(?:[-+]?\d+(?:[.,]\d+)?S)?)??$/;
|
|
76469
76475
|
var guid = /^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$/;
|
|
76470
|
-
var uuid = (
|
|
76471
|
-
if (!
|
|
76476
|
+
var uuid = (version3) => {
|
|
76477
|
+
if (!version3)
|
|
76472
76478
|
return /^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$/;
|
|
76473
|
-
return new RegExp(`^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-${
|
|
76479
|
+
return new RegExp(`^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-${version3}[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$`);
|
|
76474
76480
|
};
|
|
76475
76481
|
var uuid4 = /* @__PURE__ */ uuid(4);
|
|
76476
76482
|
var uuid6 = /* @__PURE__ */ uuid(6);
|
|
@@ -77136,7 +77142,7 @@ ${content.join(`
|
|
|
77136
77142
|
}
|
|
77137
77143
|
|
|
77138
77144
|
// node_modules/zod/v4/core/versions.js
|
|
77139
|
-
var
|
|
77145
|
+
var version3 = {
|
|
77140
77146
|
major: 4,
|
|
77141
77147
|
minor: 5,
|
|
77142
77148
|
patch: 4
|
|
@@ -77148,7 +77154,7 @@ var $ZodType = /* @__PURE__ */ $constructor("$ZodType", (inst, def) => {
|
|
|
77148
77154
|
inst ?? (inst = {});
|
|
77149
77155
|
inst._zod.def = def;
|
|
77150
77156
|
inst._zod.bag = inst._zod.bag || {};
|
|
77151
|
-
inst._zod.version =
|
|
77157
|
+
inst._zod.version = version3;
|
|
77152
77158
|
const defChecks = inst._zod.def.checks;
|
|
77153
77159
|
const checks = inst._zod.traits.has("$ZodCheck") ? [inst, ...defChecks ?? []] : defChecks?.length ? [...defChecks] : [];
|
|
77154
77160
|
for (const ch of checks) {
|
|
@@ -92895,10 +92901,10 @@ function fromJSONSchema(schema, params) {
|
|
|
92895
92901
|
} catch {
|
|
92896
92902
|
throw new Error("fromJSONSchema input is not valid JSON (possibly cyclic); use $defs/$ref for recursive schemas");
|
|
92897
92903
|
}
|
|
92898
|
-
const
|
|
92904
|
+
const version4 = detectVersion(normalized, params?.defaultTarget);
|
|
92899
92905
|
const defs = normalized.$defs || normalized.definitions || {};
|
|
92900
92906
|
const ctx = {
|
|
92901
|
-
version:
|
|
92907
|
+
version: version4,
|
|
92902
92908
|
defs,
|
|
92903
92909
|
refs: new Map,
|
|
92904
92910
|
processing: new Set,
|
|
@@ -94971,8 +94977,8 @@ class RemoteSkillsClient {
|
|
|
94971
94977
|
async downloadSkillBundle(slug2) {
|
|
94972
94978
|
return this.request(`/api/v1/skills/${encodeURIComponent(slug2)}/bundle`, { method: "GET" });
|
|
94973
94979
|
}
|
|
94974
|
-
async getBundle(slug2,
|
|
94975
|
-
const path2 =
|
|
94980
|
+
async getBundle(slug2, version4) {
|
|
94981
|
+
const path2 = version4 ? `/api/v1/skills/${encodeURIComponent(slug2)}/versions/${encodeURIComponent(version4)}/bundle` : `/api/v1/skills/${encodeURIComponent(slug2)}/bundle`;
|
|
94976
94982
|
const response = await this.request(path2, { method: "GET" });
|
|
94977
94983
|
if (response.status === 404)
|
|
94978
94984
|
return null;
|
|
@@ -94989,13 +94995,13 @@ class RemoteSkillsClient {
|
|
|
94989
94995
|
throw new Error(INVALID_SKILL_VERSION_RESPONSE);
|
|
94990
94996
|
return body4.versions.map((entry) => normalizeSkillVersion(entry, slug2));
|
|
94991
94997
|
}
|
|
94992
|
-
async getSkillVersion(slug2,
|
|
94993
|
-
const response = await this.requestNewRoute(`/api/v1/skills/${encodeURIComponent(slug2)}/versions/${encodeURIComponent(
|
|
94998
|
+
async getSkillVersion(slug2, version4) {
|
|
94999
|
+
const response = await this.requestNewRoute(`/api/v1/skills/${encodeURIComponent(slug2)}/versions/${encodeURIComponent(version4)}`, undefined, { domainNotFoundCodes: ["SKILL_NOT_FOUND", "SKILL_VERSION_NOT_FOUND"] });
|
|
94994
95000
|
if (response.status === 404)
|
|
94995
95001
|
return null;
|
|
94996
95002
|
if (!response.ok)
|
|
94997
95003
|
throw new Error(`version request failed: ${response.status}`);
|
|
94998
|
-
return normalizeSkillVersion(await readSkillVersionPayload(response), slug2,
|
|
95004
|
+
return normalizeSkillVersion(await readSkillVersionPayload(response), slug2, version4);
|
|
94999
95005
|
}
|
|
95000
95006
|
async listPins() {
|
|
95001
95007
|
const response = await this.requestNewRoute("/api/v1/pins");
|
|
@@ -95062,8 +95068,8 @@ async function readSkillVersionPayload(response) {
|
|
|
95062
95068
|
throw new Error(INVALID_SKILL_VERSION_RESPONSE);
|
|
95063
95069
|
}
|
|
95064
95070
|
}
|
|
95065
|
-
function normalizeSkillVersion(entry, slug2,
|
|
95066
|
-
if (!isVersionRecord(entry) || typeof entry.slug !== "string" || !entry.slug.trim() || entry.slug !== slug2 || typeof entry.version !== "string" || !entry.version.trim() ||
|
|
95071
|
+
function normalizeSkillVersion(entry, slug2, version4) {
|
|
95072
|
+
if (!isVersionRecord(entry) || typeof entry.slug !== "string" || !entry.slug.trim() || entry.slug !== slug2 || typeof entry.version !== "string" || !entry.version.trim() || version4 !== undefined && entry.version !== version4 || typeof entry.bundleSha256 !== "string" || !/^[a-f0-9]{64}$/i.test(entry.bundleSha256) || typeof entry.bundleByteSize !== "number" || !Number.isSafeInteger(entry.bundleByteSize) || entry.bundleByteSize < 0 || typeof entry.createdAt !== "string" || !entry.createdAt.trim() || entry.current !== undefined && typeof entry.current !== "boolean" || entry.storageKind !== undefined && typeof entry.storageKind !== "string" || entry.manifest !== undefined && !isVersionRecord(entry.manifest)) {
|
|
95067
95073
|
throw new Error(INVALID_SKILL_VERSION_RESPONSE);
|
|
95068
95074
|
}
|
|
95069
95075
|
return entry;
|