@hasna/skills 0.9.6 → 0.9.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/index.js +138 -49
- package/bin/mcp.js +1 -1
- package/bin/migrate.js +1 -1
- package/bin/server.js +1 -1
- package/bin/worker.js +1 -1
- package/dist/index.js +1 -1
- package/dist/lib/agent-codex-trust.d.ts +15 -0
- package/dist/lib/codex-hook-trust-layout.d.ts +7 -1
- package/dist/sdk/index.js +1 -1
- package/package.json +1 -1
package/bin/index.js
CHANGED
|
@@ -36868,7 +36868,7 @@ var package_default;
|
|
|
36868
36868
|
var init_package = __esm(() => {
|
|
36869
36869
|
package_default = {
|
|
36870
36870
|
name: "@hasna/skills",
|
|
36871
|
-
version: "0.9.
|
|
36871
|
+
version: "0.9.8",
|
|
36872
36872
|
description: "Skills library for AI coding agents",
|
|
36873
36873
|
type: "module",
|
|
36874
36874
|
bin: {
|
|
@@ -108033,7 +108033,7 @@ var init_codex_hook_rpc = __esm(() => {
|
|
|
108033
108033
|
|
|
108034
108034
|
// src/lib/codex-hook-trust-layout.ts
|
|
108035
108035
|
import { isDeepStrictEqual as isDeepStrictEqual5 } from "util";
|
|
108036
|
-
function codexTrustTextWitness(text3, keys3) {
|
|
108036
|
+
function codexTrustTextWitness(text3, keys3, canonicalize = true) {
|
|
108037
108037
|
const parsed = Bun.TOML.parse(text3), wanted = new Set(keys3);
|
|
108038
108038
|
const headers = [...text3.matchAll(/^[ \t]*(\[[^\r\n]+\])[ \t]*(#[^\r\n]*)?(?:\r?\n|$)/gm)];
|
|
108039
108039
|
if (headers.length > 512)
|
|
@@ -108105,9 +108105,19 @@ function codexTrustTextWitness(text3, keys3) {
|
|
|
108105
108105
|
let result2 = text3;
|
|
108106
108106
|
for (const span of replacements2.reverse())
|
|
108107
108107
|
result2 = result2.slice(0, span.start) + span.comments + result2.slice(span.end);
|
|
108108
|
-
return canonicalizeTableOrder(result2).split(/\r?\n/).filter((line) => line.trim()).join(`
|
|
108108
|
+
return (canonicalize ? canonicalizeTableOrder(result2) : result2).split(/\r?\n/).filter((line) => line.trim()).join(`
|
|
108109
108109
|
`);
|
|
108110
108110
|
}
|
|
108111
|
+
function codexTrustReconcileWitness(text3, keys3) {
|
|
108112
|
+
return codexTrustTextWitness(text3, keys3, false).replace(/[ \t]+$/gm, "");
|
|
108113
|
+
}
|
|
108114
|
+
function codexTrustUnmanagedSemantic(text3, keys3) {
|
|
108115
|
+
const parsed = structuredClone(Bun.TOML.parse(text3));
|
|
108116
|
+
for (const key of keys3)
|
|
108117
|
+
if (parsed.hooks?.state?.[key] !== undefined)
|
|
108118
|
+
delete parsed.hooks.state[key];
|
|
108119
|
+
return JSON.stringify(stableSemantic(prune(parsed)));
|
|
108120
|
+
}
|
|
108111
108121
|
var fail4 = () => new Error('CODEX_HOOK_TRUST_UNSUPPORTED_LAYOUT: preserve and convert hook trust to ordinary [hooks.state."<key>"] tables before enrollment'), prune = (value) => {
|
|
108112
108122
|
if (value.hooks?.state && !Object.keys(value.hooks.state).length)
|
|
108113
108123
|
delete value.hooks.state;
|
|
@@ -108146,6 +108156,12 @@ var fail4 = () => new Error('CODEX_HOOK_TRUST_UNSUPPORTED_LAYOUT: preserve and c
|
|
|
108146
108156
|
const simple = blocks.filter((block) => !block.key.startsWith("[["));
|
|
108147
108157
|
const arrays = blocks.filter((block) => block.key.startsWith("[["));
|
|
108148
108158
|
return prefix + [...simple, ...arrays].map((block) => block.text).join("");
|
|
108159
|
+
}, stableSemantic = (value) => {
|
|
108160
|
+
if (Array.isArray(value))
|
|
108161
|
+
return value.map(stableSemantic);
|
|
108162
|
+
if (value && typeof value === "object")
|
|
108163
|
+
return Object.fromEntries(Object.keys(value).sort().map((key) => [key, stableSemantic(value[key])]));
|
|
108164
|
+
return value;
|
|
108149
108165
|
};
|
|
108150
108166
|
var init_codex_hook_trust_layout = () => {};
|
|
108151
108167
|
|
|
@@ -108240,11 +108256,33 @@ var init_codex_hook_trust_identity = __esm(() => {
|
|
|
108240
108256
|
});
|
|
108241
108257
|
|
|
108242
108258
|
// src/lib/agent-codex-trust.ts
|
|
108243
|
-
import { lstatSync as lstatSync28, mkdirSync as mkdirSync25, readdirSync as readdirSync20 } from "fs";
|
|
108259
|
+
import { lstatSync as lstatSync28, mkdirSync as mkdirSync25, readdirSync as readdirSync20, readFileSync as readFileSync37, realpathSync as realpathSync13, statSync as statSync21 } from "fs";
|
|
108244
108260
|
import { createHash as createHash26, randomUUID as randomUUID10 } from "crypto";
|
|
108245
|
-
import {
|
|
108261
|
+
import { execFileSync } from "child_process";
|
|
108262
|
+
import { dirname as dirname30, isAbsolute as isAbsolute25, join as join56, resolve as resolve22 } from "path";
|
|
108246
108263
|
import { homedir as homedir11 } from "os";
|
|
108247
108264
|
import { isDeepStrictEqual as isDeepStrictEqual6 } from "util";
|
|
108265
|
+
function verifyReleaseArtifact(proof, skillsCli) {
|
|
108266
|
+
need4(isAbsolute25(proof.packageTarPath) && !proof.packageTarPath.includes("\x00"), "RECONCILE_RELEASE_PROVENANCE_PATH");
|
|
108267
|
+
const tarPath = realpathSync13(proof.packageTarPath);
|
|
108268
|
+
need4(statSync21(tarPath).isFile(), "RECONCILE_RELEASE_PROVENANCE_PATH");
|
|
108269
|
+
const tarBytes = readFileSync37(tarPath);
|
|
108270
|
+
need4(tarBytes.byteLength === proof.packageTarBytes && createHash26("sha256").update(tarBytes).digest("hex") === proof.packageTarSha256, "RECONCILE_RELEASE_ARTIFACT_CHANGED");
|
|
108271
|
+
const packageRoot = dirname30(dirname30(realpathSync13(skillsCli.receipt.path)));
|
|
108272
|
+
const manifest = readFileSync37(join56(packageRoot, "package.json"));
|
|
108273
|
+
need4(createHash26("sha256").update(manifest).digest("hex") === skillsCli.receipt.manifestSha256 && skillsCli.receipt.manifestSha256 === proof.manifestSha256, "RECONCILE_RELEASE_MANIFEST_CHANGED");
|
|
108274
|
+
need4(createHash26("sha256").update(readFileSync37(skillsCli.receipt.path)).digest("hex") === proof.executableSha256 && skillsCli.receipt.sha256 === proof.executableSha256, "RECONCILE_RELEASE_EXECUTABLE_CHANGED");
|
|
108275
|
+
const members2 = [["package/package.json", manifest], ["package/bin/index.js", readFileSync37(skillsCli.receipt.path)]];
|
|
108276
|
+
for (const [member, expected] of members2) {
|
|
108277
|
+
let actual;
|
|
108278
|
+
try {
|
|
108279
|
+
actual = execFileSync("tar", ["-xOf", tarPath, member], { maxBuffer: 32 * 1024 * 1024 });
|
|
108280
|
+
} catch {
|
|
108281
|
+
throw new Error("RECONCILE_RELEASE_ARTIFACT_MEMBER_MISSING");
|
|
108282
|
+
}
|
|
108283
|
+
need4(Buffer.compare(actual, expected) === 0, "RECONCILE_RELEASE_ARTIFACT_MEMBER_CHANGED");
|
|
108284
|
+
}
|
|
108285
|
+
}
|
|
108248
108286
|
async function reconcileCodexNativeHooks(options, connect = connectCodexHookRpc) {
|
|
108249
108287
|
let rpc;
|
|
108250
108288
|
try {
|
|
@@ -108267,24 +108305,54 @@ async function reconcileCodexNativeHooks(options, connect = connectCodexHookRpc)
|
|
|
108267
108305
|
need4(makePlanDigest(digestInput) === intent.planDigest, "RECONCILE_PLAN_CHANGED");
|
|
108268
108306
|
need4(isDeepStrictEqual6(intent.hooks, admitted.filter((hook) => !hook.enabled || hook.trustStatus !== "trusted")), "RECONCILE_INTENT_HOOKS_CHANGED");
|
|
108269
108307
|
need4(configBefore.sha256 === intent.beforeSha256 && hooksBefore.sha256 === intent.hooksSha256 && policyBefore.sha256 === intent.policySha256, "RECONCILE_JOURNAL_CHANGED");
|
|
108308
|
+
const policyCurrent = snapshot(join56(dataDir3, "agent-policy.json"), true);
|
|
108309
|
+
let supersededBinding = false;
|
|
108310
|
+
if (policyCurrent.sha256 !== policyBefore.sha256) {
|
|
108311
|
+
need4(options.supersedeBinding === true, "RECONCILE_POLICY_CHANGED");
|
|
108312
|
+
const oldPolicy = JSON.parse(policyBefore.text), currentPolicy = JSON.parse(policyCurrent.text);
|
|
108313
|
+
need4(isDeepStrictEqual6(withoutCodexCommand(oldPolicy), withoutCodexCommand(currentPolicy)), "RECONCILE_POLICY_CHANGED");
|
|
108314
|
+
supersededBinding = true;
|
|
108315
|
+
}
|
|
108316
|
+
if (supersededBinding) {
|
|
108317
|
+
need4(Array.isArray(intent.nativeHooks) && intent.nativeHooks.length > 0, "RECONCILE_NATIVE_INVENTORY_REQUIRED");
|
|
108318
|
+
const proof = options.releaseProof;
|
|
108319
|
+
need4(!!proof && isAbsolute25(proof.packageTarPath) && /^[a-f0-9]{64}$/.test(proof.packageTarSha256) && Number.isInteger(proof.packageTarBytes) && proof.packageTarBytes > 0 && /^[a-f0-9]{64}$/.test(proof.manifestSha256) && /^[a-f0-9]{64}$/.test(proof.executableSha256), "RECONCILE_RELEASE_PROVENANCE_REQUIRED");
|
|
108320
|
+
}
|
|
108270
108321
|
const currentConfig = snapshot(intent.configPath, true);
|
|
108271
|
-
|
|
108322
|
+
const managedKeys = intent.hooks.map((h) => h.key);
|
|
108323
|
+
const witnessSame = codexTrustReconcileWitness(configBefore.text, managedKeys) === codexTrustReconcileWitness(currentConfig.text, managedKeys);
|
|
108324
|
+
const unmanagedSame = codexTrustUnmanagedSemantic(configBefore.text, managedKeys) === codexTrustUnmanagedSemantic(currentConfig.text, managedKeys);
|
|
108325
|
+
need4(unmanagedSame && (witnessSame || supersededBinding), "RECONCILE_UNRELATED_CONFIG_CHANGED");
|
|
108272
108326
|
const before2 = structure(configBefore.text), current = structure(currentConfig.text), expectedConfig = structuredClone(before2);
|
|
108273
108327
|
expectedConfig.hooks ??= {};
|
|
108274
108328
|
expectedConfig.hooks.state ??= {};
|
|
108275
108329
|
for (const hook of intent.hooks)
|
|
108276
108330
|
expectedConfig.hooks.state[hook.key] = { ...expectedConfig.hooks.state[hook.key], enabled: true, trusted_hash: hook.currentHash };
|
|
108277
|
-
|
|
108278
|
-
|
|
108279
|
-
|
|
108280
|
-
|
|
108331
|
+
if (supersededBinding) {
|
|
108332
|
+
for (const hook of intent.hooks) {
|
|
108333
|
+
const state = current.hooks?.state?.[hook.key];
|
|
108334
|
+
need4(state?.enabled === true && typeof state.trusted_hash === "string" && /^sha256:[a-f0-9]{64}$/.test(state.trusted_hash), "RECONCILE_CONFIG_DRIFT");
|
|
108335
|
+
}
|
|
108336
|
+
} else
|
|
108337
|
+
need4(isDeepStrictEqual6(expectedConfig, current), "RECONCILE_CONFIG_DRIFT");
|
|
108338
|
+
const policy = parseManagedSkillPolicy(policyCurrent.text), binding = policy.bridge;
|
|
108281
108339
|
assertManagedAgentBridge("codex", { home, dataDir: dataDir3, projectDir: home });
|
|
108282
108340
|
const skillsCli = bindSkillsCli(binding.commands.codex, options.reviewedSkillsCli);
|
|
108283
|
-
|
|
108341
|
+
if (supersededBinding)
|
|
108342
|
+
verifyReleaseArtifact(options.releaseProof, skillsCli);
|
|
108343
|
+
const skillsBindingChanged = !isDeepStrictEqual6(skillsCli.receipt, intent.skillsCli);
|
|
108344
|
+
need4(!skillsBindingChanged || supersededBinding, "RECONCILE_SKILLS_BINDING_CHANGED");
|
|
108284
108345
|
const alias = binding.rootAliases?.find((item) => item.agent === "codex"), codexHome = alias?.target ?? join56(home, ".codex"), hooksPath = join56(codexHome, "hooks.json");
|
|
108285
108346
|
need4(resolve22(intent.configPath) === resolve22(join56(codexHome, "config.toml")), "RECONCILE_CONFIG_PATH_CHANGED");
|
|
108286
108347
|
const hooksCurrent = snapshot(hooksPath);
|
|
108287
|
-
|
|
108348
|
+
if (hooksCurrent.sha256 !== intent.hooksSha256 && hooksCurrent.sha256 !== hooksBefore.sha256) {
|
|
108349
|
+
need4(supersededBinding, "RECONCILE_HOOKS_CHANGED");
|
|
108350
|
+
const currentDeclarations = JSON.parse(hooksCurrent.text).hooks;
|
|
108351
|
+
for (const [event, [nativeEvent]] of Object.entries(eventNames)) {
|
|
108352
|
+
const command = renderAgentHookCommand(binding.commands.codex, "codex", binding.profiles.codex, event);
|
|
108353
|
+
need4(isDeepStrictEqual6(currentDeclarations?.[event], [{ hooks: [{ type: "command", command, timeout: 15 }] }]), "RECONCILE_BINDING_HOOK_CHANGED");
|
|
108354
|
+
}
|
|
108355
|
+
}
|
|
108288
108356
|
rpc = await connect({ command: options.codexCommand ?? "codex", home, codexHome });
|
|
108289
108357
|
need4(rpc.version === intent.nativeVersion, "RECONCILE_NATIVE_VERSION_CHANGED");
|
|
108290
108358
|
const discovered = await rpc.request("hooks/list", { cwds: [home] });
|
|
@@ -108294,12 +108362,15 @@ async function reconcileCodexNativeHooks(options, connect = connectCodexHookRpc)
|
|
|
108294
108362
|
if (recordedNativeHooks)
|
|
108295
108363
|
need4(nativeHooks.length === recordedNativeHooks.length, "RECONCILE_NATIVE_HOOK_LIST_CHANGED");
|
|
108296
108364
|
const plannedKeys = new Set(intent.hooks.map((hook) => hook.key));
|
|
108365
|
+
let nativeTrustPending = false;
|
|
108297
108366
|
for (const expected of recordedNativeHooks ?? []) {
|
|
108298
108367
|
const matches2 = nativeHooks.filter((hook) => hook.key === expected.key);
|
|
108299
108368
|
need4(matches2.length === 1, "RECONCILE_NATIVE_HOOK_LIST_CHANGED");
|
|
108300
108369
|
const actual = safeNativeHook(matches2[0]);
|
|
108301
108370
|
const stable = (hook) => {
|
|
108302
108371
|
const { enabled, trustStatus, ...identity4 } = hook;
|
|
108372
|
+
if (supersededBinding)
|
|
108373
|
+
delete identity4.command;
|
|
108303
108374
|
return identity4;
|
|
108304
108375
|
};
|
|
108305
108376
|
need4(isDeepStrictEqual6(stable(actual), stable(expected)), "RECONCILE_NATIVE_IDENTITY_CHANGED");
|
|
@@ -108310,7 +108381,14 @@ async function reconcileCodexNativeHooks(options, connect = connectCodexHookRpc)
|
|
|
108310
108381
|
const matches2 = nativeHooks.filter((h2) => h2.key === wanted.key || h2.key === wanted.key.replace(join56(home, ".codex/hooks.json"), hooksPath));
|
|
108311
108382
|
need4(matches2.length === 1, "RECONCILE_NATIVE_IDENTITY_CHANGED");
|
|
108312
108383
|
const h = matches2[0];
|
|
108313
|
-
|
|
108384
|
+
const trusted = h.trustStatus === "trusted";
|
|
108385
|
+
need4(h.enabled === true && (trusted || supersededBinding && h.trustStatus === "modified") && (h.currentHash === wanted.currentHash || supersededBinding && /^sha256:[a-f0-9]{64}$/.test(h.currentHash)), "RECONCILE_NATIVE_STATE_INCOMPLETE");
|
|
108386
|
+
if (!trusted)
|
|
108387
|
+
nativeTrustPending = true;
|
|
108388
|
+
if (supersededBinding) {
|
|
108389
|
+
const nativeToCliEvent = { userPromptSubmit: "UserPromptSubmit", sessionStart: "SessionStart", subagentStart: "SubagentStart" };
|
|
108390
|
+
need4(h.command === renderAgentHookCommand(binding.commands.codex, "codex", binding.profiles.codex, nativeToCliEvent[wanted.event] ?? ""), "RECONCILE_BINDING_HOOK_CHANGED");
|
|
108391
|
+
}
|
|
108314
108392
|
}
|
|
108315
108393
|
const config2 = await rpc.request("config/read", { includeLayers: true, cwd: home });
|
|
108316
108394
|
const layers = config2?.layers?.filter((layer) => layer.name?.type === "user" && layer.name.file === intent.configPath && !layer.name.profile);
|
|
@@ -108330,7 +108408,7 @@ async function reconcileCodexNativeHooks(options, connect = connectCodexHookRpc)
|
|
|
108330
108408
|
unchanged2(currentConfig);
|
|
108331
108409
|
skillsCli.recheck();
|
|
108332
108410
|
assertManagedAgentBridge("codex", { home, dataDir: dataDir3, projectDir: home });
|
|
108333
|
-
const receipt = { version: 1, status: "reconciled", reconciled: true, automaticRollback: false, journal, planDigest: intent.planDigest, nativeVersion: rpc.version, nativeStateVerified:
|
|
108411
|
+
const receipt = { version: 1, status: supersededBinding ? "superseded" : "reconciled", reconciled: true, supersededBinding, automaticRollback: false, journal, planDigest: intent.planDigest, nativeVersion: rpc.version, nativeStateVerified: !nativeTrustPending, nativeTrustPending, nativeExecutionVerified: false, configSha256: currentConfig.sha256, hooksSha256: hooksCurrent.sha256, policySha256: policyBefore.sha256, policyBeforeSha256: policyBefore.sha256, policyCurrentSha256: policyCurrent.sha256, previousSkillsCli: intent.skillsCli, skillsCli: skillsCli.receipt, releaseProof: options.releaseProof, nativeInventoryScope: recordedNativeHooks ? "complete" : "declared-managed-hooks-only", unrelatedNativeHooksPreserved: !!recordedNativeHooks, unrelatedSettingsAndCommentsPreserved: true };
|
|
108334
108412
|
save2(join56(journal, "receipt.json"), json2(receipt));
|
|
108335
108413
|
return receipt;
|
|
108336
108414
|
} catch (error61) {
|
|
@@ -108460,7 +108538,12 @@ async function enrollCodexNativeHooks(options = {}, connect = connectCodexHookRp
|
|
|
108460
108538
|
}
|
|
108461
108539
|
}
|
|
108462
108540
|
var json2 = (value) => JSON.stringify(value, null, 2) + `
|
|
108463
|
-
`, structure = (text3) => JSON.parse(JSON.stringify(Bun.TOML.parse(text3))), eventNames, makePlanDigest = (value) => createHash26("sha256").update(json2(value)).digest("hex"), safeNativeHook = (hook) => ({ key: hook.key, eventName: hook.eventName, handlerType: hook.handlerType, command: hook.command, matcher: hook.matcher, timeoutSec: hook.timeoutSec, async: hook.async, statusMessage: hook.statusMessage, additionalContextLimit: hook.additionalContextLimit, sourcePath: hook.sourcePath, source: hook.source, pluginId: hook.pluginId, isManaged: hook.isManaged, currentHash: hook.currentHash, enabled: hook.enabled, trustStatus: hook.trustStatus })
|
|
108541
|
+
`, structure = (text3) => JSON.parse(JSON.stringify(Bun.TOML.parse(text3))), eventNames, makePlanDigest = (value) => createHash26("sha256").update(json2(value)).digest("hex"), safeNativeHook = (hook) => ({ key: hook.key, eventName: hook.eventName, handlerType: hook.handlerType, command: hook.command, matcher: hook.matcher, timeoutSec: hook.timeoutSec, async: hook.async, statusMessage: hook.statusMessage, additionalContextLimit: hook.additionalContextLimit, sourcePath: hook.sourcePath, source: hook.source, pluginId: hook.pluginId, isManaged: hook.isManaged, currentHash: hook.currentHash, enabled: hook.enabled, trustStatus: hook.trustStatus }), withoutCodexCommand = (value) => {
|
|
108542
|
+
const copy = structuredClone(value);
|
|
108543
|
+
if (copy?.bridge?.commands && Object.hasOwn(copy.bridge.commands, "codex"))
|
|
108544
|
+
copy.bridge.commands.codex = "<reviewed-codex-binding>";
|
|
108545
|
+
return copy;
|
|
108546
|
+
};
|
|
108464
108547
|
var init_agent_codex_trust = __esm(() => {
|
|
108465
108548
|
init_config();
|
|
108466
108549
|
init_managed_policy();
|
|
@@ -108553,8 +108636,8 @@ var exports_agent_integration = {};
|
|
|
108553
108636
|
__export(exports_agent_integration, {
|
|
108554
108637
|
registerAgentIntegration: () => registerAgentIntegration
|
|
108555
108638
|
});
|
|
108556
|
-
import { readFileSync as
|
|
108557
|
-
import { isAbsolute as
|
|
108639
|
+
import { readFileSync as readFileSync38 } from "fs";
|
|
108640
|
+
import { isAbsolute as isAbsolute26 } from "path";
|
|
108558
108641
|
function pinnedHookProfile(input3, configuredProfile) {
|
|
108559
108642
|
try {
|
|
108560
108643
|
const parsed = parseSkillContextInput(JSON.stringify(input3));
|
|
@@ -108625,7 +108708,7 @@ function registerAgentIntegration(parent) {
|
|
|
108625
108708
|
});
|
|
108626
108709
|
hook.command("install").option("--agent <agent>", `Agent to configure: ${INTEGRATION_AGENTS.join(", ")}, all`, "all").option("--command <path>", "Skills executable used by the hook (preserves existing binding; new agents use skills)").option("--selection-profile <id>", "Selection profile (preserves existing binding; new agents use default)").option("--include-vendor", "Retained for compatibility; vendor system skills are always inventoried and disabled", false).option("--discovery-inputs <file>", "Advanced reviewed active plugin roots and source hashes for unsupported registrations").option("--allow-root-aliases", "Allow home .claude/.codex aliases to existing directories within this home", false).option("--apply", "Apply the plan, preserving prior configuration in private backups", false).option("--json", "Output a receipt as JSON", false).description("Plan or install one Skills CLI bridge plus native prompt hooks").action(async (options) => {
|
|
108627
108710
|
try {
|
|
108628
|
-
const discoveryInputs = options.discoveryInputs ? JSON.parse(
|
|
108711
|
+
const discoveryInputs = options.discoveryInputs ? JSON.parse(readFileSync38(options.discoveryInputs, "utf8")) : undefined;
|
|
108629
108712
|
const plan = planAgentIntegration({ agents: agents(options.agent), command: options.command, profileId: options.selectionProfile, includeVendor: options.includeVendor, discoveryInputs, allowRootAliases: options.allowRootAliases });
|
|
108630
108713
|
const result2 = options.apply ? applyAgentIntegration(plan) : { changed: [], backups: [] };
|
|
108631
108714
|
const receipt = { applied: options.apply, planned: plan.changes.map((change) => change.path), ...result2, rootAliases: plan.rootAliases ?? [], discovery: plan.discoveryAfter, nativeSkills: plan.nativeSkills.map((entry) => ({ agent: entry.agent, path: entry.path, managed: entry.managed, vendor: entry.vendor, system: entry.system === true, bridge: entry.bridge === true })), requiresNativeRetirement: plan.nativeSkills.some((entry) => !entry.bridge && !entry.system) };
|
|
@@ -108638,8 +108721,10 @@ function registerAgentIntegration(parent) {
|
|
|
108638
108721
|
process.exitCode = 1;
|
|
108639
108722
|
}
|
|
108640
108723
|
});
|
|
108641
|
-
const trust = hook.command("trust").
|
|
108724
|
+
const trust = hook.command("trust").option("--agent <agent>", "Native trust adapter (codex)").option("--codex-command <path>", "Installed Codex executable used for its native configuration API", "codex").option("--apply", "Enable and trust only the exact managed Skills hook identities", false).option("--plan-digest <sha256>", "Exact reviewed dry-run digest required with --apply").option("--json", "Output the native trust plan or receipt", false).description("Plan or enroll exact Skills hooks through Codex native trust controls").action(async (options) => {
|
|
108642
108725
|
try {
|
|
108726
|
+
if (!options.agent)
|
|
108727
|
+
throw new Error("Native trust enrollment requires --agent codex");
|
|
108643
108728
|
if (options.agent !== "codex")
|
|
108644
108729
|
throw new Error("Native trust enrollment currently supports --agent codex only");
|
|
108645
108730
|
const result2 = await enrollCodexNativeHooks({ codexCommand: options.codexCommand, apply: options.apply, reviewedPlanDigest: options.planDigest });
|
|
@@ -108652,11 +108737,15 @@ function registerAgentIntegration(parent) {
|
|
|
108652
108737
|
process.exitCode = 1;
|
|
108653
108738
|
}
|
|
108654
108739
|
});
|
|
108655
|
-
trust.command("reconcile").requiredOption("--agent <agent>", "Native trust adapter (codex)").requiredOption("--journal <path>", "Private incomplete native trust journal to inspect").option("--codex-command <path>", "Installed Codex executable used for its native configuration API", "codex").option("--json", "Output the reconciliation receipt", false).description("Verify an interrupted Codex native trust write and resolve its private journal").action(async (options) => {
|
|
108740
|
+
trust.command("reconcile").requiredOption("--agent <agent>", "Native trust adapter (codex)").requiredOption("--journal <path>", "Private incomplete native trust journal to inspect").option("--codex-command <path>", "Installed Codex executable used for its native configuration API", "codex").option("--supersede-binding", "Resolve a stale journal only when current policy differs solely by the reviewed Codex CLI binding", false).option("--skills-package-tar <path>", "Exact package tarball consumed by the reviewed executable").option("--skills-package-tar-sha256 <sha256>", "SHA-256 of the reviewed Skills package tarball").option("--skills-package-tar-bytes <bytes>", "Byte length of the reviewed Skills package tarball").option("--skills-package-manifest-sha256 <sha256>", "SHA-256 of the reviewed Skills package manifest").option("--skills-executable-sha256 <sha256>", "SHA-256 of the reviewed running Skills executable").option("--json", "Output the reconciliation receipt", false).description("Verify an interrupted Codex native trust write and resolve its private journal").action(async (options) => {
|
|
108656
108741
|
try {
|
|
108657
108742
|
if (options.agent !== "codex")
|
|
108658
108743
|
throw new Error("Native trust reconciliation currently supports --agent codex only");
|
|
108659
|
-
const
|
|
108744
|
+
const proofFields = [options.skillsPackageTar, options.skillsPackageTarSha256, options.skillsPackageTarBytes, options.skillsPackageManifestSha256, options.skillsExecutableSha256];
|
|
108745
|
+
if (proofFields.some((value) => value !== undefined) && proofFields.some((value) => value === undefined))
|
|
108746
|
+
throw new Error("Release provenance requires package tar path, tar hash/bytes, manifest hash, and executable hash together");
|
|
108747
|
+
const releaseProof = proofFields.every((value) => value !== undefined) ? { packageTarPath: options.skillsPackageTar, packageTarSha256: options.skillsPackageTarSha256, packageTarBytes: Number(options.skillsPackageTarBytes), manifestSha256: options.skillsPackageManifestSha256, executableSha256: options.skillsExecutableSha256 } : undefined;
|
|
108748
|
+
const result2 = await reconcileCodexNativeHooks({ journal: options.journal, codexCommand: options.codexCommand, supersedeBinding: options.supersedeBinding, releaseProof });
|
|
108660
108749
|
if (options.json)
|
|
108661
108750
|
await writeCliOutput(JSON.stringify(result2));
|
|
108662
108751
|
else
|
|
@@ -108673,7 +108762,7 @@ function registerAgentIntegration(parent) {
|
|
|
108673
108762
|
try {
|
|
108674
108763
|
if (agents(options.agent).length !== 1)
|
|
108675
108764
|
throw new Error("A hook invocation requires one agent");
|
|
108676
|
-
const inputText =
|
|
108765
|
+
const inputText = readFileSync38(0, "utf8");
|
|
108677
108766
|
if (inputText.length > 1024 * 1024)
|
|
108678
108767
|
throw new Error("Hook input is too large");
|
|
108679
108768
|
let input3 = JSON.parse(inputText);
|
|
@@ -108686,12 +108775,12 @@ function registerAgentIntegration(parent) {
|
|
|
108686
108775
|
input3.hook_event_name = event;
|
|
108687
108776
|
const projects = [process.cwd()];
|
|
108688
108777
|
if (input3.cwd !== undefined) {
|
|
108689
|
-
if (typeof input3.cwd !== "string" || !
|
|
108778
|
+
if (typeof input3.cwd !== "string" || !isAbsolute26(input3.cwd) || input3.cwd.includes("\x00"))
|
|
108690
108779
|
throw new Error("Invalid native hook working directory");
|
|
108691
108780
|
projects.push(input3.cwd);
|
|
108692
108781
|
}
|
|
108693
108782
|
if (options.agent === "cursor") {
|
|
108694
|
-
if (!Array.isArray(input3.workspace_roots) || input3.workspace_roots.length > 32 || input3.workspace_roots.some((path) => typeof path !== "string" || !
|
|
108783
|
+
if (!Array.isArray(input3.workspace_roots) || input3.workspace_roots.length > 32 || input3.workspace_roots.some((path) => typeof path !== "string" || !isAbsolute26(path) || path.includes("\x00")))
|
|
108695
108784
|
throw new Error("Invalid Cursor workspace roots");
|
|
108696
108785
|
projects.push(...input3.workspace_roots);
|
|
108697
108786
|
input3.cwd ??= input3.workspace_roots[0] ?? process.cwd();
|
|
@@ -108769,7 +108858,7 @@ function registerAgentIntegration(parent) {
|
|
|
108769
108858
|
const migrate = parent.command("migrate").description("Preserve and retire native agent skill copies");
|
|
108770
108859
|
migrate.command("native").option("--project <directory>", "Also inventory a project and its ancestors (the current directory and its ancestors are always included)").option("--include-unmanaged", "Archive user-authored skills as well as Skills-managed copies", false).option("--include-vendor", "Retire vendor SKILL.md discovery files while preserving plugin scripts and assets", false).option("--target-manifest <file>", "Reviewed exact native migration target manifest").option("--discovery-inputs <file>", "Advanced reviewed active plugin roots and source hashes").option("--allow-root-aliases", "Allow home .claude/.codex aliases to existing directories within this home", false).option("--apply", "Move selected skills to private archives outside agent discovery roots", false).option("--json", "Output inventory and archive receipt as JSON", false).description("Inventory native skill copies; preserve complete directories before retiring them").action(async (options) => {
|
|
108771
108860
|
try {
|
|
108772
|
-
const discoveryInputs = options.discoveryInputs ? JSON.parse(
|
|
108861
|
+
const discoveryInputs = options.discoveryInputs ? JSON.parse(readFileSync38(options.discoveryInputs, "utf8")) : undefined;
|
|
108773
108862
|
if (options.targetManifest && (options.includeUnmanaged || options.includeVendor))
|
|
108774
108863
|
throw new Error("--target-manifest cannot be combined with broad native migration selectors");
|
|
108775
108864
|
const targetManifest = options.targetManifest ? readNativeMigrationTargetManifest(options.targetManifest) : undefined;
|
|
@@ -109074,11 +109163,11 @@ import {
|
|
|
109074
109163
|
copyFileSync as copyFileSync2,
|
|
109075
109164
|
mkdirSync as mkdirSync26,
|
|
109076
109165
|
readdirSync as readdirSync21,
|
|
109077
|
-
readFileSync as
|
|
109078
|
-
statSync as
|
|
109166
|
+
readFileSync as readFileSync39,
|
|
109167
|
+
statSync as statSync22,
|
|
109079
109168
|
writeFileSync as writeFileSync26
|
|
109080
109169
|
} from "fs";
|
|
109081
|
-
import { dirname as
|
|
109170
|
+
import { dirname as dirname31, join as join57, resolve as resolve23, sep as sep10 } from "path";
|
|
109082
109171
|
function fail5(code2, message, detail = []) {
|
|
109083
109172
|
throw new StationSnapshotError(code2, message, detail);
|
|
109084
109173
|
}
|
|
@@ -109090,7 +109179,7 @@ function readSnapshotManifest(repoRoot, stationId) {
|
|
|
109090
109179
|
const manifestPath = join57(snapshotRoot, "sync-manifest.json");
|
|
109091
109180
|
let manifest;
|
|
109092
109181
|
try {
|
|
109093
|
-
manifest = JSON.parse(
|
|
109182
|
+
manifest = JSON.parse(readFileSync39(manifestPath, "utf8"));
|
|
109094
109183
|
} catch (error61) {
|
|
109095
109184
|
fail5("MANIFEST_UNREADABLE", `cannot read snapshot manifest: ${manifestPath}: ${error61.message}`);
|
|
109096
109185
|
}
|
|
@@ -109172,7 +109261,7 @@ function planStationHydration(stationId, repoRoot) {
|
|
|
109172
109261
|
});
|
|
109173
109262
|
continue;
|
|
109174
109263
|
}
|
|
109175
|
-
const info =
|
|
109264
|
+
const info = statSync22(entry.fullPath);
|
|
109176
109265
|
const manifestHash = manifestHashes.get(`${agent}${MANIFEST_HASH_KEY_SEP}${homeRelative}`) ?? null;
|
|
109177
109266
|
let verified = false;
|
|
109178
109267
|
if (manifestHash !== null) {
|
|
@@ -109226,7 +109315,7 @@ function planStationHydration(stationId, repoRoot) {
|
|
|
109226
109315
|
for (const copy of copies) {
|
|
109227
109316
|
let isStub = false;
|
|
109228
109317
|
try {
|
|
109229
|
-
isStub = isPointerSkillMd(
|
|
109318
|
+
isStub = isPointerSkillMd(readFileSync39(copy.fullPath, "utf8"));
|
|
109230
109319
|
} catch {
|
|
109231
109320
|
isStub = false;
|
|
109232
109321
|
}
|
|
@@ -109331,7 +109420,7 @@ function writeStationHydration(options) {
|
|
|
109331
109420
|
}
|
|
109332
109421
|
let written = 0;
|
|
109333
109422
|
for (const entry of toWrite) {
|
|
109334
|
-
mkdirSync26(
|
|
109423
|
+
mkdirSync26(dirname31(entry.destination), { recursive: true });
|
|
109335
109424
|
copyFileSync2(entry.fullPath, entry.destination);
|
|
109336
109425
|
written += 1;
|
|
109337
109426
|
}
|
|
@@ -109352,8 +109441,8 @@ function writeStationHydration(options) {
|
|
|
109352
109441
|
},
|
|
109353
109442
|
skills: resultSkills
|
|
109354
109443
|
};
|
|
109355
|
-
const hydrationManifestPath = join57(
|
|
109356
|
-
mkdirSync26(
|
|
109444
|
+
const hydrationManifestPath = join57(dirname31(cacheRoot), `hydration-${options.stationId}.json`);
|
|
109445
|
+
mkdirSync26(dirname31(hydrationManifestPath), { recursive: true });
|
|
109357
109446
|
writeFileSync26(hydrationManifestPath, `${JSON.stringify(hydration, null, 2)}
|
|
109358
109447
|
`);
|
|
109359
109448
|
return {
|
|
@@ -109430,9 +109519,9 @@ var init_hydrate = __esm(() => {
|
|
|
109430
109519
|
|
|
109431
109520
|
// src/lib/prepare-skill.ts
|
|
109432
109521
|
import { createHash as createHash28, randomUUID as randomUUID11 } from "crypto";
|
|
109433
|
-
import { chmodSync as chmodSync3, existsSync as existsSync34, lstatSync as lstatSync29, mkdirSync as mkdirSync27, mkdtempSync as mkdtempSync6, readFileSync as
|
|
109522
|
+
import { chmodSync as chmodSync3, existsSync as existsSync34, lstatSync as lstatSync29, mkdirSync as mkdirSync27, mkdtempSync as mkdtempSync6, readFileSync as readFileSync40, readdirSync as readdirSync22, renameSync as renameSync12, rmSync as rmSync9, writeFileSync as writeFileSync27 } from "fs";
|
|
109434
109523
|
import { tmpdir as tmpdir2 } from "os";
|
|
109435
|
-
import { dirname as
|
|
109524
|
+
import { dirname as dirname32, isAbsolute as isAbsolute27, join as join58, relative as relative9, resolve as resolve24, sep as sep11 } from "path";
|
|
109436
109525
|
function prepareSkill(name, options) {
|
|
109437
109526
|
const normalized = normalizePortableSkillName(name);
|
|
109438
109527
|
if (!new RegExp(SEMVER_PATTERN).test(options.version))
|
|
@@ -109477,7 +109566,7 @@ function prepareSkill(name, options) {
|
|
|
109477
109566
|
mkdirSync27(join58(staging, directory2), { recursive: true });
|
|
109478
109567
|
for (const file2 of before2.files) {
|
|
109479
109568
|
const destination = join58(staging, file2.path);
|
|
109480
|
-
mkdirSync27(
|
|
109569
|
+
mkdirSync27(dirname32(destination), { recursive: true });
|
|
109481
109570
|
writeFileSync27(destination, file2.bytes, { mode: file2.mode });
|
|
109482
109571
|
}
|
|
109483
109572
|
const stagedManifest = join58(staging, "skill.json");
|
|
@@ -109538,7 +109627,7 @@ function validateRuntimeEntrypoint(candidate2, root2) {
|
|
|
109538
109627
|
if (typeof entry !== "string")
|
|
109539
109628
|
return;
|
|
109540
109629
|
const target = resolve24(root2, entry), rel = relative9(root2, target);
|
|
109541
|
-
if (
|
|
109630
|
+
if (isAbsolute27(entry) || /^[a-zA-Z]:/.test(entry) || entry.includes("\\") || !rel || rel === ".." || rel.startsWith(`..${sep11}`) || isAbsolute27(rel) || !existsSync34(target) || !lstatSync29(target).isFile()) {
|
|
109542
109631
|
throw new Error("Executable runtime.entrypoint must name an existing regular file inside the skill directory.");
|
|
109543
109632
|
}
|
|
109544
109633
|
}
|
|
@@ -109649,7 +109738,7 @@ function snapshot2(root2) {
|
|
|
109649
109738
|
bytes += stat3.size;
|
|
109650
109739
|
if (bytes > 50000000)
|
|
109651
109740
|
throw new Error("Skill exceeds the preparation size limit (50000000 bytes).");
|
|
109652
|
-
const content =
|
|
109741
|
+
const content = readFileSync40(absolute);
|
|
109653
109742
|
if (content.length !== stat3.size)
|
|
109654
109743
|
throw new Error("Skill changed during preparation.");
|
|
109655
109744
|
files.push({ path, bytes: content, mode: stat3.mode & 511 });
|
|
@@ -110051,7 +110140,7 @@ var init_schedule = __esm(() => {
|
|
|
110051
110140
|
|
|
110052
110141
|
// src/lib/registry-sync.ts
|
|
110053
110142
|
import { mkdirSync as mkdirSync28, writeFileSync as writeFileSync28 } from "fs";
|
|
110054
|
-
import { dirname as
|
|
110143
|
+
import { dirname as dirname33, relative as relative10 } from "path";
|
|
110055
110144
|
function createRegistrySyncArtifact(options = {}) {
|
|
110056
110145
|
const profile = options.profile ?? "all";
|
|
110057
110146
|
const includeDocs = options.includeDocs ?? true;
|
|
@@ -110108,7 +110197,7 @@ function createRegistrySyncArtifact(options = {}) {
|
|
|
110108
110197
|
};
|
|
110109
110198
|
}
|
|
110110
110199
|
function writeRegistrySyncArtifact(path, artifact) {
|
|
110111
|
-
mkdirSync28(
|
|
110200
|
+
mkdirSync28(dirname33(path), { recursive: true });
|
|
110112
110201
|
writeFileSync28(path, `${JSON.stringify(artifact, null, 2)}
|
|
110113
110202
|
`);
|
|
110114
110203
|
}
|
|
@@ -110329,8 +110418,8 @@ __export(exports_publish, {
|
|
|
110329
110418
|
buildVersionManifest: () => buildVersionManifest,
|
|
110330
110419
|
PushSkillError: () => PushSkillError
|
|
110331
110420
|
});
|
|
110332
|
-
import { execFileSync } from "child_process";
|
|
110333
|
-
import { existsSync as existsSync35, readFileSync as
|
|
110421
|
+
import { execFileSync as execFileSync2 } from "child_process";
|
|
110422
|
+
import { existsSync as existsSync35, readFileSync as readFileSync41 } from "fs";
|
|
110334
110423
|
import { hostname as hostname4 } from "os";
|
|
110335
110424
|
import { join as join59 } from "path";
|
|
110336
110425
|
function registerPublish(parent) {
|
|
@@ -110385,7 +110474,7 @@ async function pushSkill(name, options = {}) {
|
|
|
110385
110474
|
await verifyPackedCanonicalHash(skill.name, packed);
|
|
110386
110475
|
const versionManifest = buildVersionManifest(skill.path, packed);
|
|
110387
110476
|
const skillMdPath = join59(skill.path, "SKILL.md");
|
|
110388
|
-
const skillMd = existsSync35(skillMdPath) ?
|
|
110477
|
+
const skillMd = existsSync35(skillMdPath) ? readFileSync41(skillMdPath, "utf-8") : undefined;
|
|
110389
110478
|
const base3 = {
|
|
110390
110479
|
slug: skill.name,
|
|
110391
110480
|
path: skill.path,
|
|
@@ -110542,7 +110631,7 @@ function sanitizeGitRemote(url2) {
|
|
|
110542
110631
|
}
|
|
110543
110632
|
function gitValue(dir, args2) {
|
|
110544
110633
|
try {
|
|
110545
|
-
const out =
|
|
110634
|
+
const out = execFileSync2("git", ["-C", dir, ...args2], { stdio: ["ignore", "pipe", "ignore"], encoding: "utf-8" }).trim();
|
|
110546
110635
|
return out || null;
|
|
110547
110636
|
} catch {
|
|
110548
110637
|
return null;
|
|
@@ -112006,11 +112095,11 @@ var init_storage2 = __esm(() => {
|
|
|
112006
112095
|
});
|
|
112007
112096
|
|
|
112008
112097
|
// src/lib/registry-reconcile.ts
|
|
112009
|
-
import { existsSync as existsSync36, readFileSync as
|
|
112098
|
+
import { existsSync as existsSync36, readFileSync as readFileSync42, statSync as statSync23, writeFileSync as writeFileSync29 } from "fs";
|
|
112010
112099
|
import { join as join60 } from "path";
|
|
112011
112100
|
function isDirectory2(path) {
|
|
112012
112101
|
try {
|
|
112013
|
-
return
|
|
112102
|
+
return statSync23(path).isDirectory();
|
|
112014
112103
|
} catch {
|
|
112015
112104
|
return false;
|
|
112016
112105
|
}
|
|
@@ -112026,7 +112115,7 @@ function readBaseline(skillDir) {
|
|
|
112026
112115
|
if (!existsSync36(markerPath))
|
|
112027
112116
|
return;
|
|
112028
112117
|
try {
|
|
112029
|
-
const marker = JSON.parse(
|
|
112118
|
+
const marker = JSON.parse(readFileSync42(markerPath, "utf-8"));
|
|
112030
112119
|
if (!isSkillsOwnershipMarker(marker))
|
|
112031
112120
|
return;
|
|
112032
112121
|
return {
|
|
@@ -112042,7 +112131,7 @@ function readCursor(root2) {
|
|
|
112042
112131
|
if (!existsSync36(path))
|
|
112043
112132
|
return { runCount: 0 };
|
|
112044
112133
|
try {
|
|
112045
|
-
const cursor2 = JSON.parse(
|
|
112134
|
+
const cursor2 = JSON.parse(readFileSync42(path, "utf-8"));
|
|
112046
112135
|
return { runCount: typeof cursor2.runCount === "number" ? cursor2.runCount : 0 };
|
|
112047
112136
|
} catch {
|
|
112048
112137
|
return { runCount: 0 };
|
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.9.
|
|
20022
|
+
version: "0.9.8",
|
|
20023
20023
|
description: "Skills library for AI coding agents",
|
|
20024
20024
|
type: "module",
|
|
20025
20025
|
bin: {
|
package/bin/migrate.js
CHANGED
package/bin/server.js
CHANGED
|
@@ -24122,7 +24122,7 @@ var init_dist_es9 = __esm(() => {
|
|
|
24122
24122
|
// package.json
|
|
24123
24123
|
var package_default = {
|
|
24124
24124
|
name: "@hasna/skills",
|
|
24125
|
-
version: "0.9.
|
|
24125
|
+
version: "0.9.8",
|
|
24126
24126
|
description: "Skills library for AI coding agents",
|
|
24127
24127
|
type: "module",
|
|
24128
24128
|
bin: {
|
package/bin/worker.js
CHANGED
|
@@ -24125,7 +24125,7 @@ import { randomUUID as randomUUID6 } from "crypto";
|
|
|
24125
24125
|
// package.json
|
|
24126
24126
|
var package_default = {
|
|
24127
24127
|
name: "@hasna/skills",
|
|
24128
|
-
version: "0.9.
|
|
24128
|
+
version: "0.9.8",
|
|
24129
24129
|
description: "Skills library for AI coding agents",
|
|
24130
24130
|
type: "module",
|
|
24131
24131
|
bin: {
|
package/dist/index.js
CHANGED
|
@@ -11448,7 +11448,7 @@ import { isAbsolute as isAbsolute10, join as join20, resolve as resolve10 } from
|
|
|
11448
11448
|
// package.json
|
|
11449
11449
|
var package_default = {
|
|
11450
11450
|
name: "@hasna/skills",
|
|
11451
|
-
version: "0.9.
|
|
11451
|
+
version: "0.9.8",
|
|
11452
11452
|
description: "Skills library for AI coding agents",
|
|
11453
11453
|
type: "module",
|
|
11454
11454
|
bin: {
|
|
@@ -8,12 +8,21 @@ export interface CodexNativeHookTrustOptions {
|
|
|
8
8
|
reviewedPlanDigest?: string;
|
|
9
9
|
reviewedSkillsCli?: ReviewedSkillsCli;
|
|
10
10
|
}
|
|
11
|
+
export interface SkillsCliReleaseProof {
|
|
12
|
+
packageTarPath: string;
|
|
13
|
+
packageTarSha256: string;
|
|
14
|
+
packageTarBytes: number;
|
|
15
|
+
manifestSha256: string;
|
|
16
|
+
executableSha256: string;
|
|
17
|
+
}
|
|
11
18
|
export interface CodexNativeHookReconcileOptions {
|
|
12
19
|
home?: string;
|
|
13
20
|
dataDir?: string;
|
|
14
21
|
codexCommand?: string;
|
|
15
22
|
journal: string;
|
|
16
23
|
reviewedSkillsCli?: ReviewedSkillsCli;
|
|
24
|
+
releaseProof?: SkillsCliReleaseProof;
|
|
25
|
+
supersedeBinding?: boolean;
|
|
17
26
|
}
|
|
18
27
|
type Connect = typeof connectCodexHookRpc;
|
|
19
28
|
/** Resolve an interrupted native write only after the native consumer and every
|
|
@@ -24,21 +33,27 @@ export declare function reconcileCodexNativeHooks(options: CodexNativeHookReconc
|
|
|
24
33
|
version: number;
|
|
25
34
|
status: string;
|
|
26
35
|
reconciled: boolean;
|
|
36
|
+
supersededBinding: boolean;
|
|
27
37
|
automaticRollback: boolean;
|
|
28
38
|
journal: string;
|
|
29
39
|
planDigest: any;
|
|
30
40
|
nativeVersion: string;
|
|
31
41
|
nativeStateVerified: boolean;
|
|
42
|
+
nativeTrustPending: boolean;
|
|
32
43
|
nativeExecutionVerified: boolean;
|
|
33
44
|
configSha256: string;
|
|
34
45
|
hooksSha256: string;
|
|
35
46
|
policySha256: string;
|
|
47
|
+
policyBeforeSha256: string;
|
|
48
|
+
policyCurrentSha256: string;
|
|
49
|
+
previousSkillsCli: any;
|
|
36
50
|
skillsCli: {
|
|
37
51
|
path: string;
|
|
38
52
|
version: string;
|
|
39
53
|
sha256: string;
|
|
40
54
|
manifestSha256: string;
|
|
41
55
|
};
|
|
56
|
+
releaseProof: SkillsCliReleaseProof | undefined;
|
|
42
57
|
nativeInventoryScope: string;
|
|
43
58
|
unrelatedNativeHooksPreserved: boolean;
|
|
44
59
|
unrelatedSettingsAndCommentsPreserved: boolean;
|
|
@@ -1,3 +1,9 @@
|
|
|
1
1
|
/** Conservative admission and text witness, never a TOML writer. Native Codex
|
|
2
2
|
* performs the versioned write; unrecognized inline/dotted trust shapes refuse. */
|
|
3
|
-
export declare function codexTrustTextWitness(text: string, keys: string[]): string;
|
|
3
|
+
export declare function codexTrustTextWitness(text: string, keys: string[], canonicalize?: boolean): string;
|
|
4
|
+
/** Reconciliation witness: retain table/array order while tolerating only
|
|
5
|
+
* blank-line and line-ending formatting emitted by the native writer. */
|
|
6
|
+
export declare function codexTrustReconcileWitness(text: string, keys: string[]): string;
|
|
7
|
+
/** Parsed unmanaged TOML semantics. Arrays retain order; managed trust entries
|
|
8
|
+
* are excluded by exact journal key and all other keys/values remain bound. */
|
|
9
|
+
export declare function codexTrustUnmanagedSemantic(text: string, keys: string[]): string;
|
package/dist/sdk/index.js
CHANGED
|
@@ -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.9.
|
|
32376
|
+
version: "0.9.8",
|
|
32377
32377
|
description: "Skills library for AI coding agents",
|
|
32378
32378
|
type: "module",
|
|
32379
32379
|
bin: {
|