@hasna/skills 0.10.49 → 0.10.51
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 +40 -6
- package/bin/index.js +82 -50
- package/bin/maintenance.js +199 -2
- package/bin/mcp.js +53 -36
- package/bin/migrate.js +1 -1
- package/bin/server.js +1 -1
- package/bin/worker.js +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +71 -39
- package/dist/lib/agent-discovery.d.ts +2 -2
- package/dist/lib/agent-integration.d.ts +1 -0
- package/dist/lib/claude-settings-witness.d.ts +19 -0
- package/dist/lib/codex-native-compatibility.d.ts +4 -1
- package/dist/sdk/index.js +49 -21
- package/dist/server/maintenance-entry.d.ts +14 -0
- package/dist/server/schema-census.d.ts +77 -0
- package/docs/plugin-admission.md +44 -5
- package/package.json +1 -1
package/bin/maintenance.js
CHANGED
|
@@ -1909,7 +1909,7 @@ var {
|
|
|
1909
1909
|
// src/server/maintenance-entry.ts
|
|
1910
1910
|
import { closeSync, constants, fstatSync, lstatSync, openSync, readSync } from "fs";
|
|
1911
1911
|
import { createHash as createHash3 } from "crypto";
|
|
1912
|
-
var {SQL:
|
|
1912
|
+
var {SQL: SQL3 } = globalThis.Bun;
|
|
1913
1913
|
|
|
1914
1914
|
// src/server/execution-grant-store.ts
|
|
1915
1915
|
import { randomUUID } from "crypto";
|
|
@@ -3991,6 +3991,140 @@ async function inspectEnrollment(databaseUrl, input) {
|
|
|
3991
3991
|
}
|
|
3992
3992
|
}
|
|
3993
3993
|
|
|
3994
|
+
// src/server/schema-census.ts
|
|
3995
|
+
var {SQL: SQL2 } = globalThis.Bun;
|
|
3996
|
+
|
|
3997
|
+
class SchemaCensusError extends Error {
|
|
3998
|
+
code;
|
|
3999
|
+
constructor(code) {
|
|
4000
|
+
super(code);
|
|
4001
|
+
this.code = code;
|
|
4002
|
+
this.name = "SchemaCensusError";
|
|
4003
|
+
}
|
|
4004
|
+
}
|
|
4005
|
+
var refuse2 = (code) => {
|
|
4006
|
+
throw new SchemaCensusError(code);
|
|
4007
|
+
};
|
|
4008
|
+
var FIXED_SCHEMA = "public";
|
|
4009
|
+
var STATEMENT_TIMEOUT_MS = 5000;
|
|
4010
|
+
var LOCK_TIMEOUT_MS = 1000;
|
|
4011
|
+
var MAX_MIGRATION_VERSIONS = 128;
|
|
4012
|
+
var MAX_MIGRATION_VERSION_CHARS = 64;
|
|
4013
|
+
var MAX_IDENTIFIER_CHARS = 128;
|
|
4014
|
+
var MAX_SERVER_VERSION_CHARS = 256;
|
|
4015
|
+
var MAX_CENSUS_BYTES = 16 * 1024;
|
|
4016
|
+
var boundedText = (value, max) => {
|
|
4017
|
+
if (typeof value !== "string" || value.length === 0 || /[\u0000-\u001f\u007f]/.test(value))
|
|
4018
|
+
return refuse2("CENSUS_INVALID_RESULT");
|
|
4019
|
+
if (value.length > max)
|
|
4020
|
+
return refuse2("CENSUS_OUTPUT_UNBOUNDED");
|
|
4021
|
+
return value;
|
|
4022
|
+
};
|
|
4023
|
+
var boundedCount = (value) => {
|
|
4024
|
+
if (typeof value !== "number" || !Number.isSafeInteger(value) || value < 0)
|
|
4025
|
+
return refuse2("CENSUS_INVALID_RESULT");
|
|
4026
|
+
return value;
|
|
4027
|
+
};
|
|
4028
|
+
async function inspectSchemaCensus(databaseUrl) {
|
|
4029
|
+
try {
|
|
4030
|
+
const url = new URL(databaseUrl);
|
|
4031
|
+
if (!["postgres:", "postgresql:"].includes(url.protocol) || !url.hostname)
|
|
4032
|
+
refuse2("CENSUS_POSTGRES_REQUIRED");
|
|
4033
|
+
} catch {
|
|
4034
|
+
refuse2("CENSUS_POSTGRES_REQUIRED");
|
|
4035
|
+
}
|
|
4036
|
+
let sql;
|
|
4037
|
+
try {
|
|
4038
|
+
sql = new SQL2(databaseUrl, { max: 1, connectionTimeout: 5, idleTimeout: 5 });
|
|
4039
|
+
return await sql.begin("ISOLATION LEVEL REPEATABLE READ READ ONLY", async (tx) => {
|
|
4040
|
+
await tx.unsafe("SET LOCAL statement_timeout = '5s'");
|
|
4041
|
+
await tx.unsafe("SET LOCAL lock_timeout = '1s'");
|
|
4042
|
+
const mode = await tx`SELECT current_setting('transaction_read_only') AS read_only,
|
|
4043
|
+
current_setting('transaction_isolation') AS isolation,
|
|
4044
|
+
current_setting('statement_timeout') AS statement_timeout,
|
|
4045
|
+
current_setting('lock_timeout') AS lock_timeout`;
|
|
4046
|
+
if (mode.length !== 1 || mode[0].read_only !== "on" || mode[0].isolation !== "repeatable read" || mode[0].statement_timeout !== "5s" || mode[0].lock_timeout !== "1s") {
|
|
4047
|
+
refuse2("CENSUS_FAILED");
|
|
4048
|
+
}
|
|
4049
|
+
const identity = await tx`SELECT current_database() AS database, current_user AS role,
|
|
4050
|
+
version() AS server_version, current_schema() AS schema`;
|
|
4051
|
+
if (identity.length !== 1)
|
|
4052
|
+
refuse2("CENSUS_INVALID_RESULT");
|
|
4053
|
+
const database = boundedText(identity[0].database, MAX_IDENTIFIER_CHARS);
|
|
4054
|
+
const role = boundedText(identity[0].role, MAX_IDENTIFIER_CHARS);
|
|
4055
|
+
const serverVersion = boundedText(identity[0].server_version, MAX_SERVER_VERSION_CHARS);
|
|
4056
|
+
if (identity[0].schema !== FIXED_SCHEMA)
|
|
4057
|
+
refuse2("CENSUS_TARGET_MISMATCH");
|
|
4058
|
+
const ledger = await tx`SELECT version FROM public.schema_migrations ORDER BY version LIMIT ${MAX_MIGRATION_VERSIONS + 1}`;
|
|
4059
|
+
if (ledger.length > MAX_MIGRATION_VERSIONS)
|
|
4060
|
+
refuse2("CENSUS_OUTPUT_UNBOUNDED");
|
|
4061
|
+
const versions = ledger.map((row) => boundedText(row.version, MAX_MIGRATION_VERSION_CHARS));
|
|
4062
|
+
const registryCount = await tx`SELECT count(*)::int AS rows FROM public.skills_registry`;
|
|
4063
|
+
const versionCount = await tx`SELECT count(*)::int AS rows FROM public.skills_versions`;
|
|
4064
|
+
if (registryCount.length !== 1 || versionCount.length !== 1)
|
|
4065
|
+
refuse2("CENSUS_INVALID_RESULT");
|
|
4066
|
+
const registryRows = boundedCount(registryCount[0].rows);
|
|
4067
|
+
const versionRows = boundedCount(versionCount[0].rows);
|
|
4068
|
+
const groups = await tx`SELECT lifecycle, (tombstoned_at IS NOT NULL) AS tombstoned, count(*)::int AS rows
|
|
4069
|
+
FROM public.skills_registry GROUP BY 1, 2 LIMIT 5`;
|
|
4070
|
+
if (groups.length > 4)
|
|
4071
|
+
refuse2("CENSUS_INVALID_RESULT");
|
|
4072
|
+
const lifecycle = { active: { live: 0, tombstoned: 0 }, archived: { live: 0, tombstoned: 0 } };
|
|
4073
|
+
for (const group of groups) {
|
|
4074
|
+
const name = group.lifecycle;
|
|
4075
|
+
const tombstoned = group.tombstoned;
|
|
4076
|
+
if (name !== "active" && name !== "archived" || typeof tombstoned !== "boolean")
|
|
4077
|
+
return refuse2("CENSUS_INVALID_RESULT");
|
|
4078
|
+
lifecycle[name][tombstoned ? "tombstoned" : "live"] = boundedCount(group.rows);
|
|
4079
|
+
}
|
|
4080
|
+
const epochColumn = await tx`SELECT count(*)::int AS rows FROM information_schema.columns
|
|
4081
|
+
WHERE table_schema = ${FIXED_SCHEMA} AND table_name = 'skills_registry' AND column_name = 'authorization_epoch'`;
|
|
4082
|
+
if (epochColumn.length !== 1)
|
|
4083
|
+
refuse2("CENSUS_INVALID_RESULT");
|
|
4084
|
+
const epochPresent = boundedCount(epochColumn[0].rows);
|
|
4085
|
+
if (epochPresent > 1)
|
|
4086
|
+
refuse2("CENSUS_INVALID_RESULT");
|
|
4087
|
+
let authorizationEpoch;
|
|
4088
|
+
if (epochPresent === 0)
|
|
4089
|
+
authorizationEpoch = { exists: false };
|
|
4090
|
+
else {
|
|
4091
|
+
const epochNulls = await tx`SELECT count(*)::int AS rows FROM public.skills_registry WHERE authorization_epoch IS NULL`;
|
|
4092
|
+
if (epochNulls.length !== 1)
|
|
4093
|
+
refuse2("CENSUS_INVALID_RESULT");
|
|
4094
|
+
authorizationEpoch = { exists: true, nullCount: boundedCount(epochNulls[0].rows) };
|
|
4095
|
+
}
|
|
4096
|
+
const result = {
|
|
4097
|
+
status: "inspected",
|
|
4098
|
+
database,
|
|
4099
|
+
role,
|
|
4100
|
+
serverVersion,
|
|
4101
|
+
schema: FIXED_SCHEMA,
|
|
4102
|
+
transaction: { readOnly: true, isolation: "repeatable read", statementTimeoutMs: STATEMENT_TIMEOUT_MS, lockTimeoutMs: LOCK_TIMEOUT_MS },
|
|
4103
|
+
migrations: { count: versions.length, versions },
|
|
4104
|
+
registry: { rows: registryRows },
|
|
4105
|
+
versions: { rows: versionRows },
|
|
4106
|
+
lifecycle,
|
|
4107
|
+
authorizationEpoch
|
|
4108
|
+
};
|
|
4109
|
+
if (Buffer.byteLength(JSON.stringify(result), "utf8") > MAX_CENSUS_BYTES)
|
|
4110
|
+
refuse2("CENSUS_OUTPUT_UNBOUNDED");
|
|
4111
|
+
return result;
|
|
4112
|
+
});
|
|
4113
|
+
} catch (error) {
|
|
4114
|
+
if (error instanceof SchemaCensusError)
|
|
4115
|
+
throw error;
|
|
4116
|
+
const state2 = error instanceof SQL2.PostgresError ? error.errno : undefined;
|
|
4117
|
+
const code = state2 === "42P01" || state2 === "42703" ? "CENSUS_SCHEMA_UNAVAILABLE" : state2 === "42501" ? "CENSUS_ACCESS_DENIED" : state2 === "25006" ? "CENSUS_WRITE_REFUSED" : state2 === "57014" || state2 === "55P03" ? "CENSUS_TIMEOUT" : ["08000", "08001", "08003", "08004", "08006", "08007", "08P01", "28000", "28P01", "57P03"].includes(state2 ?? "") ? "CENSUS_CONNECTION_FAILED" : "CENSUS_FAILED";
|
|
4118
|
+
throw new SchemaCensusError(code);
|
|
4119
|
+
} finally {
|
|
4120
|
+
try {
|
|
4121
|
+
await sql?.close({ timeout: 1 });
|
|
4122
|
+
} catch {
|
|
4123
|
+
throw new SchemaCensusError("CENSUS_FAILED");
|
|
4124
|
+
}
|
|
4125
|
+
}
|
|
4126
|
+
}
|
|
4127
|
+
|
|
3994
4128
|
// src/server/maintenance-entry.ts
|
|
3995
4129
|
class InspectionInputError extends Error {
|
|
3996
4130
|
code;
|
|
@@ -3999,6 +4133,14 @@ class InspectionInputError extends Error {
|
|
|
3999
4133
|
this.code = code;
|
|
4000
4134
|
}
|
|
4001
4135
|
}
|
|
4136
|
+
|
|
4137
|
+
class SchemaCensusInputError extends Error {
|
|
4138
|
+
code;
|
|
4139
|
+
constructor(code) {
|
|
4140
|
+
super(code);
|
|
4141
|
+
this.code = code;
|
|
4142
|
+
}
|
|
4143
|
+
}
|
|
4002
4144
|
var MAX_MANIFEST_BYTES = 32 * 1024;
|
|
4003
4145
|
function sha256(value) {
|
|
4004
4146
|
return createHash3("sha256").update(value).digest("hex");
|
|
@@ -4109,6 +4251,41 @@ function readInspectionManifest(path, receiptPath) {
|
|
|
4109
4251
|
}
|
|
4110
4252
|
return parsed;
|
|
4111
4253
|
}
|
|
4254
|
+
function readSchemaCensusManifest(path, receiptPath) {
|
|
4255
|
+
let input;
|
|
4256
|
+
let parsed;
|
|
4257
|
+
try {
|
|
4258
|
+
input = readBoundedJson(path);
|
|
4259
|
+
const value = input.value;
|
|
4260
|
+
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
4261
|
+
throw new Error;
|
|
4262
|
+
const fields = ["app", "operation", "manifestVersion", "operationId", "stationId", "keyId", "orgId", "expiresAt", "manifestDigest"];
|
|
4263
|
+
if (Object.keys(value).length !== fields.length || fields.some((field) => !Object.hasOwn(value, field)))
|
|
4264
|
+
throw new Error;
|
|
4265
|
+
if (value.app !== "skills" || value.operation !== "inspect-schema" || value.manifestVersion !== 1)
|
|
4266
|
+
throw new Error;
|
|
4267
|
+
for (const field of ["operationId", "stationId", "keyId", "orgId"]) {
|
|
4268
|
+
const item = value[field];
|
|
4269
|
+
if (typeof item !== "string" || item.trim().length === 0 || item.length > 256 || /[\u0000-\u001f\u007f]/.test(item))
|
|
4270
|
+
throw new Error;
|
|
4271
|
+
}
|
|
4272
|
+
if (typeof value.expiresAt !== "string" || value.expiresAt.length > 64 || !Number.isFinite(Date.parse(value.expiresAt)) || Date.parse(value.expiresAt) <= Date.now())
|
|
4273
|
+
throw new Error;
|
|
4274
|
+
if (typeof value.manifestDigest !== "string" || !/^[a-f0-9]{64}$/.test(value.manifestDigest))
|
|
4275
|
+
throw new Error;
|
|
4276
|
+
if (sha256(canonical(value)) !== value.manifestDigest)
|
|
4277
|
+
throw new Error;
|
|
4278
|
+
parsed = value;
|
|
4279
|
+
} catch {
|
|
4280
|
+
throw new SchemaCensusInputError("INVALID_CENSUS_MANIFEST");
|
|
4281
|
+
}
|
|
4282
|
+
try {
|
|
4283
|
+
verifyOperatorReceipt(input, readBoundedJson(receiptPath).value);
|
|
4284
|
+
} catch {
|
|
4285
|
+
throw new SchemaCensusInputError("INVALID_OPERATOR_RECEIPT");
|
|
4286
|
+
}
|
|
4287
|
+
return parsed;
|
|
4288
|
+
}
|
|
4112
4289
|
function registerMaintenance(parent) {
|
|
4113
4290
|
const maintenance = parent.command("maintenance").description("Run protected, metadata-only Skills maintenance operations");
|
|
4114
4291
|
maintenance.command("inspect-enrollment").description("Inspect one enrollment with a database-enforced read-only snapshot").requiredOption("--manifest <path>", "Fresh inspection authorization supplied by the protected task wrapper").requiredOption("--operator-receipt <path>", "Verified actor receipt written by the protected task wrapper").option("--json", "Output a safe JSON receipt", false).action(async (options) => {
|
|
@@ -4133,6 +4310,26 @@ function registerMaintenance(parent) {
|
|
|
4133
4310
|
process.exitCode = 1;
|
|
4134
4311
|
}
|
|
4135
4312
|
});
|
|
4313
|
+
maintenance.command("inspect-schema").description("Census the fixed Skills schema and migration ledger with a database-enforced read-only snapshot").requiredOption("--manifest <path>", "Fresh census authorization supplied by the protected task wrapper").requiredOption("--operator-receipt <path>", "Verified actor receipt written by the protected task wrapper").option("--json", "Output a safe JSON receipt", false).action(async (options) => {
|
|
4314
|
+
try {
|
|
4315
|
+
const manifest = readSchemaCensusManifest(options.manifest, options.operatorReceipt);
|
|
4316
|
+
const census = await inspectSchemaCensus(process.env.HASNA_SKILLS_DATABASE_URL ?? "");
|
|
4317
|
+
console.log(JSON.stringify({
|
|
4318
|
+
...census,
|
|
4319
|
+
operationId: manifest.operationId,
|
|
4320
|
+
keyId: manifest.keyId,
|
|
4321
|
+
orgId: manifest.orgId,
|
|
4322
|
+
stationId: manifest.stationId
|
|
4323
|
+
}));
|
|
4324
|
+
} catch (error) {
|
|
4325
|
+
const code = error instanceof SchemaCensusInputError || error instanceof SchemaCensusError ? error.code : "CENSUS_FAILED";
|
|
4326
|
+
if (options.json || !process.stdout.isTTY)
|
|
4327
|
+
console.log(JSON.stringify({ status: "failed", code }));
|
|
4328
|
+
else
|
|
4329
|
+
console.error(code);
|
|
4330
|
+
process.exitCode = 1;
|
|
4331
|
+
}
|
|
4332
|
+
});
|
|
4136
4333
|
maintenance.command("enroll-publish").requiredOption("--manifest <path>", "Bounded target manifest supplied by the protected task wrapper").requiredOption("--operator-receipt <path>", "Verified actor receipt written by the protected task wrapper").option("--apply", "Commit the bounded scope update; defaults to dry-run", false).option("--json", "Output a safe JSON receipt", false).action(async (options) => {
|
|
4137
4334
|
let manifest;
|
|
4138
4335
|
let store;
|
|
@@ -4167,7 +4364,7 @@ function registerMaintenance(parent) {
|
|
|
4167
4364
|
process.exitCode = 1;
|
|
4168
4365
|
} catch (error) {
|
|
4169
4366
|
const message = error instanceof Error ? error.message : "";
|
|
4170
|
-
const state2 = error instanceof
|
|
4367
|
+
const state2 = error instanceof SQL3.PostgresError ? error.errno : undefined;
|
|
4171
4368
|
const code = state2 === "42P01" || state2 === "42703" ? "MAINTENANCE_SCHEMA_UNAVAILABLE" : state2 === "42501" ? "MAINTENANCE_ACCESS_DENIED" : state2 === "25006" ? "MAINTENANCE_WRITE_REFUSED" : state2 === "57014" || state2 === "55P03" ? "MAINTENANCE_TIMEOUT" : ["08000", "08001", "08003", "08004", "08006", "08007", "08P01", "28000", "28P01", "57P03"].includes(state2 ?? "") ? "MAINTENANCE_CONNECTION_FAILED" : message.includes("expired") || message.includes("expiry") ? "INVALID_EXPIRY" : message.includes("receipt") || message.includes("operator") ? "INVALID_OPERATOR_RECEIPT" : message.includes("manifest") || message.includes("input") ? "INVALID_MANIFEST" : message.includes("database") || message.includes("store") ? "STORE_UNAVAILABLE" : "MAINTENANCE_FAILED";
|
|
4172
4369
|
if (options.json || !process.stdout.isTTY)
|
|
4173
4370
|
console.log(JSON.stringify({ status: "failed", code }));
|
package/bin/mcp.js
CHANGED
|
@@ -20019,7 +20019,7 @@ var package_default;
|
|
|
20019
20019
|
var init_package = __esm(() => {
|
|
20020
20020
|
package_default = {
|
|
20021
20021
|
name: "@hasna/skills",
|
|
20022
|
-
version: "0.10.
|
|
20022
|
+
version: "0.10.51",
|
|
20023
20023
|
description: "Skills library for AI coding agents",
|
|
20024
20024
|
type: "module",
|
|
20025
20025
|
bin: {
|
|
@@ -38370,7 +38370,9 @@ function inferencePreference(key, child, version2) {
|
|
|
38370
38370
|
function settingsDigest(text, version2 = 1) {
|
|
38371
38371
|
const value = parse6(text);
|
|
38372
38372
|
value.entries = value.entries.filter(([key, child]) => {
|
|
38373
|
-
if (version2
|
|
38373
|
+
if (version2 === 4 && key === "theme" && child.kind === "string" && BUILTIN_THEMES.has(child.value))
|
|
38374
|
+
return false;
|
|
38375
|
+
if (version2 !== 1 && inferencePreference(key, child, version2 === 4 ? 3 : version2))
|
|
38374
38376
|
return false;
|
|
38375
38377
|
if (key === "model") {
|
|
38376
38378
|
need(child.kind === "string", "contains an invalid model selection");
|
|
@@ -38418,6 +38420,16 @@ function hashClaudeSettingsReplacementV3(text, budget) {
|
|
|
38418
38420
|
budget.remaining -= bytes;
|
|
38419
38421
|
return settingsDigest(text, 3);
|
|
38420
38422
|
}
|
|
38423
|
+
function captureClaudeSettingsV4(path, budget = { remaining: 256 * 1024 * 1024 }) {
|
|
38424
|
+
return { path, hashMode: "claude-settings-v4", sha256: settingsDigest(readNativeSettingsWitnessFile(path, budget), 4) };
|
|
38425
|
+
}
|
|
38426
|
+
function hashClaudeSettingsReplacementV4(text, budget) {
|
|
38427
|
+
need(typeof text === "string", "requires settings text");
|
|
38428
|
+
const bytes = Buffer.byteLength(text);
|
|
38429
|
+
need(bytes <= CLAUDE_SETTINGS_WITNESS_LIMITS.bytes && Number.isSafeInteger(budget.remaining) && budget.remaining >= bytes, "exceeds its byte limit");
|
|
38430
|
+
budget.remaining -= bytes;
|
|
38431
|
+
return settingsDigest(text, 4);
|
|
38432
|
+
}
|
|
38421
38433
|
function hashNativeJsonControls(text, excludedMetadata) {
|
|
38422
38434
|
need(Buffer.byteLength(text) <= CLAUDE_SETTINGS_WITNESS_LIMITS.bytes, "exceeds its byte limit");
|
|
38423
38435
|
const value = parse6(text);
|
|
@@ -38450,7 +38462,7 @@ function hashSumiNativeJsonControls(text) {
|
|
|
38450
38462
|
});
|
|
38451
38463
|
return createHash2("sha256").update("hasna.skills.sumi-settings.v1\x00").update(JSON.stringify(value)).digest("hex");
|
|
38452
38464
|
}
|
|
38453
|
-
var CLAUDE_SETTINGS_WITNESS_LIMITS, sameFile = (a, b) => a.dev === b.dev && a.ino === b.ino && a.mode === b.mode && a.uid === b.uid && a.gid === b.gid && a.nlink === b.nlink && a.size === b.size && a.mtimeNs === b.mtimeNs && a.ctimeNs === b.ctimeNs, BOOLEAN_PREFERENCES, ENUM_PREFERENCES, BUILTIN_MODEL_SELECTIONS, PERSISTED_EFFORT_LEVELS;
|
|
38465
|
+
var CLAUDE_SETTINGS_WITNESS_LIMITS, sameFile = (a, b) => a.dev === b.dev && a.ino === b.ino && a.mode === b.mode && a.uid === b.uid && a.gid === b.gid && a.nlink === b.nlink && a.size === b.size && a.mtimeNs === b.mtimeNs && a.ctimeNs === b.ctimeNs, BOOLEAN_PREFERENCES, ENUM_PREFERENCES, BUILTIN_MODEL_SELECTIONS, CLAUDE_BUILTIN_THEMES, BUILTIN_THEMES, PERSISTED_EFFORT_LEVELS;
|
|
38454
38466
|
var init_claude_settings_witness = __esm(() => {
|
|
38455
38467
|
CLAUDE_SETTINGS_WITNESS_LIMITS = Object.freeze({ bytes: 1024 * 1024, rows: 1024, depth: 32, nodes: 65536, stringCharacters: 16384, pathCharacters: 4096 });
|
|
38456
38468
|
BOOLEAN_PREFERENCES = new Set([
|
|
@@ -38504,6 +38516,8 @@ var init_claude_settings_witness = __esm(() => {
|
|
|
38504
38516
|
"claude-opus-4-6[1m]",
|
|
38505
38517
|
"claude-sonnet-4-6[1m]"
|
|
38506
38518
|
]);
|
|
38519
|
+
CLAUDE_BUILTIN_THEMES = Object.freeze(["auto", "dark", "light", "dark-daltonized", "light-daltonized", "dark-ansi", "light-ansi"]);
|
|
38520
|
+
BUILTIN_THEMES = new Set(CLAUDE_BUILTIN_THEMES);
|
|
38507
38521
|
PERSISTED_EFFORT_LEVELS = new Set(["low", "medium", "high", "xhigh"]);
|
|
38508
38522
|
});
|
|
38509
38523
|
|
|
@@ -38524,6 +38538,29 @@ var init_sumi_settings_witness = __esm(() => {
|
|
|
38524
38538
|
SUMI_DISCOVERY_PROJECTION_FIELDS = ["skills", "plugin", "plugins", "permissions"];
|
|
38525
38539
|
});
|
|
38526
38540
|
|
|
38541
|
+
// src/lib/codex-native-compatibility.ts
|
|
38542
|
+
function supportsCodexNativeCapability(version2, capability) {
|
|
38543
|
+
return typeof version2 === "string" && Object.hasOwn(MEASURED_CODEX_CAPABILITIES, version2) && MEASURED_CODEX_CAPABILITIES[version2].includes(capability);
|
|
38544
|
+
}
|
|
38545
|
+
var MEASURED_CODEX_CAPABILITIES, SUPPORTED_CODEX_HOOK_VERSIONS;
|
|
38546
|
+
var init_codex_native_compatibility = __esm(() => {
|
|
38547
|
+
MEASURED_CODEX_CAPABILITIES = {
|
|
38548
|
+
"codex-cli 0.153.0": ["hooks"],
|
|
38549
|
+
"codex-cli 0.154.0": ["hooks"],
|
|
38550
|
+
"codex-cli 0.155.0": ["hooks"],
|
|
38551
|
+
"codex-cli 0.155.1": ["hooks"],
|
|
38552
|
+
"codex-cli 0.156.1": ["hooks"],
|
|
38553
|
+
"codex-cli 0.157.0": ["hooks"],
|
|
38554
|
+
"codex-cli 0.157.1": ["hooks"],
|
|
38555
|
+
"codex-cli 0.158.0": ["hooks"],
|
|
38556
|
+
"codex-cli 0.159.0": ["hooks"],
|
|
38557
|
+
"codex-cli 0.159.2": ["hooks", "qualified-skill-catalog"],
|
|
38558
|
+
"codex-cli 0.160.0": ["hooks", "qualified-skill-catalog", "installed-plugin-review"],
|
|
38559
|
+
"codex-cli 0.160.1": ["hooks", "qualified-skill-catalog", "installed-plugin-review"]
|
|
38560
|
+
};
|
|
38561
|
+
SUPPORTED_CODEX_HOOK_VERSIONS = Object.freeze(Object.keys(MEASURED_CODEX_CAPABILITIES).filter((version2) => supportsCodexNativeCapability(version2, "hooks")));
|
|
38562
|
+
});
|
|
38563
|
+
|
|
38527
38564
|
// src/lib/agent-policy-limits.ts
|
|
38528
38565
|
import { basename as basename4, isAbsolute as isAbsolute4, join as join10, resolve as resolve3, sep as sep3 } from "path";
|
|
38529
38566
|
function object4(value) {
|
|
@@ -38590,7 +38627,7 @@ function assertAgentPolicyCollections(policy) {
|
|
|
38590
38627
|
}
|
|
38591
38628
|
if (bridge.codexInactivePlugins !== undefined) {
|
|
38592
38629
|
const controls = array3(bridge.codexInactivePlugins, 4096), ids = new Set;
|
|
38593
|
-
requireBound(controls.length === 0 || object4(bridge.codexPluginSkillReview) && bridge.codexPluginSkillReview.version
|
|
38630
|
+
requireBound(controls.length === 0 || object4(bridge.codexPluginSkillReview) && supportsCodexNativeCapability(bridge.codexPluginSkillReview.version, "installed-plugin-review") && typeof bridge.codexPluginSkillReview.catalogSha256 === "string" && /^[a-f0-9]{64}$/.test(bridge.codexPluginSkillReview.catalogSha256));
|
|
38594
38631
|
for (const control of controls) {
|
|
38595
38632
|
requireBound(object4(control) && Object.keys(control).every((key) => ["pluginId", "namespace", "pluginParent", "sourceType", "sourceSha256"].includes(key)));
|
|
38596
38633
|
text(control.pluginId, 1024);
|
|
@@ -38642,7 +38679,7 @@ function assertAgentPolicyCollections(policy) {
|
|
|
38642
38679
|
}
|
|
38643
38680
|
if (value.codexInstallationInputs !== undefined) {
|
|
38644
38681
|
const proof = record3(value.codexInstallationInputs, 4), inputs = array3(proof.plugins, 4096), ids = new Set;
|
|
38645
|
-
requireBound(agent === "codex" && value.agent === "codex" && value.method === "reviewed" && proof.version
|
|
38682
|
+
requireBound(agent === "codex" && value.agent === "codex" && value.method === "reviewed" && supportsCodexNativeCapability(proof.version, "installed-plugin-review") && typeof proof.catalogSha256 === "string" && /^[a-f0-9]{64}$/.test(proof.catalogSha256) && inputs.length > 0 && object4(bridge.codexPluginSkillReview) && bridge.codexPluginSkillReview.version === proof.version && bridge.codexPluginSkillReview.catalogSha256 === proof.catalogSha256);
|
|
38646
38683
|
for (const input2 of inputs) {
|
|
38647
38684
|
requireBound(object4(input2) && Object.keys(input2).every((key) => ["pluginId", "namespace", "pluginParent", "sourceRoot", "sourceSha256"].includes(key)));
|
|
38648
38685
|
text(input2.pluginId, 1024);
|
|
@@ -38666,14 +38703,14 @@ function assertAgentPolicyCollections(policy) {
|
|
|
38666
38703
|
text(source.path);
|
|
38667
38704
|
requireBound(source.sha256 === null || typeof source.sha256 === "string" && /^[a-f0-9]{64}$/.test(source.sha256));
|
|
38668
38705
|
if (source.hashMode !== undefined)
|
|
38669
|
-
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));
|
|
38706
|
+
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));
|
|
38670
38707
|
if (source.hashMode === "claude-plugin-manifest-v1")
|
|
38671
38708
|
requireBound(agent === "claude" && value.agent === "claude" && ["automatic", "reviewed"].includes(value.method) && !/[\x00-\x1f\x7f]/.test(source.path) && isAbsolute4(source.path) && resolve3(source.path) === source.path && source.path.endsWith(join10(sep3, ".claude-plugin", "plugin.json")) && source.managedPlugins === undefined);
|
|
38672
38709
|
if (source.hashMode === "sumi-settings-v1")
|
|
38673
38710
|
requireBound(agent === "sumi" && value.agent === "sumi" && value.method === "reviewed" && !/[\x00-\x1f\x7f]/.test(source.path) && isAbsolute4(source.path) && resolve3(source.path) === source.path && basename4(source.path) === "sumi.json");
|
|
38674
38711
|
if (source.hashMode === "codex-settings-v1" || source.hashMode === "codex-settings-v2" || (source.hashMode === "codex-settings-v3" || source.hashMode === "codex-settings-v4"))
|
|
38675
38712
|
requireBound(agent === "codex" && value.agent === "codex" && value.method === "reviewed" && !/[\x00-\x1f\x7f]/.test(source.path) && isAbsolute4(source.path) && resolve3(source.path) === source.path && basename4(source.path) === "config.toml");
|
|
38676
|
-
if (source.hashMode === "claude-settings-v1" || source.hashMode === "claude-settings-v2" || source.hashMode === "claude-settings-v3")
|
|
38713
|
+
if (source.hashMode === "claude-settings-v1" || source.hashMode === "claude-settings-v2" || (source.hashMode === "claude-settings-v3" || source.hashMode === "claude-settings-v4"))
|
|
38677
38714
|
requireBound(agent === "claude" && value.agent === "claude" && value.method === "reviewed" && !/[\x00-\x1f\x7f]/.test(source.path) && isAbsolute4(source.path) && resolve3(source.path) === source.path && basename4(source.path) === "settings.json");
|
|
38678
38715
|
if (source.hashMode === "claude-marketplace-registry" || source.hashMode === "claude-marketplace-registry-v2")
|
|
38679
38716
|
requireBound(agent === "claude" && value.agent === "claude" && value.method === "reviewed" && !/[\x00-\x1f\x7f]/.test(source.path) && isAbsolute4(source.path) && resolve3(source.path) === source.path && basename4(source.path) === "known_marketplaces.json");
|
|
@@ -38707,6 +38744,7 @@ function assertAgentPolicyCollections(policy) {
|
|
|
38707
38744
|
}
|
|
38708
38745
|
var AGENT_POLICY_LIMITS;
|
|
38709
38746
|
var init_agent_policy_limits = __esm(() => {
|
|
38747
|
+
init_codex_native_compatibility();
|
|
38710
38748
|
AGENT_POLICY_LIMITS = Object.freeze({ bytes: 1024 * 1024, agents: 16, discoverySources: 2048, discoveryRawSourceBytes: 64 * 1024 * 1024, discoveryRawTotalBytes: 256 * 1024 * 1024, discoveryPathLinks: 40, discoveryPathSteps: 256, discoveryPathSourceMetadataBytes: 64 * 1024, discoveryPathTotalMetadataBytes: 8 * 1024 * 1024, discoveryRoots: 512, discoveryDirectories: 64, discoveryDirectoryEntries: 20000, discoveryDirectoryBytes: 8 * 1024 * 1024, builtinNames: 2048, rootAliases: 2, fields: 64, pathCharacters: 4096 });
|
|
38711
38749
|
});
|
|
38712
38750
|
|
|
@@ -47938,28 +47976,6 @@ function isCodexLocalStdioMcpServer(name, server) {
|
|
|
47938
47976
|
}
|
|
47939
47977
|
}
|
|
47940
47978
|
|
|
47941
|
-
// src/lib/codex-native-compatibility.ts
|
|
47942
|
-
function supportsCodexNativeCapability(version2, capability) {
|
|
47943
|
-
return typeof version2 === "string" && Object.hasOwn(MEASURED_CODEX_CAPABILITIES, version2) && MEASURED_CODEX_CAPABILITIES[version2].includes(capability);
|
|
47944
|
-
}
|
|
47945
|
-
var MEASURED_CODEX_CAPABILITIES, SUPPORTED_CODEX_HOOK_VERSIONS;
|
|
47946
|
-
var init_codex_native_compatibility = __esm(() => {
|
|
47947
|
-
MEASURED_CODEX_CAPABILITIES = {
|
|
47948
|
-
"codex-cli 0.153.0": ["hooks"],
|
|
47949
|
-
"codex-cli 0.154.0": ["hooks"],
|
|
47950
|
-
"codex-cli 0.155.0": ["hooks"],
|
|
47951
|
-
"codex-cli 0.155.1": ["hooks"],
|
|
47952
|
-
"codex-cli 0.156.1": ["hooks"],
|
|
47953
|
-
"codex-cli 0.157.0": ["hooks"],
|
|
47954
|
-
"codex-cli 0.157.1": ["hooks"],
|
|
47955
|
-
"codex-cli 0.158.0": ["hooks"],
|
|
47956
|
-
"codex-cli 0.159.0": ["hooks"],
|
|
47957
|
-
"codex-cli 0.159.2": ["hooks", "qualified-skill-catalog"],
|
|
47958
|
-
"codex-cli 0.160.0": ["hooks", "qualified-skill-catalog"]
|
|
47959
|
-
};
|
|
47960
|
-
SUPPORTED_CODEX_HOOK_VERSIONS = Object.freeze(Object.keys(MEASURED_CODEX_CAPABILITIES).filter((version2) => supportsCodexNativeCapability(version2, "hooks")));
|
|
47961
|
-
});
|
|
47962
|
-
|
|
47963
47979
|
// src/lib/codex-hook-rpc.ts
|
|
47964
47980
|
var init_codex_hook_rpc = __esm(() => {
|
|
47965
47981
|
init_codex_corpus_write();
|
|
@@ -50580,13 +50596,13 @@ function projected(source, changes, budget2 = discoveryByteBudget()) {
|
|
|
50580
50596
|
throw new Error(`Native discovery input changed; run skills hook install with a fresh discovery review: ${source.path}`);
|
|
50581
50597
|
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;
|
|
50582
50598
|
}
|
|
50583
|
-
if (source.hashMode === "claude-settings-v1" || source.hashMode === "claude-settings-v2" || source.hashMode === "claude-settings-v3") {
|
|
50599
|
+
if (source.hashMode === "claude-settings-v1" || source.hashMode === "claude-settings-v2" || (source.hashMode === "claude-settings-v3" || source.hashMode === "claude-settings-v4")) {
|
|
50584
50600
|
if (source.format !== undefined || source.fields !== undefined || source.managedPlugins !== undefined || typeof source.sha256 !== "string" || !/^[a-f0-9]{64}$/.test(source.sha256))
|
|
50585
50601
|
throw new Error("Claude settings witnesses require exact typed metadata");
|
|
50586
|
-
const current = (source.hashMode === "claude-settings-v3" ? captureClaudeSettingsV3 : source.hashMode === "claude-settings-v2" ? captureClaudeSettingsV2 : captureClaudeSettings)(source.path, budget2).sha256;
|
|
50602
|
+
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;
|
|
50587
50603
|
if (current !== source.sha256)
|
|
50588
50604
|
throw new Error(`Native discovery input changed; run skills hook install with a fresh discovery review: ${source.path}`);
|
|
50589
|
-
return changes?.has(source.path) ? (source.hashMode === "claude-settings-v3" ? hashClaudeSettingsReplacementV3 : source.hashMode === "claude-settings-v2" ? hashClaudeSettingsReplacementV2 : hashClaudeSettingsReplacement)(changes.get(source.path), budget2) : current;
|
|
50605
|
+
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;
|
|
50590
50606
|
}
|
|
50591
50607
|
if (source.hashMode === "claude-marketplace-registry" || source.hashMode === "claude-marketplace-registry-v2") {
|
|
50592
50608
|
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))
|
|
@@ -50781,7 +50797,7 @@ function codexInstallationRoots(binding) {
|
|
|
50781
50797
|
const proof = binding.codexInstallationInputs;
|
|
50782
50798
|
if (proof === undefined)
|
|
50783
50799
|
return [];
|
|
50784
|
-
if (binding.agent !== "codex" || binding.method !== "reviewed" || proof.version
|
|
50800
|
+
if (binding.agent !== "codex" || binding.method !== "reviewed" || !supportsCodexNativeCapability(proof.version, "installed-plugin-review") || !/^[a-f0-9]{64}$/.test(proof.catalogSha256) || !Array.isArray(proof.plugins) || !proof.plugins.length)
|
|
50785
50801
|
throw new Error("Invalid native installation input proof");
|
|
50786
50802
|
const cache = dirname15(dirname15(proof.plugins[0].pluginParent));
|
|
50787
50803
|
const config2 = join26(dirname15(dirname15(cache)), "config.toml"), home = dirname15(dirname15(dirname15(cache)));
|
|
@@ -50805,7 +50821,7 @@ function assertMarketplaceBinding(binding, source) {
|
|
|
50805
50821
|
throw new Error("Sumi settings witnesses require explicit reviewed Sumi configuration");
|
|
50806
50822
|
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"))
|
|
50807
50823
|
throw new Error("Codex settings witnesses require explicit reviewed Codex configuration");
|
|
50808
|
-
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"))
|
|
50824
|
+
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"))
|
|
50809
50825
|
throw new Error("Claude settings witnesses require explicit reviewed Claude configuration");
|
|
50810
50826
|
if ((source.hashMode === "claude-marketplace-registry" || source.hashMode === "claude-marketplace-registry-v2") && (binding.agent !== "claude" || binding.method !== "reviewed"))
|
|
50811
50827
|
throw new Error("Claude marketplace witnesses require explicit reviewed Claude discovery");
|
|
@@ -50927,7 +50943,7 @@ function resolveAgentDiscovery(options) {
|
|
|
50927
50943
|
verifyAgentDiscovery(retained);
|
|
50928
50944
|
if (!retained.sources.some((source) => source.path === canonical7(configPath) && source.format === undefined && source.fields === undefined))
|
|
50929
50945
|
unresolved("retained review is missing the full agent configuration source");
|
|
50930
|
-
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)))
|
|
50946
|
+
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)))
|
|
50931
50947
|
unresolved("retained settings witness names another configuration source");
|
|
50932
50948
|
const covered = supersedesSettingsProjection(agent, retained.sources, canonical7(configPath)) ? sources.filter((source) => !isSupersededSettingsProjection(agent, canonical7(configPath), source)) : sources;
|
|
50933
50949
|
if (covered.some((source) => !retained.sources.some((saved) => isDeepStrictEqual4(saved, source))) || [...roots].some((root) => !retained.roots.includes(root)) || agent === "gemini" && JSON.stringify(retained.builtinNames) !== JSON.stringify(builtinNames))
|
|
@@ -50941,7 +50957,7 @@ function resolveAgentDiscovery(options) {
|
|
|
50941
50957
|
if (review.sources.some((source) => source.format !== undefined || source.fields !== undefined))
|
|
50942
50958
|
throw new Error("Explicit discovery reviews require full source-file hashes");
|
|
50943
50959
|
verifyAgentDiscovery(supplied);
|
|
50944
|
-
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)))
|
|
50960
|
+
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)))
|
|
50945
50961
|
throw new Error("Semantic settings witnesses must name the configured agent configuration source");
|
|
50946
50962
|
if (!review.sources.some((source) => source.path === canonical7(configPath)))
|
|
50947
50963
|
throw new Error("Discovery review must include the agent configuration source");
|
|
@@ -51108,6 +51124,7 @@ var init_agent_discovery = __esm(() => {
|
|
|
51108
51124
|
init_codex_plugin_skill_controls();
|
|
51109
51125
|
init_agent_sumi();
|
|
51110
51126
|
init_native_discovery_roots();
|
|
51127
|
+
init_codex_native_compatibility();
|
|
51111
51128
|
init_agent_discovery_directories();
|
|
51112
51129
|
});
|
|
51113
51130
|
|
package/bin/migrate.js
CHANGED
package/bin/server.js
CHANGED
|
@@ -24140,7 +24140,7 @@ restoreLaunchCwd();
|
|
|
24140
24140
|
// package.json
|
|
24141
24141
|
var package_default = {
|
|
24142
24142
|
name: "@hasna/skills",
|
|
24143
|
-
version: "0.10.
|
|
24143
|
+
version: "0.10.51",
|
|
24144
24144
|
description: "Skills library for AI coding agents",
|
|
24145
24145
|
type: "module",
|
|
24146
24146
|
bin: {
|
package/bin/worker.js
CHANGED
|
@@ -24143,7 +24143,7 @@ import { randomUUID as randomUUID6 } from "crypto";
|
|
|
24143
24143
|
// package.json
|
|
24144
24144
|
var package_default = {
|
|
24145
24145
|
name: "@hasna/skills",
|
|
24146
|
-
version: "0.10.
|
|
24146
|
+
version: "0.10.51",
|
|
24147
24147
|
description: "Skills library for AI coding agents",
|
|
24148
24148
|
type: "module",
|
|
24149
24149
|
bin: {
|
package/dist/index.d.ts
CHANGED
|
@@ -64,7 +64,7 @@ export { planAgentIntegration, planClaudeStopHookUpdate, planClaudePreToolUseHoo
|
|
|
64
64
|
export type { ClaudeManagedHookProjection, ClaudeManagedHookProjectionOptions } from "./lib/agent-integration.js";
|
|
65
65
|
export { captureDiscoveryDirectories, captureDiscoveryByteSources, captureDiscoveryPathSources, type DiscoveryDirectory, type DiscoverySource } from "./lib/agent-discovery.js";
|
|
66
66
|
export { captureClaudeMarketplaceRegistry, captureClaudeMarketplaceRegistryV2 } from "./lib/claude-marketplace-registry.js";
|
|
67
|
-
export { captureClaudeSettings, captureClaudeSettingsV2, captureClaudeSettingsV3, upgradeClaudeSettingsWitness } from "./lib/claude-settings-witness.js";
|
|
67
|
+
export { captureClaudeSettings, captureClaudeSettingsV2, captureClaudeSettingsV3, captureClaudeSettingsV4, upgradeClaudeSettingsWitness, upgradeClaudeSettingsWitnessV4 } from "./lib/claude-settings-witness.js";
|
|
68
68
|
export { buildPluginProjection, pluginTreeDigest, type PluginProjectionManifest, type PluginPayloadMapping, type PluginFileWitness } from "./lib/plugin-projection.js";
|
|
69
69
|
export { planPluginAdmission, admitPlugin, resolveAdmittedPlugin, pluginResolverCommand, type PluginAdmissionTarget, type PluginAdmissionBinding, type PluginAdmissionPrincipal, type PluginAdmissionPlan, type PluginAdmissionIdentity, type PluginBundleIdentity, type PluginRoutingIdentity, type PluginAdmissionReceipt } from "./lib/plugin-admission.js";
|
|
70
70
|
export { captureManagedPluginRegistry, type ManagedPluginRegistrationWitness } from "./lib/plugin-discovery.js";
|