rulesync 18.0.0 → 20.0.0

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.
@@ -5229,8 +5229,8 @@ const CONTINUE_TO_CANONICAL_EVENT_NAMES = Object.fromEntries(Object.entries(CANO
5229
5229
  /**
5230
5230
  * Hook events supported by Hermes Agent's native Shell Hooks system.
5231
5231
  *
5232
- * Hermes validates hook events against a fixed `VALID_HOOKS` set — 39 entries as
5233
- * of v0.21.3 (`v2026.9.14`); see {@link HERMESAGENT_NATIVE_HOOK_EVENTS} for the
5232
+ * Hermes validates hook events against a fixed `VALID_HOOKS` set — 41 entries as
5233
+ * of v0.21.5 (`v2026.9.24`); see {@link HERMESAGENT_NATIVE_HOOK_EVENTS} for the
5234
5234
  * full list. Only the events with a clean 1:1 canonical equivalent are mapped
5235
5235
  * here. All other native events round-trip through `hermesagent.hooks`.
5236
5236
  * @see https://github.com/NousResearch/hermes-agent/blob/main/website/docs/user-guide/features/hooks.md
@@ -5254,13 +5254,14 @@ const HERMESAGENT_HOOK_EVENTS = [
5254
5254
  * observers, `gateway_platform_event` and `transform_api_error_classification`.
5255
5255
  * Shell hooks are gated on the same set.
5256
5256
  *
5257
- * Verified against the tag `v2026.9.14` (v0.21.3): `VALID_HOOKS` holds 39
5257
+ * Verified against the tag `v2026.9.24` (v0.21.5): `VALID_HOOKS` holds 41
5258
5258
  * entries, grown from 23 at `v2026.8.3` (v0.20.0) and 37 at `v2026.8.16`
5259
- * (v0.20.2) — v0.21 added `agent_loop_stopped` and `on_room_member_activity`.
5260
- * This list holds 38 of them — see
5259
+ * (v0.20.2) — v0.21 added `agent_loop_stopped` and `on_room_member_activity`,
5260
+ * and v0.21.5 added `pre_auxiliary_call` and `post_auxiliary_call`.
5261
+ * This list holds 40 of them — see
5261
5262
  * {@link HERMESAGENT_SHELL_UNSUPPORTED_HOOK_EVENTS} for the exclusion.
5262
5263
  *
5263
- * @see https://github.com/NousResearch/hermes-agent/blob/v2026.9.14/hermes_cli/plugins.py
5264
+ * @see https://github.com/NousResearch/hermes-agent/blob/v2026.9.24/hermes_cli/plugins.py
5264
5265
  */
5265
5266
  const HERMESAGENT_NATIVE_HOOK_EVENTS = [
5266
5267
  "pre_tool_call",
@@ -5278,6 +5279,8 @@ const HERMESAGENT_NATIVE_HOOK_EVENTS = [
5278
5279
  "pre_api_request",
5279
5280
  "post_api_request",
5280
5281
  "api_request_error",
5282
+ "pre_auxiliary_call",
5283
+ "post_auxiliary_call",
5281
5284
  "on_session_start",
5282
5285
  "on_session_end",
5283
5286
  "on_session_finalize",
@@ -5312,8 +5315,8 @@ const HERMESAGENT_NATIVE_HOOK_EVENTS = [
5312
5315
  * rulesync only ever writes shell hooks, so these are excluded from
5313
5316
  * {@link HERMESAGENT_NATIVE_HOOK_EVENTS} and warned about with their own message.
5314
5317
  *
5315
- * @see https://github.com/NousResearch/hermes-agent/blob/v2026.9.14/hermes_cli/plugins.py — `SHELL_UNSUPPORTED_HOOKS`
5316
- * @see https://github.com/NousResearch/hermes-agent/blob/v2026.9.14/agent/shell_hooks.py — `_parse_hooks_block`
5318
+ * @see https://github.com/NousResearch/hermes-agent/blob/v2026.9.24/hermes_cli/plugins.py — `SHELL_UNSUPPORTED_HOOKS`
5319
+ * @see https://github.com/NousResearch/hermes-agent/blob/v2026.9.24/agent/shell_hooks.py — `_parse_hooks_block`
5317
5320
  */
5318
5321
  const HERMESAGENT_SHELL_UNSUPPORTED_HOOK_EVENTS = ["transform_api_error_classification"];
5319
5322
  /**
@@ -26028,7 +26031,7 @@ function canonicalToHermesHooks({ config, toolOverrideHooks, logger }) {
26028
26031
  for (const [nativeEvent, definitions] of Object.entries(toolOverrideHooks ?? {})) {
26029
26032
  if (HERMESAGENT_CANONICAL_EVENTS.has(nativeEvent)) continue;
26030
26033
  if (HERMESAGENT_SHELL_UNSUPPORTED_EVENTS.has(nativeEvent)) logger?.warn(`Hermes hook event "${nativeEvent}" is Python-plugin-only; Hermes Agent refuses it for shell hooks, so the generated entry will never run.`);
26031
- else if (!HERMESAGENT_NATIVE_EVENTS.has(nativeEvent)) logger?.warn(`Hermes hook event "${nativeEvent}" is not documented by Hermes Agent v0.21.3; preserving it for forward compatibility.`);
26034
+ else if (!HERMESAGENT_NATIVE_EVENTS.has(nativeEvent)) logger?.warn(`Hermes hook event "${nativeEvent}" is not documented by Hermes Agent v0.21.5; preserving it for forward compatibility.`);
26032
26035
  setHermesHookEntries({
26033
26036
  result,
26034
26037
  event: nativeEvent,
@@ -44086,6 +44089,7 @@ var ClinePermissions = class ClinePermissions extends ToolPermissions {
44086
44089
  //#region src/features/permissions/codexcli-permissions.ts
44087
44090
  const RULESYNC_PROFILE_NAME = "rulesync";
44088
44091
  const CODEX_WORKSPACE_ROOTS_KEY = ":workspace_roots";
44092
+ const CODEX_WORKSPACE_ROOT_SUBPATH = ".";
44089
44093
  const CODEX_WORKSPACE_BASELINE = ":workspace";
44090
44094
  const CODEX_READ_ONLY_BASELINE = ":read-only";
44091
44095
  const CODEX_DANGER_FULL_ACCESS_BASELINE = ":danger-full-access";
@@ -44303,10 +44307,19 @@ function convertRulesyncToCodexProfile({ config, logger }) {
44303
44307
  applyDefaultGitWriteRules({
44304
44308
  config,
44305
44309
  filesystem,
44306
- workspaceRootFilesystem
44310
+ workspaceRootFilesystem,
44311
+ logger
44307
44312
  });
44308
44313
  if (Object.keys(workspaceRootFilesystem).length > 0) {
44309
- if (typeof filesystem[CODEX_WORKSPACE_ROOTS_KEY] === "string") logger?.warn(`"${CODEX_WORKSPACE_ROOTS_KEY}" is set as a direct filesystem access rule in the permissions, but it will be overwritten by workspace-root rules. Consider removing the direct "${CODEX_WORKSPACE_ROOTS_KEY}" entry.`);
44314
+ const directWorkspaceRootsAccess = filesystem[CODEX_WORKSPACE_ROOTS_KEY];
44315
+ if (isCodexFilesystemAccess(directWorkspaceRootsAccess)) {
44316
+ mergeIntoWorkspaceRootTable({
44317
+ workspaceRootFilesystem,
44318
+ pattern: CODEX_WORKSPACE_ROOT_SUBPATH,
44319
+ access: directWorkspaceRootsAccess
44320
+ });
44321
+ logger?.warn(`"${CODEX_WORKSPACE_ROOTS_KEY}" is set as a direct filesystem access rule in the permissions alongside workspace-relative rules; it is emitted as the "${CODEX_WORKSPACE_ROOT_SUBPATH}" entry of the "${CODEX_WORKSPACE_ROOTS_KEY}" table.`);
44322
+ }
44310
44323
  if (Object.keys(workspaceRootFilesystem).some((pattern) => pattern.includes("**"))) filesystem.glob_scan_max_depth = CODEX_GLOB_SCAN_MAX_DEPTH;
44311
44324
  filesystem[CODEX_WORKSPACE_ROOTS_KEY] = workspaceRootFilesystem;
44312
44325
  }
@@ -44323,9 +44336,13 @@ function convertRulesyncToCodexProfile({ config, logger }) {
44323
44336
  };
44324
44337
  }
44325
44338
  function addCodexFilesystemRules({ categoryRules, filesystem, workspaceRootFilesystem, logger }) {
44326
- for (const rule of mergeFilesystemCategoryRules({
44339
+ const normalizedCategoryRules = normalizeWorkspaceRelativeCategoryRules({
44327
44340
  categoryRules,
44328
44341
  logger
44342
+ });
44343
+ for (const rule of mergeFilesystemCategoryRules({
44344
+ categoryRules: normalizedCategoryRules,
44345
+ logger
44329
44346
  })) {
44330
44347
  const access = normalizeCodexFilesystemAccess({
44331
44348
  pattern: rule.pattern,
@@ -44345,11 +44362,32 @@ function addCodexFilesystemRules({ categoryRules, filesystem, workspaceRootFiles
44345
44362
  });
44346
44363
  }
44347
44364
  }
44348
- function applyDefaultGitWriteRules({ config, filesystem, workspaceRootFilesystem }) {
44365
+ function applyDefaultGitWriteRules({ config, filesystem, workspaceRootFilesystem, logger }) {
44349
44366
  if (config.codexcli?.git_write_rules === false) return;
44350
44367
  if (config.codexcli?.base_permission_profile === CODEX_READ_ONLY_BASELINE) return;
44351
44368
  if (typeof filesystem[CODEX_WORKSPACE_ROOTS_KEY] === "string") return;
44352
- for (const [pattern, access] of Object.entries(CODEX_GIT_WRITE_RULES)) workspaceRootFilesystem[pattern] ??= access;
44369
+ for (const [pattern, access] of Object.entries(CODEX_GIT_WRITE_RULES)) {
44370
+ if (workspaceRootFilesystem[pattern] !== void 0) continue;
44371
+ if (isRestrictedInWorkspaceRootTable({
44372
+ pattern,
44373
+ table: workspaceRootFilesystem
44374
+ })) {
44375
+ logger?.warn(`Skipping the default Codex CLI "${pattern}" = "${access}" carve-out: ".git" is covered by a broader workspace-relative deny or read-only rule, which the carve-out would reopen. To keep it, author read and edit allows for "${pattern}"; to silence this warning, set codexcli.git_write_rules to false.`);
44376
+ continue;
44377
+ }
44378
+ workspaceRootFilesystem[pattern] = access;
44379
+ }
44380
+ }
44381
+ function isRestrictedInWorkspaceRootTable({ pattern, table }) {
44382
+ const readRules = {};
44383
+ for (const [tablePattern, access] of Object.entries(table)) {
44384
+ if (tablePattern === pattern) continue;
44385
+ readRules[tablePattern] = access === "write" ? "allow" : "deny";
44386
+ }
44387
+ return isCoveredByReadRestriction({
44388
+ pattern,
44389
+ readRules
44390
+ });
44353
44391
  }
44354
44392
  function convertCodexProfileToRulesync({ profile, domainsHadUnknown }) {
44355
44393
  const permission = {};
@@ -44363,7 +44401,10 @@ function convertCodexProfileToRulesync({ profile, domainsHadUnknown }) {
44363
44401
  continue;
44364
44402
  }
44365
44403
  if (isCodexFilesystemRuleTable(access)) for (const [nestedPattern, nestedAccess] of Object.entries(access)) {
44366
- if (pattern === CODEX_WORKSPACE_ROOTS_KEY && CODEX_GIT_WRITE_RULES[nestedPattern] === nestedAccess) continue;
44404
+ if (pattern === CODEX_WORKSPACE_ROOTS_KEY && CODEX_GIT_WRITE_RULES[nestedPattern] === nestedAccess && !isRestrictedInWorkspaceRootTable({
44405
+ pattern: nestedPattern,
44406
+ table: access
44407
+ })) continue;
44367
44408
  addRulesyncFilesystemRule(permission, nestedPattern, nestedAccess);
44368
44409
  }
44369
44410
  }
@@ -44492,9 +44533,59 @@ function addFilesystemRule({ filesystem, workspaceRootFilesystem, pattern, acces
44492
44533
  filesystem[pattern] = access;
44493
44534
  return;
44494
44535
  }
44495
- workspaceRootFilesystem[pattern] = access;
44536
+ mergeIntoWorkspaceRootTable({
44537
+ workspaceRootFilesystem,
44538
+ pattern,
44539
+ access
44540
+ });
44541
+ }
44542
+ const PERMISSION_ACTION_RESTRICTIVENESS = {
44543
+ deny: 2,
44544
+ ask: 1,
44545
+ allow: 0
44546
+ };
44547
+ function normalizeWorkspaceRelativeCategoryRules({ categoryRules, logger }) {
44548
+ const result = {};
44549
+ for (const category of [
44550
+ "read",
44551
+ "edit",
44552
+ "write"
44553
+ ]) {
44554
+ const rules = categoryRules[category];
44555
+ if (rules === void 0) continue;
44556
+ const normalized = {};
44557
+ for (const [pattern, action] of Object.entries(rules)) {
44558
+ const key = pattern.trim() === "" || canBeCodexFilesystemRoot(pattern) ? pattern : toWorkspaceRootSubpath(pattern);
44559
+ if (key === void 0) {
44560
+ logger?.warn(`Skipping Codex CLI ${category} filesystem entry for workspace-relative pattern "${pattern}": Codex rejects a ":workspace_roots" subpath containing a ".." segment or an empty leading segment and would refuse the whole config, so the rule is dropped entirely — even a deny — and the path is NOT protected by the generated profile. Use a normalized relative path instead.`);
44561
+ continue;
44562
+ }
44563
+ const existing = normalized[key];
44564
+ normalized[key] = existing === void 0 || PERMISSION_ACTION_RESTRICTIVENESS[action] > PERMISSION_ACTION_RESTRICTIVENESS[existing] ? action : existing;
44565
+ }
44566
+ result[category] = normalized;
44567
+ }
44568
+ return result;
44569
+ }
44570
+ function toWorkspaceRootSubpath(pattern) {
44571
+ let subpath = pattern;
44572
+ while (subpath.startsWith("./")) subpath = subpath.slice(2);
44573
+ if (subpath === "" || subpath === "**" && subpath !== pattern) return CODEX_WORKSPACE_ROOT_SUBPATH;
44574
+ if (subpath.startsWith("/") || subpath.split(/[\\/]/).some((segment) => segment === "..")) return;
44575
+ return subpath;
44576
+ }
44577
+ function mergeIntoWorkspaceRootTable({ workspaceRootFilesystem, pattern, access }) {
44578
+ const existing = workspaceRootFilesystem[pattern];
44579
+ workspaceRootFilesystem[pattern] = existing === void 0 ? access : moreRestrictiveCodexAccess({
44580
+ a: existing,
44581
+ b: access
44582
+ });
44496
44583
  }
44497
44584
  function normalizeCodexFilesystemAccess({ pattern, access, writeRestriction, logger }) {
44585
+ if (isWindowsDevicePath(pattern) && !canBeCodexFilesystemRoot(pattern)) {
44586
+ logger?.warn(`Skipping Codex CLI ${access} filesystem entry for Windows device path "${pattern}": Codex cannot express it as a workspace-root entry (it is rejected on Windows and matches nothing elsewhere), so the rule is dropped entirely — even a deny — and the path is NOT protected by the generated profile. Use a plain drive path such as "C:\\..." instead.`);
44587
+ return;
44588
+ }
44498
44589
  if ((access === "read" || access === "write") && isWindowsDevicePath(pattern)) {
44499
44590
  if (writeRestriction !== void 0) {
44500
44591
  logger?.warn(`Codex CLI does not support Windows device paths for read/write access: pattern "${pattern}" will be emitted as "deny" because its write-side ${writeRestriction} restriction cannot be represented as read-only access. Use a plain drive path such as "C:\\..." instead.`);
@@ -44535,7 +44626,9 @@ function addRulesyncFilesystemRule(permission, pattern, access) {
44535
44626
  permission.read ??= {};
44536
44627
  permission.read[pattern] = "allow";
44537
44628
  } else {
44629
+ permission.read ??= {};
44538
44630
  permission.edit ??= {};
44631
+ permission.read[pattern] = "allow";
44539
44632
  permission.edit[pattern] = "allow";
44540
44633
  }
44541
44634
  }
@@ -44671,10 +44764,13 @@ function mapWriteAction(action) {
44671
44764
  * - A write-side non-allow → `"read"` (readable but not writable — exactly
44672
44765
  * what Codex's `"read"` level expresses). An `ask` action is approximated
44673
44766
  * this way because Codex has no path-level write approval.
44674
- * - A write-side-only non-allow (no `read` rule for the same pattern) whose
44675
- * path is covered by a broader `read` deny/ask rule (e.g. `X/**` covering
44676
- * `X/id_rsa`, or `:root`) → `"deny"`. Codex resolves the most specific
44677
- * path, so emitting `"read"` there would re-open reads the user denied.
44767
+ * - A write-side-only rule (no `read` rule for the same pattern) whose path
44768
+ * is covered by a broader `read` deny/ask rule (e.g. `X/**` covering
44769
+ * `X/id_rsa`, or `:root`) → `"deny"`, for a write-side `allow` too (with a
44770
+ * warning). Codex resolves the most specific path, so emitting `"read"` or
44771
+ * `"write"` there would re-open reads the user denied. Only the most
44772
+ * specific covering read rule counts: a narrower `read: allow` between the
44773
+ * broad deny and the path keeps the path readable.
44678
44774
  * - A `read` non-allow on the same pattern → `"deny"` regardless of the
44679
44775
  * write side; a contradictory write-side `allow` (unreadable but writable
44680
44776
  * is not expressible in Codex) is warned about.
@@ -44722,10 +44818,11 @@ function mergeFilesystemCategoryRules({ categoryRules, logger }) {
44722
44818
  }
44723
44819
  const writeRestriction = writeAction === "allow" ? void 0 : writeAction;
44724
44820
  const readUnspecified = readAction === void 0;
44725
- if (readUnspecified && writeRestriction !== void 0 && isCoveredByReadRestriction({
44821
+ if (readUnspecified && isCoveredByReadRestriction({
44726
44822
  pattern,
44727
44823
  readRules
44728
44824
  })) {
44825
+ if (writeRestriction === void 0) logger?.warn(`Codex CLI cannot express "writable but not readable": pattern "${pattern}" has a write-side allow but is covered by a broader read deny/ask rule. Emitting "deny".`);
44729
44826
  merged.push({
44730
44827
  pattern,
44731
44828
  access: "deny"
@@ -44742,33 +44839,89 @@ function mergeFilesystemCategoryRules({ categoryRules, logger }) {
44742
44839
  return merged;
44743
44840
  }
44744
44841
  function collapseWriteSideRules(categoryRules) {
44745
- const writeSideRestrictiveness = {
44746
- deny: 2,
44747
- ask: 1,
44748
- allow: 0
44749
- };
44750
44842
  const writeSideRules = {};
44751
44843
  for (const category of ["edit", "write"]) for (const [pattern, action] of Object.entries(categoryRules[category] ?? {})) {
44752
44844
  const existing = writeSideRules[pattern];
44753
- if (existing === void 0 || writeSideRestrictiveness[action] > writeSideRestrictiveness[existing]) writeSideRules[pattern] = action;
44845
+ if (existing === void 0 || PERMISSION_ACTION_RESTRICTIVENESS[action] > PERMISSION_ACTION_RESTRICTIVENESS[existing]) writeSideRules[pattern] = action;
44754
44846
  }
44755
44847
  return writeSideRules;
44756
44848
  }
44757
44849
  function isCoveredByReadRestriction({ pattern, readRules }) {
44758
- const key = stripLeadingDotSlash(pattern);
44759
- return Object.entries(readRules).some(([readPattern, action]) => {
44760
- if (action === "allow" || readPattern === pattern) return false;
44761
- if (readPattern === ":root" || readPattern === "/**") return true;
44762
- if (readPattern === "**") return !canBeCodexFilesystemRoot(pattern);
44763
- const withoutTrailingGlob = readPattern.endsWith("/**") ? readPattern.slice(0, -3) : readPattern;
44764
- if (withoutTrailingGlob.startsWith(":") || hasCodexFilesystemGlob(withoutTrailingGlob)) return false;
44765
- const base = stripTrailingSlash(stripLeadingDotSlash(withoutTrailingGlob));
44766
- if (base === "") return false;
44767
- return key === base || key.startsWith(base.endsWith("/") ? base : `${base}/`);
44768
- });
44850
+ const key = normalizeCoverageKey(pattern);
44851
+ const isWorkspaceRelative = !canBeCodexFilesystemRoot(pattern);
44852
+ const keyHasDotSegment = hasDotPathSegment(pattern);
44853
+ let best;
44854
+ for (const [readPattern, action] of Object.entries(readRules)) {
44855
+ if (readPattern === pattern) continue;
44856
+ const specificity = coverageSpecificity({
44857
+ readPattern,
44858
+ key,
44859
+ isWorkspaceRelative
44860
+ });
44861
+ if (specificity === void 0) continue;
44862
+ const restrictive = action !== "allow";
44863
+ if (!restrictive && isSkippedCodexGrant(readPattern)) continue;
44864
+ if (!restrictive && (keyHasDotSegment || hasDotPathSegment(readPattern))) continue;
44865
+ if (best === void 0 || specificity > best.specificity || specificity === best.specificity && restrictive) best = {
44866
+ specificity,
44867
+ restrictive
44868
+ };
44869
+ }
44870
+ return best?.restrictive ?? false;
44871
+ }
44872
+ function coverageSpecificity({ readPattern, key, isWorkspaceRelative }) {
44873
+ if (readPattern === ":root" || readPattern === "/**") return 0;
44874
+ if (readPattern === CODEX_WORKSPACE_ROOTS_KEY) return isWorkspaceRelative ? 1 : void 0;
44875
+ if (canBeCodexFilesystemRoot(readPattern) === isWorkspaceRelative) return;
44876
+ const normalized = normalizeCoverageKey(readPattern);
44877
+ if (normalized === "**" || normalized === ".") return isWorkspaceRelative ? 1 : void 0;
44878
+ const withoutTrailingGlob = normalized.endsWith("/**") ? normalized.slice(0, -3) : normalized;
44879
+ if (withoutTrailingGlob.startsWith(":") || hasCodexFilesystemGlob(withoutTrailingGlob)) return;
44880
+ const base = stripTrailingSlash(withoutTrailingGlob);
44881
+ if (base === "") return;
44882
+ return key === base || key.startsWith(base.endsWith("/") ? base : `${base}/`) ? 2 + base.length : void 0;
44883
+ }
44884
+ function normalizeCoverageKey(pattern) {
44885
+ const form = toCoverageForm(pattern);
44886
+ return canBeCodexFilesystemRoot(pattern) && !pattern.startsWith(":") ? resolveDotSegments(form) : form;
44887
+ }
44888
+ function resolveDotSegments(path) {
44889
+ const [anchor = "", ...rest] = path.split("/");
44890
+ const stack = [];
44891
+ for (const segment of rest) {
44892
+ if (segment === ".") continue;
44893
+ if (segment === "..") {
44894
+ if (stack.length > 0 && stack[stack.length - 1] !== "..") stack.pop();
44895
+ else if (anchor === "~") stack.push(segment);
44896
+ continue;
44897
+ }
44898
+ stack.push(segment);
44899
+ }
44900
+ const resolved = [anchor, ...stack].join("/");
44901
+ return resolved === "" ? "/" : stripTrailingSlash(resolved);
44902
+ }
44903
+ function toCoverageForm(pattern) {
44904
+ let normalized = /^[A-Za-z]:[\\/]/.test(pattern) ? `${pattern.charAt(0).toLowerCase()}${pattern.slice(1).replaceAll("\\", "/")}` : pattern;
44905
+ while (normalized.startsWith("./")) normalized = normalized.slice(2);
44906
+ normalized = stripTrailingSlash(normalized);
44907
+ return normalized === "" && pattern !== "" ? "." : normalized;
44908
+ }
44909
+ function hasDotPathSegment(pattern) {
44910
+ const form = toCoverageForm(pattern);
44911
+ if (form === ".") return false;
44912
+ return form.split(/[\\/]/).some((segment) => segment === "." || segment === "..");
44769
44913
  }
44770
- function stripLeadingDotSlash(pattern) {
44771
- return pattern.startsWith("./") ? pattern.slice(2) : pattern;
44914
+ function isSkippedCodexGrant(pattern) {
44915
+ return isWindowsDevicePath(pattern) || hasUnsupportedCodexFilesystemGlob(pattern);
44916
+ }
44917
+ function moreRestrictiveCodexAccess({ a, b }) {
44918
+ const rank = {
44919
+ deny: 0,
44920
+ none: 0,
44921
+ read: 1,
44922
+ write: 2
44923
+ };
44924
+ return rank[a] <= rank[b] ? a : b;
44772
44925
  }
44773
44926
  function stripTrailingSlash(pattern) {
44774
44927
  return pattern.length > 1 && pattern.endsWith("/") ? pattern.slice(0, -1) : pattern;
@@ -82459,4 +82612,4 @@ async function importChecksCore(params) {
82459
82612
  //#endregion
82460
82613
  export { RulesyncCommand as $, toPosixPath as $t, CLAUDECODE_MEMORIES_DIR_NAME as A, RULESYNC_XDG_CONFIG_HOME_DEFAULT_DIR_NAME as An, checkPathTraversal as At, RulesyncSubagent as B, stripControlCharacters as Bn, listDirectoryEntryNames as Bt, COMMANDCODE_DIR as C, RULESYNC_PERMISSIONS_SCHEMA_URL as Cn, withWarnOnceScope as Ct, CODEXCLI_DIR as D, RULESYNC_SOURCES_LOCK_RELATIVE_FILE_PATH as Dn, assertDirectoryIfExists as Dt, CODEXCLI_BASH_RULES_FILE_NAME as E, RULESYNC_SKILLS_RELATIVE_DIR_PATH as En, applyFileMode as Et, caseFoldIdentity as F, formatError as Fn, getFileSize as Ft, RulesyncRuleFrontmatterSchema as G, readFileContentOrNull as Gt, RulesyncSkill as H, stripHiddenCharacters as Hn, listSubdirectoryNames as Ht, groupSpellingsByCaseFoldedIdentity as I, truncateText as In, getHomeDirectory as It, RulesyncIgnore as J, removeFile as Jt, RulesyncPermissions as K, removeDirectory as Kt, AUGMENTCODE_DIR as L, hasDeceptiveHiddenCharacters as Ln, isFileNotFoundError as Lt, CLAUDECODE_SKILLS_DIR_PATH as M, ALL_FEATURES as Mn, directoryExists as Mt, FACTORYDROID_DIR as N, ALL_FEATURES_WITH_WILDCARD as Nn, ensureDir as Nt, CLAUDECODE_DIR as O, RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH as On, assertTreeContainsNoSymlinks as Ot, FACTORYDROID_SETTINGS_LOCAL_FILE_NAME as P, DEPRECATED_FEATURE_REPLACEMENTS as Pn, fileExists as Pt, parseJsonc as Q, runWithDirectoryRollback as Qt, AUGMENTCODE_SETTINGS_LOCAL_FILE_NAME as R, hasEnclosingMarkOutsideKeycap as Rn, isFileSystemError as Rt, QWENCODE_LOCAL_RULE_FILE_NAME as S, RULESYNC_PERMISSIONS_RELATIVE_FILE_PATH as Sn, resetRunWarningState as St, ChecksProcessor as T, RULESYNC_RULES_RELATIVE_DIR_PATH as Tn, ErrorCodes as Tt, RulesyncSkillFrontmatterSchema as U, pathEscapesRoot as Ut, RulesyncSubagentFrontmatterSchema as V, stripControlCharactersKeepingLineFeeds as Vn, listFilePathsRecursively as Vt, RulesyncRule as W, readFileContent as Wt, getRulesyncSourceCandidates as X, removeTempDirectory as Xt, RulesyncHooks as Y, removeFileStrict as Yt, resolveRulesyncSourceWritePath as Z, resolvePath as Zt, IgnoreProcessor as _, RULESYNC_IGNORE_RELATIVE_FILE_PATH as _n, JsonLogger as _t, getProcessorRegistryEntry as a, ToolTargetSchema as an, SHARED_USER_MANAGED_CONFIG_PATHS as at, CommandsProcessor as b, RULESYNC_MCP_SCHEMA_URL as bn, warnOnConflictingFlags as bt, RulesProcessor as c, MAX_FILE_SIZE as cn, mergeInputRootConfigs as ct, CODEBUDDY_DIR as d, RULESYNC_COMMANDS_RELATIVE_DIR_PATH as dn, ConfigFileSchema as dt, writeFileBuffer as en, RulesyncCommandFrontmatterSchema as et, CODEBUDDY_LOCAL_RULE_FILE_NAME as f, RULESYNC_CONFIG_RELATIVE_FILE_PATH as fn, GITIGNORE_DESTINATION_KEY as ft, McpProcessor as g, RULESYNC_HOOKS_RELATIVE_FILE_PATH as gn, ConsoleLogger as gt, shortenToWidth as h, RULESYNC_CURATED_SKILLS_RELATIVE_DIR_PATH as hn, findControlCharacter as ht, inspectInputRoots as i, PACKAGING_TOOL_TARGETS as in, loadYaml as it, CLAUDECODE_SETTINGS_LOCAL_FILE_NAME as j, parseCommaSeparatedList as jn, createTempDirectory as jt, CLAUDECODE_LOCAL_RULE_FILE_NAME as k, RULESYNC_USER_CONFIG_DIR_NAME as kn, assertWritablePathInsideRoot as kt, SubagentsProcessor as l, RULESYNC_AIIGNORE_RELATIVE_FILE_PATH as ln, resolveEffectiveInputRoots as lt, displayWidthOf as m, RULESYNC_CURATED_RULES_RELATIVE_DIR_PATH as mn, assertTargetsFeaturesExclusive as mt, formatSourceLoadFailure as n, ALL_TOOL_TARGETS as nn, RulesyncCheckFrontmatterSchema as nt, convertFromTool as o, CURATED_RULES_FEATURE_SUBDIR as on, SKILL_FILE_NAME as ot, ELLIPSIS_WIDTH as p, RULESYNC_CONFIG_SCHEMA_URL as pn, SourceEntrySchema as pt, RulesyncMcp as q, removeDirectoryStrict as qt, generate as r, ALL_TOOL_TARGETS_WITH_WILDCARD as rn, stringifyFrontmatter as rt, isPackagingToolTarget as s, FEATURE_SOURCE_TREE_ENTRIES as sn, ConfigResolver as st, importFromTool as t, writeFileContent as tn, RulesyncCheck as tt, SkillsProcessor as u, RULESYNC_CHECKS_RELATIVE_DIR_PATH as un, CONFLICTING_TARGET_PAIRS as ut, HooksProcessor as v, RULESYNC_LOCAL_CONFIG_RELATIVE_FILE_PATH as vn, WarningCollectingLogger as vt, COMMANDCODE_SETTINGS_LOCAL_FILE_NAME as w, RULESYNC_RELATIVE_DIR_PATH as wn, CLIError as wt, QWENCODE_DIR as x, RULESYNC_NPM_SOURCES_LOCK_RELATIVE_FILE_PATH as xn, withFallbackLoggerTarget as xt, CRUSH_LOCAL_RULE_FILE_NAME as y, RULESYNC_MCP_RELATIVE_FILE_PATH as yn, fallbackLogger as yt, getLocalSkillDirNames as z, quoteForLog as zn, isSymlink as zt };
82461
82614
 
82462
- //# sourceMappingURL=import-CA3RFpGB.js.map
82615
+ //# sourceMappingURL=import-_UbLpXUZ.js.map