@hasna/skills 0.10.48 → 0.10.50
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 +66 -1
- package/bin/index.js +1137 -667
- package/bin/maintenance.js +18 -0
- package/bin/mcp.js +88 -11
- package/bin/migrate.js +19 -1
- package/bin/server.js +19 -1
- package/bin/worker.js +19 -1
- package/dist/cli/commands/runtime-launcher.d.ts +102 -0
- package/dist/cli/commands/runtime.d.ts +7 -0
- package/dist/cli/index.d.ts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +452 -272
- package/dist/lib/agent-discovery.d.ts +1 -1
- package/dist/lib/agent-integration.d.ts +1 -0
- package/dist/lib/claude-settings-witness.d.ts +19 -0
- package/dist/lib/launch-cwd-apply.d.ts +1 -0
- package/dist/lib/launch-cwd.d.ts +5 -0
- package/dist/lib/self-spawn.d.ts +21 -0
- package/dist/mcp/index.d.ts +1 -0
- package/dist/sdk/index.js +433 -255
- package/dist/server/index.d.ts +1 -1
- package/dist/server/maintenance.d.ts +1 -1
- package/dist/server/migrate.d.ts +17 -0
- package/dist/server/worker.d.ts +1 -0
- package/docs/plugin-admission.md +39 -2
- 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: sep11, join: join4 } = __require("path");
|
|
9007
|
-
var { createHash:
|
|
9007
|
+
var { createHash: createHash27 } = __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 = createHash27("sha1");
|
|
9163
9163
|
const cacheName = hasher.update(id2).digest("hex");
|
|
9164
9164
|
return join4(getHomeDir(), ".aws", "sso", "cache", `${cacheName}.json`);
|
|
9165
9165
|
};
|
|
@@ -9311,11 +9311,11 @@ var require_config = __commonJS((exports) => {
|
|
|
9311
9311
|
};
|
|
9312
9312
|
function getSelectorName(functionString) {
|
|
9313
9313
|
try {
|
|
9314
|
-
const
|
|
9315
|
-
|
|
9316
|
-
|
|
9317
|
-
|
|
9318
|
-
return [...
|
|
9314
|
+
const constants16 = new Set(Array.from(functionString.match(/([A-Z_]){3,}/g) ?? []));
|
|
9315
|
+
constants16.delete("CONFIG");
|
|
9316
|
+
constants16.delete("CONFIG_PREFIX_SEPARATOR");
|
|
9317
|
+
constants16.delete("ENV");
|
|
9318
|
+
return [...constants16].join(", ");
|
|
9319
9319
|
} catch (ignored) {
|
|
9320
9320
|
return functionString;
|
|
9321
9321
|
}
|
|
@@ -10511,10 +10511,10 @@ 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: createHash27, getRandomValues } = __require("crypto");
|
|
10515
10515
|
var { hasOwn: hasOwn2, HttpResponse } = require_transport();
|
|
10516
10516
|
exports.hasOwn = hasOwn2;
|
|
10517
|
-
var { ReadStream, lstatSync:
|
|
10517
|
+
var { ReadStream, lstatSync: lstatSync27, fstatSync: fstatSync4 } = __require("fs");
|
|
10518
10518
|
var { toEndpointV1 } = require_endpoints();
|
|
10519
10519
|
var { Readable, Writable, PassThrough } = __require("stream");
|
|
10520
10520
|
var isArrayBuffer = (arg) => typeof ArrayBuffer === "function" && arg instanceof ArrayBuffer || Object.prototype.toString.call(arg) === "[object ArrayBuffer]";
|
|
@@ -11280,7 +11280,7 @@ var require_serde = __commonJS((exports) => {
|
|
|
11280
11280
|
return body.end + 1 - body.start;
|
|
11281
11281
|
} else if (body instanceof ReadStream) {
|
|
11282
11282
|
if (body.path != null) {
|
|
11283
|
-
return
|
|
11283
|
+
return lstatSync27(body.path).size;
|
|
11284
11284
|
} else if (typeof body.fd === "number") {
|
|
11285
11285
|
return fstatSync4(body.fd).size;
|
|
11286
11286
|
}
|
|
@@ -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)) : createHash27(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: createHash27, 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
|
+
createHash27("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 = createHash27("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 = createHash27("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
|
+
createHash27("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)) : createHash27("sha256");
|
|
12673
12673
|
}
|
|
12674
12674
|
};
|
|
12675
12675
|
}
|
|
@@ -12730,9 +12730,9 @@ var require_checksum = __commonJS((exports) => {
|
|
|
12730
12730
|
const hash2 = await subtle.digest("SHA-256", data);
|
|
12731
12731
|
return new Uint8Array(hash2);
|
|
12732
12732
|
}
|
|
12733
|
-
const
|
|
12734
|
-
|
|
12735
|
-
return
|
|
12733
|
+
const sha2563 = new Sha256Js(this.secret);
|
|
12734
|
+
sha2563.update(data);
|
|
12735
|
+
return sha2563.digest();
|
|
12736
12736
|
}
|
|
12737
12737
|
reset() {
|
|
12738
12738
|
this.pending = [];
|
|
@@ -18071,9 +18071,9 @@ var require_dist_cjs3 = __commonJS((exports) => {
|
|
|
18071
18071
|
sha256;
|
|
18072
18072
|
uriEscapePath;
|
|
18073
18073
|
applyChecksum;
|
|
18074
|
-
constructor({ applyChecksum, credentials, region, service, sha256:
|
|
18074
|
+
constructor({ applyChecksum, credentials, region, service, sha256: sha2563, uriEscapePath = true }) {
|
|
18075
18075
|
this.service = service;
|
|
18076
|
-
this.sha256 =
|
|
18076
|
+
this.sha256 = sha2563;
|
|
18077
18077
|
this.uriEscapePath = uriEscapePath;
|
|
18078
18078
|
this.applyChecksum = typeof applyChecksum === "boolean" ? applyChecksum : true;
|
|
18079
18079
|
this.regionProvider = normalizeProvider2(region);
|
|
@@ -18240,13 +18240,13 @@ ${toHex(hashedRequest)}`;
|
|
|
18240
18240
|
|
|
18241
18241
|
class SignatureV4 extends SignatureV4Base {
|
|
18242
18242
|
headerFormatter = new HeaderFormatter;
|
|
18243
|
-
constructor({ applyChecksum, credentials, region, service, sha256:
|
|
18243
|
+
constructor({ applyChecksum, credentials, region, service, sha256: sha2563, uriEscapePath = true }) {
|
|
18244
18244
|
super({
|
|
18245
18245
|
applyChecksum,
|
|
18246
18246
|
credentials,
|
|
18247
18247
|
region,
|
|
18248
18248
|
service,
|
|
18249
|
-
sha256:
|
|
18249
|
+
sha256: sha2563,
|
|
18250
18250
|
uriEscapePath
|
|
18251
18251
|
});
|
|
18252
18252
|
}
|
|
@@ -24474,7 +24474,7 @@ var require_httpAuthSchemes = __commonJS((exports) => {
|
|
|
24474
24474
|
configurable: true
|
|
24475
24475
|
});
|
|
24476
24476
|
config.credentials = inputCredentials;
|
|
24477
|
-
const { signingEscapePath = true, systemClockOffset = config.systemClockOffset || 0, sha256:
|
|
24477
|
+
const { signingEscapePath = true, systemClockOffset = config.systemClockOffset || 0, sha256: sha2563 } = config;
|
|
24478
24478
|
let signer;
|
|
24479
24479
|
if (config.signer) {
|
|
24480
24480
|
signer = normalizeProvider2(config.signer);
|
|
@@ -24494,7 +24494,7 @@ var require_httpAuthSchemes = __commonJS((exports) => {
|
|
|
24494
24494
|
credentials: config.credentials,
|
|
24495
24495
|
region: config.signingRegion,
|
|
24496
24496
|
service: config.signingName,
|
|
24497
|
-
sha256:
|
|
24497
|
+
sha256: sha2563,
|
|
24498
24498
|
uriEscapePath: signingEscapePath
|
|
24499
24499
|
};
|
|
24500
24500
|
const SignerCtor = config.signerConstructor || SignatureV4;
|
|
@@ -24517,7 +24517,7 @@ var require_httpAuthSchemes = __commonJS((exports) => {
|
|
|
24517
24517
|
credentials: config.credentials,
|
|
24518
24518
|
region: config.signingRegion,
|
|
24519
24519
|
service: config.signingName,
|
|
24520
|
-
sha256:
|
|
24520
|
+
sha256: sha2563,
|
|
24521
24521
|
uriEscapePath: signingEscapePath
|
|
24522
24522
|
};
|
|
24523
24523
|
const SignerCtor = config.signerConstructor || SignatureV4;
|
|
@@ -25679,7 +25679,7 @@ or increase socketAcquisitionWarningTimeout=(millis) in the NodeHttpHandler conf
|
|
|
25679
25679
|
return this.connectOptions === undefined ? http2.connect(url) : http2.connect(url, this.connectOptions);
|
|
25680
25680
|
}
|
|
25681
25681
|
}
|
|
25682
|
-
var { constants:
|
|
25682
|
+
var { constants: constants16 } = http2;
|
|
25683
25683
|
|
|
25684
25684
|
class NodeHttp2Handler {
|
|
25685
25685
|
config;
|
|
@@ -25770,8 +25770,8 @@ or increase socketAcquisitionWarningTimeout=(millis) in the NodeHttpHandler conf
|
|
|
25770
25770
|
}
|
|
25771
25771
|
const clientHttp2Stream = session.request({
|
|
25772
25772
|
...request2.headers,
|
|
25773
|
-
[
|
|
25774
|
-
[
|
|
25773
|
+
[constants16.HTTP2_HEADER_PATH]: path,
|
|
25774
|
+
[constants16.HTTP2_HEADER_METHOD]: method
|
|
25775
25775
|
});
|
|
25776
25776
|
if (effectiveRequestTimeout) {
|
|
25777
25777
|
clientHttp2Stream.setTimeout(effectiveRequestTimeout, () => {
|
|
@@ -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 createHash27, 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 join38 } from "path";
|
|
@@ -29615,7 +29615,7 @@ var init_LoginCredentialsFetcher = __esm(() => {
|
|
|
29615
29615
|
getTokenFilePath() {
|
|
29616
29616
|
const directory = process.env.AWS_LOGIN_CACHE_DIRECTORY ?? join38(homedir7(), ".aws", "login", "cache");
|
|
29617
29617
|
const loginSessionBytes = Buffer.from(this.loginSession, "utf8");
|
|
29618
|
-
const loginSessionSha256 =
|
|
29618
|
+
const loginSessionSha256 = createHash27("sha256").update(loginSessionBytes).digest("hex");
|
|
29619
29619
|
return join38(directory, `${loginSessionSha256}.json`);
|
|
29620
29620
|
}
|
|
29621
29621
|
derToRawSignature(derSignature) {
|
|
@@ -30946,7 +30946,7 @@ var fromWebToken = (init) => async (awsIdentityProperties) => {
|
|
|
30946
30946
|
};
|
|
30947
30947
|
|
|
30948
30948
|
// node_modules/@aws-sdk/credential-provider-web-identity/dist-es/fromTokenFile.js
|
|
30949
|
-
import { readFileSync as
|
|
30949
|
+
import { readFileSync as readFileSync25 } from "fs";
|
|
30950
30950
|
var import_client19, import_config32, ENV_TOKEN_FILE = "AWS_WEB_IDENTITY_TOKEN_FILE", ENV_ROLE_ARN = "AWS_ROLE_ARN", ENV_ROLE_SESSION_NAME = "AWS_ROLE_SESSION_NAME", fromTokenFile = (init = {}) => async (awsIdentityProperties) => {
|
|
30951
30951
|
init.logger?.debug("@aws-sdk/credential-provider-web-identity - fromTokenFile");
|
|
30952
30952
|
const webIdentityTokenFile = init?.webIdentityTokenFile ?? process.env[ENV_TOKEN_FILE];
|
|
@@ -30959,7 +30959,7 @@ var import_client19, import_config32, ENV_TOKEN_FILE = "AWS_WEB_IDENTITY_TOKEN_F
|
|
|
30959
30959
|
}
|
|
30960
30960
|
const credentials = await fromWebToken({
|
|
30961
30961
|
...init,
|
|
30962
|
-
webIdentityToken: import_config32.externalDataInterceptor?.getTokenRecord?.()[webIdentityTokenFile] ??
|
|
30962
|
+
webIdentityToken: import_config32.externalDataInterceptor?.getTokenRecord?.()[webIdentityTokenFile] ?? readFileSync25(webIdentityTokenFile, { encoding: "ascii" }),
|
|
30963
30963
|
roleArn,
|
|
30964
30964
|
roleSessionName
|
|
30965
30965
|
})(awsIdentityProperties);
|
|
@@ -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.50",
|
|
32377
32377
|
description: "Skills library for AI coding agents",
|
|
32378
32378
|
type: "module",
|
|
32379
32379
|
bin: {
|
|
@@ -37554,9 +37554,9 @@ async function reconcileSkillSession(input, options = {}) {
|
|
|
37554
37554
|
return { applied: true, plan, planDigest, ...result };
|
|
37555
37555
|
}
|
|
37556
37556
|
// src/lib/selected-run.ts
|
|
37557
|
-
import { createHash as
|
|
37557
|
+
import { createHash as createHash26 } from "crypto";
|
|
37558
37558
|
import { spawn as spawn2 } from "child_process";
|
|
37559
|
-
import { mkdirSync as mkdirSync11, mkdtempSync as mkdtempSync3, writeFileSync as writeFileSync10, realpathSync as
|
|
37559
|
+
import { mkdirSync as mkdirSync11, mkdtempSync as mkdtempSync3, writeFileSync as writeFileSync10, realpathSync as realpathSync15 } from "fs";
|
|
37560
37560
|
import { dirname as dirname22, join as join37, resolve as resolve21 } from "path";
|
|
37561
37561
|
import { tmpdir, hostname as stationHostname2 } from "os";
|
|
37562
37562
|
|
|
@@ -37768,7 +37768,7 @@ async function prepareSkillDependencies(skillPath, env, timeoutMs = DEFAULT_PREP
|
|
|
37768
37768
|
}
|
|
37769
37769
|
|
|
37770
37770
|
// src/lib/skillinfo.ts
|
|
37771
|
-
import { existsSync as existsSync15, readFileSync as
|
|
37771
|
+
import { existsSync as existsSync15, readFileSync as readFileSync24 } from "fs";
|
|
37772
37772
|
import { join as join36 } from "path";
|
|
37773
37773
|
|
|
37774
37774
|
// src/lib/codex-corpus-write.ts
|
|
@@ -37933,7 +37933,7 @@ function withCodexCorpusWrite(roots, run, options = {}) {
|
|
|
37933
37933
|
}
|
|
37934
37934
|
|
|
37935
37935
|
// src/lib/installer.ts
|
|
37936
|
-
import { existsSync as existsSync14, readFileSync as
|
|
37936
|
+
import { existsSync as existsSync14, readFileSync as readFileSync23, rmSync as rmSync4 } from "fs";
|
|
37937
37937
|
import { join as join35 } from "path";
|
|
37938
37938
|
import { homedir as homedir6 } from "os";
|
|
37939
37939
|
|
|
@@ -37941,10 +37941,10 @@ import { homedir as homedir6 } from "os";
|
|
|
37941
37941
|
import {
|
|
37942
37942
|
cpSync as cpSync2,
|
|
37943
37943
|
existsSync as existsSync11,
|
|
37944
|
-
lstatSync as
|
|
37944
|
+
lstatSync as lstatSync26,
|
|
37945
37945
|
mkdirSync as mkdirSync9,
|
|
37946
37946
|
mkdtempSync as mkdtempSync2,
|
|
37947
|
-
readFileSync as
|
|
37947
|
+
readFileSync as readFileSync20,
|
|
37948
37948
|
readdirSync as readdirSync11,
|
|
37949
37949
|
renameSync as renameSync6,
|
|
37950
37950
|
rmSync as rmSync3,
|
|
@@ -38140,6 +38140,8 @@ var BUILTIN_MODEL_SELECTIONS = new Set([
|
|
|
38140
38140
|
"claude-opus-4-6[1m]",
|
|
38141
38141
|
"claude-sonnet-4-6[1m]"
|
|
38142
38142
|
]);
|
|
38143
|
+
var CLAUDE_BUILTIN_THEMES = Object.freeze(["auto", "dark", "light", "dark-daltonized", "light-daltonized", "dark-ansi", "light-ansi"]);
|
|
38144
|
+
var BUILTIN_THEMES = new Set(CLAUDE_BUILTIN_THEMES);
|
|
38143
38145
|
function canonical(value) {
|
|
38144
38146
|
if (value.kind === "object")
|
|
38145
38147
|
return { kind: "object", entries: value.entries.map(([key, child]) => [key, canonical(child)]).sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0) };
|
|
@@ -38198,7 +38200,9 @@ function inferencePreference(key, child, version) {
|
|
|
38198
38200
|
function settingsDigest(text, version = 1) {
|
|
38199
38201
|
const value = parse2(text);
|
|
38200
38202
|
value.entries = value.entries.filter(([key, child]) => {
|
|
38201
|
-
if (version
|
|
38203
|
+
if (version === 4 && key === "theme" && child.kind === "string" && BUILTIN_THEMES.has(child.value))
|
|
38204
|
+
return false;
|
|
38205
|
+
if (version !== 1 && inferencePreference(key, child, version === 4 ? 3 : version))
|
|
38202
38206
|
return false;
|
|
38203
38207
|
if (key === "model") {
|
|
38204
38208
|
need(child.kind === "string", "contains an invalid model selection");
|
|
@@ -38256,6 +38260,26 @@ function upgradeClaudeSettingsWitness(previous, reviewedSettingsPath) {
|
|
|
38256
38260
|
need(settingsDigest(before, 3) === sha2562, "non-preference settings changed; explicit discovery review required");
|
|
38257
38261
|
return { path: previous.path, hashMode: "claude-settings-v3", sha256: sha2562 };
|
|
38258
38262
|
}
|
|
38263
|
+
function captureClaudeSettingsV4(path, budget = { remaining: 256 * 1024 * 1024 }) {
|
|
38264
|
+
return { path, hashMode: "claude-settings-v4", sha256: settingsDigest(readNativeSettingsWitnessFile(path, budget), 4) };
|
|
38265
|
+
}
|
|
38266
|
+
function hashClaudeSettingsReplacementV4(text, budget) {
|
|
38267
|
+
need(typeof text === "string", "requires settings text");
|
|
38268
|
+
const bytes = Buffer.byteLength(text);
|
|
38269
|
+
need(bytes <= CLAUDE_SETTINGS_WITNESS_LIMITS.bytes && Number.isSafeInteger(budget.remaining) && budget.remaining >= bytes, "exceeds its byte limit");
|
|
38270
|
+
budget.remaining -= bytes;
|
|
38271
|
+
return settingsDigest(text, 4);
|
|
38272
|
+
}
|
|
38273
|
+
function upgradeClaudeSettingsWitnessV4(previous, reviewedSettingsPath) {
|
|
38274
|
+
need(previous && Object.keys(previous).every((key) => ["path", "hashMode", "sha256"].includes(key)) && (previous.hashMode === undefined || previous.hashMode === "bytes" || previous.hashMode === "claude-settings-v1" || previous.hashMode === "claude-settings-v2" || previous.hashMode === "claude-settings-v3") && typeof previous.sha256 === "string" && /^[a-f0-9]{64}$/.test(previous.sha256), "requires an exact prior settings witness");
|
|
38275
|
+
const budget = { remaining: 2 * CLAUDE_SETTINGS_WITNESS_LIMITS.bytes };
|
|
38276
|
+
const before = readNativeSettingsWitnessFile(reviewedSettingsPath, budget), current = readNativeSettingsWitnessFile(previous.path, budget);
|
|
38277
|
+
const beforeDigest = previous.hashMode === undefined || previous.hashMode === "bytes" ? createHash6("sha256").update(before).digest("hex") : settingsDigest(before, previous.hashMode === "claude-settings-v1" ? 1 : previous.hashMode === "claude-settings-v2" ? 2 : 3);
|
|
38278
|
+
need(beforeDigest === previous.sha256, "reviewed preimage does not match the prior witness");
|
|
38279
|
+
const sha2562 = settingsDigest(current, 4);
|
|
38280
|
+
need(settingsDigest(before, 4) === sha2562, "non-preference settings changed; explicit discovery review required");
|
|
38281
|
+
return { path: previous.path, hashMode: "claude-settings-v4", sha256: sha2562 };
|
|
38282
|
+
}
|
|
38259
38283
|
function hashNativeJsonControls(text, excludedMetadata) {
|
|
38260
38284
|
need(Buffer.byteLength(text) <= CLAUDE_SETTINGS_WITNESS_LIMITS.bytes, "exceeds its byte limit");
|
|
38261
38285
|
const value = parse2(text);
|
|
@@ -40252,10 +40276,10 @@ var NATIVE_SKILL_ROOTS = [
|
|
|
40252
40276
|
];
|
|
40253
40277
|
|
|
40254
40278
|
// src/lib/agent-integration.ts
|
|
40255
|
-
import { createHash as
|
|
40279
|
+
import { createHash as createHash24, randomUUID as randomUUID4 } from "crypto";
|
|
40256
40280
|
import { isDeepStrictEqual as isDeepStrictEqual8 } from "util";
|
|
40257
|
-
import { existsSync as existsSync7, lstatSync as
|
|
40258
|
-
import { dirname as dirname17, join as join27, resolve as resolve18, relative as relative5, isAbsolute as
|
|
40281
|
+
import { existsSync as existsSync7, lstatSync as lstatSync23, statSync as statSync7, mkdirSync as mkdirSync6, readFileSync as readFileSync17, readdirSync as readdirSync8, opendirSync as opendirSync5, readlinkSync as readlinkSync6, realpathSync as realpathSync11, renameSync as renameSync4, rmdirSync as rmdirSync3, writeFileSync as writeFileSync5, unlinkSync as unlinkSync5, chmodSync, openSync as openSync18, closeSync as closeSync18, fsyncSync as fsyncSync6, fstatSync as fstatSync18, readSync as readSync12, constants as constants15, linkSync as linkSync3 } from "fs";
|
|
40282
|
+
import { dirname as dirname17, join as join27, resolve as resolve18, relative as relative5, isAbsolute as isAbsolute20, sep as sep7 } from "path";
|
|
40259
40283
|
import { homedir as homedir3 } from "os";
|
|
40260
40284
|
|
|
40261
40285
|
// src/lib/managed-policy.ts
|
|
@@ -40405,14 +40429,14 @@ function assertAgentPolicyCollections(policy) {
|
|
|
40405
40429
|
text(source.path);
|
|
40406
40430
|
requireBound(source.sha256 === null || typeof source.sha256 === "string" && /^[a-f0-9]{64}$/.test(source.sha256));
|
|
40407
40431
|
if (source.hashMode !== undefined)
|
|
40408
|
-
requireBound(["bytes", "path-bytes", "claude-plugin-manifest-v1", "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));
|
|
40432
|
+
requireBound(["bytes", "path-bytes", "claude-plugin-manifest-v1", "claude-plugin-registry", "claude-marketplace-registry", "claude-settings-v1", "claude-settings-v2", "claude-settings-v3", "claude-settings-v4", "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));
|
|
40409
40433
|
if (source.hashMode === "claude-plugin-manifest-v1")
|
|
40410
40434
|
requireBound(agent === "claude" && value.agent === "claude" && ["automatic", "reviewed"].includes(value.method) && !/[\x00-\x1f\x7f]/.test(source.path) && isAbsolute8(source.path) && resolve7(source.path) === source.path && source.path.endsWith(join14(sep4, ".claude-plugin", "plugin.json")) && source.managedPlugins === undefined);
|
|
40411
40435
|
if (source.hashMode === "sumi-settings-v1")
|
|
40412
40436
|
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");
|
|
40413
40437
|
if (source.hashMode === "codex-settings-v1" || source.hashMode === "codex-settings-v2" || (source.hashMode === "codex-settings-v3" || source.hashMode === "codex-settings-v4"))
|
|
40414
40438
|
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");
|
|
40415
|
-
if (source.hashMode === "claude-settings-v1" || source.hashMode === "claude-settings-v2" || source.hashMode === "claude-settings-v3")
|
|
40439
|
+
if (source.hashMode === "claude-settings-v1" || source.hashMode === "claude-settings-v2" || (source.hashMode === "claude-settings-v3" || source.hashMode === "claude-settings-v4"))
|
|
40416
40440
|
requireBound(agent === "claude" && value.agent === "claude" && value.method === "reviewed" && !/[\x00-\x1f\x7f]/.test(source.path) && isAbsolute8(source.path) && resolve7(source.path) === source.path && basename5(source.path) === "settings.json");
|
|
40417
40441
|
if (source.hashMode === "claude-marketplace-registry" || source.hashMode === "claude-marketplace-registry-v2")
|
|
40418
40442
|
requireBound(agent === "claude" && value.agent === "claude" && value.method === "reviewed" && !/[\x00-\x1f\x7f]/.test(source.path) && isAbsolute8(source.path) && resolve7(source.path) === source.path && basename5(source.path) === "known_marketplaces.json");
|
|
@@ -43246,13 +43270,13 @@ function projected(source, changes, budget2 = discoveryByteBudget()) {
|
|
|
43246
43270
|
throw new Error(`Native discovery input changed; run skills hook install with a fresh discovery review: ${source.path}`);
|
|
43247
43271
|
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;
|
|
43248
43272
|
}
|
|
43249
|
-
if (source.hashMode === "claude-settings-v1" || source.hashMode === "claude-settings-v2" || source.hashMode === "claude-settings-v3") {
|
|
43273
|
+
if (source.hashMode === "claude-settings-v1" || source.hashMode === "claude-settings-v2" || (source.hashMode === "claude-settings-v3" || source.hashMode === "claude-settings-v4")) {
|
|
43250
43274
|
if (source.format !== undefined || source.fields !== undefined || source.managedPlugins !== undefined || typeof source.sha256 !== "string" || !/^[a-f0-9]{64}$/.test(source.sha256))
|
|
43251
43275
|
throw new Error("Claude settings witnesses require exact typed metadata");
|
|
43252
|
-
const current = (source.hashMode === "claude-settings-v3" ? captureClaudeSettingsV3 : source.hashMode === "claude-settings-v2" ? captureClaudeSettingsV2 : captureClaudeSettings)(source.path, budget2).sha256;
|
|
43276
|
+
const current = (source.hashMode === "claude-settings-v4" ? captureClaudeSettingsV4 : source.hashMode === "claude-settings-v3" ? captureClaudeSettingsV3 : source.hashMode === "claude-settings-v2" ? captureClaudeSettingsV2 : captureClaudeSettings)(source.path, budget2).sha256;
|
|
43253
43277
|
if (current !== source.sha256)
|
|
43254
43278
|
throw new Error(`Native discovery input changed; run skills hook install with a fresh discovery review: ${source.path}`);
|
|
43255
|
-
return changes?.has(source.path) ? (source.hashMode === "claude-settings-v3" ? hashClaudeSettingsReplacementV3 : source.hashMode === "claude-settings-v2" ? hashClaudeSettingsReplacementV2 : hashClaudeSettingsReplacement)(changes.get(source.path), budget2) : current;
|
|
43279
|
+
return changes?.has(source.path) ? (source.hashMode === "claude-settings-v4" ? hashClaudeSettingsReplacementV4 : source.hashMode === "claude-settings-v3" ? hashClaudeSettingsReplacementV3 : source.hashMode === "claude-settings-v2" ? hashClaudeSettingsReplacementV2 : hashClaudeSettingsReplacement)(changes.get(source.path), budget2) : current;
|
|
43256
43280
|
}
|
|
43257
43281
|
if (source.hashMode === "claude-marketplace-registry" || source.hashMode === "claude-marketplace-registry-v2") {
|
|
43258
43282
|
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))
|
|
@@ -43487,7 +43511,7 @@ function assertMarketplaceBinding(binding, source) {
|
|
|
43487
43511
|
throw new Error("Sumi settings witnesses require explicit reviewed Sumi configuration");
|
|
43488
43512
|
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"))
|
|
43489
43513
|
throw new Error("Codex settings witnesses require explicit reviewed Codex configuration");
|
|
43490
|
-
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"))
|
|
43514
|
+
if ((source.hashMode === "claude-settings-v1" || source.hashMode === "claude-settings-v2" || (source.hashMode === "claude-settings-v3" || source.hashMode === "claude-settings-v4")) && (binding.agent !== "claude" || binding.method !== "reviewed" || basename8(source.path) !== "settings.json"))
|
|
43491
43515
|
throw new Error("Claude settings witnesses require explicit reviewed Claude configuration");
|
|
43492
43516
|
if ((source.hashMode === "claude-marketplace-registry" || source.hashMode === "claude-marketplace-registry-v2") && (binding.agent !== "claude" || binding.method !== "reviewed"))
|
|
43493
43517
|
throw new Error("Claude marketplace witnesses require explicit reviewed Claude discovery");
|
|
@@ -43689,7 +43713,7 @@ function resolveAgentDiscovery(options) {
|
|
|
43689
43713
|
verifyAgentDiscovery(retained);
|
|
43690
43714
|
if (!retained.sources.some((source) => source.path === canonical7(configPath) && source.format === undefined && source.fields === undefined))
|
|
43691
43715
|
unresolved("retained review is missing the full agent configuration source");
|
|
43692
|
-
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 !== canonical7(configPath)))
|
|
43716
|
+
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 === "claude-settings-v4" || (source.hashMode === "codex-settings-v1" || source.hashMode === "codex-settings-v2" || (source.hashMode === "codex-settings-v3" || source.hashMode === "codex-settings-v4")))) && source.path !== canonical7(configPath)))
|
|
43693
43717
|
unresolved("retained settings witness names another configuration source");
|
|
43694
43718
|
const covered = supersedesSettingsProjection(agent, retained.sources, canonical7(configPath)) ? sources.filter((source) => !isSupersededSettingsProjection(agent, canonical7(configPath), source)) : sources;
|
|
43695
43719
|
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))
|
|
@@ -43703,7 +43727,7 @@ function resolveAgentDiscovery(options) {
|
|
|
43703
43727
|
if (review.sources.some((source) => source.format !== undefined || source.fields !== undefined))
|
|
43704
43728
|
throw new Error("Explicit discovery reviews require full source-file hashes");
|
|
43705
43729
|
verifyAgentDiscovery(supplied);
|
|
43706
|
-
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 !== canonical7(configPath)))
|
|
43730
|
+
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 === "claude-settings-v4" || (source.hashMode === "codex-settings-v1" || source.hashMode === "codex-settings-v2" || (source.hashMode === "codex-settings-v3" || source.hashMode === "codex-settings-v4")))) && source.path !== canonical7(configPath)))
|
|
43707
43731
|
throw new Error("Semantic settings witnesses must name the configured agent configuration source");
|
|
43708
43732
|
if (!review.sources.some((source) => source.path === canonical7(configPath)))
|
|
43709
43733
|
throw new Error("Discovery review must include the agent configuration source");
|
|
@@ -44188,8 +44212,144 @@ function disableCodexBundledSkills(text2) {
|
|
|
44188
44212
|
return [...candidates][0];
|
|
44189
44213
|
}
|
|
44190
44214
|
|
|
44215
|
+
// src/cli/commands/runtime-launcher.ts
|
|
44216
|
+
import { createHash as createHash23 } from "crypto";
|
|
44217
|
+
import { closeSync as closeSync17, constants as constants14, fchmodSync as fchmodSync2, fstatSync as fstatSync17, fsyncSync as fsyncSync5, lstatSync as lstatSync22, openSync as openSync17, readFileSync as readFileSync16, readlinkSync as readlinkSync5, realpathSync as realpathSync10, symlinkSync, writeSync as writeSync3 } from "fs";
|
|
44218
|
+
import { isAbsolute as isAbsolute19 } from "path";
|
|
44219
|
+
var PINNED_LAUNCHER_SCHEMA = "hasna-skills-pinned-launcher-v1";
|
|
44220
|
+
var LAUNCH_CWD_VARIABLE = "HASNA_SKILLS_LAUNCH_CWD";
|
|
44221
|
+
var PINNED_LAUNCHER_BUN_FLAGS = ["--config=/dev/null", "--no-env-file", "--no-macros", "--no-install"];
|
|
44222
|
+
var PINNED_LAUNCHER_ENV_NAMES = [
|
|
44223
|
+
"HOME",
|
|
44224
|
+
"PATH",
|
|
44225
|
+
"TMPDIR",
|
|
44226
|
+
"TERM",
|
|
44227
|
+
"TERM_PROGRAM",
|
|
44228
|
+
"TERM_PROGRAM_VERSION",
|
|
44229
|
+
"COLORTERM",
|
|
44230
|
+
"LANG",
|
|
44231
|
+
"USER",
|
|
44232
|
+
"LOGNAME",
|
|
44233
|
+
"SHELL",
|
|
44234
|
+
"TZ",
|
|
44235
|
+
"NO_COLOR",
|
|
44236
|
+
"FORCE_COLOR",
|
|
44237
|
+
"CI",
|
|
44238
|
+
"COLUMNS",
|
|
44239
|
+
"LINES",
|
|
44240
|
+
"EDITOR",
|
|
44241
|
+
"VISUAL",
|
|
44242
|
+
"PAGER",
|
|
44243
|
+
"SSH_AUTH_SOCK",
|
|
44244
|
+
"DATABASE_URL",
|
|
44245
|
+
"TERMINAL_CWD",
|
|
44246
|
+
"CODEX_HOME",
|
|
44247
|
+
"HERMES_HOME",
|
|
44248
|
+
"HERMES_ENABLE_PROJECT_PLUGINS",
|
|
44249
|
+
"HOST",
|
|
44250
|
+
"PORT",
|
|
44251
|
+
"NODE_ENV",
|
|
44252
|
+
"AGENT_ID",
|
|
44253
|
+
"ECS_CONTAINER_METADATA_URI_V4"
|
|
44254
|
+
];
|
|
44255
|
+
var PINNED_LAUNCHER_ENV_PREFIXES = ["HASNA", "SKILLS", "SKILL", "MCP", "XDG", "LC", "AWS"];
|
|
44256
|
+
var ENV_PREFIX = new RegExp(`^(${PINNED_LAUNCHER_ENV_PREFIXES.join("|")})_`);
|
|
44257
|
+
var ENV_EXACT = new Set(PINNED_LAUNCHER_ENV_NAMES);
|
|
44258
|
+
function sha2562(bytes) {
|
|
44259
|
+
return createHash23("sha256").update(bytes).digest("hex");
|
|
44260
|
+
}
|
|
44261
|
+
function assertLauncherPath(value, code) {
|
|
44262
|
+
if (typeof value !== "string" || !isAbsolute19(value) || /['\x00-\x1f\x7f]/.test(value))
|
|
44263
|
+
throw new Error(code);
|
|
44264
|
+
}
|
|
44265
|
+
function renderPinnedLauncher(binding) {
|
|
44266
|
+
assertLauncherPath(binding.runtime, "LAUNCHER_RUNTIME_PATH_INVALID");
|
|
44267
|
+
assertLauncherPath(binding.cwd, "LAUNCHER_CWD_PATH_INVALID");
|
|
44268
|
+
assertLauncherPath(binding.entry, "LAUNCHER_ENTRY_PATH_INVALID");
|
|
44269
|
+
const names = PINNED_LAUNCHER_ENV_NAMES.join(" ");
|
|
44270
|
+
const prefixes = PINNED_LAUNCHER_ENV_PREFIXES.join("|");
|
|
44271
|
+
return [
|
|
44272
|
+
"#!/bin/sh -p",
|
|
44273
|
+
`# ${PINNED_LAUNCHER_SCHEMA}`,
|
|
44274
|
+
"# Written by `skills self-update`; rewrite it with `skills self-update`, do not edit by hand.",
|
|
44275
|
+
"# Runs the exact Skills entry below under one exact Bun from one trusted directory with",
|
|
44276
|
+
"# no working-directory configuration (no bunfig.toml, no .env, no macros, no auto-install)",
|
|
44277
|
+
"# and only the environment names allowed here. Everything else, BUN_* and NODE_OPTIONS",
|
|
44278
|
+
"# included, never reaches the runtime. The CLI returns to the caller's directory itself.",
|
|
44279
|
+
"# `-p` keeps the caller's exported functions and shell options out of this shell.",
|
|
44280
|
+
"set -eu",
|
|
44281
|
+
`${LAUNCH_CWD_VARIABLE}=$(pwd -P 2>/dev/null || :)`,
|
|
44282
|
+
`export ${LAUNCH_CWD_VARIABLE}`,
|
|
44283
|
+
`set -- '${binding.runtime}' ${PINNED_LAUNCHER_BUN_FLAGS.join(" ")} '--cwd=${binding.cwd}' '${binding.entry}' "$@"`,
|
|
44284
|
+
"hasna_skills_env=$(LC_ALL=C /usr/bin/awk 'BEGIN {",
|
|
44285
|
+
` n = split("${names}", exact, " ")`,
|
|
44286
|
+
" for (i = 1; i <= n; i++) allow[exact[i]] = 1",
|
|
44287
|
+
" for (name in ENVIRON) {",
|
|
44288
|
+
" if (name !~ /^[A-Za-z_][A-Za-z0-9_]*$/) continue",
|
|
44289
|
+
` if (name == "LC_ALL" || (!(name in allow) && name !~ /^(${prefixes})_/)) continue`,
|
|
44290
|
+
' value = ENVIRON[name]; quoted = ""',
|
|
44291
|
+
' while ((k = index(value, "\\047")) > 0) { quoted = quoted substr(value, 1, k - 1) "\\047\\\\\\047\\047"; value = substr(value, k + 1) }',
|
|
44292
|
+
' printf "\\047%s=%s\\047 ", name, quoted value',
|
|
44293
|
+
" }",
|
|
44294
|
+
"}')",
|
|
44295
|
+
'eval "set -- $hasna_skills_env \\"\\$@\\""',
|
|
44296
|
+
'if [ "${LC_ALL+x}" = x ]; then set -- "LC_ALL=$LC_ALL" "$@"; fi',
|
|
44297
|
+
'exec /usr/bin/env -i "$@"',
|
|
44298
|
+
""
|
|
44299
|
+
].join(`
|
|
44300
|
+
`);
|
|
44301
|
+
}
|
|
44302
|
+
var COMMAND_LINE = new RegExp(`^set -- '([^']+)' ${PINNED_LAUNCHER_BUN_FLAGS.join(" ")} '--cwd=([^']+)' '([^']+)' "\\$@"$`, "m");
|
|
44303
|
+
function parsePinnedLauncher(text2) {
|
|
44304
|
+
const match = COMMAND_LINE.exec(text2);
|
|
44305
|
+
if (!match)
|
|
44306
|
+
return null;
|
|
44307
|
+
const binding = { runtime: match[1], cwd: match[2], entry: match[3] };
|
|
44308
|
+
try {
|
|
44309
|
+
if (renderPinnedLauncher(binding) !== text2)
|
|
44310
|
+
return null;
|
|
44311
|
+
} catch {
|
|
44312
|
+
return null;
|
|
44313
|
+
}
|
|
44314
|
+
return binding;
|
|
44315
|
+
}
|
|
44316
|
+
var PINNED_LAUNCHER_MAX_BYTES = 16 * 1024;
|
|
44317
|
+
function resolveLauncherCommand(path) {
|
|
44318
|
+
const physical = realpathSync10(path);
|
|
44319
|
+
const stat2 = lstatSync22(physical);
|
|
44320
|
+
if (stat2.isFile() && stat2.size <= PINNED_LAUNCHER_MAX_BYTES) {
|
|
44321
|
+
const text2 = readFileSync16(physical, "utf8");
|
|
44322
|
+
const binding = parsePinnedLauncher(text2);
|
|
44323
|
+
if (binding) {
|
|
44324
|
+
let entry;
|
|
44325
|
+
try {
|
|
44326
|
+
entry = realpathSync10(binding.entry);
|
|
44327
|
+
} catch {
|
|
44328
|
+
throw new Error("LAUNCHER_ENTRY_UNREADABLE");
|
|
44329
|
+
}
|
|
44330
|
+
if (entry !== binding.entry)
|
|
44331
|
+
throw new Error("LAUNCHER_ENTRY_NOT_PHYSICAL");
|
|
44332
|
+
return { physical, entry, pinned: { ...binding, sha256: sha2562(text2) } };
|
|
44333
|
+
}
|
|
44334
|
+
}
|
|
44335
|
+
return { physical, entry: physical, pinned: null };
|
|
44336
|
+
}
|
|
44337
|
+
function assertPinnedLauncherRuntimeSafe(runtime) {
|
|
44338
|
+
assertLauncherPath(runtime, "LAUNCHER_RUNTIME_PATH_INVALID");
|
|
44339
|
+
let stat2;
|
|
44340
|
+
try {
|
|
44341
|
+
stat2 = lstatSync22(runtime);
|
|
44342
|
+
} catch {
|
|
44343
|
+
throw new Error("LAUNCHER_RUNTIME_UNSAFE");
|
|
44344
|
+
}
|
|
44345
|
+
const uid2 = process.getuid?.() ?? -1;
|
|
44346
|
+
if (!stat2.isFile() || stat2.isSymbolicLink() || ![0, uid2].includes(stat2.uid) || (stat2.mode & 18) !== 0 || (stat2.mode & 64) === 0) {
|
|
44347
|
+
throw new Error("LAUNCHER_RUNTIME_UNSAFE");
|
|
44348
|
+
}
|
|
44349
|
+
}
|
|
44350
|
+
|
|
44191
44351
|
// src/lib/agent-integration.ts
|
|
44192
|
-
var sha4 = (data) =>
|
|
44352
|
+
var sha4 = (data) => createHash24("sha256").update(data).digest("hex");
|
|
44193
44353
|
var ROOTS = NATIVE_SKILL_ROOTS;
|
|
44194
44354
|
function hasTrustedDarwinAcl(fd, allowDenyOnly = false) {
|
|
44195
44355
|
try {
|
|
@@ -44240,11 +44400,11 @@ function isSystemRootAlias(path) {
|
|
|
44240
44400
|
const target = `/private${path}`, link = `private${path}`;
|
|
44241
44401
|
const identity5 = (stat2) => `${stat2.dev}:${stat2.ino}:${stat2.ctimeNs}:${stat2.uid}:${stat2.mode}`;
|
|
44242
44402
|
try {
|
|
44243
|
-
const before =
|
|
44244
|
-
if (!before.isSymbolicLink() || before.uid !== 0n ||
|
|
44403
|
+
const before = lstatSync23(path, { bigint: true });
|
|
44404
|
+
if (!before.isSymbolicLink() || before.uid !== 0n || readlinkSync6(path) !== link)
|
|
44245
44405
|
return false;
|
|
44246
44406
|
const directories = ["/", "/private", target].map((directory) => {
|
|
44247
|
-
const stat2 =
|
|
44407
|
+
const stat2 = lstatSync23(directory, { bigint: true });
|
|
44248
44408
|
if (!stat2.isDirectory() || stat2.uid !== 0n)
|
|
44249
44409
|
throw new Error("Untrusted system alias directory");
|
|
44250
44410
|
if (directory !== "/private/tmp") {
|
|
@@ -44252,23 +44412,23 @@ function isSystemRootAlias(path) {
|
|
|
44252
44412
|
throw new Error("Writable system alias directory");
|
|
44253
44413
|
} else if ((stat2.mode & 0o1000n) === 0n)
|
|
44254
44414
|
throw new Error("Unprotected system temporary directory");
|
|
44255
|
-
const fd =
|
|
44415
|
+
const fd = openSync18(directory, constants15.O_RDONLY | constants15.O_DIRECTORY | constants15.O_NOFOLLOW);
|
|
44256
44416
|
try {
|
|
44257
|
-
if (identity5(
|
|
44417
|
+
if (identity5(fstatSync18(fd, { bigint: true })) !== identity5(stat2) || !hasTrustedDarwinAcl(fd) || identity5(fstatSync18(fd, { bigint: true })) !== identity5(stat2))
|
|
44258
44418
|
throw new Error("Unverified system alias directory ACL");
|
|
44259
44419
|
} finally {
|
|
44260
|
-
|
|
44420
|
+
closeSync18(fd);
|
|
44261
44421
|
}
|
|
44262
44422
|
return { directory, identity: identity5(stat2) };
|
|
44263
44423
|
});
|
|
44264
|
-
return
|
|
44424
|
+
return realpathSync11(path) === target && readlinkSync6(path) === link && identity5(lstatSync23(path, { bigint: true })) === identity5(before) && directories.every((item) => identity5(lstatSync23(item.directory, { bigint: true })) === item.identity);
|
|
44265
44425
|
} catch {
|
|
44266
44426
|
return false;
|
|
44267
44427
|
}
|
|
44268
44428
|
}
|
|
44269
44429
|
function canonicalSystemPath(path) {
|
|
44270
44430
|
const absolute = resolve18(path), root2 = `/${absolute.split(sep7)[1]}`;
|
|
44271
|
-
if (process.platform !== "darwin" || !["/var", "/tmp", "/etc"].includes(root2) || !
|
|
44431
|
+
if (process.platform !== "darwin" || !["/var", "/tmp", "/etc"].includes(root2) || !lstatSync23(root2, { throwIfNoEntry: false })?.isSymbolicLink())
|
|
44272
44432
|
return absolute;
|
|
44273
44433
|
if (!isSystemRootAlias(root2))
|
|
44274
44434
|
throw new Error(`Refusing symlink path: ${root2}`);
|
|
@@ -44277,7 +44437,7 @@ function canonicalSystemPath(path) {
|
|
|
44277
44437
|
function assertSafePath(path) {
|
|
44278
44438
|
let cursor = resolve18(path);
|
|
44279
44439
|
while (true) {
|
|
44280
|
-
if (
|
|
44440
|
+
if (lstatSync23(cursor, { throwIfNoEntry: false })?.isSymbolicLink() && !isSystemRootAlias(cursor))
|
|
44281
44441
|
throw new Error(`Refusing symlink path: ${cursor}`);
|
|
44282
44442
|
const parent = dirname17(cursor);
|
|
44283
44443
|
if (parent === cursor)
|
|
@@ -44287,17 +44447,17 @@ function assertSafePath(path) {
|
|
|
44287
44447
|
}
|
|
44288
44448
|
function readRootAlias(home, agent) {
|
|
44289
44449
|
assertSafePath(home);
|
|
44290
|
-
const realHome =
|
|
44291
|
-
const stat2 =
|
|
44450
|
+
const realHome = realpathSync11(home), alias = join27(realHome, `.${agent}`);
|
|
44451
|
+
const stat2 = lstatSync23(alias, { throwIfNoEntry: false, bigint: true });
|
|
44292
44452
|
if (!stat2?.isSymbolicLink())
|
|
44293
44453
|
throw new Error(`Agent root alias changed after planning: ${alias}`);
|
|
44294
|
-
const link =
|
|
44454
|
+
const link = readlinkSync6(alias), targetPath = resolve18(dirname17(alias), link);
|
|
44295
44455
|
assertSafePath(targetPath);
|
|
44296
|
-
const targetStat =
|
|
44456
|
+
const targetStat = lstatSync23(targetPath, { throwIfNoEntry: false });
|
|
44297
44457
|
if (!targetStat?.isDirectory())
|
|
44298
44458
|
throw new Error(`Agent root alias must target an existing directory: ${alias}`);
|
|
44299
|
-
const target =
|
|
44300
|
-
if (!inside || inside === ".." || inside.startsWith(`..${sep7}`) ||
|
|
44459
|
+
const target = realpathSync11(targetPath), inside = relative5(realHome, target);
|
|
44460
|
+
if (!inside || inside === ".." || inside.startsWith(`..${sep7}`) || isAbsolute20(inside))
|
|
44301
44461
|
throw new Error(`Agent root alias target must be inside the real home: ${alias}`);
|
|
44302
44462
|
return { agent, home: realHome, alias, target, link, aliasIdentity: `${stat2.dev}:${stat2.ino}:${stat2.ctimeNs}`, targetIdentity: `${targetStat.dev}:${targetStat.ino}` };
|
|
44303
44463
|
}
|
|
@@ -44306,7 +44466,7 @@ function rootAliases(home, allowed = false) {
|
|
|
44306
44466
|
return [];
|
|
44307
44467
|
const result = [];
|
|
44308
44468
|
for (const agent of ["claude", "codex"])
|
|
44309
|
-
if (
|
|
44469
|
+
if (lstatSync23(join27(home, `.${agent}`), { throwIfNoEntry: false })?.isSymbolicLink())
|
|
44310
44470
|
result.push(readRootAlias(home, agent));
|
|
44311
44471
|
if (result.some((item, index) => result.slice(index + 1).some((other) => item.target === other.target || item.target.startsWith(other.target + sep7) || other.target.startsWith(item.target + sep7))))
|
|
44312
44472
|
throw new Error("Agent root alias targets must not overlap");
|
|
@@ -44323,17 +44483,17 @@ function disabledCodexSkillPaths(config, aliases) {
|
|
|
44323
44483
|
const rows = skills.config;
|
|
44324
44484
|
if (!Array.isArray(rows))
|
|
44325
44485
|
return [];
|
|
44326
|
-
if (rows.some((entry) => !entry || typeof entry !== "object" || Array.isArray(entry) || typeof entry.enabled !== "boolean" || entry.path !== undefined === (entry.name !== undefined) || entry.path !== undefined && (typeof entry.path !== "string" || !
|
|
44486
|
+
if (rows.some((entry) => !entry || typeof entry !== "object" || Array.isArray(entry) || typeof entry.enabled !== "boolean" || entry.path !== undefined === (entry.name !== undefined) || entry.path !== undefined && (typeof entry.path !== "string" || !isAbsolute20(entry.path)) || entry.name !== undefined && (typeof entry.name !== "string" || !entry.name.trim())))
|
|
44327
44487
|
return [];
|
|
44328
44488
|
if (rows.some((entry) => entry.name !== undefined && entry.enabled !== false))
|
|
44329
44489
|
return [];
|
|
44330
44490
|
const settings = new Map;
|
|
44331
44491
|
for (const entry of rows) {
|
|
44332
|
-
if (typeof entry.path !== "string" || !
|
|
44492
|
+
if (typeof entry.path !== "string" || !isAbsolute20(entry.path))
|
|
44333
44493
|
continue;
|
|
44334
44494
|
let document2;
|
|
44335
44495
|
try {
|
|
44336
|
-
document2 =
|
|
44496
|
+
document2 = realpathSync11(canonicalAgentPath(entry.path, aliases));
|
|
44337
44497
|
} catch {
|
|
44338
44498
|
continue;
|
|
44339
44499
|
}
|
|
@@ -44354,16 +44514,16 @@ function recheckRootAliases(aliases) {
|
|
|
44354
44514
|
}
|
|
44355
44515
|
function nativeSourceDigest(path) {
|
|
44356
44516
|
assertSafePath(path);
|
|
44357
|
-
return
|
|
44517
|
+
return lstatSync23(path, { throwIfNoEntry: false }) ? sha4(readNativeBytes(path, 1024 * 1024)) : null;
|
|
44358
44518
|
}
|
|
44359
44519
|
function readNativeBytes(path, maximum = 64 * 1024 * 1024) {
|
|
44360
44520
|
assertSafePath(path);
|
|
44361
|
-
const before =
|
|
44521
|
+
const before = lstatSync23(path);
|
|
44362
44522
|
if (!before.isFile() || before.size > maximum)
|
|
44363
44523
|
throw new Error("Unsupported or oversized native skill file");
|
|
44364
|
-
const descriptor =
|
|
44524
|
+
const descriptor = openSync18(path, constants15.O_RDONLY | constants15.O_NOFOLLOW | constants15.O_NONBLOCK);
|
|
44365
44525
|
try {
|
|
44366
|
-
const opened =
|
|
44526
|
+
const opened = fstatSync18(descriptor);
|
|
44367
44527
|
if (!opened.isFile() || opened.dev !== before.dev || opened.ino !== before.ino || opened.size !== before.size)
|
|
44368
44528
|
throw new Error("Native skill file changed while reading");
|
|
44369
44529
|
const bytes = Buffer.allocUnsafe(before.size + 1);
|
|
@@ -44374,19 +44534,19 @@ function readNativeBytes(path, maximum = 64 * 1024 * 1024) {
|
|
|
44374
44534
|
break;
|
|
44375
44535
|
length += count;
|
|
44376
44536
|
}
|
|
44377
|
-
const after =
|
|
44537
|
+
const after = fstatSync18(descriptor), current = lstatSync23(path);
|
|
44378
44538
|
if (current.dev !== opened.dev || current.ino !== opened.ino || current.size !== after.size || current.mtimeMs !== after.mtimeMs || current.ctimeMs !== after.ctimeMs || length !== before.size || after.size !== before.size || after.mtimeMs !== opened.mtimeMs || after.ctimeMs !== opened.ctimeMs)
|
|
44379
44539
|
throw new Error("Native skill file changed while reading");
|
|
44380
44540
|
return bytes.subarray(0, length);
|
|
44381
44541
|
} finally {
|
|
44382
|
-
|
|
44542
|
+
closeSync18(descriptor);
|
|
44383
44543
|
}
|
|
44384
44544
|
}
|
|
44385
44545
|
function treeHash(root2) {
|
|
44386
|
-
const hash2 =
|
|
44546
|
+
const hash2 = createHash24("sha256");
|
|
44387
44547
|
let bytes = 0, files = 0;
|
|
44388
44548
|
function visit2(path) {
|
|
44389
|
-
const stat2 =
|
|
44549
|
+
const stat2 = lstatSync23(path);
|
|
44390
44550
|
if (stat2.isSymbolicLink())
|
|
44391
44551
|
throw new Error(`Refusing symlink in skill: ${path}`);
|
|
44392
44552
|
const rel = relative5(root2, path);
|
|
@@ -44415,13 +44575,13 @@ function selectNativeMigrationTargets(inventory, manifest) {
|
|
|
44415
44575
|
const identities = new Set;
|
|
44416
44576
|
const selected = [];
|
|
44417
44577
|
for (const target of manifest.targets) {
|
|
44418
|
-
if (!
|
|
44578
|
+
if (!isAbsolute20(target.projectRoot) || resolve18(target.projectRoot) !== target.projectRoot)
|
|
44419
44579
|
throw new Error(`Native migration target project root must be an existing absolute directory: ${target.projectRoot}`);
|
|
44420
44580
|
const projectRoot = canonicalSystemPath(target.projectRoot), normalized = relative5(projectRoot, resolve18(projectRoot, target.path));
|
|
44421
|
-
if (!existsSync7(projectRoot) || !
|
|
44581
|
+
if (!existsSync7(projectRoot) || !lstatSync23(projectRoot).isDirectory())
|
|
44422
44582
|
throw new Error(`Native migration target project root must be an existing absolute directory: ${target.projectRoot}`);
|
|
44423
44583
|
assertSafePath(projectRoot);
|
|
44424
|
-
if (
|
|
44584
|
+
if (isAbsolute20(target.path) || target.path.includes("\\") || target.path.includes("\x00") || !normalized || normalized === ".." || normalized.startsWith(`..${sep7}`) || normalized !== target.path || !/^[0-9a-f]{64}$/.test(target.treeSha256))
|
|
44425
44585
|
throw new Error(`Invalid native migration target: ${target.path}`);
|
|
44426
44586
|
const identity5 = `${target.agent}\x00${canonicalSystemPath(projectRoot)}\x00${normalized}`;
|
|
44427
44587
|
if (identities.has(identity5))
|
|
@@ -44464,9 +44624,9 @@ function isCodexSkillDiscoveryInput(path) {
|
|
|
44464
44624
|
}
|
|
44465
44625
|
function inventoryNativeSkills(home = homedir3(), options = {}) {
|
|
44466
44626
|
home = canonicalSystemPath(home);
|
|
44467
|
-
if (options.reviewedCacheAlias !== undefined && (!options.includeVendor || !
|
|
44627
|
+
if (options.reviewedCacheAlias !== undefined && (!options.includeVendor || !isAbsolute20(options.reviewedCacheAlias) || resolve18(options.reviewedCacheAlias) !== options.reviewedCacheAlias))
|
|
44468
44628
|
throw new Error("A reviewed cache alias requires vendor inventory and an exact absolute path");
|
|
44469
|
-
if (options.disabledVendorPaths?.some((path) => !
|
|
44629
|
+
if (options.disabledVendorPaths?.some((path) => !isAbsolute20(path) || resolve18(path) !== path))
|
|
44470
44630
|
throw new Error("Disabled vendor paths must be exact absolute paths");
|
|
44471
44631
|
const reviewedCacheAlias = options.reviewedCacheAlias === undefined ? undefined : canonicalSystemPath(options.reviewedCacheAlias);
|
|
44472
44632
|
const disabledVendorPaths = new Set((options.disabledVendorPaths ?? []).map(canonicalSystemPath));
|
|
@@ -44485,7 +44645,7 @@ function inventoryNativeSkills(home = homedir3(), options = {}) {
|
|
|
44485
44645
|
roots.push(["sumi", canonicalAgentPath(join27(project, directory, name), aliases)]);
|
|
44486
44646
|
}
|
|
44487
44647
|
const installationInputs = options.codexInstallationInputRoots ?? [];
|
|
44488
|
-
if (installationInputs.some((input) => resolve18(input) !== input ||
|
|
44648
|
+
if (installationInputs.some((input) => resolve18(input) !== input || realpathSync11(input) !== input || roots.some(([agent, path]) => agent === "codex" && (path === input || path.startsWith(input + sep7) || input.startsWith(path + sep7)))))
|
|
44489
44649
|
throw new Error("Native installation input overlaps an unconditional skill-loading root");
|
|
44490
44650
|
const entries = [], seen = new Set;
|
|
44491
44651
|
const cacheScans = new Map, maxAliasProofEntries = 1e4;
|
|
@@ -44499,13 +44659,13 @@ function inventoryNativeSkills(home = homedir3(), options = {}) {
|
|
|
44499
44659
|
}
|
|
44500
44660
|
let reviewedCacheAliasFound = false;
|
|
44501
44661
|
function verifiedSiblingCacheAlias(agent, path, parent) {
|
|
44502
|
-
const link =
|
|
44503
|
-
if (
|
|
44662
|
+
const link = readlinkSync6(path), lexicalTarget = resolve18(parent, link);
|
|
44663
|
+
if (isAbsolute20(link) ? link !== lexicalTarget : dirname17(link) !== ".")
|
|
44504
44664
|
return false;
|
|
44505
44665
|
const target = canonicalSystemPath(lexicalTarget);
|
|
44506
44666
|
if (dirname17(target) !== parent)
|
|
44507
44667
|
return false;
|
|
44508
|
-
if (!
|
|
44668
|
+
if (!lstatSync23(target, { throwIfNoEntry: false })?.isDirectory())
|
|
44509
44669
|
return false;
|
|
44510
44670
|
const scan = cacheScans.get(target);
|
|
44511
44671
|
if (!scan?.complete || scan.entries > maxAliasProofEntries)
|
|
@@ -44530,7 +44690,7 @@ function inventoryNativeSkills(home = homedir3(), options = {}) {
|
|
|
44530
44690
|
return scan;
|
|
44531
44691
|
if (!existsSync7(path))
|
|
44532
44692
|
return scan;
|
|
44533
|
-
const stat2 =
|
|
44693
|
+
const stat2 = lstatSync23(path);
|
|
44534
44694
|
if (stat2.isFile()) {
|
|
44535
44695
|
if (agent === "sumi" && depth === 1 && path.endsWith(".md"))
|
|
44536
44696
|
throw new Error("NATIVE_SKILL_DRIFT: flat Sumi skill documents require a dedicated migration adapter");
|
|
@@ -44547,7 +44707,7 @@ function inventoryNativeSkills(home = homedir3(), options = {}) {
|
|
|
44547
44707
|
const marker = join27(path, ".hasna-skills.json");
|
|
44548
44708
|
if (existsSync7(marker)) {
|
|
44549
44709
|
try {
|
|
44550
|
-
managed = JSON.parse(
|
|
44710
|
+
managed = JSON.parse(readFileSync17(marker, "utf8")).managedBy === "@hasna/skills";
|
|
44551
44711
|
} catch {}
|
|
44552
44712
|
}
|
|
44553
44713
|
const bridge = (!vendor || agent === "sumi") && isOwnedCliBridge(path, bridgePaths);
|
|
@@ -44579,7 +44739,7 @@ function inventoryNativeSkills(home = homedir3(), options = {}) {
|
|
|
44579
44739
|
if (isVendor && !options.includeVendor)
|
|
44580
44740
|
continue;
|
|
44581
44741
|
const child = join27(path, name);
|
|
44582
|
-
if (isVendor &&
|
|
44742
|
+
if (isVendor && lstatSync23(child, { throwIfNoEntry: false })?.isSymbolicLink()) {
|
|
44583
44743
|
const target = statSync7(child, { throwIfNoEntry: false });
|
|
44584
44744
|
if (target?.isFile() || pluginCache && target?.isDirectory() && verifiedSiblingCacheAlias(agent, child, path)) {
|
|
44585
44745
|
scan.entries++;
|
|
@@ -44622,7 +44782,7 @@ function inventoryNativeSkills(home = homedir3(), options = {}) {
|
|
|
44622
44782
|
}
|
|
44623
44783
|
function readOptional(path) {
|
|
44624
44784
|
assertSafePath(path);
|
|
44625
|
-
return existsSync7(path) ?
|
|
44785
|
+
return existsSync7(path) ? readFileSync17(path, "utf8") : null;
|
|
44626
44786
|
}
|
|
44627
44787
|
function jsonObject(text2, path) {
|
|
44628
44788
|
if (text2 === null)
|
|
@@ -44954,23 +45114,23 @@ function projectedHookAcl(path, observed) {
|
|
|
44954
45114
|
if (process.platform !== "darwin")
|
|
44955
45115
|
return;
|
|
44956
45116
|
const identity5 = (stat2) => `${stat2.dev}:${stat2.ino}:${stat2.ctimeNs}:${stat2.uid}:${stat2.mode}:${stat2.nlink}:${stat2.size}:${stat2.mtimeNs}`;
|
|
44957
|
-
const fd =
|
|
45117
|
+
const fd = openSync18(path, constants15.O_RDONLY | constants15.O_NOFOLLOW | constants15.O_NONBLOCK | (observed.isDirectory() ? constants15.O_DIRECTORY : 0));
|
|
44958
45118
|
try {
|
|
44959
|
-
if (identity5(
|
|
45119
|
+
if (identity5(fstatSync18(fd, { bigint: true })) !== identity5(observed) || !hasTrustedDarwinAcl(fd, true) || identity5(fstatSync18(fd, { bigint: true })) !== identity5(observed) || identity5(lstatSync23(path, { bigint: true })) !== identity5(observed))
|
|
44960
45120
|
hookProjectionRefusal("EXECUTABLE_UNVERIFIED");
|
|
44961
45121
|
} finally {
|
|
44962
|
-
|
|
45122
|
+
closeSync18(fd);
|
|
44963
45123
|
}
|
|
44964
45124
|
}
|
|
44965
45125
|
function projectedHookExecutable(command, expectedResolved) {
|
|
44966
45126
|
try {
|
|
44967
|
-
if (!
|
|
45127
|
+
if (!isAbsolute20(command) || /[\0\r\n]/.test(command) || resolve18(command) !== command)
|
|
44968
45128
|
hookProjectionRefusal("EXECUTABLE_UNVERIFIED");
|
|
44969
45129
|
command = canonicalSystemPath(command);
|
|
44970
45130
|
const parents3 = (file = command) => {
|
|
44971
45131
|
const result = [];
|
|
44972
45132
|
for (let path = dirname17(file);; path = dirname17(path)) {
|
|
44973
|
-
const stat2 =
|
|
45133
|
+
const stat2 = lstatSync23(path, { bigint: true });
|
|
44974
45134
|
if (!stat2.isDirectory() || (stat2.mode & 0o022n) !== 0n && !(stat2.uid === 0n && (stat2.mode & 0o1000n) !== 0n))
|
|
44975
45135
|
hookProjectionRefusal("EXECUTABLE_UNVERIFIED");
|
|
44976
45136
|
projectedHookAcl(path, stat2);
|
|
@@ -44980,13 +45140,22 @@ function projectedHookExecutable(command, expectedResolved) {
|
|
|
44980
45140
|
}
|
|
44981
45141
|
return result;
|
|
44982
45142
|
};
|
|
44983
|
-
const parentIdentity = parents3(), link =
|
|
45143
|
+
const parentIdentity = parents3(), link = lstatSync23(command, { bigint: true });
|
|
44984
45144
|
if (link.uid !== BigInt(process.getuid()) || !link.isFile() && !link.isSymbolicLink())
|
|
44985
45145
|
hookProjectionRefusal("EXECUTABLE_UNVERIFIED");
|
|
44986
45146
|
const linkIdentity = (stat2) => `${stat2.dev}:${stat2.ino}:${stat2.mode}:${stat2.uid}:${stat2.ctimeNs}`;
|
|
44987
|
-
const
|
|
45147
|
+
const target = resolveLauncherCommand(command), resolved = target.entry;
|
|
44988
45148
|
if (expectedResolved !== undefined && resolved !== expectedResolved)
|
|
44989
45149
|
hookProjectionRefusal("EXECUTABLE_UNVERIFIED");
|
|
45150
|
+
let launcher, launcherParentIdentity;
|
|
45151
|
+
if (target.pinned) {
|
|
45152
|
+
launcherParentIdentity = parents3(target.physical);
|
|
45153
|
+
launcher = snapshot(target.physical, false);
|
|
45154
|
+
projectedHookAcl(launcher.file, launcher.stat);
|
|
45155
|
+
if (launcher.sha256 !== target.pinned.sha256 || (launcher.stat.mode & 0o100n) === 0n)
|
|
45156
|
+
hookProjectionRefusal("EXECUTABLE_UNVERIFIED");
|
|
45157
|
+
assertPinnedLauncherRuntimeSafe(target.pinned.runtime);
|
|
45158
|
+
}
|
|
44990
45159
|
const resolvedParentIdentity = parents3(resolved);
|
|
44991
45160
|
const manifest = snapshot(join27(dirname17(dirname17(resolved)), "package.json"), false, { readOnlyPackage: true });
|
|
44992
45161
|
projectedHookAcl(manifest.file, manifest.stat);
|
|
@@ -44999,8 +45168,15 @@ function projectedHookExecutable(command, expectedResolved) {
|
|
|
44999
45168
|
hookProjectionRefusal("EXECUTABLE_UNVERIFIED");
|
|
45000
45169
|
const recheck = () => {
|
|
45001
45170
|
try {
|
|
45002
|
-
|
|
45171
|
+
const again = resolveLauncherCommand(command);
|
|
45172
|
+
if (again.entry !== resolved || again.physical !== target.physical || linkIdentity(lstatSync23(command, { bigint: true })) !== linkIdentity(link) || !isDeepStrictEqual8(parents3(), parentIdentity) || !isDeepStrictEqual8(parents3(resolved), resolvedParentIdentity))
|
|
45003
45173
|
hookProjectionRefusal("EXECUTABLE_UNVERIFIED");
|
|
45174
|
+
if (launcher) {
|
|
45175
|
+
if (!isDeepStrictEqual8(parents3(target.physical), launcherParentIdentity))
|
|
45176
|
+
hookProjectionRefusal("EXECUTABLE_UNVERIFIED");
|
|
45177
|
+
projectedHookAcl(launcher.file, launcher.stat);
|
|
45178
|
+
unchanged2(launcher);
|
|
45179
|
+
}
|
|
45004
45180
|
projectedHookAcl(cli.file, cli.stat);
|
|
45005
45181
|
projectedHookAcl(manifest.file, manifest.stat);
|
|
45006
45182
|
unchanged2(cli);
|
|
@@ -45122,7 +45298,7 @@ function claudeSettingsConsumers(home, path, discoveries, aliases) {
|
|
|
45122
45298
|
const canonical7 = (value) => canonicalAgentPath(value, aliases);
|
|
45123
45299
|
const containsSettings = (root2) => {
|
|
45124
45300
|
const distance = relative5(canonical7(root2), path);
|
|
45125
|
-
return distance === "" || distance !== ".." && !distance.startsWith(`..${sep7}`) && !
|
|
45301
|
+
return distance === "" || distance !== ".." && !distance.startsWith(`..${sep7}`) && !isAbsolute20(distance);
|
|
45126
45302
|
};
|
|
45127
45303
|
return discoveries.filter((binding) => binding.agent === "claude" || binding.agent === "opencode" || canonical7(join27(home, AGENT_ADAPTERS[binding.agent].config)) === path || binding.sources.some((source) => canonical7(source.path) === path) || binding.roots.some(containsSettings) || binding.directories?.some((directory) => containsSettings(directory.path))).map((binding) => binding.agent);
|
|
45128
45304
|
}
|
|
@@ -45155,7 +45331,7 @@ function planClaudeHookEventsUpdate(options) {
|
|
|
45155
45331
|
recheckRootAliases(aliases);
|
|
45156
45332
|
const path = canonicalAgentPath(join27(home, ".claude", "settings.json"), aliases);
|
|
45157
45333
|
assertSafePath(path);
|
|
45158
|
-
const before =
|
|
45334
|
+
const before = lstatSync23(path, { throwIfNoEntry: false }) ? new TextDecoder("utf-8", { fatal: true, ignoreBOM: true }).decode(readNativeBytes(path, 1024 * 1024)) : null;
|
|
45159
45335
|
if ((before === null ? "absent" : sha4(before)) !== options.expectedSettingsSha256)
|
|
45160
45336
|
throw new Error("Claude settings preimage changed");
|
|
45161
45337
|
assertClaudeHookEventsReplacement(before, options.replacement, options.events);
|
|
@@ -45222,6 +45398,8 @@ function atomicWrite2(path, content) {
|
|
|
45222
45398
|
function planAgentSettingsWitnessUpgrade(options) {
|
|
45223
45399
|
if (options.targetCodexVersion !== undefined && (options.agent !== "codex" || ![2, 3, 4].includes(options.targetCodexVersion)))
|
|
45224
45400
|
throw new Error("Invalid Codex witness target version");
|
|
45401
|
+
if (options.targetClaudeVersion !== undefined && (options.agent !== "claude" || ![3, 4].includes(options.targetClaudeVersion)))
|
|
45402
|
+
throw new Error("Invalid Claude witness target version");
|
|
45225
45403
|
const home = resolve18(options.home ?? homedir3()), dataDir2 = options.dataDir ?? getDataDirReadOnly();
|
|
45226
45404
|
const snapshot2 = readManagedSkillPolicySnapshot(dataDir2);
|
|
45227
45405
|
if (!snapshot2 || sha4(snapshot2.text) !== options.expectedPolicySha256)
|
|
@@ -45269,7 +45447,7 @@ function planAgentSettingsWitnessUpgrade(options) {
|
|
|
45269
45447
|
replaced.push(source);
|
|
45270
45448
|
}
|
|
45271
45449
|
}
|
|
45272
|
-
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);
|
|
45450
|
+
const next = options.agent === "sumi" ? upgradeSumiSettingsWitness(previous, options.reviewedPreimage) : options.agent === "claude" ? options.targetClaudeVersion === 4 ? upgradeClaudeSettingsWitnessV4(previous, options.reviewedPreimage) : upgradeClaudeSettingsWitness(previous, options.reviewedPreimage) : options.targetCodexVersion === 4 ? upgradeCodexSettingsWitnessV4(previous, options.reviewedPreimage) : options.targetCodexVersion === 3 ? upgradeCodexSettingsWitnessV3(previous, options.reviewedPreimage) : upgradeCodexSettingsWitness(previous, options.reviewedPreimage);
|
|
45273
45451
|
const rebound = [];
|
|
45274
45452
|
for (const source of binding.sources) {
|
|
45275
45453
|
if (!replaced.includes(source)) {
|
|
@@ -45315,7 +45493,7 @@ function applyAgentIntegrationUnlocked(plan, options = {}, assertCurrent) {
|
|
|
45315
45493
|
const upgrade = plan.settingsWitnessUpgrade;
|
|
45316
45494
|
if (!plan.managedAgentChecks || !plan.observedPolicy?.before)
|
|
45317
45495
|
throw new Error("Invalid settings witness upgrade plan");
|
|
45318
|
-
const verified = planAgentSettingsWitnessUpgrade({ agent: upgrade.agent, ...upgrade.agent === "codex" ? { targetCodexVersion: upgrade.toHashMode === "codex-settings-v4" ? 4 : upgrade.toHashMode === "codex-settings-v3" ? 3 : 2 } : {}, reviewedPreimage: upgrade.reviewedPreimage, home: plan.managedAgentChecks.home, dataDir: plan.dataDir, expectedPolicySha256: sha4(plan.observedPolicy.before), expectedSettingsSha256: upgrade.currentSettingsSha256 });
|
|
45496
|
+
const verified = planAgentSettingsWitnessUpgrade({ agent: upgrade.agent, ...upgrade.agent === "codex" ? { targetCodexVersion: upgrade.toHashMode === "codex-settings-v4" ? 4 : upgrade.toHashMode === "codex-settings-v3" ? 3 : 2 } : {}, ...upgrade.agent === "claude" && upgrade.toHashMode === "claude-settings-v4" ? { targetClaudeVersion: 4 } : {}, reviewedPreimage: upgrade.reviewedPreimage, home: plan.managedAgentChecks.home, dataDir: plan.dataDir, expectedPolicySha256: sha4(plan.observedPolicy.before), expectedSettingsSha256: upgrade.currentSettingsSha256 });
|
|
45319
45497
|
if (JSON.stringify(verified.changes) !== JSON.stringify(plan.changes) || JSON.stringify(verified.settingsWitnessUpgrade) !== JSON.stringify(upgrade))
|
|
45320
45498
|
throw new Error("Settings witness upgrade plan changed");
|
|
45321
45499
|
provenDiscovery = verified.discoveryBefore[0];
|
|
@@ -45346,7 +45524,7 @@ function applyAgentIntegrationUnlocked(plan, options = {}, assertCurrent) {
|
|
|
45346
45524
|
if (change.before !== null) {
|
|
45347
45525
|
const backup = join27(backupRoot, `${index}-${sha4(change.path).slice(0, 12)}.backup`);
|
|
45348
45526
|
writeFileSync5(backup, change.before, { mode: 384, flag: "wx" });
|
|
45349
|
-
if (
|
|
45527
|
+
if (readFileSync17(backup, "utf8") !== change.before)
|
|
45350
45528
|
throw new Error("Native configuration preservation readback failed");
|
|
45351
45529
|
backups.push(backup);
|
|
45352
45530
|
}
|
|
@@ -45409,11 +45587,11 @@ function applyAgentIntegrationUnlocked(plan, options = {}, assertCurrent) {
|
|
|
45409
45587
|
}
|
|
45410
45588
|
function syncArchiveDirectory(path) {
|
|
45411
45589
|
assertSafePath(path);
|
|
45412
|
-
const descriptor =
|
|
45590
|
+
const descriptor = openSync18(path, constants15.O_RDONLY | constants15.O_DIRECTORY | constants15.O_NOFOLLOW | constants15.O_NONBLOCK);
|
|
45413
45591
|
try {
|
|
45414
|
-
|
|
45592
|
+
fsyncSync6(descriptor);
|
|
45415
45593
|
} finally {
|
|
45416
|
-
|
|
45594
|
+
closeSync18(descriptor);
|
|
45417
45595
|
}
|
|
45418
45596
|
}
|
|
45419
45597
|
function writeArchiveJournal(path, value) {
|
|
@@ -45421,18 +45599,18 @@ function writeArchiveJournal(path, value) {
|
|
|
45421
45599
|
const temporary = `${path}.skills-${randomUUID4()}`;
|
|
45422
45600
|
let descriptor;
|
|
45423
45601
|
try {
|
|
45424
|
-
descriptor =
|
|
45602
|
+
descriptor = openSync18(temporary, constants15.O_WRONLY | constants15.O_CREAT | constants15.O_EXCL | constants15.O_NOFOLLOW, 384);
|
|
45425
45603
|
writeFileSync5(descriptor, `${JSON.stringify(value)}
|
|
45426
45604
|
`);
|
|
45427
|
-
|
|
45428
|
-
|
|
45605
|
+
fsyncSync6(descriptor);
|
|
45606
|
+
closeSync18(descriptor);
|
|
45429
45607
|
descriptor = undefined;
|
|
45430
45608
|
renameSync4(temporary, path);
|
|
45431
45609
|
syncArchiveDirectory(dirname17(path));
|
|
45432
45610
|
} finally {
|
|
45433
45611
|
if (descriptor !== undefined)
|
|
45434
|
-
|
|
45435
|
-
if (
|
|
45612
|
+
closeSync18(descriptor);
|
|
45613
|
+
if (lstatSync23(temporary, { throwIfNoEntry: false }))
|
|
45436
45614
|
unlinkSync5(temporary);
|
|
45437
45615
|
}
|
|
45438
45616
|
}
|
|
@@ -45478,7 +45656,7 @@ function archiveNativeSkillsUnlocked(inventory, options, assertCurrent) {
|
|
|
45478
45656
|
const moved = [];
|
|
45479
45657
|
const verifyArchive = (entry) => {
|
|
45480
45658
|
assertSafePath(entry.archive);
|
|
45481
|
-
const stat2 =
|
|
45659
|
+
const stat2 = lstatSync23(entry.archive);
|
|
45482
45660
|
if (entry.discoveryOnly ? !stat2.isFile() : !stat2.isDirectory())
|
|
45483
45661
|
throw new Error("Archive type changed");
|
|
45484
45662
|
if ((entry.discoveryOnly ? sha4(readNativeBytes(entry.archive)) : treeHash(entry.archive)) !== entry.hash)
|
|
@@ -45529,7 +45707,7 @@ function archiveNativeSkillsUnlocked(inventory, options, assertCurrent) {
|
|
|
45529
45707
|
recheckRootAliases(aliases);
|
|
45530
45708
|
assertSafePath(entry.source);
|
|
45531
45709
|
assertSafePath(entry.archive);
|
|
45532
|
-
if (
|
|
45710
|
+
if (lstatSync23(entry.source, { throwIfNoEntry: false })) {
|
|
45533
45711
|
entry.status = "recovery-required";
|
|
45534
45712
|
entry.conflict = "source-occupied";
|
|
45535
45713
|
continue;
|
|
@@ -45546,7 +45724,7 @@ function archiveNativeSkillsUnlocked(inventory, options, assertCurrent) {
|
|
|
45546
45724
|
syncArchiveDirectory(dirname17(entry.source));
|
|
45547
45725
|
unlinkSync5(entry.archive);
|
|
45548
45726
|
} else {
|
|
45549
|
-
if (
|
|
45727
|
+
if (lstatSync23(entry.source, { throwIfNoEntry: false })) {
|
|
45550
45728
|
entry.status = "recovery-required";
|
|
45551
45729
|
entry.conflict = "source-occupied";
|
|
45552
45730
|
continue;
|
|
@@ -45579,12 +45757,12 @@ function isInertCodexPluginCacheCopy(entry, cache, allowedHostPaths, read3) {
|
|
|
45579
45757
|
return false;
|
|
45580
45758
|
const document2 = join27(entry.path, "SKILL.md");
|
|
45581
45759
|
const inside = relative5(cache, entry.path);
|
|
45582
|
-
if (!inside ||
|
|
45760
|
+
if (!inside || isAbsolute20(inside) || inside.split(sep7).some((segment) => segment === ".."))
|
|
45583
45761
|
return false;
|
|
45584
45762
|
assertSafePath(entry.path);
|
|
45585
|
-
if (!
|
|
45763
|
+
if (!lstatSync23(cache).isDirectory() || !lstatSync23(entry.path).isDirectory() || !lstatSync23(document2).isFile())
|
|
45586
45764
|
return false;
|
|
45587
|
-
if (
|
|
45765
|
+
if (realpathSync11.native(cache) !== cache || realpathSync11.native(entry.path) !== entry.path || realpathSync11.native(document2) !== document2)
|
|
45588
45766
|
return false;
|
|
45589
45767
|
if (!classifyCodexPluginCacheDocument(document2, cache, read3))
|
|
45590
45768
|
return false;
|
|
@@ -45752,20 +45930,20 @@ import {
|
|
|
45752
45930
|
mkdirSync as mkdirSync8,
|
|
45753
45931
|
mkdtempSync,
|
|
45754
45932
|
readdirSync as readdirSync10,
|
|
45755
|
-
realpathSync as
|
|
45933
|
+
realpathSync as realpathSync14,
|
|
45756
45934
|
renameSync as renameSync5,
|
|
45757
45935
|
rmSync as rmSync2,
|
|
45758
45936
|
statSync as statSync10,
|
|
45759
45937
|
writeFileSync as writeFileSync7
|
|
45760
45938
|
} from "fs";
|
|
45761
|
-
import { basename as basename11, dirname as dirname20, isAbsolute as
|
|
45939
|
+
import { basename as basename11, dirname as dirname20, isAbsolute as isAbsolute21, join as join31, normalize as normalize4, relative as relative7, resolve as resolve20, sep as sep10 } from "path";
|
|
45762
45940
|
|
|
45763
45941
|
// src/lib/registry-data/index.ts
|
|
45764
45942
|
var SKILLS = [];
|
|
45765
45943
|
|
|
45766
45944
|
// src/lib/skill-hash.ts
|
|
45767
|
-
import { createHash as
|
|
45768
|
-
import { existsSync as existsSync8, readdirSync as readdirSync9, readFileSync as
|
|
45945
|
+
import { createHash as createHash25 } from "crypto";
|
|
45946
|
+
import { existsSync as existsSync8, readdirSync as readdirSync9, readFileSync as readFileSync18, statSync as statSync8 } from "fs";
|
|
45769
45947
|
import { join as join28, sep as sep8 } from "path";
|
|
45770
45948
|
var CONTENT_HASH_ALGORITHM = "sha256";
|
|
45771
45949
|
var HASH_EXCLUDE_DIRS = new Set([".git", "node_modules", "dist", "build", ".turbo"]);
|
|
@@ -45862,7 +46040,7 @@ function collectDirectory(files, dir, rel) {
|
|
|
45862
46040
|
}
|
|
45863
46041
|
}
|
|
45864
46042
|
function collectFile(files, absolute, rel) {
|
|
45865
|
-
const buffer =
|
|
46043
|
+
const buffer = readFileSync18(absolute);
|
|
45866
46044
|
files.push(normalizeBundleFile(rel.split(sep8).join("/"), buffer));
|
|
45867
46045
|
}
|
|
45868
46046
|
function normalizeBundleFile(rel, buffer) {
|
|
@@ -45888,13 +46066,13 @@ function* bundleHashParts(files) {
|
|
|
45888
46066
|
yield new TextEncoder().encode("\x00");
|
|
45889
46067
|
}
|
|
45890
46068
|
function hashBundleFiles(files) {
|
|
45891
|
-
const hash2 =
|
|
46069
|
+
const hash2 = createHash25(CONTENT_HASH_ALGORITHM);
|
|
45892
46070
|
for (const part of bundleHashParts(files))
|
|
45893
46071
|
hash2.update(part);
|
|
45894
46072
|
return hash2.digest("hex");
|
|
45895
46073
|
}
|
|
45896
46074
|
async function hashBundleFilesCooperatively(files, check) {
|
|
45897
|
-
const hash2 =
|
|
46075
|
+
const hash2 = createHash25(CONTENT_HASH_ALGORITHM);
|
|
45898
46076
|
let bytesSinceYield = 0;
|
|
45899
46077
|
for (const part of bundleHashParts(files)) {
|
|
45900
46078
|
for (let offset = 0;offset < part.byteLength; offset += 64 * 1024) {
|
|
@@ -46277,10 +46455,10 @@ function validateRuntimeContract(manifest, issues, strict) {
|
|
|
46277
46455
|
import {
|
|
46278
46456
|
cpSync,
|
|
46279
46457
|
existsSync as existsSync9,
|
|
46280
|
-
lstatSync as
|
|
46458
|
+
lstatSync as lstatSync24,
|
|
46281
46459
|
mkdirSync as mkdirSync7,
|
|
46282
|
-
readFileSync as
|
|
46283
|
-
realpathSync as
|
|
46460
|
+
readFileSync as readFileSync19,
|
|
46461
|
+
realpathSync as realpathSync12,
|
|
46284
46462
|
writeFileSync as writeFileSync6
|
|
46285
46463
|
} from "fs";
|
|
46286
46464
|
import { basename as basename9, dirname as dirname18, join as join29, relative as relative6 } from "path";
|
|
@@ -46344,7 +46522,7 @@ function readManifest(skillPath, fallbackName, normalizeName) {
|
|
|
46344
46522
|
const skillMdPath = join29(skillPath, "SKILL.md");
|
|
46345
46523
|
const pkgPath = join29(skillPath, "package.json");
|
|
46346
46524
|
const jsonManifest = existsSync9(skillJsonPath) ? readJsonObject(skillJsonPath) : undefined;
|
|
46347
|
-
const frontmatter = existsSync9(skillMdPath) ? parseSkillFrontmatter(
|
|
46525
|
+
const frontmatter = existsSync9(skillMdPath) ? parseSkillFrontmatter(readFileSync19(skillMdPath, "utf-8")) ?? undefined : undefined;
|
|
46348
46526
|
const pkg = existsSync9(pkgPath) ? readJsonObject(pkgPath) : undefined;
|
|
46349
46527
|
const name = normalizeName(stringField(jsonManifest, "name") ?? frontmatter?.name ?? stringValue(pkg?.name) ?? fallbackName);
|
|
46350
46528
|
const description = stringField(jsonManifest, "description") ?? frontmatter?.description ?? stringValue(pkg?.description) ?? `${name} skill`;
|
|
@@ -46378,7 +46556,7 @@ function readDeclaredSkillVersion(skillPath) {
|
|
|
46378
46556
|
const skillMdPath = join29(skillPath, "SKILL.md");
|
|
46379
46557
|
const pkgPath = join29(skillPath, "package.json");
|
|
46380
46558
|
const jsonManifest = existsSync9(skillJsonPath) ? readJsonObject(skillJsonPath) : undefined;
|
|
46381
|
-
const frontmatter = existsSync9(skillMdPath) ? parseSkillFrontmatter(
|
|
46559
|
+
const frontmatter = existsSync9(skillMdPath) ? parseSkillFrontmatter(readFileSync19(skillMdPath, "utf-8")) ?? undefined : undefined;
|
|
46382
46560
|
const pkg = existsSync9(pkgPath) ? readJsonObject(pkgPath) : undefined;
|
|
46383
46561
|
return stringField(jsonManifest, "version") ?? frontmatter?.version ?? stringValue(pkg?.version);
|
|
46384
46562
|
}
|
|
@@ -46499,7 +46677,7 @@ function readExistingSkillJson(skillPath) {
|
|
|
46499
46677
|
if (!existsSync9(path))
|
|
46500
46678
|
return {};
|
|
46501
46679
|
try {
|
|
46502
|
-
const parsed = JSON.parse(
|
|
46680
|
+
const parsed = JSON.parse(readFileSync19(path, "utf-8"));
|
|
46503
46681
|
return isRecord3(parsed) ? parsed : {};
|
|
46504
46682
|
} catch {
|
|
46505
46683
|
return {};
|
|
@@ -46536,7 +46714,7 @@ function ensurePortableSkillFiles(skillPath, manifest) {
|
|
|
46536
46714
|
if (!existsSync9(join29(skillPath, "SKILL.md")))
|
|
46537
46715
|
writeFileSync6(join29(skillPath, "SKILL.md"), renderSkillMd(next));
|
|
46538
46716
|
else
|
|
46539
|
-
writeFileSync6(join29(skillPath, "SKILL.md"), ensureSkillMdFrontmatter(
|
|
46717
|
+
writeFileSync6(join29(skillPath, "SKILL.md"), ensureSkillMdFrontmatter(readFileSync19(join29(skillPath, "SKILL.md"), "utf-8"), next));
|
|
46540
46718
|
if (!existsSync9(join29(skillPath, "AGENTS.md")))
|
|
46541
46719
|
writeFileSync6(join29(skillPath, "AGENTS.md"), renderAgentsMd(next));
|
|
46542
46720
|
ensurePackageJson(skillPath, next);
|
|
@@ -46597,7 +46775,7 @@ function ensureInstructionSkillFiles(skillPath, manifest) {
|
|
|
46597
46775
|
writeFileSync6(join29(skillPath, "SKILL.md"), renderSkillMd(next));
|
|
46598
46776
|
} else {
|
|
46599
46777
|
const path = join29(skillPath, "SKILL.md");
|
|
46600
|
-
const content =
|
|
46778
|
+
const content = readFileSync19(path, "utf8");
|
|
46601
46779
|
const declaredName = parseSkillFrontmatter(content)?.name;
|
|
46602
46780
|
if (declaredName && declaredName !== next.name) {
|
|
46603
46781
|
writeFileSync6(path, renameInstructionFrontmatter(content, next.name));
|
|
@@ -46635,7 +46813,7 @@ function renameInstructionFrontmatter(content, name) {
|
|
|
46635
46813
|
return renamed + content.slice(frontmatter[0].length);
|
|
46636
46814
|
}
|
|
46637
46815
|
function copySkillDirectory(source, destination) {
|
|
46638
|
-
const resolvedSource =
|
|
46816
|
+
const resolvedSource = lstatSync24(source).isSymbolicLink() ? realpathSync12(source) : source;
|
|
46639
46817
|
mkdirSync7(destination, { recursive: true });
|
|
46640
46818
|
cpSync(resolvedSource, destination, {
|
|
46641
46819
|
recursive: true,
|
|
@@ -46648,7 +46826,7 @@ function copySkillDirectory(source, destination) {
|
|
|
46648
46826
|
if (isExcludedCopyEntry(segments[i], i === 0))
|
|
46649
46827
|
return false;
|
|
46650
46828
|
}
|
|
46651
|
-
if (
|
|
46829
|
+
if (lstatSync24(src).isSymbolicLink())
|
|
46652
46830
|
return false;
|
|
46653
46831
|
return true;
|
|
46654
46832
|
}
|
|
@@ -46889,7 +47067,7 @@ function inferRuntimeFromCommands(commands) {
|
|
|
46889
47067
|
return { ...defaultRuntimeContract(entrypoint), runtime: "python3" };
|
|
46890
47068
|
}
|
|
46891
47069
|
function readJsonObject(path) {
|
|
46892
|
-
const parsed = JSON.parse(
|
|
47070
|
+
const parsed = JSON.parse(readFileSync19(path, "utf-8"));
|
|
46893
47071
|
if (!isRecord3(parsed))
|
|
46894
47072
|
throw new Error(`${basename9(path)} must contain a JSON object`);
|
|
46895
47073
|
return parsed;
|
|
@@ -46927,7 +47105,7 @@ function escapeJsString(value) {
|
|
|
46927
47105
|
}
|
|
46928
47106
|
|
|
46929
47107
|
// src/lib/authoring-path.ts
|
|
46930
|
-
import { lstatSync as
|
|
47108
|
+
import { lstatSync as lstatSync25, realpathSync as realpathSync13 } from "fs";
|
|
46931
47109
|
import { homedir as homedir4 } from "os";
|
|
46932
47110
|
import { basename as basename10, dirname as dirname19, join as join30, resolve as resolve19, sep as sep9 } from "path";
|
|
46933
47111
|
var NATIVE_DISCOVERY_ROOTS = NATIVE_SKILL_ROOTS.map(([, path]) => path.split("/"));
|
|
@@ -46948,14 +47126,14 @@ function nativeRootMatch(path) {
|
|
|
46948
47126
|
function physicalPath(path) {
|
|
46949
47127
|
let cursor = resolve19(path);
|
|
46950
47128
|
const suffix = [];
|
|
46951
|
-
while (!
|
|
47129
|
+
while (!lstatSync25(cursor, { throwIfNoEntry: false })) {
|
|
46952
47130
|
suffix.unshift(basename10(cursor));
|
|
46953
47131
|
const parent = dirname19(cursor);
|
|
46954
47132
|
if (parent === cursor)
|
|
46955
47133
|
return resolve19(path);
|
|
46956
47134
|
cursor = parent;
|
|
46957
47135
|
}
|
|
46958
|
-
return resolve19(
|
|
47136
|
+
return resolve19(realpathSync13(cursor), ...suffix);
|
|
46959
47137
|
}
|
|
46960
47138
|
function contains(root2, path) {
|
|
46961
47139
|
return path === root2 || path.startsWith(root2 + sep9);
|
|
@@ -46993,7 +47171,7 @@ function configuredRoots(home, explicitHome) {
|
|
|
46993
47171
|
continue;
|
|
46994
47172
|
}
|
|
46995
47173
|
const nativeHome = join30(home, agent === "opencode" ? ".config/opencode" : `.${agent}`);
|
|
46996
|
-
if (!
|
|
47174
|
+
if (!lstatSync25(nativeHome, { throwIfNoEntry: false }))
|
|
46997
47175
|
continue;
|
|
46998
47176
|
roots.push(...resolveAgentDiscovery({ home, agent, canonical: physicalPath }).roots);
|
|
46999
47177
|
}
|
|
@@ -47171,14 +47349,14 @@ function physicalImportPath(path) {
|
|
|
47171
47349
|
suffix.unshift(basename11(ancestor));
|
|
47172
47350
|
ancestor = dirname20(ancestor);
|
|
47173
47351
|
}
|
|
47174
|
-
return join31(
|
|
47352
|
+
return join31(realpathSync14(ancestor), ...suffix);
|
|
47175
47353
|
}
|
|
47176
47354
|
function assertDisjointImportPaths(source, destination) {
|
|
47177
|
-
const sourcePath =
|
|
47355
|
+
const sourcePath = realpathSync14(source);
|
|
47178
47356
|
const destinationPath = physicalImportPath(destination);
|
|
47179
47357
|
const contains2 = (parent, child) => {
|
|
47180
47358
|
const path = relative7(parent, child);
|
|
47181
|
-
return path === "" || !
|
|
47359
|
+
return path === "" || !isAbsolute21(path) && path !== ".." && !path.startsWith(`..${sep10}`);
|
|
47182
47360
|
};
|
|
47183
47361
|
if (contains2(sourcePath, destinationPath) || contains2(destinationPath, sourcePath)) {
|
|
47184
47362
|
throw new Error("Source and destination skill directories must not overlap");
|
|
@@ -47459,7 +47637,7 @@ function safeIsDirectory(path) {
|
|
|
47459
47637
|
}
|
|
47460
47638
|
}
|
|
47461
47639
|
function isSafeRelativePath2(value) {
|
|
47462
|
-
if (!value.trim() ||
|
|
47640
|
+
if (!value.trim() || isAbsolute21(value))
|
|
47463
47641
|
return false;
|
|
47464
47642
|
const normalized = normalize4(value).replace(/\\/g, "/");
|
|
47465
47643
|
return normalized !== ".." && !normalized.startsWith("../") && !normalized.includes("/../");
|
|
@@ -47486,9 +47664,9 @@ function isSkillsOwnershipMarker(marker) {
|
|
|
47486
47664
|
function hasSkillsOwnershipMarker(dir) {
|
|
47487
47665
|
const path = join32(dir, SYNC_MARKER_FILE);
|
|
47488
47666
|
try {
|
|
47489
|
-
if (!
|
|
47667
|
+
if (!lstatSync26(path).isFile())
|
|
47490
47668
|
return false;
|
|
47491
|
-
const marker = JSON.parse(
|
|
47669
|
+
const marker = JSON.parse(readFileSync20(path, "utf8"));
|
|
47492
47670
|
return isSkillsOwnershipMarker(marker);
|
|
47493
47671
|
} catch {
|
|
47494
47672
|
return false;
|
|
@@ -47705,7 +47883,7 @@ function writeManagedSkillDirUnlocked(dir, skillMd, options, assertCurrent) {
|
|
|
47705
47883
|
if (dirExists && managed && hasSkillMd && !options.force && isPointerSkillMd(skillMd)) {
|
|
47706
47884
|
let existingIsStub = false;
|
|
47707
47885
|
try {
|
|
47708
|
-
existingIsStub = isPointerSkillMd(
|
|
47886
|
+
existingIsStub = isPointerSkillMd(readFileSync20(skillMdPath, "utf-8"));
|
|
47709
47887
|
} catch {
|
|
47710
47888
|
existingIsStub = false;
|
|
47711
47889
|
}
|
|
@@ -47755,7 +47933,7 @@ function writeManagedSkillDirUnlocked(dir, skillMd, options, assertCurrent) {
|
|
|
47755
47933
|
assertCurrent();
|
|
47756
47934
|
renameDirectory(candidateDir, dir);
|
|
47757
47935
|
assertCurrent();
|
|
47758
|
-
if (
|
|
47936
|
+
if (readFileSync20(skillMdPath, "utf8") !== (skillMd.endsWith(`
|
|
47759
47937
|
`) ? skillMd : `${skillMd}
|
|
47760
47938
|
`))
|
|
47761
47939
|
throw new Error("Managed skill readback failed");
|
|
@@ -47799,7 +47977,7 @@ function sourceSkillMd(skillPath, name, description, kind, preferBundledDocs = f
|
|
|
47799
47977
|
if (kind === undefined || kind === "instruction" || preferBundledDocs) {
|
|
47800
47978
|
const skillMdPath = join32(skillPath, "SKILL.md");
|
|
47801
47979
|
if (existsSync11(skillMdPath))
|
|
47802
|
-
return
|
|
47980
|
+
return readFileSync20(skillMdPath, "utf-8");
|
|
47803
47981
|
}
|
|
47804
47982
|
return pointerSkillMd(name, description);
|
|
47805
47983
|
}
|
|
@@ -47829,7 +48007,7 @@ function normalizeSkillName(name) {
|
|
|
47829
48007
|
}
|
|
47830
48008
|
|
|
47831
48009
|
// src/lib/registry.ts
|
|
47832
|
-
import { existsSync as existsSync12, readFileSync as
|
|
48010
|
+
import { existsSync as existsSync12, readFileSync as readFileSync21, readdirSync as readdirSync12 } from "fs";
|
|
47833
48011
|
import { join as join33 } from "path";
|
|
47834
48012
|
|
|
47835
48013
|
// src/lib/registry-merge.ts
|
|
@@ -48045,7 +48223,7 @@ function discoverSkillsInDir(dir, source = "custom") {
|
|
|
48045
48223
|
continue;
|
|
48046
48224
|
let content;
|
|
48047
48225
|
try {
|
|
48048
|
-
content =
|
|
48226
|
+
content = readFileSync21(skillMdPath, "utf-8");
|
|
48049
48227
|
} catch {
|
|
48050
48228
|
continue;
|
|
48051
48229
|
}
|
|
@@ -48082,7 +48260,7 @@ function findExtensionSkillPath(name) {
|
|
|
48082
48260
|
continue;
|
|
48083
48261
|
let content;
|
|
48084
48262
|
try {
|
|
48085
|
-
content =
|
|
48263
|
+
content = readFileSync21(skillMdPath, "utf-8");
|
|
48086
48264
|
} catch {
|
|
48087
48265
|
continue;
|
|
48088
48266
|
}
|
|
@@ -48147,7 +48325,7 @@ function getAllTags(catalog) {
|
|
|
48147
48325
|
}
|
|
48148
48326
|
|
|
48149
48327
|
// src/lib/project-state.ts
|
|
48150
|
-
import { existsSync as existsSync13, mkdirSync as mkdirSync10, readFileSync as
|
|
48328
|
+
import { existsSync as existsSync13, mkdirSync as mkdirSync10, readFileSync as readFileSync22, writeFileSync as writeFileSync9 } from "fs";
|
|
48151
48329
|
import { join as join34 } from "path";
|
|
48152
48330
|
var VALID_PIN_SOURCES = [
|
|
48153
48331
|
"official",
|
|
@@ -48173,7 +48351,7 @@ function loadProjectConfig(targetDir = process.cwd()) {
|
|
|
48173
48351
|
if (!existsSync13(path))
|
|
48174
48352
|
return null;
|
|
48175
48353
|
try {
|
|
48176
|
-
return normalizeProjectConfig(JSON.parse(
|
|
48354
|
+
return normalizeProjectConfig(JSON.parse(readFileSync22(path, "utf-8")));
|
|
48177
48355
|
} catch {
|
|
48178
48356
|
return null;
|
|
48179
48357
|
}
|
|
@@ -48360,7 +48538,7 @@ function createLocalSkillManifest(name, generateSkillMd) {
|
|
|
48360
48538
|
let skillMd = "";
|
|
48361
48539
|
const skillMdPath = join35(sourcePath, "SKILL.md");
|
|
48362
48540
|
if (existsSync14(skillMdPath)) {
|
|
48363
|
-
skillMd =
|
|
48541
|
+
skillMd = readFileSync23(skillMdPath, "utf-8");
|
|
48364
48542
|
} else if (generateSkillMd) {
|
|
48365
48543
|
skillMd = generateSkillMd(name) ?? "";
|
|
48366
48544
|
} else {
|
|
@@ -48486,7 +48664,7 @@ function resolveAgentSkillMd(name, generateSkillMd) {
|
|
|
48486
48664
|
const sourcePath = getSkillPath(name);
|
|
48487
48665
|
const skillMdPath = join35(sourcePath, "SKILL.md");
|
|
48488
48666
|
if (existsSync14(skillMdPath))
|
|
48489
|
-
return
|
|
48667
|
+
return readFileSync23(skillMdPath, "utf-8");
|
|
48490
48668
|
if (generateSkillMd)
|
|
48491
48669
|
return generateSkillMd(name);
|
|
48492
48670
|
return generateMinimalSkillMd(name);
|
|
@@ -48542,14 +48720,14 @@ function readBundledSkillVersion(name) {
|
|
|
48542
48720
|
if (!existsSync14(pkgPath))
|
|
48543
48721
|
return "unknown";
|
|
48544
48722
|
try {
|
|
48545
|
-
const pkg = JSON.parse(
|
|
48723
|
+
const pkg = JSON.parse(readFileSync23(pkgPath, "utf-8"));
|
|
48546
48724
|
return pkg.version || "unknown";
|
|
48547
48725
|
} catch {
|
|
48548
48726
|
return "unknown";
|
|
48549
48727
|
}
|
|
48550
48728
|
}
|
|
48551
48729
|
function readFileIfExists(path) {
|
|
48552
|
-
return existsSync14(path) ?
|
|
48730
|
+
return existsSync14(path) ? readFileSync23(path, "utf-8") : null;
|
|
48553
48731
|
}
|
|
48554
48732
|
function loadProjectConfigCompat(targetDir) {
|
|
48555
48733
|
return loadProjectConfig(targetDir);
|
|
@@ -48597,7 +48775,7 @@ function isInstructionSkillDir(skillPath, meta) {
|
|
|
48597
48775
|
if (!existsSync15(skillMdPath))
|
|
48598
48776
|
return false;
|
|
48599
48777
|
try {
|
|
48600
|
-
return parseSkillFrontmatter(
|
|
48778
|
+
return parseSkillFrontmatter(readFileSync24(skillMdPath, "utf-8"))?.kind === "instruction";
|
|
48601
48779
|
} catch {
|
|
48602
48780
|
return false;
|
|
48603
48781
|
}
|
|
@@ -48648,7 +48826,7 @@ function getSkillRequirements(name) {
|
|
|
48648
48826
|
const meta = getSkill(name);
|
|
48649
48827
|
let dependencies = {};
|
|
48650
48828
|
try {
|
|
48651
|
-
dependencies = JSON.parse(
|
|
48829
|
+
dependencies = JSON.parse(readFileSync24(join36(skillPath, "package.json"), "utf8")).dependencies || {};
|
|
48652
48830
|
} catch {}
|
|
48653
48831
|
return getSkillRequirementsFromContent(name, texts, dependencies, meta);
|
|
48654
48832
|
}
|
|
@@ -48716,7 +48894,7 @@ async function runSkill(name, args, options = {}) {
|
|
|
48716
48894
|
}
|
|
48717
48895
|
let entryPoint2;
|
|
48718
48896
|
try {
|
|
48719
|
-
const pkg = JSON.parse(
|
|
48897
|
+
const pkg = JSON.parse(readFileSync24(pkgPath, "utf-8"));
|
|
48720
48898
|
if (pkg.bin) {
|
|
48721
48899
|
const binValues = Object.values(pkg.bin);
|
|
48722
48900
|
entryPoint2 = binValues[0];
|
|
@@ -48819,7 +48997,7 @@ function generateSkillMd(name) {
|
|
|
48819
48997
|
const pkgPath = join36(skillPath, "package.json");
|
|
48820
48998
|
if (existsSync15(pkgPath)) {
|
|
48821
48999
|
try {
|
|
48822
|
-
const pkg = JSON.parse(
|
|
49000
|
+
const pkg = JSON.parse(readFileSync24(pkgPath, "utf-8"));
|
|
48823
49001
|
if (pkg.bin) {
|
|
48824
49002
|
const binKeys = Object.keys(pkg.bin);
|
|
48825
49003
|
if (binKeys.length > 0)
|
|
@@ -48895,7 +49073,7 @@ function extractEnvVars(text2) {
|
|
|
48895
49073
|
function readIfExists(path) {
|
|
48896
49074
|
try {
|
|
48897
49075
|
if (existsSync15(path)) {
|
|
48898
|
-
return
|
|
49076
|
+
return readFileSync24(path, "utf-8");
|
|
48899
49077
|
}
|
|
48900
49078
|
} catch {}
|
|
48901
49079
|
return null;
|
|
@@ -49126,7 +49304,7 @@ async function executeSelectedLocal(selected, options = {}) {
|
|
|
49126
49304
|
const { authority: authority2, workspaceId, profileRevision, slug, version, bundleDigest } = selection2;
|
|
49127
49305
|
const request2 = {
|
|
49128
49306
|
selection: { authority: authority2, workspaceId, profileId, profileRevision, slug, version, bundleDigest },
|
|
49129
|
-
consumer: { stationId: process.env.HASNA_STATION || stationHostname2(), workspaceDirectory:
|
|
49307
|
+
consumer: { stationId: process.env.HASNA_STATION || stationHostname2(), workspaceDirectory: realpathSync15(options.cwd ?? process.cwd()) }
|
|
49130
49308
|
};
|
|
49131
49309
|
const grant = await (options.resolveExecutionGrant ?? resolveExecutionGrant)(request2);
|
|
49132
49310
|
if (!grant || !grantIdentifier(grant.policyRevision) || !grantIdentifier(grant.grantId))
|
|
@@ -49143,7 +49321,7 @@ async function executeSelectedLocal(selected, options = {}) {
|
|
|
49143
49321
|
selection: selection2,
|
|
49144
49322
|
target: "local",
|
|
49145
49323
|
runtime: runtimeName,
|
|
49146
|
-
inputDigest: `sha256:${
|
|
49324
|
+
inputDigest: `sha256:${createHash26("sha256").update(input).digest("hex")}`,
|
|
49147
49325
|
runDirectory,
|
|
49148
49326
|
...executionGrant ? { executionGrant } : {},
|
|
49149
49327
|
...bindings ? { secretBinding: { schema: bindings.schema, selection: bindings.selection, consumer: bindings.consumer, secretsAuthority: bindings.secretsAuthority, bindings: bindings.bindings } } : {},
|
|
@@ -58433,7 +58611,7 @@ var import_node_http_handler2 = __toESM(require_dist_cjs6(), 1);
|
|
|
58433
58611
|
|
|
58434
58612
|
// node_modules/@aws-sdk/checksums/dist-cjs/submodules/sha/index.js
|
|
58435
58613
|
var { toUint8Array: toUint8Array2, concatBytes } = require_serde();
|
|
58436
|
-
var { createHmac: createHmac2, createHash:
|
|
58614
|
+
var { createHmac: createHmac2, createHash: createHash28 } = __require("crypto");
|
|
58437
58615
|
var { Sha256: Sha2562, Sha256Js, Sha256Node } = require_checksum();
|
|
58438
58616
|
var BLOCK2 = 64;
|
|
58439
58617
|
var DIGEST_LENGTH = 20;
|
|
@@ -58602,7 +58780,7 @@ class Sha1Js {
|
|
|
58602
58780
|
}
|
|
58603
58781
|
var hasNativeCrypto = (() => {
|
|
58604
58782
|
try {
|
|
58605
|
-
|
|
58783
|
+
createHash28("sha1");
|
|
58606
58784
|
return true;
|
|
58607
58785
|
} catch {
|
|
58608
58786
|
return false;
|
|
@@ -58642,7 +58820,7 @@ function buildNativeClass() {
|
|
|
58642
58820
|
this.finished = false;
|
|
58643
58821
|
}
|
|
58644
58822
|
createHash() {
|
|
58645
|
-
return this.secret ? createHmac2("sha1", toBuffer(this.secret)) :
|
|
58823
|
+
return this.secret ? createHmac2("sha1", toBuffer(this.secret)) : createHash28("sha1");
|
|
58646
58824
|
}
|
|
58647
58825
|
};
|
|
58648
58826
|
}
|
|
@@ -58917,11 +59095,11 @@ class ArtifactStorage {
|
|
|
58917
59095
|
}));
|
|
58918
59096
|
return await bodyToText(response.Body);
|
|
58919
59097
|
}
|
|
58920
|
-
async putBundle(orgId,
|
|
58921
|
-
assertSha256(
|
|
59098
|
+
async putBundle(orgId, sha2563, bytes, contentType = "application/gzip") {
|
|
59099
|
+
assertSha256(sha2563);
|
|
58922
59100
|
if (!this.bucket)
|
|
58923
59101
|
return { storageKind: "db", bytes };
|
|
58924
|
-
const key = this.bundleKeyFor(orgId,
|
|
59102
|
+
const key = this.bundleKeyFor(orgId, sha2563);
|
|
58925
59103
|
await this.s3.send(new PutObjectCommand({
|
|
58926
59104
|
Bucket: this.bucket,
|
|
58927
59105
|
Key: key,
|
|
@@ -58941,11 +59119,11 @@ class ArtifactStorage {
|
|
|
58941
59119
|
}));
|
|
58942
59120
|
return await bodyToBytes(response.Body);
|
|
58943
59121
|
}
|
|
58944
|
-
async deleteBundle(orgId,
|
|
59122
|
+
async deleteBundle(orgId, sha2563) {
|
|
58945
59123
|
if (!this.bucket || !this.s3)
|
|
58946
59124
|
return;
|
|
58947
|
-
assertSha256(
|
|
58948
|
-
await this.s3.send(new DeleteObjectCommand({ Bucket: this.bucket, Key: this.bundleKeyFor(orgId,
|
|
59125
|
+
assertSha256(sha2563);
|
|
59126
|
+
await this.s3.send(new DeleteObjectCommand({ Bucket: this.bucket, Key: this.bundleKeyFor(orgId, sha2563) }));
|
|
58949
59127
|
}
|
|
58950
59128
|
async deleteObject(artifact) {
|
|
58951
59129
|
if (!this.bucket || !this.s3)
|
|
@@ -58992,8 +59170,8 @@ class ArtifactStorage {
|
|
|
58992
59170
|
versionKeyFor(orgId, slug, version2, file) {
|
|
58993
59171
|
return `${this.prefix}/skills/${encodeURIComponent(orgId)}/${encodeURIComponent(slug)}/${encodeURIComponent(version2)}/${file}`;
|
|
58994
59172
|
}
|
|
58995
|
-
bundleKeyFor(orgId,
|
|
58996
|
-
return `${this.prefix}/bundles/${encodeURIComponent(orgId)}/${
|
|
59173
|
+
bundleKeyFor(orgId, sha2563) {
|
|
59174
|
+
return `${this.prefix}/bundles/${encodeURIComponent(orgId)}/${sha2563}.tar.gz`;
|
|
58997
59175
|
}
|
|
58998
59176
|
}
|
|
58999
59177
|
function assertSha256(value) {
|
|
@@ -59214,7 +59392,7 @@ import { mkdirSync as mkdirSync13 } from "fs";
|
|
|
59214
59392
|
import { dirname as dirname26 } from "path";
|
|
59215
59393
|
|
|
59216
59394
|
// src/server/database-url.ts
|
|
59217
|
-
import { isAbsolute as
|
|
59395
|
+
import { isAbsolute as isAbsolute22, join as join39 } from "path";
|
|
59218
59396
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
59219
59397
|
var DEFAULT_SQLITE_FILENAME2 = "server.db";
|
|
59220
59398
|
var SQLITE_MEMORY_PATH = ":memory:";
|
|
@@ -59250,7 +59428,7 @@ function resolveDatabaseTarget(raw) {
|
|
|
59250
59428
|
throw new Error(`unsupported database scheme "${scheme}:". Supported: postgres://, postgresql://, sqlite:, file:, ` + `an absolute or relative path to a .db/.sqlite file, ":memory:", or "memory:" (non-durable, tests only). ` + `Leave the setting empty to use the default SQLite database at ${defaultSqlitePath()}.`);
|
|
59251
59429
|
}
|
|
59252
59430
|
if (looksLikeSqlitePath(value)) {
|
|
59253
|
-
const path =
|
|
59431
|
+
const path = isAbsolute22(value) ? value : join39(process.cwd(), value);
|
|
59254
59432
|
return { kind: "sqlite", path, durable: true, label: `sqlite (${path})` };
|
|
59255
59433
|
}
|
|
59256
59434
|
throw new Error(`could not resolve a database backend from "${value}". Use postgres://\u2026, sqlite:\u2026, an absolute or ` + `relative path ending in ${SQLITE_EXTENSIONS.join("/")}, ":memory:", or leave it empty for the ` + `default SQLite database at ${defaultSqlitePath()}.`);
|
|
@@ -59274,7 +59452,7 @@ function sqlitePathFromUrl(value, scheme) {
|
|
|
59274
59452
|
}
|
|
59275
59453
|
return rest.slice(2).replace(/^\/\/+/, "/");
|
|
59276
59454
|
}
|
|
59277
|
-
return
|
|
59455
|
+
return isAbsolute22(rest) ? rest : join39(process.cwd(), rest);
|
|
59278
59456
|
}
|
|
59279
59457
|
function looksLikeSqlitePath(value) {
|
|
59280
59458
|
if (value.includes("/"))
|
|
@@ -59506,13 +59684,13 @@ class PostgresSkillSelectionStore {
|
|
|
59506
59684
|
|
|
59507
59685
|
// src/server/sqlite-store.ts
|
|
59508
59686
|
import { randomUUID as randomUUID8 } from "crypto";
|
|
59509
|
-
import { mkdirSync as mkdirSync12, readFileSync as
|
|
59687
|
+
import { mkdirSync as mkdirSync12, readFileSync as readFileSync26, readdirSync as readdirSync13 } from "fs";
|
|
59510
59688
|
import { dirname as dirname25, join as join41 } from "path";
|
|
59511
59689
|
|
|
59512
59690
|
// src/server/auth.ts
|
|
59513
|
-
import { createHash as
|
|
59691
|
+
import { createHash as createHash29 } from "crypto";
|
|
59514
59692
|
function hashApiKey(token) {
|
|
59515
|
-
return
|
|
59693
|
+
return createHash29("sha256").update(token).digest("hex");
|
|
59516
59694
|
}
|
|
59517
59695
|
function bearerToken(request2) {
|
|
59518
59696
|
const header = request2.headers.get("authorization") || "";
|
|
@@ -59836,7 +60014,7 @@ function validOperatorScopeEnrollmentInput(input) {
|
|
|
59836
60014
|
}
|
|
59837
60015
|
|
|
59838
60016
|
// src/lib/revision.ts
|
|
59839
|
-
import { createHash as
|
|
60017
|
+
import { createHash as createHash30 } from "crypto";
|
|
59840
60018
|
var REVISION_ID_PATTERN = /^[0-9a-f]{64}$/;
|
|
59841
60019
|
function revisionIdOf(content) {
|
|
59842
60020
|
const canonicalContent = {
|
|
@@ -59858,7 +60036,7 @@ function revisionIdOf(content) {
|
|
|
59858
60036
|
canonicalContent.replacementSlug = content.replacementSlug ?? null;
|
|
59859
60037
|
}
|
|
59860
60038
|
const canonical7 = JSON.stringify(canonicalContent);
|
|
59861
|
-
return
|
|
60039
|
+
return createHash30("sha256").update(canonical7).digest("hex");
|
|
59862
60040
|
}
|
|
59863
60041
|
function revisionIdOfRecord(record4) {
|
|
59864
60042
|
return revisionIdOf(record4);
|
|
@@ -60467,8 +60645,8 @@ class SqliteSkillsStore {
|
|
|
60467
60645
|
return purged;
|
|
60468
60646
|
})();
|
|
60469
60647
|
}
|
|
60470
|
-
async getSkillBundle(principal,
|
|
60471
|
-
const row = this.get("SELECT * FROM skills_bundles WHERE org_id = ? AND sha256 = ? LIMIT 1", [principal.orgId,
|
|
60648
|
+
async getSkillBundle(principal, sha2563) {
|
|
60649
|
+
const row = this.get("SELECT * FROM skills_bundles WHERE org_id = ? AND sha256 = ? LIMIT 1", [principal.orgId, sha2563]);
|
|
60472
60650
|
return row ? rowToSkillBundle(row) : null;
|
|
60473
60651
|
}
|
|
60474
60652
|
async listSkillVersions(principal, slug) {
|
|
@@ -60532,11 +60710,11 @@ class SqliteSkillsStore {
|
|
|
60532
60710
|
async listPublishedSlugs(principal) {
|
|
60533
60711
|
return this.all("SELECT slug FROM skills_registry WHERE org_id = ? AND tombstoned_at IS NULL ORDER BY slug ASC", [principal.orgId]).map((row) => String(row.slug));
|
|
60534
60712
|
}
|
|
60535
|
-
collectOrphanBundle(orgId,
|
|
60536
|
-
const referenced = this.get("SELECT 1 AS present FROM skills_registry WHERE org_id = ? AND bundle_sha256 = ? LIMIT 1", [orgId,
|
|
60713
|
+
collectOrphanBundle(orgId, sha2563) {
|
|
60714
|
+
const referenced = this.get("SELECT 1 AS present FROM skills_registry WHERE org_id = ? AND bundle_sha256 = ? LIMIT 1", [orgId, sha2563]) ?? this.get("SELECT 1 AS present FROM skills_versions WHERE org_id = ? AND bundle_sha256 = ? LIMIT 1", [orgId, sha2563]);
|
|
60537
60715
|
if (referenced)
|
|
60538
60716
|
return;
|
|
60539
|
-
this.db.run("DELETE FROM skills_bundles WHERE org_id = ? AND sha256 = ?", [orgId,
|
|
60717
|
+
this.db.run("DELETE FROM skills_bundles WHERE org_id = ? AND sha256 = ?", [orgId, sha2563]);
|
|
60540
60718
|
}
|
|
60541
60719
|
get(sql, params) {
|
|
60542
60720
|
return this.db.query(sql).get(...params) ?? null;
|
|
@@ -60562,7 +60740,7 @@ function applySqliteMigrations(db, migrationsDir = resolveMigrationsDir("sqlite"
|
|
|
60562
60740
|
const appliedNow = [];
|
|
60563
60741
|
for (const file of files) {
|
|
60564
60742
|
const version2 = file.replace(/\.sql$/, "");
|
|
60565
|
-
const text2 =
|
|
60743
|
+
const text2 = readFileSync26(join41(migrationsDir, file), "utf8");
|
|
60566
60744
|
const apply = db.transaction(() => {
|
|
60567
60745
|
const already = db.query("SELECT 1 AS present FROM schema_migrations WHERE version = ? LIMIT 1").get(version2);
|
|
60568
60746
|
if (already)
|
|
@@ -60942,7 +61120,7 @@ function nextMonthPrefix(monthPrefix) {
|
|
|
60942
61120
|
}
|
|
60943
61121
|
|
|
60944
61122
|
// src/server/skills-api.ts
|
|
60945
|
-
import { createHash as
|
|
61123
|
+
import { createHash as createHash31 } from "crypto";
|
|
60946
61124
|
var SLUG_PATTERN = /^[a-z0-9][a-z0-9._-]*$/;
|
|
60947
61125
|
var SHA256_HEX2 = /^[0-9a-f]{64}$/;
|
|
60948
61126
|
var MAX_SLUG_LENGTH = 128;
|
|
@@ -61132,19 +61310,19 @@ async function parsePublishRequest(request2, config) {
|
|
|
61132
61310
|
if (bundleBytes.byteLength === 0) {
|
|
61133
61311
|
throw new SkillRequestError(400, "BUNDLE_EMPTY", "the uploaded bundle is empty");
|
|
61134
61312
|
}
|
|
61135
|
-
const
|
|
61313
|
+
const sha2563 = createHash31("sha256").update(bundleBytes).digest("hex");
|
|
61136
61314
|
const claimed = optionalString(manifest.bundleSha256);
|
|
61137
61315
|
if (claimed)
|
|
61138
61316
|
assertSha2562(claimed);
|
|
61139
|
-
if (claimed && claimed !==
|
|
61140
|
-
throw new SkillRequestError(400, "BUNDLE_DIGEST_MISMATCH", `bundle digest ${
|
|
61317
|
+
if (claimed && claimed !== sha2563) {
|
|
61318
|
+
throw new SkillRequestError(400, "BUNDLE_DIGEST_MISMATCH", `bundle digest ${sha2563} does not match the declared ${claimed}`);
|
|
61141
61319
|
}
|
|
61142
61320
|
const input = buildPublishInput(manifest);
|
|
61143
61321
|
return {
|
|
61144
61322
|
input: {
|
|
61145
61323
|
...input,
|
|
61146
61324
|
bundle: {
|
|
61147
|
-
sha256:
|
|
61325
|
+
sha256: sha2563,
|
|
61148
61326
|
byteSize: bundleBytes.byteLength,
|
|
61149
61327
|
contentType: optionalString(manifest.bundleContentType) ?? "application/gzip",
|
|
61150
61328
|
storageKind: "db"
|
|
@@ -61229,10 +61407,10 @@ async function storePublishedSkill(store, artifactStorage, principal, parsed, ex
|
|
|
61229
61407
|
async function deletePublishedSkill(store, artifactStorage, principal, slug, tombstoneWindowMs) {
|
|
61230
61408
|
return store.deleteSkill(principal, slug, tombstoneWindowMs);
|
|
61231
61409
|
}
|
|
61232
|
-
async function discardCollectedObject(store, artifactStorage, principal,
|
|
61233
|
-
if (await store.getSkillBundle(principal,
|
|
61410
|
+
async function discardCollectedObject(store, artifactStorage, principal, sha2563) {
|
|
61411
|
+
if (await store.getSkillBundle(principal, sha2563))
|
|
61234
61412
|
return;
|
|
61235
|
-
await artifactStorage.deleteBundle(principal.orgId,
|
|
61413
|
+
await artifactStorage.deleteBundle(principal.orgId, sha2563);
|
|
61236
61414
|
}
|
|
61237
61415
|
async function readPublishedBundle(store, artifactStorage, principal, slug) {
|
|
61238
61416
|
const record4 = await store.getSkill(principal, slug);
|
|
@@ -61247,7 +61425,7 @@ async function readPublishedBundle(store, artifactStorage, principal, slug) {
|
|
|
61247
61425
|
if (!bytes) {
|
|
61248
61426
|
throw new SkillRequestError(503, "BUNDLE_BACKEND_UNAVAILABLE", "bundle storage backend unavailable");
|
|
61249
61427
|
}
|
|
61250
|
-
const actual =
|
|
61428
|
+
const actual = createHash31("sha256").update(bytes).digest("hex");
|
|
61251
61429
|
if (actual !== record4.bundleSha256) {
|
|
61252
61430
|
throw new SkillRequestError(500, "BUNDLE_DIGEST_DRIFT", `stored bundle for '${slug}' hashes to ${actual} but was published as ${record4.bundleSha256}`);
|
|
61253
61431
|
}
|
|
@@ -61395,7 +61573,7 @@ async function readSkillVersionBundle(store, artifactStorage, principal, slug, v
|
|
|
61395
61573
|
const bytes = await artifactStorage.readBundle(bundle2);
|
|
61396
61574
|
if (!bytes)
|
|
61397
61575
|
throw new SkillRequestError(503, "BUNDLE_BACKEND_UNAVAILABLE", "bundle storage backend unavailable");
|
|
61398
|
-
const actual =
|
|
61576
|
+
const actual = createHash31("sha256").update(bytes).digest("hex");
|
|
61399
61577
|
if (actual !== found.bundleSha256) {
|
|
61400
61578
|
throw new SkillRequestError(500, "BUNDLE_DIGEST_DRIFT", `stored bundle for '${slug}@${version2}' hashes to ${actual} but was published as ${found.bundleSha256}`);
|
|
61401
61579
|
}
|
|
@@ -62111,7 +62289,7 @@ class RuntimeExecutionStore {
|
|
|
62111
62289
|
}
|
|
62112
62290
|
|
|
62113
62291
|
// src/sdk/execution/admission.ts
|
|
62114
|
-
import { createHash as
|
|
62292
|
+
import { createHash as createHash33 } from "crypto";
|
|
62115
62293
|
|
|
62116
62294
|
// src/sdk/execution/image-profile.ts
|
|
62117
62295
|
class ImageProfileResolutionError extends Error {
|
|
@@ -62723,11 +62901,11 @@ function ownedAdmission(admission) {
|
|
|
62723
62901
|
};
|
|
62724
62902
|
}
|
|
62725
62903
|
function digestInput(input) {
|
|
62726
|
-
return
|
|
62904
|
+
return createHash33("sha256").update(canonicalJson2(input)).digest("hex");
|
|
62727
62905
|
}
|
|
62728
62906
|
|
|
62729
62907
|
// src/sdk/execution/dispatchers/ecs.ts
|
|
62730
|
-
import { createHash as
|
|
62908
|
+
import { createHash as createHash34 } from "crypto";
|
|
62731
62909
|
|
|
62732
62910
|
// src/sdk/execution/state-machine.ts
|
|
62733
62911
|
var LEGAL_TRANSITIONS = {
|
|
@@ -66127,13 +66305,13 @@ function observedTask(states, taskArn) {
|
|
|
66127
66305
|
return state2.lastStatus === "STOPPED" || LIVE_TASK_STATUSES.has(state2.lastStatus) ? state2 : undefined;
|
|
66128
66306
|
}
|
|
66129
66307
|
function clientTokenFor(runId3, attemptId) {
|
|
66130
|
-
return
|
|
66308
|
+
return createHash34("sha256").update(`${runId3}\x00${attemptId}`).digest("hex").slice(0, CLIENT_TOKEN_BYTES * 2);
|
|
66131
66309
|
}
|
|
66132
66310
|
function startedByFor(runId3, attemptNumber) {
|
|
66133
66311
|
return `skills-exec/${runId3}/a${attemptNumber}`;
|
|
66134
66312
|
}
|
|
66135
66313
|
function requestDigestFor(admission, attemptId) {
|
|
66136
|
-
return
|
|
66314
|
+
return createHash34("sha256").update(canonicalJson2({ admission, attemptId })).digest("hex");
|
|
66137
66315
|
}
|
|
66138
66316
|
|
|
66139
66317
|
class EcsDispatcher {
|
|
@@ -66429,10 +66607,10 @@ function validText(value) {
|
|
|
66429
66607
|
}
|
|
66430
66608
|
|
|
66431
66609
|
// src/server/runtime-policy.ts
|
|
66432
|
-
import { createHash as
|
|
66610
|
+
import { createHash as createHash36, createHmac as createHmac3, timingSafeEqual as timingSafeEqual2 } from "crypto";
|
|
66433
66611
|
|
|
66434
66612
|
// src/server/runtime-pure-contract.ts
|
|
66435
|
-
import { createHash as
|
|
66613
|
+
import { createHash as createHash35 } from "crypto";
|
|
66436
66614
|
var PURE_DESCRIPTOR = Object.freeze({
|
|
66437
66615
|
id: "regex-test.v1",
|
|
66438
66616
|
runtime: "bun",
|
|
@@ -66456,7 +66634,7 @@ var PURE_LIMITS = Object.freeze({
|
|
|
66456
66634
|
maxArtifactsBytes: 0,
|
|
66457
66635
|
maxConcurrency: 1
|
|
66458
66636
|
});
|
|
66459
|
-
var hash2 = (bytes) =>
|
|
66637
|
+
var hash2 = (bytes) => createHash35("sha256").update(bytes).digest("hex");
|
|
66460
66638
|
var object7 = (v2) => {
|
|
66461
66639
|
if (!v2 || typeof v2 !== "object" || Array.isArray(v2))
|
|
66462
66640
|
throw Error("Pure contract requires an object");
|
|
@@ -66685,7 +66863,7 @@ function verifyRuntimeToken(token, key, admission, attempt, now = Date.now()) {
|
|
|
66685
66863
|
const actual = Buffer.from(token);
|
|
66686
66864
|
return actual.length === expected.length && timingSafeEqual2(actual, expected);
|
|
66687
66865
|
}
|
|
66688
|
-
var hashBytes = (bytes) =>
|
|
66866
|
+
var hashBytes = (bytes) => createHash36("sha256").update(bytes).digest("hex");
|
|
66689
66867
|
|
|
66690
66868
|
// src/server/runtime-api.ts
|
|
66691
66869
|
async function createRuntimeService(options) {
|
|
@@ -66786,8 +66964,8 @@ function publicJob(job) {
|
|
|
66786
66964
|
artifacts: (job.result?.artifacts ?? []).map(({ base64, ...meta }) => meta)
|
|
66787
66965
|
};
|
|
66788
66966
|
}
|
|
66789
|
-
function findReview(service, tenant, slug, version2,
|
|
66790
|
-
return service.config.reviewedBundles.find((b4) => b4.slug === slug && b4.version === version2 && b4.sha256 ===
|
|
66967
|
+
function findReview(service, tenant, slug, version2, sha2563) {
|
|
66968
|
+
return service.config.reviewedBundles.find((b4) => b4.slug === slug && b4.version === version2 && b4.sha256 === sha2563 && (!b4.executionContract || b4.tenantId === tenant && b4.imageDigest === service.config.imageDigest));
|
|
66791
66969
|
}
|
|
66792
66970
|
function sameContract(admission, contract, image) {
|
|
66793
66971
|
return digestInput(admission.executionContract ?? null) === digestInput(contract ?? null) && (!contract || admission.runtimeImageDigest === image);
|
|
@@ -67641,8 +67819,8 @@ class MemorySkillsStore {
|
|
|
67641
67819
|
}
|
|
67642
67820
|
return purged;
|
|
67643
67821
|
}
|
|
67644
|
-
async getSkillBundle(principal,
|
|
67645
|
-
const bundle2 = this.bundles.get(skillKey(principal.orgId,
|
|
67822
|
+
async getSkillBundle(principal, sha2563) {
|
|
67823
|
+
const bundle2 = this.bundles.get(skillKey(principal.orgId, sha2563));
|
|
67646
67824
|
return bundle2 && bundle2.orgId === principal.orgId ? bundle2 : null;
|
|
67647
67825
|
}
|
|
67648
67826
|
async pinSkill(principal, slug, metadata = {}) {
|
|
@@ -67685,10 +67863,10 @@ class MemorySkillsStore {
|
|
|
67685
67863
|
async listPublishedSlugs(principal) {
|
|
67686
67864
|
return Array.from(this.skills.values()).filter((skill) => skill.orgId === principal.orgId && !skill.tombstonedAt).map((skill) => skill.slug).sort();
|
|
67687
67865
|
}
|
|
67688
|
-
collectOrphanBundle(orgId,
|
|
67689
|
-
const referenced = Array.from(this.skills.values()).some((skill) => skill.orgId === orgId && skill.bundleSha256 ===
|
|
67866
|
+
collectOrphanBundle(orgId, sha2563) {
|
|
67867
|
+
const referenced = Array.from(this.skills.values()).some((skill) => skill.orgId === orgId && skill.bundleSha256 === sha2563) || Array.from(this.versions.values()).some((v2) => v2.orgId === orgId && v2.bundleSha256 === sha2563);
|
|
67690
67868
|
if (!referenced)
|
|
67691
|
-
this.bundles.delete(skillKey(orgId,
|
|
67869
|
+
this.bundles.delete(skillKey(orgId, sha2563));
|
|
67692
67870
|
}
|
|
67693
67871
|
patchRun(runId3, patch) {
|
|
67694
67872
|
const run = this.runs.get(runId3);
|
|
@@ -68349,8 +68527,8 @@ class PostgresSkillsStore {
|
|
|
68349
68527
|
return purged;
|
|
68350
68528
|
});
|
|
68351
68529
|
}
|
|
68352
|
-
async getSkillBundle(principal,
|
|
68353
|
-
const rows = await this.sql`SELECT * FROM skills_bundles WHERE org_id = ${principal.orgId} AND sha256 = ${
|
|
68530
|
+
async getSkillBundle(principal, sha2563) {
|
|
68531
|
+
const rows = await this.sql`SELECT * FROM skills_bundles WHERE org_id = ${principal.orgId} AND sha256 = ${sha2563} LIMIT 1`;
|
|
68354
68532
|
return rows[0] ? rowToSkillBundle(rows[0]) : null;
|
|
68355
68533
|
}
|
|
68356
68534
|
async listSkillVersions(principal, slug) {
|
|
@@ -68444,12 +68622,12 @@ class PostgresSkillsStore {
|
|
|
68444
68622
|
`;
|
|
68445
68623
|
return rows.map((row) => String(row.slug));
|
|
68446
68624
|
}
|
|
68447
|
-
async collectOrphanBundle(orgId,
|
|
68625
|
+
async collectOrphanBundle(orgId, sha2563) {
|
|
68448
68626
|
await this.sql`
|
|
68449
68627
|
DELETE FROM skills_bundles
|
|
68450
|
-
WHERE org_id = ${orgId} AND sha256 = ${
|
|
68451
|
-
AND NOT EXISTS (SELECT 1 FROM skills_registry WHERE org_id = ${orgId} AND bundle_sha256 = ${
|
|
68452
|
-
AND NOT EXISTS (SELECT 1 FROM skills_versions WHERE org_id = ${orgId} AND bundle_sha256 = ${
|
|
68628
|
+
WHERE org_id = ${orgId} AND sha256 = ${sha2563}
|
|
68629
|
+
AND NOT EXISTS (SELECT 1 FROM skills_registry WHERE org_id = ${orgId} AND bundle_sha256 = ${sha2563})
|
|
68630
|
+
AND NOT EXISTS (SELECT 1 FROM skills_versions WHERE org_id = ${orgId} AND bundle_sha256 = ${sha2563})
|
|
68453
68631
|
`;
|
|
68454
68632
|
}
|
|
68455
68633
|
}
|
|
@@ -73061,7 +73239,7 @@ var localRunExecutor = {
|
|
|
73061
73239
|
// src/sdk/storage.ts
|
|
73062
73240
|
var artifactStorageSeam = ArtifactStorage;
|
|
73063
73241
|
// src/sdk/outputs.ts
|
|
73064
|
-
import { createHash as
|
|
73242
|
+
import { createHash as createHash37 } from "crypto";
|
|
73065
73243
|
class DatabaseOnlyObjectStore {
|
|
73066
73244
|
usesS3 = false;
|
|
73067
73245
|
async materialize(run, artifact, body4) {
|
|
@@ -73108,7 +73286,7 @@ function createGovernedArtifactWriter(options) {
|
|
|
73108
73286
|
const stamped = {
|
|
73109
73287
|
...meta,
|
|
73110
73288
|
byteSize: outputBytes,
|
|
73111
|
-
sha256:
|
|
73289
|
+
sha256: createHash37("sha256").update(persistedBytes).digest("hex"),
|
|
73112
73290
|
visibility: options.visibility ?? config.defaultVisibility,
|
|
73113
73291
|
...config.artifactTtlSeconds !== undefined ? { expiresAt: expiresAtFor(createdAt, config.artifactTtlSeconds) } : {}
|
|
73114
73292
|
};
|
|
@@ -91875,7 +92053,7 @@ function date4(params) {
|
|
|
91875
92053
|
return _coercedDate(ZodDate2, params);
|
|
91876
92054
|
}
|
|
91877
92055
|
// src/lib/canonical-json.ts
|
|
91878
|
-
import { createHash as
|
|
92056
|
+
import { createHash as createHash38 } from "crypto";
|
|
91879
92057
|
function canonicalJson3(value, maximumBytes = 2 * 1024 * 1024) {
|
|
91880
92058
|
return canonicalJsonAtDepth(value, maximumBytes, 64);
|
|
91881
92059
|
}
|
|
@@ -91919,7 +92097,7 @@ function canonicalJsonAtDepth(value, maximumBytes, maximumDepth) {
|
|
|
91919
92097
|
return visit3(value, 0);
|
|
91920
92098
|
}
|
|
91921
92099
|
function canonicalJsonSha256(value, maximumBytes) {
|
|
91922
|
-
return
|
|
92100
|
+
return createHash38("sha256").update(canonicalJson3(value, maximumBytes)).digest("hex");
|
|
91923
92101
|
}
|
|
91924
92102
|
|
|
91925
92103
|
// src/lib/remote-recurring-contract.ts
|
|
@@ -94033,7 +94211,7 @@ async function requestInvitationEmail(origin, action, input2) {
|
|
|
94033
94211
|
}
|
|
94034
94212
|
|
|
94035
94213
|
// src/lib/remote-private-publications.ts
|
|
94036
|
-
import { createHash as
|
|
94214
|
+
import { createHash as createHash39 } from "crypto";
|
|
94037
94215
|
var PRIVATE_PUBLICATION_MAX_BYTES = 16 * 1024 * 1024;
|
|
94038
94216
|
var failures2 = {
|
|
94039
94217
|
INVALID_REQUEST: [400, "The publication request is invalid."],
|
|
@@ -94080,7 +94258,7 @@ var hash4 = (v2) => typeof v2 === "string" && /^[a-f0-9]{64}$/.test(v2);
|
|
|
94080
94258
|
var record10 = (v2) => !!v2 && typeof v2 === "object" && !Array.isArray(v2);
|
|
94081
94259
|
var exact = (v2, keys3) => record10(v2) && Object.keys(v2).sort().join(",") === keys3.sort().join(",");
|
|
94082
94260
|
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));
|
|
94083
|
-
var publicationSha256 = (bytes) =>
|
|
94261
|
+
var publicationSha256 = (bytes) => createHash39("sha256").update(bytes).digest("hex");
|
|
94084
94262
|
function checkedPublicationDeclaration(value) {
|
|
94085
94263
|
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)
|
|
94086
94264
|
return bad();
|
|
@@ -94562,23 +94740,23 @@ class RemoteSkillsAuthClient {
|
|
|
94562
94740
|
}
|
|
94563
94741
|
}
|
|
94564
94742
|
// src/lib/private-publication-recovery.ts
|
|
94565
|
-
import { constants as
|
|
94566
|
-
import { dirname as dirname28, isAbsolute as
|
|
94743
|
+
import { constants as constants16, closeSync as closeSync19, fsyncSync as fsyncSync7, fstatSync as fstatSync19, lstatSync as lstatSync27, mkdirSync as mkdirSync15, openSync as openSync19, readSync as readSync13, realpathSync as realpathSync16, renameSync as renameSync7, unlinkSync as unlinkSync6, writeFileSync as writeFileSync11 } from "fs";
|
|
94744
|
+
import { dirname as dirname28, isAbsolute as isAbsolute23, join as join43, resolve as resolve23 } from "path";
|
|
94567
94745
|
import { randomUUID as randomUUID12 } from "crypto";
|
|
94568
94746
|
var fail2 = () => {
|
|
94569
94747
|
throw new PrivatePublicationError("PUBLICATION_RECOVERY_INVALID", "The recovery directory is invalid or changed. Preserve it and inspect the existing intent; do not start a replacement automatically.");
|
|
94570
94748
|
};
|
|
94571
94749
|
function safeDirectory(directory) {
|
|
94572
|
-
if (!
|
|
94750
|
+
if (!isAbsolute23(directory) || directory !== resolve23(directory) || realpathSync16(directory) !== directory)
|
|
94573
94751
|
return fail2();
|
|
94574
94752
|
for (let path2 = directory;; path2 = dirname28(path2)) {
|
|
94575
|
-
const stat2 =
|
|
94753
|
+
const stat2 = lstatSync27(path2);
|
|
94576
94754
|
if (!stat2.isDirectory() || stat2.isSymbolicLink())
|
|
94577
94755
|
return fail2();
|
|
94578
94756
|
if (path2 === dirname28(path2))
|
|
94579
94757
|
break;
|
|
94580
94758
|
}
|
|
94581
|
-
const own2 =
|
|
94759
|
+
const own2 = lstatSync27(directory);
|
|
94582
94760
|
if ((own2.mode & 63) !== 0 || process.getuid && own2.uid !== process.getuid())
|
|
94583
94761
|
return fail2();
|
|
94584
94762
|
return { dev: own2.dev, ino: own2.ino };
|
|
@@ -94590,9 +94768,9 @@ function unchangedDirectory(directory, identity5) {
|
|
|
94590
94768
|
}
|
|
94591
94769
|
function readOwned(directory, name, max) {
|
|
94592
94770
|
const identity5 = safeDirectory(directory), file2 = join43(directory, name);
|
|
94593
|
-
const fd =
|
|
94771
|
+
const fd = openSync19(file2, constants16.O_RDONLY | constants16.O_NOFOLLOW);
|
|
94594
94772
|
try {
|
|
94595
|
-
const stat2 =
|
|
94773
|
+
const stat2 = fstatSync19(fd);
|
|
94596
94774
|
if (!stat2.isFile() || stat2.nlink !== 1 || stat2.size > max || stat2.size < 1 || (stat2.mode & 63) !== 0 || process.getuid && stat2.uid !== process.getuid())
|
|
94597
94775
|
return fail2();
|
|
94598
94776
|
const buffer = Buffer.alloc(Math.min(max, stat2.size) + 1);
|
|
@@ -94603,22 +94781,22 @@ function readOwned(directory, name, max) {
|
|
|
94603
94781
|
break;
|
|
94604
94782
|
length += count;
|
|
94605
94783
|
}
|
|
94606
|
-
const bytes = buffer.subarray(0, length), after =
|
|
94784
|
+
const bytes = buffer.subarray(0, length), after = fstatSync19(fd);
|
|
94607
94785
|
unchangedDirectory(directory, identity5);
|
|
94608
94786
|
if (bytes.length !== stat2.size || stat2.size !== after.size || stat2.mtimeMs !== after.mtimeMs || stat2.ctimeMs !== after.ctimeMs)
|
|
94609
94787
|
return fail2();
|
|
94610
94788
|
return bytes;
|
|
94611
94789
|
} finally {
|
|
94612
|
-
|
|
94790
|
+
closeSync19(fd);
|
|
94613
94791
|
}
|
|
94614
94792
|
}
|
|
94615
94793
|
function writeOwned(directory, name, bytes) {
|
|
94616
|
-
const fd =
|
|
94794
|
+
const fd = openSync19(join43(directory, name), constants16.O_WRONLY | constants16.O_CREAT | constants16.O_EXCL | constants16.O_NOFOLLOW, 384);
|
|
94617
94795
|
try {
|
|
94618
94796
|
writeFileSync11(fd, bytes);
|
|
94619
|
-
|
|
94797
|
+
fsyncSync7(fd);
|
|
94620
94798
|
} finally {
|
|
94621
|
-
|
|
94799
|
+
closeSync19(fd);
|
|
94622
94800
|
}
|
|
94623
94801
|
}
|
|
94624
94802
|
function save(directory, value) {
|
|
@@ -94627,11 +94805,11 @@ function save(directory, value) {
|
|
|
94627
94805
|
`);
|
|
94628
94806
|
unchangedDirectory(directory, identity5);
|
|
94629
94807
|
renameSync7(join43(directory, temporary), join43(directory, "receipt.json"));
|
|
94630
|
-
const fd =
|
|
94808
|
+
const fd = openSync19(directory, constants16.O_RDONLY | constants16.O_NOFOLLOW);
|
|
94631
94809
|
try {
|
|
94632
|
-
|
|
94810
|
+
fsyncSync7(fd);
|
|
94633
94811
|
} finally {
|
|
94634
|
-
|
|
94812
|
+
closeSync19(fd);
|
|
94635
94813
|
}
|
|
94636
94814
|
}
|
|
94637
94815
|
function bind(client2, receipt) {
|
|
@@ -94642,20 +94820,20 @@ async function locked(directory, action) {
|
|
|
94642
94820
|
const identity5 = safeDirectory(directory), file2 = join43(directory, "operation.lock");
|
|
94643
94821
|
let fd;
|
|
94644
94822
|
try {
|
|
94645
|
-
fd =
|
|
94823
|
+
fd = openSync19(file2, constants16.O_WRONLY | constants16.O_CREAT | constants16.O_EXCL | constants16.O_NOFOLLOW, 384);
|
|
94646
94824
|
} catch {
|
|
94647
94825
|
throw new PrivatePublicationError("PUBLICATION_RECOVERY_BUSY", "Another operation holds this recovery directory. If it crashed, confirm that process has stopped before explicitly removing operation.lock and resuming.");
|
|
94648
94826
|
}
|
|
94649
|
-
const lock =
|
|
94827
|
+
const lock = fstatSync19(fd);
|
|
94650
94828
|
try {
|
|
94651
94829
|
writeFileSync11(fd, JSON.stringify({ pid: process.pid }) + `
|
|
94652
94830
|
`);
|
|
94653
|
-
|
|
94831
|
+
fsyncSync7(fd);
|
|
94654
94832
|
return await action();
|
|
94655
94833
|
} finally {
|
|
94656
|
-
|
|
94834
|
+
closeSync19(fd);
|
|
94657
94835
|
unchangedDirectory(directory, identity5);
|
|
94658
|
-
const now2 =
|
|
94836
|
+
const now2 = lstatSync27(file2);
|
|
94659
94837
|
if (now2.dev !== lock.dev || now2.ino !== lock.ino || !now2.isFile() || now2.isSymbolicLink())
|
|
94660
94838
|
fail2();
|
|
94661
94839
|
unlinkSync6(file2);
|
|
@@ -94707,15 +94885,15 @@ async function preparePrivatePublication(client2, sourceDirectory, recoveryDirec
|
|
|
94707
94885
|
phase: "prepared",
|
|
94708
94886
|
intent: null
|
|
94709
94887
|
};
|
|
94710
|
-
if (!
|
|
94888
|
+
if (!isAbsolute23(recoveryDirectory) || resolve23(recoveryDirectory) !== recoveryDirectory || realpathSync16(dirname28(recoveryDirectory)) !== dirname28(recoveryDirectory))
|
|
94711
94889
|
return fail2();
|
|
94712
94890
|
mkdirSync15(recoveryDirectory, { mode: 448 });
|
|
94713
94891
|
safeDirectory(recoveryDirectory);
|
|
94714
|
-
const parent =
|
|
94892
|
+
const parent = openSync19(dirname28(recoveryDirectory), constants16.O_RDONLY | constants16.O_NOFOLLOW);
|
|
94715
94893
|
try {
|
|
94716
|
-
|
|
94894
|
+
fsyncSync7(parent);
|
|
94717
94895
|
} finally {
|
|
94718
|
-
|
|
94896
|
+
closeSync19(parent);
|
|
94719
94897
|
}
|
|
94720
94898
|
writeOwned(recoveryDirectory, "bundle.tgz", packed.bytes);
|
|
94721
94899
|
save(recoveryDirectory, receipt);
|