@intellectronica/ruler 0.3.38 → 0.3.40

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/dist/lib.js CHANGED
@@ -53,6 +53,23 @@ function resolveSkillsEnabled(cliFlag, configSetting) {
53
53
  ? configSetting
54
54
  : true; // default to enabled
55
55
  }
56
+ /**
57
+ * Resolves subagents enabled state based on precedence:
58
+ * CLI flag > ruler.toml > default (disabled).
59
+ *
60
+ * When neither `[agents] enabled` (nor the legacy `[subagents] enabled`)
61
+ * nor a CLI flag is provided, propagation is disabled by default per spec.
62
+ * Subagent definitions are an opt-in feature — propagating them silently
63
+ * could leak runtime prompts into native subagent locations on projects
64
+ * that never intended to use the feature.
65
+ */
66
+ function resolveSubagentsEnabled(cliFlag, configSetting) {
67
+ return cliFlag !== undefined
68
+ ? cliFlag
69
+ : configSetting !== undefined
70
+ ? configSetting
71
+ : false; // default to disabled — see spec: subagents must opt in
72
+ }
56
73
  /**
57
74
  * Applies ruler configurations for all supported AI agents.
58
75
  * @param projectRoot Root directory of the project
@@ -62,7 +79,7 @@ function resolveSkillsEnabled(cliFlag, configSetting) {
62
79
  * @param projectRoot Root directory of the project
63
80
  * @param includedAgents Optional list of agent name filters (case-insensitive substrings)
64
81
  */
65
- async function applyAllAgentConfigs(projectRoot, includedAgents, configPath, cliMcpEnabled = true, cliMcpStrategy, cliGitignoreEnabled, verbose = false, dryRun = false, localOnly = false, nested = false, backup = true, skillsEnabled, cliGitignoreLocal) {
82
+ async function applyAllAgentConfigs(projectRoot, includedAgents, configPath, cliMcpEnabled = true, cliMcpStrategy, cliGitignoreEnabled, verbose = false, dryRun = false, localOnly = false, nested = false, backup = true, skillsEnabled, cliGitignoreLocal, subagentsEnabled) {
66
83
  // Load configuration and rules
67
84
  (0, constants_1.logVerbose)(`Loading configuration from project root: ${projectRoot}`, verbose);
68
85
  if (configPath) {
@@ -100,6 +117,16 @@ async function applyAllAgentConfigs(projectRoot, includedAgents, configPath, cli
100
117
  await propagateSkills(nestedRoot, selectedAgents, skillsEnabledResolved, verbose, dryRun);
101
118
  }
102
119
  }
120
+ // Propagate subagents (mirrors skills handling for nested mode).
121
+ const subagentsEnabledResolved = resolveSubagentsEnabled(subagentsEnabled, rootConfig.subagents?.enabled);
122
+ {
123
+ const { propagateSubagents } = await Promise.resolve().then(() => __importStar(require('./core/SubagentsProcessor')));
124
+ for (const configEntry of hierarchicalConfigs) {
125
+ const nestedRoot = path.dirname(configEntry.rulerDir);
126
+ (0, constants_1.logVerbose)(`Propagating subagents for nested directory: ${nestedRoot}`, verbose);
127
+ await propagateSubagents(nestedRoot, selectedAgents, subagentsEnabledResolved, verbose, dryRun);
128
+ }
129
+ }
103
130
  generatedPaths = await (0, apply_engine_1.processHierarchicalConfigurations)(selectedAgents, hierarchicalConfigs, verbose, dryRun, cliMcpEnabled, cliMcpStrategy, backup);
104
131
  }
105
132
  else {
@@ -117,6 +144,12 @@ async function applyAllAgentConfigs(projectRoot, includedAgents, configPath, cli
117
144
  const { propagateSkills } = await Promise.resolve().then(() => __importStar(require('./core/SkillsProcessor')));
118
145
  await propagateSkills(projectRoot, selectedAgents, skillsEnabledResolved, verbose, dryRun);
119
146
  }
147
+ // Propagate subagents (mirrors skills handling).
148
+ const subagentsEnabledResolvedSingle = resolveSubagentsEnabled(subagentsEnabled, singleConfig.config.subagents?.enabled);
149
+ {
150
+ const { propagateSubagents } = await Promise.resolve().then(() => __importStar(require('./core/SubagentsProcessor')));
151
+ await propagateSubagents(projectRoot, selectedAgents, subagentsEnabledResolvedSingle, verbose, dryRun);
152
+ }
120
153
  generatedPaths = await (0, apply_engine_1.processSingleConfiguration)(selectedAgents, singleConfig, projectRoot, verbose, dryRun, cliMcpEnabled, cliMcpStrategy, backup);
121
154
  }
122
155
  // Add skills-generated paths to gitignore if skills are enabled
@@ -126,7 +159,14 @@ async function applyAllAgentConfigs(projectRoot, includedAgents, configPath, cli
126
159
  // Skills enabled by default or explicitly
127
160
  const { getSkillsGitignorePaths } = await Promise.resolve().then(() => __importStar(require('./core/SkillsProcessor')));
128
161
  const skillsPaths = await getSkillsGitignorePaths(projectRoot, selectedAgents);
129
- allGeneratedPaths = [...generatedPaths, ...skillsPaths];
162
+ allGeneratedPaths = [...allGeneratedPaths, ...skillsPaths];
163
+ }
164
+ // Add subagents-generated paths to gitignore if subagents are enabled.
165
+ const subagentsEnabledForGitignore = resolveSubagentsEnabled(subagentsEnabled, loadedConfig.subagents?.enabled);
166
+ if (subagentsEnabledForGitignore) {
167
+ const { getSubagentsGitignorePaths } = await Promise.resolve().then(() => __importStar(require('./core/SubagentsProcessor')));
168
+ const subagentPaths = await getSubagentsGitignorePaths(projectRoot, selectedAgents);
169
+ allGeneratedPaths = [...allGeneratedPaths, ...subagentPaths];
130
170
  }
131
171
  await (0, apply_engine_1.updateGitignore)(projectRoot, allGeneratedPaths, loadedConfig, cliGitignoreEnabled, dryRun, cliGitignoreLocal);
132
172
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@intellectronica/ruler",
3
- "version": "0.3.38",
3
+ "version": "0.3.40",
4
4
  "description": "Ruler — apply the same rules to all coding agents",
5
5
  "main": "dist/lib.js",
6
6
  "scripts": {