rulesync 10.1.0 → 12.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.
- package/README.md +1 -1
- package/dist/cli/index.cjs +2 -2
- package/dist/cli/index.js +2 -2
- package/dist/cli/index.js.map +1 -1
- package/dist/{import-Dcj5HiOE.cjs → import-C0N0Lo_F.cjs} +388 -37
- package/dist/{import-B02AyWkQ.js → import-hM4jDZn1.js} +376 -25
- package/dist/import-hM4jDZn1.js.map +1 -0
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/package.json +1 -1
- package/dist/import-B02AyWkQ.js.map +0 -1
|
@@ -264,6 +264,7 @@ const subagentsProcessorToolTargetTuple = [
|
|
|
264
264
|
"kiro-ide",
|
|
265
265
|
"opencode",
|
|
266
266
|
"qwencode",
|
|
267
|
+
"reasonix",
|
|
267
268
|
"roo",
|
|
268
269
|
"rovodev",
|
|
269
270
|
"takt",
|
|
@@ -5092,6 +5093,9 @@ const REASONIX_SETTINGS_FILE_NAME = "settings.json";
|
|
|
5092
5093
|
const REASONIX_COMMANDS_DIR_PATH = join(REASONIX_DIR, "commands");
|
|
5093
5094
|
const REASONIX_RULE_FILE_NAME = "REASONIX.md";
|
|
5094
5095
|
const REASONIX_SKILLS_DIR_PATH = join(REASONIX_DIR, "skills");
|
|
5096
|
+
const REASONIX_SUBAGENTS_DIR_PATH = REASONIX_SKILLS_DIR_PATH;
|
|
5097
|
+
const REASONIX_SUBAGENT_INVOCATION = "manual";
|
|
5098
|
+
const REASONIX_SUBAGENT_RUN_AS = "subagent";
|
|
5095
5099
|
//#endregion
|
|
5096
5100
|
//#region src/features/commands/reasonix-command.ts
|
|
5097
5101
|
/**
|
|
@@ -17428,7 +17432,11 @@ const CodexApprovalPolicySchema = z.enum([
|
|
|
17428
17432
|
]);
|
|
17429
17433
|
/**
|
|
17430
17434
|
* Codex CLI's classic sandbox mode. Serialized as a kebab-case string in
|
|
17431
|
-
* `.codex/config.toml`.
|
|
17435
|
+
* `.codex/config.toml`. Deprecated in favor of permission profiles
|
|
17436
|
+
* (`base_permission_profile`): Codex prioritizes these legacy sandbox keys
|
|
17437
|
+
* over permission profiles when both are present, so authoring one disables
|
|
17438
|
+
* the managed `[permissions.rulesync]` profile. Kept so existing configs
|
|
17439
|
+
* round-trip.
|
|
17432
17440
|
* @see https://learn.chatgpt.com/docs/config-file/config-reference
|
|
17433
17441
|
*/
|
|
17434
17442
|
const CodexSandboxModeSchema = z.enum([
|
|
@@ -17448,6 +17456,18 @@ const CodexApprovalsReviewerSchema = z.enum([
|
|
|
17448
17456
|
"guardian_subagent"
|
|
17449
17457
|
]);
|
|
17450
17458
|
/**
|
|
17459
|
+
* Codex CLI's built-in permission profiles that the managed
|
|
17460
|
+
* `[permissions.rulesync]` profile may extend. Codex ships three built-in
|
|
17461
|
+
* profiles (`:read-only`, `:workspace`, `:danger-full-access`; the leading
|
|
17462
|
+
* colon is reserved for built-ins), but `extends` rejects
|
|
17463
|
+
* `:danger-full-access` at config load time, so only the two extendable
|
|
17464
|
+
* baselines are accepted here. The value list is exported so the Codex CLI
|
|
17465
|
+
* translator derives its import-side baseline check from the same source.
|
|
17466
|
+
* @see https://learn.chatgpt.com/docs/permissions
|
|
17467
|
+
*/
|
|
17468
|
+
const CODEX_BASE_PERMISSION_PROFILES = [":read-only", ":workspace"];
|
|
17469
|
+
const CodexBasePermissionProfileSchema = z.enum(CODEX_BASE_PERMISSION_PROFILES);
|
|
17470
|
+
/**
|
|
17451
17471
|
* Codex CLI-scoped permission override.
|
|
17452
17472
|
*
|
|
17453
17473
|
* Codex CLI's permission surface is richer than the canonical allow/ask/deny
|
|
@@ -17456,16 +17476,37 @@ const CodexApprovalsReviewerSchema = z.enum([
|
|
|
17456
17476
|
* override whose fields are written verbatim as top-level `.codex/config.toml`
|
|
17457
17477
|
* keys (the override wins per key; existing sibling keys the user set directly
|
|
17458
17478
|
* are preserved):
|
|
17479
|
+
* - `base_permission_profile` — the built-in profile the managed
|
|
17480
|
+
* `[permissions.rulesync]` profile extends (`:read-only` | `:workspace`).
|
|
17481
|
+
* Unlike the other keys it is not a top-level config key: it is emitted as
|
|
17482
|
+
* the profile's `extends` value. Defaults to `:workspace` when unspecified.
|
|
17459
17483
|
* - `approval_policy` — `untrusted` | `on-request` (legacy alias `on-failure`) |
|
|
17460
17484
|
* `never`, or a `{ granular = { … } }` table (kept verbatim; the granular
|
|
17461
17485
|
* schema has required fields that are brittle to model as typed keys).
|
|
17462
|
-
*
|
|
17463
|
-
*
|
|
17464
|
-
*
|
|
17486
|
+
* Defaults to `on-request` when neither the override nor the existing
|
|
17487
|
+
* config sets it.
|
|
17488
|
+
* - `sandbox_mode` — **deprecated.** `read-only` | `workspace-write` |
|
|
17489
|
+
* `danger-full-access`, with the sibling `sandbox_workspace_write` table
|
|
17490
|
+
* (`network_access`, `writable_roots`, …). Codex has superseded the classic
|
|
17491
|
+
* sandbox system with permission profiles and prioritizes these legacy keys
|
|
17492
|
+
* over profiles when both are present, so setting them disables the managed
|
|
17493
|
+
* `[permissions.rulesync]` profile. Use `base_permission_profile` and the
|
|
17494
|
+
* shared `permission` block instead. Still accepted so existing configs
|
|
17495
|
+
* round-trip.
|
|
17465
17496
|
* - `apps` — per-app tool gating (`apps.<id>.tools.<tool>.approval_mode` /
|
|
17466
17497
|
* `.enabled`, `apps.<id>.default_tools_approval_mode`).
|
|
17467
17498
|
* - `approvals_reviewer` — the reviewer-approval surface (`user` | `auto_review`
|
|
17468
17499
|
* | `guardian_subagent`), or a table for the richer reviewer config.
|
|
17500
|
+
* Defaults to `auto_review` when neither the override nor the existing
|
|
17501
|
+
* config sets it.
|
|
17502
|
+
* - `git_write_rules` — whether the managed profile's `:workspace_roots` table
|
|
17503
|
+
* emits the default `.git` carve-outs (`".git/**" = "write"` with
|
|
17504
|
+
* `".git/config" = "read"` kept read-only as a security guard). Codex's
|
|
17505
|
+
* `:workspace` baseline makes `.git` read-only, which denies basic git
|
|
17506
|
+
* workflows (commit/stage writes to `.git/index`, `.git/objects`, refs,
|
|
17507
|
+
* logs), so the carve-outs are emitted by default. Defaults to `true`; only
|
|
17508
|
+
* an explicit `false` suppresses them. Like `base_permission_profile` it is
|
|
17509
|
+
* consumed by the profile builder, not written as a top-level config key.
|
|
17469
17510
|
*
|
|
17470
17511
|
* Two surfaces are deliberately NOT authorable here so the override can never
|
|
17471
17512
|
* clobber a feature-owned key: `mcp_servers.*` per-MCP gating is owned by the
|
|
@@ -17484,11 +17525,15 @@ const CodexApprovalsReviewerSchema = z.enum([
|
|
|
17484
17525
|
*/
|
|
17485
17526
|
const CodexcliPermissionsOverrideSchema = z.looseObject({
|
|
17486
17527
|
permission: z.optional(ToolScopedPermissionSchema),
|
|
17528
|
+
base_permission_profile: z.optional(CodexBasePermissionProfileSchema),
|
|
17487
17529
|
approval_policy: z.optional(z.union([CodexApprovalPolicySchema, z.looseObject({})])),
|
|
17530
|
+
/** @deprecated Superseded by `base_permission_profile` (permission profiles). */
|
|
17488
17531
|
sandbox_mode: z.optional(CodexSandboxModeSchema),
|
|
17532
|
+
/** @deprecated Superseded by `base_permission_profile` (permission profiles). */
|
|
17489
17533
|
sandbox_workspace_write: z.optional(z.looseObject({})),
|
|
17490
17534
|
apps: z.optional(z.looseObject({})),
|
|
17491
|
-
approvals_reviewer: z.optional(z.union([CodexApprovalsReviewerSchema, z.looseObject({})]))
|
|
17535
|
+
approvals_reviewer: z.optional(z.union([CodexApprovalsReviewerSchema, z.looseObject({})])),
|
|
17536
|
+
git_write_rules: z.optional(z.boolean())
|
|
17492
17537
|
});
|
|
17493
17538
|
/**
|
|
17494
17539
|
* Permissions configuration.
|
|
@@ -19457,14 +19502,16 @@ var ClinePermissions = class ClinePermissions extends ToolPermissions {
|
|
|
19457
19502
|
const RULESYNC_PROFILE_NAME = "rulesync";
|
|
19458
19503
|
const CODEX_WORKSPACE_ROOTS_KEY = ":workspace_roots";
|
|
19459
19504
|
const CODEX_WORKSPACE_BASELINE = ":workspace";
|
|
19505
|
+
const CODEX_READ_ONLY_BASELINE = ":read-only";
|
|
19506
|
+
const CODEX_EXTENDABLE_BASELINES = new Set(CODEX_BASE_PERMISSION_PROFILES);
|
|
19507
|
+
const CODEX_DEFAULT_APPROVAL_POLICY = "on-request";
|
|
19508
|
+
const CODEX_DEFAULT_APPROVALS_REVIEWER = "auto_review";
|
|
19460
19509
|
const CODEX_GLOB_SCAN_MAX_DEPTH = 8;
|
|
19461
|
-
const WORKSPACE_WIDE_WRITE_PATTERNS = /* @__PURE__ */ new Set([
|
|
19462
|
-
".",
|
|
19463
|
-
"./",
|
|
19464
|
-
"**",
|
|
19465
|
-
"./**"
|
|
19466
|
-
]);
|
|
19467
19510
|
const CODEX_MINIMAL_KEY = ":minimal";
|
|
19511
|
+
const CODEX_GIT_WRITE_RULES = {
|
|
19512
|
+
".git/**": "write",
|
|
19513
|
+
".git/config": "read"
|
|
19514
|
+
};
|
|
19468
19515
|
const GLOBAL_WILDCARD_DOMAIN = "*";
|
|
19469
19516
|
var CodexcliPermissions = class CodexcliPermissions extends ToolPermissions {
|
|
19470
19517
|
static getSettablePaths(_options = {}) {
|
|
@@ -19553,6 +19600,7 @@ var CodexcliPermissions = class CodexcliPermissions extends ToolPermissions {
|
|
|
19553
19600
|
domainsHadUnknown
|
|
19554
19601
|
});
|
|
19555
19602
|
const override = extractCodexcliOverride(table);
|
|
19603
|
+
if (typeof profile?.extends === "string" && CODEX_EXTENDABLE_BASELINES.has(profile.extends)) override.base_permission_profile = profile.extends;
|
|
19556
19604
|
const result = Object.keys(override).length > 0 ? {
|
|
19557
19605
|
...config,
|
|
19558
19606
|
codexcli: override
|
|
@@ -19630,23 +19678,34 @@ function convertRulesyncToCodexProfile({ config, logger }) {
|
|
|
19630
19678
|
}
|
|
19631
19679
|
logger?.warn(`Codex CLI permissions support only read/edit/write/webfetch categories. Skipping: ${toolName}`);
|
|
19632
19680
|
}
|
|
19681
|
+
applyDefaultGitWriteRules({
|
|
19682
|
+
config,
|
|
19683
|
+
filesystem,
|
|
19684
|
+
workspaceRootFilesystem
|
|
19685
|
+
});
|
|
19633
19686
|
if (Object.keys(workspaceRootFilesystem).length > 0) {
|
|
19634
19687
|
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.`);
|
|
19635
19688
|
if (Object.keys(workspaceRootFilesystem).some((pattern) => pattern.includes("**"))) filesystem.glob_scan_max_depth = CODEX_GLOB_SCAN_MAX_DEPTH;
|
|
19636
19689
|
filesystem[CODEX_WORKSPACE_ROOTS_KEY] = workspaceRootFilesystem;
|
|
19637
19690
|
}
|
|
19638
|
-
const
|
|
19691
|
+
const basePermissionProfile = config.codexcli?.base_permission_profile ?? CODEX_WORKSPACE_BASELINE;
|
|
19639
19692
|
const hasAllowDomain = Object.values(domains).some((action) => action === "allow");
|
|
19640
19693
|
const network = Object.keys(domains).length > 0 ? {
|
|
19641
19694
|
...hasAllowDomain ? { enabled: true } : {},
|
|
19642
19695
|
domains
|
|
19643
19696
|
} : void 0;
|
|
19644
19697
|
return {
|
|
19645
|
-
|
|
19698
|
+
extends: basePermissionProfile,
|
|
19646
19699
|
filesystem,
|
|
19647
19700
|
...network ? { network } : {}
|
|
19648
19701
|
};
|
|
19649
19702
|
}
|
|
19703
|
+
function applyDefaultGitWriteRules({ config, filesystem, workspaceRootFilesystem }) {
|
|
19704
|
+
if (config.codexcli?.git_write_rules === false) return;
|
|
19705
|
+
if (config.codexcli?.base_permission_profile === CODEX_READ_ONLY_BASELINE) return;
|
|
19706
|
+
if (typeof filesystem[CODEX_WORKSPACE_ROOTS_KEY] === "string") return;
|
|
19707
|
+
for (const [pattern, access] of Object.entries(CODEX_GIT_WRITE_RULES)) workspaceRootFilesystem[pattern] ??= access;
|
|
19708
|
+
}
|
|
19650
19709
|
function convertCodexProfileToRulesync({ profile, domainsHadUnknown }) {
|
|
19651
19710
|
const permission = {};
|
|
19652
19711
|
if (profile?.filesystem) {
|
|
@@ -19658,13 +19717,12 @@ function convertCodexProfileToRulesync({ profile, domainsHadUnknown }) {
|
|
|
19658
19717
|
addRulesyncFilesystemRule(permission, pattern, access);
|
|
19659
19718
|
continue;
|
|
19660
19719
|
}
|
|
19661
|
-
if (isCodexFilesystemRuleTable(access)) for (const [nestedPattern, nestedAccess] of Object.entries(access))
|
|
19720
|
+
if (isCodexFilesystemRuleTable(access)) for (const [nestedPattern, nestedAccess] of Object.entries(access)) {
|
|
19721
|
+
if (pattern === CODEX_WORKSPACE_ROOTS_KEY && CODEX_GIT_WRITE_RULES[nestedPattern] === nestedAccess) continue;
|
|
19722
|
+
addRulesyncFilesystemRule(permission, nestedPattern, nestedAccess);
|
|
19723
|
+
}
|
|
19662
19724
|
}
|
|
19663
19725
|
}
|
|
19664
|
-
if (profile?.extends === CODEX_WORKSPACE_BASELINE) {
|
|
19665
|
-
permission.edit ??= {};
|
|
19666
|
-
permission.edit["."] ??= "allow";
|
|
19667
|
-
}
|
|
19668
19726
|
if (profile?.network && profile.network.enabled !== false) {
|
|
19669
19727
|
const networkEnabled = profile.network.enabled === true;
|
|
19670
19728
|
const importedEntries = (profile.network.domains ? Object.entries(profile.network.domains) : []).filter(([, value]) => value === "deny" || networkEnabled);
|
|
@@ -19703,10 +19761,29 @@ function toCodexProfile(value) {
|
|
|
19703
19761
|
};
|
|
19704
19762
|
}
|
|
19705
19763
|
function warnAboutPreservedProfileState({ existingProfile, newProfile, existingDomainsHadUnknown, logger }) {
|
|
19706
|
-
if (existingProfile
|
|
19764
|
+
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)"}".`);
|
|
19765
|
+
warnAboutPreservedNetworkState({
|
|
19766
|
+
existingProfile,
|
|
19767
|
+
newProfile,
|
|
19768
|
+
logger
|
|
19769
|
+
});
|
|
19770
|
+
if (existingDomainsHadUnknown) logger?.warn(`Existing "network.domains" contained unrecognized values. These entries were skipped and will not be imported.`);
|
|
19771
|
+
}
|
|
19772
|
+
function networkHasAllowDomain(network) {
|
|
19773
|
+
return Object.values(network?.domains ?? {}).some((action) => action === "allow");
|
|
19774
|
+
}
|
|
19775
|
+
function warnAboutNetworkEnabledState({ existingProfile, newProfile, logger }) {
|
|
19776
|
+
if (existingProfile?.network?.enabled !== void 0 && newProfile.network?.enabled === void 0 && !networkHasAllowDomain(existingProfile.network)) logger?.warn(`Preserving existing "network.enabled" from config. Review this value manually as it may enable network access beyond the Rulesync-managed domain rules.`);
|
|
19777
|
+
if (existingProfile?.network?.enabled === false && newProfile.network?.enabled === true) logger?.warn(`Existing "network.enabled = false" will be replaced by Rulesync-managed "enabled = true" because the canonical model contains an allow domain.`);
|
|
19778
|
+
}
|
|
19779
|
+
function warnAboutPreservedNetworkState({ existingProfile, newProfile, logger }) {
|
|
19707
19780
|
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.`);
|
|
19781
|
+
warnAboutNetworkEnabledState({
|
|
19782
|
+
existingProfile,
|
|
19783
|
+
newProfile,
|
|
19784
|
+
logger
|
|
19785
|
+
});
|
|
19708
19786
|
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
|
-
if (existingDomainsHadUnknown) logger?.warn(`Existing "network.domains" contained unrecognized values. These entries were skipped and will not be imported.`);
|
|
19710
19787
|
}
|
|
19711
19788
|
const MANAGED_PROFILE_KEYS = /* @__PURE__ */ new Set([
|
|
19712
19789
|
"description",
|
|
@@ -19748,6 +19825,7 @@ function preserveUnmanagedProfileKeys({ rawExistingProfile, profile, logger }) {
|
|
|
19748
19825
|
function mergeWithExistingProfile({ newProfile, existingProfile }) {
|
|
19749
19826
|
if (!existingProfile) return newProfile;
|
|
19750
19827
|
const mergedNetwork = { ...newProfile.network };
|
|
19828
|
+
if (existingProfile.network?.enabled !== void 0 && mergedNetwork.enabled === void 0 && !networkHasAllowDomain(existingProfile.network)) mergedNetwork.enabled = existingProfile.network.enabled;
|
|
19751
19829
|
if (existingProfile.network?.mode !== void 0 && mergedNetwork.mode === void 0) mergedNetwork.mode = existingProfile.network.mode;
|
|
19752
19830
|
if (existingProfile.network?.unix_sockets !== void 0 && mergedNetwork.unix_sockets === void 0) mergedNetwork.unix_sockets = existingProfile.network.unix_sockets;
|
|
19753
19831
|
const hasNetwork = Object.keys(mergedNetwork).length > 0;
|
|
@@ -19797,20 +19875,26 @@ function isPlainObject(value) {
|
|
|
19797
19875
|
}
|
|
19798
19876
|
function computeCodexcliOverridePatch({ existing, override, logger }) {
|
|
19799
19877
|
const patch = {};
|
|
19800
|
-
if (!override) return patch;
|
|
19801
19878
|
const allowed = new Set(CODEXCLI_OVERRIDE_KEYS);
|
|
19802
|
-
for (const [key, value] of Object.entries(override)) {
|
|
19879
|
+
for (const [key, value] of Object.entries(override ?? {})) {
|
|
19880
|
+
if (key === "base_permission_profile" || key === "git_write_rules") continue;
|
|
19803
19881
|
if (!allowed.has(key)) {
|
|
19804
19882
|
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
19883
|
continue;
|
|
19806
19884
|
}
|
|
19807
19885
|
if (value === void 0) continue;
|
|
19886
|
+
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
19887
|
const existingValue = existing[key];
|
|
19809
19888
|
patch[key] = isPlainObject(existingValue) && isPlainObject(value) ? {
|
|
19810
19889
|
...existingValue,
|
|
19811
19890
|
...value
|
|
19812
19891
|
} : value;
|
|
19813
19892
|
}
|
|
19893
|
+
const defaults = {
|
|
19894
|
+
approval_policy: CODEX_DEFAULT_APPROVAL_POLICY,
|
|
19895
|
+
approvals_reviewer: CODEX_DEFAULT_APPROVALS_REVIEWER
|
|
19896
|
+
};
|
|
19897
|
+
for (const [key, value] of Object.entries(defaults)) if (patch[key] === void 0 && existing[key] === void 0) patch[key] = value;
|
|
19814
19898
|
return patch;
|
|
19815
19899
|
}
|
|
19816
19900
|
function extractCodexcliOverride(table) {
|
|
@@ -28433,6 +28517,24 @@ var ReasonixSkill = class ReasonixSkill extends ToolSkill {
|
|
|
28433
28517
|
global: loaded.global
|
|
28434
28518
|
});
|
|
28435
28519
|
}
|
|
28520
|
+
/**
|
|
28521
|
+
* Whether the skill directory belongs to the skills feature.
|
|
28522
|
+
*
|
|
28523
|
+
* `.reasonix/skills/` is shared with the subagents feature: a directory whose
|
|
28524
|
+
* SKILL.md declares `runAs: subagent` is a subagent profile, not a regular
|
|
28525
|
+
* skill, so it must be neither imported as a skill nor deleted as an orphan
|
|
28526
|
+
* skill. Directories without a readable/parsable SKILL.md keep the default
|
|
28527
|
+
* skills-feature ownership, matching the previous behavior for such dirs.
|
|
28528
|
+
*/
|
|
28529
|
+
static async isDirOwned({ outputRoot, relativeDirPath, dirName }) {
|
|
28530
|
+
const skillFilePath = join(outputRoot, relativeDirPath, dirName, SKILL_FILE_NAME);
|
|
28531
|
+
try {
|
|
28532
|
+
const { frontmatter } = parseFrontmatter(await readFileContent(skillFilePath), skillFilePath);
|
|
28533
|
+
return frontmatter["runAs"] !== REASONIX_SUBAGENT_RUN_AS;
|
|
28534
|
+
} catch {
|
|
28535
|
+
return true;
|
|
28536
|
+
}
|
|
28537
|
+
}
|
|
28436
28538
|
static forDeletion({ outputRoot = process.cwd(), relativeDirPath, dirName, global = false }) {
|
|
28437
28539
|
return new ReasonixSkill({
|
|
28438
28540
|
outputRoot,
|
|
@@ -29731,6 +29833,11 @@ var SkillsProcessor = class extends DirFeatureProcessor {
|
|
|
29731
29833
|
for (const dirPath of dirPaths) {
|
|
29732
29834
|
const dirName = basename(dirPath);
|
|
29733
29835
|
if (seenDirNames.has(dirName)) continue;
|
|
29836
|
+
if (factory.class.isDirOwned && !await factory.class.isDirOwned({
|
|
29837
|
+
outputRoot: this.outputRoot,
|
|
29838
|
+
relativeDirPath: root,
|
|
29839
|
+
dirName
|
|
29840
|
+
})) continue;
|
|
29734
29841
|
seenDirNames.add(dirName);
|
|
29735
29842
|
loadEntries.push({
|
|
29736
29843
|
root,
|
|
@@ -29757,6 +29864,11 @@ var SkillsProcessor = class extends DirFeatureProcessor {
|
|
|
29757
29864
|
const dirPaths = await findFilesByGlobs(join(skillsDirPath, "*"), { type: "dir" });
|
|
29758
29865
|
for (const dirPath of dirPaths) {
|
|
29759
29866
|
const dirName = basename(dirPath);
|
|
29867
|
+
if (factory.class.isDirOwned && !await factory.class.isDirOwned({
|
|
29868
|
+
outputRoot: this.outputRoot,
|
|
29869
|
+
relativeDirPath: root,
|
|
29870
|
+
dirName
|
|
29871
|
+
})) continue;
|
|
29760
29872
|
const toolSkill = factory.class.forDeletion({
|
|
29761
29873
|
outputRoot: this.outputRoot,
|
|
29762
29874
|
relativeDirPath: root,
|
|
@@ -33056,6 +33168,188 @@ var OpenCodeSubagent = class OpenCodeSubagent extends OpenCodeStyleSubagent {
|
|
|
33056
33168
|
}
|
|
33057
33169
|
};
|
|
33058
33170
|
//#endregion
|
|
33171
|
+
//#region src/features/subagents/reasonix-subagent.ts
|
|
33172
|
+
const ReasonixSubagentFrontmatterSchema = z.looseObject({
|
|
33173
|
+
name: z.string(),
|
|
33174
|
+
description: z.optional(z.string()),
|
|
33175
|
+
invocation: z.optional(z.string()),
|
|
33176
|
+
runAs: z.optional(z.string()),
|
|
33177
|
+
model: z.optional(z.string()),
|
|
33178
|
+
effort: z.optional(z.string()),
|
|
33179
|
+
"allowed-tools": z.optional(z.array(z.string())),
|
|
33180
|
+
color: z.optional(z.string())
|
|
33181
|
+
});
|
|
33182
|
+
/**
|
|
33183
|
+
* Represents a DeepSeek-Reasonix subagent profile.
|
|
33184
|
+
*
|
|
33185
|
+
* Reasonix discovers subagents as directory-layout Skills (`<name>/SKILL.md`)
|
|
33186
|
+
* under `.reasonix/skills/` (project) and `~/.reasonix/skills/` (global); the
|
|
33187
|
+
* global scope is served by the processor supplying the home directory as
|
|
33188
|
+
* outputRoot, so the relative directory path is identical for both scopes. A
|
|
33189
|
+
* subagent is a Skill whose frontmatter declares `invocation: manual` and
|
|
33190
|
+
* `runAs: subagent`.
|
|
33191
|
+
*
|
|
33192
|
+
* @see https://github.com/esengine/DeepSeek-Reasonix/blob/main-v2/docs/SUBAGENT_PROFILES.md
|
|
33193
|
+
*/
|
|
33194
|
+
var ReasonixSubagent = class ReasonixSubagent extends ToolSubagent {
|
|
33195
|
+
frontmatter;
|
|
33196
|
+
body;
|
|
33197
|
+
constructor({ frontmatter, body, fileContent, ...rest }) {
|
|
33198
|
+
if (rest.validate !== false) {
|
|
33199
|
+
const result = ReasonixSubagentFrontmatterSchema.safeParse(frontmatter);
|
|
33200
|
+
if (!result.success) throw new Error(`Invalid frontmatter in ${join(rest.relativeDirPath, rest.relativeFilePath)}: ${formatError(result.error)}`);
|
|
33201
|
+
}
|
|
33202
|
+
super({
|
|
33203
|
+
...rest,
|
|
33204
|
+
fileContent: fileContent ?? stringifyFrontmatter(body, frontmatter)
|
|
33205
|
+
});
|
|
33206
|
+
this.frontmatter = frontmatter;
|
|
33207
|
+
this.body = body;
|
|
33208
|
+
}
|
|
33209
|
+
static getSettablePaths({ global: _global = false } = {}) {
|
|
33210
|
+
return { relativeDirPath: REASONIX_SUBAGENTS_DIR_PATH };
|
|
33211
|
+
}
|
|
33212
|
+
getFrontmatter() {
|
|
33213
|
+
return this.frontmatter;
|
|
33214
|
+
}
|
|
33215
|
+
getBody() {
|
|
33216
|
+
return this.body;
|
|
33217
|
+
}
|
|
33218
|
+
toRulesyncSubagent() {
|
|
33219
|
+
const { name, description, invocation: _invocation, runAs: _runAs, ...restFields } = this.frontmatter;
|
|
33220
|
+
const reasonixSection = { ...restFields };
|
|
33221
|
+
const rulesyncFrontmatter = {
|
|
33222
|
+
targets: ["*"],
|
|
33223
|
+
name,
|
|
33224
|
+
description,
|
|
33225
|
+
...Object.keys(reasonixSection).length > 0 && { reasonix: reasonixSection }
|
|
33226
|
+
};
|
|
33227
|
+
return new RulesyncSubagent({
|
|
33228
|
+
outputRoot: this.getOutputRoot(),
|
|
33229
|
+
frontmatter: rulesyncFrontmatter,
|
|
33230
|
+
body: this.body,
|
|
33231
|
+
relativeDirPath: RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH,
|
|
33232
|
+
relativeFilePath: `${this.getSubagentName()}.md`,
|
|
33233
|
+
validate: true
|
|
33234
|
+
});
|
|
33235
|
+
}
|
|
33236
|
+
/**
|
|
33237
|
+
* Derive the subagent name from this instance's relative file path.
|
|
33238
|
+
*
|
|
33239
|
+
* The tool-side layout is `<name>/SKILL.md`, so the name is the parent
|
|
33240
|
+
* directory of the file. If the path is unexpectedly flat (e.g. a legacy
|
|
33241
|
+
* `<name>.md`), fall back to the basename without extension.
|
|
33242
|
+
*/
|
|
33243
|
+
getSubagentName() {
|
|
33244
|
+
const relativeFilePath = this.getRelativeFilePath();
|
|
33245
|
+
const dir = dirname(relativeFilePath);
|
|
33246
|
+
if (dir && dir !== ".") return basename(dir);
|
|
33247
|
+
return basename(relativeFilePath, extname(relativeFilePath));
|
|
33248
|
+
}
|
|
33249
|
+
static fromRulesyncSubagent({ outputRoot = process.cwd(), rulesyncSubagent, validate = true, global = false }) {
|
|
33250
|
+
const rulesyncFrontmatter = rulesyncSubagent.getFrontmatter();
|
|
33251
|
+
const reasonixSection = this.filterToolSpecificSection(rulesyncFrontmatter.reasonix ?? {}, ["name", "description"]);
|
|
33252
|
+
const rawReasonixFrontmatter = {
|
|
33253
|
+
name: rulesyncFrontmatter.name,
|
|
33254
|
+
description: rulesyncFrontmatter.description,
|
|
33255
|
+
...reasonixSection,
|
|
33256
|
+
invocation: REASONIX_SUBAGENT_INVOCATION,
|
|
33257
|
+
runAs: REASONIX_SUBAGENT_RUN_AS
|
|
33258
|
+
};
|
|
33259
|
+
const result = ReasonixSubagentFrontmatterSchema.safeParse(rawReasonixFrontmatter);
|
|
33260
|
+
if (!result.success) throw new Error(`Invalid reasonix subagent frontmatter in ${rulesyncSubagent.getRelativeFilePath()}: ${formatError(result.error)}`);
|
|
33261
|
+
const reasonixFrontmatter = result.data;
|
|
33262
|
+
const body = rulesyncSubagent.getBody();
|
|
33263
|
+
const fileContent = stringifyFrontmatter(body, reasonixFrontmatter);
|
|
33264
|
+
const paths = this.getSettablePaths({ global });
|
|
33265
|
+
const subagentName = basename(rulesyncSubagent.getRelativeFilePath(), extname(rulesyncSubagent.getRelativeFilePath()));
|
|
33266
|
+
return new ReasonixSubagent({
|
|
33267
|
+
outputRoot,
|
|
33268
|
+
frontmatter: reasonixFrontmatter,
|
|
33269
|
+
body,
|
|
33270
|
+
relativeDirPath: paths.relativeDirPath,
|
|
33271
|
+
relativeFilePath: join(subagentName, SKILL_FILE_NAME),
|
|
33272
|
+
fileContent,
|
|
33273
|
+
validate,
|
|
33274
|
+
global
|
|
33275
|
+
});
|
|
33276
|
+
}
|
|
33277
|
+
validate() {
|
|
33278
|
+
if (!this.frontmatter) return {
|
|
33279
|
+
success: true,
|
|
33280
|
+
error: null
|
|
33281
|
+
};
|
|
33282
|
+
const result = ReasonixSubagentFrontmatterSchema.safeParse(this.frontmatter);
|
|
33283
|
+
if (result.success) return {
|
|
33284
|
+
success: true,
|
|
33285
|
+
error: null
|
|
33286
|
+
};
|
|
33287
|
+
else return {
|
|
33288
|
+
success: false,
|
|
33289
|
+
error: /* @__PURE__ */ new Error(`Invalid frontmatter in ${join(this.relativeDirPath, this.relativeFilePath)}: ${formatError(result.error)}`)
|
|
33290
|
+
};
|
|
33291
|
+
}
|
|
33292
|
+
static isTargetedByRulesyncSubagent(rulesyncSubagent) {
|
|
33293
|
+
return this.isTargetedByRulesyncSubagentDefault({
|
|
33294
|
+
rulesyncSubagent,
|
|
33295
|
+
toolTarget: "reasonix"
|
|
33296
|
+
});
|
|
33297
|
+
}
|
|
33298
|
+
static async fromFile({ outputRoot = process.cwd(), relativeFilePath, validate = true, global = false }) {
|
|
33299
|
+
const paths = this.getSettablePaths({ global });
|
|
33300
|
+
const filePath = join(outputRoot, paths.relativeDirPath, relativeFilePath);
|
|
33301
|
+
const fileContent = await readFileContent(filePath);
|
|
33302
|
+
const { frontmatter, body: content } = parseFrontmatter(fileContent, filePath);
|
|
33303
|
+
const result = ReasonixSubagentFrontmatterSchema.safeParse(frontmatter);
|
|
33304
|
+
if (!result.success) throw new Error(`Invalid frontmatter in ${filePath}: ${formatError(result.error)}`);
|
|
33305
|
+
return new ReasonixSubagent({
|
|
33306
|
+
outputRoot,
|
|
33307
|
+
relativeDirPath: paths.relativeDirPath,
|
|
33308
|
+
relativeFilePath,
|
|
33309
|
+
frontmatter: result.data,
|
|
33310
|
+
body: content.trim(),
|
|
33311
|
+
fileContent,
|
|
33312
|
+
validate,
|
|
33313
|
+
global
|
|
33314
|
+
});
|
|
33315
|
+
}
|
|
33316
|
+
/**
|
|
33317
|
+
* Whether the SKILL.md at the given path is a subagent profile.
|
|
33318
|
+
*
|
|
33319
|
+
* `.reasonix/skills/` is shared with the skills feature: a regular skill and
|
|
33320
|
+
* a subagent profile differ only by their frontmatter markers. Only files
|
|
33321
|
+
* carrying `runAs: subagent` belong to this feature, so regular skills are
|
|
33322
|
+
* neither imported as subagents nor deleted as orphans by the subagents
|
|
33323
|
+
* feature. `runAs` alone is checked (not `invocation`) because it is the
|
|
33324
|
+
* marker that switches the execution mode; generation always emits both.
|
|
33325
|
+
* Unreadable or unparsable files are treated as not owned, erring on the
|
|
33326
|
+
* side of leaving foreign files untouched.
|
|
33327
|
+
*/
|
|
33328
|
+
static async isFileOwned({ outputRoot, relativeDirPath, relativeFilePath }) {
|
|
33329
|
+
const filePath = join(outputRoot, relativeDirPath, relativeFilePath);
|
|
33330
|
+
try {
|
|
33331
|
+
const { frontmatter } = parseFrontmatter(await readFileContent(filePath), filePath);
|
|
33332
|
+
return frontmatter["runAs"] === REASONIX_SUBAGENT_RUN_AS;
|
|
33333
|
+
} catch {
|
|
33334
|
+
return false;
|
|
33335
|
+
}
|
|
33336
|
+
}
|
|
33337
|
+
static forDeletion({ outputRoot = process.cwd(), relativeDirPath, relativeFilePath }) {
|
|
33338
|
+
return new ReasonixSubagent({
|
|
33339
|
+
outputRoot,
|
|
33340
|
+
relativeDirPath,
|
|
33341
|
+
relativeFilePath,
|
|
33342
|
+
frontmatter: {
|
|
33343
|
+
name: "",
|
|
33344
|
+
description: ""
|
|
33345
|
+
},
|
|
33346
|
+
body: "",
|
|
33347
|
+
fileContent: "",
|
|
33348
|
+
validate: false
|
|
33349
|
+
});
|
|
33350
|
+
}
|
|
33351
|
+
};
|
|
33352
|
+
//#endregion
|
|
33059
33353
|
//#region src/features/subagents/roo-subagent.ts
|
|
33060
33354
|
/**
|
|
33061
33355
|
* Default tool groups assigned to a generated mode when the rulesync source
|
|
@@ -33690,6 +33984,14 @@ const toolSubagentFactories = /* @__PURE__ */ new Map([
|
|
|
33690
33984
|
filePattern: "*.md"
|
|
33691
33985
|
}
|
|
33692
33986
|
}],
|
|
33987
|
+
["reasonix", {
|
|
33988
|
+
class: ReasonixSubagent,
|
|
33989
|
+
meta: {
|
|
33990
|
+
supportsSimulated: false,
|
|
33991
|
+
supportsGlobal: true,
|
|
33992
|
+
filePattern: join("*", "SKILL.md")
|
|
33993
|
+
}
|
|
33994
|
+
}],
|
|
33693
33995
|
["roo", {
|
|
33694
33996
|
class: RooSubagent,
|
|
33695
33997
|
meta: {
|
|
@@ -33842,8 +34144,17 @@ var SubagentsProcessor = class extends FeatureProcessor {
|
|
|
33842
34144
|
const baseDir = join(this.outputRoot, dirPath);
|
|
33843
34145
|
const subagentFilePaths = await findFilesByGlobs(join(baseDir, factory.meta.filePattern));
|
|
33844
34146
|
const toRelativeFilePath = (path) => relative(baseDir, path);
|
|
34147
|
+
let ownedFilePaths = subagentFilePaths;
|
|
34148
|
+
if (factory.class.isFileOwned) {
|
|
34149
|
+
const ownership = await Promise.all(subagentFilePaths.map((path) => factory.class.isFileOwned({
|
|
34150
|
+
outputRoot: this.outputRoot,
|
|
34151
|
+
relativeDirPath: dirPath,
|
|
34152
|
+
relativeFilePath: toRelativeFilePath(path)
|
|
34153
|
+
})));
|
|
34154
|
+
ownedFilePaths = subagentFilePaths.filter((_, index) => ownership[index]);
|
|
34155
|
+
}
|
|
33845
34156
|
if (forDeletion) {
|
|
33846
|
-
toolSubagents.push(...
|
|
34157
|
+
toolSubagents.push(...ownedFilePaths.map((path) => factory.class.forDeletion({
|
|
33847
34158
|
outputRoot: this.outputRoot,
|
|
33848
34159
|
relativeDirPath: dirPath,
|
|
33849
34160
|
relativeFilePath: toRelativeFilePath(path),
|
|
@@ -33851,7 +34162,7 @@ var SubagentsProcessor = class extends FeatureProcessor {
|
|
|
33851
34162
|
})).filter((subagent) => subagent.isDeletable()));
|
|
33852
34163
|
continue;
|
|
33853
34164
|
}
|
|
33854
|
-
const loaded = await Promise.all(
|
|
34165
|
+
const loaded = await Promise.all(ownedFilePaths.map((path) => factory.class.fromFile({
|
|
33855
34166
|
outputRoot: this.outputRoot,
|
|
33856
34167
|
relativeDirPath: dirPath,
|
|
33857
34168
|
relativeFilePath: toRelativeFilePath(path),
|
|
@@ -39670,11 +39981,51 @@ const GENERATION_STEP_GRAPH = [
|
|
|
39670
39981
|
}
|
|
39671
39982
|
];
|
|
39672
39983
|
/**
|
|
39984
|
+
* Warn when a rulesync skill and a rulesync subagent share a name for a tool
|
|
39985
|
+
* that emits both features into the same directory (e.g. Reasonix, where both
|
|
39986
|
+
* write `<name>/SKILL.md` under `.reasonix/skills/`). The colliding outputs
|
|
39987
|
+
* target the same on-disk file, so whichever generation step runs later
|
|
39988
|
+
* silently overwrites the other's file.
|
|
39989
|
+
*/
|
|
39990
|
+
async function warnSkillSubagentNameCollisions(params) {
|
|
39991
|
+
const { config, logger } = params;
|
|
39992
|
+
const global = config.getGlobal();
|
|
39993
|
+
for (const toolTarget of config.getTargets()) {
|
|
39994
|
+
const features = config.getFeatures(toolTarget);
|
|
39995
|
+
if (!features.includes("skills") || !features.includes("subagents")) continue;
|
|
39996
|
+
if (!SubagentsProcessor.getToolTargets({ global }).includes(toolTarget) || !SkillsProcessor.getToolTargets({ global }).includes(toolTarget)) continue;
|
|
39997
|
+
const subagentFactory = SubagentsProcessor.getFactory(toolTarget);
|
|
39998
|
+
const skillFactory = SkillsProcessor.getFactory(toolTarget);
|
|
39999
|
+
if (!subagentFactory || !skillFactory) continue;
|
|
40000
|
+
const subagentsDirPath = subagentFactory.class.getSettablePaths({ global }).relativeDirPath;
|
|
40001
|
+
if (subagentsDirPath !== skillFactory.class.getSettablePaths({ global }).relativeDirPath) continue;
|
|
40002
|
+
const subagentsProcessor = new SubagentsProcessor({
|
|
40003
|
+
inputRoot: config.getInputRoot(),
|
|
40004
|
+
toolTarget,
|
|
40005
|
+
global,
|
|
40006
|
+
logger
|
|
40007
|
+
});
|
|
40008
|
+
const subagentNames = new Set((await subagentsProcessor.loadRulesyncFiles()).filter((file) => file instanceof RulesyncSubagent).filter((file) => subagentFactory.class.isTargetedByRulesyncSubagent(file)).map((file) => basename(file.getRelativeFilePath(), extname(file.getRelativeFilePath()))));
|
|
40009
|
+
if (subagentNames.size === 0) continue;
|
|
40010
|
+
const skillNames = (await new SkillsProcessor({
|
|
40011
|
+
inputRoot: config.getInputRoot(),
|
|
40012
|
+
toolTarget,
|
|
40013
|
+
global,
|
|
40014
|
+
logger
|
|
40015
|
+
}).loadRulesyncDirs()).filter((dir) => dir instanceof RulesyncSkill).filter((skill) => skillFactory.class.isTargetedByRulesyncSkill(skill)).map((skill) => skill.getDirName());
|
|
40016
|
+
for (const name of skillNames) if (subagentNames.has(name)) logger.warn(`Skill "${name}" and subagent "${name}" both target '${toolTarget}' and write the same path '${join(subagentsDirPath, name)}'; the later generation step overwrites the other's output. Rename one of them or narrow their targets.`);
|
|
40017
|
+
}
|
|
40018
|
+
}
|
|
40019
|
+
/**
|
|
39673
40020
|
* Generate configuration files for AI tools.
|
|
39674
40021
|
* @throws Error if generation fails
|
|
39675
40022
|
*/
|
|
39676
40023
|
async function generate(params) {
|
|
39677
40024
|
const { config, logger } = params;
|
|
40025
|
+
await warnSkillSubagentNameCollisions({
|
|
40026
|
+
config,
|
|
40027
|
+
logger
|
|
40028
|
+
});
|
|
39678
40029
|
let skillsResult;
|
|
39679
40030
|
const runners = {
|
|
39680
40031
|
ignore: () => generateIgnoreCore({
|
|
@@ -40388,4 +40739,4 @@ async function importPermissionsCore(params) {
|
|
|
40388
40739
|
//#endregion
|
|
40389
40740
|
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
40741
|
|
|
40391
|
-
//# sourceMappingURL=import-
|
|
40742
|
+
//# sourceMappingURL=import-hM4jDZn1.js.map
|