rulesync 16.39.1 → 17.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.
@@ -44319,14 +44319,10 @@ function convertRulesyncToCodexProfile({ config, logger }) {
44319
44319
  }
44320
44320
  logger?.warn(`Codex CLI permissions support only read/edit/write/webfetch categories. Skipping: ${toolName}`);
44321
44321
  }
44322
- for (const [pattern, access] of mergeFilesystemCategoryRules({
44322
+ addCodexFilesystemRules({
44323
44323
  categoryRules: filesystemCategoryRules,
44324
- logger
44325
- })) addFilesystemRule({
44326
44324
  filesystem,
44327
44325
  workspaceRootFilesystem,
44328
- pattern,
44329
- access,
44330
44326
  logger
44331
44327
  });
44332
44328
  applyDefaultGitWriteRules({
@@ -44351,6 +44347,29 @@ function convertRulesyncToCodexProfile({ config, logger }) {
44351
44347
  ...network ? { network } : {}
44352
44348
  };
44353
44349
  }
44350
+ function addCodexFilesystemRules({ categoryRules, filesystem, workspaceRootFilesystem, logger }) {
44351
+ for (const rule of mergeFilesystemCategoryRules({
44352
+ categoryRules,
44353
+ logger
44354
+ })) {
44355
+ const access = normalizeCodexFilesystemAccess({
44356
+ pattern: rule.pattern,
44357
+ access: rule.access,
44358
+ writeRestriction: rule.writeRestriction,
44359
+ logger
44360
+ });
44361
+ if (access === void 0) continue;
44362
+ if (access === "read" && rule.writeRestriction === "ask") logger?.warn(`Codex CLI cannot express "ask" for filesystem write permissions: pattern "${rule.pattern}" will be emitted as read-only.`);
44363
+ if (access === "read" && rule.writeRestriction === "deny") logger?.warn(`Codex CLI maps a write-side deny to read-only access: pattern "${rule.pattern}" will be emitted as "read". A broader read deny may be overridden by this more-specific path.`);
44364
+ addFilesystemRule({
44365
+ filesystem,
44366
+ workspaceRootFilesystem,
44367
+ pattern: rule.pattern,
44368
+ access,
44369
+ logger
44370
+ });
44371
+ }
44372
+ }
44354
44373
  function applyDefaultGitWriteRules({ config, filesystem, workspaceRootFilesystem }) {
44355
44374
  if (config.codexcli?.git_write_rules === false) return;
44356
44375
  if (config.codexcli?.base_permission_profile === CODEX_READ_ONLY_BASELINE) return;
@@ -44500,6 +44519,23 @@ function addFilesystemRule({ filesystem, workspaceRootFilesystem, pattern, acces
44500
44519
  }
44501
44520
  workspaceRootFilesystem[pattern] = access;
44502
44521
  }
44522
+ function normalizeCodexFilesystemAccess({ pattern, access, writeRestriction, logger }) {
44523
+ if ((access === "read" || access === "write") && hasUnsupportedCodexFilesystemGlob(pattern)) {
44524
+ if (writeRestriction !== void 0) {
44525
+ logger?.warn(`Codex CLI only supports deny access for non-trailing filesystem globs: pattern "${pattern}" will be emitted as "deny" because its write-side ${writeRestriction} restriction cannot be represented as read-only access. Use an exact path or trailing "/**" for read/write access.`);
44526
+ return "deny";
44527
+ }
44528
+ logger?.warn(`Skipping unsupported Codex CLI ${access} filesystem glob "${pattern}"; the base permission profile remains in effect. Use an exact path or trailing "/**" for read/write access.`);
44529
+ return;
44530
+ }
44531
+ return access;
44532
+ }
44533
+ function hasCodexFilesystemGlob(pattern) {
44534
+ return pattern.includes("*") || pattern.includes("?") || pattern.includes("[") || pattern.includes("]");
44535
+ }
44536
+ function hasUnsupportedCodexFilesystemGlob(pattern) {
44537
+ return hasCodexFilesystemGlob(pattern.endsWith("/**") ? pattern.slice(0, -3) : pattern);
44538
+ }
44503
44539
  function canBeCodexFilesystemRoot(pattern) {
44504
44540
  return (0, node_path.isAbsolute)(pattern) || /^[A-Za-z]:[\\/]/.test(pattern) || pattern.startsWith("~/") || pattern === "~" || pattern.startsWith(":");
44505
44541
  }
@@ -44636,30 +44672,8 @@ function mapReadAction(action) {
44636
44672
  return action === "allow" ? "read" : "deny";
44637
44673
  }
44638
44674
  function mapWriteAction(action) {
44639
- return action === "allow" ? "write" : "deny";
44640
- }
44641
- /**
44642
- * Merge the canonical read/edit/write category rules into one Codex access
44643
- * level per path pattern (Codex models a single `deny` < `read` < `write`
44644
- * level, with no `ask`).
44645
- *
44646
- * - `edit` and `write` collapse onto Codex's write side; when both carry the
44647
- * same pattern, the more restrictive action wins (`deny` > `ask` > `allow`).
44648
- * - `read: allow` + write-side `allow` → `"write"`.
44649
- * - `read: allow` + write-side non-allow → `"read"` (readable but not
44650
- * writable — exactly what Codex's `"read"` level expresses).
44651
- * - `read` non-allow → `"deny"` regardless of the write side; a contradictory
44652
- * write-side `allow` (unreadable but writable is not expressible in Codex)
44653
- * is warned about.
44654
- * - Single-category patterns keep the existing mapReadAction/mapWriteAction
44655
- * mappings.
44656
- *
44657
- * Iteration order is read → edit → write with first-seen pattern order, so
44658
- * the emitted table is stable regardless of the authored category order.
44659
- * Note the merge is one-way: `"{path}" = "read"` imports back as
44660
- * `read: allow` only (the explicit write-side deny is implied by Codex's
44661
- * access level and not re-materialized).
44662
- */
44675
+ return action === "allow" ? "write" : "read";
44676
+ }
44663
44677
  function mergeFilesystemCategoryRules({ categoryRules, logger }) {
44664
44678
  const readRules = categoryRules.read ?? {};
44665
44679
  const writeSideRestrictiveness = {
@@ -44683,19 +44697,33 @@ function mergeFilesystemCategoryRules({ categoryRules, logger }) {
44683
44697
  const readAction = readRules[pattern];
44684
44698
  const writeAction = writeSideRules[pattern];
44685
44699
  if (readAction === void 0) {
44686
- merged.push([pattern, mapWriteAction(writeAction)]);
44700
+ merged.push({
44701
+ pattern,
44702
+ access: mapWriteAction(writeAction),
44703
+ ...writeAction === "ask" || writeAction === "deny" ? { writeRestriction: writeAction } : {}
44704
+ });
44687
44705
  continue;
44688
44706
  }
44689
44707
  if (writeAction === void 0) {
44690
- merged.push([pattern, mapReadAction(readAction)]);
44708
+ merged.push({
44709
+ pattern,
44710
+ access: mapReadAction(readAction)
44711
+ });
44691
44712
  continue;
44692
44713
  }
44693
44714
  if (readAction === "allow") {
44694
- merged.push([pattern, writeAction === "allow" ? "write" : "read"]);
44715
+ merged.push({
44716
+ pattern,
44717
+ access: writeAction === "allow" ? "write" : "read",
44718
+ ...writeAction === "ask" || writeAction === "deny" ? { writeRestriction: writeAction } : {}
44719
+ });
44695
44720
  continue;
44696
44721
  }
44697
44722
  if (writeAction === "allow") logger?.warn(`Codex CLI cannot express "writable but not readable": pattern "${pattern}" has read: ${readAction} and a write-side allow. Emitting "deny".`);
44698
- merged.push([pattern, "deny"]);
44723
+ merged.push({
44724
+ pattern,
44725
+ access: "deny"
44726
+ });
44699
44727
  }
44700
44728
  return merged;
44701
44729
  }
package/dist/index.cjs CHANGED
@@ -1,5 +1,5 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_import = require("./import-DS3OrTAl.cjs");
2
+ const require_import = require("./import-j-fApVPQ.cjs");
3
3
  //#region src/index.ts
4
4
  async function generate(options = {}) {
5
5
  const { silent = true, verbose = false, ...rest } = options;
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { Mn as ALL_FEATURES, gt as ConsoleLogger, i as inspectInputRoots, nn as ALL_TOOL_TARGETS, o as convertFromTool$1, r as generate$1, st as ConfigResolver, t as importFromTool$1 } from "./import-B2ANxi1V.js";
1
+ import { Mn as ALL_FEATURES, gt as ConsoleLogger, i as inspectInputRoots, nn as ALL_TOOL_TARGETS, o as convertFromTool$1, r as generate$1, st as ConfigResolver, t as importFromTool$1 } from "./import-CEgvxK12.js";
2
2
  //#region src/index.ts
3
3
  async function generate(options = {}) {
4
4
  const { silent = true, verbose = false, ...rest } = options;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rulesync",
3
- "version": "16.39.1",
3
+ "version": "17.0.0",
4
4
  "description": "Unified AI rules management CLI tool that generates configuration files for various AI development tools",
5
5
  "keywords": [
6
6
  "ai",