use "rule profiles" instead of "rules profiles"
This commit is contained in:
@@ -5,8 +5,8 @@
|
||||
Added comprehensive rules profile management:
|
||||
|
||||
- **Initialization**: You can now specify which rule profiles to include at project initialization using `--rules <profiles>` or `-r <profiles>` (e.g., `task-master init -r cursor,roo`). Only the selected profiles and configuration are included.
|
||||
- **Add/Remove Commands**: `task-master rules add <profiles>` and `task-master rules remove <profiles>` let you manage specific rules profiles and MCP config after initialization, supporting multiple profiles at once.
|
||||
- **Interactive Setup**: `task-master rules setup` launches an interactive prompt to select which rules profiles to add to your project. This does **not** re-initialize your project or affect shell aliases; it only manages rules.
|
||||
- **Add/Remove Commands**: `task-master rules add <profiles>` and `task-master rules remove <profiles>` let you manage specific rule profiles and MCP config after initialization, supporting multiple profiles at once.
|
||||
- **Interactive Setup**: `task-master rules setup` launches an interactive prompt to select which rule profiles to add to your project. This does **not** re-initialize your project or affect shell aliases; it only manages rules.
|
||||
- **Selective Removal**: Rules removal intelligently preserves existing non-Task Master rules and files and only removes Task Master-specific rules. Profile directories are only removed when completely empty and all conditions are met (no existing rules, no other files/folders, MCP config completely removed).
|
||||
- **Safety Features**: Confirmation messages clearly explain that only Task Master-specific rules and MCP configurations will be removed, while preserving existing custom rules and other files.
|
||||
- **Robust Validation**: Includes comprehensive checks for array types in MCP config processing and error handling throughout the rules management system.
|
||||
|
||||
@@ -23,7 +23,7 @@ This document provides a detailed reference for interacting with Taskmaster, cov
|
||||
* Example: `task-master init -r roo`
|
||||
* **What happens:**
|
||||
* For each, creates the appropriate rules directory (e.g., `.roo/rules`) and MCP config (e.g., `.roo/mcp.json`).
|
||||
* If not specified, all rules profiles are initialized by default.
|
||||
* If not specified, all rule profiles are initialized by default.
|
||||
|
||||
|
||||
* **MCP Tool:** `initialize_project`
|
||||
|
||||
@@ -23,7 +23,7 @@ This document provides a detailed reference for interacting with Taskmaster, cov
|
||||
* Example: `task-master init -r roo`
|
||||
* **What happens:**
|
||||
* For each, creates the appropriate rules directory (e.g., `.roo/rules`) and MCP config (e.g., `.roo/mcp.json`).
|
||||
* If not specified, all rules profiles are initialized by default.
|
||||
* If not specified, all rule profiles are initialized by default.
|
||||
|
||||
|
||||
* **MCP Tool:** `initialize_project`
|
||||
|
||||
@@ -239,20 +239,14 @@ task-master init
|
||||
task-master init --rules cursor,windsurf
|
||||
```
|
||||
|
||||
- The `--rules` flag allows you to specify one or more rule sets (e.g., `cursor`, `roo`, `windsurf`, `cline`) to apply during initialization.
|
||||
- If omitted, all available rule sets are installed by default (cursor, windsurf, roo, cline).
|
||||
- You can use multiple comma-separated rules in a single command.
|
||||
|
||||
**Example:**
|
||||
|
||||
```bash
|
||||
task-master init --rules cursor,roo
|
||||
```
|
||||
- The `--rules` flag allows you to specify one or more rule profiles (e.g., `cursor`, `roo`, `windsurf`, `cline`) to apply during initialization.
|
||||
- If omitted, all available rule profiles are installed by default (cursor, windsurf, roo, cline).
|
||||
- You can use multiple comma-separated profiles in a single command.
|
||||
|
||||
## Manage Rules
|
||||
|
||||
```bash
|
||||
# Add rule sets to your project
|
||||
# Add rule profiles to your project
|
||||
# (e.g., .roo/rules, .windsurf/rules)
|
||||
task-master rules add <profile1,profile2,...>
|
||||
|
||||
@@ -267,9 +261,9 @@ task-master rules remove <profile1,profile2,...> --force
|
||||
task-master rules setup
|
||||
```
|
||||
|
||||
- Adding rules creates the rules directory (e.g., `.roo/rules`) and copies/initializes the rules.
|
||||
- Removing rules deletes the rules directory and associated MCP config.
|
||||
- **Safety Check**: Attempting to remove ALL rules profiles will trigger a critical warning requiring confirmation. Use `--force` to bypass.
|
||||
- Adding rules creates the profile and rules directory (e.g., `.roo/rules`) and copies/initializes the rules.
|
||||
- Removing rules deletes the profile and rules directory and associated MCP config.
|
||||
- **Safety Check**: Attempting to remove rule profiles will trigger a critical warning requiring confirmation. Use `--force` to bypass.
|
||||
- You can use multiple comma-separated rules in a single command.
|
||||
- The `setup` action launches an interactive prompt to select which rules to apply. The list of rules is always current with the available profiles, and no manual updates are needed. This command does **not** re-initialize your project or affect shell aliases; it only manages rules interactively.
|
||||
|
||||
@@ -289,9 +283,9 @@ You can launch the interactive rules setup at any time with:
|
||||
task-master rules setup
|
||||
```
|
||||
|
||||
This command opens a prompt where you can select which rules (e.g., Cursor, Roo, Windsurf) you want to apply to your project. The list of rules is always current with the available profiles—no manual updates needed. This does **not** re-initialize your project or ask about shell aliases; it only manages rules.
|
||||
This command opens a prompt where you can select which rule profiles (e.g., Cursor, Roo, Windsurf) you want to add to your project. This does **not** re-initialize your project or ask about shell aliases; it only manages rules.
|
||||
|
||||
- Use this command to add rules interactively after project creation.
|
||||
- Use this command to add rule profiles interactively after project creation.
|
||||
- The same interactive prompt is also used during `init` if you don't specify rules with `--rules`.
|
||||
|
||||
## Configure AI Models
|
||||
|
||||
@@ -5,7 +5,7 @@ import {
|
||||
// isSilentMode // Not used directly here
|
||||
} from '../../../../scripts/modules/utils.js';
|
||||
import os from 'os'; // Import os module for home directory check
|
||||
import { RULES_PROFILES } from '../../../../src/constants/profiles.js';
|
||||
import { RULE_PROFILES } from '../../../../src/constants/profiles.js';
|
||||
import { convertAllRulesToProfileRules } from '../../../../src/utils/rule-transformer.js';
|
||||
|
||||
/**
|
||||
@@ -76,9 +76,9 @@ export async function initializeProjectDirect(args, log, context = {}) {
|
||||
options.rules = args.rules;
|
||||
log.info(`Including rules: ${args.rules.join(', ')}`);
|
||||
} else {
|
||||
options.rules = RULES_PROFILES;
|
||||
options.rules = RULE_PROFILES;
|
||||
log.info(
|
||||
`No rules profiles specified, defaulting to: ${RULES_PROFILES.join(', ')}`
|
||||
`No rule profiles specified, defaulting to: ${RULE_PROFILES.join(', ')}`
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ import {
|
||||
getRulesProfile,
|
||||
isValidProfile
|
||||
} from '../../../../src/utils/rule-transformer.js';
|
||||
import { RULES_PROFILES } from '../../../../src/constants/profiles.js';
|
||||
import { RULE_PROFILES } from '../../../../src/constants/profiles.js';
|
||||
import { RULES_ACTIONS } from '../../../../src/constants/rules-actions.js';
|
||||
import {
|
||||
wouldRemovalLeaveNoProfiles,
|
||||
@@ -56,7 +56,7 @@ export async function rulesDirect(args, log, context = {}) {
|
||||
const addResults = [];
|
||||
|
||||
if (action === RULES_ACTIONS.REMOVE) {
|
||||
// Safety check: Ensure this won't remove all rules profiles (unless forced)
|
||||
// Safety check: Ensure this won't remove all rule profiles (unless forced)
|
||||
if (!force && wouldRemovalLeaveNoProfiles(projectRoot, profiles)) {
|
||||
const installedProfiles = getInstalledProfiles(projectRoot);
|
||||
const remainingProfiles = installedProfiles.filter(
|
||||
@@ -66,7 +66,7 @@ export async function rulesDirect(args, log, context = {}) {
|
||||
success: false,
|
||||
error: {
|
||||
code: 'CRITICAL_REMOVAL_BLOCKED',
|
||||
message: `CRITICAL: This operation would remove ALL remaining rules profiles (${profiles.join(', ')}), leaving your project with no rules configurations. This could significantly impact functionality. Currently installed profiles: ${installedProfiles.join(', ')}. If you're certain you want to proceed, set force: true or use the CLI with --force flag.`
|
||||
message: `CRITICAL: This operation would remove ALL remaining rule profiles (${profiles.join(', ')}), leaving your project with no rules configurations. This could significantly impact functionality. Currently installed profiles: ${installedProfiles.join(', ')}. If you're certain you want to proceed, set force: true or use the CLI with --force flag.`
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -76,7 +76,7 @@ export async function rulesDirect(args, log, context = {}) {
|
||||
removalResults.push({
|
||||
profileName: profile,
|
||||
success: false,
|
||||
error: `The requested rules profile for '${profile}' is unavailable. Supported profiles are: ${RULES_PROFILES.join(', ')}.`
|
||||
error: `The requested rules profile for '${profile}' is unavailable. Supported profiles are: ${RULE_PROFILES.join(', ')}.`
|
||||
});
|
||||
continue;
|
||||
}
|
||||
@@ -121,7 +121,7 @@ export async function rulesDirect(args, log, context = {}) {
|
||||
addResults.push({
|
||||
profileName: profile,
|
||||
success: false,
|
||||
error: `Profile not found: static import missing for '${profile}'. Valid profiles: ${RULES_PROFILES.join(', ')}`
|
||||
error: `Profile not found: static import missing for '${profile}'. Valid profiles: ${RULE_PROFILES.join(', ')}`
|
||||
});
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ import {
|
||||
withNormalizedProjectRoot
|
||||
} from './utils.js';
|
||||
import { initializeProjectDirect } from '../core/task-master-core.js';
|
||||
import { RULES_PROFILES } from '../../../src/constants/profiles.js';
|
||||
import { RULE_PROFILES } from '../../../src/constants/profiles.js';
|
||||
|
||||
export function registerInitializeProjectTool(server) {
|
||||
server.addTool({
|
||||
@@ -38,10 +38,10 @@ export function registerInitializeProjectTool(server) {
|
||||
'The root directory for the project. ALWAYS SET THIS TO THE PROJECT ROOT DIRECTORY. IF NOT SET, THE TOOL WILL NOT WORK.'
|
||||
),
|
||||
rules: z
|
||||
.array(z.enum(RULES_PROFILES))
|
||||
.array(z.enum(RULE_PROFILES))
|
||||
.optional()
|
||||
.describe(
|
||||
`List of rules profiles to include at initialization. If omitted, defaults to all available profiles. Available options: ${RULES_PROFILES.join(', ')}`
|
||||
`List of rule profiles to include at initialization. If omitted, defaults to all available profiles. Available options: ${RULE_PROFILES.join(', ')}`
|
||||
)
|
||||
}),
|
||||
execute: withNormalizedProjectRoot(async (args, context) => {
|
||||
|
||||
@@ -10,7 +10,7 @@ import {
|
||||
withNormalizedProjectRoot
|
||||
} from './utils.js';
|
||||
import { rulesDirect } from '../core/direct-functions/rules.js';
|
||||
import { RULES_PROFILES } from '../../../src/constants/profiles.js';
|
||||
import { RULE_PROFILES } from '../../../src/constants/profiles.js';
|
||||
|
||||
/**
|
||||
* Register the rules tool with the MCP server
|
||||
@@ -19,16 +19,16 @@ import { RULES_PROFILES } from '../../../src/constants/profiles.js';
|
||||
export function registerRulesTool(server) {
|
||||
server.addTool({
|
||||
name: 'rules',
|
||||
description: 'Add or remove rules profiles from the project.',
|
||||
description: 'Add or remove rule profiles from the project.',
|
||||
parameters: z.object({
|
||||
action: z
|
||||
.enum(['add', 'remove'])
|
||||
.describe('Whether to add or remove rules profiles.'),
|
||||
.describe('Whether to add or remove rule profiles.'),
|
||||
profiles: z
|
||||
.array(z.enum(RULES_PROFILES))
|
||||
.array(z.enum(RULE_PROFILES))
|
||||
.min(1)
|
||||
.describe(
|
||||
`List of rules profiles to add or remove (e.g., [\"cursor\", \"roo\"]). Available options: ${RULES_PROFILES.join(', ')}`
|
||||
`List of rule profiles to add or remove (e.g., [\"cursor\", \"roo\"]). Available options: ${RULE_PROFILES.join(', ')}`
|
||||
),
|
||||
projectRoot: z
|
||||
.string()
|
||||
@@ -40,7 +40,7 @@ export function registerRulesTool(server) {
|
||||
.optional()
|
||||
.default(false)
|
||||
.describe(
|
||||
'DANGEROUS: Force removal even if it would leave no rules profiles. Only use if you are absolutely certain.'
|
||||
'DANGEROUS: Force removal even if it would leave no rule profiles. Only use if you are absolutely certain.'
|
||||
)
|
||||
}),
|
||||
execute: withNormalizedProjectRoot(async (args, { log, session }) => {
|
||||
|
||||
@@ -24,7 +24,7 @@ import figlet from 'figlet';
|
||||
import boxen from 'boxen';
|
||||
import gradient from 'gradient-string';
|
||||
import { isSilentMode } from './modules/utils.js';
|
||||
import { RULES_PROFILES } from '../src/constants/profiles.js';
|
||||
import { RULE_PROFILES } from '../src/constants/profiles.js';
|
||||
import {
|
||||
convertAllRulesToProfileRules,
|
||||
getRulesProfile
|
||||
@@ -312,7 +312,7 @@ async function initializeProject(options = {}) {
|
||||
let selectedRulesProfiles =
|
||||
options.rules && Array.isArray(options.rules) && options.rules.length > 0
|
||||
? options.rules
|
||||
: RULES_PROFILES; // Default to all profiles
|
||||
: RULE_PROFILES; // Default to all profiles
|
||||
|
||||
if (skipPrompts) {
|
||||
if (!isSilentMode()) {
|
||||
@@ -384,7 +384,7 @@ async function initializeProject(options = {}) {
|
||||
if (options.rulesExplicitlyProvided) {
|
||||
log(
|
||||
'info',
|
||||
`Using rules profiles provided via command line: ${selectedRulesProfiles.join(', ')}`
|
||||
`Using rule profiles provided via command line: ${selectedRulesProfiles.join(', ')}`
|
||||
);
|
||||
} else {
|
||||
selectedRulesProfiles = await runInteractiveRulesSetup();
|
||||
@@ -427,7 +427,7 @@ function promptQuestion(rl, question) {
|
||||
function createProjectStructure(
|
||||
addAliases,
|
||||
dryRun,
|
||||
selectedRulesProfiles = RULES_PROFILES // Default to all rules profiles
|
||||
selectedRulesProfiles = RULE_PROFILES // Default to all rule profiles
|
||||
) {
|
||||
const targetDir = process.cwd();
|
||||
log('info', `Initializing project in ${targetDir}`);
|
||||
@@ -441,7 +441,7 @@ function createProjectStructure(
|
||||
year: new Date().getFullYear()
|
||||
};
|
||||
|
||||
// Helper function to create rules profiles
|
||||
// Helper function to create rule profiles
|
||||
function _processSingleProfile(profileName) {
|
||||
const profile = getRulesProfile(profileName);
|
||||
if (profile) {
|
||||
|
||||
@@ -95,7 +95,7 @@ import {
|
||||
RULES_SETUP_ACTION
|
||||
} from '../../src/constants/rules-actions.js';
|
||||
import { getTaskMasterVersion } from '../../src/utils/getVersion.js';
|
||||
import { RULES_PROFILES } from '../../src/constants/profiles.js';
|
||||
import { RULE_PROFILES } from '../../src/constants/profiles.js';
|
||||
import {
|
||||
convertAllRulesToProfileRules,
|
||||
removeProfileRules,
|
||||
@@ -2279,7 +2279,7 @@ function registerCommands(programInstance) {
|
||||
.action(async (cmdOptions) => {
|
||||
// cmdOptions contains parsed arguments
|
||||
// Parse rules: accept space or comma separated, default to all available rules
|
||||
let selectedProfiles = RULES_PROFILES;
|
||||
let selectedProfiles = RULE_PROFILES;
|
||||
let rulesExplicitlyProvided = false;
|
||||
|
||||
if (cmdOptions.rules && Array.isArray(cmdOptions.rules)) {
|
||||
@@ -2685,7 +2685,7 @@ Examples:
|
||||
/**
|
||||
* 'task-master rules setup' action:
|
||||
*
|
||||
* Launches an interactive prompt to select which rules profiles to add to the current project.
|
||||
* Launches an interactive prompt to select which rule profiles to add to the current project.
|
||||
* This does NOT perform project initialization or ask about shell aliases—only rules selection.
|
||||
*
|
||||
* Example usage:
|
||||
@@ -2701,7 +2701,7 @@ Examples:
|
||||
for (const profile of selectedRulesProfiles) {
|
||||
if (!isValidProfile(profile)) {
|
||||
console.warn(
|
||||
`Rules profile for "${profile}" not found. Valid profiles: ${RULES_PROFILES.join(', ')}. Skipping.`
|
||||
`Rules profile for "${profile}" not found. Valid profiles: ${RULE_PROFILES.join(', ')}. Skipping.`
|
||||
);
|
||||
continue;
|
||||
}
|
||||
@@ -2760,7 +2760,7 @@ Examples:
|
||||
for (const profile of expandedProfiles) {
|
||||
if (!isValidProfile(profile)) {
|
||||
console.warn(
|
||||
`Rules profile for "${profile}" not found. Valid profiles: ${RULES_PROFILES.join(', ')}. Skipping.`
|
||||
`Rules profile for "${profile}" not found. Valid profiles: ${RULE_PROFILES.join(', ')}. Skipping.`
|
||||
);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -3,30 +3,30 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* Available rules profiles for project initialization and rules command
|
||||
* Available rule profiles for project initialization and rules command
|
||||
*
|
||||
* ⚠️ SINGLE SOURCE OF TRUTH: This is the authoritative list of all supported rules profiles.
|
||||
* ⚠️ SINGLE SOURCE OF TRUTH: This is the authoritative list of all supported rule profiles.
|
||||
* This constant is used directly throughout the codebase (previously aliased as PROFILE_NAMES).
|
||||
*
|
||||
* @type {RulesProfile[]}
|
||||
* @description Defines possible rules profile sets:
|
||||
* @description Defines possible rule profile sets:
|
||||
* - cline: Cline IDE rules
|
||||
* - cursor: Cursor IDE rules (default)
|
||||
* - roo: Roo Code IDE rules
|
||||
* - windsurf: Windsurf IDE rules
|
||||
*
|
||||
* To add a new rules profile:
|
||||
* To add a new rule profile:
|
||||
* 1. Add the profile name to this array
|
||||
* 2. Create a profile file in scripts/profiles/{profile}.js
|
||||
* 3. Export it as {profile}Profile in scripts/profiles/index.js
|
||||
*/
|
||||
export const RULES_PROFILES = ['cline', 'cursor', 'roo', 'windsurf'];
|
||||
export const RULE_PROFILES = ['cline', 'cursor', 'roo', 'windsurf'];
|
||||
|
||||
/**
|
||||
* Check if a given rules profile is valid
|
||||
* @param {string} rulesProfile - The rules profile to check
|
||||
* @returns {boolean} True if the rules profile is valid, false otherwise
|
||||
* Check if a given rule profile is valid
|
||||
* @param {string} rulesProfile - The rule profile to check
|
||||
* @returns {boolean} True if the rule profile is valid, false otherwise
|
||||
*/
|
||||
export function isValidRulesProfile(rulesProfile) {
|
||||
return RULES_PROFILES.includes(rulesProfile);
|
||||
return RULE_PROFILES.includes(rulesProfile);
|
||||
}
|
||||
|
||||
@@ -60,9 +60,9 @@ async function confirmRemoveAllRemainingProfiles(profiles, remainingProfiles) {
|
||||
console.log(
|
||||
boxen(
|
||||
chalk.red.bold(
|
||||
`⚠️ CRITICAL WARNING: REMOVING ALL TASK MASTER RULES PROFILES ⚠️\n\n` +
|
||||
`⚠️ CRITICAL WARNING: REMOVING ALL TASK MASTER RULE PROFILES ⚠️\n\n` +
|
||||
`You are about to remove Task Master components for: ${profileList}\n` +
|
||||
`This will leave your project with NO Task Master rules profiles remaining!\n\n` +
|
||||
`This will leave your project with NO Task Master rule profiles remaining!\n\n` +
|
||||
`What will be removed:\n` +
|
||||
`• All Task Master specific rule files\n` +
|
||||
`• Task Master MCP server configurations\n` +
|
||||
@@ -90,7 +90,7 @@ async function confirmRemoveAllRemainingProfiles(profiles, remainingProfiles) {
|
||||
type: 'confirm',
|
||||
name: 'confirm',
|
||||
message:
|
||||
'Type y to confirm removing ALL Task Master profiles, or n to abort:',
|
||||
'Type y to confirm removing ALL Task Master rule profiles, or n to abort:',
|
||||
default: false
|
||||
}
|
||||
]);
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
*/
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import { RULES_PROFILES } from '../constants/profiles.js';
|
||||
import { RULE_PROFILES } from '../constants/profiles.js';
|
||||
import { getRulesProfile } from './rule-transformer.js';
|
||||
|
||||
/**
|
||||
@@ -15,7 +15,7 @@ import { getRulesProfile } from './rule-transformer.js';
|
||||
export function getInstalledProfiles(projectRoot) {
|
||||
const installedProfiles = [];
|
||||
|
||||
for (const profileName of RULES_PROFILES) {
|
||||
for (const profileName of RULE_PROFILES) {
|
||||
const profileConfig = getRulesProfile(profileName);
|
||||
if (!profileConfig) continue;
|
||||
|
||||
|
||||
@@ -16,13 +16,13 @@ import {
|
||||
} from './mcp-config-setup.js';
|
||||
|
||||
// Import profile constants (single source of truth)
|
||||
import { RULES_PROFILES } from '../constants/profiles.js';
|
||||
import { RULE_PROFILES } from '../constants/profiles.js';
|
||||
|
||||
// --- Profile Imports ---
|
||||
import * as profilesModule from '../../scripts/profiles/index.js';
|
||||
|
||||
export function isValidProfile(profile) {
|
||||
return RULES_PROFILES.includes(profile);
|
||||
return RULE_PROFILES.includes(profile);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -41,7 +41,7 @@ export function getRulesProfile(name) {
|
||||
|
||||
if (!profile) {
|
||||
throw new Error(
|
||||
`Profile not found: static import missing for '${name}'. Valid profiles: ${RULES_PROFILES.join(', ')}`
|
||||
`Profile not found: static import missing for '${name}'. Valid profiles: ${RULE_PROFILES.join(', ')}`
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -3,10 +3,10 @@ import inquirer from 'inquirer';
|
||||
import chalk from 'chalk';
|
||||
import { log } from '../../scripts/modules/utils.js';
|
||||
import { getRulesProfile } from './rule-transformer.js';
|
||||
import { RULES_PROFILES } from '../constants/profiles.js';
|
||||
import { RULE_PROFILES } from '../constants/profiles.js';
|
||||
|
||||
// Dynamically generate availableRulesProfiles from RULES_PROFILES
|
||||
const availableRulesProfiles = RULES_PROFILES.map((name) => {
|
||||
// Dynamically generate availableRulesProfiles from RULE_PROFILES
|
||||
const availableRulesProfiles = RULE_PROFILES.map((name) => {
|
||||
const displayName = getProfileDisplayName(name);
|
||||
return {
|
||||
name: displayName,
|
||||
@@ -29,7 +29,7 @@ function getProfileDisplayName(name) {
|
||||
/**
|
||||
* Launches an interactive prompt for selecting which profile rules to include in your project.
|
||||
*
|
||||
* This function dynamically lists all available profiles (from RULES_PROFILES) and presents them as checkboxes.
|
||||
* This function dynamically lists all available profiles (from RULE_PROFILES) and presents them as checkboxes.
|
||||
* The user must select at least one profile (no defaults are pre-selected). The result is an array of selected profile names.
|
||||
*
|
||||
* Used by both project initialization (init) and the CLI 'task-master rules setup' command to ensure DRY, consistent UX.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { RULES_PROFILES } from '../../src/constants/profiles.js';
|
||||
import { RULE_PROFILES } from '../../src/constants/profiles.js';
|
||||
import { getRulesProfile } from '../../src/utils/rule-transformer.js';
|
||||
import path from 'path';
|
||||
|
||||
@@ -47,7 +47,7 @@ describe('MCP Configuration Validation', () => {
|
||||
|
||||
describe('MCP Configuration Path Consistency', () => {
|
||||
test('should ensure all profiles have consistent mcpConfigPath construction', () => {
|
||||
RULES_PROFILES.forEach((profileName) => {
|
||||
RULE_PROFILES.forEach((profileName) => {
|
||||
const profile = getRulesProfile(profileName);
|
||||
if (profile.mcpConfig !== false) {
|
||||
const expectedPath = path.join(
|
||||
@@ -61,7 +61,7 @@ describe('MCP Configuration Validation', () => {
|
||||
|
||||
test('should ensure no two profiles have the same MCP config path', () => {
|
||||
const mcpPaths = new Set();
|
||||
RULES_PROFILES.forEach((profileName) => {
|
||||
RULE_PROFILES.forEach((profileName) => {
|
||||
const profile = getRulesProfile(profileName);
|
||||
if (profile.mcpConfig !== false) {
|
||||
expect(mcpPaths.has(profile.mcpConfigPath)).toBe(false);
|
||||
@@ -71,7 +71,7 @@ describe('MCP Configuration Validation', () => {
|
||||
});
|
||||
|
||||
test('should ensure all MCP-enabled profiles use proper directory structure', () => {
|
||||
RULES_PROFILES.forEach((profileName) => {
|
||||
RULE_PROFILES.forEach((profileName) => {
|
||||
const profile = getRulesProfile(profileName);
|
||||
if (profile.mcpConfig !== false) {
|
||||
expect(profile.mcpConfigPath).toMatch(/^\.[\w-]+\/[\w_.]+$/);
|
||||
@@ -80,7 +80,7 @@ describe('MCP Configuration Validation', () => {
|
||||
});
|
||||
|
||||
test('should ensure all profiles have required MCP properties', () => {
|
||||
RULES_PROFILES.forEach((profileName) => {
|
||||
RULE_PROFILES.forEach((profileName) => {
|
||||
const profile = getRulesProfile(profileName);
|
||||
expect(profile).toHaveProperty('mcpConfig');
|
||||
expect(profile).toHaveProperty('profileDir');
|
||||
@@ -108,7 +108,7 @@ describe('MCP Configuration Validation', () => {
|
||||
describe('Profile Directory Structure', () => {
|
||||
test('should ensure each profile has a unique directory', () => {
|
||||
const profileDirs = new Set();
|
||||
RULES_PROFILES.forEach((profileName) => {
|
||||
RULE_PROFILES.forEach((profileName) => {
|
||||
const profile = getRulesProfile(profileName);
|
||||
expect(profileDirs.has(profile.profileDir)).toBe(false);
|
||||
profileDirs.add(profile.profileDir);
|
||||
@@ -116,7 +116,7 @@ describe('MCP Configuration Validation', () => {
|
||||
});
|
||||
|
||||
test('should ensure profile directories follow expected naming convention', () => {
|
||||
RULES_PROFILES.forEach((profileName) => {
|
||||
RULE_PROFILES.forEach((profileName) => {
|
||||
const profile = getRulesProfile(profileName);
|
||||
expect(profile.profileDir).toMatch(/^\.[\w-]+$/);
|
||||
});
|
||||
@@ -125,7 +125,7 @@ describe('MCP Configuration Validation', () => {
|
||||
|
||||
describe('MCP Configuration Creation Logic', () => {
|
||||
test('should indicate which profiles require MCP configuration creation', () => {
|
||||
const mcpEnabledProfiles = RULES_PROFILES.filter((profileName) => {
|
||||
const mcpEnabledProfiles = RULE_PROFILES.filter((profileName) => {
|
||||
const profile = getRulesProfile(profileName);
|
||||
return profile.mcpConfig !== false;
|
||||
});
|
||||
@@ -137,7 +137,7 @@ describe('MCP Configuration Validation', () => {
|
||||
});
|
||||
|
||||
test('should provide all necessary information for MCP config creation', () => {
|
||||
RULES_PROFILES.forEach((profileName) => {
|
||||
RULE_PROFILES.forEach((profileName) => {
|
||||
const profile = getRulesProfile(profileName);
|
||||
if (profile.mcpConfig !== false) {
|
||||
expect(profile.mcpConfigPath).toBeDefined();
|
||||
@@ -152,7 +152,7 @@ describe('MCP Configuration Validation', () => {
|
||||
test('should verify that rule transformer functions use mcpConfigPath correctly', () => {
|
||||
// This test verifies that the mcpConfigPath property exists and is properly formatted
|
||||
// for use with the setupMCPConfiguration function
|
||||
RULES_PROFILES.forEach((profileName) => {
|
||||
RULE_PROFILES.forEach((profileName) => {
|
||||
const profile = getRulesProfile(profileName);
|
||||
if (profile.mcpConfig !== false) {
|
||||
// Verify the path is properly formatted for path.join usage
|
||||
@@ -167,7 +167,7 @@ describe('MCP Configuration Validation', () => {
|
||||
});
|
||||
|
||||
test('should verify that mcpConfigPath is properly constructed for path.join usage', () => {
|
||||
RULES_PROFILES.forEach((profileName) => {
|
||||
RULE_PROFILES.forEach((profileName) => {
|
||||
const profile = getRulesProfile(profileName);
|
||||
if (profile.mcpConfig !== false) {
|
||||
// Test that path.join works correctly with the mcpConfigPath
|
||||
@@ -186,7 +186,7 @@ describe('MCP Configuration Validation', () => {
|
||||
describe('MCP Configuration Function Integration', () => {
|
||||
test('should verify that setupMCPConfiguration receives the correct mcpConfigPath parameter', () => {
|
||||
// This test verifies the integration between rule transformer and mcp-utils
|
||||
RULES_PROFILES.forEach((profileName) => {
|
||||
RULE_PROFILES.forEach((profileName) => {
|
||||
const profile = getRulesProfile(profileName);
|
||||
if (profile.mcpConfig !== false) {
|
||||
// Verify that the mcpConfigPath can be used directly with setupMCPConfiguration
|
||||
|
||||
@@ -2,25 +2,25 @@ import {
|
||||
isValidProfile,
|
||||
getRulesProfile
|
||||
} from '../../src/utils/rule-transformer.js';
|
||||
import { RULES_PROFILES } from '../../src/constants/profiles.js';
|
||||
import { RULE_PROFILES } from '../../src/constants/profiles.js';
|
||||
|
||||
describe('Rule Transformer - General', () => {
|
||||
describe('Profile Configuration Validation', () => {
|
||||
it('should use RULES_PROFILES as the single source of truth', () => {
|
||||
// Ensure RULES_PROFILES is properly defined and contains expected profiles
|
||||
expect(Array.isArray(RULES_PROFILES)).toBe(true);
|
||||
expect(RULES_PROFILES.length).toBeGreaterThan(0);
|
||||
it('should use RULE_PROFILES as the single source of truth', () => {
|
||||
// Ensure RULE_PROFILES is properly defined and contains expected profiles
|
||||
expect(Array.isArray(RULE_PROFILES)).toBe(true);
|
||||
expect(RULE_PROFILES.length).toBeGreaterThan(0);
|
||||
|
||||
// Verify expected profiles are present
|
||||
const expectedProfiles = ['cline', 'cursor', 'roo', 'windsurf'];
|
||||
expectedProfiles.forEach((profile) => {
|
||||
expect(RULES_PROFILES).toContain(profile);
|
||||
expect(RULE_PROFILES).toContain(profile);
|
||||
});
|
||||
});
|
||||
|
||||
it('should validate profiles correctly with isValidProfile', () => {
|
||||
// Test valid profiles
|
||||
RULES_PROFILES.forEach((profile) => {
|
||||
RULE_PROFILES.forEach((profile) => {
|
||||
expect(isValidProfile(profile)).toBe(true);
|
||||
});
|
||||
|
||||
@@ -33,7 +33,7 @@ describe('Rule Transformer - General', () => {
|
||||
|
||||
it('should return correct rules profile with getRulesProfile', () => {
|
||||
// Test valid profiles
|
||||
RULES_PROFILES.forEach((profile) => {
|
||||
RULE_PROFILES.forEach((profile) => {
|
||||
const profileConfig = getRulesProfile(profile);
|
||||
expect(profileConfig).toBeDefined();
|
||||
expect(profileConfig.profileName.toLowerCase()).toBe(profile);
|
||||
@@ -46,7 +46,7 @@ describe('Rule Transformer - General', () => {
|
||||
|
||||
describe('Profile Structure', () => {
|
||||
it('should have all required properties for each profile', () => {
|
||||
RULES_PROFILES.forEach((profile) => {
|
||||
RULE_PROFILES.forEach((profile) => {
|
||||
const profileConfig = getRulesProfile(profile);
|
||||
|
||||
// Check required properties
|
||||
@@ -89,7 +89,7 @@ describe('Rule Transformer - General', () => {
|
||||
'taskmaster.mdc'
|
||||
];
|
||||
|
||||
RULES_PROFILES.forEach((profile) => {
|
||||
RULE_PROFILES.forEach((profile) => {
|
||||
const profileConfig = getRulesProfile(profile);
|
||||
|
||||
// Check that fileMap exists and is an object
|
||||
@@ -116,7 +116,7 @@ describe('Rule Transformer - General', () => {
|
||||
|
||||
describe('MCP Configuration Properties', () => {
|
||||
it('should have all required MCP properties for each profile', () => {
|
||||
RULES_PROFILES.forEach((profile) => {
|
||||
RULE_PROFILES.forEach((profile) => {
|
||||
const profileConfig = getRulesProfile(profile);
|
||||
|
||||
// Check MCP-related properties exist
|
||||
@@ -160,7 +160,7 @@ describe('Rule Transformer - General', () => {
|
||||
}
|
||||
};
|
||||
|
||||
RULES_PROFILES.forEach((profile) => {
|
||||
RULE_PROFILES.forEach((profile) => {
|
||||
const profileConfig = getRulesProfile(profile);
|
||||
const expected = expectedConfigs[profile];
|
||||
|
||||
@@ -171,7 +171,7 @@ describe('Rule Transformer - General', () => {
|
||||
});
|
||||
|
||||
it('should have consistent profileDir and mcpConfigPath relationship', () => {
|
||||
RULES_PROFILES.forEach((profile) => {
|
||||
RULE_PROFILES.forEach((profile) => {
|
||||
const profileConfig = getRulesProfile(profile);
|
||||
|
||||
// The mcpConfigPath should start with the profileDir
|
||||
@@ -191,7 +191,7 @@ describe('Rule Transformer - General', () => {
|
||||
});
|
||||
|
||||
it('should have unique profile directories', () => {
|
||||
const profileDirs = RULES_PROFILES.map((profile) => {
|
||||
const profileDirs = RULE_PROFILES.map((profile) => {
|
||||
const profileConfig = getRulesProfile(profile);
|
||||
return profileConfig.profileDir;
|
||||
});
|
||||
@@ -201,7 +201,7 @@ describe('Rule Transformer - General', () => {
|
||||
});
|
||||
|
||||
it('should have unique MCP config paths', () => {
|
||||
const mcpConfigPaths = RULES_PROFILES.map((profile) => {
|
||||
const mcpConfigPaths = RULE_PROFILES.map((profile) => {
|
||||
const profileConfig = getRulesProfile(profile);
|
||||
return profileConfig.mcpConfigPath;
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user