@hasna/skills 0.9.3 → 0.9.4

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 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.3",
36871
+ version: "0.9.4",
36872
36872
  description: "Skills library for AI coding agents",
36873
36873
  type: "module",
36874
36874
  bin: {
@@ -108101,7 +108101,7 @@ function codexTrustTextWitness(text3, keys3) {
108101
108101
  let result2 = text3;
108102
108102
  for (const span of replacements2.reverse())
108103
108103
  result2 = result2.slice(0, span.start) + span.comments + result2.slice(span.end);
108104
- return result2.split(/\r?\n/).filter((line) => line.trim()).join(`
108104
+ return canonicalizeTableOrder(result2).split(/\r?\n/).filter((line) => line.trim()).join(`
108105
108105
  `);
108106
108106
  }
108107
108107
  var fail4 = () => new Error('CODEX_HOOK_TRUST_UNSUPPORTED_LAYOUT: preserve and convert hook trust to ordinary [hooks.state."<key>"] tables before enrollment'), prune = (value) => {
@@ -108110,6 +108110,25 @@ var fail4 = () => new Error('CODEX_HOOK_TRUST_UNSUPPORTED_LAYOUT: preserve and c
108110
108110
  if (value.hooks && !Object.keys(value.hooks).length)
108111
108111
  delete value.hooks;
108112
108112
  return value;
108113
+ }, canonicalizeTableOrder = (text3) => {
108114
+ const headers = [...text3.matchAll(/^[ \t]*(\[\[?[^\r\n]+\]\]?)[ \t]*(#[^\r\n]*)?(?:\r?\n|$)/gm)];
108115
+ if (!headers.length)
108116
+ return text3;
108117
+ const keys3 = headers.map((header) => header[1].trim());
108118
+ if (keys3.some((key) => key.startsWith("[[") || keys3.filter((other) => other === key).length > 1))
108119
+ return text3;
108120
+ const plain = keys3.map((key) => key.slice(1, -1).trim());
108121
+ if (plain.some((key, index) => plain.some((other, otherIndex) => index !== otherIndex && (other.startsWith(`${key}.`) || key.startsWith(`${other}.`)))))
108122
+ return text3;
108123
+ const first = headers[0].index;
108124
+ const prefix = text3.slice(0, first);
108125
+ const blocks = headers.map((header, index) => ({
108126
+ key: header[1],
108127
+ order: index,
108128
+ text: text3.slice(header.index, headers[index + 1]?.index ?? text3.length)
108129
+ }));
108130
+ blocks.sort((a, b) => a.key.localeCompare(b.key) || a.order - b.order);
108131
+ return prefix + blocks.map((block) => block.text).join("");
108113
108132
  };
108114
108133
  var init_codex_hook_trust_layout = () => {};
108115
108134
 
@@ -108209,6 +108228,101 @@ import { createHash as createHash26, randomUUID as randomUUID10 } from "crypto";
108209
108228
  import { join as join56, resolve as resolve22 } from "path";
108210
108229
  import { homedir as homedir11 } from "os";
108211
108230
  import { isDeepStrictEqual as isDeepStrictEqual6 } from "util";
108231
+ async function reconcileCodexNativeHooks(options, connect = connectCodexHookRpc) {
108232
+ let rpc;
108233
+ try {
108234
+ const home = resolve22(options.home ?? homedir11()), dataDir3 = resolve22(options.dataDir ?? getDataDirReadOnly());
108235
+ const parent = resolve22(join56(dataDir3, "native-hook-trust")), journal = resolve22(options.journal);
108236
+ need4(journal.startsWith(parent + "/") && /^[a-f0-9-]{36}$/.test(journal.slice(parent.length + 1)), "RECONCILE_JOURNAL_PATH");
108237
+ const dir = lstatSync28(journal, { throwIfNoEntry: false });
108238
+ need4(!!dir && dir.isDirectory() && !dir.isSymbolicLink() && dir.uid === process.getuid() && (dir.mode & 511) === 448, "UNSAFE_JOURNAL");
108239
+ need4(!lstatSync28(join56(journal, "receipt.json"), { throwIfNoEntry: false }), "RECONCILE_ALREADY_COMPLETE");
108240
+ need4(lstatSync28(join56(journal, "stopped.json"), { throwIfNoEntry: false })?.isFile(), "RECONCILE_JOURNAL_INCOMPLETE");
108241
+ const stoppedFile = snapshot(join56(journal, "stopped.json"), true);
108242
+ const intentFile = snapshot(join56(journal, "intent.json"), true), intent = JSON.parse(intentFile.text);
108243
+ const configBefore = snapshot(join56(journal, "config.before.toml"), true), hooksBefore = snapshot(join56(journal, "hooks.before.json"), true), policyBefore = snapshot(join56(journal, "policy.before.json"), true);
108244
+ const legacyIntent = intent.home === undefined && intent.configSha256 === undefined && intent.configVersion === undefined && intent.declarations === undefined && intent.admitted === undefined && intent.nativeHooks === undefined;
108245
+ need4(intent.version === 1 && /^[a-f0-9]{64}$/.test(intent.planDigest) && typeof intent.configPath === "string" && /^[a-f0-9]{64}$/.test(intent.policySha256) && /^[a-f0-9]{64}$/.test(intent.hooksSha256) && Array.isArray(intent.hooks) && intent.hooks.length > 0 && intent.hooks.length <= 100 && (legacyIntent || typeof intent.home === "string" && intent.home === home && /^[a-f0-9]{64}$/.test(intent.configSha256) && typeof intent.configVersion === "string" && Array.isArray(intent.declarations) && Array.isArray(intent.admitted) && Array.isArray(intent.nativeHooks)), "RECONCILE_INTENT_INVALID");
108246
+ const declarations = intent.declarations ?? intent.hooks.map((hook) => ({ event: hook.event, key: `${join56(home, ".codex/hooks.json")}${hook.key.slice(hook.key.indexOf(".codex/hooks.json") + ".codex/hooks.json".length)}`, command: hook.command }));
108247
+ const admitted = intent.admitted ?? intent.hooks;
108248
+ const configSha256 = intent.configSha256 ?? configBefore.sha256, configVersion = intent.configVersion ?? intent.expectedVersion;
108249
+ const digestInput = { version: 1, home: intent.home ?? home, configPath: intent.configPath, configSha256, configVersion, policySha256: intent.policySha256, hooksSha256: intent.hooksSha256, skillsCli: intent.skillsCli, nativeVersion: intent.nativeVersion, declarations, admitted };
108250
+ need4(makePlanDigest(digestInput) === intent.planDigest, "RECONCILE_PLAN_CHANGED");
108251
+ need4(isDeepStrictEqual6(intent.hooks, admitted.filter((hook) => !hook.enabled || hook.trustStatus !== "trusted")), "RECONCILE_INTENT_HOOKS_CHANGED");
108252
+ need4(configBefore.sha256 === intent.beforeSha256 && hooksBefore.sha256 === intent.hooksSha256 && policyBefore.sha256 === intent.policySha256, "RECONCILE_JOURNAL_CHANGED");
108253
+ const currentConfig = snapshot(intent.configPath, true);
108254
+ need4(codexTrustTextWitness(configBefore.text, intent.hooks.map((h) => h.key)) === codexTrustTextWitness(currentConfig.text, intent.hooks.map((h) => h.key)), "RECONCILE_UNRELATED_CONFIG_CHANGED");
108255
+ const before2 = structure(configBefore.text), current = structure(currentConfig.text), expectedConfig = structuredClone(before2);
108256
+ expectedConfig.hooks ??= {};
108257
+ expectedConfig.hooks.state ??= {};
108258
+ for (const hook of intent.hooks)
108259
+ expectedConfig.hooks.state[hook.key] = { ...expectedConfig.hooks.state[hook.key], enabled: true, trusted_hash: hook.currentHash };
108260
+ need4(isDeepStrictEqual6(expectedConfig, current), "RECONCILE_CONFIG_DRIFT");
108261
+ const policyCurrent = snapshot(join56(dataDir3, "agent-policy.json"), true);
108262
+ need4(policyCurrent.sha256 === policyBefore.sha256, "RECONCILE_POLICY_CHANGED");
108263
+ const policy = parseManagedSkillPolicy(policyBefore.text), binding = policy.bridge;
108264
+ assertManagedAgentBridge("codex", { home, dataDir: dataDir3, projectDir: home });
108265
+ const skillsCli = bindSkillsCli(binding.commands.codex, options.reviewedSkillsCli);
108266
+ need4(isDeepStrictEqual6(skillsCli.receipt, intent.skillsCli), "RECONCILE_SKILLS_BINDING_CHANGED");
108267
+ const alias = binding.rootAliases?.find((item) => item.agent === "codex"), codexHome = alias?.target ?? join56(home, ".codex"), hooksPath = join56(codexHome, "hooks.json");
108268
+ need4(resolve22(intent.configPath) === resolve22(join56(codexHome, "config.toml")), "RECONCILE_CONFIG_PATH_CHANGED");
108269
+ const hooksCurrent = snapshot(hooksPath);
108270
+ need4(hooksCurrent.sha256 === intent.hooksSha256 || hooksCurrent.sha256 === hooksBefore.sha256, "RECONCILE_HOOKS_CHANGED");
108271
+ rpc = await connect({ command: options.codexCommand ?? "codex", home, codexHome });
108272
+ need4(rpc.version === intent.nativeVersion, "RECONCILE_NATIVE_VERSION_CHANGED");
108273
+ const discovered = await rpc.request("hooks/list", { cwds: [home] });
108274
+ need4(Array.isArray(discovered?.data) && discovered.data.length === 1 && discovered.data[0].cwd === home && !discovered.data[0].errors?.length && !discovered.data[0].warnings?.length, "RECONCILE_NATIVE_DISCOVERY_REFUSED");
108275
+ const nativeHooks = discovered.data[0].hooks;
108276
+ const recordedNativeHooks = intent.nativeHooks;
108277
+ if (recordedNativeHooks)
108278
+ need4(nativeHooks.length === recordedNativeHooks.length, "RECONCILE_NATIVE_HOOK_LIST_CHANGED");
108279
+ const plannedKeys = new Set(intent.hooks.map((hook) => hook.key));
108280
+ for (const expected of recordedNativeHooks ?? []) {
108281
+ const matches2 = nativeHooks.filter((hook) => hook.key === expected.key);
108282
+ need4(matches2.length === 1, "RECONCILE_NATIVE_HOOK_LIST_CHANGED");
108283
+ const actual = safeNativeHook(matches2[0]);
108284
+ const stable = (hook) => {
108285
+ const { enabled, trustStatus, ...identity4 } = hook;
108286
+ return identity4;
108287
+ };
108288
+ need4(isDeepStrictEqual6(stable(actual), stable(expected)), "RECONCILE_NATIVE_IDENTITY_CHANGED");
108289
+ if (!plannedKeys.has(expected.key))
108290
+ need4(isDeepStrictEqual6(actual, expected), "RECONCILE_UNRELATED_HOOK_CHANGED");
108291
+ }
108292
+ for (const wanted of intent.hooks) {
108293
+ const matches2 = nativeHooks.filter((h2) => h2.key === wanted.key || h2.key === wanted.key.replace(join56(home, ".codex/hooks.json"), hooksPath));
108294
+ need4(matches2.length === 1, "RECONCILE_NATIVE_IDENTITY_CHANGED");
108295
+ const h = matches2[0];
108296
+ need4(h.enabled === true && h.trustStatus === "trusted" && h.currentHash === wanted.currentHash, "RECONCILE_NATIVE_STATE_INCOMPLETE");
108297
+ }
108298
+ const config2 = await rpc.request("config/read", { includeLayers: true, cwd: home });
108299
+ const layers = config2?.layers?.filter((layer) => layer.name?.type === "user" && layer.name.file === intent.configPath && !layer.name.profile);
108300
+ need4(layers?.length === 1 && !layers[0].disabledReason && isDeepStrictEqual6(layers[0].config, current), "RECONCILE_NATIVE_CONFIG_MISMATCH");
108301
+ const finalDiscovery = await rpc.request("hooks/list", { cwds: [home] });
108302
+ need4(Array.isArray(finalDiscovery?.data) && finalDiscovery.data.length === 1 && finalDiscovery.data[0].cwd === home && !finalDiscovery.data[0].errors?.length && !finalDiscovery.data[0].warnings?.length && (!recordedNativeHooks || isDeepStrictEqual6(finalDiscovery.data[0].hooks.map(safeNativeHook), nativeHooks.map(safeNativeHook))), "RECONCILE_NATIVE_STATE_CHANGED");
108303
+ const finalConfig = await rpc.request("config/read", { includeLayers: true, cwd: home });
108304
+ const finalLayers = finalConfig?.layers?.filter((layer) => layer.name?.type === "user" && layer.name.file === intent.configPath && !layer.name.profile);
108305
+ need4(finalLayers?.length === 1 && isDeepStrictEqual6(finalLayers[0].config, current), "RECONCILE_NATIVE_CONFIG_CHANGED");
108306
+ unchanged2(stoppedFile);
108307
+ unchanged2(intentFile);
108308
+ unchanged2(configBefore);
108309
+ unchanged2(hooksBefore);
108310
+ unchanged2(policyBefore);
108311
+ unchanged2(policyCurrent);
108312
+ unchanged2(hooksCurrent);
108313
+ unchanged2(currentConfig);
108314
+ skillsCli.recheck();
108315
+ assertManagedAgentBridge("codex", { home, dataDir: dataDir3, projectDir: home });
108316
+ const receipt = { version: 1, status: "reconciled", reconciled: true, automaticRollback: false, journal, planDigest: intent.planDigest, nativeVersion: rpc.version, nativeStateVerified: true, nativeExecutionVerified: false, configSha256: currentConfig.sha256, hooksSha256: hooksCurrent.sha256, policySha256: policyBefore.sha256, skillsCli: skillsCli.receipt, nativeInventoryScope: recordedNativeHooks ? "complete" : "declared-managed-hooks-only", unrelatedNativeHooksPreserved: !!recordedNativeHooks, unrelatedSettingsAndCommentsPreserved: true };
108317
+ save2(join56(journal, "receipt.json"), json2(receipt));
108318
+ return receipt;
108319
+ } catch (error61) {
108320
+ const message = error61 instanceof Error && error61.message.startsWith("CODEX_HOOK_TRUST_") ? error61.message : "CODEX_HOOK_TRUST_RECONCILE_REFUSED";
108321
+ throw new Error(message);
108322
+ } finally {
108323
+ await rpc?.close();
108324
+ }
108325
+ }
108212
108326
  async function enrollCodexNativeHooks(options = {}, connect = connectCodexHookRpc) {
108213
108327
  let rpc, journal;
108214
108328
  try {
@@ -108262,7 +108376,8 @@ async function enrollCodexNativeHooks(options = {}, connect = connectCodexHookRp
108262
108376
  unchanged2(configFile);
108263
108377
  };
108264
108378
  checkInputs();
108265
- const planDigest = createHash26("sha256").update(json2({ version: 1, home, configPath, configSha256: configFile.sha256, configVersion: layers[0].version, policySha256: policyFile.sha256, hooksSha256: hooksFile.sha256, skillsCli: skillsCli.receipt, nativeVersion: rpc.version, declarations: expected, admitted })).digest("hex");
108379
+ const digestInput = { version: 1, home, configPath, configSha256: configFile.sha256, configVersion: layers[0].version, policySha256: policyFile.sha256, hooksSha256: hooksFile.sha256, skillsCli: skillsCli.receipt, nativeVersion: rpc.version, declarations: expected, admitted };
108380
+ const planDigest = makePlanDigest(digestInput);
108266
108381
  const baseReceipt = { planDigest, skillsCli: skillsCli.receipt, nativeVersion: rpc.version, ownedNativeProcessId: rpc.processId, agent: "codex", applied: false, planned, nativeEligible: planned.length === 0, transport: "owned-stdio-process", existingSessionsReloaded: false, nativeExecutionVerified: false };
108267
108382
  if (options.apply)
108268
108383
  need4(options.reviewedPlanDigest === planDigest, "PLAN_CHANGED: run the dry-run again and pass its reviewed --plan-digest with --apply");
@@ -108286,7 +108401,7 @@ async function enrollCodexNativeHooks(options = {}, connect = connectCodexHookRp
108286
108401
  save2(join56(journal, "config.before.toml"), configFile.bytes);
108287
108402
  save2(join56(journal, "hooks.before.json"), hooksFile.bytes);
108288
108403
  save2(join56(journal, "policy.before.json"), policyFile.bytes);
108289
- save2(join56(journal, "intent.json"), json2({ version: 1, planDigest, skillsCli: skillsCli.receipt, nativeVersion: rpc.version, configPath, beforeSha256: configFile.sha256, hooksSha256: hooksFile.sha256, policySha256: policyFile.sha256, expectedVersion: layers[0].version, hooks: planned }));
108404
+ save2(join56(journal, "intent.json"), json2({ ...digestInput, planDigest, hooks: planned, nativeHooks: discovered.map(safeNativeHook) }));
108290
108405
  need4(isDeepStrictEqual6(admit(await list2()), admitted), "NATIVE_DISCOVERY_CHANGED");
108291
108406
  checkInputs();
108292
108407
  let result2;
@@ -108328,7 +108443,7 @@ async function enrollCodexNativeHooks(options = {}, connect = connectCodexHookRp
108328
108443
  }
108329
108444
  }
108330
108445
  var json2 = (value) => JSON.stringify(value, null, 2) + `
108331
- `, structure = (text3) => JSON.parse(JSON.stringify(Bun.TOML.parse(text3))), eventNames;
108446
+ `, 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 });
108332
108447
  var init_agent_codex_trust = __esm(() => {
108333
108448
  init_config();
108334
108449
  init_managed_policy();
@@ -108506,7 +108621,7 @@ function registerAgentIntegration(parent) {
108506
108621
  process.exitCode = 1;
108507
108622
  }
108508
108623
  });
108509
- hook.command("trust").requiredOption("--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) => {
108624
+ const trust = hook.command("trust").requiredOption("--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) => {
108510
108625
  try {
108511
108626
  if (options.agent !== "codex")
108512
108627
  throw new Error("Native trust enrollment currently supports --agent codex only");
@@ -108520,6 +108635,20 @@ function registerAgentIntegration(parent) {
108520
108635
  process.exitCode = 1;
108521
108636
  }
108522
108637
  });
108638
+ 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) => {
108639
+ try {
108640
+ if (options.agent !== "codex")
108641
+ throw new Error("Native trust reconciliation currently supports --agent codex only");
108642
+ const result2 = await reconcileCodexNativeHooks({ journal: options.journal, codexCommand: options.codexCommand });
108643
+ if (options.json)
108644
+ await writeCliOutput(JSON.stringify(result2));
108645
+ else
108646
+ await writeCliOutput(`Reconciled native Codex trust journal ${result2.journal}. No native configuration was written.`);
108647
+ } catch (error61) {
108648
+ console.error(error61.message);
108649
+ process.exitCode = 1;
108650
+ }
108651
+ });
108523
108652
  hook.command("user-prompt").requiredOption("--agent <agent>", `Native payload/output adapter: ${INTEGRATION_AGENTS.join(", ")}`).option("--event <event>", "Native lifecycle event supplied by the installed adapter").option("--selection-profile <id>", "Selection profile to load").description("Read native lifecycle JSON on stdin and return selected context").action(async (options) => {
108524
108653
  const deadline = Date.now() + 12000;
108525
108654
  let event = options.agent === "hermes" && options.event === "pre_tool_call" ? "pre_tool_call" : "UserPromptSubmit";
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.3",
20022
+ version: "0.9.4",
20023
20023
  description: "Skills library for AI coding agents",
20024
20024
  type: "module",
20025
20025
  bin: {
package/bin/migrate.js CHANGED
@@ -7,7 +7,7 @@ import { join as join5 } from "path";
7
7
  // package.json
8
8
  var package_default = {
9
9
  name: "@hasna/skills",
10
- version: "0.9.3",
10
+ version: "0.9.4",
11
11
  description: "Skills library for AI coding agents",
12
12
  type: "module",
13
13
  bin: {
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.3",
24125
+ version: "0.9.4",
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.3",
24128
+ version: "0.9.4",
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.3",
11451
+ version: "0.9.4",
11452
11452
  description: "Skills library for AI coding agents",
11453
11453
  type: "module",
11454
11454
  bin: {
@@ -8,7 +8,41 @@ export interface CodexNativeHookTrustOptions {
8
8
  reviewedPlanDigest?: string;
9
9
  reviewedSkillsCli?: ReviewedSkillsCli;
10
10
  }
11
+ export interface CodexNativeHookReconcileOptions {
12
+ home?: string;
13
+ dataDir?: string;
14
+ codexCommand?: string;
15
+ journal: string;
16
+ reviewedSkillsCli?: ReviewedSkillsCli;
17
+ }
11
18
  type Connect = typeof connectCodexHookRpc;
19
+ /** Resolve an interrupted native write only after the native consumer and every
20
+ * captured pre-write input agree. This never writes Codex state; it records a
21
+ * receipt for an already-effective operation so the ordinary apply guard can
22
+ * stop refusing the same journal. */
23
+ export declare function reconcileCodexNativeHooks(options: CodexNativeHookReconcileOptions, connect?: Connect): Promise<{
24
+ version: number;
25
+ status: string;
26
+ reconciled: boolean;
27
+ automaticRollback: boolean;
28
+ journal: string;
29
+ planDigest: any;
30
+ nativeVersion: string;
31
+ nativeStateVerified: boolean;
32
+ nativeExecutionVerified: boolean;
33
+ configSha256: string;
34
+ hooksSha256: string;
35
+ policySha256: string;
36
+ skillsCli: {
37
+ path: string;
38
+ version: string;
39
+ sha256: string;
40
+ manifestSha256: string;
41
+ };
42
+ nativeInventoryScope: string;
43
+ unrelatedNativeHooksPreserved: boolean;
44
+ unrelatedSettingsAndCommentsPreserved: boolean;
45
+ }>;
12
46
  /** Deliberately separate from filesystem hook installation: native trust is an
13
47
  * explicit authorization of exact owned commands, never a broad trust bypass. */
14
48
  export declare function enrollCodexNativeHooks(options?: CodexNativeHookTrustOptions, connect?: Connect): Promise<{
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.3",
32376
+ version: "0.9.4",
32377
32377
  description: "Skills library for AI coding agents",
32378
32378
  type: "module",
32379
32379
  bin: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hasna/skills",
3
- "version": "0.9.3",
3
+ "version": "0.9.4",
4
4
  "description": "Skills library for AI coding agents",
5
5
  "type": "module",
6
6
  "bin": {