basant307/AI_Governance_Project
045
1/**2 * @license3 * Copyright 2025 Google LLC4 * SPDX-License-Identifier: Apache-2.05 */6 7/**8 * Tool for migrating TOML commands to Markdown format.9 */10 11import { promises as fs } from 'node:fs';12import path from 'node:path';13import { glob } from 'glob';14import { convertTomlToMarkdown } from '@qwen-code/qwen-code-core';15import { t } from '../i18n/index.js';16 17export interface MigrationResult {18 success: boolean;19 convertedFiles: string[];20 failedFiles: Array<{ file: string; error: string }>;21}22 23export interface MigrationOptions {24 /** Directory containing command files */25 commandDir: string;26 /** Whether to create backups (default: true) */27 createBackup?: boolean;28 /** Whether to delete original TOML files after migration (default: false) */29 deleteOriginal?: boolean;30}31 32/**33 * Scans a directory for TOML command files.34 * @param commandDir Directory to scan35 * @returns Array of TOML file paths (relative to commandDir)36 */37export async function detectTomlCommands(38 commandDir: string,39): Promise<string[]> {40 try {41 await fs.access(commandDir);42 } catch {43 // Directory doesn't exist44 return [];45 }46 47 const tomlFiles = await glob('**/*.toml', {48 cwd: commandDir,49 nodir: true,50 dot: false,51 });52 53 return tomlFiles;54}55 56/**57 * Migrates TOML command files to Markdown format.58 * @param options Migration options59 * @returns Migration result with details60 */61export async function migrateTomlCommands(62 options: MigrationOptions,63): Promise<MigrationResult> {64 const { commandDir, createBackup = true, deleteOriginal = false } = options;65 66 const result: MigrationResult = {67 success: true,68 convertedFiles: [],69 failedFiles: [],70 };71 72 // Detect TOML files73 const tomlFiles = await detectTomlCommands(commandDir);74 75 if (tomlFiles.length === 0) {76 return result;77 }78 79 // Process each TOML file80 for (const relativeFile of tomlFiles) {81 const tomlPath = path.join(commandDir, relativeFile);82 83 try {84 // Read TOML file85 const tomlContent = await fs.readFile(tomlPath, 'utf-8');86 87 // Convert to Markdown88 const markdownContent = convertTomlToMarkdown(tomlContent);89 90 // Generate Markdown file path (same location, .md extension)91 const markdownPath = tomlPath.replace(/\.toml$/, '.md');92 93 // Check if Markdown file already exists94 try {95 await fs.access(markdownPath);96 throw new Error(97 t('Markdown file already exists: {{filename}}', {98 filename: path.basename(markdownPath),99 }),100 );101 } catch (error) {102 if ((error as NodeJS.ErrnoException).code !== 'ENOENT') {103 throw error;104 }105 // File doesn't exist, continue106 }107 108 // Write Markdown file109 await fs.writeFile(markdownPath, markdownContent, 'utf-8');110 111 // Backup original if requested (rename to .toml.backup)112 if (createBackup) {113 const backupPath = `${tomlPath}.backup`;114 await fs.rename(tomlPath, backupPath);115 } else if (deleteOriginal) {116 // Delete original if requested and no backup117 await fs.unlink(tomlPath);118 }119 120 result.convertedFiles.push(relativeFile);121 } catch (error) {122 result.success = false;123 result.failedFiles.push({124 file: relativeFile,125 error: error instanceof Error ? error.message : String(error),126 });127 }128 }129 130 return result;131}132 133/**134 * Generates a migration report message.135 * @param tomlFiles List of TOML files found136 * @returns Human-readable migration prompt message137 */138export function generateMigrationPrompt(tomlFiles: string[]): string {139 if (tomlFiles.length === 0) {140 return '';141 }142 143 const count = tomlFiles.length;144 const moreCount = tomlFiles.length - 3;145 const fileList =146 tomlFiles.length <= 5147 ? tomlFiles.map((f) => ` - ${f}`).join('\n')148 : ` - ${tomlFiles.slice(0, 3).join('\n - ')}\n - ${t('... and {{count}} more', { count: String(moreCount) })}`;149 150 return `151⚠ ${t('TOML Command Format Deprecation Notice')}152 153${t('Found {{count}} command file(s) in TOML format:', { count: String(count) })}154${fileList}155 156${t('The TOML format for commands is being deprecated in favor of Markdown format.')}157${t('Markdown format is more readable and easier to edit.')}158 159${t('You can migrate these files automatically using:')}160 qwen-code migrate-commands161 162${t('Or manually convert each file:')}163 - ${t('TOML: prompt = "..." / description = "..."')}164 - ${t('Markdown: YAML frontmatter + content')}165 166${t('The migration tool will:')}167 ✓ ${t('Convert TOML files to Markdown')}168 ✓ ${t('Create backups of original files')}169 ✓ ${t('Preserve all command functionality')}170 171${t('TOML format will continue to work for now, but migration is recommended.')}172`.trim();173}174 