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
241 lines (232 loc) • 9.49 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.FormalizerAgent = void 0;
const agent_1 = require("../../agent");
const fs = __importStar(require("fs"));
const path = __importStar(require("path"));
const yaml = __importStar(require("js-yaml"));
/**
* FormalizerAgent - Refactored with simplified implementation
*
* Generates formal specifications including OpenAPI specs, JSON schemas,
* and property-based test stubs from natural language requirements.
*/
class FormalizerAgent extends agent_1.Agent {
/**
* Get the prompt template for formal specification generation
*/
getPromptTemplate() {
return `You are a Formalizer Agent, a formal methods specialist expert in converting natural language requirements into precise technical specifications.
## Core Responsibilities
- Transform BDD scenarios and requirements into formal OpenAPI specifications
- Generate comprehensive JSON schemas for data validation
- Create property-based test stubs with invariants and constraints
- Ensure formal consistency and completeness across specifications
- Validate generated specifications against best practices
## Input Context
**BDD Content:** {{bddContent}}
**Project Info:** {{projectInfo}}
**Requirements:** {{requirements}}
**Feature Files:** {{featureFiles}}
**Dependencies:** {{dependencies}}
## Formalization Process
1. **Requirements Analysis**: Parse natural language to identify entities, operations, and constraints
2. **API Design**: Extract RESTful operations from user stories and scenarios
3. **Data Modeling**: Identify domain objects and their relationships
4. **Constraint Extraction**: Derive business rules and validation requirements
5. **Test Generation**: Create property-based tests that verify formal properties
## Output Generation
Generate the following formal artifacts:
### OpenAPI Specification
- Complete OpenAPI 3.0 specification with all endpoints
- Proper HTTP methods, status codes, and response structures
- Security schemes and authentication requirements
- Request/response schemas with validation rules
### JSON Schemas
- Comprehensive data models for all domain entities
- Validation constraints derived from business rules
- Proper type definitions with required fields
- Additional properties control and format specifications
### Property-Based Test Stubs
- Test stubs with property assertions
- Invariants that must hold across all inputs
- Preconditions and postconditions for operations
- Edge case identification and boundary testing
## Quality Standards
- Ensure all specifications are valid and parseable
- Maintain consistency between OpenAPI and JSON schemas
- Generate comprehensive test coverage for critical properties
- Follow industry standards for API design and documentation
Focus on precision, completeness, and formal correctness while maintaining readability and maintainability.`;
}
/**
* Generate OpenAPI specification from requirements
*/
async generateOpenApiSpec(requirements) {
// Simplified implementation maintaining core functionality
const spec = {
openapi: '3.0.0',
info: {
title: 'Generated API',
version: '1.0.0',
description: 'API specification generated from requirements'
},
paths: {}
};
// Basic path generation logic (simplified)
const lines = requirements.split('\n');
for (const line of lines) {
if (line.toLowerCase().includes('endpoint') || line.toLowerCase().includes('api')) {
const pathName = this.extractPathFromRequirement(line);
if (pathName) {
spec.paths[pathName] = {
get: {
summary: line.trim(),
responses: {
'200': {
description: 'Success'
}
}
}
};
}
}
}
return spec;
}
/**
* Generate JSON schema from data description
*/
async generateJsonSchema(description) {
// Simplified schema generation
return {
type: 'object',
description: description,
properties: {
id: { type: 'string' },
data: { type: 'object' }
},
required: ['id'],
additionalProperties: false
};
}
/**
* Generate property test stubs from specifications
*/
async generatePropertyTestStubs(spec) {
const stubs = [];
// Generate test stubs for each path
Object.keys(spec.paths).forEach(path => {
stubs.push({
name: `test_${path.replace(/[^a-zA-Z0-9]/g, '_')}`,
description: `Property test for ${path}`,
properties: ['response_time', 'status_code', 'response_format'],
invariants: ['status_code >= 200', 'status_code < 500'],
preconditions: ['valid_request'],
postconditions: ['valid_response']
});
});
return stubs;
}
/**
* Execute the formalization task
*/
async executeTask() {
if (!this.currentTask) {
throw new Error('No task available');
}
try {
await this.reportProgress('started', 'Beginning formal specification generation');
const requirements = this.currentTask.requirements || ['Generate basic API specification'];
const requirementsText = Array.isArray(requirements) ? requirements.join('\n') : requirements;
// Generate specifications
const openApiSpec = await this.generateOpenApiSpec(requirementsText);
const jsonSchema = await this.generateJsonSchema(requirementsText);
const testStubs = await this.generatePropertyTestStubs(openApiSpec);
// Save specifications if workspace is available
if (this.config?.workspaceRoot) {
await this.saveSpecifications(openApiSpec, jsonSchema, testStubs);
}
await this.reportProgress('completed', 'Formal specifications generated successfully');
return {
success: true,
output: {
openApiSpec,
jsonSchema,
testStubs,
message: 'Formal specifications generated successfully'
}
};
}
catch (error) {
await this.reportProgress('error', `Formalization failed: ${error.message}`);
throw error;
}
}
/**
* Extract API path from requirement text
*/
extractPathFromRequirement(requirement) {
// Simplified path extraction
const words = requirement.toLowerCase().split(/\s+/);
for (let i = 0; i < words.length; i++) {
if (words[i] === 'path' && i + 1 < words.length) {
return `/${words[i + 1]}`;
}
if (words[i].startsWith('/')) {
return words[i];
}
}
return '/api/resource';
}
/**
* Save generated specifications to files
*/
async saveSpecifications(openApiSpec, jsonSchema, testStubs) {
const outputDir = path.join(this.config.workspaceRoot, 'specs');
if (!fs.existsSync(outputDir)) {
fs.mkdirSync(outputDir, { recursive: true });
}
// Save OpenAPI spec
fs.writeFileSync(path.join(outputDir, 'openapi.yaml'), yaml.dump(openApiSpec));
// Save JSON schema
fs.writeFileSync(path.join(outputDir, 'schema.json'), JSON.stringify(jsonSchema, null, 2));
// Save test stubs
fs.writeFileSync(path.join(outputDir, 'test-stubs.json'), JSON.stringify(testStubs, null, 2));
}
}
exports.FormalizerAgent = FormalizerAgent;
//# sourceMappingURL=formalizer-agent.js.map