UNPKG

cortexweaver

Version:

CortexWeaver is a command-line interface (CLI) tool that orchestrates a swarm of specialized AI agents, powered by Claude Code and Gemini CLI, to assist in software development. It transforms a high-level project plan (plan.md) into a series of coordinate

436 lines (431 loc) • 16.4 kB
#!/usr/bin/env node "use strict"; /** * CLI utility for CortexWeaver 3.0 Prompt Improvement Workflow * * This utility provides command-line access to the prompt improvement system: * - View version history * - Process pending approvals * - Apply improvements * - Rollback changes * - Generate reports */ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); Object.defineProperty(exports, "__esModule", { value: true }); exports.PromptImprovementCLI = void 0; const fs = __importStar(require("fs")); const path = __importStar(require("path")); const prompt_improvement_1 = require("../prompt-improvement"); const cognitive_canvas_1 = require("../cognitive-canvas"); class PromptImprovementCLI { constructor(options = {}) { this.workflow = null; this.options = { workspaceRoot: process.cwd(), format: 'table', hoursBack: 24, verbose: false, ...options }; } async initialize() { if (!this.options.workspaceRoot) { throw new Error('Workspace root is required'); } // Create a mock cognitive canvas for CLI usage const cognitiveCanvas = new cognitive_canvas_1.CognitiveCanvas({ uri: process.env.NEO4J_URI || 'bolt://localhost:7687', username: process.env.NEO4J_USERNAME || 'neo4j', password: process.env.NEO4J_PASSWORD || 'password', projectId: 'cli-session', sessionId: `cli-${Date.now()}` }); this.workflow = new prompt_improvement_1.PromptImprovementWorkflow({ workspaceRoot: this.options.workspaceRoot, cognitiveCanvas }); } async run() { if (!this.workflow) { await this.initialize(); } const command = this.options.command || this.parseCommand(); switch (command) { case 'history': await this.showVersionHistory(); break; case 'status': await this.showStatus(); break; case 'apply': await this.applyImprovements(); break; case 'rollback': await this.rollbackVersion(); break; case 'audit': await this.showAuditTrail(); break; case 'changes': await this.showRecentChanges(); break; case 'validate': await this.validateWorkspace(); break; case 'help': this.showHelp(); break; default: console.error(`Unknown command: ${command}`); this.showHelp(); process.exit(1); } } parseCommand() { const args = process.argv.slice(2); return args[0] || 'help'; } async showVersionHistory() { if (!this.workflow) return; const versions = await this.workflow.getVersionHistory(this.options.promptFile); if (this.options.format === 'json') { console.log(JSON.stringify(versions, null, 2)); return; } if (versions.length === 0) { console.log('No version history found.'); return; } console.log(`\nšŸ“‹ Version History${this.options.promptFile ? ` for ${this.options.promptFile}` : ''}\n`); for (const version of versions.reverse()) { const statusIcon = this.getStatusIcon(version.status); const date = new Date(version.timestamp).toLocaleDateString(); console.log(`${statusIcon} ${version.id}`); console.log(` File: ${version.promptFile}`); console.log(` Date: ${date}`); console.log(` Status: ${version.status.toUpperCase()}`); console.log(` Rationale: ${version.rationale}`); if (version.approvedBy) { console.log(` Approved by: ${version.approvedBy} (${new Date(version.approvedAt).toLocaleDateString()})`); } if (this.options.verbose && version.diff) { console.log(` Diff preview: ${version.diff.substring(0, 100)}...`); } console.log(''); } } async showStatus() { if (!this.workflow) return; const versions = await this.workflow.getVersionHistory(); const auditTrail = await this.workflow.getAuditTrail(); const stats = { total: versions.length, pending: versions.filter(v => v.status === 'pending').length, approved: versions.filter(v => v.status === 'approved').length, applied: versions.filter(v => v.status === 'applied').length, rejected: versions.filter(v => v.status === 'rejected').length, auditEntries: auditTrail.length }; if (this.options.format === 'json') { console.log(JSON.stringify(stats, null, 2)); return; } console.log('\nšŸ“Š Prompt Improvement Workflow Status\n'); console.log(`Total Versions: ${stats.total}`); console.log(`ā”œā”€ 🟔 Pending: ${stats.pending}`); console.log(`ā”œā”€ 🟢 Approved: ${stats.approved}`); console.log(`ā”œā”€ āœ… Applied: ${stats.applied}`); console.log(`└─ šŸ”“ Rejected: ${stats.rejected}`); console.log(`\nAudit Trail Entries: ${stats.auditEntries}`); if (stats.pending > 0) { console.log(`\nāš ļø ${stats.pending} improvements pending approval`); } if (stats.approved > 0) { console.log(`\n✨ ${stats.approved} improvements ready to apply`); } } async applyImprovements() { if (!this.workflow) return; const versions = await this.workflow.getVersionHistory(); const approved = versions.filter(v => v.status === 'approved'); if (approved.length === 0) { console.log('No approved improvements to apply.'); return; } console.log(`\nšŸš€ Applying ${approved.length} approved improvements...\n`); let applied = 0; let failed = 0; for (const version of approved) { try { const result = await this.workflow.applyPromptImprovement(version); if (result.success) { console.log(`āœ… Applied: ${version.promptFile}`); console.log(` Version: ${version.id}`); console.log(` Backup: ${result.backupPath}`); applied++; } else { console.log(`āŒ Failed: ${version.promptFile} - ${result.error}`); failed++; } } catch (error) { console.log(`āŒ Error: ${version.promptFile} - ${error.message}`); failed++; } console.log(''); } console.log(`šŸ“ˆ Summary: ${applied} applied, ${failed} failed`); } async rollbackVersion() { if (!this.workflow) return; const { promptFile, versionId } = this.options; if (!promptFile || !versionId) { console.error('Both --prompt-file and --version-id are required for rollback'); return; } try { const result = await this.workflow.rollbackToVersion(promptFile, versionId); if (result.success) { console.log(`āœ… Successfully rolled back ${promptFile} to version ${versionId}`); if (result.newVersionId) { console.log(`šŸ“ Created rollback version: ${result.newVersionId}`); } } else { console.log(`āŒ Rollback failed: ${result.error}`); } } catch (error) { console.error(`āŒ Rollback error: ${error.message}`); } } async showAuditTrail() { if (!this.workflow) return; const auditTrail = await this.workflow.getAuditTrail(this.options.promptFile); if (this.options.format === 'json') { console.log(JSON.stringify(auditTrail, null, 2)); return; } if (auditTrail.length === 0) { console.log('No audit trail entries found.'); return; } console.log(`\nšŸ“‹ Audit Trail${this.options.promptFile ? ` for ${this.options.promptFile}` : ''}\n`); for (const entry of auditTrail.reverse()) { const actionIcon = this.getActionIcon(entry.action); const date = new Date(entry.timestamp).toLocaleString(); console.log(`${actionIcon} ${entry.action.toUpperCase()}`); console.log(` File: ${entry.promptFile}`); console.log(` By: ${entry.performedBy}`); console.log(` Date: ${date}`); if (this.options.verbose && entry.details) { console.log(` Details: ${JSON.stringify(entry.details, null, 4)}`); } console.log(''); } } async showRecentChanges() { if (!this.workflow) return; const changes = await this.workflow.getRecentChanges(this.options.hoursBack); if (this.options.format === 'json') { console.log(JSON.stringify(changes, null, 2)); return; } if (changes.length === 0) { console.log(`No changes in the last ${this.options.hoursBack} hours.`); return; } console.log(`\nšŸ”„ Recent Changes (Last ${this.options.hoursBack} hours)\n`); for (const change of changes) { const reloadIcon = change.requires_reload ? 'šŸ”„' : 'šŸ“'; const date = new Date(change.timestamp).toLocaleString(); console.log(`${reloadIcon} ${change.promptFile}`); console.log(` Action: ${change.action}`); console.log(` Date: ${date}`); console.log(` Version: ${change.versionId}`); if (change.requires_reload) { console.log(' 🚨 Hot-reload required'); } console.log(''); } } async validateWorkspace() { if (!this.workflow) return; console.log('\nšŸ” Validating workspace...\n'); const workspaceRoot = this.options.workspaceRoot; const promptsDir = path.join(workspaceRoot, 'prompts'); const historyDir = path.join(workspaceRoot, '.cortex-history'); let issues = 0; // Check prompts directory if (!fs.existsSync(promptsDir)) { console.log('āŒ Prompts directory not found'); issues++; } else { console.log('āœ… Prompts directory found'); } // Check history directory if (!fs.existsSync(historyDir)) { console.log('āš ļø History directory not found (will be created)'); } else { console.log('āœ… History directory found'); } // Check version history file const versionsFile = path.join(historyDir, 'versions.json'); if (fs.existsSync(versionsFile)) { try { const versions = await this.workflow.getVersionHistory(); console.log(`āœ… Version history valid (${versions.length} entries)`); } catch (error) { console.log('āŒ Version history corrupted'); issues++; } } else { console.log('šŸ“ No version history (clean workspace)'); } console.log(`\nšŸ“Š Validation complete: ${issues > 0 ? `${issues} issues found` : 'All checks passed'}`); } getStatusIcon(status) { const icons = { pending: '🟔', approved: '🟢', applied: 'āœ…', rejected: 'šŸ”“', rolled_back: 'āŖ' }; return icons[status] || 'ā“'; } getActionIcon(action) { const icons = { proposed: 'šŸ“', approved: 'āœ…', rejected: 'āŒ', applied: 'šŸš€', rolled_back: 'āŖ' }; return icons[action] || 'šŸ“„'; } showHelp() { console.log(` CortexWeaver 3.0 Prompt Improvement CLI USAGE: cortex-prompts <command> [options] COMMANDS: history Show version history status Show workflow status apply Apply approved improvements rollback Rollback to a specific version audit Show audit trail changes Show recent changes validate Validate workspace help Show this help message OPTIONS: --workspace-root <path> Workspace root directory (default: current) --prompt-file <file> Target specific prompt file --version-id <id> Target specific version ID --format <json|table> Output format (default: table) --hours-back <hours> Hours back for recent changes (default: 24) --verbose Show detailed information EXAMPLES: cortex-prompts status cortex-prompts history --prompt-file agents/architect.md cortex-prompts apply --verbose cortex-prompts rollback --prompt-file agents/coder.md --version-id abc123 cortex-prompts changes --hours-back 48 --format json cortex-prompts audit --prompt-file agents/governor.md For more information, see the documentation at: https://github.com/cortexweaver/cortexweaver/docs/prompt-improvement-workflow.md `); } } exports.PromptImprovementCLI = PromptImprovementCLI; // CLI entry point async function main() { const args = process.argv.slice(2); const options = {}; // Parse command line arguments for (let i = 0; i < args.length; i++) { const arg = args[i]; switch (arg) { case '--workspace-root': options.workspaceRoot = args[++i]; break; case '--prompt-file': options.promptFile = args[++i]; break; case '--version-id': options.versionId = args[++i]; break; case '--format': options.format = args[++i]; break; case '--hours-back': options.hoursBack = parseInt(args[++i], 10); break; case '--verbose': options.verbose = true; break; default: if (!arg.startsWith('--')) { options.command = arg; } break; } } try { const cli = new PromptImprovementCLI(options); await cli.run(); } catch (error) { console.error(`āŒ Error: ${error.message}`); process.exit(1); } } // Run if this file is executed directly if (require.main === module) { main().catch(console.error); } //# sourceMappingURL=prompt-improvement-cli.js.map