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
JavaScript
;
/**
* 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