Merge pull request #1 from AstroSteveo/copilot/fix-b353ac2a-efb5-43df-bdcf-14b46382a024
Implement YAML configuration system for toggling prompts, instructions, and chat modes
This commit is contained in:
commit
03ec094a4c
9
.gitignore
vendored
9
.gitignore
vendored
@ -4,3 +4,12 @@ Copilot-Processing.md
|
|||||||
|
|
||||||
# macOS system files
|
# macOS system files
|
||||||
.DS_Store
|
.DS_Store
|
||||||
|
|
||||||
|
# Configuration files (user-specific)
|
||||||
|
awesome-copilot.config.yml
|
||||||
|
*.config.yml
|
||||||
|
test-config.yml
|
||||||
|
test-apply-config.yml
|
||||||
|
|
||||||
|
# Test output directories
|
||||||
|
test-output/
|
||||||
|
|||||||
71
.schemas/config.schema.yml
Normal file
71
.schemas/config.schema.yml
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
# Schema for awesome-copilot configuration file
|
||||||
|
$schema: "http://json-schema.org/draft-07/schema#"
|
||||||
|
title: "Awesome Copilot Configuration"
|
||||||
|
description: "Configuration file to enable/disable prompts, instructions, chat modes, and collections"
|
||||||
|
type: object
|
||||||
|
|
||||||
|
properties:
|
||||||
|
version:
|
||||||
|
type: string
|
||||||
|
description: "Config file format version"
|
||||||
|
default: "1.0"
|
||||||
|
|
||||||
|
project:
|
||||||
|
type: object
|
||||||
|
description: "Project-specific settings"
|
||||||
|
properties:
|
||||||
|
name:
|
||||||
|
type: string
|
||||||
|
description: "Project name"
|
||||||
|
description:
|
||||||
|
type: string
|
||||||
|
description: "Project description"
|
||||||
|
output_directory:
|
||||||
|
type: string
|
||||||
|
description: "Directory where files should be copied (default: .github)"
|
||||||
|
default: ".github"
|
||||||
|
|
||||||
|
prompts:
|
||||||
|
type: object
|
||||||
|
description: "Enable/disable specific prompts"
|
||||||
|
additionalProperties:
|
||||||
|
type: boolean
|
||||||
|
|
||||||
|
instructions:
|
||||||
|
type: object
|
||||||
|
description: "Enable/disable specific instructions"
|
||||||
|
additionalProperties:
|
||||||
|
type: boolean
|
||||||
|
|
||||||
|
chatmodes:
|
||||||
|
type: object
|
||||||
|
description: "Enable/disable specific chat modes"
|
||||||
|
additionalProperties:
|
||||||
|
type: boolean
|
||||||
|
|
||||||
|
collections:
|
||||||
|
type: object
|
||||||
|
description: "Enable/disable entire collections (will enable/disable all items in collection)"
|
||||||
|
additionalProperties:
|
||||||
|
type: boolean
|
||||||
|
|
||||||
|
required: ["version"]
|
||||||
|
|
||||||
|
examples:
|
||||||
|
- version: "1.0"
|
||||||
|
project:
|
||||||
|
name: "My Awesome Project"
|
||||||
|
description: "A project using awesome-copilot customizations"
|
||||||
|
output_directory: ".github"
|
||||||
|
prompts:
|
||||||
|
create-readme: true
|
||||||
|
generate-tests: false
|
||||||
|
instructions:
|
||||||
|
typescript-best-practices: true
|
||||||
|
testing-standards: false
|
||||||
|
chatmodes:
|
||||||
|
architect: true
|
||||||
|
dba: false
|
||||||
|
collections:
|
||||||
|
frontend-web-dev: true
|
||||||
|
csharp-dotnet-development: false
|
||||||
185
CONFIG.md
Normal file
185
CONFIG.md
Normal file
@ -0,0 +1,185 @@
|
|||||||
|
# Configuration File System
|
||||||
|
|
||||||
|
The Awesome Copilot repository now supports a configuration file system that allows you to easily manage which prompts, instructions, chat modes, and collections are included in your project.
|
||||||
|
|
||||||
|
## Quick Start
|
||||||
|
|
||||||
|
### 1. Generate a Configuration File
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Generate default configuration file
|
||||||
|
node awesome-copilot.js init
|
||||||
|
|
||||||
|
# Or generate with a specific name
|
||||||
|
node awesome-copilot.js init my-project.config.yml
|
||||||
|
```
|
||||||
|
|
||||||
|
This creates a YAML configuration file with all available items set to `false` by default.
|
||||||
|
|
||||||
|
### 2. Enable Desired Items
|
||||||
|
|
||||||
|
Edit the configuration file to set items to `true` that you want to include:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
version: "1.0"
|
||||||
|
project:
|
||||||
|
name: "My Project"
|
||||||
|
description: "A project using awesome-copilot customizations"
|
||||||
|
output_directory: ".github"
|
||||||
|
prompts:
|
||||||
|
create-readme: true
|
||||||
|
editorconfig: true
|
||||||
|
generate-tests: false
|
||||||
|
instructions:
|
||||||
|
typescript-best-practices: true
|
||||||
|
testing-standards: true
|
||||||
|
react: false
|
||||||
|
chatmodes:
|
||||||
|
architect: true
|
||||||
|
dba: false
|
||||||
|
specification: true
|
||||||
|
collections:
|
||||||
|
frontend-web-dev: true
|
||||||
|
csharp-dotnet-development: false
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. Apply Configuration
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Apply default configuration file
|
||||||
|
node awesome-copilot.js apply
|
||||||
|
|
||||||
|
# Or apply specific configuration file
|
||||||
|
node awesome-copilot.js apply my-project.config.yml
|
||||||
|
```
|
||||||
|
|
||||||
|
This will copy the enabled files to your project's `.github` directory (or the directory specified in the config).
|
||||||
|
|
||||||
|
## Configuration File Format
|
||||||
|
|
||||||
|
### Top-level Structure
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
version: "1.0" # Required: Config format version
|
||||||
|
project: # Optional: Project metadata
|
||||||
|
name: "My Project" # Project name
|
||||||
|
description: "Project desc" # Project description
|
||||||
|
output_directory: ".github" # Where to copy files (default: .github)
|
||||||
|
prompts: {} # Enable/disable prompts
|
||||||
|
instructions: {} # Enable/disable instructions
|
||||||
|
chatmodes: {} # Enable/disable chat modes
|
||||||
|
collections: {} # Enable/disable collections
|
||||||
|
```
|
||||||
|
|
||||||
|
### Individual Items
|
||||||
|
|
||||||
|
Set any item to `true` to include it, `false` to exclude it:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
prompts:
|
||||||
|
create-readme: true # Include this prompt
|
||||||
|
generate-tests: false # Exclude this prompt
|
||||||
|
```
|
||||||
|
|
||||||
|
### Collections
|
||||||
|
|
||||||
|
Collections are special - when you enable a collection, it automatically includes all items in that collection:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
collections:
|
||||||
|
frontend-web-dev: true # Includes all prompts, instructions, and chat modes in this collection
|
||||||
|
```
|
||||||
|
|
||||||
|
## Output Structure
|
||||||
|
|
||||||
|
When you apply a configuration, files are organized as follows:
|
||||||
|
|
||||||
|
```
|
||||||
|
.github/
|
||||||
|
├── copilot/
|
||||||
|
│ ├── *.prompt.md # Prompts for /awesome-copilot commands
|
||||||
|
│ └── *.chatmode.md # Chat modes for VS Code
|
||||||
|
└── instructions/
|
||||||
|
└── *.instructions.md # Instructions that auto-apply to coding
|
||||||
|
```
|
||||||
|
|
||||||
|
## NPM Scripts
|
||||||
|
|
||||||
|
You can also use npm scripts instead of the CLI:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Generate configuration
|
||||||
|
npm run config:init
|
||||||
|
|
||||||
|
# Apply configuration
|
||||||
|
npm run config:apply
|
||||||
|
|
||||||
|
# Access CLI
|
||||||
|
npm run config help
|
||||||
|
```
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
### Frontend React Project
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
version: "1.0"
|
||||||
|
project:
|
||||||
|
name: "React Frontend"
|
||||||
|
output_directory: ".github"
|
||||||
|
collections:
|
||||||
|
frontend-web-dev: true
|
||||||
|
prompts:
|
||||||
|
create-readme: true
|
||||||
|
editorconfig: true
|
||||||
|
chatmodes:
|
||||||
|
specification: true
|
||||||
|
```
|
||||||
|
|
||||||
|
### Backend .NET Project
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
version: "1.0"
|
||||||
|
project:
|
||||||
|
name: ".NET API"
|
||||||
|
output_directory: ".github"
|
||||||
|
collections:
|
||||||
|
csharp-dotnet-development: true
|
||||||
|
instructions:
|
||||||
|
testing-standards: true
|
||||||
|
prompts:
|
||||||
|
create-specification: true
|
||||||
|
```
|
||||||
|
|
||||||
|
### Full Stack Project
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
version: "1.0"
|
||||||
|
project:
|
||||||
|
name: "Full Stack App"
|
||||||
|
output_directory: ".github"
|
||||||
|
collections:
|
||||||
|
frontend-web-dev: true
|
||||||
|
csharp-dotnet-development: true
|
||||||
|
database-data-management: true
|
||||||
|
chatmodes:
|
||||||
|
architect: true
|
||||||
|
specification: true
|
||||||
|
```
|
||||||
|
|
||||||
|
## Migration from Manual Approach
|
||||||
|
|
||||||
|
If you were previously copying files manually:
|
||||||
|
|
||||||
|
1. Remove manually copied files from your `.github` directory
|
||||||
|
2. Run `node awesome-copilot.js init` to create a config file
|
||||||
|
3. Edit the config to enable the same items you were using manually
|
||||||
|
4. Run `node awesome-copilot.js apply` to get a clean, managed setup
|
||||||
|
|
||||||
|
## Benefits
|
||||||
|
|
||||||
|
- **Centralized Management**: One file controls all your Copilot customizations
|
||||||
|
- **Version Control Friendly**: Config file tracks what's enabled in your project
|
||||||
|
- **Easy Updates**: Re-run apply command after pulling awesome-copilot updates
|
||||||
|
- **Collection Support**: Enable entire curated sets with one setting
|
||||||
|
- **Clean Organization**: Files are organized in proper directory structure
|
||||||
31
README.md
31
README.md
@ -46,6 +46,37 @@ To make it easy to add these customizations to your editor, we have created a [M
|
|||||||
|
|
||||||
## 🔧 How to Use
|
## 🔧 How to Use
|
||||||
|
|
||||||
|
There are two ways to use awesome-copilot customizations in your project:
|
||||||
|
|
||||||
|
### 🎛️ Configuration File Approach (Recommended)
|
||||||
|
|
||||||
|
Use our configuration system to manage all customizations in one place:
|
||||||
|
|
||||||
|
1. **Clone the repository** to your local machine or include it as a git submodule
|
||||||
|
2. **Generate a configuration file** with all available options:
|
||||||
|
```bash
|
||||||
|
node awesome-copilot.js init
|
||||||
|
```
|
||||||
|
3. **Edit the configuration** to enable the items you want:
|
||||||
|
```yaml
|
||||||
|
collections:
|
||||||
|
frontend-web-dev: true # Enable entire collection
|
||||||
|
prompts:
|
||||||
|
create-readme: true # Enable specific prompts
|
||||||
|
instructions:
|
||||||
|
typescript-best-practices: true
|
||||||
|
```
|
||||||
|
4. **Apply the configuration** to copy files to your project:
|
||||||
|
```bash
|
||||||
|
node awesome-copilot.js apply
|
||||||
|
```
|
||||||
|
|
||||||
|
See [CONFIG.md](CONFIG.md) for detailed configuration documentation.
|
||||||
|
|
||||||
|
### 📁 Manual File Approach
|
||||||
|
|
||||||
|
Browse the collections and manually copy files you want to use:
|
||||||
|
|
||||||
### 🎯 Prompts
|
### 🎯 Prompts
|
||||||
Use the `/` command in GitHub Copilot Chat to access prompts:
|
Use the `/` command in GitHub Copilot Chat to access prompts:
|
||||||
```
|
```
|
||||||
|
|||||||
230
apply-config.js
Executable file
230
apply-config.js
Executable file
@ -0,0 +1,230 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
|
||||||
|
const fs = require("fs");
|
||||||
|
const path = require("path");
|
||||||
|
const { parseCollectionYaml } = require("./yaml-parser");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Simple YAML parser for configuration files
|
||||||
|
*/
|
||||||
|
function parseConfigYaml(filePath) {
|
||||||
|
try {
|
||||||
|
const content = fs.readFileSync(filePath, "utf8");
|
||||||
|
const lines = content.split("\n");
|
||||||
|
const result = {};
|
||||||
|
let currentSection = null;
|
||||||
|
|
||||||
|
for (const line of lines) {
|
||||||
|
const trimmed = line.trim();
|
||||||
|
|
||||||
|
// Skip comments and empty lines
|
||||||
|
if (!trimmed || trimmed.startsWith("#")) continue;
|
||||||
|
|
||||||
|
// Handle key-value pairs
|
||||||
|
if (trimmed.includes(":")) {
|
||||||
|
const colonIndex = trimmed.indexOf(":");
|
||||||
|
const key = trimmed.substring(0, colonIndex).trim();
|
||||||
|
let value = trimmed.substring(colonIndex + 1).trim();
|
||||||
|
|
||||||
|
// Remove quotes if present
|
||||||
|
if ((value.startsWith('"') && value.endsWith('"')) ||
|
||||||
|
(value.startsWith("'") && value.endsWith("'"))) {
|
||||||
|
value = value.slice(1, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle sections (no value)
|
||||||
|
if (!value) {
|
||||||
|
currentSection = key;
|
||||||
|
if (!result[currentSection]) {
|
||||||
|
result[currentSection] = {};
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Handle boolean values
|
||||||
|
if (value === "true") value = true;
|
||||||
|
else if (value === "false") value = false;
|
||||||
|
|
||||||
|
if (currentSection) {
|
||||||
|
result[currentSection][key] = value;
|
||||||
|
} else {
|
||||||
|
result[key] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`Error parsing config file ${filePath}: ${error.message}`);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Apply configuration and copy enabled files to project
|
||||||
|
*/
|
||||||
|
async function applyConfig(configPath = "awesome-copilot.config.yml") {
|
||||||
|
if (!fs.existsSync(configPath)) {
|
||||||
|
console.error(`Configuration file not found: ${configPath}`);
|
||||||
|
console.log("Run 'node generate-config.js' to create a configuration file first.");
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
const config = parseConfigYaml(configPath);
|
||||||
|
if (!config) {
|
||||||
|
console.error("Failed to parse configuration file");
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log("Applying awesome-copilot configuration...");
|
||||||
|
|
||||||
|
const rootDir = __dirname;
|
||||||
|
const outputDir = config.project?.output_directory || ".github";
|
||||||
|
|
||||||
|
// Create output directory structure
|
||||||
|
ensureDirectoryExists(outputDir);
|
||||||
|
ensureDirectoryExists(path.join(outputDir, "copilot"));
|
||||||
|
ensureDirectoryExists(path.join(outputDir, "instructions"));
|
||||||
|
|
||||||
|
let copiedCount = 0;
|
||||||
|
const summary = {
|
||||||
|
prompts: 0,
|
||||||
|
instructions: 0,
|
||||||
|
chatmodes: 0,
|
||||||
|
collections: 0
|
||||||
|
};
|
||||||
|
|
||||||
|
// Process collections first (they can enable individual items)
|
||||||
|
const enabledItems = new Set();
|
||||||
|
if (config.collections) {
|
||||||
|
for (const [collectionName, enabled] of Object.entries(config.collections)) {
|
||||||
|
if (enabled) {
|
||||||
|
const collectionPath = path.join(rootDir, "collections", `${collectionName}.collection.yml`);
|
||||||
|
if (fs.existsSync(collectionPath)) {
|
||||||
|
const collection = parseCollectionYaml(collectionPath);
|
||||||
|
if (collection && collection.items) {
|
||||||
|
collection.items.forEach(item => {
|
||||||
|
enabledItems.add(item.path);
|
||||||
|
});
|
||||||
|
summary.collections++;
|
||||||
|
console.log(`✓ Enabled collection: ${collectionName} (${collection.items.length} items)`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Process prompts
|
||||||
|
if (config.prompts) {
|
||||||
|
for (const [promptName, enabled] of Object.entries(config.prompts)) {
|
||||||
|
if (enabled) {
|
||||||
|
const sourcePath = path.join(rootDir, "prompts", `${promptName}.prompt.md`);
|
||||||
|
if (fs.existsSync(sourcePath)) {
|
||||||
|
const destPath = path.join(outputDir, "copilot", `${promptName}.prompt.md`);
|
||||||
|
copyFile(sourcePath, destPath);
|
||||||
|
copiedCount++;
|
||||||
|
summary.prompts++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Process instructions
|
||||||
|
if (config.instructions) {
|
||||||
|
for (const [instructionName, enabled] of Object.entries(config.instructions)) {
|
||||||
|
if (enabled) {
|
||||||
|
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++;
|
||||||
|
summary.instructions++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Process chat modes
|
||||||
|
if (config.chatmodes) {
|
||||||
|
for (const [chatmodeName, enabled] of Object.entries(config.chatmodes)) {
|
||||||
|
if (enabled) {
|
||||||
|
const sourcePath = path.join(rootDir, "chatmodes", `${chatmodeName}.chatmode.md`);
|
||||||
|
if (fs.existsSync(sourcePath)) {
|
||||||
|
const destPath = path.join(outputDir, "copilot", `${chatmodeName}.chatmode.md`);
|
||||||
|
copyFile(sourcePath, destPath);
|
||||||
|
copiedCount++;
|
||||||
|
summary.chatmodes++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Process items from enabled collections
|
||||||
|
for (const itemPath of enabledItems) {
|
||||||
|
const sourcePath = path.join(rootDir, itemPath);
|
||||||
|
if (fs.existsSync(sourcePath)) {
|
||||||
|
const fileName = path.basename(itemPath);
|
||||||
|
let destPath;
|
||||||
|
|
||||||
|
if (fileName.endsWith('.prompt.md') || fileName.endsWith('.chatmode.md')) {
|
||||||
|
destPath = path.join(outputDir, "copilot", fileName);
|
||||||
|
} else if (fileName.endsWith('.instructions.md')) {
|
||||||
|
destPath = path.join(outputDir, "instructions", fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (destPath && !fs.existsSync(destPath)) {
|
||||||
|
copyFile(sourcePath, destPath);
|
||||||
|
copiedCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate summary
|
||||||
|
console.log("\n" + "=".repeat(50));
|
||||||
|
console.log("Configuration applied successfully!");
|
||||||
|
console.log("=".repeat(50));
|
||||||
|
console.log(`📂 Output directory: ${outputDir}`);
|
||||||
|
console.log(`📝 Total files copied: ${copiedCount}`);
|
||||||
|
console.log(`🎯 Prompts: ${summary.prompts}`);
|
||||||
|
console.log(`📋 Instructions: ${summary.instructions}`);
|
||||||
|
console.log(`💭 Chat modes: ${summary.chatmodes}`);
|
||||||
|
console.log(`📦 Collections: ${summary.collections}`);
|
||||||
|
|
||||||
|
if (config.project?.name) {
|
||||||
|
console.log(`🏷️ Project: ${config.project.name}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log("\nNext steps:");
|
||||||
|
console.log("1. Add the files to your version control system");
|
||||||
|
console.log("2. Use prompts with /awesome-copilot command in GitHub Copilot Chat");
|
||||||
|
console.log("3. Instructions will automatically apply to your coding");
|
||||||
|
console.log("4. Import chat modes in VS Code settings");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ensure directory exists, create if it doesn't
|
||||||
|
*/
|
||||||
|
function ensureDirectoryExists(dirPath) {
|
||||||
|
if (!fs.existsSync(dirPath)) {
|
||||||
|
fs.mkdirSync(dirPath, { recursive: true });
|
||||||
|
console.log(`📁 Created directory: ${dirPath}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copy file from source to destination
|
||||||
|
*/
|
||||||
|
function copyFile(sourcePath, destPath) {
|
||||||
|
fs.copyFileSync(sourcePath, destPath);
|
||||||
|
console.log(`✓ Copied: ${path.basename(sourcePath)}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
// CLI usage
|
||||||
|
if (require.main === module) {
|
||||||
|
const configPath = process.argv[2] || "awesome-copilot.config.yml";
|
||||||
|
applyConfig(configPath).catch(error => {
|
||||||
|
console.error("Error applying configuration:", error.message);
|
||||||
|
process.exit(1);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = { applyConfig, parseConfigYaml };
|
||||||
93
awesome-copilot.js
Executable file
93
awesome-copilot.js
Executable file
@ -0,0 +1,93 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
|
||||||
|
const { generateConfig } = require("./generate-config");
|
||||||
|
const { applyConfig } = require("./apply-config");
|
||||||
|
|
||||||
|
const commands = {
|
||||||
|
init: {
|
||||||
|
description: "Generate a new configuration file",
|
||||||
|
usage: "awesome-copilot init [config-file]",
|
||||||
|
action: async (args) => {
|
||||||
|
const configFile = args[0] || "awesome-copilot.config.yml";
|
||||||
|
generateConfig(configFile);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
apply: {
|
||||||
|
description: "Apply configuration and copy files to project",
|
||||||
|
usage: "awesome-copilot apply [config-file]",
|
||||||
|
action: async (args) => {
|
||||||
|
const configFile = args[0] || "awesome-copilot.config.yml";
|
||||||
|
await applyConfig(configFile);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
help: {
|
||||||
|
description: "Show help information",
|
||||||
|
usage: "awesome-copilot help",
|
||||||
|
action: () => {
|
||||||
|
showHelp();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
function showHelp() {
|
||||||
|
console.log("🤖 Awesome GitHub Copilot Configuration Tool");
|
||||||
|
console.log("=".repeat(50));
|
||||||
|
console.log("");
|
||||||
|
console.log("Usage: awesome-copilot <command> [options]");
|
||||||
|
console.log("");
|
||||||
|
console.log("Commands:");
|
||||||
|
|
||||||
|
for (const [name, cmd] of Object.entries(commands)) {
|
||||||
|
console.log(` ${name.padEnd(10)} ${cmd.description}`);
|
||||||
|
console.log(` ${' '.repeat(10)} ${cmd.usage}`);
|
||||||
|
console.log("");
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log("Examples:");
|
||||||
|
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 apply my-config.yml # Apply specific config");
|
||||||
|
console.log("");
|
||||||
|
console.log("Workflow:");
|
||||||
|
console.log(" 1. Run 'awesome-copilot init' to create a configuration file");
|
||||||
|
console.log(" 2. Edit the configuration file to enable desired items");
|
||||||
|
console.log(" 3. Run 'awesome-copilot apply' to copy files to your project");
|
||||||
|
}
|
||||||
|
|
||||||
|
function showError(message) {
|
||||||
|
console.error(`❌ Error: ${message}`);
|
||||||
|
console.log("");
|
||||||
|
console.log("Run 'awesome-copilot help' for usage information.");
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function main() {
|
||||||
|
const args = process.argv.slice(2);
|
||||||
|
|
||||||
|
if (args.length === 0) {
|
||||||
|
showHelp();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const command = args[0];
|
||||||
|
const commandArgs = args.slice(1);
|
||||||
|
|
||||||
|
if (!commands[command]) {
|
||||||
|
showError(`Unknown command: ${command}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
await commands[command].action(commandArgs);
|
||||||
|
} catch (error) {
|
||||||
|
showError(error.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (require.main === module) {
|
||||||
|
main();
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = { main };
|
||||||
125
generate-config.js
Executable file
125
generate-config.js
Executable file
@ -0,0 +1,125 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
|
||||||
|
const fs = require("fs");
|
||||||
|
const path = require("path");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate a configuration file with all available options
|
||||||
|
*/
|
||||||
|
function generateConfig(outputPath = "awesome-copilot.config.yml") {
|
||||||
|
const rootDir = __dirname;
|
||||||
|
|
||||||
|
// Get all available items
|
||||||
|
const prompts = getAvailableItems(path.join(rootDir, "prompts"), ".prompt.md");
|
||||||
|
const instructions = getAvailableItems(path.join(rootDir, "instructions"), ".instructions.md");
|
||||||
|
const chatmodes = getAvailableItems(path.join(rootDir, "chatmodes"), ".chatmode.md");
|
||||||
|
const collections = getAvailableItems(path.join(rootDir, "collections"), ".collection.yml");
|
||||||
|
|
||||||
|
// Create config structure
|
||||||
|
const config = {
|
||||||
|
version: "1.0",
|
||||||
|
project: {
|
||||||
|
name: "My Project",
|
||||||
|
description: "A project using awesome-copilot customizations",
|
||||||
|
output_directory: ".github"
|
||||||
|
},
|
||||||
|
prompts: {},
|
||||||
|
instructions: {},
|
||||||
|
chatmodes: {},
|
||||||
|
collections: {}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Populate with all items disabled by default (user can enable what they want)
|
||||||
|
prompts.forEach(item => {
|
||||||
|
config.prompts[item] = false;
|
||||||
|
});
|
||||||
|
|
||||||
|
instructions.forEach(item => {
|
||||||
|
config.instructions[item] = false;
|
||||||
|
});
|
||||||
|
|
||||||
|
chatmodes.forEach(item => {
|
||||||
|
config.chatmodes[item] = false;
|
||||||
|
});
|
||||||
|
|
||||||
|
collections.forEach(item => {
|
||||||
|
config.collections[item] = false;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Convert to YAML format manually (since we don't want to add dependencies)
|
||||||
|
const yamlContent = objectToYaml(config);
|
||||||
|
|
||||||
|
// Add header comment
|
||||||
|
const header = `# Awesome Copilot Configuration File
|
||||||
|
# Generated on ${new Date().toISOString()}
|
||||||
|
#
|
||||||
|
# This file allows you to enable/disable specific prompts, instructions,
|
||||||
|
# chat modes, and collections for your project.
|
||||||
|
#
|
||||||
|
# Set items to 'true' to include them in your project
|
||||||
|
# Set items to 'false' to exclude them
|
||||||
|
#
|
||||||
|
# After configuring, run: node apply-config.js
|
||||||
|
#
|
||||||
|
|
||||||
|
`;
|
||||||
|
|
||||||
|
const fullContent = header + yamlContent;
|
||||||
|
|
||||||
|
fs.writeFileSync(outputPath, fullContent);
|
||||||
|
console.log(`Configuration file generated: ${outputPath}`);
|
||||||
|
console.log(`Found ${prompts.length} prompts, ${instructions.length} instructions, ${chatmodes.length} chat modes, ${collections.length} collections`);
|
||||||
|
console.log("\nNext steps:");
|
||||||
|
console.log("1. Edit the configuration file to enable desired items");
|
||||||
|
console.log("2. Run: node apply-config.js to apply the configuration");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all available items in a directory
|
||||||
|
*/
|
||||||
|
function getAvailableItems(directory, extension) {
|
||||||
|
if (!fs.existsSync(directory)) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
return fs.readdirSync(directory)
|
||||||
|
.filter(file => file.endsWith(extension))
|
||||||
|
.map(file => path.basename(file, extension))
|
||||||
|
.sort();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert object to YAML format (simple implementation)
|
||||||
|
*/
|
||||||
|
function objectToYaml(obj, indent = 0) {
|
||||||
|
const spaces = " ".repeat(indent);
|
||||||
|
let yaml = "";
|
||||||
|
|
||||||
|
for (const [key, value] of Object.entries(obj)) {
|
||||||
|
if (typeof value === "object" && value !== null) {
|
||||||
|
yaml += `${spaces}${key}:\n`;
|
||||||
|
yaml += objectToYaml(value, indent + 1);
|
||||||
|
} else {
|
||||||
|
const valueStr = typeof value === "string" ? `"${value}"` : value;
|
||||||
|
yaml += `${spaces}${key}: ${valueStr}\n`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return yaml;
|
||||||
|
}
|
||||||
|
|
||||||
|
// CLI usage
|
||||||
|
if (require.main === module) {
|
||||||
|
const outputPath = process.argv[2] || "awesome-copilot.config.yml";
|
||||||
|
generateConfig(outputPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = { generateConfig, getAvailableItems };
|
||||||
|
|
||||||
|
// CLI usage
|
||||||
|
if (require.main === module) {
|
||||||
|
const outputPath = process.argv[2] || "awesome-copilot.config.yml";
|
||||||
|
generateConfig(outputPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = { generateConfig, getAvailableItems };
|
||||||
@ -5,6 +5,9 @@
|
|||||||
"main": "update-readme.js",
|
"main": "update-readme.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "node update-readme.js",
|
"build": "node update-readme.js",
|
||||||
|
"config:init": "node generate-config.js",
|
||||||
|
"config:apply": "node apply-config.js",
|
||||||
|
"config": "node awesome-copilot.js",
|
||||||
"contributors:add": "all-contributors add",
|
"contributors:add": "all-contributors add",
|
||||||
"contributors:generate": "all-contributors generate",
|
"contributors:generate": "all-contributors generate",
|
||||||
"contributors:check": "all-contributors check"
|
"contributors:check": "all-contributors check"
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user