@hasna/skills 0.10.45 → 0.10.46
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 +17 -0
- package/bin/index.js +757 -659
- package/bin/mcp.js +553 -497
- package/bin/migrate.js +1 -1
- package/bin/server.js +1 -1
- package/bin/worker.js +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +755 -659
- package/dist/lib/agent-discovery.d.ts +1 -1
- package/dist/lib/agent-integration.d.ts +2 -2
- package/dist/lib/agent-sumi.d.ts +3 -0
- package/dist/lib/claude-settings-witness.d.ts +5 -1
- package/dist/lib/sumi-settings-witness.d.ts +14 -0
- package/dist/sdk/index.js +353 -259
- package/package.json +1 -1
package/dist/sdk/index.js
CHANGED
|
@@ -9004,7 +9004,7 @@ var require_client = __commonJS((exports) => {
|
|
|
9004
9004
|
var require_config = __commonJS((exports) => {
|
|
9005
9005
|
var { homedir: homedir7 } = __require("os");
|
|
9006
9006
|
var { sep: sep10, join: join4 } = __require("path");
|
|
9007
|
-
var { createHash:
|
|
9007
|
+
var { createHash: createHash25 } = __require("crypto");
|
|
9008
9008
|
var { readFile: readFile$1 } = __require("fs/promises");
|
|
9009
9009
|
var { IniSectionType } = require_dist_cjs();
|
|
9010
9010
|
var { normalizeProvider } = require_client();
|
|
@@ -9159,7 +9159,7 @@ var require_config = __commonJS((exports) => {
|
|
|
9159
9159
|
var DEFAULT_PROFILE = "default";
|
|
9160
9160
|
var getProfileName = (init) => init.profile || process.env[ENV_PROFILE] || DEFAULT_PROFILE;
|
|
9161
9161
|
var getSSOTokenFilepath = (id2) => {
|
|
9162
|
-
const hasher =
|
|
9162
|
+
const hasher = createHash25("sha1");
|
|
9163
9163
|
const cacheName = hasher.update(id2).digest("hex");
|
|
9164
9164
|
return join4(getHomeDir(), ".aws", "sso", "cache", `${cacheName}.json`);
|
|
9165
9165
|
};
|
|
@@ -10511,7 +10511,7 @@ var require_endpoints = __commonJS((exports) => {
|
|
|
10511
10511
|
|
|
10512
10512
|
// node_modules/@smithy/core/dist-cjs/submodules/serde/index.js
|
|
10513
10513
|
var require_serde = __commonJS((exports) => {
|
|
10514
|
-
var { createHmac: createHmac2, createHash:
|
|
10514
|
+
var { createHmac: createHmac2, createHash: createHash25, getRandomValues } = __require("crypto");
|
|
10515
10515
|
var { hasOwn: hasOwn2, HttpResponse } = require_transport();
|
|
10516
10516
|
exports.hasOwn = hasOwn2;
|
|
10517
10517
|
var { ReadStream, lstatSync: lstatSync26, fstatSync: fstatSync4 } = __require("fs");
|
|
@@ -11416,7 +11416,7 @@ var require_serde = __commonJS((exports) => {
|
|
|
11416
11416
|
return Promise.resolve(this.hash.digest());
|
|
11417
11417
|
}
|
|
11418
11418
|
reset() {
|
|
11419
|
-
this.hash = this.secret ? createHmac2(this.algorithmIdentifier, castSourceData(this.secret)) :
|
|
11419
|
+
this.hash = this.secret ? createHmac2(this.algorithmIdentifier, castSourceData(this.secret)) : createHash25(this.algorithmIdentifier);
|
|
11420
11420
|
}
|
|
11421
11421
|
}
|
|
11422
11422
|
function castSourceData(toCast, encoding) {
|
|
@@ -12155,7 +12155,7 @@ var require_checksum = __commonJS((exports) => {
|
|
|
12155
12155
|
var { createReadStream } = __require("fs");
|
|
12156
12156
|
var { Writable } = __require("stream");
|
|
12157
12157
|
var { toUint8Array, concatBytes } = require_serde();
|
|
12158
|
-
var { createHash:
|
|
12158
|
+
var { createHash: createHash25, createHmac: createHmac2 } = __require("crypto");
|
|
12159
12159
|
var zlib = __require("zlib");
|
|
12160
12160
|
async function blobReader(blob, onChunk, chunkSize = 1024 * 1024) {
|
|
12161
12161
|
const size = blob.size;
|
|
@@ -12320,7 +12320,7 @@ var require_checksum = __commonJS((exports) => {
|
|
|
12320
12320
|
}
|
|
12321
12321
|
var hasNativeCrypto$1 = (() => {
|
|
12322
12322
|
try {
|
|
12323
|
-
|
|
12323
|
+
createHash25("md5");
|
|
12324
12324
|
return true;
|
|
12325
12325
|
} catch {
|
|
12326
12326
|
return false;
|
|
@@ -12330,7 +12330,7 @@ var require_checksum = __commonJS((exports) => {
|
|
|
12330
12330
|
function buildNativeClass$2() {
|
|
12331
12331
|
return class Md5Node2 {
|
|
12332
12332
|
digestLength = 16;
|
|
12333
|
-
hash =
|
|
12333
|
+
hash = createHash25("md5");
|
|
12334
12334
|
update(data) {
|
|
12335
12335
|
this.hash.update(toUint8Array(data));
|
|
12336
12336
|
}
|
|
@@ -12339,7 +12339,7 @@ var require_checksum = __commonJS((exports) => {
|
|
|
12339
12339
|
return new Uint8Array(buf.buffer, buf.byteOffset, buf.byteLength);
|
|
12340
12340
|
}
|
|
12341
12341
|
reset() {
|
|
12342
|
-
this.hash =
|
|
12342
|
+
this.hash = createHash25("md5");
|
|
12343
12343
|
}
|
|
12344
12344
|
};
|
|
12345
12345
|
}
|
|
@@ -12629,7 +12629,7 @@ var require_checksum = __commonJS((exports) => {
|
|
|
12629
12629
|
]);
|
|
12630
12630
|
var hasNativeCrypto = (() => {
|
|
12631
12631
|
try {
|
|
12632
|
-
|
|
12632
|
+
createHash25("sha256");
|
|
12633
12633
|
return true;
|
|
12634
12634
|
} catch {
|
|
12635
12635
|
return false;
|
|
@@ -12669,7 +12669,7 @@ var require_checksum = __commonJS((exports) => {
|
|
|
12669
12669
|
this.finished = false;
|
|
12670
12670
|
}
|
|
12671
12671
|
createHash() {
|
|
12672
|
-
return this.secret ? createHmac2("sha256", toBuffer(this.secret)) :
|
|
12672
|
+
return this.secret ? createHmac2("sha256", toBuffer(this.secret)) : createHash25("sha256");
|
|
12673
12673
|
}
|
|
12674
12674
|
};
|
|
12675
12675
|
}
|
|
@@ -29443,7 +29443,7 @@ var require_signin = __commonJS((exports) => {
|
|
|
29443
29443
|
});
|
|
29444
29444
|
|
|
29445
29445
|
// node_modules/@aws-sdk/credential-provider-ini/node_modules/@aws-sdk/credential-provider-login/dist-es/LoginCredentialsFetcher.js
|
|
29446
|
-
import { createHash as
|
|
29446
|
+
import { createHash as createHash25, createPrivateKey, createPublicKey, sign } from "crypto";
|
|
29447
29447
|
import { promises as fs2 } from "fs";
|
|
29448
29448
|
import { homedir as homedir7 } from "os";
|
|
29449
29449
|
import { dirname as dirname23, join as join37 } from "path";
|
|
@@ -29615,7 +29615,7 @@ var init_LoginCredentialsFetcher = __esm(() => {
|
|
|
29615
29615
|
getTokenFilePath() {
|
|
29616
29616
|
const directory = process.env.AWS_LOGIN_CACHE_DIRECTORY ?? join37(homedir7(), ".aws", "login", "cache");
|
|
29617
29617
|
const loginSessionBytes = Buffer.from(this.loginSession, "utf8");
|
|
29618
|
-
const loginSessionSha256 =
|
|
29618
|
+
const loginSessionSha256 = createHash25("sha256").update(loginSessionBytes).digest("hex");
|
|
29619
29619
|
return join37(directory, `${loginSessionSha256}.json`);
|
|
29620
29620
|
}
|
|
29621
29621
|
derToRawSignature(derSignature) {
|
|
@@ -32373,7 +32373,7 @@ var init_event_sink = __esm(() => {
|
|
|
32373
32373
|
// package.json
|
|
32374
32374
|
var package_default = {
|
|
32375
32375
|
name: "@hasna/skills",
|
|
32376
|
-
version: "0.10.
|
|
32376
|
+
version: "0.10.46",
|
|
32377
32377
|
description: "Skills library for AI coding agents",
|
|
32378
32378
|
type: "module",
|
|
32379
32379
|
bin: {
|
|
@@ -37516,7 +37516,7 @@ async function reconcileSkillSession(input, options = {}) {
|
|
|
37516
37516
|
return { applied: true, plan, planDigest, ...result };
|
|
37517
37517
|
}
|
|
37518
37518
|
// src/lib/selected-run.ts
|
|
37519
|
-
import { createHash as
|
|
37519
|
+
import { createHash as createHash24 } from "crypto";
|
|
37520
37520
|
import { spawn as spawn2 } from "child_process";
|
|
37521
37521
|
import { mkdirSync as mkdirSync11, mkdtempSync as mkdtempSync3, writeFileSync as writeFileSync10, realpathSync as realpathSync14 } from "fs";
|
|
37522
37522
|
import { dirname as dirname22, join as join36, resolve as resolve21 } from "path";
|
|
@@ -37916,75 +37916,9 @@ import {
|
|
|
37916
37916
|
import { homedir as homedir5 } from "os";
|
|
37917
37917
|
import { basename as basename12, dirname as dirname21, join as join31 } from "path";
|
|
37918
37918
|
|
|
37919
|
-
// src/lib/
|
|
37919
|
+
// src/lib/sumi-settings-witness.ts
|
|
37920
37920
|
import { createHash as createHash7 } from "crypto";
|
|
37921
37921
|
|
|
37922
|
-
// src/lib/codex-local-mcp-controls.ts
|
|
37923
|
-
function isCodexLocalStdioMcpServer(name, server) {
|
|
37924
|
-
const identifier3 = (value) => typeof value === "string" && /^[A-Za-z0-9_-]{1,64}$/.test(value);
|
|
37925
|
-
const refuse2 = () => {
|
|
37926
|
-
throw new Error("Unsupported Codex local stdio MCP controls");
|
|
37927
|
-
};
|
|
37928
|
-
const object2 = (v) => Boolean(v && typeof v === "object" && !Array.isArray(v) && !(v instanceof Date));
|
|
37929
|
-
const textField = (v, empty = false) => typeof v === "string" && (empty || Boolean(v.trim())) && Buffer.byteLength(v) <= 16384 && !/[\x00-\x1f\x7f]/.test(v);
|
|
37930
|
-
const envName = (v) => typeof v === "string" && /^[A-Za-z_][A-Za-z0-9_]{0,255}$/.test(v);
|
|
37931
|
-
const optional = (v, valid) => v === undefined || v === null || valid(v);
|
|
37932
|
-
const stringList = (v) => Array.isArray(v) && v.length <= 256 && v.every((item) => textField(item));
|
|
37933
|
-
const approval = (v) => ["auto", "prompt", "writes", "approve"].includes(v);
|
|
37934
|
-
const duration = (v) => typeof v === "number" && Number.isFinite(v) && v >= 0;
|
|
37935
|
-
const positiveInteger = (v) => Number.isSafeInteger(v) && v > 0;
|
|
37936
|
-
const fields = [
|
|
37937
|
-
"command",
|
|
37938
|
-
"args",
|
|
37939
|
-
"cwd",
|
|
37940
|
-
"env",
|
|
37941
|
-
"env_vars",
|
|
37942
|
-
"enabled",
|
|
37943
|
-
"required",
|
|
37944
|
-
"environment_id",
|
|
37945
|
-
"startup_readiness",
|
|
37946
|
-
"supports_parallel_tool_calls",
|
|
37947
|
-
"tool_input_schema_max_bytes",
|
|
37948
|
-
"startup_timeout_sec",
|
|
37949
|
-
"startup_timeout_ms",
|
|
37950
|
-
"tool_timeout_sec",
|
|
37951
|
-
"default_tools_approval_mode",
|
|
37952
|
-
"enabled_tools",
|
|
37953
|
-
"disabled_tools",
|
|
37954
|
-
"omit_tools_from",
|
|
37955
|
-
"tools",
|
|
37956
|
-
"name"
|
|
37957
|
-
];
|
|
37958
|
-
try {
|
|
37959
|
-
if (!identifier3(name) || !object2(server) || !Object.keys(server).every((key) => fields.includes(key)) || !textField(server.command) || !optional(server.args, (v) => Array.isArray(v) && v.length <= 256 && v.every((arg) => textField(arg, true))) || !optional(server.cwd, textField) || !optional(server.env, (v) => object2(v) && Object.keys(v).length <= 256 && Object.entries(v).every(([key, value]) => envName(key) && textField(value, true))) || !["enabled", "required", "supports_parallel_tool_calls"].every((key) => optional(server[key], (v) => typeof v === "boolean")) || !optional(server.environment_id, (v) => v === "local") || !optional(server.startup_readiness, (v) => ["connection", "catalog"].includes(v)) || !optional(server.tool_input_schema_max_bytes, positiveInteger) || !["startup_timeout_sec", "tool_timeout_sec"].every((key) => optional(server[key], duration)) || !optional(server.startup_timeout_ms, (v) => Number.isSafeInteger(v) && v >= 0) || !optional(server.default_tools_approval_mode, approval) || !["enabled_tools", "disabled_tools"].every((key) => optional(server[key], stringList)) || !optional(server.omit_tools_from, (v) => Array.isArray(v) && v.length <= 256 && v.every((item) => ["code_mode", "deferred", "direct"].includes(item))) || !optional(server.name, textField))
|
|
37960
|
-
refuse2();
|
|
37961
|
-
if (server.env_vars !== undefined && server.env_vars !== null) {
|
|
37962
|
-
if (!Array.isArray(server.env_vars) || server.env_vars.length > 256)
|
|
37963
|
-
refuse2();
|
|
37964
|
-
const names = server.env_vars.map((entry) => {
|
|
37965
|
-
if (envName(entry))
|
|
37966
|
-
return entry;
|
|
37967
|
-
if (!object2(entry) || !Object.keys(entry).every((key) => ["name", "source"].includes(key)) || !envName(entry.name) || !optional(entry.source, (v) => v === "local"))
|
|
37968
|
-
refuse2();
|
|
37969
|
-
return entry.name;
|
|
37970
|
-
});
|
|
37971
|
-
if (new Set(names).size !== names.length)
|
|
37972
|
-
refuse2();
|
|
37973
|
-
}
|
|
37974
|
-
if (server.tools !== undefined && server.tools !== null) {
|
|
37975
|
-
if (!object2(server.tools) || Object.keys(server.tools).length > 256)
|
|
37976
|
-
refuse2();
|
|
37977
|
-
for (const [tool, config] of Object.entries(server.tools)) {
|
|
37978
|
-
if (!textField(tool) || !object2(config) || !Object.keys(config).every((key) => ["approval_mode", "output_token_limit"].includes(key)) || !optional(config.approval_mode, approval) || !optional(config.output_token_limit, positiveInteger))
|
|
37979
|
-
refuse2();
|
|
37980
|
-
}
|
|
37981
|
-
}
|
|
37982
|
-
return true;
|
|
37983
|
-
} catch {
|
|
37984
|
-
return false;
|
|
37985
|
-
}
|
|
37986
|
-
}
|
|
37987
|
-
|
|
37988
37922
|
// src/lib/claude-settings-witness.ts
|
|
37989
37923
|
import { createHash as createHash6 } from "crypto";
|
|
37990
37924
|
import { closeSync as closeSync9, constants as constants6, fstatSync as fstatSync9, lstatSync as lstatSync6, openSync as openSync9, readSync as readSync4 } from "fs";
|
|
@@ -38295,6 +38229,124 @@ function hashNativeJsonControls(text, excludedMetadata) {
|
|
|
38295
38229
|
});
|
|
38296
38230
|
return createHash6("sha256").update("hasna.skills.native-json-controls.v1\x00").update(JSON.stringify(canonical(value))).digest("hex");
|
|
38297
38231
|
}
|
|
38232
|
+
function hashSumiNativeJsonControls(text) {
|
|
38233
|
+
need(Buffer.byteLength(text) <= CLAUDE_SETTINGS_WITNESS_LIMITS.bytes, "exceeds its byte limit");
|
|
38234
|
+
const value = parse2(text);
|
|
38235
|
+
value.entries = value.entries.filter(([key, child]) => {
|
|
38236
|
+
if (key === "$schema" || key === "username") {
|
|
38237
|
+
need(child.kind === "string", "has invalid Sumi display metadata");
|
|
38238
|
+
return false;
|
|
38239
|
+
}
|
|
38240
|
+
if (key !== "experimental")
|
|
38241
|
+
return true;
|
|
38242
|
+
need(child.kind === "object", "requires Sumi experimental controls to be an object");
|
|
38243
|
+
child.entries = child.entries.filter(([name, option]) => {
|
|
38244
|
+
if (name !== "statusline" && name !== "compact_tools")
|
|
38245
|
+
return true;
|
|
38246
|
+
need(option.kind === "literal" && (option.value === "true" || option.value === "false"), "has invalid Sumi display preference");
|
|
38247
|
+
return false;
|
|
38248
|
+
});
|
|
38249
|
+
return child.entries.length > 0;
|
|
38250
|
+
});
|
|
38251
|
+
return createHash6("sha256").update("hasna.skills.sumi-settings.v1\x00").update(JSON.stringify(value)).digest("hex");
|
|
38252
|
+
}
|
|
38253
|
+
|
|
38254
|
+
// src/lib/sumi-settings-witness.ts
|
|
38255
|
+
var SUMI_DISCOVERY_PROJECTION_FIELDS = ["skills", "plugin", "plugins", "permissions"];
|
|
38256
|
+
var budget = () => ({ remaining: 256 * 1024 * 1024 });
|
|
38257
|
+
function readSumiSettingsPreimage(path) {
|
|
38258
|
+
return readNativeSettingsWitnessFile(path, budget(), "sumi.json");
|
|
38259
|
+
}
|
|
38260
|
+
function hashSumiSettingsReplacement(text, limits) {
|
|
38261
|
+
const bytes = Buffer.byteLength(text);
|
|
38262
|
+
if (bytes > CLAUDE_SETTINGS_WITNESS_LIMITS.bytes || !Number.isSafeInteger(limits.remaining) || limits.remaining < bytes)
|
|
38263
|
+
throw new Error("Sumi settings witness exceeds its byte limit");
|
|
38264
|
+
limits.remaining -= bytes;
|
|
38265
|
+
return hashSumiNativeJsonControls(text);
|
|
38266
|
+
}
|
|
38267
|
+
function captureSumiSettings(path, limits = budget()) {
|
|
38268
|
+
return { path, hashMode: "sumi-settings-v1", sha256: hashSumiNativeJsonControls(readNativeSettingsWitnessFile(path, limits, "sumi.json")) };
|
|
38269
|
+
}
|
|
38270
|
+
function upgradeSumiSettingsWitness(previous, reviewedSettingsPath) {
|
|
38271
|
+
if (!previous || Object.keys(previous).some((key) => !["path", "hashMode", "sha256"].includes(key)) || ![undefined, "bytes"].includes(previous.hashMode) || !/^[a-f0-9]{64}$/.test(previous.sha256))
|
|
38272
|
+
throw new Error("Sumi settings upgrade requires one exact preserved byte witness");
|
|
38273
|
+
const before = readSumiSettingsPreimage(reviewedSettingsPath);
|
|
38274
|
+
if (createHash7("sha256").update(before).digest("hex") !== previous.sha256)
|
|
38275
|
+
throw new Error("Reviewed Sumi preimage does not match its byte witness");
|
|
38276
|
+
const next = captureSumiSettings(previous.path);
|
|
38277
|
+
if (hashSumiNativeJsonControls(before) !== next.sha256)
|
|
38278
|
+
throw new Error("Sumi non-display settings changed; explicit discovery review required");
|
|
38279
|
+
return next;
|
|
38280
|
+
}
|
|
38281
|
+
|
|
38282
|
+
// src/lib/codex-plugin-skill-controls.ts
|
|
38283
|
+
import { createHash as createHash8 } from "crypto";
|
|
38284
|
+
|
|
38285
|
+
// src/lib/codex-local-mcp-controls.ts
|
|
38286
|
+
function isCodexLocalStdioMcpServer(name, server) {
|
|
38287
|
+
const identifier3 = (value) => typeof value === "string" && /^[A-Za-z0-9_-]{1,64}$/.test(value);
|
|
38288
|
+
const refuse2 = () => {
|
|
38289
|
+
throw new Error("Unsupported Codex local stdio MCP controls");
|
|
38290
|
+
};
|
|
38291
|
+
const object2 = (v) => Boolean(v && typeof v === "object" && !Array.isArray(v) && !(v instanceof Date));
|
|
38292
|
+
const textField = (v, empty = false) => typeof v === "string" && (empty || Boolean(v.trim())) && Buffer.byteLength(v) <= 16384 && !/[\x00-\x1f\x7f]/.test(v);
|
|
38293
|
+
const envName = (v) => typeof v === "string" && /^[A-Za-z_][A-Za-z0-9_]{0,255}$/.test(v);
|
|
38294
|
+
const optional = (v, valid) => v === undefined || v === null || valid(v);
|
|
38295
|
+
const stringList = (v) => Array.isArray(v) && v.length <= 256 && v.every((item) => textField(item));
|
|
38296
|
+
const approval = (v) => ["auto", "prompt", "writes", "approve"].includes(v);
|
|
38297
|
+
const duration = (v) => typeof v === "number" && Number.isFinite(v) && v >= 0;
|
|
38298
|
+
const positiveInteger = (v) => Number.isSafeInteger(v) && v > 0;
|
|
38299
|
+
const fields = [
|
|
38300
|
+
"command",
|
|
38301
|
+
"args",
|
|
38302
|
+
"cwd",
|
|
38303
|
+
"env",
|
|
38304
|
+
"env_vars",
|
|
38305
|
+
"enabled",
|
|
38306
|
+
"required",
|
|
38307
|
+
"environment_id",
|
|
38308
|
+
"startup_readiness",
|
|
38309
|
+
"supports_parallel_tool_calls",
|
|
38310
|
+
"tool_input_schema_max_bytes",
|
|
38311
|
+
"startup_timeout_sec",
|
|
38312
|
+
"startup_timeout_ms",
|
|
38313
|
+
"tool_timeout_sec",
|
|
38314
|
+
"default_tools_approval_mode",
|
|
38315
|
+
"enabled_tools",
|
|
38316
|
+
"disabled_tools",
|
|
38317
|
+
"omit_tools_from",
|
|
38318
|
+
"tools",
|
|
38319
|
+
"name"
|
|
38320
|
+
];
|
|
38321
|
+
try {
|
|
38322
|
+
if (!identifier3(name) || !object2(server) || !Object.keys(server).every((key) => fields.includes(key)) || !textField(server.command) || !optional(server.args, (v) => Array.isArray(v) && v.length <= 256 && v.every((arg) => textField(arg, true))) || !optional(server.cwd, textField) || !optional(server.env, (v) => object2(v) && Object.keys(v).length <= 256 && Object.entries(v).every(([key, value]) => envName(key) && textField(value, true))) || !["enabled", "required", "supports_parallel_tool_calls"].every((key) => optional(server[key], (v) => typeof v === "boolean")) || !optional(server.environment_id, (v) => v === "local") || !optional(server.startup_readiness, (v) => ["connection", "catalog"].includes(v)) || !optional(server.tool_input_schema_max_bytes, positiveInteger) || !["startup_timeout_sec", "tool_timeout_sec"].every((key) => optional(server[key], duration)) || !optional(server.startup_timeout_ms, (v) => Number.isSafeInteger(v) && v >= 0) || !optional(server.default_tools_approval_mode, approval) || !["enabled_tools", "disabled_tools"].every((key) => optional(server[key], stringList)) || !optional(server.omit_tools_from, (v) => Array.isArray(v) && v.length <= 256 && v.every((item) => ["code_mode", "deferred", "direct"].includes(item))) || !optional(server.name, textField))
|
|
38323
|
+
refuse2();
|
|
38324
|
+
if (server.env_vars !== undefined && server.env_vars !== null) {
|
|
38325
|
+
if (!Array.isArray(server.env_vars) || server.env_vars.length > 256)
|
|
38326
|
+
refuse2();
|
|
38327
|
+
const names = server.env_vars.map((entry) => {
|
|
38328
|
+
if (envName(entry))
|
|
38329
|
+
return entry;
|
|
38330
|
+
if (!object2(entry) || !Object.keys(entry).every((key) => ["name", "source"].includes(key)) || !envName(entry.name) || !optional(entry.source, (v) => v === "local"))
|
|
38331
|
+
refuse2();
|
|
38332
|
+
return entry.name;
|
|
38333
|
+
});
|
|
38334
|
+
if (new Set(names).size !== names.length)
|
|
38335
|
+
refuse2();
|
|
38336
|
+
}
|
|
38337
|
+
if (server.tools !== undefined && server.tools !== null) {
|
|
38338
|
+
if (!object2(server.tools) || Object.keys(server.tools).length > 256)
|
|
38339
|
+
refuse2();
|
|
38340
|
+
for (const [tool, config] of Object.entries(server.tools)) {
|
|
38341
|
+
if (!textField(tool) || !object2(config) || !Object.keys(config).every((key) => ["approval_mode", "output_token_limit"].includes(key)) || !optional(config.approval_mode, approval) || !optional(config.output_token_limit, positiveInteger))
|
|
38342
|
+
refuse2();
|
|
38343
|
+
}
|
|
38344
|
+
}
|
|
38345
|
+
return true;
|
|
38346
|
+
} catch {
|
|
38347
|
+
return false;
|
|
38348
|
+
}
|
|
38349
|
+
}
|
|
38298
38350
|
|
|
38299
38351
|
// src/lib/codex-plugin-skill-controls.ts
|
|
38300
38352
|
import { basename as basename4, dirname as dirname6, join as join12, relative as relative4, resolve as resolve5, sep as sep3 } from "path";
|
|
@@ -38986,7 +39038,7 @@ function reviewCodexPluginControls(catalog, documents, cache, cwd, read, rules,
|
|
|
38986
39038
|
const exactPathDeny = Array.isArray(rules) && rules.some((rule) => rule?.path === document && rule?.enabled === false);
|
|
38987
39039
|
const nativeSkill = { name: parsed.name, path: document, pluginId: expectedPluginId, enabled: true };
|
|
38988
39040
|
const denial = denials.find((item) => item.path === document);
|
|
38989
|
-
const explicitDeny = denial !== undefined && remotePluginId !== undefined && catalog.version === "codex-cli 0.160.0" && denial.name === parsed.name && denial.sha256 ===
|
|
39041
|
+
const explicitDeny = denial !== undefined && remotePluginId !== undefined && catalog.version === "codex-cli 0.160.0" && denial.name === parsed.name && denial.sha256 === createHash8("sha256").update(read(document)).digest("hex") && Array.isArray(rules) && !rules.some((rule) => (rule?.path === document || typeof rule?.name === "string" && rule.name.trim() === parsed.name) && rule.enabled !== false) && Array.isArray(plannedRules) && plannedRules.some((rule) => rule?.path === document && rule.enabled === false);
|
|
38990
39042
|
if (denial && !explicitDeny)
|
|
38991
39043
|
refuse3();
|
|
38992
39044
|
if (explicitDeny)
|
|
@@ -39073,7 +39125,7 @@ enabled = false
|
|
|
39073
39125
|
}
|
|
39074
39126
|
|
|
39075
39127
|
// src/lib/codex-native-skill-policy.ts
|
|
39076
|
-
import { createHash as
|
|
39128
|
+
import { createHash as createHash9, randomUUID as randomUUID2 } from "crypto";
|
|
39077
39129
|
import { closeSync as closeSync10, constants as constants7, fstatSync as fstatSync10, fsyncSync as fsyncSync2, lstatSync as lstatSync8, mkdirSync as mkdirSync4, openSync as openSync10, readFileSync as readFileSync10, readSync as readSync5, readlinkSync as readlinkSync3, realpathSync as realpathSync7, renameSync as renameSync2, unlinkSync as unlinkSync3, writeFileSync as writeFileSync3 } from "fs";
|
|
39078
39130
|
import { dirname as dirname7, isAbsolute as isAbsolute7, join as join13, resolve as resolve6 } from "path";
|
|
39079
39131
|
import { isDeepStrictEqual as isDeepStrictEqual3 } from "util";
|
|
@@ -39201,7 +39253,7 @@ function verifyCodexNativeBridgeDocument(path, expectedContent, expectedSha256)
|
|
|
39201
39253
|
if (realpathSync7.native(path) !== path)
|
|
39202
39254
|
refuse4("NATIVE_SKILL_POLICY_BRIDGE_UNVERIFIED", "the bridge document real path differs from its lexical path");
|
|
39203
39255
|
const bytes = readBounded(path, MAX_BRIDGE_DOCUMENT_BYTES, "the bridge document");
|
|
39204
|
-
const sha2562 =
|
|
39256
|
+
const sha2562 = createHash9("sha256").update(bytes).digest("hex");
|
|
39205
39257
|
if (!bytes.equals(Buffer.from(expectedContent, "utf8")) || sha2562 !== expectedSha256)
|
|
39206
39258
|
refuse4("NATIVE_SKILL_POLICY_BRIDGE_UNVERIFIED", "the bridge document bytes differ from the managed bridge");
|
|
39207
39259
|
return { path, sha256: sha2562 };
|
|
@@ -39669,8 +39721,8 @@ function recordCodexNativePolicyAcceptance(dataDir2, verification, accepted) {
|
|
|
39669
39721
|
}
|
|
39670
39722
|
|
|
39671
39723
|
// src/lib/codex-settings-witness-v1.ts
|
|
39672
|
-
import { createHash as
|
|
39673
|
-
var sha = (text) =>
|
|
39724
|
+
import { createHash as createHash10 } from "crypto";
|
|
39725
|
+
var sha = (text) => createHash10("sha256").update(text).digest("hex");
|
|
39674
39726
|
var EFFORT = new Set(["none", "minimal", "low", "medium", "high", "xhigh"]);
|
|
39675
39727
|
var VERBOSITY = new Set(["low", "medium", "high"]);
|
|
39676
39728
|
function need2(value) {
|
|
@@ -39716,8 +39768,8 @@ function numericTokens(text) {
|
|
|
39716
39768
|
}
|
|
39717
39769
|
return result;
|
|
39718
39770
|
}
|
|
39719
|
-
function canonical2(value, depth = 0,
|
|
39720
|
-
need2(depth <= 32 && --
|
|
39771
|
+
function canonical2(value, depth = 0, budget2 = { remaining: 65536 }) {
|
|
39772
|
+
need2(depth <= 32 && --budget2.remaining >= 0);
|
|
39721
39773
|
if (value === null)
|
|
39722
39774
|
return ["null"];
|
|
39723
39775
|
if (typeof value === "string")
|
|
@@ -39733,13 +39785,13 @@ function canonical2(value, depth = 0, budget = { remaining: 65536 }) {
|
|
|
39733
39785
|
return ["date", value.toISOString()];
|
|
39734
39786
|
}
|
|
39735
39787
|
if (Array.isArray(value))
|
|
39736
|
-
return ["array", value.map((child) => canonical2(child, depth + 1,
|
|
39788
|
+
return ["array", value.map((child) => canonical2(child, depth + 1, budget2))];
|
|
39737
39789
|
need2(value && typeof value === "object");
|
|
39738
|
-
return ["object", Object.entries(value).sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0).map(([key, child]) => [key, canonical2(child, depth + 1,
|
|
39790
|
+
return ["object", Object.entries(value).sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0).map(([key, child]) => [key, canonical2(child, depth + 1, budget2)])];
|
|
39739
39791
|
}
|
|
39740
|
-
function hashCodexSettingsReplacement(text,
|
|
39741
|
-
need2(Buffer.byteLength(text) <= 1024 * 1024 &&
|
|
39742
|
-
|
|
39792
|
+
function hashCodexSettingsReplacement(text, budget2 = { remaining: 256 * 1024 * 1024 }) {
|
|
39793
|
+
need2(Buffer.byteLength(text) <= 1024 * 1024 && budget2.remaining >= Buffer.byteLength(text));
|
|
39794
|
+
budget2.remaining -= Buffer.byteLength(text);
|
|
39743
39795
|
let config;
|
|
39744
39796
|
try {
|
|
39745
39797
|
config = Bun.TOML.parse(text);
|
|
@@ -39758,8 +39810,8 @@ function hashCodexSettingsReplacement(text, budget = { remaining: 256 * 1024 * 1
|
|
|
39758
39810
|
}
|
|
39759
39811
|
return sha(`hasna.skills.codex-settings.v1\x00${JSON.stringify([canonical2(config), numericTokens(text)])}`);
|
|
39760
39812
|
}
|
|
39761
|
-
function captureCodexSettings(path,
|
|
39762
|
-
const text = readNativeSettingsWitnessFile(path,
|
|
39813
|
+
function captureCodexSettings(path, budget2 = { remaining: 256 * 1024 * 1024 }) {
|
|
39814
|
+
const text = readNativeSettingsWitnessFile(path, budget2, "config.toml");
|
|
39763
39815
|
return { path, hashMode: "codex-settings-v1", sha256: hashCodexSettingsReplacement(text) };
|
|
39764
39816
|
}
|
|
39765
39817
|
// src/lib/codex-mcp-discovery-projection.ts
|
|
@@ -39827,9 +39879,9 @@ function projectRegularCodexMcp(config, source) {
|
|
|
39827
39879
|
}
|
|
39828
39880
|
|
|
39829
39881
|
// src/lib/codex-settings-witness.ts
|
|
39830
|
-
import { createHash as
|
|
39882
|
+
import { createHash as createHash11 } from "crypto";
|
|
39831
39883
|
import { isDeepStrictEqual as isDeepStrictEqual5 } from "util";
|
|
39832
|
-
var sha2 = (text) =>
|
|
39884
|
+
var sha2 = (text) => createHash11("sha256").update(text).digest("hex");
|
|
39833
39885
|
var EFFORT2 = new Set(["none", "minimal", "low", "medium", "high", "xhigh"]);
|
|
39834
39886
|
var VERBOSITY2 = new Set(["low", "medium", "high"]);
|
|
39835
39887
|
var MODEL = /^[A-Za-z0-9][A-Za-z0-9._:/-]{0,127}$/;
|
|
@@ -39884,8 +39936,8 @@ function numericTokens2(text) {
|
|
|
39884
39936
|
}
|
|
39885
39937
|
return result.sort();
|
|
39886
39938
|
}
|
|
39887
|
-
function canonical3(value, depth = 0,
|
|
39888
|
-
need3(depth <= 32 && --
|
|
39939
|
+
function canonical3(value, depth = 0, budget2 = { remaining: 65536 }) {
|
|
39940
|
+
need3(depth <= 32 && --budget2.remaining >= 0);
|
|
39889
39941
|
if (value === null)
|
|
39890
39942
|
return ["null"];
|
|
39891
39943
|
if (typeof value === "string")
|
|
@@ -39901,9 +39953,9 @@ function canonical3(value, depth = 0, budget = { remaining: 65536 }) {
|
|
|
39901
39953
|
return ["date", value.toISOString()];
|
|
39902
39954
|
}
|
|
39903
39955
|
if (Array.isArray(value))
|
|
39904
|
-
return ["array", value.map((child) => canonical3(child, depth + 1,
|
|
39956
|
+
return ["array", value.map((child) => canonical3(child, depth + 1, budget2))];
|
|
39905
39957
|
need3(isRecord(value));
|
|
39906
|
-
return ["object", Object.entries(value).sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0).map(([key, child]) => [key, canonical3(child, depth + 1,
|
|
39958
|
+
return ["object", Object.entries(value).sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0).map(([key, child]) => [key, canonical3(child, depth + 1, budget2)])];
|
|
39907
39959
|
}
|
|
39908
39960
|
function normalize2(config, version = 2) {
|
|
39909
39961
|
if (isRecord(config.hooks)) {
|
|
@@ -40079,40 +40131,40 @@ function settingsDigest2(text, version = 2) {
|
|
|
40079
40131
|
normalize2(projected.config, version);
|
|
40080
40132
|
return sha2(`hasna.skills.codex-settings.v${version}\x00${JSON.stringify([canonical3(projected.config), numericTokens2(projected.numericSource)])}`);
|
|
40081
40133
|
}
|
|
40082
|
-
function hashCodexSettingsReplacementV2(text,
|
|
40083
|
-
need3(Buffer.byteLength(text) <= 1024 * 1024 &&
|
|
40084
|
-
|
|
40134
|
+
function hashCodexSettingsReplacementV2(text, budget2 = { remaining: 256 * 1024 * 1024 }) {
|
|
40135
|
+
need3(Buffer.byteLength(text) <= 1024 * 1024 && budget2.remaining >= Buffer.byteLength(text));
|
|
40136
|
+
budget2.remaining -= Buffer.byteLength(text);
|
|
40085
40137
|
return settingsDigest2(text);
|
|
40086
40138
|
}
|
|
40087
|
-
function captureCodexSettingsV2(path,
|
|
40088
|
-
const text = readNativeSettingsWitnessFile(path,
|
|
40139
|
+
function captureCodexSettingsV2(path, budget2 = { remaining: 256 * 1024 * 1024 }) {
|
|
40140
|
+
const text = readNativeSettingsWitnessFile(path, budget2, "config.toml");
|
|
40089
40141
|
return { path, hashMode: "codex-settings-v2", sha256: settingsDigest2(text) };
|
|
40090
40142
|
}
|
|
40091
|
-
function readCodexSettingsPreimage(path,
|
|
40092
|
-
return readNativeSettingsWitnessFile(path,
|
|
40143
|
+
function readCodexSettingsPreimage(path, budget2 = { remaining: 2 * 1024 * 1024 }) {
|
|
40144
|
+
return readNativeSettingsWitnessFile(path, budget2, "config.toml");
|
|
40093
40145
|
}
|
|
40094
40146
|
function upgradeCodexSettingsWitness(previous, reviewedSettingsPath) {
|
|
40095
40147
|
need3(previous && Object.keys(previous).every((key) => ["path", "hashMode", "sha256"].includes(key)) && (previous.hashMode === undefined || previous.hashMode === "bytes" || previous.hashMode === "codex-settings-v1") && /^[a-f0-9]{64}$/.test(previous.sha256));
|
|
40096
|
-
const
|
|
40097
|
-
const before = readNativeSettingsWitnessFile(reviewedSettingsPath,
|
|
40148
|
+
const budget2 = { remaining: 2 * 1024 * 1024 };
|
|
40149
|
+
const before = readNativeSettingsWitnessFile(reviewedSettingsPath, budget2, "config.toml"), current = readNativeSettingsWitnessFile(previous.path, budget2, "config.toml");
|
|
40098
40150
|
need3((previous.hashMode === "codex-settings-v1" ? hashCodexSettingsReplacement(before) : sha2(before)) === previous.sha256);
|
|
40099
40151
|
const sha2562 = settingsDigest2(current);
|
|
40100
40152
|
if (settingsDigest2(before) !== sha2562)
|
|
40101
40153
|
throw new Error("Codex non-preference settings changed; explicit discovery review required");
|
|
40102
40154
|
return { path: previous.path, hashMode: "codex-settings-v2", sha256: sha2562 };
|
|
40103
40155
|
}
|
|
40104
|
-
function hashCodexSettingsReplacementV3(text,
|
|
40105
|
-
need3(Buffer.byteLength(text) <= 1024 * 1024 &&
|
|
40106
|
-
|
|
40156
|
+
function hashCodexSettingsReplacementV3(text, budget2 = { remaining: 256 * 1024 * 1024 }) {
|
|
40157
|
+
need3(Buffer.byteLength(text) <= 1024 * 1024 && budget2.remaining >= Buffer.byteLength(text));
|
|
40158
|
+
budget2.remaining -= Buffer.byteLength(text);
|
|
40107
40159
|
return settingsDigest2(text, 3);
|
|
40108
40160
|
}
|
|
40109
|
-
function captureCodexSettingsV3(path,
|
|
40110
|
-
return { path, hashMode: "codex-settings-v3", sha256: settingsDigest2(readNativeSettingsWitnessFile(path,
|
|
40161
|
+
function captureCodexSettingsV3(path, budget2 = { remaining: 256 * 1024 * 1024 }) {
|
|
40162
|
+
return { path, hashMode: "codex-settings-v3", sha256: settingsDigest2(readNativeSettingsWitnessFile(path, budget2, "config.toml"), 3) };
|
|
40111
40163
|
}
|
|
40112
40164
|
function upgradeCodexSettingsWitnessV3(previous, reviewedSettingsPath) {
|
|
40113
40165
|
need3(previous && Object.keys(previous).every((key) => ["path", "hashMode", "sha256"].includes(key)) && (previous.hashMode === undefined || ["bytes", "codex-settings-v1", "codex-settings-v2"].includes(previous.hashMode)) && /^[a-f0-9]{64}$/.test(previous.sha256));
|
|
40114
|
-
const
|
|
40115
|
-
const before = readNativeSettingsWitnessFile(reviewedSettingsPath,
|
|
40166
|
+
const budget2 = { remaining: 2 * 1024 * 1024 };
|
|
40167
|
+
const before = readNativeSettingsWitnessFile(reviewedSettingsPath, budget2, "config.toml"), current = readNativeSettingsWitnessFile(previous.path, budget2, "config.toml");
|
|
40116
40168
|
const original = previous.hashMode === "codex-settings-v2" ? settingsDigest2(before) : previous.hashMode === "codex-settings-v1" ? hashCodexSettingsReplacement(before) : sha2(before);
|
|
40117
40169
|
need3(original === previous.sha256);
|
|
40118
40170
|
const sha2562 = settingsDigest2(current, 3);
|
|
@@ -40120,18 +40172,18 @@ function upgradeCodexSettingsWitnessV3(previous, reviewedSettingsPath) {
|
|
|
40120
40172
|
throw new Error("Codex settings outside the reviewed V3 contract changed; explicit discovery review required");
|
|
40121
40173
|
return { path: previous.path, hashMode: "codex-settings-v3", sha256: sha2562 };
|
|
40122
40174
|
}
|
|
40123
|
-
function hashCodexSettingsReplacementV4(text,
|
|
40124
|
-
need3(Buffer.byteLength(text) <= 1024 * 1024 &&
|
|
40125
|
-
|
|
40175
|
+
function hashCodexSettingsReplacementV4(text, budget2 = { remaining: 256 * 1024 * 1024 }) {
|
|
40176
|
+
need3(Buffer.byteLength(text) <= 1024 * 1024 && budget2.remaining >= Buffer.byteLength(text));
|
|
40177
|
+
budget2.remaining -= Buffer.byteLength(text);
|
|
40126
40178
|
return settingsDigest2(text, 4);
|
|
40127
40179
|
}
|
|
40128
|
-
function captureCodexSettingsV4(path,
|
|
40129
|
-
return { path, hashMode: "codex-settings-v4", sha256: settingsDigest2(readNativeSettingsWitnessFile(path,
|
|
40180
|
+
function captureCodexSettingsV4(path, budget2 = { remaining: 256 * 1024 * 1024 }) {
|
|
40181
|
+
return { path, hashMode: "codex-settings-v4", sha256: settingsDigest2(readNativeSettingsWitnessFile(path, budget2, "config.toml"), 4) };
|
|
40130
40182
|
}
|
|
40131
40183
|
function upgradeCodexSettingsWitnessV4(previous, reviewedSettingsPath) {
|
|
40132
40184
|
need3(previous && Object.keys(previous).every((key) => ["path", "hashMode", "sha256"].includes(key)) && (previous.hashMode === undefined || ["bytes", "codex-settings-v1", "codex-settings-v2", "codex-settings-v3"].includes(previous.hashMode)) && /^[a-f0-9]{64}$/.test(previous.sha256));
|
|
40133
|
-
const
|
|
40134
|
-
const before = readNativeSettingsWitnessFile(reviewedSettingsPath,
|
|
40185
|
+
const budget2 = { remaining: 2 * 1024 * 1024 };
|
|
40186
|
+
const before = readNativeSettingsWitnessFile(reviewedSettingsPath, budget2, "config.toml"), current = readNativeSettingsWitnessFile(previous.path, budget2, "config.toml");
|
|
40135
40187
|
const original = previous.hashMode === "codex-settings-v3" ? settingsDigest2(before, 3) : previous.hashMode === "codex-settings-v2" ? settingsDigest2(before, 2) : previous.hashMode === "codex-settings-v1" ? hashCodexSettingsReplacement(before) : sha2(before);
|
|
40136
40188
|
need3(original === previous.sha256);
|
|
40137
40189
|
const sha2562 = settingsDigest2(current, 4);
|
|
@@ -40162,7 +40214,7 @@ var NATIVE_SKILL_ROOTS = [
|
|
|
40162
40214
|
];
|
|
40163
40215
|
|
|
40164
40216
|
// src/lib/agent-integration.ts
|
|
40165
|
-
import { createHash as
|
|
40217
|
+
import { createHash as createHash22, randomUUID as randomUUID4 } from "crypto";
|
|
40166
40218
|
import { isDeepStrictEqual as isDeepStrictEqual8 } from "util";
|
|
40167
40219
|
import { existsSync as existsSync7, lstatSync as lstatSync22, statSync as statSync7, mkdirSync as mkdirSync6, readFileSync as readFileSync16, readdirSync as readdirSync8, opendirSync as opendirSync5, readlinkSync as readlinkSync5, realpathSync as realpathSync10, renameSync as renameSync4, rmdirSync as rmdirSync3, writeFileSync as writeFileSync5, unlinkSync as unlinkSync5, chmodSync, openSync as openSync17, closeSync as closeSync17, fsyncSync as fsyncSync5, fstatSync as fstatSync17, readSync as readSync12, constants as constants14, linkSync as linkSync3 } from "fs";
|
|
40168
40220
|
import { dirname as dirname17, join as join26, resolve as resolve18, relative as relative5, isAbsolute as isAbsolute19, sep as sep6 } from "path";
|
|
@@ -40315,7 +40367,9 @@ function assertAgentPolicyCollections(policy) {
|
|
|
40315
40367
|
text(source.path);
|
|
40316
40368
|
requireBound(source.sha256 === null || typeof source.sha256 === "string" && /^[a-f0-9]{64}$/.test(source.sha256));
|
|
40317
40369
|
if (source.hashMode !== undefined)
|
|
40318
|
-
requireBound(["bytes", "path-bytes", "claude-plugin-registry", "claude-marketplace-registry", "claude-settings-v1", "claude-settings-v2", "claude-settings-v3", "claude-marketplace-registry-v2", "codex-settings-v1", "codex-settings-v2", "codex-settings-v3", "codex-settings-v4"].includes(source.hashMode) && source.format === undefined && source.fields === undefined && (source.hashMode === "bytes" || source.sha256 !== null));
|
|
40370
|
+
requireBound(["bytes", "path-bytes", "claude-plugin-registry", "claude-marketplace-registry", "claude-settings-v1", "claude-settings-v2", "claude-settings-v3", "claude-marketplace-registry-v2", "codex-settings-v1", "codex-settings-v2", "codex-settings-v3", "codex-settings-v4", "sumi-settings-v1"].includes(source.hashMode) && source.format === undefined && source.fields === undefined && (source.hashMode === "bytes" || source.sha256 !== null));
|
|
40371
|
+
if (source.hashMode === "sumi-settings-v1")
|
|
40372
|
+
requireBound(agent === "sumi" && value.agent === "sumi" && value.method === "reviewed" && !/[\x00-\x1f\x7f]/.test(source.path) && isAbsolute8(source.path) && resolve7(source.path) === source.path && basename5(source.path) === "sumi.json");
|
|
40319
40373
|
if (source.hashMode === "codex-settings-v1" || source.hashMode === "codex-settings-v2" || (source.hashMode === "codex-settings-v3" || source.hashMode === "codex-settings-v4"))
|
|
40320
40374
|
requireBound(agent === "codex" && value.agent === "codex" && value.method === "reviewed" && !/[\x00-\x1f\x7f]/.test(source.path) && isAbsolute8(source.path) && resolve7(source.path) === source.path && basename5(source.path) === "config.toml");
|
|
40321
40375
|
if (source.hashMode === "claude-settings-v1" || source.hashMode === "claude-settings-v2" || source.hashMode === "claude-settings-v3")
|
|
@@ -40430,7 +40484,7 @@ function requiresCliSkillLoading(dataDir2 = getDataDirReadOnly()) {
|
|
|
40430
40484
|
}
|
|
40431
40485
|
|
|
40432
40486
|
// src/lib/agent-bridge.ts
|
|
40433
|
-
import { createHash as
|
|
40487
|
+
import { createHash as createHash12 } from "crypto";
|
|
40434
40488
|
import { lstatSync as lstatSync10, readFileSync as readFileSync11, readdirSync as readdirSync4 } from "fs";
|
|
40435
40489
|
import { join as join15 } from "path";
|
|
40436
40490
|
var CLI_BRIDGE_NAME = "skills-cli";
|
|
@@ -40449,7 +40503,7 @@ Use the Skills CLI as the skill authority for this station.
|
|
|
40449
40503
|
|
|
40450
40504
|
This bridge contains no skill payloads. Do not copy skill content into agent-native skill directories or load other native skill copies. If a Skills command refuses authority, selection, integrity, or native drift, report that refusal and use its repair guidance; do not substitute bundled or stale local content. Explicit local draft authoring remains available.
|
|
40451
40505
|
`;
|
|
40452
|
-
var CLI_BRIDGE_DIGEST =
|
|
40506
|
+
var CLI_BRIDGE_DIGEST = createHash12("sha256").update(markdown).digest("hex");
|
|
40453
40507
|
var CLI_BRIDGE_FILES = Object.freeze({
|
|
40454
40508
|
"SKILL.md": markdown,
|
|
40455
40509
|
".hasna-skills.json": `${JSON.stringify({ managedBy: "@hasna/skills", kind: "cli-bridge", version: CLI_BRIDGE_VERSION, protocol: "selection-v1", contentSha256: CLI_BRIDGE_DIGEST }, null, 2)}
|
|
@@ -40473,7 +40527,7 @@ function isOwnedCliBridge(path, expectedPaths) {
|
|
|
40473
40527
|
}
|
|
40474
40528
|
|
|
40475
40529
|
// src/lib/agent-discovery.ts
|
|
40476
|
-
import { createHash as
|
|
40530
|
+
import { createHash as createHash21 } from "crypto";
|
|
40477
40531
|
import { lstatSync as lstatSync21, readFileSync as readFileSync15, readdirSync as readdirSync7, realpathSync as realpathSync9 } from "fs";
|
|
40478
40532
|
import { basename as basename8, dirname as dirname16, isAbsolute as isAbsolute18, join as join25, resolve as resolve17, sep as sep5 } from "path";
|
|
40479
40533
|
import { isDeepStrictEqual as isDeepStrictEqual6 } from "util";
|
|
@@ -40732,7 +40786,7 @@ if (failed) process.exitCode = 2;
|
|
|
40732
40786
|
}
|
|
40733
40787
|
|
|
40734
40788
|
// src/lib/agent-discovery-directories.ts
|
|
40735
|
-
import { createHash as
|
|
40789
|
+
import { createHash as createHash13 } from "crypto";
|
|
40736
40790
|
import { lstatSync as lstatSync12, opendirSync as opendirSync2 } from "fs";
|
|
40737
40791
|
import { dirname as dirname9, isAbsolute as isAbsolute10, join as join17, resolve as resolve9 } from "path";
|
|
40738
40792
|
function need4(value, message) {
|
|
@@ -40750,7 +40804,7 @@ function safe(path) {
|
|
|
40750
40804
|
function same(before, after) {
|
|
40751
40805
|
return Boolean(after && after.isDirectory() && before.dev === after.dev && before.ino === after.ino && before.mtimeMs === after.mtimeMs && before.ctimeMs === after.ctimeMs);
|
|
40752
40806
|
}
|
|
40753
|
-
function capture(path,
|
|
40807
|
+
function capture(path, budget2, excludedRoots, omittedRoots = [], rows) {
|
|
40754
40808
|
safe(path);
|
|
40755
40809
|
if (omittedRoots.some((root2) => path === root2 || path.startsWith(root2 + "/")))
|
|
40756
40810
|
return { path, sha256: null };
|
|
@@ -40758,13 +40812,13 @@ function capture(path, budget, excludedRoots, omittedRoots = [], rows) {
|
|
|
40758
40812
|
if (!root)
|
|
40759
40813
|
return { path, sha256: null };
|
|
40760
40814
|
need4(root.isDirectory(), "Unsupported native discovery directory input");
|
|
40761
|
-
const hash2 =
|
|
40815
|
+
const hash2 = createHash13("sha256");
|
|
40762
40816
|
function walk2(current, relative5, before, depth) {
|
|
40763
40817
|
need4(depth <= 64, "Native discovery directory depth limit exceeded");
|
|
40764
40818
|
const names = [], directory = opendirSync2(current);
|
|
40765
40819
|
try {
|
|
40766
40820
|
for (let entry = directory.readSync();entry; entry = directory.readSync()) {
|
|
40767
|
-
need4(++
|
|
40821
|
+
need4(++budget2.entries <= AGENT_POLICY_LIMITS.discoveryDirectoryEntries, "Native discovery directory entry limit exceeded");
|
|
40768
40822
|
names.push(entry.name);
|
|
40769
40823
|
}
|
|
40770
40824
|
} finally {
|
|
@@ -40780,8 +40834,8 @@ function capture(path, budget, excludedRoots, omittedRoots = [], rows) {
|
|
|
40780
40834
|
need4(stat.isFile() || stat.isDirectory(), "Refusing symlink or special native discovery directory member");
|
|
40781
40835
|
const row = JSON.stringify([childRelative, stat.isDirectory() ? "directory" : "file"]) + `
|
|
40782
40836
|
`;
|
|
40783
|
-
|
|
40784
|
-
need4(
|
|
40837
|
+
budget2.bytes += Buffer.byteLength(row);
|
|
40838
|
+
need4(budget2.bytes <= AGENT_POLICY_LIMITS.discoveryDirectoryBytes, "Native discovery directory metadata limit exceeded");
|
|
40785
40839
|
hash2.update(row);
|
|
40786
40840
|
rows?.push(row);
|
|
40787
40841
|
if (stat.isDirectory() && !excludedRoots.includes(child))
|
|
@@ -40798,10 +40852,10 @@ function captureDiscoveryDirectoryProjection(paths, omittedRoots) {
|
|
|
40798
40852
|
need4(omittedRoots.length <= AGENT_POLICY_LIMITS.discoveryRoots && new Set(omittedRoots).size === omittedRoots.length, "Invalid inactive discovery roots");
|
|
40799
40853
|
for (const root of omittedRoots)
|
|
40800
40854
|
safe(root);
|
|
40801
|
-
const
|
|
40855
|
+
const budget2 = { entries: 0, bytes: 0 };
|
|
40802
40856
|
return paths.map((path) => {
|
|
40803
40857
|
const entries = [];
|
|
40804
|
-
return { ...capture(path,
|
|
40858
|
+
return { ...capture(path, budget2, [], omittedRoots, entries), entries };
|
|
40805
40859
|
});
|
|
40806
40860
|
}
|
|
40807
40861
|
function verifyDiscoveryDirectoryProjection(directories, omittedRoots) {
|
|
@@ -40810,7 +40864,7 @@ function verifyDiscoveryDirectoryProjection(directories, omittedRoots) {
|
|
|
40810
40864
|
const expected = directories.map((directory) => {
|
|
40811
40865
|
safe(directory.path);
|
|
40812
40866
|
need4(Array.isArray(directory.entries), "Missing reviewed directory membership inventory");
|
|
40813
|
-
const hash2 =
|
|
40867
|
+
const hash2 = createHash13("sha256");
|
|
40814
40868
|
const kept = [];
|
|
40815
40869
|
for (const row of directory.entries) {
|
|
40816
40870
|
need4(typeof row === "string" && ++count <= AGENT_POLICY_LIMITS.discoveryDirectoryEntries, "Invalid reviewed directory membership rows");
|
|
@@ -40826,17 +40880,17 @@ function verifyDiscoveryDirectoryProjection(directories, omittedRoots) {
|
|
|
40826
40880
|
}
|
|
40827
40881
|
need4(directory.sha256 === null ? directory.entries.length === 0 : hash2.digest("hex") === directory.sha256, "Reviewed directory inventory does not match its fingerprint");
|
|
40828
40882
|
const absent = omittedRoots.some((root) => directory.path === root || directory.path.startsWith(root + "/"));
|
|
40829
|
-
return { path: directory.path, sha256: absent || directory.sha256 === null ? null :
|
|
40883
|
+
return { path: directory.path, sha256: absent || directory.sha256 === null ? null : createHash13("sha256").update(kept.join("")).digest("hex") };
|
|
40830
40884
|
});
|
|
40831
40885
|
const current = captureDiscoveryDirectoryProjection(directories.map((item) => item.path), omittedRoots);
|
|
40832
40886
|
need4(current.every((item, index) => item.sha256 === expected[index].sha256), "Native discovery directory membership changed outside retired Codex roots");
|
|
40833
40887
|
}
|
|
40834
40888
|
function captureDiscoveryDirectories(paths, excludedRoots = []) {
|
|
40835
40889
|
need4(Array.isArray(paths) && paths.length <= AGENT_POLICY_LIMITS.discoveryDirectories && new Set(paths).size === paths.length, "Invalid native discovery directory collection");
|
|
40836
|
-
const
|
|
40890
|
+
const budget2 = { entries: 0, bytes: 0 };
|
|
40837
40891
|
for (const root of excludedRoots)
|
|
40838
40892
|
safe(root);
|
|
40839
|
-
return paths.map((path) => capture(path,
|
|
40893
|
+
return paths.map((path) => capture(path, budget2, excludedRoots));
|
|
40840
40894
|
}
|
|
40841
40895
|
function verifyDiscoveryDirectories(directories, excludedRoots = []) {
|
|
40842
40896
|
need4(Array.isArray(directories) && directories.length <= AGENT_POLICY_LIMITS.discoveryDirectories, "Invalid native discovery directory collection");
|
|
@@ -40848,7 +40902,7 @@ function verifyDiscoveryDirectories(directories, excludedRoots = []) {
|
|
|
40848
40902
|
}
|
|
40849
40903
|
|
|
40850
40904
|
// src/lib/agent-discovery-bytes.ts
|
|
40851
|
-
import { createHash as
|
|
40905
|
+
import { createHash as createHash14 } from "crypto";
|
|
40852
40906
|
import { closeSync as closeSync12, constants as constants9, fstatSync as fstatSync12, lstatSync as lstatSync13, openSync as openSync12, readSync as readSync7 } from "fs";
|
|
40853
40907
|
import { dirname as dirname10, isAbsolute as isAbsolute11, resolve as resolve10 } from "path";
|
|
40854
40908
|
function discoveryByteBudget() {
|
|
@@ -40867,33 +40921,33 @@ function safe2(path) {
|
|
|
40867
40921
|
function same2(left, right) {
|
|
40868
40922
|
return left.dev === right.dev && left.ino === right.ino && left.size === right.size && left.mtimeMs === right.mtimeMs && left.ctimeMs === right.ctimeMs;
|
|
40869
40923
|
}
|
|
40870
|
-
function consume(
|
|
40871
|
-
if (bytes >
|
|
40924
|
+
function consume(budget2, bytes) {
|
|
40925
|
+
if (bytes > budget2.remaining)
|
|
40872
40926
|
throw new Error("Raw discovery aggregate byte limit exceeded");
|
|
40873
|
-
|
|
40927
|
+
budget2.remaining -= bytes;
|
|
40874
40928
|
}
|
|
40875
|
-
function hashRawDiscoveryFile(path,
|
|
40929
|
+
function hashRawDiscoveryFile(path, budget2, changes) {
|
|
40876
40930
|
safe2(path);
|
|
40877
40931
|
if (changes?.has(path)) {
|
|
40878
40932
|
const text2 = changes.get(path), bytes = Buffer.byteLength(text2);
|
|
40879
40933
|
if (bytes > AGENT_POLICY_LIMITS.discoveryRawSourceBytes)
|
|
40880
40934
|
throw new Error("Raw discovery file byte limit exceeded");
|
|
40881
|
-
consume(
|
|
40882
|
-
return
|
|
40935
|
+
consume(budget2, bytes);
|
|
40936
|
+
return createHash14("sha256").update(text2).digest("hex");
|
|
40883
40937
|
}
|
|
40884
40938
|
const initial = lstatSync13(path, { throwIfNoEntry: false });
|
|
40885
40939
|
if (!initial)
|
|
40886
40940
|
return null;
|
|
40887
40941
|
if (!initial.isFile() || initial.size > AGENT_POLICY_LIMITS.discoveryRawSourceBytes)
|
|
40888
40942
|
throw new Error("Unsupported or oversized raw discovery input");
|
|
40889
|
-
if (initial.size >
|
|
40943
|
+
if (initial.size > budget2.remaining)
|
|
40890
40944
|
throw new Error("Raw discovery aggregate byte limit exceeded");
|
|
40891
40945
|
const fd = openSync12(path, constants9.O_RDONLY | constants9.O_NOFOLLOW | constants9.O_NONBLOCK);
|
|
40892
40946
|
try {
|
|
40893
40947
|
const opened = fstatSync12(fd);
|
|
40894
40948
|
if (!opened.isFile() || !same2(initial, opened))
|
|
40895
40949
|
throw new Error("Raw discovery input changed during open");
|
|
40896
|
-
const hash2 =
|
|
40950
|
+
const hash2 = createHash14("sha256"), buffer = Buffer.alloc(64 * 1024);
|
|
40897
40951
|
let bytes = 0;
|
|
40898
40952
|
while (true) {
|
|
40899
40953
|
const count = readSync7(fd, buffer, 0, Math.min(buffer.length, AGENT_POLICY_LIMITS.discoveryRawSourceBytes - bytes + 1), null);
|
|
@@ -40902,7 +40956,7 @@ function hashRawDiscoveryFile(path, budget, changes) {
|
|
|
40902
40956
|
bytes += count;
|
|
40903
40957
|
if (bytes > AGENT_POLICY_LIMITS.discoveryRawSourceBytes)
|
|
40904
40958
|
throw new Error("Raw discovery file byte limit exceeded");
|
|
40905
|
-
consume(
|
|
40959
|
+
consume(budget2, count);
|
|
40906
40960
|
hash2.update(buffer.subarray(0, count));
|
|
40907
40961
|
}
|
|
40908
40962
|
const final = fstatSync12(fd), current = lstatSync13(path, { throwIfNoEntry: false });
|
|
@@ -40916,7 +40970,7 @@ function hashRawDiscoveryFile(path, budget, changes) {
|
|
|
40916
40970
|
}
|
|
40917
40971
|
|
|
40918
40972
|
// src/lib/agent-discovery-path-bytes.ts
|
|
40919
|
-
import { createHash as
|
|
40973
|
+
import { createHash as createHash15 } from "crypto";
|
|
40920
40974
|
import { lstatSync as lstatSync14, readlinkSync as readlinkSync4 } from "fs";
|
|
40921
40975
|
import { dirname as dirname11, isAbsolute as isAbsolute12, join as join18, parse as parse3, resolve as resolve11, sep as sep4 } from "path";
|
|
40922
40976
|
function identity4(stat, mutable = false) {
|
|
@@ -41003,7 +41057,7 @@ function trace(path) {
|
|
|
41003
41057
|
}
|
|
41004
41058
|
throw new Error("Unsupported directory discovery path input");
|
|
41005
41059
|
}
|
|
41006
|
-
function hashDiscoveryPathFile(path,
|
|
41060
|
+
function hashDiscoveryPathFile(path, budget2, changes) {
|
|
41007
41061
|
const before = trace(path);
|
|
41008
41062
|
let createsMissingPath = false;
|
|
41009
41063
|
if (before.missing !== null && changes) {
|
|
@@ -41016,17 +41070,17 @@ function hashDiscoveryPathFile(path, budget, changes) {
|
|
|
41016
41070
|
}
|
|
41017
41071
|
if (createsMissingPath || changes?.has(path) || before.paths.some((path2) => changes?.has(path2)))
|
|
41018
41072
|
throw new Error("Discovery path witness intersects a planned write; use bytes mode for owned configuration");
|
|
41019
|
-
const remaining =
|
|
41073
|
+
const remaining = budget2.pathMetadataRemaining ?? AGENT_POLICY_LIMITS.discoveryPathTotalMetadataBytes;
|
|
41020
41074
|
if (before.metadataBytes > remaining)
|
|
41021
41075
|
throw new Error("Discovery path aggregate metadata limit exceeded");
|
|
41022
|
-
|
|
41023
|
-
const content = before.file === null ? null : hashRawDiscoveryFile(before.file,
|
|
41076
|
+
budget2.pathMetadataRemaining = remaining - before.metadataBytes;
|
|
41077
|
+
const content = before.file === null ? null : hashRawDiscoveryFile(before.file, budget2);
|
|
41024
41078
|
if (before.file !== null && content === null)
|
|
41025
41079
|
throw new Error("Discovery path input changed during read");
|
|
41026
41080
|
const after = trace(path);
|
|
41027
41081
|
if (JSON.stringify(before.rows) !== JSON.stringify(after.rows) || before.file !== after.file)
|
|
41028
41082
|
throw new Error("Discovery path input changed during read");
|
|
41029
|
-
return
|
|
41083
|
+
return createHash15("sha256").update(JSON.stringify({ version: 1, path, rows: before.rows, content })).digest("hex");
|
|
41030
41084
|
}
|
|
41031
41085
|
|
|
41032
41086
|
// src/lib/plugin-discovery.ts
|
|
@@ -41038,7 +41092,7 @@ import { homedir as homedir2 } from "os";
|
|
|
41038
41092
|
import { isAbsolute as isAbsolute15, join as join22, resolve as resolve13 } from "path";
|
|
41039
41093
|
|
|
41040
41094
|
// src/lib/plugin-projection.ts
|
|
41041
|
-
import { createHash as
|
|
41095
|
+
import { createHash as createHash16 } from "crypto";
|
|
41042
41096
|
import { posix as posix2 } from "path";
|
|
41043
41097
|
var PLUGIN_PROJECTION_MANIFEST = "plugin-projection.json";
|
|
41044
41098
|
var PLUGIN_PROJECTION_LIMITS = Object.freeze({ files: 1024, bytes: 64 * 1024 * 1024, fileBytes: 16 * 1024 * 1024, metadataBytes: 512 * 1024, registrations: 64, history: 128 });
|
|
@@ -41049,7 +41103,7 @@ function pluginNeed(value, message) {
|
|
|
41049
41103
|
if (!value)
|
|
41050
41104
|
pluginRefusal(message);
|
|
41051
41105
|
}
|
|
41052
|
-
var pluginHash = (bytes) =>
|
|
41106
|
+
var pluginHash = (bytes) => createHash16("sha256").update(bytes).digest("hex");
|
|
41053
41107
|
function pluginObject(value) {
|
|
41054
41108
|
return Boolean(value && typeof value === "object" && !Array.isArray(value));
|
|
41055
41109
|
}
|
|
@@ -41237,7 +41291,7 @@ function buildPluginProjection(entries) {
|
|
|
41237
41291
|
}
|
|
41238
41292
|
|
|
41239
41293
|
// src/lib/plugin-projection-store.ts
|
|
41240
|
-
import { createHash as
|
|
41294
|
+
import { createHash as createHash17, randomUUID as randomUUID3 } from "crypto";
|
|
41241
41295
|
import { constants as constants10, closeSync as closeSync13, fchmodSync, fstatSync as fstatSync13, fsyncSync as fsyncSync3, linkSync as linkSync2, lstatSync as lstatSync15, mkdirSync as mkdirSync5, openSync as openSync13, opendirSync as opendirSync3, readSync as readSync8, renameSync as renameSync3, rmdirSync as rmdirSync2, rmSync, unlinkSync as unlinkSync4, writeSync as writeSync2 } from "fs";
|
|
41242
41296
|
import { dirname as dirname12, isAbsolute as isAbsolute13, join as join19, parse as parse5, resolve as resolve12 } from "path";
|
|
41243
41297
|
var READ_FLAGS = constants10.O_RDONLY | constants10.O_NOFOLLOW | constants10.O_NONBLOCK;
|
|
@@ -41579,7 +41633,7 @@ function pluginExecutableDigest(path) {
|
|
|
41579
41633
|
const opened = fstatSync13(fd, { bigint: true });
|
|
41580
41634
|
same3(before, opened);
|
|
41581
41635
|
fileShape(opened, maximum, "executable");
|
|
41582
|
-
const hash2 =
|
|
41636
|
+
const hash2 = createHash17("sha256"), buffer = new Uint8Array(64 * 1024);
|
|
41583
41637
|
let remaining = Number(opened.size);
|
|
41584
41638
|
while (remaining > 0) {
|
|
41585
41639
|
const count = readSync8(fd, buffer, 0, Math.min(buffer.byteLength, remaining), null);
|
|
@@ -42574,7 +42628,7 @@ function captureManagedPluginRegistry(path, managedPlugins) {
|
|
|
42574
42628
|
}
|
|
42575
42629
|
|
|
42576
42630
|
// src/lib/claude-marketplace-registry.ts
|
|
42577
|
-
import { createHash as
|
|
42631
|
+
import { createHash as createHash18 } from "crypto";
|
|
42578
42632
|
import { closeSync as closeSync15, constants as constants12, fstatSync as fstatSync15, lstatSync as lstatSync18, openSync as openSync15, readSync as readSync10 } from "fs";
|
|
42579
42633
|
import { basename as basename7, dirname as dirname14, isAbsolute as isAbsolute17, resolve as resolve15 } from "path";
|
|
42580
42634
|
var CLAUDE_MARKETPLACE_REGISTRY_LIMITS = Object.freeze({ bytes: 1024 * 1024, rows: 1024, depth: 32, nodes: 65536, stringCharacters: 16384, pathCharacters: 4096 });
|
|
@@ -42596,13 +42650,13 @@ function parents2(path) {
|
|
|
42596
42650
|
return result;
|
|
42597
42651
|
}
|
|
42598
42652
|
}
|
|
42599
|
-
function readRegistry2(path,
|
|
42653
|
+
function readRegistry2(path, budget2) {
|
|
42600
42654
|
absolutePath3(path);
|
|
42601
42655
|
need5(basename7(path) === "known_marketplaces.json", "requires known_marketplaces.json");
|
|
42602
|
-
need5(Number.isSafeInteger(
|
|
42656
|
+
need5(Number.isSafeInteger(budget2.remaining) && budget2.remaining >= 0, "has an invalid byte budget");
|
|
42603
42657
|
const ancestors2 = parents2(path), initial = lstatSync18(path, { bigint: true });
|
|
42604
42658
|
need5(initial.isFile() && !initial.isSymbolicLink() && initial.size <= BigInt(CLAUDE_MARKETPLACE_REGISTRY_LIMITS.bytes), "is not a bounded regular file");
|
|
42605
|
-
need5(initial.size <= BigInt(
|
|
42659
|
+
need5(initial.size <= BigInt(budget2.remaining), "exceeds its aggregate byte limit");
|
|
42606
42660
|
const fd = openSync15(path, constants12.O_RDONLY | constants12.O_NOFOLLOW | constants12.O_NONBLOCK);
|
|
42607
42661
|
try {
|
|
42608
42662
|
const opened = fstatSync15(fd, { bigint: true });
|
|
@@ -42621,7 +42675,7 @@ function readRegistry2(path, budget) {
|
|
|
42621
42675
|
const now = lstatSync18(ancestor, { bigint: true });
|
|
42622
42676
|
need5(now.isDirectory() && before.dev === now.dev && before.ino === now.ino && before.mode === now.mode, "parent changed during read");
|
|
42623
42677
|
}
|
|
42624
|
-
|
|
42678
|
+
budget2.remaining -= length;
|
|
42625
42679
|
try {
|
|
42626
42680
|
return new TextDecoder("utf-8", { fatal: true, ignoreBOM: true }).decode(bytes.subarray(0, length));
|
|
42627
42681
|
} catch {
|
|
@@ -42739,27 +42793,27 @@ function normalizeRow(row, version = 1) {
|
|
|
42739
42793
|
need5(Number.isFinite(millis) && new Date(millis).toISOString() === updated, "contains an invalid recognized update timestamp");
|
|
42740
42794
|
row.entries = row.entries.map(([key, value]) => [key, key === "lastUpdated" ? { kind: "validated-update-time" } : value]);
|
|
42741
42795
|
}
|
|
42742
|
-
function captureClaudeMarketplaceRegistry(path,
|
|
42743
|
-
const value = parse6(readRegistry2(path,
|
|
42796
|
+
function captureClaudeMarketplaceRegistry(path, budget2 = { remaining: 256 * 1024 * 1024 }) {
|
|
42797
|
+
const value = parse6(readRegistry2(path, budget2));
|
|
42744
42798
|
for (const [, row] of value.entries)
|
|
42745
42799
|
normalizeRow(row);
|
|
42746
|
-
const sha2562 =
|
|
42800
|
+
const sha2562 = createHash18("sha256").update("hasna.skills.claude-marketplace-registry.v1\x00").update(JSON.stringify(value)).digest("hex");
|
|
42747
42801
|
return { path, hashMode: "claude-marketplace-registry", sha256: sha2562 };
|
|
42748
42802
|
}
|
|
42749
|
-
function captureClaudeMarketplaceRegistryV2(path,
|
|
42750
|
-
const value = parse6(readRegistry2(path,
|
|
42803
|
+
function captureClaudeMarketplaceRegistryV2(path, budget2 = { remaining: 256 * 1024 * 1024 }) {
|
|
42804
|
+
const value = parse6(readRegistry2(path, budget2));
|
|
42751
42805
|
for (const [, row] of value.entries)
|
|
42752
42806
|
normalizeRow(row, 2);
|
|
42753
|
-
const sha2562 =
|
|
42807
|
+
const sha2562 = createHash18("sha256").update("hasna.skills.claude-marketplace-registry.v2\x00").update(JSON.stringify(value)).digest("hex");
|
|
42754
42808
|
return { path, hashMode: "claude-marketplace-registry-v2", sha256: sha2562 };
|
|
42755
42809
|
}
|
|
42756
42810
|
|
|
42757
42811
|
// src/lib/codex-hook-discovery-recovery.ts
|
|
42758
|
-
import { createHash as
|
|
42812
|
+
import { createHash as createHash20 } from "crypto";
|
|
42759
42813
|
|
|
42760
42814
|
// src/lib/codex-hook-trust-files.ts
|
|
42761
42815
|
import { closeSync as closeSync16, constants as constants13, fstatSync as fstatSync16, fsyncSync as fsyncSync4, lstatSync as lstatSync19, openSync as openSync16, readSync as readSync11, writeFileSync as writeFileSync4 } from "fs";
|
|
42762
|
-
import { createHash as
|
|
42816
|
+
import { createHash as createHash19 } from "crypto";
|
|
42763
42817
|
import { dirname as dirname15 } from "path";
|
|
42764
42818
|
function need6(value, code) {
|
|
42765
42819
|
if (!value)
|
|
@@ -42795,7 +42849,7 @@ function snapshot(file, privateFile = false, options = {}) {
|
|
|
42795
42849
|
}
|
|
42796
42850
|
need6(length === Number(before.size) && sameStat(before, fstatSync16(fd, { bigint: true })) && sameStat(before, lstatSync19(file, { bigint: true })), "INPUT_CHANGED");
|
|
42797
42851
|
const content = bytes.subarray(0, length), text2 = new TextDecoder("utf-8", { fatal: true }).decode(content);
|
|
42798
|
-
return { file, privateFile, readOnlyPackage, text: text2, bytes: content, stat: before, sha256:
|
|
42852
|
+
return { file, privateFile, readOnlyPackage, text: text2, bytes: content, stat: before, sha256: createHash19("sha256").update(content).digest("hex") };
|
|
42799
42853
|
} finally {
|
|
42800
42854
|
closeSync16(fd);
|
|
42801
42855
|
}
|
|
@@ -42811,7 +42865,7 @@ var matchedEvents = { ...events, PreToolUse: ["preToolUse", "pre_tool_use"] };
|
|
|
42811
42865
|
var proofs = new WeakMap;
|
|
42812
42866
|
|
|
42813
42867
|
// src/lib/codex-hook-discovery-recovery.ts
|
|
42814
|
-
var sha3 = (text2) =>
|
|
42868
|
+
var sha3 = (text2) => createHash20("sha256").update(text2).digest("hex");
|
|
42815
42869
|
var fields = [...CODEX_DISCOVERY_PROJECTION_FIELDS];
|
|
42816
42870
|
var proofs2 = new WeakMap;
|
|
42817
42871
|
function assertCodexHookDiscoveryRecovery(binding, witness) {
|
|
@@ -42863,31 +42917,44 @@ function sumiConfigPath(home) {
|
|
|
42863
42917
|
return join24(sumiConfigDirectory(home), "sumi.json");
|
|
42864
42918
|
}
|
|
42865
42919
|
function renderSumiPlugin(command, profile) {
|
|
42920
|
+
return renderSumiPluginVersion(command, profile, false);
|
|
42921
|
+
}
|
|
42922
|
+
function isManagedSumiPlugin(text2, command, profile) {
|
|
42923
|
+
return text2 === renderSumiPlugin(command, profile) || text2 === renderSumiPluginVersion(command, profile, true);
|
|
42924
|
+
}
|
|
42925
|
+
function renderSumiPluginVersion(command, profile, legacy) {
|
|
42926
|
+
const failure = (message) => legacy ? `new Error(${JSON.stringify(message)})` : "refusal()";
|
|
42866
42927
|
return `// Managed by @hasna/skills. Regenerate with skills hook install --agent sumi.
|
|
42867
42928
|
import { spawn } from "node:child_process";
|
|
42868
42929
|
const command = ${JSON.stringify(command)};
|
|
42869
42930
|
const profile = ${JSON.stringify(profile)};
|
|
42870
|
-
function
|
|
42931
|
+
${legacy ? "" : `function refusal() {
|
|
42932
|
+
const error = new Error("Skills verification blocked this request. Review the Sumi Skills hook configuration, then retry.");
|
|
42933
|
+
error.name = "SkillsHookRefusal";
|
|
42934
|
+
error.skillsHookRefusal = { version: 1, code: "SKILLS_HOOK_REFUSED" };
|
|
42935
|
+
return error;
|
|
42936
|
+
}
|
|
42937
|
+
`}function context(input) {
|
|
42871
42938
|
return new Promise((resolve, reject) => {
|
|
42872
42939
|
const child = spawn(command, ["hook", "user-prompt", "--agent", "sumi", "--selection-profile", profile], { cwd: input.cwd, stdio: ["pipe", "pipe", "pipe"] });
|
|
42873
42940
|
const chunks = []; let bytes = 0, failure;
|
|
42874
|
-
const timer = setTimeout(() => { failure =
|
|
42875
|
-
child.stdout.on("data", chunk => { bytes += chunk.length; if (bytes > 1048576) { failure =
|
|
42941
|
+
const timer = setTimeout(() => { failure = ${failure("Skills prompt hook timed out")}; child.kill("SIGKILL"); }, 15000);
|
|
42942
|
+
child.stdout.on("data", chunk => { bytes += chunk.length; if (bytes > 1048576) { failure = ${failure("Skills prompt hook output exceeded its limit")}; child.kill("SIGKILL"); } else chunks.push(chunk); });
|
|
42876
42943
|
child.stderr.on("data", () => {});
|
|
42877
42944
|
child.stdin.on("error", () => {});
|
|
42878
|
-
child.on("error", error => { clearTimeout(timer); reject(error); });
|
|
42945
|
+
child.on("error", error => { clearTimeout(timer); reject(${legacy ? "error" : "refusal()"}); });
|
|
42879
42946
|
child.on("close", code => {
|
|
42880
42947
|
clearTimeout(timer);
|
|
42881
|
-
if (failure || code !== 0) return reject(failure ??
|
|
42948
|
+
if (failure || code !== 0) return reject(failure ?? ${failure("Skills prompt hook failed")});
|
|
42882
42949
|
try {
|
|
42883
42950
|
const result = JSON.parse(Buffer.concat(chunks).toString("utf8"));
|
|
42884
|
-
if (!result || typeof result !== "object" || Array.isArray(result)) throw
|
|
42885
|
-
if (result.decision === "block" || result.continue === false) throw
|
|
42886
|
-
if (Object.keys(result).length && (!result.hookSpecificOutput || result.hookSpecificOutput.hookEventName !== input.hook_event_name)) throw
|
|
42951
|
+
if (!result || typeof result !== "object" || Array.isArray(result)) throw ${failure("Invalid Skills hook response")};
|
|
42952
|
+
if (result.decision === "block" || result.continue === false) throw ${failure("Skills prompt hook refused")};
|
|
42953
|
+
if (Object.keys(result).length && (!result.hookSpecificOutput || result.hookSpecificOutput.hookEventName !== input.hook_event_name)) throw ${failure("Invalid Skills hook response")};
|
|
42887
42954
|
const text = result.hookSpecificOutput?.additionalContext ?? "";
|
|
42888
|
-
if (typeof text !== "string") throw
|
|
42955
|
+
if (typeof text !== "string") throw ${failure("Invalid Skills prompt context")};
|
|
42889
42956
|
resolve(text);
|
|
42890
|
-
} catch (error) { reject(error); }
|
|
42957
|
+
} catch (error) { reject(${legacy ? "error" : "refusal()"}); }
|
|
42891
42958
|
});
|
|
42892
42959
|
child.stdin.end(JSON.stringify(input));
|
|
42893
42960
|
});
|
|
@@ -42895,13 +42962,14 @@ function context(input) {
|
|
|
42895
42962
|
export default {
|
|
42896
42963
|
id: "local.hasna-skills-cli",
|
|
42897
42964
|
async setup(ctx) {
|
|
42898
|
-
if (!ctx?.session?.hook || !ctx?.session?.get || !ctx?.skill?.transform || !ctx?.tool?.hook) throw
|
|
42965
|
+
if (!ctx?.session?.hook || !ctx?.session?.get || !ctx?.skill?.transform || !ctx?.tool?.hook) throw ${failure("Unsupported Sumi native Skills contract")};
|
|
42899
42966
|
const registrations = [];
|
|
42900
42967
|
const sessions = new Set();
|
|
42901
42968
|
async function input(sessionID, prompt, first) {
|
|
42902
42969
|
// The Promise adapter unwraps single-data endpoint responses.
|
|
42903
|
-
const session = await ctx.session.get({ sessionID });
|
|
42904
|
-
|
|
42970
|
+
${legacy ? "const session = await ctx.session.get({ sessionID });" : `let session;
|
|
42971
|
+
try { session = await ctx.session.get({ sessionID }); } catch { throw refusal(); }`}
|
|
42972
|
+
if (!session || session.id !== sessionID || typeof session.location?.directory !== "string" || (session.parentID !== undefined && typeof session.parentID !== "string") || session.parentID === sessionID) throw ${failure("Invalid Sumi session custody")};
|
|
42905
42973
|
return { hook_event_name: first ? session.parentID ? "SubagentStart" : "SessionStart" : "UserPromptSubmit", cwd: session.location.directory, session_id: sessionID, parent_session_id: session.parentID ?? null, prompt, restore: true };
|
|
42906
42974
|
}
|
|
42907
42975
|
registrations.push(await ctx.skill.transform(editor => {
|
|
@@ -42910,11 +42978,11 @@ export default {
|
|
|
42910
42978
|
// Native config transforms may add skills after this transform. Guard
|
|
42911
42979
|
// both direct tool calls and prompt attachments at the consumption edge.
|
|
42912
42980
|
registrations.push(await ctx.tool.hook("execute.before", event => {
|
|
42913
|
-
if (event.tool === "skill" && event.input?.id !== "skills-cli") throw
|
|
42981
|
+
if (event.tool === "skill" && event.input?.id !== "skills-cli") throw ${failure("Native Sumi skill payload refused; use Skills CLI")};
|
|
42914
42982
|
}));
|
|
42915
42983
|
registrations.push(await ctx.session.hook("prompt", async event => {
|
|
42916
|
-
if (typeof event.prompt?.text !== "string") throw
|
|
42917
|
-
if (event.prompt.skills !== undefined && (!Array.isArray(event.prompt.skills) || event.prompt.skills.some(skill => skill?.id !== "skills-cli"))) throw
|
|
42984
|
+
if (typeof event.prompt?.text !== "string") throw ${failure("Invalid Sumi prompt")};
|
|
42985
|
+
if (event.prompt.skills !== undefined && (!Array.isArray(event.prompt.skills) || event.prompt.skills.some(skill => skill?.id !== "skills-cli"))) throw ${failure("Native Sumi skill attachment refused; use Skills CLI")};
|
|
42918
42986
|
await context(await input(event.sessionID, event.prompt.text, !sessions.has(event.sessionID)));
|
|
42919
42987
|
sessions.add(event.sessionID);
|
|
42920
42988
|
}));
|
|
@@ -42938,7 +43006,7 @@ var SUMI_SKILL_PERMISSIONS = [
|
|
|
42938
43006
|
];
|
|
42939
43007
|
|
|
42940
43008
|
// src/lib/agent-discovery.ts
|
|
42941
|
-
var digest2 = (text2) =>
|
|
43009
|
+
var digest2 = (text2) => createHash21("sha256").update(text2).digest("hex");
|
|
42942
43010
|
function parseConfig(text2, path, toml = false) {
|
|
42943
43011
|
try {
|
|
42944
43012
|
const value = toml ? Bun.TOML.parse(text2) : JSON.parse(text2);
|
|
@@ -42976,33 +43044,45 @@ function projectNativeDiscoveryFields(text2, format, fields2, path) {
|
|
|
42976
43044
|
throw new Error("Expected native discovery configuration object");
|
|
42977
43045
|
return digest2(JSON.stringify(Object.fromEntries(fields2.map((field2) => [field2, object6[field2] ?? null]))));
|
|
42978
43046
|
}
|
|
42979
|
-
function
|
|
43047
|
+
function isSupersededSettingsProjection(agent, configPath, source) {
|
|
43048
|
+
if (agent === "sumi")
|
|
43049
|
+
return source.path === configPath && source.format === "json" && isDeepStrictEqual6(source.fields, [...SUMI_DISCOVERY_PROJECTION_FIELDS]);
|
|
42980
43050
|
return agent === "codex" && source.path === configPath && source.format === "toml" && isDeepStrictEqual6(source.fields, [...CODEX_DISCOVERY_PROJECTION_FIELDS]);
|
|
42981
43051
|
}
|
|
42982
|
-
function
|
|
42983
|
-
|
|
43052
|
+
function supersedesSettingsProjection(agent, sources, configPath) {
|
|
43053
|
+
if (agent === "sumi")
|
|
43054
|
+
return sources.some((source) => source.path === configPath && source.hashMode === "sumi-settings-v1");
|
|
43055
|
+
return agent === "codex" && sources.some((source) => source.path === configPath && (source.hashMode === "codex-settings-v2" || (source.hashMode === "codex-settings-v3" || source.hashMode === "codex-settings-v4")));
|
|
42984
43056
|
}
|
|
42985
|
-
function projected(source, changes,
|
|
43057
|
+
function projected(source, changes, budget2 = discoveryByteBudget()) {
|
|
43058
|
+
if (source.hashMode === "sumi-settings-v1") {
|
|
43059
|
+
if (source.format !== undefined || source.fields !== undefined || source.managedPlugins !== undefined || typeof source.sha256 !== "string" || !/^[a-f0-9]{64}$/.test(source.sha256))
|
|
43060
|
+
throw new Error("Sumi settings witnesses require exact typed metadata");
|
|
43061
|
+
const current = captureSumiSettings(source.path, budget2).sha256;
|
|
43062
|
+
if (current !== source.sha256)
|
|
43063
|
+
throw new Error(`Native discovery input changed; run skills hook install with a fresh discovery review: ${source.path}`);
|
|
43064
|
+
return changes?.has(source.path) ? hashSumiSettingsReplacement(changes.get(source.path), budget2) : current;
|
|
43065
|
+
}
|
|
42986
43066
|
if (source.hashMode === "codex-settings-v1" || source.hashMode === "codex-settings-v2" || (source.hashMode === "codex-settings-v3" || source.hashMode === "codex-settings-v4")) {
|
|
42987
43067
|
if (source.format !== undefined || source.fields !== undefined || source.managedPlugins !== undefined || typeof source.sha256 !== "string" || !/^[a-f0-9]{64}$/.test(source.sha256))
|
|
42988
43068
|
throw new Error("Codex settings witnesses require exact typed metadata");
|
|
42989
|
-
const current = (source.hashMode === "codex-settings-v4" ? captureCodexSettingsV4 : source.hashMode === "codex-settings-v3" ? captureCodexSettingsV3 : source.hashMode === "codex-settings-v2" ? captureCodexSettingsV2 : captureCodexSettings)(source.path,
|
|
43069
|
+
const current = (source.hashMode === "codex-settings-v4" ? captureCodexSettingsV4 : source.hashMode === "codex-settings-v3" ? captureCodexSettingsV3 : source.hashMode === "codex-settings-v2" ? captureCodexSettingsV2 : captureCodexSettings)(source.path, budget2).sha256;
|
|
42990
43070
|
if (current !== source.sha256)
|
|
42991
43071
|
throw new Error(`Native discovery input changed; run skills hook install with a fresh discovery review: ${source.path}`);
|
|
42992
|
-
return changes?.has(source.path) ? (source.hashMode === "codex-settings-v4" ? hashCodexSettingsReplacementV4 : source.hashMode === "codex-settings-v3" ? hashCodexSettingsReplacementV3 : source.hashMode === "codex-settings-v2" ? hashCodexSettingsReplacementV2 : hashCodexSettingsReplacement)(changes.get(source.path),
|
|
43072
|
+
return changes?.has(source.path) ? (source.hashMode === "codex-settings-v4" ? hashCodexSettingsReplacementV4 : source.hashMode === "codex-settings-v3" ? hashCodexSettingsReplacementV3 : source.hashMode === "codex-settings-v2" ? hashCodexSettingsReplacementV2 : hashCodexSettingsReplacement)(changes.get(source.path), budget2) : current;
|
|
42993
43073
|
}
|
|
42994
43074
|
if (source.hashMode === "claude-settings-v1" || source.hashMode === "claude-settings-v2" || source.hashMode === "claude-settings-v3") {
|
|
42995
43075
|
if (source.format !== undefined || source.fields !== undefined || source.managedPlugins !== undefined || typeof source.sha256 !== "string" || !/^[a-f0-9]{64}$/.test(source.sha256))
|
|
42996
43076
|
throw new Error("Claude settings witnesses require exact typed metadata");
|
|
42997
|
-
const current = (source.hashMode === "claude-settings-v3" ? captureClaudeSettingsV3 : source.hashMode === "claude-settings-v2" ? captureClaudeSettingsV2 : captureClaudeSettings)(source.path,
|
|
43077
|
+
const current = (source.hashMode === "claude-settings-v3" ? captureClaudeSettingsV3 : source.hashMode === "claude-settings-v2" ? captureClaudeSettingsV2 : captureClaudeSettings)(source.path, budget2).sha256;
|
|
42998
43078
|
if (current !== source.sha256)
|
|
42999
43079
|
throw new Error(`Native discovery input changed; run skills hook install with a fresh discovery review: ${source.path}`);
|
|
43000
|
-
return changes?.has(source.path) ? (source.hashMode === "claude-settings-v3" ? hashClaudeSettingsReplacementV3 : source.hashMode === "claude-settings-v2" ? hashClaudeSettingsReplacementV2 : hashClaudeSettingsReplacement)(changes.get(source.path),
|
|
43080
|
+
return changes?.has(source.path) ? (source.hashMode === "claude-settings-v3" ? hashClaudeSettingsReplacementV3 : source.hashMode === "claude-settings-v2" ? hashClaudeSettingsReplacementV2 : hashClaudeSettingsReplacement)(changes.get(source.path), budget2) : current;
|
|
43001
43081
|
}
|
|
43002
43082
|
if (source.hashMode === "claude-marketplace-registry" || source.hashMode === "claude-marketplace-registry-v2") {
|
|
43003
43083
|
if (source.format !== undefined || source.fields !== undefined || source.managedPlugins !== undefined || typeof source.sha256 !== "string" || !/^[a-f0-9]{64}$/.test(source.sha256) || changes?.has(source.path))
|
|
43004
43084
|
throw new Error("Claude marketplace witnesses require an exact reviewed registry without synthetic changes");
|
|
43005
|
-
const sha2562 = (source.hashMode === "claude-marketplace-registry-v2" ? captureClaudeMarketplaceRegistryV2 : captureClaudeMarketplaceRegistry)(source.path,
|
|
43085
|
+
const sha2562 = (source.hashMode === "claude-marketplace-registry-v2" ? captureClaudeMarketplaceRegistryV2 : captureClaudeMarketplaceRegistry)(source.path, budget2).sha256;
|
|
43006
43086
|
if (sha2562 !== source.sha256)
|
|
43007
43087
|
throw new Error(`Native discovery input changed; run skills hook install with a fresh discovery review: ${source.path}`);
|
|
43008
43088
|
return sha2562;
|
|
@@ -43020,8 +43100,8 @@ function projected(source, changes, budget = discoveryByteBudget()) {
|
|
|
43020
43100
|
if (source.format !== undefined || source.fields !== undefined)
|
|
43021
43101
|
throw new Error("Raw discovery witnesses cannot project configuration fields");
|
|
43022
43102
|
if (source.hashMode === "path-bytes")
|
|
43023
|
-
return hashDiscoveryPathFile(source.path,
|
|
43024
|
-
return hashRawDiscoveryFile(source.path,
|
|
43103
|
+
return hashDiscoveryPathFile(source.path, budget2, changes);
|
|
43104
|
+
return hashRawDiscoveryFile(source.path, budget2, changes);
|
|
43025
43105
|
}
|
|
43026
43106
|
const text2 = read2(source.path, changes);
|
|
43027
43107
|
if (text2 === null)
|
|
@@ -43169,7 +43249,7 @@ function verifyAgentDiscovery(binding, codexRecovery) {
|
|
|
43169
43249
|
verifyDiscoveryDirectories(projected2, installationRoots);
|
|
43170
43250
|
}
|
|
43171
43251
|
const absentRoots = [...absentCodexSkillRoots(binding), ...absentRetiredClaudeRoots(binding), ...retiredRoots.filter((root2) => !lstatSync21(root2, { throwIfNoEntry: false }))];
|
|
43172
|
-
const
|
|
43252
|
+
const budget2 = discoveryByteBudget();
|
|
43173
43253
|
for (const source of binding.sources) {
|
|
43174
43254
|
assertMarketplaceBinding(binding, source);
|
|
43175
43255
|
if (source.hashMode === "claude-plugin-registry" && binding.agent !== "claude")
|
|
@@ -43186,7 +43266,7 @@ function verifyAgentDiscovery(binding, codexRecovery) {
|
|
|
43186
43266
|
safe4(source.path);
|
|
43187
43267
|
continue;
|
|
43188
43268
|
}
|
|
43189
|
-
const current = projected(source, undefined,
|
|
43269
|
+
const current = projected(source, undefined, budget2);
|
|
43190
43270
|
if (current !== source.sha256 && !verifiesCodexHookDiscoverySource(binding, source, current, codexRecovery))
|
|
43191
43271
|
throw new Error(`Native discovery input changed; run skills hook install with a fresh discovery review: ${source.path}`);
|
|
43192
43272
|
}
|
|
@@ -43220,6 +43300,8 @@ function codexInstallationRoots(binding) {
|
|
|
43220
43300
|
});
|
|
43221
43301
|
}
|
|
43222
43302
|
function assertMarketplaceBinding(binding, source) {
|
|
43303
|
+
if (source.hashMode === "sumi-settings-v1" && (binding.agent !== "sumi" || binding.method !== "reviewed" || basename8(source.path) !== "sumi.json"))
|
|
43304
|
+
throw new Error("Sumi settings witnesses require explicit reviewed Sumi configuration");
|
|
43223
43305
|
if ((source.hashMode === "codex-settings-v1" || source.hashMode === "codex-settings-v2" || (source.hashMode === "codex-settings-v3" || source.hashMode === "codex-settings-v4")) && (binding.agent !== "codex" || binding.method !== "reviewed" || basename8(source.path) !== "config.toml"))
|
|
43224
43306
|
throw new Error("Codex settings witnesses require explicit reviewed Codex configuration");
|
|
43225
43307
|
if ((source.hashMode === "claude-settings-v1" || source.hashMode === "claude-settings-v2" || source.hashMode === "claude-settings-v3") && (binding.agent !== "claude" || binding.method !== "reviewed" || basename8(source.path) !== "settings.json"))
|
|
@@ -43228,13 +43310,13 @@ function assertMarketplaceBinding(binding, source) {
|
|
|
43228
43310
|
throw new Error("Claude marketplace witnesses require explicit reviewed Claude discovery");
|
|
43229
43311
|
}
|
|
43230
43312
|
function rebindAgentDiscovery(binding, changes) {
|
|
43231
|
-
const
|
|
43313
|
+
const budget2 = discoveryByteBudget();
|
|
43232
43314
|
const installationRoots = codexInstallationRoots(binding), absentRoots = [...absentCodexSkillRoots(binding), ...absentRetiredClaudeRoots(binding), ...retiredCodexRoots(binding).filter((root2) => !lstatSync21(root2, { throwIfNoEntry: false }))];
|
|
43233
43315
|
const rebound = { ...binding, sources: binding.sources.map((source) => {
|
|
43234
43316
|
assertMarketplaceBinding(binding, source);
|
|
43235
43317
|
if (!changes.has(source.path) && (installationRoots.some((root2) => source.path.startsWith(root2 + sep5)) || absentRoots.some((root2) => source.path.startsWith(root2 + sep5)) && source.format === undefined && source.fields === undefined && source.managedPlugins === undefined && [undefined, "bytes"].includes(source.hashMode)))
|
|
43236
43318
|
return source;
|
|
43237
|
-
const sha2562 = projected(source, changes,
|
|
43319
|
+
const sha2562 = projected(source, changes, budget2);
|
|
43238
43320
|
if (!changes.has(source.path) && sha2562 !== source.sha256)
|
|
43239
43321
|
throw new Error(`Native discovery input changed; run skills hook install with a fresh discovery review: ${source.path}`);
|
|
43240
43322
|
return { ...source, sha256: sha2562 };
|
|
@@ -43249,14 +43331,14 @@ function rebindAgentDiscovery(binding, changes) {
|
|
|
43249
43331
|
function captureDiscoveryByteSources(paths) {
|
|
43250
43332
|
if (!Array.isArray(paths) || paths.length > AGENT_POLICY_LIMITS.discoverySources || new Set(paths).size !== paths.length)
|
|
43251
43333
|
throw new Error("Invalid raw discovery source collection");
|
|
43252
|
-
const
|
|
43253
|
-
return paths.map((path) => ({ path, hashMode: "bytes", sha256: hashRawDiscoveryFile(path,
|
|
43334
|
+
const budget2 = discoveryByteBudget();
|
|
43335
|
+
return paths.map((path) => ({ path, hashMode: "bytes", sha256: hashRawDiscoveryFile(path, budget2) }));
|
|
43254
43336
|
}
|
|
43255
43337
|
function captureDiscoveryPathSources(paths) {
|
|
43256
43338
|
if (!Array.isArray(paths) || paths.length > AGENT_POLICY_LIMITS.discoverySources || new Set(paths).size !== paths.length)
|
|
43257
43339
|
throw new Error("Invalid path discovery source collection");
|
|
43258
|
-
const
|
|
43259
|
-
return paths.map((path) => ({ path, hashMode: "path-bytes", sha256: hashDiscoveryPathFile(path,
|
|
43340
|
+
const budget2 = discoveryByteBudget();
|
|
43341
|
+
return paths.map((path) => ({ path, hashMode: "path-bytes", sha256: hashDiscoveryPathFile(path, budget2) }));
|
|
43260
43342
|
}
|
|
43261
43343
|
function assertProjectDiscovery(agent, directories, home, canonical6 = resolve17, reviewed) {
|
|
43262
43344
|
const homeConfigPath = canonical6(agentDiscoveryConfigPath(home, agent));
|
|
@@ -43324,7 +43406,7 @@ function resolveAgentDiscovery(options) {
|
|
|
43324
43406
|
if (agent === "hermes")
|
|
43325
43407
|
assertHermesEnvironment(home);
|
|
43326
43408
|
const configPath = agentDiscoveryConfigPath(home, agent);
|
|
43327
|
-
const configText = witness(configPath, agent === "hermes" ? "yaml" : agent === "codex" ? "toml" : "json", agent === "hermes" ? ["skills", "plugins", "hooks"] : agent === "claude" ? ["enabledPlugins", "extraKnownMarketplaces"] : agent === "codex" ? [...CODEX_DISCOVERY_PROJECTION_FIELDS] : agent === "gemini" ? ["skills", "extensions", "security"] : agent === "opencode" ? ["plugin", "skills"] : agent === "sumi" ? [
|
|
43409
|
+
const configText = witness(configPath, agent === "hermes" ? "yaml" : agent === "codex" ? "toml" : "json", agent === "hermes" ? ["skills", "plugins", "hooks"] : agent === "claude" ? ["enabledPlugins", "extraKnownMarketplaces"] : agent === "codex" ? [...CODEX_DISCOVERY_PROJECTION_FIELDS] : agent === "gemini" ? ["skills", "extensions", "security"] : agent === "opencode" ? ["plugin", "skills"] : agent === "sumi" ? [...SUMI_DISCOVERY_PROJECTION_FIELDS] : ["version"]);
|
|
43328
43410
|
const config = configText === null ? {} : agent === "hermes" ? parseHermesConfig(configText) : parseConfig(configText, configPath, agent === "codex");
|
|
43329
43411
|
const unresolved = (detail) => {
|
|
43330
43412
|
throw new Error(`Native discovery is unresolved (${agent}: ${detail}); provide a reviewed --discovery-inputs file`);
|
|
@@ -43421,9 +43503,9 @@ function resolveAgentDiscovery(options) {
|
|
|
43421
43503
|
verifyAgentDiscovery(retained);
|
|
43422
43504
|
if (!retained.sources.some((source) => source.path === canonical6(configPath) && source.format === undefined && source.fields === undefined))
|
|
43423
43505
|
unresolved("retained review is missing the full agent configuration source");
|
|
43424
|
-
if (retained.sources.some((source) => (source.hashMode === "claude-settings-v1" || source.hashMode === "claude-settings-v2" || (source.hashMode === "claude-settings-v3" || (source.hashMode === "codex-settings-v1" || source.hashMode === "codex-settings-v2" || (source.hashMode === "codex-settings-v3" || source.hashMode === "codex-settings-v4")))) && source.path !== canonical6(configPath)))
|
|
43506
|
+
if (retained.sources.some((source) => (source.hashMode === "sumi-settings-v1" || source.hashMode === "claude-settings-v1" || source.hashMode === "claude-settings-v2" || (source.hashMode === "claude-settings-v3" || (source.hashMode === "codex-settings-v1" || source.hashMode === "codex-settings-v2" || (source.hashMode === "codex-settings-v3" || source.hashMode === "codex-settings-v4")))) && source.path !== canonical6(configPath)))
|
|
43425
43507
|
unresolved("retained settings witness names another configuration source");
|
|
43426
|
-
const covered =
|
|
43508
|
+
const covered = supersedesSettingsProjection(agent, retained.sources, canonical6(configPath)) ? sources.filter((source) => !isSupersededSettingsProjection(agent, canonical6(configPath), source)) : sources;
|
|
43427
43509
|
if (covered.some((source) => !retained.sources.some((saved) => isDeepStrictEqual6(saved, source))) || [...roots].some((root2) => !retained.roots.includes(root2)) || agent === "gemini" && JSON.stringify(retained.builtinNames) !== JSON.stringify(builtinNames))
|
|
43428
43510
|
unresolved("retained review is missing current runtime discovery coverage");
|
|
43429
43511
|
return retained;
|
|
@@ -43438,11 +43520,11 @@ function resolveAgentDiscovery(options) {
|
|
|
43438
43520
|
if (review.sources.some((source) => source.format !== undefined || source.fields !== undefined))
|
|
43439
43521
|
throw new Error("Explicit discovery reviews require full source-file hashes");
|
|
43440
43522
|
verifyAgentDiscovery(supplied);
|
|
43441
|
-
if (review.sources.some((source) => (source.hashMode === "claude-settings-v1" || source.hashMode === "claude-settings-v2" || (source.hashMode === "claude-settings-v3" || (source.hashMode === "codex-settings-v1" || source.hashMode === "codex-settings-v2" || (source.hashMode === "codex-settings-v3" || source.hashMode === "codex-settings-v4")))) && source.path !== canonical6(configPath)))
|
|
43442
|
-
throw new Error("Semantic settings witnesses must name the configured
|
|
43523
|
+
if (review.sources.some((source) => (source.hashMode === "sumi-settings-v1" || source.hashMode === "claude-settings-v1" || source.hashMode === "claude-settings-v2" || (source.hashMode === "claude-settings-v3" || (source.hashMode === "codex-settings-v1" || source.hashMode === "codex-settings-v2" || (source.hashMode === "codex-settings-v3" || source.hashMode === "codex-settings-v4")))) && source.path !== canonical6(configPath)))
|
|
43524
|
+
throw new Error("Semantic settings witnesses must name the configured agent configuration source");
|
|
43443
43525
|
if (!review.sources.some((source) => source.path === canonical6(configPath)))
|
|
43444
43526
|
throw new Error("Discovery review must include the agent configuration source");
|
|
43445
|
-
const reviewedSources =
|
|
43527
|
+
const reviewedSources = supersedesSettingsProjection(agent, review.sources, canonical6(configPath)) ? sources.filter((source) => !isSupersededSettingsProjection(agent, canonical6(configPath), source)) : sources;
|
|
43446
43528
|
return { ...supplied, roots: [...new Set([...roots, ...supplied.roots])].sort(), sources: [...reviewedSources, ...review.sources], ...agent === "gemini" ? { builtinNames } : {} };
|
|
43447
43529
|
}
|
|
43448
43530
|
function plugin(root2) {
|
|
@@ -43894,7 +43976,7 @@ function disableCodexBundledSkills(text2) {
|
|
|
43894
43976
|
}
|
|
43895
43977
|
|
|
43896
43978
|
// src/lib/agent-integration.ts
|
|
43897
|
-
var sha4 = (data) =>
|
|
43979
|
+
var sha4 = (data) => createHash22("sha256").update(data).digest("hex");
|
|
43898
43980
|
var ROOTS = NATIVE_SKILL_ROOTS;
|
|
43899
43981
|
function hasTrustedDarwinAcl(fd, allowDenyOnly = false) {
|
|
43900
43982
|
try {
|
|
@@ -44088,7 +44170,7 @@ function readNativeBytes(path, maximum = 64 * 1024 * 1024) {
|
|
|
44088
44170
|
}
|
|
44089
44171
|
}
|
|
44090
44172
|
function treeHash(root2) {
|
|
44091
|
-
const hash2 =
|
|
44173
|
+
const hash2 = createHash22("sha256");
|
|
44092
44174
|
let bytes = 0, files = 0;
|
|
44093
44175
|
function visit2(path) {
|
|
44094
44176
|
const stat2 = lstatSync22(path);
|
|
@@ -44582,7 +44664,7 @@ function planAgentIntegration(options) {
|
|
|
44582
44664
|
const pluginPath = join26(sumiConfigDirectory(home), "plugins", "skills-cli.js"), pluginBefore = readOptional(pluginPath);
|
|
44583
44665
|
const pluginAfter = renderSumiPlugin(command, profileId2);
|
|
44584
44666
|
const priorCommand = policy.bridge?.commands?.sumi, priorProfile = policy.bridge?.profiles?.sumi ?? policy.profileId;
|
|
44585
|
-
if (pluginBefore !== null && pluginBefore !== pluginAfter && !(typeof priorCommand === "string" && typeof priorProfile === "string" && pluginBefore
|
|
44667
|
+
if (pluginBefore !== null && pluginBefore !== pluginAfter && !(typeof priorCommand === "string" && typeof priorProfile === "string" && isManagedSumiPlugin(pluginBefore, priorCommand, priorProfile)))
|
|
44586
44668
|
throw new Error("Refusing to overwrite a modified Sumi Skills plugin; preserve and review it first");
|
|
44587
44669
|
if (pluginBefore !== pluginAfter)
|
|
44588
44670
|
changes.push({ path: pluginPath, before: pluginBefore, after: pluginAfter });
|
|
@@ -44936,7 +45018,7 @@ function planAgentSettingsWitnessUpgrade(options) {
|
|
|
44936
45018
|
const binding = policy.bridge?.discovery?.[options.agent];
|
|
44937
45019
|
if (!binding || binding.agent !== options.agent || binding.method !== "reviewed")
|
|
44938
45020
|
throw new Error("Settings witness upgrade requires an existing reviewed native binding");
|
|
44939
|
-
const configPath = canonicalAgentPath(join26(home, options.agent === "claude" ? ".claude/settings.json" : ".codex/config.toml"), aliases);
|
|
45021
|
+
const configPath = canonicalAgentPath(options.agent === "sumi" ? sumiConfigPath(home) : join26(home, options.agent === "claude" ? ".claude/settings.json" : ".codex/config.toml"), aliases);
|
|
44940
45022
|
const settings = readOptional(configPath);
|
|
44941
45023
|
if (settings === null || sha4(settings) !== options.expectedSettingsSha256)
|
|
44942
45024
|
throw new Error("Native settings preimage changed");
|
|
@@ -44962,7 +45044,19 @@ function planAgentSettingsWitnessUpgrade(options) {
|
|
|
44962
45044
|
replaced.push(source);
|
|
44963
45045
|
}
|
|
44964
45046
|
}
|
|
44965
|
-
|
|
45047
|
+
if (options.agent === "sumi") {
|
|
45048
|
+
const preimage = readSumiSettingsPreimage(options.reviewedPreimage);
|
|
45049
|
+
for (const source of binding.sources) {
|
|
45050
|
+
if (source === previous || source.path !== configPath)
|
|
45051
|
+
continue;
|
|
45052
|
+
if (source.hashMode !== undefined || source.format !== "json" || !isDeepStrictEqual8(source.fields, [...SUMI_DISCOVERY_PROJECTION_FIELDS]) || typeof source.sha256 !== "string")
|
|
45053
|
+
throw new Error("Sumi settings witness upgrade found an unrecognized configuration witness");
|
|
45054
|
+
if (projectNativeDiscoveryFields(preimage, "json", source.fields, configPath) !== source.sha256)
|
|
45055
|
+
throw new Error("Reviewed preimage does not explain the Sumi discovery projection witness");
|
|
45056
|
+
replaced.push(source);
|
|
45057
|
+
}
|
|
45058
|
+
}
|
|
45059
|
+
const next = options.agent === "sumi" ? upgradeSumiSettingsWitness(previous, options.reviewedPreimage) : options.agent === "claude" ? upgradeClaudeSettingsWitness(previous, options.reviewedPreimage) : options.targetCodexVersion === 4 ? upgradeCodexSettingsWitnessV4(previous, options.reviewedPreimage) : options.targetCodexVersion === 3 ? upgradeCodexSettingsWitnessV3(previous, options.reviewedPreimage) : upgradeCodexSettingsWitness(previous, options.reviewedPreimage);
|
|
44966
45060
|
const rebound = [];
|
|
44967
45061
|
for (const source of binding.sources) {
|
|
44968
45062
|
if (!replaced.includes(source)) {
|
|
@@ -45323,7 +45417,7 @@ function assertManagedAgentBridgeWithDiscovery(agent, options = {}, provenDiscov
|
|
|
45323
45417
|
throw new Error("NATIVE_SKILL_DRIFT: Hermes supervisor binding changed; run skills hook install");
|
|
45324
45418
|
assertHermesProtection(home, config, command, profile, supervisor);
|
|
45325
45419
|
} else if (agent === "sumi") {
|
|
45326
|
-
if (JSON.stringify(config.permissions?.filter((rule) => rule.action === "skill")) !== JSON.stringify(SUMI_SKILL_PERMISSIONS) || readOptional(join26(sumiConfigDirectory(home), "plugins", "skills-cli.js"))
|
|
45420
|
+
if (JSON.stringify(config.permissions?.filter((rule) => rule.action === "skill")) !== JSON.stringify(SUMI_SKILL_PERMISSIONS) || !isManagedSumiPlugin(readOptional(join26(sumiConfigDirectory(home), "plugins", "skills-cli.js")), command, profile))
|
|
45327
45421
|
throw new Error("NATIVE_SKILL_DRIFT: Sumi bridge protection changed; run skills hook install");
|
|
45328
45422
|
} else if (agent === "opencode") {
|
|
45329
45423
|
if (JSON.stringify(config.permission?.skill) !== JSON.stringify({ "*": "deny", [CLI_BRIDGE_NAME]: "allow" }) || readOptional(join26(home, ".config", "opencode", "plugins", "skills-cli.js")) !== renderOpenCodePlugin(command, profile))
|
|
@@ -45457,7 +45551,7 @@ import { basename as basename11, dirname as dirname20, isAbsolute as isAbsolute2
|
|
|
45457
45551
|
var SKILLS = [];
|
|
45458
45552
|
|
|
45459
45553
|
// src/lib/skill-hash.ts
|
|
45460
|
-
import { createHash as
|
|
45554
|
+
import { createHash as createHash23 } from "crypto";
|
|
45461
45555
|
import { existsSync as existsSync8, readdirSync as readdirSync9, readFileSync as readFileSync17, statSync as statSync8 } from "fs";
|
|
45462
45556
|
import { join as join27, sep as sep7 } from "path";
|
|
45463
45557
|
var CONTENT_HASH_ALGORITHM = "sha256";
|
|
@@ -45581,13 +45675,13 @@ function* bundleHashParts(files) {
|
|
|
45581
45675
|
yield new TextEncoder().encode("\x00");
|
|
45582
45676
|
}
|
|
45583
45677
|
function hashBundleFiles(files) {
|
|
45584
|
-
const hash2 =
|
|
45678
|
+
const hash2 = createHash23(CONTENT_HASH_ALGORITHM);
|
|
45585
45679
|
for (const part of bundleHashParts(files))
|
|
45586
45680
|
hash2.update(part);
|
|
45587
45681
|
return hash2.digest("hex");
|
|
45588
45682
|
}
|
|
45589
45683
|
async function hashBundleFilesCooperatively(files, check) {
|
|
45590
|
-
const hash2 =
|
|
45684
|
+
const hash2 = createHash23(CONTENT_HASH_ALGORITHM);
|
|
45591
45685
|
let bytesSinceYield = 0;
|
|
45592
45686
|
for (const part of bundleHashParts(files)) {
|
|
45593
45687
|
for (let offset = 0;offset < part.byteLength; offset += 64 * 1024) {
|
|
@@ -48836,7 +48930,7 @@ async function executeSelectedLocal(selected, options = {}) {
|
|
|
48836
48930
|
selection: selection2,
|
|
48837
48931
|
target: "local",
|
|
48838
48932
|
runtime: runtimeName,
|
|
48839
|
-
inputDigest: `sha256:${
|
|
48933
|
+
inputDigest: `sha256:${createHash24("sha256").update(input).digest("hex")}`,
|
|
48840
48934
|
runDirectory,
|
|
48841
48935
|
...executionGrant ? { executionGrant } : {},
|
|
48842
48936
|
...bindings ? { secretBinding: { schema: bindings.schema, selection: bindings.selection, consumer: bindings.consumer, secretsAuthority: bindings.secretsAuthority, bindings: bindings.bindings } } : {},
|
|
@@ -58126,7 +58220,7 @@ var import_node_http_handler2 = __toESM(require_dist_cjs6(), 1);
|
|
|
58126
58220
|
|
|
58127
58221
|
// node_modules/@aws-sdk/checksums/dist-cjs/submodules/sha/index.js
|
|
58128
58222
|
var { toUint8Array: toUint8Array2, concatBytes } = require_serde();
|
|
58129
|
-
var { createHmac: createHmac2, createHash:
|
|
58223
|
+
var { createHmac: createHmac2, createHash: createHash26 } = __require("crypto");
|
|
58130
58224
|
var { Sha256: Sha2562, Sha256Js, Sha256Node } = require_checksum();
|
|
58131
58225
|
var BLOCK2 = 64;
|
|
58132
58226
|
var DIGEST_LENGTH = 20;
|
|
@@ -58295,7 +58389,7 @@ class Sha1Js {
|
|
|
58295
58389
|
}
|
|
58296
58390
|
var hasNativeCrypto = (() => {
|
|
58297
58391
|
try {
|
|
58298
|
-
|
|
58392
|
+
createHash26("sha1");
|
|
58299
58393
|
return true;
|
|
58300
58394
|
} catch {
|
|
58301
58395
|
return false;
|
|
@@ -58335,7 +58429,7 @@ function buildNativeClass() {
|
|
|
58335
58429
|
this.finished = false;
|
|
58336
58430
|
}
|
|
58337
58431
|
createHash() {
|
|
58338
|
-
return this.secret ? createHmac2("sha1", toBuffer(this.secret)) :
|
|
58432
|
+
return this.secret ? createHmac2("sha1", toBuffer(this.secret)) : createHash26("sha1");
|
|
58339
58433
|
}
|
|
58340
58434
|
};
|
|
58341
58435
|
}
|
|
@@ -59203,9 +59297,9 @@ import { mkdirSync as mkdirSync12, readFileSync as readFileSync25, readdirSync a
|
|
|
59203
59297
|
import { dirname as dirname25, join as join40 } from "path";
|
|
59204
59298
|
|
|
59205
59299
|
// src/server/auth.ts
|
|
59206
|
-
import { createHash as
|
|
59300
|
+
import { createHash as createHash27 } from "crypto";
|
|
59207
59301
|
function hashApiKey(token) {
|
|
59208
|
-
return
|
|
59302
|
+
return createHash27("sha256").update(token).digest("hex");
|
|
59209
59303
|
}
|
|
59210
59304
|
function bearerToken(request2) {
|
|
59211
59305
|
const header = request2.headers.get("authorization") || "";
|
|
@@ -59527,7 +59621,7 @@ function validOperatorScopeEnrollmentInput(input) {
|
|
|
59527
59621
|
}
|
|
59528
59622
|
|
|
59529
59623
|
// src/lib/revision.ts
|
|
59530
|
-
import { createHash as
|
|
59624
|
+
import { createHash as createHash28 } from "crypto";
|
|
59531
59625
|
var REVISION_ID_PATTERN = /^[0-9a-f]{64}$/;
|
|
59532
59626
|
function revisionIdOf(content) {
|
|
59533
59627
|
const canonicalContent = {
|
|
@@ -59549,7 +59643,7 @@ function revisionIdOf(content) {
|
|
|
59549
59643
|
canonicalContent.replacementSlug = content.replacementSlug ?? null;
|
|
59550
59644
|
}
|
|
59551
59645
|
const canonical6 = JSON.stringify(canonicalContent);
|
|
59552
|
-
return
|
|
59646
|
+
return createHash28("sha256").update(canonical6).digest("hex");
|
|
59553
59647
|
}
|
|
59554
59648
|
function revisionIdOfRecord(record4) {
|
|
59555
59649
|
return revisionIdOf(record4);
|
|
@@ -60633,7 +60727,7 @@ function nextMonthPrefix(monthPrefix) {
|
|
|
60633
60727
|
}
|
|
60634
60728
|
|
|
60635
60729
|
// src/server/skills-api.ts
|
|
60636
|
-
import { createHash as
|
|
60730
|
+
import { createHash as createHash29 } from "crypto";
|
|
60637
60731
|
var SLUG_PATTERN = /^[a-z0-9][a-z0-9._-]*$/;
|
|
60638
60732
|
var SHA256_HEX2 = /^[0-9a-f]{64}$/;
|
|
60639
60733
|
var MAX_SLUG_LENGTH = 128;
|
|
@@ -60823,7 +60917,7 @@ async function parsePublishRequest(request2, config) {
|
|
|
60823
60917
|
if (bundleBytes.byteLength === 0) {
|
|
60824
60918
|
throw new SkillRequestError(400, "BUNDLE_EMPTY", "the uploaded bundle is empty");
|
|
60825
60919
|
}
|
|
60826
|
-
const sha2562 =
|
|
60920
|
+
const sha2562 = createHash29("sha256").update(bundleBytes).digest("hex");
|
|
60827
60921
|
const claimed = optionalString(manifest.bundleSha256);
|
|
60828
60922
|
if (claimed)
|
|
60829
60923
|
assertSha2562(claimed);
|
|
@@ -60938,7 +61032,7 @@ async function readPublishedBundle(store, artifactStorage, principal, slug) {
|
|
|
60938
61032
|
if (!bytes) {
|
|
60939
61033
|
throw new SkillRequestError(503, "BUNDLE_BACKEND_UNAVAILABLE", "bundle storage backend unavailable");
|
|
60940
61034
|
}
|
|
60941
|
-
const actual =
|
|
61035
|
+
const actual = createHash29("sha256").update(bytes).digest("hex");
|
|
60942
61036
|
if (actual !== record4.bundleSha256) {
|
|
60943
61037
|
throw new SkillRequestError(500, "BUNDLE_DIGEST_DRIFT", `stored bundle for '${slug}' hashes to ${actual} but was published as ${record4.bundleSha256}`);
|
|
60944
61038
|
}
|
|
@@ -61086,7 +61180,7 @@ async function readSkillVersionBundle(store, artifactStorage, principal, slug, v
|
|
|
61086
61180
|
const bytes = await artifactStorage.readBundle(bundle2);
|
|
61087
61181
|
if (!bytes)
|
|
61088
61182
|
throw new SkillRequestError(503, "BUNDLE_BACKEND_UNAVAILABLE", "bundle storage backend unavailable");
|
|
61089
|
-
const actual =
|
|
61183
|
+
const actual = createHash29("sha256").update(bytes).digest("hex");
|
|
61090
61184
|
if (actual !== found.bundleSha256) {
|
|
61091
61185
|
throw new SkillRequestError(500, "BUNDLE_DIGEST_DRIFT", `stored bundle for '${slug}@${version2}' hashes to ${actual} but was published as ${found.bundleSha256}`);
|
|
61092
61186
|
}
|
|
@@ -61789,7 +61883,7 @@ class RuntimeExecutionStore {
|
|
|
61789
61883
|
}
|
|
61790
61884
|
|
|
61791
61885
|
// src/sdk/execution/admission.ts
|
|
61792
|
-
import { createHash as
|
|
61886
|
+
import { createHash as createHash31 } from "crypto";
|
|
61793
61887
|
|
|
61794
61888
|
// src/sdk/execution/image-profile.ts
|
|
61795
61889
|
class ImageProfileResolutionError extends Error {
|
|
@@ -62401,11 +62495,11 @@ function ownedAdmission(admission) {
|
|
|
62401
62495
|
};
|
|
62402
62496
|
}
|
|
62403
62497
|
function digestInput(input) {
|
|
62404
|
-
return
|
|
62498
|
+
return createHash31("sha256").update(canonicalJson2(input)).digest("hex");
|
|
62405
62499
|
}
|
|
62406
62500
|
|
|
62407
62501
|
// src/sdk/execution/dispatchers/ecs.ts
|
|
62408
|
-
import { createHash as
|
|
62502
|
+
import { createHash as createHash32 } from "crypto";
|
|
62409
62503
|
|
|
62410
62504
|
// src/sdk/execution/state-machine.ts
|
|
62411
62505
|
var LEGAL_TRANSITIONS = {
|
|
@@ -65805,13 +65899,13 @@ function observedTask(states, taskArn) {
|
|
|
65805
65899
|
return state2.lastStatus === "STOPPED" || LIVE_TASK_STATUSES.has(state2.lastStatus) ? state2 : undefined;
|
|
65806
65900
|
}
|
|
65807
65901
|
function clientTokenFor(runId3, attemptId) {
|
|
65808
|
-
return
|
|
65902
|
+
return createHash32("sha256").update(`${runId3}\x00${attemptId}`).digest("hex").slice(0, CLIENT_TOKEN_BYTES * 2);
|
|
65809
65903
|
}
|
|
65810
65904
|
function startedByFor(runId3, attemptNumber) {
|
|
65811
65905
|
return `skills-exec/${runId3}/a${attemptNumber}`;
|
|
65812
65906
|
}
|
|
65813
65907
|
function requestDigestFor(admission, attemptId) {
|
|
65814
|
-
return
|
|
65908
|
+
return createHash32("sha256").update(canonicalJson2({ admission, attemptId })).digest("hex");
|
|
65815
65909
|
}
|
|
65816
65910
|
|
|
65817
65911
|
class EcsDispatcher {
|
|
@@ -66107,10 +66201,10 @@ function validText(value) {
|
|
|
66107
66201
|
}
|
|
66108
66202
|
|
|
66109
66203
|
// src/server/runtime-policy.ts
|
|
66110
|
-
import { createHash as
|
|
66204
|
+
import { createHash as createHash34, createHmac as createHmac3, timingSafeEqual as timingSafeEqual2 } from "crypto";
|
|
66111
66205
|
|
|
66112
66206
|
// src/server/runtime-pure-contract.ts
|
|
66113
|
-
import { createHash as
|
|
66207
|
+
import { createHash as createHash33 } from "crypto";
|
|
66114
66208
|
var PURE_DESCRIPTOR = Object.freeze({
|
|
66115
66209
|
id: "regex-test.v1",
|
|
66116
66210
|
runtime: "bun",
|
|
@@ -66134,7 +66228,7 @@ var PURE_LIMITS = Object.freeze({
|
|
|
66134
66228
|
maxArtifactsBytes: 0,
|
|
66135
66229
|
maxConcurrency: 1
|
|
66136
66230
|
});
|
|
66137
|
-
var hash2 = (bytes) =>
|
|
66231
|
+
var hash2 = (bytes) => createHash33("sha256").update(bytes).digest("hex");
|
|
66138
66232
|
var object7 = (v2) => {
|
|
66139
66233
|
if (!v2 || typeof v2 !== "object" || Array.isArray(v2))
|
|
66140
66234
|
throw Error("Pure contract requires an object");
|
|
@@ -66363,7 +66457,7 @@ function verifyRuntimeToken(token, key, admission, attempt, now = Date.now()) {
|
|
|
66363
66457
|
const actual = Buffer.from(token);
|
|
66364
66458
|
return actual.length === expected.length && timingSafeEqual2(actual, expected);
|
|
66365
66459
|
}
|
|
66366
|
-
var hashBytes = (bytes) =>
|
|
66460
|
+
var hashBytes = (bytes) => createHash34("sha256").update(bytes).digest("hex");
|
|
66367
66461
|
|
|
66368
66462
|
// src/server/runtime-api.ts
|
|
66369
66463
|
async function createRuntimeService(options) {
|
|
@@ -72735,7 +72829,7 @@ var localRunExecutor = {
|
|
|
72735
72829
|
// src/sdk/storage.ts
|
|
72736
72830
|
var artifactStorageSeam = ArtifactStorage;
|
|
72737
72831
|
// src/sdk/outputs.ts
|
|
72738
|
-
import { createHash as
|
|
72832
|
+
import { createHash as createHash35 } from "crypto";
|
|
72739
72833
|
class DatabaseOnlyObjectStore {
|
|
72740
72834
|
usesS3 = false;
|
|
72741
72835
|
async materialize(run, artifact, body4) {
|
|
@@ -72782,7 +72876,7 @@ function createGovernedArtifactWriter(options) {
|
|
|
72782
72876
|
const stamped = {
|
|
72783
72877
|
...meta,
|
|
72784
72878
|
byteSize: outputBytes,
|
|
72785
|
-
sha256:
|
|
72879
|
+
sha256: createHash35("sha256").update(persistedBytes).digest("hex"),
|
|
72786
72880
|
visibility: options.visibility ?? config.defaultVisibility,
|
|
72787
72881
|
...config.artifactTtlSeconds !== undefined ? { expiresAt: expiresAtFor(createdAt, config.artifactTtlSeconds) } : {}
|
|
72788
72882
|
};
|
|
@@ -91549,7 +91643,7 @@ function date4(params) {
|
|
|
91549
91643
|
return _coercedDate(ZodDate2, params);
|
|
91550
91644
|
}
|
|
91551
91645
|
// src/lib/canonical-json.ts
|
|
91552
|
-
import { createHash as
|
|
91646
|
+
import { createHash as createHash36 } from "crypto";
|
|
91553
91647
|
function canonicalJson3(value, maximumBytes = 2 * 1024 * 1024) {
|
|
91554
91648
|
return canonicalJsonAtDepth(value, maximumBytes, 64);
|
|
91555
91649
|
}
|
|
@@ -91593,7 +91687,7 @@ function canonicalJsonAtDepth(value, maximumBytes, maximumDepth) {
|
|
|
91593
91687
|
return visit3(value, 0);
|
|
91594
91688
|
}
|
|
91595
91689
|
function canonicalJsonSha256(value, maximumBytes) {
|
|
91596
|
-
return
|
|
91690
|
+
return createHash36("sha256").update(canonicalJson3(value, maximumBytes)).digest("hex");
|
|
91597
91691
|
}
|
|
91598
91692
|
|
|
91599
91693
|
// src/lib/remote-recurring-contract.ts
|
|
@@ -91780,7 +91874,7 @@ function recurringRequest(action, input2) {
|
|
|
91780
91874
|
}
|
|
91781
91875
|
return { path: path2, read: read3, method: read3 ? "GET" : "POST", body: read3 ? undefined : JSON.stringify(action === "preview" ? input2 : action === "activate" ? row.approval : { contractVersion: 1 }) };
|
|
91782
91876
|
}
|
|
91783
|
-
var
|
|
91877
|
+
var budget2 = exports_external2.object({ reservedCredits: integer2, settledCredits: integer2, admittedOccurrences: integer2 });
|
|
91784
91878
|
var period = exports_external2.object({ startsAt: instant2, endsAt: instant2 });
|
|
91785
91879
|
var preview = exports_external2.object({
|
|
91786
91880
|
contractVersion: exports_external2.literal(1),
|
|
@@ -91802,8 +91896,8 @@ var consent = exports_external2.object({
|
|
|
91802
91896
|
state: exports_external2.enum(["active", "revoked", "expired"]),
|
|
91803
91897
|
activatedAt: instant2,
|
|
91804
91898
|
revokedAt: instant2.nullable(),
|
|
91805
|
-
total:
|
|
91806
|
-
currentPeriod:
|
|
91899
|
+
total: budget2,
|
|
91900
|
+
currentPeriod: budget2.extend(period.shape).nullable(),
|
|
91807
91901
|
nextDueAt: instant2.nullable()
|
|
91808
91902
|
});
|
|
91809
91903
|
var refusal3 = exports_external2.enum([
|
|
@@ -93707,7 +93801,7 @@ async function requestInvitationEmail(origin, action, input2) {
|
|
|
93707
93801
|
}
|
|
93708
93802
|
|
|
93709
93803
|
// src/lib/remote-private-publications.ts
|
|
93710
|
-
import { createHash as
|
|
93804
|
+
import { createHash as createHash37 } from "crypto";
|
|
93711
93805
|
var PRIVATE_PUBLICATION_MAX_BYTES = 16 * 1024 * 1024;
|
|
93712
93806
|
var failures2 = {
|
|
93713
93807
|
INVALID_REQUEST: [400, "The publication request is invalid."],
|
|
@@ -93754,7 +93848,7 @@ var hash4 = (v2) => typeof v2 === "string" && /^[a-f0-9]{64}$/.test(v2);
|
|
|
93754
93848
|
var record10 = (v2) => !!v2 && typeof v2 === "object" && !Array.isArray(v2);
|
|
93755
93849
|
var exact = (v2, keys3) => record10(v2) && Object.keys(v2).sort().join(",") === keys3.sort().join(",");
|
|
93756
93850
|
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));
|
|
93757
|
-
var publicationSha256 = (bytes) =>
|
|
93851
|
+
var publicationSha256 = (bytes) => createHash37("sha256").update(bytes).digest("hex");
|
|
93758
93852
|
function checkedPublicationDeclaration(value) {
|
|
93759
93853
|
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)
|
|
93760
93854
|
return bad();
|
|
@@ -93774,7 +93868,7 @@ function checkedPublicationView(value, skillId, intentId, declaration) {
|
|
|
93774
93868
|
return invalid7();
|
|
93775
93869
|
return Object.freeze({ ...value });
|
|
93776
93870
|
}
|
|
93777
|
-
async function boundedJson(url2, init, token, mutation,
|
|
93871
|
+
async function boundedJson(url2, init, token, mutation, budget3 = 15000, signal) {
|
|
93778
93872
|
const controller = new AbortController;
|
|
93779
93873
|
let reader;
|
|
93780
93874
|
let response;
|
|
@@ -93829,7 +93923,7 @@ async function boundedJson(url2, init, token, mutation, budget2 = 15000, signal)
|
|
|
93829
93923
|
controller.abort();
|
|
93830
93924
|
reject(timeout);
|
|
93831
93925
|
};
|
|
93832
|
-
timer = setTimeout(abort, Math.max(1, Math.min(15000,
|
|
93926
|
+
timer = setTimeout(abort, Math.max(1, Math.min(15000, budget3)));
|
|
93833
93927
|
signal?.addEventListener("abort", abort, { once: true });
|
|
93834
93928
|
})]);
|
|
93835
93929
|
} catch (error61) {
|