UNPKG

instruqt

Version:

CLI tool for deploying AI agent context documentation across multiple platforms with dual MERN/module support

148 lines (128 loc) • 5.25 kB
#!/usr/bin/env node /** * @file CLI wrapper for pack application system * @description Provides instruqt apply command for user-customizable context documents * @usage npx instruqt apply <pack-spec> [--plan] * * RATIONALE: Separates pack application from original context deployment to maintain * backward compatibility while adding powerful customization capabilities. Users can * choose between built-in contexts (instruct) or custom packs (apply). * * DESIGN DECISIONS: * 1. Separate command: apply vs instruct maintains clear separation of concerns * 2. CommonJS compatibility: Works with existing project structure * 3. Comprehensive help: Reduces learning curve for pack system adoption * 4. Plan mode: Enables safe preview of changes before application */ const { apply, plan } = require('../lib/packs'); const path = require('path'); /** * Display usage information and examples * * RATIONALE: Comprehensive help reduces support burden and demonstrates * the flexibility of the pack system through concrete examples. */ function showUsage() { console.log('Usage: instruqt apply <pack-spec> [options]'); console.log(''); console.log('Pack Specifications:'); console.log(' ./path/to/pack Use local folder'); console.log(' alias-name Use alias from instruqt.config.json'); console.log(' @scope/package Use npm package'); console.log(' pack-name Use pack from ~/.config/instruqt/packs/'); console.log(''); console.log('Options:'); console.log(' --plan Preview changes without applying'); console.log(' --help, -h Show this help message'); console.log(''); console.log('Examples:'); console.log(' instruqt apply ./instruqt/packs/my-pack'); console.log(' instruqt apply local-mern --plan'); console.log(' instruqt apply @acme-instruqt/nextjs-team'); console.log(' instruqt apply my-custom-pack'); console.log(''); console.log('Pack Structure:'); console.log(' my-pack/'); console.log(' pack.json Pack manifest'); console.log(' files/ Files to copy'); console.log(' README.md'); console.log(' agent-prompt.md'); console.log(''); console.log('Configuration (optional):'); console.log(' Create instruqt.config.json in project root:'); console.log(' {'); console.log(' "packs": {'); console.log(' "local-mern": "./instruqt/packs/mern-basic",'); console.log(' "team-next": "@acme-instruqt/nextjs-team"'); console.log(' }'); console.log(' }'); } /** * Apply pack with user feedback * @param {string} spec - Pack specification * @param {boolean} dryRun - Whether to preview instead of apply * * DESIGN DECISIONS: * 1. Detailed output: Shows every operation for transparency * 2. Action indicators: Clear visual distinction between operations * 3. Error context: Helpful guidance when operations fail * 4. Exit codes: Proper CLI behavior for CI/CD integration */ async function applyPack(spec, dryRun = false) { try { console.log(`šŸš€ ${dryRun ? 'Planning' : 'Applying'} pack: ${spec}\n`); const results = await apply(spec, { dryRun }); if (dryRun) { console.log('šŸ“‹ Planned operations:'); } else { console.log('āœ… Applied operations:'); } for (const result of results) { const { src, dest, action } = result; const icon = action === 'create' ? 'āž•' : action === 'replace' ? 'šŸ”„' : action === 'skip' ? 'ā­ļø' : 'āŒ'; console.log(` ${icon} ${action}: ${path.basename(src)} → ${dest}`); } const counts = results.reduce((acc, r) => { acc[r.action] = (acc[r.action] || 0) + 1; return acc; }, {}); console.log(`\nšŸ“Š Summary: ${Object.entries(counts).map(([action, count]) => `${count} ${action}`).join(', ')}`); if (dryRun) { console.log('\nšŸ’” Run without --plan to apply these changes'); } else { console.log('\nšŸŽ‰ Pack application complete!'); } } catch (error) { console.error(`āŒ Error: ${error.message}`); // Provide helpful guidance for common errors if (error.message.includes('not found')) { console.error('\nšŸ’” Make sure the pack specification is correct:'); console.error(' - For local paths: ensure the directory exists'); console.error(' - For npm packages: ensure the package is installed'); console.error(' - For aliases: check your instruqt.config.json'); console.error(' - For home packs: check ~/.config/instruqt/packs/'); } process.exit(1); } } // Command line argument parsing - moved to function to avoid global scope function parseArguments() { const args = process.argv.slice(2); if (args.length === 0 || args[0] === '--help' || args[0] === '-h') { showUsage(); process.exit(0); } const spec = args[0]; const dryRun = args.includes('--plan'); return { spec, dryRun }; } const { spec, dryRun } = parseArguments(); // Validate pack specification if (!spec || spec.startsWith('-')) { console.error('āŒ Error: Pack specification is required'); showUsage(); process.exit(1); } applyPack(spec, dryRun);