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
443 lines (421 loc) โข 18.3 kB
JavaScript
;
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.CLICommands = void 0;
const fs = __importStar(require("fs"));
const path = __importStar(require("path"));
const config_1 = require("../config");
const orchestrator_1 = require("../orchestrator");
const session_1 = require("../session");
const workspace_1 = require("../workspace");
const cli_templates_1 = require("../cli-templates");
const cli_contracts_1 = require("../cli-contracts");
const auth_manager_1 = require("../auth-manager");
const cli_utils_1 = require("../cli-utils");
/**
* CLI Commands implementation
* Contains all command logic extracted from the main CLI class
*/
class CLICommands {
constructor() {
this.authManager = new auth_manager_1.AuthManager();
}
async authStatus(projectRoot = process.cwd()) {
console.log('๐ Checking authentication status...');
try {
const authManager = new auth_manager_1.AuthManager(projectRoot);
await authManager.discoverAuthentication();
return await authManager.getAuthReport();
}
catch (error) {
throw new Error(`Failed to check authentication status: ${error.message}`);
}
}
async authConfigure(method, projectRoot = process.cwd()) {
console.log('๐ Configuring authentication...');
try {
const authManager = new auth_manager_1.AuthManager(projectRoot);
await authManager.discoverAuthentication();
const status = await authManager.getAuthStatus();
let configReport = `
๐ Authentication Configuration Guide
${'='.repeat(50)}
๐ค Claude Authentication:
Current: ${status.claudeAuth.method}
Status: ${status.claudeAuth.isAuthenticated ? 'โ
Authenticated' : 'โ Not Authenticated'}
๐ง Gemini Authentication:
Current: ${status.geminiAuth.method}
Status: ${status.geminiAuth.isAuthenticated ? 'โ
Authenticated' : 'โ Not Authenticated'}
๐ก Setup Instructions:
1. For Claude Code CLI (Recommended):
โข Install Claude Code CLI: https://claude.ai/docs/cli
โข Login: \`claude auth login\`
โข Verify: \`claude auth status\`
2. For Gemini CLI:
โข Install Google Cloud CLI: https://cloud.google.com/sdk/docs/install
โข Login: \`gcloud auth login\`
โข Setup AI Platform: \`gcloud auth application-default login\`
3. For Direct API Keys:
โข Set ANTHROPIC_API_KEY in your .env file
โข Set GOOGLE_API_KEY in your .env file
๐ Current Recommendations:
${status.recommendations.map(rec => ` โข ${rec}`).join('\n')}
`;
return configReport.trim();
}
catch (error) {
throw new Error(`Failed to show authentication configuration: ${error.message}`);
}
}
async authSwitch(method, projectRoot = process.cwd()) {
console.log(`๐ Switching authentication method to: ${method}`);
try {
const authManager = new auth_manager_1.AuthManager(projectRoot);
await authManager.discoverAuthentication();
// Validate the method
const validMethods = ['claude-code', 'gemini-cli', 'direct-api'];
if (!validMethods.includes(method)) {
throw new Error(`Invalid authentication method: ${method}. Valid methods: ${validMethods.join(', ')}`);
}
const status = await authManager.getAuthStatus();
// Check if the requested method is available
if (method === 'claude-code' && !status.claudeAuth.isAuthenticated) {
throw new Error('Claude Code CLI not configured. Run "claude auth login" first.');
}
if (method === 'gemini-cli' && !status.geminiAuth.isAuthenticated) {
throw new Error('Gemini CLI not configured. Run "gcloud auth login" first.');
}
console.log(`โ
Authentication method switched to: ${method}`);
console.log('๐ก Note: This switch affects the current session only.');
console.log(' Update your project configuration to make this change permanent.');
}
catch (error) {
throw new Error(`Failed to switch authentication method: ${error.message}`);
}
}
async logs(taskId, projectRoot = process.cwd()) {
if (!cli_utils_1.CLIUtils.validateProject(projectRoot)) {
throw new Error('Not a CortexWeaver project. Run "cortex-weaver init" first.');
}
console.log(`๐ Retrieving logs for task: ${taskId}`);
try {
const sessionManager = new session_1.SessionManager();
// Get session output for the task
const sessionId = `cortex-${taskId}`;
const sessionOutput = await sessionManager.getSessionOutput(sessionId);
if (!sessionOutput) {
return `โ No logs found for task: ${taskId}`;
}
const logReport = `
๐ Task Logs: ${taskId}
${'='.repeat(50)}
๐ Session Output:
${sessionOutput}
๐ Log retrieval completed at: ${new Date().toISOString()}
`;
return logReport.trim();
}
catch (error) {
throw new Error(`Failed to retrieve logs for task ${taskId}: ${error.message}`);
}
}
async retry(taskId, projectRoot = process.cwd()) {
if (!cli_utils_1.CLIUtils.validateProject(projectRoot)) {
throw new Error('Not a CortexWeaver project. Run "cortex-weaver init" first.');
}
console.log(`๐ Retrying failed task: ${taskId}`);
try {
// Load configuration
const configService = new config_1.ConfigService(projectRoot);
const projectConfig = configService.loadProjectConfig();
const envVars = configService.loadEnvironmentVariables();
Object.assign(process.env, envVars);
// Initialize Cognitive Canvas connection
const neo4jUri = process.env.NEO4J_URI || 'bolt://localhost:7687';
const neo4jUsername = process.env.NEO4J_USERNAME || 'neo4j';
const neo4jPassword = configService.getRequiredEnvVar('NEO4J_PASSWORD');
const orchestratorConfig = {
neo4j: {
uri: neo4jUri,
username: neo4jUsername,
password: neo4jPassword
},
claude: {
apiKey: configService.getRequiredEnvVar('CLAUDE_API_KEY'),
defaultModel: projectConfig.models.claude,
budgetLimit: projectConfig.budget.maxCost
}
};
const orchestrator = new orchestrator_1.Orchestrator(orchestratorConfig);
await orchestrator.initialize(projectRoot);
// Check if task exists and is in FAILED state
const canvas = orchestrator.canvas;
const task = await canvas.getTaskById(taskId);
if (!task) {
throw new Error(`Task ${taskId} not found`);
}
if (task.status !== 'failed') {
throw new Error(`Task ${taskId} is not in FAILED state. Current status: ${task.status}`);
}
// Reset task status to pending for retry
await canvas.updateTaskStatus(taskId, 'pending');
// Clean up any existing sessions/worktrees for this task
const workspaceManager = new workspace_1.WorkspaceManager();
const sessionManager = new session_1.SessionManager();
try {
// Remove existing worktree if it exists
await workspaceManager.removeWorktree(taskId);
}
catch (error) {
// Worktree might not exist, that's okay
}
try {
// Kill existing sessions for this task
const sessions = sessionManager.listSessions();
const taskSessions = sessions.filter(s => s.taskId === taskId);
for (const session of taskSessions) {
await sessionManager.killSession(session.sessionId);
}
}
catch (error) {
// Sessions might not exist, that's okay
}
console.log(`โ
Task ${taskId} has been re-queued for retry`);
await orchestrator.shutdown();
}
catch (error) {
throw new Error(`Failed to retry task ${taskId}: ${error.message}`);
}
}
async listAgents(projectRoot = process.cwd()) {
console.log('๐ค Discovering available agent personas...');
try {
const promptsDir = path.join(projectRoot, 'prompts');
// Check if prompts directory exists
if (!fs.existsSync(promptsDir)) {
// Create prompts directory with default agent personas
await this.createDefaultAgentPersonas(promptsDir);
}
// Scan prompts directory for agent files
const agentFiles = fs.readdirSync(promptsDir)
.filter(file => file.endsWith('.md') || file.endsWith('.txt'))
.sort();
if (agentFiles.length === 0) {
return `โ No agent personas found in ${promptsDir}`;
}
let agentList = `
๐ค Available Agent Personas
${'='.repeat(40)}
๐ Prompts Directory: ${promptsDir}
๐ Total Agents Found: ${agentFiles.length}
๐ญ Agent Personas:
`;
for (const file of agentFiles) {
const filePath = path.join(promptsDir, file);
const content = fs.readFileSync(filePath, 'utf-8');
// Extract agent info from file content
const agentInfo = cli_utils_1.CLIUtils.parseAgentPersona(content, file);
agentList += `
๐ ${agentInfo.name}
Role: ${agentInfo.role}
File: ${file}
Description: ${agentInfo.description}
`;
}
agentList += `
๐ก Usage: Use these personas in your plan.md to specify which agents handle specific features.
๐ Each agent has specialized capabilities and knowledge domains.
`;
return agentList.trim();
}
catch (error) {
throw new Error(`Failed to list agents: ${error.message}`);
}
}
async init(projectRoot = process.cwd()) {
const configService = new config_1.ConfigService(projectRoot);
// Create .cortexweaver directory
const cortexDir = configService.getCortexWeaverDir();
if (!fs.existsSync(cortexDir)) {
fs.mkdirSync(cortexDir, { recursive: true });
}
// Create contracts directory structure
await cli_contracts_1.CLIContracts.createContractsStructure(projectRoot);
// Create plan.md template
await cli_templates_1.CLITemplates.createPlanTemplate(projectRoot);
// Create default config.json
await this.createDefaultConfig(configService);
// Create docker-compose.yml for MCP servers
await cli_templates_1.CLITemplates.createDockerCompose(projectRoot);
// Create .env.example template
await cli_templates_1.CLITemplates.createEnvTemplate(projectRoot);
// Create prompts directory with agent personas
await cli_templates_1.CLITemplates.createPromptsDirectory(projectRoot);
// Create prototypes directory
await cli_templates_1.CLITemplates.createPrototypesDirectory(projectRoot);
// Discover available authentication methods
console.log('\n๐ Discovering authentication methods...');
try {
const authManager = new auth_manager_1.AuthManager(projectRoot);
await authManager.discoverAuthentication();
const status = await authManager.getAuthStatus();
if (status.claudeAuth.isAuthenticated || status.geminiAuth.isAuthenticated) {
console.log('โ
Authentication configured:');
if (status.claudeAuth.isAuthenticated) {
console.log(` - Claude: ${status.claudeAuth.method}`);
}
if (status.geminiAuth.isAuthenticated) {
console.log(` - Gemini: ${status.geminiAuth.method}`);
}
}
else {
console.log('โ ๏ธ No authentication methods configured');
console.log(' Run "cortex-weaver auth configure" to set up authentication');
}
}
catch (error) {
console.log(`โ ๏ธ Authentication discovery failed: ${error.message}`);
}
console.log('โ
CortexWeaver project initialized successfully!');
console.log(`
Next steps:
1. ๐ Verify authentication: 'cortex-weaver auth status'
2. ๐ Copy .env.example to .env and fill in your API keys (if using direct-api)
3. ๐ณ Run 'docker-compose up -d' to start MCP servers
4. ๐ Edit plan.md to define your project features
5. ๐ Define formal contracts in the /contracts directory
6. ๐ค Customize agent personas in the /prompts directory
7. ๐งช Create prototypes and experiments in the /prototypes directory
8. ๐ Run 'cortex-weaver start' to begin orchestration
๐ Specification-Driven Development:
- Use /contracts/api/ for OpenAPI specifications
- Use /contracts/schemas/ for JSON Schema definitions
- Use /contracts/properties/ for property-based test invariants
- Use /contracts/examples/ for sample data and usage patterns
๐งช Prototyping & Experimentation:
- Use /prototypes/ for rapid prototyping and experimental features
- /prototypes/features/ - Feature prototypes and early implementations
- /prototypes/experiments/ - Experimental code and research implementations
- /prototypes/proofs-of-concept/ - POCs for core system functionality
- /prototypes/spike-solutions/ - Time-boxed investigation solutions
- /prototypes/algorithms/ - Algorithm implementations and testing
- Prototype validation before formal contract creation
- Explore technical feasibility and design alternatives
๐ค Agent Personas (CortexWeaver 3.0):
- Agent persona files are now available in /prompts directory
- Each agent has a comprehensive persona defining role, responsibilities, and instructions
- Personas can be versioned and improved over time as first-class citizens
- The new Reflector agent provides retrospective analysis and continuous improvement
`);
}
async createDefaultConfig(configService) {
const defaultConfig = {
models: {
claude: 'claude-3-opus-20240229',
gemini: 'gemini-pro'
},
costs: {
claudeTokenCost: 0.015,
geminiTokenCost: 0.0005
},
budget: {
maxTokens: 50000,
maxCost: 500
},
parallelism: {
maxConcurrentTasks: 5,
maxConcurrentAgents: 3
},
monitoring: {
enableMetrics: true,
logLevel: 'info'
}
};
configService.saveProjectConfig(defaultConfig);
}
async createDefaultAgentPersonas(promptsDir) {
fs.mkdirSync(promptsDir, { recursive: true });
const defaultPersonas = [
{
filename: 'spec-writer.md',
content: `# Spec Writer Agent
## Role
Requirements Analysis and Specification Creation
## Description
Creates comprehensive BDD specifications and feature files based on project requirements.
## Capabilities
- User story creation
- Acceptance criteria definition
- Gherkin scenario writing
- Requirements documentation
- Behavior-driven development specifications
## Knowledge Domains
- Business analysis
- Requirements engineering
- BDD/TDD methodologies
- User experience design
`
},
{
filename: 'formalizer.md',
content: `# Formalizer Agent
## Role
Contract and Mathematical Specification
## Description
Transforms BDD specifications into formal contracts and mathematical representations.
## Capabilities
- Contract specification creation
- Mathematical modeling
- Invariant definition
- Precondition/postcondition specification
- Formal verification support
## Knowledge Domains
- Formal methods
- Mathematical modeling
- Contract-based design
- Verification and validation
`
}
// Note: Shortened for space - full implementation would include all personas
];
for (const persona of defaultPersonas) {
const filePath = path.join(promptsDir, persona.filename);
fs.writeFileSync(filePath, persona.content);
}
console.log(`โ
Created ${defaultPersonas.length} default agent personas in ${promptsDir}`);
}
}
exports.CLICommands = CLICommands;
//# sourceMappingURL=commands.js.map