rulesync 10.1.0 → 11.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.
@@ -17428,7 +17428,11 @@ const CodexApprovalPolicySchema = z.enum([
17428
17428
  ]);
17429
17429
  /**
17430
17430
  * Codex CLI's classic sandbox mode. Serialized as a kebab-case string in
17431
- * `.codex/config.toml`.
17431
+ * `.codex/config.toml`. Deprecated in favor of permission profiles
17432
+ * (`base_permission_profile`): Codex prioritizes these legacy sandbox keys
17433
+ * over permission profiles when both are present, so authoring one disables
17434
+ * the managed `[permissions.rulesync]` profile. Kept so existing configs
17435
+ * round-trip.
17432
17436
  * @see https://learn.chatgpt.com/docs/config-file/config-reference
17433
17437
  */
17434
17438
  const CodexSandboxModeSchema = z.enum([
@@ -17448,6 +17452,18 @@ const CodexApprovalsReviewerSchema = z.enum([
17448
17452
  "guardian_subagent"
17449
17453
  ]);
17450
17454
  /**
17455
+ * Codex CLI's built-in permission profiles that the managed
17456
+ * `[permissions.rulesync]` profile may extend. Codex ships three built-in
17457
+ * profiles (`:read-only`, `:workspace`, `:danger-full-access`; the leading
17458
+ * colon is reserved for built-ins), but `extends` rejects
17459
+ * `:danger-full-access` at config load time, so only the two extendable
17460
+ * baselines are accepted here. The value list is exported so the Codex CLI
17461
+ * translator derives its import-side baseline check from the same source.
17462
+ * @see https://learn.chatgpt.com/docs/permissions
17463
+ */
17464
+ const CODEX_BASE_PERMISSION_PROFILES = [":read-only", ":workspace"];
17465
+ const CodexBasePermissionProfileSchema = z.enum(CODEX_BASE_PERMISSION_PROFILES);
17466
+ /**
17451
17467
  * Codex CLI-scoped permission override.
17452
17468
  *
17453
17469
  * Codex CLI's permission surface is richer than the canonical allow/ask/deny
@@ -17456,16 +17472,29 @@ const CodexApprovalsReviewerSchema = z.enum([
17456
17472
  * override whose fields are written verbatim as top-level `.codex/config.toml`
17457
17473
  * keys (the override wins per key; existing sibling keys the user set directly
17458
17474
  * are preserved):
17475
+ * - `base_permission_profile` — the built-in profile the managed
17476
+ * `[permissions.rulesync]` profile extends (`:read-only` | `:workspace`).
17477
+ * Unlike the other keys it is not a top-level config key: it is emitted as
17478
+ * the profile's `extends` value. Defaults to `:workspace` when unspecified.
17459
17479
  * - `approval_policy` — `untrusted` | `on-request` (legacy alias `on-failure`) |
17460
17480
  * `never`, or a `{ granular = { … } }` table (kept verbatim; the granular
17461
17481
  * schema has required fields that are brittle to model as typed keys).
17462
- * - `sandbox_mode` `read-only` | `workspace-write` | `danger-full-access`,
17463
- * with the sibling `sandbox_workspace_write` table (`network_access`,
17464
- * `writable_roots`, …).
17482
+ * Defaults to `on-request` when neither the override nor the existing
17483
+ * config sets it.
17484
+ * - `sandbox_mode` — **deprecated.** `read-only` | `workspace-write` |
17485
+ * `danger-full-access`, with the sibling `sandbox_workspace_write` table
17486
+ * (`network_access`, `writable_roots`, …). Codex has superseded the classic
17487
+ * sandbox system with permission profiles and prioritizes these legacy keys
17488
+ * over profiles when both are present, so setting them disables the managed
17489
+ * `[permissions.rulesync]` profile. Use `base_permission_profile` and the
17490
+ * shared `permission` block instead. Still accepted so existing configs
17491
+ * round-trip.
17465
17492
  * - `apps` — per-app tool gating (`apps.<id>.tools.<tool>.approval_mode` /
17466
17493
  * `.enabled`, `apps.<id>.default_tools_approval_mode`).
17467
17494
  * - `approvals_reviewer` — the reviewer-approval surface (`user` | `auto_review`
17468
17495
  * | `guardian_subagent`), or a table for the richer reviewer config.
17496
+ * Defaults to `auto_review` when neither the override nor the existing
17497
+ * config sets it.
17469
17498
  *
17470
17499
  * Two surfaces are deliberately NOT authorable here so the override can never
17471
17500
  * clobber a feature-owned key: `mcp_servers.*` per-MCP gating is owned by the
@@ -17484,8 +17513,11 @@ const CodexApprovalsReviewerSchema = z.enum([
17484
17513
  */
17485
17514
  const CodexcliPermissionsOverrideSchema = z.looseObject({
17486
17515
  permission: z.optional(ToolScopedPermissionSchema),
17516
+ base_permission_profile: z.optional(CodexBasePermissionProfileSchema),
17487
17517
  approval_policy: z.optional(z.union([CodexApprovalPolicySchema, z.looseObject({})])),
17518
+ /** @deprecated Superseded by `base_permission_profile` (permission profiles). */
17488
17519
  sandbox_mode: z.optional(CodexSandboxModeSchema),
17520
+ /** @deprecated Superseded by `base_permission_profile` (permission profiles). */
17489
17521
  sandbox_workspace_write: z.optional(z.looseObject({})),
17490
17522
  apps: z.optional(z.looseObject({})),
17491
17523
  approvals_reviewer: z.optional(z.union([CodexApprovalsReviewerSchema, z.looseObject({})]))
@@ -19457,13 +19489,10 @@ var ClinePermissions = class ClinePermissions extends ToolPermissions {
19457
19489
  const RULESYNC_PROFILE_NAME = "rulesync";
19458
19490
  const CODEX_WORKSPACE_ROOTS_KEY = ":workspace_roots";
19459
19491
  const CODEX_WORKSPACE_BASELINE = ":workspace";
19492
+ const CODEX_EXTENDABLE_BASELINES = new Set(CODEX_BASE_PERMISSION_PROFILES);
19493
+ const CODEX_DEFAULT_APPROVAL_POLICY = "on-request";
19494
+ const CODEX_DEFAULT_APPROVALS_REVIEWER = "auto_review";
19460
19495
  const CODEX_GLOB_SCAN_MAX_DEPTH = 8;
19461
- const WORKSPACE_WIDE_WRITE_PATTERNS = /* @__PURE__ */ new Set([
19462
- ".",
19463
- "./",
19464
- "**",
19465
- "./**"
19466
- ]);
19467
19496
  const CODEX_MINIMAL_KEY = ":minimal";
19468
19497
  const GLOBAL_WILDCARD_DOMAIN = "*";
19469
19498
  var CodexcliPermissions = class CodexcliPermissions extends ToolPermissions {
@@ -19553,6 +19582,7 @@ var CodexcliPermissions = class CodexcliPermissions extends ToolPermissions {
19553
19582
  domainsHadUnknown
19554
19583
  });
19555
19584
  const override = extractCodexcliOverride(table);
19585
+ if (typeof profile?.extends === "string" && CODEX_EXTENDABLE_BASELINES.has(profile.extends)) override.base_permission_profile = profile.extends;
19556
19586
  const result = Object.keys(override).length > 0 ? {
19557
19587
  ...config,
19558
19588
  codexcli: override
@@ -19635,14 +19665,14 @@ function convertRulesyncToCodexProfile({ config, logger }) {
19635
19665
  if (Object.keys(workspaceRootFilesystem).some((pattern) => pattern.includes("**"))) filesystem.glob_scan_max_depth = CODEX_GLOB_SCAN_MAX_DEPTH;
19636
19666
  filesystem[CODEX_WORKSPACE_ROOTS_KEY] = workspaceRootFilesystem;
19637
19667
  }
19638
- const hasWorkspaceWideWrite = Object.entries(workspaceRootFilesystem).some(([pattern, access]) => access === "write" && WORKSPACE_WIDE_WRITE_PATTERNS.has(pattern));
19668
+ const basePermissionProfile = config.codexcli?.base_permission_profile ?? CODEX_WORKSPACE_BASELINE;
19639
19669
  const hasAllowDomain = Object.values(domains).some((action) => action === "allow");
19640
19670
  const network = Object.keys(domains).length > 0 ? {
19641
19671
  ...hasAllowDomain ? { enabled: true } : {},
19642
19672
  domains
19643
19673
  } : void 0;
19644
19674
  return {
19645
- ...hasWorkspaceWideWrite ? { extends: CODEX_WORKSPACE_BASELINE } : {},
19675
+ extends: basePermissionProfile,
19646
19676
  filesystem,
19647
19677
  ...network ? { network } : {}
19648
19678
  };
@@ -19661,10 +19691,6 @@ function convertCodexProfileToRulesync({ profile, domainsHadUnknown }) {
19661
19691
  if (isCodexFilesystemRuleTable(access)) for (const [nestedPattern, nestedAccess] of Object.entries(access)) addRulesyncFilesystemRule(permission, nestedPattern, nestedAccess);
19662
19692
  }
19663
19693
  }
19664
- if (profile?.extends === CODEX_WORKSPACE_BASELINE) {
19665
- permission.edit ??= {};
19666
- permission.edit["."] ??= "allow";
19667
- }
19668
19694
  if (profile?.network && profile.network.enabled !== false) {
19669
19695
  const networkEnabled = profile.network.enabled === true;
19670
19696
  const importedEntries = (profile.network.domains ? Object.entries(profile.network.domains) : []).filter(([, value]) => value === "deny" || networkEnabled);
@@ -19703,7 +19729,7 @@ function toCodexProfile(value) {
19703
19729
  };
19704
19730
  }
19705
19731
  function warnAboutPreservedProfileState({ existingProfile, newProfile, existingDomainsHadUnknown, logger }) {
19706
- if (existingProfile?.extends !== void 0 && existingProfile.extends !== newProfile.extends) logger?.warn(`Existing "extends" value "${existingProfile.extends}" will be replaced by Rulesync-managed "${newProfile.extends ?? "(none)"}".`);
19732
+ if (existingProfile !== void 0 && existingProfile.extends !== newProfile.extends) logger?.warn(`Existing "extends" value "${existingProfile.extends ?? "(none)"}" will be replaced by Rulesync-managed "${newProfile.extends ?? "(none)"}".`);
19707
19733
  if (existingProfile?.network?.unix_sockets !== void 0) logger?.warn(`Preserving existing "network.unix_sockets" from config. Review these entries manually as they may grant broad system access.`);
19708
19734
  if (existingProfile?.network?.mode !== void 0) logger?.warn(`Preserving existing "network.mode" from config. Review this value manually as it may grant broader network access than the Rulesync-managed domain rules.`);
19709
19735
  if (existingDomainsHadUnknown) logger?.warn(`Existing "network.domains" contained unrecognized values. These entries were skipped and will not be imported.`);
@@ -19797,20 +19823,26 @@ function isPlainObject(value) {
19797
19823
  }
19798
19824
  function computeCodexcliOverridePatch({ existing, override, logger }) {
19799
19825
  const patch = {};
19800
- if (!override) return patch;
19801
19826
  const allowed = new Set(CODEXCLI_OVERRIDE_KEYS);
19802
- for (const [key, value] of Object.entries(override)) {
19827
+ for (const [key, value] of Object.entries(override ?? {})) {
19828
+ if (key === "base_permission_profile") continue;
19803
19829
  if (!allowed.has(key)) {
19804
19830
  logger?.warn(`Codex CLI permission override key "${key}" is not managed and was skipped. "permissions"/"default_permissions" are owned by the canonical permission model and "mcp_servers" gating by the MCP feature.`);
19805
19831
  continue;
19806
19832
  }
19807
19833
  if (value === void 0) continue;
19834
+ if (key === "sandbox_mode" || key === "sandbox_workspace_write") logger?.warn(`Codex CLI permission override key "${key}" is deprecated. Codex prioritizes the legacy sandbox settings over permission profiles when both are present, so it disables the generated "${RULESYNC_PROFILE_NAME}" permissions profile. Use "base_permission_profile" and the shared "permission" block instead.`);
19808
19835
  const existingValue = existing[key];
19809
19836
  patch[key] = isPlainObject(existingValue) && isPlainObject(value) ? {
19810
19837
  ...existingValue,
19811
19838
  ...value
19812
19839
  } : value;
19813
19840
  }
19841
+ const defaults = {
19842
+ approval_policy: CODEX_DEFAULT_APPROVAL_POLICY,
19843
+ approvals_reviewer: CODEX_DEFAULT_APPROVALS_REVIEWER
19844
+ };
19845
+ for (const [key, value] of Object.entries(defaults)) if (patch[key] === void 0 && existing[key] === void 0) patch[key] = value;
19814
19846
  return patch;
19815
19847
  }
19816
19848
  function extractCodexcliOverride(table) {
@@ -40388,4 +40420,4 @@ async function importPermissionsCore(params) {
40388
40420
  //#endregion
40389
40421
  export { removeFile as $, CLAUDECODE_SKILLS_DIR_PATH as A, RULESYNC_SOURCES_LOCK_RELATIVE_FILE_PATH as At, ErrorCodes as B, RulesyncHooks as C, RULESYNC_PERMISSIONS_FILE_NAME as Ct, CLAUDECODE_LOCAL_RULE_FILE_NAME as D, RULESYNC_RELATIVE_DIR_PATH as Dt, CLAUDECODE_DIR as E, RULESYNC_PERMISSIONS_SCHEMA_URL as Et, ConfigResolver as F, fileExists as G, createTempDirectory as H, findControlCharacter as I, getHomeDirectory as J, findFilesByGlobs as K, ConsoleLogger as L, RulesyncCommandFrontmatterSchema as M, formatError as Mt, stringifyFrontmatter as N, ALL_FEATURES as Nt, CLAUDECODE_MEMORIES_DIR_NAME as O, RULESYNC_RULES_RELATIVE_DIR_PATH as Ot, loadYaml as P, ALL_FEATURES_WITH_WILDCARD as Pt, removeDirectory as Q, JsonLogger as R, HooksProcessor as S, RULESYNC_OVERVIEW_FILE_NAME as St, CODEXCLI_DIR as T, RULESYNC_PERMISSIONS_RELATIVE_FILE_PATH as Tt, directoryExists as U, checkPathTraversal as V, ensureDir as W, listDirectoryFiles as X, isSymlink as Y, readFileContent as Z, RulesyncPermissions as _, RULESYNC_LOCAL_CONFIG_RELATIVE_FILE_PATH as _t, convertFromTool as a, ToolTargetSchema as at, IgnoreProcessor as b, RULESYNC_MCP_RELATIVE_FILE_PATH as bt, RulesyncRuleFrontmatterSchema as c, RULESYNC_AIIGNORE_RELATIVE_FILE_PATH as ct, RulesyncSubagentFrontmatterSchema as d, RULESYNC_CONFIG_SCHEMA_URL as dt, removeTempDirectory as et, SkillsProcessor as f, RULESYNC_CURATED_SKILLS_RELATIVE_DIR_PATH as ft, SKILL_FILE_NAME as g, RULESYNC_IGNORE_RELATIVE_FILE_PATH as gt, RulesyncSkillFrontmatterSchema as h, RULESYNC_HOOKS_RELATIVE_FILE_PATH as ht, getProcessorRegistryEntry as i, ALL_TOOL_TARGETS_WITH_WILDCARD as it, RulesyncCommand as j, RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH as jt, CLAUDECODE_SETTINGS_LOCAL_FILE_NAME as k, RULESYNC_SKILLS_RELATIVE_DIR_PATH as kt, SubagentsProcessor as l, RULESYNC_COMMANDS_RELATIVE_DIR_PATH as lt, RulesyncSkill as m, RULESYNC_HOOKS_JSONC_FILE_NAME as mt, checkRulesyncDirExists as n, writeFileContent as nt, RulesProcessor as o, MAX_FILE_SIZE as ot, getLocalSkillDirNames as p, RULESYNC_HOOKS_FILE_NAME as pt, getFileSize as q, generate as r, ALL_TOOL_TARGETS as rt, RulesyncRule as s, RULESYNC_AIIGNORE_FILE_NAME as st, importFromTool as t, toPosixPath as tt, RulesyncSubagent as u, RULESYNC_CONFIG_RELATIVE_FILE_PATH as ut, McpProcessor as v, RULESYNC_MCP_FILE_NAME as vt, CommandsProcessor as w, RULESYNC_PERMISSIONS_JSONC_FILE_NAME as wt, RulesyncIgnore as x, RULESYNC_MCP_SCHEMA_URL as xt, RulesyncMcp as y, RULESYNC_MCP_JSONC_FILE_NAME as yt, CLIError as z };
40390
40422
 
40391
- //# sourceMappingURL=import-B02AyWkQ.js.map
40423
+ //# sourceMappingURL=import-AKytnIKl.js.map