@hasna/skills 0.9.14 → 0.9.15
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 +244 -210
- package/bin/mcp.js +25 -13
- package/bin/migrate.js +1 -1
- package/bin/server.js +1 -1
- package/bin/worker.js +1 -1
- package/dist/index.js +9 -3
- package/dist/lib/agent-codex-trust.d.ts +2 -1
- package/dist/lib/codex-hook-additions-review.d.ts +22 -1
- package/dist/lib/codex-hook-discovery-recovery.d.ts +2 -1
- package/dist/sdk/index.js +31 -25
- 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.15",
|
|
36872
36872
|
description: "Skills library for AI coding agents",
|
|
36873
36873
|
type: "module",
|
|
36874
36874
|
bin: {
|
|
@@ -54696,39 +54696,132 @@ var fail2 = () => new Error('CODEX_HOOK_TRUST_UNSUPPORTED_LAYOUT: preserve and c
|
|
|
54696
54696
|
};
|
|
54697
54697
|
var init_codex_hook_trust_layout = () => {};
|
|
54698
54698
|
|
|
54699
|
+
// src/lib/codex-hook-additions-review.ts
|
|
54700
|
+
import { isAbsolute as isAbsolute14 } from "path";
|
|
54701
|
+
import { isDeepStrictEqual as isDeepStrictEqual5 } from "util";
|
|
54702
|
+
function exactKeys2(value, keys2) {
|
|
54703
|
+
need4(value && typeof value === "object" && !Array.isArray(value) && isDeepStrictEqual5(Object.keys(value).sort(), [...keys2].sort()), "RECONCILE_ADDITIONS_REVIEW_SCHEMA");
|
|
54704
|
+
}
|
|
54705
|
+
function readReviewedAdditionTrustStates(proof, before2, current, journalHooks) {
|
|
54706
|
+
const captured = proofs.get(proof);
|
|
54707
|
+
need4(!!captured && captured.before.file === before2.file && captured.before.sha256 === before2.sha256 && captured.current.file === current.file && captured.current.sha256 === current.sha256 && isDeepStrictEqual5(captured.journalHooks, journalHooks.map(({ key, currentHash }) => ({ key, currentHash }))), "RECONCILE_ADDITIONS_PROOF_CHANGED");
|
|
54708
|
+
captured.recheck();
|
|
54709
|
+
unchanged2(before2);
|
|
54710
|
+
unchanged2(current);
|
|
54711
|
+
return captured.states;
|
|
54712
|
+
}
|
|
54713
|
+
function reviewNativeHookAdditions(options) {
|
|
54714
|
+
need4(isAbsolute14(options.path), "RECONCILE_ADDITIONS_REVIEW_PATH");
|
|
54715
|
+
const reviewFile = snapshot(options.path, true), review = JSON.parse(reviewFile.text);
|
|
54716
|
+
exactKeys2(review, ["version", "kind", "reason", "producerEvidence", "journalIntentSha256", "policySha256", "configCurrentSha256", "hooksCurrentSha256", "producerBefore", "additions"]);
|
|
54717
|
+
need4((review.version === 1 || review.version === 2) && review.kind === "native-hook-additions" && text2(review.reason) && text2(review.producerEvidence), "RECONCILE_ADDITIONS_REVIEW_SCHEMA");
|
|
54718
|
+
for (const [name, expected] of [["journalIntentSha256", options.intent.sha256], ["policySha256", options.policy.sha256], ["configCurrentSha256", options.configCurrent.sha256], ["hooksCurrentSha256", options.hooksCurrent.sha256]])
|
|
54719
|
+
need4(hash2(review[name]) && review[name] === expected, "RECONCILE_ADDITIONS_REVIEW_CHANGED");
|
|
54720
|
+
exactKeys2(review.producerBefore, ["configPath", "configSha256", "hooksPath", "hooksSha256"]);
|
|
54721
|
+
const before2 = review.producerBefore;
|
|
54722
|
+
need4(isAbsolute14(before2.configPath) && isAbsolute14(before2.hooksPath) && hash2(before2.configSha256) && hash2(before2.hooksSha256), "RECONCILE_ADDITIONS_PRODUCER_PREIMAGE");
|
|
54723
|
+
const producerConfig = snapshot(before2.configPath, true), producerHooks = snapshot(before2.hooksPath, true);
|
|
54724
|
+
need4(producerConfig.sha256 === before2.configSha256 && producerHooks.sha256 === before2.hooksSha256 && producerHooks.sha256 === options.hooksBefore.sha256, "RECONCILE_ADDITIONS_PRODUCER_PREIMAGE");
|
|
54725
|
+
const original = structure(options.configBefore.text), producer = structure(producerConfig.text), expectedProducer = structuredClone(original), originalKeys = options.journalHooks.map((hook) => hook.key);
|
|
54726
|
+
expectedProducer.hooks ??= {};
|
|
54727
|
+
expectedProducer.hooks.state ??= {};
|
|
54728
|
+
for (const hook of options.journalHooks)
|
|
54729
|
+
expectedProducer.hooks.state[hook.key] = { ...expectedProducer.hooks.state[hook.key], enabled: true, trusted_hash: hook.currentHash };
|
|
54730
|
+
need4(isDeepStrictEqual5(expectedProducer, producer) && codexTrustReconcileWitness(options.configBefore.text, originalKeys) === codexTrustReconcileWitness(producerConfig.text, originalKeys) && codexTrustUnmanagedSemantic(options.configBefore.text, originalKeys) === codexTrustUnmanagedSemantic(producerConfig.text, originalKeys), "RECONCILE_ADDITIONS_PRODUCER_PREIMAGE");
|
|
54731
|
+
need4(Array.isArray(review.additions) && review.additions.length > 0 && review.additions.length <= 20, "RECONCILE_ADDITIONS_REVIEW_SCHEMA");
|
|
54732
|
+
const expectedHooks = JSON.parse(options.hooksBefore.text), currentHooks = JSON.parse(options.hooksCurrent.text), expectedConfig = structuredClone(producer);
|
|
54733
|
+
need4(expectedHooks.hooks && typeof expectedHooks.hooks === "object" && !Array.isArray(expectedHooks.hooks), "RECONCILE_ADDITIONS_DECLARATIONS");
|
|
54734
|
+
const added = [], states = [], seen = new Set, commands = new Set(options.recordedNativeHooks.map((hook) => hook.command));
|
|
54735
|
+
for (const addition of review.additions) {
|
|
54736
|
+
exactKeys2(addition, review.version === 1 ? ["event", "nativeHook"] : ["event", "nativeHook", "trustState"]);
|
|
54737
|
+
need4(Object.hasOwn(review.version === 1 ? events : matchedEvents, addition.event), "RECONCILE_ADDITIONS_DECLARATIONS");
|
|
54738
|
+
const { event, nativeHook: hook } = addition;
|
|
54739
|
+
exactKeys2(hook, nativeKeys);
|
|
54740
|
+
const groups = expectedHooks.hooks[event] ?? [];
|
|
54741
|
+
need4(Array.isArray(groups), "RECONCILE_ADDITIONS_DECLARATIONS");
|
|
54742
|
+
const key = `${options.nativeHooksPath}:${matchedEvents[event][1]}:${groups.length}:0`;
|
|
54743
|
+
need4(hook.key === key && !seen.has(key) && !options.recordedNativeHooks.some((originalHook) => originalHook.key === key) && !Object.hasOwn(expectedConfig.hooks.state, key), "RECONCILE_ADDITIONS_IDENTITY");
|
|
54744
|
+
need4(hook.eventName === matchedEvents[event][0] && hook.handlerType === "command" && text2(hook.command, 16384) && !commands.has(hook.command) && Number.isInteger(hook.timeoutSec) && hook.timeoutSec > 0 && hook.timeoutSec <= 60 && (event === "PreToolUse" ? text2(hook.matcher) : hook.matcher === null) && hook.async === false && hook.statusMessage === null && hook.additionalContextLimit === null && hook.sourcePath === options.nativeHooksPath && hook.source === "user" && hook.pluginId === null && hook.isManaged === false && /^sha256:[a-f0-9]{64}$/.test(hook.currentHash) && hook.enabled === true && hook.trustStatus === "trusted", "RECONCILE_ADDITIONS_IDENTITY");
|
|
54745
|
+
let trustState = { enabled: true, trusted_hash: hook.currentHash };
|
|
54746
|
+
if (review.version === 2) {
|
|
54747
|
+
const state = addition.trustState;
|
|
54748
|
+
exactKeys2(state, state && Object.hasOwn(state, "enabled") ? ["enabled", "trusted_hash"] : ["trusted_hash"]);
|
|
54749
|
+
need4(state.trusted_hash === hook.currentHash && (!Object.hasOwn(state, "enabled") || state.enabled === true), "RECONCILE_ADDITIONS_TRUST_STATE");
|
|
54750
|
+
trustState = { ...state };
|
|
54751
|
+
}
|
|
54752
|
+
seen.add(key);
|
|
54753
|
+
commands.add(hook.command);
|
|
54754
|
+
added.push(hook);
|
|
54755
|
+
states.push(Object.freeze({ key, state: Object.freeze(trustState) }));
|
|
54756
|
+
expectedHooks.hooks[event] = [...groups, { ...event === "PreToolUse" ? { matcher: hook.matcher } : {}, hooks: [{ type: "command", command: hook.command, timeout: hook.timeoutSec }] }];
|
|
54757
|
+
expectedConfig.hooks.state[key] = trustState;
|
|
54758
|
+
}
|
|
54759
|
+
need4(isDeepStrictEqual5(expectedHooks, currentHooks), "RECONCILE_ADDITIONS_DECLARATIONS");
|
|
54760
|
+
const keys2 = added.map((hook) => hook.key);
|
|
54761
|
+
need4(isDeepStrictEqual5(expectedConfig, structure(options.configCurrent.text)) && codexTrustReconcileWitness(producerConfig.text, keys2) === codexTrustReconcileWitness(options.configCurrent.text, keys2) && codexTrustUnmanagedSemantic(producerConfig.text, keys2) === codexTrustUnmanagedSemantic(options.configCurrent.text, keys2), "RECONCILE_ADDITIONS_CONFIG");
|
|
54762
|
+
const inputs = [reviewFile, producerConfig, producerHooks, options.intent, options.policy, options.configBefore, options.configCurrent, options.hooksBefore, options.hooksCurrent];
|
|
54763
|
+
const recheck = () => {
|
|
54764
|
+
for (const input of inputs)
|
|
54765
|
+
unchanged2(input);
|
|
54766
|
+
};
|
|
54767
|
+
recheck();
|
|
54768
|
+
const trustProof = Object.freeze({ reviewSha256: reviewFile.sha256 });
|
|
54769
|
+
proofs.set(trustProof, { before: options.configBefore, current: options.configCurrent, journalHooks: options.journalHooks.map(({ key, currentHash }) => ({ key, currentHash })), states: Object.freeze(states), recheck });
|
|
54770
|
+
return { hooks: added, recheck, trustProof, receipt: { ...review.version === 2 ? { version: 2 } : {}, reviewPath: reviewFile.file, reviewSha256: reviewFile.sha256, reason: review.reason, producerEvidence: review.producerEvidence, producerBefore: { configPath: producerConfig.file, configSha256: producerConfig.sha256, hooksPath: producerHooks.file, hooksSha256: producerHooks.sha256 }, additions: review.version === 1 ? added : review.additions } };
|
|
54771
|
+
}
|
|
54772
|
+
var events, matchedEvents, hash2 = (value) => typeof value === "string" && /^[a-f0-9]{64}$/.test(value), text2 = (value, max2 = 2048) => typeof value === "string" && value.trim().length > 0 && value.length <= max2 && !/[\0\r\n]/.test(value), structure = (value) => JSON.parse(JSON.stringify(Bun.TOML.parse(value))), nativeKeys, proofs;
|
|
54773
|
+
var init_codex_hook_additions_review = __esm(() => {
|
|
54774
|
+
init_codex_hook_trust_files();
|
|
54775
|
+
init_codex_hook_trust_layout();
|
|
54776
|
+
events = { UserPromptSubmit: ["userPromptSubmit", "user_prompt_submit"], SessionStart: ["sessionStart", "session_start"], SubagentStart: ["subagentStart", "subagent_start"] };
|
|
54777
|
+
matchedEvents = { ...events, PreToolUse: ["preToolUse", "pre_tool_use"] };
|
|
54778
|
+
nativeKeys = ["key", "eventName", "handlerType", "command", "matcher", "timeoutSec", "async", "statusMessage", "additionalContextLimit", "sourcePath", "source", "pluginId", "isManaged", "currentHash", "enabled", "trustStatus"];
|
|
54779
|
+
proofs = new WeakMap;
|
|
54780
|
+
});
|
|
54781
|
+
|
|
54699
54782
|
// src/lib/codex-hook-discovery-recovery.ts
|
|
54700
54783
|
import { createHash as createHash15 } from "crypto";
|
|
54701
|
-
import { isDeepStrictEqual as
|
|
54702
|
-
function createCodexHookDiscoveryRecovery(binding, before2, current, hooks) {
|
|
54784
|
+
import { isDeepStrictEqual as isDeepStrictEqual6 } from "util";
|
|
54785
|
+
function createCodexHookDiscoveryRecovery(binding, before2, current, hooks, additions) {
|
|
54786
|
+
const journalHooks = hooks.map(({ key, currentHash }) => ({ key, currentHash }));
|
|
54787
|
+
const additionStates = additions ? readReviewedAdditionTrustStates(additions, before2, current, journalHooks) : [];
|
|
54788
|
+
const recheckAdditions = () => {
|
|
54789
|
+
if (additions)
|
|
54790
|
+
readReviewedAdditionTrustStates(additions, before2, current, journalHooks);
|
|
54791
|
+
};
|
|
54703
54792
|
const raw = binding.sources.filter((source) => source.path === current.file && source.hashMode === "bytes");
|
|
54704
54793
|
if (!raw.some((source) => source.sha256 !== current.sha256))
|
|
54705
54794
|
return;
|
|
54706
54795
|
need4(binding.agent === "codex" && binding.method === "reviewed" && raw.length === 1 && raw[0].sha256 === before2.sha256 && before2.sha256 !== current.sha256, "RECONCILE_DISCOVERY_CONFIG_WITNESS");
|
|
54707
54796
|
need4(raw[0].format === undefined && raw[0].fields === undefined && raw[0].managedPlugins === undefined, "RECONCILE_DISCOVERY_CONFIG_WITNESS");
|
|
54708
54797
|
const typed = binding.sources.filter((source) => source.path === current.file && source.format === "toml");
|
|
54709
|
-
need4(typed.length === 1 && typed[0].hashMode === undefined &&
|
|
54710
|
-
const original =
|
|
54798
|
+
need4(typed.length === 1 && typed[0].hashMode === undefined && isDeepStrictEqual6(typed[0].fields, fields), "RECONCILE_DISCOVERY_TYPED_WITNESS");
|
|
54799
|
+
const original = structure2(before2.text), actual = structure2(current.text);
|
|
54711
54800
|
const project = (value) => Object.fromEntries(fields.map((field2) => [field2, value[field2] ?? null]));
|
|
54712
54801
|
const projection = sha2(JSON.stringify(project(original)));
|
|
54713
|
-
need4(typed[0].sha256 === projection && sha2(JSON.stringify(project(actual))) === projection &&
|
|
54714
|
-
|
|
54715
|
-
|
|
54802
|
+
need4(typed[0].sha256 === projection && sha2(JSON.stringify(project(actual))) === projection && isDeepStrictEqual6(project(original), project(actual)), "RECONCILE_DISCOVERY_TYPED_WITNESS");
|
|
54803
|
+
const keys2 = [...journalHooks.map((hook) => hook.key), ...additionStates.map((hook) => hook.key)];
|
|
54804
|
+
need4(journalHooks.length > 0 && keys2.length <= 100 && new Set(keys2).size === keys2.length && journalHooks.every((hook) => typeof hook.key === "string" && /^sha256:[a-f0-9]{64}$/.test(hook.currentHash)), "RECONCILE_DISCOVERY_TRUST_WITNESS");
|
|
54805
|
+
const expected = structuredClone(original);
|
|
54716
54806
|
expected.hooks ??= {};
|
|
54717
54807
|
expected.hooks.state ??= {};
|
|
54718
|
-
for (const hook of
|
|
54808
|
+
for (const hook of journalHooks)
|
|
54719
54809
|
expected.hooks.state[hook.key] = { ...expected.hooks.state[hook.key], enabled: true, trusted_hash: hook.currentHash };
|
|
54720
|
-
|
|
54810
|
+
for (const { key, state } of additionStates)
|
|
54811
|
+
expected.hooks.state[key] = { ...state };
|
|
54812
|
+
need4(isDeepStrictEqual6(expected, actual) && codexTrustReconcileWitness(before2.text, keys2) === codexTrustReconcileWitness(current.text, keys2) && codexTrustUnmanagedSemantic(before2.text, keys2) === codexTrustUnmanagedSemantic(current.text, keys2), "RECONCILE_DISCOVERY_TRUST_WITNESS");
|
|
54721
54813
|
unchanged2(before2);
|
|
54722
54814
|
unchanged2(current);
|
|
54723
54815
|
const witness = Object.freeze({ configPath: current.file, beforeSha256: before2.sha256, currentSha256: current.sha256, discoverySha256: sha2(JSON.stringify(binding)), typedProjectionSha256: projection });
|
|
54724
|
-
|
|
54816
|
+
proofs2.set(witness, { before: before2, current, recheckAdditions });
|
|
54725
54817
|
return witness;
|
|
54726
54818
|
}
|
|
54727
54819
|
function assertCodexHookDiscoveryRecovery(binding, witness) {
|
|
54728
|
-
const proof =
|
|
54820
|
+
const proof = proofs2.get(witness);
|
|
54729
54821
|
need4(!!proof && binding.agent === "codex" && witness.discoverySha256 === sha2(JSON.stringify(binding)), "RECONCILE_DISCOVERY_RECOVERY_CHANGED");
|
|
54730
54822
|
unchanged2(proof.before);
|
|
54731
54823
|
unchanged2(proof.current);
|
|
54824
|
+
proof.recheckAdditions();
|
|
54732
54825
|
}
|
|
54733
54826
|
function verifiesCodexHookDiscoverySource(binding, source, currentDigest, witness) {
|
|
54734
54827
|
if (!witness || source.path !== witness.configPath || source.hashMode !== "bytes")
|
|
@@ -54737,21 +54830,22 @@ function verifiesCodexHookDiscoverySource(binding, source, currentDigest, witnes
|
|
|
54737
54830
|
need4(source.sha256 === witness.beforeSha256 && currentDigest === witness.currentSha256, "RECONCILE_DISCOVERY_RECOVERY_CHANGED");
|
|
54738
54831
|
return true;
|
|
54739
54832
|
}
|
|
54740
|
-
var sha2 = (
|
|
54833
|
+
var sha2 = (text3) => createHash15("sha256").update(text3).digest("hex"), fields, structure2 = (text3) => JSON.parse(JSON.stringify(Bun.TOML.parse(text3))), proofs2;
|
|
54741
54834
|
var init_codex_hook_discovery_recovery = __esm(() => {
|
|
54742
54835
|
init_codex_hook_trust_files();
|
|
54743
54836
|
init_codex_hook_trust_layout();
|
|
54837
|
+
init_codex_hook_additions_review();
|
|
54744
54838
|
fields = ["plugins", "marketplaces", "skills"];
|
|
54745
|
-
|
|
54839
|
+
proofs2 = new WeakMap;
|
|
54746
54840
|
});
|
|
54747
54841
|
|
|
54748
54842
|
// src/lib/agent-discovery.ts
|
|
54749
54843
|
import { createHash as createHash16 } from "crypto";
|
|
54750
54844
|
import { lstatSync as lstatSync20, readFileSync as readFileSync17, readdirSync as readdirSync10, realpathSync as realpathSync4 } from "fs";
|
|
54751
|
-
import { basename as basename8, dirname as dirname16, isAbsolute as
|
|
54752
|
-
function parseConfig(
|
|
54845
|
+
import { basename as basename8, dirname as dirname16, isAbsolute as isAbsolute15, join as join31, resolve as resolve15, sep as sep5 } from "path";
|
|
54846
|
+
function parseConfig(text3, path, toml = false) {
|
|
54753
54847
|
try {
|
|
54754
|
-
const value = toml ? Bun.TOML.parse(
|
|
54848
|
+
const value = toml ? Bun.TOML.parse(text3) : JSON.parse(text3);
|
|
54755
54849
|
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
54756
54850
|
throw new Error;
|
|
54757
54851
|
return value;
|
|
@@ -54760,7 +54854,7 @@ function parseConfig(text2, path, toml = false) {
|
|
|
54760
54854
|
}
|
|
54761
54855
|
}
|
|
54762
54856
|
function safe4(path) {
|
|
54763
|
-
if (!
|
|
54857
|
+
if (!isAbsolute15(path) || path.includes("\x00"))
|
|
54764
54858
|
throw new Error("Expected an absolute native discovery path");
|
|
54765
54859
|
for (let cursor = path;; cursor = dirname16(cursor)) {
|
|
54766
54860
|
if (lstatSync20(cursor, { throwIfNoEntry: false })?.isSymbolicLink())
|
|
@@ -54813,12 +54907,12 @@ function projected(source, changes, budget = discoveryByteBudget()) {
|
|
|
54813
54907
|
return hashDiscoveryPathFile(source.path, budget, changes);
|
|
54814
54908
|
return hashRawDiscoveryFile(source.path, budget, changes);
|
|
54815
54909
|
}
|
|
54816
|
-
const
|
|
54817
|
-
if (
|
|
54910
|
+
const text3 = read2(source.path, changes);
|
|
54911
|
+
if (text3 === null)
|
|
54818
54912
|
return null;
|
|
54819
54913
|
if (!source.format)
|
|
54820
|
-
return digest(
|
|
54821
|
-
const object4 = source.format === "yaml" ? parseHermesConfig(
|
|
54914
|
+
return digest(text3);
|
|
54915
|
+
const object4 = source.format === "yaml" ? parseHermesConfig(text3) : parseConfig(text3, source.path, source.format === "toml");
|
|
54822
54916
|
if (!object4 || typeof object4 !== "object" || Array.isArray(object4))
|
|
54823
54917
|
throw new Error("Expected native discovery configuration object");
|
|
54824
54918
|
return digest(JSON.stringify(Object.fromEntries((source.fields ?? []).map((field2) => [field2, object4[field2] ?? null]))));
|
|
@@ -54962,8 +55056,8 @@ function resolveAgentDiscovery(options) {
|
|
|
54962
55056
|
if (!lstatSync20(builtinRoot, { throwIfNoEntry: false })?.isDirectory())
|
|
54963
55057
|
unresolved("installed Gemini builtin root is missing");
|
|
54964
55058
|
for (const name of readdirSync10(builtinRoot).sort()) {
|
|
54965
|
-
const
|
|
54966
|
-
const match =
|
|
55059
|
+
const text3 = witness(join31(builtinRoot, name, "SKILL.md"));
|
|
55060
|
+
const match = text3?.match(/^---\r?\n[\s\S]*?^name:\s*([a-z0-9][a-z0-9-]*)\s*$/m);
|
|
54967
55061
|
if (!match?.[1] || builtinNames.includes(match[1]))
|
|
54968
55062
|
unresolved("installed Gemini builtin name is missing or ambiguous");
|
|
54969
55063
|
builtinNames.push(match[1]);
|
|
@@ -55041,7 +55135,7 @@ function resolveAgentDiscovery(options) {
|
|
|
55041
55135
|
unresolved("unsupported plugin enablement");
|
|
55042
55136
|
const split2 = id.lastIndexOf("@"), name = id.slice(0, split2), marketplace = id.slice(split2 + 1);
|
|
55043
55137
|
const market = config.marketplaces?.[marketplace] ?? (marketplace === "personal" ? { source_type: "local", source: home } : undefined);
|
|
55044
|
-
if (split2 < 1 || market?.source_type !== "local" || typeof market.source !== "string" || !
|
|
55138
|
+
if (split2 < 1 || market?.source_type !== "local" || typeof market.source !== "string" || !isAbsolute15(market.source))
|
|
55045
55139
|
unresolved("enabled plugin marketplace is not an explicit local source");
|
|
55046
55140
|
const catalogText = witness(join31(market.source, ".agents/plugins/marketplace.json"));
|
|
55047
55141
|
if (catalogText === null)
|
|
@@ -55057,7 +55151,7 @@ function resolveAgentDiscovery(options) {
|
|
|
55057
55151
|
if ((config.plugin?.length ?? 0) > 0 || config.skills?.urls?.length)
|
|
55058
55152
|
unresolved("external plugin or remote skill source");
|
|
55059
55153
|
for (const path of config.skills?.paths ?? []) {
|
|
55060
|
-
if (typeof path !== "string" || !
|
|
55154
|
+
if (typeof path !== "string" || !isAbsolute15(path))
|
|
55061
55155
|
unresolved("relative or malformed added skill root");
|
|
55062
55156
|
roots.add(path);
|
|
55063
55157
|
}
|
|
@@ -55095,7 +55189,7 @@ function resolveAgentDiscovery(options) {
|
|
|
55095
55189
|
}
|
|
55096
55190
|
return { agent, roots: [...roots].sort(), sources, method: "automatic", ...agent === "gemini" ? { builtinNames } : {}, ...agent === "hermes" ? { directories: captureDiscoveryDirectories([join31(home, ".hermes/plugins"), join31(home, ".hermes/hermes-agent")].map((path) => canonical4(path))) } : {} };
|
|
55097
55191
|
}
|
|
55098
|
-
var digest = (
|
|
55192
|
+
var digest = (text3) => createHash16("sha256").update(text3).digest("hex");
|
|
55099
55193
|
var init_agent_discovery = __esm(() => {
|
|
55100
55194
|
init_agent_policy_limits();
|
|
55101
55195
|
init_agent_hermes();
|
|
@@ -55227,7 +55321,7 @@ import {
|
|
|
55227
55321
|
statSync as statSync10,
|
|
55228
55322
|
writeFileSync as writeFileSync9
|
|
55229
55323
|
} from "fs";
|
|
55230
|
-
import { basename as basename10, dirname as dirname18, isAbsolute as
|
|
55324
|
+
import { basename as basename10, dirname as dirname18, isAbsolute as isAbsolute16, join as join33, normalize as normalize2, relative as relative5, resolve as resolve17, sep as sep7 } from "path";
|
|
55231
55325
|
function getPortableSkillsRoot(options = {}) {
|
|
55232
55326
|
return resolvePortableSkillsRoot(options, true);
|
|
55233
55327
|
}
|
|
@@ -55385,7 +55479,7 @@ function assertDisjointImportPaths(source, destination) {
|
|
|
55385
55479
|
const destinationPath = physicalImportPath(destination);
|
|
55386
55480
|
const contains2 = (parent, child) => {
|
|
55387
55481
|
const path = relative5(parent, child);
|
|
55388
|
-
return path === "" || !
|
|
55482
|
+
return path === "" || !isAbsolute16(path) && path !== ".." && !path.startsWith(`..${sep7}`);
|
|
55389
55483
|
};
|
|
55390
55484
|
if (contains2(sourcePath, destinationPath) || contains2(destinationPath, sourcePath)) {
|
|
55391
55485
|
throw new Error("Source and destination skill directories must not overlap");
|
|
@@ -55602,7 +55696,7 @@ function safeIsDirectory(path) {
|
|
|
55602
55696
|
}
|
|
55603
55697
|
}
|
|
55604
55698
|
function isSafeRelativePath2(value) {
|
|
55605
|
-
if (!value.trim() ||
|
|
55699
|
+
if (!value.trim() || isAbsolute16(value))
|
|
55606
55700
|
return false;
|
|
55607
55701
|
const normalized = normalize2(value).replace(/\\/g, "/");
|
|
55608
55702
|
return normalized !== ".." && !normalized.startsWith("../") && !normalized.includes("/../");
|
|
@@ -57626,8 +57720,8 @@ function getPublicSkillDiscovery(skill) {
|
|
|
57626
57720
|
function publicDiscoveryTags(tags) {
|
|
57627
57721
|
return tags.filter((tag) => !VENDOR_TAGS.has(tag.toLowerCase()));
|
|
57628
57722
|
}
|
|
57629
|
-
function sanitizePublicDiscoveryText(
|
|
57630
|
-
let sanitized =
|
|
57723
|
+
function sanitizePublicDiscoveryText(text3) {
|
|
57724
|
+
let sanitized = text3.replace(vendorPattern, "hosted AI").replace(/\bLLM\b/g, "AI").replace(/\s{2,}/g, " ");
|
|
57631
57725
|
let previous;
|
|
57632
57726
|
do {
|
|
57633
57727
|
previous = sanitized;
|
|
@@ -66247,8 +66341,8 @@ function lt_default() {
|
|
|
66247
66341
|
localeError: error33()
|
|
66248
66342
|
};
|
|
66249
66343
|
}
|
|
66250
|
-
var capitalizeFirstCharacter = (
|
|
66251
|
-
return
|
|
66344
|
+
var capitalizeFirstCharacter = (text3) => {
|
|
66345
|
+
return text3.charAt(0).toUpperCase() + text3.slice(1);
|
|
66252
66346
|
}, error33 = () => {
|
|
66253
66347
|
const Sizable = {
|
|
66254
66348
|
string: {
|
|
@@ -74081,7 +74175,7 @@ __export(exports_schemas2, {
|
|
|
74081
74175
|
httpUrl: () => httpUrl,
|
|
74082
74176
|
hostname: () => hostname2,
|
|
74083
74177
|
hex: () => hex2,
|
|
74084
|
-
hash: () =>
|
|
74178
|
+
hash: () => hash3,
|
|
74085
74179
|
guid: () => guid2,
|
|
74086
74180
|
function: () => _function,
|
|
74087
74181
|
float64: () => float64,
|
|
@@ -74287,7 +74381,7 @@ function hostname2(_params) {
|
|
|
74287
74381
|
function hex2(_params) {
|
|
74288
74382
|
return _stringFormat(ZodCustomStringFormat, "hex", exports_regexes.hex, _params);
|
|
74289
74383
|
}
|
|
74290
|
-
function
|
|
74384
|
+
function hash3(alg, params) {
|
|
74291
74385
|
const enc = params?.enc ?? "hex";
|
|
74292
74386
|
const format = `${alg}_${enc}`;
|
|
74293
74387
|
const regex2 = exports_regexes[format];
|
|
@@ -76547,7 +76641,7 @@ __export(exports_external, {
|
|
|
76547
76641
|
httpUrl: () => httpUrl,
|
|
76548
76642
|
hostname: () => hostname2,
|
|
76549
76643
|
hex: () => hex2,
|
|
76550
|
-
hash: () =>
|
|
76644
|
+
hash: () => hash3,
|
|
76551
76645
|
guid: () => guid2,
|
|
76552
76646
|
gte: () => _gte,
|
|
76553
76647
|
gt: () => _gt,
|
|
@@ -76782,8 +76876,8 @@ function safeAvailabilityCode(code) {
|
|
|
76782
76876
|
return;
|
|
76783
76877
|
return /^[A-Z0-9_]+$/.test(code) ? code : undefined;
|
|
76784
76878
|
}
|
|
76785
|
-
function sanitizeAvailabilityText(
|
|
76786
|
-
return secretValuePatterns.reduce((value, pattern) => value.replace(pattern, "credential"), sanitizePublicDiscoveryText(
|
|
76879
|
+
function sanitizeAvailabilityText(text3) {
|
|
76880
|
+
return secretValuePatterns.reduce((value, pattern) => value.replace(pattern, "credential"), sanitizePublicDiscoveryText(text3).replace(/\b[A-Z0-9_]*(?:API_KEY|SECRET|TOKEN|CREDENTIAL)[A-Z0-9_]*\b/g, "credential")).replace(/\s{2,}/g, " ").trim();
|
|
76787
76881
|
}
|
|
76788
76882
|
function parseRemoteRegistryPayload(payload) {
|
|
76789
76883
|
const parsed = parseRemoteContract(remoteRegistrySchema, payload, "Remote registry payload did not match the expected skills contract");
|
|
@@ -76988,11 +77082,11 @@ function canonicalJsonAtDepth(value, maximumBytes, maximumDepth) {
|
|
|
76988
77082
|
throw new Error("Invalid canonical JSON depth bound");
|
|
76989
77083
|
let bytes = 0;
|
|
76990
77084
|
const active = new Set;
|
|
76991
|
-
const piece = (
|
|
76992
|
-
bytes += Buffer.byteLength(
|
|
77085
|
+
const piece = (text3) => {
|
|
77086
|
+
bytes += Buffer.byteLength(text3);
|
|
76993
77087
|
if (bytes > maximumBytes)
|
|
76994
77088
|
throw new Error("Canonical JSON exceeds its bound");
|
|
76995
|
-
return
|
|
77089
|
+
return text3;
|
|
76996
77090
|
};
|
|
76997
77091
|
const visit3 = (v, depth) => {
|
|
76998
77092
|
if (depth > maximumDepth)
|
|
@@ -77131,9 +77225,9 @@ function requireResult(value) {
|
|
|
77131
77225
|
if (!value)
|
|
77132
77226
|
throw new RemoteRecurringReadError;
|
|
77133
77227
|
}
|
|
77134
|
-
function termsIntegrity(terms,
|
|
77228
|
+
function termsIntegrity(terms, hash4, identity4, own2) {
|
|
77135
77229
|
requireResult(terms.organizationId === identity4.organization.id && (!own2 || terms.approvedByUserId === identity4.user.id && terms.approvedMembershipId === identity4.user.membershipId));
|
|
77136
|
-
requireResult(canonicalJsonSha256(terms) ===
|
|
77230
|
+
requireResult(canonicalJsonSha256(terms) === hash4);
|
|
77137
77231
|
requireResult(canonicalJsonSha256({ skill: terms.skill, input: terms.input, args: terms.args, runtime: terms.runtime }) === terms.payloadSha256);
|
|
77138
77232
|
requireResult(Date.parse(terms.expiresAt) > Date.parse(terms.startsAt));
|
|
77139
77233
|
}
|
|
@@ -77529,7 +77623,7 @@ function invalid3() {
|
|
|
77529
77623
|
throw new Error(invalidWorkspaceResult);
|
|
77530
77624
|
}
|
|
77531
77625
|
function organization(v) {
|
|
77532
|
-
if (!record4(v) || !uuid8(v.id) || !
|
|
77626
|
+
if (!record4(v) || !uuid8(v.id) || !text3(v.slug) || !text3(v.name))
|
|
77533
77627
|
return invalid3();
|
|
77534
77628
|
return { id: v.id, slug: v.slug, name: v.name };
|
|
77535
77629
|
}
|
|
@@ -77549,7 +77643,7 @@ function parseWorkspaceIdentity(value, expectedUserId) {
|
|
|
77549
77643
|
if (!record4(value))
|
|
77550
77644
|
return invalid3();
|
|
77551
77645
|
const user = value.user;
|
|
77552
|
-
if (!record4(user) || !uuid8(user.id) || !uuid8(user.membershipId) || !
|
|
77646
|
+
if (!record4(user) || !uuid8(user.id) || !uuid8(user.membershipId) || !text3(user.email, 320) || !(user.displayName === null || text3(user.displayName)) || !role2(user.role))
|
|
77553
77647
|
return invalid3();
|
|
77554
77648
|
if (user.id !== expectedUserId)
|
|
77555
77649
|
throw new WorkspaceIdentityMismatchError;
|
|
@@ -77580,7 +77674,7 @@ function workspaceSelectionFailure(value, status) {
|
|
|
77580
77674
|
const code = value.code;
|
|
77581
77675
|
return workspaceSelectionFailures[code][0] === status ? code : null;
|
|
77582
77676
|
}
|
|
77583
|
-
var record4 = (v) => !!v && typeof v === "object" && !Array.isArray(v), uuid8 = (v) => typeof v === "string" && /^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/.test(v),
|
|
77677
|
+
var record4 = (v) => !!v && typeof v === "object" && !Array.isArray(v), uuid8 = (v) => typeof v === "string" && /^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/.test(v), text3 = (v, max2 = 1024) => typeof v === "string" && !!v.trim() && v.length <= max2 && !/[\p{Cc}\p{Cs}\u2028\u2029]/u.test(v), role2 = (v) => typeof v === "string" && ["owner", "admin", "member", "viewer"].includes(v), invalidWorkspaceResult = "The server returned an invalid workspace selection result.", WorkspaceContextInputError, WorkspaceIdentityMismatchError, workspaceSelectionFailures;
|
|
77584
77678
|
var init_remote_workspace_selection = __esm(() => {
|
|
77585
77679
|
WorkspaceContextInputError = class WorkspaceContextInputError extends Error {
|
|
77586
77680
|
constructor() {
|
|
@@ -80394,17 +80488,17 @@ var init_install = __esm(() => {
|
|
|
80394
80488
|
|
|
80395
80489
|
// src/lib/compact-output.ts
|
|
80396
80490
|
function truncateText(value, maxChars = 96) {
|
|
80397
|
-
const
|
|
80398
|
-
if (
|
|
80399
|
-
return
|
|
80400
|
-
return `${
|
|
80491
|
+
const text4 = String(value ?? "").replace(/\s+/g, " ").trim();
|
|
80492
|
+
if (text4.length <= maxChars)
|
|
80493
|
+
return text4;
|
|
80494
|
+
return `${text4.slice(0, Math.max(0, maxChars - 3)).trimEnd()}...`;
|
|
80401
80495
|
}
|
|
80402
80496
|
function previewText(value, maxChars = DEFAULT_PREVIEW_CHARS) {
|
|
80403
|
-
const
|
|
80497
|
+
const text4 = String(value ?? "");
|
|
80404
80498
|
return {
|
|
80405
|
-
text:
|
|
80406
|
-
length:
|
|
80407
|
-
truncated:
|
|
80499
|
+
text: text4.length > maxChars ? `${text4.slice(0, Math.max(0, maxChars - 3))}...` : text4,
|
|
80500
|
+
length: text4.length,
|
|
80501
|
+
truncated: text4.length > maxChars
|
|
80408
80502
|
};
|
|
80409
80503
|
}
|
|
80410
80504
|
function parsePageLimit(value, fallback, options = {}) {
|
|
@@ -80523,10 +80617,10 @@ function handleBrowseError(error61) {
|
|
|
80523
80617
|
process.exitCode = 1;
|
|
80524
80618
|
}
|
|
80525
80619
|
async function writeJson(value, space) {
|
|
80526
|
-
const
|
|
80620
|
+
const text4 = `${JSON.stringify(value, null, space)}
|
|
80527
80621
|
`;
|
|
80528
80622
|
await new Promise((resolve19, reject2) => {
|
|
80529
|
-
process.stdout.write(
|
|
80623
|
+
process.stdout.write(text4, (error61) => {
|
|
80530
80624
|
if (error61)
|
|
80531
80625
|
reject2(error61);
|
|
80532
80626
|
else
|
|
@@ -81085,7 +81179,7 @@ function handleDiff(name, options) {
|
|
|
81085
81179
|
const present = existsSync22(dir);
|
|
81086
81180
|
const managed = existsSync22(join37(dir, SYNC_MARKER_FILE));
|
|
81087
81181
|
const skillMdPath = join37(dir, "SKILL.md");
|
|
81088
|
-
const
|
|
81182
|
+
const hash4 = present && existsSync22(skillMdPath) ? hashSkillMarkdownFile(skillMdPath) : undefined;
|
|
81089
81183
|
let stub;
|
|
81090
81184
|
if (present && existsSync22(skillMdPath)) {
|
|
81091
81185
|
try {
|
|
@@ -81094,13 +81188,13 @@ function handleDiff(name, options) {
|
|
|
81094
81188
|
stub = undefined;
|
|
81095
81189
|
}
|
|
81096
81190
|
}
|
|
81097
|
-
const diverged = present && canonical4.present && managed &&
|
|
81191
|
+
const diverged = present && canonical4.present && managed && hash4 !== canonical4.hash;
|
|
81098
81192
|
homes.push({
|
|
81099
81193
|
agent,
|
|
81100
81194
|
path: dir,
|
|
81101
81195
|
present,
|
|
81102
81196
|
managed,
|
|
81103
|
-
...
|
|
81197
|
+
...hash4 ? { hash: hash4 } : {},
|
|
81104
81198
|
...stub !== undefined ? { stub } : {},
|
|
81105
81199
|
...diverged !== undefined ? { diverged } : {}
|
|
81106
81200
|
});
|
|
@@ -81956,13 +82050,13 @@ function scanUnmarkedHomes(options = {}) {
|
|
|
81956
82050
|
const skillMdPath = join39(dir, "SKILL.md");
|
|
81957
82051
|
if (!existsSync24(skillMdPath))
|
|
81958
82052
|
continue;
|
|
81959
|
-
const
|
|
82053
|
+
const hash4 = hashSkillMarkdownFile(skillMdPath);
|
|
81960
82054
|
const mtime = statSync12(skillMdPath).mtime.toISOString();
|
|
81961
|
-
const entry = { agent, skill, home, path: dir, hash:
|
|
82055
|
+
const entry = { agent, skill, home, path: dir, hash: hash4, mtime };
|
|
81962
82056
|
const canonicalHash = index.get(skill);
|
|
81963
82057
|
if (canonicalHash === undefined) {
|
|
81964
82058
|
scan.unknown.push({ ...entry });
|
|
81965
|
-
} else if (canonicalHash ===
|
|
82059
|
+
} else if (canonicalHash === hash4) {
|
|
81966
82060
|
scan.adoptable.push(entry);
|
|
81967
82061
|
} else {
|
|
81968
82062
|
scan.conflicts.push({ ...entry, canonicalHash });
|
|
@@ -82050,10 +82144,10 @@ function pruneOwnership(dir) {
|
|
|
82050
82144
|
const after2 = fstatSync15(descriptor), current = lstatSync22(dir), markerPathAfter = lstatSync22(markerPath);
|
|
82051
82145
|
if (!markerPathAfter.isFile() || markerPathAfter.dev !== before2.dev || markerPathAfter.ino !== before2.ino || markerPathAfter.size !== before2.size || markerPathAfter.mtimeMs !== before2.mtimeMs || markerPathAfter.ctimeMs !== before2.ctimeMs || length !== before2.size || after2.size !== before2.size || after2.mtimeMs !== before2.mtimeMs || after2.ctimeMs !== before2.ctimeMs || !current.isDirectory() || current.dev !== directory.dev || current.ino !== directory.ino)
|
|
82052
82146
|
return;
|
|
82053
|
-
const
|
|
82147
|
+
const text4 = bytes.subarray(0, length).toString("utf8"), marker = JSON.parse(text4);
|
|
82054
82148
|
if (!isSkillsOwnershipMarker(marker))
|
|
82055
82149
|
return;
|
|
82056
|
-
return { marker, identity: JSON.stringify([directory.dev, directory.ino, before2.dev, before2.ino, before2.mtimeMs, before2.ctimeMs,
|
|
82150
|
+
return { marker, identity: JSON.stringify([directory.dev, directory.ino, before2.dev, before2.ino, before2.mtimeMs, before2.ctimeMs, text4]) };
|
|
82057
82151
|
} catch {
|
|
82058
82152
|
return;
|
|
82059
82153
|
} finally {
|
|
@@ -82099,15 +82193,15 @@ function pruneStrayHomes(options = {}) {
|
|
|
82099
82193
|
const marker = owned.marker;
|
|
82100
82194
|
ownership.set(dir, owned.identity);
|
|
82101
82195
|
const skillMdPath = join39(dir, "SKILL.md");
|
|
82102
|
-
const
|
|
82103
|
-
candidates.push({ agent, skill, home, path: dir, hash:
|
|
82196
|
+
const hash4 = existsSync24(skillMdPath) ? hashSkillMarkdownFile(skillMdPath) : "";
|
|
82197
|
+
candidates.push({ agent, skill, home, path: dir, hash: hash4, marker });
|
|
82104
82198
|
}
|
|
82105
82199
|
}
|
|
82106
82200
|
if (!options.apply) {
|
|
82107
82201
|
return { candidates, pruned: 0, dryRun: true };
|
|
82108
82202
|
}
|
|
82109
82203
|
const appDir = options.homeDir ? join39(options.homeDir, ".hasna", "skills") : getDataDir();
|
|
82110
|
-
const rollbackFile = writeRollbackRecord("prune", candidates.map(({ agent, skill, path, hash:
|
|
82204
|
+
const rollbackFile = writeRollbackRecord("prune", candidates.map(({ agent, skill, path, hash: hash4, marker }) => ({ agent, skill, path, hash: hash4, marker })), appDir);
|
|
82111
82205
|
let pruned = 0;
|
|
82112
82206
|
for (const candidate2 of candidates) {
|
|
82113
82207
|
if (pruneOwnership(candidate2.path)?.identity !== ownership.get(candidate2.path))
|
|
@@ -82338,10 +82432,10 @@ function setEnvAssignment(path, assignment) {
|
|
|
82338
82432
|
}
|
|
82339
82433
|
let prepared = initial2;
|
|
82340
82434
|
if (previous) {
|
|
82341
|
-
const original = readFileSync27(descriptor),
|
|
82342
|
-
if (!Buffer.from(
|
|
82435
|
+
const original = readFileSync27(descriptor), text4 = original.toString("utf8");
|
|
82436
|
+
if (!Buffer.from(text4, "utf8").equals(original))
|
|
82343
82437
|
throw new EnvAssignmentError(INVALID_LAYOUT);
|
|
82344
|
-
prepared = prepareEnvAssignment(assignment,
|
|
82438
|
+
prepared = prepareEnvAssignment(assignment, text4);
|
|
82345
82439
|
}
|
|
82346
82440
|
const bytes = Buffer.from(prepared.content, "utf8");
|
|
82347
82441
|
let written = 0;
|
|
@@ -82881,7 +82975,7 @@ import { closeSync as closeSync17, fstatSync as fstatSync17, openSync as openSyn
|
|
|
82881
82975
|
import { O_NOFOLLOW as O_NOFOLLOW3, O_NONBLOCK as O_NONBLOCK3, O_RDONLY as O_RDONLY3 } from "constants";
|
|
82882
82976
|
import { createRequire as createRequire2 } from "module";
|
|
82883
82977
|
import { hostname as osHostname2 } from "os";
|
|
82884
|
-
import { isAbsolute as
|
|
82978
|
+
import { isAbsolute as isAbsolute17, join as join42 } from "path";
|
|
82885
82979
|
import { createRequire as createRequire22 } from "module";
|
|
82886
82980
|
function envToken2(name) {
|
|
82887
82981
|
return name.toUpperCase().replace(/-/g, "_");
|
|
@@ -82905,7 +82999,7 @@ function homeDir2(env3) {
|
|
|
82905
82999
|
}
|
|
82906
83000
|
function absoluteOverride2(env3, key) {
|
|
82907
83001
|
const value = env3[key]?.trim();
|
|
82908
|
-
return value &&
|
|
83002
|
+
return value && isAbsolute17(value) ? value : null;
|
|
82909
83003
|
}
|
|
82910
83004
|
function hasnaHomeDir2(env3) {
|
|
82911
83005
|
const override = absoluteOverride2(env3, HASNA_HOME_ENV_KEY2);
|
|
@@ -82936,10 +83030,10 @@ function credentialDiskSources2(name, env3) {
|
|
|
82936
83030
|
function profileDiskSources2(name, env3, profile) {
|
|
82937
83031
|
return credentialDiskSourceList2(name, env3, profile).map((s) => s.path);
|
|
82938
83032
|
}
|
|
82939
|
-
function parseEnvFile2(
|
|
83033
|
+
function parseEnvFile2(text4) {
|
|
82940
83034
|
const values2 = new Map;
|
|
82941
83035
|
const unusable = new Set;
|
|
82942
|
-
for (const rawLine of
|
|
83036
|
+
for (const rawLine of text4.split(/\r?\n/)) {
|
|
82943
83037
|
const line = rawLine.trim();
|
|
82944
83038
|
if (line.length === 0 || line.startsWith("#"))
|
|
82945
83039
|
continue;
|
|
@@ -83179,8 +83273,8 @@ function keychainAccount2(env3, options) {
|
|
|
83179
83273
|
const user = env3.USER?.trim();
|
|
83180
83274
|
return user || null;
|
|
83181
83275
|
}
|
|
83182
|
-
function keychainFailureHint2(
|
|
83183
|
-
const line =
|
|
83276
|
+
function keychainFailureHint2(text4) {
|
|
83277
|
+
const line = text4.split(/\r?\n/).find((entry) => entry.trim().length > 0)?.trim() ?? "";
|
|
83184
83278
|
const clean = line.replace(/[\u0000-\u001f\u007f]/g, "").slice(0, 200);
|
|
83185
83279
|
return clean ? `: ${clean}` : "";
|
|
83186
83280
|
}
|
|
@@ -83758,12 +83852,12 @@ function createHasnaHttpTransportInternal(options, requestBindingProvider) {
|
|
|
83758
83852
|
await response.body?.cancel();
|
|
83759
83853
|
} catch {}
|
|
83760
83854
|
} else {
|
|
83761
|
-
const
|
|
83762
|
-
if (
|
|
83855
|
+
const text4 = await response.text();
|
|
83856
|
+
if (text4.length > 0) {
|
|
83763
83857
|
try {
|
|
83764
|
-
parsed = JSON.parse(
|
|
83858
|
+
parsed = JSON.parse(text4);
|
|
83765
83859
|
} catch {
|
|
83766
|
-
parsed =
|
|
83860
|
+
parsed = text4;
|
|
83767
83861
|
}
|
|
83768
83862
|
}
|
|
83769
83863
|
}
|
|
@@ -83866,13 +83960,13 @@ class SecretsClient {
|
|
|
83866
83960
|
headers,
|
|
83867
83961
|
redirect: "manual"
|
|
83868
83962
|
});
|
|
83869
|
-
const
|
|
83963
|
+
const text4 = await response.text();
|
|
83870
83964
|
let body = undefined;
|
|
83871
|
-
if (
|
|
83965
|
+
if (text4) {
|
|
83872
83966
|
try {
|
|
83873
|
-
body = JSON.parse(
|
|
83967
|
+
body = JSON.parse(text4);
|
|
83874
83968
|
} catch {
|
|
83875
|
-
body =
|
|
83969
|
+
body = text4;
|
|
83876
83970
|
}
|
|
83877
83971
|
}
|
|
83878
83972
|
if (!response.ok) {
|
|
@@ -84201,7 +84295,7 @@ function refuse(code, message) {
|
|
|
84201
84295
|
function record7(value) {
|
|
84202
84296
|
return !!value && typeof value === "object" && !Array.isArray(value);
|
|
84203
84297
|
}
|
|
84204
|
-
function
|
|
84298
|
+
function exactKeys3(value, keys2) {
|
|
84205
84299
|
return Object.keys(value).length === keys2.length && keys2.every((key) => Object.hasOwn(value, key));
|
|
84206
84300
|
}
|
|
84207
84301
|
function identifier2(value) {
|
|
@@ -84241,7 +84335,7 @@ function readSelectedSecretBindings(path) {
|
|
|
84241
84335
|
}
|
|
84242
84336
|
}
|
|
84243
84337
|
function validateSelectedSecretBindings(value, scope, names) {
|
|
84244
|
-
if (!record7(value) || !
|
|
84338
|
+
if (!record7(value) || !exactKeys3(value, ["schema", "selection", "consumer", "secretsAuthority", "bindings"]) || value.schema !== "hasna.skills-secret-bindings.v1" || !record7(value.selection) || !exactKeys3(value.selection, ["authority", "workspaceId", "profileId", "profileRevision", "slug", "version", "bundleDigest"]) || !record7(value.consumer) || !exactKeys3(value.consumer, ["stationId", "workspaceDirectory"]) || !record7(value.bindings)) {
|
|
84245
84339
|
return refuse("INVALID_SECRET_BINDINGS", "Secret bindings do not match the hasna.skills-secret-bindings.v1 contract.");
|
|
84246
84340
|
}
|
|
84247
84341
|
for (const [key, expected] of Object.entries({ authority: scope.selection.authority, workspaceId: scope.selection.workspaceId, profileId: scope.profileId, profileRevision: scope.selection.profileRevision, slug: scope.selection.slug, version: scope.selection.version, bundleDigest: scope.selection.bundleDigest })) {
|
|
@@ -84266,7 +84360,7 @@ function validateSelectedSecretBindings(value, scope, names) {
|
|
|
84266
84360
|
} catch {
|
|
84267
84361
|
return refuse("INVALID_SECRET_BINDINGS", "Secret bindings require a canonical HTTPS Secrets /v1 authority (loopback HTTP is allowed).");
|
|
84268
84362
|
}
|
|
84269
|
-
if (!
|
|
84363
|
+
if (!exactKeys3(value.bindings, names) || Object.values(value.bindings).some((key) => !identifier2(key) || !/^[A-Za-z0-9][A-Za-z0-9._/-]*$/.test(key) || key.split("/").some((part) => !part || part === "." || part === ".."))) {
|
|
84270
84364
|
return refuse("INVALID_SECRET_BINDINGS", "Bind every declared environment name exactly once to a vault key; undeclared bindings and values are refused.");
|
|
84271
84365
|
}
|
|
84272
84366
|
return structuredClone(value);
|
|
@@ -84296,7 +84390,7 @@ async function resolveSelectedSecrets(bindings, createClient2 = createSecretsCli
|
|
|
84296
84390
|
return refuse("LOCAL_SECRET_UNAVAILABLE", "A declared secret could not be resolved, was invalid, or has expired. The skill was not started; no fallback was attempted.");
|
|
84297
84391
|
}
|
|
84298
84392
|
}
|
|
84299
|
-
function redactExecutionSecrets(
|
|
84393
|
+
function redactExecutionSecrets(text4, env3) {
|
|
84300
84394
|
const values2 = new Set(Object.values(env3).flatMap((value) => {
|
|
84301
84395
|
let encoded = "";
|
|
84302
84396
|
try {
|
|
@@ -84305,8 +84399,8 @@ function redactExecutionSecrets(text3, env3) {
|
|
|
84305
84399
|
return [value, JSON.stringify(value).slice(1, -1), Buffer.from(value).toString("base64"), encoded];
|
|
84306
84400
|
}));
|
|
84307
84401
|
for (const value of [...values2].filter(Boolean).sort((a, b) => b.length - a.length))
|
|
84308
|
-
|
|
84309
|
-
return
|
|
84402
|
+
text4 = text4.split(value).join("[REDACTED]");
|
|
84403
|
+
return text4;
|
|
84310
84404
|
}
|
|
84311
84405
|
var init_execution_secrets = __esm(() => {
|
|
84312
84406
|
init_sdk();
|
|
@@ -84444,7 +84538,7 @@ var init_execution_grants = __esm(() => {
|
|
|
84444
84538
|
});
|
|
84445
84539
|
|
|
84446
84540
|
// src/lib/execution-grant-client.ts
|
|
84447
|
-
import { isDeepStrictEqual as
|
|
84541
|
+
import { isDeepStrictEqual as isDeepStrictEqual7 } from "util";
|
|
84448
84542
|
function id(value) {
|
|
84449
84543
|
if (!grantIdentifier(value))
|
|
84450
84544
|
throw new Error("Invalid execution grant profile or revision identifier.");
|
|
@@ -84496,7 +84590,7 @@ async function saveExecutionGrantPolicy(profileId, grants, revision) {
|
|
|
84496
84590
|
headers: revision === undefined ? { "If-None-Match": "*" } : { "If-Match": `"${revision}"` },
|
|
84497
84591
|
body: JSON.stringify({ grants: snapshot2 })
|
|
84498
84592
|
}));
|
|
84499
|
-
if (policy.profileId !== profileId || policy.previousRevision !== (revision ?? null) || !
|
|
84593
|
+
if (policy.profileId !== profileId || policy.previousRevision !== (revision ?? null) || !isDeepStrictEqual7(policy.grants, snapshot2)) {
|
|
84500
84594
|
throw new Error("The API did not preserve the reviewed execution grant policy; read it before retrying.");
|
|
84501
84595
|
}
|
|
84502
84596
|
return policy;
|
|
@@ -84507,7 +84601,7 @@ async function resolveExecutionGrant(input2) {
|
|
|
84507
84601
|
if (!grantRecord(value) || Object.keys(value).length !== 3 || !grantIdentifier(value.policyRevision) || !grantIdentifier(value.grantId) || !grantRecord(value.bindings)) {
|
|
84508
84602
|
throw new SkillSelectionError("INVALID_EXECUTION_GRANT", "The Skills API returned an invalid execution grant.");
|
|
84509
84603
|
}
|
|
84510
|
-
if (!
|
|
84604
|
+
if (!isDeepStrictEqual7(value.bindings.selection, snapshot2.selection) || !isDeepStrictEqual7(value.bindings.consumer, snapshot2.consumer)) {
|
|
84511
84605
|
throw new SkillSelectionError("EXECUTION_GRANT_SCOPE_MISMATCH", "The Skills API returned a grant for a different selection or consumer.");
|
|
84512
84606
|
}
|
|
84513
84607
|
return value;
|
|
@@ -93602,10 +93696,10 @@ var require_util = __commonJS((exports) => {
|
|
|
93602
93696
|
var codegen_1 = require_codegen();
|
|
93603
93697
|
var code_1 = require_code();
|
|
93604
93698
|
function toHash(arr) {
|
|
93605
|
-
const
|
|
93699
|
+
const hash4 = {};
|
|
93606
93700
|
for (const item of arr)
|
|
93607
|
-
|
|
93608
|
-
return
|
|
93701
|
+
hash4[item] = true;
|
|
93702
|
+
return hash4;
|
|
93609
93703
|
}
|
|
93610
93704
|
exports.toHash = toHash;
|
|
93611
93705
|
function alwaysValidSchema(it, schema) {
|
|
@@ -97067,7 +97161,7 @@ var require_core = __commonJS((exports) => {
|
|
|
97067
97161
|
errorsText(errors5 = this.errors, { separator = ", ", dataVar = "data" } = {}) {
|
|
97068
97162
|
if (!errors5 || errors5.length === 0)
|
|
97069
97163
|
return "No errors";
|
|
97070
|
-
return errors5.map((e2) => `${dataVar}${e2.instancePath} ${e2.message}`).reduce((
|
|
97164
|
+
return errors5.map((e2) => `${dataVar}${e2.instancePath} ${e2.message}`).reduce((text4, msg) => text4 + separator + msg);
|
|
97071
97165
|
}
|
|
97072
97166
|
$dataMetaSchema(metaSchema, keywordsJsonPointers) {
|
|
97073
97167
|
const rules = this.RULES.all;
|
|
@@ -101145,11 +101239,11 @@ var init_remote_invitation_recovery = __esm(() => {
|
|
|
101145
101239
|
// src/lib/remote-private-publications.ts
|
|
101146
101240
|
import { createHash as createHash23 } from "crypto";
|
|
101147
101241
|
function checkedPublicationDeclaration(value) {
|
|
101148
|
-
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 || !
|
|
101242
|
+
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)
|
|
101149
101243
|
return bad();
|
|
101150
101244
|
try {
|
|
101151
101245
|
const manifest = JSON.parse(value.manifestText);
|
|
101152
|
-
if (!record10(manifest) || manifest.version !== value.version || validatePortableManifestContract(manifest, { strict: true }).length || !
|
|
101246
|
+
if (!record10(manifest) || manifest.version !== value.version || validatePortableManifestContract(manifest, { strict: true }).length || !hash4(manifest.provenance?.content_hash))
|
|
101153
101247
|
return bad();
|
|
101154
101248
|
} catch {
|
|
101155
101249
|
return bad();
|
|
@@ -101157,7 +101251,7 @@ function checkedPublicationDeclaration(value) {
|
|
|
101157
101251
|
return Object.freeze({ ...value });
|
|
101158
101252
|
}
|
|
101159
101253
|
function checkedPublicationView(value, skillId, intentId, declaration) {
|
|
101160
|
-
if (!exact(value, ["id", "skillId", "version", "expectedCurrentVersionId", "archiveSha256", "archiveByteSize", "state", "expiresAt", "createdAt", "versionId"]) || !publicationUuid(value.id) || value.skillId !== skillId || intentId !== undefined && value.id !== intentId || typeof value.version !== "string" || !value.version || value.version.length > 128 || /[\p{Cc}\p{Cs}]/u.test(value.version) || !(value.expectedCurrentVersionId === null || publicationUuid(value.expectedCurrentVersionId)) || !
|
|
101254
|
+
if (!exact(value, ["id", "skillId", "version", "expectedCurrentVersionId", "archiveSha256", "archiveByteSize", "state", "expiresAt", "createdAt", "versionId"]) || !publicationUuid(value.id) || value.skillId !== skillId || intentId !== undefined && value.id !== intentId || typeof value.version !== "string" || !value.version || value.version.length > 128 || /[\p{Cc}\p{Cs}]/u.test(value.version) || !(value.expectedCurrentVersionId === null || publicationUuid(value.expectedCurrentVersionId)) || !hash4(value.archiveSha256) || !Number.isSafeInteger(value.archiveByteSize) || Number(value.archiveByteSize) < 1 || Number(value.archiveByteSize) > PRIVATE_PUBLICATION_MAX_BYTES || typeof value.state !== "string" || !["awaiting_upload", "queued", "verifying", "needs_attention", "committed", "rejected", "cancelled", "expired"].includes(value.state) || !date6(value.expiresAt) || !date6(value.createdAt) || !(value.versionId === null || publicationUuid(value.versionId)) || value.state === "committed" && value.versionId === null)
|
|
101161
101255
|
return invalid5();
|
|
101162
101256
|
if (declaration && ["version", "expectedCurrentVersionId", "archiveSha256", "archiveByteSize"].some((k) => value[k] !== declaration[k]))
|
|
101163
101257
|
return invalid5();
|
|
@@ -101404,7 +101498,7 @@ var PRIVATE_PUBLICATION_MAX_BYTES, failures2, PrivatePublicationError, bad = ()
|
|
|
101404
101498
|
throw new PrivatePublicationError("INVALID_PUBLICATION_INPUT", "Invalid publication input or recovery data.");
|
|
101405
101499
|
}, invalid5 = () => {
|
|
101406
101500
|
throw new PrivatePublicationError("INVALID_PUBLICATION_RESPONSE", "The server returned an invalid publication result.");
|
|
101407
|
-
}, publicationUuid = (v) => typeof v === "string" && /^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/.test(v),
|
|
101501
|
+
}, publicationUuid = (v) => typeof v === "string" && /^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/.test(v), hash4 = (v) => typeof v === "string" && /^[a-f0-9]{64}$/.test(v), record10 = (v) => !!v && typeof v === "object" && !Array.isArray(v), exact = (v, keys3) => record10(v) && Object.keys(v).sort().join(",") === keys3.sort().join(","), date6 = (v) => typeof v === "string" && /^\d{4}-\d\d-\d\dT[0-9:.]+(?:Z|[+-](?:[01]\d|2[0-3]):[0-5]\d)$/.test(v) && Number.isFinite(Date.parse(v)), publicationSha256 = (bytes) => createHash23("sha256").update(bytes).digest("hex");
|
|
101408
101502
|
var init_remote_private_publications = __esm(() => {
|
|
101409
101503
|
init_fleet_credentials();
|
|
101410
101504
|
init_remote_workspace_selection();
|
|
@@ -101465,8 +101559,8 @@ async function requestAuthApi(instance, path, options) {
|
|
|
101465
101559
|
apiUrl: safeUrl
|
|
101466
101560
|
});
|
|
101467
101561
|
}
|
|
101468
|
-
const
|
|
101469
|
-
const body =
|
|
101562
|
+
const text4 = await res.text();
|
|
101563
|
+
const body = text4 ? parseJsonBody(text4) : {};
|
|
101470
101564
|
if (!res.ok) {
|
|
101471
101565
|
const record11 = isRecord5(body) ? body : {};
|
|
101472
101566
|
const detail = typeof record11.detail === "string" ? record11.detail : undefined;
|
|
@@ -101482,15 +101576,15 @@ async function requestAuthApi(instance, path, options) {
|
|
|
101482
101576
|
}
|
|
101483
101577
|
return body;
|
|
101484
101578
|
}
|
|
101485
|
-
function parseJsonBody(
|
|
101579
|
+
function parseJsonBody(text4) {
|
|
101486
101580
|
try {
|
|
101487
|
-
return JSON.parse(
|
|
101581
|
+
return JSON.parse(text4);
|
|
101488
101582
|
} catch {
|
|
101489
|
-
return { detail: condenseErrorBody(
|
|
101583
|
+
return { detail: condenseErrorBody(text4) };
|
|
101490
101584
|
}
|
|
101491
101585
|
}
|
|
101492
|
-
function condenseErrorBody(
|
|
101493
|
-
const stripped = /<[a-z!/]/i.test(
|
|
101586
|
+
function condenseErrorBody(text4) {
|
|
101587
|
+
const stripped = /<[a-z!/]/i.test(text4) ? text4.replace(/<(script|style)[\s\S]*?<\/\1>/gi, " ").replace(/<[^>]*>/g, " ") : text4;
|
|
101494
101588
|
const collapsed = stripped.replace(/\s+/g, " ").trim();
|
|
101495
101589
|
if (collapsed.length <= MAX_ERROR_DETAIL_LENGTH)
|
|
101496
101590
|
return collapsed;
|
|
@@ -101706,12 +101800,12 @@ function safeText(file2) {
|
|
|
101706
101800
|
}
|
|
101707
101801
|
}
|
|
101708
101802
|
function checkIdentityMetadata(file2, identity4) {
|
|
101709
|
-
const
|
|
101710
|
-
if (
|
|
101803
|
+
const text4 = safeText(file2);
|
|
101804
|
+
if (text4 === null)
|
|
101711
101805
|
return;
|
|
101712
101806
|
let value;
|
|
101713
101807
|
try {
|
|
101714
|
-
value = JSON.parse(
|
|
101808
|
+
value = JSON.parse(text4);
|
|
101715
101809
|
} catch {
|
|
101716
101810
|
return fail3("The profile identity metadata is invalid. Sign in again before managing this workspace.");
|
|
101717
101811
|
}
|
|
@@ -102050,7 +102144,7 @@ var init_recurring_customer = __esm(() => {
|
|
|
102050
102144
|
|
|
102051
102145
|
// src/lib/recurring-recovery.ts
|
|
102052
102146
|
import { constants as constants17, closeSync as closeSync20, fsyncSync as fsyncSync5, fstatSync as fstatSync20, lstatSync as lstatSync25, mkdirSync as mkdirSync17, openSync as openSync20, readSync as readSync14, realpathSync as realpathSync9, renameSync as renameSync10, unlinkSync as unlinkSync6, writeFileSync as writeFileSync17 } from "fs";
|
|
102053
|
-
import { dirname as dirname23, isAbsolute as
|
|
102147
|
+
import { dirname as dirname23, isAbsolute as isAbsolute18, join as join46, resolve as resolve20 } from "path";
|
|
102054
102148
|
import { randomUUID as randomUUID7 } from "crypto";
|
|
102055
102149
|
|
|
102056
102150
|
class RecoveryOwner {
|
|
@@ -102058,7 +102152,7 @@ class RecoveryOwner {
|
|
|
102058
102152
|
parents = [];
|
|
102059
102153
|
constructor(directory) {
|
|
102060
102154
|
this.directory = directory;
|
|
102061
|
-
if (!
|
|
102155
|
+
if (!isAbsolute18(directory) || resolve20(directory) !== directory || realpathSync9(directory) !== directory)
|
|
102062
102156
|
invalid6();
|
|
102063
102157
|
for (let path = directory;; path = dirname23(path)) {
|
|
102064
102158
|
const stat3 = lstatSync25(path);
|
|
@@ -102193,7 +102287,7 @@ function base2(customer, organizationId) {
|
|
|
102193
102287
|
};
|
|
102194
102288
|
}
|
|
102195
102289
|
function create3(directory, intent) {
|
|
102196
|
-
if (!
|
|
102290
|
+
if (!isAbsolute18(directory) || resolve20(directory) !== directory || realpathSync9(dirname23(directory)) !== dirname23(directory))
|
|
102197
102291
|
invalid6();
|
|
102198
102292
|
mkdirSync17(directory, { mode: 448 });
|
|
102199
102293
|
const owner2 = new RecoveryOwner(directory), checked = intentSchema.parse(intent), intentSha256 = canonicalJsonSha256(checked);
|
|
@@ -102356,12 +102450,12 @@ var init_recurring_recovery = __esm(() => {
|
|
|
102356
102450
|
});
|
|
102357
102451
|
|
|
102358
102452
|
// src/lib/recurring-surface.ts
|
|
102359
|
-
import { isAbsolute as
|
|
102453
|
+
import { isAbsolute as isAbsolute19 } from "path";
|
|
102360
102454
|
function recurringMcpSchema(action) {
|
|
102361
102455
|
return action === "activate" ? recurringSurfaceSchemas.activate.extend({ code, confirm: exports_external.literal(true) }) : recurringSurfaceSchemas[action];
|
|
102362
102456
|
}
|
|
102363
|
-
function expectedDraft(draft,
|
|
102364
|
-
if (!draft || draft.termsSha256 !==
|
|
102457
|
+
function expectedDraft(draft, hash5) {
|
|
102458
|
+
if (!draft || draft.termsSha256 !== hash5)
|
|
102365
102459
|
throw new RemoteRecurringError("RECURRING_TERMS_UNAVAILABLE");
|
|
102366
102460
|
return draft;
|
|
102367
102461
|
}
|
|
@@ -102461,7 +102555,7 @@ var init_recurring_surface = __esm(() => {
|
|
|
102461
102555
|
uuid13 = exports_external.string().regex(/^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/);
|
|
102462
102556
|
context = { userId: uuid13.optional(), membershipId: uuid13.optional() };
|
|
102463
102557
|
page2 = { limit: exports_external.number().int().min(1).max(100).optional(), cursor: exports_external.string().min(1).max(2048).optional() };
|
|
102464
|
-
directory = exports_external.string().max(4096).refine(
|
|
102558
|
+
directory = exports_external.string().max(4096).refine(isAbsolute19, "Use an absolute recovery directory");
|
|
102465
102559
|
email4 = exports_external.string().trim().toLowerCase().email().max(254);
|
|
102466
102560
|
code = exports_external.string().regex(/^\d{6}$/);
|
|
102467
102561
|
recurringSurfaceSchemas = {
|
|
@@ -105263,10 +105357,10 @@ var init_private_publication_customer = __esm(() => {
|
|
|
105263
105357
|
|
|
105264
105358
|
// src/lib/private-publication-recovery.ts
|
|
105265
105359
|
import { constants as constants18, closeSync as closeSync21, fsyncSync as fsyncSync6, fstatSync as fstatSync21, lstatSync as lstatSync26, mkdirSync as mkdirSync21, openSync as openSync21, readSync as readSync15, realpathSync as realpathSync10, renameSync as renameSync11, unlinkSync as unlinkSync7, writeFileSync as writeFileSync20 } from "fs";
|
|
105266
|
-
import { dirname as dirname26, isAbsolute as
|
|
105360
|
+
import { dirname as dirname26, isAbsolute as isAbsolute20, join as join51, resolve as resolve21 } from "path";
|
|
105267
105361
|
import { randomUUID as randomUUID8 } from "crypto";
|
|
105268
105362
|
function safeDirectory(directory2) {
|
|
105269
|
-
if (!
|
|
105363
|
+
if (!isAbsolute20(directory2) || directory2 !== resolve21(directory2) || realpathSync10(directory2) !== directory2)
|
|
105270
105364
|
return fail4();
|
|
105271
105365
|
for (let path = directory2;; path = dirname26(path)) {
|
|
105272
105366
|
const stat3 = lstatSync26(path);
|
|
@@ -105404,7 +105498,7 @@ async function preparePrivatePublication(client2, sourceDirectory, recoveryDirec
|
|
|
105404
105498
|
phase: "prepared",
|
|
105405
105499
|
intent: null
|
|
105406
105500
|
};
|
|
105407
|
-
if (!
|
|
105501
|
+
if (!isAbsolute20(recoveryDirectory) || resolve21(recoveryDirectory) !== recoveryDirectory || realpathSync10(dirname26(recoveryDirectory)) !== dirname26(recoveryDirectory))
|
|
105408
105502
|
return fail4();
|
|
105409
105503
|
mkdirSync21(recoveryDirectory, { mode: 448 });
|
|
105410
105504
|
safeDirectory(recoveryDirectory);
|
|
@@ -105505,10 +105599,10 @@ var init_private_publication_recovery = __esm(() => {
|
|
|
105505
105599
|
});
|
|
105506
105600
|
|
|
105507
105601
|
// src/mcp/private-publication-tools.ts
|
|
105508
|
-
import { isAbsolute as
|
|
105602
|
+
import { isAbsolute as isAbsolute21 } from "path";
|
|
105509
105603
|
function registerPrivatePublicationTools(server) {
|
|
105510
105604
|
const uuid9 = exports_external.string().regex(/^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/);
|
|
105511
|
-
const directory2 = exports_external.string().max(4096).refine(
|
|
105605
|
+
const directory2 = exports_external.string().max(4096).refine(isAbsolute21, "Use an absolute local directory");
|
|
105512
105606
|
const verification2 = { email: exports_external.string().email().max(254), code: exports_external.string().regex(/^\d{6}$/), userId: uuid9, membershipId: uuid9, recoveryDirectory: directory2 };
|
|
105513
105607
|
const description = "Manage a private source publication using fresh workspace-bound verification and a host-local recovery directory. Publishing requires explicit UUID current-version comparison and upload consent. Resume reuses immutable saved bytes and intent; an uncertain PUT is finalized for server verification, never uploaded twice. Sessions and signed URLs are not returned or persisted. Private execution is unavailable. Host request history may contain the supplied verification code.";
|
|
105514
105608
|
const handler = (action) => async (value) => {
|
|
@@ -106154,7 +106248,7 @@ __export(exports_runtime, {
|
|
|
106154
106248
|
});
|
|
106155
106249
|
import { createHash as createHash25, randomUUID as randomUUID9 } from "crypto";
|
|
106156
106250
|
import { lstatSync as lstatSync27, mkdirSync as mkdirSync23, readFileSync as readFileSync35, realpathSync as realpathSync11, writeFileSync as writeFileSync22 } from "fs";
|
|
106157
|
-
import { basename as basename12, isAbsolute as
|
|
106251
|
+
import { basename as basename12, isAbsolute as isAbsolute22, join as join53 } from "path";
|
|
106158
106252
|
import { createInterface } from "readline";
|
|
106159
106253
|
function registerRuntime(parent) {
|
|
106160
106254
|
parent.command("run").argument("<skill>", "Skill name").argument("[args...]", "Arguments to pass to the skill; use -- to end Skills options").allowUnknownOption(true).passThroughOptions(true).option("--json", "Output result as JSON", false).option("--remote", "Run on the configured server, using its catalog and quote", false).option("--target <target>", "Execution target: local or cloud").option("--secret-bindings <path>", "Reviewed, exact-selection local execution vault bindings (JSON file)").option("--secret-bindings-template", "Print a scoped bindings template without resolving secrets or running the skill", false).option("--input <json>", "Structured cloud execution input").option("--skill-version <version>", "Exact selected skill version").option("--selection-profile <id>", "Selected Skills profile").option("--session <id>", "Pinned Skills session").option("--cached", "Use the explicit verified selected cache", false).option("--yes", "Approve the server's quoted credit cost for this run", false).option("--idempotency-key <key>", "Reuse this key when retrying the same remote submission").option("--file <path>", "Attach a local input file to a remote run (repeatable)", (value, prior) => [...prior, value], []).option("--wait", "Poll remote runs until a terminal status", false).option("--poll-interval-ms <ms>", "Remote polling interval in milliseconds", "1000").option("--poll-timeout-ms <ms>", "Maximum time to wait for a remote run", "300000").description("Run a skill directly").action(async (name, args2, options, command) => {
|
|
@@ -106281,7 +106375,7 @@ Updating ${name}...
|
|
|
106281
106375
|
async function readUpdatedVersion(bunExecutable) {
|
|
106282
106376
|
const output2 = await readUpdateCommand([bunExecutable, "pm", "bin", "-g"]);
|
|
106283
106377
|
const globalBin = output2.replace(/\r?\n$/, "");
|
|
106284
|
-
if (!globalBin || !
|
|
106378
|
+
if (!globalBin || !isAbsolute22(globalBin) || /[\r\n\0]/.test(globalBin))
|
|
106285
106379
|
throw new Error("Update bin discovery failed");
|
|
106286
106380
|
const installed = Bun.which("skills", { PATH: globalBin, cwd: globalBin });
|
|
106287
106381
|
const selected = Bun.which("skills");
|
|
@@ -107247,13 +107341,13 @@ import { emitKeypressEvents } from "readline";
|
|
|
107247
107341
|
async function readCode() {
|
|
107248
107342
|
if (process.stdin.isTTY)
|
|
107249
107343
|
throw new NameInputError("Pipe a fresh six-digit verification code when using --code-stdin.");
|
|
107250
|
-
let
|
|
107344
|
+
let text4 = "";
|
|
107251
107345
|
for await (const chunk2 of process.stdin) {
|
|
107252
|
-
|
|
107253
|
-
if (
|
|
107346
|
+
text4 += chunk2.toString();
|
|
107347
|
+
if (text4.length > 32)
|
|
107254
107348
|
throw new NameInputError("Supply only a six-digit verification code on stdin.");
|
|
107255
107349
|
}
|
|
107256
|
-
const code2 =
|
|
107350
|
+
const code2 = text4.trim();
|
|
107257
107351
|
if (!/^\d{6}$/.test(code2))
|
|
107258
107352
|
throw new NameInputError("Supply only a six-digit verification code on stdin.");
|
|
107259
107353
|
return code2;
|
|
@@ -107281,7 +107375,7 @@ function promptCode() {
|
|
|
107281
107375
|
resolve22(answer);
|
|
107282
107376
|
};
|
|
107283
107377
|
const cancel = () => finish(null);
|
|
107284
|
-
const keypress = (
|
|
107378
|
+
const keypress = (text4, key) => {
|
|
107285
107379
|
if (key.ctrl && ["c", "d"].includes(key.name ?? "") || key.name === "escape")
|
|
107286
107380
|
return cancel();
|
|
107287
107381
|
if (key.name === "return" || key.name === "enter") {
|
|
@@ -107297,8 +107391,8 @@ Enter all six digits: `);
|
|
|
107297
107391
|
value = value.slice(0, -1);
|
|
107298
107392
|
output2.write("\b \b");
|
|
107299
107393
|
}
|
|
107300
|
-
} else if (/^[0-9]$/.test(
|
|
107301
|
-
value +=
|
|
107394
|
+
} else if (/^[0-9]$/.test(text4) && value.length < 6) {
|
|
107395
|
+
value += text4;
|
|
107302
107396
|
output2.write("*");
|
|
107303
107397
|
}
|
|
107304
107398
|
};
|
|
@@ -107780,7 +107874,7 @@ import {
|
|
|
107780
107874
|
statSync as statSync19,
|
|
107781
107875
|
writeFileSync as writeFileSync23
|
|
107782
107876
|
} from "fs";
|
|
107783
|
-
import { dirname as dirname29, isAbsolute as
|
|
107877
|
+
import { dirname as dirname29, isAbsolute as isAbsolute23, relative as relative8, resolve as resolve22, sep as sep10 } from "path";
|
|
107784
107878
|
function validateStationId(stationId) {
|
|
107785
107879
|
if (!/^[a-z0-9-]+$/.test(stationId)) {
|
|
107786
107880
|
throw new StationSnapshotError("INVALID_STATION", `station id must be a slug, got: ${stationId}`);
|
|
@@ -107886,7 +107980,7 @@ function writeStationSnapshot(options) {
|
|
|
107886
107980
|
for (const plan of plans) {
|
|
107887
107981
|
const destination = resolve22(repoRoot, plan.destination);
|
|
107888
107982
|
const destinationRelative = relative8(repoRoot, destination);
|
|
107889
|
-
if (destinationRelative.startsWith("..") || destinationRelative.startsWith(sep10) ||
|
|
107983
|
+
if (destinationRelative.startsWith("..") || destinationRelative.startsWith(sep10) || isAbsolute23(destinationRelative)) {
|
|
107890
107984
|
throw new StationSnapshotError("DESTINATION_ESCAPE", `destination escapes repo root: ${plan.destination}`);
|
|
107891
107985
|
}
|
|
107892
107986
|
let existingDigest = null;
|
|
@@ -108361,10 +108455,10 @@ var init_create_sync_config = __esm(() => {
|
|
|
108361
108455
|
// src/lib/codex-hook-rpc.ts
|
|
108362
108456
|
import { execFile, spawn as spawn3 } from "child_process";
|
|
108363
108457
|
import { realpathSync as realpathSync12, statSync as statSync20 } from "fs";
|
|
108364
|
-
import { isAbsolute as
|
|
108458
|
+
import { isAbsolute as isAbsolute24 } from "path";
|
|
108365
108459
|
import { promisify } from "util";
|
|
108366
108460
|
async function connectCodexHookRpc(options) {
|
|
108367
|
-
const found =
|
|
108461
|
+
const found = isAbsolute24(options.command) ? options.command : Bun.which(options.command, { PATH: process.env.PATH });
|
|
108368
108462
|
if (!found)
|
|
108369
108463
|
throw new Error("CODEX_HOOK_TRUST_NATIVE_UNAVAILABLE: install Codex or pass --codex-command");
|
|
108370
108464
|
const binary = realpathSync12(found), stat3 = statSync20(binary);
|
|
@@ -108500,10 +108594,10 @@ var init_codex_hook_rpc = __esm(() => {
|
|
|
108500
108594
|
|
|
108501
108595
|
// src/lib/codex-hook-trust-identity.ts
|
|
108502
108596
|
import { realpathSync as realpathSync13 } from "fs";
|
|
108503
|
-
import { dirname as dirname30, isAbsolute as
|
|
108504
|
-
import { isDeepStrictEqual as
|
|
108597
|
+
import { dirname as dirname30, isAbsolute as isAbsolute25, join as join56 } from "path";
|
|
108598
|
+
import { isDeepStrictEqual as isDeepStrictEqual8 } from "util";
|
|
108505
108599
|
function inspectRecordedSkillsCli(command, expected) {
|
|
108506
|
-
need4(
|
|
108600
|
+
need4(isAbsolute25(command) && !command.includes("\x00"), "RECONCILE_RECORDED_COMMAND_REQUIRED");
|
|
108507
108601
|
const resolved = realpathSync13(command);
|
|
108508
108602
|
const cli = snapshot(resolved, false, { readOnlyPackage: true });
|
|
108509
108603
|
const manifest = snapshot(join56(dirname30(dirname30(resolved)), "package.json"), false, { readOnlyPackage: true });
|
|
@@ -108511,7 +108605,7 @@ function inspectRecordedSkillsCli(command, expected) {
|
|
|
108511
108605
|
need4(pkg.name === "@hasna/skills" && /^\d+\.\d+\.\d+$/.test(pkg.version) && pkg.bin?.skills === "bin/index.js" && resolved === join56(dirname30(manifest.file), "bin/index.js"), "SKILLS_PACKAGE_MISMATCH");
|
|
108512
108606
|
need4((cli.stat.mode & 0o100n) !== 0n, "SKILLS_COMMAND_NOT_EXECUTABLE");
|
|
108513
108607
|
const receipt = { path: resolved, version: pkg.version, sha256: cli.sha256, manifestSha256: manifest.sha256 };
|
|
108514
|
-
need4(
|
|
108608
|
+
need4(isDeepStrictEqual8(receipt, expected), "RECONCILE_SKILLS_BINDING_CHANGED");
|
|
108515
108609
|
return { receipt, recheck() {
|
|
108516
108610
|
need4(realpathSync13(command) === resolved, "SKILLS_COMMAND_CHANGED");
|
|
108517
108611
|
unchanged2(cli);
|
|
@@ -108522,7 +108616,7 @@ function bindSkillsCli(command, reviewed) {
|
|
|
108522
108616
|
const normal = Bun.which("skills", { PATH: process.env.PATH });
|
|
108523
108617
|
need4(normal, "SKILLS_COMMAND_UNAVAILABLE");
|
|
108524
108618
|
const resolved = realpathSync13(normal);
|
|
108525
|
-
const bound =
|
|
108619
|
+
const bound = isAbsolute25(command) ? command : command === "skills" ? normal : undefined;
|
|
108526
108620
|
need4(bound && realpathSync13(bound) === resolved, "SKILLS_COMMAND_MISMATCH");
|
|
108527
108621
|
const entrypoint = reviewed?.path ?? process.argv[1];
|
|
108528
108622
|
need4(entrypoint && realpathSync13(entrypoint) === resolved, "SKILLS_ENTRYPOINT_MISMATCH");
|
|
@@ -108547,19 +108641,19 @@ var init_codex_hook_trust_identity = __esm(() => {
|
|
|
108547
108641
|
});
|
|
108548
108642
|
|
|
108549
108643
|
// src/lib/codex-hook-policy-recovery.ts
|
|
108550
|
-
import { isDeepStrictEqual as
|
|
108644
|
+
import { isDeepStrictEqual as isDeepStrictEqual9 } from "util";
|
|
108551
108645
|
function reviewedClaudeDiscoveryChange(beforeText, currentText, options) {
|
|
108552
108646
|
need4(typeof options.reason === "string" && options.reason.trim().length > 0 && options.reason.length <= 512 && !/[\x00-\x1f\x7f]/.test(options.reason), "RECONCILE_RECOVERY_REASON_REQUIRED");
|
|
108553
108647
|
need4(options.reviewedPlanDigest === undefined || /^[a-f0-9]{64}$/.test(options.reviewedPlanDigest), "RECONCILE_RECOVERY_PLAN_CHANGED");
|
|
108554
108648
|
const before2 = parseManagedSkillPolicy(beforeText), current = parseManagedSkillPolicy(currentText);
|
|
108555
108649
|
const oldDiscovery = before2.bridge?.discovery?.claude, newDiscovery = current.bridge?.discovery?.claude;
|
|
108556
108650
|
need4(oldDiscovery?.agent === "claude" && newDiscovery?.agent === "claude" && oldDiscovery.method === "reviewed" && newDiscovery.method === "reviewed", "RECONCILE_POLICY_CHANGED");
|
|
108557
|
-
const changes = ["roots", "sources"].filter((key) => !
|
|
108651
|
+
const changes = ["roots", "sources"].filter((key) => !isDeepStrictEqual9(oldDiscovery[key], newDiscovery[key])).map((key) => ({ path: `bridge.discovery.claude.${key}`, before: oldDiscovery[key], after: newDiscovery[key] }));
|
|
108558
108652
|
need4(changes.length > 0, "RECONCILE_POLICY_CHANGED");
|
|
108559
108653
|
const compared = structuredClone(current);
|
|
108560
108654
|
compared.bridge.discovery.claude.roots = oldDiscovery.roots;
|
|
108561
108655
|
compared.bridge.discovery.claude.sources = oldDiscovery.sources;
|
|
108562
|
-
need4(
|
|
108656
|
+
need4(isDeepStrictEqual9(before2, compared), "RECONCILE_POLICY_CHANGED");
|
|
108563
108657
|
verifyAgentDiscovery(newDiscovery);
|
|
108564
108658
|
return { reason: options.reason, changes };
|
|
108565
108659
|
}
|
|
@@ -108569,69 +108663,6 @@ var init_codex_hook_policy_recovery = __esm(() => {
|
|
|
108569
108663
|
init_agent_discovery();
|
|
108570
108664
|
});
|
|
108571
108665
|
|
|
108572
|
-
// src/lib/codex-hook-additions-review.ts
|
|
108573
|
-
import { isAbsolute as isAbsolute25 } from "path";
|
|
108574
|
-
import { isDeepStrictEqual as isDeepStrictEqual9 } from "util";
|
|
108575
|
-
function exactKeys3(value, keys3) {
|
|
108576
|
-
need4(value && typeof value === "object" && !Array.isArray(value) && isDeepStrictEqual9(Object.keys(value).sort(), [...keys3].sort()), "RECONCILE_ADDITIONS_REVIEW_SCHEMA");
|
|
108577
|
-
}
|
|
108578
|
-
function reviewNativeHookAdditions(options) {
|
|
108579
|
-
need4(isAbsolute25(options.path), "RECONCILE_ADDITIONS_REVIEW_PATH");
|
|
108580
|
-
const reviewFile = snapshot(options.path, true), review = JSON.parse(reviewFile.text);
|
|
108581
|
-
exactKeys3(review, ["version", "kind", "reason", "producerEvidence", "journalIntentSha256", "policySha256", "configCurrentSha256", "hooksCurrentSha256", "producerBefore", "additions"]);
|
|
108582
|
-
need4(review.version === 1 && review.kind === "native-hook-additions" && text3(review.reason) && text3(review.producerEvidence), "RECONCILE_ADDITIONS_REVIEW_SCHEMA");
|
|
108583
|
-
for (const [name, expected] of [["journalIntentSha256", options.intent.sha256], ["policySha256", options.policy.sha256], ["configCurrentSha256", options.configCurrent.sha256], ["hooksCurrentSha256", options.hooksCurrent.sha256]])
|
|
108584
|
-
need4(hash4(review[name]) && review[name] === expected, "RECONCILE_ADDITIONS_REVIEW_CHANGED");
|
|
108585
|
-
exactKeys3(review.producerBefore, ["configPath", "configSha256", "hooksPath", "hooksSha256"]);
|
|
108586
|
-
const before2 = review.producerBefore;
|
|
108587
|
-
need4(isAbsolute25(before2.configPath) && isAbsolute25(before2.hooksPath) && hash4(before2.configSha256) && hash4(before2.hooksSha256), "RECONCILE_ADDITIONS_PRODUCER_PREIMAGE");
|
|
108588
|
-
const producerConfig = snapshot(before2.configPath, true), producerHooks = snapshot(before2.hooksPath, true);
|
|
108589
|
-
need4(producerConfig.sha256 === before2.configSha256 && producerHooks.sha256 === before2.hooksSha256 && producerHooks.sha256 === options.hooksBefore.sha256, "RECONCILE_ADDITIONS_PRODUCER_PREIMAGE");
|
|
108590
|
-
const original = structure2(options.configBefore.text), producer = structure2(producerConfig.text), expectedProducer = structuredClone(original), originalKeys = options.journalHooks.map((hook) => hook.key);
|
|
108591
|
-
expectedProducer.hooks ??= {};
|
|
108592
|
-
expectedProducer.hooks.state ??= {};
|
|
108593
|
-
for (const hook of options.journalHooks)
|
|
108594
|
-
expectedProducer.hooks.state[hook.key] = { ...expectedProducer.hooks.state[hook.key], enabled: true, trusted_hash: hook.currentHash };
|
|
108595
|
-
need4(isDeepStrictEqual9(expectedProducer, producer) && codexTrustReconcileWitness(options.configBefore.text, originalKeys) === codexTrustReconcileWitness(producerConfig.text, originalKeys) && codexTrustUnmanagedSemantic(options.configBefore.text, originalKeys) === codexTrustUnmanagedSemantic(producerConfig.text, originalKeys), "RECONCILE_ADDITIONS_PRODUCER_PREIMAGE");
|
|
108596
|
-
need4(Array.isArray(review.additions) && review.additions.length > 0 && review.additions.length <= 20, "RECONCILE_ADDITIONS_REVIEW_SCHEMA");
|
|
108597
|
-
const expectedHooks = JSON.parse(options.hooksBefore.text), currentHooks = JSON.parse(options.hooksCurrent.text), expectedConfig = structuredClone(producer);
|
|
108598
|
-
need4(expectedHooks.hooks && typeof expectedHooks.hooks === "object" && !Array.isArray(expectedHooks.hooks), "RECONCILE_ADDITIONS_DECLARATIONS");
|
|
108599
|
-
const added = [], seen = new Set, commands = new Set(options.recordedNativeHooks.map((hook) => hook.command));
|
|
108600
|
-
for (const addition of review.additions) {
|
|
108601
|
-
exactKeys3(addition, ["event", "nativeHook"]);
|
|
108602
|
-
need4(Object.hasOwn(events, addition.event), "RECONCILE_ADDITIONS_DECLARATIONS");
|
|
108603
|
-
const { event, nativeHook: hook } = addition;
|
|
108604
|
-
exactKeys3(hook, nativeKeys);
|
|
108605
|
-
const groups = expectedHooks.hooks[event] ?? [];
|
|
108606
|
-
need4(Array.isArray(groups), "RECONCILE_ADDITIONS_DECLARATIONS");
|
|
108607
|
-
const key = `${options.nativeHooksPath}:${events[event][1]}:${groups.length}:0`;
|
|
108608
|
-
need4(hook.key === key && !seen.has(key) && !options.recordedNativeHooks.some((originalHook) => originalHook.key === key) && !Object.hasOwn(expectedConfig.hooks.state, key), "RECONCILE_ADDITIONS_IDENTITY");
|
|
108609
|
-
need4(hook.eventName === events[event][0] && hook.handlerType === "command" && text3(hook.command, 16384) && !commands.has(hook.command) && Number.isInteger(hook.timeoutSec) && hook.timeoutSec > 0 && hook.timeoutSec <= 60 && hook.matcher === null && hook.async === false && hook.statusMessage === null && hook.additionalContextLimit === null && hook.sourcePath === options.nativeHooksPath && hook.source === "user" && hook.pluginId === null && hook.isManaged === false && /^sha256:[a-f0-9]{64}$/.test(hook.currentHash) && hook.enabled === true && hook.trustStatus === "trusted", "RECONCILE_ADDITIONS_IDENTITY");
|
|
108610
|
-
seen.add(key);
|
|
108611
|
-
commands.add(hook.command);
|
|
108612
|
-
added.push(hook);
|
|
108613
|
-
expectedHooks.hooks[event] = [...groups, { hooks: [{ type: "command", command: hook.command, timeout: hook.timeoutSec }] }];
|
|
108614
|
-
expectedConfig.hooks.state[key] = { enabled: true, trusted_hash: hook.currentHash };
|
|
108615
|
-
}
|
|
108616
|
-
need4(isDeepStrictEqual9(expectedHooks, currentHooks), "RECONCILE_ADDITIONS_DECLARATIONS");
|
|
108617
|
-
const keys3 = added.map((hook) => hook.key);
|
|
108618
|
-
need4(isDeepStrictEqual9(expectedConfig, structure2(options.configCurrent.text)) && codexTrustReconcileWitness(producerConfig.text, keys3) === codexTrustReconcileWitness(options.configCurrent.text, keys3) && codexTrustUnmanagedSemantic(producerConfig.text, keys3) === codexTrustUnmanagedSemantic(options.configCurrent.text, keys3), "RECONCILE_ADDITIONS_CONFIG");
|
|
108619
|
-
const recheck = () => {
|
|
108620
|
-
unchanged2(reviewFile);
|
|
108621
|
-
unchanged2(producerConfig);
|
|
108622
|
-
unchanged2(producerHooks);
|
|
108623
|
-
};
|
|
108624
|
-
recheck();
|
|
108625
|
-
return { hooks: added, recheck, receipt: { reviewPath: reviewFile.file, reviewSha256: reviewFile.sha256, reason: review.reason, producerEvidence: review.producerEvidence, producerBefore: { configPath: producerConfig.file, configSha256: producerConfig.sha256, hooksPath: producerHooks.file, hooksSha256: producerHooks.sha256 }, additions: added } };
|
|
108626
|
-
}
|
|
108627
|
-
var events, hash4 = (value) => typeof value === "string" && /^[a-f0-9]{64}$/.test(value), text3 = (value, max2 = 2048) => typeof value === "string" && value.trim().length > 0 && value.length <= max2 && !/[\0\r\n]/.test(value), structure2 = (value) => JSON.parse(JSON.stringify(Bun.TOML.parse(value))), nativeKeys;
|
|
108628
|
-
var init_codex_hook_additions_review = __esm(() => {
|
|
108629
|
-
init_codex_hook_trust_files();
|
|
108630
|
-
init_codex_hook_trust_layout();
|
|
108631
|
-
events = { UserPromptSubmit: ["userPromptSubmit", "user_prompt_submit"], SessionStart: ["sessionStart", "session_start"], SubagentStart: ["subagentStart", "subagent_start"] };
|
|
108632
|
-
nativeKeys = ["key", "eventName", "handlerType", "command", "matcher", "timeoutSec", "async", "statusMessage", "additionalContextLimit", "sourcePath", "source", "pluginId", "isManaged", "currentHash", "enabled", "trustStatus"];
|
|
108633
|
-
});
|
|
108634
|
-
|
|
108635
108666
|
// src/lib/agent-codex-trust.ts
|
|
108636
108667
|
import { lstatSync as lstatSync29, mkdirSync as mkdirSync25, readdirSync as readdirSync20, readFileSync as readFileSync37, realpathSync as realpathSync14, statSync as statSync21 } from "fs";
|
|
108637
108668
|
import { createHash as createHash27, randomUUID as randomUUID10 } from "crypto";
|
|
@@ -108718,8 +108749,11 @@ async function reconcileCodexNativeHooks(options, connect = connectCodexHookRpc)
|
|
|
108718
108749
|
const before2 = structure3(configBefore.text), current = structure3(currentConfig.text), expectedConfig = structuredClone(before2);
|
|
108719
108750
|
expectedConfig.hooks ??= {};
|
|
108720
108751
|
expectedConfig.hooks.state ??= {};
|
|
108721
|
-
for (const hook of
|
|
108752
|
+
for (const hook of intent.hooks)
|
|
108722
108753
|
expectedConfig.hooks.state[hook.key] = { ...expectedConfig.hooks.state[hook.key], enabled: true, trusted_hash: hook.currentHash };
|
|
108754
|
+
if (additions)
|
|
108755
|
+
for (const { key, state } of readReviewedAdditionTrustStates(additions.trustProof, configBefore, currentConfig, intent.hooks))
|
|
108756
|
+
expectedConfig.hooks.state[key] = { ...state };
|
|
108723
108757
|
if (supersededBinding) {
|
|
108724
108758
|
for (const hook of intent.hooks) {
|
|
108725
108759
|
const state = current.hooks?.state?.[hook.key];
|
|
@@ -108727,7 +108761,7 @@ async function reconcileCodexNativeHooks(options, connect = connectCodexHookRpc)
|
|
|
108727
108761
|
}
|
|
108728
108762
|
} else
|
|
108729
108763
|
need4(isDeepStrictEqual10(expectedConfig, current), "RECONCILE_CONFIG_DRIFT");
|
|
108730
|
-
const configDiscoveryRecovery = recovery && binding.discovery?.codex ? createCodexHookDiscoveryRecovery(binding.discovery.codex, configBefore, currentConfig,
|
|
108764
|
+
const configDiscoveryRecovery = recovery && binding.discovery?.codex ? createCodexHookDiscoveryRecovery(binding.discovery.codex, configBefore, currentConfig, intent.hooks, additions?.trustProof) : undefined;
|
|
108731
108765
|
assertManagedAgentBridge("codex", { home, dataDir: dataDir3, projectDir: home, codexDiscoveryRecovery: configDiscoveryRecovery });
|
|
108732
108766
|
const recoveryCli = recovery ? bindSkillsCli("skills", options.reviewedSkillsCli) : undefined;
|
|
108733
108767
|
if (recoveryCli)
|