From 135d854742ea0997f708d5f5c3a9a01981c47c3a Mon Sep 17 00:00:00 2001 From: AstroSteveo <34114851+AstroSteveo@users.noreply.github.com> Date: Sun, 21 Sep 2025 20:36:25 -0500 Subject: [PATCH 1/6] Checkpoint from VS Code for coding agent session --- .vscode/settings.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index fc19b34..6d2744a 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -8,4 +8,4 @@ "chat.instructionsFilesLocations": { ".awesome-copilot/instructions": true } -} \ No newline at end of file +} From a7457ade5f9851fff5fe45869c32cb43734d7949 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 22 Sep 2025 01:36:31 +0000 Subject: [PATCH 2/6] Initial plan From cde062a1fb3f96ba00098dd633470482ccf7a190 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 22 Sep 2025 01:39:17 +0000 Subject: [PATCH 3/6] Initial analysis - plan for robust toggle/state management implementation Co-authored-by: AstroSteveo <34114851+AstroSteveo@users.noreply.github.com> --- .vscode/settings.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 6d2744a..fc19b34 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -8,4 +8,4 @@ "chat.instructionsFilesLocations": { ".awesome-copilot/instructions": true } -} +} \ No newline at end of file From 99d7c8cefc47d2ef36ebc8114a2510cf7edd4246 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 22 Sep 2025 01:47:53 +0000 Subject: [PATCH 4/6] Implement robust toggle/state management system with all requested features Co-authored-by: AstroSteveo <34114851+AstroSteveo@users.noreply.github.com> --- apply-config.js | 71 +++++++++++++-- awesome-copilot.js | 143 ++++++++++++++++++++++++++--- test-cli.js | 4 +- test-new-features.js | 209 +++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 405 insertions(+), 22 deletions(-) create mode 100755 test-new-features.js diff --git a/apply-config.js b/apply-config.js index fa27c64..cd2006e 100755 --- a/apply-config.js +++ b/apply-config.js @@ -137,13 +137,17 @@ async function applyConfig(configPath = "awesome-copilot.config.yml") { } } + // Clean up files that are no longer enabled (requirement #3: Toggling instructions off will remove them) + const cleanupSummary = cleanupDisabledFiles(outputDir, effectivelyEnabledSets, rootDir); + // Process prompts using effective states for (const promptName of effectivelyEnabledSets.prompts) { const sourcePath = path.join(rootDir, "prompts", `${promptName}.prompt.md`); if (fs.existsSync(sourcePath)) { const destPath = path.join(outputDir, "prompts", `${promptName}.prompt.md`); - copyFile(sourcePath, destPath); - copiedCount++; + if (copyFile(sourcePath, destPath)) { + copiedCount++; + } summary.prompts++; } } @@ -153,8 +157,9 @@ async function applyConfig(configPath = "awesome-copilot.config.yml") { const sourcePath = path.join(rootDir, "instructions", `${instructionName}.instructions.md`); if (fs.existsSync(sourcePath)) { const destPath = path.join(outputDir, "instructions", `${instructionName}.instructions.md`); - copyFile(sourcePath, destPath); - copiedCount++; + if (copyFile(sourcePath, destPath)) { + copiedCount++; + } summary.instructions++; } } @@ -164,8 +169,9 @@ async function applyConfig(configPath = "awesome-copilot.config.yml") { const sourcePath = path.join(rootDir, "chatmodes", `${chatmodeName}.chatmode.md`); if (fs.existsSync(sourcePath)) { const destPath = path.join(outputDir, "chatmodes", `${chatmodeName}.chatmode.md`); - copyFile(sourcePath, destPath); - copiedCount++; + if (copyFile(sourcePath, destPath)) { + copiedCount++; + } summary.chatmodes++; } } @@ -203,11 +209,62 @@ function ensureDirectoryExists(dirPath) { } /** - * Copy file from source to destination + * Copy file from source to destination with idempotency check */ function copyFile(sourcePath, destPath) { + // Check if destination exists and has same content (idempotency) + if (fs.existsSync(destPath)) { + const sourceContent = fs.readFileSync(sourcePath, 'utf8'); + const destContent = fs.readFileSync(destPath, 'utf8'); + + if (sourceContent === destContent) { + console.log(`āœ“ Already exists and up-to-date: ${path.basename(sourcePath)}`); + return false; // No copy needed + } + } + fs.copyFileSync(sourcePath, destPath); console.log(`āœ“ Copied: ${path.basename(sourcePath)}`); + return true; // File was copied +} + +/** + * Clean up files that are no longer enabled (requirement #3) + */ +function cleanupDisabledFiles(outputDir, effectivelyEnabledSets, rootDir) { + const cleanupSummary = { + prompts: 0, + instructions: 0, + chatmodes: 0 + }; + + const sections = [ + { name: "prompts", ext: ".prompt.md" }, + { name: "instructions", ext: ".instructions.md" }, + { name: "chatmodes", ext: ".chatmode.md" } + ]; + + for (const section of sections) { + const sectionDir = path.join(outputDir, section.name); + if (!fs.existsSync(sectionDir)) continue; + + const existingFiles = fs.readdirSync(sectionDir); + for (const fileName of existingFiles) { + if (!fileName.endsWith(section.ext)) continue; + + const itemName = fileName.replace(section.ext, ''); + + // Check if this item is still enabled + if (!effectivelyEnabledSets[section.name].has(itemName)) { + const filePath = path.join(sectionDir, fileName); + fs.unlinkSync(filePath); + cleanupSummary[section.name]++; + console.log(`šŸ—‘ļø Removed: ${section.name}/${fileName}`); + } + } + } + + return cleanupSummary; } // CLI usage diff --git a/awesome-copilot.js b/awesome-copilot.js index 4913c01..f1aff26 100755 --- a/awesome-copilot.js +++ b/awesome-copilot.js @@ -54,9 +54,17 @@ const commands = { toggle: { description: "Enable or disable prompts, instructions, chat modes, or collections", - usage: "awesome-copilot toggle
[on|off] [--config ]", + usage: "awesome-copilot toggle
[on|off] [--all] [--apply] [--config ]", + action: async (args) => { + await handleToggleCommand(args); + } + }, + + reset: { + description: "Reset .awesome-copilot directory (remove all files but keep structure)", + usage: "awesome-copilot reset [config-file]", action: (args) => { - handleToggleCommand(args); + handleResetCommand(args); } }, @@ -87,9 +95,12 @@ function showHelp() { console.log(" awesome-copilot init # Create default config file"); console.log(" awesome-copilot init my-config.yml # Create named config file"); console.log(" awesome-copilot apply # Apply default config"); + console.log(" awesome-copilot reset # Clear .awesome-copilot directory"); console.log(" awesome-copilot list instructions # See which instructions are enabled"); console.log(" awesome-copilot toggle prompts create-readme on # Enable a specific prompt"); console.log(" awesome-copilot toggle instructions all off --config team.yml # Disable all instructions"); + console.log(" awesome-copilot toggle prompts all on --all # Force enable ALL prompts (override explicit settings)"); + console.log(" awesome-copilot toggle collections testing-automation on --apply # Enable collection and apply"); console.log(""); console.log("Workflow:"); console.log(" 1. Run 'awesome-copilot init' to create a configuration file"); @@ -158,9 +169,9 @@ function handleListCommand(rawArgs) { const effectiveState = effectiveStates[section]?.[itemName]; if (effectiveState) { const symbol = effectiveState.enabled ? "āœ“" : " "; - const reasonText = effectiveState.enabled + const reasonText = effectiveState.reason === "explicit" ? ` (${effectiveState.reason})` - : ""; + : effectiveState.enabled ? ` (${effectiveState.reason})` : ""; console.log(` [${symbol}] ${itemName}${reasonText}`); } else { console.log(` [ ] ${itemName}`); @@ -172,17 +183,22 @@ function handleListCommand(rawArgs) { console.log("\nUse 'awesome-copilot toggle' to enable or disable specific items."); } -function handleToggleCommand(rawArgs) { - const { args, configPath } = extractConfigOption(rawArgs); +async function handleToggleCommand(rawArgs) { + const { args, configPath, flags } = extractToggleOptions(rawArgs); if (args.length < 2) { - throw new Error("Usage: awesome-copilot toggle
[on|off] [--config ]"); + throw new Error("Usage: awesome-copilot toggle
[on|off] [--all] [--apply] [--config ]"); } const section = validateSectionType(args[0]); - const itemName = args[1]; + let itemName = args[1]; const stateArg = args[2]; const desiredState = stateArg ? parseStateToken(stateArg) : null; + + // Handle --all flag + if (flags.all) { + itemName = "all"; + } const availableItems = getAllAvailableItems(section); const availableSet = new Set(availableItems); @@ -260,10 +276,20 @@ function handleToggleCommand(rawArgs) { if (desiredState === null) { throw new Error("Specify 'on' or 'off' when toggling all items."); } - availableItems.forEach(item => { - sectionState[item] = desiredState; - }); - console.log(`${desiredState ? "Enabled" : "Disabled"} all ${SECTION_METADATA[section].label.toLowerCase()}.`); + + // Enhanced --all behavior: override ALL items, even explicit ones + if (flags.all) { + console.log(`${desiredState ? "Force-enabling" : "Force-disabling"} ALL ${SECTION_METADATA[section].label.toLowerCase()} (including explicit overrides).`); + availableItems.forEach(item => { + sectionState[item] = desiredState; + }); + } else { + // Regular "all" behavior: set all items explicitly but respect that they are now explicit + availableItems.forEach(item => { + sectionState[item] = desiredState; + }); + console.log(`${desiredState ? "Enabled" : "Disabled"} all ${SECTION_METADATA[section].label.toLowerCase()}.`); + } if (section === "instructions" && desiredState) { console.log("āš ļø Enabling every instruction can exceed Copilot Agent's context window. Consider enabling only what you need."); @@ -295,7 +321,53 @@ function handleToggleCommand(rawArgs) { console.log(`Estimated ${SECTION_METADATA[section].label.toLowerCase()} context size: ${formatNumber(totalCharacters)} characters.`); } maybeWarnAboutContext(section, totalCharacters); - console.log("Run 'awesome-copilot apply' to copy updated selections into your project."); + + // Handle automatic application + if (flags.apply) { + console.log("\nšŸ”„ Applying configuration automatically..."); + await applyConfig(configPath); + } else { + console.log("Run 'awesome-copilot apply' to copy updated selections into your project."); + } +} + +function extractToggleOptions(rawArgs) { + const args = [...rawArgs]; + let configPath = DEFAULT_CONFIG_PATH; + const flags = { + all: false, + apply: false + }; + + // Process flags + for (let i = args.length - 1; i >= 0; i--) { + const arg = args[i]; + + if (arg === "--all") { + flags.all = true; + args.splice(i, 1); + } else if (arg === "--apply") { + flags.apply = true; + args.splice(i, 1); + } else if (CONFIG_FLAG_ALIASES.includes(arg)) { + if (i === args.length - 1) { + throw new Error("Missing configuration file after --config flag."); + } + configPath = args[i + 1]; + args.splice(i, 2); + } + } + + // Check for config file as last argument + if (args.length > 0) { + const potentialPath = args[args.length - 1]; + if (isConfigFilePath(potentialPath)) { + configPath = potentialPath; + args.pop(); + } + } + + return { args, configPath, flags }; } function extractConfigOption(rawArgs) { @@ -396,6 +468,51 @@ function findClosestMatch(target, candidates) { return candidates.find(candidate => candidate.toLowerCase().includes(normalizedTarget)); } +function handleResetCommand(rawArgs) { + const { args, configPath } = extractConfigOption(rawArgs); + + const { config } = loadConfig(configPath); + const outputDir = config.project?.output_directory || ".awesome-copilot"; + + if (!fs.existsSync(outputDir)) { + console.log(`šŸ“ Directory ${outputDir} does not exist - nothing to reset.`); + return; + } + + console.log(`šŸ”„ Resetting ${outputDir} directory...`); + + let removedCount = 0; + + // Remove all files from subdirectories but keep the directory structure + const subdirs = ["prompts", "instructions", "chatmodes"]; + for (const subdir of subdirs) { + const subdirPath = path.join(outputDir, subdir); + if (fs.existsSync(subdirPath)) { + const files = fs.readdirSync(subdirPath); + for (const file of files) { + const filePath = path.join(subdirPath, file); + if (fs.statSync(filePath).isFile()) { + fs.unlinkSync(filePath); + removedCount++; + console.log(`šŸ—‘ļø Removed: ${subdir}/${file}`); + } + } + } + } + + // Remove README.md if it exists + const readmePath = path.join(outputDir, "README.md"); + if (fs.existsSync(readmePath)) { + fs.unlinkSync(readmePath); + removedCount++; + console.log(`šŸ—‘ļø Removed: README.md`); + } + + console.log(`\nāœ… Reset complete! Removed ${removedCount} files.`); + console.log(`šŸ“ Directory structure preserved: ${outputDir}/`); + console.log("Run 'awesome-copilot apply' to repopulate with current configuration."); +} + async function main() { const args = process.argv.slice(2); diff --git a/test-cli.js b/test-cli.js index 5c1aa69..58a62f2 100644 --- a/test-cli.js +++ b/test-cli.js @@ -105,8 +105,8 @@ async function runTests() { assert(result.success, 'Individual toggle should succeed'); const listResult = await runCommand(`node awesome-copilot.js list prompts --config ${TEST_CONFIG}`); - assert(listResult.stdout.includes('playwright-generate-test') && !listResult.stdout.includes('playwright-generate-test ('), - 'Explicitly disabled item should not show reason'); + assert(listResult.stdout.includes('playwright-generate-test (explicit)'), + 'Explicitly disabled item should show explicit reason'); }); // Test 6: Error handling for invalid commands diff --git a/test-new-features.js b/test-new-features.js new file mode 100755 index 0000000..78b8257 --- /dev/null +++ b/test-new-features.js @@ -0,0 +1,209 @@ +#!/usr/bin/env node + +/** + * Tests for new features added to awesome-copilot + */ + +const fs = require('fs'); +const path = require('path'); +const { exec } = require('child_process'); +const { promisify } = require('util'); + +const execAsync = promisify(exec); + +// Change to project directory for tests +process.chdir(__dirname); + +const TEST_CONFIG = 'test-new-features.yml'; +const TEST_OUTPUT_DIR = '.test-new-features-awesome-copilot'; + +function assert(condition, message) { + if (!condition) { + throw new Error(`Assertion failed: ${message}`); + } +} + +function cleanup() { + try { + if (fs.existsSync(TEST_CONFIG)) { + fs.unlinkSync(TEST_CONFIG); + } + if (fs.existsSync(TEST_OUTPUT_DIR)) { + fs.rmSync(TEST_OUTPUT_DIR, { recursive: true, force: true }); + } + } catch (error) { + // Ignore cleanup errors + } +} + +async function runCommand(command) { + try { + const { stdout, stderr } = await execAsync(command); + return { success: true, stdout, stderr }; + } catch (error) { + return { success: false, stdout: error.stdout || '', stderr: error.stderr || '', error }; + } +} + +function setTestOutputDir(configFile) { + if (fs.existsSync(configFile)) { + let content = fs.readFileSync(configFile, 'utf8'); + content = content.replace(/output_directory: "\.awesome-copilot"/, `output_directory: "${TEST_OUTPUT_DIR}"`); + fs.writeFileSync(configFile, content); + } +} + +async function runTests() { + console.log('Running tests for new awesome-copilot features...\n'); + + let passedTests = 0; + let totalTests = 0; + + async function test(name, testFn) { + totalTests++; + try { + cleanup(); // Clean up before each test + await testFn(); + console.log(`āœ… ${name}`); + passedTests++; + } catch (error) { + console.log(`āŒ ${name}: ${error.message}`); + } + } + + // Test 1: Reset command + await test("Reset command clears .awesome-copilot directory", async () => { + await runCommand(`node awesome-copilot.js init ${TEST_CONFIG}`); + setTestOutputDir(TEST_CONFIG); + + // Enable something and apply + await runCommand(`node awesome-copilot.js toggle collections testing-automation on --config ${TEST_CONFIG}`); + await runCommand(`node awesome-copilot.js apply ${TEST_CONFIG}`); + + // Check files exist + const filesBefore = fs.readdirSync(TEST_OUTPUT_DIR, { recursive: true }); + assert(filesBefore.some(f => f.includes('.md')), 'Should have some files before reset'); + + // Reset + const resetResult = await runCommand(`node awesome-copilot.js reset ${TEST_CONFIG}`); + assert(resetResult.success, 'Reset should succeed'); + + // Check files are gone but directories remain + assert(fs.existsSync(TEST_OUTPUT_DIR), 'Output directory should still exist'); + assert(fs.existsSync(path.join(TEST_OUTPUT_DIR, 'prompts')), 'Prompts directory should still exist'); + const filesAfter = fs.readdirSync(TEST_OUTPUT_DIR, { recursive: true }); + assert(!filesAfter.some(f => f.includes('.md')), 'Should have no .md files after reset'); + }); + + // Test 2: --apply flag + await test("--apply flag automatically applies after toggle", async () => { + await runCommand(`node awesome-copilot.js init ${TEST_CONFIG}`); + setTestOutputDir(TEST_CONFIG); + + // Toggle with --apply flag + const result = await runCommand(`node awesome-copilot.js toggle collections testing-automation on --apply --config ${TEST_CONFIG}`); + assert(result.success, 'Toggle with --apply should succeed'); + assert(result.stdout.includes('Applying configuration automatically'), 'Should show auto-apply message'); + + // Check files were applied + const files = fs.readdirSync(TEST_OUTPUT_DIR, { recursive: true }); + assert(files.some(f => f.includes('.md')), 'Files should be automatically applied'); + }); + + // Test 3: --all flag force overrides + await test("--all flag overrides explicit settings", async () => { + await runCommand(`node awesome-copilot.js init ${TEST_CONFIG}`); + + // Set explicit false + await runCommand(`node awesome-copilot.js toggle prompts create-readme off --config ${TEST_CONFIG}`); + + // Check it's explicitly disabled + const listResult1 = await runCommand(`node awesome-copilot.js list prompts --config ${TEST_CONFIG}`); + assert(listResult1.stdout.includes('create-readme (explicit)'), 'Should show explicit disabled'); + + // Force enable all with --all flag + await runCommand(`node awesome-copilot.js toggle prompts all on --all --config ${TEST_CONFIG}`); + + // Check it's now explicitly enabled + const listResult2 = await runCommand(`node awesome-copilot.js list prompts --config ${TEST_CONFIG}`); + assert(listResult2.stdout.includes('create-readme (explicit)') && listResult2.stdout.includes('[āœ“]'), 'Should be explicitly enabled'); + }); + + // Test 4: File cleanup on disable + await test("Files are removed when items are disabled", async () => { + await runCommand(`node awesome-copilot.js init ${TEST_CONFIG}`); + setTestOutputDir(TEST_CONFIG); + + // Enable and apply + await runCommand(`node awesome-copilot.js toggle collections testing-automation on --apply --config ${TEST_CONFIG}`); + + const filesBefore = fs.readdirSync(TEST_OUTPUT_DIR, { recursive: true }); + assert(filesBefore.some(f => f.includes('.md')), 'Should have files after enable'); + + // Disable and apply + await runCommand(`node awesome-copilot.js toggle collections testing-automation off --apply --config ${TEST_CONFIG}`); + + const filesAfter = fs.readdirSync(TEST_OUTPUT_DIR, { recursive: true }); + assert(!filesAfter.some(f => f.includes('.md')), 'Should have no files after disable'); + }); + + // Test 5: Idempotency with file content checking + await test("Idempotency checks file content correctly", async () => { + await runCommand(`node awesome-copilot.js init ${TEST_CONFIG}`); + setTestOutputDir(TEST_CONFIG); + + // Enable and apply + await runCommand(`node awesome-copilot.js toggle collections testing-automation on --apply --config ${TEST_CONFIG}`); + + // Apply again (should show already up-to-date) + const result = await runCommand(`node awesome-copilot.js apply ${TEST_CONFIG}`); + assert(result.stdout.includes('Already exists and up-to-date'), 'Should show idempotency message'); + assert(!result.stdout.includes('Copied:'), 'Should not copy any files'); + }); + + // Test 6: Explicit overrides preserved across collection toggles + await test("Explicit overrides preserved across collection toggles", async () => { + await runCommand(`node awesome-copilot.js init ${TEST_CONFIG}`); + + // Enable collection + await runCommand(`node awesome-copilot.js toggle collections testing-automation on --config ${TEST_CONFIG}`); + + // Set explicit override + await runCommand(`node awesome-copilot.js toggle prompts playwright-generate-test off --config ${TEST_CONFIG}`); + + // Toggle collection off and on + await runCommand(`node awesome-copilot.js toggle collections testing-automation off --config ${TEST_CONFIG}`); + const toggleResult = await runCommand(`node awesome-copilot.js toggle collections testing-automation on --config ${TEST_CONFIG}`); + + // Check that the explicit override is preserved (playwright-generate-test should NOT be in enabled list) + assert(!toggleResult.stdout.includes('playwright-generate-test'), 'Explicit override should be preserved'); + + // Double-check with list command + const listResult = await runCommand(`node awesome-copilot.js list prompts --config ${TEST_CONFIG}`); + assert(listResult.stdout.includes('playwright-generate-test (explicit)') && !listResult.stdout.includes('[āœ“] playwright-generate-test'), 'Should remain explicitly disabled'); + }); + + console.log(`\nNew Features Test Results: ${passedTests}/${totalTests} passed`); + + cleanup(); // Final cleanup + + if (passedTests === totalTests) { + console.log('šŸŽ‰ All new features tests passed!'); + return true; + } else { + console.log('šŸ’„ Some new features tests failed!'); + return false; + } +} + +if (require.main === module) { + runTests().then(success => { + process.exit(success ? 0 : 1); + }).catch(error => { + console.error('Test runner error:', error); + cleanup(); + process.exit(1); + }); +} + +module.exports = { runTests }; \ No newline at end of file From 60545b9cd1212e3f369ce795ef9c8d6713890bba Mon Sep 17 00:00:00 2001 From: Steven Mosley <34114851+AstroSteveo@users.noreply.github.com> Date: Mon, 22 Sep 2025 05:54:00 -0500 Subject: [PATCH 5/6] Update apply-config.js Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- apply-config.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/apply-config.js b/apply-config.js index cd2006e..b8aa487 100755 --- a/apply-config.js +++ b/apply-config.js @@ -229,10 +229,14 @@ function copyFile(sourcePath, destPath) { } /** - * Clean up files that are no longer enabled (requirement #3) + * Cleans up files in the output directory that are no longer enabled. + * + * @param {string} outputDir - The root directory where generated files are stored. + * @param {Object} effectivelyEnabledSets - An object mapping section names to Sets of enabled item names. + * @param {string} rootDir - The root directory of the project (used for path resolution). + * @returns {Object} Summary of the number of files removed per section. */ function cleanupDisabledFiles(outputDir, effectivelyEnabledSets, rootDir) { - const cleanupSummary = { prompts: 0, instructions: 0, chatmodes: 0 From ddf8d4bafc9ac3584cc7158b429da598cd5089f0 Mon Sep 17 00:00:00 2001 From: Steven Mosley <34114851+AstroSteveo@users.noreply.github.com> Date: Mon, 22 Sep 2025 05:54:27 -0500 Subject: [PATCH 6/6] Update test-new-features.js Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- test-new-features.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test-new-features.js b/test-new-features.js index 78b8257..8c2a9c7 100755 --- a/test-new-features.js +++ b/test-new-features.js @@ -180,7 +180,8 @@ async function runTests() { // Double-check with list command const listResult = await runCommand(`node awesome-copilot.js list prompts --config ${TEST_CONFIG}`); - assert(listResult.stdout.includes('playwright-generate-test (explicit)') && !listResult.stdout.includes('[āœ“] playwright-generate-test'), 'Should remain explicitly disabled'); + assert(listResult.stdout.includes('playwright-generate-test (explicit)'), "'playwright-generate-test (explicit)' should be present in the list output"); + assert(!listResult.stdout.includes('[āœ“] playwright-generate-test'), "'[āœ“] playwright-generate-test' should NOT be present in the list output (should remain explicitly disabled)"); }); console.log(`\nNew Features Test Results: ${passedTests}/${totalTests} passed`);